From 8e13c775becf133c2697dbc6e117427c688b42ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ertu=C4=9Frul=20Erata?= Date: Sun, 17 May 2015 16:28:10 +0300 Subject: [PATCH] core updated. --- circle_and_problems_in_core.txt | 102 + circledep-finder | 193 + components.xml | 55 +- desktop/component.xml | 3 + desktop/font/component.xml | 3 + desktop/font/dejavu-fonts/actions.py | 30 + desktop/font/dejavu-fonts/pspec.xml | 56 + desktop/font/dejavu-fonts/translations.xml | 11 + .../base => desktop/font}/freetype/actions.py | 3 +- .../base => desktop/font}/freetype/pspec.xml | 23 +- .../font}/freetype/translations.xml | 0 distribution.xml | 37 + groups.xml | 28 +- hardware/component.xml | 3 + hardware/disk/component.xml | 3 + .../base => hardware/disk}/lvm2/actions.py | 5 +- .../disk}/lvm2/comar/package.py | 0 .../lvm2-2.02.105-pthread-pkgconfig.patch | 0 .../lvm2-2.02.106-static-pkgconfig-libs.patch | 0 ...vm2-2.02.63-always-make-static-libdm.patch | 0 .../lvm2-2.02.92-dynamic-static-ldflags.patch | 0 .../disk}/lvm2/files/tmpfiles.conf | 0 hardware/disk/lvm2/pspec.xml | 241 + .../disk/lvm2/pspec.xml.new | 25 +- .../disk}/lvm2/translations.xml | 0 hardware/disk/mdadm/actions.py | 39 + hardware/disk/mdadm/comar/service.py | 42 + hardware/disk/mdadm/files/mdadm.confd | 7 + hardware/disk/mdadm/files/mdadm.rules | 8 + hardware/disk/mdadm/files/mdadm.service | 8 + hardware/disk/mdadm/files/mdadm.tmpfiles.conf | 1 + hardware/disk/mdadm/files/scripts/raid-check | 6 + .../disk/mdadm/files/scripts/raid-start.sh | 29 + .../disk/mdadm/files/scripts/raid-stop.sh | 10 + hardware/disk/mdadm/pspec.xml | 90 + hardware/disk/mdadm/translations.xml | 14 + hardware/firmware/component.xml | 3 + hardware/firmware/linux-firmware/actions.py | 43 + .../firmware/linux-firmware/files/fw-check | 17 + .../fw/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq | Bin 0 -> 13315 bytes hardware/firmware/linux-firmware/pspec.xml | 168 + .../firmware/linux-firmware/translations.xml | 8 + kernel/component.xml | 3 + kernel/kernel/actions.py | 36 + kernel/kernel/comar/package.py | 22 + .../kernel/files/configs/kernel-i686-config | 5486 + .../kernel/files/configs/kernel-x86_64-config | 6337 + .../change-default-console-loglevel.patch | 11 + .../fix_CPU0_microcode_on_resume.patch | 21 + .../gentoo/1500_XATTR_USER_PREFIX.patch | 54 + ...ink-security-restrictions-by-default.patch | 22 + ...0_ThinkPad-30-brightness-control-fix.patch | 67 + .../gentoo/2900_dev-root-proc-mount-fix.patch | 30 + .../gentoo/2905_2disk-resume-image-fix.patch | 24 + .../patches/gentoo/4200_fbcondecor-3.19.patch | 2119 + .../gentoo/4567_distro-Gentoo-Kconfig.patch | 143 + ...kconfig-build-bits-for-BFQ-v7r7-3.19.patch | 104 + ...duce-the-BFQ-v7r7-I-O-sched-for-3.19.patch | 6966 + ...the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt | 6966 + ...eue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch | 1222 + ...tional-cpu-optimizations-for-gcc-4.9.patch | 387 + .../files/patches/linux/patch-3.17.4.xz | Bin 0 -> 216560 bytes .../files/patches/linux/patch-3.18.1.xz | Bin 0 -> 11500 bytes .../files/patches/linux/patch-3.18.3.xz | Bin 0 -> 80880 bytes .../files/patches/linux/patch-3.19.1.xz | Bin 0 -> 60636 bytes .../files/patches/linux/patch-3.19.2.xz | Bin 0 -> 115320 bytes .../files/patches/linux/patch-3.19.3.xz | Bin 0 -> 144892 bytes .../files/patches/linux/patch-3.19.4.xz | Bin 0 -> 164964 bytes .../files/patches/linux/patch-3.19.5.xz | Bin 0 -> 192220 bytes .../files/patches/linux/patch-3.19.6.xz | Bin 0 -> 202724 bytes .../files/patches/linux/patch-3.19.8.xz | Bin 0 -> 250604 bytes .../kernel/files/patches/linux/patch-4.0.3.gz | Bin 0 -> 110849 bytes .../mageia/3rd-3rdparty-1.0-tree.patch | 181 + .../patches/mageia/3rd-3rdparty-merge.patch | 175 + .../patches/mageia/3rd-acerhk-0.5.35.patch | 4212 + .../mageia/3rd-acerhk-2.6.36-buildfix.patch | 20 + .../mageia/3rd-acerhk-extra-cflags.patch | 33 + ...cerhk-fix-build-with-function-tracer.patch | 22 + .../mageia/3rd-acerhk-fix-include.patch | 23 + .../patches/mageia/3rd-acerhk-kbuild.patch | 37 + .../3rd-acerhk-proc_dir_entry-owner.patch | 67 + .../patches/mageia/3rd-aes2501-kbuild.patch | 47 + .../patches/mageia/3rd-aes2501-r19.patch | 2356 + .../mageia/3rd-aes2501-rmmod-oops-fix.patch | 21 + .../patches/mageia/3rd-ndiswrapper-1.59.patch | 26399 ++ .../mageia/3rd-ndiswrapper-Kconfig.patch | 7 + .../3rd-ndiswrapper-Makefile-build-fix.patch | 45 + .../3rd-ndiswrapper-linux-3.14-buildfix.patch | 33 + .../patches/mageia/3rd-rfswitch-1.3.patch | 978 + .../mageia/3rd-rfswitch-3.0-buildfix.patch | 19 + .../mageia/3rd-rfswitch-build-fix.patch | 51 + .../mageia/3rd-rtl8723bs-buildfix.patch | 23 + .../3rd-rtl8723bs-revert-4.0-changes.patch | 73 + .../mageia/3rd-rtl8723bs-updates.patch | 28991 ++ .../files/patches/mageia/3rd-rtl8723bs.patch | 140470 +++++++++ .../patches/mageia/3rd-viahss-0.92.patch | 189 + .../mageia/3rd-viahss-2.6.35-buildfix.patch | 20 + .../mageia/3rd-viahss-3.0-buildfix.patch | 19 + .../patches/mageia/3rd-viahss-config.patch | 18 + .../mageia/3rd-viahss-module-license.patch | 7 + .../files/patches/mageia/3rdparty.series | 3 + ...sable-changing-resolution-rate-scale.patch | 128 + ...sable-palm-detection-in-the-focaltec.patch | 41 + ...sure-that-focaltech-reports-consiste.patch | 44 + ...move-hardcoded-touchpad-size-from-th.patch | 41 + ...pport-for-the-FocalTech-PS-2-protoco.patch | 585 + ...op-kvm.h-from-installed-user-headers.patch | 28 + ...cc-Enable-autoload-of-pcc-cpufreq-fo.patch | 32 + ...-Windows-2015-string-to-_OSI-support.patch | 45 + .../acpi-CLEVO-M360S-disable_acpi_irq.patch | 28 + ...-IDs-to-list-for-PNPACPI-device-enum.patch | 42 + ...us-delay-to-fix-SBS-hangs-on-MacBook.patch | 85 + ...e-ordering-of-acpi_reserve_resources.patch | 56 + .../acpi-processor-M720SR-limit-to-C2.patch | 21 + ...-enable-battery-manager-when-present.patch | 34 + ...r_debug-instead-of-pr_info-for-MADT-.patch | 106 + ...-forcing-native-backlight-on-non-win.patch | 77 + ...alsa-emu10k1-emu10k2-32-bit-dma-mode.patch | 205 + ...ard-shortname-string-buffer-overflow.patch | 62 + ...jmicron-disable-broken-async_suspend.patch | 29 + ...over-ide-drivers-when-both-are-built.patch | 33 + ...he-async-PM-for-JMicron-chip-363-361.patch | 68 + ...e-requests-if-a-stopped-queue-restar.patch | 49 + .../blk-mq-fix-CPU-hotplug-handling.patch | 97 + .../mageia/blk-mq-fix-FUA-request-hang.patch | 38 + ...race-between-timeout-and-CPU-hotplug.patch | 62 + .../block-floppy-disable-pnp-modalias.patch | 21 + ...tooth-hci_usb-disable-isoc-transfers.patch | 23 + .../mageia/char-agp-intel-new-Q57-id.patch | 35 + .../patches/mageia/dm-raid-aliases.patch | 20 + .../firewire-ieee1394-module-aliases.patch | 29 + ...ndling-in-add_sysfs_runtime_map_entr.patch | 55 + .../patches/mageia/fs-aufs-3.19-modular.patch | 290 + .../files/patches/mageia/fs-aufs-3.19.patch | 34020 +++ ...-in-btrfs_orphan_add-when-delete-unu.patch | 96 + ...ting-to-delete-subvolume-during-send.patch | 53 + ...nsure-VariableName-is-NUL-terminated.patch | 41 + ...rruption-caused-by-unwritten-and-del.patch | 93 + ...eck-under-lock-scope-to-close-a-race.patch | 53 + ..._mounts-when-applied-to-unmounted-mo.patch | 49 + ..._visible-to-verify-the-root-director.patch | 36 + .../fs-path_openat-fix-double-fput.patch | 36 + ...sendfile-at-once-fails-for-big-files.patch | 136 + ...pointer-reference-in-irq_set_affinit.patch | 37 + ...al-affinity-in-irq_set_affinity_hint.patch | 69 + ...-RAW-Stall-Optimization-on-Broadwell.patch | 45 + ...ll-Optimization-is-on-for-Cherryview.patch | 35 + ...Improve-HiZ-throughput-on-Cherryview.patch | 47 + ...mple_c-messages-go-faster-on-Haswell.patch | 69 + .../mageia/gpu-drm-i915-fix-vlv-crash.patch | 24 + .../mageia/gpu-drm-mach64-2.6.31.patch | 100 + .../gpu-drm-mach64-2.6.36-buildfix.patch | 27 + .../gpu-drm-mach64-2.6.37-buildfix.patch | 24 + .../mageia/gpu-drm-mach64-3.0-buildfix.patch | 44 + .../mageia/gpu-drm-mach64-3.12-buildfix.patch | 17 + .../mageia/gpu-drm-mach64-3.17-buildfix.patch | 31 + .../mageia/gpu-drm-mach64-3.18-buildfix.patch | 142 + .../mageia/gpu-drm-mach64-3.3-buildfix.patch | 47 + .../mageia/gpu-drm-mach64-3.6-buildfix.patch | 15 + .../mageia/gpu-drm-mach64-3.7-buildfix.patch | 61 + ...drm-mach64-fix-for-changed-drm_ioctl.patch | 20 + ...mach64-fix-for-changed-drm_pci_alloc.patch | 12 + .../patches/mageia/gpu-drm-mach64-fixes.patch | 97 + .../gpu-drm-mach64-include-module.h.patch | 10 + .../gpu-drm-mach64-linux-3.14-buildfix.patch | 102 + ...pu-drm-mach64-restore-mach64_PCI_IDS.patch | 38 + .../files/patches/mageia/gpu-drm-mach64.patch | 4144 + ...hid-usbhid-IBM-BladeCenterHS20-quirk.patch | 37 + .../patches/mageia/ide-pci-sis5513-965.patch | 23 + .../include-kbuild-export-pci_ids.patch | 19 + ...ks-for-Fujitsu-Lifebook-A544-and-Lif.patch | 47 + .../iommu-vt-d-Remove-unused-variable.patch | 29 + ...ord-new-size-if-resize_stripes-fails.patch | 36 + ...edia-usb-pwc-lie-in-proc-usb-devices.patch | 13 + ...p-all-pfmemalloc-throttled-processes.patch | 44 + ...instead-of-1-to-protect-against-div-.patch | 68 + .../files/patches/mageia/mpt-vmware-fix.patch | 49 + ...v4-netfilter-ipt_IFWLOG-3.6-buildfix.patch | 33 + ...net-netfilter-IFWLOG-2.6.35-buildfix.patch | 32 + ...net-netfilter-IFWLOG-2.6.37-buildfix.patch | 15 + .../net-netfilter-IFWLOG-3.7-buildfix.patch | 20 + .../mageia/net-netfilter-IFWLOG-mdv.patch | 264 + .../patches/mageia/net-netfilter-IFWLOG.patch | 269 + .../net-netfilter-psd-2.6.35-buildfix.patch | 11 + .../mageia/net-netfilter-psd-mdv.patch | 233 + .../patches/mageia/net-netfilter-psd.patch | 420 + .../mageia/net-sis190-fix-list-usage.patch | 30 + ...less-ath9k-Update-PCI-IDs-for-AR9565.patch | 177 + ...ort-for-bcm43340_1-wireless-chipsets.patch | 116 + ...ull-pointer-access-when-brcmf_msgbuf.patch | 53 + ...check-result-of-USB-firmware-request.patch | 42 + ...g-X99-to-Intel-PCH-root-port-ACS-qui.patch | 33 + ...ks-for-Intel-9-series-PCH-root-ports.patch | 28 + ...I-M5229-ide-compatibility-mode-quirk.patch | 60 + .../mageia/pci-quirks-drop-devinit-exit.patch | 11 + .../platform-x86-add-shuttle-wmi-driver.patch | 1437 + ...rm-x86-shuttle-wmi-drop-devinit-exit.patch | 38 + .../mageia/pnp-isapnp-async-init.patch | 54 + .../mageia/pnp-pnpbios-off-by-default.patch | 15 + ...ier-race-that-could-result-in-too-sh.patch | 206 + ...add-1024-max-sectors-black-list-flag.patch | 94 + .../mageia/scsi-megaraid-new-sysfs-name.patch | 15 + .../patches/mageia/scsi-ppscsi-2.6.2.patch | 5083 + .../mageia/scsi-ppscsi-3.0-buildfix.patch | 19 + .../mageia/scsi-ppscsi-mdvbz45393.patch | 31 + .../mageia/scsi-ppscsi-sg-helper-update.patch | 36 + ...i-ppscsi-update-for-scsi_data_buffer.patch | 88 + .../patches/mageia/scsi-ppscsi_fixes.patch | 226 + kernel/kernel/files/patches/mageia/series | 478 + ...d-alsa-add-VT1613-AC97-codec-support.patch | 69 + ...Support-Dell-headset-mode-for-ALC256.patch | 65 + ...Support-Dell-headset-mode-for-ALC288.patch | 119 + ...-Support-headset-mode-for-ALC286-288.patch | 178 + .../mageia/sound-bluetooth-SCO-support.patch | 1296 + .../uas-add-us_fl_max_sectors_240-flag.patch | 98 + ...s_driver-to-return-usb-storage-flags.patch | 79 + ...ectors_240-quirk-for-asm1053-devices.patch | 43 + ...finite-loop-when-parsing-cdc-headers.patch | 56 + ...k-and-lock-while-stop-and-start-role.patch | 53 + ...-unusual_devs-add-id-2.6.37-buildfix.patch | 46 + .../usb-storage-unusual_devs-add-id.patch | 55 + ...y-increasing-TRBS_PER_SEGMENT-to-256.patch | 49 + ...rameters-for-functions-in-xhci-mem.c.patch | 339 + ...vancing-too-far-on-transaction-error.patch | 43 + ...acefully-handle-xhci_irq-dead-device.patch | 30 + ...eter-xhci-in-function-xhci-handshake.patch | 128 + ...ideo-fbdev-Add-additional-vesa-modes.patch | 68 + ...ev-Check-Standard-Timing-against-DMT.patch | 239 + ...eo-fbdev-Fix-sparse-warning-messages.patch | 128 + ...Validate-mode-timing-against-monspec.patch | 107 + ...vertical-front-and-back-porch-values.patch | 44 + ...-fbdev-fix-possible-null-dereference.patch | 42 + .../mageia/video-fbdev-fix-sys_copyarea.patch | 332 + .../patches/mageia/video-mageia-logo.patch | 949 + .../x86-boot-video-80x25-if-break.patch | 24 + .../x86-default_poweroff_up_machines.patch | 58 + ...per-bits-of-command-line-buffer-addr.patch | 39 + ...inimum-vmalloc-area-by-64MB-to-192MB.patch | 28 + ...pci-toshiba-equium-a60-assign-busses.patch | 29 + ...x-regression-in-spinlock-contention-.patch | 46 + .../kernel/files/scripts/generate-module-list | 39 + kernel/kernel/pspec.xml | 660 + kernel/kernel/translations.xml | 41 + multimedia/component.xml | 3 + multimedia/graphics/component.xml | 3 + .../graphics}/libpng/actions.py | 0 .../libpng/files/libpng-1.6.10-apng.patch.gz | Bin .../libpng/files/libpng-1.6.12-apng.patch.gz | Bin .../libpng/files/libpng-1.6.15-apng.patch.gz | Bin .../libpng/files/libpng-multilib.patch | 0 .../graphics}/libpng/pspec.xml | 12 +- .../graphics}/libpng/translations.xml | 0 pisi-index.xml | 30700 +- pisi-index.xml.sha1sum | 2 +- pisi-index.xml.xz | Bin 93380 -> 95480 bytes pisi-index.xml.xz.sha1sum | 2 +- system/base/ConsoleKit/actions.py | 44 - system/base/ConsoleKit/files/ConsoleKit.conf | 2 - .../ConsoleKit/files/pam-foreground-compat.ck | 17 - system/base/ConsoleKit/pspec.xml | 134 - system/base/ConsoleKit/translations.xml | 13 - system/base/acl/pspec.xml | 9 +- system/base/alternatives/pspec.xml | 5 +- system/base/attr/pspec.xml | 11 + system/base/audit/actions.py | 40 - system/base/audit/comar/package.py | 9 - system/base/audit/comar/service.py | 24 - .../base/audit/files/without_openldap.patch | 25 - system/base/audit/pspec.xml | 125 - system/base/audit/translations.xml | 18 - .../base/baselayout/files/pisilinux-release | 2 +- system/base/baselayout/pspec.xml | 7 + .../bash/files/official/bash43-001.tar.gz | Bin 829 -> 0 bytes .../bash/files/official/bash43-002.tar.gz | Bin 776 -> 0 bytes .../bash/files/official/bash43-003.tar.gz | Bin 844 -> 0 bytes .../bash/files/official/bash43-004.tar.gz | Bin 759 -> 0 bytes .../bash/files/official/bash43-005.tar.gz | Bin 956 -> 0 bytes .../bash/files/official/bash43-006.tar.gz | Bin 782 -> 0 bytes .../bash/files/official/bash43-007.tar.gz | Bin 806 -> 0 bytes .../bash/files/official/bash43-008.tar.gz | Bin 1545 -> 0 bytes .../bash/files/official/bash43-009.tar.gz | Bin 900 -> 0 bytes .../bash/files/official/bash43-010.tar.gz | Bin 2103 -> 0 bytes .../bash/files/official/bash43-011.tar.gz | Bin 836 -> 0 bytes .../bash/files/official/bash43-012.tar.gz | Bin 791 -> 0 bytes .../bash/files/official/bash43-013.tar.gz | Bin 1000 -> 0 bytes .../bash/files/official/bash43-014.tar.gz | Bin 1657 -> 0 bytes .../bash/files/official/bash43-015.tar.gz | Bin 918 -> 0 bytes .../bash/files/official/bash43-016.tar.gz | Bin 1643 -> 0 bytes .../bash/files/official/bash43-017.tar.gz | Bin 805 -> 0 bytes .../bash/files/official/bash43-018.tar.gz | Bin 786 -> 0 bytes .../bash/files/official/bash43-019.tar.gz | Bin 1090 -> 0 bytes .../bash/files/official/bash43-020.tar.gz | Bin 1022 -> 0 bytes .../bash/files/official/bash43-021.tar.gz | Bin 895 -> 0 bytes .../bash/files/official/bash43-022.tar.gz | Bin 926 -> 0 bytes .../bash/files/official/bash43-023.tar.gz | Bin 1289 -> 0 bytes .../bash/files/official/bash43-024.tar.gz | Bin 948 -> 0 bytes .../bash/files/official/bash43-025.tar.gz | Bin 1678 -> 0 bytes .../bash/files/official/bash43-026.tar.gz | Bin 809 -> 0 bytes .../bash/files/official/bash43-027.tar.gz | Bin 2221 -> 0 bytes .../bash/files/official/bash43-028.tar.gz | Bin 8202 -> 0 bytes .../bash/files/official/bash43-029.tar.gz | Bin 864 -> 0 bytes .../bash/files/official/bash43-030.tar.gz | Bin 6783 -> 0 bytes .../bash/files/official/bash43-031.tar.gz | Bin 0 -> 1452 bytes .../bash/files/official/bash43-032.tar.gz | Bin 0 -> 937 bytes .../bash/files/official/bash43-033.tar.gz | Bin 0 -> 2612 bytes system/base/bash/pspec.xml | 42 +- system/base/{libXdmcp => bc}/actions.py | 8 +- .../bc/files/fedora/bc-1.06-dc_ibase.patch | 58 + .../bc/files/fedora/bc-1.06.95-matlib.patch | 20 + .../bc/files/fedora/bc-1.06.95-memleak.patch | 26 + system/base/bc/pspec.xml | 64 + system/base/bc/translations.xml | 9 + system/base/biosdevname/actions.py | 3 + system/base/biosdevname/pspec.xml | 12 +- system/base/comar/pspec.xml | 6 +- system/base/coreutils/pspec.xml | 3 +- system/base/cryptsetup/pspec.xml | 21 +- system/base/curl/pspec.xml | 20 +- system/base/dbus-glib/pspec.xml | 20 +- system/base/dbus-python/pspec.xml | 6 +- system/base/dbus/actions.py | 4 +- system/base/dbus/pspec.xml | 35 +- system/base/dhcpcd/pspec.xml | 12 +- ...içindeki derleyici gcc olarak değiştirildi | 1 - system/base/disktype/actions.py | 19 - system/base/disktype/files/disktype.patch | 80 - system/base/disktype/files/ext4.patch | 112 - system/base/disktype/files/vfat.patch | 19 - system/base/disktype/pspec.xml | 56 - system/base/disktype/translations.xml | 8 - system/base/dnsmasq/actions.py | 32 - system/base/dnsmasq/comar/service.py | 67 - system/base/dnsmasq/comar/stack.py | 108 - system/base/dnsmasq/files/dnsmasq.conf | 489 - system/base/dnsmasq/files/dnsmasq.py | 31 - .../files/uk.org.thekelleys.dnsmasq.service | 4 - system/base/dnsmasq/pspec.xml | 93 - system/base/dnsmasq/translations.xml | 8 - system/base/e2fsprogs/pspec.xml | 20 +- system/base/eudev/actions.py | 73 + system/base/eudev/comar/package.py | 31 + system/base/eudev/files/config.cache | 3 + system/base/eudev/files/tmpfiles.conf | 1 + system/base/eudev/pspec.xml | 137 + system/base/eudev/translations.xml | 8 + system/base/expat/pspec.xml | 6 +- system/base/file/pspec.xml | 13 +- .../files/fix_segfault_with_harfbuzz.diff | 27 - .../files/freetype-2.2.1-enable-valid.patch | 20 - .../files/freetype-2.5.1-enable-sph.patch | 13 - .../files/freetype-2.5.1-enable-spr.patch | 13 - system/base/fuse/pspec.xml | 5 +- system/base/gettext/pspec.xml | 9 +- system/base/glib2/actions.py | 8 +- system/base/glib2/pspec.xml | 23 +- system/base/glibc/actions.py | 13 +- .../base/glibc/files/glibc-2.21-roundup.patch | 70 + system/base/glibc/pspec.xml | 11 +- system/base/groff/actions.py | 8 +- .../groff-1.19.2-man-unicode-dashes.patch | 24 + .../files/groff-1.22.3-parallel-mom.patch | 11 + system/base/groff/files/gropdf.patch | 13 + system/base/groff/files/savannah_bug.patch | 228193 +++++++++++++++ system/base/groff/pspec.xml | 14 +- system/base/iputils/actions.py | 28 - .../021109-uclibc-no-ether_ntohost.patch | 24 - system/base/iputils/files/docs.patch | 31 - .../iputils-20020124-countermeasures.patch | 12 - .../fedora/iputils-20020927-ping-subint.patch | 12 - .../iputils-20070202-traffic_class.patch | 14 - .../fedora/iputils-20100418-convtoint.patch | 24 - .../base/iputils/files/fedora/rdisc.service | 11 - .../base/iputils/files/fedora/rdisc.sysconfig | 1 - .../iputils/files/ifenslave/README.bonding | 2440 - .../base/iputils/files/ifenslave/ifenslave.8 | 68 - .../base/iputils/files/ifenslave/ifenslave.c | 1103 - .../iputils-20071127-kernel-ifaddr.patch | 55 - .../iputils-20071127-nonroot-floodping.patch | 11 - .../files/iputils-20100418-so_mark.patch | 22 - .../files/iputils-20121221-crypto-build.patch | 35 - .../files/iputils-20121221-makefile.patch | 61 - .../files/iputils-20121221-openssl.patch | 92 - .../files/iputils-20121221-owl-pingsock.diff | 224 - .../files/iputils-20121221-printf-size.patch | 64 - system/base/iputils/files/man/arping.8 | 110 - system/base/iputils/files/man/clockdiff.8 | 81 - system/base/iputils/files/man/ping.8 | 408 - system/base/iputils/files/man/rarpd.8 | 84 - system/base/iputils/files/man/rdisc.8 | 110 - system/base/iputils/files/man/tracepath.8 | 97 - system/base/iputils/files/man/traceroute6.8 | 42 - system/base/iputils/pspec.xml | 130 - system/base/iputils/translations.xml | 9 - system/base/json-c/pspec.xml | 5 +- system/base/kbd/actions.py | 13 +- .../kbd/files/archlinux/fix-dvorak-es.patch | 11 + .../base/kbd/files/archlinux/fix-euro2.patch | 9 + system/base/kbd/pspec.xml | 56 +- system/base/kmod/actions.py | 5 +- system/base/kmod/files/depmod-search.conf | 5 + .../kmod/files/kmod-15-dynamic-kmod.patch | 23 + system/base/kmod/pspec.xml | 22 +- system/base/libX11/actions.py | 26 - .../base/libX11/files/fix-null-pointer.patch | 12 - system/base/libX11/files/fix-segfault.diff | 50 - system/base/libX11/pspec.xml | 118 - system/base/libX11/translations.xml | 19 - system/base/libXau/actions.py | 20 - system/base/libXau/files/visibility.patch | 22 - system/base/libXau/pspec.xml | 86 - system/base/libXau/translations.xml | 20 - system/base/libXdmcp/pspec.xml | 77 - system/base/libXdmcp/translations.xml | 20 - system/base/libcap/pspec.xml | 12 +- system/base/libgcrypt/pspec.xml | 11 +- system/base/libgpg-error/pspec.xml | 17 +- system/base/libidn/pspec.xml | 3 + system/base/libpcre/pspec.xml | 1 + system/{devel => base}/libunwind/actions.py | 0 system/{devel => base}/libunwind/pspec.xml | 0 .../libunwind/translations.xml | 0 system/base/libusb-compat/pspec.xml | 5 +- system/base/libusb/actions.py | 4 +- system/base/libusb/pspec.xml | 11 +- system/base/libuser/actions.py | 35 + .../libuser/files/add-python-linkage.diff | 11 + .../files/disable-sgml2x-conversion.diff | 18 + .../files/libuser-0.56.15-fix_blowfish.patch | 28 + .../files/libuser-0.56.9-fix-str-fmt.patch | 22 + system/base/libuser/pspec.xml | 122 + system/base/libuser/translations.xml | 18 + system/base/libxcb/actions.py | 29 - system/base/libxcb/files/pthread-stubs.pc | 8 - system/base/libxcb/pspec.xml | 118 - system/base/libxcb/translations.xml | 17 - system/base/libxml2/pspec.xml | 3 +- system/base/lsb-release/pspec.xml | 3 + system/base/lzo/pspec.xml | 15 +- system/base/man-pages/pspec.xml | 11 +- system/base/mkinitramfs/actions.py | 19 - system/base/mkinitramfs/comar/pakhandler.py | 24 - system/base/mkinitramfs/files/hotplug | 14 - system/base/mkinitramfs/files/init | 593 - system/base/mkinitramfs/files/initramfs.conf | 29 - system/base/mkinitramfs/files/mkinitramfs | 586 - system/base/mkinitramfs/files/profile.rc | 6 - system/base/mkinitramfs/files/udhcpc.script | 85 - system/base/mkinitramfs/pspec.xml | 101 - system/base/mkinitramfs/translations.xml | 9 - system/base/mudur/actions.py | 20 + system/base/mudur/comar/disk.py | 492 + system/base/mudur/comar/netfs.py | 48 + system/base/mudur/comar/package.py | 17 + system/base/mudur/comar/pakhandler.py | 23 + system/base/mudur/comar/system.py | 122 + system/base/mudur/files/boot_option.patch | 43 + system/base/mudur/files/mount_cgroupfs.patch | 115 + system/base/mudur/files/no_err-no_msg.patch | 11 + .../recreate_dir_if_new_uid_or_gid.patch | 13 + system/base/mudur/files/set_file_mode.patch | 10 + system/base/mudur/pspec.xml | 188 + system/base/mudur/translations.xml | 9 + system/base/ncurses/pspec.xml | 3 + system/base/nettle/pspec.xml | 7 +- system/base/nspr/pspec.xml | 9 +- system/base/ntfs-3g/actions.py | 17 +- .../ntfs-3g/files/ntfsprogs_destdir.patch | 47 + system/base/ntfs-3g/pspec.xml | 15 +- system/base/openssl/pspec.xml | 17 +- system/base/os-prober/pspec.xml | 9 +- system/base/pam/actions.py | 3 + system/base/pam/pspec.xml | 9 +- system/base/pcmciautils/pspec.xml | 4 +- system/base/piksemel/pspec.xml | 2 +- system/base/pisi/files/qt5.py | 73 + system/base/pisi/pspec.xml | 14 +- .../files/remove_libX11_dep.patch | 147 + system/base/pisilinux-python/pspec.xml | 16 +- system/base/plyvel/pspec.xml | 5 +- system/base/polkit/actions.py | 16 +- system/base/polkit/pspec.xml | 8 + system/base/procps/pspec.xml | 2 +- system/base/psmisc/files/psmisc-fuser.patch | 11 + system/base/psmisc/pspec.xml | 14 +- system/base/pycurl/actions.py | 3 + system/base/pycurl/pspec.xml | 6 +- system/base/pypolkit/pspec.xml | 13 +- system/base/python-psutil/actions.py | 16 + system/base/python-psutil/pspec.xml | 55 + system/base/python-psutil/translations.xml | 8 + system/base/python-pyliblzma/pspec.xml | 4 +- system/base/python/pspec.xml | 12 +- system/base/readline/pspec.xml | 4 + system/base/rsyslog/actions.py | 6 +- system/base/rsyslog/comar/service.py | 4 +- system/base/rsyslog/files/50-default.conf | 95 + system/base/rsyslog/files/rsyslog.conf | 138 +- system/base/rsyslog/files/rsyslog.logrotate | 41 +- system/base/rsyslog/files/rsyslog.sysconfig | 33 +- system/base/rsyslog/pspec.xml | 12 +- system/base/run-parts/pspec.xml | 6 +- system/base/shadow/actions.py | 2 +- system/base/shadow/pspec.xml | 8 +- system/base/snappy/pspec.xml | 4 + system/base/spidermonkey/pspec.xml | 8 + system/base/sqlite/actions.py | 42 +- system/base/sqlite/pspec.xml | 43 +- system/base/timezone/actions.py | 9 +- .../files/timezone-data-2015c-makefile.patch | 86 + system/base/timezone/pspec.xml | 16 +- system/base/udev/pspec.xml | 10 +- system/base/util-linux/actions.py | 7 +- system/base/util-linux/files/uuidd.tmpfiles | 1 + system/base/util-linux/pspec.xml | 154 +- system/base/util-linux/pspec.xml.new | 236 + system/base/util-linux/translations.xml | 14 +- system/base/vixie-cron/pspec.xml | 4 +- system/base/which/pspec.xml | 11 +- system/base/wireless-tools/pspec.xml | 9 +- system/base/xz/pspec.xml | 13 +- system/base/zlib/pspec.xml | 4 + system/boot/component.xml | 3 + system/{base => boot}/grub2/actions.py | 0 .../{base => boot}/grub2/files/grub-defaults | 0 .../grub2/files/grub-defaults.orig | 0 .../grub2/files/mkconfig-fix.patch | 0 .../grub2/files/pisi-grub-bg.png | Bin .../grub2/files/pisi_name_and_initramfs.patch | 0 system/{base => boot}/grub2/pspec.xml | 1 + system/{base => boot}/grub2/translations.xml | 0 system/devel/autogen/actions.py | 2 + system/devel/autogen/pspec.xml | 3 + system/devel/binutils/actions.py | 4 +- .../binutils-2.24-gold-testsuite-plugin.patch | 2985 +- .../files/binutils-2.25-roundup.patch | 1660 + system/devel/binutils/pspec.xml | 17 +- system/devel/bison/pspec.xml | 9 +- system/devel/catbox/pspec.xml | 11 + system/devel/ccache/actions.py | 4 +- system/devel/ccache/pspec.xml | 3 + system/devel/cloog/pspec.xml | 1 + system/devel/cmake/actions.py | 1 + system/devel/cmake/pspec.xml | 23 +- system/devel/elfutils/pspec.xml | 10 +- system/devel/gmp/pspec.xml | 3 + system/devel/gobject-introspection/pspec.xml | 10 +- system/devel/guile/actions.py | 2 + system/devel/guile/pspec.xml | 4 + system/devel/isl/pspec.xml | 5 +- system/devel/libmpc/actions.py | 3 + system/devel/libmpc/pspec.xml | 9 +- system/devel/python-setuptools/pspec.xml | 4 +- system/devel/quilt/pspec.xml | 9 +- system/devel/xorg-proto/actions.py | 39 - system/devel/xorg-proto/files/docdir.patch | 14 - system/devel/xorg-proto/pspec.xml | 126 - system/devel/xorg-proto/translations.xml | 10 - system/devel/xtrans/pspec.xml | 11 +- 558 files changed, 543408 insertions(+), 27657 deletions(-) create mode 100644 circle_and_problems_in_core.txt create mode 100755 circledep-finder create mode 100644 desktop/component.xml create mode 100644 desktop/font/component.xml create mode 100644 desktop/font/dejavu-fonts/actions.py create mode 100644 desktop/font/dejavu-fonts/pspec.xml create mode 100644 desktop/font/dejavu-fonts/translations.xml rename {system/base => desktop/font}/freetype/actions.py (83%) rename {system/base => desktop/font}/freetype/pspec.xml (87%) rename {system/base => desktop/font}/freetype/translations.xml (100%) create mode 100644 hardware/component.xml create mode 100644 hardware/disk/component.xml rename {system/base => hardware/disk}/lvm2/actions.py (97%) rename {system/base => hardware/disk}/lvm2/comar/package.py (100%) rename {system/base => hardware/disk}/lvm2/files/lvm2-2.02.105-pthread-pkgconfig.patch (100%) rename {system/base => hardware/disk}/lvm2/files/lvm2-2.02.106-static-pkgconfig-libs.patch (100%) rename {system/base => hardware/disk}/lvm2/files/lvm2-2.02.63-always-make-static-libdm.patch (100%) rename {system/base => hardware/disk}/lvm2/files/lvm2-2.02.92-dynamic-static-ldflags.patch (100%) rename {system/base => hardware/disk}/lvm2/files/tmpfiles.conf (100%) create mode 100644 hardware/disk/lvm2/pspec.xml rename system/base/lvm2/pspec.xml => hardware/disk/lvm2/pspec.xml.new (92%) rename {system/base => hardware/disk}/lvm2/translations.xml (100%) create mode 100644 hardware/disk/mdadm/actions.py create mode 100644 hardware/disk/mdadm/comar/service.py create mode 100644 hardware/disk/mdadm/files/mdadm.confd create mode 100644 hardware/disk/mdadm/files/mdadm.rules create mode 100644 hardware/disk/mdadm/files/mdadm.service create mode 100644 hardware/disk/mdadm/files/mdadm.tmpfiles.conf create mode 100644 hardware/disk/mdadm/files/scripts/raid-check create mode 100644 hardware/disk/mdadm/files/scripts/raid-start.sh create mode 100644 hardware/disk/mdadm/files/scripts/raid-stop.sh create mode 100644 hardware/disk/mdadm/pspec.xml create mode 100644 hardware/disk/mdadm/translations.xml create mode 100644 hardware/firmware/component.xml create mode 100644 hardware/firmware/linux-firmware/actions.py create mode 100644 hardware/firmware/linux-firmware/files/fw-check create mode 100644 hardware/firmware/linux-firmware/files/fw/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq create mode 100644 hardware/firmware/linux-firmware/pspec.xml create mode 100644 hardware/firmware/linux-firmware/translations.xml create mode 100644 kernel/component.xml create mode 100644 kernel/kernel/actions.py create mode 100644 kernel/kernel/comar/package.py create mode 100644 kernel/kernel/files/configs/kernel-i686-config create mode 100644 kernel/kernel/files/configs/kernel-x86_64-config create mode 100644 kernel/kernel/files/patches/archlinux/change-default-console-loglevel.patch create mode 100644 kernel/kernel/files/patches/archlinux/fix_CPU0_microcode_on_resume.patch create mode 100644 kernel/kernel/files/patches/gentoo/1500_XATTR_USER_PREFIX.patch create mode 100644 kernel/kernel/files/patches/gentoo/1510_fs-enable-link-security-restrictions-by-default.patch create mode 100644 kernel/kernel/files/patches/gentoo/2700_ThinkPad-30-brightness-control-fix.patch create mode 100644 kernel/kernel/files/patches/gentoo/2900_dev-root-proc-mount-fix.patch create mode 100644 kernel/kernel/files/patches/gentoo/2905_2disk-resume-image-fix.patch create mode 100644 kernel/kernel/files/patches/gentoo/4200_fbcondecor-3.19.patch create mode 100644 kernel/kernel/files/patches/gentoo/4567_distro-Gentoo-Kconfig.patch create mode 100644 kernel/kernel/files/patches/gentoo/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r7-3.19.patch create mode 100644 kernel/kernel/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch create mode 100644 kernel/kernel/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt create mode 100644 kernel/kernel/files/patches/gentoo/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch create mode 100644 kernel/kernel/files/patches/gentoo/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch create mode 100644 kernel/kernel/files/patches/linux/patch-3.17.4.xz create mode 100644 kernel/kernel/files/patches/linux/patch-3.18.1.xz create mode 100644 kernel/kernel/files/patches/linux/patch-3.18.3.xz create mode 100644 kernel/kernel/files/patches/linux/patch-3.19.1.xz create mode 100644 kernel/kernel/files/patches/linux/patch-3.19.2.xz create mode 100644 kernel/kernel/files/patches/linux/patch-3.19.3.xz create mode 100644 kernel/kernel/files/patches/linux/patch-3.19.4.xz create mode 100644 kernel/kernel/files/patches/linux/patch-3.19.5.xz create mode 100644 kernel/kernel/files/patches/linux/patch-3.19.6.xz create mode 100644 kernel/kernel/files/patches/linux/patch-3.19.8.xz create mode 100644 kernel/kernel/files/patches/linux/patch-4.0.3.gz create mode 100644 kernel/kernel/files/patches/mageia/3rd-3rdparty-1.0-tree.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-3rdparty-merge.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-acerhk-0.5.35.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-acerhk-2.6.36-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-acerhk-extra-cflags.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-acerhk-fix-build-with-function-tracer.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-acerhk-fix-include.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-acerhk-kbuild.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-acerhk-proc_dir_entry-owner.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-aes2501-kbuild.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-aes2501-r19.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-aes2501-rmmod-oops-fix.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-ndiswrapper-1.59.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-ndiswrapper-Kconfig.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-ndiswrapper-Makefile-build-fix.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-ndiswrapper-linux-3.14-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-rfswitch-1.3.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-rfswitch-3.0-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-rfswitch-build-fix.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-rtl8723bs-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-rtl8723bs-revert-4.0-changes.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-rtl8723bs-updates.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-rtl8723bs.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-viahss-0.92.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-viahss-2.6.35-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-viahss-3.0-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-viahss-config.patch create mode 100644 kernel/kernel/files/patches/mageia/3rd-viahss-module-license.patch create mode 100644 kernel/kernel/files/patches/mageia/3rdparty.series create mode 100644 kernel/kernel/files/patches/mageia/Input-psmouse-disable-changing-resolution-rate-scale.patch create mode 100644 kernel/kernel/files/patches/mageia/Input-psmouse-disable-palm-detection-in-the-focaltec.patch create mode 100644 kernel/kernel/files/patches/mageia/Input-psmouse-ensure-that-focaltech-reports-consiste.patch create mode 100644 kernel/kernel/files/patches/mageia/Input-psmouse-remove-hardcoded-touchpad-size-from-th.patch create mode 100644 kernel/kernel/files/patches/mageia/Input-psmouse-support-for-the-FocalTech-PS-2-protoco.patch create mode 100644 kernel/kernel/files/patches/mageia/KVM-ia64-drop-kvm.h-from-installed-user-headers.patch create mode 100644 kernel/kernel/files/patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch create mode 100644 kernel/kernel/files/patches/mageia/acpi-ACPICA-Add-Windows-2015-string-to-_OSI-support.patch create mode 100644 kernel/kernel/files/patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch create mode 100644 kernel/kernel/files/patches/mageia/acpi-PNP-add-two-IDs-to-list-for-PNPACPI-device-enum.patch create mode 100644 kernel/kernel/files/patches/mageia/acpi-SBS-Add-5-us-delay-to-fix-SBS-hangs-on-MacBook.patch create mode 100644 kernel/kernel/files/patches/mageia/acpi-init-Fix-the-ordering-of-acpi_reserve_resources.patch create mode 100644 kernel/kernel/files/patches/mageia/acpi-processor-M720SR-limit-to-C2.patch create mode 100644 kernel/kernel/files/patches/mageia/acpi-sbs-enable-battery-manager-when-present.patch create mode 100644 kernel/kernel/files/patches/mageia/acpi-table-Use-pr_debug-instead-of-pr_info-for-MADT-.patch create mode 100644 kernel/kernel/files/patches/mageia/acpi-video-Allow-forcing-native-backlight-on-non-win.patch create mode 100644 kernel/kernel/files/patches/mageia/alsa-emu10k1-emu10k2-32-bit-dma-mode.patch create mode 100644 kernel/kernel/files/patches/mageia/alsa-emu10k1-fix-card-shortname-string-buffer-overflow.patch create mode 100644 kernel/kernel/files/patches/mageia/ata-jmicron-disable-broken-async_suspend.patch create mode 100644 kernel/kernel/files/patches/mageia/ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch create mode 100644 kernel/kernel/files/patches/mageia/ata-revert-Disabling-the-async-PM-for-JMicron-chip-363-361.patch create mode 100644 kernel/kernel/files/patches/mageia/blk-mq-don-t-lose-requests-if-a-stopped-queue-restar.patch create mode 100644 kernel/kernel/files/patches/mageia/blk-mq-fix-CPU-hotplug-handling.patch create mode 100644 kernel/kernel/files/patches/mageia/blk-mq-fix-FUA-request-hang.patch create mode 100644 kernel/kernel/files/patches/mageia/blk-mq-fix-race-between-timeout-and-CPU-hotplug.patch create mode 100644 kernel/kernel/files/patches/mageia/block-floppy-disable-pnp-modalias.patch create mode 100644 kernel/kernel/files/patches/mageia/bluetooth-hci_usb-disable-isoc-transfers.patch create mode 100644 kernel/kernel/files/patches/mageia/char-agp-intel-new-Q57-id.patch create mode 100644 kernel/kernel/files/patches/mageia/dm-raid-aliases.patch create mode 100644 kernel/kernel/files/patches/mageia/firewire-ieee1394-module-aliases.patch create mode 100644 kernel/kernel/files/patches/mageia/firmware-efi-Fix-error-handling-in-add_sysfs_runtime_map_entr.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-aufs-3.19-modular.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-aufs-3.19.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-btrfs-fix-BUG_ON-in-btrfs_orphan_add-when-delete-unu.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-btrfs-unlock-i_mutex-after-attempting-to-delete-subvolume-during-send.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-efivarfs-Ensure-VariableName-is-NUL-terminated.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-ext4-fix-data-corruption-caused-by-unwritten-and-del.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-ext4-move-check-under-lock-scope-to-close-a-race.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-mnt-Fail-collect_mounts-when-applied-to-unmounted-mo.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-mnt-Fix-fs_fully_visible-to-verify-the-root-director.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-path_openat-fix-double-fput.patch create mode 100644 kernel/kernel/files/patches/mageia/fs-splice-sendfile-at-once-fails-for-big-files.patch create mode 100644 kernel/kernel/files/patches/mageia/genirq-Fix-null-pointer-reference-in-irq_set_affinit.patch create mode 100644 kernel/kernel/files/patches/mageia/genirq-Set-initial-affinity-in-irq_set_affinity_hint.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-i915-Enable-the-HiZ-RAW-Stall-Optimization-on-Broadwell.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-i915-Ensure-the-HiZ-RAW-Stall-Optimization-is-on-for-Cherryview.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-i915-Improve-HiZ-throughput-on-Cherryview.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-i915-Make-sample_c-messages-go-faster-on-Haswell.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-i915-fix-vlv-crash.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.31.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.36-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.37-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.0-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.12-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.17-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.18-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.3-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.6-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.7-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-fix-for-changed-drm_ioctl.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-fix-for-changed-drm_pci_alloc.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-fixes.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-include-module.h.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64-restore-mach64_PCI_IDS.patch create mode 100644 kernel/kernel/files/patches/mageia/gpu-drm-mach64.patch create mode 100644 kernel/kernel/files/patches/mageia/hid-usbhid-IBM-BladeCenterHS20-quirk.patch create mode 100644 kernel/kernel/files/patches/mageia/ide-pci-sis5513-965.patch create mode 100644 kernel/kernel/files/patches/mageia/include-kbuild-export-pci_ids.patch create mode 100644 kernel/kernel/files/patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch create mode 100644 kernel/kernel/files/patches/mageia/iommu-vt-d-Remove-unused-variable.patch create mode 100644 kernel/kernel/files/patches/mageia/md-raid5-dont-record-new-size-if-resize_stripes-fails.patch create mode 100644 kernel/kernel/files/patches/mageia/media-usb-pwc-lie-in-proc-usb-devices.patch create mode 100644 kernel/kernel/files/patches/mageia/mm-vmscan-wake-up-all-pfmemalloc-throttled-processes.patch create mode 100644 kernel/kernel/files/patches/mageia/mm-writeback-use-1-instead-of-1-to-protect-against-div-.patch create mode 100644 kernel/kernel/files/patches/mageia/mpt-vmware-fix.patch create mode 100644 kernel/kernel/files/patches/mageia/net-ipv4-netfilter-ipt_IFWLOG-3.6-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-2.6.35-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-2.6.37-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-3.7-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-mdv.patch create mode 100644 kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG.patch create mode 100644 kernel/kernel/files/patches/mageia/net-netfilter-psd-2.6.35-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/net-netfilter-psd-mdv.patch create mode 100644 kernel/kernel/files/patches/mageia/net-netfilter-psd.patch create mode 100644 kernel/kernel/files/patches/mageia/net-sis190-fix-list-usage.patch create mode 100644 kernel/kernel/files/patches/mageia/net-wireless-ath9k-Update-PCI-IDs-for-AR9565.patch create mode 100644 kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-Add-support-for-bcm43340_1-wireless-chipsets.patch create mode 100644 kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch create mode 100644 kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-check-result-of-USB-firmware-request.patch create mode 100644 kernel/kernel/files/patches/mageia/pci-Add-Wellsburg-X99-to-Intel-PCH-root-port-ACS-qui.patch create mode 100644 kernel/kernel/files/patches/mageia/pci-acs-quirks-for-Intel-9-series-PCH-root-ports.patch create mode 100644 kernel/kernel/files/patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch create mode 100644 kernel/kernel/files/patches/mageia/pci-quirks-drop-devinit-exit.patch create mode 100644 kernel/kernel/files/patches/mageia/platform-x86-add-shuttle-wmi-driver.patch create mode 100644 kernel/kernel/files/patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch create mode 100644 kernel/kernel/files/patches/mageia/pnp-isapnp-async-init.patch create mode 100644 kernel/kernel/files/patches/mageia/pnp-pnpbios-off-by-default.patch create mode 100644 kernel/kernel/files/patches/mageia/rcu-Fix-rcu_barrier-race-that-could-result-in-too-sh.patch create mode 100644 kernel/kernel/files/patches/mageia/scsi-add-1024-max-sectors-black-list-flag.patch create mode 100644 kernel/kernel/files/patches/mageia/scsi-megaraid-new-sysfs-name.patch create mode 100644 kernel/kernel/files/patches/mageia/scsi-ppscsi-2.6.2.patch create mode 100644 kernel/kernel/files/patches/mageia/scsi-ppscsi-3.0-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/scsi-ppscsi-mdvbz45393.patch create mode 100644 kernel/kernel/files/patches/mageia/scsi-ppscsi-sg-helper-update.patch create mode 100644 kernel/kernel/files/patches/mageia/scsi-ppscsi-update-for-scsi_data_buffer.patch create mode 100644 kernel/kernel/files/patches/mageia/scsi-ppscsi_fixes.patch create mode 100644 kernel/kernel/files/patches/mageia/series create mode 100644 kernel/kernel/files/patches/mageia/sound-alsa-add-VT1613-AC97-codec-support.patch create mode 100644 kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC256.patch create mode 100644 kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC288.patch create mode 100644 kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-headset-mode-for-ALC286-288.patch create mode 100644 kernel/kernel/files/patches/mageia/sound-bluetooth-SCO-support.patch create mode 100644 kernel/kernel/files/patches/mageia/uas-add-us_fl_max_sectors_240-flag.patch create mode 100644 kernel/kernel/files/patches/mageia/uas-allow-uas_use_uas_driver-to-return-usb-storage-flags.patch create mode 100644 kernel/kernel/files/patches/mageia/uas-set-max_sectors_240-quirk-for-asm1053-devices.patch create mode 100644 kernel/kernel/files/patches/mageia/usb-cdc-acm-prevent-infinite-loop-when-parsing-cdc-headers.patch create mode 100644 kernel/kernel/files/patches/mageia/usb-chipidea-otg-remove-mutex-unlock-and-lock-while-stop-and-start-role.patch create mode 100644 kernel/kernel/files/patches/mageia/usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch create mode 100644 kernel/kernel/files/patches/mageia/usb-storage-unusual_devs-add-id.patch create mode 100644 kernel/kernel/files/patches/mageia/usb-xhci-Solve-full-event-ring-by-increasing-TRBS_PER_SEGMENT-to-256.patch create mode 100644 kernel/kernel/files/patches/mageia/usb-xhci-clean-up-work-to-remove-unused-parameters-for-functions-in-xhci-mem.c.patch create mode 100644 kernel/kernel/files/patches/mageia/usb-xhci-fix-isoc-endpoint-dequeue-from-advancing-too-far-on-transaction-error.patch create mode 100644 kernel/kernel/files/patches/mageia/usb-xhci-gracefully-handle-xhci_irq-dead-device.patch create mode 100644 kernel/kernel/files/patches/mageia/usb-xhci-remove-unused-parameter-xhci-in-function-xhci-handshake.patch create mode 100644 kernel/kernel/files/patches/mageia/video-fbdev-Add-additional-vesa-modes.patch create mode 100644 kernel/kernel/files/patches/mageia/video-fbdev-Check-Standard-Timing-against-DMT.patch create mode 100644 kernel/kernel/files/patches/mageia/video-fbdev-Fix-sparse-warning-messages.patch create mode 100644 kernel/kernel/files/patches/mageia/video-fbdev-Validate-mode-timing-against-monspec.patch create mode 100644 kernel/kernel/files/patches/mageia/video-fbdev-fix-CVT-vertical-front-and-back-porch-values.patch create mode 100644 kernel/kernel/files/patches/mageia/video-fbdev-fix-possible-null-dereference.patch create mode 100644 kernel/kernel/files/patches/mageia/video-fbdev-fix-sys_copyarea.patch create mode 100644 kernel/kernel/files/patches/mageia/video-mageia-logo.patch create mode 100644 kernel/kernel/files/patches/mageia/x86-boot-video-80x25-if-break.patch create mode 100644 kernel/kernel/files/patches/mageia/x86-default_poweroff_up_machines.patch create mode 100644 kernel/kernel/files/patches/mageia/x86-efi-Store-upper-bits-of-command-line-buffer-addr.patch create mode 100644 kernel/kernel/files/patches/mageia/x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch create mode 100644 kernel/kernel/files/patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch create mode 100644 kernel/kernel/files/patches/mageia/x86-spinlocks-Fix-regression-in-spinlock-contention-.patch create mode 100644 kernel/kernel/files/scripts/generate-module-list create mode 100644 kernel/kernel/pspec.xml create mode 100644 kernel/kernel/translations.xml create mode 100644 multimedia/component.xml create mode 100644 multimedia/graphics/component.xml rename {system/base => multimedia/graphics}/libpng/actions.py (100%) rename {system/base => multimedia/graphics}/libpng/files/libpng-1.6.10-apng.patch.gz (100%) rename {system/base => multimedia/graphics}/libpng/files/libpng-1.6.12-apng.patch.gz (100%) rename {system/base => multimedia/graphics}/libpng/files/libpng-1.6.15-apng.patch.gz (100%) rename {system/base => multimedia/graphics}/libpng/files/libpng-multilib.patch (100%) rename {system/base => multimedia/graphics}/libpng/pspec.xml (91%) rename {system/base => multimedia/graphics}/libpng/translations.xml (100%) delete mode 100644 system/base/ConsoleKit/actions.py delete mode 100644 system/base/ConsoleKit/files/ConsoleKit.conf delete mode 100644 system/base/ConsoleKit/files/pam-foreground-compat.ck delete mode 100644 system/base/ConsoleKit/pspec.xml delete mode 100644 system/base/ConsoleKit/translations.xml delete mode 100644 system/base/audit/actions.py delete mode 100644 system/base/audit/comar/package.py delete mode 100644 system/base/audit/comar/service.py delete mode 100644 system/base/audit/files/without_openldap.patch delete mode 100644 system/base/audit/pspec.xml delete mode 100644 system/base/audit/translations.xml delete mode 100644 system/base/bash/files/official/bash43-001.tar.gz delete mode 100644 system/base/bash/files/official/bash43-002.tar.gz delete mode 100644 system/base/bash/files/official/bash43-003.tar.gz delete mode 100644 system/base/bash/files/official/bash43-004.tar.gz delete mode 100644 system/base/bash/files/official/bash43-005.tar.gz delete mode 100644 system/base/bash/files/official/bash43-006.tar.gz delete mode 100644 system/base/bash/files/official/bash43-007.tar.gz delete mode 100644 system/base/bash/files/official/bash43-008.tar.gz delete mode 100644 system/base/bash/files/official/bash43-009.tar.gz delete mode 100644 system/base/bash/files/official/bash43-010.tar.gz delete mode 100644 system/base/bash/files/official/bash43-011.tar.gz delete mode 100644 system/base/bash/files/official/bash43-012.tar.gz delete mode 100644 system/base/bash/files/official/bash43-013.tar.gz delete mode 100644 system/base/bash/files/official/bash43-014.tar.gz delete mode 100644 system/base/bash/files/official/bash43-015.tar.gz delete mode 100644 system/base/bash/files/official/bash43-016.tar.gz delete mode 100644 system/base/bash/files/official/bash43-017.tar.gz delete mode 100644 system/base/bash/files/official/bash43-018.tar.gz delete mode 100644 system/base/bash/files/official/bash43-019.tar.gz delete mode 100644 system/base/bash/files/official/bash43-020.tar.gz delete mode 100644 system/base/bash/files/official/bash43-021.tar.gz delete mode 100644 system/base/bash/files/official/bash43-022.tar.gz delete mode 100644 system/base/bash/files/official/bash43-023.tar.gz delete mode 100644 system/base/bash/files/official/bash43-024.tar.gz delete mode 100644 system/base/bash/files/official/bash43-025.tar.gz delete mode 100644 system/base/bash/files/official/bash43-026.tar.gz delete mode 100644 system/base/bash/files/official/bash43-027.tar.gz delete mode 100644 system/base/bash/files/official/bash43-028.tar.gz delete mode 100644 system/base/bash/files/official/bash43-029.tar.gz delete mode 100644 system/base/bash/files/official/bash43-030.tar.gz create mode 100644 system/base/bash/files/official/bash43-031.tar.gz create mode 100644 system/base/bash/files/official/bash43-032.tar.gz create mode 100644 system/base/bash/files/official/bash43-033.tar.gz rename system/base/{libXdmcp => bc}/actions.py (66%) create mode 100644 system/base/bc/files/fedora/bc-1.06-dc_ibase.patch create mode 100644 system/base/bc/files/fedora/bc-1.06.95-matlib.patch create mode 100644 system/base/bc/files/fedora/bc-1.06.95-memleak.patch create mode 100644 system/base/bc/pspec.xml create mode 100644 system/base/bc/translations.xml delete mode 100644 system/base/disktype/Makefile içindeki derleyici gcc olarak değiştirildi delete mode 100644 system/base/disktype/actions.py delete mode 100644 system/base/disktype/files/disktype.patch delete mode 100644 system/base/disktype/files/ext4.patch delete mode 100644 system/base/disktype/files/vfat.patch delete mode 100644 system/base/disktype/pspec.xml delete mode 100644 system/base/disktype/translations.xml delete mode 100644 system/base/dnsmasq/actions.py delete mode 100644 system/base/dnsmasq/comar/service.py delete mode 100644 system/base/dnsmasq/comar/stack.py delete mode 100644 system/base/dnsmasq/files/dnsmasq.conf delete mode 100644 system/base/dnsmasq/files/dnsmasq.py delete mode 100644 system/base/dnsmasq/files/uk.org.thekelleys.dnsmasq.service delete mode 100644 system/base/dnsmasq/pspec.xml delete mode 100644 system/base/dnsmasq/translations.xml create mode 100644 system/base/eudev/actions.py create mode 100644 system/base/eudev/comar/package.py create mode 100644 system/base/eudev/files/config.cache create mode 100644 system/base/eudev/files/tmpfiles.conf create mode 100644 system/base/eudev/pspec.xml create mode 100644 system/base/eudev/translations.xml delete mode 100644 system/base/freetype/files/fix_segfault_with_harfbuzz.diff delete mode 100644 system/base/freetype/files/freetype-2.2.1-enable-valid.patch delete mode 100644 system/base/freetype/files/freetype-2.5.1-enable-sph.patch delete mode 100644 system/base/freetype/files/freetype-2.5.1-enable-spr.patch create mode 100644 system/base/glibc/files/glibc-2.21-roundup.patch create mode 100644 system/base/groff/files/groff-1.19.2-man-unicode-dashes.patch create mode 100644 system/base/groff/files/groff-1.22.3-parallel-mom.patch create mode 100644 system/base/groff/files/gropdf.patch create mode 100644 system/base/groff/files/savannah_bug.patch delete mode 100644 system/base/iputils/actions.py delete mode 100644 system/base/iputils/files/021109-uclibc-no-ether_ntohost.patch delete mode 100644 system/base/iputils/files/docs.patch delete mode 100644 system/base/iputils/files/fedora/iputils-20020124-countermeasures.patch delete mode 100644 system/base/iputils/files/fedora/iputils-20020927-ping-subint.patch delete mode 100644 system/base/iputils/files/fedora/iputils-20070202-traffic_class.patch delete mode 100644 system/base/iputils/files/fedora/iputils-20100418-convtoint.patch delete mode 100644 system/base/iputils/files/fedora/rdisc.service delete mode 100644 system/base/iputils/files/fedora/rdisc.sysconfig delete mode 100644 system/base/iputils/files/ifenslave/README.bonding delete mode 100644 system/base/iputils/files/ifenslave/ifenslave.8 delete mode 100644 system/base/iputils/files/ifenslave/ifenslave.c delete mode 100644 system/base/iputils/files/iputils-20071127-kernel-ifaddr.patch delete mode 100644 system/base/iputils/files/iputils-20071127-nonroot-floodping.patch delete mode 100644 system/base/iputils/files/iputils-20100418-so_mark.patch delete mode 100644 system/base/iputils/files/iputils-20121221-crypto-build.patch delete mode 100644 system/base/iputils/files/iputils-20121221-makefile.patch delete mode 100644 system/base/iputils/files/iputils-20121221-openssl.patch delete mode 100644 system/base/iputils/files/iputils-20121221-owl-pingsock.diff delete mode 100644 system/base/iputils/files/iputils-20121221-printf-size.patch delete mode 100644 system/base/iputils/files/man/arping.8 delete mode 100644 system/base/iputils/files/man/clockdiff.8 delete mode 100644 system/base/iputils/files/man/ping.8 delete mode 100644 system/base/iputils/files/man/rarpd.8 delete mode 100644 system/base/iputils/files/man/rdisc.8 delete mode 100644 system/base/iputils/files/man/tracepath.8 delete mode 100644 system/base/iputils/files/man/traceroute6.8 delete mode 100644 system/base/iputils/pspec.xml delete mode 100644 system/base/iputils/translations.xml create mode 100644 system/base/kbd/files/archlinux/fix-dvorak-es.patch create mode 100644 system/base/kbd/files/archlinux/fix-euro2.patch create mode 100644 system/base/kmod/files/depmod-search.conf create mode 100644 system/base/kmod/files/kmod-15-dynamic-kmod.patch delete mode 100644 system/base/libX11/actions.py delete mode 100644 system/base/libX11/files/fix-null-pointer.patch delete mode 100644 system/base/libX11/files/fix-segfault.diff delete mode 100644 system/base/libX11/pspec.xml delete mode 100644 system/base/libX11/translations.xml delete mode 100644 system/base/libXau/actions.py delete mode 100644 system/base/libXau/files/visibility.patch delete mode 100644 system/base/libXau/pspec.xml delete mode 100644 system/base/libXau/translations.xml delete mode 100644 system/base/libXdmcp/pspec.xml delete mode 100644 system/base/libXdmcp/translations.xml rename system/{devel => base}/libunwind/actions.py (100%) rename system/{devel => base}/libunwind/pspec.xml (100%) rename system/{devel => base}/libunwind/translations.xml (100%) create mode 100644 system/base/libuser/actions.py create mode 100644 system/base/libuser/files/add-python-linkage.diff create mode 100644 system/base/libuser/files/disable-sgml2x-conversion.diff create mode 100644 system/base/libuser/files/libuser-0.56.15-fix_blowfish.patch create mode 100644 system/base/libuser/files/libuser-0.56.9-fix-str-fmt.patch create mode 100644 system/base/libuser/pspec.xml create mode 100644 system/base/libuser/translations.xml delete mode 100644 system/base/libxcb/actions.py delete mode 100644 system/base/libxcb/files/pthread-stubs.pc delete mode 100644 system/base/libxcb/pspec.xml delete mode 100644 system/base/libxcb/translations.xml delete mode 100644 system/base/mkinitramfs/actions.py delete mode 100644 system/base/mkinitramfs/comar/pakhandler.py delete mode 100644 system/base/mkinitramfs/files/hotplug delete mode 100644 system/base/mkinitramfs/files/init delete mode 100644 system/base/mkinitramfs/files/initramfs.conf delete mode 100644 system/base/mkinitramfs/files/mkinitramfs delete mode 100644 system/base/mkinitramfs/files/profile.rc delete mode 100644 system/base/mkinitramfs/files/udhcpc.script delete mode 100644 system/base/mkinitramfs/pspec.xml delete mode 100644 system/base/mkinitramfs/translations.xml create mode 100644 system/base/mudur/actions.py create mode 100644 system/base/mudur/comar/disk.py create mode 100644 system/base/mudur/comar/netfs.py create mode 100644 system/base/mudur/comar/package.py create mode 100644 system/base/mudur/comar/pakhandler.py create mode 100644 system/base/mudur/comar/system.py create mode 100644 system/base/mudur/files/boot_option.patch create mode 100644 system/base/mudur/files/mount_cgroupfs.patch create mode 100644 system/base/mudur/files/no_err-no_msg.patch create mode 100644 system/base/mudur/files/recreate_dir_if_new_uid_or_gid.patch create mode 100644 system/base/mudur/files/set_file_mode.patch create mode 100644 system/base/mudur/pspec.xml create mode 100644 system/base/mudur/translations.xml create mode 100644 system/base/ntfs-3g/files/ntfsprogs_destdir.patch create mode 100644 system/base/pisi/files/qt5.py create mode 100644 system/base/pisilinux-python/files/remove_libX11_dep.patch create mode 100644 system/base/psmisc/files/psmisc-fuser.patch create mode 100644 system/base/python-psutil/actions.py create mode 100644 system/base/python-psutil/pspec.xml create mode 100644 system/base/python-psutil/translations.xml create mode 100644 system/base/rsyslog/files/50-default.conf create mode 100644 system/base/timezone/files/timezone-data-2015c-makefile.patch create mode 100644 system/base/util-linux/files/uuidd.tmpfiles create mode 100644 system/base/util-linux/pspec.xml.new create mode 100644 system/boot/component.xml rename system/{base => boot}/grub2/actions.py (100%) rename system/{base => boot}/grub2/files/grub-defaults (100%) rename system/{base => boot}/grub2/files/grub-defaults.orig (100%) rename system/{base => boot}/grub2/files/mkconfig-fix.patch (100%) rename system/{base => boot}/grub2/files/pisi-grub-bg.png (100%) rename system/{base => boot}/grub2/files/pisi_name_and_initramfs.patch (100%) rename system/{base => boot}/grub2/pspec.xml (99%) rename system/{base => boot}/grub2/translations.xml (100%) create mode 100644 system/devel/binutils/files/binutils-2.25-roundup.patch delete mode 100644 system/devel/xorg-proto/actions.py delete mode 100644 system/devel/xorg-proto/files/docdir.patch delete mode 100644 system/devel/xorg-proto/pspec.xml delete mode 100644 system/devel/xorg-proto/translations.xml diff --git a/circle_and_problems_in_core.txt b/circle_and_problems_in_core.txt new file mode 100644 index 00000000..50bb5ad3 --- /dev/null +++ b/circle_and_problems_in_core.txt @@ -0,0 +1,102 @@ + (0001/185) Calculating build dep of busybox (0002/185) Calculating build dep of libuser (0004/185) Calculating build dep of libpipeline (0005/185) Calculating build dep of liblogging (0006/185) Calculating build dep of alternatives (0003/185) Calculating build dep of less (0007/185) Calculating build dep of kbd (0008/185) Calculating build dep of spidermonkey ---> borks in 'check-devel' + (0009/185) Calculating build dep of sysvinit (0010/185) Calculating build dep of findutils ---> borks in 'libX11-devel' + (0011/185) Calculating build dep of rsyslog (0012/185) Calculating build dep of popt (0013/185) Calculating build dep of gdbm (0014/185) Calculating build dep of python-pyliblzma (0015/185) Calculating build dep of gobject-introspection ---> borks in 'cairo-devel' + (0016/185) Calculating build dep of pisilinux-python ---> borks in 'xmlto' + (0017/185) Calculating build dep of mingetty (0018/185) Calculating build dep of scons ---> borks in 'xmlto' + (0019/185) Calculating build dep of grub2 ---> borks in 'gc-devel' + (0020/185) Calculating build dep of snappy ---> borks in 'xmlto' + (0021/185) Calculating build dep of gnuconfig (0022/185) Calculating build dep of dejavu-fonts ---> borks in 'fontforge' + (0023/185) Calculating build dep of os-prober (0024/185) Calculating build dep of gmp ---> borks in 'xmlto' + (0025/185) Calculating build dep of baselayout ---> borks in 'xmlto' + (0026/185) Calculating build dep of swig (0027/185) Calculating build dep of flex ---> borks in 'xmlto' + (0028/185) Calculating build dep of python-setuptools (0029/185) Calculating build dep of unzip (0030/185) Calculating build dep of libusb-compat ---> borks in 'libX11-devel' + (0031/185) Calculating build dep of python (0032/185) Calculating build dep of libidn (0033/185) Calculating build dep of db (0034/185) Calculating build dep of cpio (0035/185) Calculating build dep of ca-certificates (0036/185) Calculating build dep of lzo ---> borks in 'xmlto' + (0037/185) Calculating build dep of libseccomp (0038/185) Calculating build dep of shadow ---> borks in 'xmlto' + (0039/185) Calculating build dep of util-linux ---> borks in 'xmlto' + (0040/185) Calculating build dep of dhcpcd (0041/185) Calculating build dep of attr ---> borks in 'xmlto' + (0042/185) Calculating build dep of python-psutil ---> borks in 'xmlto' + (0043/185) Calculating build dep of nspr (0044/185) Calculating build dep of dbus ---> borks in 'libX11-devel' + (0045/185) Calculating build dep of comar-api (0046/185) Calculating build dep of patch ---> borks in 'xmlto' + (0047/185) Calculating build dep of psmisc ---> borks in 'xmlto' + (0048/185) Calculating build dep of bison ---> borks in 'xmlto' + (0049/185) Calculating build dep of net-tools (0050/185) Calculating build dep of help2man ---> borks in 'xmlto' + (0051/185) Calculating build dep of man-pages ---> borks in 'libX11-devel' + (0052/185) Calculating build dep of kernel ---> borks in 'xmlto' + (0053/185) Calculating build dep of quilt (0054/185) Calculating build dep of json-c (0055/185) Calculating build dep of udev ---> borks in 'xmlto' + (0056/185) Calculating build dep of yacc (0057/185) Calculating build dep of util-macros (0058/185) Calculating build dep of sed (0059/185) Calculating build dep of intltool ---> borks in 'xmlto' + (0060/185) Calculating build dep of tcp-wrappers (0061/185) Calculating build dep of gperftools (0062/185) Calculating build dep of mdadm (0063/185) Calculating build dep of klibc (0064/185) Calculating build dep of mailcap (0065/185) Calculating build dep of kmod ---> borks in 'xmlto' + (0066/185) Calculating build dep of nss-mdns (0067/185) Calculating build dep of pisi ---> borks in 'xmlto' + (0068/185) Calculating build dep of libunistring (0069/185) Calculating build dep of glibc ---> borks in 'xmlto' + (0070/185) Calculating build dep of libestr (0071/185) Calculating build dep of piksemel ---> borks in 'cython' + (0072/185) Calculating build dep of automake ---> borks in 'xmlto' + (0073/185) Calculating build dep of icecream ---> borks in 'xmlto' + (0074/185) Calculating build dep of miscfiles ---> borks in 'librsync-devel' + (0075/185) Calculating build dep of ccache (0076/185) Calculating build dep of linux-firmware (0077/185) Calculating build dep of run-parts (0078/185) Calculating build dep of libpng ---> borks in 'xmlto' + (0079/185) Calculating build dep of uClibc (0080/185) Calculating build dep of bc (0081/185) Calculating build dep of v86d (0082/185) Calculating build dep of gawk ---> borks in 'xmlto' + (0083/185) Calculating build dep of xcb-proto (0084/185) Calculating build dep of libgcrypt ---> borks in 'xmlto' + (0085/185) Calculating build dep of bash (0086/185) Calculating build dep of eudev (0087/185) Calculating build dep of pcmciautils (0088/185) Calculating build dep of openssl ---> borks in 'xmlto' + (0089/185) Calculating build dep of acl ---> borks in 'xmlto' + (0090/185) Calculating build dep of btyacc (0091/185) Calculating build dep of guile ---> borks in 'gc-devel' + (0092/185) Calculating build dep of glib2 ---> borks in 'libX11-devel' + (0093/185) Calculating build dep of binutils ---> borks in 'xmlto' + (0094/185) Calculating build dep of ppl ---> borks in 'xmlto' + (0095/185) Calculating build dep of cryptsetup ---> borks in 'xmlto' + (0096/185) Calculating build dep of lvm2 (0097/185) Calculating build dep of perl-XML-Parser (0098/185) Calculating build dep of isl (0099/185) Calculating build dep of xz ---> borks in 'xmlto' + (0100/185) Calculating build dep of ntfs-3g ---> borks in 'xmlto' + (0101/185) Calculating build dep of unifdef (0102/185) Calculating build dep of biosdevname ---> borks in 'xmlto' + (0103/185) Calculating build dep of perl-Locale-gettext ---> borks in 'xmlto' + (0104/185) Calculating build dep of lsb-release ---> borks in 'xmlto' + (0105/185) Calculating build dep of mudur ---> borks in 'xmlto' + (0106/185) Calculating build dep of libssh2 ---> borks in 'xmlto' + (0107/185) Calculating build dep of zip (0108/185) Calculating build dep of pkgconfig ---> borks in 'xmlto' + (0109/185) Calculating build dep of perl ---> borks in 'libX11-devel' + (0110/185) Calculating build dep of m4 ---> borks in 'libX11-devel' + (0111/185) Calculating build dep of glpk (0112/185) Calculating build dep of dietlibc (0113/185) Calculating build dep of man-db ---> borks in 'xmlto' + (0114/185) Calculating build dep of libpcre (0115/185) Calculating build dep of groff ---> borks in 'xmlto' + (0116/185) Calculating build dep of libee (0117/185) Calculating build dep of cracklib (0118/185) Calculating build dep of autogen ---> borks in 'gc-devel' + (0119/185) Calculating build dep of libmpc (0120/185) Calculating build dep of ncurses (0121/185) Calculating build dep of yasm (0122/185) Calculating build dep of libunwind (0123/185) Calculating build dep of dbus-python ---> borks in 'python3' + (0124/185) Calculating build dep of sysfsutils (0125/185) Calculating build dep of pypolkit (0126/185) Calculating build dep of grep ---> borks in 'xmlto' + (0127/185) Calculating build dep of pycurl ---> borks in 'xmlto' + (0128/185) Calculating build dep of plyvel ---> borks in 'cython' + (0129/185) Calculating build dep of catbox (0130/185) Calculating build dep of zlib ---> borks in 'libX11-devel' + (0131/185) Calculating build dep of libgpg-error ---> borks in 'xmlto' + (0132/185) Calculating build dep of xtrans (0133/185) Calculating build dep of autoconf ---> borks in 'xmlto' + (0134/185) Calculating build dep of procps (0135/185) Calculating build dep of libsigsegv (0136/185) Calculating build dep of sqlite ---> borks in 'xmlto' + (0137/185) Calculating build dep of chrpath (0138/185) Calculating build dep of tar ---> borks in 'xmlto' + (0139/185) Calculating build dep of diffstat ---> borks in 'xmlto' + (0140/185) Calculating build dep of libxml2 (0141/185) Calculating build dep of expat ---> borks in 'xmlto' + (0142/185) Calculating build dep of freetype ---> borks in 'xmlto' + (0143/185) Calculating build dep of cloog (0144/185) Calculating build dep of file ---> borks in 'xmlto' + (0145/185) Calculating build dep of timezone ---> borks in 'xmlto' + (0146/185) Calculating build dep of curl ---> borks in 'xmlto' + (0147/185) Calculating build dep of libarchive ---> borks in 'xmlto' + (0148/185) Calculating build dep of texinfo (0149/185) Calculating build dep of dbus-glib (0150/185) Calculating build dep of bzip2 ---> borks in 'xmlto' + (0151/185) Calculating build dep of leveldb (0152/185) Calculating build dep of cmake ---> borks in 'libX11-devel' + (0153/185) Calculating build dep of make ---> borks in 'gc-devel' + (0154/185) Calculating build dep of gettext ---> borks in 'xmlto' + (0155/185) Calculating build dep of coreutils (0156/185) Calculating build dep of vixie-cron (0157/185) Calculating build dep of libcap-ng (0158/185) Calculating build dep of which (0159/185) Calculating build dep of libcap (0160/185) Calculating build dep of pam ---> borks in 'xmlto' + (0161/185) Calculating build dep of wireless-tools (0162/185) Calculating build dep of xorg-util (0163/185) Calculating build dep of gperf ---> borks in 'libX11-devel' + (0164/185) Calculating build dep of time (0165/185) Calculating build dep of gcc ---> borks in 'xmlto' + (0166/185) Calculating build dep of polkit ---> borks in 'libX11-devel' + (0167/185) Calculating build dep of fuse (0168/185) Calculating build dep of libtool (0169/185) Calculating build dep of ncompress (0170/185) Calculating build dep of libffi (0171/185) Calculating build dep of readline (0172/185) Calculating build dep of slang ---> borks in 'xmlto' + (0173/185) Calculating build dep of comar ---> borks in 'libX11-devel' + (0174/185) Calculating build dep of nano ---> borks in 'xmlto' + (0175/185) Calculating build dep of diffutils ---> borks in 'xmlto' + (0176/185) Calculating build dep of urlgrabber (0177/185) Calculating build dep of usbutils (0178/185) Calculating build dep of e2fsprogs ---> borks in 'xmlto' + (0179/185) Calculating build dep of nettle ---> borks in 'xmlto' + (0180/185) Calculating build dep of libusb ---> borks in 'xmlto' + (0181/185) Calculating build dep of pciutils (0182/185) Calculating build dep of gzip (0183/185) Calculating build dep of nasm (0184/185) Calculating build dep of elfutils ---> borks in 'xmlto' + (0185/185) Calculating build dep of mpfr ---> borks in 'xmlto' + + +Encountered cycle ['gcc', 'isl', 'gmp'] +Encountered cycle ['glibc', 'binutils'] +Encountered cycle ['gcc', 'gmp'] +Encountered cycle ['gcc', 'libmpc', 'gmp'] +Encountered cycle ['gcc', 'elfutils'] +Encountered cycle ['gettext', 'gcc'] +Encountered cycle ['gcc', 'gettext'] +Encountered cycle ['glibc', 'gettext', 'gcc', 'zlib'] +Encountered cycle ['ppl', 'gcc'] +Encountered cycle ['gcc', 'ppl'] +Encountered cycle ['gettext', 'gcc', 'zlib', 'glibc'] diff --git a/circledep-finder b/circledep-finder new file mode 100755 index 00000000..d237f861 --- /dev/null +++ b/circledep-finder @@ -0,0 +1,193 @@ +#!/usr/bin/python +# +# -*- coding: utf-8 -*- +# +# Copyright (C) 2008, TUBITAK/UEKAE +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# Please read the COPYING file. +# + +import sys +import multiprocessing + +import urllib2 +import bz2 +import lzma + +import piksemel + +import pisi +import pisi.dependency as dependency +from pisi.graph import CycleException + + +class SourceDB: + def __init__(self, index): + + self.__source_nodes = {} + self.__pkgstosrc = {} + + doc = piksemel.parseString(index) + self.__source_nodes, self.__pkgstosrc = self.__generate_sources(doc) + + def __generate_sources(self, doc): + sources = {} + pkgstosrc = {} + + for spec in doc.tags("SpecFile"): + src_name = spec.getTag("Source").getTagData("Name") + sources[src_name] = spec.toString() + for package in spec.tags("Package"): + pkgstosrc[package.getTagData("Name")] = src_name + + return sources, pkgstosrc + + def has_spec(self, name): + return self.__source_nodes.has_key(name) + + def get_spec(self, name): + src = self.__source_nodes[name] + spec = pisi.specfile.SpecFile() + spec.parse(src) + return spec + + def list_specs(self): + return self.__source_nodes.keys() + + def pkgtosrc(self, name): + return self.__pkgstosrc[name] + +def find_circle(sourcedb, A): + + G_f = pisi.graph.Digraph() + + def get_spec(name): + if sourcedb.has_spec(name): + return sourcedb.get_spec(name) + else: + raise Exception('Cannot find source package: %s' % name) + + def get_src(name): + return get_spec(name).source + + def add_src(src): + if not str(src.name) in G_f.vertices(): + G_f.add_vertex(str(src.name), (src.version, src.release)) + + def pkgtosrc(pkg): + try: + tmp = sourcedb.pkgtosrc(pkg) + except KeyError, e: + # this is a bad hack but after we hit a problem we need to continue + tmp = "e3" + print "---> borks in ", e + + return tmp + + B = A + + install_list = set() + + while len(B) > 0: + Bp = set() + for x in B: + sf = get_spec(x) + src = sf.source + add_src(src) + + # add dependencies + + def process_dep(dep): + srcdep = pkgtosrc(dep.package) + if not srcdep in G_f.vertices(): + Bp.add(srcdep) + add_src(get_src(srcdep)) + if not src.name == srcdep: # firefox - firefox-devel thing + G_f.add_edge(src.name, srcdep) + + for builddep in src.buildDependencies: + process_dep(builddep) + + for pkg in sf.packages: + for rtdep in pkg.packageDependencies: + process_dep(rtdep) + B = Bp + + try: + order_build = G_f.topological_sort() + order_build.reverse() + except CycleException, cycle: + return str(cycle) + + return "" + +def getIndex(uri): + try: + if "://" in uri: + rawdata = urllib2.urlopen(uri).read() + else: + rawdata = open(uri, "r").read() + except IOError: + print "could not fetch %s" % uri + return None + + if uri.endswith("bz2"): + data = bz2.decompress(rawdata) + elif uri.endswith("xz") or uri.endswith("lzma"): + data = lzma.decompress(rawdata) + else: + data = rawdata + + return data + +def processPackage(pkg, sourcesLength, counter): + global sourcedb + + sys.stdout.write("\r(%04d/%d) Calculating build dep of %s " % (counter, sourcesLength, pkg)) + sys.stdout.flush() + + return find_circle(sourcedb, [pkg]) + +def updateStatus(circleResult): + global cycles + cycles.add(circleResult) + + +if __name__ == "__main__": + + if len(sys.argv) < 2: + print "Usage: circlefinder.py " + sys.exit(1) + + rawIndex = getIndex(sys.argv[1]) + sourcedb = SourceDB(rawIndex) + sources = sourcedb.list_specs() + + sourcesLength = len(sources) + counter = 0 + + global cycles + cycles = set() + + pool = multiprocessing.Pool() + + for pkg in sources: + counter += 1 + pool.apply_async(processPackage, (pkg, sourcesLength, counter), callback=updateStatus) + + pool.close() + pool.join() + + if len(cycles): + print + for cycle in cycles: + print cycle + else: + print "No circular dep found" + + diff --git a/components.xml b/components.xml index d1a67859..cc4fcdef 100755 --- a/components.xml +++ b/components.xml @@ -792,6 +792,17 @@ admins@pisilinux.org + + desktop.toolkit.qt5 + FIXME + FIXME + FIXME + programming + + PisiLinux Community + admins@pisilinux.org + + desktop.toolkit.motif FIXME @@ -1210,39 +1221,6 @@ admins@pisilinux.org - - desktop.lxde - FIXME - FIXME - FIXME - lxde.desktop - - PisiLinux Community - admins@pisilinux.org - - - - desktop.lxde.addon - FIXME - FIXME - FIXME - lxde.addon - - PisiLinux Community - admins@pisilinux.org - - - - desktop.lxde.base - FIXME - FIXME - FIXME - lxde.desktop - - PisiLinux Community - admins@pisilinux.org - - desktop.lxqt FIXME @@ -1298,6 +1276,17 @@ admins@pisilinux.org + + kernel.tools + Kernel Tools + Kernel Tools; perf, cpupowertools + FIXME + system + + PisiLinux Community + admins@pisilinux.org + + x11 FIXME diff --git a/desktop/component.xml b/desktop/component.xml new file mode 100644 index 00000000..f2e99cf5 --- /dev/null +++ b/desktop/component.xml @@ -0,0 +1,3 @@ + + desktop + diff --git a/desktop/font/component.xml b/desktop/font/component.xml new file mode 100644 index 00000000..709d503f --- /dev/null +++ b/desktop/font/component.xml @@ -0,0 +1,3 @@ + + desktop.font + diff --git a/desktop/font/dejavu-fonts/actions.py b/desktop/font/dejavu-fonts/actions.py new file mode 100644 index 00000000..72e68e5b --- /dev/null +++ b/desktop/font/dejavu-fonts/actions.py @@ -0,0 +1,30 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 3. +# See the file http://www.gnu.org/licenses/gpl-3.0.txt + +from pisi.actionsapi import shelltools +from pisi.actionsapi import pisitools +from pisi.actionsapi import autotools +from pisi.actionsapi import get + + +def build(): + autotools.make('FC-LANG="" BLOCKS="/usr/share/unicode/ucd/Blocks.txt" UNICODEDATA="/usr/share/unicode/ucd/UnicodeData.txt"') + +def check(): + autotools.make("check") + +def install(): + pisitools.insinto("/usr/share/fonts/dejavu", "build/*.ttf") + + # Create symlinks for fontconfig files + for conf in shelltools.ls("fontconfig"): + pisitools.insinto("/etc/fonts/conf.avail", "fontconfig/%s" % conf) + pisitools.dosym("/etc/fonts/conf.avail/%s" % conf, "/etc/fonts/conf.d/%s" % conf) + + + pisitools.dosym("/usr/share/fonts/dejavu" , "/etc/X11/fontpath.d/dejavu") + + pisitools.dodoc("AUTHORS", "LICENSE", "NEWS", "README") diff --git a/desktop/font/dejavu-fonts/pspec.xml b/desktop/font/dejavu-fonts/pspec.xml new file mode 100644 index 00000000..cac22b24 --- /dev/null +++ b/desktop/font/dejavu-fonts/pspec.xml @@ -0,0 +1,56 @@ + + + + + dejavu-fonts + http://www.dejavu-fonts.org + + Sezai Yeniay + sezaiyeniay@pisilinux.org + + as-is + data:font + DejaVu fonts + Contains DejaVu fonts that are based on Bitstream fonts, with improvements. + mirrors://sourceforge/dejavu/dejavu-fonts-2.34.tar.bz2 + + fontforge + perl-Font-TTF + unicode-ucd + + + + + dejavu-fonts + + /etc/fonts + /etc/X11/fontpath.d/dejavu + /usr/share/fonts + /usr/share/doc + + + + + + 2014-01-27 + 2.34 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-05-24 + 2.33.2514 + First release + PisiLinux Community + admins@pisilinux.org + + + 2012-05-24 + 2.33 + First release + Sezai Yeniay + sezaiyeniay@pisilinux.org + + + diff --git a/desktop/font/dejavu-fonts/translations.xml b/desktop/font/dejavu-fonts/translations.xml new file mode 100644 index 00000000..533b9c34 --- /dev/null +++ b/desktop/font/dejavu-fonts/translations.xml @@ -0,0 +1,11 @@ + + + + dejavu-fonts + DejaVu yazıtipleri + DejaVu yazıtipleri + Les fontes DejaVu basées sur des fontes Bitstream avec des améliorations. + DejaVu fonts + Bevat de DejaVu fonts die zijn gebasserd op de Bitstream fonts, met verbeteringen. + + diff --git a/system/base/freetype/actions.py b/desktop/font/freetype/actions.py similarity index 83% rename from system/base/freetype/actions.py rename to desktop/font/freetype/actions.py index 30e30b53..c8c7e356 100644 --- a/system/base/freetype/actions.py +++ b/desktop/font/freetype/actions.py @@ -10,7 +10,8 @@ from pisi.actionsapi import shelltools from pisi.actionsapi import get def setup(): - autotools.configure("-disable-static") + autotools.configure("--disable-static \ + --with-harfbuzz=no") def build(): autotools.make() diff --git a/system/base/freetype/pspec.xml b/desktop/font/freetype/pspec.xml similarity index 87% rename from system/base/freetype/pspec.xml rename to desktop/font/freetype/pspec.xml index 61f1c112..d2146a34 100644 --- a/system/base/freetype/pspec.xml +++ b/desktop/font/freetype/pspec.xml @@ -13,18 +13,12 @@ library A high-quality and portable font engine FreeType 2 is a software font engine that is designed to be small, efficient, highly customizable, and portable while capable of producing high-quality output. It can be used in graphics libraries, display servers, font conversion tools, text image generation tools, and many other products as well. - mirrors://sourceforge/freetype/freetype-2.5.3.tar.bz2 + mirrors://sourceforge/freetype/freetype-2.5.5.tar.bz2 zlib-devel bzip2 libpng-devel - - freetype-2.2.1-enable-valid.patch - freetype-2.5.1-enable-sph.patch - freetype-2.5.1-enable-spr.patch - fix_segfault_with_harfbuzz.diff - @@ -43,11 +37,10 @@ freetype-devel - system.devel Development files for freetype - freetype - harfbuzz-devel + zlib-devel + libpng-devel /usr/bin @@ -66,10 +59,9 @@ zlib-32bit libpng-32bit - harfbuzz-32bit - freetype + glibc-32bit zlib-32bit libpng-32bit @@ -79,6 +71,13 @@ + + 2015-03-11 + 2.5.5 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + 2014-05-11 2.5.3 diff --git a/system/base/freetype/translations.xml b/desktop/font/freetype/translations.xml similarity index 100% rename from system/base/freetype/translations.xml rename to desktop/font/freetype/translations.xml diff --git a/distribution.xml b/distribution.xml index 829a01db..bb6898ac 100755 --- a/distribution.xml +++ b/distribution.xml @@ -8,6 +8,9 @@ Core PisiLinux + xorg-video-modesetting + glamor-egl + glamor-egl-devel kdeadmin kdenetwork kdenetwork-devel @@ -363,5 +366,39 @@ libusbx-devel libusbx-32bit labltk + udev + libudev + libgudev1 + libudev-devel + libgudev1-devel + libudev-32bit + libgudev1-32bit + mdbtools-gui + module-nvidia96 + xorg-video-nvidia96 + module-nvidia173 + xorg-video-nvidia173 + libfm + libfm-devel + lxappearance + lxappearance-devel + lxappearance-obconf + lxde-common + lxde-menu-cache + lxde-menu-cache-devel + lxinput + lxmenu-data + lxpanel + lxpanel-devel + lxpolkit + lxrandr + lxsession + lxtask + lxterminal + pcmanfm + pcmanfm-devel + gpicview + lxlauncher + screengrab diff --git a/groups.xml b/groups.xml index fa4560d3..856d45c1 100755 --- a/groups.xml +++ b/groups.xml @@ -288,30 +288,14 @@ Escritorio Razor-qt razor-qt - - lxde.desktop - LXDE Desktop - LXDE Desktop - Skrivbord, LXDE - LXDE Masaüstü - Bureau LXDE - Escritorio LXDE - preferences-desktop - - - lxde.addon - Lxde Desktop Addons - Lxde Masaüstü Araçları - preferences-desktop - lxqt.desktop - LXQT Desktop - LXQT Desktop - Skrivbord, LXQT - LXQT Masaüstü - Bureau LXQT - Escritorio LXQT + Lxqt Desktop + Lxqt Desktop + Skrivbord, Lxqt + Lxqt Masaüstü + Bureau Lxqt + Escritorio Lxqt preferences-desktop diff --git a/hardware/component.xml b/hardware/component.xml new file mode 100644 index 00000000..3d5a2b3c --- /dev/null +++ b/hardware/component.xml @@ -0,0 +1,3 @@ + + hardware + diff --git a/hardware/disk/component.xml b/hardware/disk/component.xml new file mode 100644 index 00000000..1e279a7b --- /dev/null +++ b/hardware/disk/component.xml @@ -0,0 +1,3 @@ + + hardware.disk + diff --git a/system/base/lvm2/actions.py b/hardware/disk/lvm2/actions.py similarity index 97% rename from system/base/lvm2/actions.py rename to hardware/disk/lvm2/actions.py index b7e66566..2eab4ef5 100644 --- a/system/base/lvm2/actions.py +++ b/hardware/disk/lvm2/actions.py @@ -11,11 +11,13 @@ from pisi.actionsapi import shelltools def builddiet(): pisitools.flags.add("-fno-lto") + shelltools.export("LIBS","-lpthread -luuid") #dietCC = "diet %s %s %s -Os -static" % (get.CC(), get.CFLAGS(), get.LDFLAGS()) dietCC = "%s %s %s -Os -static" % (get.CC(), get.CFLAGS(), get.LDFLAGS()) shelltools.export("CC", dietCC) - + autotools.make("distclean") + autotools.autoreconf("-fi") autotools.configure('ac_cv_lib_dl_dlopen=no \ --with-staticdir="/sbin" \ @@ -31,6 +33,7 @@ def builddiet(): --enable-cmdlib \ --enable-pkgconfig \ --enable-udev_rules \ + --with-systemdsystemunitdir=no \ --enable-udev_sync' % get.CFLAGS()) pisitools.dosed("lib/misc/configure.h","rpl_malloc","malloc") diff --git a/system/base/lvm2/comar/package.py b/hardware/disk/lvm2/comar/package.py similarity index 100% rename from system/base/lvm2/comar/package.py rename to hardware/disk/lvm2/comar/package.py diff --git a/system/base/lvm2/files/lvm2-2.02.105-pthread-pkgconfig.patch b/hardware/disk/lvm2/files/lvm2-2.02.105-pthread-pkgconfig.patch similarity index 100% rename from system/base/lvm2/files/lvm2-2.02.105-pthread-pkgconfig.patch rename to hardware/disk/lvm2/files/lvm2-2.02.105-pthread-pkgconfig.patch diff --git a/system/base/lvm2/files/lvm2-2.02.106-static-pkgconfig-libs.patch b/hardware/disk/lvm2/files/lvm2-2.02.106-static-pkgconfig-libs.patch similarity index 100% rename from system/base/lvm2/files/lvm2-2.02.106-static-pkgconfig-libs.patch rename to hardware/disk/lvm2/files/lvm2-2.02.106-static-pkgconfig-libs.patch diff --git a/system/base/lvm2/files/lvm2-2.02.63-always-make-static-libdm.patch b/hardware/disk/lvm2/files/lvm2-2.02.63-always-make-static-libdm.patch similarity index 100% rename from system/base/lvm2/files/lvm2-2.02.63-always-make-static-libdm.patch rename to hardware/disk/lvm2/files/lvm2-2.02.63-always-make-static-libdm.patch diff --git a/system/base/lvm2/files/lvm2-2.02.92-dynamic-static-ldflags.patch b/hardware/disk/lvm2/files/lvm2-2.02.92-dynamic-static-ldflags.patch similarity index 100% rename from system/base/lvm2/files/lvm2-2.02.92-dynamic-static-ldflags.patch rename to hardware/disk/lvm2/files/lvm2-2.02.92-dynamic-static-ldflags.patch diff --git a/system/base/lvm2/files/tmpfiles.conf b/hardware/disk/lvm2/files/tmpfiles.conf similarity index 100% rename from system/base/lvm2/files/tmpfiles.conf rename to hardware/disk/lvm2/files/tmpfiles.conf diff --git a/hardware/disk/lvm2/pspec.xml b/hardware/disk/lvm2/pspec.xml new file mode 100644 index 00000000..d2f17dbd --- /dev/null +++ b/hardware/disk/lvm2/pspec.xml @@ -0,0 +1,241 @@ + + + + + lvm2 + http://sources.redhat.com/lvm/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + Userland logical volume management tools + LVM2 includes all of the support for handling read/write operations physical and logical volumes. + ftp://sources.redhat.com/pub/lvm2/LVM2.2.02.118.tgz + + libutil-linux-devel + eudev-devel + + + + + + + + device-mapper + + eudev + + Light-weight kernel component can support user-space tools for logical volume management + Device-mapper includes the driver enables the definition of new block devices composed of ranges of sectors of existing devices to define disk partitions or logical volumes. + + /usr/sbin/dmsetup + /usr/lib/libdevmapper.a + /usr/lib/libdevmapper.so* + /lib/udev/rules.d/10-dm.rules + /lib/udev/rules.d/13-dm-disk.rules + /lib/udev/rules.d/95-dm-notify.rules + /usr/share/doc/VERSION_DM + /usr/share/doc/WHATS_NEW_DM + /usr/share/man/man8/dmsetup.8 + + + + + device-mapper-devel + system.devel + Development libraries and headers for device-mapper + Device-mapper-devel contains files needed to develop applications that use the device-mapper libraries. + + device-mapper + eudev-devel + + + /usr/include/libdevmapper.h + /usr/lib/pkgconfig/devmapper.pc + + + + + device-mapper-event + Device-mapper event daemon + This package contains the dmeventd daemon for monitoring the state of device-mapper devices. + + device-mapper + + + /usr/sbin/dmeventd + /usr/lib/libdevmapper-event.a + /usr/lib/libdevmapper-event.so* + /usr/lib/libdevmapper-event-lvm2thin.so + /usr/lib/device-mapper/libdevmapper-event-lvm2thin.so + /usr/share/man/man8/dmeventd.8 + + + + + device-mapper-event-devel + system.devel + Development libraries and headers for the device-mapper event daemon + This contains contains files needed to develop applications that use the device-mapper event library. + + device-mapper-event + + + /usr/include/libdevmapper-event.h + /usr/lib/pkgconfig/devmapper-event.pc + + + + + lvm2 + Userland logical volume management tools + LVM2 includes all of the support for handling read/write operations on physical volumes,creating volume groups from one or more physical volumes and creating one or more logical volumes in volume groups. + + device-mapper + device-mapper-event + libutil-linux + eudev + + + /sbin/lvmconf + /usr/sbin/blkdeactivate + /usr/sbin/fsadm + /usr/sbin/lv* + /usr/sbin/vg* + /usr/sbin/pv* + /usr/lib/liblvm2app.so* + /usr/lib/liblvm2cmd.so* + /usr/lib/libdevmapper-event-lvm2.so* + /usr/lib/device-mapper/libdevmapper-event-lvm2mirror.so + /usr/lib/device-mapper/libdevmapper-event-lvm2snapshot.so + /usr/lib/libdevmapper-event-lvm2mirror.so + /usr/lib/libdevmapper-event-lvm2snapshot.so + /usr/lib/libdevmapper-event-lvm2raid.so + /usr/lib/device-mapper/libdevmapper-event-lvm2raid.so + /etc/lvm + /etc/lvm/archive + /etc/lvm/backup + /etc/lvm/cache + /var/lock/lvm + /lib/udev/rules.d/11-dm-lvm.rules + /usr/lib/tmpfiles.d/lvm2.conf + /usr/share/doc + /usr/share/man/man5/lvm.conf.5 + /usr/share/man/man7 + /usr/share/man/man8/fsadm.8 + /usr/share/man/man8/blkdeactivate.8 + /usr/share/man/man8/*pv* + /usr/share/man/man8/*lv* + /usr/share/man/man8/*vg* + + + tmpfiles.conf + + + System.Package + + + + + lvm2-devel + system.devel + Development libraries and headers + This package contains files needed to develop applications that use the lvm2 libraries. + + libutil-linux-devel + lvm2 + device-mapper-devel + device-mapper-event-devel + + + /usr/include/lvm2cmd.h + /usr/include/lvm2app.h + /usr/lib/pkgconfig/lvm2app.pc + + + + + dietlibc-libdevmapper + system.devel + Static devmapper library built with dietlibc + device mapper contains ioctl library and utilities for use with logical volume management (LVM2) built with dietlibc + + /usr/lib/dietlibc/lib-i386/libdevmapper.a + + + + + device-mapper-static + Staticaly linked Device-mapper library and utility + device mapper contains statically linked libraries and utility for initramfs. + + /sbin/dmsetup.static + + + + + lvm2-static + Staticaly linked Logical Volume Management utilities + Number of utilities for creating, checking, and repairing logical volumes - statically linked for initramfs. + + /sbin/lvm.static + + + + + + 2015-05-02 + 2.02.118 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-09-04 + 2.02.111 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-09 + 2.02.106 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-07 + 2.02.105 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-11-09 + 2.02.103 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-26 + 2.02.98 + Fix dep, release bump. + Serdar Soytetir + kaptanan@pisilinux.org + + + 2012-11-14 + 2.02.98 + First release + PisiLinux Community + admins@pisilinux.org + + + diff --git a/system/base/lvm2/pspec.xml b/hardware/disk/lvm2/pspec.xml.new similarity index 92% rename from system/base/lvm2/pspec.xml rename to hardware/disk/lvm2/pspec.xml.new index 7eef1335..fb194a20 100644 --- a/system/base/lvm2/pspec.xml +++ b/hardware/disk/lvm2/pspec.xml.new @@ -3,7 +3,7 @@ lvm2 - http://sources.redhat.com/lvm/ + https://www.sourceware.org/lvm2/ PisiLinux Community admins@pisilinux.org @@ -12,16 +12,15 @@ app:console Userland logical volume management tools LVM2 includes all of the support for handling read/write operations physical and logical volumes. - ftp://sources.redhat.com/pub/lvm2/LVM2.2.02.111.tgz + ftp://sources.redhat.com/pub/lvm2/LVM2.2.02.118.tgz - libuuid-devel - libblkid-devel + libutil-linux-devel - lvm2-2.02.63-always-make-static-libdm.patch - lvm2-2.02.92-dynamic-static-ldflags.patch - lvm2-2.02.105-pthread-pkgconfig.patch - lvm2-2.02.106-static-pkgconfig-libs.patch + lvm2-make-sockets-static.patch + @@ -97,8 +96,7 @@ device-mapper device-mapper-event - libudev - libblkid + libutil-linux /sbin/lvmconf @@ -186,6 +184,13 @@ + + 2015-04-30 + 2.02.118 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-09-04 2.02.111 diff --git a/system/base/lvm2/translations.xml b/hardware/disk/lvm2/translations.xml similarity index 100% rename from system/base/lvm2/translations.xml rename to hardware/disk/lvm2/translations.xml diff --git a/hardware/disk/mdadm/actions.py b/hardware/disk/mdadm/actions.py new file mode 100644 index 00000000..b264c923 --- /dev/null +++ b/hardware/disk/mdadm/actions.py @@ -0,0 +1,39 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 3. +# See the file http://www.gnu.org/licenses/gpl.txt + +from pisi.actionsapi import get +from pisi.actionsapi import autotools +from pisi.actionsapi import pisitools +from pisi.actionsapi import shelltools + +def builddiet(): + autotools.make("clean") + shelltools.export("CC", "diet %s %s %s %s -DHAVE_STDINT_H -Os -static" % (get.CC(), get.CFLAGS(), get.CXXFLAGS(), get.LDFLAGS())) + autotools.make("mdadm.static") + autotools.make("mdassemble.static") + + pisitools.insinto("/sbin", "mdadm.static") + pisitools.insinto("/sbin", "mdassemble.static") + +def build(): + # fix build with gcc-4.9.0 + pisitools.dosed("Makefile", "(Wall) -Werror", "\\1") + # Not sure about MDASSEMBLE_AUTO=1. Need to investigate. + autotools.make("SYSCONFDIR=/%s MDASSEMBLE_AUTO=1 mdassemble mdadm mdmon" % get.confDIR()) + +def install(): + autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + + # Remove the udev file as its shipped with udev package + pisitools.remove("/lib/udev/rules.d/*") + + # Install config file + pisitools.insinto("/etc", "mdadm.conf-example", "mdadm.conf") + + builddiet() + + pisitools.dodoc("TODO", "ChangeLog", "COPYING", "mdadm.conf-example", "misc/*") + diff --git a/hardware/disk/mdadm/comar/service.py b/hardware/disk/mdadm/comar/service.py new file mode 100644 index 00000000..7f6355f4 --- /dev/null +++ b/hardware/disk/mdadm/comar/service.py @@ -0,0 +1,42 @@ +from comar.service import * + +serviceType = "server" +serviceDesc = _({"en": "RAID monitor daemon", + "tr": "RAID izleme servisi"}) +serviceConf = "mdadm" + +MSG_ERR_STRTSRVC = {"en": "Couldn't start service.Please edit mdadm.conf file.", + "tr": "Servis başlatılamadı.Lütfen mdadm.conf dosyasını düzenleyiniz.", + } + +def check(): + try: + f = file("/etc/mdadm.conf") + confLines = [a.lstrip() for a in f] + confLines = filter(lambda x: not (x.startswith("\#") or x == ""), confLines) + check = False + for line in confLines: + if "MAILADDR" or "PROGRAM" in line.split(): + check = True + if not check: + fail(MSG_ERR_STRTSRVC) + except: + fail(MSG_ERR_STRTSRVC) + finally: + f.close() + +@synchronized +def start(): + check() + startService(command="/sbin/mdadm", + args="--monitor --scan --daemonise --pid-file /run/mdadm.pid %s" % config.get("MDADM_OPTS"), + pidfile="/run/mdadm.pid", + donotify=True) + +@synchronized +def stop(): + stopService(pidfile="/run/mdadm.pid", + donotify=True) + +def status(): + return isServiceRunning("/run/mdadm.pid") diff --git a/hardware/disk/mdadm/files/mdadm.confd b/hardware/disk/mdadm/files/mdadm.confd new file mode 100644 index 00000000..d23368c3 --- /dev/null +++ b/hardware/disk/mdadm/files/mdadm.confd @@ -0,0 +1,7 @@ +# config file for mdadm + +# Misc options to pass to mdadm in monitor mode. +# For more info, run `mdadm --monitor --help` or see +# the mdadm(8) manpage. + +MDADM_OPTS="--syslog" diff --git a/hardware/disk/mdadm/files/mdadm.rules b/hardware/disk/mdadm/files/mdadm.rules new file mode 100644 index 00000000..39fd0cd4 --- /dev/null +++ b/hardware/disk/mdadm/files/mdadm.rules @@ -0,0 +1,8 @@ +# This file causes block devices with Linux RAID (mdadm) signatures to +# automatically cause mdadm to be run. +# See udev(8) for syntax + +SUBSYSTEM=="block", ACTION=="add", ENV{ID_FS_TYPE}=="linux_raid_member", \ + IMPORT{program}="/sbin/mdadm --examine --export $tempnode", \ + RUN+="/bin/bash -c '[ ! -f /dev/.in_sysinit ] && mdadm -I $env{DEVNAME}'" + diff --git a/hardware/disk/mdadm/files/mdadm.service b/hardware/disk/mdadm/files/mdadm.service new file mode 100644 index 00000000..d09ad8e8 --- /dev/null +++ b/hardware/disk/mdadm/files/mdadm.service @@ -0,0 +1,8 @@ +[Unit] +Description=MDADM Event Monitor + +[Service] +ExecStart=/sbin/mdadm --monitor --scan + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/hardware/disk/mdadm/files/mdadm.tmpfiles.conf b/hardware/disk/mdadm/files/mdadm.tmpfiles.conf new file mode 100644 index 00000000..3207ddae --- /dev/null +++ b/hardware/disk/mdadm/files/mdadm.tmpfiles.conf @@ -0,0 +1 @@ +d /run/mdadm 0710 root root - diff --git a/hardware/disk/mdadm/files/scripts/raid-check b/hardware/disk/mdadm/files/scripts/raid-check new file mode 100644 index 00000000..31091bf8 --- /dev/null +++ b/hardware/disk/mdadm/files/scripts/raid-check @@ -0,0 +1,6 @@ +#!/bin/bash + +for dev in `grep "^md.*: active" /proc/mdstat | cut -f 1 -d ' '`; do + echo "repair" > /sys/block/$dev/md/sync_action +done + diff --git a/hardware/disk/mdadm/files/scripts/raid-start.sh b/hardware/disk/mdadm/files/scripts/raid-start.sh new file mode 100644 index 00000000..290b1e89 --- /dev/null +++ b/hardware/disk/mdadm/files/scripts/raid-start.sh @@ -0,0 +1,29 @@ +[[ -f /proc/mdstat ]] || exit 0 + +# Try to make sure the devices exist before we use them +create_devs() { + local node dir minor + for node in $@ ; do + [[ ${node} != /dev/* ]] && node=/dev/${node} + [[ -e ${node} ]] && continue + + dir=${node%/*} + [[ ! -d ${dir} ]] && mkdir -p "${dir}" + + minor=${node##*/} + mknod "${node}" b ${MAJOR} ${minor##*md} &> /dev/null + done +} + +[[ -e /etc/mdadm.conf ]] && mdadm_conf="/etc/mdadm.conf" +if [[ -x /sbin/mdadm && -f ${mdadm_conf} ]] ; then + devs=$(awk '/^[[:space:]]*ARRAY/ { print $2 }' ${mdadm_conf}) + if [[ -n ${devs} ]] ; then + create_devs ${devs} + ebegin "Starting up RAID devices (mdadm)" + output=$(mdadm -As 2>&1) + ret=$? + [[ ${ret} -ne 0 ]] && echo "${output}" + eend ${ret} + fi +fi diff --git a/hardware/disk/mdadm/files/scripts/raid-stop.sh b/hardware/disk/mdadm/files/scripts/raid-stop.sh new file mode 100644 index 00000000..67a3cfe1 --- /dev/null +++ b/hardware/disk/mdadm/files/scripts/raid-stop.sh @@ -0,0 +1,10 @@ +[[ -f /proc/mdstat ]] || exit 0 + +[[ -e /etc/mdadm.conf ]] && mdadm_conf="/etc/mdadm.conf" +if [[ -x /sbin/mdadm && -f ${mdadm_conf} ]] ; then + ebegin "Shutting down RAID devices (mdadm)" + output=$(mdadm -Ss 2>&1) + ret=$? + [[ ${ret} -ne 0 ]] && echo "${output}" + eend ${ret} +fi diff --git a/hardware/disk/mdadm/pspec.xml b/hardware/disk/mdadm/pspec.xml new file mode 100644 index 00000000..665bc572 --- /dev/null +++ b/hardware/disk/mdadm/pspec.xml @@ -0,0 +1,90 @@ + + + + + mdadm + http://www.kernel.org/pub/linux/utils/raid/mdadm + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + Utility to control Linux MD devices (software RAID arrays) + mdadm is used to create, manage, and monitor Linux MD (software RAID) devices. + https://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-3.3.2.tar.xz + + + + mdadm + + /sbin/mdadm + /sbin/mdmon + /lib/udev/rules.d + /usr/lib/tmpfiles.d + /usr/share/man + /usr/share/doc + /etc + + + mdadm.tmpfiles.conf + + scripts/raid-check + + mdadm.confd + + + mdadm.rules + + + System.Service + + + + + mdadm-static + system.base + + /sbin/mdadm.static + /sbin/mdassemble.static + + + + + + 2014-12-13 + 3.3.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-17 + 3.3 + Rebuild. Fixed service.py file + Aydın Demirel + aydin.demirel@pisilinux.org + + + 2014-04-13 + 3.3 + mdadm-static is a part of system.base now. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-31 + 3.3 + Ver. bump, rebuild + Kamil Atlı + admins@pisilinux.org + + + 2012-11-14 + 3.2.6 + First release + PisiLinux Community + admins@pisilinux.org + + + diff --git a/hardware/disk/mdadm/translations.xml b/hardware/disk/mdadm/translations.xml new file mode 100644 index 00000000..2edd3633 --- /dev/null +++ b/hardware/disk/mdadm/translations.xml @@ -0,0 +1,14 @@ + + + + mdadm + MD aygıtlarını (Yazılımsal RAID) denetleme aracı + mdadm Linux MD (yazılımsal RAID) aygıtları yaratmak, yönetmek ve izlemek için kullanılan bir araçtır. + + + + mdadm-static + Statik linklemiş Raid denetleme aracı + mdadm Linux MD (yazılımsal RAID) aygıtları yaratmak, yönetmek ve izlemek için kullanılan bir araçtır. + + diff --git a/hardware/firmware/component.xml b/hardware/firmware/component.xml new file mode 100644 index 00000000..ada4b9d0 --- /dev/null +++ b/hardware/firmware/component.xml @@ -0,0 +1,3 @@ + + hardware.firmware + diff --git a/hardware/firmware/linux-firmware/actions.py b/hardware/firmware/linux-firmware/actions.py new file mode 100644 index 00000000..aaddc341 --- /dev/null +++ b/hardware/firmware/linux-firmware/actions.py @@ -0,0 +1,43 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 3. +# See the file http://www.gnu.org/licenses/gpl.txt + +from pisi.actionsapi import shelltools +from pisi.actionsapi import autotools +from pisi.actionsapi import pisitools +from pisi.actionsapi import get + +WorkDir = "linux-firmware" + +def setup(): + # Remove source files + shelltools.unlink("usbdux/*dux") + shelltools.unlink("*/*.asm") + + # These + a lot of other firmware are shipped within alsa-firmware + for fw in ("ess", "korg", "sb16", "yamaha"): + shelltools.unlinkDir(fw) + +def build(): + autotools.make() + + +def install(): + autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + pisitools.insinto("/lib/firmware", "mix/*") + + # Remove installed and LIC* files from /lib/firmware + pisitools.remove("/lib/firmware/GPL-3") + pisitools.remove("/lib/firmware/LICENCE*") + pisitools.remove("/lib/firmware/LICENSE*") + pisitools.remove("/lib/firmware/configure") + pisitools.remove("/lib/firmware/Makefile") + pisitools.removeDir("/lib/firmware/mix") + #conflict on alsa-firmware + #pisitools.remove("/lib/firmware/ctefx.bin") + pisitools.remove("/lib/firmware/ctspeq.bin") + + # Install LICENSE files + pisitools.dodoc("WHENCE", "LICENCE.*", "LICENSE.*", "GPL-3") diff --git a/hardware/firmware/linux-firmware/files/fw-check b/hardware/firmware/linux-firmware/files/fw-check new file mode 100644 index 00000000..9cbcae9f --- /dev/null +++ b/hardware/firmware/linux-firmware/files/fw-check @@ -0,0 +1,17 @@ +#!/bin/bash + +KVER=$1 + +if [ -z $KVER ]; then + KVER=`uname -r` +fi + +MODPATH=/lib/modules/$KVER + +for mod in `find $MODPATH -name "*.ko"`; do + for fw in `modinfo -F firmware $mod`; do + if [ ! -e "/lib/firmware/$fw" ]; then + echo "`basename $mod` requires $fw which is missing." + fi + done +done diff --git a/hardware/firmware/linux-firmware/files/fw/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq b/hardware/firmware/linux-firmware/files/fw/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq new file mode 100644 index 0000000000000000000000000000000000000000..5b87ae1c2ff733038bdff5eb14af89de82a6c0c2 GIT binary patch literal 13315 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 Yptzc4re?(&o)EF}xBM_L8n40s1+U%BN&o-= literal 0 HcmV?d00001 diff --git a/hardware/firmware/linux-firmware/pspec.xml b/hardware/firmware/linux-firmware/pspec.xml new file mode 100644 index 00000000..febc8e1b --- /dev/null +++ b/hardware/firmware/linux-firmware/pspec.xml @@ -0,0 +1,168 @@ + + + + + linux-firmware + http://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/ + + PisiLinux Community + admins@pisilinux.org + + ipw2100-fw + ipw2200-fw + freedist + GPLv2+ + GPLv2 + MIT + data + Firmware files used by the Linux kernel + linux-firmware contains different firmware files required for some devices to operate correctly. + + http://source.pisilinux.org/1.0/linux-firmware/linux-firmware-20150320.tar.bz2 + http://source.pisilinux.org/erdinc/common-fw.tar.xz + http://source.pisilinux.org/erdinc/firmware-ipw.tar.xz + http://source.pisilinux.org/erdinc/firmware/firmware-nonfreebox-2-tar.bz2 + http://source.pisilinux.org/erdinc/firmware/ar9170.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/ipw2x00-firmware.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/aic94xx-seq.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/zd12x1-firmware.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/accessrunner-firmware.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/rtl8192se-firmware.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/nouveau-1.tar.xz + + fw/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq + + + + + + + + + linux-firmware + + /lib/firmware + /usr/share/doc + + + noDelta + + + + + + 2015-03-26 + 20150320 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-02-14 + 20150214 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-12-16 + 20141216 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-11-07 + 20141107 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-07-23 + 20140603 + Version bump. + Marcin Bojara + marcin.bojara@pisilinux.org + + + 2014-04-02 + 20140316 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-03-01 + 20140217 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-11-30 + 20131013 + Remove unneeded build dep,fix unpack problem. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2013-11-23 + 20131013 + Version bump to 20131013 git. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-09-30 + 20130811 + add update Intel-Bluetooth patchs + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-08-11 + 20130811 + add update patchs + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-07-19 + 20130609 + add update patchs + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-06-09 + 20130609 + bump + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-04-07 + 20130421 + bump + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-03-07 + 20130224 + bump + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2012-12-12 + 20121212 + First release + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + diff --git a/hardware/firmware/linux-firmware/translations.xml b/hardware/firmware/linux-firmware/translations.xml new file mode 100644 index 00000000..50210c1a --- /dev/null +++ b/hardware/firmware/linux-firmware/translations.xml @@ -0,0 +1,8 @@ + + + + linux-firmware + Linux çekirdeği tarafından kullanılan firmware dosyaları + linux-firmware, bazı aygıtların düzgün çalışabilmesi için gerekli firmware dosyalarını içerir. + + diff --git a/kernel/component.xml b/kernel/component.xml new file mode 100644 index 00000000..7adc4a67 --- /dev/null +++ b/kernel/component.xml @@ -0,0 +1,3 @@ + + kernel + diff --git a/kernel/kernel/actions.py b/kernel/kernel/actions.py new file mode 100644 index 00000000..e4aedaef --- /dev/null +++ b/kernel/kernel/actions.py @@ -0,0 +1,36 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 3. +# See the file http://www.gnu.org/licenses/gpl.txt + +from pisi.actionsapi import kerneltools +from pisi.actionsapi import shelltools +from pisi.actionsapi import autotools +from pisi.actionsapi import pisitools +from pisi.actionsapi import get + +NoStrip = ["/lib", "/boot"] + +shelltools.export("KBUILD_BUILD_USER", "pisilinux") +shelltools.export("KBUILD_BUILD_HOST", "buildfarm") +shelltools.export("PYTHONDONTWRITEBYTECODE", "1") + +#cpupower_arch = get.ARCH().replace("i686", "i386") + +def setup(): + kerneltools.configure() + +def build(): + kerneltools.build(debugSymbols=False) + +def install(): + kerneltools.install() + + # Install kernel headers needed for out-of-tree module compilation + kerneltools.installHeaders() + + kerneltools.installLibcHeaders() + + # Generate some module lists to use within mkinitramfs + shelltools.system("./generate-module-list %s/lib/modules/%s" % (get.installDIR(), kerneltools.__getSuffix())) diff --git a/kernel/kernel/comar/package.py b/kernel/kernel/comar/package.py new file mode 100644 index 00000000..60ff125b --- /dev/null +++ b/kernel/kernel/comar/package.py @@ -0,0 +1,22 @@ +#!/usr/bin/python + +import os + +def read_file(path): + with open(path) as f: + return f.read().strip() + +def postInstall(fromVersion, fromRelease, toVersion, toRelease): + gcf = "/boot/grub2/grub.cfg" + if not os.path.isfile(gcf): return + + if os.path.isfile("/etc/mudur/locale"): os.environ["LANG"] = read_file("/etc/mudur/locale").split("\n")[0] + os.environ["PATH"] = "/usr/sbin:/usr/bin:/sbin:/bin" + os.system("grub2-mkconfig -o %s" % gcf) + + # Update GRUB entry + #if os.path.exists("/boot/grub/grub.conf"): + # call("grub", "Boot.Loader", "updateKernelEntry", (KVER, "")) + +def preRemove(): + pass diff --git a/kernel/kernel/files/configs/kernel-i686-config b/kernel/kernel/files/configs/kernel-i686-config new file mode 100644 index 00000000..657c42c3 --- /dev/null +++ b/kernel/kernel/files/configs/kernel-i686-config @@ -0,0 +1,5486 @@ +# +# Automatically generated file; DO NOT EDIT. +# PisiLinux/i386 3.8.5 Kernel Configuration +# +# CONFIG_64BIT is not set +CONFIG_X86_32=y +CONFIG_X86=y +CONFIG_INSTRUCTION_DECODER=y +CONFIG_OUTPUT_FORMAT="elf32-i386" +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_MMU=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_AUTOPROBE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +# CONFIG_ZONE_DMA32 is not set +# CONFIG_AUDIT_ARCH is not set +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_HAVE_INTEL_TXT=y +CONFIG_X86_32_SMP=y +CONFIG_X86_HT=y +CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx" +CONFIG_ARCH_CPU_PROBE_RELEASE=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_HAVE_IRQ_WORK=y +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +CONFIG_DEFAULT_HOSTNAME="(PisiLinux)" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_FHANDLE=y +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_WATCH=y +CONFIG_AUDIT_TREE=y +# CONFIG_AUDIT_LOGINUID_IMMUTABLE is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_IRQ_DOMAIN=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_KTIME_SCALAR=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y +CONFIG_GENERIC_CMOS_UPDATE=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_IRQ_TIME_ACCOUNTING is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_PREEMPT_RCU is not set +CONFIG_RCU_FANOUT=32 +CONFIG_RCU_FANOUT_LEAF=16 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_NOCB_CPU is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_WANTS_PROT_NUMA_PROT_NONE=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_DEBUG is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_SWAP_ENABLED=y +CONFIG_MEMCG_KMEM=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +CONFIG_PID_NS=y +CONFIG_NET_NS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_MM_OWNER=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +# CONFIG_EXPERT is not set +CONFIG_HAVE_UID16=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_KALLSYMS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_HAVE_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +# CONFIG_EMBEDDED is not set +CONFIG_HAVE_PERF_EVENTS=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_PCI_QUIRKS=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=m +CONFIG_OPROFILE_EVENT_MULTIPLEX=y +CONFIG_HAVE_OPROFILE=y +CONFIG_OPROFILE_NMI_TIMER=y +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_OPTPROBES=y +CONFIG_UPROBES=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_KRETPROBES=y +CONFIG_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y +CONFIG_HAVE_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_PERF_EVENTS_NMI=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_GENERIC_SIGALTSTACK=y +CONFIG_CLONE_BACKWARDS=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_THROTTLING=y + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PADATA=y +CONFIG_ASN1=m +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_INLINE_READ_UNLOCK=y +CONFIG_INLINE_READ_UNLOCK_IRQ=y +CONFIG_INLINE_WRITE_UNLOCK=y +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# Processor type and features +# +CONFIG_ZONE_DMA=y +CONFIG_SMP=y +CONFIG_X86_MPPARSE=y +CONFIG_X86_BIGSMP=y +CONFIG_X86_EXTENDED_PLATFORM=y +# CONFIG_X86_WANT_INTEL_MID is not set +# CONFIG_X86_RDC321X is not set +CONFIG_X86_32_NON_STANDARD=y +# CONFIG_X86_NUMAQ is not set +CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y +# CONFIG_STA2X11 is not set +# CONFIG_X86_SUMMIT is not set +# CONFIG_X86_ES7000 is not set +CONFIG_X86_32_IRIS=m +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_PARAVIRT_GUEST=y +CONFIG_PARAVIRT_TIME_ACCOUNTING=y +CONFIG_XEN=y +CONFIG_XEN_DOM0=y +CONFIG_XEN_PRIVILEGED_GUEST=y +CONFIG_XEN_PVHVM=y +CONFIG_XEN_MAX_DOMAIN_MEMORY=64 +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_XEN_DEBUG_FS=y +CONFIG_KVM_GUEST=y +CONFIG_LGUEST_GUEST=y +CONFIG_PARAVIRT=y +# CONFIG_PARAVIRT_SPINLOCKS is not set +CONFIG_PARAVIRT_CLOCK=y +CONFIG_NO_BOOTMEM=y +# CONFIG_MEMTEST is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +CONFIG_M686=y +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MEFFICEON is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MELAN is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +# CONFIG_MCORE2 is not set +# CONFIG_MATOM is not set +CONFIG_X86_GENERIC=y +CONFIG_X86_INTERNODE_CACHE_SHIFT=6 +CONFIG_X86_L1_CACHE_SHIFT=6 +# CONFIG_X86_PPRO_FENCE is not set +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_TSC=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=5 +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR=y +CONFIG_CPU_SUP_TRANSMETA_32=y +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_DMI=y +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +CONFIG_NR_CPUS=32 +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_MCE=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y +# CONFIG_X86_ANCIENT_MCE is not set +CONFIG_X86_MCE_THRESHOLD=y +# CONFIG_X86_MCE_INJECT is not set +CONFIG_X86_THERMAL_VECTOR=y +CONFIG_VM86=y +CONFIG_TOSHIBA=m +CONFIG_I8K=m +# CONFIG_X86_REBOOTFIXUPS is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_X86_MSR=y +CONFIG_X86_CPUID=y +# CONFIG_NOHIGHMEM is not set +# CONFIG_HIGHMEM4G is not set +CONFIG_HIGHMEM64G=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_HIGHMEM=y +CONFIG_X86_PAE=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +# CONFIG_NUMA is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ILLEGAL_POINTER_VALUE=0 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_BALLOON_COMPACTION=y +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_MMU_NOTIFIER=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +CONFIG_MEMORY_FAILURE=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y +# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +CONFIG_HIGHPTE=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_RESERVE_LOW=64 +# CONFIG_MATH_EMULATION is not set +CONFIG_MTRR=y +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +CONFIG_X86_PAT=y +CONFIG_ARCH_USES_PG_UNCACHED=y +CONFIG_ARCH_RANDOM=y +CONFIG_X86_SMAP=y +CONFIG_EFI=y +CONFIG_EFI_STUB=y +CONFIG_SECCOMP=y +CONFIG_CC_STACKPROTECTOR=y +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_HZ_1000=y +CONFIG_HZ=1000 +CONFIG_SCHED_HRTICK=y +CONFIG_KEXEC=y +CONFIG_CRASH_DUMP=y +# CONFIG_KEXEC_JUMP is not set +CONFIG_PHYSICAL_START=0x400000 +CONFIG_RELOCATABLE=y +CONFIG_X86_NEED_RELOCS=y +CONFIG_PHYSICAL_ALIGN=0x400000 +CONFIG_HOTPLUG_CPU=y +# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set +# CONFIG_DEBUG_HOTPLUG_CPU0 is not set +# CONFIG_COMPAT_VDSO is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y + +# +# Power management and ACPI options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_ADVANCED_DEBUG is not set +CONFIG_PM_TEST_SUSPEND=y +CONFIG_PM_SLEEP_DEBUG=y +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +CONFIG_ACPI=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_PROCFS=y +# CONFIG_ACPI_PROCFS_POWER is not set +CONFIG_ACPI_EC_DEBUGFS=m +# CONFIG_ACPI_PROC_EVENT is not set +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_I2C=m +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_IPMI=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PROCESSOR_AGGREGATOR=m +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_INITRD_TABLE_OVERRIDE=y +CONFIG_ACPI_BLACKLIST_YEAR=1999 +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_PCI_SLOT=y +CONFIG_X86_PM_TIMER=y +CONFIG_ACPI_CONTAINER=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_HED=y +CONFIG_ACPI_CUSTOM_METHOD=m +CONFIG_ACPI_BGRT=y +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_PCIEAER=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +# CONFIG_ACPI_APEI_EINJ is not set +# CONFIG_ACPI_APEI_ERST_DEBUG is not set +CONFIG_SFI=y +# CONFIG_APM is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y + +# +# x86 CPU frequency scaling drivers +# +CONFIG_X86_PCC_CPUFREQ=y +CONFIG_X86_ACPI_CPUFREQ=y +CONFIG_X86_ACPI_CPUFREQ_CPB=y +# CONFIG_X86_POWERNOW_K6 is not set +CONFIG_X86_POWERNOW_K7=y +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=y +# CONFIG_X86_GX_SUSPMOD is not set +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +CONFIG_X86_SPEEDSTEP_ICH=y +CONFIG_X86_SPEEDSTEP_SMI=y +CONFIG_X86_P4_CLOCKMOD=y +# CONFIG_X86_CPUFREQ_NFORCE2 is not set +CONFIG_X86_LONGRUN=y +# CONFIG_X86_LONGHAUL is not set +# CONFIG_X86_E_POWERSAVER is not set + +# +# shared options +# +CONFIG_X86_SPEEDSTEP_LIB=y +# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set +CONFIG_CPU_IDLE=y +# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set +CONFIG_INTEL_IDLE=y + +# +# Bus options (PCI etc.) +# +CONFIG_PCI=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GOMMCONFIG is not set +# CONFIG_PCI_GODIRECT is not set +CONFIG_PCI_GOANY=y +CONFIG_PCI_BIOS=y +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_XEN=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_PCIEAER=y +CONFIG_PCIE_ECRC=y +CONFIG_PCIEAER_INJECT=m +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEBUG is not set +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_PERFORMANCE is not set +CONFIG_PCIE_PME=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_PCI_MSI=y +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +CONFIG_PCI_STUB=y +CONFIG_XEN_PCIDEV_FRONTEND=m +CONFIG_HT_IRQ=y +CONFIG_PCI_ATS=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PRI=y +CONFIG_PCI_PASID=y +CONFIG_PCI_IOAPIC=y +CONFIG_PCI_LABEL=y +CONFIG_ISA_DMA_API=y +# CONFIG_ISA is not set +# CONFIG_SCx200 is not set +# CONFIG_ALIX is not set +# CONFIG_NET5501 is not set +# CONFIG_GEOS is not set +CONFIG_AMD_NB=y +CONFIG_PCCARD=y +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m +CONFIG_I82092=m +CONFIG_PCCARD_NONSTATIC=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_COMPAQ=m +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_ACPI=y +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set +# CONFIG_RAPIDIO is not set + +# +# Executable file formats / Emulations +# +CONFIG_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=m +CONFIG_COREDUMP=y +CONFIG_HAVE_ATOMIC_IOMAP=y +CONFIG_HAVE_TEXT_POKE_SMP=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM=y +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +CONFIG_XFRM_STATISTICS=y +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_ARPD=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETLABEL=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +# CONFIG_NF_CT_NETLINK_HELPER is not set +CONFIG_NETFILTER_NETLINK_QUEUE_CT=y +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_NFCT=y +CONFIG_IP_VS_PE_SIP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_PSD=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_NF_NAT_IPV4=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_NF_NAT_IPV6=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=y +CONFIG_IP_SCTP=m +CONFIG_NET_SCTPPROBE=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_RDMA=m +CONFIG_RDS_TCP=m +# CONFIG_RDS_DEBUG is not set +# CONFIG_TIPC is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +# CONFIG_ATM_MPOA is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_HAVE_NET_DSA=y +CONFIG_NET_DSA=m +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_DSA_TAG_TRAILER=y +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +CONFIG_IPDDP_DECAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +CONFIG_WAN_ROUTER=m +# CONFIG_PHONET is not set +CONFIG_IEEE802154=m +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_IPSET=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +CONFIG_DCB=y +CONFIG_DNS_RESOLVER=y +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_BLA=y +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_BATMAN_ADV_DEBUG is not set +CONFIG_OPENVSWITCH=m +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +CONFIG_NETPRIO_CGROUP=m +CONFIG_BQL=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NET_TCPPROBE is not set +CONFIG_NET_DROP_MONITOR=y +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_EPP=m +CONFIG_YAM=m +# CONFIG_CAN is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_NSC_FIR=m +CONFIG_WINBOND_FIR=m +# CONFIG_TOSHIBA_FIR is not set +CONFIG_SMC_IRCC_FIR=m +CONFIG_ALI_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_VIA_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HIDP=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_DEFAULT_PS is not set +CONFIG_CFG80211_DEBUGFS=y +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_MESSAGE_TRACING=y +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +CONFIG_NET_9P=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_9P_RDMA=m +# CONFIG_NET_9P_DEBUG is not set +# CONFIG_CAIF is not set +CONFIG_CEPH_LIB=m +# CONFIG_CEPH_LIB_PRETTYDEBUG is not set +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set +CONFIG_NFC=m +CONFIG_NFC_NCI=m +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y +CONFIG_NFC_LLCP=y + +# +# Near Field Communication (NFC) devices +# +CONFIG_PN544_HCI_NFC=m +CONFIG_NFC_PN533=m + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_EXTRA_FIRMWARE="" +CONFIG_SYS_HYPERVISOR=y +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=m +CONFIG_REGMAP_MMIO=m +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y + +# +# Bus devices +# +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=m +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +# CONFIG_MTD_BLKDEVS is not set +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_SWAP is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_TS5500 is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_LIMIT=20 +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_AX88796 is not set +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_NOT_PC=y +CONFIG_PNP=y +# CONFIG_PNP_DEBUG_MESSAGES is not set + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_FD=m +# CONFIG_PARIDE is not set +CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m +# CONFIG_DRBD_FAULT_INJECTION is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NVME=m +CONFIG_BLK_DEV_OSD=m +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +# CONFIG_BLK_DEV_XIP is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +CONFIG_CDROM_PKTCDVD_WCACHE=y +CONFIG_ATA_OVER_ETH=m +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_BLKDEV_BACKEND=m +CONFIG_VIRTIO_BLK=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_RBD=m + +# +# Misc devices +# +CONFIG_SENSORS_LIS3LV02D=m +# CONFIG_AD525X_DPOT is not set +CONFIG_IBM_ASM=m +# CONFIG_PHANTOM is not set +# CONFIG_INTEL_MID_PTI is not set +# CONFIG_SGI_IOC4 is not set +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +# CONFIG_ICS932S401 is not set +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_CS5535_MFGPT=m +CONFIG_CS5535_MFGPT_DEFAULT_IRQ=7 +CONFIG_CS5535_CLOCK_EVENT_SRC=m +CONFIG_HP_ILO=m +CONFIG_APDS9802ALS=m +CONFIG_ISL29003=m +CONFIG_ISL29020=m +CONFIG_SENSORS_TSL2550=m +# CONFIG_SENSORS_BH1780 is not set +CONFIG_SENSORS_BH1770=m +CONFIG_SENSORS_APDS990X=m +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +CONFIG_VMWARE_BALLOON=m +# CONFIG_BMP085_I2C is not set +CONFIG_PCH_PHUB=m +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_LEGACY=m +CONFIG_EEPROM_MAX6875=m +CONFIG_EEPROM_93CX6=m +CONFIG_CB710_CORE=m +# CONFIG_CB710_DEBUG is not set +CONFIG_CB710_DEBUG_ASSUMPTIONS=y + +# +# Texas Instruments shared transport line discipline +# +CONFIG_SENSORS_LIS3_I2C=m + +# +# Altera FPGA firmware download module +# +CONFIG_ALTERA_STAPL=m +CONFIG_INTEL_MEI=m +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_SCSI_CXGB4_ISCSI=m +CONFIG_SCSI_BNX2_ISCSI=m +CONFIG_SCSI_BNX2X_FCOE=m +CONFIG_BE2ISCSI=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_HPSA=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_3W_SAS=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_SCSI_MVSAS=m +# CONFIG_SCSI_MVSAS_DEBUG is not set +CONFIG_SCSI_MVSAS_TASKLET=y +CONFIG_SCSI_MVUMI=m +# CONFIG_SCSI_DPT_I2O is not set +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_ARCMSR=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_MPT2SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +CONFIG_SCSI_MPT2SAS_LOGGING=y +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPT3SAS_MAX_SGE=128 +CONFIG_SCSI_MPT3SAS_LOGGING=y +CONFIG_SCSI_UFSHCD=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_FLASHPOINT=y +CONFIG_VMWARE_PVSCSI=m +CONFIG_HYPERV_STORAGE=m +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +CONFIG_FCOE=m +CONFIG_FCOE_FNIC=m +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_ISCI=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +CONFIG_PPSCSI=m +CONFIG_PPSCSI_T348=m +CONFIG_PPSCSI_T358=m +CONFIG_PPSCSI_VPI0=m +CONFIG_PPSCSI_VPI2=m +CONFIG_PPSCSI_ONSCSI=m +CONFIG_PPSCSI_SPARCSI=m +CONFIG_PPSCSI_EPSA2=m +CONFIG_PPSCSI_EPST=m +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_IPR is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_TCM_QLA2XXX=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_LPFC_DEBUG_FS is not set +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DC390T=m +# CONFIG_SCSI_NSP32 is not set +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_PMCRAID=m +CONFIG_SCSI_PM8001=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_BFA_FC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_CHELSIO_FCOE=m +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_SCSI_OSD_DPRINT_SENSE=1 +# CONFIG_SCSI_OSD_DEBUG is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_ACPI=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_ACARD_AHCI=m +CONFIG_SATA_SIL24=m +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SX4=m +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +CONFIG_ATA_PIIX=y +CONFIG_SATA_HIGHBANK=m +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m + +# +# PATA SFF controllers with BMDMA +# +CONFIG_PATA_ALI=m +CONFIG_PATA_AMD=m +CONFIG_PATA_ARASAN_CF=m +CONFIG_PATA_ARTOP=m +CONFIG_PATA_ATIIXP=m +CONFIG_PATA_ATP867X=m +CONFIG_PATA_CMD64X=m +CONFIG_PATA_CS5520=m +CONFIG_PATA_CS5530=m +CONFIG_PATA_CS5535=m +CONFIG_PATA_CS5536=m +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=m +CONFIG_PATA_HPT366=m +CONFIG_PATA_HPT37X=m +CONFIG_PATA_HPT3X2N=m +CONFIG_PATA_HPT3X3=m +# CONFIG_PATA_HPT3X3_DMA is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_NINJA32=m +CONFIG_PATA_NS87415=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_OPTIDMA=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_PDC_OLD=m +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RDC=m +# CONFIG_PATA_SC1200 is not set +CONFIG_PATA_SCH=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TOSHIBA=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m + +# +# PIO-only SFF controllers +# +CONFIG_PATA_CMD640_PCI=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NS87410=m +CONFIG_PATA_OPTI=m +CONFIG_PATA_PCMCIA=m +# CONFIG_PATA_RZ1000 is not set + +# +# Generic fallback / legacy drivers +# +CONFIG_PATA_ACPI=m +CONFIG_ATA_GENERIC=m +# CONFIG_PATA_LEGACY is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +# CONFIG_MULTICORE_RAID456 is not set +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=y +CONFIG_DM_DEBUG=y +CONFIG_DM_BUFIO=m +CONFIG_DM_BIO_PRISON=m +CONFIG_DM_PERSISTENT_DATA=m +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=y +CONFIG_DM_THIN_PROVISIONING=m +# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set +CONFIG_DM_MIRROR=y +CONFIG_DM_RAID=m +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_ZERO=y +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +# CONFIG_DM_DELAY is not set +CONFIG_DM_UEVENT=y +CONFIG_DM_FLAKEY=m +CONFIG_DM_VERITY=m +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m +CONFIG_LOOPBACK_TARGET=m +CONFIG_TCM_FC=m +CONFIG_ISCSI_TARGET=m +CONFIG_SBP_TARGET=m +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y + +# +# IEEE 1394 (FireWire) support +# +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIREWIRE_NET=m +CONFIG_FIREWIRE_NOSY=m +# CONFIG_I2O is not set +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_EQUALIZER=m +CONFIG_NET_FC=y +CONFIG_MII=m +CONFIG_IFB=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +CONFIG_NETPOLL_TRAP=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_SUNGEM_PHY=m +# CONFIG_ARCNET is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_TCP=m +# CONFIG_ATM_LANAI is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_IA is not set +# CONFIG_ATM_FORE200E is not set +CONFIG_ATM_HE=m +# CONFIG_ATM_HE_USE_SUNI is not set +CONFIG_ATM_SOLOS=m + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +CONFIG_NET_DSA_MV88E6XXX=m +CONFIG_NET_DSA_MV88E6060=m +CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y +CONFIG_NET_DSA_MV88E6131=m +CONFIG_NET_DSA_MV88E6123_61_65=m +CONFIG_ETHERNET=y +CONFIG_MDIO=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +CONFIG_NET_VENDOR_ADAPTEC=y +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_NET_VENDOR_ALTEON=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_NET_VENDOR_AMD=y +CONFIG_AMD8111_ETH=m +CONFIG_PCNET32=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_NET_VENDOR_ATHEROS=y +CONFIG_ATL2=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL1C=m +CONFIG_ALX=m +CONFIG_NET_CADENCE=y +CONFIG_ARM_AT91_ETHER=m +CONFIG_MACB=m +CONFIG_NET_VENDOR_BROADCOM=y +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +CONFIG_BNX2=m +CONFIG_CNIC=m +CONFIG_TIGON3=m +CONFIG_BNX2X=m +CONFIG_NET_VENDOR_BROCADE=y +CONFIG_BNA=m +CONFIG_NET_CALXEDA_XGMAC=m +CONFIG_NET_VENDOR_CHELSIO=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHELSIO_T4=m +CONFIG_CHELSIO_T4VF=m +CONFIG_NET_VENDOR_CISCO=y +CONFIG_ENIC=m +CONFIG_DNET=m +CONFIG_NET_VENDOR_DEC=y +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_DE2104X_DSL=0 +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_TULIP_NAPI is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_ULI526X=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_NET_VENDOR_DLINK=y +CONFIG_DE600=m +CONFIG_DE620=m +CONFIG_DL2K=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_NET_VENDOR_EMULEX=y +CONFIG_BE2NET=m +CONFIG_NET_VENDOR_EXAR=y +CONFIG_S2IO=m +CONFIG_VXGE=m +# CONFIG_VXGE_DEBUG_TRACE_ALL is not set +# CONFIG_NET_VENDOR_FUJITSU is not set +# CONFIG_NET_VENDOR_HP is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_IGB=m +CONFIG_IGB_DCA=y +CONFIG_IGBVF=m +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_IXGBE_HWMON=y +CONFIG_IXGBE_DCA=y +CONFIG_IXGBE_DCB=y +CONFIG_IXGBEVF=m +# CONFIG_NET_VENDOR_I825XX is not set +CONFIG_IP1000=m +CONFIG_JME=m +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_MVMDIO=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKGE_GENESIS=y +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_NET_VENDOR_MELLANOX=y +CONFIG_MLX4_EN=m +CONFIG_MLX4_EN_DCB=y +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_KSZ884X_PCI=m +CONFIG_NET_VENDOR_MYRI=y +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +CONFIG_FEALNX=m +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NATSEMI=m +CONFIG_NS83820=m +CONFIG_NET_VENDOR_8390=y +CONFIG_PCMCIA_AXNET=m +CONFIG_NE2K_PCI=m +CONFIG_PCMCIA_PCNET=m +CONFIG_NET_VENDOR_NVIDIA=y +CONFIG_FORCEDETH=m +CONFIG_NET_VENDOR_OKI=y +CONFIG_PCH_GBE=m +CONFIG_ETHOC=m +CONFIG_NET_PACKET_ENGINE=y +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +CONFIG_NET_VENDOR_QLOGIC=y +CONFIG_QLA3XXX=m +CONFIG_QLCNIC=m +CONFIG_QLGE=m +CONFIG_NETXEN_NIC=m +CONFIG_NET_VENDOR_REALTEK=y +CONFIG_ATP=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_R8169=m +CONFIG_NET_VENDOR_RDC=y +CONFIG_R6040=m +# CONFIG_NET_VENDOR_SEEQ is not set +CONFIG_NET_VENDOR_SILAN=y +CONFIG_SC92031=m +CONFIG_NET_VENDOR_SIS=y +CONFIG_SIS900=m +CONFIG_SIS190=m +CONFIG_SFC=m +# CONFIG_SFC_MTD is not set +CONFIG_SFC_MCDI_MON=y +CONFIG_SFC_SRIOV=y +CONFIG_NET_VENDOR_SMSC=y +CONFIG_PCMCIA_SMC91C92=m +CONFIG_EPIC100=m +CONFIG_SMSC9420=m +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=m +# CONFIG_STMMAC_PLATFORM is not set +# CONFIG_STMMAC_PCI is not set +# CONFIG_STMMAC_DEBUG_FS is not set +# CONFIG_STMMAC_DA is not set +CONFIG_STMMAC_RING=y +# CONFIG_STMMAC_CHAINED is not set +CONFIG_NET_VENDOR_SUN=y +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_CASSINI=m +CONFIG_NIU=m +CONFIG_NET_VENDOR_TEHUTI=y +CONFIG_TEHUTI=m +CONFIG_NET_VENDOR_TI=y +CONFIG_TLAN=m +CONFIG_NET_VENDOR_VIA=y +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_NET_VENDOR_WIZNET=y +CONFIG_WIZNET_W5100=m +CONFIG_WIZNET_W5300=m +# CONFIG_WIZNET_BUS_DIRECT is not set +# CONFIG_WIZNET_BUS_INDIRECT is not set +CONFIG_WIZNET_BUS_ANY=y +CONFIG_NET_VENDOR_XIRCOM=y +CONFIG_PCMCIA_XIRC2PS=m +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_NET_SB1000 is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +CONFIG_AT803X_PHY=m +CONFIG_AMD_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_BCM87XX_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_REALTEK_PHY=m +CONFIG_NATIONAL_PHY=m +CONFIG_STE10XP=m +CONFIG_LSI_ET1011C_PHY=m +CONFIG_MICREL_PHY=m +CONFIG_FIXED_PHY=y +CONFIG_MDIO_BITBANG=m +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLIP=m +CONFIG_SLHC=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +# CONFIG_SLIP_MODE_SLIP6 is not set + +# +# USB Network Adapters +# +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_WLAN=y +# CONFIG_PCMCIA_RAYCS is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_AIRO is not set +# CONFIG_ATMEL is not set +CONFIG_AT76C50X_USB=m +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +# CONFIG_ADM8211 is not set +CONFIG_MAC80211_HWSIM=m +CONFIG_MWL8K=m +CONFIG_ATH_COMMON=m +CONFIG_ATH_CARDS=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH5K=m +CONFIG_ATH5K_DEBUG=y +# CONFIG_ATH5K_TRACER is not set +CONFIG_ATH5K_PCI=y +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH9K_AHB=y +CONFIG_ATH9K_DEBUGFS=y +# CONFIG_ATH9K_MAC_DEBUG is not set +CONFIG_ATH9K_RATE_CONTROL=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +# CONFIG_CARL9170_DEBUGFS is not set +CONFIG_CARL9170_WPC=y +# CONFIG_CARL9170_HWRNG is not set +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_USB=m +CONFIG_ATH6KL_DEBUG=y +CONFIG_AR5523=m +CONFIG_WIL6210=m +CONFIG_WIL6210_ISR_COR=y +CONFIG_B43=m +CONFIG_B43_BCMA=y +# CONFIG_B43_BCMA_EXTRA is not set +CONFIG_B43_SSB=y +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCMCIA=y +CONFIG_B43_SDIO=y +CONFIG_B43_BCMA_PIO=y +CONFIG_B43_PIO=y +CONFIG_B43_PHY_N=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_PHY_HT=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +CONFIG_B43_DEBUG=y +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_HWRNG=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_BRCMUTIL=m +CONFIG_BRCMSMAC=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_SDIO_OOB=y +CONFIG_BRCMFMAC_USB=y +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +# CONFIG_HOSTAP is not set +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBIPW=m +# CONFIG_LIBIPW_DEBUG is not set +CONFIG_IWLWIFI=m +CONFIG_IWLDVM=m + +# +# Debugging Options +# +CONFIG_IWLWIFI_DEBUG=y +CONFIG_IWLWIFI_DEBUGFS=y +# CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE is not set +# CONFIG_IWLWIFI_DEVICE_TRACING is not set +# CONFIG_IWLWIFI_P2P is not set +CONFIG_IWLEGACY=m +CONFIG_IWL4965=m +CONFIG_IWL3945=m + +# +# iwl3945 / iwl4965 Debugging Options +# +CONFIG_IWLEGACY_DEBUG=y +CONFIG_IWLEGACY_DEBUGFS=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_CS=m +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_MESH=y +# CONFIG_HERMES is not set +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_PCI=m +CONFIG_P54_LEDS=y +CONFIG_RT2X00=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2800PCI=m +CONFIG_RT2800PCI_RT33XX=y +CONFIG_RT2800PCI_RT35XX=y +CONFIG_RT2800PCI_RT53XX=y +CONFIG_RT2800PCI_RT3290=y +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2X00_LIB_DEBUGFS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8192C_COMMON=m +# CONFIG_WL_TI is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MWIFIEX_PCIE=m +CONFIG_MWIFIEX_USB=m + +# +# WiMAX Wireless Broadband devices +# +CONFIG_WIMAX_I2400M=m +CONFIG_WIMAX_I2400M_USB=m +CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 +# CONFIG_WAN is not set +CONFIG_IEEE802154_DRIVERS=m +CONFIG_IEEE802154_FAKEHARD=m +CONFIG_IEEE802154_FAKELB=m +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_VMXNET3=m +CONFIG_HYPERV_NET=m +CONFIG_ISDN=y +CONFIG_ISDN_I4L=m +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +CONFIG_IPPP_FILTER=y +# CONFIG_ISDN_PPP_BSDCOMP is not set +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_TTY_FAX=y + +# +# ISDN feature submodules +# +CONFIG_ISDN_DIVERSION=m + +# +# ISDN4Linux hardware drivers +# + +# +# Passive cards +# +CONFIG_ISDN_DRV_HISAX=m + +# +# D-channel protocol features +# +CONFIG_HISAX_EURO=y +CONFIG_DE_AOC=y +CONFIG_HISAX_NO_SENDCOMPLETE=y +CONFIG_HISAX_NO_LLC=y +CONFIG_HISAX_NO_KEYPAD=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 + +# +# HiSax supported cards +# +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set + +# +# HiSax PCMCIA card service modules +# +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_TELES_CS=m + +# +# HiSax sub driver modules +# +CONFIG_HISAX_ST5481=m +# CONFIG_HISAX_HFCUSB is not set +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_FRITZ_PCIPNP=m + +# +# Active cards +# +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +# CONFIG_CAPI_TRACE is not set +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m + +# +# CAPI hardware drivers +# +CONFIG_CAPI_AVM=y +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_CAPI_EICON=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_CAPI=y +# CONFIG_GIGASET_I4L is not set +# CONFIG_GIGASET_DUMMYLL is not set +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M105=m +CONFIG_GIGASET_M101=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_L1OIP=m + +# +# mISDN hardware drivers +# +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_MISDN_HFCUSB=m +CONFIG_MISDN_AVMFRITZ=m +CONFIG_MISDN_SPEEDFAX=m +CONFIG_MISDN_INFINEON=m +CONFIG_MISDN_W6692=m +CONFIG_MISDN_NETJET=m +CONFIG_MISDN_IPAC=m +CONFIG_MISDN_ISAR=m +CONFIG_ISDN_HDLC=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_SPARSEKMAP=m +# CONFIG_INPUT_MATRIXKMAP is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_CYPRESS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_SENTELIC=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOUSE_SYNAPTICS_I2C=m +CONFIG_MOUSE_SYNAPTICS_USB=m +CONFIG_MOUSE_LMPCM_USB=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +# CONFIG_JOYSTICK_AS5011 is not set +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_WALKERA0701=m +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_HANWANG=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_AD7879=m +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_BU21013=m +CONFIG_TOUCHSCREEN_CYTTSP_CORE=m +CONFIG_TOUCHSCREEN_CYTTSP_I2C=m +CONFIG_TOUCHSCREEN_DYNAPRO=m +CONFIG_TOUCHSCREEN_HAMPSHIRE=m +CONFIG_TOUCHSCREEN_EETI=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_ILI210X=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_ELOUSB=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_WACOM_I2C=m +CONFIG_TOUCHSCREEN_MAX11801=m +CONFIG_TOUCHSCREEN_MCS5000=m +CONFIG_TOUCHSCREEN_MMS114=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m +CONFIG_TOUCHSCREEN_PIXCIR=m +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TSC_SERIO=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_TOUCHSCREEN_ST1232=m +CONFIG_TOUCHSCREEN_TPS6507X=m +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_MMA8450=m +CONFIG_INPUT_MPU3050=m +CONFIG_INPUT_APANEL=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_KXTJ9=m +# CONFIG_INPUT_KXTJ9_POLLED_MODE is not set +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_RETU_PWRBUTTON=m +CONFIG_INPUT_UINPUT=m +# CONFIG_INPUT_PCF8574 is not set +CONFIG_INPUT_PWM_BEEPER=m +# CONFIG_INPUT_ADXL34X is not set +CONFIG_INPUT_CMA3000=m +CONFIG_INPUT_CMA3000_I2C=m +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_SERIO_ALTERA_PS2=m +# CONFIG_SERIO_PS2MULT is not set +CONFIG_SERIO_ARC_PS2=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_ROCKETPORT=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_NOZOMI=m +# CONFIG_ISI is not set +CONFIG_N_HDLC=m +CONFIG_N_GSM=m +# CONFIG_TRACE_SINK is not set +# CONFIG_DEVKMEM is not set +# CONFIG_STALDRV is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_MFD_HSU is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_SCCNXP=m +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_PCH_UART is not set +CONFIG_SERIAL_ARC=m +CONFIG_SERIAL_ARC_NR_PORTS=1 +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m +CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HVC_XEN_FRONTEND=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HW_RANDOM_TPM=m +CONFIG_NVRAM=y +CONFIG_R3964=m +# CONFIG_APPLICOM is not set +CONFIG_SONYPI=m + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_IPWIRELESS=m +CONFIG_MWAVE=m +CONFIG_PC8736x_GPIO=m +CONFIG_NSC_GPIO=m +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +CONFIG_HPET=y +# CONFIG_HPET_MMAP is not set +CONFIG_HANGCHECK_TIMER=m +CONFIG_TCG_TPM=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TIS_I2C_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TELCLOCK=m +CONFIG_DEVPORT=y +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_MUX is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_SMBUS=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# ACPI drivers +# +CONFIG_I2C_SCMI=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EG20T is not set +# CONFIG_I2C_INTEL_MID is not set +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_PCA_PLATFORM=m +# CONFIG_I2C_PXA_PCI is not set +CONFIG_I2C_SIMTEC=m +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_DIOLAN_U2C=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +# CONFIG_I2C_TAOS_EVM is not set +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIPERBOARD=m + +# +# Other I2C/SMBus bus drivers +# +CONFIG_SCx200_ACB=m +CONFIG_I2C_STUB=m +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_SPI is not set +# CONFIG_HSI is not set + +# +# PPS support +# +CONFIG_PPS=m +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_PARPORT=m +CONFIG_PPS_CLIENT_GPIO=m + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=m +CONFIG_DP83640_PHY=m +CONFIG_PTP_1588_CLOCK_PCH=m +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_GPIOLIB is not set +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_MATROX is not set +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS1WM=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2433_CRC=y +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_ISP1704 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +CONFIG_CHARGER_BQ2415X=m +CONFIG_CHARGER_SMB347=m +# CONFIG_POWER_RESET is not set +CONFIG_POWER_AVS=y +CONFIG_HWMON=y +CONFIG_HWMON_VID=m +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7410=m +CONFIG_SENSORS_ADT7411=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_ASC7621=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_K10TEMP=m +CONFIG_SENSORS_FAM15H_POWER=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS620=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HIH6130=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +# CONFIG_SENSORS_JC42 is not set +CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM73=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LTC4151=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LTC4261=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_LM95245=m +CONFIG_SENSORS_MAX16065=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX1668=m +CONFIG_SENSORS_MAX197=m +CONFIG_SENSORS_MAX6639=m +CONFIG_SENSORS_MAX6642=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MCP3021=m +CONFIG_SENSORS_NTC_THERMISTOR=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCF8591=m +CONFIG_PMBUS=m +CONFIG_SENSORS_PMBUS=m +CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_LM25066=m +CONFIG_SENSORS_LTC2978=m +CONFIG_SENSORS_MAX16064=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_ZL6100=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SIS5595=m +# CONFIG_SENSORS_SMM665 is not set +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_EMC1403=m +# CONFIG_SENSORS_EMC2103 is not set +CONFIG_SENSORS_EMC6W201=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SCH56XX_COMMON=m +CONFIG_SENSORS_SCH5627=m +CONFIG_SENSORS_SCH5636=m +CONFIG_SENSORS_ADS1015=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_AMC6821=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP102=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_VIA_CPUTEMP=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83795=m +# CONFIG_SENSORS_W83795_FANCTRL is not set +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_APPLESMC=m + +# +# ACPI drivers +# +CONFIG_SENSORS_ACPI_POWER=m +CONFIG_SENSORS_ATK0110=m +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +CONFIG_FAIR_SHARE=y +CONFIG_STEP_WISE=y +CONFIG_USER_SPACE=y +CONFIG_CPU_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_F71808E_WDT=m +CONFIG_SP5100_TCO=m +CONFIG_GEODE_WDT=m +# CONFIG_SC520_WDT is not set +CONFIG_SBC_FITPC2_WATCHDOG=m +# CONFIG_EUROTECH_WDT is not set +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +# CONFIG_WAFER_WDT is not set +CONFIG_I6300ESB_WDT=m +CONFIG_IE6XX_WDT=m +CONFIG_ITCO_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_HP_WATCHDOG=m +CONFIG_HPWDT_NMI_DECODING=y +# CONFIG_SC1200_WDT is not set +# CONFIG_PC87413_WDT is not set +CONFIG_NV_TCO=m +# CONFIG_60XX_WDT is not set +# CONFIG_SBC8360_WDT is not set +# CONFIG_SBC7240_WDT is not set +# CONFIG_CPU5_WDT is not set +CONFIG_SMSC_SCH311X_WDT=m +# CONFIG_SMSC37B787_WDT is not set +CONFIG_VIA_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83697UG_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_MACHZ_WDT=m +# CONFIG_SBC_EPX_C3_WATCHDOG is not set +CONFIG_XEN_WDT=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_PCMCIAHOST=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +CONFIG_SSB_SDIOHOST=y +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +CONFIG_BCMA=m +CONFIG_BCMA_BLOCKIO=y +CONFIG_BCMA_HOST_PCI_POSSIBLE=y +CONFIG_BCMA_HOST_PCI=y +CONFIG_BCMA_DRIVER_GMAC_CMN=y +# CONFIG_BCMA_DEBUG is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=m +CONFIG_MFD_SM501=m +CONFIG_MFD_RTSX_PCI=m +CONFIG_MFD_TI_AM335X_TSCADC=m +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_ABX500_CORE is not set +CONFIG_MFD_CS5535=m +CONFIG_LPC_SCH=m +CONFIG_LPC_ICH=m +# CONFIG_MFD_RDC321X is not set +# CONFIG_MFD_JANZ_CMODIO is not set +CONFIG_MFD_VX855=m +CONFIG_MFD_WL1273_CORE=m +CONFIG_MFD_VIPERBOARD=m +CONFIG_MFD_RETU=m +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_V4L2=m +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_MEM2MEM_DEV=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_DVB_CORE=m +CONFIG_DVB_NET=y +CONFIG_DVB_MAX_ADAPTERS=8 +CONFIG_DVB_DYNAMIC_MINORS=y + +# +# Media drivers +# +CONFIG_RC_CORE=m +CONFIG_RC_MAP=m +CONFIG_RC_DECODERS=y +CONFIG_LIRC=m +CONFIG_IR_LIRC_CODEC=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_RC5_SZ_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_ENE=m +CONFIG_IR_IMON=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_ITE_CIR=m +CONFIG_IR_FINTEK=m +CONFIG_IR_NUVOTON=m +CONFIG_IR_REDRAT3=m +CONFIG_IR_STREAMZAP=m +CONFIG_IR_WINBOND_CIR=m +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +CONFIG_RC_LOOPBACK=m +CONFIG_IR_GPIO_CIR=m +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_VIDEO_CPIA2=m +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +# CONFIG_USB_SN9C102 is not set + +# +# Analog TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_TLG2300=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_STK1160=m +CONFIG_VIDEO_STK1160_AC97=y + +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_RC=y +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_TM6000=m +CONFIG_VIDEO_TM6000_ALSA=m +CONFIG_VIDEO_TM6000_DVB=m + +# +# Digital TV USB devices +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_FRIIO=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_CYPRESS_FIRMWARE=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_IT913X=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set + +# +# Webcam, TV (analog/digital) USB devices +# +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_EM28XX_RC=m +CONFIG_MEDIA_PCI_SUPPORT=y + +# +# Media capture support +# +CONFIG_VIDEO_MEYE=m + +# +# Media capture/analog TV support +# +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_IVTV_ALSA=m +CONFIG_VIDEO_FB_IVTV=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_MXB=m + +# +# Media capture/analog/hybrid TV support +# +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CX18_ALSA=m +CONFIG_VIDEO_CX23885=m +CONFIG_MEDIA_ALTERA_CI=m +# CONFIG_VIDEO_CX25821 is not set +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_CX88_MPEG=m +CONFIG_VIDEO_BT848=m +CONFIG_DVB_BT8XX=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_RC=y +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7164=m + +# +# Media digital TV PCI Adapters +# +CONFIG_TTPCI_EEPROM=m +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_DM1105=m +CONFIG_DVB_PT1=m +CONFIG_MANTIS_CORE=m +CONFIG_DVB_MANTIS=m +CONFIG_DVB_HOPPER=m +CONFIG_DVB_NGENE=m +CONFIG_DVB_DDBRIDGE=m +# CONFIG_V4L_PLATFORM_DRIVERS is not set +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m +CONFIG_V4L_TEST_DRIVERS=y +# CONFIG_VIDEO_VIVI is not set +# CONFIG_VIDEO_MEM2MEM_TESTDEV is not set + +# +# Supported MMC/SDIO adapters +# +CONFIG_SMS_SDIO_DRV=m +CONFIG_MEDIA_PARPORT_SUPPORT=y +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_W9966=m +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_SI470X=y +CONFIG_USB_SI470X=m +CONFIG_I2C_SI470X=m +CONFIG_USB_MR800=m +CONFIG_USB_DSBR=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_SHARK=m +CONFIG_RADIO_SHARK2=m +CONFIG_I2C_SI4713=m +CONFIG_RADIO_SI4713=m +CONFIG_USB_KEENE=m +CONFIG_RADIO_TEA5764=m +CONFIG_RADIO_SAA7706H=m +# CONFIG_RADIO_TEF6862 is not set +CONFIG_RADIO_WL1273=m + +# +# Texas Instruments WL128x FM driver (ST based) +# + +# +# Supported FireWire (IEEE 1394) Adapters +# +CONFIG_DVB_FIREDTV=m +CONFIG_DVB_FIREDTV_INPUT=y +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_SMS_SIANO_MDTV=m +CONFIG_SMS_SIANO_RC=y +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y + +# +# Media ancillary drivers (tuners, sensors, i2c, frontends) +# +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_IR_I2C=m + +# +# Audio decoders, processors and mixers +# +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_VP27SMPX=m + +# +# RDS decoders +# +CONFIG_VIDEO_SAA6588=m + +# +# Video decoders +# +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_VPX3220=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_CX25840=m + +# +# MPEG video encoders +# +CONFIG_VIDEO_CX2341X=m + +# +# Video encoders +# +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m + +# +# Camera sensor devices +# +CONFIG_VIDEO_MT9V011=m + +# +# Flash devices +# + +# +# Video improvement chips +# +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m + +# +# Miscelaneous helper chips +# +CONFIG_VIDEO_M52790=m + +# +# Sensors used on soc_camera driver +# +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_TUA9001=m + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV6110x=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_TDA18271C2DD=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_MB86A16=m +CONFIG_DVB_TDA10071=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_DRXD=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +CONFIG_DVB_STV0367=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_LG2160=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m +CONFIG_DVB_S5H1411=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_S921=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_MB86A20S=m + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_A8293=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_TDA665x=m +CONFIG_DVB_IX2505V=m +CONFIG_DVB_IT913X_FE=m +CONFIG_DVB_M88RS2000=m +CONFIG_DVB_AF9033=m + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set + +# +# Graphics support +# +CONFIG_AGP=y +CONFIG_AGP_ALI=y +CONFIG_AGP_ATI=y +CONFIG_AGP_AMD=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=y +CONFIG_AGP_NVIDIA=y +CONFIG_AGP_SIS=y +CONFIG_AGP_SWORKS=y +CONFIG_AGP_VIA=y +CONFIG_AGP_EFFICEON=y +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_VGA_SWITCHEROO=y +CONFIG_DRM=m +CONFIG_DRM_USB=m +CONFIG_DRM_KMS_HELPER=m +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_TTM=m +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=m +CONFIG_DRM_RADEON_KMS=y +CONFIG_DRM_NOUVEAU=m +CONFIG_NOUVEAU_DEBUG=5 +CONFIG_NOUVEAU_DEBUG_DEFAULT=3 +CONFIG_DRM_NOUVEAU_BACKLIGHT=y + +# +# I2C encoder or helper chips +# +CONFIG_DRM_I2C_CH7006=m +CONFIG_DRM_I2C_SIL164=m +# CONFIG_DRM_I810 is not set +CONFIG_DRM_I915=m +CONFIG_DRM_I915_KMS=y +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set +CONFIG_DRM_VIA=m +# CONFIG_DRM_SAVAGE is not set +CONFIG_DRM_VMWGFX=m +CONFIG_DRM_VMWGFX_FBCON=y +CONFIG_DRM_GMA500=m +# CONFIG_DRM_GMA600 is not set +CONFIG_DRM_GMA3600=y +CONFIG_DRM_UDL=m +CONFIG_DRM_AST=m +CONFIG_DRM_MGAG200=m +CONFIG_DRM_CIRRUS_QEMU=m +# CONFIG_STUB_POULSBO is not set +CONFIG_VGASTATE=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_DDC=m +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +# CONFIG_FB_WMT_GE_ROPS is not set +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=m +# CONFIG_FB_UVESA is not set +CONFIG_FB_VESA=y +CONFIG_FB_EFI=y +# CONFIG_FB_N411 is not set +# CONFIG_FB_HGA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +CONFIG_FB_I810=m +CONFIG_FB_I810_GTF=y +CONFIG_FB_I810_I2C=y +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIA is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +CONFIG_FB_VOODOO1=m +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_LX=y +CONFIG_FB_GEODE_GX=y +# CONFIG_FB_GEODE_GX1 is not set +# CONFIG_FB_TMIO is not set +# CONFIG_FB_SM501 is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +CONFIG_FB_VIRTUAL=m +CONFIG_XEN_FBDEV_FRONTEND=y +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +# CONFIG_EXYNOS_VIDEO is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_PLATFORM=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_PWM=m +CONFIG_BACKLIGHT_APPLE=m +# CONFIG_BACKLIGHT_SAHARA is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +CONFIG_BACKLIGHT_LM3630=m +CONFIG_BACKLIGHT_LM3639=m +CONFIG_BACKLIGHT_LP855X=m + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_VGACON_SOFT_SCROLLBACK=y +CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64 +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_KCTL_JACK=y +CONFIG_SND_DMA_SGBUF=y +CONFIG_SND_RAWMIDI_SEQ=m +CONFIG_SND_OPL3_LIB_SEQ=m +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +CONFIG_SND_EMU10K1_SEQ=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_PCSP=m +CONFIG_SND_DUMMY=m +CONFIG_SND_ALOOP=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_BT_SCO=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_SB_COMMON=m +CONFIG_SND_SB16_DSP=m +CONFIG_SND_TEA575X=m +CONFIG_SND_PCI=y +CONFIG_SND_AD1889=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ASIHPI=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +# CONFIG_SND_AW2 is not set +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_OXYGEN=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5530=m +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_CTXFI=m +CONFIG_SND_DARLA20=m +CONFIG_SND_GINA20=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_GINA24=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MONA=m +CONFIG_SND_MIA=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIOX=m +CONFIG_SND_INDIGODJX=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_ES1968_INPUT=y +CONFIG_SND_ES1968_RADIO=y +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_PREALLOC_SIZE=4096 +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_RECONFIG=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INPUT_BEEP_MODE=0 +CONFIG_SND_HDA_INPUT_JACK=y +CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_CODEC_HDMI=y +CONFIG_SND_HDA_CODEC_CIRRUS=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_CA0110=y +CONFIG_SND_HDA_CODEC_CA0132=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_GENERIC=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_LOLA=m +CONFIG_SND_LX6464ES=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_INPUT=y +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SIS7019=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRTUOSO=m +CONFIG_SND_VX222=m +CONFIG_SND_YMFPCI=m +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_US122L=m +CONFIG_SND_USB_6FIRE=m +CONFIG_SND_FIREWIRE=y +CONFIG_SND_FIREWIRE_LIB=m +CONFIG_SND_FIREWIRE_SPEAKERS=m +CONFIG_SND_ISIGHT=m +CONFIG_SND_SCS1X=m +CONFIG_SND_PCMCIA=y +CONFIG_SND_VXPOCKET=m +CONFIG_SND_PDAUDIOCF=m +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m + +# +# HID support +# +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +CONFIG_HID_ACRUX=m +CONFIG_HID_ACRUX_FF=y +CONFIG_HID_APPLE=y +CONFIG_HID_AUREAL=m +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_PRODIKEYS=m +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +CONFIG_HID_EMS_FF=m +CONFIG_HID_ELECOM=m +CONFIG_HID_EZKEY=y +CONFIG_HID_HOLTEK=m +CONFIG_HOLTEK_FF=y +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m +CONFIG_HID_GYRATION=m +CONFIG_HID_ICADE=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LCPOWER=m +CONFIG_HID_LENOVO_TPKBD=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_LOGITECH_DJ=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_LOGIWHEELS_FF=y +CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_MULTITOUCH=m +CONFIG_HID_NTRIG=y +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_PANTHERLORD_FF=y +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_PICOLCD_FB=y +CONFIG_HID_PICOLCD_BACKLIGHT=y +CONFIG_HID_PICOLCD_LCD=y +CONFIG_HID_PICOLCD_LEDS=y +CONFIG_HID_PICOLCD_CIR=y +CONFIG_HID_PRIMAX=m +CONFIG_HID_PS3REMOTE=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAITEK=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SPEEDLINK=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_GREENASIA=m +CONFIG_GREENASIA_FF=y +CONFIG_HID_HYPERV_MOUSE=m +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TIVO=m +CONFIG_HID_TOPSEED=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_THRUSTMASTER_FF=y +CONFIG_HID_WACOM=m +CONFIG_HID_WIIMOTE=m +CONFIG_HID_WIIMOTE_EXT=y +CONFIG_HID_ZEROPLUS=m +CONFIG_ZEROPLUS_FF=y +CONFIG_HID_ZYDACRON=m +CONFIG_HID_SENSOR_HUB=m + +# +# USB HID support +# +CONFIG_USB_HID=y +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +CONFIG_I2C_HID=m +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DYNAMIC_MINORS=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +CONFIG_USB_MON=y +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=y +# CONFIG_USB_XHCI_HCD_DEBUGGING is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_ISP1362_HCD=m +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_PLATFORM is not set +# CONFIG_USB_EHCI_HCD_PLATFORM is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_U132_HCD=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_HCD_ISO=y +# CONFIG_USB_SL811_CS is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_WHCI_HCD=m +CONFIG_USB_HWA_HCD=m +# CONFIG_USB_HCD_BCMA is not set +# CONFIG_USB_HCD_SSB is not set +# CONFIG_USB_CHIPIDEA is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_REALTEK_AUTOPM=y +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m + +# +# USB port drivers +# +CONFIG_USB_USS720=m +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +# CONFIG_USB_SERIAL_METRO is not set +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7715_PARPORT=y +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_SIEMENS_MPI=m +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_VIVOPAY_SERIAL=m +CONFIG_USB_SERIAL_ZIO=m +CONFIG_USB_SERIAL_ZTE=m +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +# CONFIG_USB_RIO500 is not set +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_LED=m +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +# CONFIG_USB_TEST is not set +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m +CONFIG_USB_EZUSB_FX2=m + +# +# USB Physical Layer drivers +# +CONFIG_USB_ISP1301=m +CONFIG_USB_RCAR_PHY=m +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m +# CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# +CONFIG_USB_OTG_UTILS=y +CONFIG_NOP_USB_XCEIV=m +CONFIG_UWB=m +CONFIG_UWB_HWA=m +CONFIG_UWB_WHCI=m +CONFIG_UWB_I1480U=m +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +# CONFIG_MMC_CLKGATE is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=m +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_RICOH_MMC=y +CONFIG_MMC_SDHCI_ACPI=m +CONFIG_MMC_SDHCI_PLTFM=m +CONFIG_MMC_WBSD=m +CONFIG_MMC_TIFM_SD=m +CONFIG_MMC_SDRICOH_CS=m +CONFIG_MMC_CB710=m +CONFIG_MMC_VIA_SDMMC=m +CONFIG_MMC_VUB300=m +CONFIG_MMC_USHC=m +CONFIG_MMC_REALTEK_PCI=m +CONFIG_MEMSTICK=m +# CONFIG_MEMSTICK_DEBUG is not set + +# +# MemoryStick drivers +# +# CONFIG_MEMSTICK_UNSAFE_RESUME is not set +CONFIG_MSPRO_BLOCK=m + +# +# MemoryStick Host Controller Drivers +# +CONFIG_MEMSTICK_TIFM_MS=m +CONFIG_MEMSTICK_JMICRON_38X=m +CONFIG_MEMSTICK_R592=m +CONFIG_MEMSTICK_REALTEK_PCI=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_LM3530=m +CONFIG_LEDS_LM3642=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_LP5521=m +CONFIG_LEDS_LP5523=m +CONFIG_LEDS_CLEVO_MAIL=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_PCA9633=m +CONFIG_LEDS_BD2802=m +CONFIG_LEDS_INTEL_SS4200=m +CONFIG_LEDS_DELL_NETBOOKS=m +CONFIG_LEDS_TCA6507=m +CONFIG_LEDS_LM355x=m +CONFIG_LEDS_OT200=m +CONFIG_LEDS_BLINKM=m +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_ACCESSIBILITY=y +CONFIG_A11Y_BRAILLE_CONSOLE=y +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_AMSO1100=m +# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_CXGB4=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_INFINIBAND_NES=m +# CONFIG_INFINIBAND_NES_DEBUG is not set +# CONFIG_INFINIBAND_OCRDMA is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_SRPT=m +CONFIG_INFINIBAND_ISER=m +CONFIG_EDAC=y +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_DECODE_MCE=m +CONFIG_EDAC_MCE_INJ=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_AMD76X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I3200=m +CONFIG_EDAC_X38=m +CONFIG_EDAC_I5400=m +CONFIG_EDAC_I7CORE=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_R82600=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I7300=m +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_BQ32K=m +# CONFIG_RTC_DRV_S35390A is not set +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RX8025=m +CONFIG_RTC_DRV_EM3027=m +CONFIG_RTC_DRV_RV3029C2=m + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1511=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_STK17TA8=m +# CONFIG_RTC_DRV_M48T86 is not set +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_MSM6242=m +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_RP5C01=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_DS2404=m + +# +# on-CPU RTC drivers +# +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +# CONFIG_INTEL_MID_DMAC is not set +CONFIG_INTEL_IOATDMA=m +# CONFIG_TIMB_DMA is not set +CONFIG_PCH_DMA=m +CONFIG_DMA_ENGINE=y + +# +# DMA Clients +# +CONFIG_NET_DMA=y +CONFIG_ASYNC_TX_DMA=y +# CONFIG_DMATEST is not set +CONFIG_DCA=m +CONFIG_AUXDISPLAY=y +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_UIO=m +CONFIG_UIO_CIF=m +# CONFIG_UIO_PDRV is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +CONFIG_UIO_DMEM_GENIRQ=m +CONFIG_UIO_AEC=m +CONFIG_UIO_SERCOS3=m +CONFIG_UIO_PCI_GENERIC=m +# CONFIG_UIO_NETX is not set +CONFIG_VFIO_IOMMU_TYPE1=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VIRTIO=y + +# +# Virtio drivers +# +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_MMIO=m +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_HYPERV=m +CONFIG_HYPERV_UTILS=m +CONFIG_HYPERV_BALLOON=m + +# +# Xen driver support +# +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SELFBALLOONING=y +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XEN_DEV_EVTCHN=m +CONFIG_XEN_BACKEND=y +CONFIG_XENFS=m +CONFIG_XEN_COMPAT_XENFS=y +CONFIG_XEN_SYS_HYPERVISOR=y +CONFIG_XEN_XENBUS_FRONTEND=y +CONFIG_XEN_GNTDEV=m +CONFIG_XEN_GRANT_DEV_ALLOC=m +CONFIG_SWIOTLB_XEN=y +CONFIG_XEN_TMEM=y +CONFIG_XEN_PCIDEV_BACKEND=m +CONFIG_XEN_PRIVCMD=m +CONFIG_XEN_ACPI_PROCESSOR=m +CONFIG_XEN_HAVE_PVMMU=y +CONFIG_STAGING=y +# CONFIG_ET131X is not set +# CONFIG_SLICOSS is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_W35UND is not set +# CONFIG_PRISM2_USB is not set +# CONFIG_ECHO is not set +# CONFIG_COMEDI is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_PANEL is not set +# CONFIG_R8187SE is not set +# CONFIG_RTL8192U is not set +# CONFIG_RTLLIB is not set +CONFIG_R8712U=m +# CONFIG_RTS5139 is not set +# CONFIG_TRANZPORT is not set +# CONFIG_IDE_PHISON is not set +# CONFIG_LINE6_USB is not set +# CONFIG_USB_SERIAL_QUATECH2 is not set +# CONFIG_VT6655 is not set +# CONFIG_VT6656 is not set +# CONFIG_DX_SEP is not set +# CONFIG_ZSMALLOC is not set +# CONFIG_WLAGS49_H2 is not set +# CONFIG_WLAGS49_H25 is not set +# CONFIG_FB_SM7XX is not set +CONFIG_CRYSTALHD=m +# CONFIG_FB_XGI is not set +# CONFIG_ACPI_QUICKSTART is not set +# CONFIG_USB_ENESTORAGE is not set +# CONFIG_BCM_WIMAX is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +CONFIG_STAGING_MEDIA=y +# CONFIG_DVB_AS102 is not set +# CONFIG_DVB_CXD2099 is not set +# CONFIG_VIDEO_DT3155 is not set +# CONFIG_VIDEO_GO7007 is not set +# CONFIG_SOLO6X10 is not set +CONFIG_LIRC_STAGING=y +CONFIG_LIRC_BT829=m +CONFIG_LIRC_IGORPLUGUSB=m +CONFIG_LIRC_IMON=m +CONFIG_LIRC_PARALLEL=m +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_LIRC_SERIAL_TRANSMITTER=y +CONFIG_LIRC_SIR=m +CONFIG_LIRC_ZILOG=m + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_USB_WPAN_HCD is not set +# CONFIG_WIMAX_GDM72XX is not set +CONFIG_CSR_WIFI=m +CONFIG_ZCACHE2=y +CONFIG_NET_VENDOR_SILICOM=y +CONFIG_SBYPASS=m +CONFIG_BPCTL=m +CONFIG_CED1401=m +CONFIG_DGRP=m +CONFIG_SB105X=m +CONFIG_FIREWIRE_SERIAL=m +CONFIG_X86_PLATFORM_DEVICES=y +CONFIG_ACER_WMI=m +CONFIG_ACERHDF=m +CONFIG_ASUS_LAPTOP=m +CONFIG_DELL_LAPTOP=m +CONFIG_DELL_WMI=m +CONFIG_DELL_WMI_AIO=m +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +CONFIG_FUJITSU_TABLET=m +CONFIG_AMILO_RFKILL=m +CONFIG_TC1100_WMI=m +CONFIG_HP_ACCEL=m +CONFIG_HP_WMI=m +CONFIG_MSI_LAPTOP=m +CONFIG_PANASONIC_LAPTOP=m +CONFIG_COMPAL_LAPTOP=m +CONFIG_SONY_LAPTOP=m +CONFIG_SONYPI_COMPAT=y +CONFIG_IDEAPAD_LAPTOP=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y +# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set +# CONFIG_THINKPAD_ACPI_DEBUG is not set +# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_SENSORS_HDAPS=m +# CONFIG_INTEL_MENLOW is not set +CONFIG_EEEPC_LAPTOP=m +CONFIG_ASUS_WMI=m +CONFIG_ASUS_NB_WMI=m +CONFIG_EEEPC_WMI=m +CONFIG_ACPI_WMI=m +CONFIG_MSI_WMI=m +CONFIG_TOPSTAR_LAPTOP=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_TOSHIBA_BT_RFKILL=m +CONFIG_ACPI_CMPC=m +CONFIG_INTEL_IPS=m +# CONFIG_IBM_RTL is not set +CONFIG_XO15_EBOOK=m +CONFIG_SAMSUNG_LAPTOP=m +CONFIG_MXM_WMI=m +CONFIG_INTEL_OAKTRAIL=m +CONFIG_SAMSUNG_Q10=m +CONFIG_APPLE_GMUX=m +CONFIG_SHUTTLE_WMI=m +CONFIG_FSAM7400=m +CONFIG_FSAM7440=m + +# +# Hardware Spinlock drivers +# +CONFIG_CLKSRC_I8253=y +CONFIG_CLKEVT_I8253=y +CONFIG_I8253_LOCK=y +CONFIG_CLKBLD_I8253=y +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y +CONFIG_DMAR_TABLE=y +CONFIG_INTEL_IOMMU=y +# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_FLOPPY_WA=y + +# +# Remoteproc drivers (EXPERIMENTAL) +# +CONFIG_REMOTEPROC=m +CONFIG_STE_MODEM_RPROC=m + +# +# Rpmsg drivers (EXPERIMENTAL) +# +# CONFIG_VIRT_DRIVERS is not set +# CONFIG_PM_DEVFREQ is not set +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_VME_BUS is not set +CONFIG_PWM=y +# CONFIG_IPACK_BUS is not set + +# +# Firmware Drivers +# +CONFIG_EDD=m +# CONFIG_EDD_OFF is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_EFI_VARS=y +CONFIG_EFI_VARS_PSTORE=y +CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m +CONFIG_DMIID=y +CONFIG_DMI_SYSFS=y +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_IBFT=m +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT23=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +# CONFIG_OCFS2_FS_STATS is not set +# CONFIG_OCFS2_DEBUG_MASKLOG is not set +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +CONFIG_NILFS2_FS=m +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +# CONFIG_QUOTA_DEBUG is not set +CONFIG_QUOTA_TREE=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAYFS_FS=m +CONFIG_GENERIC_ACL=y + +# +# Caches +# +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +CONFIG_FSCACHE_OBJECT_LIST=y +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_VMCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_CONFIGFS_FS=y +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +CONFIG_MINIX_FS=m +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_FTRACE=y +CONFIG_PSTORE_RAM=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +# CONFIG_EXOFS_FS is not set +CONFIG_F2FS_FS=m +CONFIG_F2FS_STAT_FS=y +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_FS_POSIX_ACL=y +CONFIG_ORE=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V2=m +CONFIG_NFS_V3=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +CONFIG_PNFS_FILE_LAYOUT=m +CONFIG_PNFS_BLOCK=m +CONFIG_PNFS_OBJLAYOUT=m +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" +CONFIG_NFS_FSCACHE=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFS_DEBUG=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUNRPC_SWAP=y +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_SUNRPC_DEBUG=y +CONFIG_CEPH_FS=m +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +# CONFIG_CIFS_STATS2 is not set +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_ACL=y +CONFIG_CIFS_DEBUG=y +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_DFS_UPCALL=y +# CONFIG_CIFS_SMB2 is not set +CONFIG_CIFS_FSCACHE=y +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_SMALLDOS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +# CONFIG_AFS_FS is not set +CONFIG_9P_FS=m +CONFIG_9P_FSCACHE=y +CONFIG_9P_FS_POSIX_ACL=y +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +CONFIG_DLM_DEBUG=y + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_PRINTK_TIME=y +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +CONFIG_STRIP_ASM_SYMS=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +CONFIG_HEADERS_CHECK=y +CONFIG_DEBUG_SECTION_MISMATCH=y +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_SPARSE_RCU_POINTER=y +CONFIG_STACKTRACE=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_LKDTM is not set +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_EVENT_POWER_TRACING_DEPRECATED=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +# CONFIG_FUNCTION_GRAPH_TRACER is not set +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_SCHED_TRACER=y +CONFIG_FTRACE_SYSCALLS=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_KPROBE_EVENT=y +CONFIG_UPROBE_EVENT=y +CONFIG_PROBE_EVENTS=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_FUNCTION_PROFILER=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_MMIOTRACE is not set +CONFIG_RING_BUFFER_BENCHMARK=m +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set +# CONFIG_BUILD_DOCSRC is not set +CONFIG_DYNAMIC_DEBUG=y +# CONFIG_DMA_API_DEBUG is not set +CONFIG_ATOMIC64_SELFTEST=y +CONFIG_ASYNC_RAID6_TEST=m +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_KMEMCHECK=y +CONFIG_TEST_KSTRTOX=y +CONFIG_STRICT_DEVMEM=y +# CONFIG_X86_VERBOSE_BOOTUP is not set +CONFIG_EARLY_PRINTK=y +CONFIG_EARLY_PRINTK_DBGP=y +CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_DOUBLEFAULT=y +# CONFIG_IOMMU_STRESS is not set +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=0 +CONFIG_OPTIMIZE_INLINING=y + +# +# Security options +# +CONFIG_KEYS=y +CONFIG_TRUSTED_KEYS=m +CONFIG_ENCRYPTED_KEYS=m +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +CONFIG_SECURITY_PATH=y +CONFIG_INTEL_TXT=y +# CONFIG_SECURITY_SELINUX is not set +# CONFIG_SECURITY_SMACK is not set +CONFIG_SECURITY_TOMOYO=y +CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048 +CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024 +# CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set +CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init" +CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_YAMA is not set +# CONFIG_IMA is not set +CONFIG_DEFAULT_SECURITY_TOMOYO=y +# CONFIG_DEFAULT_SECURITY_APPARMOR is not set +# CONFIG_DEFAULT_SECURITY_DAC is not set +CONFIG_DEFAULT_SECURITY="tomoyo" +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA=y +CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA=y +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=m +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_ABLK_HELPER_X86=y +CONFIG_CRYPTO_GLUE_HELPER_X86=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=y + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_LRW=y +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=y + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_586=y +CONFIG_CRYPTO_AES_NI_INTEL=y +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_BLOWFISH_COMMON=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST_COMMON=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SALSA20_586=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SERPENT_SSE2_586=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH_586=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ZLIB=m +CONFIG_CRYPTO_LZO=y + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_ASYMMETRIC_KEY_TYPE=m +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m +CONFIG_PUBLIC_KEY_ALGO_RSA=m +CONFIG_X509_CERTIFICATE_PARSER=m +CONFIG_HAVE_KVM=y +CONFIG_HAVE_KVM_IRQCHIP=y +CONFIG_HAVE_KVM_EVENTFD=y +CONFIG_KVM_APIC_ARCHITECTURE=y +CONFIG_KVM_MMIO=y +CONFIG_KVM_ASYNC_PF=y +CONFIG_HAVE_KVM_MSI=y +CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_INTEL=m +CONFIG_KVM_AMD=m +CONFIG_KVM_MMU_AUDIT=y +CONFIG_VHOST_NET=m +CONFIG_TCM_VHOST=m +CONFIG_LGUEST=m +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=m +CONFIG_BITREVERSE=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_PERCPU_RWSEM=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_CRC8=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_BTREE=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_LRU_CACHE=m +CONFIG_AVERAGE=y +CONFIG_CLZ_TAB=y +CONFIG_CORDIC=m +# CONFIG_DDR is not set +CONFIG_MPILIB=m +CONFIG_OID_REGISTRY=m + +# +# Unofficial 3rd party kernel additions +# +CONFIG_ACERHK=y +CONFIG_NDISWRAPPER=m +# CONFIG_AES2501 is not set + +# +# RF Switch +# +CONFIG_RFSWITCH=m +CONFIG_AVERATEC_5100P=m +CONFIG_PACKARDBELL_E5=m +CONFIG_VIAHSS=m diff --git a/kernel/kernel/files/configs/kernel-x86_64-config b/kernel/kernel/files/configs/kernel-x86_64-config new file mode 100644 index 00000000..52dd691a --- /dev/null +++ b/kernel/kernel/files/configs/kernel-x86_64-config @@ -0,0 +1,6337 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/x86_64 4.0.3 Kernel Configuration +# +CONFIG_64BIT=y +CONFIG_X86_64=y +CONFIG_X86=y +CONFIG_INSTRUCTION_DECODER=y +CONFIG_PERF_EVENTS_INTEL_UNCORE=y +CONFIG_OUTPUT_FORMAT="elf64-x86-64" +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_MMU=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_SG_DMA_LENGTH=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ZONE_DMA32=y +CONFIG_AUDIT_ARCH=y +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_HAVE_INTEL_TXT=y +CONFIG_X86_64_SMP=y +CONFIG_X86_HT=y +CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_BZIP2=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_BZIP2 is not set +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_DEFAULT_HOSTNAME="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_FHANDLE=y +# CONFIG_USELIB is not set +CONFIG_AUDIT=y +CONFIG_HAVE_ARCH_AUDITSYSCALL=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_WATCH=y +CONFIG_AUDIT_TREE=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_LEGACY_ALLOC_HWIRQ=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_IRQ_CHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_GENERIC_MSI_IRQ=y +# CONFIG_IRQ_DOMAIN_DEBUG is not set +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y +CONFIG_GENERIC_CMOS_UPDATE=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +CONFIG_SRCU=y +# CONFIG_TASKS_RCU is not set +CONFIG_RCU_STALL_COMMON=y +CONFIG_CONTEXT_TRACKING=y +CONFIG_RCU_USER_QS=y +CONFIG_CONTEXT_TRACKING_FORCE=y +CONFIG_RCU_FANOUT=64 +CONFIG_RCU_FANOUT_LEAF=16 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_RCU_FAST_NO_HZ is not set +# CONFIG_TREE_RCU_TRACE is not set +CONFIG_RCU_KTHREAD_PRIO=0 +CONFIG_RCU_NOCB_CPU=y +# CONFIG_RCU_NOCB_CPU_NONE is not set +# CONFIG_RCU_NOCB_CPU_ZERO is not set +CONFIG_RCU_NOCB_CPU_ALL=y +CONFIG_BUILD_BIN2C=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y +CONFIG_ARCH_SUPPORTS_INT128=y +# CONFIG_NUMA_BALANCING is not set +CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_PAGE_COUNTER=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_MEMCG_SWAP_ENABLED=y +CONFIG_MEMCG_KMEM=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_BLK_CGROUP=y +# CONFIG_DEBUG_BLK_CGROUP is not set +# CONFIG_CHECKPOINT_RESTORE is not set +CONFIG_NAMESPACES=y +CONFIG_UTS_NS=y +CONFIG_IPC_NS=y +# CONFIG_USER_NS is not set +CONFIG_PID_NS=y +CONFIG_NET_NS=y +CONFIG_SCHED_AUTOGROUP=y +# CONFIG_SYSFS_DEPRECATED is not set +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +CONFIG_RD_BZIP2=y +CONFIG_RD_LZMA=y +CONFIG_RD_XZ=y +CONFIG_RD_LZO=y +CONFIG_RD_LZ4=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_HAVE_UID16=y +CONFIG_SYSCTL_EXCEPTION_TRACE=y +CONFIG_HAVE_PCSPKR_PLATFORM=y +CONFIG_BPF=y +# CONFIG_EXPERT is not set +CONFIG_UID16=y +CONFIG_SGETMASK_SYSCALL=y +CONFIG_SYSFS_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +# CONFIG_BPF_SYSCALL is not set +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_ADVISE_SYSCALLS=y +CONFIG_PCI_QUIRKS=y +# CONFIG_EMBEDDED is not set +CONFIG_HAVE_PERF_EVENTS=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=m +CONFIG_OPROFILE_EVENT_MULTIPLEX=y +CONFIG_HAVE_OPROFILE=y +CONFIG_OPROFILE_NMI_TIMER=y +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_OPTPROBES=y +CONFIG_KPROBES_ON_FTRACE=y +CONFIG_UPROBES=y +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_KRETPROBES=y +CONFIG_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_KPROBES_ON_FTRACE=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_HW_BREAKPOINT=y +CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y +CONFIG_HAVE_USER_RETURN_NOTIFIER=y +CONFIG_HAVE_PERF_EVENTS_NMI=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y +CONFIG_HAVE_CMPXCHG_LOCAL=y +CONFIG_HAVE_CMPXCHG_DOUBLE=y +CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y +CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_SECCOMP_FILTER=y +CONFIG_HAVE_CC_STACKPROTECTOR=y +# CONFIG_CC_STACKPROTECTOR is not set +CONFIG_CC_STACKPROTECTOR_NONE=y +# CONFIG_CC_STACKPROTECTOR_REGULAR is not set +# CONFIG_CC_STACKPROTECTOR_STRONG is not set +CONFIG_HAVE_CONTEXT_TRACKING=y +CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y +CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y +CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y +CONFIG_HAVE_ARCH_SOFT_DIRTY=y +CONFIG_MODULES_USE_ELF_RELA=y +CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_COMPAT_OLD_SIGACTION=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_MODULE_SIG is not set +# CONFIG_MODULE_COMPRESS is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_BLK_DEV_BSG=y +CONFIG_BLK_DEV_BSGLIB=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_THROTTLING=y +CONFIG_BLK_CMDLINE_PARSER=y + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AIX_PARTITION is not set +CONFIG_OSF_PARTITION=y +CONFIG_AMIGA_PARTITION=y +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +CONFIG_BSD_DISKLABEL=y +CONFIG_MINIX_SUBPARTITION=y +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_UNIXWARE_DISKLABEL=y +# CONFIG_LDM_PARTITION is not set +CONFIG_SGI_PARTITION=y +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_SUN_PARTITION=y +CONFIG_KARMA_PARTITION=y +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_CMDLINE_PARTITION=y +CONFIG_BLOCK_COMPAT=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_CFQ_GROUP_IOSCHED=y +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PADATA=y +CONFIG_ASN1=m +CONFIG_INLINE_SPIN_UNLOCK_IRQ=y +CONFIG_INLINE_READ_UNLOCK=y +CONFIG_INLINE_READ_UNLOCK_IRQ=y +CONFIG_INLINE_WRITE_UNLOCK=y +CONFIG_INLINE_WRITE_UNLOCK_IRQ=y +CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_RWSEM_SPIN_ON_OWNER=y +CONFIG_LOCK_SPIN_ON_OWNER=y +CONFIG_ARCH_USE_QUEUE_RWLOCK=y +CONFIG_QUEUE_RWLOCK=y +CONFIG_FREEZER=y + +# +# Processor type and features +# +CONFIG_ZONE_DMA=y +CONFIG_SMP=y +CONFIG_X86_FEATURE_NAMES=y +CONFIG_X86_X2APIC=y +CONFIG_X86_MPPARSE=y +CONFIG_X86_EXTENDED_PLATFORM=y +# CONFIG_X86_NUMACHIP is not set +# CONFIG_X86_VSMP is not set +# CONFIG_X86_UV is not set +# CONFIG_X86_GOLDFISH is not set +# CONFIG_X86_INTEL_LPSS is not set +CONFIG_X86_AMD_PLATFORM_DEVICE=y +CONFIG_IOSF_MBI=m +# CONFIG_IOSF_MBI_DEBUG is not set +CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_HYPERVISOR_GUEST=y +CONFIG_PARAVIRT=y +# CONFIG_PARAVIRT_SPINLOCKS is not set +CONFIG_XEN=y +CONFIG_XEN_DOM0=y +CONFIG_XEN_PVHVM=y +CONFIG_XEN_MAX_DOMAIN_MEMORY=500 +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_XEN_DEBUG_FS=y +CONFIG_XEN_PVH=y +CONFIG_KVM_GUEST=y +# CONFIG_KVM_DEBUG_FS is not set +CONFIG_PARAVIRT_TIME_ACCOUNTING=y +CONFIG_PARAVIRT_CLOCK=y +CONFIG_NO_BOOTMEM=y +# CONFIG_MEMTEST is not set +# CONFIG_MK8 is not set +# CONFIG_MPSC is not set +# CONFIG_MCORE2 is not set +# CONFIG_MATOM is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_INTERNODE_CACHE_SHIFT=6 +CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_TSC=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CMOV=y +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_DEBUGCTLMSR=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR=y +CONFIG_HPET_TIMER=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_DMI=y +CONFIG_GART_IOMMU=y +# CONFIG_CALGARY_IOMMU is not set +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +CONFIG_NR_CPUS=8 +CONFIG_SCHED_SMT=y +CONFIG_SCHED_MC=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +CONFIG_X86_UP_APIC_MSI=y +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y +CONFIG_X86_MCE=y +CONFIG_X86_MCE_INTEL=y +CONFIG_X86_MCE_AMD=y +CONFIG_X86_MCE_THRESHOLD=y +# CONFIG_X86_MCE_INJECT is not set +CONFIG_X86_THERMAL_VECTOR=y +CONFIG_X86_16BIT=y +CONFIG_X86_ESPFIX64=y +CONFIG_X86_VSYSCALL_EMULATION=y +CONFIG_I8K=m +CONFIG_MICROCODE=m +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_OLD_INTERFACE=y +# CONFIG_MICROCODE_INTEL_EARLY is not set +# CONFIG_MICROCODE_AMD_EARLY is not set +CONFIG_X86_MSR=y +CONFIG_X86_CPUID=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_ARCH_DMA_ADDR_T_64BIT=y +CONFIG_DIRECT_GBPAGES=y +CONFIG_NUMA=y +CONFIG_AMD_NUMA=y +CONFIG_X86_64_ACPI_NUMA=y +CONFIG_NODES_SPAN_OTHER_NODES=y +# CONFIG_NUMA_EMU is not set +CONFIG_NODES_SHIFT=10 +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_ARCH_PROC_KCORE_TEXT=y +CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_NEED_MULTIPLE_NODES=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_MEMORY_ISOLATION=y +# CONFIG_MOVABLE_NODE is not set +CONFIG_HAVE_BOOTMEM_INFO_NODE=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTPLUG_SPARSE=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y +CONFIG_MEMORY_BALLOON=y +CONFIG_BALLOON_COMPACTION=y +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_NEED_BOUNCE_POOL=y +CONFIG_VIRT_TO_BUS=y +CONFIG_MMU_NOTIFIER=y +CONFIG_KSM=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y +CONFIG_MEMORY_FAILURE=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS=y +# CONFIG_TRANSPARENT_HUGEPAGE_MADVISE is not set +CONFIG_CLEANCACHE=y +CONFIG_FRONTSWAP=y +# CONFIG_CMA is not set +# CONFIG_ZSWAP is not set +CONFIG_ZPOOL=y +# CONFIG_ZBUD is not set +# CONFIG_ZSMALLOC is not set +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_RESERVE_LOW=64 +CONFIG_MTRR=y +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +CONFIG_X86_PAT=y +CONFIG_ARCH_USES_PG_UNCACHED=y +CONFIG_ARCH_RANDOM=y +CONFIG_X86_SMAP=y +# CONFIG_X86_INTEL_MPX is not set +CONFIG_EFI=y +CONFIG_EFI_STUB=y +# CONFIG_EFI_MIXED is not set +CONFIG_SECCOMP=y +# CONFIG_HZ_100 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +CONFIG_HZ_1000=y +CONFIG_HZ=1000 +CONFIG_SCHED_HRTICK=y +CONFIG_KEXEC=y +# CONFIG_KEXEC_FILE is not set +CONFIG_CRASH_DUMP=y +CONFIG_KEXEC_JUMP=y +CONFIG_PHYSICAL_START=0x200000 +CONFIG_RELOCATABLE=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_RANDOMIZE_BASE_MAX_OFFSET=0x40000000 +CONFIG_X86_NEED_RELOCS=y +CONFIG_PHYSICAL_ALIGN=0x1000000 +CONFIG_HOTPLUG_CPU=y +# CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set +# CONFIG_DEBUG_HOTPLUG_CPU0 is not set +# CONFIG_COMPAT_VDSO is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_HAVE_LIVEPATCH=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_USE_PERCPU_NUMA_NODE_ID=y + +# +# Power management and ACPI options +# +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_HIBERNATE_CALLBACKS=y +CONFIG_HIBERNATION=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM=y +CONFIG_PM_DEBUG=y +# CONFIG_PM_ADVANCED_DEBUG is not set +CONFIG_PM_TEST_SUSPEND=y +CONFIG_PM_SLEEP_DEBUG=y +# CONFIG_DPM_WATCHDOG is not set +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +CONFIG_PM_CLK=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_ACPI=y +CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y +CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y +CONFIG_ACPI_SLEEP=y +# CONFIG_ACPI_PROCFS_POWER is not set +CONFIG_ACPI_EC_DEBUGFS=m +CONFIG_ACPI_AC=y +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_FAN=y +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_IPMI=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PROCESSOR_AGGREGATOR=m +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_NUMA=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_INITRD_TABLE_OVERRIDE=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_PCI_SLOT=y +CONFIG_X86_PM_TIMER=y +CONFIG_ACPI_CONTAINER=y +CONFIG_ACPI_HOTPLUG_MEMORY=y +CONFIG_ACPI_HOTPLUG_IOAPIC=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_HED=y +CONFIG_ACPI_CUSTOM_METHOD=m +CONFIG_ACPI_BGRT=y +# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set +CONFIG_HAVE_ACPI_APEI=y +CONFIG_HAVE_ACPI_APEI_NMI=y +CONFIG_ACPI_APEI=y +CONFIG_ACPI_APEI_GHES=y +CONFIG_ACPI_APEI_PCIEAER=y +CONFIG_ACPI_APEI_MEMORY_FAILURE=y +# CONFIG_ACPI_APEI_EINJ is not set +# CONFIG_ACPI_APEI_ERST_DEBUG is not set +CONFIG_ACPI_EXTLOG=m +# CONFIG_PMIC_OPREGION is not set +CONFIG_SFI=y + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y + +# +# CPU frequency scaling drivers +# +CONFIG_X86_INTEL_PSTATE=y +CONFIG_X86_PCC_CPUFREQ=y +CONFIG_X86_ACPI_CPUFREQ=y +CONFIG_X86_ACPI_CPUFREQ_CPB=y +CONFIG_X86_POWERNOW_K8=y +CONFIG_X86_AMD_FREQ_SENSITIVITY=m +# CONFIG_X86_SPEEDSTEP_CENTRINO is not set +CONFIG_X86_P4_CLOCKMOD=y + +# +# shared options +# +CONFIG_X86_SPEEDSTEP_LIB=y + +# +# CPU Idle +# +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set +CONFIG_INTEL_IDLE=y + +# +# Memory power savings +# +CONFIG_I7300_IDLE_IOAT_CHANNEL=y +CONFIG_I7300_IDLE=m + +# +# Bus options (PCI etc.) +# +CONFIG_PCI=y +CONFIG_PCI_DIRECT=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_XEN=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_PCIEAER=y +CONFIG_PCIE_ECRC=y +CONFIG_PCIEAER_INJECT=m +CONFIG_PCIEASPM=y +# CONFIG_PCIEASPM_DEBUG is not set +CONFIG_PCIEASPM_DEFAULT=y +# CONFIG_PCIEASPM_POWERSAVE is not set +# CONFIG_PCIEASPM_PERFORMANCE is not set +CONFIG_PCIE_PME=y +CONFIG_PCI_MSI=y +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set +CONFIG_PCI_STUB=y +CONFIG_XEN_PCIDEV_FRONTEND=m +CONFIG_HT_IRQ=y +CONFIG_PCI_ATS=y +CONFIG_PCI_IOV=y +CONFIG_PCI_PRI=y +CONFIG_PCI_PASID=y +CONFIG_PCI_LABEL=y + +# +# PCI host controller drivers +# +CONFIG_ISA_DMA_API=y +CONFIG_AMD_NB=y +CONFIG_PCCARD=y +CONFIG_PCMCIA=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_CARDBUS=y + +# +# PC-card bridges +# +CONFIG_YENTA=m +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_PD6729=m +CONFIG_I82092=m +CONFIG_PCCARD_NONSTATIC=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=y +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +# CONFIG_HOTPLUG_PCI_CPCI is not set +CONFIG_HOTPLUG_PCI_SHPC=m +# CONFIG_RAPIDIO is not set +# CONFIG_X86_SYSFB is not set + +# +# Executable file formats / Emulations +# +CONFIG_BINFMT_ELF=y +CONFIG_COMPAT_BINFMT_ELF=y +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_HAVE_AOUT is not set +CONFIG_BINFMT_MISC=m +CONFIG_COREDUMP=y +CONFIG_IA32_EMULATION=y +# CONFIG_IA32_AOUT is not set +CONFIG_X86_X32=y +CONFIG_COMPAT=y +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_KEYS_COMPAT=y +CONFIG_X86_DEV_DMA_OPS=y +CONFIG_PMC_ATOM=y +CONFIG_NET=y +CONFIG_COMPAT_NETLINK_MESSAGES=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_DIAG=m +CONFIG_UNIX=y +CONFIG_UNIX_DIAG=m +CONFIG_XFRM=y +CONFIG_XFRM_ALGO=y +CONFIG_XFRM_USER=y +CONFIG_XFRM_SUB_POLICY=y +CONFIG_XFRM_MIGRATE=y +CONFIG_XFRM_STATISTICS=y +CONFIG_XFRM_IPCOMP=m +CONFIG_NET_KEY=m +CONFIG_NET_KEY_MIGRATE=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_FIB_TRIE_STATS=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_ROUTE_CLASSID=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE_DEMUX=m +CONFIG_NET_IP_TUNNEL=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=m +CONFIG_NET_UDP_TUNNEL=m +# CONFIG_NET_FOU is not set +# CONFIG_NET_FOU_IP_TUNNELS is not set +# CONFIG_GENEVE is not set +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_LRO=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_UDP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_CONG_ILLINOIS=m +# CONFIG_TCP_CONG_DCTCP is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_MD5SIG=y +CONFIG_IPV6=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_IPV6_VTI=m +CONFIG_IPV6_SIT=m +CONFIG_IPV6_SIT_6RD=y +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_GRE=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_SUBTREES=y +CONFIG_IPV6_MROUTE=y +CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y +CONFIG_IPV6_PIMSM_V2=y +CONFIG_NETLABEL=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NET_PTP_CLASSIFY=y +CONFIG_NETWORK_PHY_TIMESTAMPING=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=m + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_ACCT=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_LOG_COMMON=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_ZONES=y +CONFIG_NF_CONNTRACK_PROCFS=y +CONFIG_NF_CONNTRACK_EVENTS=y +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +CONFIG_NF_CONNTRACK_TIMESTAMP=y +CONFIG_NF_CONNTRACK_LABELS=y +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_BROADCAST=m +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_SNMP=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_NETLINK=m +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +# CONFIG_NF_CT_NETLINK_HELPER is not set +CONFIG_NETFILTER_NETLINK_QUEUE_CT=y +CONFIG_NF_NAT=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NF_NAT_REDIRECT=m +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=m +CONFIG_NFT_EXTHDR=m +CONFIG_NFT_META=m +CONFIG_NFT_CT=m +CONFIG_NFT_RBTREE=m +CONFIG_NFT_HASH=m +CONFIG_NFT_COUNTER=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +# CONFIG_NFT_MASQ is not set +# CONFIG_NFT_REDIR is not set +CONFIG_NFT_NAT=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_REJECT_INET=m +CONFIG_NFT_COMPAT=m +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_CONNMARK=m +CONFIG_NETFILTER_XT_SET=m + +# +# Xtables targets +# +CONFIG_NETFILTER_XT_TARGET_AUDIT=m +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_CT=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_HL=m +CONFIG_NETFILTER_XT_TARGET_HMARK=m +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m +CONFIG_NETFILTER_XT_TARGET_LED=m +CONFIG_NETFILTER_XT_TARGET_LOG=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_NAT=m +CONFIG_NETFILTER_XT_TARGET_NETMAP=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_REDIRECT=m +CONFIG_NETFILTER_XT_TARGET_TEE=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m + +# +# Xtables matches +# +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_BPF=m +CONFIG_NETFILTER_XT_MATCH_CGROUP=m +CONFIG_NETFILTER_XT_MATCH_CLUSTER=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_CPU=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ECN=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_HL=m +CONFIG_NETFILTER_XT_MATCH_IPCOMP=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_NETFILTER_XT_MATCH_L2TP=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_NFACCT=m +CONFIG_NETFILTER_XT_MATCH_OSF=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_IP_SET=m +CONFIG_IP_SET_MAX=256 +CONFIG_IP_SET_BITMAP_IP=m +CONFIG_IP_SET_BITMAP_IPMAC=m +CONFIG_IP_SET_BITMAP_PORT=m +CONFIG_IP_SET_HASH_IP=m +CONFIG_IP_SET_HASH_IPMARK=m +CONFIG_IP_SET_HASH_IPPORT=m +CONFIG_IP_SET_HASH_IPPORTIP=m +CONFIG_IP_SET_HASH_IPPORTNET=m +# CONFIG_IP_SET_HASH_MAC is not set +CONFIG_IP_SET_HASH_NETPORTNET=m +CONFIG_IP_SET_HASH_NET=m +CONFIG_IP_SET_HASH_NETNET=m +CONFIG_IP_SET_HASH_NETPORT=m +CONFIG_IP_SET_HASH_NETIFACE=m +CONFIG_IP_SET_LIST_SET=m +CONFIG_IP_VS=m +CONFIG_IP_VS_IPV6=y +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS transport protocol load balancing support +# +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_SCTP=y + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +# CONFIG_IP_VS_FO is not set +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS SH scheduler +# +CONFIG_IP_VS_SH_TAB_BITS=8 + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_NFCT=y +CONFIG_IP_VS_PE_SIP=m + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_CONNTRACK_IPV4=m +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_NF_LOG_ARP=m +CONFIG_NF_LOG_IPV4=m +CONFIG_NF_TABLES_IPV4=m +CONFIG_NFT_CHAIN_ROUTE_IPV4=m +CONFIG_NF_REJECT_IPV4=y +CONFIG_NFT_REJECT_IPV4=m +CONFIG_NF_TABLES_ARP=m +CONFIG_NF_NAT_IPV4=m +CONFIG_NFT_CHAIN_NAT_IPV4=m +CONFIG_NF_NAT_MASQUERADE_IPV4=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_H323=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_RPFILTER=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_TABLES_IPV6=m +CONFIG_NFT_CHAIN_ROUTE_IPV6=m +CONFIG_NF_REJECT_IPV6=m +CONFIG_NFT_REJECT_IPV6=m +CONFIG_NF_LOG_IPV6=m +CONFIG_NF_NAT_IPV6=m +CONFIG_NFT_CHAIN_NAT_IPV6=m +CONFIG_NF_NAT_MASQUERADE_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_RPFILTER=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_NAT=m +CONFIG_IP6_NF_TARGET_MASQUERADE=m +CONFIG_IP6_NF_TARGET_NPT=m +CONFIG_NF_TABLES_BRIDGE=m +CONFIG_NFT_BRIDGE_META=m +CONFIG_NFT_BRIDGE_REJECT=m +CONFIG_NF_LOG_BRIDGE=m +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_IP_DCCP=m +CONFIG_INET_DCCP_DIAG=m + +# +# DCCP CCIDs Configuration +# +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=y +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=y +CONFIG_IP_SCTP=m +CONFIG_NET_SCTPPROBE=m +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set +# CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set +CONFIG_SCTP_COOKIE_HMAC_MD5=y +CONFIG_SCTP_COOKIE_HMAC_SHA1=y +CONFIG_RDS=m +CONFIG_RDS_RDMA=m +CONFIG_RDS_TCP=m +# CONFIG_RDS_DEBUG is not set +# CONFIG_TIPC is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_LANE=m +# CONFIG_ATM_MPOA is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_L2TP=m +CONFIG_L2TP_DEBUGFS=m +CONFIG_L2TP_V3=y +CONFIG_L2TP_IP=m +CONFIG_L2TP_ETH=m +CONFIG_STP=m +CONFIG_GARP=m +CONFIG_MRP=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_IGMP_SNOOPING=y +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_HAVE_NET_DSA=y +CONFIG_NET_DSA=m +CONFIG_NET_DSA_HWMON=y +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_DSA_TAG_TRAILER=y +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLAN_8021Q_MVRP=y +# CONFIG_DECNET is not set +CONFIG_LLC=m +# CONFIG_LLC2 is not set +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m +CONFIG_DEV_APPLETALK=m +CONFIG_IPDDP=m +CONFIG_IPDDP_ENCAP=y +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +CONFIG_6LOWPAN=m +CONFIG_IEEE802154=m +CONFIG_IEEE802154_SOCKET=m +CONFIG_IEEE802154_6LOWPAN=m +CONFIG_MAC802154=m +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFB=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_DRR=m +CONFIG_NET_SCH_MQPRIO=m +CONFIG_NET_SCH_CHOKE=m +CONFIG_NET_SCH_QFQ=m +CONFIG_NET_SCH_CODEL=m +CONFIG_NET_SCH_FQ_CODEL=m +# CONFIG_NET_SCH_FQ is not set +CONFIG_NET_SCH_HHF=m +CONFIG_NET_SCH_PIE=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_PLUG=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_CGROUP=y +CONFIG_NET_CLS_BPF=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_IPSET=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_ACT_CSUM=m +# CONFIG_NET_ACT_VLAN is not set +CONFIG_NET_ACT_BPF=m +CONFIG_NET_ACT_CONNMARK=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_SCH_FIFO=y +CONFIG_DCB=y +CONFIG_DNS_RESOLVER=y +CONFIG_BATMAN_ADV=m +CONFIG_BATMAN_ADV_BLA=y +CONFIG_BATMAN_ADV_DAT=y +# CONFIG_BATMAN_ADV_NC is not set +# CONFIG_BATMAN_ADV_MCAST is not set +# CONFIG_BATMAN_ADV_DEBUG is not set +CONFIG_OPENVSWITCH=m +CONFIG_OPENVSWITCH_GRE=m +CONFIG_OPENVSWITCH_VXLAN=m +CONFIG_VSOCKETS=m +CONFIG_VMWARE_VMCI_VSOCKETS=m +CONFIG_NETLINK_MMAP=y +CONFIG_NETLINK_DIAG=m +CONFIG_NET_MPLS_GSO=m +CONFIG_HSR=m +# CONFIG_NET_SWITCHDEV is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y +# CONFIG_CGROUP_NET_PRIO is not set +CONFIG_CGROUP_NET_CLASSID=y +CONFIG_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +CONFIG_BPF_JIT=y +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_NET_TCPPROBE is not set +CONFIG_NET_DROP_MONITOR=y +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_NETROM=m +CONFIG_ROSE=m + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +CONFIG_6PACK=m +CONFIG_BPQETHER=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +CONFIG_BAYCOM_PAR=m +CONFIG_YAM=m +# CONFIG_CAN is not set +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +# CONFIG_IRDA_ULTRA is not set + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +CONFIG_IRTTY_SIR=m + +# +# Dongle support +# +CONFIG_DONGLE=y +CONFIG_ESI_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m +CONFIG_LITELINK_DONGLE=m +CONFIG_MA600_DONGLE=m +CONFIG_GIRBIL_DONGLE=m +CONFIG_MCP2120_DONGLE=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_ACT200L_DONGLE=m +CONFIG_KINGSUN_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KS959_DONGLE=m + +# +# FIR device drivers +# +CONFIG_USB_IRDA=m +CONFIG_SIGMATEL_FIR=m +CONFIG_NSC_FIR=m +CONFIG_WINBOND_FIR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_ALI_FIR=m +CONFIG_VLSI_FIR=m +CONFIG_VIA_FIR=m +CONFIG_MCS_FIR=m +CONFIG_BT=m +CONFIG_BT_BREDR=y +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HIDP=m +CONFIG_BT_LE=y +CONFIG_BT_6LOWPAN=m + +# +# Bluetooth device drivers +# +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIVHCI=m +CONFIG_BT_MRVL=m +CONFIG_BT_MRVL_SDIO=m +CONFIG_BT_ATH3K=m +CONFIG_BT_WILINK=m +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_WEXT_SPY=y +CONFIG_WEXT_PRIV=y +CONFIG_CFG80211=m +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +# CONFIG_CFG80211_DEFAULT_PS is not set +CONFIG_CFG80211_DEBUGFS=y +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +CONFIG_LIB80211=m +CONFIG_LIB80211_CRYPT_WEP=m +CONFIG_LIB80211_CRYPT_CCMP=m +CONFIG_LIB80211_CRYPT_TKIP=m +# CONFIG_LIB80211_DEBUG is not set +CONFIG_MAC80211=m +CONFIG_MAC80211_HAS_RC=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL_HT=y +# CONFIG_MAC80211_RC_MINSTREL_VHT is not set +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_MESSAGE_TRACING=y +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_WIMAX=m +CONFIG_WIMAX_DEBUG_LEVEL=8 +CONFIG_RFKILL=m +CONFIG_RFKILL_LEDS=y +CONFIG_RFKILL_INPUT=y +CONFIG_RFKILL_GPIO=m +CONFIG_NET_9P=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_9P_RDMA=m +# CONFIG_NET_9P_DEBUG is not set +# CONFIG_CAIF is not set +CONFIG_CEPH_LIB=m +# CONFIG_CEPH_LIB_PRETTYDEBUG is not set +# CONFIG_CEPH_LIB_USE_DNS_RESOLVER is not set +CONFIG_NFC=m +CONFIG_NFC_DIGITAL=m +CONFIG_NFC_NCI=m +CONFIG_NFC_HCI=m +CONFIG_NFC_SHDLC=y + +# +# Near Field Communication (NFC) devices +# +CONFIG_NFC_PN533=m +CONFIG_NFC_WILINK=m +CONFIG_NFC_MEI_PHY=m +# CONFIG_NFC_SIM is not set +CONFIG_NFC_PORT100=m +CONFIG_NFC_PN544=m +CONFIG_NFC_PN544_I2C=m +CONFIG_NFC_PN544_MEI=m +CONFIG_NFC_MICROREAD=m +CONFIG_NFC_MICROREAD_I2C=m +CONFIG_NFC_MICROREAD_MEI=m +CONFIG_NFC_MRVL=m +CONFIG_NFC_MRVL_USB=m +CONFIG_NFC_ST21NFCA=m +CONFIG_NFC_ST21NFCA_I2C=m +# CONFIG_NFC_ST21NFCB is not set +CONFIG_HAVE_BPF_JIT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_UEVENT_HELPER is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FW_LOADER_USER_HELPER=y +# CONFIG_FW_LOADER_USER_HELPER_FALLBACK is not set +CONFIG_WANT_DEV_COREDUMP=y +CONFIG_ALLOW_DEV_COREDUMP=y +CONFIG_DEV_COREDUMP=y +CONFIG_SYS_HYPERVISOR=y +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=m +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_IRQ=y +CONFIG_DMA_SHARED_BUFFER=y +# CONFIG_FENCE_TRACE is not set + +# +# Bus devices +# +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=m +# CONFIG_MTD_TESTS is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_BLOCK is not set +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_SM_FTL is not set +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_SWAP is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOCG3 is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR & LPDDR2 PCM memory drivers +# +# CONFIG_MTD_LPDDR is not set +CONFIG_MTD_SPI_NOR=m +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_LIMIT=20 +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +# CONFIG_MTD_UBI_BLOCK is not set +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_SERIAL=m +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_GSC is not set +# CONFIG_PARPORT_AX88796 is not set +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_NOT_PC=y +CONFIG_PNP=y +# CONFIG_PNP_DEBUG_MESSAGES is not set + +# +# Protocols +# +CONFIG_PNPACPI=y +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +CONFIG_BLK_DEV_FD=m +# CONFIG_PARIDE is not set +CONFIG_BLK_DEV_PCIESSD_MTIP32XX=m +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_CISS_SCSI_TAPE=y +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DRBD=m +# CONFIG_DRBD_FAULT_INJECTION is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_NVME=m +CONFIG_BLK_DEV_SKD=m +CONFIG_BLK_DEV_OSD=m +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_BLK_DEV_RAM_DAX=y +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_XEN_BLKDEV_FRONTEND=m +CONFIG_XEN_BLKDEV_BACKEND=m +CONFIG_VIRTIO_BLK=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_RBD=m +CONFIG_BLK_DEV_RSXX=m + +# +# Misc devices +# +CONFIG_SENSORS_LIS3LV02D=m +# CONFIG_AD525X_DPOT is not set +CONFIG_DUMMY_IRQ=m +# CONFIG_IBM_ASM is not set +# CONFIG_PHANTOM is not set +CONFIG_SGI_IOC4=m +CONFIG_TIFM_CORE=m +CONFIG_TIFM_7XX1=m +# CONFIG_ICS932S401 is not set +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_HP_ILO=m +CONFIG_APDS9802ALS=m +CONFIG_ISL29003=m +CONFIG_ISL29020=m +CONFIG_SENSORS_TSL2550=m +# CONFIG_SENSORS_BH1780 is not set +CONFIG_SENSORS_BH1770=m +CONFIG_SENSORS_APDS990X=m +# CONFIG_HMC6352 is not set +# CONFIG_DS1682 is not set +CONFIG_VMWARE_BALLOON=m +# CONFIG_BMP085_I2C is not set +# CONFIG_USB_SWITCH_FSA9480 is not set +# CONFIG_SRAM is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=m +CONFIG_EEPROM_LEGACY=m +CONFIG_EEPROM_MAX6875=m +CONFIG_EEPROM_93CX6=m +CONFIG_CB710_CORE=m +# CONFIG_CB710_DEBUG is not set +CONFIG_CB710_DEBUG_ASSUMPTIONS=y + +# +# Texas Instruments shared transport line discipline +# +CONFIG_TI_ST=m +CONFIG_SENSORS_LIS3_I2C=m + +# +# Altera FPGA firmware download module +# +CONFIG_ALTERA_STAPL=m +CONFIG_INTEL_MEI=y +CONFIG_INTEL_MEI_ME=m +CONFIG_INTEL_MEI_TXE=m +CONFIG_VMWARE_VMCI=m + +# +# Intel MIC Bus Driver +# +CONFIG_INTEL_MIC_BUS=m + +# +# Intel MIC Host Driver +# +CONFIG_INTEL_MIC_HOST=m + +# +# Intel MIC Card Driver +# +CONFIG_INTEL_MIC_CARD=m +CONFIG_GENWQE=m +CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY=1 +# CONFIG_ECHO is not set +# CONFIG_CXL_BASE is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +CONFIG_RAID_ATTRS=m +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_MQ_DEFAULT is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_SCH=m +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_SCAN_ASYNC=y + +# +# SCSI Transports +# +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_ISCSI_ATTRS=m +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_LOWLEVEL=y +CONFIG_ISCSI_TCP=m +CONFIG_ISCSI_BOOT_SYSFS=m +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_SCSI_CXGB4_ISCSI=m +CONFIG_SCSI_BNX2_ISCSI=m +CONFIG_SCSI_BNX2X_FCOE=m +CONFIG_BE2ISCSI=m +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_HPSA=m +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_3W_SAS=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=4 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=4 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC94XX=m +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_SCSI_MVSAS=m +# CONFIG_SCSI_MVSAS_DEBUG is not set +CONFIG_SCSI_MVSAS_TASKLET=y +CONFIG_SCSI_MVUMI=m +# CONFIG_SCSI_DPT_I2O is not set +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_ARCMSR=m +# CONFIG_SCSI_ESAS2R is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_SAS=m +CONFIG_SCSI_MPT2SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +CONFIG_SCSI_MPT2SAS_LOGGING=y +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPT3SAS_MAX_SGE=128 +CONFIG_SCSI_MPT3SAS_LOGGING=y +CONFIG_SCSI_UFSHCD=m +CONFIG_SCSI_UFSHCD_PCI=m +CONFIG_SCSI_UFSHCD_PLATFORM=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_BUSLOGIC=m +# CONFIG_SCSI_FLASHPOINT is not set +CONFIG_VMWARE_PVSCSI=m +# CONFIG_XEN_SCSI_FRONTEND is not set +CONFIG_HYPERV_STORAGE=m +CONFIG_LIBFC=m +CONFIG_LIBFCOE=m +CONFIG_FCOE=m +CONFIG_FCOE_FNIC=m +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_ISCI=m +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_IPR is not set +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLA_FC=m +CONFIG_TCM_QLA2XXX=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +# CONFIG_SCSI_LPFC_DEBUG_FS is not set +CONFIG_SCSI_DC395x=m +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_WD719X is not set +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_PMCRAID=m +CONFIG_SCSI_PM8001=m +CONFIG_SCSI_BFA_FC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_CHELSIO_FCOE=m +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_OSD_INITIATOR=m +CONFIG_SCSI_OSD_ULD=m +CONFIG_SCSI_OSD_DPRINT_SENSE=1 +# CONFIG_SCSI_OSD_DEBUG is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_VERBOSE_ERROR=y +CONFIG_ATA_ACPI=y +CONFIG_SATA_ZPODD=y +CONFIG_SATA_PMP=y + +# +# Controllers with non-SFF native interface +# +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=m +CONFIG_SATA_INIC162X=m +CONFIG_SATA_ACARD_AHCI=m +CONFIG_SATA_SIL24=m +CONFIG_ATA_SFF=y + +# +# SFF controllers with custom DMA interface +# +CONFIG_PDC_ADMA=m +CONFIG_SATA_QSTOR=m +CONFIG_SATA_SX4=m +CONFIG_ATA_BMDMA=y + +# +# SATA SFF controllers with BMDMA +# +CONFIG_ATA_PIIX=y +CONFIG_SATA_MV=m +CONFIG_SATA_NV=m +CONFIG_SATA_PROMISE=m +CONFIG_SATA_SIL=m +CONFIG_SATA_SIS=m +CONFIG_SATA_SVW=m +CONFIG_SATA_ULI=m +CONFIG_SATA_VIA=m +CONFIG_SATA_VITESSE=m + +# +# PATA SFF controllers with BMDMA +# +CONFIG_PATA_ALI=m +CONFIG_PATA_AMD=m +CONFIG_PATA_ARTOP=m +CONFIG_PATA_ATIIXP=m +CONFIG_PATA_ATP867X=m +CONFIG_PATA_CMD64X=m +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=m +CONFIG_PATA_HPT366=m +CONFIG_PATA_HPT37X=m +CONFIG_PATA_HPT3X2N=m +CONFIG_PATA_HPT3X3=m +# CONFIG_PATA_HPT3X3_DMA is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=m +CONFIG_PATA_JMICRON=m +CONFIG_PATA_MARVELL=m +CONFIG_PATA_NETCELL=m +CONFIG_PATA_NINJA32=m +CONFIG_PATA_NS87415=m +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_OPTIDMA=m +CONFIG_PATA_PDC2027X=m +CONFIG_PATA_PDC_OLD=m +# CONFIG_PATA_RADISYS is not set +CONFIG_PATA_RDC=m +CONFIG_PATA_SCH=m +CONFIG_PATA_SERVERWORKS=m +CONFIG_PATA_SIL680=m +CONFIG_PATA_SIS=m +CONFIG_PATA_TOSHIBA=m +CONFIG_PATA_TRIFLEX=m +CONFIG_PATA_VIA=m +CONFIG_PATA_WINBOND=m + +# +# PIO-only SFF controllers +# +CONFIG_PATA_CMD640_PCI=m +CONFIG_PATA_MPIIX=m +CONFIG_PATA_NS87410=m +CONFIG_PATA_OPTI=m +CONFIG_PATA_PCMCIA=m +# CONFIG_PATA_RZ1000 is not set + +# +# Generic fallback / legacy drivers +# +CONFIG_PATA_ACPI=m +CONFIG_ATA_GENERIC=m +# CONFIG_PATA_LEGACY is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_AUTODETECT=y +CONFIG_MD_LINEAR=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BCACHE=m +# CONFIG_BCACHE_DEBUG is not set +# CONFIG_BCACHE_CLOSURES_DEBUG is not set +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_DEBUG=y +CONFIG_DM_BUFIO=y +CONFIG_DM_BIO_PRISON=m +CONFIG_DM_PERSISTENT_DATA=m +# CONFIG_DM_DEBUG_BLOCK_STACK_TRACING is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=y +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_CACHE=m +CONFIG_DM_CACHE_MQ=m +CONFIG_DM_CACHE_CLEANER=m +CONFIG_DM_ERA=m +CONFIG_DM_MIRROR=y +CONFIG_DM_LOG_USERSPACE=m +CONFIG_DM_RAID=m +CONFIG_DM_ZERO=y +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +# CONFIG_DM_DELAY is not set +CONFIG_DM_UEVENT=y +CONFIG_DM_FLAKEY=m +CONFIG_DM_VERITY=m +# CONFIG_DM_SWITCH is not set +CONFIG_TARGET_CORE=m +CONFIG_TCM_IBLOCK=m +CONFIG_TCM_FILEIO=m +CONFIG_TCM_PSCSI=m +# CONFIG_TCM_USER is not set +CONFIG_LOOPBACK_TARGET=m +CONFIG_TCM_FC=m +CONFIG_ISCSI_TARGET=m +CONFIG_SBP_TARGET=m +CONFIG_FUSION=y +CONFIG_FUSION_SPI=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_SAS=m +CONFIG_FUSION_MAX_SGE=40 +CONFIG_FUSION_CTL=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y + +# +# IEEE 1394 (FireWire) support +# +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIREWIRE_NET=m +CONFIG_FIREWIRE_NOSY=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_NETDEVICES=y +CONFIG_MII=m +CONFIG_NET_CORE=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_EQUALIZER=m +CONFIG_NET_FC=y +CONFIG_IFB=m +CONFIG_NET_TEAM=m +CONFIG_NET_TEAM_MODE_BROADCAST=m +CONFIG_NET_TEAM_MODE_ROUNDROBIN=m +CONFIG_NET_TEAM_MODE_RANDOM=m +CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m +CONFIG_NET_TEAM_MODE_LOADBALANCE=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +# CONFIG_IPVLAN is not set +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETPOLL=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NTB_NETDEV=m +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +# CONFIG_NLMON is not set +CONFIG_SUNGEM_PHY=m +# CONFIG_ARCNET is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_TCP=m +# CONFIG_ATM_LANAI is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +# CONFIG_ATM_ZATM is not set +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_IA is not set +# CONFIG_ATM_FORE200E is not set +CONFIG_ATM_HE=m +# CONFIG_ATM_HE_USE_SUNI is not set +CONFIG_ATM_SOLOS=m + +# +# CAIF transport drivers +# +CONFIG_VHOST_NET=m +CONFIG_VHOST_SCSI=m +CONFIG_VHOST_RING=m +CONFIG_VHOST=m + +# +# Distributed Switch Architecture drivers +# +CONFIG_NET_DSA_MV88E6XXX=m +CONFIG_NET_DSA_MV88E6060=m +CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y +CONFIG_NET_DSA_MV88E6131=m +CONFIG_NET_DSA_MV88E6123_61_65=m +# CONFIG_NET_DSA_MV88E6171 is not set +# CONFIG_NET_DSA_MV88E6352 is not set +# CONFIG_NET_DSA_BCM_SF2 is not set +CONFIG_ETHERNET=y +CONFIG_MDIO=m +CONFIG_NET_VENDOR_3COM=y +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_VORTEX=m +CONFIG_TYPHOON=m +CONFIG_NET_VENDOR_ADAPTEC=y +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_NET_VENDOR_AGERE=y +# CONFIG_ET131X is not set +CONFIG_NET_VENDOR_ALTEON=y +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ALTERA_TSE=m +CONFIG_NET_VENDOR_AMD=y +CONFIG_AMD8111_ETH=m +CONFIG_PCNET32=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_AMD_XGBE=m +CONFIG_AMD_XGBE_DCB=y +CONFIG_NET_XGENE=m +CONFIG_NET_VENDOR_ARC=y +CONFIG_NET_VENDOR_ATHEROS=y +CONFIG_ATL2=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL1C=m +CONFIG_ALX=m +CONFIG_NET_VENDOR_BROADCOM=y +CONFIG_B44=m +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI=y +# CONFIG_BCMGENET is not set +CONFIG_BNX2=m +CONFIG_CNIC=m +CONFIG_TIGON3=m +CONFIG_BNX2X=m +CONFIG_BNX2X_SRIOV=y +CONFIG_NET_VENDOR_BROCADE=y +CONFIG_BNA=m +CONFIG_NET_VENDOR_CHELSIO=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHELSIO_T4=m +CONFIG_CHELSIO_T4_DCB=y +CONFIG_CHELSIO_T4VF=m +CONFIG_NET_VENDOR_CISCO=y +CONFIG_ENIC=m +CONFIG_CX_ECAT=m +CONFIG_DNET=m +CONFIG_NET_VENDOR_DEC=y +CONFIG_NET_TULIP=y +CONFIG_DE2104X=m +CONFIG_DE2104X_DSL=0 +CONFIG_TULIP=m +# CONFIG_TULIP_MWI is not set +CONFIG_TULIP_MMIO=y +# CONFIG_TULIP_NAPI is not set +CONFIG_DE4X5=m +CONFIG_WINBOND_840=m +CONFIG_DM9102=m +CONFIG_ULI526X=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_NET_VENDOR_DLINK=y +CONFIG_DL2K=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_NET_VENDOR_EMULEX=y +CONFIG_BE2NET=m +CONFIG_BE2NET_VXLAN=y +CONFIG_NET_VENDOR_EXAR=y +CONFIG_S2IO=m +CONFIG_VXGE=m +# CONFIG_VXGE_DEBUG_TRACE_ALL is not set +# CONFIG_NET_VENDOR_FUJITSU is not set +# CONFIG_NET_VENDOR_HP is not set +CONFIG_NET_VENDOR_INTEL=y +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_IGB=m +CONFIG_IGB_HWMON=y +CONFIG_IGB_DCA=y +CONFIG_IGBVF=m +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_IXGBE_VXLAN=y +CONFIG_IXGBE_HWMON=y +CONFIG_IXGBE_DCA=y +CONFIG_IXGBE_DCB=y +CONFIG_IXGBEVF=m +CONFIG_I40E=m +CONFIG_I40E_VXLAN=y +CONFIG_I40E_DCB=y +# CONFIG_I40E_FCOE is not set +CONFIG_I40EVF=m +# CONFIG_FM10K is not set +# CONFIG_NET_VENDOR_I825XX is not set +CONFIG_IP1000=m +CONFIG_JME=m +CONFIG_NET_VENDOR_MARVELL=y +CONFIG_MVMDIO=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKGE_GENESIS=y +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +CONFIG_NET_VENDOR_MELLANOX=y +CONFIG_MLX4_EN=m +CONFIG_MLX4_EN_DCB=y +CONFIG_MLX4_EN_VXLAN=y +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +# CONFIG_MLX5_CORE is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851_MLL is not set +CONFIG_KSZ884X_PCI=m +CONFIG_NET_VENDOR_MYRI=y +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +CONFIG_FEALNX=m +CONFIG_NET_VENDOR_NATSEMI=y +CONFIG_NATSEMI=m +CONFIG_NS83820=m +CONFIG_NET_VENDOR_8390=y +CONFIG_PCMCIA_AXNET=m +CONFIG_NE2K_PCI=m +CONFIG_PCMCIA_PCNET=m +CONFIG_NET_VENDOR_NVIDIA=y +CONFIG_FORCEDETH=m +CONFIG_NET_VENDOR_OKI=y +CONFIG_ETHOC=m +CONFIG_NET_PACKET_ENGINE=y +CONFIG_HAMACHI=m +CONFIG_YELLOWFIN=m +CONFIG_NET_VENDOR_QLOGIC=y +CONFIG_QLA3XXX=m +CONFIG_QLCNIC=m +CONFIG_QLCNIC_SRIOV=y +CONFIG_QLCNIC_DCB=y +CONFIG_QLCNIC_VXLAN=y +CONFIG_QLCNIC_HWMON=y +CONFIG_QLGE=m +CONFIG_NETXEN_NIC=m +CONFIG_NET_VENDOR_QUALCOMM=y +CONFIG_NET_VENDOR_REALTEK=y +CONFIG_ATP=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_R8169=m +CONFIG_NET_VENDOR_RDC=y +CONFIG_R6040=m +CONFIG_NET_VENDOR_ROCKER=y +CONFIG_NET_VENDOR_SAMSUNG=y +CONFIG_SXGBE_ETH=m +# CONFIG_NET_VENDOR_SEEQ is not set +CONFIG_NET_VENDOR_SILAN=y +CONFIG_SC92031=m +CONFIG_NET_VENDOR_SIS=y +CONFIG_SIS900=m +CONFIG_SIS190=m +CONFIG_SFC=m +# CONFIG_SFC_MTD is not set +CONFIG_SFC_MCDI_MON=y +CONFIG_SFC_SRIOV=y +CONFIG_NET_VENDOR_SMSC=y +CONFIG_PCMCIA_SMC91C92=m +CONFIG_EPIC100=m +CONFIG_SMSC911X=m +# CONFIG_SMSC911X_ARCH_HOOKS is not set +CONFIG_SMSC9420=m +CONFIG_NET_VENDOR_STMICRO=y +CONFIG_STMMAC_ETH=m +# CONFIG_STMMAC_PLATFORM is not set +# CONFIG_STMMAC_PCI is not set +CONFIG_NET_VENDOR_SUN=y +CONFIG_HAPPYMEAL=m +CONFIG_SUNGEM=m +CONFIG_CASSINI=m +CONFIG_NIU=m +CONFIG_NET_VENDOR_TEHUTI=y +CONFIG_TEHUTI=m +CONFIG_NET_VENDOR_TI=y +CONFIG_TI_CPSW_ALE=m +CONFIG_TLAN=m +CONFIG_NET_VENDOR_VIA=y +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_NET_VENDOR_WIZNET=y +CONFIG_WIZNET_W5100=m +CONFIG_WIZNET_W5300=m +# CONFIG_WIZNET_BUS_DIRECT is not set +# CONFIG_WIZNET_BUS_INDIRECT is not set +CONFIG_WIZNET_BUS_ANY=y +CONFIG_NET_VENDOR_XIRCOM=y +CONFIG_PCMCIA_XIRC2PS=m +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_NET_SB1000 is not set +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +CONFIG_AT803X_PHY=m +CONFIG_AMD_PHY=m +CONFIG_AMD_XGBE_PHY=m +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m +CONFIG_BROADCOM_PHY=m +CONFIG_BCM7XXX_PHY=m +CONFIG_BCM87XX_PHY=m +CONFIG_ICPLUS_PHY=m +CONFIG_REALTEK_PHY=m +CONFIG_NATIONAL_PHY=m +CONFIG_STE10XP=m +CONFIG_LSI_ET1011C_PHY=m +CONFIG_MICREL_PHY=m +CONFIG_FIXED_PHY=y +CONFIG_MDIO_BITBANG=m +CONFIG_MDIO_GPIO=m +# CONFIG_MDIO_BCM_UNIMAC is not set +# CONFIG_PLIP is not set +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPTP=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_SLIP=m +CONFIG_SLHC=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +# CONFIG_SLIP_MODE_SLIP6 is not set +CONFIG_USB_NET_DRIVERS=m +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_RTL8152=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_AX88179_178A=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_EEM=m +CONFIG_USB_NET_CDC_NCM=m +CONFIG_USB_NET_HUAWEI_CDC_NCM=m +CONFIG_USB_NET_CDC_MBIM=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_SR9700=m +CONFIG_USB_NET_SR9800=m +CONFIG_USB_NET_SMSC75XX=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +CONFIG_USB_BELKIN=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_EPSON2888=y +CONFIG_USB_KC2190=y +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_NET_CX82310_ETH=m +CONFIG_USB_NET_KALMIA=m +CONFIG_USB_NET_QMI_WWAN=m +CONFIG_USB_HSO=m +CONFIG_USB_NET_INT51X1=m +CONFIG_USB_IPHETH=m +CONFIG_USB_SIERRA_NET=m +CONFIG_USB_VL600=m +CONFIG_WLAN=y +# CONFIG_PCMCIA_RAYCS is not set +# CONFIG_LIBERTAS_THINFIRM is not set +# CONFIG_AIRO is not set +# CONFIG_ATMEL is not set +CONFIG_AT76C50X_USB=m +# CONFIG_AIRO_CS is not set +# CONFIG_PCMCIA_WL3501 is not set +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187_LEDS=y +# CONFIG_ADM8211 is not set +CONFIG_MAC80211_HWSIM=m +CONFIG_MWL8K=m +CONFIG_ATH_COMMON=m +CONFIG_ATH_CARDS=m +# CONFIG_ATH_DEBUG is not set +CONFIG_ATH5K=m +CONFIG_ATH5K_DEBUG=y +# CONFIG_ATH5K_TRACER is not set +CONFIG_ATH5K_PCI=y +CONFIG_ATH9K_HW=m +CONFIG_ATH9K_COMMON=m +CONFIG_ATH9K_BTCOEX_SUPPORT=y +CONFIG_ATH9K=m +CONFIG_ATH9K_PCI=y +CONFIG_ATH9K_AHB=y +CONFIG_ATH9K_DEBUGFS=y +# CONFIG_ATH9K_STATION_STATISTICS is not set +# CONFIG_ATH9K_DYNACK is not set +CONFIG_ATH9K_WOW=y +CONFIG_ATH9K_RFKILL=y +# CONFIG_ATH9K_CHANNEL_CONTEXT is not set +CONFIG_ATH9K_PCOEM=y +CONFIG_ATH9K_HTC=m +# CONFIG_ATH9K_HTC_DEBUGFS is not set +CONFIG_CARL9170=m +CONFIG_CARL9170_LEDS=y +# CONFIG_CARL9170_DEBUGFS is not set +CONFIG_CARL9170_WPC=y +CONFIG_CARL9170_HWRNG=y +CONFIG_ATH6KL=m +CONFIG_ATH6KL_SDIO=m +CONFIG_ATH6KL_USB=m +# CONFIG_ATH6KL_DEBUG is not set +# CONFIG_ATH6KL_TRACING is not set +CONFIG_AR5523=m +CONFIG_WIL6210=m +CONFIG_WIL6210_ISR_COR=y +CONFIG_WIL6210_TRACING=y +CONFIG_ATH10K=m +CONFIG_ATH10K_PCI=m +CONFIG_ATH10K_DEBUG=y +# CONFIG_ATH10K_DEBUGFS is not set +# CONFIG_ATH10K_TRACING is not set +CONFIG_WCN36XX=m +# CONFIG_WCN36XX_DEBUGFS is not set +CONFIG_B43=m +CONFIG_B43_BCMA=y +CONFIG_B43_SSB=y +CONFIG_B43_BUSES_BCMA_AND_SSB=y +# CONFIG_B43_BUSES_BCMA is not set +# CONFIG_B43_BUSES_SSB is not set +CONFIG_B43_PCI_AUTOSELECT=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCMCIA=y +CONFIG_B43_SDIO=y +CONFIG_B43_BCMA_PIO=y +CONFIG_B43_PIO=y +CONFIG_B43_PHY_G=y +CONFIG_B43_PHY_N=y +CONFIG_B43_PHY_LP=y +CONFIG_B43_PHY_HT=y +CONFIG_B43_LEDS=y +CONFIG_B43_HWRNG=y +CONFIG_B43_DEBUG=y +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_HWRNG=y +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_PIO=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_BRCMUTIL=m +CONFIG_BRCMSMAC=m +CONFIG_BRCMFMAC=m +CONFIG_BRCMFMAC_PROTO_BCDC=y +CONFIG_BRCMFMAC_PROTO_MSGBUF=y +CONFIG_BRCMFMAC_SDIO=y +CONFIG_BRCMFMAC_USB=y +CONFIG_BRCMFMAC_PCIE=y +# CONFIG_BRCM_TRACING is not set +# CONFIG_BRCMDBG is not set +# CONFIG_HOSTAP is not set +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +# CONFIG_IPW2200_DEBUG is not set +CONFIG_LIBIPW=m +# CONFIG_LIBIPW_DEBUG is not set +CONFIG_IWLWIFI=m +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLDVM=m +CONFIG_IWLMVM=m +CONFIG_IWLWIFI_OPMODE_MODULAR=y +# CONFIG_IWLWIFI_BCAST_FILTERING is not set +# CONFIG_IWLWIFI_UAPSD is not set + +# +# Debugging Options +# +CONFIG_IWLWIFI_DEBUG=y +CONFIG_IWLWIFI_DEBUGFS=y +# CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE is not set +# CONFIG_IWLWIFI_DEVICE_TRACING is not set +CONFIG_IWLEGACY=m +CONFIG_IWL4965=m +CONFIG_IWL3945=m + +# +# iwl3945 / iwl4965 Debugging Options +# +CONFIG_IWLEGACY_DEBUG=y +CONFIG_IWLEGACY_DEBUGFS=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_CS=m +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_MESH=y +# CONFIG_HERMES is not set +CONFIG_P54_COMMON=m +CONFIG_P54_USB=m +CONFIG_P54_PCI=m +CONFIG_P54_LEDS=y +CONFIG_RT2X00=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT61PCI=m +CONFIG_RT2800PCI=m +CONFIG_RT2800PCI_RT33XX=y +CONFIG_RT2800PCI_RT35XX=y +CONFIG_RT2800PCI_RT53XX=y +CONFIG_RT2800PCI_RT3290=y +CONFIG_RT2500USB=m +CONFIG_RT73USB=m +CONFIG_RT2800USB=m +CONFIG_RT2800USB_RT33XX=y +CONFIG_RT2800USB_RT35XX=y +# CONFIG_RT2800USB_RT3573 is not set +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RT2800_LIB=m +CONFIG_RT2800_LIB_MMIO=m +CONFIG_RT2X00_LIB_MMIO=m +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2X00_LIB_DEBUGFS=y +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RTL_CARDS=m +CONFIG_RTL8192CE=m +CONFIG_RTL8192SE=m +CONFIG_RTL8192DE=m +CONFIG_RTL8723AE=m +CONFIG_RTL8723BE=m +CONFIG_RTL8188EE=m +# CONFIG_RTL8192EE is not set +# CONFIG_RTL8821AE is not set +CONFIG_RTL8192CU=m +CONFIG_RTLWIFI=m +CONFIG_RTLWIFI_PCI=m +CONFIG_RTLWIFI_USB=m +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8192C_COMMON=m +CONFIG_RTL8723_COMMON=m +CONFIG_RTLBTCOEXIST=m +# CONFIG_WL_TI is not set +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_MWIFIEX=m +CONFIG_MWIFIEX_SDIO=m +CONFIG_MWIFIEX_PCIE=m +CONFIG_MWIFIEX_USB=m +CONFIG_CW1200=m +CONFIG_CW1200_WLAN_SDIO=m +CONFIG_RSI_91X=m +CONFIG_RSI_DEBUGFS=y +CONFIG_RSI_SDIO=m +CONFIG_RSI_USB=m + +# +# WiMAX Wireless Broadband devices +# +CONFIG_WIMAX_I2400M=m +CONFIG_WIMAX_I2400M_USB=m +CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 +# CONFIG_WAN is not set +CONFIG_IEEE802154_DRIVERS=m +CONFIG_IEEE802154_FAKELB=m +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_NETDEV_BACKEND=m +CONFIG_VMXNET3=m +CONFIG_HYPERV_NET=m +CONFIG_ISDN=y +CONFIG_ISDN_I4L=m +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_MPP=y +CONFIG_IPPP_FILTER=y +# CONFIG_ISDN_PPP_BSDCOMP is not set +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_TTY_FAX=y + +# +# ISDN feature submodules +# +CONFIG_ISDN_DIVERSION=m + +# +# ISDN4Linux hardware drivers +# + +# +# Passive cards +# +CONFIG_ISDN_DRV_HISAX=m + +# +# D-channel protocol features +# +CONFIG_HISAX_EURO=y +CONFIG_DE_AOC=y +CONFIG_HISAX_NO_SENDCOMPLETE=y +CONFIG_HISAX_NO_LLC=y +CONFIG_HISAX_NO_KEYPAD=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_MAX_CARDS=8 + +# +# HiSax supported cards +# +CONFIG_HISAX_16_3=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NICCY=y +CONFIG_HISAX_BKM_A4T=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_W6692=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_ENTERNOW_PCI=y +# CONFIG_HISAX_DEBUG is not set + +# +# HiSax PCMCIA card service modules +# +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_TELES_CS=m + +# +# HiSax sub driver modules +# +CONFIG_HISAX_ST5481=m +# CONFIG_HISAX_HFCUSB is not set +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_FRITZ_PCIPNP=m + +# +# Active cards +# +CONFIG_ISDN_CAPI=m +# CONFIG_CAPI_TRACE is not set +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPIDRV=m +# CONFIG_ISDN_CAPI_CAPIDRV_VERBOSE is not set + +# +# CAPI hardware drivers +# +CONFIG_CAPI_AVM=y +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_CAPI_EICON=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_CAPI=y +# CONFIG_GIGASET_I4L is not set +# CONFIG_GIGASET_DUMMYLL is not set +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M105=m +CONFIG_GIGASET_M101=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_L1OIP=m + +# +# mISDN hardware drivers +# +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_MISDN_HFCUSB=m +CONFIG_MISDN_AVMFRITZ=m +CONFIG_MISDN_SPEEDFAX=m +CONFIG_MISDN_INFINEON=m +CONFIG_MISDN_W6692=m +CONFIG_MISDN_NETJET=m +CONFIG_MISDN_IPAC=m +CONFIG_MISDN_ISAR=m +CONFIG_ISDN_HDLC=m + +# +# Input device support +# +CONFIG_INPUT=y +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_SPARSEKMAP=m +CONFIG_INPUT_MATRIXKMAP=m + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_GPIO_POLLED=m +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_TCA8418 is not set +CONFIG_KEYBOARD_MATRIX=m +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_LM8333 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +CONFIG_KEYBOARD_SAMSUNG=m +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_CROS_EC=m +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +CONFIG_MOUSE_PS2_CYPRESS=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_SENTELIC=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_FOCALTECH=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_CYAPA=m +# CONFIG_MOUSE_ELAN_I2C is not set +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOUSE_GPIO=m +CONFIG_MOUSE_SYNAPTICS_I2C=m +CONFIG_MOUSE_SYNAPTICS_USB=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_TURBOGRAFX=m +# CONFIG_JOYSTICK_AS5011 is not set +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_WALKERA0701=m +CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_HANWANG=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_SERIAL_WACOM4=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_AD7879=m +CONFIG_TOUCHSCREEN_AD7879_I2C=m +CONFIG_TOUCHSCREEN_ATMEL_MXT=m +CONFIG_TOUCHSCREEN_AUO_PIXCIR=m +CONFIG_TOUCHSCREEN_BU21013=m +CONFIG_TOUCHSCREEN_CY8CTMG110=m +CONFIG_TOUCHSCREEN_CYTTSP_CORE=m +CONFIG_TOUCHSCREEN_CYTTSP_I2C=m +CONFIG_TOUCHSCREEN_CYTTSP4_CORE=m +CONFIG_TOUCHSCREEN_CYTTSP4_I2C=m +CONFIG_TOUCHSCREEN_DYNAPRO=m +CONFIG_TOUCHSCREEN_HAMPSHIRE=m +CONFIG_TOUCHSCREEN_EETI=m +CONFIG_TOUCHSCREEN_FUJITSU=m +# CONFIG_TOUCHSCREEN_GOODIX is not set +CONFIG_TOUCHSCREEN_ILI210X=m +CONFIG_TOUCHSCREEN_GUNZE=m +# CONFIG_TOUCHSCREEN_ELAN is not set +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_WACOM_W8001=m +CONFIG_TOUCHSCREEN_WACOM_I2C=m +CONFIG_TOUCHSCREEN_MAX11801=m +CONFIG_TOUCHSCREEN_MCS5000=m +CONFIG_TOUCHSCREEN_MMS114=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_EDT_FT5X06=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_TI_AM335X_TSC=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_PIXCIR=m +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_JASTEC=y +CONFIG_TOUCHSCREEN_USB_ELO=y +CONFIG_TOUCHSCREEN_USB_E2I=y +CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y +CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y +CONFIG_TOUCHSCREEN_USB_NEXIO=y +CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TSC_SERIO=m +CONFIG_TOUCHSCREEN_TSC2007=m +CONFIG_TOUCHSCREEN_ST1232=m +CONFIG_TOUCHSCREEN_SUR40=m +CONFIG_TOUCHSCREEN_TPS6507X=m +CONFIG_TOUCHSCREEN_ZFORCE=m +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_BMA150 is not set +CONFIG_INPUT_E3X0_BUTTON=m +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_MMA8450=m +CONFIG_INPUT_MPU3050=m +CONFIG_INPUT_APANEL=m +CONFIG_INPUT_GP2A=m +CONFIG_INPUT_GPIO_BEEPER=m +CONFIG_INPUT_GPIO_TILT_POLLED=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_KXTJ9=m +# CONFIG_INPUT_KXTJ9_POLLED_MODE is not set +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_YEALINK=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_RETU_PWRBUTTON=m +CONFIG_INPUT_TPS65218_PWRBUTTON=m +CONFIG_INPUT_UINPUT=m +# CONFIG_INPUT_PCF8574 is not set +CONFIG_INPUT_PWM_BEEPER=m +CONFIG_INPUT_GPIO_ROTARY_ENCODER=m +# CONFIG_INPUT_ADXL34X is not set +CONFIG_INPUT_IMS_PCU=m +CONFIG_INPUT_CMA3000=m +CONFIG_INPUT_CMA3000_I2C=m +CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y +CONFIG_INPUT_IDEAPAD_SLIDEBAR=m +CONFIG_INPUT_SOC_BUTTON_ARRAY=m +CONFIG_INPUT_DRV260X_HAPTICS=m +# CONFIG_INPUT_DRV2667_HAPTICS is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y +CONFIG_SERIO_I8042=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_RAW=m +CONFIG_SERIO_ALTERA_PS2=m +CONFIG_SERIO_PS2MULT=m +CONFIG_SERIO_ARC_PS2=m +CONFIG_HYPERV_KEYBOARD=m +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m + +# +# Character devices +# +CONFIG_TTY=y +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_CONSOLE_SLEEP=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_UNIX98_PTYS=y +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_ROCKETPORT=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_GT=m +CONFIG_NOZOMI=m +# CONFIG_ISI is not set +CONFIG_N_HDLC=m +CONFIG_N_GSM=m +# CONFIG_TRACE_SINK is not set +CONFIG_DEVMEM=y +# CONFIG_DEVKMEM is not set + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DMA=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_CS=m +CONFIG_SERIAL_8250_NR_UARTS=32 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_DW=m +# CONFIG_SERIAL_8250_FINTEK is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_MFD_HSU=m +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_SCCNXP=m +CONFIG_SERIAL_SC16IS7XX=m +CONFIG_SERIAL_ALTERA_JTAGUART=m +CONFIG_SERIAL_ALTERA_UART=m +CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4 +CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200 +CONFIG_SERIAL_ARC=m +CONFIG_SERIAL_ARC_NR_PORTS=1 +CONFIG_SERIAL_RP2=m +CONFIG_SERIAL_RP2_NR_UARTS=32 +CONFIG_SERIAL_FSL_LPUART=m +CONFIG_PRINTER=m +CONFIG_LP_CONSOLE=y +CONFIG_PPDEV=m +CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HVC_XEN_FRONTEND=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +# CONFIG_IPMI_SI_PROBE_DEFAULTS is not set +# CONFIG_IPMI_SSIF is not set +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_TIMERIOMEM=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HW_RANDOM_TPM=m +CONFIG_NVRAM=y +CONFIG_R3964=m +# CONFIG_APPLICOM is not set + +# +# PCMCIA character devices +# +# CONFIG_SYNCLINK_CS is not set +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +CONFIG_IPWIRELESS=m +CONFIG_MWAVE=m +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=8192 +CONFIG_HPET=y +# CONFIG_HPET_MMAP is not set +CONFIG_HANGCHECK_TIMER=m +CONFIG_TCG_TPM=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TIS_I2C_ATMEL=m +CONFIG_TCG_TIS_I2C_INFINEON=m +CONFIG_TCG_TIS_I2C_NUVOTON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_TIS_I2C_ST33=m +CONFIG_TCG_XEN=m +CONFIG_TCG_CRB=m +CONFIG_TELCLOCK=m +CONFIG_DEVPORT=y +CONFIG_XILLYBUS=m +# CONFIG_XILLYBUS_PCIE is not set + +# +# I2C support +# +CONFIG_I2C=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_MUX=m + +# +# Multiplexer I2C Chip support +# +CONFIG_I2C_MUX_GPIO=m +CONFIG_I2C_MUX_PCA9541=m +CONFIG_I2C_MUX_PCA954x=m +CONFIG_I2C_MUX_PINCTRL=m +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_SMBUS=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_ISMT=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +CONFIG_I2C_SIS96X=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m + +# +# ACPI drivers +# +CONFIG_I2C_SCMI=m + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +CONFIG_I2C_CBUS_GPIO=m +CONFIG_I2C_DESIGNWARE_CORE=m +CONFIG_I2C_DESIGNWARE_PLATFORM=m +# CONFIG_I2C_DESIGNWARE_PCI is not set +CONFIG_I2C_GPIO=m +# CONFIG_I2C_OCORES is not set +CONFIG_I2C_PCA_PLATFORM=m +# CONFIG_I2C_PXA_PCI is not set +CONFIG_I2C_SIMTEC=m +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +CONFIG_I2C_DIOLAN_U2C=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_ROBOTFUZZ_OSIF=m +# CONFIG_I2C_TAOS_EVM is not set +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIPERBOARD=m + +# +# Other I2C/SMBus bus drivers +# +CONFIG_I2C_CROS_EC_TUNNEL=m +CONFIG_I2C_STUB=m +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_SPI is not set +CONFIG_SPMI=m +# CONFIG_HSI is not set + +# +# PPS support +# +CONFIG_PPS=m +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +CONFIG_PPS_CLIENT_LDISC=m +CONFIG_PPS_CLIENT_PARPORT=m +CONFIG_PPS_CLIENT_GPIO=m + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=m +CONFIG_DP83640_PHY=m +CONFIG_PINCTRL=y + +# +# Pin controllers +# +CONFIG_PINMUX=y +CONFIG_PINCONF=y +CONFIG_GENERIC_PINCONF=y +CONFIG_PINCTRL_BAYTRAIL=y +CONFIG_PINCTRL_CHERRYVIEW=m +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_DEVRES=y +CONFIG_GPIO_ACPI=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC=y +CONFIG_GPIO_MAX730X=m + +# +# Memory mapped GPIO drivers: +# +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_IT8761E=m +CONFIG_GPIO_F7188X=m +CONFIG_GPIO_SCH311X=m +CONFIG_GPIO_SCH=m +CONFIG_GPIO_ICH=m +CONFIG_GPIO_VX855=m +CONFIG_GPIO_LYNXPOINT=m + +# +# I2C GPIO expanders: +# +CONFIG_GPIO_LP3943=m +CONFIG_GPIO_MAX7300=m +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_ADP5588=m + +# +# PCI GPIO expanders: +# +CONFIG_GPIO_AMD8111=m +CONFIG_GPIO_INTEL_MID=y +CONFIG_GPIO_ML_IOH=m +CONFIG_GPIO_RDC321X=m + +# +# SPI GPIO expanders: +# +CONFIG_GPIO_MCP23S08=m + +# +# AC97 GPIO expanders: +# +CONFIG_GPIO_UCB1400=m + +# +# LPC GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# + +# +# USB GPIO expanders: +# +CONFIG_GPIO_VIPERBOARD=m +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_MATROX is not set +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS1WM=m +CONFIG_W1_MASTER_GPIO=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2408=m +CONFIG_W1_SLAVE_DS2408_READBACK=y +CONFIG_W1_SLAVE_DS2413=m +CONFIG_W1_SLAVE_DS2406=m +CONFIG_W1_SLAVE_DS2423=m +CONFIG_W1_SLAVE_DS2431=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2433_CRC=y +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_DS2780=m +CONFIG_W1_SLAVE_DS2781=m +CONFIG_W1_SLAVE_DS28E04=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2760 is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2781 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_SBS is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_CHARGER_ISP1704 is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_CHARGER_LP8727 is not set +CONFIG_CHARGER_GPIO=m +CONFIG_CHARGER_BQ2415X=m +CONFIG_CHARGER_BQ24190=m +CONFIG_CHARGER_BQ24735=m +CONFIG_CHARGER_SMB347=m +CONFIG_BATTERY_GAUGE_LTC2941=m +# CONFIG_POWER_RESET is not set +CONFIG_POWER_AVS=y +CONFIG_HWMON=y +CONFIG_HWMON_VID=m +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADT7X10=m +CONFIG_SENSORS_ADT7410=m +CONFIG_SENSORS_ADT7411=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7475=m +CONFIG_SENSORS_ASC7621=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_K10TEMP=m +CONFIG_SENSORS_FAM15H_POWER=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DS620=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_G760A=m +CONFIG_SENSORS_G762=m +CONFIG_SENSORS_GPIO_FAN=m +CONFIG_SENSORS_HIH6130=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +# CONFIG_SENSORS_I5500 is not set +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_IT87=m +# CONFIG_SENSORS_JC42 is not set +CONFIG_SENSORS_POWR1220=m +CONFIG_SENSORS_LINEAGE=m +CONFIG_SENSORS_LTC2945=m +CONFIG_SENSORS_LTC4151=m +CONFIG_SENSORS_LTC4215=m +CONFIG_SENSORS_LTC4222=m +CONFIG_SENSORS_LTC4245=m +CONFIG_SENSORS_LTC4260=m +CONFIG_SENSORS_LTC4261=m +CONFIG_SENSORS_MAX16065=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX1668=m +CONFIG_SENSORS_MAX197=m +CONFIG_SENSORS_MAX6639=m +CONFIG_SENSORS_MAX6642=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6697=m +CONFIG_SENSORS_HTU21=m +CONFIG_SENSORS_MCP3021=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM73=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_LM95234=m +CONFIG_SENSORS_LM95241=m +CONFIG_SENSORS_LM95245=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_NTC_THERMISTOR=m +CONFIG_SENSORS_NCT6683=m +CONFIG_SENSORS_NCT6775=m +# CONFIG_SENSORS_NCT7802 is not set +CONFIG_SENSORS_PCF8591=m +CONFIG_PMBUS=m +CONFIG_SENSORS_PMBUS=m +CONFIG_SENSORS_ADM1275=m +CONFIG_SENSORS_LM25066=m +CONFIG_SENSORS_LTC2978=m +CONFIG_SENSORS_MAX16064=m +CONFIG_SENSORS_MAX34440=m +CONFIG_SENSORS_MAX8688=m +CONFIG_SENSORS_TPS40422=m +CONFIG_SENSORS_UCD9000=m +CONFIG_SENSORS_UCD9200=m +CONFIG_SENSORS_ZL6100=m +CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SHT21=m +CONFIG_SENSORS_SHTC1=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_EMC1403=m +# CONFIG_SENSORS_EMC2103 is not set +CONFIG_SENSORS_EMC6W201=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SCH56XX_COMMON=m +CONFIG_SENSORS_SCH5627=m +CONFIG_SENSORS_SCH5636=m +# CONFIG_SENSORS_SMM665 is not set +CONFIG_SENSORS_ADC128D818=m +CONFIG_SENSORS_ADS1015=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_AMC6821=m +CONFIG_SENSORS_INA209=m +CONFIG_SENSORS_INA2XX=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TMP102=m +CONFIG_SENSORS_TMP103=m +CONFIG_SENSORS_TMP401=m +CONFIG_SENSORS_TMP421=m +CONFIG_SENSORS_VIA_CPUTEMP=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83795=m +# CONFIG_SENSORS_W83795_FANCTRL is not set +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83627EHF=m + +# +# ACPI drivers +# +CONFIG_SENSORS_ACPI_POWER=m +CONFIG_SENSORS_ATK0110=m +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_THERMAL_GOV_BANG_BANG=y +CONFIG_THERMAL_GOV_USER_SPACE=y +# CONFIG_THERMAL_EMULATION is not set +# CONFIG_INTEL_POWERCLAMP is not set +CONFIG_X86_PKG_TEMP_THERMAL=m +CONFIG_INTEL_SOC_DTS_THERMAL=m +# CONFIG_INT340X_THERMAL is not set + +# +# Texas Instruments thermal drivers +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_CORE=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +# CONFIG_XILINX_WATCHDOG is not set +CONFIG_DW_WATCHDOG=m +CONFIG_RETU_WATCHDOG=m +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_F71808E_WDT=m +CONFIG_SP5100_TCO=m +CONFIG_SBC_FITPC2_WATCHDOG=m +# CONFIG_EUROTECH_WDT is not set +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +# CONFIG_WAFER_WDT is not set +CONFIG_I6300ESB_WDT=m +CONFIG_IE6XX_WDT=m +CONFIG_ITCO_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_HP_WATCHDOG=m +CONFIG_HPWDT_NMI_DECODING=y +# CONFIG_SC1200_WDT is not set +# CONFIG_PC87413_WDT is not set +CONFIG_NV_TCO=m +# CONFIG_60XX_WDT is not set +# CONFIG_CPU5_WDT is not set +CONFIG_SMSC_SCH311X_WDT=m +# CONFIG_SMSC37B787_WDT is not set +CONFIG_VIA_WDT=m +CONFIG_W83627HF_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_MACHZ_WDT=m +# CONFIG_SBC_EPX_C3_WATCHDOG is not set +CONFIG_MEN_A21_WDT=m +CONFIG_XEN_WDT=m + +# +# PCI-based Watchdog Cards +# +CONFIG_PCIPCWATCHDOG=m +CONFIG_WDTPCI=m + +# +# USB-based Watchdog Cards +# +CONFIG_USBPCWATCHDOG=m +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +CONFIG_SSB=m +CONFIG_SSB_SPROM=y +CONFIG_SSB_BLOCKIO=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_PCMCIAHOST=y +CONFIG_SSB_SDIOHOST_POSSIBLE=y +CONFIG_SSB_SDIOHOST=y +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_GPIO=y +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +CONFIG_BCMA=m +CONFIG_BCMA_BLOCKIO=y +CONFIG_BCMA_HOST_PCI_POSSIBLE=y +CONFIG_BCMA_HOST_PCI=y +# CONFIG_BCMA_HOST_SOC is not set +CONFIG_BCMA_DRIVER_GMAC_CMN=y +CONFIG_BCMA_DRIVER_GPIO=y +# CONFIG_BCMA_DEBUG is not set + +# +# Multifunction device drivers +# +CONFIG_MFD_CORE=y +CONFIG_MFD_BCM590XX=m +CONFIG_MFD_CROS_EC=m +CONFIG_MFD_CROS_EC_I2C=m +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_HTC_PASIC3 is not set +CONFIG_LPC_ICH=m +CONFIG_LPC_SCH=m +# CONFIG_MFD_JANZ_CMODIO is not set +# CONFIG_MFD_KEMPLD is not set +# CONFIG_MFD_MENF21BMC is not set +CONFIG_MFD_VIPERBOARD=m +CONFIG_MFD_RETU=m +# CONFIG_MFD_PCF50633 is not set +CONFIG_UCB1400_CORE=m +CONFIG_MFD_RDC321X=m +CONFIG_MFD_RTSX_PCI=m +CONFIG_MFD_RTSX_USB=m +# CONFIG_MFD_RN5T618 is not set +CONFIG_MFD_SI476X_CORE=m +CONFIG_MFD_SM501=m +CONFIG_MFD_SM501_GPIO=y +# CONFIG_ABX500_CORE is not set +CONFIG_MFD_SYSCON=y +CONFIG_MFD_TI_AM335X_TSCADC=m +CONFIG_MFD_LP3943=m +# CONFIG_TPS6105X is not set +CONFIG_TPS65010=m +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65217 is not set +CONFIG_MFD_TPS65218=m +CONFIG_MFD_TPS65912=y +CONFIG_MFD_WL1273_CORE=m +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TMIO is not set +CONFIG_MFD_VX855=m +# CONFIG_MFD_ARIZONA_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_REGULATOR is not set +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y +CONFIG_MEDIA_RADIO_SUPPORT=y +CONFIG_MEDIA_SDR_SUPPORT=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_VIDEO_V4L2=m +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_TUNER=m +CONFIG_V4L2_MEM2MEM_DEV=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF2_CORE=m +CONFIG_VIDEOBUF2_MEMOPS=m +CONFIG_VIDEOBUF2_DMA_CONTIG=m +CONFIG_VIDEOBUF2_VMALLOC=m +CONFIG_VIDEOBUF2_DMA_SG=m +CONFIG_VIDEOBUF2_DVB=m +CONFIG_DVB_CORE=m +CONFIG_DVB_NET=y +CONFIG_TTPCI_EEPROM=m +CONFIG_DVB_MAX_ADAPTERS=8 +CONFIG_DVB_DYNAMIC_MINORS=y + +# +# Media drivers +# +CONFIG_RC_CORE=m +CONFIG_RC_MAP=m +CONFIG_RC_DECODERS=y +CONFIG_LIRC=m +CONFIG_IR_LIRC_CODEC=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_RC_DEVICES=y +CONFIG_RC_ATI_REMOTE=m +CONFIG_IR_ENE=m +# CONFIG_IR_HIX5HD2 is not set +CONFIG_IR_IMON=m +CONFIG_IR_MCEUSB=m +CONFIG_IR_ITE_CIR=m +CONFIG_IR_FINTEK=m +CONFIG_IR_NUVOTON=m +CONFIG_IR_REDRAT3=m +CONFIG_IR_STREAMZAP=m +CONFIG_IR_WINBOND_CIR=m +# CONFIG_IR_IGORPLUGUSB is not set +CONFIG_IR_IGUANA=m +CONFIG_IR_TTUSBIR=m +CONFIG_RC_LOOPBACK=m +CONFIG_IR_GPIO_CIR=m +CONFIG_MEDIA_USB_SUPPORT=y + +# +# Webcam devices +# +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_GSPCA=m +CONFIG_USB_M5602=m +CONFIG_USB_STV06XX=m +CONFIG_USB_GL860=m +CONFIG_USB_GSPCA_BENQ=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_DTCS033=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_JEILINJ=m +CONFIG_USB_GSPCA_JL2005BCD=m +CONFIG_USB_GSPCA_KINECT=m +CONFIG_USB_GSPCA_KONICA=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_MR97310A=m +CONFIG_USB_GSPCA_NW80X=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_OV534=m +CONFIG_USB_GSPCA_OV534_9=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7302=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SE401=m +CONFIG_USB_GSPCA_SN9C2028=m +CONFIG_USB_GSPCA_SN9C20X=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_SPCA1528=m +CONFIG_USB_GSPCA_SQ905=m +CONFIG_USB_GSPCA_SQ905C=m +CONFIG_USB_GSPCA_SQ930X=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_STK1135=m +CONFIG_USB_GSPCA_STV0680=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TOPRO=m +CONFIG_USB_GSPCA_TOUPTEK=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_VICAM=m +CONFIG_USB_GSPCA_XIRLINK_CIT=m +CONFIG_USB_GSPCA_ZC3XX=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_PWC_INPUT_EVDEV=y +CONFIG_VIDEO_CPIA2=m +CONFIG_USB_ZR364XX=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_S2255=m +CONFIG_VIDEO_USBTV=m + +# +# Analog TV USB devices +# +CONFIG_VIDEO_PVRUSB2=m +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_PVRUSB2_DVB=y +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_HDPVR=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_STK1160_COMMON=m +CONFIG_VIDEO_STK1160_AC97=y +CONFIG_VIDEO_STK1160=m +# CONFIG_VIDEO_GO7007 is not set + +# +# Analog/digital TV USB devices +# +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_AU0828_V4L2=y +CONFIG_VIDEO_AU0828_RC=y +CONFIG_VIDEO_CX231XX=m +CONFIG_VIDEO_CX231XX_RC=y +CONFIG_VIDEO_CX231XX_ALSA=m +CONFIG_VIDEO_CX231XX_DVB=m +CONFIG_VIDEO_TM6000=m +CONFIG_VIDEO_TM6000_ALSA=m +CONFIG_VIDEO_TM6000_DVB=m + +# +# Digital TV USB devices +# +CONFIG_DVB_USB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_CXUSB=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_PCTV452E=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_FRIIO=m +CONFIG_DVB_USB_AZ6027=m +CONFIG_DVB_USB_TECHNISAT_USB2=m +CONFIG_DVB_USB_V2=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_AF9035=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_AZ6007=m +CONFIG_DVB_USB_CE6230=m +CONFIG_DVB_USB_EC168=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_LME2510=m +CONFIG_DVB_USB_MXL111SF=m +CONFIG_DVB_USB_RTL28XXU=m +# CONFIG_DVB_USB_DVBSKY is not set +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_SMS_USB_DRV=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +# CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG is not set +# CONFIG_DVB_AS102 is not set + +# +# Webcam, TV (analog/digital) USB devices +# +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_V4L2=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_EM28XX_RC=m + +# +# Software defined radio USB devices +# +CONFIG_USB_AIRSPY=m +# CONFIG_USB_HACKRF is not set +CONFIG_MEDIA_PCI_SUPPORT=y + +# +# Media capture support +# +CONFIG_VIDEO_MEYE=m + +# +# Media capture/analog TV support +# +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_IVTV_ALSA=m +CONFIG_VIDEO_FB_IVTV=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_MXB=m +CONFIG_VIDEO_SOLO6X10=m +# CONFIG_VIDEO_TW68 is not set + +# +# Media capture/analog/hybrid TV support +# +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CX18_ALSA=m +CONFIG_VIDEO_CX23885=m +CONFIG_MEDIA_ALTERA_CI=m +# CONFIG_VIDEO_CX25821 is not set +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_ENABLE_VP3054=y +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_CX88_MPEG=m +CONFIG_VIDEO_BT848=m +CONFIG_DVB_BT8XX=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_RC=y +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7164=m + +# +# Media digital TV PCI Adapters +# +CONFIG_DVB_AV7110_IR=y +CONFIG_DVB_AV7110=m +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +# CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG is not set +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_DM1105=m +CONFIG_DVB_PT1=m +# CONFIG_DVB_PT3 is not set +CONFIG_MANTIS_CORE=m +CONFIG_DVB_MANTIS=m +CONFIG_DVB_HOPPER=m +CONFIG_DVB_NGENE=m +CONFIG_DVB_DDBRIDGE=m +# CONFIG_DVB_SMIPCIE is not set +# CONFIG_V4L_PLATFORM_DRIVERS is not set +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_MEM2MEM_DEINTERLACE=m +CONFIG_VIDEO_SH_VEU=m +CONFIG_V4L_TEST_DRIVERS=y +# CONFIG_VIDEO_VIVID is not set +# CONFIG_VIDEO_VIM2M is not set + +# +# Supported MMC/SDIO adapters +# +CONFIG_SMS_SDIO_DRV=m +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_TEA575X=m +CONFIG_RADIO_SI470X=y +CONFIG_USB_SI470X=m +CONFIG_I2C_SI470X=m +CONFIG_RADIO_SI4713=m +CONFIG_USB_SI4713=m +CONFIG_PLATFORM_SI4713=m +CONFIG_I2C_SI4713=m +CONFIG_USB_MR800=m +CONFIG_USB_DSBR=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_SHARK=m +CONFIG_RADIO_SHARK2=m +CONFIG_USB_KEENE=m +CONFIG_USB_RAREMONO=m +CONFIG_USB_MA901=m +CONFIG_RADIO_TEA5764=m +CONFIG_RADIO_SAA7706H=m +# CONFIG_RADIO_TEF6862 is not set +CONFIG_RADIO_WL1273=m + +# +# Texas Instruments WL128x FM driver (ST based) +# +CONFIG_RADIO_WL128X=m + +# +# Supported FireWire (IEEE 1394) Adapters +# +CONFIG_DVB_FIREDTV=m +CONFIG_DVB_FIREDTV_INPUT=y +CONFIG_MEDIA_COMMON_OPTIONS=y + +# +# common driver options +# +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_CYPRESS_FIRMWARE=m +CONFIG_DVB_B2C2_FLEXCOP=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_SMS_SIANO_MDTV=m +CONFIG_SMS_SIANO_RC=y +# CONFIG_SMS_SIANO_DEBUGFS is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, frontends) +# +CONFIG_MEDIA_SUBDRV_AUTOSELECT=y +CONFIG_MEDIA_ATTACH=y +CONFIG_VIDEO_IR_I2C=m + +# +# Audio decoders, processors and mixers +# +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_VP27SMPX=m + +# +# RDS decoders +# +CONFIG_VIDEO_SAA6588=m + +# +# Video decoders +# +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BT866=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_VPX3220=m + +# +# Video and audio decoders +# +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_CX25840=m + +# +# Video encoders +# +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m + +# +# Camera sensor devices +# +CONFIG_VIDEO_MT9V011=m + +# +# Flash devices +# + +# +# Video improvement chips +# +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m + +# +# Audio/Video compression chips +# +CONFIG_VIDEO_SAA6752HS=m + +# +# Miscellaneous helper chips +# +CONFIG_VIDEO_M52790=m + +# +# Sensors used on soc_camera driver +# +CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT2063=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +CONFIG_MEDIA_TUNER_XC4000=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_MC44S803=m +CONFIG_MEDIA_TUNER_MAX2165=m +CONFIG_MEDIA_TUNER_TDA18218=m +CONFIG_MEDIA_TUNER_FC0011=m +CONFIG_MEDIA_TUNER_FC0012=m +CONFIG_MEDIA_TUNER_FC0013=m +CONFIG_MEDIA_TUNER_TDA18212=m +CONFIG_MEDIA_TUNER_E4000=m +CONFIG_MEDIA_TUNER_FC2580=m +CONFIG_MEDIA_TUNER_M88TS2022=m +CONFIG_MEDIA_TUNER_M88RS6000T=m +CONFIG_MEDIA_TUNER_TUA9001=m +CONFIG_MEDIA_TUNER_SI2157=m +CONFIG_MEDIA_TUNER_IT913X=m +CONFIG_MEDIA_TUNER_R820T=m + +# +# Multistandard (satellite) frontends +# +CONFIG_DVB_STB0899=m +CONFIG_DVB_STB6100=m +CONFIG_DVB_STV090x=m +CONFIG_DVB_STV6110x=m +CONFIG_DVB_M88DS3103=m + +# +# Multistandard (cable + terrestrial) frontends +# +CONFIG_DVB_DRXK=m +CONFIG_DVB_TDA18271C2DD=m +CONFIG_DVB_SI2165=m + +# +# DVB-S (satellite) frontends +# +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_MT312=m +CONFIG_DVB_ZL10036=m +CONFIG_DVB_ZL10039=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_STV6110=m +CONFIG_DVB_STV0900=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8261=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_TUNER_CX24113=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24117=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_TS2020=m +CONFIG_DVB_DS3000=m +CONFIG_DVB_MB86A16=m +CONFIG_DVB_TDA10071=m + +# +# DVB-T (terrestrial) frontends +# +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_DRXD=m +CONFIG_DVB_L64781=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_AF9013=m +CONFIG_DVB_EC100=m +CONFIG_DVB_STV0367=m +CONFIG_DVB_CXD2820R=m +CONFIG_DVB_RTL2830=m +CONFIG_DVB_RTL2832=m +CONFIG_DVB_RTL2832_SDR=m +CONFIG_DVB_SI2168=m +# CONFIG_DVB_AS102_FE is not set + +# +# DVB-C (cable) frontends +# +CONFIG_DVB_VES1820=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_STV0297=m + +# +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends +# +CONFIG_DVB_NXT200X=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGDT3305=m +CONFIG_DVB_LG2160=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AU8522_DTV=m +CONFIG_DVB_AU8522_V4L=m +CONFIG_DVB_S5H1411=m + +# +# ISDB-T (terrestrial) frontends +# +CONFIG_DVB_S921=m +CONFIG_DVB_DIB8000=m +CONFIG_DVB_MB86A20S=m + +# +# ISDB-S (satellite) & ISDB-T (terrestrial) frontends +# + +# +# Digital terrestrial only tuners/PLL +# +CONFIG_DVB_PLL=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_DIB0090=m + +# +# SEC control devices for DVB-S +# +CONFIG_DVB_DRX39XYJ=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_LNBP22=m +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_ISL6423=m +CONFIG_DVB_A8293=m +CONFIG_DVB_LGS8GXX=m +CONFIG_DVB_ATBM8830=m +CONFIG_DVB_TDA665x=m +CONFIG_DVB_IX2505V=m +CONFIG_DVB_M88RS2000=m +CONFIG_DVB_AF9033=m + +# +# Tools to develop new frontends +# +# CONFIG_DVB_DUMMY_FE is not set + +# +# Graphics support +# +CONFIG_AGP=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=y +CONFIG_AGP_SIS=y +CONFIG_AGP_VIA=y +CONFIG_INTEL_GTT=y +CONFIG_VGA_ARB=y +CONFIG_VGA_ARB_MAX_GPUS=16 +CONFIG_VGA_SWITCHEROO=y + +# +# Direct Rendering Manager +# +CONFIG_DRM=m +CONFIG_DRM_MIPI_DSI=y +CONFIG_DRM_KMS_HELPER=m +CONFIG_DRM_KMS_FB_HELPER=y +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_TTM=m + +# +# I2C encoder or helper chips +# +# CONFIG_DRM_I2C_ADV7511 is not set +CONFIG_DRM_I2C_CH7006=m +CONFIG_DRM_I2C_SIL164=m +CONFIG_DRM_I2C_NXP_TDA998X=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +# CONFIG_DRM_RADEON_UMS is not set +CONFIG_DRM_NOUVEAU=m +CONFIG_NOUVEAU_DEBUG=5 +CONFIG_NOUVEAU_DEBUG_DEFAULT=3 +CONFIG_DRM_NOUVEAU_BACKLIGHT=y +CONFIG_DRM_I810=m +CONFIG_DRM_I915=m +CONFIG_DRM_I915_KMS=y +CONFIG_DRM_I915_FBDEV=y +CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT=y +CONFIG_DRM_MGA=m +CONFIG_DRM_SIS=m +CONFIG_DRM_VIA=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_VMWGFX=m +CONFIG_DRM_VMWGFX_FBCON=y +CONFIG_DRM_GMA500=m +CONFIG_DRM_GMA600=y +CONFIG_DRM_GMA3600=y +CONFIG_DRM_UDL=m +CONFIG_DRM_AST=m +CONFIG_DRM_MGAG200=m +CONFIG_DRM_CIRRUS_QEMU=m +CONFIG_DRM_QXL=m +CONFIG_DRM_BOCHS=m +CONFIG_DRM_PANEL=y + +# +# Display Panels +# +# CONFIG_HSA_AMD is not set + +# +# Frame buffer Devices +# +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB_CMDLINE=y +# CONFIG_FB_DDC is not set +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_SYS_FILLRECT=y +CONFIG_FB_SYS_COPYAREA=y +CONFIG_FB_SYS_IMAGEBLIT=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_SYS_FOPS=y +CONFIG_FB_DEFERRED_IO=y +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +CONFIG_FB_BACKLIGHT=y +# CONFIG_FB_MODE_HELPERS is not set +CONFIG_FB_TILEBLITTING=y + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +CONFIG_FB_VGA16=m +# CONFIG_FB_UVESA is not set +CONFIG_FB_VESA=y +CONFIG_FB_EFI=y +# CONFIG_FB_N411 is not set +# CONFIG_FB_HGA is not set +CONFIG_FB_OPENCORES=m +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I740 is not set +# CONFIG_FB_LE80578 is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIA is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +CONFIG_FB_VOODOO1=m +# CONFIG_FB_VT8623 is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_ARK is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_CARMINE is not set +# CONFIG_FB_SM501 is not set +# CONFIG_FB_SMSCUFX is not set +# CONFIG_FB_UDL is not set +CONFIG_FB_VIRTUAL=m +CONFIG_XEN_FBDEV_FRONTEND=y +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_BROADSHEET is not set +# CONFIG_FB_AUO_K190X is not set +CONFIG_FB_HYPERV=m +# CONFIG_FB_SIMPLE is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_PLATFORM=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set +CONFIG_BACKLIGHT_PWM=m +CONFIG_BACKLIGHT_APPLE=m +# CONFIG_BACKLIGHT_SAHARA is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set +CONFIG_BACKLIGHT_LM3630A=m +CONFIG_BACKLIGHT_LM3639=m +CONFIG_BACKLIGHT_LP855X=m +CONFIG_BACKLIGHT_GPIO=m +CONFIG_BACKLIGHT_LV5207LP=m +CONFIG_BACKLIGHT_BD6107=m +CONFIG_VGASTATE=m +CONFIG_HDMI=y + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_VGACON_SOFT_SCROLLBACK=y +CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64 +CONFIG_DUMMY_CONSOLE=y +CONFIG_DUMMY_CONSOLE_COLUMNS=80 +CONFIG_DUMMY_CONSOLE_ROWS=25 +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_LOGO is not set +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_OSS_CORE_PRECLAIM=y +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_HWDEP=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_JACK=y +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_HRTIMER=m +CONFIG_SND_SEQ_HRTIMER_DEFAULT=y +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_MAX_CARDS=32 +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_VMASTER=y +CONFIG_SND_KCTL_JACK=y +CONFIG_SND_DMA_SGBUF=y +CONFIG_SND_RAWMIDI_SEQ=m +CONFIG_SND_OPL3_LIB_SEQ=m +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +CONFIG_SND_EMU10K1_SEQ=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_DRIVERS=y +CONFIG_SND_PCSP=m +CONFIG_SND_DUMMY=m +CONFIG_SND_ALOOP=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_MPU401=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_SB_COMMON=m +CONFIG_SND_PCI=y +CONFIG_SND_AD1889=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ASIHPI=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +# CONFIG_SND_AW2 is not set +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_OXYGEN=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CTXFI=m +CONFIG_SND_DARLA20=m +CONFIG_SND_GINA20=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_DARLA24=m +CONFIG_SND_GINA24=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MONA=m +CONFIG_SND_MIA=m +CONFIG_SND_ECHO3G=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIOX=m +CONFIG_SND_INDIGODJX=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_ES1968_INPUT=y +CONFIG_SND_ES1968_RADIO=y +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_LOLA=m +CONFIG_SND_LX6464ES=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MAESTRO3_INPUT=y +CONFIG_SND_MIXART=m +CONFIG_SND_NM256=m +CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRTUOSO=m +CONFIG_SND_VX222=m +CONFIG_SND_YMFPCI=m + +# +# HD-Audio +# +CONFIG_SND_HDA=m +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_DSP_LOADER=y +CONFIG_SND_HDA_PREALLOC_SIZE=4096 +CONFIG_SND_HDA_HWDEP=y +CONFIG_SND_HDA_RECONFIG=y +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INPUT_BEEP_MODE=0 +CONFIG_SND_HDA_INPUT_JACK=y +CONFIG_SND_HDA_PATCH_LOADER=y +CONFIG_SND_HDA_CODEC_REALTEK=m +CONFIG_SND_HDA_CODEC_ANALOG=m +CONFIG_SND_HDA_CODEC_SIGMATEL=m +CONFIG_SND_HDA_CODEC_VIA=m +CONFIG_SND_HDA_CODEC_HDMI=m +CONFIG_SND_HDA_I915=y +CONFIG_SND_HDA_CODEC_CIRRUS=m +CONFIG_SND_HDA_CODEC_CONEXANT=m +CONFIG_SND_HDA_CODEC_CA0110=m +CONFIG_SND_HDA_CODEC_CA0132=m +CONFIG_SND_HDA_CODEC_CA0132_DSP=y +CONFIG_SND_HDA_CODEC_CMEDIA=m +CONFIG_SND_HDA_CODEC_SI3054=m +CONFIG_SND_HDA_GENERIC=m +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_UA101=m +CONFIG_SND_USB_USX2Y=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_US122L=m +CONFIG_SND_USB_6FIRE=m +# CONFIG_SND_USB_HIFACE is not set +CONFIG_SND_BCD2000=m +CONFIG_SND_USB_LINE6=m +CONFIG_SND_USB_POD=m +CONFIG_SND_USB_PODHD=m +CONFIG_SND_USB_TONEPORT=m +CONFIG_SND_USB_VARIAX=m +CONFIG_SND_FIREWIRE=y +CONFIG_SND_FIREWIRE_LIB=m +CONFIG_SND_DICE=m +# CONFIG_SND_OXFW is not set +CONFIG_SND_ISIGHT=m +CONFIG_SND_SCS1X=m +CONFIG_SND_FIREWORKS=m +CONFIG_SND_BEBOB=m +# CONFIG_SND_PCMCIA is not set +# CONFIG_SND_SOC is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_AC97_BUS=m + +# +# HID support +# +CONFIG_HID=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_GENERIC=y + +# +# Special HID drivers +# +CONFIG_HID_A4TECH=y +CONFIG_HID_ACRUX=m +CONFIG_HID_ACRUX_FF=y +CONFIG_HID_APPLE=y +CONFIG_HID_APPLEIR=m +CONFIG_HID_AUREAL=m +CONFIG_HID_BELKIN=y +CONFIG_HID_BETOP_FF=m +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_PRODIKEYS=m +CONFIG_HID_CP2112=m +CONFIG_HID_CYPRESS=y +CONFIG_HID_DRAGONRISE=m +CONFIG_DRAGONRISE_FF=y +CONFIG_HID_EMS_FF=m +CONFIG_HID_ELECOM=m +CONFIG_HID_ELO=m +CONFIG_HID_EZKEY=y +CONFIG_HID_HOLTEK=m +CONFIG_HOLTEK_FF=y +CONFIG_HID_GT683R=m +CONFIG_HID_HUION=m +CONFIG_HID_KEYTOUCH=m +CONFIG_HID_KYE=m +CONFIG_HID_UCLOGIC=m +CONFIG_HID_WALTOP=m +CONFIG_HID_GYRATION=m +CONFIG_HID_ICADE=m +CONFIG_HID_TWINHAN=m +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LCPOWER=m +CONFIG_HID_LENOVO=m +CONFIG_HID_LOGITECH=y +CONFIG_HID_LOGITECH_DJ=m +CONFIG_HID_LOGITECH_HIDPP=m +CONFIG_LOGITECH_FF=y +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGIG940_FF=y +CONFIG_LOGIWHEELS_FF=y +CONFIG_HID_MAGICMOUSE=m +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_MULTITOUCH=m +CONFIG_HID_NTRIG=y +CONFIG_HID_ORTEK=m +CONFIG_HID_PANTHERLORD=m +CONFIG_PANTHERLORD_FF=y +# CONFIG_HID_PENMOUNT is not set +CONFIG_HID_PETALYNX=m +CONFIG_HID_PICOLCD=m +CONFIG_HID_PICOLCD_FB=y +CONFIG_HID_PICOLCD_BACKLIGHT=y +CONFIG_HID_PICOLCD_LCD=y +CONFIG_HID_PICOLCD_LEDS=y +CONFIG_HID_PICOLCD_CIR=y +CONFIG_HID_PLANTRONICS=y +CONFIG_HID_PRIMAX=m +CONFIG_HID_ROCCAT=m +CONFIG_HID_SAITEK=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_SONY_FF=y +CONFIG_HID_SPEEDLINK=m +CONFIG_HID_STEELSERIES=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_RMI=m +CONFIG_HID_GREENASIA=m +CONFIG_GREENASIA_FF=y +CONFIG_HID_HYPERV_MOUSE=m +CONFIG_HID_SMARTJOYPLUS=m +CONFIG_SMARTJOYPLUS_FF=y +CONFIG_HID_TIVO=m +CONFIG_HID_TOPSEED=m +CONFIG_HID_THINGM=m +CONFIG_HID_THRUSTMASTER=m +CONFIG_THRUSTMASTER_FF=y +CONFIG_HID_WACOM=m +CONFIG_HID_WIIMOTE=m +CONFIG_HID_XINMO=m +CONFIG_HID_ZEROPLUS=m +CONFIG_ZEROPLUS_FF=y +CONFIG_HID_ZYDACRON=m +CONFIG_HID_SENSOR_HUB=m + +# +# USB HID support +# +CONFIG_USB_HID=y +CONFIG_HID_PID=y +CONFIG_USB_HIDDEV=y + +# +# I2C HID support +# +CONFIG_I2C_HID=m +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_SUPPORT=y +CONFIG_USB_COMMON=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_OTG=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_OTG_FSM=m +CONFIG_USB_MON=y +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PCI=y +CONFIG_USB_XHCI_PLATFORM=m +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +# CONFIG_USB_EHCI_HCD_PLATFORM is not set +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_ISP1362_HCD=m +CONFIG_USB_FUSBH200_HCD=m +CONFIG_USB_FOTG210_HCD=m +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PCI=y +# CONFIG_USB_OHCI_HCD_PLATFORM is not set +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_U132_HCD=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SL811_HCD_ISO=y +# CONFIG_USB_SL811_CS is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_WHCI_HCD=m +CONFIG_USB_HWA_HCD=m +# CONFIG_USB_HCD_BCMA is not set +# CONFIG_USB_HCD_SSB is not set +# CONFIG_USB_HCD_TEST_MODE is not set + +# +# USB Device Class drivers +# +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m +CONFIG_USB_WDM=m +CONFIG_USB_TMC=m + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_REALTEK=m +CONFIG_REALTEK_AUTOPM=y +CONFIG_USB_STORAGE_DATAFAB=m +CONFIG_USB_STORAGE_FREECOM=m +CONFIG_USB_STORAGE_ISD200=m +CONFIG_USB_STORAGE_USBAT=m +CONFIG_USB_STORAGE_SDDR09=m +CONFIG_USB_STORAGE_SDDR55=m +CONFIG_USB_STORAGE_JUMPSHOT=m +CONFIG_USB_STORAGE_ALAUDA=m +CONFIG_USB_STORAGE_ONETOUCH=m +CONFIG_USB_STORAGE_KARMA=m +CONFIG_USB_STORAGE_CYPRESS_ATACB=m +CONFIG_USB_STORAGE_ENE_UB6250=m +CONFIG_USB_UAS=m + +# +# USB Imaging devices +# +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USBIP_CORE is not set +CONFIG_USB_MUSB_HDRC=m +CONFIG_USB_MUSB_HOST=y + +# +# Platform Glue Layer +# +CONFIG_MUSB_PIO_ONLY=y +CONFIG_USB_DWC3=m +CONFIG_USB_DWC3_HOST=y + +# +# Platform Glue Driver Support +# +CONFIG_USB_DWC3_PCI=m + +# +# Debugging features +# +# CONFIG_USB_DWC3_DEBUG is not set +CONFIG_DWC3_HOST_USB3_LPM_ENABLE=y +CONFIG_USB_DWC2=y +CONFIG_USB_DWC2_HOST=y + +# +# Gadget/Dual-role mode requires USB Gadget support to be enabled +# +CONFIG_USB_DWC2_PLATFORM=y +CONFIG_USB_DWC2_PCI=y +# CONFIG_USB_DWC2_DEBUG is not set +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set +# CONFIG_USB_CHIPIDEA is not set +CONFIG_USB_ISP1760=m +CONFIG_USB_ISP1760_HCD=y +CONFIG_USB_ISP1760_HOST_ROLE=y + +# +# USB port drivers +# +CONFIG_USB_USS720=m +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_SIMPLE is not set +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP210X=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +# CONFIG_USB_SERIAL_F81232 is not set +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +# CONFIG_USB_SERIAL_METRO is not set +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7715_PARPORT=y +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MXUPORT=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_QCAUX=m +CONFIG_USB_SERIAL_QUALCOMM=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SYMBOL=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_WWAN=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTICON=m +CONFIG_USB_SERIAL_XSENS_MT=m +CONFIG_USB_SERIAL_WISHBONE=m +CONFIG_USB_SERIAL_SSU100=m +CONFIG_USB_SERIAL_QT2=m +CONFIG_USB_SERIAL_DEBUG=m + +# +# USB Miscellaneous drivers +# +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_SEVSEG=m +# CONFIG_USB_RIO500 is not set +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_LED=m +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +CONFIG_USB_IDMOUSE=m +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_LD=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_IOWARRIOR=m +# CONFIG_USB_TEST is not set +# CONFIG_USB_EHSET_TEST_FIXTURE is not set +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_YUREX=m +CONFIG_USB_EZUSB_FX2=m +CONFIG_USB_HSIC_USB3503=m +# CONFIG_USB_LINK_LAYER_TEST is not set +CONFIG_USB_ATM=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_CXACRU=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_XUSBATM=m + +# +# USB Physical Layer drivers +# +CONFIG_USB_PHY=y +CONFIG_NOP_USB_XCEIV=m +CONFIG_USB_GPIO_VBUS=m +CONFIG_USB_ISP1301=m +# CONFIG_USB_GADGET is not set +# CONFIG_USB_LED_TRIG is not set +CONFIG_UWB=m +CONFIG_UWB_HWA=m +CONFIG_UWB_WHCI=m +CONFIG_UWB_I1480U=m +CONFIG_MMC=m +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_CLKGATE is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y +CONFIG_SDIO_UART=m +# CONFIG_MMC_TEST is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_RICOH_MMC=y +CONFIG_MMC_SDHCI_ACPI=m +CONFIG_MMC_SDHCI_PLTFM=m +CONFIG_MMC_WBSD=m +CONFIG_MMC_TIFM_SD=m +CONFIG_MMC_SDRICOH_CS=m +CONFIG_MMC_CB710=m +CONFIG_MMC_VIA_SDMMC=m +CONFIG_MMC_VUB300=m +CONFIG_MMC_USHC=m +CONFIG_MMC_USDHI6ROL0=m +CONFIG_MMC_REALTEK_PCI=m +CONFIG_MMC_REALTEK_USB=m +# CONFIG_MMC_TOSHIBA_PCI is not set +CONFIG_MEMSTICK=m +# CONFIG_MEMSTICK_DEBUG is not set + +# +# MemoryStick drivers +# +# CONFIG_MEMSTICK_UNSAFE_RESUME is not set +CONFIG_MSPRO_BLOCK=m +# CONFIG_MS_BLOCK is not set + +# +# MemoryStick Host Controller Drivers +# +CONFIG_MEMSTICK_TIFM_MS=m +CONFIG_MEMSTICK_JMICRON_38X=m +CONFIG_MEMSTICK_R592=m +CONFIG_MEMSTICK_REALTEK_PCI=m +CONFIG_MEMSTICK_REALTEK_USB=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=m + +# +# LED drivers +# +CONFIG_LEDS_LM3530=m +CONFIG_LEDS_LM3642=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_PCA9532_GPIO=y +CONFIG_LEDS_GPIO=m +CONFIG_LEDS_LP3944=m +CONFIG_LEDS_LP55XX_COMMON=m +CONFIG_LEDS_LP5521=m +CONFIG_LEDS_LP5523=m +CONFIG_LEDS_LP5562=m +CONFIG_LEDS_LP8501=m +# CONFIG_LEDS_LP8860 is not set +CONFIG_LEDS_CLEVO_MAIL=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_PCA963X=m +CONFIG_LEDS_PWM=m +CONFIG_LEDS_BD2802=m +CONFIG_LEDS_INTEL_SS4200=m +CONFIG_LEDS_LT3593=m +CONFIG_LEDS_DELL_NETBOOKS=m +CONFIG_LEDS_TCA6507=m +CONFIG_LEDS_LM355x=m + +# +# LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) +# +CONFIG_LEDS_BLINKM=m + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m + +# +# iptables trigger is under Netfilter config (LED target) +# +CONFIG_LEDS_TRIGGER_TRANSIENT=m +CONFIG_LEDS_TRIGGER_CAMERA=m +CONFIG_ACCESSIBILITY=y +CONFIG_A11Y_BRAILLE_CONSOLE=y +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFINIBAND_ON_DEMAND_PAGING=y +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +CONFIG_INFINIBAND_IPATH=m +CONFIG_INFINIBAND_QIB=m +CONFIG_INFINIBAND_QIB_DCA=y +CONFIG_INFINIBAND_AMSO1100=m +# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_CXGB4=m +CONFIG_MLX4_INFINIBAND=m +# CONFIG_MLX5_INFINIBAND is not set +CONFIG_INFINIBAND_NES=m +# CONFIG_INFINIBAND_NES_DEBUG is not set +# CONFIG_INFINIBAND_OCRDMA is not set +CONFIG_INFINIBAND_USNIC=m +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_SRPT=m +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_ISERT=m +CONFIG_EDAC=y +CONFIG_EDAC_LEGACY_SYSFS=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_DECODE_MCE=m +CONFIG_EDAC_MCE_INJ=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_AMD64=m +# CONFIG_EDAC_AMD64_ERROR_INJECTION is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I3200=m +CONFIG_EDAC_IE31200=m +CONFIG_EDAC_X38=m +CONFIG_EDAC_I5400=m +CONFIG_EDAC_I7CORE=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I7300=m +CONFIG_EDAC_SBRIDGE=m +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_SYSTOHC=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +CONFIG_RTC_DRV_ABB5ZES3=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +# CONFIG_RTC_DRV_DS1374_WDT is not set +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS3232=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_ISL12022=m +CONFIG_RTC_DRV_ISL12057=m +CONFIG_RTC_DRV_X1205=m +# CONFIG_RTC_DRV_PCF2127 is not set +CONFIG_RTC_DRV_PCF8523=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF85063=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_BQ32K=m +# CONFIG_RTC_DRV_S35390A is not set +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_RX8025=m +CONFIG_RTC_DRV_EM3027=m +CONFIG_RTC_DRV_RV3029C2=m + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1511=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1685_FAMILY=m +CONFIG_RTC_DRV_DS1685=y +# CONFIG_RTC_DRV_DS1689 is not set +# CONFIG_RTC_DRV_DS17285 is not set +# CONFIG_RTC_DRV_DS17485 is not set +# CONFIG_RTC_DRV_DS17885 is not set +CONFIG_RTC_DS1685_PROC_REGS=y +CONFIG_RTC_DS1685_SYSFS_REGS=y +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_DS2404=m +CONFIG_RTC_DRV_STK17TA8=m +# CONFIG_RTC_DRV_M48T86 is not set +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_MSM6242=m +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_RP5C01=m +CONFIG_RTC_DRV_V3020=m + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_XGENE=m + +# +# HID Sensor RTC drivers +# +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set +CONFIG_DMADEVICES=y +# CONFIG_DMADEVICES_DEBUG is not set + +# +# DMA Devices +# +CONFIG_INTEL_MIC_X100_DMA=m +# CONFIG_INTEL_MID_DMAC is not set +CONFIG_INTEL_IOATDMA=m +# CONFIG_DW_DMAC_CORE is not set +# CONFIG_DW_DMAC is not set +# CONFIG_DW_DMAC_PCI is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMA_ACPI=y + +# +# DMA Clients +# +CONFIG_ASYNC_TX_DMA=y +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE_RAID=y +CONFIG_DCA=m +CONFIG_AUXDISPLAY=y +CONFIG_KS0108=m +CONFIG_KS0108_PORT=0x378 +CONFIG_KS0108_DELAY=2 +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_UIO=m +CONFIG_UIO_CIF=m +# CONFIG_UIO_PDRV_GENIRQ is not set +CONFIG_UIO_DMEM_GENIRQ=m +CONFIG_UIO_AEC=m +CONFIG_UIO_SERCOS3=m +CONFIG_UIO_PCI_GENERIC=m +# CONFIG_UIO_NETX is not set +# CONFIG_UIO_MF624 is not set +CONFIG_VFIO_IOMMU_TYPE1=y +CONFIG_VFIO=y +CONFIG_VFIO_PCI=y +CONFIG_VFIO_PCI_VGA=y +CONFIG_VFIO_PCI_MMAP=y +CONFIG_VFIO_PCI_INTX=y +# CONFIG_VIRT_DRIVERS is not set +CONFIG_VIRTIO=y + +# +# Virtio drivers +# +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_PCI_LEGACY=y +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_MMIO=m +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set + +# +# Microsoft Hyper-V guest support +# +CONFIG_HYPERV=m +CONFIG_HYPERV_UTILS=m +CONFIG_HYPERV_BALLOON=m + +# +# Xen driver support +# +CONFIG_XEN_BALLOON=y +CONFIG_XEN_SELFBALLOONING=y +# CONFIG_XEN_BALLOON_MEMORY_HOTPLUG is not set +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XEN_DEV_EVTCHN=m +CONFIG_XEN_BACKEND=y +CONFIG_XENFS=m +CONFIG_XEN_COMPAT_XENFS=y +CONFIG_XEN_SYS_HYPERVISOR=y +CONFIG_XEN_XENBUS_FRONTEND=y +CONFIG_XEN_GNTDEV=m +CONFIG_XEN_GRANT_DEV_ALLOC=m +CONFIG_SWIOTLB_XEN=y +CONFIG_XEN_TMEM=m +CONFIG_XEN_PCIDEV_BACKEND=m +# CONFIG_XEN_SCSI_BACKEND is not set +CONFIG_XEN_PRIVCMD=m +CONFIG_XEN_ACPI_PROCESSOR=m +CONFIG_XEN_MCE_LOG=y +CONFIG_XEN_HAVE_PVMMU=y +CONFIG_XEN_EFI=y +CONFIG_STAGING=y +# CONFIG_SLICOSS is not set +# CONFIG_PRISM2_USB is not set +# CONFIG_COMEDI is not set +# CONFIG_PANEL is not set +# CONFIG_RTL8192U is not set +# CONFIG_RTLLIB is not set +CONFIG_R8712U=m +CONFIG_R8188EU=m +CONFIG_88EU_AP_MODE=y +CONFIG_R8723AU=m +CONFIG_8723AU_AP_MODE=y +CONFIG_8723AU_BT_COEXIST=y +CONFIG_RTS5208=m +# CONFIG_VT6655 is not set +# CONFIG_VT6656 is not set +CONFIG_FB_SM7XX=m +# CONFIG_FB_XGI is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +CONFIG_STAGING_MEDIA=y +CONFIG_I2C_BCM2048=m +# CONFIG_DVB_CXD2099 is not set +# CONFIG_VIDEO_DT3155 is not set +# CONFIG_DVB_MN88472 is not set +# CONFIG_DVB_MN88473 is not set +CONFIG_LIRC_STAGING=y +CONFIG_LIRC_BT829=m +CONFIG_LIRC_IMON=m +CONFIG_LIRC_PARALLEL=m +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_LIRC_SERIAL_TRANSMITTER=y +CONFIG_LIRC_SIR=m +CONFIG_LIRC_ZILOG=m + +# +# Android +# +# CONFIG_ASHMEM is not set +CONFIG_ANDROID_TIMED_OUTPUT=y +CONFIG_ANDROID_TIMED_GPIO=m +# CONFIG_ANDROID_LOW_MEMORY_KILLER is not set +CONFIG_SYNC=y +CONFIG_SW_SYNC=y +CONFIG_SW_SYNC_USER=y +# CONFIG_ION is not set +CONFIG_USB_WPAN_HCD=m +CONFIG_WIMAX_GDM72XX=m +CONFIG_WIMAX_GDM72XX_QOS=y +CONFIG_WIMAX_GDM72XX_K_MODE=y +CONFIG_WIMAX_GDM72XX_WIMAX2=y +CONFIG_WIMAX_GDM72XX_USB=y +# CONFIG_WIMAX_GDM72XX_SDIO is not set +CONFIG_WIMAX_GDM72XX_USB_PM=y +CONFIG_LTE_GDM724X=m +CONFIG_FIREWIRE_SERIAL=m +CONFIG_FWTTY_MAX_TOTAL_PORTS=64 +CONFIG_FWTTY_MAX_CARD_PORTS=32 +# CONFIG_LUSTRE_FS is not set +CONFIG_DGNC=m +CONFIG_DGAP=m +# CONFIG_GS_FPGABOOT is not set +# CONFIG_CRYPTO_SKEIN is not set +CONFIG_UNISYSSPAR=y +CONFIG_UNISYS_VISORUTIL=m +CONFIG_UNISYS_VISORCHANNEL=m +CONFIG_UNISYS_VISORCHIPSET=m +CONFIG_UNISYS_UISLIB=m +CONFIG_UNISYS_VIRTPCI=m +CONFIG_UNISYS_VIRTHBA=m +# CONFIG_I2O is not set +CONFIG_X86_PLATFORM_DEVICES=y +CONFIG_ACER_WMI=m +CONFIG_ACERHDF=m +CONFIG_ALIENWARE_WMI=m +CONFIG_ASUS_LAPTOP=m +CONFIG_DELL_LAPTOP=m +CONFIG_DELL_WMI=m +CONFIG_DELL_WMI_AIO=m +CONFIG_DELL_SMO8800=m +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +CONFIG_FUJITSU_TABLET=m +CONFIG_AMILO_RFKILL=m +CONFIG_HP_ACCEL=m +CONFIG_HP_WIRELESS=m +CONFIG_HP_WMI=m +CONFIG_MSI_LAPTOP=m +CONFIG_PANASONIC_LAPTOP=m +CONFIG_COMPAL_LAPTOP=m +CONFIG_SONY_LAPTOP=m +CONFIG_SONYPI_COMPAT=y +CONFIG_IDEAPAD_LAPTOP=m +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_ALSA_SUPPORT=y +# CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set +# CONFIG_THINKPAD_ACPI_DEBUG is not set +# CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_SENSORS_HDAPS=m +CONFIG_INTEL_MENLOW=m +CONFIG_EEEPC_LAPTOP=m +CONFIG_ASUS_WMI=m +CONFIG_ASUS_NB_WMI=m +CONFIG_EEEPC_WMI=m +CONFIG_ACPI_WMI=m +CONFIG_MSI_WMI=m +CONFIG_TOPSTAR_LAPTOP=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_TOSHIBA_BT_RFKILL=m +CONFIG_TOSHIBA_HAPS=m +CONFIG_ACPI_CMPC=m +CONFIG_INTEL_IPS=m +# CONFIG_IBM_RTL is not set +CONFIG_SAMSUNG_LAPTOP=m +CONFIG_MXM_WMI=m +CONFIG_INTEL_OAKTRAIL=m +CONFIG_SAMSUNG_Q10=m +CONFIG_APPLE_GMUX=m +CONFIG_INTEL_RST=m +# CONFIG_INTEL_SMARTCONNECT is not set +CONFIG_PVPANIC=m +CONFIG_CHROME_PLATFORMS=y +CONFIG_CHROMEOS_LAPTOP=m +CONFIG_CHROMEOS_PSTORE=m +CONFIG_CLKDEV_LOOKUP=y +CONFIG_HAVE_CLK_PREPARE=y +CONFIG_COMMON_CLK=y + +# +# Common Clock Framework +# +CONFIG_COMMON_CLK_SI5351=m +# CONFIG_COMMON_CLK_PXA is not set +CONFIG_COMMON_CLK_CDCE706=m + +# +# Hardware Spinlock drivers +# + +# +# Clock Source drivers +# +CONFIG_CLKEVT_I8253=y +CONFIG_I8253_LOCK=y +CONFIG_CLKBLD_I8253=y +# CONFIG_ATMEL_PIT is not set +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_EM_TIMER_STI is not set +CONFIG_MAILBOX=y +# CONFIG_PCC is not set +CONFIG_ALTERA_MBOX=m +CONFIG_IOMMU_API=y +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +CONFIG_IOMMU_IOVA=y +CONFIG_AMD_IOMMU=y +CONFIG_AMD_IOMMU_STATS=y +CONFIG_AMD_IOMMU_V2=m +CONFIG_DMAR_TABLE=y +CONFIG_INTEL_IOMMU=y +# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set +CONFIG_INTEL_IOMMU_FLOPPY_WA=y +CONFIG_IRQ_REMAP=y + +# +# Remoteproc drivers +# +CONFIG_REMOTEPROC=m +CONFIG_STE_MODEM_RPROC=m + +# +# Rpmsg drivers +# + +# +# SOC (System On Chip) specific Drivers +# +# CONFIG_SOC_TI is not set +CONFIG_PM_DEVFREQ=y + +# +# DEVFREQ Governors +# +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=m +# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set +# CONFIG_DEVFREQ_GOV_POWERSAVE is not set +# CONFIG_DEVFREQ_GOV_USERSPACE is not set + +# +# DEVFREQ Drivers +# +CONFIG_PM_DEVFREQ_EVENT=y +# CONFIG_EXTCON is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +CONFIG_NTB=m +# CONFIG_VME_BUS is not set +CONFIG_PWM=y +CONFIG_PWM_SYSFS=y +CONFIG_PWM_LP3943=m +CONFIG_PWM_LPSS=m +# CONFIG_PWM_LPSS_PCI is not set +# CONFIG_PWM_LPSS_PLATFORM is not set +# CONFIG_IPACK_BUS is not set +CONFIG_RESET_CONTROLLER=y +# CONFIG_FMC is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=y +CONFIG_BCM_KONA_USB2_PHY=m +CONFIG_PHY_SAMSUNG_USB2=m +# CONFIG_PHY_EXYNOS4210_USB2 is not set +# CONFIG_PHY_EXYNOS4X12_USB2 is not set +# CONFIG_PHY_EXYNOS5250_USB2 is not set +CONFIG_POWERCAP=y +CONFIG_INTEL_RAPL=m +# CONFIG_MCB is not set +CONFIG_RAS=y +CONFIG_THUNDERBOLT=m + +# +# Android +# +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y + +# +# Firmware Drivers +# +CONFIG_EDD=m +# CONFIG_EDD_OFF is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_DELL_RBU=m +CONFIG_DCDBAS=m +CONFIG_DMIID=y +CONFIG_DMI_SYSFS=y +CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_IBFT=m +CONFIG_GOOGLE_FIRMWARE=y + +# +# Google Firmware Drivers +# +CONFIG_GOOGLE_SMI=m +# CONFIG_GOOGLE_MEMCONSOLE is not set + +# +# EFI (Extensible Firmware Interface) Support +# +CONFIG_EFI_VARS=y +CONFIG_EFI_VARS_PSTORE=y +# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set +CONFIG_EFI_RUNTIME_MAP=y +CONFIG_EFI_RUNTIME_WRAPPERS=y +CONFIG_UEFI_CPER=y + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=m +CONFIG_EXT3_DEFAULTS_TO_ORDERED=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +CONFIG_FS_MBCACHE=y +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_PROC_INFO=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +CONFIG_XFS_FS=m +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_WARN is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +# CONFIG_OCFS2_FS_STATS is not set +# CONFIG_OCFS2_DEBUG_MASKLOG is not set +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set +# CONFIG_BTRFS_DEBUG is not set +# CONFIG_BTRFS_ASSERT is not set +CONFIG_NILFS2_FS=m +CONFIG_FS_DAX=y +CONFIG_FS_POSIX_ACL=y +CONFIG_EXPORTFS=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +CONFIG_DNOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_FANOTIFY=y +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y +CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +# CONFIG_PRINT_QUOTA_WARNING is not set +# CONFIG_QUOTA_DEBUG is not set +CONFIG_QUOTA_TREE=y +# CONFIG_QFMT_V1 is not set +CONFIG_QFMT_V2=y +CONFIG_QUOTACTL=y +CONFIG_QUOTACTL_COMPAT=y +CONFIG_AUTOFS4_FS=y +CONFIG_FUSE_FS=m +CONFIG_CUSE=m +CONFIG_OVERLAY_FS=y + +# +# Caches +# +CONFIG_FSCACHE=m +CONFIG_FSCACHE_STATS=y +# CONFIG_FSCACHE_HISTOGRAM is not set +# CONFIG_FSCACHE_DEBUG is not set +CONFIG_FSCACHE_OBJECT_LIST=y +CONFIG_CACHEFILES=m +# CONFIG_CACHEFILES_DEBUG is not set +# CONFIG_CACHEFILES_HISTOGRAM is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="ascii" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_VMCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_KERNFS=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_CONFIGFS_FS=y +CONFIG_EFIVAR_FS=m +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +CONFIG_AFFS_FS=m +CONFIG_ECRYPT_FS=m +CONFIG_ECRYPT_FS_MESSAGING=y +CONFIG_HFS_FS=m +CONFIG_HFSPLUS_FS=m +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set +CONFIG_BEFS_FS=m +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_LOGFS is not set +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +# CONFIG_SQUASHFS_DECOMP_MULTI is not set +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +# CONFIG_SQUASHFS_LZ4 is not set +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +CONFIG_MINIX_FS=m +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +CONFIG_ROMFS_FS=m +CONFIG_ROMFS_BACKED_BY_BLOCK=y +# CONFIG_ROMFS_BACKED_BY_MTD is not set +# CONFIG_ROMFS_BACKED_BY_BOTH is not set +CONFIG_ROMFS_ON_BLOCK=y +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_PMSG=y +CONFIG_PSTORE_FTRACE=y +CONFIG_PSTORE_RAM=m +CONFIG_SYSV_FS=m +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_UFS_DEBUG is not set +# CONFIG_EXOFS_FS is not set +CONFIG_F2FS_FS=m +CONFIG_F2FS_STAT_FS=y +CONFIG_F2FS_FS_XATTR=y +CONFIG_F2FS_FS_POSIX_ACL=y +# CONFIG_F2FS_FS_SECURITY is not set +# CONFIG_F2FS_CHECK_FS is not set +CONFIG_F2FS_IO_TRACE=y +CONFIG_ORE=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V2=m +CONFIG_NFS_V3=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=m +CONFIG_NFS_SWAP=y +CONFIG_NFS_V4_1=y +# CONFIG_NFS_V4_2 is not set +CONFIG_PNFS_FILE_LAYOUT=m +CONFIG_PNFS_BLOCK=m +CONFIG_PNFS_OBJLAYOUT=m +CONFIG_PNFS_FLEXFILE_LAYOUT=m +CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" +# CONFIG_NFS_V4_1_MIGRATION is not set +CONFIG_NFS_FSCACHE=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFS_DEBUG=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFSD_PNFS=y +# CONFIG_NFSD_V4_SECURITY_LABEL is not set +CONFIG_GRACE_PERIOD=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUNRPC_BACKCHANNEL=y +CONFIG_SUNRPC_SWAP=y +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_SUNRPC_DEBUG=y +CONFIG_SUNRPC_XPRT_RDMA_CLIENT=m +CONFIG_SUNRPC_XPRT_RDMA_SERVER=m +CONFIG_CEPH_FS=m +# CONFIG_CEPH_FSCACHE is not set +CONFIG_CEPH_FS_POSIX_ACL=y +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +# CONFIG_CIFS_STATS2 is not set +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_CIFS_ACL=y +# CONFIG_CIFS_DEBUG is not set +CONFIG_CIFS_DFS_UPCALL=y +# CONFIG_CIFS_SMB2 is not set +CONFIG_CIFS_FSCACHE=y +CONFIG_NCP_FS=m +CONFIG_NCPFS_PACKET_SIGNING=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_STRONG=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_SMALLDOS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_EXTRAS=y +CONFIG_CODA_FS=m +# CONFIG_AFS_FS is not set +CONFIG_9P_FS=m +CONFIG_9P_FSCACHE=y +CONFIG_9P_FS_POSIX_ACL=y +# CONFIG_9P_FS_SECURITY is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_ISO8859_8=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_2=m +CONFIG_NLS_ISO8859_3=m +CONFIG_NLS_ISO8859_4=m +CONFIG_NLS_ISO8859_5=m +CONFIG_NLS_ISO8859_6=m +CONFIG_NLS_ISO8859_7=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_MAC_ROMAN=m +CONFIG_NLS_MAC_CELTIC=m +CONFIG_NLS_MAC_CENTEURO=m +CONFIG_NLS_MAC_CROATIAN=m +CONFIG_NLS_MAC_CYRILLIC=m +CONFIG_NLS_MAC_GAELIC=m +CONFIG_NLS_MAC_GREEK=m +CONFIG_NLS_MAC_ICELAND=m +CONFIG_NLS_MAC_INUIT=m +CONFIG_NLS_MAC_ROMANIAN=m +CONFIG_NLS_MAC_TURKISH=m +CONFIG_NLS_UTF8=m +CONFIG_DLM=m +CONFIG_DLM_DEBUG=y + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y + +# +# printk and dmesg options +# +CONFIG_PRINTK_TIME=y +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 +CONFIG_DYNAMIC_DEBUG=y + +# +# Compile-time checks and compiler options +# +# CONFIG_ENABLE_WARN_DEPRECATED is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=2048 +CONFIG_STRIP_ASM_SYMS=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_DEBUG_FS=y +CONFIG_HEADERS_CHECK=y +CONFIG_DEBUG_SECTION_MISMATCH=y +CONFIG_ARCH_WANT_FRAME_POINTERS=y +CONFIG_FRAME_POINTER=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 +# CONFIG_DEBUG_KERNEL is not set + +# +# Memory Debugging +# +# CONFIG_PAGE_EXTENSION is not set +CONFIG_HAVE_DEBUG_KMEMLEAK=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_HAVE_DEBUG_STACKOVERFLOW=y +CONFIG_HAVE_ARCH_KMEMCHECK=y +CONFIG_HAVE_ARCH_KASAN=y +CONFIG_KASAN_SHADOW_OFFSET=0xdffffc0000000000 + +# +# Debug Lockups and Hangs +# +# CONFIG_PANIC_ON_OOPS is not set +CONFIG_PANIC_ON_OOPS_VALUE=0 +CONFIG_PANIC_TIMEOUT=0 + +# +# Lock Debugging (spinlocks, mutexes, etc...) +# +CONFIG_STACKTRACE=y +CONFIG_DEBUG_BUGVERBOSE=y + +# +# RCU Debugging +# +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y +CONFIG_USER_STACKTRACE_SUPPORT=y +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_FENTRY=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_RING_BUFFER_ALLOW_SWAP=y +CONFIG_TRACING=y +CONFIG_GENERIC_TRACER=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y +CONFIG_FUNCTION_TRACER=y +CONFIG_FUNCTION_GRAPH_TRACER=y +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_SCHED_TRACER=y +CONFIG_FTRACE_SYSCALLS=y +CONFIG_TRACER_SNAPSHOT=y +CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y +CONFIG_BRANCH_PROFILE_NONE=y +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set +# CONFIG_PROFILE_ALL_BRANCHES is not set +CONFIG_STACK_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_KPROBE_EVENT=y +CONFIG_UPROBE_EVENT=y +CONFIG_PROBE_EVENTS=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_FUNCTION_PROFILER=y +CONFIG_FTRACE_MCOUNT_RECORD=y +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_MMIOTRACE is not set +# CONFIG_TRACEPOINT_BENCHMARK is not set +CONFIG_RING_BUFFER_BENCHMARK=m +# CONFIG_RING_BUFFER_STARTUP_TEST is not set + +# +# Runtime Testing +# +# CONFIG_LKDTM is not set +CONFIG_ATOMIC64_SELFTEST=y +CONFIG_ASYNC_RAID6_TEST=m +CONFIG_TEST_HEXDUMP=m +# CONFIG_TEST_STRING_HELPERS is not set +CONFIG_TEST_KSTRTOX=y +# CONFIG_TEST_RHASHTABLE is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_BUILD_DOCSRC is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_TEST_LKM is not set +# CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set +# CONFIG_TEST_FIRMWARE is not set +# CONFIG_TEST_UDELAY is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_STRICT_DEVMEM=y +# CONFIG_X86_VERBOSE_BOOTUP is not set +CONFIG_EARLY_PRINTK=y +CONFIG_EARLY_PRINTK_DBGP=y +# CONFIG_EARLY_PRINTK_EFI is not set +CONFIG_DEBUG_SET_MODULE_RONX=y +CONFIG_DOUBLEFAULT=y +# CONFIG_IOMMU_STRESS is not set +CONFIG_HAVE_MMIOTRACE_SUPPORT=y +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_0X80=y +# CONFIG_IO_DELAY_0XED is not set +# CONFIG_IO_DELAY_UDELAY is not set +# CONFIG_IO_DELAY_NONE is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=0 +CONFIG_OPTIMIZE_INLINING=y + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS is not set +# CONFIG_BIG_KEYS is not set +CONFIG_TRUSTED_KEYS=m +CONFIG_ENCRYPTED_KEYS=m +# CONFIG_SECURITY_DMESG_RESTRICT is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_NETWORK_XFRM=y +CONFIG_SECURITY_PATH=y +CONFIG_INTEL_TXT=y +# CONFIG_SECURITY_SELINUX is not set +# CONFIG_SECURITY_SMACK is not set +CONFIG_SECURITY_TOMOYO=y +CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048 +CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024 +# CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set +CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init" +CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init" +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_APPARMOR_HASH=y +# CONFIG_SECURITY_YAMA is not set +CONFIG_INTEGRITY=y +# CONFIG_INTEGRITY_SIGNATURE is not set +CONFIG_INTEGRITY_AUDIT=y +# CONFIG_IMA is not set +# CONFIG_EVM is not set +CONFIG_DEFAULT_SECURITY_TOMOYO=y +# CONFIG_DEFAULT_SECURITY_APPARMOR is not set +# CONFIG_DEFAULT_SECURITY_DAC is not set +CONFIG_DEFAULT_SECURITY="tomoyo" +CONFIG_XOR_BLOCKS=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ASYNC_PQ=m +CONFIG_ASYNC_RAID6_RECOV=m +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP=m +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_USER=m +# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCRYPT=m +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=y +# CONFIG_CRYPTO_MCRYPTD is not set +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_ABLK_HELPER=m +CONFIG_CRYPTO_GLUE_HELPER_X86=m + +# +# Authenticated Encryption with Associated Data +# +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_SEQIV=y + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_LRW=y +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_XTS=y + +# +# Hash modes +# +CONFIG_CRYPTO_CMAC=m +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_VMAC=m + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_CRC32=y +CONFIG_CRYPTO_CRC32_PCLMUL=m +CONFIG_CRYPTO_CRCT10DIF=y +# CONFIG_CRYPTO_CRCT10DIF_PCLMUL is not set +CONFIG_CRYPTO_GHASH=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA1_SSSE3=m +CONFIG_CRYPTO_SHA256_SSSE3=m +CONFIG_CRYPTO_SHA512_SSSE3=m +# CONFIG_CRYPTO_SHA1_MB is not set +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=m + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_AES_X86_64=m +CONFIG_CRYPTO_AES_NI_INTEL=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_BLOWFISH_COMMON=m +CONFIG_CRYPTO_BLOWFISH_X86_64=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAMELLIA_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=m +CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=m +CONFIG_CRYPTO_CAST_COMMON=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST5_AVX_X86_64=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CAST6_AVX_X86_64=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DES3_EDE_X86_64=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SALSA20_X86_64=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SERPENT_SSE2_X86_64=m +CONFIG_CRYPTO_SERPENT_AVX_X86_64=m +CONFIG_CRYPTO_SERPENT_AVX2_X86_64=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH_X86_64=m +CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=m +CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_ZLIB=m +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +# CONFIG_CRYPTO_DRBG_CTR is not set +CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_USER_API=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_CRYPTO_USER_API_RNG=m +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_DEV_PADLOCK=m +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_DEV_CCP=y +CONFIG_CRYPTO_DEV_CCP_DD=m +CONFIG_CRYPTO_DEV_CCP_CRYPTO=m +CONFIG_CRYPTO_DEV_QAT=m +CONFIG_CRYPTO_DEV_QAT_DH895xCC=m +CONFIG_ASYMMETRIC_KEY_TYPE=m +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m +CONFIG_PUBLIC_KEY_ALGO_RSA=m +CONFIG_X509_CERTIFICATE_PARSER=m +# CONFIG_PKCS7_MESSAGE_PARSER is not set +CONFIG_HAVE_KVM=y +CONFIG_HAVE_KVM_IRQCHIP=y +CONFIG_HAVE_KVM_IRQFD=y +CONFIG_HAVE_KVM_IRQ_ROUTING=y +CONFIG_HAVE_KVM_EVENTFD=y +CONFIG_KVM_APIC_ARCHITECTURE=y +CONFIG_KVM_MMIO=y +CONFIG_KVM_ASYNC_PF=y +CONFIG_HAVE_KVM_MSI=y +CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y +CONFIG_KVM_VFIO=y +CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y +CONFIG_KVM_COMPAT=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_KVM_INTEL=m +CONFIG_KVM_AMD=m +CONFIG_KVM_MMU_AUDIT=y +CONFIG_KVM_DEVICE_ASSIGNMENT=y +CONFIG_BINARY_PRINTF=y + +# +# Library routines +# +CONFIG_RAID6_PQ=m +CONFIG_BITREVERSE=y +# CONFIG_HAVE_ARCH_BITREVERSE is not set +CONFIG_RATIONAL=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_NET_UTILS=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IO=y +CONFIG_PERCPU_RWSEM=y +CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y +CONFIG_ARCH_HAS_FAST_MULTIPLIER=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC_ITU_T=m +CONFIG_CRC32=y +# CONFIG_CRC32_SELFTEST is not set +CONFIG_CRC32_SLICEBY8=y +# CONFIG_CRC32_SLICEBY4 is not set +# CONFIG_CRC32_SARWATE is not set +# CONFIG_CRC32_BIT is not set +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=m +CONFIG_CRC8=m +# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_COMPRESS=m +CONFIG_LZ4HC_COMPRESS=m +CONFIG_LZ4_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_DECOMPRESS_LZ4=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_BTREE=y +CONFIG_INTERVAL_TREE=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAS_DMA=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CPU_RMAP=y +CONFIG_DQL=y +CONFIG_GLOB=y +# CONFIG_GLOB_SELFTEST is not set +CONFIG_NLATTR=y +CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y +CONFIG_LRU_CACHE=m +CONFIG_AVERAGE=y +CONFIG_CLZ_TAB=y +CONFIG_CORDIC=m +# CONFIG_DDR is not set +CONFIG_MPILIB=m +CONFIG_OID_REGISTRY=m +CONFIG_UCS2_STRING=y +CONFIG_FONT_SUPPORT=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y +CONFIG_ARCH_HAS_SG_CHAIN=y diff --git a/kernel/kernel/files/patches/archlinux/change-default-console-loglevel.patch b/kernel/kernel/files/patches/archlinux/change-default-console-loglevel.patch new file mode 100644 index 00000000..11da2a9d --- /dev/null +++ b/kernel/kernel/files/patches/archlinux/change-default-console-loglevel.patch @@ -0,0 +1,11 @@ +--- linux-3.16/include/linux/printk.h.old 2014-08-04 18:48:30.686043266 +0200 ++++ linux-3.16/include/linux/printk.h 2014-08-04 18:48:47.706218528 +0200 +@@ -37,7 +37,7 @@ + #define CONSOLE_LOGLEVEL_SILENT 0 /* Mum's the word */ + #define CONSOLE_LOGLEVEL_MIN 1 /* Minimum loglevel we let people use */ + #define CONSOLE_LOGLEVEL_QUIET 4 /* Shhh ..., when booted with "quiet" */ +-#define CONSOLE_LOGLEVEL_DEFAULT 7 /* anything MORE serious than KERN_DEBUG */ ++#define CONSOLE_LOGLEVEL_DEFAULT 4 /* anything MORE serious than KERN_DEBUG */ + #define CONSOLE_LOGLEVEL_DEBUG 10 /* issue debug messages */ + #define CONSOLE_LOGLEVEL_MOTORMOUTH 15 /* You can't shut this one up */ + diff --git a/kernel/kernel/files/patches/archlinux/fix_CPU0_microcode_on_resume.patch b/kernel/kernel/files/patches/archlinux/fix_CPU0_microcode_on_resume.patch new file mode 100644 index 00000000..56f8094f --- /dev/null +++ b/kernel/kernel/files/patches/archlinux/fix_CPU0_microcode_on_resume.patch @@ -0,0 +1,21 @@ +diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c +index dd9d6190b08d..181e42bd85d3 100644 +--- a/arch/x86/kernel/cpu/microcode/core.c ++++ b/arch/x86/kernel/cpu/microcode/core.c +@@ -85,6 +85,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -465,6 +466,8 @@ static void mc_bp_resume(void) + + if (uci->valid && uci->mc) + microcode_ops->apply_microcode(cpu); ++ else if (!uci->mc) ++ load_ucode_intel_ap(); + } + + static struct syscore_ops mc_syscore_ops = { diff --git a/kernel/kernel/files/patches/gentoo/1500_XATTR_USER_PREFIX.patch b/kernel/kernel/files/patches/gentoo/1500_XATTR_USER_PREFIX.patch new file mode 100644 index 00000000..cc15cd51 --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/1500_XATTR_USER_PREFIX.patch @@ -0,0 +1,54 @@ +From: Anthony G. Basile + +This patch adds support for a restricted user-controlled namespace on +tmpfs filesystem used to house PaX flags. The namespace must be of the +form user.pax.* and its value cannot exceed a size of 8 bytes. + +This is needed even on all Gentoo systems so that XATTR_PAX flags +are preserved for users who might build packages using portage on +a tmpfs system with a non-hardened kernel and then switch to a +hardened kernel with XATTR_PAX enabled. + +The namespace is added to any user with Extended Attribute support +enabled for tmpfs. Users who do not enable xattrs will not have +the XATTR_PAX flags preserved. + +diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h +index e4629b9..6958086 100644 +--- a/include/uapi/linux/xattr.h ++++ b/include/uapi/linux/xattr.h +@@ -63,5 +63,9 @@ + #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default" + #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT + ++/* User namespace */ ++#define XATTR_PAX_PREFIX XATTR_USER_PREFIX "pax." ++#define XATTR_PAX_FLAGS_SUFFIX "flags" ++#define XATTR_NAME_PAX_FLAGS XATTR_PAX_PREFIX XATTR_PAX_FLAGS_SUFFIX + + #endif /* _UAPI_LINUX_XATTR_H */ +diff --git a/mm/shmem.c b/mm/shmem.c +index 1c44af7..f23bb1b 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -2201,6 +2201,7 @@ static const struct xattr_handler *shmem_xattr_handlers[] = { + static int shmem_xattr_validate(const char *name) + { + struct { const char *prefix; size_t len; } arr[] = { ++ { XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN}, + { XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN }, + { XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN } + }; +@@ -2256,6 +2257,12 @@ static int shmem_setxattr(struct dentry *dentry, const char *name, + if (err) + return err; + ++ if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { ++ if (strcmp(name, XATTR_NAME_PAX_FLAGS)) ++ return -EOPNOTSUPP; ++ if (size > 8) ++ return -EINVAL; ++ } + return simple_xattr_set(&info->xattrs, name, value, size, flags); + } + diff --git a/kernel/kernel/files/patches/gentoo/1510_fs-enable-link-security-restrictions-by-default.patch b/kernel/kernel/files/patches/gentoo/1510_fs-enable-link-security-restrictions-by-default.patch new file mode 100644 index 00000000..639fb3c3 --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/1510_fs-enable-link-security-restrictions-by-default.patch @@ -0,0 +1,22 @@ +From: Ben Hutchings +Subject: fs: Enable link security restrictions by default +Date: Fri, 02 Nov 2012 05:32:06 +0000 +Bug-Debian: https://bugs.debian.org/609455 +Forwarded: not-needed + +This reverts commit 561ec64ae67ef25cac8d72bb9c4bfc955edfd415 +('VFS: don't do protected {sym,hard}links by default'). + +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -651,8 +651,8 @@ static inline void put_link(struct namei + path_put(link); + } + +-int sysctl_protected_symlinks __read_mostly = 0; +-int sysctl_protected_hardlinks __read_mostly = 0; ++int sysctl_protected_symlinks __read_mostly = 1; ++int sysctl_protected_hardlinks __read_mostly = 1; + + /** + * may_follow_link - Check symlink following for unsafe situations diff --git a/kernel/kernel/files/patches/gentoo/2700_ThinkPad-30-brightness-control-fix.patch b/kernel/kernel/files/patches/gentoo/2700_ThinkPad-30-brightness-control-fix.patch new file mode 100644 index 00000000..b548c6dc --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/2700_ThinkPad-30-brightness-control-fix.patch @@ -0,0 +1,67 @@ +diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c +index cb96296..6c242ed 100644 +--- a/drivers/acpi/blacklist.c ++++ b/drivers/acpi/blacklist.c +@@ -269,6 +276,61 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { + }, + + /* ++ * The following Lenovo models have a broken workaround in the ++ * acpi_video backlight implementation to meet the Windows 8 ++ * requirement of 101 backlight levels. Reverting to pre-Win8 ++ * behavior fixes the problem. ++ */ ++ { ++ .callback = dmi_disable_osi_win8, ++ .ident = "Lenovo ThinkPad L430", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L430"), ++ }, ++ }, ++ { ++ .callback = dmi_disable_osi_win8, ++ .ident = "Lenovo ThinkPad T430s", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"), ++ }, ++ }, ++ { ++ .callback = dmi_disable_osi_win8, ++ .ident = "Lenovo ThinkPad T530", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T530"), ++ }, ++ }, ++ { ++ .callback = dmi_disable_osi_win8, ++ .ident = "Lenovo ThinkPad W530", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"), ++ }, ++ }, ++ { ++ .callback = dmi_disable_osi_win8, ++ .ident = "Lenovo ThinkPad X1 Carbon", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"), ++ }, ++ }, ++ { ++ .callback = dmi_disable_osi_win8, ++ .ident = "Lenovo ThinkPad X230", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), ++ }, ++ }, ++ ++ /* + * BIOS invocation of _OSI(Linux) is almost always a BIOS bug. + * Linux ignores it, except for the machines enumerated below. + */ + diff --git a/kernel/kernel/files/patches/gentoo/2900_dev-root-proc-mount-fix.patch b/kernel/kernel/files/patches/gentoo/2900_dev-root-proc-mount-fix.patch new file mode 100644 index 00000000..6ea86e29 --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/2900_dev-root-proc-mount-fix.patch @@ -0,0 +1,30 @@ +--- a/init/do_mounts.c 2014-08-26 08:03:30.000013100 -0400 ++++ b/init/do_mounts.c 2014-08-26 08:11:19.720014712 -0400 +@@ -484,7 +484,10 @@ void __init change_floppy(char *fmt, ... + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); ++ if (saved_root_name[0]) ++ fd = sys_open(saved_root_name, O_RDWR | O_NDELAY, 0); ++ else ++ fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); + if (fd >= 0) { + sys_ioctl(fd, FDEJECT, 0); + sys_close(fd); +@@ -527,8 +530,13 @@ void __init mount_root(void) + } + #endif + #ifdef CONFIG_BLOCK +- create_dev("/dev/root", ROOT_DEV); +- mount_block_root("/dev/root", root_mountflags); ++ if (saved_root_name[0]) { ++ create_dev(saved_root_name, ROOT_DEV); ++ mount_block_root(saved_root_name, root_mountflags); ++ } else { ++ create_dev("/dev/root", ROOT_DEV); ++ mount_block_root("/dev/root", root_mountflags); ++ } + #endif + } + diff --git a/kernel/kernel/files/patches/gentoo/2905_2disk-resume-image-fix.patch b/kernel/kernel/files/patches/gentoo/2905_2disk-resume-image-fix.patch new file mode 100644 index 00000000..7e95d298 --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/2905_2disk-resume-image-fix.patch @@ -0,0 +1,24 @@ +diff --git a/kernel/kmod.c b/kernel/kmod.c +index fb32636..d968882 100644 +--- a/kernel/kmod.c ++++ b/kernel/kmod.c +@@ -575,7 +575,8 @@ + call_usermodehelper_freeinfo(sub_info); + return -EINVAL; + } +- helper_lock(); ++ if (!(current->flags & PF_FREEZER_SKIP)) ++ helper_lock(); + if (!khelper_wq || usermodehelper_disabled) { + retval = -EBUSY; + goto out; +@@ -611,7 +612,8 @@ wait_done: + out: + call_usermodehelper_freeinfo(sub_info); + unlock: +- helper_unlock(); ++ if (!(current->flags & PF_FREEZER_SKIP)) ++ helper_unlock(); + return retval; + } + EXPORT_SYMBOL(call_usermodehelper_exec); diff --git a/kernel/kernel/files/patches/gentoo/4200_fbcondecor-3.19.patch b/kernel/kernel/files/patches/gentoo/4200_fbcondecor-3.19.patch new file mode 100644 index 00000000..29c379fe --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/4200_fbcondecor-3.19.patch @@ -0,0 +1,2119 @@ +diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX +index fe85e7c..2230930 100644 +--- a/Documentation/fb/00-INDEX ++++ b/Documentation/fb/00-INDEX +@@ -23,6 +23,8 @@ ep93xx-fb.txt + - info on the driver for EP93xx LCD controller. + fbcon.txt + - intro to and usage guide for the framebuffer console (fbcon). ++fbcondecor.txt ++ - info on the Framebuffer Console Decoration + framebuffer.txt + - introduction to frame buffer devices. + gxfb.txt +diff --git a/Documentation/fb/fbcondecor.txt b/Documentation/fb/fbcondecor.txt +new file mode 100644 +index 0000000..3388c61 +--- /dev/null ++++ b/Documentation/fb/fbcondecor.txt +@@ -0,0 +1,207 @@ ++What is it? ++----------- ++ ++The framebuffer decorations are a kernel feature which allows displaying a ++background picture on selected consoles. ++ ++What do I need to get it to work? ++--------------------------------- ++ ++To get fbcondecor up-and-running you will have to: ++ 1) get a copy of splashutils [1] or a similar program ++ 2) get some fbcondecor themes ++ 3) build the kernel helper program ++ 4) build your kernel with the FB_CON_DECOR option enabled. ++ ++To get fbcondecor operational right after fbcon initialization is finished, you ++will have to include a theme and the kernel helper into your initramfs image. ++Please refer to splashutils documentation for instructions on how to do that. ++ ++[1] The splashutils package can be downloaded from: ++ http://github.com/alanhaggai/fbsplash ++ ++The userspace helper ++-------------------- ++ ++The userspace fbcondecor helper (by default: /sbin/fbcondecor_helper) is called by the ++kernel whenever an important event occurs and the kernel needs some kind of ++job to be carried out. Important events include console switches and video ++mode switches (the kernel requests background images and configuration ++parameters for the current console). The fbcondecor helper must be accessible at ++all times. If it's not, fbcondecor will be switched off automatically. ++ ++It's possible to set path to the fbcondecor helper by writing it to ++/proc/sys/kernel/fbcondecor. ++ ++***************************************************************************** ++ ++The information below is mostly technical stuff. There's probably no need to ++read it unless you plan to develop a userspace helper. ++ ++The fbcondecor protocol ++----------------------- ++ ++The fbcondecor protocol defines a communication interface between the kernel and ++the userspace fbcondecor helper. ++ ++The kernel side is responsible for: ++ ++ * rendering console text, using an image as a background (instead of a ++ standard solid color fbcon uses), ++ * accepting commands from the user via ioctls on the fbcondecor device, ++ * calling the userspace helper to set things up as soon as the fb subsystem ++ is initialized. ++ ++The userspace helper is responsible for everything else, including parsing ++configuration files, decompressing the image files whenever the kernel needs ++it, and communicating with the kernel if necessary. ++ ++The fbcondecor protocol specifies how communication is done in both ways: ++kernel->userspace and userspace->helper. ++ ++Kernel -> Userspace ++------------------- ++ ++The kernel communicates with the userspace helper by calling it and specifying ++the task to be done in a series of arguments. ++ ++The arguments follow the pattern: ++ ++ ++All commands defined in fbcondecor protocol v2 have the following parameters: ++ virtual console ++ framebuffer number ++ theme ++ ++Fbcondecor protocol v1 specified an additional 'fbcondecor mode' after the ++framebuffer number. Fbcondecor protocol v1 is deprecated and should not be used. ++ ++Fbcondecor protocol v2 specifies the following commands: ++ ++getpic ++------ ++ The kernel issues this command to request image data. It's up to the ++ userspace helper to find a background image appropriate for the specified ++ theme and the current resolution. The userspace helper should respond by ++ issuing the FBIOCONDECOR_SETPIC ioctl. ++ ++init ++---- ++ The kernel issues this command after the fbcondecor device is created and ++ the fbcondecor interface is initialized. Upon receiving 'init', the userspace ++ helper should parse the kernel command line (/proc/cmdline) or otherwise ++ decide whether fbcondecor is to be activated. ++ ++ To activate fbcondecor on the first console the helper should issue the ++ FBIOCONDECOR_SETCFG, FBIOCONDECOR_SETPIC and FBIOCONDECOR_SETSTATE commands, ++ in the above-mentioned order. ++ ++ When the userspace helper is called in an early phase of the boot process ++ (right after the initialization of fbcon), no filesystems will be mounted. ++ The helper program should mount sysfs and then create the appropriate ++ framebuffer, fbcondecor and tty0 devices (if they don't already exist) to get ++ current display settings and to be able to communicate with the kernel side. ++ It should probably also mount the procfs to be able to parse the kernel ++ command line parameters. ++ ++ Note that the console sem is not held when the kernel calls fbcondecor_helper ++ with the 'init' command. The fbcondecor helper should perform all ioctls with ++ origin set to FBCON_DECOR_IO_ORIG_USER. ++ ++modechange ++---------- ++ The kernel issues this command on a mode change. The helper's response should ++ be similar to the response to the 'init' command. Note that this time the ++ console sem is held and all ioctls must be performed with origin set to ++ FBCON_DECOR_IO_ORIG_KERNEL. ++ ++ ++Userspace -> Kernel ++------------------- ++ ++Userspace programs can communicate with fbcondecor via ioctls on the ++fbcondecor device. These ioctls are to be used by both the userspace helper ++(called only by the kernel) and userspace configuration tools (run by the users). ++ ++The fbcondecor helper should set the origin field to FBCON_DECOR_IO_ORIG_KERNEL ++when doing the appropriate ioctls. All userspace configuration tools should ++use FBCON_DECOR_IO_ORIG_USER. Failure to set the appropriate value in the origin ++field when performing ioctls from the kernel helper will most likely result ++in a console deadlock. ++ ++FBCON_DECOR_IO_ORIG_KERNEL instructs fbcondecor not to try to acquire the console ++semaphore. Not surprisingly, FBCON_DECOR_IO_ORIG_USER instructs it to acquire ++the console sem. ++ ++The framebuffer console decoration provides the following ioctls (all defined in ++linux/fb.h): ++ ++FBIOCONDECOR_SETPIC ++description: loads a background picture for a virtual console ++argument: struct fbcon_decor_iowrapper*; data: struct fb_image* ++notes: ++If called for consoles other than the current foreground one, the picture data ++will be ignored. ++ ++If the current virtual console is running in a 8-bpp mode, the cmap substruct ++of fb_image has to be filled appropriately: start should be set to 16 (first ++16 colors are reserved for fbcon), len to a value <= 240 and red, green and ++blue should point to valid cmap data. The transp field is ingored. The fields ++dx, dy, bg_color, fg_color in fb_image are ignored as well. ++ ++FBIOCONDECOR_SETCFG ++description: sets the fbcondecor config for a virtual console ++argument: struct fbcon_decor_iowrapper*; data: struct vc_decor* ++notes: The structure has to be filled with valid data. ++ ++FBIOCONDECOR_GETCFG ++description: gets the fbcondecor config for a virtual console ++argument: struct fbcon_decor_iowrapper*; data: struct vc_decor* ++ ++FBIOCONDECOR_SETSTATE ++description: sets the fbcondecor state for a virtual console ++argument: struct fbcon_decor_iowrapper*; data: unsigned int* ++ values: 0 = disabled, 1 = enabled. ++ ++FBIOCONDECOR_GETSTATE ++description: gets the fbcondecor state for a virtual console ++argument: struct fbcon_decor_iowrapper*; data: unsigned int* ++ values: as in FBIOCONDECOR_SETSTATE ++ ++Info on used structures: ++ ++Definition of struct vc_decor can be found in linux/console_decor.h. It's ++heavily commented. Note that the 'theme' field should point to a string ++no longer than FBCON_DECOR_THEME_LEN. When FBIOCONDECOR_GETCFG call is ++performed, the theme field should point to a char buffer of length ++FBCON_DECOR_THEME_LEN. ++ ++Definition of struct fbcon_decor_iowrapper can be found in linux/fb.h. ++The fields in this struct have the following meaning: ++ ++vc: ++Virtual console number. ++ ++origin: ++Specifies if the ioctl is performed as a response to a kernel request. The ++fbcondecor helper should set this field to FBCON_DECOR_IO_ORIG_KERNEL, userspace ++programs should set it to FBCON_DECOR_IO_ORIG_USER. This field is necessary to ++avoid console semaphore deadlocks. ++ ++data: ++Pointer to a data structure appropriate for the performed ioctl. Type of ++the data struct is specified in the ioctls description. ++ ++***************************************************************************** ++ ++Credit ++------ ++ ++Original 'bootsplash' project & implementation by: ++ Volker Poplawski , Stefan Reinauer , ++ Steffen Winterfeldt , Michael Schroeder , ++ Ken Wimer . ++ ++Fbcondecor, fbcondecor protocol design, current implementation & docs by: ++ Michal Januszewski ++ +diff --git a/drivers/Makefile b/drivers/Makefile +index 7183b6a..d576148 100644 +--- a/drivers/Makefile ++++ b/drivers/Makefile +@@ -17,6 +17,10 @@ obj-y += pwm/ + obj-$(CONFIG_PCI) += pci/ + obj-$(CONFIG_PARISC) += parisc/ + obj-$(CONFIG_RAPIDIO) += rapidio/ ++# tty/ comes before char/ so that the VT console is the boot-time ++# default. ++obj-y += tty/ ++obj-y += char/ + obj-y += video/ + obj-y += idle/ + +@@ -42,11 +46,6 @@ obj-$(CONFIG_REGULATOR) += regulator/ + # reset controllers early, since gpu drivers might rely on them to initialize + obj-$(CONFIG_RESET_CONTROLLER) += reset/ + +-# tty/ comes before char/ so that the VT console is the boot-time +-# default. +-obj-y += tty/ +-obj-y += char/ +- + # iommu/ comes before gpu as gpu are using iommu controllers + obj-$(CONFIG_IOMMU_SUPPORT) += iommu/ + +diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig +index fe1cd01..6d2e87a 100644 +--- a/drivers/video/console/Kconfig ++++ b/drivers/video/console/Kconfig +@@ -126,6 +126,19 @@ config FRAMEBUFFER_CONSOLE_ROTATION + such that other users of the framebuffer will remain normally + oriented. + ++config FB_CON_DECOR ++ bool "Support for the Framebuffer Console Decorations" ++ depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING ++ default n ++ ---help--- ++ This option enables support for framebuffer console decorations which ++ makes it possible to display images in the background of the system ++ consoles. Note that userspace utilities are necessary in order to take ++ advantage of these features. Refer to Documentation/fb/fbcondecor.txt ++ for more information. ++ ++ If unsure, say N. ++ + config STI_CONSOLE + bool "STI text console" + depends on PARISC +diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile +index 43bfa48..cc104b6f 100644 +--- a/drivers/video/console/Makefile ++++ b/drivers/video/console/Makefile +@@ -16,4 +16,5 @@ obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \ + fbcon_ccw.o + endif + ++obj-$(CONFIG_FB_CON_DECOR) += fbcondecor.o cfbcondecor.o + obj-$(CONFIG_FB_STI) += sticore.o +diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c +index 61b182b..984384b 100644 +--- a/drivers/video/console/bitblit.c ++++ b/drivers/video/console/bitblit.c +@@ -18,6 +18,7 @@ + #include + #include + #include "fbcon.h" ++#include "fbcondecor.h" + + /* + * Accelerated handlers. +@@ -55,6 +56,13 @@ static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy, + area.height = height * vc->vc_font.height; + area.width = width * vc->vc_font.width; + ++ if (fbcon_decor_active(info, vc)) { ++ area.sx += vc->vc_decor.tx; ++ area.sy += vc->vc_decor.ty; ++ area.dx += vc->vc_decor.tx; ++ area.dy += vc->vc_decor.ty; ++ } ++ + info->fbops->fb_copyarea(info, &area); + } + +@@ -380,11 +388,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode, + cursor.image.depth = 1; + cursor.rop = ROP_XOR; + +- if (info->fbops->fb_cursor) +- err = info->fbops->fb_cursor(info, &cursor); ++ if (fbcon_decor_active(info, vc)) { ++ fbcon_decor_cursor(info, &cursor); ++ } else { ++ if (info->fbops->fb_cursor) ++ err = info->fbops->fb_cursor(info, &cursor); + +- if (err) +- soft_cursor(info, &cursor); ++ if (err) ++ soft_cursor(info, &cursor); ++ } + + ops->cursor_reset = 0; + } +diff --git a/drivers/video/console/cfbcondecor.c b/drivers/video/console/cfbcondecor.c +new file mode 100644 +index 0000000..a2b4497 +--- /dev/null ++++ b/drivers/video/console/cfbcondecor.c +@@ -0,0 +1,471 @@ ++/* ++ * linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions ++ * ++ * Copyright (C) 2004 Michal Januszewski ++ * ++ * Code based upon "Bootdecor" (C) 2001-2003 ++ * Volker Poplawski , ++ * Stefan Reinauer , ++ * Steffen Winterfeldt , ++ * Michael Schroeder , ++ * Ken Wimer . ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file COPYING in the main directory of this archive for ++ * more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "fbcon.h" ++#include "fbcondecor.h" ++ ++#define parse_pixel(shift,bpp,type) \ ++ do { \ ++ if (d & (0x80 >> (shift))) \ ++ dd2[(shift)] = fgx; \ ++ else \ ++ dd2[(shift)] = transparent ? *(type *)decor_src : bgx; \ ++ decor_src += (bpp); \ ++ } while (0) \ ++ ++extern int get_color(struct vc_data *vc, struct fb_info *info, ++ u16 c, int is_fg); ++ ++void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) ++{ ++ int i, j, k; ++ int minlen = min(min(info->var.red.length, info->var.green.length), ++ info->var.blue.length); ++ u32 col; ++ ++ for (j = i = 0; i < 16; i++) { ++ k = color_table[i]; ++ ++ col = ((vc->vc_palette[j++] >> (8-minlen)) ++ << info->var.red.offset); ++ col |= ((vc->vc_palette[j++] >> (8-minlen)) ++ << info->var.green.offset); ++ col |= ((vc->vc_palette[j++] >> (8-minlen)) ++ << info->var.blue.offset); ++ ((u32 *)info->pseudo_palette)[k] = col; ++ } ++} ++ ++void fbcon_decor_renderc(struct fb_info *info, int ypos, int xpos, int height, ++ int width, u8* src, u32 fgx, u32 bgx, u8 transparent) ++{ ++ unsigned int x, y; ++ u32 dd; ++ int bytespp = ((info->var.bits_per_pixel + 7) >> 3); ++ unsigned int d = ypos * info->fix.line_length + xpos * bytespp; ++ unsigned int ds = (ypos * info->var.xres + xpos) * bytespp; ++ u16 dd2[4]; ++ ++ u8* decor_src = (u8 *)(info->bgdecor.data + ds); ++ u8* dst = (u8 *)(info->screen_base + d); ++ ++ if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres) ++ return; ++ ++ for (y = 0; y < height; y++) { ++ switch (info->var.bits_per_pixel) { ++ ++ case 32: ++ for (x = 0; x < width; x++) { ++ ++ if ((x & 7) == 0) ++ d = *src++; ++ if (d & 0x80) ++ dd = fgx; ++ else ++ dd = transparent ? ++ *(u32 *)decor_src : bgx; ++ ++ d <<= 1; ++ decor_src += 4; ++ fb_writel(dd, dst); ++ dst += 4; ++ } ++ break; ++ case 24: ++ for (x = 0; x < width; x++) { ++ ++ if ((x & 7) == 0) ++ d = *src++; ++ if (d & 0x80) ++ dd = fgx; ++ else ++ dd = transparent ? ++ (*(u32 *)decor_src & 0xffffff) : bgx; ++ ++ d <<= 1; ++ decor_src += 3; ++#ifdef __LITTLE_ENDIAN ++ fb_writew(dd & 0xffff, dst); ++ dst += 2; ++ fb_writeb((dd >> 16), dst); ++#else ++ fb_writew(dd >> 8, dst); ++ dst += 2; ++ fb_writeb(dd & 0xff, dst); ++#endif ++ dst++; ++ } ++ break; ++ case 16: ++ for (x = 0; x < width; x += 2) { ++ if ((x & 7) == 0) ++ d = *src++; ++ ++ parse_pixel(0, 2, u16); ++ parse_pixel(1, 2, u16); ++#ifdef __LITTLE_ENDIAN ++ dd = dd2[0] | (dd2[1] << 16); ++#else ++ dd = dd2[1] | (dd2[0] << 16); ++#endif ++ d <<= 2; ++ fb_writel(dd, dst); ++ dst += 4; ++ } ++ break; ++ ++ case 8: ++ for (x = 0; x < width; x += 4) { ++ if ((x & 7) == 0) ++ d = *src++; ++ ++ parse_pixel(0, 1, u8); ++ parse_pixel(1, 1, u8); ++ parse_pixel(2, 1, u8); ++ parse_pixel(3, 1, u8); ++ ++#ifdef __LITTLE_ENDIAN ++ dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24); ++#else ++ dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24); ++#endif ++ d <<= 4; ++ fb_writel(dd, dst); ++ dst += 4; ++ } ++ } ++ ++ dst += info->fix.line_length - width * bytespp; ++ decor_src += (info->var.xres - width) * bytespp; ++ } ++} ++ ++#define cc2cx(a) \ ++ ((info->fix.visual == FB_VISUAL_TRUECOLOR || \ ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \ ++ ((u32*)info->pseudo_palette)[a] : a) ++ ++void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, ++ const unsigned short *s, int count, int yy, int xx) ++{ ++ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; ++ struct fbcon_ops *ops = info->fbcon_par; ++ int fg_color, bg_color, transparent; ++ u8 *src; ++ u32 bgx, fgx; ++ u16 c = scr_readw(s); ++ ++ fg_color = get_color(vc, info, c, 1); ++ bg_color = get_color(vc, info, c, 0); ++ ++ /* Don't paint the background image if console is blanked */ ++ transparent = ops->blank_state ? 0 : ++ (vc->vc_decor.bg_color == bg_color); ++ ++ xx = xx * vc->vc_font.width + vc->vc_decor.tx; ++ yy = yy * vc->vc_font.height + vc->vc_decor.ty; ++ ++ fgx = cc2cx(fg_color); ++ bgx = cc2cx(bg_color); ++ ++ while (count--) { ++ c = scr_readw(s++); ++ src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * ++ ((vc->vc_font.width + 7) >> 3); ++ ++ fbcon_decor_renderc(info, yy, xx, vc->vc_font.height, ++ vc->vc_font.width, src, fgx, bgx, transparent); ++ xx += vc->vc_font.width; ++ } ++} ++ ++void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) ++{ ++ int i; ++ unsigned int dsize, s_pitch; ++ struct fbcon_ops *ops = info->fbcon_par; ++ struct vc_data* vc; ++ u8 *src; ++ ++ /* we really don't need any cursors while the console is blanked */ ++ if (info->state != FBINFO_STATE_RUNNING || ops->blank_state) ++ return; ++ ++ vc = vc_cons[ops->currcon].d; ++ ++ src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC); ++ if (!src) ++ return; ++ ++ s_pitch = (cursor->image.width + 7) >> 3; ++ dsize = s_pitch * cursor->image.height; ++ if (cursor->enable) { ++ switch (cursor->rop) { ++ case ROP_XOR: ++ for (i = 0; i < dsize; i++) ++ src[i] = cursor->image.data[i] ^ cursor->mask[i]; ++ break; ++ case ROP_COPY: ++ default: ++ for (i = 0; i < dsize; i++) ++ src[i] = cursor->image.data[i] & cursor->mask[i]; ++ break; ++ } ++ } else ++ memcpy(src, cursor->image.data, dsize); ++ ++ fbcon_decor_renderc(info, ++ cursor->image.dy + vc->vc_decor.ty, ++ cursor->image.dx + vc->vc_decor.tx, ++ cursor->image.height, ++ cursor->image.width, ++ (u8*)src, ++ cc2cx(cursor->image.fg_color), ++ cc2cx(cursor->image.bg_color), ++ cursor->image.bg_color == vc->vc_decor.bg_color); ++ ++ kfree(src); ++} ++ ++static void decorset(u8 *dst, int height, int width, int dstbytes, ++ u32 bgx, int bpp) ++{ ++ int i; ++ ++ if (bpp == 8) ++ bgx |= bgx << 8; ++ if (bpp == 16 || bpp == 8) ++ bgx |= bgx << 16; ++ ++ while (height-- > 0) { ++ u8 *p = dst; ++ ++ switch (bpp) { ++ ++ case 32: ++ for (i=0; i < width; i++) { ++ fb_writel(bgx, p); p += 4; ++ } ++ break; ++ case 24: ++ for (i=0; i < width; i++) { ++#ifdef __LITTLE_ENDIAN ++ fb_writew((bgx & 0xffff),(u16*)p); p += 2; ++ fb_writeb((bgx >> 16),p++); ++#else ++ fb_writew((bgx >> 8),(u16*)p); p += 2; ++ fb_writeb((bgx & 0xff),p++); ++#endif ++ } ++ case 16: ++ for (i=0; i < width/4; i++) { ++ fb_writel(bgx,p); p += 4; ++ fb_writel(bgx,p); p += 4; ++ } ++ if (width & 2) { ++ fb_writel(bgx,p); p += 4; ++ } ++ if (width & 1) ++ fb_writew(bgx,(u16*)p); ++ break; ++ case 8: ++ for (i=0; i < width/4; i++) { ++ fb_writel(bgx,p); p += 4; ++ } ++ ++ if (width & 2) { ++ fb_writew(bgx,p); p += 2; ++ } ++ if (width & 1) ++ fb_writeb(bgx,(u8*)p); ++ break; ++ ++ } ++ dst += dstbytes; ++ } ++} ++ ++void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, ++ int srclinebytes, int bpp) ++{ ++ int i; ++ ++ while (height-- > 0) { ++ u32 *p = (u32 *)dst; ++ u32 *q = (u32 *)src; ++ ++ switch (bpp) { ++ ++ case 32: ++ for (i=0; i < width; i++) ++ fb_writel(*q++, p++); ++ break; ++ case 24: ++ for (i=0; i < (width*3/4); i++) ++ fb_writel(*q++, p++); ++ if ((width*3) % 4) { ++ if (width & 2) { ++ fb_writeb(*(u8*)q, (u8*)p); ++ } else if (width & 1) { ++ fb_writew(*(u16*)q, (u16*)p); ++ fb_writeb(*(u8*)((u16*)q+1),(u8*)((u16*)p+2)); ++ } ++ } ++ break; ++ case 16: ++ for (i=0; i < width/4; i++) { ++ fb_writel(*q++, p++); ++ fb_writel(*q++, p++); ++ } ++ if (width & 2) ++ fb_writel(*q++, p++); ++ if (width & 1) ++ fb_writew(*(u16*)q, (u16*)p); ++ break; ++ case 8: ++ for (i=0; i < width/4; i++) ++ fb_writel(*q++, p++); ++ ++ if (width & 2) { ++ fb_writew(*(u16*)q, (u16*)p); ++ q = (u32*) ((u16*)q + 1); ++ p = (u32*) ((u16*)p + 1); ++ } ++ if (width & 1) ++ fb_writeb(*(u8*)q, (u8*)p); ++ break; ++ } ++ ++ dst += linebytes; ++ src += srclinebytes; ++ } ++} ++ ++static void decorfill(struct fb_info *info, int sy, int sx, int height, ++ int width) ++{ ++ int bytespp = ((info->var.bits_per_pixel + 7) >> 3); ++ int d = sy * info->fix.line_length + sx * bytespp; ++ int ds = (sy * info->var.xres + sx) * bytespp; ++ ++ fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds), ++ height, width, info->fix.line_length, info->var.xres * bytespp, ++ info->var.bits_per_pixel); ++} ++ ++void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, ++ int height, int width) ++{ ++ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; ++ struct fbcon_ops *ops = info->fbcon_par; ++ u8 *dst; ++ int transparent, bg_color = attr_bgcol_ec(bgshift, vc, info); ++ ++ transparent = (vc->vc_decor.bg_color == bg_color); ++ sy = sy * vc->vc_font.height + vc->vc_decor.ty; ++ sx = sx * vc->vc_font.width + vc->vc_decor.tx; ++ height *= vc->vc_font.height; ++ width *= vc->vc_font.width; ++ ++ /* Don't paint the background image if console is blanked */ ++ if (transparent && !ops->blank_state) { ++ decorfill(info, sy, sx, height, width); ++ } else { ++ dst = (u8 *)(info->screen_base + sy * info->fix.line_length + ++ sx * ((info->var.bits_per_pixel + 7) >> 3)); ++ decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color), ++ info->var.bits_per_pixel); ++ } ++} ++ ++void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, ++ int bottom_only) ++{ ++ unsigned int tw = vc->vc_cols*vc->vc_font.width; ++ unsigned int th = vc->vc_rows*vc->vc_font.height; ++ ++ if (!bottom_only) { ++ /* top margin */ ++ decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres); ++ /* left margin */ ++ decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx); ++ /* right margin */ ++ decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th, ++ info->var.xres - vc->vc_decor.tx - tw); ++ } ++ decorfill(info, vc->vc_decor.ty + th, 0, ++ info->var.yres - vc->vc_decor.ty - th, info->var.xres); ++} ++ ++void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, ++ int sx, int dx, int width) ++{ ++ u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2); ++ u16 *s = d + (dx - sx); ++ u16 *start = d; ++ u16 *ls = d; ++ u16 *le = d + width; ++ u16 c; ++ int x = dx; ++ u16 attr = 1; ++ ++ do { ++ c = scr_readw(d); ++ if (attr != (c & 0xff00)) { ++ attr = c & 0xff00; ++ if (d > start) { ++ fbcon_decor_putcs(vc, info, start, d - start, y, x); ++ x += d - start; ++ start = d; ++ } ++ } ++ if (s >= ls && s < le && c == scr_readw(s)) { ++ if (d > start) { ++ fbcon_decor_putcs(vc, info, start, d - start, y, x); ++ x += d - start + 1; ++ start = d + 1; ++ } else { ++ x++; ++ start++; ++ } ++ } ++ s++; ++ d++; ++ } while (d < le); ++ if (d > start) ++ fbcon_decor_putcs(vc, info, start, d - start, y, x); ++} ++ ++void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) ++{ ++ if (blank) { ++ decorset((u8 *)info->screen_base, info->var.yres, info->var.xres, ++ info->fix.line_length, 0, info->var.bits_per_pixel); ++ } else { ++ update_screen(vc); ++ fbcon_decor_clear_margins(vc, info, 0); ++ } ++} ++ +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c +index f447734..da50d61 100644 +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -79,6 +79,7 @@ + #include + + #include "fbcon.h" ++#include "../console/fbcondecor.h" + + #ifdef FBCONDEBUG + # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) +@@ -94,7 +95,7 @@ enum { + + static struct display fb_display[MAX_NR_CONSOLES]; + +-static signed char con2fb_map[MAX_NR_CONSOLES]; ++signed char con2fb_map[MAX_NR_CONSOLES]; + static signed char con2fb_map_boot[MAX_NR_CONSOLES]; + + static int logo_lines; +@@ -286,7 +287,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) + !vt_force_oops_output(vc); + } + +-static int get_color(struct vc_data *vc, struct fb_info *info, ++int get_color(struct vc_data *vc, struct fb_info *info, + u16 c, int is_fg) + { + int depth = fb_get_color_depth(&info->var, &info->fix); +@@ -551,6 +552,9 @@ static int do_fbcon_takeover(int show_logo) + info_idx = -1; + } else { + fbcon_has_console_bind = 1; ++#ifdef CONFIG_FB_CON_DECOR ++ fbcon_decor_init(); ++#endif + } + + return err; +@@ -1007,6 +1011,12 @@ static const char *fbcon_startup(void) + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; ++ ++ if (fbcon_decor_active(info, vc)) { ++ cols = vc->vc_decor.twidth / vc->vc_font.width; ++ rows = vc->vc_decor.theight / vc->vc_font.height; ++ } ++ + vc_resize(vc, cols, rows); + + DPRINTK("mode: %s\n", info->fix.id); +@@ -1036,7 +1046,7 @@ static void fbcon_init(struct vc_data *vc, int init) + cap = info->flags; + + if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW || +- (info->fix.type == FB_TYPE_TEXT)) ++ (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc)) + logo = 0; + + if (var_to_display(p, &info->var, info)) +@@ -1260,6 +1270,11 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, + fbcon_clear_margins(vc, 0); + } + ++ if (fbcon_decor_active(info, vc)) { ++ fbcon_decor_clear(vc, info, sy, sx, height, width); ++ return; ++ } ++ + /* Split blits that cross physical y_wrap boundary */ + + y_break = p->vrows - p->yscroll; +@@ -1279,10 +1294,15 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, + struct display *p = &fb_display[vc->vc_num]; + struct fbcon_ops *ops = info->fbcon_par; + +- if (!fbcon_is_inactive(vc, info)) +- ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, +- get_color(vc, info, scr_readw(s), 1), +- get_color(vc, info, scr_readw(s), 0)); ++ if (!fbcon_is_inactive(vc, info)) { ++ ++ if (fbcon_decor_active(info, vc)) ++ fbcon_decor_putcs(vc, info, s, count, ypos, xpos); ++ else ++ ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, ++ get_color(vc, info, scr_readw(s), 1), ++ get_color(vc, info, scr_readw(s), 0)); ++ } + } + + static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) +@@ -1298,8 +1318,13 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) + struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fbcon_ops *ops = info->fbcon_par; + +- if (!fbcon_is_inactive(vc, info)) +- ops->clear_margins(vc, info, bottom_only); ++ if (!fbcon_is_inactive(vc, info)) { ++ if (fbcon_decor_active(info, vc)) { ++ fbcon_decor_clear_margins(vc, info, bottom_only); ++ } else { ++ ops->clear_margins(vc, info, bottom_only); ++ } ++ } + } + + static void fbcon_cursor(struct vc_data *vc, int mode) +@@ -1819,7 +1844,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, + count = vc->vc_rows; + if (softback_top) + fbcon_softback_note(vc, t, count); +- if (logo_shown >= 0) ++ if (logo_shown >= 0 || fbcon_decor_active(info, vc)) + goto redraw_up; + switch (p->scrollmode) { + case SCROLL_MOVE: +@@ -1912,6 +1937,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, + count = vc->vc_rows; + if (logo_shown >= 0) + goto redraw_down; ++ if (fbcon_decor_active(info, vc)) ++ goto redraw_down; + switch (p->scrollmode) { + case SCROLL_MOVE: + fbcon_redraw_blit(vc, info, p, b - 1, b - t - count, +@@ -2060,6 +2087,13 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s + } + return; + } ++ ++ if (fbcon_decor_active(info, vc) && sy == dy && height == 1) { ++ /* must use slower redraw bmove to keep background pic intact */ ++ fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width); ++ return; ++ } ++ + ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx, + height, width); + } +@@ -2130,8 +2164,8 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, + var.yres = virt_h * virt_fh; + x_diff = info->var.xres - var.xres; + y_diff = info->var.yres - var.yres; +- if (x_diff < 0 || x_diff > virt_fw || +- y_diff < 0 || y_diff > virt_fh) { ++ if ((x_diff < 0 || x_diff > virt_fw || ++ y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) { + const struct fb_videomode *mode; + + DPRINTK("attempting resize %ix%i\n", var.xres, var.yres); +@@ -2167,6 +2201,21 @@ static int fbcon_switch(struct vc_data *vc) + + info = registered_fb[con2fb_map[vc->vc_num]]; + ops = info->fbcon_par; ++ prev_console = ops->currcon; ++ if (prev_console != -1) ++ old_info = registered_fb[con2fb_map[prev_console]]; ++ ++#ifdef CONFIG_FB_CON_DECOR ++ if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) { ++ struct vc_data *vc_curr = vc_cons[prev_console].d; ++ if (vc_curr && fbcon_decor_active_vc(vc_curr)) { ++ /* Clear the screen to avoid displaying funky colors during ++ * palette updates. */ ++ memset((u8*)info->screen_base + info->fix.line_length * info->var.yoffset, ++ 0, info->var.yres * info->fix.line_length); ++ } ++ } ++#endif + + if (softback_top) { + if (softback_lines) +@@ -2185,9 +2234,6 @@ static int fbcon_switch(struct vc_data *vc) + logo_shown = FBCON_LOGO_CANSHOW; + } + +- prev_console = ops->currcon; +- if (prev_console != -1) +- old_info = registered_fb[con2fb_map[prev_console]]; + /* + * FIXME: If we have multiple fbdev's loaded, we need to + * update all info->currcon. Perhaps, we can place this +@@ -2231,6 +2277,18 @@ static int fbcon_switch(struct vc_data *vc) + fbcon_del_cursor_timer(old_info); + } + ++ if (fbcon_decor_active_vc(vc)) { ++ struct vc_data *vc_curr = vc_cons[prev_console].d; ++ ++ if (!vc_curr->vc_decor.theme || ++ strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) || ++ (fbcon_decor_active_nores(info, vc_curr) && ++ !fbcon_decor_active(info, vc_curr))) { ++ fbcon_decor_disable(vc, 0); ++ fbcon_decor_call_helper("modechange", vc->vc_num); ++ } ++ } ++ + if (fbcon_is_inactive(vc, info) || + ops->blank_state != FB_BLANK_UNBLANK) + fbcon_del_cursor_timer(info); +@@ -2339,15 +2397,20 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) + } + } + +- if (!fbcon_is_inactive(vc, info)) { ++ if (!fbcon_is_inactive(vc, info)) { + if (ops->blank_state != blank) { + ops->blank_state = blank; + fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); + ops->cursor_flash = (!blank); + +- if (!(info->flags & FBINFO_MISC_USEREVENT)) +- if (fb_blank(info, blank)) +- fbcon_generic_blank(vc, info, blank); ++ if (!(info->flags & FBINFO_MISC_USEREVENT)) { ++ if (fb_blank(info, blank)) { ++ if (fbcon_decor_active(info, vc)) ++ fbcon_decor_blank(vc, info, blank); ++ else ++ fbcon_generic_blank(vc, info, blank); ++ } ++ } + } + + if (!blank) +@@ -2522,13 +2585,22 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, + } + + if (resize) { ++ /* reset wrap/pan */ + int cols, rows; + + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); ++ ++ if (fbcon_decor_active(info, vc)) { ++ info->var.xoffset = info->var.yoffset = p->yscroll = 0; ++ cols = vc->vc_decor.twidth; ++ rows = vc->vc_decor.theight; ++ } + cols /= w; + rows /= h; ++ + vc_resize(vc, cols, rows); ++ + if (CON_IS_VISIBLE(vc) && softback_buf) + fbcon_update_softback(vc); + } else if (CON_IS_VISIBLE(vc) +@@ -2657,7 +2729,11 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) + int i, j, k, depth; + u8 val; + +- if (fbcon_is_inactive(vc, info)) ++ if (fbcon_is_inactive(vc, info) ++#ifdef CONFIG_FB_CON_DECOR ++ || vc->vc_num != fg_console ++#endif ++ ) + return -EINVAL; + + if (!CON_IS_VISIBLE(vc)) +@@ -2683,14 +2759,56 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) + } else + fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap); + +- return fb_set_cmap(&palette_cmap, info); ++ if (fbcon_decor_active(info, vc_cons[fg_console].d) && ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR) { ++ ++ u16 *red, *green, *blue; ++ int minlen = min(min(info->var.red.length, info->var.green.length), ++ info->var.blue.length); ++ int h; ++ ++ struct fb_cmap cmap = { ++ .start = 0, ++ .len = (1 << minlen), ++ .red = NULL, ++ .green = NULL, ++ .blue = NULL, ++ .transp = NULL ++ }; ++ ++ red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL); ++ ++ if (!red) ++ goto out; ++ ++ green = red + 256; ++ blue = green + 256; ++ cmap.red = red; ++ cmap.green = green; ++ cmap.blue = blue; ++ ++ for (i = 0; i < cmap.len; i++) { ++ red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1); ++ } ++ ++ h = fb_set_cmap(&cmap, info); ++ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d); ++ kfree(red); ++ ++ return h; ++ ++ } else if (fbcon_decor_active(info, vc_cons[fg_console].d) && ++ info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL) ++ fb_set_cmap(&info->bgdecor.cmap, info); ++ ++out: return fb_set_cmap(&palette_cmap, info); + } + + static u16 *fbcon_screen_pos(struct vc_data *vc, int offset) + { + unsigned long p; + int line; +- ++ + if (vc->vc_num != fg_console || !softback_lines) + return (u16 *) (vc->vc_origin + offset); + line = offset / vc->vc_size_row; +@@ -2909,7 +3027,14 @@ static void fbcon_modechanged(struct fb_info *info) + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; +- vc_resize(vc, cols, rows); ++ ++ if (!fbcon_decor_active_nores(info, vc)) { ++ vc_resize(vc, cols, rows); ++ } else { ++ fbcon_decor_disable(vc, 0); ++ fbcon_decor_call_helper("modechange", vc->vc_num); ++ } ++ + updatescrollmode(p, info, vc); + scrollback_max = 0; + scrollback_current = 0; +@@ -2954,7 +3079,9 @@ static void fbcon_set_all_vcs(struct fb_info *info) + rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); + cols /= vc->vc_font.width; + rows /= vc->vc_font.height; +- vc_resize(vc, cols, rows); ++ if (!fbcon_decor_active_nores(info, vc)) { ++ vc_resize(vc, cols, rows); ++ } + } + + if (fg != -1) +@@ -3596,6 +3723,7 @@ static void fbcon_exit(void) + } + } + ++ fbcon_decor_exit(); + fbcon_has_exited = 1; + } + +diff --git a/drivers/video/console/fbcondecor.c b/drivers/video/console/fbcondecor.c +new file mode 100644 +index 0000000..babc8c5 +--- /dev/null ++++ b/drivers/video/console/fbcondecor.c +@@ -0,0 +1,555 @@ ++/* ++ * linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations ++ * ++ * Copyright (C) 2004-2009 Michal Januszewski ++ * ++ * Code based upon "Bootsplash" (C) 2001-2003 ++ * Volker Poplawski , ++ * Stefan Reinauer , ++ * Steffen Winterfeldt , ++ * Michael Schroeder , ++ * Ken Wimer . ++ * ++ * Compat ioctl support by Thorsten Klein . ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file COPYING in the main directory of this archive for ++ * more details. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "fbcon.h" ++#include "fbcondecor.h" ++ ++extern signed char con2fb_map[]; ++static int fbcon_decor_enable(struct vc_data *vc); ++char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper"; ++static int initialized = 0; ++ ++int fbcon_decor_call_helper(char* cmd, unsigned short vc) ++{ ++ char *envp[] = { ++ "HOME=/", ++ "PATH=/sbin:/bin", ++ NULL ++ }; ++ ++ char tfb[5]; ++ char tcons[5]; ++ unsigned char fb = (int) con2fb_map[vc]; ++ ++ char *argv[] = { ++ fbcon_decor_path, ++ "2", ++ cmd, ++ tcons, ++ tfb, ++ vc_cons[vc].d->vc_decor.theme, ++ NULL ++ }; ++ ++ snprintf(tfb,5,"%d",fb); ++ snprintf(tcons,5,"%d",vc); ++ ++ return call_usermodehelper(fbcon_decor_path, argv, envp, UMH_WAIT_EXEC); ++} ++ ++/* Disables fbcondecor on a virtual console; called with console sem held. */ ++int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) ++{ ++ struct fb_info* info; ++ ++ if (!vc->vc_decor.state) ++ return -EINVAL; ++ ++ info = registered_fb[(int) con2fb_map[vc->vc_num]]; ++ ++ if (info == NULL) ++ return -EINVAL; ++ ++ vc->vc_decor.state = 0; ++ vc_resize(vc, info->var.xres / vc->vc_font.width, ++ info->var.yres / vc->vc_font.height); ++ ++ if (fg_console == vc->vc_num && redraw) { ++ redraw_screen(vc, 0); ++ update_region(vc, vc->vc_origin + ++ vc->vc_size_row * vc->vc_top, ++ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); ++ } ++ ++ printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n", ++ vc->vc_num); ++ ++ return 0; ++} ++ ++/* Enables fbcondecor on a virtual console; called with console sem held. */ ++static int fbcon_decor_enable(struct vc_data *vc) ++{ ++ struct fb_info* info; ++ ++ info = registered_fb[(int) con2fb_map[vc->vc_num]]; ++ ++ if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 || ++ info == NULL || vc->vc_decor.state || (!info->bgdecor.data && ++ vc->vc_num == fg_console)) ++ return -EINVAL; ++ ++ vc->vc_decor.state = 1; ++ vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width, ++ vc->vc_decor.theight / vc->vc_font.height); ++ ++ if (fg_console == vc->vc_num) { ++ redraw_screen(vc, 0); ++ update_region(vc, vc->vc_origin + ++ vc->vc_size_row * vc->vc_top, ++ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); ++ fbcon_decor_clear_margins(vc, info, 0); ++ } ++ ++ printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n", ++ vc->vc_num); ++ ++ return 0; ++} ++ ++static inline int fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int state, unsigned char origin) ++{ ++ int ret; ++ ++// if (origin == FBCON_DECOR_IO_ORIG_USER) ++ console_lock(); ++ if (!state) ++ ret = fbcon_decor_disable(vc, 1); ++ else ++ ret = fbcon_decor_enable(vc); ++// if (origin == FBCON_DECOR_IO_ORIG_USER) ++ console_unlock(); ++ ++ return ret; ++} ++ ++static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state) ++{ ++ *state = vc->vc_decor.state; ++} ++ ++static int fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor *cfg, unsigned char origin) ++{ ++ struct fb_info *info; ++ int len; ++ char *tmp; ++ ++ info = registered_fb[(int) con2fb_map[vc->vc_num]]; ++ ++ if (info == NULL || !cfg->twidth || !cfg->theight || ++ cfg->tx + cfg->twidth > info->var.xres || ++ cfg->ty + cfg->theight > info->var.yres) ++ return -EINVAL; ++ ++ len = strlen_user(cfg->theme); ++ if (!len || len > FBCON_DECOR_THEME_LEN) ++ return -EINVAL; ++ tmp = kmalloc(len, GFP_KERNEL); ++ if (!tmp) ++ return -ENOMEM; ++ if (copy_from_user(tmp, (void __user *)cfg->theme, len)) ++ return -EFAULT; ++ cfg->theme = tmp; ++ cfg->state = 0; ++ ++ /* If this ioctl is a response to a request from kernel, the console sem ++ * is already held; we also don't need to disable decor because either the ++ * new config and background picture will be successfully loaded, and the ++ * decor will stay on, or in case of a failure it'll be turned off in fbcon. */ ++// if (origin == FBCON_DECOR_IO_ORIG_USER) { ++ console_lock(); ++ if (vc->vc_decor.state) ++ fbcon_decor_disable(vc, 1); ++// } ++ ++ if (vc->vc_decor.theme) ++ kfree(vc->vc_decor.theme); ++ ++ vc->vc_decor = *cfg; ++ ++// if (origin == FBCON_DECOR_IO_ORIG_USER) ++ console_unlock(); ++ ++ printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n", ++ vc->vc_num, vc->vc_decor.theme); ++ return 0; ++} ++ ++static int fbcon_decor_ioctl_dogetcfg(struct vc_data *vc, struct vc_decor *decor) ++{ ++ char __user *tmp; ++ ++ tmp = decor->theme; ++ *decor = vc->vc_decor; ++ decor->theme = tmp; ++ ++ if (vc->vc_decor.theme) { ++ if (copy_to_user(tmp, vc->vc_decor.theme, strlen(vc->vc_decor.theme) + 1)) ++ return -EFAULT; ++ } else ++ if (put_user(0, tmp)) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++static int fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image *img, unsigned char origin) ++{ ++ struct fb_info *info; ++ int len; ++ u8 *tmp; ++ ++ if (vc->vc_num != fg_console) ++ return -EINVAL; ++ ++ info = registered_fb[(int) con2fb_map[vc->vc_num]]; ++ ++ if (info == NULL) ++ return -EINVAL; ++ ++ if (img->width != info->var.xres || img->height != info->var.yres) { ++ printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n"); ++ printk(KERN_ERR "%dx%d vs %dx%d\n", img->width, img->height, info->var.xres, info->var.yres); ++ return -EINVAL; ++ } ++ ++ if (img->depth != info->var.bits_per_pixel) { ++ printk(KERN_ERR "fbcondecor: picture depth mismatch\n"); ++ return -EINVAL; ++ } ++ ++ if (img->depth == 8) { ++ if (!img->cmap.len || !img->cmap.red || !img->cmap.green || ++ !img->cmap.blue) ++ return -EINVAL; ++ ++ tmp = vmalloc(img->cmap.len * 3 * 2); ++ if (!tmp) ++ return -ENOMEM; ++ ++ if (copy_from_user(tmp, ++ (void __user*)img->cmap.red, (img->cmap.len << 1)) || ++ copy_from_user(tmp + (img->cmap.len << 1), ++ (void __user*)img->cmap.green, (img->cmap.len << 1)) || ++ copy_from_user(tmp + (img->cmap.len << 2), ++ (void __user*)img->cmap.blue, (img->cmap.len << 1))) { ++ vfree(tmp); ++ return -EFAULT; ++ } ++ ++ img->cmap.transp = NULL; ++ img->cmap.red = (u16*)tmp; ++ img->cmap.green = img->cmap.red + img->cmap.len; ++ img->cmap.blue = img->cmap.green + img->cmap.len; ++ } else { ++ img->cmap.red = NULL; ++ } ++ ++ len = ((img->depth + 7) >> 3) * img->width * img->height; ++ ++ /* ++ * Allocate an additional byte so that we never go outside of the ++ * buffer boundaries in the rendering functions in a 24 bpp mode. ++ */ ++ tmp = vmalloc(len + 1); ++ ++ if (!tmp) ++ goto out; ++ ++ if (copy_from_user(tmp, (void __user*)img->data, len)) ++ goto out; ++ ++ img->data = tmp; ++ ++ /* If this ioctl is a response to a request from kernel, the console sem ++ * is already held. */ ++// if (origin == FBCON_DECOR_IO_ORIG_USER) ++ console_lock(); ++ ++ if (info->bgdecor.data) ++ vfree((u8*)info->bgdecor.data); ++ if (info->bgdecor.cmap.red) ++ vfree(info->bgdecor.cmap.red); ++ ++ info->bgdecor = *img; ++ ++ if (fbcon_decor_active_vc(vc) && fg_console == vc->vc_num) { ++ redraw_screen(vc, 0); ++ update_region(vc, vc->vc_origin + ++ vc->vc_size_row * vc->vc_top, ++ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2); ++ fbcon_decor_clear_margins(vc, info, 0); ++ } ++ ++// if (origin == FBCON_DECOR_IO_ORIG_USER) ++ console_unlock(); ++ ++ return 0; ++ ++out: if (img->cmap.red) ++ vfree(img->cmap.red); ++ ++ if (tmp) ++ vfree(tmp); ++ return -ENOMEM; ++} ++ ++static long fbcon_decor_ioctl(struct file *filp, u_int cmd, u_long arg) ++{ ++ struct fbcon_decor_iowrapper __user *wrapper = (void __user*) arg; ++ struct vc_data *vc = NULL; ++ unsigned short vc_num = 0; ++ unsigned char origin = 0; ++ void __user *data = NULL; ++ ++ if (!access_ok(VERIFY_READ, wrapper, ++ sizeof(struct fbcon_decor_iowrapper))) ++ return -EFAULT; ++ ++ __get_user(vc_num, &wrapper->vc); ++ __get_user(origin, &wrapper->origin); ++ __get_user(data, &wrapper->data); ++ ++ if (!vc_cons_allocated(vc_num)) ++ return -EINVAL; ++ ++ vc = vc_cons[vc_num].d; ++ ++ switch (cmd) { ++ case FBIOCONDECOR_SETPIC: ++ { ++ struct fb_image img; ++ if (copy_from_user(&img, (struct fb_image __user *)data, sizeof(struct fb_image))) ++ return -EFAULT; ++ ++ return fbcon_decor_ioctl_dosetpic(vc, &img, origin); ++ } ++ case FBIOCONDECOR_SETCFG: ++ { ++ struct vc_decor cfg; ++ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor))) ++ return -EFAULT; ++ ++ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin); ++ } ++ case FBIOCONDECOR_GETCFG: ++ { ++ int rval; ++ struct vc_decor cfg; ++ ++ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor))) ++ return -EFAULT; ++ ++ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg); ++ ++ if (copy_to_user(data, &cfg, sizeof(struct vc_decor))) ++ return -EFAULT; ++ return rval; ++ } ++ case FBIOCONDECOR_SETSTATE: ++ { ++ unsigned int state = 0; ++ if (get_user(state, (unsigned int __user *)data)) ++ return -EFAULT; ++ return fbcon_decor_ioctl_dosetstate(vc, state, origin); ++ } ++ case FBIOCONDECOR_GETSTATE: ++ { ++ unsigned int state = 0; ++ fbcon_decor_ioctl_dogetstate(vc, &state); ++ return put_user(state, (unsigned int __user *)data); ++ } ++ ++ default: ++ return -ENOIOCTLCMD; ++ } ++} ++ ++#ifdef CONFIG_COMPAT ++ ++static long fbcon_decor_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { ++ ++ struct fbcon_decor_iowrapper32 __user *wrapper = (void __user *)arg; ++ struct vc_data *vc = NULL; ++ unsigned short vc_num = 0; ++ unsigned char origin = 0; ++ compat_uptr_t data_compat = 0; ++ void __user *data = NULL; ++ ++ if (!access_ok(VERIFY_READ, wrapper, ++ sizeof(struct fbcon_decor_iowrapper32))) ++ return -EFAULT; ++ ++ __get_user(vc_num, &wrapper->vc); ++ __get_user(origin, &wrapper->origin); ++ __get_user(data_compat, &wrapper->data); ++ data = compat_ptr(data_compat); ++ ++ if (!vc_cons_allocated(vc_num)) ++ return -EINVAL; ++ ++ vc = vc_cons[vc_num].d; ++ ++ switch (cmd) { ++ case FBIOCONDECOR_SETPIC32: ++ { ++ struct fb_image32 img_compat; ++ struct fb_image img; ++ ++ if (copy_from_user(&img_compat, (struct fb_image32 __user *)data, sizeof(struct fb_image32))) ++ return -EFAULT; ++ ++ fb_image_from_compat(img, img_compat); ++ ++ return fbcon_decor_ioctl_dosetpic(vc, &img, origin); ++ } ++ ++ case FBIOCONDECOR_SETCFG32: ++ { ++ struct vc_decor32 cfg_compat; ++ struct vc_decor cfg; ++ ++ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32))) ++ return -EFAULT; ++ ++ vc_decor_from_compat(cfg, cfg_compat); ++ ++ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin); ++ } ++ ++ case FBIOCONDECOR_GETCFG32: ++ { ++ int rval; ++ struct vc_decor32 cfg_compat; ++ struct vc_decor cfg; ++ ++ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32))) ++ return -EFAULT; ++ cfg.theme = compat_ptr(cfg_compat.theme); ++ ++ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg); ++ ++ vc_decor_to_compat(cfg_compat, cfg); ++ ++ if (copy_to_user((struct vc_decor32 __user *)data, &cfg_compat, sizeof(struct vc_decor32))) ++ return -EFAULT; ++ return rval; ++ } ++ ++ case FBIOCONDECOR_SETSTATE32: ++ { ++ compat_uint_t state_compat = 0; ++ unsigned int state = 0; ++ ++ if (get_user(state_compat, (compat_uint_t __user *)data)) ++ return -EFAULT; ++ ++ state = (unsigned int)state_compat; ++ ++ return fbcon_decor_ioctl_dosetstate(vc, state, origin); ++ } ++ ++ case FBIOCONDECOR_GETSTATE32: ++ { ++ compat_uint_t state_compat = 0; ++ unsigned int state = 0; ++ ++ fbcon_decor_ioctl_dogetstate(vc, &state); ++ state_compat = (compat_uint_t)state; ++ ++ return put_user(state_compat, (compat_uint_t __user *)data); ++ } ++ ++ default: ++ return -ENOIOCTLCMD; ++ } ++} ++#else ++ #define fbcon_decor_compat_ioctl NULL ++#endif ++ ++static struct file_operations fbcon_decor_ops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = fbcon_decor_ioctl, ++ .compat_ioctl = fbcon_decor_compat_ioctl ++}; ++ ++static struct miscdevice fbcon_decor_dev = { ++ .minor = MISC_DYNAMIC_MINOR, ++ .name = "fbcondecor", ++ .fops = &fbcon_decor_ops ++}; ++ ++void fbcon_decor_reset(void) ++{ ++ int i; ++ ++ for (i = 0; i < num_registered_fb; i++) { ++ registered_fb[i]->bgdecor.data = NULL; ++ registered_fb[i]->bgdecor.cmap.red = NULL; ++ } ++ ++ for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) { ++ vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth = ++ vc_cons[i].d->vc_decor.theight = 0; ++ vc_cons[i].d->vc_decor.theme = NULL; ++ } ++ ++ return; ++} ++ ++int fbcon_decor_init(void) ++{ ++ int i; ++ ++ fbcon_decor_reset(); ++ ++ if (initialized) ++ return 0; ++ ++ i = misc_register(&fbcon_decor_dev); ++ if (i) { ++ printk(KERN_ERR "fbcondecor: failed to register device\n"); ++ return i; ++ } ++ ++ fbcon_decor_call_helper("init", 0); ++ initialized = 1; ++ return 0; ++} ++ ++int fbcon_decor_exit(void) ++{ ++ fbcon_decor_reset(); ++ return 0; ++} ++ ++EXPORT_SYMBOL(fbcon_decor_path); +diff --git a/drivers/video/console/fbcondecor.h b/drivers/video/console/fbcondecor.h +new file mode 100644 +index 0000000..3b3724b +--- /dev/null ++++ b/drivers/video/console/fbcondecor.h +@@ -0,0 +1,78 @@ ++/* ++ * linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers ++ * ++ * Copyright (C) 2004 Michal Januszewski ++ * ++ */ ++ ++#ifndef __FBCON_DECOR_H ++#define __FBCON_DECOR_H ++ ++#ifndef _LINUX_FB_H ++#include ++#endif ++ ++/* This is needed for vc_cons in fbcmap.c */ ++#include ++ ++struct fb_cursor; ++struct fb_info; ++struct vc_data; ++ ++#ifdef CONFIG_FB_CON_DECOR ++/* fbcondecor.c */ ++int fbcon_decor_init(void); ++int fbcon_decor_exit(void); ++int fbcon_decor_call_helper(char* cmd, unsigned short cons); ++int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw); ++ ++/* cfbcondecor.c */ ++void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx); ++void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor); ++void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width); ++void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only); ++void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank); ++void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width); ++void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp); ++void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc); ++ ++/* vt.c */ ++void acquire_console_sem(void); ++void release_console_sem(void); ++void do_unblank_screen(int entering_gfx); ++ ++/* struct vc_data *y */ ++#define fbcon_decor_active_vc(y) (y->vc_decor.state && y->vc_decor.theme) ++ ++/* struct fb_info *x, struct vc_data *y */ ++#define fbcon_decor_active_nores(x,y) (x->bgdecor.data && fbcon_decor_active_vc(y)) ++ ++/* struct fb_info *x, struct vc_data *y */ ++#define fbcon_decor_active(x,y) (fbcon_decor_active_nores(x,y) && \ ++ x->bgdecor.width == x->var.xres && \ ++ x->bgdecor.height == x->var.yres && \ ++ x->bgdecor.depth == x->var.bits_per_pixel) ++ ++ ++#else /* CONFIG_FB_CON_DECOR */ ++ ++static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {} ++static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {} ++static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {} ++static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {} ++static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {} ++static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {} ++static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {} ++static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {} ++static inline int fbcon_decor_call_helper(char* cmd, unsigned short cons) { return 0; } ++static inline int fbcon_decor_init(void) { return 0; } ++static inline int fbcon_decor_exit(void) { return 0; } ++static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; } ++ ++#define fbcon_decor_active_vc(y) (0) ++#define fbcon_decor_active_nores(x,y) (0) ++#define fbcon_decor_active(x,y) (0) ++ ++#endif /* CONFIG_FB_CON_DECOR */ ++ ++#endif /* __FBCON_DECOR_H */ +diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig +index e1f4727..2952e33 100644 +--- a/drivers/video/fbdev/Kconfig ++++ b/drivers/video/fbdev/Kconfig +@@ -1204,7 +1204,6 @@ config FB_MATROX + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT +- select FB_TILEBLITTING + select FB_MACMODES if PPC_PMAC + ---help--- + Say Y here if you have a Matrox Millennium, Matrox Millennium II, +diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c +index f89245b..05e036c 100644 +--- a/drivers/video/fbdev/core/fbcmap.c ++++ b/drivers/video/fbdev/core/fbcmap.c +@@ -17,6 +17,8 @@ + #include + #include + ++#include "../../console/fbcondecor.h" ++ + static u16 red2[] __read_mostly = { + 0x0000, 0xaaaa + }; +@@ -249,14 +251,17 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) + if (transp) + htransp = *transp++; + if (info->fbops->fb_setcolreg(start++, +- hred, hgreen, hblue, ++ hred, hgreen, hblue, + htransp, info)) + break; + } + } +- if (rc == 0) ++ if (rc == 0) { + fb_copy_cmap(cmap, &info->cmap); +- ++ if (fbcon_decor_active(info, vc_cons[fg_console].d) && ++ info->fix.visual == FB_VISUAL_DIRECTCOLOR) ++ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d); ++ } + return rc; + } + +diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c +index b6d5008..d6703f2 100644 +--- a/drivers/video/fbdev/core/fbmem.c ++++ b/drivers/video/fbdev/core/fbmem.c +@@ -1250,15 +1250,6 @@ struct fb_fix_screeninfo32 { + u16 reserved[3]; + }; + +-struct fb_cmap32 { +- u32 start; +- u32 len; +- compat_caddr_t red; +- compat_caddr_t green; +- compat_caddr_t blue; +- compat_caddr_t transp; +-}; +- + static int fb_getput_cmap(struct fb_info *info, unsigned int cmd, + unsigned long arg) + { +diff --git a/include/linux/console_decor.h b/include/linux/console_decor.h +new file mode 100644 +index 0000000..04b8d80 +--- /dev/null ++++ b/include/linux/console_decor.h +@@ -0,0 +1,46 @@ ++#ifndef _LINUX_CONSOLE_DECOR_H_ ++#define _LINUX_CONSOLE_DECOR_H_ 1 ++ ++/* A structure used by the framebuffer console decorations (drivers/video/console/fbcondecor.c) */ ++struct vc_decor { ++ __u8 bg_color; /* The color that is to be treated as transparent */ ++ __u8 state; /* Current decor state: 0 = off, 1 = on */ ++ __u16 tx, ty; /* Top left corner coordinates of the text field */ ++ __u16 twidth, theight; /* Width and height of the text field */ ++ char* theme; ++}; ++ ++#ifdef __KERNEL__ ++#ifdef CONFIG_COMPAT ++#include ++ ++struct vc_decor32 { ++ __u8 bg_color; /* The color that is to be treated as transparent */ ++ __u8 state; /* Current decor state: 0 = off, 1 = on */ ++ __u16 tx, ty; /* Top left corner coordinates of the text field */ ++ __u16 twidth, theight; /* Width and height of the text field */ ++ compat_uptr_t theme; ++}; ++ ++#define vc_decor_from_compat(to, from) \ ++ (to).bg_color = (from).bg_color; \ ++ (to).state = (from).state; \ ++ (to).tx = (from).tx; \ ++ (to).ty = (from).ty; \ ++ (to).twidth = (from).twidth; \ ++ (to).theight = (from).theight; \ ++ (to).theme = compat_ptr((from).theme) ++ ++#define vc_decor_to_compat(to, from) \ ++ (to).bg_color = (from).bg_color; \ ++ (to).state = (from).state; \ ++ (to).tx = (from).tx; \ ++ (to).ty = (from).ty; \ ++ (to).twidth = (from).twidth; \ ++ (to).theight = (from).theight; \ ++ (to).theme = ptr_to_compat((from).theme) ++ ++#endif /* CONFIG_COMPAT */ ++#endif /* __KERNEL__ */ ++ ++#endif +diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h +index 7f0c329..98f5d60 100644 +--- a/include/linux/console_struct.h ++++ b/include/linux/console_struct.h +@@ -19,6 +19,7 @@ + struct vt_struct; + + #define NPAR 16 ++#include + + struct vc_data { + struct tty_port port; /* Upper level data */ +@@ -107,6 +108,8 @@ struct vc_data { + unsigned long vc_uni_pagedir; + unsigned long *vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ + bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */ ++ ++ struct vc_decor vc_decor; + /* additional information is in vt_kern.h */ + }; + +diff --git a/include/linux/fb.h b/include/linux/fb.h +index fe6ac95..1e36b03 100644 +--- a/include/linux/fb.h ++++ b/include/linux/fb.h +@@ -219,6 +219,34 @@ struct fb_deferred_io { + }; + #endif + ++#ifdef __KERNEL__ ++#ifdef CONFIG_COMPAT ++struct fb_image32 { ++ __u32 dx; /* Where to place image */ ++ __u32 dy; ++ __u32 width; /* Size of image */ ++ __u32 height; ++ __u32 fg_color; /* Only used when a mono bitmap */ ++ __u32 bg_color; ++ __u8 depth; /* Depth of the image */ ++ const compat_uptr_t data; /* Pointer to image data */ ++ struct fb_cmap32 cmap; /* color map info */ ++}; ++ ++#define fb_image_from_compat(to, from) \ ++ (to).dx = (from).dx; \ ++ (to).dy = (from).dy; \ ++ (to).width = (from).width; \ ++ (to).height = (from).height; \ ++ (to).fg_color = (from).fg_color; \ ++ (to).bg_color = (from).bg_color; \ ++ (to).depth = (from).depth; \ ++ (to).data = compat_ptr((from).data); \ ++ fb_cmap_from_compat((to).cmap, (from).cmap) ++ ++#endif /* CONFIG_COMPAT */ ++#endif /* __KERNEL__ */ ++ + /* + * Frame buffer operations + * +@@ -489,6 +517,9 @@ struct fb_info { + #define FBINFO_STATE_SUSPENDED 1 + u32 state; /* Hardware state i.e suspend */ + void *fbcon_par; /* fbcon use-only private area */ ++ ++ struct fb_image bgdecor; ++ + /* From here on everything is device dependent */ + void *par; + /* we need the PCI or similar aperture base/size not +diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h +index fb795c3..dc77a03 100644 +--- a/include/uapi/linux/fb.h ++++ b/include/uapi/linux/fb.h +@@ -8,6 +8,25 @@ + + #define FB_MAX 32 /* sufficient for now */ + ++struct fbcon_decor_iowrapper ++{ ++ unsigned short vc; /* Virtual console */ ++ unsigned char origin; /* Point of origin of the request */ ++ void *data; ++}; ++ ++#ifdef __KERNEL__ ++#ifdef CONFIG_COMPAT ++#include ++struct fbcon_decor_iowrapper32 ++{ ++ unsigned short vc; /* Virtual console */ ++ unsigned char origin; /* Point of origin of the request */ ++ compat_uptr_t data; ++}; ++#endif /* CONFIG_COMPAT */ ++#endif /* __KERNEL__ */ ++ + /* ioctls + 0x46 is 'F' */ + #define FBIOGET_VSCREENINFO 0x4600 +@@ -35,6 +54,25 @@ + #define FBIOGET_DISPINFO 0x4618 + #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) + ++#define FBIOCONDECOR_SETCFG _IOWR('F', 0x19, struct fbcon_decor_iowrapper) ++#define FBIOCONDECOR_GETCFG _IOR('F', 0x1A, struct fbcon_decor_iowrapper) ++#define FBIOCONDECOR_SETSTATE _IOWR('F', 0x1B, struct fbcon_decor_iowrapper) ++#define FBIOCONDECOR_GETSTATE _IOR('F', 0x1C, struct fbcon_decor_iowrapper) ++#define FBIOCONDECOR_SETPIC _IOWR('F', 0x1D, struct fbcon_decor_iowrapper) ++#ifdef __KERNEL__ ++#ifdef CONFIG_COMPAT ++#define FBIOCONDECOR_SETCFG32 _IOWR('F', 0x19, struct fbcon_decor_iowrapper32) ++#define FBIOCONDECOR_GETCFG32 _IOR('F', 0x1A, struct fbcon_decor_iowrapper32) ++#define FBIOCONDECOR_SETSTATE32 _IOWR('F', 0x1B, struct fbcon_decor_iowrapper32) ++#define FBIOCONDECOR_GETSTATE32 _IOR('F', 0x1C, struct fbcon_decor_iowrapper32) ++#define FBIOCONDECOR_SETPIC32 _IOWR('F', 0x1D, struct fbcon_decor_iowrapper32) ++#endif /* CONFIG_COMPAT */ ++#endif /* __KERNEL__ */ ++ ++#define FBCON_DECOR_THEME_LEN 128 /* Maximum lenght of a theme name */ ++#define FBCON_DECOR_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */ ++#define FBCON_DECOR_IO_ORIG_USER 1 /* User ioctl origin */ ++ + #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ + #define FB_TYPE_PLANES 1 /* Non interleaved planes */ + #define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */ +@@ -277,6 +315,29 @@ struct fb_var_screeninfo { + __u32 reserved[4]; /* Reserved for future compatibility */ + }; + ++#ifdef __KERNEL__ ++#ifdef CONFIG_COMPAT ++struct fb_cmap32 { ++ __u32 start; ++ __u32 len; /* Number of entries */ ++ compat_uptr_t red; /* Red values */ ++ compat_uptr_t green; ++ compat_uptr_t blue; ++ compat_uptr_t transp; /* transparency, can be NULL */ ++}; ++ ++#define fb_cmap_from_compat(to, from) \ ++ (to).start = (from).start; \ ++ (to).len = (from).len; \ ++ (to).red = compat_ptr((from).red); \ ++ (to).green = compat_ptr((from).green); \ ++ (to).blue = compat_ptr((from).blue); \ ++ (to).transp = compat_ptr((from).transp) ++ ++#endif /* CONFIG_COMPAT */ ++#endif /* __KERNEL__ */ ++ ++ + struct fb_cmap { + __u32 start; /* First entry */ + __u32 len; /* Number of entries */ +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index 74f5b58..6386ab0 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -146,6 +146,10 @@ static const int cap_last_cap = CAP_LAST_CAP; + static unsigned long hung_task_timeout_max = (LONG_MAX/HZ); + #endif + ++#ifdef CONFIG_FB_CON_DECOR ++extern char fbcon_decor_path[]; ++#endif ++ + #ifdef CONFIG_INOTIFY_USER + #include + #endif +@@ -255,6 +259,15 @@ static struct ctl_table sysctl_base_table[] = { + .mode = 0555, + .child = dev_table, + }, ++#ifdef CONFIG_FB_CON_DECOR ++ { ++ .procname = "fbcondecor", ++ .data = &fbcon_decor_path, ++ .maxlen = KMOD_PATH_LEN, ++ .mode = 0644, ++ .proc_handler = &proc_dostring, ++ }, ++#endif + { } + }; + diff --git a/kernel/kernel/files/patches/gentoo/4567_distro-Gentoo-Kconfig.patch b/kernel/kernel/files/patches/gentoo/4567_distro-Gentoo-Kconfig.patch new file mode 100644 index 00000000..c7af596c --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/4567_distro-Gentoo-Kconfig.patch @@ -0,0 +1,143 @@ +--- a/Kconfig ++++ b/Kconfig +@@ -8,4 +8,6 @@ config SRCARCH + string + option env="SRCARCH" + ++source "distro/Kconfig" ++ + source "arch/$SRCARCH/Kconfig" +--- /dev/null ++++ b/distro/Kconfig +@@ -0,0 +1,131 @@ ++menu "Gentoo Linux" ++ ++config GENTOO_LINUX ++ bool "Gentoo Linux support" ++ ++ default y ++ ++ help ++ In order to boot Gentoo Linux a minimal set of config settings needs to ++ be enabled in the kernel; to avoid the users from having to enable them ++ manually as part of a Gentoo Linux installation or a new clean config, ++ we enable these config settings by default for convenience. ++ ++ See the settings that become available for more details and fine-tuning. ++ ++config GENTOO_LINUX_UDEV ++ bool "Linux dynamic and persistent device naming (userspace devfs) support" ++ ++ depends on GENTOO_LINUX ++ default y if GENTOO_LINUX ++ ++ select DEVTMPFS ++ select TMPFS ++ ++ select MMU ++ select SHMEM ++ ++ help ++ In order to boot Gentoo Linux a minimal set of config settings needs to ++ be enabled in the kernel; to avoid the users from having to enable them ++ manually as part of a Gentoo Linux installation or a new clean config, ++ we enable these config settings by default for convenience. ++ ++ Currently this only selects TMPFS, DEVTMPFS and their dependencies. ++ TMPFS is enabled to maintain a tmpfs file system at /dev/shm, /run and ++ /sys/fs/cgroup; DEVTMPFS to maintain a devtmpfs file system at /dev. ++ ++ Some of these are critical files that need to be available early in the ++ boot process; if not available, it causes sysfs and udev to malfunction. ++ ++ To ensure Gentoo Linux boots, it is best to leave this setting enabled; ++ if you run a custom setup, you could consider whether to disable this. ++ ++config GENTOO_LINUX_PORTAGE ++ bool "Select options required by Portage features" ++ ++ depends on GENTOO_LINUX ++ default y if GENTOO_LINUX ++ ++ select CGROUPS ++ select NAMESPACES ++ select IPC_NS ++ select NET_NS ++ ++ help ++ This enables options required by various Portage FEATURES. ++ Currently this selects: ++ ++ CGROUPS (required for FEATURES=cgroup) ++ IPC_NS (required for FEATURES=ipc-sandbox) ++ NET_NS (required for FEATURES=network-sandbox) ++ ++ It is highly recommended that you leave this enabled as these FEATURES ++ are, or will soon be, enabled by default. ++ ++menu "Support for init systems, system and service managers" ++ visible if GENTOO_LINUX ++ ++config GENTOO_LINUX_INIT_SCRIPT ++ bool "OpenRC, runit and other script based systems and managers" ++ ++ default y if GENTOO_LINUX ++ ++ depends on GENTOO_LINUX ++ ++ select BINFMT_SCRIPT ++ ++ help ++ The init system is the first thing that loads after the kernel booted. ++ ++ These config settings allow you to select which init systems to support; ++ instead of having to select all the individual settings all over the ++ place, these settings allows you to select all the settings at once. ++ ++ This particular setting enables all the known requirements for OpenRC, ++ runit and similar script based systems and managers. ++ ++ If you are unsure about this, it is best to leave this setting enabled. ++ ++config GENTOO_LINUX_INIT_SYSTEMD ++ bool "systemd" ++ ++ default n ++ ++ depends on GENTOO_LINUX && GENTOO_LINUX_UDEV ++ ++ select AUTOFS4_FS ++ select BLK_DEV_BSG ++ select CGROUPS ++ select DEVPTS_MULTIPLE_INSTANCES ++ select EPOLL ++ select FANOTIFY ++ select FHANDLE ++ select INOTIFY_USER ++ select NET ++ select NET_NS ++ select PROC_FS ++ select SIGNALFD ++ select SYSFS ++ select TIMERFD ++ ++ select ANON_INODES ++ select BLOCK ++ select EVENTFD ++ select FSNOTIFY ++ select INET ++ select NLATTR ++ ++ help ++ The init system is the first thing that loads after the kernel booted. ++ ++ These config settings allow you to select which init systems to support; ++ instead of having to select all the individual settings all over the ++ place, these settings allows you to select all the settings at once. ++ ++ This particular setting enables all the known requirements for systemd; ++ it also enables suggested optional settings, as the package suggests to. ++ ++endmenu ++ ++endmenu diff --git a/kernel/kernel/files/patches/gentoo/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r7-3.19.patch b/kernel/kernel/files/patches/gentoo/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r7-3.19.patch new file mode 100644 index 00000000..b36d572c --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r7-3.19.patch @@ -0,0 +1,104 @@ +From a828d56aebc0735676be23734cccf31e279c0d1b Mon Sep 17 00:00:00 2001 +From: Paolo Valente +Date: Mon, 8 Dec 2014 16:04:25 +0100 +Subject: [PATCH 1/3] block: cgroups, kconfig, build bits for BFQ-v7r7-3.19 + +Update Kconfig.iosched and do the related Makefile changes to include +kernel configuration options for BFQ. Also add the bfqio controller +to the cgroups subsystem. + +Signed-off-by: Paolo Valente +Signed-off-by: Arianna Avanzini +--- + block/Kconfig.iosched | 32 ++++++++++++++++++++++++++++++++ + block/Makefile | 1 + + include/linux/cgroup_subsys.h | 4 ++++ + 3 files changed, 37 insertions(+) + +diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched +index 421bef9..0ee5f0f 100644 +--- a/block/Kconfig.iosched ++++ b/block/Kconfig.iosched +@@ -39,6 +39,27 @@ config CFQ_GROUP_IOSCHED + ---help--- + Enable group IO scheduling in CFQ. + ++config IOSCHED_BFQ ++ tristate "BFQ I/O scheduler" ++ default n ++ ---help--- ++ The BFQ I/O scheduler tries to distribute bandwidth among ++ all processes according to their weights. ++ It aims at distributing the bandwidth as desired, independently of ++ the disk parameters and with any workload. It also tries to ++ guarantee low latency to interactive and soft real-time ++ applications. If compiled built-in (saying Y here), BFQ can ++ be configured to support hierarchical scheduling. ++ ++config CGROUP_BFQIO ++ bool "BFQ hierarchical scheduling support" ++ depends on CGROUPS && IOSCHED_BFQ=y ++ default n ++ ---help--- ++ Enable hierarchical scheduling in BFQ, using the cgroups ++ filesystem interface. The name of the subsystem will be ++ bfqio. ++ + choice + prompt "Default I/O scheduler" + default DEFAULT_CFQ +@@ -52,6 +73,16 @@ choice + config DEFAULT_CFQ + bool "CFQ" if IOSCHED_CFQ=y + ++ config DEFAULT_BFQ ++ bool "BFQ" if IOSCHED_BFQ=y ++ help ++ Selects BFQ as the default I/O scheduler which will be ++ used by default for all block devices. ++ The BFQ I/O scheduler aims at distributing the bandwidth ++ as desired, independently of the disk parameters and with ++ any workload. It also tries to guarantee low latency to ++ interactive and soft real-time applications. ++ + config DEFAULT_NOOP + bool "No-op" + +@@ -61,6 +92,7 @@ config DEFAULT_IOSCHED + string + default "deadline" if DEFAULT_DEADLINE + default "cfq" if DEFAULT_CFQ ++ default "bfq" if DEFAULT_BFQ + default "noop" if DEFAULT_NOOP + + endmenu +diff --git a/block/Makefile b/block/Makefile +index 00ecc97..1ed86d5 100644 +--- a/block/Makefile ++++ b/block/Makefile +@@ -18,6 +18,7 @@ obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o + obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o + obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o + obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o ++obj-$(CONFIG_IOSCHED_BFQ) += bfq-iosched.o + + obj-$(CONFIG_BLOCK_COMPAT) += compat_ioctl.o + obj-$(CONFIG_BLK_CMDLINE_PARSER) += cmdline-parser.o +diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h +index 98c4f9b..13b010d 100644 +--- a/include/linux/cgroup_subsys.h ++++ b/include/linux/cgroup_subsys.h +@@ -35,6 +35,10 @@ SUBSYS(net_cls) + SUBSYS(blkio) + #endif + ++#if IS_ENABLED(CONFIG_CGROUP_BFQIO) ++SUBSYS(bfqio) ++#endif ++ + #if IS_ENABLED(CONFIG_CGROUP_PERF) + SUBSYS(perf_event) + #endif +-- +2.3.0 + diff --git a/kernel/kernel/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch b/kernel/kernel/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch new file mode 100644 index 00000000..fb96ff28 --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch @@ -0,0 +1,6966 @@ +From 5bfaaa91a51940efaccb66bc5cd562ba3b9d4053 Mon Sep 17 00:00:00 2001 +From: Paolo Valente +Date: Thu, 9 May 2013 19:10:02 +0200 +Subject: [PATCH 2/3] block: introduce the BFQ-v7r7 I/O sched for 3.19 + +Add the BFQ-v7r7 I/O scheduler to 3.19. +The general structure is borrowed from CFQ, as much of the code for +handling I/O contexts. Over time, several useful features have been +ported from CFQ as well (details in the changelog in README.BFQ). A +(bfq_)queue is associated to each task doing I/O on a device, and each +time a scheduling decision has to be made a queue is selected and served +until it expires. + + - Slices are given in the service domain: tasks are assigned + budgets, measured in number of sectors. Once got the disk, a task + must however consume its assigned budget within a configurable + maximum time (by default, the maximum possible value of the + budgets is automatically computed to comply with this timeout). + This allows the desired latency vs "throughput boosting" tradeoff + to be set. + + - Budgets are scheduled according to a variant of WF2Q+, implemented + using an augmented rb-tree to take eligibility into account while + preserving an O(log N) overall complexity. + + - A low-latency tunable is provided; if enabled, both interactive + and soft real-time applications are guaranteed a very low latency. + + - Latency guarantees are preserved also in the presence of NCQ. + + - Also with flash-based devices, a high throughput is achieved + while still preserving latency guarantees. + + - BFQ features Early Queue Merge (EQM), a sort of fusion of the + cooperating-queue-merging and the preemption mechanisms present + in CFQ. EQM is in fact a unified mechanism that tries to get a + sequential read pattern, and hence a high throughput, with any + set of processes performing interleaved I/O over a contiguous + sequence of sectors. + + - BFQ supports full hierarchical scheduling, exporting a cgroups + interface. Since each node has a full scheduler, each group can + be assigned its own weight. + + - If the cgroups interface is not used, only I/O priorities can be + assigned to processes, with ioprio values mapped to weights + with the relation weight = IOPRIO_BE_NR - ioprio. + + - ioprio classes are served in strict priority order, i.e., lower + priority queues are not served as long as there are higher + priority queues. Among queues in the same class the bandwidth is + distributed in proportion to the weight of each queue. A very + thin extra bandwidth is however guaranteed to the Idle class, to + prevent it from starving. + +Signed-off-by: Paolo Valente +Signed-off-by: Arianna Avanzini +--- + block/bfq-cgroup.c | 936 ++++++++++++ + block/bfq-ioc.c | 36 + + block/bfq-iosched.c | 3902 +++++++++++++++++++++++++++++++++++++++++++++++++++ + block/bfq-sched.c | 1214 ++++++++++++++++ + block/bfq.h | 775 ++++++++++ + 5 files changed, 6863 insertions(+) + create mode 100644 block/bfq-cgroup.c + create mode 100644 block/bfq-ioc.c + create mode 100644 block/bfq-iosched.c + create mode 100644 block/bfq-sched.c + create mode 100644 block/bfq.h + +diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c +new file mode 100644 +index 0000000..11e2f1d +--- /dev/null ++++ b/block/bfq-cgroup.c +@@ -0,0 +1,936 @@ ++/* ++ * BFQ: CGROUPS support. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ */ ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ ++static DEFINE_MUTEX(bfqio_mutex); ++ ++static bool bfqio_is_removed(struct bfqio_cgroup *bgrp) ++{ ++ return bgrp ? !bgrp->online : false; ++} ++ ++static struct bfqio_cgroup bfqio_root_cgroup = { ++ .weight = BFQ_DEFAULT_GRP_WEIGHT, ++ .ioprio = BFQ_DEFAULT_GRP_IOPRIO, ++ .ioprio_class = BFQ_DEFAULT_GRP_CLASS, ++}; ++ ++static inline void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ entity->ioprio = entity->new_ioprio; ++ entity->ioprio_class = entity->new_ioprio_class; ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static struct bfqio_cgroup *css_to_bfqio(struct cgroup_subsys_state *css) ++{ ++ return css ? container_of(css, struct bfqio_cgroup, css) : NULL; ++} ++ ++/* ++ * Search the bfq_group for bfqd into the hash table (by now only a list) ++ * of bgrp. Must be called under rcu_read_lock(). ++ */ ++static struct bfq_group *bfqio_lookup_group(struct bfqio_cgroup *bgrp, ++ struct bfq_data *bfqd) ++{ ++ struct bfq_group *bfqg; ++ void *key; ++ ++ hlist_for_each_entry_rcu(bfqg, &bgrp->group_data, group_node) { ++ key = rcu_dereference(bfqg->bfqd); ++ if (key == bfqd) ++ return bfqg; ++ } ++ ++ return NULL; ++} ++ ++static inline void bfq_group_init_entity(struct bfqio_cgroup *bgrp, ++ struct bfq_group *bfqg) ++{ ++ struct bfq_entity *entity = &bfqg->entity; ++ ++ /* ++ * If the weight of the entity has never been set via the sysfs ++ * interface, then bgrp->weight == 0. In this case we initialize ++ * the weight from the current ioprio value. Otherwise, the group ++ * weight, if set, has priority over the ioprio value. ++ */ ++ if (bgrp->weight == 0) { ++ entity->new_weight = bfq_ioprio_to_weight(bgrp->ioprio); ++ entity->new_ioprio = bgrp->ioprio; ++ } else { ++ if (bgrp->weight < BFQ_MIN_WEIGHT || ++ bgrp->weight > BFQ_MAX_WEIGHT) { ++ printk(KERN_CRIT "bfq_group_init_entity: " ++ "bgrp->weight %d\n", bgrp->weight); ++ BUG(); ++ } ++ entity->new_weight = bgrp->weight; ++ entity->new_ioprio = bfq_weight_to_ioprio(bgrp->weight); ++ } ++ entity->orig_weight = entity->weight = entity->new_weight; ++ entity->ioprio = entity->new_ioprio; ++ entity->ioprio_class = entity->new_ioprio_class = bgrp->ioprio_class; ++ entity->my_sched_data = &bfqg->sched_data; ++ bfqg->active_entities = 0; ++} ++ ++static inline void bfq_group_set_parent(struct bfq_group *bfqg, ++ struct bfq_group *parent) ++{ ++ struct bfq_entity *entity; ++ ++ BUG_ON(parent == NULL); ++ BUG_ON(bfqg == NULL); ++ ++ entity = &bfqg->entity; ++ entity->parent = parent->my_entity; ++ entity->sched_data = &parent->sched_data; ++} ++ ++/** ++ * bfq_group_chain_alloc - allocate a chain of groups. ++ * @bfqd: queue descriptor. ++ * @css: the leaf cgroup_subsys_state this chain starts from. ++ * ++ * Allocate a chain of groups starting from the one belonging to ++ * @cgroup up to the root cgroup. Stop if a cgroup on the chain ++ * to the root has already an allocated group on @bfqd. ++ */ ++static struct bfq_group *bfq_group_chain_alloc(struct bfq_data *bfqd, ++ struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp; ++ struct bfq_group *bfqg, *prev = NULL, *leaf = NULL; ++ ++ for (; css != NULL; css = css->parent) { ++ bgrp = css_to_bfqio(css); ++ ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ if (bfqg != NULL) { ++ /* ++ * All the cgroups in the path from there to the ++ * root must have a bfq_group for bfqd, so we don't ++ * need any more allocations. ++ */ ++ break; ++ } ++ ++ bfqg = kzalloc(sizeof(*bfqg), GFP_ATOMIC); ++ if (bfqg == NULL) ++ goto cleanup; ++ ++ bfq_group_init_entity(bgrp, bfqg); ++ bfqg->my_entity = &bfqg->entity; ++ ++ if (leaf == NULL) { ++ leaf = bfqg; ++ prev = leaf; ++ } else { ++ bfq_group_set_parent(prev, bfqg); ++ /* ++ * Build a list of allocated nodes using the bfqd ++ * filed, that is still unused and will be ++ * initialized only after the node will be ++ * connected. ++ */ ++ prev->bfqd = bfqg; ++ prev = bfqg; ++ } ++ } ++ ++ return leaf; ++ ++cleanup: ++ while (leaf != NULL) { ++ prev = leaf; ++ leaf = leaf->bfqd; ++ kfree(prev); ++ } ++ ++ return NULL; ++} ++ ++/** ++ * bfq_group_chain_link - link an allocated group chain to a cgroup ++ * hierarchy. ++ * @bfqd: the queue descriptor. ++ * @css: the leaf cgroup_subsys_state to start from. ++ * @leaf: the leaf group (to be associated to @cgroup). ++ * ++ * Try to link a chain of groups to a cgroup hierarchy, connecting the ++ * nodes bottom-up, so we can be sure that when we find a cgroup in the ++ * hierarchy that already as a group associated to @bfqd all the nodes ++ * in the path to the root cgroup have one too. ++ * ++ * On locking: the queue lock protects the hierarchy (there is a hierarchy ++ * per device) while the bfqio_cgroup lock protects the list of groups ++ * belonging to the same cgroup. ++ */ ++static void bfq_group_chain_link(struct bfq_data *bfqd, ++ struct cgroup_subsys_state *css, ++ struct bfq_group *leaf) ++{ ++ struct bfqio_cgroup *bgrp; ++ struct bfq_group *bfqg, *next, *prev = NULL; ++ unsigned long flags; ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ ++ for (; css != NULL && leaf != NULL; css = css->parent) { ++ bgrp = css_to_bfqio(css); ++ next = leaf->bfqd; ++ ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ BUG_ON(bfqg != NULL); ++ ++ spin_lock_irqsave(&bgrp->lock, flags); ++ ++ rcu_assign_pointer(leaf->bfqd, bfqd); ++ hlist_add_head_rcu(&leaf->group_node, &bgrp->group_data); ++ hlist_add_head(&leaf->bfqd_node, &bfqd->group_list); ++ ++ spin_unlock_irqrestore(&bgrp->lock, flags); ++ ++ prev = leaf; ++ leaf = next; ++ } ++ ++ BUG_ON(css == NULL && leaf != NULL); ++ if (css != NULL && prev != NULL) { ++ bgrp = css_to_bfqio(css); ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ bfq_group_set_parent(prev, bfqg); ++ } ++} ++ ++/** ++ * bfq_find_alloc_group - return the group associated to @bfqd in @cgroup. ++ * @bfqd: queue descriptor. ++ * @cgroup: cgroup being searched for. ++ * ++ * Return a group associated to @bfqd in @cgroup, allocating one if ++ * necessary. When a group is returned all the cgroups in the path ++ * to the root have a group associated to @bfqd. ++ * ++ * If the allocation fails, return the root group: this breaks guarantees ++ * but is a safe fallback. If this loss becomes a problem it can be ++ * mitigated using the equivalent weight (given by the product of the ++ * weights of the groups in the path from @group to the root) in the ++ * root scheduler. ++ * ++ * We allocate all the missing nodes in the path from the leaf cgroup ++ * to the root and we connect the nodes only after all the allocations ++ * have been successful. ++ */ ++static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, ++ struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); ++ struct bfq_group *bfqg; ++ ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ if (bfqg != NULL) ++ return bfqg; ++ ++ bfqg = bfq_group_chain_alloc(bfqd, css); ++ if (bfqg != NULL) ++ bfq_group_chain_link(bfqd, css, bfqg); ++ else ++ bfqg = bfqd->root_group; ++ ++ return bfqg; ++} ++ ++/** ++ * bfq_bfqq_move - migrate @bfqq to @bfqg. ++ * @bfqd: queue descriptor. ++ * @bfqq: the queue to move. ++ * @entity: @bfqq's entity. ++ * @bfqg: the group to move to. ++ * ++ * Move @bfqq to @bfqg, deactivating it from its old group and reactivating ++ * it on the new one. Avoid putting the entity on the old group idle tree. ++ * ++ * Must be called under the queue lock; the cgroup owning @bfqg must ++ * not disappear (by now this just means that we are called under ++ * rcu_read_lock()). ++ */ ++static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct bfq_entity *entity, struct bfq_group *bfqg) ++{ ++ int busy, resume; ++ ++ busy = bfq_bfqq_busy(bfqq); ++ resume = !RB_EMPTY_ROOT(&bfqq->sort_list); ++ ++ BUG_ON(resume && !entity->on_st); ++ BUG_ON(busy && !resume && entity->on_st && ++ bfqq != bfqd->in_service_queue); ++ ++ if (busy) { ++ BUG_ON(atomic_read(&bfqq->ref) < 2); ++ ++ if (!resume) ++ bfq_del_bfqq_busy(bfqd, bfqq, 0); ++ else ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ } else if (entity->on_st) ++ bfq_put_idle_entity(bfq_entity_service_tree(entity), entity); ++ ++ /* ++ * Here we use a reference to bfqg. We don't need a refcounter ++ * as the cgroup reference will not be dropped, so that its ++ * destroy() callback will not be invoked. ++ */ ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++ ++ if (busy && resume) ++ bfq_activate_bfqq(bfqd, bfqq); ++ ++ if (bfqd->in_service_queue == NULL && !bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++} ++ ++/** ++ * __bfq_bic_change_cgroup - move @bic to @cgroup. ++ * @bfqd: the queue descriptor. ++ * @bic: the bic to move. ++ * @cgroup: the cgroup to move to. ++ * ++ * Move bic to cgroup, assuming that bfqd->queue is locked; the caller ++ * has to make sure that the reference to cgroup is valid across the call. ++ * ++ * NOTE: an alternative approach might have been to store the current ++ * cgroup in bfqq and getting a reference to it, reducing the lookup ++ * time here, at the price of slightly more complex code. ++ */ ++static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic, ++ struct cgroup_subsys_state *css) ++{ ++ struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); ++ struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); ++ struct bfq_entity *entity; ++ struct bfq_group *bfqg; ++ struct bfqio_cgroup *bgrp; ++ ++ bgrp = css_to_bfqio(css); ++ ++ bfqg = bfq_find_alloc_group(bfqd, css); ++ if (async_bfqq != NULL) { ++ entity = &async_bfqq->entity; ++ ++ if (entity->sched_data != &bfqg->sched_data) { ++ bic_set_bfqq(bic, NULL, 0); ++ bfq_log_bfqq(bfqd, async_bfqq, ++ "bic_change_group: %p %d", ++ async_bfqq, atomic_read(&async_bfqq->ref)); ++ bfq_put_queue(async_bfqq); ++ } ++ } ++ ++ if (sync_bfqq != NULL) { ++ entity = &sync_bfqq->entity; ++ if (entity->sched_data != &bfqg->sched_data) ++ bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg); ++ } ++ ++ return bfqg; ++} ++ ++/** ++ * bfq_bic_change_cgroup - move @bic to @cgroup. ++ * @bic: the bic being migrated. ++ * @cgroup: the destination cgroup. ++ * ++ * When the task owning @bic is moved to @cgroup, @bic is immediately ++ * moved into its new parent group. ++ */ ++static void bfq_bic_change_cgroup(struct bfq_io_cq *bic, ++ struct cgroup_subsys_state *css) ++{ ++ struct bfq_data *bfqd; ++ unsigned long uninitialized_var(flags); ++ ++ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), ++ &flags); ++ if (bfqd != NULL) { ++ __bfq_bic_change_cgroup(bfqd, bic, css); ++ bfq_put_bfqd_unlock(bfqd, &flags); ++ } ++} ++ ++/** ++ * bfq_bic_update_cgroup - update the cgroup of @bic. ++ * @bic: the @bic to update. ++ * ++ * Make sure that @bic is enqueued in the cgroup of the current task. ++ * We need this in addition to moving bics during the cgroup attach ++ * phase because the task owning @bic could be at its first disk ++ * access or we may end up in the root cgroup as the result of a ++ * memory allocation failure and here we try to move to the right ++ * group. ++ * ++ * Must be called under the queue lock. It is safe to use the returned ++ * value even after the rcu_read_unlock() as the migration/destruction ++ * paths act under the queue lock too. IOW it is impossible to race with ++ * group migration/destruction and end up with an invalid group as: ++ * a) here cgroup has not yet been destroyed, nor its destroy callback ++ * has started execution, as current holds a reference to it, ++ * b) if it is destroyed after rcu_read_unlock() [after current is ++ * migrated to a different cgroup] its attach() callback will have ++ * taken care of remove all the references to the old cgroup data. ++ */ ++static struct bfq_group *bfq_bic_update_cgroup(struct bfq_io_cq *bic) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ struct bfq_group *bfqg; ++ struct cgroup_subsys_state *css; ++ ++ BUG_ON(bfqd == NULL); ++ ++ rcu_read_lock(); ++ css = task_css(current, bfqio_cgrp_id); ++ bfqg = __bfq_bic_change_cgroup(bfqd, bic, css); ++ rcu_read_unlock(); ++ ++ return bfqg; ++} ++ ++/** ++ * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st. ++ * @st: the service tree being flushed. ++ */ ++static inline void bfq_flush_idle_tree(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entity = st->first_idle; ++ ++ for (; entity != NULL; entity = st->first_idle) ++ __bfq_deactivate_entity(entity, 0); ++} ++ ++/** ++ * bfq_reparent_leaf_entity - move leaf entity to the root_group. ++ * @bfqd: the device data structure with the root group. ++ * @entity: the entity to move. ++ */ ++static inline void bfq_reparent_leaf_entity(struct bfq_data *bfqd, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ BUG_ON(bfqq == NULL); ++ bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group); ++ return; ++} ++ ++/** ++ * bfq_reparent_active_entities - move to the root group all active ++ * entities. ++ * @bfqd: the device data structure with the root group. ++ * @bfqg: the group to move from. ++ * @st: the service tree with the entities. ++ * ++ * Needs queue_lock to be taken and reference to be valid over the call. ++ */ ++static inline void bfq_reparent_active_entities(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ struct bfq_service_tree *st) ++{ ++ struct rb_root *active = &st->active; ++ struct bfq_entity *entity = NULL; ++ ++ if (!RB_EMPTY_ROOT(&st->active)) ++ entity = bfq_entity_of(rb_first(active)); ++ ++ for (; entity != NULL; entity = bfq_entity_of(rb_first(active))) ++ bfq_reparent_leaf_entity(bfqd, entity); ++ ++ if (bfqg->sched_data.in_service_entity != NULL) ++ bfq_reparent_leaf_entity(bfqd, ++ bfqg->sched_data.in_service_entity); ++ ++ return; ++} ++ ++/** ++ * bfq_destroy_group - destroy @bfqg. ++ * @bgrp: the bfqio_cgroup containing @bfqg. ++ * @bfqg: the group being destroyed. ++ * ++ * Destroy @bfqg, making sure that it is not referenced from its parent. ++ */ ++static void bfq_destroy_group(struct bfqio_cgroup *bgrp, struct bfq_group *bfqg) ++{ ++ struct bfq_data *bfqd; ++ struct bfq_service_tree *st; ++ struct bfq_entity *entity = bfqg->my_entity; ++ unsigned long uninitialized_var(flags); ++ int i; ++ ++ hlist_del(&bfqg->group_node); ++ ++ /* ++ * Empty all service_trees belonging to this group before ++ * deactivating the group itself. ++ */ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) { ++ st = bfqg->sched_data.service_tree + i; ++ ++ /* ++ * The idle tree may still contain bfq_queues belonging ++ * to exited task because they never migrated to a different ++ * cgroup from the one being destroyed now. No one else ++ * can access them so it's safe to act without any lock. ++ */ ++ bfq_flush_idle_tree(st); ++ ++ /* ++ * It may happen that some queues are still active ++ * (busy) upon group destruction (if the corresponding ++ * processes have been forced to terminate). We move ++ * all the leaf entities corresponding to these queues ++ * to the root_group. ++ * Also, it may happen that the group has an entity ++ * in service, which is disconnected from the active ++ * tree: it must be moved, too. ++ * There is no need to put the sync queues, as the ++ * scheduler has taken no reference. ++ */ ++ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); ++ if (bfqd != NULL) { ++ bfq_reparent_active_entities(bfqd, bfqg, st); ++ bfq_put_bfqd_unlock(bfqd, &flags); ++ } ++ BUG_ON(!RB_EMPTY_ROOT(&st->active)); ++ BUG_ON(!RB_EMPTY_ROOT(&st->idle)); ++ } ++ BUG_ON(bfqg->sched_data.next_in_service != NULL); ++ BUG_ON(bfqg->sched_data.in_service_entity != NULL); ++ ++ /* ++ * We may race with device destruction, take extra care when ++ * dereferencing bfqg->bfqd. ++ */ ++ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); ++ if (bfqd != NULL) { ++ hlist_del(&bfqg->bfqd_node); ++ __bfq_deactivate_entity(entity, 0); ++ bfq_put_async_queues(bfqd, bfqg); ++ bfq_put_bfqd_unlock(bfqd, &flags); ++ } ++ BUG_ON(entity->tree != NULL); ++ ++ /* ++ * No need to defer the kfree() to the end of the RCU grace ++ * period: we are called from the destroy() callback of our ++ * cgroup, so we can be sure that no one is a) still using ++ * this cgroup or b) doing lookups in it. ++ */ ++ kfree(bfqg); ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ struct hlist_node *tmp; ++ struct bfq_group *bfqg; ++ ++ hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) ++ bfq_end_wr_async_queues(bfqd, bfqg); ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++/** ++ * bfq_disconnect_groups - disconnect @bfqd from all its groups. ++ * @bfqd: the device descriptor being exited. ++ * ++ * When the device exits we just make sure that no lookup can return ++ * the now unused group structures. They will be deallocated on cgroup ++ * destruction. ++ */ ++static void bfq_disconnect_groups(struct bfq_data *bfqd) ++{ ++ struct hlist_node *tmp; ++ struct bfq_group *bfqg; ++ ++ bfq_log(bfqd, "disconnect_groups beginning"); ++ hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) { ++ hlist_del(&bfqg->bfqd_node); ++ ++ __bfq_deactivate_entity(bfqg->my_entity, 0); ++ ++ /* ++ * Don't remove from the group hash, just set an ++ * invalid key. No lookups can race with the ++ * assignment as bfqd is being destroyed; this ++ * implies also that new elements cannot be added ++ * to the list. ++ */ ++ rcu_assign_pointer(bfqg->bfqd, NULL); ++ ++ bfq_log(bfqd, "disconnect_groups: put async for group %p", ++ bfqg); ++ bfq_put_async_queues(bfqd, bfqg); ++ } ++} ++ ++static inline void bfq_free_root_group(struct bfq_data *bfqd) ++{ ++ struct bfqio_cgroup *bgrp = &bfqio_root_cgroup; ++ struct bfq_group *bfqg = bfqd->root_group; ++ ++ bfq_put_async_queues(bfqd, bfqg); ++ ++ spin_lock_irq(&bgrp->lock); ++ hlist_del_rcu(&bfqg->group_node); ++ spin_unlock_irq(&bgrp->lock); ++ ++ /* ++ * No need to synchronize_rcu() here: since the device is gone ++ * there cannot be any read-side access to its root_group. ++ */ ++ kfree(bfqg); ++} ++ ++static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) ++{ ++ struct bfq_group *bfqg; ++ struct bfqio_cgroup *bgrp; ++ int i; ++ ++ bfqg = kzalloc_node(sizeof(*bfqg), GFP_KERNEL, node); ++ if (bfqg == NULL) ++ return NULL; ++ ++ bfqg->entity.parent = NULL; ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++ ++ bgrp = &bfqio_root_cgroup; ++ spin_lock_irq(&bgrp->lock); ++ rcu_assign_pointer(bfqg->bfqd, bfqd); ++ hlist_add_head_rcu(&bfqg->group_node, &bgrp->group_data); ++ spin_unlock_irq(&bgrp->lock); ++ ++ return bfqg; ++} ++ ++#define SHOW_FUNCTION(__VAR) \ ++static u64 bfqio_cgroup_##__VAR##_read(struct cgroup_subsys_state *css, \ ++ struct cftype *cftype) \ ++{ \ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); \ ++ u64 ret = -ENODEV; \ ++ \ ++ mutex_lock(&bfqio_mutex); \ ++ if (bfqio_is_removed(bgrp)) \ ++ goto out_unlock; \ ++ \ ++ spin_lock_irq(&bgrp->lock); \ ++ ret = bgrp->__VAR; \ ++ spin_unlock_irq(&bgrp->lock); \ ++ \ ++out_unlock: \ ++ mutex_unlock(&bfqio_mutex); \ ++ return ret; \ ++} ++ ++SHOW_FUNCTION(weight); ++SHOW_FUNCTION(ioprio); ++SHOW_FUNCTION(ioprio_class); ++#undef SHOW_FUNCTION ++ ++#define STORE_FUNCTION(__VAR, __MIN, __MAX) \ ++static int bfqio_cgroup_##__VAR##_write(struct cgroup_subsys_state *css,\ ++ struct cftype *cftype, \ ++ u64 val) \ ++{ \ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); \ ++ struct bfq_group *bfqg; \ ++ int ret = -EINVAL; \ ++ \ ++ if (val < (__MIN) || val > (__MAX)) \ ++ return ret; \ ++ \ ++ ret = -ENODEV; \ ++ mutex_lock(&bfqio_mutex); \ ++ if (bfqio_is_removed(bgrp)) \ ++ goto out_unlock; \ ++ ret = 0; \ ++ \ ++ spin_lock_irq(&bgrp->lock); \ ++ bgrp->__VAR = (unsigned short)val; \ ++ hlist_for_each_entry(bfqg, &bgrp->group_data, group_node) { \ ++ /* \ ++ * Setting the ioprio_changed flag of the entity \ ++ * to 1 with new_##__VAR == ##__VAR would re-set \ ++ * the value of the weight to its ioprio mapping. \ ++ * Set the flag only if necessary. \ ++ */ \ ++ if ((unsigned short)val != bfqg->entity.new_##__VAR) { \ ++ bfqg->entity.new_##__VAR = (unsigned short)val; \ ++ /* \ ++ * Make sure that the above new value has been \ ++ * stored in bfqg->entity.new_##__VAR before \ ++ * setting the ioprio_changed flag. In fact, \ ++ * this flag may be read asynchronously (in \ ++ * critical sections protected by a different \ ++ * lock than that held here), and finding this \ ++ * flag set may cause the execution of the code \ ++ * for updating parameters whose value may \ ++ * depend also on bfqg->entity.new_##__VAR (in \ ++ * __bfq_entity_update_weight_prio). \ ++ * This barrier makes sure that the new value \ ++ * of bfqg->entity.new_##__VAR is correctly \ ++ * seen in that code. \ ++ */ \ ++ smp_wmb(); \ ++ bfqg->entity.ioprio_changed = 1; \ ++ } \ ++ } \ ++ spin_unlock_irq(&bgrp->lock); \ ++ \ ++out_unlock: \ ++ mutex_unlock(&bfqio_mutex); \ ++ return ret; \ ++} ++ ++STORE_FUNCTION(weight, BFQ_MIN_WEIGHT, BFQ_MAX_WEIGHT); ++STORE_FUNCTION(ioprio, 0, IOPRIO_BE_NR - 1); ++STORE_FUNCTION(ioprio_class, IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE); ++#undef STORE_FUNCTION ++ ++static struct cftype bfqio_files[] = { ++ { ++ .name = "weight", ++ .read_u64 = bfqio_cgroup_weight_read, ++ .write_u64 = bfqio_cgroup_weight_write, ++ }, ++ { ++ .name = "ioprio", ++ .read_u64 = bfqio_cgroup_ioprio_read, ++ .write_u64 = bfqio_cgroup_ioprio_write, ++ }, ++ { ++ .name = "ioprio_class", ++ .read_u64 = bfqio_cgroup_ioprio_class_read, ++ .write_u64 = bfqio_cgroup_ioprio_class_write, ++ }, ++ { }, /* terminate */ ++}; ++ ++static struct cgroup_subsys_state *bfqio_create(struct cgroup_subsys_state ++ *parent_css) ++{ ++ struct bfqio_cgroup *bgrp; ++ ++ if (parent_css != NULL) { ++ bgrp = kzalloc(sizeof(*bgrp), GFP_KERNEL); ++ if (bgrp == NULL) ++ return ERR_PTR(-ENOMEM); ++ } else ++ bgrp = &bfqio_root_cgroup; ++ ++ spin_lock_init(&bgrp->lock); ++ INIT_HLIST_HEAD(&bgrp->group_data); ++ bgrp->ioprio = BFQ_DEFAULT_GRP_IOPRIO; ++ bgrp->ioprio_class = BFQ_DEFAULT_GRP_CLASS; ++ ++ return &bgrp->css; ++} ++ ++/* ++ * We cannot support shared io contexts, as we have no means to support ++ * two tasks with the same ioc in two different groups without major rework ++ * of the main bic/bfqq data structures. By now we allow a task to change ++ * its cgroup only if it's the only owner of its ioc; the drawback of this ++ * behavior is that a group containing a task that forked using CLONE_IO ++ * will not be destroyed until the tasks sharing the ioc die. ++ */ ++static int bfqio_can_attach(struct cgroup_subsys_state *css, ++ struct cgroup_taskset *tset) ++{ ++ struct task_struct *task; ++ struct io_context *ioc; ++ int ret = 0; ++ ++ cgroup_taskset_for_each(task, tset) { ++ /* ++ * task_lock() is needed to avoid races with ++ * exit_io_context() ++ */ ++ task_lock(task); ++ ioc = task->io_context; ++ if (ioc != NULL && atomic_read(&ioc->nr_tasks) > 1) ++ /* ++ * ioc == NULL means that the task is either too ++ * young or exiting: if it has still no ioc the ++ * ioc can't be shared, if the task is exiting the ++ * attach will fail anyway, no matter what we ++ * return here. ++ */ ++ ret = -EINVAL; ++ task_unlock(task); ++ if (ret) ++ break; ++ } ++ ++ return ret; ++} ++ ++static void bfqio_attach(struct cgroup_subsys_state *css, ++ struct cgroup_taskset *tset) ++{ ++ struct task_struct *task; ++ struct io_context *ioc; ++ struct io_cq *icq; ++ ++ /* ++ * IMPORTANT NOTE: The move of more than one process at a time to a ++ * new group has not yet been tested. ++ */ ++ cgroup_taskset_for_each(task, tset) { ++ ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE); ++ if (ioc) { ++ /* ++ * Handle cgroup change here. ++ */ ++ rcu_read_lock(); ++ hlist_for_each_entry_rcu(icq, &ioc->icq_list, ioc_node) ++ if (!strncmp( ++ icq->q->elevator->type->elevator_name, ++ "bfq", ELV_NAME_MAX)) ++ bfq_bic_change_cgroup(icq_to_bic(icq), ++ css); ++ rcu_read_unlock(); ++ put_io_context(ioc); ++ } ++ } ++} ++ ++static void bfqio_destroy(struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); ++ struct hlist_node *tmp; ++ struct bfq_group *bfqg; ++ ++ /* ++ * Since we are destroying the cgroup, there are no more tasks ++ * referencing it, and all the RCU grace periods that may have ++ * referenced it are ended (as the destruction of the parent ++ * cgroup is RCU-safe); bgrp->group_data will not be accessed by ++ * anything else and we don't need any synchronization. ++ */ ++ hlist_for_each_entry_safe(bfqg, tmp, &bgrp->group_data, group_node) ++ bfq_destroy_group(bgrp, bfqg); ++ ++ BUG_ON(!hlist_empty(&bgrp->group_data)); ++ ++ kfree(bgrp); ++} ++ ++static int bfqio_css_online(struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); ++ ++ mutex_lock(&bfqio_mutex); ++ bgrp->online = true; ++ mutex_unlock(&bfqio_mutex); ++ ++ return 0; ++} ++ ++static void bfqio_css_offline(struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); ++ ++ mutex_lock(&bfqio_mutex); ++ bgrp->online = false; ++ mutex_unlock(&bfqio_mutex); ++} ++ ++struct cgroup_subsys bfqio_cgrp_subsys = { ++ .css_alloc = bfqio_create, ++ .css_online = bfqio_css_online, ++ .css_offline = bfqio_css_offline, ++ .can_attach = bfqio_can_attach, ++ .attach = bfqio_attach, ++ .css_free = bfqio_destroy, ++ .legacy_cftypes = bfqio_files, ++}; ++#else ++static inline void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ entity->ioprio = entity->new_ioprio; ++ entity->ioprio_class = entity->new_ioprio_class; ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static inline struct bfq_group * ++bfq_bic_update_cgroup(struct bfq_io_cq *bic) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ return bfqd->root_group; ++} ++ ++static inline void bfq_bfqq_move(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++static inline void bfq_disconnect_groups(struct bfq_data *bfqd) ++{ ++ bfq_put_async_queues(bfqd, bfqd->root_group); ++} ++ ++static inline void bfq_free_root_group(struct bfq_data *bfqd) ++{ ++ kfree(bfqd->root_group); ++} ++ ++static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) ++{ ++ struct bfq_group *bfqg; ++ int i; ++ ++ bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node); ++ if (bfqg == NULL) ++ return NULL; ++ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++ ++ return bfqg; ++} ++#endif +diff --git a/block/bfq-ioc.c b/block/bfq-ioc.c +new file mode 100644 +index 0000000..7f6b000 +--- /dev/null ++++ b/block/bfq-ioc.c +@@ -0,0 +1,36 @@ ++/* ++ * BFQ: I/O context handling. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++/** ++ * icq_to_bic - convert iocontext queue structure to bfq_io_cq. ++ * @icq: the iocontext queue. ++ */ ++static inline struct bfq_io_cq *icq_to_bic(struct io_cq *icq) ++{ ++ /* bic->icq is the first member, %NULL will convert to %NULL */ ++ return container_of(icq, struct bfq_io_cq, icq); ++} ++ ++/** ++ * bfq_bic_lookup - search into @ioc a bic associated to @bfqd. ++ * @bfqd: the lookup key. ++ * @ioc: the io_context of the process doing I/O. ++ * ++ * Queue lock must be held. ++ */ ++static inline struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd, ++ struct io_context *ioc) ++{ ++ if (ioc) ++ return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue)); ++ return NULL; ++} +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +new file mode 100644 +index 0000000..97ee934 +--- /dev/null ++++ b/block/bfq-iosched.c +@@ -0,0 +1,3902 @@ ++/* ++ * Budget Fair Queueing (BFQ) disk scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ * ++ * BFQ is a proportional-share storage-I/O scheduling algorithm based on ++ * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets, ++ * measured in number of sectors, to processes instead of time slices. The ++ * device is not granted to the in-service process for a given time slice, ++ * but until it has exhausted its assigned budget. This change from the time ++ * to the service domain allows BFQ to distribute the device throughput ++ * among processes as desired, without any distortion due to ZBR, workload ++ * fluctuations or other factors. BFQ uses an ad hoc internal scheduler, ++ * called B-WF2Q+, to schedule processes according to their budgets. More ++ * precisely, BFQ schedules queues associated to processes. Thanks to the ++ * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to ++ * I/O-bound processes issuing sequential requests (to boost the ++ * throughput), and yet guarantee a low latency to interactive and soft ++ * real-time applications. ++ * ++ * BFQ is described in [1], where also a reference to the initial, more ++ * theoretical paper on BFQ can be found. The interested reader can find ++ * in the latter paper full details on the main algorithm, as well as ++ * formulas of the guarantees and formal proofs of all the properties. ++ * With respect to the version of BFQ presented in these papers, this ++ * implementation adds a few more heuristics, such as the one that ++ * guarantees a low latency to soft real-time applications, and a ++ * hierarchical extension based on H-WF2Q+. ++ * ++ * B-WF2Q+ is based on WF2Q+, that is described in [2], together with ++ * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N) ++ * complexity derives from the one introduced with EEVDF in [3]. ++ * ++ * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness ++ * with the BFQ Disk I/O Scheduler'', ++ * Proceedings of the 5th Annual International Systems and Storage ++ * Conference (SYSTOR '12), June 2012. ++ * ++ * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf ++ * ++ * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing ++ * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689, ++ * Oct 1997. ++ * ++ * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz ++ * ++ * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline ++ * First: A Flexible and Accurate Mechanism for Proportional Share ++ * Resource Allocation,'' technical report. ++ * ++ * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bfq.h" ++#include "blk.h" ++ ++/* Max number of dispatches in one round of service. */ ++static const int bfq_quantum = 4; ++ ++/* Expiration time of sync (0) and async (1) requests, in jiffies. */ ++static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 }; ++ ++/* Maximum backwards seek, in KiB. */ ++static const int bfq_back_max = 16 * 1024; ++ ++/* Penalty of a backwards seek, in number of sectors. */ ++static const int bfq_back_penalty = 2; ++ ++/* Idling period duration, in jiffies. */ ++static int bfq_slice_idle = HZ / 125; ++ ++/* Default maximum budget values, in sectors and number of requests. */ ++static const int bfq_default_max_budget = 16 * 1024; ++static const int bfq_max_budget_async_rq = 4; ++ ++/* ++ * Async to sync throughput distribution is controlled as follows: ++ * when an async request is served, the entity is charged the number ++ * of sectors of the request, multiplied by the factor below ++ */ ++static const int bfq_async_charge_factor = 10; ++ ++/* Default timeout values, in jiffies, approximating CFQ defaults. */ ++static const int bfq_timeout_sync = HZ / 8; ++static int bfq_timeout_async = HZ / 25; ++ ++struct kmem_cache *bfq_pool; ++ ++/* Below this threshold (in ms), we consider thinktime immediate. */ ++#define BFQ_MIN_TT 2 ++ ++/* hw_tag detection: parallel requests threshold and min samples needed. */ ++#define BFQ_HW_QUEUE_THRESHOLD 4 ++#define BFQ_HW_QUEUE_SAMPLES 32 ++ ++#define BFQQ_SEEK_THR (sector_t)(8 * 1024) ++#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR) ++ ++/* Min samples used for peak rate estimation (for autotuning). */ ++#define BFQ_PEAK_RATE_SAMPLES 32 ++ ++/* Shift used for peak rate fixed precision calculations. */ ++#define BFQ_RATE_SHIFT 16 ++ ++/* ++ * By default, BFQ computes the duration of the weight raising for ++ * interactive applications automatically, using the following formula: ++ * duration = (R / r) * T, where r is the peak rate of the device, and ++ * R and T are two reference parameters. ++ * In particular, R is the peak rate of the reference device (see below), ++ * and T is a reference time: given the systems that are likely to be ++ * installed on the reference device according to its speed class, T is ++ * about the maximum time needed, under BFQ and while reading two files in ++ * parallel, to load typical large applications on these systems. ++ * In practice, the slower/faster the device at hand is, the more/less it ++ * takes to load applications with respect to the reference device. ++ * Accordingly, the longer/shorter BFQ grants weight raising to interactive ++ * applications. ++ * ++ * BFQ uses four different reference pairs (R, T), depending on: ++ * . whether the device is rotational or non-rotational; ++ * . whether the device is slow, such as old or portable HDDs, as well as ++ * SD cards, or fast, such as newer HDDs and SSDs. ++ * ++ * The device's speed class is dynamically (re)detected in ++ * bfq_update_peak_rate() every time the estimated peak rate is updated. ++ * ++ * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0] ++ * are the reference values for a slow/fast rotational device, whereas ++ * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for ++ * a slow/fast non-rotational device. Finally, device_speed_thresh are the ++ * thresholds used to switch between speed classes. ++ * Both the reference peak rates and the thresholds are measured in ++ * sectors/usec, left-shifted by BFQ_RATE_SHIFT. ++ */ ++static int R_slow[2] = {1536, 10752}; ++static int R_fast[2] = {17415, 34791}; ++/* ++ * To improve readability, a conversion function is used to initialize the ++ * following arrays, which entails that they can be initialized only in a ++ * function. ++ */ ++static int T_slow[2]; ++static int T_fast[2]; ++static int device_speed_thresh[2]; ++ ++#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \ ++ { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 }) ++ ++#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0]) ++#define RQ_BFQQ(rq) ((rq)->elv.priv[1]) ++ ++static inline void bfq_schedule_dispatch(struct bfq_data *bfqd); ++ ++#include "bfq-ioc.c" ++#include "bfq-sched.c" ++#include "bfq-cgroup.c" ++ ++#define bfq_class_idle(bfqq) ((bfqq)->entity.ioprio_class ==\ ++ IOPRIO_CLASS_IDLE) ++#define bfq_class_rt(bfqq) ((bfqq)->entity.ioprio_class ==\ ++ IOPRIO_CLASS_RT) ++ ++#define bfq_sample_valid(samples) ((samples) > 80) ++ ++/* ++ * We regard a request as SYNC, if either it's a read or has the SYNC bit ++ * set (in which case it could also be a direct WRITE). ++ */ ++static inline int bfq_bio_sync(struct bio *bio) ++{ ++ if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC)) ++ return 1; ++ ++ return 0; ++} ++ ++/* ++ * Scheduler run of queue, if there are requests pending and no one in the ++ * driver that will restart queueing. ++ */ ++static inline void bfq_schedule_dispatch(struct bfq_data *bfqd) ++{ ++ if (bfqd->queued != 0) { ++ bfq_log(bfqd, "schedule dispatch"); ++ kblockd_schedule_work(&bfqd->unplug_work); ++ } ++} ++ ++/* ++ * Lifted from AS - choose which of rq1 and rq2 that is best served now. ++ * We choose the request that is closesr to the head right now. Distance ++ * behind the head is penalized and only allowed to a certain extent. ++ */ ++static struct request *bfq_choose_req(struct bfq_data *bfqd, ++ struct request *rq1, ++ struct request *rq2, ++ sector_t last) ++{ ++ sector_t s1, s2, d1 = 0, d2 = 0; ++ unsigned long back_max; ++#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */ ++#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */ ++ unsigned wrap = 0; /* bit mask: requests behind the disk head? */ ++ ++ if (rq1 == NULL || rq1 == rq2) ++ return rq2; ++ if (rq2 == NULL) ++ return rq1; ++ ++ if (rq_is_sync(rq1) && !rq_is_sync(rq2)) ++ return rq1; ++ else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) ++ return rq2; ++ if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META)) ++ return rq1; ++ else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META)) ++ return rq2; ++ ++ s1 = blk_rq_pos(rq1); ++ s2 = blk_rq_pos(rq2); ++ ++ /* ++ * By definition, 1KiB is 2 sectors. ++ */ ++ back_max = bfqd->bfq_back_max * 2; ++ ++ /* ++ * Strict one way elevator _except_ in the case where we allow ++ * short backward seeks which are biased as twice the cost of a ++ * similar forward seek. ++ */ ++ if (s1 >= last) ++ d1 = s1 - last; ++ else if (s1 + back_max >= last) ++ d1 = (last - s1) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ1_WRAP; ++ ++ if (s2 >= last) ++ d2 = s2 - last; ++ else if (s2 + back_max >= last) ++ d2 = (last - s2) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ2_WRAP; ++ ++ /* Found required data */ ++ ++ /* ++ * By doing switch() on the bit mask "wrap" we avoid having to ++ * check two variables for all permutations: --> faster! ++ */ ++ switch (wrap) { ++ case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ ++ if (d1 < d2) ++ return rq1; ++ else if (d2 < d1) ++ return rq2; ++ else { ++ if (s1 >= s2) ++ return rq1; ++ else ++ return rq2; ++ } ++ ++ case BFQ_RQ2_WRAP: ++ return rq1; ++ case BFQ_RQ1_WRAP: ++ return rq2; ++ case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */ ++ default: ++ /* ++ * Since both rqs are wrapped, ++ * start with the one that's further behind head ++ * (--> only *one* back seek required), ++ * since back seek takes more time than forward. ++ */ ++ if (s1 <= s2) ++ return rq1; ++ else ++ return rq2; ++ } ++} ++ ++static struct bfq_queue * ++bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root, ++ sector_t sector, struct rb_node **ret_parent, ++ struct rb_node ***rb_link) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *bfqq = NULL; ++ ++ parent = NULL; ++ p = &root->rb_node; ++ while (*p) { ++ struct rb_node **n; ++ ++ parent = *p; ++ bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ ++ /* ++ * Sort strictly based on sector. Smallest to the left, ++ * largest to the right. ++ */ ++ if (sector > blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_right; ++ else if (sector < blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_left; ++ else ++ break; ++ p = n; ++ bfqq = NULL; ++ } ++ ++ *ret_parent = parent; ++ if (rb_link) ++ *rb_link = p; ++ ++ bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d", ++ (long long unsigned)sector, ++ bfqq != NULL ? bfqq->pid : 0); ++ ++ return bfqq; ++} ++ ++static void bfq_rq_pos_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *__bfqq; ++ ++ if (bfqq->pos_root != NULL) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ ++ if (bfq_class_idle(bfqq)) ++ return; ++ if (!bfqq->next_rq) ++ return; ++ ++ bfqq->pos_root = &bfqd->rq_pos_tree; ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root, ++ blk_rq_pos(bfqq->next_rq), &parent, &p); ++ if (__bfqq == NULL) { ++ rb_link_node(&bfqq->pos_node, parent, p); ++ rb_insert_color(&bfqq->pos_node, bfqq->pos_root); ++ } else ++ bfqq->pos_root = NULL; ++} ++ ++/* ++ * Tell whether there are active queues or groups with differentiated weights. ++ */ ++static inline bool bfq_differentiated_weights(struct bfq_data *bfqd) ++{ ++ BUG_ON(!bfqd->hw_tag); ++ /* ++ * For weights to differ, at least one of the trees must contain ++ * at least two nodes. ++ */ ++ return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) && ++ (bfqd->queue_weights_tree.rb_node->rb_left || ++ bfqd->queue_weights_tree.rb_node->rb_right) ++#ifdef CONFIG_CGROUP_BFQIO ++ ) || ++ (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) && ++ (bfqd->group_weights_tree.rb_node->rb_left || ++ bfqd->group_weights_tree.rb_node->rb_right) ++#endif ++ ); ++} ++ ++/* ++ * If the weight-counter tree passed as input contains no counter for ++ * the weight of the input entity, then add that counter; otherwise just ++ * increment the existing counter. ++ * ++ * Note that weight-counter trees contain few nodes in mostly symmetric ++ * scenarios. For example, if all queues have the same weight, then the ++ * weight-counter tree for the queues may contain at most one node. ++ * This holds even if low_latency is on, because weight-raised queues ++ * are not inserted in the tree. ++ * In most scenarios, the rate at which nodes are created/destroyed ++ * should be low too. ++ */ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ struct rb_node **new = &(root->rb_node), *parent = NULL; ++ ++ /* ++ * Do not insert if: ++ * - the device does not support queueing; ++ * - the entity is already associated with a counter, which happens if: ++ * 1) the entity is associated with a queue, 2) a request arrival ++ * has caused the queue to become both non-weight-raised, and hence ++ * change its weight, and backlogged; in this respect, each ++ * of the two events causes an invocation of this function, ++ * 3) this is the invocation of this function caused by the second ++ * event. This second invocation is actually useless, and we handle ++ * this fact by exiting immediately. More efficient or clearer ++ * solutions might possibly be adopted. ++ */ ++ if (!bfqd->hw_tag || entity->weight_counter) ++ return; ++ ++ while (*new) { ++ struct bfq_weight_counter *__counter = container_of(*new, ++ struct bfq_weight_counter, ++ weights_node); ++ parent = *new; ++ ++ if (entity->weight == __counter->weight) { ++ entity->weight_counter = __counter; ++ goto inc_counter; ++ } ++ if (entity->weight < __counter->weight) ++ new = &((*new)->rb_left); ++ else ++ new = &((*new)->rb_right); ++ } ++ ++ entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter), ++ GFP_ATOMIC); ++ entity->weight_counter->weight = entity->weight; ++ rb_link_node(&entity->weight_counter->weights_node, parent, new); ++ rb_insert_color(&entity->weight_counter->weights_node, root); ++ ++inc_counter: ++ entity->weight_counter->num_active++; ++} ++ ++/* ++ * Decrement the weight counter associated with the entity, and, if the ++ * counter reaches 0, remove the counter from the tree. ++ * See the comments to the function bfq_weights_tree_add() for considerations ++ * about overhead. ++ */ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ /* ++ * Check whether the entity is actually associated with a counter. ++ * In fact, the device may not be considered NCQ-capable for a while, ++ * which implies that no insertion in the weight trees is performed, ++ * after which the device may start to be deemed NCQ-capable, and hence ++ * this function may start to be invoked. This may cause the function ++ * to be invoked for entities that are not associated with any counter. ++ */ ++ if (!entity->weight_counter) ++ return; ++ ++ BUG_ON(RB_EMPTY_ROOT(root)); ++ BUG_ON(entity->weight_counter->weight != entity->weight); ++ ++ BUG_ON(!entity->weight_counter->num_active); ++ entity->weight_counter->num_active--; ++ if (entity->weight_counter->num_active > 0) ++ goto reset_entity_pointer; ++ ++ rb_erase(&entity->weight_counter->weights_node, root); ++ kfree(entity->weight_counter); ++ ++reset_entity_pointer: ++ entity->weight_counter = NULL; ++} ++ ++static struct request *bfq_find_next_rq(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct request *last) ++{ ++ struct rb_node *rbnext = rb_next(&last->rb_node); ++ struct rb_node *rbprev = rb_prev(&last->rb_node); ++ struct request *next = NULL, *prev = NULL; ++ ++ BUG_ON(RB_EMPTY_NODE(&last->rb_node)); ++ ++ if (rbprev != NULL) ++ prev = rb_entry_rq(rbprev); ++ ++ if (rbnext != NULL) ++ next = rb_entry_rq(rbnext); ++ else { ++ rbnext = rb_first(&bfqq->sort_list); ++ if (rbnext && rbnext != &last->rb_node) ++ next = rb_entry_rq(rbnext); ++ } ++ ++ return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last)); ++} ++ ++/* see the definition of bfq_async_charge_factor for details */ ++static inline unsigned long bfq_serv_to_charge(struct request *rq, ++ struct bfq_queue *bfqq) ++{ ++ return blk_rq_sectors(rq) * ++ (1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) * ++ bfq_async_charge_factor)); ++} ++ ++/** ++ * bfq_updated_next_req - update the queue after a new next_rq selection. ++ * @bfqd: the device data the queue belongs to. ++ * @bfqq: the queue to update. ++ * ++ * If the first request of a queue changes we make sure that the queue ++ * has enough budget to serve at least its first request (if the ++ * request has grown). We do this because if the queue has not enough ++ * budget for its first request, it has to go through two dispatch ++ * rounds to actually get it dispatched. ++ */ ++static void bfq_updated_next_req(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ struct request *next_rq = bfqq->next_rq; ++ unsigned long new_budget; ++ ++ if (next_rq == NULL) ++ return; ++ ++ if (bfqq == bfqd->in_service_queue) ++ /* ++ * In order not to break guarantees, budgets cannot be ++ * changed after an entity has been selected. ++ */ ++ return; ++ ++ BUG_ON(entity->tree != &st->active); ++ BUG_ON(entity == entity->sched_data->in_service_entity); ++ ++ new_budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ if (entity->budget != new_budget) { ++ entity->budget = new_budget; ++ bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu", ++ new_budget); ++ bfq_activate_bfqq(bfqd, bfqq); ++ } ++} ++ ++static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd) ++{ ++ u64 dur; ++ ++ if (bfqd->bfq_wr_max_time > 0) ++ return bfqd->bfq_wr_max_time; ++ ++ dur = bfqd->RT_prod; ++ do_div(dur, bfqd->peak_rate); ++ ++ return dur; ++} ++ ++/* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ ++static inline void bfq_reset_burst_list(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *item; ++ struct hlist_node *n; ++ ++ hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node) ++ hlist_del_init(&item->burst_list_node); ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++ bfqd->burst_size = 1; ++} ++ ++/* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */ ++static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ /* Increment burst size to take into account also bfqq */ ++ bfqd->burst_size++; ++ ++ if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { ++ struct bfq_queue *pos, *bfqq_item; ++ struct hlist_node *n; ++ ++ /* ++ * Enough queues have been activated shortly after each ++ * other to consider this burst as large. ++ */ ++ bfqd->large_burst = true; ++ ++ /* ++ * We can now mark all queues in the burst list as ++ * belonging to a large burst. ++ */ ++ hlist_for_each_entry(bfqq_item, &bfqd->burst_list, ++ burst_list_node) ++ bfq_mark_bfqq_in_large_burst(bfqq_item); ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ ++ /* ++ * From now on, and until the current burst finishes, any ++ * new queue being activated shortly after the last queue ++ * was inserted in the burst can be immediately marked as ++ * belonging to a large burst. So the burst list is not ++ * needed any more. Remove it. ++ */ ++ hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, ++ burst_list_node) ++ hlist_del_init(&pos->burst_list_node); ++ } else /* burst not yet large: add bfqq to the burst list */ ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++} ++ ++/* ++ * If many queues happen to become active shortly after each other, then, ++ * to help the processes associated to these queues get their job done as ++ * soon as possible, it is usually better to not grant either weight-raising ++ * or device idling to these queues. In this comment we describe, firstly, ++ * the reasons why this fact holds, and, secondly, the next function, which ++ * implements the main steps needed to properly mark these queues so that ++ * they can then be treated in a different way. ++ * ++ * As for the terminology, we say that a queue becomes active, i.e., ++ * switches from idle to backlogged, either when it is created (as a ++ * consequence of the arrival of an I/O request), or, if already existing, ++ * when a new request for the queue arrives while the queue is idle. ++ * Bursts of activations, i.e., activations of different queues occurring ++ * shortly after each other, are typically caused by services or applications ++ * that spawn or reactivate many parallel threads/processes. Examples are ++ * systemd during boot or git grep. ++ * ++ * These services or applications benefit mostly from a high throughput: ++ * the quicker the requests of the activated queues are cumulatively served, ++ * the sooner the target job of these queues gets completed. As a consequence, ++ * weight-raising any of these queues, which also implies idling the device ++ * for it, is almost always counterproductive: in most cases it just lowers ++ * throughput. ++ * ++ * On the other hand, a burst of activations may be also caused by the start ++ * of an application that does not consist in a lot of parallel I/O-bound ++ * threads. In fact, with a complex application, the burst may be just a ++ * consequence of the fact that several processes need to be executed to ++ * start-up the application. To start an application as quickly as possible, ++ * the best thing to do is to privilege the I/O related to the application ++ * with respect to all other I/O. Therefore, the best strategy to start as ++ * quickly as possible an application that causes a burst of activations is ++ * to weight-raise all the queues activated during the burst. This is the ++ * exact opposite of the best strategy for the other type of bursts. ++ * ++ * In the end, to take the best action for each of the two cases, the two ++ * types of bursts need to be distinguished. Fortunately, this seems ++ * relatively easy to do, by looking at the sizes of the bursts. In ++ * particular, we found a threshold such that bursts with a larger size ++ * than that threshold are apparently caused only by services or commands ++ * such as systemd or git grep. For brevity, hereafter we call just 'large' ++ * these bursts. BFQ *does not* weight-raise queues whose activations occur ++ * in a large burst. In addition, for each of these queues BFQ performs or ++ * does not perform idling depending on which choice boosts the throughput ++ * most. The exact choice depends on the device and request pattern at ++ * hand. ++ * ++ * Turning back to the next function, it implements all the steps needed ++ * to detect the occurrence of a large burst and to properly mark all the ++ * queues belonging to it (so that they can then be treated in a different ++ * way). This goal is achieved by maintaining a special "burst list" that ++ * holds, temporarily, the queues that belong to the burst in progress. The ++ * list is then used to mark these queues as belonging to a large burst if ++ * the burst does become large. The main steps are the following. ++ * ++ * . when the very first queue is activated, the queue is inserted into the ++ * list (as it could be the first queue in a possible burst) ++ * ++ * . if the current burst has not yet become large, and a queue Q that does ++ * not yet belong to the burst is activated shortly after the last time ++ * at which a new queue entered the burst list, then the function appends ++ * Q to the burst list ++ * ++ * . if, as a consequence of the previous step, the burst size reaches ++ * the large-burst threshold, then ++ * ++ * . all the queues in the burst list are marked as belonging to a ++ * large burst ++ * ++ * . the burst list is deleted; in fact, the burst list already served ++ * its purpose (keeping temporarily track of the queues in a burst, ++ * so as to be able to mark them as belonging to a large burst in the ++ * previous sub-step), and now is not needed any more ++ * ++ * . the device enters a large-burst mode ++ * ++ * . if a queue Q that does not belong to the burst is activated while ++ * the device is in large-burst mode and shortly after the last time ++ * at which a queue either entered the burst list or was marked as ++ * belonging to the current large burst, then Q is immediately marked ++ * as belonging to a large burst. ++ * ++ * . if a queue Q that does not belong to the burst is activated a while ++ * later, i.e., not shortly after, than the last time at which a queue ++ * either entered the burst list or was marked as belonging to the ++ * current large burst, then the current burst is deemed as finished and: ++ * ++ * . the large-burst mode is reset if set ++ * ++ * . the burst list is emptied ++ * ++ * . Q is inserted in the burst list, as Q may be the first queue ++ * in a possible new burst (then the burst list contains just Q ++ * after this step). ++ */ ++static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ bool idle_for_long_time) ++{ ++ /* ++ * If bfqq happened to be activated in a burst, but has been idle ++ * for at least as long as an interactive queue, then we assume ++ * that, in the overall I/O initiated in the burst, the I/O ++ * associated to bfqq is finished. So bfqq does not need to be ++ * treated as a queue belonging to a burst anymore. Accordingly, ++ * we reset bfqq's in_large_burst flag if set, and remove bfqq ++ * from the burst list if it's there. We do not decrement instead ++ * burst_size, because the fact that bfqq does not need to belong ++ * to the burst list any more does not invalidate the fact that ++ * bfqq may have been activated during the current burst. ++ */ ++ if (idle_for_long_time) { ++ hlist_del_init(&bfqq->burst_list_node); ++ bfq_clear_bfqq_in_large_burst(bfqq); ++ } ++ ++ /* ++ * If bfqq is already in the burst list or is part of a large ++ * burst, then there is nothing else to do. ++ */ ++ if (!hlist_unhashed(&bfqq->burst_list_node) || ++ bfq_bfqq_in_large_burst(bfqq)) ++ return; ++ ++ /* ++ * If bfqq's activation happens late enough, then the current ++ * burst is finished, and related data structures must be reset. ++ * ++ * In this respect, consider the special case where bfqq is the very ++ * first queue being activated. In this case, last_ins_in_burst is ++ * not yet significant when we get here. But it is easy to verify ++ * that, whether or not the following condition is true, bfqq will ++ * end up being inserted into the burst list. In particular the ++ * list will happen to contain only bfqq. And this is exactly what ++ * has to happen, as bfqq may be the first queue in a possible ++ * burst. ++ */ ++ if (time_is_before_jiffies(bfqd->last_ins_in_burst + ++ bfqd->bfq_burst_interval)) { ++ bfqd->large_burst = false; ++ bfq_reset_burst_list(bfqd, bfqq); ++ return; ++ } ++ ++ /* ++ * If we get here, then bfqq is being activated shortly after the ++ * last queue. So, if the current burst is also large, we can mark ++ * bfqq as belonging to this large burst immediately. ++ */ ++ if (bfqd->large_burst) { ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ return; ++ } ++ ++ /* ++ * If we get here, then a large-burst state has not yet been ++ * reached, but bfqq is being activated shortly after the last ++ * queue. Then we add bfqq to the burst. ++ */ ++ bfq_add_to_burst(bfqd, bfqq); ++} ++ ++static void bfq_add_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *next_rq, *prev; ++ unsigned long old_wr_coeff = bfqq->wr_coeff; ++ bool interactive = false; ++ ++ bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq)); ++ bfqq->queued[rq_is_sync(rq)]++; ++ bfqd->queued++; ++ ++ elv_rb_add(&bfqq->sort_list, rq); ++ ++ /* ++ * Check if this request is a better next-serve candidate. ++ */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position); ++ BUG_ON(next_rq == NULL); ++ bfqq->next_rq = next_rq; ++ ++ /* ++ * Adjust priority tree position, if next_rq changes. ++ */ ++ if (prev != bfqq->next_rq) ++ bfq_rq_pos_tree_add(bfqd, bfqq); ++ ++ if (!bfq_bfqq_busy(bfqq)) { ++ bool soft_rt, ++ idle_for_long_time = time_is_before_jiffies( ++ bfqq->budget_timeout + ++ bfqd->bfq_wr_min_idle_time); ++ ++ if (bfq_bfqq_sync(bfqq)) { ++ bool already_in_burst = ++ !hlist_unhashed(&bfqq->burst_list_node) || ++ bfq_bfqq_in_large_burst(bfqq); ++ bfq_handle_burst(bfqd, bfqq, idle_for_long_time); ++ /* ++ * If bfqq was not already in the current burst, ++ * then, at this point, bfqq either has been ++ * added to the current burst or has caused the ++ * current burst to terminate. In particular, in ++ * the second case, bfqq has become the first ++ * queue in a possible new burst. ++ * In both cases last_ins_in_burst needs to be ++ * moved forward. ++ */ ++ if (!already_in_burst) ++ bfqd->last_ins_in_burst = jiffies; ++ } ++ ++ soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && ++ !bfq_bfqq_in_large_burst(bfqq) && ++ time_is_before_jiffies(bfqq->soft_rt_next_start); ++ interactive = !bfq_bfqq_in_large_burst(bfqq) && ++ idle_for_long_time; ++ entity->budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ ++ if (!bfq_bfqq_IO_bound(bfqq)) { ++ if (time_before(jiffies, ++ RQ_BIC(rq)->ttime.last_end_request + ++ bfqd->bfq_slice_idle)) { ++ bfqq->requests_within_timer++; ++ if (bfqq->requests_within_timer >= ++ bfqd->bfq_requests_within_timer) ++ bfq_mark_bfqq_IO_bound(bfqq); ++ } else ++ bfqq->requests_within_timer = 0; ++ } ++ ++ if (!bfqd->low_latency) ++ goto add_bfqq_busy; ++ ++ /* ++ * If the queue is not being boosted and has been idle ++ * for enough time, start a weight-raising period ++ */ ++ if (old_wr_coeff == 1 && (interactive || soft_rt)) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ if (interactive) ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ else ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais starting at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } else if (old_wr_coeff > 1) { ++ if (interactive) ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ else if (bfq_bfqq_in_large_burst(bfqq) || ++ (bfqq->wr_cur_max_time == ++ bfqd->bfq_wr_rt_max_time && ++ !soft_rt)) { ++ bfqq->wr_coeff = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais ending at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq-> ++ wr_cur_max_time)); ++ } else if (time_before( ++ bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time, ++ jiffies + ++ bfqd->bfq_wr_rt_max_time) && ++ soft_rt) { ++ /* ++ * ++ * The remaining weight-raising time is lower ++ * than bfqd->bfq_wr_rt_max_time, which ++ * means that the application is enjoying ++ * weight raising either because deemed soft- ++ * rt in the near past, or because deemed ++ * interactive a long ago. In both cases, ++ * resetting now the current remaining weight- ++ * raising time for the application to the ++ * weight-raising duration for soft rt ++ * applications would not cause any latency ++ * increase for the application (as the new ++ * duration would be higher than the remaining ++ * time). ++ * ++ * In addition, the application is now meeting ++ * the requirements for being deemed soft rt. ++ * In the end we can correctly and safely ++ * (re)charge the weight-raising duration for ++ * the application with the weight-raising ++ * duration for soft rt applications. ++ * ++ * In particular, doing this recharge now, i.e., ++ * before the weight-raising period for the ++ * application finishes, reduces the probability ++ * of the following negative scenario: ++ * 1) the weight of a soft rt application is ++ * raised at startup (as for any newly ++ * created application), ++ * 2) since the application is not interactive, ++ * at a certain time weight-raising is ++ * stopped for the application, ++ * 3) at that time the application happens to ++ * still have pending requests, and hence ++ * is destined to not have a chance to be ++ * deemed soft rt before these requests are ++ * completed (see the comments to the ++ * function bfq_bfqq_softrt_next_start() ++ * for details on soft rt detection), ++ * 4) these pending requests experience a high ++ * latency because the application is not ++ * weight-raised while they are pending. ++ */ ++ bfqq->last_wr_start_finish = jiffies; ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ } ++ } ++ if (old_wr_coeff != bfqq->wr_coeff) ++ entity->ioprio_changed = 1; ++add_bfqq_busy: ++ bfqq->last_idle_bklogged = jiffies; ++ bfqq->service_from_backlogged = 0; ++ bfq_clear_bfqq_softrt_update(bfqq); ++ bfq_add_bfqq_busy(bfqd, bfqq); ++ } else { ++ if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) && ++ time_is_before_jiffies( ++ bfqq->last_wr_start_finish + ++ bfqd->bfq_wr_min_inter_arr_async)) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ ++ bfqd->wr_busy_queues++; ++ entity->ioprio_changed = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "non-idle wrais starting at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ if (prev != bfqq->next_rq) ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ if (bfqd->low_latency && ++ (old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive)) ++ bfqq->last_wr_start_finish = jiffies; ++} ++ ++static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd, ++ struct bio *bio) ++{ ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (bic == NULL) ++ return NULL; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ if (bfqq != NULL) ++ return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio)); ++ ++ return NULL; ++} ++ ++static void bfq_activate_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ ++ bfqd->rq_in_driver++; ++ bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ bfq_log(bfqd, "activate_request: new bfqd->last_position %llu", ++ (long long unsigned)bfqd->last_position); ++} ++ ++static inline void bfq_deactivate_request(struct request_queue *q, ++ struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ ++ BUG_ON(bfqd->rq_in_driver == 0); ++ bfqd->rq_in_driver--; ++} ++ ++static void bfq_remove_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ const int sync = rq_is_sync(rq); ++ ++ if (bfqq->next_rq == rq) { ++ bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq); ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ list_del_init(&rq->queuelist); ++ BUG_ON(bfqq->queued[sync] == 0); ++ bfqq->queued[sync]--; ++ bfqd->queued--; ++ elv_rb_del(&bfqq->sort_list, rq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ /* ++ * Remove queue from request-position tree as it is empty. ++ */ ++ if (bfqq->pos_root != NULL) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ } ++ ++ if (rq->cmd_flags & REQ_META) { ++ BUG_ON(bfqq->meta_pending == 0); ++ bfqq->meta_pending--; ++ } ++} ++ ++static int bfq_merge(struct request_queue *q, struct request **req, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct request *__rq; ++ ++ __rq = bfq_find_rq_fmerge(bfqd, bio); ++ if (__rq != NULL && elv_rq_merge_ok(__rq, bio)) { ++ *req = __rq; ++ return ELEVATOR_FRONT_MERGE; ++ } ++ ++ return ELEVATOR_NO_MERGE; ++} ++ ++static void bfq_merged_request(struct request_queue *q, struct request *req, ++ int type) ++{ ++ if (type == ELEVATOR_FRONT_MERGE && ++ rb_prev(&req->rb_node) && ++ blk_rq_pos(req) < ++ blk_rq_pos(container_of(rb_prev(&req->rb_node), ++ struct request, rb_node))) { ++ struct bfq_queue *bfqq = RQ_BFQQ(req); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *prev, *next_rq; ++ ++ /* Reposition request in its sort_list */ ++ elv_rb_del(&bfqq->sort_list, req); ++ elv_rb_add(&bfqq->sort_list, req); ++ /* Choose next request to be served for bfqq */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req, ++ bfqd->last_position); ++ BUG_ON(next_rq == NULL); ++ bfqq->next_rq = next_rq; ++ /* ++ * If next_rq changes, update both the queue's budget to ++ * fit the new request and the queue's position in its ++ * rq_pos_tree. ++ */ ++ if (prev != bfqq->next_rq) { ++ bfq_updated_next_req(bfqd, bfqq); ++ bfq_rq_pos_tree_add(bfqd, bfqq); ++ } ++ } ++} ++ ++static void bfq_merged_requests(struct request_queue *q, struct request *rq, ++ struct request *next) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ /* ++ * Reposition in fifo if next is older than rq. ++ */ ++ if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && ++ time_before(next->fifo_time, rq->fifo_time)) { ++ list_move(&rq->queuelist, &next->queuelist); ++ rq->fifo_time = next->fifo_time; ++ } ++ ++ if (bfqq->next_rq == next) ++ bfqq->next_rq = rq; ++ ++ bfq_remove_request(next); ++} ++ ++/* Must be called with bfqq != NULL */ ++static inline void bfq_bfqq_end_wr(struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfqq == NULL); ++ if (bfq_bfqq_busy(bfqq)) ++ bfqq->bfqd->wr_busy_queues--; ++ bfqq->wr_coeff = 1; ++ bfqq->wr_cur_max_time = 0; ++ /* Trigger a weight change on the next activation of the queue */ ++ bfqq->entity.ioprio_changed = 1; ++} ++ ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ if (bfqg->async_bfqq[i][j] != NULL) ++ bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]); ++ if (bfqg->async_idle_bfqq != NULL) ++ bfq_bfqq_end_wr(bfqg->async_idle_bfqq); ++} ++ ++static void bfq_end_wr(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq; ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ bfq_end_wr_async(bfqd); ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++} ++ ++static int bfq_allow_merge(struct request_queue *q, struct request *rq, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ /* ++ * Disallow merge of a sync bio into an async request. ++ */ ++ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) ++ return 0; ++ ++ /* ++ * Lookup the bfqq that this bio will be queued with. Allow ++ * merge only if rq is queued there. ++ * Queue lock is held here. ++ */ ++ bic = bfq_bic_lookup(bfqd, current->io_context); ++ if (bic == NULL) ++ return 0; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ return bfqq == RQ_BFQQ(rq); ++} ++ ++static void __bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq != NULL) { ++ bfq_mark_bfqq_must_alloc(bfqq); ++ bfq_mark_bfqq_budget_new(bfqq); ++ bfq_clear_bfqq_fifo_expire(bfqq); ++ ++ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_in_service_queue, cur-budget = %lu", ++ bfqq->entity.budget); ++ } ++ ++ bfqd->in_service_queue = bfqq; ++} ++ ++/* ++ * Get and set a new queue for service. ++ */ ++static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (!bfqq) ++ bfqq = bfq_get_next_queue(bfqd); ++ else ++ bfq_get_next_queue_forced(bfqd, bfqq); ++ ++ __bfq_set_in_service_queue(bfqd, bfqq); ++ return bfqq; ++} ++ ++static inline sector_t bfq_dist_from_last(struct bfq_data *bfqd, ++ struct request *rq) ++{ ++ if (blk_rq_pos(rq) >= bfqd->last_position) ++ return blk_rq_pos(rq) - bfqd->last_position; ++ else ++ return bfqd->last_position - blk_rq_pos(rq); ++} ++ ++/* ++ * Return true if bfqq has no request pending and rq is close enough to ++ * bfqd->last_position, or if rq is closer to bfqd->last_position than ++ * bfqq->next_rq ++ */ ++static inline int bfq_rq_close(struct bfq_data *bfqd, struct request *rq) ++{ ++ return bfq_dist_from_last(bfqd, rq) <= BFQQ_SEEK_THR; ++} ++ ++static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) ++{ ++ struct rb_root *root = &bfqd->rq_pos_tree; ++ struct rb_node *parent, *node; ++ struct bfq_queue *__bfqq; ++ sector_t sector = bfqd->last_position; ++ ++ if (RB_EMPTY_ROOT(root)) ++ return NULL; ++ ++ /* ++ * First, if we find a request starting at the end of the last ++ * request, choose it. ++ */ ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL); ++ if (__bfqq != NULL) ++ return __bfqq; ++ ++ /* ++ * If the exact sector wasn't found, the parent of the NULL leaf ++ * will contain the closest sector (rq_pos_tree sorted by ++ * next_request position). ++ */ ++ __bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ return __bfqq; ++ ++ if (blk_rq_pos(__bfqq->next_rq) < sector) ++ node = rb_next(&__bfqq->pos_node); ++ else ++ node = rb_prev(&__bfqq->pos_node); ++ if (node == NULL) ++ return NULL; ++ ++ __bfqq = rb_entry(node, struct bfq_queue, pos_node); ++ if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ return __bfqq; ++ ++ return NULL; ++} ++ ++/* ++ * bfqd - obvious ++ * cur_bfqq - passed in so that we don't decide that the current queue ++ * is closely cooperating with itself. ++ * ++ * We are assuming that cur_bfqq has dispatched at least one request, ++ * and that bfqd->last_position reflects a position on the disk associated ++ * with the I/O issued by cur_bfqq. ++ */ ++static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, ++ struct bfq_queue *cur_bfqq) ++{ ++ struct bfq_queue *bfqq; ++ ++ if (bfq_class_idle(cur_bfqq)) ++ return NULL; ++ if (!bfq_bfqq_sync(cur_bfqq)) ++ return NULL; ++ if (BFQQ_SEEKY(cur_bfqq)) ++ return NULL; ++ ++ /* If device has only one backlogged bfq_queue, don't search. */ ++ if (bfqd->busy_queues == 1) ++ return NULL; ++ ++ /* ++ * We should notice if some of the queues are cooperating, e.g. ++ * working closely on the same area of the disk. In that case, ++ * we can group them together and don't waste time idling. ++ */ ++ bfqq = bfqq_close(bfqd); ++ if (bfqq == NULL || bfqq == cur_bfqq) ++ return NULL; ++ ++ /* ++ * Do not merge queues from different bfq_groups. ++ */ ++ if (bfqq->entity.parent != cur_bfqq->entity.parent) ++ return NULL; ++ ++ /* ++ * It only makes sense to merge sync queues. ++ */ ++ if (!bfq_bfqq_sync(bfqq)) ++ return NULL; ++ if (BFQQ_SEEKY(bfqq)) ++ return NULL; ++ ++ /* ++ * Do not merge queues of different priority classes. ++ */ ++ if (bfq_class_rt(bfqq) != bfq_class_rt(cur_bfqq)) ++ return NULL; ++ ++ return bfqq; ++} ++ ++/* ++ * If enough samples have been computed, return the current max budget ++ * stored in bfqd, which is dynamically updated according to the ++ * estimated disk peak rate; otherwise return the default max budget ++ */ ++static inline unsigned long bfq_max_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < 194) ++ return bfq_default_max_budget; ++ else ++ return bfqd->bfq_max_budget; ++} ++ ++/* ++ * Return min budget, which is a fraction of the current or default ++ * max budget (trying with 1/32) ++ */ ++static inline unsigned long bfq_min_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < 194) ++ return bfq_default_max_budget / 32; ++ else ++ return bfqd->bfq_max_budget / 32; ++} ++ ++static void bfq_arm_slice_timer(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfqd->in_service_queue; ++ struct bfq_io_cq *bic; ++ unsigned long sl; ++ ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Processes have exited, don't wait. */ ++ bic = bfqd->in_service_bic; ++ if (bic == NULL || atomic_read(&bic->icq.ioc->active_ref) == 0) ++ return; ++ ++ bfq_mark_bfqq_wait_request(bfqq); ++ ++ /* ++ * We don't want to idle for seeks, but we do want to allow ++ * fair distribution of slice time for a process doing back-to-back ++ * seeks. So allow a little bit of time for him to submit a new rq. ++ * ++ * To prevent processes with (partly) seeky workloads from ++ * being too ill-treated, grant them a small fraction of the ++ * assigned budget before reducing the waiting time to ++ * BFQ_MIN_TT. This happened to help reduce latency. ++ */ ++ sl = bfqd->bfq_slice_idle; ++ /* ++ * Unless the queue is being weight-raised, grant only minimum idle ++ * time if the queue either has been seeky for long enough or has ++ * already proved to be constantly seeky. ++ */ ++ if (bfq_sample_valid(bfqq->seek_samples) && ++ ((BFQQ_SEEKY(bfqq) && bfqq->entity.service > ++ bfq_max_budget(bfqq->bfqd) / 8) || ++ bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1) ++ sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT)); ++ else if (bfqq->wr_coeff > 1) ++ sl = sl * 3; ++ bfqd->last_idling_start = ktime_get(); ++ mod_timer(&bfqd->idle_slice_timer, jiffies + sl); ++ bfq_log(bfqd, "arm idle: %u/%u ms", ++ jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle)); ++} ++ ++/* ++ * Set the maximum time for the in-service queue to consume its ++ * budget. This prevents seeky processes from lowering the disk ++ * throughput (always guaranteed with a time slice scheme as in CFQ). ++ */ ++static void bfq_set_budget_timeout(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfqd->in_service_queue; ++ unsigned int timeout_coeff; ++ if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) ++ timeout_coeff = 1; ++ else ++ timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight; ++ ++ bfqd->last_budget_start = ktime_get(); ++ ++ bfq_clear_bfqq_budget_new(bfqq); ++ bfqq->budget_timeout = jiffies + ++ bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff; ++ ++ bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u", ++ jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * ++ timeout_coeff)); ++} ++ ++/* ++ * Move request from internal lists to the request queue dispatch list. ++ */ ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ /* ++ * For consistency, the next instruction should have been executed ++ * after removing the request from the queue and dispatching it. ++ * We execute instead this instruction before bfq_remove_request() ++ * (and hence introduce a temporary inconsistency), for efficiency. ++ * In fact, in a forced_dispatch, this prevents two counters related ++ * to bfqq->dispatched to risk to be uselessly decremented if bfqq ++ * is not in service, and then to be incremented again after ++ * incrementing bfqq->dispatched. ++ */ ++ bfqq->dispatched++; ++ bfq_remove_request(rq); ++ elv_dispatch_sort(q, rq); ++ ++ if (bfq_bfqq_sync(bfqq)) ++ bfqd->sync_flight++; ++} ++ ++/* ++ * Return expired entry, or NULL to just start from scratch in rbtree. ++ */ ++static struct request *bfq_check_fifo(struct bfq_queue *bfqq) ++{ ++ struct request *rq = NULL; ++ ++ if (bfq_bfqq_fifo_expire(bfqq)) ++ return NULL; ++ ++ bfq_mark_bfqq_fifo_expire(bfqq); ++ ++ if (list_empty(&bfqq->fifo)) ++ return NULL; ++ ++ rq = rq_entry_fifo(bfqq->fifo.next); ++ ++ if (time_before(jiffies, rq->fifo_time)) ++ return NULL; ++ ++ return rq; ++} ++ ++/* Must be called with the queue_lock held. */ ++static int bfqq_process_refs(struct bfq_queue *bfqq) ++{ ++ int process_refs, io_refs; ++ ++ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; ++ process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; ++ BUG_ON(process_refs < 0); ++ return process_refs; ++} ++ ++static void bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ int process_refs, new_process_refs; ++ struct bfq_queue *__bfqq; ++ ++ /* ++ * If there are no process references on the new_bfqq, then it is ++ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain ++ * may have dropped their last reference (not just their last process ++ * reference). ++ */ ++ if (!bfqq_process_refs(new_bfqq)) ++ return; ++ ++ /* Avoid a circular list and skip interim queue merges. */ ++ while ((__bfqq = new_bfqq->new_bfqq)) { ++ if (__bfqq == bfqq) ++ return; ++ new_bfqq = __bfqq; ++ } ++ ++ process_refs = bfqq_process_refs(bfqq); ++ new_process_refs = bfqq_process_refs(new_bfqq); ++ /* ++ * If the process for the bfqq has gone away, there is no ++ * sense in merging the queues. ++ */ ++ if (process_refs == 0 || new_process_refs == 0) ++ return; ++ ++ /* ++ * Merge in the direction of the lesser amount of work. ++ */ ++ if (new_process_refs >= process_refs) { ++ bfqq->new_bfqq = new_bfqq; ++ atomic_add(process_refs, &new_bfqq->ref); ++ } else { ++ new_bfqq->new_bfqq = bfqq; ++ atomic_add(new_process_refs, &bfqq->ref); ++ } ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", ++ new_bfqq->pid); ++} ++ ++static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ return entity->budget - entity->service; ++} ++ ++static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ __bfq_bfqd_reset_in_service(bfqd); ++ ++ /* ++ * If this bfqq is shared between multiple processes, check ++ * to make sure that those processes are still issuing I/Os ++ * within the mean seek distance. If not, it may be time to ++ * break the queues apart again. ++ */ ++ if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq)) ++ bfq_mark_bfqq_split_coop(bfqq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ /* ++ * Overloading budget_timeout field to store the time ++ * at which the queue remains with no backlog; used by ++ * the weight-raising mechanism. ++ */ ++ bfqq->budget_timeout = jiffies; ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ } else { ++ bfq_activate_bfqq(bfqd, bfqq); ++ /* ++ * Resort priority tree of potential close cooperators. ++ */ ++ bfq_rq_pos_tree_add(bfqd, bfqq); ++ } ++} ++ ++/** ++ * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior. ++ * @bfqd: device data. ++ * @bfqq: queue to update. ++ * @reason: reason for expiration. ++ * ++ * Handle the feedback on @bfqq budget. See the body for detailed ++ * comments. ++ */ ++static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ enum bfqq_expiration reason) ++{ ++ struct request *next_rq; ++ unsigned long budget, min_budget; ++ ++ budget = bfqq->max_budget; ++ min_budget = bfq_min_budget(bfqd); ++ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %lu, budg left %lu", ++ bfqq->entity.budget, bfq_bfqq_budget_left(bfqq)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %lu, min budg %lu", ++ budget, bfq_min_budget(bfqd)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d", ++ bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue)); ++ ++ if (bfq_bfqq_sync(bfqq)) { ++ switch (reason) { ++ /* ++ * Caveat: in all the following cases we trade latency ++ * for throughput. ++ */ ++ case BFQ_BFQQ_TOO_IDLE: ++ /* ++ * This is the only case where we may reduce ++ * the budget: if there is no request of the ++ * process still waiting for completion, then ++ * we assume (tentatively) that the timer has ++ * expired because the batch of requests of ++ * the process could have been served with a ++ * smaller budget. Hence, betting that ++ * process will behave in the same way when it ++ * becomes backlogged again, we reduce its ++ * next budget. As long as we guess right, ++ * this budget cut reduces the latency ++ * experienced by the process. ++ * ++ * However, if there are still outstanding ++ * requests, then the process may have not yet ++ * issued its next request just because it is ++ * still waiting for the completion of some of ++ * the still outstanding ones. So in this ++ * subcase we do not reduce its budget, on the ++ * contrary we increase it to possibly boost ++ * the throughput, as discussed in the ++ * comments to the BUDGET_TIMEOUT case. ++ */ ++ if (bfqq->dispatched > 0) /* still outstanding reqs */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ else { ++ if (budget > 5 * min_budget) ++ budget -= 4 * min_budget; ++ else ++ budget = min_budget; ++ } ++ break; ++ case BFQ_BFQQ_BUDGET_TIMEOUT: ++ /* ++ * We double the budget here because: 1) it ++ * gives the chance to boost the throughput if ++ * this is not a seeky process (which may have ++ * bumped into this timeout because of, e.g., ++ * ZBR), 2) together with charge_full_budget ++ * it helps give seeky processes higher ++ * timestamps, and hence be served less ++ * frequently. ++ */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_BUDGET_EXHAUSTED: ++ /* ++ * The process still has backlog, and did not ++ * let either the budget timeout or the disk ++ * idling timeout expire. Hence it is not ++ * seeky, has a short thinktime and may be ++ * happy with a higher budget too. So ++ * definitely increase the budget of this good ++ * candidate to boost the disk throughput. ++ */ ++ budget = min(budget * 4, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_NO_MORE_REQUESTS: ++ /* ++ * Leave the budget unchanged. ++ */ ++ default: ++ return; ++ } ++ } else /* async queue */ ++ /* async queues get always the maximum possible budget ++ * (their ability to dispatch is limited by ++ * @bfqd->bfq_max_budget_async_rq). ++ */ ++ budget = bfqd->bfq_max_budget; ++ ++ bfqq->max_budget = budget; ++ ++ if (bfqd->budgets_assigned >= 194 && bfqd->bfq_user_max_budget == 0 && ++ bfqq->max_budget > bfqd->bfq_max_budget) ++ bfqq->max_budget = bfqd->bfq_max_budget; ++ ++ /* ++ * Make sure that we have enough budget for the next request. ++ * Since the finish time of the bfqq must be kept in sync with ++ * the budget, be sure to call __bfq_bfqq_expire() after the ++ * update. ++ */ ++ next_rq = bfqq->next_rq; ++ if (next_rq != NULL) ++ bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ else ++ bfqq->entity.budget = bfqq->max_budget; ++ ++ bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %lu", ++ next_rq != NULL ? blk_rq_sectors(next_rq) : 0, ++ bfqq->entity.budget); ++} ++ ++static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout) ++{ ++ unsigned long max_budget; ++ ++ /* ++ * The max_budget calculated when autotuning is equal to the ++ * amount of sectors transfered in timeout_sync at the ++ * estimated peak rate. ++ */ ++ max_budget = (unsigned long)(peak_rate * 1000 * ++ timeout >> BFQ_RATE_SHIFT); ++ ++ return max_budget; ++} ++ ++/* ++ * In addition to updating the peak rate, checks whether the process ++ * is "slow", and returns 1 if so. This slow flag is used, in addition ++ * to the budget timeout, to reduce the amount of service provided to ++ * seeky processes, and hence reduce their chances to lower the ++ * throughput. See the code for more details. ++ */ ++static int bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int compensate, enum bfqq_expiration reason) ++{ ++ u64 bw, usecs, expected, timeout; ++ ktime_t delta; ++ int update = 0; ++ ++ if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq)) ++ return 0; ++ ++ if (compensate) ++ delta = bfqd->last_idling_start; ++ else ++ delta = ktime_get(); ++ delta = ktime_sub(delta, bfqd->last_budget_start); ++ usecs = ktime_to_us(delta); ++ ++ /* Don't trust short/unrealistic values. */ ++ if (usecs < 100 || usecs >= LONG_MAX) ++ return 0; ++ ++ /* ++ * Calculate the bandwidth for the last slice. We use a 64 bit ++ * value to store the peak rate, in sectors per usec in fixed ++ * point math. We do so to have enough precision in the estimate ++ * and to avoid overflows. ++ */ ++ bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT; ++ do_div(bw, (unsigned long)usecs); ++ ++ timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); ++ ++ /* ++ * Use only long (> 20ms) intervals to filter out spikes for ++ * the peak rate estimation. ++ */ ++ if (usecs > 20000) { ++ if (bw > bfqd->peak_rate || ++ (!BFQQ_SEEKY(bfqq) && ++ reason == BFQ_BFQQ_BUDGET_TIMEOUT)) { ++ bfq_log(bfqd, "measured bw =%llu", bw); ++ /* ++ * To smooth oscillations use a low-pass filter with ++ * alpha=7/8, i.e., ++ * new_rate = (7/8) * old_rate + (1/8) * bw ++ */ ++ do_div(bw, 8); ++ if (bw == 0) ++ return 0; ++ bfqd->peak_rate *= 7; ++ do_div(bfqd->peak_rate, 8); ++ bfqd->peak_rate += bw; ++ update = 1; ++ bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate); ++ } ++ ++ update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1; ++ ++ if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES) ++ bfqd->peak_rate_samples++; ++ ++ if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES && ++ update) { ++ int dev_type = blk_queue_nonrot(bfqd->queue); ++ if (bfqd->bfq_user_max_budget == 0) { ++ bfqd->bfq_max_budget = ++ bfq_calc_max_budget(bfqd->peak_rate, ++ timeout); ++ bfq_log(bfqd, "new max_budget=%lu", ++ bfqd->bfq_max_budget); ++ } ++ if (bfqd->device_speed == BFQ_BFQD_FAST && ++ bfqd->peak_rate < device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_SLOW; ++ bfqd->RT_prod = R_slow[dev_type] * ++ T_slow[dev_type]; ++ } else if (bfqd->device_speed == BFQ_BFQD_SLOW && ++ bfqd->peak_rate > device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ bfqd->RT_prod = R_fast[dev_type] * ++ T_fast[dev_type]; ++ } ++ } ++ } ++ ++ /* ++ * If the process has been served for a too short time ++ * interval to let its possible sequential accesses prevail on ++ * the initial seek time needed to move the disk head on the ++ * first sector it requested, then give the process a chance ++ * and for the moment return false. ++ */ ++ if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8) ++ return 0; ++ ++ /* ++ * A process is considered ``slow'' (i.e., seeky, so that we ++ * cannot treat it fairly in the service domain, as it would ++ * slow down too much the other processes) if, when a slice ++ * ends for whatever reason, it has received service at a ++ * rate that would not be high enough to complete the budget ++ * before the budget timeout expiration. ++ */ ++ expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT; ++ ++ /* ++ * Caveat: processes doing IO in the slower disk zones will ++ * tend to be slow(er) even if not seeky. And the estimated ++ * peak rate will actually be an average over the disk ++ * surface. Hence, to not be too harsh with unlucky processes, ++ * we keep a budget/3 margin of safety before declaring a ++ * process slow. ++ */ ++ return expected > (4 * bfqq->entity.budget) / 3; ++} ++ ++/* ++ * To be deemed as soft real-time, an application must meet two ++ * requirements. First, the application must not require an average ++ * bandwidth higher than the approximate bandwidth required to playback or ++ * record a compressed high-definition video. ++ * The next function is invoked on the completion of the last request of a ++ * batch, to compute the next-start time instant, soft_rt_next_start, such ++ * that, if the next request of the application does not arrive before ++ * soft_rt_next_start, then the above requirement on the bandwidth is met. ++ * ++ * The second requirement is that the request pattern of the application is ++ * isochronous, i.e., that, after issuing a request or a batch of requests, ++ * the application stops issuing new requests until all its pending requests ++ * have been completed. After that, the application may issue a new batch, ++ * and so on. ++ * For this reason the next function is invoked to compute ++ * soft_rt_next_start only for applications that meet this requirement, ++ * whereas soft_rt_next_start is set to infinity for applications that do ++ * not. ++ * ++ * Unfortunately, even a greedy application may happen to behave in an ++ * isochronous way if the CPU load is high. In fact, the application may ++ * stop issuing requests while the CPUs are busy serving other processes, ++ * then restart, then stop again for a while, and so on. In addition, if ++ * the disk achieves a low enough throughput with the request pattern ++ * issued by the application (e.g., because the request pattern is random ++ * and/or the device is slow), then the application may meet the above ++ * bandwidth requirement too. To prevent such a greedy application to be ++ * deemed as soft real-time, a further rule is used in the computation of ++ * soft_rt_next_start: soft_rt_next_start must be higher than the current ++ * time plus the maximum time for which the arrival of a request is waited ++ * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle. ++ * This filters out greedy applications, as the latter issue instead their ++ * next request as soon as possible after the last one has been completed ++ * (in contrast, when a batch of requests is completed, a soft real-time ++ * application spends some time processing data). ++ * ++ * Unfortunately, the last filter may easily generate false positives if ++ * only bfqd->bfq_slice_idle is used as a reference time interval and one ++ * or both the following cases occur: ++ * 1) HZ is so low that the duration of a jiffy is comparable to or higher ++ * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with ++ * HZ=100. ++ * 2) jiffies, instead of increasing at a constant rate, may stop increasing ++ * for a while, then suddenly 'jump' by several units to recover the lost ++ * increments. This seems to happen, e.g., inside virtual machines. ++ * To address this issue, we do not use as a reference time interval just ++ * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In ++ * particular we add the minimum number of jiffies for which the filter ++ * seems to be quite precise also in embedded systems and KVM/QEMU virtual ++ * machines. ++ */ ++static inline unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ return max(bfqq->last_idle_bklogged + ++ HZ * bfqq->service_from_backlogged / ++ bfqd->bfq_wr_max_softrt_rate, ++ jiffies + bfqq->bfqd->bfq_slice_idle + 4); ++} ++ ++/* ++ * Return the largest-possible time instant such that, for as long as possible, ++ * the current time will be lower than this time instant according to the macro ++ * time_is_before_jiffies(). ++ */ ++static inline unsigned long bfq_infinity_from_now(unsigned long now) ++{ ++ return now + ULONG_MAX / 2; ++} ++ ++/** ++ * bfq_bfqq_expire - expire a queue. ++ * @bfqd: device owning the queue. ++ * @bfqq: the queue to expire. ++ * @compensate: if true, compensate for the time spent idling. ++ * @reason: the reason causing the expiration. ++ * ++ * ++ * If the process associated to the queue is slow (i.e., seeky), or in ++ * case of budget timeout, or, finally, if it is async, we ++ * artificially charge it an entire budget (independently of the ++ * actual service it received). As a consequence, the queue will get ++ * higher timestamps than the correct ones upon reactivation, and ++ * hence it will be rescheduled as if it had received more service ++ * than what it actually received. In the end, this class of processes ++ * will receive less service in proportion to how slowly they consume ++ * their budgets (and hence how seriously they tend to lower the ++ * throughput). ++ * ++ * In contrast, when a queue expires because it has been idling for ++ * too much or because it exhausted its budget, we do not touch the ++ * amount of service it has received. Hence when the queue will be ++ * reactivated and its timestamps updated, the latter will be in sync ++ * with the actual service received by the queue until expiration. ++ * ++ * Charging a full budget to the first type of queues and the exact ++ * service to the others has the effect of using the WF2Q+ policy to ++ * schedule the former on a timeslice basis, without violating the ++ * service domain guarantees of the latter. ++ */ ++static void bfq_bfqq_expire(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ int compensate, ++ enum bfqq_expiration reason) ++{ ++ int slow; ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ /* Update disk peak rate for autotuning and check whether the ++ * process is slow (see bfq_update_peak_rate). ++ */ ++ slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason); ++ ++ /* ++ * As above explained, 'punish' slow (i.e., seeky), timed-out ++ * and async queues, to favor sequential sync workloads. ++ * ++ * Processes doing I/O in the slower disk zones will tend to be ++ * slow(er) even if not seeky. Hence, since the estimated peak ++ * rate is actually an average over the disk surface, these ++ * processes may timeout just for bad luck. To avoid punishing ++ * them we do not charge a full budget to a process that ++ * succeeded in consuming at least 2/3 of its budget. ++ */ ++ if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT && ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3)) ++ bfq_bfqq_charge_full_budget(bfqq); ++ ++ bfqq->service_from_backlogged += bfqq->entity.service; ++ ++ if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT && ++ !bfq_bfqq_constantly_seeky(bfqq)) { ++ bfq_mark_bfqq_constantly_seeky(bfqq); ++ if (!blk_queue_nonrot(bfqd->queue)) ++ bfqd->const_seeky_busy_in_flight_queues++; ++ } ++ ++ if (reason == BFQ_BFQQ_TOO_IDLE && ++ bfqq->entity.service <= 2 * bfqq->entity.budget / 10 ) ++ bfq_clear_bfqq_IO_bound(bfqq); ++ ++ if (bfqd->low_latency && bfqq->wr_coeff == 1) ++ bfqq->last_wr_start_finish = jiffies; ++ ++ if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ /* ++ * If we get here, and there are no outstanding requests, ++ * then the request pattern is isochronous (see the comments ++ * to the function bfq_bfqq_softrt_next_start()). Hence we ++ * can compute soft_rt_next_start. If, instead, the queue ++ * still has outstanding requests, then we have to wait ++ * for the completion of all the outstanding requests to ++ * discover whether the request pattern is actually ++ * isochronous. ++ */ ++ if (bfqq->dispatched == 0) ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ else { ++ /* ++ * The application is still waiting for the ++ * completion of one or more requests: ++ * prevent it from possibly being incorrectly ++ * deemed as soft real-time by setting its ++ * soft_rt_next_start to infinity. In fact, ++ * without this assignment, the application ++ * would be incorrectly deemed as soft ++ * real-time if: ++ * 1) it issued a new request before the ++ * completion of all its in-flight ++ * requests, and ++ * 2) at that time, its soft_rt_next_start ++ * happened to be in the past. ++ */ ++ bfqq->soft_rt_next_start = ++ bfq_infinity_from_now(jiffies); ++ /* ++ * Schedule an update of soft_rt_next_start to when ++ * the task may be discovered to be isochronous. ++ */ ++ bfq_mark_bfqq_softrt_update(bfqq); ++ } ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "expire (%d, slow %d, num_disp %d, idle_win %d)", reason, ++ slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq)); ++ ++ /* ++ * Increase, decrease or leave budget unchanged according to ++ * reason. ++ */ ++ __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); ++ __bfq_bfqq_expire(bfqd, bfqq); ++} ++ ++/* ++ * Budget timeout is not implemented through a dedicated timer, but ++ * just checked on request arrivals and completions, as well as on ++ * idle timer expirations. ++ */ ++static int bfq_bfqq_budget_timeout(struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_budget_new(bfqq) || ++ time_before(jiffies, bfqq->budget_timeout)) ++ return 0; ++ return 1; ++} ++ ++/* ++ * If we expire a queue that is waiting for the arrival of a new ++ * request, we may prevent the fictitious timestamp back-shifting that ++ * allows the guarantees of the queue to be preserved (see [1] for ++ * this tricky aspect). Hence we return true only if this condition ++ * does not hold, or if the queue is slow enough to deserve only to be ++ * kicked off for preserving a high throughput. ++*/ ++static inline int bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "may_budget_timeout: wait_request %d left %d timeout %d", ++ bfq_bfqq_wait_request(bfqq), ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3, ++ bfq_bfqq_budget_timeout(bfqq)); ++ ++ return (!bfq_bfqq_wait_request(bfqq) || ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3) ++ && ++ bfq_bfqq_budget_timeout(bfqq); ++} ++ ++/* ++ * Device idling is allowed only for the queues for which this function ++ * returns true. For this reason, the return value of this function plays a ++ * critical role for both throughput boosting and service guarantees. The ++ * return value is computed through a logical expression. In this rather ++ * long comment, we try to briefly describe all the details and motivations ++ * behind the components of this logical expression. ++ * ++ * First, the expression is false if bfqq is not sync, or if: bfqq happened ++ * to become active during a large burst of queue activations, and the ++ * pattern of requests bfqq contains boosts the throughput if bfqq is ++ * expired. In fact, queues that became active during a large burst benefit ++ * only from throughput, as discussed in the comments to bfq_handle_burst. ++ * In this respect, expiring bfqq certainly boosts the throughput on NCQ- ++ * capable flash-based devices, whereas, on rotational devices, it boosts ++ * the throughput only if bfqq contains random requests. ++ * ++ * On the opposite end, if (a) bfqq is sync, (b) the above burst-related ++ * condition does not hold, and (c) bfqq is being weight-raised, then the ++ * expression always evaluates to true, as device idling is instrumental ++ * for preserving low-latency guarantees (see [1]). If, instead, conditions ++ * (a) and (b) do hold, but (c) does not, then the expression evaluates to ++ * true only if: (1) bfqq is I/O-bound and has a non-null idle window, and ++ * (2) at least one of the following two conditions holds. ++ * The first condition is that the device is not performing NCQ, because ++ * idling the device most certainly boosts the throughput if this condition ++ * holds and bfqq is I/O-bound and has been granted a non-null idle window. ++ * The second compound condition is made of the logical AND of two components. ++ * ++ * The first component is true only if there is no weight-raised busy ++ * queue. This guarantees that the device is not idled for a sync non- ++ * weight-raised queue when there are busy weight-raised queues. The former ++ * is then expired immediately if empty. Combined with the timestamping ++ * rules of BFQ (see [1] for details), this causes sync non-weight-raised ++ * queues to get a lower number of requests served, and hence to ask for a ++ * lower number of requests from the request pool, before the busy weight- ++ * raised queues get served again. ++ * ++ * This is beneficial for the processes associated with weight-raised ++ * queues, when the request pool is saturated (e.g., in the presence of ++ * write hogs). In fact, if the processes associated with the other queues ++ * ask for requests at a lower rate, then weight-raised processes have a ++ * higher probability to get a request from the pool immediately (or at ++ * least soon) when they need one. Hence they have a higher probability to ++ * actually get a fraction of the disk throughput proportional to their ++ * high weight. This is especially true with NCQ-capable drives, which ++ * enqueue several requests in advance and further reorder internally- ++ * queued requests. ++ * ++ * In the end, mistreating non-weight-raised queues when there are busy ++ * weight-raised queues seems to mitigate starvation problems in the ++ * presence of heavy write workloads and NCQ, and hence to guarantee a ++ * higher application and system responsiveness in these hostile scenarios. ++ * ++ * If the first component of the compound condition is instead true, i.e., ++ * there is no weight-raised busy queue, then the second component of the ++ * compound condition takes into account service-guarantee and throughput ++ * issues related to NCQ (recall that the compound condition is evaluated ++ * only if the device is detected as supporting NCQ). ++ * ++ * As for service guarantees, allowing the drive to enqueue more than one ++ * request at a time, and hence delegating de facto final scheduling ++ * decisions to the drive's internal scheduler, causes loss of control on ++ * the actual request service order. In this respect, when the drive is ++ * allowed to enqueue more than one request at a time, the service ++ * distribution enforced by the drive's internal scheduler is likely to ++ * coincide with the desired device-throughput distribution only in the ++ * following, perfectly symmetric, scenario: ++ * 1) all active queues have the same weight, ++ * 2) all active groups at the same level in the groups tree have the same ++ * weight, ++ * 3) all active groups at the same level in the groups tree have the same ++ * number of children. ++ * ++ * Even in such a scenario, sequential I/O may still receive a preferential ++ * treatment, but this is not likely to be a big issue with flash-based ++ * devices, because of their non-dramatic loss of throughput with random ++ * I/O. Things do differ with HDDs, for which additional care is taken, as ++ * explained after completing the discussion for flash-based devices. ++ * ++ * Unfortunately, keeping the necessary state for evaluating exactly the ++ * above symmetry conditions would be quite complex and time-consuming. ++ * Therefore BFQ evaluates instead the following stronger sub-conditions, ++ * for which it is much easier to maintain the needed state: ++ * 1) all active queues have the same weight, ++ * 2) all active groups have the same weight, ++ * 3) all active groups have at most one active child each. ++ * In particular, the last two conditions are always true if hierarchical ++ * support and the cgroups interface are not enabled, hence no state needs ++ * to be maintained in this case. ++ * ++ * According to the above considerations, the second component of the ++ * compound condition evaluates to true if any of the above symmetry ++ * sub-condition does not hold, or the device is not flash-based. Therefore, ++ * if also the first component is true, then idling is allowed for a sync ++ * queue. These are the only sub-conditions considered if the device is ++ * flash-based, as, for such a device, it is sensible to force idling only ++ * for service-guarantee issues. In fact, as for throughput, idling ++ * NCQ-capable flash-based devices would not boost the throughput even ++ * with sequential I/O; rather it would lower the throughput in proportion ++ * to how fast the device is. In the end, (only) if all the three ++ * sub-conditions hold and the device is flash-based, the compound ++ * condition evaluates to false and therefore no idling is performed. ++ * ++ * As already said, things change with a rotational device, where idling ++ * boosts the throughput with sequential I/O (even with NCQ). Hence, for ++ * such a device the second component of the compound condition evaluates ++ * to true also if the following additional sub-condition does not hold: ++ * the queue is constantly seeky. Unfortunately, this different behavior ++ * with respect to flash-based devices causes an additional asymmetry: if ++ * some sync queues enjoy idling and some other sync queues do not, then ++ * the latter get a low share of the device throughput, simply because the ++ * former get many requests served after being set as in service, whereas ++ * the latter do not. As a consequence, to guarantee the desired throughput ++ * distribution, on HDDs the compound expression evaluates to true (and ++ * hence device idling is performed) also if the following last symmetry ++ * condition does not hold: no other queue is benefiting from idling. Also ++ * this last condition is actually replaced with a simpler-to-maintain and ++ * stronger condition: there is no busy queue which is not constantly seeky ++ * (and hence may also benefit from idling). ++ * ++ * To sum up, when all the required symmetry and throughput-boosting ++ * sub-conditions hold, the second component of the compound condition ++ * evaluates to false, and hence no idling is performed. This helps to ++ * keep the drives' internal queues full on NCQ-capable devices, and hence ++ * to boost the throughput, without causing 'almost' any loss of service ++ * guarantees. The 'almost' follows from the fact that, if the internal ++ * queue of one such device is filled while all the sub-conditions hold, ++ * but at some point in time some sub-condition stops to hold, then it may ++ * become impossible to let requests be served in the new desired order ++ * until all the requests already queued in the device have been served. ++ */ ++static inline bool bfq_bfqq_must_not_expire(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++#ifdef CONFIG_CGROUP_BFQIO ++#define symmetric_scenario (!bfqd->active_numerous_groups && \ ++ !bfq_differentiated_weights(bfqd)) ++#else ++#define symmetric_scenario (!bfq_differentiated_weights(bfqd)) ++#endif ++#define cond_for_seeky_on_ncq_hdd (bfq_bfqq_constantly_seeky(bfqq) && \ ++ bfqd->busy_in_flight_queues == \ ++ bfqd->const_seeky_busy_in_flight_queues) ++ ++#define cond_for_expiring_in_burst (bfq_bfqq_in_large_burst(bfqq) && \ ++ bfqd->hw_tag && \ ++ (blk_queue_nonrot(bfqd->queue) || \ ++ bfq_bfqq_constantly_seeky(bfqq))) ++ ++/* ++ * Condition for expiring a non-weight-raised queue (and hence not idling ++ * the device). ++ */ ++#define cond_for_expiring_non_wr (bfqd->hw_tag && \ ++ (bfqd->wr_busy_queues > 0 || \ ++ (symmetric_scenario && \ ++ (blk_queue_nonrot(bfqd->queue) || \ ++ cond_for_seeky_on_ncq_hdd)))) ++ ++ return bfq_bfqq_sync(bfqq) && ++ !cond_for_expiring_in_burst && ++ (bfqq->wr_coeff > 1 || ++ (bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_idle_window(bfqq) && ++ !cond_for_expiring_non_wr) ++ ); ++} ++ ++/* ++ * If the in-service queue is empty but sync, and the function ++ * bfq_bfqq_must_not_expire returns true, then: ++ * 1) the queue must remain in service and cannot be expired, and ++ * 2) the disk must be idled to wait for the possible arrival of a new ++ * request for the queue. ++ * See the comments to the function bfq_bfqq_must_not_expire for the reasons ++ * why performing device idling is the best choice to boost the throughput ++ * and preserve service guarantees when bfq_bfqq_must_not_expire itself ++ * returns true. ++ */ ++static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 && ++ bfq_bfqq_must_not_expire(bfqq); ++} ++ ++/* ++ * Select a queue for service. If we have a current queue in service, ++ * check whether to continue servicing it, or retrieve and set a new one. ++ */ ++static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq, *new_bfqq = NULL; ++ struct request *next_rq; ++ enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ ++ bfqq = bfqd->in_service_queue; ++ if (bfqq == NULL) ++ goto new_queue; ++ ++ bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); ++ ++ /* ++ * If another queue has a request waiting within our mean seek ++ * distance, let it run. The expire code will check for close ++ * cooperators and put the close queue at the front of the ++ * service tree. If possible, merge the expiring queue with the ++ * new bfqq. ++ */ ++ new_bfqq = bfq_close_cooperator(bfqd, bfqq); ++ if (new_bfqq != NULL && bfqq->new_bfqq == NULL) ++ bfq_setup_merge(bfqq, new_bfqq); ++ ++ if (bfq_may_expire_for_budg_timeout(bfqq) && ++ !timer_pending(&bfqd->idle_slice_timer) && ++ !bfq_bfqq_must_idle(bfqq)) ++ goto expire; ++ ++ next_rq = bfqq->next_rq; ++ /* ++ * If bfqq has requests queued and it has enough budget left to ++ * serve them, keep the queue, otherwise expire it. ++ */ ++ if (next_rq != NULL) { ++ if (bfq_serv_to_charge(next_rq, bfqq) > ++ bfq_bfqq_budget_left(bfqq)) { ++ reason = BFQ_BFQQ_BUDGET_EXHAUSTED; ++ goto expire; ++ } else { ++ /* ++ * The idle timer may be pending because we may ++ * not disable disk idling even when a new request ++ * arrives. ++ */ ++ if (timer_pending(&bfqd->idle_slice_timer)) { ++ /* ++ * If we get here: 1) at least a new request ++ * has arrived but we have not disabled the ++ * timer because the request was too small, ++ * 2) then the block layer has unplugged ++ * the device, causing the dispatch to be ++ * invoked. ++ * ++ * Since the device is unplugged, now the ++ * requests are probably large enough to ++ * provide a reasonable throughput. ++ * So we disable idling. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ del_timer(&bfqd->idle_slice_timer); ++ } ++ if (new_bfqq == NULL) ++ goto keep_queue; ++ else ++ goto expire; ++ } ++ } ++ ++ /* ++ * No requests pending. If the in-service queue still has requests ++ * in flight (possibly waiting for a completion) or is idling for a ++ * new request, then keep it. ++ */ ++ if (new_bfqq == NULL && (timer_pending(&bfqd->idle_slice_timer) || ++ (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq)))) { ++ bfqq = NULL; ++ goto keep_queue; ++ } else if (new_bfqq != NULL && timer_pending(&bfqd->idle_slice_timer)) { ++ /* ++ * Expiring the queue because there is a close cooperator, ++ * cancel timer. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ del_timer(&bfqd->idle_slice_timer); ++ } ++ ++ reason = BFQ_BFQQ_NO_MORE_REQUESTS; ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, 0, reason); ++new_queue: ++ bfqq = bfq_set_in_service_queue(bfqd, new_bfqq); ++ bfq_log(bfqd, "select_queue: new queue %d returned", ++ bfqq != NULL ? bfqq->pid : 0); ++keep_queue: ++ return bfqq; ++} ++ ++static void bfq_update_wr_data(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq->wr_coeff > 1) { /* queue is being boosted */ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "raising period dur %u/%u msec, old coeff %u, w %d(%d)", ++ jiffies_to_msecs(jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time), ++ bfqq->wr_coeff, ++ bfqq->entity.weight, bfqq->entity.orig_weight); ++ ++ BUG_ON(bfqq != bfqd->in_service_queue && entity->weight != ++ entity->orig_weight * bfqq->wr_coeff); ++ if (entity->ioprio_changed) ++ bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); ++ /* ++ * If the queue was activated in a burst, or ++ * too much time has elapsed from the beginning ++ * of this weight-raising, then end weight raising. ++ */ ++ if (bfq_bfqq_in_large_burst(bfqq) || ++ time_is_before_jiffies(bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time)) { ++ bfqq->last_wr_start_finish = jiffies; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais ending at %lu, rais_max_time %u", ++ bfqq->last_wr_start_finish, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ bfq_bfqq_end_wr(bfqq); ++ __bfq_entity_update_weight_prio( ++ bfq_entity_service_tree(entity), ++ entity); ++ } ++ } ++} ++ ++/* ++ * Dispatch one request from bfqq, moving it to the request queue ++ * dispatch list. ++ */ ++static int bfq_dispatch_request(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ struct request *rq; ++ unsigned long service_to_charge; ++ ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Follow expired path, else get first next available. */ ++ rq = bfq_check_fifo(bfqq); ++ if (rq == NULL) ++ rq = bfqq->next_rq; ++ service_to_charge = bfq_serv_to_charge(rq, bfqq); ++ ++ if (service_to_charge > bfq_bfqq_budget_left(bfqq)) { ++ /* ++ * This may happen if the next rq is chosen in fifo order ++ * instead of sector order. The budget is properly ++ * dimensioned to be always sufficient to serve the next ++ * request only if it is chosen in sector order. The reason ++ * is that it would be quite inefficient and little useful ++ * to always make sure that the budget is large enough to ++ * serve even the possible next rq in fifo order. ++ * In fact, requests are seldom served in fifo order. ++ * ++ * Expire the queue for budget exhaustion, and make sure ++ * that the next act_budget is enough to serve the next ++ * request, even if it comes from the fifo expired path. ++ */ ++ bfqq->next_rq = rq; ++ /* ++ * Since this dispatch is failed, make sure that ++ * a new one will be performed ++ */ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ goto expire; ++ } ++ ++ /* Finally, insert request into driver dispatch list. */ ++ bfq_bfqq_served(bfqq, service_to_charge); ++ bfq_dispatch_insert(bfqd->queue, rq); ++ ++ bfq_update_wr_data(bfqd, bfqq); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "dispatched %u sec req (%llu), budg left %lu", ++ blk_rq_sectors(rq), ++ (long long unsigned)blk_rq_pos(rq), ++ bfq_bfqq_budget_left(bfqq)); ++ ++ dispatched++; ++ ++ if (bfqd->in_service_bic == NULL) { ++ atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount); ++ bfqd->in_service_bic = RQ_BIC(rq); ++ } ++ ++ if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) && ++ dispatched >= bfqd->bfq_max_budget_async_rq) || ++ bfq_class_idle(bfqq))) ++ goto expire; ++ ++ return dispatched; ++ ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_EXHAUSTED); ++ return dispatched; ++} ++ ++static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ ++ while (bfqq->next_rq != NULL) { ++ bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq); ++ dispatched++; ++ } ++ ++ BUG_ON(!list_empty(&bfqq->fifo)); ++ return dispatched; ++} ++ ++/* ++ * Drain our current requests. ++ * Used for barriers and when switching io schedulers on-the-fly. ++ */ ++static int bfq_forced_dispatch(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq, *n; ++ struct bfq_service_tree *st; ++ int dispatched = 0; ++ ++ bfqq = bfqd->in_service_queue; ++ if (bfqq != NULL) ++ __bfq_bfqq_expire(bfqd, bfqq); ++ ++ /* ++ * Loop through classes, and be careful to leave the scheduler ++ * in a consistent state, as feedback mechanisms and vtime ++ * updates cannot be disabled during the process. ++ */ ++ list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) { ++ st = bfq_entity_service_tree(&bfqq->entity); ++ ++ dispatched += __bfq_forced_dispatch_bfqq(bfqq); ++ bfqq->max_budget = bfq_max_budget(bfqd); ++ ++ bfq_forget_idle(st); ++ } ++ ++ BUG_ON(bfqd->busy_queues != 0); ++ ++ return dispatched; ++} ++ ++static int bfq_dispatch_requests(struct request_queue *q, int force) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq; ++ int max_dispatch; ++ ++ bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues); ++ if (bfqd->busy_queues == 0) ++ return 0; ++ ++ if (unlikely(force)) ++ return bfq_forced_dispatch(bfqd); ++ ++ bfqq = bfq_select_queue(bfqd); ++ if (bfqq == NULL) ++ return 0; ++ ++ max_dispatch = bfqd->bfq_quantum; ++ if (bfq_class_idle(bfqq)) ++ max_dispatch = 1; ++ ++ if (!bfq_bfqq_sync(bfqq)) ++ max_dispatch = bfqd->bfq_max_budget_async_rq; ++ ++ if (bfqq->dispatched >= max_dispatch) { ++ if (bfqd->busy_queues > 1) ++ return 0; ++ if (bfqq->dispatched >= 4 * max_dispatch) ++ return 0; ++ } ++ ++ if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq)) ++ return 0; ++ ++ bfq_clear_bfqq_wait_request(bfqq); ++ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); ++ ++ if (!bfq_dispatch_request(bfqd, bfqq)) ++ return 0; ++ ++ bfq_log_bfqq(bfqd, bfqq, "dispatched one request of %d (max_disp %d)", ++ bfqq->pid, max_dispatch); ++ ++ return 1; ++} ++ ++/* ++ * Task holds one reference to the queue, dropped when task exits. Each rq ++ * in-flight on this queue also holds a reference, dropped when rq is freed. ++ * ++ * Queue lock must be held here. ++ */ ++static void bfq_put_queue(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ BUG_ON(atomic_read(&bfqq->ref) <= 0); ++ ++ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ if (!atomic_dec_and_test(&bfqq->ref)) ++ return; ++ ++ BUG_ON(rb_first(&bfqq->sort_list) != NULL); ++ BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0); ++ BUG_ON(bfqq->entity.tree != NULL); ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqd->in_service_queue == bfqq); ++ ++ if (bfq_bfqq_sync(bfqq)) ++ /* ++ * The fact that this queue is being destroyed does not ++ * invalidate the fact that this queue may have been ++ * activated during the current burst. As a consequence, ++ * although the queue does not exist anymore, and hence ++ * needs to be removed from the burst list if there, ++ * the burst size has not to be decremented. ++ */ ++ hlist_del_init(&bfqq->burst_list_node); ++ ++ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq); ++ ++ kmem_cache_free(bfq_pool, bfqq); ++} ++ ++static void bfq_put_cooperator(struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *__bfqq, *next; ++ ++ /* ++ * If this queue was scheduled to merge with another queue, be ++ * sure to drop the reference taken on that queue (and others in ++ * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs. ++ */ ++ __bfqq = bfqq->new_bfqq; ++ while (__bfqq) { ++ if (__bfqq == bfqq) ++ break; ++ next = __bfqq->new_bfqq; ++ bfq_put_queue(__bfqq); ++ __bfqq = next; ++ } ++} ++ ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ if (bfqq == bfqd->in_service_queue) { ++ __bfq_bfqq_expire(bfqd, bfqq); ++ bfq_schedule_dispatch(bfqd); ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++} ++ ++static inline void bfq_init_icq(struct io_cq *icq) ++{ ++ struct bfq_io_cq *bic = icq_to_bic(icq); ++ ++ bic->ttime.last_end_request = jiffies; ++} ++ ++static void bfq_exit_icq(struct io_cq *icq) ++{ ++ struct bfq_io_cq *bic = icq_to_bic(icq); ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ ++ if (bic->bfqq[BLK_RW_ASYNC]) { ++ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]); ++ bic->bfqq[BLK_RW_ASYNC] = NULL; ++ } ++ ++ if (bic->bfqq[BLK_RW_SYNC]) { ++ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); ++ bic->bfqq[BLK_RW_SYNC] = NULL; ++ } ++} ++ ++/* ++ * Update the entity prio values; note that the new values will not ++ * be used until the next (re)activation. ++ */ ++static void bfq_init_prio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) ++{ ++ struct task_struct *tsk = current; ++ int ioprio_class; ++ ++ if (!bfq_bfqq_prio_changed(bfqq)) ++ return; ++ ++ ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); ++ switch (ioprio_class) { ++ default: ++ dev_err(bfqq->bfqd->queue->backing_dev_info.dev, ++ "bfq: bad prio class %d\n", ioprio_class); ++ case IOPRIO_CLASS_NONE: ++ /* ++ * No prio set, inherit CPU scheduling settings. ++ */ ++ bfqq->entity.new_ioprio = task_nice_ioprio(tsk); ++ bfqq->entity.new_ioprio_class = task_nice_ioclass(tsk); ++ break; ++ case IOPRIO_CLASS_RT: ++ bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_RT; ++ break; ++ case IOPRIO_CLASS_BE: ++ bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_BE; ++ break; ++ case IOPRIO_CLASS_IDLE: ++ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_IDLE; ++ bfqq->entity.new_ioprio = 7; ++ bfq_clear_bfqq_idle_window(bfqq); ++ break; ++ } ++ ++ if (bfqq->entity.new_ioprio < 0 || ++ bfqq->entity.new_ioprio >= IOPRIO_BE_NR) { ++ printk(KERN_CRIT "bfq_init_prio_data: new_ioprio %d\n", ++ bfqq->entity.new_ioprio); ++ BUG(); ++ } ++ ++ bfqq->entity.ioprio_changed = 1; ++ ++ bfq_clear_bfqq_prio_changed(bfqq); ++} ++ ++static void bfq_changed_ioprio(struct bfq_io_cq *bic) ++{ ++ struct bfq_data *bfqd; ++ struct bfq_queue *bfqq, *new_bfqq; ++ struct bfq_group *bfqg; ++ unsigned long uninitialized_var(flags); ++ int ioprio = bic->icq.ioc->ioprio; ++ ++ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), ++ &flags); ++ /* ++ * This condition may trigger on a newly created bic, be sure to ++ * drop the lock before returning. ++ */ ++ if (unlikely(bfqd == NULL) || likely(bic->ioprio == ioprio)) ++ goto out; ++ ++ bfqq = bic->bfqq[BLK_RW_ASYNC]; ++ if (bfqq != NULL) { ++ bfqg = container_of(bfqq->entity.sched_data, struct bfq_group, ++ sched_data); ++ new_bfqq = bfq_get_queue(bfqd, bfqg, BLK_RW_ASYNC, bic, ++ GFP_ATOMIC); ++ if (new_bfqq != NULL) { ++ bic->bfqq[BLK_RW_ASYNC] = new_bfqq; ++ bfq_log_bfqq(bfqd, bfqq, ++ "changed_ioprio: bfqq %p %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ } ++ } ++ ++ bfqq = bic->bfqq[BLK_RW_SYNC]; ++ if (bfqq != NULL) ++ bfq_mark_bfqq_prio_changed(bfqq); ++ ++ bic->ioprio = ioprio; ++ ++out: ++ bfq_put_bfqd_unlock(bfqd, &flags); ++} ++ ++static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ pid_t pid, int is_sync) ++{ ++ RB_CLEAR_NODE(&bfqq->entity.rb_node); ++ INIT_LIST_HEAD(&bfqq->fifo); ++ INIT_HLIST_NODE(&bfqq->burst_list_node); ++ ++ atomic_set(&bfqq->ref, 0); ++ bfqq->bfqd = bfqd; ++ ++ bfq_mark_bfqq_prio_changed(bfqq); ++ ++ if (is_sync) { ++ if (!bfq_class_idle(bfqq)) ++ bfq_mark_bfqq_idle_window(bfqq); ++ bfq_mark_bfqq_sync(bfqq); ++ } ++ bfq_mark_bfqq_IO_bound(bfqq); ++ ++ /* Tentative initial value to trade off between thr and lat */ ++ bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3; ++ bfqq->pid = pid; ++ ++ bfqq->wr_coeff = 1; ++ bfqq->last_wr_start_finish = 0; ++ /* ++ * Set to the value for which bfqq will not be deemed as ++ * soft rt when it becomes backlogged. ++ */ ++ bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies); ++} ++ ++static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ int is_sync, ++ struct bfq_io_cq *bic, ++ gfp_t gfp_mask) ++{ ++ struct bfq_queue *bfqq, *new_bfqq = NULL; ++ ++retry: ++ /* bic always exists here */ ++ bfqq = bic_to_bfqq(bic, is_sync); ++ ++ /* ++ * Always try a new alloc if we fall back to the OOM bfqq ++ * originally, since it should just be a temporary situation. ++ */ ++ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { ++ bfqq = NULL; ++ if (new_bfqq != NULL) { ++ bfqq = new_bfqq; ++ new_bfqq = NULL; ++ } else if (gfp_mask & __GFP_WAIT) { ++ spin_unlock_irq(bfqd->queue->queue_lock); ++ new_bfqq = kmem_cache_alloc_node(bfq_pool, ++ gfp_mask | __GFP_ZERO, ++ bfqd->queue->node); ++ spin_lock_irq(bfqd->queue->queue_lock); ++ if (new_bfqq != NULL) ++ goto retry; ++ } else { ++ bfqq = kmem_cache_alloc_node(bfq_pool, ++ gfp_mask | __GFP_ZERO, ++ bfqd->queue->node); ++ } ++ ++ if (bfqq != NULL) { ++ bfq_init_bfqq(bfqd, bfqq, current->pid, is_sync); ++ bfq_init_prio_data(bfqq, bic); ++ bfq_init_entity(&bfqq->entity, bfqg); ++ bfq_log_bfqq(bfqd, bfqq, "allocated"); ++ } else { ++ bfqq = &bfqd->oom_bfqq; ++ bfq_log_bfqq(bfqd, bfqq, "using oom bfqq"); ++ } ++ } ++ ++ if (new_bfqq != NULL) ++ kmem_cache_free(bfq_pool, new_bfqq); ++ ++ return bfqq; ++} ++ ++static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ int ioprio_class, int ioprio) ++{ ++ switch (ioprio_class) { ++ case IOPRIO_CLASS_RT: ++ return &bfqg->async_bfqq[0][ioprio]; ++ case IOPRIO_CLASS_NONE: ++ ioprio = IOPRIO_NORM; ++ /* fall through */ ++ case IOPRIO_CLASS_BE: ++ return &bfqg->async_bfqq[1][ioprio]; ++ case IOPRIO_CLASS_IDLE: ++ return &bfqg->async_idle_bfqq; ++ default: ++ BUG(); ++ } ++} ++ ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, int is_sync, ++ struct bfq_io_cq *bic, gfp_t gfp_mask) ++{ ++ const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); ++ struct bfq_queue **async_bfqq = NULL; ++ struct bfq_queue *bfqq = NULL; ++ ++ if (!is_sync) { ++ async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class, ++ ioprio); ++ bfqq = *async_bfqq; ++ } ++ ++ if (bfqq == NULL) ++ bfqq = bfq_find_alloc_queue(bfqd, bfqg, is_sync, bic, gfp_mask); ++ ++ /* ++ * Pin the queue now that it's allocated, scheduler exit will ++ * prune it. ++ */ ++ if (!is_sync && *async_bfqq == NULL) { ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ *async_bfqq = bfqq; ++ } ++ ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ return bfqq; ++} ++ ++static void bfq_update_io_thinktime(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic) ++{ ++ unsigned long elapsed = jiffies - bic->ttime.last_end_request; ++ unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle); ++ ++ bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8; ++ bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8; ++ bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) / ++ bic->ttime.ttime_samples; ++} ++ ++static void bfq_update_io_seektime(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ sector_t sdist; ++ u64 total; ++ ++ if (bfqq->last_request_pos < blk_rq_pos(rq)) ++ sdist = blk_rq_pos(rq) - bfqq->last_request_pos; ++ else ++ sdist = bfqq->last_request_pos - blk_rq_pos(rq); ++ ++ /* ++ * Don't allow the seek distance to get too large from the ++ * odd fragment, pagein, etc. ++ */ ++ if (bfqq->seek_samples == 0) /* first request, not really a seek */ ++ sdist = 0; ++ else if (bfqq->seek_samples <= 60) /* second & third seek */ ++ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024); ++ else ++ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64); ++ ++ bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8; ++ bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8; ++ total = bfqq->seek_total + (bfqq->seek_samples/2); ++ do_div(total, bfqq->seek_samples); ++ bfqq->seek_mean = (sector_t)total; ++ ++ bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist, ++ (u64)bfqq->seek_mean); ++} ++ ++/* ++ * Disable idle window if the process thinks too long or seeks so much that ++ * it doesn't matter. ++ */ ++static void bfq_update_idle_window(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic) ++{ ++ int enable_idle; ++ ++ /* Don't idle for async or idle io prio class. */ ++ if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) ++ return; ++ ++ enable_idle = bfq_bfqq_idle_window(bfqq); ++ ++ if (atomic_read(&bic->icq.ioc->active_ref) == 0 || ++ bfqd->bfq_slice_idle == 0 || ++ (bfqd->hw_tag && BFQQ_SEEKY(bfqq) && ++ bfqq->wr_coeff == 1)) ++ enable_idle = 0; ++ else if (bfq_sample_valid(bic->ttime.ttime_samples)) { ++ if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle && ++ bfqq->wr_coeff == 1) ++ enable_idle = 0; ++ else ++ enable_idle = 1; ++ } ++ bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d", ++ enable_idle); ++ ++ if (enable_idle) ++ bfq_mark_bfqq_idle_window(bfqq); ++ else ++ bfq_clear_bfqq_idle_window(bfqq); ++} ++ ++/* ++ * Called when a new fs request (rq) is added to bfqq. Check if there's ++ * something we should do about it. ++ */ ++static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ struct bfq_io_cq *bic = RQ_BIC(rq); ++ ++ if (rq->cmd_flags & REQ_META) ++ bfqq->meta_pending++; ++ ++ bfq_update_io_thinktime(bfqd, bic); ++ bfq_update_io_seektime(bfqd, bfqq, rq); ++ if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) { ++ bfq_clear_bfqq_constantly_seeky(bfqq); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ BUG_ON(!bfqd->const_seeky_busy_in_flight_queues); ++ bfqd->const_seeky_busy_in_flight_queues--; ++ } ++ } ++ if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || ++ !BFQQ_SEEKY(bfqq)) ++ bfq_update_idle_window(bfqd, bfqq, bic); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", ++ bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq), ++ (long long unsigned)bfqq->seek_mean); ++ ++ bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ ++ if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) { ++ int small_req = bfqq->queued[rq_is_sync(rq)] == 1 && ++ blk_rq_sectors(rq) < 32; ++ int budget_timeout = bfq_bfqq_budget_timeout(bfqq); ++ ++ /* ++ * There is just this request queued: if the request ++ * is small and the queue is not to be expired, then ++ * just exit. ++ * ++ * In this way, if the disk is being idled to wait for ++ * a new request from the in-service queue, we avoid ++ * unplugging the device and committing the disk to serve ++ * just a small request. On the contrary, we wait for ++ * the block layer to decide when to unplug the device: ++ * hopefully, new requests will be merged to this one ++ * quickly, then the device will be unplugged and ++ * larger requests will be dispatched. ++ */ ++ if (small_req && !budget_timeout) ++ return; ++ ++ /* ++ * A large enough request arrived, or the queue is to ++ * be expired: in both cases disk idling is to be ++ * stopped, so clear wait_request flag and reset ++ * timer. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ del_timer(&bfqd->idle_slice_timer); ++ ++ /* ++ * The queue is not empty, because a new request just ++ * arrived. Hence we can safely expire the queue, in ++ * case of budget timeout, without risking that the ++ * timestamps of the queue are not updated correctly. ++ * See [1] for more details. ++ */ ++ if (budget_timeout) ++ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); ++ ++ /* ++ * Let the request rip immediately, or let a new queue be ++ * selected if bfqq has just been expired. ++ */ ++ __blk_run_queue(bfqd->queue); ++ } ++} ++ ++static void bfq_insert_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ bfq_init_prio_data(bfqq, RQ_BIC(rq)); ++ ++ bfq_add_request(rq); ++ ++ rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]; ++ list_add_tail(&rq->queuelist, &bfqq->fifo); ++ ++ bfq_rq_enqueued(bfqd, bfqq, rq); ++} ++ ++static void bfq_update_hw_tag(struct bfq_data *bfqd) ++{ ++ bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver, ++ bfqd->rq_in_driver); ++ ++ if (bfqd->hw_tag == 1) ++ return; ++ ++ /* ++ * This sample is valid if the number of outstanding requests ++ * is large enough to allow a queueing behavior. Note that the ++ * sum is not exact, as it's not taking into account deactivated ++ * requests. ++ */ ++ if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD) ++ return; ++ ++ if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES) ++ return; ++ ++ bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD; ++ bfqd->max_rq_in_driver = 0; ++ bfqd->hw_tag_samples = 0; ++} ++ ++static void bfq_completed_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ bool sync = bfq_bfqq_sync(bfqq); ++ ++ bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)", ++ blk_rq_sectors(rq), sync); ++ ++ bfq_update_hw_tag(bfqd); ++ ++ BUG_ON(!bfqd->rq_in_driver); ++ BUG_ON(!bfqq->dispatched); ++ bfqd->rq_in_driver--; ++ bfqq->dispatched--; ++ ++ if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) { ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ BUG_ON(!bfqd->busy_in_flight_queues); ++ bfqd->busy_in_flight_queues--; ++ if (bfq_bfqq_constantly_seeky(bfqq)) { ++ BUG_ON(!bfqd-> ++ const_seeky_busy_in_flight_queues); ++ bfqd->const_seeky_busy_in_flight_queues--; ++ } ++ } ++ } ++ ++ if (sync) { ++ bfqd->sync_flight--; ++ RQ_BIC(rq)->ttime.last_end_request = jiffies; ++ } ++ ++ /* ++ * If we are waiting to discover whether the request pattern of the ++ * task associated with the queue is actually isochronous, and ++ * both requisites for this condition to hold are satisfied, then ++ * compute soft_rt_next_start (see the comments to the function ++ * bfq_bfqq_softrt_next_start()). ++ */ ++ if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ ++ /* ++ * If this is the in-service queue, check if it needs to be expired, ++ * or if we want to idle in case it has no pending requests. ++ */ ++ if (bfqd->in_service_queue == bfqq) { ++ if (bfq_bfqq_budget_new(bfqq)) ++ bfq_set_budget_timeout(bfqd); ++ ++ if (bfq_bfqq_must_idle(bfqq)) { ++ bfq_arm_slice_timer(bfqd); ++ goto out; ++ } else if (bfq_may_expire_for_budg_timeout(bfqq)) ++ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); ++ else if (RB_EMPTY_ROOT(&bfqq->sort_list) && ++ (bfqq->dispatched == 0 || ++ !bfq_bfqq_must_not_expire(bfqq))) ++ bfq_bfqq_expire(bfqd, bfqq, 0, ++ BFQ_BFQQ_NO_MORE_REQUESTS); ++ } ++ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ ++out: ++ return; ++} ++ ++static inline int __bfq_may_queue(struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) { ++ bfq_clear_bfqq_must_alloc(bfqq); ++ return ELV_MQUEUE_MUST; ++ } ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++static int bfq_may_queue(struct request_queue *q, int rw) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ /* ++ * Don't force setup of a queue from here, as a call to may_queue ++ * does not necessarily imply that a request actually will be ++ * queued. So just lookup a possibly existing queue, or return ++ * 'may queue' if that fails. ++ */ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (bic == NULL) ++ return ELV_MQUEUE_MAY; ++ ++ bfqq = bic_to_bfqq(bic, rw_is_sync(rw)); ++ if (bfqq != NULL) { ++ bfq_init_prio_data(bfqq, bic); ++ ++ return __bfq_may_queue(bfqq); ++ } ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++/* ++ * Queue lock held here. ++ */ ++static void bfq_put_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ if (bfqq != NULL) { ++ const int rw = rq_data_dir(rq); ++ ++ BUG_ON(!bfqq->allocated[rw]); ++ bfqq->allocated[rw]--; ++ ++ rq->elv.priv[0] = NULL; ++ rq->elv.priv[1] = NULL; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++static struct bfq_queue * ++bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", ++ (long unsigned)bfqq->new_bfqq->pid); ++ bic_set_bfqq(bic, bfqq->new_bfqq, 1); ++ bfq_mark_bfqq_coop(bfqq->new_bfqq); ++ bfq_put_queue(bfqq); ++ return bic_to_bfqq(bic, 1); ++} ++ ++/* ++ * Returns NULL if a new bfqq should be allocated, or the old bfqq if this ++ * was the last process referring to said bfqq. ++ */ ++static struct bfq_queue * ++bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); ++ if (bfqq_process_refs(bfqq) == 1) { ++ bfqq->pid = current->pid; ++ bfq_clear_bfqq_coop(bfqq); ++ bfq_clear_bfqq_split_coop(bfqq); ++ return bfqq; ++ } ++ ++ bic_set_bfqq(bic, NULL, 1); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++ return NULL; ++} ++ ++/* ++ * Allocate bfq data structures associated with this request. ++ */ ++static int bfq_set_request(struct request_queue *q, struct request *rq, ++ struct bio *bio, gfp_t gfp_mask) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq); ++ const int rw = rq_data_dir(rq); ++ const int is_sync = rq_is_sync(rq); ++ struct bfq_queue *bfqq; ++ struct bfq_group *bfqg; ++ unsigned long flags; ++ ++ might_sleep_if(gfp_mask & __GFP_WAIT); ++ ++ bfq_changed_ioprio(bic); ++ ++ spin_lock_irqsave(q->queue_lock, flags); ++ ++ if (bic == NULL) ++ goto queue_fail; ++ ++ bfqg = bfq_bic_update_cgroup(bic); ++ ++new_queue: ++ bfqq = bic_to_bfqq(bic, is_sync); ++ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { ++ bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask); ++ bic_set_bfqq(bic, bfqq, is_sync); ++ } else { ++ /* ++ * If the queue was seeky for too long, break it apart. ++ */ ++ if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { ++ bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); ++ bfqq = bfq_split_bfqq(bic, bfqq); ++ if (!bfqq) ++ goto new_queue; ++ } ++ ++ /* ++ * Check to see if this queue is scheduled to merge with ++ * another closely cooperating queue. The merging of queues ++ * happens here as it must be done in process context. ++ * The reference on new_bfqq was taken in merge_bfqqs. ++ */ ++ if (bfqq->new_bfqq != NULL) ++ bfqq = bfq_merge_bfqqs(bfqd, bic, bfqq); ++ } ++ ++ bfqq->allocated[rw]++; ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ ++ rq->elv.priv[0] = bic; ++ rq->elv.priv[1] = bfqq; ++ ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 0; ++ ++queue_fail: ++ bfq_schedule_dispatch(bfqd); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 1; ++} ++ ++static void bfq_kick_queue(struct work_struct *work) ++{ ++ struct bfq_data *bfqd = ++ container_of(work, struct bfq_data, unplug_work); ++ struct request_queue *q = bfqd->queue; ++ ++ spin_lock_irq(q->queue_lock); ++ __blk_run_queue(q); ++ spin_unlock_irq(q->queue_lock); ++} ++ ++/* ++ * Handler of the expiration of the timer running if the in-service queue ++ * is idling inside its time slice. ++ */ ++static void bfq_idle_slice_timer(unsigned long data) ++{ ++ struct bfq_data *bfqd = (struct bfq_data *)data; ++ struct bfq_queue *bfqq; ++ unsigned long flags; ++ enum bfqq_expiration reason; ++ ++ spin_lock_irqsave(bfqd->queue->queue_lock, flags); ++ ++ bfqq = bfqd->in_service_queue; ++ /* ++ * Theoretical race here: the in-service queue can be NULL or ++ * different from the queue that was idling if the timer handler ++ * spins on the queue_lock and a new request arrives for the ++ * current queue and there is a full dispatch cycle that changes ++ * the in-service queue. This can hardly happen, but in the worst ++ * case we just expire a queue too early. ++ */ ++ if (bfqq != NULL) { ++ bfq_log_bfqq(bfqd, bfqq, "slice_timer expired"); ++ if (bfq_bfqq_budget_timeout(bfqq)) ++ /* ++ * Also here the queue can be safely expired ++ * for budget timeout without wasting ++ * guarantees ++ */ ++ reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0) ++ /* ++ * The queue may not be empty upon timer expiration, ++ * because we may not disable the timer when the ++ * first request of the in-service queue arrives ++ * during disk idling. ++ */ ++ reason = BFQ_BFQQ_TOO_IDLE; ++ else ++ goto schedule_dispatch; ++ ++ bfq_bfqq_expire(bfqd, bfqq, 1, reason); ++ } ++ ++schedule_dispatch: ++ bfq_schedule_dispatch(bfqd); ++ ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, flags); ++} ++ ++static void bfq_shutdown_timer_wq(struct bfq_data *bfqd) ++{ ++ del_timer_sync(&bfqd->idle_slice_timer); ++ cancel_work_sync(&bfqd->unplug_work); ++} ++ ++static inline void __bfq_put_async_bfqq(struct bfq_data *bfqd, ++ struct bfq_queue **bfqq_ptr) ++{ ++ struct bfq_group *root_group = bfqd->root_group; ++ struct bfq_queue *bfqq = *bfqq_ptr; ++ ++ bfq_log(bfqd, "put_async_bfqq: %p", bfqq); ++ if (bfqq != NULL) { ++ bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group); ++ bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ *bfqq_ptr = NULL; ++ } ++} ++ ++/* ++ * Release all the bfqg references to its async queues. If we are ++ * deallocating the group these queues may still contain requests, so ++ * we reparent them to the root cgroup (i.e., the only one that will ++ * exist for sure until all the requests on a device are gone). ++ */ ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]); ++ ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq); ++} ++ ++static void bfq_exit_queue(struct elevator_queue *e) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ struct request_queue *q = bfqd->queue; ++ struct bfq_queue *bfqq, *n; ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ spin_lock_irq(q->queue_lock); ++ ++ BUG_ON(bfqd->in_service_queue != NULL); ++ list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ ++ bfq_disconnect_groups(bfqd); ++ spin_unlock_irq(q->queue_lock); ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ synchronize_rcu(); ++ ++ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); ++ ++ bfq_free_root_group(bfqd); ++ kfree(bfqd); ++} ++ ++static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) ++{ ++ struct bfq_group *bfqg; ++ struct bfq_data *bfqd; ++ struct elevator_queue *eq; ++ ++ eq = elevator_alloc(q, e); ++ if (eq == NULL) ++ return -ENOMEM; ++ ++ bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node); ++ if (bfqd == NULL) { ++ kobject_put(&eq->kobj); ++ return -ENOMEM; ++ } ++ eq->elevator_data = bfqd; ++ ++ /* ++ * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues. ++ * Grab a permanent reference to it, so that the normal code flow ++ * will not attempt to free it. ++ */ ++ bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, 1, 0); ++ atomic_inc(&bfqd->oom_bfqq.ref); ++ bfqd->oom_bfqq.entity.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO; ++ bfqd->oom_bfqq.entity.new_ioprio_class = IOPRIO_CLASS_BE; ++ /* ++ * Trigger weight initialization, according to ioprio, at the ++ * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio ++ * class won't be changed any more. ++ */ ++ bfqd->oom_bfqq.entity.ioprio_changed = 1; ++ ++ bfqd->queue = q; ++ ++ spin_lock_irq(q->queue_lock); ++ q->elevator = eq; ++ spin_unlock_irq(q->queue_lock); ++ ++ bfqg = bfq_alloc_root_group(bfqd, q->node); ++ if (bfqg == NULL) { ++ kfree(bfqd); ++ kobject_put(&eq->kobj); ++ return -ENOMEM; ++ } ++ ++ bfqd->root_group = bfqg; ++ bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); ++#ifdef CONFIG_CGROUP_BFQIO ++ bfqd->active_numerous_groups = 0; ++#endif ++ ++ init_timer(&bfqd->idle_slice_timer); ++ bfqd->idle_slice_timer.function = bfq_idle_slice_timer; ++ bfqd->idle_slice_timer.data = (unsigned long)bfqd; ++ ++ bfqd->rq_pos_tree = RB_ROOT; ++ bfqd->queue_weights_tree = RB_ROOT; ++ bfqd->group_weights_tree = RB_ROOT; ++ ++ INIT_WORK(&bfqd->unplug_work, bfq_kick_queue); ++ ++ INIT_LIST_HEAD(&bfqd->active_list); ++ INIT_LIST_HEAD(&bfqd->idle_list); ++ INIT_HLIST_HEAD(&bfqd->burst_list); ++ ++ bfqd->hw_tag = -1; ++ ++ bfqd->bfq_max_budget = bfq_default_max_budget; ++ ++ bfqd->bfq_quantum = bfq_quantum; ++ bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0]; ++ bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1]; ++ bfqd->bfq_back_max = bfq_back_max; ++ bfqd->bfq_back_penalty = bfq_back_penalty; ++ bfqd->bfq_slice_idle = bfq_slice_idle; ++ bfqd->bfq_class_idle_last_service = 0; ++ bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq; ++ bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async; ++ bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync; ++ ++ bfqd->bfq_coop_thresh = 2; ++ bfqd->bfq_failed_cooperations = 7000; ++ bfqd->bfq_requests_within_timer = 120; ++ ++ bfqd->bfq_large_burst_thresh = 11; ++ bfqd->bfq_burst_interval = msecs_to_jiffies(500); ++ ++ bfqd->low_latency = true; ++ ++ bfqd->bfq_wr_coeff = 20; ++ bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300); ++ bfqd->bfq_wr_max_time = 0; ++ bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000); ++ bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500); ++ bfqd->bfq_wr_max_softrt_rate = 7000; /* ++ * Approximate rate required ++ * to playback or record a ++ * high-definition compressed ++ * video. ++ */ ++ bfqd->wr_busy_queues = 0; ++ bfqd->busy_in_flight_queues = 0; ++ bfqd->const_seeky_busy_in_flight_queues = 0; ++ ++ /* ++ * Begin by assuming, optimistically, that the device peak rate is ++ * equal to the highest reference rate. ++ */ ++ bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] * ++ T_fast[blk_queue_nonrot(bfqd->queue)]; ++ bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)]; ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ ++ return 0; ++} ++ ++static void bfq_slab_kill(void) ++{ ++ if (bfq_pool != NULL) ++ kmem_cache_destroy(bfq_pool); ++} ++ ++static int __init bfq_slab_setup(void) ++{ ++ bfq_pool = KMEM_CACHE(bfq_queue, 0); ++ if (bfq_pool == NULL) ++ return -ENOMEM; ++ return 0; ++} ++ ++static ssize_t bfq_var_show(unsigned int var, char *page) ++{ ++ return sprintf(page, "%d\n", var); ++} ++ ++static ssize_t bfq_var_store(unsigned long *var, const char *page, ++ size_t count) ++{ ++ unsigned long new_val; ++ int ret = kstrtoul(page, 10, &new_val); ++ ++ if (ret == 0) ++ *var = new_val; ++ ++ return count; ++} ++ ++static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ? ++ jiffies_to_msecs(bfqd->bfq_wr_max_time) : ++ jiffies_to_msecs(bfq_wr_duration(bfqd))); ++} ++ ++static ssize_t bfq_weights_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_queue *bfqq; ++ struct bfq_data *bfqd = e->elevator_data; ++ ssize_t num_char = 0; ++ ++ num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n", ++ bfqd->queued); ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ num_char += sprintf(page + num_char, "Active:\n"); ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, nr_queued %d %d, dur %d/%u\n", ++ bfqq->pid, ++ bfqq->entity.weight, ++ bfqq->queued[0], ++ bfqq->queued[1], ++ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ num_char += sprintf(page + num_char, "Idle:\n"); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, dur %d/%u\n", ++ bfqq->pid, ++ bfqq->entity.weight, ++ jiffies_to_msecs(jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++ ++ return num_char; ++} ++ ++#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ ++static ssize_t __FUNC(struct elevator_queue *e, char *page) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned int __data = __VAR; \ ++ if (__CONV) \ ++ __data = jiffies_to_msecs(__data); \ ++ return bfq_var_show(__data, (page)); \ ++} ++SHOW_FUNCTION(bfq_quantum_show, bfqd->bfq_quantum, 0); ++SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1); ++SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1); ++SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0); ++SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0); ++SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1); ++SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0); ++SHOW_FUNCTION(bfq_max_budget_async_rq_show, ++ bfqd->bfq_max_budget_async_rq, 0); ++SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1); ++SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1); ++SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0); ++SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0); ++SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1); ++SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1); ++SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async, ++ 1); ++SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0); ++#undef SHOW_FUNCTION ++ ++#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ ++static ssize_t \ ++__FUNC(struct elevator_queue *e, const char *page, size_t count) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned long uninitialized_var(__data); \ ++ int ret = bfq_var_store(&__data, (page), count); \ ++ if (__data < (MIN)) \ ++ __data = (MIN); \ ++ else if (__data > (MAX)) \ ++ __data = (MAX); \ ++ if (__CONV) \ ++ *(__PTR) = msecs_to_jiffies(__data); \ ++ else \ ++ *(__PTR) = __data; \ ++ return ret; \ ++} ++STORE_FUNCTION(bfq_quantum_store, &bfqd->bfq_quantum, 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0); ++STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1, ++ INT_MAX, 0); ++STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq, ++ 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX, ++ 1); ++STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_min_inter_arr_async_store, ++ &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0, ++ INT_MAX, 0); ++#undef STORE_FUNCTION ++ ++/* do nothing for the moment */ ++static ssize_t bfq_weights_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ return count; ++} ++ ++static inline unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd) ++{ ++ u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); ++ ++ if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES) ++ return bfq_calc_max_budget(bfqd->peak_rate, timeout); ++ else ++ return bfq_default_max_budget; ++} ++ ++static ssize_t bfq_max_budget_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data == 0) ++ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); ++ else { ++ if (__data > INT_MAX) ++ __data = INT_MAX; ++ bfqd->bfq_max_budget = __data; ++ } ++ ++ bfqd->bfq_user_max_budget = __data; ++ ++ return ret; ++} ++ ++static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data < 1) ++ __data = 1; ++ else if (__data > INT_MAX) ++ __data = INT_MAX; ++ ++ bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data); ++ if (bfqd->bfq_user_max_budget == 0) ++ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); ++ ++ return ret; ++} ++ ++static ssize_t bfq_low_latency_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data > 1) ++ __data = 1; ++ if (__data == 0 && bfqd->low_latency != 0) ++ bfq_end_wr(bfqd); ++ bfqd->low_latency = __data; ++ ++ return ret; ++} ++ ++#define BFQ_ATTR(name) \ ++ __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store) ++ ++static struct elv_fs_entry bfq_attrs[] = { ++ BFQ_ATTR(quantum), ++ BFQ_ATTR(fifo_expire_sync), ++ BFQ_ATTR(fifo_expire_async), ++ BFQ_ATTR(back_seek_max), ++ BFQ_ATTR(back_seek_penalty), ++ BFQ_ATTR(slice_idle), ++ BFQ_ATTR(max_budget), ++ BFQ_ATTR(max_budget_async_rq), ++ BFQ_ATTR(timeout_sync), ++ BFQ_ATTR(timeout_async), ++ BFQ_ATTR(low_latency), ++ BFQ_ATTR(wr_coeff), ++ BFQ_ATTR(wr_max_time), ++ BFQ_ATTR(wr_rt_max_time), ++ BFQ_ATTR(wr_min_idle_time), ++ BFQ_ATTR(wr_min_inter_arr_async), ++ BFQ_ATTR(wr_max_softrt_rate), ++ BFQ_ATTR(weights), ++ __ATTR_NULL ++}; ++ ++static struct elevator_type iosched_bfq = { ++ .ops = { ++ .elevator_merge_fn = bfq_merge, ++ .elevator_merged_fn = bfq_merged_request, ++ .elevator_merge_req_fn = bfq_merged_requests, ++ .elevator_allow_merge_fn = bfq_allow_merge, ++ .elevator_dispatch_fn = bfq_dispatch_requests, ++ .elevator_add_req_fn = bfq_insert_request, ++ .elevator_activate_req_fn = bfq_activate_request, ++ .elevator_deactivate_req_fn = bfq_deactivate_request, ++ .elevator_completed_req_fn = bfq_completed_request, ++ .elevator_former_req_fn = elv_rb_former_request, ++ .elevator_latter_req_fn = elv_rb_latter_request, ++ .elevator_init_icq_fn = bfq_init_icq, ++ .elevator_exit_icq_fn = bfq_exit_icq, ++ .elevator_set_req_fn = bfq_set_request, ++ .elevator_put_req_fn = bfq_put_request, ++ .elevator_may_queue_fn = bfq_may_queue, ++ .elevator_init_fn = bfq_init_queue, ++ .elevator_exit_fn = bfq_exit_queue, ++ }, ++ .icq_size = sizeof(struct bfq_io_cq), ++ .icq_align = __alignof__(struct bfq_io_cq), ++ .elevator_attrs = bfq_attrs, ++ .elevator_name = "bfq", ++ .elevator_owner = THIS_MODULE, ++}; ++ ++static int __init bfq_init(void) ++{ ++ /* ++ * Can be 0 on HZ < 1000 setups. ++ */ ++ if (bfq_slice_idle == 0) ++ bfq_slice_idle = 1; ++ ++ if (bfq_timeout_async == 0) ++ bfq_timeout_async = 1; ++ ++ if (bfq_slab_setup()) ++ return -ENOMEM; ++ ++ /* ++ * Times to load large popular applications for the typical systems ++ * installed on the reference devices (see the comments before the ++ * definitions of the two arrays). ++ */ ++ T_slow[0] = msecs_to_jiffies(2600); ++ T_slow[1] = msecs_to_jiffies(1000); ++ T_fast[0] = msecs_to_jiffies(5500); ++ T_fast[1] = msecs_to_jiffies(2000); ++ ++ /* ++ * Thresholds that determine the switch between speed classes (see ++ * the comments before the definition of the array). ++ */ ++ device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2; ++ device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2; ++ ++ elv_register(&iosched_bfq); ++ pr_info("BFQ I/O-scheduler version: v7r7"); ++ ++ return 0; ++} ++ ++static void __exit bfq_exit(void) ++{ ++ elv_unregister(&iosched_bfq); ++ bfq_slab_kill(); ++} ++ ++module_init(bfq_init); ++module_exit(bfq_exit); ++ ++MODULE_AUTHOR("Fabio Checconi, Paolo Valente"); ++MODULE_LICENSE("GPL"); +diff --git a/block/bfq-sched.c b/block/bfq-sched.c +new file mode 100644 +index 0000000..2931563 +--- /dev/null ++++ b/block/bfq-sched.c +@@ -0,0 +1,1214 @@ ++/* ++ * BFQ: Hierarchical B-WF2Q+ scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++#ifdef CONFIG_CGROUP_BFQIO ++#define for_each_entity(entity) \ ++ for (; entity != NULL; entity = entity->parent) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (; entity && ({ parent = entity->parent; 1; }); entity = parent) ++ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd); ++ ++static inline void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++ struct bfq_entity *bfqg_entity; ++ struct bfq_group *bfqg; ++ struct bfq_sched_data *group_sd; ++ ++ BUG_ON(next_in_service == NULL); ++ ++ group_sd = next_in_service->sched_data; ++ ++ bfqg = container_of(group_sd, struct bfq_group, sched_data); ++ /* ++ * bfq_group's my_entity field is not NULL only if the group ++ * is not the root group. We must not touch the root entity ++ * as it must never become an in-service entity. ++ */ ++ bfqg_entity = bfqg->my_entity; ++ if (bfqg_entity != NULL) ++ bfqg_entity->budget = next_in_service->budget; ++} ++ ++static int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ struct bfq_entity *next_in_service; ++ ++ if (sd->in_service_entity != NULL) ++ /* will update/requeue at the end of service */ ++ return 0; ++ ++ /* ++ * NOTE: this can be improved in many ways, such as returning ++ * 1 (and thus propagating upwards the update) only when the ++ * budget changes, or caching the bfqq that will be scheduled ++ * next from this subtree. By now we worry more about ++ * correctness than about performance... ++ */ ++ next_in_service = bfq_lookup_next_entity(sd, 0, NULL); ++ sd->next_in_service = next_in_service; ++ ++ if (next_in_service != NULL) ++ bfq_update_budget(next_in_service); ++ ++ return 1; ++} ++ ++static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++ BUG_ON(sd->next_in_service != entity); ++} ++#else ++#define for_each_entity(entity) \ ++ for (; entity != NULL; entity = NULL) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (parent = NULL; entity != NULL; entity = parent) ++ ++static inline int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ return 0; ++} ++ ++static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++} ++ ++static inline void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++} ++#endif ++ ++/* ++ * Shift for timestamp calculations. This actually limits the maximum ++ * service allowed in one timestamp delta (small shift values increase it), ++ * the maximum total weight that can be used for the queues in the system ++ * (big shift values increase it), and the period of virtual time ++ * wraparounds. ++ */ ++#define WFQ_SERVICE_SHIFT 22 ++ ++/** ++ * bfq_gt - compare two timestamps. ++ * @a: first ts. ++ * @b: second ts. ++ * ++ * Return @a > @b, dealing with wrapping correctly. ++ */ ++static inline int bfq_gt(u64 a, u64 b) ++{ ++ return (s64)(a - b) > 0; ++} ++ ++static inline struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = NULL; ++ ++ BUG_ON(entity == NULL); ++ ++ if (entity->my_sched_data == NULL) ++ bfqq = container_of(entity, struct bfq_queue, entity); ++ ++ return bfqq; ++} ++ ++ ++/** ++ * bfq_delta - map service into the virtual time domain. ++ * @service: amount of service. ++ * @weight: scale factor (weight of an entity or weight sum). ++ */ ++static inline u64 bfq_delta(unsigned long service, ++ unsigned long weight) ++{ ++ u64 d = (u64)service << WFQ_SERVICE_SHIFT; ++ ++ do_div(d, weight); ++ return d; ++} ++ ++/** ++ * bfq_calc_finish - assign the finish time to an entity. ++ * @entity: the entity to act upon. ++ * @service: the service to be charged to the entity. ++ */ ++static inline void bfq_calc_finish(struct bfq_entity *entity, ++ unsigned long service) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ BUG_ON(entity->weight == 0); ++ ++ entity->finish = entity->start + ++ bfq_delta(service, entity->weight); ++ ++ if (bfqq != NULL) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: serv %lu, w %d", ++ service, entity->weight); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: start %llu, finish %llu, delta %llu", ++ entity->start, entity->finish, ++ bfq_delta(service, entity->weight)); ++ } ++} ++ ++/** ++ * bfq_entity_of - get an entity from a node. ++ * @node: the node field of the entity. ++ * ++ * Convert a node pointer to the relative entity. This is used only ++ * to simplify the logic of some functions and not as the generic ++ * conversion mechanism because, e.g., in the tree walking functions, ++ * the check for a %NULL value would be redundant. ++ */ ++static inline struct bfq_entity *bfq_entity_of(struct rb_node *node) ++{ ++ struct bfq_entity *entity = NULL; ++ ++ if (node != NULL) ++ entity = rb_entry(node, struct bfq_entity, rb_node); ++ ++ return entity; ++} ++ ++/** ++ * bfq_extract - remove an entity from a tree. ++ * @root: the tree root. ++ * @entity: the entity to remove. ++ */ ++static inline void bfq_extract(struct rb_root *root, ++ struct bfq_entity *entity) ++{ ++ BUG_ON(entity->tree != root); ++ ++ entity->tree = NULL; ++ rb_erase(&entity->rb_node, root); ++} ++ ++/** ++ * bfq_idle_extract - extract an entity from the idle tree. ++ * @st: the service tree of the owning @entity. ++ * @entity: the entity being removed. ++ */ ++static void bfq_idle_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *next; ++ ++ BUG_ON(entity->tree != &st->idle); ++ ++ if (entity == st->first_idle) { ++ next = rb_next(&entity->rb_node); ++ st->first_idle = bfq_entity_of(next); ++ } ++ ++ if (entity == st->last_idle) { ++ next = rb_prev(&entity->rb_node); ++ st->last_idle = bfq_entity_of(next); ++ } ++ ++ bfq_extract(&st->idle, entity); ++ ++ if (bfqq != NULL) ++ list_del(&bfqq->bfqq_list); ++} ++ ++/** ++ * bfq_insert - generic tree insertion. ++ * @root: tree root. ++ * @entity: entity to insert. ++ * ++ * This is used for the idle and the active tree, since they are both ++ * ordered by finish time. ++ */ ++static void bfq_insert(struct rb_root *root, struct bfq_entity *entity) ++{ ++ struct bfq_entity *entry; ++ struct rb_node **node = &root->rb_node; ++ struct rb_node *parent = NULL; ++ ++ BUG_ON(entity->tree != NULL); ++ ++ while (*node != NULL) { ++ parent = *node; ++ entry = rb_entry(parent, struct bfq_entity, rb_node); ++ ++ if (bfq_gt(entry->finish, entity->finish)) ++ node = &parent->rb_left; ++ else ++ node = &parent->rb_right; ++ } ++ ++ rb_link_node(&entity->rb_node, parent, node); ++ rb_insert_color(&entity->rb_node, root); ++ ++ entity->tree = root; ++} ++ ++/** ++ * bfq_update_min - update the min_start field of a entity. ++ * @entity: the entity to update. ++ * @node: one of its children. ++ * ++ * This function is called when @entity may store an invalid value for ++ * min_start due to updates to the active tree. The function assumes ++ * that the subtree rooted at @node (which may be its left or its right ++ * child) has a valid min_start value. ++ */ ++static inline void bfq_update_min(struct bfq_entity *entity, ++ struct rb_node *node) ++{ ++ struct bfq_entity *child; ++ ++ if (node != NULL) { ++ child = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entity->min_start, child->min_start)) ++ entity->min_start = child->min_start; ++ } ++} ++ ++/** ++ * bfq_update_active_node - recalculate min_start. ++ * @node: the node to update. ++ * ++ * @node may have changed position or one of its children may have moved, ++ * this function updates its min_start value. The left and right subtrees ++ * are assumed to hold a correct min_start value. ++ */ ++static inline void bfq_update_active_node(struct rb_node *node) ++{ ++ struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node); ++ ++ entity->min_start = entity->start; ++ bfq_update_min(entity, node->rb_right); ++ bfq_update_min(entity, node->rb_left); ++} ++ ++/** ++ * bfq_update_active_tree - update min_start for the whole active tree. ++ * @node: the starting node. ++ * ++ * @node must be the deepest modified node after an update. This function ++ * updates its min_start using the values held by its children, assuming ++ * that they did not change, and then updates all the nodes that may have ++ * changed in the path to the root. The only nodes that may have changed ++ * are the ones in the path or their siblings. ++ */ ++static void bfq_update_active_tree(struct rb_node *node) ++{ ++ struct rb_node *parent; ++ ++up: ++ bfq_update_active_node(node); ++ ++ parent = rb_parent(node); ++ if (parent == NULL) ++ return; ++ ++ if (node == parent->rb_left && parent->rb_right != NULL) ++ bfq_update_active_node(parent->rb_right); ++ else if (parent->rb_left != NULL) ++ bfq_update_active_node(parent->rb_left); ++ ++ node = parent; ++ goto up; ++} ++ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++ ++/** ++ * bfq_active_insert - insert an entity in the active tree of its ++ * group/device. ++ * @st: the service tree of the entity. ++ * @entity: the entity being inserted. ++ * ++ * The active tree is ordered by finish time, but an extra key is kept ++ * per each node, containing the minimum value for the start times of ++ * its children (and the node itself), so it's possible to search for ++ * the eligible node with the lowest finish time in logarithmic time. ++ */ ++static void bfq_active_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node = &entity->rb_node; ++#ifdef CONFIG_CGROUP_BFQIO ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ bfq_insert(&st->active, entity); ++ ++ if (node->rb_left != NULL) ++ node = node->rb_left; ++ else if (node->rb_right != NULL) ++ node = node->rb_right; ++ ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq != NULL) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list); ++#ifdef CONFIG_CGROUP_BFQIO ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ bfqg->active_entities++; ++ if (bfqg->active_entities == 2) ++ bfqd->active_numerous_groups++; ++ } ++#endif ++} ++ ++/** ++ * bfq_ioprio_to_weight - calc a weight from an ioprio. ++ * @ioprio: the ioprio value to convert. ++ */ ++static inline unsigned short bfq_ioprio_to_weight(int ioprio) ++{ ++ BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR); ++ return IOPRIO_BE_NR - ioprio; ++} ++ ++/** ++ * bfq_weight_to_ioprio - calc an ioprio from a weight. ++ * @weight: the weight value to convert. ++ * ++ * To preserve as mush as possible the old only-ioprio user interface, ++ * 0 is used as an escape ioprio value for weights (numerically) equal or ++ * larger than IOPRIO_BE_NR ++ */ ++static inline unsigned short bfq_weight_to_ioprio(int weight) ++{ ++ BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT); ++ return IOPRIO_BE_NR - weight < 0 ? 0 : IOPRIO_BE_NR - weight; ++} ++ ++static inline void bfq_get_entity(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ if (bfqq != NULL) { ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ } ++} ++ ++/** ++ * bfq_find_deepest - find the deepest node that an extraction can modify. ++ * @node: the node being removed. ++ * ++ * Do the first step of an extraction in an rb tree, looking for the ++ * node that will replace @node, and returning the deepest node that ++ * the following modifications to the tree can touch. If @node is the ++ * last node in the tree return %NULL. ++ */ ++static struct rb_node *bfq_find_deepest(struct rb_node *node) ++{ ++ struct rb_node *deepest; ++ ++ if (node->rb_right == NULL && node->rb_left == NULL) ++ deepest = rb_parent(node); ++ else if (node->rb_right == NULL) ++ deepest = node->rb_left; ++ else if (node->rb_left == NULL) ++ deepest = node->rb_right; ++ else { ++ deepest = rb_next(node); ++ if (deepest->rb_right != NULL) ++ deepest = deepest->rb_right; ++ else if (rb_parent(deepest) != node) ++ deepest = rb_parent(deepest); ++ } ++ ++ return deepest; ++} ++ ++/** ++ * bfq_active_extract - remove an entity from the active tree. ++ * @st: the service_tree containing the tree. ++ * @entity: the entity being removed. ++ */ ++static void bfq_active_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node; ++#ifdef CONFIG_CGROUP_BFQIO ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ node = bfq_find_deepest(&entity->rb_node); ++ bfq_extract(&st->active, entity); ++ ++ if (node != NULL) ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq != NULL) ++ list_del(&bfqq->bfqq_list); ++#ifdef CONFIG_CGROUP_BFQIO ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_remove(bfqd, entity, ++ &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ BUG_ON(!bfqg->active_entities); ++ bfqg->active_entities--; ++ if (bfqg->active_entities == 1) { ++ BUG_ON(!bfqd->active_numerous_groups); ++ bfqd->active_numerous_groups--; ++ } ++ } ++#endif ++} ++ ++/** ++ * bfq_idle_insert - insert an entity into the idle tree. ++ * @st: the service tree containing the tree. ++ * @entity: the entity to insert. ++ */ ++static void bfq_idle_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (first_idle == NULL || bfq_gt(first_idle->finish, entity->finish)) ++ st->first_idle = entity; ++ if (last_idle == NULL || bfq_gt(entity->finish, last_idle->finish)) ++ st->last_idle = entity; ++ ++ bfq_insert(&st->idle, entity); ++ ++ if (bfqq != NULL) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list); ++} ++ ++/** ++ * bfq_forget_entity - remove an entity from the wfq trees. ++ * @st: the service tree. ++ * @entity: the entity being removed. ++ * ++ * Update the device status and forget everything about @entity, putting ++ * the device reference to it, if it is a queue. Entities belonging to ++ * groups are not refcounted. ++ */ ++static void bfq_forget_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_sched_data *sd; ++ ++ BUG_ON(!entity->on_st); ++ ++ entity->on_st = 0; ++ st->wsum -= entity->weight; ++ if (bfqq != NULL) { ++ sd = entity->sched_data; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++/** ++ * bfq_put_idle_entity - release the idle tree ref of an entity. ++ * @st: service tree for the entity. ++ * @entity: the entity being released. ++ */ ++static void bfq_put_idle_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ bfq_idle_extract(st, entity); ++ bfq_forget_entity(st, entity); ++} ++ ++/** ++ * bfq_forget_idle - update the idle tree if necessary. ++ * @st: the service tree to act upon. ++ * ++ * To preserve the global O(log N) complexity we only remove one entry here; ++ * as the idle tree will not grow indefinitely this can be done safely. ++ */ ++static void bfq_forget_idle(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (RB_EMPTY_ROOT(&st->active) && last_idle != NULL && ++ !bfq_gt(last_idle->finish, st->vtime)) { ++ /* ++ * Forget the whole idle tree, increasing the vtime past ++ * the last finish time of idle entities. ++ */ ++ st->vtime = last_idle->finish; ++ } ++ ++ if (first_idle != NULL && !bfq_gt(first_idle->finish, st->vtime)) ++ bfq_put_idle_entity(st, first_idle); ++} ++ ++static struct bfq_service_tree * ++__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_service_tree *new_st = old_st; ++ ++ if (entity->ioprio_changed) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ unsigned short prev_weight, new_weight; ++ struct bfq_data *bfqd = NULL; ++ struct rb_root *root; ++#ifdef CONFIG_CGROUP_BFQIO ++ struct bfq_sched_data *sd; ++ struct bfq_group *bfqg; ++#endif ++ ++ if (bfqq != NULL) ++ bfqd = bfqq->bfqd; ++#ifdef CONFIG_CGROUP_BFQIO ++ else { ++ sd = entity->my_sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++ BUG_ON(!bfqd); ++ } ++#endif ++ ++ BUG_ON(old_st->wsum < entity->weight); ++ old_st->wsum -= entity->weight; ++ ++ if (entity->new_weight != entity->orig_weight) { ++ if (entity->new_weight < BFQ_MIN_WEIGHT || ++ entity->new_weight > BFQ_MAX_WEIGHT) { ++ printk(KERN_CRIT "update_weight_prio: " ++ "new_weight %d\n", ++ entity->new_weight); ++ BUG(); ++ } ++ entity->orig_weight = entity->new_weight; ++ entity->ioprio = ++ bfq_weight_to_ioprio(entity->orig_weight); ++ } else if (entity->new_ioprio != entity->ioprio) { ++ entity->ioprio = entity->new_ioprio; ++ entity->orig_weight = ++ bfq_ioprio_to_weight(entity->ioprio); ++ } else ++ entity->new_weight = entity->orig_weight = ++ bfq_ioprio_to_weight(entity->ioprio); ++ ++ entity->ioprio_class = entity->new_ioprio_class; ++ entity->ioprio_changed = 0; ++ ++ /* ++ * NOTE: here we may be changing the weight too early, ++ * this will cause unfairness. The correct approach ++ * would have required additional complexity to defer ++ * weight changes to the proper time instants (i.e., ++ * when entity->finish <= old_st->vtime). ++ */ ++ new_st = bfq_entity_service_tree(entity); ++ ++ prev_weight = entity->weight; ++ new_weight = entity->orig_weight * ++ (bfqq != NULL ? bfqq->wr_coeff : 1); ++ /* ++ * If the weight of the entity changes, remove the entity ++ * from its old weight counter (if there is a counter ++ * associated with the entity), and add it to the counter ++ * associated with its new weight. ++ */ ++ if (prev_weight != new_weight) { ++ root = bfqq ? &bfqd->queue_weights_tree : ++ &bfqd->group_weights_tree; ++ bfq_weights_tree_remove(bfqd, entity, root); ++ } ++ entity->weight = new_weight; ++ /* ++ * Add the entity to its weights tree only if it is ++ * not associated with a weight-raised queue. ++ */ ++ if (prev_weight != new_weight && ++ (bfqq ? bfqq->wr_coeff == 1 : 1)) ++ /* If we get here, root has been initialized. */ ++ bfq_weights_tree_add(bfqd, entity, root); ++ ++ new_st->wsum += entity->weight; ++ ++ if (new_st != old_st) ++ entity->start = new_st->vtime; ++ } ++ ++ return new_st; ++} ++ ++/** ++ * bfq_bfqq_served - update the scheduler status after selection for ++ * service. ++ * @bfqq: the queue being served. ++ * @served: bytes to transfer. ++ * ++ * NOTE: this can be optimized, as the timestamps of upper level entities ++ * are synchronized every time a new bfqq is selected for service. By now, ++ * we keep it to better check consistency. ++ */ ++static void bfq_bfqq_served(struct bfq_queue *bfqq, unsigned long served) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st; ++ ++ for_each_entity(entity) { ++ st = bfq_entity_service_tree(entity); ++ ++ entity->service += served; ++ BUG_ON(entity->service > entity->budget); ++ BUG_ON(st->wsum == 0); ++ ++ st->vtime += bfq_delta(served, st->wsum); ++ bfq_forget_idle(st); ++ } ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %lu secs", served); ++} ++ ++/** ++ * bfq_bfqq_charge_full_budget - set the service to the entity budget. ++ * @bfqq: the queue that needs a service update. ++ * ++ * When it's not possible to be fair in the service domain, because ++ * a queue is not consuming its budget fast enough (the meaning of ++ * fast depends on the timeout parameter), we charge it a full ++ * budget. In this way we should obtain a sort of time-domain ++ * fairness among all the seeky/slow queues. ++ */ ++static inline void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget"); ++ ++ bfq_bfqq_served(bfqq, entity->budget - entity->service); ++} ++ ++/** ++ * __bfq_activate_entity - activate an entity. ++ * @entity: the entity being activated. ++ * ++ * Called whenever an entity is activated, i.e., it is not active and one ++ * of its children receives a new request, or has to be reactivated due to ++ * budget exhaustion. It uses the current budget of the entity (and the ++ * service received if @entity is active) of the queue to calculate its ++ * timestamps. ++ */ ++static void __bfq_activate_entity(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ ++ if (entity == sd->in_service_entity) { ++ BUG_ON(entity->tree != NULL); ++ /* ++ * If we are requeueing the current entity we have ++ * to take care of not charging to it service it has ++ * not received. ++ */ ++ bfq_calc_finish(entity, entity->service); ++ entity->start = entity->finish; ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) { ++ /* ++ * Requeueing an entity due to a change of some ++ * next_in_service entity below it. We reuse the ++ * old start time. ++ */ ++ bfq_active_extract(st, entity); ++ } else if (entity->tree == &st->idle) { ++ /* ++ * Must be on the idle tree, bfq_idle_extract() will ++ * check for that. ++ */ ++ bfq_idle_extract(st, entity); ++ entity->start = bfq_gt(st->vtime, entity->finish) ? ++ st->vtime : entity->finish; ++ } else { ++ /* ++ * The finish time of the entity may be invalid, and ++ * it is in the past for sure, otherwise the queue ++ * would have been on the idle tree. ++ */ ++ entity->start = st->vtime; ++ st->wsum += entity->weight; ++ bfq_get_entity(entity); ++ ++ BUG_ON(entity->on_st); ++ entity->on_st = 1; ++ } ++ ++ st = __bfq_entity_update_weight_prio(st, entity); ++ bfq_calc_finish(entity, entity->budget); ++ bfq_active_insert(st, entity); ++} ++ ++/** ++ * bfq_activate_entity - activate an entity and its ancestors if necessary. ++ * @entity: the entity to activate. ++ * ++ * Activate @entity and all the entities on the path from it to the root. ++ */ ++static void bfq_activate_entity(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sd; ++ ++ for_each_entity(entity) { ++ __bfq_activate_entity(entity); ++ ++ sd = entity->sched_data; ++ if (!bfq_update_next_in_service(sd)) ++ /* ++ * No need to propagate the activation to the ++ * upper entities, as they will be updated when ++ * the in-service entity is rescheduled. ++ */ ++ break; ++ } ++} ++ ++/** ++ * __bfq_deactivate_entity - deactivate an entity from its service tree. ++ * @entity: the entity to deactivate. ++ * @requeue: if false, the entity will not be put into the idle tree. ++ * ++ * Deactivate an entity, independently from its previous state. If the ++ * entity was not on a service tree just return, otherwise if it is on ++ * any scheduler tree, extract it from that tree, and if necessary ++ * and if the caller did not specify @requeue, put it on the idle tree. ++ * ++ * Return %1 if the caller should update the entity hierarchy, i.e., ++ * if the entity was in service or if it was the next_in_service for ++ * its sched_data; return %0 otherwise. ++ */ ++static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ int was_in_service = entity == sd->in_service_entity; ++ int ret = 0; ++ ++ if (!entity->on_st) ++ return 0; ++ ++ BUG_ON(was_in_service && entity->tree != NULL); ++ ++ if (was_in_service) { ++ bfq_calc_finish(entity, entity->service); ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) ++ bfq_active_extract(st, entity); ++ else if (entity->tree == &st->idle) ++ bfq_idle_extract(st, entity); ++ else if (entity->tree != NULL) ++ BUG(); ++ ++ if (was_in_service || sd->next_in_service == entity) ++ ret = bfq_update_next_in_service(sd); ++ ++ if (!requeue || !bfq_gt(entity->finish, st->vtime)) ++ bfq_forget_entity(st, entity); ++ else ++ bfq_idle_insert(st, entity); ++ ++ BUG_ON(sd->in_service_entity == entity); ++ BUG_ON(sd->next_in_service == entity); ++ ++ return ret; ++} ++ ++/** ++ * bfq_deactivate_entity - deactivate an entity. ++ * @entity: the entity to deactivate. ++ * @requeue: true if the entity can be put on the idle tree ++ */ ++static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd; ++ struct bfq_entity *parent; ++ ++ for_each_entity_safe(entity, parent) { ++ sd = entity->sched_data; ++ ++ if (!__bfq_deactivate_entity(entity, requeue)) ++ /* ++ * The parent entity is still backlogged, and ++ * we don't need to update it as it is still ++ * in service. ++ */ ++ break; ++ ++ if (sd->next_in_service != NULL) ++ /* ++ * The parent entity is still backlogged and ++ * the budgets on the path towards the root ++ * need to be updated. ++ */ ++ goto update; ++ ++ /* ++ * If we reach there the parent is no more backlogged and ++ * we want to propagate the dequeue upwards. ++ */ ++ requeue = 1; ++ } ++ ++ return; ++ ++update: ++ entity = parent; ++ for_each_entity(entity) { ++ __bfq_activate_entity(entity); ++ ++ sd = entity->sched_data; ++ if (!bfq_update_next_in_service(sd)) ++ break; ++ } ++} ++ ++/** ++ * bfq_update_vtime - update vtime if necessary. ++ * @st: the service tree to act upon. ++ * ++ * If necessary update the service tree vtime to have at least one ++ * eligible entity, skipping to its start time. Assumes that the ++ * active tree of the device is not empty. ++ * ++ * NOTE: this hierarchical implementation updates vtimes quite often, ++ * we may end up with reactivated processes getting timestamps after a ++ * vtime skip done because we needed a ->first_active entity on some ++ * intermediate node. ++ */ ++static void bfq_update_vtime(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry; ++ struct rb_node *node = st->active.rb_node; ++ ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entry->min_start, st->vtime)) { ++ st->vtime = entry->min_start; ++ bfq_forget_idle(st); ++ } ++} ++ ++/** ++ * bfq_first_active_entity - find the eligible entity with ++ * the smallest finish time ++ * @st: the service tree to select from. ++ * ++ * This function searches the first schedulable entity, starting from the ++ * root of the tree and going on the left every time on this side there is ++ * a subtree with at least one eligible (start >= vtime) entity. The path on ++ * the right is followed only if a) the left subtree contains no eligible ++ * entities and b) no eligible entity has been found yet. ++ */ ++static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry, *first = NULL; ++ struct rb_node *node = st->active.rb_node; ++ ++ while (node != NULL) { ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++left: ++ if (!bfq_gt(entry->start, st->vtime)) ++ first = entry; ++ ++ BUG_ON(bfq_gt(entry->min_start, st->vtime)); ++ ++ if (node->rb_left != NULL) { ++ entry = rb_entry(node->rb_left, ++ struct bfq_entity, rb_node); ++ if (!bfq_gt(entry->min_start, st->vtime)) { ++ node = node->rb_left; ++ goto left; ++ } ++ } ++ if (first != NULL) ++ break; ++ node = node->rb_right; ++ } ++ ++ BUG_ON(first == NULL && !RB_EMPTY_ROOT(&st->active)); ++ return first; ++} ++ ++/** ++ * __bfq_lookup_next_entity - return the first eligible entity in @st. ++ * @st: the service tree. ++ * ++ * Update the virtual time in @st and return the first eligible entity ++ * it contains. ++ */ ++static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st, ++ bool force) ++{ ++ struct bfq_entity *entity, *new_next_in_service = NULL; ++ ++ if (RB_EMPTY_ROOT(&st->active)) ++ return NULL; ++ ++ bfq_update_vtime(st); ++ entity = bfq_first_active_entity(st); ++ BUG_ON(bfq_gt(entity->start, st->vtime)); ++ ++ /* ++ * If the chosen entity does not match with the sched_data's ++ * next_in_service and we are forcedly serving the IDLE priority ++ * class tree, bubble up budget update. ++ */ ++ if (unlikely(force && entity != entity->sched_data->next_in_service)) { ++ new_next_in_service = entity; ++ for_each_entity(new_next_in_service) ++ bfq_update_budget(new_next_in_service); ++ } ++ ++ return entity; ++} ++ ++/** ++ * bfq_lookup_next_entity - return the first eligible entity in @sd. ++ * @sd: the sched_data. ++ * @extract: if true the returned entity will be also extracted from @sd. ++ * ++ * NOTE: since we cache the next_in_service entity at each level of the ++ * hierarchy, the complexity of the lookup can be decreased with ++ * absolutely no effort just returning the cached next_in_service value; ++ * we prefer to do full lookups to test the consistency of * the data ++ * structures. ++ */ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd) ++{ ++ struct bfq_service_tree *st = sd->service_tree; ++ struct bfq_entity *entity; ++ int i = 0; ++ ++ BUG_ON(sd->in_service_entity != NULL); ++ ++ if (bfqd != NULL && ++ jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) { ++ entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1, ++ true); ++ if (entity != NULL) { ++ i = BFQ_IOPRIO_CLASSES - 1; ++ bfqd->bfq_class_idle_last_service = jiffies; ++ sd->next_in_service = entity; ++ } ++ } ++ for (; i < BFQ_IOPRIO_CLASSES; i++) { ++ entity = __bfq_lookup_next_entity(st + i, false); ++ if (entity != NULL) { ++ if (extract) { ++ bfq_check_next_in_service(sd, entity); ++ bfq_active_extract(st + i, entity); ++ sd->in_service_entity = entity; ++ sd->next_in_service = NULL; ++ } ++ break; ++ } ++ } ++ ++ return entity; ++} ++ ++/* ++ * Get next queue for service. ++ */ ++static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_entity *entity = NULL; ++ struct bfq_sched_data *sd; ++ struct bfq_queue *bfqq; ++ ++ BUG_ON(bfqd->in_service_queue != NULL); ++ ++ if (bfqd->busy_queues == 0) ++ return NULL; ++ ++ sd = &bfqd->root_group->sched_data; ++ for (; sd != NULL; sd = entity->my_sched_data) { ++ entity = bfq_lookup_next_entity(sd, 1, bfqd); ++ BUG_ON(entity == NULL); ++ entity->service = 0; ++ } ++ ++ bfqq = bfq_entity_to_bfqq(entity); ++ BUG_ON(bfqq == NULL); ++ ++ return bfqq; ++} ++ ++/* ++ * Forced extraction of the given queue. ++ */ ++static void bfq_get_next_queue_forced(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity; ++ struct bfq_sched_data *sd; ++ ++ BUG_ON(bfqd->in_service_queue != NULL); ++ ++ entity = &bfqq->entity; ++ /* ++ * Bubble up extraction/update from the leaf to the root. ++ */ ++ for_each_entity(entity) { ++ sd = entity->sched_data; ++ bfq_update_budget(entity); ++ bfq_update_vtime(bfq_entity_service_tree(entity)); ++ bfq_active_extract(bfq_entity_service_tree(entity), entity); ++ sd->in_service_entity = entity; ++ sd->next_in_service = NULL; ++ entity->service = 0; ++ } ++ ++ return; ++} ++ ++static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) ++{ ++ if (bfqd->in_service_bic != NULL) { ++ put_io_context(bfqd->in_service_bic->icq.ioc); ++ bfqd->in_service_bic = NULL; ++ } ++ ++ bfqd->in_service_queue = NULL; ++ del_timer(&bfqd->idle_slice_timer); ++} ++ ++static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ if (bfqq == bfqd->in_service_queue) ++ __bfq_bfqd_reset_in_service(bfqd); ++ ++ bfq_deactivate_entity(entity, requeue); ++} ++ ++static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_activate_entity(entity); ++} ++ ++/* ++ * Called when the bfqq no longer has requests pending, remove it from ++ * the service tree. ++ */ ++static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ BUG_ON(!bfq_bfqq_busy(bfqq)); ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ bfq_log_bfqq(bfqd, bfqq, "del from busy"); ++ ++ bfq_clear_bfqq_busy(bfqq); ++ ++ BUG_ON(bfqd->busy_queues == 0); ++ bfqd->busy_queues--; ++ ++ if (!bfqq->dispatched) { ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ BUG_ON(!bfqd->busy_in_flight_queues); ++ bfqd->busy_in_flight_queues--; ++ if (bfq_bfqq_constantly_seeky(bfqq)) { ++ BUG_ON(!bfqd-> ++ const_seeky_busy_in_flight_queues); ++ bfqd->const_seeky_busy_in_flight_queues--; ++ } ++ } ++ } ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues--; ++ ++ bfq_deactivate_bfqq(bfqd, bfqq, requeue); ++} ++ ++/* ++ * Called when an inactive queue receives a new request. ++ */ ++static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "add to busy"); ++ ++ bfq_activate_bfqq(bfqd, bfqq); ++ ++ bfq_mark_bfqq_busy(bfqq); ++ bfqd->busy_queues++; ++ ++ if (!bfqq->dispatched) { ++ if (bfqq->wr_coeff == 1) ++ bfq_weights_tree_add(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ bfqd->busy_in_flight_queues++; ++ if (bfq_bfqq_constantly_seeky(bfqq)) ++ bfqd->const_seeky_busy_in_flight_queues++; ++ } ++ } ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues++; ++} +diff --git a/block/bfq.h b/block/bfq.h +new file mode 100644 +index 0000000..3c5d85e +--- /dev/null ++++ b/block/bfq.h +@@ -0,0 +1,775 @@ ++/* ++ * BFQ-v7r7 for 3.19.0: data structures and common functions prototypes. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++#ifndef _BFQ_H ++#define _BFQ_H ++ ++#include ++#include ++#include ++#include ++ ++#define BFQ_IOPRIO_CLASSES 3 ++#define BFQ_CL_IDLE_TIMEOUT (HZ/5) ++ ++#define BFQ_MIN_WEIGHT 1 ++#define BFQ_MAX_WEIGHT 1000 ++ ++#define BFQ_DEFAULT_QUEUE_IOPRIO 4 ++ ++#define BFQ_DEFAULT_GRP_WEIGHT 10 ++#define BFQ_DEFAULT_GRP_IOPRIO 0 ++#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE ++ ++struct bfq_entity; ++ ++/** ++ * struct bfq_service_tree - per ioprio_class service tree. ++ * @active: tree for active entities (i.e., those backlogged). ++ * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i). ++ * @first_idle: idle entity with minimum F_i. ++ * @last_idle: idle entity with maximum F_i. ++ * @vtime: scheduler virtual time. ++ * @wsum: scheduler weight sum; active and idle entities contribute to it. ++ * ++ * Each service tree represents a B-WF2Q+ scheduler on its own. Each ++ * ioprio_class has its own independent scheduler, and so its own ++ * bfq_service_tree. All the fields are protected by the queue lock ++ * of the containing bfqd. ++ */ ++struct bfq_service_tree { ++ struct rb_root active; ++ struct rb_root idle; ++ ++ struct bfq_entity *first_idle; ++ struct bfq_entity *last_idle; ++ ++ u64 vtime; ++ unsigned long wsum; ++}; ++ ++/** ++ * struct bfq_sched_data - multi-class scheduler. ++ * @in_service_entity: entity in service. ++ * @next_in_service: head-of-the-line entity in the scheduler. ++ * @service_tree: array of service trees, one per ioprio_class. ++ * ++ * bfq_sched_data is the basic scheduler queue. It supports three ++ * ioprio_classes, and can be used either as a toplevel queue or as ++ * an intermediate queue on a hierarchical setup. ++ * @next_in_service points to the active entity of the sched_data ++ * service trees that will be scheduled next. ++ * ++ * The supported ioprio_classes are the same as in CFQ, in descending ++ * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE. ++ * Requests from higher priority queues are served before all the ++ * requests from lower priority queues; among requests of the same ++ * queue requests are served according to B-WF2Q+. ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_sched_data { ++ struct bfq_entity *in_service_entity; ++ struct bfq_entity *next_in_service; ++ struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES]; ++}; ++ ++/** ++ * struct bfq_weight_counter - counter of the number of all active entities ++ * with a given weight. ++ * @weight: weight of the entities that this counter refers to. ++ * @num_active: number of active entities with this weight. ++ * @weights_node: weights tree member (see bfq_data's @queue_weights_tree ++ * and @group_weights_tree). ++ */ ++struct bfq_weight_counter { ++ short int weight; ++ unsigned int num_active; ++ struct rb_node weights_node; ++}; ++ ++/** ++ * struct bfq_entity - schedulable entity. ++ * @rb_node: service_tree member. ++ * @weight_counter: pointer to the weight counter associated with this entity. ++ * @on_st: flag, true if the entity is on a tree (either the active or ++ * the idle one of its service_tree). ++ * @finish: B-WF2Q+ finish timestamp (aka F_i). ++ * @start: B-WF2Q+ start timestamp (aka S_i). ++ * @tree: tree the entity is enqueued into; %NULL if not on a tree. ++ * @min_start: minimum start time of the (active) subtree rooted at ++ * this entity; used for O(log N) lookups into active trees. ++ * @service: service received during the last round of service. ++ * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight. ++ * @weight: weight of the queue ++ * @parent: parent entity, for hierarchical scheduling. ++ * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the ++ * associated scheduler queue, %NULL on leaf nodes. ++ * @sched_data: the scheduler queue this entity belongs to. ++ * @ioprio: the ioprio in use. ++ * @new_weight: when a weight change is requested, the new weight value. ++ * @orig_weight: original weight, used to implement weight boosting ++ * @new_ioprio: when an ioprio change is requested, the new ioprio value. ++ * @ioprio_class: the ioprio_class in use. ++ * @new_ioprio_class: when an ioprio_class change is requested, the new ++ * ioprio_class value. ++ * @ioprio_changed: flag, true when the user requested a weight, ioprio or ++ * ioprio_class change. ++ * ++ * A bfq_entity is used to represent either a bfq_queue (leaf node in the ++ * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each ++ * entity belongs to the sched_data of the parent group in the cgroup ++ * hierarchy. Non-leaf entities have also their own sched_data, stored ++ * in @my_sched_data. ++ * ++ * Each entity stores independently its priority values; this would ++ * allow different weights on different devices, but this ++ * functionality is not exported to userspace by now. Priorities and ++ * weights are updated lazily, first storing the new values into the ++ * new_* fields, then setting the @ioprio_changed flag. As soon as ++ * there is a transition in the entity state that allows the priority ++ * update to take place the effective and the requested priority ++ * values are synchronized. ++ * ++ * Unless cgroups are used, the weight value is calculated from the ++ * ioprio to export the same interface as CFQ. When dealing with ++ * ``well-behaved'' queues (i.e., queues that do not spend too much ++ * time to consume their budget and have true sequential behavior, and ++ * when there are no external factors breaking anticipation) the ++ * relative weights at each level of the cgroups hierarchy should be ++ * guaranteed. All the fields are protected by the queue lock of the ++ * containing bfqd. ++ */ ++struct bfq_entity { ++ struct rb_node rb_node; ++ struct bfq_weight_counter *weight_counter; ++ ++ int on_st; ++ ++ u64 finish; ++ u64 start; ++ ++ struct rb_root *tree; ++ ++ u64 min_start; ++ ++ unsigned long service, budget; ++ unsigned short weight, new_weight; ++ unsigned short orig_weight; ++ ++ struct bfq_entity *parent; ++ ++ struct bfq_sched_data *my_sched_data; ++ struct bfq_sched_data *sched_data; ++ ++ unsigned short ioprio, new_ioprio; ++ unsigned short ioprio_class, new_ioprio_class; ++ ++ int ioprio_changed; ++}; ++ ++struct bfq_group; ++ ++/** ++ * struct bfq_queue - leaf schedulable entity. ++ * @ref: reference counter. ++ * @bfqd: parent bfq_data. ++ * @new_bfqq: shared bfq_queue if queue is cooperating with ++ * one or more other queues. ++ * @pos_node: request-position tree member (see bfq_data's @rq_pos_tree). ++ * @pos_root: request-position tree root (see bfq_data's @rq_pos_tree). ++ * @sort_list: sorted list of pending requests. ++ * @next_rq: if fifo isn't expired, next request to serve. ++ * @queued: nr of requests queued in @sort_list. ++ * @allocated: currently allocated requests. ++ * @meta_pending: pending metadata requests. ++ * @fifo: fifo list of requests in sort_list. ++ * @entity: entity representing this queue in the scheduler. ++ * @max_budget: maximum budget allowed from the feedback mechanism. ++ * @budget_timeout: budget expiration (in jiffies). ++ * @dispatched: number of requests on the dispatch list or inside driver. ++ * @flags: status flags. ++ * @bfqq_list: node for active/idle bfqq list inside our bfqd. ++ * @burst_list_node: node for the device's burst list. ++ * @seek_samples: number of seeks sampled ++ * @seek_total: sum of the distances of the seeks sampled ++ * @seek_mean: mean seek distance ++ * @last_request_pos: position of the last request enqueued ++ * @requests_within_timer: number of consecutive pairs of request completion ++ * and arrival, such that the queue becomes idle ++ * after the completion, but the next request arrives ++ * within an idle time slice; used only if the queue's ++ * IO_bound has been cleared. ++ * @pid: pid of the process owning the queue, used for logging purposes. ++ * @last_wr_start_finish: start time of the current weight-raising period if ++ * the @bfq-queue is being weight-raised, otherwise ++ * finish time of the last weight-raising period ++ * @wr_cur_max_time: current max raising time for this queue ++ * @soft_rt_next_start: minimum time instant such that, only if a new ++ * request is enqueued after this time instant in an ++ * idle @bfq_queue with no outstanding requests, then ++ * the task associated with the queue it is deemed as ++ * soft real-time (see the comments to the function ++ * bfq_bfqq_softrt_next_start()). ++ * @last_idle_bklogged: time of the last transition of the @bfq_queue from ++ * idle to backlogged ++ * @service_from_backlogged: cumulative service received from the @bfq_queue ++ * since the last transition from idle to ++ * backlogged ++ * ++ * A bfq_queue is a leaf request queue; it can be associated with an io_context ++ * or more, if it is async or shared between cooperating processes. @cgroup ++ * holds a reference to the cgroup, to be sure that it does not disappear while ++ * a bfqq still references it (mostly to avoid races between request issuing and ++ * task migration followed by cgroup destruction). ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_queue { ++ atomic_t ref; ++ struct bfq_data *bfqd; ++ ++ /* fields for cooperating queues handling */ ++ struct bfq_queue *new_bfqq; ++ struct rb_node pos_node; ++ struct rb_root *pos_root; ++ ++ struct rb_root sort_list; ++ struct request *next_rq; ++ int queued[2]; ++ int allocated[2]; ++ int meta_pending; ++ struct list_head fifo; ++ ++ struct bfq_entity entity; ++ ++ unsigned long max_budget; ++ unsigned long budget_timeout; ++ ++ int dispatched; ++ ++ unsigned int flags; ++ ++ struct list_head bfqq_list; ++ ++ struct hlist_node burst_list_node; ++ ++ unsigned int seek_samples; ++ u64 seek_total; ++ sector_t seek_mean; ++ sector_t last_request_pos; ++ ++ unsigned int requests_within_timer; ++ ++ pid_t pid; ++ ++ /* weight-raising fields */ ++ unsigned long wr_cur_max_time; ++ unsigned long soft_rt_next_start; ++ unsigned long last_wr_start_finish; ++ unsigned int wr_coeff; ++ unsigned long last_idle_bklogged; ++ unsigned long service_from_backlogged; ++}; ++ ++/** ++ * struct bfq_ttime - per process thinktime stats. ++ * @ttime_total: total process thinktime ++ * @ttime_samples: number of thinktime samples ++ * @ttime_mean: average process thinktime ++ */ ++struct bfq_ttime { ++ unsigned long last_end_request; ++ ++ unsigned long ttime_total; ++ unsigned long ttime_samples; ++ unsigned long ttime_mean; ++}; ++ ++/** ++ * struct bfq_io_cq - per (request_queue, io_context) structure. ++ * @icq: associated io_cq structure ++ * @bfqq: array of two process queues, the sync and the async ++ * @ttime: associated @bfq_ttime struct ++ */ ++struct bfq_io_cq { ++ struct io_cq icq; /* must be the first member */ ++ struct bfq_queue *bfqq[2]; ++ struct bfq_ttime ttime; ++ int ioprio; ++}; ++ ++enum bfq_device_speed { ++ BFQ_BFQD_FAST, ++ BFQ_BFQD_SLOW, ++}; ++ ++/** ++ * struct bfq_data - per device data structure. ++ * @queue: request queue for the managed device. ++ * @root_group: root bfq_group for the device. ++ * @rq_pos_tree: rbtree sorted by next_request position, used when ++ * determining if two or more queues have interleaving ++ * requests (see bfq_close_cooperator()). ++ * @active_numerous_groups: number of bfq_groups containing more than one ++ * active @bfq_entity. ++ * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by ++ * weight. Used to keep track of whether all @bfq_queues ++ * have the same weight. The tree contains one counter ++ * for each distinct weight associated to some active ++ * and not weight-raised @bfq_queue (see the comments to ++ * the functions bfq_weights_tree_[add|remove] for ++ * further details). ++ * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted ++ * by weight. Used to keep track of whether all ++ * @bfq_groups have the same weight. The tree contains ++ * one counter for each distinct weight associated to ++ * some active @bfq_group (see the comments to the ++ * functions bfq_weights_tree_[add|remove] for further ++ * details). ++ * @busy_queues: number of bfq_queues containing requests (including the ++ * queue in service, even if it is idling). ++ * @busy_in_flight_queues: number of @bfq_queues containing pending or ++ * in-flight requests, plus the @bfq_queue in ++ * service, even if idle but waiting for the ++ * possible arrival of its next sync request. This ++ * field is updated only if the device is rotational, ++ * but used only if the device is also NCQ-capable. ++ * The reason why the field is updated also for non- ++ * NCQ-capable rotational devices is related to the ++ * fact that the value of @hw_tag may be set also ++ * later than when busy_in_flight_queues may need to ++ * be incremented for the first time(s). Taking also ++ * this possibility into account, to avoid unbalanced ++ * increments/decrements, would imply more overhead ++ * than just updating busy_in_flight_queues ++ * regardless of the value of @hw_tag. ++ * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues ++ * (that is, seeky queues that expired ++ * for budget timeout at least once) ++ * containing pending or in-flight ++ * requests, including the in-service ++ * @bfq_queue if constantly seeky. This ++ * field is updated only if the device ++ * is rotational, but used only if the ++ * device is also NCQ-capable (see the ++ * comments to @busy_in_flight_queues). ++ * @wr_busy_queues: number of weight-raised busy @bfq_queues. ++ * @queued: number of queued requests. ++ * @rq_in_driver: number of requests dispatched and waiting for completion. ++ * @sync_flight: number of sync requests in the driver. ++ * @max_rq_in_driver: max number of reqs in driver in the last ++ * @hw_tag_samples completed requests. ++ * @hw_tag_samples: nr of samples used to calculate hw_tag. ++ * @hw_tag: flag set to one if the driver is showing a queueing behavior. ++ * @budgets_assigned: number of budgets assigned. ++ * @idle_slice_timer: timer set when idling for the next sequential request ++ * from the queue in service. ++ * @unplug_work: delayed work to restart dispatching on the request queue. ++ * @in_service_queue: bfq_queue in service. ++ * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue. ++ * @last_position: on-disk position of the last served request. ++ * @last_budget_start: beginning of the last budget. ++ * @last_idling_start: beginning of the last idle slice. ++ * @peak_rate: peak transfer rate observed for a budget. ++ * @peak_rate_samples: number of samples used to calculate @peak_rate. ++ * @bfq_max_budget: maximum budget allotted to a bfq_queue before ++ * rescheduling. ++ * @group_list: list of all the bfq_groups active on the device. ++ * @active_list: list of all the bfq_queues active on the device. ++ * @idle_list: list of all the bfq_queues idle on the device. ++ * @bfq_quantum: max number of requests dispatched per dispatch round. ++ * @bfq_fifo_expire: timeout for async/sync requests; when it expires ++ * requests are served in fifo order. ++ * @bfq_back_penalty: weight of backward seeks wrt forward ones. ++ * @bfq_back_max: maximum allowed backward seek. ++ * @bfq_slice_idle: maximum idling time. ++ * @bfq_user_max_budget: user-configured max budget value ++ * (0 for auto-tuning). ++ * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to ++ * async queues. ++ * @bfq_timeout: timeout for bfq_queues to consume their budget; used to ++ * to prevent seeky queues to impose long latencies to well ++ * behaved ones (this also implies that seeky queues cannot ++ * receive guarantees in the service domain; after a timeout ++ * they are charged for the whole allocated budget, to try ++ * to preserve a behavior reasonably fair among them, but ++ * without service-domain guarantees). ++ * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is ++ * no more granted any weight-raising. ++ * @bfq_failed_cooperations: number of consecutive failed cooperation ++ * chances after which weight-raising is restored ++ * to a queue subject to more than bfq_coop_thresh ++ * queue merges. ++ * @bfq_requests_within_timer: number of consecutive requests that must be ++ * issued within the idle time slice to set ++ * again idling to a queue which was marked as ++ * non-I/O-bound (see the definition of the ++ * IO_bound flag for further details). ++ * @last_ins_in_burst: last time at which a queue entered the current ++ * burst of queues being activated shortly after ++ * each other; for more details about this and the ++ * following parameters related to a burst of ++ * activations, see the comments to the function ++ * @bfq_handle_burst. ++ * @bfq_burst_interval: reference time interval used to decide whether a ++ * queue has been activated shortly after ++ * @last_ins_in_burst. ++ * @burst_size: number of queues in the current burst of queue activations. ++ * @bfq_large_burst_thresh: maximum burst size above which the current ++ * queue-activation burst is deemed as 'large'. ++ * @large_burst: true if a large queue-activation burst is in progress. ++ * @burst_list: head of the burst list (as for the above fields, more details ++ * in the comments to the function bfq_handle_burst). ++ * @low_latency: if set to true, low-latency heuristics are enabled. ++ * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised ++ * queue is multiplied. ++ * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies). ++ * @bfq_wr_rt_max_time: maximum duration for soft real-time processes. ++ * @bfq_wr_min_idle_time: minimum idle period after which weight-raising ++ * may be reactivated for a queue (in jiffies). ++ * @bfq_wr_min_inter_arr_async: minimum period between request arrivals ++ * after which weight-raising may be ++ * reactivated for an already busy queue ++ * (in jiffies). ++ * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue, ++ * sectors per seconds. ++ * @RT_prod: cached value of the product R*T used for computing the maximum ++ * duration of the weight raising automatically. ++ * @device_speed: device-speed class for the low-latency heuristic. ++ * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions. ++ * ++ * All the fields are protected by the @queue lock. ++ */ ++struct bfq_data { ++ struct request_queue *queue; ++ ++ struct bfq_group *root_group; ++ struct rb_root rq_pos_tree; ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ int active_numerous_groups; ++#endif ++ ++ struct rb_root queue_weights_tree; ++ struct rb_root group_weights_tree; ++ ++ int busy_queues; ++ int busy_in_flight_queues; ++ int const_seeky_busy_in_flight_queues; ++ int wr_busy_queues; ++ int queued; ++ int rq_in_driver; ++ int sync_flight; ++ ++ int max_rq_in_driver; ++ int hw_tag_samples; ++ int hw_tag; ++ ++ int budgets_assigned; ++ ++ struct timer_list idle_slice_timer; ++ struct work_struct unplug_work; ++ ++ struct bfq_queue *in_service_queue; ++ struct bfq_io_cq *in_service_bic; ++ ++ sector_t last_position; ++ ++ ktime_t last_budget_start; ++ ktime_t last_idling_start; ++ int peak_rate_samples; ++ u64 peak_rate; ++ unsigned long bfq_max_budget; ++ ++ struct hlist_head group_list; ++ struct list_head active_list; ++ struct list_head idle_list; ++ ++ unsigned int bfq_quantum; ++ unsigned int bfq_fifo_expire[2]; ++ unsigned int bfq_back_penalty; ++ unsigned int bfq_back_max; ++ unsigned int bfq_slice_idle; ++ u64 bfq_class_idle_last_service; ++ ++ unsigned int bfq_user_max_budget; ++ unsigned int bfq_max_budget_async_rq; ++ unsigned int bfq_timeout[2]; ++ ++ unsigned int bfq_coop_thresh; ++ unsigned int bfq_failed_cooperations; ++ unsigned int bfq_requests_within_timer; ++ ++ unsigned long last_ins_in_burst; ++ unsigned long bfq_burst_interval; ++ int burst_size; ++ unsigned long bfq_large_burst_thresh; ++ bool large_burst; ++ struct hlist_head burst_list; ++ ++ bool low_latency; ++ ++ /* parameters of the low_latency heuristics */ ++ unsigned int bfq_wr_coeff; ++ unsigned int bfq_wr_max_time; ++ unsigned int bfq_wr_rt_max_time; ++ unsigned int bfq_wr_min_idle_time; ++ unsigned long bfq_wr_min_inter_arr_async; ++ unsigned int bfq_wr_max_softrt_rate; ++ u64 RT_prod; ++ enum bfq_device_speed device_speed; ++ ++ struct bfq_queue oom_bfqq; ++}; ++ ++enum bfqq_state_flags { ++ BFQ_BFQQ_FLAG_busy = 0, /* has requests or is in service */ ++ BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */ ++ BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ ++ BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ ++ BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */ ++ BFQ_BFQQ_FLAG_prio_changed, /* task priority has changed */ ++ BFQ_BFQQ_FLAG_sync, /* synchronous queue */ ++ BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */ ++ BFQ_BFQQ_FLAG_IO_bound, /* ++ * bfqq has timed-out at least once ++ * having consumed at most 2/10 of ++ * its budget ++ */ ++ BFQ_BFQQ_FLAG_in_large_burst, /* ++ * bfqq activated in a large burst, ++ * see comments to bfq_handle_burst. ++ */ ++ BFQ_BFQQ_FLAG_constantly_seeky, /* ++ * bfqq has proved to be slow and ++ * seeky until budget timeout ++ */ ++ BFQ_BFQQ_FLAG_softrt_update, /* ++ * may need softrt-next-start ++ * update ++ */ ++ BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ ++ BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be splitted */ ++}; ++ ++#define BFQ_BFQQ_FNS(name) \ ++static inline void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static inline void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static inline int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ ++{ \ ++ return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \ ++} ++ ++BFQ_BFQQ_FNS(busy); ++BFQ_BFQQ_FNS(wait_request); ++BFQ_BFQQ_FNS(must_alloc); ++BFQ_BFQQ_FNS(fifo_expire); ++BFQ_BFQQ_FNS(idle_window); ++BFQ_BFQQ_FNS(prio_changed); ++BFQ_BFQQ_FNS(sync); ++BFQ_BFQQ_FNS(budget_new); ++BFQ_BFQQ_FNS(IO_bound); ++BFQ_BFQQ_FNS(in_large_burst); ++BFQ_BFQQ_FNS(constantly_seeky); ++BFQ_BFQQ_FNS(coop); ++BFQ_BFQQ_FNS(split_coop); ++BFQ_BFQQ_FNS(softrt_update); ++#undef BFQ_BFQQ_FNS ++ ++/* Logging facilities. */ ++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args) ++ ++#define bfq_log(bfqd, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) ++ ++/* Expiration reasons. */ ++enum bfqq_expiration { ++ BFQ_BFQQ_TOO_IDLE = 0, /* ++ * queue has been idling for ++ * too long ++ */ ++ BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */ ++ BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */ ++ BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */ ++}; ++ ++#ifdef CONFIG_CGROUP_BFQIO ++/** ++ * struct bfq_group - per (device, cgroup) data structure. ++ * @entity: schedulable entity to insert into the parent group sched_data. ++ * @sched_data: own sched_data, to contain child entities (they may be ++ * both bfq_queues and bfq_groups). ++ * @group_node: node to be inserted into the bfqio_cgroup->group_data ++ * list of the containing cgroup's bfqio_cgroup. ++ * @bfqd_node: node to be inserted into the @bfqd->group_list list ++ * of the groups active on the same device; used for cleanup. ++ * @bfqd: the bfq_data for the device this group acts upon. ++ * @async_bfqq: array of async queues for all the tasks belonging to ++ * the group, one queue per ioprio value per ioprio_class, ++ * except for the idle class that has only one queue. ++ * @async_idle_bfqq: async queue for the idle class (ioprio is ignored). ++ * @my_entity: pointer to @entity, %NULL for the toplevel group; used ++ * to avoid too many special cases during group creation/ ++ * migration. ++ * @active_entities: number of active entities belonging to the group; ++ * unused for the root group. Used to know whether there ++ * are groups with more than one active @bfq_entity ++ * (see the comments to the function ++ * bfq_bfqq_must_not_expire()). ++ * ++ * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup ++ * there is a set of bfq_groups, each one collecting the lower-level ++ * entities belonging to the group that are acting on the same device. ++ * ++ * Locking works as follows: ++ * o @group_node is protected by the bfqio_cgroup lock, and is accessed ++ * via RCU from its readers. ++ * o @bfqd is protected by the queue lock, RCU is used to access it ++ * from the readers. ++ * o All the other fields are protected by the @bfqd queue lock. ++ */ ++struct bfq_group { ++ struct bfq_entity entity; ++ struct bfq_sched_data sched_data; ++ ++ struct hlist_node group_node; ++ struct hlist_node bfqd_node; ++ ++ void *bfqd; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++ ++ struct bfq_entity *my_entity; ++ ++ int active_entities; ++}; ++ ++/** ++ * struct bfqio_cgroup - bfq cgroup data structure. ++ * @css: subsystem state for bfq in the containing cgroup. ++ * @online: flag marked when the subsystem is inserted. ++ * @weight: cgroup weight. ++ * @ioprio: cgroup ioprio. ++ * @ioprio_class: cgroup ioprio_class. ++ * @lock: spinlock that protects @ioprio, @ioprio_class and @group_data. ++ * @group_data: list containing the bfq_group belonging to this cgroup. ++ * ++ * @group_data is accessed using RCU, with @lock protecting the updates, ++ * @ioprio and @ioprio_class are protected by @lock. ++ */ ++struct bfqio_cgroup { ++ struct cgroup_subsys_state css; ++ bool online; ++ ++ unsigned short weight, ioprio, ioprio_class; ++ ++ spinlock_t lock; ++ struct hlist_head group_data; ++}; ++#else ++struct bfq_group { ++ struct bfq_sched_data sched_data; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++}; ++#endif ++ ++static inline struct bfq_service_tree * ++bfq_entity_service_tree(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sched_data = entity->sched_data; ++ unsigned int idx = entity->ioprio_class - 1; ++ ++ BUG_ON(idx >= BFQ_IOPRIO_CLASSES); ++ BUG_ON(sched_data == NULL); ++ ++ return sched_data->service_tree + idx; ++} ++ ++static inline struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, ++ bool is_sync) ++{ ++ return bic->bfqq[is_sync]; ++} ++ ++static inline void bic_set_bfqq(struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq, bool is_sync) ++{ ++ bic->bfqq[is_sync] = bfqq; ++} ++ ++static inline struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) ++{ ++ return bic->icq.q->elevator->elevator_data; ++} ++ ++/** ++ * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer. ++ * @ptr: a pointer to a bfqd. ++ * @flags: storage for the flags to be saved. ++ * ++ * This function allows bfqg->bfqd to be protected by the ++ * queue lock of the bfqd they reference; the pointer is dereferenced ++ * under RCU, so the storage for bfqd is assured to be safe as long ++ * as the RCU read side critical section does not end. After the ++ * bfqd->queue->queue_lock is taken the pointer is rechecked, to be ++ * sure that no other writer accessed it. If we raced with a writer, ++ * the function returns NULL, with the queue unlocked, otherwise it ++ * returns the dereferenced pointer, with the queue locked. ++ */ ++static inline struct bfq_data *bfq_get_bfqd_locked(void **ptr, ++ unsigned long *flags) ++{ ++ struct bfq_data *bfqd; ++ ++ rcu_read_lock(); ++ bfqd = rcu_dereference(*(struct bfq_data **)ptr); ++ ++ if (bfqd != NULL) { ++ spin_lock_irqsave(bfqd->queue->queue_lock, *flags); ++ if (*ptr == bfqd) ++ goto out; ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); ++ } ++ ++ bfqd = NULL; ++out: ++ rcu_read_unlock(); ++ return bfqd; ++} ++ ++static inline void bfq_put_bfqd_unlock(struct bfq_data *bfqd, ++ unsigned long *flags) ++{ ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); ++} ++ ++static void bfq_changed_ioprio(struct bfq_io_cq *bic); ++static void bfq_put_queue(struct bfq_queue *bfqq); ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq); ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, int is_sync, ++ struct bfq_io_cq *bic, gfp_t gfp_mask); ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg); ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); ++ ++#endif /* _BFQ_H */ +-- +2.3.0 + diff --git a/kernel/kernel/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt b/kernel/kernel/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt new file mode 100644 index 00000000..fb96ff28 --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/5002_block-introduce-the-BFQ-v7r7-I-O-sched-for-3.19.patch1.txt @@ -0,0 +1,6966 @@ +From 5bfaaa91a51940efaccb66bc5cd562ba3b9d4053 Mon Sep 17 00:00:00 2001 +From: Paolo Valente +Date: Thu, 9 May 2013 19:10:02 +0200 +Subject: [PATCH 2/3] block: introduce the BFQ-v7r7 I/O sched for 3.19 + +Add the BFQ-v7r7 I/O scheduler to 3.19. +The general structure is borrowed from CFQ, as much of the code for +handling I/O contexts. Over time, several useful features have been +ported from CFQ as well (details in the changelog in README.BFQ). A +(bfq_)queue is associated to each task doing I/O on a device, and each +time a scheduling decision has to be made a queue is selected and served +until it expires. + + - Slices are given in the service domain: tasks are assigned + budgets, measured in number of sectors. Once got the disk, a task + must however consume its assigned budget within a configurable + maximum time (by default, the maximum possible value of the + budgets is automatically computed to comply with this timeout). + This allows the desired latency vs "throughput boosting" tradeoff + to be set. + + - Budgets are scheduled according to a variant of WF2Q+, implemented + using an augmented rb-tree to take eligibility into account while + preserving an O(log N) overall complexity. + + - A low-latency tunable is provided; if enabled, both interactive + and soft real-time applications are guaranteed a very low latency. + + - Latency guarantees are preserved also in the presence of NCQ. + + - Also with flash-based devices, a high throughput is achieved + while still preserving latency guarantees. + + - BFQ features Early Queue Merge (EQM), a sort of fusion of the + cooperating-queue-merging and the preemption mechanisms present + in CFQ. EQM is in fact a unified mechanism that tries to get a + sequential read pattern, and hence a high throughput, with any + set of processes performing interleaved I/O over a contiguous + sequence of sectors. + + - BFQ supports full hierarchical scheduling, exporting a cgroups + interface. Since each node has a full scheduler, each group can + be assigned its own weight. + + - If the cgroups interface is not used, only I/O priorities can be + assigned to processes, with ioprio values mapped to weights + with the relation weight = IOPRIO_BE_NR - ioprio. + + - ioprio classes are served in strict priority order, i.e., lower + priority queues are not served as long as there are higher + priority queues. Among queues in the same class the bandwidth is + distributed in proportion to the weight of each queue. A very + thin extra bandwidth is however guaranteed to the Idle class, to + prevent it from starving. + +Signed-off-by: Paolo Valente +Signed-off-by: Arianna Avanzini +--- + block/bfq-cgroup.c | 936 ++++++++++++ + block/bfq-ioc.c | 36 + + block/bfq-iosched.c | 3902 +++++++++++++++++++++++++++++++++++++++++++++++++++ + block/bfq-sched.c | 1214 ++++++++++++++++ + block/bfq.h | 775 ++++++++++ + 5 files changed, 6863 insertions(+) + create mode 100644 block/bfq-cgroup.c + create mode 100644 block/bfq-ioc.c + create mode 100644 block/bfq-iosched.c + create mode 100644 block/bfq-sched.c + create mode 100644 block/bfq.h + +diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c +new file mode 100644 +index 0000000..11e2f1d +--- /dev/null ++++ b/block/bfq-cgroup.c +@@ -0,0 +1,936 @@ ++/* ++ * BFQ: CGROUPS support. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ */ ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ ++static DEFINE_MUTEX(bfqio_mutex); ++ ++static bool bfqio_is_removed(struct bfqio_cgroup *bgrp) ++{ ++ return bgrp ? !bgrp->online : false; ++} ++ ++static struct bfqio_cgroup bfqio_root_cgroup = { ++ .weight = BFQ_DEFAULT_GRP_WEIGHT, ++ .ioprio = BFQ_DEFAULT_GRP_IOPRIO, ++ .ioprio_class = BFQ_DEFAULT_GRP_CLASS, ++}; ++ ++static inline void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ entity->ioprio = entity->new_ioprio; ++ entity->ioprio_class = entity->new_ioprio_class; ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static struct bfqio_cgroup *css_to_bfqio(struct cgroup_subsys_state *css) ++{ ++ return css ? container_of(css, struct bfqio_cgroup, css) : NULL; ++} ++ ++/* ++ * Search the bfq_group for bfqd into the hash table (by now only a list) ++ * of bgrp. Must be called under rcu_read_lock(). ++ */ ++static struct bfq_group *bfqio_lookup_group(struct bfqio_cgroup *bgrp, ++ struct bfq_data *bfqd) ++{ ++ struct bfq_group *bfqg; ++ void *key; ++ ++ hlist_for_each_entry_rcu(bfqg, &bgrp->group_data, group_node) { ++ key = rcu_dereference(bfqg->bfqd); ++ if (key == bfqd) ++ return bfqg; ++ } ++ ++ return NULL; ++} ++ ++static inline void bfq_group_init_entity(struct bfqio_cgroup *bgrp, ++ struct bfq_group *bfqg) ++{ ++ struct bfq_entity *entity = &bfqg->entity; ++ ++ /* ++ * If the weight of the entity has never been set via the sysfs ++ * interface, then bgrp->weight == 0. In this case we initialize ++ * the weight from the current ioprio value. Otherwise, the group ++ * weight, if set, has priority over the ioprio value. ++ */ ++ if (bgrp->weight == 0) { ++ entity->new_weight = bfq_ioprio_to_weight(bgrp->ioprio); ++ entity->new_ioprio = bgrp->ioprio; ++ } else { ++ if (bgrp->weight < BFQ_MIN_WEIGHT || ++ bgrp->weight > BFQ_MAX_WEIGHT) { ++ printk(KERN_CRIT "bfq_group_init_entity: " ++ "bgrp->weight %d\n", bgrp->weight); ++ BUG(); ++ } ++ entity->new_weight = bgrp->weight; ++ entity->new_ioprio = bfq_weight_to_ioprio(bgrp->weight); ++ } ++ entity->orig_weight = entity->weight = entity->new_weight; ++ entity->ioprio = entity->new_ioprio; ++ entity->ioprio_class = entity->new_ioprio_class = bgrp->ioprio_class; ++ entity->my_sched_data = &bfqg->sched_data; ++ bfqg->active_entities = 0; ++} ++ ++static inline void bfq_group_set_parent(struct bfq_group *bfqg, ++ struct bfq_group *parent) ++{ ++ struct bfq_entity *entity; ++ ++ BUG_ON(parent == NULL); ++ BUG_ON(bfqg == NULL); ++ ++ entity = &bfqg->entity; ++ entity->parent = parent->my_entity; ++ entity->sched_data = &parent->sched_data; ++} ++ ++/** ++ * bfq_group_chain_alloc - allocate a chain of groups. ++ * @bfqd: queue descriptor. ++ * @css: the leaf cgroup_subsys_state this chain starts from. ++ * ++ * Allocate a chain of groups starting from the one belonging to ++ * @cgroup up to the root cgroup. Stop if a cgroup on the chain ++ * to the root has already an allocated group on @bfqd. ++ */ ++static struct bfq_group *bfq_group_chain_alloc(struct bfq_data *bfqd, ++ struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp; ++ struct bfq_group *bfqg, *prev = NULL, *leaf = NULL; ++ ++ for (; css != NULL; css = css->parent) { ++ bgrp = css_to_bfqio(css); ++ ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ if (bfqg != NULL) { ++ /* ++ * All the cgroups in the path from there to the ++ * root must have a bfq_group for bfqd, so we don't ++ * need any more allocations. ++ */ ++ break; ++ } ++ ++ bfqg = kzalloc(sizeof(*bfqg), GFP_ATOMIC); ++ if (bfqg == NULL) ++ goto cleanup; ++ ++ bfq_group_init_entity(bgrp, bfqg); ++ bfqg->my_entity = &bfqg->entity; ++ ++ if (leaf == NULL) { ++ leaf = bfqg; ++ prev = leaf; ++ } else { ++ bfq_group_set_parent(prev, bfqg); ++ /* ++ * Build a list of allocated nodes using the bfqd ++ * filed, that is still unused and will be ++ * initialized only after the node will be ++ * connected. ++ */ ++ prev->bfqd = bfqg; ++ prev = bfqg; ++ } ++ } ++ ++ return leaf; ++ ++cleanup: ++ while (leaf != NULL) { ++ prev = leaf; ++ leaf = leaf->bfqd; ++ kfree(prev); ++ } ++ ++ return NULL; ++} ++ ++/** ++ * bfq_group_chain_link - link an allocated group chain to a cgroup ++ * hierarchy. ++ * @bfqd: the queue descriptor. ++ * @css: the leaf cgroup_subsys_state to start from. ++ * @leaf: the leaf group (to be associated to @cgroup). ++ * ++ * Try to link a chain of groups to a cgroup hierarchy, connecting the ++ * nodes bottom-up, so we can be sure that when we find a cgroup in the ++ * hierarchy that already as a group associated to @bfqd all the nodes ++ * in the path to the root cgroup have one too. ++ * ++ * On locking: the queue lock protects the hierarchy (there is a hierarchy ++ * per device) while the bfqio_cgroup lock protects the list of groups ++ * belonging to the same cgroup. ++ */ ++static void bfq_group_chain_link(struct bfq_data *bfqd, ++ struct cgroup_subsys_state *css, ++ struct bfq_group *leaf) ++{ ++ struct bfqio_cgroup *bgrp; ++ struct bfq_group *bfqg, *next, *prev = NULL; ++ unsigned long flags; ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ ++ for (; css != NULL && leaf != NULL; css = css->parent) { ++ bgrp = css_to_bfqio(css); ++ next = leaf->bfqd; ++ ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ BUG_ON(bfqg != NULL); ++ ++ spin_lock_irqsave(&bgrp->lock, flags); ++ ++ rcu_assign_pointer(leaf->bfqd, bfqd); ++ hlist_add_head_rcu(&leaf->group_node, &bgrp->group_data); ++ hlist_add_head(&leaf->bfqd_node, &bfqd->group_list); ++ ++ spin_unlock_irqrestore(&bgrp->lock, flags); ++ ++ prev = leaf; ++ leaf = next; ++ } ++ ++ BUG_ON(css == NULL && leaf != NULL); ++ if (css != NULL && prev != NULL) { ++ bgrp = css_to_bfqio(css); ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ bfq_group_set_parent(prev, bfqg); ++ } ++} ++ ++/** ++ * bfq_find_alloc_group - return the group associated to @bfqd in @cgroup. ++ * @bfqd: queue descriptor. ++ * @cgroup: cgroup being searched for. ++ * ++ * Return a group associated to @bfqd in @cgroup, allocating one if ++ * necessary. When a group is returned all the cgroups in the path ++ * to the root have a group associated to @bfqd. ++ * ++ * If the allocation fails, return the root group: this breaks guarantees ++ * but is a safe fallback. If this loss becomes a problem it can be ++ * mitigated using the equivalent weight (given by the product of the ++ * weights of the groups in the path from @group to the root) in the ++ * root scheduler. ++ * ++ * We allocate all the missing nodes in the path from the leaf cgroup ++ * to the root and we connect the nodes only after all the allocations ++ * have been successful. ++ */ ++static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd, ++ struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); ++ struct bfq_group *bfqg; ++ ++ bfqg = bfqio_lookup_group(bgrp, bfqd); ++ if (bfqg != NULL) ++ return bfqg; ++ ++ bfqg = bfq_group_chain_alloc(bfqd, css); ++ if (bfqg != NULL) ++ bfq_group_chain_link(bfqd, css, bfqg); ++ else ++ bfqg = bfqd->root_group; ++ ++ return bfqg; ++} ++ ++/** ++ * bfq_bfqq_move - migrate @bfqq to @bfqg. ++ * @bfqd: queue descriptor. ++ * @bfqq: the queue to move. ++ * @entity: @bfqq's entity. ++ * @bfqg: the group to move to. ++ * ++ * Move @bfqq to @bfqg, deactivating it from its old group and reactivating ++ * it on the new one. Avoid putting the entity on the old group idle tree. ++ * ++ * Must be called under the queue lock; the cgroup owning @bfqg must ++ * not disappear (by now this just means that we are called under ++ * rcu_read_lock()). ++ */ ++static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct bfq_entity *entity, struct bfq_group *bfqg) ++{ ++ int busy, resume; ++ ++ busy = bfq_bfqq_busy(bfqq); ++ resume = !RB_EMPTY_ROOT(&bfqq->sort_list); ++ ++ BUG_ON(resume && !entity->on_st); ++ BUG_ON(busy && !resume && entity->on_st && ++ bfqq != bfqd->in_service_queue); ++ ++ if (busy) { ++ BUG_ON(atomic_read(&bfqq->ref) < 2); ++ ++ if (!resume) ++ bfq_del_bfqq_busy(bfqd, bfqq, 0); ++ else ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ } else if (entity->on_st) ++ bfq_put_idle_entity(bfq_entity_service_tree(entity), entity); ++ ++ /* ++ * Here we use a reference to bfqg. We don't need a refcounter ++ * as the cgroup reference will not be dropped, so that its ++ * destroy() callback will not be invoked. ++ */ ++ entity->parent = bfqg->my_entity; ++ entity->sched_data = &bfqg->sched_data; ++ ++ if (busy && resume) ++ bfq_activate_bfqq(bfqd, bfqq); ++ ++ if (bfqd->in_service_queue == NULL && !bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++} ++ ++/** ++ * __bfq_bic_change_cgroup - move @bic to @cgroup. ++ * @bfqd: the queue descriptor. ++ * @bic: the bic to move. ++ * @cgroup: the cgroup to move to. ++ * ++ * Move bic to cgroup, assuming that bfqd->queue is locked; the caller ++ * has to make sure that the reference to cgroup is valid across the call. ++ * ++ * NOTE: an alternative approach might have been to store the current ++ * cgroup in bfqq and getting a reference to it, reducing the lookup ++ * time here, at the price of slightly more complex code. ++ */ ++static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic, ++ struct cgroup_subsys_state *css) ++{ ++ struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0); ++ struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1); ++ struct bfq_entity *entity; ++ struct bfq_group *bfqg; ++ struct bfqio_cgroup *bgrp; ++ ++ bgrp = css_to_bfqio(css); ++ ++ bfqg = bfq_find_alloc_group(bfqd, css); ++ if (async_bfqq != NULL) { ++ entity = &async_bfqq->entity; ++ ++ if (entity->sched_data != &bfqg->sched_data) { ++ bic_set_bfqq(bic, NULL, 0); ++ bfq_log_bfqq(bfqd, async_bfqq, ++ "bic_change_group: %p %d", ++ async_bfqq, atomic_read(&async_bfqq->ref)); ++ bfq_put_queue(async_bfqq); ++ } ++ } ++ ++ if (sync_bfqq != NULL) { ++ entity = &sync_bfqq->entity; ++ if (entity->sched_data != &bfqg->sched_data) ++ bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg); ++ } ++ ++ return bfqg; ++} ++ ++/** ++ * bfq_bic_change_cgroup - move @bic to @cgroup. ++ * @bic: the bic being migrated. ++ * @cgroup: the destination cgroup. ++ * ++ * When the task owning @bic is moved to @cgroup, @bic is immediately ++ * moved into its new parent group. ++ */ ++static void bfq_bic_change_cgroup(struct bfq_io_cq *bic, ++ struct cgroup_subsys_state *css) ++{ ++ struct bfq_data *bfqd; ++ unsigned long uninitialized_var(flags); ++ ++ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), ++ &flags); ++ if (bfqd != NULL) { ++ __bfq_bic_change_cgroup(bfqd, bic, css); ++ bfq_put_bfqd_unlock(bfqd, &flags); ++ } ++} ++ ++/** ++ * bfq_bic_update_cgroup - update the cgroup of @bic. ++ * @bic: the @bic to update. ++ * ++ * Make sure that @bic is enqueued in the cgroup of the current task. ++ * We need this in addition to moving bics during the cgroup attach ++ * phase because the task owning @bic could be at its first disk ++ * access or we may end up in the root cgroup as the result of a ++ * memory allocation failure and here we try to move to the right ++ * group. ++ * ++ * Must be called under the queue lock. It is safe to use the returned ++ * value even after the rcu_read_unlock() as the migration/destruction ++ * paths act under the queue lock too. IOW it is impossible to race with ++ * group migration/destruction and end up with an invalid group as: ++ * a) here cgroup has not yet been destroyed, nor its destroy callback ++ * has started execution, as current holds a reference to it, ++ * b) if it is destroyed after rcu_read_unlock() [after current is ++ * migrated to a different cgroup] its attach() callback will have ++ * taken care of remove all the references to the old cgroup data. ++ */ ++static struct bfq_group *bfq_bic_update_cgroup(struct bfq_io_cq *bic) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ struct bfq_group *bfqg; ++ struct cgroup_subsys_state *css; ++ ++ BUG_ON(bfqd == NULL); ++ ++ rcu_read_lock(); ++ css = task_css(current, bfqio_cgrp_id); ++ bfqg = __bfq_bic_change_cgroup(bfqd, bic, css); ++ rcu_read_unlock(); ++ ++ return bfqg; ++} ++ ++/** ++ * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st. ++ * @st: the service tree being flushed. ++ */ ++static inline void bfq_flush_idle_tree(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entity = st->first_idle; ++ ++ for (; entity != NULL; entity = st->first_idle) ++ __bfq_deactivate_entity(entity, 0); ++} ++ ++/** ++ * bfq_reparent_leaf_entity - move leaf entity to the root_group. ++ * @bfqd: the device data structure with the root group. ++ * @entity: the entity to move. ++ */ ++static inline void bfq_reparent_leaf_entity(struct bfq_data *bfqd, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ BUG_ON(bfqq == NULL); ++ bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group); ++ return; ++} ++ ++/** ++ * bfq_reparent_active_entities - move to the root group all active ++ * entities. ++ * @bfqd: the device data structure with the root group. ++ * @bfqg: the group to move from. ++ * @st: the service tree with the entities. ++ * ++ * Needs queue_lock to be taken and reference to be valid over the call. ++ */ ++static inline void bfq_reparent_active_entities(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ struct bfq_service_tree *st) ++{ ++ struct rb_root *active = &st->active; ++ struct bfq_entity *entity = NULL; ++ ++ if (!RB_EMPTY_ROOT(&st->active)) ++ entity = bfq_entity_of(rb_first(active)); ++ ++ for (; entity != NULL; entity = bfq_entity_of(rb_first(active))) ++ bfq_reparent_leaf_entity(bfqd, entity); ++ ++ if (bfqg->sched_data.in_service_entity != NULL) ++ bfq_reparent_leaf_entity(bfqd, ++ bfqg->sched_data.in_service_entity); ++ ++ return; ++} ++ ++/** ++ * bfq_destroy_group - destroy @bfqg. ++ * @bgrp: the bfqio_cgroup containing @bfqg. ++ * @bfqg: the group being destroyed. ++ * ++ * Destroy @bfqg, making sure that it is not referenced from its parent. ++ */ ++static void bfq_destroy_group(struct bfqio_cgroup *bgrp, struct bfq_group *bfqg) ++{ ++ struct bfq_data *bfqd; ++ struct bfq_service_tree *st; ++ struct bfq_entity *entity = bfqg->my_entity; ++ unsigned long uninitialized_var(flags); ++ int i; ++ ++ hlist_del(&bfqg->group_node); ++ ++ /* ++ * Empty all service_trees belonging to this group before ++ * deactivating the group itself. ++ */ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) { ++ st = bfqg->sched_data.service_tree + i; ++ ++ /* ++ * The idle tree may still contain bfq_queues belonging ++ * to exited task because they never migrated to a different ++ * cgroup from the one being destroyed now. No one else ++ * can access them so it's safe to act without any lock. ++ */ ++ bfq_flush_idle_tree(st); ++ ++ /* ++ * It may happen that some queues are still active ++ * (busy) upon group destruction (if the corresponding ++ * processes have been forced to terminate). We move ++ * all the leaf entities corresponding to these queues ++ * to the root_group. ++ * Also, it may happen that the group has an entity ++ * in service, which is disconnected from the active ++ * tree: it must be moved, too. ++ * There is no need to put the sync queues, as the ++ * scheduler has taken no reference. ++ */ ++ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); ++ if (bfqd != NULL) { ++ bfq_reparent_active_entities(bfqd, bfqg, st); ++ bfq_put_bfqd_unlock(bfqd, &flags); ++ } ++ BUG_ON(!RB_EMPTY_ROOT(&st->active)); ++ BUG_ON(!RB_EMPTY_ROOT(&st->idle)); ++ } ++ BUG_ON(bfqg->sched_data.next_in_service != NULL); ++ BUG_ON(bfqg->sched_data.in_service_entity != NULL); ++ ++ /* ++ * We may race with device destruction, take extra care when ++ * dereferencing bfqg->bfqd. ++ */ ++ bfqd = bfq_get_bfqd_locked(&bfqg->bfqd, &flags); ++ if (bfqd != NULL) { ++ hlist_del(&bfqg->bfqd_node); ++ __bfq_deactivate_entity(entity, 0); ++ bfq_put_async_queues(bfqd, bfqg); ++ bfq_put_bfqd_unlock(bfqd, &flags); ++ } ++ BUG_ON(entity->tree != NULL); ++ ++ /* ++ * No need to defer the kfree() to the end of the RCU grace ++ * period: we are called from the destroy() callback of our ++ * cgroup, so we can be sure that no one is a) still using ++ * this cgroup or b) doing lookups in it. ++ */ ++ kfree(bfqg); ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ struct hlist_node *tmp; ++ struct bfq_group *bfqg; ++ ++ hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) ++ bfq_end_wr_async_queues(bfqd, bfqg); ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++/** ++ * bfq_disconnect_groups - disconnect @bfqd from all its groups. ++ * @bfqd: the device descriptor being exited. ++ * ++ * When the device exits we just make sure that no lookup can return ++ * the now unused group structures. They will be deallocated on cgroup ++ * destruction. ++ */ ++static void bfq_disconnect_groups(struct bfq_data *bfqd) ++{ ++ struct hlist_node *tmp; ++ struct bfq_group *bfqg; ++ ++ bfq_log(bfqd, "disconnect_groups beginning"); ++ hlist_for_each_entry_safe(bfqg, tmp, &bfqd->group_list, bfqd_node) { ++ hlist_del(&bfqg->bfqd_node); ++ ++ __bfq_deactivate_entity(bfqg->my_entity, 0); ++ ++ /* ++ * Don't remove from the group hash, just set an ++ * invalid key. No lookups can race with the ++ * assignment as bfqd is being destroyed; this ++ * implies also that new elements cannot be added ++ * to the list. ++ */ ++ rcu_assign_pointer(bfqg->bfqd, NULL); ++ ++ bfq_log(bfqd, "disconnect_groups: put async for group %p", ++ bfqg); ++ bfq_put_async_queues(bfqd, bfqg); ++ } ++} ++ ++static inline void bfq_free_root_group(struct bfq_data *bfqd) ++{ ++ struct bfqio_cgroup *bgrp = &bfqio_root_cgroup; ++ struct bfq_group *bfqg = bfqd->root_group; ++ ++ bfq_put_async_queues(bfqd, bfqg); ++ ++ spin_lock_irq(&bgrp->lock); ++ hlist_del_rcu(&bfqg->group_node); ++ spin_unlock_irq(&bgrp->lock); ++ ++ /* ++ * No need to synchronize_rcu() here: since the device is gone ++ * there cannot be any read-side access to its root_group. ++ */ ++ kfree(bfqg); ++} ++ ++static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) ++{ ++ struct bfq_group *bfqg; ++ struct bfqio_cgroup *bgrp; ++ int i; ++ ++ bfqg = kzalloc_node(sizeof(*bfqg), GFP_KERNEL, node); ++ if (bfqg == NULL) ++ return NULL; ++ ++ bfqg->entity.parent = NULL; ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++ ++ bgrp = &bfqio_root_cgroup; ++ spin_lock_irq(&bgrp->lock); ++ rcu_assign_pointer(bfqg->bfqd, bfqd); ++ hlist_add_head_rcu(&bfqg->group_node, &bgrp->group_data); ++ spin_unlock_irq(&bgrp->lock); ++ ++ return bfqg; ++} ++ ++#define SHOW_FUNCTION(__VAR) \ ++static u64 bfqio_cgroup_##__VAR##_read(struct cgroup_subsys_state *css, \ ++ struct cftype *cftype) \ ++{ \ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); \ ++ u64 ret = -ENODEV; \ ++ \ ++ mutex_lock(&bfqio_mutex); \ ++ if (bfqio_is_removed(bgrp)) \ ++ goto out_unlock; \ ++ \ ++ spin_lock_irq(&bgrp->lock); \ ++ ret = bgrp->__VAR; \ ++ spin_unlock_irq(&bgrp->lock); \ ++ \ ++out_unlock: \ ++ mutex_unlock(&bfqio_mutex); \ ++ return ret; \ ++} ++ ++SHOW_FUNCTION(weight); ++SHOW_FUNCTION(ioprio); ++SHOW_FUNCTION(ioprio_class); ++#undef SHOW_FUNCTION ++ ++#define STORE_FUNCTION(__VAR, __MIN, __MAX) \ ++static int bfqio_cgroup_##__VAR##_write(struct cgroup_subsys_state *css,\ ++ struct cftype *cftype, \ ++ u64 val) \ ++{ \ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); \ ++ struct bfq_group *bfqg; \ ++ int ret = -EINVAL; \ ++ \ ++ if (val < (__MIN) || val > (__MAX)) \ ++ return ret; \ ++ \ ++ ret = -ENODEV; \ ++ mutex_lock(&bfqio_mutex); \ ++ if (bfqio_is_removed(bgrp)) \ ++ goto out_unlock; \ ++ ret = 0; \ ++ \ ++ spin_lock_irq(&bgrp->lock); \ ++ bgrp->__VAR = (unsigned short)val; \ ++ hlist_for_each_entry(bfqg, &bgrp->group_data, group_node) { \ ++ /* \ ++ * Setting the ioprio_changed flag of the entity \ ++ * to 1 with new_##__VAR == ##__VAR would re-set \ ++ * the value of the weight to its ioprio mapping. \ ++ * Set the flag only if necessary. \ ++ */ \ ++ if ((unsigned short)val != bfqg->entity.new_##__VAR) { \ ++ bfqg->entity.new_##__VAR = (unsigned short)val; \ ++ /* \ ++ * Make sure that the above new value has been \ ++ * stored in bfqg->entity.new_##__VAR before \ ++ * setting the ioprio_changed flag. In fact, \ ++ * this flag may be read asynchronously (in \ ++ * critical sections protected by a different \ ++ * lock than that held here), and finding this \ ++ * flag set may cause the execution of the code \ ++ * for updating parameters whose value may \ ++ * depend also on bfqg->entity.new_##__VAR (in \ ++ * __bfq_entity_update_weight_prio). \ ++ * This barrier makes sure that the new value \ ++ * of bfqg->entity.new_##__VAR is correctly \ ++ * seen in that code. \ ++ */ \ ++ smp_wmb(); \ ++ bfqg->entity.ioprio_changed = 1; \ ++ } \ ++ } \ ++ spin_unlock_irq(&bgrp->lock); \ ++ \ ++out_unlock: \ ++ mutex_unlock(&bfqio_mutex); \ ++ return ret; \ ++} ++ ++STORE_FUNCTION(weight, BFQ_MIN_WEIGHT, BFQ_MAX_WEIGHT); ++STORE_FUNCTION(ioprio, 0, IOPRIO_BE_NR - 1); ++STORE_FUNCTION(ioprio_class, IOPRIO_CLASS_RT, IOPRIO_CLASS_IDLE); ++#undef STORE_FUNCTION ++ ++static struct cftype bfqio_files[] = { ++ { ++ .name = "weight", ++ .read_u64 = bfqio_cgroup_weight_read, ++ .write_u64 = bfqio_cgroup_weight_write, ++ }, ++ { ++ .name = "ioprio", ++ .read_u64 = bfqio_cgroup_ioprio_read, ++ .write_u64 = bfqio_cgroup_ioprio_write, ++ }, ++ { ++ .name = "ioprio_class", ++ .read_u64 = bfqio_cgroup_ioprio_class_read, ++ .write_u64 = bfqio_cgroup_ioprio_class_write, ++ }, ++ { }, /* terminate */ ++}; ++ ++static struct cgroup_subsys_state *bfqio_create(struct cgroup_subsys_state ++ *parent_css) ++{ ++ struct bfqio_cgroup *bgrp; ++ ++ if (parent_css != NULL) { ++ bgrp = kzalloc(sizeof(*bgrp), GFP_KERNEL); ++ if (bgrp == NULL) ++ return ERR_PTR(-ENOMEM); ++ } else ++ bgrp = &bfqio_root_cgroup; ++ ++ spin_lock_init(&bgrp->lock); ++ INIT_HLIST_HEAD(&bgrp->group_data); ++ bgrp->ioprio = BFQ_DEFAULT_GRP_IOPRIO; ++ bgrp->ioprio_class = BFQ_DEFAULT_GRP_CLASS; ++ ++ return &bgrp->css; ++} ++ ++/* ++ * We cannot support shared io contexts, as we have no means to support ++ * two tasks with the same ioc in two different groups without major rework ++ * of the main bic/bfqq data structures. By now we allow a task to change ++ * its cgroup only if it's the only owner of its ioc; the drawback of this ++ * behavior is that a group containing a task that forked using CLONE_IO ++ * will not be destroyed until the tasks sharing the ioc die. ++ */ ++static int bfqio_can_attach(struct cgroup_subsys_state *css, ++ struct cgroup_taskset *tset) ++{ ++ struct task_struct *task; ++ struct io_context *ioc; ++ int ret = 0; ++ ++ cgroup_taskset_for_each(task, tset) { ++ /* ++ * task_lock() is needed to avoid races with ++ * exit_io_context() ++ */ ++ task_lock(task); ++ ioc = task->io_context; ++ if (ioc != NULL && atomic_read(&ioc->nr_tasks) > 1) ++ /* ++ * ioc == NULL means that the task is either too ++ * young or exiting: if it has still no ioc the ++ * ioc can't be shared, if the task is exiting the ++ * attach will fail anyway, no matter what we ++ * return here. ++ */ ++ ret = -EINVAL; ++ task_unlock(task); ++ if (ret) ++ break; ++ } ++ ++ return ret; ++} ++ ++static void bfqio_attach(struct cgroup_subsys_state *css, ++ struct cgroup_taskset *tset) ++{ ++ struct task_struct *task; ++ struct io_context *ioc; ++ struct io_cq *icq; ++ ++ /* ++ * IMPORTANT NOTE: The move of more than one process at a time to a ++ * new group has not yet been tested. ++ */ ++ cgroup_taskset_for_each(task, tset) { ++ ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE); ++ if (ioc) { ++ /* ++ * Handle cgroup change here. ++ */ ++ rcu_read_lock(); ++ hlist_for_each_entry_rcu(icq, &ioc->icq_list, ioc_node) ++ if (!strncmp( ++ icq->q->elevator->type->elevator_name, ++ "bfq", ELV_NAME_MAX)) ++ bfq_bic_change_cgroup(icq_to_bic(icq), ++ css); ++ rcu_read_unlock(); ++ put_io_context(ioc); ++ } ++ } ++} ++ ++static void bfqio_destroy(struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); ++ struct hlist_node *tmp; ++ struct bfq_group *bfqg; ++ ++ /* ++ * Since we are destroying the cgroup, there are no more tasks ++ * referencing it, and all the RCU grace periods that may have ++ * referenced it are ended (as the destruction of the parent ++ * cgroup is RCU-safe); bgrp->group_data will not be accessed by ++ * anything else and we don't need any synchronization. ++ */ ++ hlist_for_each_entry_safe(bfqg, tmp, &bgrp->group_data, group_node) ++ bfq_destroy_group(bgrp, bfqg); ++ ++ BUG_ON(!hlist_empty(&bgrp->group_data)); ++ ++ kfree(bgrp); ++} ++ ++static int bfqio_css_online(struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); ++ ++ mutex_lock(&bfqio_mutex); ++ bgrp->online = true; ++ mutex_unlock(&bfqio_mutex); ++ ++ return 0; ++} ++ ++static void bfqio_css_offline(struct cgroup_subsys_state *css) ++{ ++ struct bfqio_cgroup *bgrp = css_to_bfqio(css); ++ ++ mutex_lock(&bfqio_mutex); ++ bgrp->online = false; ++ mutex_unlock(&bfqio_mutex); ++} ++ ++struct cgroup_subsys bfqio_cgrp_subsys = { ++ .css_alloc = bfqio_create, ++ .css_online = bfqio_css_online, ++ .css_offline = bfqio_css_offline, ++ .can_attach = bfqio_can_attach, ++ .attach = bfqio_attach, ++ .css_free = bfqio_destroy, ++ .legacy_cftypes = bfqio_files, ++}; ++#else ++static inline void bfq_init_entity(struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++ entity->weight = entity->new_weight; ++ entity->orig_weight = entity->new_weight; ++ entity->ioprio = entity->new_ioprio; ++ entity->ioprio_class = entity->new_ioprio_class; ++ entity->sched_data = &bfqg->sched_data; ++} ++ ++static inline struct bfq_group * ++bfq_bic_update_cgroup(struct bfq_io_cq *bic) ++{ ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ return bfqd->root_group; ++} ++ ++static inline void bfq_bfqq_move(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct bfq_entity *entity, ++ struct bfq_group *bfqg) ++{ ++} ++ ++static void bfq_end_wr_async(struct bfq_data *bfqd) ++{ ++ bfq_end_wr_async_queues(bfqd, bfqd->root_group); ++} ++ ++static inline void bfq_disconnect_groups(struct bfq_data *bfqd) ++{ ++ bfq_put_async_queues(bfqd, bfqd->root_group); ++} ++ ++static inline void bfq_free_root_group(struct bfq_data *bfqd) ++{ ++ kfree(bfqd->root_group); ++} ++ ++static struct bfq_group *bfq_alloc_root_group(struct bfq_data *bfqd, int node) ++{ ++ struct bfq_group *bfqg; ++ int i; ++ ++ bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node); ++ if (bfqg == NULL) ++ return NULL; ++ ++ for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) ++ bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT; ++ ++ return bfqg; ++} ++#endif +diff --git a/block/bfq-ioc.c b/block/bfq-ioc.c +new file mode 100644 +index 0000000..7f6b000 +--- /dev/null ++++ b/block/bfq-ioc.c +@@ -0,0 +1,36 @@ ++/* ++ * BFQ: I/O context handling. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++/** ++ * icq_to_bic - convert iocontext queue structure to bfq_io_cq. ++ * @icq: the iocontext queue. ++ */ ++static inline struct bfq_io_cq *icq_to_bic(struct io_cq *icq) ++{ ++ /* bic->icq is the first member, %NULL will convert to %NULL */ ++ return container_of(icq, struct bfq_io_cq, icq); ++} ++ ++/** ++ * bfq_bic_lookup - search into @ioc a bic associated to @bfqd. ++ * @bfqd: the lookup key. ++ * @ioc: the io_context of the process doing I/O. ++ * ++ * Queue lock must be held. ++ */ ++static inline struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd, ++ struct io_context *ioc) ++{ ++ if (ioc) ++ return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue)); ++ return NULL; ++} +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +new file mode 100644 +index 0000000..97ee934 +--- /dev/null ++++ b/block/bfq-iosched.c +@@ -0,0 +1,3902 @@ ++/* ++ * Budget Fair Queueing (BFQ) disk scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ * ++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ ++ * file. ++ * ++ * BFQ is a proportional-share storage-I/O scheduling algorithm based on ++ * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets, ++ * measured in number of sectors, to processes instead of time slices. The ++ * device is not granted to the in-service process for a given time slice, ++ * but until it has exhausted its assigned budget. This change from the time ++ * to the service domain allows BFQ to distribute the device throughput ++ * among processes as desired, without any distortion due to ZBR, workload ++ * fluctuations or other factors. BFQ uses an ad hoc internal scheduler, ++ * called B-WF2Q+, to schedule processes according to their budgets. More ++ * precisely, BFQ schedules queues associated to processes. Thanks to the ++ * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to ++ * I/O-bound processes issuing sequential requests (to boost the ++ * throughput), and yet guarantee a low latency to interactive and soft ++ * real-time applications. ++ * ++ * BFQ is described in [1], where also a reference to the initial, more ++ * theoretical paper on BFQ can be found. The interested reader can find ++ * in the latter paper full details on the main algorithm, as well as ++ * formulas of the guarantees and formal proofs of all the properties. ++ * With respect to the version of BFQ presented in these papers, this ++ * implementation adds a few more heuristics, such as the one that ++ * guarantees a low latency to soft real-time applications, and a ++ * hierarchical extension based on H-WF2Q+. ++ * ++ * B-WF2Q+ is based on WF2Q+, that is described in [2], together with ++ * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N) ++ * complexity derives from the one introduced with EEVDF in [3]. ++ * ++ * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness ++ * with the BFQ Disk I/O Scheduler'', ++ * Proceedings of the 5th Annual International Systems and Storage ++ * Conference (SYSTOR '12), June 2012. ++ * ++ * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf ++ * ++ * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing ++ * Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689, ++ * Oct 1997. ++ * ++ * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz ++ * ++ * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline ++ * First: A Flexible and Accurate Mechanism for Proportional Share ++ * Resource Allocation,'' technical report. ++ * ++ * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "bfq.h" ++#include "blk.h" ++ ++/* Max number of dispatches in one round of service. */ ++static const int bfq_quantum = 4; ++ ++/* Expiration time of sync (0) and async (1) requests, in jiffies. */ ++static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 }; ++ ++/* Maximum backwards seek, in KiB. */ ++static const int bfq_back_max = 16 * 1024; ++ ++/* Penalty of a backwards seek, in number of sectors. */ ++static const int bfq_back_penalty = 2; ++ ++/* Idling period duration, in jiffies. */ ++static int bfq_slice_idle = HZ / 125; ++ ++/* Default maximum budget values, in sectors and number of requests. */ ++static const int bfq_default_max_budget = 16 * 1024; ++static const int bfq_max_budget_async_rq = 4; ++ ++/* ++ * Async to sync throughput distribution is controlled as follows: ++ * when an async request is served, the entity is charged the number ++ * of sectors of the request, multiplied by the factor below ++ */ ++static const int bfq_async_charge_factor = 10; ++ ++/* Default timeout values, in jiffies, approximating CFQ defaults. */ ++static const int bfq_timeout_sync = HZ / 8; ++static int bfq_timeout_async = HZ / 25; ++ ++struct kmem_cache *bfq_pool; ++ ++/* Below this threshold (in ms), we consider thinktime immediate. */ ++#define BFQ_MIN_TT 2 ++ ++/* hw_tag detection: parallel requests threshold and min samples needed. */ ++#define BFQ_HW_QUEUE_THRESHOLD 4 ++#define BFQ_HW_QUEUE_SAMPLES 32 ++ ++#define BFQQ_SEEK_THR (sector_t)(8 * 1024) ++#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR) ++ ++/* Min samples used for peak rate estimation (for autotuning). */ ++#define BFQ_PEAK_RATE_SAMPLES 32 ++ ++/* Shift used for peak rate fixed precision calculations. */ ++#define BFQ_RATE_SHIFT 16 ++ ++/* ++ * By default, BFQ computes the duration of the weight raising for ++ * interactive applications automatically, using the following formula: ++ * duration = (R / r) * T, where r is the peak rate of the device, and ++ * R and T are two reference parameters. ++ * In particular, R is the peak rate of the reference device (see below), ++ * and T is a reference time: given the systems that are likely to be ++ * installed on the reference device according to its speed class, T is ++ * about the maximum time needed, under BFQ and while reading two files in ++ * parallel, to load typical large applications on these systems. ++ * In practice, the slower/faster the device at hand is, the more/less it ++ * takes to load applications with respect to the reference device. ++ * Accordingly, the longer/shorter BFQ grants weight raising to interactive ++ * applications. ++ * ++ * BFQ uses four different reference pairs (R, T), depending on: ++ * . whether the device is rotational or non-rotational; ++ * . whether the device is slow, such as old or portable HDDs, as well as ++ * SD cards, or fast, such as newer HDDs and SSDs. ++ * ++ * The device's speed class is dynamically (re)detected in ++ * bfq_update_peak_rate() every time the estimated peak rate is updated. ++ * ++ * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0] ++ * are the reference values for a slow/fast rotational device, whereas ++ * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for ++ * a slow/fast non-rotational device. Finally, device_speed_thresh are the ++ * thresholds used to switch between speed classes. ++ * Both the reference peak rates and the thresholds are measured in ++ * sectors/usec, left-shifted by BFQ_RATE_SHIFT. ++ */ ++static int R_slow[2] = {1536, 10752}; ++static int R_fast[2] = {17415, 34791}; ++/* ++ * To improve readability, a conversion function is used to initialize the ++ * following arrays, which entails that they can be initialized only in a ++ * function. ++ */ ++static int T_slow[2]; ++static int T_fast[2]; ++static int device_speed_thresh[2]; ++ ++#define BFQ_SERVICE_TREE_INIT ((struct bfq_service_tree) \ ++ { RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 }) ++ ++#define RQ_BIC(rq) ((struct bfq_io_cq *) (rq)->elv.priv[0]) ++#define RQ_BFQQ(rq) ((rq)->elv.priv[1]) ++ ++static inline void bfq_schedule_dispatch(struct bfq_data *bfqd); ++ ++#include "bfq-ioc.c" ++#include "bfq-sched.c" ++#include "bfq-cgroup.c" ++ ++#define bfq_class_idle(bfqq) ((bfqq)->entity.ioprio_class ==\ ++ IOPRIO_CLASS_IDLE) ++#define bfq_class_rt(bfqq) ((bfqq)->entity.ioprio_class ==\ ++ IOPRIO_CLASS_RT) ++ ++#define bfq_sample_valid(samples) ((samples) > 80) ++ ++/* ++ * We regard a request as SYNC, if either it's a read or has the SYNC bit ++ * set (in which case it could also be a direct WRITE). ++ */ ++static inline int bfq_bio_sync(struct bio *bio) ++{ ++ if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC)) ++ return 1; ++ ++ return 0; ++} ++ ++/* ++ * Scheduler run of queue, if there are requests pending and no one in the ++ * driver that will restart queueing. ++ */ ++static inline void bfq_schedule_dispatch(struct bfq_data *bfqd) ++{ ++ if (bfqd->queued != 0) { ++ bfq_log(bfqd, "schedule dispatch"); ++ kblockd_schedule_work(&bfqd->unplug_work); ++ } ++} ++ ++/* ++ * Lifted from AS - choose which of rq1 and rq2 that is best served now. ++ * We choose the request that is closesr to the head right now. Distance ++ * behind the head is penalized and only allowed to a certain extent. ++ */ ++static struct request *bfq_choose_req(struct bfq_data *bfqd, ++ struct request *rq1, ++ struct request *rq2, ++ sector_t last) ++{ ++ sector_t s1, s2, d1 = 0, d2 = 0; ++ unsigned long back_max; ++#define BFQ_RQ1_WRAP 0x01 /* request 1 wraps */ ++#define BFQ_RQ2_WRAP 0x02 /* request 2 wraps */ ++ unsigned wrap = 0; /* bit mask: requests behind the disk head? */ ++ ++ if (rq1 == NULL || rq1 == rq2) ++ return rq2; ++ if (rq2 == NULL) ++ return rq1; ++ ++ if (rq_is_sync(rq1) && !rq_is_sync(rq2)) ++ return rq1; ++ else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) ++ return rq2; ++ if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META)) ++ return rq1; ++ else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META)) ++ return rq2; ++ ++ s1 = blk_rq_pos(rq1); ++ s2 = blk_rq_pos(rq2); ++ ++ /* ++ * By definition, 1KiB is 2 sectors. ++ */ ++ back_max = bfqd->bfq_back_max * 2; ++ ++ /* ++ * Strict one way elevator _except_ in the case where we allow ++ * short backward seeks which are biased as twice the cost of a ++ * similar forward seek. ++ */ ++ if (s1 >= last) ++ d1 = s1 - last; ++ else if (s1 + back_max >= last) ++ d1 = (last - s1) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ1_WRAP; ++ ++ if (s2 >= last) ++ d2 = s2 - last; ++ else if (s2 + back_max >= last) ++ d2 = (last - s2) * bfqd->bfq_back_penalty; ++ else ++ wrap |= BFQ_RQ2_WRAP; ++ ++ /* Found required data */ ++ ++ /* ++ * By doing switch() on the bit mask "wrap" we avoid having to ++ * check two variables for all permutations: --> faster! ++ */ ++ switch (wrap) { ++ case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ ++ if (d1 < d2) ++ return rq1; ++ else if (d2 < d1) ++ return rq2; ++ else { ++ if (s1 >= s2) ++ return rq1; ++ else ++ return rq2; ++ } ++ ++ case BFQ_RQ2_WRAP: ++ return rq1; ++ case BFQ_RQ1_WRAP: ++ return rq2; ++ case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */ ++ default: ++ /* ++ * Since both rqs are wrapped, ++ * start with the one that's further behind head ++ * (--> only *one* back seek required), ++ * since back seek takes more time than forward. ++ */ ++ if (s1 <= s2) ++ return rq1; ++ else ++ return rq2; ++ } ++} ++ ++static struct bfq_queue * ++bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root, ++ sector_t sector, struct rb_node **ret_parent, ++ struct rb_node ***rb_link) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *bfqq = NULL; ++ ++ parent = NULL; ++ p = &root->rb_node; ++ while (*p) { ++ struct rb_node **n; ++ ++ parent = *p; ++ bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ ++ /* ++ * Sort strictly based on sector. Smallest to the left, ++ * largest to the right. ++ */ ++ if (sector > blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_right; ++ else if (sector < blk_rq_pos(bfqq->next_rq)) ++ n = &(*p)->rb_left; ++ else ++ break; ++ p = n; ++ bfqq = NULL; ++ } ++ ++ *ret_parent = parent; ++ if (rb_link) ++ *rb_link = p; ++ ++ bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d", ++ (long long unsigned)sector, ++ bfqq != NULL ? bfqq->pid : 0); ++ ++ return bfqq; ++} ++ ++static void bfq_rq_pos_tree_add(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct rb_node **p, *parent; ++ struct bfq_queue *__bfqq; ++ ++ if (bfqq->pos_root != NULL) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ ++ if (bfq_class_idle(bfqq)) ++ return; ++ if (!bfqq->next_rq) ++ return; ++ ++ bfqq->pos_root = &bfqd->rq_pos_tree; ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root, ++ blk_rq_pos(bfqq->next_rq), &parent, &p); ++ if (__bfqq == NULL) { ++ rb_link_node(&bfqq->pos_node, parent, p); ++ rb_insert_color(&bfqq->pos_node, bfqq->pos_root); ++ } else ++ bfqq->pos_root = NULL; ++} ++ ++/* ++ * Tell whether there are active queues or groups with differentiated weights. ++ */ ++static inline bool bfq_differentiated_weights(struct bfq_data *bfqd) ++{ ++ BUG_ON(!bfqd->hw_tag); ++ /* ++ * For weights to differ, at least one of the trees must contain ++ * at least two nodes. ++ */ ++ return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) && ++ (bfqd->queue_weights_tree.rb_node->rb_left || ++ bfqd->queue_weights_tree.rb_node->rb_right) ++#ifdef CONFIG_CGROUP_BFQIO ++ ) || ++ (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) && ++ (bfqd->group_weights_tree.rb_node->rb_left || ++ bfqd->group_weights_tree.rb_node->rb_right) ++#endif ++ ); ++} ++ ++/* ++ * If the weight-counter tree passed as input contains no counter for ++ * the weight of the input entity, then add that counter; otherwise just ++ * increment the existing counter. ++ * ++ * Note that weight-counter trees contain few nodes in mostly symmetric ++ * scenarios. For example, if all queues have the same weight, then the ++ * weight-counter tree for the queues may contain at most one node. ++ * This holds even if low_latency is on, because weight-raised queues ++ * are not inserted in the tree. ++ * In most scenarios, the rate at which nodes are created/destroyed ++ * should be low too. ++ */ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ struct rb_node **new = &(root->rb_node), *parent = NULL; ++ ++ /* ++ * Do not insert if: ++ * - the device does not support queueing; ++ * - the entity is already associated with a counter, which happens if: ++ * 1) the entity is associated with a queue, 2) a request arrival ++ * has caused the queue to become both non-weight-raised, and hence ++ * change its weight, and backlogged; in this respect, each ++ * of the two events causes an invocation of this function, ++ * 3) this is the invocation of this function caused by the second ++ * event. This second invocation is actually useless, and we handle ++ * this fact by exiting immediately. More efficient or clearer ++ * solutions might possibly be adopted. ++ */ ++ if (!bfqd->hw_tag || entity->weight_counter) ++ return; ++ ++ while (*new) { ++ struct bfq_weight_counter *__counter = container_of(*new, ++ struct bfq_weight_counter, ++ weights_node); ++ parent = *new; ++ ++ if (entity->weight == __counter->weight) { ++ entity->weight_counter = __counter; ++ goto inc_counter; ++ } ++ if (entity->weight < __counter->weight) ++ new = &((*new)->rb_left); ++ else ++ new = &((*new)->rb_right); ++ } ++ ++ entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter), ++ GFP_ATOMIC); ++ entity->weight_counter->weight = entity->weight; ++ rb_link_node(&entity->weight_counter->weights_node, parent, new); ++ rb_insert_color(&entity->weight_counter->weights_node, root); ++ ++inc_counter: ++ entity->weight_counter->num_active++; ++} ++ ++/* ++ * Decrement the weight counter associated with the entity, and, if the ++ * counter reaches 0, remove the counter from the tree. ++ * See the comments to the function bfq_weights_tree_add() for considerations ++ * about overhead. ++ */ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root) ++{ ++ /* ++ * Check whether the entity is actually associated with a counter. ++ * In fact, the device may not be considered NCQ-capable for a while, ++ * which implies that no insertion in the weight trees is performed, ++ * after which the device may start to be deemed NCQ-capable, and hence ++ * this function may start to be invoked. This may cause the function ++ * to be invoked for entities that are not associated with any counter. ++ */ ++ if (!entity->weight_counter) ++ return; ++ ++ BUG_ON(RB_EMPTY_ROOT(root)); ++ BUG_ON(entity->weight_counter->weight != entity->weight); ++ ++ BUG_ON(!entity->weight_counter->num_active); ++ entity->weight_counter->num_active--; ++ if (entity->weight_counter->num_active > 0) ++ goto reset_entity_pointer; ++ ++ rb_erase(&entity->weight_counter->weights_node, root); ++ kfree(entity->weight_counter); ++ ++reset_entity_pointer: ++ entity->weight_counter = NULL; ++} ++ ++static struct request *bfq_find_next_rq(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct request *last) ++{ ++ struct rb_node *rbnext = rb_next(&last->rb_node); ++ struct rb_node *rbprev = rb_prev(&last->rb_node); ++ struct request *next = NULL, *prev = NULL; ++ ++ BUG_ON(RB_EMPTY_NODE(&last->rb_node)); ++ ++ if (rbprev != NULL) ++ prev = rb_entry_rq(rbprev); ++ ++ if (rbnext != NULL) ++ next = rb_entry_rq(rbnext); ++ else { ++ rbnext = rb_first(&bfqq->sort_list); ++ if (rbnext && rbnext != &last->rb_node) ++ next = rb_entry_rq(rbnext); ++ } ++ ++ return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last)); ++} ++ ++/* see the definition of bfq_async_charge_factor for details */ ++static inline unsigned long bfq_serv_to_charge(struct request *rq, ++ struct bfq_queue *bfqq) ++{ ++ return blk_rq_sectors(rq) * ++ (1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) * ++ bfq_async_charge_factor)); ++} ++ ++/** ++ * bfq_updated_next_req - update the queue after a new next_rq selection. ++ * @bfqd: the device data the queue belongs to. ++ * @bfqq: the queue to update. ++ * ++ * If the first request of a queue changes we make sure that the queue ++ * has enough budget to serve at least its first request (if the ++ * request has grown). We do this because if the queue has not enough ++ * budget for its first request, it has to go through two dispatch ++ * rounds to actually get it dispatched. ++ */ ++static void bfq_updated_next_req(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ struct request *next_rq = bfqq->next_rq; ++ unsigned long new_budget; ++ ++ if (next_rq == NULL) ++ return; ++ ++ if (bfqq == bfqd->in_service_queue) ++ /* ++ * In order not to break guarantees, budgets cannot be ++ * changed after an entity has been selected. ++ */ ++ return; ++ ++ BUG_ON(entity->tree != &st->active); ++ BUG_ON(entity == entity->sched_data->in_service_entity); ++ ++ new_budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ if (entity->budget != new_budget) { ++ entity->budget = new_budget; ++ bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu", ++ new_budget); ++ bfq_activate_bfqq(bfqd, bfqq); ++ } ++} ++ ++static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd) ++{ ++ u64 dur; ++ ++ if (bfqd->bfq_wr_max_time > 0) ++ return bfqd->bfq_wr_max_time; ++ ++ dur = bfqd->RT_prod; ++ do_div(dur, bfqd->peak_rate); ++ ++ return dur; ++} ++ ++/* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ ++static inline void bfq_reset_burst_list(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *item; ++ struct hlist_node *n; ++ ++ hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node) ++ hlist_del_init(&item->burst_list_node); ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++ bfqd->burst_size = 1; ++} ++ ++/* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */ ++static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ /* Increment burst size to take into account also bfqq */ ++ bfqd->burst_size++; ++ ++ if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) { ++ struct bfq_queue *pos, *bfqq_item; ++ struct hlist_node *n; ++ ++ /* ++ * Enough queues have been activated shortly after each ++ * other to consider this burst as large. ++ */ ++ bfqd->large_burst = true; ++ ++ /* ++ * We can now mark all queues in the burst list as ++ * belonging to a large burst. ++ */ ++ hlist_for_each_entry(bfqq_item, &bfqd->burst_list, ++ burst_list_node) ++ bfq_mark_bfqq_in_large_burst(bfqq_item); ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ ++ /* ++ * From now on, and until the current burst finishes, any ++ * new queue being activated shortly after the last queue ++ * was inserted in the burst can be immediately marked as ++ * belonging to a large burst. So the burst list is not ++ * needed any more. Remove it. ++ */ ++ hlist_for_each_entry_safe(pos, n, &bfqd->burst_list, ++ burst_list_node) ++ hlist_del_init(&pos->burst_list_node); ++ } else /* burst not yet large: add bfqq to the burst list */ ++ hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list); ++} ++ ++/* ++ * If many queues happen to become active shortly after each other, then, ++ * to help the processes associated to these queues get their job done as ++ * soon as possible, it is usually better to not grant either weight-raising ++ * or device idling to these queues. In this comment we describe, firstly, ++ * the reasons why this fact holds, and, secondly, the next function, which ++ * implements the main steps needed to properly mark these queues so that ++ * they can then be treated in a different way. ++ * ++ * As for the terminology, we say that a queue becomes active, i.e., ++ * switches from idle to backlogged, either when it is created (as a ++ * consequence of the arrival of an I/O request), or, if already existing, ++ * when a new request for the queue arrives while the queue is idle. ++ * Bursts of activations, i.e., activations of different queues occurring ++ * shortly after each other, are typically caused by services or applications ++ * that spawn or reactivate many parallel threads/processes. Examples are ++ * systemd during boot or git grep. ++ * ++ * These services or applications benefit mostly from a high throughput: ++ * the quicker the requests of the activated queues are cumulatively served, ++ * the sooner the target job of these queues gets completed. As a consequence, ++ * weight-raising any of these queues, which also implies idling the device ++ * for it, is almost always counterproductive: in most cases it just lowers ++ * throughput. ++ * ++ * On the other hand, a burst of activations may be also caused by the start ++ * of an application that does not consist in a lot of parallel I/O-bound ++ * threads. In fact, with a complex application, the burst may be just a ++ * consequence of the fact that several processes need to be executed to ++ * start-up the application. To start an application as quickly as possible, ++ * the best thing to do is to privilege the I/O related to the application ++ * with respect to all other I/O. Therefore, the best strategy to start as ++ * quickly as possible an application that causes a burst of activations is ++ * to weight-raise all the queues activated during the burst. This is the ++ * exact opposite of the best strategy for the other type of bursts. ++ * ++ * In the end, to take the best action for each of the two cases, the two ++ * types of bursts need to be distinguished. Fortunately, this seems ++ * relatively easy to do, by looking at the sizes of the bursts. In ++ * particular, we found a threshold such that bursts with a larger size ++ * than that threshold are apparently caused only by services or commands ++ * such as systemd or git grep. For brevity, hereafter we call just 'large' ++ * these bursts. BFQ *does not* weight-raise queues whose activations occur ++ * in a large burst. In addition, for each of these queues BFQ performs or ++ * does not perform idling depending on which choice boosts the throughput ++ * most. The exact choice depends on the device and request pattern at ++ * hand. ++ * ++ * Turning back to the next function, it implements all the steps needed ++ * to detect the occurrence of a large burst and to properly mark all the ++ * queues belonging to it (so that they can then be treated in a different ++ * way). This goal is achieved by maintaining a special "burst list" that ++ * holds, temporarily, the queues that belong to the burst in progress. The ++ * list is then used to mark these queues as belonging to a large burst if ++ * the burst does become large. The main steps are the following. ++ * ++ * . when the very first queue is activated, the queue is inserted into the ++ * list (as it could be the first queue in a possible burst) ++ * ++ * . if the current burst has not yet become large, and a queue Q that does ++ * not yet belong to the burst is activated shortly after the last time ++ * at which a new queue entered the burst list, then the function appends ++ * Q to the burst list ++ * ++ * . if, as a consequence of the previous step, the burst size reaches ++ * the large-burst threshold, then ++ * ++ * . all the queues in the burst list are marked as belonging to a ++ * large burst ++ * ++ * . the burst list is deleted; in fact, the burst list already served ++ * its purpose (keeping temporarily track of the queues in a burst, ++ * so as to be able to mark them as belonging to a large burst in the ++ * previous sub-step), and now is not needed any more ++ * ++ * . the device enters a large-burst mode ++ * ++ * . if a queue Q that does not belong to the burst is activated while ++ * the device is in large-burst mode and shortly after the last time ++ * at which a queue either entered the burst list or was marked as ++ * belonging to the current large burst, then Q is immediately marked ++ * as belonging to a large burst. ++ * ++ * . if a queue Q that does not belong to the burst is activated a while ++ * later, i.e., not shortly after, than the last time at which a queue ++ * either entered the burst list or was marked as belonging to the ++ * current large burst, then the current burst is deemed as finished and: ++ * ++ * . the large-burst mode is reset if set ++ * ++ * . the burst list is emptied ++ * ++ * . Q is inserted in the burst list, as Q may be the first queue ++ * in a possible new burst (then the burst list contains just Q ++ * after this step). ++ */ ++static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ bool idle_for_long_time) ++{ ++ /* ++ * If bfqq happened to be activated in a burst, but has been idle ++ * for at least as long as an interactive queue, then we assume ++ * that, in the overall I/O initiated in the burst, the I/O ++ * associated to bfqq is finished. So bfqq does not need to be ++ * treated as a queue belonging to a burst anymore. Accordingly, ++ * we reset bfqq's in_large_burst flag if set, and remove bfqq ++ * from the burst list if it's there. We do not decrement instead ++ * burst_size, because the fact that bfqq does not need to belong ++ * to the burst list any more does not invalidate the fact that ++ * bfqq may have been activated during the current burst. ++ */ ++ if (idle_for_long_time) { ++ hlist_del_init(&bfqq->burst_list_node); ++ bfq_clear_bfqq_in_large_burst(bfqq); ++ } ++ ++ /* ++ * If bfqq is already in the burst list or is part of a large ++ * burst, then there is nothing else to do. ++ */ ++ if (!hlist_unhashed(&bfqq->burst_list_node) || ++ bfq_bfqq_in_large_burst(bfqq)) ++ return; ++ ++ /* ++ * If bfqq's activation happens late enough, then the current ++ * burst is finished, and related data structures must be reset. ++ * ++ * In this respect, consider the special case where bfqq is the very ++ * first queue being activated. In this case, last_ins_in_burst is ++ * not yet significant when we get here. But it is easy to verify ++ * that, whether or not the following condition is true, bfqq will ++ * end up being inserted into the burst list. In particular the ++ * list will happen to contain only bfqq. And this is exactly what ++ * has to happen, as bfqq may be the first queue in a possible ++ * burst. ++ */ ++ if (time_is_before_jiffies(bfqd->last_ins_in_burst + ++ bfqd->bfq_burst_interval)) { ++ bfqd->large_burst = false; ++ bfq_reset_burst_list(bfqd, bfqq); ++ return; ++ } ++ ++ /* ++ * If we get here, then bfqq is being activated shortly after the ++ * last queue. So, if the current burst is also large, we can mark ++ * bfqq as belonging to this large burst immediately. ++ */ ++ if (bfqd->large_burst) { ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ return; ++ } ++ ++ /* ++ * If we get here, then a large-burst state has not yet been ++ * reached, but bfqq is being activated shortly after the last ++ * queue. Then we add bfqq to the burst. ++ */ ++ bfq_add_to_burst(bfqd, bfqq); ++} ++ ++static void bfq_add_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *next_rq, *prev; ++ unsigned long old_wr_coeff = bfqq->wr_coeff; ++ bool interactive = false; ++ ++ bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq)); ++ bfqq->queued[rq_is_sync(rq)]++; ++ bfqd->queued++; ++ ++ elv_rb_add(&bfqq->sort_list, rq); ++ ++ /* ++ * Check if this request is a better next-serve candidate. ++ */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position); ++ BUG_ON(next_rq == NULL); ++ bfqq->next_rq = next_rq; ++ ++ /* ++ * Adjust priority tree position, if next_rq changes. ++ */ ++ if (prev != bfqq->next_rq) ++ bfq_rq_pos_tree_add(bfqd, bfqq); ++ ++ if (!bfq_bfqq_busy(bfqq)) { ++ bool soft_rt, ++ idle_for_long_time = time_is_before_jiffies( ++ bfqq->budget_timeout + ++ bfqd->bfq_wr_min_idle_time); ++ ++ if (bfq_bfqq_sync(bfqq)) { ++ bool already_in_burst = ++ !hlist_unhashed(&bfqq->burst_list_node) || ++ bfq_bfqq_in_large_burst(bfqq); ++ bfq_handle_burst(bfqd, bfqq, idle_for_long_time); ++ /* ++ * If bfqq was not already in the current burst, ++ * then, at this point, bfqq either has been ++ * added to the current burst or has caused the ++ * current burst to terminate. In particular, in ++ * the second case, bfqq has become the first ++ * queue in a possible new burst. ++ * In both cases last_ins_in_burst needs to be ++ * moved forward. ++ */ ++ if (!already_in_burst) ++ bfqd->last_ins_in_burst = jiffies; ++ } ++ ++ soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && ++ !bfq_bfqq_in_large_burst(bfqq) && ++ time_is_before_jiffies(bfqq->soft_rt_next_start); ++ interactive = !bfq_bfqq_in_large_burst(bfqq) && ++ idle_for_long_time; ++ entity->budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ ++ if (!bfq_bfqq_IO_bound(bfqq)) { ++ if (time_before(jiffies, ++ RQ_BIC(rq)->ttime.last_end_request + ++ bfqd->bfq_slice_idle)) { ++ bfqq->requests_within_timer++; ++ if (bfqq->requests_within_timer >= ++ bfqd->bfq_requests_within_timer) ++ bfq_mark_bfqq_IO_bound(bfqq); ++ } else ++ bfqq->requests_within_timer = 0; ++ } ++ ++ if (!bfqd->low_latency) ++ goto add_bfqq_busy; ++ ++ /* ++ * If the queue is not being boosted and has been idle ++ * for enough time, start a weight-raising period ++ */ ++ if (old_wr_coeff == 1 && (interactive || soft_rt)) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ if (interactive) ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ else ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais starting at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } else if (old_wr_coeff > 1) { ++ if (interactive) ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ else if (bfq_bfqq_in_large_burst(bfqq) || ++ (bfqq->wr_cur_max_time == ++ bfqd->bfq_wr_rt_max_time && ++ !soft_rt)) { ++ bfqq->wr_coeff = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais ending at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq-> ++ wr_cur_max_time)); ++ } else if (time_before( ++ bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time, ++ jiffies + ++ bfqd->bfq_wr_rt_max_time) && ++ soft_rt) { ++ /* ++ * ++ * The remaining weight-raising time is lower ++ * than bfqd->bfq_wr_rt_max_time, which ++ * means that the application is enjoying ++ * weight raising either because deemed soft- ++ * rt in the near past, or because deemed ++ * interactive a long ago. In both cases, ++ * resetting now the current remaining weight- ++ * raising time for the application to the ++ * weight-raising duration for soft rt ++ * applications would not cause any latency ++ * increase for the application (as the new ++ * duration would be higher than the remaining ++ * time). ++ * ++ * In addition, the application is now meeting ++ * the requirements for being deemed soft rt. ++ * In the end we can correctly and safely ++ * (re)charge the weight-raising duration for ++ * the application with the weight-raising ++ * duration for soft rt applications. ++ * ++ * In particular, doing this recharge now, i.e., ++ * before the weight-raising period for the ++ * application finishes, reduces the probability ++ * of the following negative scenario: ++ * 1) the weight of a soft rt application is ++ * raised at startup (as for any newly ++ * created application), ++ * 2) since the application is not interactive, ++ * at a certain time weight-raising is ++ * stopped for the application, ++ * 3) at that time the application happens to ++ * still have pending requests, and hence ++ * is destined to not have a chance to be ++ * deemed soft rt before these requests are ++ * completed (see the comments to the ++ * function bfq_bfqq_softrt_next_start() ++ * for details on soft rt detection), ++ * 4) these pending requests experience a high ++ * latency because the application is not ++ * weight-raised while they are pending. ++ */ ++ bfqq->last_wr_start_finish = jiffies; ++ bfqq->wr_cur_max_time = ++ bfqd->bfq_wr_rt_max_time; ++ } ++ } ++ if (old_wr_coeff != bfqq->wr_coeff) ++ entity->ioprio_changed = 1; ++add_bfqq_busy: ++ bfqq->last_idle_bklogged = jiffies; ++ bfqq->service_from_backlogged = 0; ++ bfq_clear_bfqq_softrt_update(bfqq); ++ bfq_add_bfqq_busy(bfqd, bfqq); ++ } else { ++ if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) && ++ time_is_before_jiffies( ++ bfqq->last_wr_start_finish + ++ bfqd->bfq_wr_min_inter_arr_async)) { ++ bfqq->wr_coeff = bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); ++ ++ bfqd->wr_busy_queues++; ++ entity->ioprio_changed = 1; ++ bfq_log_bfqq(bfqd, bfqq, ++ "non-idle wrais starting at %lu, rais_max_time %u", ++ jiffies, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ if (prev != bfqq->next_rq) ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ if (bfqd->low_latency && ++ (old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive)) ++ bfqq->last_wr_start_finish = jiffies; ++} ++ ++static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd, ++ struct bio *bio) ++{ ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (bic == NULL) ++ return NULL; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ if (bfqq != NULL) ++ return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio)); ++ ++ return NULL; ++} ++ ++static void bfq_activate_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ ++ bfqd->rq_in_driver++; ++ bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ bfq_log(bfqd, "activate_request: new bfqd->last_position %llu", ++ (long long unsigned)bfqd->last_position); ++} ++ ++static inline void bfq_deactivate_request(struct request_queue *q, ++ struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ ++ BUG_ON(bfqd->rq_in_driver == 0); ++ bfqd->rq_in_driver--; ++} ++ ++static void bfq_remove_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ const int sync = rq_is_sync(rq); ++ ++ if (bfqq->next_rq == rq) { ++ bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq); ++ bfq_updated_next_req(bfqd, bfqq); ++ } ++ ++ list_del_init(&rq->queuelist); ++ BUG_ON(bfqq->queued[sync] == 0); ++ bfqq->queued[sync]--; ++ bfqd->queued--; ++ elv_rb_del(&bfqq->sort_list, rq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ /* ++ * Remove queue from request-position tree as it is empty. ++ */ ++ if (bfqq->pos_root != NULL) { ++ rb_erase(&bfqq->pos_node, bfqq->pos_root); ++ bfqq->pos_root = NULL; ++ } ++ } ++ ++ if (rq->cmd_flags & REQ_META) { ++ BUG_ON(bfqq->meta_pending == 0); ++ bfqq->meta_pending--; ++ } ++} ++ ++static int bfq_merge(struct request_queue *q, struct request **req, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct request *__rq; ++ ++ __rq = bfq_find_rq_fmerge(bfqd, bio); ++ if (__rq != NULL && elv_rq_merge_ok(__rq, bio)) { ++ *req = __rq; ++ return ELEVATOR_FRONT_MERGE; ++ } ++ ++ return ELEVATOR_NO_MERGE; ++} ++ ++static void bfq_merged_request(struct request_queue *q, struct request *req, ++ int type) ++{ ++ if (type == ELEVATOR_FRONT_MERGE && ++ rb_prev(&req->rb_node) && ++ blk_rq_pos(req) < ++ blk_rq_pos(container_of(rb_prev(&req->rb_node), ++ struct request, rb_node))) { ++ struct bfq_queue *bfqq = RQ_BFQQ(req); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ struct request *prev, *next_rq; ++ ++ /* Reposition request in its sort_list */ ++ elv_rb_del(&bfqq->sort_list, req); ++ elv_rb_add(&bfqq->sort_list, req); ++ /* Choose next request to be served for bfqq */ ++ prev = bfqq->next_rq; ++ next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req, ++ bfqd->last_position); ++ BUG_ON(next_rq == NULL); ++ bfqq->next_rq = next_rq; ++ /* ++ * If next_rq changes, update both the queue's budget to ++ * fit the new request and the queue's position in its ++ * rq_pos_tree. ++ */ ++ if (prev != bfqq->next_rq) { ++ bfq_updated_next_req(bfqd, bfqq); ++ bfq_rq_pos_tree_add(bfqd, bfqq); ++ } ++ } ++} ++ ++static void bfq_merged_requests(struct request_queue *q, struct request *rq, ++ struct request *next) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ /* ++ * Reposition in fifo if next is older than rq. ++ */ ++ if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && ++ time_before(next->fifo_time, rq->fifo_time)) { ++ list_move(&rq->queuelist, &next->queuelist); ++ rq->fifo_time = next->fifo_time; ++ } ++ ++ if (bfqq->next_rq == next) ++ bfqq->next_rq = rq; ++ ++ bfq_remove_request(next); ++} ++ ++/* Must be called with bfqq != NULL */ ++static inline void bfq_bfqq_end_wr(struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfqq == NULL); ++ if (bfq_bfqq_busy(bfqq)) ++ bfqq->bfqd->wr_busy_queues--; ++ bfqq->wr_coeff = 1; ++ bfqq->wr_cur_max_time = 0; ++ /* Trigger a weight change on the next activation of the queue */ ++ bfqq->entity.ioprio_changed = 1; ++} ++ ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ if (bfqg->async_bfqq[i][j] != NULL) ++ bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]); ++ if (bfqg->async_idle_bfqq != NULL) ++ bfq_bfqq_end_wr(bfqg->async_idle_bfqq); ++} ++ ++static void bfq_end_wr(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq; ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) ++ bfq_bfqq_end_wr(bfqq); ++ bfq_end_wr_async(bfqd); ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++} ++ ++static int bfq_allow_merge(struct request_queue *q, struct request *rq, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ /* ++ * Disallow merge of a sync bio into an async request. ++ */ ++ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) ++ return 0; ++ ++ /* ++ * Lookup the bfqq that this bio will be queued with. Allow ++ * merge only if rq is queued there. ++ * Queue lock is held here. ++ */ ++ bic = bfq_bic_lookup(bfqd, current->io_context); ++ if (bic == NULL) ++ return 0; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ return bfqq == RQ_BFQQ(rq); ++} ++ ++static void __bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq != NULL) { ++ bfq_mark_bfqq_must_alloc(bfqq); ++ bfq_mark_bfqq_budget_new(bfqq); ++ bfq_clear_bfqq_fifo_expire(bfqq); ++ ++ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_in_service_queue, cur-budget = %lu", ++ bfqq->entity.budget); ++ } ++ ++ bfqd->in_service_queue = bfqq; ++} ++ ++/* ++ * Get and set a new queue for service. ++ */ ++static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (!bfqq) ++ bfqq = bfq_get_next_queue(bfqd); ++ else ++ bfq_get_next_queue_forced(bfqd, bfqq); ++ ++ __bfq_set_in_service_queue(bfqd, bfqq); ++ return bfqq; ++} ++ ++static inline sector_t bfq_dist_from_last(struct bfq_data *bfqd, ++ struct request *rq) ++{ ++ if (blk_rq_pos(rq) >= bfqd->last_position) ++ return blk_rq_pos(rq) - bfqd->last_position; ++ else ++ return bfqd->last_position - blk_rq_pos(rq); ++} ++ ++/* ++ * Return true if bfqq has no request pending and rq is close enough to ++ * bfqd->last_position, or if rq is closer to bfqd->last_position than ++ * bfqq->next_rq ++ */ ++static inline int bfq_rq_close(struct bfq_data *bfqd, struct request *rq) ++{ ++ return bfq_dist_from_last(bfqd, rq) <= BFQQ_SEEK_THR; ++} ++ ++static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) ++{ ++ struct rb_root *root = &bfqd->rq_pos_tree; ++ struct rb_node *parent, *node; ++ struct bfq_queue *__bfqq; ++ sector_t sector = bfqd->last_position; ++ ++ if (RB_EMPTY_ROOT(root)) ++ return NULL; ++ ++ /* ++ * First, if we find a request starting at the end of the last ++ * request, choose it. ++ */ ++ __bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL); ++ if (__bfqq != NULL) ++ return __bfqq; ++ ++ /* ++ * If the exact sector wasn't found, the parent of the NULL leaf ++ * will contain the closest sector (rq_pos_tree sorted by ++ * next_request position). ++ */ ++ __bfqq = rb_entry(parent, struct bfq_queue, pos_node); ++ if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ return __bfqq; ++ ++ if (blk_rq_pos(__bfqq->next_rq) < sector) ++ node = rb_next(&__bfqq->pos_node); ++ else ++ node = rb_prev(&__bfqq->pos_node); ++ if (node == NULL) ++ return NULL; ++ ++ __bfqq = rb_entry(node, struct bfq_queue, pos_node); ++ if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ return __bfqq; ++ ++ return NULL; ++} ++ ++/* ++ * bfqd - obvious ++ * cur_bfqq - passed in so that we don't decide that the current queue ++ * is closely cooperating with itself. ++ * ++ * We are assuming that cur_bfqq has dispatched at least one request, ++ * and that bfqd->last_position reflects a position on the disk associated ++ * with the I/O issued by cur_bfqq. ++ */ ++static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, ++ struct bfq_queue *cur_bfqq) ++{ ++ struct bfq_queue *bfqq; ++ ++ if (bfq_class_idle(cur_bfqq)) ++ return NULL; ++ if (!bfq_bfqq_sync(cur_bfqq)) ++ return NULL; ++ if (BFQQ_SEEKY(cur_bfqq)) ++ return NULL; ++ ++ /* If device has only one backlogged bfq_queue, don't search. */ ++ if (bfqd->busy_queues == 1) ++ return NULL; ++ ++ /* ++ * We should notice if some of the queues are cooperating, e.g. ++ * working closely on the same area of the disk. In that case, ++ * we can group them together and don't waste time idling. ++ */ ++ bfqq = bfqq_close(bfqd); ++ if (bfqq == NULL || bfqq == cur_bfqq) ++ return NULL; ++ ++ /* ++ * Do not merge queues from different bfq_groups. ++ */ ++ if (bfqq->entity.parent != cur_bfqq->entity.parent) ++ return NULL; ++ ++ /* ++ * It only makes sense to merge sync queues. ++ */ ++ if (!bfq_bfqq_sync(bfqq)) ++ return NULL; ++ if (BFQQ_SEEKY(bfqq)) ++ return NULL; ++ ++ /* ++ * Do not merge queues of different priority classes. ++ */ ++ if (bfq_class_rt(bfqq) != bfq_class_rt(cur_bfqq)) ++ return NULL; ++ ++ return bfqq; ++} ++ ++/* ++ * If enough samples have been computed, return the current max budget ++ * stored in bfqd, which is dynamically updated according to the ++ * estimated disk peak rate; otherwise return the default max budget ++ */ ++static inline unsigned long bfq_max_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < 194) ++ return bfq_default_max_budget; ++ else ++ return bfqd->bfq_max_budget; ++} ++ ++/* ++ * Return min budget, which is a fraction of the current or default ++ * max budget (trying with 1/32) ++ */ ++static inline unsigned long bfq_min_budget(struct bfq_data *bfqd) ++{ ++ if (bfqd->budgets_assigned < 194) ++ return bfq_default_max_budget / 32; ++ else ++ return bfqd->bfq_max_budget / 32; ++} ++ ++static void bfq_arm_slice_timer(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfqd->in_service_queue; ++ struct bfq_io_cq *bic; ++ unsigned long sl; ++ ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Processes have exited, don't wait. */ ++ bic = bfqd->in_service_bic; ++ if (bic == NULL || atomic_read(&bic->icq.ioc->active_ref) == 0) ++ return; ++ ++ bfq_mark_bfqq_wait_request(bfqq); ++ ++ /* ++ * We don't want to idle for seeks, but we do want to allow ++ * fair distribution of slice time for a process doing back-to-back ++ * seeks. So allow a little bit of time for him to submit a new rq. ++ * ++ * To prevent processes with (partly) seeky workloads from ++ * being too ill-treated, grant them a small fraction of the ++ * assigned budget before reducing the waiting time to ++ * BFQ_MIN_TT. This happened to help reduce latency. ++ */ ++ sl = bfqd->bfq_slice_idle; ++ /* ++ * Unless the queue is being weight-raised, grant only minimum idle ++ * time if the queue either has been seeky for long enough or has ++ * already proved to be constantly seeky. ++ */ ++ if (bfq_sample_valid(bfqq->seek_samples) && ++ ((BFQQ_SEEKY(bfqq) && bfqq->entity.service > ++ bfq_max_budget(bfqq->bfqd) / 8) || ++ bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1) ++ sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT)); ++ else if (bfqq->wr_coeff > 1) ++ sl = sl * 3; ++ bfqd->last_idling_start = ktime_get(); ++ mod_timer(&bfqd->idle_slice_timer, jiffies + sl); ++ bfq_log(bfqd, "arm idle: %u/%u ms", ++ jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle)); ++} ++ ++/* ++ * Set the maximum time for the in-service queue to consume its ++ * budget. This prevents seeky processes from lowering the disk ++ * throughput (always guaranteed with a time slice scheme as in CFQ). ++ */ ++static void bfq_set_budget_timeout(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfqd->in_service_queue; ++ unsigned int timeout_coeff; ++ if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time) ++ timeout_coeff = 1; ++ else ++ timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight; ++ ++ bfqd->last_budget_start = ktime_get(); ++ ++ bfq_clear_bfqq_budget_new(bfqq); ++ bfqq->budget_timeout = jiffies + ++ bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff; ++ ++ bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u", ++ jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * ++ timeout_coeff)); ++} ++ ++/* ++ * Move request from internal lists to the request queue dispatch list. ++ */ ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ /* ++ * For consistency, the next instruction should have been executed ++ * after removing the request from the queue and dispatching it. ++ * We execute instead this instruction before bfq_remove_request() ++ * (and hence introduce a temporary inconsistency), for efficiency. ++ * In fact, in a forced_dispatch, this prevents two counters related ++ * to bfqq->dispatched to risk to be uselessly decremented if bfqq ++ * is not in service, and then to be incremented again after ++ * incrementing bfqq->dispatched. ++ */ ++ bfqq->dispatched++; ++ bfq_remove_request(rq); ++ elv_dispatch_sort(q, rq); ++ ++ if (bfq_bfqq_sync(bfqq)) ++ bfqd->sync_flight++; ++} ++ ++/* ++ * Return expired entry, or NULL to just start from scratch in rbtree. ++ */ ++static struct request *bfq_check_fifo(struct bfq_queue *bfqq) ++{ ++ struct request *rq = NULL; ++ ++ if (bfq_bfqq_fifo_expire(bfqq)) ++ return NULL; ++ ++ bfq_mark_bfqq_fifo_expire(bfqq); ++ ++ if (list_empty(&bfqq->fifo)) ++ return NULL; ++ ++ rq = rq_entry_fifo(bfqq->fifo.next); ++ ++ if (time_before(jiffies, rq->fifo_time)) ++ return NULL; ++ ++ return rq; ++} ++ ++/* Must be called with the queue_lock held. */ ++static int bfqq_process_refs(struct bfq_queue *bfqq) ++{ ++ int process_refs, io_refs; ++ ++ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; ++ process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; ++ BUG_ON(process_refs < 0); ++ return process_refs; ++} ++ ++static void bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ int process_refs, new_process_refs; ++ struct bfq_queue *__bfqq; ++ ++ /* ++ * If there are no process references on the new_bfqq, then it is ++ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain ++ * may have dropped their last reference (not just their last process ++ * reference). ++ */ ++ if (!bfqq_process_refs(new_bfqq)) ++ return; ++ ++ /* Avoid a circular list and skip interim queue merges. */ ++ while ((__bfqq = new_bfqq->new_bfqq)) { ++ if (__bfqq == bfqq) ++ return; ++ new_bfqq = __bfqq; ++ } ++ ++ process_refs = bfqq_process_refs(bfqq); ++ new_process_refs = bfqq_process_refs(new_bfqq); ++ /* ++ * If the process for the bfqq has gone away, there is no ++ * sense in merging the queues. ++ */ ++ if (process_refs == 0 || new_process_refs == 0) ++ return; ++ ++ /* ++ * Merge in the direction of the lesser amount of work. ++ */ ++ if (new_process_refs >= process_refs) { ++ bfqq->new_bfqq = new_bfqq; ++ atomic_add(process_refs, &new_bfqq->ref); ++ } else { ++ new_bfqq->new_bfqq = bfqq; ++ atomic_add(new_process_refs, &bfqq->ref); ++ } ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", ++ new_bfqq->pid); ++} ++ ++static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ return entity->budget - entity->service; ++} ++ ++static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ __bfq_bfqd_reset_in_service(bfqd); ++ ++ /* ++ * If this bfqq is shared between multiple processes, check ++ * to make sure that those processes are still issuing I/Os ++ * within the mean seek distance. If not, it may be time to ++ * break the queues apart again. ++ */ ++ if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq)) ++ bfq_mark_bfqq_split_coop(bfqq); ++ ++ if (RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ /* ++ * Overloading budget_timeout field to store the time ++ * at which the queue remains with no backlog; used by ++ * the weight-raising mechanism. ++ */ ++ bfqq->budget_timeout = jiffies; ++ bfq_del_bfqq_busy(bfqd, bfqq, 1); ++ } else { ++ bfq_activate_bfqq(bfqd, bfqq); ++ /* ++ * Resort priority tree of potential close cooperators. ++ */ ++ bfq_rq_pos_tree_add(bfqd, bfqq); ++ } ++} ++ ++/** ++ * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior. ++ * @bfqd: device data. ++ * @bfqq: queue to update. ++ * @reason: reason for expiration. ++ * ++ * Handle the feedback on @bfqq budget. See the body for detailed ++ * comments. ++ */ ++static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ enum bfqq_expiration reason) ++{ ++ struct request *next_rq; ++ unsigned long budget, min_budget; ++ ++ budget = bfqq->max_budget; ++ min_budget = bfq_min_budget(bfqd); ++ ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %lu, budg left %lu", ++ bfqq->entity.budget, bfq_bfqq_budget_left(bfqq)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %lu, min budg %lu", ++ budget, bfq_min_budget(bfqd)); ++ bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d", ++ bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue)); ++ ++ if (bfq_bfqq_sync(bfqq)) { ++ switch (reason) { ++ /* ++ * Caveat: in all the following cases we trade latency ++ * for throughput. ++ */ ++ case BFQ_BFQQ_TOO_IDLE: ++ /* ++ * This is the only case where we may reduce ++ * the budget: if there is no request of the ++ * process still waiting for completion, then ++ * we assume (tentatively) that the timer has ++ * expired because the batch of requests of ++ * the process could have been served with a ++ * smaller budget. Hence, betting that ++ * process will behave in the same way when it ++ * becomes backlogged again, we reduce its ++ * next budget. As long as we guess right, ++ * this budget cut reduces the latency ++ * experienced by the process. ++ * ++ * However, if there are still outstanding ++ * requests, then the process may have not yet ++ * issued its next request just because it is ++ * still waiting for the completion of some of ++ * the still outstanding ones. So in this ++ * subcase we do not reduce its budget, on the ++ * contrary we increase it to possibly boost ++ * the throughput, as discussed in the ++ * comments to the BUDGET_TIMEOUT case. ++ */ ++ if (bfqq->dispatched > 0) /* still outstanding reqs */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ else { ++ if (budget > 5 * min_budget) ++ budget -= 4 * min_budget; ++ else ++ budget = min_budget; ++ } ++ break; ++ case BFQ_BFQQ_BUDGET_TIMEOUT: ++ /* ++ * We double the budget here because: 1) it ++ * gives the chance to boost the throughput if ++ * this is not a seeky process (which may have ++ * bumped into this timeout because of, e.g., ++ * ZBR), 2) together with charge_full_budget ++ * it helps give seeky processes higher ++ * timestamps, and hence be served less ++ * frequently. ++ */ ++ budget = min(budget * 2, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_BUDGET_EXHAUSTED: ++ /* ++ * The process still has backlog, and did not ++ * let either the budget timeout or the disk ++ * idling timeout expire. Hence it is not ++ * seeky, has a short thinktime and may be ++ * happy with a higher budget too. So ++ * definitely increase the budget of this good ++ * candidate to boost the disk throughput. ++ */ ++ budget = min(budget * 4, bfqd->bfq_max_budget); ++ break; ++ case BFQ_BFQQ_NO_MORE_REQUESTS: ++ /* ++ * Leave the budget unchanged. ++ */ ++ default: ++ return; ++ } ++ } else /* async queue */ ++ /* async queues get always the maximum possible budget ++ * (their ability to dispatch is limited by ++ * @bfqd->bfq_max_budget_async_rq). ++ */ ++ budget = bfqd->bfq_max_budget; ++ ++ bfqq->max_budget = budget; ++ ++ if (bfqd->budgets_assigned >= 194 && bfqd->bfq_user_max_budget == 0 && ++ bfqq->max_budget > bfqd->bfq_max_budget) ++ bfqq->max_budget = bfqd->bfq_max_budget; ++ ++ /* ++ * Make sure that we have enough budget for the next request. ++ * Since the finish time of the bfqq must be kept in sync with ++ * the budget, be sure to call __bfq_bfqq_expire() after the ++ * update. ++ */ ++ next_rq = bfqq->next_rq; ++ if (next_rq != NULL) ++ bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget, ++ bfq_serv_to_charge(next_rq, bfqq)); ++ else ++ bfqq->entity.budget = bfqq->max_budget; ++ ++ bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %lu", ++ next_rq != NULL ? blk_rq_sectors(next_rq) : 0, ++ bfqq->entity.budget); ++} ++ ++static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout) ++{ ++ unsigned long max_budget; ++ ++ /* ++ * The max_budget calculated when autotuning is equal to the ++ * amount of sectors transfered in timeout_sync at the ++ * estimated peak rate. ++ */ ++ max_budget = (unsigned long)(peak_rate * 1000 * ++ timeout >> BFQ_RATE_SHIFT); ++ ++ return max_budget; ++} ++ ++/* ++ * In addition to updating the peak rate, checks whether the process ++ * is "slow", and returns 1 if so. This slow flag is used, in addition ++ * to the budget timeout, to reduce the amount of service provided to ++ * seeky processes, and hence reduce their chances to lower the ++ * throughput. See the code for more details. ++ */ ++static int bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int compensate, enum bfqq_expiration reason) ++{ ++ u64 bw, usecs, expected, timeout; ++ ktime_t delta; ++ int update = 0; ++ ++ if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq)) ++ return 0; ++ ++ if (compensate) ++ delta = bfqd->last_idling_start; ++ else ++ delta = ktime_get(); ++ delta = ktime_sub(delta, bfqd->last_budget_start); ++ usecs = ktime_to_us(delta); ++ ++ /* Don't trust short/unrealistic values. */ ++ if (usecs < 100 || usecs >= LONG_MAX) ++ return 0; ++ ++ /* ++ * Calculate the bandwidth for the last slice. We use a 64 bit ++ * value to store the peak rate, in sectors per usec in fixed ++ * point math. We do so to have enough precision in the estimate ++ * and to avoid overflows. ++ */ ++ bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT; ++ do_div(bw, (unsigned long)usecs); ++ ++ timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); ++ ++ /* ++ * Use only long (> 20ms) intervals to filter out spikes for ++ * the peak rate estimation. ++ */ ++ if (usecs > 20000) { ++ if (bw > bfqd->peak_rate || ++ (!BFQQ_SEEKY(bfqq) && ++ reason == BFQ_BFQQ_BUDGET_TIMEOUT)) { ++ bfq_log(bfqd, "measured bw =%llu", bw); ++ /* ++ * To smooth oscillations use a low-pass filter with ++ * alpha=7/8, i.e., ++ * new_rate = (7/8) * old_rate + (1/8) * bw ++ */ ++ do_div(bw, 8); ++ if (bw == 0) ++ return 0; ++ bfqd->peak_rate *= 7; ++ do_div(bfqd->peak_rate, 8); ++ bfqd->peak_rate += bw; ++ update = 1; ++ bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate); ++ } ++ ++ update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1; ++ ++ if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES) ++ bfqd->peak_rate_samples++; ++ ++ if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES && ++ update) { ++ int dev_type = blk_queue_nonrot(bfqd->queue); ++ if (bfqd->bfq_user_max_budget == 0) { ++ bfqd->bfq_max_budget = ++ bfq_calc_max_budget(bfqd->peak_rate, ++ timeout); ++ bfq_log(bfqd, "new max_budget=%lu", ++ bfqd->bfq_max_budget); ++ } ++ if (bfqd->device_speed == BFQ_BFQD_FAST && ++ bfqd->peak_rate < device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_SLOW; ++ bfqd->RT_prod = R_slow[dev_type] * ++ T_slow[dev_type]; ++ } else if (bfqd->device_speed == BFQ_BFQD_SLOW && ++ bfqd->peak_rate > device_speed_thresh[dev_type]) { ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ bfqd->RT_prod = R_fast[dev_type] * ++ T_fast[dev_type]; ++ } ++ } ++ } ++ ++ /* ++ * If the process has been served for a too short time ++ * interval to let its possible sequential accesses prevail on ++ * the initial seek time needed to move the disk head on the ++ * first sector it requested, then give the process a chance ++ * and for the moment return false. ++ */ ++ if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8) ++ return 0; ++ ++ /* ++ * A process is considered ``slow'' (i.e., seeky, so that we ++ * cannot treat it fairly in the service domain, as it would ++ * slow down too much the other processes) if, when a slice ++ * ends for whatever reason, it has received service at a ++ * rate that would not be high enough to complete the budget ++ * before the budget timeout expiration. ++ */ ++ expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT; ++ ++ /* ++ * Caveat: processes doing IO in the slower disk zones will ++ * tend to be slow(er) even if not seeky. And the estimated ++ * peak rate will actually be an average over the disk ++ * surface. Hence, to not be too harsh with unlucky processes, ++ * we keep a budget/3 margin of safety before declaring a ++ * process slow. ++ */ ++ return expected > (4 * bfqq->entity.budget) / 3; ++} ++ ++/* ++ * To be deemed as soft real-time, an application must meet two ++ * requirements. First, the application must not require an average ++ * bandwidth higher than the approximate bandwidth required to playback or ++ * record a compressed high-definition video. ++ * The next function is invoked on the completion of the last request of a ++ * batch, to compute the next-start time instant, soft_rt_next_start, such ++ * that, if the next request of the application does not arrive before ++ * soft_rt_next_start, then the above requirement on the bandwidth is met. ++ * ++ * The second requirement is that the request pattern of the application is ++ * isochronous, i.e., that, after issuing a request or a batch of requests, ++ * the application stops issuing new requests until all its pending requests ++ * have been completed. After that, the application may issue a new batch, ++ * and so on. ++ * For this reason the next function is invoked to compute ++ * soft_rt_next_start only for applications that meet this requirement, ++ * whereas soft_rt_next_start is set to infinity for applications that do ++ * not. ++ * ++ * Unfortunately, even a greedy application may happen to behave in an ++ * isochronous way if the CPU load is high. In fact, the application may ++ * stop issuing requests while the CPUs are busy serving other processes, ++ * then restart, then stop again for a while, and so on. In addition, if ++ * the disk achieves a low enough throughput with the request pattern ++ * issued by the application (e.g., because the request pattern is random ++ * and/or the device is slow), then the application may meet the above ++ * bandwidth requirement too. To prevent such a greedy application to be ++ * deemed as soft real-time, a further rule is used in the computation of ++ * soft_rt_next_start: soft_rt_next_start must be higher than the current ++ * time plus the maximum time for which the arrival of a request is waited ++ * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle. ++ * This filters out greedy applications, as the latter issue instead their ++ * next request as soon as possible after the last one has been completed ++ * (in contrast, when a batch of requests is completed, a soft real-time ++ * application spends some time processing data). ++ * ++ * Unfortunately, the last filter may easily generate false positives if ++ * only bfqd->bfq_slice_idle is used as a reference time interval and one ++ * or both the following cases occur: ++ * 1) HZ is so low that the duration of a jiffy is comparable to or higher ++ * than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with ++ * HZ=100. ++ * 2) jiffies, instead of increasing at a constant rate, may stop increasing ++ * for a while, then suddenly 'jump' by several units to recover the lost ++ * increments. This seems to happen, e.g., inside virtual machines. ++ * To address this issue, we do not use as a reference time interval just ++ * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In ++ * particular we add the minimum number of jiffies for which the filter ++ * seems to be quite precise also in embedded systems and KVM/QEMU virtual ++ * machines. ++ */ ++static inline unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ return max(bfqq->last_idle_bklogged + ++ HZ * bfqq->service_from_backlogged / ++ bfqd->bfq_wr_max_softrt_rate, ++ jiffies + bfqq->bfqd->bfq_slice_idle + 4); ++} ++ ++/* ++ * Return the largest-possible time instant such that, for as long as possible, ++ * the current time will be lower than this time instant according to the macro ++ * time_is_before_jiffies(). ++ */ ++static inline unsigned long bfq_infinity_from_now(unsigned long now) ++{ ++ return now + ULONG_MAX / 2; ++} ++ ++/** ++ * bfq_bfqq_expire - expire a queue. ++ * @bfqd: device owning the queue. ++ * @bfqq: the queue to expire. ++ * @compensate: if true, compensate for the time spent idling. ++ * @reason: the reason causing the expiration. ++ * ++ * ++ * If the process associated to the queue is slow (i.e., seeky), or in ++ * case of budget timeout, or, finally, if it is async, we ++ * artificially charge it an entire budget (independently of the ++ * actual service it received). As a consequence, the queue will get ++ * higher timestamps than the correct ones upon reactivation, and ++ * hence it will be rescheduled as if it had received more service ++ * than what it actually received. In the end, this class of processes ++ * will receive less service in proportion to how slowly they consume ++ * their budgets (and hence how seriously they tend to lower the ++ * throughput). ++ * ++ * In contrast, when a queue expires because it has been idling for ++ * too much or because it exhausted its budget, we do not touch the ++ * amount of service it has received. Hence when the queue will be ++ * reactivated and its timestamps updated, the latter will be in sync ++ * with the actual service received by the queue until expiration. ++ * ++ * Charging a full budget to the first type of queues and the exact ++ * service to the others has the effect of using the WF2Q+ policy to ++ * schedule the former on a timeslice basis, without violating the ++ * service domain guarantees of the latter. ++ */ ++static void bfq_bfqq_expire(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ int compensate, ++ enum bfqq_expiration reason) ++{ ++ int slow; ++ BUG_ON(bfqq != bfqd->in_service_queue); ++ ++ /* Update disk peak rate for autotuning and check whether the ++ * process is slow (see bfq_update_peak_rate). ++ */ ++ slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason); ++ ++ /* ++ * As above explained, 'punish' slow (i.e., seeky), timed-out ++ * and async queues, to favor sequential sync workloads. ++ * ++ * Processes doing I/O in the slower disk zones will tend to be ++ * slow(er) even if not seeky. Hence, since the estimated peak ++ * rate is actually an average over the disk surface, these ++ * processes may timeout just for bad luck. To avoid punishing ++ * them we do not charge a full budget to a process that ++ * succeeded in consuming at least 2/3 of its budget. ++ */ ++ if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT && ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3)) ++ bfq_bfqq_charge_full_budget(bfqq); ++ ++ bfqq->service_from_backlogged += bfqq->entity.service; ++ ++ if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT && ++ !bfq_bfqq_constantly_seeky(bfqq)) { ++ bfq_mark_bfqq_constantly_seeky(bfqq); ++ if (!blk_queue_nonrot(bfqd->queue)) ++ bfqd->const_seeky_busy_in_flight_queues++; ++ } ++ ++ if (reason == BFQ_BFQQ_TOO_IDLE && ++ bfqq->entity.service <= 2 * bfqq->entity.budget / 10 ) ++ bfq_clear_bfqq_IO_bound(bfqq); ++ ++ if (bfqd->low_latency && bfqq->wr_coeff == 1) ++ bfqq->last_wr_start_finish = jiffies; ++ ++ if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) { ++ /* ++ * If we get here, and there are no outstanding requests, ++ * then the request pattern is isochronous (see the comments ++ * to the function bfq_bfqq_softrt_next_start()). Hence we ++ * can compute soft_rt_next_start. If, instead, the queue ++ * still has outstanding requests, then we have to wait ++ * for the completion of all the outstanding requests to ++ * discover whether the request pattern is actually ++ * isochronous. ++ */ ++ if (bfqq->dispatched == 0) ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ else { ++ /* ++ * The application is still waiting for the ++ * completion of one or more requests: ++ * prevent it from possibly being incorrectly ++ * deemed as soft real-time by setting its ++ * soft_rt_next_start to infinity. In fact, ++ * without this assignment, the application ++ * would be incorrectly deemed as soft ++ * real-time if: ++ * 1) it issued a new request before the ++ * completion of all its in-flight ++ * requests, and ++ * 2) at that time, its soft_rt_next_start ++ * happened to be in the past. ++ */ ++ bfqq->soft_rt_next_start = ++ bfq_infinity_from_now(jiffies); ++ /* ++ * Schedule an update of soft_rt_next_start to when ++ * the task may be discovered to be isochronous. ++ */ ++ bfq_mark_bfqq_softrt_update(bfqq); ++ } ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "expire (%d, slow %d, num_disp %d, idle_win %d)", reason, ++ slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq)); ++ ++ /* ++ * Increase, decrease or leave budget unchanged according to ++ * reason. ++ */ ++ __bfq_bfqq_recalc_budget(bfqd, bfqq, reason); ++ __bfq_bfqq_expire(bfqd, bfqq); ++} ++ ++/* ++ * Budget timeout is not implemented through a dedicated timer, but ++ * just checked on request arrivals and completions, as well as on ++ * idle timer expirations. ++ */ ++static int bfq_bfqq_budget_timeout(struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_budget_new(bfqq) || ++ time_before(jiffies, bfqq->budget_timeout)) ++ return 0; ++ return 1; ++} ++ ++/* ++ * If we expire a queue that is waiting for the arrival of a new ++ * request, we may prevent the fictitious timestamp back-shifting that ++ * allows the guarantees of the queue to be preserved (see [1] for ++ * this tricky aspect). Hence we return true only if this condition ++ * does not hold, or if the queue is slow enough to deserve only to be ++ * kicked off for preserving a high throughput. ++*/ ++static inline int bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "may_budget_timeout: wait_request %d left %d timeout %d", ++ bfq_bfqq_wait_request(bfqq), ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3, ++ bfq_bfqq_budget_timeout(bfqq)); ++ ++ return (!bfq_bfqq_wait_request(bfqq) || ++ bfq_bfqq_budget_left(bfqq) >= bfqq->entity.budget / 3) ++ && ++ bfq_bfqq_budget_timeout(bfqq); ++} ++ ++/* ++ * Device idling is allowed only for the queues for which this function ++ * returns true. For this reason, the return value of this function plays a ++ * critical role for both throughput boosting and service guarantees. The ++ * return value is computed through a logical expression. In this rather ++ * long comment, we try to briefly describe all the details and motivations ++ * behind the components of this logical expression. ++ * ++ * First, the expression is false if bfqq is not sync, or if: bfqq happened ++ * to become active during a large burst of queue activations, and the ++ * pattern of requests bfqq contains boosts the throughput if bfqq is ++ * expired. In fact, queues that became active during a large burst benefit ++ * only from throughput, as discussed in the comments to bfq_handle_burst. ++ * In this respect, expiring bfqq certainly boosts the throughput on NCQ- ++ * capable flash-based devices, whereas, on rotational devices, it boosts ++ * the throughput only if bfqq contains random requests. ++ * ++ * On the opposite end, if (a) bfqq is sync, (b) the above burst-related ++ * condition does not hold, and (c) bfqq is being weight-raised, then the ++ * expression always evaluates to true, as device idling is instrumental ++ * for preserving low-latency guarantees (see [1]). If, instead, conditions ++ * (a) and (b) do hold, but (c) does not, then the expression evaluates to ++ * true only if: (1) bfqq is I/O-bound and has a non-null idle window, and ++ * (2) at least one of the following two conditions holds. ++ * The first condition is that the device is not performing NCQ, because ++ * idling the device most certainly boosts the throughput if this condition ++ * holds and bfqq is I/O-bound and has been granted a non-null idle window. ++ * The second compound condition is made of the logical AND of two components. ++ * ++ * The first component is true only if there is no weight-raised busy ++ * queue. This guarantees that the device is not idled for a sync non- ++ * weight-raised queue when there are busy weight-raised queues. The former ++ * is then expired immediately if empty. Combined with the timestamping ++ * rules of BFQ (see [1] for details), this causes sync non-weight-raised ++ * queues to get a lower number of requests served, and hence to ask for a ++ * lower number of requests from the request pool, before the busy weight- ++ * raised queues get served again. ++ * ++ * This is beneficial for the processes associated with weight-raised ++ * queues, when the request pool is saturated (e.g., in the presence of ++ * write hogs). In fact, if the processes associated with the other queues ++ * ask for requests at a lower rate, then weight-raised processes have a ++ * higher probability to get a request from the pool immediately (or at ++ * least soon) when they need one. Hence they have a higher probability to ++ * actually get a fraction of the disk throughput proportional to their ++ * high weight. This is especially true with NCQ-capable drives, which ++ * enqueue several requests in advance and further reorder internally- ++ * queued requests. ++ * ++ * In the end, mistreating non-weight-raised queues when there are busy ++ * weight-raised queues seems to mitigate starvation problems in the ++ * presence of heavy write workloads and NCQ, and hence to guarantee a ++ * higher application and system responsiveness in these hostile scenarios. ++ * ++ * If the first component of the compound condition is instead true, i.e., ++ * there is no weight-raised busy queue, then the second component of the ++ * compound condition takes into account service-guarantee and throughput ++ * issues related to NCQ (recall that the compound condition is evaluated ++ * only if the device is detected as supporting NCQ). ++ * ++ * As for service guarantees, allowing the drive to enqueue more than one ++ * request at a time, and hence delegating de facto final scheduling ++ * decisions to the drive's internal scheduler, causes loss of control on ++ * the actual request service order. In this respect, when the drive is ++ * allowed to enqueue more than one request at a time, the service ++ * distribution enforced by the drive's internal scheduler is likely to ++ * coincide with the desired device-throughput distribution only in the ++ * following, perfectly symmetric, scenario: ++ * 1) all active queues have the same weight, ++ * 2) all active groups at the same level in the groups tree have the same ++ * weight, ++ * 3) all active groups at the same level in the groups tree have the same ++ * number of children. ++ * ++ * Even in such a scenario, sequential I/O may still receive a preferential ++ * treatment, but this is not likely to be a big issue with flash-based ++ * devices, because of their non-dramatic loss of throughput with random ++ * I/O. Things do differ with HDDs, for which additional care is taken, as ++ * explained after completing the discussion for flash-based devices. ++ * ++ * Unfortunately, keeping the necessary state for evaluating exactly the ++ * above symmetry conditions would be quite complex and time-consuming. ++ * Therefore BFQ evaluates instead the following stronger sub-conditions, ++ * for which it is much easier to maintain the needed state: ++ * 1) all active queues have the same weight, ++ * 2) all active groups have the same weight, ++ * 3) all active groups have at most one active child each. ++ * In particular, the last two conditions are always true if hierarchical ++ * support and the cgroups interface are not enabled, hence no state needs ++ * to be maintained in this case. ++ * ++ * According to the above considerations, the second component of the ++ * compound condition evaluates to true if any of the above symmetry ++ * sub-condition does not hold, or the device is not flash-based. Therefore, ++ * if also the first component is true, then idling is allowed for a sync ++ * queue. These are the only sub-conditions considered if the device is ++ * flash-based, as, for such a device, it is sensible to force idling only ++ * for service-guarantee issues. In fact, as for throughput, idling ++ * NCQ-capable flash-based devices would not boost the throughput even ++ * with sequential I/O; rather it would lower the throughput in proportion ++ * to how fast the device is. In the end, (only) if all the three ++ * sub-conditions hold and the device is flash-based, the compound ++ * condition evaluates to false and therefore no idling is performed. ++ * ++ * As already said, things change with a rotational device, where idling ++ * boosts the throughput with sequential I/O (even with NCQ). Hence, for ++ * such a device the second component of the compound condition evaluates ++ * to true also if the following additional sub-condition does not hold: ++ * the queue is constantly seeky. Unfortunately, this different behavior ++ * with respect to flash-based devices causes an additional asymmetry: if ++ * some sync queues enjoy idling and some other sync queues do not, then ++ * the latter get a low share of the device throughput, simply because the ++ * former get many requests served after being set as in service, whereas ++ * the latter do not. As a consequence, to guarantee the desired throughput ++ * distribution, on HDDs the compound expression evaluates to true (and ++ * hence device idling is performed) also if the following last symmetry ++ * condition does not hold: no other queue is benefiting from idling. Also ++ * this last condition is actually replaced with a simpler-to-maintain and ++ * stronger condition: there is no busy queue which is not constantly seeky ++ * (and hence may also benefit from idling). ++ * ++ * To sum up, when all the required symmetry and throughput-boosting ++ * sub-conditions hold, the second component of the compound condition ++ * evaluates to false, and hence no idling is performed. This helps to ++ * keep the drives' internal queues full on NCQ-capable devices, and hence ++ * to boost the throughput, without causing 'almost' any loss of service ++ * guarantees. The 'almost' follows from the fact that, if the internal ++ * queue of one such device is filled while all the sub-conditions hold, ++ * but at some point in time some sub-condition stops to hold, then it may ++ * become impossible to let requests be served in the new desired order ++ * until all the requests already queued in the device have been served. ++ */ ++static inline bool bfq_bfqq_must_not_expire(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++#ifdef CONFIG_CGROUP_BFQIO ++#define symmetric_scenario (!bfqd->active_numerous_groups && \ ++ !bfq_differentiated_weights(bfqd)) ++#else ++#define symmetric_scenario (!bfq_differentiated_weights(bfqd)) ++#endif ++#define cond_for_seeky_on_ncq_hdd (bfq_bfqq_constantly_seeky(bfqq) && \ ++ bfqd->busy_in_flight_queues == \ ++ bfqd->const_seeky_busy_in_flight_queues) ++ ++#define cond_for_expiring_in_burst (bfq_bfqq_in_large_burst(bfqq) && \ ++ bfqd->hw_tag && \ ++ (blk_queue_nonrot(bfqd->queue) || \ ++ bfq_bfqq_constantly_seeky(bfqq))) ++ ++/* ++ * Condition for expiring a non-weight-raised queue (and hence not idling ++ * the device). ++ */ ++#define cond_for_expiring_non_wr (bfqd->hw_tag && \ ++ (bfqd->wr_busy_queues > 0 || \ ++ (symmetric_scenario && \ ++ (blk_queue_nonrot(bfqd->queue) || \ ++ cond_for_seeky_on_ncq_hdd)))) ++ ++ return bfq_bfqq_sync(bfqq) && ++ !cond_for_expiring_in_burst && ++ (bfqq->wr_coeff > 1 || ++ (bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_idle_window(bfqq) && ++ !cond_for_expiring_non_wr) ++ ); ++} ++ ++/* ++ * If the in-service queue is empty but sync, and the function ++ * bfq_bfqq_must_not_expire returns true, then: ++ * 1) the queue must remain in service and cannot be expired, and ++ * 2) the disk must be idled to wait for the possible arrival of a new ++ * request for the queue. ++ * See the comments to the function bfq_bfqq_must_not_expire for the reasons ++ * why performing device idling is the best choice to boost the throughput ++ * and preserve service guarantees when bfq_bfqq_must_not_expire itself ++ * returns true. ++ */ ++static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 && ++ bfq_bfqq_must_not_expire(bfqq); ++} ++ ++/* ++ * Select a queue for service. If we have a current queue in service, ++ * check whether to continue servicing it, or retrieve and set a new one. ++ */ ++static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq, *new_bfqq = NULL; ++ struct request *next_rq; ++ enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ ++ bfqq = bfqd->in_service_queue; ++ if (bfqq == NULL) ++ goto new_queue; ++ ++ bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); ++ ++ /* ++ * If another queue has a request waiting within our mean seek ++ * distance, let it run. The expire code will check for close ++ * cooperators and put the close queue at the front of the ++ * service tree. If possible, merge the expiring queue with the ++ * new bfqq. ++ */ ++ new_bfqq = bfq_close_cooperator(bfqd, bfqq); ++ if (new_bfqq != NULL && bfqq->new_bfqq == NULL) ++ bfq_setup_merge(bfqq, new_bfqq); ++ ++ if (bfq_may_expire_for_budg_timeout(bfqq) && ++ !timer_pending(&bfqd->idle_slice_timer) && ++ !bfq_bfqq_must_idle(bfqq)) ++ goto expire; ++ ++ next_rq = bfqq->next_rq; ++ /* ++ * If bfqq has requests queued and it has enough budget left to ++ * serve them, keep the queue, otherwise expire it. ++ */ ++ if (next_rq != NULL) { ++ if (bfq_serv_to_charge(next_rq, bfqq) > ++ bfq_bfqq_budget_left(bfqq)) { ++ reason = BFQ_BFQQ_BUDGET_EXHAUSTED; ++ goto expire; ++ } else { ++ /* ++ * The idle timer may be pending because we may ++ * not disable disk idling even when a new request ++ * arrives. ++ */ ++ if (timer_pending(&bfqd->idle_slice_timer)) { ++ /* ++ * If we get here: 1) at least a new request ++ * has arrived but we have not disabled the ++ * timer because the request was too small, ++ * 2) then the block layer has unplugged ++ * the device, causing the dispatch to be ++ * invoked. ++ * ++ * Since the device is unplugged, now the ++ * requests are probably large enough to ++ * provide a reasonable throughput. ++ * So we disable idling. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ del_timer(&bfqd->idle_slice_timer); ++ } ++ if (new_bfqq == NULL) ++ goto keep_queue; ++ else ++ goto expire; ++ } ++ } ++ ++ /* ++ * No requests pending. If the in-service queue still has requests ++ * in flight (possibly waiting for a completion) or is idling for a ++ * new request, then keep it. ++ */ ++ if (new_bfqq == NULL && (timer_pending(&bfqd->idle_slice_timer) || ++ (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq)))) { ++ bfqq = NULL; ++ goto keep_queue; ++ } else if (new_bfqq != NULL && timer_pending(&bfqd->idle_slice_timer)) { ++ /* ++ * Expiring the queue because there is a close cooperator, ++ * cancel timer. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ del_timer(&bfqd->idle_slice_timer); ++ } ++ ++ reason = BFQ_BFQQ_NO_MORE_REQUESTS; ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, 0, reason); ++new_queue: ++ bfqq = bfq_set_in_service_queue(bfqd, new_bfqq); ++ bfq_log(bfqd, "select_queue: new queue %d returned", ++ bfqq != NULL ? bfqq->pid : 0); ++keep_queue: ++ return bfqq; ++} ++ ++static void bfq_update_wr_data(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq->wr_coeff > 1) { /* queue is being boosted */ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "raising period dur %u/%u msec, old coeff %u, w %d(%d)", ++ jiffies_to_msecs(jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time), ++ bfqq->wr_coeff, ++ bfqq->entity.weight, bfqq->entity.orig_weight); ++ ++ BUG_ON(bfqq != bfqd->in_service_queue && entity->weight != ++ entity->orig_weight * bfqq->wr_coeff); ++ if (entity->ioprio_changed) ++ bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); ++ /* ++ * If the queue was activated in a burst, or ++ * too much time has elapsed from the beginning ++ * of this weight-raising, then end weight raising. ++ */ ++ if (bfq_bfqq_in_large_burst(bfqq) || ++ time_is_before_jiffies(bfqq->last_wr_start_finish + ++ bfqq->wr_cur_max_time)) { ++ bfqq->last_wr_start_finish = jiffies; ++ bfq_log_bfqq(bfqd, bfqq, ++ "wrais ending at %lu, rais_max_time %u", ++ bfqq->last_wr_start_finish, ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ bfq_bfqq_end_wr(bfqq); ++ __bfq_entity_update_weight_prio( ++ bfq_entity_service_tree(entity), ++ entity); ++ } ++ } ++} ++ ++/* ++ * Dispatch one request from bfqq, moving it to the request queue ++ * dispatch list. ++ */ ++static int bfq_dispatch_request(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ struct request *rq; ++ unsigned long service_to_charge; ++ ++ BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ /* Follow expired path, else get first next available. */ ++ rq = bfq_check_fifo(bfqq); ++ if (rq == NULL) ++ rq = bfqq->next_rq; ++ service_to_charge = bfq_serv_to_charge(rq, bfqq); ++ ++ if (service_to_charge > bfq_bfqq_budget_left(bfqq)) { ++ /* ++ * This may happen if the next rq is chosen in fifo order ++ * instead of sector order. The budget is properly ++ * dimensioned to be always sufficient to serve the next ++ * request only if it is chosen in sector order. The reason ++ * is that it would be quite inefficient and little useful ++ * to always make sure that the budget is large enough to ++ * serve even the possible next rq in fifo order. ++ * In fact, requests are seldom served in fifo order. ++ * ++ * Expire the queue for budget exhaustion, and make sure ++ * that the next act_budget is enough to serve the next ++ * request, even if it comes from the fifo expired path. ++ */ ++ bfqq->next_rq = rq; ++ /* ++ * Since this dispatch is failed, make sure that ++ * a new one will be performed ++ */ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ goto expire; ++ } ++ ++ /* Finally, insert request into driver dispatch list. */ ++ bfq_bfqq_served(bfqq, service_to_charge); ++ bfq_dispatch_insert(bfqd->queue, rq); ++ ++ bfq_update_wr_data(bfqd, bfqq); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "dispatched %u sec req (%llu), budg left %lu", ++ blk_rq_sectors(rq), ++ (long long unsigned)blk_rq_pos(rq), ++ bfq_bfqq_budget_left(bfqq)); ++ ++ dispatched++; ++ ++ if (bfqd->in_service_bic == NULL) { ++ atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount); ++ bfqd->in_service_bic = RQ_BIC(rq); ++ } ++ ++ if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) && ++ dispatched >= bfqd->bfq_max_budget_async_rq) || ++ bfq_class_idle(bfqq))) ++ goto expire; ++ ++ return dispatched; ++ ++expire: ++ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_EXHAUSTED); ++ return dispatched; ++} ++ ++static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq) ++{ ++ int dispatched = 0; ++ ++ while (bfqq->next_rq != NULL) { ++ bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq); ++ dispatched++; ++ } ++ ++ BUG_ON(!list_empty(&bfqq->fifo)); ++ return dispatched; ++} ++ ++/* ++ * Drain our current requests. ++ * Used for barriers and when switching io schedulers on-the-fly. ++ */ ++static int bfq_forced_dispatch(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq, *n; ++ struct bfq_service_tree *st; ++ int dispatched = 0; ++ ++ bfqq = bfqd->in_service_queue; ++ if (bfqq != NULL) ++ __bfq_bfqq_expire(bfqd, bfqq); ++ ++ /* ++ * Loop through classes, and be careful to leave the scheduler ++ * in a consistent state, as feedback mechanisms and vtime ++ * updates cannot be disabled during the process. ++ */ ++ list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) { ++ st = bfq_entity_service_tree(&bfqq->entity); ++ ++ dispatched += __bfq_forced_dispatch_bfqq(bfqq); ++ bfqq->max_budget = bfq_max_budget(bfqd); ++ ++ bfq_forget_idle(st); ++ } ++ ++ BUG_ON(bfqd->busy_queues != 0); ++ ++ return dispatched; ++} ++ ++static int bfq_dispatch_requests(struct request_queue *q, int force) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq; ++ int max_dispatch; ++ ++ bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues); ++ if (bfqd->busy_queues == 0) ++ return 0; ++ ++ if (unlikely(force)) ++ return bfq_forced_dispatch(bfqd); ++ ++ bfqq = bfq_select_queue(bfqd); ++ if (bfqq == NULL) ++ return 0; ++ ++ max_dispatch = bfqd->bfq_quantum; ++ if (bfq_class_idle(bfqq)) ++ max_dispatch = 1; ++ ++ if (!bfq_bfqq_sync(bfqq)) ++ max_dispatch = bfqd->bfq_max_budget_async_rq; ++ ++ if (bfqq->dispatched >= max_dispatch) { ++ if (bfqd->busy_queues > 1) ++ return 0; ++ if (bfqq->dispatched >= 4 * max_dispatch) ++ return 0; ++ } ++ ++ if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq)) ++ return 0; ++ ++ bfq_clear_bfqq_wait_request(bfqq); ++ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); ++ ++ if (!bfq_dispatch_request(bfqd, bfqq)) ++ return 0; ++ ++ bfq_log_bfqq(bfqd, bfqq, "dispatched one request of %d (max_disp %d)", ++ bfqq->pid, max_dispatch); ++ ++ return 1; ++} ++ ++/* ++ * Task holds one reference to the queue, dropped when task exits. Each rq ++ * in-flight on this queue also holds a reference, dropped when rq is freed. ++ * ++ * Queue lock must be held here. ++ */ ++static void bfq_put_queue(struct bfq_queue *bfqq) ++{ ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ BUG_ON(atomic_read(&bfqq->ref) <= 0); ++ ++ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ if (!atomic_dec_and_test(&bfqq->ref)) ++ return; ++ ++ BUG_ON(rb_first(&bfqq->sort_list) != NULL); ++ BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0); ++ BUG_ON(bfqq->entity.tree != NULL); ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqd->in_service_queue == bfqq); ++ ++ if (bfq_bfqq_sync(bfqq)) ++ /* ++ * The fact that this queue is being destroyed does not ++ * invalidate the fact that this queue may have been ++ * activated during the current burst. As a consequence, ++ * although the queue does not exist anymore, and hence ++ * needs to be removed from the burst list if there, ++ * the burst size has not to be decremented. ++ */ ++ hlist_del_init(&bfqq->burst_list_node); ++ ++ bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq); ++ ++ kmem_cache_free(bfq_pool, bfqq); ++} ++ ++static void bfq_put_cooperator(struct bfq_queue *bfqq) ++{ ++ struct bfq_queue *__bfqq, *next; ++ ++ /* ++ * If this queue was scheduled to merge with another queue, be ++ * sure to drop the reference taken on that queue (and others in ++ * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs. ++ */ ++ __bfqq = bfqq->new_bfqq; ++ while (__bfqq) { ++ if (__bfqq == bfqq) ++ break; ++ next = __bfqq->new_bfqq; ++ bfq_put_queue(__bfqq); ++ __bfqq = next; ++ } ++} ++ ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ if (bfqq == bfqd->in_service_queue) { ++ __bfq_bfqq_expire(bfqd, bfqq); ++ bfq_schedule_dispatch(bfqd); ++ } ++ ++ bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++} ++ ++static inline void bfq_init_icq(struct io_cq *icq) ++{ ++ struct bfq_io_cq *bic = icq_to_bic(icq); ++ ++ bic->ttime.last_end_request = jiffies; ++} ++ ++static void bfq_exit_icq(struct io_cq *icq) ++{ ++ struct bfq_io_cq *bic = icq_to_bic(icq); ++ struct bfq_data *bfqd = bic_to_bfqd(bic); ++ ++ if (bic->bfqq[BLK_RW_ASYNC]) { ++ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]); ++ bic->bfqq[BLK_RW_ASYNC] = NULL; ++ } ++ ++ if (bic->bfqq[BLK_RW_SYNC]) { ++ bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); ++ bic->bfqq[BLK_RW_SYNC] = NULL; ++ } ++} ++ ++/* ++ * Update the entity prio values; note that the new values will not ++ * be used until the next (re)activation. ++ */ ++static void bfq_init_prio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic) ++{ ++ struct task_struct *tsk = current; ++ int ioprio_class; ++ ++ if (!bfq_bfqq_prio_changed(bfqq)) ++ return; ++ ++ ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); ++ switch (ioprio_class) { ++ default: ++ dev_err(bfqq->bfqd->queue->backing_dev_info.dev, ++ "bfq: bad prio class %d\n", ioprio_class); ++ case IOPRIO_CLASS_NONE: ++ /* ++ * No prio set, inherit CPU scheduling settings. ++ */ ++ bfqq->entity.new_ioprio = task_nice_ioprio(tsk); ++ bfqq->entity.new_ioprio_class = task_nice_ioclass(tsk); ++ break; ++ case IOPRIO_CLASS_RT: ++ bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_RT; ++ break; ++ case IOPRIO_CLASS_BE: ++ bfqq->entity.new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_BE; ++ break; ++ case IOPRIO_CLASS_IDLE: ++ bfqq->entity.new_ioprio_class = IOPRIO_CLASS_IDLE; ++ bfqq->entity.new_ioprio = 7; ++ bfq_clear_bfqq_idle_window(bfqq); ++ break; ++ } ++ ++ if (bfqq->entity.new_ioprio < 0 || ++ bfqq->entity.new_ioprio >= IOPRIO_BE_NR) { ++ printk(KERN_CRIT "bfq_init_prio_data: new_ioprio %d\n", ++ bfqq->entity.new_ioprio); ++ BUG(); ++ } ++ ++ bfqq->entity.ioprio_changed = 1; ++ ++ bfq_clear_bfqq_prio_changed(bfqq); ++} ++ ++static void bfq_changed_ioprio(struct bfq_io_cq *bic) ++{ ++ struct bfq_data *bfqd; ++ struct bfq_queue *bfqq, *new_bfqq; ++ struct bfq_group *bfqg; ++ unsigned long uninitialized_var(flags); ++ int ioprio = bic->icq.ioc->ioprio; ++ ++ bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data), ++ &flags); ++ /* ++ * This condition may trigger on a newly created bic, be sure to ++ * drop the lock before returning. ++ */ ++ if (unlikely(bfqd == NULL) || likely(bic->ioprio == ioprio)) ++ goto out; ++ ++ bfqq = bic->bfqq[BLK_RW_ASYNC]; ++ if (bfqq != NULL) { ++ bfqg = container_of(bfqq->entity.sched_data, struct bfq_group, ++ sched_data); ++ new_bfqq = bfq_get_queue(bfqd, bfqg, BLK_RW_ASYNC, bic, ++ GFP_ATOMIC); ++ if (new_bfqq != NULL) { ++ bic->bfqq[BLK_RW_ASYNC] = new_bfqq; ++ bfq_log_bfqq(bfqd, bfqq, ++ "changed_ioprio: bfqq %p %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ } ++ } ++ ++ bfqq = bic->bfqq[BLK_RW_SYNC]; ++ if (bfqq != NULL) ++ bfq_mark_bfqq_prio_changed(bfqq); ++ ++ bic->ioprio = ioprio; ++ ++out: ++ bfq_put_bfqd_unlock(bfqd, &flags); ++} ++ ++static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ pid_t pid, int is_sync) ++{ ++ RB_CLEAR_NODE(&bfqq->entity.rb_node); ++ INIT_LIST_HEAD(&bfqq->fifo); ++ INIT_HLIST_NODE(&bfqq->burst_list_node); ++ ++ atomic_set(&bfqq->ref, 0); ++ bfqq->bfqd = bfqd; ++ ++ bfq_mark_bfqq_prio_changed(bfqq); ++ ++ if (is_sync) { ++ if (!bfq_class_idle(bfqq)) ++ bfq_mark_bfqq_idle_window(bfqq); ++ bfq_mark_bfqq_sync(bfqq); ++ } ++ bfq_mark_bfqq_IO_bound(bfqq); ++ ++ /* Tentative initial value to trade off between thr and lat */ ++ bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3; ++ bfqq->pid = pid; ++ ++ bfqq->wr_coeff = 1; ++ bfqq->last_wr_start_finish = 0; ++ /* ++ * Set to the value for which bfqq will not be deemed as ++ * soft rt when it becomes backlogged. ++ */ ++ bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies); ++} ++ ++static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ int is_sync, ++ struct bfq_io_cq *bic, ++ gfp_t gfp_mask) ++{ ++ struct bfq_queue *bfqq, *new_bfqq = NULL; ++ ++retry: ++ /* bic always exists here */ ++ bfqq = bic_to_bfqq(bic, is_sync); ++ ++ /* ++ * Always try a new alloc if we fall back to the OOM bfqq ++ * originally, since it should just be a temporary situation. ++ */ ++ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { ++ bfqq = NULL; ++ if (new_bfqq != NULL) { ++ bfqq = new_bfqq; ++ new_bfqq = NULL; ++ } else if (gfp_mask & __GFP_WAIT) { ++ spin_unlock_irq(bfqd->queue->queue_lock); ++ new_bfqq = kmem_cache_alloc_node(bfq_pool, ++ gfp_mask | __GFP_ZERO, ++ bfqd->queue->node); ++ spin_lock_irq(bfqd->queue->queue_lock); ++ if (new_bfqq != NULL) ++ goto retry; ++ } else { ++ bfqq = kmem_cache_alloc_node(bfq_pool, ++ gfp_mask | __GFP_ZERO, ++ bfqd->queue->node); ++ } ++ ++ if (bfqq != NULL) { ++ bfq_init_bfqq(bfqd, bfqq, current->pid, is_sync); ++ bfq_init_prio_data(bfqq, bic); ++ bfq_init_entity(&bfqq->entity, bfqg); ++ bfq_log_bfqq(bfqd, bfqq, "allocated"); ++ } else { ++ bfqq = &bfqd->oom_bfqq; ++ bfq_log_bfqq(bfqd, bfqq, "using oom bfqq"); ++ } ++ } ++ ++ if (new_bfqq != NULL) ++ kmem_cache_free(bfq_pool, new_bfqq); ++ ++ return bfqq; ++} ++ ++static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, ++ int ioprio_class, int ioprio) ++{ ++ switch (ioprio_class) { ++ case IOPRIO_CLASS_RT: ++ return &bfqg->async_bfqq[0][ioprio]; ++ case IOPRIO_CLASS_NONE: ++ ioprio = IOPRIO_NORM; ++ /* fall through */ ++ case IOPRIO_CLASS_BE: ++ return &bfqg->async_bfqq[1][ioprio]; ++ case IOPRIO_CLASS_IDLE: ++ return &bfqg->async_idle_bfqq; ++ default: ++ BUG(); ++ } ++} ++ ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, int is_sync, ++ struct bfq_io_cq *bic, gfp_t gfp_mask) ++{ ++ const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio); ++ const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio); ++ struct bfq_queue **async_bfqq = NULL; ++ struct bfq_queue *bfqq = NULL; ++ ++ if (!is_sync) { ++ async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class, ++ ioprio); ++ bfqq = *async_bfqq; ++ } ++ ++ if (bfqq == NULL) ++ bfqq = bfq_find_alloc_queue(bfqd, bfqg, is_sync, bic, gfp_mask); ++ ++ /* ++ * Pin the queue now that it's allocated, scheduler exit will ++ * prune it. ++ */ ++ if (!is_sync && *async_bfqq == NULL) { ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ *async_bfqq = bfqq; ++ } ++ ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ return bfqq; ++} ++ ++static void bfq_update_io_thinktime(struct bfq_data *bfqd, ++ struct bfq_io_cq *bic) ++{ ++ unsigned long elapsed = jiffies - bic->ttime.last_end_request; ++ unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle); ++ ++ bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8; ++ bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8; ++ bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) / ++ bic->ttime.ttime_samples; ++} ++ ++static void bfq_update_io_seektime(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ sector_t sdist; ++ u64 total; ++ ++ if (bfqq->last_request_pos < blk_rq_pos(rq)) ++ sdist = blk_rq_pos(rq) - bfqq->last_request_pos; ++ else ++ sdist = bfqq->last_request_pos - blk_rq_pos(rq); ++ ++ /* ++ * Don't allow the seek distance to get too large from the ++ * odd fragment, pagein, etc. ++ */ ++ if (bfqq->seek_samples == 0) /* first request, not really a seek */ ++ sdist = 0; ++ else if (bfqq->seek_samples <= 60) /* second & third seek */ ++ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024); ++ else ++ sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64); ++ ++ bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8; ++ bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8; ++ total = bfqq->seek_total + (bfqq->seek_samples/2); ++ do_div(total, bfqq->seek_samples); ++ bfqq->seek_mean = (sector_t)total; ++ ++ bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist, ++ (u64)bfqq->seek_mean); ++} ++ ++/* ++ * Disable idle window if the process thinks too long or seeks so much that ++ * it doesn't matter. ++ */ ++static void bfq_update_idle_window(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq, ++ struct bfq_io_cq *bic) ++{ ++ int enable_idle; ++ ++ /* Don't idle for async or idle io prio class. */ ++ if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) ++ return; ++ ++ enable_idle = bfq_bfqq_idle_window(bfqq); ++ ++ if (atomic_read(&bic->icq.ioc->active_ref) == 0 || ++ bfqd->bfq_slice_idle == 0 || ++ (bfqd->hw_tag && BFQQ_SEEKY(bfqq) && ++ bfqq->wr_coeff == 1)) ++ enable_idle = 0; ++ else if (bfq_sample_valid(bic->ttime.ttime_samples)) { ++ if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle && ++ bfqq->wr_coeff == 1) ++ enable_idle = 0; ++ else ++ enable_idle = 1; ++ } ++ bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d", ++ enable_idle); ++ ++ if (enable_idle) ++ bfq_mark_bfqq_idle_window(bfqq); ++ else ++ bfq_clear_bfqq_idle_window(bfqq); ++} ++ ++/* ++ * Called when a new fs request (rq) is added to bfqq. Check if there's ++ * something we should do about it. ++ */ ++static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ struct request *rq) ++{ ++ struct bfq_io_cq *bic = RQ_BIC(rq); ++ ++ if (rq->cmd_flags & REQ_META) ++ bfqq->meta_pending++; ++ ++ bfq_update_io_thinktime(bfqd, bic); ++ bfq_update_io_seektime(bfqd, bfqq, rq); ++ if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) { ++ bfq_clear_bfqq_constantly_seeky(bfqq); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ BUG_ON(!bfqd->const_seeky_busy_in_flight_queues); ++ bfqd->const_seeky_busy_in_flight_queues--; ++ } ++ } ++ if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || ++ !BFQQ_SEEKY(bfqq)) ++ bfq_update_idle_window(bfqd, bfqq, bic); ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", ++ bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq), ++ (long long unsigned)bfqq->seek_mean); ++ ++ bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq); ++ ++ if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) { ++ int small_req = bfqq->queued[rq_is_sync(rq)] == 1 && ++ blk_rq_sectors(rq) < 32; ++ int budget_timeout = bfq_bfqq_budget_timeout(bfqq); ++ ++ /* ++ * There is just this request queued: if the request ++ * is small and the queue is not to be expired, then ++ * just exit. ++ * ++ * In this way, if the disk is being idled to wait for ++ * a new request from the in-service queue, we avoid ++ * unplugging the device and committing the disk to serve ++ * just a small request. On the contrary, we wait for ++ * the block layer to decide when to unplug the device: ++ * hopefully, new requests will be merged to this one ++ * quickly, then the device will be unplugged and ++ * larger requests will be dispatched. ++ */ ++ if (small_req && !budget_timeout) ++ return; ++ ++ /* ++ * A large enough request arrived, or the queue is to ++ * be expired: in both cases disk idling is to be ++ * stopped, so clear wait_request flag and reset ++ * timer. ++ */ ++ bfq_clear_bfqq_wait_request(bfqq); ++ del_timer(&bfqd->idle_slice_timer); ++ ++ /* ++ * The queue is not empty, because a new request just ++ * arrived. Hence we can safely expire the queue, in ++ * case of budget timeout, without risking that the ++ * timestamps of the queue are not updated correctly. ++ * See [1] for more details. ++ */ ++ if (budget_timeout) ++ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); ++ ++ /* ++ * Let the request rip immediately, or let a new queue be ++ * selected if bfqq has just been expired. ++ */ ++ __blk_run_queue(bfqd->queue); ++ } ++} ++ ++static void bfq_insert_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ assert_spin_locked(bfqd->queue->queue_lock); ++ bfq_init_prio_data(bfqq, RQ_BIC(rq)); ++ ++ bfq_add_request(rq); ++ ++ rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]; ++ list_add_tail(&rq->queuelist, &bfqq->fifo); ++ ++ bfq_rq_enqueued(bfqd, bfqq, rq); ++} ++ ++static void bfq_update_hw_tag(struct bfq_data *bfqd) ++{ ++ bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver, ++ bfqd->rq_in_driver); ++ ++ if (bfqd->hw_tag == 1) ++ return; ++ ++ /* ++ * This sample is valid if the number of outstanding requests ++ * is large enough to allow a queueing behavior. Note that the ++ * sum is not exact, as it's not taking into account deactivated ++ * requests. ++ */ ++ if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD) ++ return; ++ ++ if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES) ++ return; ++ ++ bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD; ++ bfqd->max_rq_in_driver = 0; ++ bfqd->hw_tag_samples = 0; ++} ++ ++static void bfq_completed_request(struct request_queue *q, struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_data *bfqd = bfqq->bfqd; ++ bool sync = bfq_bfqq_sync(bfqq); ++ ++ bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)", ++ blk_rq_sectors(rq), sync); ++ ++ bfq_update_hw_tag(bfqd); ++ ++ BUG_ON(!bfqd->rq_in_driver); ++ BUG_ON(!bfqq->dispatched); ++ bfqd->rq_in_driver--; ++ bfqq->dispatched--; ++ ++ if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) { ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ BUG_ON(!bfqd->busy_in_flight_queues); ++ bfqd->busy_in_flight_queues--; ++ if (bfq_bfqq_constantly_seeky(bfqq)) { ++ BUG_ON(!bfqd-> ++ const_seeky_busy_in_flight_queues); ++ bfqd->const_seeky_busy_in_flight_queues--; ++ } ++ } ++ } ++ ++ if (sync) { ++ bfqd->sync_flight--; ++ RQ_BIC(rq)->ttime.last_end_request = jiffies; ++ } ++ ++ /* ++ * If we are waiting to discover whether the request pattern of the ++ * task associated with the queue is actually isochronous, and ++ * both requisites for this condition to hold are satisfied, then ++ * compute soft_rt_next_start (see the comments to the function ++ * bfq_bfqq_softrt_next_start()). ++ */ ++ if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 && ++ RB_EMPTY_ROOT(&bfqq->sort_list)) ++ bfqq->soft_rt_next_start = ++ bfq_bfqq_softrt_next_start(bfqd, bfqq); ++ ++ /* ++ * If this is the in-service queue, check if it needs to be expired, ++ * or if we want to idle in case it has no pending requests. ++ */ ++ if (bfqd->in_service_queue == bfqq) { ++ if (bfq_bfqq_budget_new(bfqq)) ++ bfq_set_budget_timeout(bfqd); ++ ++ if (bfq_bfqq_must_idle(bfqq)) { ++ bfq_arm_slice_timer(bfqd); ++ goto out; ++ } else if (bfq_may_expire_for_budg_timeout(bfqq)) ++ bfq_bfqq_expire(bfqd, bfqq, 0, BFQ_BFQQ_BUDGET_TIMEOUT); ++ else if (RB_EMPTY_ROOT(&bfqq->sort_list) && ++ (bfqq->dispatched == 0 || ++ !bfq_bfqq_must_not_expire(bfqq))) ++ bfq_bfqq_expire(bfqd, bfqq, 0, ++ BFQ_BFQQ_NO_MORE_REQUESTS); ++ } ++ ++ if (!bfqd->rq_in_driver) ++ bfq_schedule_dispatch(bfqd); ++ ++out: ++ return; ++} ++ ++static inline int __bfq_may_queue(struct bfq_queue *bfqq) ++{ ++ if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) { ++ bfq_clear_bfqq_must_alloc(bfqq); ++ return ELV_MQUEUE_MUST; ++ } ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++static int bfq_may_queue(struct request_queue *q, int rw) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct task_struct *tsk = current; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq; ++ ++ /* ++ * Don't force setup of a queue from here, as a call to may_queue ++ * does not necessarily imply that a request actually will be ++ * queued. So just lookup a possibly existing queue, or return ++ * 'may queue' if that fails. ++ */ ++ bic = bfq_bic_lookup(bfqd, tsk->io_context); ++ if (bic == NULL) ++ return ELV_MQUEUE_MAY; ++ ++ bfqq = bic_to_bfqq(bic, rw_is_sync(rw)); ++ if (bfqq != NULL) { ++ bfq_init_prio_data(bfqq, bic); ++ ++ return __bfq_may_queue(bfqq); ++ } ++ ++ return ELV_MQUEUE_MAY; ++} ++ ++/* ++ * Queue lock held here. ++ */ ++static void bfq_put_request(struct request *rq) ++{ ++ struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ ++ if (bfqq != NULL) { ++ const int rw = rq_data_dir(rq); ++ ++ BUG_ON(!bfqq->allocated[rw]); ++ bfqq->allocated[rw]--; ++ ++ rq->elv.priv[0] = NULL; ++ rq->elv.priv[1] = NULL; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++static struct bfq_queue * ++bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", ++ (long unsigned)bfqq->new_bfqq->pid); ++ bic_set_bfqq(bic, bfqq->new_bfqq, 1); ++ bfq_mark_bfqq_coop(bfqq->new_bfqq); ++ bfq_put_queue(bfqq); ++ return bic_to_bfqq(bic, 1); ++} ++ ++/* ++ * Returns NULL if a new bfqq should be allocated, or the old bfqq if this ++ * was the last process referring to said bfqq. ++ */ ++static struct bfq_queue * ++bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) ++{ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); ++ if (bfqq_process_refs(bfqq) == 1) { ++ bfqq->pid = current->pid; ++ bfq_clear_bfqq_coop(bfqq); ++ bfq_clear_bfqq_split_coop(bfqq); ++ return bfqq; ++ } ++ ++ bic_set_bfqq(bic, NULL, 1); ++ ++ bfq_put_cooperator(bfqq); ++ ++ bfq_put_queue(bfqq); ++ return NULL; ++} ++ ++/* ++ * Allocate bfq data structures associated with this request. ++ */ ++static int bfq_set_request(struct request_queue *q, struct request *rq, ++ struct bio *bio, gfp_t gfp_mask) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq); ++ const int rw = rq_data_dir(rq); ++ const int is_sync = rq_is_sync(rq); ++ struct bfq_queue *bfqq; ++ struct bfq_group *bfqg; ++ unsigned long flags; ++ ++ might_sleep_if(gfp_mask & __GFP_WAIT); ++ ++ bfq_changed_ioprio(bic); ++ ++ spin_lock_irqsave(q->queue_lock, flags); ++ ++ if (bic == NULL) ++ goto queue_fail; ++ ++ bfqg = bfq_bic_update_cgroup(bic); ++ ++new_queue: ++ bfqq = bic_to_bfqq(bic, is_sync); ++ if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { ++ bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask); ++ bic_set_bfqq(bic, bfqq, is_sync); ++ } else { ++ /* ++ * If the queue was seeky for too long, break it apart. ++ */ ++ if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { ++ bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); ++ bfqq = bfq_split_bfqq(bic, bfqq); ++ if (!bfqq) ++ goto new_queue; ++ } ++ ++ /* ++ * Check to see if this queue is scheduled to merge with ++ * another closely cooperating queue. The merging of queues ++ * happens here as it must be done in process context. ++ * The reference on new_bfqq was taken in merge_bfqqs. ++ */ ++ if (bfqq->new_bfqq != NULL) ++ bfqq = bfq_merge_bfqqs(bfqd, bic, bfqq); ++ } ++ ++ bfqq->allocated[rw]++; ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq, ++ atomic_read(&bfqq->ref)); ++ ++ rq->elv.priv[0] = bic; ++ rq->elv.priv[1] = bfqq; ++ ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 0; ++ ++queue_fail: ++ bfq_schedule_dispatch(bfqd); ++ spin_unlock_irqrestore(q->queue_lock, flags); ++ ++ return 1; ++} ++ ++static void bfq_kick_queue(struct work_struct *work) ++{ ++ struct bfq_data *bfqd = ++ container_of(work, struct bfq_data, unplug_work); ++ struct request_queue *q = bfqd->queue; ++ ++ spin_lock_irq(q->queue_lock); ++ __blk_run_queue(q); ++ spin_unlock_irq(q->queue_lock); ++} ++ ++/* ++ * Handler of the expiration of the timer running if the in-service queue ++ * is idling inside its time slice. ++ */ ++static void bfq_idle_slice_timer(unsigned long data) ++{ ++ struct bfq_data *bfqd = (struct bfq_data *)data; ++ struct bfq_queue *bfqq; ++ unsigned long flags; ++ enum bfqq_expiration reason; ++ ++ spin_lock_irqsave(bfqd->queue->queue_lock, flags); ++ ++ bfqq = bfqd->in_service_queue; ++ /* ++ * Theoretical race here: the in-service queue can be NULL or ++ * different from the queue that was idling if the timer handler ++ * spins on the queue_lock and a new request arrives for the ++ * current queue and there is a full dispatch cycle that changes ++ * the in-service queue. This can hardly happen, but in the worst ++ * case we just expire a queue too early. ++ */ ++ if (bfqq != NULL) { ++ bfq_log_bfqq(bfqd, bfqq, "slice_timer expired"); ++ if (bfq_bfqq_budget_timeout(bfqq)) ++ /* ++ * Also here the queue can be safely expired ++ * for budget timeout without wasting ++ * guarantees ++ */ ++ reason = BFQ_BFQQ_BUDGET_TIMEOUT; ++ else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0) ++ /* ++ * The queue may not be empty upon timer expiration, ++ * because we may not disable the timer when the ++ * first request of the in-service queue arrives ++ * during disk idling. ++ */ ++ reason = BFQ_BFQQ_TOO_IDLE; ++ else ++ goto schedule_dispatch; ++ ++ bfq_bfqq_expire(bfqd, bfqq, 1, reason); ++ } ++ ++schedule_dispatch: ++ bfq_schedule_dispatch(bfqd); ++ ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, flags); ++} ++ ++static void bfq_shutdown_timer_wq(struct bfq_data *bfqd) ++{ ++ del_timer_sync(&bfqd->idle_slice_timer); ++ cancel_work_sync(&bfqd->unplug_work); ++} ++ ++static inline void __bfq_put_async_bfqq(struct bfq_data *bfqd, ++ struct bfq_queue **bfqq_ptr) ++{ ++ struct bfq_group *root_group = bfqd->root_group; ++ struct bfq_queue *bfqq = *bfqq_ptr; ++ ++ bfq_log(bfqd, "put_async_bfqq: %p", bfqq); ++ if (bfqq != NULL) { ++ bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group); ++ bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ *bfqq_ptr = NULL; ++ } ++} ++ ++/* ++ * Release all the bfqg references to its async queues. If we are ++ * deallocating the group these queues may still contain requests, so ++ * we reparent them to the root cgroup (i.e., the only one that will ++ * exist for sure until all the requests on a device are gone). ++ */ ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg) ++{ ++ int i, j; ++ ++ for (i = 0; i < 2; i++) ++ for (j = 0; j < IOPRIO_BE_NR; j++) ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]); ++ ++ __bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq); ++} ++ ++static void bfq_exit_queue(struct elevator_queue *e) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ struct request_queue *q = bfqd->queue; ++ struct bfq_queue *bfqq, *n; ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ spin_lock_irq(q->queue_lock); ++ ++ BUG_ON(bfqd->in_service_queue != NULL); ++ list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list) ++ bfq_deactivate_bfqq(bfqd, bfqq, 0); ++ ++ bfq_disconnect_groups(bfqd); ++ spin_unlock_irq(q->queue_lock); ++ ++ bfq_shutdown_timer_wq(bfqd); ++ ++ synchronize_rcu(); ++ ++ BUG_ON(timer_pending(&bfqd->idle_slice_timer)); ++ ++ bfq_free_root_group(bfqd); ++ kfree(bfqd); ++} ++ ++static int bfq_init_queue(struct request_queue *q, struct elevator_type *e) ++{ ++ struct bfq_group *bfqg; ++ struct bfq_data *bfqd; ++ struct elevator_queue *eq; ++ ++ eq = elevator_alloc(q, e); ++ if (eq == NULL) ++ return -ENOMEM; ++ ++ bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node); ++ if (bfqd == NULL) { ++ kobject_put(&eq->kobj); ++ return -ENOMEM; ++ } ++ eq->elevator_data = bfqd; ++ ++ /* ++ * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues. ++ * Grab a permanent reference to it, so that the normal code flow ++ * will not attempt to free it. ++ */ ++ bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, 1, 0); ++ atomic_inc(&bfqd->oom_bfqq.ref); ++ bfqd->oom_bfqq.entity.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO; ++ bfqd->oom_bfqq.entity.new_ioprio_class = IOPRIO_CLASS_BE; ++ /* ++ * Trigger weight initialization, according to ioprio, at the ++ * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio ++ * class won't be changed any more. ++ */ ++ bfqd->oom_bfqq.entity.ioprio_changed = 1; ++ ++ bfqd->queue = q; ++ ++ spin_lock_irq(q->queue_lock); ++ q->elevator = eq; ++ spin_unlock_irq(q->queue_lock); ++ ++ bfqg = bfq_alloc_root_group(bfqd, q->node); ++ if (bfqg == NULL) { ++ kfree(bfqd); ++ kobject_put(&eq->kobj); ++ return -ENOMEM; ++ } ++ ++ bfqd->root_group = bfqg; ++ bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group); ++#ifdef CONFIG_CGROUP_BFQIO ++ bfqd->active_numerous_groups = 0; ++#endif ++ ++ init_timer(&bfqd->idle_slice_timer); ++ bfqd->idle_slice_timer.function = bfq_idle_slice_timer; ++ bfqd->idle_slice_timer.data = (unsigned long)bfqd; ++ ++ bfqd->rq_pos_tree = RB_ROOT; ++ bfqd->queue_weights_tree = RB_ROOT; ++ bfqd->group_weights_tree = RB_ROOT; ++ ++ INIT_WORK(&bfqd->unplug_work, bfq_kick_queue); ++ ++ INIT_LIST_HEAD(&bfqd->active_list); ++ INIT_LIST_HEAD(&bfqd->idle_list); ++ INIT_HLIST_HEAD(&bfqd->burst_list); ++ ++ bfqd->hw_tag = -1; ++ ++ bfqd->bfq_max_budget = bfq_default_max_budget; ++ ++ bfqd->bfq_quantum = bfq_quantum; ++ bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0]; ++ bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1]; ++ bfqd->bfq_back_max = bfq_back_max; ++ bfqd->bfq_back_penalty = bfq_back_penalty; ++ bfqd->bfq_slice_idle = bfq_slice_idle; ++ bfqd->bfq_class_idle_last_service = 0; ++ bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq; ++ bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async; ++ bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync; ++ ++ bfqd->bfq_coop_thresh = 2; ++ bfqd->bfq_failed_cooperations = 7000; ++ bfqd->bfq_requests_within_timer = 120; ++ ++ bfqd->bfq_large_burst_thresh = 11; ++ bfqd->bfq_burst_interval = msecs_to_jiffies(500); ++ ++ bfqd->low_latency = true; ++ ++ bfqd->bfq_wr_coeff = 20; ++ bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300); ++ bfqd->bfq_wr_max_time = 0; ++ bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000); ++ bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500); ++ bfqd->bfq_wr_max_softrt_rate = 7000; /* ++ * Approximate rate required ++ * to playback or record a ++ * high-definition compressed ++ * video. ++ */ ++ bfqd->wr_busy_queues = 0; ++ bfqd->busy_in_flight_queues = 0; ++ bfqd->const_seeky_busy_in_flight_queues = 0; ++ ++ /* ++ * Begin by assuming, optimistically, that the device peak rate is ++ * equal to the highest reference rate. ++ */ ++ bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] * ++ T_fast[blk_queue_nonrot(bfqd->queue)]; ++ bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)]; ++ bfqd->device_speed = BFQ_BFQD_FAST; ++ ++ return 0; ++} ++ ++static void bfq_slab_kill(void) ++{ ++ if (bfq_pool != NULL) ++ kmem_cache_destroy(bfq_pool); ++} ++ ++static int __init bfq_slab_setup(void) ++{ ++ bfq_pool = KMEM_CACHE(bfq_queue, 0); ++ if (bfq_pool == NULL) ++ return -ENOMEM; ++ return 0; ++} ++ ++static ssize_t bfq_var_show(unsigned int var, char *page) ++{ ++ return sprintf(page, "%d\n", var); ++} ++ ++static ssize_t bfq_var_store(unsigned long *var, const char *page, ++ size_t count) ++{ ++ unsigned long new_val; ++ int ret = kstrtoul(page, 10, &new_val); ++ ++ if (ret == 0) ++ *var = new_val; ++ ++ return count; ++} ++ ++static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ? ++ jiffies_to_msecs(bfqd->bfq_wr_max_time) : ++ jiffies_to_msecs(bfq_wr_duration(bfqd))); ++} ++ ++static ssize_t bfq_weights_show(struct elevator_queue *e, char *page) ++{ ++ struct bfq_queue *bfqq; ++ struct bfq_data *bfqd = e->elevator_data; ++ ssize_t num_char = 0; ++ ++ num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n", ++ bfqd->queued); ++ ++ spin_lock_irq(bfqd->queue->queue_lock); ++ ++ num_char += sprintf(page + num_char, "Active:\n"); ++ list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, nr_queued %d %d, dur %d/%u\n", ++ bfqq->pid, ++ bfqq->entity.weight, ++ bfqq->queued[0], ++ bfqq->queued[1], ++ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ num_char += sprintf(page + num_char, "Idle:\n"); ++ list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) { ++ num_char += sprintf(page + num_char, ++ "pid%d: weight %hu, dur %d/%u\n", ++ bfqq->pid, ++ bfqq->entity.weight, ++ jiffies_to_msecs(jiffies - ++ bfqq->last_wr_start_finish), ++ jiffies_to_msecs(bfqq->wr_cur_max_time)); ++ } ++ ++ spin_unlock_irq(bfqd->queue->queue_lock); ++ ++ return num_char; ++} ++ ++#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ ++static ssize_t __FUNC(struct elevator_queue *e, char *page) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned int __data = __VAR; \ ++ if (__CONV) \ ++ __data = jiffies_to_msecs(__data); \ ++ return bfq_var_show(__data, (page)); \ ++} ++SHOW_FUNCTION(bfq_quantum_show, bfqd->bfq_quantum, 0); ++SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1); ++SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1); ++SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0); ++SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0); ++SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1); ++SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0); ++SHOW_FUNCTION(bfq_max_budget_async_rq_show, ++ bfqd->bfq_max_budget_async_rq, 0); ++SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1); ++SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1); ++SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0); ++SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0); ++SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1); ++SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1); ++SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async, ++ 1); ++SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0); ++#undef SHOW_FUNCTION ++ ++#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ ++static ssize_t \ ++__FUNC(struct elevator_queue *e, const char *page, size_t count) \ ++{ \ ++ struct bfq_data *bfqd = e->elevator_data; \ ++ unsigned long uninitialized_var(__data); \ ++ int ret = bfq_var_store(&__data, (page), count); \ ++ if (__data < (MIN)) \ ++ __data = (MIN); \ ++ else if (__data > (MAX)) \ ++ __data = (MAX); \ ++ if (__CONV) \ ++ *(__PTR) = msecs_to_jiffies(__data); \ ++ else \ ++ *(__PTR) = __data; \ ++ return ret; \ ++} ++STORE_FUNCTION(bfq_quantum_store, &bfqd->bfq_quantum, 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0); ++STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1, ++ INT_MAX, 0); ++STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq, ++ 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0); ++STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX, ++ 1); ++STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0, ++ INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_min_inter_arr_async_store, ++ &bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1); ++STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0, ++ INT_MAX, 0); ++#undef STORE_FUNCTION ++ ++/* do nothing for the moment */ ++static ssize_t bfq_weights_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ return count; ++} ++ ++static inline unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd) ++{ ++ u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]); ++ ++ if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES) ++ return bfq_calc_max_budget(bfqd->peak_rate, timeout); ++ else ++ return bfq_default_max_budget; ++} ++ ++static ssize_t bfq_max_budget_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data == 0) ++ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); ++ else { ++ if (__data > INT_MAX) ++ __data = INT_MAX; ++ bfqd->bfq_max_budget = __data; ++ } ++ ++ bfqd->bfq_user_max_budget = __data; ++ ++ return ret; ++} ++ ++static ssize_t bfq_timeout_sync_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data < 1) ++ __data = 1; ++ else if (__data > INT_MAX) ++ __data = INT_MAX; ++ ++ bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data); ++ if (bfqd->bfq_user_max_budget == 0) ++ bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd); ++ ++ return ret; ++} ++ ++static ssize_t bfq_low_latency_store(struct elevator_queue *e, ++ const char *page, size_t count) ++{ ++ struct bfq_data *bfqd = e->elevator_data; ++ unsigned long uninitialized_var(__data); ++ int ret = bfq_var_store(&__data, (page), count); ++ ++ if (__data > 1) ++ __data = 1; ++ if (__data == 0 && bfqd->low_latency != 0) ++ bfq_end_wr(bfqd); ++ bfqd->low_latency = __data; ++ ++ return ret; ++} ++ ++#define BFQ_ATTR(name) \ ++ __ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store) ++ ++static struct elv_fs_entry bfq_attrs[] = { ++ BFQ_ATTR(quantum), ++ BFQ_ATTR(fifo_expire_sync), ++ BFQ_ATTR(fifo_expire_async), ++ BFQ_ATTR(back_seek_max), ++ BFQ_ATTR(back_seek_penalty), ++ BFQ_ATTR(slice_idle), ++ BFQ_ATTR(max_budget), ++ BFQ_ATTR(max_budget_async_rq), ++ BFQ_ATTR(timeout_sync), ++ BFQ_ATTR(timeout_async), ++ BFQ_ATTR(low_latency), ++ BFQ_ATTR(wr_coeff), ++ BFQ_ATTR(wr_max_time), ++ BFQ_ATTR(wr_rt_max_time), ++ BFQ_ATTR(wr_min_idle_time), ++ BFQ_ATTR(wr_min_inter_arr_async), ++ BFQ_ATTR(wr_max_softrt_rate), ++ BFQ_ATTR(weights), ++ __ATTR_NULL ++}; ++ ++static struct elevator_type iosched_bfq = { ++ .ops = { ++ .elevator_merge_fn = bfq_merge, ++ .elevator_merged_fn = bfq_merged_request, ++ .elevator_merge_req_fn = bfq_merged_requests, ++ .elevator_allow_merge_fn = bfq_allow_merge, ++ .elevator_dispatch_fn = bfq_dispatch_requests, ++ .elevator_add_req_fn = bfq_insert_request, ++ .elevator_activate_req_fn = bfq_activate_request, ++ .elevator_deactivate_req_fn = bfq_deactivate_request, ++ .elevator_completed_req_fn = bfq_completed_request, ++ .elevator_former_req_fn = elv_rb_former_request, ++ .elevator_latter_req_fn = elv_rb_latter_request, ++ .elevator_init_icq_fn = bfq_init_icq, ++ .elevator_exit_icq_fn = bfq_exit_icq, ++ .elevator_set_req_fn = bfq_set_request, ++ .elevator_put_req_fn = bfq_put_request, ++ .elevator_may_queue_fn = bfq_may_queue, ++ .elevator_init_fn = bfq_init_queue, ++ .elevator_exit_fn = bfq_exit_queue, ++ }, ++ .icq_size = sizeof(struct bfq_io_cq), ++ .icq_align = __alignof__(struct bfq_io_cq), ++ .elevator_attrs = bfq_attrs, ++ .elevator_name = "bfq", ++ .elevator_owner = THIS_MODULE, ++}; ++ ++static int __init bfq_init(void) ++{ ++ /* ++ * Can be 0 on HZ < 1000 setups. ++ */ ++ if (bfq_slice_idle == 0) ++ bfq_slice_idle = 1; ++ ++ if (bfq_timeout_async == 0) ++ bfq_timeout_async = 1; ++ ++ if (bfq_slab_setup()) ++ return -ENOMEM; ++ ++ /* ++ * Times to load large popular applications for the typical systems ++ * installed on the reference devices (see the comments before the ++ * definitions of the two arrays). ++ */ ++ T_slow[0] = msecs_to_jiffies(2600); ++ T_slow[1] = msecs_to_jiffies(1000); ++ T_fast[0] = msecs_to_jiffies(5500); ++ T_fast[1] = msecs_to_jiffies(2000); ++ ++ /* ++ * Thresholds that determine the switch between speed classes (see ++ * the comments before the definition of the array). ++ */ ++ device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2; ++ device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2; ++ ++ elv_register(&iosched_bfq); ++ pr_info("BFQ I/O-scheduler version: v7r7"); ++ ++ return 0; ++} ++ ++static void __exit bfq_exit(void) ++{ ++ elv_unregister(&iosched_bfq); ++ bfq_slab_kill(); ++} ++ ++module_init(bfq_init); ++module_exit(bfq_exit); ++ ++MODULE_AUTHOR("Fabio Checconi, Paolo Valente"); ++MODULE_LICENSE("GPL"); +diff --git a/block/bfq-sched.c b/block/bfq-sched.c +new file mode 100644 +index 0000000..2931563 +--- /dev/null ++++ b/block/bfq-sched.c +@@ -0,0 +1,1214 @@ ++/* ++ * BFQ: Hierarchical B-WF2Q+ scheduler. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++#ifdef CONFIG_CGROUP_BFQIO ++#define for_each_entity(entity) \ ++ for (; entity != NULL; entity = entity->parent) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (; entity && ({ parent = entity->parent; 1; }); entity = parent) ++ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd); ++ ++static inline void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++ struct bfq_entity *bfqg_entity; ++ struct bfq_group *bfqg; ++ struct bfq_sched_data *group_sd; ++ ++ BUG_ON(next_in_service == NULL); ++ ++ group_sd = next_in_service->sched_data; ++ ++ bfqg = container_of(group_sd, struct bfq_group, sched_data); ++ /* ++ * bfq_group's my_entity field is not NULL only if the group ++ * is not the root group. We must not touch the root entity ++ * as it must never become an in-service entity. ++ */ ++ bfqg_entity = bfqg->my_entity; ++ if (bfqg_entity != NULL) ++ bfqg_entity->budget = next_in_service->budget; ++} ++ ++static int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ struct bfq_entity *next_in_service; ++ ++ if (sd->in_service_entity != NULL) ++ /* will update/requeue at the end of service */ ++ return 0; ++ ++ /* ++ * NOTE: this can be improved in many ways, such as returning ++ * 1 (and thus propagating upwards the update) only when the ++ * budget changes, or caching the bfqq that will be scheduled ++ * next from this subtree. By now we worry more about ++ * correctness than about performance... ++ */ ++ next_in_service = bfq_lookup_next_entity(sd, 0, NULL); ++ sd->next_in_service = next_in_service; ++ ++ if (next_in_service != NULL) ++ bfq_update_budget(next_in_service); ++ ++ return 1; ++} ++ ++static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++ BUG_ON(sd->next_in_service != entity); ++} ++#else ++#define for_each_entity(entity) \ ++ for (; entity != NULL; entity = NULL) ++ ++#define for_each_entity_safe(entity, parent) \ ++ for (parent = NULL; entity != NULL; entity = parent) ++ ++static inline int bfq_update_next_in_service(struct bfq_sched_data *sd) ++{ ++ return 0; ++} ++ ++static inline void bfq_check_next_in_service(struct bfq_sched_data *sd, ++ struct bfq_entity *entity) ++{ ++} ++ ++static inline void bfq_update_budget(struct bfq_entity *next_in_service) ++{ ++} ++#endif ++ ++/* ++ * Shift for timestamp calculations. This actually limits the maximum ++ * service allowed in one timestamp delta (small shift values increase it), ++ * the maximum total weight that can be used for the queues in the system ++ * (big shift values increase it), and the period of virtual time ++ * wraparounds. ++ */ ++#define WFQ_SERVICE_SHIFT 22 ++ ++/** ++ * bfq_gt - compare two timestamps. ++ * @a: first ts. ++ * @b: second ts. ++ * ++ * Return @a > @b, dealing with wrapping correctly. ++ */ ++static inline int bfq_gt(u64 a, u64 b) ++{ ++ return (s64)(a - b) > 0; ++} ++ ++static inline struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = NULL; ++ ++ BUG_ON(entity == NULL); ++ ++ if (entity->my_sched_data == NULL) ++ bfqq = container_of(entity, struct bfq_queue, entity); ++ ++ return bfqq; ++} ++ ++ ++/** ++ * bfq_delta - map service into the virtual time domain. ++ * @service: amount of service. ++ * @weight: scale factor (weight of an entity or weight sum). ++ */ ++static inline u64 bfq_delta(unsigned long service, ++ unsigned long weight) ++{ ++ u64 d = (u64)service << WFQ_SERVICE_SHIFT; ++ ++ do_div(d, weight); ++ return d; ++} ++ ++/** ++ * bfq_calc_finish - assign the finish time to an entity. ++ * @entity: the entity to act upon. ++ * @service: the service to be charged to the entity. ++ */ ++static inline void bfq_calc_finish(struct bfq_entity *entity, ++ unsigned long service) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ BUG_ON(entity->weight == 0); ++ ++ entity->finish = entity->start + ++ bfq_delta(service, entity->weight); ++ ++ if (bfqq != NULL) { ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: serv %lu, w %d", ++ service, entity->weight); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, ++ "calc_finish: start %llu, finish %llu, delta %llu", ++ entity->start, entity->finish, ++ bfq_delta(service, entity->weight)); ++ } ++} ++ ++/** ++ * bfq_entity_of - get an entity from a node. ++ * @node: the node field of the entity. ++ * ++ * Convert a node pointer to the relative entity. This is used only ++ * to simplify the logic of some functions and not as the generic ++ * conversion mechanism because, e.g., in the tree walking functions, ++ * the check for a %NULL value would be redundant. ++ */ ++static inline struct bfq_entity *bfq_entity_of(struct rb_node *node) ++{ ++ struct bfq_entity *entity = NULL; ++ ++ if (node != NULL) ++ entity = rb_entry(node, struct bfq_entity, rb_node); ++ ++ return entity; ++} ++ ++/** ++ * bfq_extract - remove an entity from a tree. ++ * @root: the tree root. ++ * @entity: the entity to remove. ++ */ ++static inline void bfq_extract(struct rb_root *root, ++ struct bfq_entity *entity) ++{ ++ BUG_ON(entity->tree != root); ++ ++ entity->tree = NULL; ++ rb_erase(&entity->rb_node, root); ++} ++ ++/** ++ * bfq_idle_extract - extract an entity from the idle tree. ++ * @st: the service tree of the owning @entity. ++ * @entity: the entity being removed. ++ */ ++static void bfq_idle_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *next; ++ ++ BUG_ON(entity->tree != &st->idle); ++ ++ if (entity == st->first_idle) { ++ next = rb_next(&entity->rb_node); ++ st->first_idle = bfq_entity_of(next); ++ } ++ ++ if (entity == st->last_idle) { ++ next = rb_prev(&entity->rb_node); ++ st->last_idle = bfq_entity_of(next); ++ } ++ ++ bfq_extract(&st->idle, entity); ++ ++ if (bfqq != NULL) ++ list_del(&bfqq->bfqq_list); ++} ++ ++/** ++ * bfq_insert - generic tree insertion. ++ * @root: tree root. ++ * @entity: entity to insert. ++ * ++ * This is used for the idle and the active tree, since they are both ++ * ordered by finish time. ++ */ ++static void bfq_insert(struct rb_root *root, struct bfq_entity *entity) ++{ ++ struct bfq_entity *entry; ++ struct rb_node **node = &root->rb_node; ++ struct rb_node *parent = NULL; ++ ++ BUG_ON(entity->tree != NULL); ++ ++ while (*node != NULL) { ++ parent = *node; ++ entry = rb_entry(parent, struct bfq_entity, rb_node); ++ ++ if (bfq_gt(entry->finish, entity->finish)) ++ node = &parent->rb_left; ++ else ++ node = &parent->rb_right; ++ } ++ ++ rb_link_node(&entity->rb_node, parent, node); ++ rb_insert_color(&entity->rb_node, root); ++ ++ entity->tree = root; ++} ++ ++/** ++ * bfq_update_min - update the min_start field of a entity. ++ * @entity: the entity to update. ++ * @node: one of its children. ++ * ++ * This function is called when @entity may store an invalid value for ++ * min_start due to updates to the active tree. The function assumes ++ * that the subtree rooted at @node (which may be its left or its right ++ * child) has a valid min_start value. ++ */ ++static inline void bfq_update_min(struct bfq_entity *entity, ++ struct rb_node *node) ++{ ++ struct bfq_entity *child; ++ ++ if (node != NULL) { ++ child = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entity->min_start, child->min_start)) ++ entity->min_start = child->min_start; ++ } ++} ++ ++/** ++ * bfq_update_active_node - recalculate min_start. ++ * @node: the node to update. ++ * ++ * @node may have changed position or one of its children may have moved, ++ * this function updates its min_start value. The left and right subtrees ++ * are assumed to hold a correct min_start value. ++ */ ++static inline void bfq_update_active_node(struct rb_node *node) ++{ ++ struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node); ++ ++ entity->min_start = entity->start; ++ bfq_update_min(entity, node->rb_right); ++ bfq_update_min(entity, node->rb_left); ++} ++ ++/** ++ * bfq_update_active_tree - update min_start for the whole active tree. ++ * @node: the starting node. ++ * ++ * @node must be the deepest modified node after an update. This function ++ * updates its min_start using the values held by its children, assuming ++ * that they did not change, and then updates all the nodes that may have ++ * changed in the path to the root. The only nodes that may have changed ++ * are the ones in the path or their siblings. ++ */ ++static void bfq_update_active_tree(struct rb_node *node) ++{ ++ struct rb_node *parent; ++ ++up: ++ bfq_update_active_node(node); ++ ++ parent = rb_parent(node); ++ if (parent == NULL) ++ return; ++ ++ if (node == parent->rb_left && parent->rb_right != NULL) ++ bfq_update_active_node(parent->rb_right); ++ else if (parent->rb_left != NULL) ++ bfq_update_active_node(parent->rb_left); ++ ++ node = parent; ++ goto up; ++} ++ ++static void bfq_weights_tree_add(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++static void bfq_weights_tree_remove(struct bfq_data *bfqd, ++ struct bfq_entity *entity, ++ struct rb_root *root); ++ ++ ++/** ++ * bfq_active_insert - insert an entity in the active tree of its ++ * group/device. ++ * @st: the service tree of the entity. ++ * @entity: the entity being inserted. ++ * ++ * The active tree is ordered by finish time, but an extra key is kept ++ * per each node, containing the minimum value for the start times of ++ * its children (and the node itself), so it's possible to search for ++ * the eligible node with the lowest finish time in logarithmic time. ++ */ ++static void bfq_active_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node = &entity->rb_node; ++#ifdef CONFIG_CGROUP_BFQIO ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ bfq_insert(&st->active, entity); ++ ++ if (node->rb_left != NULL) ++ node = node->rb_left; ++ else if (node->rb_right != NULL) ++ node = node->rb_right; ++ ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq != NULL) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list); ++#ifdef CONFIG_CGROUP_BFQIO ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ bfqg->active_entities++; ++ if (bfqg->active_entities == 2) ++ bfqd->active_numerous_groups++; ++ } ++#endif ++} ++ ++/** ++ * bfq_ioprio_to_weight - calc a weight from an ioprio. ++ * @ioprio: the ioprio value to convert. ++ */ ++static inline unsigned short bfq_ioprio_to_weight(int ioprio) ++{ ++ BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR); ++ return IOPRIO_BE_NR - ioprio; ++} ++ ++/** ++ * bfq_weight_to_ioprio - calc an ioprio from a weight. ++ * @weight: the weight value to convert. ++ * ++ * To preserve as mush as possible the old only-ioprio user interface, ++ * 0 is used as an escape ioprio value for weights (numerically) equal or ++ * larger than IOPRIO_BE_NR ++ */ ++static inline unsigned short bfq_weight_to_ioprio(int weight) ++{ ++ BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT); ++ return IOPRIO_BE_NR - weight < 0 ? 0 : IOPRIO_BE_NR - weight; ++} ++ ++static inline void bfq_get_entity(struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ ++ if (bfqq != NULL) { ++ atomic_inc(&bfqq->ref); ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ } ++} ++ ++/** ++ * bfq_find_deepest - find the deepest node that an extraction can modify. ++ * @node: the node being removed. ++ * ++ * Do the first step of an extraction in an rb tree, looking for the ++ * node that will replace @node, and returning the deepest node that ++ * the following modifications to the tree can touch. If @node is the ++ * last node in the tree return %NULL. ++ */ ++static struct rb_node *bfq_find_deepest(struct rb_node *node) ++{ ++ struct rb_node *deepest; ++ ++ if (node->rb_right == NULL && node->rb_left == NULL) ++ deepest = rb_parent(node); ++ else if (node->rb_right == NULL) ++ deepest = node->rb_left; ++ else if (node->rb_left == NULL) ++ deepest = node->rb_right; ++ else { ++ deepest = rb_next(node); ++ if (deepest->rb_right != NULL) ++ deepest = deepest->rb_right; ++ else if (rb_parent(deepest) != node) ++ deepest = rb_parent(deepest); ++ } ++ ++ return deepest; ++} ++ ++/** ++ * bfq_active_extract - remove an entity from the active tree. ++ * @st: the service_tree containing the tree. ++ * @entity: the entity being removed. ++ */ ++static void bfq_active_extract(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct rb_node *node; ++#ifdef CONFIG_CGROUP_BFQIO ++ struct bfq_sched_data *sd = NULL; ++ struct bfq_group *bfqg = NULL; ++ struct bfq_data *bfqd = NULL; ++#endif ++ ++ node = bfq_find_deepest(&entity->rb_node); ++ bfq_extract(&st->active, entity); ++ ++ if (node != NULL) ++ bfq_update_active_tree(node); ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ sd = entity->sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++#endif ++ if (bfqq != NULL) ++ list_del(&bfqq->bfqq_list); ++#ifdef CONFIG_CGROUP_BFQIO ++ else { /* bfq_group */ ++ BUG_ON(!bfqd); ++ bfq_weights_tree_remove(bfqd, entity, ++ &bfqd->group_weights_tree); ++ } ++ if (bfqg != bfqd->root_group) { ++ BUG_ON(!bfqg); ++ BUG_ON(!bfqd); ++ BUG_ON(!bfqg->active_entities); ++ bfqg->active_entities--; ++ if (bfqg->active_entities == 1) { ++ BUG_ON(!bfqd->active_numerous_groups); ++ bfqd->active_numerous_groups--; ++ } ++ } ++#endif ++} ++ ++/** ++ * bfq_idle_insert - insert an entity into the idle tree. ++ * @st: the service tree containing the tree. ++ * @entity: the entity to insert. ++ */ ++static void bfq_idle_insert(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (first_idle == NULL || bfq_gt(first_idle->finish, entity->finish)) ++ st->first_idle = entity; ++ if (last_idle == NULL || bfq_gt(entity->finish, last_idle->finish)) ++ st->last_idle = entity; ++ ++ bfq_insert(&st->idle, entity); ++ ++ if (bfqq != NULL) ++ list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list); ++} ++ ++/** ++ * bfq_forget_entity - remove an entity from the wfq trees. ++ * @st: the service tree. ++ * @entity: the entity being removed. ++ * ++ * Update the device status and forget everything about @entity, putting ++ * the device reference to it, if it is a queue. Entities belonging to ++ * groups are not refcounted. ++ */ ++static void bfq_forget_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ struct bfq_sched_data *sd; ++ ++ BUG_ON(!entity->on_st); ++ ++ entity->on_st = 0; ++ st->wsum -= entity->weight; ++ if (bfqq != NULL) { ++ sd = entity->sched_data; ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d", ++ bfqq, atomic_read(&bfqq->ref)); ++ bfq_put_queue(bfqq); ++ } ++} ++ ++/** ++ * bfq_put_idle_entity - release the idle tree ref of an entity. ++ * @st: service tree for the entity. ++ * @entity: the entity being released. ++ */ ++static void bfq_put_idle_entity(struct bfq_service_tree *st, ++ struct bfq_entity *entity) ++{ ++ bfq_idle_extract(st, entity); ++ bfq_forget_entity(st, entity); ++} ++ ++/** ++ * bfq_forget_idle - update the idle tree if necessary. ++ * @st: the service tree to act upon. ++ * ++ * To preserve the global O(log N) complexity we only remove one entry here; ++ * as the idle tree will not grow indefinitely this can be done safely. ++ */ ++static void bfq_forget_idle(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *first_idle = st->first_idle; ++ struct bfq_entity *last_idle = st->last_idle; ++ ++ if (RB_EMPTY_ROOT(&st->active) && last_idle != NULL && ++ !bfq_gt(last_idle->finish, st->vtime)) { ++ /* ++ * Forget the whole idle tree, increasing the vtime past ++ * the last finish time of idle entities. ++ */ ++ st->vtime = last_idle->finish; ++ } ++ ++ if (first_idle != NULL && !bfq_gt(first_idle->finish, st->vtime)) ++ bfq_put_idle_entity(st, first_idle); ++} ++ ++static struct bfq_service_tree * ++__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st, ++ struct bfq_entity *entity) ++{ ++ struct bfq_service_tree *new_st = old_st; ++ ++ if (entity->ioprio_changed) { ++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity); ++ unsigned short prev_weight, new_weight; ++ struct bfq_data *bfqd = NULL; ++ struct rb_root *root; ++#ifdef CONFIG_CGROUP_BFQIO ++ struct bfq_sched_data *sd; ++ struct bfq_group *bfqg; ++#endif ++ ++ if (bfqq != NULL) ++ bfqd = bfqq->bfqd; ++#ifdef CONFIG_CGROUP_BFQIO ++ else { ++ sd = entity->my_sched_data; ++ bfqg = container_of(sd, struct bfq_group, sched_data); ++ BUG_ON(!bfqg); ++ bfqd = (struct bfq_data *)bfqg->bfqd; ++ BUG_ON(!bfqd); ++ } ++#endif ++ ++ BUG_ON(old_st->wsum < entity->weight); ++ old_st->wsum -= entity->weight; ++ ++ if (entity->new_weight != entity->orig_weight) { ++ if (entity->new_weight < BFQ_MIN_WEIGHT || ++ entity->new_weight > BFQ_MAX_WEIGHT) { ++ printk(KERN_CRIT "update_weight_prio: " ++ "new_weight %d\n", ++ entity->new_weight); ++ BUG(); ++ } ++ entity->orig_weight = entity->new_weight; ++ entity->ioprio = ++ bfq_weight_to_ioprio(entity->orig_weight); ++ } else if (entity->new_ioprio != entity->ioprio) { ++ entity->ioprio = entity->new_ioprio; ++ entity->orig_weight = ++ bfq_ioprio_to_weight(entity->ioprio); ++ } else ++ entity->new_weight = entity->orig_weight = ++ bfq_ioprio_to_weight(entity->ioprio); ++ ++ entity->ioprio_class = entity->new_ioprio_class; ++ entity->ioprio_changed = 0; ++ ++ /* ++ * NOTE: here we may be changing the weight too early, ++ * this will cause unfairness. The correct approach ++ * would have required additional complexity to defer ++ * weight changes to the proper time instants (i.e., ++ * when entity->finish <= old_st->vtime). ++ */ ++ new_st = bfq_entity_service_tree(entity); ++ ++ prev_weight = entity->weight; ++ new_weight = entity->orig_weight * ++ (bfqq != NULL ? bfqq->wr_coeff : 1); ++ /* ++ * If the weight of the entity changes, remove the entity ++ * from its old weight counter (if there is a counter ++ * associated with the entity), and add it to the counter ++ * associated with its new weight. ++ */ ++ if (prev_weight != new_weight) { ++ root = bfqq ? &bfqd->queue_weights_tree : ++ &bfqd->group_weights_tree; ++ bfq_weights_tree_remove(bfqd, entity, root); ++ } ++ entity->weight = new_weight; ++ /* ++ * Add the entity to its weights tree only if it is ++ * not associated with a weight-raised queue. ++ */ ++ if (prev_weight != new_weight && ++ (bfqq ? bfqq->wr_coeff == 1 : 1)) ++ /* If we get here, root has been initialized. */ ++ bfq_weights_tree_add(bfqd, entity, root); ++ ++ new_st->wsum += entity->weight; ++ ++ if (new_st != old_st) ++ entity->start = new_st->vtime; ++ } ++ ++ return new_st; ++} ++ ++/** ++ * bfq_bfqq_served - update the scheduler status after selection for ++ * service. ++ * @bfqq: the queue being served. ++ * @served: bytes to transfer. ++ * ++ * NOTE: this can be optimized, as the timestamps of upper level entities ++ * are synchronized every time a new bfqq is selected for service. By now, ++ * we keep it to better check consistency. ++ */ ++static void bfq_bfqq_served(struct bfq_queue *bfqq, unsigned long served) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ struct bfq_service_tree *st; ++ ++ for_each_entity(entity) { ++ st = bfq_entity_service_tree(entity); ++ ++ entity->service += served; ++ BUG_ON(entity->service > entity->budget); ++ BUG_ON(st->wsum == 0); ++ ++ st->vtime += bfq_delta(served, st->wsum); ++ bfq_forget_idle(st); ++ } ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %lu secs", served); ++} ++ ++/** ++ * bfq_bfqq_charge_full_budget - set the service to the entity budget. ++ * @bfqq: the queue that needs a service update. ++ * ++ * When it's not possible to be fair in the service domain, because ++ * a queue is not consuming its budget fast enough (the meaning of ++ * fast depends on the timeout parameter), we charge it a full ++ * budget. In this way we should obtain a sort of time-domain ++ * fairness among all the seeky/slow queues. ++ */ ++static inline void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget"); ++ ++ bfq_bfqq_served(bfqq, entity->budget - entity->service); ++} ++ ++/** ++ * __bfq_activate_entity - activate an entity. ++ * @entity: the entity being activated. ++ * ++ * Called whenever an entity is activated, i.e., it is not active and one ++ * of its children receives a new request, or has to be reactivated due to ++ * budget exhaustion. It uses the current budget of the entity (and the ++ * service received if @entity is active) of the queue to calculate its ++ * timestamps. ++ */ ++static void __bfq_activate_entity(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ ++ if (entity == sd->in_service_entity) { ++ BUG_ON(entity->tree != NULL); ++ /* ++ * If we are requeueing the current entity we have ++ * to take care of not charging to it service it has ++ * not received. ++ */ ++ bfq_calc_finish(entity, entity->service); ++ entity->start = entity->finish; ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) { ++ /* ++ * Requeueing an entity due to a change of some ++ * next_in_service entity below it. We reuse the ++ * old start time. ++ */ ++ bfq_active_extract(st, entity); ++ } else if (entity->tree == &st->idle) { ++ /* ++ * Must be on the idle tree, bfq_idle_extract() will ++ * check for that. ++ */ ++ bfq_idle_extract(st, entity); ++ entity->start = bfq_gt(st->vtime, entity->finish) ? ++ st->vtime : entity->finish; ++ } else { ++ /* ++ * The finish time of the entity may be invalid, and ++ * it is in the past for sure, otherwise the queue ++ * would have been on the idle tree. ++ */ ++ entity->start = st->vtime; ++ st->wsum += entity->weight; ++ bfq_get_entity(entity); ++ ++ BUG_ON(entity->on_st); ++ entity->on_st = 1; ++ } ++ ++ st = __bfq_entity_update_weight_prio(st, entity); ++ bfq_calc_finish(entity, entity->budget); ++ bfq_active_insert(st, entity); ++} ++ ++/** ++ * bfq_activate_entity - activate an entity and its ancestors if necessary. ++ * @entity: the entity to activate. ++ * ++ * Activate @entity and all the entities on the path from it to the root. ++ */ ++static void bfq_activate_entity(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sd; ++ ++ for_each_entity(entity) { ++ __bfq_activate_entity(entity); ++ ++ sd = entity->sched_data; ++ if (!bfq_update_next_in_service(sd)) ++ /* ++ * No need to propagate the activation to the ++ * upper entities, as they will be updated when ++ * the in-service entity is rescheduled. ++ */ ++ break; ++ } ++} ++ ++/** ++ * __bfq_deactivate_entity - deactivate an entity from its service tree. ++ * @entity: the entity to deactivate. ++ * @requeue: if false, the entity will not be put into the idle tree. ++ * ++ * Deactivate an entity, independently from its previous state. If the ++ * entity was not on a service tree just return, otherwise if it is on ++ * any scheduler tree, extract it from that tree, and if necessary ++ * and if the caller did not specify @requeue, put it on the idle tree. ++ * ++ * Return %1 if the caller should update the entity hierarchy, i.e., ++ * if the entity was in service or if it was the next_in_service for ++ * its sched_data; return %0 otherwise. ++ */ ++static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd = entity->sched_data; ++ struct bfq_service_tree *st = bfq_entity_service_tree(entity); ++ int was_in_service = entity == sd->in_service_entity; ++ int ret = 0; ++ ++ if (!entity->on_st) ++ return 0; ++ ++ BUG_ON(was_in_service && entity->tree != NULL); ++ ++ if (was_in_service) { ++ bfq_calc_finish(entity, entity->service); ++ sd->in_service_entity = NULL; ++ } else if (entity->tree == &st->active) ++ bfq_active_extract(st, entity); ++ else if (entity->tree == &st->idle) ++ bfq_idle_extract(st, entity); ++ else if (entity->tree != NULL) ++ BUG(); ++ ++ if (was_in_service || sd->next_in_service == entity) ++ ret = bfq_update_next_in_service(sd); ++ ++ if (!requeue || !bfq_gt(entity->finish, st->vtime)) ++ bfq_forget_entity(st, entity); ++ else ++ bfq_idle_insert(st, entity); ++ ++ BUG_ON(sd->in_service_entity == entity); ++ BUG_ON(sd->next_in_service == entity); ++ ++ return ret; ++} ++ ++/** ++ * bfq_deactivate_entity - deactivate an entity. ++ * @entity: the entity to deactivate. ++ * @requeue: true if the entity can be put on the idle tree ++ */ ++static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue) ++{ ++ struct bfq_sched_data *sd; ++ struct bfq_entity *parent; ++ ++ for_each_entity_safe(entity, parent) { ++ sd = entity->sched_data; ++ ++ if (!__bfq_deactivate_entity(entity, requeue)) ++ /* ++ * The parent entity is still backlogged, and ++ * we don't need to update it as it is still ++ * in service. ++ */ ++ break; ++ ++ if (sd->next_in_service != NULL) ++ /* ++ * The parent entity is still backlogged and ++ * the budgets on the path towards the root ++ * need to be updated. ++ */ ++ goto update; ++ ++ /* ++ * If we reach there the parent is no more backlogged and ++ * we want to propagate the dequeue upwards. ++ */ ++ requeue = 1; ++ } ++ ++ return; ++ ++update: ++ entity = parent; ++ for_each_entity(entity) { ++ __bfq_activate_entity(entity); ++ ++ sd = entity->sched_data; ++ if (!bfq_update_next_in_service(sd)) ++ break; ++ } ++} ++ ++/** ++ * bfq_update_vtime - update vtime if necessary. ++ * @st: the service tree to act upon. ++ * ++ * If necessary update the service tree vtime to have at least one ++ * eligible entity, skipping to its start time. Assumes that the ++ * active tree of the device is not empty. ++ * ++ * NOTE: this hierarchical implementation updates vtimes quite often, ++ * we may end up with reactivated processes getting timestamps after a ++ * vtime skip done because we needed a ->first_active entity on some ++ * intermediate node. ++ */ ++static void bfq_update_vtime(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry; ++ struct rb_node *node = st->active.rb_node; ++ ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++ if (bfq_gt(entry->min_start, st->vtime)) { ++ st->vtime = entry->min_start; ++ bfq_forget_idle(st); ++ } ++} ++ ++/** ++ * bfq_first_active_entity - find the eligible entity with ++ * the smallest finish time ++ * @st: the service tree to select from. ++ * ++ * This function searches the first schedulable entity, starting from the ++ * root of the tree and going on the left every time on this side there is ++ * a subtree with at least one eligible (start >= vtime) entity. The path on ++ * the right is followed only if a) the left subtree contains no eligible ++ * entities and b) no eligible entity has been found yet. ++ */ ++static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st) ++{ ++ struct bfq_entity *entry, *first = NULL; ++ struct rb_node *node = st->active.rb_node; ++ ++ while (node != NULL) { ++ entry = rb_entry(node, struct bfq_entity, rb_node); ++left: ++ if (!bfq_gt(entry->start, st->vtime)) ++ first = entry; ++ ++ BUG_ON(bfq_gt(entry->min_start, st->vtime)); ++ ++ if (node->rb_left != NULL) { ++ entry = rb_entry(node->rb_left, ++ struct bfq_entity, rb_node); ++ if (!bfq_gt(entry->min_start, st->vtime)) { ++ node = node->rb_left; ++ goto left; ++ } ++ } ++ if (first != NULL) ++ break; ++ node = node->rb_right; ++ } ++ ++ BUG_ON(first == NULL && !RB_EMPTY_ROOT(&st->active)); ++ return first; ++} ++ ++/** ++ * __bfq_lookup_next_entity - return the first eligible entity in @st. ++ * @st: the service tree. ++ * ++ * Update the virtual time in @st and return the first eligible entity ++ * it contains. ++ */ ++static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st, ++ bool force) ++{ ++ struct bfq_entity *entity, *new_next_in_service = NULL; ++ ++ if (RB_EMPTY_ROOT(&st->active)) ++ return NULL; ++ ++ bfq_update_vtime(st); ++ entity = bfq_first_active_entity(st); ++ BUG_ON(bfq_gt(entity->start, st->vtime)); ++ ++ /* ++ * If the chosen entity does not match with the sched_data's ++ * next_in_service and we are forcedly serving the IDLE priority ++ * class tree, bubble up budget update. ++ */ ++ if (unlikely(force && entity != entity->sched_data->next_in_service)) { ++ new_next_in_service = entity; ++ for_each_entity(new_next_in_service) ++ bfq_update_budget(new_next_in_service); ++ } ++ ++ return entity; ++} ++ ++/** ++ * bfq_lookup_next_entity - return the first eligible entity in @sd. ++ * @sd: the sched_data. ++ * @extract: if true the returned entity will be also extracted from @sd. ++ * ++ * NOTE: since we cache the next_in_service entity at each level of the ++ * hierarchy, the complexity of the lookup can be decreased with ++ * absolutely no effort just returning the cached next_in_service value; ++ * we prefer to do full lookups to test the consistency of * the data ++ * structures. ++ */ ++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd, ++ int extract, ++ struct bfq_data *bfqd) ++{ ++ struct bfq_service_tree *st = sd->service_tree; ++ struct bfq_entity *entity; ++ int i = 0; ++ ++ BUG_ON(sd->in_service_entity != NULL); ++ ++ if (bfqd != NULL && ++ jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) { ++ entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1, ++ true); ++ if (entity != NULL) { ++ i = BFQ_IOPRIO_CLASSES - 1; ++ bfqd->bfq_class_idle_last_service = jiffies; ++ sd->next_in_service = entity; ++ } ++ } ++ for (; i < BFQ_IOPRIO_CLASSES; i++) { ++ entity = __bfq_lookup_next_entity(st + i, false); ++ if (entity != NULL) { ++ if (extract) { ++ bfq_check_next_in_service(sd, entity); ++ bfq_active_extract(st + i, entity); ++ sd->in_service_entity = entity; ++ sd->next_in_service = NULL; ++ } ++ break; ++ } ++ } ++ ++ return entity; ++} ++ ++/* ++ * Get next queue for service. ++ */ ++static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_entity *entity = NULL; ++ struct bfq_sched_data *sd; ++ struct bfq_queue *bfqq; ++ ++ BUG_ON(bfqd->in_service_queue != NULL); ++ ++ if (bfqd->busy_queues == 0) ++ return NULL; ++ ++ sd = &bfqd->root_group->sched_data; ++ for (; sd != NULL; sd = entity->my_sched_data) { ++ entity = bfq_lookup_next_entity(sd, 1, bfqd); ++ BUG_ON(entity == NULL); ++ entity->service = 0; ++ } ++ ++ bfqq = bfq_entity_to_bfqq(entity); ++ BUG_ON(bfqq == NULL); ++ ++ return bfqq; ++} ++ ++/* ++ * Forced extraction of the given queue. ++ */ ++static void bfq_get_next_queue_forced(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity; ++ struct bfq_sched_data *sd; ++ ++ BUG_ON(bfqd->in_service_queue != NULL); ++ ++ entity = &bfqq->entity; ++ /* ++ * Bubble up extraction/update from the leaf to the root. ++ */ ++ for_each_entity(entity) { ++ sd = entity->sched_data; ++ bfq_update_budget(entity); ++ bfq_update_vtime(bfq_entity_service_tree(entity)); ++ bfq_active_extract(bfq_entity_service_tree(entity), entity); ++ sd->in_service_entity = entity; ++ sd->next_in_service = NULL; ++ entity->service = 0; ++ } ++ ++ return; ++} ++ ++static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) ++{ ++ if (bfqd->in_service_bic != NULL) { ++ put_io_context(bfqd->in_service_bic->icq.ioc); ++ bfqd->in_service_bic = NULL; ++ } ++ ++ bfqd->in_service_queue = NULL; ++ del_timer(&bfqd->idle_slice_timer); ++} ++ ++static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ if (bfqq == bfqd->in_service_queue) ++ __bfq_bfqd_reset_in_service(bfqd); ++ ++ bfq_deactivate_entity(entity, requeue); ++} ++ ++static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ struct bfq_entity *entity = &bfqq->entity; ++ ++ bfq_activate_entity(entity); ++} ++ ++/* ++ * Called when the bfqq no longer has requests pending, remove it from ++ * the service tree. ++ */ ++static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ int requeue) ++{ ++ BUG_ON(!bfq_bfqq_busy(bfqq)); ++ BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list)); ++ ++ bfq_log_bfqq(bfqd, bfqq, "del from busy"); ++ ++ bfq_clear_bfqq_busy(bfqq); ++ ++ BUG_ON(bfqd->busy_queues == 0); ++ bfqd->busy_queues--; ++ ++ if (!bfqq->dispatched) { ++ bfq_weights_tree_remove(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ BUG_ON(!bfqd->busy_in_flight_queues); ++ bfqd->busy_in_flight_queues--; ++ if (bfq_bfqq_constantly_seeky(bfqq)) { ++ BUG_ON(!bfqd-> ++ const_seeky_busy_in_flight_queues); ++ bfqd->const_seeky_busy_in_flight_queues--; ++ } ++ } ++ } ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues--; ++ ++ bfq_deactivate_bfqq(bfqd, bfqq, requeue); ++} ++ ++/* ++ * Called when an inactive queue receives a new request. ++ */ ++static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq) ++{ ++ BUG_ON(bfq_bfqq_busy(bfqq)); ++ BUG_ON(bfqq == bfqd->in_service_queue); ++ ++ bfq_log_bfqq(bfqd, bfqq, "add to busy"); ++ ++ bfq_activate_bfqq(bfqd, bfqq); ++ ++ bfq_mark_bfqq_busy(bfqq); ++ bfqd->busy_queues++; ++ ++ if (!bfqq->dispatched) { ++ if (bfqq->wr_coeff == 1) ++ bfq_weights_tree_add(bfqd, &bfqq->entity, ++ &bfqd->queue_weights_tree); ++ if (!blk_queue_nonrot(bfqd->queue)) { ++ bfqd->busy_in_flight_queues++; ++ if (bfq_bfqq_constantly_seeky(bfqq)) ++ bfqd->const_seeky_busy_in_flight_queues++; ++ } ++ } ++ if (bfqq->wr_coeff > 1) ++ bfqd->wr_busy_queues++; ++} +diff --git a/block/bfq.h b/block/bfq.h +new file mode 100644 +index 0000000..3c5d85e +--- /dev/null ++++ b/block/bfq.h +@@ -0,0 +1,775 @@ ++/* ++ * BFQ-v7r7 for 3.19.0: data structures and common functions prototypes. ++ * ++ * Based on ideas and code from CFQ: ++ * Copyright (C) 2003 Jens Axboe ++ * ++ * Copyright (C) 2008 Fabio Checconi ++ * Paolo Valente ++ * ++ * Copyright (C) 2010 Paolo Valente ++ */ ++ ++#ifndef _BFQ_H ++#define _BFQ_H ++ ++#include ++#include ++#include ++#include ++ ++#define BFQ_IOPRIO_CLASSES 3 ++#define BFQ_CL_IDLE_TIMEOUT (HZ/5) ++ ++#define BFQ_MIN_WEIGHT 1 ++#define BFQ_MAX_WEIGHT 1000 ++ ++#define BFQ_DEFAULT_QUEUE_IOPRIO 4 ++ ++#define BFQ_DEFAULT_GRP_WEIGHT 10 ++#define BFQ_DEFAULT_GRP_IOPRIO 0 ++#define BFQ_DEFAULT_GRP_CLASS IOPRIO_CLASS_BE ++ ++struct bfq_entity; ++ ++/** ++ * struct bfq_service_tree - per ioprio_class service tree. ++ * @active: tree for active entities (i.e., those backlogged). ++ * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i). ++ * @first_idle: idle entity with minimum F_i. ++ * @last_idle: idle entity with maximum F_i. ++ * @vtime: scheduler virtual time. ++ * @wsum: scheduler weight sum; active and idle entities contribute to it. ++ * ++ * Each service tree represents a B-WF2Q+ scheduler on its own. Each ++ * ioprio_class has its own independent scheduler, and so its own ++ * bfq_service_tree. All the fields are protected by the queue lock ++ * of the containing bfqd. ++ */ ++struct bfq_service_tree { ++ struct rb_root active; ++ struct rb_root idle; ++ ++ struct bfq_entity *first_idle; ++ struct bfq_entity *last_idle; ++ ++ u64 vtime; ++ unsigned long wsum; ++}; ++ ++/** ++ * struct bfq_sched_data - multi-class scheduler. ++ * @in_service_entity: entity in service. ++ * @next_in_service: head-of-the-line entity in the scheduler. ++ * @service_tree: array of service trees, one per ioprio_class. ++ * ++ * bfq_sched_data is the basic scheduler queue. It supports three ++ * ioprio_classes, and can be used either as a toplevel queue or as ++ * an intermediate queue on a hierarchical setup. ++ * @next_in_service points to the active entity of the sched_data ++ * service trees that will be scheduled next. ++ * ++ * The supported ioprio_classes are the same as in CFQ, in descending ++ * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE. ++ * Requests from higher priority queues are served before all the ++ * requests from lower priority queues; among requests of the same ++ * queue requests are served according to B-WF2Q+. ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_sched_data { ++ struct bfq_entity *in_service_entity; ++ struct bfq_entity *next_in_service; ++ struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES]; ++}; ++ ++/** ++ * struct bfq_weight_counter - counter of the number of all active entities ++ * with a given weight. ++ * @weight: weight of the entities that this counter refers to. ++ * @num_active: number of active entities with this weight. ++ * @weights_node: weights tree member (see bfq_data's @queue_weights_tree ++ * and @group_weights_tree). ++ */ ++struct bfq_weight_counter { ++ short int weight; ++ unsigned int num_active; ++ struct rb_node weights_node; ++}; ++ ++/** ++ * struct bfq_entity - schedulable entity. ++ * @rb_node: service_tree member. ++ * @weight_counter: pointer to the weight counter associated with this entity. ++ * @on_st: flag, true if the entity is on a tree (either the active or ++ * the idle one of its service_tree). ++ * @finish: B-WF2Q+ finish timestamp (aka F_i). ++ * @start: B-WF2Q+ start timestamp (aka S_i). ++ * @tree: tree the entity is enqueued into; %NULL if not on a tree. ++ * @min_start: minimum start time of the (active) subtree rooted at ++ * this entity; used for O(log N) lookups into active trees. ++ * @service: service received during the last round of service. ++ * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight. ++ * @weight: weight of the queue ++ * @parent: parent entity, for hierarchical scheduling. ++ * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the ++ * associated scheduler queue, %NULL on leaf nodes. ++ * @sched_data: the scheduler queue this entity belongs to. ++ * @ioprio: the ioprio in use. ++ * @new_weight: when a weight change is requested, the new weight value. ++ * @orig_weight: original weight, used to implement weight boosting ++ * @new_ioprio: when an ioprio change is requested, the new ioprio value. ++ * @ioprio_class: the ioprio_class in use. ++ * @new_ioprio_class: when an ioprio_class change is requested, the new ++ * ioprio_class value. ++ * @ioprio_changed: flag, true when the user requested a weight, ioprio or ++ * ioprio_class change. ++ * ++ * A bfq_entity is used to represent either a bfq_queue (leaf node in the ++ * cgroup hierarchy) or a bfq_group into the upper level scheduler. Each ++ * entity belongs to the sched_data of the parent group in the cgroup ++ * hierarchy. Non-leaf entities have also their own sched_data, stored ++ * in @my_sched_data. ++ * ++ * Each entity stores independently its priority values; this would ++ * allow different weights on different devices, but this ++ * functionality is not exported to userspace by now. Priorities and ++ * weights are updated lazily, first storing the new values into the ++ * new_* fields, then setting the @ioprio_changed flag. As soon as ++ * there is a transition in the entity state that allows the priority ++ * update to take place the effective and the requested priority ++ * values are synchronized. ++ * ++ * Unless cgroups are used, the weight value is calculated from the ++ * ioprio to export the same interface as CFQ. When dealing with ++ * ``well-behaved'' queues (i.e., queues that do not spend too much ++ * time to consume their budget and have true sequential behavior, and ++ * when there are no external factors breaking anticipation) the ++ * relative weights at each level of the cgroups hierarchy should be ++ * guaranteed. All the fields are protected by the queue lock of the ++ * containing bfqd. ++ */ ++struct bfq_entity { ++ struct rb_node rb_node; ++ struct bfq_weight_counter *weight_counter; ++ ++ int on_st; ++ ++ u64 finish; ++ u64 start; ++ ++ struct rb_root *tree; ++ ++ u64 min_start; ++ ++ unsigned long service, budget; ++ unsigned short weight, new_weight; ++ unsigned short orig_weight; ++ ++ struct bfq_entity *parent; ++ ++ struct bfq_sched_data *my_sched_data; ++ struct bfq_sched_data *sched_data; ++ ++ unsigned short ioprio, new_ioprio; ++ unsigned short ioprio_class, new_ioprio_class; ++ ++ int ioprio_changed; ++}; ++ ++struct bfq_group; ++ ++/** ++ * struct bfq_queue - leaf schedulable entity. ++ * @ref: reference counter. ++ * @bfqd: parent bfq_data. ++ * @new_bfqq: shared bfq_queue if queue is cooperating with ++ * one or more other queues. ++ * @pos_node: request-position tree member (see bfq_data's @rq_pos_tree). ++ * @pos_root: request-position tree root (see bfq_data's @rq_pos_tree). ++ * @sort_list: sorted list of pending requests. ++ * @next_rq: if fifo isn't expired, next request to serve. ++ * @queued: nr of requests queued in @sort_list. ++ * @allocated: currently allocated requests. ++ * @meta_pending: pending metadata requests. ++ * @fifo: fifo list of requests in sort_list. ++ * @entity: entity representing this queue in the scheduler. ++ * @max_budget: maximum budget allowed from the feedback mechanism. ++ * @budget_timeout: budget expiration (in jiffies). ++ * @dispatched: number of requests on the dispatch list or inside driver. ++ * @flags: status flags. ++ * @bfqq_list: node for active/idle bfqq list inside our bfqd. ++ * @burst_list_node: node for the device's burst list. ++ * @seek_samples: number of seeks sampled ++ * @seek_total: sum of the distances of the seeks sampled ++ * @seek_mean: mean seek distance ++ * @last_request_pos: position of the last request enqueued ++ * @requests_within_timer: number of consecutive pairs of request completion ++ * and arrival, such that the queue becomes idle ++ * after the completion, but the next request arrives ++ * within an idle time slice; used only if the queue's ++ * IO_bound has been cleared. ++ * @pid: pid of the process owning the queue, used for logging purposes. ++ * @last_wr_start_finish: start time of the current weight-raising period if ++ * the @bfq-queue is being weight-raised, otherwise ++ * finish time of the last weight-raising period ++ * @wr_cur_max_time: current max raising time for this queue ++ * @soft_rt_next_start: minimum time instant such that, only if a new ++ * request is enqueued after this time instant in an ++ * idle @bfq_queue with no outstanding requests, then ++ * the task associated with the queue it is deemed as ++ * soft real-time (see the comments to the function ++ * bfq_bfqq_softrt_next_start()). ++ * @last_idle_bklogged: time of the last transition of the @bfq_queue from ++ * idle to backlogged ++ * @service_from_backlogged: cumulative service received from the @bfq_queue ++ * since the last transition from idle to ++ * backlogged ++ * ++ * A bfq_queue is a leaf request queue; it can be associated with an io_context ++ * or more, if it is async or shared between cooperating processes. @cgroup ++ * holds a reference to the cgroup, to be sure that it does not disappear while ++ * a bfqq still references it (mostly to avoid races between request issuing and ++ * task migration followed by cgroup destruction). ++ * All the fields are protected by the queue lock of the containing bfqd. ++ */ ++struct bfq_queue { ++ atomic_t ref; ++ struct bfq_data *bfqd; ++ ++ /* fields for cooperating queues handling */ ++ struct bfq_queue *new_bfqq; ++ struct rb_node pos_node; ++ struct rb_root *pos_root; ++ ++ struct rb_root sort_list; ++ struct request *next_rq; ++ int queued[2]; ++ int allocated[2]; ++ int meta_pending; ++ struct list_head fifo; ++ ++ struct bfq_entity entity; ++ ++ unsigned long max_budget; ++ unsigned long budget_timeout; ++ ++ int dispatched; ++ ++ unsigned int flags; ++ ++ struct list_head bfqq_list; ++ ++ struct hlist_node burst_list_node; ++ ++ unsigned int seek_samples; ++ u64 seek_total; ++ sector_t seek_mean; ++ sector_t last_request_pos; ++ ++ unsigned int requests_within_timer; ++ ++ pid_t pid; ++ ++ /* weight-raising fields */ ++ unsigned long wr_cur_max_time; ++ unsigned long soft_rt_next_start; ++ unsigned long last_wr_start_finish; ++ unsigned int wr_coeff; ++ unsigned long last_idle_bklogged; ++ unsigned long service_from_backlogged; ++}; ++ ++/** ++ * struct bfq_ttime - per process thinktime stats. ++ * @ttime_total: total process thinktime ++ * @ttime_samples: number of thinktime samples ++ * @ttime_mean: average process thinktime ++ */ ++struct bfq_ttime { ++ unsigned long last_end_request; ++ ++ unsigned long ttime_total; ++ unsigned long ttime_samples; ++ unsigned long ttime_mean; ++}; ++ ++/** ++ * struct bfq_io_cq - per (request_queue, io_context) structure. ++ * @icq: associated io_cq structure ++ * @bfqq: array of two process queues, the sync and the async ++ * @ttime: associated @bfq_ttime struct ++ */ ++struct bfq_io_cq { ++ struct io_cq icq; /* must be the first member */ ++ struct bfq_queue *bfqq[2]; ++ struct bfq_ttime ttime; ++ int ioprio; ++}; ++ ++enum bfq_device_speed { ++ BFQ_BFQD_FAST, ++ BFQ_BFQD_SLOW, ++}; ++ ++/** ++ * struct bfq_data - per device data structure. ++ * @queue: request queue for the managed device. ++ * @root_group: root bfq_group for the device. ++ * @rq_pos_tree: rbtree sorted by next_request position, used when ++ * determining if two or more queues have interleaving ++ * requests (see bfq_close_cooperator()). ++ * @active_numerous_groups: number of bfq_groups containing more than one ++ * active @bfq_entity. ++ * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by ++ * weight. Used to keep track of whether all @bfq_queues ++ * have the same weight. The tree contains one counter ++ * for each distinct weight associated to some active ++ * and not weight-raised @bfq_queue (see the comments to ++ * the functions bfq_weights_tree_[add|remove] for ++ * further details). ++ * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted ++ * by weight. Used to keep track of whether all ++ * @bfq_groups have the same weight. The tree contains ++ * one counter for each distinct weight associated to ++ * some active @bfq_group (see the comments to the ++ * functions bfq_weights_tree_[add|remove] for further ++ * details). ++ * @busy_queues: number of bfq_queues containing requests (including the ++ * queue in service, even if it is idling). ++ * @busy_in_flight_queues: number of @bfq_queues containing pending or ++ * in-flight requests, plus the @bfq_queue in ++ * service, even if idle but waiting for the ++ * possible arrival of its next sync request. This ++ * field is updated only if the device is rotational, ++ * but used only if the device is also NCQ-capable. ++ * The reason why the field is updated also for non- ++ * NCQ-capable rotational devices is related to the ++ * fact that the value of @hw_tag may be set also ++ * later than when busy_in_flight_queues may need to ++ * be incremented for the first time(s). Taking also ++ * this possibility into account, to avoid unbalanced ++ * increments/decrements, would imply more overhead ++ * than just updating busy_in_flight_queues ++ * regardless of the value of @hw_tag. ++ * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues ++ * (that is, seeky queues that expired ++ * for budget timeout at least once) ++ * containing pending or in-flight ++ * requests, including the in-service ++ * @bfq_queue if constantly seeky. This ++ * field is updated only if the device ++ * is rotational, but used only if the ++ * device is also NCQ-capable (see the ++ * comments to @busy_in_flight_queues). ++ * @wr_busy_queues: number of weight-raised busy @bfq_queues. ++ * @queued: number of queued requests. ++ * @rq_in_driver: number of requests dispatched and waiting for completion. ++ * @sync_flight: number of sync requests in the driver. ++ * @max_rq_in_driver: max number of reqs in driver in the last ++ * @hw_tag_samples completed requests. ++ * @hw_tag_samples: nr of samples used to calculate hw_tag. ++ * @hw_tag: flag set to one if the driver is showing a queueing behavior. ++ * @budgets_assigned: number of budgets assigned. ++ * @idle_slice_timer: timer set when idling for the next sequential request ++ * from the queue in service. ++ * @unplug_work: delayed work to restart dispatching on the request queue. ++ * @in_service_queue: bfq_queue in service. ++ * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue. ++ * @last_position: on-disk position of the last served request. ++ * @last_budget_start: beginning of the last budget. ++ * @last_idling_start: beginning of the last idle slice. ++ * @peak_rate: peak transfer rate observed for a budget. ++ * @peak_rate_samples: number of samples used to calculate @peak_rate. ++ * @bfq_max_budget: maximum budget allotted to a bfq_queue before ++ * rescheduling. ++ * @group_list: list of all the bfq_groups active on the device. ++ * @active_list: list of all the bfq_queues active on the device. ++ * @idle_list: list of all the bfq_queues idle on the device. ++ * @bfq_quantum: max number of requests dispatched per dispatch round. ++ * @bfq_fifo_expire: timeout for async/sync requests; when it expires ++ * requests are served in fifo order. ++ * @bfq_back_penalty: weight of backward seeks wrt forward ones. ++ * @bfq_back_max: maximum allowed backward seek. ++ * @bfq_slice_idle: maximum idling time. ++ * @bfq_user_max_budget: user-configured max budget value ++ * (0 for auto-tuning). ++ * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to ++ * async queues. ++ * @bfq_timeout: timeout for bfq_queues to consume their budget; used to ++ * to prevent seeky queues to impose long latencies to well ++ * behaved ones (this also implies that seeky queues cannot ++ * receive guarantees in the service domain; after a timeout ++ * they are charged for the whole allocated budget, to try ++ * to preserve a behavior reasonably fair among them, but ++ * without service-domain guarantees). ++ * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is ++ * no more granted any weight-raising. ++ * @bfq_failed_cooperations: number of consecutive failed cooperation ++ * chances after which weight-raising is restored ++ * to a queue subject to more than bfq_coop_thresh ++ * queue merges. ++ * @bfq_requests_within_timer: number of consecutive requests that must be ++ * issued within the idle time slice to set ++ * again idling to a queue which was marked as ++ * non-I/O-bound (see the definition of the ++ * IO_bound flag for further details). ++ * @last_ins_in_burst: last time at which a queue entered the current ++ * burst of queues being activated shortly after ++ * each other; for more details about this and the ++ * following parameters related to a burst of ++ * activations, see the comments to the function ++ * @bfq_handle_burst. ++ * @bfq_burst_interval: reference time interval used to decide whether a ++ * queue has been activated shortly after ++ * @last_ins_in_burst. ++ * @burst_size: number of queues in the current burst of queue activations. ++ * @bfq_large_burst_thresh: maximum burst size above which the current ++ * queue-activation burst is deemed as 'large'. ++ * @large_burst: true if a large queue-activation burst is in progress. ++ * @burst_list: head of the burst list (as for the above fields, more details ++ * in the comments to the function bfq_handle_burst). ++ * @low_latency: if set to true, low-latency heuristics are enabled. ++ * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised ++ * queue is multiplied. ++ * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies). ++ * @bfq_wr_rt_max_time: maximum duration for soft real-time processes. ++ * @bfq_wr_min_idle_time: minimum idle period after which weight-raising ++ * may be reactivated for a queue (in jiffies). ++ * @bfq_wr_min_inter_arr_async: minimum period between request arrivals ++ * after which weight-raising may be ++ * reactivated for an already busy queue ++ * (in jiffies). ++ * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue, ++ * sectors per seconds. ++ * @RT_prod: cached value of the product R*T used for computing the maximum ++ * duration of the weight raising automatically. ++ * @device_speed: device-speed class for the low-latency heuristic. ++ * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions. ++ * ++ * All the fields are protected by the @queue lock. ++ */ ++struct bfq_data { ++ struct request_queue *queue; ++ ++ struct bfq_group *root_group; ++ struct rb_root rq_pos_tree; ++ ++#ifdef CONFIG_CGROUP_BFQIO ++ int active_numerous_groups; ++#endif ++ ++ struct rb_root queue_weights_tree; ++ struct rb_root group_weights_tree; ++ ++ int busy_queues; ++ int busy_in_flight_queues; ++ int const_seeky_busy_in_flight_queues; ++ int wr_busy_queues; ++ int queued; ++ int rq_in_driver; ++ int sync_flight; ++ ++ int max_rq_in_driver; ++ int hw_tag_samples; ++ int hw_tag; ++ ++ int budgets_assigned; ++ ++ struct timer_list idle_slice_timer; ++ struct work_struct unplug_work; ++ ++ struct bfq_queue *in_service_queue; ++ struct bfq_io_cq *in_service_bic; ++ ++ sector_t last_position; ++ ++ ktime_t last_budget_start; ++ ktime_t last_idling_start; ++ int peak_rate_samples; ++ u64 peak_rate; ++ unsigned long bfq_max_budget; ++ ++ struct hlist_head group_list; ++ struct list_head active_list; ++ struct list_head idle_list; ++ ++ unsigned int bfq_quantum; ++ unsigned int bfq_fifo_expire[2]; ++ unsigned int bfq_back_penalty; ++ unsigned int bfq_back_max; ++ unsigned int bfq_slice_idle; ++ u64 bfq_class_idle_last_service; ++ ++ unsigned int bfq_user_max_budget; ++ unsigned int bfq_max_budget_async_rq; ++ unsigned int bfq_timeout[2]; ++ ++ unsigned int bfq_coop_thresh; ++ unsigned int bfq_failed_cooperations; ++ unsigned int bfq_requests_within_timer; ++ ++ unsigned long last_ins_in_burst; ++ unsigned long bfq_burst_interval; ++ int burst_size; ++ unsigned long bfq_large_burst_thresh; ++ bool large_burst; ++ struct hlist_head burst_list; ++ ++ bool low_latency; ++ ++ /* parameters of the low_latency heuristics */ ++ unsigned int bfq_wr_coeff; ++ unsigned int bfq_wr_max_time; ++ unsigned int bfq_wr_rt_max_time; ++ unsigned int bfq_wr_min_idle_time; ++ unsigned long bfq_wr_min_inter_arr_async; ++ unsigned int bfq_wr_max_softrt_rate; ++ u64 RT_prod; ++ enum bfq_device_speed device_speed; ++ ++ struct bfq_queue oom_bfqq; ++}; ++ ++enum bfqq_state_flags { ++ BFQ_BFQQ_FLAG_busy = 0, /* has requests or is in service */ ++ BFQ_BFQQ_FLAG_wait_request, /* waiting for a request */ ++ BFQ_BFQQ_FLAG_must_alloc, /* must be allowed rq alloc */ ++ BFQ_BFQQ_FLAG_fifo_expire, /* FIFO checked in this slice */ ++ BFQ_BFQQ_FLAG_idle_window, /* slice idling enabled */ ++ BFQ_BFQQ_FLAG_prio_changed, /* task priority has changed */ ++ BFQ_BFQQ_FLAG_sync, /* synchronous queue */ ++ BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */ ++ BFQ_BFQQ_FLAG_IO_bound, /* ++ * bfqq has timed-out at least once ++ * having consumed at most 2/10 of ++ * its budget ++ */ ++ BFQ_BFQQ_FLAG_in_large_burst, /* ++ * bfqq activated in a large burst, ++ * see comments to bfq_handle_burst. ++ */ ++ BFQ_BFQQ_FLAG_constantly_seeky, /* ++ * bfqq has proved to be slow and ++ * seeky until budget timeout ++ */ ++ BFQ_BFQQ_FLAG_softrt_update, /* ++ * may need softrt-next-start ++ * update ++ */ ++ BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ ++ BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be splitted */ ++}; ++ ++#define BFQ_BFQQ_FNS(name) \ ++static inline void bfq_mark_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static inline void bfq_clear_bfqq_##name(struct bfq_queue *bfqq) \ ++{ \ ++ (bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name); \ ++} \ ++static inline int bfq_bfqq_##name(const struct bfq_queue *bfqq) \ ++{ \ ++ return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0; \ ++} ++ ++BFQ_BFQQ_FNS(busy); ++BFQ_BFQQ_FNS(wait_request); ++BFQ_BFQQ_FNS(must_alloc); ++BFQ_BFQQ_FNS(fifo_expire); ++BFQ_BFQQ_FNS(idle_window); ++BFQ_BFQQ_FNS(prio_changed); ++BFQ_BFQQ_FNS(sync); ++BFQ_BFQQ_FNS(budget_new); ++BFQ_BFQQ_FNS(IO_bound); ++BFQ_BFQQ_FNS(in_large_burst); ++BFQ_BFQQ_FNS(constantly_seeky); ++BFQ_BFQQ_FNS(coop); ++BFQ_BFQQ_FNS(split_coop); ++BFQ_BFQQ_FNS(softrt_update); ++#undef BFQ_BFQQ_FNS ++ ++/* Logging facilities. */ ++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args) ++ ++#define bfq_log(bfqd, fmt, args...) \ ++ blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args) ++ ++/* Expiration reasons. */ ++enum bfqq_expiration { ++ BFQ_BFQQ_TOO_IDLE = 0, /* ++ * queue has been idling for ++ * too long ++ */ ++ BFQ_BFQQ_BUDGET_TIMEOUT, /* budget took too long to be used */ ++ BFQ_BFQQ_BUDGET_EXHAUSTED, /* budget consumed */ ++ BFQ_BFQQ_NO_MORE_REQUESTS, /* the queue has no more requests */ ++}; ++ ++#ifdef CONFIG_CGROUP_BFQIO ++/** ++ * struct bfq_group - per (device, cgroup) data structure. ++ * @entity: schedulable entity to insert into the parent group sched_data. ++ * @sched_data: own sched_data, to contain child entities (they may be ++ * both bfq_queues and bfq_groups). ++ * @group_node: node to be inserted into the bfqio_cgroup->group_data ++ * list of the containing cgroup's bfqio_cgroup. ++ * @bfqd_node: node to be inserted into the @bfqd->group_list list ++ * of the groups active on the same device; used for cleanup. ++ * @bfqd: the bfq_data for the device this group acts upon. ++ * @async_bfqq: array of async queues for all the tasks belonging to ++ * the group, one queue per ioprio value per ioprio_class, ++ * except for the idle class that has only one queue. ++ * @async_idle_bfqq: async queue for the idle class (ioprio is ignored). ++ * @my_entity: pointer to @entity, %NULL for the toplevel group; used ++ * to avoid too many special cases during group creation/ ++ * migration. ++ * @active_entities: number of active entities belonging to the group; ++ * unused for the root group. Used to know whether there ++ * are groups with more than one active @bfq_entity ++ * (see the comments to the function ++ * bfq_bfqq_must_not_expire()). ++ * ++ * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup ++ * there is a set of bfq_groups, each one collecting the lower-level ++ * entities belonging to the group that are acting on the same device. ++ * ++ * Locking works as follows: ++ * o @group_node is protected by the bfqio_cgroup lock, and is accessed ++ * via RCU from its readers. ++ * o @bfqd is protected by the queue lock, RCU is used to access it ++ * from the readers. ++ * o All the other fields are protected by the @bfqd queue lock. ++ */ ++struct bfq_group { ++ struct bfq_entity entity; ++ struct bfq_sched_data sched_data; ++ ++ struct hlist_node group_node; ++ struct hlist_node bfqd_node; ++ ++ void *bfqd; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++ ++ struct bfq_entity *my_entity; ++ ++ int active_entities; ++}; ++ ++/** ++ * struct bfqio_cgroup - bfq cgroup data structure. ++ * @css: subsystem state for bfq in the containing cgroup. ++ * @online: flag marked when the subsystem is inserted. ++ * @weight: cgroup weight. ++ * @ioprio: cgroup ioprio. ++ * @ioprio_class: cgroup ioprio_class. ++ * @lock: spinlock that protects @ioprio, @ioprio_class and @group_data. ++ * @group_data: list containing the bfq_group belonging to this cgroup. ++ * ++ * @group_data is accessed using RCU, with @lock protecting the updates, ++ * @ioprio and @ioprio_class are protected by @lock. ++ */ ++struct bfqio_cgroup { ++ struct cgroup_subsys_state css; ++ bool online; ++ ++ unsigned short weight, ioprio, ioprio_class; ++ ++ spinlock_t lock; ++ struct hlist_head group_data; ++}; ++#else ++struct bfq_group { ++ struct bfq_sched_data sched_data; ++ ++ struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR]; ++ struct bfq_queue *async_idle_bfqq; ++}; ++#endif ++ ++static inline struct bfq_service_tree * ++bfq_entity_service_tree(struct bfq_entity *entity) ++{ ++ struct bfq_sched_data *sched_data = entity->sched_data; ++ unsigned int idx = entity->ioprio_class - 1; ++ ++ BUG_ON(idx >= BFQ_IOPRIO_CLASSES); ++ BUG_ON(sched_data == NULL); ++ ++ return sched_data->service_tree + idx; ++} ++ ++static inline struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, ++ bool is_sync) ++{ ++ return bic->bfqq[is_sync]; ++} ++ ++static inline void bic_set_bfqq(struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq, bool is_sync) ++{ ++ bic->bfqq[is_sync] = bfqq; ++} ++ ++static inline struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic) ++{ ++ return bic->icq.q->elevator->elevator_data; ++} ++ ++/** ++ * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer. ++ * @ptr: a pointer to a bfqd. ++ * @flags: storage for the flags to be saved. ++ * ++ * This function allows bfqg->bfqd to be protected by the ++ * queue lock of the bfqd they reference; the pointer is dereferenced ++ * under RCU, so the storage for bfqd is assured to be safe as long ++ * as the RCU read side critical section does not end. After the ++ * bfqd->queue->queue_lock is taken the pointer is rechecked, to be ++ * sure that no other writer accessed it. If we raced with a writer, ++ * the function returns NULL, with the queue unlocked, otherwise it ++ * returns the dereferenced pointer, with the queue locked. ++ */ ++static inline struct bfq_data *bfq_get_bfqd_locked(void **ptr, ++ unsigned long *flags) ++{ ++ struct bfq_data *bfqd; ++ ++ rcu_read_lock(); ++ bfqd = rcu_dereference(*(struct bfq_data **)ptr); ++ ++ if (bfqd != NULL) { ++ spin_lock_irqsave(bfqd->queue->queue_lock, *flags); ++ if (*ptr == bfqd) ++ goto out; ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); ++ } ++ ++ bfqd = NULL; ++out: ++ rcu_read_unlock(); ++ return bfqd; ++} ++ ++static inline void bfq_put_bfqd_unlock(struct bfq_data *bfqd, ++ unsigned long *flags) ++{ ++ spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags); ++} ++ ++static void bfq_changed_ioprio(struct bfq_io_cq *bic); ++static void bfq_put_queue(struct bfq_queue *bfqq); ++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq); ++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd, ++ struct bfq_group *bfqg, int is_sync, ++ struct bfq_io_cq *bic, gfp_t gfp_mask); ++static void bfq_end_wr_async_queues(struct bfq_data *bfqd, ++ struct bfq_group *bfqg); ++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg); ++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq); ++ ++#endif /* _BFQ_H */ +-- +2.3.0 + diff --git a/kernel/kernel/files/patches/gentoo/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch b/kernel/kernel/files/patches/gentoo/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch new file mode 100644 index 00000000..b2e83e40 --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r7-for-3.19.0.patch @@ -0,0 +1,1222 @@ +From 8308a96c0ba080015eb1c58a1bfbfbf1fee80fd6 Mon Sep 17 00:00:00 2001 +From: Mauro Andreolini +Date: Thu, 18 Dec 2014 21:32:08 +0100 +Subject: [PATCH 3/3] block, bfq: add Early Queue Merge (EQM) to BFQ-v7r7 for + 3.19.0 + +A set of processes may happen to perform interleaved reads, i.e.,requests +whose union would give rise to a sequential read pattern. There are two +typical cases: in the first case, processes read fixed-size chunks of +data at a fixed distance from each other, while in the second case processes +may read variable-size chunks at variable distances. The latter case occurs +for example with QEMU, which splits the I/O generated by the guest into +multiple chunks, and lets these chunks be served by a pool of cooperating +processes, iteratively assigning the next chunk of I/O to the first +available process. CFQ uses actual queue merging for the first type of +rocesses, whereas it uses preemption to get a sequential read pattern out +of the read requests performed by the second type of processes. In the end +it uses two different mechanisms to achieve the same goal: boosting the +throughput with interleaved I/O. + +This patch introduces Early Queue Merge (EQM), a unified mechanism to get a +sequential read pattern with both types of processes. The main idea is +checking newly arrived requests against the next request of the active queue +both in case of actual request insert and in case of request merge. By doing +so, both the types of processes can be handled by just merging their queues. +EQM is then simpler and more compact than the pair of mechanisms used in +CFQ. + +Finally, EQM also preserves the typical low-latency properties of BFQ, by +properly restoring the weight-raising state of a queue when it gets back to +a non-merged state. + +Signed-off-by: Mauro Andreolini +Signed-off-by: Arianna Avanzini +Signed-off-by: Paolo Valente +--- + block/bfq-iosched.c | 751 +++++++++++++++++++++++++++++++++++++--------------- + block/bfq-sched.c | 28 -- + block/bfq.h | 54 +++- + 3 files changed, 581 insertions(+), 252 deletions(-) + +diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c +index 97ee934..328f33c 100644 +--- a/block/bfq-iosched.c ++++ b/block/bfq-iosched.c +@@ -571,6 +571,57 @@ static inline unsigned int bfq_wr_duration(struct bfq_data *bfqd) + return dur; + } + ++static inline unsigned ++bfq_bfqq_cooperations(struct bfq_queue *bfqq) ++{ ++ return bfqq->bic ? bfqq->bic->cooperations : 0; ++} ++ ++static inline void ++bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic) ++{ ++ if (bic->saved_idle_window) ++ bfq_mark_bfqq_idle_window(bfqq); ++ else ++ bfq_clear_bfqq_idle_window(bfqq); ++ if (bic->saved_IO_bound) ++ bfq_mark_bfqq_IO_bound(bfqq); ++ else ++ bfq_clear_bfqq_IO_bound(bfqq); ++ /* Assuming that the flag in_large_burst is already correctly set */ ++ if (bic->wr_time_left && bfqq->bfqd->low_latency && ++ !bfq_bfqq_in_large_burst(bfqq) && ++ bic->cooperations < bfqq->bfqd->bfq_coop_thresh) { ++ /* ++ * Start a weight raising period with the duration given by ++ * the raising_time_left snapshot. ++ */ ++ if (bfq_bfqq_busy(bfqq)) ++ bfqq->bfqd->wr_busy_queues++; ++ bfqq->wr_coeff = bfqq->bfqd->bfq_wr_coeff; ++ bfqq->wr_cur_max_time = bic->wr_time_left; ++ bfqq->last_wr_start_finish = jiffies; ++ bfqq->entity.ioprio_changed = 1; ++ } ++ /* ++ * Clear wr_time_left to prevent bfq_bfqq_save_state() from ++ * getting confused about the queue's need of a weight-raising ++ * period. ++ */ ++ bic->wr_time_left = 0; ++} ++ ++/* Must be called with the queue_lock held. */ ++static int bfqq_process_refs(struct bfq_queue *bfqq) ++{ ++ int process_refs, io_refs; ++ ++ io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; ++ process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; ++ BUG_ON(process_refs < 0); ++ return process_refs; ++} ++ + /* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */ + static inline void bfq_reset_burst_list(struct bfq_data *bfqd, + struct bfq_queue *bfqq) +@@ -815,7 +866,7 @@ static void bfq_add_request(struct request *rq) + bfq_rq_pos_tree_add(bfqd, bfqq); + + if (!bfq_bfqq_busy(bfqq)) { +- bool soft_rt, ++ bool soft_rt, coop_or_in_burst, + idle_for_long_time = time_is_before_jiffies( + bfqq->budget_timeout + + bfqd->bfq_wr_min_idle_time); +@@ -839,11 +890,12 @@ static void bfq_add_request(struct request *rq) + bfqd->last_ins_in_burst = jiffies; + } + ++ coop_or_in_burst = bfq_bfqq_in_large_burst(bfqq) || ++ bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh; + soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 && +- !bfq_bfqq_in_large_burst(bfqq) && ++ !coop_or_in_burst && + time_is_before_jiffies(bfqq->soft_rt_next_start); +- interactive = !bfq_bfqq_in_large_burst(bfqq) && +- idle_for_long_time; ++ interactive = !coop_or_in_burst && idle_for_long_time; + entity->budget = max_t(unsigned long, bfqq->max_budget, + bfq_serv_to_charge(next_rq, bfqq)); + +@@ -862,11 +914,20 @@ static void bfq_add_request(struct request *rq) + if (!bfqd->low_latency) + goto add_bfqq_busy; + ++ if (bfq_bfqq_just_split(bfqq)) ++ goto set_ioprio_changed; ++ + /* +- * If the queue is not being boosted and has been idle +- * for enough time, start a weight-raising period ++ * If the queue: ++ * - is not being boosted, ++ * - has been idle for enough time, ++ * - is not a sync queue or is linked to a bfq_io_cq (it is ++ * shared "for its nature" or it is not shared and its ++ * requests have not been redirected to a shared queue) ++ * start a weight-raising period. + */ +- if (old_wr_coeff == 1 && (interactive || soft_rt)) { ++ if (old_wr_coeff == 1 && (interactive || soft_rt) && ++ (!bfq_bfqq_sync(bfqq) || bfqq->bic != NULL)) { + bfqq->wr_coeff = bfqd->bfq_wr_coeff; + if (interactive) + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); +@@ -880,7 +941,7 @@ static void bfq_add_request(struct request *rq) + } else if (old_wr_coeff > 1) { + if (interactive) + bfqq->wr_cur_max_time = bfq_wr_duration(bfqd); +- else if (bfq_bfqq_in_large_burst(bfqq) || ++ else if (coop_or_in_burst || + (bfqq->wr_cur_max_time == + bfqd->bfq_wr_rt_max_time && + !soft_rt)) { +@@ -899,18 +960,18 @@ static void bfq_add_request(struct request *rq) + /* + * + * The remaining weight-raising time is lower +- * than bfqd->bfq_wr_rt_max_time, which +- * means that the application is enjoying +- * weight raising either because deemed soft- +- * rt in the near past, or because deemed +- * interactive a long ago. In both cases, +- * resetting now the current remaining weight- +- * raising time for the application to the +- * weight-raising duration for soft rt +- * applications would not cause any latency +- * increase for the application (as the new +- * duration would be higher than the remaining +- * time). ++ * than bfqd->bfq_wr_rt_max_time, which means ++ * that the application is enjoying weight ++ * raising either because deemed soft-rt in ++ * the near past, or because deemed interactive ++ * a long ago. ++ * In both cases, resetting now the current ++ * remaining weight-raising time for the ++ * application to the weight-raising duration ++ * for soft rt applications would not cause any ++ * latency increase for the application (as the ++ * new duration would be higher than the ++ * remaining time). + * + * In addition, the application is now meeting + * the requirements for being deemed soft rt. +@@ -945,6 +1006,7 @@ static void bfq_add_request(struct request *rq) + bfqd->bfq_wr_rt_max_time; + } + } ++set_ioprio_changed: + if (old_wr_coeff != bfqq->wr_coeff) + entity->ioprio_changed = 1; + add_bfqq_busy: +@@ -1156,90 +1218,35 @@ static void bfq_end_wr(struct bfq_data *bfqd) + spin_unlock_irq(bfqd->queue->queue_lock); + } + +-static int bfq_allow_merge(struct request_queue *q, struct request *rq, +- struct bio *bio) ++static inline sector_t bfq_io_struct_pos(void *io_struct, bool request) + { +- struct bfq_data *bfqd = q->elevator->elevator_data; +- struct bfq_io_cq *bic; +- struct bfq_queue *bfqq; +- +- /* +- * Disallow merge of a sync bio into an async request. +- */ +- if (bfq_bio_sync(bio) && !rq_is_sync(rq)) +- return 0; +- +- /* +- * Lookup the bfqq that this bio will be queued with. Allow +- * merge only if rq is queued there. +- * Queue lock is held here. +- */ +- bic = bfq_bic_lookup(bfqd, current->io_context); +- if (bic == NULL) +- return 0; +- +- bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); +- return bfqq == RQ_BFQQ(rq); +-} +- +-static void __bfq_set_in_service_queue(struct bfq_data *bfqd, +- struct bfq_queue *bfqq) +-{ +- if (bfqq != NULL) { +- bfq_mark_bfqq_must_alloc(bfqq); +- bfq_mark_bfqq_budget_new(bfqq); +- bfq_clear_bfqq_fifo_expire(bfqq); +- +- bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; +- +- bfq_log_bfqq(bfqd, bfqq, +- "set_in_service_queue, cur-budget = %lu", +- bfqq->entity.budget); +- } +- +- bfqd->in_service_queue = bfqq; +-} +- +-/* +- * Get and set a new queue for service. +- */ +-static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd, +- struct bfq_queue *bfqq) +-{ +- if (!bfqq) +- bfqq = bfq_get_next_queue(bfqd); ++ if (request) ++ return blk_rq_pos(io_struct); + else +- bfq_get_next_queue_forced(bfqd, bfqq); +- +- __bfq_set_in_service_queue(bfqd, bfqq); +- return bfqq; ++ return ((struct bio *)io_struct)->bi_iter.bi_sector; + } + +-static inline sector_t bfq_dist_from_last(struct bfq_data *bfqd, +- struct request *rq) ++static inline sector_t bfq_dist_from(sector_t pos1, ++ sector_t pos2) + { +- if (blk_rq_pos(rq) >= bfqd->last_position) +- return blk_rq_pos(rq) - bfqd->last_position; ++ if (pos1 >= pos2) ++ return pos1 - pos2; + else +- return bfqd->last_position - blk_rq_pos(rq); ++ return pos2 - pos1; + } + +-/* +- * Return true if bfqq has no request pending and rq is close enough to +- * bfqd->last_position, or if rq is closer to bfqd->last_position than +- * bfqq->next_rq +- */ +-static inline int bfq_rq_close(struct bfq_data *bfqd, struct request *rq) ++static inline int bfq_rq_close_to_sector(void *io_struct, bool request, ++ sector_t sector) + { +- return bfq_dist_from_last(bfqd, rq) <= BFQQ_SEEK_THR; ++ return bfq_dist_from(bfq_io_struct_pos(io_struct, request), sector) <= ++ BFQQ_SEEK_THR; + } + +-static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) ++static struct bfq_queue *bfqq_close(struct bfq_data *bfqd, sector_t sector) + { + struct rb_root *root = &bfqd->rq_pos_tree; + struct rb_node *parent, *node; + struct bfq_queue *__bfqq; +- sector_t sector = bfqd->last_position; + + if (RB_EMPTY_ROOT(root)) + return NULL; +@@ -1258,7 +1265,7 @@ static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) + * next_request position). + */ + __bfqq = rb_entry(parent, struct bfq_queue, pos_node); +- if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) + return __bfqq; + + if (blk_rq_pos(__bfqq->next_rq) < sector) +@@ -1269,7 +1276,7 @@ static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) + return NULL; + + __bfqq = rb_entry(node, struct bfq_queue, pos_node); +- if (bfq_rq_close(bfqd, __bfqq->next_rq)) ++ if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector)) + return __bfqq; + + return NULL; +@@ -1278,14 +1285,12 @@ static struct bfq_queue *bfqq_close(struct bfq_data *bfqd) + /* + * bfqd - obvious + * cur_bfqq - passed in so that we don't decide that the current queue +- * is closely cooperating with itself. +- * +- * We are assuming that cur_bfqq has dispatched at least one request, +- * and that bfqd->last_position reflects a position on the disk associated +- * with the I/O issued by cur_bfqq. ++ * is closely cooperating with itself ++ * sector - used as a reference point to search for a close queue + */ + static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, +- struct bfq_queue *cur_bfqq) ++ struct bfq_queue *cur_bfqq, ++ sector_t sector) + { + struct bfq_queue *bfqq; + +@@ -1305,7 +1310,7 @@ static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, + * working closely on the same area of the disk. In that case, + * we can group them together and don't waste time idling. + */ +- bfqq = bfqq_close(bfqd); ++ bfqq = bfqq_close(bfqd, sector); + if (bfqq == NULL || bfqq == cur_bfqq) + return NULL; + +@@ -1332,6 +1337,315 @@ static struct bfq_queue *bfq_close_cooperator(struct bfq_data *bfqd, + return bfqq; + } + ++static struct bfq_queue * ++bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ int process_refs, new_process_refs; ++ struct bfq_queue *__bfqq; ++ ++ /* ++ * If there are no process references on the new_bfqq, then it is ++ * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain ++ * may have dropped their last reference (not just their last process ++ * reference). ++ */ ++ if (!bfqq_process_refs(new_bfqq)) ++ return NULL; ++ ++ /* Avoid a circular list and skip interim queue merges. */ ++ while ((__bfqq = new_bfqq->new_bfqq)) { ++ if (__bfqq == bfqq) ++ return NULL; ++ new_bfqq = __bfqq; ++ } ++ ++ process_refs = bfqq_process_refs(bfqq); ++ new_process_refs = bfqq_process_refs(new_bfqq); ++ /* ++ * If the process for the bfqq has gone away, there is no ++ * sense in merging the queues. ++ */ ++ if (process_refs == 0 || new_process_refs == 0) ++ return NULL; ++ ++ bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", ++ new_bfqq->pid); ++ ++ /* ++ * Merging is just a redirection: the requests of the process ++ * owning one of the two queues are redirected to the other queue. ++ * The latter queue, in its turn, is set as shared if this is the ++ * first time that the requests of some process are redirected to ++ * it. ++ * ++ * We redirect bfqq to new_bfqq and not the opposite, because we ++ * are in the context of the process owning bfqq, hence we have ++ * the io_cq of this process. So we can immediately configure this ++ * io_cq to redirect the requests of the process to new_bfqq. ++ * ++ * NOTE, even if new_bfqq coincides with the in-service queue, the ++ * io_cq of new_bfqq is not available, because, if the in-service ++ * queue is shared, bfqd->in_service_bic may not point to the ++ * io_cq of the in-service queue. ++ * Redirecting the requests of the process owning bfqq to the ++ * currently in-service queue is in any case the best option, as ++ * we feed the in-service queue with new requests close to the ++ * last request served and, by doing so, hopefully increase the ++ * throughput. ++ */ ++ bfqq->new_bfqq = new_bfqq; ++ atomic_add(process_refs, &new_bfqq->ref); ++ return new_bfqq; ++} ++ ++/* ++ * Attempt to schedule a merge of bfqq with the currently in-service queue ++ * or with a close queue among the scheduled queues. ++ * Return NULL if no merge was scheduled, a pointer to the shared bfq_queue ++ * structure otherwise. ++ * ++ * The OOM queue is not allowed to participate to cooperation: in fact, since ++ * the requests temporarily redirected to the OOM queue could be redirected ++ * again to dedicated queues at any time, the state needed to correctly ++ * handle merging with the OOM queue would be quite complex and expensive ++ * to maintain. Besides, in such a critical condition as an out of memory, ++ * the benefits of queue merging may be little relevant, or even negligible. ++ */ ++static struct bfq_queue * ++bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq, ++ void *io_struct, bool request) ++{ ++ struct bfq_queue *in_service_bfqq, *new_bfqq; ++ ++ if (bfqq->new_bfqq) ++ return bfqq->new_bfqq; ++ ++ if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq)) ++ return NULL; ++ ++ in_service_bfqq = bfqd->in_service_queue; ++ ++ if (in_service_bfqq == NULL || in_service_bfqq == bfqq || ++ !bfqd->in_service_bic || ++ unlikely(in_service_bfqq == &bfqd->oom_bfqq)) ++ goto check_scheduled; ++ ++ if (bfq_class_idle(in_service_bfqq) || bfq_class_idle(bfqq)) ++ goto check_scheduled; ++ ++ if (bfq_class_rt(in_service_bfqq) != bfq_class_rt(bfqq)) ++ goto check_scheduled; ++ ++ if (in_service_bfqq->entity.parent != bfqq->entity.parent) ++ goto check_scheduled; ++ ++ if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) && ++ bfq_bfqq_sync(in_service_bfqq) && bfq_bfqq_sync(bfqq)) { ++ new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq); ++ if (new_bfqq != NULL) ++ return new_bfqq; /* Merge with in-service queue */ ++ } ++ ++ /* ++ * Check whether there is a cooperator among currently scheduled ++ * queues. The only thing we need is that the bio/request is not ++ * NULL, as we need it to establish whether a cooperator exists. ++ */ ++check_scheduled: ++ new_bfqq = bfq_close_cooperator(bfqd, bfqq, ++ bfq_io_struct_pos(io_struct, request)); ++ if (new_bfqq && likely(new_bfqq != &bfqd->oom_bfqq)) ++ return bfq_setup_merge(bfqq, new_bfqq); ++ ++ return NULL; ++} ++ ++static inline void ++bfq_bfqq_save_state(struct bfq_queue *bfqq) ++{ ++ /* ++ * If bfqq->bic == NULL, the queue is already shared or its requests ++ * have already been redirected to a shared queue; both idle window ++ * and weight raising state have already been saved. Do nothing. ++ */ ++ if (bfqq->bic == NULL) ++ return; ++ if (bfqq->bic->wr_time_left) ++ /* ++ * This is the queue of a just-started process, and would ++ * deserve weight raising: we set wr_time_left to the full ++ * weight-raising duration to trigger weight-raising when ++ * and if the queue is split and the first request of the ++ * queue is enqueued. ++ */ ++ bfqq->bic->wr_time_left = bfq_wr_duration(bfqq->bfqd); ++ else if (bfqq->wr_coeff > 1) { ++ unsigned long wr_duration = ++ jiffies - bfqq->last_wr_start_finish; ++ /* ++ * It may happen that a queue's weight raising period lasts ++ * longer than its wr_cur_max_time, as weight raising is ++ * handled only when a request is enqueued or dispatched (it ++ * does not use any timer). If the weight raising period is ++ * about to end, don't save it. ++ */ ++ if (bfqq->wr_cur_max_time <= wr_duration) ++ bfqq->bic->wr_time_left = 0; ++ else ++ bfqq->bic->wr_time_left = ++ bfqq->wr_cur_max_time - wr_duration; ++ /* ++ * The bfq_queue is becoming shared or the requests of the ++ * process owning the queue are being redirected to a shared ++ * queue. Stop the weight raising period of the queue, as in ++ * both cases it should not be owned by an interactive or ++ * soft real-time application. ++ */ ++ bfq_bfqq_end_wr(bfqq); ++ } else ++ bfqq->bic->wr_time_left = 0; ++ bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq); ++ bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq); ++ bfqq->bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq); ++ bfqq->bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node); ++ bfqq->bic->cooperations++; ++ bfqq->bic->failed_cooperations = 0; ++} ++ ++static inline void ++bfq_get_bic_reference(struct bfq_queue *bfqq) ++{ ++ /* ++ * If bfqq->bic has a non-NULL value, the bic to which it belongs ++ * is about to begin using a shared bfq_queue. ++ */ ++ if (bfqq->bic) ++ atomic_long_inc(&bfqq->bic->icq.ioc->refcount); ++} ++ ++static void ++bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, ++ struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) ++{ ++ bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", ++ (long unsigned)new_bfqq->pid); ++ /* Save weight raising and idle window of the merged queues */ ++ bfq_bfqq_save_state(bfqq); ++ bfq_bfqq_save_state(new_bfqq); ++ if (bfq_bfqq_IO_bound(bfqq)) ++ bfq_mark_bfqq_IO_bound(new_bfqq); ++ bfq_clear_bfqq_IO_bound(bfqq); ++ /* ++ * Grab a reference to the bic, to prevent it from being destroyed ++ * before being possibly touched by a bfq_split_bfqq(). ++ */ ++ bfq_get_bic_reference(bfqq); ++ bfq_get_bic_reference(new_bfqq); ++ /* ++ * Merge queues (that is, let bic redirect its requests to new_bfqq) ++ */ ++ bic_set_bfqq(bic, new_bfqq, 1); ++ bfq_mark_bfqq_coop(new_bfqq); ++ /* ++ * new_bfqq now belongs to at least two bics (it is a shared queue): ++ * set new_bfqq->bic to NULL. bfqq either: ++ * - does not belong to any bic any more, and hence bfqq->bic must ++ * be set to NULL, or ++ * - is a queue whose owning bics have already been redirected to a ++ * different queue, hence the queue is destined to not belong to ++ * any bic soon and bfqq->bic is already NULL (therefore the next ++ * assignment causes no harm). ++ */ ++ new_bfqq->bic = NULL; ++ bfqq->bic = NULL; ++ bfq_put_queue(bfqq); ++} ++ ++static inline void bfq_bfqq_increase_failed_cooperations(struct bfq_queue *bfqq) ++{ ++ struct bfq_io_cq *bic = bfqq->bic; ++ struct bfq_data *bfqd = bfqq->bfqd; ++ ++ if (bic && bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh) { ++ bic->failed_cooperations++; ++ if (bic->failed_cooperations >= bfqd->bfq_failed_cooperations) ++ bic->cooperations = 0; ++ } ++} ++ ++static int bfq_allow_merge(struct request_queue *q, struct request *rq, ++ struct bio *bio) ++{ ++ struct bfq_data *bfqd = q->elevator->elevator_data; ++ struct bfq_io_cq *bic; ++ struct bfq_queue *bfqq, *new_bfqq; ++ ++ /* ++ * Disallow merge of a sync bio into an async request. ++ */ ++ if (bfq_bio_sync(bio) && !rq_is_sync(rq)) ++ return 0; ++ ++ /* ++ * Lookup the bfqq that this bio will be queued with. Allow ++ * merge only if rq is queued there. ++ * Queue lock is held here. ++ */ ++ bic = bfq_bic_lookup(bfqd, current->io_context); ++ if (bic == NULL) ++ return 0; ++ ++ bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio)); ++ /* ++ * We take advantage of this function to perform an early merge ++ * of the queues of possible cooperating processes. ++ */ ++ if (bfqq != NULL) { ++ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false); ++ if (new_bfqq != NULL) { ++ bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq); ++ /* ++ * If we get here, the bio will be queued in the ++ * shared queue, i.e., new_bfqq, so use new_bfqq ++ * to decide whether bio and rq can be merged. ++ */ ++ bfqq = new_bfqq; ++ } else ++ bfq_bfqq_increase_failed_cooperations(bfqq); ++ } ++ ++ return bfqq == RQ_BFQQ(rq); ++} ++ ++static void __bfq_set_in_service_queue(struct bfq_data *bfqd, ++ struct bfq_queue *bfqq) ++{ ++ if (bfqq != NULL) { ++ bfq_mark_bfqq_must_alloc(bfqq); ++ bfq_mark_bfqq_budget_new(bfqq); ++ bfq_clear_bfqq_fifo_expire(bfqq); ++ ++ bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8; ++ ++ bfq_log_bfqq(bfqd, bfqq, ++ "set_in_service_queue, cur-budget = %lu", ++ bfqq->entity.budget); ++ } ++ ++ bfqd->in_service_queue = bfqq; ++} ++ ++/* ++ * Get and set a new queue for service. ++ */ ++static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd) ++{ ++ struct bfq_queue *bfqq = bfq_get_next_queue(bfqd); ++ ++ __bfq_set_in_service_queue(bfqd, bfqq); ++ return bfqq; ++} ++ + /* + * If enough samples have been computed, return the current max budget + * stored in bfqd, which is dynamically updated according to the +@@ -1475,61 +1789,6 @@ static struct request *bfq_check_fifo(struct bfq_queue *bfqq) + return rq; + } + +-/* Must be called with the queue_lock held. */ +-static int bfqq_process_refs(struct bfq_queue *bfqq) +-{ +- int process_refs, io_refs; +- +- io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE]; +- process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st; +- BUG_ON(process_refs < 0); +- return process_refs; +-} +- +-static void bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq) +-{ +- int process_refs, new_process_refs; +- struct bfq_queue *__bfqq; +- +- /* +- * If there are no process references on the new_bfqq, then it is +- * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain +- * may have dropped their last reference (not just their last process +- * reference). +- */ +- if (!bfqq_process_refs(new_bfqq)) +- return; +- +- /* Avoid a circular list and skip interim queue merges. */ +- while ((__bfqq = new_bfqq->new_bfqq)) { +- if (__bfqq == bfqq) +- return; +- new_bfqq = __bfqq; +- } +- +- process_refs = bfqq_process_refs(bfqq); +- new_process_refs = bfqq_process_refs(new_bfqq); +- /* +- * If the process for the bfqq has gone away, there is no +- * sense in merging the queues. +- */ +- if (process_refs == 0 || new_process_refs == 0) +- return; +- +- /* +- * Merge in the direction of the lesser amount of work. +- */ +- if (new_process_refs >= process_refs) { +- bfqq->new_bfqq = new_bfqq; +- atomic_add(process_refs, &new_bfqq->ref); +- } else { +- new_bfqq->new_bfqq = bfqq; +- atomic_add(new_process_refs, &bfqq->ref); +- } +- bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d", +- new_bfqq->pid); +-} +- + static inline unsigned long bfq_bfqq_budget_left(struct bfq_queue *bfqq) + { + struct bfq_entity *entity = &bfqq->entity; +@@ -2263,7 +2522,7 @@ static inline bool bfq_bfqq_must_idle(struct bfq_queue *bfqq) + */ + static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + { +- struct bfq_queue *bfqq, *new_bfqq = NULL; ++ struct bfq_queue *bfqq; + struct request *next_rq; + enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT; + +@@ -2273,17 +2532,6 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + + bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue"); + +- /* +- * If another queue has a request waiting within our mean seek +- * distance, let it run. The expire code will check for close +- * cooperators and put the close queue at the front of the +- * service tree. If possible, merge the expiring queue with the +- * new bfqq. +- */ +- new_bfqq = bfq_close_cooperator(bfqd, bfqq); +- if (new_bfqq != NULL && bfqq->new_bfqq == NULL) +- bfq_setup_merge(bfqq, new_bfqq); +- + if (bfq_may_expire_for_budg_timeout(bfqq) && + !timer_pending(&bfqd->idle_slice_timer) && + !bfq_bfqq_must_idle(bfqq)) +@@ -2322,10 +2570,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + bfq_clear_bfqq_wait_request(bfqq); + del_timer(&bfqd->idle_slice_timer); + } +- if (new_bfqq == NULL) +- goto keep_queue; +- else +- goto expire; ++ goto keep_queue; + } + } + +@@ -2334,40 +2579,30 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) + * in flight (possibly waiting for a completion) or is idling for a + * new request, then keep it. + */ +- if (new_bfqq == NULL && (timer_pending(&bfqd->idle_slice_timer) || +- (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq)))) { ++ if (timer_pending(&bfqd->idle_slice_timer) || ++ (bfqq->dispatched != 0 && bfq_bfqq_must_not_expire(bfqq))) { + bfqq = NULL; + goto keep_queue; +- } else if (new_bfqq != NULL && timer_pending(&bfqd->idle_slice_timer)) { +- /* +- * Expiring the queue because there is a close cooperator, +- * cancel timer. +- */ +- bfq_clear_bfqq_wait_request(bfqq); +- del_timer(&bfqd->idle_slice_timer); + } + + reason = BFQ_BFQQ_NO_MORE_REQUESTS; + expire: + bfq_bfqq_expire(bfqd, bfqq, 0, reason); + new_queue: +- bfqq = bfq_set_in_service_queue(bfqd, new_bfqq); ++ bfqq = bfq_set_in_service_queue(bfqd); + bfq_log(bfqd, "select_queue: new queue %d returned", + bfqq != NULL ? bfqq->pid : 0); + keep_queue: + return bfqq; + } + +-static void bfq_update_wr_data(struct bfq_data *bfqd, +- struct bfq_queue *bfqq) ++static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq) + { +- if (bfqq->wr_coeff > 1) { /* queue is being boosted */ +- struct bfq_entity *entity = &bfqq->entity; +- ++ struct bfq_entity *entity = &bfqq->entity; ++ if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */ + bfq_log_bfqq(bfqd, bfqq, + "raising period dur %u/%u msec, old coeff %u, w %d(%d)", +- jiffies_to_msecs(jiffies - +- bfqq->last_wr_start_finish), ++ jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish), + jiffies_to_msecs(bfqq->wr_cur_max_time), + bfqq->wr_coeff, + bfqq->entity.weight, bfqq->entity.orig_weight); +@@ -2376,12 +2611,16 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, + entity->orig_weight * bfqq->wr_coeff); + if (entity->ioprio_changed) + bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change"); ++ + /* + * If the queue was activated in a burst, or + * too much time has elapsed from the beginning +- * of this weight-raising, then end weight raising. ++ * of this weight-raising period, or the queue has ++ * exceeded the acceptable number of cooperations, ++ * then end weight raising. + */ + if (bfq_bfqq_in_large_burst(bfqq) || ++ bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh || + time_is_before_jiffies(bfqq->last_wr_start_finish + + bfqq->wr_cur_max_time)) { + bfqq->last_wr_start_finish = jiffies; +@@ -2390,11 +2629,13 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, + bfqq->last_wr_start_finish, + jiffies_to_msecs(bfqq->wr_cur_max_time)); + bfq_bfqq_end_wr(bfqq); +- __bfq_entity_update_weight_prio( +- bfq_entity_service_tree(entity), +- entity); + } + } ++ /* Update weight both if it must be raised and if it must be lowered */ ++ if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1)) ++ __bfq_entity_update_weight_prio( ++ bfq_entity_service_tree(entity), ++ entity); + } + + /* +@@ -2642,6 +2883,25 @@ static inline void bfq_init_icq(struct io_cq *icq) + struct bfq_io_cq *bic = icq_to_bic(icq); + + bic->ttime.last_end_request = jiffies; ++ /* ++ * A newly created bic indicates that the process has just ++ * started doing I/O, and is probably mapping into memory its ++ * executable and libraries: it definitely needs weight raising. ++ * There is however the possibility that the process performs, ++ * for a while, I/O close to some other process. EQM intercepts ++ * this behavior and may merge the queue corresponding to the ++ * process with some other queue, BEFORE the weight of the queue ++ * is raised. Merged queues are not weight-raised (they are assumed ++ * to belong to processes that benefit only from high throughput). ++ * If the merge is basically the consequence of an accident, then ++ * the queue will be split soon and will get back its old weight. ++ * It is then important to write down somewhere that this queue ++ * does need weight raising, even if it did not make it to get its ++ * weight raised before being merged. To this purpose, we overload ++ * the field raising_time_left and assign 1 to it, to mark the queue ++ * as needing weight raising. ++ */ ++ bic->wr_time_left = 1; + } + + static void bfq_exit_icq(struct io_cq *icq) +@@ -2655,6 +2915,13 @@ static void bfq_exit_icq(struct io_cq *icq) + } + + if (bic->bfqq[BLK_RW_SYNC]) { ++ /* ++ * If the bic is using a shared queue, put the reference ++ * taken on the io_context when the bic started using a ++ * shared bfq_queue. ++ */ ++ if (bfq_bfqq_coop(bic->bfqq[BLK_RW_SYNC])) ++ put_io_context(icq->ioc); + bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]); + bic->bfqq[BLK_RW_SYNC] = NULL; + } +@@ -2950,6 +3217,10 @@ static void bfq_update_idle_window(struct bfq_data *bfqd, + if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq)) + return; + ++ /* Idle window just restored, statistics are meaningless. */ ++ if (bfq_bfqq_just_split(bfqq)) ++ return; ++ + enable_idle = bfq_bfqq_idle_window(bfqq); + + if (atomic_read(&bic->icq.ioc->active_ref) == 0 || +@@ -2997,6 +3268,7 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, + if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 || + !BFQQ_SEEKY(bfqq)) + bfq_update_idle_window(bfqd, bfqq, bic); ++ bfq_clear_bfqq_just_split(bfqq); + + bfq_log_bfqq(bfqd, bfqq, + "rq_enqueued: idle_window=%d (seeky %d, mean %llu)", +@@ -3057,13 +3329,49 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq, + static void bfq_insert_request(struct request_queue *q, struct request *rq) + { + struct bfq_data *bfqd = q->elevator->elevator_data; +- struct bfq_queue *bfqq = RQ_BFQQ(rq); ++ struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq; + + assert_spin_locked(bfqd->queue->queue_lock); ++ ++ /* ++ * An unplug may trigger a requeue of a request from the device ++ * driver: make sure we are in process context while trying to ++ * merge two bfq_queues. ++ */ ++ if (!in_interrupt()) { ++ new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true); ++ if (new_bfqq != NULL) { ++ if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq) ++ new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1); ++ /* ++ * Release the request's reference to the old bfqq ++ * and make sure one is taken to the shared queue. ++ */ ++ new_bfqq->allocated[rq_data_dir(rq)]++; ++ bfqq->allocated[rq_data_dir(rq)]--; ++ atomic_inc(&new_bfqq->ref); ++ bfq_put_queue(bfqq); ++ if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq) ++ bfq_merge_bfqqs(bfqd, RQ_BIC(rq), ++ bfqq, new_bfqq); ++ rq->elv.priv[1] = new_bfqq; ++ bfqq = new_bfqq; ++ } else ++ bfq_bfqq_increase_failed_cooperations(bfqq); ++ } ++ + bfq_init_prio_data(bfqq, RQ_BIC(rq)); + + bfq_add_request(rq); + ++ /* ++ * Here a newly-created bfq_queue has already started a weight-raising ++ * period: clear raising_time_left to prevent bfq_bfqq_save_state() ++ * from assigning it a full weight-raising period. See the detailed ++ * comments about this field in bfq_init_icq(). ++ */ ++ if (bfqq->bic != NULL) ++ bfqq->bic->wr_time_left = 0; + rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)]; + list_add_tail(&rq->queuelist, &bfqq->fifo); + +@@ -3228,18 +3536,6 @@ static void bfq_put_request(struct request *rq) + } + } + +-static struct bfq_queue * +-bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic, +- struct bfq_queue *bfqq) +-{ +- bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu", +- (long unsigned)bfqq->new_bfqq->pid); +- bic_set_bfqq(bic, bfqq->new_bfqq, 1); +- bfq_mark_bfqq_coop(bfqq->new_bfqq); +- bfq_put_queue(bfqq); +- return bic_to_bfqq(bic, 1); +-} +- + /* + * Returns NULL if a new bfqq should be allocated, or the old bfqq if this + * was the last process referring to said bfqq. +@@ -3248,6 +3544,9 @@ static struct bfq_queue * + bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq) + { + bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue"); ++ ++ put_io_context(bic->icq.ioc); ++ + if (bfqq_process_refs(bfqq) == 1) { + bfqq->pid = current->pid; + bfq_clear_bfqq_coop(bfqq); +@@ -3276,6 +3575,7 @@ static int bfq_set_request(struct request_queue *q, struct request *rq, + struct bfq_queue *bfqq; + struct bfq_group *bfqg; + unsigned long flags; ++ bool split = false; + + might_sleep_if(gfp_mask & __GFP_WAIT); + +@@ -3293,25 +3593,26 @@ new_queue: + if (bfqq == NULL || bfqq == &bfqd->oom_bfqq) { + bfqq = bfq_get_queue(bfqd, bfqg, is_sync, bic, gfp_mask); + bic_set_bfqq(bic, bfqq, is_sync); ++ if (split && is_sync) { ++ if ((bic->was_in_burst_list && bfqd->large_burst) || ++ bic->saved_in_large_burst) ++ bfq_mark_bfqq_in_large_burst(bfqq); ++ else { ++ bfq_clear_bfqq_in_large_burst(bfqq); ++ if (bic->was_in_burst_list) ++ hlist_add_head(&bfqq->burst_list_node, ++ &bfqd->burst_list); ++ } ++ } + } else { +- /* +- * If the queue was seeky for too long, break it apart. +- */ ++ /* If the queue was seeky for too long, break it apart. */ + if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) { + bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq"); + bfqq = bfq_split_bfqq(bic, bfqq); ++ split = true; + if (!bfqq) + goto new_queue; + } +- +- /* +- * Check to see if this queue is scheduled to merge with +- * another closely cooperating queue. The merging of queues +- * happens here as it must be done in process context. +- * The reference on new_bfqq was taken in merge_bfqqs. +- */ +- if (bfqq->new_bfqq != NULL) +- bfqq = bfq_merge_bfqqs(bfqd, bic, bfqq); + } + + bfqq->allocated[rw]++; +@@ -3322,6 +3623,26 @@ new_queue: + rq->elv.priv[0] = bic; + rq->elv.priv[1] = bfqq; + ++ /* ++ * If a bfq_queue has only one process reference, it is owned ++ * by only one bfq_io_cq: we can set the bic field of the ++ * bfq_queue to the address of that structure. Also, if the ++ * queue has just been split, mark a flag so that the ++ * information is available to the other scheduler hooks. ++ */ ++ if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) { ++ bfqq->bic = bic; ++ if (split) { ++ bfq_mark_bfqq_just_split(bfqq); ++ /* ++ * If the queue has just been split from a shared ++ * queue, restore the idle window and the possible ++ * weight raising period. ++ */ ++ bfq_bfqq_resume_state(bfqq, bic); ++ } ++ } ++ + spin_unlock_irqrestore(q->queue_lock, flags); + + return 0; +diff --git a/block/bfq-sched.c b/block/bfq-sched.c +index 2931563..6764a7e 100644 +--- a/block/bfq-sched.c ++++ b/block/bfq-sched.c +@@ -1091,34 +1091,6 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd) + return bfqq; + } + +-/* +- * Forced extraction of the given queue. +- */ +-static void bfq_get_next_queue_forced(struct bfq_data *bfqd, +- struct bfq_queue *bfqq) +-{ +- struct bfq_entity *entity; +- struct bfq_sched_data *sd; +- +- BUG_ON(bfqd->in_service_queue != NULL); +- +- entity = &bfqq->entity; +- /* +- * Bubble up extraction/update from the leaf to the root. +- */ +- for_each_entity(entity) { +- sd = entity->sched_data; +- bfq_update_budget(entity); +- bfq_update_vtime(bfq_entity_service_tree(entity)); +- bfq_active_extract(bfq_entity_service_tree(entity), entity); +- sd->in_service_entity = entity; +- sd->next_in_service = NULL; +- entity->service = 0; +- } +- +- return; +-} +- + static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd) + { + if (bfqd->in_service_bic != NULL) { +diff --git a/block/bfq.h b/block/bfq.h +index 3c5d85e..5ced336 100644 +--- a/block/bfq.h ++++ b/block/bfq.h +@@ -218,18 +218,21 @@ struct bfq_group; + * idle @bfq_queue with no outstanding requests, then + * the task associated with the queue it is deemed as + * soft real-time (see the comments to the function +- * bfq_bfqq_softrt_next_start()). ++ * bfq_bfqq_softrt_next_start()) + * @last_idle_bklogged: time of the last transition of the @bfq_queue from + * idle to backlogged + * @service_from_backlogged: cumulative service received from the @bfq_queue + * since the last transition from idle to + * backlogged ++ * @bic: pointer to the bfq_io_cq owning the bfq_queue, set to %NULL if the ++ * queue is shared + * +- * A bfq_queue is a leaf request queue; it can be associated with an io_context +- * or more, if it is async or shared between cooperating processes. @cgroup +- * holds a reference to the cgroup, to be sure that it does not disappear while +- * a bfqq still references it (mostly to avoid races between request issuing and +- * task migration followed by cgroup destruction). ++ * A bfq_queue is a leaf request queue; it can be associated with an ++ * io_context or more, if it is async or shared between cooperating ++ * processes. @cgroup holds a reference to the cgroup, to be sure that it ++ * does not disappear while a bfqq still references it (mostly to avoid ++ * races between request issuing and task migration followed by cgroup ++ * destruction). + * All the fields are protected by the queue lock of the containing bfqd. + */ + struct bfq_queue { +@@ -269,6 +272,7 @@ struct bfq_queue { + unsigned int requests_within_timer; + + pid_t pid; ++ struct bfq_io_cq *bic; + + /* weight-raising fields */ + unsigned long wr_cur_max_time; +@@ -298,12 +302,42 @@ struct bfq_ttime { + * @icq: associated io_cq structure + * @bfqq: array of two process queues, the sync and the async + * @ttime: associated @bfq_ttime struct ++ * @wr_time_left: snapshot of the time left before weight raising ends ++ * for the sync queue associated to this process; this ++ * snapshot is taken to remember this value while the weight ++ * raising is suspended because the queue is merged with a ++ * shared queue, and is used to set @raising_cur_max_time ++ * when the queue is split from the shared queue and its ++ * weight is raised again ++ * @saved_idle_window: same purpose as the previous field for the idle ++ * window ++ * @saved_IO_bound: same purpose as the previous two fields for the I/O ++ * bound classification of a queue ++ * @saved_in_large_burst: same purpose as the previous fields for the ++ * value of the field keeping the queue's belonging ++ * to a large burst ++ * @was_in_burst_list: true if the queue belonged to a burst list ++ * before its merge with another cooperating queue ++ * @cooperations: counter of consecutive successful queue merges underwent ++ * by any of the process' @bfq_queues ++ * @failed_cooperations: counter of consecutive failed queue merges of any ++ * of the process' @bfq_queues + */ + struct bfq_io_cq { + struct io_cq icq; /* must be the first member */ + struct bfq_queue *bfqq[2]; + struct bfq_ttime ttime; + int ioprio; ++ ++ unsigned int wr_time_left; ++ bool saved_idle_window; ++ bool saved_IO_bound; ++ ++ bool saved_in_large_burst; ++ bool was_in_burst_list; ++ ++ unsigned int cooperations; ++ unsigned int failed_cooperations; + }; + + enum bfq_device_speed { +@@ -539,7 +573,7 @@ enum bfqq_state_flags { + BFQ_BFQQ_FLAG_prio_changed, /* task priority has changed */ + BFQ_BFQQ_FLAG_sync, /* synchronous queue */ + BFQ_BFQQ_FLAG_budget_new, /* no completion with this budget */ +- BFQ_BFQQ_FLAG_IO_bound, /* ++ BFQ_BFQQ_FLAG_IO_bound, /* + * bfqq has timed-out at least once + * having consumed at most 2/10 of + * its budget +@@ -552,12 +586,13 @@ enum bfqq_state_flags { + * bfqq has proved to be slow and + * seeky until budget timeout + */ +- BFQ_BFQQ_FLAG_softrt_update, /* ++ BFQ_BFQQ_FLAG_softrt_update, /* + * may need softrt-next-start + * update + */ + BFQ_BFQQ_FLAG_coop, /* bfqq is shared */ +- BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be splitted */ ++ BFQ_BFQQ_FLAG_split_coop, /* shared bfqq will be split */ ++ BFQ_BFQQ_FLAG_just_split, /* queue has just been split */ + }; + + #define BFQ_BFQQ_FNS(name) \ +@@ -587,6 +622,7 @@ BFQ_BFQQ_FNS(in_large_burst); + BFQ_BFQQ_FNS(constantly_seeky); + BFQ_BFQQ_FNS(coop); + BFQ_BFQQ_FNS(split_coop); ++BFQ_BFQQ_FNS(just_split); + BFQ_BFQQ_FNS(softrt_update); + #undef BFQ_BFQQ_FNS + +-- +2.3.0 + diff --git a/kernel/kernel/files/patches/gentoo/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch b/kernel/kernel/files/patches/gentoo/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch new file mode 100644 index 00000000..f931f75f --- /dev/null +++ b/kernel/kernel/files/patches/gentoo/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch @@ -0,0 +1,387 @@ +WARNING - this version of the patch works with version 4.9+ of gcc and with +kernel version 3.15.x+ and should NOT be applied when compiling on older +versions due to name changes of the flags with the 4.9 release of gcc. +Use the older version of this patch hosted on the same github for older +versions of gcc. For example: + +corei7 --> nehalem +corei7-avx --> sandybridge +core-avx-i --> ivybridge +core-avx2 --> haswell + +For more, see: https://gcc.gnu.org/gcc-4.9/changes.html + +It also changes 'atom' to 'bonnell' in accordance with the gcc v4.9 changes. +Note that upstream is using the deprecated 'match=atom' flags when I believe it +should use the newer 'march=bonnell' flag for atom processors. + +I have made that change to this patch set as well. See the following kernel +bug report to see if I'm right: https://bugzilla.kernel.org/show_bug.cgi?id=77461 + +This patch will expand the number of microarchitectures to include new +processors including: AMD K10-family, AMD Family 10h (Barcelona), AMD Family +14h (Bobcat), AMD Family 15h (Bulldozer), AMD Family 15h (Piledriver), AMD +Family 16h (Jaguar), Intel 1st Gen Core i3/i5/i7 (Nehalem), Intel 1.5 Gen Core +i3/i5/i7 (Westmere), Intel 2nd Gen Core i3/i5/i7 (Sandybridge), Intel 3rd Gen +Core i3/i5/i7 (Ivybridge), Intel 4th Gen Core i3/i5/i7 (Haswell), and Intel 5th +Gen Core i3/i5/i7 (Broadwell). It also offers the compiler the 'native' flag. + +Small but real speed increases are measurable using a make endpoint comparing +a generic kernel to one built with one of the respective microarchs. + +See the following experimental evidence supporting this statement: +https://github.com/graysky2/kernel_gcc_patch + +REQUIREMENTS +linux version >=3.15 +gcc version >=4.9 + +--- a/arch/x86/include/asm/module.h 2014-08-03 18:25:02.000000000 -0400 ++++ b/arch/x86/include/asm/module.h 2014-09-13 09:37:16.721385247 -0400 +@@ -15,6 +15,20 @@ + #define MODULE_PROC_FAMILY "586MMX " + #elif defined CONFIG_MCORE2 + #define MODULE_PROC_FAMILY "CORE2 " ++#elif defined CONFIG_MNATIVE ++#define MODULE_PROC_FAMILY "NATIVE " ++#elif defined CONFIG_MNEHALEM ++#define MODULE_PROC_FAMILY "NEHALEM " ++#elif defined CONFIG_MWESTMERE ++#define MODULE_PROC_FAMILY "WESTMERE " ++#elif defined CONFIG_MSANDYBRIDGE ++#define MODULE_PROC_FAMILY "SANDYBRIDGE " ++#elif defined CONFIG_MIVYBRIDGE ++#define MODULE_PROC_FAMILY "IVYBRIDGE " ++#elif defined CONFIG_MHASWELL ++#define MODULE_PROC_FAMILY "HASWELL " ++#elif defined CONFIG_MBROADWELL ++#define MODULE_PROC_FAMILY "BROADWELL " + #elif defined CONFIG_MATOM + #define MODULE_PROC_FAMILY "ATOM " + #elif defined CONFIG_M686 +@@ -33,6 +47,20 @@ + #define MODULE_PROC_FAMILY "K7 " + #elif defined CONFIG_MK8 + #define MODULE_PROC_FAMILY "K8 " ++#elif defined CONFIG_MK8SSE3 ++#define MODULE_PROC_FAMILY "K8SSE3 " ++#elif defined CONFIG_MK10 ++#define MODULE_PROC_FAMILY "K10 " ++#elif defined CONFIG_MBARCELONA ++#define MODULE_PROC_FAMILY "BARCELONA " ++#elif defined CONFIG_MBOBCAT ++#define MODULE_PROC_FAMILY "BOBCAT " ++#elif defined CONFIG_MBULLDOZER ++#define MODULE_PROC_FAMILY "BULLDOZER " ++#elif defined CONFIG_MPILEDRIVER ++#define MODULE_PROC_FAMILY "PILEDRIVER " ++#elif defined CONFIG_MJAGUAR ++#define MODULE_PROC_FAMILY "JAGUAR " + #elif defined CONFIG_MELAN + #define MODULE_PROC_FAMILY "ELAN " + #elif defined CONFIG_MCRUSOE +--- a/arch/x86/Kconfig.cpu 2014-08-03 18:25:02.000000000 -0400 ++++ b/arch/x86/Kconfig.cpu 2014-09-13 09:37:16.721385247 -0400 +@@ -137,9 +137,8 @@ config MPENTIUM4 + -Paxville + -Dempsey + +- + config MK6 +- bool "K6/K6-II/K6-III" ++ bool "AMD K6/K6-II/K6-III" + depends on X86_32 + ---help--- + Select this for an AMD K6-family processor. Enables use of +@@ -147,7 +146,7 @@ config MK6 + flags to GCC. + + config MK7 +- bool "Athlon/Duron/K7" ++ bool "AMD Athlon/Duron/K7" + depends on X86_32 + ---help--- + Select this for an AMD Athlon K7-family processor. Enables use of +@@ -155,12 +154,62 @@ config MK7 + flags to GCC. + + config MK8 +- bool "Opteron/Athlon64/Hammer/K8" ++ bool "AMD Opteron/Athlon64/Hammer/K8" + ---help--- + Select this for an AMD Opteron or Athlon64 Hammer-family processor. + Enables use of some extended instructions, and passes appropriate + optimization flags to GCC. + ++config MK8SSE3 ++ bool "AMD Opteron/Athlon64/Hammer/K8 with SSE3" ++ ---help--- ++ Select this for improved AMD Opteron or Athlon64 Hammer-family processors. ++ Enables use of some extended instructions, and passes appropriate ++ optimization flags to GCC. ++ ++config MK10 ++ bool "AMD 61xx/7x50/PhenomX3/X4/II/K10" ++ ---help--- ++ Select this for an AMD 61xx Eight-Core Magny-Cours, Athlon X2 7x50, ++ Phenom X3/X4/II, Athlon II X2/X3/X4, or Turion II-family processor. ++ Enables use of some extended instructions, and passes appropriate ++ optimization flags to GCC. ++ ++config MBARCELONA ++ bool "AMD Barcelona" ++ ---help--- ++ Select this for AMD Barcelona and newer processors. ++ ++ Enables -march=barcelona ++ ++config MBOBCAT ++ bool "AMD Bobcat" ++ ---help--- ++ Select this for AMD Bobcat processors. ++ ++ Enables -march=btver1 ++ ++config MBULLDOZER ++ bool "AMD Bulldozer" ++ ---help--- ++ Select this for AMD Bulldozer processors. ++ ++ Enables -march=bdver1 ++ ++config MPILEDRIVER ++ bool "AMD Piledriver" ++ ---help--- ++ Select this for AMD Piledriver processors. ++ ++ Enables -march=bdver2 ++ ++config MJAGUAR ++ bool "AMD Jaguar" ++ ---help--- ++ Select this for AMD Jaguar processors. ++ ++ Enables -march=btver2 ++ + config MCRUSOE + bool "Crusoe" + depends on X86_32 +@@ -251,8 +300,17 @@ config MPSC + using the cpu family field + in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one. + ++config MATOM ++ bool "Intel Atom" ++ ---help--- ++ ++ Select this for the Intel Atom platform. Intel Atom CPUs have an ++ in-order pipelining architecture and thus can benefit from ++ accordingly optimized code. Use a recent GCC with specific Atom ++ support in order to fully benefit from selecting this option. ++ + config MCORE2 +- bool "Core 2/newer Xeon" ++ bool "Intel Core 2" + ---help--- + + Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and +@@ -260,14 +318,55 @@ config MCORE2 + family in /proc/cpuinfo. Newer ones have 6 and older ones 15 + (not a typo) + +-config MATOM +- bool "Intel Atom" ++ Enables -march=core2 ++ ++config MNEHALEM ++ bool "Intel Nehalem" + ---help--- + +- Select this for the Intel Atom platform. Intel Atom CPUs have an +- in-order pipelining architecture and thus can benefit from +- accordingly optimized code. Use a recent GCC with specific Atom +- support in order to fully benefit from selecting this option. ++ Select this for 1st Gen Core processors in the Nehalem family. ++ ++ Enables -march=nehalem ++ ++config MWESTMERE ++ bool "Intel Westmere" ++ ---help--- ++ ++ Select this for the Intel Westmere formerly Nehalem-C family. ++ ++ Enables -march=westmere ++ ++config MSANDYBRIDGE ++ bool "Intel Sandy Bridge" ++ ---help--- ++ ++ Select this for 2nd Gen Core processors in the Sandy Bridge family. ++ ++ Enables -march=sandybridge ++ ++config MIVYBRIDGE ++ bool "Intel Ivy Bridge" ++ ---help--- ++ ++ Select this for 3rd Gen Core processors in the Ivy Bridge family. ++ ++ Enables -march=ivybridge ++ ++config MHASWELL ++ bool "Intel Haswell" ++ ---help--- ++ ++ Select this for 4th Gen Core processors in the Haswell family. ++ ++ Enables -march=haswell ++ ++config MBROADWELL ++ bool "Intel Broadwell" ++ ---help--- ++ ++ Select this for 5th Gen Core processors in the Broadwell family. ++ ++ Enables -march=broadwell + + config GENERIC_CPU + bool "Generic-x86-64" +@@ -276,6 +375,19 @@ config GENERIC_CPU + Generic x86-64 CPU. + Run equally well on all x86-64 CPUs. + ++config MNATIVE ++ bool "Native optimizations autodetected by GCC" ++ ---help--- ++ ++ GCC 4.2 and above support -march=native, which automatically detects ++ the optimum settings to use based on your processor. -march=native ++ also detects and applies additional settings beyond -march specific ++ to your CPU, (eg. -msse4). Unless you have a specific reason not to ++ (e.g. distcc cross-compiling), you should probably be using ++ -march=native rather than anything listed below. ++ ++ Enables -march=native ++ + endchoice + + config X86_GENERIC +@@ -300,7 +412,7 @@ config X86_INTERNODE_CACHE_SHIFT + config X86_L1_CACHE_SHIFT + int + default "7" if MPENTIUM4 || MPSC +- default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU ++ default "6" if MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MJAGUAR || MPENTIUMM || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || BROADWELL || MNATIVE || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU + default "4" if MELAN || M486 || MGEODEGX1 + default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX + +@@ -331,11 +443,11 @@ config X86_ALIGNMENT_16 + + config X86_INTEL_USERCOPY + def_bool y +- depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 ++ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK8SSE3 || MK7 || MEFFICEON || MCORE2 || MK10 || MBARCELONA || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MNATIVE + + config X86_USE_PPRO_CHECKSUM + def_bool y +- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM ++ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MK10 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MK8SSE3 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MATOM || MNATIVE + + config X86_USE_3DNOW + def_bool y +@@ -359,17 +471,17 @@ config X86_P6_NOP + + config X86_TSC + def_bool y +- depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64 ++ depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MK8SSE3 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MNATIVE || MATOM) || X86_64 + + config X86_CMPXCHG64 + def_bool y +- depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM ++ depends on X86_PAE || X86_64 || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM || MNATIVE + + # this should be set for all -march=.. options where the compiler + # generates cmov. + config X86_CMOV + def_bool y +- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX) ++ depends on (MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MJAGUAR || MK7 || MCORE2 || MNEHALEM || MWESTMERE || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MNATIVE || MATOM || MGEODE_LX) + + config X86_MINIMUM_CPU_FAMILY + int +--- a/arch/x86/Makefile 2014-08-03 18:25:02.000000000 -0400 ++++ b/arch/x86/Makefile 2014-09-13 09:37:16.721385247 -0400 +@@ -92,13 +92,33 @@ else + KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3) + + # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu) ++ cflags-$(CONFIG_MNATIVE) += $(call cc-option,-march=native) + cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) ++ cflags-$(CONFIG_MK8SSE3) += $(call cc-option,-march=k8-sse3,-mtune=k8) ++ cflags-$(CONFIG_MK10) += $(call cc-option,-march=amdfam10) ++ cflags-$(CONFIG_MBARCELONA) += $(call cc-option,-march=barcelona) ++ cflags-$(CONFIG_MBOBCAT) += $(call cc-option,-march=btver1) ++ cflags-$(CONFIG_MBULLDOZER) += $(call cc-option,-march=bdver1) ++ cflags-$(CONFIG_MPILEDRIVER) += $(call cc-option,-march=bdver2) ++ cflags-$(CONFIG_MJAGUAR) += $(call cc-option,-march=btver2) + cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) + + cflags-$(CONFIG_MCORE2) += \ +- $(call cc-option,-march=core2,$(call cc-option,-mtune=generic)) +- cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \ +- $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic)) ++ $(call cc-option,-march=core2,$(call cc-option,-mtune=core2)) ++ cflags-$(CONFIG_MNEHALEM) += \ ++ $(call cc-option,-march=nehalem,$(call cc-option,-mtune=nehalem)) ++ cflags-$(CONFIG_MWESTMERE) += \ ++ $(call cc-option,-march=westmere,$(call cc-option,-mtune=westmere)) ++ cflags-$(CONFIG_MSANDYBRIDGE) += \ ++ $(call cc-option,-march=sandybridge,$(call cc-option,-mtune=sandybridge)) ++ cflags-$(CONFIG_MIVYBRIDGE) += \ ++ $(call cc-option,-march=ivybridge,$(call cc-option,-mtune=ivybridge)) ++ cflags-$(CONFIG_MHASWELL) += \ ++ $(call cc-option,-march=haswell,$(call cc-option,-mtune=haswell)) ++ cflags-$(CONFIG_MBROADWELL) += \ ++ $(call cc-option,-march=broadwell,$(call cc-option,-mtune=broadwell)) ++ cflags-$(CONFIG_MATOM) += $(call cc-option,-march=bonnell) \ ++ $(call cc-option,-mtune=bonnell,$(call cc-option,-mtune=generic)) + cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) + KBUILD_CFLAGS += $(cflags-y) + +--- a/arch/x86/Makefile_32.cpu 2014-08-03 18:25:02.000000000 -0400 ++++ b/arch/x86/Makefile_32.cpu 2014-09-13 09:37:16.721385247 -0400 +@@ -23,7 +23,15 @@ cflags-$(CONFIG_MK6) += -march=k6 + # Please note, that patches that add -march=athlon-xp and friends are pointless. + # They make zero difference whatsosever to performance at this time. + cflags-$(CONFIG_MK7) += -march=athlon ++cflags-$(CONFIG_MNATIVE) += $(call cc-option,-march=native) + cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,-march=athlon) ++cflags-$(CONFIG_MK8SSE3) += $(call cc-option,-march=k8-sse3,-march=athlon) ++cflags-$(CONFIG_MK10) += $(call cc-option,-march=amdfam10,-march=athlon) ++cflags-$(CONFIG_MBARCELONA) += $(call cc-option,-march=barcelona,-march=athlon) ++cflags-$(CONFIG_MBOBCAT) += $(call cc-option,-march=btver1,-march=athlon) ++cflags-$(CONFIG_MBULLDOZER) += $(call cc-option,-march=bdver1,-march=athlon) ++cflags-$(CONFIG_MPILEDRIVER) += $(call cc-option,-march=bdver2,-march=athlon) ++cflags-$(CONFIG_MJAGUAR) += $(call cc-option,-march=btver2,-march=athlon) + cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 + cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 + cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586) +@@ -32,8 +40,14 @@ cflags-$(CONFIG_MCYRIXIII) += $(call cc- + cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) + cflags-$(CONFIG_MVIAC7) += -march=i686 + cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2) +-cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom,$(call cc-option,-march=core2,-march=i686)) \ +- $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic)) ++cflags-$(CONFIG_MNEHALEM) += -march=i686 $(call tune,nehalem) ++cflags-$(CONFIG_MWESTMERE) += -march=i686 $(call tune,westmere) ++cflags-$(CONFIG_MSANDYBRIDGE) += -march=i686 $(call tune,sandybridge) ++cflags-$(CONFIG_MIVYBRIDGE) += -march=i686 $(call tune,ivybridge) ++cflags-$(CONFIG_MHASWELL) += -march=i686 $(call tune,haswell) ++cflags-$(CONFIG_MBROADWELL) += -march=i686 $(call tune,broadwell) ++cflags-$(CONFIG_MATOM) += $(call cc-option,-march=bonnell,$(call cc-option,-march=core2,-march=i686)) \ ++ $(call cc-option,-mtune=bonnell,$(call cc-option,-mtune=generic)) + + # AMD Elan support + cflags-$(CONFIG_MELAN) += -march=i486 diff --git a/kernel/kernel/files/patches/linux/patch-3.17.4.xz b/kernel/kernel/files/patches/linux/patch-3.17.4.xz new file mode 100644 index 0000000000000000000000000000000000000000..32871fba658bd33fbad4c8f4f119ef779f1f692f GIT binary patch literal 216560 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

5{HHmlDYCWfBbMSptQ5A^ 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%0D>znN1h#2!P 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 D87PL_ literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/linux/patch-3.18.1.xz b/kernel/kernel/files/patches/linux/patch-3.18.1.xz new file mode 100644 index 0000000000000000000000000000000000000000..48ce7dfb196cc74e6c30bd657de49d4a9e09ca32 GIT binary patch literal 11500 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 S0!1FN#Ao{g000001X)^h_fbp$ literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/linux/patch-3.18.3.xz b/kernel/kernel/files/patches/linux/patch-3.18.3.xz new file mode 100644 index 0000000000000000000000000000000000000000..f1c3bfc7322cc084da31d137635684da0f3a1f80 GIT binary patch literal 80880 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

FuH0#*S8KP2e{^nYh*5jeo+h-^ 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 literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/linux/patch-3.19.1.xz b/kernel/kernel/files/patches/linux/patch-3.19.1.xz new file mode 100644 index 0000000000000000000000000000000000000000..105dd15edec9a9dd89765202bb6388bdf6c37e39 GIT binary patch literal 60636 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ǃt*)Q!Gad{vKw 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 literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/linux/patch-3.19.2.xz b/kernel/kernel/files/patches/linux/patch-3.19.2.xz new file mode 100644 index 0000000000000000000000000000000000000000..6dd9defd6dc33ac5a772407cb98224426acf2620 GIT binary patch literal 115320 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

ihRFV6)NIwpt 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 literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/linux/patch-3.19.3.xz b/kernel/kernel/files/patches/linux/patch-3.19.3.xz new file mode 100644 index 0000000000000000000000000000000000000000..2b27eb0f9db3137046b66f4b5d10f3f812e64ca0 GIT binary patch literal 144892 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�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%0D>s7HWP}f_)hzcbRt~=m=qACk_DhR^ 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 SGQtG0#Ao{g000001X)`7R{M?s literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/linux/patch-3.19.4.xz b/kernel/kernel/files/patches/linux/patch-3.19.4.xz new file mode 100644 index 0000000000000000000000000000000000000000..ec0a8590e1571cce404963d3c5d7db1486e2f236 GIT binary patch literal 164964 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%0Ay4mm)=;l!$ESnBSLyxJ+)gHnqA;8lZasEr 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 dg#P=*WdaZST#*MhLNQ|Y*j*S*) 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 literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/linux/patch-3.19.6.xz b/kernel/kernel/files/patches/linux/patch-3.19.6.xz new file mode 100644 index 0000000000000000000000000000000000000000..f55c450afb52cec48147667d7149fff3f97d44b3 GIT binary patch literal 202724 zcmV(nK=Qx+H+ooF000E$*0e?f03iV!0000G&sfak+ZgZuT>vr~NeROI5q(hJ3QtGS z!4;|pXZW)T&B<2$p4<@~sQgF+7=_}gH1m=L=A4a7Y8-;x#VvB?;@c1qWdXMK<9{yo zL6PxUuKs(kypc#rY_|R2-H@7A?&*5{U9gxBM@VtQ{qCOy{!AOS#6 ziIIUc!K#^Sk*NqdNo`6JMp5(Qp+>{rTn4O7*8-df$#bN6W{Bf9Mluk}#-LP3DzkdI zVQu1{9L6=l3RyAay>bi|{INo@IS#$uYHYG)1~b zgYkk=8K(0~_O+;KD>7S|#_KJAOr0Ch#3h;N?|>W}%s6FzI}>^-(kHBHbJO}u$G{~0 zziTEdE}x3oGEn3TJqWQ( zZG8~M$Ov9&+NQ@J?X)a$WxT3;;b{{V{t=W3{{Y^ypYs*sg*KgYo$Z)b9B5jT!sN&5 za)?;{Nr_2o_1u0rg$QYM-gPqJY%oMdO(NWSF92H!6yA|r^7gdY14?$b5~>0fuI#h) zKgv>2+RPPQ|`00I()3@}+5d-xgIlJXcphLq}Z1i1@3zUuv=;}|Z-TyuL1 zYenbh%<^b5&dAd6Y?$M0Hl9cg`$x`KI--5B(~KS?#s`?41Y9#ilDY@vl3ZImRT~jN z#qPBUK4olAe+bT~(Eu9YveJ8<47sYj!c+fY3HDfb`e`oyC;z4XUVsZ&H9gonH2DE) zZnxi0z!Y--DGL=2JZVv8QYXIA+R0@P(v(HjAp)Khbd04?j4Y#B2%o)t?SE0hj3>fw zq#()k9XdB6FjOM6mg%1yP)`Z$kq`TPTYN(5Aj@CM@9%0n#ePY|<>qhBZ{CdM%sGQT z?j=3lrB8!&t|y#|*+K>#))R|FSsA8+HL2&!Q2tWc-wAQoZ+CYgwj2bF+(7`tza3my zb$eUo7vTu%_0`1TncUk&ua`SiEa_bCL>%m|mz`nM@f7O`$`ZsprV- zp{(+o-asSE2Az7@h%9l6G!YX3f%W?8S1la;|KmtEwC+GHQ}_qomBq$O3`2bFUuFZ;%Pg2<1PF+ckPR9D|_}aA8Se-hsBWT}MOJ_8YGS#FVa` z8^3q3?dbu(N9;B!P8Y2->TLRfzDl5DYE9utc3}Az0OOV|V2}c52^l8m|KVd$t$WMR zVYJGbGpS-Z%MdPB9*VPVVj8vY-Wb+VUPxC!&&P!@fs1x*H>Iz#qz}Ae6!7Iro{0xwOYD0)24x*f4|)7DWq_XHo{Gm zE)Ix);oE`vfZQRW)C{0?(R$@RRCEDo9PiRh=cIccr%q^Si!5PUXy{p!R3L%Ag`OA**;w}t-P8d}?km8JTu?ckghS{j(7_}`Z(%}BKilS)G)L;vgz*Z{ zmE@g+E#yzl!xL>DHr6;+bx>ym$I_LIJ9b@s*#h5Bk3({mzUu+PAgp8iiI6e>Qp*pw znQyr4rCiLf;_oSU7NED7aJl*~H2uGbzl zA>(≈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�&($bG0PlC^|DXSVXHM?5a5 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

VZ=9Lnh7D>$> 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�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 z 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

Gt#eni_SoJQ zZ1K1(Ny5KlQY?h6D~2PD6HxLx9B}myewaA*{S3DdB(3S%o&iGK>0S(YR=%`mc=}Iw z#>IBtYELs+XZPoqHMCT%_CCAGO0D^xSWqJ&T|#~_30xFg77vFOz8bftGxswNg*sjL zb~w4z-A3iejnyKNeA0vKJ^%D@Nn17ZH`aH3E1J}88Zsz%O92DtDg=w0#yh9(&*XUc z${5c5POQwfmQ=;+^7njlS_DG%JKpGc7DUWIhl=f|xgO&szxMq10?--SrEs)oM^$%= zQ-|jTVaM{cK?+a2M2e7N*VtY3&7wVN42pwgwlre%DnjcB7mKA9?wq$*IO(@zO!Jid zm)FkDZ~dZX_b3%FcH=P5*}&fxuG$0?nOeFb-u;MDw@cZHf$E)Q5HrlMn5KO;1r?Oe zrRE22zyWbW&}>)4(27AF% z?vI%~WY*(tP=IK0Trd4w5(P@X_Cef=*;oLvsS1oNfdHld&dvT3oAgvJxbT%vsH8xl zGUPG6JV4AulDTLk*(z>cdmxLp0L?^i;vreOa4i+LXdrs;kHLOcotIv;_u|(#@AEiS zM8)j*#q$t)YdT_o`j2OuuT3LOIOfxxFoNtk31gnXj}Vvjr8+B66T}qej%<=))t_>b zEpHN$x=!O6o;Nw=Zp5N;1s<$N!cT1NJT+m5(z;9hBVI$GDVTG*s|~;aS_JYC(Iw-P z)Nm;kaNYgOm3DUAKv1*;Ri)$yRtbFUAq6BeT#^M>BzD2jq(f;W1ltVKlb0NvjwwcC z?|KIe)1Zh?5I1Jpx*R1K_Uh0R_o4WFZhEeu*L|l=$Z(o0Gi6Dtmx-P*% zu9BL01h&!lC+lGhBI0vJbfBEl`hJoS@R%2(N$Z8p0XBN~+)~aqCelni)_Vz>R>~|0 z>WVzYmhi`C-w6(~xmrZ=7HkA@B683H(<|z9l0-<=`7^Wj5f`r}O8)_DS3=F}30OXq zh7N_Pl+)m_w(z&bI+7+{y;WbzSc%?P=ui&-Y5CarM2y#G*Dq3w(WT>q1UXSgN={Te zGw%WzE3AF3t4fr6Bl7d?)LBx*i2z+!!;UwACm8cp*gHh?o7$C=Jh|o^12gaH2s`Tf zn(ZcqHd$&&zJN2rB!1R-v3{3$zD2ueNfeYu(wqQg$q2U$KDJ~IqagP?*KgzSyJ%V` zbewvo(pz|eq3(YY`Yk{t;IL$t_X*($5KG|i2LAUg}j~lCf*HP zgM;V~L6SQ|6XO#{y_3#!CnwC46-NzSOoLlvR?Z+#ihmko`Cqb$WDmx$2Ha7FuoDT9 zSe*4@!tKo|yhc@rNyMV;Nf9=|xMK{uYquH}YI5LEk8tL4VI(5oMdG@)&-yZsionc? zHkU;$1Z|Qj(Za8qtoU}$?W{pw?i=9|qYu@8xO_bDj9-VHf?{_)y6-|i%^d+mH;PpZ zZkj7VqIy3MLJ!pPyga76)!0*0bfQ3Hkfr?5=;iEZ5bAQvG%!_htgW0R{(3qNg!9*& zMSpxU1A63=d7_6tsGk~?h_zC5G{f?FmA(Om?3w)d&Q`Bbgm3vel6Jyh)$wdIm*h^Y z*=a-YcLlyLIdu8~Ms>n;&h86HRwNJ(Nl26rgzIONg!ElD)sTh*;Gc)`}$sON{xcP5scmc64JZC}zBlctw%y@`+s_nY7Q6{VnEHpdnck4a!Tu?K&kyfSff6KJiF9(wHO zPC)pb8xRLhvFn$9!j%D~zw+IZ<#3JJ%+eL(_8xEYjl>BlF_`4H(tr>E#8|VSKg(M3 z5?4rgRH@4f62PnOP?fb{R@_^(r!RQkQpB&) zkwzCiDg^MLYK2M*6s|gFBu#ZzFP9bx%C75>HEO~O8--nPNNi+U@xNU$0|N<^5^7LiYPGhMdCgD!RFoNycxu3#M_MMK~}eLI|@T%-(BL8@#pX}D*m1> zN&>w>yEa#|uwkmWwezw~gHwm4^1lC3O5D`Zv)MGCyi_O@2-|7fZ{%wStrVgcSm7I< zc1Hke(`d8o>ke-=#aWsm2PWD3ijV-YyN&M1pfbNV=kK-2j?-y}VaM1A-r;y!M+yabQ}A|k)Ves}j$ZjUpc=UX^zE=NWBp5;fSq)j1I z*$xIG7WYHx26Xd23B*KlxJU`l0fYVUeo8glSUO3^ZJi^BkiTvhX%@Z33**u`#70ap zIAU_5N)+Hv6nOpz#^prVRabL$1PB%a(=_r<+jHB?pskMEzYTiE2$03U zvxjH|h+m$#lWP)}PH&fS=K6L$jFFw<`NpEw!(PAH~4yN}7!|H8b;n$m% z-sPB0YmY1bB}krMiq4&@XxcggwdhO|Ixei8rO+GsG0@D45Iij<8QB%w9_gL(1t_7Z zy1u3sj@M8`LgDSZ8sz`kDu)9vroh91F5VBM!vK0{)ZHlKupG|li&tJe@DeLHg$e7G zG-^yr)=f8tKiir3->Cqz;y0tBe^Fp;kH~U<+=Y|y5uPraF~?LQls_ceuxwLdgT)*? z4Wvpb55`7c!u{(N<@2HAp8HC8hQzAM!WxCDQ^WHN^u~Vr^kM3?UUsK$Y@-MpR!$HG zL7!x<=&9ONfa^j96ZJxQH#qb2V8U35!EUyBAx^$!?W007KXlgH?Z8`3~wXVtQPh}jMx$8o@h^Z z2!*NF7d~s1LtF7g_6_>_s#BB#DGGm6n+xIm+HNZVh+y^_OI@kp=c%U?hJ~V`EB*|1 z+y6t5=6^Ha4m@;Y)jI%wJ#adBi;TRN2os1PiTpYP$rr;QN>8_33Ly!Q+IwJ?^gf^% zb9x4Ika#3v^p3Oy&wTP}MpVxFwhE}zX2JN@ctn_O2_mWhTKe;8+>!hfHzmVGHg$?g zp|Oj?^!tW-ar*X_EF%IT`BA7{{m79~Qpg5gso! zZimuu!lyyP-)X*$J9K3*GN-&Ou)`I~ktS_1V+fbXfT7FAjAk4fchi-*7_^<@^s&DY_ zrU*$20GMbXlQ%iGFFuvhj#%Yzc&Qs8{?X49PCRA%?J8_WF^chE0*<1eU_Dz*It*2o zWx&xy^^ag#{-L>xqc3%ModDY~E(R<(6z+8BHyU;;*=subm_K!mqnnw++c9`T7A#qiTlA8G{M;L}f8)`eF+4I|Ysu>|>cewMO z=zzMLGUmdAcn%v3e{I^p0fY>VF>6uu?uw@oRa*=}1Vo*{=AS}%cRBWzaLY?*bjpY9 zu^>yM{a(<(0aZC7B1UYgCu9nugsIuAabY^HYIzRHC5RUDdUsJPyZ~frLH`U(w7C`R z<*?kv;NAWDHFsCB3BAzy%i|nOzd`iwQdr6D711gy28?qJM0WJQ|Hq1JkTuZO1z!Cyy#9+;Jdm1V&hv zHo%1^@=+l!Nw2Uu{?t9nw$j29>d(9IotIK7m_@{4QrmtALgjO~Hh>0z|^Ab96Lrzq;#e)~6A(QQ>ZYZj2;f~R=( zVvy%`U6j57nY5Yl{+(~9U_U?v+Xlz@KEnnoDsW<<^@JppDea zrHv{+wuHu((xjikgp9hQhk826f$^Kdd@vH)GYS5V{)|>jG;nr6WH*h|m&1-on_clv zns97upw}tr{374rsN+s$Z zO^60-W&<-s`jCehMYAUf` zl5lvkXLJ-#Bk$YTU|!vz>_#VK$(N~8SD^?HhELzGQqUaQXGc~fwi%+xRN)x{amHN% zf^g&MG3@7Hkfq$~QXPdzB9_48*GOFJN?r{UR(4I&wbGgBWffZ9j)=F&dpGKv3f_FO zA&27G2_%k4mPeroiEFYY0))G)uGsD~In^vA2OfxlsXhB;R6A82=!1}egLUo*e95E6 z#dPYRc1bV_J<~M6+{BuE!YVJ01YS|Yea0I(#{S%U>MQ!srNVvVdH;QXCDTvOc>8+F zwW+LVAYnl7T_!^Z@fEIRa%GcTR?Ndzh)lE?1k&bGV<;ev#Ng<{)R;d>S2?im^7F8| z(!^4LJ0j<2$3?UtxEFP!9w7ZxCYpQX#ouLEsBoC^^KNQYh;c!IkK|7-C5F^>sV+T) zuRE;&dT4RoY6u%fV{`~&vl?^N@)bAj^}_Z0&_($*4DzCbT-~_b2I6zEeRk0QP@pVi zt~Jx6`+;(WX&f@|BPmWFdGbD$5mc0@24|BdhK0>$teBMU4U zvu2sI|c3gp%)6nrnLE-c%d!F zMw2%L73sRChZ-QQrO^lOE0zV?yPvwkh&v*Gcm)E^fQg86Co1Adq`#q7hToB6WldQ) zm5t%NF4$G#tc-7q(`^kJgOL(Dv zgF32@GfOC>tplaL^1ClY>bY3hUe=Hhg!-)3fH4TxjhHB2vg)F?D-xSLxciQKQ&Q&5 zLOz^ov$MSM5|`$a2e~Fo4*s^X;YQ-?c_RxJd>yo48_Ai zjx%pSD8tK#QR5*s(+KMfz!vLg325w$=A!Ma1`USSsZ*?#A#9*vV@O$mf+DxgM4Q!W^haMyv z_I|m&Me;>}ADH>z17Iz5z}gej{52l!Lno83QAZ@YiiNl^D)9B`oxad5`l52a%7F`s z;|So~q{7&}uxr}w_yf-(B}R-eK}O@+;+hVTe~i)lx8oZYFGQzsOZpIII!04slp`MDH3=x9dVcBLp}^Kh4wuU_1dgDQ7;9p6(NOI5U4#rW)IpOAr|C zPhVIq`+yjt7y7WLP?_TJ#N!Tv;CY++T#_6~)?F62a6J<^t^`m%hfs~{gTqdV zQFGjq37NxG%I{?Q)`eZhjGvbp)F1b;Cfdu-W}K>JDiXW-;2=Qhx}|JuwHR`#T6ssf{Yl{NIxmCFH!bHNpzJqUC8PdcMLpeCeu=}c5P_V zUVwLB2(gL$Ik)$EFO8z6xsAigFMt0}H&cO2<>$7MGMY88=~dViy!=!hS<%N>=03>r zx)8-Mkg1;7yi#95Zia)Za%^*D#zAiv1ClZv_u}b0D9O42oEZLB9NzT8ZJH!393S+4 zu+k|c?rHx7o|MdZzQ$v_FPuODVgOk%^>cz8gosV${G6&VFhK=@7+QwJRfFF)Za=YP^a5J&t&fB(Yiz;x zxM?K%PG_fP;5#w`{W>330OT0n)ztD!DrOjFvv0Pal&ZBF&5n-2Yc+&OVD>s&4Jpms zPf%zMWD2%|2lm$(olBpCDZ+fnkQ`WXK7@%4x0PH~^0A%i5+|hK7$>Iq$*Y$2BLxQ2 ze94WH_Fu$5d21;h(iPcMdlApCdVA67}Oj>`$-r1A1dG&poy z*`j#ujGl~FV|I{vxmqf^y<=L-DPq1!Enr_h0a@i~-UbBw5Sf#x%J5Yl1C*Mv5Iz`_ zTMd(C+9sYK{^w-dWCpY-lu3|dKi*IYE?7B9|u3 z-ubgUsN&s`a`)3%g~xT(*cN^$+M{Pvj!0M+aZbGXBBxGrgvBx!#v}Ux0+TxPRECl53PRbZ z(vpubX-ZEi^=f4Fg;?gp8#qnoiZ>SofYdM%OG_1>C3<+JmTw0GF)LkLmb%0lzYqP& zT@Ryj5xU$k&rq9|qy~NXyjJg*@&vbrkS{}{vJa*%y6iw&&~Q3ofXK>t@s&j0vJ?7K zB7Xlk<>y=ObPUzz-o`Wp{9)jlK335>ZX)NXtEz+jrnfEJZFbK|b;Ru`YKgo0hW|TlOGQ{amF@hJ$FsS%zIQCZK0F;=W)~BmoJsOfXy4P98;KF%!@m>G z`I=Pq{!A?n-t2vBTa7aHft-wy+H=~?GpKcig&vu+|5uMt-iZTDhkRg-R+sA_k^C3{ zbw1B*hCNoiJwqkj>)DHC>!be_%+hx6|o28CJQP+nJdF5|bSk$Rm0aDiER&NMW35f=)$DJ~Q!vjszGRv6o&17=l6AYqMU-Fy8 zX7XCVQWZy!X|acf$P;K8hF_JVxmexhUMEgmyU8xVT2~dd7I_aEVniLr2xEo$6tqNA#GVz8iE@L~ zt5LS$;Tobo9Bj1S0cg%dscqY)6g{ZuR6O`B@|_@F#`B^8DjDVj)JeXz=<62*%Z0H) z4_{=*n4W8jrO~KsK621umaIjvIp)*|k4G#~c@Iae(VVAP%g%G4#KlZrl>7DBuPmQ9 zF4axL&id{jnpY@D4y{_t$Tn=pG=RxVx(Da?OLMtRS>m8;;mY|g<*fI+-wg{TiT3#? z$~u-7;NM!TiGvqFz9!iI(WyOzXrDoL7<3uUwQPVDj_1z|{xb3WI3h|lxp+!DsJYzV}?@sGGTY6s^-{`}Qe_dBZ*^H=T7?tfE2f-6@fPmujd93It zqe8k1m5Rp>ol1B6&Jd#169#D2jdk0>iCu4G*&|mn_m|38@~s92Mhl(qt}we$T;3Xm zTr_OX-1<$5bHwq*HoR7V0XMB$6}l1~Ahr-5f|aTAHD$TlJUG~l_rMooFvB;m{yIf8 zAYIWXDb0u@aLwby5Kw&bmg0YlAJ{9~SRdTi86l*R!UJvM zY7+iyEng-6S{Ur(S+1NVKJD&E(Qz%@k8jmY)=_(A)a_~c8DX9o)vIJuJlldQD*|;t zAV)?&1OfjR4!1(AeIC-_XQX?Xz**hgyJTmGwc<~oDo)2a*0`A+{yPpT)XnDV({J%YQFMxlmP z!!g)ptO>e{zTks8Pn+jrv$Kkr*G?I8!w6A{{=+;t39ljnPO+4yt5m;U0-y1is3MKh(66=5`CtWTm+8zTL`EwO>kD^;#u0&*PBJw51Mgi z6fHw!M|ulyJ>UU8CAUTiU519bRbbKXzU7&WQY_&%V5F>+BK#u8Aq{=p)Pl@+QXXk^ z#83@bLqlFy8Z4hStJG_t-ur|KO}c1dWLjlO5MJ3uf=#X<2VSnhD1)Hw$ZvcU-={Q( zco*q3V~H*NiQAY!kJti4V!8HS;W54J09`tJ076-1gs06dM5Z8tL4V8!e@JauwdS=4AT{0E5SE}0Vx50Z-gpqz4xcn~iVa&}QPMk$^7j--8YLTO& znpSf*s3jtwT-LWdTS{xG;Wm{@a9Gc11~oO6mS`ET?c3xbosA@;wBQ2U;tRk6yGE;l zx26#3Lbu($dHAwDM(hAxysS6F&RXY;37*8ubeq*f^Xcl~+iJiS_$?x_{_832jMb{@5ktKovBEiZLdz z(K7p4Uo5C8jqQ4y)Eryvrq8Wa!#@x}060Mb^&+SdoiI!9 zF;JPu-OYSicImjl`LDslMW#Gs&%P?oCbBr1vW^fRkYg#6Y=nQ#Eya8S#Mc${u12O% z_3O8OcC>K*DdcvcF=p<$y;x64UbN-jAs-NXTWhl!5RezksNJn04&uutbN^2YNi9Qq zpM|CYYzgq#0jpv_Q7C%m%*GARKJOSrQ{+M$scR|PE@u`*ImzkXL+mC!3uo+EO2A&$ z&^GfaS*BY%_050Jko?tK%^_I#;Cs%F*i82o7EnCe4+Sv}))KjHl`<5F#Nx?m=X9I* zfi&f$`EzLXHJJq3jox`}6Sku2ju8AVSR^;HkoGtWa$KQ6u2yb^BQ88cVfOT%s_XJv ziMg>$=5>=WpU}r9B3{d)|HJucP%nlW&-M#s9-|kjgbK#7TMwz}dUybTOI#oQ3+b4< z=js+ABh5ft8-XhTX1E;-Wnj&5Gv@FOxevoS4fSob{gVIV+s<7*h{S=6COzIffkfr~ zL3HeO zy+-D&jbmuXsqgdMlM@S&7AJi18pvhuTx-?7WtAoE!ot(m-`S%SqC=vz@Hzww)Ce1h z`+?#iX)XJ^Q^CgQwD;@XcfMRj3$2nn0%3NTwuDLKNmi(MKJ+v-dr7SD_;`v*+@5h+m=p2U&oz{lMJx|m$f`b{7 zg;r!+rhI`>gx^+j+R#nf`ClwQb02Z7v%5nyuOS%0iVl~FW|lYYVSZhLOtLjVrgJG- zO{9P3w#gFyh>|~}w-cvHoYRc{W*%^tF@@t^$)^VW*36ek?5HO+&H z(qRkhy7KOr!hv}!O}!aZY8cCTe?-!S07N^Ni;PgloUA6wKyQPX)&vDqaxVf8|6;Zx z&?E{gEyvJU8DsCzJkWz9J#x2Uuqwsh~^(lUvr1HZLTzXD4N6makJ?^4w9)a;%nCX%$>Q z-`9;^g|xDGUA#YtfSNet8~a;P^wF19lJOIG5BnTX!~01GbQQXJ$h;5Gc7+}6QwZ_C z&~WY+hq(5Q4(#ej4b;g}&vgdtbJUL2^n#nMc|jm2cUC<=Ruvb%H=P!8xv(5wgG5~*A{u4uq98?wwtB-f{RdAy9mEeGzU zQ*qVIXlXR3n@sqcwQ)S>eQk-#f415Pk)WhidK*S_s~RI__)~*M>g!JDHx0e;2flbS=GEO9?+NL1x`9vJ$%786<|R{J|yc3 zV5ATJyL^-G$^L`@4s^fDY!_OQP9&Jf0#EZNG;I{M7`TGutpX)c68modVW?e;%h}uz zILTiRYk<#gLcGs3Bv!$b)0C+&r`mM~7ARji!gBLuqT_VmCxvBn;j>3bG%!3aq% z35aD-WuKxmgsP!}3)R|9W4#W5B+i2>Cp(c-Ae9)X#Z2Ji#j;Vvip=2kWJ=hvGNHk5 zL3*8)rluBv+wM;SL<>-Z;`AB;2>U`-c`CY6<=tc!WWv68POL{#XN)MB#ANnwWAdEDn`b{LWZ zJHB@8Bf1kbScL3J|UG@ge}HM(WMR zP|%o|;WjPxV`JRFA((m^P6E?K?e$vE$vm6vk~Tr-H@F^eImpnDAMYCsl$iE?23|Wt z`CuTiGgSRCQ;)&0*x0CGvj|G(^MrM)qf840|a7}S0C*N6L(`%hEhtYs)~j{6S|2rXvGOlTHF1E>ez3c>2@a_{09W_r`B z6r4dkf_CS8tGC4e>fs$en1csS>FgQ27)d3f?`fb7S=k;r5wUUZZ)J?W@7o`G`qTV~ zKWqE!3c8k^$96Y5D5nGQu;ljg9iO9J*~(GAA}<`prmRU7LkkM(ddH$Av?ETG%}Qrp#O|C#9jRJ;CiUr?rn z+{*fCe2@Z_2_2s9-IF+5@Pq;3x}W_b&Aw1Q?s_=JB!waf`L`+D$IpXi@S;sX^ns6^ zsl<@<4~4L}bWKPby~$8QnULhPTi(m?u=OGmt8AtTI<5;o7&4gVA4|QC0YVBn?UZ3I zLfn2m1mB8&HJ1921a($9KJK5}^IsmUPRvQjc$TH5NxUtue8iB$7u`I zw1V;mGc!TALppzI)A4QEHvx`uzJXZ@CbEP?-!V|yo`gnJgcE$|;uIyRh!<=6yWo9< zP|r~1IQJ;@+)Z;%h4A`2!-CDF^NOX<8OPUs_nUE4Ibx~l6qeEr{`<`ES7ZkuZ-Ej; z4lVYQ_~itci}A!Zo3=r*Hw{2gTwPI9lsFlLs?Y~zU5=uXUK);2gOB#~BxLwkr=E%) zwOuv_;c!?5#$Of2(PoA;k$y4k$=1JEowfq92jv?E@Tc94+7!5E`&Yq|T#z)@_wBY$ zbZ)O-$CY!Pi4%%g?=$Z67_eZ-XnA+b;f?_A_uqT@0emp*|DQCS@?x?AwG|8a`UG7q zMOVcqMZ^ZXx0qi`>Tc)A4pEDa_jw2pcxi`4`=Zs_vTitSU#^b!5;)iJOK4N{OH-T1 z+yG`GVU*H~*MQu0IgaCce+C8haewL|vV1 zy$!7Z2BkjyUsL}$j}&+UhKs0NP^#fwI;JjofX-tPY9^3Rmxnm<%`*daY!}ja4Om3; zz#NU$N+il@sT zm4tSPVUK0Ifo9Xk*80@?UP}s!MTpZEF*_t_CX26dF*!23XvG5Sq?im)QIrw_Aw$Li6pQ%0wZ|9Iy_`yav`nDl#)?xUh6K7VN*hu8TS| z*j!|(?QP#*iS}fjfKe=Ip}A@fe=-&ct;z!OC^zZ@V@fQ#o|;LoI<~8I*^Q{nC_jX6 zkFl$eTtSP#Oqu#bxO~56`W$f5 zW~!`)zet%!)ZlQZJ05ie1@$yTUVI@r4O&gKQ1R*qd!WbRP89N>bVCYEn9dkU#{D1V zXAYugRhVePM|TG#?_o4%)lsehpUxG`A^YHbt8`7wGwgU1o9=*?j2FyBx@Ne8LtMW) zw}?2^=m^Vd5r0t~%c-etvupack(mBK^rmZO{;KvYOjSzDy(+!w^# zl}bMw*~+~jWsrZY#mb8-qCLtnrB(lgveLz2^<<0&MxA48J|^dk5hM3k<*y8gwTF)u zAtRNk{eJ)gpf0+dg*^^?US0!rzP>^ZRz)lhral#+L{TR#W*n3}8iIXt-mYw$kn zHaC)_K%$91bf+=;I3^bg+ted`usA=>HWR#_LIV_gnURftCEg)1yN_oY^fIO(BD^{R1{-VnachUfK6IcKD07M#1~EH~O2=I%dmB zTLZVq!v%^%z>-B-U83c@&&JL$m=+&K>h`c`tL0# zgk=+!Ov+y<@9I4;dtwX?kc)Z;QpMC5r78&vK&hF-i6xi(e-V1PZixmY$5YiO_o>}m z^>t|Bzo^hHggX9SR(Rc^nsWs6VeSsW*TIs~cn1Pni}4Z@WY6>z{NYLqFq4GsB=)kR zIw&;2YPAqE6KSf(xM^W1RUhG1ljBL=!3;LQQJIhbg$&$VRca!tzU=M&{JJ%GFu!Cn z1tA^~&tzG+6?NNLfIKPI0uIT>L`0GAOraAuxgORfesk|%_dNF@v10<3`xiWA>+C8z z>I6a!HtNQ-RK1Or;O~X`aZu_I!RIL5?m$zn*|Md=X#^zsWX`I$*-OG=&I+xz`*v&4 z43?W-;iAd>cD-{ocWjbgd!BV~tP*AzeY6yHQDJ}>6E@fOm ze7Nj(K4Sa0l6~m|54I|Fhq9TSIfbiFf%}F-KcU>VK*O?7f@*+EkgZ3Zt5Ac&QNW`R z!>!qav!D&IF#D8#AU-q2vO=x+&xLh5dXyUn;```7oEwqCrtK)WI?z%Ue6ZwQrhBRa7Wx=Eo8_( z0nGb6$PHIlxeoK@1vDzg7K1kZznlUBDtb;)Cu~`0H#A|^0QGOh2!#dPfqMym@6v2^ zLU?{@iuOe6=>e$R)t8%d4;~8o=kTqYonMNI8l|+Ca=Ka9>o-JTIQ;^dWIN1?`(Db^=wN`(@$v-`sQl(WUIRh-{tf4Qrro? z0a|2Pq2NdlT4Y)yol9B~zR-7^894dP;><5f|6dS1W?h-VsE4?F;^>kdJqIck^_1 zd{gMYMj<|g)&nWtQ?z3>OfIPOY14ldsF|hxFX9D%svc(d}AbiK?Q+!Usx6PBBu# zJ1?(TVw@UsO2@)Zy_EwR35?&%U(RNqpO(4AUnd-hQn@B?`n|5pkpl@+*~ z%3D!BG|jXucBf^ol`4SZBc}9O{Sg>~|Cmy*puh*Ah<}i1R&s+YY?{ULeB;T}Yc5FF9QK(nk7urF)+K zw!cz7;hy0L-1u`ZENC`_$hjyo=ePe9cmWjIpoTRp{nL*!Y|RSFRGAG)yeSreq2N zlGzTAS225=u~R)jJ!gC^98g%$5qFDRLiW4TSN>>0cl{}4stV62 zrK$&(hakbddE7T(#~I5uS~M_utbKlP*B#XIB#4B7`TUgA;ZAcV6(egAe*a?<-LY|V@7N1~3~a!my2wp0mxsxCQl^Q| zd}w{l656Z|B%$@{XDRqW=@t_{tI&oISM9oi-wl2i{B4V-;H^hldMxgYk-WmTL=Q?! z?-MgYkC-8lhse~{=}ndgQ~_3d^ZGG#rw?uC;(82Gt0p{qd?Rp);JAS$MWH$7I3O`ujfyUu4-c)>Y1G zOW?-;fraz492kBlU|7IN#^ZzKjyeM@S%2~Mkhae*h(es%99av<#?1n}`r9FloAa2! z&zI1V5IkqWNf{zOHP(oC%Ge4lKkzCJ2_jIQ1K^Bf#|c!rBYz!(WAUqx8})E|p03q} zfZGiFAW}5A9MN}g&a>JBI$6)dm^=O z_JXJ3-^oV(l^U&qX8kD3ouDxhAJ?0b+sP2v8l-@o^UjMV24i4}VYIH%y`NJ)I)p2& z`|HgMJF_(($mb?hwf~&mVp@Xpy^qRG$X|ZXfCW)Y#+_el*0PUM7rkl~{F<;AweNvd<&ph}Arm}8TzW{F|CV`qsH}to2NA`RoYZxx~;8v=2>9&vhjh?_p?Bepy7!IO&8cj-io6jk((k$$ zFcHhv^UNJLQkt$!g_mRD=9xE+)%MRCe8nd_6)`WNdial!Uj#8Sis<1z5h5-QAE5x-A4ja=lmDcz+i#AY6ty1O&`Bf$KvRAnnY1b zK+CF{6&f{S4S8Hm5)>MhzTtMwtCg&Z~UGFKB}Fu<}!*$MU_sS#duWiZ74WBHbxM}>OqD`rn&+BSn=~FyS!0HYbZ85 z=?HVhcdGtuWL8hT7pNs$az?j8>M9@1EysN2ZpM=MdY+Kcg0#T>+P?KEnWqX9Fx{{5 zCmKi45$D2G+)hyC`X<@Yet6*B-k{CI-K8-Iq*l**#n&(x#7)LSf?sE5lqb2JB~kuA%Jjv|}F^*l$zRkE#MIp2=!Q zJwI3PzcfPkBd}p!1vvN(GmV6cgVHugexQ-(VJRy=fo{(!A2x?z_Y-jnmWOgf=aka3 z^6FhJ^ZNtuc0?g1G^9C~C42BTGtk(z#zeky*~KpV@s{8h-&CsxJ907m6Gv(qI?=3S zA`9DLC6)8zLQu5Dqsx&c7$29L0j2)aqRPS`TnpFhvYb;8xMA9(shX>cwZn=XMj~|c z{+zPCCxL|A`|hro4pnN_TxDof)cyNo>~pc~c;vuA4Swh;zC~p}Kxi{dWmZQ)&8T(md}e?sdTl|aC0C8j z*Y7Qig>#UwV_-|Y;@Qvv1HfBAPISq-X?Oyj%6#}wrE4hA_KkmeXvRPIk|dN5MSi74-mNHKJSBd`(c)0KVB0xztin&SGDHaA z8D9`&JP``~ zx)2*Yrfw2EI{|>Sn;;ZH#uMNN^{NjA5Ioqmqam8L8#J5iSGI?x_Wq(%ZN$KXrY3G! z_SkA5Z59ihb2d=?L8(W1Yvr-aZJ_9F-;M{hQ)JCs;~UL)TOSwR3H{{J2rIf6kulFk z=(^+p;zFtdbAoCQEiPo!dD}^|P|t`PGs^hwnadfbkhce({!!)HsUL%OD5SjGd_2$XC zj#ws&)_duxR9K_w@PNJ5&`#v$wZ3NOBijt|f|Ij~G@-ezL+e*jNADA1Xf-^PG-qQ{Ekd2WLy zB#D0f9lxVn6rOdm601#Ym^0=WVRLgMxy!2u+6=yyB<#un^+py+PUcH_V1!Ti-?DYW z23{37Z-)T_xd>==)~hkyKd3_fy1=lGzyuz(SC7J-qLx{G#BQD!Kt4?M;3)NN0o$JGw{MD0Pf{+5S z=_{1kJsB1uze?@8LN^-CIXY%LW&6NsacR&01g-k79p2-QB)?c^1y^a-`A=`bgkG1V zXU{#5QjQaMQ#aF`hGf})%PhEgyttp9VwI*@W9=z^cT6XIbCsp7f>XQ#nC-$jven3n zxm0Ivo|CB^TgOvdObyL;7SLNi51Ht2V7YF+s3~Hx z9bo-K*iK6lKhxjyh`p5^$R((ttFWpb-?OkopEis?L2St6u6GeuYqGcJY`xI-za}f( z2}__HUl$7{2`k^*v$0{HGk1~z(RI3!RsITB`75w)zWXWVM22pR$SsBEI#gO5=zb@0 zH$KEI+0r+W_fiPY4_VMZ*;Y9>qYG-oCCL7U4A zu^;Tgg9}`IODuUX4)lw;bGCI7CE0Z#Qz>kh<4yj34qauC#M-@@@TL7QJ(-j?Z{n1Y zuxs1w%3pDk7g)bv{Q1h}%AAS2lYVKyJqYzoY&56gKS~?VY|PwaKstcVe>)GD{WiK$ zX|AL~^AzU!@ZJSkeo__9M98IL3pkbtc7ByhUF*ChyRxD*xU7#B8#o%DXc8K_Aq0$! zwwk2lQdH_|37|}Lu`1pHSsNAFn!_S^ z<^)1P9A=;@hk>Bg7(GX8qAEBf%hXNC?-8xik29i#C(ux0;??tsm5&8SRQ@ZWzxzvC zYBoJ&CBmdjvX?e1-HbtA`o^QyBw!xyVSKjlTq9iXu{62Y%rhq$p2|VuSbAXDT3lTC zwMx<58@k8=rcTN9+taFiiZXK9zg4}bJkAL>_IPMjsWsnJ1Vm}BIi{3)r+X}+Pc6W# zgs#Qo67x0yaiUy3niE?%|1CyrGWg+aXLS;7s#ncAov<(;@W4=4q#toE8-VxBuFmIA zhP0lcbF=G$Mi|a(AF{HEt=OPXgPbL6c;sz9n>I08#L46PN$~M~KbUd1VYu))Z^S>Q z4owJ5di}I$nU=l!gPqB|JB0vb64M{#^ptnAR__&AbouOT%f8MD1bxGtjTnFuc^oLs z&c|dF9(c$axk9*paJ+@0w2H?iZX7#1{T~jK0sd57f^9%bWZK^}_6OWY=p<~2iQj{L zc|29z`V7`k3W$DMkd^YgU2!m=lVJ=uk&cqx7}t329+ONkn(__ELMBhU1l`qi7WuF=JyEvxDA(@T)EXoKL-~Ll!shdR*LM7t zSF*xlo}U0HClX&%e$dd2N+jvQ|VInycJR4L%yS z=a>|>bh^?x0DKsS!1@2U)Pgnt7 z{AZZdAucqP3KgKhL#R&#Mh=!PTXxcSz?*n4f=$Az!u+C5j=)EaWh|L(Y4q;pz;^Qi zO}Sv^uHuC{-Kf8Zig*-;H|bKI>lhXyZU7RxqGGl-&ut@UlYx7wY@cJVPeu(kLGdhWeKp*D9R z_q3Yucnnp6GywxCQTo6w$75VBrf-ex4SD#AyBJgiS1Wi5B?#HzVgDP<^@uiDGdb!F9Lw_TM$zmS_4G&lIK=c zc)Nq!$bMc%IlkPXf*NDHr;MvOQ)nw~R0HSx?S5l#xQ~UPDOR^ULVu2HrBVYuU~=?Y z*~rha5>yzPL-iKj_E};3bF3yBq^>KblAd|_yoF(R>iS$2bO}cStWSoOtwdoYH>d~1 zn#$!Rw->ucrqU>kbe?}$M>f&u1I zyNdYdx|)xiDo4rsY^{y#vK!ua&;NEqJDOW@D+pb8`*Z~S-dJ5DiE`?W_F1g*@D?Ip z^ecv7;KMlmS3$o_#!2YmutA>`UrKswj#~&&*7D#6!YFDzrvwLrOW3$h!iF&Kjf}TU z9-U4WzPp}>nij)nxDo@Q$BHCTZ3>y1a!q3Q@9p6#{1!2ulqGtE+fJPz01yz>MPsN zq2`&q%`|SiIxZ&HeyX-Sf@))5)bndELED$2f`?o7D5ljV_`W_g`Q8MYB2>f8L~z-2 zO&G^)SCYxB;K6u0VTap6P~O_=sk&49G-|_XjB{2K(uUA4!6@#!0M6xh_5i5i`2|J9wg1wb{fb-OkGJY$?0~P_G5@RM%nsubR{Bq_HYRljOiu zqqT-JA$Cs1!~eoA!dd!6KGM*l8> z%V&z<>2yZHi7J_%UrZm5fDy7gYv{(;r|834RIS{2jiPt#mMW>%J2JgPeaShh`^bCx z$;jW#AtQuPy?JI*yD3J2L#K}-#8X-vRbD{Uw0gzn2`Eub!-EnNekTfRBxmQtpjhxP z-9?Xl)udcrs|(fuq{*4Y$;<#*ti4n|9~A0}H{e2{&p!EptBgKslFkr4T8i#S z(7;Pgu8i9zVzo$|ns}z5o3|v$(2NhsnA9ibe=Cj1Q4|gQ0$2i?c4{5~^$ewVh$U|x ziVa4ycpVSIWQMxh!Y9TAU{Aw5BMp((8@8~$A;I@Q!DBf4?|nD{hmL4x;}nZVq{w=I zqvA>uQPaC8H9OqIIXY6`?9Q3_)Fm>eG0kLeMv)ex*bW+IzU2aopS2ttCt#^y*sbqXg+LeWm%6r^L`pP?F?vGycOQn4cY zJ^l<;nnXVxhreUn3ylc67V@9T!SD1e;(1-u=ag&NOU~Z3OL9x`NKYlF;ATO$YZ(C$ z1O4=|^u3<|xtiw2=>%`k^a&8-${qn3MfCRR^cv0iAC8PTl!Oak${gB|+YXrKyfO8e zI!vsSg^dcz?QDRyVD9!ivX7!#qCtO(G-@x-JIqq?>8UNYfil!Ci@g42rhV>X5LBvH z&Wt=e{<|WHJU)QSJS2O{KLCzr+i$KP)4D5nSzuvKr$yL3YA9)^%9w9RgU&{cSMi|1 z%us*So+Dis!~5He%j>Wnqnyek_zxu0>epwWin4hqmsgfIb%M!fb9aK0FEkn zhvFAb*#|%_%z%jrMajc;en&gESh7HiK1&n(BQL&SyqTnCrQ1gD!MJii73RL@1`l8VWC*TDQqy%kAD#KAL_jSzR(c=f)#~^BuZb`%VOJw8Ap|*= z84*m1xR>iq%^i=%<1l$4Fgnzb7%lHgWhy*~jEx|YEK5Xa^~gu*ksp<7eC6h~mr4qs zgn-8qnZoS5mrNv(&6XV))vT?f1Oc?`d7p<#vjoHzv+7uSx;@&krO|ULvu}(T$y`hV zj&A_NQYLD!Mm|_LO<__PgtEWgttq~qz8qAI6;6Z4^=5IO9Um=Mn$=LVMCj`8LZO21 zhbXH3NJY7;A6H^jK+|bxMtR4;N7tGL31d(PxW5$(-w$DA!-aEDiU|NNuORcFL*6^T z)xHqsC3#N+Bh4suyQlYdf)#h|1QGdpfK{2uj7cAINVCKig4PBJM5BH86RdJI<>??1dc@tZ+x9wG8^ZYn` z5V-=mT9L=K62lea+*v^*^pvs$x}rh(v=PE2xPGqY)LXmi@`PKoCu{Mn}9 zBJ8{4M zG%{}U6{p-I;gw4?o26B^RU<^E(5|k@=F@1x_~tt7Yc^V>kW>^U%`LAyfaGbPhHk2g z*zQfq4hr`;(&`t8GRES|YM{5@=nbZUr~qj4NVMVft$K4KB38#0FU!7Sw?T5gT~PN(c79wgdr z;a1!yxIbzJt7db87>jsjIox=dNkglVZOm@`C&1HJ&nif-Nny{28_?9}75s-(T~^G$ zDlXH5@eOb@nKT~d<6+gvqb4t{77v_$iuj~%Ydn=p+K{)~di+;?``8~m;zVM2Yg1K8 z4evDVnHA)wn)VksID&7{;LoPq@L3)=W;apFC1u`yD$g2Qiy>dh{p|CCT8Bdq|I$Tfyvr{jtlEUtY0`*;@|_TI!iWJkULrW&rKZP-Op}-$u~605 z#gRSek>Krgw5KtMIk0Z6eimj6r;02)RDp~bh>a`b;R0)PtR!m!0t12v8^&dwh`c$S z$cuWql&5Bs+wTw@MD_tL8-D`hvd^U!iJQuOT7Z{i%G~(m{Atv!W^Dw-Q@e5Bd|KQU z^>1+L7SwsYyawdp=MYk0-OQU;a5{BSyn2!j;fN5qiY2z}VP`_S zeo|cd=mG8BQQIOk^p@6e>=TF#_xo`O+tjZ9s2sWi_#Rb#48GJ(SGYC}X|xyO2t$A` zVFsI>_a-cMLTrS`Y&$=1E9@ZWk^hLxFpLd6fE*5U%x*Ck`wrpt^H0_qi@**&nWl2B zBJ`F-b;4DW2R%-X%3#q`nJY0|CR%Z#8NwgbCkQggHsV#e&oL-5o(=MJgHSt2B5R zA0|2DUjQ*c&cC2iLYp#VXDH}g&KTx8gflaHlP0&8!t%j+v0FVozhAjS7QK-Ok^+KE zD@_+|@K-97Z!>YttGnaZlZ9^vF3|t8@Unlters-2KtqH*)h$)#wt9YhlttTbl-~8+ zV0{H9#Ym64U=S0CfZlRZolUkn&z+<#O#YfNm?|M~dciMV5~0Qst5YoCvq3jF`V(g( z1F|Sg+q?Cq#sVX^#C6COTC>NhP-oQzj*Ce5uMx$9ZjDE+fro235_;=%U4nd>XP7r z5vbNU+-vhB7(ANn&41&a3AmHiv8j!!}9hKv+->AeCO>Qr$X8)#`DJvwqEWU z8G59Z6#+In1tV=Ur3@7oHE~~SiuASIpG<9h=-~&^6fS0Pj$K+dF-1KcA~@)y=uDMf zX}K5quj$5w^y^jB%{H&IBG_hjO*$q5ZtJ)nfA8ZE~&nFKg&bt3pLltDxo7wZE^sd$Pg?SkplAgYIpkv z&=*!JjL8aO)nOJ8et&h6;)&5d1C0%6LaR0we*>G;mY1hJ&}@bDvPC+HWdJy(%Y)57 z>=dnhD+4n9gL!ME!ZIpga#z&aS3&a)u7{E4$4{#~8tv;(+gj^N%9Kept$kw(!B|ou z$i?2OB@Z3`$u+vy$Cip|B?DIqF`5Rn%REgOoEbAKti713Lma`L^6w?Jkh^w^XOC}< z*k6ga3UTXNGwu zx-KRaQ3xq0!<3x-d|3gcYIwLsK$=<)eC1*0KpdlurQZ1w`L6ZR3-7|2n|}X+k^1M- zZ(g-zu=}t{; zq8<)V zzMMwU0t7(f3!^L6kJZtL_(DJ191&X35l0O06kzaQ%A&rbccVs@aT+}8GW2sJ#iZIJ4dY28-Y_L+J%W>|xQZ7g zt#q|LjhOzNk&rp8zi*)Ni=Zuc8Vs+~EZtGLq6`qG%?B5mC{s(c6~kdz=_F493ZmJt1`*QzqA1Im?dMDa(fHbtJ@H!Vf(sNy|J63X|ZMUNjEI;WwOaCTEep00w zoL!Wsl>-Fw^4866()e#Zj7N2R>wZ2NaML`40gq0VRWs-_5p17W!@mFQSG zBa$%n_`ioPCof3+M>9&=$Q)RIm}8h<9-9t6I^P+Y{_K`n@1f0*sPEtm$RUbz1V8t) z@0V1&MFUWg3+!N^GDgQ&o$C#=4tb7lc4C_aq_KN&FTtf759mUqNkNM}UVywnb@AXH zpq4x8_+~DuCnYugZ@Wd+ID}}?K|t_G79}T|lr%NKe~;|7de4=S1*t5ppCt5ltSZu(&8LbY4d0Mb5m*H(bciT%NIl4?AVik{;kZn zSlxQ#Z)lekfeF4(hmPeSA$}MStemCeScif(cbQm9VBUePz>CZi)L+&y5+dUC3iPt@)*X-xI!xX)p?2{*s)TOpIV znX~kaZOuJH!5P;fI=EcMj$>z1ZU(-i;h}tZkKOAMg@xzKAN0WMFG{1|yBVzt-M%cJ z8_q0HTO`=ffa(}$t=4rf-Rf@aguwkbHq)KZs>2|3VN0bXRUf`GOdP(Xx{Lcgy$8P% zIo?70DMXjeK~Z_e_nW_SAZm*X1o}v@ZgEpiS1s$ZCIi)`G-YpDlihfWIeMXGszhe& zGSXU@*u+uZ*Z&h-$Pzgy%Ui?TvO9cvJn4^6rSsE3v9I0uP(Y5zIi%Gsv{@JHR_XYS zhqcEMsE{%z=&pieZnWs%@}Zg#s1soTGWUm&JFeGYzLVvLoqxIkpYsw#G{4K1jk+5o zt4;%QE_KhS=45z?i^MQI7g-J!6TbrJ(_icGwQQ#NtPq{UwrXfbE%0W@DhErl(0&HVwSOJU_m2iK_m)1r!;@3Ojb2Xa|J~|I zO6=N9?B?W73PAXy70F!O&9nVo&JkXOvr&Vy(W#ZsHMh8YeD56qICK9w|Ke6&VC*vbI>08AqQ3ht%j=4OCK~J zV0AB;?t8{Fj~+aGpri+Z5ooQUXy;Qxl%AhGR+YcZM^t7UlGGI4muxe9^(1wgs~2qh zP`)YI5r#?nJD|r{FtnF-d`jr~O$OA@ zW>mNOWkV_#k1uJHmvX9#W|UV!3C3c?g-CkFdE~^TJ>6_Z_`|idqiNGQr^Yvj`|>!sc@4|+tU-R1(;OUz);) zvjnexGGH@_m91h@Ux2-EpYT2NkJbDjH$-aetaR|PepG=5ar?_Z*Km&?+jT0la5@>d zQ}T(z;L3W-xsKAL9fhU0S#?~hEShXk?n=g`k6iFcH|lpWpqZT2c)vR*2Z`GZ2LbhDO(rgoGUTzZ+(PFAw)GCw&wDd<4ytOC75R6DdX zCvfMWPI3896oYF~Z>knJBn+?6gzt@8U8ty`c({Am8#*S9T4n5rn5a79vHN zKs2D#Q&NUMEQq|S5#kXHynBG|D2-qTfLr?o_HM*;RG=0mpB_2Wc%U8doK#*%9$X%8F&-<9R|VLSZ^^3o4Hre%%2PrSjZW59QxB^ z2_`*>J=|z-`0mUFx1_j(1mO=4he3|JOd~J9LEZbi3t1%T+wg{z@H?KRo9I!qzZ`@H zt{Gv_s)__4jYma%vEoZEb?#!2uMl@+e6{KDH;#5lK~XvpOjL;M~&hA%iJC zo(ZI!k#+ZKdAB&|7^5FLQ8LgZIb$1PO8M4qSQ4!RLjv^k4do4r{6iz{<29`q)?C;~ zRTw6srY{8cDYXJ3ZBsex1W8SOHS`JnQ71t$W5P>$MK%QeR62~9Ty@Qbg2&A+4vlX& zRaa*fQu{#YNsjRLIoh&cG&iVpo_)h3huA1mdM%;zr!PD!zYHn5KQ(B|X|FoMCn&Ww$M#fxhs2|SHO$R560irHp zDR%>>vN5!L-VckV)Rs-4=%gTR_mT2eZXHlvaK-Kze25=K;r}}_7z_cL0v|Ifd2I=$ zk*-Qfea;QLCo(XAD!p>By{{DiHj@&e-7^l{ZG*H8dZ+*^O)myBma4s6C87Nd%Bd-z z6VmG_JA%4kiX98Dvu25>6cTiD4$QW})(v+vUi`Ij$xE-90iXr}Kp|#w2+|{wNIWWl zjghe?)kF9ea?yjrFw3~xq(>`?N;*eBo=%GBrqU^YN&i2R#(O6F6ja{047|h~N*gh& z-1H)KNA8E5VV)+48z@@2Rk`YNF}y%g z#;U|Kt}=4-U=k14EgbUdd(l~cvO3!1QN@H;t`TjE0O@rdAz?57@)v=O58c5AT#^aX z>@!?Us#=XI8#RSyb$Guc6$mqH5}LG%V}6j#Nk;N@TIzYHO~PoYP(mSA=HjHB#=S2F z#lkDkjdYLf78N74At%&$n?(D+)Z9#wfkq3yyut=m+$xm67}2_x!Ck89m11x`47tu$ zQ=(PZ<+)kDm72I<4S~}nw+(=S_*kY@$FXhsh%VR9iYH#K4YRhcCTQ9F6WY~SQn_JG zzSP1MCztW&a)tdI$HQ=LjjLfk%lO@yTIHZ^(+=}6TZyyy5!an!+ z!4)F(ZrobXs6h1l;^f*-8FO1UZ^E0US4a#%A((F}1@_KIq?+I0G0Oga#@EX#Jf}s& zqAHr@pE(f!0eg4#JNclKsQv2bj!UrWT6fTyuxa6MjtgbW7DvZw?a*vrK<)`5LnToKnAlP^y( z>8DFR@U2rY#oS6grnRyY2}$P>wSbKhVjXlEbWnM2VfHC!`TL}BGhbgi`yl0^-}o2v zi;HDO*J;?tEg=g@~GUm6zFa`ZPX z_(52*dPd1=7x&!7Vu&JghmqW}!56&|#!Wpj$)4CRI#G;{&lVy@?&h_&Ki7VTOuDp_ zR!bZsX|LD0$#FwMX#ezQ-qq~(qC}H-=zfkoN--XKd8A76_O@+%+ySCFqG)#dUVHqm zw(wa|a9s7+{q9Q_{^lrNUR=`*6v%YpMhc;l7MjuRY{NmC@f0p~uKg;mmNA*rm?v-AE`g}XICUvsg-E) zR&InXLAysp7am9TS47zAD?s6)@l2{tBX}_>cZxWaSofuWzsHjNIl9B0HK> zBM(IZVw2LRBOJbs>8;}E!&J+`{w~gfLi2%)M^O+(cdl70JnU;%-xP7e z2ZDk3@-YyH3$+&ZIjV})B;G5uJ=G}B5(B)zHd27%pt3UdZ~yu;+QHoYmbyx#mAuRa z5-cyra8MNiVtB{7dZbQn-?&(Z%p7{t-H+j%3b3HjfMtl#EJdaiXCh|GkgTGRNgDfh zy}DI;$h4T%?$)lv?!Hcp#0e*Z`x~{omqpZ2v!wMUzA0v5$#j`(Xzp(F{N}>?iFZ1t zB6d&RM^{Wfc1ya0o_~Ha=-%Tk&+vD44v$6S%nB$JPwtT)h)^5B+vPmfi96NK3d52x z!(k=M$fp>-@z-L3x+ruAsW?I|$bSSQd97!$zHCCZiPVDq2k1&N{BoNGsxtBLVd{|4 z)Qbe^O!F7iR7IzYG5eKvIQc845!CD=)}T}jdwnzNM;6K7wSjz4BHJW>TAH|E}WtICdBVd7oV{v;baKQ?qcx!pTcFq9#%6`eDjxTE1YaB>Y?W4gSxw(Z2Ilb`%@ldZ-4XxI zCD!#G{dz> zj9?Y)19;*I!9*vnxFC}rR`q7$k7u;sVMp^&VMzYVEsf7`UX`%>=nN3tZo@(N4dhAZ zAd7d%^Fs}bVSRq8=DfSv4r_PBO4X1540|P?<)Z&@S*IZettZA;-?eUIdWwaMJhyhf zw#$ay(~Psyv6%u070yVF!PC6sxXQ@agk3o)Y}9HHtZ9KG?mwVzmHt~Bs|=fs@I)$+ z;mAi3FaQ6BZE(Z>M4Z8XIZ&6lB+lTLm+g(`YEY;HL6v&>#8E;5g3~9&eHumsF%`H9pkIRh8BIzM@frX+hThn_1^tb8cI6WgfHy5dbk6Wo z8r}^V!@L&m6*Bl7>2o{_h8Mdo1HN`dh_)7KyR;rJn_ke{RI0M)-!2|`@Ik#nd=X;) zP=@S3?&+Fc$^xv^E;`M-Yx+Fjo>IngEZk>=8(X!TT+t0Xgkbajm_$pa@q)%it&tHnT*qun6LgJp#^nl_;=DMK&>evO7_DEKhV&c zSgJjZww@4~;v%rCk$RWLGH~lJlxFq@0+tJwt&eihQo$#Kl>t5Sq!`P6+>pk^wV1Kg zH-076*xjWbYy0(NNxINAAa3UNcF~Y))X(g+I?KXK2+l#{ygPx|>2#rDTbXi}X>`nf zj-uxgDuky8>-;tQ+JV(CK0B!!A=!heIoOjCN)iw2?LxmagxK8D2Ac=;M+vdM7g36%|j1$yKpN0S59Qou#HFV> zzdIaxH6-~^rH<9m@1b~Dm{$DGy#BhdZTBy#kY(>9EafTwh19GL=GCk+DdwN@DTCEPNFcTqmeE>iYh|S!G?ksFA*pP zWu@L6cn(*%b9kKE9BsY*(}4k&QLTo_1jdvvarURV?CY#oh7DnujH)e23s}1kRyH?M zjy?Bb&S0=TYHcicy`(Ir+kHV}{_z^xZZf4{%Dae&e@9V=2mf@Tm`rcHIqkrAto z6D?|z@GV*+$lV@u4lh;~|}hPwe@z`|^;6!sg`E=5palv@(;Ru4Xw` z(11)C6LJyC=|UcBNT(ko$I>Ur&UHe_b^#{dGnGks0(D#i&$$qRU{TI%&nKiHu*e6M z)KOFGRPdBV;Oc9Ebph3(XxlT*8wF>zZ%qct^H+#O^d6_T2cU-)*4fYZPqF=>*X7k2 z+zwI>Eu!iaNYBZJz;v!YcnXtb!p?M*c*uS&&n(Tx)JDmTW_Iz^`Ggv(#V%KVb0c8= zZ+es5L2#e@c2rk6tP2l4j~sw6nGAh7;V=^0i+L68Z?p(R5?^wu^Xcf)GyJ4v=p z4qcU13&>PU_N2c{M`oqN*{x6euwH!*(9Mrr>EjHjC4<FzK+nZ^DDFNARIht8M4ysqy5O$tia<;- zkTUb`*8evg)u5ns+Wr`BGNs&kvUjf#{+3%G8|0y@k}0AJaZ?Fu(lNo$p0KpbRzTT_ zCNl8|#<*$$NDC7WRA`wA=*Ccusf$d^2O`}BJTJNm5S%W z#)Y$7z7hn8qP-56`e${@M@kWPSsdw`K`Y0B6%>;d?N^Fpyw{~#)1f*vlsbM0?IS?& z-V@{{ofaWR4qm$_ad{kf#8CfQE2de9Lg%NP(9Gu*n}2ANWS%k%DaVu%-yI!K^8%l2 zi*}>&JVUf-)07;$cZcNP-H2?34`8GT`{AE^Q95hmi;alNEM%{ImeirBtRNtt^UENw zU{SX*|C0}EJN#+QBy_;ed-1$?<|ISz3GqR~BZF8N4D-fZ$?ez%AC53#*0e{U`tG^%|IO^~W))iw*;fPLiN$CNWb0zT03loX zvRGK42l1ICd~iz3_SN{+2C*Av@b=P##5#a}2rHDo>OEa$r9^QHwh-9kz2qDZWcsHbkS=*{yW1v6U9g?HqCxSTmnN zg>P}|%`)&D#vf?p>cA?#b-(4f*cM!Wgj{g<5*Mj_G>wfq!0gzh`*Ohwep&vI_}VNt zLwVnXA=|ku`_OP->&8`oG{__c$fhbrYb2`}{uG!MT=gDLrpT2R_|rkt#ub5yXfLY~ zMwuFbGj6}9@2QI=#F@ouM@ok_RIc-f%%o;3YX# zs;M{!hFHL+kj|=Nb5rTfO-|t@gaHoFLOQoCW~q%~Em=2sB&sx!t$#(l;l?IOQpJ_` zZRp2G(NT)np;~C>?J^B$AE*okiXi0V?Llc}ue4z$=8WOGF6vxm^{$XgdlRA0MpMAg zD=*%GKXru(hlI|Ym7?o~(q(Q*4?;VK*phFc*yD!#5F$J!KNF|mU=zdnv5wiQp-Tow zkJx-b1uO&w(It$-#+x*Ojp$vzAokFT`OLteu#9-cB{6H>aOJ-&b z_-FQkf3Io&kRy!O3%|18y^|N+JO-ApR8{k)wz$DXm482ybR&#T%1pn6lLdG8_3C1~0!l?MEcQd6 zh@Egk1kYe_V&LWXO^48wUeF8U;mYnhkiEv6-eD}H&&26pVk|5`OAb}pwl=DuW$Pc& zk_6doqisE;wMG3j8UN#y8_FcC0rUGI!phLo*^e%E`gIo2x^)00#p0YIt4nX;*(`g6 zD-ip5T!lR2PY5ym387c+&^_D;KmDHL%!=pLJs#HP2g5Jv8>E@<3(9Z(9*eCz5|Gomu^r8 zCk%`c_dn5%z%uppmx(2Q5fsRiQlA-Ca1%^Z326-e#$3Pa8XC%2%ps zuP$bajSUE)As+wdwh&h-N4TN!TW;zYK;W1_smik$DA*+^=vO%qIlXT`HF7mD;4Z{~0_{O{w8 zHD~5JqXHV(4w0g?*^%;u6M~bXjIn9%$~cOM0YOU9ztt-scjcNK+)qS#WFkC8*qLhpdZ9apjr*L zf#AadsF`QEzVoQ&K2&SRU8xG!b8NUcKhwPSvO+Y7U_O3|AZ<=V99}&VBWr=ZuX9q4 zO@0T9V=DxXy)K?TJ~wcmIPtlnt{_$k+zwWqa(A0%!d$8h;u7?*z&Bf>i58vo*8)Goq?t5<`af@p^#z`GE z{FTa;<#wAcYBF5p5m`GAUM|vzl^4Dgfl}x7&2_93rCX|C4Bf}Q04RV%o8`sa3YK@i zVuHsVeHxM&n5~q!jLYz9+Rgor^R8~fBt&Z{M_s~|43y{=lRWKqTu^z0YSHb`b6w$8 zrS!h8=>?DrH&F?qO_<9?b2#pY>K+O<$UEQ2F!HC37$Ew{WnW+dnwT0Fm%|FSZtt0W z!Q@HI8#?211K;i9X=`y&7{oz2p~gXS)mrA7@Hl^O4rR@?RNg0egV-={Rk(ol4-e9O z%Bue}4EiyBUa*q(4aA~L1zlL8(9knSg+hiq#61va0EwX7q>8!jjQJJi4^74brH+~u z%N6?Bz^buhA>qgR0tjvx{Q-uextW1ey`k^7nhns80~!A66$m(#+^`UtuicBb&Bz6m zr9@k2*q+0T3b9GAX$|lNhiqyTc3l-3R2MtU(f*_bbjvW#1rd*ayoH7ZToZW=WUyNv z1bsA`)XE*pB^628vwm5?DjP9!YcA3i4I_JzdzccUn;kN7rBvPR@No!M)eKhp&JRj` zr|YGm}wyN&;X6*d;F1Km0$e%XT8IWtPu18IZ{<)vP<1dgDjxORtg@I;y9ScNuj zh(gQ)&+qKF9KT1O7|1p3bVOO5enGD=S>Lk>bxRl_R&5NMIwtesLnh8nVSRT(DK-wE zX4^C}n7M*Go&x;_*o|<{x@FaH;c~|`%>}{wW8G&EcA(+VRb4GSpm3{WlOP`9iBHR< zQ&Zt12z(_RX{rJ~NQ>Cna7YEJ%2P8u|(xB`$1W{u&x}VDkMSMQ%^E(Ev!4 zlvw5X=3wyW*g&ArqiHXd3uTIu`GGuW3_YYA5jIbu zLkt3n6Ukvy{lf**Dzr8y^A{O;#N^Un4|4<$D6A62vR!5o zUJY%a4tsf2h(zQ~VYO83_?HIdZfrZcK=kd*+Z&EBHkZofo7dl_#-9k%HTIgksR~La zguYJ)bWdP`jif91rI8%O3%3BJ3CFw`GNaYg6)DEYGz-sQ6D`y24?6Lowy_n05Wc+DS|BHntQtozeW74oQ8P>*=xv*vx0Y&>Zjf7y1&Vaz&B`hmVJI zJ2NO~qd9s0J_17(%=OaXwe6oUyXvWJErP?AN%sqPs=(y zd?7M%h;c$v`bn>5@1SVl}6JL6$NxEghQA_&`ZQ>3YX1rwss2NTW$G<&21COs6zgP z?$vlFN_HCKOiVmD(O$UK)YKrG;urCth}I0sYu*R=DoIcY&%+OlLQV;9CCTWY&zTcz z@MU)5P(+BVu&T=u1hl4}pma@dZUUp8CDziB0oCf>ha#3T9NNC)?J!zr?hrB&M!AJ*9%-p`(%dfbu29=q)P2_DPQYpKM>{U#ln0#qAxpT;%ko!J#V zr!sa0*gl*9DY1+&7~OAtEI8DJBZ;XL8R6q|Frr>va8>|!V_h2Md2rdX^b^5oMhp!+ zVt*$S$?}+^Tz$Odeba%EY>Vbi%EHZ&Q!mxQq~9krMNg}6B(4`jH02`ImXv3TBm-=ws1s$pa4<5|FakQx!iZE!S zoxgBNx_^HK_~AfKvnG+kia=M78tFh{dA?2u0aK0(q`_yj4;+_laA;^I2BFiy{qO9L zfV4n@x}H|!0C+eB4LDEX8ozLFvp8qrZeH5+O4t$OB`wYlNiop=W2GgS*1!ouw>oE0 zHkYs<8SUZ52!S)yZ%+RdPj6i30>z+T=e>Ooa5>$RQE?3#_w<`s(&*PtRZ-bE_9`dN z?0eA>zRB~%{PchxDS<{`Mw7gwVy7+PB23T|uFWy{c7sw@hUnPatg07Q#X zF?#^^kb1ficQ}}kBiAFYV&5#gqvq7_9NFpdk9onW4y?FsTh4v=Iw0cD@uN7bJ^HaA zSU!(r)9d5jl4Vlmz6;sIM)O!)9;)rz+jIyWTr=##g0PtnXvVHH#P>PM&L1esm_pHa z72o?@&s($&D7e*Uh(JB6U&%T>|F6K4g#NsM%pWfjIstDbPdzr$AH0MtXyzD9&PK#N z`aNy&$PLtZfUro));?4v!yX&LxxeN$2zL9o_D7wsNE;DvU?u3$P z5=wrB{;}f?o}kL*Ie5^|kVU2w?dlEW`8q&#XWNgn76nZ&`07wvIV%%!;ifz{Nl8U=%XfIHTc$|t1AN7{rDGX zef3&dEy}eLbj|0{HU{3bf0ju;a*x!c zxwe@WRZ7vTES^F0M452SaXPU1V_4?q=Fup#g>H&L71ATyrdo+Jt6H*EJkQpJsl$Nu z{E`{GgtX+8=jKuH&R!%6VU4kG?)A>8JT~Y-#k}G9NW&r$Uvj%yyC~F)!?HjY4_Ln3 zJJNn3n`z6nQCY)1o0qwgVCghmC;YLKPZ5?uge}$}z!!1rt=FZvjSr}%D>>7}I3{_K zWnEqI2}m|!6DhXgY-U7#B}&P>U)O^`&*t;{MOyDyde6o|(J*7o+n>!leR?z*Aj z;;$d^w*lZre3)_S{?GL8O9;OfiIOLfCDxW?w6nK$NFZ+-Dp|Bb^^o?ykC_XaHav%I zW??_!XxQ%L_|}+*#&A3#u3mZ0Ko@f_{gCcAqN(eYDCa#?`;woT_Kg2(&nw5o<& zmDzG#GeXLuP!U|SGKi{rSkl|TrY%FU?|_)6Waag&z>iMvo2iYggGLj$aSkNW^f%W2 z8erCW@=>8Qo z-h^77J9)R1+8`-8rcCCcadFkRA~jb3l`yqDfABGc z2DS^zaAeFeCV~US#t*ED{oEP!tV#qx&^vKU>Dd+Yv9IXN^DO_#4HBo2L`Ut&z+wLjqXuz^2e7EsLXJ~!+(m{-=?#(eZnNT#}B%6|XZ#f@7tRv{-qKF7$P_;N@wf?TO4CXIyt!_8i zF@$OqHJ!Vb*SEPWom}}ibA_(Y9-M7A4qFUNa{+bCpKKU5Jb^R*l6Di|@_BO28wBXc zh{@t-yTo8`RMGTQHpH~&o_-d!vppry6>(9*CQzXUoQTmrbB`|cy9|9}b_HBmQd+cX z$5u{n^P;^3?8^4=R#*V>&`t{UDaBvRB`B!(r}}^4SE*qy)l1&z(O1`PY>WTXsZqfM z>GPc!y^U(n?q4QNi4U?!qSEkmM_HP5)o_GrD&;@(Pwjm=aR1;R^sfj1A(QK4U^-Mu z=hMvSh3bj~pLOo7m0Nskfa+W}@Ti)-)rmOT8^Zv+`JPt@HvB#kRZIECCPxMQbOjr` zdHNQ`;r^9d3@Dl3XX?(*ZTxk8aY>*%@2$NNZQ$A7gB#l*nTn z=W`^h_IuHlHE8p4rxW@qa?G7c;DZvwLn!Tlo`#OL;B$~`?LRCI;nXrR!rpKRRlRGR zcm5;CMD|hHoLBhY1WNX|5p$|Wmv350;Trv0%C?9hku{qKcFcA1QoyToWMqg<83 zYc`~8fR0?OPm&?FXtYE$7l#RjZQ*?G03yC`gf?s#Z9@C>O%)Txxl6e&H6ebjbT5Gx zW3{W4XJ8U{@}>#F{oQcfO~=Z>nAB&R3SfF9IdY3)x!zzCRRRWn6I?yeAqJ>{GaBkF zS;RwJ(Oc|5ADIX`v63Wj@9+6o?avO^SpMQZGJRE^aFj4}0E6XE5D8D;g@+ z>VyLmKaedONUia1ku%NSNsBwj0u9kEg-r@d>awTXW|;?5_8+(B3b&aCREq^eW)iD!jmUu!=#T2v zHiKW4^ipXBM3MBl6`E8XamPSbyjYEUbRZK?FasR&Ne;wU+WcVr8CGRh#F{pyclIuX zS8cc^$!xnzV00Vxd1h85;1lb+%i59gCZ6p>~Cmn#GBZ7 zL~U#6k9)r!mdkQSB=A#ywhtyXanegd&~01yEeD6Kg6iiu%g~7g<)q&yy#U{N=MeNPAwYHO_FftnIEJJ&BbZGl_FFZrU}@Xus@k z|4D}!vnkf>FqZqIdC39iLjry5res~y?aZ-@$aUK{C@S*@vj0k|98 z&nKb6PXo6pZb9}(G~R-Pv)fT_9}u1joxR)tCk$NQqxW7lk5)WZ{vmG64~a5TjDv)L zoQjk^7If67octzwN>Xyf4(fX6|vor<{ zMKvI`ULWZ8bTJkXS+K%}`JXccc|UXmN_f)j6m^AT{mS9Bs2W_&JV?7hhwaR`ZsgZY zF{`fHh~vKLA|eGNB=SeZ$t*}PaUf{o<>>K6w3X_qf;`r)Ix)|O%eDhO$is-&>WIyj ze$uB7F24vU+&bJv0(X2L1rB#PfYv1N2 z8pFQ3l~$l(fLi=p6jnvsW6?8F-d5H3?6#ZO6IocBMDXJR$1uPxg9jP8@k^!{Jauh|KJfFhCH*EeaN-;3wVu7Df#>+F6})F+i_9&nwuZ{z~KdA{&V5FEBR|~Y zO*;$|Bj2|oE)TO;!{|ui?a_hs$F}Ef%Q*Iikcf$d%&d?72yoS(EYcQ zF1;Tk=3^91ZIHLWVV*HTU-z3@?`^e+#0#p365?cU2bf*%Z}&Tr@vtv$Gzeo_WH({! zho*bWNH{XCAaY=9=^T5n(u$+!3Wz!_(a$(v=?J%+obdP+*H?-Bbu$}%CxL20TA|_X z;Q>-W{ID*lvlz&FKAim`gjEpO!u_5!W-ST<J3!bON zKhSFx90Le=CZ@IgXnE7zf3sT3)Vm98Y@{LlBWO)I_bW|7bjg+%T$8BSZ*&C;J`yRn`aF;a0kev)Q4M%d7=BydN@7HYXw0Auq#6 znn6+`A4T?pCTfb;WZ*&bc$*F-y5mYl^NR57F9dg_UzZkns{`6FVjCKcMEE%nJMBT* zYS^9e(N-Mb0(zy#B+h^;rF}ne7JarjJ4ck&NX@>?&2pQu84K&^5xTLlaV7VrpWeZc z%;r_7?Lndq3MZl@QEKO-M_Jm>C1WQ875pqsy}~93}`JoDBi5IX6A1d5)!>xQDaZrvgbkv&q0&q^r#bI4!bA|>}xth82tlS zOLe?dKj38S0WzJ%L_O5+{$VLQ8>I$TyzA)mZgdmAQ3kv6YaXJNFN8t_Jb)cV;ce}H zlRb%dWLs2DBhoA-fne6jNX=M8HCSQ!^(?7RaO8u!?2B}F%8_wE6i@H$Zt`pSj`T&A z%cB=f@re;AmDX(q{mE*9%^OHsi?V9n<54mt+L^#bcTlLrc+`JK>4&YioONZSi|~g} zz(JLb#M*d0ncx|YMrk8ft#rl=$K4(yJ$dSV@I8SJa>R-6#>4xu!#;%d}iAz1M6P!34auRGE>pHo5wt6;6# zGCk-zJ&D%&(stYG^dhP=O!2TjSnxUTFkh8Q!eD5dKKP90KwW%$rQl`ORw2}vU(DeJ z*Vjb2pOmz>5lH?l%Os_nfaB{s`>F@2biOh`H)WA9NqhE0i00hVf>x4!tx7&R8S_92 za&Tlf=+@zRyuIq~@g4f2{hONZuI0h%!nLyTryLn2c&WvN4J zXiz)1xMaiT#H2w!-h1o5j_t!cdrira1ECNC=+TW_sHN z1a4mc=D%bPhUzrpL0xBKI<#EVJmWsH@h#u&p}<@>5+4nu&5*#$YgjyM-utCKBJ9LS zI(Nmo43OQ%(blag8EM<0t zJA)zus|ae>UTfRIA@@Y=+q@TKo}(6D%*{J4LD0~JU{sg}P{N;-pLTkSJe7QW$BnIi zGfouhf(*QuP;kSUX+;rQUmAuVFo6#N_LhK^R9AH^MQ2wbL*?;V{WFz6N^nF{!aEGLa&CkTbi- zn_Tbp1#?ePuwb)QO1uyFHTj@xXKRm<&AJpjaIffm!tH;szIR;>zAbbwiUBl}?7~}V zRc$!noXqmpw7JeS#=S3ptZtF`@Y`07uQCc3Xm9t}4O%XbkQwS#U4dlJ25mq4BXb_a z_ty;1wG&kbAYU8E%AtY>5>$vx@QQH9$Xu4^Y*-PSv^tBQfU|#lK|AIeO?o(jdwM0- z4p}>iDaZ&mf!X~Mk4lLofweP1+Ya&~@QZlujzTd9Stp+`MS-Q9 zaWZ%LyREB0OBc=F{*-O6s}gULKb~N$y;xU;jEe39UtwxtJuH<4R&zX7^udkptwo}3 zA?hfG5*3EH%h`@=Yt4bUNqB@0WJkd`7xx;TqT*!>+Z@>t-7=2caa?7t;eStq)!|~C zcw65BBqXlv&I=K)2`Tr>$Q3yr7%QFnsh^1Xa%XI+1TK_K5j$LVT_vp(izn+ID23X` z3LqW<<={hW32j3|4N=#k(9+{y`+`^e3gjUVQ_XpNU3unZ?G1yUomXlo5*U2SKBi0i z1bnyYijF>8Kg`@)-W}_Fgx}yTQTD9qQZ;bnt!fc-bI=`O1r70Hqfsk+q{uwep;1dA z#(hyM^!uq3>kBr#dE65;y2d}3R7LDHTxRGi=x}@HfDSMlPC^Rhoat41eFfAeZ20EV z?l}kpo*=;qCPpb4XCUfw>UJ;~&F>v?nhKzh=I7xN`3*yZHgUG_&$C$%aUd4Gnoku? zYa(KA7f4egKv(D5o=1BlJ)+p03W$Rsea*3IIPq-bj!z<2Dc7_&-@2T(sQZqy`fSJ zy`wf&p)1x-`J9UN*EH}|RFfRtu@ta&|FgGq)!t_T^kZi=_rF!r#K>{__J*}R}J!!rinUREP(osyQZUuNi zvmEu01D>P;B-DlfQT?Ba#f-z-sxlbpt#3Q)W!Bv_KbEkG!eV>e`<2{1aOIO+FaXGK zJeil3B$D$8Z&q|WX;3Qd_NJ1!2lf1ag|gzeYwR#tiIB8t4PMCQs;#5KKz)EOAvW@J z9yWK^TiW6fx7I*>K5RDtyY47;8_V${Y=1bcDO^`2g1|{;et-}zTrNc+VPRos&-5eTMb5;+}3gxwEChhX`; z+;VDWOuN(SIVHaY6li|za9E5xg41wEaT3oNyBmm!NLb9qHIJ}6x_>Q6JHJeM7xaPA zb7K%{P8-)vol)y!7gFV_eSB8I1b^FH$K~UM?^6~t4gBs)U(xI{qwug_Ob|XnCX*1X z!)k_uDxlL!c-`NfZisMQ_a|L76tG+*KV^H@nt6^(+0=K|RwmVE3&9n+7NNPIYwgE# zG*rB$sA)j~(gSx|2CL1AjtEjZ2uf=GyWi_6K4X+Lz8wF`03t4ZgdE!A46ic=URO{_ z2u=JoC7E5*8`q;p3g$jxA0Z(-RcH_cyO&LgHU#&%j2){qDnrd0omaEg2Tev zC{tXlM=#{=Ik3bt!2M2_bFwW<7V+daxLYC`|!R1&rC~HW`X9?m&Vna(DL2Ela#&LPI)#o zY0NI}E}}+UV-3Z44da6DO6|tFi(}4Yn+zau)romP6as6Mwum!`_V5pA=ho z-&!>tod7E%DwRH3eM!L~4e=3^j;g|%R5Xc$!~h#blR>Z~&ZY)#*VIQ4uADKHi=m4a znt__u8tg%6_a-0>cT`{dVWR6)-ljAG%C7Pesd*!G3#RZpY5s(&u1T*ZC%SgW^kNjf zwTmKRlCP>;Y8UHMMb>SJ%c`R{k$%0SGzs4*-b#41^| zH2`?Jw`ZZvirzU-(Og5H~%O)Soc=wzy* zP>s}l+cH68_PC@u)(P>T^JXXwo3@P$J>K*Bk84I5ZTF5o;Sj4&J7@jVI6W7J`cxP9 zOGh~m4r4<@b&AkLx4ZX02VYx_*^1$eXC%tkas_7=RGgP87y zOJDg_S%15rI9yNIWYe1)Xol*&9YDx-4j%aWV^)NBFO{1~lg?&1GQCRYFcxZ9jzO*p zqI>YgGVYB&GO6h!L3C&F9om_K!Ni=D0jd7Iii44%vTVGeG+DRvcNblb$2QpsEYMa$)tvY zL+`$8Q4{H@+u>~7u~@!c9i&_4h#P|hUDS@YT7?VEWxauXgl=wy%k%^+m(0qnZG>t; zadL@gkT+bPcck8f6}s7nt#;^&o8DUaolN9~XRLKHz>3zC%%0K-8BQbxLAJ!m#w}dv z%pz1gLIc`Z8l=UtWR#5EiBzwbO2qIsk&2p3)l-_sIo`uT9&k55$y*k_)iqUSpw% zmnavK{`%<}Q)v@@yU7 zde##GnGa62DZk#2eDcKs{C4V2C5IX@O_!Bd>uSc8F93rh@&Na|ZdxHqVVNr4b!l?E z0WE&XZqhqz0)ZJj-H5?O1}NaIUL8n90jDBB6(``rKHP|hDawz(hx)C;-9RGJ^qF34 zA`+Vh_hN0cFt&}^EO{6c$`VX)d;c7*vE}|*wm!q1bxi6XeqImcg@9FN=|2SBx;Ykde30D2)LCD*Y)@Cr&1l z#9viBWprZSWD4T{6w`YUP9&5f$v~-D+6iy=VH9EhQ7lll<_zG)8dPd!05kR{3Z>b- zOvax9KSooT%V^$>r|}Cy{i|~aBtz}mx0R-3bOA*?tk4^}n&kAv!*CA-xP^swo~1IIHy`j9HG{Z5yf?W-Yr40}o0=nJv7hER)LiSB@6xgW z5ToYvWf+CH{_Z}ODR_RB?(zVVS@tDF_fD){N{j3R?))X7-Dh5`sS6M-HsHff893$G z(*We|J|@$}^P)o8lDtKIQf(t#X{dgGw58U;Ti>0S#N_q>I?Y2Hix4s0{+IK44`Moz zQ$`8*;P2G_FA-&qnW^l^4o z6Hb^eDZ`#4)TThmd!A~6d*TMu3QQzbqiwuH_;qbIoVLOt94;z+5KBmw50+SiWSmNd z|G-M?7KL*#>d>|@4UlN-6x(ls1TgKCrs?8=KzB0!dq7eohQ7-SmwTGNKH#M+~BP(2I+F`N$T5U~?CzOBn&*vM< zH8@rW#>9cUuah*02-%b4q`Vy`t3sCwJOrqWjU8&gSId5cF0DI%MvZL~zowUA%S%OK zdK2_{81ppz_2lDwNolG|YxSOrn$Hja!6kG8F-RMzB@GCX%fqBH^!=mkS*~0ftSF)W!i&cPmdqX>!y`97Z3so^Aj5 zI(uAa>PcMiqVxzJ3g-a2s40I{J;_J1SGZ-^U*9gie^5yK2zB@K*PM>?CN@jHt3P>s z+}8rb4jV}6SNO3=+M9*%QP!-w5z}(WX*jhd!#NzbI&Xem_KEDJH2QM8^p97jhOD{Z zlcWwk(Fu9ktXVk;!OBu%=@eqt|Hu59-dXyOU}B4EYdsh*993wAH*d7&TNjo!`9OL< z#S4GHh23c=)A!kHTGm2E1$n){oquL#0F`SiOM*0r{8TBAbXrYjd~}H#Pc4Rh7YRMH zC@z>Ft{Cv|LamqC&NLj4p^TnH5rs_=6xJEcG|BV1){oKrFkbdAce5de6PH1Qe^0m^ zw!o0gl#)#0(sdf{->dB8X=;!l>awNu(-|AZ$%S2{X!W$LZoI9cv6Q>@(Ht*iuL^20B_l` z@hl0=3ABGK#m!Jq^-^xDd8I#?w8U`SqI6;W_}96|pCJr)gaeqUmz zJP>~xjo6J`rlOa(bqKrQ0oISQF`VuB0W;iI)4UMX6)m-Bzk4|(p4!&;|X$17x7j<$uZ~%(X*Vg=oe<($y;K8(y8d3W>-|JCCha3~v zXm7kvN8MTmsz7Nswq02nlwWP^>XN{d=BYqbjt&oc`ysw+=MAh1=k}|EBU4+@GM3jz zjg>wi@gbV2K9Sw@vk~kvAf(^3iC^#|BUr(<9^}ta1T?$YG0X>U>uWPmuYi#Lxsksf z)rP8DPq>OJCofoxM&Y=X3gvp*P7b_pzSV3OZ|(c#H}0e;b3P&<61qD8v}8e$Lp4AY zv;-=&nPlRZxgNoLmVCQSMM&i0yNqIUOqfT@pVy|TO(k4i=Qx1B^` z2sd=YP7>I|Dk%SX{0|g^uihvrmPfaTmdpgpN8R)QIoHBzl0+kELOI1=OZw|}HH%P@ zpnN)Tk#97@wCMAb6Z!$c{P3G{TKYD^A#VdqG8D({Me~7amN~$%$jT2nIHz!un61LL zcizbK$%7N~62E&@aVT6R@@@_sLXYnpf5eM`pK%q|Wfq{hm)QSyO(ehMqfUv?A=ySl zQ&YaNJksqHl_VgW_;urYss*Z~zq`A+t&HH~(;EoZUw3FB$B5gyS+R;Gmxt%XOSKjR z@vZB4MS@t{-kuv&SE;8aK&iLusJEN|L*kL3#XbWzK-+U{lo_)CiI;FbLJa8KV`N|7-(PSabg|}x` zO!eij;MjGl!qW(LZZZdlC+;9`!klbynRwsc!i^*>w(^wI`P53edoeAzSy0EEwMLNS zy?6sPd2MyXfd*71?;V=ASHi*$&Bfr?XdkvgC4m2i#M7{}q=+qze+q5Dtu`{!{dy)Q z=E$xGIGKghl~!XGwQ0PXGGPQFn&3Cv^H*@>qF@E;l0#^7we$-h$GP1L%mRmcM5O$^AQB3_(xM9a(?o3RhOi9CX zeLo65bI^C`EQ2bCs8Z5-MrV&15%9Ds^qhM`T~vDXynT5IiLsp)Bj7&pb|_ zd;gy03uB~~oUM)+xz~Xih#4@OWWz~=&c9sA714$UnjCXglA<{!vYh5Q;D8bs5uC^+ikv55UTxP#x`V%QnMGo>$=aO7_~(O0zhB<_WvFs9*22= zIBdq&0*pcF@eOi}--_%Fv$lHdMb+j5<6$!fTHdPwtp{Ae#>vLd%C1T+rSi)2!#&9) z$;YG~UMMwa-EPrY&(UDqoCen{WuL-Z`_ez7+0t#91jG7geCE+o18^rsSCfMFS1rUC z?chpRlqp)xEi?TkwC4=wY+!_rd-gyK?HADUvzG>U>|Kos=$dG?yM+gng@I4^3 zHU|cK7}VS;%IG+vE~#BhM^oOO@IYRMTA!gfAZubworLsQ$>(+=)3K&56N>PTG3Y5U za&%eC@hr0ttJrm&aM$wYyn81%{sY|oEFUUjENw(h9u`fJd#tnJ>?S*&TLZ_s=@U$7 zz7crxrPk$%(_?ehXe{3o4jv*&-g(~l2$0J5ZhhmMIFIkkLyQ$+uEGXZZJOaE=PW1= z74EWCJ+nXsC%!&{Xcv$}f>py}=)AgBb9h@tT#ubT?~v$hb3_Z)qLdqtD8SMxE1{bd6( zMZ9R`Cu&TqVRd=>A*7Q4`f*c_>d% zi3p|kl?;S42z~%s;xm!9>TB4?89A3>unZpuC#D|rTNA@G407~H=<$eED$;MgzF5nT zO?c{c(hU6M)#OGh&7J!JE$tPCIXg1G#8(EZq^b&>cvl$HmcWJN4U-0o ziFB(pt{HTn%<&t&BfK4NI=a;JzhbC5MA1>9XZY^7G94ePWK*PWtd5xakxLXpXgJ$i!VLI)oZckSwTn4?;|S76!({C5BiMRyUjz#$#HIq!cw?$T*)KiE+MA(Jb@`bhnb`5 zuqS>1H(ysl4i~F7ltg1Xw?VseE#kS=tyGL|4jgF;J19(gx65_jo2K`MVi-g+2&RMk z5QkC>Kt*s(0&^ZF)KSZ(|DBuC)-%Hdl)XVX)vET>4K&y_mw$INe!U6NsU3pQ;43Su zu4X5Q&~|EYwPVI#THe=$_`||e^~+$Rn^hFMr6M2<9}X0Tzdkex5aD3HR z-Mq1{7flSu?PDKfLUM)nGUH^|sQ|N$P|d7VrN6RgKF%Ed~cq61AR+k%2Yx zq`&6D+$@Ywq*17YyMwq4`M?G*c`lUWH}9i|nF&TEmdz)i$^1evYr2pQYH+k6qPNB< zJ}S3m09KyeKVMnjNej1K6!KMA=k)c^&l^|+-RU^cN&JcYk8w?lc;NKL>zMxZEPRZqU?Y152SO;Zz{d0wB)Qq#eD{pj%pns??K;sIVzflG(g;KY`oy?cH5j|4j z{T{%QojD9W=_k;_5n+7l8LuTbVq26^^HC>5UPI|FlvvP=v=6c;S^Fy>TU@j=t2n0I zlS1jO#lsq$5u(u*hh`_=%>In+7LC{%R$$x#^r}`E)<9@ED6X{ASdRWf8%8?mu6+NE z=AkH=KN)Jyq6u3l%YkM65vo{>ln%Q>vlIh1(VEN7FkBvFeXX@{AKfD5!h3$qiETgC z%;eA15kStsmC?e+Bhn&0l$^@oKUkMA(@^p6jL8}PJQ=V&R{4}pI5VlUIG><}3^1{pBry440y6N4cU#(To?L9OKTW$#$4S;yEosRng;x#Eb zNPDBTf)f6p(bcMZlt=aT!u?w%`c3ELUUKC+Zj~X)GCl%vC8Qfm*} zk_=2vi;5LA?I;Tjw-=UV&v2t~!Fzs!0s}X6RVFfZj;d8RFw?CYZXQi*Hq!O|nt9YR z5TDZe#MQTWImA4#03-bqqipm6e>OEzdC%oV9|;8`7wAO>$I%_y!pc2P&TK}zkGi;_ zB%Sx&NmLQTOnLZJLoj98D(Kkah8LSr+G! z{jEo}L|yQ3LITr?YIm6;)NmST11f}hgjH-gcy zTpgcCKi&Bvguz{;3kw}y_M`w0>ZXxnQ#6^6=RNn8i)T}{Nm8&?xjrbQo*?H+nK6Gi zNwVmcnNuOuxE1~L{T~)ao!WT7>dX1M%25c|I?R@*&&_@MDuwNOOIaDD5bs2B_CU6`zCJRcrR_vg+(c4#Txoq8aEy`uZP5 z4LAYz93PpQhl6Bmj=jl9!LWAh6A~)Q$cG<}BdFMZU(`z;HRg8-_16PsP^(jsC@517 zzN)!w=cZ4aRjJ)(PG|KEloRsp1AX##%SupNYTv%u?$y73d8_LhlXyyvUMoVqAGQINW*7$=|y2j%#Gn z{6k$BYTitsiW~t%o8bI*G8zDaY#$q{=4Qenw3_9PLZKW+$7Ay=Nno`sGx~l+Gvayg z^au`N3H>nvDh2d=ju-7VyM}vo%ho65Nk5K@DZaE*JYa|d5sosIQP&2Ycnb7M*@#S>X*yN7TexqCZ)eV5ZR4!Wda)p5y12u$n^y#)OUaj7cb%C|F!6I&h&$+{Dl%P_Ns2Thm6$ zUiP~mRb57j@bO?G=Wk4>Kif}%g1b-eaj8@-IGC&70}|fbG4V)N!2R+dpwUZ+U9k>Z z!!6JLe#JXMn4p4-n&4{RehwMM;ao8@cK$Fpb5SE-?9gsy8-(g#*9$V40;jtW$<-ts zW_0>lws=5_J(i$79%v^~9dYcN)uz<|D&hpD_F5rH`~U(WkNG?EjFpn?ha13k9?=b~ zl)-xn(r=JI)Ox}0>i$k>XAiQF^-*jUAGV}Z@FW`jCbthvj5WAoM)k{2fd>K-6B;Z?$G-dRVBQoTMT8C}O^e-tI zTK^^V68dgWr&!wAt#og&_nqSxAK#8j*LxxfW-fM2H0WD2;@~HbKLZdeURREsUosFz z&sHoUFUq4FDxgBa#(G}>I%@^0y0x0990V0ilWo{H8+8$-6QnK(XC8-rSxud%{)RA5 z0hM>eFRT5o3vqrOKh|tEIrY&~`98b{vbpGXPH2NX@ACu>IZ9hx3i#eAD=l{bO5U0p zjBc`%A88JCX_HF~9de5Db;<}eLhy(yfi<<}-22=@B>oOJrl|p|-ReJe0l|#SDjQ_+ zLo}Hdx;T@%7{T%mN!%+oWp@O$ScR`YYaE}4Vb=mktuWo|=pVeh&JspKYMV_p0^=Z3!VGDfpPtV*+C3uY-M!0bf>mFWD$>Hr9lQgT|0m50 zxO2SW29s9~fH!H5l#O1Z#emCXJdD+asilIwEgD(0olQfG%`6iLtPfavVT?Tm8>~gOmy%PyhS>m_q|o+$XF8w7~qDK*-c3si7%aB22mW)WE4(0!oC`M7I2|6AP;$ zt006$(@Yes?I?Br#IxqnPO3G6H)y)yqNr)3(D4Mb*`W>Y#l2L@G}SE*hi(L$SdIQv zA-dDNKhG4G4)j0Fn8h}wC}hX8fwsM&=Z-U$-Sqo*xuM50J%W^l`hn3&498#3EXP?{ySwoo9%EOa8zKD;!8^VVp z+iE`sDg7W|{X^VvU9RrQ<41)lO9Tq=SLeS%X5`9B9`0Zf6L~$?W5V6c=^9rHkC2SR zlf0E0^7}-EADX#&rFO^WOVLvrPgW$I$q)?kLh*6n=uI!XUEP%?YJ=1#6;X*wtaL+@ ziePN8!dR9=!)jeskqC)xoyp9cN#Us{LgVt)5%(J*Z|o;0*%M3g{;Q?!O>Jvus7~v5 zULg*)(_+A}Vvag48NP#oJ8wh3SWJ0P=-3U|4D{Q&C;%S#Re%y!cAZiduXO%$+FkQ3 zihVOws-|IbQ)CjeCbxS<9mFh^HTs;M_^+)xoKZ*E`DxdaZ9TZ}Hewn^d0l$rfqnnS z7{p(+UFg?M$jw;@w|3MSpF9ey#Lu1`n1rzTGFo)R+{3I2ulj~+MSOhC<6Zoz+v_fR zCOw?DDqVwJ=Dk5VzhW^T8;ax~1H|lz&amo3K9R?o3_$Fo^?3Gk?@X4iEUBytD-;jj zKTJ+!)#EbM3{=xhu-AAUw$-o`7(Zlm_XFCW@r$#MC_P|>`>PP265xhc@H~1QxvWon zjsg#?J!i)lMVdXeEC3e7|VtkVz=BQp@kh+6^oJMPW<$yaR5Fk_b-1%!S zlC?P0iwCtj?aGDJ&Ab$ZPpER3E!gomG}mR0ey^RFQUbc; zJskX(7K!PVZ4$hhVSgbHx`%Eld2>tSHRwI_-7s`nR{WPE`O2d4C7X1UblTVu^TF@B z-730BtuACt%|%!?zR-MpMj>7km8Is!c-?aEZe<%**!GN;d_YUm)C{8a#wUT9}fO#C4*Q!L|H8EE##>*SYYD^)$cm?q! zla(VKfSDAqqO`J6YVPg*0~FQ}B3=BDT6;wNObBO_P%&~P)g}LrK9w?Xvov+tK{(`V z_Wa3}L*zp;RBP(pU#RIgf-Lgrb7Xyh)AejX4T5V)Fd(OF(8Iw48D%=@3dhig4itC&1(s zsNn?2$r{QX4wlNMUGKr5)Je#>H(YOuw%`FUu!kZ>n1+mL&_N|S8fdeetM^?IUMDZU~y^6H*D z__sA4#P3eJcJ%ajC4d#*=5#lov~~Gwy0+MGnm99<6Z=OLX=q^oE1T4rhmW7`4P4CeZwjhC$2)Y4h@VcbR0}n8opp{-lONd#12|zzu8J zQ%LfYOgG%Mr}dO`rXKVGAz&!ob)xpmxjdGc0*U$qrPHLCEJZ*lptB*I???PWXwm>O z0T9FECl5_gF}8hXqiqD_CxZR#AlrnKak-8Nm;C9bZ)Q* zoLPzwBKSTf-Fy@vvcN|0TaSStKA|o4&)ZI$#;W9qmn%|rROIwPH8af5vVVyMpx|gl z^$~3`lt-KUJD?8Dj+%!mB)gQgYy3*zDeeYjL0sd)HO+00S+>t0w0u)U4Y-T=$k3qF zQhOYDXhk#PZx0L9z+fd3ZtW;3Zc!otQ2X2GjzrJ%9qX#UwGJGhmL=2qbY+aq)K>U8 zJpb;SMH8UCCFHtQ*IfVFwe@6HHloCbZ@|YV-8e7M+eN>ZHYY?^kHITOtG#?VajA+L zGX?Ud4H>q+du&(uxB)57+cp6~-exMN30&N7XGw}dJ?#czU7YKBC`Rq;ZY85}l7lmB zcEyrXr*-sjkt#r?nzT-Slg+iRei(aJEZx^hu<6UQq+Zo%687QK3k-0cY5lSISTEpu zV;{~xNp&jM+kqvoPE&BWqQMmeyn@3ruu z0S44@!wJpxzwqb54qJV{1C?@O28|-XN{YPi7#^<`zB8Z|6#^7M5KlWpa>_MzQeE3D zh)WS7q3y^)QIT=>zP_Im^_0_cihyl(jU;!#A~yUKI>)@{^g&-BVqU{K9Tg8zCIM+5 zjspp{E>ra!X+3$bGveE^|5p@$1IAV>~7*g?hd8TCzE5S{8tbtN%?( z+UD%*)7VX{t|{#)mhP;$zo6Z`R+0ChVOxW?@^!FN8|5Dq0d>dXMi*h+*rRaD9KeQ^G zCOx}K&w_f>2Yx4-jPz7`SPl^}Hi)OW2F+5iFxb;po@FFB3PJn-SDXD12Tgv}8S zd|U-BW-^vKUtHS9E=EM{fgQ-}XfV(a@csxN=)Lu_7(n`m>0HFc(%o=@y<)0l8@=Pq zU+$yX{iM?VQySsn?Itdg4H!4h(c%;d(QuW67?Dx#>83Kw+yDBuN5}c$!u#$nM<*?F zyAQ}~hVf;Dml~+EJ@k2A3^z>p97yM~8kQtLP&qI?W@j~z>T|{HD$#!~QtWLG>RFi2 zpOcZlimGDje(4?(2I=)%8$&{I?kKwkXEer?e-O6;XPO=yVR?(15-w|erM4*=qSuyb z{R&M);B-nTmxp0b*R;v)*8VC3V&j{3Y8Rl?2+~X`VU{%boe$YuB;?82XvSA(y*UgN zq~Bngy+>U@j12UjVa&`8p}FTl|db@iS|$BFJ19=eu8m`L4XD_wXq$jivk z=*J?|-;|6|b{}0hKE=2?CrH!A(8AMFg}mbQ5Sv23CcP&k5$KQ-P}V1zJ6#s+h=>#a zkrK-{9G=j2j{Ul>sv8!_t;Mw*+c5F|+BUD1Q*^O7z%*~>Z+`0)ZP{8G;^c*L>FM{DKJ$M&v06)a5_WS8!A5LXPQvD_ z5F1@7vw38UYG5~nf>(fdk0Kpyh)_HrL6*T=Fc{jtm=1Ve<=N=RAd9ops)rb;p&_R> zoHDQkR?|0!>^p++yt#r>vG&a2%uQOKWSB?hrm5mT!Ec6>rVE`vtHyfL$bJv<#U~=w zKGEKPssEc2)o0eRv|$6b!*{@FfgEh2xt5ais_iA;$%m@2*VZ+_1OBgo131ZN5*lG; zFZpP_#<6)iMUDl4xzr#mNi1FFHfL~A>vhXO8jIN<+uid=r3+s5FLjVtxix9k<;{49 z?sPvUeT$tAQFUFs(wx+D$;R$&v_**3DyYezfameL;vG>&n%H_3XF6s_{7|EroxNG5VrohPSG<(~Q;>q!k;5xBnZ{eHs3 z8Ua@UfrhmvB!nwrisxf0rt!XSb1V@FrCpg;<$vgK3DZ$KQ;Aek2o=UF7@8-DOT5kV zgGx#6-9Z2hAhZZqv1#&hy_e3D-TwIVza# z&WOxwy!SZ#nYaiAjZPyoIp+Ou8Jef;SJmL+vS`VANjdPT6Js%mBeaA_3;dJMpM@R> z2BY#%O2q!4h`oJ%)^(VMc$HXttqX=GB`RU4`+fH(0jy=?!z%|qq_OsnVWaP8To|VB zMC-wR@)L~01)j!?`eYY*G}5PZrdHJ(qwu(52+i4&Mr3_E}D)X?+okp zodxm>m3Dqw8VOe4NtSl+onl*gR1mB1im8RM^Jxt$?f%$Gms?;xl0x-xmtXkGaK0Q5cDJ+tvzD~9stw>OMKJdLx zP>qeiw5`by8UL<~AReBJsxE{2NdsIDcZ$5!?R{v4iCe&Ztcg@5l# z5Sz&VrsE3z>td-*hEz(A9~o#NFza@zZ%aBZIiNE*k!m)%-zELU0gDL1AwB>+ zS=*tRV6$Ro!}%bK%isG`B+uLL%$V80Toh8-4)zuu6Zf44I1u0`RYfh>wT^-3_4iV^ z4qT4o=5Mp-FyKm~%||iK?4Y>gyxJ|7r0+qe;gIGwll(bIRcp5U#y62jC>nd%c9p)G zvZE>+kH_j*tC%zQ5tL*!Xutve1Vq+c@8i41!B(d13;fmeChU#u&50ZR>*G4}1h;V7 z6G!&l`g6|Cs&b9)?h?nE^Ekyd_NKBCgq5eyF)PkaFENUNUgjDm8-vsZK}ejJoa_UN zOGd*Q6*m`FxK22xq|0?5wZB4DS=ZB5EuwZt6oo#;^V4OySXCz`3knWils4W3TbIy+ z?dz9a2^N|bvP66_{HtDV;%^H*77yJTOg4_Fnlu)byosa1Bp!3@Lgv;4rN%g3wRW(L(k2o*LNcPSb|C4+Bfh38GE%Hs> z_q27Q2C^EI2UP|Vt$7nsfD#?>ylg@(HID0)X*GfI2R5|!!N(Hi+HNCAfIoz4FwKx?*|2(| z%SHB*)F0|jyw#%G~WaA9P~_oU;QX=FJniH+MFEKL;NpUjqvFMoOu`BXkt}sz zE+?v}7Z<`+ZuivH@!IoJa!LInM#|2&meX-8{EIrynajc;&$5l+5Ppbh7(gWV1^zb5 zJkGTpFIjAuMP=XlYm}fHT&ZY4P$|G>ew;$Ytb$LwP-b0nvS+ zuza{wRyL?^Y9bq6A~Vlm(rhr3P%`{&Rrl16FnsX%sT zPYMmtzZZ>g6`DMuh292=OO=wbc4+L<1 zRdjIhScRlQl^#ZzB9bI-8&OuEJbgh*~Ht+J$F0sb#_d1AUBk~27 z`r7cZ%Ahr?bt%id(R{KNbc^WFO;C2FO^1~FjO84vFzqd^nwt9aY;4N^^(Vdu7^SkH z++@mPP)e`?gk=48-SQ;=r?mw>Mj#>Ely(=z$)C{7NcXO=`g%5CTY%8hsy%a94h>j`lx1W$_8g(_>KK)cg9N@~<-HA|xf z0tYu$|$4?+cy%7$Pb{7eiV4nYA-ZeC;n56Ih?O0E1`7n zI9=vd2akU1(n1A;>6Qf-6Lat@j~TuA6_wVg5mq>VWA3Xu?o6ET#*sj#Trl8qEg`Z7 zi}qw0NC*&d65EIobZIjZi}me+q~Ne2D}021!nLt@T@h2N7)&b@xE7^hy2Vd3biJ`| zn+ftr_f|^NCF12%#YAYPZW}QK(Ec)MKKK9}YHLS&d}LvGKB<&-me0ws{=`YMXD}%3 zkyXS{p$+t5_XFL;s-DcEiR|gzG^S!8d;MH81O^T4i&R!7VdDx%J@NvMrV_bR)aR;j z(t4t^j{jkJ4q;ZfU)&cfR8R2*%=5k9~hEoYMETZb@FA3LG^5A@I)w5ASn)KEX-td zt;+}GIjjOhyN^y_ZW6MrxNtox;xh`?Wnj`it###>Q33L!Y%|&?OwDdSHW9-UZHY~E}giu`|TJDPRHTfqK6StYR8EhL2Q;$W35UB$8&!f^*+e=Mx5>%@k z&y9^h@UtIbU0Uw2X;isX098Ct>rP7akY|^-s%gt0yf2`LdE;$*^)omWscLwzTzu?f z{R@ooK|dax6Q}z4ya;>}0?y3y$1mS*giSz1&Hle@3s11;*ckUWP7GB0qP*lxtU6gN zo8;ZxG#uZKzVAh);%;#2Pie+Gp6vJb#v9)TrYM!OqxeNUt_x@uco?hDvJ|xhwxU7Am|D;R}^_TInPSRIcA2I4kZH*A89-W4jp03Aw?z5h2!5f&zwl1>fb_Jk-9mm%43cDFt$sxBv1% zLyyXD&YVaqO3oMyGPDd=3;Ji^_YfM5t2oQG(rYg2vWpR8T$paTxqjx}7LM-y9VOI^ zpxRhNi+|z%;zS0{pCZn+H1^I~ts0diL~10h#pqkO-U|4%PupGm2)Avbnd+faSGm@F z6^h;nxo>1jCu=}ybG@yQTy;}fS6!E5R4i)iT_LsUih0~3Ye67WpyM0^Qh#G|#HFf4xt5~N^I+}MfqgheR2sFvYmX=P%6jp_ zMWJ{Cxqu!jlY_(VBt+7gl9nr9IzdwKwiu6o7FCPoSQy07a|GutN;GFN#p+XR#*7|6 zjiSBgz=#3{(q&D(8VeDBMM6L}=dU6U1JcaiF_tPT?02WMR+8{^LK3$0>LB7oj(RM; z+go|+La7-YuOqj@76Ux|Pk6>K>8Ie@3siL?L;{xZs2K@itU8U_AC`@X&;N=ze*_8y zvB+`_roKmClSM?2UHN=mVJ!WAM1IG8&#HRKQe*|}IC=eNDv$I;%I$aMo~@KuMRflp zubduH-&Pnr%-?1S`Oe%#_$LMUU+Xw`e9eQb8haFyj*V|E)=y@+*C&LndDkoR+{bVO zl2YBbg(qe%qEeTos^#nI>_#K3L+{RX)xOSA*#xsa-%)Vjw?#e5ofhI?{s>586iL zn0o5mLv5qH-N+1tBkHV~p#QN&p*>O@sz`Jh&l=%Dd|OQZp#5H<0W^=oqg0XqWt@7n zy$S94PB+RI)nc+>l8DxY?Mi1S;A^a)!+y!|`+B%d`ydhix$xOuVrN>CH@n*{D3RgIA; z+WgO8u!a8if#HaHTr$cNi4vs_>FR?OiiX}_Sq&vh%$uo0PXPk>#+tr`V`y0&;2ByO zB1$r=fi#wEJVgMi7K1b^=m78wXXEz01)jyd)cX%(Fo~;}Uk8^p{J?TW9)--yF2ecy zKsrQHPLTrPPGaI~Q%{A}C=uo>#q|%4m8`{N{?a7xFK`b@DJ+rJSD~Rm5_QdklPjxk z)*wbY(Vx4tVeydzyu?Q!gp140%V!6@h>C@=4lk~xFvoK z{*m*|eH17h`D;-G5v>wW@Dr)Am|>`(|F5jt^Iw0TEu};O%vj2yuf!;2`fXd6wg!0y z5~!zn;+?o(@~i%R9%CrQ9xeXnZBtPVLj|!H>}D>>>Of`YA6QA{gQ`kECi@INh-eLv z4v;j6y=7~WoXTu1+t7$jKUK@)9N|*7NCZuT5!KMon?d5@Ry*W ztzJ$#=prW=&_q|8o!O^+>T2Ij9L%M9$^|6fU2#hIbCwM=V{L_Q(#_bf!L zic1veuqW)7jt-n^tV4Ujck3^T2(T*FYfYl$(J#;wLWAkRo4s>&lACK&&nAOzq|L@@X49K*p3b`cYNI_<3AUAFW^>z&SFK9PCMfWo~4 zgQd=<1Yq0eNs#|Z7dowi3nUoQufBqV>l6a*pa8|1_0oDgK7A_wh9B;xGjHP^VhxRB zLoezc?7Qet) z0NB;Ko`^4NA82o?1C5mlPnEd)2sOrz{xjHb4;Ue&3OUOSO-|iR&W5~(QV)pMj{^bt zKVB(3P7J72@7~6JxB#sYx-V88;7r6K9{@k}61178d#B_i;_S3soP^nFV%`1^n%%<3 zJ$jC6J?*fI?^Jg^uYgT|8v={jdE@Ra>wCQCGTmtJGcoi8wKcTQ63ku91^AhMGAF-z z)lYkct7+oA;^Xy;ui~5)zP*|qH0ZM@38#a1Fb4|zw1eUvpYP9p{ zt_oVg%2{93Y|!eO^nEYD%oRDPEad+$42{;xD${VmD6xzqjI>-x*W1ahNN0x{&m%K` z%|3J#iG8axj#V&ba2NEwsl9PGsWmkybkj9<&dR(EdSk*3GCFa%7!nREYb1Yu#5O0~ zCF9j-YIgcHUb-(+sWir+)vj<0t#=FwcC?YZ0M$4mUSr5}7RQ;>LyMTE<6m z8$8;NcAdFjjl0jOJ+^QiQOhBl#+qEG#YggkW+5$Uf14hPPR^ zNQ^n`dyt}+3Vhew10S+Kw%-=C<<@fX?~j^vvXRcN|6imAF&y*LPlf~Ap8VU#J$vam z8(f&H*H`?LdDy;et5arxx^}UEH6fzfd=HU9LPOStIRj{YDc0=} z>to$#J%Y#D^I_+~~v(=z-B6^KSWa;2T`|sz#~nl9~Vm3s71f!SojP=1%~s z>N|Cp;oeMUECzo{q~JBjE#H$<~Eqi zIhK-to@~dsYV5-=fxqR!a#C}!?tELMm{ZOVkzxU+mP_trj8(U=6M+O>&mQl!8!zG{ zy#_<}kA93XM!>+oYLkUF=IkseRz z0!+;x2am&(9M0z$7J1&Q1tXct&NtGf2FMfWQ8x<`%^Qbwf~pL-%kMl{zDLK}I^6N| zQ$7w=w+0=pcs~Quowb`uDBDJ-H1e!_UW5_X{_Z`+ChQ(Az5BmtZ?UIVLfpZA^gq2L zytOp4_5y}LMGfb1n*3`7IS;C!#7^eGW8mwe@nh)c%P^*N#7?`pr+Ujl@Ng{X|3u9e z=;9koh!LieBkEb|eBA*ttw;)s9 z_*$_#_7b@DUic`X6;R)g>)G^6|Z;5rKJ9zeBm@_|Hw2v)Hlrk=mMPqv#R z(O1r9lY^1XgyO{rUozQNAp9({_=%wBs;M%Qk~V(tB;P5Y6cH$*Cl= za%H!C2obhJDw=TS&Jz*9I`4#w}}Y;yT9`yE^g>e54+S_vFD1X`uG zH&u!Idt12#?fJ(GnP}?Awnq24^JcyzlyMNsoF)bYnRP-G-Ep>52`w(EDge1z7QeQO zMjy?wfO}@uIo)9xh!fB;_!>;G+sZ)UzF!|G z@VgU;a`a$mc71Bsovx+>y}UoK*AtR*AX(T)Y(IVOAb;}Vlz|8WVulV%*MT0YTQIWm zTtebb*Zma3nrp9Q%|Y`!6XRhZEX1)If$*t_ip8T6n1D-s<_( z1c?=~HGpdi4XrUGCR|;{WO!f2!@c8IR-mL}k9V7z1>HA0d3@y?BHjw-YaLt(FO(OjMFBlnIz^+0 zL+1amdT^379M{NkK2>;O?X`1d%@j!gp#*S76L<|jYZt}$_1A_5{9D^mI%03 zvVv%2@3hn?`Mwy2fc$(kVJ1Me<-i-6pNdu$+tZPMegGI(S^PZZ5`k4` zSy!pb@|!_`nMyQ?uC?rXIO_zb&09&g>B}&;TXArprKAkm@sp*CW;`eP{b$H?F}wRb z4k+Q>w+}D#WV~#lFqJdST7Z0eeWH+LQh2Hg=PYjYDC)_H&vMQx0lVFt!()y{1|*Mc z%m&g@zq1nOC0i8|akJlQ+)P9gsz-PY1T1VurAu9JUr1FQM+;eV;A|=&$fJisdf<#C_X-N?WT> zZWtAIoV@Qy0gi>}-N6kAA;Vw0h2x+jD?&AqC&a}7Q4#|2kW51uJhPRZyUa2PNV2)J zOWIc6E0f8$u?|#2e2sG=o5;?DERfFv<(8G5rpG6+#%_{(8^Zy`aO}~DDH&$ zc@g39v?0TWFz0>GTW&BYV&%(Fbu!YezOxY?<(9qH)u4Q<)W<_e`R9%Wml{URn(qy9R*y?EnfKoY#$fP8_s*8iH}s zu{{a{Z|0WqE%NqFJEawmxt6f&t8GyhAMjzXqdlII_nT75UBp(=^k6>x91EXn)x%l= zD6K|*gQ7-{w~MFt@vg}|So2oGh+|>Lf%D8+?&K7r4Gd)&1XkCH?LYc823~&nUk7PcnagOIsZ7`_@+Jo!i&}6!| zWap};WjrVv-1wc{>FG2Kz^}5DF5o+TEgrny{`Lz$FhmBvG)QgH`4Q&x&X$vLlu2AW z=(4$cjum}zGfaks|FS8Ac2?BFOAU+sH()zRM^Vo`gMuC7%&yfJONJ>3kDt6Cnc8&j z@<2P@zNce}vVl2lEe8VdN?pVCl1(YBUG#g69`WL=YbR7ea745;j5i(&FM*IWf{;IW z0QLKj3lbW1Xoh$-Ge3L0^F78`M1h5)h{Le7dR_uVg=WDKG(Xw>=ZgZmq@K|tsJ$_I zrIc8Ymy^f&1NQJaWaeR0(wl)~ogPe2y*T0DWQ*X9K7*zyJ0k6vdeAe%SpO)xEWyK8 z(-}J3+p}TBh#hf`@)tQ1KRDr3d-$>=3Vw;g$MvcX=?*p) zTL7u6aQ~+kTo989@)f$Rnb*SN=MWp&55*H>39B&ItElN)eq)3Ad`o=Fdb*{whs5)D zrKqI|*gtGs@JiD;dPx)6!RIU=3McjnBb*)xXk1i1&UH13y@DgzYGdO|%mNv|V;?(F zgRN);+#K-*Ol>-gVlKH-p`qALgEU&|*Ui5#CUqON?o+Ai-qQ=MyZtJqh(Lk&hlYVd zh3j+Iy6J3-d1lL1%eXI*=e3CpTU0eau~iMt6>&y{@re7!@;pB2i0ma)g?F+SCij)4 z5Jo;U-+1S2N*dRW*Iv$&%4h?wQ5?!A9_`LeBW|+#NP)SXa7Z8YT07XB% zEZ4dZ+{a{{3INCe!FCxqs(yo7b$yqnLAdKMp~+wvH2+4QYss{%y1{&U&EN;j6u$^- zNkB?>!^Wc1>=(0)wcEmek76{tibx&*Nhs)vm8ozeeIit@hiAp3-K5tz4%q7|*b+#p zufd@wU7>&+qw`jStbm^v=AjH}l&aPb76cz?&2;Cuady{DEp+b~ooO4kxyJYg3_m3g zdzk#r&bS7jpVx^J%-N;L%}UrD?cF z3iQL{a^$m;*b@4;fj+8QiZ#;XZsF!30ghsCb#`2BEj%wQBKmnOU}E7=Ce!C)5*?&B z9R>9vwc=*Ds|LAG3#4n7;T>HW)$8IN=(Of0p4^aHGlO$MPI!bd?A=WEto7b(MoOn4 zIQc|Beu-R7A)b=tjWom~(qZ;ZKiGYFOs1Z`#+SqHXPOS)9 zlnMSC!Yy4M7R4Oivh46L3TY{ocX`xfwfQLqS*HTP%2!LA(w(?qpmqi5|1jSzeUyLK1}gIAI5K zg=4Re&mh%Me7AnaJOISKm8?3q`*)6?yWF(f3c^ixuxgJZyWTAUURPpt4|4Q-%4EU? zxVqq>v%4pgsD3M`tW7*0J7Qp4mUyA>w_I63dNV<}--r|vBK*Wl{VZT)c(*=thsL;e zTp)n{dZkx9`Xq|+dc3l>;ZEPk4(QEXF2S-ZJ7q@8TUL?Mm+-}(uckp)|29|>o)k3D z3D+$|j83!zJd{^F3+#;GyLbS6asEes;O-}<_fA`3X1dW&tjc3q==3^86q4C>uo;62 zECEEm3MS<-wljB()XTg3C$)S$1D1hVj+T%)UNE7~js!+wAMi{$C<(FN6zK}Ia+icQ z7);p?P30-`g>KqTCdBD=O1yc9bZ}Odj#-kX`QyPN4rg3W8b{p@u?)xku}_XATG$Ro zwaZ^kj9B$IsXpozB7}09s?{aBn#M@$q*;jxqF2&uiYf10^l0?=qns^>!LnwMi}iS7 z{?;yTF=rLHW?7IMTPY{-udxO>!3^H0sM~S zbN@z$W;~8JiH99La}SlrzYly)TiOP#~_?rT}{oa1IlrQsyj zwee6zEFJkQF>e6a@nv>qS?U~dQKTQ;6k~Q0#wf`&98hrw^y7XbZrxY@`tlgNZo(0r zqxLk9A$6N=b33U zmB88E&J^VLWIVA!p|0cN&+!5s3@((PQD_BMcXC@+48iS4H`-qujICq_Lq}O4@lAA* zaYqE*%YM%15KTuFDp^A8Aozy$Caz75l)|yW5FKw|LWIQ8r;>~gQb^|>aR$|)3$ zV;^1K^weC}m_>ru)M7fbOG3p`_#8>jPMmnNFiX;=KDVT~2bY?k1V1$VV#-;P3dzRS|Ny8`b`p-zgDq?ONQ}rytbKuK8^G0og zI?;|jN{80|`0lYj_XlK0v_eaEzz-R~&9}Q2&S-Mqp$lF)dADaIRILxoK};GADCvGA zrLT_A#wDpPMyJ(Nmtk%UgOg(@0C6a`cPS2J;m>J?v!lwT zeO;QF)G>nZ7&m0EGIlNoLa);4W|Li+4TU?S1?W=gm)G#6*3THb9 zvnmIOky=GnITCCT0OxXOJ76mSBqo|F@6mgIuecRYupxtP97O^r3k6lN#uYb1Y&uVR zxe7fNC3Zs+)qQv5_#4ZGx*eQsWi0+87oNg%Q%;w$-_SQf&DcMe`pkx-g^<^JlMWKv z$dgUe8Gp%VeS;qP!qKu?W5imRrYUZ`(#L1C&6$L^!8P zld}pd8PsQ@L7~-aO3!3cAc2=*-Dn&!&b8u#Y>7~cMC@h8g7zaL387UjOQJjz1AVz2 z*`m);y7Fd=Kn^e0yI$QWeVV12Uw9^dDRl);u>yKB?5CoP$0EfCs9xqx^{rX@Nh_hq z!KW3l)VVGM#I*%$)+qTUQ9p5xnQg@PpJE%#-A2d}U65?FU>=b1nq53lzZB#Nx^ffQ zM0V6)=WqA*!d2S#A2Qw+QO*bbZ0@zv9W?WFQRP5_Es+2h_uKfNd71TUcJjpuNo;6i}rxbP$P@efl}u zs3+cLuZS0&O+MZ%-UgXJs-?M}faOcAIf*Ns78Bcd=HkXxYGQQsP`^&VC8~Zh!w^;h zNFl=2@Bv?q;-iNdzw@(x1NJ~NCk=XlJYE~m zM};;e$60!3U9|%gpX2Y^?VniFmDj^I@sGM?)^tKrzG%=ASF11myA2PwsL=G8Q7fHm zqoZ$clEsRyOx1Fgzy&g3Y7x$Zh3hT6{dr0{cK=XJmgBzgE&1jFlE{V&fr;rFW#QY| zrX02o%RO$I=9=b3ZNrF>*MferF+lO5aQt1Z)amyG;c+T%9*ITb!iE-}#Ucn(Pjb|% zaqpNB=mQL`DS-Zn)|OP8%*oAmrbPA(t?~f6%h9LBn0V?z=UGacNxOWv!kP+@f{2_e z?4v_>-rl>$sqhuWuAPj5n!dPQ7HFoyW<{wD+9BLdE~%TZoy$T~BDeBP`xcjdphCtO z!@2$eMrkP->X80Za!GT!BJU0c#jFoNZdSU=OiXCKdX95*rbkjMWE>QaiDl48943aK z&u3tUE{6TWarFI&JweW`Q+|!xoM>{ddhLHdaze`Hzvd}ZKO30E__)7ZO$Ap(#WFgb z?!|gvXjq`Uo{w?ZT>yb#buN`aFgfAV0prJs=@na7 zH*Rd{+vm=4&>go9(%$Q)$d#)2OEFJ+-ZmTWYU*OLeVi-{%VOQ$r5uX$o=FmY(VTlY z>N(fO{!2?{Fj#_=N~0q-dymax0mgd$rrubg+mgClvjDIPm0Dc|)LP@Rl9ijag)>4? z%1K6|OMy035Xa5uFDE84Dw)wBfVW?kjnzCqg%$v#n8P5VfL6Si=*Z1Wqa2_!mU*I1 z>oLnsWHxj)79jyDfsb%$GPcfE?$R)HFWP^Ih_U^M+z*@Qjzz3^TAU`>?!-{*Hm105 zI8~+qg?ud=k$8|k>H6Ii%RjS<^ZNgdYXUo^YF&u)S!dP>l#~6i>j_};rq?H$|LKZT;_j`BXt2e+R=JCFSD8Z?fJIiM0~c* zk0lAHS$R>agkhr6;WexfykYuFhAAuHm)I_f@*FV{B_5 z3Sf3S-oh-916L{i-_)CxG;#Sb=RuY(Hm0T&sqT*=91K{=P4S+WMucW9`_QT=^_%Xf zIr~(?X^?TzkKjYx$xG`%IYp!)Pi9uzLwjYCl;Js1;NiXU0jfM&;b}*xSOmUU=SePq zJK-W~NX>4Z6zVFafsRO#o?a23|1&DgN6en9hif=v=Duo)_H(u^N1-0ptR>z->uV3N zfM_6dzO@0i{w_+k=u-i;3x9k!ssDWq&i4_hX>U~}y4wx1`r6~JBZze28&98Sq)U#E zj;H=GxYNy*czPVs_zRMVCYU=0ETePw z!)uj(?Mb2(Ts7k~>h}D4W$2~$?u(*iO&2O_o>1v=3^ePYCb$>&YI+F@1p2NgNb<^> z{E}Y$h&u*KkD}%5(pSQO+SPY7!u_UI6<~;9aTS`TI_=F-+x6<~DHwJI4JVLdhjGEe za=Ab~Tqm`bVi6m`NOJQ2AzbpA$sa)p;mUu`ZC2o9K+it)^+ z|6cKA60mJXk)UlGQzBg<`U+{K5Ofa_?Y_1d*ba2+zbM&NDn!-@7y~E4u4D+ev}1b~ zF!vaLgyK4_(zQnm!fnwBo%{t3(f*Us3@axl5|wop`_{!> z0nG`}0cg~gxkv}Z-t??`b0sjN+7S`rAD)H9T@u^J&-kZ{kco{1cqoG;=IY)fQ$PafSAiX(<%NATFsDcP zWfYo4{(NUw;Bk8_K<&Z zZ$D<1i?@jdYFAUF`}t%}P)*64(7i@{$rN6*VV1ei0N(%Yr9c~)4i7Gas7;2JTE!w) zC8y6lE`Em1}#xNX4;L1Xv^6GD{GNExoul6s=&I@cG`*809{UcIvJ}MRf^dKobl^ zAe+TuL8WJ9B0RoX>9u>)hnFk<{57$etCR+X$%~=vCcOoN? zyxGCV_h*Ag8G-0Lle2+a>#mP?2J{UhvtrWw!)e|20%uQ&y5h}xbxmele=D5y_`7ac zD~RLCY*OXE0giJJd*-@|p@gV*8?;Os{oUFKm~{!>V&f=-ITdFhR!@>_!K|(f1;sEx z4x!Dmj4sj5X9RncC}`VO7G`UIxo2b+pkGLxRdybaFpd%Z2;#rS0j`hX-tk<&h+_|+ zk8_y*^@BZqCqEgBfC6n;u&yHohqd{O1UX4Bd^j7wAQRt_2uMEWzSQWmKxF<%k<b(d`xL_65k0rO&4eMuSG

W`(`g9p*R&tScpC$fC5UsO)ffxs~5U5actUAT3iAv#nPH}A-#1&;GAlP+B(h~SP z?=2e&ISZEHHXh8$e;s184m(2N2EpnL!9-8)cpaa6D1AC=Kg3b5PLPy{GOE1TXJWc| z-cOGTtiDGE*SqeTq^pLx>v~=y6Fo&XJCKj#Y4HloRGyLie_l!b;iwd)$L-oyG3DavJa%wNXe8__h1d{%|q*Jefmi3p%;0rNfG(6o#NB(HwbP)(Yft(J9MHF;Nl zp*hjiMl|M-Cr8k5yvsJWb7ZfvY*VC>JX$eaRkOxL@UFJmCOKqmVz5=L0{|#>CA<(5 zVEYqfIqnZMxvV{AcKxTdJ6J(4g6u|U!suG%d5HY0Ob}s)#(HvGml>R{A-AE*4G^v+ z!kq2YzzEqh<=+W~x)^tFSF+N;6FEvTI8iZiPR3G8Q*TY*zciX6Rh3g`)vNSFbT`0f z=aS=hycit;M3SkyA*(N4ZK3$%>y37uO09LQi1y_4WR{3wEy$tl?bSeq9XJ6s&(Yp` zY?7Li)~EdN_pP|x+_=mWXhrn0jL%M{h%}_vhcqxTqRv4N_RSy{ze>#F;2||5$ebfG zt&)XX=w=kSHZ@+QVNBH z8$<*!cn2w1-(VYOi;^{9plUuuX$wWs=Peq&Cx)p-9<8?6oUdJFJnBv zQ9TJx-hDGDf*WXAzHa2AVywnaWCVKdQux|dy&qR0d;JlG9Z3COPfCa-Y5cnhi=aW2 zw&>{0w~zmp(8Ru_pH^uZcTlD_Bz{vrwXU6$p7P-p``fk}ypIL~jx2_>rkc@<`AYo* zlj>6Z4WHe|CXpC>KgHUH1}YL0f1P6!8K8eg^@HejHWHUiXA5Lf0&Ur#Q$i0UZa{)h zm32NM-oTC3|K!D9ZQ5gf0F-?d^32KP)C0jQM^<5^vxm%;_#q6$gCIZ1Z_se&N_DQ+<^2H?hJYeH>D?+H zh5;FujuSmL5O!NG6b0RLg`NpS-?i<40YGLRFoG&(3cq*w44F1n7_&6a*1_YCmjY+A zUBa#4`Tts)o!J&B4+aBCF#JZ2-0|3G}D!NBt6=^+kTh*1)rH zi{#B`tqQsG#7LbQN*o7bFiC>RKMpBMTcsXNn=x_$CG6=d zJvb%;Ciyjz9~`&S**Y%1jI22lv?MU?DPEm-G)UcYBsxRnMW~pU;EI~3kF1H#w@Rp` zvI?q3*oW(UtEhQq3@q4xk%QDG<%`Njx zp@PZ`M@rT{APN9o1;*9#)-{h73?>xvANc8c>YiILy3&5Bs90>fwZNM=>VhQy1TjUM z)+!->NK(LM*dl5MmXc4_Y{lKJm#}oiIArPh!J9JHx0qEK2Cq&lcw1#+O&qMiJGTQsnGE07w!?+GNXJrvQi`aKbha)| zRN0W^8G`|Pp%u}$S&A>$|5>7NdE&ntY9&n^Ih`XVbwBQD=JwtGTJ zgNoz;(mvmpOHKxaZE&;_4z^v8#4)9=qzmYeLHyOEB zpC5GwKLmv*dA$zjEQkdDtnd4%q<9r;1W^G-%GU`I1KtG)*fxTG$< z__44O^#FfS+nOemMfb*jqnQcG-Wl?h&`xChQPs-b%((Pvf%vutFfCs6>dO+2`07Ei z40h*Fh4eufw+ZTfBL$uoZdL2Y_@fk6)htwR7ti9A_F$t~lvX`{EQI>gZtXo*;xQ~b zY?tN06$Rl28E(2{T8)U-@z+$|l_-xRQ+~k4(AwYKy1qL$fN$KlyId3Gi~|$$+Mebe z&6us(WBheVqM(Y;eKIsP&L>L~mu*Nsi?yVU!U+d>@n4KCCQoyTgHOnCiQ1=v_;MJ8 zId<#RFX|O~EF3)w2aLj~7kNpd@G;c5$J5Ps!y$F#(0$;F z#}TkZvEcKWUk{s)dIM=qI0vmv- z-OZqoIaB)2#>Pqz+V~U)349w;(<>ui+u(|47D4e=g3<8N7G#g|)@cNe>M@`qVN2}5 zOAB7lq-rzzT_){DTQiixVIoe7AW|T7&dKz7uCJi}hyI4Rl^FWwnldym;wG?K_*7@l zU9KkZG-C}r+hJ1jL9DX)(6%Lo?!)j$i{BCFBbdq8MFSw)3yl4{Uh`DmoV(7#Ydv(` zr@6Qn-RC`U6att~5sM4uUoXL*8ZcjKb_+5IW?>aa4 z!N(t+HY4@^`{pZj)g9*zX@JovShU-pSG z-p^PlQG&e0C$U~SM2c#R3NRfGvC7F&J)6wsGD*fvY__$leihNKml{^KJA(m<$(CXb z3WvOBj}lil6J8A;rEW%=Hm!i32#G~-T7>1B9#C+*U5-n(x#v2KbF_Ry+bL5AI{lY| zBzhuAtFl(XWiW0ch{6k^o?qIjLBZoG%W2W_j9?_(W4W_l0Ez!gG2NjWy2R)vZi;2t=uPKQzVdn7S=EWt}Zji7A{(47T%sWsAb}` zMXt*k5<)NiB%>n7vi-DYCynffure16b!1b&H$BNot&JuT@hV>U^}<^QErZkx@xMU( z-;B=Q<(`hFT-UP*CW-giJX-^0sA zsUmR%pSS^Z){;3%)xxhfHVi>|s3mS-!-9dX5?=r3`poN>f5{E2TvdPIIqpyGfvHVZ zfa=+tuIv+_BC)wo%)-a=R{$pk(7#m-)H=)DWU9G97|7>~>GS${WGx*3x>rA@IWzt~ zIs)Wbh4M#iE}6n|l{6+BnOB?8+)g+~sm*cIwM2H2;Dck6pjYi_MMu5!IzSaC*6_e( z^w=))5xQzE@y*v-HLdf5XW>{V=?(ZFlj5gNbJMV0ZH@grpCkQ9tmGpVdoy!Ycat>L zTuMS>9PmLbr+r9K^6wlsVk2|SJ z^^PhJD@%qd{80l`i<5{dWJ=Y9zw~>7bL^r>8Vpt_o7C|0oMb^-j~sq@L}05Hm|6p6 z+U%-CYo9;!7OfnSb3ooP)-iaT$<*4VW9sI1S-_<(-4M~A1zaR?yJ+AD4KK*icZm6l zSp}g`m(+Eq*Hfi%?Apo8Ki!C&e0XP6YQ8(JAc?dE!)>OKm-%+rDc1;T0ZAP~#d`YW z#!0)+c;=8dZdXqC?sT8}C2gQaf5#V_GqOtj41lR(BQRjslTwHP2;*`ag8 z`_oJ7CBpr*;HlvEsa}Z&Rg0dld3)uuDcnEQ*22xFhr@v#isn z`^LzdK1WC1QWMKR1sqZ$0jb(vXgBqMvi6n{K`iZ1hWZ9CuJV=G3CJ| zoM{cvBET!?ug%LDKa$d=RBJgm5dEKq{SO;2ZhtN8o-=s8=6Wb;?E)edyP&FvEdD=c zPC=3}EoI!TBl+TTf;IMKTC_#a()~{X<}OkqtcBNA72+o`+xeJisEjW<;xa}En<^>G zcrVm`xv0>^g$Dh=1=*OCnoWXxvx)tW>7oRCYLQ?LEvK|)KLAcZvA^S8M`=Np);dM>7eiU^dR_n$ddyik7VJ{nLgx!d&d7aGF-At8t$K z9&rTJ<23A{4(y-0M7^DF$yo*K`5NOV16UU|o^@Jh&uR{dphiyMTs@TUv-$)qC`|CiW3i=if0Bjk*yux387i`Sx2P z5mqkO4P?2eGTh#vL_K7kafodezWO6U!EX+8c$kOE) zje(Yq&X_~XK^N%ae}bg9zDR%*Hb!@Eo;lPc|cuh=&efEf>~B+K}>=Pqbu9g8R!W#Sk5;w z-t=dnNglVa9*gyZ^+p9PGn0QWVhvr{*12m1IX5u4Q0FbVBq1_?`7#j#ZcB_NY&(PjL`GAYoRAU|d1Na;L;>!&^v zvkYXy?>1I$pZ3>5Uj|6BE|524@x6fQLF`8!&t~7`fH1#d79X^P6MzPoMp#yKu4PiQN$MIfX9Em$K`ENofA_& z{tn6(LY(GoemT(+&R3~|Huu&o&1~miomJxDSTEL(NR(Z!gX`4Ab=0EZ<)t=DGI4Se;fS3 zKR}$R1UOlUBm3yhn)w(o$rx#rTJCrNr^e3QH6T|jpTW*KKyo>1LZQO6Q~<62G{>4T zOo^iRlNwqS&0K5p9*1G5)Ho^NZvf@0QNA&e(Ry`T-ZFV7LJkHVrZ6I$16RA`9&!Kp zl3JOc<;-@#8kDeF>TP@!-Y#)sp0eE`EtBY=Gk)uy>N?GSPLTF1Z;>%>W5EtrO4fg= zRsP#UwL#wGO;n>P50{tuOLt8Fcis(j>8j3zaA%>G zO$~Jcv64?4sJKTBa_JyJQ?n*QaIwKkzJpyUE;Zi8gEjc$U+GU=74k9r2~@Sq(+ zN9(5#+5_@3i<9Dl2u1~WQ9b7#)EHCP4EzGzE7-`I7JhM_pN{M7^e9q|!i09b$@?Q$(iZpz=y7eS)YP3ta=0l**3>wT1nT#MsO4y?f7>l>Do_ zVy&PnWw>&?+*K4CDd}jUa`C#T(ndUW=6cS(xxmji^8WRFJB+DxDXGzZw;M7nBr}&c ze)|Gp4MzXXW`~r^>p9wHEneMkOw#;hXFn-GJ{QE|k{+3C7WsQJRt2dB`^jBics@%C z;It8{m7Ti)HXDQ5JY6ijx7t^tUWP3%E)ge9IUXIh?BEp1lM*9sfM}FGo<_`L~7s zsHOEPDVZ*fd!%shjl8=UXd#p8_?_+K$)?%y#WF1G95;7SPYwlX-hk!3KFB%kY{uNo z){RYK-aSG9)q2*yL}OXo7h(^I;;FGINB*70QpVu9a4#91!bh#OI^DBkC{*9(*ERFP z`xd_iN5p7lwIS(ZZ~<-`&vkQ-a*RC@Gm@waGaJV@ZNo5L*l;zihVBSzi&BS84;1F~8PLJjrb*;G(zB zMaL{CAp>)qjrZ-;&9j_C$@w#JHCLs(^x}ykR?|LC?O$(lBvMGgWc{s+QIO8DIIbZRFnvQTn8=20yJi>VW05K9)@ zs5j)K7aCXN2mwApz%Yun^8o%t>bKz9LXVZkEX+h)s(LE}0WoY$hYLOsmsp`0f9IS* z8ON_kWnA(AIjMq7Xf-KrI8y8ku)IJ88cPc@1ILxOL8Ns=AxODp8?4Se7}1P|sY7*l z(y5~$uL=Kf-`#|Cy3nLv18Sd&Pc*QBOm@@<`v?#PLyTU(Z}ga=eZD&w4}(IK%yotrC8eX7qcEzsI@|uqPrzNUdoXLV-K@oOAF5@6M8^|7W10~sxG*1xL+!=h`pViIM%z0}) za0}SjUa!+2G?F3+JD$X%Ux*g~qp(^p^=z#k=1foC(4l{Usl{o&E_?V=&C{NvCf_)b zB%f|KrKrTSGhEf};*cU3 zxdo2~qd0U+sS$i#23e@vklAlb@f)R{3&N@e6mP)8H!1@(Ou=xFXVay^!^vc$=Rds8 z&j`u-ka)d3WF=3k8-c#3$LT~!&F|`>Im&0@qdZuDfSW8(sn@t^iU%639eg@jR_OAj zpREhhPrl`ofm)kko{s7%6H#GVCPBG+eS|7mzn+lPc|BalCgAStEt(L}R4s2n%@`SW zIKjEVt)|bLGD&$TW_m~-Pt8SFmk}iK;rUM>1XBy10JzITrcHA|-^y>Gt$mvR+R}|q zk==(iOb=X?KS+ZL6Hy5L+owv5>kMYVDRlL#rX_D%z5JzX``+&_3K(iN9EXA>v zj3DT~(P?50FkVsbMvcK@cxp%|bld~`XpJCF(LyE3oL{+8xy zy`O3`qt(D&2tu{e6HVpLZgk%tB?0cwfuwJ}TBlqNO}v*2#p&FR|FACiyk2e?@jOpF z_YC7=3?ccG_xoVdn}w05H%XAcE1qgMbDqj7`#*s*AbqMo({%A_5czWPbQ|#2Dttlo`$Wa!!K8$8^Kb-5xA_UpFWnmaTmWC zlGD<>Uj0kJ7$R&NDgH^~$T%-BYi2I07#KpdW>%^<_?R!kjv&)cx%^GRCN}}8HjQxZ z89{S@Ccoak3>{@Rm$IoTkCEl*0!%RR1yr>A*smWr6KA00u`)F^Lo zA?Ck%=08bQHs8@VaYCuq{OPM1CQ&V#!*z?xL~sy7oXT3rYno#FCzNc;J=Vt4q^&t7 zq{>eCh0Yqk=7S3fl>QWe*9<2lw>GmD1KGpCgEt)cF$FcULo=x*3ed z>NATs)hwZv$}9whJY*ABAjhxKjFL|?@_NBnq%Naw=Yr%^;GIX`mm7!iTW z;lF{A|5}9>&K#R9t-=^6)l>h8uIDtiDpRqH+&H2RQ%~1+?R{Q6*hfex1v_Z$bt*3y zSJ3yQ*Fq4XAz$Im;1t-z(gErtTeUKV0(ts9D3<-~)w?k5S6VgMqsg1(fQ&_JV1!!X zfl$3JsI=xLJR{O%b~fAYSn95*ie?!Q9^RE#D!e>u#G@2o$Rv<)f$-H@5f@OEjXgoN zp1**4r=VKYVVuIK;)!dpkJ&`z;O@HO4nD5l{|&Rj9);USRhFEB`d^R*_yAg%wE5Td z&i|6|UAC|@f%&i$zdKs)P&QakL?TAqf%4=dXcH5VqP9yclR0Gonh6!to|7hiMQ^>r z)&se4#!|l;5p>qc3LmhWBL>F2yXX#3xF%(OyI!#_Pp>-2CvB&|9t?SG%jwalZeUK( z8RCRynl22l1m*m(j1R;o9Ri`6MU2bwV zt`G!RM=a`~$^#n=es6wjZyH7`L=wLb+!c&bD#`nOQe}*q<+OU*f|R4?cbPXuyoKFvaQlN>eW0TSM=KdI^D1x z9msiZS?q_@XalZin1SO_E9C(m6vXqxmb9w_xaxG*##GRq^0X_!B-nhH?Wt{=M{9--M3kE~?sTY$3TZIIMjc-&zT-mMG^Z^Zk z77h&BCrno1I@eS$2*nhzupp|w9A)$ndk|(8@9DhpqXa$}@P=Z!+=I{ICZ|@h>?3>`HH6O6;;#@>&^197_OLQ%n6$IE6`0VUvB+f`-F6G+Ek+ z?7i}f5%M+esB^*;$tlBZRh(nj*?Q)%;1y=*bw@B-RaH?FWQZnS$pt5k$bLg0$+Fc# z!(`_;mffu|d9f!r+B1^pw{LZx&ym~{69rFMcGlUoA1t(C*QU2g)yMlvOWU%HDJ%U4V*SEZF1ot7QDACtBb|H+_KLV271tc z2gypYlfm1SBnwz^e^iDV9BMx=2k7kp#XR0m=Ui;Mr*TpFyg=zeW|006&H^4hA^ zUwZNQB&2v(v3p%kPB2V}JncXxRz{aRl5+rTkcXrTdOA>SFIjn%S6;s4Z@^8C?2qS50d#&Ndx=u18FO& zR~H{U3-50%_xcp(WPPc>R-z@JL(~r@=hT1^JaM#3uoxqd0_?^j9+^J~d9Hi1tTG+> zrS44#l7sJ!KVPh%HFLaHL@F3?epTIayC7(p$*HNYbq5{*u$t$3G-tHL_NN}m5TXpC zslAkDe-CM~nQwvPQ-}D8i8atR5!b%^^XLJ3I+S*5 z`#+`Buvk)KNH~zUUo=%`l%%*}|1ww_IqT#@{LqM%z=aq!h*$UKm?8cQ_lT=K(}|Xa zGS>O?wiQ*93HGdPJzC9c95@b02f1?*W*UeGZ8NMnAHuv9gp9 znvGyfK+|?Byxe66)!a&8sCtc^`c564NkroWVWlVcLD4d)`(z_Y1N%L2{sIDJFnJ+y zZ-9@cGzg!QK}7crI*I*7Ilt?PW(=i}I!uDuT{d=>PIpKA(IYXO9PEMxSmbF@ITRgKn$&_30Lw5fg0tAWR21xiHokBgf-QcUC9UurE68 zM9VTn2b}KpUri~hhUZ|7%}BejiKx=@4XdD%>*iZL*+A%lDuy78HkGyKJEtStwWXy^98WhQS!LD_H60b*ig z9{gBVWCun8XP*>>h+ppHhx!k!<5~#UsI}@y4tPu=$9z~BC7~1x(chgK<2|&>Lr9JM zg0=u9(xnw6gnrYAyx%K#5l8VRfPWC@w8Q4*f5=&Ffac3sV7T>J{vplKu&EDS?kZS``r7s(_P>;JB!aiQj@}l4Llfm|8P)6 zY2H!O$JOpwh9AsV#o^eJZQmK3y4gJr&he!&wQ4dSL-`rZ$e7nO^QV3Q!(WZIBLIsJk2RRG zr9UB1{i)5jJ3Z3o{ZeSi4JeGno;mPe$tkL(z;_9NcP(&KaV;(Uv)b;flnFn)#frHj zsuJhGWa3a!RT{(UXv9{OFe}>)P>41#B^AdJuEaK=tuv6kCsmeka5i$)CrhKV+{bkV zPoE;;?L%)iI2F{euu-15E~N{k{RFq!c}Z$qs~cRC|#La4(Z460+Q`ywnz8i>1zAXd)JJ9U62XdhfmqX zaWR}-y2pEA+#J*y-=vDQ?BgoIz#IR^jvC4>XR7?pI9uX07^oQ(5U_TkCbAl~?Em zZX4aJn6l#_pNSuHEmS6AUq?QEW>mGti5;oHuIzR9zVEBTd?NAWg4pK$JqXRr?~DbK zAFQoMru$jbp>3i#`XxU3?s$aLKwMugZrrJiKH~d&4LmAlFWX zeVpfq4k1M{1gvD;NOKPmeg*3C1pNyKTqd9Ej12tQhtp6~_3H_r&h@`5=SL3=19QGc zcvUxZB(puEu^U)qj)E)Hv-ij2TP#mzIak#jYYGq`;?EF~?+?ofBBkPZmxt}1J5H+Y z6AlDRVUi}619r0`7;aC|_~Bh_bItB#IRe!t~}+e*06CR4@yCXxGj%oSi%LtWJ*-BdnGZpQ`Y)&Zqg6szmfT7elO(%nyMGS5FIf&_}9cx$HR+vCt80zF_PZH*+$L zrW+8<<3-W=8B=z2!{BRn%x}p$jB_{E$q0j)x?2YyuK#QXs1=7$3S2UcFQ#X-KV^4e z9DVFm(vDcdBugpwZLm|UQNc)&-%-@E(DkV@-|lh5Us(8sX!WYawp>t?jX zZ&3JlVf2#(SK=&j*3Epxd}2FZ?He&}st?o;bGRz%G2J@;UxOjLLjV}t&|cO$eT=L< zDMV*Tj=U{5O7h2aiR!x$qv!$HXdAL6Qqeu6t8izj`kHHarp>*gMg4GGlbhMXF5SrWRs1`7#zl422CX#0xE!|S&Z|hh> z^QCMV_2?*19z%BmV%RQEJX+(JN7Dmc!017;ppxA{u=Xk)J?Yssr5@o6aBTa4I}qGiupz6j3`gE5oY<0jH2R^|0%hOJ>YIOJw{JmF*Ka zcl%5Ls)xmWdIxshpT`Vo&O_w_Ehk#hyydxqO5 zhT?J7f)jIEX8tul4E%$=`=y*O3y{mB-GcIte`6vi?Y@n@O>r=MNY6OK;1qa$poK?1 zUs6N4kAO{eH?iZFby%v}Z~sBYkTHJAo%&e&&?3Oq1A}dMI4p<*w|2n#QU;)_NPYAy zR8O-DTfFE-+e{$)WLerWz=n$NYWbQy9g~?_+s89Vmal$PhiON9!7{!b7pcINHl?kA za(dQj+p^qf8oHBM*2Quo(^O;HdnyKMDQ8rfmZfLa5*Ie7#NR`5%&tEc*D3q1f;$-M zA$4(}fg2jd%~SrAX8t~Z@2dS(h;O#jIAYx1eFPaz|(6-#N*yk-d!!D_a4vVgA81fiA`c=Y?HVMsBYehINXVxRp2SMa497 zjqm+KOt)mE&#KOUR!>O1M{HmT*de=iK4*OP{)1vlY4=e79rKRG5%ZIxp-{KoecH^b zO|y8dI2{ZN{I)S_vN7FpjOqi3PKW6>nF9CgloPm^Na(%8aYFji&W6WFCL2=xJz%!9 z_#}b!M&Ti|8JxQ&&GqzFE8>{Nf;V8@42#3=woxZMV!TDmRDzx{Wd)GC=vcH&6!3tU zXl0QUn+WKZ5)J5e2_xEM)6 z5+8U+dKYB220jeMM8cHG6I?!A1}D6b41^U~Q+EogC&^M1R6TbqJ;`B#8td9gOCt>l!U$2~IOIDOd zC4V$p@OTmJ_0|;<4T=W&0R=q~s{viP4YrYXB-2YOiCC{(_TJb|)w_fAGgTZ0QC#So z+p7>ou^aIG4bu@F4rVlVIGdh(!DO+EaQM*Bc7k}kgxmMHGOgd z#p|0EBEYIk$M}fCAK+bbl8Y61h~lgvWen(8OF__Dt$K3!*-V6PNLaNcrRY&QwzRd2 zxSlH+rCL+NbTqpS7a;Y0sDyF$mKbd!HXJN*Bubg5W5hOsF=Bs}Da9fAX7y$sT;(!U zIXoPE7#lBr{FL{9mS9l!2>L?aO);t$xeOy`{urq`mnx?s8|A#no}Qp2xh8qycqYo9 zbj=_D=&Vz~i{wl+gYKr`3rQI*-#Vj-M`PXkWuZ@LR3 zK9>VIh)MC=iS|^*kt;W*Hcv&Aenk2p5~G{_^=?}>upe{co9-g=H~vlgHm-Y!8P3w8 z&n0vyyC{z3qq^|_Y`-S|K3pxX@t-aiI-nPStReI`t)ifpr|EKryj}W3U+zD>VrL6^ z7VYqd2&x=QM4&pF$%~|wlJYv7{|$YjEY4U}9Zd}CjqL4uls3&H$|r7|!v8Ozz9d2E zeoByMQB*WVw;)l4j82@J3C=LA4u8*9^QbETNPxYLJ@+X%@(=Zt(~5h5Zk|II_JsCJ zO=y#HA;pgY>NW@ysVYpFHp2TCz9`|zV{twDV)sVU%k9ufJfH}=bViuBQBsFRPUs`p zaF`5xCx$CCG}Ztvvv|3Li|_zV?DM2Pi}}lx+1-A9Ai-IgcbjSVxn4DE!b|kzJ2(vbLBd?fdUqHzyzc z<^a}~M&@k`v)~0n4oI+APf;sjdkDw4+LFY>?jScsG`5Lwix_CutxZTYZn+Nq`4&^~ zxXujo$e*-|E_mUEBDim)(_Fu2X8F%szZvuDRQ0ra#xeO`Nrgd1`D>3Lekvw2*7!

VvZ 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࿾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νxuX`9;rMK2c2g=~J58n!sQb`G2C6t#{0TcHy))+y!pREnE?Nx1-XwkrKq zhCWZH|LfIY*vI?Ag9G#4v=W7*v))H4<3gJ=0h#3H*r=zS9OH-<6wm|%o7}<)8RYJ9 zk-je1#WGo+cyh$j6dRu*9!b-B5hA6Ma+s=UN2*R4kjm~$MR4!!NkVeQT_k?Uc|Jh| zz}{6984(*?InCtM#gU-uKUmJE!0q5I&os!Bg7~s7A-jfrKpIspipH8W^-ns&3-}bz6G5y4K65TdW@v_2tRC!$c=@h z7{eRFx(&dQPvDnBnrw9C=edBi^KOqMuq%u@K{5C=&Kv6jqns;r!xFSTx0z3GN}S}dXURj+S^ zi_g>baxsVXsu{h}nSoc2(;4#j?gMc9ckV-!ejDYUc3Danozl>#?QH5I2aL!O31Kih z{pk{!HyBrRoKw2GeTXnctyTvBg*rju6TbsmBz!7>4K~P2uR~O7h5-q*6@#MH8qso& z;Q(g-c1DDjbCMeJ-G+E~Nbsi4?$++g0Dh1|!-#o%cuk9$He7o7KqE|0p zdfS`-1mW4OeL~gpthQX=yhLpY5W$<8e>45tG&%?0r-M;mT`Q;R$>qiAU_7|I06=MPu)nKjs*Zp|fEkT`PWIYB zw}*n!QX9Q;DLtJpIsKP&`V&)1cUa2IIln_gMYw_j1I>Ur3WHHKt^noX;SO58f;|Kj zW)8mq^Rpy7T`up5gLWhEn^w^D+O=Bf2a|5YYz9HvPH1;uIRrdYhY+kqhSV*2>7fJg ztT%k$C-dmhRqq78U7q$+RnRWV854*RlA}@o{O#Fq8LYo}4;98A&=8@28nd#y2)w}? zl$SuD`hDnA-0bPic1`rDW}I(lo9X5jujDWwzHYhJ3lk%e&hz-m0spAQ?RLe z>_QQ}^pSgdxe0I9u4Ol>zPqlnjy|z)d$y2E8QP&|wOy;#?9^(mZ8ckF*KD@xll-OJ zxA)}Y?%Rs)xVr4XDq;o13pMV)ANHV$b8_~xb9Hv+oHPu(ZSJUWdIc4%9ThN~_ODP! zBMRv{r_SkU09EQSPGsMMb)3uVG1Wt4u-gqfLFsEV{@N;BXi8lD(pyaui>W=8T$4BP zLl1~;qiNS_^}5%zC!QJFX2F8#JtP-JFCm$T990{ggu4P1WAZ^vrA=RuQ&wi_fiYoI zU(DXSUHFu`)Lq|f@%&`waqUh;a50V}huuI8y8R`0HrT)*A^tZ006P%Fm{jnvL#uAp z4{!p@PwWtcl}|4(#wWdDUsc{NwwNI`uD?M2$_h4>8WX;rlMIt(I7OjGovA)V>IAqX z5Lz}%93ESn%Xzb=@+EsZy~Il=5NqJ?yi`{2;dJMGa|3@nob)C;YnjXer-RwB&?92p zJNa47on!}OSe8ck_Uavu3APKSYsUmrsx2IG?B8+nGn?>Zdw8D*O@WnUe=pZZ6IDzh zi=I}hha&+_3H!={e0d4AcvE)<3~5l#Sq9@zx#lz-c+qEfwhfVALj{a{Q)&&OM=+oD zq*>e-&t;r=+i$k4z&9Zp%srDbd~6HTH#q z8eLwV_fJu;0B^^C$zn}~fpzS>I;?oX;)W(*K0M~Z8JbCRjc0UOxo?RQMYz2iR>e9Nn{xbaeVsY z2Wx6DA?

5;;ok(j9kTU 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%0D4$m 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 Z12iM>9jQ@%X}bRKe*iBu1J#ru1_1Yya>4)r literal 0 HcmV?d00001 diff --git a/kernel/kernel/files/patches/mageia/3rd-3rdparty-1.0-tree.patch b/kernel/kernel/files/patches/mageia/3rd-3rdparty-1.0-tree.patch new file mode 100644 index 00000000..233389b4 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-3rdparty-1.0-tree.patch @@ -0,0 +1,181 @@ + + 3rdparty/mkbuild.pl | 92 +++++++++++++++++++++++++++++++++++++++++++++ + Documentation/3rdparty.txt | 76 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 168 insertions(+) + +diff -Nurp linux-2.6.37/3rdparty/mkbuild.pl linux-2.6.37.3rdparty/3rdparty/mkbuild.pl +--- linux-2.6.37/3rdparty/mkbuild.pl 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/mkbuild.pl 2004-04-23 14:59:03.000000000 +0300 +@@ -0,0 +1,92 @@ ++#!/usr/bin/perl -w ++# ++# Version 1.0 ++# ++# Copyright 2001 Jeff Garzik ++# Copyright 2002 Juan Quintela ++# Copyright 2003 Nicolas Planel ++# ++# This software may be used and distributed according to the terms ++# of the GNU General Public License, incorporated herein by reference. ++# ++# ++# Run "mkbuild.pl" ++# ++# This program generates the following files ++# Makefile ++# Makefile.drivers ++# Config.in ++# using the information in the subdirs of this directory. ++# ++# subdirs need to have: ++# a Config.in file ++# a Makefile with a O_TARGET/L_TARGET targets ++# The config.in should set a CONFIG_ to m/y. ++ ++use strict; ++ ++opendir(THISDIR, "."); ++# get dirs without . and .. garbage ++my (@modules) = grep(!/\.\.?$/,grep(-d, readdir(THISDIR))); ++closedir(THISDIR); ++ ++generate_kconfig(@modules); ++generate_makefile(@modules); ++exit(0); ++ ++########################################################################## ++ ++sub generate_makefile { ++ my (@modules) = @_; ++ ++ local *F; ++ open F, "> Makefile" or die "Cannot create new Makefile: $!\n"; ++ print F <<'EOM'; ++# ++# THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT. ++# ++ ++EOM ++ printf F "obj- := 3rdparty.o # Dummy rule to force built-in.o to be made\n"; ++ printf F "obj-\$(%s) += %s\n", to_CONFIG($_), $_ . '/' foreach @modules; ++} ++ ++sub generate_kconfig { ++ my (@modules) = @_; ++ ++ local *F; ++ open F, "> Kconfig" or die "Cannot create Kconfig: $!\n"; ++ print F <<"EOM"; ++# ++# THIS IS AN AUTOMATICALLY GENERATED FILE. DO NOT EDIT. ++# ++ ++menu "Unofficial 3rd party kernel additions" ++ ++EOM ++ ++ foreach (@modules) { ++ die "No Kconfig in $_.\n" if ! -r "$_/Kconfig"; ++ print F "source 3rdparty/$_/Kconfig\n"; ++ } ++ print F "\n\nendmenu\n"; ++} ++ ++sub to_CONFIG { ++ local $_ = $_[0]; ++ tr/a-z/A-Z/; ++ s/[\-\. ]/_/g; ++ "CONFIG_$_"; ++} ++ ++sub find_target { ++ my ($module_dir) = @_; ++ ++ local *F; ++ open(F, "$module_dir/Makefile") or die "$module_dir/Makefile: $!\n"; ++ while () { ++ chomp; ++ return $1 if (/[LO]_TARGET.*:=\s+(\S+)/); ++ } ++} ++ +diff -Nurp linux-2.6.37/Documentation/3rdparty.txt linux-2.6.37.3rdparty/Documentation/3rdparty.txt +--- linux-2.6.37/Documentation/3rdparty.txt 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/Documentation/3rdparty.txt 2003-11-22 01:07:26.000000000 +0200 +@@ -0,0 +1,76 @@ ++ ++Third-Party Kernel Source Module Support, or ++an easy way to add modules to your kernel build. ++ ++ ++ ++Vendors quite often add additional drivers and features to the kernel ++which require nothing more than modifying Kconfig, Makefile, and ++adding one or more files to a sub-directory. As a single discrete task, ++this is not a problem. However, using patches to add modules to the ++kernel very often results in patch conflicts, resulting in needless time ++wastage as developers regenerate an otherwise working kernel patch. ++ ++This is designed as a solution to these problems. It is NOT designed as ++a replacement for the kernel build system, but merely as a tool for ++vendors and system administrators to ease the pain of patch management. ++ ++The key feature of this system is the distinct lack of patches. Drivers ++are installed via unpacking a tarball. ++ ++ ++ ++Adding a directory to the build (usually from a tarball) ++-------------------------------------------------------- ++If a directory exists inside the 3rdparty sub-directory that contains a ++proper Makefile, it can be added to the build. It also needs a ++Kconfig file. ++ ++ cd /usr/src/linux-2.4.3/3rdparty ++ bzcat /tmp/my-driver2.tar.bz2 | tar xf - # creates "my2" dir ++ ++ ++Limitations ++----------- ++There are some limitations to this system. This system is only ++designed to support a very common case. If you find yourself running ++into limitations (kernel build experts can spot them right off), ++then you should probably be patching the kernel instead of using ++mkbuild.pl for that particular module. ++ ++FIXME: actually list the limitations ++ ++ ++ ++Other notes ++----------- ++Link order is controlled by the order of mkbuild.pl executions. ++ ++"make mrproper" will erase Makefile.meta, and empty Kconfig, Makefile, ++and Makefile.drivers. ++ ++IMPORTANT NOTE: Because this feature modifies the kernel's makefiles and ++configuration system, you MUST complete all mkbuild.pl runs before ++running any "make" command. ++ ++Building in the 3rdparty dir ++---------------------------- ++ ++If you use modules that: ++ - are contained in one subdir with the name of the module ++ - has a Makefile ++ - has a Kconfig file ++ ++The system calls the ./mkbuild.pl script. It will search for ++subdirectories, and will try to build each of them as a module. ++Things to note: ++ ++ The dependencies will be done in a module called: ++ ++ 3rdparty// ++ ++depending of CONFIG_. ++ ++ is the value of O_TARGET/L_TARGET. ++ ++ diff --git a/kernel/kernel/files/patches/mageia/3rd-3rdparty-merge.patch b/kernel/kernel/files/patches/mageia/3rd-3rdparty-merge.patch new file mode 100644 index 00000000..4d9cc095 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-3rdparty-merge.patch @@ -0,0 +1,175 @@ + +Include 3rdparty directory into the main build-system. + +Original author is unknown. +(Was either Juan Quintela or Jeff Garzik) + +Signed-off-by: Luiz Fernando N. Capitulino +Signed-off-by: Herton Ronaldo Krzesinski +Signed-off-by: Thomas Backlund + + Makefile | 2 +- + arch/alpha/Kconfig | 1 + + arch/ia64/Kconfig | 2 ++ + arch/mips/Kconfig | 2 ++ + arch/powerpc/Kconfig | 2 ++ + arch/sparc/Kconfig | 2 ++ + arch/x86/Kconfig | 2 ++ + scripts/kconfig/Makefile | 31 +++++++++++++++++-------------- + 8 files changed, 29 insertions(+), 15 deletions(-) + +diff -Nurp linux-3.18-rc6/arch/alpha/Kconfig linux-3.18-rc6-3rdparty/arch/alpha/Kconfig +--- linux-3.18-rc6/arch/alpha/Kconfig 2014-10-05 22:23:04.000000000 +0300 ++++ linux-3.18-rc6-3rdparty/arch/alpha/Kconfig 2014-11-29 21:42:38.015594440 +0200 +@@ -746,3 +746,4 @@ source "crypto/Kconfig" + + source "lib/Kconfig" + ++source "3rdparty/Kconfig" +diff -Nurp linux-3.18-rc6/arch/ia64/Kconfig linux-3.18-rc6-3rdparty/arch/ia64/Kconfig +--- linux-3.18-rc6/arch/ia64/Kconfig 2014-10-05 22:23:04.000000000 +0300 ++++ linux-3.18-rc6-3rdparty/arch/ia64/Kconfig 2014-11-29 21:42:38.015594440 +0200 +@@ -646,3 +646,5 @@ source "lib/Kconfig" + + config IOMMU_HELPER + def_bool (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC || SWIOTLB) ++ ++source "3rdparty/Kconfig" +diff -Nurp linux-3.18-rc6/arch/mips/Kconfig linux-3.18-rc6-3rdparty/arch/mips/Kconfig +--- linux-3.18-rc6/arch/mips/Kconfig 2014-11-29 21:37:34.434802374 +0200 ++++ linux-3.18-rc6-3rdparty/arch/mips/Kconfig 2014-11-29 21:42:38.015594440 +0200 +@@ -2709,3 +2709,5 @@ source "crypto/Kconfig" + source "lib/Kconfig" + + source "arch/mips/kvm/Kconfig" ++ ++source "3rdparty/Kconfig" +diff -Nurp linux-3.18-rc6/arch/powerpc/Kconfig linux-3.18-rc6-3rdparty/arch/powerpc/Kconfig +--- linux-3.18-rc6/arch/powerpc/Kconfig 2014-11-29 21:37:34.446802445 +0200 ++++ linux-3.18-rc6-3rdparty/arch/powerpc/Kconfig 2014-11-29 21:42:38.016594446 +0200 +@@ -1081,3 +1081,5 @@ config PPC_LIB_RHEAP + bool + + source "arch/powerpc/kvm/Kconfig" ++ ++source "3rdparty/Kconfig" +diff -Nurp linux-3.18-rc6/arch/sparc/Kconfig linux-3.18-rc6-3rdparty/arch/sparc/Kconfig +--- linux-3.18-rc6/arch/sparc/Kconfig 2014-11-29 21:37:34.478802634 +0200 ++++ linux-3.18-rc6-3rdparty/arch/sparc/Kconfig 2014-11-29 21:42:38.016594446 +0200 +@@ -562,3 +562,5 @@ source "security/Kconfig" + source "crypto/Kconfig" + + source "lib/Kconfig" ++ ++source "3rdparty/Kconfig" +diff -Nurp linux-3.18-rc6/arch/x86/Kconfig linux-3.18-rc6-3rdparty/arch/x86/Kconfig +--- linux-3.18-rc6/arch/x86/Kconfig 2014-11-29 21:37:34.488802693 +0200 ++++ linux-3.18-rc6-3rdparty/arch/x86/Kconfig 2014-11-29 21:42:38.016594446 +0200 +@@ -2509,3 +2509,5 @@ source "crypto/Kconfig" + source "arch/x86/kvm/Kconfig" + + source "lib/Kconfig" ++ ++source "3rdparty/Kconfig" +diff -Nurp linux-3.18-rc6/Makefile linux-3.18-rc6-3rdparty/Makefile +--- linux-3.18-rc6/Makefile 2014-11-29 21:37:34.352801890 +0200 ++++ linux-3.18-rc6-3rdparty/Makefile 2014-11-29 21:42:38.016594446 +0200 +@@ -556,7 +556,7 @@ scripts: scripts_basic include/config/au + + # Objects we will link into vmlinux / subdirs we need to visit + init-y := init/ +-drivers-y := drivers/ sound/ firmware/ ++drivers-y := drivers/ sound/ firmware/ 3rdparty/ + net-y := net/ + libs-y := lib/ + core-y := usr/ +diff -Nurp linux-3.18-rc6/scripts/kconfig/Makefile linux-3.18-rc6-3rdparty/scripts/kconfig/Makefile +--- linux-3.18-rc6/scripts/kconfig/Makefile 2014-11-29 21:37:35.487808590 +0200 ++++ linux-3.18-rc6-3rdparty/scripts/kconfig/Makefile 2014-11-29 21:46:48.227071462 +0200 +@@ -14,29 +14,29 @@ endif + # We need this, in case the user has it in its environment + unexport CONFIG_ + +-xconfig: $(obj)/qconf ++xconfig: $(obj)/qconf 3rdparty/Makefile + $< $(Kconfig) + +-gconfig: $(obj)/gconf ++gconfig: $(obj)/gconf 3rdparty/Makefile + $< $(Kconfig) + +-menuconfig: $(obj)/mconf ++menuconfig: $(obj)/mconf 3rdparty/Makefile + $< $(Kconfig) + +-config: $(obj)/conf ++config: $(obj)/conf 3rdparty/Makefile + $< --oldaskconfig $(Kconfig) + +-nconfig: $(obj)/nconf ++nconfig: $(obj)/nconf 3rdparty/Makefile + $< $(Kconfig) + +-oldconfig: $(obj)/conf ++oldconfig: $(obj)/conf 3rdparty/Makefile + $< --$@ $(Kconfig) + +-silentoldconfig: $(obj)/conf ++silentoldconfig: $(obj)/conf 3rdparty/Makefile + $(Q)mkdir -p include/config include/generated + $< --$@ $(Kconfig) + +-localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf ++localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf 3rdparty/Makefile + $(Q)mkdir -p include/config include/generated + $(Q)perl $< --$@ $(srctree) $(Kconfig) > .tmp.config + $(Q)if [ -f .config ]; then \ +@@ -76,24 +76,24 @@ update-po-config: $(obj)/kxgettext $(obj + + PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig + +-allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf ++allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf 3rdparty/Makefile + $< --$@ $(Kconfig) + + PHONY += listnewconfig olddefconfig oldnoconfig savedefconfig defconfig + +-listnewconfig olddefconfig: $(obj)/conf ++listnewconfig olddefconfig: $(obj)/conf 3rdparty/Makefile + $< --$@ $(Kconfig) + + # oldnoconfig is an alias of olddefconfig, because people already are dependent + # on its behavior(sets new symbols to their default value but not 'n') with the + # counter-intuitive name. +-oldnoconfig: $(obj)/conf ++oldnoconfig: $(obj)/conf 3rdparty/Makefile + $< --olddefconfig $(Kconfig) + +-savedefconfig: $(obj)/conf ++savedefconfig: $(obj)/conf 3rdparty/Makefile + $< --$@=defconfig $(Kconfig) + +-defconfig: $(obj)/conf ++defconfig: $(obj)/conf 3rdparty/Makefile + ifeq ($(KBUILD_DEFCONFIG),) + $< --defconfig $(Kconfig) + else +@@ -101,7 +101,7 @@ else + $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig) + endif + +-%_defconfig: $(obj)/conf ++%_defconfig: $(obj)/conf 3rdparty/Makefile + $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) + + configfiles=$(wildcard $(srctree)/kernel/configs/$(1).config $(srctree)/arch/$(SRCARCH)/configs/$(1).config) +@@ -178,6 +178,9 @@ gconf-objs := gconf.o zconf.tab.o + + hostprogs-y := conf nconf mconf kxgettext qconf gconf + ++3rdparty/Makefile: ++ pushd $(srctree)/3rdparty ; $(PERL) ./mkbuild.pl ; popd ++ + clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck + clean-files += zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h + clean-files += config.pot linux.pot diff --git a/kernel/kernel/files/patches/mageia/3rd-acerhk-0.5.35.patch b/kernel/kernel/files/patches/mageia/3rd-acerhk-0.5.35.patch new file mode 100644 index 00000000..5d61570f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-acerhk-0.5.35.patch @@ -0,0 +1,4212 @@ + 3rdparty/acerhk/AUTHORS | 1 + 3rdparty/acerhk/COPYING | 340 ++++ + 3rdparty/acerhk/INSTALL | 109 + + 3rdparty/acerhk/Makefile | 65 + 3rdparty/acerhk/NEWS | 16 + 3rdparty/acerhk/README | 215 ++ + 3rdparty/acerhk/acerhk.c | 2999 ++++++++++++++++++++++++++++++++++++++++ + 3rdparty/acerhk/acerhk.h | 91 + + 3rdparty/acerhk/doc/FAQ | 150 ++ + 3rdparty/acerhk/doc/IOCTL | 61 + 3rdparty/acerhk/doc/acertm.def | 56 + 3rdparty/acerhk/doc/keycodes | 26 + 3rdparty/acerhk/doc/md95400.def | 14 + 13 files changed, 4143 insertions(+) +diff -Nurp linux-2.6.37/3rdparty/acerhk/acerhk.c linux-2.6.37.3rdparty/3rdparty/acerhk/acerhk.c +--- linux-2.6.37/3rdparty/acerhk/acerhk.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/acerhk.c 2007-02-10 17:46:23.000000000 +0200 +@@ -0,0 +1,2999 @@ ++/********************************************************************* ++ * Filename: acerhk.c ++ * Version: 0.5 ++ * ++ * Copyright (C) 2002-2006, Olaf Tauber (olaf-tauber@versanet.de) ++ * ++ * Description: kernel driver for Acer Travelmate and similar ++ * laptops special keys ++ * Author: Olaf Tauber ++ * Created at: Mon Apr 29 22:16:42 2002 ++ * Modified at: Mon Oct 16 21:36:44 2006 ++ * Modified by: Olaf Tauber ++ * Modified at: Thu Nov 24 13:03:01 2005 ++ * Modified by: Antonio Cuni ++ * Modified at: Wed Oct 27 19:47:11 CEST 2004 ++ * Modified by: Joachim Fenkes ++ * ++ * This program is free software; you can redistribute ++ * it and/or modify it under the terms of the GNU General ++ * Public License as published by the Free Software ++ * Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be ++ * useful, but WITHOUT ANY WARRANTY; without even the implied ++ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ++ * PURPOSE. See the GNU General Public License for more ++ * details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this program; if not, write to the ++ * Free Software Foundation, Inc., 59 Temple Place, ++ * Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ++ */ ++ ++#ifndef AUTOCONF_INCLUDED ++#include ++#endif ++ ++/* This driver is heavily dependent on the architecture, don't let ++ * anyone without an X86 machine use it. On laptops with AMD64 ++ * architecture this driver is only useable in 32 bit mode. ++ */ ++#ifdef CONFIG_X86 ++ ++#include ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++#define KERNEL26 ++#include ++#else ++#include ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) ++#define STATIC_INPUT_DEV ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "acerhk.h" ++ ++/* #define ACERDEBUG */ ++/* #define DUMMYHW */ ++ ++#define ACERHK_VERSION "0.5.35" ++#define MODULE_NAME "acerhk" ++ ++/* maximum number of polling loops, adjust it if needed to values between ++ * 1 and 32 ++ */ ++#define MAX_POLLING_LOOPS 16U ++ ++/* maximum length for model string */ ++#define ACERHK_MODEL_STRLEN 16 ++/* size of mapped areas */ ++#define AREA_SIZE 0xffff ++/* needed for colussi algorithm */ ++#define XSIZE 20 ++ ++/* Module parameters */ ++static int poll=1; ++static int autowlan; ++static int usedritek=1; ++static int wlan_state=-1; ++static int bluetooth_state=-1; ++static int verbose; ++static unsigned int force_series; ++#ifdef KERNEL26 ++module_param(poll, int, 0444); ++module_param(autowlan, int, 0444); ++module_param(usedritek, int, 0444); ++module_param(verbose, int, 0444); ++module_param(wlan_state, int, 0444); ++module_param(bluetooth_state, int, 0444); ++module_param(force_series, uint, 0444); ++#else ++MODULE_PARM(poll, "i"); ++MODULE_PARM(autowlan, "i"); ++MODULE_PARM(wlan_state, "i"); ++MODULE_PARM(bluetooth_state, "i"); ++MODULE_PARM(usedritek, "i"); ++MODULE_PARM(verbose, "i"); ++MODULE_PARM(force_series, "i"); ++#endif ++MODULE_PARM_DESC(poll, "start polling timer"); ++MODULE_PARM_DESC(autowlan, "automatic switching of wlan hardware"); ++MODULE_PARM_DESC(wlan_state, "(assumed) initial state of WLAN LED/hardware"); ++MODULE_PARM_DESC(bluetooth_state, "(assumed) initial state of Bluetooth LED/hardware"); ++MODULE_PARM_DESC(usedritek, "enable dritek keyboard extension"); ++MODULE_PARM_DESC(verbose, "output additional information"); ++MODULE_PARM_DESC(force_series, "force laptop series, skip autodetection"); ++ ++/* input device */ ++static struct input_dev *acerhk_input_dev_ptr; ++#ifdef STATIC_INPUT_DEV ++static struct input_dev acerhk_input_dev; ++#endif ++ ++/* mapped IO area from 0xf0000 */ ++static void *reg1; ++/* mapped IO area from 0xe0000 */ ++static void *reg2; ++/* Pointer to mapped area at 0x400 on 520 series */ ++static void *preg400; ++/* location of IO routine in mapped area */ ++static unsigned int bios_routine; ++/* index of CMOS port to get key event */ ++static unsigned int cmos_index; ++/* function for bios call */ ++static bios_call call_bios; ++/* address of model string */ ++static char *acerhk_model_addr; ++/* copied string, maximum length 16 ('TravelMate xxx') */ ++static char acerhk_model_string[ACERHK_MODEL_STRLEN]; ++/* type of hardware access */ ++static t_acer_type acerhk_type; ++/* travelmate series */ ++static unsigned int acerhk_series; ++/* supported features for this model */ ++static unsigned int acerhk_model_features; ++/* map of acer key codes to acer key names */ ++static unsigned char acerhk_key2name[0xff]; ++/* map of acer key names to key events */ ++static t_map_name2event acerhk_name2event; ++/* timer for polling key presses */ ++static struct timer_list acerhk_timer_poll; ++/* polling active */ ++static int acerhk_polling_state; ++/* polling delay */ ++static unsigned acerhk_polling_delay = HZ/5; ++/* wlan hardware toggle */ ++static int acerhk_wlan_state; ++/* bluetooth hardware toggle */ ++static int acerhk_bluetooth_state; ++ ++/* bluetooth blinking state; added by Antonio Cuni ++ possible values: ++ -1: blinking disabled (default) ++ 0: blinking enabled, led currently off ++ 1: blinking enabled, led currently on ++*/ ++static int acerhk_blueled_blinking = -1; ++/* delay between two changes of state, in jiffies */ ++static unsigned acerhk_blueled_blinking_delay; ++/* timer for blinking */ ++static struct timer_list acerhk_timer_blinking; ++ ++/* function prototypes */ ++static void start_polling(void); ++static void stop_polling(void); ++ ++/* Added by Antonio Cuni */ ++static void start_blinking(void); ++static void stop_blinking(void); ++ ++/* {{{ Experimental use of dritek keyboard extension */ ++ ++#define EC_STATUS_REG 0x66 /* Status register of EC (R) */ ++#define EC_CNTL_REG 0x66 /* Controller command register of EC (W) */ ++#define EC_DATA_REG 0x62 /* EC data register (R/W) */ ++ ++#ifdef KERNEL26 ++ ++#include ++ ++#define KBD_STATUS_REG 0x64 /* Status register (R) */ ++#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ ++#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ ++ ++#else ++ ++#ifndef KEY_MEDIA ++#define KEY_MEDIA 226 ++#endif ++ ++#define preempt_disable() do { } while (0) ++#define preempt_enable_no_resched() do { } while (0) ++#define preempt_enable() do { } while (0) ++#define preempt_check_resched() do { } while (0) ++#include ++ ++#endif ++ ++static inline int my_i8042_read_status(void) ++{ ++ return inb(KBD_STATUS_REG); ++} ++static int my_i8042_wait_write(void) ++{ ++ int i = 0; ++ while ((my_i8042_read_status() & 0x02) && (i < 10000)) { ++ udelay(50); ++ i++; ++ } ++ return -(i == 10000); ++} ++static void send_kbd_cmd(unsigned char cmd, unsigned char val) ++{ ++ if (usedritek) { ++ preempt_disable(); ++ if (!my_i8042_wait_write()) ++ outb(cmd, KBD_CNTL_REG); ++ if (!my_i8042_wait_write()) ++ outb(val, KBD_DATA_REG); ++ preempt_enable_no_resched(); ++ } else { ++ printk(KERN_INFO"acerhk: request for accessing EC ignored\n" ++ KERN_INFO"acerhk: Use of dritek keyboard extension not enabled, use module\n" ++ KERN_INFO"acerhk: parameter usedritek=1 to do that (possibly dangerous)\n"); ++ } ++} ++#ifdef ACERDEBUG ++static inline int my_i8042_read_ecstatus(void) ++{ ++ return inb(EC_STATUS_REG); ++} ++static int my_i8042_wait_ecwrite(void) ++{ ++ int i = 0; ++ while ((my_i8042_read_ecstatus() & 0x02) && (i < 10000)) { ++ udelay(50); ++ i++; ++ } ++ return -(i == 10000); ++} ++static void send_ec_cmd(unsigned char cmd, unsigned char val) ++{ ++ if (usedritek) { ++ preempt_disable(); ++ if (!my_i8042_wait_ecwrite()) ++ outb(cmd, EC_CNTL_REG); ++ if (!my_i8042_wait_ecwrite()) ++ outb(val, EC_DATA_REG); ++ preempt_enable_no_resched(); ++ } else { ++ printk(KERN_INFO"acerhk: request for accessing EC ignored\n" ++ KERN_INFO"acerhk: Use of dritek keyboard extension not enabled, use module\n" ++ KERN_INFO"acerhk: parameter usedritek=1 to do that (possibly dangerous)\n"); ++ } ++} ++#endif ++#ifdef ACERDEBUG ++static void enable_mute_led_ec(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling mute led via EC\n"); ++ send_kbd_cmd(0x59, 0x94); ++} ++static void disable_mute_led_ec(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling mute led via EC\n"); ++ send_kbd_cmd(0x59, 0x95); ++} ++static void enable_dmm_function(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling WLAN via EC variant 2\n"); ++ send_kbd_cmd(0x45, 0xd3); ++} ++#endif ++static void enable_wlan_ec_1(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling WLAN via EC variant 1\n"); ++ send_kbd_cmd(0xe7, 0x01); ++ acerhk_wlan_state = 1; ++} ++static void disable_wlan_ec_1(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling WLAN via EC variant 1\n"); ++ send_kbd_cmd(0xe7, 0x00); ++ acerhk_wlan_state = 0; ++} ++static void enable_bluetooth_ec_1(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling Bluetooth via EC variant 1\n"); ++ send_kbd_cmd(0xe7, 0x03); ++ acerhk_bluetooth_state = 1; ++} ++static void disable_bluetooth_ec_1(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling Bluetooth via EC variant 1\n"); ++ send_kbd_cmd(0xe7, 0x02); ++ acerhk_bluetooth_state = 0; ++} ++static void enable_wlan_ec_2(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling WLAN via EC variant 2\n"); ++ send_kbd_cmd(0x45, acerhk_bluetooth_state ? 0xa2 : 0xa0); ++ acerhk_wlan_state = 1; ++} ++static void disable_wlan_ec_2(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling WLAN via EC variant 2\n"); ++ send_kbd_cmd(0x45, acerhk_bluetooth_state ? 0xa1 : 0xa3); ++ acerhk_wlan_state = 0; ++} ++static void enable_bluetooth_ec_2(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling Bluetooth via EC variant 2\n"); ++ send_kbd_cmd(0x45, acerhk_wlan_state ? 0xa2 : 0xa1); ++ acerhk_bluetooth_state = 1; ++} ++static void disable_bluetooth_ec_2(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling Bluetooth via EC variant 2\n"); ++ send_kbd_cmd(0x45, acerhk_wlan_state ? 0xa0 : 0xa3); ++ acerhk_bluetooth_state = 0; ++} ++#ifdef ACERDEBUG ++static void enable_wireless_ec(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling wireless hardware\n"); ++ if (usedritek) { ++ preempt_disable(); ++ if (!my_i8042_wait_ecwrite()) ++ outb(0x4d, EC_CNTL_REG); ++ if (!my_i8042_wait_ecwrite()) ++ outb(0xd2, EC_DATA_REG); ++ if (!my_i8042_wait_ecwrite()) ++ outb(0x01, EC_DATA_REG); ++ preempt_enable_no_resched(); ++ } ++ acerhk_wlan_state = 1; ++} ++static void disable_wireless_ec(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling wireless hardware\n"); ++ if (usedritek) { ++ preempt_disable(); ++ if (!my_i8042_wait_ecwrite()) ++ outb(0x4d, EC_CNTL_REG); ++ if (!my_i8042_wait_ecwrite()) ++ outb(0xd2, EC_DATA_REG); ++ if (!my_i8042_wait_ecwrite()) ++ outb(0x00, EC_DATA_REG); ++ preempt_enable_no_resched(); ++ } ++ acerhk_wlan_state = 0; ++} ++#endif ++static void enable_dritek_keyboard(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling dritek keyboard extension\n"); ++ send_kbd_cmd(0x59, 0x90); ++} ++static void disable_dritek_keyboard(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling dritek keyboard extension\n"); ++ send_kbd_cmd(0x59, 0x91); ++} ++static void enable_mail_led_ec_1(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling mail led via EC variant 1\n"); ++ send_kbd_cmd(0xe8, 0x01); ++} ++static void disable_mail_led_ec_1(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling mail led via EC variant 1\n"); ++ send_kbd_cmd(0xe8, 0x00); ++} ++ ++static void enable_mail_led_ec_2(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling mail led via EC variant 2\n"); ++ send_kbd_cmd(0x59, 0x92); ++} ++static void disable_mail_led_ec_2(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling mail led via EC variant 2\n"); ++ send_kbd_cmd(0x59, 0x93); ++} ++static void enable_mail_led_ec_3(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: enabling mail led via EC variant 3\n"); ++ if (usedritek) { ++ preempt_disable(); ++ if (!my_i8042_wait_write()) ++ outl(0x80008894, 0xCF8); ++ if (!my_i8042_wait_write()) ++ outw(0xC061, 0xCFC); ++ preempt_enable_no_resched(); ++ } ++} ++static void disable_mail_led_ec_3(void) ++{ ++ if (verbose) ++ printk(KERN_INFO "acerhk: disabling mail led via EC variant 3\n"); ++ if (usedritek) { ++ preempt_disable(); ++ if (!my_i8042_wait_write()) ++ outl(0x80008894, 0xCF8); ++ if (!my_i8042_wait_write()) ++ outw(0xC060, 0xCFC); ++ preempt_enable_no_resched(); ++ } ++} ++ ++/* }}} */ ++ ++/* {{{ string search functions */ ++ ++/* This is the Colussi algorithm, the code is taken from ++ http://www-igm.univ-mlv.fr/~lecroq/string ++*/ ++int preColussi(char *x, int m, int *h, int *next, int *shift) ++{ ++ int i, k, nd, q, r, s; ++ int hmax[XSIZE], kmin[XSIZE], nhd0[XSIZE], rmin[XSIZE]; ++ /* Computation of hmax */ ++ i = k = 1; ++ do { ++ while (x[i] == x[i - k]) ++ i++; ++ hmax[k] = i; ++ q = k + 1; ++ while (hmax[q - k] + k < i) { ++ hmax[q] = hmax[q - k] + k; ++ q++; ++ } ++ k = q; ++ if (k == i + 1) ++ i = k; ++ } while (k <= m); /* Computation of kmin */ ++ memset(kmin, 0, m*sizeof(int)); ++ r = 0; ++ for (i = m; i >= 1; --i) ++ if (hmax[i] < m) ++ kmin[hmax[i]] = i; /* Computation of rmin */ ++ for (i = m - 1; i >= 0; --i) { ++ if (hmax[i + 1] == m) ++ r = i + 1; ++ if (kmin[i] == 0) ++ rmin[i] = r; ++ else ++ rmin[i] = 0; ++ } /* Computation of h */ ++ s = -1; ++ r = m; ++ for (i = 0; i < m; ++i) ++ if (kmin[i] == 0) ++ h[--r] = i; ++ else ++ h[++s] = i; ++ nd = s; /* Computation of shift */ ++ for (i = 0; i <= nd; ++i) ++ shift[i] = kmin[h[i]]; ++ for (i = nd + 1; i < m; ++i) ++ shift[i] = rmin[h[i]]; ++ shift[m] = rmin[0]; /* Computation of nhd0 */ ++ s = 0; ++ for (i = 0; i < m; ++i) { ++ nhd0[i] = s; ++ if (kmin[i] > 0) ++ ++s; ++ } /* Computation of next */ ++ for (i = 0; i <= nd; ++i) ++ next[i] = nhd0[h[i] - kmin[h[i]]]; ++ for (i = nd + 1; i < m; ++i) ++ next[i] = nhd0[m - rmin[h[i]]]; ++ next[m] = nhd0[m - rmin[h[m - 1]]]; return(nd); ++} ++ ++int COLUSSI(char *x, int m, char *y, int n) { ++ int i, j, last, nd, ++ h[XSIZE], next[XSIZE], shift[XSIZE]; /* Processing */ ++ int match_pos; /* position of first match */ ++ nd = preColussi(x, m, h, next, shift); /* Searching */ ++ i = j = 0; ++ last = -1; ++ match_pos = -1; ++ while ( (match_pos == -1) ++ && (j <= n - m) ) { ++ while (i < m && last < j + h[i] && ++ x[h[i]] == y[j + h[i]]) ++ i++; ++ if (i >= m || last >= j + h[i]) { ++ /* Match found, bail out */ ++ match_pos = j; ++ i = m; ++ } ++ if (i > nd) ++ last = j + m - 1; ++ j += shift[i]; ++ i = next[i]; ++ } ++ return match_pos; ++} ++ ++/* }}} */ ++ ++/* {{{ hardware access functions */ ++ ++/* call_bios_ ++ * ++ * call request handler in mapped system rom ++ * ++ * the request is handed over via all 6 general purpose registers, results are ++ * taken from them and copied back to buf ++ */ ++static asmlinkage void call_bios_6xx(struct register_buffer *buf) ++{ ++ if (bios_routine) { ++ local_irq_disable(); ++ __asm__ __volatile__( ++ "movl %1,%%edx\n\t" ++ "pusha\n\t" ++ "movl %%edx,%%ebp\n\t" ++ "movl (%%ebp),%%eax\n\t" ++ "movl 4(%%ebp),%%ebx\n\t" ++ "movl 8(%%ebp),%%ecx\n\t" ++ "movl 12(%%ebp),%%edx\n\t" ++ "movl 16(%%ebp),%%edi\n\t" ++ "movl 20(%%ebp),%%esi\n\t" ++ "pushl %%ebp\n\t" ++ "call *%0\n\t" ++ "popl %%ebp\n\t" ++ "movl %%eax, (%%ebp)\n\t" ++ "movl %%ebx, 4(%%ebp)\n\t" ++ "movl %%ecx, 8(%%ebp)\n\t" ++ "movl %%edx, 12(%%ebp)\n\t" ++ "movl %%edi, 16(%%ebp)\n\t" ++ "movl %%esi, 20(%%ebp)\n\t" ++ "popa\n\t" ++ : ++ :"m" (bios_routine), "m" (buf) ++ :"%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi", "%ebp" ++ ); ++ local_irq_enable(); ++ } ++} ++ ++static asmlinkage void call_bios_52x(struct register_buffer *buf) ++{ ++ if (bios_routine) { ++ local_irq_disable(); ++ __asm__ __volatile__( ++ "movl %2,%%edx\n\t" ++ "pusha\n\t" ++ "movl %%edx,%%ebp\n\t" ++ "movl (%%ebp),%%eax\n\t" ++ "movl 4(%%ebp),%%ebx\n\t" ++ "movl 8(%%ebp),%%ecx\n\t" ++ "movl 12(%%ebp),%%edx\n\t" ++ "movl 16(%%ebp),%%edi\n\t" ++ "movl 20(%%ebp),%%esi\n\t" ++ "pushl %%ebp\n\t" ++ "movl %1, %%ebp\n\t" ++ "call *%0\n\t" ++ "popl %%ebp\n\t" ++ "movl %%eax, (%%ebp)\n\t" ++ "movl %%ebx, 4(%%ebp)\n\t" ++ "movl %%ecx, 8(%%ebp)\n\t" ++ "movl %%edx, 12(%%ebp)\n\t" ++ "movl %%edi, 16(%%ebp)\n\t" ++ "movl %%esi, 20(%%ebp)\n\t" ++ "popa\n\t" ++ : ++ :"m" (bios_routine), "m" (preg400), "m" (buf) ++ :"%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi", "%ebp" ++ ); ++ local_irq_enable(); ++ } ++} ++ ++#define PRINT_BUFFER(x) \ ++ printk(KERN_INFO"acerhk: eax=0x%x ebx=0x%x ecx=0x%x edx=0x%x\n" \ ++ "acerhk: edi=0x%x esi=0x%x ebp=0x%x\n", \ ++ x.eax, x.ebx, x.ecx, x.edx, x.edi, x.esi, x.ebp); ++ ++/* get_fnkey_event ++ * ++ * gets the first (oldest) key id from the queue of events ++ * ++ * return value: id of key ++ */ ++static int get_fnkey_event(void) ++{ ++ struct register_buffer regs; ++ regs.eax = 0x9610; ++ regs.ebx = 0x61C; ++ /* clear other registers, some models need this */ ++ regs.ecx = 0; ++ regs.edx = 0; ++ preempt_disable(); ++ call_bios(®s); ++ preempt_enable_no_resched(); ++ return regs.eax & 0xffff; ++} ++ ++/* get_thermal_event ++ * ++ * does what? ++ * ++ * return value: event ? ++ */ ++static int get_thermal_event(void) ++{ ++ struct register_buffer regs; ++ if (acerhk_model_features & TM_F_THERMAL) { ++ regs.eax = 0x9612; ++ regs.ebx = 0x12e; ++ preempt_disable(); ++ call_bios(®s); ++ preempt_enable_no_resched(); ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: thermal event = 0x%x\n", regs.eax); ++ } else { ++ regs.eax = 0x00; ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: thermal event not supported\n"); ++ } ++ return regs.eax & 0xffff; ++} ++ ++#ifdef ACERDEBUG ++/* pbutton_fct ++ * ++ * does what? ++ * ++ * return value: ? ++ */ ++static int pbutton_fct(void) ++{ ++ struct register_buffer regs; ++ if (acerhk_model_features & TM_F_PBUTTON) { ++ regs.eax = 0x9612; ++ regs.ebx = 0x10b; ++ regs.ecx = 0x2; ++ preempt_disable(); ++ call_bios(®s); ++ preempt_enable_no_resched(); ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: pbutton = 0x%x\n", regs.eax); ++ } else { ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: pbutton function not supported\n"); ++ regs.eax = 0x00; ++ } ++ return regs.eax & 0xffff; ++} ++#endif ++ ++/* wbutton_fct_1 ++ * ++ * turn on installed Bluetooth hardware together with the corresponding LED ++ * ++ * val: 0 turns off the LED ++ * 1 turns the LED to green/blue ++ * ++ * return value: ? ++ */ ++static int wbutton_fct_1(int val) ++{ ++ struct register_buffer regs; ++ if (acerhk_model_features & TM_F_WBUTTON) { ++ acerhk_bluetooth_state = val; ++ regs.eax = 0x9610; ++ regs.ebx = ((val & 0xff) << 8) | 0x34; ++ preempt_disable(); ++ call_bios(®s); ++ preempt_enable_no_resched(); ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: wbutton1 = 0x%x\n", regs.eax); ++ } else { ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: wbutton function 1 not supported\n"); ++ regs.eax = 0x00; ++ } ++ return regs.eax & 0xffff; ++} ++ ++/* wbutton_fct_2 ++ * ++ * turn on installed WLAN hardware together with the corresponding LED ++ * ++ * val: 0 turns off the LED ++ * 1 turns the LED to orange ++ * ++ * return value: ? ++ */ ++static int wbutton_fct_2(int val) ++{ ++ struct register_buffer regs; ++ if (acerhk_model_features & TM_F_WBUTTON) { ++ acerhk_wlan_state = val; ++ regs.eax = 0x9610; ++ regs.ebx = ((val & 0xff) << 8) | 0x35; ++ preempt_disable(); ++ call_bios(®s); ++ preempt_enable_no_resched(); ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: wbutton2 = 0x%x\n", regs.eax); ++ } else { ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: wbutton function 2 not supported\n"); ++ regs.eax = 0x00; ++ } ++ return regs.eax & 0xffff; ++} ++ ++/* get_cmos_index ++ * ++ * gets index of CMOS port from ROM. The number of events is monitored ++ * in this port. ++ * ++ * return value: index of CMOS port ++ */ ++static int get_cmos_index(void) ++{ ++ struct register_buffer regs; ++ regs.eax = 0x9610; ++ regs.ebx = 0x51C; ++ preempt_disable(); ++ call_bios(®s); ++ preempt_enable_no_resched(); ++ cmos_index = regs.ecx & 0xff; ++ if (verbose) ++ printk(KERN_INFO"acerhk: cmos index set to 0x%x\n", cmos_index); ++ return cmos_index; ++} ++ ++/* get_nr_events ++ * ++ * gets the number of cached events (keys pressed) in queue. Up to 31 events ++ * are cached. ++ * ++ * return value: number of events in queue ++ */ ++static int get_nr_events(void) ++{ ++ unsigned long flags; ++ unsigned char c = 0; ++ ++ spin_lock_irqsave (&rtc_lock, flags); ++#ifndef DUMMYHW ++ if (cmos_index) ++ c = CMOS_READ(cmos_index); ++ else if (verbose > 3) ++ printk(KERN_INFO"acerhk: get_nr_events - no valid cmos index set\n"); ++#endif ++ spin_unlock_irqrestore (&rtc_lock, flags); ++ return c; ++} ++ ++/* set_mail_led ++ * ++ * change state of mail led ++ * ++ * val: 0 - switch led off ++ * 1 - switch led on (blinking) ++ * ++ * return value: 1 - action succesfull (val valid) ++ * 0 - no action taken (val invalid) ++ */ ++static int set_mail_led(int val) ++{ ++ struct register_buffer regs; ++ if (acerhk_model_features & TM_F_MAIL_LED) { ++ regs.eax = 0x9610; ++ regs.ebx = ((val & 0xff) << 8) | 0x31; ++ preempt_disable(); ++ call_bios(®s); ++ preempt_enable_no_resched(); ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: mail led set to = 0x%x\n", val); ++ } else if (acerhk_model_features & TM_F_MAIL_LED_EC) { ++ if (val == 1) ++ enable_mail_led_ec_1(); ++ else if (val == 0) ++ disable_mail_led_ec_1(); ++ } else if (acerhk_model_features & TM_F_MAIL_LED_EC2) { ++ if (val == 1) ++ enable_mail_led_ec_2(); ++ else if (val == 0) ++ disable_mail_led_ec_2(); ++ } else if (acerhk_model_features & TM_F_MAIL_LED_EC3) { ++ if (val == 1) ++ enable_mail_led_ec_3(); ++ else if (val == 0) ++ disable_mail_led_ec_3(); ++ } else { ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: mail led not supported\n"); ++ regs.eax = 0x00; ++ } ++ return regs.eax & 0xffff; ++} ++ ++/* launch_connect ++ * ++ * does what? ++ * val: 1 - only known value from windows driver ++ */ ++static int launch_connect(int val) ++{ ++ struct register_buffer regs; ++ if (acerhk_model_features & TM_F_CONNECT) { ++ regs.eax = 0x9610; ++ regs.ebx = ((val & 0xff) << 8) | 0x2e; ++ preempt_disable(); ++ call_bios(®s); ++ preempt_enable_no_resched(); ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: connect(%d) = 0x%x\n", val, regs.eax); ++ } else { ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: connect not supported\n"); ++ regs.eax = 0x00; ++ } ++ return regs.eax & 0xffff; ++} ++ ++/* }}} */ ++ ++/* {{{ hardware probing */ ++ ++static struct proc_dir_entry *proc_acer_dir; ++ ++static unsigned int __init find_hk_area(void) ++{ ++ int offset, sig; ++ unsigned int fkt; ++ fkt = 0; ++ sig = -1; /* offset to signature in io area */ ++ /* Look for signature, start at 0xf0000, search until 0xffff0 */ ++ for (offset = 0;offset < 0xfffd; offset += 16) { ++ if (readl(reg1 + offset) == 0x30552142) { ++ sig = offset; ++ offset = 0xffff; ++ } ++ } ++ if (sig < 0) ++ printk(KERN_WARNING"acerhk: could not find request handler, possibly not all functions available\n"); ++ else { ++ /* compute location of bios routine */ ++ fkt = readl(reg1 + sig + 5); ++ /* adjust fkt to address of mapped IO area */ ++ if (fkt >= 0xf0000) ++ fkt = (unsigned int)reg1 + fkt - 0xf0000; ++ else if (fkt >= 0xe0000) ++ fkt = (unsigned int)reg1 + fkt - 0xe0000; ++ else ++ fkt = 0; ++ } ++ return fkt; ++} ++ ++static void print_features(void) ++{ ++ int i; ++ printk(KERN_INFO"acerhk: supported keys:"); ++ for (i = 0; i < 255; i++) { ++ switch (acerhk_key2name[i]) { ++ case k_help: printk(" help"); break; ++ case k_setup: printk(" setup"); break; ++ case k_p1: printk(" p1"); break; ++ case k_p2: printk(" p2"); break; ++ case k_p3: printk(" p3"); break; ++ case k_www: printk(" www"); break; ++ case k_mail: printk(" mail"); break; ++ case k_wireless: printk(" wireless"); break; ++ case k_power: printk(" power"); break; ++ case k_mute: printk(" mute"); break; ++ case k_volup: printk(" volup"); break; ++ case k_voldn: printk(" voldn"); break; ++ case k_res: printk(" res"); break; ++ case k_close: printk(" close"); break; ++ case k_open: printk(" open"); break; ++ case k_wireless2: printk(" wireless2"); break; ++ case k_play: printk(" play"); break; ++ case k_stop: printk(" stop"); break; ++ case k_prev: printk(" prev"); break; ++ case k_next: printk(" next"); break; ++ case k_display: printk(" display"); break; ++ default: break; ++ } ++ } ++ printk("\n"); ++ if (acerhk_model_features & TM_F_MUTE_LED_EC) ++ printk(KERN_INFO"acerhk: mute led is supported\n"); ++ if (acerhk_model_features & TM_F_MAIL_LED) ++ printk(KERN_INFO"acerhk: mail led is supported\n"); ++ else if (acerhk_model_features & TM_F_MAIL_LED_EC) ++ printk(KERN_INFO"acerhk: mail led (EC) is supported\n"); ++ else if (acerhk_model_features & TM_F_MAIL_LED_EC2) ++ printk(KERN_INFO"acerhk: mail led (EC2) is supported\n"); ++ else if (acerhk_model_features & TM_F_MAIL_LED_EC3) ++ printk(KERN_INFO"acerhk: mail led (EC3) is supported\n"); ++ if (acerhk_model_features & TM_F_WLAN_EC1) ++ printk(KERN_INFO"acerhk: wlan control (EC1) is supported\n"); ++ else if (acerhk_model_features & TM_F_WLAN_EC2) ++ printk(KERN_INFO"acerhk: wlan control (EC2) is supported\n"); ++ if (acerhk_model_features & TM_F_BLUE_EC1) ++ printk(KERN_INFO"acerhk: bluetooth control (EC1) is supported\n"); ++ else if (acerhk_model_features & TM_F_BLUE_EC2) ++ printk(KERN_INFO"acerhk: bluetooth control (EC2) is supported\n"); ++ printk(KERN_INFO"acerhk: supported functions:"); ++ if (acerhk_model_features & TM_F_CONNECT) ++ printk(" connect"); ++ if (acerhk_model_features & TM_F_THERMAL) ++ printk(" thermal"); ++ if (acerhk_model_features & TM_F_PBUTTON) ++ printk(" pbutton"); ++ if (acerhk_model_features & TM_F_WBUTTON) ++ printk(" wbutton"); ++ printk("\n"); ++} ++ ++static void __init setup_keymap_model(unsigned int series) ++{ ++ /* clear mapping keycode -> keyname, */ ++ memset(&acerhk_key2name[0], k_none, sizeof(acerhk_key2name)); ++ /* first set the common keys, namely FnF1 and FnF2, */ ++ acerhk_key2name[1] = k_help; ++ acerhk_key2name[2] = k_setup; ++ /* then set known keycodes according to model */ ++ switch (series) { ++ case 110: ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[3] = k_power; ++ acerhk_key2name[8] = k_mute; ++ acerhk_key2name[32] = k_volup; ++ acerhk_key2name[33] = k_voldn; ++ /* C110 generates 2 extra codes when opening/closing the lid */ ++ acerhk_key2name[74] = k_close; ++ acerhk_key2name[75] = k_open; ++ break; ++ case 300: /* treat C300 like C100 with Bluetooth button */ ++ acerhk_key2name[68] = k_wireless2; ++ case 100: ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[49] = k_www; ++ acerhk_key2name[54] = k_mail; ++ acerhk_key2name[3] = k_power; ++ acerhk_key2name[8] = k_mute; ++ acerhk_key2name[32] = k_volup; ++ acerhk_key2name[33] = k_voldn; ++ break; ++ default: ++ /* only the two common keys are supported */ ++ break; ++ case 210: ++ acerhk_key2name[19] = k_p1; ++ acerhk_key2name[20] = k_p2; ++ acerhk_key2name[17] = k_www; ++ acerhk_key2name[18] = k_mail; ++ break; ++ case 220: ++ case 260: /* 260 with same keys? */ ++ acerhk_key2name[49] = k_p1; ++ acerhk_key2name[19] = k_p2; ++ acerhk_key2name[18] = k_www; ++ acerhk_key2name[17] = k_mail; ++ break; ++ case 230: ++ case 280: /* 280 with same keys? */ ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[54] = k_www; ++ break; ++ case 1500: ++ acerhk_key2name[0x49] = k_setup; ++ acerhk_key2name[0x36] = k_www; ++ acerhk_key2name[0x31] = k_mail; ++ acerhk_key2name[0x11] = k_p1; ++ acerhk_key2name[0x12] = k_p2; ++ acerhk_key2name[0x30] = k_wireless; ++ acerhk_key2name[0x44] = k_wireless2; ++ acerhk_key2name[0x03] = k_power; ++ break; ++ case 240: ++ acerhk_key2name[0x31] = k_www; ++ acerhk_key2name[0x36] = k_mail; ++ acerhk_key2name[0x11] = k_p1; ++ acerhk_key2name[0x12] = k_p2; ++ acerhk_key2name[0x44] = k_wireless; ++ acerhk_key2name[0x30] = k_wireless2; ++ acerhk_key2name[0x03] = k_power; ++ acerhk_key2name[0x08] = k_mute; ++ // acerhk_key2name[] = k_volup; ++ // acerhk_key2name[] = k_voldn; ++ break; ++ case 2900: ++ acerhk_key2name[0x31] = k_mail; /* with led */ ++ acerhk_key2name[0x36] = k_www; ++ acerhk_key2name[0x11] = k_p1; ++ acerhk_key2name[0x12] = k_p2; ++ acerhk_key2name[0x30] = k_wireless; /* wireless, with led, related with autowlan=1 */ ++ break; ++ case 250: /* enriqueg@altern.org */ ++ /* TravelMate 254LMi_DT manual common for 240/250 series, but key order ++ differ from 240 already present on acerhk driver */ ++ /* TravelMate 254LMi_DT: 6 buttons: left to right: mail, www, p1, p2, bluetooth, wireless */ ++ acerhk_key2name[0x31] = k_mail; /* with led */ ++ acerhk_key2name[0x36] = k_www; ++ acerhk_key2name[0x11] = k_p1; ++ acerhk_key2name[0x12] = k_p2; ++ acerhk_key2name[0x44] = k_wireless2; /* bluetooth, hw optional */ ++ acerhk_key2name[0x30] = k_wireless; /* wireless, with led, related with autowlan=1 */ ++ acerhk_key2name[0x03] = k_power; /* Fn+F3 */ ++ acerhk_key2name[0x08] = k_mute; /* Fn+F8 */ ++ break; ++ case 380: ++ /* TM 380 has same codes as TM 370, with an additional one */ ++ acerhk_key2name[0x03] = k_power; ++ case 370: ++ acerhk_key2name[0x30] = k_wireless; ++ acerhk_key2name[0x11] = k_p1; ++ acerhk_key2name[0x12] = k_p2; ++ acerhk_key2name[0x13] = k_p3; ++ acerhk_key2name[0x36] = k_www; ++ acerhk_key2name[0x31] = k_mail; ++ break; ++ case 360: ++ /* 360 series has the same layout as 350, with an ++ additional wireless key */ ++ acerhk_key2name[64] = k_wireless; ++ case 350: ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[20] = k_p3; ++ acerhk_key2name[21] = k_www; ++ acerhk_key2name[19] = k_mail; ++ break; ++ case 520: ++ acerhk_key2name[19] = k_p1; ++ acerhk_key2name[20] = k_p2; ++ acerhk_key2name[17] = k_www; ++ acerhk_key2name[18] = k_mail; ++ break; ++ case 610: ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[19] = k_p3; ++ acerhk_key2name[21] = k_www; ++ acerhk_key2name[20] = k_mail; ++ acerhk_key2name[64] = k_wireless; ++ break; ++ case 630: ++ /* 630 has all keys of 620 plus one */ ++ acerhk_key2name[8] = k_mute; ++ case 620: ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[19] = k_p3; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[3] = k_power; ++ acerhk_key2name[32] = k_volup; ++ acerhk_key2name[33] = k_voldn; ++ break; ++ case 290: ++ case 420: ++ case 430: ++ case 530: ++ case 540: ++ case 650: ++ case 660: ++ case 800: ++ case 1450: ++ case 2300: ++ case 2350: ++ case 4000: ++ case 4050: ++ case 6000: ++ case 8000: ++ case 4100: ++ case 4150: ++ case 4500: ++ case 4600: ++ case 4650: ++ case 1680: ++ case 1690: ++ /* keys are handled by dritek EC */ ++ acerhk_key2name[1] = k_none; ++ acerhk_key2name[2] = k_none; ++ break; ++ case 1300: ++ case 1310: ++ case 1350: ++ case 1360: ++ case 1400: ++ case 1700: ++ case 1800: ++ case 2000: ++ case 2010: ++ case 2020: ++ /* Aspire 13xx series laptops use dritek hardware, no ++ acerhk-mapping needed ++ VolUp and VolDown are managed as normal keys ++ 1300/1310 series should have P1, P2, Mail, WWW, Mute buttons ++ 1353 has bluetooth, wifi, p1, p2, www, mail, help, setup, power ++ and mute ++ Aspire 1400/1450/Ferrari use dritek EC, too ++ 1450 should have bluetooth, wifi, p1, p2, www, mail, help, ++ setup, power and mute ++ Aspire 1700 uses dritek EC, too ++ 1700 should have bluetooth, wifi, p1, p2, www, mail, help, ++ setup, power and mute ++ need the MM-buttons Activation? (forward, shuffle, ...) ++ 2000 hast lots of MM buttons ++ 2010 should have bluetooth, wifi, p1, p2, www, mail, help, ++ setup, power and mute ++ */ ++ acerhk_key2name[1] = k_none; ++ acerhk_key2name[2] = k_none; ++ break; ++ case 1600: ++ /* Aspire 1600 has acer keycode 0x49 for FnF2 */ ++ acerhk_key2name[73] = k_setup; ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[19] = k_p3; ++ acerhk_key2name[3] = k_power; ++ acerhk_key2name[8] = k_mute; ++ /* VolUp and VolDown keys doesn't seem to be managed as special keys ++ but as normal keys ! */ ++ break; ++ case 5020: /* Aspire 5020 has 0x6a for Fn+F2 */ ++ acerhk_key2name[2] = k_none; ++ acerhk_key2name[106] = k_setup; ++ acerhk_key2name[3] = k_power; ++ acerhk_key2name[5] = k_display; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[68] = k_wireless2; ++ break; ++ case 2410: /* TM 2410 is very similar to Aspire 5020, but has 0x6s for Fn-F3 */ ++ acerhk_key2name[2] = k_none; ++ acerhk_key2name[106] = k_setup; ++ acerhk_key2name[109] = k_power; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[68] = k_wireless2; ++ break; ++ case 40100: ++ /* Medion MD40100, 4 keys */ ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[55] = k_res; ++ break; ++ case 96500: ++ case 95400: ++ /* Medion MD95400, many keys */ ++ acerhk_key2name[49] = k_mail; /* 1 */ ++ acerhk_key2name[54] = k_www; /* 2 */ ++ acerhk_key2name[48] = k_wireless; /* 3 */ ++ acerhk_key2name[68] = k_wireless2; /* 4 (Bluetooth) */ ++ ++ acerhk_key2name[17] = k_p1; /* 5 */ ++ acerhk_key2name[18] = k_p2; /* 6 */ ++ acerhk_key2name[36] = k_play; /* 7 */ ++ acerhk_key2name[37] = k_stop; /* 8 */ ++ acerhk_key2name[34] = k_prev; /* 9 */ ++ acerhk_key2name[35] = k_next; /* 10 */ ++ acerhk_key2name[33] = k_voldn; /* 11 */ ++ acerhk_key2name[32] = k_volup; /* 12 */ ++ acerhk_key2name[38] = k_p3; /* 13 */ ++ acerhk_key2name[8] = k_mute; /* 14 */ ++ ++ acerhk_key2name[1] = k_help; /* FN+F1 (Help) */ ++ acerhk_key2name[5] = k_display; /* FN+F3 (Display switch) */ ++ acerhk_key2name[6] = k_res; /* FN+F4 (Display ein/ausschalten) */ ++ break; ++ case 42200: ++ /* Medion MD42200, 7 keys, no setup */ ++ acerhk_key2name[2] = k_none; ++ acerhk_key2name[5] = k_display; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ break; ++ case 9783: ++ /* Medion MD9783, 6 keys + info, no setup */ ++ acerhk_key2name[2] = k_none; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[19] = k_p3; ++ acerhk_key2name[8] = k_mute; ++ break; ++ case 7400: ++ /* Amilo Pro V2000 does not have Help and Setup key (?) ++ Amilo M 7400 has Help key, disabling only setup ++ */ ++ acerhk_key2name[2] = k_none; ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ break; ++ case 1559: ++ acerhk_key2name[6] = k_display; /* FN+F4 (Display ein/ausschalten) */ ++ case 1555: ++ /* AOpen (Ahtec Signal 1555M) is similar to FS Amilo M */ ++ acerhk_key2name[2] = k_none; ++ acerhk_key2name[48] = k_wireless; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[34] = k_prev; ++ acerhk_key2name[35] = k_next; ++ acerhk_key2name[36] = k_play; ++ acerhk_key2name[37] = k_stop; ++ break; ++ case 6800: ++ case 7820: ++ /* Amilo D does not have Setup key */ ++ acerhk_key2name[2] = k_none; ++ acerhk_key2name[49] = k_mail; ++ acerhk_key2name[54] = k_www; ++ acerhk_key2name[17] = k_p1; ++ acerhk_key2name[18] = k_p2; ++ acerhk_key2name[19] = k_p3; ++ acerhk_key2name[8] = k_mute; ++ break; ++ } ++} ++ ++static void __init setup_model_features(unsigned int series) ++{ ++ switch (series) { ++ case 200: ++ case 210: ++ case 520: ++ /* nothing special */ ++ acerhk_model_features = 0; ++ acerhk_type = TM_old; ++ break; ++ case 220: ++ case 230: ++ case 260: ++ case 280: ++ case 360: ++ case 40100: /* Medion MD40100 */ ++ case 95400: /* Medion MD95400 */ ++ case 96500: /* Medion MD96500 */ ++ /* all special functions, no mail led */ ++ acerhk_model_features = 0x00f00000; ++ acerhk_type = TM_new; ++ break; ++ case 42200: /* Medion MD42200 */ ++ /* has WLAN button, should call connect() */ ++ acerhk_model_features = TM_F_WBUTTON | TM_F_CONNECT; ++ acerhk_type = TM_old; ++ break; ++ case 9783: /* Medion MD9783 */ ++ /* only email led */ ++ acerhk_model_features = TM_F_MAIL_LED; ++ acerhk_type = TM_new; ++ break; ++ case 1600: ++ acerhk_type = TM_new; ++ /* Do Aspire 1600 series have special functions or not ? I enable ++ them, perhaps it helps with problems Francois Valenduc has */ ++ acerhk_model_features = 0x00f00000; ++ break; ++ case 300: ++ case 100: ++ case 110: ++ case 240: ++ case 350: ++ case 610: ++ case 620: ++ case 630: ++ /* all special functions, mail led */ ++ acerhk_model_features = TM_F_MAIL_LED | 0x00f00000; ++ acerhk_type = TM_new; ++ break; ++ case 370: ++ case 380: ++ case 2410: ++ case 2900: /* Medion MD2900 */ ++ case 2100: /* TM 2100 uses same driver as 5020 */ ++ case 5020: /* Aspire 5020 is still old hardware */ ++ acerhk_model_features = TM_F_MAIL_LED | TM_F_CONNECT| TM_F_WBUTTON; ++ acerhk_type = TM_new; ++ break; ++ case 7400: ++ case 1555: ++ case 1559: ++ /* all special functions for Fujitsu-Siemens Amilo M7400, Pro V2000; AOpen */ ++ acerhk_model_features = 0x00f00000; ++ acerhk_type = TM_new; ++ break; ++ case 6800: ++ case 7820: ++ /* mail led and all special functions for FS Amilo D */ ++ acerhk_model_features = TM_F_MAIL_LED | 0x00f00000; ++ acerhk_type = TM_new; ++ break; ++ case 2350: ++ case 4050: ++ acerhk_wlan_state = 1; // Default state is on ++ case 290: ++ /* no special functions, wireless hardware controlled by EC */ ++ acerhk_model_features = TM_F_WLAN_EC2 | TM_F_BLUE_EC2; ++ acerhk_type = TM_dritek; ++ break; ++ case 650: ++ case 1300: ++ case 1310: ++ case 1400: ++ case 1700: ++ /* all special functions, wireless hardware can be controlled */ ++ acerhk_model_features = 0x00f00000; ++ acerhk_type = TM_dritek; ++ break; ++ case 4100: ++ case 4600: ++ case 1680: ++ case 1690: /* Aspire 1680/1690 should be similar to TM 4100/4600 */ ++ /* mail led, wireless and bluetooth controlled the old way, but keys are ++ controlled by normal keyboard controller, so mark as dritek and ++ deactivate dritek use */ ++ acerhk_model_features = TM_F_MAIL_LED | TM_F_WBUTTON; ++ acerhk_type = TM_dritek; ++ usedritek=0; ++ break; ++ case 660: ++ case 800: ++ /* all special functions, mail led */ ++ acerhk_model_features = TM_F_MAIL_LED | 0x00f00000; ++ acerhk_type = TM_dritek; ++ break; ++ case 1350: ++ case 1360: ++ /* mail led, handled by EC, wireless HW is not (yet) controllable ? */ ++ acerhk_model_features = TM_F_MAIL_LED_EC|TM_F_WLAN_EC1; ++ acerhk_type = TM_dritek; ++ break; ++ case 1450: ++ /* Bluetooth/Wlan led, Mail led handled by EC (variant 3) */ ++ acerhk_model_features = TM_F_MAIL_LED_EC3|TM_F_WBUTTON; ++ acerhk_type = TM_dritek; ++ break; ++ case 1500: ++ /* Bluetooth/Wlan led */ ++ acerhk_model_features = TM_F_WBUTTON; ++ acerhk_type = TM_new; ++ break; ++ case 420: ++ case 430: ++ /* all functions and dritek EC, mail LED is handled by EC, second ++ variant. An additional led is available, mute. (really?) ++ */ ++ acerhk_type = TM_dritek; ++ acerhk_model_features = TM_F_MUTE_LED_EC|TM_F_MAIL_LED_EC2; ++ break; ++ case 2300: ++ case 4000: ++ case 4500: ++ /* wireless hardware, hopefully under control of my driver */ ++ acerhk_type = TM_dritek; ++ acerhk_model_features = TM_F_BLUE_EC1|TM_F_WLAN_EC1; ++ break; ++ case 3200: ++ /* test, if this model uses old style wlan control */ ++ acerhk_model_features = TM_F_WBUTTON; ++ acerhk_type = TM_dritek; ++ break; ++ case 6000: ++ case 8000: ++ /* 6000 and 8000 have wireless hardware, but I don't know how to handle, ++ so I choose no features */ ++ acerhk_type = TM_dritek; ++ break; ++ case 530: ++ case 540: ++ case 2000: ++ /* No features (?) dritek EC, mail LED is handled by EC but ++ different from other Aspire series */ ++ acerhk_type = TM_dritek; ++ acerhk_model_features = TM_F_MAIL_LED_EC2; ++ break; ++ case 4150: ++ case 4650: ++ /* Dritek EC, bluetooth, wifi, mail */ ++ /* According to Andreas Stumpfl his TM 4652LMi does also work as series ++ 3200, which might mean that the BIOS function accesses the EC */ ++ acerhk_type = TM_dritek; ++ acerhk_model_features = TM_F_MAIL_LED_EC2 | TM_F_WLAN_EC2 | TM_F_BLUE_EC2; ++ break; ++ case 1800: ++ case 2010: ++ case 2020: ++ /* Dritek EC, bluetooth, wifi, mail */ ++ acerhk_type = TM_dritek; ++ acerhk_model_features = TM_F_MAIL_LED_EC2 | TM_F_WLAN_EC2 | TM_F_BLUE_EC2; ++ acerhk_wlan_state = 1; // Default state is on ++ break; ++ case 250: /* enriqueg@altern.org */ ++ /* TravelMate254LMi_DT : mail led, bluetooth (button present, hw optional), wifi (with led) */ ++ acerhk_model_features = TM_F_MAIL_LED| ++ TM_F_WBUTTON ; ++ acerhk_type = TM_new; ++ acerhk_wlan_state = 0; //Initial state is off on 254LMi_DT ++ break; ++ default: ++ /* nothing special */ ++ acerhk_model_features = 0; ++ acerhk_type = TM_unknown; ++ break; ++ } ++ /* set the correct bios call function according to type */ ++ if ((acerhk_type == TM_new) || (acerhk_type == TM_dritek)) { ++ call_bios = call_bios_6xx; ++ if (verbose > 2) ++ printk(KERN_INFO"acerhk: using call_bios_6xx mode\n"); ++ } else { ++ call_bios = call_bios_52x; ++ if (verbose > 2) ++ printk(KERN_INFO"acerhk: using call_bios_52x mode\n"); ++ } ++ /* remove key file on dritek hardware */ ++ if (acerhk_type == TM_dritek) { ++ remove_proc_entry("key", proc_acer_dir); ++ } ++ /* setup available keys */ ++ setup_keymap_model(acerhk_series); ++ if (verbose > 1) ++ print_features(); ++} ++ ++static unsigned int __init determine_laptop_series(char * str) ++{ ++ /* 0 means unknown series, handled like TM 200 */ ++ unsigned int series = 0; ++ if (strncmp(str, "TravelMate ", 11) == 0) { ++ switch (str[11]) { ++ case 'C': ++ if (str[12] == '1') { ++ if (str[13] == '0') { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates TM C100 series\n"); ++ series = 100; ++ } else if (str[13] == '1') { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates TM C110 series\n"); ++ series = 110; ++ } ++ } else if (str[12] == '3') { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates TM C300 series\n"); ++ series = 300; ++ } ++ break; ++ case 'F': ++ if (str[12] == '4') { ++ series = 230; ++ } ++ break; ++ case '2': ++ if (str[14] == '0') { ++ /* newer Travelmate 2xxx series */ ++ switch (str[12]) { ++ case '0': ++ case '5': ++ series = 2000; // 2000 and 2500 are the same ++ break; ++ case '1': ++ if (str[13] == '0') ++ series = 2100; ++ break; ++ case '2': ++ case '7': ++ series = 2200; // 2200 and 2700 are the same ++ break; ++ case '3': ++ if (str[13] == '0') ++ series = 4000; // 2300 is the same as 4000 ++ else if (str[13] == '5') ++ series = 4050; // 2350 is the same as 4050 ++ break; ++ case '4': ++ if (str[13] == '1') ++ series = 2410; ++ break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM 2xxx series\n"); ++ break; ++ } ++ } else { ++ /* older Travelmate 2xx series */ ++ switch (str[12]) { ++ case '0': series = 200; break; ++ case '1': series = 210; break; ++ case '2': series = 220; break; ++ case '4': series = 240; break; ++ case '5': series = 250; break; /* enriqueg@altern.org */ ++ case '6': series = 260; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM 2xx series\n"); ++ break; ++ } ++ } ++ break; ++ case '3': ++ switch (str[12]) { ++ case '0': series = 3200; break; /* TM 3000 works like TM 3200 */ ++ /* Travelmate 3xx series */ ++ case '5': series = 350; break; ++ case '6': series = 360; break; ++ case '7': series = 370; break; ++ case '8': series = 380; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM 3xx series\n"); ++ break; ++ } ++ break; ++ case '4': ++ if ( (strnlen(str, ACERHK_MODEL_STRLEN-1) == 15) && ++ (str[14] == '0') ) { /* Travelmate 4xxx series */ ++ switch (str[12]) { ++ case '0': /* 4000 and 4500 are the same */ ++ case '5': ++ series = 4000; ++ break; ++ case '1': ++ case '6': /* 4100 and 4600 are the same */ ++ series = 4100; ++ break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM 4xxx series\n"); ++ break; ++ } ++ } else { /* Travelmate 4xx series */ ++ switch (str[12]) { ++ case '2': series = 420; break; ++ case '3': series = 430; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM 4xx series\n"); ++ break; ++ } ++ } ++ break; ++ case '5': /* Travelmate 5xx series */ ++ if (str[12] == '2') ++ series = 520; ++ else if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM 5xx series\n"); ++ break; ++ case '6': /* older Travelmate 6xx series */ ++ switch (str[12]) { ++ case '1': series = 610; break; ++ case '2': series = 620; break; ++ case '3': series = 630; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM 6xx series\n"); ++ break; ++ } ++ break; ++ default: ++ printk(KERN_INFO"acerhk: model string indicates unknown TM xxx series\n"); ++ break; ++ } ++ if (series && verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates TM %d series\n", series); ++ } ++ /* newer Travelmate series do not have a space after 'TravelMate' */ ++ else if (strncmp(str, "TravelMate", 10) == 0) { ++ switch (str[10]) { ++ case '2': ++ if (str[11] == '9') { ++ series = 290; ++ } else { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM2xx series\n"); ++ } ++ break; ++ case '3': ++ if (str[11] == '2' && str[14] == '3') { ++ // TM 3200 uses "TravelMate32003" ++ series = 3200; ++ } else { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM3xxx series\n"); ++ } ++ break; ++ case '4': ++ switch (str[11]) { ++ case '3': series = 430; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM4xx series\n"); ++ break; ++ } ++ break; ++ case '5': ++ switch (str[11]) { ++ case '3': series = 530; break; ++ case '4': series = 540; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM5xx series\n"); ++ break; ++ } ++ break; ++ case '6': ++ switch (str[11]) { ++ case '5': series = 650; break; ++ case '6': series = 660; break; ++ case '0': ++ if (strncmp(str, "TravelMate60003", 15) == 0) { ++ series = 6000; break; ++ } ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM6xx series\n"); ++ break; ++ } ++ break; ++ case '8': ++ if (strncmp(str, "TravelMate80003", 15) == 0) { ++ series = 8000; ++ } else if (str[11] == '0') { ++ series = 800; ++ } else { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown TM8xx series\n"); ++ } ++ break; ++ default: ++ printk(KERN_INFO"acerhk: model string indicates unknown TMxxx series\n"); ++ break; ++ } ++ if (series && verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates TM%d series\n", series); ++ } ++ else if (strncmp(str, "Aspire ", 7) == 0) { ++ switch(str[7]) { ++ case '1': /* Aspire 1xxx series */ ++ switch(str[8]) { ++ case '3': /* Aspire 13xx series */ ++ switch (str[9]) { ++ case '0': series = 1300; break; ++ case '1': series = 1310; break; ++ case '5': series = 1350; break; ++ case '6': series = 1360; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 13xx series\n"); ++ break; ++ } ++ break; ++ case '4': /* Aspire 14xx series */ ++ switch (str[9]) { ++ case '0': series = 1400; break; ++ case '5': series = 1450; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 14xx series\n"); ++ break; ++ } ++ break; ++ case '5': series = 1500; break; ++ case '6': /* Aspire 14xx series */ ++ switch (str[9]) { ++ case '0': series = 1600; break; ++ case '8': ++ case '9': series = 1680; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 16xx series\n"); ++ break; ++ } ++ break; ++ case '7': series = 1700; break; ++ case '8': series = 1800; break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 1xxx series\n"); ++ break; ++ } ++ break; ++ case '2': /* Aspire 2xxx series */ ++ if (str[8] == '0') { ++ switch (str[9]) { ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 20xx series\n"); ++ break; ++ case '0': series = 2000; break; ++ case '1': series = 2010; break; ++ case '2': series = 2020; break; ++ } ++ } else { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 2xxx series\n"); ++ } ++ break; ++ case '3': /* Aspire 3xxx series */ ++ if (str[8] == '0') { ++ switch (str[9]) { ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 30xx series\n"); ++ break; ++ case '2': series = 5020; break; /* Aspire 3020/5020 are identical */ ++ } ++ } else { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 3xxx series\n"); ++ } ++ break; ++ case '5': /* Aspire 5xxx series */ ++ if (str[8] == '0') { ++ switch (str[9]) { ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 50xx series\n"); ++ break; ++ case '2': series = 5020; break; ++ } ++ } else { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire 5xxx series\n"); ++ } ++ break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Aspire series\n"); ++ break; ++ } ++ if (series && verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates Aspire %d series\n", series); ++ } ++ else if (strncmp(str, "Extensa ", 8) == 0) { ++ /* Extensa series */ ++ switch (str[8]) { ++ case '3': ++ switch (str[9]) { ++ case '0': ++ series = 3000; break; ++ default: break; ++ } ++ break; ++ default: break; ++ } ++ if (series && verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates Extensa %d series\n", series); ++ else if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown Extensa series\n"); ++ } ++ else if (strncmp(str, "Amilo ", 6) == 0) { ++ switch (str[6]) { ++ case 'D': /* complete string is "Amilo D-Series", there seems to be no model number */ ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates FS Amilo D series\n"); ++ /* this is the model number of my Amilo */ ++ series = 7820; ++ break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown FS Amilo XX series\n"); ++ series = 7820; ++ } ++ } ++ else if (strncmp(str, "AMILO ", 6) == 0) { ++ switch (str[6]) { ++ case 'D': /* AMILO D 6800 P4-2000 */ ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates FS AMILO D series\n"); ++ series = 6800; ++ break; ++ case 'M': ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates FS AMILO M(7400) series\n"); ++ series = 7400; ++ break; ++ case 'P': ++ /* it is assumed, that 'AMILO P' appears only on Amilo Pro Series */ ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates FS AMILO Pro (V2000) series\n"); ++ series = 7400; ++ break; ++ default: ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates unknown FS AMILO XX series\n"); ++ series = 6800; ++ } ++ } ++ else if (strncmp(str, "MEDIONPC", 8) == 0) { ++ uint medionmodel; ++ if ((medionmodel = COLUSSI("WIM 2040", 4, reg1, AREA_SIZE)) >= 0) { ++ printk(KERN_INFO"acerhk: found Medion model string:'%s'\n", (char*)reg1+medionmodel); ++ series = 96500; ++ } else { ++ if ((medionmodel = COLUSSI("MD 9", 4, reg1, AREA_SIZE)) >= 0) { ++ printk(KERN_INFO"acerhk: found Medion model string:'%s'\n", (char*)reg1+medionmodel); ++ } ++ series = 95400; ++ } ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates a medion MD %d\n", series); ++ } ++ else if (strncmp(str, "MEDIONNB", 8) == 0) { ++ /* Search for the Product string of the MD9783. */ ++ if (COLUSSI("MD 42200", 8, reg1, AREA_SIZE) >= 0) { ++ if (verbose>1) ++ printk(KERN_INFO"acerhk: model string indicates a Medion MD 42200\n"); ++ series = 42200; ++ } else if (COLUSSI("MD 9783", 7, reg1, AREA_SIZE) >= 0){ ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates a medion MD 9783\n"); ++ series = 9783; ++ } else if (COLUSSI("WIM 2000", 7, reg1, AREA_SIZE) >= 0){ ++ if (verbose>1) ++ printk(KERN_INFO"acerhk: model string indicates a Medion MD 2900\n"); ++ series = 2900; ++ } else { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates a medion MD40100\n"); ++ series = 40100; ++ } ++ } else if (strncmp(str, "AOpen", 5) == 0) { ++ if (strncmp(str, "AOpen*EzRestore", 15) == 0) { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates a AOpen 1559\n"); ++ series = 1559; ++ } else { ++ /* Unless I know of other models no further differentiation, ++ although there is a second part of the model string */ ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates a AOpen\n"); ++ series = 1555; ++ } ++ } else if (strncmp(str, "CL56", 4) == 0) { ++ /* Unless I know of other models no further differentiation, ++ although there are strings with more numbers ("CL561" on a Compal ++ CL56/Zepto 4200, reported by Stian B. Barmen) ++ It has the same functions as Acer Aspire 2010 ++ */ ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates a Compal CL56 (or similar)\n"); ++ series = 2010; ++ } else if (strncmp(str, "Geneva2", 7) == 0) { ++ /* This might be an Aspire 9110 which is very similar to 4650 */ ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates an Aspire 9110\n"); ++ series = 4650; ++ } else { ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: model string indicates no supported hardware\n"); ++ } ++ return (series); ++} ++ ++static void __init probe_model(void) { ++ int offset; /* offset from beginning of reg1 to Model string */ ++ if (verbose) ++ printk(KERN_INFO"acerhk: start search for model string at %p\n", reg1); ++ /* first we look for Travelmate, if it isn't one we try to identify other ++ laptops, such as Medion or Aspire */ ++ offset = COLUSSI("Travel", 6, reg1, AREA_SIZE); ++ /* Try to detect Aspire laptops */ ++ if (offset < 0) ++ offset = COLUSSI("Aspire", 6, reg1, AREA_SIZE); ++ /* Try to detect Extensa laptops */ ++ if (offset < 0) ++ offset = COLUSSI("Extensa", 7, reg1, AREA_SIZE); ++ /* Try to detect Medion laptops */ ++ if (offset < 0) ++ offset = COLUSSI("MEDION", 6, reg1, AREA_SIZE); ++ /* Try to detect AOpen laptops */ ++ if (offset < 0) ++ offset = COLUSSI("AOpen", 5, reg1, AREA_SIZE); ++ /* Try to detect Fujitsu Siemens Amilo laptops */ ++ if (offset < 0) ++ offset = COLUSSI("Amilo", 5, reg1, AREA_SIZE); ++ if (offset < 0) ++ offset = COLUSSI("AMILO", 5, reg1, AREA_SIZE); ++ /* Try to detect Compal */ ++ if (offset < 0) ++ offset = COLUSSI("CL56", 4, reg1, AREA_SIZE); ++ /* That might be an Aspire 9110 */ ++ if (offset < 0) ++ offset = COLUSSI("Geneva2", 7, reg1, AREA_SIZE); ++ if (offset >= 0) { ++ acerhk_model_addr = reg1 + offset; ++ /* copy the string, but not more than 15 characters */ ++ strncpy(acerhk_model_string, acerhk_model_addr, ACERHK_MODEL_STRLEN-1); ++ if (verbose) ++ printk(KERN_INFO"acerhk: found model string '%s' at %p\n", ++ acerhk_model_string, acerhk_model_addr); ++ if (bios_routine && verbose > 2) ++ printk(KERN_INFO"acerhk: offset from model string to function address: 0x%lx\n", ++ bios_routine - (unsigned long)acerhk_model_addr); ++ acerhk_series = determine_laptop_series(acerhk_model_string); ++ } else { ++ printk(KERN_WARNING"acerhk: Could not find model string, will assume type 200 series\n"); ++ acerhk_series = 200; ++ } ++} ++ ++/* }}} */ ++ ++/* {{{ key polling and translation */ ++ ++static void print_mapping(void) ++{ ++ printk(KERN_INFO"acerhk: key mapping:\n"); ++ printk("acerhk: help 0x%x\n", acerhk_name2event[k_help]); ++ printk("acerhk: setup 0x%x\n", acerhk_name2event[k_setup]); ++ printk("acerhk: p1 0x%x\n", acerhk_name2event[k_p1]); ++ printk("acerhk: p2 0x%x\n", acerhk_name2event[k_p2]); ++ printk("acerhk: p3 0x%x\n", acerhk_name2event[k_p3]); ++ printk("acerhk: www 0x%x\n", acerhk_name2event[k_www]); ++ printk("acerhk: mail 0x%x\n", acerhk_name2event[k_mail]); ++ printk("acerhk: wireless 0x%x\n", acerhk_name2event[k_wireless]); ++ printk("acerhk: power 0x%x\n", acerhk_name2event[k_power]); ++ printk("acerhk: mute 0x%x\n", acerhk_name2event[k_mute]); ++ printk("acerhk: volup 0x%x\n", acerhk_name2event[k_volup]); ++ printk("acerhk: voldn 0x%x\n", acerhk_name2event[k_voldn]); ++ printk("acerhk: res 0x%x\n", acerhk_name2event[k_res]); ++ printk("acerhk: close 0x%x\n", acerhk_name2event[k_close]); ++ printk("acerhk: open 0x%x\n", acerhk_name2event[k_open]); ++ printk("acerhk: wireless2 0x%x\n", acerhk_name2event[k_wireless2]); ++ printk("acerhk: play 0x%x\n", acerhk_name2event[k_play]); ++ printk("acerhk: stop 0x%x\n", acerhk_name2event[k_stop]); ++ printk("acerhk: prev 0x%x\n", acerhk_name2event[k_prev]); ++ printk("acerhk: next 0x%x\n", acerhk_name2event[k_next]); ++ printk("acerhk: display 0x%x\n", acerhk_name2event[k_display]); ++} ++ ++static void set_keymap_name(t_key_names name, unsigned int key) ++{ ++ acerhk_name2event[name] = key; ++} ++ ++static void init_keymap_input(void) ++{ ++ /* these values for input keys are chosen to match the key names on the ++ actual Acer laptop */ ++ set_keymap_name(k_none, KEY_RESERVED); ++ set_keymap_name(k_help, KEY_HELP); ++ set_keymap_name(k_setup, KEY_CONFIG); ++ set_keymap_name(k_p1, KEY_PROG1); ++ set_keymap_name(k_p2, KEY_PROG2); ++ set_keymap_name(k_p3, KEY_PROG3); ++ set_keymap_name(k_www, KEY_WWW); ++ set_keymap_name(k_mail, KEY_MAIL); ++ set_keymap_name(k_wireless, KEY_XFER); ++ set_keymap_name(k_power, KEY_POWER); ++ set_keymap_name(k_mute, KEY_MUTE); ++ set_keymap_name(k_volup, KEY_VOLUMEUP); ++ set_keymap_name(k_voldn, KEY_VOLUMEDOWN); ++ set_keymap_name(k_res, KEY_CONFIG); ++ set_keymap_name(k_close, KEY_CLOSE); ++ set_keymap_name(k_open, KEY_OPEN); ++ /* I am not really happy with the selections for wireless and wireless2, ++ but coffee looks good. Michal Veselenyi proposed this value */ ++ set_keymap_name(k_wireless2, KEY_COFFEE); ++ set_keymap_name(k_play, KEY_PLAYPAUSE); ++ set_keymap_name(k_stop, KEY_STOPCD); ++ set_keymap_name(k_prev, KEY_PREVIOUSSONG); ++ set_keymap_name(k_next, KEY_NEXTSONG); ++ set_keymap_name(k_display, KEY_MEDIA); /* also not happy with this */ ++ if (verbose > 1) ++ print_mapping(); ++} ++ ++static int filter_idle_value(int keycode) ++{ ++ int validkey = 0; ++ if (keycode != 0x0 && ++ keycode != 0x9610 && ++ keycode != 0xc100 && /* Francois Valenduc, Aspire 1601 LC */ ++ keycode != 0x8610 && ++ keycode != 0x861 && ++ keycode != 0x8650 && ++ keycode != 0x865) ++ validkey = keycode; ++ if (verbose > 4 && !validkey) ++ printk(KERN_INFO"acerhk: throw away idle value 0x%x\n", keycode); ++ return validkey; ++} ++ ++static void send_key_event(t_key_names key) ++{ ++ unsigned int input_key; ++ if (key != k_none) { ++ /* convert key name to kernel keycode */ ++ input_key = acerhk_name2event[key]; ++ if (verbose > 2) ++ printk(KERN_INFO"acerhk: translated acer key name 0x%x to input key 0x%x\n", ++ key, input_key); ++ /* send press and release together, as there is no such event from acer as 'release' */ ++ input_report_key(acerhk_input_dev_ptr, input_key, 1); ++ input_report_key(acerhk_input_dev_ptr, input_key, 0); ++ } ++} ++ ++static t_key_names transl8_key_code(int keycode) ++{ ++ t_key_names keyname = k_none; ++ /* first filter out idle values */ ++ if ( (keycode = filter_idle_value(keycode)) ) { ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: received key code 0x%x\n", keycode); ++ /* translate keycode to key name */ ++ if (keycode >= 0 && keycode <= 255) ++ keyname = acerhk_key2name[keycode]; ++ else { ++ if (verbose > 3) ++ printk(KERN_INFO"acerhk: keycode 0x%x too big, will use only 8 bits\n", keycode); ++ /* use only lower 8 bits of value to distinguish keys */ ++ keyname = acerhk_key2name[keycode&0xff]; ++ } ++ /* produce some log information for higher verbosity levels */ ++ if (keyname != k_none && verbose > 2) ++ printk(KERN_INFO"acerhk: translated acer key code 0x%x to key name 0x%x\n", ++ keycode, keyname); ++ else if (keyname == k_none && verbose > 3) ++ printk(KERN_INFO"acerhk: translated acer key code 0x%x to no key\n", ++ keycode); ++ if (autowlan) { ++ /* if automatic switching of wlan hardware is enabled, do it here ++ on wireless key press */ ++ if (keyname == k_wireless2) { ++ if (acerhk_bluetooth_state) ++ wbutton_fct_1(0); ++ else ++ wbutton_fct_1(1); ++ } ++ if (keyname == k_wireless) { ++ if (acerhk_wlan_state) ++ wbutton_fct_2(0); ++ else ++ wbutton_fct_2(1); ++ } ++ } ++ } ++ return keyname; ++} ++ ++/* polling timer handler */ ++static void acerhk_poll_event(unsigned long save_size) ++{ ++#ifndef DUMMYHW ++ unsigned int max = MAX_POLLING_LOOPS; ++ /* make sure not to loop more then 32 times */ ++ if (!max || max > 32) ++ max = 32; ++ if (acerhk_type != TM_dritek) { ++ while (get_nr_events() && max--) { ++ send_key_event(transl8_key_code(get_fnkey_event())); ++ } ++ } else { ++ send_key_event(transl8_key_code(get_fnkey_event())); ++ } ++#endif ++ acerhk_timer_poll.expires = jiffies + acerhk_polling_delay; ++ add_timer(&acerhk_timer_poll); ++} ++ ++/* blinking timer handler; added by Antonio Cuni */ ++static void acerhk_blink_event(unsigned long not_used) ++{ ++ if (acerhk_blueled_blinking != -1) { ++ acerhk_blueled_blinking = !acerhk_blueled_blinking; ++#ifndef DUMMYHW ++ wbutton_fct_1(acerhk_blueled_blinking); ++#endif ++ acerhk_timer_blinking.expires = jiffies + acerhk_blueled_blinking_delay; ++ add_timer(&acerhk_timer_blinking); ++ } ++ else ++ printk(KERN_WARNING "acerhk: blinking event called, but blinking not active\n"); ++} ++ ++static void init_input(void) ++{ ++ int i; ++ ++#ifndef KERNEL26 ++ /* request keyboard input module */ ++ request_module("keybdev"); ++ if (verbose > 3) ++ printk(KERN_INFO"requested keyboard input driver\n"); ++#endif ++ ++#ifndef STATIC_INPUT_DEV ++ /* allocate acerhk input device */ ++ acerhk_input_dev_ptr=input_allocate_device(); ++ /* enter some name */ ++ acerhk_input_dev_ptr->name = "Acer hotkey driver"; ++#else ++ acerhk_input_dev_ptr=&acerhk_input_dev; ++#endif ++ ++ /* some laptops have a mail led, should I announce it here? */ ++ acerhk_input_dev_ptr->evbit[0] = BIT(EV_KEY); ++ /* announce keys to input system ++ * the generated keys can be changed on runtime, ++ * but to publish those changes the device needs to ++ * get reconnected (I dont't know any other way) ++ * Therefore I enable all possible keys */ ++ for (i = KEY_RESERVED; i < BTN_MISC; i++) ++ set_bit(i, acerhk_input_dev_ptr->keybit); ++ /* set mapping keyname -> input event */ ++ init_keymap_input(); ++ if (verbose) ++ printk(KERN_INFO"acerhk: registered input device\n"); ++ input_register_device(acerhk_input_dev_ptr); ++ init_timer(&acerhk_timer_poll); ++ acerhk_polling_state = 0; ++} ++ ++static void stop_polling(void) ++{ ++ if (acerhk_polling_state == 1) { ++ del_timer(&acerhk_timer_poll); ++ if (verbose) ++ printk(KERN_INFO"acerhk: key polling stopped\n"); ++ acerhk_polling_state = 0; ++ } else ++ if (verbose) ++ printk(KERN_INFO"acerhk: key polling not active\n"); ++} ++ ++static void start_polling(void) ++{ ++ if (acerhk_polling_state != 1) { ++ acerhk_timer_poll.function = acerhk_poll_event; ++ acerhk_timer_poll.expires = jiffies + acerhk_polling_delay; ++ acerhk_timer_poll.data = get_nr_events(); ++ add_timer(&acerhk_timer_poll); ++ acerhk_polling_state = 1; ++ if (acerhk_type == TM_dritek) { ++ printk(KERN_INFO"acerhk: Your hardware does not need polling enabled for hotkeys to work, " ++ "you can safely disable polling by using the module parameter poll=0 (unless you " ++ "want to play around with the driver and see if there are buttons which need polling).\n"); ++ } ++ if (verbose) ++ printk(KERN_INFO"acerhk: starting key polling, every %d ms\n", acerhk_polling_delay); ++ } else ++ if (verbose) ++ printk(KERN_INFO"acerhk: key polling already active\n"); ++} ++ ++/* addedd by Antonio Cuni */ ++static void start_blinking(void) ++{ ++ if (acerhk_blueled_blinking == -1) { ++ // blinking was disabled... enable it! ++ acerhk_timer_blinking.function = acerhk_blink_event; ++ acerhk_timer_blinking.expires = jiffies + acerhk_blueled_blinking_delay; ++ acerhk_timer_blinking.data = 0; // not used ++ add_timer(&acerhk_timer_blinking); ++ acerhk_blueled_blinking = 0; ++ if (verbose) ++ printk(KERN_INFO "acerhk: starting blueled blinking\n"); ++ } else ++ if (verbose) ++ printk(KERN_INFO "acerhk: blueled already blinking\n"); ++} ++ ++/* Added by Antonio Cuni */ ++static void stop_blinking(void) ++{ ++ if (acerhk_blueled_blinking != -1) { ++ del_timer(&acerhk_timer_blinking); ++ if (verbose) ++ printk(KERN_INFO "acerhk: blueled blinking stopped\n"); ++ acerhk_blueled_blinking = -1; ++ } ++} ++ ++static void release_input(void) ++{ ++ stop_polling(); ++ input_unregister_device(acerhk_input_dev_ptr); ++} ++ ++/* }}} */ ++ ++/* {{{ procfs functions */ ++ ++#ifndef CONFIG_PROC_FS ++ ++static int acerhk_proc_init(void) ++{ ++ return 1; ++} ++#else ++ ++/* This macro frees the machine specific function from bounds checking and ++ * things like that... */ ++#define PRINT_PROC(fmt,args...) \ ++ do { \ ++ *len += sprintf( buffer+*len, fmt, ##args ); \ ++ if (*begin + *len > offset + size) \ ++ return( 0 ); \ ++ if (*begin + *len < offset) { \ ++ *begin += *len; \ ++ *len = 0; \ ++ } \ ++ } while(0) ++ ++static int pc_proc_infos( char *buffer, int *len, ++ off_t *begin, off_t offset, int size ) ++{ ++ PRINT_PROC( "Acer hotkeys version %s\n", ACERHK_VERSION); ++ PRINT_PROC( "Model(Type)\t: %s(", acerhk_model_string); ++ switch(acerhk_type) { ++ default: ++ PRINT_PROC( "unknown)\n"); ++ break; ++ case TM_old: ++ PRINT_PROC( "old)\n"); ++ break; ++ case TM_new: ++ PRINT_PROC( "new)\n"); ++ break; ++ case TM_dritek: ++ PRINT_PROC( "Dritek)\n"); ++ break; ++ } ++ if (bios_routine != 0) { ++ PRINT_PROC( "request handler\t: 0x%x\n", bios_routine); ++ if (cmos_index) { ++ PRINT_PROC( "CMOS index\t: 0x%x\n", cmos_index); ++ PRINT_PROC( "events pending\t: %u\n", get_nr_events()); ++ } else { ++ PRINT_PROC( "CMOS index\t: not available\n"); ++ } ++ if (acerhk_polling_state == 1) ++ PRINT_PROC( "kernel polling\t: active\n"); ++ else ++ PRINT_PROC( "kernel polling\t: inactive\n"); ++ PRINT_PROC( "autoswitch wlan\t: "); ++ if (autowlan == 1) ++ PRINT_PROC( "enabled\n"); ++ else ++ PRINT_PROC( "disabled\n"); ++ } else { ++ PRINT_PROC( "request handler\t: not found\n"); ++ PRINT_PROC( "kernel polling\t: not possible\n"); ++ } ++ /* model specific infos */ ++ if (acerhk_type == TM_dritek) { ++ PRINT_PROC( "use of Dritek EC: "); ++ if (usedritek) ++ PRINT_PROC( "enabled\n"); ++ else ++ PRINT_PROC( "disabled\n"); ++ } ++ if (acerhk_type == TM_old) ++ PRINT_PROC( "preg400\t\t: 0x%p\n", preg400); ++ return (1); ++} ++ ++static int acerhk_proc_info( char *buffer, char **start, off_t offset, ++ int size, int *eof, void *data ) ++{ ++ int len = 0; ++ off_t begin = 0; ++ ++ *eof = pc_proc_infos( buffer, &len, &begin, offset, size ); ++ ++ if (offset >= begin + len) ++ return( 0 ); ++ *start = buffer + (offset - begin); ++ return( size < begin + len - offset ? size : begin + len - offset ); ++ ++} ++ ++static int acerhk_proc_key( char *buffer, char **start, off_t offset, ++ int size, int *eof, void *data ) ++{ ++ if (size >= 5 && offset == 0) { ++ if (acerhk_type == TM_dritek || acerhk_polling_state == 1) { ++ snprintf(buffer+offset, size, "n/a\n"); ++ } else { ++ snprintf(buffer+offset, size, "0x%02x\n", filter_idle_value(get_fnkey_event())); ++ } ++ *eof = 1; ++ return 5; ++ } ++ *eof = 1; ++ return 0; ++} ++ ++static int acerhk_proc_led(struct file* file, const char* buffer, ++ unsigned long count, void* data) ++{ ++ char str[4]; ++ int len; ++ if (count > 4) ++ len = 4; ++ else ++ len = count; ++ if (copy_from_user(str, buffer, len)) ++ return -EFAULT; ++ str[3] = '\0'; ++ if ( ( (len >= 2) && (!strncmp(str, "on", 2) || !strncmp(str, "an", 2)) ) ++ || str[0] == '1') ++ set_mail_led(1); ++ else ++ set_mail_led(0); ++ return len; ++} ++ ++static int acerhk_proc_wirelessled(struct file* file, const char* buffer, ++ unsigned long count, void* data) ++{ ++ char str[4]; ++ int len; ++ if (count > 4) ++ len = 4; ++ else ++ len = count; ++ if (copy_from_user(str, buffer, len)) ++ return -EFAULT; ++ str[3] = '\0'; ++ if ( ( (len >= 2) && (!strncmp(str, "on", 2) || !strncmp(str, "an", 2)) ) ++ || str[0] == '1') { ++ if (acerhk_model_features & TM_F_WLAN_EC1) ++ enable_wlan_ec_1(); ++ else if (acerhk_model_features & TM_F_WLAN_EC2) ++ enable_wlan_ec_2(); ++ else ++ wbutton_fct_2(1); ++ } ++ else { ++ if (acerhk_model_features & TM_F_WLAN_EC1) ++ disable_wlan_ec_1(); ++ else if (acerhk_model_features & TM_F_WLAN_EC2) ++ disable_wlan_ec_2(); ++ else ++ wbutton_fct_2(0); ++ } ++ return len; ++} ++ ++ ++/* Modified by Antonio Cuni: added support for blinking ++ possible values: ++ - off, 0: led always off ++ - on, an, 1: led alway on ++ - n (a number): led blinking; n is the delay between ++ two changes of state, in jiffies; n must ++ be > 50, to prevent the user from overloading ++ the kernel. ++ ++ */ ++static int acerhk_proc_blueled(struct file* file, const char* buffer, ++ unsigned long count, void* data) ++{ ++ const int MAXLEN=11; ++ char str[MAXLEN]; ++ int len; ++ int isNumber; ++ ++ if (count > MAXLEN) ++ len = MAXLEN; ++ else ++ len = count; ++ if (copy_from_user(str, buffer, len)) ++ return -EFAULT; ++ str[MAXLEN - 1] = '\0'; ++ ++ /* try to parse a number */ ++ isNumber = sscanf(str, "%u", &acerhk_blueled_blinking_delay); ++ /* if the delay is 0, turn off the led */ ++ if (isNumber && acerhk_blueled_blinking_delay != 0 && acerhk_blueled_blinking_delay != 1) { ++ if (acerhk_blueled_blinking_delay < 50) ++ printk(KERN_INFO"acerhk: blinking request rejected. The delay must be > 50.\n"); ++ else { ++ if (verbose) ++ printk(KERN_INFO"acerhk: blinking delay set to %u.\n", acerhk_blueled_blinking_delay); ++ start_blinking(); ++ } ++ } else if (acerhk_blueled_blinking_delay == 1 || !strncmp(str, "on", 2) || !strncmp(str, "an", 2)) { ++ stop_blinking(); ++ if (acerhk_model_features & TM_F_BLUE_EC1) ++ enable_bluetooth_ec_1(); ++ else if (acerhk_model_features & TM_F_BLUE_EC2) ++ enable_bluetooth_ec_2(); ++ else ++ wbutton_fct_1(1); ++ } else { ++ /* it's 0 or everything else */ ++ stop_blinking(); ++ if (acerhk_model_features & TM_F_BLUE_EC1) ++ disable_bluetooth_ec_1(); ++ else if (acerhk_model_features & TM_F_BLUE_EC2) ++ disable_bluetooth_ec_2(); ++ else ++ wbutton_fct_1(0); ++ } ++ return len; ++} ++ ++#ifdef ACERDEBUG ++static void do_debug(const char* buffer, unsigned long len) ++{ ++ unsigned int h, i; ++ switch (buffer[0]) { ++ case 'b': ++ /* test WLAN on TM 4001 */ ++ switch (buffer[1]) { ++ case '0': ++ disable_wlan_ec_1(); ++ break; ++ case '1': ++ default: ++ enable_wlan_ec_1(); ++ } ++ break; ++ case 'B': ++ /* test BLUETOOTH on TM 4001 */ ++ switch (buffer[1]) { ++ case '0': ++ disable_bluetooth_ec_1(); ++ break; ++ case '1': ++ default: ++ enable_bluetooth_ec_1(); ++ } ++ break; ++ case 'D': ++ /* test "DMM Function Enabled" entry of TM 4150/4650 */ ++ enable_dmm_function(); ++ break; ++ case 'i': ++ case '1': ++#ifndef KERNEL26 ++ MOD_INC_USE_COUNT; ++#endif ++ break; ++ case 'e': ++ switch (buffer[1]) { ++ case '1': ++ start_polling(); ++ break; ++ default: ++ stop_polling(); ++ } ++ break; ++ case 'k': ++ for (i = 0; i <= 255;i++) { ++ input_report_key(acerhk_input_dev_ptr, i, 1); ++ input_report_key(acerhk_input_dev_ptr, i, 0); ++ } ++ break; ++ case 'm': ++ /* set mapping key names -> input events */ ++ sscanf(&buffer[2],"%x", &i); ++ h = buffer[1] - '0' + 1; ++ printk("acerhk: key name %x maps to %x\n", h, i); ++ acerhk_name2event[h] = i; ++ break; ++ case 'M': ++ /* test mute LED on dritek hardware */ ++ switch (buffer[1]) { ++ case '0': ++ disable_mute_led_ec(); ++ break; ++ case '1': ++ default: ++ enable_mute_led_ec(); ++ } ++ break; ++ case 'p': ++ printk("acerhk: pbutton = 0x%x\n", pbutton_fct()); ++ break; ++ case 's': ++ /* send key event to test the key translation in input system */ ++ sscanf(&buffer[1],"%x", &h); ++ printk("acerhk: sending key event 0x%x\n", h); ++ input_report_key(acerhk_input_dev_ptr, h, 1); ++ input_report_key(acerhk_input_dev_ptr, h, 0); ++ break; ++ case 'S': ++ /* simulate key codes to test the key translation in acerhk */ ++ sscanf(&buffer[1],"%x", &h); ++ send_key_event(transl8_key_code(h)); ++ break; ++ case 't': ++ printk("acerhk: thermal event = 0x%x\n", get_thermal_event()); ++ break; ++ case 'w': ++ /* test the wbutton functions, someone really needs to have another look ++ at the windows driver */ ++ switch (buffer[1]) { ++ case '2': ++ printk("acerhk: wbutton_2(%d) = 0x%x\n", buffer[2]-'0', wbutton_fct_2(buffer[2]-'0')); ++ break; ++ case '1': ++ default: ++ printk("acerhk: wbutton_1(%d) = 0x%x\n", buffer[2]-'0', wbutton_fct_1(buffer[2]-'0')); ++ } ++ break; ++ case 'W': ++ /* test wireless HW/LED on some models using dritek hardware */ ++ switch (buffer[1]) { ++ case '0': ++ disable_wireless_ec(); ++ break; ++ case '1': ++ default: ++ enable_wireless_ec(); ++ } ++ break; ++ case 'v': ++ verbose = buffer[1]-'0'; ++ printk("acerhk: verbosity level changed to %d\n", verbose); ++ break; ++ case 'd': ++ case '0': ++ default: ++#ifndef KERNEL26 ++ MOD_DEC_USE_COUNT; ++#endif ++ break; ++ } ++} ++ ++static int acerhk_proc_debug(struct file* file, const char* buffer, ++ unsigned long count, void* data) ++{ ++ char str[5]; ++ int len; ++ if (count > 5) ++ len = 5; ++ else ++ len = count; ++ if (copy_from_user(str, buffer, len)) ++ return -EFAULT; ++ str[4] = '\0'; ++ do_debug(str, len); ++ return len; ++} ++#endif ++ ++static int acerhk_proc_init(void) ++{ ++ int retval; ++ struct proc_dir_entry *entry; ++ /* create own directory */ ++ proc_acer_dir = proc_mkdir("driver/acerhk", NULL); ++ if (proc_acer_dir == NULL) { ++ retval = 0; ++ printk(KERN_INFO"acerhk: could not create /proc/driver/acerhk\n"); ++ } ++ else { ++ proc_acer_dir->owner = THIS_MODULE; ++ /* now create several files, first general info ... */ ++ entry = create_proc_read_entry("info", ++ 0444, proc_acer_dir, acerhk_proc_info, NULL); ++ if (entry == NULL) { ++ printk(KERN_INFO"acerhk: cannot create info file\n"); ++ remove_proc_entry("driver/acerhk", NULL); ++ retval = 0; ++ } else { ++ entry->owner = THIS_MODULE; ++ /* ... last pressed key ... */ ++ entry = create_proc_read_entry("key", ++ 0444, proc_acer_dir, acerhk_proc_key, NULL); ++ if (entry == NULL) { ++ printk(KERN_INFO"acerhk: cannot create key file\n"); ++ remove_proc_entry("info", proc_acer_dir); ++ remove_proc_entry("driver/acerhk", NULL); ++ retval = 0; ++ } else { ++ entry->owner = THIS_MODULE; ++ /* ... and led control file */ ++ entry = create_proc_entry("led", 0222, proc_acer_dir); ++ if (entry == NULL) { ++ printk(KERN_INFO"acerhk: cannot create LED file\n"); ++ remove_proc_entry("info", proc_acer_dir); ++ remove_proc_entry("key", proc_acer_dir); ++ remove_proc_entry("driver/acerhk", NULL); ++ retval = 0; ++ } ++ else { ++ entry->write_proc = acerhk_proc_led; ++ entry->owner = THIS_MODULE; ++ /* ... and wireless led controll file */ ++ entry = create_proc_entry("wirelessled", 0222, proc_acer_dir); ++ if (entry == NULL) { ++ printk(KERN_INFO"acerhk: cannot create wirelessled file\n"); ++ remove_proc_entry("info", proc_acer_dir); ++ remove_proc_entry("key", proc_acer_dir); ++ remove_proc_entry("led", proc_acer_dir); ++ remove_proc_entry("driver/acerhk", NULL); ++ retval = 0; ++ } ++ else { ++ entry->write_proc = acerhk_proc_wirelessled; ++ entry->owner = THIS_MODULE; ++ /* ... and bluetooth led controll file */ ++ entry = create_proc_entry("blueled", 0222, proc_acer_dir); ++ if (entry == NULL) { ++ printk(KERN_INFO"acerhk: cannot create blueled file\n"); ++ remove_proc_entry("info", proc_acer_dir); ++ remove_proc_entry("key", proc_acer_dir); ++ remove_proc_entry("led", proc_acer_dir); ++ remove_proc_entry("wirelessled", proc_acer_dir); ++ remove_proc_entry("driver/acerhk", NULL); ++ retval = 0; ++ } else { ++ entry->write_proc = acerhk_proc_blueled; ++ entry->owner = THIS_MODULE; ++ retval = 1; ++#ifdef ACERDEBUG ++ /* add extra file for debugging purposes */ ++ entry = create_proc_entry("debug", 0222, proc_acer_dir); ++ if (entry == NULL) { ++ printk(KERN_INFO"acerhk: cannot create debug file\n"); ++ remove_proc_entry("info", proc_acer_dir); ++ remove_proc_entry("key", proc_acer_dir); ++ remove_proc_entry("led", proc_acer_dir); ++ remove_proc_entry("wirelessled", proc_acer_dir); ++ remove_proc_entry("blueled", proc_acer_dir); ++ remove_proc_entry("driver/acerhk", NULL); ++ retval = 0; ++ } ++ else { ++ entry->write_proc = acerhk_proc_debug; ++ entry->owner = THIS_MODULE; ++ retval = 1; ++ } ++#endif ++ } ++ } ++ } ++ } ++ } ++ } ++ return retval; ++} ++ ++static void acerhk_proc_cleanup(void) ++{ ++ if (proc_acer_dir) { ++ remove_proc_entry("info", proc_acer_dir); ++ /* On dritek type hardware key file is already removed */ ++ if (acerhk_type != TM_dritek) ++ remove_proc_entry("key", proc_acer_dir); ++ remove_proc_entry("led", proc_acer_dir); ++ remove_proc_entry("wirelessled", proc_acer_dir); ++ remove_proc_entry("blueled", proc_acer_dir); ++#ifdef ACERDEBUG ++ remove_proc_entry("debug", proc_acer_dir); ++#endif ++ remove_proc_entry("driver/acerhk", NULL); ++ proc_acer_dir = NULL; ++ } ++} ++ ++#endif /* CONFIG_PROC_FS */ ++ ++/* }}} */ ++ ++/* {{{ file operations */ ++ ++static int acerhk_ioctl( struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg ) ++{ ++ int retval; ++ switch( cmd ) { ++ case ACERHK_GET_KEYCOUNT: ++ { ++ char nr; ++ nr = get_nr_events(); ++ put_user(nr, (char*)arg); ++ retval = 0; ++ break; ++ } ++ case ACERHK_GET_KEYID: ++ { ++ char id; ++ id = get_fnkey_event(); ++ put_user(id, (char*)arg); ++ retval = 0; ++ break; ++ } ++ case ACERHK_CONNECT: ++ launch_connect(1); ++ retval = 0; ++ break; ++ case ACERHK_START_POLLING: ++ start_polling(); ++ retval = 0; ++ break; ++ case ACERHK_STOP_POLLING: ++ stop_polling(); ++ retval = 0; ++ break; ++ case ACERHK_DISCONNECT: ++ launch_connect(0); ++ retval = 0; ++ break; ++ case ACERHK_GET_THERMAL_EVENT: ++ { ++ short event; ++ event = get_thermal_event(); ++ put_user(event, (short*)arg); ++ retval = 0; ++ break; ++ } ++ case ACERHK_MAIL_LED_OFF: ++ set_mail_led(0); ++ retval = 0; ++ break; ++ case ACERHK_MAIL_LED_ON: ++ set_mail_led(1); ++ retval = 0; ++ break; ++ case ACERHK_GET_KEY_MAP: ++ if (copy_to_user((t_map_name2event*)arg, &acerhk_name2event, sizeof(acerhk_name2event))) ++ retval = -EFAULT; ++ else ++ retval = 0; ++ break; ++ case ACERHK_SET_KEY_MAP: ++ if (copy_from_user(&acerhk_name2event, (t_map_name2event*)arg, sizeof(acerhk_name2event))) ++ retval = -EFAULT; ++ else { ++ if (verbose) { ++ printk(KERN_INFO"acerhk: changed key mapping\n"); ++ print_mapping(); ++ } ++ retval = 0; ++ } ++ break; ++ default: ++ retval = -EINVAL; ++ } ++ return retval; ++} ++ ++#ifdef ACERDEBUG ++static ssize_t acerhk_write (struct file* file, const char* buffer, size_t length, loff_t* offset) ++{ ++ if (length) ++ do_debug(buffer, length); ++ return length; ++} ++#endif ++ ++static int acerhk_open( struct inode *inode, struct file *file ) ++{ ++ return 0; ++} ++ ++static int acerhk_release( struct inode *inode, struct file *file ) ++{ ++ return 0; ++} ++ ++static struct file_operations acerhk_fops = { ++ owner: THIS_MODULE, ++ ioctl: acerhk_ioctl, ++ open: acerhk_open, ++#ifdef ACERDEBUG ++ write: acerhk_write, ++#endif ++ release: acerhk_release, ++}; ++ ++static struct miscdevice acerhk_dev = { ++ MISC_DYNAMIC_MINOR, ++ "acerhk", ++ &acerhk_fops ++}; ++ ++/* }}} */ ++ ++static void __init model_init(void) ++{ ++ /* set callroutine, features and keymap for model */ ++ setup_model_features(acerhk_series); ++ /* override initial state of wireless hardware if specified by module options */ ++ if (wlan_state >= 0) acerhk_wlan_state = wlan_state; ++ if (bluetooth_state >= 0) acerhk_bluetooth_state = bluetooth_state; ++ /* Launch connect only if available */ ++ if (acerhk_model_features & TM_F_CONNECT) { ++ if (verbose) ++ printk(KERN_INFO"acerhk: Model type %d, calling launch_connect(1)\n", ++ acerhk_type); ++ launch_connect(1); ++ } ++ if ( acerhk_type != TM_dritek ) { ++ get_cmos_index(); ++ } ++ if ( acerhk_type == TM_dritek ) { ++ enable_dritek_keyboard(); ++ } ++ /* added by Antonio Cuni */ ++ init_timer(&acerhk_timer_blinking); ++} ++ ++ ++static void __exit acerhk_cleanup_module (void); ++static int __init acerhk_init(void) ++{ ++ int ret; ++ ++ ret = misc_register( &acerhk_dev ); ++ if (ret) { ++ printk(KERN_ERR "acerhk: can't misc_register on minor=%d\n", ACERHK_MINOR); ++ ret = -EAGAIN; ++ } ++ else if (!acerhk_proc_init()) { ++ printk(KERN_ERR "acerhk: can't create procfs entries\n"); ++ ret = -ENOMEM; ++ misc_deregister( &acerhk_dev ); ++ } ++ else { ++ reg1 = ioremap(0xf0000, 0xffff); ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: area from 0xf000 to 0xffff mapped to %p\n", reg1); ++ reg2 = ioremap(0xe0000, 0xffff); ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: area from 0xe000 to 0xffff mapped to %p\n", reg2); ++ /* the area 0x400 is used as data area by earlier (520) series */ ++ preg400 = ioremap(0x400, 0xfff); ++ if (verbose > 1) ++ printk(KERN_INFO"acerhk: area from 0x400 to 0x13ff mapped to %p\n", preg400); ++ /* attach to input system */ ++ init_input(); ++ memset(acerhk_model_string, 0x00, ACERHK_MODEL_STRLEN); ++#ifdef DUMMYHW ++ acerhk_model_addr = (void*)0x12345678; ++ /* copy the string, but not more than 15 characters */ ++ strncpy(acerhk_model_string, "TravelmateDummy", ACERHK_MODEL_STRLEN-1); ++ /* set callroutine for model */ ++ if (force_series) ++ acerhk_series = force_series; ++ else ++ acerhk_series = 2000; ++ setup_model_features(acerhk_series); ++ printk(KERN_INFO "Acer Travelmate hotkey driver v" ACERHK_VERSION " dummy\n"); ++ if ( acerhk_type == TM_dritek ) ++ enable_dritek_keyboard(); ++ if (poll) ++ start_polling(); ++ init_timer(&acerhk_timer_blinking); ++#else ++ bios_routine = find_hk_area(); ++ if (!force_series) ++ probe_model(); ++ else { ++ if (verbose) ++ printk(KERN_INFO"acerhk: forced laptop series to %d\n", force_series); ++ acerhk_series = force_series; ++ } ++ /* do model specific initialization */ ++ model_init(); ++ /* Without a bios routine we cannot do anything except on dritek ++ type HW, unload on other types */ ++ if (bios_routine || (acerhk_type == TM_dritek)) { ++ ret = 0; ++ if (verbose && bios_routine) ++ printk(KERN_INFO"acerhk: bios routine found at 0x%x\n", bios_routine); ++ printk(KERN_INFO "Acer Travelmate hotkey driver v" ACERHK_VERSION "\n"); ++ /* If automatic switching of wlan is wanted but polling is disabled, ++ automatically enable it */ ++ if (!poll && autowlan) { ++ printk(KERN_INFO "Automatic switching of wireless hardware needs polling, enabling it\n"); ++ poll = 1; ++ } ++ /* start automatic polling of key presses if wanted and bios routine found */ ++ if (poll && bios_routine) ++ start_polling(); ++ } else { ++ printk(KERN_ERR "acerhk: can't find bios routine, cannot do anything for you, sorry!\n"); ++ ret = -ENOMEM; ++ acerhk_cleanup_module(); ++ } ++#endif ++ } ++ return ret; ++} ++ ++static void __exit acerhk_cleanup_module (void) ++{ ++ acerhk_proc_cleanup(); ++ stop_blinking(); ++ if (reg1) ++ iounmap(reg1); ++ if (reg2) ++ iounmap(reg2); ++ if (preg400) ++ iounmap(preg400); ++ release_input(); ++ misc_deregister( &acerhk_dev ); ++ if ( acerhk_type == TM_dritek ) { ++ disable_dritek_keyboard(); ++ } ++ if (verbose > 2) ++ printk(KERN_INFO "acerhk: unloaded\n"); ++} ++ ++module_init(acerhk_init); ++module_exit(acerhk_cleanup_module); ++ ++MODULE_AUTHOR("Olaf Tauber"); ++MODULE_DESCRIPTION("AcerHotkeys extra buttons keyboard driver"); ++MODULE_LICENSE("GPL"); ++ ++#ifndef KERNEL26 ++EXPORT_NO_SYMBOLS; ++#endif ++ ++#else ++#error This driver is only available for X86 architecture ++#endif ++/* ++ * Local variables: ++ * c-indent-level: 4 ++ * tab-width: 4 ++ * End: ++ */ ++ +diff -Nurp linux-2.6.37/3rdparty/acerhk/acerhk.h linux-2.6.37.3rdparty/3rdparty/acerhk/acerhk.h +--- linux-2.6.37/3rdparty/acerhk/acerhk.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/acerhk.h 2005-06-17 00:10:12.000000000 +0300 +@@ -0,0 +1,91 @@ ++#ifndef __ACERHK_H__ ++#define __ACERHK_H__ ++ ++#include ++ ++#define ACERHK_MINOR MISC_DYNAMIC_MINOR ++ ++#define ACERHK_GET_KEYCOUNT _IOR('p', 0x01, char) /* Get number of cached key presses */ ++#define ACERHK_GET_KEYID _IOR('p', 0x02, char) /* Get first key in queue */ ++#define ACERHK_CONNECT _IO('p', 0x03) /* ? */ ++#define ACERHK_DISCONNECT _IO('p', 0x04) /* ? */ ++#define ACERHK_GET_THERMAL_EVENT _IOR('p', 0x05, short) /* ? */ ++#define ACERHK_MAIL_LED_OFF _IO('p', 0x10) /* switch mail LED off */ ++#define ACERHK_MAIL_LED_ON _IO('p', 0x11) /* switch mail LED on (blinking) */ ++#define ACERHK_START_POLLING _IO('p', 0x12) /* poll keys in kernel, send real key events */ ++#define ACERHK_STOP_POLLING _IO('p', 0x13) /* stop key polling in kernel */ ++#define ACERHK_GET_KEY_MAP _IOR('p', 0x20, int) /* Get mapping of key names to key events, */ ++#define ACERHK_SET_KEY_MAP _IOW('p', 0x21, int) /* Set mapping of key names to key events */ ++ ++/* all possible keys (known to me) */ ++typedef enum e_key_names { ++ k_none = 0, ++ k_help = 1, /* Fn+F1 */ ++ k_setup = 2, /* Fn+F2 */ ++ k_p1 = 3, ++ k_p2 = 4, ++ k_p3 = 5, ++ k_www = 6, ++ k_mail = 7, ++ k_wireless = 8, ++ k_power = 9, /* Fn+F3 */ ++ k_mute = 10, /* Fn+F8 */ ++ k_volup = 11, /* Fn+Up */ ++ k_voldn = 12, /* Fn+Down */ ++ k_res = 13, /* resolution change on Medion MD 40100 */ ++ k_close = 14, /* if lid is closed in tablet mode */ ++ k_open = 15, /* if lid is opend in tablet mode */ ++ k_wireless2 = 16, /* second wireless button on TM 243LC */ ++ k_play = 17, /* Play/Pause found on AOpen */ ++ k_stop = 18, /* Stop/Eject found on AOpen */ ++ k_prev = 19, /* Prev found on AOpen */ ++ k_next = 20, /* Next found on AOpen */ ++ k_display = 21 /* Change internal/external display on MD 42200 */ ++} t_key_names; ++#define NR_KEY_NAMES 22 ++typedef unsigned int t_map_name2event[NR_KEY_NAMES]; ++ ++#ifdef __KERNEL__ ++ ++/* available features */ ++#define TM_F_WLAN_EC1 0x00000010 ++#define TM_F_BLUE_EC1 0x00000020 ++#define TM_F_WLAN_EC2 0x00000040 ++#define TM_F_BLUE_EC2 0x00000080 ++#define TM_F_MUTE_LED_EC 0x00001000 ++#define TM_F_MAIL_LED 0x00010000 ++#define TM_F_MAIL_LED_EC 0x00020000 ++#define TM_F_MAIL_LED_EC2 0x00040000 ++#define TM_F_MAIL_LED_EC3 0x00080000 ++ ++#define TM_F_CONNECT 0x00100000 ++#define TM_F_THERMAL 0x00200000 ++#define TM_F_PBUTTON 0x00400000 ++#define TM_F_WBUTTON 0x00800000 ++ ++typedef enum acer_type { ++ TM_unknown, ++ /* 200, 210, 520, 600 and 730 series, Medion MD42200 */ ++ TM_old, ++ /* C100, C110, 220, 230, 240, 260, 350, 360, 610, 620, 630, 740 series ++ Medion MD40100, Aspire 1600, FS Amilo */ ++ TM_new, ++ /* Aspire 13xx, 14xx, 1700, TM 290, 650, 660, 800 */ ++ TM_dritek ++} t_acer_type; ++ ++struct register_buffer { ++ unsigned int eax; ++ unsigned int ebx; ++ unsigned int ecx; ++ unsigned int edx; ++ unsigned int edi; ++ unsigned int esi; ++ unsigned int ebp; ++}; ++ ++typedef asmlinkage void (*bios_call) (struct register_buffer *); ++ ++#endif ++ ++#endif +diff -Nurp linux-2.6.37/3rdparty/acerhk/AUTHORS linux-2.6.37.3rdparty/3rdparty/acerhk/AUTHORS +--- linux-2.6.37/3rdparty/acerhk/AUTHORS 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/AUTHORS 2006-11-10 00:02:55.000000000 +0200 +@@ -0,0 +1 @@ ++Olaf Tauber +\ Ingen nyrad vid filslut +diff -Nurp linux-2.6.37/3rdparty/acerhk/COPYING linux-2.6.37.3rdparty/3rdparty/acerhk/COPYING +--- linux-2.6.37/3rdparty/acerhk/COPYING 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/COPYING 2002-05-08 22:01:52.000000000 +0300 +@@ -0,0 +1,340 @@ ++ GNU GENERAL PUBLIC LICENSE ++ Version 2, June 1991 ++ ++ Copyright (C) 1989, 1991 Free Software Foundation, Inc. ++ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ Everyone is permitted to copy and distribute verbatim copies ++ of this license document, but changing it is not allowed. ++ ++ Preamble ++ ++ The licenses for most software are designed to take away your ++freedom to share and change it. By contrast, the GNU General Public ++License is intended to guarantee your freedom to share and change free ++software--to make sure the software is free for all its users. This ++General Public License applies to most of the Free Software ++Foundation's software and to any other program whose authors commit to ++using it. (Some other Free Software Foundation software is covered by ++the GNU Library General Public License instead.) You can apply it to ++your programs, too. ++ ++ When we speak of free software, we are referring to freedom, not ++price. Our General Public Licenses are designed to make sure that you ++have the freedom to distribute copies of free software (and charge for ++this service if you wish), that you receive source code or can get it ++if you want it, that you can change the software or use pieces of it ++in new free programs; and that you know you can do these things. ++ ++ To protect your rights, we need to make restrictions that forbid ++anyone to deny you these rights or to ask you to surrender the rights. ++These restrictions translate to certain responsibilities for you if you ++distribute copies of the software, or if you modify it. ++ ++ For example, if you distribute copies of such a program, whether ++gratis or for a fee, you must give the recipients all the rights that ++you have. You must make sure that they, too, receive or can get the ++source code. And you must show them these terms so they know their ++rights. ++ ++ We protect your rights with two steps: (1) copyright the software, and ++(2) offer you this license which gives you legal permission to copy, ++distribute and/or modify the software. ++ ++ Also, for each author's protection and ours, we want to make certain ++that everyone understands that there is no warranty for this free ++software. If the software is modified by someone else and passed on, we ++want its recipients to know that what they have is not the original, so ++that any problems introduced by others will not reflect on the original ++authors' reputations. ++ ++ Finally, any free program is threatened constantly by software ++patents. We wish to avoid the danger that redistributors of a free ++program will individually obtain patent licenses, in effect making the ++program proprietary. To prevent this, we have made it clear that any ++patent must be licensed for everyone's free use or not licensed at all. ++ ++ The precise terms and conditions for copying, distribution and ++modification follow. ++ ++ GNU GENERAL PUBLIC LICENSE ++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++ 0. This License applies to any program or other work which contains ++a notice placed by the copyright holder saying it may be distributed ++under the terms of this General Public License. The "Program", below, ++refers to any such program or work, and a "work based on the Program" ++means either the Program or any derivative work under copyright law: ++that is to say, a work containing the Program or a portion of it, ++either verbatim or with modifications and/or translated into another ++language. (Hereinafter, translation is included without limitation in ++the term "modification".) Each licensee is addressed as "you". ++ ++Activities other than copying, distribution and modification are not ++covered by this License; they are outside its scope. The act of ++running the Program is not restricted, and the output from the Program ++is covered only if its contents constitute a work based on the ++Program (independent of having been made by running the Program). ++Whether that is true depends on what the Program does. ++ ++ 1. You may copy and distribute verbatim copies of the Program's ++source code as you receive it, in any medium, provided that you ++conspicuously and appropriately publish on each copy an appropriate ++copyright notice and disclaimer of warranty; keep intact all the ++notices that refer to this License and to the absence of any warranty; ++and give any other recipients of the Program a copy of this License ++along with the Program. ++ ++You may charge a fee for the physical act of transferring a copy, and ++you may at your option offer warranty protection in exchange for a fee. ++ ++ 2. You may modify your copy or copies of the Program or any portion ++of it, thus forming a work based on the Program, and copy and ++distribute such modifications or work under the terms of Section 1 ++above, provided that you also meet all of these conditions: ++ ++ a) You must cause the modified files to carry prominent notices ++ stating that you changed the files and the date of any change. ++ ++ b) You must cause any work that you distribute or publish, that in ++ whole or in part contains or is derived from the Program or any ++ part thereof, to be licensed as a whole at no charge to all third ++ parties under the terms of this License. ++ ++ c) If the modified program normally reads commands interactively ++ when run, you must cause it, when started running for such ++ interactive use in the most ordinary way, to print or display an ++ announcement including an appropriate copyright notice and a ++ notice that there is no warranty (or else, saying that you provide ++ a warranty) and that users may redistribute the program under ++ these conditions, and telling the user how to view a copy of this ++ License. (Exception: if the Program itself is interactive but ++ does not normally print such an announcement, your work based on ++ the Program is not required to print an announcement.) ++ ++These requirements apply to the modified work as a whole. If ++identifiable sections of that work are not derived from the Program, ++and can be reasonably considered independent and separate works in ++themselves, then this License, and its terms, do not apply to those ++sections when you distribute them as separate works. But when you ++distribute the same sections as part of a whole which is a work based ++on the Program, the distribution of the whole must be on the terms of ++this License, whose permissions for other licensees extend to the ++entire whole, and thus to each and every part regardless of who wrote it. ++ ++Thus, it is not the intent of this section to claim rights or contest ++your rights to work written entirely by you; rather, the intent is to ++exercise the right to control the distribution of derivative or ++collective works based on the Program. ++ ++In addition, mere aggregation of another work not based on the Program ++with the Program (or with a work based on the Program) on a volume of ++a storage or distribution medium does not bring the other work under ++the scope of this License. ++ ++ 3. You may copy and distribute the Program (or a work based on it, ++under Section 2) in object code or executable form under the terms of ++Sections 1 and 2 above provided that you also do one of the following: ++ ++ a) Accompany it with the complete corresponding machine-readable ++ source code, which must be distributed under the terms of Sections ++ 1 and 2 above on a medium customarily used for software interchange; or, ++ ++ b) Accompany it with a written offer, valid for at least three ++ years, to give any third party, for a charge no more than your ++ cost of physically performing source distribution, a complete ++ machine-readable copy of the corresponding source code, to be ++ distributed under the terms of Sections 1 and 2 above on a medium ++ customarily used for software interchange; or, ++ ++ c) Accompany it with the information you received as to the offer ++ to distribute corresponding source code. (This alternative is ++ allowed only for noncommercial distribution and only if you ++ received the program in object code or executable form with such ++ an offer, in accord with Subsection b above.) ++ ++The source code for a work means the preferred form of the work for ++making modifications to it. For an executable work, complete source ++code means all the source code for all modules it contains, plus any ++associated interface definition files, plus the scripts used to ++control compilation and installation of the executable. However, as a ++special exception, the source code distributed need not include ++anything that is normally distributed (in either source or binary ++form) with the major components (compiler, kernel, and so on) of the ++operating system on which the executable runs, unless that component ++itself accompanies the executable. ++ ++If distribution of executable or object code is made by offering ++access to copy from a designated place, then offering equivalent ++access to copy the source code from the same place counts as ++distribution of the source code, even though third parties are not ++compelled to copy the source along with the object code. ++ ++ 4. You may not copy, modify, sublicense, or distribute the Program ++except as expressly provided under this License. Any attempt ++otherwise to copy, modify, sublicense or distribute the Program is ++void, and will automatically terminate your rights under this License. ++However, parties who have received copies, or rights, from you under ++this License will not have their licenses terminated so long as such ++parties remain in full compliance. ++ ++ 5. You are not required to accept this License, since you have not ++signed it. However, nothing else grants you permission to modify or ++distribute the Program or its derivative works. These actions are ++prohibited by law if you do not accept this License. Therefore, by ++modifying or distributing the Program (or any work based on the ++Program), you indicate your acceptance of this License to do so, and ++all its terms and conditions for copying, distributing or modifying ++the Program or works based on it. ++ ++ 6. Each time you redistribute the Program (or any work based on the ++Program), the recipient automatically receives a license from the ++original licensor to copy, distribute or modify the Program subject to ++these terms and conditions. You may not impose any further ++restrictions on the recipients' exercise of the rights granted herein. ++You are not responsible for enforcing compliance by third parties to ++this License. ++ ++ 7. If, as a consequence of a court judgment or allegation of patent ++infringement or for any other reason (not limited to patent issues), ++conditions are imposed on you (whether by court order, agreement or ++otherwise) that contradict the conditions of this License, they do not ++excuse you from the conditions of this License. If you cannot ++distribute so as to satisfy simultaneously your obligations under this ++License and any other pertinent obligations, then as a consequence you ++may not distribute the Program at all. For example, if a patent ++license would not permit royalty-free redistribution of the Program by ++all those who receive copies directly or indirectly through you, then ++the only way you could satisfy both it and this License would be to ++refrain entirely from distribution of the Program. ++ ++If any portion of this section is held invalid or unenforceable under ++any particular circumstance, the balance of the section is intended to ++apply and the section as a whole is intended to apply in other ++circumstances. ++ ++It is not the purpose of this section to induce you to infringe any ++patents or other property right claims or to contest validity of any ++such claims; this section has the sole purpose of protecting the ++integrity of the free software distribution system, which is ++implemented by public license practices. Many people have made ++generous contributions to the wide range of software distributed ++through that system in reliance on consistent application of that ++system; it is up to the author/donor to decide if he or she is willing ++to distribute software through any other system and a licensee cannot ++impose that choice. ++ ++This section is intended to make thoroughly clear what is believed to ++be a consequence of the rest of this License. ++ ++ 8. If the distribution and/or use of the Program is restricted in ++certain countries either by patents or by copyrighted interfaces, the ++original copyright holder who places the Program under this License ++may add an explicit geographical distribution limitation excluding ++those countries, so that distribution is permitted only in or among ++countries not thus excluded. In such case, this License incorporates ++the limitation as if written in the body of this License. ++ ++ 9. The Free Software Foundation may publish revised and/or new versions ++of the General Public License from time to time. Such new versions will ++be similar in spirit to the present version, but may differ in detail to ++address new problems or concerns. ++ ++Each version is given a distinguishing version number. If the Program ++specifies a version number of this License which applies to it and "any ++later version", you have the option of following the terms and conditions ++either of that version or of any later version published by the Free ++Software Foundation. If the Program does not specify a version number of ++this License, you may choose any version ever published by the Free Software ++Foundation. ++ ++ 10. If you wish to incorporate parts of the Program into other free ++programs whose distribution conditions are different, write to the author ++to ask for permission. For software which is copyrighted by the Free ++Software Foundation, write to the Free Software Foundation; we sometimes ++make exceptions for this. Our decision will be guided by the two goals ++of preserving the free status of all derivatives of our free software and ++of promoting the sharing and reuse of software generally. ++ ++ NO WARRANTY ++ ++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY ++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN ++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES ++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED ++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS ++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE ++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, ++REPAIR OR CORRECTION. ++ ++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR ++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, ++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING ++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED ++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY ++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER ++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE ++POSSIBILITY OF SUCH DAMAGES. ++ ++ END OF TERMS AND CONDITIONS ++ ++ How to Apply These Terms to Your New Programs ++ ++ If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it ++free software which everyone can redistribute and change under these terms. ++ ++ To do so, attach the following notices to the program. It is safest ++to attach them to the start of each source file to most effectively ++convey the exclusion of warranty; and each file should have at least ++the "copyright" line and a pointer to where the full notice is found. ++ ++ ++ Copyright (C) 19yy ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++If the program is interactive, make it output a short notice like this ++when it starts in an interactive mode: ++ ++ Gnomovision version 69, Copyright (C) 19yy name of author ++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. ++ This is free software, and you are welcome to redistribute it ++ under certain conditions; type `show c' for details. ++ ++The hypothetical commands `show w' and `show c' should show the appropriate ++parts of the General Public License. Of course, the commands you use may ++be called something other than `show w' and `show c'; they could even be ++mouse-clicks or menu items--whatever suits your program. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the program, if ++necessary. Here is a sample; alter the names: ++ ++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program ++ `Gnomovision' (which makes passes at compilers) written by James Hacker. ++ ++ , 1 April 1989 ++ Ty Coon, President of Vice ++ ++This General Public License does not permit incorporating your program into ++proprietary programs. If your program is a subroutine library, you may ++consider it more useful to permit linking proprietary applications with the ++library. If this is what you want to do, use the GNU Library General ++Public License instead of this License. +diff -Nurp linux-2.6.37/3rdparty/acerhk/doc/acertm.def linux-2.6.37.3rdparty/3rdparty/acerhk/doc/acertm.def +--- linux-2.6.37/3rdparty/acerhk/doc/acertm.def 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/doc/acertm.def 2003-08-24 19:46:37.000000000 +0300 +@@ -0,0 +1,56 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ Konfiguration ++ ++ Mute/Unmute ++ Lauter ++ Leiser ++ ++ Terminal ++ XEmacs ++ Play/Pause ++ Play/Pause ++ ++ ++ ++ +diff -Nurp linux-2.6.37/3rdparty/acerhk/doc/FAQ linux-2.6.37.3rdparty/3rdparty/acerhk/doc/FAQ +--- linux-2.6.37/3rdparty/acerhk/doc/FAQ 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/doc/FAQ 2005-11-10 19:45:33.000000000 +0200 +@@ -0,0 +1,150 @@ ++****************************************************************************** ++ ++Q: I have a (non Acer) notebook which is not recognized by your driver but I ++think it should. What information do you need? ++ ++A: If it is a non-Acer laptop I would like to know, what makes you think that ++your laptop would work with my driver. A windows driver/utility package of the ++name "LaunchManager" or "EasyButton" is a good hint. If it is clear that your ++hardware is okay, I need the string with your model name from BIOS. Please ++don't ask me how to do it. To find out which functions of your laptop the ++driver will support, it is best, if you can tell me where to get this ++"LaunchManager" or "EasyButton" package. ++If it is a model from 2003 or newer then chances are good that it's a dritek ++type one. In this case try the option "force_series=6000" to at least enable ++the keys. ++ ++****************************************************************************** ++ ++Q: Why can't I activate my wireless hardware on Acer TM 420/430/6000/8000 ...? ++ ++A: On many newer laptops (Dritek type) I do not now how to do this, ++sorry. Someone would need to find out how windows does it. Volunteers? ++ ++****************************************************************************** ++ ++Q: I know that wireless hardware is supported on my Aspire 1690/TravelMate4600, ++but I cannot get it to work, why? ++ ++A: On these model (and similar) the wireless hardware is controlled on two ++different levels. One is controlled by acerhk's xxxled file, the other level ++is controlled by the key itself. To actually activate the hardware you need to ++write '1' to the xxled file and you need to press the corresponding button. ++Example: ++echo 1 > /proc/driver/acerhk/wirelessled ++ ++ ++****************************************************************************** ++ ++Q: Why do I always get 0x00 from /proc/driver/acerhk/key? ++ ++A1: Check the type of your laptop if /proc/driver/acerhk/info. If it is ++"Dritek", you cannot read the keys from the driver. Starting from version ++0.5.17 you get "n/a" out of the key file in this case. ++A2: If you have polling enabled (default) you will almost always read 0x00 ++from this file. This is because in every polling cycle it is checked for key ++events and if there is one, it is instantly translated and sent to the kernel ++input system. Starting with version 0.5.20 you get "n/a" out of the key file ++in this case. ++ ++****************************************************************************** ++ ++Q: When I press a key, nothing happens. Why are they not working? ++ ++A: Most keys won't do anything by themself. If nothing happens, that is ++because no programm knows what to do with the new keys. You need to assign ++actions to them, use the hotkey manager of your desktop to do that. If ++using Gnome, you find it under desktop settings - keyboard shortcuts. ++ ++****************************************************************************** ++ ++Q: The driver works for my laptop, but not all of the keys are working. What ++can I do? ++ ++A: There are some keys/key combinations which generate an ACPI event, ++e.g. Fn+F4 on some models or the lid button. ++If you have a different laptop than the one which got detected (or you used ++"force_series=xxx" anyway), then it is possible that the mapping acerhk uses ++to translate the codes from the buttons to key events is wrong. ++In this case, load the driver with "verbose=4" and press the buttons which do ++not work. Then look for messages from acerhk of the form "translated acer key ++code xxx to no key". Note these codes together with the button they belong to ++and send me this list along with the model name of your laptop. ++If you do not see a usable name in /proc/driver/acerhk/info please try the ++tools dmidecode/biosdecode/vpddecode to find this name. ++ ++****************************************************************************** ++Q: I press the wireless key but the hardware doesn't get activated, what's wrong? ++ ++A: The driver is only on older models (non-Dritek type) able to read ++keypresses by itself and toggle the hardware/LED automatically (with option ++autowlan=1). On Dritek type models this must be done by writing the desired ++value to one of the wireless files in the proc filesystem. In most ++cases this would be /proc/drivers/acerhk/wirelessled to control wlan ++hardware (blueled for Bluetooth hardware): ++ ++echo 1 > /proc/driver/acerhk/wirelessled ++ ++But you could use a hotkey manager to do that automatically when you press the ++button. In this case be aware that on some models the button generates ++different key events according to the actual state of the wireless hardware. ++ ++****************************************************************************** ++ ++Q: My keys do not work, I only get kernel messages of the form: ++atkbd.c: Unknown key pressed (translated set 2, code 0xf4 on isa0060/serio0). ++atkbd.c: Use 'setkeycodes e074 ' to make it known. ++ ++A: Press each of the buttons and note the mentioned ++code for it (e074 in this example). You should get a list like this: ++P1 e074 ++P2 e075 ++... ++If you are finished with it, look into /usr/include/linux/input.h, using ++your favourite text viewer/editor. Search for "KEY_STOP". You should see ++the following line in the file: ++ ++#define KEY_STOP 128 ++ ++After it many more lines with equal #defines should be visible. Look for ++key names which best match the names of your buttons, e.g. KEY_PROG1, ++KEY_WWW and so on. Note the numbers assigned to the names, for KEY_STOP ++this would be 128, for KEY_PROG1 148. ++Now you have a list with three items per entry, your button, a code ++from the kernel messages and a corresponding number from the file ++linux.h: ++P1 e074 148 ++P2 e075 149 ++... ++For each line in this list, issue the setkeycodes command as mentioned ++in the kernel message: ++setkeycodes e074 148 ++setkeycodes e075 149 ++... ++After doing that, the keys should be available for your hotkey manager. ++ ++****************************************************************************** ++ ++Q: My WLAN hardware gets activated through /proc/driver/acerhk/wirelessled, ++but the LED is not working. Why not? ++ ++A: Try if adding the option "led=1" to your wireless module helps. For the ++ipw2200 driver it works, as Didier CLERC found out: ++ ++ I have to load the module "ipw2200" with the option "led=1", then ++ the wifi button blinks until a network is detected. ++ ++****************************************************************************** ++ ++Q: I have an unsupported laptop, but the driver works when I force the series ++to a type like 610 or 2100. Only my buttons doesn't get recognized, why? ++ ++A: On models of the type TM_new (like TravelMate 600, 2100 and many other, see ++acerhk.c, function setup_model_features for details) the buttons use different ++codes on different models. Therefore the driver needs to know these codes. You ++can get them if you load the driver with verbose=4, press the buttons and key ++combinations (Fn+xx) you are interested in and look for kernel messages of the ++form "acerhk: translated acer key code 0xnn to ...". Write down the key code ++for each button/key combination and send them to me so I can patch the ++driver. I also need your model string to make autodetection work, so include ++/proc/driver/acerk/info. +\ Ingen nyrad vid filslut +diff -Nurp linux-2.6.37/3rdparty/acerhk/doc/IOCTL linux-2.6.37.3rdparty/3rdparty/acerhk/doc/IOCTL +--- linux-2.6.37/3rdparty/acerhk/doc/IOCTL 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/doc/IOCTL 2004-01-31 22:38:17.000000000 +0200 +@@ -0,0 +1,61 @@ ++Documentation of possible IOCTLs used by acerhk +++++++++++++++++++++++++++++++++++++++++++++++++ ++ ++ACERHK_GET_KEYCOUNT ++ Read the number of unread key presses in queue ++ Parameter: pointer to char ++ ++ACERHK_GET_KEYID ++ Read the code of the first key press (oldest) in queue ++ Parameter: pointer to char ++ ++ACERHK_CONNECT ++ Don't know what it does, used in windows driver ++ ++ACERHK_DISCONNECT ++ Don't know what it does, used in windows driver ++ ++ACERHK_GET_THERMAL_EVENT ++ Don't know what it does, used in windows driver ++ Parameter: pointer to short ++ ++ACERHK_MAIL_LED_OFF ++ Switch off the LED of the mail button(if available) ++ ++ACERHK_MAIL_LED_ON ++ Switch on the LED of the mail button (if available) ++ ++ACERHK_START_POLLING ++ Start polling (and translation to key events) in kernel ++ ++ACERHK_STOP_POLLING ++ Stop polling in kernel ++ ++ACERHK_GET_KEY_MAP ++ Get mapping of key names to key events ++ Parameter: pointer to t_map_name2event ++ ++ACERHK_SET_KEY_MAP ++ Set mapping of key names to key events ++ Parameter: pointer to t_map_name2event ++ ++IOCTLs used by windows driver +++++++++++++++++++++++++++++++ ++device name: ++\DosDevices\HOTKEY ++\Device\HOTKEY ++ ++ ++630 series: ++0x222404 ++ Get CMOS index ++0x222408 ++ ACERHK_GET_KEYCOUNT ++0x22240C ++ ACERHK_GET_KEYID ++0x222410 ++ ACERHK_MAIL_LED_OFF/ACERHK_MAIL_LED_ON ++0x222414 ++ ACERHK_CONNECT/ACERHK_DISCONNECT ++0x222418 ++ ACERHK_GET_THERMAL_EVENT +diff -Nurp linux-2.6.37/3rdparty/acerhk/doc/keycodes linux-2.6.37.3rdparty/3rdparty/acerhk/doc/keycodes +--- linux-2.6.37/3rdparty/acerhk/doc/keycodes 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/doc/keycodes 2004-04-18 20:42:59.000000000 +0300 +@@ -0,0 +1,26 @@ ++standard X keycodes with older (acerhk controlled) hardware from Acer ++********************************************************************* ++help (Fn+F1) 226 ++setup (Fn+F2) 129 ++p1 153 ++p2 144 ++p3 171 ++www 178 ++mail 236 ++wireless 147 ++power (Fn+F3) 222 ++mute (Fn+F8) 166 ++volup (Fn+Up) 158 ++voldn (Fn+Down) 165 ++ ++standard X keycodes with newer (acerhk activated) hardware from Dritek ++********************************************************************** ++help (Fn+F1) 226 ++setup (Fn+F2) 129 ++p1 153 ++p2 144 ++www 178 ++mail 236 ++volup (Fn+Up) 176 ++voldn (Fn+Down) 174 ++mute (Fn+F8) 160 +diff -Nurp linux-2.6.37/3rdparty/acerhk/doc/md95400.def linux-2.6.37.3rdparty/3rdparty/acerhk/doc/md95400.def +--- linux-2.6.37/3rdparty/acerhk/doc/md95400.def 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/doc/md95400.def 2005-03-01 22:46:53.000000000 +0200 +@@ -0,0 +1,14 @@ ++ ++ ++ ++Mail ++Web ++Play/Pause ++Stop ++Previous ++Next ++Leiser ++Lauter ++ ++ ++ +diff -Nurp linux-2.6.37/3rdparty/acerhk/INSTALL linux-2.6.37.3rdparty/3rdparty/acerhk/INSTALL +--- linux-2.6.37/3rdparty/acerhk/INSTALL 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/INSTALL 2005-12-07 14:27:16.000000000 +0200 +@@ -0,0 +1,109 @@ ++Installation ++************ ++ ++1. You need the kernel sources (or kernel headers for your kernel) ++installed to compile the driver. ++ ++2. Your kernel needs loadable module support with version information for ++modules enabled. Usage of procfs is highly recommended. ++If you want the driver to generate regular keyboard events using ++kernel version 2.4 you need the input system of the kernel enabled ++(Input core support AND keyboard support). In kernel version 2.6 all ++needed functionality should be available by default. ++ ++In most cases you can skip the next step, the Makefile tries do determine ++the correct directory on its own. Change KERNELSRC only if the autodetection ++does not work for you. Otherwise proceed directly with step 4. ++ ++3. Before you compile the driver, change KERNELSRC in the makefile to your ++path to the kernel build environment. If you are using a self compiled kernel, ++point it to the root of your sources. If you are using a packaged kernel of ++your distribution, install the package with kernel headers ++(Debian:kernel-headers) and point KERNELSRC to where the headers and config ++files are located. If you are using Debian, this ++would be "/lib/modules//build". ++ ++4. Do: ++ make ++to compile the driver. If you run into problems because of the makefile not ++recognizing your kernel version correctly, try this: ++ make acerhk.o - kernel version 2.4 ++ make acerhk.ko - kernel version 2.6 ++ ++5. Do: ++ make install ++to automatically copy the driver into the kernel module library. If you've ++done so, proceed directly with step 8. If you want to install the module ++binary yourself (because you want a different location), use steps 6 and 7 ++instead. ++ ++6. Copy the created file "acerhk.o" ("acerhk.ko" with version 2.6) to your ++kernel modules path. In Debian this could be ++"/lib/modules//kernel/drivers/extra/". ++ ++7. Update module dependencies: depmod -a ++ ++8. Try loading the module with: ++ insmod/modprobe acerhk ++If it succeeds - congratulations! If you have procfs enabled, you can try the ++following to test the driver: ++ ++Non-Dritek models: ++Press one of the special keys and after that: ++ cat /proc/driver/acerhk/key ++to read the (hexadezimal) code of the key pressed. It should ++be different from 0x00. ++(Note: You mustn't have the polling feature enabled for this to work, so load ++ the module with poll=0) ++ ++Dritek-models: ++Press one of the special keys and look for the generated key with "xev". If ++there is none, then you should see at least kernel messages about using ++setkeycodes. ++ ++If your notebook has a mail led you can try this: ++ echo on > /proc/driver/acerhk/led ++This should sete the mail led to blinking mode. ++ echo off > /proc/driver/acerhk/led ++turns it off again. ++See README for further usage information. ++ ++If the module didn't load look into your kernel messages what went wrong. If ++you see something like the following lines: ++ acerhk: could not find request handler ++ acerhk: can't find ROM area ++ acerhk: unloaded ++then your hardware is not recognized. See README for supported models. If it ++won't work on your notebook, please contact me and I will see if I can fix ++that. ++ ++Integrating the driver into kernel tree version 2.6 ++*************************************************** ++ ++If you want the driver to fully integrate into the kernel tree of version 2.6 ++proceed as follows: ++1. Copy the acerhk directory into the source tree, for instance ++ /usr/src/linux/drivers/misc/acerhk ++2. Include the driver directory in the config files. Add to the Kconfig ++file of the parent directory(/usr/src/linux/drivers/misc/Kconfig): ++ ++config ACERHK ++ tristate "Acerhk driver" ++ depends on EXPERIMENTAL ++ ---help--- ++ This is an experimental acer keyboard driver for ++ acer laptops ++ ++3. Include the acer directory in it's parents ++Makefile(/usr/src/linux/drivers/misc/Makefile): ++ ++obj-$(CONFIG_ACERHK) += acerhk/ ++ ++4. In this case you also need to activate the misc drivers first ++(/usr/src/linux/drivers/Kconfig): ++ ++source "drivers/misc/Kconfig" ++ ++If that's done, you should be able to select the driver from the configuration ++programm and build the module. ++ +diff -Nurp linux-2.6.37/3rdparty/acerhk/Makefile linux-2.6.37.3rdparty/3rdparty/acerhk/Makefile +--- linux-2.6.37/3rdparty/acerhk/Makefile 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/Makefile 2006-08-16 19:11:08.000000000 +0300 +@@ -0,0 +1,65 @@ ++# change KERNELSRC to the location of your kernel build tree only if ++# autodetection does not work ++#KERNELSRC=/usr/src/linux ++KERNELSRC?=/lib/modules/`uname -r`/build ++# Starting with 2.6.18, the kernel version is in utsrelease.h instead of version.h, accomodate both cases ++KERNELVERSION=$(shell awk -F\" '/REL/ {print $$2}' $(shell grep -s -l REL $(KERNELSRC)/include/linux/version.h $(KERNELSRC)/include/linux/utsrelease.h)) ++KERNELMAJOR=$(shell echo $(KERNELVERSION)|head -c3) ++ ++# next line is for kernel 2.6, if you integrate the driver in the kernel tree ++# /usr/src/linux/drivers/acerhk - or something similar ++# don't forget to add the following line to the parent dir's Makefile: ++# (/usr/src/linux/drivers/Makefile) ++# obj-m += acerhk/ ++CONFIG_ACERHK?=m ++obj-$(CONFIG_ACERHK) += acerhk.o ++ ++CFLAGS+=-c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe ++INCLUDE=-I$(KERNELSRC)/include ++ ++ifeq ($(KERNELMAJOR), 2.6) ++TARGET := acerhk.ko ++else ++TARGET := acerhk.o ++endif ++ ++SOURCE := acerhk.c ++ ++all: $(TARGET) ++ ++help: ++ @echo Possible targets: ++ @echo -e all\\t- default target, builds kernel module ++ @echo -e install\\t- copies module binary to /lib/modules/$(KERNELVERSION)/extra/ ++ @echo -e clean\\t- removes all binaries and temporary files ++ ++# this target is only for me, don't use it yourself (Olaf) ++export: ++ sh export.sh ++ ++acerhk.ko: $(SOURCE) acerhk.h ++ $(MAKE) -C $(KERNELSRC) SUBDIRS=$(PWD) modules ++ ++acerhk.o: $(SOURCE) acerhk.h ++ $(CC) $(INCLUDE) $(CFLAGS) -DMODVERSIONS -DMODULE -D__KERNEL__ -o $(TARGET) $(SOURCE) ++ ++asm: $(SOURCE) ++ifeq ($(KERNELMAJOR), 2.6) ++ $(CC) $(INCLUDE) $(INCLUDE)/asm-i386/mach-default $(CFLAGS) -fverbose-asm -S -DMODVERSIONS -DMODULE -D__KERNEL__ $(SOURCE) ++else ++ $(CC) $(INCLUDE) $(CFLAGS) -fverbose-asm -S -DMODVERSIONS -DMODULE -D__KERNEL__ $(SOURCE) ++endif ++ ++clean: ++ rm -f *~ *.o *.s *.ko .acerhk* *.mod.c ++ ++load: $(TARGET) ++ insmod $(TARGET) ++ ++unload: ++ rmmod acerhk ++ ++install: $(TARGET) ++ mkdir -p /lib/modules/$(KERNELVERSION)/extra ++ cp -v $(TARGET) /lib/modules/$(KERNELVERSION)/extra/ ++ depmod -a +diff -Nurp linux-2.6.37/3rdparty/acerhk/NEWS linux-2.6.37.3rdparty/3rdparty/acerhk/NEWS +--- linux-2.6.37/3rdparty/acerhk/NEWS 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/NEWS 2003-02-28 02:47:18.000000000 +0200 +@@ -0,0 +1,16 @@ ++2003-02-28 Version 0.5.0 ++ completely changed key polling/translation ++ support for more series ++2002-07-06 Version 0.4.2 ++ added debug functionality ++ bugfix with 520/210 ++2002-06-24 Version 0.4.1 ++ added support for TM 210 series ++ removed nvram dependency ++2002-06-15 Version 0.4 ++ added model recognition ++ added kernel polling an key event generation ++ added support for 520 series ++ ++2002-04-29 Version 0.3 ++ Initial release +\ Ingen nyrad vid filslut +diff -Nurp linux-2.6.37/3rdparty/acerhk/README linux-2.6.37.3rdparty/3rdparty/acerhk/README +--- linux-2.6.37/3rdparty/acerhk/README 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/acerhk/README 2006-11-10 00:01:46.000000000 +0200 +@@ -0,0 +1,215 @@ ++ ++What is this driver good for? ++***************************** ++ ++This driver will give access to the special keys on notebooks of the ++Acer Travelmate series, which are not handled by the keyboard ++driver. ++It also works on notebooks from other manufacturers (some Medion, ++Fujitsu-Siemens, ...). ++ ++It also has some other related functionality (depending on the model): ++- controlling LEDs (Mail, Wireless) ++- enable/disable wireless hardware ++ ++Usage ++***** ++ ++The driver provides a device /dev/misc/acerhk where you can access all ++functions through IOCTL's, look into acerhk.h for their definitions. ++I use devfs and don't care about the minor number. You may want to change ++ACERHK_MINOR in acerhk.h. ++If you don't use devfs you need to create the device node. The device uses ++major 10 (misc character devices), the minor is chosen by the kernel (if ++ACERHK_MINOR equals MISC_DYNAMIC_MINOR) or by yourself (any other value). ++Use something like ++ mknod /dev/acerhk c 10 123 ++to create the device node. ++You can also use most functions through procfs. You will find some files in ++/proc/driver/acerhk: ++ led - write "on" or "off" to set the mail led state ++ key - read it to get a key press, only useful on non-dritek models ++ and only if polling is disabled ++ This file exists only on non-dritek models ++ info - some information about the driver, including the number of ++ pending keys ++ wirelessled - write "on" or "off" to set the led state and enable ++ wlan hardware ++ On some laptops you need to load the ipw2200 (others ++ too?) with option "led=1" to make the led work. ++ blueled - write "on" or "off" to set the led state and enable ++ bluetooth hardware ++ write a value n >= 50 to let the led blink every n jiffies ++ Do not use blinking mode where not only the led but also the ++ bluetooth hardware is controlled! ++ ++Probably the best way to use the driver is to let it poll for the keys itself ++and generate real key events. this is the normal case when loading the module ++without an additional parameter : ++ ++ modprobe acerhk ++ ++or you can use the ioctl as specified in acerhk.h to control the polling. If ++your kernel has keyboard input support you will get real key events when ++pressing the special keys. ++You can then use whatever software you like to make use of those keys, ++i.e. 'hotkeys' or Linux Easy Access Keyboard 'lineakd'. I prefer hotkeys, just ++in case anyone is interested, you can find a sample configuration for this ++programm in doc/acertm.def. ++Gnome >= 2.4 has built in support for multimedia keys (acme), that's ++what I use now. ++ ++Have a look at ++ http://mmkc.sourceforge.net/ ++ ++Note: If you have one of the newer models using dritek hardware you don't need ++polling (nor the file /proc/driver/acerhk/key) to use your buttons. On this ++hardware the driver only needs to send a special command to the keyboard ++controller to make them work. The actual key presses are then handled by the ++normal keyboard driver of the kernel. You can switch of polling by ++loading the module with poll=0. It saves you precious cpu time. ++ ++ ++Module parameters ++***************** ++name values meaning ++autowlan 0,1 disable(default)/enable automatic switching of wlan hardware ++ on wireless keypress, only useful for older (no ++ dritek-hardware) models, works only will poll=1 ++poll 0,1 disable/enable(default) kernel polling of key events ++verbose 0-4 verbosity level, see below ++usedritek 0,1 disable/enable(default) use of dritek hardware on newer ++ series, needed to activate the keys on such models ++force_series set this to the laptop series number you want the driver to ++ assume, skip autodetection (look at function ++ setup_model_features() for possible values) ++ ++Debugging ++********* ++ ++You can make the the driver be more verbose. To do this, add the following ++parameter when loading the module: ++ ++ verbose= ++ ++n is an integer, 0 (default) means no additional information while increasing ++values provide an increasing amount of information. Currently 3 is maximum, ++bigger values will have the same effect as 3. The existing verbosity levels ++will generate information about: ++ Level Information ++ 1 state changes and variable initialization ++ 2 model probing ++ 3 key translation, only known keys ++ 4 key translation, also unknown keys ++ 5 misc. information (idle values) ++ ++If you have rather serious problems you can activate debugging functionality ++in the driver. To do this, uncomment the '#define ACERDEBUG' in acerhk.c. You ++will find a new file in /proc/driver/acerhk, named 'debug'. You cannot read ++from this file, but you can write commands consisting of up to 4 digits. The ++first one specifies the action, while the latter can give additional ++parameters. Implemented are: ++ 'd' decrement module usage counter ++ 'i' increment module usage counter ++ ++ 'p' call function pbutton_fct() ++ 't' call function get_thermal_event() ++ 'w1x' call function wbutton_fct_1() with parameter x (0-9) ++ 'w2x' call function wbutton_fct_2() with parameter x (0-9) ++ ++ 'vx' change verbosity level to x (0-9) ++ ++ 'mxyy' set mapping of key name x to key event yy (hex) ++ 'sxx' send key event xx (hex) to input system ++ 'Sxx' simulate acer key press with code xx (hex) ++ ++ 'e0' stop kernel polling ++ 'e1' start kernel polling ++ ++Example: ++ ++1) echo d > /proc/driver/acerhk/debug ++ ++will decrement the usage counter, very useful if a program using the driver ++segfaulted. This way you can still unload the driver. ++ ++2) echo v4 > /proc/driver/acerhk/debug ++ ++will set the verbosity level to maximum. ++ ++Keycodes ++******** ++ ++see doc/keycodes ++Also see http://bernd-wurst.de/linux/tm800.php#mmkeys (only in german) ++ ++If you have one of the newer models with the dritek hardware, use kernel 2.6 ++and get (after enabling it) kernel messages of the form: ++ ++ atkbd.c: Unknown key pressed (translated set 2, code 0xf4 on ++ isa0060/serio0). ++ atkbd.c: Use 'setkeycodes e074 ' to make it known. ++ ++then you should do exactly what your told. In this case you could do ++ ++ setkeycodes e074 158 ++ ++to map the button with scancode e074 (hex) to keycode 158 (decimal). To find ++out the scancodes of the buttons either look into the kernel log or into the ++file MMKEYBD.CFG of the windows launch manager package. There you should find ++lines like this: ++ ++Key 1 = 1,E0,74,E0,F4,F500,P1 ++ ** ** ** ++ ++The important information is marked in the example above. The numbers give the ++scancode produced by the button which's name is given last. ++The keycode you give as parameter to setkeycodes is one out of the header file ++linux/input.h, in the example above the one for KEY_BACK. ++Important note: I received mails from a number of people where setkeycodes ++rejected keycodes above a certain value. This is caused by an outdated version ++of setkeycodes, use a more recent one. ++To ease the setup of keymappings for the newer series I will try to include ++setup scripts for the different notebook series. If I have enough time to ++spare I will perhaps expand the driver itself do to that. ++ ++How does it work? ++***************** ++ ++The driver is based on the windows Me for series 610 driver and ++resembles its structure and functionality. ++Key presses are events, which are stored in a FIFO queue with 31 ++entries. You can access the event count via CMOS nvram, but the access to ++the actual queue (and other functionality like switching the mail led) is ++done through calling a system ROM function. ++Upon loading the driver looks for this function, if it cannot find it, ++loading aborts. ++Newer Dritek Hardware: ++Button handling is done entirely by the EC (embbedded/environment ++controller) which behaves like an extended keyboard controller. My ++driver only enables/disables this extension. ++ ++ ++Credits ++******* ++ ++Leif Jensen, whose driver inspired me to do the probing stuff ++http://www.math.columbia.edu/~jensen/linux/acertm/ ++ ++Thanks to all who contributed patches to this driver or who just tried it out ++on their laptops, without them it wouldn't support anything else but my ++TM 613. ++ ++Contact ++******* ++ ++If you have problems with the driver, please include the following information: ++1. name of your laptop (e.g. Acer TM 4001) ++2. content of /proc/driver/acerhk/info, if available ++3. kernel output after loading the module with verbose=2 ++ ++Email: Olaf Tauber ++ ++The latest version can be found here: ++ ++http://www.informatik.hu-berlin.de/~tauber/acerhk diff --git a/kernel/kernel/files/patches/mageia/3rd-acerhk-2.6.36-buildfix.patch b/kernel/kernel/files/patches/mageia/3rd-acerhk-2.6.36-buildfix.patch new file mode 100644 index 00000000..47a71053 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-acerhk-2.6.36-buildfix.patch @@ -0,0 +1,20 @@ +--- linux-2.6.35/3rdparty/acerhk/acerhk.c.orig 2010-10-03 12:50:33.000000000 +0000 ++++ linux-2.6.35/3rdparty/acerhk/acerhk.c 2010-10-03 13:13:22.093868410 +0000 +@@ -2730,7 +2730,7 @@ static void acerhk_proc_cleanup(void) + + /* {{{ file operations */ + +-static int acerhk_ioctl( struct inode *inode, struct file *file, ++static long acerhk_ioctl( struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg ) + { + int retval; +@@ -2827,7 +2827,7 @@ static int acerhk_release( struct inode + + static struct file_operations acerhk_fops = { + owner: THIS_MODULE, +- ioctl: acerhk_ioctl, ++ unlocked_ioctl: acerhk_ioctl, + open: acerhk_open, + #ifdef ACERDEBUG + write: acerhk_write, diff --git a/kernel/kernel/files/patches/mageia/3rd-acerhk-extra-cflags.patch b/kernel/kernel/files/patches/mageia/3rd-acerhk-extra-cflags.patch new file mode 100644 index 00000000..7971c699 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-acerhk-extra-cflags.patch @@ -0,0 +1,33 @@ +CFLAGS use isn't allowed anymore with 2.6.24, we must use EXTRA_CFLAGS +in its place + +Signed-off-by: Herton Ronaldo Krzesinski + +--- linux-2.6.23/3rdparty/acerhk/Makefile.orig 2007-11-08 21:32:43.000000000 -0200 ++++ linux-2.6.23/3rdparty/acerhk/Makefile 2007-11-08 21:33:28.000000000 -0200 +@@ -14,7 +14,7 @@ + CONFIG_ACERHK?=m + obj-$(CONFIG_ACERHK) += acerhk.o + +-CFLAGS+=-c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe ++EXTRA_CFLAGS+=-c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe + INCLUDE=-I$(KERNELSRC)/include + + ifeq ($(KERNELMAJOR), 2.6) +@@ -41,13 +41,13 @@ acerhk.ko: $(SOURCE) acerhk.h + $(MAKE) -C $(KERNELSRC) SUBDIRS=$(PWD) modules + + acerhk.o: $(SOURCE) acerhk.h +- $(CC) $(INCLUDE) $(CFLAGS) -DMODVERSIONS -DMODULE -D__KERNEL__ -o $(TARGET) $(SOURCE) ++ $(CC) $(INCLUDE) $(EXTRA_CFLAGS) -DMODVERSIONS -DMODULE -D__KERNEL__ -o $(TARGET) $(SOURCE) + + asm: $(SOURCE) + ifeq ($(KERNELMAJOR), 2.6) +- $(CC) $(INCLUDE) $(INCLUDE)/asm-i386/mach-default $(CFLAGS) -fverbose-asm -S -DMODVERSIONS -DMODULE -D__KERNEL__ $(SOURCE) ++ $(CC) $(INCLUDE) $(INCLUDE)/asm-i386/mach-default $(EXTRA_CFLAGS) -fverbose-asm -S -DMODVERSIONS -DMODULE -D__KERNEL__ $(SOURCE) + else +- $(CC) $(INCLUDE) $(CFLAGS) -fverbose-asm -S -DMODVERSIONS -DMODULE -D__KERNEL__ $(SOURCE) ++ $(CC) $(INCLUDE) $(EXTRA_CFLAGS) -fverbose-asm -S -DMODVERSIONS -DMODULE -D__KERNEL__ $(SOURCE) + endif + + clean: diff --git a/kernel/kernel/files/patches/mageia/3rd-acerhk-fix-build-with-function-tracer.patch b/kernel/kernel/files/patches/mageia/3rd-acerhk-fix-build-with-function-tracer.patch new file mode 100644 index 00000000..c8d000b5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-acerhk-fix-build-with-function-tracer.patch @@ -0,0 +1,22 @@ +Fix acerhk build with FUNCTION_TRACER enabled. + +Signed-off-by: Herton Ronaldo Krzesinski +--- + 3rdparty/acerhk/Makefile | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff -p -up linux-2.6.31/3rdparty/acerhk/Makefile.orig linux-2.6.31/3rdparty/acerhk/Makefile +--- linux-2.6.31/3rdparty/acerhk/Makefile.orig 2009-10-02 16:39:06.000000000 -0300 ++++ linux-2.6.31/3rdparty/acerhk/Makefile 2009-10-02 16:45:13.000000000 -0300 +@@ -14,7 +14,10 @@ + CONFIG_ACERHK?=m + obj-$(CONFIG_ACERHK) += acerhk.o + +-EXTRA_CFLAGS+=-c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe ++CFLAGS_acerhk.o += -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe ++ifdef CONFIG_FUNCTION_TRACER ++CFLAGS_REMOVE_acerhk.o = -pg ++endif + INCLUDE=-I$(KERNELSRC)/include + + ifeq ($(KERNELMAJOR), 2.6) diff --git a/kernel/kernel/files/patches/mageia/3rd-acerhk-fix-include.patch b/kernel/kernel/files/patches/mageia/3rd-acerhk-fix-include.patch new file mode 100644 index 00000000..cba26984 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-acerhk-fix-include.patch @@ -0,0 +1,23 @@ + +AUTOCONF_INCLUDED is not defined anymore in 2.6.38, so old include got exposed. + +Fix by removing the offending bits. + +Signed-off-by: Thomas Backlund + + 3rdparty/acerhk/acerhk.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- linux-2.6.38/3rdparty/acerhk/acerhk.c.orig 2011-03-20 13:57:32.000000000 +0200 ++++ linux-2.6.38/3rdparty/acerhk/acerhk.c 2011-03-20 15:00:45.768659568 +0200 +@@ -35,10 +35,6 @@ + * + */ + +-#ifndef AUTOCONF_INCLUDED +-#include +-#endif +- + /* This driver is heavily dependent on the architecture, don't let + * anyone without an X86 machine use it. On laptops with AMD64 + * architecture this driver is only useable in 32 bit mode. diff --git a/kernel/kernel/files/patches/mageia/3rd-acerhk-kbuild.patch b/kernel/kernel/files/patches/mageia/3rd-acerhk-kbuild.patch new file mode 100644 index 00000000..f0c419ad --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-acerhk-kbuild.patch @@ -0,0 +1,37 @@ +Fix Makefile and add Kconfig for the acerhk driver +--- + 3rdparty/acerhk/Kconfig | 8 8 + 0 - 0 ! + 3rdparty/acerhk/Makefile | 6 3 + 3 - 0 ! + 2 files changed, 11 insertions(+), 3 deletions(-) + +Index: linux-2.6.21/3rdparty/acerhk/Makefile +=================================================================== +--- linux-2.6.21.orig/3rdparty/acerhk/Makefile 2007-05-15 15:34:48.000000000 +0200 ++++ linux-2.6.21/3rdparty/acerhk/Makefile 2007-05-15 15:37:17.000000000 +0200 +@@ -1,10 +1,10 @@ + # change KERNELSRC to the location of your kernel build tree only if + # autodetection does not work + #KERNELSRC=/usr/src/linux +-KERNELSRC?=/lib/modules/`uname -r`/build ++#KERNELSRC?=/lib/modules/`uname -r`/build + # Starting with 2.6.18, the kernel version is in utsrelease.h instead of version.h, accomodate both cases +-KERNELVERSION=$(shell awk -F\" '/REL/ {print $$2}' $(shell grep -s -l REL $(KERNELSRC)/include/linux/version.h $(KERNELSRC)/include/linux/utsrelease.h)) +-KERNELMAJOR=$(shell echo $(KERNELVERSION)|head -c3) ++#KERNELVERSION=$(shell awk -F\" '/REL/ {print $$2}' $(shell grep -s -l REL $(KERNELSRC)/include/linux/version.h $(KERNELSRC)/include/linux/utsrelease.h)) ++#KERNELMAJOR=$(shell echo $(KERNELVERSION)|head -c3) + + # next line is for kernel 2.6, if you integrate the driver in the kernel tree + # /usr/src/linux/drivers/acerhk - or something similar +Index: linux-2.6.21/3rdparty/acerhk/Kconfig +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-2.6.21/3rdparty/acerhk/Kconfig 2007-05-15 15:39:30.000000000 +0200 +@@ -0,0 +1,8 @@ ++config ACERHK ++ tristate "Acerhk driver" ++ depends on EXPERIMENTAL && X86 ++ ---help--- ++ This is an experimental acer keyboard driver for ++ acer laptops. If you have a notebook with a ipw2X00 ++ wireless card, it allows you to turn off the rf_kill ++ diff --git a/kernel/kernel/files/patches/mageia/3rd-acerhk-proc_dir_entry-owner.patch b/kernel/kernel/files/patches/mageia/3rd-acerhk-proc_dir_entry-owner.patch new file mode 100644 index 00000000..e5821d46 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-acerhk-proc_dir_entry-owner.patch @@ -0,0 +1,67 @@ +Updated for owner removal from struct proc_dir_entry (2.6.30) + +Signed-off-by: Herton Ronaldo Krzesinski + +--- + 3rdparty/acerhk/acerhk.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff -p -up linux-2.6.29/3rdparty/acerhk/acerhk.c.orig linux-2.6.29/3rdparty/acerhk/acerhk.c +--- linux-2.6.29/3rdparty/acerhk/acerhk.c.orig 2009-05-22 02:42:44.000000000 -0300 ++++ linux-2.6.29/3rdparty/acerhk/acerhk.c 2009-05-22 02:43:45.000000000 -0300 +@@ -2626,7 +2626,6 @@ static int acerhk_proc_init(void) + printk(KERN_INFO"acerhk: could not create /proc/driver/acerhk\n"); + } + else { +- proc_acer_dir->owner = THIS_MODULE; + /* now create several files, first general info ... */ + entry = create_proc_read_entry("info", + 0444, proc_acer_dir, acerhk_proc_info, NULL); +@@ -2635,7 +2634,6 @@ static int acerhk_proc_init(void) + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } else { +- entry->owner = THIS_MODULE; + /* ... last pressed key ... */ + entry = create_proc_read_entry("key", + 0444, proc_acer_dir, acerhk_proc_key, NULL); +@@ -2645,7 +2643,6 @@ static int acerhk_proc_init(void) + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } else { +- entry->owner = THIS_MODULE; + /* ... and led control file */ + entry = create_proc_entry("led", 0222, proc_acer_dir); + if (entry == NULL) { +@@ -2657,7 +2654,6 @@ static int acerhk_proc_init(void) + } + else { + entry->write_proc = acerhk_proc_led; +- entry->owner = THIS_MODULE; + /* ... and wireless led controll file */ + entry = create_proc_entry("wirelessled", 0222, proc_acer_dir); + if (entry == NULL) { +@@ -2670,7 +2666,6 @@ static int acerhk_proc_init(void) + } + else { + entry->write_proc = acerhk_proc_wirelessled; +- entry->owner = THIS_MODULE; + /* ... and bluetooth led controll file */ + entry = create_proc_entry("blueled", 0222, proc_acer_dir); + if (entry == NULL) { +@@ -2683,7 +2678,6 @@ static int acerhk_proc_init(void) + retval = 0; + } else { + entry->write_proc = acerhk_proc_blueled; +- entry->owner = THIS_MODULE; + retval = 1; + #ifdef ACERDEBUG + /* add extra file for debugging purposes */ +@@ -2700,7 +2694,6 @@ static int acerhk_proc_init(void) + } + else { + entry->write_proc = acerhk_proc_debug; +- entry->owner = THIS_MODULE; + retval = 1; + } + #endif diff --git a/kernel/kernel/files/patches/mageia/3rd-aes2501-kbuild.patch b/kernel/kernel/files/patches/mageia/3rd-aes2501-kbuild.patch new file mode 100644 index 00000000..1dcf8fa0 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-aes2501-kbuild.patch @@ -0,0 +1,47 @@ +Fix Makefile and add Kconfig for the aes2501 driver. + +Signed-off-by: Herton Ronaldo Krzesinski + +--- + linux-2.6.23/3rdparty/aes2501/Kconfig | 10 ++++++++++ + linux-2.6.23/3rdparty/aes2501/Makefile | 19 +------------------ + 2 files changed, 11 insertions(+), 18 deletions(-) + +diff -p -up linux-2.6.23/3rdparty/aes2501/Kconfig.orig linux-2.6.23/3rdparty/aes2501/Kconfig +--- linux-2.6.23/3rdparty/aes2501/Kconfig.orig 2008-01-13 23:14:47.000000000 -0200 ++++ linux-2.6.23/3rdparty/aes2501/Kconfig 2008-01-13 23:35:21.000000000 -0200 +@@ -0,0 +1,10 @@ ++config AES2501 ++ tristate "AuthenTec AES2501 Fingerprint Sensor Driver" ++ depends on USB ++ default m ++ ---help--- ++ Say Y here if you have a AuthenTec AES2501 Fingerprint ++ Sensor device. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called aes2501. +diff -p -up linux-2.6.23/3rdparty/aes2501/Makefile.orig linux-2.6.23/3rdparty/aes2501/Makefile +--- linux-2.6.23/3rdparty/aes2501/Makefile.orig 2008-01-13 23:14:36.000000000 -0200 ++++ linux-2.6.23/3rdparty/aes2501/Makefile 2008-01-13 23:21:33.000000000 -0200 +@@ -1,19 +1,2 @@ +- +-obj-m := aes2501.o +- +-KERNELDIR ?= /lib/modules/$(shell uname -r)/build +- +-PWD := $(shell pwd) +- +-all: usertest +- $(MAKE) -C $(KERNELDIR) M=$(PWD) +- +-usertest: +- gcc -I. -o usertest usertest.c +- +-clean: +- rm -f *.o *~ aes2501.ko aes2501.mod.c Module.symvers usertest +- rm -rf .tmp_versions +- rm -f .*.cmd +- ++obj-$(CONFIG_AES2501) := aes2501.o + diff --git a/kernel/kernel/files/patches/mageia/3rd-aes2501-r19.patch b/kernel/kernel/files/patches/mageia/3rd-aes2501-r19.patch new file mode 100644 index 00000000..a5f95e79 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-aes2501-r19.patch @@ -0,0 +1,2356 @@ + 3rdparty/aes2501/ChangeLog | 95 ++ + 3rdparty/aes2501/Makefile | 19 + 3rdparty/aes2501/aes2501.c | 1629 ++++++++++++++++++++++++++++++++++++++++ + 3rdparty/aes2501/aes2501.h | 40 + 3rdparty/aes2501/aes2501_regs.h | 464 +++++++++++ + 3rdparty/aes2501/usertest.c | 78 + + 6 files changed, 2325 insertions(+) +diff -Nurp linux-2.6.37/3rdparty/aes2501/aes2501.c linux-2.6.37.3rdparty/3rdparty/aes2501/aes2501.c +--- linux-2.6.37/3rdparty/aes2501/aes2501.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/aes2501/aes2501.c 2008-01-14 03:07:30.000000000 +0200 +@@ -0,0 +1,1629 @@ ++ ++/* ++ * aes2501.c -- AuthenTec AES2501 Fingerprint Sensor Driver for Linux ++ * ++ * Maintainer: Cyrille Bagard ++ * ++ * Copyright (C) 2007 Cyrille Bagard ++ * ++ * This file is part of the AES2501 driver. ++ * ++ * the AES2501 driver is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * the AES2501 driver is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with the AES2501 driver; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#include "aes2501.h" ++#include "aes2501_regs.h" ++ ++ ++static int major = 0; ++ ++module_param(major, int, 0); ++MODULE_PARM_DESC(major, "major number"); ++ ++ ++//#define DEBUG ++ ++ ++#define PRINTK_INFO(fmt, arg...) printk(KERN_INFO "aes2501: " fmt, ## arg) ++ ++#define PRINTK_CRIT(fmt, arg...) printk(KERN_CRIT "aes2501: " fmt, ## arg) ++ ++#define PRINTK_DBG(fmt, arg...) printk(KERN_DEBUG "aes2501: " fmt, ## arg) ++ ++ ++static struct workqueue_struct *comm_queue; ++ ++ ++static char *finger_print = NULL; ++static size_t finger_print_len; ++ ++ ++ ++static DECLARE_WAIT_QUEUE_HEAD(wq); ++static int flag = 0; ++ ++ ++ ++struct usb_aes2501 *_dev; ++ ++ ++ ++ ++ ++ ++struct aes2501 { ++ ++ struct usb_device *udev; ++ ++ int temp; ++ ++ unsigned char *int_in_buffer; ++ struct urb *int_in_urb; ++ ++}; ++ ++ ++/* ++#define VENDOR_ID 0x08f7 ++#define PRODUCT_ID 0x0002 ++*/ ++ ++#define VENDOR_ID 0x08ff ++#define PRODUCT_ID 0x2580 ++ ++ ++/* Table of devices that work with this driver */ ++ ++static struct usb_device_id id_table [] = { ++ { USB_DEVICE(VENDOR_ID, PRODUCT_ID) }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(usb, id_table); ++ ++ ++/* Get a minor range for your devices from the usb maintainer */ ++#define USB_AES2501_MINOR_BASE 192 ++ ++ ++ ++#define WRITES_IN_FLIGHT 8 /* ??? */ ++ ++ ++ ++enum AES2501_Status { ++ ++ AESS_INIT_DONE, ++ AESS_IS_SCANNING, ++ ++ AESS_COUNT ++ ++}; ++ ++ ++#define BULK_OUT_BUFFER_SIZE 32 ++ ++ ++/* Read a register value from a dump sent by the device. */ ++static int read_register_value(const uint8_t *, Aes2501Registers); ++ ++/* Tells if a finger motion is still detected. */ ++static int sum_histogram_values(const uint8_t *, uint8_t); ++ ++ ++/* Structure to hold all device specific stuff */ ++struct usb_aes2501 { ++ ++ struct usb_device *udev; /* the usb device for this device */ ++ struct usb_interface *interface; /* the interface for this device */ ++ struct semaphore limit_sem; /* limiting the number of writes in progress */ ++ unsigned char *bulk_in_buffer; /* the buffer to receive data */ ++ size_t bulk_in_size; /* the size of the receive buffer */ ++ __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ ++ uint8_t bulk_out_buffer[BULK_OUT_BUFFER_SIZE]; /* the buffer to send data (32 / 8 = 4) */ ++ size_t bulk_out_buffer_used; /* the quantity of buffered data to send */ ++ __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ ++ struct kref kref; ++ struct mutex io_mutex; /* synchronize I/O with disconnect */ ++ ++ DECLARE_BITMAP(status, AESS_COUNT); /* Information about what has been set / is running */ ++ ++ struct work_struct scan_work; ++ uint8_t stop_scan; /* Flag to stop finger detecting during module removal */ ++}; ++ ++ ++#define to_aes2501_dev(r) container_of(r, struct usb_aes2501, kref) ++ ++static struct usb_driver aes2501_driver; ++ ++static void aes2501_delete(struct kref *kref) ++{ ++ struct usb_aes2501 *dev; ++ ++ dev = to_aes2501_dev(kref); ++ ++ usb_put_dev(dev->udev); ++ kfree(dev->bulk_in_buffer); ++ kfree(dev); ++ ++} ++ ++ ++static int aes2501_open(struct inode *inode, struct file *file); ++/* ++struct usb_aes2501 *_dev; ++static int aes2501_open(struct inode *inode, struct file *file) ++{ ++ printk(KERN_INFO "Plop !\n"); ++ ++ ++ ++ return 0; ++} ++*/ ++ ++static ssize_t aes2501_read(struct file *file, char *buffer, size_t count, loff_t *ppos) ++{ ++ int read_len; ++ ++ //printk(KERN_INFO "aes2501_read ! got %d -> need (%d ; %d)\n", finger_print_len, *ppos, count); ++ ++ if (flag == 0) ++ printk(KERN_INFO "Process %i (%s) is going to sleep\n", current->pid, current->comm); ++ ++ wait_event_interruptible(wq, flag == 1); ++ ++ if (signal_pending(current)) ++ return -ERESTARTSYS; ++ ++ if (finger_print_len == 0) ++ return -ENODATA; ++ ++ if (unlikely((*ppos < 0) || (loff_t)(*ppos + count) < 0)) ++ return -EINVAL; ++ ++ if (*ppos + count > finger_print_len) ++ read_len = finger_print_len - *ppos; ++ else read_len = count; ++ ++ if (read_len > 0) ++ { ++ if (!access_ok(VERIFY_WRITE, buffer, read_len)) ++ return -EFAULT; ++ ++ read_len -= copy_to_user(buffer, finger_print + *ppos, read_len); ++ *ppos += read_len; ++ ++ } ++ ++ /* !!!! */ ++ else flag = 0; ++ ++ return read_len; ++ ++} ++ ++ ++ ++static int detect_finger_on_aes2501(struct usb_aes2501 *dev); ++ ++static void do_scanning(struct work_struct *work); ++ ++ ++// ioctl - I/O control ++static int aes2501_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ struct usb_aes2501 *dev; ++ int retval; ++ ++ dev = _dev; ++ ++ ++ printk(KERN_INFO "Get IOCtl :: cmd = %d vs %d\n", cmd, (AES2501_IOC_TEST)); ++ ++ switch (cmd) { ++ ++ case AES2501_IOC_TEST: ++ ++#if defined(_arch_um__) || !(LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)) ++ INIT_WORK(&dev->scan_work, do_scanning); ++#else ++ INIT_WORK(&dev->scan_work, do_scanning, NULL); ++#endif ++ ++ retval = queue_work(comm_queue, &dev->scan_work); ++ ++ ++ } ++ ++ ++ ++ return 0; ++ ++ ++#if 0 ++ int retval = 0; ++ switch ( cmd ) { ++ case CASE1:/* for writing data to arg */ ++ if (copy_from_user(&data, (int *)arg, sizeof(int))) ++ return -EFAULT; ++ break; ++ case CASE2:/* for reading data from arg */ ++ if (copy_to_user((int *)arg, &data, sizeof(int))) ++ return -EFAULT; ++ break; ++ default: ++ retval = -EINVAL; ++ } ++ return retval; ++#endif ++} ++ ++ ++ ++static const struct file_operations aes2501_fops = { ++ .owner = THIS_MODULE, ++ .read = aes2501_read,/* ++ .write = aes2501_write,*/ ++ .open = aes2501_open,/* ++ .release = skel_release,*/ ++ .ioctl = aes2501_ioctl ++}; ++ ++ ++ ++/* ++static int send_data_to_aes2501(struct usb_aes2501 *dev, unsigned char *buffer, int len) ++{ ++#ifdef DEBUG ++ int i; ++#endif ++ int bytes_written; ++ int ret; ++ ++#ifdef DEBUG ++ printk(KERN_INFO "\n:: OUT :: len=%d\n", len); ++ ++ for (i = 0; i < len; i++) ++ { ++ if (i > 0 && i % 16 == 0) ++ printk("\n"); ++ if (i % 16 == 0) ++ printk(KERN_INFO " %05x: ", i); ++ ++ if (i % 8 == 0) ++ printk(" "); ++ ++ printk("%02x ", buffer[i]); ++ ++ } ++ ++ printk("\n"); ++#endif ++ ++ ret = usb_bulk_msg(dev->udev, ++ usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), ++ buffer, ++ len, ++ &bytes_written, 4000); ++ ++ if (ret < 0) ++ PRINTK_CRIT("error while sending data: %d\n", ret); ++ ++ if (bytes_written != len) ++ printk(KERN_INFO "did not write all ! %d vs %d\n", bytes_written, len); ++ ++ return ret; ++ ++} ++*/ ++ ++static int flush_aes2501_bulk_out(struct usb_aes2501 *dev) ++{ ++ int ret; ++ int bytes_written; ++ ++ ret = 0; ++ ++ if (dev->bulk_out_buffer_used > 0) { ++ ++ ret = usb_bulk_msg(dev->udev, ++ usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), ++ dev->bulk_out_buffer, ++ dev->bulk_out_buffer_used, ++ &bytes_written, 4000); ++ ++ if (ret < 0) ++ PRINTK_CRIT("error while sending data: %d\n", ret); ++ ++ else if (bytes_written != dev->bulk_out_buffer_used) ++ { ++ printk(KERN_INFO "did not write all ! %d vs %d\n", bytes_written, dev->bulk_out_buffer_used); ++ /*ret = ... */ ++ } ++ ++ dev->bulk_out_buffer_used = 0; ++ ++ } ++ ++ return ret; ++ ++} ++ ++ ++static int write_aes2501_register(struct usb_aes2501 *dev, uint8_t reg, uint8_t data) ++{ ++ int ret; ++ ++ if (dev->bulk_out_buffer_used == BULK_OUT_BUFFER_SIZE) ++ ret = flush_aes2501_bulk_out(dev); ++ else ++ ret = 0; ++ ++ dev->bulk_out_buffer[dev->bulk_out_buffer_used++] = reg; ++ dev->bulk_out_buffer[dev->bulk_out_buffer_used++] = data; ++ ++ return ret; ++ ++} ++ ++ ++static int recv_data_to_aes2501(struct usb_aes2501 *dev, unsigned char *buffer, int len) ++{ ++ int bytes_read; ++ int ret; ++#ifdef DEBUG ++ int i; ++#endif ++ ++ ret = usb_bulk_msg(dev->udev, ++ usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr), ++ buffer, ++ len, ++ &bytes_read, 4000); ++ ++ if (ret < 0) ++ PRINTK_CRIT("error while sending data: %d\n", ret); ++ ++ if (bytes_read != len) ++ printk(KERN_INFO "did not read all ! %d vs %d\n", bytes_read, len); ++ ++#ifdef DEBUG ++ if (ret == 0) ++ { ++ printk(KERN_INFO "\n:: IN :: len=%d\n", len); ++ ++ for (i = 0; i < len; i++) ++ { ++ if (i > 0 && i % 16 == 0) ++ printk("\n"); ++ if (i % 16 == 0) ++ printk(KERN_INFO " %05x: ", i); ++ ++ if (i % 8 == 0) ++ printk(" "); ++ ++ printk("%02x ", buffer[i]); ++ ++ } ++ ++ printk("\n"); ++ ++ } ++#endif ++ ++ return ret; ++ ++} ++ ++ ++ ++static int standby_aes2501(struct usb_aes2501 *dev) ++{ ++ ++ //unsigned char cmd[] = "\xac\x01\xad\x1a\x81\x02"; ++ ++ ++ unsigned char buffer[4]; ++ ++ ++ ++ ++ printk(KERN_INFO ">> Standby aes2501 !\n"); ++ ++ ++ //msleep(800); ++ ++ write_aes2501_register(dev, AES2501_REG_TREGC, AES2501_TREGC_ENABLE); ++ write_aes2501_register(dev, AES2501_REG_TREGD, 0x1a); ++ ++ flush_aes2501_bulk_out(dev); ++ ++ /** ++ * TODO: ++ * - lire ici les deux octets. ++ * - voir pour inverser les commandes. ++ */ ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL2, 0x02/* AES2501_CTRL2_READ_REGS ??? */); ++ flush_aes2501_bulk_out(dev); ++ ++ //send_data_to_aes2501(dev, cmd, 6); ++ recv_data_to_aes2501(dev, buffer, 2); ++ ++ ++ ++ printk(KERN_INFO " %02x %02x\n", buffer[0], buffer[1]); ++ ++ ++ if ((buffer[1] & AES2501_STAT_SCAN) == buffer[1]) ++ { ++ PRINTK_DBG("scan state: "); ++ ++ switch (buffer[1]) ++ { ++ case STATE_WAITING_FOR_FINGER: ++ printk("'Waiting for finger'\n"); ++ break; ++ case STATE_FINGER_SETTLING_DELAY: ++ printk("'In Finger settling delay'\n"); ++ break; ++ case STATE_POWER_UP_DELAY: ++ printk("'In power up delay'\n"); ++ break; ++ case STATE_WAITING_TO_START_SCAN: ++ printk("'Waiting to start image scan'\n"); ++ break; ++ case STATE_PRELOADING_SUBARRAY_0: ++ printk("'Pre-loading subarray 0'\n"); ++ break; ++ case STATE_SETUP_FOR_ROW_ADVANCE: ++ printk("'Setup for row advance'\n"); ++ break; ++ case STATE_WAITING_FOR_ROW_ADVANCE: ++ printk("'Waiting for row advance'\n"); ++ break; ++ case STATE_PRELOADING_COL_0: ++ printk("'Pre-loading column 0'\n"); ++ break; ++ case STATE_SETUP_FOR_COL_ADVANCE: ++ printk("'Setup for column advance'\n"); ++ break; ++ case STATE_WAITING_FOR_COL_ADVANCE: ++ printk("'Waiting for column advance'\n"); ++ break; ++ case STATE_WAITING_FOR_SCAN_START: ++ printk("'Waiting for scan start'\n"); ++ break; ++ case STATE_WAITING_FOR_SCAN_END: ++ printk("'Waiting for scan end'\n"); ++ break; ++ case STATE_WAITING_FOR_ROW_SETUP: ++ printk("'Waiting for row setup'\n"); ++ break; ++ case STATE_WAITING_FOR_COL_TIME: ++ printk("'Waiting for one column time (depends on scan rate)'\n"); ++ break; ++ case STATE_WAITING_FOR_QUEUED_DATA: ++ printk("'Waiting for queued data transmission to be completed'\n"); ++ break; ++ case STATE_WAIT_FOR_128_US: ++ printk("'Wait for 128 us'\n"); ++ break; ++ default: ++ printk("none (?!)\n"); ++ break; ++ ++ } ++ ++ } ++ ++ if (buffer[1] & AES2501_STAT_ERROR) ++ PRINTK_DBG("got serial interface framing error\n"); ++ ++ if (buffer[1] & AES2501_STAT_PAUSED) ++ PRINTK_DBG("scan was paused due to input buffer full\n"); ++ ++ if (buffer[1] & AES2501_STAT_RESET) ++ PRINTK_DBG("master reset input has been asserted\n"); ++ ++ ++ ++ ++ return 0; ++ ++ ++} ++ ++ ++ ++ ++static int setup_aes2501(struct usb_aes2501 *dev) ++{ ++ //unsigned char patch_msg[] = "\x80\x01"; ++ ++ ++ //unsigned char cmd[] = "\x80\x01\x81\x02"; ++ ++ //unsigned char cmd_00[] = "\xb0\x27"; ++ //unsigned char cmd_01[] = "\x80\x01\x82\x40"; ++ //unsigned char cmd_02[] = "\xff\x00"; ++ //unsigned char cmd_03[] = "\x80\x01\x82\x40\x83\x00\x88\x02\x89\x10\x8a\x05\x8c\x00\x8e\x13\x91\x44\x92\x34\x95\x16\x96\x16\x97\x18\xa1\x70\xa2\x02\xa7\x00\xac\x01\xad\x1a\x80\x04\x81\x04\xb4\x00";/*42*/ ++ //unsigned char cmd_04[] = "\x80\x01\x82\x40"; ++ ++ //unsigned char cmd2[] = "\x80\x01\xa8\x41\x82\x42\x83\x53\x80\x04\x81\x02";/*12*/ ++ ++ //unsigned char cmd3_00[] = "\xff\x00"; ++ //unsigned char cmd3_01[] = "\x80\x01\xa8\x41\x82\x42\x83\x53\x80\x04\x81\x02";/*12*/ ++ ++ //unsigned char cmd4[] = "\x80\x01\x82\x40\xb0\x27\x94\x0a\x80\x04\x83\x45\xa8\x41";/*14*/ ++ ++ //unsigned char cmd5_00[] = "\xb0\x27"; ++ //unsigned char cmd5_01[] = "\x80\x01\x82\x40"; ++ //unsigned char cmd5_02[] = "\xff\x00"; ++ //unsigned char cmd5_03[] = "\x80\x02"; ++ //unsigned char cmd5_04[] = "\x81\x02"; ++ ++ ++ int i; ++ ++ unsigned char buffer[128]; ++ ++ ++ /* To be sure the device will respond */ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ //send_data_to_aes2501(dev, patch_msg, 2); ++ flush_aes2501_bulk_out(dev);/* ... */ ++ ++ printk(KERN_INFO ">> Setting up aes2501 !\n"); ++ ++ /* Part 1 */ ++ ++ printk(KERN_INFO " -- part 1 --\n"); ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_CTRL2, AES2501_CTRL2_READ_REGS); ++ flush_aes2501_bulk_out(dev); ++ ++ //send_data_to_aes2501(dev, cmd, 4); ++ recv_data_to_aes2501(dev, buffer, 126); ++ ++ ++ ++ //send_data_to_aes2501(dev, cmd_00, 2); ++ ++ write_aes2501_register(dev, 0xb0, 0x27);/* Reserved */ ++ ++ ++ ++ //send_data_to_aes2501(dev, cmd_01, 4); ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ ++ for (i = 0; i <= 10; i++) ++ { ++ //msleep(200); ++ //send_data_to_aes2501(dev, cmd_02, 2); ++ write_aes2501_register(dev, 0xff, 0x00);/* Reserved */ ++ } ++ ++ //msleep(100); ++ ++ ++ //send_data_to_aes2501(dev, cmd_03, 42); ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ write_aes2501_register(dev, AES2501_REG_DETCTRL, AES2501_DETCTRL_DRATE_CONTINUOUS | AES2501_DETCTRL_SDELAY_31_MS); ++ write_aes2501_register(dev, AES2501_REG_COLSCAN, AES2501_COLSCAN_SRATE_128_US); ++ write_aes2501_register(dev, AES2501_REG_MEASDRV, AES2501_MEASDRV_MDRIVE_0_325 | AES2501_MEASDRV_MEASURE_SQUARE); ++ write_aes2501_register(dev, AES2501_REG_MEASFREQ, AES2501_MEASFREQ_2M); ++ write_aes2501_register(dev, AES2501_REG_DEMODPHASE1, DEMODPHASE_NONE);/* Default */ ++ write_aes2501_register(dev, AES2501_REG_DEMODPHASE2, DEMODPHASE_NONE); ++ write_aes2501_register(dev, AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE2_4X | AES2501_CHANGAIN_STAGE1_16X); ++ write_aes2501_register(dev, AES2501_REG_ADREFHI, 0x44); ++ write_aes2501_register(dev, AES2501_REG_ADREFLO, 0x34); ++ write_aes2501_register(dev, AES2501_REG_STRTCOL, 0x16); ++ write_aes2501_register(dev, AES2501_REG_ENDCOL, 0x16); ++ write_aes2501_register(dev, AES2501_REG_DATFMT, AES2501_DATFMT_BIN_IMG | 0x08);/* ??? */ ++ write_aes2501_register(dev, AES2501_REG_TREG1, 0x70);/* Reserved + 0xXX */ ++ write_aes2501_register(dev, 0xa2, 0x02);/* Reserved */ ++ write_aes2501_register(dev, 0xa7, 0x00);/* Reserved */ ++ write_aes2501_register(dev, AES2501_REG_TREGC, AES2501_TREGC_ENABLE); ++ write_aes2501_register(dev, AES2501_REG_TREGD, 0x1a); ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE); ++ write_aes2501_register(dev, AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT); ++ write_aes2501_register(dev, AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE); ++ ++ ++ flush_aes2501_bulk_out(dev); ++ ++ recv_data_to_aes2501(dev, buffer, 20); ++ ++ ++ ++ //send_data_to_aes2501(dev, cmd_04, 4); ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ ++ /* Part 2 */ ++ ++ printk(KERN_INFO " -- part 2 --\n"); ++ ++ //msleep(100); ++ ++ //send_data_to_aes2501(dev, cmd2, 12); ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_AUTOCALOFFSET, 0x41); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x42);/* ??? */ ++ write_aes2501_register(dev, AES2501_REG_DETCTRL, 0x53);/* Cumul ??? */ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE); ++ write_aes2501_register(dev, AES2501_REG_CTRL2, AES2501_CTRL2_READ_REGS); ++ ++ ++ ++ ++ flush_aes2501_bulk_out(dev); ++ ++ ++ recv_data_to_aes2501(dev, buffer, 126); ++ ++ /* Part 3 */ ++ ++ printk(KERN_INFO " -- part 3 --\n"); ++ ++ i = 0; ++ ++ printk(KERN_INFO " reg 0xaf = 0x%x\n", buffer[0x5f]); ++ while (buffer[0x5f] == 0x6b) ++ { ++ //msleep(200); ++ ++ ++ //send_data_to_aes2501(dev, cmd3_00, 2); ++ write_aes2501_register(dev, 0xff, 0x00);/* Reserved */ ++ ++ //msleep(80); ++ ++ //send_data_to_aes2501(dev, cmd3_01, 12); ++ ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_AUTOCALOFFSET, 0x41); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x42);/* ??? */ ++ write_aes2501_register(dev, AES2501_REG_DETCTRL, 0x53);/* Cumul ??? */ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE); ++ write_aes2501_register(dev, AES2501_REG_CTRL2, AES2501_CTRL2_READ_REGS); ++ ++ flush_aes2501_bulk_out(dev); ++ ++ ++ ++ ++ recv_data_to_aes2501(dev, buffer, 126); ++ ++ printk(KERN_INFO " +reg 0xaf = 0x%x\n", buffer[0x5f]); ++ ++ if (++i == 13) break; ++ ++ } ++ ++ ++ ++ ++ ++ /* Part 4 */ ++ ++ printk(KERN_INFO " -- part 4 --\n"); ++ ++ //send_data_to_aes2501(dev, cmd4, 14); ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ write_aes2501_register(dev, 0xb0, 0x27);/* Reserved */ ++ write_aes2501_register(dev, AES2501_REG_ENDROW, 0x0a); ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE); ++ write_aes2501_register(dev, AES2501_REG_DETCTRL, 0x45);/* ???? */ ++ write_aes2501_register(dev, AES2501_REG_AUTOCALOFFSET, 0x41); ++ ++ ++ ++ ++ ++ ++ /* ... */ ++ ++ ++/* ++ for (i = 0; i < 126; i += 10) ++ { ++ printk(KERN_INFO " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", ++ buffer[i + 0], buffer[i + 1], buffer[i + 2], buffer[i + 3], buffer[i + 4], ++ buffer[i + 5], buffer[i + 6], buffer[i + 7], buffer[i + 8], buffer[i + 9]); ++ ++ if (i % 20 == 0) ++ printk(KERN_INFO "\n "); ++ ++ } ++ ++ printk(KERN_INFO "\n"); ++*/ ++ ++ ++ ++ /* Part 5 */ ++ ++ printk(KERN_INFO " -- part 5 --\n"); ++ ++ //send_data_to_aes2501(dev, cmd5_00, 2); ++ ++ write_aes2501_register(dev, 0xb0, 0x27);/* Reserved */ ++ ++ //send_data_to_aes2501(dev, cmd5_01, 4); ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ ++ //msleep(200); ++ ++ ++ //send_data_to_aes2501(dev, cmd5_02, 2); ++ //send_data_to_aes2501(dev, cmd5_01, 4); ++ //send_data_to_aes2501(dev, cmd5_01, 4); ++ ++ write_aes2501_register(dev, 0xff, 0x00);/* Reserved */ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ ++ ++ ++ //msleep(50); ++ ++ //send_data_to_aes2501(dev, cmd5_01, 4); ++ //send_data_to_aes2501(dev, cmd5_01, 4); ++ //send_data_to_aes2501(dev, cmd5_01, 4); ++ //send_data_to_aes2501(dev, cmd5_03, 2); ++ //send_data_to_aes2501(dev, cmd5_03, 2); ++ //send_data_to_aes2501(dev, cmd5_04, 2); ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* ??? */ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_SCAN_RESET); ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_SCAN_RESET); ++ write_aes2501_register(dev, AES2501_REG_CTRL2, AES2501_CTRL2_READ_REGS); ++ flush_aes2501_bulk_out(dev); ++ ++ ++ recv_data_to_aes2501(dev, buffer, 126); ++ ++ ++ ++ ++ ++ return 0; ++ ++} ++ ++static int detect_finger_on_aes2501(struct usb_aes2501 *dev) ++{ ++ //uint8_t cmd1[] = "\x80\x01\x82\x40"; ++ //uint8_t cmd2[] = "\x80\x01\x82\x40\x83\x00\x88\x02\x89\x10\x8a\x05\x8c\x00\x8e\x13\x91\x44\x92\x34\x95\x16\x96\x16\x97\x18\xa1\x70\xa2\x02\xa7\x00\xac\x01\xad\x1a\x80\x04\x81\x04\xb4\x00";/*42*/ ++ ++ ++ unsigned char buffer[22]; ++ unsigned i, sum; ++ ++ //send_data_to_aes2501(dev, cmd1, 4); ++ ++ //msleep(30); ++ ++ ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* Reserved */ ++ write_aes2501_register(dev, AES2501_REG_DETCTRL, AES2501_DETCTRL_DRATE_CONTINUOUS | AES2501_DETCTRL_SDELAY_31_MS); ++ write_aes2501_register(dev, AES2501_REG_COLSCAN, AES2501_COLSCAN_SRATE_128_US);/* not the faster ??? */ ++ write_aes2501_register(dev, AES2501_REG_MEASDRV, AES2501_MEASDRV_MDRIVE_0_325 | AES2501_MEASDRV_MEASURE_SQUARE); ++ write_aes2501_register(dev, AES2501_REG_MEASFREQ, AES2501_MEASFREQ_2M); ++ write_aes2501_register(dev, AES2501_REG_DEMODPHASE1, DEMODPHASE_NONE);/* Default */ ++ write_aes2501_register(dev, AES2501_REG_DEMODPHASE2, DEMODPHASE_NONE); ++ write_aes2501_register(dev, AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE2_4X | AES2501_CHANGAIN_STAGE1_16X); ++ write_aes2501_register(dev, AES2501_REG_ADREFHI, 0x44); ++ write_aes2501_register(dev, AES2501_REG_ADREFLO, 0x34); ++ write_aes2501_register(dev, AES2501_REG_STRTCOL, 0x16); ++ write_aes2501_register(dev, AES2501_REG_ENDCOL, 0x16); ++ write_aes2501_register(dev, AES2501_REG_DATFMT, AES2501_DATFMT_BIN_IMG | 0x08); ++ write_aes2501_register(dev, AES2501_REG_TREG1, 0x70);/* Reserved + 0xXX */ ++ write_aes2501_register(dev, 0xa2, 0x02);/* Reserved */ ++ write_aes2501_register(dev, 0xa7, 0x00);/* Reserved */ ++ write_aes2501_register(dev, AES2501_REG_TREGC, AES2501_TREGC_ENABLE); ++ write_aes2501_register(dev, AES2501_REG_TREGD, 0x1a); ++ ++ flush_aes2501_bulk_out(dev); ++ ++ /** ++ * TODO: ++ * - lire ici les deux octets. ++ * - voir pour inverser les commandes. ++ */ ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE); ++ write_aes2501_register(dev, AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT); ++ write_aes2501_register(dev, AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE); ++ ++ flush_aes2501_bulk_out(dev); ++ ++ ++ //send_data_to_aes2501(dev, cmd2, 42); ++ ++ recv_data_to_aes2501(dev, buffer, 20); ++ ++ ++ /* One column is returned here but I don't know which one. ++ Maybe an average over the whole sensor area. */ ++ sum = 0; ++ for (i = 1; i != 9; i++) { ++ sum += (buffer[i] & 0xf) + (buffer[i] >> 4); ++ } ++ ++ ++ //printk(KERN_INFO "===finger=== sum = %d vs %d\n", sum, 20); ++ ++ ++ /* ++ return (sum > aes->fingerTh1); ++ */ ++ ++ return sum > 20; ++ ++} ++ ++ ++static unsigned read_fingerprint_on_aes2501(struct usb_aes2501 *dev, void *raw_, unsigned maxstrip) ++{ ++ //unsigned char patch_msg[] = "\x80\x01"; ++ ++ /* 8e xx = set gain */ ++ //uint8_t cmd1_00[] = "0x80\x01\x82\x40"; ++ //uint8_t cmd1_01[] = "0x80\x01\x82\x40\x83\x00\x88\x02\x8c\x7c\x89\x10\x8d\x24\x9b\x00\x9c\x6c\x9d\x09\x9e\x54\x9f\x78\xa2\x02\xa7\x00\xb6\x26\xb7\x1a\x80\x04\x98\x23\x95\x10\x96\x1f\x8e\x00\x91\x70\x92\x20\x81\x04\xb4\x00";/*50*/ ++ ++ //uint8_t cmd2[] = "\x98\x23\x95\x10\x96\x1f\x8e\x03\x91\x70\x92\x20\x81\x04";/*14*/ ++ ++ //uint8_t cmd3[] = "\x98\x22\x95\x00\x96\x2f\x8e\x03\x91\x5b\x92\x20\x81\x04";/*14*/ ++ ++ uint8_t buf[1705]; ++ uint8_t *raw = (uint8_t *) raw_; ++ unsigned nstrips; ++ ++ int threshold; ++ int sum; ++ ++ ++ //send_data_to_aes2501(dev, patch_msg, 2); ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ flush_aes2501_bulk_out(dev); ++ ++ ++ ++ //send_data_to_aes2501(dev, cmd1_00, 4); ++ ++ ++ //send_data_to_aes2501(dev, cmd1_01, 50); ++ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_MASTER_RESET); ++ write_aes2501_register(dev, AES2501_REG_EXCITCTRL, 0x40);/* Reserved */ ++ write_aes2501_register(dev, AES2501_REG_DETCTRL, AES2501_DETCTRL_SDELAY_31_MS | AES2501_DETCTRL_DRATE_CONTINUOUS); ++ write_aes2501_register(dev, AES2501_REG_COLSCAN, AES2501_COLSCAN_SRATE_128_US); ++ write_aes2501_register(dev, AES2501_REG_DEMODPHASE2, 0x7c);/* ... */ ++ write_aes2501_register(dev, AES2501_REG_MEASDRV, AES2501_MEASDRV_MEASURE_SQUARE | AES2501_MEASDRV_MDRIVE_0_325); ++ write_aes2501_register(dev, AES2501_REG_DEMODPHASE1, 0x24);/* ... */ ++ write_aes2501_register(dev, AES2501_REG_CHWORD1, 0x00);/* Challenge Word */ ++ write_aes2501_register(dev, AES2501_REG_CHWORD2, 0x6c);/* Challenge Word */ ++ write_aes2501_register(dev, AES2501_REG_CHWORD3, 0x09);/* Challenge Word */ ++ write_aes2501_register(dev, AES2501_REG_CHWORD4, 0x54);/* Challenge Word */ ++ write_aes2501_register(dev, AES2501_REG_CHWORD5, 0x78);/* Challenge Word */ ++ write_aes2501_register(dev, 0xa2, 0x02);/* Reserved */ ++ write_aes2501_register(dev, 0xa7, 0x00);/* Reserved */ ++ write_aes2501_register(dev, 0xb6, 0x26);/* Reserved */ ++ write_aes2501_register(dev, 0xb7, 0x1a);/* Reserved */ ++ write_aes2501_register(dev, AES2501_REG_CTRL1, AES2501_CTRL1_REG_UPDATE); ++ write_aes2501_register(dev, AES2501_REG_IMAGCTRL, AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE | AES2501_IMAGCTRL_IMG_DATA_DISABLE); ++ write_aes2501_register(dev, AES2501_REG_STRTCOL, 0x10); ++ write_aes2501_register(dev, AES2501_REG_ENDCOL, 0x1f); ++ write_aes2501_register(dev, AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE1_2X | AES2501_CHANGAIN_STAGE2_2X); ++ write_aes2501_register(dev, AES2501_REG_ADREFHI, 0x70); ++ write_aes2501_register(dev, AES2501_REG_ADREFLO, 0x20); ++ write_aes2501_register(dev, AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT); ++ write_aes2501_register(dev, AES2501_REG_LPONT, AES2501_LPONT_MIN_VALUE); ++ ++ ///////recv_data_to_aes2501(dev, buf, 159); ++ /* TODO: calibration e.g setting gain (0x8e xx) */ ++ ++ ++ ++ ++ //send_data_to_aes2501(dev, cmd2, 14); ++ ++ ++ ++ write_aes2501_register(dev, AES2501_REG_IMAGCTRL, AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE | AES2501_IMAGCTRL_IMG_DATA_DISABLE); ++ write_aes2501_register(dev, AES2501_REG_STRTCOL, 0x10); ++ write_aes2501_register(dev, AES2501_REG_ENDCOL, 0x1f); ++ write_aes2501_register(dev, AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE1_16X); ++ write_aes2501_register(dev, AES2501_REG_ADREFHI, 0x70); ++ write_aes2501_register(dev, AES2501_REG_ADREFLO, 0x20); ++ write_aes2501_register(dev, AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT); ++ ++ flush_aes2501_bulk_out(dev); ++ ++ ++ recv_data_to_aes2501(dev, buf, 159); ++ ++ nstrips = 0; ++ do { ++ printk(KERN_INFO "-start-\n"); ++ /* Timing in this loop is critical. It decides how fast you can move your finger. ++ If one loop takes tl second, the maximum speed is: ++ (16/500 * 25.4) / tl [mm per sec] ++ */ ++ //send_data_to_aes2501(dev, cmd3, 14); ++ ++ write_aes2501_register(dev, AES2501_REG_IMAGCTRL, AES2501_IMAGCTRL_TST_REG_ENABLE | AES2501_IMAGCTRL_HISTO_DATA_ENABLE); ++ write_aes2501_register(dev, AES2501_REG_STRTCOL, 0x00); ++ write_aes2501_register(dev, AES2501_REG_ENDCOL, 0x2f); ++ write_aes2501_register(dev, AES2501_REG_CHANGAIN, AES2501_CHANGAIN_STAGE1_16X); ++ write_aes2501_register(dev, AES2501_REG_ADREFHI, 0x5b); ++ write_aes2501_register(dev, AES2501_REG_ADREFLO, 0x20); ++ write_aes2501_register(dev, AES2501_REG_CTRL2, AES2501_CTRL2_SET_ONE_SHOT); ++ ++ flush_aes2501_bulk_out(dev); ++ ++ ++ ++ recv_data_to_aes2501(dev, buf, 1705); ++ memcpy(raw, buf+1, 192*8); ++ raw += 192*8; ++ ++ printk(KERN_INFO "-end of copy-\n"); ++ ++ ++ threshold = read_register_value((buf + 1 + 192*8 + 1 + 16*2 + 1 + 8), _AES2501_REG_DATFMT); ++ /*if (threshold < 0) ++ return threshold;*/ ++ ++ threshold &= 0x0f; ++ ++ sum = sum_histogram_values((buf + 1 + 192*8), threshold); ++ /*if (threshold < 0) ++ return threshold;*/ ++ ++ nstrips++; ++ printk(KERN_INFO "-end- %d vs %d\n", nstrips, maxstrip); ++ } while (sum > 0 && nstrips < maxstrip); ++ printk(KERN_INFO "nstrips = %u\n", nstrips); ++ if (nstrips == maxstrip) ++ printk(KERN_INFO "nstrips == %u, swiping the finger too slowly?\n", maxstrip); ++ return nstrips; ++} ++ ++ ++ ++/** ++ * Read a register value from a dump sent by the device. ++ * @data: list of couples . ++ * @target: index of the register to process. ++ * @return: -EILSEQ,-EINVAL if error, value > 0 if a finger is here. ++ */ ++int read_register_value(const uint8_t *data, Aes2501Registers target) ++{ ++ int result; ++ uint8_t offset; ++ ++ if (*data == FIRST_AES2501_REG) ++ { ++ offset = target; ++ ++ if (!(FIRST_AES2501_REG <= offset && offset <= LAST_AES2501_REG)) ++ result = -EINVAL; ++ ++ else ++ { ++ offset -= FIRST_AES2501_REG; ++ offset *= 2; ++ ++ result = data[++offset]; ++ ++ } ++ ++ } ++ else result = -EILSEQ; ++ ++ return result; ++ ++} ++ ++ ++/** ++ * Tells if a finger motion is still detected. ++ * @data: start point of data to handle, preceded by 0xde. ++ * @threshold: index of values set to 1 by the device. ++ * @return: -EILSEQ,-EINVAL if error, value > 0 if a finger is here. ++ * ++ * Histograms always are a 16-uint16_t long message, where ++ * histogram[i] = number of pixels of value i. ++ */ ++int sum_histogram_values(const uint8_t *data, uint8_t threshold) ++{ ++ int result; ++ uint16_t *histogram; ++ uint8_t i; ++ ++ if (*data == 0xde) ++ { ++ if (threshold > 0x0f) ++ result = -EINVAL; ++ ++ else ++ { ++ result = 0; ++ histogram = (uint16_t *)(data + 1); ++ ++ for (i = threshold; i < 16; i++) ++ result += histogram[i]; ++ ++ } ++ ++ } ++ else result = -EILSEQ; ++ ++ return result; ++ ++} ++ ++ ++ ++/********************************************************** ++ ** Image processing ++ **********************************************************/ ++ ++/* This function finds overlapping parts of two frames ++ * Based on calculating normalized hamming distance ++ * between two frames ++ */ ++ ++static unsigned find_overlap(const uint8_t *first_frame, ++ const uint8_t *second_frame, ++ uint32_t frame_height, ++ uint32_t frame_width, ++ uint32_t *min_error) ++{ ++ uint32_t dy, i; ++ uint32_t error, not_overlapped_height = 0; ++ *min_error = 255 * frame_height * frame_width; ++ for (dy = 0; dy < frame_height; dy++) { ++ /* Calculating difference (error) between parts of frames */ ++ error = 0; ++ for (i = 0; i < frame_width * (frame_height - dy); i++) { ++ /* Using ? operator to avoid abs function */ ++ error += first_frame[i] > second_frame[i] ? ++ (first_frame[i] - second_frame[i]) : ++ (second_frame[i] - first_frame[i]); ++ } ++ ++ /* Normalizing error */ ++ error *= 15; ++ error /= i; ++ if (error < *min_error) { ++ *min_error = error; ++ not_overlapped_height = dy; ++ } ++ first_frame += frame_width; ++ } ++ ++ return not_overlapped_height; ++} ++ ++ ++/* This function assembles frames to single image, returns image height ++ * TODO: add Doxygen comments ++ */ ++static unsigned assemble(const uint8_t *input, /* Raw data received from device */ ++ uint8_t *output, /* Output buffer */ ++ uint32_t frame_height, /* Height of each frame */ ++ uint32_t frame_width, /* Width of each frame */ ++ uint32_t frames_count, /* Frames count */ ++ /*int overlap, */ ++ uint8_t reversed, ++ uint32_t *errors_sum ++ ) ++{ ++ uint8_t *assembled = output; ++ uint32_t frame, column, row, image_height = frame_height; ++ uint32_t error, not_overlapped; ++ ++ *errors_sum = 0; ++ ++ if (frames_count < 1) return 0; ++ ++ /* Rotating given data by 90 degrees ++ * Taken from document describing aes2501 image format ++ * TODO: move reversing detection here */ ++ if (reversed) { ++ output += (frames_count - 1) * frame_width * frame_height; ++ } ++ ++ for (frame = 0; frame < frames_count; frame++) { ++ for (column = 0; column < frame_width; column++) { ++ for (row = 0; row < (frame_height / 2); row++) { ++ output[frame_width * ( 2 * row) + column] = *input & 0x0F; ++ output[frame_width * ( 2 * row + 1) + column] = *input >> 4; ++ input++; ++ } ++ } ++ ++ if (reversed) { ++ output -= frame_width * frame_height; ++ } ++ else { ++ output += frame_width * frame_height; ++ } ++ } ++ ++ /* Detecting where frames overlaped */ ++ output = assembled; ++ for (frame = 1; frame < frames_count; frame++) ++ { ++ output += frame_width * frame_height; ++ not_overlapped = find_overlap(assembled, output, frame_height, frame_width, &error); ++ *errors_sum += error; ++ image_height += not_overlapped; ++ assembled += frame_width * not_overlapped; ++ memcpy(assembled, output, frame_width * frame_height); ++ } ++ ++ return image_height; ++} ++ ++ ++ ++static void store_new_aes2501_pnm(const uint8_t *data, unsigned int width, unsigned int height) ++{ ++ char header[20]; ++ __kernel_size_t header_len; ++ int i; ++ char *iter; ++ ++ sprintf(header, "P5\n%u %u\n255\n", width, height); ++ header_len = strlen(header); ++ ++ finger_print_len = header_len + width * height; ++ finger_print = kzalloc(finger_print_len, GFP_KERNEL); ++ ++ memcpy(finger_print, header, header_len); ++ ++ for (i = 0, iter = &finger_print[header_len]; i < width * height; i++, iter++) ++ *iter = (data[i] << 4) + 0x0f; ++ ++} ++ ++ ++ ++static void do_scanning(struct work_struct *work) ++{ ++ struct usb_aes2501 *dev; ++ ++ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ ++ ++ uint8_t *raw, *cooked; ++ unsigned swidth = 192; ++ unsigned sheight = 16; ++ unsigned maxstrip = 150; ++ unsigned nstrips, height, mindiff_sum, mindiff_sum_r; ++ ++ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ ++ ++ dev = container_of(work, struct usb_aes2501, scan_work); ++ ++ ++ ++ ++ ++ ++ setup_aes2501(dev); ++ ++ while (!detect_finger_on_aes2501(dev)) ++ { ++ if (dev->stop_scan) ++ { ++ PRINTK_INFO("aborting scan due to module removal\n"); ++ return; ++ } ++ }; ++ ++ /* We don't need physical continuity of allocated memory */ ++ raw = (uint8_t *)vmalloc((3 * maxstrip * sheight * swidth) / 2); ++ if (raw == NULL) ++ { ++ PRINTK_CRIT("failed to allocate memory\n"); ++ return; ++ } ++ ++ cooked = raw + (maxstrip * sheight * swidth)/2; ++ ++ ++ ++ printk(KERN_INFO "Raw is 0x%p\n", raw); ++ ++ ++ printk(KERN_INFO "Scanning...\n"); ++ nstrips = read_fingerprint_on_aes2501(dev, raw, maxstrip); ++ ++ printk(KERN_INFO "Assembling...\n"); ++ ++ ++ height = assemble(raw, cooked, 16, 192, nstrips, 0, &mindiff_sum); ++ height = assemble(raw, cooked, 16, 192, nstrips, 1, &mindiff_sum_r); ++ ++ ++ printk(KERN_INFO "Mindiff normal: %d, mindiff reversed: %d\n", mindiff_sum, mindiff_sum_r); ++ ++ if (mindiff_sum_r < mindiff_sum) ++ { ++ PRINTK_INFO("reversed image detected\n"); ++ } ++ else ++ { ++ height = assemble(raw, cooked, 16, 192, nstrips, 0, &mindiff_sum); ++ } ++ ++ printk(KERN_INFO "First height :: %d\n", height); ++ ++#if 0 ++ if (height < 100) { ++ /* It was a "touch", not a finger scan. */ ++ printk(KERN_INFO "Was only a 'touch' ;( [%d]\n", height); ++ /*break;*/ ++ } ++ else ++ ++ { ++ //store_new_aes2501_pnm(cooked, swidth, height); ++ height = assemble(raw, cooked, nstrips, 1, sensor_reversed); ++ printk(KERN_INFO "Second height :: %d\n", height); ++ store_new_aes2501_pnm(cooked, swidth, height); ++ } ++#endif ++ store_new_aes2501_pnm(cooked, swidth, height); ++ standby_aes2501(dev); ++ ++ vfree(raw); ++ ++ flag = 1; ++ wake_up_interruptible(&wq); ++ ++ ++} ++ ++ ++static int aes2501_open(struct inode *inode, struct file *file) ++{ ++ struct usb_aes2501 *dev; ++ ++ //return 0; ++ ++ ++ dev = _dev; ++ ++ printk(KERN_INFO "Plop !\n"); ++ ++ ++ return 0; ++} ++ ++ ++ ++ ++ ++ ++/* ++ * usb class driver info in order to get a minor number from the usb core, ++ * and to have the device registered with the driver core ++ */ ++static struct usb_class_driver aes2501_class = { ++ .name = "aes2501%d", ++ .fops = &aes2501_fops, ++ .minor_base = USB_AES2501_MINOR_BASE, ++}; ++ ++static int aes2501_probe(struct usb_interface *interface, const struct usb_device_id *id) ++{ ++ int retval; ++ struct usb_aes2501 *dev; ++ struct usb_host_interface *iface_desc; ++ __u8 i; ++ struct usb_endpoint_descriptor *endpoint; ++ __u16 buffer_size; ++ ++ ++ ++#if 0 ++ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ ++ ++ uint8_t *raw, *cooked; ++ unsigned swidth = 192; ++ unsigned sheight = 16; ++ unsigned maxstrip = 150; ++ unsigned nstrips, height; ++ ++ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ ++ ++ ++ raw = (uint8_t *)__get_free_page(GFP_KERNEL);//kmalloc((3 * maxstrip * sheight * swidth) / 2, GFP_KERNEL); ++ cooked = raw + (maxstrip * sheight * swidth)/2; ++#endif ++ ++ printk(KERN_INFO "aes2501 probe !\n"); ++ ++ ++ retval = -ENOMEM; ++ ++ /* Allocate memory for our device state and initialize it */ ++ ++ dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ if (dev == NULL) ++ { ++ PRINTK_CRIT("out of memory\n"); ++ goto error; ++ } ++ ++ _dev = dev; ++ ++ dev->stop_scan = 0; ++ ++ kref_init(&dev->kref); ++ sema_init(&dev->limit_sem, WRITES_IN_FLIGHT); ++ mutex_init(&dev->io_mutex); ++ ++ dev->udev = usb_get_dev(interface_to_usbdev(interface)); ++ dev->interface = interface; ++ ++ printk(KERN_INFO "num_altsetting == %d\n", interface->num_altsetting); ++ ++ /** ++ * Set up the endpoint information. ++ * Use only the first bulk-in and bulk-out endpoints. ++ */ ++ ++ iface_desc = interface->cur_altsetting; ++ ++ printk(KERN_INFO "BULK COUNT %d\n", iface_desc->desc.bNumEndpoints); ++ ++ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) ++ { ++ endpoint = &iface_desc->endpoint[i].desc; ++ ++ if (!dev->bulk_in_endpointAddr && /*usb_endpoint_is_bulk_in(endpoint))*/ ++ ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ++ == USB_DIR_IN) && ++ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ++ == USB_ENDPOINT_XFER_BULK)) ++ { ++ /* We found a bulk in endpoint */ ++ buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); ++ dev->bulk_in_size = buffer_size; ++ dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; ++ dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); ++ ++ printk(KERN_INFO "BULK IN %d ; size = %d\n", i, buffer_size); ++ ++ if (dev->bulk_in_buffer == NULL) ++ { ++ PRINTK_CRIT("could not allocate bulk_in_buffer\n"); ++ goto error; ++ } ++ ++ } ++ ++ if (!dev->bulk_out_endpointAddr && /*usb_endpoint_is_bulk_out(endpoint))*/ ++ ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ++ == USB_DIR_OUT) && ++ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ++ == USB_ENDPOINT_XFER_BULK)) ++ { ++ printk(KERN_INFO "BULK OUT %d\n", i); ++ ++ /* We found a bulk out endpoint */ ++ dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; ++ } ++ ++ } ++ ++ if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) ++ { ++ PRINTK_CRIT("could not find both bulk-in and bulk-out endpoints\n"); ++ goto error; ++ } ++ ++/* ++ dev->once_tasklet = kzalloc(sizeof(*dev->once_tasklet), GFP_KERNEL); ++ if (dev->once_tasklet == NULL) ++ { ++ PRINTK_CRIT("out of memory\n"); ++ goto error; ++ } ++*/ ++ /* Save our data pointer in this interface device */ ++ usb_set_intfdata(interface, dev); ++ ++ /* We can register the device now, as it is ready */ ++ retval = usb_register_dev(interface, &aes2501_class); ++ if (retval) { ++ /* something prevented us from registering this driver */ ++ PRINTK_CRIT("not able to get a minor for this device\n"); ++ usb_set_intfdata(interface, NULL); ++ goto error; ++ } ++ ++ /* Let the user know what node this device is now attached to */ ++ PRINTK_INFO("device now attached to aes2501-%d\n", interface->minor); ++ ++#if 0 ++ setup_aes2501(dev); ++ ++ while (!detect_finger_on_aes2501(dev)); ++ ++ ++ printk(KERN_INFO "Raw is 0x%p\n", raw); ++ ++ ++ printk(KERN_INFO "Scanning...\n"); ++ nstrips = read_fingerprint_on_aes2501(dev, raw, maxstrip); ++ ++ printk(KERN_INFO "Assembling...\n"); ++ ++ height = assemble(raw, cooked, nstrips, 1); ++ if (height < 100) { ++ /* It was a "touch", not a finger scan. */ ++ printk(KERN_INFO "Was only a 'touch' ;(\n"); ++ /*break;*/ ++ } ++ else ++ { ++ store_new_aes2501_pnm(cooked, swidth, height); ++ height = assemble(raw, cooked, nstrips, 0); ++ store_new_aes2501_pnm(cooked, swidth, height); ++ } ++ ++ standby_aes2501(dev); ++#endif ++ ++ return 0; ++ ++error: ++ if (dev != NULL) ++ kref_put(&dev->kref, aes2501_delete); ++ ++ return retval; ++ ++} ++ ++ ++static void aes2501_disconnect(struct usb_interface *interface) ++{ ++ int minor; ++ struct usb_aes2501 *dev; ++ ++ minor = interface->minor; ++ ++ /* Prevent aes2501_open() from racing aes2501_disconnect() */ ++ lock_kernel(); ++ ++ dev = usb_get_intfdata(interface); ++ usb_set_intfdata(interface, NULL); ++ ++ /* Give back our minor */ ++ usb_deregister_dev(interface, &aes2501_class); ++ ++ /* Prevent more I/O from starting */ ++ mutex_lock(&dev->io_mutex); ++ dev->interface = NULL; ++ mutex_unlock(&dev->io_mutex); ++ ++ unlock_kernel(); ++ ++ /* Decrement our usage count */ ++ kref_put(&dev->kref, aes2501_delete); ++ ++ PRINTK_INFO("aes2501 device #%d now disconnected\n", minor); ++ ++ ++ ++ ++ printk(KERN_INFO "aes2501 disconnect !\n"); ++ ++ ++} ++ ++ ++static struct usb_driver aes2501_driver = { ++ .name = "aes2501", ++ .probe = aes2501_probe, ++ .disconnect = aes2501_disconnect, ++ .id_table = id_table, ++}; ++ ++ ++static int __init aes2501_init(void) ++{ ++ int retval; ++ ++ comm_queue = create_singlethread_workqueue("aes2501"); ++ if (comm_queue == NULL) { ++ PRINTK_CRIT("could not create work queue\n"); ++ return -ENOMEM; ++ } ++ ++ retval = usb_register(&aes2501_driver); ++ if (retval == -EINVAL) ++ { ++ printk(KERN_ERR "usb_register failed. Error number %d\n", retval); ++ destroy_workqueue(comm_queue); ++ return retval; ++ } ++ ++ return 0; ++ ++} ++ ++static void __exit aes2501_exit(void) ++{ ++ _dev->stop_scan = 1; ++ destroy_workqueue(comm_queue); ++ usb_deregister(&aes2501_driver); ++} ++ ++module_init(aes2501_init); ++module_exit(aes2501_exit); ++ ++MODULE_AUTHOR("Cyrille Bagard"); ++MODULE_DESCRIPTION("AES 2501 fingerprint scanner driver"); ++MODULE_LICENSE("GPL"); +diff -Nurp linux-2.6.37/3rdparty/aes2501/aes2501.h linux-2.6.37.3rdparty/3rdparty/aes2501/aes2501.h +--- linux-2.6.37/3rdparty/aes2501/aes2501.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/aes2501/aes2501.h 2008-01-14 03:07:30.000000000 +0200 +@@ -0,0 +1,40 @@ ++ ++/* ++ * aes2501.h -- AuthenTec AES2501 Fingerprint Sensor Driver for Linux ++ * ++ * Maintainer: Cyrille Bagard ++ * ++ * Copyright (C) 2007 Cyrille Bagard ++ * ++ * This file is part of the AES2501 driver. ++ * ++ * the AES2501 driver is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * the AES2501 driver is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with the AES2501 driver; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++ ++#ifndef __AES2501_H ++#define __AES2501_H ++ ++ ++#define AES2501_IOC_MAGIC 'N' ++ ++ ++#define AES2501_IOC_TEST _IOW(AES2501_IOC_MAGIC, 1, int) ++ ++ ++ ++ ++#endif /* __AES2501_H */ +diff -Nurp linux-2.6.37/3rdparty/aes2501/aes2501_regs.h linux-2.6.37.3rdparty/3rdparty/aes2501/aes2501_regs.h +--- linux-2.6.37/3rdparty/aes2501/aes2501_regs.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/aes2501/aes2501_regs.h 2008-01-14 03:07:30.000000000 +0200 +@@ -0,0 +1,464 @@ ++ ++/* ++ * aes2501_regs.h -- AuthenTec AES2501 Fingerprint Sensor Driver for Linux ++ * ++ * Maintainer: Cyrille Bagard ++ * ++ * Copyright (C) 2007 Cyrille Bagard ++ * ++ * This file is part of the AES2501 driver. ++ * ++ * the AES2501 driver is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * the AES2501 driver is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with the AES2501 driver; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++ ++#ifndef __AES2501_REGS_H ++#define __AES2501_REGS_H ++ ++ ++ ++/* ++ * AES2501 Control Register 1 (CTRL1) ++ */ ++ ++#define AES2501_REG_CTRL1 0x80 ++ ++#define AES2501_CTRL1_MASTER_RESET 0x01 /* Master reset, same as Power On Reset */ ++#define AES2501_CTRL1_SCAN_RESET 0x02 /* Scan reset: stop and restart the scan sequencer */ ++#define AES2501_CTRL1_REG_UPDATE 0x04 /* 1 = continuously updated, 0 = updated prior to starting a scan */ ++ ++ ++/* ++ * AES2501 Control Register 2 (CTRL2) ++ */ ++ ++#define AES2501_REG_CTRL2 0x81 ++ ++#define AES2501_CTRL2_CONTINUOUS 0x01 /* 1 = continuous scans, 0 = single scans */ ++#define AES2501_CTRL2_READ_REGS 0x02 /* Read the current state of the local registers in the Sensor IC */ ++#define AES2501_CTRL2_SET_ONE_SHOT 0x04 /* Set the one-shot flip-flop */ ++#define AES2501_CTRL2_CLR_ONE_SHOT 0x08 /* Clear the one-shot flip-flop */ ++#define AES2501_CTRL2_READ_ID 0x10 /* Read the ID register of the chip */ ++ ++ ++/* ++ * AES2501 Excitation Common Control Register (EXCITCTRL) ++ */ ++ ++#define AES2501_REG_EXCITCTRL 0x82 ++ ++#define AES2501_EXCITCTRL_LO_PWR 0x01 /* If set, enable detection in sleep/suspend mode */ ++#define AES2501_EXCITCTRL_AUTO_CAL 0x02 /* If set, perform finger detection calibration */ ++#define AES2501_EXCITCTRL_SGC_ENABLE 0x04 /* ??? */ ++#define AES2501_EXCITCTRL_SGC_RESTART 0x08 /* ??? */ ++ ++#define AES2501_EXCITCTRL_EXCIT_SQR 0x20 /* Select the (1=square | 0=sine) wave finger drive signal */ ++#define AES2501_EXCITCTRL_EXCIT_BOOST 0x10 /* TODO: understand this part */ ++ ++ ++/* ++ * AES2501 Detect Control Register (DETCTRL) ++ */ ++ ++#define AES2501_REG_DETCTRL 0x83 ++ ++enum aes2501_detection_rate { ++ ++ AES2501_DETCTRL_DRATE_CONTINUOUS = 0x00, /* Detection cycles occur continuously */ ++ AES2501_DETCTRL_DRATE_16_MS = 0x01, /* Detection cycles occur every 16.62 ms */ ++ AES2501_DETCTRL_DRATE_31_MS = 0x02, /* Detection cycles occur every 31.24 ms */ ++ AES2501_DETCTRL_DRATE_62_MS = 0x03, /* Detection cycles occur every 62.50 ms */ ++ AES2501_DETCTRL_DRATE_125_MS = 0x04, /* Detection cycles occur every 125.0 ms */ ++ AES2501_DETCTRL_DRATE_250_MS = 0x05, /* Detection cycles occur every 250.0 ms */ ++ AES2501_DETCTRL_DRATE_500_MS = 0x06, /* Detection cycles occur every 500.0 ms */ ++ AES2501_DETCTRL_DRATE_1_S = 0x07 /* Detection cycles occur every 1 s */ ++ ++}; ++ ++enum aes2501_settling_delay { ++ ++ AES2501_DETCTRL_SDELAY_31_MS = 0x00, /* 31.25 ms */ ++ AES2501_DETCTRL_SSDELAY_62_MS = 0x10, /* 62.5 ms */ ++ AES2501_DETCTRL_SSDELAY_125_MS = 0x20, /* 125 ms */ ++ AES2501_DETCTRL_SSDELAY_250_MS = 0x30 /* 250 ms */ ++ ++}; ++ ++ ++ ++ ++ ++/* ++ * AES2501 Column Scan Rate Register (COLSCAN) ++ */ ++ ++#define AES2501_REG_COLSCAN 0x88 ++ ++enum aes2501_col_scan_rate { ++ ++ AES2501_COLSCAN_SRATE_32_US = 0x00, /* 32 us */ ++ AES2501_COLSCAN_SRATE_64_US = 0x01, /* 64 us */ ++ AES2501_COLSCAN_SRATE_128_US = 0x02, /* 128 us */ ++ AES2501_COLSCAN_SRATE_256_US = 0x03, /* 256 us */ ++ AES2501_COLSCAN_SRATE_512_US = 0x04, /* 512 us */ ++ AES2501_COLSCAN_SRATE_1024_US = 0x05, /* 1024 us */ ++ AES2501_COLSCAN_SRATE_2048_US = 0x06, /* 2048 us */ ++ ++}; ++ ++ ++/* ++ * AES2501 Measure Drive Register (MEASDRV) ++ */ ++ ++#define AES2501_REG_MEASDRV 0x89 ++ ++enum aes2501_mesure_drive { ++ ++ AES2501_MEASDRV_MDRIVE_0_325 = 0x00, /* 0.325 Vpp */ ++ AES2501_MEASDRV_MDRIVE_0_65 = 0x01, /* 0.65 Vpp */ ++ AES2501_MEASDRV_MDRIVE_1_3 = 0x02, /* 1.3 Vpp */ ++ AES2501_MEASDRV_MDRIVE_2_6 = 0x03 /* 2.6 Vpp */ ++ ++}; ++ ++#define AES2501_MEASDRV_SQUARE 0x20 /* Select (1=square | 0=sine) wave drive during measure */ ++#define AES2501_MEASDRV_MEASURE_SQUARE 0x10 /* 0 = use mesure drive setting, 1 = when sine wave is selected */ ++ ++ ++/* ++ * AES2501 Measure Frequency Register (MEASFREQ) ++ */ ++ ++#define AES2501_REG_MEASFREQ 0x8a ++ ++enum aes2501_measure_freq { ++ ++ AES2501_MEASFREQ_125K = 0x01, /* 125 kHz */ ++ AES2501_MEASFREQ_250K = 0x02, /* 250 kHz */ ++ AES2501_MEASFREQ_500K = 0x03, /* 500 kHz */ ++ AES2501_MEASFREQ_1M = 0x04, /* 1 MHz */ ++ AES2501_MEASFREQ_2M = 0x05 /* 2 MHz */ ++ ++}; ++ ++ ++ ++ ++/* ++ * AES2501 Demod Phase 2 Register (DEMODPHASE2) ++ */ ++ ++#define AES2501_REG_DEMODPHASE2 0x8c ++ ++#define DEMODPHASE_NONE 0x00 ++ ++#define DEMODPHASE_180_00 0x40 /* 180 degrees */ ++#define DEMODPHASE_2_81 0x01 /* 2.8125 degrees */ ++ ++ ++/* ++ * AES2501 Demod Phase 1 Register (DEMODPHASE1) ++ */ ++ ++#define AES2501_REG_DEMODPHASE1 0x8d ++ ++#define DEMODPHASE_1_40 0x40 /* 1.40625 degrees */ ++#define DEMODPHASE_0_02 0x01 /* 0.02197256 degrees */ ++ ++ ++/* ++ * AES2501 Channel Gain Register (CHANGAIN) ++ */ ++ ++#define AES2501_REG_CHANGAIN 0x8e ++ ++enum aes2501_sensor_gain1 { ++ ++ AES2501_CHANGAIN_STAGE1_2X = 0x00, /* 2x */ ++ AES2501_CHANGAIN_STAGE1_4X = 0x01, /* 4x */ ++ AES2501_CHANGAIN_STAGE1_8X = 0x02, /* 8x */ ++ AES2501_CHANGAIN_STAGE1_16X = 0x03 /* 16x */ ++ ++}; ++ ++enum aes2501_sensor_gain2 { ++ ++ AES2501_CHANGAIN_STAGE2_2X = 0x00, /* 2x */ ++ AES2501_CHANGAIN_STAGE2_4X = 0x10, /* 4x */ ++ AES2501_CHANGAIN_STAGE2_8X = 0x20, /* 8x */ ++ AES2501_CHANGAIN_STAGE2_16X = 0x30 /* 16x */ ++ ++}; ++ ++ ++ ++/* ++ * AES2501 A/D Reference High Register (ADREFHI) ++ */ ++ ++#define AES2501_REG_ADREFHI 0x91 ++ ++ ++/* ++ * AES2501 A/D Reference Low Register (ADREFLO) ++ */ ++ ++#define AES2501_REG_ADREFLO 0x92 ++ ++ ++/* ++ * AES2501 Start Row Register (STRTROW) ++ */ ++ ++#define AES2501_REG_STRTROW 0x93 ++ ++ ++/* ++ * AES2501 End Row Register (ENDROW) ++ */ ++ ++#define AES2501_REG_ENDROW 0x94 ++ ++ ++/* ++ * AES2501 Start Column Register (STRTCOL) ++ */ ++ ++#define AES2501_REG_STRTCOL 0x95 ++ ++ ++/* ++ * AES2501 End Column Register (ENDCOL) ++ */ ++ ++#define AES2501_REG_ENDCOL 0x96 ++ ++ ++/* ++ * AES2501 Data Format Register (DATFMT) ++ */ ++ ++#define AES2501_REG_DATFMT 0x97 ++ ++#define AES2501_DATFMT_EIGHT 0x40 /* 1 = 8-bit data, 0 = 4-bit data */ ++#define AES2501_DATFMT_LOW_RES 0x20 /* TODO: understand this part */ ++#define AES2501_DATFMT_BIN_IMG 0x10 /* TODO: understand this part */ ++ ++/* TODO: Threshold */ ++ ++ ++/* ++ * AES2501 Image Data Control Register (IMAGCTRL) ++ */ ++ ++#define AES2501_REG_IMAGCTRL 0x98 ++ ++#define AES2501_IMAGCTRL_IMG_DATA_DISABLE 0x01 /* If set, image data message and authentication message are not returned when imaging */ ++#define AES2501_IMAGCTRL_HISTO_DATA_ENABLE 0x02 /* if set, send histogram message when imaging */ ++#define AES2501_IMAGCTRL_HISTO_EACH_ROW 0x04 /* A histo message is sent at the end of (1=each row | 0 = scanning) */ ++#define AES2501_IMAGCTRL_HISTO_FULL_ARRAY 0x08 /* 1 = full image array, 0 = 64x64 center */ ++#define AES2501_IMAGCTRL_REG_FIRST 0x10 /* Registers are returned (1=before | 0=after) image data */ ++#define AES2501_IMAGCTRL_TST_REG_ENABLE 0x20 /* If set, Test Registers are returned with register messages */ ++ ++ ++ ++ ++ ++ ++ ++ ++/* ++ * AES2501 Status Register (STAT) ++ */ ++ ++#define AES2501_REG_STAT 0x9a ++ ++#define AES2501_STAT_SCAN 0x0f /* Scan state */ ++#define AES2501_STAT_ERROR 0x10 /* Framing error */ ++#define AES2501_STAT_PAUSED 0x20 /* Scan paused */ ++#define AES2501_STAT_RESET 0x40 /* Reset occurred */ ++ ++enum aes2501_scan_state { ++ ++ STATE_WAITING_FOR_FINGER = 0x00, /* Waiting for finger */ ++ STATE_FINGER_SETTLING_DELAY = 0x01, /* In Finger settling delay */ ++ STATE_POWER_UP_DELAY = 0x02, /* In power up delay */ ++ STATE_WAITING_TO_START_SCAN = 0x03, /* Waiting to start image scan */ ++ STATE_PRELOADING_SUBARRAY_0 = 0x04, /* Pre-loading subarray 0 */ ++ STATE_SETUP_FOR_ROW_ADVANCE = 0x05, /* Setup for row advance */ ++ STATE_WAITING_FOR_ROW_ADVANCE = 0x06, /* Waiting for row advance */ ++ STATE_PRELOADING_COL_0 = 0x07, /* Pre-loading column 0 */ ++ STATE_SETUP_FOR_COL_ADVANCE = 0x08, /* Setup for column advance */ ++ STATE_WAITING_FOR_COL_ADVANCE = 0x09, /* Waiting for column advance */ ++ STATE_WAITING_FOR_SCAN_START = 0x0a, /* Waiting for scan start */ ++ STATE_WAITING_FOR_SCAN_END = 0x0b, /* Waiting for scan end */ ++ STATE_WAITING_FOR_ROW_SETUP = 0x0c, /* Waiting for row setup */ ++ STATE_WAITING_FOR_COL_TIME = 0x0d, /* Waiting for one column time (depends on scan rate) */ ++ STATE_WAITING_FOR_QUEUED_DATA = 0x0e, /* Waiting for queued data transmission to be completed */ ++ STATE_WAIT_FOR_128_US = 0x0f /* Wait for 128 us */ ++ ++}; ++ ++ ++/* ++ * AES2501 Challenge Word 1 Register (CHWORD1) ++ */ ++ ++#define AES2501_REG_CHWORD1 0x9b ++ ++#define AES2501_CHWORD1_IS_FINGER 0x01 /* If set, finger is present */ ++ ++ ++/* ++ * AES2501 Challenge Word 2 Register (CHWORD2) ++ */ ++ ++#define AES2501_REG_CHWORD2 0x9c ++ ++ ++/* ++ * AES2501 Challenge Word 3 Register (CHWORD3) ++ */ ++ ++#define AES2501_REG_CHWORD3 0x9d ++ ++ ++/* ++ * AES2501 Challenge Word 4 Register (CHWORD4) ++ */ ++ ++#define AES2501_REG_CHWORD4 0x9e ++ ++ ++/* ++ * AES2501 Challenge Word 5 Register (CHWORD5) ++ */ ++ ++#define AES2501_REG_CHWORD5 0x9f ++ ++ ++ ++ ++ ++/* ++ * AES2501 Test Register 1 (TREG1) ++ */ ++ ++#define AES2501_REG_TREG1 0xa1 ++ ++#define AES2501_TREG1_SBIAS_UNLCK 0x10 /* 1 = unlock the controlling of sense amp bias, 0 = sense amp bias changes */ ++ ++enum aes2501_sense_amp_bias { ++ ++ AES2501_TREG1_SAMP_BIAS_2_UA = 0x00, /* 2.5 uA */ ++ AES2501_TREG1_SAMP_BIAS_5_UA = 0x01, /* 5 uA */ ++ AES2501_TREG1_SAMP_BIAS_8_UA = 0x02, /* 8 uA */ ++ AES2501_TREG1_SAMP_BIAS_10_UA = 0x03 /* 10 uA */ ++ ++}; ++ ++ ++ ++ ++/* ++ * AES2501 Auto-Calibration Offset Register (AUTOCALOFFSET) ++ */ ++ ++#define AES2501_REG_AUTOCALOFFSET 0xa8 ++ ++ ++ ++ ++ ++/* ++ * AES2501 Test Register C (TREGC) ++ */ ++ ++#define AES2501_REG_TREGC 0xac ++ ++#define AES2501_TREGC_ENABLE 0x01 /* Enable the reading of the register in TREGD */ ++ ++ ++/* ++ * AES2501 Test Register D (TREGD) ++ */ ++ ++#define AES2501_REG_TREGD 0xad ++ ++ ++ ++ ++ ++/* ++ * AES2501 Low Power Oscillator On Time Register (LPONT) ++ */ ++ ++#define AES2501_REG_LPONT 0xb4 ++ ++/* ++ * This register sets the low power oscillator on time. ++ * Units are roughly equivalent to milliseconds. ++ */ ++ ++#define AES2501_LPONT_MIN_VALUE 0x00 /* 0 ms */ ++#define AES2501_LPONT_MAX_VALUE 0x1f /* About 16 ms */ ++ ++ ++ ++#define ENUM_REG(reg) _ ## reg = reg ++ ++typedef enum _Aes2501Registers ++{ ++ ENUM_REG(AES2501_REG_CTRL1), ++ ENUM_REG(AES2501_REG_CTRL2), ++ ENUM_REG(AES2501_REG_EXCITCTRL), ++ ENUM_REG(AES2501_REG_DETCTRL), ++ ENUM_REG(AES2501_REG_COLSCAN), ++ ENUM_REG(AES2501_REG_MEASDRV), ++ ENUM_REG(AES2501_REG_MEASFREQ), ++ ENUM_REG(AES2501_REG_DEMODPHASE2), ++ ENUM_REG(AES2501_REG_DEMODPHASE1), ++ ENUM_REG(AES2501_REG_CHANGAIN), ++ ENUM_REG(AES2501_REG_ADREFHI), ++ ENUM_REG(AES2501_REG_ADREFLO), ++ ENUM_REG(AES2501_REG_STRTROW), ++ ENUM_REG(AES2501_REG_ENDROW), ++ ENUM_REG(AES2501_REG_STRTCOL), ++ ENUM_REG(AES2501_REG_ENDCOL), ++ ENUM_REG(AES2501_REG_DATFMT), ++ ENUM_REG(AES2501_REG_IMAGCTRL), ++ ENUM_REG(AES2501_REG_STAT), ++ ENUM_REG(AES2501_REG_CHWORD1), ++ ENUM_REG(AES2501_REG_CHWORD2), ++ ENUM_REG(AES2501_REG_CHWORD3), ++ ENUM_REG(AES2501_REG_CHWORD4), ++ ENUM_REG(AES2501_REG_CHWORD5), ++ ENUM_REG(AES2501_REG_TREG1), ++ ENUM_REG(AES2501_REG_AUTOCALOFFSET), ++ ENUM_REG(AES2501_REG_TREGC), ++ ENUM_REG(AES2501_REG_TREGD), ++ ENUM_REG(AES2501_REG_LPONT) ++ ++} Aes2501Registers; ++ ++ ++#define FIRST_AES2501_REG 0x80 ++#define LAST_AES2501_REG 0x9f ++ ++ ++ ++#endif /* __AES2501_REGS_H */ +diff -Nurp linux-2.6.37/3rdparty/aes2501/ChangeLog linux-2.6.37.3rdparty/3rdparty/aes2501/ChangeLog +--- linux-2.6.37/3rdparty/aes2501/ChangeLog 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/aes2501/ChangeLog 2008-01-14 03:07:30.000000000 +0200 +@@ -0,0 +1,95 @@ ++2007-11-05 Cyrille Bagard ++ ++ * aes2501.c: ++ Apply Vasily Khoruzhick's new patch: rewrite image processing functions. ++ Thus, there should be no more significant common points with aes2501-wy. ++ ++2007-11-05 Cyrille Bagard ++ ++ * aes2501.c: ++ In order to respect the license of aes2501-wy, on which this driver is ++ based, begin to rewrite some functions. Thus, better handle histograms. ++ One more strip is often processed, but that is more logical like this. ++ ++ * aes2501_regs.h: ++ Enumerate all used registers for convenience. ++ ++2007-11-03 Cyrille Bagard ++ ++ * aes2501.c: ++ Clean the code. Take care of signals when processes are awaking. ++ Apply Vasily Khoruzhick's new patch: autodetect picture reversing needs ++ and fix kernel oops in case of module removal. ++ ++ * Makefile: ++ Remove hidden files and clean the rules. KERNELDIR has to be overrided ++ from the sheel if needed now. ++ ++2007-10-29 Cyrille Bagard ++ ++ * aes2501.c: ++ Apply Vasily Khoruzhick's patch and thus increase the resulting pictures ++ quality. Many thanks to him ! ++ ++ * Makefile: ++ Add two new rules: usertest and clean. ++ ++ * usertest.c: ++ Initial commit. ++ ++2007-08-27 Cyrille Bagard ++ ++ * aes2501.c: ++ Make INIT_WORK macro working with 2.6.20+ kernels. Many thanks to ++ Miguel Gea Milvaques for the patch ! ++ ++2007-06-13 Cyrille Bagard ++ ++ * aes2501.c: ++ * aes2501_regs.h: ++ Complete translation of all binary communications using well documented ++ registers and values (as often as possible). ++ ++2007-06-13 Cyrille Bagard ++ ++ * aes2501.c: ++ Increase communication speed by buffering bulk out. Output data ++ need to be flushed at the end now. ++ ++2007-06-13 Cyrille Bagard ++ ++ * aes2501.c: ++ * aes2501_regs.h: ++ Translate binary data used in finger detection. Some register values ++ still need to be understood. Note: some hex values are reserved bits ++ in registers. ++ ++2007-06-12 Cyrille Bagard ++ ++ * aes2501.c: ++ Begin the binary translation: the "standby" function now uses understood ++ instructions and prints debug status information if needed. CTRL2 register ++ value needs to be checked. ++ ++ * aes2501_regs.h: ++ Define the interesting hex values for the following registers: ++ CTRL2, STAT, TREGC and TREGD. ++ ++2007-06-12 Cyrille Bagard ++ ++ * aes2501.c: ++ Clean the driver a little bit by removing old piece of code to handle ++ a character device in the old way. ++ ++2007-06-12 Cyrille Bagard ++ ++ * aes2501.c: ++ Use an own work queue. Scanning now starts with the AES2501_IOC_TEST ++ ioctl command. Reading the /dev entry blocks until data is available. ++ ++2007-06-12 Cyrille Bagard ++ ++ * aes2501.c: ++ * aes2501.h: ++ * Makefile: ++ Initial [crappy] commit. +diff -Nurp linux-2.6.37/3rdparty/aes2501/Makefile linux-2.6.37.3rdparty/3rdparty/aes2501/Makefile +--- linux-2.6.37/3rdparty/aes2501/Makefile 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/aes2501/Makefile 2008-01-14 03:07:30.000000000 +0200 +@@ -0,0 +1,19 @@ ++ ++obj-m := aes2501.o ++ ++KERNELDIR ?= /lib/modules/$(shell uname -r)/build ++ ++PWD := $(shell pwd) ++ ++all: usertest ++ $(MAKE) -C $(KERNELDIR) M=$(PWD) ++ ++usertest: ++ gcc -I. -o usertest usertest.c ++ ++clean: ++ rm -f *.o *~ aes2501.ko aes2501.mod.c Module.symvers usertest ++ rm -rf .tmp_versions ++ rm -f .*.cmd ++ ++ +diff -Nurp linux-2.6.37/3rdparty/aes2501/usertest.c linux-2.6.37.3rdparty/3rdparty/aes2501/usertest.c +--- linux-2.6.37/3rdparty/aes2501/usertest.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/aes2501/usertest.c 2008-01-14 03:07:30.000000000 +0200 +@@ -0,0 +1,78 @@ ++/** ++ * AES2501 Device Driver ++ * Userspace test program ++ * ++ * Compile with: ++ * gcc -I. -o usertest usertest.c ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define BUFFER_SIZE 256 ++ ++ ++int main(int argc, char *argv[]) ++{ ++ int fd_in; ++ int fd_out; ++ char buffer[BUFFER_SIZE]; ++ size_t len; ++ ++ fd_in = -1; ++ fd_out = -1; ++ ++ ++ int data, rdata; ++ ++ ++ ++ fd_in = open("/dev/aes2501", O_RDONLY); ++ if (fd_in == -1) { ++ perror("open() -- "); ++ goto err; ++ } ++ ++ fd_out = open("/root/pic.pnm", O_CREAT | O_WRONLY); ++ if (fd_out == -1) { ++ perror("open() -- "); ++ goto err; ++ } ++ ++ ++ ++ data = 0x55555555; ++ ioctl(fd_in, AES2501_IOC_TEST, data); ++ //ioctl(fd_in, CASE2, &rdata); ++ ++ printf("IOCTL test: written: '%x' - received: '%x'\n", data, rdata); ++ ++ ++ ++ ++ /* Write the fingerprint */ ++ while ((len = read(fd_in, buffer, BUFFER_SIZE)) > 0) ++ write(fd_out, buffer, len); ++ ++ close(fd_in); ++ close(fd_out); ++ ++ return EXIT_SUCCESS; ++ ++ err: ++ ++ if (fd_in != -1) ++ close(fd_in); ++ ++ if (fd_out != -1) ++ close(fd_out); ++ ++ return EXIT_FAILURE; ++ ++} diff --git a/kernel/kernel/files/patches/mageia/3rd-aes2501-rmmod-oops-fix.patch b/kernel/kernel/files/patches/mageia/3rd-aes2501-rmmod-oops-fix.patch new file mode 100644 index 00000000..f11cc2e5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-aes2501-rmmod-oops-fix.patch @@ -0,0 +1,21 @@ +Prevent oops on module removal when we don't have the device available. + +Signed-off-by: Herton Ronaldo Krzesinski + +--- + linux-2.6.23/3rdparty/aes2501/aes2501.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff -p -up linux-2.6.23/3rdparty/aes2501/aes2501.c.orig linux-2.6.23/3rdparty/aes2501/aes2501.c +--- linux-2.6.23/3rdparty/aes2501/aes2501.c.orig 2008-01-13 23:37:38.000000000 -0200 ++++ linux-2.6.23/3rdparty/aes2501/aes2501.c 2008-01-13 23:38:26.000000000 -0200 +@@ -1616,7 +1616,8 @@ static int __init aes2501_init(void) + + static void __exit aes2501_exit(void) + { +- _dev->stop_scan = 1; ++ if (_dev) ++ _dev->stop_scan = 1; + destroy_workqueue(comm_queue); + usb_deregister(&aes2501_driver); + } diff --git a/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-1.59.patch b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-1.59.patch new file mode 100644 index 00000000..63ccc093 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-1.59.patch @@ -0,0 +1,26399 @@ +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/crt.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/crt.c +--- linux-3.12.2/3rdparty/ndiswrapper/crt.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/crt.c 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,589 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ntoskernel.h" ++#include "crt_exports.h" ++ ++#ifdef CONFIG_X86_64 ++/* Windows long is 32-bit, so strip single 'l' in integer formats */ ++static void strip_l_modifier(char *str) ++{ ++ char *ptr = str; ++ int in_format = 0; ++ char *lptr = NULL; ++ char last = 0; ++ char *end_ptr; ++ char *wptr; ++ ++ /* Replace single 'l' inside integer formats with '\0' */ ++ for (ptr = str; *ptr; ptr++) { ++ if (!in_format) { ++ if (*ptr == '%') ++ in_format = 1; ++ last = *ptr; ++ continue; ++ } ++ switch (*ptr) { ++ case 'd': ++ case 'i': ++ case 'o': ++ case 'u': ++ case 'x': ++ case 'X': ++ case 'p': ++ case 'n': ++ case 'm': ++ if (lptr) { ++ *lptr = '\0'; ++ lptr = NULL; ++ } ++ in_format = 0; ++ break; ++ case 'c': ++ case 'C': ++ case 's': ++ case 'S': ++ case 'f': ++ case 'e': ++ case 'E': ++ case 'g': ++ case 'G': ++ case 'a': ++ case 'A': ++ lptr = NULL; ++ in_format = 0; ++ break; ++ case '%': ++ lptr = NULL; ++ if (last == '%') ++ in_format = 0; ++ else ++ in_format = 1; /* ignore previous junk */ ++ break; ++ case 'l': ++ if (last == 'l') ++ lptr = NULL; ++ else ++ lptr = ptr; ++ break; ++ default: ++ break; ++ } ++ last = *ptr; ++ } ++ ++ /* Purge zeroes from the resulting string */ ++ end_ptr = ptr; ++ wptr = str; ++ for (ptr = str; ptr < end_ptr; ptr++) ++ if (*ptr != 0) ++ *(wptr++) = *ptr; ++ *wptr = 0; ++} ++ ++/* ++ * va_list on x86_64 Linux is designed to allow passing arguments in registers ++ * even to variadic functions. va_list is a structure holding pointers to the ++ * register save area, which holds the arguments passed in registers, and to ++ * the stack, which may have the arguments that did not fit the registers. ++ * va_list also holds offsets in the register save area for the next general ++ * purpose and floating point registers that the next va_arg() would fetch. ++ * ++ * Unlike Linux, the Windows va_list is just a pointer to the stack. No ++ * arguments are passed in the registers. That's why we construct the Linux ++ * va_list so that the register save area is never used. For that goal, we set ++ * the offsets to the maximal allowed values, meaning that the arguments passed ++ * in the registers have been exhausted. The values are 48 for general purpose ++ * registers (6 registers, 8 bytes each) and 304 for floating point registers ++ * (16 registers, 16 bytes each, on top of general purpose register). ++ */ ++ ++struct x86_64_va_list { ++ int gp_offset; ++ int fp_offset; ++ void *overflow_arg_area; ++ void *reg_save_area; ++}; ++ ++#define VA_LIST_DECL(_args) \ ++ va_list _args##new; \ ++ struct x86_64_va_list *_args##x; ++#define VA_LIST_PREP(_args) \ ++do { \ ++ _args##x = (struct x86_64_va_list *)&_args##new; \ ++ _args##x->gp_offset = 6 * 8; /* GP registers exhausted */ \ ++ _args##x->fp_offset = 6 * 8 + 16 * 16; /* FP registers exhausted */ \ ++ _args##x->overflow_arg_area = (void *)_args; \ ++ _args##x->reg_save_area = NULL; \ ++} while (0) ++#define VA_LIST_CONV(_args) (_args##new) ++#define VA_LIST_FREE(_args) ++#define FMT_DECL(_fmt) \ ++ char *_fmt##copy; \ ++ int _fmt##len; ++#define FMT_PREP(_fmt) \ ++do { \ ++ _fmt##len = strlen(format) + 1; \ ++ _fmt##copy = kmalloc(_fmt##len, irql_gfp()); \ ++ if (_fmt##copy) { \ ++ memcpy(_fmt##copy, format, _fmt##len); \ ++ strip_l_modifier(_fmt##copy); \ ++ } \ ++} while (0) ++#define FMT_CONV(_fmt) (_fmt##copy ? _fmt##copy : format) ++#define FMT_FREE(_fmt) kfree(_fmt##copy) ++ ++#else /* !CONFIG_X86_64 */ ++ ++#define VA_LIST_DECL(_args) ++#define VA_LIST_PREP(_args) ++#define VA_LIST_CONV(_args) (_args) ++#define VA_LIST_FREE(_args) ++#define FMT_DECL(_fmt) ++#define FMT_PREP(_fmt) ++#define FMT_CONV(_fmt) (format) ++#define FMT_FREE(_fmt) ++ ++#endif /* !CONFIG_X86_64 */ ++ ++__attribute__((format(printf, 2, 3))) ++noregparm INT WIN_FUNC(_win_sprintf,12) ++ (char *buf, const char *format, ...) ++{ ++ va_list args; ++ int res; ++ FMT_DECL(format) ++ ++ FMT_PREP(format); ++ va_start(args, format); ++ res = vsprintf(buf, FMT_CONV(format), args); ++ va_end(args); ++ FMT_FREE(format); ++ ++ TRACE2("buf: %p: %s", buf, buf); ++ return res; ++} ++ ++noregparm INT WIN_FUNC(swprintf,12) ++ (wchar_t *buf, const wchar_t *format, ...) ++{ ++ TODO(); ++ EXIT2(return 0); ++} ++ ++noregparm INT WIN_FUNC(_win_vsprintf,3) ++ (char *str, const char *format, va_list ap) ++{ ++ INT i; ++ VA_LIST_DECL(ap) ++ FMT_DECL(format) ++ ++ VA_LIST_PREP(ap); ++ FMT_PREP(format); ++ ++ i = vsprintf(str, FMT_CONV(format), VA_LIST_CONV(ap)); ++ TRACE2("str: %p: %s", str, str); ++ ++ FMT_FREE(format); ++ VA_LIST_FREE(ap); ++ EXIT2(return i); ++} ++ ++__attribute__((format(printf, 3, 4))) ++noregparm INT WIN_FUNC(_win_snprintf,12) ++ (char *buf, SIZE_T count, const char *format, ...) ++{ ++ va_list args; ++ int res; ++ FMT_DECL(format) ++ ++ FMT_PREP(format); ++ va_start(args, format); ++ res = vsnprintf(buf, count, FMT_CONV(format), args); ++ va_end(args); ++ TRACE2("buf: %p: %s", buf, buf); ++ ++ FMT_FREE(format); ++ return res; ++} ++ ++__attribute__((format(printf, 3, 4))) ++noregparm INT WIN_FUNC(_win__snprintf,12) ++ (char *buf, SIZE_T count, const char *format, ...) ++{ ++ va_list args; ++ int res; ++ FMT_DECL(format) ++ ++ FMT_PREP(format); ++ va_start(args, format); ++ res = vsnprintf(buf, count, FMT_CONV(format), args); ++ va_end(args); ++ TRACE2("buf: %p: %s", buf, buf); ++ ++ FMT_FREE(format); ++ return res; ++} ++ ++noregparm INT WIN_FUNC(_win_vsnprintf,4) ++ (char *str, SIZE_T size, const char *format, va_list ap) ++{ ++ INT i; ++ VA_LIST_DECL(ap) ++ FMT_DECL(format) ++ ++ VA_LIST_PREP(ap); ++ FMT_PREP(format); ++ ++ i = vsnprintf(str, size, FMT_CONV(format), VA_LIST_CONV(ap)); ++ TRACE2("str: %p: %s", str, str); ++ ++ FMT_FREE(format); ++ VA_LIST_FREE(ap); ++ EXIT2(return i); ++} ++ ++noregparm INT WIN_FUNC(_win__vsnprintf,4) ++ (char *str, SIZE_T size, const char *format, va_list ap) ++{ ++ INT i; ++ VA_LIST_DECL(ap) ++ FMT_DECL(format) ++ ++ VA_LIST_PREP(ap); ++ FMT_PREP(format); ++ ++ i = vsnprintf(str, size, FMT_CONV(format), VA_LIST_CONV(ap)); ++ TRACE2("str: %p: %s", str, str); ++ ++ FMT_FREE(format); ++ VA_LIST_FREE(ap); ++ EXIT2(return i); ++} ++ ++noregparm INT WIN_FUNC(_win__vsnwprintf,4) ++ (wchar_t *str, SIZE_T size, const wchar_t *format, va_list ap) ++{ ++ int ret; ++ ++ TODO(); /* format expansion not implemented */ ++ _win_wcsncpy(str, format, size); ++ ret = _win_wcslen(format); ++ if (ret >= size) ++ ret = -1; ++ return ret; ++} ++ ++noregparm char *WIN_FUNC(_win_strncpy,3) ++ (char *dst, char *src, SIZE_T n) ++{ ++ return strncpy(dst, src, n); ++} ++ ++noregparm SIZE_T WIN_FUNC(_win_strlen,1) ++ (const char *s) ++{ ++ return strlen(s); ++} ++ ++noregparm INT WIN_FUNC(_win_strncmp,3) ++ (const char *s1, const char *s2, SIZE_T n) ++{ ++ return strncmp(s1, s2, n); ++} ++ ++noregparm INT WIN_FUNC(_win_strcmp,2) ++ (const char *s1, const char *s2) ++{ ++ return strcmp(s1, s2); ++} ++ ++noregparm INT WIN_FUNC(_win_stricmp,2) ++ (const char *s1, const char *s2) ++{ ++ return stricmp(s1, s2); ++} ++ ++noregparm char *WIN_FUNC(_win_strncat,3) ++ (char *dest, const char *src, SIZE_T n) ++{ ++ return strncat(dest, src, n); ++} ++ ++noregparm INT WIN_FUNC(_win_wcscmp,2) ++ (const wchar_t *s1, const wchar_t *s2) ++{ ++ while (*s1 && *s1 == *s2) { ++ s1++; ++ s2++; ++ } ++ return *s1 - *s2; ++} ++ ++noregparm INT WIN_FUNC(_win_wcsicmp,2) ++ (const wchar_t *s1, const wchar_t *s2) ++{ ++ while (*s1 && tolower((char)*s1) == tolower((char)*s2)) { ++ s1++; ++ s2++; ++ } ++ return tolower((char)*s1) - tolower((char)*s2); ++} ++ ++noregparm SIZE_T WIN_FUNC(_win_wcslen,1) ++ (const wchar_t *s) ++{ ++ const wchar_t *t = s; ++ while (*t) ++ t++; ++ return t - s; ++} ++ ++noregparm wchar_t *WIN_FUNC(_win_wcsncpy,3) ++ (wchar_t *dest, const wchar_t *src, SIZE_T n) ++{ ++ const wchar_t *s; ++ wchar_t *d; ++ s = src + n; ++ d = dest; ++ while (src < s && (*d++ = *src++)) ++ ; ++ if (s > src) ++ memset(d, 0, (s - src) * sizeof(wchar_t)); ++ return dest; ++} ++ ++noregparm wchar_t *WIN_FUNC(_win_wcscpy,2) ++ (wchar_t *dest, const wchar_t *src) ++{ ++ wchar_t *d = dest; ++ while ((*d++ = *src++)) ++ ; ++ return dest; ++} ++ ++noregparm wchar_t *WIN_FUNC(_win_wcscat,2) ++ (wchar_t *dest, const wchar_t *src) ++{ ++ wchar_t *d; ++ d = dest; ++ while (*d) ++ d++; ++ while ((*d++ = *src++)) ++ ; ++ return dest; ++} ++ ++noregparm INT WIN_FUNC(_win_towupper,1) ++ (wchar_t c) ++{ ++ return toupper(c); ++} ++ ++noregparm INT WIN_FUNC(_win_towlower,1) ++ (wchar_t c) ++{ ++ return tolower(c); ++} ++ ++noregparm INT WIN_FUNC(_win_tolower,1) ++ (INT c) ++{ ++ return tolower(c); ++} ++ ++noregparm INT WIN_FUNC(_win_toupper,1) ++ (INT c) ++{ ++ return toupper(c); ++} ++ ++noregparm void *WIN_FUNC(_win_strcpy,2) ++ (void *to, const void *from) ++{ ++ return strcpy(to, from); ++} ++ ++noregparm char *WIN_FUNC(_win_strstr,2) ++ (const char *s1, const char *s2) ++{ ++ return strstr(s1, s2); ++} ++ ++noregparm char *WIN_FUNC(_win_strchr,2) ++ (const char *s, int c) ++{ ++ return strchr(s, c); ++} ++ ++noregparm char *WIN_FUNC(_win_strrchr,2) ++ (const char *s, int c) ++{ ++ return strrchr(s, c); ++} ++ ++noregparm void *WIN_FUNC(_win_memmove,3) ++ (void *to, void *from, SIZE_T count) ++{ ++ return memmove(to, from, count); ++} ++ ++noregparm void *WIN_FUNC(_win_memchr,3) ++ (const void *s, INT c, SIZE_T n) ++{ ++ return memchr(s, c, n); ++} ++ ++noregparm void *WIN_FUNC(_win_memcpy,3) ++ (void *to, const void *from, SIZE_T n) ++{ ++ return memcpy(to, from, n); ++} ++ ++noregparm void *WIN_FUNC(_win_memset,3) ++ (void *s, char c, SIZE_T count) ++{ ++ return memset(s, c, count); ++} ++ ++noregparm int WIN_FUNC(_win_memcmp,3) ++ (void *s1, void *s2, SIZE_T n) ++{ ++ return memcmp(s1, s2, n); ++} ++ ++noregparm void WIN_FUNC(_win_srand,1) ++ (UINT seed) ++{ ++ net_srandom(seed); ++} ++ ++noregparm int WIN_FUNC(rand,0) ++ (void) ++{ ++ char buf[6]; ++ int i, n; ++ ++ get_random_bytes(buf, sizeof(buf)); ++ for (n = i = 0; i < sizeof(buf); i++) ++ n += buf[i]; ++ return n; ++} ++ ++noregparm int WIN_FUNC(_win_atoi,1) ++ (const char *ptr) ++{ ++ int i = simple_strtol(ptr, NULL, 10); ++ return i; ++} ++ ++noregparm int WIN_FUNC(_win_isdigit,1) ++ (int c) ++{ ++ return isdigit(c); ++} ++ ++noregparm int WIN_FUNC(_win_isprint,1) ++ (int c) ++{ ++ return isprint(c); ++} ++ ++wstdcall s64 WIN_FUNC(_alldiv,2) ++ (s64 a, s64 b) ++{ ++ return a / b; ++} ++ ++wstdcall u64 WIN_FUNC(_aulldiv,2) ++ (u64 a, u64 b) ++{ ++ return a / b; ++} ++ ++wstdcall s64 WIN_FUNC(_allmul,2) ++ (s64 a, s64 b) ++{ ++ return a * b; ++} ++ ++wstdcall u64 WIN_FUNC(_aullmul,2) ++ (u64 a, u64 b) ++{ ++ return a * b; ++} ++ ++wstdcall s64 WIN_FUNC(_allrem,2) ++ (s64 a, s64 b) ++{ ++ return a % b; ++} ++ ++wstdcall u64 WIN_FUNC(_aullrem,2) ++ (u64 a, u64 b) ++{ ++ return a % b; ++} ++ ++regparm3 s64 WIN_FUNC(_allshl,2) ++ (s64 a, u8 b) ++{ ++ return a << b; ++} ++ ++regparm3 u64 WIN_FUNC(_aullshl,2) ++ (u64 a, u8 b) ++{ ++ return a << b; ++} ++ ++regparm3 s64 WIN_FUNC(_allshr,2) ++ (s64 a, u8 b) ++{ ++ return a >> b; ++} ++ ++regparm3 u64 WIN_FUNC(_aullshr,2) ++ (u64 a, u8 b) ++{ ++ return a >> b; ++} ++ ++int stricmp(const char *s1, const char *s2) ++{ ++ while (*s1 && tolower(*s1) == tolower(*s2)) { ++ s1++; ++ s2++; ++ } ++ return *s1 - *s2; ++} ++ ++void dump_bytes(const char *ctx, const u8 *from, int len) ++{ ++ int i, j; ++ u8 *buf; ++ ++ buf = kmalloc(len * 3 + 1, irql_gfp()); ++ if (!buf) { ++ ERROR("couldn't allocate memory"); ++ return; ++ } ++ for (i = j = 0; i < len; i++, j += 3) { ++ sprintf(&buf[j], "%02x ", from[i]); ++ } ++ buf[j] = 0; ++ printk(KERN_DEBUG "%s: %p: %s\n", ctx, from, buf); ++ kfree(buf); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/divdi3.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/divdi3.c +--- linux-3.12.2/3rdparty/ndiswrapper/divdi3.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/divdi3.c 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,329 @@ ++/* 64-bit multiplication and division ++ Copyright (C) 1989, 1992-1999, 2000, 2001, 2002, 2003 ++ Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++#include ++#include ++ ++#if BITS_PER_LONG != 32 ++#error This is for 32-bit targets only ++#endif ++ ++typedef unsigned int UQItype __attribute__ ((mode (QI))); ++typedef int SItype __attribute__ ((mode (SI))); ++typedef unsigned int USItype __attribute__ ((mode (SI))); ++typedef int DItype __attribute__ ((mode (DI))); ++typedef unsigned int UDItype __attribute__ ((mode (DI))); ++#define Wtype SItype ++#define HWtype SItype ++#define DWtype DItype ++#define UWtype USItype ++#define UHWtype USItype ++#define UDWtype UDItype ++#define W_TYPE_SIZE 32 ++ ++#include "longlong.h" ++ ++#if defined(__BIG_ENDIAN) ++struct DWstruct { Wtype high, low;}; ++#elif defined(__LITTLE_ENDIAN) ++struct DWstruct { Wtype low, high;}; ++#else ++#error Unhandled endianity ++#endif ++typedef union { struct DWstruct s; DWtype ll; } DWunion; ++ ++/* Prototypes of exported functions. */ ++extern DWtype __divdi3 (DWtype u, DWtype v); ++extern DWtype __moddi3 (DWtype u, DWtype v); ++extern UDWtype __udivdi3 (UDWtype u, UDWtype v); ++extern UDWtype __umoddi3 (UDWtype u, UDWtype v); ++ ++static UDWtype ++__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) ++{ ++ DWunion ww; ++ DWunion nn, dd; ++ DWunion rr; ++ UWtype d0, d1, n0, n1, n2; ++ UWtype q0, q1; ++ UWtype b, bm; ++ ++ nn.ll = n; ++ dd.ll = d; ++ ++ d0 = dd.s.low; ++ d1 = dd.s.high; ++ n0 = nn.s.low; ++ n1 = nn.s.high; ++ ++#if !UDIV_NEEDS_NORMALIZATION ++ if (d1 == 0) ++ { ++ if (d0 > n1) ++ { ++ /* 0q = nn / 0D */ ++ ++ udiv_qrnnd (q0, n0, n1, n0, d0); ++ q1 = 0; ++ ++ /* Remainder in n0. */ ++ } ++ else ++ { ++ /* qq = NN / 0d */ ++ ++ if (d0 == 0) ++ d0 = 1 / d0; /* Divide intentionally by zero. */ ++ ++ udiv_qrnnd (q1, n1, 0, n1, d0); ++ udiv_qrnnd (q0, n0, n1, n0, d0); ++ ++ /* Remainder in n0. */ ++ } ++ ++ if (rp != NULL) ++ { ++ rr.s.low = n0; ++ rr.s.high = 0; ++ *rp = rr.ll; ++ } ++ } ++ ++#else /* UDIV_NEEDS_NORMALIZATION */ ++ ++ if (d1 == 0) ++ { ++ if (d0 > n1) ++ { ++ /* 0q = nn / 0D */ ++ ++ count_leading_zeros (bm, d0); ++ ++ if (bm != 0) ++ { ++ /* Normalize, i.e. make the most significant bit of the ++ denominator set. */ ++ ++ d0 = d0 << bm; ++ n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); ++ n0 = n0 << bm; ++ } ++ ++ udiv_qrnnd (q0, n0, n1, n0, d0); ++ q1 = 0; ++ ++ /* Remainder in n0 >> bm. */ ++ } ++ else ++ { ++ /* qq = NN / 0d */ ++ ++ if (d0 == 0) ++ d0 = 1 / d0; /* Divide intentionally by zero. */ ++ ++ count_leading_zeros (bm, d0); ++ ++ if (bm == 0) ++ { ++ /* From (n1 >= d0) /\ (the most significant bit of d0 is set), ++ conclude (the most significant bit of n1 is set) /\ (the ++ leading quotient digit q1 = 1). ++ ++ This special case is necessary, not an optimization. ++ (Shifts counts of W_TYPE_SIZE are undefined.) */ ++ ++ n1 -= d0; ++ q1 = 1; ++ } ++ else ++ { ++ /* Normalize. */ ++ ++ b = W_TYPE_SIZE - bm; ++ ++ d0 = d0 << bm; ++ n2 = n1 >> b; ++ n1 = (n1 << bm) | (n0 >> b); ++ n0 = n0 << bm; ++ ++ udiv_qrnnd (q1, n1, n2, n1, d0); ++ } ++ ++ /* n1 != d0... */ ++ ++ udiv_qrnnd (q0, n0, n1, n0, d0); ++ ++ /* Remainder in n0 >> bm. */ ++ } ++ ++ if (rp != NULL) ++ { ++ rr.s.low = n0 >> bm; ++ rr.s.high = 0; ++ *rp = rr.ll; ++ } ++ } ++#endif /* UDIV_NEEDS_NORMALIZATION */ ++ ++ else ++ { ++ if (d1 > n1) ++ { ++ /* 00 = nn / DD */ ++ ++ q0 = 0; ++ q1 = 0; ++ ++ /* Remainder in n1n0. */ ++ if (rp != NULL) ++ { ++ rr.s.low = n0; ++ rr.s.high = n1; ++ *rp = rr.ll; ++ } ++ } ++ else ++ { ++ /* 0q = NN / dd */ ++ ++ count_leading_zeros (bm, d1); ++ if (bm == 0) ++ { ++ /* From (n1 >= d1) /\ (the most significant bit of d1 is set), ++ conclude (the most significant bit of n1 is set) /\ (the ++ quotient digit q0 = 0 or 1). ++ ++ This special case is necessary, not an optimization. */ ++ ++ /* The condition on the next line takes advantage of that ++ n1 >= d1 (true due to program flow). */ ++ if (n1 > d1 || n0 >= d0) ++ { ++ q0 = 1; ++ sub_ddmmss (n1, n0, n1, n0, d1, d0); ++ } ++ else ++ q0 = 0; ++ ++ q1 = 0; ++ ++ if (rp != NULL) ++ { ++ rr.s.low = n0; ++ rr.s.high = n1; ++ *rp = rr.ll; ++ } ++ } ++ else ++ { ++ UWtype m1, m0; ++ /* Normalize. */ ++ ++ b = W_TYPE_SIZE - bm; ++ ++ d1 = (d1 << bm) | (d0 >> b); ++ d0 = d0 << bm; ++ n2 = n1 >> b; ++ n1 = (n1 << bm) | (n0 >> b); ++ n0 = n0 << bm; ++ ++ udiv_qrnnd (q0, n1, n2, n1, d1); ++ umul_ppmm (m1, m0, q0, d0); ++ ++ if (m1 > n1 || (m1 == n1 && m0 > n0)) ++ { ++ q0--; ++ sub_ddmmss (m1, m0, m1, m0, d1, d0); ++ } ++ ++ q1 = 0; ++ ++ /* Remainder in (n1n0 - m1m0) >> bm. */ ++ if (rp != NULL) ++ { ++ sub_ddmmss (n1, n0, n1, n0, m1, m0); ++ rr.s.low = (n1 << b) | (n0 >> bm); ++ rr.s.high = n1 >> bm; ++ *rp = rr.ll; ++ } ++ } ++ } ++ } ++ ++ ww.s.low = q0; ++ ww.s.high = q1; ++ return ww.ll; ++} ++ ++DWtype ++__divdi3 (DWtype u, DWtype v) ++{ ++ Wtype c = 0; ++ DWtype w; ++ ++ if (u < 0) ++ { ++ c = ~c; ++ u = -u; ++ } ++ if (v < 0) ++ { ++ c = ~c; ++ v = -v; ++ } ++ w = __udivmoddi4 (u, v, NULL); ++ if (c) ++ w = -w; ++ return w; ++} ++ ++DWtype ++__moddi3 (DWtype u, DWtype v) ++{ ++ Wtype c = 0; ++ DWtype w; ++ ++ if (u < 0) ++ { ++ c = ~c; ++ u = -u; ++ } ++ if (v < 0) ++ v = -v; ++ __udivmoddi4 (u, v, &w); ++ if (c) ++ w = -w; ++ return w; ++} ++ ++UDWtype ++__udivdi3 (UDWtype u, UDWtype v) ++{ ++ return __udivmoddi4 (u, v, NULL); ++} ++ ++UDWtype ++__umoddi3 (UDWtype u, UDWtype v) ++{ ++ UDWtype w; ++ ++ __udivmoddi4 (u, v, &w); ++ return w; ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/hal.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/hal.c +--- linux-3.12.2/3rdparty/ndiswrapper/hal.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/hal.c 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,157 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ntoskernel.h" ++#include "hal_exports.h" ++ ++wstdcall void WIN_FUNC(WRITE_PORT_ULONG,2) ++ (ULONG_PTR port, ULONG value) ++{ ++ outl(value, port); ++} ++ ++wstdcall ULONG WIN_FUNC(READ_PORT_ULONG,1) ++ (ULONG_PTR port) ++{ ++ return inl(port); ++} ++ ++wstdcall void WIN_FUNC(WRITE_PORT_USHORT,2) ++ (ULONG_PTR port, USHORT value) ++{ ++ outw(value, port); ++} ++ ++wstdcall USHORT WIN_FUNC(READ_PORT_USHORT,1) ++ (ULONG_PTR port) ++{ ++ return inw(port); ++} ++ ++wstdcall void WIN_FUNC(WRITE_PORT_UCHAR,2) ++ (ULONG_PTR port, UCHAR value) ++{ ++ outb(value, port); ++} ++ ++wstdcall UCHAR WIN_FUNC(READ_PORT_UCHAR,1) ++ (ULONG_PTR port) ++{ ++ return inb(port); ++} ++ ++wstdcall void WIN_FUNC(WRITE_PORT_BUFFER_USHORT,3) ++ (ULONG_PTR port, USHORT *buf, ULONG count) ++{ ++ outsw(port, buf, count); ++} ++ ++wstdcall void WIN_FUNC(READ_PORT_BUFFER_USHORT,3) ++ (ULONG_PTR port, USHORT *buf, ULONG count) ++{ ++ insw(port, buf, count); ++} ++ ++wstdcall void WIN_FUNC(WRITE_PORT_BUFFER_ULONG,3) ++ (ULONG_PTR port, ULONG *buf, ULONG count) ++{ ++ outsl(port, buf, count); ++} ++ ++wstdcall void WIN_FUNC(READ_PORT_BUFFER_ULONG,3) ++ (ULONG_PTR port, ULONG *buf, ULONG count) ++{ ++ insl(port, buf, count); ++} ++ ++wstdcall USHORT WIN_FUNC(READ_REGISTER_USHORT,1) ++ (void __iomem *reg) ++{ ++ return readw(reg); ++} ++ ++wstdcall void WIN_FUNC(WRITE_REGISTER_ULONG,2) ++ (void __iomem *reg, UINT val) ++{ ++ writel(val, reg); ++} ++ ++wstdcall void WIN_FUNC(WRITE_REGISTER_USHORT,2) ++ (void __iomem *reg, USHORT val) ++{ ++ writew(val, reg); ++} ++ ++wstdcall void WIN_FUNC(WRITE_REGISTER_UCHAR,2) ++ (void __iomem *reg, UCHAR val) ++{ ++ writeb(val, reg); ++} ++ ++wstdcall void WIN_FUNC(KeStallExecutionProcessor,1) ++ (ULONG usecs) ++{ ++ udelay(usecs); ++} ++ ++wstdcall KIRQL WIN_FUNC(KeGetCurrentIrql,0) ++ (void) ++{ ++ return current_irql(); ++} ++ ++wfastcall KIRQL WIN_FUNC(KfRaiseIrql,1) ++ (KIRQL newirql) ++{ ++ return raise_irql(newirql); ++} ++ ++wfastcall void WIN_FUNC(KfLowerIrql,1) ++ (KIRQL oldirql) ++{ ++ lower_irql(oldirql); ++} ++ ++wfastcall KIRQL WIN_FUNC(KfAcquireSpinLock,1) ++ (NT_SPIN_LOCK *lock) ++{ ++ return nt_spin_lock_irql(lock, DISPATCH_LEVEL); ++} ++ ++wfastcall void WIN_FUNC(KfReleaseSpinLock,2) ++ (NT_SPIN_LOCK *lock, KIRQL oldirql) ++{ ++ nt_spin_unlock_irql(lock, oldirql); ++} ++ ++wfastcall void WIN_FUNC(KefAcquireSpinLockAtDpcLevel,1) ++ (NT_SPIN_LOCK *lock) ++{ ++#ifdef DEBUG_IRQL ++ if (current_irql() != DISPATCH_LEVEL) ++ ERROR("irql != DISPATCH_LEVEL"); ++#endif ++ nt_spin_lock(lock); ++} ++ ++wfastcall void WIN_FUNC(KefReleaseSpinLockFromDpcLevel,1) ++ (NT_SPIN_LOCK *lock) ++{ ++#ifdef DEBUG_IRQL ++ if (current_irql() != DISPATCH_LEVEL) ++ ERROR("irql != DISPATCH_LEVEL"); ++#endif ++ nt_spin_unlock(lock); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/iw_ndis.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/iw_ndis.c +--- linux-3.12.2/3rdparty/ndiswrapper/iw_ndis.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/iw_ndis.c 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,2001 @@ ++ /* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "iw_ndis.h" ++#include "wrapndis.h" ++ ++#ifdef CONFIG_WIRELESS_EXT ++ ++static int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, ++ 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; ++ ++static const char *network_names[] = {"IEEE 802.11FH", "IEEE 802.11b", ++ "IEEE 802.11a", "IEEE 802.11g", "Auto"}; ++ ++static int set_essid(struct ndis_device *wnd, const char *ssid, int ssid_len) ++{ ++ NDIS_STATUS res; ++ struct ndis_essid req; ++ ++ if (ssid_len > NDIS_ESSID_MAX_SIZE) ++ return -EINVAL; ++ ++ memset(&req, 0, sizeof(req)); ++ req.length = ssid_len; ++ if (ssid_len) ++ memcpy(&req.essid, ssid, ssid_len); ++ ++ res = mp_set(wnd, OID_802_11_SSID, &req, sizeof(req)); ++ if (res) { ++ WARNING("setting essid failed (%08X)", res); ++ EXIT2(return -EINVAL); ++ } ++ memcpy(&wnd->essid, &req, sizeof(req)); ++ EXIT2(return 0); ++} ++ ++static int set_iw_auth_mode(struct ndis_device *wnd, int wpa_version, ++ int auth_80211_alg) ++{ ++ NDIS_STATUS res; ++ ULONG auth_mode; ++ ++ ENTER2("%d, %d", wpa_version, auth_80211_alg); ++ if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { ++ if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X) ++ auth_mode = Ndis802_11AuthModeWPA2; ++ else ++ auth_mode = Ndis802_11AuthModeWPA2PSK; ++ } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { ++ if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X) ++ auth_mode = Ndis802_11AuthModeWPA; ++ else if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_PSK) ++ auth_mode = Ndis802_11AuthModeWPAPSK; ++ else ++ auth_mode = Ndis802_11AuthModeWPANone; ++ } else if (auth_80211_alg & IW_AUTH_ALG_SHARED_KEY) { ++ if (auth_80211_alg & IW_AUTH_ALG_OPEN_SYSTEM) ++ auth_mode = Ndis802_11AuthModeAutoSwitch; ++ else ++ auth_mode = Ndis802_11AuthModeShared; ++ } else ++ auth_mode = Ndis802_11AuthModeOpen; ++ ++ res = mp_set_int(wnd, OID_802_11_AUTHENTICATION_MODE, auth_mode); ++ if (res) { ++ WARNING("setting auth mode to %u failed (%08X)", ++ auth_mode, res); ++ if (res == NDIS_STATUS_INVALID_DATA) ++ EXIT2(return -EINVAL); ++ return -EOPNOTSUPP; ++ } ++ wnd->iw_auth_wpa_version = wpa_version; ++ wnd->iw_auth_80211_alg = auth_80211_alg; ++ EXIT2(return 0); ++} ++ ++static int set_auth_mode(struct ndis_device *wnd) ++{ ++ return set_iw_auth_mode(wnd, wnd->iw_auth_wpa_version, ++ wnd->iw_auth_80211_alg); ++} ++ ++static enum ndis_priv_filter ndis_priv_mode(struct ndis_device *wnd) ++{ ++ if (wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2 || ++ wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA) ++ return Ndis802_11PrivFilter8021xWEP; ++ else ++ return Ndis802_11PrivFilterAcceptAll; ++} ++ ++static int set_priv_filter(struct ndis_device *wnd) ++{ ++ NDIS_STATUS res; ++ ULONG flags; ++ ++ flags = ndis_priv_mode(wnd); ++ ENTER2("filter: %d", flags); ++ res = mp_set_int(wnd, OID_802_11_PRIVACY_FILTER, flags); ++ if (res) ++ TRACE2("setting privacy filter to %d failed (%08X)", ++ flags, res); ++ EXIT2(return 0); ++} ++ ++static int set_encr_mode(struct ndis_device *wnd) ++{ ++ return set_iw_encr_mode(wnd, wnd->iw_auth_cipher_pairwise, ++ wnd->iw_auth_cipher_group); ++} ++ ++static int set_assoc_params(struct ndis_device *wnd) ++{ ++ TRACE2("wpa_version=0x%x auth_alg=0x%x key_mgmt=0x%x " ++ "cipher_pairwise=0x%x cipher_group=0x%x", ++ wnd->iw_auth_wpa_version, wnd->iw_auth_80211_alg, ++ wnd->iw_auth_key_mgmt, wnd->iw_auth_cipher_pairwise, ++ wnd->iw_auth_cipher_group); ++ set_auth_mode(wnd); ++ set_priv_filter(wnd); ++ set_encr_mode(wnd); ++ return 0; ++} ++ ++static int iw_set_essid(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ int length; ++ ++ ENTER2(""); ++ /* there is no way to turn off essid other than to set to ++ * random bytes; instead, we use off to mean any */ ++ if (wrqu->essid.flags) { ++ length = wrqu->essid.length; ++ /* Strip '\0' appended by wireless extensions 19 and older */ ++ if (length > 0 && extra[length - 1] == '\0') ++ length--; ++ TRACE2("%d", length); ++ if (length <= 0 || length > NDIS_ESSID_MAX_SIZE) ++ EXIT2(return -EINVAL); ++ } else ++ length = 0; ++ ++ set_assoc_params(wnd); ++ ++ if (set_essid(wnd, extra, length)) ++ EXIT2(return -EINVAL); ++ ++ EXIT2(return 0); ++} ++ ++static int iw_get_essid(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ struct ndis_essid req; ++ ++ ENTER2(""); ++ memset(&req, 0, sizeof(req)); ++ res = mp_query(wnd, OID_802_11_SSID, &req, sizeof(req)); ++ if (res) { ++ WARNING("getting essid failed (%08X)", res); ++ EXIT2(return -EOPNOTSUPP); ++ } ++ memcpy(extra, req.essid, req.length); ++ if (req.length > 0) ++ wrqu->essid.flags = 1; ++ else ++ wrqu->essid.flags = 0; ++ wrqu->essid.length = req.length; ++ EXIT2(return 0); ++} ++ ++/* index must be 0 - N, as per NDIS */ ++static int add_wep_key(struct ndis_device *wnd, char *key, int key_len, ++ int index) ++{ ++ struct ndis_encr_key ndis_key; ++ NDIS_STATUS res; ++ ++ ENTER2("key index: %d, length: %d", index, key_len); ++ if (key_len <= 0 || key_len > NDIS_ENCODING_TOKEN_MAX) { ++ WARNING("invalid key length (%d)", key_len); ++ EXIT2(return -EINVAL); ++ } ++ if (index < 0 || index >= MAX_ENCR_KEYS) { ++ WARNING("invalid key index (%d)", index); ++ EXIT2(return -EINVAL); ++ } ++ ndis_key.struct_size = sizeof(ndis_key); ++ ndis_key.length = key_len; ++ memcpy(&ndis_key.key, key, key_len); ++ ndis_key.index = index; ++ ++ if (index == wnd->encr_info.tx_key_index) { ++ ndis_key.index |= (1 << 31); ++ res = set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104, ++ IW_AUTH_CIPHER_NONE); ++ if (res) ++ WARNING("encryption couldn't be enabled (%08X)", res); ++ } ++ TRACE2("key %d: " MACSTRSEP, index, MAC2STR(key)); ++ res = mp_set(wnd, OID_802_11_ADD_WEP, &ndis_key, sizeof(ndis_key)); ++ if (res) { ++ WARNING("adding encryption key %d failed (%08X)", ++ index+1, res); ++ EXIT2(return -EINVAL); ++ } ++ ++ /* Atheros driver messes up ndis_key during ADD_WEP, so ++ * don't rely on that; instead use info in key and key_len */ ++ wnd->encr_info.keys[index].length = key_len; ++ memcpy(&wnd->encr_info.keys[index].key, key, key_len); ++ ++ EXIT2(return 0); ++} ++ ++static int set_infra_mode(struct ndis_device *wnd, ++ enum ndis_infrastructure_mode mode) ++{ ++ NDIS_STATUS res; ++ unsigned int i; ++ ++ ENTER2("%d", mode); ++ res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, ++ &wnd->infrastructure_mode); ++ if (res != NDIS_STATUS_SUCCESS) { ++ WARNING("getting operating mode failed (%08X)", res); ++ EXIT2(return -EINVAL); ++ } ++ if (wnd->infrastructure_mode == mode) ++ EXIT2(return 0); ++ res = mp_set_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, mode); ++ if (res) { ++ WARNING("setting operating mode to %d failed (%08X)", ++ mode, res); ++ EXIT2(return -EINVAL); ++ } ++ /* NDIS drivers clear keys when infrastructure mode is ++ * changed. But Linux tools assume otherwise. So set the ++ * keys */ ++ if (wnd->iw_auth_key_mgmt == 0 || ++ wnd->iw_auth_key_mgmt == IW_AUTH_KEY_MGMT_802_1X) { ++ for (i = 0; i < MAX_ENCR_KEYS; i++) { ++ if (wnd->encr_info.keys[i].length > 0) ++ add_wep_key(wnd, wnd->encr_info.keys[i].key, ++ wnd->encr_info.keys[i].length, i); ++ } ++ } ++ wnd->infrastructure_mode = mode; ++ EXIT2(return 0); ++} ++ ++static int iw_set_infra_mode(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ enum ndis_infrastructure_mode ndis_mode; ++ ++ ENTER2("%d", wrqu->mode); ++ switch (wrqu->mode) { ++ case IW_MODE_ADHOC: ++ ndis_mode = Ndis802_11IBSS; ++ break; ++ case IW_MODE_INFRA: ++ ndis_mode = Ndis802_11Infrastructure; ++ break; ++ case IW_MODE_AUTO: ++ ndis_mode = Ndis802_11AutoUnknown; ++ break; ++ default: ++ EXIT2(return -EINVAL); ++ } ++ ++ if (set_infra_mode(wnd, ndis_mode)) ++ EXIT2(return -EINVAL); ++ ++ EXIT2(return 0); ++} ++ ++static int iw_get_infra_mode(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ int ndis_mode, iw_mode; ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &ndis_mode); ++ if (res) { ++ WARNING("getting operating mode failed (%08X)", res); ++ EXIT2(return -EOPNOTSUPP); ++ } ++ ++ switch (ndis_mode) { ++ case Ndis802_11IBSS: ++ iw_mode = IW_MODE_ADHOC; ++ break; ++ case Ndis802_11Infrastructure: ++ iw_mode = IW_MODE_INFRA; ++ break; ++ case Ndis802_11AutoUnknown: ++ iw_mode = IW_MODE_AUTO; ++ break; ++ default: ++ ERROR("invalid operating mode (%u)", ndis_mode); ++ EXIT2(return -EINVAL); ++ } ++ wrqu->mode = iw_mode; ++ EXIT2(return 0); ++} ++ ++static const char *network_type_to_name(int net_type) ++{ ++ if (net_type >= 0 && net_type < ARRAY_SIZE(network_names)) ++ return network_names[net_type]; ++ else ++ return network_names[ARRAY_SIZE(network_names) - 1]; ++} ++ ++static int iw_get_network_type(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ unsigned int network_type; ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ res = mp_query_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, ++ &network_type); ++ if (res) { ++ WARNING("getting network type failed: %08X", res); ++ network_type = -1; ++ } ++ strncpy(wrqu->name, network_type_to_name(network_type), ++ sizeof(wrqu->name) - 1); ++ wrqu->name[sizeof(wrqu->name)-1] = 0; ++ return 0; ++} ++ ++static int iw_get_freq(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ struct ndis_configuration req; ++ ++ ENTER2(""); ++ memset(&req, 0, sizeof(req)); ++ res = mp_query(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req)); ++ if (res) { ++ WARNING("getting configuration failed (%08X)", res); ++ EXIT2(return -EOPNOTSUPP); ++ } ++ ++ memset(&(wrqu->freq), 0, sizeof(struct iw_freq)); ++ ++ /* see comment in wireless.h above the "struct iw_freq" ++ definition for an explanation of this if ++ NOTE: 1000000 is due to the kHz ++ */ ++ if (req.ds_config > 1000000) { ++ wrqu->freq.m = req.ds_config / 10; ++ wrqu->freq.e = 1; ++ } ++ else ++ wrqu->freq.m = req.ds_config; ++ ++ /* convert from kHz to Hz */ ++ wrqu->freq.e += 3; ++ ++ return 0; ++} ++ ++static int iw_set_freq(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ struct ndis_configuration req; ++ ++ ENTER2(""); ++ /* this OID is valid only when not associated */ ++ if (netif_carrier_ok(wnd->net_dev)) ++ EXIT2(return 0); ++ memset(&req, 0, sizeof(req)); ++ res = mp_query(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req)); ++ if (res) { ++ WARNING("getting configuration failed (%08X)", res); ++ EXIT2(return 0); ++ } ++ ++ if (wrqu->freq.m < 1000 && wrqu->freq.e == 0) { ++ if (wrqu->freq.m >= 1 && wrqu->freq.m <= ARRAY_SIZE(freq_chan)) ++ req.ds_config = freq_chan[wrqu->freq.m - 1] * 1000; ++ else ++ return -EINVAL; ++ } else { ++ int i; ++ req.ds_config = wrqu->freq.m; ++ for (i = wrqu->freq.e; i > 0; i--) ++ req.ds_config *= 10; ++ req.ds_config /= 1000; ++ } ++ res = mp_set(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req)); ++ if (res) ++ WARNING("setting configuration failed (%08X)", res); ++ return 0; ++} ++ ++static int iw_get_tx_power(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ndis_tx_power_level ndis_power; ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, ++ &ndis_power, sizeof(ndis_power)); ++ if (res) ++ return -EOPNOTSUPP; ++ wrqu->txpower.flags = IW_TXPOW_MWATT; ++ wrqu->txpower.disabled = 0; ++ wrqu->txpower.fixed = 0; ++ wrqu->txpower.value = ndis_power; ++ return 0; ++} ++ ++static int iw_set_tx_power(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ndis_tx_power_level ndis_power; ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ if (wrqu->txpower.disabled) ++ ndis_power = 0; ++ else { ++ if (wrqu->txpower.flags == IW_TXPOW_MWATT) ++ ndis_power = wrqu->txpower.value; ++ else { // wrqu->txpower.flags == IW_TXPOW_DBM ++ if (wrqu->txpower.value > 20) ++ ndis_power = 128; ++ else if (wrqu->txpower.value < -43) ++ ndis_power = 127; ++ else { ++ signed char tmp; ++ tmp = wrqu->txpower.value; ++ tmp = -12 - tmp; ++ tmp <<= 2; ++ ndis_power = (unsigned char)tmp; ++ } ++ } ++ } ++ TRACE2("%d", ndis_power); ++ res = mp_set(wnd, OID_802_11_TX_POWER_LEVEL, ++ &ndis_power, sizeof(ndis_power)); ++ if (res) ++ EXIT2(return -EOPNOTSUPP); ++ if (ndis_power == 0) ++ res = disassociate(wnd, 0); ++ EXIT2(return 0); ++} ++ ++static int iw_get_bitrate(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ULONG ndis_rate; ++ int res; ++ ++ ENTER2(""); ++ res = mp_query(wnd, OID_GEN_LINK_SPEED, &ndis_rate, sizeof(ndis_rate)); ++ if (res) { ++ WARNING("getting bitrate failed (%08X)", res); ++ ndis_rate = 0; ++ } ++ ++ wrqu->bitrate.value = ndis_rate * 100; ++ return 0; ++} ++ ++static int iw_set_bitrate(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ int i, n; ++ NDIS_STATUS res; ++ UCHAR rates[NDIS_MAX_RATES_EX]; ++ ++ ENTER2(""); ++ if (wrqu->bitrate.fixed == 0) ++ EXIT2(return 0); ++ ++ res = mp_query_info(wnd, OID_802_11_SUPPORTED_RATES, &rates, ++ sizeof(rates), &n, NULL); ++ if (res) { ++ WARNING("getting bit rate failed (%08X)", res); ++ EXIT2(return 0); ++ } ++ for (i = 0; i < n; i++) { ++ if (rates[i] & 0x80) ++ continue; ++ if ((rates[i] & 0x7f) * 500000 > wrqu->bitrate.value) { ++ TRACE2("setting rate %d to 0", ++ (rates[i] & 0x7f) * 500000); ++ rates[i] = 0; ++ } ++ } ++ ++ res = mp_set(wnd, OID_802_11_DESIRED_RATES, &rates, n); ++ if (res) { ++ WARNING("setting bit rate failed (%08X)", res); ++ EXIT2(return 0); ++ } ++ ++ return 0; ++} ++ ++static int iw_set_dummy(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ /* Do nothing. Used for ioctls that are not implemented. */ ++ return 0; ++} ++ ++static int iw_get_rts_threshold(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ndis_rts_threshold threshold; ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ res = mp_query(wnd, OID_802_11_RTS_THRESHOLD, ++ &threshold, sizeof(threshold)); ++ if (res) ++ return -EOPNOTSUPP; ++ ++ wrqu->rts.value = threshold; ++ return 0; ++} ++ ++static int iw_set_rts_threshold(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ndis_rts_threshold threshold; ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ threshold = wrqu->rts.value; ++ res = mp_set(wnd, OID_802_11_RTS_THRESHOLD, ++ &threshold, sizeof(threshold)); ++ if (res == NDIS_STATUS_INVALID_DATA) ++ return -EINVAL; ++ if (res) ++ return -EOPNOTSUPP; ++ ++ return 0; ++} ++ ++static int iw_get_frag_threshold(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ndis_fragmentation_threshold frag_threshold; ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, ++ &frag_threshold, sizeof(frag_threshold)); ++ if (res) ++ return -ENOTSUPP; ++ ++ wrqu->frag.value = frag_threshold; ++ return 0; ++} ++ ++static int iw_set_frag_threshold(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ndis_rts_threshold threshold; ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ threshold = wrqu->frag.value; ++ res = mp_set(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, ++ &threshold, sizeof(threshold)); ++ if (res == NDIS_STATUS_INVALID_DATA) ++ return -EINVAL; ++ if (res) ++ return -EOPNOTSUPP; ++ return 0; ++} ++ ++int get_ap_address(struct ndis_device *wnd, mac_address ap_addr) ++{ ++ NDIS_STATUS res; ++ ++ res = mp_query(wnd, OID_802_11_BSSID, ap_addr, ETH_ALEN); ++ TRACE2(MACSTRSEP, MAC2STR(ap_addr)); ++ if (res) { ++ TRACE2("res: %08X", res); ++ memset(ap_addr, 0x0, ETH_ALEN); ++ EXIT2(return -EOPNOTSUPP); ++ } ++ EXIT2(return 0); ++} ++ ++static int iw_get_ap_address(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ mac_address ap_addr; ++ ++ ENTER2(""); ++ get_ap_address(wnd, ap_addr); ++ memcpy(wrqu->ap_addr.sa_data, ap_addr, ETH_ALEN); ++ wrqu->ap_addr.sa_family = ARPHRD_ETHER; ++ EXIT2(return 0); ++} ++ ++static int iw_set_ap_address(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ mac_address ap_addr; ++ ++ ENTER2(""); ++ memcpy(ap_addr, wrqu->ap_addr.sa_data, ETH_ALEN); ++ TRACE2(MACSTRSEP, MAC2STR(ap_addr)); ++ res = mp_set(wnd, OID_802_11_BSSID, ap_addr, ETH_ALEN); ++ /* user apps may set ap's mac address, which is not required; ++ * they may fail to work if this function fails, so return ++ * success */ ++ if (res) ++ WARNING("setting AP mac address failed (%08X)", res); ++ ++ EXIT2(return 0); ++} ++ ++int set_ndis_auth_mode(struct ndis_device *wnd, ULONG auth_mode) ++{ ++ NDIS_STATUS res; ++ ++ ENTER2("%d", auth_mode); ++ res = mp_set_int(wnd, OID_802_11_AUTHENTICATION_MODE, auth_mode); ++ if (res) { ++ WARNING("setting auth mode to %u failed (%08X)", ++ auth_mode, res); ++ if (res == NDIS_STATUS_INVALID_DATA) ++ EXIT2(return -EINVAL); ++ return -EOPNOTSUPP; ++ } ++ switch (auth_mode) { ++ case Ndis802_11AuthModeWPA: ++ wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA; ++ wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_802_1X; ++ break; ++ case Ndis802_11AuthModeWPAPSK: ++ wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA; ++ wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK; ++ case Ndis802_11AuthModeWPANone: ++ wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; ++ wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK; ++ break; ++ case Ndis802_11AuthModeWPA2: ++ wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA2; ++ wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_802_1X; ++ break; ++ case Ndis802_11AuthModeWPA2PSK: ++ wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA2; ++ wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK; ++ break; ++ case Ndis802_11AuthModeOpen: ++ wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; ++ wnd->iw_auth_80211_alg = IW_AUTH_ALG_OPEN_SYSTEM; ++ break; ++ case Ndis802_11AuthModeShared: ++ wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; ++ wnd->iw_auth_80211_alg = IW_AUTH_ALG_SHARED_KEY; ++ break; ++ case Ndis802_11AuthModeAutoSwitch: ++ wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; ++ wnd->iw_auth_80211_alg = IW_AUTH_ALG_SHARED_KEY; ++ wnd->iw_auth_80211_alg |= IW_AUTH_ALG_OPEN_SYSTEM; ++ break; ++ default: ++ WARNING("invalid authentication algorithm: %d", auth_mode); ++ break; ++ } ++ EXIT2(return 0); ++} ++ ++int get_ndis_auth_mode(struct ndis_device *wnd) ++{ ++ ULONG mode; ++ NDIS_STATUS res; ++ ++ res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &mode); ++ if (res) { ++ WARNING("getting authentication mode failed (%08X)", res); ++ EXIT2(return -EOPNOTSUPP); ++ } ++ TRACE2("%d", mode); ++ return mode; ++} ++ ++int set_iw_encr_mode(struct ndis_device *wnd, int cipher_pairwise, ++ int cipher_groupwise) ++{ ++ NDIS_STATUS res; ++ ULONG ndis_mode; ++ ++ ENTER2("%d, %d", cipher_pairwise, cipher_groupwise); ++ if (cipher_pairwise & IW_AUTH_CIPHER_CCMP) ++ ndis_mode = Ndis802_11Encryption3Enabled; ++ else if (cipher_pairwise & IW_AUTH_CIPHER_TKIP) ++ ndis_mode = Ndis802_11Encryption2Enabled; ++ else if (cipher_pairwise & ++ (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) ++ ndis_mode = Ndis802_11Encryption1Enabled; ++ else if (cipher_groupwise & IW_AUTH_CIPHER_CCMP) ++ ndis_mode = Ndis802_11Encryption3Enabled; ++ else if (cipher_groupwise & IW_AUTH_CIPHER_TKIP) ++ ndis_mode = Ndis802_11Encryption2Enabled; ++ else ++ ndis_mode = Ndis802_11EncryptionDisabled; ++ ++ res = mp_set_int(wnd, OID_802_11_ENCRYPTION_STATUS, ndis_mode); ++ if (res) { ++ WARNING("setting encryption mode to %u failed (%08X)", ++ ndis_mode, res); ++ if (res == NDIS_STATUS_INVALID_DATA) ++ EXIT2(return -EINVAL); ++ return -EOPNOTSUPP; ++ } ++ wnd->iw_auth_cipher_pairwise = cipher_pairwise; ++ wnd->iw_auth_cipher_group = cipher_groupwise; ++ EXIT2(return 0); ++} ++ ++int get_ndis_encr_mode(struct ndis_device *wnd) ++{ ++ ULONG mode; ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &mode); ++ if (res) { ++ WARNING("getting encryption status failed (%08X)", res); ++ EXIT2(return -EOPNOTSUPP); ++ } else ++ EXIT2(return mode); ++} ++ ++static int iw_get_encr(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ int index, mode; ++ struct encr_info *encr_info = &wnd->encr_info; ++ ++ ENTER2("wnd = %p", wnd); ++ wrqu->data.length = 0; ++ extra[0] = 0; ++ ++ index = (wrqu->encoding.flags & IW_ENCODE_INDEX); ++ TRACE2("index = %u", index); ++ if (index > 0) ++ index--; ++ else ++ index = encr_info->tx_key_index; ++ ++ if (index < 0 || index >= MAX_ENCR_KEYS) { ++ WARNING("encryption index out of range (%u)", index); ++ EXIT2(return -EINVAL); ++ } ++ ++ if (index != encr_info->tx_key_index) { ++ if (encr_info->keys[index].length > 0) { ++ wrqu->data.flags |= IW_ENCODE_ENABLED; ++ wrqu->data.length = encr_info->keys[index].length; ++ memcpy(extra, encr_info->keys[index].key, ++ encr_info->keys[index].length); ++ } ++ else ++ wrqu->data.flags |= IW_ENCODE_DISABLED; ++ ++ EXIT2(return 0); ++ } ++ ++ /* transmit key */ ++ mode = get_ndis_encr_mode(wnd); ++ if (mode < 0) ++ EXIT2(return -EOPNOTSUPP); ++ ++ if (mode == Ndis802_11EncryptionDisabled || ++ mode == Ndis802_11EncryptionNotSupported) ++ wrqu->data.flags |= IW_ENCODE_DISABLED; ++ else { ++ if (mode == Ndis802_11Encryption1KeyAbsent || ++ mode == Ndis802_11Encryption2KeyAbsent || ++ mode == Ndis802_11Encryption3KeyAbsent) ++ wrqu->data.flags |= IW_ENCODE_NOKEY; ++ else { ++ wrqu->data.flags |= IW_ENCODE_ENABLED; ++ wrqu->encoding.flags |= index+1; ++ wrqu->data.length = encr_info->keys[index].length; ++ memcpy(extra, encr_info->keys[index].key, ++ encr_info->keys[index].length); ++ } ++ } ++ mode = get_ndis_auth_mode(wnd); ++ if (mode < 0) ++ EXIT2(return -EOPNOTSUPP); ++ ++ if (mode == Ndis802_11AuthModeOpen) ++ wrqu->data.flags |= IW_ENCODE_OPEN; ++ else if (mode == Ndis802_11AuthModeAutoSwitch) ++ wrqu->data.flags |= IW_ENCODE_RESTRICTED; ++ else // Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA etc. ++ wrqu->data.flags |= IW_ENCODE_RESTRICTED; ++ ++ EXIT2(return 0); ++} ++ ++/* remove_key is for both wep and wpa */ ++static int remove_key(struct ndis_device *wnd, int index, ++ mac_address bssid) ++{ ++ NDIS_STATUS res; ++ if (wnd->encr_info.keys[index].length == 0) ++ EXIT2(return 0); ++ wnd->encr_info.keys[index].length = 0; ++ memset(&wnd->encr_info.keys[index].key, 0, ++ sizeof(wnd->encr_info.keys[index].length)); ++ if (wnd->iw_auth_cipher_pairwise == IW_AUTH_CIPHER_TKIP || ++ wnd->iw_auth_cipher_pairwise == IW_AUTH_CIPHER_CCMP || ++ wnd->iw_auth_cipher_group == IW_AUTH_CIPHER_TKIP || ++ wnd->iw_auth_cipher_group == IW_AUTH_CIPHER_CCMP) { ++ struct ndis_remove_key rmkey; ++ rmkey.struct_size = sizeof(rmkey); ++ rmkey.index = index; ++ if (bssid) { ++ /* pairwise key */ ++ if (memcmp(bssid, "\xff\xff\xff\xff\xff\xff", ++ ETH_ALEN) != 0) ++ rmkey.index |= (1 << 30); ++ memcpy(rmkey.bssid, bssid, sizeof(rmkey.bssid)); ++ } else ++ memset(rmkey.bssid, 0xff, sizeof(rmkey.bssid)); ++ if (mp_set(wnd, OID_802_11_REMOVE_KEY, &rmkey, sizeof(rmkey))) ++ EXIT2(return -EINVAL); ++ } else { ++ ndis_key_index keyindex = index; ++ res = mp_set_int(wnd, OID_802_11_REMOVE_WEP, keyindex); ++ if (res) { ++ WARNING("removing encryption key %d failed (%08X)", ++ keyindex, res); ++ EXIT2(return -EINVAL); ++ } ++ } ++ /* if it is transmit key, disable encryption */ ++ if (index == wnd->encr_info.tx_key_index) { ++ res = set_iw_encr_mode(wnd, IW_AUTH_CIPHER_NONE, ++ IW_AUTH_CIPHER_NONE); ++ if (res) ++ WARNING("changing encr status failed (%08X)", res); ++ } ++ TRACE2("key %d removed", index); ++ EXIT2(return 0); ++} ++ ++static int iw_set_wep(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ unsigned int index, key_len; ++ struct encr_info *encr_info = &wnd->encr_info; ++ unsigned char *key; ++ ++ ENTER2(""); ++ index = (wrqu->encoding.flags & IW_ENCODE_INDEX); ++ TRACE2("index = %u", index); ++ ++ /* iwconfig gives index as 1 - N */ ++ if (index > 0) ++ index--; ++ else ++ index = encr_info->tx_key_index; ++ ++ if (index >= MAX_ENCR_KEYS) { ++ WARNING("encryption index out of range (%u)", index); ++ EXIT2(return -EINVAL); ++ } ++ ++ /* remove key if disabled */ ++ if (wrqu->data.flags & IW_ENCODE_DISABLED) { ++ if (remove_key(wnd, index, NULL)) ++ EXIT2(return -EINVAL); ++ else ++ EXIT2(return 0); ++ } ++ ++ /* global encryption state (for all keys) */ ++ if (wrqu->data.flags & IW_ENCODE_OPEN) ++ res = set_ndis_auth_mode(wnd, Ndis802_11AuthModeOpen); ++ else // if (wrqu->data.flags & IW_ENCODE_RESTRICTED) ++ res = set_ndis_auth_mode(wnd, Ndis802_11AuthModeShared); ++ if (res) { ++ WARNING("setting authentication mode failed (%08X)", res); ++ EXIT2(return -EINVAL); ++ } ++ ++ TRACE2("key length: %d", wrqu->data.length); ++ ++ if (wrqu->data.length > 0) { ++ key_len = wrqu->data.length; ++ key = extra; ++ } else { // must be set as tx key ++ if (encr_info->keys[index].length == 0) { ++ WARNING("key %d is not set", index+1); ++ EXIT2(return -EINVAL); ++ } ++ key_len = encr_info->keys[index].length; ++ key = encr_info->keys[index].key; ++ encr_info->tx_key_index = index; ++ } ++ ++ if (add_wep_key(wnd, key, key_len, index)) ++ EXIT2(return -EINVAL); ++ ++ if (index == encr_info->tx_key_index) { ++ /* if transmit key is at index other than 0, some ++ * drivers, at least Atheros and TI, want another ++ * (global) non-transmit key to be set; don't know why */ ++ if (index != 0) { ++ int i; ++ for (i = 0; i < MAX_ENCR_KEYS; i++) ++ if (i != index && ++ encr_info->keys[i].length != 0) ++ break; ++ if (i == MAX_ENCR_KEYS) { ++ if (index == 0) ++ i = index + 1; ++ else ++ i = index - 1; ++ if (add_wep_key(wnd, key, key_len, i)) ++ WARNING("couldn't add broadcast key" ++ " at %d", i); ++ } ++ } ++ /* ndis drivers want essid to be set after setting encr */ ++ set_essid(wnd, wnd->essid.essid, wnd->essid.length); ++ } ++ EXIT2(return 0); ++} ++ ++static int iw_set_nick(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ++ if (wrqu->data.length >= sizeof(wnd->nick)) ++ return -EINVAL; ++ memcpy(wnd->nick, extra, wrqu->data.length); ++ wnd->nick[wrqu->data.length] = 0; ++ return 0; ++} ++ ++static int iw_get_nick(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ++ wrqu->data.length = strlen(wnd->nick); ++ memcpy(extra, wnd->nick, wrqu->data.length); ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) && !defined(IW_REQUEST_FLAG_COMPAT) ++#define iwe_stream_add_event(a, b, c, d, e) iwe_stream_add_event(b, c, d, e) ++#define iwe_stream_add_point(a, b, c, d, e) iwe_stream_add_point(b, c, d, e) ++#define iwe_stream_add_value(a, b, c, d, e, f) \ ++ iwe_stream_add_value(b, c, d, e, f) ++#define iwe_stream_lcp_len(a) IW_EV_LCP_LEN ++#endif ++ ++static char *ndis_translate_scan(struct net_device *dev, ++ struct iw_request_info *info, char *event, ++ char *end_buf, void *item) ++{ ++ struct iw_event iwe; ++ char *current_val; ++ char *ret; ++ int i, nrates; ++ unsigned char custom_str[64]; ++ struct ndis_wlan_bssid *bssid; ++ struct ndis_wlan_bssid_ex *bssid_ex; ++ int extended; ++ ++ ENTER2("%p, %p", event, item); ++ bssid = item; ++ bssid_ex = item; ++ extended = (bssid->length > offsetof(struct ndis_wlan_bssid_ex, var)); ++ ++ /* add mac address */ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = SIOCGIWAP; ++ iwe.u.ap_addr.sa_family = ARPHRD_ETHER; ++ iwe.len = IW_EV_ADDR_LEN; ++ memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); ++ ret = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_ADDR_LEN); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ ++ /* add essid */ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = SIOCGIWESSID; ++ iwe.u.data.length = bssid->ssid.length; ++ if (iwe.u.data.length > IW_ESSID_MAX_SIZE) ++ iwe.u.data.length = IW_ESSID_MAX_SIZE; ++ iwe.u.data.flags = 1; ++ iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; ++ ret = iwe_stream_add_point(info, event, end_buf, &iwe, ++ bssid->ssid.essid); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ ++ /* add protocol name */ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = SIOCGIWNAME; ++ strncpy(iwe.u.name, network_type_to_name(bssid->net_type), IFNAMSIZ); ++ ret = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_CHAR_LEN); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ ++ /* add mode */ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = SIOCGIWMODE; ++ if (bssid->mode == Ndis802_11IBSS) ++ iwe.u.mode = IW_MODE_ADHOC; ++ else if (bssid->mode == Ndis802_11Infrastructure) ++ iwe.u.mode = IW_MODE_MASTER; ++ else // if (bssid->mode == Ndis802_11AutoUnknown) ++ iwe.u.mode = IW_MODE_AUTO; ++ ret = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_UINT_LEN); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ ++ /* add freq */ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = SIOCGIWFREQ; ++ iwe.u.freq.m = bssid->config.ds_config; ++ if (bssid->config.ds_config > 1000000) { ++ iwe.u.freq.m = bssid->config.ds_config / 10; ++ iwe.u.freq.e = 1; ++ } ++ else ++ iwe.u.freq.m = bssid->config.ds_config; ++ /* convert from kHz to Hz */ ++ iwe.u.freq.e += 3; ++ iwe.len = IW_EV_FREQ_LEN; ++ ret = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_FREQ_LEN); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ ++ /* add qual */ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVQUAL; ++ i = 100 * (bssid->rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE); ++ if (i < 0) ++ i = 0; ++ else if (i > 100) ++ i = 100; ++ iwe.u.qual.level = bssid->rssi; ++ iwe.u.qual.noise = WL_NOISE; ++ iwe.u.qual.qual = i; ++ iwe.len = IW_EV_QUAL_LEN; ++ ret = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_QUAL_LEN); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ ++ /* add key info */ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = SIOCGIWENCODE; ++ if (bssid->privacy == Ndis802_11PrivFilterAcceptAll) ++ iwe.u.data.flags = IW_ENCODE_DISABLED; ++ else ++ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; ++ iwe.u.data.length = 0; ++ iwe.len = IW_EV_POINT_LEN; ++ ret = iwe_stream_add_point(info, event, end_buf, &iwe, ++ bssid->ssid.essid); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ ++ /* add rate */ ++ memset(&iwe, 0, sizeof(iwe)); ++ current_val = event + iwe_stream_lcp_len(info); ++ iwe.cmd = SIOCGIWRATE; ++ if (extended) ++ nrates = ARRAY_SIZE(bssid->rates); ++ else ++ nrates = ARRAY_SIZE(bssid_ex->rates_ex); ++ for (i = 0; i < nrates; i++) { ++ if (bssid_ex->rates_ex[i] & 0x7f) { ++ iwe.u.bitrate.value = ((bssid->rates[i] & 0x7f) * ++ 500000); ++ ret = iwe_stream_add_value(info, event, current_val, ++ end_buf, &iwe, ++ IW_EV_PARAM_LEN); ++ if (ret == current_val) ++ return NULL; ++ current_val = ret; ++ } ++ } ++ ++ if ((current_val - event) > iwe_stream_lcp_len(info)) ++ event = current_val; ++ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ sprintf(custom_str, "bcn_int=%d", bssid->config.beacon_period); ++ iwe.u.data.length = strlen(custom_str); ++ ret = iwe_stream_add_point(info, event, end_buf, &iwe, custom_str); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVCUSTOM; ++ sprintf(custom_str, "atim=%u", bssid->config.atim_window); ++ iwe.u.data.length = strlen(custom_str); ++ ret = iwe_stream_add_point(info, event, end_buf, &iwe, custom_str); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ ++ TRACE2("%d, %zu", bssid->length, sizeof(*bssid)); ++ if (extended) { ++ struct ndis_variable_ies *iep = bssid_ex->var; ++ unsigned char *end = (unsigned char *)&bssid_ex->fixed + ++ bssid_ex->ie_length; ++ ++ while (&iep->length < end && &iep->data[iep->length] <= end) { ++ unsigned char ielen = iep->length + 2; ++ ++ memset(&iwe, 0, sizeof(iwe)); ++ iwe.cmd = IWEVGENIE; ++ iwe.u.data.length = ielen; ++ ret = iwe_stream_add_point(info, event, end_buf, &iwe, ++ (char *)iep); ++ if (ret == event) ++ return NULL; ++ event = ret; ++ iep = (typeof(iep))&iep->data[iep->length]; ++ } ++ } ++ TRACE2("event = %p, current_val = %p", event, current_val); ++ EXIT2(return event); ++} ++ ++static int set_scan(struct ndis_device *wnd) ++{ ++ NDIS_STATUS res; ++ ++ ENTER2(""); ++ res = mp_set(wnd, OID_802_11_BSSID_LIST_SCAN, NULL, 0); ++ if (res) { ++ WARNING("scanning failed (%08X)", res); ++ EXIT2(return -EOPNOTSUPP); ++ } ++ wnd->scan_timestamp = jiffies; ++ EXIT2(return 0); ++} ++ ++static int iw_set_scan(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ return set_scan(wnd); ++} ++ ++static int iw_get_scan(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ unsigned int i, buf_len, needed, data_len; ++ NDIS_STATUS res; ++ struct ndis_bssid_list *bssid_list = NULL; ++ char *event = extra; ++ struct ndis_wlan_bssid *cur_item; ++ ++ ENTER2(""); ++ if (time_before(jiffies, wnd->scan_timestamp + 3 * HZ)) ++ return -EAGAIN; ++ /* try with space for a few scan items */ ++ buf_len = sizeof(ULONG) + offsetof(struct ndis_wlan_bssid_ex, var) * 8; ++ ++ /* Try many times, as the needed space may grow between queries */ ++ for (i = 0; i < 10; i++) { ++ bssid_list = kzalloc(buf_len, GFP_KERNEL); ++ if (!bssid_list) { ++ ERROR("couldn't allocate %u bytes for scan results", ++ buf_len); ++ return -ENOMEM; ++ } ++ ++ needed = 0; ++ data_len = 0; ++ res = mp_query_info(wnd, OID_802_11_BSSID_LIST, bssid_list, ++ buf_len, &data_len, &needed); ++ TRACE2("try %d: given %d bytes, needed %d, written %d", ++ i, buf_len, needed, data_len); ++ if (needed <= buf_len) ++ break; ++ kfree(bssid_list); ++ buf_len = needed; ++ } ++ if (res) { ++ WARNING("getting BSSID list failed (%08X)", res); ++ kfree(bssid_list); ++ EXIT2(return -EOPNOTSUPP); ++ } ++ ++ /* some drivers don't set bssid_list->num_items to 0 if ++ OID_802_11_BSSID_LIST returns no items (prism54 driver, e.g.,) */ ++ TRACE2("items: %d", bssid_list->num_items); ++ cur_item = &bssid_list->bssid[0]; ++ for (i = 0; i < bssid_list->num_items; i++) { ++ TRACE2("item %d: len %d, remaining data %d", ++ i, cur_item->length, data_len); ++ /* drop truncated items */ ++ if (cur_item->length > data_len) ++ break; ++ event = ndis_translate_scan(dev, info, event, ++ extra + wrqu->data.length, ++ cur_item); ++ if (!event) { ++ kfree(bssid_list); ++ return -E2BIG; ++ } ++ data_len -= cur_item->length; ++ cur_item = (struct ndis_wlan_bssid *)((char *)cur_item + ++ cur_item->length); ++ } ++ wrqu->data.length = event - extra; ++ wrqu->data.flags = 0; ++ kfree(bssid_list); ++ EXIT2(return 0); ++} ++ ++static int iw_set_power_mode(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ enum ndis_power power_mode; ++ ++ if (wrqu->power.disabled == 1) ++ power_mode = NDIS_POWER_OFF; ++ else if (wrqu->power.flags & IW_POWER_MIN) ++ power_mode = NDIS_POWER_MIN; ++ else // if (wrqu->power.flags & IW_POWER_MAX) ++ power_mode = NDIS_POWER_MAX; ++ ++ TRACE2("%d", power_mode); ++ res = mp_set(wnd, OID_802_11_POWER_MODE, ++ &power_mode, sizeof(power_mode)); ++ if (res) ++ WARNING("setting power mode failed (%08X)", res); ++ return 0; ++} ++ ++static int iw_get_power_mode(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ enum ndis_power power_mode; ++ ++ ENTER2(""); ++ res = mp_query(wnd, OID_802_11_POWER_MODE, ++ &power_mode, sizeof(power_mode)); ++ if (res) ++ return -ENOTSUPP; ++ ++ if (power_mode == NDIS_POWER_OFF) ++ wrqu->power.disabled = 1; ++ else { ++ if (wrqu->power.flags != 0) ++ return 0; ++ wrqu->power.flags |= IW_POWER_ALL_R; ++ wrqu->power.flags |= IW_POWER_TIMEOUT; ++ wrqu->power.value = 0; ++ wrqu->power.disabled = 0; ++ ++ if (power_mode == NDIS_POWER_MIN) ++ wrqu->power.flags |= IW_POWER_MIN; ++ else // if (power_mode == NDIS_POWER_MAX) ++ wrqu->power.flags |= IW_POWER_MAX; ++ } ++ return 0; ++} ++ ++static int iw_get_sensitivity(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ ndis_rssi rssi_trigger; ++ ++ ENTER2(""); ++ res = mp_query(wnd, OID_802_11_RSSI_TRIGGER, ++ &rssi_trigger, sizeof(rssi_trigger)); ++ if (res) ++ return -EOPNOTSUPP; ++ wrqu->param.value = rssi_trigger; ++ wrqu->param.disabled = (rssi_trigger == 0); ++ wrqu->param.fixed = 1; ++ return 0; ++} ++ ++static int iw_set_sensitivity(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ ndis_rssi rssi_trigger; ++ ++ ENTER2(""); ++ if (wrqu->param.disabled) ++ rssi_trigger = 0; ++ else ++ rssi_trigger = wrqu->param.value; ++ res = mp_set(wnd, OID_802_11_RSSI_TRIGGER, ++ &rssi_trigger, sizeof(rssi_trigger)); ++ if (res == NDIS_STATUS_INVALID_DATA) ++ return -EINVAL; ++ if (res) ++ return -EOPNOTSUPP; ++ return 0; ++} ++ ++static int iw_get_ndis_stats(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ struct iw_statistics *stats = &wnd->iw_stats; ++ memcpy(&wrqu->qual, &stats->qual, sizeof(stats->qual)); ++ return 0; ++} ++ ++static int iw_get_range(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct iw_range *range = (struct iw_range *)extra; ++ struct iw_point *data = &wrqu->data; ++ struct ndis_device *wnd = netdev_priv(dev); ++ unsigned int i, n; ++ NDIS_STATUS res; ++ UCHAR rates[NDIS_MAX_RATES_EX]; ++ ndis_tx_power_level tx_power; ++ ++ ENTER2(""); ++ data->length = sizeof(struct iw_range); ++ memset(range, 0, sizeof(struct iw_range)); ++ ++ range->txpower_capa = IW_TXPOW_MWATT; ++ range->num_txpower = 0; ++ ++ res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, ++ &tx_power, sizeof(tx_power)); ++ if (!res) { ++ range->num_txpower = 1; ++ range->txpower[0] = tx_power; ++ } ++ ++ range->we_version_compiled = WIRELESS_EXT; ++ range->we_version_source = 19; ++ ++ range->retry_capa = IW_RETRY_LIMIT; ++ range->retry_flags = IW_RETRY_LIMIT; ++ range->min_retry = 0; ++ range->max_retry = 255; ++ ++ range->num_channels = 1; ++ ++ range->max_qual.qual = 100; ++ range->max_qual.level = 154; ++ range->max_qual.noise = 154; ++ range->sensitivity = 3; ++ ++ range->max_encoding_tokens = 4; ++ range->num_encoding_sizes = 2; ++ range->encoding_size[0] = 5; ++ range->encoding_size[1] = 13; ++ ++ range->num_bitrates = 0; ++ memset(&rates, 0, sizeof(rates)); ++ res = mp_query_info(wnd, OID_802_11_SUPPORTED_RATES, ++ &rates, sizeof(rates), &n, NULL); ++ if (res) ++ WARNING("getting bit rates failed: %08X", res); ++ else { ++ for (i = 0; i < n && range->num_bitrates < IW_MAX_BITRATES; i++) ++ if (rates[i] & 0x80) ++ continue; ++ else if (rates[i] & 0x7f) { ++ range->bitrate[range->num_bitrates] = ++ (rates[i] & 0x7f) * 500000; ++ range->num_bitrates++; ++ } ++ } ++ ++ range->num_channels = ARRAY_SIZE(freq_chan); ++ ++ for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) { ++ range->freq[i].i = i + 1; ++ range->freq[i].m = freq_chan[i] * 100000; ++ range->freq[i].e = 1; ++ } ++ range->num_frequency = i; ++ ++ range->min_rts = 0; ++ range->max_rts = 2347; ++ range->min_frag = 256; ++ range->max_frag = 2346; ++ ++ /* Event capability (kernel + driver) */ ++ range->event_capa[0] = (IW_EVENT_CAPA_K_0 | ++ IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) | ++ IW_EVENT_CAPA_MASK(SIOCGIWAP) | ++ IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); ++ range->event_capa[1] = IW_EVENT_CAPA_K_1; ++ range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) | ++ IW_EVENT_CAPA_MASK(IWEVCUSTOM) | ++ IW_EVENT_CAPA_MASK(IWEVREGISTERED) | ++ IW_EVENT_CAPA_MASK(IWEVEXPIRED)); ++ ++ range->enc_capa = 0; ++ ++ if (test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr)) ++ range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; ++ if (test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr)) ++ range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; ++ ++ if (test_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth) || ++ test_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth)) ++ range->enc_capa |= IW_ENC_CAPA_WPA; ++ if (test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) || ++ test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth)) ++ range->enc_capa |= IW_ENC_CAPA_WPA2; ++ ++ return 0; ++} ++ ++void set_default_iw_params(struct ndis_device *wnd) ++{ ++ wnd->iw_auth_key_mgmt = 0; ++ wnd->iw_auth_wpa_version = 0; ++ set_infra_mode(wnd, Ndis802_11Infrastructure); ++ set_ndis_auth_mode(wnd, Ndis802_11AuthModeOpen); ++ set_priv_filter(wnd); ++ set_iw_encr_mode(wnd, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE); ++} ++ ++static int deauthenticate(struct ndis_device *wnd) ++{ ++ int ret; ++ ++ ENTER2(""); ++ ret = disassociate(wnd, 1); ++ set_default_iw_params(wnd); ++ EXIT2(return ret); ++} ++ ++NDIS_STATUS disassociate(struct ndis_device *wnd, int reset_ssid) ++{ ++ NDIS_STATUS res; ++ u8 buf[NDIS_ESSID_MAX_SIZE]; ++ int i; ++ ++ TRACE2(""); ++ res = mp_set(wnd, OID_802_11_DISASSOCIATE, NULL, 0); ++ /* disassociate causes radio to be turned off; if reset_ssid ++ * is given, set ssid to random to enable radio */ ++ if (reset_ssid) { ++ get_random_bytes(buf, sizeof(buf)); ++ for (i = 0; i < sizeof(buf); i++) ++ buf[i] = 'a' + (buf[i] % 26); ++ set_essid(wnd, buf, sizeof(buf)); ++ } ++ return res; ++} ++ ++static int iw_set_mlme(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ struct iw_mlme *mlme = (struct iw_mlme *)extra; ++ ++ ENTER2(""); ++ switch (mlme->cmd) { ++ case IW_MLME_DEAUTH: ++ return deauthenticate(wnd); ++ case IW_MLME_DISASSOC: ++ TRACE2("cmd=%d reason_code=%d", mlme->cmd, mlme->reason_code); ++ return disassociate(wnd, 1); ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static int iw_set_genie(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ /* ++ * NDIS drivers do not allow IEs to be configured; this is ++ * done by the driver based on other configuration. Return 0 ++ * to avoid causing issues with user space programs that ++ * expect this function to succeed. ++ */ ++ return 0; ++} ++ ++static int iw_set_auth(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ TRACE2("index=%d value=%d", wrqu->param.flags & IW_AUTH_INDEX, ++ wrqu->param.value); ++ switch (wrqu->param.flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++ wnd->iw_auth_wpa_version = wrqu->param.value; ++ break; ++ case IW_AUTH_CIPHER_PAIRWISE: ++ wnd->iw_auth_cipher_pairwise = wrqu->param.value; ++ break; ++ case IW_AUTH_CIPHER_GROUP: ++ wnd->iw_auth_cipher_group = wrqu->param.value; ++ break; ++ case IW_AUTH_KEY_MGMT: ++ wnd->iw_auth_key_mgmt = wrqu->param.value; ++ break; ++ case IW_AUTH_80211_AUTH_ALG: ++ wnd->iw_auth_80211_alg = wrqu->param.value; ++ break; ++ case IW_AUTH_WPA_ENABLED: ++ if (wrqu->param.value) ++ deauthenticate(wnd); ++ break; ++#ifdef IW_AUTH_MFP ++ case IW_AUTH_MFP: ++ if (wrqu->param.value == IW_AUTH_MFP_DISABLED || ++ wrqu->param.value == IW_AUTH_MFP_OPTIONAL) ++ break; ++ WARNING("MFP not implemented"); ++ return -EOPNOTSUPP; ++#endif ++ case IW_AUTH_TKIP_COUNTERMEASURES: ++ case IW_AUTH_DROP_UNENCRYPTED: ++ case IW_AUTH_RX_UNENCRYPTED_EAPOL: ++ case IW_AUTH_PRIVACY_INVOKED: ++ TRACE2("%d not implemented: %d", ++ wrqu->param.flags & IW_AUTH_INDEX, wrqu->param.value); ++ break; ++ default: ++ WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX); ++ return -EOPNOTSUPP; ++ } ++ return 0; ++} ++ ++static int iw_get_auth(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ++ ENTER2("index=%d", wrqu->param.flags & IW_AUTH_INDEX); ++ switch (wrqu->param.flags & IW_AUTH_INDEX) { ++ case IW_AUTH_WPA_VERSION: ++ wrqu->param.value = wnd->iw_auth_wpa_version; ++ break; ++ case IW_AUTH_CIPHER_PAIRWISE: ++ wrqu->param.value = wnd->iw_auth_cipher_pairwise; ++ break; ++ case IW_AUTH_CIPHER_GROUP: ++ wrqu->param.value = wnd->iw_auth_cipher_group; ++ break; ++ case IW_AUTH_KEY_MGMT: ++ wrqu->param.value = wnd->iw_auth_key_mgmt; ++ break; ++ case IW_AUTH_80211_AUTH_ALG: ++ wrqu->param.value = wnd->iw_auth_80211_alg; ++ break; ++ default: ++ WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX); ++ return -EOPNOTSUPP; ++ } ++ return 0; ++} ++ ++static int iw_set_encodeext(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; ++ struct ndis_device *wnd = netdev_priv(dev); ++ struct ndis_add_key ndis_key; ++ int i, keyidx; ++ NDIS_STATUS res; ++ u8 *addr; ++ ++ keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; ++ ENTER2("%d", keyidx); ++ if (keyidx) ++ keyidx--; ++ else ++ keyidx = wnd->encr_info.tx_key_index; ++ ++ if (keyidx < 0 || keyidx >= MAX_ENCR_KEYS) ++ return -EINVAL; ++ ++ if (ext->alg == WPA_ALG_WEP) { ++ if (!test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr)) ++ EXIT2(return -1); ++ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) ++ wnd->encr_info.tx_key_index = keyidx; ++ if (add_wep_key(wnd, ext->key, ext->key_len, keyidx)) ++ EXIT2(return -1); ++ else ++ EXIT2(return 0); ++ } ++ if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) || ++ ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0) ++ EXIT2(return remove_key(wnd, keyidx, ndis_key.bssid)); ++ ++ if (ext->key_len > sizeof(ndis_key.key)) { ++ TRACE2("incorrect key length (%u)", ext->key_len); ++ EXIT2(return -1); ++ } ++ ++ memset(&ndis_key, 0, sizeof(ndis_key)); ++ ++ ndis_key.struct_size = ++ sizeof(ndis_key) - sizeof(ndis_key.key) + ext->key_len; ++ ndis_key.length = ext->key_len; ++ ndis_key.index = keyidx; ++ ++ if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { ++ for (i = 0; i < 6; i++) ++ ndis_key.rsc |= (((u64)ext->rx_seq[i]) << (i * 8)); ++ TRACE2("0x%llx", ndis_key.rsc); ++ ndis_key.index |= 1 << 29; ++ } ++ ++ addr = ext->addr.sa_data; ++ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { ++ /* group key */ ++ if (wnd->infrastructure_mode == Ndis802_11IBSS) ++ memset(ndis_key.bssid, 0xff, ETH_ALEN); ++ else ++ get_ap_address(wnd, ndis_key.bssid); ++ } else { ++ /* pairwise key */ ++ ndis_key.index |= (1 << 30); ++ memcpy(ndis_key.bssid, addr, ETH_ALEN); ++ } ++ TRACE2(MACSTRSEP, MAC2STR(ndis_key.bssid)); ++ ++ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) ++ ndis_key.index |= (1 << 31); ++ ++ if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) { ++ /* wpa_supplicant gives us the Michael MIC RX/TX keys in ++ * different order than NDIS spec, so swap the order here. */ ++ memcpy(ndis_key.key, ext->key, 16); ++ memcpy(ndis_key.key + 16, ext->key + 24, 8); ++ memcpy(ndis_key.key + 24, ext->key + 16, 8); ++ } else ++ memcpy(ndis_key.key, ext->key, ext->key_len); ++ ++ res = mp_set(wnd, OID_802_11_ADD_KEY, &ndis_key, ndis_key.struct_size); ++ if (res) { ++ TRACE2("adding key failed (%08X), %u", ++ res, ndis_key.struct_size); ++ EXIT2(return -1); ++ } ++ wnd->encr_info.keys[keyidx].length = ext->key_len; ++ memcpy(&wnd->encr_info.keys[keyidx].key, ndis_key.key, ext->key_len); ++ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) ++ wnd->encr_info.tx_key_index = keyidx; ++ TRACE2("key %d added", keyidx); ++ ++ EXIT2(return 0); ++} ++ ++static int iw_get_encodeext(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ /* struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; */ ++ /* TODO */ ++ ENTER2(""); ++ return 0; ++} ++ ++static int iw_set_pmksa(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct iw_pmksa *pmksa = (struct iw_pmksa *)extra; ++ struct ndis_pmkid pmkid; ++ NDIS_STATUS res; ++ struct ndis_device *wnd = netdev_priv(dev); ++ ++ /* TODO: must keep local list of PMKIDs since NDIS drivers ++ * expect that all PMKID entries are included whenever a new ++ * one is added. */ ++ ++ ENTER2("%d", pmksa->cmd); ++ if ((pmksa->cmd == IW_PMKSA_ADD || pmksa->cmd == IW_PMKSA_REMOVE) && ++ (!(wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2))) ++ EXIT2(return -EOPNOTSUPP); ++ ++ memset(&pmkid, 0, sizeof(pmkid)); ++ if (pmksa->cmd == IW_PMKSA_ADD) { ++ pmkid.bssid_info_count = 1; ++ memcpy(pmkid.bssid_info[0].bssid, pmksa->bssid.sa_data, ++ ETH_ALEN); ++ memcpy(pmkid.bssid_info[0].pmkid, pmksa->pmkid, IW_PMKID_LEN); ++ } ++ pmkid.length = sizeof(pmkid); ++ ++ res = mp_set(wnd, OID_802_11_PMKID, &pmkid, pmkid.length); ++ if (res == NDIS_STATUS_FAILURE) ++ EXIT2(return -EOPNOTSUPP); ++ TRACE2("OID_802_11_PMKID -> %d", res); ++ if (res) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++#define WEXT(id) [id - SIOCIWFIRST] ++ ++static const iw_handler ndis_handler[] = { ++ WEXT(SIOCGIWNAME) = iw_get_network_type, ++ WEXT(SIOCSIWESSID) = iw_set_essid, ++ WEXT(SIOCGIWESSID) = iw_get_essid, ++ WEXT(SIOCSIWMODE) = iw_set_infra_mode, ++ WEXT(SIOCGIWMODE) = iw_get_infra_mode, ++ WEXT(SIOCGIWFREQ) = iw_get_freq, ++ WEXT(SIOCSIWFREQ) = iw_set_freq, ++ WEXT(SIOCGIWTXPOW) = iw_get_tx_power, ++ WEXT(SIOCSIWTXPOW) = iw_set_tx_power, ++ WEXT(SIOCGIWRATE) = iw_get_bitrate, ++ WEXT(SIOCSIWRATE) = iw_set_bitrate, ++ WEXT(SIOCGIWRTS) = iw_get_rts_threshold, ++ WEXT(SIOCSIWRTS) = iw_set_rts_threshold, ++ WEXT(SIOCGIWFRAG) = iw_get_frag_threshold, ++ WEXT(SIOCSIWFRAG) = iw_set_frag_threshold, ++ WEXT(SIOCGIWAP) = iw_get_ap_address, ++ WEXT(SIOCSIWAP) = iw_set_ap_address, ++ WEXT(SIOCSIWENCODE) = iw_set_wep, ++ WEXT(SIOCGIWENCODE) = iw_get_encr, ++ WEXT(SIOCSIWSCAN) = iw_set_scan, ++ WEXT(SIOCGIWSCAN) = iw_get_scan, ++ WEXT(SIOCGIWPOWER) = iw_get_power_mode, ++ WEXT(SIOCSIWPOWER) = iw_set_power_mode, ++ WEXT(SIOCGIWRANGE) = iw_get_range, ++ WEXT(SIOCGIWSTATS) = iw_get_ndis_stats, ++ WEXT(SIOCGIWSENS) = iw_get_sensitivity, ++ WEXT(SIOCSIWSENS) = iw_set_sensitivity, ++ WEXT(SIOCGIWNICKN) = iw_get_nick, ++ WEXT(SIOCSIWNICKN) = iw_set_nick, ++ WEXT(SIOCSIWCOMMIT) = iw_set_dummy, ++ WEXT(SIOCSIWMLME) = iw_set_mlme, ++ WEXT(SIOCSIWGENIE) = iw_set_genie, ++ WEXT(SIOCSIWAUTH) = iw_set_auth, ++ WEXT(SIOCGIWAUTH) = iw_get_auth, ++ WEXT(SIOCSIWENCODEEXT) = iw_set_encodeext, ++ WEXT(SIOCGIWENCODEEXT) = iw_get_encodeext, ++ WEXT(SIOCSIWPMKSA) = iw_set_pmksa, ++}; ++ ++/* private ioctl's */ ++ ++static int priv_reset(struct net_device *dev, struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int res; ++ ENTER2(""); ++ res = mp_reset(netdev_priv(dev)); ++ if (res) { ++ WARNING("reset failed: %08X", res); ++ return -EOPNOTSUPP; ++ } ++ return 0; ++} ++ ++static int priv_deauthenticate(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ int res; ++ ENTER2(""); ++ res = deauthenticate(netdev_priv(dev)); ++ return res; ++} ++ ++static int priv_power_profile(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ struct miniport *mp; ++ ULONG profile_inf; ++ ++ ENTER2(""); ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ if (!mp->pnp_event_notify) ++ EXIT2(return -EOPNOTSUPP); ++ ++ /* 1 for AC and 0 for Battery */ ++ if (wrqu->param.value) ++ profile_inf = NdisPowerProfileAcOnLine; ++ else ++ profile_inf = NdisPowerProfileBattery; ++ ++ LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx, ++ NdisDevicePnPEventPowerProfileChanged, ++ &profile_inf, sizeof(profile_inf)); ++ EXIT2(return 0); ++} ++ ++static int priv_network_type(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ enum network_type network_type; ++ NDIS_STATUS res; ++ char type; ++ ++ ENTER2(""); ++ type = wrqu->param.value; ++ if (type == 'f') ++ network_type = Ndis802_11FH; ++ else if (type == 'b') ++ network_type = Ndis802_11DS; ++ else if (type == 'a') ++ network_type = Ndis802_11OFDM5; ++ else if (type == 'g' || type == 'n') ++ network_type = Ndis802_11OFDM24; ++ else ++ network_type = Ndis802_11Automode; ++ ++ res = mp_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, network_type); ++ if (res) { ++ WARNING("setting network type to %d failed (%08X)", ++ network_type, res); ++ EXIT2(return -EINVAL); ++ } ++ ++ EXIT2(return 0); ++} ++ ++static int priv_media_stream_mode(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ NDIS_STATUS res; ++ int mode; ++ ++ ENTER2(""); ++ if (wrqu->param.value > 0) ++ mode = Ndis802_11MediaStreamOn; ++ else ++ mode = Ndis802_11MediaStreamOff; ++ res = mp_set_int(wnd, OID_802_11_MEDIA_STREAM_MODE, mode); ++ if (res) { ++ WARNING("oid failed (%08X)", res); ++ EXIT2(return -EINVAL); ++ } ++ EXIT2(return 0); ++} ++ ++static int priv_reload_defaults(struct net_device *dev, ++ struct iw_request_info *info, ++ union iwreq_data *wrqu, char *extra) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ int res; ++ ENTER2(""); ++ res = mp_set_int(wnd, OID_802_11_RELOAD_DEFAULTS, ++ Ndis802_11ReloadWEPKeys); ++ if (res) { ++ WARNING("reloading defaults failed: %08X", res); ++ return -EOPNOTSUPP; ++ } ++ return 0; ++} ++ ++static const struct iw_priv_args priv_args[] = { ++ {PRIV_RESET, 0, 0, "ndis_reset"}, ++ {PRIV_POWER_PROFILE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ++ "power_profile"}, ++ {PRIV_DEAUTHENTICATE, 0, 0, "deauthenticate"}, ++ {PRIV_NETWORK_TYPE, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, ++ "network_type"}, ++ {PRIV_MEDIA_STREAM_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ++ "media_stream"}, ++ ++ {PRIV_RELOAD_DEFAULTS, 0, 0, "reload_defaults"}, ++}; ++ ++#define WEPRIV(id) [id - SIOCIWFIRSTPRIV] ++ ++static const iw_handler priv_handler[] = { ++ WEPRIV(PRIV_RESET) = priv_reset, ++ WEPRIV(PRIV_POWER_PROFILE) = priv_power_profile, ++ WEPRIV(PRIV_DEAUTHENTICATE) = priv_deauthenticate, ++ WEPRIV(PRIV_NETWORK_TYPE) = priv_network_type, ++ WEPRIV(PRIV_MEDIA_STREAM_MODE) = priv_media_stream_mode, ++ WEPRIV(PRIV_RELOAD_DEFAULTS) = priv_reload_defaults, ++}; ++ ++const struct iw_handler_def ndis_handler_def = { ++ .num_standard = ARRAY_SIZE(ndis_handler), ++ .num_private = ARRAY_SIZE(priv_handler), ++ .num_private_args = ARRAY_SIZE(priv_args), ++ ++ .standard = (iw_handler *)ndis_handler, ++ .private = (iw_handler *)priv_handler, ++ .private_args = (struct iw_priv_args *)priv_args, ++ .get_wireless_stats = get_iw_stats, ++}; ++ ++#endif +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/iw_ndis.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/iw_ndis.h +--- linux-3.12.2/3rdparty/ndiswrapper/iw_ndis.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/iw_ndis.h 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,194 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _IW_NDIS_H_ ++#define _IW_NDIS_H_ ++ ++#include "ndis.h" ++ ++#define WL_NOISE -96 /* typical noise level in dBm */ ++#define WL_SIGMAX -32 /* typical maximum signal level in dBm */ ++ ++struct ndis_encr_key { ++ ULONG struct_size; ++ ULONG index; ++ ULONG length; ++ UCHAR key[NDIS_ENCODING_TOKEN_MAX]; ++}; ++ ++struct ndis_add_key { ++ ULONG struct_size; ++ ndis_key_index index; ++ ULONG length; ++ mac_address bssid; ++ UCHAR pad[6]; ++ ndis_key_rsc rsc; ++ UCHAR key[NDIS_ENCODING_TOKEN_MAX]; ++}; ++ ++struct ndis_remove_key { ++ ULONG struct_size; ++ ndis_key_index index; ++ mac_address bssid; ++}; ++ ++struct ndis_fixed_ies { ++ UCHAR time_stamp[8]; ++ USHORT beacon_interval; ++ USHORT capa; ++}; ++ ++struct ndis_variable_ies { ++ UCHAR elem_id; ++ UCHAR length; ++ UCHAR data[]; ++}; ++ ++enum ndis_reload_defaults { Ndis802_11ReloadWEPKeys }; ++ ++struct ndis_assoc_info { ++ ULONG length; ++ USHORT req_ies; ++ struct req_ie { ++ USHORT capa; ++ USHORT listen_interval; ++ mac_address cur_ap_address; ++ } req_ie; ++ ULONG req_ie_length; ++ ULONG offset_req_ies; ++ USHORT resp_ies; ++ struct resp_ie { ++ USHORT capa; ++ USHORT status_code; ++ USHORT assoc_id; ++ } resp_ie; ++ ULONG resp_ie_length; ++ ULONG offset_resp_ies; ++}; ++ ++struct ndis_configuration_fh { ++ ULONG length; ++ ULONG hop_pattern; ++ ULONG hop_set; ++ ULONG dwell_time; ++}; ++ ++struct ndis_configuration { ++ ULONG length; ++ ULONG beacon_period; ++ ULONG atim_window; ++ ULONG ds_config; ++ struct ndis_configuration_fh fh_config; ++}; ++ ++struct ndis_wlan_bssid { ++ ULONG length; ++ mac_address mac; ++ UCHAR reserved[2]; ++ struct ndis_essid ssid; ++ ULONG privacy; ++ ndis_rssi rssi; ++ UINT net_type; ++ struct ndis_configuration config; ++ UINT mode; ++ UCHAR rates[NDIS_MAX_RATES]; ++}; ++ ++struct ndis_wlan_bssid_ex { ++ ULONG length; ++ mac_address mac; ++ UCHAR reserved[2]; ++ struct ndis_essid ssid; ++ ULONG privacy; ++ ndis_rssi rssi; ++ UINT net_type; ++ struct ndis_configuration config; ++ UINT mode; ++ UCHAR rates_ex[NDIS_MAX_RATES_EX]; ++ ULONG ie_length; ++ struct ndis_fixed_ies fixed; ++ struct ndis_variable_ies var[]; ++}; ++ ++/* we use bssid_list as bssid_list_ex also */ ++struct ndis_bssid_list { ++ ULONG num_items; ++ struct ndis_wlan_bssid bssid[1]; ++}; ++ ++enum ndis_priv_filter { ++ Ndis802_11PrivFilterAcceptAll, Ndis802_11PrivFilter8021xWEP ++}; ++ ++enum network_type { ++ Ndis802_11FH, Ndis802_11DS, Ndis802_11OFDM5, Ndis802_11OFDM24, ++ /* MSDN site uses Ndis802_11Automode, which is not mentioned ++ * in DDK, so add one and assign it to ++ * Ndis802_11NetworkTypeMax */ ++ Ndis802_11Automode, Ndis802_11NetworkTypeMax = Ndis802_11Automode ++}; ++ ++struct network_type_list { ++ ULONG num; ++ enum network_type types[1]; ++}; ++ ++enum ndis_power { ++ NDIS_POWER_OFF = 0, NDIS_POWER_MAX, NDIS_POWER_MIN, ++}; ++ ++struct ndis_auth_req { ++ ULONG length; ++ mac_address bssid; ++ ULONG flags; ++}; ++ ++struct ndis_bssid_info { ++ mac_address bssid; ++ UCHAR pmkid[IW_PMKID_LEN]; ++}; ++ ++struct ndis_pmkid { ++ ULONG length; ++ ULONG bssid_info_count; ++ struct ndis_bssid_info bssid_info[1]; ++}; ++ ++int get_ap_address(struct ndis_device *wnd, mac_address mac); ++int set_ndis_auth_mode(struct ndis_device *wnd, ULONG auth_mode); ++int get_ndis_encr_mode(struct ndis_device *wnd); ++int set_iw_encr_mode(struct ndis_device *wnd, int cipher_pairwise, ++ int cipher_groupwise); ++int get_ndis_auth_mode(struct ndis_device *wnd); ++NDIS_STATUS disassociate(struct ndis_device *wnd, int reset_ssid); ++void set_default_iw_params(struct ndis_device *wnd); ++extern const struct iw_handler_def ndis_handler_def; ++ ++#define PRIV_RESET SIOCIWFIRSTPRIV+16 ++#define PRIV_POWER_PROFILE SIOCIWFIRSTPRIV+17 ++#define PRIV_NETWORK_TYPE SIOCIWFIRSTPRIV+18 ++#define PRIV_DEAUTHENTICATE SIOCIWFIRSTPRIV+19 ++#define PRIV_MEDIA_STREAM_MODE SIOCIWFIRSTPRIV+20 ++#define PRIV_RELOAD_DEFAULTS SIOCIWFIRSTPRIV+23 ++ ++/* these have to match what is in wpa_supplicant */ ++ ++enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; ++enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, ++ CIPHER_WEP104 }; ++enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, ++ KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE }; ++ ++#endif // IW_NDIS_H +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/lin2win.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/lin2win.h +--- linux-3.12.2/3rdparty/ndiswrapper/lin2win.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/lin2win.h 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,111 @@ ++/* ++ * Copyright (C) 2006 Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifdef CONFIG_X86_64 ++ ++u64 lin2win0(void *func); ++u64 lin2win1(void *func, u64 arg1); ++u64 lin2win2(void *func, u64 arg1, u64 arg2); ++u64 lin2win3(void *func, u64 arg1, u64 arg2, u64 arg3); ++u64 lin2win4(void *func, u64 arg1, u64 arg2, u64 arg3, u64 arg4); ++u64 lin2win5(void *func, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5); ++u64 lin2win6(void *func, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, ++ u64 arg6); ++ ++#define LIN2WIN0(func) \ ++({ \ ++ if (0) \ ++ func(); \ ++ lin2win0(func); \ ++}) ++ ++#define LIN2WIN1(func, arg1) \ ++({ \ ++ if (0) \ ++ func(arg1); \ ++ lin2win1(func, (u64)arg1); \ ++}) ++ ++#define LIN2WIN2(func, arg1, arg2) \ ++({ \ ++ if (0) \ ++ func(arg1, arg2); \ ++ lin2win2(func, (u64)arg1, (u64)arg2); \ ++}) ++ ++#define LIN2WIN3(func, arg1, arg2, arg3) \ ++({ \ ++ if (0) \ ++ func(arg1, arg2, arg3); \ ++ lin2win3(func, (u64)arg1, (u64)arg2, (u64)arg3); \ ++}) ++ ++#define LIN2WIN4(func, arg1, arg2, arg3, arg4) \ ++({ \ ++ if (0) \ ++ func(arg1, arg2, arg3, arg4); \ ++ lin2win4(func, (u64)arg1, (u64)arg2, (u64)arg3, (u64)arg4); \ ++}) ++ ++#define LIN2WIN5(func, arg1, arg2, arg3, arg4, arg5) \ ++({ \ ++ if (0) \ ++ func(arg1, arg2, arg3, arg4, arg5); \ ++ lin2win5(func, (u64)arg1, (u64)arg2, (u64)arg3, (u64)arg4, \ ++ (u64)arg5); \ ++}) ++ ++#define LIN2WIN6(func, arg1, arg2, arg3, arg4, arg5, arg6) \ ++({ \ ++ if (0) \ ++ func(arg1, arg2, arg3, arg4, arg5, arg6); \ ++ lin2win6(func, (u64)arg1, (u64)arg2, (u64)arg3, (u64)arg4, \ ++ (u64)arg5, (u64)arg6); \ ++}) ++ ++#else // CONFIG_X86_64 ++ ++#define LIN2WIN1(func, arg1) \ ++({ \ ++ TRACE6("calling %p", func); \ ++ func(arg1); \ ++}) ++#define LIN2WIN2(func, arg1, arg2) \ ++({ \ ++ TRACE6("calling %p", func); \ ++ func(arg1, arg2); \ ++}) ++#define LIN2WIN3(func, arg1, arg2, arg3) \ ++({ \ ++ TRACE6("calling %p", func); \ ++ func(arg1, arg2, arg3); \ ++}) ++#define LIN2WIN4(func, arg1, arg2, arg3, arg4) \ ++({ \ ++ TRACE6("calling %p", func); \ ++ func(arg1, arg2, arg3, arg4); \ ++}) ++#define LIN2WIN5(func, arg1, arg2, arg3, arg4, arg5) \ ++({ \ ++ TRACE6("calling %p", func); \ ++ func(arg1, arg2, arg3, arg4, arg5); \ ++}) ++#define LIN2WIN6(func, arg1, arg2, arg3, arg4, arg5, arg6) \ ++({ \ ++ TRACE6("calling %p", func); \ ++ func(arg1, arg2, arg3, arg4, arg5, arg6); \ ++}) ++ ++#endif // CONFIG_X86_64 +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/lin2win.S linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/lin2win.S +--- linux-3.12.2/3rdparty/ndiswrapper/lin2win.S 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/lin2win.S 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,138 @@ ++/* ++ * Copyright (C) 2011 Pavel Roskin ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++ ++ .text ++ ++#define WORD_BYTES 8 ++#define LINUX_REG_ARGS 6 ++#define WINDOWS_REG_ARGS 4 ++ ++/* %rbp is saved to create a stack frame, which can help with debugging */ ++#define SAVED_REGS 1 ++ ++/* ++ * When calling a Windows function, stack space is allocated for at least 4 ++ * arguments even if the number of arguments is less than 4. The value of ++ * true is -1 in assembler, so we multiply it by another true value. ++ */ ++#define stack_args(argc) \ ++ (WINDOWS_REG_ARGS + \ ++ (0 < 1) * (argc > WINDOWS_REG_ARGS) * (argc - WINDOWS_REG_ARGS)) ++ ++/* Full required change of stack pointer, in words */ ++#define stack_words_raw(argc) (stack_args(argc) + SAVED_REGS + 1) ++ ++/* Full actual change of stack pointer, in words (must be even) */ ++#define stack_words_aligned(argc) ((stack_words_raw(argc) + 1) & ~1) ++ ++/* Space allocated for Linux arguments on stack */ ++#define stack_space(argc) \ ++ ((stack_words_aligned(argc) - SAVED_REGS - 1) * WORD_BYTES) ++ ++/* ++ * lin2win_win_arg(N) gives the address of the Nth Windows argument on our ++ * stack frame. %rsp points to the first argument. The Nth argument is ++ * therefore at ((N - 1) * 8)(%rsp). ++ * ++ * Don't call with N less than 5! ++ */ ++#define lin2win_win_arg(n) ((n - 1) * WORD_BYTES)(%rsp) ++ ++/* ++ * lin2win_lin_arg(N, ARGC) gives the address of the Nth Linux argument after ++ * the stack has been prepared for a Windows function call with ARGC arguments. ++ * ++ * When called from Linux, the Nth argument is at ((N - 6) * 8)(%rsp). We add ++ * the allocated stack space and saved registers to compensate for %rsp change. ++ * ++ * Don't call with N less than 7! ++ */ ++#define lin2win_lin_arg(n, argc) \ ++ (stack_space(argc) + \ ++ (SAVED_REGS + n - LINUX_REG_ARGS) * WORD_BYTES)(%rsp) ++ ++/* ++ * lin2win(func, winarg1, winarg2, ...) ++ * Call Windows FUNC function with ARGC arguments WINARG1, WINARG2, ... ++ * We get (ARGC + 1) arguments. ++ */ ++.macro lin2win name, argc ++ .type \name, @function ++ ENTRY(\name) ++ ++ /* Create a call frame - it's optional, but good for debugging */ ++ .cfi_startproc ++ push %rbp ++ .cfi_def_cfa %rsp, 2 * WORD_BYTES ++ .cfi_offset %rbp, -2 * WORD_BYTES ++ mov %rsp, %rbp ++ .cfi_def_cfa %rbp, 2 * WORD_BYTES ++ ++ /* Allocate space for Windows arguments */ ++ sub $stack_space(\argc), %rsp ++ ++ /* arg7 to winarg6 */ ++ .if (\argc >= 6) ++ mov lin2win_lin_arg(7, \argc), %r11 ++ mov %r11, lin2win_win_arg(6) ++ .endif ++ ++ /* arg6 to winarg5 */ ++ .if (\argc >= 5) ++ mov %r9, lin2win_win_arg(5) ++ .endif ++ ++ /* arg5 to winarg4 */ ++ .if (\argc >= 4) ++ mov %r8, %r9 ++ .endif ++ ++ /* arg4 to winarg3 */ ++ .if (\argc >= 3) ++ mov %rcx, %r8 ++ .endif ++ ++ /* arg3 to winarg2 - nothing needed, both are in %rdx */ ++ ++ /* arg2 to winarg1 */ ++ .if (\argc >= 1) ++ mov %rsi, %rcx ++ .endif ++ ++ /* Call function (arg1) */ ++ call *%rdi ++ ++ /* Reclaim space for Windows arguments */ ++ add $stack_space(\argc), %rsp ++ ++ /* Return to the caller */ ++ leave ++ .cfi_def_cfa %rsp, WORD_BYTES ++ .cfi_restore %rbp ++ ret ++ .cfi_endproc ++ .size \name, (. - \name) ++.endm ++ ++/* Define lin2winN functions */ ++lin2win lin2win0, 0 ++lin2win lin2win1, 1 ++lin2win lin2win2, 2 ++lin2win lin2win3, 3 ++lin2win lin2win4, 4 ++lin2win lin2win5, 5 ++lin2win lin2win6, 6 +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/loader.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/loader.c +--- linux-3.12.2/3rdparty/ndiswrapper/loader.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/loader.c 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,967 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ndis.h" ++#include "loader.h" ++#include "wrapndis.h" ++#include "pnp.h" ++ ++#include ++#include ++#include ++#include ++ ++/* ++ Network adapter: ClassGuid = {4d36e972-e325-11ce-bfc1-08002be10318} ++ Network client: ClassGuid = {4d36e973-e325-11ce-bfc1-08002be10318} ++ PCMCIA adapter: ClassGuid = {4d36e977-e325-11ce-bfc1-08002be10318} ++ USB: ClassGuid = {36fc9e60-c465-11cf-8056-444553540000} ++*/ ++ ++/* the indices used here must match macros WRAP_NDIS_DEVICE etc. */ ++static struct guid class_guids[] = { ++ /* Network */ ++ { .data1 = 0x4d36e972, .data2 = 0xe325, .data3 = 0x11ce }, ++ /* USB WDM */ ++ { .data1 = 0x36fc9e60, .data2 = 0xc465, .data3 = 0x11cf }, ++ /* Bluetooth */ ++ { .data1 = 0xe0cbf06c, .data2 = 0xcd8b, .data3 = 0x4647 }, ++ /* ivtcorporation.com's bluetooth device claims this is ++ * bluetooth guid */ ++ { .data1 = 0xf12d3cf8, .data2 = 0xb11d, .data3 = 0x457e}, ++}; ++ ++struct mutex loader_mutex; ++static struct completion loader_complete; ++ ++static struct nt_list wrap_devices; ++static struct nt_list wrap_drivers; ++ ++static int wrap_device_type(int data1) ++{ ++ int i; ++ for (i = 0; i < ARRAY_SIZE(class_guids); i++) ++ if (data1 == class_guids[i].data1) ++ return i; ++ ERROR("unknown device: 0x%x\n", data1); ++ return -1; ++} ++ ++/* load driver for given device, if not already loaded */ ++struct wrap_driver *load_wrap_driver(struct wrap_device *wd) ++{ ++ int ret; ++ struct nt_list *cur; ++ struct wrap_driver *wrap_driver; ++ ++ ENTER1("device: %04X:%04X:%04X:%04X", wd->vendor, wd->device, ++ wd->subvendor, wd->subdevice); ++ mutex_lock(&loader_mutex); ++ wrap_driver = NULL; ++ nt_list_for_each(cur, &wrap_drivers) { ++ wrap_driver = container_of(cur, struct wrap_driver, list); ++ if (!stricmp(wrap_driver->name, wd->driver_name)) { ++ TRACE1("driver %s already loaded", wrap_driver->name); ++ break; ++ } else ++ wrap_driver = NULL; ++ } ++ mutex_unlock(&loader_mutex); ++ ++ if (!wrap_driver) { ++ char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_DRIVER, ++#if DEBUG >= 1 ++ "1", ++#else ++ "0", ++#endif ++ UTILS_VERSION, wd->driver_name, ++ wd->conf_file_name, NULL}; ++ char *env[] = {NULL}; ++ ++ TRACE1("loading driver %s", wd->driver_name); ++ mutex_lock(&loader_mutex); ++ reinit_completion(&loader_complete); ++ ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, ++ UMH_WAIT_PROC); ++ if (ret) { ++ mutex_unlock(&loader_mutex); ++ ERROR("couldn't load driver %s; check system log " ++ "for messages from 'loadndisdriver'", ++ wd->driver_name); ++ EXIT1(return NULL); ++ } ++ wait_for_completion(&loader_complete); ++ TRACE1("%s", wd->driver_name); ++ wrap_driver = NULL; ++ nt_list_for_each(cur, &wrap_drivers) { ++ wrap_driver = container_of(cur, struct wrap_driver, ++ list); ++ if (!stricmp(wrap_driver->name, wd->driver_name)) { ++ wd->driver = wrap_driver; ++ break; ++ } else ++ wrap_driver = NULL; ++ } ++ mutex_unlock(&loader_mutex); ++ if (wrap_driver) ++ TRACE1("driver %s is loaded", wrap_driver->name); ++ else ++ ERROR("couldn't load driver '%s'", wd->driver_name); ++ } ++ EXIT1(return wrap_driver); ++} ++ ++/* load the driver files from userspace. */ ++static int load_sys_files(struct wrap_driver *driver, ++ struct load_driver *load_driver) ++{ ++ int i, err; ++ ++ TRACE1("num_pe_images = %d", load_driver->num_sys_files); ++ TRACE1("loading driver: %s", load_driver->name); ++ strncpy(driver->name, load_driver->name, sizeof(driver->name)); ++ driver->name[sizeof(driver->name)-1] = 0; ++ TRACE1("driver: %s", driver->name); ++ err = 0; ++ driver->num_pe_images = 0; ++ for (i = 0; i < load_driver->num_sys_files; i++) { ++ struct pe_image *pe_image; ++ pe_image = &driver->pe_images[driver->num_pe_images]; ++ ++ strncpy(pe_image->name, load_driver->sys_files[i].name, ++ sizeof(pe_image->name)); ++ pe_image->name[sizeof(pe_image->name)-1] = 0; ++ TRACE1("image size: %zu bytes", load_driver->sys_files[i].size); ++ ++#ifdef CONFIG_X86_64 ++#ifdef PAGE_KERNEL_EXECUTABLE ++ pe_image->image = ++ __vmalloc(load_driver->sys_files[i].size, ++ GFP_KERNEL | __GFP_HIGHMEM, ++ PAGE_KERNEL_EXECUTABLE); ++#elif defined PAGE_KERNEL_EXEC ++ pe_image->image = ++ __vmalloc(load_driver->sys_files[i].size, ++ GFP_KERNEL | __GFP_HIGHMEM, ++ PAGE_KERNEL_EXEC); ++#else ++#error x86_64 should have either PAGE_KERNEL_EXECUTABLE or PAGE_KERNEL_EXEC ++#endif ++#else ++ /* hate to play with kernel macros, but PAGE_KERNEL_EXEC is ++ * not available to modules! */ ++#ifdef cpu_has_nx ++ if (cpu_has_nx) ++ pe_image->image = ++ __vmalloc(load_driver->sys_files[i].size, ++ GFP_KERNEL | __GFP_HIGHMEM, ++ __pgprot(__PAGE_KERNEL & ~_PAGE_NX)); ++ else ++ pe_image->image = ++ vmalloc(load_driver->sys_files[i].size); ++#else ++ pe_image->image = ++ vmalloc(load_driver->sys_files[i].size); ++#endif ++#endif ++ if (!pe_image->image) { ++ ERROR("couldn't allocate memory"); ++ err = -ENOMEM; ++ break; ++ } ++ TRACE1("image is at %p", pe_image->image); ++ ++ if (copy_from_user(pe_image->image, ++ load_driver->sys_files[i].data, ++ load_driver->sys_files[i].size)) { ++ ERROR("couldn't load file %s", ++ load_driver->sys_files[i].name); ++ err = -EFAULT; ++ break; ++ } ++ pe_image->size = load_driver->sys_files[i].size; ++ driver->num_pe_images++; ++ } ++ ++ if (!err && link_pe_images(driver->pe_images, driver->num_pe_images)) { ++ ERROR("couldn't prepare driver '%s'", load_driver->name); ++ err = -EINVAL; ++ } ++ ++ if (driver->num_pe_images < load_driver->num_sys_files || err) { ++ for (i = 0; i < driver->num_pe_images; i++) ++ if (driver->pe_images[i].image) ++ vfree(driver->pe_images[i].image); ++ driver->num_pe_images = 0; ++ EXIT1(return err); ++ } else ++ EXIT1(return 0); ++} ++ ++struct wrap_bin_file *get_bin_file(char *bin_file_name) ++{ ++ int i = 0; ++ struct wrap_driver *driver, *cur; ++ ++ ENTER1("%s", bin_file_name); ++ mutex_lock(&loader_mutex); ++ driver = NULL; ++ nt_list_for_each_entry(cur, &wrap_drivers, list) { ++ for (i = 0; i < cur->num_bin_files; i++) ++ if (!stricmp(cur->bin_files[i].name, bin_file_name)) { ++ driver = cur; ++ break; ++ } ++ if (driver) ++ break; ++ } ++ mutex_unlock(&loader_mutex); ++ if (!driver) { ++ TRACE1("couldn't find bin file '%s'", bin_file_name); ++ return NULL; ++ } ++ ++ if (!driver->bin_files[i].data) { ++ char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_BIN_FILE, ++#if DEBUG >= 1 ++ "1", ++#else ++ "0", ++#endif ++ UTILS_VERSION, driver->name, ++ driver->bin_files[i].name, NULL}; ++ char *env[] = {NULL}; ++ int ret; ++ ++ TRACE1("loading bin file %s/%s", driver->name, ++ driver->bin_files[i].name); ++ mutex_lock(&loader_mutex); ++ reinit_completion(&loader_complete); ++ ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, ++ UMH_WAIT_PROC); ++ if (ret) { ++ mutex_unlock(&loader_mutex); ++ ERROR("couldn't load file %s/%s; check system log " ++ "for messages from 'loadndisdriver' (%d)", ++ driver->name, driver->bin_files[i].name, ret); ++ EXIT1(return NULL); ++ } ++ wait_for_completion(&loader_complete); ++ mutex_unlock(&loader_mutex); ++ if (!driver->bin_files[i].data) { ++ WARNING("couldn't load binary file %s", ++ driver->bin_files[i].name); ++ EXIT1(return NULL); ++ } ++ } ++ EXIT2(return &(driver->bin_files[i])); ++} ++ ++/* called with loader_mutex down */ ++static int add_bin_file(struct load_driver_file *driver_file) ++{ ++ struct wrap_driver *driver, *cur; ++ struct wrap_bin_file *bin_file; ++ int i = 0; ++ ++ driver = NULL; ++ nt_list_for_each_entry(cur, &wrap_drivers, list) { ++ for (i = 0; i < cur->num_bin_files; i++) ++ if (!stricmp(cur->bin_files[i].name, ++ driver_file->name)) { ++ driver = cur; ++ break; ++ } ++ if (driver) ++ break; ++ } ++ if (!driver) { ++ ERROR("couldn't find %s", driver_file->name); ++ return -EINVAL; ++ } ++ bin_file = &driver->bin_files[i]; ++ strncpy(bin_file->name, driver_file->name, sizeof(bin_file->name)); ++ bin_file->name[sizeof(bin_file->name)-1] = 0; ++ bin_file->data = vmalloc(driver_file->size); ++ if (!bin_file->data) { ++ ERROR("couldn't allocate memory"); ++ return -ENOMEM; ++ } ++ bin_file->size = driver_file->size; ++ if (copy_from_user(bin_file->data, driver_file->data, bin_file->size)) { ++ ERROR("couldn't copy data"); ++ free_bin_file(bin_file); ++ return -EFAULT; ++ } ++ return 0; ++} ++ ++void free_bin_file(struct wrap_bin_file *bin_file) ++{ ++ TRACE2("unloading %s", bin_file->name); ++ if (bin_file->data) ++ vfree(bin_file->data); ++ bin_file->data = NULL; ++ bin_file->size = 0; ++ EXIT2(return); ++} ++ ++/* load firmware files from userspace */ ++static int load_bin_files_info(struct wrap_driver *driver, ++ struct load_driver *load_driver) ++{ ++ struct wrap_bin_file *bin_files; ++ int i; ++ ++ ENTER1("%s, %d", load_driver->name, load_driver->num_bin_files); ++ driver->num_bin_files = 0; ++ driver->bin_files = NULL; ++ if (load_driver->num_bin_files == 0) ++ EXIT1(return 0); ++ bin_files = kzalloc(load_driver->num_bin_files * sizeof(*bin_files), ++ GFP_KERNEL); ++ if (!bin_files) { ++ ERROR("couldn't allocate memory"); ++ EXIT1(return -ENOMEM); ++ } ++ ++ for (i = 0; i < load_driver->num_bin_files; i++) { ++ strncpy(bin_files[i].name, load_driver->bin_files[i].name, ++ sizeof(bin_files[i].name)); ++ bin_files[i].name[sizeof(bin_files[i].name)-1] = 0; ++ TRACE2("loaded bin file %s", bin_files[i].name); ++ } ++ driver->num_bin_files = load_driver->num_bin_files; ++ driver->bin_files = bin_files; ++ EXIT1(return 0); ++} ++ ++/* load settings for a device. called with loader_mutex down */ ++static int load_settings(struct wrap_driver *wrap_driver, ++ struct load_driver *load_driver) ++{ ++ int i, num_settings; ++ ++ ENTER1("%p, %p", wrap_driver, load_driver); ++ ++ num_settings = 0; ++ for (i = 0; i < load_driver->num_settings; i++) { ++ struct load_device_setting *load_setting = ++ &load_driver->settings[i]; ++ struct wrap_device_setting *setting; ++ ULONG data1; ++ ++ setting = kzalloc(sizeof(*setting), GFP_KERNEL); ++ if (!setting) { ++ ERROR("couldn't allocate memory"); ++ break; ++ } ++ strncpy(setting->name, load_setting->name, ++ sizeof(setting->name)); ++ setting->name[sizeof(setting->name)-1] = 0; ++ strncpy(setting->value, load_setting->value, ++ sizeof(setting->value)); ++ setting->value[sizeof(setting->value)-1] = 0; ++ TRACE2("%p: %s=%s", setting, setting->name, setting->value); ++ ++ if (strcmp(setting->name, "driver_version") == 0) { ++ strncpy(wrap_driver->version, setting->value, ++ sizeof(wrap_driver->version)); ++ wrap_driver->version[sizeof(wrap_driver->version)-1] = 0; ++ } else if (strcmp(setting->name, "class_guid") == 0 && ++ sscanf(setting->value, "%x", &data1) == 1) { ++ wrap_driver->dev_type = wrap_device_type(data1); ++ if (wrap_driver->dev_type < 0) { ++ WARNING("unknown guid: %x", data1); ++ wrap_driver->dev_type = 0; ++ } ++ } ++ InsertTailList(&wrap_driver->settings, &setting->list); ++ num_settings++; ++ } ++ /* it is not a fatal error if some settings couldn't be loaded */ ++ if (num_settings > 0) ++ EXIT1(return 0); ++ else ++ EXIT1(return -EINVAL); ++} ++ ++void unload_wrap_device(struct wrap_device *wd) ++{ ++ struct nt_list *cur; ++ ENTER1("unloading device %p (%04X:%04X:%04X:%04X), driver %s", wd, ++ wd->vendor, wd->device, wd->subvendor, wd->subdevice, ++ wd->driver_name); ++ mutex_lock(&loader_mutex); ++ while ((cur = RemoveHeadList(&wd->settings))) { ++ struct wrap_device_setting *setting; ++ setting = container_of(cur, struct wrap_device_setting, list); ++ kfree(setting); ++ } ++ RemoveEntryList(&wd->list); ++ mutex_unlock(&loader_mutex); ++ kfree(wd); ++ EXIT1(return); ++} ++ ++/* should be called with loader_mutex down */ ++void unload_wrap_driver(struct wrap_driver *driver) ++{ ++ int i; ++ struct driver_object *drv_obj; ++ struct nt_list *cur, *next; ++ ++ ENTER1("unloading driver: %s (%p)", driver->name, driver); ++ TRACE1("freeing %d images", driver->num_pe_images); ++ drv_obj = driver->drv_obj; ++ for (i = 0; i < driver->num_pe_images; i++) ++ if (driver->pe_images[i].image) { ++ TRACE1("freeing image at %p", ++ driver->pe_images[i].image); ++ vfree(driver->pe_images[i].image); ++ } ++ ++ TRACE1("freeing %d bin files", driver->num_bin_files); ++ for (i = 0; i < driver->num_bin_files; i++) { ++ TRACE1("freeing image at %p", driver->bin_files[i].data); ++ if (driver->bin_files[i].data) ++ vfree(driver->bin_files[i].data); ++ } ++ kfree(driver->bin_files); ++ RtlFreeUnicodeString(&drv_obj->name); ++ RemoveEntryList(&driver->list); ++ nt_list_for_each_safe(cur, next, &driver->settings) { ++ struct wrap_device_setting *setting; ++ struct ndis_configuration_parameter *param; ++ ++ setting = container_of(cur, struct wrap_device_setting, list); ++ TRACE2("%p", setting); ++ param = setting->encoded; ++ if (param) { ++ TRACE2("%p", param); ++ if (param->type == NdisParameterString) ++ RtlFreeUnicodeString(¶m->data.string); ++ ExFreePool(param); ++ } ++ kfree(setting); ++ } ++ /* this frees driver */ ++ free_custom_extensions(drv_obj->drv_ext); ++ kfree(drv_obj->drv_ext); ++ TRACE1("drv_obj: %p", drv_obj); ++ ++ EXIT1(return); ++} ++ ++/* call the entry point of the driver */ ++static int start_wrap_driver(struct wrap_driver *driver) ++{ ++ int i; ++ NTSTATUS ret, res; ++ struct driver_object *drv_obj; ++ typeof(driver->pe_images[0].entry) entry; ++ ++ ENTER1("%s", driver->name); ++ drv_obj = driver->drv_obj; ++ for (ret = res = 0, i = 0; i < driver->num_pe_images; i++) ++ /* dlls are already started by loader */ ++ if (driver->pe_images[i].type == IMAGE_FILE_EXECUTABLE_IMAGE) { ++ entry = driver->pe_images[i].entry; ++ drv_obj->start = driver->pe_images[i].entry; ++ drv_obj->driver_size = driver->pe_images[i].size; ++ TRACE1("entry: %p, %p, drv_obj: %p", ++ entry, *entry, drv_obj); ++ res = LIN2WIN2(entry, drv_obj, &drv_obj->name); ++ ret |= res; ++ TRACE1("entry returns %08X", res); ++ break; ++ } ++ if (ret) { ++ ERROR("driver initialization failed: %08X", ret); ++ RtlFreeUnicodeString(&drv_obj->name); ++ /* this frees ndis_driver */ ++ free_custom_extensions(drv_obj->drv_ext); ++ kfree(drv_obj->drv_ext); ++ TRACE1("drv_obj: %p", drv_obj); ++ ObDereferenceObject(drv_obj); ++ EXIT1(return -EINVAL); ++ } ++ EXIT1(return 0); ++} ++ ++/* ++ * add driver to list of loaded driver but make sure this driver is ++ * not loaded before. called with loader_mutex down ++ */ ++static int add_wrap_driver(struct wrap_driver *driver) ++{ ++ struct wrap_driver *tmp; ++ ++ ENTER1("name: %s", driver->name); ++ nt_list_for_each_entry(tmp, &wrap_drivers, list) { ++ if (stricmp(tmp->name, driver->name) == 0) { ++ ERROR("cannot add duplicate driver"); ++ EXIT1(return -EBUSY); ++ } ++ } ++ InsertHeadList(&wrap_drivers, &driver->list); ++ EXIT1(return 0); ++} ++ ++/* load a driver from userspace and initialize it. called with ++ * loader_mutex down */ ++static int load_user_space_driver(struct load_driver *load_driver) ++{ ++ struct driver_object *drv_obj; ++ struct ansi_string ansi_reg; ++ struct wrap_driver *wrap_driver = NULL; ++ ++ ENTER1("%p", load_driver); ++ drv_obj = allocate_object(sizeof(*drv_obj), OBJECT_TYPE_DRIVER, NULL); ++ if (!drv_obj) { ++ ERROR("couldn't allocate memory"); ++ EXIT1(return -ENOMEM); ++ } ++ TRACE1("drv_obj: %p", drv_obj); ++ drv_obj->drv_ext = kzalloc(sizeof(*(drv_obj->drv_ext)), GFP_KERNEL); ++ if (!drv_obj->drv_ext) { ++ ERROR("couldn't allocate memory"); ++ ObDereferenceObject(drv_obj); ++ EXIT1(return -ENOMEM); ++ } ++ InitializeListHead(&drv_obj->drv_ext->custom_ext); ++ if (IoAllocateDriverObjectExtension(drv_obj, ++ (void *)WRAP_DRIVER_CLIENT_ID, ++ sizeof(*wrap_driver), ++ (void **)&wrap_driver) != ++ STATUS_SUCCESS) ++ EXIT1(return -ENOMEM); ++ TRACE1("driver: %p", wrap_driver); ++ memset(wrap_driver, 0, sizeof(*wrap_driver)); ++ InitializeListHead(&wrap_driver->list); ++ InitializeListHead(&wrap_driver->settings); ++ wrap_driver->drv_obj = drv_obj; ++ RtlInitAnsiString(&ansi_reg, "/tmp"); ++ if (RtlAnsiStringToUnicodeString(&drv_obj->name, &ansi_reg, TRUE) != ++ STATUS_SUCCESS) { ++ ERROR("couldn't initialize registry path"); ++ free_custom_extensions(drv_obj->drv_ext); ++ kfree(drv_obj->drv_ext); ++ TRACE1("drv_obj: %p", drv_obj); ++ ObDereferenceObject(drv_obj); ++ EXIT1(return -EINVAL); ++ } ++ strncpy(wrap_driver->name, load_driver->name, sizeof(wrap_driver->name)); ++ wrap_driver->name[sizeof(wrap_driver->name)-1] = 0; ++ if (load_sys_files(wrap_driver, load_driver) || ++ load_bin_files_info(wrap_driver, load_driver) || ++ load_settings(wrap_driver, load_driver) || ++ start_wrap_driver(wrap_driver) || ++ add_wrap_driver(wrap_driver)) { ++ unload_wrap_driver(wrap_driver); ++ ObDereferenceObject(drv_obj); ++ EXIT1(return -EINVAL); ++ } else { ++ printk(KERN_INFO "%s: driver %s (%s) loaded\n", ++ DRIVER_NAME, wrap_driver->name, wrap_driver->version); ++ add_taint(TAINT_PROPRIETARY_MODULE, LOCKDEP_NOW_UNRELIABLE); ++ EXIT1(return 0); ++ } ++} ++ ++static struct pci_device_id wrap_pci_id_table[] = { ++ { ++ .vendor = PCI_ANY_ID, ++ .device = PCI_ANY_ID, ++ .subvendor = PCI_ANY_ID, ++ .subdevice = PCI_ANY_ID, ++ .class = 0, ++ .class_mask = 0, ++ .driver_data = 0 ++ } ++}; ++ ++static struct pci_driver wrap_pci_driver = { ++ .name = DRIVER_NAME, ++ .id_table = wrap_pci_id_table, ++ .probe = wrap_pnp_start_pci_device, ++ .remove = wrap_pnp_remove_pci_device, ++ .suspend = wrap_pnp_suspend_pci_device, ++ .resume = wrap_pnp_resume_pci_device, ++}; ++ ++#ifdef ENABLE_USB ++static struct usb_device_id wrap_usb_id_table[] = { ++ { ++ .driver_info = 1 ++ }, ++}; ++ ++static struct usb_driver wrap_usb_driver = { ++ .name = DRIVER_NAME, ++ .id_table = wrap_usb_id_table, ++ .probe = wrap_pnp_start_usb_device, ++ .disconnect = wrap_pnp_remove_usb_device, ++ .suspend = wrap_pnp_suspend_usb_device, ++ .resume = wrap_pnp_resume_usb_device, ++}; ++#endif ++ ++/* register drivers for pci and usb */ ++static void register_devices(void) ++{ ++ int res; ++ ++ res = pci_register_driver(&wrap_pci_driver); ++ if (res < 0) { ++ ERROR("couldn't register pci driver: %d", res); ++ wrap_pci_driver.name = NULL; ++ } ++ ++#ifdef ENABLE_USB ++ res = usb_register(&wrap_usb_driver); ++ if (res < 0) { ++ ERROR("couldn't register usb driver: %d", res); ++ wrap_usb_driver.name = NULL; ++ } ++#endif ++ EXIT1(return); ++} ++ ++static void unregister_devices(void) ++{ ++ struct nt_list *cur, *next; ++ ++ mutex_lock(&loader_mutex); ++ nt_list_for_each_safe(cur, next, &wrap_devices) { ++ struct wrap_device *wd; ++ wd = container_of(cur, struct wrap_device, list); ++ set_bit(HW_DISABLED, &wd->hw_status); ++ } ++ mutex_unlock(&loader_mutex); ++ ++ if (wrap_pci_driver.name) ++ pci_unregister_driver(&wrap_pci_driver); ++#ifdef ENABLE_USB ++ if (wrap_usb_driver.name) ++ usb_deregister(&wrap_usb_driver); ++#endif ++} ++ ++struct wrap_device *load_wrap_device(struct load_device *load_device) ++{ ++ int ret; ++ struct nt_list *cur; ++ struct wrap_device *wd = NULL; ++ char vendor[5], device[5], subvendor[5], subdevice[5], bus[5]; ++ ++ ENTER1("%04x, %04x, %04x, %04x", load_device->vendor, ++ load_device->device, load_device->subvendor, ++ load_device->subdevice); ++ if (sprintf(vendor, "%04x", load_device->vendor) == 4 && ++ sprintf(device, "%04x", load_device->device) == 4 && ++ sprintf(subvendor, "%04x", load_device->subvendor) == 4 && ++ sprintf(subdevice, "%04x", load_device->subdevice) == 4 && ++ sprintf(bus, "%04x", load_device->bus) == 4) { ++ char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_DEVICE, ++#if DEBUG >= 1 ++ "1", ++#else ++ "0", ++#endif ++ UTILS_VERSION, vendor, device, ++ subvendor, subdevice, bus, NULL}; ++ char *env[] = {NULL}; ++ TRACE2("%s, %s, %s, %s, %s", vendor, device, ++ subvendor, subdevice, bus); ++ mutex_lock(&loader_mutex); ++ reinit_completion(&loader_complete); ++ ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, ++ UMH_WAIT_PROC); ++ if (ret) { ++ mutex_unlock(&loader_mutex); ++ TRACE1("couldn't load device %04x:%04x; check system " ++ "log for messages from 'loadndisdriver'", ++ load_device->vendor, load_device->device); ++ EXIT1(return NULL); ++ } ++ wait_for_completion(&loader_complete); ++ wd = NULL; ++ nt_list_for_each(cur, &wrap_devices) { ++ wd = container_of(cur, struct wrap_device, list); ++ TRACE2("%p, %04x, %04x, %04x, %04x", wd, wd->vendor, ++ wd->device, wd->subvendor, wd->subdevice); ++ if (wd->vendor == load_device->vendor && ++ wd->device == load_device->device) ++ break; ++ else ++ wd = NULL; ++ } ++ mutex_unlock(&loader_mutex); ++ } else ++ wd = NULL; ++ EXIT1(return wd); ++} ++ ++struct wrap_device *get_wrap_device(void *dev, int bus) ++{ ++ struct nt_list *cur; ++ struct wrap_device *wd; ++ ++ mutex_lock(&loader_mutex); ++ wd = NULL; ++ nt_list_for_each(cur, &wrap_devices) { ++ wd = container_of(cur, struct wrap_device, list); ++ if (bus == WRAP_PCI_BUS && ++ wrap_is_pci_bus(wd->dev_bus) && wd->pci.pdev == dev) ++ break; ++ else if (bus == WRAP_USB_BUS && ++ wrap_is_usb_bus(wd->dev_bus) && wd->usb.udev == dev) ++ break; ++ else ++ wd = NULL; ++ } ++ mutex_unlock(&loader_mutex); ++ return wd; ++} ++ ++/* called with loader_mutex is down */ ++static long wrapper_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct load_driver *load_driver; ++ struct load_device load_device; ++ struct load_driver_file load_bin_file; ++ int ret; ++ void __user *addr = (void __user *)arg; ++ ++ ENTER1("cmd: 0x%x", cmd); ++ ++ ret = 0; ++ switch (cmd) { ++ case WRAP_IOCTL_LOAD_DEVICE: ++ if (copy_from_user(&load_device, addr, sizeof(load_device))) { ++ ret = -EFAULT; ++ break; ++ } ++ TRACE2("%04x, %04x, %04x, %04x", load_device.vendor, ++ load_device.device, load_device.subvendor, ++ load_device.subdevice); ++ if (load_device.vendor) { ++ struct wrap_device *wd; ++ wd = kzalloc(sizeof(*wd), GFP_KERNEL); ++ if (!wd) { ++ ret = -ENOMEM; ++ break; ++ } ++ InitializeListHead(&wd->settings); ++ wd->dev_bus = WRAP_BUS(load_device.bus); ++ wd->vendor = load_device.vendor; ++ wd->device = load_device.device; ++ wd->subvendor = load_device.subvendor; ++ wd->subdevice = load_device.subdevice; ++ strncpy(wd->conf_file_name, load_device.conf_file_name, ++ sizeof(wd->conf_file_name)); ++ wd->conf_file_name[sizeof(wd->conf_file_name)-1] = 0; ++ strncpy(wd->driver_name, load_device.driver_name, ++ sizeof(wd->driver_name)); ++ wd->driver_name[sizeof(wd->driver_name)-1] = 0; ++ InsertHeadList(&wrap_devices, &wd->list); ++ ret = 0; ++ } else ++ ret = -EINVAL; ++ break; ++ case WRAP_IOCTL_LOAD_DRIVER: ++ TRACE1("loading driver at %p", addr); ++ load_driver = vmalloc(sizeof(*load_driver)); ++ if (!load_driver) { ++ ret = -ENOMEM; ++ break; ++ } ++ if (copy_from_user(load_driver, addr, sizeof(*load_driver))) ++ ret = -EFAULT; ++ else ++ ret = load_user_space_driver(load_driver); ++ vfree(load_driver); ++ break; ++ case WRAP_IOCTL_LOAD_BIN_FILE: ++ if (copy_from_user(&load_bin_file, addr, sizeof(load_bin_file))) ++ ret = -EFAULT; ++ else ++ ret = add_bin_file(&load_bin_file); ++ break; ++ default: ++ ERROR("unknown ioctl 0x%x", cmd); ++ ret = -EINVAL; ++ break; ++ } ++ complete(&loader_complete); ++ EXIT1(return ret); ++} ++ ++#ifdef CONFIG_COMPAT ++static int copy_load_driver_file32(struct load_driver_file *k, ++ struct load_driver_file32 __user *u) ++{ ++ u32 data; ++ ++ if (copy_from_user(&k->driver_name, &u->driver_name, ++ sizeof(u->driver_name) + sizeof(u->name))) ++ return -EFAULT; ++ ++ if (get_user(k->size, &u->size)) ++ return -EFAULT; ++ if (get_user(data, &u->data)) ++ return -EFAULT; ++ ++ k->data = (void __user *)(unsigned long)data; ++ return 0; ++} ++ ++static int copy_load_driver32(struct load_driver *k, ++ struct load_driver32 __user *u) ++{ ++ int i; ++ ++ if (copy_from_user(&k->name, &u->name, ++ sizeof(u->name) + sizeof(u->conf_file_name))) ++ return -EFAULT; ++ ++ if (get_user(k->num_sys_files, &u->num_sys_files)) ++ return -EFAULT; ++ ++ for (i = 0; i < k->num_sys_files; i++) ++ if (copy_load_driver_file32(&k->sys_files[i], &u->sys_files[i])) ++ return -EFAULT; ++ ++ if (get_user(k->num_settings, &u->num_settings)) ++ return -EFAULT; ++ ++ if (copy_from_user(&k->settings, &u->settings, ++ sizeof(u->settings[0]) * k->num_settings)) ++ return -EFAULT; ++ ++ if (get_user(k->num_bin_files, &u->num_bin_files)) ++ return -EFAULT; ++ ++ for (i = 0; i < k->num_bin_files; i++) ++ if (copy_load_driver_file32(&k->bin_files[i], &u->bin_files[i])) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++static long wrapper_ioctl_compat(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ int ret = 0; ++ void __user *addr = (void __user *)arg; ++ struct load_driver *kdriver; ++ struct load_driver32 __user *udriver = addr; ++ struct load_driver_file kfile; ++ struct load_driver_file32 __user *ufile = addr; ++ ++ ENTER1("cmd: 0x%x", cmd); ++ ++ switch (cmd) { ++ case WRAP_IOCTL_LOAD_DEVICE32: ++ return wrapper_ioctl(file, WRAP_IOCTL_LOAD_DEVICE, arg); ++ case WRAP_IOCTL_LOAD_DRIVER32: ++ TRACE1("loading driver at %p", addr); ++ kdriver = vmalloc(sizeof(*kdriver)); ++ if (!kdriver) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ ret = copy_load_driver32(kdriver, udriver); ++ if (!ret) ++ ret = load_user_space_driver(kdriver); ++ ++ vfree(kdriver); ++ break; ++ case WRAP_IOCTL_LOAD_BIN_FILE32: ++ ret = copy_load_driver_file32(&kfile, ufile); ++ if (ret) ++ break; ++ ++ ret = add_bin_file(&kfile); ++ break; ++ default: ++ ERROR("unknown ioctl 0x%x", cmd); ++ ret = -EINVAL; ++ break; ++ } ++ complete(&loader_complete); ++ EXIT1(return ret); ++} ++#endif ++ ++static int wrapper_ioctl_release(struct inode *inode, struct file *file) ++{ ++ ENTER1(""); ++ complete(&loader_complete); ++ return 0; ++} ++ ++static struct file_operations wrapper_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = wrapper_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = wrapper_ioctl_compat, ++#endif ++ .release = wrapper_ioctl_release, ++}; ++ ++static struct miscdevice wrapper_misc = { ++ .name = DRIVER_NAME, ++ .minor = MISC_DYNAMIC_MINOR, ++ .fops = &wrapper_fops ++}; ++ ++int loader_init(void) ++{ ++ int err; ++ ++ InitializeListHead(&wrap_drivers); ++ InitializeListHead(&wrap_devices); ++ mutex_init(&loader_mutex); ++ init_completion(&loader_complete); ++ if ((err = misc_register(&wrapper_misc)) < 0) { ++ ERROR("couldn't register module (%d)", err); ++ unregister_devices(); ++ EXIT1(return err); ++ } ++ register_devices(); ++ EXIT1(return 0); ++} ++ ++void loader_exit(void) ++{ ++ struct nt_list *cur, *next; ++ ++ ENTER1(""); ++ misc_deregister(&wrapper_misc); ++ unregister_devices(); ++ mutex_lock(&loader_mutex); ++ nt_list_for_each_safe(cur, next, &wrap_drivers) { ++ struct wrap_driver *driver; ++ driver = container_of(cur, struct wrap_driver, list); ++ unload_wrap_driver(driver); ++ } ++ mutex_unlock(&loader_mutex); ++ EXIT1(return); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/loader.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/loader.h +--- linux-3.12.2/3rdparty/ndiswrapper/loader.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/loader.h 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,108 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _LOADER_H_ ++#define _LOADER_H_ ++ ++#include "ndiswrapper.h" ++ ++#ifndef __KERNEL__ ++#define __user ++#endif ++ ++struct load_driver_file { ++ char driver_name[MAX_DRIVER_NAME_LEN]; ++ char name[MAX_DRIVER_NAME_LEN]; ++ size_t size; ++ void __user *data; ++}; ++ ++struct load_device_setting { ++ char name[MAX_SETTING_NAME_LEN]; ++ char value[MAX_SETTING_VALUE_LEN]; ++}; ++ ++struct load_device { ++ int bus; ++ int vendor; ++ int device; ++ int subvendor; ++ int subdevice; ++ char conf_file_name[MAX_DRIVER_NAME_LEN]; ++ char driver_name[MAX_DRIVER_NAME_LEN]; ++}; ++ ++struct load_driver { ++ char name[MAX_DRIVER_NAME_LEN]; ++ char conf_file_name[MAX_DRIVER_NAME_LEN]; ++ unsigned int num_sys_files; ++ struct load_driver_file sys_files[MAX_DRIVER_PE_IMAGES]; ++ unsigned int num_settings; ++ struct load_device_setting settings[MAX_DEVICE_SETTINGS]; ++ unsigned int num_bin_files; ++ struct load_driver_file bin_files[MAX_DRIVER_BIN_FILES]; ++}; ++ ++#define WRAP_IOCTL_LOAD_DEVICE _IOW(('N' + 'd' + 'i' + 'S'), 0, \ ++ struct load_device *) ++#define WRAP_IOCTL_LOAD_DRIVER _IOW(('N' + 'd' + 'i' + 'S'), 1, \ ++ struct load_driver *) ++#define WRAP_IOCTL_LOAD_BIN_FILE _IOW(('N' + 'd' + 'i' + 'S'), 2, \ ++ struct load_driver_file *) ++ ++#ifdef CONFIG_COMPAT ++struct load_driver_file32 { ++ char driver_name[MAX_DRIVER_NAME_LEN]; ++ char name[MAX_DRIVER_NAME_LEN]; ++ u32 size; ++ u32 data; ++}; ++ ++struct load_driver32 { ++ char name[MAX_DRIVER_NAME_LEN]; ++ char conf_file_name[MAX_DRIVER_NAME_LEN]; ++ u32 num_sys_files; ++ struct load_driver_file32 sys_files[MAX_DRIVER_PE_IMAGES]; ++ u32 num_settings; ++ struct load_device_setting settings[MAX_DEVICE_SETTINGS]; ++ u32 num_bin_files; ++ struct load_driver_file32 bin_files[MAX_DRIVER_BIN_FILES]; ++} __packed; ++ ++#define WRAP_IOCTL_LOAD_DEVICE32 _IOW(('N' + 'd' + 'i' + 'S'), 0, u32) ++#define WRAP_IOCTL_LOAD_DRIVER32 _IOW(('N' + 'd' + 'i' + 'S'), 1, u32) ++#define WRAP_IOCTL_LOAD_BIN_FILE32 _IOW(('N' + 'd' + 'i' + 'S'), 2, u32) ++#endif ++ ++#define WRAP_CMD_LOAD_DEVICE "load_device" ++#define WRAP_CMD_LOAD_DRIVER "load_driver" ++#define WRAP_CMD_LOAD_BIN_FILE "load_bin_file" ++ ++int loader_init(void); ++void loader_exit(void); ++ ++#ifdef __KERNEL__ ++struct wrap_device *load_wrap_device(struct load_device *load_device); ++struct wrap_driver *load_wrap_driver(struct wrap_device *device); ++struct wrap_bin_file *get_bin_file(char *bin_file_name); ++void free_bin_file(struct wrap_bin_file *bin_file); ++void unload_wrap_driver(struct wrap_driver *driver); ++void unload_wrap_device(struct wrap_device *wd); ++struct wrap_device *get_wrap_device(void *dev, int bus_type); ++ ++extern struct mutex loader_mutex; ++#endif ++ ++#endif /* LOADER_H */ +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/longlong.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/longlong.h +--- linux-3.12.2/3rdparty/ndiswrapper/longlong.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/longlong.h 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,1333 @@ ++/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. ++ Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 ++ Free Software Foundation, Inc. ++ ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ++ 02111-1307 USA. */ ++ ++/* You have to define the following before including this file: ++ ++ UWtype -- An unsigned type, default type for operations (typically a "word") ++ UHWtype -- An unsigned type, at least half the size of UWtype. ++ UDWtype -- An unsigned type, at least twice as large a UWtype ++ W_TYPE_SIZE -- size in bits of UWtype ++ ++ UQItype -- Unsigned 8 bit type. ++ SItype, USItype -- Signed and unsigned 32 bit types. ++ DItype, UDItype -- Signed and unsigned 64 bit types. ++ ++ On a 32 bit machine UWtype should typically be USItype; ++ on a 64 bit machine, UWtype should typically be UDItype. ++*/ ++ ++#define __BITS4 (W_TYPE_SIZE / 4) ++#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) ++#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) ++#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) ++ ++#ifndef W_TYPE_SIZE ++#define W_TYPE_SIZE 32 ++#define UWtype USItype ++#define UHWtype USItype ++#define UDWtype UDItype ++#endif ++ ++/* Define auxiliary asm macros. ++ ++ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two ++ UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype ++ word product in HIGH_PROD and LOW_PROD. ++ ++ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a ++ UDWtype product. This is just a variant of umul_ppmm. ++ ++ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, ++ denominator) divides a UDWtype, composed by the UWtype integers ++ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient ++ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less ++ than DENOMINATOR for correct operation. If, in addition, the most ++ significant bit of DENOMINATOR must be 1, then the pre-processor symbol ++ UDIV_NEEDS_NORMALIZATION is defined to 1. ++ ++ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, ++ denominator). Like udiv_qrnnd but the numbers are signed. The quotient ++ is rounded towards 0. ++ ++ 5) count_leading_zeros(count, x) counts the number of zero-bits from the ++ msb to the first nonzero bit in the UWtype X. This is the number of ++ steps X needs to be shifted left to set the msb. Undefined for X == 0, ++ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. ++ ++ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts ++ from the least significant end. ++ ++ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, ++ high_addend_2, low_addend_2) adds two UWtype integers, composed by ++ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 ++ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow ++ (i.e. carry out) is not stored anywhere, and is lost. ++ ++ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, ++ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, ++ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and ++ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE ++ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, ++ and is lost. ++ ++ If any of these macros are left undefined for a particular CPU, ++ C macros are used. */ ++ ++/* The CPUs come in alphabetical order below. ++ ++ Please add support for more CPUs here, or improve the current support ++ for the CPUs below! ++ (E.g. WE32100, IBM360.) */ ++ ++#if defined (__GNUC__) && !defined (NO_ASM) ++ ++/* We sometimes need to clobber "cc" with gcc2, but that would not be ++ understood by gcc1. Use cpp to avoid major code duplication. */ ++#if __GNUC__ < 2 ++#define __CLOBBER_CC ++#define __AND_CLOBBER_CC ++#else /* __GNUC__ >= 2 */ ++#define __CLOBBER_CC : "cc" ++#define __AND_CLOBBER_CC , "cc" ++#endif /* __GNUC__ < 2 */ ++ ++#if defined (__alpha) && W_TYPE_SIZE == 64 ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ UDItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("umulh %r1,%2,%0" \ ++ : "=r" ((UDItype) ph) \ ++ : "%rJ" (__m0), \ ++ "rI" (__m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 46 ++#ifndef LONGLONG_STANDALONE ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ do { UDItype __r; \ ++ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ ++ (r) = __r; \ ++ } while (0) ++extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); ++#define UDIV_TIME 220 ++#endif /* LONGLONG_STANDALONE */ ++#ifdef __alpha_cix__ ++#define count_leading_zeros(COUNT,X) \ ++ __asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X)) ++#define count_trailing_zeros(COUNT,X) \ ++ __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X)) ++#define COUNT_LEADING_ZEROS_0 64 ++#else ++extern const UQItype __clz_tab[]; ++#define count_leading_zeros(COUNT,X) \ ++ do { \ ++ UDItype __xr = (X), __t, __a; \ ++ __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \ ++ __a = __clz_tab[__t ^ 0xff] - 1; \ ++ __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \ ++ (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ ++ } while (0) ++#define count_trailing_zeros(COUNT,X) \ ++ do { \ ++ UDItype __xr = (X), __t, __a; \ ++ __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \ ++ __t = ~__t & -~__t; \ ++ __a = ((__t & 0xCC) != 0) * 2; \ ++ __a += ((__t & 0xF0) != 0) * 4; \ ++ __a += ((__t & 0xAA) != 0); \ ++ __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \ ++ __a <<= 3; \ ++ __t &= -__t; \ ++ __a += ((__t & 0xCC) != 0) * 2; \ ++ __a += ((__t & 0xF0) != 0) * 4; \ ++ __a += ((__t & 0xAA) != 0); \ ++ (COUNT) = __a; \ ++ } while (0) ++#endif /* __alpha_cix__ */ ++#endif /* __alpha */ ++ ++#if defined (__arc__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%r" ((USItype) (ah)), \ ++ "rIJ" ((USItype) (bh)), \ ++ "%r" ((USItype) (al)), \ ++ "rIJ" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "r" ((USItype) (ah)), \ ++ "rIJ" ((USItype) (bh)), \ ++ "r" ((USItype) (al)), \ ++ "rIJ" ((USItype) (bl))) ++/* Call libgcc routine. */ ++#define umul_ppmm(w1, w0, u, v) \ ++do { \ ++ DWunion __w; \ ++ __w.ll = __umulsidi3 (u, v); \ ++ w1 = __w.s.high; \ ++ w0 = __w.s.low; \ ++} while (0) ++#define __umulsidi3 __umulsidi3 ++UDItype __umulsidi3 (USItype, USItype); ++#endif ++ ++#if defined (__arm__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%r" ((USItype) (ah)), \ ++ "rI" ((USItype) (bh)), \ ++ "%r" ((USItype) (al)), \ ++ "rI" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "r" ((USItype) (ah)), \ ++ "rI" ((USItype) (bh)), \ ++ "r" ((USItype) (al)), \ ++ "rI" ((USItype) (bl))) ++#define umul_ppmm(xh, xl, a, b) \ ++{register USItype __t0, __t1, __t2; \ ++ __asm__ ("%@ Inlined umul_ppmm\n" \ ++ " mov %2, %5, lsr #16\n" \ ++ " mov %0, %6, lsr #16\n" \ ++ " bic %3, %5, %2, lsl #16\n" \ ++ " bic %4, %6, %0, lsl #16\n" \ ++ " mul %1, %3, %4\n" \ ++ " mul %4, %2, %4\n" \ ++ " mul %3, %0, %3\n" \ ++ " mul %0, %2, %0\n" \ ++ " adds %3, %4, %3\n" \ ++ " addcs %0, %0, #65536\n" \ ++ " adds %1, %1, %3, lsl #16\n" \ ++ " adc %0, %0, %3, lsr #16" \ ++ : "=&r" ((USItype) (xh)), \ ++ "=r" ((USItype) (xl)), \ ++ "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ ++ : "r" ((USItype) (a)), \ ++ "r" ((USItype) (b)));} ++#define UMUL_TIME 20 ++#define UDIV_TIME 100 ++#endif /* __arm__ */ ++ ++#if defined (__hppa) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%rM" ((USItype) (ah)), \ ++ "rM" ((USItype) (bh)), \ ++ "%rM" ((USItype) (al)), \ ++ "rM" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "rM" ((USItype) (ah)), \ ++ "rM" ((USItype) (bh)), \ ++ "rM" ((USItype) (al)), \ ++ "rM" ((USItype) (bl))) ++#if defined (_PA_RISC1_1) ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ union \ ++ { \ ++ UDItype __f; \ ++ struct {USItype __w1, __w0;} __w1w0; \ ++ } __t; \ ++ __asm__ ("xmpyu %1,%2,%0" \ ++ : "=x" (__t.__f) \ ++ : "x" ((USItype) (u)), \ ++ "x" ((USItype) (v))); \ ++ (w1) = __t.__w1w0.__w1; \ ++ (w0) = __t.__w1w0.__w0; \ ++ } while (0) ++#define UMUL_TIME 8 ++#else ++#define UMUL_TIME 30 ++#endif ++#define UDIV_TIME 40 ++#define count_leading_zeros(count, x) \ ++ do { \ ++ USItype __tmp; \ ++ __asm__ ( \ ++ "ldi 1,%0\n" \ ++" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ ++" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ ++" ldo 16(%0),%0 ; Yes. Perform add.\n" \ ++" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ ++" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ ++" ldo 8(%0),%0 ; Yes. Perform add.\n" \ ++" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ ++" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ ++" ldo 4(%0),%0 ; Yes. Perform add.\n" \ ++" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ ++" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ ++" ldo 2(%0),%0 ; Yes. Perform add.\n" \ ++" extru %1,30,1,%1 ; Extract bit 1.\n" \ ++" sub %0,%1,%0 ; Subtract it.\n" \ ++ : "=r" (count), "=r" (__tmp) : "1" (x)); \ ++ } while (0) ++#endif ++ ++#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32 ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mr %0,%3" \ ++ : "=r" (__xx.__i.__h), \ ++ "=r" (__xx.__i.__l) \ ++ : "%1" (__m0), \ ++ "r" (__m1)); \ ++ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ ++ (xh) += ((((SItype) __m0 >> 31) & __m1) \ ++ + (((SItype) __m1 >> 31) & __m0)); \ ++ } while (0) ++#define smul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union {DItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ __asm__ ("mr %0,%3" \ ++ : "=r" (__xx.__i.__h), \ ++ "=r" (__xx.__i.__l) \ ++ : "%1" (m0), \ ++ "r" (m1)); \ ++ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ ++ } while (0) ++#define sdiv_qrnnd(q, r, n1, n0, d) \ ++ do { \ ++ union {DItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ __xx.__i.__h = n1; __xx.__i.__l = n0; \ ++ __asm__ ("dr %0,%2" \ ++ : "=r" (__xx.__ll) \ ++ : "0" (__xx.__ll), "r" (d)); \ ++ (q) = __xx.__i.__l; (r) = __xx.__i.__h; \ ++ } while (0) ++#endif ++ ++#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addl %5,%1\n\tadcl %3,%0" \ ++ : "=r" (sh), \ ++ "=&r" (sl) \ ++ : "%0" ((USItype) (ah)), \ ++ "g" ((USItype) (bh)), \ ++ "%1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subl %5,%1\n\tsbbl %3,%0" \ ++ : "=r" (sh), \ ++ "=&r" (sl) \ ++ : "0" ((USItype) (ah)), \ ++ "g" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("mull %3" \ ++ : "=a" (w0), \ ++ "=d" (w1) \ ++ : "%0" ((USItype) (u)), \ ++ "rm" ((USItype) (v))) ++#define udiv_qrnnd(q, r, n1, n0, dv) \ ++ __asm__ ("divl %4" \ ++ : "=a" (q), \ ++ "=d" (r) \ ++ : "0" ((USItype) (n0)), \ ++ "1" ((USItype) (n1)), \ ++ "rm" ((USItype) (dv))) ++#define count_leading_zeros(count, x) \ ++ do { \ ++ USItype __cbtmp; \ ++ __asm__ ("bsrl %1,%0" \ ++ : "=r" (__cbtmp) : "rm" ((USItype) (x))); \ ++ (count) = __cbtmp ^ 31; \ ++ } while (0) ++#define count_trailing_zeros(count, x) \ ++ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x))) ++#define UMUL_TIME 40 ++#define UDIV_TIME 40 ++#endif /* 80x86 */ ++ ++#if defined (__i960__) && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __asm__ ("emul %2,%1,%0" \ ++ : "=d" (__xx.__ll) \ ++ : "%dI" ((USItype) (u)), \ ++ "dI" ((USItype) (v))); \ ++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) ++#define __umulsidi3(u, v) \ ++ ({UDItype __w; \ ++ __asm__ ("emul %2,%1,%0" \ ++ : "=d" (__w) \ ++ : "%dI" ((USItype) (u)), \ ++ "dI" ((USItype) (v))); \ ++ __w; }) ++#endif /* __i960__ */ ++ ++#if defined (__M32R__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ /* The cmp clears the condition bit. */ \ ++ __asm__ ("cmp %0,%0\n\taddx %%5,%1\n\taddx %%3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%0" ((USItype) (ah)), \ ++ "r" ((USItype) (bh)), \ ++ "%1" ((USItype) (al)), \ ++ "r" ((USItype) (bl)) \ ++ : "cbit") ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ /* The cmp clears the condition bit. */ \ ++ __asm__ ("cmp %0,%0\n\tsubx %5,%1\n\tsubx %3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "r" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "r" ((USItype) (bl)) \ ++ : "cbit") ++#endif /* __M32R__ */ ++ ++#if defined (__mc68000__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ ++ : "=d" ((USItype) (sh)), \ ++ "=&d" ((USItype) (sl)) \ ++ : "%0" ((USItype) (ah)), \ ++ "d" ((USItype) (bh)), \ ++ "%1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ ++ : "=d" ((USItype) (sh)), \ ++ "=&d" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "d" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++ ++/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */ ++#if defined (__mc68020__) || defined(mc68020) \ ++ || defined(__mc68030__) || defined(mc68030) \ ++ || defined(__mc68040__) || defined(mc68040) \ ++ || defined(__mcpu32__) || defined(mcpu32) ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("mulu%.l %3,%1:%0" \ ++ : "=d" ((USItype) (w0)), \ ++ "=d" ((USItype) (w1)) \ ++ : "%0" ((USItype) (u)), \ ++ "dmi" ((USItype) (v))) ++#define UMUL_TIME 45 ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("divu%.l %4,%1:%0" \ ++ : "=d" ((USItype) (q)), \ ++ "=d" ((USItype) (r)) \ ++ : "0" ((USItype) (n0)), \ ++ "1" ((USItype) (n1)), \ ++ "dmi" ((USItype) (d))) ++#define UDIV_TIME 90 ++#define sdiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("divs%.l %4,%1:%0" \ ++ : "=d" ((USItype) (q)), \ ++ "=d" ((USItype) (r)) \ ++ : "0" ((USItype) (n0)), \ ++ "1" ((USItype) (n1)), \ ++ "dmi" ((USItype) (d))) ++ ++#else /* not mc68020 */ ++#if !defined(__mcf5200__) ++/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ ++#define umul_ppmm(xh, xl, a, b) \ ++ __asm__ ("| Inlined umul_ppmm\n" \ ++ " move%.l %2,%/d0\n" \ ++ " move%.l %3,%/d1\n" \ ++ " move%.l %/d0,%/d2\n" \ ++ " swap %/d0\n" \ ++ " move%.l %/d1,%/d3\n" \ ++ " swap %/d1\n" \ ++ " move%.w %/d2,%/d4\n" \ ++ " mulu %/d3,%/d4\n" \ ++ " mulu %/d1,%/d2\n" \ ++ " mulu %/d0,%/d3\n" \ ++ " mulu %/d0,%/d1\n" \ ++ " move%.l %/d4,%/d0\n" \ ++ " eor%.w %/d0,%/d0\n" \ ++ " swap %/d0\n" \ ++ " add%.l %/d0,%/d2\n" \ ++ " add%.l %/d3,%/d2\n" \ ++ " jcc 1f\n" \ ++ " add%.l %#65536,%/d1\n" \ ++ "1: swap %/d2\n" \ ++ " moveq %#0,%/d0\n" \ ++ " move%.w %/d2,%/d0\n" \ ++ " move%.w %/d4,%/d2\n" \ ++ " move%.l %/d2,%1\n" \ ++ " add%.l %/d1,%/d0\n" \ ++ " move%.l %/d0,%0" \ ++ : "=g" ((USItype) (xh)), \ ++ "=g" ((USItype) (xl)) \ ++ : "g" ((USItype) (a)), \ ++ "g" ((USItype) (b)) \ ++ : "d0", "d1", "d2", "d3", "d4") ++#define UMUL_TIME 100 ++#define UDIV_TIME 400 ++#endif /* not mcf5200 */ ++#endif /* not mc68020 */ ++ ++/* The '020, '030, '040 and '060 have bitfield insns. */ ++#if defined (__mc68020__) || defined(mc68020) \ ++ || defined(__mc68030__) || defined(mc68030) \ ++ || defined(__mc68040__) || defined(mc68040) \ ++ || defined(__mc68060__) || defined(mc68060) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("bfffo %1{%b2:%b2},%0" \ ++ : "=d" ((USItype) (count)) \ ++ : "od" ((USItype) (x)), "n" (0)) ++#endif ++#endif /* mc68000 */ ++ ++#if defined (__m88000__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%rJ" ((USItype) (ah)), \ ++ "rJ" ((USItype) (bh)), \ ++ "%rJ" ((USItype) (al)), \ ++ "rJ" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "rJ" ((USItype) (ah)), \ ++ "rJ" ((USItype) (bh)), \ ++ "rJ" ((USItype) (al)), \ ++ "rJ" ((USItype) (bl))) ++#define count_leading_zeros(count, x) \ ++ do { \ ++ USItype __cbtmp; \ ++ __asm__ ("ff1 %0,%1" \ ++ : "=r" (__cbtmp) \ ++ : "r" ((USItype) (x))); \ ++ (count) = __cbtmp ^ 31; \ ++ } while (0) ++#define COUNT_LEADING_ZEROS_0 63 /* sic */ ++#if defined (__mc88110__) ++#define umul_ppmm(wh, wl, u, v) \ ++ do { \ ++ union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ __asm__ ("mulu.d %0,%1,%2" \ ++ : "=r" (__xx.__ll) \ ++ : "r" ((USItype) (u)), \ ++ "r" ((USItype) (v))); \ ++ (wh) = __xx.__i.__h; \ ++ (wl) = __xx.__i.__l; \ ++ } while (0) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __h, __l;} __i; \ ++ } __xx; \ ++ USItype __q; \ ++ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ ++ __asm__ ("divu.d %0,%1,%2" \ ++ : "=r" (__q) \ ++ : "r" (__xx.__ll), \ ++ "r" ((USItype) (d))); \ ++ (r) = (n0) - __q * (d); (q) = __q; }) ++#define UMUL_TIME 5 ++#define UDIV_TIME 25 ++#else ++#define UMUL_TIME 17 ++#define UDIV_TIME 150 ++#endif /* __mc88110__ */ ++#endif /* __m88000__ */ ++ ++#if defined (__mips__) && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("multu %2,%3" \ ++ : "=l" ((USItype) (w0)), \ ++ "=h" ((USItype) (w1)) \ ++ : "d" ((USItype) (u)), \ ++ "d" ((USItype) (v))) ++#define UMUL_TIME 10 ++#define UDIV_TIME 100 ++#endif /* __mips__ */ ++ ++#if defined (__ns32000__) && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __asm__ ("meid %2,%0" \ ++ : "=g" (__xx.__ll) \ ++ : "%0" ((USItype) (u)), \ ++ "g" ((USItype) (v))); \ ++ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) ++#define __umulsidi3(u, v) \ ++ ({UDItype __w; \ ++ __asm__ ("meid %2,%0" \ ++ : "=g" (__w) \ ++ : "%0" ((USItype) (u)), \ ++ "g" ((USItype) (v))); \ ++ __w; }) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ ({union {UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ ++ __asm__ ("deid %2,%0" \ ++ : "=g" (__xx.__ll) \ ++ : "0" (__xx.__ll), \ ++ "g" ((USItype) (d))); \ ++ (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) ++#define count_trailing_zeros(count,x) \ ++ do { \ ++ __asm__ ("ffsd %2,%0" \ ++ : "=r" ((USItype) (count)) \ ++ : "0" ((USItype) 0), \ ++ "r" ((USItype) (x))); \ ++ } while (0) ++#endif /* __ns32000__ */ ++ ++/* FIXME: We should test _IBMR2 here when we add assembly support for the ++ system vendor compilers. ++ FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good ++ enough, since that hits ARM and m68k too. */ ++#if (defined (_ARCH_PPC) /* AIX */ \ ++ || defined (_ARCH_PWR) /* AIX */ \ ++ || defined (_ARCH_COM) /* AIX */ \ ++ || defined (__powerpc__) /* gcc */ \ ++ || defined (__POWERPC__) /* BEOS */ \ ++ || defined (__ppc__) /* Darwin */ \ ++ || defined (PPC) /* GNU/Linux, SysV */ \ ++ ) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else \ ++ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ ++ } while (0) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (ah) && (ah) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else \ ++ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ ++ } while (0) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) ++#define COUNT_LEADING_ZEROS_0 32 ++#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ ++ || defined (__ppc__) || defined (PPC) || defined (__vxworks__) ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 15 ++#define smul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ SItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define SMUL_TIME 14 ++#define UDIV_TIME 120 ++#elif defined (_ARCH_PWR) ++#define UMUL_TIME 8 ++#define smul_ppmm(xh, xl, m0, m1) \ ++ __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) ++#define SMUL_TIME 4 ++#define sdiv_qrnnd(q, r, nh, nl, d) \ ++ __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) ++#define UDIV_TIME 100 ++#endif ++#endif /* 32-bit POWER architecture variants. */ ++ ++/* We should test _IBMR2 here when we add assembly support for the system ++ vendor compilers. */ ++#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ ++ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ ++ else \ ++ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ ++ } while (0) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ if (__builtin_constant_p (ah) && (ah) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ ++ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ ++ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ ++ else \ ++ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ ++ : "=r" (sh), "=&r" (sl) \ ++ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ ++ } while (0) ++#define count_leading_zeros(count, x) \ ++ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) ++#define COUNT_LEADING_ZEROS_0 64 ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ UDItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define UMUL_TIME 15 ++#define smul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ DItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ ++ (pl) = __m0 * __m1; \ ++ } while (0) ++#define SMUL_TIME 14 /* ??? */ ++#define UDIV_TIME 120 /* ??? */ ++#endif /* 64-bit PowerPC. */ ++ ++#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("a %1,%5\n\tae %0,%3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%0" ((USItype) (ah)), \ ++ "r" ((USItype) (bh)), \ ++ "%1" ((USItype) (al)), \ ++ "r" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("s %1,%5\n\tse %0,%3" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "r" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "r" ((USItype) (bl))) ++#define umul_ppmm(ph, pl, m0, m1) \ ++ do { \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ( \ ++ "s r2,r2\n" \ ++" mts r10,%2\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" m r2,%3\n" \ ++" cas %0,r2,r0\n" \ ++" mfs r10,%1" \ ++ : "=r" ((USItype) (ph)), \ ++ "=r" ((USItype) (pl)) \ ++ : "%r" (__m0), \ ++ "r" (__m1) \ ++ : "r2"); \ ++ (ph) += ((((SItype) __m0 >> 31) & __m1) \ ++ + (((SItype) __m1 >> 31) & __m0)); \ ++ } while (0) ++#define UMUL_TIME 20 ++#define UDIV_TIME 200 ++#define count_leading_zeros(count, x) \ ++ do { \ ++ if ((x) >= 0x10000) \ ++ __asm__ ("clz %0,%1" \ ++ : "=r" ((USItype) (count)) \ ++ : "r" ((USItype) (x) >> 16)); \ ++ else \ ++ { \ ++ __asm__ ("clz %0,%1" \ ++ : "=r" ((USItype) (count)) \ ++ : "r" ((USItype) (x))); \ ++ (count) += 16; \ ++ } \ ++ } while (0) ++#endif ++ ++#if defined (__sh2__) && W_TYPE_SIZE == 32 ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ( \ ++ "dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \ ++ : "=r" ((USItype)(w1)), \ ++ "=r" ((USItype)(w0)) \ ++ : "r" ((USItype)(u)), \ ++ "r" ((USItype)(v)) \ ++ : "macl", "mach") ++#define UMUL_TIME 5 ++#endif ++ ++#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 ++#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) ++#define count_leading_zeros(count, x) \ ++ do \ ++ { \ ++ UDItype x_ = (USItype)(x); \ ++ SItype c_; \ ++ \ ++ __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ ++ (count) = c_ - 31; \ ++ } \ ++ while (0) ++#define COUNT_LEADING_ZEROS_0 32 ++#endif ++ ++#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ ++ && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "%rJ" ((USItype) (ah)), \ ++ "rI" ((USItype) (bh)), \ ++ "%rJ" ((USItype) (al)), \ ++ "rI" ((USItype) (bl)) \ ++ __CLOBBER_CC) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ ++ : "=r" ((USItype) (sh)), \ ++ "=&r" ((USItype) (sl)) \ ++ : "rJ" ((USItype) (ah)), \ ++ "rI" ((USItype) (bh)), \ ++ "rJ" ((USItype) (al)), \ ++ "rI" ((USItype) (bl)) \ ++ __CLOBBER_CC) ++#if defined (__sparc_v8__) ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ ++ : "=r" ((USItype) (w1)), \ ++ "=r" ((USItype) (w0)) \ ++ : "r" ((USItype) (u)), \ ++ "r" ((USItype) (v))) ++#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ ++ __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ ++ : "=&r" ((USItype) (__q)), \ ++ "=&r" ((USItype) (__r)) \ ++ : "r" ((USItype) (__n1)), \ ++ "r" ((USItype) (__n0)), \ ++ "r" ((USItype) (__d))) ++#else ++#if defined (__sparclite__) ++/* This has hardware multiply but not divide. It also has two additional ++ instructions scan (ffs from high bit) and divscc. */ ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ ++ : "=r" ((USItype) (w1)), \ ++ "=r" ((USItype) (w0)) \ ++ : "r" ((USItype) (u)), \ ++ "r" ((USItype) (v))) ++#define udiv_qrnnd(q, r, n1, n0, d) \ ++ __asm__ ("! Inlined udiv_qrnnd\n" \ ++" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ ++" tst %%g0\n" \ ++" divscc %3,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%%g1\n" \ ++" divscc %%g1,%4,%0\n" \ ++" rd %%y,%1\n" \ ++" bl,a 1f\n" \ ++" add %1,%4,%1\n" \ ++"1: ! End of inline udiv_qrnnd" \ ++ : "=r" ((USItype) (q)), \ ++ "=r" ((USItype) (r)) \ ++ : "r" ((USItype) (n1)), \ ++ "r" ((USItype) (n0)), \ ++ "rI" ((USItype) (d)) \ ++ : "g1" __AND_CLOBBER_CC) ++#define UDIV_TIME 37 ++#define count_leading_zeros(count, x) \ ++ do { \ ++ __asm__ ("scan %1,1,%0" \ ++ : "=r" ((USItype) (count)) \ ++ : "r" ((USItype) (x))); \ ++ } while (0) ++/* Early sparclites return 63 for an argument of 0, but they warn that future ++ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 ++ undefined. */ ++#else ++/* SPARC without integer multiplication and divide instructions. ++ (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ ++#define umul_ppmm(w1, w0, u, v) \ ++ __asm__ ("! Inlined umul_ppmm\n" \ ++" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ ++" sra %3,31,%%o5 ! Don't move this insn\n" \ ++" and %2,%%o5,%%o5 ! Don't move this insn\n" \ ++" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,%3,%%g1\n" \ ++" mulscc %%g1,0,%%g1\n" \ ++" add %%g1,%%o5,%0\n" \ ++" rd %%y,%1" \ ++ : "=r" ((USItype) (w1)), \ ++ "=r" ((USItype) (w0)) \ ++ : "%rI" ((USItype) (u)), \ ++ "r" ((USItype) (v)) \ ++ : "g1", "o5" __AND_CLOBBER_CC) ++#define UMUL_TIME 39 /* 39 instructions */ ++/* It's quite necessary to add this much assembler for the sparc. ++ The default udiv_qrnnd (in C) is more than 10 times slower! */ ++#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ ++ __asm__ ("! Inlined udiv_qrnnd\n" \ ++" mov 32,%%g1\n" \ ++" subcc %1,%2,%%g0\n" \ ++"1: bcs 5f\n" \ ++" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ ++" sub %1,%2,%1 ! this kills msb of n\n" \ ++" addx %1,%1,%1 ! so this can't give carry\n" \ ++" subcc %%g1,1,%%g1\n" \ ++"2: bne 1b\n" \ ++" subcc %1,%2,%%g0\n" \ ++" bcs 3f\n" \ ++" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ ++" b 3f\n" \ ++" sub %1,%2,%1 ! this kills msb of n\n" \ ++"4: sub %1,%2,%1\n" \ ++"5: addxcc %1,%1,%1\n" \ ++" bcc 2b\n" \ ++" subcc %%g1,1,%%g1\n" \ ++"! Got carry from n. Subtract next step to cancel this carry.\n" \ ++" bne 4b\n" \ ++" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ ++" sub %1,%2,%1\n" \ ++"3: xnor %0,0,%0\n" \ ++" ! End of inline udiv_qrnnd" \ ++ : "=&r" ((USItype) (__q)), \ ++ "=&r" ((USItype) (__r)) \ ++ : "r" ((USItype) (__d)), \ ++ "1" ((USItype) (__n1)), \ ++ "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) ++#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ ++#endif /* __sparclite__ */ ++#endif /* __sparc_v8__ */ ++#endif /* sparc32 */ ++ ++#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ ++ && W_TYPE_SIZE == 64 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addcc %r4,%5,%1\n\t" \ ++ "add %r2,%3,%0\n\t" \ ++ "bcs,a,pn %%xcc, 1f\n\t" \ ++ "add %0, 1, %0\n" \ ++ "1:" \ ++ : "=r" ((UDItype)(sh)), \ ++ "=&r" ((UDItype)(sl)) \ ++ : "%rJ" ((UDItype)(ah)), \ ++ "rI" ((UDItype)(bh)), \ ++ "%rJ" ((UDItype)(al)), \ ++ "rI" ((UDItype)(bl)) \ ++ __CLOBBER_CC) ++ ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subcc %r4,%5,%1\n\t" \ ++ "sub %r2,%3,%0\n\t" \ ++ "bcs,a,pn %%xcc, 1f\n\t" \ ++ "sub %0, 1, %0\n\t" \ ++ "1:" \ ++ : "=r" ((UDItype)(sh)), \ ++ "=&r" ((UDItype)(sl)) \ ++ : "rJ" ((UDItype)(ah)), \ ++ "rI" ((UDItype)(bh)), \ ++ "rJ" ((UDItype)(al)), \ ++ "rI" ((UDItype)(bl)) \ ++ __CLOBBER_CC) ++ ++#define umul_ppmm(wh, wl, u, v) \ ++ do { \ ++ UDItype tmp1, tmp2, tmp3, tmp4; \ ++ __asm__ __volatile__ ( \ ++ "srl %7,0,%3\n\t" \ ++ "mulx %3,%6,%1\n\t" \ ++ "srlx %6,32,%2\n\t" \ ++ "mulx %2,%3,%4\n\t" \ ++ "sllx %4,32,%5\n\t" \ ++ "srl %6,0,%3\n\t" \ ++ "sub %1,%5,%5\n\t" \ ++ "srlx %5,32,%5\n\t" \ ++ "addcc %4,%5,%4\n\t" \ ++ "srlx %7,32,%5\n\t" \ ++ "mulx %3,%5,%3\n\t" \ ++ "mulx %2,%5,%5\n\t" \ ++ "sethi %%hi(0x80000000),%2\n\t" \ ++ "addcc %4,%3,%4\n\t" \ ++ "srlx %4,32,%4\n\t" \ ++ "add %2,%2,%2\n\t" \ ++ "movcc %%xcc,%%g0,%2\n\t" \ ++ "addcc %5,%4,%5\n\t" \ ++ "sllx %3,32,%3\n\t" \ ++ "add %1,%3,%1\n\t" \ ++ "add %5,%2,%0" \ ++ : "=r" ((UDItype)(wh)), \ ++ "=&r" ((UDItype)(wl)), \ ++ "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ ++ : "r" ((UDItype)(u)), \ ++ "r" ((UDItype)(v)) \ ++ __CLOBBER_CC); \ ++ } while (0) ++#define UMUL_TIME 96 ++#define UDIV_TIME 230 ++#endif /* sparc64 */ ++ ++#if defined (__vax__) && W_TYPE_SIZE == 32 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ ++ : "=g" ((USItype) (sh)), \ ++ "=&g" ((USItype) (sl)) \ ++ : "%0" ((USItype) (ah)), \ ++ "g" ((USItype) (bh)), \ ++ "%1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ ++ : "=g" ((USItype) (sh)), \ ++ "=&g" ((USItype) (sl)) \ ++ : "0" ((USItype) (ah)), \ ++ "g" ((USItype) (bh)), \ ++ "1" ((USItype) (al)), \ ++ "g" ((USItype) (bl))) ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union { \ ++ UDItype __ll; \ ++ struct {USItype __l, __h;} __i; \ ++ } __xx; \ ++ USItype __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("emul %1,%2,$0,%0" \ ++ : "=r" (__xx.__ll) \ ++ : "g" (__m0), \ ++ "g" (__m1)); \ ++ (xh) = __xx.__i.__h; \ ++ (xl) = __xx.__i.__l; \ ++ (xh) += ((((SItype) __m0 >> 31) & __m1) \ ++ + (((SItype) __m1 >> 31) & __m0)); \ ++ } while (0) ++#define sdiv_qrnnd(q, r, n1, n0, d) \ ++ do { \ ++ union {DItype __ll; \ ++ struct {SItype __l, __h;} __i; \ ++ } __xx; \ ++ __xx.__i.__h = n1; __xx.__i.__l = n0; \ ++ __asm__ ("ediv %3,%2,%0,%1" \ ++ : "=g" (q), "=g" (r) \ ++ : "g" (__xx.__ll), "g" (d)); \ ++ } while (0) ++#endif /* __vax__ */ ++ ++#if defined (__z8000__) && W_TYPE_SIZE == 16 ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ ++ : "=r" ((unsigned int)(sh)), \ ++ "=&r" ((unsigned int)(sl)) \ ++ : "%0" ((unsigned int)(ah)), \ ++ "r" ((unsigned int)(bh)), \ ++ "%1" ((unsigned int)(al)), \ ++ "rQR" ((unsigned int)(bl))) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ ++ : "=r" ((unsigned int)(sh)), \ ++ "=&r" ((unsigned int)(sl)) \ ++ : "0" ((unsigned int)(ah)), \ ++ "r" ((unsigned int)(bh)), \ ++ "1" ((unsigned int)(al)), \ ++ "rQR" ((unsigned int)(bl))) ++#define umul_ppmm(xh, xl, m0, m1) \ ++ do { \ ++ union {long int __ll; \ ++ struct {unsigned int __h, __l;} __i; \ ++ } __xx; \ ++ unsigned int __m0 = (m0), __m1 = (m1); \ ++ __asm__ ("mult %S0,%H3" \ ++ : "=r" (__xx.__i.__h), \ ++ "=r" (__xx.__i.__l) \ ++ : "%1" (__m0), \ ++ "rQR" (__m1)); \ ++ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ ++ (xh) += ((((signed int) __m0 >> 15) & __m1) \ ++ + (((signed int) __m1 >> 15) & __m0)); \ ++ } while (0) ++#endif /* __z8000__ */ ++ ++#endif /* __GNUC__ */ ++ ++/* If this machine has no inline assembler, use C macros. */ ++ ++#if !defined (add_ssaaaa) ++#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ UWtype __x; \ ++ __x = (al) + (bl); \ ++ (sh) = (ah) + (bh) + (__x < (al)); \ ++ (sl) = __x; \ ++ } while (0) ++#endif ++ ++#if !defined (sub_ddmmss) ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ UWtype __x; \ ++ __x = (al) - (bl); \ ++ (sh) = (ah) - (bh) - (__x > (al)); \ ++ (sl) = __x; \ ++ } while (0) ++#endif ++ ++#if !defined (umul_ppmm) ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ UWtype __x0, __x1, __x2, __x3; \ ++ UHWtype __ul, __vl, __uh, __vh; \ ++ \ ++ __ul = __ll_lowpart (u); \ ++ __uh = __ll_highpart (u); \ ++ __vl = __ll_lowpart (v); \ ++ __vh = __ll_highpart (v); \ ++ \ ++ __x0 = (UWtype) __ul * __vl; \ ++ __x1 = (UWtype) __ul * __vh; \ ++ __x2 = (UWtype) __uh * __vl; \ ++ __x3 = (UWtype) __uh * __vh; \ ++ \ ++ __x1 += __ll_highpart (__x0);/* this can't give carry */ \ ++ __x1 += __x2; /* but this indeed can */ \ ++ if (__x1 < __x2) /* did we get it? */ \ ++ __x3 += __ll_B; /* yes, add it in the proper pos. */ \ ++ \ ++ (w1) = __x3 + __ll_highpart (__x1); \ ++ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ ++ } while (0) ++#endif ++ ++#if !defined (__umulsidi3) ++#define __umulsidi3(u, v) \ ++ ({DWunion __w; \ ++ umul_ppmm (__w.s.high, __w.s.low, u, v); \ ++ __w.ll; }) ++#endif ++ ++/* Define this unconditionally, so it can be used for debugging. */ ++#define __udiv_qrnnd_c(q, r, n1, n0, d) \ ++ do { \ ++ UWtype __d1, __d0, __q1, __q0; \ ++ UWtype __r1, __r0, __m; \ ++ __d1 = __ll_highpart (d); \ ++ __d0 = __ll_lowpart (d); \ ++ \ ++ __r1 = (n1) % __d1; \ ++ __q1 = (n1) / __d1; \ ++ __m = (UWtype) __q1 * __d0; \ ++ __r1 = __r1 * __ll_B | __ll_highpart (n0); \ ++ if (__r1 < __m) \ ++ { \ ++ __q1--, __r1 += (d); \ ++ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ ++ if (__r1 < __m) \ ++ __q1--, __r1 += (d); \ ++ } \ ++ __r1 -= __m; \ ++ \ ++ __r0 = __r1 % __d1; \ ++ __q0 = __r1 / __d1; \ ++ __m = (UWtype) __q0 * __d0; \ ++ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ ++ if (__r0 < __m) \ ++ { \ ++ __q0--, __r0 += (d); \ ++ if (__r0 >= (d)) \ ++ if (__r0 < __m) \ ++ __q0--, __r0 += (d); \ ++ } \ ++ __r0 -= __m; \ ++ \ ++ (q) = (UWtype) __q1 * __ll_B | __q0; \ ++ (r) = __r0; \ ++ } while (0) ++ ++/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through ++ __udiv_w_sdiv (defined in libgcc or elsewhere). */ ++#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) ++#define udiv_qrnnd(q, r, nh, nl, d) \ ++ do { \ ++ USItype __r; \ ++ (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ ++ (r) = __r; \ ++ } while (0) ++#endif ++ ++/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ ++#if !defined (udiv_qrnnd) ++#define UDIV_NEEDS_NORMALIZATION 1 ++#define udiv_qrnnd __udiv_qrnnd_c ++#endif ++ ++#if !defined (count_leading_zeros) ++extern const UQItype __clz_tab[]; ++#define count_leading_zeros(count, x) \ ++ do { \ ++ UWtype __xr = (x); \ ++ UWtype __a; \ ++ \ ++ if (W_TYPE_SIZE <= 32) \ ++ { \ ++ __a = __xr < ((UWtype)1<<2*__BITS4) \ ++ ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ ++ : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ ++ } \ ++ else \ ++ { \ ++ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ ++ if (((__xr >> __a) & 0xff) != 0) \ ++ break; \ ++ } \ ++ \ ++ (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ ++ } while (0) ++#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE ++#endif ++ ++#if !defined (count_trailing_zeros) ++/* Define count_trailing_zeros using count_leading_zeros. The latter might be ++ defined in asm, but if it is not, the C version above is good enough. */ ++#define count_trailing_zeros(count, x) \ ++ do { \ ++ UWtype __ctz_x = (x); \ ++ UWtype __ctz_c; \ ++ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ ++ (count) = W_TYPE_SIZE - 1 - __ctz_c; \ ++ } while (0) ++#endif ++ ++#ifndef UDIV_NEEDS_NORMALIZATION ++#define UDIV_NEEDS_NORMALIZATION 0 ++#endif +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/Makefile linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/Makefile +--- linux-3.12.2/3rdparty/ndiswrapper/Makefile 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/Makefile 2013-11-28 21:42:10.000000000 +0200 +@@ -0,0 +1,213 @@ ++# Name of the module ++MODNAME = ndiswrapper ++ ++DISTFILES = \ ++ Makefile crt.c divdi3.c hal.c iw_ndis.c iw_ndis.h lin2win.S lin2win.h \ ++ loader.c loader.h longlong.h mkexport.sh mkstubs.sh ndis.c ndis.h \ ++ ndiswrapper.h ntoskernel.c ntoskernel.h ntoskernel_io.c pe_linker.c \ ++ pe_linker.h pnp.c pnp.h proc.c rtl.c usb.c usb.h win2lin_stubs.S \ ++ winnt_types.h workqueue.c wrapmem.c wrapmem.h wrapndis.c wrapndis.h \ ++ wrapper.c wrapper.h ++ ++# By default, we try to compile the modules for the currently running ++# kernel. But it's the first approximation, as we will re-read the ++# version from the kernel sources. ++KVERS_UNAME ?= $(shell uname -r) ++ ++# KBUILD is the path to the Linux kernel build tree. It is usually the ++# same as the kernel source tree, except when the kernel was compiled in ++# a separate directory. ++KBUILD ?= $(shell readlink -f /lib/modules/$(KVERS_UNAME)/build) ++ ++ifeq (,$(KBUILD)) ++$(error Kernel build tree not found - please set KBUILD to configured kernel) ++endif ++ ++KCONFIG := $(KBUILD)/.config ++ifeq (,$(wildcard $(KCONFIG))) ++$(error No .config found in $(KBUILD), please set KBUILD to configured kernel) ++endif ++ ++ifneq (,$(wildcard $(KBUILD)/include/linux/version.h)) ++ifneq (,$(wildcard $(KBUILD)/include/generated/uapi/linux/version.h)) ++$(error Multiple copies of version.h found, please clean your build tree) ++endif ++endif ++ ++# Kernel Makefile doesn't always know the exact kernel version, so we ++# get it from the kernel headers instead and pass it to make. ++VERSION_H := $(KBUILD)/include/generated/utsrelease.h ++ifeq (,$(wildcard $(VERSION_H))) ++VERSION_H := $(KBUILD)/include/linux/utsrelease.h ++endif ++ifeq (,$(wildcard $(VERSION_H))) ++VERSION_H := $(KBUILD)/include/linux/version.h ++endif ++ifeq (,$(wildcard $(VERSION_H))) ++$(error Please run 'make modules_prepare' in $(KBUILD)) ++endif ++ ++KVERS := $(shell sed -ne 's/"//g;s/^\#define UTS_RELEASE //p' $(VERSION_H)) ++ ++ifeq (,$(KVERS)) ++$(error Cannot find UTS_RELEASE in $(VERSION_H), please report) ++endif ++ ++INST_DIR = /lib/modules/$(KVERS)/misc ++ ++SRC_DIR=$(shell pwd) ++ ++include $(KCONFIG) ++ ++# returns of structs and unions in registers when possible, like Windows ++EXTRA_CFLAGS += -freg-struct-return ++ ++# to produce debug trace, add option "DEBUG=" where is 1 to 6 ++ifdef DEBUG ++EXTRA_CFLAGS += -DDEBUG=$(DEBUG) -g ++endif ++ ++# to debug timers, add option "TIMER_DEBUG=1" ++ifdef TIMER_DEBUG ++EXTRA_CFLAGS += -DTIMER_DEBUG ++endif ++ ++# to debug event layer, add option "EVENT_DEBUG=1" ++ifdef EVENT_DEBUG ++EXTRA_CFLAGS += -DEVENT_DEBUG ++endif ++ ++# to debug USB layer, add option "USB_DEBUG=1" ++ifdef USB_DEBUG ++EXTRA_CFLAGS += -DUSB_DEBUG ++endif ++ ++# to debug I/O layer, add option "IO_DEBUG=1" ++ifdef IO_DEBUG ++EXTRA_CFLAGS += -DIO_DEBUG ++endif ++ ++# to debug worker threads, add option "WORK_DEBUG=1" ++ifdef WORK_DEBUG ++EXTRA_CFLAGS += -DWORK_DEBUG ++endif ++ ++# to debug memory allocation, add option "ALLOC_DEBUG=" where is 1 or 2 ++ifdef ALLOC_DEBUG ++EXTRA_CFLAGS += -DALLOC_DEBUG=$(ALLOC_DEBUG) ++endif ++ ++OBJS = crt.o hal.o iw_ndis.o loader.o ndis.o ntoskernel.o ntoskernel_io.o \ ++ pe_linker.o pnp.o proc.o rtl.o wrapmem.o wrapndis.o wrapper.o ++ ++EXPORT_SRCS = crt.c hal.c ndis.c ntoskernel.c ntoskernel_io.c rtl.c ++ ++STUB_SRCS = crt.c hal.c ndis.c ntoskernel.c ntoskernel_io.c \ ++ pnp.c rtl.c wrapndis.c ++ ++ ++# By default, USB layer is compiled in if USB support is in kernel; ++# to disable USB support in ndiswrapper even if USB support is in kernel, ++# add option "DISABLE_USB=1" ++ifndef DISABLE_USB ++ifeq ($(CONFIG_USB),y) ++ENABLE_USB = 1 ++endif ++ifeq ($(CONFIG_USB),m) ++ENABLE_USB = 1 ++endif ++endif ++ ++ifdef ENABLE_USB ++EXPORT_SRCS += usb.c ++STUB_SRCS += usb.c ++OBJS += usb.o ++EXTRA_CFLAGS += -DENABLE_USB ++endif ++ ++ifdef WRAP_WQ ++EXTRA_CFLAGS += -DWRAP_WQ ++OBJS += workqueue.o ++endif ++ ++ ++all: config_check modules ++ ++# generate exports symbol table from C files ++quiet_cmd_mkexport = MKEXPORT $@ ++cmd_mkexport = $(SHELL) $(obj)/mkexport.sh $< $@ ++ ++extra-y += $(EXPORT_SRCS:.c=_exports.h) ++%_exports.h: %.c $(obj)/mkexport.sh FORCE ++ $(call if_changed,mkexport) ++ ++$(addprefix $(obj)/,$(EXPORT_SRCS:.c=.o)): %.o: %_exports.h ++ ++ifeq ($(CONFIG_X86_64),y) ++quiet_cmd_mkstubs = MKSTUBS $@ ++cmd_mkstubs = $(SHELL) $(obj)/mkstubs.sh $(addprefix $(src)/,$(STUB_SRCS)) >$@ ++ ++extra-y += win2lin_stubs.h ++$(obj)/win2lin_stubs.h: $(addprefix $(src)/,$(STUB_SRCS)) FORCE ++ $(call if_changed,mkstubs) ++ ++$(obj)/win2lin_stubs.o: $(obj)/win2lin_stubs.h ++OBJS += win2lin_stubs.o lin2win.o ++else ++OBJS += divdi3.o ++endif ++ ++MODULE := $(MODNAME).ko ++obj-m := $(MODNAME).o ++ ++$(MODNAME)-objs := $(OBJS) ++ ++ ++config_check: ++ @if [ -z "$(CONFIG_WIRELESS_EXT)$(CONFIG_NET_RADIO)" ]; then \ ++ echo; echo; \ ++ echo "*** WARNING: This kernel lacks wireless extensions."; \ ++ echo "Wireless drivers will not work properly."; \ ++ echo; echo; \ ++ fi ++ @if [ -z "$(CONFIG_X86_64)" ] && [ -n "$(CONFIG_4KSTACKS)" ]; then \ ++ echo; echo; \ ++ echo "*** WARNING: This kernel uses 4K stack size option"; \ ++ echo "(CONFIG_4KSTACKS); many Windows drivers will not work"; \ ++ echo "with this option enabled. Disable CONFIG_4KSTACKS"; \ ++ echo "in kernel's .config file, recompile and install kernel"; \ ++ echo; echo; \ ++ fi ++ ++modules: ++ $(MAKE) -C $(KBUILD) M=$(SRC_DIR) ++ ++$(MODULE): ++ $(MAKE) modules ++ ++clean: ++ rm -f *.o *.ko .*.cmd *.mod.c *.symvers modules.order *~ .\#* ++ rm -f *_exports.h win2lin_stubs.h ++ rm -rf .tmp_versions ++ ++install: config_check $(MODULE) ++ @/sbin/modinfo $(MODULE) | grep -q "^vermagic: *$(KVERS) " || \ ++ { echo "$(MODULE)" is not for Linux $(KVERS); exit 1; } ++ mkdir -p -m 755 $(DESTDIR)$(INST_DIR) ++ install -m 0644 $(MODULE) $(DESTDIR)$(INST_DIR) ++ifndef DESTDIR ++ -/sbin/depmod -a $(KVERS) ++endif ++ ++uninstall: ++ rm -f $(DESTDIR)$(INST_DIR)/$(MODULE) ++ifndef DESTDIR ++ -/sbin/depmod -a $(KVERS) ++endif ++ ++dist: ++ @for file in $(DISTFILES); do \ ++ cp $$file $(distdir)/$$file || exit 1; \ ++ done ++ ++.PHONY: all modules clean install config_check dist +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/mkexport.sh linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/mkexport.sh +--- linux-3.12.2/3rdparty/ndiswrapper/mkexport.sh 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/mkexport.sh 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,42 @@ ++#! /bin/sh ++ ++# Generate exports symbol table from C files ++ ++input="$1" ++output="$2" ++exports=$(basename "$output" .h) ++exec >"$output" ++ ++echo "/* automatically generated from src */"; ++ ++sed -n -e '/^\(wstdcall\|wfastcall\|noregparm\|regparm3\|__attribute__\)/{ ++:more ++N ++s/\([^{]\)$/\1/ ++t more ++s/\n{$/;/ ++p ++}' $input ++ ++echo "#ifdef CONFIG_X86_64"; ++ ++sed -n \ ++ -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ ++'WIN_FUNC_DECL(\1, \2)/p' \ ++ -e 's/.*WIN_FUNC_PTR(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ ++'WIN_FUNC_DECL(\1, \2)/p' $input | sort -u ++ ++echo "#endif" ++echo "extern struct wrap_export $exports[];" ++echo "struct wrap_export $exports[] = {" ++ ++sed -n \ ++ -e 's/.*WIN_FUNC(_win_\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ ++' WIN_WIN_SYMBOL(\1, \2),/p' \ ++ -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ ++' WIN_SYMBOL(\1, \2),/p' \ ++ -e 's/.*WIN_SYMBOL_MAP(\("[^"]\+"\)[ ,\n]\+\([^)]\+\)).*/'\ ++' {\1, (generic_func)\2},/p' $input | sort -u ++ ++echo " {NULL, NULL}" ++echo "};" +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/mkstubs.sh linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/mkstubs.sh +--- linux-3.12.2/3rdparty/ndiswrapper/mkstubs.sh 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/mkstubs.sh 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,12 @@ ++#! /bin/sh ++ ++for file in "$@"; do ++ echo ++ echo "# automatically generated from $file" ++ sed -n \ ++ -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/\ ++ win2lin(\1, \2)/p' \ ++ -e 's/.*WIN_FUNC_PTR(\([^\,]\+\) *\, *\([0-9]\+\)).*/\ ++ win2lin(\1, \2)/p' \ ++ $file | sed -e 's/[ \t ]\+//' | sort -u; \ ++done +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/ndis.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ndis.c +--- linux-3.12.2/3rdparty/ndiswrapper/ndis.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ndis.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,3025 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ndis.h" ++#include "iw_ndis.h" ++#include "wrapndis.h" ++#include "pnp.h" ++#include "loader.h" ++#include ++#include ++#include "ndis_exports.h" ++ ++#define MAX_ALLOCATED_NDIS_PACKETS TX_RING_SIZE ++#define MAX_ALLOCATED_NDIS_BUFFERS TX_RING_SIZE ++ ++static struct work_struct ndis_work; ++static struct nt_list ndis_work_list; ++static spinlock_t ndis_work_list_lock; ++ ++struct workqueue_struct *ndis_wq; ++ ++static void *ndis_get_routine_address(char *name); ++ ++wstdcall void WIN_FUNC(NdisInitializeWrapper,4) ++ (void **driver_handle, struct driver_object *driver, ++ struct unicode_string *reg_path, void *unused) ++{ ++ ENTER1("handle: %p, driver: %p", driver_handle, driver); ++ *driver_handle = driver; ++ EXIT1(return); ++} ++ ++wstdcall void WIN_FUNC(NdisTerminateWrapper,2) ++ (struct device_object *dev_obj, void *system_specific) ++{ ++ EXIT1(return); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterMiniport,3) ++ (struct driver_object *drv_obj, struct miniport *mp, UINT length) ++{ ++ int min_length; ++ struct wrap_driver *wrap_driver; ++ struct ndis_driver *ndis_driver; ++ ++ min_length = ((char *)&mp->co_create_vc) - ((char *)mp); ++ ++ ENTER1("%p %p %d", drv_obj, mp, length); ++ ++ if (mp->major_version < 4) { ++ ERROR("Driver is using ndis version %d which is too old.", ++ mp->major_version); ++ EXIT1(return NDIS_STATUS_BAD_VERSION); ++ } ++ ++ if (length < min_length) { ++ ERROR("Characteristics length %d is too small", length); ++ EXIT1(return NDIS_STATUS_BAD_CHARACTERISTICS); ++ } ++ ++ TRACE1("%d.%d, %d, %u", mp->major_version, mp->minor_version, length, ++ (u32)sizeof(struct miniport)); ++ wrap_driver = IoGetDriverObjectExtension(drv_obj, ++ (void *)WRAP_DRIVER_CLIENT_ID); ++ if (!wrap_driver) { ++ ERROR("couldn't get wrap_driver"); ++ EXIT1(return NDIS_STATUS_RESOURCES); ++ } ++ if (IoAllocateDriverObjectExtension( ++ drv_obj, (void *)NDIS_DRIVER_CLIENT_ID, ++ sizeof(*ndis_driver), (void **)&ndis_driver) != ++ STATUS_SUCCESS) ++ EXIT1(return NDIS_STATUS_RESOURCES); ++ wrap_driver->ndis_driver = ndis_driver; ++ TRACE1("driver: %p", ndis_driver); ++ memcpy(&ndis_driver->mp, mp, min_t(int, sizeof(*mp), length)); ++ ++ DBG_BLOCK(2) { ++ int i; ++ void **func; ++ char *mp_funcs[] = { ++ "queryinfo", "reconfig", "reset", "send", "setinfo", ++ "tx_data", "return_packet", "send_packets", ++ "alloc_complete", "co_create_vc", "co_delete_vc", ++ "co_activate_vc", "co_deactivate_vc", ++ "co_send_packets", "co_request", "cancel_send_packets", ++ "pnp_event_notify", "shutdown", ++ }; ++ func = (void **)&ndis_driver->mp.queryinfo; ++ for (i = 0; i < ARRAY_SIZE(mp_funcs); i++) ++ TRACE0("function '%s' is at %p", mp_funcs[i], func[i]); ++ } ++ EXIT1(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterDevice,6) ++ (struct driver_object *drv_obj, struct unicode_string *dev_name, ++ struct unicode_string *link, void **funcs, ++ struct device_object **dev_obj, void **dev_obj_handle) ++{ ++ NTSTATUS status; ++ struct device_object *tmp; ++ int i; ++ ++ ENTER1("%p, %p, %p", drv_obj, dev_name, link); ++ status = IoCreateDevice(drv_obj, 0, dev_name, FILE_DEVICE_NETWORK, 0, ++ FALSE, &tmp); ++ ++ if (status != STATUS_SUCCESS) ++ EXIT1(return NDIS_STATUS_RESOURCES); ++ if (link) ++ status = IoCreateSymbolicLink(link, dev_name); ++ if (status != STATUS_SUCCESS) { ++ IoDeleteDevice(tmp); ++ EXIT1(return NDIS_STATUS_RESOURCES); ++ } ++ ++ *dev_obj = tmp; ++ *dev_obj_handle = *dev_obj; ++ for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) ++ if (funcs[i] && i != IRP_MJ_PNP && i != IRP_MJ_POWER) { ++ drv_obj->major_func[i] = funcs[i]; ++ TRACE1("mj_fn for 0x%x is at %p", i, funcs[i]); ++ } ++ EXIT1(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMDeregisterDevice,1) ++ (struct device_object *dev_obj) ++{ ++ ENTER2("%p", dev_obj); ++ IoDeleteDevice(dev_obj); ++ return NDIS_STATUS_SUCCESS; ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisAllocateMemoryWithTag,3) ++ (void **dest, UINT length, ULONG tag) ++{ ++ void *addr; ++ ++ assert_irql(_irql_ <= DISPATCH_LEVEL); ++ addr = ExAllocatePoolWithTag(NonPagedPool, length, tag); ++ TRACE4("%p", addr); ++ if (addr) { ++ *dest = addr; ++ EXIT4(return NDIS_STATUS_SUCCESS); ++ } else ++ EXIT4(return NDIS_STATUS_FAILURE); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisAllocateMemory,4) ++ (void **dest, UINT length, UINT flags, NDIS_PHY_ADDRESS highest_address) ++{ ++ return NdisAllocateMemoryWithTag(dest, length, 0); ++} ++ ++/* length_tag is either length or tag, depending on if ++ * NdisAllocateMemory or NdisAllocateMemoryTag is used to allocate ++ * memory */ ++wstdcall void WIN_FUNC(NdisFreeMemory,3) ++ (void *addr, UINT length_tag, UINT flags) ++{ ++ TRACE4("%p", addr); ++ ExFreePool(addr); ++} ++ ++noregparm void WIN_FUNC(NdisWriteErrorLogEntry,12) ++ (struct driver_object *drv_obj, ULONG error, ULONG count, ...) ++{ ++ va_list args; ++ int i; ++ ULONG code; ++ ++ va_start(args, count); ++ ERROR("log: %08X, count: %d, return_address: %p", ++ error, count, __builtin_return_address(0)); ++ for (i = 0; i < count; i++) { ++ code = va_arg(args, ULONG); ++ ERROR("code: 0x%x", code); ++ } ++ va_end(args); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisOpenConfiguration,3) ++ (NDIS_STATUS *status, struct ndis_mp_block **conf_handle, ++ struct ndis_mp_block *handle) ++{ ++ ENTER2("%p", conf_handle); ++ *conf_handle = handle; ++ *status = NDIS_STATUS_SUCCESS; ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisOpenProtocolConfiguration,3) ++ (NDIS_STATUS *status, void **confhandle, ++ struct unicode_string *section) ++{ ++ ENTER2("%p", confhandle); ++ *status = NDIS_STATUS_SUCCESS; ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisOpenConfigurationKeyByName,4) ++ (NDIS_STATUS *status, void *handle, ++ struct unicode_string *key, void **subkeyhandle) ++{ ++ struct ansi_string ansi; ++ ENTER2(""); ++ if (RtlUnicodeStringToAnsiString(&ansi, key, TRUE) == STATUS_SUCCESS) { ++ TRACE2("%s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ *subkeyhandle = handle; ++ *status = NDIS_STATUS_SUCCESS; ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisOpenConfigurationKeyByIndex,5) ++ (NDIS_STATUS *status, void *handle, ULONG index, ++ struct unicode_string *key, void **subkeyhandle) ++{ ++ ENTER2("%u", index); ++// *subkeyhandle = handle; ++ *status = NDIS_STATUS_FAILURE; ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisCloseConfiguration,1) ++ (void *handle) ++{ ++ /* instead of freeing all configuration parameters as we are ++ * supposed to do here, we free them when the device is ++ * removed */ ++ ENTER2("%p", handle); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisOpenFile,5) ++ (NDIS_STATUS *status, struct wrap_bin_file **file, ++ UINT *filelength, struct unicode_string *filename, ++ NDIS_PHY_ADDRESS highest_address) ++{ ++ struct ansi_string ansi; ++ struct wrap_bin_file *bin_file; ++ ++ ENTER2("%p, %d, %llx, %p", status, *filelength, highest_address, *file); ++ if (RtlUnicodeStringToAnsiString(&ansi, filename, TRUE) != ++ STATUS_SUCCESS) { ++ *status = NDIS_STATUS_RESOURCES; ++ EXIT2(return); ++ } ++ TRACE2("%s", ansi.buf); ++ bin_file = get_bin_file(ansi.buf); ++ if (bin_file) { ++ *file = bin_file; ++ *filelength = bin_file->size; ++ *status = NDIS_STATUS_SUCCESS; ++ } else ++ *status = NDIS_STATUS_FILE_NOT_FOUND; ++ ++ RtlFreeAnsiString(&ansi); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisMapFile,3) ++ (NDIS_STATUS *status, void **mappedbuffer, struct wrap_bin_file *file) ++{ ++ ENTER2("%p", file); ++ ++ if (!file) { ++ *status = NDIS_STATUS_ALREADY_MAPPED; ++ EXIT2(return); ++ } ++ ++ *status = NDIS_STATUS_SUCCESS; ++ *mappedbuffer = file->data; ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisUnmapFile,1) ++ (struct wrap_bin_file *file) ++{ ++ ENTER2("%p", file); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisCloseFile,1) ++ (struct wrap_bin_file *file) ++{ ++ ENTER2("%p", file); ++ free_bin_file(file); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisGetSystemUpTime,1) ++ (ULONG *ms) ++{ ++ *ms = 1000 * jiffies / HZ; ++ EXIT5(return); ++} ++ ++wstdcall ULONG WIN_FUNC(NDIS_BUFFER_TO_SPAN_PAGES,1) ++ (ndis_buffer *buffer) ++{ ++ ULONG n, length; ++ ++ if (buffer == NULL) ++ EXIT2(return 0); ++ if (MmGetMdlByteCount(buffer) == 0) ++ EXIT2(return 1); ++ ++ length = MmGetMdlByteCount(buffer); ++ n = SPAN_PAGES(MmGetMdlVirtualAddress(buffer), length); ++ TRACE4("%p, %p, %d, %d", buffer->startva, buffer->mappedsystemva, ++ length, n); ++ EXIT3(return n); ++} ++ ++wstdcall void WIN_FUNC(NdisGetBufferPhysicalArraySize,2) ++ (ndis_buffer *buffer, UINT *arraysize) ++{ ++ ENTER3("%p", buffer); ++ *arraysize = NDIS_BUFFER_TO_SPAN_PAGES(buffer); ++ EXIT3(return); ++} ++ ++static struct ndis_configuration_parameter * ++ndis_encode_setting(struct wrap_device_setting *setting, ++ enum ndis_parameter_type type) ++{ ++ struct ansi_string ansi; ++ struct ndis_configuration_parameter *param; ++ ++ param = setting->encoded; ++ if (param) { ++ if (param->type == type) ++ EXIT2(return param); ++ if (param->type == NdisParameterString) ++ RtlFreeUnicodeString(¶m->data.string); ++ setting->encoded = NULL; ++ } else ++ param = ExAllocatePoolWithTag(NonPagedPool, sizeof(*param), 0); ++ if (!param) { ++ ERROR("couldn't allocate memory"); ++ return NULL; ++ } ++ switch (type) { ++ case NdisParameterInteger: ++ param->data.integer = simple_strtol(setting->value, NULL, 0); ++ TRACE2("0x%x", param->data.integer); ++ break; ++ case NdisParameterHexInteger: ++ param->data.integer = simple_strtol(setting->value, NULL, 16); ++ TRACE2("0x%x", param->data.integer); ++ break; ++ case NdisParameterString: ++ RtlInitAnsiString(&ansi, setting->value); ++ TRACE2("'%s'", ansi.buf); ++ if (RtlAnsiStringToUnicodeString(¶m->data.string, ++ &ansi, TRUE)) { ++ ExFreePool(param); ++ EXIT2(return NULL); ++ } ++ break; ++ case NdisParameterBinary: ++ param->data.integer = simple_strtol(setting->value, NULL, 2); ++ TRACE2("0x%x", param->data.integer); ++ break; ++ default: ++ ERROR("unknown type: %d", type); ++ ExFreePool(param); ++ return NULL; ++ } ++ param->type = type; ++ setting->encoded = param; ++ EXIT2(return param); ++} ++ ++static int ndis_decode_setting(struct wrap_device_setting *setting, ++ struct ndis_configuration_parameter *param) ++{ ++ struct ansi_string ansi; ++ struct ndis_configuration_parameter *prev; ++ ++ ENTER2("%p, %p", setting, param); ++ prev = setting->encoded; ++ if (prev && prev->type == NdisParameterString) { ++ RtlFreeUnicodeString(&prev->data.string); ++ setting->encoded = NULL; ++ } ++ switch (param->type) { ++ case NdisParameterInteger: ++ snprintf(setting->value, MAX_SETTING_VALUE_LEN, "%u", ++ param->data.integer); ++ break; ++ case NdisParameterHexInteger: ++ snprintf(setting->value, MAX_SETTING_VALUE_LEN, "%x", ++ param->data.integer); ++ break; ++ case NdisParameterString: ++ ansi.buf = setting->value; ++ ansi.max_length = MAX_SETTING_VALUE_LEN; ++ if ((RtlUnicodeStringToAnsiString(&ansi, ¶m->data.string, ++ FALSE) != STATUS_SUCCESS) ++ || ansi.length >= MAX_SETTING_VALUE_LEN) { ++ EXIT1(return -1); ++ } ++ if (ansi.length == ansi.max_length) ++ ansi.length--; ++ setting->value[ansi.length] = 0; ++ break; ++ default: ++ TRACE2("unknown setting type: %d", param->type); ++ return -1; ++ } ++ TRACE2("setting changed %s='%s', %d", setting->name, setting->value, ++ ansi.length); ++ return 0; ++} ++ ++static int read_setting(struct nt_list *setting_list, char *keyname, int length, ++ struct ndis_configuration_parameter **param, ++ enum ndis_parameter_type type) ++{ ++ struct wrap_device_setting *setting; ++ mutex_lock(&loader_mutex); ++ nt_list_for_each_entry(setting, setting_list, list) { ++ if (strnicmp(keyname, setting->name, length) == 0) { ++ TRACE2("setting %s='%s'", keyname, setting->value); ++ mutex_unlock(&loader_mutex); ++ *param = ndis_encode_setting(setting, type); ++ if (*param) ++ EXIT2(return 0); ++ else ++ EXIT2(return -1); ++ } ++ } ++ mutex_unlock(&loader_mutex); ++ EXIT2(return -1); ++} ++ ++wstdcall void WIN_FUNC(NdisReadConfiguration,5) ++ (NDIS_STATUS *status, struct ndis_configuration_parameter **param, ++ struct ndis_mp_block *nmb, struct unicode_string *key, ++ enum ndis_parameter_type type) ++{ ++ struct ansi_string ansi; ++ int ret; ++ ++ ENTER2("nmb: %p", nmb); ++ ret = RtlUnicodeStringToAnsiString(&ansi, key, TRUE); ++ if (ret != STATUS_SUCCESS || ansi.buf == NULL) { ++ *param = NULL; ++ *status = NDIS_STATUS_FAILURE; ++ RtlFreeAnsiString(&ansi); ++ EXIT2(return); ++ } ++ TRACE2("%d, %s", type, ansi.buf); ++ ++ if (read_setting(&nmb->wnd->wd->settings, ansi.buf, ++ ansi.length, param, type) == 0 || ++ read_setting(&nmb->wnd->wd->driver->settings, ansi.buf, ++ ansi.length, param, type) == 0) ++ *status = NDIS_STATUS_SUCCESS; ++ else { ++ TRACE2("setting %s not found (type:%d)", ansi.buf, type); ++ *status = NDIS_STATUS_FAILURE; ++ } ++ RtlFreeAnsiString(&ansi); ++ EXIT2(return); ++ ++} ++ ++wstdcall void WIN_FUNC(NdisWriteConfiguration,4) ++ (NDIS_STATUS *status, struct ndis_mp_block *nmb, ++ struct unicode_string *key, struct ndis_configuration_parameter *param) ++{ ++ struct ansi_string ansi; ++ char *keyname; ++ struct wrap_device_setting *setting; ++ ++ ENTER2("nmb: %p", nmb); ++ if (RtlUnicodeStringToAnsiString(&ansi, key, TRUE)) { ++ *status = NDIS_STATUS_FAILURE; ++ EXIT2(return); ++ } ++ keyname = ansi.buf; ++ TRACE2("%s", keyname); ++ ++ mutex_lock(&loader_mutex); ++ nt_list_for_each_entry(setting, &nmb->wnd->wd->settings, list) { ++ if (strnicmp(keyname, setting->name, ansi.length) == 0) { ++ mutex_unlock(&loader_mutex); ++ if (ndis_decode_setting(setting, param)) ++ *status = NDIS_STATUS_FAILURE; ++ else ++ *status = NDIS_STATUS_SUCCESS; ++ RtlFreeAnsiString(&ansi); ++ EXIT2(return); ++ } ++ } ++ mutex_unlock(&loader_mutex); ++ setting = kzalloc(sizeof(*setting), GFP_KERNEL); ++ if (setting) { ++ if (ansi.length == ansi.max_length) ++ ansi.length--; ++ memcpy(setting->name, keyname, ansi.length); ++ setting->name[ansi.length] = 0; ++ if (ndis_decode_setting(setting, param)) ++ *status = NDIS_STATUS_FAILURE; ++ else { ++ *status = NDIS_STATUS_SUCCESS; ++ mutex_lock(&loader_mutex); ++ InsertTailList(&nmb->wnd->wd->settings, &setting->list); ++ mutex_unlock(&loader_mutex); ++ } ++ } else ++ *status = NDIS_STATUS_RESOURCES; ++ ++ RtlFreeAnsiString(&ansi); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisReadNetworkAddress,4) ++ (NDIS_STATUS *status, void **addr, UINT *len, ++ struct ndis_mp_block *nmb) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ struct ndis_configuration_parameter *param; ++ struct unicode_string key; ++ struct ansi_string ansi; ++ typeof(wnd->mac) mac; ++ int i, ret; ++ ++ ENTER2("%p", nmb); ++ RtlInitAnsiString(&ansi, "NetworkAddress"); ++ *status = NDIS_STATUS_FAILURE; ++ if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS) ++ EXIT1(return); ++ ++ NdisReadConfiguration(&ret, ¶m, nmb, &key, NdisParameterString); ++ RtlFreeUnicodeString(&key); ++ if (ret != NDIS_STATUS_SUCCESS) ++ EXIT1(return); ++ ret = RtlUnicodeStringToAnsiString(&ansi, ¶m->data.string, TRUE); ++ if (ret != STATUS_SUCCESS) ++ EXIT1(return); ++ ++ i = 0; ++ if (ansi.length >= 2 * sizeof(mac)) { ++ for (i = 0; i < sizeof(mac); i++) { ++ char c[3]; ++ int x; ++ c[0] = ansi.buf[i*2]; ++ c[1] = ansi.buf[i*2+1]; ++ c[2] = 0; ++ ret = sscanf(c, "%x", &x); ++ if (ret != 1) ++ break; ++ mac[i] = x; ++ } ++ } ++ TRACE2("%s, %d, " MACSTR, ansi.buf, i, MAC2STR(mac)); ++ RtlFreeAnsiString(&ansi); ++ if (i == sizeof(mac)) { ++ memcpy(wnd->mac, mac, sizeof(wnd->mac)); ++ *len = sizeof(mac); ++ *addr = wnd->mac; ++ *status = NDIS_STATUS_SUCCESS; ++ } ++ EXIT1(return); ++} ++ ++wstdcall void WIN_FUNC(NdisInitializeString,2) ++ (struct unicode_string *dest, UCHAR *src) ++{ ++ struct ansi_string ansi; ++ ++ ENTER2(""); ++ if (src == NULL) { ++ dest->length = dest->max_length = 0; ++ dest->buf = NULL; ++ } else { ++ RtlInitAnsiString(&ansi, src); ++ /* the string is freed with NdisFreeMemory */ ++ RtlAnsiStringToUnicodeString(dest, &ansi, TRUE); ++ } ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisInitAnsiString,2) ++ (struct ansi_string *dst, CHAR *src) ++{ ++ RtlInitAnsiString(dst, src); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisInitUnicodeString,2) ++ (struct unicode_string *dest, const wchar_t *src) ++{ ++ RtlInitUnicodeString(dest, src); ++ return; ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisAnsiStringToUnicodeString,2) ++ (struct unicode_string *dst, struct ansi_string *src) ++{ ++ ENTER2(""); ++ if (dst == NULL || src == NULL) ++ EXIT2(return NDIS_STATUS_FAILURE); ++ if (RtlAnsiStringToUnicodeString(dst, src, FALSE) == STATUS_SUCCESS) ++ return NDIS_STATUS_SUCCESS; ++ else ++ return NDIS_STATUS_FAILURE; ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisUnicodeStringToAnsiString,2) ++ (struct ansi_string *dst, struct unicode_string *src) ++{ ++ ENTER2(""); ++ if (dst == NULL || src == NULL) ++ EXIT2(return NDIS_STATUS_FAILURE); ++ if (RtlUnicodeStringToAnsiString(dst, src, FALSE) == STATUS_SUCCESS) ++ return NDIS_STATUS_SUCCESS; ++ else ++ return NDIS_STATUS_FAILURE; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(NdisUpcaseUnicodeString,2) ++ (struct unicode_string *dst, struct unicode_string *src) ++{ ++ EXIT2(return RtlUpcaseUnicodeString(dst, src, FALSE)); ++} ++ ++wstdcall void WIN_FUNC(NdisMSetAttributesEx,5) ++ (struct ndis_mp_block *nmb, void *mp_ctx, ++ UINT hangcheck_interval, UINT attributes, ULONG adaptertype) ++{ ++ struct ndis_device *wnd; ++ ++ ENTER1("%p, %p, %d, %08x, %d", nmb, mp_ctx, hangcheck_interval, ++ attributes, adaptertype); ++ wnd = nmb->wnd; ++ nmb->mp_ctx = mp_ctx; ++ wnd->attributes = attributes; ++ ++ if ((attributes & NDIS_ATTRIBUTE_BUS_MASTER) && ++ wrap_is_pci_bus(wnd->wd->dev_bus)) ++ pci_set_master(wnd->wd->pci.pdev); ++ ++ if (hangcheck_interval > 0) ++ wnd->hangcheck_interval = 2 * hangcheck_interval * HZ; ++ else ++ wnd->hangcheck_interval = 2 * HZ; ++ ++ EXIT1(return); ++} ++ ++wstdcall ULONG WIN_FUNC(NdisReadPciSlotInformation,5) ++ (struct ndis_mp_block *nmb, ULONG slot, ++ ULONG offset, char *buf, ULONG len) ++{ ++ struct wrap_device *wd = nmb->wnd->wd; ++ ULONG i; ++ if (!wrap_is_pci_bus(wd->dev_bus)) { ++ ERROR("used on a non-PCI device"); ++ return 0; ++ } ++ for (i = 0; i < len; i++) ++ if (pci_read_config_byte(wd->pci.pdev, offset + i, &buf[i]) != ++ PCIBIOS_SUCCESSFUL) ++ break; ++ DBG_BLOCK(2) { ++ if (i != len) ++ WARNING("%u, %u", i, len); ++ } ++ return i; ++} ++ ++wstdcall ULONG WIN_FUNC(NdisImmediateReadPciSlotInformation,5) ++ (struct ndis_mp_block *nmb, ULONG slot, ++ ULONG offset, char *buf, ULONG len) ++{ ++ return NdisReadPciSlotInformation(nmb, slot, offset, buf, len); ++} ++ ++wstdcall ULONG WIN_FUNC(NdisWritePciSlotInformation,5) ++ (struct ndis_mp_block *nmb, ULONG slot, ++ ULONG offset, char *buf, ULONG len) ++{ ++ struct wrap_device *wd = nmb->wnd->wd; ++ ULONG i; ++ if (!wrap_is_pci_bus(wd->dev_bus)) { ++ ERROR("used on a non-PCI device"); ++ return 0; ++ } ++ for (i = 0; i < len; i++) ++ if (pci_write_config_byte(wd->pci.pdev, offset + i, buf[i]) != ++ PCIBIOS_SUCCESSFUL) ++ break; ++ DBG_BLOCK(2) { ++ if (i != len) ++ WARNING("%u, %u", i, len); ++ } ++ return i; ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterIoPortRange,4) ++ (void **virt, struct ndis_mp_block *nmb, UINT start, UINT len) ++{ ++ ENTER3("%08x %08x", start, len); ++ *virt = (void *)(ULONG_PTR)start; ++ return NDIS_STATUS_SUCCESS; ++} ++ ++wstdcall void WIN_FUNC(NdisMDeregisterIoPortRange,4) ++ (struct ndis_mp_block *nmb, UINT start, UINT len, void* virt) ++{ ++ ENTER1("%08x %08x", start, len); ++} ++ ++wstdcall void WIN_FUNC(NdisReadPortUchar,3) ++ (struct ndis_mp_block *nmb, ULONG port, char *data) ++{ ++ *data = inb(port); ++} ++ ++wstdcall void WIN_FUNC(NdisImmediateReadPortUchar,3) ++ (struct ndis_mp_block *nmb, ULONG port, char *data) ++{ ++ *data = inb(port); ++} ++ ++wstdcall void WIN_FUNC(NdisWritePortUchar,3) ++ (struct ndis_mp_block *nmb, ULONG port, char data) ++{ ++ outb(data, port); ++} ++ ++wstdcall void WIN_FUNC(NdisImmediateWritePortUchar,3) ++ (struct ndis_mp_block *nmb, ULONG port, char data) ++{ ++ outb(data, port); ++} ++ ++wstdcall void WIN_FUNC(NdisMQueryAdapterResources,4) ++ (NDIS_STATUS *status, struct ndis_mp_block *nmb, ++ NDIS_RESOURCE_LIST *resource_list, UINT *size) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ NDIS_RESOURCE_LIST *list; ++ UINT resource_length; ++ ++ list = &wnd->wd->resource_list->list->partial_resource_list; ++ resource_length = sizeof(struct cm_partial_resource_list) + ++ sizeof(struct cm_partial_resource_descriptor) * ++ (list->count - 1); ++ TRACE2("%p, %p,%d (%d), %p %d %d", wnd, resource_list, *size, ++ resource_length, &list->partial_descriptors[list->count-1], ++ list->partial_descriptors[list->count-1].u.interrupt.level, ++ list->partial_descriptors[list->count-1].u.interrupt.vector); ++ if (*size < sizeof(*list)) { ++ *size = resource_length; ++ *status = NDIS_STATUS_BUFFER_TOO_SHORT; ++ } else { ++ ULONG count; ++ if (*size >= resource_length) { ++ *size = resource_length; ++ count = list->count; ++ } else { ++ UINT n = sizeof(*list); ++ count = 1; ++ while (count++ < list->count && n < *size) ++ n += sizeof(list->partial_descriptors); ++ *size = n; ++ } ++ memcpy(resource_list, list, *size); ++ resource_list->count = count; ++ *status = NDIS_STATUS_SUCCESS; ++ } ++ EXIT2(return); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMPciAssignResources,3) ++ (struct ndis_mp_block *nmb, ULONG slot_number, ++ NDIS_RESOURCE_LIST **resources) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ++ ENTER2("%p, %p", wnd, wnd->wd->resource_list); ++ *resources = &wnd->wd->resource_list->list->partial_resource_list; ++ EXIT2(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMMapIoSpace,4) ++ (void __iomem **virt, struct ndis_mp_block *nmb, ++ NDIS_PHY_ADDRESS phy_addr, UINT len) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ++ ENTER2("%llx, %d", phy_addr, len); ++ *virt = MmMapIoSpace(phy_addr, len, MmCached); ++ if (*virt == NULL) { ++ ERROR("ioremap failed"); ++ EXIT2(return NDIS_STATUS_FAILURE); ++ } ++ wnd->mem_start = phy_addr; ++ wnd->mem_end = phy_addr + len; ++ TRACE2("%p", *virt); ++ EXIT2(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(NdisMUnmapIoSpace,3) ++ (struct ndis_mp_block *nmb, void __iomem *virt, UINT len) ++{ ++ ENTER2("%p, %d", virt, len); ++ MmUnmapIoSpace(virt, len); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisAllocateSpinLock,1) ++ (struct ndis_spinlock *lock) ++{ ++ TRACE4("lock %p, %p", lock, &lock->klock); ++ KeInitializeSpinLock(&lock->klock); ++ lock->irql = PASSIVE_LEVEL; ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisFreeSpinLock,1) ++ (struct ndis_spinlock *lock) ++{ ++ TRACE4("lock %p, %p", lock, &lock->klock); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisAcquireSpinLock,1) ++ (struct ndis_spinlock *lock) ++{ ++ ENTER6("lock %p, %p", lock, &lock->klock); ++// assert_irql(_irql_ <= DISPATCH_LEVEL); ++ lock->irql = nt_spin_lock_irql(&lock->klock, DISPATCH_LEVEL); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisReleaseSpinLock,1) ++ (struct ndis_spinlock *lock) ++{ ++ ENTER6("lock %p, %p", lock, &lock->klock); ++// assert_irql(_irql_ == DISPATCH_LEVEL); ++ nt_spin_unlock_irql(&lock->klock, lock->irql); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisDprAcquireSpinLock,1) ++ (struct ndis_spinlock *lock) ++{ ++ ENTER6("lock %p", &lock->klock); ++// assert_irql(_irql_ == DISPATCH_LEVEL); ++ nt_spin_lock(&lock->klock); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisDprReleaseSpinLock,1) ++ (struct ndis_spinlock *lock) ++{ ++ ENTER6("lock %p", &lock->klock); ++// assert_irql(_irql_ == DISPATCH_LEVEL); ++ nt_spin_unlock(&lock->klock); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisInitializeReadWriteLock,1) ++ (struct ndis_rw_lock *rw_lock) ++{ ++ ENTER3("%p", rw_lock); ++ memset(rw_lock, 0, sizeof(*rw_lock)); ++ KeInitializeSpinLock(&rw_lock->klock); ++ return; ++} ++ ++/* read/write locks are implemented in a rather simplistic way - we ++ * should probably use Linux's rw_lock implementation */ ++ ++wstdcall void WIN_FUNC(NdisAcquireReadWriteLock,3) ++ (struct ndis_rw_lock *rw_lock, BOOLEAN write, ++ struct lock_state *lock_state) ++{ ++ if (write) { ++ while (1) { ++ if (cmpxchg(&rw_lock->count, 0, -1) == 0) ++ return; ++ while (rw_lock->count) ++ cpu_relax(); ++ } ++ return; ++ } ++ while (1) { ++ typeof(rw_lock->count) count; ++ while ((count = rw_lock->count) < 0) ++ cpu_relax(); ++ if (cmpxchg(&rw_lock->count, count, count + 1) == count) ++ return; ++ } ++} ++ ++wstdcall void WIN_FUNC(NdisReleaseReadWriteLock,2) ++ (struct ndis_rw_lock *rw_lock, struct lock_state *lock_state) ++{ ++ if (rw_lock->count > 0) ++ pre_atomic_add(rw_lock->count, -1); ++ else if (rw_lock->count == -1) ++ rw_lock->count = 0; ++ else ++ WARNING("invalid state: %d", rw_lock->count); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateMapRegisters,5) ++ (struct ndis_mp_block *nmb, UINT dmachan, ++ NDIS_DMA_SIZE dmasize, ULONG basemap, ULONG max_buf_size) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ++ ENTER2("%p, %d %d %d %d", wnd, dmachan, dmasize, basemap, max_buf_size); ++ if (!wrap_is_pci_bus(wnd->wd->dev_bus)) { ++ ERROR("used on a non-PCI device"); ++ return NDIS_STATUS_NOT_SUPPORTED; ++ } ++ if (wnd->dma_map_count > 0) { ++ WARNING("%s: map registers already allocated: %u", ++ wnd->net_dev->name, wnd->dma_map_count); ++ EXIT2(return NDIS_STATUS_RESOURCES); ++ } ++ if (dmasize == NDIS_DMA_24BITS) { ++ if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_BIT_MASK(24)) || ++ pci_set_consistent_dma_mask(wnd->wd->pci.pdev, ++ DMA_BIT_MASK(24))) ++ WARNING("setting dma mask failed"); ++ } else if (dmasize == NDIS_DMA_32BITS) { ++ /* consistent dma is in low 32-bits by default */ ++ if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_BIT_MASK(32))) ++ WARNING("setting dma mask failed"); ++#ifdef CONFIG_X86_64 ++ } else if (dmasize == NDIS_DMA_64BITS) { ++ if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_BIT_MASK(64)) || ++ pci_set_consistent_dma_mask(wnd->wd->pci.pdev, ++ DMA_BIT_MASK(64))) ++ WARNING("setting dma mask failed"); ++ else ++ wnd->net_dev->features |= NETIF_F_HIGHDMA; ++#endif ++ } else { ++ ERROR("dmasize %d not supported", dmasize); ++ EXIT2(return NDIS_STATUS_NOT_SUPPORTED); ++ } ++ /* since memory for buffer is allocated with kmalloc, buffer ++ * is physically contiguous, so entire map will fit in one ++ * register */ ++ if (basemap > 64) { ++ WARNING("Windows driver %s requesting too many (%u) " ++ "map registers", wnd->wd->driver->name, basemap); ++ /* As per NDIS, NDIS_STATUS_RESOURCES should be ++ * returned, but with that Atheros PCI driver fails - ++ * for now tolerate it */ ++// EXIT2(return NDIS_STATUS_RESOURCES); ++ } ++ ++ wnd->dma_map_addr = kzalloc(basemap * sizeof(*(wnd->dma_map_addr)), ++ GFP_KERNEL); ++ if (!wnd->dma_map_addr) ++ EXIT2(return NDIS_STATUS_RESOURCES); ++ wnd->dma_map_count = basemap; ++ TRACE2("%u", wnd->dma_map_count); ++ EXIT2(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(NdisMFreeMapRegisters,1) ++ (struct ndis_mp_block *nmb) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ int i; ++ ++ ENTER2("wnd: %p", wnd); ++ if (wnd->dma_map_addr) { ++ for (i = 0; i < wnd->dma_map_count; i++) { ++ if (wnd->dma_map_addr[i]) ++ WARNING("%s: dma addr 0x%llx not freed by " ++ "Windows driver", wnd->net_dev->name, ++ (unsigned long long)wnd->dma_map_addr[i]); ++ } ++ kfree(wnd->dma_map_addr); ++ wnd->dma_map_addr = NULL; ++ } else ++ WARNING("map registers already freed?"); ++ wnd->dma_map_count = 0; ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisMStartBufferPhysicalMapping,6) ++ (struct ndis_mp_block *nmb, ndis_buffer *buf, ++ ULONG index, BOOLEAN write_to_dev, ++ struct ndis_phy_addr_unit *phy_addr_array, UINT *array_size) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ++ ENTER3("%p, %p, %u, %u", wnd, buf, index, wnd->dma_map_count); ++ if (!wrap_is_pci_bus(wnd->wd->dev_bus)) { ++ ERROR("used on a non-PCI device"); ++ return; ++ } ++ if (unlikely(wnd->sg_dma_size || !write_to_dev || ++ index >= wnd->dma_map_count)) { ++ WARNING("invalid request: %d, %d, %d, %d", wnd->sg_dma_size, ++ write_to_dev, index, wnd->dma_map_count); ++ phy_addr_array[0].phy_addr = 0; ++ phy_addr_array[0].length = 0; ++ *array_size = 0; ++ return; ++ } ++ if (wnd->dma_map_addr[index]) { ++ TRACE2("buffer %p at %d is already mapped: %llx", buf, index, ++ (unsigned long long)wnd->dma_map_addr[index]); ++// *array_size = 1; ++ return; ++ } ++ TRACE3("%p, %p, %u", buf, MmGetSystemAddressForMdl(buf), ++ MmGetMdlByteCount(buf)); ++ DBG_BLOCK(4) { ++ dump_bytes(__func__, MmGetSystemAddressForMdl(buf), ++ MmGetMdlByteCount(buf)); ++ } ++ wnd->dma_map_addr[index] = ++ PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, ++ MmGetSystemAddressForMdl(buf), ++ MmGetMdlByteCount(buf), PCI_DMA_TODEVICE); ++ phy_addr_array[0].phy_addr = wnd->dma_map_addr[index]; ++ phy_addr_array[0].length = MmGetMdlByteCount(buf); ++ TRACE4("%llx, %d, %d", phy_addr_array[0].phy_addr, ++ phy_addr_array[0].length, index); ++ *array_size = 1; ++} ++ ++wstdcall void WIN_FUNC(NdisMCompleteBufferPhysicalMapping,3) ++ (struct ndis_mp_block *nmb, ndis_buffer *buf, ULONG index) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ++ ENTER3("%p, %p %u (%u)", wnd, buf, index, wnd->dma_map_count); ++ ++ if (!wrap_is_pci_bus(wnd->wd->dev_bus)) { ++ ERROR("used on a non-PCI device"); ++ return; ++ } ++ if (unlikely(wnd->sg_dma_size)) ++ WARNING("buffer %p may have been unmapped already", buf); ++ if (index >= wnd->dma_map_count) { ++ ERROR("invalid map register (%u >= %u)", ++ index, wnd->dma_map_count); ++ return; ++ } ++ TRACE4("%llx", (unsigned long long)wnd->dma_map_addr[index]); ++ if (wnd->dma_map_addr[index]) { ++ PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, wnd->dma_map_addr[index], ++ MmGetMdlByteCount(buf), PCI_DMA_TODEVICE); ++ wnd->dma_map_addr[index] = 0; ++ } else ++ WARNING("map registers at %u not used", index); ++} ++ ++wstdcall void WIN_FUNC(NdisMAllocateSharedMemory,5) ++ (struct ndis_mp_block *nmb, ULONG size, ++ BOOLEAN cached, void **virt, NDIS_PHY_ADDRESS *phys) ++{ ++ dma_addr_t dma_addr; ++ struct wrap_device *wd = nmb->wnd->wd; ++ ++ ENTER3("size: %u, cached: %d", size, cached); ++ if (!wrap_is_pci_bus(wd->dev_bus)) { ++ ERROR("used on a non-PCI device"); ++ return; ++ } ++ *virt = PCI_DMA_ALLOC_COHERENT(wd->pci.pdev, size, &dma_addr); ++ if (*virt) ++ *phys = dma_addr; ++ else ++ WARNING("couldn't allocate %d bytes of %scached DMA memory", ++ size, cached ? "" : "un-"); ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(NdisMFreeSharedMemory,5) ++ (struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached, ++ void *virt, NDIS_PHY_ADDRESS addr) ++{ ++ struct wrap_device *wd = nmb->wnd->wd; ++ ENTER3("%p, %llx, %u", virt, addr, size); ++ if (!wrap_is_pci_bus(wd->dev_bus)) { ++ ERROR("used on a non-PCI device"); ++ return; ++ } ++ PCI_DMA_FREE_COHERENT(wd->pci.pdev, size, virt, addr); ++ EXIT3(return); ++} ++ ++wstdcall void alloc_shared_memory_async(void *arg1, void *arg2) ++{ ++ struct ndis_device *wnd; ++ struct alloc_shared_mem *alloc_shared_mem; ++ struct miniport *mp; ++ void *virt; ++ NDIS_PHY_ADDRESS phys; ++ KIRQL irql; ++ ++ wnd = arg1; ++ alloc_shared_mem = arg2; ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ NdisMAllocateSharedMemory(wnd->nmb, alloc_shared_mem->size, ++ alloc_shared_mem->cached, &virt, &phys); ++ irql = serialize_lock_irql(wnd); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ LIN2WIN5(mp->alloc_complete, wnd->nmb, virt, ++ &phys, alloc_shared_mem->size, alloc_shared_mem->ctx); ++ serialize_unlock_irql(wnd, irql); ++ kfree(alloc_shared_mem); ++} ++WIN_FUNC_DECL(alloc_shared_memory_async,2) ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateSharedMemoryAsync,4) ++ (struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached, void *ctx) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ struct alloc_shared_mem *alloc_shared_mem; ++ ++ ENTER3("wnd: %p", wnd); ++ alloc_shared_mem = kmalloc(sizeof(*alloc_shared_mem), irql_gfp()); ++ if (!alloc_shared_mem) { ++ WARNING("couldn't allocate memory"); ++ return NDIS_STATUS_FAILURE; ++ } ++ ++ alloc_shared_mem->size = size; ++ alloc_shared_mem->cached = cached; ++ alloc_shared_mem->ctx = ctx; ++ if (schedule_ntos_work_item(WIN_FUNC_PTR(alloc_shared_memory_async,2), ++ wnd, alloc_shared_mem)) ++ EXIT3(return NDIS_STATUS_FAILURE); ++ EXIT3(return NDIS_STATUS_PENDING); ++} ++ ++/* Some drivers allocate NDIS_BUFFER (aka MDL) very often; instead of ++ * allocating and freeing with kernel functions, we chain them into ++ * ndis_buffer_pool. When an MDL is freed, it is added to the list of ++ * free MDLs. When allocated, we first check if there is one in free ++ * list and if so just return it; otherwise, we allocate a new one and ++ * return that. This reduces memory fragmentation. Windows DDK says ++ * that the driver itself shouldn't check what is returned in ++ * pool_handle, presumably because buffer pools are not used in ++ * XP. However, as long as driver follows rest of the semantics - that ++ * it should indicate maximum number of MDLs used with num_descr and ++ * pass the same pool_handle in other buffer functions, this should ++ * work. Sadly, though, NdisFreeBuffer doesn't pass the pool_handle, ++ * so we use 'process' field of MDL to store pool_handle. */ ++ ++wstdcall void WIN_FUNC(NdisAllocateBufferPool,3) ++ (NDIS_STATUS *status, struct ndis_buffer_pool **pool_handle, ++ UINT num_descr) ++{ ++ struct ndis_buffer_pool *pool; ++ ++ ENTER1("buffers: %d", num_descr); ++ pool = kmalloc(sizeof(*pool), irql_gfp()); ++ if (!pool) { ++ *status = NDIS_STATUS_RESOURCES; ++ EXIT3(return); ++ } ++ spin_lock_init(&pool->lock); ++ pool->max_descr = num_descr; ++ pool->num_allocated_descr = 0; ++ pool->free_descr = NULL; ++ *pool_handle = pool; ++ *status = NDIS_STATUS_SUCCESS; ++ TRACE1("pool: %p, num_descr: %d", pool, num_descr); ++ EXIT1(return); ++} ++ ++wstdcall void WIN_FUNC(NdisAllocateBuffer,5) ++ (NDIS_STATUS *status, ndis_buffer **buffer, ++ struct ndis_buffer_pool *pool, void *virt, UINT length) ++{ ++ ndis_buffer *descr; ++ ++ ENTER4("pool: %p (%d)", pool, pool->num_allocated_descr); ++ /* NDIS drivers should call this at DISPATCH_LEVEL, but ++ * alloc_tx_packet calls at SOFT_IRQL */ ++ assert_irql(_irql_ <= SOFT_LEVEL); ++ if (!pool) { ++ *status = NDIS_STATUS_FAILURE; ++ *buffer = NULL; ++ EXIT4(return); ++ } ++ spin_lock_bh(&pool->lock); ++ if ((descr = pool->free_descr)) ++ pool->free_descr = descr->next; ++ spin_unlock_bh(&pool->lock); ++ if (descr) { ++ typeof(descr->flags) flags; ++ flags = descr->flags; ++ memset(descr, 0, sizeof(*descr)); ++ MmInitializeMdl(descr, virt, length); ++ if (flags & MDL_CACHE_ALLOCATED) ++ descr->flags |= MDL_CACHE_ALLOCATED; ++ } else { ++ if (pool->num_allocated_descr > pool->max_descr) { ++ TRACE2("pool %p is full: %d(%d)", pool, ++ pool->num_allocated_descr, pool->max_descr); ++#ifndef ALLOW_POOL_OVERFLOW ++ *status = NDIS_STATUS_FAILURE; ++ *buffer = NULL; ++ return; ++#endif ++ } ++ descr = allocate_init_mdl(virt, length); ++ if (!descr) { ++ WARNING("couldn't allocate buffer"); ++ *status = NDIS_STATUS_FAILURE; ++ *buffer = NULL; ++ EXIT4(return); ++ } ++ TRACE4("buffer %p for %p, %d", descr, virt, length); ++ atomic_inc_var(pool->num_allocated_descr); ++ } ++ /* TODO: make sure this mdl can map given buffer */ ++ MmBuildMdlForNonPagedPool(descr); ++// descr->flags |= MDL_ALLOCATED_FIXED_SIZE | ++// MDL_MAPPED_TO_SYSTEM_VA | MDL_PAGES_LOCKED; ++ descr->pool = pool; ++ *buffer = descr; ++ *status = NDIS_STATUS_SUCCESS; ++ TRACE4("buffer: %p", descr); ++ EXIT4(return); ++} ++ ++wstdcall void WIN_FUNC(NdisFreeBuffer,1) ++ (ndis_buffer *buffer) ++{ ++ struct ndis_buffer_pool *pool; ++ ++ ENTER4("%p", buffer); ++ if (!buffer || !buffer->pool) { ++ ERROR("invalid buffer"); ++ EXIT4(return); ++ } ++ pool = buffer->pool; ++ if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_BUFFERS) { ++ /* NB NB NB: set mdl's 'pool' field to NULL before ++ * calling free_mdl; otherwise free_mdl calls ++ * NdisFreeBuffer back */ ++ atomic_dec_var(pool->num_allocated_descr); ++ buffer->pool = NULL; ++ free_mdl(buffer); ++ } else { ++ spin_lock_bh(&pool->lock); ++ buffer->next = pool->free_descr; ++ pool->free_descr = buffer; ++ spin_unlock_bh(&pool->lock); ++ } ++ EXIT4(return); ++} ++ ++wstdcall void WIN_FUNC(NdisFreeBufferPool,1) ++ (struct ndis_buffer_pool *pool) ++{ ++ ndis_buffer *cur, *next; ++ ++ TRACE3("pool: %p", pool); ++ if (!pool) { ++ WARNING("invalid pool"); ++ EXIT3(return); ++ } ++ spin_lock_bh(&pool->lock); ++ cur = pool->free_descr; ++ while (cur) { ++ next = cur->next; ++ cur->pool = NULL; ++ free_mdl(cur); ++ cur = next; ++ } ++ spin_unlock_bh(&pool->lock); ++ kfree(pool); ++ pool = NULL; ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(NdisAdjustBufferLength,2) ++ (ndis_buffer *buffer, UINT length) ++{ ++ ENTER4("%p, %d", buffer, length); ++ buffer->bytecount = length; ++} ++ ++wstdcall void WIN_FUNC(NdisQueryBuffer,3) ++ (ndis_buffer *buffer, void **virt, UINT *length) ++{ ++ ENTER4("buffer: %p", buffer); ++ if (virt) ++ *virt = MmGetSystemAddressForMdl(buffer); ++ *length = MmGetMdlByteCount(buffer); ++ TRACE4("%p, %u", virt ? *virt : NULL, *length); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisQueryBufferSafe,4) ++ (ndis_buffer *buffer, void **virt, UINT *length, ++ enum mm_page_priority priority) ++{ ++ ENTER4("%p, %p, %p, %d", buffer, virt, length, priority); ++ if (virt) ++ *virt = MmGetSystemAddressForMdlSafe(buffer, priority); ++ *length = MmGetMdlByteCount(buffer); ++ TRACE4("%p, %u", virt ? *virt : NULL, *length); ++} ++ ++wstdcall void *WIN_FUNC(NdisBufferVirtualAddress,1) ++ (ndis_buffer *buffer) ++{ ++ ENTER3("%p", buffer); ++ return MmGetSystemAddressForMdl(buffer); ++} ++ ++wstdcall ULONG WIN_FUNC(NdisBufferLength,1) ++ (ndis_buffer *buffer) ++{ ++ ENTER3("%p", buffer); ++ return MmGetMdlByteCount(buffer); ++} ++ ++wstdcall void WIN_FUNC(NdisQueryBufferOffset,3) ++ (ndis_buffer *buffer, UINT *offset, UINT *length) ++{ ++ ENTER3("%p", buffer); ++ *offset = MmGetMdlByteOffset(buffer); ++ *length = MmGetMdlByteCount(buffer); ++ TRACE3("%d, %d", *offset, *length); ++} ++ ++wstdcall void WIN_FUNC(NdisUnchainBufferAtBack,2) ++ (struct ndis_packet *packet, ndis_buffer **buffer) ++{ ++ ndis_buffer *b, *btail; ++ ++ ENTER3("%p", packet); ++ b = packet->private.buffer_head; ++ if (!b) { ++ /* no buffer in packet */ ++ *buffer = NULL; ++ EXIT3(return); ++ } ++ btail = packet->private.buffer_tail; ++ *buffer = btail; ++ if (b == btail) { ++ /* one buffer in packet */ ++ packet->private.buffer_head = NULL; ++ packet->private.buffer_tail = NULL; ++ } else { ++ while (b->next != btail) ++ b = b->next; ++ packet->private.buffer_tail = b; ++ b->next = NULL; ++ } ++ packet->private.valid_counts = FALSE; ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(NdisUnchainBufferAtFront,2) ++ (struct ndis_packet *packet, ndis_buffer **buffer) ++{ ++ ENTER3("%p", packet); ++ if (packet->private.buffer_head == NULL) { ++ /* no buffer in packet */ ++ *buffer = NULL; ++ EXIT3(return); ++ } ++ ++ *buffer = packet->private.buffer_head; ++ if (packet->private.buffer_head == packet->private.buffer_tail) { ++ /* one buffer in packet */ ++ packet->private.buffer_head = NULL; ++ packet->private.buffer_tail = NULL; ++ } else ++ packet->private.buffer_head = (*buffer)->next; ++ ++ packet->private.valid_counts = FALSE; ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacketSafe,6) ++ (struct ndis_packet *packet, ndis_buffer **first_buffer, ++ void **first_buffer_va, UINT *first_buffer_length, ++ UINT *total_buffer_length, enum mm_page_priority priority) ++{ ++ ndis_buffer *b = packet->private.buffer_head; ++ ++ ENTER3("%p(%p)", packet, b); ++ *first_buffer = b; ++ if (b) { ++ *first_buffer_va = MmGetSystemAddressForMdlSafe(b, priority); ++ *first_buffer_length = *total_buffer_length = ++ MmGetMdlByteCount(b); ++ for (b = b->next; b; b = b->next) ++ *total_buffer_length += MmGetMdlByteCount(b); ++ } else { ++ *first_buffer_va = NULL; ++ *first_buffer_length = 0; ++ *total_buffer_length = 0; ++ } ++ TRACE3("%p, %d, %d", *first_buffer_va, *first_buffer_length, ++ *total_buffer_length); ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacket,6) ++ (struct ndis_packet *packet, ndis_buffer **first_buffer, ++ void **first_buffer_va, UINT *first_buffer_length, ++ UINT *total_buffer_length, enum mm_page_priority priority) ++{ ++ NdisGetFirstBufferFromPacketSafe(packet, first_buffer, ++ first_buffer_va, first_buffer_length, ++ total_buffer_length, ++ NormalPagePriority); ++} ++ ++wstdcall void WIN_FUNC(NdisAllocatePacketPoolEx,5) ++ (NDIS_STATUS *status, struct ndis_packet_pool **pool_handle, ++ UINT num_descr, UINT overflowsize, UINT proto_rsvd_length) ++{ ++ struct ndis_packet_pool *pool; ++ ++ ENTER3("buffers: %d, length: %d", num_descr, proto_rsvd_length); ++ pool = kzalloc(sizeof(*pool), irql_gfp()); ++ if (!pool) { ++ *status = NDIS_STATUS_RESOURCES; ++ EXIT3(return); ++ } ++ spin_lock_init(&pool->lock); ++ pool->max_descr = num_descr; ++ pool->num_allocated_descr = 0; ++ pool->num_used_descr = 0; ++ pool->free_descr = NULL; ++ pool->proto_rsvd_length = proto_rsvd_length; ++ *pool_handle = pool; ++ *status = NDIS_STATUS_SUCCESS; ++ TRACE3("pool: %p", pool); ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(NdisAllocatePacketPool,4) ++ (NDIS_STATUS *status, struct ndis_packet_pool **pool_handle, ++ UINT num_descr, UINT proto_rsvd_length) ++{ ++ NdisAllocatePacketPoolEx(status, pool_handle, num_descr, 0, ++ proto_rsvd_length); ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(NdisFreePacketPool,1) ++ (struct ndis_packet_pool *pool) ++{ ++ struct ndis_packet *packet, *next; ++ ++ ENTER3("pool: %p", pool); ++ if (!pool) { ++ WARNING("invalid pool"); ++ EXIT3(return); ++ } ++ spin_lock_bh(&pool->lock); ++ packet = pool->free_descr; ++ while (packet) { ++ next = (struct ndis_packet *)packet->reserved[0]; ++ kfree(packet); ++ packet = next; ++ } ++ pool->num_allocated_descr = 0; ++ pool->num_used_descr = 0; ++ pool->free_descr = NULL; ++ spin_unlock_bh(&pool->lock); ++ kfree(pool); ++ EXIT3(return); ++} ++ ++wstdcall UINT WIN_FUNC(NdisPacketPoolUsage,1) ++ (struct ndis_packet_pool *pool) ++{ ++ EXIT4(return pool->num_used_descr); ++} ++ ++wstdcall void WIN_FUNC(NdisAllocatePacket,3) ++ (NDIS_STATUS *status, struct ndis_packet **ndis_packet, ++ struct ndis_packet_pool *pool) ++{ ++ struct ndis_packet *packet; ++ int packet_length; ++ ++ ENTER4("pool: %p", pool); ++ if (!pool) { ++ *status = NDIS_STATUS_RESOURCES; ++ *ndis_packet = NULL; ++ EXIT4(return); ++ } ++ assert_irql(_irql_ <= SOFT_LEVEL); ++ if (pool->num_used_descr > pool->max_descr) { ++ TRACE3("pool %p is full: %d(%d)", pool, ++ pool->num_used_descr, pool->max_descr); ++#ifndef ALLOW_POOL_OVERFLOW ++ *status = NDIS_STATUS_RESOURCES; ++ *ndis_packet = NULL; ++ return; ++#endif ++ } ++ /* packet has space for 1 byte in protocol_reserved field */ ++ packet_length = sizeof(*packet) - 1 + pool->proto_rsvd_length + ++ sizeof(struct ndis_packet_oob_data); ++ spin_lock_bh(&pool->lock); ++ if ((packet = pool->free_descr)) ++ pool->free_descr = (void *)packet->reserved[0]; ++ spin_unlock_bh(&pool->lock); ++ if (!packet) { ++ packet = kmalloc(packet_length, irql_gfp()); ++ if (!packet) { ++ WARNING("couldn't allocate packet"); ++ *status = NDIS_STATUS_RESOURCES; ++ *ndis_packet = NULL; ++ return; ++ } ++ atomic_inc_var(pool->num_allocated_descr); ++ } ++ TRACE4("%p, %p", pool, packet); ++ atomic_inc_var(pool->num_used_descr); ++ memset(packet, 0, packet_length); ++ packet->private.oob_offset = ++ packet_length - sizeof(struct ndis_packet_oob_data); ++ packet->private.packet_flags = fPACKET_ALLOCATED_BY_NDIS; ++ packet->private.pool = pool; ++ *ndis_packet = packet; ++ *status = NDIS_STATUS_SUCCESS; ++ EXIT4(return); ++} ++ ++wstdcall void WIN_FUNC(NdisDprAllocatePacket,3) ++ (NDIS_STATUS *status, struct ndis_packet **packet, ++ struct ndis_packet_pool *pool) ++{ ++ NdisAllocatePacket(status, packet, pool); ++} ++ ++wstdcall void WIN_FUNC(NdisFreePacket,1) ++ (struct ndis_packet *packet) ++{ ++ struct ndis_packet_pool *pool; ++ ++ ENTER4("%p, %p", packet, packet->private.pool); ++ pool = packet->private.pool; ++ if (!pool) { ++ ERROR("invalid pool %p", packet); ++ EXIT4(return); ++ } ++ assert((int)pool->num_used_descr > 0); ++ atomic_dec_var(pool->num_used_descr); ++ if (packet->reserved[1]) { ++ TRACE3("%p, %p", packet, (void *)packet->reserved[1]); ++ kfree((void *)packet->reserved[1]); ++ packet->reserved[1] = 0; ++ } ++ if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_PACKETS) { ++ TRACE3("%p", pool); ++ atomic_dec_var(pool->num_allocated_descr); ++ kfree(packet); ++ } else { ++ TRACE4("%p, %p, %p", pool, packet, pool->free_descr); ++ spin_lock_bh(&pool->lock); ++ packet->reserved[0] = ++ (typeof(packet->reserved[0]))pool->free_descr; ++ pool->free_descr = packet; ++ spin_unlock_bh(&pool->lock); ++ } ++ EXIT4(return); ++} ++ ++wstdcall struct ndis_packet_stack *WIN_FUNC(NdisIMGetCurrentPacketStack,2) ++ (struct ndis_packet *packet, BOOLEAN *stacks_remain) ++{ ++ struct ndis_packet_stack *stack; ++ ++ if (!packet->reserved[1]) { ++ stack = kzalloc(2 * sizeof(*stack), irql_gfp()); ++ TRACE3("%p, %p", packet, stack); ++ packet->reserved[1] = (typeof(packet->reserved[1]))stack; ++ } else { ++ stack = (void *)packet->reserved[1];; ++ if (xchg(&stack->ndis_reserved[0], 1)) { ++ stack++; ++ if (xchg(&stack->ndis_reserved[0], 1)) ++ stack = NULL; ++ } ++ TRACE3("%p", stack); ++ } ++ if (stack) ++ *stacks_remain = TRUE; ++ else ++ *stacks_remain = FALSE; ++ ++ EXIT3(return stack); ++} ++ ++wstdcall void WIN_FUNC(NdisCopyFromPacketToPacketSafe,7) ++ (struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy, ++ struct ndis_packet *src, UINT src_offset, UINT *num_copied, ++ enum mm_page_priority priority) ++{ ++ UINT dst_n, src_n, n, left; ++ ndis_buffer *dst_buf; ++ ndis_buffer *src_buf; ++ ++ ENTER4(""); ++ if (!dst || !src) { ++ *num_copied = 0; ++ EXIT4(return); ++ } ++ ++ dst_buf = dst->private.buffer_head; ++ src_buf = src->private.buffer_head; ++ ++ if (!dst_buf || !src_buf) { ++ *num_copied = 0; ++ EXIT4(return); ++ } ++ dst_n = MmGetMdlByteCount(dst_buf) - dst_offset; ++ src_n = MmGetMdlByteCount(src_buf) - src_offset; ++ ++ n = min(src_n, dst_n); ++ n = min(n, num_to_copy); ++ memcpy(MmGetSystemAddressForMdl(dst_buf) + dst_offset, ++ MmGetSystemAddressForMdl(src_buf) + src_offset, n); ++ ++ left = num_to_copy - n; ++ while (left > 0) { ++ src_offset += n; ++ dst_offset += n; ++ dst_n -= n; ++ src_n -= n; ++ if (dst_n == 0) { ++ dst_buf = dst_buf->next; ++ if (!dst_buf) ++ break; ++ dst_n = MmGetMdlByteCount(dst_buf); ++ dst_offset = 0; ++ } ++ if (src_n == 0) { ++ src_buf = src_buf->next; ++ if (!src_buf) ++ break; ++ src_n = MmGetMdlByteCount(src_buf); ++ src_offset = 0; ++ } ++ ++ n = min(src_n, dst_n); ++ n = min(n, left); ++ memcpy(MmGetSystemAddressForMdl(dst_buf) + dst_offset, ++ MmGetSystemAddressForMdl(src_buf) + src_offset, n); ++ left -= n; ++ } ++ *num_copied = num_to_copy - left; ++ EXIT4(return); ++} ++ ++wstdcall void WIN_FUNC(NdisCopyFromPacketToPacket,6) ++ (struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy, ++ struct ndis_packet *src, UINT src_offset, UINT *num_copied) ++{ ++ NdisCopyFromPacketToPacketSafe(dst, dst_offset, num_to_copy, ++ src, src_offset, num_copied, ++ NormalPagePriority); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisIMCopySendPerPacketInfo,2) ++ (struct ndis_packet *dst, struct ndis_packet *src) ++{ ++ struct ndis_packet_oob_data *dst_oob, *src_oob; ++ dst_oob = NDIS_PACKET_OOB_DATA(dst); ++ src_oob = NDIS_PACKET_OOB_DATA(src); ++ memcpy(&dst_oob->ext, &src_oob->ext, sizeof(dst_oob->ext)); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisSend,3) ++ (NDIS_STATUS *status, struct ndis_mp_block *nmb, ++ struct ndis_packet *packet) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ struct miniport *mp; ++ KIRQL irql; ++ ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ if (mp->send_packets) { ++ irql = serialize_lock_irql(wnd); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, &packet, 1); ++ serialize_unlock_irql(wnd, irql); ++ if (deserialized_driver(wnd)) ++ *status = NDIS_STATUS_PENDING; ++ else { ++ struct ndis_packet_oob_data *oob_data; ++ oob_data = NDIS_PACKET_OOB_DATA(packet); ++ *status = oob_data->status; ++ switch (*status) { ++ case NDIS_STATUS_SUCCESS: ++ free_tx_packet(wnd, packet, *status); ++ break; ++ case NDIS_STATUS_PENDING: ++ break; ++ case NDIS_STATUS_RESOURCES: ++ wnd->tx_ok = 0; ++ break; ++ case NDIS_STATUS_FAILURE: ++ default: ++ free_tx_packet(wnd, packet, *status); ++ break; ++ } ++ } ++ } else { ++ irql = serialize_lock_irql(wnd); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ *status = LIN2WIN3(mp->send, wnd->nmb->mp_ctx, packet, 0); ++ serialize_unlock_irql(wnd, irql); ++ switch (*status) { ++ case NDIS_STATUS_SUCCESS: ++ free_tx_packet(wnd, packet, *status); ++ break; ++ case NDIS_STATUS_PENDING: ++ break; ++ case NDIS_STATUS_RESOURCES: ++ wnd->tx_ok = 0; ++ break; ++ case NDIS_STATUS_FAILURE: ++ default: ++ free_tx_packet(wnd, packet, *status); ++ break; ++ } ++ } ++ EXIT3(return); ++} ++ ++/* called for serialized drivers only */ ++wstdcall void mp_timer_dpc(struct kdpc *kdpc, void *ctx, void *arg1, void *arg2) ++{ ++ struct ndis_mp_timer *timer; ++ struct ndis_mp_block *nmb; ++ ++ timer = ctx; ++ TIMERENTER("%p, %p, %p, %p", timer, timer->func, timer->ctx, timer->nmb); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ nmb = timer->nmb; ++ serialize_lock(nmb->wnd); ++ LIN2WIN4(timer->func, NULL, timer->ctx, NULL, NULL); ++ serialize_unlock(nmb->wnd); ++ TIMEREXIT(return); ++} ++WIN_FUNC_DECL(mp_timer_dpc,4) ++ ++wstdcall void WIN_FUNC(NdisMInitializeTimer,4) ++ (struct ndis_mp_timer *timer, struct ndis_mp_block *nmb, ++ DPC func, void *ctx) ++{ ++ TIMERENTER("%p, %p, %p, %p", timer, func, ctx, nmb); ++ assert_irql(_irql_ == PASSIVE_LEVEL); ++ timer->func = func; ++ timer->ctx = ctx; ++ timer->nmb = nmb; ++ if (deserialized_driver(nmb->wnd)) ++ KeInitializeDpc(&timer->kdpc, func, ctx); ++ else ++ KeInitializeDpc(&timer->kdpc, WIN_FUNC_PTR(mp_timer_dpc,4), ++ timer); ++ wrap_init_timer(&timer->nt_timer, NotificationTimer, nmb); ++ TIMEREXIT(return); ++} ++ ++wstdcall void WIN_FUNC(NdisMSetPeriodicTimer,2) ++ (struct ndis_mp_timer *timer, UINT period_ms) ++{ ++ unsigned long expires = MSEC_TO_HZ(period_ms); ++ ++ TIMERENTER("%p, %u, %ld", timer, period_ms, expires); ++ assert_irql(_irql_ <= DISPATCH_LEVEL); ++ wrap_set_timer(&timer->nt_timer, expires, expires, &timer->kdpc); ++ TIMEREXIT(return); ++} ++ ++wstdcall void WIN_FUNC(NdisMCancelTimer,2) ++ (struct ndis_mp_timer *timer, BOOLEAN *canceled) ++{ ++ TIMERENTER("%p", timer); ++ assert_irql(_irql_ <= DISPATCH_LEVEL); ++ *canceled = KeCancelTimer(&timer->nt_timer); ++ TIMERTRACE("%d", *canceled); ++ return; ++} ++ ++wstdcall void WIN_FUNC(NdisInitializeTimer,3) ++ (struct ndis_timer *timer, void *func, void *ctx) ++{ ++ TIMERENTER("%p, %p, %p", timer, func, ctx); ++ assert_irql(_irql_ == PASSIVE_LEVEL); ++ KeInitializeDpc(&timer->kdpc, func, ctx); ++ wrap_init_timer(&timer->nt_timer, NotificationTimer, NULL); ++ TIMEREXIT(return); ++} ++ ++/* NdisMSetTimer is a macro that calls NdisSetTimer with ++ * ndis_mp_timer typecast to ndis_timer */ ++ ++wstdcall void WIN_FUNC(NdisSetTimer,2) ++ (struct ndis_timer *timer, UINT duetime_ms) ++{ ++ unsigned long expires = MSEC_TO_HZ(duetime_ms); ++ ++ TIMERENTER("%p, %p, %u, %ld", timer, timer->nt_timer.wrap_timer, ++ duetime_ms, expires); ++ assert_irql(_irql_ <= DISPATCH_LEVEL); ++ wrap_set_timer(&timer->nt_timer, expires, 0, &timer->kdpc); ++ TIMEREXIT(return); ++} ++ ++wstdcall void WIN_FUNC(NdisCancelTimer,2) ++ (struct ndis_timer *timer, BOOLEAN *canceled) ++{ ++ TIMERENTER("%p", timer); ++ assert_irql(_irql_ <= DISPATCH_LEVEL); ++ *canceled = KeCancelTimer(&timer->nt_timer); ++ TIMEREXIT(return); ++} ++ ++wstdcall void WIN_FUNC(NdisMRegisterAdapterShutdownHandler,3) ++ (struct ndis_mp_block *nmb, void *ctx, void *func) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ENTER1("%p", func); ++ wnd->wd->driver->ndis_driver->mp.shutdown = func; ++ wnd->shutdown_ctx = ctx; ++} ++ ++wstdcall void WIN_FUNC(NdisMDeregisterAdapterShutdownHandler,1) ++ (struct ndis_mp_block *nmb) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ wnd->wd->driver->ndis_driver->mp.shutdown = NULL; ++ wnd->shutdown_ctx = NULL; ++} ++ ++/* TODO: rt61 (serialized) driver doesn't want MiniportEnableInterrupt ++ * to be called in irq handler, but mrv800c (deserialized) driver ++ * wants. NDIS is confusing about when to call MiniportEnableInterrupt ++ * For now, handle these cases with two separate irq handlers based on ++ * observation of these two drivers. However, it is likely not ++ * correct. */ ++wstdcall void deserialized_irq_handler(struct kdpc *kdpc, void *ctx, ++ void *arg1, void *arg2) ++{ ++ struct ndis_device *wnd = ctx; ++ ndis_interrupt_handler irq_handler = arg1; ++ struct miniport *mp = arg2; ++ ++ TRACE6("%p", irq_handler); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ LIN2WIN1(irq_handler, wnd->nmb->mp_ctx); ++ if (mp->enable_interrupt) ++ LIN2WIN1(mp->enable_interrupt, wnd->nmb->mp_ctx); ++ EXIT6(return); ++} ++WIN_FUNC_DECL(deserialized_irq_handler,4) ++ ++wstdcall void serialized_irq_handler(struct kdpc *kdpc, void *ctx, ++ void *arg1, void *arg2) ++{ ++ struct ndis_device *wnd = ctx; ++ ndis_interrupt_handler irq_handler = arg1; ++ ++ TRACE6("%p, %p, %p", wnd, irq_handler, arg2); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ serialize_lock(wnd); ++ LIN2WIN1(irq_handler, arg2); ++ serialize_unlock(wnd); ++ EXIT6(return); ++} ++WIN_FUNC_DECL(serialized_irq_handler,4) ++ ++wstdcall BOOLEAN ndis_isr(struct kinterrupt *kinterrupt, void *ctx) ++{ ++ struct ndis_mp_interrupt *mp_interrupt = ctx; ++ struct ndis_device *wnd = mp_interrupt->nmb->wnd; ++ BOOLEAN recognized = TRUE, queue_handler = TRUE; ++ ++ TRACE6("%p", wnd); ++ /* kernel may call ISR when registering interrupt, in ++ * the same context if DEBUG_SHIRQ is enabled */ ++ assert_irql(_irql_ == DIRQL || _irql_ == PASSIVE_LEVEL); ++ if (mp_interrupt->shared) ++ LIN2WIN3(mp_interrupt->isr, &recognized, &queue_handler, ++ wnd->nmb->mp_ctx); ++ else { ++ struct miniport *mp; ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ LIN2WIN1(mp->disable_interrupt, wnd->nmb->mp_ctx); ++ /* it is not shared interrupt, so handler must be called */ ++ recognized = queue_handler = TRUE; ++ } ++ if (recognized) { ++ if (queue_handler) { ++ TRACE5("%p", &wnd->irq_kdpc); ++ queue_kdpc(&wnd->irq_kdpc); ++ } ++ EXIT6(return TRUE); ++ } ++ EXIT6(return FALSE); ++} ++WIN_FUNC_DECL(ndis_isr,2) ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterInterrupt,7) ++ (struct ndis_mp_interrupt *mp_interrupt, ++ struct ndis_mp_block *nmb, UINT vector, UINT level, ++ BOOLEAN req_isr, BOOLEAN shared, enum kinterrupt_mode mode) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ struct miniport *mp; ++ ++ ENTER1("%p, vector:%d, level:%d, req_isr:%d, shared:%d, mode:%d", ++ mp_interrupt, vector, level, req_isr, shared, mode); ++ ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ nt_spin_lock_init(&mp_interrupt->lock); ++ mp_interrupt->irq = vector; ++ mp_interrupt->isr = mp->isr; ++ mp_interrupt->mp_dpc = mp->handle_interrupt; ++ mp_interrupt->nmb = nmb; ++ mp_interrupt->req_isr = req_isr; ++ if (shared && !req_isr) ++ WARNING("shared but dynamic interrupt!"); ++ mp_interrupt->shared = shared; ++ wnd->mp_interrupt = mp_interrupt; ++ if (mp->enable_interrupt) ++ mp_interrupt->enable = TRUE; ++ else ++ mp_interrupt->enable = FALSE; ++ ++ if (deserialized_driver(wnd)) { ++ KeInitializeDpc(&wnd->irq_kdpc, ++ WIN_FUNC_PTR(deserialized_irq_handler,4), ++ nmb->wnd); ++ wnd->irq_kdpc.arg1 = mp->handle_interrupt; ++ wnd->irq_kdpc.arg2 = mp; ++ TRACE2("%p, %p, %p, %p", wnd->irq_kdpc.arg1, wnd->irq_kdpc.arg2, ++ nmb->wnd, nmb->mp_ctx); ++ } else { ++ KeInitializeDpc(&wnd->irq_kdpc, ++ WIN_FUNC_PTR(serialized_irq_handler,4), ++ nmb->wnd); ++ wnd->irq_kdpc.arg1 = mp->handle_interrupt; ++ wnd->irq_kdpc.arg2 = nmb->mp_ctx; ++ TRACE2("%p, %p, %p", wnd->irq_kdpc.arg1, wnd->irq_kdpc.arg2, ++ nmb->wnd); ++ } ++ ++ if (IoConnectInterrupt(&mp_interrupt->kinterrupt, ++ WIN_FUNC_PTR(ndis_isr,2), mp_interrupt, NULL, ++ vector, DIRQL, DIRQL, mode, shared, 0, FALSE) != ++ STATUS_SUCCESS) { ++ printk(KERN_WARNING "%s: request for IRQ %d failed\n", ++ DRIVER_NAME, vector); ++ return NDIS_STATUS_RESOURCES; ++ } ++ printk(KERN_INFO "%s: using IRQ %d\n", DRIVER_NAME, vector); ++ EXIT1(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(NdisMDeregisterInterrupt,1) ++ (struct ndis_mp_interrupt *mp_interrupt) ++{ ++ struct ndis_mp_block *nmb; ++ ++ ENTER1("%p", mp_interrupt); ++ nmb = xchg(&mp_interrupt->nmb, NULL); ++ TRACE1("%p", nmb); ++ if (!nmb) { ++ WARNING("interrupt already freed?"); ++ return; ++ } ++ nmb->wnd->mp_interrupt = NULL; ++ if (dequeue_kdpc(&nmb->wnd->irq_kdpc)) ++ TRACE2("interrupt kdpc was pending"); ++ flush_workqueue(wrapndis_wq); ++ IoDisconnectInterrupt(mp_interrupt->kinterrupt); ++ EXIT1(return); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(NdisMSynchronizeWithInterrupt,3) ++ (struct ndis_mp_interrupt *mp_interrupt, ++ PKSYNCHRONIZE_ROUTINE sync_func, void *ctx) ++{ ++ return KeSynchronizeExecution(mp_interrupt->kinterrupt, sync_func, ctx); ++} ++ ++/* called via function pointer; but 64-bit RNDIS driver calls directly */ ++wstdcall void WIN_FUNC(NdisMIndicateStatus,4) ++ (struct ndis_mp_block *nmb, NDIS_STATUS status, void *buf, UINT len) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ struct ndis_status_indication *si; ++ ++ ENTER2("status=0x%x len=%d", status, len); ++ switch (status) { ++ case NDIS_STATUS_MEDIA_CONNECT: ++ set_media_state(wnd, NdisMediaStateConnected); ++ break; ++ case NDIS_STATUS_MEDIA_DISCONNECT: ++ set_media_state(wnd, NdisMediaStateDisconnected); ++ break; ++ case NDIS_STATUS_MEDIA_SPECIFIC_INDICATION: ++ if (!buf) ++ break; ++ si = buf; ++ TRACE2("status_type=%d", si->status_type); ++ switch (si->status_type) { ++ case Ndis802_11StatusType_MediaStreamMode: ++ break; ++#ifdef CONFIG_WIRELESS_EXT ++ case Ndis802_11StatusType_Authentication: ++ buf = (char *)buf + sizeof(*si); ++ len -= sizeof(*si); ++ while (len > 0) { ++ int pairwise_error = 0, group_error = 0; ++ struct ndis_auth_req *auth_req = ++ (struct ndis_auth_req *)buf; ++ TRACE1(MACSTRSEP, MAC2STR(auth_req->bssid)); ++ if (auth_req->flags & 0x01) ++ TRACE2("reauth request"); ++ if (auth_req->flags & 0x02) ++ TRACE2("key update request"); ++ if (auth_req->flags & 0x06) { ++ pairwise_error = 1; ++ TRACE2("pairwise_error"); ++ } ++ if (auth_req->flags & 0x0E) { ++ group_error = 1; ++ TRACE2("group_error"); ++ } ++ if (pairwise_error || group_error) { ++ union iwreq_data wrqu; ++ struct iw_michaelmicfailure micfailure; ++ ++ memset(&micfailure, 0, sizeof(micfailure)); ++ if (pairwise_error) ++ micfailure.flags |= ++ IW_MICFAILURE_PAIRWISE; ++ if (group_error) ++ micfailure.flags |= ++ IW_MICFAILURE_GROUP; ++ memcpy(micfailure.src_addr.sa_data, ++ auth_req->bssid, ETH_ALEN); ++ memset(&wrqu, 0, sizeof(wrqu)); ++ wrqu.data.length = sizeof(micfailure); ++ wireless_send_event(wnd->net_dev, ++ IWEVMICHAELMICFAILURE, ++ &wrqu, (u8 *)&micfailure); ++ } ++ len -= auth_req->length; ++ buf = (char *)buf + auth_req->length; ++ } ++ break; ++ case Ndis802_11StatusType_PMKID_CandidateList: ++ { ++ u8 *end; ++ unsigned long i; ++ struct ndis_pmkid_candidate_list *cand; ++ ++ cand = buf + sizeof(struct ndis_status_indication); ++ if (len < sizeof(struct ndis_status_indication) + ++ sizeof(struct ndis_pmkid_candidate_list) || ++ cand->version != 1) { ++ WARNING("unrecognized PMKID ignored"); ++ EXIT1(return); ++ } ++ ++ end = (u8 *)buf + len; ++ TRACE2("PMKID ver %d num_cand %d", ++ cand->version, cand->num_candidates); ++ for (i = 0; i < cand->num_candidates; i++) { ++ struct iw_pmkid_cand pcand; ++ union iwreq_data wrqu; ++ struct ndis_pmkid_candidate *c = ++ &cand->candidates[i]; ++ if ((u8 *)(c + 1) > end) { ++ TRACE2("truncated PMKID"); ++ break; ++ } ++ TRACE2("%ld: " MACSTRSEP " 0x%x", ++ i, MAC2STR(c->bssid), c->flags); ++ memset(&pcand, 0, sizeof(pcand)); ++ if (c->flags & 0x01) ++ pcand.flags |= IW_PMKID_CAND_PREAUTH; ++ pcand.index = i; ++ memcpy(pcand.bssid.sa_data, c->bssid, ETH_ALEN); ++ ++ memset(&wrqu, 0, sizeof(wrqu)); ++ wrqu.data.length = sizeof(pcand); ++ wireless_send_event(wnd->net_dev, IWEVPMKIDCAND, ++ &wrqu, (u8 *)&pcand); ++ } ++ break; ++ } ++ case Ndis802_11StatusType_RadioState: ++ { ++ struct ndis_radio_status_indication *radio_status = buf; ++ if (radio_status->radio_state == ++ Ndis802_11RadioStatusOn) ++ INFO("radio is turned on"); ++ else if (radio_status->radio_state == ++ Ndis802_11RadioStatusHardwareOff) ++ INFO("radio is turned off by hardware"); ++ else if (radio_status->radio_state == ++ Ndis802_11RadioStatusSoftwareOff) ++ INFO("radio is turned off by software"); ++ break; ++ } ++#endif ++ default: ++ /* is this RSSI indication? */ ++ TRACE2("unknown indication: %x", si->status_type); ++ break; ++ } ++ break; ++ default: ++ TRACE2("unknown status: %08X", status); ++ break; ++ } ++ ++ EXIT2(return); ++} ++ ++/* called via function pointer; but 64-bit RNDIS driver calls directly */ ++wstdcall void WIN_FUNC(NdisMIndicateStatusComplete,1) ++ (struct ndis_mp_block *nmb) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ENTER2("%p", wnd); ++ if (wnd->tx_ok) ++ queue_work(wrapndis_wq, &wnd->tx_work); ++} ++ ++/* called via function pointer */ ++wstdcall void NdisMSendComplete(struct ndis_mp_block *nmb, ++ struct ndis_packet *packet, NDIS_STATUS status) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ENTER4("%p, %08X", packet, status); ++ assert_irql(_irql_ <= DISPATCH_LEVEL); ++ if (deserialized_driver(wnd)) ++ free_tx_packet(wnd, packet, status); ++ else { ++ struct ndis_packet_oob_data *oob_data; ++ NDIS_STATUS pkt_status; ++ TRACE3("%p, %08x", packet, status); ++ oob_data = NDIS_PACKET_OOB_DATA(packet); ++ switch ((pkt_status = xchg(&oob_data->status, status))) { ++ case NDIS_STATUS_NOT_RECOGNIZED: ++ free_tx_packet(wnd, packet, status); ++ break; ++ case NDIS_STATUS_PENDING: ++ case 0: ++ break; ++ default: ++ WARNING("%p: invalid status: %08X", packet, pkt_status); ++ break; ++ } ++ /* In case a serialized driver has earlier requested a ++ * pause by returning NDIS_STATUS_RESOURCES during ++ * MiniportSend(Packets), wakeup tx worker now. ++ */ ++ if (xchg(&wnd->tx_ok, 1) == 0) { ++ TRACE3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end); ++ queue_work(wrapndis_wq, &wnd->tx_work); ++ } ++ } ++ EXIT3(return); ++} ++ ++/* called via function pointer */ ++wstdcall void NdisMSendResourcesAvailable(struct ndis_mp_block *nmb) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ENTER3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end); ++ wnd->tx_ok = 1; ++ queue_work(wrapndis_wq, &wnd->tx_work); ++ EXIT3(return); ++} ++ ++wstdcall void return_packet(void *arg1, void *arg2) ++{ ++ struct ndis_device *wnd; ++ struct ndis_packet *packet; ++ struct miniport *mp; ++ KIRQL irql; ++ ++ wnd = arg1; ++ packet = arg2; ++ ENTER4("%p, %p", wnd, packet); ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ irql = serialize_lock_irql(wnd); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ LIN2WIN2(mp->return_packet, wnd->nmb->mp_ctx, packet); ++ serialize_unlock_irql(wnd, irql); ++ EXIT4(return); ++} ++WIN_FUNC_DECL(return_packet,2) ++ ++/* called via function pointer */ ++wstdcall void NdisMIndicateReceivePacket(struct ndis_mp_block *nmb, ++ struct ndis_packet **packets, ++ UINT nr_packets) ++{ ++ struct ndis_device *wnd; ++ ndis_buffer *buffer; ++ struct ndis_packet *packet; ++ struct sk_buff *skb; ++ ULONG i, length, total_length; ++ struct ndis_packet_oob_data *oob_data; ++ void *virt; ++ struct ndis_tcp_ip_checksum_packet_info csum; ++ ++ ENTER3("%p, %d", nmb, nr_packets); ++ assert_irql(_irql_ <= DISPATCH_LEVEL); ++ wnd = nmb->wnd; ++ for (i = 0; i < nr_packets; i++) { ++ packet = packets[i]; ++ if (!packet) { ++ WARNING("empty packet ignored"); ++ continue; ++ } ++ wnd->net_dev->last_rx = jiffies; ++ /* get total number of bytes in packet */ ++ NdisGetFirstBufferFromPacketSafe(packet, &buffer, &virt, ++ &length, &total_length, ++ NormalPagePriority); ++ TRACE3("%d, %d", length, total_length); ++ oob_data = NDIS_PACKET_OOB_DATA(packet); ++ TRACE3("0x%x, 0x%x, %llu", packet->private.flags, ++ packet->private.packet_flags, oob_data->time_rxed); ++ skb = dev_alloc_skb(total_length); ++ if (skb) { ++ while (buffer) { ++ memcpy_skb(skb, MmGetSystemAddressForMdl(buffer), ++ MmGetMdlByteCount(buffer)); ++ buffer = buffer->next; ++ } ++ skb->dev = wnd->net_dev; ++ skb->protocol = eth_type_trans(skb, wnd->net_dev); ++ pre_atomic_add(wnd->net_stats.rx_bytes, total_length); ++ atomic_inc_var(wnd->net_stats.rx_packets); ++ csum.value = (typeof(csum.value))(ULONG_PTR) ++ oob_data->ext.info[TcpIpChecksumPacketInfo]; ++ TRACE3("0x%05x", csum.value); ++ if (wnd->rx_csum.value && ++ (csum.rx.tcp_succeeded || csum.rx.udp_succeeded || ++ csum.rx.ip_succeeded)) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ else ++ skb->ip_summed = CHECKSUM_NONE; ++ ++ if (in_interrupt()) ++ netif_rx(skb); ++ else ++ netif_rx_ni(skb); ++ } else { ++ WARNING("couldn't allocate skb; packet dropped"); ++ atomic_inc_var(wnd->net_stats.rx_dropped); ++ } ++ ++ /* serialized drivers check the status upon return ++ * from this function */ ++ if (!deserialized_driver(wnd)) { ++ oob_data->status = NDIS_STATUS_SUCCESS; ++ continue; ++ } ++ ++ /* if a deserialized driver sets ++ * NDIS_STATUS_RESOURCES, then it reclaims the packet ++ * upon return from this function */ ++ if (oob_data->status == NDIS_STATUS_RESOURCES) ++ continue; ++ ++ assert(oob_data->status == NDIS_STATUS_SUCCESS); ++ /* deserialized driver doesn't check the status upon ++ * return from this function; we need to call ++ * MiniportReturnPacket later for this packet. Calling ++ * MiniportReturnPacket from here is not correct - the ++ * driver doesn't expect it (at least Centrino driver ++ * crashes) */ ++ schedule_ntos_work_item(WIN_FUNC_PTR(return_packet,2), ++ wnd, packet); ++ } ++ EXIT3(return); ++} ++ ++/* called via function pointer (by NdisMEthIndicateReceive macro); the ++ * first argument is nmb->eth_db */ ++wstdcall void EthRxIndicateHandler(struct ndis_mp_block *nmb, void *rx_ctx, ++ char *header1, char *header, UINT header_size, ++ void *look_ahead, UINT look_ahead_size, ++ UINT packet_size) ++{ ++ struct sk_buff *skb = NULL; ++ struct ndis_device *wnd; ++ unsigned int skb_size = 0; ++ KIRQL irql; ++ struct ndis_packet_oob_data *oob_data; ++ ++ ENTER3("nmb = %p, rx_ctx = %p, buf = %p, size = %d, buf = %p, " ++ "size = %d, packet = %d", nmb, rx_ctx, header, header_size, ++ look_ahead, look_ahead_size, packet_size); ++ ++ wnd = nmb->wnd; ++ TRACE3("wnd = %p", wnd); ++ if (!wnd) { ++ ERROR("nmb is NULL"); ++ EXIT3(return); ++ } ++ wnd->net_dev->last_rx = jiffies; ++ ++ if (look_ahead_size < packet_size) { ++ struct ndis_packet *packet; ++ struct miniport *mp; ++ unsigned int bytes_txed; ++ NDIS_STATUS res; ++ ++ NdisAllocatePacket(&res, &packet, wnd->tx_packet_pool); ++ if (res != NDIS_STATUS_SUCCESS) { ++ atomic_inc_var(wnd->net_stats.rx_dropped); ++ EXIT3(return); ++ } ++ oob_data = NDIS_PACKET_OOB_DATA(packet); ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ irql = serialize_lock_irql(wnd); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ res = LIN2WIN6(mp->tx_data, packet, &bytes_txed, nmb, ++ rx_ctx, look_ahead_size, packet_size); ++ serialize_unlock_irql(wnd, irql); ++ TRACE3("%d, %d, %d", header_size, look_ahead_size, bytes_txed); ++ if (res == NDIS_STATUS_SUCCESS) { ++ ndis_buffer *buffer; ++ struct ndis_tcp_ip_checksum_packet_info csum; ++ skb = dev_alloc_skb(header_size + look_ahead_size + ++ bytes_txed); ++ if (!skb) { ++ ERROR("couldn't allocate skb; packet dropped"); ++ atomic_inc_var(wnd->net_stats.rx_dropped); ++ NdisFreePacket(packet); ++ return; ++ } ++ memcpy_skb(skb, header, header_size); ++ memcpy_skb(skb, look_ahead, look_ahead_size); ++ buffer = packet->private.buffer_head; ++ while (buffer) { ++ memcpy_skb(skb, ++ MmGetSystemAddressForMdl(buffer), ++ MmGetMdlByteCount(buffer)); ++ buffer = buffer->next; ++ } ++ skb_size = header_size + look_ahead_size + bytes_txed; ++ csum.value = (typeof(csum.value))(ULONG_PTR) ++ oob_data->ext.info[TcpIpChecksumPacketInfo]; ++ TRACE3("0x%05x", csum.value); ++ if (wnd->rx_csum.value && ++ (csum.rx.tcp_succeeded || csum.rx.udp_succeeded)) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ else ++ skb->ip_summed = CHECKSUM_NONE; ++ NdisFreePacket(packet); ++ } else if (res == NDIS_STATUS_PENDING) { ++ /* driver will call td_complete */ ++ oob_data->look_ahead = kmalloc(look_ahead_size, ++ GFP_ATOMIC); ++ if (!oob_data->look_ahead) { ++ NdisFreePacket(packet); ++ ERROR("packet dropped"); ++ atomic_inc_var(wnd->net_stats.rx_dropped); ++ EXIT3(return); ++ } ++ assert(sizeof(oob_data->header) == header_size); ++ memcpy(oob_data->header, header, ++ sizeof(oob_data->header)); ++ memcpy(oob_data->look_ahead, look_ahead, ++ look_ahead_size); ++ oob_data->look_ahead_size = look_ahead_size; ++ EXIT3(return); ++ } else { ++ WARNING("packet dropped: %08X", res); ++ atomic_inc_var(wnd->net_stats.rx_dropped); ++ NdisFreePacket(packet); ++ EXIT3(return); ++ } ++ } else { ++ skb_size = header_size + packet_size; ++ skb = dev_alloc_skb(skb_size); ++ if (skb) { ++ memcpy_skb(skb, header, header_size); ++ memcpy_skb(skb, look_ahead, packet_size); ++ } ++ } ++ ++ if (skb) { ++ skb->dev = wnd->net_dev; ++ skb->protocol = eth_type_trans(skb, wnd->net_dev); ++ pre_atomic_add(wnd->net_stats.rx_bytes, skb_size); ++ atomic_inc_var(wnd->net_stats.rx_packets); ++ if (in_interrupt()) ++ netif_rx(skb); ++ else ++ netif_rx_ni(skb); ++ } ++ ++ EXIT3(return); ++} ++ ++/* called via function pointer */ ++wstdcall void NdisMTransferDataComplete(struct ndis_mp_block *nmb, ++ struct ndis_packet *packet, ++ NDIS_STATUS status, UINT bytes_txed) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ struct sk_buff *skb; ++ unsigned int skb_size; ++ struct ndis_packet_oob_data *oob_data; ++ ndis_buffer *buffer; ++ struct ndis_tcp_ip_checksum_packet_info csum; ++ ++ ENTER3("wnd = %p, packet = %p, bytes_txed = %d", ++ wnd, packet, bytes_txed); ++ if (!packet) { ++ WARNING("illegal packet"); ++ EXIT3(return); ++ } ++ wnd->net_dev->last_rx = jiffies; ++ oob_data = NDIS_PACKET_OOB_DATA(packet); ++ skb_size = sizeof(oob_data->header) + oob_data->look_ahead_size + ++ bytes_txed; ++ skb = dev_alloc_skb(skb_size); ++ if (!skb) { ++ kfree(oob_data->look_ahead); ++ NdisFreePacket(packet); ++ ERROR("couldn't allocate skb; packet dropped"); ++ atomic_inc_var(wnd->net_stats.rx_dropped); ++ EXIT3(return); ++ } ++ memcpy_skb(skb, oob_data->header, sizeof(oob_data->header)); ++ memcpy_skb(skb, oob_data->look_ahead, oob_data->look_ahead_size); ++ buffer = packet->private.buffer_head; ++ while (buffer) { ++ memcpy_skb(skb, MmGetSystemAddressForMdl(buffer), ++ MmGetMdlByteCount(buffer)); ++ buffer = buffer->next; ++ } ++ kfree(oob_data->look_ahead); ++ NdisFreePacket(packet); ++ skb->dev = wnd->net_dev; ++ skb->protocol = eth_type_trans(skb, wnd->net_dev); ++ pre_atomic_add(wnd->net_stats.rx_bytes, skb_size); ++ atomic_inc_var(wnd->net_stats.rx_packets); ++ ++ csum.value = (typeof(csum.value))(ULONG_PTR) ++ oob_data->ext.info[TcpIpChecksumPacketInfo]; ++ TRACE3("0x%05x", csum.value); ++ if (wnd->rx_csum.value && ++ (csum.rx.tcp_succeeded || csum.rx.udp_succeeded)) ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ else ++ skb->ip_summed = CHECKSUM_NONE; ++ ++ if (in_interrupt()) ++ netif_rx(skb); ++ else ++ netif_rx_ni(skb); ++} ++ ++/* called via function pointer */ ++wstdcall void EthRxComplete(struct ndis_mp_block *nmb) ++{ ++ TRACE3(""); ++} ++ ++/* called via function pointer */ ++wstdcall void NdisMQueryInformationComplete(struct ndis_mp_block *nmb, ++ NDIS_STATUS status) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ typeof(wnd->ndis_req_task) task; ++ ++ ENTER2("nmb: %p, wnd: %p, %08X", nmb, wnd, status); ++ wnd->ndis_req_status = status; ++ wnd->ndis_req_done = 1; ++ if ((task = xchg(&wnd->ndis_req_task, NULL))) ++ wake_up_process(task); ++ else ++ WARNING("invalid task"); ++ EXIT2(return); ++} ++ ++/* called via function pointer */ ++wstdcall void NdisMSetInformationComplete(struct ndis_mp_block *nmb, ++ NDIS_STATUS status) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ typeof(wnd->ndis_req_task) task; ++ ++ ENTER2("status = %08X", status); ++ wnd->ndis_req_status = status; ++ wnd->ndis_req_done = 1; ++ if ((task = xchg(&wnd->ndis_req_task, NULL))) ++ wake_up_process(task); ++ else ++ WARNING("invalid task"); ++ EXIT2(return); ++} ++ ++/* called via function pointer */ ++wstdcall void NdisMResetComplete(struct ndis_mp_block *nmb, ++ NDIS_STATUS status, BOOLEAN address_reset) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ typeof(wnd->ndis_req_task) task; ++ ++ ENTER2("status: %08X, %u", status, address_reset); ++ wnd->ndis_req_status = status; ++ wnd->ndis_req_done = address_reset + 1; ++ if ((task = xchg(&wnd->ndis_req_task, NULL))) ++ wake_up_process(task); ++ else ++ WARNING("invalid task"); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(NdisMSleep,1) ++ (ULONG us) ++{ ++ unsigned long delay; ++ ++ ENTER4("%p: us: %u", current, us); ++ delay = USEC_TO_HZ(us); ++ sleep_hz(delay); ++ TRACE4("%p: done", current); ++} ++ ++wstdcall void WIN_FUNC(NdisGetCurrentSystemTime,1) ++ (LARGE_INTEGER *time) ++{ ++ *time = ticks_1601(); ++ TRACE5("%llu, %lu", *time, jiffies); ++} ++ ++wstdcall LONG WIN_FUNC(NdisInterlockedDecrement,1) ++ (LONG *val) ++{ ++ return InterlockedDecrement(val); ++} ++ ++wstdcall LONG WIN_FUNC(NdisInterlockedIncrement,1) ++ (LONG *val) ++{ ++ return InterlockedIncrement(val); ++} ++ ++wstdcall struct nt_list *WIN_FUNC(NdisInterlockedInsertHeadList,3) ++ (struct nt_list *head, struct nt_list *entry, ++ struct ndis_spinlock *lock) ++{ ++ return ExInterlockedInsertHeadList(head, entry, &lock->klock); ++} ++ ++wstdcall struct nt_list *WIN_FUNC(NdisInterlockedInsertTailList,3) ++ (struct nt_list *head, struct nt_list *entry, ++ struct ndis_spinlock *lock) ++{ ++ return ExInterlockedInsertTailList(head, entry, &lock->klock); ++} ++ ++wstdcall struct nt_list *WIN_FUNC(NdisInterlockedRemoveHeadList,2) ++ (struct nt_list *head, struct ndis_spinlock *lock) ++{ ++ return ExInterlockedRemoveHeadList(head, &lock->klock); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMInitializeScatterGatherDma,3) ++ (struct ndis_mp_block *nmb, BOOLEAN dma64_supported, ULONG max_phy_map) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ ENTER2("dma64_supported=%d, maxtransfer=%u", dma64_supported, ++ max_phy_map); ++ if (!wrap_is_pci_bus(wnd->wd->dev_bus)) { ++ ERROR("used on a non-PCI device"); ++ return NDIS_STATUS_NOT_SUPPORTED; ++ } ++#ifdef CONFIG_X86_64 ++ if (!dma64_supported) { ++ TRACE1("64-bit DMA size is not supported"); ++ if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_BIT_MASK(32)) || ++ pci_set_consistent_dma_mask(wnd->wd->pci.pdev, ++ DMA_BIT_MASK(32))) ++ WARNING("setting dma mask failed"); ++ } ++#endif ++ if ((wnd->attributes & NDIS_ATTRIBUTE_BUS_MASTER) && ++ wrap_is_pci_bus(wnd->wd->dev_bus)) { ++ wnd->sg_dma_size = max_phy_map; ++ return NDIS_STATUS_SUCCESS; ++ } else ++ EXIT1(return NDIS_STATUS_NOT_SUPPORTED); ++} ++ ++wstdcall ULONG WIN_FUNC(NdisMGetDmaAlignment,1) ++ (struct ndis_mp_block *nmb) ++{ ++ ENTER3(""); ++ return dma_get_cache_alignment(); ++} ++ ++wstdcall CHAR WIN_FUNC(NdisSystemProcessorCount,0) ++ (void) ++{ ++ return num_online_cpus(); ++} ++ ++wstdcall void WIN_FUNC(NdisGetCurrentProcessorCounts,3) ++ (ULONG *idle, ULONG *kernel_user, ULONG *index) ++{ ++ int cpu = smp_processor_id(); ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0) ++ *idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE]; ++ *kernel_user = kcpustat_cpu(cpu).cpustat[CPUTIME_SYSTEM] + ++ kcpustat_cpu(cpu).cpustat[CPUTIME_USER]; ++#else ++ *idle = kstat_cpu(cpu).cpustat.idle; ++ *kernel_user = kstat_cpu(cpu).cpustat.system + ++ kstat_cpu(cpu).cpustat.user; ++#endif ++ *index = cpu; ++} ++ ++wstdcall void WIN_FUNC(NdisInitializeEvent,1) ++ (struct ndis_event *ndis_event) ++{ ++ EVENTENTER("%p", ndis_event); ++ KeInitializeEvent(&ndis_event->nt_event, NotificationEvent, 0); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(NdisWaitEvent,2) ++ (struct ndis_event *ndis_event, UINT ms) ++{ ++ LARGE_INTEGER ticks; ++ NTSTATUS res; ++ ++ EVENTENTER("%p %u", ndis_event, ms); ++ ticks = -((LARGE_INTEGER)ms * TICKSPERMSEC); ++ res = KeWaitForSingleObject(&ndis_event->nt_event, 0, 0, TRUE, ++ ms == 0 ? NULL : &ticks); ++ if (res == STATUS_SUCCESS) ++ EXIT3(return TRUE); ++ else ++ EXIT3(return FALSE); ++} ++ ++wstdcall void WIN_FUNC(NdisSetEvent,1) ++ (struct ndis_event *ndis_event) ++{ ++ EVENTENTER("%p", ndis_event); ++ KeSetEvent(&ndis_event->nt_event, 0, 0); ++} ++ ++wstdcall void WIN_FUNC(NdisResetEvent,1) ++ (struct ndis_event *ndis_event) ++{ ++ EVENTENTER("%p", ndis_event); ++ KeResetEvent(&ndis_event->nt_event); ++} ++ ++static void ndis_worker(struct work_struct *dummy) ++{ ++ struct nt_list *ent; ++ struct ndis_work_item *ndis_work_item; ++ ++ WORKENTER(""); ++ while (1) { ++ spin_lock_bh(&ndis_work_list_lock); ++ ent = RemoveHeadList(&ndis_work_list); ++ spin_unlock_bh(&ndis_work_list_lock); ++ if (!ent) ++ break; ++ ndis_work_item = container_of(ent, struct ndis_work_item, list); ++ WORKTRACE("%p: %p, %p", ndis_work_item, ++ ndis_work_item->func, ndis_work_item->ctx); ++ LIN2WIN2(ndis_work_item->func, ndis_work_item, ++ ndis_work_item->ctx); ++ WORKTRACE("%p done", ndis_work_item); ++ } ++ WORKEXIT(return); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisScheduleWorkItem,1) ++ (struct ndis_work_item *ndis_work_item) ++{ ++ ENTER3("%p", ndis_work_item); ++ spin_lock_bh(&ndis_work_list_lock); ++ InsertTailList(&ndis_work_list, &ndis_work_item->list); ++ spin_unlock_bh(&ndis_work_list_lock); ++ WORKTRACE("scheduling %p", ndis_work_item); ++ queue_work(ndis_wq, &ndis_work); ++ EXIT3(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(NdisMGetDeviceProperty,6) ++ (struct ndis_mp_block *nmb, void **phy_dev, void **func_dev, ++ void **next_dev, void **alloc_res, void**trans_res) ++{ ++ ENTER2("nmb: %p, phy_dev = %p, func_dev = %p, next_dev = %p, " ++ "alloc_res = %p, trans_res = %p", nmb, phy_dev, func_dev, ++ next_dev, alloc_res, trans_res); ++ if (phy_dev) ++ *phy_dev = nmb->pdo; ++ if (func_dev) ++ *func_dev = nmb->fdo; ++ if (next_dev) ++ *next_dev = nmb->next_device; ++} ++ ++wstdcall void WIN_FUNC(NdisMRegisterUnloadHandler,2) ++ (struct driver_object *drv_obj, void *unload) ++{ ++ if (drv_obj) ++ drv_obj->unload = unload; ++ return; ++} ++ ++wstdcall UINT WIN_FUNC(NdisGetVersion,0) ++ (void) ++{ ++ return 0x00050001; ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMQueryAdapterInstanceName,2) ++ (struct unicode_string *name, struct ndis_mp_block *nmb) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ struct ansi_string ansi; ++ ++ if (wrap_is_pci_bus(wnd->wd->dev_bus)) ++ RtlInitAnsiString(&ansi, "PCI Ethernet Adapter"); ++ else ++ RtlInitAnsiString(&ansi, "USB Ethernet Adapter"); ++ ++ if (RtlAnsiStringToUnicodeString(name, &ansi, TRUE)) ++ EXIT2(return NDIS_STATUS_RESOURCES); ++ else ++ EXIT2(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisWriteEventLogEntry,7) ++ (void *handle, NDIS_STATUS code, ULONG value, USHORT n, ++ void *strings, ULONG datasize, void *data) ++{ ++ TRACE1("0x%x, 0x%x, %u, %u", code, value, n, datasize); ++ return NDIS_STATUS_SUCCESS; ++} ++ ++wstdcall void *WIN_FUNC(NdisGetRoutineAddress,1) ++ (struct unicode_string *unicode_string) ++{ ++ struct ansi_string ansi_string; ++ void *address; ++ ++ if (RtlUnicodeStringToAnsiString(&ansi_string, unicode_string, TRUE) != ++ STATUS_SUCCESS) ++ EXIT1(return NULL); ++ INFO("%s", ansi_string.buf); ++ address = ndis_get_routine_address(ansi_string.buf); ++ RtlFreeAnsiString(&ansi_string); ++ return address; ++} ++ ++wstdcall ULONG WIN_FUNC(NdisReadPcmciaAttributeMemory,4) ++ (struct ndis_mp_block *nmb, ULONG offset, void *buffer, ++ ULONG length) ++{ ++ TODO(); ++ return 0; ++} ++ ++wstdcall ULONG WIN_FUNC(NdisWritePcmciaAttributeMemory,4) ++ (struct ndis_mp_block *nmb, ULONG offset, void *buffer, ++ ULONG length) ++{ ++ TODO(); ++ return 0; ++} ++ ++wstdcall void WIN_FUNC(NdisMCoIndicateReceivePacket,3) ++ (struct ndis_mp_block *nmb, struct ndis_packet **packets, ++ UINT nr_packets) ++{ ++ ENTER3("nmb = %p", nmb); ++ NdisMIndicateReceivePacket(nmb, packets, nr_packets); ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(NdisMCoSendComplete,3) ++ (NDIS_STATUS status, struct ndis_mp_block *nmb, ++ struct ndis_packet *packet) ++{ ++ ENTER3("%08x", status); ++ NdisMSendComplete(nmb, packet, status); ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(NdisMCoRequestComplete,3) ++ (NDIS_STATUS status, struct ndis_mp_block *nmb, ++ struct ndis_request *ndis_request) ++{ ++ struct ndis_device *wnd = nmb->wnd; ++ typeof(wnd->ndis_req_task) task; ++ ++ ENTER3("%08X", status); ++ wnd->ndis_req_status = status; ++ wnd->ndis_req_done = 1; ++ if ((task = xchg(&wnd->ndis_req_task, NULL))) ++ wake_up_process(task); ++ else ++ WARNING("invalid task"); ++ EXIT3(return); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisIMNotifiyPnPEvent,2) ++ (struct ndis_mp_block *nmb, struct net_pnp_event *event) ++{ ++ ENTER2("%p, %d", nmb, event->code); ++ /* NdisWrapper never calls protocol's pnp event notifier, so ++ * nothing to do here */ ++ EXIT2(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(NdisCompletePnPEvent,3) ++ (NDIS_STATUS status, void *handle, struct net_pnp_event *event) ++{ ++ ENTER2("%d, %p, %d", status, handle, event->code); ++ /* NdisWrapper never calls protocol's pnp event notifier, so ++ * nothing to do here */ ++ EXIT2(return); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMSetMiniportSecondary,2) ++ (struct ndis_mp_block *nmb2, struct ndis_mp_block *nmb1) ++{ ++ ENTER3("%p, %p", nmb1, nmb2); ++ TODO(); ++ EXIT3(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMPromoteMiniport,1) ++ (struct ndis_mp_block *nmb) ++{ ++ ENTER3("%p", nmb); ++ TODO(); ++ EXIT3(return NDIS_STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(NdisMCoActivateVcComplete,3) ++ (NDIS_STATUS status, void *handle, void *params) ++{ ++ TODO(); ++} ++ ++wstdcall void WIN_FUNC(NdisMCoDeactivateVcComplete,2) ++ (NDIS_STATUS status, void *handle) ++{ ++ TODO(); ++} ++ ++wstdcall void WIN_FUNC(NdisMRemoveMiniport,1) ++ (void *handle) ++{ ++ TODO(); ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMOpenLog,3) ++ (struct ndis_device *wnd, UINT size, void *handle) ++{ ++ if (size >= sizeof(int)) ++ *((int *)handle) = 42; ++ return NDIS_STATUS_SUCCESS; ++} ++ ++wstdcall NDIS_STATUS WIN_FUNC(NdisMWriteLogData,3) ++ (void *handle, char *buffer, UINT buffer_size) ++{ ++ TODO(); ++ return NDIS_STATUS_SUCCESS; ++} ++ ++wstdcall void WIN_FUNC(NdisMFlushLog,1) ++ (void *handle) ++{ ++ TODO(); ++} ++ ++wstdcall void WIN_FUNC(NdisMCloseLog,1) ++ (void *handle) ++{ ++ TODO(); ++} ++ ++static void *ndis_get_routine_address(char *name) ++{ ++ int i; ++ ENTER2("%p", name); ++ for (i = 0; i < ARRAY_SIZE(ndis_exports); i++) { ++ if (strcmp(name, ndis_exports[i].name) == 0) { ++ TRACE2("%p", ndis_exports[i].func); ++ return ndis_exports[i].func; ++ } ++ } ++ EXIT2(return NULL); ++} ++ ++/* ndis_init_device is called for each device */ ++int ndis_init_device(struct ndis_device *wnd) ++{ ++ struct ndis_mp_block *nmb = wnd->nmb; ++ ++ KeInitializeSpinLock(&nmb->lock); ++ wnd->mp_interrupt = NULL; ++ wnd->wrap_timer_slist.next = NULL; ++ if (wnd->wd->driver->ndis_driver) ++ wnd->wd->driver->ndis_driver->mp.shutdown = NULL; ++ ++ nmb->filterdbs.eth_db = nmb; ++ nmb->filterdbs.tr_db = nmb; ++ nmb->filterdbs.fddi_db = nmb; ++ nmb->filterdbs.arc_db = nmb; ++ ++ nmb->rx_packet = WIN_FUNC_PTR(NdisMIndicateReceivePacket,3); ++ nmb->send_complete = WIN_FUNC_PTR(NdisMSendComplete,3); ++ nmb->send_resource_avail = WIN_FUNC_PTR(NdisMSendResourcesAvailable,1); ++ nmb->status = WIN_FUNC_PTR(NdisMIndicateStatus,4); ++ nmb->status_complete = WIN_FUNC_PTR(NdisMIndicateStatusComplete,1); ++ nmb->queryinfo_complete = WIN_FUNC_PTR(NdisMQueryInformationComplete,2); ++ nmb->setinfo_complete = WIN_FUNC_PTR(NdisMSetInformationComplete,2); ++ nmb->reset_complete = WIN_FUNC_PTR(NdisMResetComplete,3); ++ nmb->eth_rx_indicate = WIN_FUNC_PTR(EthRxIndicateHandler,8); ++ nmb->eth_rx_complete = WIN_FUNC_PTR(EthRxComplete,1); ++ nmb->td_complete = WIN_FUNC_PTR(NdisMTransferDataComplete,4); ++ return 0; ++} ++ ++/* ndis_exit_device is called for each device */ ++void ndis_exit_device(struct ndis_device *wnd) ++{ ++ struct wrap_device_setting *setting; ++ ENTER2("%p", wnd); ++ mutex_lock(&loader_mutex); ++ nt_list_for_each_entry(setting, &wnd->wd->settings, list) { ++ struct ndis_configuration_parameter *param; ++ param = setting->encoded; ++ if (param) { ++ if (param->type == NdisParameterString) ++ RtlFreeUnicodeString(¶m->data.string); ++ ExFreePool(param); ++ setting->encoded = NULL; ++ } ++ } ++ mutex_unlock(&loader_mutex); ++} ++ ++/* ndis_init is called once when module is loaded */ ++int ndis_init(void) ++{ ++ InitializeListHead(&ndis_work_list); ++ spin_lock_init(&ndis_work_list_lock); ++ INIT_WORK(&ndis_work, ndis_worker); ++ ++ ndis_wq = create_singlethread_workqueue("ndis_wq"); ++ if (!ndis_wq) { ++ WARNING("couldn't create worker thread"); ++ EXIT1(return -ENOMEM); ++ } ++ ++ TRACE1("ndis_wq: %p", ndis_wq); ++ return 0; ++} ++ ++/* ndis_exit is called once when module is removed */ ++void ndis_exit(void) ++{ ++ ENTER1(""); ++ if (ndis_wq) ++ destroy_workqueue(ndis_wq); ++ EXIT1(return); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/ndis.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ndis.h +--- linux-3.12.2/3rdparty/ndiswrapper/ndis.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ndis.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,1309 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _NDIS_H_ ++#define _NDIS_H_ ++ ++#include "ntoskernel.h" ++ ++//#define ALLOW_POOL_OVERFLOW 1 ++ ++#define NDIS_DMA_24BITS 0 ++#define NDIS_DMA_32BITS 1 ++#define NDIS_DMA_64BITS 2 ++ ++#ifdef CONFIG_X86_64 ++#define MAXIMUM_PROCESSORS 64 ++#else ++#define MAXIMUM_PROCESSORS 32 ++#endif ++ ++typedef UINT NDIS_STATUS; ++typedef UCHAR NDIS_DMA_SIZE; ++typedef LONG ndis_rssi; ++typedef ULONG ndis_key_index; ++typedef ULONG ndis_tx_power_level; ++typedef ULONGULONG ndis_key_rsc; ++typedef UCHAR mac_address[ETH_ALEN]; ++typedef ULONG ndis_fragmentation_threshold; ++typedef ULONG ndis_rts_threshold; ++typedef ULONG ndis_antenna; ++typedef ULONG ndis_oid; ++ ++typedef uint64_t NDIS_PHY_ADDRESS; ++ ++struct ndis_sg_element { ++ PHYSICAL_ADDRESS address; ++ ULONG length; ++ ULONG_PTR reserved; ++}; ++ ++struct ndis_sg_list { ++ ULONG nent; ++ ULONG_PTR reserved; ++ struct ndis_sg_element elements[]; ++}; ++ ++/* when sending packets, ndiswrapper associates exactly one sg element ++ * in sg list */ ++struct wrap_tx_sg_list { ++ ULONG nent; ++ ULONG_PTR reserved; ++ struct ndis_sg_element elements[1]; ++}; ++ ++struct ndis_phy_addr_unit { ++ NDIS_PHY_ADDRESS phy_addr; ++ UINT length; ++}; ++ ++typedef struct mdl ndis_buffer; ++ ++struct ndis_buffer_pool { ++ ndis_buffer *free_descr; ++// NT_SPIN_LOCK lock; ++ spinlock_t lock; ++ UINT max_descr; ++ UINT num_allocated_descr; ++}; ++ ++#define NDIS_PROTOCOL_ID_DEFAULT 0x00 ++#define NDIS_PROTOCOL_ID_TCP_IP 0x02 ++#define NDIS_PROTOCOL_ID_IPX 0x06 ++#define NDIS_PROTOCOL_ID_NBF 0x07 ++#define NDIS_PROTOCOL_ID_MAX 0x0F ++#define NDIS_PROTOCOL_ID_MASK 0x0F ++ ++#define fPACKET_WRAPPER_RESERVED 0x3F ++#define fPACKET_CONTAINS_MEDIA_SPECIFIC_INFO 0x40 ++#define fPACKET_ALLOCATED_BY_NDIS 0x80 ++ ++#define PROTOCOL_RESERVED_SIZE_IN_PACKET (4 * sizeof(void *)) ++ ++struct transport_header_offset { ++ USHORT protocol_type; ++ USHORT header_offset; ++}; ++ ++struct ndis_network_address { ++ USHORT length; ++ USHORT type; ++ UCHAR address[1]; ++}; ++ ++struct ndis_network_address_list { ++ LONG count; ++ USHORT type; ++ struct ndis_network_address address[1]; ++}; ++ ++struct ndis_tcp_ip_checksum_packet_info { ++ union { ++ struct { ++ ULONG v4:1; ++ ULONG v6:1; ++ ULONG tcp:1; ++ ULONG udp:1; ++ ULONG ip:1; ++ } tx; ++ struct { ++ ULONG tcp_failed:1; ++ ULONG udp_failed:1; ++ ULONG ip_failed:1; ++ ULONG tcp_succeeded:1; ++ ULONG udp_succeeded:1; ++ ULONG ip_succeeded:1; ++ ULONG loopback:1; ++ } rx; ++ ULONG value; ++ }; ++}; ++ ++enum ndis_task { ++ TcpIpChecksumNdisTask, IpSecNdisTask, TcpLargeSendNdisTask, MaxNdisTask ++}; ++ ++enum ndis_encapsulation { ++ UNSPECIFIED_Encapsulation, NULL_Encapsulation, ++ IEEE_802_3_Encapsulation, IEEE_802_5_Encapsulation, ++ LLC_SNAP_ROUTED_Encapsulation, LLC_SNAP_BRIDGED_Encapsulation ++}; ++ ++#define NDIS_TASK_OFFLOAD_VERSION 1 ++ ++struct ndis_encapsulation_format { ++ enum ndis_encapsulation encap; ++ struct { ++ ULONG fixed_header_size:1; ++ ULONG reserved:31; ++ } flags; ++ ULONG header_size; ++}; ++ ++struct ndis_task_offload_header { ++ ULONG version; ++ ULONG size; ++ ULONG reserved; ++ ULONG offset_first_task; ++ struct ndis_encapsulation_format encap_format; ++}; ++ ++struct ndis_task_offload { ++ ULONG version; ++ ULONG size; ++ enum ndis_task task; ++ ULONG offset_next_task; ++ ULONG task_buf_length; ++ UCHAR task_buf[1]; ++}; ++ ++struct v4_checksum { ++ union { ++ struct { ++ ULONG ip_opts:1; ++ ULONG tcp_opts:1; ++ ULONG tcp_csum:1; ++ ULONG udp_csum:1; ++ ULONG ip_csum:1; ++ }; ++ ULONG value; ++ }; ++}; ++ ++struct v6_checksum { ++ ULONG ip_supported:1; ++ ULONG tcp_supported:1; ++ ULONG tcp_csum:1; ++ ULONG udp_csum:1; ++}; ++ ++struct ndis_task_tcp_ip_checksum { ++ struct v4_checksum v4_tx; ++ struct v4_checksum v4_rx; ++ struct v6_checksum v6_tx; ++ struct v6_checksum v6_rx; ++}; ++ ++struct ndis_task_tcp_large_send { ++ ULONG version; ++ ULONG max_size; ++ ULONG min_seg_count; ++ BOOLEAN tcp_opts; ++ BOOLEAN ip_opts; ++}; ++ ++struct ndis_packet; ++ ++struct ndis_packet_pool { ++ struct ndis_packet *free_descr; ++// NT_SPIN_LOCK lock; ++ spinlock_t lock; ++ UINT max_descr; ++ UINT num_allocated_descr; ++ UINT num_used_descr; ++ UINT proto_rsvd_length; ++}; ++ ++struct ndis_packet_stack { ++ ULONG_PTR IM_reserved[2]; ++ ULONG_PTR ndis_reserved[4]; ++}; ++ ++enum ndis_per_packet_info { ++ TcpIpChecksumPacketInfo, IpSecPacketInfo, TcpLargeSendPacketInfo, ++ ClassificationHandlePacketInfo, NdisReserved, ++ ScatterGatherListPacketInfo, Ieee8021QInfo, OriginalPacketInfo, ++ PacketCancelId, MaxPerPacketInfo ++}; ++ ++struct ndis_packet_extension { ++ void *info[MaxPerPacketInfo]; ++}; ++ ++struct ndis_packet_private { ++ UINT nr_pages; ++ UINT len; ++ ndis_buffer *buffer_head; ++ ndis_buffer *buffer_tail; ++ struct ndis_packet_pool *pool; ++ UINT count; ++ ULONG flags; ++ BOOLEAN valid_counts; ++ UCHAR packet_flags; ++ USHORT oob_offset; ++}; ++ ++struct ndis_packet { ++ struct ndis_packet_private private; ++ /* for use by miniport */ ++ union { ++ /* for connectionless mininports */ ++ struct { ++ UCHAR miniport_reserved[2 * sizeof(void *)]; ++ UCHAR wrapper_reserved[2 * sizeof(void *)]; ++ } cl_reserved; ++ /* for deserialized miniports */ ++ struct { ++ UCHAR miniport_reserved_ex[3 * sizeof(void *)]; ++ UCHAR wrapper_reserved_ex[sizeof(void *)]; ++ } deserialized_reserved; ++ struct { ++ UCHAR mac_reserved[4 * sizeof(void *)]; ++ } mac_reserved; ++ }; ++ ULONG_PTR reserved[2]; ++ UCHAR protocol_reserved[1]; ++}; ++ ++/* OOB data */ ++struct ndis_packet_oob_data { ++ union { ++ ULONGLONG time_to_tx; ++ ULONGLONG time_txed; ++ }; ++ ULONGLONG time_rxed; ++ UINT header_size; ++ UINT media_size; ++ void *media; ++ NDIS_STATUS status; ++ ++ /* ndiswrapper specific info; extension should be right after ++ * ndis's oob_data */ ++ struct ndis_packet_extension ext; ++ union { ++ /* used for tx only */ ++ struct { ++ struct sk_buff *tx_skb; ++ union { ++ struct wrap_tx_sg_list wrap_tx_sg_list; ++ struct ndis_sg_list *tx_sg_list; ++ }; ++ }; ++ /* used for rx only */ ++ struct { ++ unsigned char header[ETH_HLEN]; ++ unsigned char *look_ahead; ++ UINT look_ahead_size; ++ }; ++ }; ++}; ++ ++#define NDIS_PACKET_OOB_DATA(packet) \ ++ (struct ndis_packet_oob_data *)(((void *)(packet)) + \ ++ (packet)->private.oob_offset) ++ ++enum ndis_device_pnp_event { ++ NdisDevicePnPEventQueryRemoved, NdisDevicePnPEventRemoved, ++ NdisDevicePnPEventSurpriseRemoved, NdisDevicePnPEventQueryStopped, ++ NdisDevicePnPEventStopped, NdisDevicePnPEventPowerProfileChanged, ++ NdisDevicePnPEventMaximum ++}; ++ ++enum ndis_request_type { ++ NdisRequestQueryInformation, NdisRequestSetInformation, ++ NdisRequestQueryStatistics, NdisRequestOpen, NdisRequestClose, ++ NdisRequestSend, NdisRequestTransferData, NdisRequestReset, ++ NdisRequestGeneric1, NdisRequestGeneric2, NdisRequestGeneric3, ++ NdisRequestGeneric4 ++}; ++ ++struct ndis_request { ++ mac_address mac; ++ enum ndis_request_type request_type; ++ union data { ++ struct query_info { ++ UINT oid; ++ void *buf; ++ UINT buf_len; ++ UINT written; ++ UINT needed; ++ } query_info; ++ struct set_info { ++ UINT oid; ++ void *buf; ++ UINT buf_len; ++ UINT written; ++ UINT needed; ++ } set_info; ++ } data; ++}; ++ ++enum ndis_medium { ++ NdisMedium802_3, NdisMedium802_5, NdisMediumFddi, NdisMediumWan, ++ NdisMediumLocalTalk, NdisMediumDix, NdisMediumArcnetRaw, ++ NdisMediumArcnet878_2, NdisMediumAtm, NdisMediumWirelessWan, ++ NdisMediumIrda, NdisMediumBpc, NdisMediumCoWan, ++ NdisMedium1394, NdisMediumMax ++}; ++ ++enum ndis_physical_medium { ++ NdisPhysicalMediumUnspecified, NdisPhysicalMediumWirelessLan, ++ NdisPhysicalMediumCableModem, NdisPhysicalMediumPhoneLine, ++ NdisPhysicalMediumPowerLine, NdisPhysicalMediumDSL, ++ NdisPhysicalMediumFibreChannel, NdisPhysicalMedium1394, ++ NdisPhysicalMediumWirelessWan, NdisPhysicalMediumMax ++}; ++ ++enum ndis_power_state { ++ NdisDeviceStateUnspecified = 0, ++ NdisDeviceStateD0, NdisDeviceStateD1, NdisDeviceStateD2, ++ NdisDeviceStateD3, NdisDeviceStateMaximum ++}; ++ ++enum ndis_power_profile { ++ NdisPowerProfileBattery, NdisPowerProfileAcOnLine ++}; ++ ++struct ndis_pm_wakeup_capabilities { ++ enum ndis_power_state min_magic_packet_wakeup; ++ enum ndis_power_state min_pattern_wakeup; ++ enum ndis_power_state min_link_change_wakeup; ++}; ++ ++#define NDIS_PNP_WAKE_UP_MAGIC_PACKET 0x00000001 ++#define NDIS_PNP_WAKE_UP_PATTERN_MATCH 0x00000002 ++#define NDIS_PNP_WAKE_UP_LINK_CHANGE 0x00000004 ++ ++enum net_pnp_event_code { ++ NetEventSetPower, NetEventQueryPower, NetEventQueryRemoveDevice, ++ NetEventCancelRemoveDevice, NetEventReconfigure, NetEventBindList, ++ NetEventBindsComplete, NetEventPnPCapabilities, NetEventMaximum ++}; ++ ++struct net_pnp_event { ++ enum net_pnp_event_code code; ++ void *buf; ++ ULONG buf_length; ++ ULONG_PTR ndis_reserved[4]; ++ ULONG_PTR transport_reserved[4]; ++ ULONG_PTR tdi_reserved[4]; ++ ULONG_PTR tdi_client_reserved[4]; ++}; ++ ++struct ndis_pnp_capabilities { ++ ULONG flags; ++ struct ndis_pm_wakeup_capabilities wakeup; ++}; ++ ++typedef void (*ndis_isr_handler)(BOOLEAN *recognized, BOOLEAN *queue_handler, ++ void *handle) wstdcall; ++typedef void (*ndis_interrupt_handler)(void *ctx) wstdcall; ++ ++struct miniport { ++ /* NDIS 3.0 */ ++ UCHAR major_version; ++ UCHAR minor_version; ++ USHORT filler; ++ UINT reserved; ++ BOOLEAN (*hangcheck)(void *ctx) wstdcall; ++ void (*disable_interrupt)(void *ctx) wstdcall; ++ void (*enable_interrupt)(void *ctx) wstdcall; ++ void (*mp_halt)(void *ctx) wstdcall; ++ ndis_interrupt_handler handle_interrupt; ++ NDIS_STATUS (*init)(NDIS_STATUS *error_status, UINT *medium_index, ++ enum ndis_medium medium[], UINT medium_array_size, ++ void *handle, void *conf_handle) wstdcall; ++ ndis_isr_handler isr; ++ NDIS_STATUS (*queryinfo)(void *ctx, ndis_oid oid, void *buffer, ++ ULONG buflen, ULONG *written, ++ ULONG *needed) wstdcall; ++ void *reconfig; ++ NDIS_STATUS (*reset)(BOOLEAN *reset_address, void *ctx) wstdcall; ++ NDIS_STATUS (*send)(void *ctx, struct ndis_packet *packet, ++ UINT flags) wstdcall; ++ NDIS_STATUS (*setinfo)(void *ctx, ndis_oid oid, void *buffer, ++ ULONG buflen, ULONG *written, ++ ULONG *needed) wstdcall; ++ NDIS_STATUS (*tx_data)(struct ndis_packet *ndis_packet, ++ UINT *bytes_txed, void *mp_ctx, void *rx_ctx, ++ UINT offset, UINT bytes_to_tx) wstdcall; ++ /* NDIS 4.0 extensions */ ++ void (*return_packet)(void *ctx, void *packet) wstdcall; ++ void (*send_packets)(void *ctx, struct ndis_packet **packets, ++ INT nr_of_packets) wstdcall; ++ void (*alloc_complete)(void *handle, void *virt, ++ NDIS_PHY_ADDRESS *phys, ++ ULONG size, void *ctx) wstdcall; ++ /* NDIS 5.0 extensions */ ++ NDIS_STATUS (*co_create_vc)(void *ctx, void *vc_handle, ++ void *vc_ctx) wstdcall; ++ NDIS_STATUS (*co_delete_vc)(void *vc_ctx) wstdcall; ++ NDIS_STATUS (*co_activate_vc)(void *vc_ctx, void *call_params) wstdcall; ++ NDIS_STATUS (*co_deactivate_vc)(void *vc_ctx) wstdcall; ++ NDIS_STATUS (*co_send_packets)(void *vc_ctx, void **packets, ++ UINT nr_of_packets) wstdcall; ++ NDIS_STATUS (*co_request)(void *ctx, void *vc_ctx, UINT *req) wstdcall; ++ /* NDIS 5.1 extensions */ ++ void (*cancel_send_packets)(void *ctx, void *id) wstdcall; ++ void (*pnp_event_notify)(void *ctx, enum ndis_device_pnp_event event, ++ void *inf_buf, ULONG inf_buf_len) wstdcall; ++ void (*shutdown)(void *ctx) wstdcall; ++ void *reserved1; ++ void *reserved2; ++ void *reserved3; ++ void *reserved4; ++}; ++ ++struct ndis_spinlock { ++ NT_SPIN_LOCK klock; ++ KIRQL irql; ++}; ++ ++union ndis_rw_lock_refcount { ++ UCHAR cache_line[16]; ++}; ++ ++struct ndis_rw_lock { ++ union { ++ struct { ++ NT_SPIN_LOCK klock; ++ void *context; ++ }; ++ UCHAR reserved[16]; ++ }; ++ union { ++ union ndis_rw_lock_refcount ref_count[MAXIMUM_PROCESSORS]; ++ /* ndiswrapper specific */ ++ volatile int count; ++ }; ++}; ++ ++struct lock_state { ++ USHORT state; ++ KIRQL irql; ++}; ++ ++struct ndis_work_item; ++typedef void (*NDIS_PROC)(struct ndis_work_item *, void *) wstdcall; ++ ++struct ndis_work_item { ++ void *ctx; ++ NDIS_PROC func; ++ union { ++ UCHAR reserved[8 * sizeof(void *)]; ++ /* ndiswrapper specific */ ++ struct nt_list list; ++ }; ++}; ++ ++struct alloc_shared_mem { ++ void *ctx; ++ ULONG size; ++ BOOLEAN cached; ++}; ++ ++struct ndis_mp_block; ++ ++/* this is opaque to drivers, so we can use it as we please */ ++struct ndis_mp_interrupt { ++ struct kinterrupt *kinterrupt; ++ NT_SPIN_LOCK lock; ++ union { ++ void *reserved; ++ unsigned int irq; ++ }; ++ ndis_isr_handler isr; ++ ndis_interrupt_handler mp_dpc; ++ struct kdpc intr_dpc; ++ struct ndis_mp_block *nmb; ++ UCHAR dpc_count; ++ BOOLEAN enable; ++ struct nt_event dpc_completed_event; ++ BOOLEAN shared; ++ BOOLEAN req_isr; ++}; ++ ++struct ndis_binary_data { ++ USHORT len; ++ void *buf; ++}; ++ ++enum ndis_parameter_type { ++ NdisParameterInteger, NdisParameterHexInteger, ++ NdisParameterString, NdisParameterMultiString, NdisParameterBinary, ++}; ++ ++typedef struct unicode_string NDIS_STRING; ++ ++struct ndis_configuration_parameter { ++ enum ndis_parameter_type type; ++ union { ++ ULONG integer; ++ NDIS_STRING string; ++ } data; ++}; ++ ++struct ndis_driver { ++ struct miniport mp; ++}; ++ ++/* IDs used to store extensions in driver_object's custom extension */ ++#define NDIS_DRIVER_CLIENT_ID 10 ++ ++struct ndis_wireless_stats { ++ ULONG length; ++ LARGE_INTEGER tx_frag; ++ LARGE_INTEGER tx_multi_frag; ++ LARGE_INTEGER failed; ++ LARGE_INTEGER retry; ++ LARGE_INTEGER multi_retry; ++ LARGE_INTEGER rtss_succ; ++ LARGE_INTEGER rtss_fail; ++ LARGE_INTEGER ack_fail; ++ LARGE_INTEGER frame_dup; ++ LARGE_INTEGER rx_frag; ++ LARGE_INTEGER rx_multi_frag; ++ LARGE_INTEGER fcs_err; ++ LARGE_INTEGER tkip_local_mic_failures; ++ LARGE_INTEGER tkip_icv_errors; ++ LARGE_INTEGER tkip_counter_measures_invoked; ++ LARGE_INTEGER tkip_replays; ++ LARGE_INTEGER ccmp_format_errors; ++ LARGE_INTEGER ccmp_replays; ++ LARGE_INTEGER ccmp_decrypt_errors; ++ LARGE_INTEGER fourway_handshake_failures; ++ LARGE_INTEGER wep_undecryptable_count; ++ LARGE_INTEGER wep_icv_errorcount; ++ LARGE_INTEGER decrypt_success_count; ++ LARGE_INTEGER decrypt_failure_count; ++}; ++ ++enum ndis_status_type { ++ Ndis802_11StatusType_Authentication, ++ Ndis802_11StatusType_MediaStreamMode, ++ Ndis802_11StatusType_PMKID_CandidateList, ++ Ndis802_11StatusType_RadioState, ++}; ++ ++struct ndis_status_indication { ++ enum ndis_status_type status_type; ++}; ++ ++enum ndis_radio_status { ++ Ndis802_11RadioStatusOn, Ndis802_11RadioStatusHardwareOff, ++ Ndis802_11RadioStatusSoftwareOff, ++}; ++ ++struct ndis_radio_status_indication ++{ ++ enum ndis_status_type status_type; ++ enum ndis_radio_status radio_state; ++}; ++ ++enum ndis_media_state { ++ NdisMediaStateConnected, ++ NdisMediaStateDisconnected, ++}; ++ ++enum ndis_media_stream_mode { ++ Ndis802_11MediaStreamOff, Ndis802_11MediaStreamOn ++}; ++ ++enum wrapper_work { ++ LINK_STATUS_OFF, LINK_STATUS_ON, SET_MULTICAST_LIST, COLLECT_IW_STATS, ++ HANGCHECK, NETIF_WAKEQ, ++}; ++ ++struct encr_info { ++ struct encr_key { ++ ULONG length; ++ UCHAR key[NDIS_ENCODING_TOKEN_MAX]; ++ } keys[MAX_ENCR_KEYS]; ++ unsigned short tx_key_index; ++}; ++ ++struct ndis_essid { ++ ULONG length; ++ UCHAR essid[NDIS_ESSID_MAX_SIZE]; ++}; ++ ++enum ndis_infrastructure_mode { ++ Ndis802_11IBSS, Ndis802_11Infrastructure, Ndis802_11AutoUnknown, ++ Ndis802_11InfrastructureMax ++}; ++ ++enum authentication_mode { ++ Ndis802_11AuthModeOpen, Ndis802_11AuthModeShared, ++ Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA, ++ Ndis802_11AuthModeWPAPSK, Ndis802_11AuthModeWPANone, ++ Ndis802_11AuthModeWPA2, Ndis802_11AuthModeWPA2PSK, ++ Ndis802_11AuthModeMax ++}; ++ ++enum encryption_status { ++ Ndis802_11WEPEnabled, ++ Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, ++ Ndis802_11WEPDisabled, ++ Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, ++ Ndis802_11WEPKeyAbsent, ++ Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, ++ Ndis802_11WEPNotSupported, ++ Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, ++ Ndis802_11Encryption2Enabled, Ndis802_11Encryption2KeyAbsent, ++ Ndis802_11Encryption3Enabled, Ndis802_11Encryption3KeyAbsent ++}; ++ ++struct ndis_auth_encr_pair { ++ enum authentication_mode auth_mode; ++ enum encryption_status encr_mode; ++}; ++ ++struct ndis_capability { ++ ULONG length; ++ ULONG version; ++ ULONG num_PMKIDs; ++ ULONG num_auth_encr_pair; ++ struct ndis_auth_encr_pair auth_encr_pair[1]; ++}; ++ ++struct ndis_guid { ++ struct guid guid; ++ union { ++ ndis_oid oid; ++ NDIS_STATUS status; ++ }; ++ ULONG size; ++ ULONG flags; ++}; ++ ++struct ndis_timer { ++ struct nt_timer nt_timer; ++ struct kdpc kdpc; ++}; ++ ++struct ndis_mp_timer { ++ struct nt_timer nt_timer; ++ struct kdpc kdpc; ++ DPC func; ++ void *ctx; ++ struct ndis_mp_block *nmb; ++ struct ndis_mp_timer *next; ++}; ++ ++typedef struct cm_partial_resource_list NDIS_RESOURCE_LIST; ++ ++struct ndis_event { ++ struct nt_event nt_event; ++}; ++ ++struct ndis_bind_paths { ++ UINT number; ++ struct unicode_string paths[1]; ++}; ++ ++struct ndis_reference { ++ NT_SPIN_LOCK lock; ++ USHORT ref_count; ++ BOOLEAN closing; ++}; ++ ++struct ndis_filterdbs { ++ union { ++ void *eth_db; ++ void *null_db; ++ }; ++ void *tr_db; ++ void *fddi_db; ++ void *arc_db; ++}; ++ ++enum ndis_interface_type { ++ NdisInterfaceInternal, NdisInterfaceIsa, NdisInterfaceEisa, ++ NdisInterfaceMca, NdisInterfaceTurboChannel, NdisInterfacePci, ++ NdisInterfacePcMcia, ++}; ++ ++struct auth_encr_capa { ++ unsigned long auth; ++ unsigned long encr; ++}; ++ ++struct ndis_pmkid_candidate { ++ mac_address bssid; ++ DWORD flags; ++}; ++ ++struct ndis_pmkid_candidate_list { ++ ULONG version; ++ ULONG num_candidates; ++ struct ndis_pmkid_candidate candidates[1]; ++}; ++ ++/* ++ * This struct contains function pointers that the drivers references ++ * directly via macros, so it's important that they are at the correct ++ * position. ++ */ ++struct ndis_mp_block { ++ void *signature; ++ struct ndis_mp_block *next; ++ struct driver_object *drv_obj; ++ void *mp_ctx; ++ struct unicode_string name; ++ struct ndis_bind_paths *bindpaths; ++ void *openqueue; ++ struct ndis_reference reference; ++ void *device_ctx; ++ UCHAR padding; ++ UCHAR lock_acquired; ++ UCHAR pmode_opens; ++ UCHAR assigned_cpu; ++ NT_SPIN_LOCK lock; ++ enum ndis_request_type *mediarequest; ++ struct ndis_mp_interrupt *interrupt; ++ ULONG flags; ++ ULONG pnp_flags; ++ struct nt_list packet_list; ++ struct ndis_packet *first_pending_tx_packet; ++ struct ndis_packet *return_packet_queue; ++ ULONG request_buffer; ++ void *set_mcast_buffer; ++ struct ndis_mp_block *primary_mp; ++ void *wrapper_ctx; ++ void *bus_data_ctx; ++ ULONG pnp_capa; ++ void *resources; ++ struct ndis_timer wakeup_dpc_timer; ++ struct unicode_string basename; ++ struct unicode_string symlink_name; ++ ULONG ndis_hangcheck_interval; ++ USHORT hangcheck_ticks; ++ USHORT hangcheck_tick; ++ NDIS_STATUS ndis_reset_status; ++ void *resetopen; ++ struct ndis_filterdbs filterdbs; ++ void *rx_packet; ++ void *send_complete; ++ void *send_resource_avail; ++ void *reset_complete; ++ ++ enum ndis_medium media_type; ++ ULONG bus_number; ++ enum ndis_interface_type bus_type; ++ enum ndis_interface_type adapter_type; ++ struct device_object *fdo; ++ struct device_object *pdo; ++ struct device_object *next_device; ++ void *mapreg; ++ void *call_mgraflist; ++ void *mp_thread; ++ void *setinfobuf; ++ USHORT setinfo_buf_len; ++ USHORT max_send_pkts; ++ NDIS_STATUS fake_status; ++ void *lock_handler; ++ struct unicode_string *adapter_instance_name; ++ void *timer_queue; ++ UINT mac_options; ++ void *pending_req; ++ UINT max_long_addrs; ++ UINT max_short_addrs; ++ UINT cur_lookahead; ++ UINT max_lookahead; ++ ++ ndis_interrupt_handler irq_bh; ++ void *disable_intr; ++ void *enable_intr; ++ void *send_pkts; ++ void *deferred_send; ++ void *eth_rx_indicate; ++ void *tr_rx_indicate; ++ void *fddi_rx_indicate; ++ void *eth_rx_complete; ++ void *tr_rx_complete; ++ void *fddi_rx_complete; ++ ++ void *status; ++ void *status_complete; ++ void *td_complete; ++ ++ void *queryinfo_complete; ++ void *setinfo_complete; ++ void *wan_tx_complete; ++ void *wan_rx; ++ void *wan_rx_complete; ++ /* ndiswrapper specific */ ++ struct ndis_device *wnd; ++}; ++ ++struct ndis_device { ++ struct ndis_mp_block *nmb; ++ struct wrap_device *wd; ++ struct net_device *net_dev; ++ void *shutdown_ctx; ++ struct ndis_mp_interrupt *mp_interrupt; ++ struct kdpc irq_kdpc; ++ unsigned long mem_start; ++ unsigned long mem_end; ++ ++ struct net_device_stats net_stats; ++ struct iw_statistics iw_stats; ++ BOOLEAN iw_stats_enabled; ++ struct ndis_wireless_stats ndis_stats; ++ ++ struct work_struct tx_work; ++ struct ndis_packet *tx_ring[TX_RING_SIZE]; ++ u8 tx_ring_start; ++ u8 tx_ring_end; ++ u8 is_tx_ring_full; ++ u8 tx_ok; ++ spinlock_t tx_ring_lock; ++ struct mutex tx_ring_mutex; ++ unsigned int max_tx_packets; ++ struct mutex ndis_req_mutex; ++ struct task_struct *ndis_req_task; ++ int ndis_req_done; ++ NDIS_STATUS ndis_req_status; ++ ULONG packet_filter; ++ ++ ULONG sg_dma_size; ++ ULONG dma_map_count; ++ dma_addr_t *dma_map_addr; ++ ++ int hangcheck_interval; ++ struct timer_list hangcheck_timer; ++ int iw_stats_interval; ++ struct timer_list iw_stats_timer; ++ unsigned long scan_timestamp; ++ struct encr_info encr_info; ++ char nick[IW_ESSID_MAX_SIZE + 1]; ++ struct ndis_essid essid; ++ struct auth_encr_capa capa; ++ enum ndis_infrastructure_mode infrastructure_mode; ++ int max_pmkids; ++ int num_pmkids; ++ struct ndis_pmkid *pmkids; ++ mac_address mac; ++ struct proc_dir_entry *procfs_iface; ++ ++ struct work_struct ndis_work; ++ unsigned long ndis_pending_work; ++ UINT attributes; ++ int iw_auth_wpa_version; ++ int iw_auth_cipher_pairwise; ++ int iw_auth_cipher_group; ++ int iw_auth_key_mgmt; ++ int iw_auth_80211_alg; ++ struct ndis_packet_pool *tx_packet_pool; ++ struct ndis_buffer_pool *tx_buffer_pool; ++ int multicast_size; ++ struct v4_checksum rx_csum; ++ struct v4_checksum tx_csum; ++ enum ndis_physical_medium physical_medium; ++ ULONG ndis_wolopts; ++ struct nt_slist wrap_timer_slist; ++ int drv_ndis_version; ++ struct ndis_pnp_capabilities pnp_capa; ++}; ++ ++BOOLEAN ndis_isr(struct kinterrupt *kinterrupt, void *ctx) wstdcall; ++ ++int ndis_init(void); ++void ndis_exit(void); ++int ndis_init_device(struct ndis_device *wnd); ++void ndis_exit_device(struct ndis_device *wnd); ++ ++int wrap_procfs_add_ndis_device(struct ndis_device *wnd); ++void wrap_procfs_remove_ndis_device(struct ndis_device *wnd); ++ ++void NdisAllocatePacketPoolEx(NDIS_STATUS *status, ++ struct ndis_packet_pool **pool_handle, ++ UINT num_descr, UINT overflowsize, ++ UINT proto_rsvd_length) wstdcall; ++void NdisFreePacketPool(struct ndis_packet_pool *pool) wstdcall; ++void NdisAllocatePacket(NDIS_STATUS *status, struct ndis_packet **packet, ++ struct ndis_packet_pool *pool) wstdcall; ++void NdisFreePacket(struct ndis_packet *descr) wstdcall; ++void NdisAllocateBufferPool(NDIS_STATUS *status, ++ struct ndis_buffer_pool **pool_handle, ++ UINT num_descr) wstdcall; ++void NdisFreeBufferPool(struct ndis_buffer_pool *pool) wstdcall; ++void NdisAllocateBuffer(NDIS_STATUS *status, ndis_buffer **buffer, ++ struct ndis_buffer_pool *pool, void *virt, ++ UINT length) wstdcall; ++void NdisFreeBuffer(ndis_buffer *descr) wstdcall; ++void NdisMIndicateReceivePacket(struct ndis_mp_block *nmb, ++ struct ndis_packet **packets, ++ UINT nr_packets) wstdcall; ++void NdisMSendComplete(struct ndis_mp_block *nmb, struct ndis_packet *packet, ++ NDIS_STATUS status) wstdcall; ++void NdisMSendResourcesAvailable(struct ndis_mp_block *nmb) wstdcall; ++void NdisMIndicateStatus(struct ndis_mp_block *nmb, ++ NDIS_STATUS status, void *buf, UINT len) wstdcall; ++void NdisMIndicateStatusComplete(struct ndis_mp_block *nmb) wstdcall; ++void NdisMQueryInformationComplete(struct ndis_mp_block *nmb, ++ NDIS_STATUS status) wstdcall; ++void NdisMSetInformationComplete(struct ndis_mp_block *nmb, ++ NDIS_STATUS status) wstdcall; ++void NdisMResetComplete(struct ndis_mp_block *nmb, NDIS_STATUS status, ++ BOOLEAN address_reset) wstdcall; ++ULONG NDIS_BUFFER_TO_SPAN_PAGES(ndis_buffer *buffer) wstdcall; ++BOOLEAN NdisWaitEvent(struct ndis_event *event, UINT timeout) wstdcall; ++void NdisSetEvent(struct ndis_event *event) wstdcall; ++void NdisMDeregisterInterrupt(struct ndis_mp_interrupt *mp_interrupt) wstdcall; ++void EthRxIndicateHandler(struct ndis_mp_block *nmb, void *rx_ctx, ++ char *header1, char *header, UINT header_size, ++ void *look_ahead, UINT look_ahead_size, ++ UINT packet_size) wstdcall; ++void EthRxComplete(struct ndis_mp_block *nmb) wstdcall; ++void NdisMTransferDataComplete(struct ndis_mp_block *nmb, ++ struct ndis_packet *packet, NDIS_STATUS status, ++ UINT bytes_txed) wstdcall; ++void NdisWriteConfiguration(NDIS_STATUS *status, struct ndis_mp_block *nmb, ++ struct unicode_string *key, ++ struct ndis_configuration_parameter *param) wstdcall; ++void NdisReadConfiguration(NDIS_STATUS *status, ++ struct ndis_configuration_parameter **param, ++ struct ndis_mp_block *nmb, ++ struct unicode_string *key, ++ enum ndis_parameter_type type) wstdcall; ++ ++/* Required OIDs */ ++#define OID_GEN_SUPPORTED_LIST 0x00010101 ++#define OID_GEN_HARDWARE_STATUS 0x00010102 ++#define OID_GEN_MEDIA_SUPPORTED 0x00010103 ++#define OID_GEN_MEDIA_IN_USE 0x00010104 ++#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 ++#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 ++#define OID_GEN_LINK_SPEED 0x00010107 ++#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 ++#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 ++#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A ++#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B ++#define OID_GEN_VENDOR_ID 0x0001010C ++#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D ++#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E ++#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F ++#define OID_GEN_DRIVER_VERSION 0x00010110 ++#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 ++#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 ++#define OID_GEN_MAC_OPTIONS 0x00010113 ++#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 ++#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 ++#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 ++#define OID_GEN_SUPPORTED_GUIDS 0x00010117 ++#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 /* Set only */ ++#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 /* Set only */ ++#define OID_GEN_MACHINE_NAME 0x0001021A ++#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B /* Set only */ ++#define OID_GEN_VLAN_ID 0x0001021C ++ ++/* Optional OIDs. */ ++#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 ++#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 ++ ++/* Required statistics OIDs. */ ++#define OID_GEN_XMIT_OK 0x00020101 ++#define OID_GEN_RCV_OK 0x00020102 ++#define OID_GEN_XMIT_ERROR 0x00020103 ++#define OID_GEN_RCV_ERROR 0x00020104 ++#define OID_GEN_RCV_NO_BUFFER 0x00020105 ++ ++/* Optional OID statistics */ ++#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 ++#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 ++#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 ++#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 ++#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 ++#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 ++#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 ++#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 ++#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 ++#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A ++#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B ++#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C ++#define OID_GEN_RCV_CRC_ERROR 0x0002020D ++#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E ++#define OID_GEN_GET_TIME_CAPS 0x0002020F ++#define OID_GEN_GET_NETCARD_TIME 0x00020210 ++#define OID_GEN_NETCARD_LOAD 0x00020211 ++#define OID_GEN_DEVICE_PROFILE 0x00020212 ++ ++/* 802.3 (ethernet) OIDs */ ++#define OID_802_3_PERMANENT_ADDRESS 0x01010101 ++#define OID_802_3_CURRENT_ADDRESS 0x01010102 ++#define OID_802_3_MULTICAST_LIST 0x01010103 ++#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 ++#define OID_802_3_MAC_OPTIONS 0x01010105 ++#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 ++#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 ++#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 ++#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 ++#define OID_802_3_XMIT_DEFERRED 0x01020201 ++#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 ++#define OID_802_3_RCV_OVERRUN 0x01020203 ++#define OID_802_3_XMIT_UNDERRUN 0x01020204 ++#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 ++#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 ++#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 ++ ++/* PnP and power management OIDs */ ++#define OID_PNP_CAPABILITIES 0xFD010100 ++#define OID_PNP_SET_POWER 0xFD010101 ++#define OID_PNP_QUERY_POWER 0xFD010102 ++#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 ++#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 ++#define OID_PNP_WAKE_UP_PATTERN_LIST 0xFD010105 ++#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 ++ ++/* PnP/PM Statistics (Optional). */ ++#define OID_PNP_WAKE_UP_OK 0xFD020200 ++#define OID_PNP_WAKE_UP_ERROR 0xFD020201 ++ ++/* The following bits are defined for OID_PNP_ENABLE_WAKE_UP */ ++#define NDIS_PNP_WAKE_UP_MAGIC_PACKET 0x00000001 ++#define NDIS_PNP_WAKE_UP_PATTERN_MATCH 0x00000002 ++#define NDIS_PNP_WAKE_UP_LINK_CHANGE 0x00000004 ++ ++/* 802.11 OIDs */ ++#define OID_802_11_BSSID 0x0D010101 ++#define OID_802_11_SSID 0x0D010102 ++#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0D010203 ++#define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204 ++#define OID_802_11_TX_POWER_LEVEL 0x0D010205 ++#define OID_802_11_RSSI 0x0D010206 ++#define OID_802_11_RSSI_TRIGGER 0x0D010207 ++#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108 ++#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0D010209 ++#define OID_802_11_RTS_THRESHOLD 0x0D01020A ++#define OID_802_11_NUMBER_OF_ANTENNAS 0x0D01020B ++#define OID_802_11_RX_ANTENNA_SELECTED 0x0D01020C ++#define OID_802_11_TX_ANTENNA_SELECTED 0x0D01020D ++#define OID_802_11_SUPPORTED_RATES 0x0D01020E ++#define OID_802_11_DESIRED_RATES 0x0D010210 ++#define OID_802_11_CONFIGURATION 0x0D010211 ++#define OID_802_11_STATISTICS 0x0D020212 ++#define OID_802_11_ADD_WEP 0x0D010113 ++#define OID_802_11_REMOVE_WEP 0x0D010114 ++#define OID_802_11_DISASSOCIATE 0x0D010115 ++#define OID_802_11_POWER_MODE 0x0D010216 ++#define OID_802_11_BSSID_LIST 0x0D010217 ++#define OID_802_11_AUTHENTICATION_MODE 0x0D010118 ++#define OID_802_11_PRIVACY_FILTER 0x0D010119 ++#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A ++#define OID_802_11_WEP_STATUS 0x0D01011B ++#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS ++#define OID_802_11_RELOAD_DEFAULTS 0x0D01011C ++#define OID_802_11_ADD_KEY 0x0D01011D ++#define OID_802_11_REMOVE_KEY 0x0D01011E ++#define OID_802_11_ASSOCIATION_INFORMATION 0x0D01011F ++#define OID_802_11_TEST 0x0D010120 ++#define OID_802_11_MEDIA_STREAM_MODE 0x0D010121 ++#define OID_802_11_CAPABILITY 0x0D010122 ++#define OID_802_11_PMKID 0x0D010123 ++ ++#define NDIS_STATUS_SUCCESS 0 ++#define NDIS_STATUS_PENDING 0x00000103 ++#define NDIS_STATUS_NOT_RECOGNIZED 0x00010001 ++#define NDIS_STATUS_NOT_COPIED 0x00010002 ++#define NDIS_STATUS_NOT_ACCEPTED 0x00010003 ++#define NDIS_STATUS_CALL_ACTIVE 0x00010007 ++#define NDIS_STATUS_ONLINE 0x40010003 ++#define NDIS_STATUS_RESET_START 0x40010004 ++#define NDIS_STATUS_RESET_END 0x40010005 ++#define NDIS_STATUS_RING_STATUS 0x40010006 ++#define NDIS_STATUS_CLOSED 0x40010007 ++#define NDIS_STATUS_WAN_LINE_UP 0x40010008 ++#define NDIS_STATUS_WAN_LINE_DOWN 0x40010009 ++#define NDIS_STATUS_WAN_FRAGMENT 0x4001000A ++#define NDIS_STATUS_MEDIA_CONNECT 0x4001000B ++#define NDIS_STATUS_MEDIA_DISCONNECT 0x4001000C ++#define NDIS_STATUS_HARDWARE_LINE_UP 0x4001000D ++#define NDIS_STATUS_HARDWARE_LINE_DOWN 0x4001000E ++#define NDIS_STATUS_INTERFACE_UP 0x4001000F ++#define NDIS_STATUS_INTERFACE_DOWN 0x40010010 ++#define NDIS_STATUS_MEDIA_BUSY 0x40010011 ++#define NDIS_STATUS_MEDIA_SPECIFIC_INDICATION 0x40010012 ++#define NDIS_STATUS_WW_INDICATION NDIS_STATUS_MEDIA_SPECIFIC_INDICATION ++#define NDIS_STATUS_LINK_SPEED_CHANGE 0x40010013 ++#define NDIS_STATUS_WAN_GET_STATS 0x40010014 ++#define NDIS_STATUS_WAN_CO_FRAGMENT 0x40010015 ++#define NDIS_STATUS_WAN_CO_LINKPARAMS 0x40010016 ++#define NDIS_STATUS_NOT_RESETTABLE 0x80010001 ++#define NDIS_STATUS_SOFT_ERRORS 0x80010003 ++#define NDIS_STATUS_HARD_ERRORS 0x80010004 ++#define NDIS_STATUS_BUFFER_OVERFLOW 0x80000005 ++#define NDIS_STATUS_FAILURE 0xC0000001 ++#define NDIS_STATUS_INVALID_PARAMETER 0xC000000D ++#define NDIS_STATUS_RESOURCES 0xC000009A ++#define NDIS_STATUS_CLOSING 0xC0010002 ++#define NDIS_STATUS_BAD_VERSION 0xC0010004 ++#define NDIS_STATUS_BAD_CHARACTERISTICS 0xC0010005 ++#define NDIS_STATUS_ADAPTER_NOT_FOUND 0xC0010006 ++#define NDIS_STATUS_OPEN_FAILED 0xC0010007 ++#define NDIS_STATUS_DEVICE_FAILED 0xC0010008 ++#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 ++#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A ++#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B ++#define NDIS_STATUS_REQUEST_ABORTED 0xC001000C ++#define NDIS_STATUS_RESET_IN_PROGRESS 0xC001000D ++#define NDIS_STATUS_CLOSING_INDICATING 0xC001000E ++#define NDIS_STATUS_BAD_VERSION 0xC0010004 ++#define NDIS_STATUS_NOT_SUPPORTED 0xC00000BB ++#define NDIS_STATUS_INVALID_PACKET 0xC001000F ++#define NDIS_STATUS_OPEN_LIST_FULL 0xC0010010 ++#define NDIS_STATUS_ADAPTER_NOT_READY 0xC0010011 ++#define NDIS_STATUS_ADAPTER_NOT_OPEN 0xC0010012 ++#define NDIS_STATUS_NOT_INDICATING 0xC0010013 ++#define NDIS_STATUS_INVALID_LENGTH 0xC0010014 ++#define NDIS_STATUS_INVALID_DATA 0xC0010015 ++#define NDIS_STATUS_BUFFER_TOO_SHORT 0xC0010016 ++#define NDIS_STATUS_INVALID_OID 0xC0010017 ++#define NDIS_STATUS_ADAPTER_REMOVED 0xC0010018 ++#define NDIS_STATUS_UNSUPPORTED_MEDIA 0xC0010019 ++#define NDIS_STATUS_GROUP_ADDRESS_IN_USE 0xC001001A ++#define NDIS_STATUS_FILE_NOT_FOUND 0xC001001B ++#define NDIS_STATUS_ERROR_READING_FILE 0xC001001C ++#define NDIS_STATUS_ALREADY_MAPPED 0xC001001D ++#define NDIS_STATUS_RESOURCE_CONFLICT 0xC001001E ++#define NDIS_STATUS_NO_CABLE 0xC001001F ++#define NDIS_STATUS_INVALID_SAP 0xC0010020 ++#define NDIS_STATUS_SAP_IN_USE 0xC0010021 ++#define NDIS_STATUS_INVALID_ADDRESS 0xC0010022 ++#define NDIS_STATUS_VC_NOT_ACTIVATED 0xC0010023 ++#define NDIS_STATUS_DEST_OUT_OF_ORDER 0xC0010024 ++#define NDIS_STATUS_VC_NOT_AVAILABLE 0xC0010025 ++#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE 0xC0010026 ++#define NDIS_STATUS_INCOMPATABLE_QOS 0xC0010027 ++#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED 0xC0010028 ++#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION 0xC0010029 ++#define NDIS_STATUS_TOKEN_RING_OPEN_ERROR 0xC0011000 ++#define NDIS_STATUS_INVALID_DEVICE_REQUEST 0xC0000010 ++#define NDIS_STATUS_NETWORK_UNREACHABLE 0xC000023C ++ ++/* Event codes */ ++ ++#define EVENT_NDIS_RESOURCE_CONFLICT 0xC0001388 ++#define EVENT_NDIS_OUT_OF_RESOURCE 0xC0001389 ++#define EVENT_NDIS_HARDWARE_FAILURE 0xC000138A ++#define EVENT_NDIS_ADAPTER_NOT_FOUND 0xC000138B ++#define EVENT_NDIS_INTERRUPT_CONNECT 0xC000138C ++#define EVENT_NDIS_DRIVER_FAILURE 0xC000138D ++#define EVENT_NDIS_BAD_VERSION 0xC000138E ++#define EVENT_NDIS_TIMEOUT 0x8000138F ++#define EVENT_NDIS_NETWORK_ADDRESS 0xC0001390 ++#define EVENT_NDIS_UNSUPPORTED_CONFIGURATION 0xC0001391 ++#define EVENT_NDIS_INVALID_VALUE_FROM_ADAPTER 0xC0001392 ++#define EVENT_NDIS_MISSING_CONFIGURATION_PARAMETER 0xC0001393 ++#define EVENT_NDIS_BAD_IO_BASE_ADDRESS 0xC0001394 ++#define EVENT_NDIS_RECEIVE_SPACE_SMALL 0x40001395 ++#define EVENT_NDIS_ADAPTER_DISABLED 0x80001396 ++#define EVENT_NDIS_IO_PORT_CONFLICT 0x80001397 ++#define EVENT_NDIS_PORT_OR_DMA_CONFLICT 0x80001398 ++#define EVENT_NDIS_MEMORY_CONFLICT 0x80001399 ++#define EVENT_NDIS_INTERRUPT_CONFLICT 0x8000139A ++#define EVENT_NDIS_DMA_CONFLICT 0x8000139B ++#define EVENT_NDIS_INVALID_DOWNLOAD_FILE_ERROR 0xC000139C ++#define EVENT_NDIS_MAXRECEIVES_ERROR 0x8000139D ++#define EVENT_NDIS_MAXTRANSMITS_ERROR 0x8000139E ++#define EVENT_NDIS_MAXFRAMESIZE_ERROR 0x8000139F ++#define EVENT_NDIS_MAXINTERNALBUFS_ERROR 0x800013A0 ++#define EVENT_NDIS_MAXMULTICAST_ERROR 0x800013A1 ++#define EVENT_NDIS_PRODUCTID_ERROR 0x800013A2 ++#define EVENT_NDIS_LOBE_FAILUE_ERROR 0x800013A3 ++#define EVENT_NDIS_SIGNAL_LOSS_ERROR 0x800013A4 ++#define EVENT_NDIS_REMOVE_RECEIVED_ERROR 0x800013A5 ++#define EVENT_NDIS_TOKEN_RING_CORRECTION 0x400013A6 ++#define EVENT_NDIS_ADAPTER_CHECK_ERROR 0xC00013A7 ++#define EVENT_NDIS_RESET_FAILURE_ERROR 0x800013A8 ++#define EVENT_NDIS_CABLE_DISCONNECTED_ERROR 0x800013A9 ++#define EVENT_NDIS_RESET_FAILURE_CORRECTION 0x800013AA ++ ++/* packet filter bits used by NDIS_OID_PACKET_FILTER */ ++#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 ++#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 ++#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 ++#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 ++#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 ++#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 ++#define NDIS_PACKET_TYPE_SMT 0x00000040 ++#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 ++#define NDIS_PACKET_TYPE_GROUP 0x00001000 ++#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000 ++#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000 ++#define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000 ++ ++/* memory allocation flags */ ++#define NDIS_MEMORY_CONTIGUOUS 0x00000001 ++#define NDIS_MEMORY_NONCACHED 0x00000002 ++ ++/* Attribute flags to NdisMSetAtrributesEx */ ++#define NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT 0x00000001 ++#define NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT 0x00000002 ++#define NDIS_ATTRIBUTE_IGNORE_TOKEN_RING_ERRORS 0x00000004 ++#define NDIS_ATTRIBUTE_BUS_MASTER 0x00000008 ++#define NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER 0x00000010 ++#define NDIS_ATTRIBUTE_DESERIALIZE 0x00000020 ++#define NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND 0x00000040 ++#define NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK 0x00000080 ++#define NDIS_ATTRIBUTE_NOT_CO_NDIS 0x00000100 ++#define NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS 0x00000200 ++ ++#define OID_TCP_TASK_OFFLOAD 0xFC010201 ++ ++#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 ++#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 ++#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 ++#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 ++#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 ++#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 ++#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 ++#define NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00000080 ++#define NDIS_MAC_OPTION_RECEIVE_AT_DPC 0x00000100 ++#define NDIS_MAC_OPTION_8021Q_VLAN 0x00000200 ++#define NDIS_MAC_OPTION_RESERVED 0x80000000 ++ ++#define deserialized_driver(wnd) (wnd->attributes & NDIS_ATTRIBUTE_DESERIALIZE) ++ ++static inline void serialize_lock(struct ndis_device *wnd) ++{ ++ nt_spin_lock(&wnd->nmb->lock); ++} ++ ++static inline void serialize_unlock(struct ndis_device *wnd) ++{ ++ nt_spin_unlock(&wnd->nmb->lock); ++} ++ ++static inline KIRQL serialize_lock_irql(struct ndis_device *wnd) ++{ ++ if (deserialized_driver(wnd)) ++ return raise_irql(DISPATCH_LEVEL); ++ else ++ return nt_spin_lock_irql(&wnd->nmb->lock, DISPATCH_LEVEL); ++} ++ ++static inline void serialize_unlock_irql(struct ndis_device *wnd, ++ KIRQL irql) ++{ ++ if (deserialized_driver(wnd)) ++ lower_irql(irql); ++ else ++ nt_spin_unlock_irql(&wnd->nmb->lock, irql); ++} ++ ++static inline void if_serialize_lock(struct ndis_device *wnd) ++{ ++ if (!deserialized_driver(wnd)) ++ nt_spin_lock(&wnd->nmb->lock); ++} ++ ++static inline void if_serialize_unlock(struct ndis_device *wnd) ++{ ++ if (!deserialized_driver(wnd)) ++ nt_spin_unlock(&wnd->nmb->lock); ++} ++ ++#endif /* NDIS_H */ +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/ndiswrapper.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ndiswrapper.h +--- linux-3.12.2/3rdparty/ndiswrapper/ndiswrapper.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ndiswrapper.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,219 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _NDISWRAPPER_H_ ++#define _NDISWRAPPER_H_ ++ ++#define DRIVER_VERSION "1.59" ++#define UTILS_VERSION "1.9" ++ ++#define DRIVER_NAME "ndiswrapper" ++#define DRIVER_CONFIG_DIR "/etc/ndiswrapper" ++ ++#define NDIS_ESSID_MAX_SIZE 32 ++#define NDIS_ENCODING_TOKEN_MAX 32 ++#define MAX_ENCR_KEYS 4 ++#define TX_RING_SIZE 16 ++#define NDIS_MAX_RATES 8 ++#define NDIS_MAX_RATES_EX 16 ++ ++#define WRAP_PCI_BUS 5 ++#define WRAP_PCMCIA_BUS 8 ++/* some USB devices, e.g., DWL-G120 have BusType as 0 */ ++#define WRAP_INTERNAL_BUS 0 ++/* documentation at msdn says 15 is PNP bus, but inf files from all ++ * vendors say 15 is USB; which is correct? */ ++#define WRAP_USB_BUS 15 ++ ++/* NDIS device must be 0, for compatibility with old versions of ++ * ndiswrapper where device type for NDIS drivers is 0 */ ++#define WRAP_NDIS_DEVICE 0 ++#define WRAP_USB_DEVICE 1 ++#define WRAP_BLUETOOTH_DEVICE1 2 ++#define WRAP_BLUETOOTH_DEVICE2 3 ++ ++#define WRAP_DEVICE_BUS(dev, bus) ((dev) << 8 | (bus)) ++#define WRAP_BUS(dev_bus) ((dev_bus) & 0x000FF) ++#define WRAP_DEVICE(dev_bus) ((dev_bus) >> 8) ++ ++#define MAX_DRIVER_NAME_LEN 32 ++#define MAX_VERSION_STRING_LEN 64 ++#define MAX_SETTING_NAME_LEN 128 ++#define MAX_SETTING_VALUE_LEN 256 ++ ++#define MAX_DRIVER_PE_IMAGES 4 ++#define MAX_DRIVER_BIN_FILES 5 ++#define MAX_DEVICE_SETTINGS 512 ++ ++#define MAX_ALLOCATED_URBS 15 ++ ++#define DEV_ANY_ID -1 ++ ++#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] ++#define MACSTRSEP "%02x:%02x:%02x:%02x:%02x:%02x" ++#define MACSTR "%02x%02x%02x%02x%02x%02x" ++#define MACINTADR(a) (int*)&((a)[0]), (int*)&((a)[1]), (int*)&((a)[2]), \ ++ (int*)&((a)[3]), (int*)&((a)[4]), (int*)&((a)[5]) ++ ++#ifdef __KERNEL__ ++/* DEBUG macros */ ++ ++#define MSG(level, fmt, ...) \ ++ printk(level DRIVER_NAME " (%s:%d): " fmt "\n", \ ++ __func__, __LINE__ , ## __VA_ARGS__) ++ ++#define WARNING(fmt, ...) MSG(KERN_WARNING, fmt, ## __VA_ARGS__) ++#define ERROR(fmt, ...) MSG(KERN_ERR, fmt , ## __VA_ARGS__) ++#define INFO(fmt, ...) MSG(KERN_INFO, fmt , ## __VA_ARGS__) ++#define TODO() WARNING("not fully implemented (yet)") ++ ++#define TRACE(level, fmt, ...) \ ++do { \ ++ if (debug >= level) \ ++ printk(KERN_INFO "%s (%s:%d): " fmt "\n", DRIVER_NAME, \ ++ __func__, __LINE__ , ## __VA_ARGS__); \ ++} while (0) ++#define TRACE0(fmt, ...) TRACE(0, fmt , ## __VA_ARGS__) ++ ++extern int debug; ++ ++#ifndef DEBUG ++#define DEBUG 0 ++#endif ++ ++/* for a block of code */ ++#if DEBUG >= 1 ++#define DBG_BLOCK(level) if (debug >= level) ++#else ++#define DBG_BLOCK(level) while (0) ++#endif ++ ++#if DEBUG >= 1 ++#define TRACE1(fmt, ...) TRACE(1, fmt , ## __VA_ARGS__) ++#else ++#define TRACE1(fmt, ...) do { } while (0) ++#endif ++ ++#if DEBUG >= 2 ++#define TRACE2(fmt, ...) TRACE(2, fmt , ## __VA_ARGS__) ++#else ++#define TRACE2(fmt, ...) do { } while (0) ++#endif ++ ++#if DEBUG >= 3 ++#define TRACE3(fmt, ...) TRACE(3, fmt , ## __VA_ARGS__) ++#else ++#define TRACE3(fmt, ...) do { } while (0) ++#endif ++ ++#if DEBUG >= 4 ++#define TRACE4(fmt, ...) TRACE(4, fmt , ## __VA_ARGS__) ++#else ++#define TRACE4(fmt, ...) do { } while (0) ++#endif ++ ++#if DEBUG >= 5 ++#define TRACE5(fmt, ...) TRACE(5, fmt , ## __VA_ARGS__) ++#else ++#define TRACE5(fmt, ...) do { } while (0) ++#endif ++ ++#if DEBUG >= 6 ++#define TRACE6(fmt, ...) TRACE(6, fmt , ## __VA_ARGS__) ++#else ++#define TRACE6(fmt, ...) do { } while (0) ++#endif ++ ++#define ENTER0(fmt, ...) TRACE0("Enter " fmt , ## __VA_ARGS__) ++#define ENTER1(fmt, ...) TRACE1("Enter " fmt , ## __VA_ARGS__) ++#define ENTER2(fmt, ...) TRACE2("Enter " fmt , ## __VA_ARGS__) ++#define ENTER3(fmt, ...) TRACE3("Enter " fmt , ## __VA_ARGS__) ++#define ENTER4(fmt, ...) TRACE4("Enter " fmt , ## __VA_ARGS__) ++#define ENTER5(fmt, ...) TRACE5("Enter " fmt , ## __VA_ARGS__) ++#define ENTER6(fmt, ...) TRACE6("Enter " fmt , ## __VA_ARGS__) ++ ++#define EXIT0(stmt) do { TRACE0("Exit"); stmt; } while (0) ++#define EXIT1(stmt) do { TRACE1("Exit"); stmt; } while (0) ++#define EXIT2(stmt) do { TRACE2("Exit"); stmt; } while (0) ++#define EXIT3(stmt) do { TRACE3("Exit"); stmt; } while (0) ++#define EXIT4(stmt) do { TRACE4("Exit"); stmt; } while (0) ++#define EXIT5(stmt) do { TRACE5("Exit"); stmt; } while (0) ++#define EXIT6(stmt) do { TRACE6("Exit"); stmt; } while (0) ++ ++#if defined(USB_DEBUG) ++#define USBTRACE TRACE0 ++#define USBENTER ENTER0 ++#define USBEXIT EXIT0 ++#else ++#define USBTRACE(fmt, ...) do { } while (0) ++#define USBENTER(fmt, ...) ++#define USBEXIT(stmt) stmt ++#endif ++ ++#if defined(EVENT_DEBUG) ++#define EVENTTRACE TRACE0 ++#define EVENTENTER ENTER0 ++#define EVENTEXIT EXIT0 ++#else ++#define EVENTTRACE(fmt, ...) do { } while (0) ++#define EVENTENTER(fmt, ...) ++#define EVENTEXIT(stmt) stmt ++#endif ++ ++#if defined(TIMER_DEBUG) ++#define TIMERTRACE TRACE0 ++#define TIMERENTER ENTER0 ++#define TIMEREXIT EXIT0 ++#else ++#define TIMERTRACE(fmt, ...) do { } while (0) ++#define TIMERENTER(fmt, ...) ++#define TIMEREXIT(stmt) stmt ++#endif ++ ++#if defined(IO_DEBUG) ++#define IOTRACE TRACE0 ++#define IOENTER ENTER0 ++#define IOEXIT EXIT0 ++#else ++#define IOTRACE(fmt, ...) do { } while (0) ++#define IOENTER(fmt, ...) ++#define IOEXIT(stmt) stmt ++#endif ++ ++#if defined(WORK_DEBUG) ++#define WORKTRACE TRACE0 ++#define WORKENTER ENTER0 ++#define WORKEXIT EXIT0 ++#else ++#define WORKTRACE(fmt, ...) do { } while (0) ++#define WORKENTER(fmt, ...) ++#define WORKEXIT(stmt) stmt ++#endif ++ ++#if DEBUG >= 1 ++#define assert(expr) \ ++do { \ ++ if (!(expr)) { \ ++ ERROR("assertion '%s' failed", #expr); \ ++ dump_stack(); \ ++ } \ ++} while (0) ++#else ++#define assert(expr) do { } while (0) ++#endif ++ ++#endif // __KERNEL__ ++ ++#endif // NDISWRAPPER_H +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/ntoskernel.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ntoskernel.c +--- linux-3.12.2/3rdparty/ndiswrapper/ntoskernel.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ntoskernel.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,2677 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ntoskernel.h" ++#include "ndis.h" ++#include "usb.h" ++#include "pnp.h" ++#include "loader.h" ++#include "ntoskernel_exports.h" ++ ++/* MDLs describe a range of virtual address with an array of physical ++ * pages right after the header. For different ranges of virtual ++ * addresses, the number of entries of physical pages may be different ++ * (depending on number of entries required). If we want to allocate ++ * MDLs from a pool, the size has to be constant. So we assume that ++ * maximum range used by a driver is MDL_CACHE_PAGES; if a driver ++ * requests an MDL for a bigger region, we allocate it with kmalloc; ++ * otherwise, we allocate from the pool */ ++ ++#define MDL_CACHE_PAGES 3 ++#define MDL_CACHE_SIZE (sizeof(struct mdl) + \ ++ (sizeof(PFN_NUMBER) * MDL_CACHE_PAGES)) ++struct wrap_mdl { ++ struct nt_list list; ++ struct mdl mdl[0]; ++}; ++ ++/* everything here is for all drivers/devices - not per driver/device */ ++static spinlock_t dispatcher_lock; ++spinlock_t ntoskernel_lock; ++static void *mdl_cache; ++static struct nt_list wrap_mdl_list; ++ ++static struct work_struct kdpc_work; ++static void kdpc_worker(struct work_struct *dummy); ++ ++static struct nt_list kdpc_list; ++static spinlock_t kdpc_list_lock; ++ ++static struct nt_list callback_objects; ++ ++struct nt_list object_list; ++ ++struct bus_driver { ++ struct nt_list list; ++ char name[MAX_DRIVER_NAME_LEN]; ++ struct driver_object drv_obj; ++}; ++ ++static struct nt_list bus_driver_list; ++ ++static struct work_struct ntos_work; ++static struct nt_list ntos_work_list; ++static spinlock_t ntos_work_lock; ++static void ntos_work_worker(struct work_struct *dummy); ++spinlock_t irp_cancel_lock; ++static NT_SPIN_LOCK nt_list_lock; ++static struct nt_slist wrap_timer_slist; ++CCHAR cpu_count; ++ ++/* compute ticks (100ns) since 1601 until when system booted into ++ * wrap_ticks_to_boot */ ++u64 wrap_ticks_to_boot; ++ ++#if defined(CONFIG_X86_64) ++static struct timer_list shared_data_timer; ++struct kuser_shared_data kuser_shared_data; ++static void update_user_shared_data_proc(unsigned long data); ++#endif ++ ++WIN_SYMBOL_MAP("KeTickCount", &jiffies) ++WIN_SYMBOL_MAP("KeNumberProcessors", &cpu_count) ++WIN_SYMBOL_MAP("NlsMbCodePageTag", FALSE) ++ ++struct workqueue_struct *ntos_wq; ++ ++#ifdef WRAP_PREEMPT ++DEFINE_PER_CPU(struct irql_info, irql_info); ++#endif ++ ++#if defined(CONFIG_X86_64) ++static void update_user_shared_data_proc(unsigned long data) ++{ ++ /* timer is supposed to be scheduled every 10ms, but bigger ++ * intervals seem to work (tried up to 50ms) */ ++ *((ULONG64 *)&kuser_shared_data.system_time) = ticks_1601(); ++ *((ULONG64 *)&kuser_shared_data.interrupt_time) = ++ jiffies * TICKSPERSEC / HZ; ++ *((ULONG64 *)&kuser_shared_data.tick) = jiffies; ++ ++ mod_timer(&shared_data_timer, jiffies + MSEC_TO_HZ(30)); ++} ++#endif ++ ++void *allocate_object(ULONG size, enum common_object_type type, ++ struct unicode_string *name) ++{ ++ struct common_object_header *hdr; ++ void *body; ++ ++ /* we pad header as prefix to body */ ++ hdr = ExAllocatePoolWithTag(NonPagedPool, OBJECT_SIZE(size), 0); ++ if (!hdr) { ++ WARNING("couldn't allocate memory"); ++ return NULL; ++ } ++ memset(hdr, 0, OBJECT_SIZE(size)); ++ if (name) { ++ hdr->name.buf = ExAllocatePoolWithTag(NonPagedPool, ++ name->max_length, 0); ++ if (!hdr->name.buf) { ++ ExFreePool(hdr); ++ return NULL; ++ } ++ memcpy(hdr->name.buf, name->buf, name->max_length); ++ hdr->name.length = name->length; ++ hdr->name.max_length = name->max_length; ++ } ++ hdr->type = type; ++ hdr->ref_count = 1; ++ spin_lock_bh(&ntoskernel_lock); ++ /* threads are looked up often (in KeWaitForXXX), so optimize ++ * for fast lookups of threads */ ++ if (type == OBJECT_TYPE_NT_THREAD) ++ InsertHeadList(&object_list, &hdr->list); ++ else ++ InsertTailList(&object_list, &hdr->list); ++ spin_unlock_bh(&ntoskernel_lock); ++ body = HEADER_TO_OBJECT(hdr); ++ TRACE3("allocated hdr: %p, body: %p", hdr, body); ++ return body; ++} ++ ++static void free_object(void *object) ++{ ++ struct common_object_header *hdr; ++ ++ hdr = OBJECT_TO_HEADER(object); ++ spin_lock_bh(&ntoskernel_lock); ++ RemoveEntryList(&hdr->list); ++ spin_unlock_bh(&ntoskernel_lock); ++ TRACE3("freed hdr: %p, body: %p", hdr, object); ++ if (hdr->name.buf) ++ ExFreePool(hdr->name.buf); ++ ExFreePool(hdr); ++} ++ ++static int add_bus_driver(const char *name) ++{ ++ struct bus_driver *bus_driver; ++ ++ bus_driver = kzalloc(sizeof(*bus_driver), GFP_KERNEL); ++ if (!bus_driver) { ++ ERROR("couldn't allocate memory"); ++ return -ENOMEM; ++ } ++ strncpy(bus_driver->name, name, sizeof(bus_driver->name)); ++ bus_driver->name[sizeof(bus_driver->name)-1] = 0; ++ spin_lock_bh(&ntoskernel_lock); ++ InsertTailList(&bus_driver_list, &bus_driver->list); ++ spin_unlock_bh(&ntoskernel_lock); ++ TRACE1("bus driver %s is at %p", name, &bus_driver->drv_obj); ++ return STATUS_SUCCESS; ++} ++ ++struct driver_object *find_bus_driver(const char *name) ++{ ++ struct bus_driver *bus_driver; ++ struct driver_object *drv_obj; ++ ++ spin_lock_bh(&ntoskernel_lock); ++ drv_obj = NULL; ++ nt_list_for_each_entry(bus_driver, &bus_driver_list, list) { ++ if (strcmp(bus_driver->name, name) == 0) { ++ drv_obj = &bus_driver->drv_obj; ++ break; ++ } ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ return drv_obj; ++} ++ ++wfastcall struct nt_list *WIN_FUNC(ExfInterlockedInsertHeadList,3) ++ (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) ++{ ++ struct nt_list *first; ++ unsigned long flags; ++ ++ ENTER5("head = %p, entry = %p", head, entry); ++ nt_spin_lock_irqsave(lock, flags); ++ first = InsertHeadList(head, entry); ++ nt_spin_unlock_irqrestore(lock, flags); ++ TRACE5("head = %p, old = %p", head, first); ++ return first; ++} ++ ++wfastcall struct nt_list *WIN_FUNC(ExInterlockedInsertHeadList,3) ++ (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) ++{ ++ ENTER5("%p", head); ++ return ExfInterlockedInsertHeadList(head, entry, lock); ++} ++ ++wfastcall struct nt_list *WIN_FUNC(ExfInterlockedInsertTailList,3) ++ (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) ++{ ++ struct nt_list *last; ++ unsigned long flags; ++ ++ ENTER5("head = %p, entry = %p", head, entry); ++ nt_spin_lock_irqsave(lock, flags); ++ last = InsertTailList(head, entry); ++ nt_spin_unlock_irqrestore(lock, flags); ++ TRACE5("head = %p, old = %p", head, last); ++ return last; ++} ++ ++wfastcall struct nt_list *WIN_FUNC(ExInterlockedInsertTailList,3) ++ (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) ++{ ++ ENTER5("%p", head); ++ return ExfInterlockedInsertTailList(head, entry, lock); ++} ++ ++wfastcall struct nt_list *WIN_FUNC(ExfInterlockedRemoveHeadList,2) ++ (struct nt_list *head, NT_SPIN_LOCK *lock) ++{ ++ struct nt_list *ret; ++ unsigned long flags; ++ ++ ENTER5("head = %p", head); ++ nt_spin_lock_irqsave(lock, flags); ++ ret = RemoveHeadList(head); ++ nt_spin_unlock_irqrestore(lock, flags); ++ TRACE5("head = %p, ret = %p", head, ret); ++ return ret; ++} ++ ++wfastcall struct nt_list *WIN_FUNC(ExInterlockedRemoveHeadList,2) ++ (struct nt_list *head, NT_SPIN_LOCK *lock) ++{ ++ ENTER5("%p", head); ++ return ExfInterlockedRemoveHeadList(head, lock); ++} ++ ++wfastcall struct nt_list *WIN_FUNC(ExfInterlockedRemoveTailList,2) ++ (struct nt_list *head, NT_SPIN_LOCK *lock) ++{ ++ struct nt_list *ret; ++ unsigned long flags; ++ ++ ENTER5("head = %p", head); ++ nt_spin_lock_irqsave(lock, flags); ++ ret = RemoveTailList(head); ++ nt_spin_unlock_irqrestore(lock, flags); ++ TRACE5("head = %p, ret = %p", head, ret); ++ return ret; ++} ++ ++wfastcall struct nt_list *WIN_FUNC(ExInterlockedRemoveTailList,2) ++ (struct nt_list *head, NT_SPIN_LOCK *lock) ++{ ++ ENTER5("%p", head); ++ return ExfInterlockedRemoveTailList(head, lock); ++} ++ ++wfastcall void WIN_FUNC(InitializeSListHead,1) ++ (nt_slist_header *head) ++{ ++ memset(head, 0, sizeof(*head)); ++} ++ ++wfastcall struct nt_slist *WIN_FUNC(ExInterlockedPushEntrySList,3) ++ (nt_slist_header *head, struct nt_slist *entry, NT_SPIN_LOCK *lock) ++{ ++ struct nt_slist *ret; ++ ++ ret = PushEntrySList(head, entry, lock); ++ return ret; ++} ++ ++wstdcall struct nt_slist *WIN_FUNC(ExpInterlockedPushEntrySList,2) ++ (nt_slist_header *head, struct nt_slist *entry) ++{ ++ struct nt_slist *ret; ++ ++ ret = PushEntrySList(head, entry, &nt_list_lock); ++ return ret; ++} ++ ++wfastcall struct nt_slist *WIN_FUNC(InterlockedPushEntrySList,2) ++ (nt_slist_header *head, struct nt_slist *entry) ++{ ++ struct nt_slist *ret; ++ ++ ret = PushEntrySList(head, entry, &nt_list_lock); ++ return ret; ++} ++ ++wfastcall struct nt_slist *WIN_FUNC(ExInterlockedPopEntrySList,2) ++ (nt_slist_header *head, NT_SPIN_LOCK *lock) ++{ ++ struct nt_slist *ret; ++ ++ ret = PopEntrySList(head, lock); ++ return ret; ++} ++ ++wstdcall struct nt_slist *WIN_FUNC(ExpInterlockedPopEntrySList,1) ++ (nt_slist_header *head) ++{ ++ struct nt_slist *ret; ++ ++ ret = PopEntrySList(head, &nt_list_lock); ++ return ret; ++} ++ ++wfastcall struct nt_slist *WIN_FUNC(InterlockedPopEntrySList,1) ++ (nt_slist_header *head) ++{ ++ struct nt_slist *ret; ++ ++ ret = PopEntrySList(head, &nt_list_lock); ++ return ret; ++} ++ ++wstdcall USHORT WIN_FUNC(ExQueryDepthSList,1) ++ (nt_slist_header *head) ++{ ++ USHORT depth; ++ ENTER5("%p", head); ++ depth = head->depth; ++ TRACE5("%d, %p", depth, head->next); ++ return depth; ++} ++ ++wfastcall LONG WIN_FUNC(InterlockedIncrement,1) ++ (LONG volatile *val) ++{ ++ return post_atomic_add(*val, 1); ++} ++ ++wfastcall LONG WIN_FUNC(InterlockedDecrement,1) ++ (LONG volatile *val) ++{ ++ return post_atomic_add(*val, -1); ++} ++ ++wfastcall LONG WIN_FUNC(InterlockedExchange,2) ++ (LONG volatile *target, LONG val) ++{ ++ return xchg(target, val); ++} ++ ++wfastcall LONG WIN_FUNC(InterlockedCompareExchange,3) ++ (LONG volatile *dest, LONG new, LONG old) ++{ ++ return cmpxchg(dest, old, new); ++} ++ ++wfastcall void WIN_FUNC(ExInterlockedAddLargeStatistic,2) ++ (LARGE_INTEGER volatile *plint, ULONG n) ++{ ++ unsigned long flags; ++ ++ local_irq_save(flags); ++#ifdef CONFIG_X86_64 ++ __asm__ __volatile__( ++ "\n" ++ LOCK_PREFIX "add %1, %0\n\t" ++ : "+m" (*plint) ++ : "r" (n)); ++#else ++ __asm__ __volatile__( ++ "1:\t" ++ " movl %1, %%ebx\n\t" ++ " movl %%edx, %%ecx\n\t" ++ " addl %%eax, %%ebx\n\t" ++ " adcl $0, %%ecx\n\t" ++ LOCK_PREFIX "cmpxchg8b %0\n\t" ++ " jnz 1b\n\t" ++ : "+m" (*plint) ++ : "m" (n), "A" (*plint) ++ : "ebx", "ecx"); ++#endif ++ local_irq_restore(flags); ++} ++ ++static void initialize_object(struct dispatcher_header *dh, enum dh_type type, ++ int state) ++{ ++ memset(dh, 0, sizeof(*dh)); ++ set_object_type(dh, type); ++ dh->signal_state = state; ++ InitializeListHead(&dh->wait_blocks); ++} ++ ++static void timer_proc(unsigned long data) ++{ ++ struct wrap_timer *wrap_timer = (struct wrap_timer *)data; ++ struct nt_timer *nt_timer; ++ struct kdpc *kdpc; ++ ++ nt_timer = wrap_timer->nt_timer; ++ TIMERENTER("%p(%p), %lu", wrap_timer, nt_timer, jiffies); ++#ifdef TIMER_DEBUG ++ BUG_ON(wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC); ++ BUG_ON(nt_timer->wrap_timer_magic != WRAP_TIMER_MAGIC); ++#endif ++ KeSetEvent((struct nt_event *)nt_timer, 0, FALSE); ++ if (wrap_timer->repeat) ++ mod_timer(&wrap_timer->timer, jiffies + wrap_timer->repeat); ++ kdpc = nt_timer->kdpc; ++ if (kdpc) ++ queue_kdpc(kdpc); ++ TIMEREXIT(return); ++} ++ ++void wrap_init_timer(struct nt_timer *nt_timer, enum timer_type type, ++ struct ndis_mp_block *nmb) ++{ ++ struct wrap_timer *wrap_timer; ++ ++ /* TODO: if a timer is initialized more than once, we allocate ++ * memory for wrap_timer more than once for the same nt_timer, ++ * wasting memory. We can check if nt_timer->wrap_timer_magic is ++ * set and not allocate, but it is not guaranteed always to be ++ * safe */ ++ TIMERENTER("%p", nt_timer); ++ /* we allocate memory for wrap_timer behind driver's back and ++ * there is no NDIS/DDK function where this memory can be ++ * freed, so we use slack_kmalloc so it gets freed when driver ++ * is unloaded */ ++ if (nmb) ++ wrap_timer = kzalloc(sizeof(*wrap_timer), irql_gfp()); ++ else ++ wrap_timer = slack_kzalloc(sizeof(*wrap_timer)); ++ if (!wrap_timer) { ++ ERROR("couldn't allocate memory for timer"); ++ return; ++ } ++ ++ init_timer(&wrap_timer->timer); ++ wrap_timer->timer.data = (unsigned long)wrap_timer; ++ wrap_timer->timer.function = timer_proc; ++ wrap_timer->nt_timer = nt_timer; ++#ifdef TIMER_DEBUG ++ wrap_timer->wrap_timer_magic = WRAP_TIMER_MAGIC; ++#endif ++ nt_timer->wrap_timer = wrap_timer; ++ nt_timer->kdpc = NULL; ++ initialize_object(&nt_timer->dh, (enum dh_type)type, 0); ++ nt_timer->wrap_timer_magic = WRAP_TIMER_MAGIC; ++ TIMERTRACE("timer %p (%p)", wrap_timer, nt_timer); ++ spin_lock_bh(&ntoskernel_lock); ++ if (nmb) { ++ wrap_timer->slist.next = nmb->wnd->wrap_timer_slist.next; ++ nmb->wnd->wrap_timer_slist.next = &wrap_timer->slist; ++ } else { ++ wrap_timer->slist.next = wrap_timer_slist.next; ++ wrap_timer_slist.next = &wrap_timer->slist; ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ TIMEREXIT(return); ++} ++ ++wstdcall void WIN_FUNC(KeInitializeTimerEx,2) ++ (struct nt_timer *nt_timer, enum timer_type type) ++{ ++ TIMERENTER("%p", nt_timer); ++ wrap_init_timer(nt_timer, type, NULL); ++} ++ ++wstdcall void WIN_FUNC(KeInitializeTimer,1) ++ (struct nt_timer *nt_timer) ++{ ++ TIMERENTER("%p", nt_timer); ++ wrap_init_timer(nt_timer, NotificationTimer, NULL); ++} ++ ++/* expires and repeat are in HZ */ ++BOOLEAN wrap_set_timer(struct nt_timer *nt_timer, unsigned long expires_hz, ++ unsigned long repeat_hz, struct kdpc *kdpc) ++{ ++ struct wrap_timer *wrap_timer; ++ ++ TIMERENTER("%p, %lu, %lu, %p, %lu", ++ nt_timer, expires_hz, repeat_hz, kdpc, jiffies); ++ ++ wrap_timer = nt_timer->wrap_timer; ++ TIMERTRACE("%p", wrap_timer); ++#ifdef TIMER_DEBUG ++ if (wrap_timer->nt_timer != nt_timer) ++ WARNING("bad timers: %p, %p, %p", wrap_timer, nt_timer, ++ wrap_timer->nt_timer); ++ if (nt_timer->wrap_timer_magic != WRAP_TIMER_MAGIC) { ++ WARNING("buggy Windows timer didn't initialize timer %p", ++ nt_timer); ++ return FALSE; ++ } ++ if (wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC) { ++ WARNING("timer %p is not initialized (%lx)?", ++ wrap_timer, wrap_timer->wrap_timer_magic); ++ wrap_timer->wrap_timer_magic = WRAP_TIMER_MAGIC; ++ } ++#endif ++ KeClearEvent((struct nt_event *)nt_timer); ++ nt_timer->kdpc = kdpc; ++ wrap_timer->repeat = repeat_hz; ++ if (mod_timer(&wrap_timer->timer, jiffies + expires_hz)) ++ TIMEREXIT(return TRUE); ++ else ++ TIMEREXIT(return FALSE); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeSetTimerEx,4) ++ (struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, ++ LONG period_ms, struct kdpc *kdpc) ++{ ++ unsigned long expires_hz, repeat_hz; ++ ++ TIMERENTER("%p, %lld, %d", nt_timer, duetime_ticks, period_ms); ++ expires_hz = SYSTEM_TIME_TO_HZ(duetime_ticks); ++ repeat_hz = MSEC_TO_HZ(period_ms); ++ return wrap_set_timer(nt_timer, expires_hz, repeat_hz, kdpc); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeSetTimer,3) ++ (struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, ++ struct kdpc *kdpc) ++{ ++ TIMERENTER("%p, %lld, %p", nt_timer, duetime_ticks, kdpc); ++ return KeSetTimerEx(nt_timer, duetime_ticks, 0, kdpc); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeCancelTimer,1) ++ (struct nt_timer *nt_timer) ++{ ++ struct wrap_timer *wrap_timer; ++ int ret; ++ ++ TIMERENTER("%p", nt_timer); ++ wrap_timer = nt_timer->wrap_timer; ++ if (!wrap_timer) { ++ ERROR("invalid wrap_timer"); ++ return TRUE; ++ } ++#ifdef TIMER_DEBUG ++ BUG_ON(wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC); ++#endif ++ /* disable timer before deleting so if it is periodic timer, it ++ * won't be re-armed after deleting */ ++ wrap_timer->repeat = 0; ++ ret = del_timer_sync(&wrap_timer->timer); ++ /* the documentation for KeCancelTimer suggests the DPC is ++ * deqeued, but actually DPC is left to run */ ++ if (ret) ++ TIMEREXIT(return TRUE); ++ else ++ TIMEREXIT(return FALSE); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeReadStateTimer,1) ++ (struct nt_timer *nt_timer) ++{ ++ if (nt_timer->dh.signal_state) ++ return TRUE; ++ else ++ return FALSE; ++} ++ ++wstdcall void WIN_FUNC(KeInitializeDpc,3) ++ (struct kdpc *kdpc, void *func, void *ctx) ++{ ++ ENTER3("%p, %p, %p", kdpc, func, ctx); ++ memset(kdpc, 0, sizeof(*kdpc)); ++ kdpc->func = func; ++ kdpc->ctx = ctx; ++ InitializeListHead(&kdpc->list); ++} ++ ++static void kdpc_worker(struct work_struct *dummy) ++{ ++ struct nt_list *entry; ++ struct kdpc *kdpc; ++ unsigned long flags; ++ KIRQL irql; ++ ++ WORKENTER(""); ++ irql = raise_irql(DISPATCH_LEVEL); ++ while (1) { ++ spin_lock_irqsave(&kdpc_list_lock, flags); ++ entry = RemoveHeadList(&kdpc_list); ++ if (entry) { ++ kdpc = container_of(entry, struct kdpc, list); ++ assert(kdpc->queued); ++ kdpc->queued = 0; ++ } else ++ kdpc = NULL; ++ spin_unlock_irqrestore(&kdpc_list_lock, flags); ++ if (!kdpc) ++ break; ++ WORKTRACE("%p, %p, %p, %p, %p", kdpc, kdpc->func, kdpc->ctx, ++ kdpc->arg1, kdpc->arg2); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ LIN2WIN4(kdpc->func, kdpc, kdpc->ctx, kdpc->arg1, kdpc->arg2); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ } ++ lower_irql(irql); ++ WORKEXIT(return); ++} ++ ++wstdcall void WIN_FUNC(KeFlushQueuedDpcs,0) ++ (void) ++{ ++ kdpc_worker(NULL); ++} ++ ++BOOLEAN queue_kdpc(struct kdpc *kdpc) ++{ ++ BOOLEAN ret; ++ unsigned long flags; ++ ++ WORKENTER("%p", kdpc); ++ spin_lock_irqsave(&kdpc_list_lock, flags); ++ if (kdpc->queued) ++ ret = FALSE; ++ else { ++ if (unlikely(kdpc->importance == HighImportance)) ++ InsertHeadList(&kdpc_list, &kdpc->list); ++ else ++ InsertTailList(&kdpc_list, &kdpc->list); ++ kdpc->queued = 1; ++ ret = TRUE; ++ } ++ spin_unlock_irqrestore(&kdpc_list_lock, flags); ++ if (ret == TRUE) ++ queue_work(ntos_wq, &kdpc_work); ++ WORKTRACE("%d", ret); ++ return ret; ++} ++ ++BOOLEAN dequeue_kdpc(struct kdpc *kdpc) ++{ ++ BOOLEAN ret; ++ unsigned long flags; ++ ++ WORKENTER("%p", kdpc); ++ spin_lock_irqsave(&kdpc_list_lock, flags); ++ if (kdpc->queued) { ++ RemoveEntryList(&kdpc->list); ++ kdpc->queued = 0; ++ ret = TRUE; ++ } else ++ ret = FALSE; ++ spin_unlock_irqrestore(&kdpc_list_lock, flags); ++ WORKTRACE("%d", ret); ++ return ret; ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeInsertQueueDpc,3) ++ (struct kdpc *kdpc, void *arg1, void *arg2) ++{ ++ WORKENTER("%p, %p, %p", kdpc, arg1, arg2); ++ kdpc->arg1 = arg1; ++ kdpc->arg2 = arg2; ++ return queue_kdpc(kdpc); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeRemoveQueueDpc,1) ++ (struct kdpc *kdpc) ++{ ++ return dequeue_kdpc(kdpc); ++} ++ ++wstdcall void WIN_FUNC(KeSetImportanceDpc,2) ++ (struct kdpc *kdpc, enum kdpc_importance importance) ++{ ++ kdpc->importance = importance; ++} ++ ++static void ntos_work_worker(struct work_struct *dummy) ++{ ++ struct ntos_work_item *ntos_work_item; ++ struct nt_list *cur; ++ ++ while (1) { ++ spin_lock_bh(&ntos_work_lock); ++ cur = RemoveHeadList(&ntos_work_list); ++ spin_unlock_bh(&ntos_work_lock); ++ if (!cur) ++ break; ++ ntos_work_item = container_of(cur, struct ntos_work_item, list); ++ WORKTRACE("%p: executing %p, %p, %p", current, ++ ntos_work_item->func, ntos_work_item->arg1, ++ ntos_work_item->arg2); ++ LIN2WIN2(ntos_work_item->func, ntos_work_item->arg1, ++ ntos_work_item->arg2); ++ kfree(ntos_work_item); ++ } ++ WORKEXIT(return); ++} ++ ++int schedule_ntos_work_item(NTOS_WORK_FUNC func, void *arg1, void *arg2) ++{ ++ struct ntos_work_item *ntos_work_item; ++ ++ WORKENTER("adding work: %p, %p, %p", func, arg1, arg2); ++ ntos_work_item = kmalloc(sizeof(*ntos_work_item), irql_gfp()); ++ if (!ntos_work_item) { ++ ERROR("couldn't allocate memory"); ++ return -ENOMEM; ++ } ++ ntos_work_item->func = func; ++ ntos_work_item->arg1 = arg1; ++ ntos_work_item->arg2 = arg2; ++ spin_lock_bh(&ntos_work_lock); ++ InsertTailList(&ntos_work_list, &ntos_work_item->list); ++ spin_unlock_bh(&ntos_work_lock); ++ queue_work(ntos_wq, &ntos_work); ++ WORKEXIT(return 0); ++} ++ ++wstdcall void WIN_FUNC(KeInitializeSpinLock,1) ++ (NT_SPIN_LOCK *lock) ++{ ++ ENTER6("%p", lock); ++ nt_spin_lock_init(lock); ++} ++ ++wstdcall void WIN_FUNC(KeAcquireSpinLock,2) ++ (NT_SPIN_LOCK *lock, KIRQL *irql) ++{ ++ ENTER6("%p", lock); ++ *irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); ++} ++ ++wstdcall void WIN_FUNC(KeReleaseSpinLock,2) ++ (NT_SPIN_LOCK *lock, KIRQL oldirql) ++{ ++ ENTER6("%p", lock); ++ nt_spin_unlock_irql(lock, oldirql); ++} ++ ++wstdcall void WIN_FUNC(KeAcquireSpinLockAtDpcLevel,1) ++ (NT_SPIN_LOCK *lock) ++{ ++ ENTER6("%p", lock); ++ nt_spin_lock(lock); ++} ++ ++wstdcall void WIN_FUNC(KeReleaseSpinLockFromDpcLevel,1) ++ (NT_SPIN_LOCK *lock) ++{ ++ ENTER6("%p", lock); ++ nt_spin_unlock(lock); ++} ++ ++wstdcall void WIN_FUNC(KeRaiseIrql,2) ++ (KIRQL newirql, KIRQL *oldirql) ++{ ++ ENTER6("%d", newirql); ++ *oldirql = raise_irql(newirql); ++} ++ ++wstdcall KIRQL WIN_FUNC(KeRaiseIrqlToDpcLevel,0) ++ (void) ++{ ++ return raise_irql(DISPATCH_LEVEL); ++} ++ ++wstdcall void WIN_FUNC(KeLowerIrql,1) ++ (KIRQL irql) ++{ ++ ENTER6("%d", irql); ++ lower_irql(irql); ++} ++ ++wstdcall KIRQL WIN_FUNC(KeAcquireSpinLockRaiseToDpc,1) ++ (NT_SPIN_LOCK *lock) ++{ ++ ENTER6("%p", lock); ++ return nt_spin_lock_irql(lock, DISPATCH_LEVEL); ++} ++ ++wstdcall void *WIN_FUNC(ExAllocatePoolWithTag,3) ++ (enum pool_type pool_type, SIZE_T size, ULONG tag) ++{ ++ void *addr; ++ ++ ENTER4("pool_type: %d, size: %zu, tag: 0x%x", pool_type, size, tag); ++ assert_irql(_irql_ <= DISPATCH_LEVEL); ++ if (size < PAGE_SIZE) ++ addr = kmalloc(size, irql_gfp()); ++ else { ++ if (irql_gfp() & GFP_ATOMIC) { ++ addr = __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, ++ PAGE_KERNEL); ++ TRACE1("%p, %zu", addr, size); ++ } else { ++ addr = vmalloc(size); ++ TRACE1("%p, %zu", addr, size); ++ } ++ } ++ DBG_BLOCK(1) { ++ if (addr) ++ TRACE4("addr: %p, %zu", addr, size); ++ else ++ TRACE1("failed: %zu", size); ++ } ++ return addr; ++} ++WIN_FUNC_DECL(ExAllocatePoolWithTag,3) ++ ++wstdcall void WIN_FUNC(ExFreePoolWithTag,2) ++ (void *addr, ULONG tag) ++{ ++ TRACE4("%p", addr); ++ if ((unsigned long)addr < VMALLOC_START || ++ (unsigned long)addr >= VMALLOC_END) ++ kfree(addr); ++ else ++ vfree(addr); ++ ++ EXIT4(return); ++} ++ ++wstdcall void WIN_FUNC(ExFreePool,1) ++ (void *addr) ++{ ++ ExFreePoolWithTag(addr, 0); ++} ++WIN_FUNC_DECL(ExFreePool,1) ++ ++wstdcall void WIN_FUNC(ExInitializeNPagedLookasideList,7) ++ (struct npaged_lookaside_list *lookaside, ++ LOOKASIDE_ALLOC_FUNC *alloc_func, LOOKASIDE_FREE_FUNC *free_func, ++ ULONG flags, SIZE_T size, ULONG tag, USHORT depth) ++{ ++ ENTER3("lookaside: %p, size: %zu, flags: %u, head: %p, " ++ "alloc: %p, free: %p", lookaside, size, flags, ++ lookaside, alloc_func, free_func); ++ ++ memset(lookaside, 0, sizeof(*lookaside)); ++ ++ lookaside->size = size; ++ lookaside->tag = tag; ++ lookaside->depth = 4; ++ lookaside->maxdepth = 256; ++ lookaside->pool_type = NonPagedPool; ++ ++ if (alloc_func) ++ lookaside->alloc_func = alloc_func; ++ else ++ lookaside->alloc_func = WIN_FUNC_PTR(ExAllocatePoolWithTag,3); ++ if (free_func) ++ lookaside->free_func = free_func; ++ else ++ lookaside->free_func = WIN_FUNC_PTR(ExFreePool,1); ++ ++#ifndef CONFIG_X86_64 ++ nt_spin_lock_init(&lookaside->obsolete); ++#endif ++ EXIT3(return); ++} ++ ++wstdcall void WIN_FUNC(ExDeleteNPagedLookasideList,1) ++ (struct npaged_lookaside_list *lookaside) ++{ ++ struct nt_slist *entry; ++ ++ ENTER3("lookaside = %p", lookaside); ++ while ((entry = ExpInterlockedPopEntrySList(&lookaside->head))) ++ LIN2WIN1(lookaside->free_func, entry); ++ EXIT3(return); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ExCreateCallback,4) ++ (struct callback_object **object, struct object_attributes *attributes, ++ BOOLEAN create, BOOLEAN allow_multiple_callbacks) ++{ ++ struct callback_object *obj; ++ ++ ENTER2(""); ++ spin_lock_bh(&ntoskernel_lock); ++ nt_list_for_each_entry(obj, &callback_objects, callback_funcs) { ++ if (obj->attributes == attributes) { ++ spin_unlock_bh(&ntoskernel_lock); ++ *object = obj; ++ return STATUS_SUCCESS; ++ } ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ obj = allocate_object(sizeof(struct callback_object), ++ OBJECT_TYPE_CALLBACK, NULL); ++ if (!obj) ++ EXIT2(return STATUS_INSUFFICIENT_RESOURCES); ++ InitializeListHead(&obj->callback_funcs); ++ nt_spin_lock_init(&obj->lock); ++ obj->allow_multiple_callbacks = allow_multiple_callbacks; ++ obj->attributes = attributes; ++ *object = obj; ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++wstdcall void *WIN_FUNC(ExRegisterCallback,3) ++ (struct callback_object *object, PCALLBACK_FUNCTION func, void *context) ++{ ++ struct callback_func *callback; ++ KIRQL irql; ++ ++ ENTER2(""); ++ irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); ++ if (object->allow_multiple_callbacks == FALSE && ++ !IsListEmpty(&object->callback_funcs)) { ++ nt_spin_unlock_irql(&object->lock, irql); ++ EXIT2(return NULL); ++ } ++ nt_spin_unlock_irql(&object->lock, irql); ++ callback = kmalloc(sizeof(*callback), GFP_KERNEL); ++ if (!callback) { ++ ERROR("couldn't allocate memory"); ++ return NULL; ++ } ++ callback->func = func; ++ callback->context = context; ++ callback->object = object; ++ irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); ++ InsertTailList(&object->callback_funcs, &callback->list); ++ nt_spin_unlock_irql(&object->lock, irql); ++ EXIT2(return callback); ++} ++ ++wstdcall void WIN_FUNC(ExUnregisterCallback,1) ++ (struct callback_func *callback) ++{ ++ struct callback_object *object; ++ KIRQL irql; ++ ++ ENTER3("%p", callback); ++ if (!callback) ++ return; ++ object = callback->object; ++ irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); ++ RemoveEntryList(&callback->list); ++ nt_spin_unlock_irql(&object->lock, irql); ++ kfree(callback); ++ return; ++} ++ ++wstdcall void WIN_FUNC(ExNotifyCallback,3) ++ (struct callback_object *object, void *arg1, void *arg2) ++{ ++ struct callback_func *callback; ++ KIRQL irql; ++ ++ ENTER3("%p", object); ++ irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); ++ nt_list_for_each_entry(callback, &object->callback_funcs, list) { ++ LIN2WIN3(callback->func, callback->context, arg1, arg2); ++ } ++ nt_spin_unlock_irql(&object->lock, irql); ++ return; ++} ++ ++/* check and set signaled state; should be called with dispatcher_lock held */ ++/* @grab indicates if the event should be grabbed or checked ++ * - note that a semaphore may stay in signaled state for multiple ++ * 'grabs' if the count is > 1 */ ++static int grab_object(struct dispatcher_header *dh, ++ struct task_struct *thread, int grab) ++{ ++ EVENTTRACE("%p, %p, %d, %d", dh, thread, grab, dh->signal_state); ++ if (unlikely(is_mutex_object(dh))) { ++ struct nt_mutex *nt_mutex; ++ nt_mutex = container_of(dh, struct nt_mutex, dh); ++ EVENTTRACE("%p, %p, %d, %p, %d", nt_mutex, ++ nt_mutex->owner_thread, dh->signal_state, ++ thread, grab); ++ /* either no thread owns the mutex or this thread owns ++ * it */ ++ assert(dh->signal_state == 1 && nt_mutex->owner_thread == NULL); ++ assert(dh->signal_state < 1 && nt_mutex->owner_thread != NULL); ++ if ((dh->signal_state == 1 && nt_mutex->owner_thread == NULL) || ++ nt_mutex->owner_thread == thread) { ++ if (grab) { ++ dh->signal_state--; ++ nt_mutex->owner_thread = thread; ++ } ++ EVENTEXIT(return 1); ++ } ++ } else if (dh->signal_state > 0) { ++ /* to grab, decrement signal_state for synchronization ++ * or semaphore objects */ ++ if (grab && (is_synch_object(dh) || is_semaphore_object(dh))) ++ dh->signal_state--; ++ EVENTEXIT(return 1); ++ } ++ EVENTEXIT(return 0); ++} ++ ++/* this function should be called holding dispatcher_lock */ ++static void object_signaled(struct dispatcher_header *dh) ++{ ++ struct nt_list *cur, *next; ++ struct wait_block *wb; ++ ++ EVENTENTER("%p", dh); ++ nt_list_for_each_safe(cur, next, &dh->wait_blocks) { ++ wb = container_of(cur, struct wait_block, list); ++ assert(wb->thread != NULL); ++ assert(wb->object == NULL); ++ if (!grab_object(dh, wb->thread, 1)) ++ continue; ++ EVENTTRACE("%p (%p): waking %p", dh, wb, wb->thread); ++ RemoveEntryList(cur); ++ wb->object = dh; ++ *(wb->wait_done) = 1; ++ wake_up_process(wb->thread); ++ } ++ EVENTEXIT(return); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(KeWaitForMultipleObjects,8) ++ (ULONG count, void *object[], enum wait_type wait_type, ++ KWAIT_REASON wait_reason, KPROCESSOR_MODE wait_mode, ++ BOOLEAN alertable, LARGE_INTEGER *timeout, ++ struct wait_block *wait_block_array) ++{ ++ int i, res = 0, wait_count, wait_done; ++ typeof(jiffies) wait_hz = 0; ++ struct wait_block *wb, wb_array[THREAD_WAIT_OBJECTS]; ++ struct dispatcher_header *dh; ++ KIRQL irql = current_irql(); ++ ++ EVENTENTER("%p, %d, %u, %p", current, count, wait_type, timeout); ++ ++ if (count > MAX_WAIT_OBJECTS || ++ (count > THREAD_WAIT_OBJECTS && wait_block_array == NULL)) ++ EVENTEXIT(return STATUS_INVALID_PARAMETER); ++ ++ if (wait_block_array == NULL) ++ wb = wb_array; ++ else ++ wb = wait_block_array; ++ ++ /* If *timeout == 0: In the case of WaitAny, if an object can ++ * be grabbed (object is in signaled state), grab and ++ * return. In the case of WaitAll, we have to first make sure ++ * all objects can be grabbed. If any/some of them can't be ++ * grabbed, either we return STATUS_TIMEOUT or wait for them, ++ * depending on how to satisfy wait. If all of them can be ++ * grabbed, we will grab them in the next loop below */ ++ ++ spin_lock_bh(&dispatcher_lock); ++ for (i = wait_count = 0; i < count; i++) { ++ dh = object[i]; ++ EVENTTRACE("%p: event %p (%d)", current, dh, dh->signal_state); ++ /* wait_type == 1 for WaitAny, 0 for WaitAll */ ++ if (grab_object(dh, current, wait_type)) { ++ if (wait_type == WaitAny) { ++ spin_unlock_bh(&dispatcher_lock); ++ EVENTEXIT(return STATUS_WAIT_0 + i); ++ } ++ } else { ++ EVENTTRACE("%p: wait for %p", current, dh); ++ wait_count++; ++ } ++ } ++ ++ if (timeout && *timeout == 0 && wait_count) { ++ spin_unlock_bh(&dispatcher_lock); ++ EVENTEXIT(return STATUS_TIMEOUT); ++ } ++ ++ /* get the list of objects the thread needs to wait on and add ++ * the thread on the wait list for each such object */ ++ /* if *timeout == 0, this step will grab all the objects */ ++ wait_done = 0; ++ for (i = 0; i < count; i++) { ++ dh = object[i]; ++ EVENTTRACE("%p: event %p (%d)", current, dh, dh->signal_state); ++ wb[i].object = NULL; ++ if (grab_object(dh, current, 1)) { ++ EVENTTRACE("%p: no wait for %p (%d)", ++ current, dh, dh->signal_state); ++ /* mark that we are not waiting on this object */ ++ wb[i].thread = NULL; ++ } else { ++ wb[i].wait_done = &wait_done; ++ wb[i].thread = current; ++ EVENTTRACE("%p: wait for %p", current, dh); ++ InsertTailList(&dh->wait_blocks, &wb[i].list); ++ } ++ } ++ spin_unlock_bh(&dispatcher_lock); ++ if (wait_count == 0) ++ EVENTEXIT(return STATUS_SUCCESS); ++ ++ assert(timeout == NULL || *timeout != 0); ++ if (timeout == NULL) ++ wait_hz = 0; ++ else ++ wait_hz = SYSTEM_TIME_TO_HZ(*timeout); ++ ++ if (irql >= DISPATCH_LEVEL) { ++ WARNING("attempt to wait with irql %d", irql); ++ EVENTEXIT(return STATUS_INVALID_PARAMETER); ++ } ++ EVENTTRACE("%p: sleep for %ld on %p", current, wait_hz, &wait_done); ++ /* we don't honor 'alertable' - according to description for ++ * this, even if waiting in non-alertable state, thread may be ++ * alerted in some circumstances */ ++ while (wait_count) { ++ res = wait_condition(wait_done, wait_hz, TASK_INTERRUPTIBLE); ++ spin_lock_bh(&dispatcher_lock); ++ EVENTTRACE("%p woke up: %d, %d", current, res, wait_done); ++ /* the event may have been set by the time ++ * wrap_wait_event returned and spinlock obtained, so ++ * don't rely on value of 'res' - check event status */ ++ if (!wait_done) { ++ assert(res <= 0); ++ /* timed out or interrupted; remove from wait list */ ++ for (i = 0; i < count; i++) { ++ if (!wb[i].thread) ++ continue; ++ EVENTTRACE("%p: timedout, dequeue %p (%p)", ++ current, object[i], wb[i].object); ++ assert(wb[i].object == NULL); ++ RemoveEntryList(&wb[i].list); ++ } ++ spin_unlock_bh(&dispatcher_lock); ++ if (res < 0) ++ EVENTEXIT(return STATUS_ALERTED); ++ else ++ EVENTEXIT(return STATUS_TIMEOUT); ++ } ++ assert(res > 0); ++ /* woken because object(s) signaled */ ++ for (i = 0; wait_count && i < count; i++) { ++ if (!wb[i].thread || !wb[i].object) ++ continue; ++ DBG_BLOCK(1) { ++ if (wb[i].object != object[i]) { ++ EVENTTRACE("oops %p != %p", ++ wb[i].object, object[i]); ++ continue; ++ } ++ } ++ wait_count--; ++ if (wait_type == WaitAny) { ++ int j; ++ /* done; remove from rest of wait list */ ++ for (j = i + 1; j < count; j++) { ++ if (wb[j].thread && !wb[j].object) ++ RemoveEntryList(&wb[j].list); ++ } ++ spin_unlock_bh(&dispatcher_lock); ++ EVENTEXIT(return STATUS_WAIT_0 + i); ++ } ++ } ++ wait_done = 0; ++ spin_unlock_bh(&dispatcher_lock); ++ if (wait_count == 0) ++ EVENTEXIT(return STATUS_SUCCESS); ++ ++ /* this thread is still waiting for more objects, so ++ * let it wait for remaining time and those objects */ ++ if (timeout) ++ wait_hz = res; ++ else ++ wait_hz = 0; ++ } ++ /* should never reach here, but compiler wants return value */ ++ ERROR("%p: wait_hz: %ld", current, wait_hz); ++ EVENTEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(KeWaitForSingleObject,5) ++ (void *object, KWAIT_REASON wait_reason, KPROCESSOR_MODE wait_mode, ++ BOOLEAN alertable, LARGE_INTEGER *timeout) ++{ ++ return KeWaitForMultipleObjects(1, &object, WaitAny, wait_reason, ++ wait_mode, alertable, timeout, NULL); ++} ++ ++wstdcall void WIN_FUNC(KeInitializeEvent,3) ++ (struct nt_event *nt_event, enum event_type type, BOOLEAN state) ++{ ++ EVENTENTER("event = %p, type = %d, state = %d", nt_event, type, state); ++ initialize_object(&nt_event->dh, (enum dh_type)type, state); ++ EVENTEXIT(return); ++} ++ ++wstdcall LONG WIN_FUNC(KeSetEvent,3) ++ (struct nt_event *nt_event, KPRIORITY incr, BOOLEAN wait) ++{ ++ LONG old_state; ++ ++ EVENTENTER("%p, %d", nt_event, nt_event->dh.type); ++ if (wait == TRUE) ++ WARNING("wait = %d, not yet implemented", wait); ++ spin_lock_bh(&dispatcher_lock); ++ old_state = nt_event->dh.signal_state; ++ nt_event->dh.signal_state = 1; ++ if (old_state == 0) ++ object_signaled(&nt_event->dh); ++ spin_unlock_bh(&dispatcher_lock); ++ EVENTEXIT(return old_state); ++} ++ ++wstdcall void WIN_FUNC(KeClearEvent,1) ++ (struct nt_event *nt_event) ++{ ++ EVENTENTER("%p", nt_event); ++ nt_event->dh.signal_state = 0; ++ EVENTEXIT(return); ++} ++ ++wstdcall LONG WIN_FUNC(KeResetEvent,1) ++ (struct nt_event *nt_event) ++{ ++ LONG old_state; ++ ++ EVENTENTER("%p", nt_event); ++ old_state = xchg(&nt_event->dh.signal_state, 0); ++ EVENTEXIT(return old_state); ++} ++ ++wstdcall LONG WIN_FUNC(KeReadStateEvent,1) ++ (struct nt_event *nt_event) ++{ ++ LONG state; ++ ++ state = nt_event->dh.signal_state; ++ EVENTTRACE("%d", state); ++ return state; ++} ++ ++wstdcall void WIN_FUNC(KeInitializeMutex,2) ++ (struct nt_mutex *mutex, ULONG level) ++{ ++ EVENTENTER("%p", mutex); ++ initialize_object(&mutex->dh, MutexObject, 1); ++ mutex->dh.size = sizeof(*mutex); ++ InitializeListHead(&mutex->list); ++ mutex->abandoned = FALSE; ++ mutex->apc_disable = 1; ++ mutex->owner_thread = NULL; ++ EVENTEXIT(return); ++} ++ ++wstdcall LONG WIN_FUNC(KeReleaseMutex,2) ++ (struct nt_mutex *mutex, BOOLEAN wait) ++{ ++ LONG ret; ++ struct task_struct *thread; ++ ++ EVENTENTER("%p, %d, %p", mutex, wait, current); ++ if (wait == TRUE) ++ WARNING("wait: %d", wait); ++ thread = current; ++ spin_lock_bh(&dispatcher_lock); ++ EVENTTRACE("%p, %p, %p, %d", mutex, thread, mutex->owner_thread, ++ mutex->dh.signal_state); ++ if ((mutex->owner_thread == thread) && (mutex->dh.signal_state <= 0)) { ++ ret = mutex->dh.signal_state++; ++ if (ret == 0) { ++ mutex->owner_thread = NULL; ++ object_signaled(&mutex->dh); ++ } ++ } else { ++ ret = STATUS_MUTANT_NOT_OWNED; ++ WARNING("invalid mutex: %p, %p, %p", mutex, mutex->owner_thread, ++ thread); ++ } ++ EVENTTRACE("%p, %p, %p, %d", mutex, thread, mutex->owner_thread, ++ mutex->dh.signal_state); ++ spin_unlock_bh(&dispatcher_lock); ++ EVENTEXIT(return ret); ++} ++ ++wstdcall void WIN_FUNC(KeInitializeSemaphore,3) ++ (struct nt_semaphore *semaphore, LONG count, LONG limit) ++{ ++ EVENTENTER("%p: %d", semaphore, count); ++ /* if limit > 1, we need to satisfy as many waits (until count ++ * becomes 0); so we keep decrementing count every time a wait ++ * is satisfied */ ++ initialize_object(&semaphore->dh, SemaphoreObject, count); ++ semaphore->dh.size = sizeof(*semaphore); ++ semaphore->limit = limit; ++ EVENTEXIT(return); ++} ++ ++wstdcall LONG WIN_FUNC(KeReleaseSemaphore,4) ++ (struct nt_semaphore *semaphore, KPRIORITY incr, LONG adjustment, ++ BOOLEAN wait) ++{ ++ LONG ret; ++ ++ EVENTENTER("%p", semaphore); ++ spin_lock_bh(&dispatcher_lock); ++ ret = semaphore->dh.signal_state; ++ assert(ret >= 0); ++ if (semaphore->dh.signal_state + adjustment <= semaphore->limit) ++ semaphore->dh.signal_state += adjustment; ++ else { ++ WARNING("releasing %d over limit %d", adjustment, ++ semaphore->limit); ++ semaphore->dh.signal_state = semaphore->limit; ++ } ++ if (semaphore->dh.signal_state > 0) ++ object_signaled(&semaphore->dh); ++ spin_unlock_bh(&dispatcher_lock); ++ EVENTEXIT(return ret); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(KeDelayExecutionThread,3) ++ (KPROCESSOR_MODE wait_mode, BOOLEAN alertable, LARGE_INTEGER *interval) ++{ ++ int res; ++ long timeout; ++ ++ if (wait_mode != 0) ++ ERROR("invalid wait_mode %d", wait_mode); ++ ++ timeout = SYSTEM_TIME_TO_HZ(*interval); ++ EVENTTRACE("%p, %lld, %ld", current, *interval, timeout); ++ if (timeout <= 0) ++ EVENTEXIT(return STATUS_SUCCESS); ++ ++ if (alertable) ++ set_current_state(TASK_INTERRUPTIBLE); ++ else ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ ++ res = schedule_timeout(timeout); ++ EVENTTRACE("%p, %d", current, res); ++ if (res == 0) ++ EVENTEXIT(return STATUS_SUCCESS); ++ else ++ EVENTEXIT(return STATUS_ALERTED); ++} ++ ++wstdcall ULONGLONG WIN_FUNC(KeQueryInterruptTime,0) ++ (void) ++{ ++ EXIT5(return jiffies * TICKSPERJIFFY); ++} ++ ++wstdcall ULONG WIN_FUNC(KeQueryTimeIncrement,0) ++ (void) ++{ ++ EXIT5(return TICKSPERSEC / HZ); ++} ++ ++wstdcall void WIN_FUNC(KeQuerySystemTime,1) ++ (LARGE_INTEGER *time) ++{ ++ *time = ticks_1601(); ++ TRACE5("%llu, %lu", *time, jiffies); ++} ++ ++wstdcall void WIN_FUNC(KeQueryTickCount,1) ++ (LARGE_INTEGER *count) ++{ ++ *count = jiffies; ++} ++ ++wstdcall LARGE_INTEGER WIN_FUNC(KeQueryPerformanceCounter,1) ++ (LARGE_INTEGER *counter) ++{ ++ if (counter) ++ *counter = HZ; ++ return jiffies; ++} ++ ++wstdcall KAFFINITY WIN_FUNC(KeQueryActiveProcessors,0) ++ (void) ++{ ++ int i, n; ++ KAFFINITY bits = 0; ++ n = num_online_cpus(); ++ for (i = 0; i < n; i++) ++ bits = (bits << 1) | 1; ++ return bits; ++} ++ ++struct nt_thread *get_current_nt_thread(void) ++{ ++ struct task_struct *task = current; ++ struct nt_thread *thread; ++ struct common_object_header *header; ++ ++ TRACE6("task: %p", task); ++ thread = NULL; ++ spin_lock_bh(&ntoskernel_lock); ++ nt_list_for_each_entry(header, &object_list, list) { ++ TRACE6("%p, %d", header, header->type); ++ if (header->type != OBJECT_TYPE_NT_THREAD) ++ break; ++ thread = HEADER_TO_OBJECT(header); ++ TRACE6("%p, %p", thread, thread->task); ++ if (thread->task == task) ++ break; ++ else ++ thread = NULL; ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ if (thread == NULL) ++ TRACE4("couldn't find thread for task %p, %d", task, task->pid); ++ TRACE6("%p", thread); ++ return thread; ++} ++ ++static struct task_struct *get_nt_thread_task(struct nt_thread *thread) ++{ ++ struct task_struct *task; ++ struct common_object_header *header; ++ ++ TRACE6("%p", thread); ++ task = NULL; ++ spin_lock_bh(&ntoskernel_lock); ++ nt_list_for_each_entry(header, &object_list, list) { ++ TRACE6("%p, %d", header, header->type); ++ if (header->type != OBJECT_TYPE_NT_THREAD) ++ break; ++ if (thread == HEADER_TO_OBJECT(header)) { ++ task = thread->task; ++ break; ++ } ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ if (task == NULL) ++ TRACE2("%p: couldn't find task for %p", current, thread); ++ return task; ++} ++ ++static struct nt_thread *create_nt_thread(struct task_struct *task) ++{ ++ struct nt_thread *thread; ++ thread = allocate_object(sizeof(*thread), OBJECT_TYPE_NT_THREAD, NULL); ++ if (!thread) { ++ ERROR("couldn't allocate thread object"); ++ EXIT2(return NULL); ++ } ++ thread->task = task; ++ if (task) ++ thread->pid = task->pid; ++ else ++ thread->pid = 0; ++ nt_spin_lock_init(&thread->lock); ++ InitializeListHead(&thread->irps); ++ initialize_object(&thread->dh, ThreadObject, 0); ++ thread->dh.size = sizeof(*thread); ++ thread->prio = LOW_PRIORITY; ++ return thread; ++} ++ ++wstdcall struct nt_thread *WIN_FUNC(KeGetCurrentThread,0) ++ (void) ++{ ++ struct nt_thread *thread = get_current_nt_thread(); ++ TRACE2("%p, %p", thread, current); ++ return thread; ++} ++ ++wstdcall KPRIORITY WIN_FUNC(KeQueryPriorityThread,1) ++ (struct nt_thread *thread) ++{ ++ KPRIORITY prio; ++ struct task_struct *task; ++ ++ TRACE2("%p", thread); ++#ifdef CONFIG_X86_64 ++ /* sis163u driver for amd64 passes 0x1f from thread created by ++ * PsCreateSystemThread - no idea what is 0x1f */ ++ if (thread == (void *)0x1f) ++ thread = get_current_nt_thread(); ++#endif ++ if (!thread) { ++ TRACE2("invalid thread"); ++ EXIT2(return LOW_REALTIME_PRIORITY); ++ } ++ task = get_nt_thread_task(thread); ++ if (!task) { ++ TRACE2("couldn't find task for thread: %p", thread); ++ EXIT2(return LOW_REALTIME_PRIORITY); ++ } ++ ++ prio = thread->prio; ++ ++ TRACE2("%d", prio); ++ return prio; ++} ++ ++wstdcall KPRIORITY WIN_FUNC(KeSetPriorityThread,2) ++ (struct nt_thread *thread, KPRIORITY prio) ++{ ++ KPRIORITY old_prio; ++ struct task_struct *task; ++ ++ TRACE2("thread: %p, priority = %u", thread, prio); ++#ifdef CONFIG_X86_64 ++ if (thread == (void *)0x1f) ++ thread = get_current_nt_thread(); ++#endif ++ if (!thread) { ++ TRACE2("invalid thread"); ++ EXIT2(return LOW_REALTIME_PRIORITY); ++ } ++ task = get_nt_thread_task(thread); ++ if (!task) { ++ TRACE2("couldn't find task for thread: %p", thread); ++ EXIT2(return LOW_REALTIME_PRIORITY); ++ } ++ ++ old_prio = thread->prio; ++ thread->prio = prio; ++ ++ TRACE2("%d, %d", old_prio, thread->prio); ++ return old_prio; ++} ++ ++struct thread_trampoline { ++ void (*func)(void *) wstdcall; ++ void *ctx; ++ struct nt_thread *thread; ++ struct completion started; ++}; ++ ++static int ntdriver_thread(void *data) ++{ ++ struct thread_trampoline *thread_tramp = data; ++ /* yes, a tramp! */ ++ typeof(thread_tramp->func) func = thread_tramp->func; ++ typeof(thread_tramp->ctx) ctx = thread_tramp->ctx; ++ ++ thread_tramp->thread->task = current; ++ thread_tramp->thread->pid = current->pid; ++ TRACE2("thread: %p, task: %p (%d)", thread_tramp->thread, ++ current, current->pid); ++ complete(&thread_tramp->started); ++ ++#ifdef PF_NOFREEZE ++ current->flags |= PF_NOFREEZE; ++#endif ++ strncpy(current->comm, "ntdriver", sizeof(current->comm)); ++ current->comm[sizeof(current->comm)-1] = 0; ++ LIN2WIN1(func, ctx); ++ ERROR("task: %p", current); ++ return 0; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(PsCreateSystemThread,7) ++ (void **handle, ULONG access, void *obj_attr, void *process, ++ void *client_id, void (*func)(void *) wstdcall, void *ctx) ++{ ++ struct thread_trampoline thread_tramp; ++ ++ ENTER2("handle = %p, access = %u, obj_attr = %p, process = %p, " ++ "client_id = %p, func = %p, context = %p", handle, access, ++ obj_attr, process, client_id, func, ctx); ++ ++ thread_tramp.thread = create_nt_thread(NULL); ++ if (!thread_tramp.thread) { ++ ERROR("couldn't allocate thread object"); ++ EXIT2(return STATUS_RESOURCES); ++ } ++ TRACE2("thread: %p", thread_tramp.thread); ++ thread_tramp.func = func; ++ thread_tramp.ctx = ctx; ++ init_completion(&thread_tramp.started); ++ ++ thread_tramp.thread->task = kthread_run(ntdriver_thread, ++ &thread_tramp, "ntdriver"); ++ if (IS_ERR(thread_tramp.thread->task)) { ++ free_object(thread_tramp.thread); ++ EXIT2(return STATUS_FAILURE); ++ } ++ TRACE2("created task: %p", thread_tramp.thread->task); ++ ++ wait_for_completion(&thread_tramp.started); ++ *handle = OBJECT_TO_HEADER(thread_tramp.thread); ++ TRACE2("created thread: %p, %p", thread_tramp.thread, *handle); ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(PsTerminateSystemThread,1) ++ (NTSTATUS status) ++{ ++ struct nt_thread *thread; ++ ++ TRACE2("%p, %08X", current, status); ++ thread = get_current_nt_thread(); ++ TRACE2("%p", thread); ++ if (thread) { ++ KeSetEvent((struct nt_event *)&thread->dh, 0, FALSE); ++ while (1) { ++ struct nt_list *ent; ++ struct irp *irp; ++ KIRQL irql; ++ irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL); ++ ent = RemoveHeadList(&thread->irps); ++ nt_spin_unlock_irql(&thread->lock, irql); ++ if (!ent) ++ break; ++ irp = container_of(ent, struct irp, thread_list); ++ IOTRACE("%p", irp); ++ IoCancelIrp(irp); ++ } ++ /* the driver may later query this status with ++ * ZwQueryInformationThread */ ++ thread->status = status; ++ } else ++ ERROR("couldn't find thread for task: %p", current); ++ ++ complete_and_exit(NULL, status); ++ ERROR("oops: %p, %d", thread->task, thread->pid); ++ return STATUS_FAILURE; ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeRemoveEntryDeviceQueue,2) ++ (struct kdevice_queue *dev_queue, struct kdevice_queue_entry *entry) ++{ ++ struct kdevice_queue_entry *e; ++ KIRQL irql; ++ ++ irql = nt_spin_lock_irql(&dev_queue->lock, DISPATCH_LEVEL); ++ nt_list_for_each_entry(e, &dev_queue->list, list) { ++ if (e == entry) { ++ RemoveEntryList(&e->list); ++ nt_spin_unlock_irql(&dev_queue->lock, irql); ++ return TRUE; ++ } ++ } ++ nt_spin_unlock_irql(&dev_queue->lock, irql); ++ return FALSE; ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeSynchronizeExecution,3) ++ (struct kinterrupt *interrupt, PKSYNCHRONIZE_ROUTINE synch_routine, ++ void *ctx) ++{ ++ BOOLEAN ret; ++ unsigned long flags; ++ ++ nt_spin_lock_irqsave(interrupt->actual_lock, flags); ++ ret = LIN2WIN1(synch_routine, ctx); ++ nt_spin_unlock_irqrestore(interrupt->actual_lock, flags); ++ TRACE6("%d", ret); ++ return ret; ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeRegisterBugCheckReasonCallback,4) ++ (void *callback_record, void *callback_routine, UINT reason, ++ char *component) ++{ ++ TRACE1("callback_record: %p, callback_routine: %p, reason: %d, " ++ "component: %s", callback_record, callback_routine, reason, ++ component); ++ TODO(); ++ return FALSE; ++} ++ ++wstdcall BOOLEAN WIN_FUNC(KeDeregisterBugCheckReasonCallback,1) ++ (void *callback_record) ++{ ++ TRACE1("callback_record: %p", callback_record); ++ TODO(); ++ return TRUE; ++} ++ ++wstdcall void *WIN_FUNC(MmAllocateContiguousMemorySpecifyCache,5) ++ (SIZE_T size, PHYSICAL_ADDRESS lowest, PHYSICAL_ADDRESS highest, ++ PHYSICAL_ADDRESS boundary, enum memory_caching_type cache_type) ++{ ++ void *addr; ++ gfp_t flags; ++ ++ ENTER2("%zu, 0x%llx, 0x%llx, 0x%llx, %d", size, lowest, ++ highest, boundary, cache_type); ++ flags = irql_gfp(); ++ addr = wrap_get_free_pages(flags, size); ++ TRACE2("%p, %zu, 0x%x", addr, size, flags); ++ if (addr && ((virt_to_phys(addr) + size) <= highest)) ++ EXIT2(return addr); ++#ifdef CONFIG_X86_64 ++ /* GFP_DMA is really only 16MB even on x86-64, but there is no ++ * other zone available */ ++ if (highest <= DMA_BIT_MASK(31)) ++ flags |= __GFP_DMA; ++ else if (highest <= DMA_BIT_MASK(32)) ++ flags |= __GFP_DMA32; ++#else ++ if (highest <= DMA_BIT_MASK(24)) ++ flags |= __GFP_DMA; ++ else if (highest > DMA_BIT_MASK(30)) ++ flags |= __GFP_HIGHMEM; ++#endif ++ if (addr) ++ free_pages((unsigned long)addr, get_order(size)); ++ addr = wrap_get_free_pages(flags, size); ++ TRACE2("%p, %zu, 0x%x", addr, size, flags); ++ return addr; ++} ++ ++wstdcall void WIN_FUNC(MmFreeContiguousMemorySpecifyCache,3) ++ (void *base, SIZE_T size, enum memory_caching_type cache_type) ++{ ++ TRACE2("%p, %zu", base, size); ++ free_pages((unsigned long)base, get_order(size)); ++} ++ ++wstdcall PHYSICAL_ADDRESS WIN_FUNC(MmGetPhysicalAddress,1) ++ (void *base) ++{ ++ unsigned long phy = virt_to_phys(base); ++ TRACE2("%p, %p", base, (void *)phy); ++ return phy; ++} ++ ++/* Atheros card with pciid 168C:0014 calls this function with 0xf0000 ++ * and 0xf6ef0 address, and then check for things that seem to be ++ * related to ACPI: "_SM_" and "_DMI_". This may be the hack they do ++ * to check if this card is installed in IBM thinkpads; we can ++ * probably get this device to work if we create a buffer with the ++ * strings as required by the driver and return virtual address for ++ * that address instead */ ++wstdcall void __iomem *WIN_FUNC(MmMapIoSpace,3) ++ (PHYSICAL_ADDRESS phys_addr, SIZE_T size, ++ enum memory_caching_type cache) ++{ ++ void __iomem *virt; ++ ENTER1("cache type: %d", cache); ++ if (cache == MmCached) ++ virt = ioremap(phys_addr, size); ++ else ++ virt = ioremap_nocache(phys_addr, size); ++ TRACE1("%llx, %zu, %p", phys_addr, size, virt); ++ return virt; ++} ++ ++wstdcall void WIN_FUNC(MmUnmapIoSpace,2) ++ (void __iomem *addr, SIZE_T size) ++{ ++ ENTER1("%p, %zu", addr, size); ++ iounmap(addr); ++ return; ++} ++ ++wstdcall ULONG WIN_FUNC(MmSizeOfMdl,2) ++ (void *base, ULONG length) ++{ ++ return sizeof(struct mdl) + ++ (sizeof(PFN_NUMBER) * SPAN_PAGES(base, length)); ++} ++ ++struct mdl *allocate_init_mdl(void *virt, ULONG length) ++{ ++ struct wrap_mdl *wrap_mdl; ++ struct mdl *mdl; ++ int mdl_size = MmSizeOfMdl(virt, length); ++ ++ if (mdl_size <= MDL_CACHE_SIZE) { ++ wrap_mdl = kmem_cache_alloc(mdl_cache, irql_gfp()); ++ if (!wrap_mdl) ++ return NULL; ++ spin_lock_bh(&dispatcher_lock); ++ InsertHeadList(&wrap_mdl_list, &wrap_mdl->list); ++ spin_unlock_bh(&dispatcher_lock); ++ mdl = wrap_mdl->mdl; ++ TRACE3("allocated mdl from cache: %p(%p), %p(%d)", ++ wrap_mdl, mdl, virt, length); ++ memset(mdl, 0, MDL_CACHE_SIZE); ++ MmInitializeMdl(mdl, virt, length); ++ /* mark the MDL as allocated from cache pool so when ++ * it is freed, we free it back to the pool */ ++ mdl->flags = MDL_ALLOCATED_FIXED_SIZE | MDL_CACHE_ALLOCATED; ++ } else { ++ wrap_mdl = ++ kmalloc(sizeof(*wrap_mdl) + mdl_size, irql_gfp()); ++ if (!wrap_mdl) ++ return NULL; ++ mdl = wrap_mdl->mdl; ++ TRACE3("allocated mdl from memory: %p(%p), %p(%d)", ++ wrap_mdl, mdl, virt, length); ++ spin_lock_bh(&dispatcher_lock); ++ InsertHeadList(&wrap_mdl_list, &wrap_mdl->list); ++ spin_unlock_bh(&dispatcher_lock); ++ memset(mdl, 0, mdl_size); ++ MmInitializeMdl(mdl, virt, length); ++ mdl->flags = MDL_ALLOCATED_FIXED_SIZE; ++ } ++ return mdl; ++} ++ ++void free_mdl(struct mdl *mdl) ++{ ++ /* A driver may allocate Mdl with NdisAllocateBuffer and free ++ * with IoFreeMdl (e.g., 64-bit Broadcom). Since we need to ++ * treat buffers allocated with Ndis calls differently, we ++ * must call NdisFreeBuffer if it is allocated with Ndis ++ * function. We set 'pool' field in Ndis functions. */ ++ if (!mdl) ++ return; ++ if (mdl->pool) ++ NdisFreeBuffer(mdl); ++ else { ++ struct wrap_mdl *wrap_mdl = (struct wrap_mdl *) ++ ((char *)mdl - offsetof(struct wrap_mdl, mdl)); ++ spin_lock_bh(&dispatcher_lock); ++ RemoveEntryList(&wrap_mdl->list); ++ spin_unlock_bh(&dispatcher_lock); ++ ++ if (mdl->flags & MDL_CACHE_ALLOCATED) { ++ TRACE3("freeing mdl cache: %p, %p, %p", ++ wrap_mdl, mdl, mdl->mappedsystemva); ++ kmem_cache_free(mdl_cache, wrap_mdl); ++ } else { ++ TRACE3("freeing mdl: %p, %p, %p", ++ wrap_mdl, mdl, mdl->mappedsystemva); ++ kfree(wrap_mdl); ++ } ++ } ++ return; ++} ++ ++wstdcall void WIN_FUNC(IoBuildPartialMdl,4) ++ (struct mdl *source, struct mdl *target, void *virt, ULONG length) ++{ ++ MmInitializeMdl(target, virt, length); ++ target->flags |= MDL_PARTIAL; ++} ++ ++wstdcall void WIN_FUNC(MmBuildMdlForNonPagedPool,1) ++ (struct mdl *mdl) ++{ ++ PFN_NUMBER *mdl_pages; ++ int i, n; ++ ++ ENTER4("%p", mdl); ++ /* already mapped */ ++// mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl); ++ mdl->flags |= MDL_SOURCE_IS_NONPAGED_POOL; ++ TRACE4("%p, %p, %p, %d, %d", mdl, mdl->mappedsystemva, mdl->startva, ++ mdl->byteoffset, mdl->bytecount); ++ n = SPAN_PAGES(MmGetSystemAddressForMdl(mdl), MmGetMdlByteCount(mdl)); ++ if (n > MDL_CACHE_PAGES) ++ WARNING("%p, %d, %d", MmGetSystemAddressForMdl(mdl), ++ MmGetMdlByteCount(mdl), n); ++ mdl_pages = MmGetMdlPfnArray(mdl); ++ for (i = 0; i < n; i++) ++ mdl_pages[i] = (ULONG_PTR)mdl->startva + (i * PAGE_SIZE); ++ EXIT4(return); ++} ++ ++wstdcall void *WIN_FUNC(MmMapLockedPages,2) ++ (struct mdl *mdl, KPROCESSOR_MODE access_mode) ++{ ++ /* already mapped */ ++// mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl); ++ mdl->flags |= MDL_MAPPED_TO_SYSTEM_VA; ++ /* what is the need for MDL_PARTIAL_HAS_BEEN_MAPPED? */ ++ if (mdl->flags & MDL_PARTIAL) ++ mdl->flags |= MDL_PARTIAL_HAS_BEEN_MAPPED; ++ return mdl->mappedsystemva; ++} ++ ++wstdcall void *WIN_FUNC(MmMapLockedPagesSpecifyCache,6) ++ (struct mdl *mdl, KPROCESSOR_MODE access_mode, ++ enum memory_caching_type cache_type, void *base_address, ++ ULONG bug_check, enum mm_page_priority priority) ++{ ++ return MmMapLockedPages(mdl, access_mode); ++} ++ ++wstdcall void WIN_FUNC(MmUnmapLockedPages,2) ++ (void *base, struct mdl *mdl) ++{ ++ mdl->flags &= ~MDL_MAPPED_TO_SYSTEM_VA; ++ return; ++} ++ ++wstdcall void WIN_FUNC(MmProbeAndLockPages,3) ++ (struct mdl *mdl, KPROCESSOR_MODE access_mode, ++ enum lock_operation operation) ++{ ++ /* already locked */ ++ mdl->flags |= MDL_PAGES_LOCKED; ++ return; ++} ++ ++wstdcall void WIN_FUNC(MmUnlockPages,1) ++ (struct mdl *mdl) ++{ ++ mdl->flags &= ~MDL_PAGES_LOCKED; ++ return; ++} ++ ++wstdcall BOOLEAN WIN_FUNC(MmIsAddressValid,1) ++ (void *virt_addr) ++{ ++ if (virt_addr_valid(virt_addr)) ++ return TRUE; ++ else ++ return FALSE; ++} ++ ++wstdcall void *WIN_FUNC(MmLockPagableDataSection,1) ++ (void *address) ++{ ++ return address; ++} ++ ++wstdcall void WIN_FUNC(MmUnlockPagableImageSection,1) ++ (void *handle) ++{ ++ return; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ObReferenceObjectByHandle,6) ++ (void *handle, ACCESS_MASK desired_access, void *obj_type, ++ KPROCESSOR_MODE access_mode, void **object, void *handle_info) ++{ ++ struct common_object_header *hdr; ++ ++ TRACE2("%p", handle); ++ hdr = HANDLE_TO_HEADER(handle); ++ atomic_inc_var(hdr->ref_count); ++ *object = HEADER_TO_OBJECT(hdr); ++ TRACE2("%p, %p, %d, %p", hdr, object, hdr->ref_count, *object); ++ return STATUS_SUCCESS; ++} ++ ++/* DDK doesn't say if return value should be before incrementing or ++ * after incrementing reference count, but according to #reactos ++ * developers, it should be return value after incrementing */ ++wfastcall LONG WIN_FUNC(ObfReferenceObject,1) ++ (void *object) ++{ ++ struct common_object_header *hdr; ++ LONG ret; ++ ++ hdr = OBJECT_TO_HEADER(object); ++ ret = post_atomic_add(hdr->ref_count, 1); ++ TRACE2("%p, %d, %p", hdr, hdr->ref_count, object); ++ return ret; ++} ++ ++static int dereference_object(void *object) ++{ ++ struct common_object_header *hdr; ++ int ref_count; ++ ++ ENTER2("object: %p", object); ++ hdr = OBJECT_TO_HEADER(object); ++ TRACE2("hdr: %p", hdr); ++ ref_count = post_atomic_add(hdr->ref_count, -1); ++ TRACE2("object: %p, %d", object, ref_count); ++ if (ref_count < 0) ++ ERROR("invalid object: %p (%d)", object, ref_count); ++ if (ref_count <= 0) { ++ free_object(object); ++ return 1; ++ } else ++ return 0; ++} ++ ++wfastcall void WIN_FUNC(ObfDereferenceObject,1) ++ (void *object) ++{ ++ TRACE2("%p", object); ++ dereference_object(object); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwCreateFile,11) ++ (void **handle, ACCESS_MASK access_mask, ++ struct object_attributes *obj_attr, struct io_status_block *iosb, ++ LARGE_INTEGER *size, ULONG file_attr, ULONG share_access, ++ ULONG create_disposition, ULONG create_options, void *ea_buffer, ++ ULONG ea_length) ++{ ++ struct common_object_header *coh; ++ struct file_object *fo; ++ struct ansi_string ansi; ++ struct wrap_bin_file *bin_file; ++ char *file_basename; ++ NTSTATUS status; ++ ++ spin_lock_bh(&ntoskernel_lock); ++ nt_list_for_each_entry(coh, &object_list, list) { ++ if (coh->type != OBJECT_TYPE_FILE) ++ continue; ++ /* TODO: check if file is opened in shared mode */ ++ if (!RtlCompareUnicodeString(&coh->name, obj_attr->name, TRUE)) { ++ fo = HEADER_TO_OBJECT(coh); ++ bin_file = fo->wrap_bin_file; ++ *handle = coh; ++ spin_unlock_bh(&ntoskernel_lock); ++ ObReferenceObject(fo); ++ iosb->status = FILE_OPENED; ++ iosb->info = bin_file->size; ++ EXIT2(return STATUS_SUCCESS); ++ } ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ ++ if (RtlUnicodeStringToAnsiString(&ansi, obj_attr->name, TRUE) != ++ STATUS_SUCCESS) ++ EXIT2(return STATUS_INSUFFICIENT_RESOURCES); ++ ++ file_basename = strrchr(ansi.buf, '\\'); ++ if (file_basename) ++ file_basename++; ++ else ++ file_basename = ansi.buf; ++ TRACE2("file: '%s', '%s'", ansi.buf, file_basename); ++ ++ fo = allocate_object(sizeof(struct file_object), OBJECT_TYPE_FILE, ++ obj_attr->name); ++ if (!fo) { ++ RtlFreeAnsiString(&ansi); ++ iosb->status = STATUS_INSUFFICIENT_RESOURCES; ++ iosb->info = 0; ++ EXIT2(return STATUS_FAILURE); ++ } ++ coh = OBJECT_TO_HEADER(fo); ++ bin_file = get_bin_file(file_basename); ++ if (bin_file) { ++ TRACE2("%s, %s", bin_file->name, file_basename); ++ fo->flags = FILE_OPENED; ++ } else if (access_mask & FILE_WRITE_DATA) { ++ bin_file = kzalloc(sizeof(*bin_file), GFP_KERNEL); ++ if (bin_file) { ++ strncpy(bin_file->name, file_basename, ++ sizeof(bin_file->name)); ++ bin_file->name[sizeof(bin_file->name)-1] = 0; ++ bin_file->data = vmalloc(*size); ++ if (bin_file->data) { ++ memset(bin_file->data, 0, *size); ++ bin_file->size = *size; ++ fo->flags = FILE_CREATED; ++ } else { ++ kfree(bin_file); ++ bin_file = NULL; ++ } ++ } ++ } else ++ bin_file = NULL; ++ ++ RtlFreeAnsiString(&ansi); ++ if (!bin_file) { ++ iosb->status = FILE_DOES_NOT_EXIST; ++ iosb->info = 0; ++ free_object(fo); ++ EXIT2(return STATUS_FAILURE); ++ } ++ ++ fo->wrap_bin_file = bin_file; ++ fo->current_byte_offset = 0; ++ if (access_mask & FILE_READ_DATA) ++ fo->read_access = TRUE; ++ if (access_mask & FILE_WRITE_DATA) ++ fo->write_access = TRUE; ++ iosb->status = FILE_OPENED; ++ iosb->info = bin_file->size; ++ *handle = coh; ++ TRACE2("handle: %p", *handle); ++ status = STATUS_SUCCESS; ++ EXIT2(return status); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwOpenFile,6) ++ (void **handle, ACCESS_MASK access_mask, ++ struct object_attributes *obj_attr, struct io_status_block *iosb, ++ ULONG share_access, ULONG open_options) ++{ ++ LARGE_INTEGER size; ++ return ZwCreateFile(handle, access_mask, obj_attr, iosb, &size, 0, ++ share_access, 0, open_options, NULL, 0); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwReadFile,9) ++ (void *handle, struct nt_event *event, void *apc_routine, ++ void *apc_context, struct io_status_block *iosb, void *buffer, ++ ULONG length, LARGE_INTEGER *byte_offset, ULONG *key) ++{ ++ struct file_object *fo; ++ struct common_object_header *coh; ++ ULONG count; ++ size_t offset; ++ struct wrap_bin_file *file; ++ ++ TRACE2("%p", handle); ++ coh = handle; ++ if (coh->type != OBJECT_TYPE_FILE) { ++ ERROR("handle %p is invalid: %d", handle, coh->type); ++ EXIT2(return STATUS_FAILURE); ++ } ++ fo = HANDLE_TO_OBJECT(coh); ++ file = fo->wrap_bin_file; ++ TRACE2("file: %s (%zu)", file->name, file->size); ++ spin_lock_bh(&ntoskernel_lock); ++ if (byte_offset) ++ offset = *byte_offset; ++ else ++ offset = fo->current_byte_offset; ++ count = min((size_t)length, file->size - offset); ++ TRACE2("count: %u, offset: %zu, length: %u", count, offset, length); ++ memcpy(buffer, ((void *)file->data) + offset, count); ++ fo->current_byte_offset = offset + count; ++ spin_unlock_bh(&ntoskernel_lock); ++ iosb->status = STATUS_SUCCESS; ++ iosb->info = count; ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwWriteFile,9) ++ (void *handle, struct nt_event *event, void *apc_routine, ++ void *apc_context, struct io_status_block *iosb, void *buffer, ++ ULONG length, LARGE_INTEGER *byte_offset, ULONG *key) ++{ ++ struct file_object *fo; ++ struct common_object_header *coh; ++ struct wrap_bin_file *file; ++ unsigned long offset; ++ ++ TRACE2("%p", handle); ++ coh = handle; ++ if (coh->type != OBJECT_TYPE_FILE) { ++ ERROR("handle %p is invalid: %d", handle, coh->type); ++ EXIT2(return STATUS_FAILURE); ++ } ++ fo = HANDLE_TO_OBJECT(coh); ++ file = fo->wrap_bin_file; ++ TRACE2("file: %zu, %u", file->size, length); ++ spin_lock_bh(&ntoskernel_lock); ++ if (byte_offset) ++ offset = *byte_offset; ++ else ++ offset = fo->current_byte_offset; ++ if (length + offset > file->size) { ++ WARNING("%lu, %zu", length + offset, file->size); ++ /* TODO: implement writing past end of current size */ ++ iosb->status = STATUS_FAILURE; ++ iosb->info = 0; ++ } else { ++ memcpy(file->data + offset, buffer, length); ++ iosb->status = STATUS_SUCCESS; ++ iosb->info = length; ++ fo->current_byte_offset = offset + length; ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ EXIT2(return iosb->status); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwClose,1) ++ (void *handle) ++{ ++ struct common_object_header *coh; ++ ++ TRACE2("%p", handle); ++ if (handle == NULL) { ++ TRACE1(""); ++ EXIT2(return STATUS_SUCCESS); ++ } ++ coh = handle; ++ if (coh->type == OBJECT_TYPE_FILE) { ++ struct file_object *fo; ++ struct wrap_bin_file *bin_file; ++ typeof(fo->flags) flags; ++ ++ fo = HANDLE_TO_OBJECT(handle); ++ flags = fo->flags; ++ bin_file = fo->wrap_bin_file; ++ if (dereference_object(fo)) { ++ if (flags == FILE_CREATED) { ++ vfree(bin_file->data); ++ kfree(bin_file); ++ } else ++ free_bin_file(bin_file); ++ } ++ } else if (coh->type == OBJECT_TYPE_NT_THREAD) { ++ struct nt_thread *thread = HANDLE_TO_OBJECT(handle); ++ TRACE2("thread: %p (%p)", thread, handle); ++ ObDereferenceObject(thread); ++ } else { ++ /* TODO: can we just dereference object here? */ ++ WARNING("closing handle 0x%x not implemented", coh->type); ++ } ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwQueryInformationFile,5) ++ (void *handle, struct io_status_block *iosb, void *info, ++ ULONG length, enum file_info_class class) ++{ ++ struct file_object *fo; ++ struct file_name_info *fni; ++ struct file_std_info *fsi; ++ struct wrap_bin_file *file; ++ struct common_object_header *coh; ++ ++ ENTER2("%p", handle); ++ coh = handle; ++ if (coh->type != OBJECT_TYPE_FILE) { ++ ERROR("handle %p is invalid: %d", coh, coh->type); ++ EXIT2(return STATUS_FAILURE); ++ } ++ fo = HANDLE_TO_OBJECT(handle); ++ TRACE2("fo: %p, %d", fo, class); ++ switch (class) { ++ case FileNameInformation: ++ fni = info; ++ fni->length = min(length, (typeof(length))coh->name.length); ++ memcpy(fni->name, coh->name.buf, fni->length); ++ iosb->status = STATUS_SUCCESS; ++ iosb->info = fni->length; ++ break; ++ case FileStandardInformation: ++ fsi = info; ++ file = fo->wrap_bin_file; ++ fsi->alloc_size = file->size; ++ fsi->eof = file->size; ++ fsi->num_links = 1; ++ fsi->delete_pending = FALSE; ++ fsi->dir = FALSE; ++ iosb->status = STATUS_SUCCESS; ++ iosb->info = 0; ++ break; ++ default: ++ WARNING("type %d not implemented yet", class); ++ iosb->status = STATUS_FAILURE; ++ iosb->info = 0; ++ break; ++ } ++ EXIT2(return iosb->status); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwOpenSection,3) ++ (void **handle, ACCESS_MASK access, struct object_attributes *obj_attrs) ++{ ++ INFO("%p, 0x%x, %d", obj_attrs, obj_attrs->attributes, access); ++ TODO(); ++ *handle = obj_attrs; ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwMapViewOfSection,10) ++ (void *secn_handle, void *process_handle, void **base_address, ++ ULONG zero_bits, SIZE_T commit_size, LARGE_INTEGER *secn_offset, ++ SIZE_T *view_size, enum section_inherit inherit, ULONG alloc_type, ++ ULONG protect) ++{ ++ INFO("%p, %p, %p", secn_handle, process_handle, base_address); ++ TODO(); ++ *base_address = (void *)0xdeadbeef; ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwUnmapViewOfSection,2) ++ (void *process_handle, void *base_address) ++{ ++ INFO("%p, %p", process_handle, base_address); ++ TODO(); ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwCreateKey,7) ++ (void **handle, ACCESS_MASK desired_access, ++ struct object_attributes *attr, ULONG title_index, ++ struct unicode_string *class, ULONG create_options, ++ ULONG *disposition) ++{ ++ struct ansi_string ansi; ++ if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) == ++ STATUS_SUCCESS) { ++ TRACE1("key: %s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ *handle = NULL; ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwOpenKey,3) ++ (void **handle, ACCESS_MASK desired_access, ++ struct object_attributes *attr) ++{ ++ struct ansi_string ansi; ++ if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) == ++ STATUS_SUCCESS) { ++ TRACE1("key: %s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ *handle = NULL; ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwSetValueKey,6) ++ (void *handle, struct unicode_string *name, ULONG title_index, ++ ULONG type, void *data, ULONG data_size) ++{ ++ struct ansi_string ansi; ++ if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == ++ STATUS_SUCCESS) { ++ TRACE1("key: %s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwQueryValueKey,6) ++ (void *handle, struct unicode_string *name, ++ enum key_value_information_class class, void *info, ++ ULONG length, ULONG *res_length) ++{ ++ struct ansi_string ansi; ++ if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == STATUS_SUCCESS) { ++ TRACE1("key: %s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ TODO(); ++ return STATUS_INVALID_PARAMETER; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwDeleteKey,1) ++ (void *handle) ++{ ++ ENTER2("%p", handle); ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(ZwPowerInformation,5) ++ (INT info_level, void *in_buf, ULONG in_buf_len, void *out_buf, ++ ULONG out_buf_len) ++{ ++ INFO("%d, %u, %u", info_level, in_buf_len, out_buf_len); ++ TODO(); ++ return STATUS_ACCESS_DENIED; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(WmiSystemControl,4) ++ (struct wmilib_context *info, struct device_object *dev_obj, ++ struct irp *irp, void *irp_disposition) ++{ ++ TODO(); ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(WmiCompleteRequest,5) ++ (struct device_object *dev_obj, struct irp *irp, NTSTATUS status, ++ ULONG buffer_used, CCHAR priority_boost) ++{ ++ TODO(); ++ return STATUS_SUCCESS; ++} ++ ++noregparm NTSTATUS WIN_FUNC(WmiTraceMessage,12) ++ (void *tracehandle, ULONG message_flags, ++ void *message_guid, USHORT message_no, ...) ++{ ++ TODO(); ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(WmiQueryTraceInformation,4) ++ (enum trace_information_class trace_info_class, void *trace_info, ++ ULONG *req_length, void *buf) ++{ ++ TODO(); ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++/* this function can't be wstdcall as it takes variable number of args */ ++__attribute__((format(printf, 1, 2))) ++noregparm ULONG WIN_FUNC(DbgPrint,12) ++ (char *format, ...) ++{ ++#if DEBUG >= 1 ++ va_list args; ++ static char buf[100]; ++ ++ va_start(args, format); ++ vsnprintf(buf, sizeof(buf), format, args); ++ printk(KERN_DEBUG "%s (%s): %s", DRIVER_NAME, __func__, buf); ++ va_end(args); ++#endif ++ return STATUS_SUCCESS; ++} ++ ++__attribute__((format(printf, 3, 4))) ++noregparm ULONG WIN_FUNC(DbgPrintEx,12) ++ (ULONG component_id, ULONG severity, char *format, ...) ++{ ++#if DEBUG >= 1 ++ va_list args; ++ static char buf[100]; ++ ++ va_start(args, format); ++ vsnprintf(buf, sizeof(buf), format, args); ++ TRACE1("component_id: %d, severity: %d\n", component_id, severity); ++ printk(KERN_DEBUG "%s (%s): %s", DRIVER_NAME, __func__, buf); ++ va_end(args); ++#endif ++ return STATUS_SUCCESS; ++} ++ ++wstdcall void WIN_FUNC(KeBugCheck,1) ++ (ULONG code) ++{ ++ ERROR("Unrecoverable error reported by the driver"); ++ ERROR("code: 0x%x\n", code); ++ dump_stack(); ++ return; ++} ++ ++wstdcall void WIN_FUNC(KeBugCheckEx,5) ++ (ULONG code, ULONG_PTR param1, ULONG_PTR param2, ++ ULONG_PTR param3, ULONG_PTR param4) ++{ ++ ERROR("Unrecoverable error reported by the driver"); ++ ERROR("code: 0x%x, params: 0x%lx 0x%lx 0x%lx 0x%lx\n", code, param1, ++ param2, param3, param4); ++ dump_stack(); ++ return; ++} ++ ++wstdcall void WIN_FUNC(ExSystemTimeToLocalTime,2) ++ (LARGE_INTEGER *system_time, LARGE_INTEGER *local_time) ++{ ++ *local_time = *system_time; ++} ++ ++wstdcall ULONG WIN_FUNC(ExSetTimerResolution,2) ++ (ULONG time, BOOLEAN set) ++{ ++ /* why a driver should change system wide timer resolution is ++ * beyond me */ ++ return time; ++} ++ ++wstdcall void WIN_FUNC(DbgBreakPoint,0) ++ (void) ++{ ++ TODO(); ++} ++ ++wstdcall void WIN_FUNC(_except_handler3,0) ++ (void) ++{ ++ TODO(); ++} ++ ++wstdcall void WIN_FUNC(__C_specific_handler,0) ++ (void) ++{ ++ TODO(); ++} ++ ++wstdcall void WIN_FUNC(_purecall,0) ++ (void) ++{ ++ TODO(); ++} ++ ++struct worker_init_struct { ++ struct work_struct work; ++ struct completion completion; ++ struct nt_thread *nt_thread; ++}; ++ ++int ntoskernel_init(void) ++{ ++ struct timeval now; ++ ++ spin_lock_init(&dispatcher_lock); ++ spin_lock_init(&ntoskernel_lock); ++ spin_lock_init(&ntos_work_lock); ++ spin_lock_init(&kdpc_list_lock); ++ spin_lock_init(&irp_cancel_lock); ++ InitializeListHead(&wrap_mdl_list); ++ InitializeListHead(&kdpc_list); ++ InitializeListHead(&callback_objects); ++ InitializeListHead(&bus_driver_list); ++ InitializeListHead(&object_list); ++ InitializeListHead(&ntos_work_list); ++ ++ nt_spin_lock_init(&nt_list_lock); ++ ++ INIT_WORK(&kdpc_work, kdpc_worker); ++ INIT_WORK(&ntos_work, ntos_work_worker); ++ wrap_timer_slist.next = NULL; ++ ++ do_gettimeofday(&now); ++ wrap_ticks_to_boot = TICKS_1601_TO_1970; ++ wrap_ticks_to_boot += (u64)now.tv_sec * TICKSPERSEC; ++ wrap_ticks_to_boot += now.tv_usec * 10; ++ wrap_ticks_to_boot -= jiffies * TICKSPERJIFFY; ++ TRACE2("%llu", wrap_ticks_to_boot); ++ ++ cpu_count = num_online_cpus(); ++ ++#ifdef WRAP_PREEMPT ++ do { ++ int cpu; ++ for_each_possible_cpu(cpu) { ++ struct irql_info *info; ++ info = &per_cpu(irql_info, cpu); ++ mutex_init(&(info->lock)); ++ info->task = NULL; ++ info->count = 0; ++#ifdef CONFIG_SMP ++ cpumask_setall(&info->cpus_allowed); ++#endif ++ } ++ } while (0); ++#endif ++ ++ ntos_wq = create_singlethread_workqueue("ntos_wq"); ++ if (!ntos_wq) { ++ WARNING("couldn't create ntos_wq thread"); ++ return -ENOMEM; ++ } ++ TRACE1("ntos_wq: %p", ntos_wq); ++ ++ if (add_bus_driver("PCI") ++#ifdef ENABLE_USB ++ || add_bus_driver("USB") ++#endif ++ ) { ++ ntoskernel_exit(); ++ return -ENOMEM; ++ } ++ mdl_cache = ++ wrap_kmem_cache_create(DRIVER_NAME "_mdl", ++ sizeof(struct wrap_mdl) + MDL_CACHE_SIZE, ++ 0, 0); ++ TRACE2("%p", mdl_cache); ++ if (!mdl_cache) { ++ ERROR("couldn't allocate MDL cache"); ++ ntoskernel_exit(); ++ return -ENOMEM; ++ } ++ ++#if defined(CONFIG_X86_64) ++ memset(&kuser_shared_data, 0, sizeof(kuser_shared_data)); ++ *((ULONG64 *)&kuser_shared_data.system_time) = ticks_1601(); ++ init_timer(&shared_data_timer); ++ shared_data_timer.function = update_user_shared_data_proc; ++ shared_data_timer.data = 0; ++#endif ++ return 0; ++} ++ ++int ntoskernel_init_device(struct wrap_device *wd) ++{ ++#if defined(CONFIG_X86_64) ++ if (kuser_shared_data.reserved1) ++ mod_timer(&shared_data_timer, jiffies + MSEC_TO_HZ(30)); ++#endif ++ return 0; ++} ++ ++void ntoskernel_exit_device(struct wrap_device *wd) ++{ ++ ENTER2(""); ++ ++ KeFlushQueuedDpcs(); ++ EXIT2(return); ++} ++ ++void ntoskernel_exit(void) ++{ ++ struct nt_list *cur; ++ ++ ENTER2(""); ++ ++ /* free kernel (Ke) timers */ ++ TRACE2("freeing timers"); ++ while (1) { ++ struct wrap_timer *wrap_timer; ++ struct nt_slist *slist; ++ ++ spin_lock_bh(&ntoskernel_lock); ++ if ((slist = wrap_timer_slist.next)) ++ wrap_timer_slist.next = slist->next; ++ spin_unlock_bh(&ntoskernel_lock); ++ TIMERTRACE("%p", slist); ++ if (!slist) ++ break; ++ wrap_timer = container_of(slist, struct wrap_timer, slist); ++ if (del_timer_sync(&wrap_timer->timer)) ++ WARNING("Buggy Windows driver left timer %p running", ++ wrap_timer->nt_timer); ++ memset(wrap_timer, 0, sizeof(*wrap_timer)); ++ slack_kfree(wrap_timer); ++ } ++ ++ TRACE2("freeing MDLs"); ++ if (mdl_cache) { ++ spin_lock_bh(&ntoskernel_lock); ++ if (!IsListEmpty(&wrap_mdl_list)) ++ ERROR("Windows driver didn't free all MDLs; " ++ "freeing them now"); ++ while ((cur = RemoveHeadList(&wrap_mdl_list))) { ++ struct wrap_mdl *wrap_mdl; ++ wrap_mdl = container_of(cur, struct wrap_mdl, list); ++ if (wrap_mdl->mdl->flags & MDL_CACHE_ALLOCATED) ++ kmem_cache_free(mdl_cache, wrap_mdl); ++ else ++ kfree(wrap_mdl); ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ kmem_cache_destroy(mdl_cache); ++ mdl_cache = NULL; ++ } ++ ++ TRACE2("freeing callbacks"); ++ spin_lock_bh(&ntoskernel_lock); ++ while ((cur = RemoveHeadList(&callback_objects))) { ++ struct callback_object *object; ++ struct nt_list *ent; ++ object = container_of(cur, struct callback_object, list); ++ while ((ent = RemoveHeadList(&object->callback_funcs))) { ++ struct callback_func *f; ++ f = container_of(ent, struct callback_func, list); ++ kfree(f); ++ } ++ kfree(object); ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ ++ spin_lock_bh(&ntoskernel_lock); ++ while ((cur = RemoveHeadList(&bus_driver_list))) { ++ struct bus_driver *bus_driver; ++ bus_driver = container_of(cur, struct bus_driver, list); ++ /* TODO: make sure all all drivers are shutdown/removed */ ++ kfree(bus_driver); ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ ++#if defined(CONFIG_X86_64) ++ del_timer_sync(&shared_data_timer); ++#endif ++ if (ntos_wq) ++ destroy_workqueue(ntos_wq); ++ ENTER2("freeing objects"); ++ spin_lock_bh(&ntoskernel_lock); ++ while ((cur = RemoveHeadList(&object_list))) { ++ struct common_object_header *hdr; ++ hdr = container_of(cur, struct common_object_header, list); ++ if (hdr->type == OBJECT_TYPE_NT_THREAD) ++ TRACE1("object %p(%d) was not freed, freeing it now", ++ HEADER_TO_OBJECT(hdr), hdr->type); ++ else ++ WARNING("object %p(%d) was not freed, freeing it now", ++ HEADER_TO_OBJECT(hdr), hdr->type); ++ ExFreePool(hdr); ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ ++ EXIT2(return); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/ntoskernel.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ntoskernel.h +--- linux-3.12.2/3rdparty/ndiswrapper/ntoskernel.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ntoskernel.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,1083 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _NTOSKERNEL_H_ ++#define _NTOSKERNEL_H_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if !defined(CONFIG_X86) && !defined(CONFIG_X86_64) ++#error "this module is for x86 or x86_64 architectures only" ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) ++#define gfp_t unsigned int __nocast ++ ++static inline void *_kzalloc(size_t size, gfp_t flags) ++{ ++ void *p = kmalloc(size, flags); ++ if (likely(p != NULL)) ++ memset(p, 0, size); ++ return p; ++} ++ ++#define kzalloc(size, flags) _kzalloc(size, flags) ++#endif ++ ++/* Interrupt backwards compatibility stuff */ ++#include ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) ++#ifndef IRQ_HANDLED ++#define IRQ_HANDLED ++#define IRQ_NONE ++#define irqreturn_t void ++#endif ++#endif /* Linux < 2.6.29 */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) ++#ifndef mutex_init ++#define mutex semaphore ++#define mutex_init(m) sema_init(m, 1) ++#define mutex_lock(m) down(m) ++#define mutex_trylock(m) (!down_trylock(m)) ++#define mutex_unlock(m) up(m) ++#define mutex_is_locked(m) (atomic_read(m.count) == 0) ++#endif ++#endif /* Linux < 2.6.16 */ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) ++#define set_cpus_allowed_ptr(task, mask) set_cpus_allowed(task, *mask) ++#endif /* Linux < 2.6.26 */ ++ ++#ifdef CONFIG_SMP ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) ++#define cpumask_copy(dst, src) do { *dst = *src; } while (0) ++#define cpumask_equal(mask1, mask2) cpus_equal(*mask1, *mask2) ++#define cpumask_setall(mask) cpus_setall(*mask) ++static cpumask_t cpumasks[NR_CPUS]; ++#define cpumask_of(cpu) \ ++({ \ ++ cpumasks[cpu] = cpumask_of_cpu(cpu); \ ++ &cpumasks[cpu]; \ ++}) ++#endif /* Linux < 2.6.28 */ ++#endif /* CONFIG_SMP */ ++ ++#ifndef tsk_cpus_allowed ++#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) ++#endif ++ ++#ifndef __packed ++#define __packed __attribute__((packed)) ++#endif ++ ++/* pci functions in 2.6 kernels have problems allocating dma buffers, ++ * but seem to work fine with dma functions ++ */ ++#include ++ ++#define PCI_DMA_ALLOC_COHERENT(pci_dev,size,dma_handle) \ ++ dma_alloc_coherent(&pci_dev->dev,size,dma_handle, \ ++ GFP_KERNEL | __GFP_REPEAT) ++#define PCI_DMA_FREE_COHERENT(pci_dev,size,cpu_addr,dma_handle) \ ++ dma_free_coherent(&pci_dev->dev,size,cpu_addr,dma_handle) ++#define PCI_DMA_MAP_SINGLE(pci_dev,addr,size,direction) \ ++ dma_map_single(&pci_dev->dev,addr,size,direction) ++#define PCI_DMA_UNMAP_SINGLE(pci_dev,dma_handle,size,direction) \ ++ dma_unmap_single(&pci_dev->dev,dma_handle,size,direction) ++#define MAP_SG(pci_dev, sglist, nents, direction) \ ++ dma_map_sg(&pci_dev->dev, sglist, nents, direction) ++#define UNMAP_SG(pci_dev, sglist, nents, direction) \ ++ dma_unmap_sg(&pci_dev->dev, sglist, nents, direction) ++#define PCI_DMA_MAP_ERROR(dma_addr) dma_mapping_error(dma_addr) ++ ++ ++#if defined(CONFIG_NET_RADIO) && !defined(CONFIG_WIRELESS_EXT) ++#define CONFIG_WIRELESS_EXT ++#endif ++ ++#define prepare_wait_condition(task, var, value) \ ++do { \ ++ var = value; \ ++ task = current; \ ++ barrier(); \ ++} while (0) ++ ++/* Wait in wait_state (e.g., TASK_INTERRUPTIBLE) for condition to ++ * become true; timeout is either jiffies (> 0) to wait or 0 to wait ++ * forever. ++ * When timeout == 0, return value is ++ * > 0 if condition becomes true, or ++ * < 0 if signal is pending on the thread. ++ * When timeout > 0, return value is ++ * > 0 if condition becomes true before timeout, ++ * < 0 if signal is pending on the thread before timeout, or ++ * 0 if timedout (condition may have become true at the same time) ++ */ ++ ++#define wait_condition(condition, timeout, wait_state) \ ++({ \ ++ long ret = timeout ? timeout : 1; \ ++ while (1) { \ ++ if (signal_pending(current)) { \ ++ ret = -ERESTARTSYS; \ ++ break; \ ++ } \ ++ set_current_state(wait_state); \ ++ if (condition) { \ ++ __set_current_state(TASK_RUNNING); \ ++ break; \ ++ } \ ++ if (timeout) { \ ++ ret = schedule_timeout(ret); \ ++ if (!ret) \ ++ break; \ ++ } else \ ++ schedule(); \ ++ } \ ++ ret; \ ++}) ++ ++#ifdef WRAP_WQ ++ ++struct wrap_workqueue_struct; ++ ++struct wrap_work_struct { ++ struct list_head list; ++ void (*func)(struct wrap_work_struct *data); ++ void *data; ++ /* whether/on which thread scheduled */ ++ struct workqueue_thread *thread; ++}; ++ ++#define work_struct wrap_work_struct ++#define workqueue_struct wrap_workqueue_struct ++ ++#undef INIT_WORK ++#define INIT_WORK(work, pfunc) \ ++ do { \ ++ (work)->func = (pfunc); \ ++ (work)->data = (work); \ ++ (work)->thread = NULL; \ ++ } while (0) ++ ++#undef create_singlethread_workqueue ++#define create_singlethread_workqueue(wq) wrap_create_wq(wq, 1, 0) ++#undef create_workqueue ++#define create_workqueue(wq) wrap_create_wq(wq, 0, 0) ++#undef destroy_workqueue ++#define destroy_workqueue(wq) wrap_destroy_wq(wq) ++#undef queue_work ++#define queue_work(wq, work) wrap_queue_work(wq, work) ++#undef flush_workqueue ++#define flush_workqueue(wq) wrap_flush_wq(wq) ++ ++struct workqueue_struct *wrap_create_wq(const char *name, u8 singlethread, ++ u8 freeze); ++void wrap_destroy_wq(struct workqueue_struct *workq); ++int wrap_queue_work(struct workqueue_struct *workq, struct work_struct *work); ++void wrap_cancel_work(struct work_struct *work); ++void wrap_flush_wq(struct workqueue_struct *workq); ++ ++#else // WRAP_WQ ++ ++/* Compatibility for Linux before 2.6.20 where INIT_WORK takes 3 arguments */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) && \ ++ !defined(INIT_WORK_NAR) && \ ++ !defined(INIT_DELAYED_WORK_DEFERRABLE) ++typedef void (*compat_work_func_t)(void *work); ++typedef void (*work_func_t)(struct work_struct *work); ++static inline void (INIT_WORK)(struct work_struct *work, work_func_t func) ++{ ++ INIT_WORK(work, (compat_work_func_t)func, work); ++} ++#undef INIT_WORK ++#endif ++ ++#endif // WRAP_WQ ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) ++#define ISR_PT_REGS_PARAM_DECL ++#else ++#define ISR_PT_REGS_PARAM_DECL , struct pt_regs *regs ++#endif ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16) ++#define for_each_possible_cpu(_cpu) for_each_cpu(_cpu) ++#endif ++ ++#ifndef CHECKSUM_PARTIAL ++#define CHECKSUM_PARTIAL CHECKSUM_HW ++#endif ++ ++#ifndef IRQF_SHARED ++#define IRQF_SHARED SA_SHIRQ ++#endif ++ ++#ifndef UMH_WAIT_PROC ++#define UMH_WAIT_PROC 1 ++#endif ++ ++#define memcpy_skb(skb, from, length) \ ++ memcpy(skb_put(skb, length), from, length) ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ++#ifndef DMA_BIT_MASK ++#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) ++#endif ++#endif ++ ++#ifndef __GFP_DMA32 ++#define __GFP_DMA32 GFP_DMA ++#endif ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22) ++#define wrap_kmem_cache_create(name, size, align, flags) \ ++ kmem_cache_create(name, size, align, flags, NULL, NULL) ++#else ++#define wrap_kmem_cache_create(name, size, align, flags) \ ++ kmem_cache_create(name, size, align, flags, NULL) ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) ++#define netdev_mc_count(dev) ((dev)->mc_count) ++#define usb_alloc_coherent(dev, size, mem_flags, dma) (usb_buffer_alloc((dev), (size), (mem_flags), (dma))) ++#define usb_free_coherent(dev, size, addr, dma) (usb_buffer_free((dev), (size), (addr), (dma))) ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) ++#define daemonize(name, ...) do {} while (0) ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ++#define add_taint(flag, lockdep_ok) add_taint(flag) ++#endif ++ ++#include "winnt_types.h" ++#include "ndiswrapper.h" ++#include "pe_linker.h" ++#include "wrapmem.h" ++#include "lin2win.h" ++#include "loader.h" ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ++static inline void netif_tx_lock(struct net_device *dev) ++{ ++ spin_lock(&dev->xmit_lock); ++} ++static inline void netif_tx_unlock(struct net_device *dev) ++{ ++ spin_unlock(&dev->xmit_lock); ++} ++static inline void netif_tx_lock_bh(struct net_device *dev) ++{ ++ spin_lock_bh(&dev->xmit_lock); ++} ++static inline void netif_tx_unlock_bh(struct net_device *dev) ++{ ++ spin_unlock_bh(&dev->xmit_lock); ++} ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++static inline void netif_poll_enable(struct net_device *dev) ++{ ++} ++static inline void netif_poll_disable(struct net_device *dev) ++{ ++} ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ++#define proc_net_root init_net.proc_net ++#else ++#define proc_net_root proc_net ++#endif ++ ++#if ((LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)) && \ ++ (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))) || \ ++ (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,42)) ++#ifndef skb_frag_page ++#define skb_frag_page(frag) ((frag)->page) ++#endif ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0) ++#define netdev_notifier_info_to_dev(x) ((struct net_device *)(x)) ++#endif ++ ++#ifdef INIT_COMPLETION ++static inline void reinit_completion(struct completion *x) ++{ ++ INIT_COMPLETION(*x); ++} ++#endif ++ ++/* TICK is 100ns */ ++#define TICKSPERSEC 10000000 ++#define TICKSPERMSEC 10000 ++#define SECSPERDAY 86400 ++#define TICKSPERJIFFY ((TICKSPERSEC + HZ - 1) / HZ) ++ ++#define int_div_round(x, y) (((x) + (y - 1)) / (y)) ++ ++/* 1601 to 1970 is 369 years plus 89 leap days */ ++#define SECS_1601_TO_1970 ((369 * 365 + 89) * (u64)SECSPERDAY) ++#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC) ++ ++/* 100ns units to HZ; if sys_time is negative, relative to current ++ * clock, otherwise from year 1601 */ ++#define SYSTEM_TIME_TO_HZ(sys_time) \ ++ (((sys_time) <= 0) ? \ ++ int_div_round(((u64)HZ * (-(sys_time))), TICKSPERSEC) : \ ++ int_div_round(((s64)HZ * ((sys_time) - ticks_1601())), TICKSPERSEC)) ++ ++#define MSEC_TO_HZ(ms) int_div_round((ms * HZ), 1000) ++#define USEC_TO_HZ(us) int_div_round((us * HZ), 1000000) ++ ++extern u64 wrap_ticks_to_boot; ++ ++static inline u64 ticks_1601(void) ++{ ++ return wrap_ticks_to_boot + (u64)jiffies * TICKSPERJIFFY; ++} ++ ++typedef void (*generic_func)(void); ++ ++struct wrap_export { ++ const char *name; ++ generic_func func; ++}; ++ ++#ifdef CONFIG_X86_64 ++ ++#define WIN_SYMBOL(name, argc) \ ++ {#name, (generic_func) win2lin_ ## name ## _ ## argc} ++#define WIN_WIN_SYMBOL(name, argc) \ ++ {#name, (generic_func) win2lin__win_ ## name ## _ ## argc} ++#define WIN_FUNC_DECL(name, argc) \ ++ extern typeof(name) win2lin_ ## name ## _ ## argc; ++#define WIN_FUNC_PTR(name, argc) win2lin_ ## name ## _ ## argc ++ ++#else ++ ++#define WIN_SYMBOL(name, argc) {#name, (generic_func)name} ++#define WIN_WIN_SYMBOL(name, argc) {#name, (generic_func)_win_ ## name} ++#define WIN_FUNC_DECL(name, argc) ++#define WIN_FUNC_PTR(name, argc) name ++ ++#endif ++ ++#define WIN_FUNC(name, argc) (name) ++/* map name s to f - if f is different from s */ ++#define WIN_SYMBOL_MAP(s, f) ++ ++#define POOL_TAG(A, B, C, D) \ ++ ((ULONG)((A) + ((B) << 8) + ((C) << 16) + ((D) << 24))) ++ ++struct pe_image { ++ char name[MAX_DRIVER_NAME_LEN]; ++ UINT (*entry)(struct driver_object *, struct unicode_string *) wstdcall; ++ void *image; ++ int size; ++ int type; ++ ++ IMAGE_NT_HEADERS *nt_hdr; ++ IMAGE_OPTIONAL_HEADER *opt_hdr; ++}; ++ ++struct ndis_mp_block; ++ ++struct wrap_timer { ++ struct nt_slist slist; ++ struct timer_list timer; ++ struct nt_timer *nt_timer; ++ long repeat; ++#ifdef TIMER_DEBUG ++ unsigned long wrap_timer_magic; ++#endif ++}; ++ ++struct ntos_work_item { ++ struct nt_list list; ++ void *arg1; ++ void *arg2; ++ NTOS_WORK_FUNC func; ++}; ++ ++struct wrap_device_setting { ++ struct nt_list list; ++ char name[MAX_SETTING_NAME_LEN]; ++ char value[MAX_SETTING_VALUE_LEN]; ++ void *encoded; ++}; ++ ++struct wrap_bin_file { ++ char name[MAX_DRIVER_NAME_LEN]; ++ size_t size; ++ void *data; ++}; ++ ++#define WRAP_DRIVER_CLIENT_ID 1 ++ ++struct wrap_driver { ++ struct nt_list list; ++ struct driver_object *drv_obj; ++ char name[MAX_DRIVER_NAME_LEN]; ++ char version[MAX_SETTING_VALUE_LEN]; ++ unsigned short num_pe_images; ++ struct pe_image pe_images[MAX_DRIVER_PE_IMAGES]; ++ unsigned short num_bin_files; ++ struct wrap_bin_file *bin_files; ++ struct nt_list settings; ++ int dev_type; ++ struct ndis_driver *ndis_driver; ++}; ++ ++enum hw_status { ++ HW_INITIALIZED = 1, HW_SUSPENDED, HW_HALTED, HW_DISABLED, ++}; ++ ++struct wrap_device { ++ /* first part is (de)initialized once by loader */ ++ struct nt_list list; ++ int dev_bus; ++ int vendor; ++ int device; ++ int subvendor; ++ int subdevice; ++ char conf_file_name[MAX_DRIVER_NAME_LEN]; ++ char driver_name[MAX_DRIVER_NAME_LEN]; ++ struct wrap_driver *driver; ++ struct nt_list settings; ++ ++ /* rest should be (de)initialized when a device is ++ * (un)plugged */ ++ struct cm_resource_list *resource_list; ++ unsigned long hw_status; ++ struct device_object *pdo; ++ union { ++ struct { ++ struct pci_dev *pdev; ++ enum device_power_state wake_state; ++ } pci; ++ struct { ++ struct usb_device *udev; ++ struct usb_interface *intf; ++ int num_alloc_urbs; ++ struct nt_list wrap_urb_list; ++ } usb; ++ }; ++}; ++ ++#define wrap_is_pci_bus(dev_bus) \ ++ (WRAP_BUS(dev_bus) == WRAP_PCI_BUS || \ ++ WRAP_BUS(dev_bus) == WRAP_PCMCIA_BUS) ++#ifdef ENABLE_USB ++/* earlier versions of ndiswrapper used 0 as USB_BUS */ ++#define wrap_is_usb_bus(dev_bus) \ ++ (WRAP_BUS(dev_bus) == WRAP_USB_BUS || \ ++ WRAP_BUS(dev_bus) == WRAP_INTERNAL_BUS) ++#else ++#define wrap_is_usb_bus(dev_bus) 0 ++#endif ++#define wrap_is_bluetooth_device(dev_bus) \ ++ (WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE1 || \ ++ WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE2) ++ ++extern struct workqueue_struct *ntos_wq; ++extern struct workqueue_struct *ndis_wq; ++extern struct workqueue_struct *wrapndis_wq; ++ ++#define atomic_unary_op(var, size, oper) \ ++do { \ ++ if (size == 1) \ ++ __asm__ __volatile__( \ ++ LOCK_PREFIX oper "b %b0\n\t" : "+m" (var)); \ ++ else if (size == 2) \ ++ __asm__ __volatile__( \ ++ LOCK_PREFIX oper "w %w0\n\t" : "+m" (var)); \ ++ else if (size == 4) \ ++ __asm__ __volatile__( \ ++ LOCK_PREFIX oper "l %0\n\t" : "+m" (var)); \ ++ else if (size == 8) \ ++ __asm__ __volatile__( \ ++ LOCK_PREFIX oper "q %q0\n\t" : "+m" (var)); \ ++ else { \ ++ extern void _invalid_op_size_(void); \ ++ _invalid_op_size_(); \ ++ } \ ++} while (0) ++ ++#define atomic_inc_var_size(var, size) atomic_unary_op(var, size, "inc") ++ ++#define atomic_inc_var(var) atomic_inc_var_size(var, sizeof(var)) ++ ++#define atomic_dec_var_size(var, size) atomic_unary_op(var, size, "dec") ++ ++#define atomic_dec_var(var) atomic_dec_var_size(var, sizeof(var)) ++ ++#define pre_atomic_add(var, i) \ ++({ \ ++ typeof(var) pre; \ ++ __asm__ __volatile__( \ ++ LOCK_PREFIX "xadd %0, %1\n\t" \ ++ : "=r"(pre), "+m"(var) \ ++ : "0"(i)); \ ++ pre; \ ++}) ++ ++#define post_atomic_add(var, i) (pre_atomic_add(var, i) + i) ++ ++//#define DEBUG_IRQL 1 ++ ++#ifdef DEBUG_IRQL ++#define assert_irql(cond) \ ++do { \ ++ KIRQL _irql_ = current_irql(); \ ++ if (!(cond)) { \ ++ WARNING("assertion '%s' failed: %d", #cond, _irql_); \ ++ DBG_BLOCK(4) { \ ++ dump_stack(); \ ++ } \ ++ } \ ++} while (0) ++#else ++#define assert_irql(cond) do { } while (0) ++#endif ++ ++/* When preempt is enabled, we should preempt_disable to raise IRQL to ++ * DISPATCH_LEVEL, to be consistent with the semantics. However, using ++ * a mutex instead, so that only ndiswrapper threads run one at a time ++ * on a processor when at DISPATCH_LEVEL seems to be enough. So that ++ * is what we will use until we learn otherwise. If ++ * preempt_(en|dis)able is required for some reason, comment out ++ * following #define. */ ++ ++#define WRAP_PREEMPT 1 ++ ++#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_RT) ++#ifndef WRAP_PREEMPT ++#define WRAP_PREEMPT 1 ++#endif ++#endif ++ ++//#undef WRAP_PREEMPT ++ ++#ifdef WRAP_PREEMPT ++ ++struct irql_info { ++ int count; ++ struct mutex lock; ++#ifdef CONFIG_SMP ++ cpumask_t cpus_allowed; ++#endif ++ struct task_struct *task; ++}; ++ ++DECLARE_PER_CPU(struct irql_info, irql_info); ++ ++static inline KIRQL raise_irql(KIRQL newirql) ++{ ++ struct irql_info *info; ++ ++ assert(newirql == DISPATCH_LEVEL); ++ info = &get_cpu_var(irql_info); ++ if (info->task == current) { ++ assert(info->count > 0); ++ assert(mutex_is_locked(&info->lock)); ++#if defined(CONFIG_SMP) && DEBUG >= 1 ++ assert(cpumask_equal(tsk_cpus_allowed(current), ++ cpumask_of(smp_processor_id()))); ++#endif ++ info->count++; ++ put_cpu_var(irql_info); ++ return DISPATCH_LEVEL; ++ } ++ /* TODO: is this enough to pin down to current cpu? */ ++#ifdef CONFIG_SMP ++ assert(task_cpu(current) == smp_processor_id()); ++ cpumask_copy(&info->cpus_allowed, tsk_cpus_allowed(current)); ++ set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id())); ++#endif ++ put_cpu_var(irql_info); ++ mutex_lock(&info->lock); ++ assert(info->count == 0); ++ assert(info->task == NULL); ++ info->count = 1; ++ info->task = current; ++ return PASSIVE_LEVEL; ++} ++ ++static inline void lower_irql(KIRQL oldirql) ++{ ++ struct irql_info *info; ++ ++ assert(oldirql <= DISPATCH_LEVEL); ++ info = &get_cpu_var(irql_info); ++ assert(info->task == current); ++ assert(mutex_is_locked(&info->lock)); ++ assert(info->count > 0); ++ if (--info->count == 0) { ++ info->task = NULL; ++#ifdef CONFIG_SMP ++ set_cpus_allowed_ptr(current, &info->cpus_allowed); ++#endif ++ mutex_unlock(&info->lock); ++ } ++ put_cpu_var(irql_info); ++} ++ ++static inline KIRQL current_irql(void) ++{ ++ int count; ++ if (in_irq() || irqs_disabled()) ++ EXIT4(return DIRQL); ++ if (in_atomic() || in_interrupt()) ++ EXIT4(return SOFT_IRQL); ++ count = get_cpu_var(irql_info).count; ++ put_cpu_var(irql_info); ++ if (count) ++ EXIT6(return DISPATCH_LEVEL); ++ else ++ EXIT6(return PASSIVE_LEVEL); ++} ++ ++#else ++ ++static inline KIRQL current_irql(void) ++{ ++ if (in_irq() || irqs_disabled()) ++ EXIT4(return DIRQL); ++ if (in_interrupt()) ++ EXIT4(return SOFT_IRQL); ++ if (in_atomic()) ++ EXIT6(return DISPATCH_LEVEL); ++ else ++ EXIT6(return PASSIVE_LEVEL); ++} ++ ++static inline KIRQL raise_irql(KIRQL newirql) ++{ ++ KIRQL ret = in_atomic() ? DISPATCH_LEVEL : PASSIVE_LEVEL; ++ assert(newirql == DISPATCH_LEVEL); ++ assert(current_irql() <= DISPATCH_LEVEL); ++ preempt_disable(); ++ return ret; ++} ++ ++static inline void lower_irql(KIRQL oldirql) ++{ ++ assert(current_irql() == DISPATCH_LEVEL); ++ preempt_enable(); ++} ++ ++#endif ++ ++#define irql_gfp() (in_atomic() ? GFP_ATOMIC : GFP_KERNEL) ++ ++/* Windows spinlocks are of type ULONG_PTR which is not big enough to ++ * store Linux spinlocks; so we implement Windows spinlocks using ++ * ULONG_PTR space with our own functions/macros */ ++ ++/* Windows seems to use 0 for unlocked state of spinlock - if Linux ++ * convention of 1 for unlocked state is used, at least prism54 driver ++ * crashes */ ++ ++#define NT_SPIN_LOCK_UNLOCKED 0 ++#define NT_SPIN_LOCK_LOCKED 1 ++ ++static inline void nt_spin_lock_init(NT_SPIN_LOCK *lock) ++{ ++ *lock = NT_SPIN_LOCK_UNLOCKED; ++} ++ ++#ifdef CONFIG_SMP ++ ++static inline void nt_spin_lock(NT_SPIN_LOCK *lock) ++{ ++ while (1) { ++ unsigned long lockval = xchg(lock, NT_SPIN_LOCK_LOCKED); ++ ++ if (likely(lockval == NT_SPIN_LOCK_UNLOCKED)) ++ break; ++ if (unlikely(lockval > NT_SPIN_LOCK_LOCKED)) { ++ ERROR("bad spinlock: 0x%lx at %p", lockval, lock); ++ return; ++ } ++ /* "rep; nop" doesn't change cx register, it's a "pause" */ ++ __asm__ __volatile__("rep; nop"); ++ } ++} ++ ++static inline void nt_spin_unlock(NT_SPIN_LOCK *lock) ++{ ++ unsigned long lockval = xchg(lock, NT_SPIN_LOCK_UNLOCKED); ++ ++ if (likely(lockval == NT_SPIN_LOCK_LOCKED)) ++ return; ++ WARNING("unlocking unlocked spinlock: 0x%lx at %p", lockval, lock); ++} ++ ++#else // CONFIG_SMP ++ ++#define nt_spin_lock(lock) do { } while (0) ++ ++#define nt_spin_unlock(lock) do { } while (0) ++ ++#endif // CONFIG_SMP ++ ++/* When kernel would've disabled preempt (e.g., in interrupt ++ * handlers), we need to fake preempt so driver thinks it is running ++ * at right IRQL */ ++ ++/* raise IRQL to given (higher) IRQL if necessary before locking */ ++static inline KIRQL nt_spin_lock_irql(NT_SPIN_LOCK *lock, KIRQL newirql) ++{ ++ KIRQL oldirql = raise_irql(newirql); ++ nt_spin_lock(lock); ++ return oldirql; ++} ++ ++/* lower IRQL to given (lower) IRQL if necessary after unlocking */ ++static inline void nt_spin_unlock_irql(NT_SPIN_LOCK *lock, KIRQL oldirql) ++{ ++ nt_spin_unlock(lock); ++ lower_irql(oldirql); ++} ++ ++#define nt_spin_lock_irqsave(lock, flags) \ ++do { \ ++ local_irq_save(flags); \ ++ preempt_disable(); \ ++ nt_spin_lock(lock); \ ++} while (0) ++ ++#define nt_spin_unlock_irqrestore(lock, flags) \ ++do { \ ++ nt_spin_unlock(lock); \ ++ preempt_enable_no_resched(); \ ++ local_irq_restore(flags); \ ++ preempt_check_resched(); \ ++} while (0) ++ ++static inline ULONG SPAN_PAGES(void *ptr, SIZE_T length) ++{ ++ return PAGE_ALIGN(((unsigned long)ptr & (PAGE_SIZE - 1)) + length) ++ >> PAGE_SHIFT; ++} ++ ++#ifdef CONFIG_X86_64 ++ ++/* TODO: can these be implemented without using spinlock? */ ++ ++static inline struct nt_slist *PushEntrySList(nt_slist_header *head, ++ struct nt_slist *entry, ++ NT_SPIN_LOCK *lock) ++{ ++ KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); ++ entry->next = head->next; ++ head->next = entry; ++ head->depth++; ++ nt_spin_unlock_irql(lock, irql); ++ TRACE4("%p, %p, %p", head, entry, entry->next); ++ return entry->next; ++} ++ ++static inline struct nt_slist *PopEntrySList(nt_slist_header *head, ++ NT_SPIN_LOCK *lock) ++{ ++ struct nt_slist *entry; ++ KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); ++ entry = head->next; ++ if (entry) { ++ head->next = entry->next; ++ head->depth--; ++ } ++ nt_spin_unlock_irql(lock, irql); ++ TRACE4("%p, %p", head, entry); ++ return entry; ++} ++ ++#else ++ ++#define u64_low_32(x) ((u32)x) ++#define u64_high_32(x) ((u32)(x >> 32)) ++ ++static inline u64 nt_cmpxchg8b(volatile u64 *ptr, u64 old, u64 new) ++{ ++ u64 prev; ++ ++ __asm__ __volatile__( ++ "\n" ++ LOCK_PREFIX "cmpxchg8b %0\n" ++ : "+m" (*ptr), "=A" (prev) ++ : "A" (old), "b" (u64_low_32(new)), "c" (u64_high_32(new))); ++ return prev; ++} ++ ++/* slist routines below update slist atomically - no need for ++ * spinlocks */ ++ ++static inline struct nt_slist *PushEntrySList(nt_slist_header *head, ++ struct nt_slist *entry, ++ NT_SPIN_LOCK *lock) ++{ ++ nt_slist_header old, new; ++ do { ++ old.align = head->align; ++ entry->next = old.next; ++ new.next = entry; ++ new.depth = old.depth + 1; ++ } while (nt_cmpxchg8b(&head->align, old.align, new.align) != old.align); ++ TRACE4("%p, %p, %p", head, entry, old.next); ++ return old.next; ++} ++ ++static inline struct nt_slist *PopEntrySList(nt_slist_header *head, ++ NT_SPIN_LOCK *lock) ++{ ++ struct nt_slist *entry; ++ nt_slist_header old, new; ++ do { ++ old.align = head->align; ++ entry = old.next; ++ if (!entry) ++ break; ++ new.next = entry->next; ++ new.depth = old.depth - 1; ++ } while (nt_cmpxchg8b(&head->align, old.align, new.align) != old.align); ++ TRACE4("%p, %p", head, entry); ++ return entry; ++} ++ ++#endif ++ ++#define sleep_hz(n) \ ++do { \ ++ set_current_state(TASK_INTERRUPTIBLE); \ ++ schedule_timeout(n); \ ++} while (0) ++ ++int ntoskernel_init(void); ++void ntoskernel_exit(void); ++int ntoskernel_init_device(struct wrap_device *wd); ++void ntoskernel_exit_device(struct wrap_device *wd); ++void *allocate_object(ULONG size, enum common_object_type type, ++ struct unicode_string *name); ++ ++#ifdef ENABLE_USB ++int usb_init(void); ++void usb_exit(void); ++#else ++static inline int usb_init(void) { return 0; } ++static inline void usb_exit(void) {} ++#endif ++int usb_init_device(struct wrap_device *wd); ++void usb_exit_device(struct wrap_device *wd); ++ ++int wrap_procfs_init(void); ++void wrap_procfs_remove(void); ++ ++int link_pe_images(struct pe_image *pe_image, unsigned short n); ++ ++int stricmp(const char *s1, const char *s2); ++void dump_bytes(const char *name, const u8 *from, int len); ++struct mdl *allocate_init_mdl(void *virt, ULONG length); ++void free_mdl(struct mdl *mdl); ++struct driver_object *find_bus_driver(const char *name); ++void free_custom_extensions(struct driver_extension *drv_obj_ext); ++struct nt_thread *get_current_nt_thread(void); ++u64 ticks_1601(void); ++int schedule_ntos_work_item(NTOS_WORK_FUNC func, void *arg1, void *arg2); ++void wrap_init_timer(struct nt_timer *nt_timer, enum timer_type type, ++ struct ndis_mp_block *nmb); ++BOOLEAN wrap_set_timer(struct nt_timer *nt_timer, unsigned long expires_hz, ++ unsigned long repeat_hz, struct kdpc *kdpc); ++ ++LONG InterlockedDecrement(LONG volatile *val) wfastcall; ++LONG InterlockedIncrement(LONG volatile *val) wfastcall; ++struct nt_list *ExInterlockedInsertHeadList ++ (struct nt_list *head, struct nt_list *entry, ++ NT_SPIN_LOCK *lock) wfastcall; ++struct nt_list *ExInterlockedInsertTailList ++ (struct nt_list *head, struct nt_list *entry, ++ NT_SPIN_LOCK *lock) wfastcall; ++struct nt_list *ExInterlockedRemoveHeadList ++ (struct nt_list *head, NT_SPIN_LOCK *lock) wfastcall; ++NTSTATUS IofCallDriver(struct device_object *dev_obj, struct irp *irp) wfastcall; ++KIRQL KfRaiseIrql(KIRQL newirql) wfastcall; ++void KfLowerIrql(KIRQL oldirql) wfastcall; ++KIRQL KfAcquireSpinLock(NT_SPIN_LOCK *lock) wfastcall; ++void KfReleaseSpinLock(NT_SPIN_LOCK *lock, KIRQL oldirql) wfastcall; ++void IofCompleteRequest(struct irp *irp, CHAR prio_boost) wfastcall; ++void KefReleaseSpinLockFromDpcLevel(NT_SPIN_LOCK *lock) wfastcall; ++ ++LONG ObfReferenceObject(void *object) wfastcall; ++void ObfDereferenceObject(void *object) wfastcall; ++ ++#define ObReferenceObject(object) ObfReferenceObject(object) ++#define ObDereferenceObject(object) ObfDereferenceObject(object) ++ ++/* prevent expansion of ExAllocatePoolWithTag macro */ ++void *(ExAllocatePoolWithTag)(enum pool_type pool_type, SIZE_T size, ++ ULONG tag) wstdcall; ++ ++void ExFreePool(void *p) wstdcall; ++ULONG MmSizeOfMdl(void *base, ULONG length) wstdcall; ++void __iomem *MmMapIoSpace(PHYSICAL_ADDRESS phys_addr, SIZE_T size, ++ enum memory_caching_type cache) wstdcall; ++void MmUnmapIoSpace(void __iomem *addr, SIZE_T size) wstdcall; ++void MmProbeAndLockPages(struct mdl *mdl, KPROCESSOR_MODE access_mode, ++ enum lock_operation operation) wstdcall; ++void MmUnlockPages(struct mdl *mdl) wstdcall; ++void KeInitializeEvent(struct nt_event *nt_event, ++ enum event_type type, BOOLEAN state) wstdcall; ++LONG KeSetEvent(struct nt_event *nt_event, KPRIORITY incr, ++ BOOLEAN wait) wstdcall; ++LONG KeResetEvent(struct nt_event *nt_event) wstdcall; ++BOOLEAN queue_kdpc(struct kdpc *kdpc); ++BOOLEAN dequeue_kdpc(struct kdpc *kdpc); ++ ++NTSTATUS IoConnectInterrupt(struct kinterrupt **kinterrupt, ++ PKSERVICE_ROUTINE service_routine, ++ void *service_context, NT_SPIN_LOCK *lock, ++ ULONG vector, KIRQL irql, KIRQL synch_irql, ++ enum kinterrupt_mode interrupt_mode, ++ BOOLEAN shareable, KAFFINITY processor_enable_mask, ++ BOOLEAN floating_save) wstdcall; ++void IoDisconnectInterrupt(struct kinterrupt *interrupt) wstdcall; ++BOOLEAN KeSynchronizeExecution(struct kinterrupt *interrupt, ++ PKSYNCHRONIZE_ROUTINE synch_routine, ++ void *ctx) wstdcall; ++ ++NTSTATUS KeWaitForSingleObject(void *object, KWAIT_REASON reason, ++ KPROCESSOR_MODE waitmode, BOOLEAN alertable, ++ LARGE_INTEGER *timeout) wstdcall; ++void MmBuildMdlForNonPagedPool(struct mdl *mdl) wstdcall; ++NTSTATUS IoCreateDevice(struct driver_object *driver, ULONG dev_ext_length, ++ struct unicode_string *dev_name, DEVICE_TYPE dev_type, ++ ULONG dev_chars, BOOLEAN exclusive, ++ struct device_object **dev_obj) wstdcall; ++NTSTATUS IoCreateSymbolicLink(struct unicode_string *link, ++ struct unicode_string *dev_name) wstdcall; ++void IoDeleteDevice(struct device_object *dev) wstdcall; ++void IoDetachDevice(struct device_object *topdev) wstdcall; ++struct device_object *IoGetAttachedDevice(struct device_object *dev) wstdcall; ++struct device_object *IoGetAttachedDeviceReference ++ (struct device_object *dev) wstdcall; ++NTSTATUS IoAllocateDriverObjectExtension ++ (struct driver_object *drv_obj, void *client_id, ULONG extlen, ++ void **ext) wstdcall; ++void *IoGetDriverObjectExtension(struct driver_object *drv, ++ void *client_id) wstdcall; ++struct device_object *IoAttachDeviceToDeviceStack ++ (struct device_object *src, struct device_object *dst) wstdcall; ++BOOLEAN IoCancelIrp(struct irp *irp) wstdcall; ++struct irp *IoBuildSynchronousFsdRequest ++ (ULONG major_func, struct device_object *dev_obj, void *buf, ++ ULONG length, LARGE_INTEGER *offset, struct nt_event *event, ++ struct io_status_block *status) wstdcall; ++ ++NTSTATUS IoPassIrpDown(struct device_object *dev_obj, struct irp *irp) wstdcall; ++WIN_FUNC_DECL(IoPassIrpDown,2); ++NTSTATUS IoSyncForwardIrp(struct device_object *dev_obj, ++ struct irp *irp) wstdcall; ++NTSTATUS IoAsyncForwardIrp(struct device_object *dev_obj, ++ struct irp *irp) wstdcall; ++NTSTATUS IoInvalidDeviceRequest(struct device_object *dev_obj, ++ struct irp *irp) wstdcall; ++ ++void KeInitializeSpinLock(NT_SPIN_LOCK *lock) wstdcall; ++void IoAcquireCancelSpinLock(KIRQL *irql) wstdcall; ++void IoReleaseCancelSpinLock(KIRQL irql) wstdcall; ++ ++NTSTATUS RtlUnicodeStringToAnsiString ++ (struct ansi_string *dst, const struct unicode_string *src, ++ BOOLEAN dup) wstdcall; ++NTSTATUS RtlAnsiStringToUnicodeString ++ (struct unicode_string *dst, const struct ansi_string *src, ++ BOOLEAN dup) wstdcall; ++void RtlInitAnsiString(struct ansi_string *dst, const char *src) wstdcall; ++void RtlInitUnicodeString(struct unicode_string *dest, ++ const wchar_t *src) wstdcall; ++void RtlFreeUnicodeString(struct unicode_string *string) wstdcall; ++void RtlFreeAnsiString(struct ansi_string *string) wstdcall; ++LONG RtlCompareUnicodeString(const struct unicode_string *s1, ++ const struct unicode_string *s2, ++ BOOLEAN case_insensitive) wstdcall; ++NTSTATUS RtlUpcaseUnicodeString(struct unicode_string *dst, ++ struct unicode_string *src, ++ BOOLEAN alloc) wstdcall; ++BOOLEAN KeCancelTimer(struct nt_timer *nt_timer) wstdcall; ++void KeInitializeDpc(struct kdpc *kdpc, void *func, void *ctx) wstdcall; ++ ++extern spinlock_t ntoskernel_lock; ++extern spinlock_t irp_cancel_lock; ++extern struct nt_list object_list; ++extern CCHAR cpu_count; ++#ifdef CONFIG_X86_64 ++extern struct kuser_shared_data kuser_shared_data; ++#endif ++ ++#define IoCompleteRequest(irp, prio) IofCompleteRequest(irp, prio) ++#define IoCallDriver(dev, irp) IofCallDriver(dev, irp) ++ ++#if defined(IO_DEBUG) ++#define DUMP_IRP(_irp) \ ++do { \ ++ struct io_stack_location *_irp_sl; \ ++ _irp_sl = IoGetCurrentIrpStackLocation(_irp); \ ++ IOTRACE("irp: %p, stack size: %d, cl: %d, sl: %p, dev_obj: %p, " \ ++ "mj_fn: %d, minor_fn: %d, nt_urb: %p, event: %p", \ ++ _irp, _irp->stack_count, (_irp)->current_location, \ ++ _irp_sl, _irp_sl->dev_obj, _irp_sl->major_fn, \ ++ _irp_sl->minor_fn, IRP_URB(_irp), \ ++ (_irp)->user_event); \ ++} while (0) ++#else ++#define DUMP_IRP(_irp) do { } while (0) ++#endif ++ ++#endif // _NTOSKERNEL_H_ +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/ntoskernel_io.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ntoskernel_io.c +--- linux-3.12.2/3rdparty/ndiswrapper/ntoskernel_io.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/ntoskernel_io.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,1161 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ntoskernel.h" ++#include "ndis.h" ++#include "wrapndis.h" ++#include "usb.h" ++#include "loader.h" ++#include "ntoskernel_io_exports.h" ++ ++wstdcall void WIN_FUNC(IoAcquireCancelSpinLock,1) ++ (KIRQL *irql) __acquires(irql) ++{ ++ spin_lock_bh(&irp_cancel_lock); ++ *irql = 0; ++} ++ ++wstdcall void WIN_FUNC(IoReleaseCancelSpinLock,1) ++ (KIRQL irql) __releases(irql) ++{ ++ spin_unlock_bh(&irp_cancel_lock); ++} ++ ++wstdcall int WIN_FUNC(IoIsWdmVersionAvailable,2) ++ (UCHAR major, UCHAR minor) ++{ ++ IOENTER("%d, %x", major, minor); ++ if (major == 1 && ++ (minor == 0x30 || // Windows 2003 ++ minor == 0x20 || // Windows XP ++ minor == 0x10)) // Windows 2000 ++ IOEXIT(return TRUE); ++ IOEXIT(return FALSE); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(IoIs32bitProcess,1) ++ (struct irp *irp) ++{ ++#ifdef CONFIG_X86_64 ++ return FALSE; ++#else ++ return TRUE; ++#endif ++} ++ ++wstdcall void WIN_FUNC(IoInitializeIrp,3) ++ (struct irp *irp, USHORT size, CCHAR stack_count) ++{ ++ IOENTER("irp: %p, %d, %d", irp, size, stack_count); ++ ++ memset(irp, 0, size); ++ irp->size = size; ++ irp->stack_count = stack_count; ++ irp->current_location = stack_count; ++ IoGetCurrentIrpStackLocation(irp) = IRP_SL(irp, stack_count); ++ IOEXIT(return); ++} ++ ++wstdcall void WIN_FUNC(IoReuseIrp,2) ++ (struct irp *irp, NTSTATUS status) ++{ ++ IOENTER("%p, %d", irp, status); ++ if (irp) { ++ UCHAR alloc_flags; ++ ++ alloc_flags = irp->alloc_flags; ++ IoInitializeIrp(irp, irp->size, irp->stack_count); ++ irp->alloc_flags = alloc_flags; ++ irp->io_status.status = status; ++ } ++ IOEXIT(return); ++} ++ ++wstdcall struct irp *WIN_FUNC(IoAllocateIrp,2) ++ (char stack_count, BOOLEAN charge_quota) ++{ ++ struct irp *irp; ++ int irp_size; ++ ++ IOENTER("count: %d", stack_count); ++ stack_count++; ++ irp_size = IoSizeOfIrp(stack_count); ++ irp = kmalloc(irp_size, irql_gfp()); ++ if (irp) ++ IoInitializeIrp(irp, irp_size, stack_count); ++ IOTRACE("irp %p", irp); ++ IOEXIT(return irp); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(IoCancelIrp,1) ++ (struct irp *irp) ++{ ++ typeof(irp->cancel_routine) cancel_routine; ++ ++ /* NB: this function may be called at DISPATCH_LEVEL */ ++ IOTRACE("irp: %p", irp); ++ if (!irp) ++ return FALSE; ++ DUMP_IRP(irp); ++ IoAcquireCancelSpinLock(&irp->cancel_irql); ++ cancel_routine = xchg(&irp->cancel_routine, NULL); ++ IOTRACE("%p", cancel_routine); ++ irp->cancel = TRUE; ++ if (cancel_routine) { ++ struct device_object *dev_obj; ++ ++ if (irp->current_location >= 0 && ++ irp->current_location < irp->stack_count) ++ dev_obj = IoGetCurrentIrpStackLocation(irp)->dev_obj; ++ else ++ dev_obj = NULL; ++ IOTRACE("current_location: %d, dev_obj: %p", ++ irp->current_location, dev_obj); ++ /* cancel_routine will release the spin lock */ ++ __release(irp->cancel_irql); ++ LIN2WIN2(cancel_routine, dev_obj, irp); ++ /* in usb's cancel, irp->cancel is set to indicate ++ * status of cancel */ ++ IOEXIT(return xchg(&irp->cancel, TRUE)); ++ } else { ++ IOTRACE("irp %p already canceled", irp); ++ IoReleaseCancelSpinLock(irp->cancel_irql); ++ IOEXIT(return FALSE); ++ } ++} ++ ++wstdcall void IoQueueThreadIrp(struct irp *irp) ++{ ++ struct nt_thread *thread; ++ KIRQL irql; ++ ++ thread = get_current_nt_thread(); ++ if (thread) { ++ IOTRACE("thread: %p, task: %p", thread, thread->task); ++ irp->flags |= IRP_SYNCHRONOUS_API; ++ irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL); ++ InsertTailList(&thread->irps, &irp->thread_list); ++ IoIrpThread(irp) = thread; ++ nt_spin_unlock_irql(&thread->lock, irql); ++ } else ++ IoIrpThread(irp) = NULL; ++} ++ ++wstdcall void IoDequeueThreadIrp(struct irp *irp) ++{ ++ struct nt_thread *thread; ++ KIRQL irql; ++ ++ thread = IoIrpThread(irp); ++ if (thread) { ++ irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL); ++ RemoveEntryList(&irp->thread_list); ++ nt_spin_unlock_irql(&thread->lock, irql); ++ } ++} ++ ++wstdcall void WIN_FUNC(IoFreeIrp,1) ++ (struct irp *irp) ++{ ++ IOENTER("irp = %p", irp); ++ if (!irp) { ++ WARNING("irp is NULL"); ++ return; ++ } ++ ++ if (irp->flags & IRP_SYNCHRONOUS_API) ++ IoDequeueThreadIrp(irp); ++ IoCancelIrp(irp); ++ kfree(irp); ++ ++ IOEXIT(return); ++} ++ ++wstdcall struct irp *WIN_FUNC(IoBuildAsynchronousFsdRequest,6) ++ (ULONG major_fn, struct device_object *dev_obj, void *buffer, ++ ULONG length, LARGE_INTEGER *offset, ++ struct io_status_block *user_status) ++{ ++ struct irp *irp; ++ struct io_stack_location *irp_sl; ++ ++ IOENTER("%p", dev_obj); ++ if (!dev_obj) ++ IOEXIT(return NULL); ++ irp = IoAllocateIrp(dev_obj->stack_count, FALSE); ++ if (irp == NULL) { ++ WARNING("couldn't allocate irp"); ++ IOEXIT(return NULL); ++ } ++ ++ irp_sl = IoGetNextIrpStackLocation(irp); ++ irp_sl->major_fn = major_fn; ++ IOTRACE("major_fn: %d", major_fn); ++ irp_sl->minor_fn = 0; ++ irp_sl->flags = 0; ++ irp_sl->control = 0; ++ irp_sl->dev_obj = dev_obj; ++ irp_sl->file_obj = NULL; ++ irp_sl->completion_routine = NULL; ++ ++ if (dev_obj->flags & DO_DIRECT_IO) { ++ irp->mdl = IoAllocateMdl(buffer, length, FALSE, FALSE, irp); ++ if (irp->mdl == NULL) { ++ IoFreeIrp(irp); ++ return NULL; ++ } ++ MmProbeAndLockPages(irp->mdl, KernelMode, ++ major_fn == IRP_MJ_WRITE ? ++ IoReadAccess : IoWriteAccess); ++ IOTRACE("mdl: %p", irp->mdl); ++ } else if (dev_obj->flags & DO_BUFFERED_IO) { ++ irp->associated_irp.system_buffer = buffer; ++ irp->flags = IRP_BUFFERED_IO; ++ irp->mdl = NULL; ++ IOTRACE("buffer: %p", buffer); ++ } ++ if (major_fn == IRP_MJ_READ) { ++ irp_sl->params.read.length = length; ++ irp_sl->params.read.byte_offset = *offset; ++ } else if (major_fn == IRP_MJ_WRITE) { ++ irp_sl->params.write.length = length; ++ irp_sl->params.write.byte_offset = *offset; ++ } ++ irp->user_status = user_status; ++ IOTRACE("irp: %p", irp); ++ return irp; ++} ++ ++wstdcall struct irp *WIN_FUNC(IoBuildSynchronousFsdRequest,7) ++ (ULONG major_fn, struct device_object *dev_obj, void *buf, ++ ULONG length, LARGE_INTEGER *offset, struct nt_event *event, ++ struct io_status_block *user_status) ++{ ++ struct irp *irp; ++ ++ irp = IoBuildAsynchronousFsdRequest(major_fn, dev_obj, buf, length, ++ offset, user_status); ++ if (irp == NULL) ++ return NULL; ++ irp->user_event = event; ++ IoQueueThreadIrp(irp); ++ return irp; ++} ++ ++wstdcall struct irp *WIN_FUNC(IoBuildDeviceIoControlRequest,9) ++ (ULONG ioctl, struct device_object *dev_obj, ++ void *input_buf, ULONG input_buf_len, void *output_buf, ++ ULONG output_buf_len, BOOLEAN internal_ioctl, ++ struct nt_event *event, struct io_status_block *io_status) ++{ ++ struct irp *irp; ++ struct io_stack_location *irp_sl; ++ ULONG buf_len; ++ ++ IOENTER("%p, 0x%08x, %d", dev_obj, ioctl, internal_ioctl); ++ if (!dev_obj) ++ IOEXIT(return NULL); ++ irp = IoAllocateIrp(dev_obj->stack_count, FALSE); ++ if (irp == NULL) { ++ WARNING("couldn't allocate irp"); ++ return NULL; ++ } ++ irp_sl = IoGetNextIrpStackLocation(irp); ++ irp_sl->params.dev_ioctl.code = ioctl; ++ irp_sl->params.dev_ioctl.input_buf_len = input_buf_len; ++ irp_sl->params.dev_ioctl.output_buf_len = output_buf_len; ++ irp_sl->major_fn = (internal_ioctl) ? ++ IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL; ++ IOTRACE("%d", IO_METHOD_FROM_CTL_CODE(ioctl)); ++ ++ switch (IO_METHOD_FROM_CTL_CODE(ioctl)) { ++ case METHOD_BUFFERED: ++ buf_len = max(input_buf_len, output_buf_len); ++ if (buf_len) { ++ irp->associated_irp.system_buffer = ++ ExAllocatePoolWithTag(NonPagedPool, buf_len, 0); ++ if (!irp->associated_irp.system_buffer) { ++ IoFreeIrp(irp); ++ IOEXIT(return NULL); ++ } ++ irp->associated_irp.system_buffer = input_buf; ++ if (input_buf) ++ memcpy(irp->associated_irp.system_buffer, ++ input_buf, input_buf_len); ++ irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; ++ if (output_buf) ++ irp->flags = IRP_INPUT_OPERATION; ++ irp->user_buf = output_buf; ++ } else ++ irp->user_buf = NULL; ++ break; ++ case METHOD_IN_DIRECT: ++ case METHOD_OUT_DIRECT: ++ if (input_buf) { ++ irp->associated_irp.system_buffer = ++ ExAllocatePoolWithTag(NonPagedPool, ++ input_buf_len, 0); ++ if (!irp->associated_irp.system_buffer) { ++ IoFreeIrp(irp); ++ IOEXIT(return NULL); ++ } ++ memcpy(irp->associated_irp.system_buffer, ++ input_buf, input_buf_len); ++ irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; ++ } ++ /* TODO: we are supposed to setup MDL, but USB layer ++ * doesn't use MDLs. Moreover, USB layer mirrors ++ * non-DMAable buffers, so no need to allocate ++ * DMAable buffer here */ ++ if (output_buf) { ++ irp->associated_irp.system_buffer = ++ ExAllocatePoolWithTag(NonPagedPool, ++ output_buf_len, 0); ++ if (!irp->associated_irp.system_buffer) { ++ IoFreeIrp(irp); ++ IOEXIT(return NULL); ++ } ++ irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; ++ } ++ break; ++ case METHOD_NEITHER: ++ irp->user_buf = output_buf; ++ irp_sl->params.dev_ioctl.type3_input_buf = input_buf; ++ break; ++ } ++ ++ irp->user_status = io_status; ++ irp->user_event = event; ++ IoQueueThreadIrp(irp); ++ ++ IOTRACE("irp: %p", irp); ++ IOEXIT(return irp); ++} ++ ++wfastcall NTSTATUS WIN_FUNC(IofCallDriver,2) ++ (struct device_object *dev_obj, struct irp *irp) ++{ ++ struct io_stack_location *irp_sl; ++ NTSTATUS status; ++ driver_dispatch_t *major_func; ++ struct driver_object *drv_obj; ++ ++ if (irp->current_location <= 0) { ++ ERROR("invalid irp: %p, %d", irp, irp->current_location); ++ return STATUS_INVALID_PARAMETER; ++ } ++ IOTRACE("%p, %p, %p, %d, %d, %p", dev_obj, irp, dev_obj->drv_obj, ++ irp->current_location, irp->stack_count, ++ IoGetCurrentIrpStackLocation(irp)); ++ IoSetNextIrpStackLocation(irp); ++ DUMP_IRP(irp); ++ irp_sl = IoGetCurrentIrpStackLocation(irp); ++ drv_obj = dev_obj->drv_obj; ++ irp_sl->dev_obj = dev_obj; ++ major_func = drv_obj->major_func[irp_sl->major_fn]; ++ IOTRACE("major_func: %p, dev_obj: %p", major_func, dev_obj); ++ if (major_func) ++ status = LIN2WIN2(major_func, dev_obj, irp); ++ else { ++ ERROR("major_function %d is not implemented", ++ irp_sl->major_fn); ++ status = STATUS_NOT_SUPPORTED; ++ } ++ IOEXIT(return status); ++} ++ ++wfastcall void WIN_FUNC(IofCompleteRequest,2) ++ (struct irp *irp, CHAR prio_boost) ++{ ++ struct io_stack_location *irp_sl; ++ ++#ifdef IO_DEBUG ++ DUMP_IRP(irp); ++ if (irp->io_status.status == STATUS_PENDING) { ++ ERROR("invalid irp: %p, STATUS_PENDING", irp); ++ return; ++ } ++ if (irp->current_location < 0 || ++ irp->current_location >= irp->stack_count) { ++ ERROR("invalid irp: %p, %d", irp, irp->current_location); ++ return; ++ } ++#endif ++ for (irp_sl = IoGetCurrentIrpStackLocation(irp); ++ irp->current_location < irp->stack_count; irp_sl++) { ++ struct device_object *dev_obj; ++ NTSTATUS status; ++ ++ DUMP_IRP(irp); ++ if (irp_sl->control & SL_PENDING_RETURNED) ++ irp->pending_returned = TRUE; ++ ++ /* current_location and dev_obj must be same as when ++ * driver called IoSetCompletionRoutine, which sets ++ * completion routine at next (lower) location, which ++ * is what we are going to call below; so we set ++ * current_location and dev_obj for the previous ++ * (higher) location */ ++ IoSkipCurrentIrpStackLocation(irp); ++ if (irp->current_location < irp->stack_count) ++ dev_obj = IoGetCurrentIrpStackLocation(irp)->dev_obj; ++ else ++ dev_obj = NULL; ++ ++ IOTRACE("%d, %d, %p", irp->current_location, irp->stack_count, ++ dev_obj); ++ if (irp_sl->completion_routine && ++ ((irp->io_status.status == STATUS_SUCCESS && ++ irp_sl->control & SL_INVOKE_ON_SUCCESS) || ++ (irp->io_status.status != STATUS_SUCCESS && ++ irp_sl->control & SL_INVOKE_ON_ERROR) || ++ (irp->cancel == TRUE && ++ irp_sl->control & SL_INVOKE_ON_CANCEL))) { ++ IOTRACE("calling completion_routine at: %p, %p", ++ irp_sl->completion_routine, irp_sl->context); ++ status = LIN2WIN3(irp_sl->completion_routine, ++ dev_obj, irp, irp_sl->context); ++ IOTRACE("status: %08X", status); ++ if (status == STATUS_MORE_PROCESSING_REQUIRED) ++ IOEXIT(return); ++ } else { ++ /* propagate pending status to next irp_sl */ ++ if (irp->pending_returned && ++ irp->current_location < irp->stack_count) ++ IoMarkIrpPending(irp); ++ } ++ } ++ ++ if (irp->user_status) { ++ irp->user_status->status = irp->io_status.status; ++ irp->user_status->info = irp->io_status.info; ++ } ++ ++ if (irp->user_event) { ++ IOTRACE("setting event %p", irp->user_event); ++ KeSetEvent(irp->user_event, prio_boost, FALSE); ++ } ++ ++ if (irp->associated_irp.system_buffer && ++ (irp->flags & IRP_DEALLOCATE_BUFFER)) ++ ExFreePool(irp->associated_irp.system_buffer); ++ else { ++ struct mdl *mdl; ++ while ((mdl = irp->mdl)) { ++ irp->mdl = mdl->next; ++ MmUnlockPages(mdl); ++ IoFreeMdl(mdl); ++ } ++ } ++ IOTRACE("freeing irp %p", irp); ++ IoFreeIrp(irp); ++ IOEXIT(return); ++} ++ ++wstdcall NTSTATUS IoPassIrpDown(struct device_object *dev_obj, struct irp *irp) ++{ ++ IoSkipCurrentIrpStackLocation(irp); ++ IOEXIT(return IoCallDriver(dev_obj, irp)); ++} ++ ++wstdcall NTSTATUS IoIrpSyncComplete(struct device_object *dev_obj, ++ struct irp *irp, void *context) ++{ ++ if (irp->pending_returned == TRUE) ++ KeSetEvent(context, IO_NO_INCREMENT, FALSE); ++ IOEXIT(return STATUS_MORE_PROCESSING_REQUIRED); ++} ++WIN_FUNC_DECL(IoIrpSyncComplete,3) ++ ++wstdcall NTSTATUS IoSyncForwardIrp(struct device_object *dev_obj, ++ struct irp *irp) ++{ ++ struct nt_event event; ++ NTSTATUS status; ++ ++ IoCopyCurrentIrpStackLocationToNext(irp); ++ KeInitializeEvent(&event, SynchronizationEvent, FALSE); ++ /* completion function is called as Windows function */ ++ IoSetCompletionRoutine(irp, WIN_FUNC_PTR(IoIrpSyncComplete,3), &event, ++ TRUE, TRUE, TRUE); ++ status = IoCallDriver(dev_obj, irp); ++ IOTRACE("%08X", status); ++ if (status == STATUS_PENDING) { ++ KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, ++ NULL); ++ status = irp->io_status.status; ++ } ++ IOTRACE("%08X", status); ++ IOEXIT(return status); ++} ++WIN_FUNC_DECL(IoSyncForwardIrp,2) ++ ++wstdcall NTSTATUS IoAsyncForwardIrp(struct device_object *dev_obj, ++ struct irp *irp) ++{ ++ NTSTATUS status; ++ ++ IoCopyCurrentIrpStackLocationToNext(irp); ++ status = IoCallDriver(dev_obj, irp); ++ IOEXIT(return status); ++} ++WIN_FUNC_DECL(IoAsyncForwardIrp,2) ++ ++wstdcall NTSTATUS IoInvalidDeviceRequest(struct device_object *dev_obj, ++ struct irp *irp) ++{ ++ struct io_stack_location *irp_sl; ++ NTSTATUS status; ++ ++ irp_sl = IoGetCurrentIrpStackLocation(irp); ++ WARNING("%d:%d not implemented", irp_sl->major_fn, irp_sl->minor_fn); ++ irp->io_status.status = STATUS_SUCCESS; ++ irp->io_status.info = 0; ++ status = irp->io_status.status; ++ IoCompleteRequest(irp, IO_NO_INCREMENT); ++ IOEXIT(return status); ++} ++WIN_FUNC_DECL(IoInvalidDeviceRequest,2) ++ ++static irqreturn_t io_irq_isr(int irq, void *data ISR_PT_REGS_PARAM_DECL) ++{ ++ struct kinterrupt *interrupt = data; ++ BOOLEAN ret; ++ ++#ifdef CONFIG_DEBUG_SHIRQ ++ if (!interrupt->u.enabled) ++ EXIT1(return IRQ_NONE); ++#endif ++ TRACE6("%p", interrupt); ++ nt_spin_lock(interrupt->actual_lock); ++ ret = LIN2WIN2(interrupt->isr, interrupt, interrupt->isr_ctx); ++ nt_spin_unlock(interrupt->actual_lock); ++ if (ret == TRUE) ++ EXIT6(return IRQ_HANDLED); ++ else ++ EXIT6(return IRQ_NONE); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoConnectInterrupt,11) ++ (struct kinterrupt **kinterrupt, PKSERVICE_ROUTINE isr, void *isr_ctx, ++ NT_SPIN_LOCK *lock, ULONG vector, KIRQL irql, KIRQL synch_irql, ++ enum kinterrupt_mode mode, BOOLEAN shared, KAFFINITY cpu_mask, ++ BOOLEAN save_fp) ++{ ++ struct kinterrupt *interrupt; ++ IOENTER(""); ++ interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL); ++ if (!interrupt) ++ IOEXIT(return STATUS_INSUFFICIENT_RESOURCES); ++ interrupt->vector = vector; ++ interrupt->cpu_mask = cpu_mask; ++ nt_spin_lock_init(&interrupt->lock); ++ if (lock) ++ interrupt->actual_lock = lock; ++ else ++ interrupt->actual_lock = &interrupt->lock; ++ interrupt->shared = shared; ++ interrupt->save_fp = save_fp; ++ interrupt->isr = isr; ++ interrupt->isr_ctx = isr_ctx; ++ InitializeListHead(&interrupt->list); ++ interrupt->irql = irql; ++ interrupt->synch_irql = synch_irql; ++ interrupt->mode = mode; ++ if (request_irq(vector, io_irq_isr, shared ? IRQF_SHARED : 0, ++ DRIVER_NAME, interrupt)) { ++ WARNING("request for irq %d failed", vector); ++ kfree(interrupt); ++ IOEXIT(return STATUS_INSUFFICIENT_RESOURCES); ++ } ++ *kinterrupt = interrupt; ++#ifdef CONFIG_DEBUG_SHIRQ ++ interrupt->u.enabled = 1; ++#endif ++ IOEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(IoDisconnectInterrupt,1) ++ (struct kinterrupt *interrupt) ++{ ++#ifdef CONFIG_DEBUG_SHIRQ ++ interrupt->u.enabled = 0; ++#endif ++ free_irq(interrupt->vector, interrupt); ++ kfree(interrupt); ++} ++ ++wstdcall struct mdl *WIN_FUNC(IoAllocateMdl,5) ++ (void *virt, ULONG length, BOOLEAN second_buf, BOOLEAN charge_quota, ++ struct irp *irp) ++{ ++ struct mdl *mdl; ++ mdl = allocate_init_mdl(virt, length); ++ if (!mdl) ++ return NULL; ++ if (irp) { ++ if (second_buf == TRUE) { ++ struct mdl *last; ++ ++ last = irp->mdl; ++ while (last->next) ++ last = last->next; ++ last->next = mdl; ++ } else ++ irp->mdl = mdl; ++ } ++ IOTRACE("%p", mdl); ++ return mdl; ++} ++ ++wstdcall void WIN_FUNC(IoFreeMdl,1) ++ (struct mdl *mdl) ++{ ++ IOTRACE("%p", mdl); ++ free_mdl(mdl); ++} ++ ++wstdcall struct io_workitem *WIN_FUNC(IoAllocateWorkItem,1) ++ (struct device_object *dev_obj) ++{ ++ struct io_workitem *io_workitem; ++ ++ IOENTER("%p", dev_obj); ++ io_workitem = kmalloc(sizeof(*io_workitem), irql_gfp()); ++ if (!io_workitem) ++ IOEXIT(return NULL); ++ io_workitem->dev_obj = dev_obj; ++ IOEXIT(return io_workitem); ++} ++ ++wstdcall void WIN_FUNC(IoFreeWorkItem,1) ++ (struct io_workitem *io_workitem) ++{ ++ kfree(io_workitem); ++ IOEXIT(return); ++} ++ ++wstdcall void WIN_FUNC(IoQueueWorkItem,4) ++ (struct io_workitem *io_workitem, void *func, ++ enum work_queue_type queue_type, void *context) ++{ ++ IOENTER("%p, %p", io_workitem, io_workitem->dev_obj); ++ io_workitem->worker_routine = func; ++ io_workitem->context = context; ++ schedule_ntos_work_item(func, io_workitem->dev_obj, context); ++ IOEXIT(return); ++} ++ ++wstdcall void WIN_FUNC(ExQueueWorkItem,2) ++ (struct io_workitem *io_workitem, enum work_queue_type queue_type) ++{ ++ IOENTER("%p", io_workitem); ++ schedule_ntos_work_item(io_workitem->worker_routine, ++ io_workitem->dev_obj, io_workitem->context); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoAllocateDriverObjectExtension,4) ++ (struct driver_object *drv_obj, void *client_id, ULONG extlen, ++ void **ext) ++{ ++ struct custom_ext *ce; ++ ++ IOENTER("%p, %p", drv_obj, client_id); ++ ce = kmalloc(sizeof(*ce) + extlen, irql_gfp()); ++ if (ce == NULL) ++ return STATUS_INSUFFICIENT_RESOURCES; ++ ++ IOTRACE("custom_ext: %p", ce); ++ ce->client_id = client_id; ++ spin_lock_bh(&ntoskernel_lock); ++ InsertTailList(&drv_obj->drv_ext->custom_ext, &ce->list); ++ spin_unlock_bh(&ntoskernel_lock); ++ ++ *ext = (void *)ce + sizeof(*ce); ++ IOTRACE("ext: %p", *ext); ++ IOEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall void *WIN_FUNC(IoGetDriverObjectExtension,2) ++ (struct driver_object *drv_obj, void *client_id) ++{ ++ struct custom_ext *ce; ++ void *ret; ++ ++ IOENTER("drv_obj: %p, client_id: %p", drv_obj, client_id); ++ ret = NULL; ++ spin_lock_bh(&ntoskernel_lock); ++ nt_list_for_each_entry(ce, &drv_obj->drv_ext->custom_ext, list) { ++ if (ce->client_id == client_id) { ++ ret = (void *)ce + sizeof(*ce); ++ break; ++ } ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ IOTRACE("ret: %p", ret); ++ return ret; ++} ++ ++void free_custom_extensions(struct driver_extension *drv_ext) ++{ ++ struct nt_list *ent; ++ ++ IOENTER("%p", drv_ext); ++ spin_lock_bh(&ntoskernel_lock); ++ while ((ent = RemoveHeadList(&drv_ext->custom_ext))) ++ kfree(ent); ++ spin_unlock_bh(&ntoskernel_lock); ++ IOEXIT(return); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoCreateDevice,7) ++ (struct driver_object *drv_obj, ULONG dev_ext_length, ++ struct unicode_string *dev_name, DEVICE_TYPE dev_type, ++ ULONG dev_chars, BOOLEAN exclusive, struct device_object **newdev) ++{ ++ struct device_object *dev; ++ struct dev_obj_ext *dev_obj_ext; ++ int size; ++ ++ IOENTER("%p, %u, %p", drv_obj, dev_ext_length, dev_name); ++ ++ size = sizeof(*dev) + dev_ext_length + sizeof(*dev_obj_ext); ++ dev = allocate_object(size, OBJECT_TYPE_DEVICE, dev_name); ++ if (!dev) ++ IOEXIT(return STATUS_INSUFFICIENT_RESOURCES); ++ if (dev_ext_length) ++ dev->dev_ext = dev + 1; ++ else ++ dev->dev_ext = NULL; ++ ++ dev_obj_ext = ((void *)(dev + 1)) + dev_ext_length; ++ dev_obj_ext->dev_obj = dev; ++ dev_obj_ext->size = 0; ++ dev_obj_ext->type = IO_TYPE_DEVICE; ++ dev->dev_obj_ext = dev_obj_ext; ++ ++ dev->type = dev_type; ++ dev->flags = 0; ++ dev->size = sizeof(*dev) + dev_ext_length; ++ dev->ref_count = 1; ++ dev->attached = NULL; ++ dev->stack_count = 1; ++ ++ dev->drv_obj = drv_obj; ++ dev->next = drv_obj->dev_obj; ++ drv_obj->dev_obj = dev; ++ ++ dev->align_req = 1; ++ dev->characteristics = dev_chars; ++ dev->io_timer = NULL; ++ KeInitializeEvent(&dev->lock, SynchronizationEvent, TRUE); ++ dev->vpb = NULL; ++ ++ IOTRACE("dev: %p, ext: %p", dev, dev->dev_ext); ++ *newdev = dev; ++ IOEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoCreateUnprotectedSymbolicLink,2) ++ (struct unicode_string *link, struct unicode_string *dev_name) ++{ ++ struct ansi_string ansi; ++ ++ IOENTER("%p, %p", dev_name, link); ++ if (dev_name && (RtlUnicodeStringToAnsiString(&ansi, dev_name, TRUE) == ++ STATUS_SUCCESS)) { ++ IOTRACE("dev_name: %s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ if (link && (RtlUnicodeStringToAnsiString(&ansi, link, TRUE) == ++ STATUS_SUCCESS)) { ++ IOTRACE("link: %s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++// TODO(); ++ IOEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoCreateSymbolicLink,2) ++ (struct unicode_string *link, struct unicode_string *dev_name) ++{ ++ IOEXIT(return IoCreateUnprotectedSymbolicLink(link, dev_name)); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoDeleteSymbolicLink,1) ++ (struct unicode_string *link) ++{ ++ struct ansi_string ansi; ++ ++ IOENTER("%p", link); ++ if (link && (RtlUnicodeStringToAnsiString(&ansi, link, TRUE) == ++ STATUS_SUCCESS)) { ++ IOTRACE("dev_name: %s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ IOEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(IoDeleteDevice,1) ++ (struct device_object *dev) ++{ ++ IOENTER("%p", dev); ++ if (dev == NULL) ++ IOEXIT(return); ++ IOTRACE("drv_obj: %p", dev->drv_obj); ++ if (dev->drv_obj) { ++ struct device_object *prev; ++ ++ prev = dev->drv_obj->dev_obj; ++ IOTRACE("dev_obj: %p", prev); ++ if (prev == dev) ++ dev->drv_obj->dev_obj = dev->next; ++ else if (prev) { ++ while (prev->next != dev) ++ prev = prev->next; ++ prev->next = dev->next; ++ } ++ } ++ ObDereferenceObject(dev); ++ IOEXIT(return); ++} ++ ++wstdcall void WIN_FUNC(IoDetachDevice,1) ++ (struct device_object *tgt) ++{ ++ struct device_object *tail; ++ ++ IOENTER("%p", tgt); ++ if (!tgt) ++ IOEXIT(return); ++ tail = tgt->attached; ++ if (!tail) ++ IOEXIT(return); ++ IOTRACE("tail: %p", tail); ++ ++ spin_lock_bh(&ntoskernel_lock); ++ tgt->attached = tail->attached; ++ IOTRACE("attached:%p", tgt->attached); ++ for ( ; tail; tail = tail->attached) { ++ IOTRACE("tail:%p", tail); ++ tail->stack_count--; ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ IOEXIT(return); ++} ++ ++wstdcall struct device_object *WIN_FUNC(IoGetAttachedDevice,1) ++ (struct device_object *dev) ++{ ++ IOENTER("%p", dev); ++ if (!dev) ++ IOEXIT(return NULL); ++ spin_lock_bh(&ntoskernel_lock); ++ while (dev->attached) ++ dev = dev->attached; ++ spin_unlock_bh(&ntoskernel_lock); ++ IOEXIT(return dev); ++} ++ ++wstdcall struct device_object *WIN_FUNC(IoGetAttachedDeviceReference,1) ++ (struct device_object *dev) ++{ ++ IOENTER("%p", dev); ++ if (!dev) ++ IOEXIT(return NULL); ++ dev = IoGetAttachedDevice(dev); ++ ObReferenceObject(dev); ++ IOEXIT(return dev); ++} ++ ++wstdcall struct device_object *WIN_FUNC(IoAttachDeviceToDeviceStack,2) ++ (struct device_object *src, struct device_object *tgt) ++{ ++ struct device_object *attached; ++ struct dev_obj_ext *src_dev_ext; ++ ++ IOENTER("%p, %p", src, tgt); ++ attached = IoGetAttachedDevice(tgt); ++ IOTRACE("%p", attached); ++ src_dev_ext = src->dev_obj_ext; ++ spin_lock_bh(&ntoskernel_lock); ++ if (attached) ++ attached->attached = src; ++ src->attached = NULL; ++ src->stack_count = attached->stack_count + 1; ++ src_dev_ext->attached_to = attached; ++ spin_unlock_bh(&ntoskernel_lock); ++ IOTRACE("stack_count: %d -> %d", attached->stack_count, ++ src->stack_count); ++ IOEXIT(return attached); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoGetDeviceProperty,5) ++ (struct device_object *pdo, enum device_registry_property dev_property, ++ ULONG buffer_len, void *buffer, ULONG *result_len) ++{ ++ struct ansi_string ansi; ++ struct unicode_string unicode; ++ struct wrap_device *wd; ++ ULONG need; ++ ++ IOENTER("dev_obj = %p, dev_property = %d, buffer_len = %u, " ++ "buffer = %p, result_len = %p", pdo, dev_property, ++ buffer_len, buffer, result_len); ++ ++ wd = pdo->reserved; ++ switch (dev_property) { ++ case DevicePropertyDeviceDescription: ++ case DevicePropertyFriendlyName: ++ case DevicePropertyDriverKeyName: ++ if (wrap_is_pci_bus(wd->dev_bus)) ++ RtlInitAnsiString(&ansi, "PCI"); ++ else // if (wrap_is_usb_bus(wd->dev_bus)) ++ RtlInitAnsiString(&ansi, "USB"); ++ need = sizeof(wchar_t) * (ansi.max_length + 1); ++ if (buffer_len < need) { ++ *result_len = need; ++ IOEXIT(return STATUS_BUFFER_TOO_SMALL); ++ } ++ unicode.max_length = buffer_len; ++ unicode.buf = buffer; ++ if (RtlAnsiStringToUnicodeString(&unicode, &ansi, ++ FALSE) != STATUS_SUCCESS) { ++ *result_len = unicode.length; ++ IOEXIT(return STATUS_BUFFER_TOO_SMALL); ++ } ++ IOEXIT(return STATUS_SUCCESS); ++ default: ++ WARNING("%d not implemented", dev_property); ++ IOEXIT(return STATUS_INVALID_PARAMETER_2); ++ } ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoGetDeviceObjectPointer,4) ++ (struct unicode_string *name, ACCESS_MASK desired_access, ++ struct file_object *file_obj, struct device_object *dev_obj) ++{ ++ struct common_object_header *coh; ++ ++ dev_obj = NULL; ++ /* TODO: access is not checked and file_obj is filled with zeroes */ ++ spin_lock_bh(&ntoskernel_lock); ++ nt_list_for_each_entry(coh, &object_list, list) { ++ TRACE5("header: %p, type: %d", coh, coh->type); ++ if (coh->type != OBJECT_TYPE_DEVICE) ++ continue; ++ if (!RtlCompareUnicodeString(&coh->name, name, TRUE)) { ++ dev_obj = HEADER_TO_OBJECT(coh); ++ TRACE5("dev_obj: %p", dev_obj); ++ break; ++ } ++ } ++ spin_unlock_bh(&ntoskernel_lock); ++ if (dev_obj) { ++ memset(file_obj, 0, sizeof(*file_obj)); ++ WARNING("file_obj filled with zeroes"); ++ IOEXIT(return STATUS_SUCCESS); ++ } else ++ IOEXIT(return STATUS_OBJECT_NAME_INVALID); ++} ++ ++/* NOTE: Make sure to compile with -freg-struct-return, so gcc will ++ * return union in register, like Windows */ ++wstdcall union power_state WIN_FUNC(PoSetPowerState,3) ++ (struct device_object *dev_obj, enum power_state_type type, ++ union power_state state) ++{ ++ IOEXIT(return state); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(PoCallDriver,2) ++ (struct device_object *dev_obj, struct irp *irp) ++{ ++ return IoCallDriver(dev_obj, irp); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(PoRequestPowerIrp,6) ++ (struct device_object *dev_obj, UCHAR minor_fn, ++ union power_state power_state, void *completion_func, ++ void *context, struct irp **pirp) ++{ ++ struct irp *irp; ++ struct io_stack_location *irp_sl; ++ ++ TRACE1("%p, %d, %p", dev_obj, dev_obj->stack_count, dev_obj->drv_obj); ++ irp = IoAllocateIrp(dev_obj->stack_count, FALSE); ++ if (!irp) ++ return STATUS_INSUFFICIENT_RESOURCES; ++ irp_sl = IoGetNextIrpStackLocation(irp); ++ irp_sl->major_fn = IRP_MJ_POWER; ++ irp_sl->minor_fn = minor_fn; ++ if (minor_fn == IRP_MN_WAIT_WAKE) ++ irp_sl->params.power.type = SystemPowerState; ++ else ++ irp_sl->params.power.type = DevicePowerState; ++ irp_sl->params.power.state = power_state; ++ irp_sl->completion_routine = completion_func; ++ irp->io_status.status = STATUS_NOT_SUPPORTED; ++ *pirp = irp; ++ return PoCallDriver(dev_obj, irp); ++} ++ ++wstdcall void WIN_FUNC(PoStartNextPowerIrp,1) ++ (struct irp *irp) ++{ ++ IOENTER("irp = %p", irp); ++ IOEXIT(return); ++} ++ ++wstdcall void WIN_FUNC(IoInitializeRemoveLockEx,5) ++ (struct io_remove_lock *lock, ULONG alloc_tag, ULONG max_locked_min, ++ ULONG high_mark, ULONG lock_size) ++{ ++ TODO(); ++} ++ ++wstdcall void *WIN_FUNC(IoAllocateErrorLogEntry,2) ++ (void *io_object, UCHAR entry_size) ++{ ++ /* not implemented fully */ ++ void *ret = kmalloc(sizeof(struct io_error_log_packet) + entry_size, ++ irql_gfp()); ++ TRACE2("%p", ret); ++ if (ret) ++ return ret + sizeof(struct io_error_log_packet); ++ else ++ return NULL; ++} ++ ++wstdcall void WIN_FUNC(IoWriteErrorLogEntry,1) ++ (void *entry) ++{ ++ /* TODO: log error with codes and message */ ++ ERROR(""); ++} ++ ++wstdcall void WIN_FUNC(IoFreeErrorLogEntry,1) ++ (void *entry) ++{ ++ TRACE2("%p", entry); ++ kfree(entry - sizeof(struct io_error_log_packet)); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoAcquireRemoveLockEx,5) ++ (struct io_remove_lock *lock, void *tag, char *file, ULONG line, ++ ULONG lock_size) ++{ ++ TODO(); ++ IOEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoReleaseRemoveLockEx,3) ++ (struct io_remove_lock *lock, void *tag, ULONG lock_size) ++{ ++ TODO(); ++ IOEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoRegisterDeviceInterface,4) ++ (struct device_object *pdo, struct guid *guid_class, ++ struct unicode_string *reference, struct unicode_string *link) ++{ ++ struct ansi_string ansi; ++ ++ /* TODO: check if pdo is valid */ ++ RtlInitAnsiString(&ansi, "ndis"); ++ ENTER1("pdo: %p, ref: %p, link: %p, %x, %x, %x", pdo, reference, link, ++ guid_class->data1, guid_class->data2, guid_class->data3); ++ return RtlAnsiStringToUnicodeString(link, &ansi, TRUE); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoSetDeviceInterfaceState,2) ++ (struct unicode_string *link, BOOLEAN enable) ++{ ++ ENTER1("link: %p, enable: %d", link, enable); ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoOpenDeviceRegistryKey,4) ++ (struct device_object *dev_obj, ULONG type, ACCESS_MASK mask, ++ void **handle) ++{ ++ ENTER1("dev_obj: %p", dev_obj); ++ *handle = dev_obj; ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoWMIRegistrationControl,2) ++ (struct device_object *dev_obj, ULONG action) ++{ ++ ENTER2("%p, %d", dev_obj, action); ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(IoInvalidateDeviceRelations,2) ++ (struct device_object *dev_obj, enum device_relation_type type) ++{ ++ INFO("%p, %d", dev_obj, type); ++ TODO(); ++} ++ ++wstdcall void WIN_FUNC(IoInvalidateDeviceState,1) ++ (struct device_object *pdo) ++{ ++ INFO("%p", pdo); ++ TODO(); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoRegisterPlugPlayNotification,7) ++ (UINT category, ULONG flags, void *data, struct driver_object *object, ++ void *callback, void *context, void **notification_entry) ++{ ++ TRACE2("category: %d, flags 0x%x, data: %p, object: %p, callback: %p, " ++ "context: %p, notification_entry: %p", category, flags, data, ++ object, callback, context, notification_entry); ++ TODO(); ++ IOEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoUnregisterPlugPlayNotification,1) ++ (void *notification_entry) ++{ ++ TRACE2("%p", notification_entry); ++ TODO(); ++ IOEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoWMIOpenBlock,3) ++ (struct guid *guid, ULONG access, void *object) ++{ ++ TODO(); ++ IOEXIT(return STATUS_NOT_IMPLEMENTED); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(IoWMIQueryAllData,3) ++ (void *data_block_object, UINT *buffer_size, void *buffer) ++{ ++ TODO(); ++ IOEXIT(return STATUS_NOT_IMPLEMENTED); ++} ++ ++wstdcall void WIN_FUNC(IoGetStackLimits,2) ++ (ULONG_PTR *LowLimit, ULONG_PTR *HighLimit) ++{ ++ *LowLimit = (ULONG_PTR)&LowLimit & ~(THREAD_SIZE - 1); ++ *HighLimit = *LowLimit + THREAD_SIZE; ++ IOTRACE("LowLimit: 0x%lx, HighLimit: 0x%lx", *LowLimit, *HighLimit); ++ IOEXIT(return); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/pe_linker.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/pe_linker.c +--- linux-3.12.2/3rdparty/ndiswrapper/pe_linker.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/pe_linker.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,600 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifdef TEST_LOADER ++ ++#include "usr_linker.h" ++ ++#else ++ ++#include ++#include ++ ++//#define DEBUGLINKER 2 ++ ++#include "ntoskernel.h" ++ ++#endif ++ ++struct pe_exports { ++ char *dll; ++ char *name; ++ generic_func addr; ++}; ++ ++static struct pe_exports pe_exports[40]; ++static int num_pe_exports; ++ ++#define RVA2VA(image, rva, type) (type)(ULONG_PTR)((void *)image + rva) ++#define CHECK_SZ(a,b) { if (sizeof(a) != b) { \ ++ ERROR("%s is bad, got %zd, expected %d", \ ++ #a , sizeof(a), (b)); return -EINVAL; } } ++ ++#if defined(DEBUGLINKER) && DEBUGLINKER > 0 ++#define DBGLINKER(fmt, ...) printk(KERN_INFO "%s (%s:%d): " fmt "\n", \ ++ DRIVER_NAME, __func__, \ ++ __LINE__ , ## __VA_ARGS__); ++static const char *image_directory_name[] = { ++ "EXPORT", ++ "IMPORT", ++ "RESOURCE", ++ "EXCEPTION", ++ "SECURITY", ++ "BASERELOC", ++ "DEBUG", ++ "COPYRIGHT", ++ "GLOBALPTR", ++ "TLS", ++ "LOAD_CONFIG", ++ "BOUND_IMPORT", ++ "IAT", ++ "DELAY_IMPORT", ++ "COM_DESCRIPTOR" }; ++#else ++#define DBGLINKER(fmt, ...) do { } while (0) ++#endif ++ ++#ifndef TEST_LOADER ++extern struct wrap_export ntoskernel_exports[], ntoskernel_io_exports[], ++ ndis_exports[], crt_exports[], hal_exports[], rtl_exports[]; ++#ifdef ENABLE_USB ++extern struct wrap_export usb_exports[]; ++#endif ++ ++static int get_export(char *name, generic_func *func) ++{ ++ int i, j; ++ ++ struct wrap_export *exports[] = { ++ ntoskernel_exports, ++ ntoskernel_io_exports, ++ ndis_exports, ++ crt_exports, ++ hal_exports, ++ rtl_exports, ++#ifdef ENABLE_USB ++ usb_exports, ++#endif ++ }; ++ ++ for (j = 0; j < ARRAY_SIZE(exports); j++) ++ for (i = 0; exports[j][i].name != NULL; i++) ++ if (strcmp(exports[j][i].name, name) == 0) { ++ *func = exports[j][i].func; ++ return 0; ++ } ++ ++ for (i = 0; i < num_pe_exports; i++) ++ if (strcmp(pe_exports[i].name, name) == 0) { ++ *func = pe_exports[i].addr; ++ return 0; ++ } ++ ++ return -1; ++} ++#endif // TEST_LOADER ++ ++static void *get_dll_init(char *name) ++{ ++ int i; ++ for (i = 0; i < num_pe_exports; i++) ++ if ((strcmp(pe_exports[i].dll, name) == 0) && ++ (strcmp(pe_exports[i].name, "DllInitialize") == 0)) ++ return (void *)pe_exports[i].addr; ++ return NULL; ++} ++ ++/* ++ * Find and validate the coff header ++ * ++ */ ++static int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr) ++{ ++ int i; ++ WORD attr; ++ PIMAGE_OPTIONAL_HEADER opt_hdr; ++ ++ /* Validate the "PE\0\0" signature */ ++ if (nt_hdr->Signature != IMAGE_NT_SIGNATURE) { ++ ERROR("is this driver file? bad signature %08x", ++ nt_hdr->Signature); ++ return -EINVAL; ++ } ++ ++ opt_hdr = &nt_hdr->OptionalHeader; ++ /* Make sure Image is PE32 or PE32+ */ ++#ifdef CONFIG_X86_64 ++ if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { ++ ERROR("kernel is 64-bit, but Windows driver is not 64-bit;" ++ "bad magic: %04X", opt_hdr->Magic); ++ return -EINVAL; ++ } ++#else ++ if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { ++ ERROR("kernel is 32-bit, but Windows driver is not 32-bit;" ++ "bad magic: %04X", opt_hdr->Magic); ++ return -EINVAL; ++ } ++#endif ++ ++ /* Validate the image for the current architecture. */ ++#ifdef CONFIG_X86_64 ++ if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) { ++ ERROR("kernel is 64-bit, but Windows driver is not 64-bit;" ++ " (PE signature is %04X)", nt_hdr->FileHeader.Machine); ++ return -EINVAL; ++ } ++#else ++ if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) { ++ ERROR("kernel is 32-bit, but Windows driver is not 32-bit;" ++ " (PE signature is %04X)", nt_hdr->FileHeader.Machine); ++ return -EINVAL; ++ } ++#endif ++ ++ /* Must have attributes */ ++#ifdef CONFIG_X86_64 ++ attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LARGE_ADDRESS_AWARE; ++#else ++ attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE; ++#endif ++ if ((nt_hdr->FileHeader.Characteristics & attr) != attr) ++ return -EINVAL; ++ ++ /* Must be relocatable */ ++ attr = IMAGE_FILE_RELOCS_STRIPPED; ++ if ((nt_hdr->FileHeader.Characteristics & attr)) ++ return -EINVAL; ++ ++ /* Make sure we have at least one section */ ++ if (nt_hdr->FileHeader.NumberOfSections == 0) ++ return -EINVAL; ++ ++ if (opt_hdr->SectionAlignment < opt_hdr->FileAlignment) { ++ ERROR("alignment mismatch: section: 0x%x, file: 0x%x", ++ opt_hdr->SectionAlignment, opt_hdr->FileAlignment); ++ return -EINVAL; ++ } ++ ++ DBGLINKER("number of datadictionary entries %d", ++ opt_hdr->NumberOfRvaAndSizes); ++ for (i = 0; i < opt_hdr->NumberOfRvaAndSizes; i++) { ++ DBGLINKER("datadirectory %s RVA:%X Size:%d", ++ (i <= IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR) ? ++ image_directory_name[i] : "unknown", ++ opt_hdr->DataDirectory[i].VirtualAddress, ++ opt_hdr->DataDirectory[i].Size); ++ } ++ ++ if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) ++ return IMAGE_FILE_EXECUTABLE_IMAGE; ++ if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_DLL)) ++ return IMAGE_FILE_DLL; ++ return -EINVAL; ++} ++ ++static int import(void *image, IMAGE_IMPORT_DESCRIPTOR *dirent, char *dll) ++{ ++ ULONG_PTR *lookup_tbl, *address_tbl; ++ char *symname = NULL; ++ int i; ++ int ret = 0; ++ generic_func adr; ++ ++ lookup_tbl = RVA2VA(image, dirent->u.OriginalFirstThunk, ULONG_PTR *); ++ address_tbl = RVA2VA(image, dirent->FirstThunk, ULONG_PTR *); ++ ++ for (i = 0; lookup_tbl[i]; i++) { ++ if (IMAGE_SNAP_BY_ORDINAL(lookup_tbl[i])) { ++ ERROR("ordinal import not supported: %llu", ++ (uint64_t)lookup_tbl[i]); ++ return -1; ++ } ++ else { ++ symname = RVA2VA(image, ++ ((lookup_tbl[i] & ++ ~IMAGE_ORDINAL_FLAG) + 2), char *); ++ } ++ ++ if (get_export(symname, &adr) < 0) { ++ ERROR("unknown symbol: %s:'%s'", dll, symname); ++ ret = -1; ++ } else { ++ DBGLINKER("found symbol: %s:%s: addr: %p, rva = %llu", ++ dll, symname, adr, (uint64_t)address_tbl[i]); ++ address_tbl[i] = (ULONG_PTR)adr; ++ } ++ } ++ return ret; ++} ++ ++static int read_exports(struct pe_image *pe) ++{ ++ IMAGE_EXPORT_DIRECTORY *export_dir_table; ++ uint32_t *export_addr_table; ++ int i; ++ uint32_t *name_table; ++ PIMAGE_OPTIONAL_HEADER opt_hdr; ++ IMAGE_DATA_DIRECTORY *export_data_dir; ++ ++ opt_hdr = &pe->nt_hdr->OptionalHeader; ++ export_data_dir = ++ &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; ++ ++ if (export_data_dir->Size == 0) { ++ DBGLINKER("no exports"); ++ return 0; ++ } ++ ++ export_dir_table = ++ RVA2VA(pe->image, export_data_dir->VirtualAddress, ++ IMAGE_EXPORT_DIRECTORY *); ++ ++ name_table = (unsigned int *)(pe->image + ++ export_dir_table->AddressOfNames); ++ export_addr_table = (uint32_t *) ++ (pe->image + export_dir_table->AddressOfFunctions); ++ ++ for (i = 0; i < export_dir_table->NumberOfNames; i++) { ++ ++ if (export_data_dir->VirtualAddress <= *export_addr_table || ++ *export_addr_table >= (export_data_dir->VirtualAddress + ++ export_data_dir->Size)) ++ DBGLINKER("forwarder rva"); ++ ++ DBGLINKER("export symbol: %s, at %p", ++ (char *)(pe->image + *name_table), ++ pe->image + *export_addr_table); ++ ++ pe_exports[num_pe_exports].dll = pe->name; ++ pe_exports[num_pe_exports].name = pe->image + *name_table; ++ pe_exports[num_pe_exports].addr = ++ pe->image + *export_addr_table; ++ ++ num_pe_exports++; ++ name_table++; ++ export_addr_table++; ++ } ++ return 0; ++} ++ ++static int fixup_imports(void *image, IMAGE_NT_HEADERS *nt_hdr) ++{ ++ int i; ++ char *name; ++ int ret = 0; ++ IMAGE_IMPORT_DESCRIPTOR *dirent; ++ IMAGE_DATA_DIRECTORY *import_data_dir; ++ PIMAGE_OPTIONAL_HEADER opt_hdr; ++ ++ opt_hdr = &nt_hdr->OptionalHeader; ++ import_data_dir = ++ &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; ++ dirent = RVA2VA(image, import_data_dir->VirtualAddress, ++ IMAGE_IMPORT_DESCRIPTOR *); ++ ++ for (i = 0; dirent[i].Name; i++) { ++ name = RVA2VA(image, dirent[i].Name, char*); ++ ++ DBGLINKER("imports from dll: %s", name); ++ ret += import(image, &dirent[i], name); ++ } ++ return ret; ++} ++ ++static int fixup_reloc(void *image, IMAGE_NT_HEADERS *nt_hdr) ++{ ++ ULONG_PTR base; ++ ULONG_PTR size; ++ IMAGE_BASE_RELOCATION *fixup_block; ++ IMAGE_DATA_DIRECTORY *base_reloc_data_dir; ++ PIMAGE_OPTIONAL_HEADER opt_hdr; ++ ++ opt_hdr = &nt_hdr->OptionalHeader; ++ base = opt_hdr->ImageBase; ++ base_reloc_data_dir = ++ &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; ++ if (base_reloc_data_dir->Size == 0) ++ return 0; ++ ++ fixup_block = RVA2VA(image, base_reloc_data_dir->VirtualAddress, ++ IMAGE_BASE_RELOCATION *); ++ DBGLINKER("fixup_block=%p, image=%p", fixup_block, image); ++ DBGLINKER("fixup_block info: %x %d", ++ fixup_block->VirtualAddress, fixup_block->SizeOfBlock); ++ ++ while (fixup_block->SizeOfBlock) { ++ int i; ++ WORD fixup, offset; ++ ++ size = (fixup_block->SizeOfBlock - ++ sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); ++ DBGLINKER("found %llu relocations in this block", ++ (uint64_t)size); ++ ++ for (i = 0; i < size; i++) { ++ fixup = fixup_block->TypeOffset[i]; ++ offset = fixup & 0xfff; ++ switch ((fixup >> 12) & 0x0f) { ++ case IMAGE_REL_BASED_ABSOLUTE: ++ break; ++ ++ case IMAGE_REL_BASED_HIGHLOW: { ++ uint32_t addr; ++ uint32_t *loc = ++ RVA2VA(image, ++ fixup_block->VirtualAddress + ++ offset, uint32_t *); ++ addr = RVA2VA(image, (*loc - base), uint32_t); ++ DBGLINKER("relocation: *%p (Val:%X)= %X", ++ loc, *loc, addr); ++ *loc = addr; ++ } ++ break; ++ ++ case IMAGE_REL_BASED_DIR64: { ++ uint64_t addr; ++ uint64_t *loc = ++ RVA2VA(image, ++ fixup_block->VirtualAddress + ++ offset, uint64_t *); ++ addr = RVA2VA(image, (*loc - base), uint64_t); ++ DBGLINKER("relocation: *%p (Val:%llX)= %llx", ++ loc, *loc, addr); ++ *loc = addr; ++ } ++ break; ++ ++ default: ++ ERROR("unknown fixup: %08X", ++ (fixup >> 12) & 0x0f); ++ return -EOPNOTSUPP; ++ break; ++ } ++ } ++ DBGLINKER("finished relocating block"); ++ ++ fixup_block = (IMAGE_BASE_RELOCATION *) ++ ((void *)fixup_block + fixup_block->SizeOfBlock); ++ }; ++ DBGLINKER("done relocating all"); ++ ++ return 0; ++} ++ ++/* Expand the image in memory if necessary. The image on disk does not ++ * necessarily maps the image of the driver in memory, so we have to ++ * re-write it in order to fulfill the sections alignments. The ++ * advantage to do that is that rva_to_va becomes a simple ++ * addition. */ ++static int fix_pe_image(struct pe_image *pe) ++{ ++ void *image; ++ IMAGE_SECTION_HEADER *sect_hdr; ++ int i, sections; ++ int image_size; ++ ++ if (pe->size == pe->opt_hdr->SizeOfImage) { ++ /* Nothing to do */ ++ return 0; ++ } ++ ++ image_size = pe->opt_hdr->SizeOfImage; ++#ifdef CONFIG_X86_64 ++#ifdef PAGE_KERNEL_EXECUTABLE ++ image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM, ++ PAGE_KERNEL_EXECUTABLE); ++#elif defined PAGE_KERNEL_EXEC ++ image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM, ++ PAGE_KERNEL_EXEC); ++#else ++#error x86_64 should have either PAGE_KERNEL_EXECUTABLE or PAGE_KERNEL_EXEC ++#endif ++#else ++#ifdef cpu_has_nx ++ /* hate to play with kernel macros, but PAGE_KERNEL_EXEC is ++ * not available to modules! */ ++ if (cpu_has_nx) ++ image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM, ++ __pgprot(__PAGE_KERNEL & ~_PAGE_NX)); ++ else ++ image = vmalloc(image_size); ++#else ++ image = vmalloc(image_size); ++#endif ++#endif ++ if (image == NULL) { ++ ERROR("failed to allocate enough space for new image:" ++ " %d bytes", image_size); ++ return -ENOMEM; ++ } ++ memset(image, 0, image_size); ++ ++ /* Copy all the headers, ie everything before the first section. */ ++ ++ sections = pe->nt_hdr->FileHeader.NumberOfSections; ++ sect_hdr = IMAGE_FIRST_SECTION(pe->nt_hdr); ++ ++ DBGLINKER("copying headers: %u bytes", sect_hdr->PointerToRawData); ++ ++ memcpy(image, pe->image, sect_hdr->PointerToRawData); ++ ++ /* Copy all the sections */ ++ for (i = 0; i < sections; i++) { ++ DBGLINKER("Copy section %s from %x to %x", ++ sect_hdr->Name, sect_hdr->PointerToRawData, ++ sect_hdr->VirtualAddress); ++ if (sect_hdr->VirtualAddress+sect_hdr->SizeOfRawData > ++ image_size) { ++ ERROR("Invalid section %s in driver", sect_hdr->Name); ++ vfree(image); ++ return -EINVAL; ++ } ++ ++ memcpy(image+sect_hdr->VirtualAddress, ++ pe->image + sect_hdr->PointerToRawData, ++ sect_hdr->SizeOfRawData); ++ sect_hdr++; ++ } ++ ++ vfree(pe->image); ++ pe->image = image; ++ pe->size = image_size; ++ ++ /* Update our internal pointers */ ++ pe->nt_hdr = (IMAGE_NT_HEADERS *) ++ (pe->image + ((IMAGE_DOS_HEADER *)pe->image)->e_lfanew); ++ pe->opt_hdr = &pe->nt_hdr->OptionalHeader; ++ ++ DBGLINKER("set nt headers: nt_hdr=%p, opt_hdr=%p, image=%p", ++ pe->nt_hdr, pe->opt_hdr, pe->image); ++ ++ return 0; ++} ++ ++#if defined(CONFIG_X86_64) ++static void fix_user_shared_data_addr(char *driver, unsigned long length) ++{ ++ unsigned long i, n, max_addr, *addr; ++ ++ TRACE1("fixing KI_USER_SHARED_DATA address in the driver"); ++ n = length - sizeof(unsigned long); ++ max_addr = KI_USER_SHARED_DATA + sizeof(kuser_shared_data); ++ for (i = 0; i < n; i++) { ++ addr = (unsigned long *)(driver + i); ++ if (*addr >= KI_USER_SHARED_DATA && *addr < max_addr) { ++ *addr -= KI_USER_SHARED_DATA; ++ *addr += (unsigned long)&kuser_shared_data; ++ kuser_shared_data.reserved1 = 1; ++ } ++ } ++} ++#endif ++ ++int link_pe_images(struct pe_image *pe_image, unsigned short n) ++{ ++ int i; ++ struct pe_image *pe; ++ ++#if DEBUG >= 1 ++ /* Sanity checks */ ++ CHECK_SZ(IMAGE_SECTION_HEADER, IMAGE_SIZEOF_SECTION_HEADER); ++ CHECK_SZ(IMAGE_FILE_HEADER, IMAGE_SIZEOF_FILE_HEADER); ++ CHECK_SZ(IMAGE_OPTIONAL_HEADER, IMAGE_SIZEOF_NT_OPTIONAL_HEADER); ++ CHECK_SZ(IMAGE_NT_HEADERS, 4 + IMAGE_SIZEOF_FILE_HEADER + ++ IMAGE_SIZEOF_NT_OPTIONAL_HEADER); ++ CHECK_SZ(IMAGE_DOS_HEADER, 0x40); ++ CHECK_SZ(IMAGE_EXPORT_DIRECTORY, 40); ++ CHECK_SZ(IMAGE_BASE_RELOCATION, 8); ++ CHECK_SZ(IMAGE_IMPORT_DESCRIPTOR, 20); ++#endif ++ ++ for (i = 0; i < n; i++) { ++ IMAGE_DOS_HEADER *dos_hdr; ++ pe = &pe_image[i]; ++ dos_hdr = pe->image; ++ ++ if (pe->size < sizeof(IMAGE_DOS_HEADER)) { ++ TRACE1("image too small: %d", pe->size); ++ return -EINVAL; ++ } ++ ++ pe->nt_hdr = ++ (IMAGE_NT_HEADERS *)(pe->image + dos_hdr->e_lfanew); ++ pe->opt_hdr = &pe->nt_hdr->OptionalHeader; ++ ++ pe->type = check_nt_hdr(pe->nt_hdr); ++ if (pe->type <= 0) { ++ TRACE1("type <= 0"); ++ return -EINVAL; ++ } ++ ++ if (fix_pe_image(pe)) { ++ TRACE1("bad PE image"); ++ return -EINVAL; ++ } ++ ++ if (read_exports(pe)) { ++ TRACE1("read exports failed"); ++ return -EINVAL; ++ } ++ } ++ ++ for (i = 0; i < n; i++) { ++ pe = &pe_image[i]; ++ ++ if (fixup_reloc(pe->image, pe->nt_hdr)) { ++ TRACE1("fixup reloc failed"); ++ return -EINVAL; ++ } ++ if (fixup_imports(pe->image, pe->nt_hdr)) { ++ TRACE1("fixup imports failed"); ++ return -EINVAL; ++ } ++#if defined(CONFIG_X86_64) ++ fix_user_shared_data_addr(pe_image[i].image, pe_image[i].size); ++#endif ++ flush_icache_range((unsigned long)pe->image, pe->size); ++ ++ pe->entry = ++ RVA2VA(pe->image, ++ pe->opt_hdr->AddressOfEntryPoint, void *); ++ TRACE1("entry is at %p, rva at %08X", pe->entry, ++ pe->opt_hdr->AddressOfEntryPoint); ++ } ++ ++ for (i = 0; i < n; i++) { ++ pe = &pe_image[i]; ++ ++ if (pe->type == IMAGE_FILE_DLL) { ++ struct unicode_string ustring; ++ char *buf = "0/0t0m0p00"; ++ int (*dll_entry)(struct unicode_string *ustring) ++ wstdcall; ++ ++ memset(&ustring, 0, sizeof(ustring)); ++ ustring.buf = (wchar_t *)buf; ++ dll_entry = (void *)get_dll_init(pe->name); ++ ++ TRACE1("calling dll_init at %p", dll_entry); ++ if (!dll_entry || dll_entry(&ustring)) ++ ERROR("DLL initialize failed for %s", ++ pe->name); ++ } ++ else if (pe->type != IMAGE_FILE_EXECUTABLE_IMAGE) ++ ERROR("illegal image type: %d", pe->type); ++ } ++ return 0; ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/pe_linker.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/pe_linker.h +--- linux-3.12.2/3rdparty/ndiswrapper/pe_linker.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/pe_linker.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,992 @@ ++/* ++ * This file is an excerpt of winnt.h from WINE, which bears the ++ * following copyright: ++ * ++ * Win32 definitions for Windows NT ++ * ++ * Copyright 1996 Alexandre Julliard ++ * ++ * This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/* ++ * File formats definitions ++ */ ++typedef struct _IMAGE_DOS_HEADER { ++ WORD e_magic; /* 00: MZ Header signature */ ++ WORD e_cblp; /* 02: Bytes on last page of file */ ++ WORD e_cp; /* 04: Pages in file */ ++ WORD e_crlc; /* 06: Relocations */ ++ WORD e_cparhdr; /* 08: Size of header in paragraphs */ ++ WORD e_minalloc; /* 0a: Minimum extra paragraphs needed */ ++ WORD e_maxalloc; /* 0c: Maximum extra paragraphs needed */ ++ WORD e_ss; /* 0e: Initial (relative) SS value */ ++ WORD e_sp; /* 10: Initial SP value */ ++ WORD e_csum; /* 12: Checksum */ ++ WORD e_ip; /* 14: Initial IP value */ ++ WORD e_cs; /* 16: Initial (relative) CS value */ ++ WORD e_lfarlc; /* 18: File address of relocation table */ ++ WORD e_ovno; /* 1a: Overlay number */ ++ WORD e_res[4]; /* 1c: Reserved words */ ++ WORD e_oemid; /* 24: OEM identifier (for e_oeminfo) */ ++ WORD e_oeminfo; /* 26: OEM information; e_oemid specific */ ++ WORD e_res2[10]; /* 28: Reserved words */ ++ DWORD e_lfanew; /* 3c: Offset to extended header */ ++} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; ++ ++#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ ++#define IMAGE_OS2_SIGNATURE 0x454E /* NE */ ++#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ ++#define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */ ++#define IMAGE_VXD_SIGNATURE 0x454C /* LE */ ++#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ ++ ++/* ++ * This is the Windows executable (NE) header. ++ * the name IMAGE_OS2_HEADER is misleading, but in the SDK this way. ++ */ ++typedef struct ++{ ++ WORD ne_magic; /* 00 NE signature 'NE' */ ++ BYTE ne_ver; /* 02 Linker version number */ ++ BYTE ne_rev; /* 03 Linker revision number */ ++ WORD ne_enttab; /* 04 Offset to entry table relative to NE */ ++ WORD ne_cbenttab; /* 06 Length of entry table in bytes */ ++ LONG ne_crc; /* 08 Checksum */ ++ WORD ne_flags; /* 0c Flags about segments in this file */ ++ WORD ne_autodata; /* 0e Automatic data segment number */ ++ WORD ne_heap; /* 10 Initial size of local heap */ ++ WORD ne_stack; /* 12 Initial size of stack */ ++ DWORD ne_csip; /* 14 Initial CS:IP */ ++ DWORD ne_sssp; /* 18 Initial SS:SP */ ++ WORD ne_cseg; /* 1c # of entries in segment table */ ++ WORD ne_cmod; /* 1e # of entries in module reference tab. */ ++ WORD ne_cbnrestab; /* 20 Length of nonresident-name table */ ++ WORD ne_segtab; /* 22 Offset to segment table */ ++ WORD ne_rsrctab; /* 24 Offset to resource table */ ++ WORD ne_restab; /* 26 Offset to resident-name table */ ++ WORD ne_modtab; /* 28 Offset to module reference table */ ++ WORD ne_imptab; /* 2a Offset to imported name table */ ++ DWORD ne_nrestab; /* 2c Offset to nonresident-name table */ ++ WORD ne_cmovent; /* 30 # of movable entry points */ ++ WORD ne_align; /* 32 Logical sector alignment shift count */ ++ WORD ne_cres; /* 34 # of resource segments */ ++ BYTE ne_exetyp; /* 36 Flags indicating target OS */ ++ BYTE ne_flagsothers; /* 37 Additional information flags */ ++ WORD ne_pretthunks; /* 38 Offset to return thunks */ ++ WORD ne_psegrefbytes; /* 3a Offset to segment ref. bytes */ ++ WORD ne_swaparea; /* 3c Reserved by Microsoft */ ++ WORD ne_expver; /* 3e Expected Windows version number */ ++} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; ++ ++typedef struct _IMAGE_VXD_HEADER { ++ WORD e32_magic; ++ BYTE e32_border; ++ BYTE e32_worder; ++ DWORD e32_level; ++ WORD e32_cpu; ++ WORD e32_os; ++ DWORD e32_ver; ++ DWORD e32_mflags; ++ DWORD e32_mpages; ++ DWORD e32_startobj; ++ DWORD e32_eip; ++ DWORD e32_stackobj; ++ DWORD e32_esp; ++ DWORD e32_pagesize; ++ DWORD e32_lastpagesize; ++ DWORD e32_fixupsize; ++ DWORD e32_fixupsum; ++ DWORD e32_ldrsize; ++ DWORD e32_ldrsum; ++ DWORD e32_objtab; ++ DWORD e32_objcnt; ++ DWORD e32_objmap; ++ DWORD e32_itermap; ++ DWORD e32_rsrctab; ++ DWORD e32_rsrccnt; ++ DWORD e32_restab; ++ DWORD e32_enttab; ++ DWORD e32_dirtab; ++ DWORD e32_dircnt; ++ DWORD e32_fpagetab; ++ DWORD e32_frectab; ++ DWORD e32_impmod; ++ DWORD e32_impmodcnt; ++ DWORD e32_impproc; ++ DWORD e32_pagesum; ++ DWORD e32_datapage; ++ DWORD e32_preload; ++ DWORD e32_nrestab; ++ DWORD e32_cbnrestab; ++ DWORD e32_nressum; ++ DWORD e32_autodata; ++ DWORD e32_debuginfo; ++ DWORD e32_debuglen; ++ DWORD e32_instpreload; ++ DWORD e32_instdemand; ++ DWORD e32_heapsize; ++ BYTE e32_res3[12]; ++ DWORD e32_winresoff; ++ DWORD e32_winreslen; ++ WORD e32_devid; ++ WORD e32_ddkver; ++} IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER; ++ ++/* These defines describe the meanings of the bits in the ++ Characteristics field */ ++ ++#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* No relocation info */ ++#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 ++#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 ++#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 ++#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 ++#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 ++#define IMAGE_FILE_16BIT_MACHINE 0x0040 ++#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 ++#define IMAGE_FILE_32BIT_MACHINE 0x0100 ++#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 ++#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 ++#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 ++#define IMAGE_FILE_SYSTEM 0x1000 ++#define IMAGE_FILE_DLL 0x2000 ++#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 ++#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 ++ ++/* These are the settings of the Machine field. */ ++#define IMAGE_FILE_MACHINE_UNKNOWN 0 ++#define IMAGE_FILE_MACHINE_I860 0x014d ++#define IMAGE_FILE_MACHINE_I386 0x014c ++#define IMAGE_FILE_MACHINE_R3000 0x0162 ++#define IMAGE_FILE_MACHINE_R4000 0x0166 ++#define IMAGE_FILE_MACHINE_R10000 0x0168 ++#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 ++#define IMAGE_FILE_MACHINE_ALPHA 0x0184 ++#define IMAGE_FILE_MACHINE_SH3 0x01a2 ++#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 ++#define IMAGE_FILE_MACHINE_SH3E 0x01a4 ++#define IMAGE_FILE_MACHINE_SH4 0x01a6 ++#define IMAGE_FILE_MACHINE_SH5 0x01a8 ++#define IMAGE_FILE_MACHINE_ARM 0x01c0 ++#define IMAGE_FILE_MACHINE_THUMB 0x01c2 ++#define IMAGE_FILE_MACHINE_AM33 0x01d3 ++#define IMAGE_FILE_MACHINE_POWERPC 0x01f0 ++#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 ++#define IMAGE_FILE_MACHINE_IA64 0x0200 ++#define IMAGE_FILE_MACHINE_MIPS16 0x0266 ++#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 ++#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 ++#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 ++#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 ++#define IMAGE_FILE_MACHINE_TRICORE 0x0520 ++#define IMAGE_FILE_MACHINE_CEF 0x0cef ++#define IMAGE_FILE_MACHINE_EBC 0x0ebc ++#define IMAGE_FILE_MACHINE_AMD64 0x8664 ++#define IMAGE_FILE_MACHINE_M32R 0x9041 ++#define IMAGE_FILE_MACHINE_CEE 0xc0ee ++ ++#define IMAGE_SIZEOF_FILE_HEADER 20 ++#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 ++#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 ++#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER32 224 ++#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER64 240 ++#define IMAGE_SIZEOF_SHORT_NAME 8 ++#define IMAGE_SIZEOF_SECTION_HEADER 40 ++#define IMAGE_SIZEOF_SYMBOL 18 ++#define IMAGE_SIZEOF_AUX_SYMBOL 18 ++#define IMAGE_SIZEOF_RELOCATION 10 ++#define IMAGE_SIZEOF_BASE_RELOCATION 8 ++#define IMAGE_SIZEOF_LINENUMBER 6 ++#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 ++ ++/* Possible Magic values */ ++#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x010b ++#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x020b ++#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x0107 ++ ++#ifdef CONFIG_X86_64 ++#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL_HEADER64 ++#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC ++#else ++#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL_HEADER32 ++#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC ++#endif ++ ++/* These are indexes into the DataDirectory array */ ++#define IMAGE_FILE_EXPORT_DIRECTORY 0 ++#define IMAGE_FILE_IMPORT_DIRECTORY 1 ++#define IMAGE_FILE_RESOURCE_DIRECTORY 2 ++#define IMAGE_FILE_EXCEPTION_DIRECTORY 3 ++#define IMAGE_FILE_SECURITY_DIRECTORY 4 ++#define IMAGE_FILE_BASE_RELOCATION_TABLE 5 ++#define IMAGE_FILE_DEBUG_DIRECTORY 6 ++#define IMAGE_FILE_DESCRIPTION_STRING 7 ++#define IMAGE_FILE_MACHINE_VALUE 8 /* Mips */ ++#define IMAGE_FILE_THREAD_LOCAL_STORAGE 9 ++#define IMAGE_FILE_CALLBACK_DIRECTORY 10 ++ ++/* Directory Entries, indices into the DataDirectory array */ ++ ++#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 ++#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 ++#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 ++#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 ++#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 ++#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 ++#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 ++#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 ++#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */ ++#define IMAGE_DIRECTORY_ENTRY_TLS 9 ++#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 ++#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 ++#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */ ++#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 ++#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 ++ ++/* Subsystem Values */ ++ ++#define IMAGE_SUBSYSTEM_UNKNOWN 0 ++#define IMAGE_SUBSYSTEM_NATIVE 1 ++#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI subsystem */ ++#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows character subsystem */ ++#define IMAGE_SUBSYSTEM_OS2_CUI 5 ++#define IMAGE_SUBSYSTEM_POSIX_CUI 7 ++#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 /* native Win9x driver */ ++#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 /* Windows CE subsystem */ ++#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 ++#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 ++#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 ++#define IMAGE_SUBSYSTEM_EFI_ROM 13 ++#define IMAGE_SUBSYSTEM_XBOX 14 ++ ++typedef struct _IMAGE_FILE_HEADER { ++ WORD Machine; ++ WORD NumberOfSections; ++ DWORD TimeDateStamp; ++ DWORD PointerToSymbolTable; ++ DWORD NumberOfSymbols; ++ WORD SizeOfOptionalHeader; ++ WORD Characteristics; ++} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; ++ ++typedef struct _IMAGE_DATA_DIRECTORY { ++ DWORD VirtualAddress; ++ DWORD Size; ++} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; ++ ++#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 ++ ++typedef struct _IMAGE_OPTIONAL_HEADER32 { ++ ++ /* Standard fields */ ++ ++ WORD Magic; ++ BYTE MajorLinkerVersion; ++ BYTE MinorLinkerVersion; ++ DWORD SizeOfCode; ++ DWORD SizeOfInitializedData; ++ DWORD SizeOfUninitializedData; ++ DWORD AddressOfEntryPoint; ++ DWORD BaseOfCode; ++ DWORD BaseOfData; ++ ++ /* NT additional fields */ ++ DWORD ImageBase; ++ DWORD SectionAlignment; ++ DWORD FileAlignment; ++ WORD MajorOperatingSystemVersion; ++ WORD MinorOperatingSystemVersion; ++ WORD MajorImageVersion; ++ WORD MinorImageVersion; ++ WORD MajorSubsystemVersion; ++ WORD MinorSubsystemVersion; ++ DWORD Win32VersionValue; ++ DWORD SizeOfImage; ++ DWORD SizeOfHeaders; ++ DWORD CheckSum; ++ WORD Subsystem; ++ WORD DllCharacteristics; ++ DWORD SizeOfStackReserve; ++ DWORD SizeOfStackCommit; ++ DWORD SizeOfHeapReserve; ++ DWORD SizeOfHeapCommit; ++ DWORD LoaderFlags; ++ DWORD NumberOfRvaAndSizes; ++ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; ++} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; ++ ++typedef struct _IMAGE_OPTIONAL_HEADER64 { ++ ++ /* Standard fields */ ++ ++ WORD Magic; ++ BYTE MajorLinkerVersion; ++ BYTE MinorLinkerVersion; ++ DWORD SizeOfCode; ++ DWORD SizeOfInitializedData; ++ DWORD SizeOfUninitializedData; ++ DWORD AddressOfEntryPoint; ++ DWORD BaseOfCode; ++ ++ /* NT additional fields */ ++ ULONGLONG ImageBase; ++ DWORD SectionAlignment; ++ DWORD FileAlignment; ++ WORD MajorOperatingSystemVersion; ++ WORD MinorOperatingSystemVersion; ++ WORD MajorImageVersion; ++ WORD MinorImageVersion; ++ WORD MajorSubsystemVersion; ++ WORD MinorSubsystemVersion; ++ DWORD Win32VersionValue; ++ DWORD SizeOfImage; ++ DWORD SizeOfHeaders; ++ DWORD CheckSum; ++ WORD Subsystem; ++ WORD DllCharacteristics; ++ ULONGLONG SizeOfStackReserve; ++ ULONGLONG SizeOfStackCommit; ++ ULONGLONG SizeOfHeapReserve; ++ ULONGLONG SizeOfHeapCommit; ++ DWORD LoaderFlags; ++ DWORD NumberOfRvaAndSizes; ++ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; ++} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; ++ ++#ifdef CONFIG_X86_64 ++typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; ++typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER; ++#else ++typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; ++typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER; ++#endif ++ ++typedef struct _IMAGE_NT_HEADERS32 { ++ DWORD Signature; /* "PE"\0\0 */ /* 0x00 */ ++ IMAGE_FILE_HEADER FileHeader; /* 0x04 */ ++ IMAGE_OPTIONAL_HEADER32 OptionalHeader; /* 0x18 */ ++} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; ++ ++typedef struct _IMAGE_NT_HEADERS64 { ++ DWORD Signature; /* "PE"\0\0 */ /* 0x00 */ ++ IMAGE_FILE_HEADER FileHeader; /* 0x04 */ ++ IMAGE_OPTIONAL_HEADER64 OptionalHeader; /* 0x18 */ ++} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; ++ ++#ifdef CONFIG_X86_64 ++typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; ++typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; ++#else ++typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; ++typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; ++#endif ++ ++#define IMAGE_SIZEOF_SHORT_NAME 8 ++ ++typedef struct _IMAGE_SECTION_HEADER { ++ BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; ++ union { ++ DWORD PhysicalAddress; ++ DWORD VirtualSize; ++ } Misc; ++ DWORD VirtualAddress; ++ DWORD SizeOfRawData; ++ DWORD PointerToRawData; ++ DWORD PointerToRelocations; ++ DWORD PointerToLinenumbers; ++ WORD NumberOfRelocations; ++ WORD NumberOfLinenumbers; ++ DWORD Characteristics; ++} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; ++ ++#define IMAGE_SIZEOF_SECTION_HEADER 40 ++ ++#define IMAGE_FIRST_SECTION(ntheader) \ ++((PIMAGE_SECTION_HEADER)((LPBYTE)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \ ++((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader)) ++ ++/* These defines are for the Characteristics bitfield. */ ++/* #define IMAGE_SCN_TYPE_REG 0x00000000 - Reserved */ ++/* #define IMAGE_SCN_TYPE_DSECT 0x00000001 - Reserved */ ++/* #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 - Reserved */ ++/* #define IMAGE_SCN_TYPE_GROUP 0x00000004 - Reserved */ ++#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved */ ++/* #define IMAGE_SCN_TYPE_COPY 0x00000010 - Reserved */ ++ ++#define IMAGE_SCN_CNT_CODE 0x00000020 ++#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 ++#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 ++ ++#define IMAGE_SCN_LNK_OTHER 0x00000100 ++#define IMAGE_SCN_LNK_INFO 0x00000200 ++/* #define IMAGE_SCN_TYPE_OVER 0x00000400 - Reserved */ ++#define IMAGE_SCN_LNK_REMOVE 0x00000800 ++#define IMAGE_SCN_LNK_COMDAT 0x00001000 ++ ++/* 0x00002000 - Reserved */ ++/* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */ ++#define IMAGE_SCN_MEM_FARDATA 0x00008000 ++ ++/* #define IMAGE_SCN_MEM_SYSHEAP 0x00010000 - Obsolete */ ++#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 ++#define IMAGE_SCN_MEM_16BIT 0x00020000 ++#define IMAGE_SCN_MEM_LOCKED 0x00040000 ++#define IMAGE_SCN_MEM_PRELOAD 0x00080000 ++ ++#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 ++#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 ++#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 ++#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 ++#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default */ ++#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 ++#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 ++#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 ++#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 ++#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 ++#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 ++#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 ++#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 ++#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 ++/* 0x00F00000 - Unused */ ++#define IMAGE_SCN_ALIGN_MASK 0x00F00000 ++ ++#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 ++ ++ ++#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 ++#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 ++#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 ++#define IMAGE_SCN_MEM_SHARED 0x10000000 ++#define IMAGE_SCN_MEM_EXECUTE 0x20000000 ++#define IMAGE_SCN_MEM_READ 0x40000000 ++#define IMAGE_SCN_MEM_WRITE 0x80000000 ++ ++typedef struct _IMAGE_SYMBOL { ++ union { ++ BYTE ShortName[8]; ++ struct { ++ DWORD Short; ++ DWORD Long; ++ } Name; ++ DWORD LongName[2]; ++ } N; ++ DWORD Value; ++ SHORT SectionNumber; ++ WORD Type; ++ BYTE StorageClass; ++ BYTE NumberOfAuxSymbols; ++} IMAGE_SYMBOL; ++typedef IMAGE_SYMBOL *PIMAGE_SYMBOL; ++ ++#define IMAGE_SIZEOF_SYMBOL 18 ++ ++typedef struct _IMAGE_LINENUMBER { ++ union { ++ DWORD SymbolTableIndex; ++ DWORD VirtualAddress; ++ } Type; ++ WORD Linenumber; ++} IMAGE_LINENUMBER; ++typedef IMAGE_LINENUMBER *PIMAGE_LINENUMBER; ++ ++#define IMAGE_SIZEOF_LINENUMBER 6 ++ ++typedef union _IMAGE_AUX_SYMBOL { ++ struct { ++ DWORD TagIndex; ++ union { ++ struct { ++ WORD Linenumber; ++ WORD Size; ++ } LnSz; ++ DWORD TotalSize; ++ } Misc; ++ union { ++ struct { ++ DWORD PointerToLinenumber; ++ DWORD PointerToNextFunction; ++ } Function; ++ struct { ++ WORD Dimension[4]; ++ } Array; ++ } FcnAry; ++ WORD TvIndex; ++ } Sym; ++ struct { ++ BYTE Name[IMAGE_SIZEOF_SYMBOL]; ++ } File; ++ struct { ++ DWORD Length; ++ WORD NumberOfRelocations; ++ WORD NumberOfLinenumbers; ++ DWORD CheckSum; ++ SHORT Number; ++ BYTE Selection; ++ } Section; ++} IMAGE_AUX_SYMBOL; ++typedef IMAGE_AUX_SYMBOL *PIMAGE_AUX_SYMBOL; ++ ++#define IMAGE_SIZEOF_AUX_SYMBOL 18 ++ ++#define IMAGE_SYM_UNDEFINED (SHORT)0 ++#define IMAGE_SYM_ABSOLUTE (SHORT)-1 ++#define IMAGE_SYM_DEBUG (SHORT)-2 ++ ++#define IMAGE_SYM_TYPE_NULL 0x0000 ++#define IMAGE_SYM_TYPE_VOID 0x0001 ++#define IMAGE_SYM_TYPE_CHAR 0x0002 ++#define IMAGE_SYM_TYPE_SHORT 0x0003 ++#define IMAGE_SYM_TYPE_INT 0x0004 ++#define IMAGE_SYM_TYPE_LONG 0x0005 ++#define IMAGE_SYM_TYPE_FLOAT 0x0006 ++#define IMAGE_SYM_TYPE_DOUBLE 0x0007 ++#define IMAGE_SYM_TYPE_STRUCT 0x0008 ++#define IMAGE_SYM_TYPE_UNION 0x0009 ++#define IMAGE_SYM_TYPE_ENUM 0x000A ++#define IMAGE_SYM_TYPE_MOE 0x000B ++#define IMAGE_SYM_TYPE_BYTE 0x000C ++#define IMAGE_SYM_TYPE_WORD 0x000D ++#define IMAGE_SYM_TYPE_UINT 0x000E ++#define IMAGE_SYM_TYPE_DWORD 0x000F ++#define IMAGE_SYM_TYPE_PCODE 0x8000 ++ ++#define IMAGE_SYM_DTYPE_NULL 0 ++#define IMAGE_SYM_DTYPE_POINTER 1 ++#define IMAGE_SYM_DTYPE_FUNCTION 2 ++#define IMAGE_SYM_DTYPE_ARRAY 3 ++ ++#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 ++#define IMAGE_SYM_CLASS_NULL 0x0000 ++#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001 ++#define IMAGE_SYM_CLASS_EXTERNAL 0x0002 ++#define IMAGE_SYM_CLASS_STATIC 0x0003 ++#define IMAGE_SYM_CLASS_REGISTER 0x0004 ++#define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005 ++#define IMAGE_SYM_CLASS_LABEL 0x0006 ++#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007 ++#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008 ++#define IMAGE_SYM_CLASS_ARGUMENT 0x0009 ++#define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A ++#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B ++#define IMAGE_SYM_CLASS_UNION_TAG 0x000C ++#define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D ++#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E ++#define IMAGE_SYM_CLASS_ENUM_TAG 0x000F ++#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010 ++#define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011 ++#define IMAGE_SYM_CLASS_BIT_FIELD 0x0012 ++ ++#define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044 ++#define IMAGE_SYM_CLASS_BLOCK 0x0064 ++#define IMAGE_SYM_CLASS_FUNCTION 0x0065 ++#define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066 ++#define IMAGE_SYM_CLASS_FILE 0x0067 ++#define IMAGE_SYM_CLASS_SECTION 0x0068 ++#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069 ++ ++#define N_BTMASK 0x000F ++#define N_TMASK 0x0030 ++#define N_TMASK1 0x00C0 ++#define N_TMASK2 0x00F0 ++#define N_BTSHFT 4 ++#define N_TSHIFT 2 ++ ++#define BTYPE(x) ((x) & N_BTMASK) ++ ++#ifndef ISPTR ++#define ISPTR(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT)) ++#endif ++ ++#ifndef ISFCN ++#define ISFCN(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT)) ++#endif ++ ++#ifndef ISARY ++#define ISARY(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT)) ++#endif ++ ++#ifndef ISTAG ++#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG) ++#endif ++ ++#ifndef INCREF ++#define INCREF(x) ((((x)&~N_BTMASK)<>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) ++#endif ++ ++#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 ++#define IMAGE_COMDAT_SELECT_ANY 2 ++#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 ++#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 ++#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 ++#define IMAGE_COMDAT_SELECT_LARGEST 6 ++#define IMAGE_COMDAT_SELECT_NEWEST 7 ++ ++#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 ++#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 ++#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 ++ ++/* Export module directory */ ++ ++typedef struct _IMAGE_EXPORT_DIRECTORY { ++ DWORD Characteristics; ++ DWORD TimeDateStamp; ++ WORD MajorVersion; ++ WORD MinorVersion; ++ DWORD Name; ++ DWORD Base; ++ DWORD NumberOfFunctions; ++ DWORD NumberOfNames; ++ DWORD AddressOfFunctions; ++ DWORD AddressOfNames; ++ DWORD AddressOfNameOrdinals; ++} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; ++ ++/* Import name entry */ ++typedef struct _IMAGE_IMPORT_BY_NAME { ++ WORD Hint; ++ BYTE Name[1]; ++} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; ++ ++/* Import thunk */ ++typedef struct _IMAGE_THUNK_DATA32 { ++ union { ++ DWORD ForwarderString; ++ DWORD Function; ++ DWORD Ordinal; ++ DWORD AddressOfData; ++ } u1; ++} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32; ++ ++typedef struct _IMAGE_THUNK_DATA64 { ++ union { ++ ULONGLONG ForwarderString; ++ ULONGLONG Function; ++ ULONGLONG Ordinal; ++ ULONGLONG AddressOfData; ++ } u1; ++} IMAGE_THUNK_DATA64,*PIMAGE_THUNK_DATA64; ++ ++#ifdef CONFIG_X86_64 ++typedef IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA; ++typedef PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA; ++#else ++typedef IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA; ++typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA; ++#endif ++ ++/* Import module directory */ ++ ++typedef struct __packed _IMAGE_IMPORT_DESCRIPTOR { ++ union { ++ DWORD Characteristics; /* 0 for terminating null ++ * import descriptor */ ++ DWORD OriginalFirstThunk; /* RVA to original unbound ++ * IAT */ ++ } u; ++ DWORD TimeDateStamp; /* 0 if not bound, ++ * -1 if bound, and real date\time stamp ++ * in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ++ * (new BIND) ++ * otherwise date/time stamp of DLL bound to ++ * (Old BIND) ++ */ ++ DWORD ForwarderChain; /* -1 if no forwarders */ ++ DWORD Name; ++ /* RVA to IAT (if bound this IAT has actual addresses) */ ++ DWORD FirstThunk; ++} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; ++ ++#define IMAGE_ORDINAL_FLAG32 0x80000000 ++#define IMAGE_ORDINAL_FLAG64 0x8000000000000000UL ++#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32) != 0) ++#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0) ++#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) ++ ++#ifdef CONFIG_X86_64 ++#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG64 ++#define IMAGE_SNAP_BY_ORDINAL IMAGE_SNAP_BY_ORDINAL64 ++#else ++#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG32 ++#define IMAGE_SNAP_BY_ORDINAL IMAGE_SNAP_BY_ORDINAL32 ++#endif ++ ++typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR ++{ ++ DWORD TimeDateStamp; ++ WORD OffsetModuleName; ++ WORD NumberOfModuleForwarderRefs; ++/* Array of zero or more IMAGE_BOUND_FORWARDER_REF follows */ ++} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR; ++ ++typedef struct _IMAGE_BOUND_FORWARDER_REF ++{ ++ DWORD TimeDateStamp; ++ WORD OffsetModuleName; ++ WORD Reserved; ++} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF; ++ ++typedef struct _IMAGE_BASE_RELOCATION ++{ ++ DWORD VirtualAddress; ++ DWORD SizeOfBlock; ++ WORD TypeOffset[0]; ++} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; ++ ++typedef struct _IMAGE_RELOCATION ++{ ++ union { ++ DWORD VirtualAddress; ++ DWORD RelocCount; ++ } DUMMYUNIONNAME; ++ DWORD SymbolTableIndex; ++ WORD Type; ++} IMAGE_RELOCATION, *PIMAGE_RELOCATION; ++ ++#define IMAGE_SIZEOF_RELOCATION 10 ++ ++/* generic relocation types */ ++#define IMAGE_REL_BASED_ABSOLUTE 0 ++#define IMAGE_REL_BASED_HIGH 1 ++#define IMAGE_REL_BASED_LOW 2 ++#define IMAGE_REL_BASED_HIGHLOW 3 ++#define IMAGE_REL_BASED_HIGHADJ 4 ++#define IMAGE_REL_BASED_MIPS_JMPADDR 5 ++#define IMAGE_REL_BASED_SECTION 6 ++#define IMAGE_REL_BASED_REL 7 ++#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 ++#define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */ ++#define IMAGE_REL_BASED_DIR64 10 ++#define IMAGE_REL_BASED_HIGH3ADJ 11 ++ ++/* I386 relocation types */ ++#define IMAGE_REL_I386_ABSOLUTE 0 ++#define IMAGE_REL_I386_DIR16 1 ++#define IMAGE_REL_I386_REL16 2 ++#define IMAGE_REL_I386_DIR32 6 ++#define IMAGE_REL_I386_DIR32NB 7 ++#define IMAGE_REL_I386_SEG12 9 ++#define IMAGE_REL_I386_SECTION 10 ++#define IMAGE_REL_I386_SECREL 11 ++#define IMAGE_REL_I386_REL32 20 ++ ++/* MIPS relocation types */ ++#define IMAGE_REL_MIPS_ABSOLUTE 0x0000 ++#define IMAGE_REL_MIPS_REFHALF 0x0001 ++#define IMAGE_REL_MIPS_REFWORD 0x0002 ++#define IMAGE_REL_MIPS_JMPADDR 0x0003 ++#define IMAGE_REL_MIPS_REFHI 0x0004 ++#define IMAGE_REL_MIPS_REFLO 0x0005 ++#define IMAGE_REL_MIPS_GPREL 0x0006 ++#define IMAGE_REL_MIPS_LITERAL 0x0007 ++#define IMAGE_REL_MIPS_SECTION 0x000A ++#define IMAGE_REL_MIPS_SECREL 0x000B ++#define IMAGE_REL_MIPS_SECRELLO 0x000C ++#define IMAGE_REL_MIPS_SECRELHI 0x000D ++#define IMAGE_REL_MIPS_JMPADDR16 0x0010 ++#define IMAGE_REL_MIPS_REFWORDNB 0x0022 ++#define IMAGE_REL_MIPS_PAIR 0x0025 ++ ++/* ALPHA relocation types */ ++#define IMAGE_REL_ALPHA_ABSOLUTE 0x0000 ++#define IMAGE_REL_ALPHA_REFLONG 0x0001 ++#define IMAGE_REL_ALPHA_REFQUAD 0x0002 ++#define IMAGE_REL_ALPHA_GPREL 0x0003 ++#define IMAGE_REL_ALPHA_LITERAL 0x0004 ++#define IMAGE_REL_ALPHA_LITUSE 0x0005 ++#define IMAGE_REL_ALPHA_GPDISP 0x0006 ++#define IMAGE_REL_ALPHA_BRADDR 0x0007 ++#define IMAGE_REL_ALPHA_HINT 0x0008 ++#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x0009 ++#define IMAGE_REL_ALPHA_REFHI 0x000A ++#define IMAGE_REL_ALPHA_REFLO 0x000B ++#define IMAGE_REL_ALPHA_PAIR 0x000C ++#define IMAGE_REL_ALPHA_MATCH 0x000D ++#define IMAGE_REL_ALPHA_SECTION 0x000E ++#define IMAGE_REL_ALPHA_SECREL 0x000F ++#define IMAGE_REL_ALPHA_REFLONGNB 0x0010 ++#define IMAGE_REL_ALPHA_SECRELLO 0x0011 ++#define IMAGE_REL_ALPHA_SECRELHI 0x0012 ++#define IMAGE_REL_ALPHA_REFQ3 0x0013 ++#define IMAGE_REL_ALPHA_REFQ2 0x0014 ++#define IMAGE_REL_ALPHA_REFQ1 0x0015 ++#define IMAGE_REL_ALPHA_GPRELLO 0x0016 ++#define IMAGE_REL_ALPHA_GPRELHI 0x0017 ++ ++/* PowerPC relocation types */ ++#define IMAGE_REL_PPC_ABSOLUTE 0x0000 ++#define IMAGE_REL_PPC_ADDR64 0x0001 ++#define IMAGE_REL_PPC_ADDR 0x0002 ++#define IMAGE_REL_PPC_ADDR24 0x0003 ++#define IMAGE_REL_PPC_ADDR16 0x0004 ++#define IMAGE_REL_PPC_ADDR14 0x0005 ++#define IMAGE_REL_PPC_REL24 0x0006 ++#define IMAGE_REL_PPC_REL14 0x0007 ++#define IMAGE_REL_PPC_TOCREL16 0x0008 ++#define IMAGE_REL_PPC_TOCREL14 0x0009 ++#define IMAGE_REL_PPC_ADDR32NB 0x000A ++#define IMAGE_REL_PPC_SECREL 0x000B ++#define IMAGE_REL_PPC_SECTION 0x000C ++#define IMAGE_REL_PPC_IFGLUE 0x000D ++#define IMAGE_REL_PPC_IMGLUE 0x000E ++#define IMAGE_REL_PPC_SECREL16 0x000F ++#define IMAGE_REL_PPC_REFHI 0x0010 ++#define IMAGE_REL_PPC_REFLO 0x0011 ++#define IMAGE_REL_PPC_PAIR 0x0012 ++#define IMAGE_REL_PPC_SECRELLO 0x0013 ++#define IMAGE_REL_PPC_SECRELHI 0x0014 ++#define IMAGE_REL_PPC_GPREL 0x0015 ++#define IMAGE_REL_PPC_TYPEMASK 0x00FF ++/* modifier bits */ ++#define IMAGE_REL_PPC_NEG 0x0100 ++#define IMAGE_REL_PPC_BRTAKEN 0x0200 ++#define IMAGE_REL_PPC_BRNTAKEN 0x0400 ++#define IMAGE_REL_PPC_TOCDEFN 0x0800 ++ ++/* SH3 ? relocation type */ ++#define IMAGE_REL_SH3_ABSOLUTE 0x0000 ++#define IMAGE_REL_SH3_DIRECT16 0x0001 ++#define IMAGE_REL_SH3_DIRECT 0x0002 ++#define IMAGE_REL_SH3_DIRECT8 0x0003 ++#define IMAGE_REL_SH3_DIRECT8_WORD 0x0004 ++#define IMAGE_REL_SH3_DIRECT8_LONG 0x0005 ++#define IMAGE_REL_SH3_DIRECT4 0x0006 ++#define IMAGE_REL_SH3_DIRECT4_WORD 0x0007 ++#define IMAGE_REL_SH3_DIRECT4_LONG 0x0008 ++#define IMAGE_REL_SH3_PCREL8_WORD 0x0009 ++#define IMAGE_REL_SH3_PCREL8_LONG 0x000A ++#define IMAGE_REL_SH3_PCREL12_WORD 0x000B ++#define IMAGE_REL_SH3_STARTOF_SECTION 0x000C ++#define IMAGE_REL_SH3_SIZEOF_SECTION 0x000D ++#define IMAGE_REL_SH3_SECTION 0x000E ++#define IMAGE_REL_SH3_SECREL 0x000F ++#define IMAGE_REL_SH3_DIRECT32_NB 0x0010 ++ ++/* ARM (Archimedes?) relocation types */ ++#define IMAGE_REL_ARM_ABSOLUTE 0x0000 ++#define IMAGE_REL_ARM_ADDR 0x0001 ++#define IMAGE_REL_ARM_ADDR32NB 0x0002 ++#define IMAGE_REL_ARM_BRANCH24 0x0003 ++#define IMAGE_REL_ARM_BRANCH11 0x0004 ++#define IMAGE_REL_ARM_SECTION 0x000E ++#define IMAGE_REL_ARM_SECREL 0x000F ++ ++/* IA64 relocation types */ ++#define IMAGE_REL_IA64_ABSOLUTE 0x0000 ++#define IMAGE_REL_IA64_IMM14 0x0001 ++#define IMAGE_REL_IA64_IMM22 0x0002 ++#define IMAGE_REL_IA64_IMM64 0x0003 ++#define IMAGE_REL_IA64_DIR 0x0004 ++#define IMAGE_REL_IA64_DIR64 0x0005 ++#define IMAGE_REL_IA64_PCREL21B 0x0006 ++#define IMAGE_REL_IA64_PCREL21M 0x0007 ++#define IMAGE_REL_IA64_PCREL21F 0x0008 ++#define IMAGE_REL_IA64_GPREL22 0x0009 ++#define IMAGE_REL_IA64_LTOFF22 0x000A ++#define IMAGE_REL_IA64_SECTION 0x000B ++#define IMAGE_REL_IA64_SECREL22 0x000C ++#define IMAGE_REL_IA64_SECREL64I 0x000D ++#define IMAGE_REL_IA64_SECREL 0x000E ++#define IMAGE_REL_IA64_LTOFF64 0x000F ++#define IMAGE_REL_IA64_DIR32NB 0x0010 ++#define IMAGE_REL_IA64_RESERVED_11 0x0011 ++#define IMAGE_REL_IA64_RESERVED_12 0x0012 ++#define IMAGE_REL_IA64_RESERVED_13 0x0013 ++#define IMAGE_REL_IA64_RESERVED_14 0x0014 ++#define IMAGE_REL_IA64_RESERVED_15 0x0015 ++#define IMAGE_REL_IA64_RESERVED_16 0x0016 ++#define IMAGE_REL_IA64_ADDEND 0x001F ++ ++/* archive format */ ++ ++#define IMAGE_ARCHIVE_START_SIZE 8 ++#define IMAGE_ARCHIVE_START "!\n" ++#define IMAGE_ARCHIVE_END "`\n" ++#define IMAGE_ARCHIVE_PAD "\n" ++#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " ++#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " ++ ++typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER ++{ ++ BYTE Name[16]; ++ BYTE Date[12]; ++ BYTE UserID[6]; ++ BYTE GroupID[6]; ++ BYTE Mode[8]; ++ BYTE Size[10]; ++ BYTE EndHeader[2]; ++} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; ++ ++#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 ++ ++/* ++ * Resource directory stuff ++ */ ++typedef struct _IMAGE_RESOURCE_DIRECTORY { ++ DWORD Characteristics; ++ DWORD TimeDateStamp; ++ WORD MajorVersion; ++ WORD MinorVersion; ++ WORD NumberOfNamedEntries; ++ WORD NumberOfIdEntries; ++ /* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */ ++} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY; ++ ++#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 ++#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 ++ ++typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { ++ union { ++ struct { ++#ifdef BITFIELDS_BIGENDIAN ++ unsigned NameIsString:1; ++ unsigned NameOffset:31; ++#else ++ unsigned NameOffset:31; ++ unsigned NameIsString:1; ++#endif ++ } DUMMYSTRUCTNAME1; ++ DWORD Name; ++ struct { ++#ifdef WORDS_BIGENDIAN ++ WORD __pad; ++ WORD Id; ++#else ++ WORD Id; ++ WORD __pad; ++#endif ++ } DUMMYSTRUCTNAME2; ++ } DUMMYUNIONNAME1; ++ union { ++ DWORD OffsetToData; ++ struct { ++#ifdef BITFIELDS_BIGENDIAN ++ unsigned DataIsDirectory:1; ++ unsigned OffsetToDirectory:31; ++#else ++ unsigned OffsetToDirectory:31; ++ unsigned DataIsDirectory:1; ++#endif ++ } DUMMYSTRUCTNAME3; ++ } DUMMYUNIONNAME2; ++} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY; ++ ++ ++typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { ++ WORD Length; ++ CHAR NameString[ 1 ]; ++} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING; +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/pnp.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/pnp.c +--- linux-3.12.2/3rdparty/ndiswrapper/pnp.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/pnp.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,697 @@ ++/* ++ * Copyright (C) 2005 Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "usb.h" ++#include "pnp.h" ++#include "wrapndis.h" ++#include "loader.h" ++ ++/* Functions callable from the NDIS driver */ ++wstdcall NTSTATUS pdoDispatchDeviceControl(struct device_object *pdo, ++ struct irp *irp); ++wstdcall NTSTATUS pdoDispatchPnp(struct device_object *pdo, struct irp *irp); ++wstdcall NTSTATUS pdoDispatchPower(struct device_object *pdo, struct irp *irp); ++ ++static NTSTATUS start_pdo(struct device_object *pdo) ++{ ++ int i, ret, count, resources_size; ++ struct wrap_device *wd; ++ struct pci_dev *pdev; ++ struct cm_partial_resource_descriptor *entry; ++ struct cm_partial_resource_list *partial_resource_list; ++ ++ ENTER1("%p, %p", pdo, pdo->reserved); ++ wd = pdo->reserved; ++ if (ntoskernel_init_device(wd)) ++ EXIT1(return STATUS_FAILURE); ++ if (wrap_is_usb_bus(wd->dev_bus)) { ++ if (usb_init_device(wd)) { ++ ntoskernel_exit_device(wd); ++ EXIT1(return STATUS_FAILURE); ++ } ++ EXIT1(return STATUS_SUCCESS); ++ } ++ if (!wrap_is_pci_bus(wd->dev_bus)) ++ EXIT1(return STATUS_SUCCESS); ++ pdev = wd->pci.pdev; ++ ret = pci_enable_device(pdev); ++ if (ret) { ++ ERROR("couldn't enable PCI device: %x", ret); ++ return STATUS_FAILURE; ++ } ++ ret = pci_request_regions(pdev, DRIVER_NAME); ++ if (ret) { ++ ERROR("couldn't request PCI regions: %x", ret); ++ goto err_enable; ++ } ++ pci_set_power_state(pdev, PCI_D0); ++#ifdef CONFIG_X86_64 ++ /* 64-bit broadcom driver doesn't work if DMA is allocated ++ * from over 1GB */ ++ if (wd->vendor == 0x14e4) { ++ if (pci_set_dma_mask(pdev, DMA_BIT_MASK(30)) || ++ pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(30))) ++ WARNING("couldn't set DMA mask; this driver " ++ "may not work with more than 1GB RAM"); ++ } ++#endif ++ /* IRQ resource entry is filled in from pdev, instead of ++ * pci_resource macros */ ++ for (i = count = 0; pci_resource_start(pdev, i); i++) ++ if ((pci_resource_flags(pdev, i) & IORESOURCE_MEM) || ++ (pci_resource_flags(pdev, i) & IORESOURCE_IO)) ++ count++; ++ /* space for entry for IRQ is already in ++ * cm_partial_resource_list */ ++ resources_size = sizeof(struct cm_resource_list) + ++ sizeof(struct cm_partial_resource_descriptor) * count; ++ TRACE2("resources: %d, %d", count, resources_size); ++ wd->resource_list = kzalloc(resources_size, GFP_KERNEL); ++ if (!wd->resource_list) { ++ WARNING("couldn't allocate memory"); ++ goto err_regions; ++ } ++ wd->resource_list->count = 1; ++ wd->resource_list->list[0].interface_type = PCIBus; ++ /* bus_number is not used by WDM drivers */ ++ wd->resource_list->list[0].bus_number = pdev->bus->number; ++ ++ partial_resource_list = ++ &wd->resource_list->list->partial_resource_list; ++ partial_resource_list->version = 1; ++ partial_resource_list->revision = 1; ++ partial_resource_list->count = count + 1; ++ ++ for (i = count = 0; pci_resource_start(pdev, i); i++) { ++ entry = &partial_resource_list->partial_descriptors[count]; ++ TRACE2("%d", count); ++ if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { ++ entry->type = CmResourceTypeMemory; ++ entry->flags = CM_RESOURCE_MEMORY_READ_WRITE; ++ entry->share = CmResourceShareDeviceExclusive; ++ } else if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { ++ entry->type = CmResourceTypePort; ++ entry->flags = CM_RESOURCE_PORT_IO; ++ entry->share = CmResourceShareDeviceExclusive; ++#if 0 ++ } else if (pci_resource_flags(pdev, i) & IORESOURCE_DMA) { ++ /* it looks like no driver uses this resource */ ++ typeof(pci_resource_flags(pdev, 0)) flags; ++ entry->type = CmResourceTypeDma; ++ flags = pci_resource_flags(pdev, i); ++ if (flags & IORESOURCE_DMA_TYPEA) ++ entry->flags |= CM_RESOURCE_DMA_TYPE_A; ++ else if (flags & IORESOURCE_DMA_TYPEB) ++ entry->flags |= CM_RESOURCE_DMA_TYPE_B; ++ else if (flags & IORESOURCE_DMA_TYPEF) ++ entry->flags |= CM_RESOURCE_DMA_TYPE_F; ++ if (flags & IORESOURCE_DMA_8BIT) ++ entry->flags |= CM_RESOURCE_DMA_8; ++ else if (flags & IORESOURCE_DMA_16BIT) ++ entry->flags |= CM_RESOURCE_DMA_16; ++ /* what about 32bit DMA? */ ++ else if (flags & IORESOURCE_DMA_8AND16BIT) ++ entry->flags |= CM_RESOURCE_DMA_8_AND_16; ++ if (flags & IORESOURCE_DMA_MASTER) ++ entry->flags |= CM_RESOURCE_DMA_BUS_MASTER; ++ entry->u.dma.channel = pci_resource_start(pdev, i); ++ /* what should this be? */ ++ entry->u.dma.port = 1; ++#endif ++ } else ++ continue; ++ /* TODO: Add other resource types? */ ++ entry->u.generic.start = ++ (ULONG_PTR)pci_resource_start(pdev, i); ++ entry->u.generic.length = pci_resource_len(pdev, i); ++ count++; ++ } ++ ++ /* put IRQ resource at the end */ ++ entry = &partial_resource_list->partial_descriptors[count++]; ++ entry->type = CmResourceTypeInterrupt; ++ entry->flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; ++ /* we assume all devices use shared IRQ */ ++ entry->share = CmResourceShareShared; ++ /* as per documentation, interrupt level should be DIRQL, but ++ * examples from DDK as well some drivers, such as AR5211, ++ * RT8180L use interrupt level as interrupt vector also in ++ * NdisMRegisterInterrupt */ ++ entry->u.interrupt.level = pdev->irq; ++ entry->u.interrupt.vector = pdev->irq; ++ entry->u.interrupt.affinity = -1; ++ ++ TRACE2("resource list count %d, irq: %d", ++ partial_resource_list->count, pdev->irq); ++ pci_set_drvdata(pdev, wd); ++ EXIT1(return STATUS_SUCCESS); ++err_regions: ++ pci_release_regions(pdev); ++err_enable: ++ pci_disable_device(pdev); ++ wd->pci.pdev = NULL; ++ wd->pdo = NULL; ++ EXIT1(return STATUS_FAILURE); ++} ++ ++static void remove_pdo(struct device_object *pdo) ++{ ++ struct wrap_device *wd = pdo->reserved; ++ ++ ntoskernel_exit_device(wd); ++ if (wrap_is_pci_bus(wd->dev_bus)) { ++ struct pci_dev *pdev = wd->pci.pdev; ++ pci_release_regions(pdev); ++ pci_disable_device(pdev); ++ wd->pci.pdev = NULL; ++ pci_set_drvdata(pdev, NULL); ++ } else if (wrap_is_usb_bus(wd->dev_bus)) { ++ usb_exit_device(wd); ++ } ++ kfree(wd->resource_list); ++ wd->resource_list = NULL; ++ return; ++} ++ ++static NTSTATUS IoSendIrpTopDev(struct device_object *dev_obj, ULONG major_fn, ++ ULONG minor_fn, struct io_stack_location *sl) ++{ ++ NTSTATUS status; ++ struct nt_event event; ++ struct irp *irp; ++ struct io_stack_location *irp_sl; ++ struct device_object *top_dev = IoGetAttachedDeviceReference(dev_obj); ++ ++ KeInitializeEvent(&event, NotificationEvent, FALSE); ++ irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, top_dev, NULL, 0, NULL, ++ &event, NULL); ++ irp->io_status.status = STATUS_NOT_IMPLEMENTED; ++ irp->io_status.info = 0; ++ irp_sl = IoGetNextIrpStackLocation(irp); ++ if (sl) ++ memcpy(irp_sl, sl, sizeof(*irp_sl)); ++ irp_sl->major_fn = major_fn; ++ irp_sl->minor_fn = minor_fn; ++ status = IoCallDriver(top_dev, irp); ++ if (status == STATUS_PENDING) { ++ KeWaitForSingleObject(&event, Executive, KernelMode, ++ FALSE, NULL); ++ status = irp->io_status.status; ++ } ++ ObDereferenceObject(top_dev); ++ return status; ++} ++ ++wstdcall NTSTATUS pdoDispatchDeviceControl(struct device_object *pdo, ++ struct irp *irp) ++{ ++ NTSTATUS status; ++ struct wrap_device *wd = pdo->reserved; ++ ++ DUMP_IRP(irp); ++ (void)wd; ++ if (wrap_is_usb_bus(wd->dev_bus)) { ++ status = wrap_submit_irp(pdo, irp); ++ IOTRACE("status: %08X", status); ++ if (status != STATUS_PENDING) ++ IoCompleteRequest(irp, IO_NO_INCREMENT); ++ } else { ++ status = irp->io_status.status = STATUS_NOT_IMPLEMENTED; ++ IoCompleteRequest(irp, IO_NO_INCREMENT); ++ } ++ IOEXIT(return status); ++} ++WIN_FUNC_DECL(pdoDispatchDeviceControl,2) ++ ++wstdcall NTSTATUS pdoDispatchPnp(struct device_object *pdo, struct irp *irp) ++{ ++ struct io_stack_location *irp_sl; ++ NTSTATUS status; ++ struct wrap_device *wd = pdo->reserved; ++ ++ irp_sl = IoGetCurrentIrpStackLocation(irp); ++ TRACE2("%p %d:%d", pdo, irp_sl->major_fn, irp_sl->minor_fn); ++ switch (irp_sl->minor_fn) { ++ case IRP_MN_START_DEVICE: ++ status = start_pdo(pdo); ++ break; ++ case IRP_MN_QUERY_STOP_DEVICE: ++ case IRP_MN_STOP_DEVICE: ++ case IRP_MN_QUERY_REMOVE_DEVICE: ++ status = STATUS_SUCCESS; ++ break; ++ case IRP_MN_REMOVE_DEVICE: ++ remove_pdo(pdo); ++ status = STATUS_SUCCESS; ++ break; ++ case IRP_MN_QUERY_INTERFACE: ++ if (wrap_is_usb_bus(wd->dev_bus)) ++ status = usb_query_interface(wd, irp_sl); ++ else ++ status = STATUS_NOT_IMPLEMENTED; ++ break; ++ default: ++ TRACE2("fn %d not implemented", irp_sl->minor_fn); ++ status = STATUS_SUCCESS; ++ break; ++ } ++ irp->io_status.status = status; ++ TRACE2("status: %08X", status); ++ IoCompleteRequest(irp, IO_NO_INCREMENT); ++ IOEXIT(return status); ++} ++WIN_FUNC_DECL(pdoDispatchPnp,2) ++ ++wstdcall NTSTATUS pdoDispatchPower(struct device_object *pdo, struct irp *irp) ++{ ++ struct io_stack_location *irp_sl; ++ struct wrap_device *wd; ++ union power_state power_state; ++ struct pci_dev *pdev; ++ NTSTATUS status; ++ ++ irp_sl = IoGetCurrentIrpStackLocation(irp); ++ wd = pdo->reserved; ++ TRACE2("pdo: %p, fn: %d:%d, wd: %p", ++ pdo, irp_sl->major_fn, irp_sl->minor_fn, wd); ++ switch (irp_sl->minor_fn) { ++ case IRP_MN_WAIT_WAKE: ++ /* TODO: this is not complete/correct */ ++ TRACE2("state: %d, completion: %p", ++ irp_sl->params.power.state.system_state, ++ irp_sl->completion_routine); ++ IoMarkIrpPending(irp); ++ status = STATUS_PENDING; ++ break; ++ case IRP_MN_SET_POWER: ++ power_state = irp_sl->params.power.state; ++ if (power_state.device_state == PowerDeviceD0) { ++ TRACE2("resuming %p", wd); ++ if (wrap_is_pci_bus(wd->dev_bus)) { ++ pdev = wd->pci.pdev; ++ pci_restore_state(pdev); ++ if (wd->pci.wake_state == PowerDeviceD3) { ++ pci_enable_wake(wd->pci.pdev, ++ PCI_D3hot, 0); ++ pci_enable_wake(wd->pci.pdev, ++ PCI_D3cold, 0); ++ } ++ pci_set_power_state(pdev, PCI_D0); ++ } else if (wrap_is_usb_bus(wd->dev_bus)) { ++ wrap_resume_urbs(wd); ++ } ++ } else { ++ TRACE2("suspending device %p", wd); ++ if (wrap_is_pci_bus(wd->dev_bus)) { ++ pdev = wd->pci.pdev; ++ pci_save_state(pdev); ++ TRACE2("%d", wd->pci.wake_state); ++ if (wd->pci.wake_state == PowerDeviceD3) { ++ pci_enable_wake(wd->pci.pdev, ++ PCI_D3hot, 1); ++ pci_enable_wake(wd->pci.pdev, ++ PCI_D3cold, 1); ++ } ++ pci_set_power_state(pdev, PCI_D3hot); ++ } else if (wrap_is_usb_bus(wd->dev_bus)) { ++ wrap_suspend_urbs(wd); ++ } ++ } ++ status = STATUS_SUCCESS; ++ break; ++ case IRP_MN_QUERY_POWER: ++ status = STATUS_SUCCESS; ++ break; ++ default: ++ TRACE2("fn %d not implemented", irp_sl->minor_fn); ++ status = STATUS_SUCCESS; ++ break; ++ } ++ irp->io_status.status = status; ++ IoCompleteRequest(irp, IO_NO_INCREMENT); ++ return status; ++} ++WIN_FUNC_DECL(pdoDispatchPower,2) ++ ++static NTSTATUS pnp_set_device_power_state(struct wrap_device *wd, ++ enum device_power_state state) ++{ ++ NTSTATUS status; ++ struct device_object *pdo; ++ struct io_stack_location irp_sl; ++ ++ pdo = wd->pdo; ++ IOTRACE("%p, %p", pdo, IoGetAttachedDevice(pdo)); ++ memset(&irp_sl, 0, sizeof(irp_sl)); ++ irp_sl.params.power.state.device_state = state; ++ irp_sl.params.power.type = DevicePowerState; ++ if (state > PowerDeviceD0) { ++ status = IoSendIrpTopDev(pdo, IRP_MJ_POWER, IRP_MN_QUERY_POWER, ++ &irp_sl); ++ if (status != STATUS_SUCCESS) { ++ TRACE1("query of power to %d returns %08X", ++ state, status); ++ EXIT1(return status); ++ } ++ } ++ status = IoSendIrpTopDev(pdo, IRP_MJ_POWER, IRP_MN_SET_POWER, &irp_sl); ++ if (status != STATUS_SUCCESS) ++ WARNING("setting power to %d failed: %08X", state, status); ++ EXIT1(return status); ++} ++ ++static NTSTATUS pnp_start_device(struct wrap_device *wd) ++{ ++ struct device_object *fdo; ++ struct device_object *pdo; ++ struct io_stack_location irp_sl; ++ NTSTATUS status; ++ ++ pdo = wd->pdo; ++ /* TODO: for now we use same resources for both translated ++ * resources and raw resources */ ++ memset(&irp_sl, 0, sizeof(irp_sl)); ++ irp_sl.params.start_device.allocated_resources = ++ wd->resource_list; ++ irp_sl.params.start_device.allocated_resources_translated = ++ wd->resource_list; ++ status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_START_DEVICE, &irp_sl); ++ fdo = IoGetAttachedDevice(pdo); ++ fdo->drv_obj->drv_ext->count++; ++ if (status != STATUS_SUCCESS) ++ WARNING("Windows driver couldn't initialize the device (%08X)", ++ status); ++ EXIT1(return status); ++} ++ ++#if 0 ++static NTSTATUS pnp_stop_device(struct wrap_device *wd) ++{ ++ struct device_object *pdo; ++ NTSTATUS status; ++ ++ pdo = wd->pdo; ++ status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_QUERY_STOP_DEVICE, ++ NULL); ++ if (status != STATUS_SUCCESS) ++ WARNING("status: %08X", status); ++ /* for now we ignore query status */ ++ status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_STOP_DEVICE, NULL); ++ if (status != STATUS_SUCCESS) ++ WARNING("status: %08X", status); ++ if (status != STATUS_SUCCESS) ++ WARNING("status: %08X", status); ++ EXIT2(return status); ++} ++#endif ++ ++static NTSTATUS pnp_remove_device(struct wrap_device *wd) ++{ ++ struct device_object *pdo, *fdo; ++ struct driver_object *fdo_drv_obj; ++ NTSTATUS status; ++ ++ pdo = wd->pdo; ++ fdo = IoGetAttachedDevice(pdo); ++ fdo_drv_obj = fdo->drv_obj; ++ TRACE2("%p, %p, %p", pdo, fdo, fdo_drv_obj); ++ status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_QUERY_REMOVE_DEVICE, ++ NULL); ++ if (status != STATUS_SUCCESS) ++ WARNING("status: %08X", status); ++ ++ status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_REMOVE_DEVICE, NULL); ++ if (status != STATUS_SUCCESS) ++ WARNING("status: %08X", status); ++ /* TODO: should we use count in drv_ext or driver's Object ++ * header reference count to keep count of devices associated ++ * with a driver? */ ++ if (status == STATUS_SUCCESS) ++ fdo_drv_obj->drv_ext->count--; ++ TRACE1("count: %d", fdo_drv_obj->drv_ext->count); ++ if ((LONG)fdo_drv_obj->drv_ext->count < 0) ++ WARNING("wrong count: %d", fdo_drv_obj->drv_ext->count); ++ if (fdo_drv_obj->drv_ext->count == 0) { ++ struct wrap_driver *wrap_driver; ++ TRACE1("unloading driver: %p", fdo_drv_obj); ++ wrap_driver = ++ IoGetDriverObjectExtension(fdo_drv_obj, ++ (void *)WRAP_DRIVER_CLIENT_ID); ++ if (fdo_drv_obj->unload) ++ LIN2WIN1(fdo_drv_obj->unload, fdo_drv_obj); ++ if (wrap_driver) { ++ mutex_lock(&loader_mutex); ++ unload_wrap_driver(wrap_driver); ++ mutex_unlock(&loader_mutex); ++ } else ++ ERROR("couldn't get wrap_driver"); ++ ObDereferenceObject(fdo_drv_obj); ++ } ++ IoDeleteDevice(pdo); ++ unload_wrap_device(wd); ++ EXIT1(return status); ++} ++ ++WIN_FUNC_DECL(IoInvalidDeviceRequest,2) ++ ++static struct device_object *alloc_pdo(struct driver_object *drv_obj) ++{ ++ struct device_object *pdo; ++ NTSTATUS status; ++ int i; ++ struct ansi_string ansi_name; ++ struct unicode_string unicode_name; ++ ++ RtlInitAnsiString(&ansi_name, "NDISpdo"); ++ if (RtlAnsiStringToUnicodeString(&unicode_name, &ansi_name, TRUE) == ++ STATUS_SUCCESS) { ++ status = IoCreateDevice(drv_obj, 0, &unicode_name, ++ FILE_DEVICE_UNKNOWN, ++ FILE_AUTOGENERATED_DEVICE_NAME, ++ FALSE, &pdo); ++ RtlFreeUnicodeString(&unicode_name); ++ } else { ++ status = IoCreateDevice(drv_obj, 0, NULL, ++ FILE_DEVICE_UNKNOWN, ++ FILE_AUTOGENERATED_DEVICE_NAME, ++ FALSE, &pdo); ++ } ++ TRACE1("%p, %d, %p", drv_obj, status, pdo); ++ if (status != STATUS_SUCCESS) ++ return NULL; ++ /* dispatch routines are called as Windows functions */ ++ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) ++ drv_obj->major_func[i] = WIN_FUNC_PTR(IoInvalidDeviceRequest,2); ++ drv_obj->major_func[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ++ WIN_FUNC_PTR(pdoDispatchDeviceControl,2); ++ drv_obj->major_func[IRP_MJ_DEVICE_CONTROL] = ++ WIN_FUNC_PTR(pdoDispatchDeviceControl,2); ++ drv_obj->major_func[IRP_MJ_POWER] = WIN_FUNC_PTR(pdoDispatchPower,2); ++ drv_obj->major_func[IRP_MJ_PNP] = WIN_FUNC_PTR(pdoDispatchPnp,2); ++ return pdo; ++} ++ ++static int wrap_pnp_start_device(struct wrap_device *wd) ++{ ++ struct wrap_driver *driver; ++ struct device_object *pdo; ++ struct driver_object *pdo_drv_obj; ++ ++ ENTER1("wd: %p", wd); ++ ++ if (!((wrap_is_pci_bus(wd->dev_bus)) || ++ (wrap_is_usb_bus(wd->dev_bus)))) { ++ ERROR("bus type %d (%d) not supported", ++ WRAP_BUS(wd->dev_bus), wd->dev_bus); ++ EXIT1(return -EINVAL); ++ } ++ driver = load_wrap_driver(wd); ++ if (!driver) ++ return -ENODEV; ++ ++ wd->driver = driver; ++ wd->dev_bus = WRAP_DEVICE_BUS(driver->dev_type, WRAP_BUS(wd->dev_bus)); ++ TRACE1("dev type: %d, bus type: %d, %d", WRAP_DEVICE(wd->dev_bus), ++ WRAP_BUS(wd->dev_bus), wd->dev_bus); ++ TRACE1("%d, %d", driver->dev_type, wrap_is_usb_bus(wd->dev_bus)); ++ /* first create pdo */ ++ if (wrap_is_pci_bus(wd->dev_bus)) ++ pdo_drv_obj = find_bus_driver("PCI"); ++ else // if (wrap_is_usb_bus(wd->dev_bus)) ++ pdo_drv_obj = find_bus_driver("USB"); ++ if (!pdo_drv_obj) ++ return -EINVAL; ++ pdo = alloc_pdo(pdo_drv_obj); ++ if (!pdo) ++ return -ENOMEM; ++ wd->pdo = pdo; ++ pdo->reserved = wd; ++ if (WRAP_DEVICE(wd->dev_bus) == WRAP_NDIS_DEVICE) { ++ if (init_ndis_driver(driver->drv_obj)) { ++ IoDeleteDevice(pdo); ++ return -EINVAL; ++ } ++ } ++ TRACE1("%p", driver->drv_obj->drv_ext->add_device); ++ if (driver->drv_obj->drv_ext->add_device(driver->drv_obj, pdo) != ++ STATUS_SUCCESS) { ++ IoDeleteDevice(pdo); ++ return -ENOMEM; ++ } ++ if (pnp_start_device(wd) != STATUS_SUCCESS) { ++ /* TODO: we need proper cleanup, to deallocate memory, ++ * for example */ ++ pnp_remove_device(wd); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++int wrap_pnp_start_pci_device(struct pci_dev *pdev, ++ const struct pci_device_id *ent) ++{ ++ struct load_device load_device; ++ struct wrap_device *wd; ++ ++ ENTER1("called for %04x:%04x:%04x:%04x", pdev->vendor, pdev->device, ++ pdev->subsystem_vendor, pdev->subsystem_device); ++ ++ load_device.bus = WRAP_PCI_BUS; ++ load_device.vendor = pdev->vendor; ++ load_device.device = pdev->device; ++ load_device.subvendor = pdev->subsystem_vendor; ++ load_device.subdevice = pdev->subsystem_device; ++ wd = load_wrap_device(&load_device); ++ if (!wd) ++ EXIT1(return -ENODEV); ++ wd->pci.pdev = pdev; ++ return wrap_pnp_start_device(wd); ++} ++ ++void wrap_pnp_remove_pci_device(struct pci_dev *pdev) ++{ ++ struct wrap_device *wd; ++ ++ wd = (struct wrap_device *)pci_get_drvdata(pdev); ++ ENTER1("%p, %p", pdev, wd); ++ if (!wd) ++ EXIT1(return); ++ pnp_remove_device(wd); ++} ++ ++int wrap_pnp_suspend_pci_device(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct wrap_device *wd; ++ ++ wd = (struct wrap_device *)pci_get_drvdata(pdev); ++ return pnp_set_device_power_state(wd, PowerDeviceD3); ++} ++ ++int wrap_pnp_resume_pci_device(struct pci_dev *pdev) ++{ ++ struct wrap_device *wd; ++ ++ wd = (struct wrap_device *)pci_get_drvdata(pdev); ++ return pnp_set_device_power_state(wd, PowerDeviceD0); ++} ++ ++#ifdef ENABLE_USB ++int wrap_pnp_start_usb_device(struct usb_interface *intf, ++ const struct usb_device_id *usb_id) ++{ ++ struct wrap_device *wd; ++ int ret; ++ struct usb_device *udev = interface_to_usbdev(intf); ++ ENTER1("%04x, %04x, %04x", udev->descriptor.idVendor, ++ udev->descriptor.idProduct, udev->descriptor.bDeviceClass); ++ ++ /* USB device (e.g., RNDIS) may have multiple interfaces; ++ initialize one interface only (is there a way to know which ++ of these interfaces is for network?) */ ++ ++ if ((wd = get_wrap_device(udev, WRAP_USB_BUS))) { ++ TRACE1("device already initialized: %p", wd); ++ usb_set_intfdata(intf, NULL); ++ ret = 0; ++ } else { ++ struct load_device load_device; ++ ++ load_device.bus = WRAP_USB_BUS; ++ load_device.vendor = le16_to_cpu(udev->descriptor.idVendor); ++ load_device.device = le16_to_cpu(udev->descriptor.idProduct); ++ load_device.subvendor = 0; ++ load_device.subdevice = 0; ++ wd = load_wrap_device(&load_device); ++ TRACE2("%p", wd); ++ if (wd) { ++ /* some devices (e.g., TI 4150, RNDIS) need ++ * full reset */ ++ ret = usb_reset_device(udev); ++ if (ret) ++ WARNING("reset failed: %d", ret); ++ usb_set_intfdata(intf, wd); ++ wd->usb.intf = intf; ++ wd->usb.udev = udev; ++ ret = wrap_pnp_start_device(wd); ++ } else ++ ret = -ENODEV; ++ } ++ ++ TRACE2("ret: %d", ret); ++ if (ret) ++ EXIT1(return ret); ++ else ++ return 0; ++} ++ ++void wrap_pnp_remove_usb_device(struct usb_interface *intf) ++{ ++ struct wrap_device *wd; ++ ++ wd = (struct wrap_device *)usb_get_intfdata(intf); ++ TRACE1("%p, %p", intf, wd); ++ if (wd == NULL) ++ EXIT1(return); ++ usb_set_intfdata(intf, NULL); ++ wd->usb.intf = NULL; ++ pnp_remove_device(wd); ++} ++ ++int wrap_pnp_suspend_usb_device(struct usb_interface *intf, pm_message_t state) ++{ ++ struct wrap_device *wd; ++ ++ wd = usb_get_intfdata(intf); ++ ENTER1("%p, %p", intf, wd); ++ if (!wd) ++ EXIT1(return 0); ++ if (pnp_set_device_power_state(wd, PowerDeviceD3)) ++ return -1; ++ return 0; ++} ++ ++int wrap_pnp_resume_usb_device(struct usb_interface *intf) ++{ ++ struct wrap_device *wd; ++ wd = usb_get_intfdata(intf); ++ ENTER1("%p, %p", intf, wd); ++ if (!wd) ++ EXIT1(return 0); ++ if (pnp_set_device_power_state(wd, PowerDeviceD0)) ++ return -1; ++ return 0; ++} ++ ++#endif // USB +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/pnp.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/pnp.h +--- linux-3.12.2/3rdparty/ndiswrapper/pnp.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/pnp.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (C) 2005 Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _PNP_H_ ++#define _PNP_H_ ++ ++#include "ntoskernel.h" ++#include "ndis.h" ++#include "wrapndis.h" ++ ++int wrap_pnp_start_pci_device(struct pci_dev *pdev, ++ const struct pci_device_id *ent); ++void wrap_pnp_remove_pci_device(struct pci_dev *pdev); ++int wrap_pnp_suspend_pci_device(struct pci_dev *pdev, pm_message_t state); ++int wrap_pnp_resume_pci_device(struct pci_dev *pdev); ++ ++int wrap_pnp_start_usb_device(struct usb_interface *intf, ++ const struct usb_device_id *usb_id); ++void wrap_pnp_remove_usb_device(struct usb_interface *intf); ++int wrap_pnp_suspend_usb_device(struct usb_interface *intf, ++ pm_message_t state); ++int wrap_pnp_resume_usb_device(struct usb_interface *intf); ++ ++#endif +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/proc.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/proc.c +--- linux-3.12.2/3rdparty/ndiswrapper/proc.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/proc.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,588 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++#include ++#include ++#include ++#include ++ ++#include "ndis.h" ++#include "iw_ndis.h" ++#include "wrapndis.h" ++#include "pnp.h" ++#include "wrapper.h" ++ ++#define MAX_PROC_STR_LEN 32 ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) ++static kuid_t proc_kuid; ++static kgid_t proc_kgid; ++#else ++#define proc_kuid proc_uid ++#define proc_kgid proc_gid ++#define kuid_t uid_t ++#define kgid_t gid_t ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ++static inline struct inode *file_inode(struct file *f) ++{ ++ return f->f_dentry->d_inode; ++} ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0) ++static inline struct inode *file_inode(struct file *f) ++{ ++ return f->f_path.dentry->d_inode; ++} ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ++static inline void proc_set_user(struct proc_dir_entry *de, kuid_t uid, ++ kgid_t gid) ++{ ++ de->uid = uid; ++ de->gid = gid; ++} ++ ++static inline void proc_remove(struct proc_dir_entry *de) ++{ ++ if (de) ++ remove_proc_entry(de->name, de->parent); ++} ++ ++static inline void *PDE_DATA(const struct inode *inode) ++{ ++ return PDE(inode)->data; ++} ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) ++static inline struct proc_dir_entry *proc_create_data(const char *name, ++ umode_t mode, struct proc_dir_entry *parent, ++ struct file_operations *fops, void *data) ++{ ++ struct proc_dir_entry *de; ++ ++ de = create_proc_entry(name, mode, parent); ++ if (de) { ++ de->data = data; ++ de->proc_fops = fops; ++ } ++ ++ return de; ++} ++#endif ++ ++static int do_proc_make_entry(const char *name, umode_t mode, ++ struct proc_dir_entry *parent, ++ struct file_operations *fops, kuid_t uid, ++ kgid_t gid, struct ndis_device *wnd) ++{ ++ struct proc_dir_entry *de; ++ ++ de = proc_create_data(name, mode, parent, fops, wnd); ++ if (de == NULL) { ++ ERROR("couldn't create proc entry for '%s'", name); ++ return -ENOMEM; ++ } ++ proc_set_user(de, uid, gid); ++ return 0; ++} ++ ++#define PROC_DECLARE_RO(name) \ ++ static int proc_##name##_open(struct inode *inode, struct file *file) \ ++ { \ ++ return single_open(file, proc_##name##_read, PDE_DATA(inode)); \ ++ } \ ++ static struct file_operations name##_fops = { \ ++ .owner = THIS_MODULE, \ ++ .open = proc_##name##_open, \ ++ .read = seq_read, \ ++ .llseek = seq_lseek, \ ++ .release = single_release, \ ++ }; ++ ++#define PROC_DECLARE_RW(name) \ ++ static int proc_##name##_open(struct inode *inode, struct file *file) \ ++ { \ ++ return single_open(file, proc_##name##_read, PDE_DATA(inode)); \ ++ } \ ++ static struct file_operations name##_fops = { \ ++ .owner = THIS_MODULE, \ ++ .open = proc_##name##_open, \ ++ .read = seq_read, \ ++ .llseek = seq_lseek, \ ++ .release = single_release, \ ++ .write = proc_##name##_write, \ ++ }; ++ ++#define proc_make_entry_ro(name, parent, wnd) \ ++ do_proc_make_entry(#name, S_IFREG | S_IRUSR | S_IRGRP, parent, \ ++ &name##_fops, proc_kuid, proc_kgid, wnd) ++#define proc_make_entry_rw(name, parent, wnd) \ ++ do_proc_make_entry(#name, \ ++ S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP, \ ++ parent, &name##_fops, proc_kuid, proc_kgid, wnd) ++ ++#define add_text(fmt, ...) seq_printf(sf, fmt, ##__VA_ARGS__) ++ ++static struct proc_dir_entry *wrap_procfs_entry; ++ ++static int proc_stats_read(struct seq_file *sf, void *v) ++{ ++ struct ndis_device *wnd = (struct ndis_device *)sf->private; ++ struct ndis_wireless_stats stats; ++ NDIS_STATUS res; ++ ndis_rssi rssi; ++ ++ res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi)); ++ if (!res) ++ add_text("signal_level=%d dBm\n", (s32)rssi); ++ ++ res = mp_query(wnd, OID_802_11_STATISTICS, &stats, sizeof(stats)); ++ if (!res) { ++ add_text("tx_frames=%llu\n", stats.tx_frag); ++ add_text("tx_multicast_frames=%llu\n", stats.tx_multi_frag); ++ add_text("tx_failed=%llu\n", stats.failed); ++ add_text("tx_retry=%llu\n", stats.retry); ++ add_text("tx_multi_retry=%llu\n", stats.multi_retry); ++ add_text("tx_rtss_success=%llu\n", stats.rtss_succ); ++ add_text("tx_rtss_fail=%llu\n", stats.rtss_fail); ++ add_text("ack_fail=%llu\n", stats.ack_fail); ++ add_text("frame_duplicates=%llu\n", stats.frame_dup); ++ add_text("rx_frames=%llu\n", stats.rx_frag); ++ add_text("rx_multicast_frames=%llu\n", stats.rx_multi_frag); ++ add_text("fcs_errors=%llu\n", stats.fcs_err); ++ } ++ ++ return 0; ++} ++ ++PROC_DECLARE_RO(stats) ++ ++static int proc_encr_read(struct seq_file *sf, void *v) ++{ ++ struct ndis_device *wnd = (struct ndis_device *)sf->private; ++ int i, encr_status, auth_mode, infra_mode; ++ NDIS_STATUS res; ++ struct ndis_essid essid; ++ mac_address ap_address; ++ ++ res = mp_query(wnd, OID_802_11_BSSID, ++ &ap_address, sizeof(ap_address)); ++ if (res) ++ memset(ap_address, 0, ETH_ALEN); ++ add_text("ap_address=" MACSTRSEP "\n", MAC2STR(ap_address)); ++ ++ res = mp_query(wnd, OID_802_11_SSID, &essid, sizeof(essid)); ++ if (!res) ++ add_text("essid=%.*s\n", essid.length, essid.essid); ++ ++ res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &encr_status); ++ if (!res) { ++ typeof(&wnd->encr_info.keys[0]) tx_key; ++ add_text("tx_key=%u\n", wnd->encr_info.tx_key_index); ++ add_text("key="); ++ tx_key = &wnd->encr_info.keys[wnd->encr_info.tx_key_index]; ++ if (tx_key->length > 0) ++ for (i = 0; i < tx_key->length; i++) ++ add_text("%2.2X", tx_key->key[i]); ++ else ++ add_text("off"); ++ add_text("\n"); ++ add_text("encr_mode=%d\n", encr_status); ++ } ++ res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &auth_mode); ++ if (!res) ++ add_text("auth_mode=%d\n", auth_mode); ++ res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &infra_mode); ++ add_text("mode=%s\n", (infra_mode == Ndis802_11IBSS) ? "adhoc" : ++ (infra_mode == Ndis802_11Infrastructure) ? "managed" : "auto"); ++ ++ return 0; ++} ++ ++PROC_DECLARE_RO(encr) ++ ++static int proc_hw_read(struct seq_file *sf, void *v) ++{ ++ struct ndis_device *wnd = (struct ndis_device *)sf->private; ++ struct ndis_configuration config; ++ enum ndis_power power_mode; ++ NDIS_STATUS res; ++ ndis_tx_power_level tx_power; ++ ULONG bit_rate; ++ ndis_rts_threshold rts_threshold; ++ ndis_fragmentation_threshold frag_threshold; ++ ndis_antenna antenna; ++ ULONG packet_filter; ++ int n; ++ mac_address mac; ++ char *hw_status[] = {"ready", "initializing", "resetting", "closing", ++ "not ready"}; ++ ++ res = mp_query_int(wnd, OID_GEN_HARDWARE_STATUS, &n); ++ if (res == NDIS_STATUS_SUCCESS && n >= 0 && n < ARRAY_SIZE(hw_status)) ++ add_text("status=%s\n", hw_status[n]); ++ ++ res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac)); ++ if (!res) ++ add_text("mac: " MACSTRSEP "\n", MAC2STR(mac)); ++ res = mp_query(wnd, OID_802_11_CONFIGURATION, &config, sizeof(config)); ++ if (!res) { ++ add_text("beacon_period=%u msec\n", config.beacon_period); ++ add_text("atim_window=%u msec\n", config.atim_window); ++ add_text("frequency=%u kHz\n", config.ds_config); ++ add_text("hop_pattern=%u\n", config.fh_config.hop_pattern); ++ add_text("hop_set=%u\n", config.fh_config.hop_set); ++ add_text("dwell_time=%u msec\n", config.fh_config.dwell_time); ++ } ++ ++ res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, ++ &tx_power, sizeof(tx_power)); ++ if (!res) ++ add_text("tx_power=%u mW\n", tx_power); ++ ++ res = mp_query(wnd, OID_GEN_LINK_SPEED, &bit_rate, sizeof(bit_rate)); ++ if (!res) ++ add_text("bit_rate=%u kBps\n", (u32)bit_rate / 10); ++ ++ res = mp_query(wnd, OID_802_11_RTS_THRESHOLD, ++ &rts_threshold, sizeof(rts_threshold)); ++ if (!res) ++ add_text("rts_threshold=%u bytes\n", rts_threshold); ++ ++ res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, ++ &frag_threshold, sizeof(frag_threshold)); ++ if (!res) ++ add_text("frag_threshold=%u bytes\n", frag_threshold); ++ ++ res = mp_query_int(wnd, OID_802_11_POWER_MODE, &power_mode); ++ if (!res) ++ add_text("power_mode=%s\n", ++ (power_mode == NDIS_POWER_OFF) ? "always_on" : ++ (power_mode == NDIS_POWER_MAX) ? "max_savings" : ++ "min_savings"); ++ ++ res = mp_query(wnd, OID_802_11_NUMBER_OF_ANTENNAS, ++ &antenna, sizeof(antenna)); ++ if (!res) ++ add_text("num_antennas=%u\n", antenna); ++ ++ res = mp_query(wnd, OID_802_11_TX_ANTENNA_SELECTED, ++ &antenna, sizeof(antenna)); ++ if (!res) ++ add_text("tx_antenna=%u\n", antenna); ++ ++ res = mp_query(wnd, OID_802_11_RX_ANTENNA_SELECTED, ++ &antenna, sizeof(antenna)); ++ if (!res) ++ add_text("rx_antenna=%u\n", antenna); ++ ++ add_text("encryption_modes=%s%s%s%s%s%s%s\n", ++ test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ? ++ "WEP" : "none", ++ test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ? ++ "; TKIP with WPA" : "", ++ test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? ++ ", WPA2" : "", ++ test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? ++ ", WPA2PSK" : "", ++ test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ? ++ "; AES/CCMP with WPA" : "", ++ test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? ++ ", WPA2" : "", ++ test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? ++ ", WPA2PSK" : ""); ++ ++ res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter); ++ if (!res) { ++ if (packet_filter != wnd->packet_filter) ++ WARNING("wrong packet_filter? 0x%08x, 0x%08x\n", ++ packet_filter, wnd->packet_filter); ++ add_text("packet_filter: 0x%08x\n", packet_filter); ++ } ++ ++ return 0; ++} ++ ++PROC_DECLARE_RO(hw) ++ ++static int proc_settings_read(struct seq_file *sf, void *v) ++{ ++ struct ndis_device *wnd = (struct ndis_device *)sf->private; ++ struct wrap_device_setting *setting; ++ ++ add_text("hangcheck_interval=%d\n", (hangcheck_interval == 0) ? ++ (wnd->hangcheck_interval / HZ) : -1); ++ ++ list_for_each_entry(setting, &wnd->wd->settings, list) { ++ add_text("%s=%s\n", setting->name, setting->value); ++ } ++ ++ list_for_each_entry(setting, &wnd->wd->driver->settings, list) { ++ add_text("%s=%s\n", setting->name, setting->value); ++ } ++ ++ return 0; ++} ++ ++static ssize_t proc_settings_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ndis_device *wnd = PDE_DATA(file_inode(file)); ++ char setting[MAX_PROC_STR_LEN], *p; ++ unsigned int i; ++ NDIS_STATUS res; ++ ++ if (count > MAX_PROC_STR_LEN) ++ return -EINVAL; ++ ++ memset(setting, 0, sizeof(setting)); ++ if (copy_from_user(setting, buf, count)) ++ return -EFAULT; ++ ++ if ((p = strchr(setting, '\n'))) ++ *p = 0; ++ ++ if ((p = strchr(setting, '='))) ++ *p = 0; ++ ++ if (!strcmp(setting, "hangcheck_interval")) { ++ if (!p) ++ return -EINVAL; ++ p++; ++ i = simple_strtol(p, NULL, 10); ++ hangcheck_del(wnd); ++ if (i > 0) { ++ wnd->hangcheck_interval = i * HZ; ++ hangcheck_add(wnd); ++ } ++ } else if (!strcmp(setting, "suspend")) { ++ if (!p) ++ return -EINVAL; ++ p++; ++ i = simple_strtol(p, NULL, 10); ++ if (i <= 0 || i > 3) ++ return -EINVAL; ++ i = -1; ++ if (wrap_is_pci_bus(wnd->wd->dev_bus)) ++ i = wrap_pnp_suspend_pci_device(wnd->wd->pci.pdev, ++ PMSG_SUSPEND); ++ else if (wrap_is_usb_bus(wnd->wd->dev_bus)) ++ i = wrap_pnp_suspend_usb_device(wnd->wd->usb.intf, ++ PMSG_SUSPEND); ++ if (i) ++ return -EINVAL; ++ } else if (!strcmp(setting, "resume")) { ++ i = -1; ++ if (wrap_is_pci_bus(wnd->wd->dev_bus)) ++ i = wrap_pnp_resume_pci_device(wnd->wd->pci.pdev); ++ else if (wrap_is_usb_bus(wnd->wd->dev_bus)) ++ i = wrap_pnp_resume_usb_device(wnd->wd->usb.intf); ++ if (i) ++ return -EINVAL; ++ } else if (!strcmp(setting, "stats_enabled")) { ++ if (!p) ++ return -EINVAL; ++ p++; ++ i = simple_strtol(p, NULL, 10); ++ if (i > 0) ++ wnd->iw_stats_enabled = TRUE; ++ else ++ wnd->iw_stats_enabled = FALSE; ++ } else if (!strcmp(setting, "packet_filter")) { ++ if (!p) ++ return -EINVAL; ++ p++; ++ i = simple_strtol(p, NULL, 10); ++ res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, i); ++ if (res) ++ WARNING("setting packet_filter failed: %08X", res); ++ } else if (!strcmp(setting, "reinit")) { ++ if (ndis_reinit(wnd) != NDIS_STATUS_SUCCESS) ++ return -EFAULT; ++ } else { ++ struct ndis_configuration_parameter param; ++ struct unicode_string key; ++ struct ansi_string ansi; ++ ++ if (!p) ++ return -EINVAL; ++ p++; ++ RtlInitAnsiString(&ansi, p); ++ if (RtlAnsiStringToUnicodeString(¶m.data.string, &ansi, ++ TRUE) != STATUS_SUCCESS) ++ EXIT1(return -EFAULT); ++ param.type = NdisParameterString; ++ RtlInitAnsiString(&ansi, setting); ++ if (RtlAnsiStringToUnicodeString(&key, &ansi, ++ TRUE) != STATUS_SUCCESS) { ++ RtlFreeUnicodeString(¶m.data.string); ++ EXIT1(return -EINVAL); ++ } ++ NdisWriteConfiguration(&res, wnd->nmb, &key, ¶m); ++ RtlFreeUnicodeString(&key); ++ RtlFreeUnicodeString(¶m.data.string); ++ if (res != NDIS_STATUS_SUCCESS) ++ return -EFAULT; ++ } ++ return count; ++} ++ ++PROC_DECLARE_RW(settings) ++ ++int wrap_procfs_add_ndis_device(struct ndis_device *wnd) ++{ ++ int ret; ++ ++ if (wrap_procfs_entry == NULL) ++ return -ENOMEM; ++ ++ if (wnd->procfs_iface) { ++ ERROR("%s already registered?", wnd->net_dev->name); ++ return -EINVAL; ++ } ++ wnd->procfs_iface = proc_mkdir(wnd->net_dev->name, wrap_procfs_entry); ++ if (wnd->procfs_iface == NULL) { ++ ERROR("couldn't create proc directory"); ++ return -ENOMEM; ++ } ++ proc_set_user(wnd->procfs_iface, proc_kuid, proc_kgid); ++ ++ ret = proc_make_entry_ro(hw, wnd->procfs_iface, wnd); ++ if (ret) ++ goto err_hw; ++ ++ ret = proc_make_entry_ro(stats, wnd->procfs_iface, wnd); ++ if (ret) ++ goto err_stats; ++ ++ ret = proc_make_entry_ro(encr, wnd->procfs_iface, wnd); ++ if (ret) ++ goto err_encr; ++ ++ ret = proc_make_entry_rw(settings, wnd->procfs_iface, wnd); ++ if (ret) ++ goto err_settings; ++ ++ return 0; ++ ++err_settings: ++ remove_proc_entry("encr", wnd->procfs_iface); ++err_encr: ++ remove_proc_entry("stats", wnd->procfs_iface); ++err_stats: ++ remove_proc_entry("hw", wnd->procfs_iface); ++err_hw: ++ proc_remove(wnd->procfs_iface); ++ wnd->procfs_iface = NULL; ++ return -ENOMEM; ++} ++ ++void wrap_procfs_remove_ndis_device(struct ndis_device *wnd) ++{ ++ struct proc_dir_entry *procfs_iface = xchg(&wnd->procfs_iface, NULL); ++ ++ if (procfs_iface == NULL) ++ return; ++ remove_proc_entry("hw", procfs_iface); ++ remove_proc_entry("stats", procfs_iface); ++ remove_proc_entry("encr", procfs_iface); ++ remove_proc_entry("settings", procfs_iface); ++ if (wrap_procfs_entry) ++ proc_remove(procfs_iface); ++} ++ ++static int proc_debug_read(struct seq_file *sf, void *v) ++{ ++#if ALLOC_DEBUG ++ enum alloc_type type; ++#endif ++ ++ add_text("%d\n", debug); ++#if ALLOC_DEBUG ++ for (type = 0; type < ALLOC_TYPE_MAX; type++) ++ add_text("total size of allocations in %s: %d\n", ++ alloc_type_name[type], alloc_size(type)); ++#endif ++ return 0; ++} ++ ++static ssize_t proc_debug_write(struct file *file, const char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ int i; ++ char setting[MAX_PROC_STR_LEN], *p; ++ ++ if (count > MAX_PROC_STR_LEN) ++ return -EINVAL; ++ ++ memset(setting, 0, sizeof(setting)); ++ if (copy_from_user(setting, buf, count)) ++ return -EFAULT; ++ ++ if ((p = strchr(setting, '\n'))) ++ *p = 0; ++ ++ if ((p = strchr(setting, '='))) ++ *p = 0; ++ ++ i = simple_strtol(setting, NULL, 10); ++ if (i >= 0 && i < 10) ++ debug = i; ++ else ++ return -EINVAL; ++ return count; ++} ++ ++PROC_DECLARE_RW(debug) ++ ++int wrap_procfs_init(void) ++{ ++ int ret; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) ++ struct user_namespace *ns = current_user_ns(); ++ proc_kuid = make_kuid(ns, proc_uid); ++ if (!uid_valid(proc_kuid)) { ++ ERROR("invalid UID\n"); ++ return -EINVAL; ++ } ++ proc_kgid = make_kgid(ns, proc_gid); ++ if (!gid_valid(proc_kgid)) { ++ ERROR("invalid GID\n"); ++ return -EINVAL; ++ } ++#endif ++ ++ wrap_procfs_entry = proc_mkdir(DRIVER_NAME, proc_net_root); ++ if (wrap_procfs_entry == NULL) { ++ ERROR("couldn't create procfs directory"); ++ return -ENOMEM; ++ } ++ proc_set_user(wrap_procfs_entry, proc_kuid, proc_kgid); ++ ++ ret = proc_make_entry_rw(debug, wrap_procfs_entry, NULL); ++ ++ return ret; ++} ++ ++void wrap_procfs_remove(void) ++{ ++ if (wrap_procfs_entry == NULL) ++ return; ++ remove_proc_entry("debug", wrap_procfs_entry); ++ proc_remove(wrap_procfs_entry); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/rtl.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/rtl.c +--- linux-3.12.2/3rdparty/ndiswrapper/rtl.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/rtl.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,715 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * Copyright (C) 2006-2007 Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ntoskernel.h" ++#include "rtl_exports.h" ++ ++wstdcall SIZE_T WIN_FUNC(RtlCompareMemory,3) ++ (const void *a, const void *b, SIZE_T len) ++{ ++ size_t i; ++ char *x, *y; ++ ++ ENTER1("%p %p %zd", a, b, len); ++ x = (char *)a; ++ y = (char *)b; ++ /* MSDN says this should return number of bytes that compare as ++ * equal. This can be interpreted as either all bytes that are ++ * equal in 'len' bytes or that only until the bytes compare as ++ * not equal. Initially we had it the former way, but Realtek driver ++ * doesn't like it that way - it takes many attempts to associate ++ * with WPA. ReactOS returns the number of bytes that are equal ++ * before the first differing byte. ++ * According to lords at #reactos, that is the way it should be ++ * and that msdn is wrong about it! ++ */ ++ for (i = 0; i < len && x[i] == y[i]; i++) ++ ; ++ return i; ++} ++ ++wstdcall void WIN_FUNC(RtlCopyMemory,3) ++ (void *dst, const void *src, SIZE_T length) ++{ ++ memcpy(dst, src, length); ++} ++ ++wstdcall void WIN_FUNC(RtlZeroMemory,2) ++ (void *dst, SIZE_T length) ++{ ++ memset(dst, 0, length); ++} ++ ++wstdcall void WIN_FUNC(RtlSecureZeroMemory,2) ++ (void *dst, SIZE_T length) ++{ ++ memset(dst, 0, length); ++} ++ ++wstdcall void WIN_FUNC(RtlFillMemory,3) ++ (void *dest, SIZE_T length, UCHAR fill) ++{ ++ memset(dest, fill, length); ++} ++ ++wstdcall void WIN_FUNC(RtlMoveMemory,3) ++ (void *dest, const void *src, SIZE_T length) ++{ ++ memmove(dest, src, length); ++} ++ ++wstdcall LONG WIN_FUNC(RtlCompareString,3) ++ (const struct ansi_string *s1, const struct ansi_string *s2, ++ BOOLEAN case_insensitive) ++{ ++ unsigned int len; ++ LONG ret = 0; ++ const char *p1, *p2; ++ ++ ENTER2(""); ++ len = min(s1->length, s2->length); ++ p1 = s1->buf; ++ p2 = s2->buf; ++ if (case_insensitive) ++ while (!ret && len--) ++ ret = toupper(*p1++) - toupper(*p2++); ++ else ++ while (!ret && len--) ++ ret = *p1++ - *p2++; ++ if (!ret) ++ ret = s1->length - s2->length; ++ EXIT2(return ret); ++} ++ ++wstdcall LONG WIN_FUNC(RtlCompareUnicodeString,3) ++ (const struct unicode_string *s1, const struct unicode_string *s2, ++ BOOLEAN case_insensitive) ++{ ++ unsigned int len; ++ LONG ret = 0; ++ const wchar_t *p1, *p2; ++ ++ ENTER2(""); ++ ++ len = min(s1->length, s2->length) / sizeof(wchar_t); ++ p1 = s1->buf; ++ p2 = s2->buf; ++ if (case_insensitive) ++ while (!ret && len--) ++ ret = toupper((u8)*p1++) - toupper((u8)*p2++); ++ else ++ while (!ret && len--) ++ ret = (u8)*p1++ - (u8)*p2++; ++ if (!ret) ++ ret = s1->length - s2->length; ++ TRACE2("len: %d, ret: %d", len, ret); ++ EXIT2(return ret); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(RtlEqualString,3) ++ (const struct ansi_string *s1, const struct ansi_string *s2, ++ BOOLEAN case_insensitive) ++{ ++ ENTER1(""); ++ if (s1->length != s2->length) ++ return FALSE; ++ return !RtlCompareString(s1, s2, case_insensitive); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(RtlEqualUnicodeString,3) ++ (const struct unicode_string *s1, const struct unicode_string *s2, ++ BOOLEAN case_insensitive) ++{ ++ if (s1->length != s2->length) ++ return FALSE; ++ return !RtlCompareUnicodeString(s1, s2, case_insensitive); ++} ++ ++wstdcall void WIN_FUNC(RtlCopyUnicodeString,2) ++ (struct unicode_string *dst, struct unicode_string *src) ++{ ++ ENTER1("%p, %p", dst, src); ++ if (src && src->buf && dst->buf) { ++ dst->length = min(src->length, dst->max_length); ++ memcpy(dst->buf, src->buf, dst->length); ++ if (dst->length < dst->max_length) ++ dst->buf[dst->length / sizeof(dst->buf[0])] = 0; ++ } else ++ dst->length = 0; ++ EXIT1(return); ++} ++ ++wstdcall void WIN_FUNC(RtlCopyString,2) ++ (struct ansi_string *dst, struct ansi_string *src) ++{ ++ ENTER1("%p, %p", dst, src); ++ if (src && src->buf && dst->buf) { ++ dst->length = min(src->length, dst->max_length); ++ memcpy(dst->buf, src->buf, dst->length); ++ if (dst->length < dst->max_length) ++ dst->buf[dst->length] = 0; ++ } else ++ dst->length = 0; ++ EXIT1(return); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlAppendUnicodeToString,2) ++ (struct unicode_string *dst, wchar_t *src) ++{ ++ if (src) { ++ int len; ++ for (len = 0; src[len]; len++) ++ ; ++ if (dst->length + (len * sizeof(dst->buf[0])) > dst->max_length) ++ return STATUS_BUFFER_TOO_SMALL; ++ memcpy(&dst->buf[dst->length], src, len * sizeof(dst->buf[0])); ++ dst->length += len * sizeof(dst->buf[0]); ++ if (dst->max_length > dst->length) ++ dst->buf[dst->length / sizeof(dst->buf[0])] = 0; ++ } ++ return STATUS_SUCCESS; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlAppendUnicodeStringToString,2) ++ (struct unicode_string *dst, struct unicode_string *src) ++{ ++ if (dst->max_length < src->length + dst->length) ++ return STATUS_BUFFER_TOO_SMALL; ++ if (src->length) { ++ memcpy(&dst->buf[dst->length], src->buf, src->length); ++ dst->length += src->length; ++ if (dst->max_length > dst->length) ++ dst->buf[dst->length / sizeof(dst->buf[0])] = 0; ++ } ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++wstdcall ULONG WIN_FUNC(RtlxAnsiStringToUnicodeSize,1) ++ (const struct ansi_string *string) ++{ ++ int i; ++ ++ for (i = 0; i < string->max_length && string->buf[i]; i++) ++ ; ++ return i * sizeof(wchar_t); ++} ++ ++wstdcall ULONG WIN_FUNC(RtlxUnicodeStringToAnsiSize,1) ++ (const struct unicode_string *string) ++{ ++ int i; ++ ++ for (i = 0; i < string->max_length && string->buf[i]; i++) ++ ; ++ return i; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlAnsiStringToUnicodeString,3) ++ (struct unicode_string *dst, const struct ansi_string *src, ++ BOOLEAN alloc) ++{ ++ int i, n; ++ ++ n = RtlxAnsiStringToUnicodeSize(src); ++ TRACE2("%d, %d, %d, %d, %p", n, dst->max_length, src->length, ++ src->max_length, src->buf); ++ if (alloc == TRUE) { ++#if 0 ++ if (n == 0) { ++ dst->length = dst->max_length = 0; ++ dst->buf = NULL; ++ EXIT2(return STATUS_SUCCESS); ++ } ++#endif ++ dst->max_length = n + sizeof(dst->buf[0]); ++ dst->buf = ExAllocatePoolWithTag(NonPagedPool, ++ dst->max_length, 0); ++ if (!dst->buf) { ++ dst->max_length = dst->length = 0; ++ EXIT2(return STATUS_NO_MEMORY); ++ } ++ } else if (dst->max_length < n) ++ EXIT2(return STATUS_BUFFER_TOO_SMALL); ++ ++ dst->length = n; ++ n /= sizeof(dst->buf[0]); ++ for (i = 0; i < n; i++) ++ dst->buf[i] = src->buf[i]; ++ if (i * sizeof(dst->buf[0]) < dst->max_length) ++ dst->buf[i] = 0; ++ TRACE2("dst: length: %d, max_length: %d, string: %p", ++ dst->length, dst->max_length, src->buf); ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlUnicodeStringToAnsiString,3) ++ (struct ansi_string *dst, const struct unicode_string *src, ++ BOOLEAN alloc) ++{ ++ int i, n; ++ ++ n = RtlxUnicodeStringToAnsiSize(src); ++ TRACE2("%d, %d, %d, %d, %p", n, dst->max_length, src->length, ++ src->max_length, src->buf); ++ if (alloc == TRUE) { ++#if 0 ++ if (n == 0) { ++ dst->length = dst->max_length = 0; ++ dst->buf = NULL; ++ EXIT2(return STATUS_SUCCESS); ++ } ++#endif ++ dst->max_length = n + sizeof(dst->buf[0]); ++ dst->buf = ExAllocatePoolWithTag(NonPagedPool, ++ dst->max_length, 0); ++ if (!dst->buf) { ++ dst->max_length = dst->length = 0; ++ EXIT1(return STATUS_NO_MEMORY); ++ } ++ } else if (dst->max_length < n) ++ EXIT2(return STATUS_BUFFER_TOO_SMALL); ++ ++ dst->length = n; ++ for (i = 0; i < n; i++) ++ dst->buf[i] = src->buf[i]; ++ if (i < dst->max_length) ++ dst->buf[i] = 0; ++ TRACE2("string: %p, len: %d(%d)", dst->buf, dst->length, ++ dst->max_length); ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlUnicodeStringToInteger,3) ++ (struct unicode_string *ustring, ULONG base, ULONG *value) ++{ ++ int i, sign = 1; ++ ULONG res; ++ typeof(ustring->buf) string; ++ ++ if (ustring->length == 0) { ++ *value = 0; ++ return STATUS_SUCCESS; ++ } ++ ++ string = ustring->buf; ++ i = 0; ++ while (i < (ustring->length / sizeof(*string)) && string[i] == ' ') ++ i++; ++ if (string[i] == '+') ++ i++; ++ else if (string[i] == '-') { ++ i++; ++ sign = -1; ++ } ++ if (base == 0) { ++ base = 10; ++ if (i <= ((ustring->length / sizeof(*string)) - 2) && ++ string[i] == '0') { ++ i++; ++ if (string[i] == 'b') { ++ base = 2; ++ i++; ++ } else if (string[i] == 'o') { ++ base = 8; ++ i++; ++ } else if (string[i] == 'x') { ++ base = 16; ++ i++; ++ } ++ } ++ } ++ if (!(base == 2 || base == 8 || base == 10 || base == 16)) ++ EXIT2(return STATUS_INVALID_PARAMETER); ++ ++ for (res = 0; i < (ustring->length / sizeof(*string)); i++) { ++ int v; ++ if (isdigit((char)string[i])) ++ v = string[i] - '0'; ++ else if (isxdigit((char)string[i])) ++ v = tolower((char)string[i]) - 'a' + 10; ++ else ++ v = base; ++ if (v >= base) ++ EXIT2(return STATUS_INVALID_PARAMETER); ++ res = res * base + v; ++ } ++ *value = sign * res; ++ EXIT3(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlCharToInteger,3) ++ (const char *string, ULONG base, ULONG *value) ++{ ++ int sign = 1; ++ ULONG res; ++ ++ if (!string || !value) ++ EXIT2(return STATUS_INVALID_PARAMETER); ++ while (*string == ' ') ++ string++; ++ if (*string == '+') ++ string++; ++ else if (*string == '-') { ++ string++; ++ sign = -1; ++ } ++ if (base == 0) { ++ base = 10; ++ if (*string == '0') { ++ string++; ++ if (*string == 'b') { ++ base = 2; ++ string++; ++ } else if (*string == 'o') { ++ base = 8; ++ string++; ++ } else if (*string == 'x') { ++ base = 16; ++ string++; ++ } ++ } ++ } ++ if (!(base == 2 || base == 8 || base == 10 || base == 16)) ++ EXIT2(return STATUS_INVALID_PARAMETER); ++ ++ for (res = 0; *string; string++) { ++ int v; ++ if (isdigit(*string)) ++ v = *string - '0'; ++ else if (isxdigit(*string)) ++ v = tolower(*string) - 'a' + 10; ++ else ++ v = base; ++ if (v >= base) ++ EXIT2(return STATUS_INVALID_PARAMETER); ++ res = res * base + v; ++ } ++ *value = sign * res; ++ EXIT3(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlIntegerToUnicodeString,3) ++ (ULONG value, ULONG base, struct unicode_string *ustring) ++{ ++ typeof(ustring->buf) buf = ustring->buf; ++ int i; ++ ++ if (base == 0) ++ base = 10; ++ if (!(base == 2 || base == 8 || base == 10 || base == 16)) ++ return STATUS_INVALID_PARAMETER; ++ for (i = 0; value && i < ustring->max_length / sizeof(*buf); i++) { ++ int r; ++ r = value % base; ++ value /= base; ++ if (r < 10) ++ buf[i] = r + '0'; ++ else ++ buf[i] = r + 'a' - 10; ++ } ++ if (value) ++ return STATUS_BUFFER_OVERFLOW; ++ ustring->length = i * sizeof(*buf); ++ return STATUS_SUCCESS; ++} ++ ++wstdcall LARGE_INTEGER WIN_FUNC(RtlConvertUlongToLargeInteger,1) ++ (ULONG ul) ++{ ++ LARGE_INTEGER li = ul; ++ return li; ++} ++ ++wfastcall USHORT WIN_FUNC(RtlUshortByteSwap,1) ++ (USHORT src) ++{ ++ return __swab16(src); ++} ++ ++wfastcall ULONG WIN_FUNC(RtlUlongByteSwap,1) ++ (ULONG src) ++{ ++ /* ULONG is 32 bits for both 32-bit and 64-bit architectures */ ++ return __swab32(src); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlUpcaseUnicodeString,3) ++ (struct unicode_string *dst, struct unicode_string *src, BOOLEAN alloc) ++{ ++ USHORT i, n; ++ ++ if (alloc) { ++ dst->buf = ExAllocatePoolWithTag(NonPagedPool, src->length, 0); ++ if (dst->buf) ++ dst->max_length = src->length; ++ else ++ EXIT2(return STATUS_NO_MEMORY); ++ } else { ++ if (dst->max_length < src->length) ++ EXIT2(return STATUS_BUFFER_OVERFLOW); ++ } ++ ++ n = src->length / sizeof(src->buf[0]); ++ for (i = 0; i < n; i++) ++ dst->buf[i] = toupper(src->buf[i]); ++ ++ dst->length = src->length; ++ EXIT3(return STATUS_SUCCESS); ++} ++ ++wstdcall void WIN_FUNC(RtlInitUnicodeString,2) ++ (struct unicode_string *dst, const wchar_t *src) ++{ ++ ENTER2("%p", dst); ++ if (dst == NULL) ++ EXIT1(return); ++ if (src == NULL) { ++ dst->max_length = dst->length = 0; ++ dst->buf = NULL; ++ } else { ++ int i; ++ for (i = 0; (char)src[i]; i++) ++ ; ++ dst->buf = (typeof(dst->buf))src; ++ dst->length = i * sizeof(dst->buf[0]); ++ dst->max_length = (i + 1) * sizeof(dst->buf[0]); ++ } ++ EXIT1(return); ++} ++ ++wstdcall void WIN_FUNC(RtlInitAnsiString,2) ++ (struct ansi_string *dst, const char *src) ++{ ++ ENTER2("%p", dst); ++ if (dst == NULL) ++ EXIT2(return); ++ if (src == NULL) { ++ dst->max_length = dst->length = 0; ++ dst->buf = NULL; ++ } else { ++ int i; ++ for (i = 0; src[i]; i++) ++ ; ++ dst->buf = (typeof(dst->buf))src; ++ dst->length = i; ++ dst->max_length = i + 1; ++ } ++ TRACE2("%p", dst->buf); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(RtlInitString,2) ++ (struct ansi_string *dst, const char *src) ++{ ++ ENTER2("%p", dst); ++ RtlInitAnsiString(dst, src); ++ EXIT2(return); ++} ++ ++wstdcall void WIN_FUNC(RtlFreeUnicodeString,1) ++ (struct unicode_string *string) ++{ ++ ENTER2("%p", string); ++ if (string == NULL) ++ return; ++ if (string->buf) ++ ExFreePool(string->buf); ++ string->length = string->max_length = 0; ++ string->buf = NULL; ++ return; ++} ++ ++wstdcall void WIN_FUNC(RtlFreeAnsiString,1) ++ (struct ansi_string *string) ++{ ++ ENTER2("%p", string); ++ if (string == NULL) ++ return; ++ if (string->buf) ++ ExFreePool(string->buf); ++ string->length = string->max_length = 0; ++ string->buf = NULL; ++ return; ++} ++ ++/* guid string is of the form: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */ ++wstdcall NTSTATUS WIN_FUNC(RtlGUIDFromString,2) ++ (struct unicode_string *guid_string, struct guid *guid) ++{ ++ struct ansi_string ansi; ++ NTSTATUS ret; ++ int i, j, k, l, m; ++ ++ ret = RtlUnicodeStringToAnsiString(&ansi, guid_string, TRUE); ++ if (ret != STATUS_SUCCESS) ++ return ret; ++ if (ansi.length != 37 || ansi.buf[0] != '{' || ++ ansi.buf[36] != '}' || ansi.buf[9] != '-' || ++ ansi.buf[14] != '-' || ansi.buf[19] != '-' || ++ ansi.buf[24] != '-') { ++ RtlFreeAnsiString(&ansi); ++ EXIT2(return STATUS_INVALID_PARAMETER); ++ } ++ memcpy(&guid->data4, &ansi.buf[29], sizeof(guid->data3)); ++ /* set end of data3 for scanf */ ++ ansi.buf[29] = 0; ++ if (sscanf(&ansi.buf[1], "%x", &i) == 1 && ++ sscanf(&ansi.buf[10], "%x", &j) == 1 && ++ sscanf(&ansi.buf[15], "%x", &k) == 1 && ++ sscanf(&ansi.buf[20], "%x", &l) == 1 && ++ sscanf(&ansi.buf[25], "%x", &m) == 1) { ++ guid->data1 = (i << 16) | (j < 8) | k; ++ guid->data2 = l; ++ guid->data3 = m; ++ ret = STATUS_SUCCESS; ++ } else ++ ret = STATUS_INVALID_PARAMETER; ++ RtlFreeAnsiString(&ansi); ++ return ret; ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlQueryRegistryValues,5) ++ (ULONG relative, wchar_t *path, struct rtl_query_registry_table *tbl, ++ void *context, void *env) ++{ ++ struct ansi_string ansi; ++ struct unicode_string unicode; ++ NTSTATUS status, ret; ++ static int i = 0; ++ ++ ENTER3("%x, %p", relative, tbl); ++// TODO(); ++ ++ RtlInitUnicodeString(&unicode, path); ++ if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == ++ STATUS_SUCCESS) { ++ TRACE2("%s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ ret = STATUS_SUCCESS; ++ for (; tbl->name; tbl++) { ++ RtlInitUnicodeString(&unicode, tbl->name); ++ if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == ++ STATUS_SUCCESS) { ++ TRACE2("name: %s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ TRACE2("flags: %08X", tbl->flags); ++ if (tbl->flags == RTL_QUERY_REGISTRY_DIRECT) { ++ TRACE2("type: %08X", tbl->def_type); ++ if (tbl->def_type == REG_DWORD) { ++ /* Atheros USB driver needs this, but ++ * don't know where and how to get its ++ * value */ ++ if (tbl->def_data) { ++ TRACE2("def_data: %x", ++ *(int *)tbl->def_data); ++ *(DWORD *)tbl->context = 0x5f292a + i++; ++// *(DWORD *)tbl->def_data; ++ } else ++ *(DWORD *)tbl->context = 0x2345dbe; ++ } ++ } else { ++ void *data; ++ ULONG type, length; ++ ++ if (!tbl->query_func) { ++ ERROR("oops: no query_func"); ++ ret = STATUS_INVALID_PARAMETER; ++ break; ++ } ++ if (tbl->flags & RTL_QUERY_REGISTRY_NOVALUE) { ++ data = NULL; ++ type = REG_NONE; ++ length = 0; ++ } else { ++ data = tbl->def_data; ++ type = tbl->def_type; ++ length = tbl->def_length;; ++ } ++ TRACE2("calling query_func: %p", tbl->query_func); ++ status = LIN2WIN6(tbl->query_func, tbl->name, type, ++ data, length, context, env); ++ TRACE2("status: %08X", status); ++ if (status) { ++ if (status == STATUS_BUFFER_TOO_SMALL) ++ ret = STATUS_BUFFER_TOO_SMALL; ++ else ++ EXIT2(return STATUS_INVALID_PARAMETER); ++ } ++ } ++ } ++ EXIT3(return ret); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlWriteRegistryValue,6) ++ (ULONG relative, wchar_t *path, wchar_t *name, ULONG type, ++ void *data, ULONG length) ++{ ++ struct ansi_string ansi; ++ struct unicode_string unicode; ++ ++ ENTER3("%d", relative); ++ TODO(); ++ ++ RtlInitUnicodeString(&unicode, path); ++ if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == ++ STATUS_SUCCESS) { ++ TRACE2("%s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ RtlInitUnicodeString(&unicode, name); ++ if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == ++ STATUS_SUCCESS) { ++ TRACE2("%s", ansi.buf); ++ RtlFreeAnsiString(&ansi); ++ } ++ EXIT5(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS WIN_FUNC(RtlDeleteRegistryValue,3) ++ (ULONG relative, wchar_t *path, wchar_t *name) ++{ ++ return STATUS_SUCCESS; ++} ++ ++wstdcall void WIN_FUNC(RtlAssert,4) ++ (char *failed_assertion, char *file_name, ULONG line_num, char *message) ++{ ++ ERROR("assertion '%s' failed at %s line %d%s", ++ failed_assertion, file_name, line_num, message ? message : ""); ++ return; ++} ++ ++wstdcall void WIN_FUNC(RtlUnwind,0) ++ (void) ++{ ++ TODO(); ++} ++ ++wstdcall void WIN_FUNC(RtlRaiseException,1) ++ (void *exception_record) ++{ ++ TODO(); ++} ++ ++wstdcall BOOLEAN WIN_FUNC(RtlIsServicePackVersionInstalled,1) ++ (ULONG version) ++{ ++ /* Assume we have all service packs */ ++ TRACE1("version: %d", version); ++ return TRUE; ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/usb.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/usb.c +--- linux-3.12.2/3rdparty/ndiswrapper/usb.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/usb.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,1496 @@ ++/* ++ * Copyright (C) 2004 Jan Kiszka ++ * Copyright (C) 2005 Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ndis.h" ++#include "usb.h" ++#include "usb_exports.h" ++ ++#ifdef USB_DEBUG ++static unsigned int urb_id = 0; ++ ++#define DUMP_WRAP_URB(wrap_urb, dir) \ ++ USBTRACE("urb %p (%d) %s: buf: %p, len: %d, pipe: 0x%x, %d", \ ++ (wrap_urb)->urb, (wrap_urb)->id, \ ++ (dir == USB_DIR_OUT) ? "going down" : "coming back", \ ++ (wrap_urb)->urb->transfer_buffer, \ ++ (wrap_urb)->urb->transfer_buffer_length, \ ++ (wrap_urb)->urb->pipe, (wrap_urb)->urb->status) ++ ++#define DUMP_URB_BUFFER(urb, dir) \ ++ while (debug >= 2) { \ ++ int i; \ ++ char msg[20], *t; \ ++ if (!urb->transfer_buffer) \ ++ break; \ ++ if (!((usb_pipein(urb->pipe) && dir == USB_DIR_IN) || \ ++ (usb_pipeout(urb->pipe) && dir == USB_DIR_OUT))) \ ++ break; \ ++ t = msg; \ ++ t += sprintf(t, "%d: ", (urb)->actual_length); \ ++ for (i = 0; i < urb->actual_length && \ ++ t < &msg[sizeof(msg) - 4]; i++) \ ++ t += sprintf(t, "%02X ", \ ++ ((char *)urb->transfer_buffer)[i]); \ ++ *t = 0; \ ++ USBTRACE("%s", msg); \ ++ break; \ ++ } ++ ++#else ++ ++#define DUMP_WRAP_URB(wrap_urb, dir) (void)0 ++#define DUMP_URB_BUFFER(urb, dir) (void)0 ++ ++#endif ++ ++#define CUR_ALT_SETTING(intf) (intf)->cur_altsetting ++ ++#ifndef USB_CTRL_SET_TIMEOUT ++#define USB_CTRL_SET_TIMEOUT 5000 ++#endif ++ ++#ifndef USB_CTRL_GET_TIMEOUT ++#define USB_CTRL_GET_TIMEOUT 5000 ++#endif ++ ++#ifndef URB_NO_TRANSFER_DMA_MAP ++#define URB_NO_TRANSFER_DMA_MAP 0 ++#endif ++ ++/* wrap_urb->flags */ ++/* transfer_buffer for urb is allocated; free it in wrap_free_urb */ ++#define WRAP_URB_COPY_BUFFER 0x01 ++ ++static inline int wrap_cancel_urb(struct wrap_urb *wrap_urb) ++{ ++ int ret; ++ USBTRACE("%p, %p, %d", wrap_urb, wrap_urb->urb, wrap_urb->state); ++ if (wrap_urb->state != URB_SUBMITTED) ++ USBEXIT(return -1); ++ ret = usb_unlink_urb(wrap_urb->urb); ++ USBTRACE("ret: %d", ret); ++ if (ret == -EINPROGRESS) ++ return 0; ++ else { ++ WARNING("unlink failed: %d", ret); ++ return ret; ++ } ++} ++ ++#define URB_STATUS(wrap_urb) (wrap_urb->urb->status) ++ ++static struct nt_list wrap_urb_complete_list; ++static spinlock_t wrap_urb_complete_list_lock; ++ ++static struct work_struct wrap_urb_complete_work; ++static void wrap_urb_complete_worker(struct work_struct *dummy); ++ ++static void kill_all_urbs(struct wrap_device *wd, int complete) ++{ ++ struct nt_list *ent; ++ struct wrap_urb *wrap_urb; ++ KIRQL irql; ++ ++ USBTRACE("%d", wd->usb.num_alloc_urbs); ++ while (1) { ++ IoAcquireCancelSpinLock(&irql); ++ ent = RemoveHeadList(&wd->usb.wrap_urb_list); ++ IoReleaseCancelSpinLock(irql); ++ if (!ent) ++ break; ++ wrap_urb = container_of(ent, struct wrap_urb, list); ++ if (wrap_urb->state == URB_SUBMITTED) { ++ WARNING("Windows driver %s didn't free urb: %p", ++ wd->driver->name, wrap_urb->urb); ++ if (!complete) ++ wrap_urb->urb->complete = NULL; ++ usb_kill_urb(wrap_urb->urb); ++ } ++ USBTRACE("%p, %p", wrap_urb, wrap_urb->urb); ++ usb_free_urb(wrap_urb->urb); ++ kfree(wrap_urb); ++ } ++ wd->usb.num_alloc_urbs = 0; ++} ++ ++/* for a given Linux urb status code, return corresponding NT urb status */ ++static USBD_STATUS wrap_urb_status(int urb_status) ++{ ++ switch (urb_status) { ++ case 0: ++ return USBD_STATUS_SUCCESS; ++ case -EPROTO: ++ return USBD_STATUS_TIMEOUT; ++ case -EILSEQ: ++ return USBD_STATUS_CRC; ++ case -EPIPE: ++ return USBD_STATUS_INVALID_PIPE_HANDLE; ++ case -ECOMM: ++ return USBD_STATUS_DATA_OVERRUN; ++ case -ENOSR: ++ return USBD_STATUS_DATA_UNDERRUN; ++ case -EOVERFLOW: ++ return USBD_STATUS_BABBLE_DETECTED; ++ case -EREMOTEIO: ++ return USBD_STATUS_ERROR_SHORT_TRANSFER;; ++ case -ENODEV: ++ case -ESHUTDOWN: ++ case -ENOENT: ++ return USBD_STATUS_DEVICE_GONE; ++ case -ENOMEM: ++ return USBD_STATUS_NO_MEMORY; ++ case -EINVAL: ++ return USBD_STATUS_REQUEST_FAILED; ++ default: ++ return USBD_STATUS_NOT_SUPPORTED; ++ } ++} ++ ++/* for a given USBD_STATUS, return its corresponding NTSTATUS (for irp) */ ++static NTSTATUS nt_urb_irp_status(USBD_STATUS nt_urb_status) ++{ ++ switch (nt_urb_status) { ++ case USBD_STATUS_SUCCESS: ++ return STATUS_SUCCESS; ++ case USBD_STATUS_DEVICE_GONE: ++ return STATUS_DEVICE_REMOVED; ++ case USBD_STATUS_PENDING: ++ return STATUS_PENDING; ++ case USBD_STATUS_NOT_SUPPORTED: ++ return STATUS_NOT_IMPLEMENTED; ++ case USBD_STATUS_NO_MEMORY: ++ return STATUS_NO_MEMORY; ++ case USBD_STATUS_REQUEST_FAILED: ++ return STATUS_NOT_SUPPORTED; ++ default: ++ return STATUS_FAILURE; ++ } ++} ++ ++static void wrap_free_urb(struct urb *urb) ++{ ++ struct wrap_urb *wrap_urb = urb->context; ++ struct irp *irp = wrap_urb->irp; ++ struct wrap_device *wd = IRP_WRAP_DEVICE(irp); ++ ++ USBTRACE("freeing urb: %p", urb); ++ irp->cancel_routine = NULL; ++ IRP_WRAP_URB(irp) = NULL; ++ if (wrap_urb->flags & WRAP_URB_COPY_BUFFER) { ++ USBTRACE("freeing DMA buffer for URB: %p %p", ++ urb, urb->transfer_buffer); ++ usb_free_coherent(wd->usb.udev, urb->transfer_buffer_length, ++ urb->transfer_buffer, urb->transfer_dma); ++ } ++ kfree(urb->setup_packet); ++ if (wd->usb.num_alloc_urbs > MAX_ALLOCATED_URBS) { ++ IoAcquireCancelSpinLock(&irp->cancel_irql); ++ RemoveEntryList(&wrap_urb->list); ++ wd->usb.num_alloc_urbs--; ++ IoReleaseCancelSpinLock(irp->cancel_irql); ++ usb_free_urb(urb); ++ kfree(wrap_urb); ++ } else { ++ wrap_urb->state = URB_FREE; ++ wrap_urb->flags = 0; ++ wrap_urb->irp = NULL; ++ } ++ return; ++} ++ ++void wrap_suspend_urbs(struct wrap_device *wd) ++{ ++ /* TODO: do we need to cancel urbs? */ ++ USBTRACE("%p, %d", wd, wd->usb.num_alloc_urbs); ++} ++ ++void wrap_resume_urbs(struct wrap_device *wd) ++{ ++ /* TODO: do we need to resubmit urbs? */ ++ USBTRACE("%p, %d", wd, wd->usb.num_alloc_urbs); ++} ++ ++wstdcall void wrap_cancel_irp(struct device_object *dev_obj, struct irp *irp) ++{ ++ struct urb *urb; ++ struct wrap_urb *wrap_urb = IRP_WRAP_URB(irp); ++ ++ /* NB: this function is called holding Cancel spinlock */ ++ USBENTER("irp: %p", irp); ++ urb = wrap_urb->urb; ++ USBTRACE("canceling urb %p", urb); ++ if (wrap_cancel_urb(IRP_WRAP_URB(irp))) { ++ irp->cancel = FALSE; ++ ERROR("urb %p can't be canceled: %d", urb, wrap_urb->state); ++ } else ++ USBTRACE("urb %p canceled", urb); ++ IoReleaseCancelSpinLock(irp->cancel_irql); ++ return; ++} ++WIN_FUNC_DECL(wrap_cancel_irp,2) ++ ++static struct urb *wrap_alloc_urb(struct irp *irp, unsigned int pipe, ++ void *buf, unsigned int buf_len) ++{ ++ struct urb *urb; ++ gfp_t alloc_flags; ++ struct wrap_urb *wrap_urb; ++ struct wrap_device *wd; ++ ++ USBENTER("irp: %p", irp); ++ wd = IRP_WRAP_DEVICE(irp); ++ ++ /* Don't interfere with URB cleanup by the kernel */ ++ if (test_bit(HW_DISABLED, &wd->hw_status)) ++ return NULL; ++ ++ alloc_flags = irql_gfp(); ++ IoAcquireCancelSpinLock(&irp->cancel_irql); ++ urb = NULL; ++ nt_list_for_each_entry(wrap_urb, &wd->usb.wrap_urb_list, list) { ++ if (cmpxchg(&wrap_urb->state, URB_FREE, ++ URB_ALLOCATED) == URB_FREE) { ++ urb = wrap_urb->urb; ++ /* Clean URB but keep the refcount */ ++ memset((char *)urb + sizeof(urb->kref), 0, ++ sizeof(*urb) - sizeof(urb->kref)); ++ break; ++ } ++ } ++ if (!urb) { ++ IoReleaseCancelSpinLock(irp->cancel_irql); ++ wrap_urb = kzalloc(sizeof(*wrap_urb), alloc_flags); ++ if (!wrap_urb) { ++ WARNING("couldn't allocate memory"); ++ return NULL; ++ } ++ urb = usb_alloc_urb(0, alloc_flags); ++ if (!urb) { ++ WARNING("couldn't allocate urb"); ++ kfree(wrap_urb); ++ return NULL; ++ } ++ IoAcquireCancelSpinLock(&irp->cancel_irql); ++ wrap_urb->urb = urb; ++ wrap_urb->state = URB_ALLOCATED; ++ InsertTailList(&wd->usb.wrap_urb_list, &wrap_urb->list); ++ wd->usb.num_alloc_urbs++; ++ } ++ ++#ifdef URB_ASYNC_UNLINK ++ urb->transfer_flags |= URB_ASYNC_UNLINK; ++#elif defined(USB_ASYNC_UNLINK) ++ urb->transfer_flags |= USB_ASYNC_UNLINK; ++#endif ++ urb->context = wrap_urb; ++ wrap_urb->irp = irp; ++ IRP_WRAP_URB(irp) = wrap_urb; ++ /* called as Windows function */ ++ irp->cancel_routine = WIN_FUNC_PTR(wrap_cancel_irp,2); ++ IoReleaseCancelSpinLock(irp->cancel_irql); ++ USBTRACE("urb: %p", urb); ++ ++ urb->transfer_buffer_length = buf_len; ++ if (buf_len && buf && (!virt_addr_valid(buf) ++#if defined(CONFIG_HIGHMEM) || defined(CONFIG_HIGHMEM4G) ++ || PageHighMem(virt_to_page(buf)) ++#endif ++ )) { ++ urb->transfer_buffer = ++ usb_alloc_coherent(wd->usb.udev, buf_len, alloc_flags, ++ &urb->transfer_dma); ++ if (!urb->transfer_buffer) { ++ WARNING("couldn't allocate dma buf"); ++ IoAcquireCancelSpinLock(&irp->cancel_irql); ++ irp->cancel_routine = NULL; ++ wrap_urb->state = URB_FREE; ++ wrap_urb->irp = NULL; ++ IRP_WRAP_URB(irp) = NULL; ++ IoReleaseCancelSpinLock(irp->cancel_irql); ++ return NULL; ++ } ++ if (urb->transfer_dma) ++ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ wrap_urb->flags |= WRAP_URB_COPY_BUFFER; ++ if (usb_pipeout(pipe)) ++ memcpy(urb->transfer_buffer, buf, buf_len); ++ USBTRACE("DMA buf for urb %p: %p", urb, urb->transfer_buffer); ++ } else ++ urb->transfer_buffer = buf; ++ return urb; ++} ++ ++static USBD_STATUS wrap_submit_urb(struct irp *irp) ++{ ++ int ret; ++ struct wrap_urb *wrap_urb = IRP_WRAP_URB(irp); ++ struct urb *urb = wrap_urb->urb; ++ union nt_urb *nt_urb = IRP_URB(irp); ++ ++#ifdef USB_DEBUG ++ if (wrap_urb->state != URB_ALLOCATED) { ++ ERROR("urb %p is in wrong state: %d", ++ urb, wrap_urb->state); ++ NT_URB_STATUS(nt_urb) = USBD_STATUS_REQUEST_FAILED; ++ return NT_URB_STATUS(nt_urb); ++ } ++ wrap_urb->id = pre_atomic_add(urb_id, 1); ++#endif ++ DUMP_WRAP_URB(IRP_WRAP_URB(irp), USB_DIR_OUT); ++ irp->io_status.status = STATUS_PENDING; ++ irp->io_status.info = 0; ++ NT_URB_STATUS(nt_urb) = USBD_STATUS_PENDING; ++ IoMarkIrpPending(irp); ++ DUMP_URB_BUFFER(urb, USB_DIR_OUT); ++ USBTRACE("%p", urb); ++ wrap_urb->state = URB_SUBMITTED; ++ ret = usb_submit_urb(urb, irql_gfp()); ++ if (ret) { ++ USBTRACE("ret: %d", ret); ++ wrap_free_urb(urb); ++ /* we assume that IRP was not in pending state before */ ++ IoUnmarkIrpPending(irp); ++ NT_URB_STATUS(nt_urb) = wrap_urb_status(ret); ++ USBEXIT(return NT_URB_STATUS(nt_urb)); ++ } else ++ USBEXIT(return USBD_STATUS_PENDING); ++} ++ ++static void wrap_urb_complete(struct urb *urb ISR_PT_REGS_PARAM_DECL) ++{ ++ struct irp *irp; ++ struct wrap_urb *wrap_urb; ++ ++ wrap_urb = urb->context; ++ USBTRACE("%p (%p) completed", wrap_urb, urb); ++ irp = wrap_urb->irp; ++ DUMP_WRAP_URB(wrap_urb, USB_DIR_IN); ++ irp->cancel_routine = NULL; ++#ifdef USB_DEBUG ++ if (wrap_urb->state != URB_SUBMITTED) { ++ WARNING("urb %p in wrong state: %d (%d)", urb, wrap_urb->state, ++ urb->status); ++ return; ++ } ++#endif ++ wrap_urb->state = URB_COMPLETED; ++ spin_lock(&wrap_urb_complete_list_lock); ++ InsertTailList(&wrap_urb_complete_list, &wrap_urb->complete_list); ++ spin_unlock(&wrap_urb_complete_list_lock); ++ queue_work(ntos_wq, &wrap_urb_complete_work); ++} ++ ++/* one worker for all devices */ ++static void wrap_urb_complete_worker(struct work_struct *dummy) ++{ ++ struct irp *irp; ++ struct urb *urb; ++ struct usbd_bulk_or_intr_transfer *bulk_int_tx; ++ struct usbd_vendor_or_class_request *vc_req; ++ union nt_urb *nt_urb; ++ struct wrap_urb *wrap_urb; ++ struct nt_list *ent; ++ unsigned long flags; ++ ++ USBENTER(""); ++ while (1) { ++ spin_lock_irqsave(&wrap_urb_complete_list_lock, flags); ++ ent = RemoveHeadList(&wrap_urb_complete_list); ++ spin_unlock_irqrestore(&wrap_urb_complete_list_lock, flags); ++ if (!ent) ++ break; ++ wrap_urb = container_of(ent, struct wrap_urb, complete_list); ++ urb = wrap_urb->urb; ++#ifdef USB_DEBUG ++ if (wrap_urb->state != URB_COMPLETED && ++ wrap_urb->state != URB_INT_UNLINKED) ++ WARNING("urb %p in wrong state: %d", ++ urb, wrap_urb->state); ++#endif ++ irp = wrap_urb->irp; ++ DUMP_IRP(irp); ++ nt_urb = IRP_URB(irp); ++ USBTRACE("urb: %p, nt_urb: %p, status: %d", ++ urb, nt_urb, urb->status); ++ switch (urb->status) { ++ case 0: ++ /* successfully transferred */ ++ irp->io_status.info = urb->actual_length; ++ if (nt_urb->header.function == ++ URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) { ++ bulk_int_tx = &nt_urb->bulk_int_transfer; ++ bulk_int_tx->transfer_buffer_length = ++ urb->actual_length; ++ DUMP_URB_BUFFER(urb, USB_DIR_IN); ++ if ((wrap_urb->flags & WRAP_URB_COPY_BUFFER) && ++ usb_pipein(urb->pipe)) ++ memcpy(bulk_int_tx->transfer_buffer, ++ urb->transfer_buffer, ++ urb->actual_length); ++ } else { // vendor or class request ++ vc_req = &nt_urb->vendor_class_request; ++ vc_req->transfer_buffer_length = ++ urb->actual_length; ++ DUMP_URB_BUFFER(urb, USB_DIR_IN); ++ if ((wrap_urb->flags & WRAP_URB_COPY_BUFFER) && ++ usb_pipein(urb->pipe)) ++ memcpy(vc_req->transfer_buffer, ++ urb->transfer_buffer, ++ urb->actual_length); ++ } ++ NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS; ++ irp->io_status.status = STATUS_SUCCESS; ++ break; ++ case -ENOENT: ++ case -ECONNRESET: ++ /* urb canceled */ ++ irp->io_status.info = 0; ++ TRACE2("urb %p canceled", urb); ++ NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS; ++ irp->io_status.status = STATUS_CANCELLED; ++ break; ++ default: ++ TRACE2("irp: %p, urb: %p, status: %d/%d", ++ irp, urb, urb->status, wrap_urb->state); ++ irp->io_status.info = 0; ++ NT_URB_STATUS(nt_urb) = wrap_urb_status(urb->status); ++ irp->io_status.status = ++ nt_urb_irp_status(NT_URB_STATUS(nt_urb)); ++ break; ++ } ++ wrap_free_urb(urb); ++ IoCompleteRequest(irp, IO_NO_INCREMENT); ++ } ++ USBEXIT(return); ++} ++ ++static USBD_STATUS wrap_bulk_or_intr_trans(struct irp *irp) ++{ ++ struct usb_endpoint_descriptor *pipe_handle; ++ struct urb *urb; ++ unsigned int pipe; ++ struct usbd_bulk_or_intr_transfer *bulk_int_tx; ++ USBD_STATUS status; ++ struct wrap_device *wd = IRP_WRAP_DEVICE(irp); ++ struct usb_device *udev = wd->usb.udev; ++ union nt_urb *nt_urb = IRP_URB(irp); ++ ++ bulk_int_tx = &nt_urb->bulk_int_transfer; ++ pipe_handle = bulk_int_tx->pipe_handle; ++ USBTRACE("flags: 0x%x, length: %u, buffer: %p, handle: %p", ++ bulk_int_tx->transfer_flags, ++ bulk_int_tx->transfer_buffer_length, ++ bulk_int_tx->transfer_buffer, pipe_handle); ++ ++ if (USBD_IS_BULK_PIPE(pipe_handle)) { ++ if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN) ++ pipe = usb_rcvbulkpipe(udev, ++ pipe_handle->bEndpointAddress); ++ else ++ pipe = usb_sndbulkpipe(udev, ++ pipe_handle->bEndpointAddress); ++ } else { ++ if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN) ++ pipe = usb_rcvintpipe(udev, ++ pipe_handle->bEndpointAddress); ++ else ++ pipe = usb_sndintpipe(udev, ++ pipe_handle->bEndpointAddress); ++ } ++ ++ DUMP_IRP(irp); ++ urb = wrap_alloc_urb(irp, pipe, bulk_int_tx->transfer_buffer, ++ bulk_int_tx->transfer_buffer_length); ++ if (!urb) { ++ ERROR("couldn't allocate urb"); ++ return USBD_STATUS_NO_MEMORY; ++ } ++ if (usb_pipein(pipe) && ++ (!(bulk_int_tx->transfer_flags & USBD_SHORT_TRANSFER_OK))) { ++ USBTRACE("short not ok"); ++ urb->transfer_flags |= URB_SHORT_NOT_OK; ++ } ++ if (usb_pipebulk(pipe)) { ++ usb_fill_bulk_urb(urb, udev, pipe, urb->transfer_buffer, ++ bulk_int_tx->transfer_buffer_length, ++ wrap_urb_complete, urb->context); ++ USBTRACE("submitting bulk urb %p on pipe 0x%x (ep 0x%x)", ++ urb, urb->pipe, pipe_handle->bEndpointAddress); ++ } else { ++ usb_fill_int_urb(urb, udev, pipe, urb->transfer_buffer, ++ bulk_int_tx->transfer_buffer_length, ++ wrap_urb_complete, urb->context, ++ pipe_handle->bInterval); ++ USBTRACE("submitting interrupt urb %p on pipe 0x%x (ep 0x%x), " ++ "intvl: %d", urb, urb->pipe, ++ pipe_handle->bEndpointAddress, pipe_handle->bInterval); ++ } ++ status = wrap_submit_urb(irp); ++ USBTRACE("status: %08X", status); ++ USBEXIT(return status); ++} ++ ++static USBD_STATUS wrap_vendor_or_class_req(struct irp *irp) ++{ ++ u8 req_type; ++ unsigned int pipe; ++ struct usbd_vendor_or_class_request *vc_req; ++ USBD_STATUS status; ++ struct urb *urb; ++ struct usb_ctrlrequest *dr; ++ struct wrap_device *wd = IRP_WRAP_DEVICE(irp); ++ struct usb_device *udev = wd->usb.udev; ++ union nt_urb *nt_urb = IRP_URB(irp); ++ ++ vc_req = &nt_urb->vendor_class_request; ++ USBTRACE("bits: %x, req: %x, val: %08x, index: %08x, flags: %x," ++ "buf: %p, len: %d", vc_req->reserved_bits, vc_req->request, ++ vc_req->value, vc_req->index, vc_req->transfer_flags, ++ vc_req->transfer_buffer, vc_req->transfer_buffer_length); ++ ++ USBTRACE("%x", nt_urb->header.function); ++ switch (nt_urb->header.function) { ++ case URB_FUNCTION_VENDOR_DEVICE: ++ req_type = USB_TYPE_VENDOR | USB_RECIP_DEVICE; ++ break; ++ case URB_FUNCTION_VENDOR_INTERFACE: ++ req_type = USB_TYPE_VENDOR | USB_RECIP_INTERFACE; ++ break; ++ case URB_FUNCTION_VENDOR_ENDPOINT: ++ req_type = USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; ++ break; ++ case URB_FUNCTION_VENDOR_OTHER: ++ req_type = USB_TYPE_VENDOR | USB_RECIP_OTHER; ++ break; ++ case URB_FUNCTION_CLASS_DEVICE: ++ req_type = USB_TYPE_CLASS | USB_RECIP_DEVICE; ++ break; ++ case URB_FUNCTION_CLASS_INTERFACE: ++ req_type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; ++ break; ++ case URB_FUNCTION_CLASS_ENDPOINT: ++ req_type = USB_TYPE_CLASS | USB_RECIP_ENDPOINT; ++ break; ++ case URB_FUNCTION_CLASS_OTHER: ++ req_type = USB_TYPE_CLASS | USB_RECIP_OTHER; ++ break; ++ default: ++ ERROR("unknown request type: %x", nt_urb->header.function); ++ req_type = 0; ++ break; ++ } ++ ++ req_type |= vc_req->reserved_bits; ++ USBTRACE("req type: %08x", req_type); ++ ++ if (vc_req->transfer_flags & USBD_TRANSFER_DIRECTION_IN) { ++ pipe = usb_rcvctrlpipe(udev, 0); ++ req_type |= USB_DIR_IN; ++ USBTRACE("pipe: %x, dir in", pipe); ++ } else { ++ pipe = usb_sndctrlpipe(udev, 0); ++ req_type |= USB_DIR_OUT; ++ USBTRACE("pipe: %x, dir out", pipe); ++ } ++ urb = wrap_alloc_urb(irp, pipe, vc_req->transfer_buffer, ++ vc_req->transfer_buffer_length); ++ if (!urb) { ++ ERROR("couldn't allocate urb"); ++ return USBD_STATUS_NO_MEMORY; ++ } ++ ++ if (usb_pipein(pipe) && ++ (!(vc_req->transfer_flags & USBD_SHORT_TRANSFER_OK))) { ++ USBTRACE("short not ok"); ++ urb->transfer_flags |= URB_SHORT_NOT_OK; ++ } ++ ++ dr = kzalloc(sizeof(*dr), irql_gfp()); ++ if (!dr) { ++ ERROR("couldn't allocate memory"); ++ wrap_free_urb(urb); ++ return USBD_STATUS_NO_MEMORY; ++ } ++ dr->bRequestType = req_type; ++ dr->bRequest = vc_req->request; ++ dr->wValue = cpu_to_le16(vc_req->value); ++ dr->wIndex = cpu_to_le16((u16)vc_req->index); ++ dr->wLength = cpu_to_le16((u16)urb->transfer_buffer_length); ++ ++ usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr, ++ urb->transfer_buffer, urb->transfer_buffer_length, ++ wrap_urb_complete, urb->context); ++ status = wrap_submit_urb(irp); ++ USBTRACE("status: %08X", status); ++ USBEXIT(return status); ++} ++ ++static USBD_STATUS wrap_reset_pipe(struct usb_device *udev, struct irp *irp) ++{ ++ int ret; ++ union nt_urb *nt_urb; ++ struct usb_endpoint_descriptor *pipe_handle; ++ unsigned int pipe1, pipe2; ++ ++ nt_urb = IRP_URB(irp); ++ pipe_handle = nt_urb->pipe_req.pipe_handle; ++ /* TODO: not clear if both directions should be cleared? */ ++ if (USBD_IS_BULK_PIPE(pipe_handle)) { ++ pipe1 = usb_rcvbulkpipe(udev, pipe_handle->bEndpointAddress); ++ pipe2 = usb_sndbulkpipe(udev, pipe_handle->bEndpointAddress); ++ } else if (USBD_IS_INT_PIPE(pipe_handle)) { ++ pipe1 = usb_rcvintpipe(udev, pipe_handle->bEndpointAddress); ++ pipe2 = pipe1; ++ } else { ++ WARNING("invalid pipe %d", pipe_handle->bEndpointAddress); ++ return USBD_STATUS_INVALID_PIPE_HANDLE; ++ } ++ USBTRACE("ep: %d, pipe: 0x%x", pipe_handle->bEndpointAddress, pipe1); ++ ret = usb_clear_halt(udev, pipe1); ++ if (ret) ++ USBTRACE("resetting pipe %d failed: %d", pipe1, ret); ++ if (pipe2 != pipe1) { ++ ret = usb_clear_halt(udev, pipe2); ++ if (ret) ++ USBTRACE("resetting pipe %d failed: %d", pipe2, ret); ++ } ++// return wrap_urb_status(ret); ++ return USBD_STATUS_SUCCESS; ++} ++ ++static USBD_STATUS wrap_abort_pipe(struct usb_device *udev, struct irp *irp) ++{ ++ union nt_urb *nt_urb; ++ struct usb_endpoint_descriptor *pipe_handle; ++ struct wrap_urb *wrap_urb; ++ struct wrap_device *wd; ++ KIRQL irql; ++ ++ wd = IRP_WRAP_DEVICE(irp); ++ nt_urb = IRP_URB(irp); ++ pipe_handle = nt_urb->pipe_req.pipe_handle; ++ USBENTER("%p, %x", irp, pipe_handle->bEndpointAddress); ++ IoAcquireCancelSpinLock(&irql); ++ nt_list_for_each_entry(wrap_urb, &wd->usb.wrap_urb_list, list) { ++ USBTRACE("%p, %p, %d, %x, %x", wrap_urb, wrap_urb->urb, ++ wrap_urb->state, wrap_urb->urb->pipe, ++ usb_pipeendpoint(wrap_urb->urb->pipe)); ++ /* for WG111T driver, urbs for endpoint 0 should also ++ * be canceled */ ++ if ((usb_pipeendpoint(wrap_urb->urb->pipe) == ++ pipe_handle->bEndpointAddress) || ++ (usb_pipeendpoint(wrap_urb->urb->pipe) == 0)) { ++ if (wrap_cancel_urb(wrap_urb) == 0) ++ USBTRACE("canceled wrap_urb: %p", wrap_urb); ++ } ++ } ++ IoReleaseCancelSpinLock(irql); ++ NT_URB_STATUS(nt_urb) = USBD_STATUS_CANCELED; ++ USBEXIT(return USBD_STATUS_SUCCESS); ++} ++ ++static USBD_STATUS wrap_set_clear_feature(struct usb_device *udev, ++ struct irp *irp) ++{ ++ union nt_urb *nt_urb; ++ struct urb_control_feature_request *feat_req; ++ int ret = 0; ++ __u8 request, type; ++ __u16 feature; ++ ++ nt_urb = IRP_URB(irp); ++ feat_req = &nt_urb->feat_req; ++ feature = feat_req->feature_selector; ++ switch (nt_urb->header.function) { ++ case URB_FUNCTION_SET_FEATURE_TO_DEVICE: ++ request = USB_REQ_SET_FEATURE; ++ type = USB_DT_DEVICE; ++ break; ++ case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: ++ request = USB_REQ_SET_FEATURE; ++ type = USB_DT_INTERFACE; ++ break; ++ case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: ++ request = USB_REQ_SET_FEATURE; ++ type = USB_DT_ENDPOINT; ++ break; ++ case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE: ++ request = USB_REQ_CLEAR_FEATURE; ++ type = USB_DT_DEVICE; ++ break; ++ case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: ++ request = USB_REQ_CLEAR_FEATURE; ++ type = USB_DT_INTERFACE; ++ break; ++ case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: ++ request = USB_REQ_CLEAR_FEATURE; ++ type = USB_DT_ENDPOINT; ++ break; ++ default: ++ WARNING("invalid function: %x", nt_urb->header.function); ++ NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED; ++ return NT_URB_STATUS(nt_urb); ++ } ++ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, type, ++ feature, feat_req->index, NULL, 0, 1000); ++ NT_URB_STATUS(nt_urb) = wrap_urb_status(ret); ++ USBEXIT(return NT_URB_STATUS(nt_urb)); ++} ++ ++static USBD_STATUS wrap_get_status_request(struct usb_device *udev, ++ struct irp *irp) ++{ ++ union nt_urb *nt_urb; ++ struct urb_control_get_status_request *status_req; ++ int ret = 0; ++ __u8 type; ++ ++ nt_urb = IRP_URB(irp); ++ status_req = &nt_urb->status_req; ++ switch (nt_urb->header.function) { ++ case URB_FUNCTION_GET_STATUS_FROM_DEVICE: ++ type = USB_RECIP_DEVICE; ++ break; ++ case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: ++ type = USB_RECIP_INTERFACE; ++ break; ++ case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: ++ type = USB_RECIP_ENDPOINT; ++ break; ++ default: ++ WARNING("invalid function: %x", nt_urb->header.function); ++ NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED; ++ return NT_URB_STATUS(nt_urb); ++ } ++ assert(status_req->transfer_buffer_length == sizeof(u16)); ++ ret = usb_get_status(udev, type, status_req->index, ++ status_req->transfer_buffer); ++ if (ret >= 0) { ++ assert(ret <= status_req->transfer_buffer_length); ++ status_req->transfer_buffer_length = ret; ++ NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS; ++ } else ++ NT_URB_STATUS(nt_urb) = wrap_urb_status(ret); ++ USBEXIT(return NT_URB_STATUS(nt_urb)); ++} ++ ++static void set_intf_pipe_info(struct wrap_device *wd, ++ struct usb_interface *usb_intf, ++ struct usbd_interface_information *intf) ++{ ++ int i; ++ struct usb_endpoint_descriptor *ep; ++ struct usbd_pipe_information *pipe; ++ ++ for (i = 0; i < CUR_ALT_SETTING(usb_intf)->desc.bNumEndpoints; i++) { ++ ep = &(CUR_ALT_SETTING(usb_intf)->endpoint[i]).desc; ++ if (i >= intf->bNumEndpoints) { ++ ERROR("intf %p has only %d endpoints, " ++ "ignoring endpoints above %d", ++ intf, intf->bNumEndpoints, i); ++ break; ++ } ++ pipe = &intf->pipes[i]; ++ ++ if (pipe->flags & USBD_PF_CHANGE_MAX_PACKET) ++ USBTRACE("pkt_sz: %d: %d", pipe->wMaxPacketSize, ++ pipe->max_tx_size); ++ USBTRACE("driver wants max_tx_size to %d", ++ pipe->max_tx_size); ++ ++ pipe->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); ++ pipe->bEndpointAddress = ep->bEndpointAddress; ++ pipe->type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ if (pipe->type == UsbdPipeTypeInterrupt) { ++ /* Windows and Linux differ in how the ++ * bInterval is interpreted */ ++ /* for low speed: ++ interval (Windows) -> frames per ms (Linux) ++ 0 to 15 -> 8 ++ 16 to 35 -> 16 ++ 36 to 255 -> 32 ++ ++ for full speed: interval -> frames per ms ++ 1 -> 1 ++ 2 to 3 -> 2 ++ 4 to 7 -> 4 ++ 8 to 15 -> 8 ++ 16 to 31 -> 16 ++ 32 to 255 -> 32 ++ ++ for high speed: interval -> microframes ++ 1 -> 1 ++ 2 -> 2 ++ 3 -> 4 ++ 4 -> 8 ++ 5 -> 16 ++ 6 -> 32 ++ 7 to 255 -> 32 ++ */ ++ if (wd->usb.udev->speed == USB_SPEED_LOW) ++ pipe->bInterval = ep->bInterval + 5; ++ else if (wd->usb.udev->speed == USB_SPEED_FULL) ++ pipe->bInterval = ep->bInterval; ++ else { ++ int j, k; ++ for (j = k = 1; j < ep->bInterval; k++) ++ j *= 2; ++ pipe->bInterval = k; ++ } ++ } ++ pipe->handle = ep; ++ USBTRACE("%d: ep 0x%x, type %d, pkt_sz %d, intv %d (%d)," ++ "type: %d, handle %p", i, ep->bEndpointAddress, ++ ep->bmAttributes, pipe->wMaxPacketSize, ep->bInterval, ++ pipe->bInterval, pipe->type, pipe->handle); ++ } ++} ++ ++static USBD_STATUS wrap_select_configuration(struct wrap_device *wd, ++ union nt_urb *nt_urb, ++ struct irp *irp) ++{ ++ int i, ret; ++ struct usbd_select_configuration *sel_conf; ++ struct usb_device *udev; ++ struct usbd_interface_information *intf; ++ struct usb_config_descriptor *config; ++ struct usb_interface *usb_intf; ++ ++ udev = wd->usb.udev; ++ sel_conf = &nt_urb->select_conf; ++ config = sel_conf->config; ++ USBTRACE("%p", config); ++ if (config == NULL) { ++ kill_all_urbs(wd, 1); ++ ret = usb_reset_configuration(udev); ++ return wrap_urb_status(ret); ++ } ++ ++ USBTRACE("conf: %d, type: %d, length: %d, numif: %d, attr: %08x", ++ config->bConfigurationValue, config->bDescriptorType, ++ config->wTotalLength, config->bNumInterfaces, ++ config->bmAttributes); ++ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), ++ USB_REQ_SET_CONFIGURATION, 0, ++ config->bConfigurationValue, 0, ++ NULL, 0, USB_CTRL_SET_TIMEOUT); ++ if (ret < 0) { ++ ERROR("ret: %d", ret); ++ return wrap_urb_status(ret); ++ } ++ sel_conf->handle = udev->actconfig; ++ intf = &sel_conf->intf; ++ for (i = 0; i < config->bNumInterfaces && intf->bLength > 0; ++ i++, intf = (((void *)intf) + intf->bLength)) { ++ ++ USBTRACE("intf: %d, alt setting: %d", ++ intf->bInterfaceNumber, intf->bAlternateSetting); ++ ret = usb_set_interface(udev, intf->bInterfaceNumber, ++ intf->bAlternateSetting); ++ if (ret < 0) { ++ ERROR("failed with %d", ret); ++ return wrap_urb_status(ret); ++ } ++ usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber); ++ if (!usb_intf) { ++ ERROR("couldn't obtain ifnum"); ++ return USBD_STATUS_REQUEST_FAILED; ++ } ++ USBTRACE("intf: %p, num ep: %d", intf, intf->bNumEndpoints); ++ set_intf_pipe_info(wd, usb_intf, intf); ++ } ++ return USBD_STATUS_SUCCESS; ++} ++ ++static USBD_STATUS wrap_select_interface(struct wrap_device *wd, ++ union nt_urb *nt_urb, ++ struct irp *irp) ++{ ++ int ret; ++ struct usbd_select_interface *sel_intf; ++ struct usb_device *udev; ++ struct usbd_interface_information *intf; ++ struct usb_interface *usb_intf; ++ ++ udev = wd->usb.udev; ++ sel_intf = &nt_urb->select_intf; ++ intf = &sel_intf->intf; ++ ++ ret = usb_set_interface(udev, intf->bInterfaceNumber, ++ intf->bAlternateSetting); ++ if (ret < 0) { ++ ERROR("failed with %d", ret); ++ return wrap_urb_status(ret); ++ } ++ usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber); ++ if (!usb_intf) { ++ ERROR("couldn't get interface information"); ++ return USBD_STATUS_REQUEST_FAILED; ++ } ++ USBTRACE("intf: %p, num ep: %d", usb_intf, intf->bNumEndpoints); ++ set_intf_pipe_info(wd, usb_intf, intf); ++ return USBD_STATUS_SUCCESS; ++} ++ ++static int wrap_usb_get_string(struct usb_device *udev, unsigned short langid, ++ unsigned char index, void *buf, int size) ++{ ++ int i, ret; ++ /* if langid is 0, return array of languages supported in ++ * buf */ ++ for (i = 0; i < 3; i++) { ++ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), ++ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, ++ (USB_DT_STRING << 8) + index, langid, ++ buf, size, USB_CTRL_GET_TIMEOUT); ++ if (ret > 0 || ret == -EPIPE) ++ break; ++ } ++ return ret; ++} ++ ++static USBD_STATUS wrap_get_descriptor(struct wrap_device *wd, ++ union nt_urb *nt_urb, struct irp *irp) ++{ ++ struct usbd_control_descriptor_request *control_desc; ++ int ret = 0; ++ struct usb_device *udev; ++ ++ udev = wd->usb.udev; ++ control_desc = &nt_urb->control_desc; ++ USBTRACE("desctype = %d, descindex = %d, transfer_buffer = %p," ++ "transfer_buffer_length = %d", control_desc->desc_type, ++ control_desc->index, control_desc->transfer_buffer, ++ control_desc->transfer_buffer_length); ++ ++ if (control_desc->desc_type == USB_DT_STRING) { ++ USBTRACE("langid: %x", control_desc->language_id); ++ ret = wrap_usb_get_string(udev, control_desc->language_id, ++ control_desc->index, ++ control_desc->transfer_buffer, ++ control_desc->transfer_buffer_length); ++ } else { ++ ret = usb_get_descriptor(udev, control_desc->desc_type, ++ control_desc->index, ++ control_desc->transfer_buffer, ++ control_desc->transfer_buffer_length); ++ } ++ if (ret < 0) { ++ USBTRACE("request %d failed: %d", control_desc->desc_type, ret); ++ control_desc->transfer_buffer_length = 0; ++ return wrap_urb_status(ret); ++ } else { ++ USBTRACE("ret: %08x", ret); ++ control_desc->transfer_buffer_length = ret; ++ irp->io_status.info = ret; ++ return USBD_STATUS_SUCCESS; ++ } ++} ++ ++static USBD_STATUS wrap_process_nt_urb(struct irp *irp) ++{ ++ USBD_STATUS status; ++ struct wrap_device *wd = IRP_WRAP_DEVICE(irp); ++ struct usb_device *udev = wd->usb.udev; ++ union nt_urb *nt_urb = IRP_URB(irp); ++ ++ USBENTER("nt_urb = %p, irp = %p, length = %d, function = %x", ++ nt_urb, irp, nt_urb->header.length, nt_urb->header.function); ++ ++ if (test_bit(HW_DISABLED, &wd->hw_status)) { ++ status = USBD_STATUS_DEVICE_GONE; ++ NT_URB_STATUS(nt_urb) = status; ++ return status; ++ } ++ ++ DUMP_IRP(irp); ++ switch (nt_urb->header.function) { ++ /* bulk/int and vendor/class urbs are submitted to ++ * Linux USB core; if the call is successful, urb's ++ * completion worker will return IRP later */ ++ case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: ++ USBTRACE("submitting bulk/int irp: %p", irp); ++ status = wrap_bulk_or_intr_trans(irp); ++ break; ++ ++ case URB_FUNCTION_VENDOR_DEVICE: ++ case URB_FUNCTION_VENDOR_INTERFACE: ++ case URB_FUNCTION_VENDOR_ENDPOINT: ++ case URB_FUNCTION_VENDOR_OTHER: ++ case URB_FUNCTION_CLASS_DEVICE: ++ case URB_FUNCTION_CLASS_INTERFACE: ++ case URB_FUNCTION_CLASS_ENDPOINT: ++ case URB_FUNCTION_CLASS_OTHER: ++ USBTRACE("submitting vendor/class irp: %p", irp); ++ status = wrap_vendor_or_class_req(irp); ++ break; ++ ++ /* rest are synchronous */ ++ case URB_FUNCTION_SELECT_CONFIGURATION: ++ status = wrap_select_configuration(wd, nt_urb, irp); ++ NT_URB_STATUS(nt_urb) = status; ++ break; ++ ++ case URB_FUNCTION_SELECT_INTERFACE: ++ status = wrap_select_interface(wd, nt_urb, irp); ++ NT_URB_STATUS(nt_urb) = status; ++ break; ++ ++ case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: ++ status = wrap_get_descriptor(wd, nt_urb, irp); ++ NT_URB_STATUS(nt_urb) = status; ++ break; ++ ++ case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: ++ status = wrap_reset_pipe(udev, irp); ++ NT_URB_STATUS(nt_urb) = status; ++ break; ++ ++ case URB_FUNCTION_ABORT_PIPE: ++ status = wrap_abort_pipe(udev, irp); ++ break; ++ ++ case URB_FUNCTION_SET_FEATURE_TO_DEVICE: ++ case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: ++ case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: ++ case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE: ++ case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: ++ case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: ++ status = wrap_set_clear_feature(udev, irp); ++ break; ++ ++ case URB_FUNCTION_GET_STATUS_FROM_DEVICE: ++ case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: ++ case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: ++ status = wrap_get_status_request(udev, irp); ++ break; ++ ++ default: ++ ERROR("function %x not implemented", nt_urb->header.function); ++ status = NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED; ++ break; ++ } ++ USBTRACE("status: %08X", status); ++ return status; ++} ++ ++static USBD_STATUS wrap_reset_port(struct irp *irp) ++{ ++ int ret, lock = 0; ++ struct wrap_device *wd; ++ ++ wd = IRP_WRAP_DEVICE(irp); ++ USBENTER("%p, %p", wd, wd->usb.udev); ++ lock = usb_lock_device_for_reset(wd->usb.udev, wd->usb.intf); ++ if (lock < 0) { ++ WARNING("locking failed: %d", lock); ++// return wrap_urb_status(lock); ++ return USBD_STATUS_SUCCESS; ++ } ++ ret = usb_reset_device(wd->usb.udev); ++ if (ret < 0) ++ USBTRACE("reset failed: %d", ret); ++ /* TODO: should reconfigure? */ ++ if (lock) ++ usb_unlock_device(wd->usb.udev); ++// return wrap_urb_status(ret); ++ return USBD_STATUS_SUCCESS; ++} ++ ++static USBD_STATUS wrap_get_port_status(struct irp *irp) ++{ ++ struct wrap_device *wd; ++ ULONG *status; ++ enum usb_device_state state; ++ ++ wd = IRP_WRAP_DEVICE(irp); ++ USBENTER("%p, %p", wd, wd->usb.udev); ++ status = IoGetCurrentIrpStackLocation(irp)->params.others.arg1; ++ state = wd->usb.udev->state; ++ if (state != USB_STATE_NOTATTACHED && ++ state != USB_STATE_SUSPENDED) { ++ *status |= USBD_PORT_CONNECTED; ++ if (state == USB_STATE_CONFIGURED) ++ *status |= USBD_PORT_ENABLED; ++ } ++ USBTRACE("state: %d, *status: %08X", state, *status); ++ return USBD_STATUS_SUCCESS; ++} ++ ++NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp) ++{ ++ struct io_stack_location *irp_sl; ++ struct wrap_device *wd; ++ USBD_STATUS status; ++ struct usbd_idle_callback *idle_callback; ++ ++ USBENTER("%p, %p", pdo, irp); ++ wd = pdo->reserved; ++ if (wd->usb.intf == NULL) { ++ USBTRACE("%p", irp); ++ irp->io_status.status = STATUS_DEVICE_REMOVED; ++ irp->io_status.info = 0; ++ USBEXIT(return STATUS_DEVICE_REMOVED); ++ } ++ IRP_WRAP_DEVICE(irp) = wd; ++ irp_sl = IoGetCurrentIrpStackLocation(irp); ++ switch (irp_sl->params.dev_ioctl.code) { ++ case IOCTL_INTERNAL_USB_SUBMIT_URB: ++ status = wrap_process_nt_urb(irp); ++ break; ++ case IOCTL_INTERNAL_USB_RESET_PORT: ++ status = wrap_reset_port(irp); ++ break; ++ case IOCTL_INTERNAL_USB_GET_PORT_STATUS: ++ status = wrap_get_port_status(irp); ++ break; ++ case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: ++ idle_callback = irp_sl->params.dev_ioctl.type3_input_buf; ++ (void)idle_callback; ++ USBTRACE("suspend function: %p", idle_callback->callback); ++ status = USBD_STATUS_NOT_SUPPORTED; ++ break; ++ default: ++ ERROR("ioctl %08X NOT IMPLEMENTED", ++ irp_sl->params.dev_ioctl.code); ++ status = USBD_STATUS_NOT_SUPPORTED; ++ break; ++ } ++ ++ USBTRACE("status: %08X", status); ++ if (status == USBD_STATUS_PENDING) { ++ /* don't touch this IRP - it may have been already ++ * completed/returned */ ++ return STATUS_PENDING; ++ } else { ++ irp->io_status.status = nt_urb_irp_status(status); ++ if (status != USBD_STATUS_SUCCESS) ++ irp->io_status.info = 0; ++ USBEXIT(return irp->io_status.status); ++ } ++} ++ ++/* TODO: The example on msdn in reference section suggests that second ++ * argument should be an array of usbd_interface_information, but ++ * description and examples elsewhere suggest that it should be ++ * usbd_interface_list_entry structre. Which is correct? */ ++ ++wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequestEx,2) ++ (struct usb_config_descriptor *config, ++ struct usbd_interface_list_entry *intf_list) ++{ ++ int size, i, n; ++ struct usbd_interface_information *intf; ++ struct usbd_pipe_information *pipe; ++ struct usb_interface_descriptor *intf_desc; ++ struct usbd_select_configuration *select_conf; ++ ++ USBENTER("config = %p, intf_list = %p", config, intf_list); ++ ++ /* calculate size required; select_conf already has space for ++ * one intf structure */ ++ size = sizeof(*select_conf) - sizeof(*intf); ++ for (n = 0; n < config->bNumInterfaces; n++) { ++ i = intf_list[n].intf_desc->bNumEndpoints; ++ /* intf already has space for one pipe */ ++ size += sizeof(*intf) + (i - 1) * sizeof(*pipe); ++ } ++ /* don't use kmalloc - driver frees it with ExFreePool */ ++ select_conf = ExAllocatePoolWithTag(NonPagedPool, size, ++ POOL_TAG('L', 'U', 'S', 'B')); ++ if (!select_conf) { ++ WARNING("couldn't allocate memory"); ++ return NULL; ++ } ++ memset(select_conf, 0, size); ++ intf = &select_conf->intf; ++ select_conf->handle = config; ++ for (n = 0; n < config->bNumInterfaces && intf_list[n].intf_desc; n++) { ++ /* initialize 'intf' fields in intf_list so they point ++ * to appropriate entry; these may be read/written by ++ * driver after this function returns */ ++ intf_list[n].intf = intf; ++ intf_desc = intf_list[n].intf_desc; ++ ++ i = intf_desc->bNumEndpoints; ++ intf->bLength = sizeof(*intf) + (i - 1) * sizeof(*pipe); ++ ++ intf->bInterfaceNumber = intf_desc->bInterfaceNumber; ++ intf->bAlternateSetting = intf_desc->bAlternateSetting; ++ intf->bInterfaceClass = intf_desc->bInterfaceClass; ++ intf->bInterfaceSubClass = intf_desc->bInterfaceSubClass; ++ intf->bInterfaceProtocol = intf_desc->bInterfaceProtocol; ++ intf->bNumEndpoints = intf_desc->bNumEndpoints; ++ ++ pipe = &intf->pipes[0]; ++ for (i = 0; i < intf->bNumEndpoints; i++) { ++ memset(&pipe[i], 0, sizeof(*pipe)); ++ pipe[i].max_tx_size = ++ USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; ++ } ++ intf->handle = intf_desc; ++ intf = (((void *)intf) + intf->bLength); ++ } ++ select_conf->header.function = URB_FUNCTION_SELECT_CONFIGURATION; ++ select_conf->header.length = size; ++ select_conf->config = config; ++ USBEXIT(return (union nt_urb *)select_conf); ++} ++ ++WIN_SYMBOL_MAP("_USBD_CreateConfigurationRequestEx@8", USBD_CreateConfigurationRequestEx) ++ ++wstdcall struct usb_interface_descriptor * ++WIN_FUNC(USBD_ParseConfigurationDescriptorEx,7) ++ (struct usb_config_descriptor *config, void *start, ++ LONG bInterfaceNumber, LONG bAlternateSetting, LONG bInterfaceClass, ++ LONG bInterfaceSubClass, LONG bInterfaceProtocol) ++{ ++ void *pos; ++ struct usb_interface_descriptor *intf; ++ ++ USBENTER("config = %p, start = %p, ifnum = %d, alt_setting = %d," ++ " class = %d, subclass = %d, proto = %d", config, start, ++ bInterfaceNumber, bAlternateSetting, bInterfaceClass, ++ bInterfaceSubClass, bInterfaceProtocol); ++ ++ for (pos = start; ++ pos < ((void *)config + le16_to_cpu(config->wTotalLength)); ++ pos += intf->bLength) { ++ ++ intf = pos; ++ ++ if ((intf->bDescriptorType == USB_DT_INTERFACE) && ++ ((bInterfaceNumber == -1) || ++ (intf->bInterfaceNumber == bInterfaceNumber)) && ++ ((bAlternateSetting == -1) || ++ (intf->bAlternateSetting == bAlternateSetting)) && ++ ((bInterfaceClass == -1) || ++ (intf->bInterfaceClass == bInterfaceClass)) && ++ ((bInterfaceSubClass == -1) || ++ (intf->bInterfaceSubClass == bInterfaceSubClass)) && ++ ((bInterfaceProtocol == -1) || ++ (intf->bInterfaceProtocol == bInterfaceProtocol))) { ++ USBTRACE("selected interface = %p", intf); ++ USBEXIT(return intf); ++ } ++ } ++ USBEXIT(return NULL); ++} ++ ++WIN_SYMBOL_MAP("_USBD_ParseConfigurationDescriptorEx@28", USBD_ParseConfigurationDescriptorEx) ++ ++wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequest,2) ++ (struct usb_config_descriptor *config, USHORT *size) ++{ ++ union nt_urb *nt_urb; ++ struct usbd_interface_list_entry intf_list[2]; ++ struct usb_interface_descriptor *intf_desc; ++ ++ USBENTER("config = %p, urb_size = %p", config, size); ++ ++ intf_desc = USBD_ParseConfigurationDescriptorEx(config, config, -1, -1, ++ -1, -1, -1); ++ intf_list[0].intf_desc = intf_desc; ++ intf_list[0].intf = NULL; ++ intf_list[1].intf_desc = NULL; ++ intf_list[1].intf = NULL; ++ nt_urb = USBD_CreateConfigurationRequestEx(config, intf_list); ++ if (!nt_urb) ++ return NULL; ++ ++ *size = nt_urb->select_conf.header.length; ++ USBEXIT(return nt_urb); ++} ++ ++wstdcall struct usb_interface_descriptor * ++WIN_FUNC(USBD_ParseConfigurationDescriptor,3) ++ (struct usb_config_descriptor *config, UCHAR bInterfaceNumber, ++ UCHAR bAlternateSetting) ++{ ++ return USBD_ParseConfigurationDescriptorEx(config, config, ++ bInterfaceNumber, ++ bAlternateSetting, ++ -1, -1, -1); ++} ++ ++wstdcall struct usb_descriptor_header *WIN_FUNC(USBD_ParseDescriptors,4) ++ (void *buf, ULONG length, struct usb_descriptor_header *descr, ++ LONG type) ++{ ++ while ((void *)descr < buf + length) { ++ if (descr->bDescriptorType == type) ++ return descr; ++ if (descr->bLength == 0) ++ break; ++ descr = (void *)descr + descr->bLength; ++ } ++ USBEXIT(return NULL); ++} ++ ++WIN_SYMBOL_MAP("_USBD_ParseDescriptors@16", USBD_ParseDescriptors) ++ ++wstdcall void WIN_FUNC(USBD_GetUSBDIVersion,1) ++ (struct usbd_version_info *version_info) ++{ ++ /* this function is obsolete in Windows XP */ ++ if (version_info) { ++ version_info->usbdi_version = USBDI_VERSION_XP; ++ /* TODO: how do we get this correctly? */ ++ version_info->supported_usb_version = 0x110; ++ } ++ USBEXIT(return); ++} ++ ++wstdcall void ++USBD_InterfaceGetUSBDIVersion(void *context, ++ struct usbd_version_info *version_info, ++ ULONG *hcd_capa) ++{ ++ struct wrap_device *wd = context; ++ ++ if (version_info) { ++ version_info->usbdi_version = USBDI_VERSION_XP; ++ if (wd->usb.udev->speed == USB_SPEED_HIGH) ++ version_info->supported_usb_version = 0x200; ++ else ++ version_info->supported_usb_version = 0x110; ++ } ++ *hcd_capa = USB_HCD_CAPS_SUPPORTS_RT_THREADS; ++ USBEXIT(return); ++} ++ ++wstdcall BOOLEAN USBD_InterfaceIsDeviceHighSpeed(void *context) ++{ ++ struct wrap_device *wd = context; ++ ++ USBTRACE("wd: %p", wd); ++ if (wd->usb.udev->speed == USB_SPEED_HIGH) ++ USBEXIT(return TRUE); ++ else ++ USBEXIT(return FALSE); ++} ++ ++wstdcall void USBD_InterfaceReference(void *context) ++{ ++ USBTRACE("%p", context); ++ TODO(); ++} ++ ++wstdcall void USBD_InterfaceDereference(void *context) ++{ ++ USBTRACE("%p", context); ++ TODO(); ++} ++ ++wstdcall NTSTATUS USBD_InterfaceQueryBusTime(void *context, ULONG *frame) ++{ ++ struct wrap_device *wd = context; ++ ++ *frame = usb_get_current_frame_number(wd->usb.udev); ++ USBEXIT(return STATUS_SUCCESS); ++} ++ ++wstdcall NTSTATUS USBD_InterfaceSubmitIsoOutUrb(void *context, ++ union nt_urb *nt_urb) ++{ ++ /* TODO: implement this */ ++ TODO(); ++ USBEXIT(return STATUS_NOT_IMPLEMENTED); ++} ++ ++wstdcall NTSTATUS ++USBD_InterfaceQueryBusInformation(void *context, ULONG level, void *buf, ++ ULONG *buf_length, ULONG *buf_actual_length) ++{ ++#if 0 ++ struct wrap_device *wd = context; ++ struct usb_bus *bus = wd->usb.udev->bus; ++ struct usb_bus_information_level *bus_info = buf; ++#endif ++ ++ TODO(); ++ USBEXIT(return STATUS_NOT_IMPLEMENTED); ++} ++ ++wstdcall NTSTATUS ++USBD_InterfaceLogEntry(void *context, ULONG driver_tag, ULONG enum_tag, ++ ULONG p1, ULONG p2) ++{ ++ ERROR("%p, %x, %x, %x, %x", context, driver_tag, enum_tag, p1, p2); ++ USBEXIT(return STATUS_SUCCESS); ++} ++ ++NTSTATUS ++usb_query_interface(struct wrap_device *wd, struct io_stack_location *irp_sl) ++{ ++ struct usbd_bus_interface_usbdi *intf = ++ (struct usbd_bus_interface_usbdi *) ++ irp_sl->params.query_intf.intf; ++ ++ TRACE2("type: %x, size: %d, version: %d", ++ irp_sl->params.query_intf.type->data1, ++ irp_sl->params.query_intf.size, ++ irp_sl->params.query_intf.version); ++ intf->Context = wd; ++ intf->InterfaceReference = ++ WIN_FUNC_PTR(USBD_InterfaceReference, 1); ++ intf->InterfaceDereference = ++ WIN_FUNC_PTR(USBD_InterfaceDereference, 1); ++ intf->GetUSBDIVersion = ++ WIN_FUNC_PTR(USBD_InterfaceGetUSBDIVersion, 3); ++ intf->QueryBusTime = ++ WIN_FUNC_PTR(USBD_InterfaceQueryBusTime, 2); ++ intf->SubmitIsoOutUrb = ++ WIN_FUNC_PTR(USBD_InterfaceSubmitIsoOutUrb, 2); ++ intf->QueryBusInformation = ++ WIN_FUNC_PTR(USBD_InterfaceQueryBusInformation, 5); ++ if (irp_sl->params.query_intf.version >= USB_BUSIF_USBDI_VERSION_1) ++ intf->IsDeviceHighSpeed = ++ WIN_FUNC_PTR(USBD_InterfaceIsDeviceHighSpeed, 1); ++ if (irp_sl->params.query_intf.version >= USB_BUSIF_USBDI_VERSION_2) ++ intf->LogEntry = WIN_FUNC_PTR(USBD_InterfaceLogEntry, 5); ++ return STATUS_SUCCESS; ++} ++ ++int usb_init(void) ++{ ++ InitializeListHead(&wrap_urb_complete_list); ++ spin_lock_init(&wrap_urb_complete_list_lock); ++ INIT_WORK(&wrap_urb_complete_work, wrap_urb_complete_worker); ++#ifdef USB_DEBUG ++ urb_id = 0; ++#endif ++ return 0; ++} ++ ++void usb_exit(void) ++{ ++ USBEXIT(return); ++} ++ ++int usb_init_device(struct wrap_device *wd) ++{ ++ InitializeListHead(&wd->usb.wrap_urb_list); ++ wd->usb.num_alloc_urbs = 0; ++ USBEXIT(return 0); ++} ++ ++void usb_exit_device(struct wrap_device *wd) ++{ ++ kill_all_urbs(wd, 0); ++ USBEXIT(return); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/usb.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/usb.h +--- linux-3.12.2/3rdparty/ndiswrapper/usb.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/usb.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,360 @@ ++/* ++ * Copyright (C) 2004 Jan Kiszka ++ * Copyright (C) 2005 Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _USB_H_ ++#define _USB_H_ ++ ++#include "ntoskernel.h" ++ ++#define IOCTL_INTERNAL_USB_SUBMIT_URB 0x00220003 ++#define IOCTL_INTERNAL_USB_RESET_PORT 0x00220007 ++#define IOCTL_INTERNAL_USB_GET_PORT_STATUS 0x00220013 ++#define IOCTL_INTERNAL_USB_CYCLE_PORT 0x0022001F ++#define IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION 0x00220027 ++ ++#define URB_FUNCTION_SELECT_CONFIGURATION 0x0000 ++#define URB_FUNCTION_SELECT_INTERFACE 0x0001 ++#define URB_FUNCTION_ABORT_PIPE 0x0002 ++#define URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL 0x0003 ++#define URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL 0x0004 ++#define URB_FUNCTION_GET_FRAME_LENGTH 0x0005 ++#define URB_FUNCTION_SET_FRAME_LENGTH 0x0006 ++#define URB_FUNCTION_GET_CURRENT_FRAME_NUMBER 0x0007 ++#define URB_FUNCTION_CONTROL_TRANSFER 0x0008 ++#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER 0x0009 ++#define URB_FUNCTION_ISOCH_TRANSFER 0x000A ++#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 0x000B ++#define URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE 0x000C ++#define URB_FUNCTION_SET_FEATURE_TO_DEVICE 0x000D ++#define URB_FUNCTION_SET_FEATURE_TO_INTERFACE 0x000E ++#define URB_FUNCTION_SET_FEATURE_TO_ENDPOINT 0x000F ++#define URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE 0x0010 ++#define URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE 0x0011 ++#define URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT 0x0012 ++#define URB_FUNCTION_GET_STATUS_FROM_DEVICE 0x0013 ++#define URB_FUNCTION_GET_STATUS_FROM_INTERFACE 0x0014 ++#define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT 0x0015 ++#define URB_FUNCTION_RESERVED_0X0016 0x0016 ++#define URB_FUNCTION_VENDOR_DEVICE 0x0017 ++#define URB_FUNCTION_VENDOR_INTERFACE 0x0018 ++#define URB_FUNCTION_VENDOR_ENDPOINT 0x0019 ++#define URB_FUNCTION_CLASS_DEVICE 0x001A ++#define URB_FUNCTION_CLASS_INTERFACE 0x001B ++#define URB_FUNCTION_CLASS_ENDPOINT 0x001C ++#define URB_FUNCTION_RESERVE_0X001D 0x001D ++#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 0x001E ++#define URB_FUNCTION_CLASS_OTHER 0x001F ++#define URB_FUNCTION_VENDOR_OTHER 0x0020 ++#define URB_FUNCTION_GET_STATUS_FROM_OTHER 0x0021 ++#define URB_FUNCTION_CLEAR_FEATURE_TO_OTHER 0x0022 ++#define URB_FUNCTION_SET_FEATURE_TO_OTHER 0x0023 ++#define URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT 0x0024 ++#define URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT 0x0025 ++#define URB_FUNCTION_GET_CONFIGURATION 0x0026 ++#define URB_FUNCTION_GET_INTERFACE 0x0027 ++#define URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE 0x0028 ++#define URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE 0x0029 ++#define URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR 0x002A ++#define URB_FUNCTION_RESERVE_0X002B 0x002B ++#define URB_FUNCTION_RESERVE_0X002C 0x002C ++#define URB_FUNCTION_RESERVE_0X002D 0x002D ++#define URB_FUNCTION_RESERVE_0X002E 0x002E ++#define URB_FUNCTION_RESERVE_0X002F 0x002F ++// USB 2.0 calls start at 0x0030 ++#define URB_FUNCTION_SYNC_RESET_PIPE 0x0030 ++#define URB_FUNCTION_SYNC_CLEAR_STALL 0x0031 ++#define URB_FUNCTION_CONTROL_TRANSFER_EX 0x0032 ++ ++#define USBD_PF_CHANGE_MAX_PACKET 0x00000001 ++ ++#define USBD_TRANSFER_DIRECTION_OUT 0 ++#define USBD_TRANSFER_DIRECTION_IN 1 ++ ++#define USBD_SHORT_TRANSFER_OK 0x00000002 ++#define USBD_START_ISO_TRANSFER_ASAP 0x00000004 ++#define USBD_DEFAULT_PIPE_TRANSFER 0x00000008 ++ ++#define USBD_TRANSFER_DIRECTION(flags) \ ++ ((flags) & USBD_TRANSFER_DIRECTION_IN) ++ ++enum pipe_type {UsbdPipeTypeControl = USB_ENDPOINT_XFER_CONTROL, ++ UsbdPipeTypeIsochronous = USB_ENDPOINT_XFER_ISOC, ++ UsbdPipeTypeBulk = USB_ENDPOINT_XFER_BULK, ++ UsbdPipeTypeInterrupt = USB_ENDPOINT_XFER_INT}; ++ ++#define USBD_IS_BULK_PIPE(pipe_handle) \ ++ (((pipe_handle)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) \ ++ == USB_ENDPOINT_XFER_BULK) ++ ++#define USBD_IS_INT_PIPE(pipe_handle) \ ++ (((pipe_handle)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) \ ++ == USB_ENDPOINT_XFER_INT) ++ ++#define USBD_PORT_ENABLED 0x00000001 ++#define USBD_PORT_CONNECTED 0x00000002 ++ ++typedef LONG USBD_STATUS; ++ ++#define USBD_STATUS_SUCCESS 0x0 ++#define USBD_STATUS_PENDING 0x40000000 ++#define USBD_STATUS_CANCELED 0x00010000 ++ ++#define USBD_STATUS_CRC 0xC0000001 ++#define USBD_STATUS_BTSTUFF 0xC0000002 ++#define USBD_STATUS_DATA_TOGGLE_MISMATCH 0xC0000003 ++#define USBD_STATUS_STALL_PID 0xC0000004 ++#define USBD_STATUS_DEV_NOT_RESPONDING 0xC0000005 ++#define USBD_STATUS_PID_CHECK_FAILURE 0xC0000006 ++#define USBD_STATUS_UNEXPECTED_PID 0xC0000007 ++#define USBD_STATUS_DATA_OVERRUN 0xC0000008 ++#define USBD_STATUS_DATA_UNDERRUN 0xC0000009 ++#define USBD_STATUS_RESERVED1 0xC000000A ++#define USBD_STATUS_RESERVED2 0xC000000B ++#define USBD_STATUS_BUFFER_OVERRUN 0xC000000C ++#define USBD_STATUS_BUFFER_UNDERRUN 0xC000000D ++#define USBD_STATUS_NOT_ACCESSED 0xC000000F ++#define USBD_STATUS_FIFO 0xC0000010 ++#define USBD_STATUS_XACT_ERROR 0xC0000011 ++#define USBD_STATUS_BABBLE_DETECTED 0xC0000012 ++#define USBD_STATUS_DATA_BUFFER_ERROR 0xC0000013 ++ ++#define USBD_STATUS_NOT_SUPPORTED 0xC0000E00 ++#define USBD_STATUS_BUFFER_TOO_SMALL 0xC0003000 ++#define USBD_STATUS_TIMEOUT 0xC0006000 ++#define USBD_STATUS_DEVICE_GONE 0xC0007000 ++ ++#define USBD_STATUS_NO_MEMORY 0x80000100 ++#define USBD_STATUS_INVALID_URB_FUNCTION 0x80000200 ++#define USBD_STATUS_INVALID_PARAMETER 0x80000300 ++#define USBD_STATUS_REQUEST_FAILED 0x80000500 ++#define USBD_STATUS_INVALID_PIPE_HANDLE 0x80000600 ++#define USBD_STATUS_ERROR_SHORT_TRANSFER 0x80000900 ++ ++#define USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE PAGE_SIZE ++ ++struct urb_hcd_area { ++ void *reserved8[8]; ++}; ++ ++struct usbd_pipe_information { ++ USHORT wMaxPacketSize; ++ UCHAR bEndpointAddress; ++ UCHAR bInterval; ++ enum pipe_type type; ++ struct usb_endpoint_descriptor *handle; ++ ULONG max_tx_size; ++ ULONG flags; ++}; ++ ++struct usbd_interface_information { ++ USHORT bLength; ++ UCHAR bInterfaceNumber; ++ UCHAR bAlternateSetting; ++ UCHAR bInterfaceClass; ++ UCHAR bInterfaceSubClass; ++ UCHAR bInterfaceProtocol; ++ UCHAR reserved; ++ void *handle; ++ ULONG bNumEndpoints; ++ struct usbd_pipe_information pipes[1]; ++}; ++ ++struct usbd_interface_list_entry { ++ struct usb_interface_descriptor *intf_desc; ++ struct usbd_interface_information *intf; ++}; ++ ++struct nt_urb_header { ++ USHORT length; ++ USHORT function; ++ USBD_STATUS status; ++ void *usbd_dev_handle; ++ ULONG usbd_flags; ++}; ++ ++struct usbd_select_interface { ++ struct nt_urb_header header; ++ void *handle; ++ struct usbd_interface_information intf; ++}; ++ ++struct usbd_select_configuration { ++ struct nt_urb_header header; ++ struct usb_config_descriptor *config; ++ void *handle; ++ struct usbd_interface_information intf; ++}; ++ ++struct usbd_control_descriptor_request { ++ struct nt_urb_header header; ++ void *reserved; ++ ULONG reserved0; ++ ULONG transfer_buffer_length; ++ void *transfer_buffer; ++ struct mdl *mdl; ++ union nt_urb *urb_link; ++ struct urb_hcd_area hca; ++ USHORT reserved1; ++ UCHAR index; ++ UCHAR desc_type; ++ USHORT language_id; ++ USHORT reserved2; ++}; ++ ++struct usbd_bulk_or_intr_transfer { ++ struct nt_urb_header header; ++ struct usb_endpoint_descriptor *pipe_handle; ++ ULONG transfer_flags; ++ ULONG transfer_buffer_length; ++ void *transfer_buffer; ++ struct mdl *mdl; ++ union nt_urb *urb_link; ++ struct urb_hcd_area hca; ++}; ++ ++struct usbd_pipe_request { ++ struct nt_urb_header header; ++ struct usb_endpoint_descriptor *pipe_handle; ++}; ++ ++struct usbd_vendor_or_class_request { ++ struct nt_urb_header header; ++ void *reserved; ++ ULONG transfer_flags; ++ ULONG transfer_buffer_length; ++ void *transfer_buffer; ++ struct mdl *mdl; ++ union nt_urb *link; ++ struct urb_hcd_area hca; ++ UCHAR reserved_bits; ++ UCHAR request; ++ USHORT value; ++ USHORT index; ++ USHORT reserved1; ++}; ++ ++struct urb_control_feature_request { ++ struct nt_urb_header header; ++ void *reserved; ++ ULONG reserved2; ++ ULONG reserved3; ++ void *reserved4; ++ struct mdl *reserved5; ++ union nt_urb *link; ++ struct urb_hcd_area hca; ++ USHORT reserved0; ++ USHORT feature_selector; ++ USHORT index; ++ USHORT reserved1; ++}; ++ ++struct urb_control_get_status_request { ++ struct nt_urb_header header; ++ void *reserved; ++ ULONG reserved0; ++ ULONG transfer_buffer_length; ++ void *transfer_buffer; ++ struct mdl *mdl; ++ union nt_urb *link; ++ struct urb_hcd_area hca; ++ UCHAR reserved1[4]; ++ USHORT index; ++ USHORT reserved2; ++}; ++ ++struct usbd_iso_packet_desc { ++ ULONG offset; ++ ULONG length; ++ USBD_STATUS status; ++}; ++ ++struct usbd_isochronous_transfer { ++ struct nt_urb_header header; ++ struct usb_endpoint_descriptor *pipe_handle; ++ ULONG transfer_flags; ++ ULONG transfer_buffer_length; ++ void *transfer_buffer; ++ struct mdl *mdl; ++ union nt_urb *urb_link; ++ struct urb_hcd_area hca; ++ ULONG start_frame; ++ ULONG number_of_packets; ++ ULONG error_count; ++ struct usbd_iso_packet_desc iso_packet[1]; ++}; ++ ++union nt_urb { ++ struct nt_urb_header header; ++ struct usbd_select_interface select_intf; ++ struct usbd_select_configuration select_conf; ++ struct usbd_bulk_or_intr_transfer bulk_int_transfer; ++ struct usbd_control_descriptor_request control_desc; ++ struct usbd_vendor_or_class_request vendor_class_request; ++ struct usbd_isochronous_transfer isochronous; ++ struct usbd_pipe_request pipe_req; ++ struct urb_control_feature_request feat_req; ++ struct urb_control_get_status_request status_req; ++}; ++ ++struct usbd_bus_interface_usbdi { ++ USHORT Size; ++ USHORT Version; ++ void *Context; ++ void *InterfaceReference; ++ void *InterfaceDereference; ++ void *GetUSBDIVersion; ++ void *QueryBusTime; ++ void *SubmitIsoOutUrb; ++ void *QueryBusInformation; ++ /* version 1 and above have following field */ ++ void *IsDeviceHighSpeed; ++ /* version 2 (and above) have following field */ ++ void *LogEntry; ++}; ++ ++struct usbd_bus_information_level { ++ ULONG TotalBandwidth; ++ ULONG ConsumedBandwidth; ++ /* level 1 and above have following fields */ ++ ULONG ControllerNameLength; ++ wchar_t ControllerName[1]; ++}; ++ ++#define USBDI_VERSION_XP 0x00000500 // Windows XP ++#define USB_HCD_CAPS_SUPPORTS_RT_THREADS 0x00000001 ++#define USB_BUSIF_USBDI_VERSION_0 0x0000 ++#define USB_BUSIF_USBDI_VERSION_1 0x0001 ++#define USB_BUSIF_USBDI_VERSION_2 0x0002 ++ ++struct usbd_version_info { ++ ULONG usbdi_version; ++ ULONG supported_usb_version; ++}; ++ ++struct usbd_idle_callback { ++ void *callback; ++ void *context; ++}; ++ ++#define NT_URB_STATUS(nt_urb) ((nt_urb)->header.status) ++ ++NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp); ++void wrap_suspend_urbs(struct wrap_device *wd); ++void wrap_resume_urbs(struct wrap_device *wd); ++NTSTATUS usb_query_interface(struct wrap_device *wd, ++ struct io_stack_location *irp_sl); ++ ++#endif /* USB_H */ +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/win2lin_stubs.S linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/win2lin_stubs.S +--- linux-3.12.2/3rdparty/ndiswrapper/win2lin_stubs.S 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/win2lin_stubs.S 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,253 @@ ++/* ++ * Copyright (C) 2005 Karl Vogel, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++ ++#ifdef CONFIG_X86_64 ++ ++/* ++# Windows <---> Linux register usage conversion when calling functions ++# V = Volatile ++# NV = Non Volatile (needs to be saved) ++# ++# Win Lin ++# --------------------------------------- ++# Rax Return V Return V ++# Rbx NV NV ++# Rcx Arg1 V Arg4 V ++# Rdx Arg2 V Arg3 V ++# Rsi NV Arg2 V ++# Rdi NV Arg1 V ++# Rsp NV NV ++# Rbp NV NV ++# R8 Arg3 V Arg5 V ++# R9 Arg4 V Arg6 V ++# R10 V V ++# R11 V V ++# R12 NV NV ++# R13 NV NV ++# R14 NV NV ++# R15 NV NV ++# ++# In addition, Linux uses %rax to indicate number of SSE registers used ++# when variadic functions are called. Since there is no way to obtain this ++# from Windows, for now, we just assume this is 0 (hence %rax is cleared). ++# ++# Windows pushes arguments 5 and higher onto stack in case of integer ++# variables and 4 and higher in case of floating point variables (passed ++# in SSE registers). ++ ++In a windows function, the stackframe/registers look like this: ++ ++# 0x0048 .... ++# 0x0040 arg8 ++# 0x0038 arg7 ++# 0x0030 arg6 ++# 0x0028 arg5 ++# 0x0020 shadow/spill space for arg4 ++# 0x0018 shadow/spill space for arg3 ++# 0x0010 shadow/spill space for arg2 ++# 0x0008 shadow/spill space for arg1 ++# 0x0000 ret ++ ++# register spill space is same irrespective of number of arguments - even ++# if Windows function takes less than 4 arguments, 32 bytes above return ++# address is reserved for the function ++ ++In Linux it should look like: ++ ++# 0x0018 .... ++# 0x0010 arg8 ++# 0x0008 arg7 ++# 0x0000 ret ++ ++*/ ++ ++ .text ++ ++#define LINUX_REG_ARGS 6 ++#define LOOP_THRESHOLD 9 ++#define WORD_BYTES 8 ++ ++/* ++ * %rsi and %rdi must be saved because they are not saved by Linux calls, but ++ * Windows callers expect them to be saved. %rbp is saved to create a stack ++ * frame, which can help with debugging. We need to reserve space for an odd ++ * number of registers anyway to keep 16-bit alignment of the stack (one more ++ * position is used by the return address). ++ */ ++#define SAVED_REGS 3 ++ ++/* ++ * When calling the Linux function, several registers are saved on the stack. ++ * When passing more than 6 arguments, arguments starting with argument 7 are ++ * pushed to the stack as well. ++ * ++ * We also need to allocate an additional word on the stack to keep it aligned ++ * to the 16-bit boundary if the number of saved arguments plus one (for the ++ * return address) is odd. ++ */ ++ ++/* ++ * Number of arguments we pass on stack to the Linux function. ++ * The value of true is -1 in assembler, so we multiply it by another true ++ * value. ++ */ ++#define stack_args(argc) \ ++ ((0 < 1) * (argc > LINUX_REG_ARGS) * (argc - LINUX_REG_ARGS)) ++ ++/* Full required change of stack pointer, in words */ ++#define stack_words_raw(argc) (stack_args(argc) + SAVED_REGS + 1) ++ ++/* Full actual change of stack pointer, in words (must be even) */ ++#define stack_words_aligned(argc) ((stack_words_raw(argc) + 1) & ~1) ++ ++/* Space allocated for Linux arguments on stack */ ++#define stack_space(argc) \ ++ ((stack_words_aligned(argc) - SAVED_REGS - 1) * WORD_BYTES) ++ ++/* ++ * win2lin_win_arg(N, ARGC) gives the address of the Windows argument N out of ++ * total ARGC after the stack has been prepared for the Linux function call. ++ * ++ * When called from Windows, the Nth argument is at (N * 8)(%rsp). We add the ++ * stack space allocated by the Linux function to compensate for %rsp change. ++ * ++ * Don't call with N less than 5! ++ */ ++#define win2lin_win_arg(n, argc) \ ++ ((n + SAVED_REGS) * WORD_BYTES + stack_space(argc))(%rsp) ++ ++/* ++ * win2lin_lin_arg(N) gives the address of the Nth Linux argument on the extra ++ * Linux stack frame. When more than 6 arguments are used, %rsp points to the ++ * 7th argument. The Nth argument is therefore at ((N - 7) * 8)(%rsp). ++ * ++ * Don't call with N less than 7! ++ */ ++#define win2lin_lin_arg(n) ((n - 1 - LINUX_REG_ARGS) * WORD_BYTES)(%rsp) ++ ++/* Declare function LONGNAME, call function SHORTNAME with ARGC arguments */ ++.macro win2linm longname, shortname, argc ++ .type \longname, @function ++ ENTRY(\longname) ++ ++ /* Create a call frame - it's optional, but good for debugging */ ++ .cfi_startproc ++ push %rbp ++ .cfi_def_cfa %rsp, 2 * WORD_BYTES ++ .cfi_offset %rbp, -2 * WORD_BYTES ++ mov %rsp, %rbp ++ .cfi_def_cfa %rbp, 2 * WORD_BYTES ++ ++ /* ++ * Registers %rdi and %rsi are volatile on Linux, but not on Windows, ++ * so save them on the stack. ++ */ ++ push %rsi ++ push %rdi ++ ++ /* Allocate extra stack space for arguments 7 and up */ ++ sub $stack_space(\argc), %rsp ++ ++ /* ++ * Copy arguments 7 and up. We do it early, before %rdi and %rsi ++ * are used for arguments 1 and 2, so we don't have to save them. ++ * We still need to save %rcx if using a string copy. ++ */ ++ .if (\argc < LOOP_THRESHOLD) ++ /* If a few arguments, copy them individually through %r11 */ ++ .if (\argc >= 7) ++ mov win2lin_win_arg(7, \argc), %r11 ++ mov %r11, win2lin_lin_arg(7) ++ .endif ++ .if (\argc >= 8) ++ mov win2lin_win_arg(8, \argc), %r11 ++ mov %r11, win2lin_lin_arg(8) ++ .endif ++ .else ++ /* If there are many arguments, copy them in a loop */ ++ /* Save arg1 to %r11 */ ++ mov %rcx, %r11 ++ /* Source and destination */ ++ lea win2lin_win_arg(LINUX_REG_ARGS + 1, \argc), %rsi ++ lea win2lin_lin_arg(LINUX_REG_ARGS + 1), %rdi ++ /* Number of arguments to copy (%ecx zero-extends to %rcx) */ ++ mov $(\argc - LINUX_REG_ARGS), %ecx ++ rep movsq ++ /* Restore arg1 directly to %rdi */ ++ mov %r11, %rdi ++ .endif ++ ++ /* ++ * Argument 1 - %rcx on Windows, %rdi on Linux ++ * Micro-optimization - if we used loop, arg1 is already in %rdi ++ */ ++ .if (\argc >= 1) && (\argc < LOOP_THRESHOLD) ++ mov %rcx, %rdi ++ .endif ++ ++ /* Argument 2 - %rdx on Windows, %rsi on Linux */ ++ .if (\argc >= 2) ++ mov %rdx, %rsi ++ .endif ++ ++ /* Argument 3 - %r8 on Windows, %rdx on Linux */ ++ .if (\argc >= 3) ++ mov %r8, %rdx ++ .endif ++ ++ /* Argument 4 - %r9 on Windows, %rcx on Linux */ ++ .if (\argc >= 4) ++ mov %r9, %rcx ++ .endif ++ ++ /* Argument 5 - first argument on stack on Windows, %r8 Linux */ ++ .if (\argc >= 5) ++ mov win2lin_win_arg(5, \argc), %r8 ++ .endif ++ ++ /* Argument 6 - second argument on stack on Windows, %r9 Linux */ ++ .if (\argc >= 6) ++ mov win2lin_win_arg(6, \argc), %r9 ++ .endif ++ ++ /* %rax on Linux is the number of arguments in SSE registers (zero) */ ++ xor %rax, %rax ++ ++ /* Call the function */ ++ call \shortname ++ ++ /* Free stack space for arguments 7 and up */ ++ add $stack_space(\argc), %rsp ++ ++ /* Restore saved registers */ ++ pop %rdi ++ pop %rsi ++ ++ /* Return to Windows code */ ++ leave ++ .cfi_def_cfa %rsp, WORD_BYTES ++ .cfi_restore %rbp ++ ret ++ .cfi_endproc ++ .size \longname, (. - \longname) ++.endm ++ ++#define win2lin(name, argc) win2linm win2lin_ ## name ## _ ## argc, name, argc ++ ++#include "win2lin_stubs.h" ++ ++#endif /* CONFIG_X86_64 */ +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/winnt_types.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/winnt_types.h +--- linux-3.12.2/3rdparty/ndiswrapper/winnt_types.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/winnt_types.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,1701 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _WINNT_TYPES_H_ ++#define _WINNT_TYPES_H_ ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++#define PASSIVE_LEVEL 0 ++#define APC_LEVEL 1 ++#define DISPATCH_LEVEL 2 ++#define DEVICE_LEVEL_BASE 4 ++ ++/* soft interrupts / bottom-half's are disabled at SOFT_IRQL */ ++#define SOFT_IRQL (DEVICE_LEVEL_BASE + 1) ++#define DIRQL (DEVICE_LEVEL_BASE + 2) ++ ++#define STATUS_WAIT_0 0 ++#define STATUS_SUCCESS 0 ++#define STATUS_ALERTED 0x00000101 ++#define STATUS_TIMEOUT 0x00000102 ++#define STATUS_PENDING 0x00000103 ++#define STATUS_FAILURE 0xC0000001 ++#define STATUS_NOT_IMPLEMENTED 0xC0000002 ++#define STATUS_INVALID_PARAMETER 0xC000000D ++#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 ++#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 ++#define STATUS_ACCESS_DENIED 0xC0000022 ++#define STATUS_BUFFER_TOO_SMALL 0xC0000023 ++#define STATUS_OBJECT_NAME_INVALID 0xC0000023 ++#define STATUS_MUTANT_NOT_OWNED 0xC0000046 ++#define STATUS_RESOURCES 0xC000009A ++#define STATUS_DELETE_PENDING 0xC0000056 ++#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A ++#define STATUS_NOT_SUPPORTED 0xC00000BB ++#define STATUS_INVALID_PARAMETER_2 0xC00000F0 ++#define STATUS_NO_MEMORY 0xC0000017 ++#define STATUS_CANCELLED 0xC0000120 ++#define STATUS_DEVICE_REMOVED 0xC00002B6 ++#define STATUS_DEVICE_NOT_CONNECTED 0xC000009D ++ ++#define STATUS_BUFFER_OVERFLOW 0x80000005 ++ ++#define SL_PENDING_RETURNED 0x01 ++#define SL_INVOKE_ON_CANCEL 0x20 ++#define SL_INVOKE_ON_SUCCESS 0x40 ++#define SL_INVOKE_ON_ERROR 0x80 ++ ++#define IRP_MJ_CREATE 0x00 ++#define IRP_MJ_CREATE_NAMED_PIPE 0x01 ++#define IRP_MJ_CLOSE 0x02 ++#define IRP_MJ_READ 0x03 ++#define IRP_MJ_WRITE 0x04 ++ ++#define IRP_MJ_DEVICE_CONTROL 0x0E ++#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0F ++#define IRP_MJ_POWER 0x16 ++#define IRP_MJ_SYSTEM_CONTROL 0x0E ++#define IRP_MJ_PNP 0x1b ++#define IRP_MJ_MAXIMUM_FUNCTION 0x1b ++ ++#define IRP_MN_WAIT_WAKE 0x00 ++#define IRP_MN_POWER_SEQUENCE 0x01 ++#define IRP_MN_SET_POWER 0x02 ++#define IRP_MN_QUERY_POWER 0x03 ++ ++#define IRP_MN_REGINFO 0x08 ++#define IRP_MN_REGINFO_EX 0x0b ++ ++#define IRP_MN_START_DEVICE 0x00 ++#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 ++#define IRP_MN_REMOVE_DEVICE 0x02 ++#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 ++#define IRP_MN_STOP_DEVICE 0x04 ++#define IRP_MN_QUERY_STOP_DEVICE 0x05 ++#define IRP_MN_CANCEL_STOP_DEVICE 0x06 ++#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 ++#define IRP_MN_QUERY_INTERFACE 0x08 ++ ++#define IRP_BUFFERED_IO 0x00000010 ++#define IRP_DEALLOCATE_BUFFER 0x00000020 ++#define IRP_INPUT_OPERATION 0x00000040 ++ ++#define IRP_DEFFER_IO_COMPLETION 0x00000800 ++ ++#define THREAD_WAIT_OBJECTS 3 ++#define MAX_WAIT_OBJECTS 64 ++ ++#define LOW_PRIORITY 0 ++#define LOW_REALTIME_PRIORITY 16 ++#define HIGH_PRIORITY 31 ++#define MAXIMUM_PRIORITY 32 ++ ++#define PROCESSOR_FEATURE_MAX 64 ++ ++#define IO_NO_INCREMENT 0 ++ ++#define WMIREG_ACTION_REGISTER 1 ++#define WMIREG_ACTION_DEREGISTER 2 ++#define WMIREG_ACTION_REREGISTER 3 ++#define WMIREG_ACTION_UPDATE_GUIDS 4 ++ ++#define WMIREGISTER 0 ++#define WMIUPDATE 1 ++ ++#ifdef CONFIG_X86_64 ++#define wstdcall ++#define wfastcall ++#define noregparm ++#define regparm3 ++ ++#define KI_USER_SHARED_DATA 0xfffff78000000000UL ++ ++#else ++ ++#define noregparm __attribute__((regparm(0))) ++#define regparm3 __attribute__((regparm(3))) ++#define wstdcall __attribute__((__stdcall__, regparm(0))) ++#if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ > 3) || __GNUC__ > 3) ++#undef fastcall ++#define wfastcall __attribute__((fastcall)) ++#else ++#error "gcc 3.4 or newer should be used for compiling this module" ++#endif ++ ++#define KI_USER_SHARED_DATA 0xffdf0000 ++ ++#endif ++ ++typedef u8 BOOLEAN; ++typedef u8 BYTE; ++typedef u8 *LPBYTE; ++typedef s8 CHAR; ++typedef u8 UCHAR; ++typedef s16 SHORT; ++typedef u16 USHORT; ++typedef u16 WORD; ++typedef s32 INT; ++typedef u32 UINT; ++typedef u32 DWORD; ++typedef s32 LONG; ++typedef u32 ULONG; ++typedef s64 LONGLONG; ++typedef u64 ULONGLONG; ++typedef u64 ULONGULONG; ++typedef u64 ULONG64; ++ ++typedef CHAR CCHAR; ++typedef USHORT wchar_t; ++typedef SHORT CSHORT; ++typedef LONGLONG LARGE_INTEGER; ++ ++typedef LONG NTSTATUS; ++ ++typedef LONG KPRIORITY; ++typedef LARGE_INTEGER PHYSICAL_ADDRESS; ++typedef UCHAR KIRQL; ++typedef CHAR KPROCESSOR_MODE; ++ ++/* ULONG_PTR is 32 bits on 32-bit platforms and 64 bits on 64-bit ++ * platform, which is same as 'unsigned long' in Linux */ ++typedef unsigned long ULONG_PTR; ++ ++typedef size_t SIZE_T; ++typedef ULONG_PTR KAFFINITY; ++typedef ULONG ACCESS_MASK; ++ ++typedef ULONG_PTR PFN_NUMBER; ++typedef ULONG SECURITY_INFORMATION; ++ ++/* non-negative numbers indicate success */ ++#define NT_SUCCESS(status) ((NTSTATUS)(status) >= 0) ++ ++struct ansi_string { ++ USHORT length; ++ USHORT max_length; ++ char *buf; ++}; ++ ++struct unicode_string { ++ USHORT length; ++ USHORT max_length; ++ wchar_t *buf; ++}; ++ ++struct nt_slist { ++ struct nt_slist *next; ++}; ++ ++#ifdef CONFIG_X86_64 ++/* it is not clear how nt_slist_head is used to store pointer to ++ * slists and depth; here we assume 'align' field is used to store ++ * depth and 'region' field is used to store slist pointers */ ++struct nt_slist_head { ++ union { ++ USHORT depth; ++ ULONGLONG align; ++ }; ++ union { ++ ULONGLONG region; ++ struct nt_slist *next; ++ }; ++} __attribute__((aligned(16))); ++typedef struct nt_slist_head nt_slist_header; ++#else ++union nt_slist_head { ++ ULONGLONG align; ++ struct { ++ struct nt_slist *next; ++ USHORT depth; ++ USHORT sequence; ++ }; ++}; ++typedef union nt_slist_head nt_slist_header; ++#endif ++ ++struct nt_list { ++ struct nt_list *next; ++ struct nt_list *prev; ++}; ++ ++typedef ULONG_PTR NT_SPIN_LOCK; ++ ++enum kdpc_importance {LowImportance, MediumImportance, HighImportance}; ++ ++struct kdpc; ++typedef void (*DPC)(struct kdpc *kdpc, void *ctx, void *arg1, ++ void *arg2) wstdcall; ++struct kdpc { ++ SHORT type; ++ UCHAR nr_cpu; ++ UCHAR importance; ++ struct nt_list list; ++ DPC func; ++ void *ctx; ++ void *arg1; ++ void *arg2; ++ union { ++ NT_SPIN_LOCK *lock; ++ /* 'lock' is not used; 'queued' represents whether ++ * kdpc is queued or not */ ++ int queued; ++ }; ++}; ++ ++enum pool_type { ++ NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, ++ NonPagedPoolCacheAligned, PagedPoolCacheAligned, ++ NonPagedPoolCacheAlignedMustS, MaxPoolType, ++ NonPagedPoolSession = 32, ++ PagedPoolSession = NonPagedPoolSession + 1, ++ NonPagedPoolMustSucceedSession = PagedPoolSession + 1, ++ DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, ++ NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, ++ PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, ++ NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1 ++}; ++ ++enum memory_caching_type_orig { ++ MmFrameBufferCached = 2 ++}; ++ ++enum memory_caching_type { ++ MmNonCached = FALSE, MmCached = TRUE, ++ MmWriteCombined = MmFrameBufferCached, MmHardwareCoherentCached, ++ MmNonCachedUnordered, MmUSWCCached, MmMaximumCacheType ++}; ++ ++enum lock_operation { ++ IoReadAccess, IoWriteAccess, IoModifyAccess ++}; ++ ++enum mode { ++ KernelMode, UserMode, MaximumMode ++}; ++ ++struct mdl { ++ struct mdl *next; ++ CSHORT size; ++ CSHORT flags; ++ /* NdisFreeBuffer doesn't pass pool, so we store pool in ++ * unused field 'process' */ ++ union { ++ void *process; ++ void *pool; ++ }; ++ void *mappedsystemva; ++ void *startva; ++ ULONG bytecount; ++ ULONG byteoffset; ++}; ++ ++#define MDL_MAPPED_TO_SYSTEM_VA 0x0001 ++#define MDL_PAGES_LOCKED 0x0002 ++#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004 ++#define MDL_ALLOCATED_FIXED_SIZE 0x0008 ++#define MDL_PARTIAL 0x0010 ++#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020 ++#define MDL_IO_PAGE_READ 0x0040 ++#define MDL_WRITE_OPERATION 0x0080 ++#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100 ++#define MDL_FREE_EXTRA_PTES 0x0200 ++#define MDL_IO_SPACE 0x0800 ++#define MDL_NETWORK_HEADER 0x1000 ++#define MDL_MAPPING_CAN_FAIL 0x2000 ++#define MDL_ALLOCATED_MUST_SUCCEED 0x4000 ++ ++#define MDL_POOL_ALLOCATED 0x0400 ++#define MDL_CACHE_ALLOCATED 0x8000 ++ ++#define PAGE_START(ptr) ((void *)((ULONG_PTR)(ptr) & ~(PAGE_SIZE - 1))) ++#define BYTE_OFFSET(ptr) ((ULONG)((ULONG_PTR)(ptr) & (PAGE_SIZE - 1))) ++ ++#define MmGetMdlByteCount(mdl) ((mdl)->bytecount) ++#define MmGetMdlVirtualAddress(mdl) ((mdl)->startva + (mdl)->byteoffset) ++#define MmGetMdlByteOffset(mdl) ((mdl)->byteoffset) ++#define MmGetSystemAddressForMdl(mdl) ((mdl)->mappedsystemva) ++#define MmGetSystemAddressForMdlSafe(mdl, priority) ((mdl)->mappedsystemva) ++#define MmGetMdlPfnArray(mdl) ((PFN_NUMBER *)(mdl + 1)) ++#define MmInitializeMdl(mdl, baseva, length) \ ++do { \ ++ (mdl)->next = NULL; \ ++ (mdl)->size = MmSizeOfMdl(baseva, length); \ ++ (mdl)->flags = 0; \ ++ (mdl)->startva = PAGE_START(baseva); \ ++ (mdl)->byteoffset = BYTE_OFFSET(baseva); \ ++ (mdl)->bytecount = length; \ ++ (mdl)->mappedsystemva = baseva; \ ++ TRACE4("%p %p %p %d %d", (mdl), baseva, (mdl)->startva, \ ++ (mdl)->byteoffset, length); \ ++} while (0) ++ ++struct kdevice_queue_entry { ++ struct nt_list list; ++ ULONG sort_key; ++ BOOLEAN inserted; ++}; ++ ++struct kdevice_queue { ++ USHORT type; ++ USHORT size; ++ struct nt_list list; ++ NT_SPIN_LOCK lock; ++ BOOLEAN busy; ++}; ++ ++struct wait_context_block { ++ struct kdevice_queue_entry wait_queue_entry; ++ void *device_routine; ++ void *device_context; ++ ULONG num_regs; ++ void *device_object; ++ void *current_irp; ++ void *buffer_chaining_dpc; ++}; ++ ++struct wait_block { ++ struct nt_list list; ++ struct task_struct *thread; ++ void *object; ++ int *wait_done; ++ USHORT wait_key; ++ USHORT wait_type; ++}; ++ ++struct dispatcher_header { ++ UCHAR type; ++ UCHAR absolute; ++ UCHAR size; ++ UCHAR inserted; ++ LONG signal_state; ++ struct nt_list wait_blocks; ++}; ++ ++enum event_type { ++ NotificationEvent, ++ SynchronizationEvent, ++}; ++ ++enum timer_type { ++ NotificationTimer = NotificationEvent, ++ SynchronizationTimer = SynchronizationEvent, ++}; ++ ++enum dh_type { ++ NotificationObject = NotificationEvent, ++ SynchronizationObject = SynchronizationEvent, ++ MutexObject, ++ SemaphoreObject, ++ ThreadObject, ++}; ++ ++enum wait_type { ++ WaitAll, WaitAny ++}; ++ ++/* objects that use dispatcher_header have it as the first field, so ++ * whenever we need to initialize dispatcher_header, we can convert ++ * that object into a nt_event and access dispatcher_header */ ++struct nt_event { ++ struct dispatcher_header dh; ++}; ++ ++struct wrap_timer; ++ ++#define WRAP_TIMER_MAGIC 47697249 ++ ++struct nt_timer { ++ struct dispatcher_header dh; ++ /* We can't fit Linux timer in this structure. Instead of ++ * padding the nt_timer structure, we replace due_time field ++ * with *wrap_timer and allocate memory for it when nt_timer is ++ * initialized */ ++ union { ++ ULONGLONG due_time; ++ struct wrap_timer *wrap_timer; ++ }; ++ struct nt_list nt_timer_list; ++ struct kdpc *kdpc; ++ union { ++ LONG period; ++ LONG wrap_timer_magic; ++ }; ++}; ++ ++struct nt_mutex { ++ struct dispatcher_header dh; ++ struct nt_list list; ++ struct task_struct *owner_thread; ++ BOOLEAN abandoned; ++ BOOLEAN apc_disable; ++}; ++ ++struct nt_semaphore { ++ struct dispatcher_header dh; ++ LONG limit; ++}; ++ ++struct nt_thread { ++ struct dispatcher_header dh; ++ /* the rest in Windows is a long structure; since this ++ * structure is opaque to drivers, we just define what we ++ * need */ ++ int pid; ++ NTSTATUS status; ++ struct task_struct *task; ++ struct nt_list irps; ++ NT_SPIN_LOCK lock; ++ KPRIORITY prio; ++}; ++ ++#define set_object_type(dh, type) ((dh)->type = (type)) ++#define is_notify_object(dh) ((dh)->type == NotificationObject) ++#define is_synch_object(dh) ((dh)->type == SynchronizationObject) ++#define is_mutex_object(dh) ((dh)->type == MutexObject) ++#define is_semaphore_object(dh) ((dh)->type == SemaphoreObject) ++#define is_nt_thread_object(dh) ((dh)->type == ThreadObject) ++ ++#define IO_TYPE_ADAPTER 1 ++#define IO_TYPE_CONTROLLER 2 ++#define IO_TYPE_DEVICE 3 ++#define IO_TYPE_DRIVER 4 ++#define IO_TYPE_FILE 5 ++#define IO_TYPE_IRP 6 ++#define IO_TYPE_DEVICE_OBJECT_EXTENSION 13 ++ ++struct irp; ++struct dev_obj_ext; ++struct driver_object; ++ ++struct device_object { ++ CSHORT type; ++ USHORT size; ++ LONG ref_count; ++ struct driver_object *drv_obj; ++ struct device_object *next; ++ struct device_object *attached; ++ struct irp *current_irp; ++ void *io_timer; ++ ULONG flags; ++ ULONG characteristics; ++ void *vpb; ++ void *dev_ext; ++ CCHAR stack_count; ++ union { ++ struct nt_list queue_list; ++ struct wait_context_block wcb; ++ } queue; ++ ULONG align_req; ++ struct kdevice_queue dev_queue; ++ struct kdpc dpc; ++ ULONG active_threads; ++ void *security_desc; ++ struct nt_event lock; ++ USHORT sector_size; ++ USHORT spare1; ++ struct dev_obj_ext *dev_obj_ext; ++ void *reserved; ++}; ++ ++struct dev_obj_ext { ++ CSHORT type; ++ CSHORT size; ++ struct device_object *dev_obj; ++ struct device_object *attached_to; ++}; ++ ++struct io_status_block { ++ union { ++ NTSTATUS status; ++ void *pointer; ++ }; ++ ULONG_PTR info; ++}; ++ ++#ifdef CONFIG_X86_64 ++struct io_status_block32 { ++ NTSTATUS status; ++ ULONG info; ++}; ++#endif ++ ++#define DEVICE_TYPE ULONG ++ ++struct driver_extension; ++ ++typedef NTSTATUS driver_dispatch_t(struct device_object *dev_obj, ++ struct irp *irp) wstdcall; ++ ++struct driver_object { ++ CSHORT type; ++ CSHORT size; ++ struct device_object *dev_obj; ++ ULONG flags; ++ void *start; ++ ULONG driver_size; ++ void *section; ++ struct driver_extension *drv_ext; ++ struct unicode_string name; ++ struct unicode_string *hardware_database; ++ void *fast_io_dispatch; ++ void *init; ++ void *start_io; ++ void (*unload)(struct driver_object *driver) wstdcall; ++ driver_dispatch_t *major_func[IRP_MJ_MAXIMUM_FUNCTION + 1]; ++}; ++ ++struct driver_extension { ++ struct driver_object *drv_obj; ++ NTSTATUS (*add_device)(struct driver_object *drv_obj, ++ struct device_object *dev_obj); ++ ULONG count; ++ struct unicode_string service_key_name; ++ struct nt_list custom_ext; ++}; ++ ++struct custom_ext { ++ struct nt_list list; ++ void *client_id; ++}; ++ ++struct wrap_bin_file; ++ ++struct file_object { ++ CSHORT type; ++ CSHORT size; ++ struct device_object *dev_obj; ++ void *volume_parameter_block; ++ void *fs_context; ++ void *fs_context2; ++ void *section_object_pointer; ++ void *private_cache_map; ++ NTSTATUS final_status; ++ union { ++ struct file_object *related_file_object; ++ struct wrap_bin_file *wrap_bin_file; ++ }; ++ BOOLEAN lock_operation; ++ BOOLEAN delete_pending; ++ BOOLEAN read_access; ++ BOOLEAN write_access; ++ BOOLEAN delete_access; ++ BOOLEAN shared_read; ++ BOOLEAN shared_write; ++ BOOLEAN shared_delete; ++ ULONG flags; ++ struct unicode_string _name_; ++ LARGE_INTEGER current_byte_offset; ++ ULONG waiters; ++ ULONG busy; ++ void *last_lock; ++ struct nt_event lock; ++ struct nt_event event; ++ void *completion_context; ++}; ++ ++#ifdef CONFIG_X86_64 ++#define POINTER_ALIGN __attribute__((aligned(8))) ++#else ++#define POINTER_ALIGN ++#endif ++ ++#define CACHE_ALIGN __attribute__((aligned(128))) ++ ++enum system_power_state { ++ PowerSystemUnspecified = 0, ++ PowerSystemWorking, PowerSystemSleeping1, PowerSystemSleeping2, ++ PowerSystemSleeping3, PowerSystemHibernate, PowerSystemShutdown, ++ PowerSystemMaximum, ++}; ++ ++enum device_power_state { ++ PowerDeviceUnspecified = 0, ++ PowerDeviceD0, PowerDeviceD1, PowerDeviceD2, PowerDeviceD3, ++ PowerDeviceMaximum, ++}; ++ ++union power_state { ++ enum system_power_state system_state; ++ enum device_power_state device_state; ++}; ++ ++enum power_state_type { ++ SystemPowerState = 0, DevicePowerState, ++}; ++ ++enum power_action { ++ PowerActionNone = 0, ++ PowerActionReserved, PowerActionSleep, PowerActionHibernate, ++ PowerActionShutdown, PowerActionShutdownReset, PowerActionShutdownOff, ++ PowerActionWarmEject, ++}; ++ ++struct guid { ++ ULONG data1; ++ USHORT data2; ++ USHORT data3; ++ UCHAR data4[8]; ++}; ++ ++struct nt_interface { ++ USHORT size; ++ USHORT version; ++ void *context; ++ void (*reference)(void *context) wstdcall; ++ void (*dereference)(void *context) wstdcall; ++}; ++ ++enum interface_type { ++ InterfaceTypeUndefined = -1, Internal, Isa, Eisa, MicroChannel, ++ TurboChannel, PCIBus, VMEBus, NuBus, PCMCIABus, CBus, MPIBus, ++ MPSABus, ProcessorInternal, InternalPowerBus, PNPISABus, ++ PNPBus, MaximumInterfaceType, ++}; ++ ++#define CmResourceTypeNull 0 ++#define CmResourceTypePort 1 ++#define CmResourceTypeInterrupt 2 ++#define CmResourceTypeMemory 3 ++#define CmResourceTypeDma 4 ++#define CmResourceTypeDeviceSpecific 5 ++#define CmResourceTypeBusNumber 6 ++#define CmResourceTypeMaximum 7 ++ ++#define CmResourceTypeNonArbitrated 128 ++#define CmResourceTypeConfigData 128 ++#define CmResourceTypeDevicePrivate 129 ++#define CmResourceTypePcCardConfig 130 ++#define CmResourceTypeMfCardConfig 131 ++ ++enum cm_share_disposition { ++ CmResourceShareUndetermined = 0, CmResourceShareDeviceExclusive, ++ CmResourceShareDriverExclusive, CmResourceShareShared ++}; ++ ++#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0 ++#define CM_RESOURCE_INTERRUPT_LATCHED 1 ++#define CM_RESOURCE_MEMORY_READ_WRITE 0x0000 ++#define CM_RESOURCE_MEMORY_READ_ONLY 0x0001 ++#define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002 ++#define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004 ++ ++#define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008 ++#define CM_RESOURCE_MEMORY_24 0x0010 ++#define CM_RESOURCE_MEMORY_CACHEABLE 0x0020 ++ ++#define CM_RESOURCE_PORT_MEMORY 0x0000 ++#define CM_RESOURCE_PORT_IO 0x0001 ++#define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004 ++#define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008 ++#define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010 ++#define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020 ++#define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040 ++#define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080 ++ ++#define CM_RESOURCE_DMA_8 0x0000 ++#define CM_RESOURCE_DMA_16 0x0001 ++#define CM_RESOURCE_DMA_32 0x0002 ++#define CM_RESOURCE_DMA_8_AND_16 0x0004 ++#define CM_RESOURCE_DMA_BUS_MASTER 0x0008 ++#define CM_RESOURCE_DMA_TYPE_A 0x0010 ++#define CM_RESOURCE_DMA_TYPE_B 0x0020 ++#define CM_RESOURCE_DMA_TYPE_F 0x0040 ++ ++#define MAX_RESOURCES 20 ++ ++#pragma pack(push,4) ++struct cm_partial_resource_descriptor { ++ UCHAR type; ++ UCHAR share; ++ USHORT flags; ++ union { ++ struct { ++ PHYSICAL_ADDRESS start; ++ ULONG length; ++ } generic; ++ struct { ++ PHYSICAL_ADDRESS start; ++ ULONG length; ++ } port; ++ struct { ++ ULONG level; ++ ULONG vector; ++ KAFFINITY affinity; ++ } interrupt; ++ struct { ++ PHYSICAL_ADDRESS start; ++ ULONG length; ++ } memory; ++ struct { ++ ULONG channel; ++ ULONG port; ++ ULONG reserved1; ++ } dma; ++ struct { ++ ULONG data[3]; ++ } device_private; ++ struct { ++ ULONG start; ++ ULONG length; ++ ULONG reserved; ++ } bus_number; ++ struct { ++ ULONG data_size; ++ ULONG reserved1; ++ ULONG reserved2; ++ } device_specific_data; ++ } u; ++}; ++#pragma pack(pop) ++ ++struct cm_partial_resource_list { ++ USHORT version; ++ USHORT revision; ++ ULONG count; ++ struct cm_partial_resource_descriptor partial_descriptors[1]; ++}; ++ ++struct cm_full_resource_descriptor { ++ enum interface_type interface_type; ++ ULONG bus_number; ++ struct cm_partial_resource_list partial_resource_list; ++}; ++ ++struct cm_resource_list { ++ ULONG count; ++ struct cm_full_resource_descriptor list[1]; ++}; ++ ++enum file_info_class { ++ FileDirectoryInformation = 1, ++ FileBasicInformation = 4, ++ FileStandardInformation = 5, ++ FileNameInformation = 9, ++ FilePositionInformation = 14, ++ FileAlignmentInformation = 17, ++ FileNetworkOpenInformation = 34, ++ FileAttributeTagInformation = 35, ++ FileMaximumInformation = 41, ++}; ++ ++enum fs_info_class { ++ FileFsVolumeInformation = 1, ++ /* ... */ ++ FileFsMaximumInformation = 9, ++}; ++ ++enum device_relation_type { ++ BusRelations, EjectionRelations, PowerRelations, RemovalRelations, ++ TargetDeviceRelation, SingleBusRelations, ++}; ++ ++enum bus_query_id_type { ++ BusQueryDeviceID = 0, BusQueryHardwareIDs = 1, ++ BusQueryCompatibleIDs = 2, BusQueryInstanceID = 3, ++ BusQueryDeviceSerialNumber = 4, ++}; ++ ++enum device_text_type { ++ DeviceTextDescription = 0, DeviceTextLocationInformation = 1, ++}; ++ ++enum device_usage_notification_type { ++ DeviceUsageTypeUndefined, DeviceUsageTypePaging, ++ DeviceUsageTypeHibernation, DevbiceUsageTypeDumpFile, ++}; ++ ++#define METHOD_BUFFERED 0 ++#define METHOD_IN_DIRECT 1 ++#define METHOD_OUT_DIRECT 2 ++#define METHOD_NEITHER 3 ++ ++#define CTL_CODE(dev_type, func, method, access) \ ++ (((dev_type) << 16) | ((access) << 14) | ((func) << 2) | (method)) ++ ++#define IO_METHOD_FROM_CTL_CODE(code) (code & 0x3) ++ ++#ifndef CONFIG_X86_64 ++#pragma pack(push,4) ++#endif ++struct io_stack_location { ++ UCHAR major_fn; ++ UCHAR minor_fn; ++ UCHAR flags; ++ UCHAR control; ++ union { ++ struct { ++ void *security_context; ++ ULONG options; ++ USHORT POINTER_ALIGN file_attributes; ++ USHORT share_access; ++ ULONG POINTER_ALIGN ea_length; ++ } create; ++ struct { ++ ULONG length; ++ ULONG POINTER_ALIGN key; ++ LARGE_INTEGER byte_offset; ++ } read; ++ struct { ++ ULONG length; ++ ULONG POINTER_ALIGN key; ++ LARGE_INTEGER byte_offset; ++ } write; ++ struct { ++ ULONG length; ++ enum file_info_class POINTER_ALIGN file_info_class; ++ } query_file; ++ struct { ++ ULONG length; ++ enum file_info_class POINTER_ALIGN file_info_class; ++ struct file_object *file_object; ++ union { ++ struct { ++ BOOLEAN replace_if_exists; ++ BOOLEAN advance_only; ++ }; ++ ULONG cluster_count; ++ void *delete_handle; ++ }; ++ } set_file; ++ struct { ++ ULONG length; ++ enum fs_info_class POINTER_ALIGN fs_info_class; ++ } query_volume; ++ struct { ++ ULONG output_buf_len; ++ ULONG POINTER_ALIGN input_buf_len; ++ ULONG POINTER_ALIGN code; ++ void *type3_input_buf; ++ } dev_ioctl; ++ struct { ++ SECURITY_INFORMATION security_info; ++ ULONG POINTER_ALIGN length; ++ } query_security; ++ struct { ++ SECURITY_INFORMATION security_info; ++ void *security_descriptor; ++ } set_security; ++ struct { ++ void *vpb; ++ struct device_object *device_object; ++ } mount_volume; ++ struct { ++ void *vpb; ++ struct device_object *device_object; ++ } verify_volume; ++ struct { ++ void *srb; ++ } scsi; ++ struct { ++ enum device_relation_type type; ++ } query_device_relations; ++ struct { ++ const struct guid *type; ++ USHORT size; ++ USHORT version; ++ struct nt_interface *intf; ++ void *intf_data; ++ } query_intf; ++ struct { ++ void *capabilities; ++ } device_capabilities; ++ struct { ++ void *io_resource_requirement_list; ++ } filter_resource_requirements; ++ struct { ++ ULONG which_space; ++ void *buffer; ++ ULONG offset; ++ ULONG POINTER_ALIGN length; ++ } read_write_config; ++ struct { ++ BOOLEAN lock; ++ } set_lock; ++ struct { ++ enum bus_query_id_type id_type; ++ } query_id; ++ struct { ++ enum device_text_type device_text_type; ++ ULONG POINTER_ALIGN locale_id; ++ } query_device_text; ++ struct { ++ BOOLEAN in_path; ++ BOOLEAN reserved[3]; ++ enum device_usage_notification_type POINTER_ALIGN type; ++ } usage_notification; ++ struct { ++ enum system_power_state power_state; ++ } wait_wake; ++ struct { ++ void *power_sequence; ++ } power_sequence; ++ struct { ++ ULONG sys_context; ++ enum power_state_type POINTER_ALIGN type; ++ union power_state POINTER_ALIGN state; ++ enum power_action POINTER_ALIGN shutdown_type; ++ } power; ++ struct { ++ struct cm_resource_list *allocated_resources; ++ struct cm_resource_list *allocated_resources_translated; ++ } start_device; ++ struct { ++ ULONG_PTR provider_id; ++ void *data_path; ++ ULONG buf_len; ++ void *buf; ++ } wmi; ++ struct { ++ void *arg1; ++ void *arg2; ++ void *arg3; ++ void *arg4; ++ } others; ++ } params; ++ struct device_object *dev_obj; ++ struct file_object *file_obj; ++ NTSTATUS (*completion_routine)(struct device_object *, ++ struct irp *, void *) wstdcall; ++ void *context; ++}; ++#ifndef CONFIG_X86_64 ++#pragma pack(pop) ++#endif ++ ++struct kapc { ++ CSHORT type; ++ CSHORT size; ++ ULONG spare0; ++ struct nt_thread *thread; ++ struct nt_list list; ++ void *kernele_routine; ++ void *rundown_routine; ++ void *normal_routine; ++ void *normal_context; ++ void *sys_arg1; ++ void *sys_arg2; ++ CCHAR apc_state_index; ++ KPROCESSOR_MODE apc_mode; ++ BOOLEAN inserted; ++}; ++ ++#define IRP_NOCACHE 0x00000001 ++#define IRP_SYNCHRONOUS_API 0x00000004 ++#define IRP_ASSOCIATED_IRP 0x00000008 ++ ++enum urb_state { ++ URB_INVALID = 1, URB_ALLOCATED, URB_SUBMITTED, ++ URB_COMPLETED, URB_FREE, URB_SUSPEND, URB_INT_UNLINKED }; ++ ++struct wrap_urb { ++ struct nt_list list; ++ enum urb_state state; ++ struct nt_list complete_list; ++ unsigned int flags; ++ struct urb *urb; ++ struct irp *irp; ++#ifdef USB_DEBUG ++ unsigned int id; ++#endif ++}; ++ ++struct irp { ++ SHORT type; ++ USHORT size; ++ struct mdl *mdl; ++ ULONG flags; ++ union { ++ struct irp *master_irp; ++ LONG irp_count; ++ void *system_buffer; ++ } associated_irp; ++ struct nt_list thread_list; ++ struct io_status_block io_status; ++ KPROCESSOR_MODE requestor_mode; ++ BOOLEAN pending_returned; ++ CHAR stack_count; ++ CHAR current_location; ++ BOOLEAN cancel; ++ KIRQL cancel_irql; ++ CCHAR apc_env; ++ UCHAR alloc_flags; ++ struct io_status_block *user_status; ++ struct nt_event *user_event; ++ union { ++ struct { ++ void *user_apc_routine; ++ void *user_apc_context; ++ } async_params; ++ LARGE_INTEGER alloc_size; ++ } overlay; ++ void (*cancel_routine)(struct device_object *, struct irp *) wstdcall; ++ void *user_buf; ++ union { ++ struct { ++ union { ++ struct kdevice_queue_entry dev_q_entry; ++ struct { ++ void *driver_context[4]; ++ }; ++ }; ++ void *thread; ++ char *aux_buf; ++ struct { ++ struct nt_list list; ++ union { ++ struct io_stack_location *csl; ++ ULONG packet_type; ++ }; ++ }; ++ struct file_object *file_object; ++ } overlay; ++ union { ++ struct kapc apc; ++ /* space for apc is used for ndiswrapper ++ * specific fields */ ++ struct { ++ struct wrap_urb *wrap_urb; ++ struct wrap_device *wrap_device; ++ }; ++ }; ++ void *completion_key; ++ } tail; ++}; ++ ++#define IoSizeOfIrp(stack_count) \ ++ ((USHORT)(sizeof(struct irp) + \ ++ ((stack_count) * sizeof(struct io_stack_location)))) ++#define IoGetCurrentIrpStackLocation(irp) \ ++ (irp)->tail.overlay.csl ++#define IoGetNextIrpStackLocation(irp) \ ++ (IoGetCurrentIrpStackLocation(irp) - 1) ++#define IoGetPreviousIrpStackLocation(irp) \ ++ (IoGetCurrentIrpStackLocation(irp) + 1) ++ ++#define IoSetNextIrpStackLocation(irp) \ ++do { \ ++ KIRQL _irql_; \ ++ IoAcquireCancelSpinLock(&_irql_); \ ++ (irp)->current_location--; \ ++ IoGetCurrentIrpStackLocation(irp)--; \ ++ IoReleaseCancelSpinLock(_irql_); \ ++} while (0) ++ ++#define IoSkipCurrentIrpStackLocation(irp) \ ++do { \ ++ KIRQL _irql_; \ ++ IoAcquireCancelSpinLock(&_irql_); \ ++ (irp)->current_location++; \ ++ IoGetCurrentIrpStackLocation(irp)++; \ ++ IoReleaseCancelSpinLock(_irql_); \ ++} while (0) ++ ++static inline void ++IoCopyCurrentIrpStackLocationToNext(struct irp *irp) ++{ ++ struct io_stack_location *next; ++ next = IoGetNextIrpStackLocation(irp); ++ memcpy(next, IoGetCurrentIrpStackLocation(irp), ++ offsetof(struct io_stack_location, completion_routine)); ++ next->control = 0; ++} ++ ++static inline void ++IoSetCompletionRoutine(struct irp *irp, void *routine, void *context, ++ BOOLEAN success, BOOLEAN error, BOOLEAN cancel) ++{ ++ struct io_stack_location *irp_sl = IoGetNextIrpStackLocation(irp); ++ irp_sl->completion_routine = routine; ++ irp_sl->context = context; ++ irp_sl->control = 0; ++ if (success) ++ irp_sl->control |= SL_INVOKE_ON_SUCCESS; ++ if (error) ++ irp_sl->control |= SL_INVOKE_ON_ERROR; ++ if (cancel) ++ irp_sl->control |= SL_INVOKE_ON_CANCEL; ++} ++ ++#define IoMarkIrpPending(irp) \ ++ (IoGetCurrentIrpStackLocation((irp))->control |= SL_PENDING_RETURNED) ++#define IoUnmarkIrpPending(irp) \ ++ (IoGetCurrentIrpStackLocation((irp))->control &= ~SL_PENDING_RETURNED) ++ ++#define IRP_SL(irp, n) (((struct io_stack_location *)((irp) + 1)) + (n)) ++#define IRP_DRIVER_CONTEXT(irp) (irp)->tail.overlay.driver_context ++#define IoIrpThread(irp) ((irp)->tail.overlay.thread) ++ ++#define IRP_URB(irp) \ ++ (union nt_urb *)(IoGetCurrentIrpStackLocation(irp)->params.others.arg1) ++ ++#define IRP_WRAP_DEVICE(irp) (irp)->tail.wrap_device ++#define IRP_WRAP_URB(irp) (irp)->tail.wrap_urb ++ ++struct wmi_guid_reg_info { ++ struct guid *guid; ++ ULONG instance_count; ++ ULONG flags; ++}; ++ ++struct wmilib_context { ++ ULONG guid_count; ++ struct wmi_guid_reg_info *guid_list; ++ void *query_wmi_reg_info; ++ void *query_wmi_data_block; ++ void *set_wmi_data_block; ++ void *set_wmi_data_item; ++ void *execute_wmi_method; ++ void *wmi_function_control; ++}; ++ ++enum key_value_information_class { ++ KeyValueBasicInformation, KeyValueFullInformation, ++ KeyValuePartialInformation, KeyValueFullInformationAlign64, ++ KeyValuePartialInformationAlign64 ++}; ++ ++struct file_name_info { ++ ULONG length; ++ wchar_t *name; ++}; ++ ++struct file_std_info { ++ LARGE_INTEGER alloc_size; ++ LARGE_INTEGER eof; ++ ULONG num_links; ++ BOOLEAN delete_pending; ++ BOOLEAN dir; ++}; ++ ++enum nt_obj_type { ++ NT_OBJ_EVENT = 10, NT_OBJ_MUTEX, NT_OBJ_THREAD, NT_OBJ_TIMER, ++ NT_OBJ_SEMAPHORE, ++}; ++ ++enum common_object_type { ++ OBJECT_TYPE_NONE, OBJECT_TYPE_DEVICE, OBJECT_TYPE_DRIVER, ++ OBJECT_TYPE_NT_THREAD, OBJECT_TYPE_FILE, OBJECT_TYPE_CALLBACK, ++}; ++ ++struct common_object_header { ++ struct nt_list list; ++ enum common_object_type type; ++ UINT size; ++ UINT ref_count; ++ BOOLEAN close_in_process; ++ BOOLEAN permanent; ++ struct unicode_string name; ++}; ++ ++#define OBJECT_TO_HEADER(object) \ ++ (struct common_object_header *)((void *)(object) - \ ++ sizeof(struct common_object_header)) ++#define OBJECT_SIZE(size) \ ++ ((size) + sizeof(struct common_object_header)) ++#define HEADER_TO_OBJECT(hdr) \ ++ ((void *)(hdr) + sizeof(struct common_object_header)) ++#define HANDLE_TO_OBJECT(handle) HEADER_TO_OBJECT(handle) ++#define HANDLE_TO_HEADER(handle) (handle) ++ ++enum work_queue_type { ++ CriticalWorkQueue, DelayedWorkQueue, HyperCriticalWorkQueue, ++ MaximumWorkQueue ++}; ++ ++typedef void (*NTOS_WORK_FUNC)(void *arg1, void *arg2) wstdcall; ++ ++struct io_workitem { ++ enum work_queue_type type; ++ struct device_object *dev_obj; ++ NTOS_WORK_FUNC worker_routine; ++ void *context; ++}; ++ ++struct io_workitem_entry { ++ struct nt_list list; ++ struct io_workitem *io_workitem; ++}; ++ ++enum mm_page_priority { ++ LowPagePriority, NormalPagePriority = 16, HighPagePriority = 32 ++}; ++ ++enum kinterrupt_mode { ++ LevelSensitive, Latched ++}; ++ ++enum ntos_wait_reason { ++ Executive, FreePage, PageIn, PoolAllocation, DelayExecution, ++ Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, ++ WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, ++ WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, ++ WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, ++ WrKernel, MaximumWaitReason ++}; ++ ++typedef enum ntos_wait_reason KWAIT_REASON; ++ ++typedef void *LOOKASIDE_ALLOC_FUNC(enum pool_type pool_type, ++ SIZE_T size, ULONG tag) wstdcall; ++typedef void LOOKASIDE_FREE_FUNC(void *) wstdcall; ++ ++struct npaged_lookaside_list { ++ nt_slist_header head; ++ USHORT depth; ++ USHORT maxdepth; ++ ULONG totalallocs; ++ union { ++ ULONG allocmisses; ++ ULONG allochits; ++ } u1; ++ ULONG totalfrees; ++ union { ++ ULONG freemisses; ++ ULONG freehits; ++ } u2; ++ enum pool_type pool_type; ++ ULONG tag; ++ ULONG size; ++ LOOKASIDE_ALLOC_FUNC *alloc_func; ++ LOOKASIDE_FREE_FUNC *free_func; ++ struct nt_list list; ++ ULONG lasttotallocs; ++ union { ++ ULONG lastallocmisses; ++ ULONG lastallochits; ++ } u3; ++ ULONG pad[2]; ++#ifndef CONFIG_X86_64 ++ NT_SPIN_LOCK obsolete; ++#endif ++} ++#ifdef CONFIG_X86_64 ++CACHE_ALIGN ++#endif ++; ++ ++enum device_registry_property { ++ DevicePropertyDeviceDescription, DevicePropertyHardwareID, ++ DevicePropertyCompatibleIDs, DevicePropertyBootConfiguration, ++ DevicePropertyBootConfigurationTranslated, ++ DevicePropertyClassName, DevicePropertyClassGuid, ++ DevicePropertyDriverKeyName, DevicePropertyManufacturer, ++ DevicePropertyFriendlyName, DevicePropertyLocationInformation, ++ DevicePropertyPhysicalDeviceObjectName, DevicePropertyBusTypeGuid, ++ DevicePropertyLegacyBusType, DevicePropertyBusNumber, ++ DevicePropertyEnumeratorName, DevicePropertyAddress, ++ DevicePropertyUINumber, DevicePropertyInstallState, ++ DevicePropertyRemovalPolicy ++}; ++ ++enum trace_information_class { ++ TraceIdClass, TraceHandleClass, TraceEnableFlagsClass, ++ TraceEnableLevelClass, GlobalLoggerHandleClass, EventLoggerHandleClass, ++ AllLoggerHandlesClass, TraceHandleByNameClass ++}; ++ ++struct kinterrupt; ++typedef BOOLEAN (*PKSERVICE_ROUTINE)(struct kinterrupt *interrupt, ++ void *context) wstdcall; ++typedef BOOLEAN (*PKSYNCHRONIZE_ROUTINE)(void *context) wstdcall; ++ ++struct kinterrupt { ++ ULONG vector; ++ KAFFINITY cpu_mask; ++ NT_SPIN_LOCK lock; ++ NT_SPIN_LOCK *actual_lock; ++ BOOLEAN shared; ++ BOOLEAN save_fp; ++ union { ++ CHAR processor_number; ++#ifdef CONFIG_DEBUG_SHIRQ ++ CHAR enabled; ++#endif ++ } u; ++ PKSERVICE_ROUTINE isr; ++ void *isr_ctx; ++ struct nt_list list; ++ KIRQL irql; ++ KIRQL synch_irql; ++ enum kinterrupt_mode mode; ++}; ++ ++struct time_fields { ++ CSHORT year; ++ CSHORT month; ++ CSHORT day; ++ CSHORT hour; ++ CSHORT minute; ++ CSHORT second; ++ CSHORT milliseconds; ++ CSHORT weekday; ++}; ++ ++struct object_attributes { ++ ULONG length; ++ void *root_dir; ++ struct unicode_string *name; ++ ULONG attributes; ++ void *security_descr; ++ void *security_qos; ++}; ++ ++typedef void (*PCALLBACK_FUNCTION)(void *context, void *arg1, ++ void *arg2) wstdcall; ++ ++struct callback_object; ++struct callback_func { ++ PCALLBACK_FUNCTION func; ++ void *context; ++ struct nt_list list; ++ struct callback_object *object; ++}; ++ ++struct callback_object { ++ NT_SPIN_LOCK lock; ++ struct nt_list list; ++ struct nt_list callback_funcs; ++ BOOLEAN allow_multiple_callbacks; ++ struct object_attributes *attributes; ++}; ++ ++enum section_inherit { ++ ViewShare = 1, ViewUnmap = 2 ++}; ++ ++struct ksystem_time { ++ ULONG low_part; ++ LONG high1_time; ++ LONG high2_time; ++}; ++ ++enum nt_product_type { ++ nt_product_win_nt = 1, nt_product_lan_man_nt, nt_product_server ++}; ++ ++enum alt_arch_type { ++ arch_type_standard, arch_type_nex98x86, end_alternatives ++}; ++ ++struct kuser_shared_data { ++ ULONG tick_count; ++ ULONG tick_count_multiplier; ++ volatile struct ksystem_time interrupt_time; ++ volatile struct ksystem_time system_time; ++ volatile struct ksystem_time time_zone_bias; ++ USHORT image_number_low; ++ USHORT image_number_high; ++ wchar_t nt_system_root[260]; ++ ULONG max_stack_trace_depth; ++ ULONG crypto_exponent; ++ ULONG time_zone_id; ++ ULONG large_page_min; ++ ULONG reserved2[7]; ++ enum nt_product_type nt_product_type; ++ BOOLEAN product_type_is_valid; ++ ULONG nt_major_version; ++ ULONG nt_minor_version; ++ BOOLEAN processor_features[PROCESSOR_FEATURE_MAX]; ++ ULONG reserved1; ++ ULONG reserved3; ++ volatile LONG time_slip; ++ enum alt_arch_type alt_arch_type; ++ LARGE_INTEGER system_expiration_date; ++ ULONG suite_mask; ++ BOOLEAN kdbg_enabled; ++ volatile ULONG active_console; ++ volatile ULONG dismount_count; ++ ULONG com_plus_package; ++ ULONG last_system_rite_event_tick_count; ++ ULONG num_phys_pages; ++ BOOLEAN safe_boot_mode; ++ ULONG trace_log; ++ ULONGLONG fill0; ++ ULONGLONG sys_call[4]; ++ union { ++ volatile struct ksystem_time tick_count; ++ volatile ULONG64 tick_count_quad; ++ } tick; ++}; ++ ++#define REG_NONE (0) ++#define REG_SZ (1) ++#define REG_EXPAND_SZ (2) ++#define REG_BINARY (3) ++#define REG_DWORD (4) ++ ++#define RTL_REGISTRY_ABSOLUTE 0 ++#define RTL_REGISTRY_SERVICES 1 ++#define RTL_REGISTRY_CONTROL 2 ++#define RTL_REGISTRY_WINDOWS_NT 3 ++#define RTL_REGISTRY_DEVICEMAP 4 ++#define RTL_REGISTRY_USER 5 ++#define RTL_REGISTRY_MAXIMUM 6 ++#define RTL_REGISTRY_HANDLE 0x40000000 ++#define RTL_REGISTRY_OPTIONAL 0x80000000 ++ ++#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 ++#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 ++#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 ++#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 ++#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 ++#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 ++#define RTL_QUERY_REGISTRY_DELETE 0x00000040 ++ ++typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)(wchar_t *name, ULONG type, ++ void *data, ULONG length, ++ void *context, ++ void *entry) wstdcall; ++ ++struct rtl_query_registry_table { ++ PRTL_QUERY_REGISTRY_ROUTINE query_func; ++ ULONG flags; ++ wchar_t *name; ++ void *context; ++ ULONG def_type; ++ void *def_data; ++ ULONG def_length; ++}; ++ ++struct io_remove_lock { ++ BOOLEAN removed; ++ BOOLEAN reserved[3]; ++ LONG io_count; ++ struct nt_event remove_event; ++}; ++ ++struct io_error_log_packet { ++ UCHAR major_fn_code; ++ UCHAR retry_count; ++ USHORT dump_data_size; ++ USHORT nr_of_strings; ++ USHORT string_offset; ++ USHORT event_category; ++ NTSTATUS error_code; ++ ULONG unique_error_value; ++ NTSTATUS final_status; ++ ULONG sequence_number; ++ ULONG io_control_code; ++ LARGE_INTEGER device_offset; ++ ULONG dump_data[1]; ++}; ++ ++/* some of the functions below are slightly different from DDK's ++ * implementation; e.g., Insert functions return appropriate ++ * pointer */ ++ ++/* instead of using Linux's lists, we implement list manipulation ++ * functions because nt_list is used by drivers and we don't want to ++ * worry about Linux's list being different from nt_list (right now ++ * they are same, but in future they could be different) */ ++ ++static inline void InitializeListHead(struct nt_list *head) ++{ ++ head->next = head->prev = head; ++} ++ ++static inline BOOLEAN IsListEmpty(struct nt_list *head) ++{ ++ if (head == head->next) ++ return TRUE; ++ else ++ return FALSE; ++} ++ ++static inline void RemoveEntryList(struct nt_list *entry) ++{ ++ entry->prev->next = entry->next; ++ entry->next->prev = entry->prev; ++} ++ ++static inline struct nt_list *RemoveHeadList(struct nt_list *head) ++{ ++ struct nt_list *entry; ++ ++ entry = head->next; ++ if (entry == head) ++ return NULL; ++ else { ++ RemoveEntryList(entry); ++ return entry; ++ } ++} ++ ++static inline struct nt_list *RemoveTailList(struct nt_list *head) ++{ ++ struct nt_list *entry; ++ ++ entry = head->prev; ++ if (entry == head) ++ return NULL; ++ else { ++ RemoveEntryList(entry); ++ return entry; ++ } ++} ++ ++static inline void InsertListEntry(struct nt_list *entry, struct nt_list *prev, ++ struct nt_list *next) ++{ ++ next->prev = entry; ++ entry->next = next; ++ entry->prev = prev; ++ prev->next = entry; ++} ++ ++static inline struct nt_list *InsertHeadList(struct nt_list *head, ++ struct nt_list *entry) ++{ ++ struct nt_list *ret; ++ ++ if (IsListEmpty(head)) ++ ret = NULL; ++ else ++ ret = head->next; ++ ++ InsertListEntry(entry, head, head->next); ++ return ret; ++} ++ ++static inline struct nt_list *InsertTailList(struct nt_list *head, ++ struct nt_list *entry) ++{ ++ struct nt_list *ret; ++ ++ if (IsListEmpty(head)) ++ ret = NULL; ++ else ++ ret = head->prev; ++ ++ InsertListEntry(entry, head->prev, head); ++ return ret; ++} ++ ++#define nt_list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) ++ ++#define nt_list_for_each_entry(pos, head, member) \ ++ for (pos = container_of((head)->next, typeof(*pos), member); \ ++ &pos->member != (head); \ ++ pos = container_of(pos->member.next, typeof(*pos), member)) ++ ++#define nt_list_for_each_safe(pos, n, head) \ ++ for (pos = (head)->next, n = pos->next; pos != (head); \ ++ pos = n, n = pos->next) ++ ++/* device object flags */ ++#define DO_VERIFY_VOLUME 0x00000002 ++#define DO_BUFFERED_IO 0x00000004 ++#define DO_EXCLUSIVE 0x00000008 ++#define DO_DIRECT_IO 0x00000010 ++#define DO_MAP_IO_BUFFER 0x00000020 ++#define DO_DEVICE_HAS_NAME 0x00000040 ++#define DO_DEVICE_INITIALIZING 0x00000080 ++#define DO_SYSTEM_BOOT_PARTITION 0x00000100 ++#define DO_LONG_TERM_REQUESTS 0x00000200 ++#define DO_NEVER_LAST_DEVICE 0x00000400 ++#define DO_SHUTDOWN_REGISTERED 0x00000800 ++#define DO_BUS_ENUMERATED_DEVICE 0x00001000 ++#define DO_POWER_PAGABLE 0x00002000 ++#define DO_POWER_INRUSH 0x00004000 ++#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 ++ ++/* Various supported device types (used with IoCreateDevice()) */ ++ ++#define FILE_DEVICE_BEEP 0x00000001 ++#define FILE_DEVICE_CD_ROM 0x00000002 ++#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 ++#define FILE_DEVICE_CONTROLLER 0x00000004 ++#define FILE_DEVICE_DATALINK 0x00000005 ++#define FILE_DEVICE_DFS 0x00000006 ++#define FILE_DEVICE_DISK 0x00000007 ++#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 ++#define FILE_DEVICE_FILE_SYSTEM 0x00000009 ++#define FILE_DEVICE_INPORT_PORT 0x0000000A ++#define FILE_DEVICE_KEYBOARD 0x0000000B ++#define FILE_DEVICE_MAILSLOT 0x0000000C ++#define FILE_DEVICE_MIDI_IN 0x0000000D ++#define FILE_DEVICE_MIDI_OUT 0x0000000E ++#define FILE_DEVICE_MOUSE 0x0000000F ++#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 ++#define FILE_DEVICE_NAMED_PIPE 0x00000011 ++#define FILE_DEVICE_NETWORK 0x00000012 ++#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 ++#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 ++#define FILE_DEVICE_NULL 0x00000015 ++#define FILE_DEVICE_PARALLEL_PORT 0x00000016 ++#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 ++#define FILE_DEVICE_PRINTER 0x00000018 ++#define FILE_DEVICE_SCANNER 0x00000019 ++#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A ++#define FILE_DEVICE_SERIAL_PORT 0x0000001B ++#define FILE_DEVICE_SCREEN 0x0000001C ++#define FILE_DEVICE_SOUND 0x0000001D ++#define FILE_DEVICE_STREAMS 0x0000001E ++#define FILE_DEVICE_TAPE 0x0000001F ++#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 ++#define FILE_DEVICE_TRANSPORT 0x00000021 ++#define FILE_DEVICE_UNKNOWN 0x00000022 ++#define FILE_DEVICE_VIDEO 0x00000023 ++#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 ++#define FILE_DEVICE_WAVE_IN 0x00000025 ++#define FILE_DEVICE_WAVE_OUT 0x00000026 ++#define FILE_DEVICE_8042_PORT 0x00000027 ++#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 ++#define FILE_DEVICE_BATTERY 0x00000029 ++#define FILE_DEVICE_BUS_EXTENDER 0x0000002A ++#define FILE_DEVICE_MODEM 0x0000002B ++#define FILE_DEVICE_VDM 0x0000002C ++#define FILE_DEVICE_MASS_STORAGE 0x0000002D ++#define FILE_DEVICE_SMB 0x0000002E ++#define FILE_DEVICE_KS 0x0000002F ++#define FILE_DEVICE_CHANGER 0x00000030 ++#define FILE_DEVICE_SMARTCARD 0x00000031 ++#define FILE_DEVICE_ACPI 0x00000032 ++#define FILE_DEVICE_DVD 0x00000033 ++#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 ++#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 ++#define FILE_DEVICE_DFS_VOLUME 0x00000036 ++#define FILE_DEVICE_SERENUM 0x00000037 ++#define FILE_DEVICE_TERMSRV 0x00000038 ++#define FILE_DEVICE_KSEC 0x00000039 ++#define FILE_DEVICE_FIPS 0x0000003A ++ ++/* Device characteristics */ ++ ++#define FILE_REMOVABLE_MEDIA 0x00000001 ++#define FILE_READ_ONLY_DEVICE 0x00000002 ++#define FILE_FLOPPY_DISKETTE 0x00000004 ++#define FILE_WRITE_ONCE_MEDIA 0x00000008 ++#define FILE_REMOTE_DEVICE 0x00000010 ++#define FILE_DEVICE_IS_MOUNTED 0x00000020 ++#define FILE_VIRTUAL_VOLUME 0x00000040 ++#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 ++#define FILE_DEVICE_SECURE_OPEN 0x00000100 ++ ++#define FILE_READ_DATA 0x0001 ++#define FILE_WRITE_DATA 0x0002 ++ ++#define FILE_SUPERSEDED 0x00000000 ++#define FILE_OPENED 0x00000001 ++#define FILE_CREATED 0x00000002 ++#define FILE_OVERWRITTEN 0x00000003 ++#define FILE_EXISTS 0x00000004 ++#define FILE_DOES_NOT_EXIST 0x00000005 ++ ++ ++#endif /* WINNT_TYPES_H */ +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/workqueue.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/workqueue.c +--- linux-3.12.2/3rdparty/ndiswrapper/workqueue.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/workqueue.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,279 @@ ++/* ++ * Copyright (C) 2006 Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ntoskernel.h" ++ ++struct workqueue_thread { ++ spinlock_t lock; ++ struct task_struct *task; ++ struct completion *completion; ++ char name[16]; ++ int pid; ++ /* whether any work_structs pending? <0 implies quit */ ++ s8 pending; ++ /* list of work_structs pending */ ++ struct list_head work_list; ++}; ++ ++struct workq_thread_data { ++ struct workqueue_struct *workq; ++ int index; ++}; ++ ++struct wrap_workqueue_struct { ++ u8 singlethread; ++ u8 qon; ++ int num_cpus; ++ struct workqueue_thread threads[0]; ++}; ++ ++static void wrap_destroy_wq_on(struct workqueue_struct *workq, int cpu); ++ ++static int workq_thread(void *data) ++{ ++ struct workq_thread_data *thread_data = data; ++ struct workqueue_thread *thread; ++ struct workqueue_struct *workq; ++ struct work_struct *work; ++ ++ workq = thread_data->workq; ++ thread = &workq->threads[thread_data->index]; ++ WORKTRACE("%p, %d, %p", workq, thread_data->index, thread); ++ strncpy(thread->name, current->comm, sizeof(thread->name)); ++ ++ daemonize(thread->name); ++ set_user_nice(current, -5); ++ ++ if (thread->task != current) { ++ WARNING("invalid task: %p, %p", thread->task, current); ++ thread->task = current; ++ } ++ thread->pid = current->pid; ++ complete(xchg(&thread->completion, NULL)); ++ WORKTRACE("%s (%d) started", thread->name, thread->pid); ++ while (1) { ++ if (wait_condition(thread->pending, 0, TASK_INTERRUPTIBLE) < 0) { ++ /* TODO: deal with signal */ ++ WARNING("signal not blocked?"); ++ flush_signals(current); ++ continue; ++ } ++ while (1) { ++ struct list_head *entry; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&thread->lock, flags); ++ if (list_empty(&thread->work_list)) { ++ struct completion *completion; ++ if (thread->pending < 0) { ++ spin_unlock_irqrestore(&thread->lock, ++ flags); ++ goto out; ++ } ++ thread->pending = 0; ++ completion = thread->completion; ++ thread->completion = NULL; ++ spin_unlock_irqrestore(&thread->lock, flags); ++ if (completion) ++ complete(completion); ++ break; ++ } ++ entry = thread->work_list.next; ++ work = list_entry(entry, struct work_struct, list); ++ if (xchg(&work->thread, NULL)) ++ list_del(entry); ++ else ++ work = NULL; ++ spin_unlock_irqrestore(&thread->lock, flags); ++ DBG_BLOCK(4) { ++ WORKTRACE("%p, %p", work, thread); ++ } ++ if (work) ++ work->func(work->data); ++ } ++ } ++ ++out: ++ WORKTRACE("%s exiting", thread->name); ++ thread->pid = 0; ++ return 0; ++} ++ ++static int wrap_queue_work_on(struct workqueue_struct *workq, ++ struct work_struct *work, int cpu) ++{ ++ struct workqueue_thread *thread = &workq->threads[cpu]; ++ unsigned long flags; ++ int ret; ++ ++ assert(thread->pid > 0); ++ DBG_BLOCK(4) { ++ WORKTRACE("%p, %d", workq, cpu); ++ } ++ spin_lock_irqsave(&thread->lock, flags); ++ if (work->thread) ++ ret = 0; ++ else { ++ work->thread = thread; ++ list_add_tail(&work->list, &thread->work_list); ++ thread->pending = 1; ++ wake_up_process(thread->task); ++ ret = 1; ++ } ++ spin_unlock_irqrestore(&thread->lock, flags); ++ return ret; ++} ++ ++int wrap_queue_work(struct workqueue_struct *workq, struct work_struct *work) ++{ ++ if (num_online_cpus() == 1 || workq->singlethread) ++ return wrap_queue_work_on(workq, work, 0); ++ else { ++ typeof(workq->qon) qon; ++ /* work is queued on threads in a round-robin fashion */ ++ do { ++ qon = workq->qon % workq->num_cpus; ++ atomic_inc_var(workq->qon); ++ } while (!workq->threads[qon].pid); ++ return wrap_queue_work_on(workq, work, qon); ++ } ++} ++ ++void wrap_cancel_work(struct work_struct *work) ++{ ++ struct workqueue_thread *thread; ++ unsigned long flags; ++ ++ WORKTRACE("%p", work); ++ if ((thread = xchg(&work->thread, NULL))) { ++ WORKTRACE("%p", thread); ++ spin_lock_irqsave(&thread->lock, flags); ++ list_del(&work->list); ++ spin_unlock_irqrestore(&thread->lock, flags); ++ } ++} ++ ++struct workqueue_struct *wrap_create_wq(const char *name, u8 singlethread, ++ u8 freeze) ++{ ++ struct completion started; ++ struct workqueue_struct *workq; ++ int i, n; ++ ++ if (singlethread) ++ n = 1; ++ else ++ n = num_online_cpus(); ++ workq = kzalloc(sizeof(*workq) + n * sizeof(workq->threads[0]), ++ GFP_KERNEL); ++ if (!workq) { ++ WARNING("couldn't allocate memory"); ++ return NULL; ++ } ++ WORKTRACE("%p", workq); ++ workq->singlethread = singlethread; ++ init_completion(&started); ++ for_each_online_cpu(i) { ++ struct workq_thread_data thread_data; ++ spin_lock_init(&workq->threads[i].lock); ++ INIT_LIST_HEAD(&workq->threads[i].work_list); ++ reinit_completion(&started); ++ workq->threads[i].completion = &started; ++ thread_data.workq = workq; ++ thread_data.index = i; ++ WORKTRACE("%p, %d, %p", workq, i, &workq->threads[i]); ++ workq->threads[i].task = ++ kthread_create(workq_thread, &thread_data, ++ "%s/%d", name, i); ++ if (IS_ERR(workq->threads[i].task)) { ++ int j; ++ for (j = 0; j < i; j++) ++ wrap_destroy_wq_on(workq, j); ++ kfree(workq); ++ WARNING("couldn't start thread %s", name); ++ return NULL; ++ } ++#ifdef PF_NOFREEZE ++ if (!freeze) ++ workq->threads[i].task->flags |= PF_NOFREEZE; ++#endif ++ kthread_bind(workq->threads[i].task, i); ++ workq->num_cpus = max(workq->num_cpus, i); ++ wake_up_process(workq->threads[i].task); ++ wait_for_completion(&started); ++ WORKTRACE("%s, %d: %p, %d", name, i, ++ workq, workq->threads[i].pid); ++ if (singlethread) ++ break; ++ } ++ workq->num_cpus++; ++ return workq; ++} ++ ++static void wrap_flush_wq_on(struct workqueue_struct *workq, int cpu) ++{ ++ struct workqueue_thread *thread = &workq->threads[cpu]; ++ struct completion done; ++ ++ WORKTRACE("%p: %d, %s", workq, cpu, thread->name); ++ init_completion(&done); ++ thread->completion = &done; ++ thread->pending = 1; ++ wake_up_process(thread->task); ++ wait_for_completion(&done); ++ return; ++} ++ ++void wrap_flush_wq(struct workqueue_struct *workq) ++{ ++ int i, n; ++ ++ WORKTRACE("%p", workq); ++ if (workq->singlethread) ++ n = 1; ++ else ++ n = num_online_cpus(); ++ for (i = 0; i < n; i++) ++ wrap_flush_wq_on(workq, i); ++} ++ ++static void wrap_destroy_wq_on(struct workqueue_struct *workq, int cpu) ++{ ++ struct workqueue_thread *thread = &workq->threads[cpu]; ++ ++ WORKTRACE("%p: %d, %s", workq, cpu, thread->name); ++ if (!thread->pid) ++ return; ++ thread->pending = -1; ++ wake_up_process(thread->task); ++ while (thread->pid) { ++ WORKTRACE("%d", thread->pid); ++ schedule(); ++ } ++} ++ ++void wrap_destroy_wq(struct workqueue_struct *workq) ++{ ++ int i, n; ++ ++ WORKTRACE("%p", workq); ++ if (workq->singlethread) ++ n = 1; ++ else ++ n = num_online_cpus(); ++ for (i = 0; i < n; i++) ++ wrap_destroy_wq_on(workq, i); ++ kfree(workq); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/wrapmem.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapmem.c +--- linux-3.12.2/3rdparty/ndiswrapper/wrapmem.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapmem.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,366 @@ ++/* ++ * Copyright (C) 2006 Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#define _WRAPMEM_C_ ++ ++#include "ntoskernel.h" ++#include "wrapmem.h" ++ ++struct slack_alloc_info { ++ struct nt_list list; ++ size_t size; ++}; ++ ++#if ALLOC_DEBUG > 1 ++static struct nt_list allocs; ++#endif ++ ++static struct nt_list slack_allocs; ++static spinlock_t alloc_lock; ++ ++#if ALLOC_DEBUG ++const char *alloc_type_name[ALLOC_TYPE_MAX] = { ++ "kmalloc_atomic", ++ "kmalloc_nonatomic", ++ "vmalloc_atomic", ++ "vmalloc_nonatomic", ++ "kmalloc_slack", ++ "pages" ++}; ++ ++struct alloc_info { ++ enum alloc_type type; ++ size_t size; ++#if ALLOC_DEBUG > 1 ++ struct nt_list list; ++ const char *file; ++ int line; ++ ULONG tag; ++#endif ++}; ++ ++static atomic_t alloc_sizes[ALLOC_TYPE_MAX]; ++#endif ++ ++/* allocate memory and add it to list of allocated pointers; if a ++ * driver doesn't free this memory for any reason (buggy driver or we ++ * allocate space behind driver's back since we need more space than ++ * corresponding Windows structure provides etc.), this gets freed ++ * automatically when module is unloaded ++ */ ++void *slack_kmalloc(size_t size) ++{ ++ struct slack_alloc_info *info; ++ ++ ENTER4("size = %zu", size); ++ info = kmalloc(size + sizeof(*info), irql_gfp()); ++ if (!info) ++ return NULL; ++ info->size = size; ++ spin_lock_bh(&alloc_lock); ++ InsertTailList(&slack_allocs, &info->list); ++ spin_unlock_bh(&alloc_lock); ++#if ALLOC_DEBUG ++ atomic_add(size, &alloc_sizes[ALLOC_TYPE_SLACK]); ++#endif ++ TRACE4("%p, %p", info, info + 1); ++ EXIT4(return info + 1); ++} ++ ++/* free pointer and remove from list of allocated pointers */ ++void slack_kfree(void *ptr) ++{ ++ struct slack_alloc_info *info; ++ ++ ENTER4("%p", ptr); ++ info = ptr - sizeof(*info); ++ spin_lock_bh(&alloc_lock); ++ RemoveEntryList(&info->list); ++ spin_unlock_bh(&alloc_lock); ++#if ALLOC_DEBUG ++ atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]); ++#endif ++ kfree(info); ++ EXIT4(return); ++} ++ ++void *slack_kzalloc(size_t size) ++{ ++ void *ptr = slack_kmalloc(size); ++ if (ptr) ++ memset(ptr, 0, size); ++ return ptr; ++} ++ ++#if ALLOC_DEBUG ++void *wrap_kmalloc(size_t size, gfp_t flags, const char *file, int line) ++{ ++ struct alloc_info *info; ++ ++ info = kmalloc(size + sizeof(*info), flags); ++ if (!info) ++ return NULL; ++ if (flags & GFP_ATOMIC) ++ info->type = ALLOC_TYPE_KMALLOC_ATOMIC; ++ else ++ info->type = ALLOC_TYPE_KMALLOC_NON_ATOMIC; ++ info->size = size; ++ atomic_add(size, &alloc_sizes[info->type]); ++#if ALLOC_DEBUG > 1 ++ info->file = file; ++ info->line = line; ++ info->tag = 0; ++ spin_lock_bh(&alloc_lock); ++ InsertTailList(&allocs, &info->list); ++ spin_unlock_bh(&alloc_lock); ++#endif ++ TRACE4("%p", info + 1); ++ return info + 1; ++} ++ ++void *wrap_kzalloc(size_t size, gfp_t flags, const char *file, int line) ++{ ++ void *ptr = wrap_kmalloc(size, flags, file, line); ++ if (ptr) ++ memset(ptr, 0, size); ++ return ptr; ++} ++ ++void wrap_kfree(void *ptr) ++{ ++ struct alloc_info *info; ++ ++ TRACE4("%p", ptr); ++ if (!ptr) ++ return; ++ info = ptr - sizeof(*info); ++ atomic_sub(info->size, &alloc_sizes[info->type]); ++#if ALLOC_DEBUG > 1 ++ spin_lock_bh(&alloc_lock); ++ RemoveEntryList(&info->list); ++ spin_unlock_bh(&alloc_lock); ++ if (!(info->type == ALLOC_TYPE_KMALLOC_ATOMIC || ++ info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC)) { ++ WARNING("invalid type: %d", info->type); ++ return; ++ } ++#endif ++ kfree(info); ++} ++ ++void *wrap_vmalloc(unsigned long size, const char *file, int line) ++{ ++ struct alloc_info *info; ++ ++ info = vmalloc(size + sizeof(*info)); ++ if (!info) ++ return NULL; ++ info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC; ++ info->size = size; ++ atomic_add(size, &alloc_sizes[info->type]); ++#if ALLOC_DEBUG > 1 ++ info->file = file; ++ info->line = line; ++ info->tag = 0; ++ spin_lock_bh(&alloc_lock); ++ InsertTailList(&allocs, &info->list); ++ spin_unlock_bh(&alloc_lock); ++#endif ++ return info + 1; ++} ++ ++void *wrap__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot, ++ const char *file, int line) ++{ ++ struct alloc_info *info; ++ ++ info = __vmalloc(size + sizeof(*info), gfp_mask, prot); ++ if (!info) ++ return NULL; ++ if (gfp_mask & GFP_ATOMIC) ++ info->type = ALLOC_TYPE_VMALLOC_ATOMIC; ++ else ++ info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC; ++ info->size = size; ++ atomic_add(size, &alloc_sizes[info->type]); ++#if ALLOC_DEBUG > 1 ++ info->file = file; ++ info->line = line; ++ info->tag = 0; ++ spin_lock_bh(&alloc_lock); ++ InsertTailList(&allocs, &info->list); ++ spin_unlock_bh(&alloc_lock); ++#endif ++ return info + 1; ++} ++ ++void wrap_vfree(void *ptr) ++{ ++ struct alloc_info *info; ++ ++ info = ptr - sizeof(*info); ++ atomic_sub(info->size, &alloc_sizes[info->type]); ++#if ALLOC_DEBUG > 1 ++ spin_lock_bh(&alloc_lock); ++ RemoveEntryList(&info->list); ++ spin_unlock_bh(&alloc_lock); ++ if (!(info->type == ALLOC_TYPE_VMALLOC_ATOMIC || ++ info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC)) { ++ WARNING("invalid type: %d", info->type); ++ return; ++ } ++#endif ++ vfree(info); ++} ++ ++void *wrap_alloc_pages(gfp_t flags, unsigned int size, ++ const char *file, int line) ++{ ++ struct alloc_info *info; ++ ++ size += sizeof(*info); ++ info = (struct alloc_info *)__get_free_pages(flags, get_order(size)); ++ if (!info) ++ return NULL; ++ info->type = ALLOC_TYPE_PAGES; ++ info->size = size; ++ atomic_add(size, &alloc_sizes[info->type]); ++#if ALLOC_DEBUG > 1 ++ info->file = file; ++ info->line = line; ++ info->tag = 0; ++ spin_lock_bh(&alloc_lock); ++ InsertTailList(&allocs, &info->list); ++ spin_unlock_bh(&alloc_lock); ++#endif ++ return info + 1; ++} ++ ++void wrap_free_pages(unsigned long ptr, int order) ++{ ++ struct alloc_info *info; ++ ++ info = (void *)ptr - sizeof(*info); ++ atomic_sub(info->size, &alloc_sizes[info->type]); ++#if ALLOC_DEBUG > 1 ++ spin_lock_bh(&alloc_lock); ++ RemoveEntryList(&info->list); ++ spin_unlock_bh(&alloc_lock); ++ if (info->type != ALLOC_TYPE_PAGES) { ++ WARNING("invalid type: %d", info->type); ++ return; ++ } ++#endif ++ free_pages((unsigned long)info, get_order(info->size)); ++} ++ ++#if ALLOC_DEBUG > 1 ++void *wrap_ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size, ++ ULONG tag, const char *file, int line) ++{ ++ void *addr; ++ struct alloc_info *info; ++ ++ ENTER4("pool_type: %d, size: %zu, tag: %u", pool_type, size, tag); ++ addr = (ExAllocatePoolWithTag)(pool_type, size, tag); ++ if (!addr) ++ return NULL; ++ info = addr - sizeof(*info); ++ info->file = file; ++ info->line = line; ++ info->tag = tag; ++ EXIT4(return addr); ++} ++#endif ++ ++int alloc_size(enum alloc_type type) ++{ ++ if ((int)type >= 0 && type < ALLOC_TYPE_MAX) ++ return atomic_read(&alloc_sizes[type]); ++ else ++ return -EINVAL; ++} ++ ++#endif // ALLOC_DEBUG ++ ++int wrapmem_init(void) ++{ ++#if ALLOC_DEBUG > 1 ++ InitializeListHead(&allocs); ++#endif ++ InitializeListHead(&slack_allocs); ++ spin_lock_init(&alloc_lock); ++ return 0; ++} ++ ++void wrapmem_exit(void) ++{ ++#if ALLOC_DEBUG ++ enum alloc_type type; ++#endif ++ struct nt_list *ent; ++ ++ /* free all pointers on the slack list */ ++ while (1) { ++ struct slack_alloc_info *info; ++ spin_lock_bh(&alloc_lock); ++ ent = RemoveHeadList(&slack_allocs); ++ spin_unlock_bh(&alloc_lock); ++ if (!ent) ++ break; ++ info = container_of(ent, struct slack_alloc_info, list); ++#if ALLOC_DEBUG ++ atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]); ++#endif ++ kfree(info); ++ } ++#if ALLOC_DEBUG ++ for (type = 0; type < ALLOC_TYPE_MAX; type++) { ++ int n = atomic_read(&alloc_sizes[type]); ++ if (n) ++ WARNING("%d bytes of memory in %s leaking", n, ++ alloc_type_name[type]); ++ } ++ ++#if ALLOC_DEBUG > 1 ++ while (1) { ++ struct alloc_info *info; ++ ++ spin_lock_bh(&alloc_lock); ++ ent = RemoveHeadList(&allocs); ++ spin_unlock_bh(&alloc_lock); ++ if (!ent) ++ break; ++ info = container_of(ent, struct alloc_info, list); ++ atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]); ++ printk(KERN_DEBUG DRIVER_NAME ++ ": %s:%d leaked %zd bytes at %p (%s, tag 0x%08X)\n", ++ info->file, info->line, info->size, info + 1, ++ alloc_type_name[info->type], info->tag); ++ if (info->type == ALLOC_TYPE_KMALLOC_ATOMIC || ++ info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC) ++ kfree(info); ++ else if (info->type == ALLOC_TYPE_VMALLOC_ATOMIC || ++ info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC) ++ vfree(info); ++ else if (info->type == ALLOC_TYPE_PAGES) ++ free_pages((unsigned long)info, get_order(info->size)); ++ else ++ WARNING("invalid type: %d; not freed", info->type); ++ } ++#endif ++#endif ++ return; ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/wrapmem.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapmem.h +--- linux-3.12.2/3rdparty/ndiswrapper/wrapmem.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapmem.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,97 @@ ++/* ++ * Copyright (C) 2006 Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _WRAPMEM_H_ ++#define _WRAPMEM_H_ ++ ++/* ++ * Set ALLOC_DEBUG to 1 to show information about memory used by both ++ * ndiswrapper and Windows driver in /proc/net/ndiswrapper/debug ++ * This will also show memory leaks (memory allocated but not freed) when ++ * ndiswrapper module is unloaded. ++ * ++ * Set ALLOC_DEBUG to 2 to see details about every leaking allocation. ++*/ ++ ++#ifndef ALLOC_DEBUG ++#define ALLOC_DEBUG 0 ++#endif ++ ++int wrapmem_init(void); ++void wrapmem_exit(void); ++void *slack_kmalloc(size_t size); ++void *slack_kzalloc(size_t size); ++void slack_kfree(void *ptr); ++ ++#if ALLOC_DEBUG ++enum alloc_type { ALLOC_TYPE_KMALLOC_ATOMIC, ++ ALLOC_TYPE_KMALLOC_NON_ATOMIC, ++ ALLOC_TYPE_VMALLOC_ATOMIC, ALLOC_TYPE_VMALLOC_NON_ATOMIC, ++ ALLOC_TYPE_SLACK, ALLOC_TYPE_PAGES, ALLOC_TYPE_MAX }; ++ ++extern const char *alloc_type_name[ALLOC_TYPE_MAX]; ++ ++void *wrap_kmalloc(size_t size, gfp_t flags, const char *file, int line); ++void *wrap_kzalloc(size_t size, gfp_t flags, const char *file, int line); ++void wrap_kfree(void *ptr); ++void *wrap_vmalloc(unsigned long size, const char *file, int line); ++void *wrap__vmalloc(unsigned long size, gfp_t flags, pgprot_t prot, ++ const char *file, int line); ++void wrap_vfree(void *ptr); ++void *wrap_alloc_pages(gfp_t flags, unsigned int size, ++ const char *file, int line); ++void wrap_free_pages(unsigned long ptr, int order); ++int alloc_size(enum alloc_type type); ++ ++#if ALLOC_DEBUG > 1 ++void *wrap_ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size, ++ ULONG tag, const char *file, int line); ++#define ExAllocatePoolWithTag(pool_type, size, tag) \ ++ wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__) ++#endif ++ ++#ifndef _WRAPMEM_C_ ++#undef kmalloc ++#undef kzalloc ++#undef kfree ++#undef vmalloc ++#undef __vmalloc ++#undef vfree ++#define kmalloc(size, flags) \ ++ wrap_kmalloc(size, flags, __FILE__, __LINE__) ++#define kzalloc(size, flags) \ ++ wrap_kzalloc(size, flags, __FILE__, __LINE__) ++#define vmalloc(size) \ ++ wrap_vmalloc(size, __FILE__, __LINE__) ++#define __vmalloc(size, flags, prot) \ ++ wrap__vmalloc(size, flags, prot, __FILE__, __LINE__) ++#define kfree(ptr) wrap_kfree(ptr) ++#define vfree(ptr) wrap_vfree(ptr) ++ ++#define wrap_get_free_pages(flags, size) \ ++ wrap_alloc_pages(flags, size, __FILE__, __LINE__) ++#undef free_pages ++#define free_pages(ptr, order) wrap_free_pages(ptr, order) ++ ++#endif // _WRAPMEM_C_ ++ ++#else ++ ++#define wrap_get_free_pages(flags, size) \ ++ (void *)__get_free_pages(flags, get_order(size)) ++ ++#endif // ALLOC_DEBUG ++ ++#endif +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/wrapndis.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapndis.c +--- linux-3.12.2/3rdparty/ndiswrapper/wrapndis.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapndis.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,2186 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include "ndis.h" ++#include "iw_ndis.h" ++#include "pnp.h" ++#include "loader.h" ++#include "wrapndis.h" ++#include "wrapper.h" ++ ++/* Functions callable from the NDIS driver */ ++wstdcall NTSTATUS NdisDispatchDeviceControl(struct device_object *fdo, ++ struct irp *irp); ++wstdcall NTSTATUS NdisDispatchPnp(struct device_object *fdo, struct irp *irp); ++wstdcall NTSTATUS NdisDispatchPower(struct device_object *fdo, struct irp *irp); ++ ++struct workqueue_struct *wrapndis_wq; ++ ++static int set_packet_filter(struct ndis_device *wnd, ++ ULONG packet_filter); ++static void add_iw_stats_timer(struct ndis_device *wnd); ++static void del_iw_stats_timer(struct ndis_device *wnd); ++static NDIS_STATUS ndis_start_device(struct ndis_device *wnd); ++static int ndis_remove_device(struct ndis_device *wnd); ++static void set_multicast_list(struct ndis_device *wnd); ++static int ndis_net_dev_open(struct net_device *net_dev); ++static int ndis_net_dev_close(struct net_device *net_dev); ++ ++/* MiniportReset */ ++NDIS_STATUS mp_reset(struct ndis_device *wnd) ++{ ++ NDIS_STATUS res; ++ struct miniport *mp; ++ BOOLEAN reset_address; ++ KIRQL irql; ++ ++ ENTER2("wnd: %p", wnd); ++ mutex_lock(&wnd->tx_ring_mutex); ++ mutex_lock(&wnd->ndis_req_mutex); ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ prepare_wait_condition(wnd->ndis_req_task, wnd->ndis_req_done, 0); ++ WARNING("%s is being reset", wnd->net_dev->name); ++ irql = serialize_lock_irql(wnd); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ res = LIN2WIN2(mp->reset, &reset_address, wnd->nmb->mp_ctx); ++ serialize_unlock_irql(wnd, irql); ++ ++ TRACE2("%08X, %08X", res, reset_address); ++ if (res == NDIS_STATUS_PENDING) { ++ /* wait for NdisMResetComplete */ ++ if (wait_condition((wnd->ndis_req_done > 0), 0, ++ TASK_INTERRUPTIBLE) < 0) ++ res = NDIS_STATUS_FAILURE; ++ else { ++ res = wnd->ndis_req_status; ++ reset_address = wnd->ndis_req_done - 1; ++ } ++ TRACE2("%08X, %08X", res, reset_address); ++ } ++ mutex_unlock(&wnd->ndis_req_mutex); ++ if (res == NDIS_STATUS_SUCCESS && reset_address) { ++ set_packet_filter(wnd, wnd->packet_filter); ++ set_multicast_list(wnd); ++ } ++ mutex_unlock(&wnd->tx_ring_mutex); ++ EXIT3(return res); ++} ++ ++/* MiniportRequest(Query/Set)Information */ ++NDIS_STATUS mp_request(enum ndis_request_type request, ++ struct ndis_device *wnd, ndis_oid oid, ++ void *buf, ULONG buflen, ULONG *written, ULONG *needed) ++{ ++ NDIS_STATUS res; ++ ULONG w, n; ++ struct miniport *mp; ++ KIRQL irql; ++ ++ mutex_lock(&wnd->ndis_req_mutex); ++ if (!written) ++ written = &w; ++ if (!needed) ++ needed = &n; ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ prepare_wait_condition(wnd->ndis_req_task, wnd->ndis_req_done, 0); ++ irql = serialize_lock_irql(wnd); ++ assert_irql(_irql_ == DISPATCH_LEVEL); ++ switch (request) { ++ case NdisRequestQueryInformation: ++ TRACE2("%p, %08X, %p", mp->queryinfo, oid, wnd->nmb->mp_ctx); ++ res = LIN2WIN6(mp->queryinfo, wnd->nmb->mp_ctx, oid, buf, ++ buflen, written, needed); ++ break; ++ case NdisRequestSetInformation: ++ TRACE2("%p, %08X, %p", mp->setinfo, oid, wnd->nmb->mp_ctx); ++ res = LIN2WIN6(mp->setinfo, wnd->nmb->mp_ctx, oid, buf, ++ buflen, written, needed); ++ break; ++ default: ++ WARNING("invalid request %d, %08X", request, oid); ++ res = NDIS_STATUS_NOT_SUPPORTED; ++ break; ++ } ++ serialize_unlock_irql(wnd, irql); ++ TRACE2("%08X, %08X", res, oid); ++ if (res == NDIS_STATUS_PENDING) { ++ /* wait for NdisMQueryInformationComplete */ ++ if (wait_condition((wnd->ndis_req_done > 0), 0, ++ TASK_INTERRUPTIBLE) < 0) ++ res = NDIS_STATUS_FAILURE; ++ else ++ res = wnd->ndis_req_status; ++ TRACE2("%08X, %08X", res, oid); ++ } ++ mutex_unlock(&wnd->ndis_req_mutex); ++ DBG_BLOCK(2) { ++ if (res || needed) ++ TRACE2("%08X, %d, %d, %d", res, buflen, *written, ++ *needed); ++ } ++ EXIT3(return res); ++} ++ ++/* MiniportPnPEventNotify */ ++static NDIS_STATUS mp_pnp_event(struct ndis_device *wnd, ++ enum ndis_device_pnp_event event, ++ ULONG power_profile) ++{ ++ struct miniport *mp; ++ ++ ENTER1("%p, %d", wnd, event); ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ if (!mp->pnp_event_notify) { ++ TRACE1("Windows driver %s doesn't support " ++ "MiniportPnpEventNotify", wnd->wd->driver->name); ++ return NDIS_STATUS_FAILURE; ++ } ++ /* RNDIS driver doesn't like to be notified if device is ++ * already halted */ ++ if (!test_bit(HW_INITIALIZED, &wnd->wd->hw_status)) ++ EXIT1(return NDIS_STATUS_SUCCESS); ++ switch (event) { ++ case NdisDevicePnPEventSurpriseRemoved: ++ TRACE1("%u, %p", ++ (wnd->attributes & NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK), ++ mp->pnp_event_notify); ++ if ((wnd->attributes & NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK) && ++ !test_bit(HW_DISABLED, &wnd->wd->hw_status) && ++ mp->pnp_event_notify) { ++ TRACE1("calling surprise_removed"); ++ LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx, ++ NdisDevicePnPEventSurpriseRemoved, NULL, 0); ++ } else ++ TRACE1("Windows driver %s doesn't support " ++ "MiniportPnpEventNotify for safe unplugging", ++ wnd->wd->driver->name); ++ return NDIS_STATUS_SUCCESS; ++ case NdisDevicePnPEventPowerProfileChanged: ++ if (power_profile) ++ power_profile = NdisPowerProfileAcOnLine; ++ LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx, ++ NdisDevicePnPEventPowerProfileChanged, ++ &power_profile, sizeof(power_profile)); ++ return NDIS_STATUS_SUCCESS; ++ default: ++ WARNING("event %d not yet implemented", event); ++ return NDIS_STATUS_SUCCESS; ++ } ++} ++ ++/* MiniportInitialize */ ++static NDIS_STATUS mp_init(struct ndis_device *wnd) ++{ ++ NDIS_STATUS error_status, status; ++ UINT medium_index; ++ enum ndis_medium medium_array[] = {NdisMedium802_3}; ++ struct miniport *mp; ++ ++ ENTER1("irql: %d", current_irql()); ++ if (test_bit(HW_INITIALIZED, &wnd->wd->hw_status)) { ++ WARNING("device %p already initialized!", wnd); ++ return NDIS_STATUS_FAILURE; ++ } ++ ++ if (!wnd->wd->driver->ndis_driver || ++ !wnd->wd->driver->ndis_driver->mp.init) { ++ WARNING("assuming WDM (non-NDIS) driver"); ++ EXIT1(return NDIS_STATUS_NOT_RECOGNIZED); ++ } ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ status = LIN2WIN6(mp->init, &error_status, &medium_index, medium_array, ++ ARRAY_SIZE(medium_array), wnd->nmb, wnd->nmb); ++ TRACE1("init returns: %08X, irql: %d", status, current_irql()); ++ if (status != NDIS_STATUS_SUCCESS) { ++ WARNING("couldn't initialize device: %08X", status); ++ EXIT1(return NDIS_STATUS_FAILURE); ++ } ++ ++ /* Wait a little to let card power up otherwise ifup might ++ * fail after boot */ ++ sleep_hz(HZ / 5); ++ status = mp_pnp_event(wnd, NdisDevicePnPEventPowerProfileChanged, ++ NdisPowerProfileAcOnLine); ++ if (status != NDIS_STATUS_SUCCESS) ++ TRACE1("setting power failed: %08X", status); ++ set_bit(HW_INITIALIZED, &wnd->wd->hw_status); ++ /* the description about NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND is ++ * misleading/confusing */ ++ status = mp_query(wnd, OID_PNP_CAPABILITIES, ++ &wnd->pnp_capa, sizeof(wnd->pnp_capa)); ++ if (status == NDIS_STATUS_SUCCESS) { ++ TRACE1("%d, %d", wnd->pnp_capa.wakeup.min_magic_packet_wakeup, ++ wnd->pnp_capa.wakeup.min_pattern_wakeup); ++ wnd->attributes |= NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; ++ status = mp_query_int(wnd, OID_PNP_ENABLE_WAKE_UP, ++ &wnd->ndis_wolopts); ++ TRACE1("%08X, %x", status, wnd->ndis_wolopts); ++ } else if (status == NDIS_STATUS_NOT_SUPPORTED) ++ wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; ++ TRACE1("%d", wnd->pnp_capa.wakeup.min_magic_packet_wakeup); ++ /* although some NDIS drivers support suspend, Linux kernel ++ * has issues with suspending USB devices */ ++ if (wrap_is_usb_bus(wnd->wd->dev_bus)) { ++ wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; ++ wnd->ndis_wolopts = 0; ++ } ++ mp_set_int(wnd, OID_802_11_POWER_MODE, NDIS_POWER_OFF); ++ EXIT1(return NDIS_STATUS_SUCCESS); ++} ++ ++/* MiniportHalt */ ++static void mp_halt(struct ndis_device *wnd) ++{ ++ struct miniport *mp; ++ ++ ENTER1("%p", wnd); ++ if (!test_and_clear_bit(HW_INITIALIZED, &wnd->wd->hw_status)) { ++ WARNING("device %p is not initialized - not halting", wnd); ++ return; ++ } ++ hangcheck_del(wnd); ++ del_iw_stats_timer(wnd); ++#ifdef CONFIG_WIRELESS_EXT ++ if (wnd->physical_medium == NdisPhysicalMediumWirelessLan && ++ wrap_is_pci_bus(wnd->wd->dev_bus)) { ++ mutex_unlock(&wnd->ndis_req_mutex); ++ disassociate(wnd, 0); ++ mutex_lock(&wnd->ndis_req_mutex); ++ } ++#endif ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ TRACE1("halt: %p", mp->mp_halt); ++ LIN2WIN1(mp->mp_halt, wnd->nmb->mp_ctx); ++ /* if a driver doesn't call NdisMDeregisterInterrupt during ++ * halt, deregister it now */ ++ if (wnd->mp_interrupt) ++ NdisMDeregisterInterrupt(wnd->mp_interrupt); ++ /* cancel any timers left by buggy windows driver; also free ++ * the memory for timers */ ++ while (1) { ++ struct nt_slist *slist; ++ struct wrap_timer *wrap_timer; ++ ++ spin_lock_bh(&ntoskernel_lock); ++ if ((slist = wnd->wrap_timer_slist.next)) ++ wnd->wrap_timer_slist.next = slist->next; ++ spin_unlock_bh(&ntoskernel_lock); ++ TIMERTRACE("%p", slist); ++ if (!slist) ++ break; ++ wrap_timer = container_of(slist, struct wrap_timer, slist); ++ wrap_timer->repeat = 0; ++ /* ktimer that this wrap_timer is associated to can't ++ * be touched, as it may have been freed by the driver ++ * already */ ++ if (del_timer_sync(&wrap_timer->timer)) ++ WARNING("Buggy Windows driver left timer %p " ++ "running", wrap_timer->nt_timer); ++ memset(wrap_timer, 0, sizeof(*wrap_timer)); ++ kfree(wrap_timer); ++ } ++ EXIT1(return); ++} ++ ++static NDIS_STATUS mp_set_power_state(struct ndis_device *wnd, ++ enum ndis_power_state state) ++{ ++ NDIS_STATUS status; ++ ++ TRACE1("%d", state); ++ if (state == NdisDeviceStateD0) { ++ status = NDIS_STATUS_SUCCESS; ++ mutex_unlock(&wnd->ndis_req_mutex); ++ if (test_and_clear_bit(HW_HALTED, &wnd->wd->hw_status)) { ++ status = mp_init(wnd); ++ if (status == NDIS_STATUS_SUCCESS) { ++ set_packet_filter(wnd, wnd->packet_filter); ++ set_multicast_list(wnd); ++ } ++ } else if (test_and_clear_bit(HW_SUSPENDED, ++ &wnd->wd->hw_status)) { ++ status = mp_set_int(wnd, OID_PNP_SET_POWER, state); ++ if (status != NDIS_STATUS_SUCCESS) ++ WARNING("%s: setting power to state %d failed? " ++ "%08X", wnd->net_dev->name, state, ++ status); ++ } else ++ return NDIS_STATUS_FAILURE; ++ ++ if (wrap_is_pci_bus(wnd->wd->dev_bus)) { ++ pci_enable_wake(wnd->wd->pci.pdev, PCI_D3hot, 0); ++ pci_enable_wake(wnd->wd->pci.pdev, PCI_D3cold, 0); ++ } ++ if (status == NDIS_STATUS_SUCCESS) { ++ mutex_unlock(&wnd->tx_ring_mutex); ++ netif_device_attach(wnd->net_dev); ++ hangcheck_add(wnd); ++ add_iw_stats_timer(wnd); ++ } else ++ WARNING("%s: couldn't set power to state %d; device not" ++ " resumed", wnd->net_dev->name, state); ++ EXIT1(return status); ++ } else { ++ mutex_lock(&wnd->tx_ring_mutex); ++ netif_device_detach(wnd->net_dev); ++ hangcheck_del(wnd); ++ del_iw_stats_timer(wnd); ++ status = NDIS_STATUS_NOT_SUPPORTED; ++ if (wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND) { ++ status = mp_set_int(wnd, OID_PNP_ENABLE_WAKE_UP, ++ wnd->ndis_wolopts); ++ TRACE2("0x%x, 0x%x", status, wnd->ndis_wolopts); ++ if (status == NDIS_STATUS_SUCCESS && ++ wrap_is_pci_bus(wnd->wd->dev_bus)) { ++ if (wnd->ndis_wolopts) ++ wnd->wd->pci.wake_state = ++ PowerDeviceD3; ++ else ++ wnd->wd->pci.wake_state = ++ PowerDeviceUnspecified; ++ } else ++ WARNING("couldn't set wake-on-lan options: " ++ "0x%x, %08X", wnd->ndis_wolopts, status); ++ status = mp_set_int(wnd, OID_PNP_SET_POWER, state); ++ if (status == NDIS_STATUS_SUCCESS) ++ set_bit(HW_SUSPENDED, &wnd->wd->hw_status); ++ else ++ WARNING("suspend failed: %08X", status); ++ } ++ if (status != NDIS_STATUS_SUCCESS) { ++ WARNING("%s does not support power management; " ++ "halting the device", wnd->net_dev->name); ++ mp_halt(wnd); ++ set_bit(HW_HALTED, &wnd->wd->hw_status); ++ status = STATUS_SUCCESS; ++ } ++ mutex_lock(&wnd->ndis_req_mutex); ++ EXIT1(return status); ++ } ++} ++ ++static int ndis_set_mac_address(struct net_device *dev, void *p) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ struct sockaddr *addr = p; ++ struct ndis_configuration_parameter param; ++ struct unicode_string key; ++ struct ansi_string ansi; ++ NDIS_STATUS res; ++ unsigned char mac_string[2 * ETH_ALEN + 1]; ++ mac_address mac; ++ ++ memcpy(mac, addr->sa_data, sizeof(mac)); ++ memset(mac_string, 0, sizeof(mac_string)); ++ res = snprintf(mac_string, sizeof(mac_string), MACSTR, MAC2STR(mac)); ++ if (res != (sizeof(mac_string) - 1)) ++ EXIT1(return -EINVAL); ++ TRACE1("new mac: %s", mac_string); ++ ++ RtlInitAnsiString(&ansi, mac_string); ++ if (RtlAnsiStringToUnicodeString(¶m.data.string, &ansi, ++ TRUE) != STATUS_SUCCESS) ++ EXIT1(return -EINVAL); ++ ++ param.type = NdisParameterString; ++ RtlInitAnsiString(&ansi, "NetworkAddress"); ++ if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS) { ++ RtlFreeUnicodeString(¶m.data.string); ++ EXIT1(return -EINVAL); ++ } ++ NdisWriteConfiguration(&res, wnd->nmb, &key, ¶m); ++ RtlFreeUnicodeString(&key); ++ RtlFreeUnicodeString(¶m.data.string); ++ ++ if (res != NDIS_STATUS_SUCCESS) ++ EXIT1(return -EFAULT); ++ if (ndis_reinit(wnd) == NDIS_STATUS_SUCCESS) { ++ res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, ++ mac, sizeof(mac)); ++ if (res == NDIS_STATUS_SUCCESS) { ++ TRACE1("mac:" MACSTRSEP, MAC2STR(mac)); ++ memcpy(dev->dev_addr, mac, sizeof(mac)); ++ } else ++ ERROR("couldn't get mac address: %08X", res); ++ } ++ EXIT1(return 0); ++} ++ ++static int setup_tx_sg_list(struct ndis_device *wnd, struct sk_buff *skb, ++ struct ndis_packet_oob_data *oob_data) ++{ ++ struct ndis_sg_element *sg_element; ++ struct ndis_sg_list *sg_list; ++ int i; ++ ++ ENTER3("%p, %d", skb, skb_shinfo(skb)->nr_frags); ++ if (skb_shinfo(skb)->nr_frags <= 1) { ++ sg_element = &oob_data->wrap_tx_sg_list.elements[0]; ++ sg_element->address = ++ PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, skb->data, ++ skb->len, PCI_DMA_TODEVICE); ++ sg_element->length = skb->len; ++ oob_data->wrap_tx_sg_list.nent = 1; ++ oob_data->ext.info[ScatterGatherListPacketInfo] = ++ &oob_data->wrap_tx_sg_list; ++ TRACE3("%llx, %u", sg_element->address, sg_element->length); ++ return 0; ++ } ++ sg_list = kmalloc(sizeof(*sg_list) + ++ (skb_shinfo(skb)->nr_frags + 1) * sizeof(*sg_element), ++ GFP_ATOMIC); ++ if (!sg_list) ++ return -ENOMEM; ++ sg_list->nent = skb_shinfo(skb)->nr_frags + 1; ++ TRACE3("%p, %d", sg_list, sg_list->nent); ++ sg_element = sg_list->elements; ++ sg_element->length = skb_headlen(skb); ++ sg_element->address = ++ PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, skb->data, ++ skb_headlen(skb), PCI_DMA_TODEVICE); ++ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { ++ skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; ++ sg_element++; ++ sg_element->length = frag->size; ++ sg_element->address = ++ pci_map_page(wnd->wd->pci.pdev, skb_frag_page(frag), ++ frag->page_offset, frag->size, ++ PCI_DMA_TODEVICE); ++ TRACE3("%llx, %u", sg_element->address, sg_element->length); ++ } ++ oob_data->ext.info[ScatterGatherListPacketInfo] = sg_list; ++ return 0; ++} ++ ++static void free_tx_sg_list(struct ndis_device *wnd, ++ struct ndis_packet_oob_data *oob_data) ++{ ++ int i; ++ struct ndis_sg_element *sg_element; ++ struct ndis_sg_list *sg_list = ++ oob_data->ext.info[ScatterGatherListPacketInfo]; ++ sg_element = sg_list->elements; ++ TRACE3("%p, %d", sg_list, sg_list->nent); ++ PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, sg_element->address, ++ sg_element->length, PCI_DMA_TODEVICE); ++ if (sg_list->nent == 1) ++ EXIT3(return); ++ for (i = 1; i < sg_list->nent; i++, sg_element++) { ++ TRACE3("%llx, %u", sg_element->address, sg_element->length); ++ pci_unmap_page(wnd->wd->pci.pdev, sg_element->address, ++ sg_element->length, PCI_DMA_TODEVICE); ++ } ++ TRACE3("%p", sg_list); ++ kfree(sg_list); ++} ++ ++static struct ndis_packet *alloc_tx_packet(struct ndis_device *wnd, ++ struct sk_buff *skb) ++{ ++ struct ndis_packet *packet; ++ ndis_buffer *buffer; ++ struct ndis_packet_oob_data *oob_data; ++ NDIS_STATUS status; ++ ++ NdisAllocatePacket(&status, &packet, wnd->tx_packet_pool); ++ if (status != NDIS_STATUS_SUCCESS) ++ return NULL; ++ NdisAllocateBuffer(&status, &buffer, wnd->tx_buffer_pool, ++ skb->data, skb->len); ++ if (status != NDIS_STATUS_SUCCESS) { ++ NdisFreePacket(packet); ++ return NULL; ++ } ++ packet->private.buffer_head = buffer; ++ packet->private.buffer_tail = buffer; ++ ++ oob_data = NDIS_PACKET_OOB_DATA(packet); ++ oob_data->tx_skb = skb; ++ if (wnd->sg_dma_size) { ++ if (setup_tx_sg_list(wnd, skb, oob_data)) { ++ NdisFreeBuffer(buffer); ++ NdisFreePacket(packet); ++ return NULL; ++ } ++ } ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ struct ndis_tcp_ip_checksum_packet_info csum; ++ int protocol; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21) ++ protocol = ntohs(skb->protocol); ++#else ++ protocol = skb->nh.iph->protocol; ++#endif ++ csum.value = 0; ++ csum.tx.v4 = 1; ++ if (protocol == IPPROTO_TCP) ++ csum.tx.tcp = 1; ++ else if (protocol == IPPROTO_UDP) ++ csum.tx.udp = 1; ++// csum->tx.ip = 1; ++ packet->private.flags |= NDIS_PROTOCOL_ID_TCP_IP; ++ oob_data->ext.info[TcpIpChecksumPacketInfo] = ++ (void *)(ULONG_PTR)csum.value; ++ } ++ DBG_BLOCK(4) { ++ dump_bytes(__func__, skb->data, skb->len); ++ } ++ TRACE4("%p, %p, %p", packet, buffer, skb); ++ return packet; ++} ++ ++void free_tx_packet(struct ndis_device *wnd, struct ndis_packet *packet, ++ NDIS_STATUS status) ++{ ++ ndis_buffer *buffer; ++ struct ndis_packet_oob_data *oob_data; ++ struct sk_buff *skb; ++ struct ndis_packet_pool *pool; ++ ++ assert_irql(_irql_ <= DISPATCH_LEVEL); ++ assert(packet->private.packet_flags); ++ oob_data = NDIS_PACKET_OOB_DATA(packet); ++ skb = oob_data->tx_skb; ++ buffer = packet->private.buffer_head; ++ TRACE4("%p, %p, %p, %08X", packet, buffer, skb, status); ++ if (status == NDIS_STATUS_SUCCESS) { ++ pre_atomic_add(wnd->net_stats.tx_bytes, packet->private.len); ++ atomic_inc_var(wnd->net_stats.tx_packets); ++ } else { ++ TRACE1("packet dropped: %08X", status); ++ atomic_inc_var(wnd->net_stats.tx_dropped); ++ } ++ if (wnd->sg_dma_size) ++ free_tx_sg_list(wnd, oob_data); ++ NdisFreeBuffer(buffer); ++ dev_kfree_skb_any(skb); ++ pool = packet->private.pool; ++ NdisFreePacket(packet); ++ if (netif_queue_stopped(wnd->net_dev) && ++ ((pool->max_descr - pool->num_used_descr) >= ++ (wnd->max_tx_packets / 4))) { ++ set_bit(NETIF_WAKEQ, &wnd->ndis_pending_work); ++ queue_work(wrapndis_wq, &wnd->ndis_work); ++ } ++ EXIT4(return); ++} ++ ++/* MiniportSend and MiniportSendPackets */ ++/* this function is called holding tx_ring_mutex. start and n are such ++ * that start + n < TX_RING_SIZE; i.e., packets don't wrap around ++ * ring */ ++static u8 mp_tx_packets(struct ndis_device *wnd, u8 start, u8 n) ++{ ++ NDIS_STATUS res; ++ struct miniport *mp; ++ struct ndis_packet *packet; ++ u8 sent; ++ KIRQL irql; ++ ++ ENTER3("%d, %d", start, n); ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ if (mp->send_packets) { ++ if (deserialized_driver(wnd)) { ++ LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, ++ &wnd->tx_ring[start], n); ++ sent = n; ++ } else { ++ irql = serialize_lock_irql(wnd); ++ LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, ++ &wnd->tx_ring[start], n); ++ serialize_unlock_irql(wnd, irql); ++ for (sent = 0; sent < n && wnd->tx_ok; sent++) { ++ struct ndis_packet_oob_data *oob_data; ++ packet = wnd->tx_ring[start + sent]; ++ oob_data = NDIS_PACKET_OOB_DATA(packet); ++ switch ((res = ++ xchg(&oob_data->status, ++ NDIS_STATUS_NOT_RECOGNIZED))) { ++ case NDIS_STATUS_SUCCESS: ++ free_tx_packet(wnd, packet, ++ NDIS_STATUS_SUCCESS); ++ break; ++ case NDIS_STATUS_PENDING: ++ break; ++ case NDIS_STATUS_RESOURCES: ++ wnd->tx_ok = 0; ++ /* resubmit this packet and ++ * the rest when resources ++ * become available */ ++ sent--; ++ break; ++ case NDIS_STATUS_FAILURE: ++ free_tx_packet(wnd, packet, ++ NDIS_STATUS_FAILURE); ++ break; ++ default: ++ ERROR("%p: invalid status: %08X", ++ packet, res); ++ free_tx_packet(wnd, packet, ++ oob_data->status); ++ break; ++ } ++ TRACE3("%p, %d", packet, res); ++ } ++ } ++ TRACE3("sent: %d(%d)", sent, n); ++ } else { ++ for (sent = 0; sent < n && wnd->tx_ok; sent++) { ++ struct ndis_packet_oob_data *oob_data; ++ packet = wnd->tx_ring[start + sent]; ++ oob_data = NDIS_PACKET_OOB_DATA(packet); ++ oob_data->status = NDIS_STATUS_NOT_RECOGNIZED; ++ irql = serialize_lock_irql(wnd); ++ res = LIN2WIN3(mp->send, wnd->nmb->mp_ctx, ++ packet, packet->private.flags); ++ serialize_unlock_irql(wnd, irql); ++ switch (res) { ++ case NDIS_STATUS_SUCCESS: ++ free_tx_packet(wnd, packet, res); ++ break; ++ case NDIS_STATUS_PENDING: ++ break; ++ case NDIS_STATUS_RESOURCES: ++ wnd->tx_ok = 0; ++ /* resend this packet when resources ++ * become available */ ++ sent--; ++ break; ++ case NDIS_STATUS_FAILURE: ++ free_tx_packet(wnd, packet, res); ++ break; ++ default: ++ ERROR("packet %p: invalid status: %08X", ++ packet, res); ++ break; ++ } ++ } ++ } ++ EXIT3(return sent); ++} ++ ++static void tx_worker(struct work_struct *work) ++{ ++ struct ndis_device *wnd; ++ s8 n; ++ ++ wnd = container_of(work, struct ndis_device, tx_work); ++ ENTER3("tx_ok %d", wnd->tx_ok); ++ while (wnd->tx_ok) { ++ mutex_lock(&wnd->tx_ring_mutex); ++ spin_lock_bh(&wnd->tx_ring_lock); ++ n = wnd->tx_ring_end - wnd->tx_ring_start; ++ TRACE3("%d, %d, %d", wnd->tx_ring_start, wnd->tx_ring_end, n); ++ /* end == start if either ring is empty or full; in ++ * the latter case is_tx_ring_full is set */ ++ if (n == 0) { ++ if (wnd->is_tx_ring_full) ++ n = TX_RING_SIZE - wnd->tx_ring_start; ++ else { ++ spin_unlock_bh(&wnd->tx_ring_lock); ++ mutex_unlock(&wnd->tx_ring_mutex); ++ break; ++ } ++ } else if (n < 0) ++ n = TX_RING_SIZE - wnd->tx_ring_start; ++ spin_unlock_bh(&wnd->tx_ring_lock); ++ if (unlikely(n > wnd->max_tx_packets)) ++ n = wnd->max_tx_packets; ++ n = mp_tx_packets(wnd, wnd->tx_ring_start, n); ++ if (n) { ++ wnd->net_dev->trans_start = jiffies; ++ wnd->tx_ring_start = ++ (wnd->tx_ring_start + n) % TX_RING_SIZE; ++ wnd->is_tx_ring_full = 0; ++ } ++ mutex_unlock(&wnd->tx_ring_mutex); ++ TRACE3("%d, %d, %d", wnd->tx_ring_start, wnd->tx_ring_end, n); ++ } ++ EXIT3(return); ++} ++ ++static int tx_skbuff(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ struct ndis_packet *packet; ++ ++ packet = alloc_tx_packet(wnd, skb); ++ if (!packet) { ++ TRACE2("couldn't allocate packet"); ++ netif_tx_lock(dev); ++ netif_stop_queue(dev); ++ netif_tx_unlock(dev); ++ return NETDEV_TX_BUSY; ++ } ++ spin_lock(&wnd->tx_ring_lock); ++ wnd->tx_ring[wnd->tx_ring_end++] = packet; ++ if (wnd->tx_ring_end == TX_RING_SIZE) ++ wnd->tx_ring_end = 0; ++ if (wnd->tx_ring_end == wnd->tx_ring_start) { ++ netif_tx_lock(dev); ++ wnd->is_tx_ring_full = 1; ++ netif_stop_queue(dev); ++ netif_tx_unlock(dev); ++ } ++ spin_unlock(&wnd->tx_ring_lock); ++ TRACE4("ring: %d, %d", wnd->tx_ring_start, wnd->tx_ring_end); ++ queue_work(wrapndis_wq, &wnd->tx_work); ++ return NETDEV_TX_OK; ++} ++ ++static int set_packet_filter(struct ndis_device *wnd, ULONG packet_filter) ++{ ++ NDIS_STATUS res; ++ ++ while (1) { ++ res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, ++ packet_filter); ++ if (res == NDIS_STATUS_SUCCESS) ++ break; ++ TRACE2("couldn't set filter 0x%08x", packet_filter); ++ /* NDIS_PACKET_TYPE_PROMISCUOUS may not work with 802.11 */ ++ if (packet_filter & NDIS_PACKET_TYPE_PROMISCUOUS) { ++ packet_filter &= ~NDIS_PACKET_TYPE_PROMISCUOUS; ++ continue; ++ } ++ if (packet_filter & NDIS_PACKET_TYPE_ALL_LOCAL) { ++ packet_filter &= ~NDIS_PACKET_TYPE_ALL_LOCAL; ++ continue; ++ } ++ if (packet_filter & NDIS_PACKET_TYPE_ALL_FUNCTIONAL) { ++ packet_filter &= ~NDIS_PACKET_TYPE_ALL_FUNCTIONAL; ++ continue; ++ } ++ if (packet_filter & NDIS_PACKET_TYPE_MULTICAST) { ++ packet_filter &= ~NDIS_PACKET_TYPE_MULTICAST; ++ packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; ++ continue; ++ } ++ if (packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST) { ++ packet_filter &= ~NDIS_PACKET_TYPE_ALL_MULTICAST; ++ continue; ++ } ++ break; ++ } ++ ++ wnd->packet_filter = packet_filter; ++ res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter); ++ if (packet_filter != wnd->packet_filter) { ++ WARNING("filter not set: 0x%08x, 0x%08x", ++ packet_filter, wnd->packet_filter); ++ wnd->packet_filter = packet_filter; ++ } ++ if (wnd->packet_filter) ++ EXIT3(return 0); ++ else ++ EXIT3(return -1); ++} ++ ++void set_media_state(struct ndis_device *wnd, enum ndis_media_state state) ++{ ++ struct net_device *net_dev = wnd->net_dev; ++ ++ ENTER2("state: 0x%x, carrier %d", state, netif_carrier_ok(net_dev)); ++ switch (state) { ++ case NdisMediaStateConnected: ++ if (netif_carrier_ok(net_dev)) ++ return; ++ netif_carrier_on(net_dev); ++ wnd->tx_ok = 1; ++ if (netif_queue_stopped(net_dev)) ++ netif_wake_queue(net_dev); ++ if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { ++ set_bit(LINK_STATUS_ON, &wnd->ndis_pending_work); ++ queue_work(wrapndis_wq, &wnd->ndis_work); ++ } ++ break; ++ case NdisMediaStateDisconnected: ++ if (!netif_carrier_ok(net_dev)) ++ return; ++ netif_carrier_off(net_dev); ++ netif_stop_queue(net_dev); ++ wnd->tx_ok = 0; ++ if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { ++ memset(&wnd->essid, 0, sizeof(wnd->essid)); ++ set_bit(LINK_STATUS_OFF, &wnd->ndis_pending_work); ++ queue_work(wrapndis_wq, &wnd->ndis_work); ++ } ++ break; ++ default: ++ WARNING("invalid media state: 0x%x", state); ++ break; ++ } ++} ++ ++static int ndis_net_dev_init(struct net_device *net_dev) ++{ ++ struct ndis_device *wnd = netdev_priv(net_dev); ++ ++ ENTER1("%p", wnd); ++ wrap_procfs_add_ndis_device(wnd); ++ EXIT1(return 0); ++} ++ ++static void ndis_net_dev_uninit(struct net_device *net_dev) ++{ ++ struct ndis_device *wnd = netdev_priv(net_dev); ++ ++ ENTER1("%p", wnd); ++ wrap_procfs_remove_ndis_device(wnd); ++ EXIT1(return); ++} ++ ++static int ndis_net_dev_open(struct net_device *net_dev) ++{ ++ int status, res; ++ struct ndis_device *wnd = netdev_priv(net_dev); ++ ++ ENTER1("%p", wnd); ++ res = mp_query_int(wnd, OID_GEN_MEDIA_CONNECT_STATUS, &status); ++ if (res == NDIS_STATUS_SUCCESS && status >= NdisMediaStateConnected && ++ status <= NdisMediaStateDisconnected) ++ set_media_state(wnd, status); ++ netif_start_queue(net_dev); ++ netif_poll_enable(net_dev); ++ EXIT1(return 0); ++} ++ ++static int ndis_net_dev_close(struct net_device *net_dev) ++{ ++ ENTER1("%p", netdev_priv(net_dev)); ++ netif_poll_disable(net_dev); ++ netif_tx_disable(net_dev); ++ EXIT1(return 0); ++} ++ ++static int ndis_change_mtu(struct net_device *net_dev, int mtu) ++{ ++ struct ndis_device *wnd = netdev_priv(net_dev); ++ int max; ++ ++ if (mtu < ETH_ZLEN) ++ return -EINVAL; ++ if (mp_query_int(wnd, OID_GEN_MAXIMUM_TOTAL_SIZE, &max) != ++ NDIS_STATUS_SUCCESS) ++ return -EOPNOTSUPP; ++ TRACE1("%d", max); ++ max -= ETH_HLEN; ++ if (max <= ETH_ZLEN) ++ return -EINVAL; ++ if (mtu + ETH_HLEN > max) ++ return -EINVAL; ++ net_dev->mtu = mtu; ++ return 0; ++} ++ ++#ifdef CONFIG_NET_POLL_CONTROLLER ++static void ndis_poll_controller(struct net_device *dev) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ++ disable_irq(dev->irq); ++ ndis_isr(wnd->mp_interrupt->kinterrupt, wnd->mp_interrupt); ++ enable_irq(dev->irq); ++} ++#endif ++ ++/* called from BH context */ ++static struct net_device_stats *ndis_get_stats(struct net_device *dev) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ return &wnd->net_stats; ++} ++ ++/* called from BH context */ ++static void ndis_set_multicast_list(struct net_device *dev) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ set_bit(SET_MULTICAST_LIST, &wnd->ndis_pending_work); ++ queue_work(wrapndis_wq, &wnd->ndis_work); ++} ++ ++/* called from BH context */ ++struct iw_statistics *get_iw_stats(struct net_device *dev) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ return &wnd->iw_stats; ++} ++ ++static void update_iw_stats(struct ndis_device *wnd) ++{ ++ struct iw_statistics *iw_stats = &wnd->iw_stats; ++ struct ndis_wireless_stats ndis_stats; ++ NDIS_STATUS res; ++ ndis_rssi rssi; ++ int qual; ++ ++ ENTER2("%p", wnd); ++ if (wnd->iw_stats_enabled == FALSE || !netif_carrier_ok(wnd->net_dev)) { ++ memset(iw_stats, 0, sizeof(*iw_stats)); ++ EXIT2(return); ++ } ++ res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi)); ++ if (res == NDIS_STATUS_SUCCESS) ++ iw_stats->qual.level = rssi; ++ ++ qual = 100 * (rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE); ++ if (qual < 0) ++ qual = 0; ++ else if (qual > 100) ++ qual = 100; ++ ++ iw_stats->qual.noise = WL_NOISE; ++ iw_stats->qual.qual = qual; ++ ++ res = mp_query(wnd, OID_802_11_STATISTICS, ++ &ndis_stats, sizeof(ndis_stats)); ++ if (res != NDIS_STATUS_SUCCESS) ++ EXIT2(return); ++ iw_stats->discard.retries = (unsigned long)ndis_stats.retry + ++ (unsigned long)ndis_stats.multi_retry; ++ iw_stats->discard.misc = (unsigned long)ndis_stats.fcs_err + ++ (unsigned long)ndis_stats.rtss_fail + ++ (unsigned long)ndis_stats.ack_fail + ++ (unsigned long)ndis_stats.frame_dup; ++ ++ EXIT2(return); ++} ++ ++static void set_multicast_list(struct ndis_device *wnd) ++{ ++ struct net_device *net_dev; ++ ULONG packet_filter; ++ NDIS_STATUS res; ++ ++ net_dev = wnd->net_dev; ++ packet_filter = wnd->packet_filter; ++ ++ TRACE2("0x%08x", packet_filter); ++ if (net_dev->flags & IFF_PROMISC) { ++ packet_filter |= NDIS_PACKET_TYPE_PROMISCUOUS | ++ NDIS_PACKET_TYPE_ALL_LOCAL; ++ } else if (net_dev->flags & IFF_ALLMULTI || ++ netdev_mc_count(net_dev) > wnd->multicast_size) { ++ packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; ++ TRACE2("0x%08x", packet_filter); ++ } else if (netdev_mc_count(net_dev) > 0) { ++ int i, size; ++ char *buf; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ++ struct netdev_hw_addr *ha; ++#else ++ struct dev_mc_list *mclist; ++#endif ++ size = min(wnd->multicast_size, netdev_mc_count(net_dev)); ++ TRACE2("%d, %d", wnd->multicast_size, netdev_mc_count(net_dev)); ++ buf = kmalloc(size * ETH_ALEN, GFP_KERNEL); ++ if (!buf) { ++ WARNING("couldn't allocate memory"); ++ EXIT2(return); ++ } ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ++ i = 0; ++ netdev_for_each_mc_addr(ha, net_dev) { ++ if (i >= size) ++ break; ++ memcpy(buf + i * ETH_ALEN, ha->addr, ETH_ALEN); ++ TRACE2(MACSTRSEP, MAC2STR(ha->addr)); ++ i++; ++ } ++#else ++ mclist = net_dev->mc_list; ++ for (i = 0; i < size && mclist; mclist = mclist->next) { ++ if (mclist->dmi_addrlen != ETH_ALEN) ++ continue; ++ memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); ++ TRACE2(MACSTRSEP, MAC2STR(mclist->dmi_addr)); ++ i++; ++ } ++#endif ++ res = mp_set(wnd, OID_802_3_MULTICAST_LIST, buf, i * ETH_ALEN); ++ if (res == NDIS_STATUS_SUCCESS && i > 0) ++ packet_filter |= NDIS_PACKET_TYPE_MULTICAST; ++ else ++ packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; ++ kfree(buf); ++ } ++ TRACE2("0x%08x", packet_filter); ++ res = set_packet_filter(wnd, packet_filter); ++ if (res) ++ TRACE1("couldn't set packet filter (%08X)", res); ++ EXIT2(return); ++} ++ ++static void link_status_off(struct ndis_device *wnd) ++{ ++#ifdef CONFIG_WIRELESS_EXT ++ union iwreq_data wrqu; ++ ++ memset(&wrqu, 0, sizeof(wrqu)); ++ wrqu.ap_addr.sa_family = ARPHRD_ETHER; ++ wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL); ++#endif ++ EXIT2(return); ++} ++ ++static void link_status_on(struct ndis_device *wnd) ++{ ++#ifdef CONFIG_WIRELESS_EXT ++ struct ndis_assoc_info *ndis_assoc_info; ++ union iwreq_data wrqu; ++ NDIS_STATUS res; ++ const int assoc_size = sizeof(*ndis_assoc_info) + IW_CUSTOM_MAX + 32; ++#endif ++ ++ ENTER2(""); ++#ifdef CONFIG_WIRELESS_EXT ++ memset(&wrqu, 0, sizeof(wrqu)); ++ ndis_assoc_info = kzalloc(assoc_size, GFP_KERNEL); ++ if (!ndis_assoc_info) { ++ ERROR("couldn't allocate memory"); ++ goto send_assoc_event; ++ } ++ res = mp_query(wnd, OID_802_11_ASSOCIATION_INFORMATION, ++ ndis_assoc_info, assoc_size); ++ if (res) { ++ TRACE2("query assoc_info failed (%08X)", res); ++ kfree(ndis_assoc_info); ++ goto send_assoc_event; ++ } ++ TRACE2("%u, 0x%x, %u, 0x%x, %u", ndis_assoc_info->length, ++ ndis_assoc_info->req_ies, ndis_assoc_info->req_ie_length, ++ ndis_assoc_info->resp_ies, ndis_assoc_info->resp_ie_length); ++ if (ndis_assoc_info->req_ie_length > 0) { ++ wrqu.data.length = ndis_assoc_info->req_ie_length; ++ wireless_send_event(wnd->net_dev, IWEVASSOCREQIE, &wrqu, ++ ((char *)ndis_assoc_info) + ++ ndis_assoc_info->offset_req_ies); ++ } ++ if (ndis_assoc_info->resp_ie_length > 0) { ++ wrqu.data.length = ndis_assoc_info->resp_ie_length; ++ wireless_send_event(wnd->net_dev, IWEVASSOCRESPIE, &wrqu, ++ ((char *)ndis_assoc_info) + ++ ndis_assoc_info->offset_resp_ies); ++ } ++ kfree(ndis_assoc_info); ++ ++send_assoc_event: ++ get_ap_address(wnd, wrqu.ap_addr.sa_data); ++ wrqu.ap_addr.sa_family = ARPHRD_ETHER; ++ TRACE2(MACSTRSEP, MAC2STR(wrqu.ap_addr.sa_data)); ++ wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL); ++#endif ++ EXIT2(return); ++} ++ ++static void iw_stats_timer_proc(unsigned long data) ++{ ++ struct ndis_device *wnd = (struct ndis_device *)data; ++ ++ ENTER2("%d", wnd->iw_stats_interval); ++ if (wnd->iw_stats_interval > 0) { ++ set_bit(COLLECT_IW_STATS, &wnd->ndis_pending_work); ++ queue_work(wrapndis_wq, &wnd->ndis_work); ++ } ++ mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval); ++} ++ ++static void add_iw_stats_timer(struct ndis_device *wnd) ++{ ++ if (wnd->physical_medium != NdisPhysicalMediumWirelessLan) ++ return; ++ if (wnd->iw_stats_interval < 0) ++ wnd->iw_stats_interval *= -1; ++ wnd->iw_stats_timer.data = (unsigned long)wnd; ++ wnd->iw_stats_timer.function = iw_stats_timer_proc; ++ mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval); ++} ++ ++static void del_iw_stats_timer(struct ndis_device *wnd) ++{ ++ ENTER2("%d", wnd->iw_stats_interval); ++ wnd->iw_stats_interval *= -1; ++ del_timer_sync(&wnd->iw_stats_timer); ++ EXIT2(return); ++} ++ ++static void hangcheck_proc(unsigned long data) ++{ ++ struct ndis_device *wnd = (struct ndis_device *)data; ++ ++ ENTER3("%d", wnd->hangcheck_interval); ++ if (wnd->hangcheck_interval > 0) { ++ set_bit(HANGCHECK, &wnd->ndis_pending_work); ++ queue_work(wrapndis_wq, &wnd->ndis_work); ++ } ++ mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval); ++ EXIT3(return); ++} ++ ++void hangcheck_add(struct ndis_device *wnd) ++{ ++ if (!wnd->wd->driver->ndis_driver->mp.hangcheck || ++ hangcheck_interval < 0) ++ EXIT2(return); ++ ++ if (hangcheck_interval > 0) ++ wnd->hangcheck_interval = hangcheck_interval * HZ; ++ if (wnd->hangcheck_interval < 0) ++ wnd->hangcheck_interval *= -1; ++ wnd->hangcheck_timer.data = (unsigned long)wnd; ++ wnd->hangcheck_timer.function = hangcheck_proc; ++ mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval); ++ EXIT2(return); ++} ++ ++void hangcheck_del(struct ndis_device *wnd) ++{ ++ ENTER2("%d", wnd->hangcheck_interval); ++ if (wnd->hangcheck_interval > 0) ++ wnd->hangcheck_interval *= -1; ++ del_timer_sync(&wnd->hangcheck_timer); ++ EXIT2(return); ++} ++ ++/* worker procedure to take care of setting/checking various states */ ++static void wrapndis_worker(struct work_struct *work) ++{ ++ struct ndis_device *wnd; ++ ++ wnd = container_of(work, struct ndis_device, ndis_work); ++ WORKTRACE("0x%lx", wnd->ndis_pending_work); ++ ++ if (test_and_clear_bit(NETIF_WAKEQ, &wnd->ndis_pending_work)) { ++ netif_tx_lock_bh(wnd->net_dev); ++ netif_wake_queue(wnd->net_dev); ++ netif_tx_unlock_bh(wnd->net_dev); ++ } ++ ++ if (test_and_clear_bit(LINK_STATUS_OFF, &wnd->ndis_pending_work)) ++ link_status_off(wnd); ++ ++ if (test_and_clear_bit(LINK_STATUS_ON, &wnd->ndis_pending_work)) ++ link_status_on(wnd); ++ ++ if (test_and_clear_bit(COLLECT_IW_STATS, &wnd->ndis_pending_work)) ++ update_iw_stats(wnd); ++ ++ if (test_and_clear_bit(SET_MULTICAST_LIST, ++ &wnd->ndis_pending_work)) ++ set_multicast_list(wnd); ++ ++ if (test_and_clear_bit(HANGCHECK, &wnd->ndis_pending_work)) { ++ struct miniport *mp; ++ BOOLEAN reset; ++ KIRQL irql; ++ ++ mp = &wnd->wd->driver->ndis_driver->mp; ++ irql = serialize_lock_irql(wnd); ++ reset = LIN2WIN1(mp->hangcheck, wnd->nmb->mp_ctx); ++ serialize_unlock_irql(wnd, irql); ++ if (reset) { ++ TRACE2("%s needs reset", wnd->net_dev->name); ++ mp_reset(wnd); ++ } ++ } ++ WORKEXIT(return); ++} ++ ++NDIS_STATUS ndis_reinit(struct ndis_device *wnd) ++{ ++ NDIS_STATUS status; ++ ++ wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; ++ status = mp_set_power_state(wnd, NdisDeviceStateD3); ++ if (status != NDIS_STATUS_SUCCESS) { ++ ERROR("halting device %s failed: %08X", wnd->net_dev->name, ++ status); ++ return status; ++ } ++ status = mp_set_power_state(wnd, NdisDeviceStateD0); ++ if (status != NDIS_STATUS_SUCCESS) ++ ERROR("starting device %s failed: %08X", wnd->net_dev->name, ++ status); ++ return status; ++} ++ ++#ifdef CONFIG_WIRELESS_EXT ++static void get_encryption_capa(struct ndis_device *wnd, char *buf, ++ const int buf_len) ++{ ++ int i, mode; ++ NDIS_STATUS res; ++ struct ndis_assoc_info ndis_assoc_info; ++ struct ndis_add_key ndis_key; ++ struct ndis_capability *c; ++ ++ ENTER1("%p", wnd); ++ /* set network type to g, b, or a, in that order */ ++ res = mp_query(wnd, OID_802_11_NETWORK_TYPES_SUPPORTED, buf, buf_len); ++ if (res == NDIS_STATUS_SUCCESS) { ++ struct network_type_list *net_types; ++ unsigned long types = 0; ++ net_types = (typeof(net_types))buf; ++ for (i = 0; i < net_types->num; i++) { ++ TRACE2("%d", net_types->types[i]); ++ set_bit(net_types->types[i], &types); ++ } ++ if (test_bit(Ndis802_11OFDM24, &types)) ++ mode = Ndis802_11OFDM24; ++ else if (test_bit(Ndis802_11DS, &types)) ++ mode = Ndis802_11DS; ++ else if (test_bit(Ndis802_11OFDM5, &types)) ++ mode = Ndis802_11OFDM5; ++ else ++ mode = Ndis802_11DS; ++ mp_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, mode); ++ } ++ /* check if WEP is supported */ ++ if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104, ++ IW_AUTH_CIPHER_NONE) == 0 && ++ get_ndis_encr_mode(wnd) == Ndis802_11Encryption1KeyAbsent) ++ set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr); ++ ++ /* check if WPA is supported */ ++ if (set_ndis_auth_mode(wnd, Ndis802_11AuthModeWPA) == 0 && ++ get_ndis_auth_mode(wnd) == Ndis802_11AuthModeWPA) ++ set_bit(Ndis802_11AuthModeWPA, &wnd->capa.encr); ++ else ++ EXIT1(return); ++ ++ if (set_ndis_auth_mode(wnd, Ndis802_11AuthModeWPAPSK) == 0 && ++ get_ndis_auth_mode(wnd) == Ndis802_11AuthModeWPAPSK) ++ set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.encr); ++ ++ /* check for highest encryption */ ++ mode = 0; ++ if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_CCMP, ++ IW_AUTH_CIPHER_NONE) == 0 && ++ (i = get_ndis_encr_mode(wnd)) > 0 && ++ (i == Ndis802_11Encryption3KeyAbsent || ++ i == Ndis802_11Encryption3Enabled)) ++ mode = Ndis802_11Encryption3Enabled; ++ else if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_TKIP, ++ IW_AUTH_CIPHER_NONE) == 0 && ++ (i = get_ndis_encr_mode(wnd)) > 0 && ++ (i == Ndis802_11Encryption2KeyAbsent || ++ i == Ndis802_11Encryption2Enabled)) ++ mode = Ndis802_11Encryption2Enabled; ++ else if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104, ++ IW_AUTH_CIPHER_NONE) == 0 && ++ (i = get_ndis_encr_mode(wnd)) > 0 && ++ (i == Ndis802_11Encryption1KeyAbsent || ++ i == Ndis802_11Encryption1Enabled)) ++ mode = Ndis802_11Encryption1Enabled; ++ ++ TRACE1("mode: %d", mode); ++ if (mode == 0) ++ EXIT1(return); ++ set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr); ++ if (mode == Ndis802_11Encryption1Enabled) ++ EXIT1(return); ++ ++ ndis_key.length = 32; ++ ndis_key.index = 0xC0000001; ++ ndis_key.struct_size = sizeof(ndis_key); ++ res = mp_set(wnd, OID_802_11_ADD_KEY, &ndis_key, ndis_key.struct_size); ++ TRACE2("%08X, %zu", res, sizeof(ndis_key)); ++ if (res && res != NDIS_STATUS_INVALID_DATA) ++ EXIT1(return); ++ res = mp_query(wnd, OID_802_11_ASSOCIATION_INFORMATION, ++ &ndis_assoc_info, sizeof(ndis_assoc_info)); ++ TRACE1("%08X", res); ++ if (res == NDIS_STATUS_NOT_SUPPORTED) ++ EXIT1(return); ++ ++ set_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr); ++ if (mode == Ndis802_11Encryption3Enabled) ++ set_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr); ++ /* not all drivers support OID_802_11_CAPABILITY, so we don't ++ * know for sure if driver support WPA or WPAPSK; assume ++ * WPAPSK */ ++ set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth); ++ wnd->max_pmkids = 1; ++ ++ memset(buf, 0, buf_len); ++ c = (struct ndis_capability *)buf; ++ res = mp_query(wnd, OID_802_11_CAPABILITY, buf, buf_len); ++ if (!(res == NDIS_STATUS_SUCCESS && c->version == 2)) ++ EXIT1(return); ++ wnd->max_pmkids = c->num_PMKIDs; ++ ++ for (i = 0; i < c->num_auth_encr_pair; i++) { ++ struct ndis_auth_encr_pair *ae; ++ ++ ae = &c->auth_encr_pair[i]; ++ if ((char *)(ae + 1) > buf + buf_len) ++ break; ++ switch (ae->auth_mode) { ++ case Ndis802_11AuthModeOpen: ++ case Ndis802_11AuthModeShared: ++ case Ndis802_11AuthModeWPA: ++ case Ndis802_11AuthModeWPAPSK: ++ case Ndis802_11AuthModeWPANone: ++ case Ndis802_11AuthModeWPA2: ++ case Ndis802_11AuthModeWPA2PSK: ++ set_bit(ae->auth_mode, &wnd->capa.auth); ++ break; ++ default: ++ WARNING("unknown auth_mode: %d", ae->auth_mode); ++ break; ++ } ++ switch (ae->encr_mode) { ++ case Ndis802_11EncryptionDisabled: ++ case Ndis802_11Encryption1Enabled: ++ case Ndis802_11Encryption2Enabled: ++ case Ndis802_11Encryption3Enabled: ++ set_bit(ae->encr_mode, &wnd->capa.encr); ++ break; ++ default: ++ WARNING("unknown encr_mode: %d", ae->encr_mode); ++ break; ++ } ++ } ++ EXIT1(return); ++} ++#endif ++ ++wstdcall NTSTATUS NdisDispatchDeviceControl(struct device_object *fdo, ++ struct irp *irp) ++{ ++ struct ndis_device *wnd; ++ ++ TRACE3("fdo: %p", fdo); ++ /* for now, we don't have anything interesting here, so pass it ++ * down to bus driver */ ++ wnd = fdo->reserved; ++ return IoPassIrpDown(wnd->nmb->pdo, irp); ++} ++WIN_FUNC_DECL(NdisDispatchDeviceControl,2) ++ ++wstdcall NTSTATUS NdisDispatchPower(struct device_object *fdo, struct irp *irp) ++{ ++ struct io_stack_location *irp_sl; ++ struct ndis_device *wnd; ++ enum ndis_power_state state; ++ NTSTATUS status; ++ NDIS_STATUS ndis_status; ++ ++ irp_sl = IoGetCurrentIrpStackLocation(irp); ++ wnd = fdo->reserved; ++ IOTRACE("fdo: %p, fn: %d:%d, wnd: %p", fdo, irp_sl->major_fn, ++ irp_sl->minor_fn, wnd); ++ if ((irp_sl->params.power.type == SystemPowerState && ++ irp_sl->params.power.state.system_state > PowerSystemWorking) || ++ (irp_sl->params.power.type == DevicePowerState && ++ irp_sl->params.power.state.device_state > PowerDeviceD0)) ++ state = NdisDeviceStateD3; ++ else ++ state = NdisDeviceStateD0; ++ switch (irp_sl->minor_fn) { ++ case IRP_MN_SET_POWER: ++ if (state == NdisDeviceStateD0) { ++ status = IoSyncForwardIrp(wnd->nmb->pdo, irp); ++ if (status != STATUS_SUCCESS) ++ break; ++ ndis_status = mp_set_power_state(wnd, state); ++ if (ndis_status != NDIS_STATUS_SUCCESS) ++ WARNING("couldn't set power to %d: %08X", ++ state, ndis_status); ++ TRACE2("%s: device resumed", wnd->net_dev->name); ++ irp->io_status.status = status = STATUS_SUCCESS; ++ IoCompleteRequest(irp, IO_NO_INCREMENT); ++ break; ++ } else { ++ ndis_status = mp_set_power_state(wnd, state); ++ /* TODO: handle error case */ ++ if (ndis_status != NDIS_STATUS_SUCCESS) ++ WARNING("setting power to %d failed: %08X", ++ state, ndis_status); ++ status = IoAsyncForwardIrp(wnd->nmb->pdo, irp); ++ } ++ break; ++ case IRP_MN_QUERY_POWER: ++ if (wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND) { ++ ndis_status = mp_query(wnd, OID_PNP_QUERY_POWER, ++ &state, sizeof(state)); ++ TRACE2("%d, %08X", state, ndis_status); ++ /* this OID must always succeed */ ++ if (ndis_status != NDIS_STATUS_SUCCESS) ++ TRACE1("query power returns %08X", ndis_status); ++ irp->io_status.status = STATUS_SUCCESS; ++ } else ++ irp->io_status.status = STATUS_SUCCESS; ++ status = IoPassIrpDown(wnd->nmb->pdo, irp); ++ break; ++ case IRP_MN_WAIT_WAKE: ++ case IRP_MN_POWER_SEQUENCE: ++ /* TODO: implement WAIT_WAKE */ ++ status = IoPassIrpDown(wnd->nmb->pdo, irp); ++ break; ++ default: ++ status = IoPassIrpDown(wnd->nmb->pdo, irp); ++ break; ++ } ++ IOEXIT(return status); ++} ++WIN_FUNC_DECL(NdisDispatchPower,2) ++ ++wstdcall NTSTATUS NdisDispatchPnp(struct device_object *fdo, struct irp *irp) ++{ ++ struct io_stack_location *irp_sl; ++ struct ndis_device *wnd; ++ struct device_object *pdo; ++ NTSTATUS status; ++ ++ IOTRACE("fdo: %p, irp: %p", fdo, irp); ++ irp_sl = IoGetCurrentIrpStackLocation(irp); ++ wnd = fdo->reserved; ++ pdo = wnd->nmb->pdo; ++ switch (irp_sl->minor_fn) { ++ case IRP_MN_START_DEVICE: ++ status = IoSyncForwardIrp(pdo, irp); ++ if (status != STATUS_SUCCESS) ++ break; ++ if (ndis_start_device(wnd) == NDIS_STATUS_SUCCESS) ++ status = STATUS_SUCCESS; ++ else ++ status = STATUS_FAILURE; ++ irp->io_status.status = status; ++ IoCompleteRequest(irp, IO_NO_INCREMENT); ++ break; ++ case IRP_MN_QUERY_STOP_DEVICE: ++ /* TODO: implement in NDIS */ ++ status = IoPassIrpDown(wnd->nmb->pdo, irp); ++ break; ++ case IRP_MN_STOP_DEVICE: ++ mp_halt(wnd); ++ irp->io_status.status = STATUS_SUCCESS; ++ status = IoAsyncForwardIrp(pdo, irp); ++ break; ++ case IRP_MN_REMOVE_DEVICE: ++ TRACE1("%s", wnd->net_dev->name); ++ mp_pnp_event(wnd, NdisDevicePnPEventSurpriseRemoved, 0); ++ if (ndis_remove_device(wnd)) { ++ status = STATUS_FAILURE; ++ break; ++ } ++ /* wnd is already freed */ ++ status = IoAsyncForwardIrp(pdo, irp); ++ IoDetachDevice(fdo); ++ IoDeleteDevice(fdo); ++ break; ++ default: ++ status = IoAsyncForwardIrp(pdo, irp); ++ break; ++ } ++ IOTRACE("status: %08X", status); ++ IOEXIT(return status); ++} ++WIN_FUNC_DECL(NdisDispatchPnp,2) ++ ++static void set_task_offload(struct ndis_device *wnd, void *buf, ++ const int buf_size) ++{ ++ struct ndis_task_offload_header *task_offload_header; ++ struct ndis_task_offload *task_offload; ++ struct ndis_task_tcp_ip_checksum *csum = NULL; ++ struct ndis_task_tcp_large_send *tso = NULL; ++ NDIS_STATUS status; ++ ++ memset(buf, 0, buf_size); ++ task_offload_header = buf; ++ task_offload_header->version = NDIS_TASK_OFFLOAD_VERSION; ++ task_offload_header->size = sizeof(*task_offload_header); ++ task_offload_header->encap_format.flags.fixed_header_size = 1; ++ task_offload_header->encap_format.header_size = sizeof(struct ethhdr); ++ task_offload_header->encap_format.encap = IEEE_802_3_Encapsulation; ++ status = mp_query(wnd, OID_TCP_TASK_OFFLOAD, buf, buf_size); ++ TRACE1("%08X", status); ++ if (status != NDIS_STATUS_SUCCESS) ++ EXIT1(return); ++ if (task_offload_header->offset_first_task == 0) ++ EXIT1(return); ++ task_offload = ((void *)task_offload_header + ++ task_offload_header->offset_first_task); ++ while (1) { ++ TRACE1("%d, %d", task_offload->version, task_offload->task); ++ switch (task_offload->task) { ++ case TcpIpChecksumNdisTask: ++ csum = (void *)task_offload->task_buf; ++ break; ++ case TcpLargeSendNdisTask: ++ tso = (void *)task_offload->task_buf; ++ break; ++ default: ++ TRACE1("%d", task_offload->task); ++ break; ++ } ++ if (task_offload->offset_next_task == 0) ++ break; ++ task_offload = (void *)task_offload + ++ task_offload->offset_next_task; ++ } ++ if (tso) ++ TRACE1("%u, %u, %d, %d", tso->max_size, tso->min_seg_count, ++ tso->tcp_opts, tso->ip_opts); ++ if (!csum) ++ EXIT1(return); ++ TRACE1("%08x, %08x", csum->v4_tx.value, csum->v4_rx.value); ++ task_offload_header->encap_format.flags.fixed_header_size = 1; ++ task_offload_header->encap_format.header_size = sizeof(struct ethhdr); ++ task_offload_header->offset_first_task = sizeof(*task_offload_header); ++ task_offload = ((void *)task_offload_header + ++ task_offload_header->offset_first_task); ++ task_offload->offset_next_task = 0; ++ task_offload->size = sizeof(*task_offload); ++ task_offload->task = TcpIpChecksumNdisTask; ++ memcpy(task_offload->task_buf, csum, sizeof(*csum)); ++ task_offload->task_buf_length = sizeof(*csum); ++ status = mp_set(wnd, OID_TCP_TASK_OFFLOAD, task_offload_header, ++ sizeof(*task_offload_header) + ++ sizeof(*task_offload) + sizeof(*csum)); ++ TRACE1("%08X", status); ++ if (status != NDIS_STATUS_SUCCESS) ++ EXIT2(return); ++ wnd->tx_csum = csum->v4_tx; ++ if (csum->v4_tx.tcp_csum && csum->v4_tx.udp_csum) { ++ if (csum->v4_tx.ip_csum) { ++ wnd->net_dev->features |= NETIF_F_HW_CSUM; ++ TRACE1("hw checksum enabled"); ++ } else { ++ wnd->net_dev->features |= NETIF_F_IP_CSUM; ++ TRACE1("IP checksum enabled"); ++ } ++ if (wnd->sg_dma_size) ++ wnd->net_dev->features |= NETIF_F_SG; ++ } ++ wnd->rx_csum = csum->v4_rx; ++ EXIT1(return); ++} ++ ++static void get_supported_oids(struct ndis_device *wnd) ++{ ++ NDIS_STATUS res; ++ int i, n, needed; ++ ndis_oid *oids; ++ ++ res = mp_query_info(wnd, OID_GEN_SUPPORTED_LIST, NULL, 0, NULL, ++ &needed); ++ if (!(res == NDIS_STATUS_BUFFER_TOO_SHORT || ++ res == NDIS_STATUS_INVALID_LENGTH)) ++ EXIT1(return); ++ oids = kmalloc(needed, GFP_KERNEL); ++ if (!oids) { ++ TRACE1("couldn't allocate memory"); ++ EXIT1(return); ++ } ++ res = mp_query(wnd, OID_GEN_SUPPORTED_LIST, oids, needed); ++ if (res) { ++ TRACE1("failed: %08X", res); ++ kfree(oids); ++ EXIT1(return); ++ } ++ for (i = 0, n = needed / sizeof(*oids); i < n; i++) { ++ TRACE1("oid: %08X", oids[i]); ++ /* if a wireless device didn't say so for ++ * OID_GEN_PHYSICAL_MEDIUM (they should, but in case) */ ++ if (wnd->physical_medium != NdisPhysicalMediumWirelessLan && ++ oids[i] == OID_802_11_SSID) ++ wnd->physical_medium = NdisPhysicalMediumWirelessLan; ++ } ++ kfree(oids); ++ EXIT1(return); ++} ++ ++static void ndis_get_drvinfo(struct net_device *dev, ++ struct ethtool_drvinfo *info) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 2); ++ strcat(info->driver, "+"); ++ strncat(info->driver, wnd->wd->driver->name, ++ sizeof(info->driver) - strlen(DRIVER_NAME) - 1); ++ strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 2); ++ strcat(info->version, "+"); ++ strncat(info->version, wnd->wd->driver->version, ++ sizeof(info->version) - strlen(DRIVER_VERSION) - 1); ++ if (wrap_is_pci_bus(wnd->wd->dev_bus)) ++ strncpy(info->bus_info, pci_name(wnd->wd->pci.pdev), ++ sizeof(info->bus_info) - 1); ++#ifdef ENABLE_USB ++ else ++ usb_make_path(wnd->wd->usb.udev, info->bus_info, ++ sizeof(info->bus_info) - 1); ++#endif ++ return; ++} ++ ++static u32 ndis_get_link(struct net_device *dev) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ return netif_carrier_ok(wnd->net_dev); ++} ++ ++static void ndis_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ++ wol->supported = 0; ++ wol->wolopts = 0; ++ if (!(wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND)) ++ EXIT2(return); ++ if (!wrap_is_pci_bus(wnd->wd->dev_bus)) ++ EXIT2(return); ++ /* we always suspend to D3 */ ++ if (wnd->pnp_capa.wakeup.min_magic_packet_wakeup < NdisDeviceStateD3) ++ return; ++ wol->supported |= WAKE_MAGIC; ++ if (wnd->ndis_wolopts & NDIS_PNP_WAKE_UP_MAGIC_PACKET) ++ wol->wolopts |= WAKE_MAGIC; ++ return; ++} ++ ++static int ndis_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ++ if (!(wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND)) ++ return -EOPNOTSUPP; ++ if (wnd->pnp_capa.wakeup.min_magic_packet_wakeup < NdisDeviceStateD3) ++ EXIT2(return -EOPNOTSUPP); ++ TRACE2("0x%x", wol->wolopts); ++ if (wol->wolopts & WAKE_MAGIC) { ++ wnd->ndis_wolopts |= NDIS_PNP_WAKE_UP_MAGIC_PACKET; ++ if (wol->wolopts != WAKE_MAGIC) ++ WARNING("ignored wake-on-lan options: 0x%x", ++ wol->wolopts & ~WAKE_MAGIC); ++ } else if (!wol->wolopts) ++ wnd->ndis_wolopts = 0; ++ else ++ return -EOPNOTSUPP; ++ TRACE2("0x%x", wnd->ndis_wolopts); ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) ++static u32 ndis_get_tx_csum(struct net_device *dev) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ if (wnd->tx_csum.tcp_csum && wnd->tx_csum.udp_csum) ++ return 1; ++ else ++ return 0; ++} ++ ++static u32 ndis_get_rx_csum(struct net_device *dev) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ if (wnd->rx_csum.value) ++ return 1; ++ else ++ return 0; ++} ++ ++static int ndis_set_tx_csum(struct net_device *dev, u32 data) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ++ if (data && (wnd->tx_csum.value == 0)) ++ return -EOPNOTSUPP; ++ ++ if (wnd->tx_csum.ip_csum) ++ ethtool_op_set_tx_hw_csum(dev, data); ++ else ++ ethtool_op_set_tx_csum(dev, data); ++ return 0; ++} ++ ++static int ndis_set_rx_csum(struct net_device *dev, u32 data) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ ++ if (data && (wnd->tx_csum.value == 0)) ++ return -EOPNOTSUPP; ++ ++ /* TODO: enable/disable rx csum through NDIS */ ++ return 0; ++} ++ ++static u32 ndis_get_sg(struct net_device *dev) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ if (wnd->sg_dma_size) ++ return ethtool_op_get_sg(dev); ++ else ++ return 0; ++} ++ ++static int ndis_set_sg(struct net_device *dev, u32 data) ++{ ++ struct ndis_device *wnd = netdev_priv(dev); ++ if (wnd->sg_dma_size) ++ return ethtool_op_set_sg(dev, data); ++ else ++ return -EOPNOTSUPP; ++} ++#endif ++ ++static struct ethtool_ops ndis_ethtool_ops = { ++ .get_drvinfo = ndis_get_drvinfo, ++ .get_link = ndis_get_link, ++ .get_wol = ndis_get_wol, ++ .set_wol = ndis_set_wol, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) ++ .get_tx_csum = ndis_get_tx_csum, ++ .get_rx_csum = ndis_get_rx_csum, ++ .set_tx_csum = ndis_set_tx_csum, ++ .set_rx_csum = ndis_set_rx_csum, ++ .get_sg = ndis_get_sg, ++ .set_sg = ndis_set_sg, ++#endif ++}; ++ ++static int notifier_event(struct notifier_block *notifier, unsigned long event, ++ void *ptr) ++{ ++ struct net_device *net_dev = netdev_notifier_info_to_dev(ptr); ++ ++ ENTER2("0x%lx", event); ++ if (net_dev->ethtool_ops == &ndis_ethtool_ops ++ && event == NETDEV_CHANGENAME) { ++ struct ndis_device *wnd = netdev_priv(net_dev); ++ ++ /* called with rtnl lock held, so no need to lock */ ++ if (likely(wnd->procfs_iface)) { ++ printk(KERN_INFO "%s: interface renamed to '%s'\n", ++ DRIVER_NAME, net_dev->name); ++ wrap_procfs_remove_ndis_device(wnd); ++ wrap_procfs_add_ndis_device(wnd); ++ } ++ } ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block netdev_notifier = { ++ .notifier_call = notifier_event, ++}; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) ++static const struct net_device_ops ndis_netdev_ops = { ++ .ndo_init = ndis_net_dev_init, ++ .ndo_uninit = ndis_net_dev_uninit, ++ .ndo_open = ndis_net_dev_open, ++ .ndo_stop = ndis_net_dev_close, ++ .ndo_start_xmit = tx_skbuff, ++ .ndo_change_mtu = ndis_change_mtu, ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0) ++ .ndo_set_rx_mode = ndis_set_multicast_list, ++#else ++ .ndo_set_multicast_list = ndis_set_multicast_list, ++#endif ++ .ndo_set_mac_address = ndis_set_mac_address, ++ .ndo_get_stats = ndis_get_stats, ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ .ndo_poll_controller = ndis_poll_controller, ++#endif ++}; ++#endif ++ ++static NDIS_STATUS ndis_start_device(struct ndis_device *wnd) ++{ ++ struct wrap_device *wd; ++ struct net_device *net_dev; ++ NDIS_STATUS status; ++ char *buf; ++ const int buf_len = 256; ++ mac_address mac; ++ struct transport_header_offset *tx_header_offset; ++ int n; ++ ++ ENTER2("%d", in_atomic()); ++ status = mp_init(wnd); ++ if (status == NDIS_STATUS_NOT_RECOGNIZED) ++ EXIT1(return NDIS_STATUS_SUCCESS); ++ if (status != NDIS_STATUS_SUCCESS) ++ EXIT1(return status); ++ wd = wnd->wd; ++ net_dev = wnd->net_dev; ++ ++ get_supported_oids(wnd); ++ memset(mac, 0, sizeof(mac)); ++ status = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac)); ++ if (memcmp(mac, "\x00\x00\x00\x00\x00\x00", sizeof(mac)) == 0) { ++ status = mp_query(wnd, OID_802_3_PERMANENT_ADDRESS, mac, ++ sizeof(mac)); ++ if (status != NDIS_STATUS_SUCCESS) { ++ ERROR("couldn't get mac address: %08X", status); ++ goto err_start; ++ } ++ } ++ TRACE1("mac:" MACSTRSEP, MAC2STR(mac)); ++ memcpy(net_dev->dev_addr, mac, ETH_ALEN); ++ ++ strncpy(net_dev->name, if_name, IFNAMSIZ - 1); ++ net_dev->name[IFNAMSIZ - 1] = 0; ++ ++ wnd->packet_filter = NDIS_PACKET_TYPE_DIRECTED | ++ NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_MULTICAST; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) ++ net_dev->netdev_ops = &ndis_netdev_ops; ++#else ++ net_dev->init = ndis_net_dev_init; ++ net_dev->uninit = ndis_net_dev_uninit; ++ net_dev->open = ndis_net_dev_open; ++ net_dev->hard_start_xmit = tx_skbuff; ++ net_dev->stop = ndis_net_dev_close; ++ net_dev->get_stats = ndis_get_stats; ++ net_dev->change_mtu = ndis_change_mtu; ++ net_dev->set_multicast_list = ndis_set_multicast_list; ++ net_dev->set_mac_address = ndis_set_mac_address; ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ net_dev->poll_controller = ndis_poll_controller; ++#endif ++#endif ++#ifdef CONFIG_WIRELESS_EXT ++ if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { ++ net_dev->wireless_handlers = &ndis_handler_def; ++ } ++#endif ++ net_dev->ethtool_ops = &ndis_ethtool_ops; ++ if (wnd->mp_interrupt) ++ net_dev->irq = wnd->mp_interrupt->irq; ++ net_dev->mem_start = wnd->mem_start; ++ net_dev->mem_end = wnd->mem_end; ++ status = mp_query_int(wnd, OID_802_3_MAXIMUM_LIST_SIZE, ++ &wnd->multicast_size); ++ if (status != NDIS_STATUS_SUCCESS || wnd->multicast_size < 0) ++ wnd->multicast_size = 0; ++ if (wnd->multicast_size > 0) ++ net_dev->flags |= IFF_MULTICAST; ++ else ++ net_dev->flags &= ~IFF_MULTICAST; ++ ++ buf = kmalloc(buf_len, GFP_KERNEL); ++ if (!buf) { ++ WARNING("couldn't allocate memory"); ++ goto err_start; ++ } ++ ++ set_task_offload(wnd, buf, buf_len); ++#ifdef NETIF_F_LLTX ++ net_dev->features |= NETIF_F_LLTX; ++#endif ++ ++ if (register_netdev(net_dev)) { ++ ERROR("cannot register net device %s", net_dev->name); ++ goto err_register; ++ } ++ memset(buf, 0, buf_len); ++ status = mp_query(wnd, OID_GEN_VENDOR_DESCRIPTION, buf, buf_len); ++ if (status != NDIS_STATUS_SUCCESS) { ++ WARNING("couldn't get vendor information: 0x%x", status); ++ buf[0] = 0; ++ } ++ wnd->drv_ndis_version = n = 0; ++ mp_query_int(wnd, OID_GEN_DRIVER_VERSION, &wnd->drv_ndis_version); ++ mp_query_int(wnd, OID_GEN_VENDOR_DRIVER_VERSION, &n); ++ ++ printk(KERN_INFO "%s: ethernet device " MACSTRSEP " using %sNDIS " ++ "driver: %s, version: 0x%x, NDIS version: 0x%x, vendor: '%s', " ++ "%s\n", net_dev->name, MAC2STR(net_dev->dev_addr), ++ deserialized_driver(wnd) ? "" : "serialized ", ++ wd->driver->name, n, wnd->drv_ndis_version, buf, ++ wd->conf_file_name); ++ ++ if (deserialized_driver(wnd)) { ++ /* deserialized drivers don't have a limit, but we ++ * keep max at TX_RING_SIZE */ ++ wnd->max_tx_packets = TX_RING_SIZE; ++ } else { ++ status = mp_query_int(wnd, OID_GEN_MAXIMUM_SEND_PACKETS, ++ &wnd->max_tx_packets); ++ if (status != NDIS_STATUS_SUCCESS) ++ wnd->max_tx_packets = 1; ++ if (wnd->max_tx_packets > TX_RING_SIZE) ++ wnd->max_tx_packets = TX_RING_SIZE; ++ } ++ TRACE2("maximum send packets: %d", wnd->max_tx_packets); ++ NdisAllocatePacketPoolEx(&status, &wnd->tx_packet_pool, ++ wnd->max_tx_packets, 0, ++ PROTOCOL_RESERVED_SIZE_IN_PACKET); ++ if (status != NDIS_STATUS_SUCCESS) { ++ ERROR("couldn't allocate packet pool"); ++ goto packet_pool_err; ++ } ++ NdisAllocateBufferPool(&status, &wnd->tx_buffer_pool, ++ wnd->max_tx_packets + 4); ++ if (status != NDIS_STATUS_SUCCESS) { ++ ERROR("couldn't allocate buffer pool"); ++ goto buffer_pool_err; ++ } ++ TRACE1("pool: %p", wnd->tx_buffer_pool); ++ ++ if (mp_query_int(wnd, OID_GEN_MAXIMUM_TOTAL_SIZE, &n) == ++ NDIS_STATUS_SUCCESS && n > ETH_HLEN) ++ ndis_change_mtu(wnd->net_dev, n - ETH_HLEN); ++ ++ if (mp_query_int(wnd, OID_GEN_MAC_OPTIONS, &n) == NDIS_STATUS_SUCCESS) ++ TRACE2("mac options supported: 0x%x", n); ++ ++ tx_header_offset = (typeof(tx_header_offset))buf; ++ tx_header_offset->protocol_type = NDIS_PROTOCOL_ID_TCP_IP; ++ tx_header_offset->header_offset = sizeof(ETH_HLEN); ++ status = mp_set(wnd, OID_GEN_TRANSPORT_HEADER_OFFSET, ++ tx_header_offset, sizeof(*tx_header_offset)); ++ TRACE2("%08X", status); ++ ++ status = mp_query_int(wnd, OID_GEN_PHYSICAL_MEDIUM, ++ &wnd->physical_medium); ++ if (status != NDIS_STATUS_SUCCESS) ++ wnd->physical_medium = NdisPhysicalMediumUnspecified; ++ ++#ifdef CONFIG_WIRELESS_EXT ++ if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { ++ mp_set_int(wnd, OID_802_11_POWER_MODE, NDIS_POWER_OFF); ++ get_encryption_capa(wnd, buf, buf_len); ++ TRACE1("capabilities = %ld", wnd->capa.encr); ++ printk(KERN_INFO "%s: encryption modes supported: " ++ "%s%s%s%s%s%s%s\n", net_dev->name, ++ test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ? ++ "WEP" : "none", ++ ++ test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ? ++ "; TKIP with WPA" : "", ++ test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? ++ ", WPA2" : "", ++ test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? ++ ", WPA2-PSK" : "", ++ ++ test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ? ++ "; AES/CCMP with WPA" : "", ++ test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? ++ ", WPA2" : "", ++ test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? ++ ", WPA2-PSK" : ""); ++ ++ set_default_iw_params(wnd); ++ } ++#endif ++ kfree(buf); ++ hangcheck_add(wnd); ++ add_iw_stats_timer(wnd); ++ EXIT1(return NDIS_STATUS_SUCCESS); ++ ++buffer_pool_err: ++ wnd->tx_buffer_pool = NULL; ++ if (wnd->tx_packet_pool) { ++ NdisFreePacketPool(wnd->tx_packet_pool); ++ wnd->tx_packet_pool = NULL; ++ } ++packet_pool_err: ++ unregister_netdev(net_dev); ++ wnd->max_tx_packets = 0; ++err_register: ++ kfree(buf); ++err_start: ++ mp_halt(wnd); ++ EXIT1(return NDIS_STATUS_FAILURE); ++} ++ ++static int ndis_remove_device(struct ndis_device *wnd) ++{ ++ s8 tx_pending; ++ int our_mutex; ++ ++ /* prevent setting essid during disassociation */ ++ memset(&wnd->essid, 0, sizeof(wnd->essid)); ++ wnd->tx_ok = 0; ++ netif_carrier_off(wnd->net_dev); ++ if (wnd->max_tx_packets) ++ unregister_netdev(wnd->net_dev); ++ /* if device is suspended, but resume failed, tx_ring_mutex ++ * may already be locked */ ++ our_mutex = mutex_trylock(&wnd->tx_ring_mutex); ++ if (!our_mutex) ++ WARNING("couldn't obtain tx_ring_mutex"); ++ spin_lock_bh(&wnd->tx_ring_lock); ++ tx_pending = wnd->tx_ring_end - wnd->tx_ring_start; ++ if (tx_pending < 0) ++ tx_pending += TX_RING_SIZE; ++ else if (tx_pending == 0 && wnd->is_tx_ring_full) ++ tx_pending = TX_RING_SIZE - 1; ++ wnd->is_tx_ring_full = 0; ++ /* throw away pending packets */ ++ while (tx_pending-- > 0) { ++ struct ndis_packet *packet; ++ ++ packet = wnd->tx_ring[wnd->tx_ring_start]; ++ free_tx_packet(wnd, packet, NDIS_STATUS_CLOSING); ++ wnd->tx_ring_start = (wnd->tx_ring_start + 1) % TX_RING_SIZE; ++ } ++ spin_unlock_bh(&wnd->tx_ring_lock); ++ if (our_mutex) ++ mutex_unlock(&wnd->tx_ring_mutex); ++ mp_halt(wnd); ++ ndis_exit_device(wnd); ++ ++ if (wnd->tx_packet_pool) { ++ NdisFreePacketPool(wnd->tx_packet_pool); ++ wnd->tx_packet_pool = NULL; ++ } ++ if (wnd->tx_buffer_pool) { ++ NdisFreeBufferPool(wnd->tx_buffer_pool); ++ wnd->tx_buffer_pool = NULL; ++ } ++ kfree(wnd->pmkids); ++ printk(KERN_INFO "%s: device %s removed\n", DRIVER_NAME, ++ wnd->net_dev->name); ++ kfree(wnd->nmb); ++ free_netdev(wnd->net_dev); ++ EXIT2(return 0); ++} ++ ++static NTSTATUS ndis_add_device(struct driver_object *drv_obj, ++ struct device_object *pdo) ++{ ++ struct device_object *fdo; ++ struct ndis_mp_block *nmb; ++ NTSTATUS status; ++ struct ndis_device *wnd; ++ struct net_device *net_dev; ++ struct wrap_device *wd; ++ unsigned long i; ++ ++ ENTER2("%p, %p", drv_obj, pdo); ++ if (strlen(if_name) >= IFNAMSIZ) { ++ ERROR("interface name '%s' is too long", if_name); ++ return STATUS_INVALID_PARAMETER; ++ } ++ net_dev = alloc_etherdev(sizeof(*wnd)); ++ if (!net_dev) { ++ ERROR("couldn't allocate device"); ++ return STATUS_RESOURCES; ++ } ++ wd = pdo->reserved; ++ if (wrap_is_pci_bus(wd->dev_bus)) ++ SET_NETDEV_DEV(net_dev, &wd->pci.pdev->dev); ++ if (wrap_is_usb_bus(wd->dev_bus)) ++ SET_NETDEV_DEV(net_dev, &wd->usb.intf->dev); ++ status = IoCreateDevice(drv_obj, 0, NULL, FILE_DEVICE_UNKNOWN, 0, ++ FALSE, &fdo); ++ if (status != STATUS_SUCCESS) { ++ free_netdev(net_dev); ++ EXIT2(return status); ++ } ++ wnd = netdev_priv(net_dev); ++ TRACE1("wnd: %p", wnd); ++ ++ nmb = kmalloc(sizeof(*nmb), GFP_KERNEL); ++ if (!nmb) { ++ WARNING("couldn't allocate memory"); ++ IoDeleteDevice(fdo); ++ free_netdev(net_dev); ++ return STATUS_RESOURCES; ++ } ++#if DEBUG >= 6 ++ /* poison nmb so if a driver accesses uninitialized pointers, we ++ * know what it is */ ++ for (i = 0; i < sizeof(*nmb) / sizeof(unsigned long); i++) ++ ((unsigned long *)nmb)[i] = i + 0x8a3fc1; ++#endif ++ ++ wnd->nmb = nmb; ++ nmb->wnd = wnd; ++ nmb->pdo = pdo; ++ wnd->wd = wd; ++ wnd->net_dev = net_dev; ++ fdo->reserved = wnd; ++ nmb->fdo = fdo; ++ if (ndis_init_device(wnd)) { ++ IoDeleteDevice(fdo); ++ kfree(nmb); ++ free_netdev(net_dev); ++ EXIT1(return STATUS_RESOURCES); ++ } ++ nmb->next_device = IoAttachDeviceToDeviceStack(fdo, pdo); ++ spin_lock_init(&wnd->tx_ring_lock); ++ mutex_init(&wnd->tx_ring_mutex); ++ mutex_init(&wnd->ndis_req_mutex); ++ wnd->ndis_req_done = 0; ++ INIT_WORK(&wnd->tx_work, tx_worker); ++ wnd->tx_ring_start = 0; ++ wnd->tx_ring_end = 0; ++ wnd->is_tx_ring_full = 0; ++ wnd->capa.encr = 0; ++ wnd->capa.auth = 0; ++ wnd->attributes = 0; ++ wnd->dma_map_count = 0; ++ wnd->dma_map_addr = NULL; ++ wnd->nick[0] = 0; ++ init_timer(&wnd->hangcheck_timer); ++ wnd->scan_timestamp = 0; ++ init_timer(&wnd->iw_stats_timer); ++ wnd->iw_stats_interval = 10 * HZ; ++ wnd->ndis_pending_work = 0; ++ memset(&wnd->essid, 0, sizeof(wnd->essid)); ++ memset(&wnd->encr_info, 0, sizeof(wnd->encr_info)); ++ wnd->infrastructure_mode = Ndis802_11Infrastructure; ++ INIT_WORK(&wnd->ndis_work, wrapndis_worker); ++ wnd->iw_stats_enabled = TRUE; ++ ++ TRACE1("nmb: %p, pdo: %p, fdo: %p, attached: %p, next: %p", ++ nmb, pdo, fdo, fdo->attached, nmb->next_device); ++ ++ /* dispatch routines are called as Windows functions */ ++ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) ++ drv_obj->major_func[i] = WIN_FUNC_PTR(IoPassIrpDown,2); ++ ++ drv_obj->major_func[IRP_MJ_PNP] = WIN_FUNC_PTR(NdisDispatchPnp,2); ++ drv_obj->major_func[IRP_MJ_POWER] = WIN_FUNC_PTR(NdisDispatchPower,2); ++ drv_obj->major_func[IRP_MJ_INTERNAL_DEVICE_CONTROL] = ++ WIN_FUNC_PTR(NdisDispatchDeviceControl,2); ++// drv_obj->major_func[IRP_MJ_DEVICE_CONTROL] = ++// WIN_FUNC_PTR(NdisDispatchDeviceControl,2); ++ EXIT2(return STATUS_SUCCESS); ++} ++ ++int init_ndis_driver(struct driver_object *drv_obj) ++{ ++ ENTER1("%p", drv_obj); ++ drv_obj->drv_ext->add_device = ndis_add_device; ++ return 0; ++} ++ ++int wrapndis_init(void) ++{ ++ wrapndis_wq = create_singlethread_workqueue("wrapndis_wq"); ++ if (!wrapndis_wq) ++ EXIT1(return -ENOMEM); ++ TRACE1("wrapndis_wq: %p", wrapndis_wq); ++ register_netdevice_notifier(&netdev_notifier); ++ return 0; ++} ++ ++void wrapndis_exit(void) ++{ ++ unregister_netdevice_notifier(&netdev_notifier); ++ if (wrapndis_wq) ++ destroy_workqueue(wrapndis_wq); ++} +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/wrapndis.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapndis.h +--- linux-3.12.2/3rdparty/ndiswrapper/wrapndis.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapndis.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,86 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _WRAPNDIS_H_ ++#define _WRAPNDIS_H_ ++ ++#include "ndis.h" ++#include "pnp.h" ++ ++int wrapndis_init(void); ++void wrapndis_exit(void); ++ ++NDIS_STATUS mp_reset(struct ndis_device *wnd); ++ ++NDIS_STATUS mp_request(enum ndis_request_type request, ++ struct ndis_device *wnd, ndis_oid oid, ++ void *buf, ULONG buflen, ULONG *written, ULONG *needed); ++ ++static inline NDIS_STATUS mp_query_info(struct ndis_device *wnd, ++ ndis_oid oid, void *buf, ULONG buflen, ++ ULONG *written, ULONG *needed) ++{ ++ return mp_request(NdisRequestQueryInformation, wnd, oid, ++ buf, buflen, written, needed); ++} ++ ++static inline NDIS_STATUS mp_set_info(struct ndis_device *wnd, ++ ndis_oid oid, void *buf, ULONG buflen, ++ ULONG *written, ULONG *needed) ++{ ++ return mp_request(NdisRequestSetInformation, wnd, oid, ++ buf, buflen, written, needed); ++} ++ ++static inline NDIS_STATUS mp_query(struct ndis_device *wnd, ndis_oid oid, ++ void *buf, ULONG buflen) ++{ ++ return mp_request(NdisRequestQueryInformation, wnd, oid, ++ buf, buflen, NULL, NULL); ++} ++ ++static inline NDIS_STATUS mp_query_int(struct ndis_device *wnd, ++ ndis_oid oid, ULONG *data) ++{ ++ return mp_request(NdisRequestQueryInformation, wnd, oid, ++ data, sizeof(ULONG), NULL, NULL); ++} ++ ++static inline NDIS_STATUS mp_set(struct ndis_device *wnd, ndis_oid oid, ++ void *buf, ULONG buflen) ++{ ++ return mp_request(NdisRequestSetInformation, wnd, oid, ++ buf, buflen, NULL, NULL); ++} ++ ++static inline NDIS_STATUS mp_set_int(struct ndis_device *wnd, ++ ndis_oid oid, ULONG data) ++{ ++ return mp_request(NdisRequestSetInformation, wnd, oid, ++ &data, sizeof(ULONG), NULL, NULL); ++} ++ ++void free_tx_packet(struct ndis_device *wnd, struct ndis_packet *packet, ++ NDIS_STATUS status); ++int init_ndis_driver(struct driver_object *drv_obj); ++NDIS_STATUS ndis_reinit(struct ndis_device *wnd); ++void set_media_state(struct ndis_device *wnd, enum ndis_media_state state); ++ ++void hangcheck_add(struct ndis_device *wnd); ++void hangcheck_del(struct ndis_device *wnd); ++ ++struct iw_statistics *get_iw_stats(struct net_device *dev); ++ ++#endif +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/wrapper.c linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapper.c +--- linux-3.12.2/3rdparty/ndiswrapper/wrapper.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapper.c 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,111 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include "ndis.h" ++#include "iw_ndis.h" ++#include "loader.h" ++#include "pnp.h" ++#include "wrapper.h" ++ ++char *if_name = "wlan%d"; ++int proc_uid, proc_gid; ++int hangcheck_interval; ++static char *utils_version = UTILS_VERSION; ++int debug = DEBUG; ++ ++module_param(if_name, charp, 0400); ++MODULE_PARM_DESC(if_name, "Network interface name or template " ++ "(default: wlan%d)"); ++module_param(proc_uid, int, 0600); ++MODULE_PARM_DESC(proc_uid, "The uid of the files created in /proc " ++ "(default: 0)."); ++module_param(proc_gid, int, 0600); ++MODULE_PARM_DESC(proc_gid, "The gid of the files created in /proc " ++ "(default: 0)."); ++module_param(debug, int, 0600); ++MODULE_PARM_DESC(debug, "debug level"); ++ ++/* 0 - default value provided by NDIS driver, ++ * positive value - force hangcheck interval to that many seconds ++ * negative value - disable hangcheck ++ */ ++module_param(hangcheck_interval, int, 0600); ++MODULE_PARM_DESC(hangcheck_interval, "The interval, in seconds, for checking" ++ " if driver is hung. (default: 0)"); ++ ++module_param(utils_version, charp, 0400); ++MODULE_PARM_DESC(utils_version, "Compatible version of utils " ++ "(read only: " UTILS_VERSION ")"); ++ ++MODULE_AUTHOR("ndiswrapper team "); ++#ifdef MODULE_DESCRIPTION ++MODULE_DESCRIPTION("NDIS wrapper driver"); ++#endif ++#ifdef MODULE_VERSION ++MODULE_VERSION(DRIVER_VERSION); ++#endif ++MODULE_LICENSE("GPL"); ++ ++static void module_cleanup(void) ++{ ++ loader_exit(); ++ usb_exit(); ++ wrap_procfs_remove(); ++ wrapndis_exit(); ++ ndis_exit(); ++ ntoskernel_exit(); ++ wrapmem_exit(); ++} ++ ++static int __init wrapper_init(void) ++{ ++#ifdef TAINT_OOT_MODULE ++ add_taint(TAINT_OOT_MODULE, LOCKDEP_NOW_UNRELIABLE); ++#endif ++ printk(KERN_INFO "%s version %s loaded (smp=%s, preempt=%s)\n", ++ DRIVER_NAME, DRIVER_VERSION, ++#ifdef CONFIG_SMP ++ "yes" ++#else ++ "no" ++#endif ++ , ++#ifdef CONFIG_PREEMPT_RT ++ "rt" ++#elif defined(CONFIG_PREEMPT) ++ "yes" ++#else ++ "no" ++#endif ++ ); ++ ++ if (wrapmem_init() || ntoskernel_init() || ndis_init() || ++ wrapndis_init() || usb_init() || wrap_procfs_init() || ++ loader_init()) { ++ module_cleanup(); ++ ERROR("%s: initialization failed", DRIVER_NAME); ++ return -EINVAL; ++ } ++ EXIT1(return 0); ++} ++ ++static void __exit wrapper_exit(void) ++{ ++ ENTER1(""); ++ module_cleanup(); ++} ++ ++module_init(wrapper_init); ++module_exit(wrapper_exit); +diff -Nurp linux-3.12.2/3rdparty/ndiswrapper/wrapper.h linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapper.h +--- linux-3.12.2/3rdparty/ndiswrapper/wrapper.h 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/wrapper.h 2013-11-28 21:42:11.000000000 +0200 +@@ -0,0 +1,24 @@ ++/* ++ * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef WRAPPER_H ++#define WRAPPER_H ++ ++extern char *if_name; ++extern int proc_uid; ++extern int proc_gid; ++extern int hangcheck_interval; ++ ++#endif /* WRAPPER_H */ diff --git a/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-Kconfig.patch b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-Kconfig.patch new file mode 100644 index 00000000..f7d26e62 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-Kconfig.patch @@ -0,0 +1,7 @@ +--- linux-2.6.24.orig/3rdparty/ndiswrapper/Kconfig 1969-12-31 21:00:00.000000000 -0300 ++++ linux-2.6.24/3rdparty/ndiswrapper/Kconfig 2007-11-26 15:11:31.000000000 -0200 +@@ -0,0 +1,4 @@ ++ ++config NDISWRAPPER ++ tristate "NDIS driver wrapper support" ++ depends on PCI && USB && !X86_64_XEN diff --git a/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-Makefile-build-fix.patch b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-Makefile-build-fix.patch new file mode 100644 index 00000000..b44f4b29 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-Makefile-build-fix.patch @@ -0,0 +1,45 @@ +--- linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/Makefile.orig 2013-11-28 21:42:10.000000000 +0200 ++++ linux-3.12.2-ndiswrapper-1.59/3rdparty/ndiswrapper/Makefile 2013-11-30 21:41:19.550504380 +0200 +@@ -9,24 +9,10 @@ DISTFILES = \ + winnt_types.h workqueue.c wrapmem.c wrapmem.h wrapndis.c wrapndis.h \ + wrapper.c wrapper.h + +-# By default, we try to compile the modules for the currently running +-# kernel. But it's the first approximation, as we will re-read the +-# version from the kernel sources. +-KVERS_UNAME ?= $(shell uname -r) +- + # KBUILD is the path to the Linux kernel build tree. It is usually the + # same as the kernel source tree, except when the kernel was compiled in + # a separate directory. +-KBUILD ?= $(shell readlink -f /lib/modules/$(KVERS_UNAME)/build) +- +-ifeq (,$(KBUILD)) +-$(error Kernel build tree not found - please set KBUILD to configured kernel) +-endif +- +-KCONFIG := $(KBUILD)/.config +-ifeq (,$(wildcard $(KCONFIG))) +-$(error No .config found in $(KBUILD), please set KBUILD to configured kernel) +-endif ++KBUILD ?= $(srctree) + + ifneq (,$(wildcard $(KBUILD)/include/linux/version.h)) + ifneq (,$(wildcard $(KBUILD)/include/generated/uapi/linux/version.h)) +@@ -43,16 +29,9 @@ endif + ifeq (,$(wildcard $(VERSION_H))) + VERSION_H := $(KBUILD)/include/linux/version.h + endif +-ifeq (,$(wildcard $(VERSION_H))) +-$(error Please run 'make modules_prepare' in $(KBUILD)) +-endif + + KVERS := $(shell sed -ne 's/"//g;s/^\#define UTS_RELEASE //p' $(VERSION_H)) + +-ifeq (,$(KVERS)) +-$(error Cannot find UTS_RELEASE in $(VERSION_H), please report) +-endif +- + INST_DIR = /lib/modules/$(KVERS)/misc + + SRC_DIR=$(shell pwd) diff --git a/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-linux-3.14-buildfix.patch b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-linux-3.14-buildfix.patch new file mode 100644 index 00000000..6550b9f2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-ndiswrapper-linux-3.14-buildfix.patch @@ -0,0 +1,33 @@ + +Fix build with kernel-3.14 + +Signed-off-by: Thomas Backlund + + 3rdparty/ndiswrapper/crt.c | 2 +- + 3rdparty/ndiswrapper/ntoskernel.h | 3 +-- + 2 files changed, 2 insertions(+), 3 deletions(-) + +--- linux/3rdparty/ndiswrapper/crt.c.orig 2014-04-26 19:10:55.000000000 +0300 ++++ linux/3rdparty/ndiswrapper/crt.c 2014-04-26 19:25:27.766116082 +0300 +@@ -467,7 +467,7 @@ noregparm int WIN_FUNC(_win_memcmp,3) + noregparm void WIN_FUNC(_win_srand,1) + (UINT seed) + { +- net_srandom(seed); ++ prandom_seed((__force u32) seed); + } + + noregparm int WIN_FUNC(rand,0) +--- linux/3rdparty/ndiswrapper/ntoskernel.h.orig 2014-04-26 19:42:32.000000000 +0300 ++++ linux/3rdparty/ndiswrapper/ntoskernel.h 2014-04-26 19:59:13.662522942 +0300 +@@ -798,9 +798,8 @@ do { \ + #define nt_spin_unlock_irqrestore(lock, flags) \ + do { \ + nt_spin_unlock(lock); \ +- preempt_enable_no_resched(); \ ++ preempt_enable(); \ + local_irq_restore(flags); \ +- preempt_check_resched(); \ + } while (0) + + static inline ULONG SPAN_PAGES(void *ptr, SIZE_T length) diff --git a/kernel/kernel/files/patches/mageia/3rd-rfswitch-1.3.patch b/kernel/kernel/files/patches/mageia/3rd-rfswitch-1.3.patch new file mode 100644 index 00000000..e87bf7e0 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-rfswitch-1.3.patch @@ -0,0 +1,978 @@ + 3rdparty/rfswitch/FILES | 6 + 3rdparty/rfswitch/ISSUES | 28 +++ + 3rdparty/rfswitch/Kconfig | 22 ++ + 3rdparty/rfswitch/LICENSE | 339 +++++++++++++++++++++++++++++++++++++++++++++ + 3rdparty/rfswitch/Makefile | 119 +++++++++++++++ + 3rdparty/rfswitch/README | 44 +++++ + 3rdparty/rfswitch/av5100.c | 174 +++++++++++++++++++++++ + 3rdparty/rfswitch/pbe5.c | 205 +++++++++++++++++++++++++++ + 8 files changed, 937 insertions(+) +diff -Nurp linux-2.6.37/3rdparty/rfswitch/av5100.c linux-2.6.37.3rdparty/3rdparty/rfswitch/av5100.c +--- linux-2.6.37/3rdparty/rfswitch/av5100.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/rfswitch/av5100.c 2008-03-28 05:25:28.000000000 +0200 +@@ -0,0 +1,174 @@ ++/******************************************************************************* ++ ++ Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms of version 2 of the GNU General Public License as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ more details. ++ ++ You should have received a copy of the GNU General Public License along with ++ this program; if not, write to the Free Software Foundation, Inc., 59 ++ Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++ The full GNU General Public License is included in this distribution in the ++ file called LICENSE. ++ ++ Contact Information: ++ James P. Ketrenos ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define DRV_NAME "av5100" ++#define DRV_VERSION "1.3" ++#define DRV_DESCRIPTION "SW RF kill switch for Averatec 5100P" ++#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" ++ ++static int radio = 1; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++ ++MODULE_PARM(radio, "i"); ++ ++#else /* LINUX_VERSION_CODE < 2.6.0 */ ++ ++#include ++module_param(radio, int, 1); ++ ++#endif /* LINUX_VERSION_CODE < 2.6.0 */ ++ ++MODULE_PARM_DESC(radio, "controls state of radio (1=on, 0=off)"); ++ ++MODULE_DESCRIPTION(DRV_DESCRIPTION); ++MODULE_AUTHOR(DRV_COPYRIGHT); ++MODULE_LICENSE("GPL"); ++ ++#define AV5100_RADIO_ON (0xe0) ++#define AV5100_RADIO_OFF (0xe1) ++ ++static int av5100_radio = AV5100_RADIO_OFF; ++ ++static void av5100_set_radio(int state) ++{ ++ printk(KERN_INFO DRV_NAME ": Radio being turned %s\n", ++ (state == AV5100_RADIO_ON) ? "ON" : "OFF"); ++ outl(0x80020800, 0xcf8); ++ outb(0x6f, 0x0072); ++ outl(0x1800ffff, 0x1184); ++ outb(state, 0x00b2); ++ av5100_radio = state; ++} ++ ++ ++/* ++ * proc stuff ++ */ ++static struct proc_dir_entry *dir_base = NULL; ++ ++static int proc_set_radio(struct file *file, const char *buffer, ++ unsigned long count, void *data) ++{ ++ av5100_set_radio(buffer[0] == '0' ? AV5100_RADIO_OFF : AV5100_RADIO_ON); ++ ++ return count; ++} ++ ++static int proc_get_radio(char *page, char **start, off_t offset, ++ int count, int *eof, void *data) ++{ ++ int len = 0; ++ ++ len += snprintf(page, count, DRV_NAME ": %d\n", ++ av5100_radio == AV5100_RADIO_OFF ? 0 : 1); ++ ++ *eof = 1; ++ return len; ++} ++ ++ ++static void av5100_proc_cleanup(void) ++{ ++ if (dir_base) { ++ remove_proc_entry("radio", dir_base); ++ remove_proc_entry(DRV_NAME, &proc_root); ++ dir_base = NULL; ++ } ++} ++ ++ ++static int av5100_proc_init(void) ++{ ++ struct proc_dir_entry *ent; ++ int err = 0; ++ ++ dir_base = create_proc_entry(DRV_NAME, S_IFDIR, &proc_root); ++ if (dir_base == NULL) { ++ printk(KERN_ERR DRV_NAME ": Unable to initialise /proc/" ++ DRV_NAME "\n"); ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ ++ ent = create_proc_entry("radio", S_IFREG | S_IRUGO | S_IWUSR, ++ dir_base); ++ if (ent) { ++ ent->read_proc = proc_get_radio; ++ ent->write_proc = proc_set_radio; ++ } else { ++ printk(KERN_ERR ++ "Unable to initialize /proc/" DRV_NAME "/radio\n"); ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ return 0; ++ ++ fail: ++ av5100_proc_cleanup(); ++ return err; ++} ++ ++/* ++ * module stuff ++ */ ++static int __init av5100_init(void) ++{ ++ av5100_proc_init(); ++ ++ av5100_set_radio((radio == 1) ? AV5100_RADIO_ON : AV5100_RADIO_OFF); ++ ++ return 0; ++} ++ ++static void __exit av5100_exit(void) ++{ ++ av5100_set_radio(AV5100_RADIO_OFF); ++ ++ av5100_proc_cleanup(); ++} ++ ++module_init(av5100_init); ++module_exit(av5100_exit); ++ ++/* ++ 1 2 3 4 5 6 7 ++12345678901234567890123456789012345678901234567890123456789012345678901234567890 ++*/ +diff -Nurp linux-2.6.37/3rdparty/rfswitch/FILES linux-2.6.37.3rdparty/3rdparty/rfswitch/FILES +--- linux-2.6.37/3rdparty/rfswitch/FILES 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/rfswitch/FILES 2004-07-09 07:44:19.000000000 +0300 +@@ -0,0 +1,6 @@ ++Makefile Used for building on 2.4, 2.6, internally and exteranlly ++ ++FILES This file ++ ++av5100.c Averatec 5100P SW Switch Module ++pbe5.c Packard Bell Easynote SW Switch Module +diff -Nurp linux-2.6.37/3rdparty/rfswitch/ISSUES linux-2.6.37.3rdparty/3rdparty/rfswitch/ISSUES +--- linux-2.6.37/3rdparty/rfswitch/ISSUES 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/rfswitch/ISSUES 2004-07-09 07:43:22.000000000 +0300 +@@ -0,0 +1,28 @@ ++ ++ISSUES ++------------ ----- ----- ---- --- -- - ++ ++No packets! - RF kill switch ++ ++If the module loads, but no packets are transferred you may have a SW based ++radio kill switch. All laptops have some capability to disable the radio ++via a button or switch. On some laptops that switch is physically tied to the ++IPW2100; simply toggling the switch should enable the radio. ++ ++On other laptops, the switch is a button that when pressed requires some ++software driver to send some hardware command to some other piece of hardware ++on the laptop, that then controls the radio. The driver currently has support ++for the Averatec 5100P laptop's SW switch. Support will be added for other ++laptop vendors as we become aware of them and figure out how to enable the ++radio. ++ ++To know if the radio is being disabled via the RF switch, perform the following: ++ ++% cat /proc/net/ipw2100/eth1/state ++Radio is disabled by RF switch ++ ++If it says that, then your RF switch is currently disabling the radio. The ++driver doesn't currently support switching back to the on state if you have a ++physical RF switch (the radio may turn on and packets will work, but the proc ++entry won't be updated) ++ +diff -Nurp linux-2.6.37/3rdparty/rfswitch/Kconfig linux-2.6.37.3rdparty/3rdparty/rfswitch/Kconfig +--- linux-2.6.37/3rdparty/rfswitch/Kconfig 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/rfswitch/Kconfig 2008-05-27 23:39:10.000000000 +0300 +@@ -0,0 +1,22 @@ ++menu "RF Switch" ++ depends on EXPERIMENTAL ++ ++config RFSWITCH ++ tristate "RF Switch" ++ depends on EXPERIMENTAL ++ ++config AVERATEC_5100P ++ tristate "averatec 5100P driver" ++ depends on RFSWITCH ++ ---help--- ++ This is an experimental driver for the wireless switch ++ of some laptops (usefull with some ipw2x00 cards) ++ ++config PACKARDBELL_E5 ++ tristate "pbe5 driver" ++ depends on RFSWITCH ++ ---help--- ++ This is an experimental driver for the wireless switch ++ of some laptops (usefull with some ipw2x00 cards) ++ ++endmenu +diff -Nurp linux-2.6.37/3rdparty/rfswitch/LICENSE linux-2.6.37.3rdparty/3rdparty/rfswitch/LICENSE +--- linux-2.6.37/3rdparty/rfswitch/LICENSE 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/rfswitch/LICENSE 2004-07-09 07:43:22.000000000 +0300 +@@ -0,0 +1,339 @@ ++ ++"This software program is licensed subject to the GNU General Public License ++(GPL). Version 2, June 1991, available at ++" ++ ++GNU General Public License ++ ++Version 2, June 1991 ++ ++Copyright (C) 1989, 1991 Free Software Foundation, Inc. ++59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ++ ++Everyone is permitted to copy and distribute verbatim copies of this license ++document, but changing it is not allowed. ++ ++Preamble ++ ++The licenses for most software are designed to take away your freedom to ++share and change it. By contrast, the GNU General Public License is intended ++to guarantee your freedom to share and change free software--to make sure ++the software is free for all its users. This General Public License applies ++to most of the Free Software Foundation's software and to any other program ++whose authors commit to using it. (Some other Free Software Foundation ++software is covered by the GNU Library General Public License instead.) You ++can apply it to your programs, too. ++ ++When we speak of free software, we are referring to freedom, not price. Our ++General Public Licenses are designed to make sure that you have the freedom ++to distribute copies of free software (and charge for this service if you ++wish), that you receive source code or can get it if you want it, that you ++can change the software or use pieces of it in new free programs; and that ++you know you can do these things. ++ ++To protect your rights, we need to make restrictions that forbid anyone to ++deny you these rights or to ask you to surrender the rights. These ++restrictions translate to certain responsibilities for you if you distribute ++copies of the software, or if you modify it. ++ ++For example, if you distribute copies of such a program, whether gratis or ++for a fee, you must give the recipients all the rights that you have. You ++must make sure that they, too, receive or can get the source code. And you ++must show them these terms so they know their rights. ++ ++We protect your rights with two steps: (1) copyright the software, and (2) ++offer you this license which gives you legal permission to copy, distribute ++and/or modify the software. ++ ++Also, for each author's protection and ours, we want to make certain that ++everyone understands that there is no warranty for this free software. If ++the software is modified by someone else and passed on, we want its ++recipients to know that what they have is not the original, so that any ++problems introduced by others will not reflect on the original authors' ++reputations. ++ ++Finally, any free program is threatened constantly by software patents. We ++wish to avoid the danger that redistributors of a free program will ++individually obtain patent licenses, in effect making the program ++proprietary. To prevent this, we have made it clear that any patent must be ++licensed for everyone's free use or not licensed at all. ++ ++The precise terms and conditions for copying, distribution and modification ++follow. ++ ++TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ++ ++0. This License applies to any program or other work which contains a notice ++ placed by the copyright holder saying it may be distributed under the ++ terms of this General Public License. The "Program", below, refers to any ++ such program or work, and a "work based on the Program" means either the ++ Program or any derivative work under copyright law: that is to say, a ++ work containing the Program or a portion of it, either verbatim or with ++ modifications and/or translated into another language. (Hereinafter, ++ translation is included without limitation in the term "modification".) ++ Each licensee is addressed as "you". ++ ++ Activities other than copying, distribution and modification are not ++ covered by this License; they are outside its scope. The act of running ++ the Program is not restricted, and the output from the Program is covered ++ only if its contents constitute a work based on the Program (independent ++ of having been made by running the Program). Whether that is true depends ++ on what the Program does. ++ ++1. You may copy and distribute verbatim copies of the Program's source code ++ as you receive it, in any medium, provided that you conspicuously and ++ appropriately publish on each copy an appropriate copyright notice and ++ disclaimer of warranty; keep intact all the notices that refer to this ++ License and to the absence of any warranty; and give any other recipients ++ of the Program a copy of this License along with the Program. ++ ++ You may charge a fee for the physical act of transferring a copy, and you ++ may at your option offer warranty protection in exchange for a fee. ++ ++2. You may modify your copy or copies of the Program or any portion of it, ++ thus forming a work based on the Program, and copy and distribute such ++ modifications or work under the terms of Section 1 above, provided that ++ you also meet all of these conditions: ++ ++ * a) You must cause the modified files to carry prominent notices stating ++ that you changed the files and the date of any change. ++ ++ * b) You must cause any work that you distribute or publish, that in ++ whole or in part contains or is derived from the Program or any part ++ thereof, to be licensed as a whole at no charge to all third parties ++ under the terms of this License. ++ ++ * c) If the modified program normally reads commands interactively when ++ run, you must cause it, when started running for such interactive ++ use in the most ordinary way, to print or display an announcement ++ including an appropriate copyright notice and a notice that there is ++ no warranty (or else, saying that you provide a warranty) and that ++ users may redistribute the program under these conditions, and ++ telling the user how to view a copy of this License. (Exception: if ++ the Program itself is interactive but does not normally print such ++ an announcement, your work based on the Program is not required to ++ print an announcement.) ++ ++ These requirements apply to the modified work as a whole. If identifiable ++ sections of that work are not derived from the Program, and can be ++ reasonably considered independent and separate works in themselves, then ++ this License, and its terms, do not apply to those sections when you ++ distribute them as separate works. But when you distribute the same ++ sections as part of a whole which is a work based on the Program, the ++ distribution of the whole must be on the terms of this License, whose ++ permissions for other licensees extend to the entire whole, and thus to ++ each and every part regardless of who wrote it. ++ ++ Thus, it is not the intent of this section to claim rights or contest ++ your rights to work written entirely by you; rather, the intent is to ++ exercise the right to control the distribution of derivative or ++ collective works based on the Program. ++ ++ In addition, mere aggregation of another work not based on the Program ++ with the Program (or with a work based on the Program) on a volume of a ++ storage or distribution medium does not bring the other work under the ++ scope of this License. ++ ++3. You may copy and distribute the Program (or a work based on it, under ++ Section 2) in object code or executable form under the terms of Sections ++ 1 and 2 above provided that you also do one of the following: ++ ++ * a) Accompany it with the complete corresponding machine-readable source ++ code, which must be distributed under the terms of Sections 1 and 2 ++ above on a medium customarily used for software interchange; or, ++ ++ * b) Accompany it with a written offer, valid for at least three years, ++ to give any third party, for a charge no more than your cost of ++ physically performing source distribution, a complete machine- ++ readable copy of the corresponding source code, to be distributed ++ under the terms of Sections 1 and 2 above on a medium customarily ++ used for software interchange; or, ++ ++ * c) Accompany it with the information you received as to the offer to ++ distribute corresponding source code. (This alternative is allowed ++ only for noncommercial distribution and only if you received the ++ program in object code or executable form with such an offer, in ++ accord with Subsection b above.) ++ ++ The source code for a work means the preferred form of the work for ++ making modifications to it. For an executable work, complete source code ++ means all the source code for all modules it contains, plus any ++ associated interface definition files, plus the scripts used to control ++ compilation and installation of the executable. However, as a special ++ exception, the source code distributed need not include anything that is ++ normally distributed (in either source or binary form) with the major ++ components (compiler, kernel, and so on) of the operating system on which ++ the executable runs, unless that component itself accompanies the ++ executable. ++ ++ If distribution of executable or object code is made by offering access ++ to copy from a designated place, then offering equivalent access to copy ++ the source code from the same place counts as distribution of the source ++ code, even though third parties are not compelled to copy the source ++ along with the object code. ++ ++4. You may not copy, modify, sublicense, or distribute the Program except as ++ expressly provided under this License. Any attempt otherwise to copy, ++ modify, sublicense or distribute the Program is void, and will ++ automatically terminate your rights under this License. However, parties ++ who have received copies, or rights, from you under this License will not ++ have their licenses terminated so long as such parties remain in full ++ compliance. ++ ++5. You are not required to accept this License, since you have not signed ++ it. However, nothing else grants you permission to modify or distribute ++ the Program or its derivative works. These actions are prohibited by law ++ if you do not accept this License. Therefore, by modifying or ++ distributing the Program (or any work based on the Program), you ++ indicate your acceptance of this License to do so, and all its terms and ++ conditions for copying, distributing or modifying the Program or works ++ based on it. ++ ++6. Each time you redistribute the Program (or any work based on the ++ Program), the recipient automatically receives a license from the ++ original licensor to copy, distribute or modify the Program subject to ++ these terms and conditions. You may not impose any further restrictions ++ on the recipients' exercise of the rights granted herein. You are not ++ responsible for enforcing compliance by third parties to this License. ++ ++7. If, as a consequence of a court judgment or allegation of patent ++ infringement or for any other reason (not limited to patent issues), ++ conditions are imposed on you (whether by court order, agreement or ++ otherwise) that contradict the conditions of this License, they do not ++ excuse you from the conditions of this License. If you cannot distribute ++ so as to satisfy simultaneously your obligations under this License and ++ any other pertinent obligations, then as a consequence you may not ++ distribute the Program at all. For example, if a patent license would ++ not permit royalty-free redistribution of the Program by all those who ++ receive copies directly or indirectly through you, then the only way you ++ could satisfy both it and this License would be to refrain entirely from ++ distribution of the Program. ++ ++ If any portion of this section is held invalid or unenforceable under any ++ particular circumstance, the balance of the section is intended to apply ++ and the section as a whole is intended to apply in other circumstances. ++ ++ It is not the purpose of this section to induce you to infringe any ++ patents or other property right claims or to contest validity of any ++ such claims; this section has the sole purpose of protecting the ++ integrity of the free software distribution system, which is implemented ++ by public license practices. Many people have made generous contributions ++ to the wide range of software distributed through that system in ++ reliance on consistent application of that system; it is up to the ++ author/donor to decide if he or she is willing to distribute software ++ through any other system and a licensee cannot impose that choice. ++ ++ This section is intended to make thoroughly clear what is believed to be ++ a consequence of the rest of this License. ++ ++8. If the distribution and/or use of the Program is restricted in certain ++ countries either by patents or by copyrighted interfaces, the original ++ copyright holder who places the Program under this License may add an ++ explicit geographical distribution limitation excluding those countries, ++ so that distribution is permitted only in or among countries not thus ++ excluded. In such case, this License incorporates the limitation as if ++ written in the body of this License. ++ ++9. The Free Software Foundation may publish revised and/or new versions of ++ the General Public License from time to time. Such new versions will be ++ similar in spirit to the present version, but may differ in detail to ++ address new problems or concerns. ++ ++ Each version is given a distinguishing version number. If the Program ++ specifies a version number of this License which applies to it and "any ++ later version", you have the option of following the terms and ++ conditions either of that version or of any later version published by ++ the Free Software Foundation. If the Program does not specify a version ++ number of this License, you may choose any version ever published by the ++ Free Software Foundation. ++ ++10. If you wish to incorporate parts of the Program into other free programs ++ whose distribution conditions are different, write to the author to ask ++ for permission. For software which is copyrighted by the Free Software ++ Foundation, write to the Free Software Foundation; we sometimes make ++ exceptions for this. Our decision will be guided by the two goals of ++ preserving the free status of all derivatives of our free software and ++ of promoting the sharing and reuse of software generally. ++ ++ NO WARRANTY ++ ++11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY ++ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN ++ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES ++ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER ++ EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ++ ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH ++ YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL ++ NECESSARY SERVICING, REPAIR OR CORRECTION. ++ ++12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING ++ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR ++ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR ++ DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL ++ DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM ++ (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED ++ INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF ++ THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR ++ OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. ++ ++END OF TERMS AND CONDITIONS ++ ++How to Apply These Terms to Your New Programs ++ ++If you develop a new program, and you want it to be of the greatest ++possible use to the public, the best way to achieve this is to make it free ++software which everyone can redistribute and change under these terms. ++ ++To do so, attach the following notices to the program. It is safest to ++attach them to the start of each source file to most effectively convey the ++exclusion of warranty; and each file should have at least the "copyright" ++line and a pointer to where the full notice is found. ++ ++one line to give the program's name and an idea of what it does. ++Copyright (C) yyyy name of author ++ ++This program is free software; you can redistribute it and/or modify it ++under the terms of the GNU General Public License as published by the Free ++Software Foundation; either version 2 of the License, or (at your option) ++any later version. ++ ++This program is distributed in the hope that it will be useful, but WITHOUT ++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++more details. ++ ++You should have received a copy of the GNU General Public License along with ++this program; if not, write to the Free Software Foundation, Inc., 59 ++Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++Also add information on how to contact you by electronic and paper mail. ++ ++If the program is interactive, make it output a short notice like this when ++it starts in an interactive mode: ++ ++Gnomovision version 69, Copyright (C) year name of author Gnomovision comes ++with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free ++software, and you are welcome to redistribute it under certain conditions; ++type 'show c' for details. ++ ++The hypothetical commands 'show w' and 'show c' should show the appropriate ++parts of the General Public License. Of course, the commands you use may be ++called something other than 'show w' and 'show c'; they could even be ++mouse-clicks or menu items--whatever suits your program. ++ ++You should also get your employer (if you work as a programmer) or your ++school, if any, to sign a "copyright disclaimer" for the program, if ++necessary. Here is a sample; alter the names: ++ ++Yoyodyne, Inc., hereby disclaims all copyright interest in the program ++'Gnomovision' (which makes passes at compilers) written by James Hacker. ++ ++signature of Ty Coon, 1 April 1989 ++Ty Coon, President of Vice ++ ++This General Public License does not permit incorporating your program into ++proprietary programs. If your program is a subroutine library, you may ++consider it more useful to permit linking proprietary applications with the ++library. If this is what you want to do, use the GNU Library General Public ++License instead of this License. +diff -Nurp linux-2.6.37/3rdparty/rfswitch/Makefile linux-2.6.37.3rdparty/3rdparty/rfswitch/Makefile +--- linux-2.6.37/3rdparty/rfswitch/Makefile 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/rfswitch/Makefile 2008-03-28 05:17:16.000000000 +0200 +@@ -0,0 +1,119 @@ ++# ++# Makefile for the SW RF Switch kernel modules ++# ++# NOTE: This make file can serve as both an external Makefile (launched ++# directly by the user), or as the sub-dir Makefile used by the kernel ++# build system. ++ ++ ++CONFIG_AVERATEC_5100P=m ++CONFIG_PACKARDBELL_E5=m ++ ++ ++ ++list-m := ++list-$(CONFIG_AVERATEC_5100P) += av5100 ++list-$(CONFIG_PACKARDBELL_E5) += pbe5 ++ ++ ++obj-$(CONFIG_AVERATEC_5100P) += av5100.o ++obj-$(CONFIG_PACKARDBELL_E5) += pbe5.o ++ ++# ++# Begin dual Makefile mode here. First we provide support for when we ++# are being invoked by the kernel build system ++# ++ifneq ($(KERNELRELEASE),) ++ ++ifneq ($(PATCHLEVEL),6) # If we are not on a 2.6, then do 2.4 specific things ++ ++O_TARGET := rfswitch.o ++ ++include $(TOPDIR)/Rules.make ++ ++endif # End if 2.4 specific settings ++ ++else ++# Here we begin the portion that is executed if the user invoked this Makefile ++# directly. ++ ++# KSRC should be set to the path to your sources ++# modules are installed into KMISC ++KVER := $(shell uname -r) ++KSRC := /lib/modules/$(KVER)/build ++KMISC := /lib/modules/$(KVER)/kernel/drivers/net/wireless/ ++ ++# KSRC_OUTPUT should be overridden if you are using a 2.6 kernel that ++# has it's output sent elsewhere via KBUILD_OUTPUT= or O= ++KSRC_OUTPUT := $(KSRC) ++ ++# If we find Rules.make, we can assume we're using the old 2.4 style building ++OLDMAKE=$(wildcard $(KSRC)/Rules.make) ++PWD=$(shell pwd) ++ ++VERFILE := $(KSRC_OUTPUT)/include/linux/version.h ++KERNELRELEASE := $(shell \ ++ if [ -r $(VERFILE) ]; then \ ++ (cat $(VERFILE); echo UTS_RELEASE) | \ ++ $(CC) -I$(KSRC_OUTPUT) $(CFLAGS) -E - | \ ++ tail -n 1 | \ ++ xargs echo; \ ++ else \ ++ uname -r; \ ++ fi) ++ ++MODPATH := $(DESTDIR)/lib/modules/$(KERNELRELEASE) ++ ++all: modules ++ ++clean: ++ rm -f *.mod.c *.mod *.o *.ko .*.cmd .*.flags Modules.symvers ++ rm -rf $(PWD)/tmp ++ ++ ++ifeq ($(OLDMAKE),) ++ ++TMP=$(PWD)/tmp ++MODVERDIR=$(TMP)/.tmp_versions ++ ++modules: ++ifdef ($(KSRC_OUTPUT)/.tmp_versions) ++ mkdir -p $(MODVERDIR) ++ -cp $(KSRC_OUTPUT)/.tmp_versions/*.mod $(MODVERDIR) ++endif ++ifeq ($(KSRC),$(KSRC_OUTPUT)) # We're not outputting elsewhere ++ifdef ($(KSRC)/.tmp_versions) ++ -cp $(KSRC)/.tmp_versions/*.mod $(MODVERDIR) ++endif ++ $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) MODVERDIR=$(MODVERDIR) modules ++else # We've got a kernel with seperate output, copy the config, and use O= ++ mkdir -p $(TMP) ++ cp $(KSRC_OUTPUT)/.config $(TMP) ++ $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) MODVERDIR=$(MODVERDIR) O=$(PWD)/tmp modules ++endif ++ ++install: modules ++ install -d $(KMISC) ++ install -m 644 -c $(addsuffix .ko,$(list-m)) $(KMISC) ++ /sbin/depmod -a ++ ++ ++else # We're on 2.4, and things are slightly different ++ ++modules: ++ $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) BUILD_DIR=$(PWD) modules ++ ++install: modules ++ install -d $(KMISC) ++ install -m 644 -c $(addsuffix .o,$(list-m)) $(KMISC) ++ /sbin/depmod -a ++ ++endif ++ ++uninstall: ++ cd $(KMISC) ++ rm -rf $(addsuffix .ko,$(list-m)) ++ cd - ++ /sbin/depmod -a ++ ++endif +diff -Nurp linux-2.6.37/3rdparty/rfswitch/pbe5.c linux-2.6.37.3rdparty/3rdparty/rfswitch/pbe5.c +--- linux-2.6.37/3rdparty/rfswitch/pbe5.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/rfswitch/pbe5.c 2008-03-28 05:25:16.000000000 +0200 +@@ -0,0 +1,205 @@ ++/******************************************************************************* ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms of version 2 of the GNU General Public License as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ more details. ++ ++ You should have received a copy of the GNU General Public License along with ++ this program; if not, write to the Free Software Foundation, Inc., 59 ++ Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ ++ The full GNU General Public License is included in this distribution in the ++ file called LICENSE. ++ ++ Author: ++ Pedro Ramalhais ++ ++ Based on: ++ av5100.c from http://ipw2100.sourceforge.net/ ++ ++*******************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DRV_NAME "pbe5" ++#define DRV_VERSION "1.3" ++#define DRV_DESCRIPTION "SW RF kill switch for Packard Bell EasyNote E5" ++#define DRV_AUTHOR "Pedro Ramalhais" ++#define DRV_LICENSE "GPL" ++ ++static int radio = 1; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ++ ++MODULE_PARM(radio, "i"); ++ ++#else /* LINUX_VERSION_CODE < 2.6.0 */ ++ ++#include ++module_param(radio, int, 1); ++ ++#endif /* LINUX_VERSION_CODE < 2.6.0 */ ++ ++MODULE_PARM_DESC(radio, "controls state of radio (1=on, 0=off)"); ++ ++MODULE_DESCRIPTION(DRV_DESCRIPTION); ++MODULE_AUTHOR(DRV_AUTHOR); ++MODULE_LICENSE(DRV_LICENSE); ++ ++/* ++ * NOTE: These values were obtained from disassembling the Icon.exe program ++ * installed in the Packard Bell EasyNote E5 laptop. The names were guessed, ++ * so don't rely on them. ++ */ ++#define PBE5_PORT_TOGGLE 0x0b3 ++#define PBE5_VALUE_TOGGLE_ON 0x01 ++#define PBE5_VALUE_TOGGLE_OFF 0x00 ++#define PBE5_PORT_APPLY 0x0b2 ++#define PBE5_VALUE_APPLY 0xef ++ ++// Some "booleans" =;-) ++#define PBE5_RADIO_OFF 0 ++#define PBE5_RADIO_ON 1 ++ ++static int pbe5_radio_status = PBE5_RADIO_ON; ++ ++unsigned char pbe5_get_radio(void) ++{ ++ unsigned char val = 0x00; ++ ++ val = inb(PBE5_PORT_TOGGLE); ++ ++ return val; ++} ++ ++static void pbe5_set_radio(int state_set) ++{ ++ pbe5_radio_status = pbe5_get_radio(); ++ ++ if (pbe5_radio_status != state_set) { ++ // Set the radio toggle register ++ outb(PBE5_VALUE_TOGGLE_ON, PBE5_PORT_TOGGLE); ++ // Commit the radio toggle register value ++ outb(PBE5_VALUE_APPLY, PBE5_PORT_APPLY); ++ // Update the radio status ++ pbe5_radio_status = pbe5_get_radio(); ++ ++ printk(KERN_INFO DRV_NAME ": Radio turned %s\n", ++ (state_set == PBE5_RADIO_ON) ? "ON" : "OFF"); ++ } else { ++ printk(KERN_INFO DRV_NAME ": Radio already %s\n", ++ (state_set == PBE5_RADIO_ON) ? "ON" : "OFF"); ++ } ++} ++ ++ ++/* ++ * proc stuff ++ */ ++static struct proc_dir_entry *dir_base = NULL; ++ ++static int proc_set_radio(struct file *file, const char *buffer, ++ unsigned long count, void *data) ++{ ++ pbe5_set_radio(buffer[0] == '0' ? PBE5_RADIO_OFF : PBE5_RADIO_ON); ++ ++ return count; ++} ++ ++static int proc_get_radio(char *page, char **start, off_t offset, ++ int count, int *eof, void *data) ++{ ++ int len = 0; ++ ++ len += snprintf(page, count, DRV_NAME ": %d\n", ++ pbe5_radio_status == PBE5_RADIO_OFF ? 0 : 1); ++ ++ *eof = 1; ++ return len; ++} ++ ++ ++static void pbe5_proc_cleanup(void) ++{ ++ if (dir_base) { ++ remove_proc_entry("radio", dir_base); ++ remove_proc_entry(DRV_NAME, &proc_root); ++ dir_base = NULL; ++ } ++} ++ ++ ++static int pbe5_proc_init(void) ++{ ++ struct proc_dir_entry *ent; ++ int err = 0; ++ ++ dir_base = create_proc_entry(DRV_NAME, S_IFDIR, &proc_root); ++ if (dir_base == NULL) { ++ printk(KERN_ERR DRV_NAME ": Unable to initialise /proc/" ++ DRV_NAME "\n"); ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ ++ ent = create_proc_entry("radio", S_IFREG | S_IRUGO | S_IWUSR, ++ dir_base); ++ if (ent) { ++ ent->read_proc = proc_get_radio; ++ ent->write_proc = proc_set_radio; ++ } else { ++ printk(KERN_ERR ++ "Unable to initialize /proc/" DRV_NAME "/radio\n"); ++ err = -ENOMEM; ++ goto fail; ++ } ++ ++ return 0; ++ ++ fail: ++ pbe5_proc_cleanup(); ++ return err; ++} ++ ++/* ++ * module stuff ++ */ ++static int __init pbe5_init(void) ++{ ++ pbe5_proc_init(); ++ ++ pbe5_set_radio((radio == 1) ? PBE5_RADIO_ON : PBE5_RADIO_OFF); ++ ++ return 0; ++} ++ ++static void __exit pbe5_exit(void) ++{ ++ pbe5_set_radio(PBE5_RADIO_OFF); ++ ++ pbe5_proc_cleanup(); ++} ++ ++module_init(pbe5_init); ++module_exit(pbe5_exit); ++ ++/* ++ 1 2 3 4 5 6 7 ++12345678901234567890123456789012345678901234567890123456789012345678901234567890 ++*/ +diff -Nurp linux-2.6.37/3rdparty/rfswitch/README linux-2.6.37.3rdparty/3rdparty/rfswitch/README +--- linux-2.6.37/3rdparty/rfswitch/README 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/rfswitch/README 2004-07-09 17:26:20.000000000 +0300 +@@ -0,0 +1,44 @@ ++Radio Kill Switch ++------------ ----- ----- ---- --- -- - ++Most laptops provide the ability for the user to physically disable the radio. ++Some vendors have implemented this as a physical switch that requires no ++software to turn the radio off and on. On other laptops, however, the switch ++is controlled through a button being pressed and a software driver then making ++calls to turn the radio off and on. This is referred to as a "software based ++RF kill switch" ++ ++Currently this project provides modules for controlling the software RF kill ++switch on the Averatec 5100P and Packard Bell EasyNote E5. The code may work ++on other laptops, but these are the only models on which it has been tested. ++ ++To determine if you have a system that might be compatible with one of the ++provided SW RF Kill switch modules, you can run: ++ ++ ++ To check for the Packard Bell (to use module pbe) -- ++ ++ % dd if=/dev/mem bs=1 skip=983040 count=65535 2>/dev/null | strings | egrep "NEW-PC|Insyde Software MobilePRO BIOS" ++ ++ To check for the Averatec (to use module av5100) -- ++ ++ % dd if=/dev/mem bs=1 skip=983040 count=65535 2>/dev/null | strings | egrep "AVERATEC" ++ ++If you have one of those laptop models you can imply loading the av5100/pbe5 ++module and the radio will be toggled on and off. In addition, you can turn ++the driver on and off by writing either a 1 or 0 to /proc/av5100/radio or ++/proc/pbe5/radio. If you automatically load the av5100/pbe5 module when your ++system boots, you may wish to use the radio module parameter to control the ++state of the radio upon loading: ++ ++ modprobe av5100 radio=0 ++ modprobe pbe5 radio=0 ++ ++results in the module loading with the radio turned off. You can then turn the ++radio on by: ++ ++ echo 1 > /proc/av5100/radio ++ echo 1 > /proc/pbe5/radio ++ ++If you have a SW RF kill switch and can not use one of the above modules, ++please join us on IRC (irc.freenode.net) on channel #ipw2100 and someone may ++be able to help. diff --git a/kernel/kernel/files/patches/mageia/3rd-rfswitch-3.0-buildfix.patch b/kernel/kernel/files/patches/mageia/3rd-rfswitch-3.0-buildfix.patch new file mode 100644 index 00000000..7bfc2c64 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-rfswitch-3.0-buildfix.patch @@ -0,0 +1,19 @@ + +fix build with 3.0 + +Signed-off-by: Thomas Backlund + + 3rdparty/rfswitch/Makefile | 2 -- + 1 file changed, 2 deletions(-) + +--- a/3rdparty/rfswitch/Makefile.orig 2011-07-15 02:37:27.000000000 +0300 ++++ a/3rdparty/rfswitch/Makefile 2011-07-15 13:47:10.463914526 +0300 +@@ -29,8 +29,6 @@ ifneq ($(PATCHLEVEL),6) # If we are not + + O_TARGET := rfswitch.o + +-include $(TOPDIR)/Rules.make +- + endif # End if 2.4 specific settings + + else diff --git a/kernel/kernel/files/patches/mageia/3rd-rfswitch-build-fix.patch b/kernel/kernel/files/patches/mageia/3rd-rfswitch-build-fix.patch new file mode 100644 index 00000000..ab1c279c --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-rfswitch-build-fix.patch @@ -0,0 +1,51 @@ +Remove 'proc_root' usage + +Commit c74c120a21d87b0b6925ada5830d8cac21e852d9 (Linus's tree) removed +the export of 'proc_root' variable, because you can create on the proc's +root directory by passing NULL where you would pass 'proc_root'. + +Signed-off-by: Luiz Fernando N. Capitulino +Index: linux-2.6.25/3rdparty/rfswitch/av5100.c +=================================================================== +--- linux-2.6.25.orig/3rdparty/rfswitch/av5100.c ++++ linux-2.6.25/3rdparty/rfswitch/av5100.c +@@ -107,7 +107,7 @@ static void av5100_proc_cleanup(void) + { + if (dir_base) { + remove_proc_entry("radio", dir_base); +- remove_proc_entry(DRV_NAME, &proc_root); ++ remove_proc_entry(DRV_NAME, NULL); + dir_base = NULL; + } + } +@@ -118,7 +118,7 @@ static int av5100_proc_init(void) + struct proc_dir_entry *ent; + int err = 0; + +- dir_base = create_proc_entry(DRV_NAME, S_IFDIR, &proc_root); ++ dir_base = create_proc_entry(DRV_NAME, S_IFDIR, NULL); + if (dir_base == NULL) { + printk(KERN_ERR DRV_NAME ": Unable to initialise /proc/" + DRV_NAME "\n"); +Index: linux-2.6.25/3rdparty/rfswitch/pbe5.c +=================================================================== +--- linux-2.6.25.orig/3rdparty/rfswitch/pbe5.c ++++ linux-2.6.25/3rdparty/rfswitch/pbe5.c +@@ -138,7 +138,7 @@ static void pbe5_proc_cleanup(void) + { + if (dir_base) { + remove_proc_entry("radio", dir_base); +- remove_proc_entry(DRV_NAME, &proc_root); ++ remove_proc_entry(DRV_NAME, NULL); + dir_base = NULL; + } + } +@@ -149,7 +149,7 @@ static int pbe5_proc_init(void) + struct proc_dir_entry *ent; + int err = 0; + +- dir_base = create_proc_entry(DRV_NAME, S_IFDIR, &proc_root); ++ dir_base = create_proc_entry(DRV_NAME, S_IFDIR, NULL); + if (dir_base == NULL) { + printk(KERN_ERR DRV_NAME ": Unable to initialise /proc/" + DRV_NAME "\n"); diff --git a/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-buildfix.patch b/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-buildfix.patch new file mode 100644 index 00000000..61c96c46 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-buildfix.patch @@ -0,0 +1,23 @@ +From 842e61cb85813b1ed8a1646cbe6739950c0c9822 Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Thu, 7 May 2015 19:08:17 +0000 +Subject: [PATCH] rtl8723bs: Fix Makefile to allow warnings + +Signed-off-by: Larry Finger +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git linux.old/3rdparty/rtl8723bs/Makefile linux/3rdparty/rtl8723bs/Makefile +index a4d9f45..4da73fa 100644 +--- linux.old/3rdparty/rtl8723bs/Makefile ++++ linux/3rdparty/rtl8723bs/Makefile +@@ -3,7 +3,7 @@ EXTRA_CFLAGS += -O1 + #EXTRA_CFLAGS += -O3 + #EXTRA_CFLAGS += -Wall + #EXTRA_CFLAGS += -Wextra +-EXTRA_CFLAGS += -Werror ++#EXTRA_CFLAGS += -Werror + #EXTRA_CFLAGS += -pedantic + #EXTRA_CFLAGS += -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes + diff --git a/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-revert-4.0-changes.patch b/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-revert-4.0-changes.patch new file mode 100644 index 00000000..fbea7652 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-revert-4.0-changes.patch @@ -0,0 +1,73 @@ + +This reverts the parts of: + +commit 86fe2db84ba7b9a83b60323cd805198ff43136ec +Author: Bastien Nocera +Date: Fri Mar 20 18:28:08 2015 +0100 + + cfg80211: Update for newest mac80211 API + + +that breaks building with 3.19 series kernels. + + + +Signed-off-by: Thomas Backlund + + +diff -Nurp linux/3rdparty/rtl8723bs.rev/include/ioctl_cfg80211.h linux/3rdparty/rtl8723bs/include/ioctl_cfg80211.h +--- linux/3rdparty/rtl8723bs.rev/include/ioctl_cfg80211.h 2015-05-07 17:46:55.000000000 +0300 ++++ linux/3rdparty/rtl8723bs/include/ioctl_cfg80211.h 2015-05-10 14:55:44.744038033 +0300 +@@ -22,10 +22,6 @@ + + #include + +-#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) +-#error This driver only works with kernel 4.0 +-#endif +- + struct rtw_wdev_invit_info { + u8 state; /* 0: req, 1:rep */ + u8 peer_mac[ETH_ALEN]; +diff -Nurp linux/3rdparty/rtl8723bs.rev/os_dep/ioctl_cfg80211.c linux/3rdparty/rtl8723bs/os_dep/ioctl_cfg80211.c +--- linux/3rdparty/rtl8723bs.rev/os_dep/ioctl_cfg80211.c 2015-05-10 14:54:53.241616597 +0300 ++++ linux/3rdparty/rtl8723bs/os_dep/ioctl_cfg80211.c 2015-05-10 14:49:42.766354711 +0300 +@@ -1289,16 +1289,16 @@ static int cfg80211_rtw_get_station(stru + goto exit; + } + +- sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); ++ sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength); + +- sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); ++ sinfo->filled |= STATION_INFO_TX_BITRATE; + sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter); + +- sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); ++ sinfo->filled |= STATION_INFO_RX_PACKETS; + sinfo->rx_packets = sta_rx_data_pkts(psta); + +- sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); ++ sinfo->filled |= STATION_INFO_TX_PACKETS; + sinfo->tx_packets = psta->sta_stats.tx_pkts; + + } +@@ -2473,6 +2473,7 @@ void rtw_cfg80211_indicate_sta_assoc(_ad + ie_offset = _REASOCREQ_IE_OFFSET_; + + sinfo.filled = 0; ++ sinfo.filled = STATION_INFO_ASSOC_REQ_IES; + sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset; + sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset; + cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC); +@@ -3078,7 +3079,8 @@ static int cfg80211_rtw_dump_station(str + goto exit; + } + memcpy(mac, psta->hwaddr, ETH_ALEN); +- sinfo->filled = BIT(NL80211_STA_INFO_SIGNAL); ++ sinfo->filled = 0; ++ sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = psta->rssi; + + exit: diff --git a/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-updates.patch b/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-updates.patch new file mode 100644 index 00000000..a620e888 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-rtl8723bs-updates.patch @@ -0,0 +1,28991 @@ + +Updates / cleanups from: + +git://github.com/hadess/rtl8723bs.git + +Topmost commit: + +commit 8d329c00dba5d8805a738ecea2bddde8eb0e4945 +Author: Bastien Nocera +Date: Tue May 5 18:30:38 2015 +0200 + + ioctl_linux: Fix compiling with Wake-On-LAN support + + + +Signed-off-by: Thomas backlund + +diff -Nurp linux/3rdparty/rtl8723bs.old/core/rtw_ap.c linux/3rdparty/rtl8723bs/core/rtw_ap.c +--- linux/3rdparty/rtl8723bs.old/core/rtw_ap.c 2015-05-10 14:36:05.663667846 +0300 ++++ linux/3rdparty/rtl8723bs/core/rtw_ap.c 2015-05-07 17:46:55.000000000 +0300 +@@ -21,9 +21,6 @@ + + #include + +- +-#ifdef CONFIG_AP_MODE +- + extern unsigned char RTW_WPA_OUI[]; + extern unsigned char WMM_OUI[]; + extern unsigned char WPS_OUI[]; +@@ -32,7 +29,6 @@ extern unsigned char WFD_OUI[]; + + void init_mlme_ap_info(_adapter *padapter) + { +- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + struct sta_priv *pstapriv = &padapter->stapriv; + struct wlan_acl_pool *pacl_list = &pstapriv->acl_list; +@@ -71,9 +67,9 @@ void free_mlme_ap_info(_adapter *padapte + + //free bc/mc sta_info + psta = rtw_get_bcmc_stainfo(padapter); +- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); ++ spin_lock_bh(&(pstapriv->sta_hash_lock)); + rtw_free_stainfo(padapter, psta); +- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); ++ spin_unlock_bh(&(pstapriv->sta_hash_lock)); + } + + static void update_BCNTIM(_adapter *padapter) +@@ -191,7 +187,7 @@ static void update_BCNTIM(_adapter *pada + { + memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); + +- rtw_mfree(pbackup_remainder_ie, remainder_ielen); ++ kfree(pbackup_remainder_ie); + } + + offset = (uint)(dst_ie - pie); +@@ -200,122 +196,6 @@ static void update_BCNTIM(_adapter *pada + } + } + +-void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len) +-{ +- PNDIS_802_11_VARIABLE_IEs pIE; +- u8 bmatch = false; +- u8 *pie = pnetwork->IEs; +- u8 *p=NULL, *dst_ie=NULL, *premainder_ie=NULL, *pbackup_remainder_ie=NULL; +- u32 i, offset, ielen, ie_offset, remainder_ielen = 0; +- +- for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;) +- { +- pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i); +- +- if (pIE->ElementID > index) +- { +- break; +- } +- else if(pIE->ElementID == index) // already exist the same IE +- { +- p = (u8 *)pIE; +- ielen = pIE->Length; +- bmatch = true; +- break; +- } +- +- p = (u8 *)pIE; +- ielen = pIE->Length; +- i += (pIE->Length + 2); +- } +- +- if (p != NULL && ielen>0) +- { +- ielen += 2; +- +- premainder_ie = p+ielen; +- +- ie_offset = (sint)(p -pie); +- +- remainder_ielen = pnetwork->IELength - ie_offset - ielen; +- +- if(bmatch) +- dst_ie = p; +- else +- dst_ie = (p+ielen); +- } +- +- if(dst_ie == NULL) +- return; +- +- if(remainder_ielen>0) +- { +- pbackup_remainder_ie = rtw_malloc(remainder_ielen); +- if(pbackup_remainder_ie && premainder_ie) +- memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); +- } +- +- *dst_ie++=index; +- *dst_ie++=len; +- +- memcpy(dst_ie, data, len); +- dst_ie+=len; +- +- //copy remainder IE +- if(pbackup_remainder_ie) +- { +- memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); +- +- rtw_mfree(pbackup_remainder_ie, remainder_ielen); +- } +- +- offset = (uint)(dst_ie - pie); +- pnetwork->IELength = offset + remainder_ielen; +-} +- +-void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index) +-{ +- u8 *p, *dst_ie=NULL, *premainder_ie=NULL, *pbackup_remainder_ie=NULL; +- uint offset, ielen, ie_offset, remainder_ielen = 0; +- u8 *pie = pnetwork->IEs; +- +- p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_); +- if (p != NULL && ielen>0) +- { +- ielen += 2; +- +- premainder_ie = p+ielen; +- +- ie_offset = (sint)(p -pie); +- +- remainder_ielen = pnetwork->IELength - ie_offset - ielen; +- +- dst_ie = p; +- } +- else { +- return; +- } +- +- if(remainder_ielen>0) +- { +- pbackup_remainder_ie = rtw_malloc(remainder_ielen); +- if(pbackup_remainder_ie && premainder_ie) +- memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); +- } +- +- //copy remainder IE +- if(pbackup_remainder_ie) +- { +- memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen); +- +- rtw_mfree(pbackup_remainder_ie, remainder_ielen); +- } +- +- offset = (uint)(dst_ie - pie); +- pnetwork->IELength = offset + remainder_ielen; +-} +- +- + u8 chk_sta_is_alive(struct sta_info *psta); + u8 chk_sta_is_alive(struct sta_info *psta) + { +@@ -349,19 +229,19 @@ void expire_timeout_chk(_adapter *padapt + int i; + + +- _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); ++ spin_lock_bh(&pstapriv->auth_list_lock); + + phead = &pstapriv->auth_list; + plist = get_next(phead); + + //check auth_queue + #ifdef DBG_EXPIRATION_CHK +- if (rtw_end_of_queue_search(phead, plist) == false) { ++ if (phead != plist) { + DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n" + , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt); + } + #endif +- while ((rtw_end_of_queue_search(phead, plist)) == false) ++ while (phead != plist) + { + psta = LIST_CONTAINOR(plist, struct sta_info, auth_list); + +@@ -372,41 +252,41 @@ void expire_timeout_chk(_adapter *padapt + psta->expire_to--; + if (psta->expire_to == 0) + { +- rtw_list_delete(&psta->auth_list); ++ list_del_init(&psta->auth_list); + pstapriv->auth_list_cnt--; + + DBG_871X("auth expire %02X%02X%02X%02X%02X%02X\n", + psta->hwaddr[0],psta->hwaddr[1],psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]); + +- _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); ++ spin_unlock_bh(&pstapriv->auth_list_lock); + +- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); ++ spin_lock_bh(&(pstapriv->sta_hash_lock)); + rtw_free_stainfo(padapter, psta); +- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); ++ spin_unlock_bh(&(pstapriv->sta_hash_lock)); + +- _enter_critical_bh(&pstapriv->auth_list_lock, &irqL); ++ spin_lock_bh(&pstapriv->auth_list_lock); + } + } + + } + +- _exit_critical_bh(&pstapriv->auth_list_lock, &irqL); ++ spin_unlock_bh(&pstapriv->auth_list_lock); + psta = NULL; + + +- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ spin_lock_bh(&pstapriv->asoc_list_lock); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //check asoc_queue + #ifdef DBG_EXPIRATION_CHK +- if (rtw_end_of_queue_search(phead, plist) == false) { ++ if (phead != plist) { + DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n" + , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt); + } + #endif +- while ((rtw_end_of_queue_search(phead, plist)) == false) ++ while (phead != plist) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + plist = get_next(plist); +@@ -417,14 +297,13 @@ void expire_timeout_chk(_adapter *padapt + if (chk_sta_is_alive(psta) || !psta->expire_to) { + psta->expire_to = pstapriv->expire_to; + psta->keep_alive_trycnt = 0; +- #ifdef CONFIG_TX_MCAST2UNI + psta->under_exist_checking = 0; +- #endif // CONFIG_TX_MCAST2UNI + } else { +- psta->expire_to--; ++ if (psta->expire_to > 0) ++ psta->expire_to--; + } + +- if (psta->expire_to <= 0) ++ if (psta->expire_to == 0) + { + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + +@@ -460,7 +339,7 @@ void expire_timeout_chk(_adapter *padapt + + continue; + } +- rtw_list_delete(&psta->asoc_list); ++ list_del_init(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state); + updated = ap_free_sta(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING); +@@ -479,7 +358,7 @@ void expire_timeout_chk(_adapter *padapt + } + } + +- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ spin_unlock_bh(&pstapriv->asoc_list_lock); + + if (chk_alive_num) { + +@@ -521,13 +400,13 @@ if (chk_alive_num) { + + psta->keep_alive_trycnt = 0; + DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state); +- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); +- if (rtw_is_list_empty(&psta->asoc_list)==false) { +- rtw_list_delete(&psta->asoc_list); ++ spin_lock_bh(&pstapriv->asoc_list_lock); ++ if (list_empty(&psta->asoc_list)==false) { ++ list_del_init(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + updated = ap_free_sta(padapter, psta, false, WLAN_REASON_DEAUTH_LEAVING); + } +- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ spin_unlock_bh(&pstapriv->asoc_list_lock); + + } + +@@ -544,13 +423,10 @@ void add_RATid(_adapter *padapter, struc + u8 rf_type; + unsigned char sta_band = 0, shortGIrate = false; + unsigned int tx_ra_bitmap=0; +- struct ht_priv *psta_ht = NULL; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; + +- if(psta) +- psta_ht = &psta->htpriv; +- else ++ if(!psta) + return; + + if(!(psta->state & _FW_LINKED)) +@@ -672,9 +548,9 @@ void update_bmc_sta(_adapter *padapter) + + rtw_sta_media_status_rpt(padapter, psta, 1); + +- _enter_critical_bh(&psta->lock, &irqL); ++ spin_lock_bh(&psta->lock); + psta->state = _FW_LINKED; +- _exit_critical_bh(&psta->lock, &irqL); ++ spin_unlock_bh(&psta->lock); + + } + else +@@ -815,9 +691,9 @@ void update_sta_info_apmode(_adapter *pa + //add_RATid(padapter, psta);//move to ap_sta_info_defer_update() + + +- _enter_critical_bh(&psta->lock, &irqL); ++ spin_lock_bh(&psta->lock); + psta->state |= _FW_LINKED; +- _exit_critical_bh(&psta->lock, &irqL); ++ spin_unlock_bh(&psta->lock); + + + } +@@ -826,7 +702,6 @@ static void update_ap_info(_adapter *pad + { + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; +- struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv; + +@@ -875,7 +750,6 @@ static void update_hw_ht_param(_adapter + { + unsigned char max_AMPDU_len; + unsigned char min_MPDU_spacing; +- struct registry_priv *pregpriv = &padapter->registrypriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + +@@ -933,8 +807,7 @@ void start_bss_network(_adapter *padapte + WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network); + struct HT_info_element *pht_info=NULL; + u8 cbw40_enable=0; +- u8 change_band = false; +- ++ + //DBG_871X("%s\n", __FUNCTION__); + + bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod; +@@ -1114,15 +987,12 @@ int rtw_check_beacon_data(_adapter *pada + u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX]; + int supportRateNum = 0; + u8 OUI1[] = {0x00, 0x50, 0xf2,0x01}; +- u8 wps_oui[4]={0x0,0x50,0xf2,0x04}; + u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); + WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network; +- struct sta_priv *pstapriv = &padapter->stapriv; + u8 *ie = pbss_network->IEs; +- u8 vht_cap=false; + + /* SSID */ + /* Supported rates */ +@@ -1483,12 +1353,12 @@ int rtw_acl_add_sta(_adapter *padapter, + return (-1); + + +- _enter_critical_bh(&(pacl_node_q->lock), &irqL); ++ spin_lock_bh(&(pacl_node_q->lock)); + + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + +- while ((rtw_end_of_queue_search(phead, plist)) == false) ++ while (phead != plist) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); +@@ -1504,14 +1374,14 @@ int rtw_acl_add_sta(_adapter *padapter, + } + } + +- _exit_critical_bh(&(pacl_node_q->lock), &irqL); ++ spin_unlock_bh(&(pacl_node_q->lock)); + + + if(added == true) + return ret; + + +- _enter_critical_bh(&(pacl_node_q->lock), &irqL); ++ spin_lock_bh(&(pacl_node_q->lock)); + + for(i=0; i< NUM_ACL; i++) + { +@@ -1519,13 +1389,13 @@ int rtw_acl_add_sta(_adapter *padapter, + + if(paclnode->valid == false) + { +- _rtw_init_listhead(&paclnode->list); ++ INIT_LIST_HEAD(&paclnode->list); + + memcpy(paclnode->addr, addr, ETH_ALEN); + + paclnode->valid = true; + +- rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q)); ++ list_add_tail(&paclnode->list, get_list_head(pacl_node_q)); + + pacl_list->num++; + +@@ -1535,7 +1405,7 @@ int rtw_acl_add_sta(_adapter *padapter, + + DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num); + +- _exit_critical_bh(&(pacl_node_q->lock), &irqL); ++ spin_unlock_bh(&(pacl_node_q->lock)); + + return ret; + } +@@ -1553,12 +1423,12 @@ int rtw_acl_remove_sta(_adapter *padapte + + DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr)); + +- _enter_critical_bh(&(pacl_node_q->lock), &irqL); ++ spin_lock_bh(&(pacl_node_q->lock)); + + phead = get_list_head(pacl_node_q); + plist = get_next(phead); + +- while ((rtw_end_of_queue_search(phead, plist)) == false) ++ while (phead != plist) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); +@@ -1569,14 +1439,14 @@ int rtw_acl_remove_sta(_adapter *padapte + { + paclnode->valid = false; + +- rtw_list_delete(&paclnode->list); ++ list_del_init(&paclnode->list); + + pacl_list->num--; + } + } + } + +- _exit_critical_bh(&(pacl_node_q->lock), &irqL); ++ spin_unlock_bh(&(pacl_node_q->lock)); + + DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num); + +@@ -1599,7 +1469,7 @@ u8 rtw_ap_set_pairwise_key(_adapter *pad + + psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm)); + if(psetstakey_para==NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); ++ kfree((u8 *) ph2c); + res=_FAIL; + goto exit; + } +@@ -1639,7 +1509,7 @@ static int rtw_ap_set_key(_adapter *pada + } + psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm)); + if(psetkeyparm==NULL){ +- rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)pcmd); + res= _FAIL; + goto exit; + } +@@ -1678,7 +1548,7 @@ static int rtw_ap_set_key(_adapter *pada + pcmd->rspsz = 0; + + +- _rtw_init_listhead(&pcmd->list); ++ INIT_LIST_HEAD(&pcmd->list); + + res = rtw_enqueue_cmd(pcmdpriv, pcmd); + +@@ -1715,8 +1585,6 @@ int rtw_ap_set_wep_key(_adapter *padapte + return rtw_ap_set_key(padapter, key, alg, keyid, set_tx); + } + +-#ifdef CONFIG_NATIVEAP_MLME +- + static void update_bcn_fixed_ie(_adapter *padapter) + { + DBG_871X("%s\n", __FUNCTION__); +@@ -1838,7 +1706,7 @@ static void update_bcn_wps_ie(_adapter * + } + + if(pbackup_remainder_ie) +- rtw_mfree(pbackup_remainder_ie, remainder_ielen); ++ kfree(pbackup_remainder_ie); + + // deal with the case without set_tx_beacon_cmd() in update_beacon() + #if defined( CONFIG_INTERRUPT_BASED_TXBCN ) +@@ -1907,7 +1775,7 @@ void update_beacon(_adapter *padapter, u + if(false == pmlmeext->bstart_bss) + return; + +- _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL); ++ spin_lock_bh(&pmlmepriv->bcn_update_lock); + + switch(ie_id) + { +@@ -1959,7 +1827,7 @@ void update_beacon(_adapter *padapter, u + + pmlmepriv->update_bcn = true; + +- _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL); ++ spin_unlock_bh(&pmlmepriv->bcn_update_lock); + + #ifndef CONFIG_INTERRUPT_BASED_TXBCN + if(tx) +@@ -2064,13 +1932,13 @@ void associated_clients_update(_adapter + struct sta_info *psta=NULL; + struct sta_priv *pstapriv = &padapter->stapriv; + +- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ spin_lock_bh(&pstapriv->asoc_list_lock); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //check asoc_queue +- while ((rtw_end_of_queue_search(phead, plist)) == false) ++ while (phead != plist) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + +@@ -2079,7 +1947,7 @@ void associated_clients_update(_adapter + VCS_update(padapter, psta); + } + +- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ spin_unlock_bh(&pstapriv->asoc_list_lock); + + } + +@@ -2332,8 +2200,6 @@ u8 ap_free_sta(_adapter *padapter, struc + { + _irqL irqL; + u8 beacon_updated = false; +- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); +- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct sta_priv *pstapriv = &padapter->stapriv; + + if(!psta) +@@ -2360,9 +2226,9 @@ u8 ap_free_sta(_adapter *padapter, struc + rtw_clearstakey_cmd(padapter, psta, true); + + +- _enter_critical_bh(&psta->lock, &irqL); ++ spin_lock_bh(&psta->lock); + psta->state &= ~_FW_LINKED; +- _exit_critical_bh(&psta->lock, &irqL); ++ spin_unlock_bh(&psta->lock); + + rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason); + +@@ -2370,52 +2236,15 @@ u8 ap_free_sta(_adapter *padapter, struc + + beacon_updated = bss_cap_update_on_sta_leave(padapter, psta); + +- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); ++ spin_lock_bh(&(pstapriv->sta_hash_lock)); + rtw_free_stainfo(padapter, psta); +- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); ++ spin_unlock_bh(&(pstapriv->sta_hash_lock)); + + + return beacon_updated; + + } + +-int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset) +-{ +- _irqL irqL; +- _list *phead, *plist; +- int ret=0; +- struct sta_info *psta = NULL; +- struct sta_priv *pstapriv = &padapter->stapriv; +- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; +- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); +- u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; +- +- if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) +- return ret; +- +- DBG_871X(FUNC_NDEV_FMT" with ch:%u, offset:%u\n", +- FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset); +- +- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); +- phead = &pstapriv->asoc_list; +- plist = get_next(phead); +- +- /* for each sta in asoc_queue */ +- while ((rtw_end_of_queue_search(phead, plist)) == false) +- { +- psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); +- plist = get_next(plist); +- +- issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset); +- psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2); +- } +- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); +- +- issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset); +- +- return ret; +-} +- + int rtw_sta_flush(_adapter *padapter) + { + _irqL irqL; +@@ -2433,25 +2262,25 @@ int rtw_sta_flush(_adapter *padapter) + return ret; + + +- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ spin_lock_bh(&pstapriv->asoc_list_lock); + phead = &pstapriv->asoc_list; + plist = get_next(phead); + + //free sta asoc_queue +- while ((rtw_end_of_queue_search(phead, plist)) == false) ++ while (phead != plist) + { + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); + + plist = get_next(plist); + +- rtw_list_delete(&psta->asoc_list); ++ list_del_init(&psta->asoc_list); + pstapriv->asoc_list_cnt--; + +- //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ //spin_unlock_bh(&pstapriv->asoc_list_lock); + ap_free_sta(padapter, psta, true, WLAN_REASON_DEAUTH_LEAVING); +- //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ //spin_lock_bh(&pstapriv->asoc_list_lock); + } +- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ spin_unlock_bh(&pstapriv->asoc_list_lock); + + + issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING); +@@ -2516,7 +2345,6 @@ void rtw_ap_restore_network(_adapter *pa + { + struct mlme_priv *mlmepriv = &padapter->mlmepriv; + struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; +- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct sta_priv * pstapriv = &padapter->stapriv; + struct sta_info *psta; + struct security_priv* psecuritypriv=&(padapter->securitypriv); +@@ -2539,12 +2367,12 @@ void rtw_ap_restore_network(_adapter *pa + rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0,false); + } + +- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ spin_lock_bh(&pstapriv->asoc_list_lock); + + phead = &pstapriv->asoc_list; + plist = get_next(phead); + +- while ((rtw_end_of_queue_search(phead, plist)) == false) { ++ while (phead != plist) { + int stainfo_offset; + + psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); +@@ -2556,7 +2384,7 @@ void rtw_ap_restore_network(_adapter *pa + } + } + +- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); ++ spin_unlock_bh(&pstapriv->asoc_list_lock); + + for (i = 0; i < chk_alive_num; i++) { + psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]); +@@ -2619,12 +2447,12 @@ void start_ap_mode(_adapter *padapter) + + + //for ACL +- _rtw_init_listhead(&(pacl_list->acl_node_q.queue)); ++ INIT_LIST_HEAD(&(pacl_list->acl_node_q.queue)); + pacl_list->num = 0; + pacl_list->mode = 0; + for(i = 0; i < NUM_ACL; i++) + { +- _rtw_init_listhead(&pacl_list->aclnode[i].list); ++ INIT_LIST_HEAD(&pacl_list->aclnode[i].list); + pacl_list->aclnode[i].valid = false; + } + +@@ -2651,10 +2479,10 @@ void stop_ap_mode(_adapter *padapter) + padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled; + + //for ACL +- _enter_critical_bh(&(pacl_node_q->lock), &irqL); ++ spin_lock_bh(&(pacl_node_q->lock)); + phead = get_list_head(pacl_node_q); + plist = get_next(phead); +- while ((rtw_end_of_queue_search(phead, plist)) == false) ++ while (phead != plist) + { + paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list); + plist = get_next(plist); +@@ -2663,12 +2491,12 @@ void stop_ap_mode(_adapter *padapter) + { + paclnode->valid = false; + +- rtw_list_delete(&paclnode->list); ++ list_del_init(&paclnode->list); + + pacl_list->num--; + } + } +- _exit_critical_bh(&(pacl_node_q->lock), &irqL); ++ spin_unlock_bh(&(pacl_node_q->lock)); + + DBG_871X("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num); + +@@ -2678,9 +2506,9 @@ void stop_ap_mode(_adapter *padapter) + rtw_free_all_stainfo(padapter); + + psta = rtw_get_bcmc_stainfo(padapter); +- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); ++ spin_lock_bh(&(pstapriv->sta_hash_lock)); + rtw_free_stainfo(padapter, psta); +- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); ++ spin_unlock_bh(&(pstapriv->sta_hash_lock)); + + rtw_init_bcmc_stainfo(padapter); + +@@ -2688,8 +2516,3 @@ void stop_ap_mode(_adapter *padapter) + + rtw_btcoex_MediaStatusNotify(padapter, 0); //disconnect + } +- +-#endif //CONFIG_NATIVEAP_MLME +- +-#endif //CONFIG_AP_MODE +- +diff -Nurp linux/3rdparty/rtl8723bs.old/core/rtw_btcoex.c linux/3rdparty/rtl8723bs/core/rtw_btcoex.c +--- linux/3rdparty/rtl8723bs.old/core/rtw_btcoex.c 2015-05-10 14:36:05.663667846 +0300 ++++ linux/3rdparty/rtl8723bs/core/rtw_btcoex.c 2015-05-07 17:46:55.000000000 +0300 +@@ -108,16 +108,6 @@ void rtw_btcoex_HaltNotify(PADAPTER pada + hal_btcoex_HaltNotify(padapter); + } + +-void rtw_btcoex_SwitchBtTRxMask(PADAPTER padapter) +-{ +- hal_btcoex_SwitchBtTRxMask(padapter); +-} +- +-void rtw_btcoex_Switch(PADAPTER padapter, u8 enable) +-{ +- hal_btcoex_SetBTCoexist(padapter, enable); +-} +- + u8 rtw_btcoex_IsBtDisabled(PADAPTER padapter) + { + return hal_btcoex_IsBtDisabled(padapter); +@@ -137,15 +127,6 @@ s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PAD + return coexctrl; + } + +-u32 rtw_btcoex_GetAMPDUSize(PADAPTER padapter) +-{ +- u32 size; +- +- size = hal_btcoex_GetAMPDUSize(padapter); +- +- return size; +-} +- + void rtw_btcoex_SetManualControl(PADAPTER padapter, u8 manual) + { + if (true == manual) +@@ -158,11 +139,6 @@ void rtw_btcoex_SetManualControl(PADAPTE + } + } + +-u8 rtw_btcoex_1Ant(PADAPTER padapter) +-{ +- return hal_btcoex_1Ant(padapter); +-} +- + u8 rtw_btcoex_IsBtControlLps(PADAPTER padapter) + { + return hal_btcoex_IsBtControlLps(padapter); +@@ -198,11 +174,6 @@ void rtw_btcoex_SetPGAntNum(PADAPTER pad + hal_btcoex_SetPgAntNum(padapter, antNum); + } + +-u8 rtw_btcoex_GetPGAntNum(PADAPTER padapter) +-{ +- return hal_btcoex_GetPgAntNum(padapter); +-} +- + void rtw_btcoex_SetSingleAntPath(PADAPTER padapter, u8 singleAntPath) + { + hal_btcoex_SetSingleAntPath(padapter, singleAntPath); +@@ -233,16 +204,6 @@ u32 rtw_btcoex_GetDBG(PADAPTER padapter, + return hal_btcoex_GetDBG(padapter, pStrBuf, bufSize); + } + +-u8 rtw_btcoex_IncreaseScanDeviceNum(PADAPTER padapter) +-{ +- return hal_btcoex_IncreaseScanDeviceNum(padapter); +-} +- +-u8 rtw_btcoex_IsBtLinkExist(PADAPTER padapter) +-{ +- return hal_btcoex_IsBtLinkExist(padapter); +-} +- + // ================================================== + // Below Functions are called by BT-Coex + // ================================================== +diff -Nurp linux/3rdparty/rtl8723bs.old/core/rtw_cmd.c linux/3rdparty/rtl8723bs/core/rtw_cmd.c +--- linux/3rdparty/rtl8723bs.old/core/rtw_cmd.c 2015-05-10 14:36:05.665667868 +0300 ++++ linux/3rdparty/rtl8723bs/core/rtw_cmd.c 2015-05-07 17:46:55.000000000 +0300 +@@ -255,10 +255,10 @@ _func_enter_; + void *c2h; + if ((c2h = rtw_cbuf_pop(pevtpriv->c2h_queue)) != NULL + && c2h != (void *)pevtpriv) { +- rtw_mfree(c2h, 16); ++ kfree(c2h); + } + } +- rtw_cbuf_free(pevtpriv->c2h_queue); ++ kfree(pevtpriv->c2h_queue); + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("-_rtw_free_evt_priv \n")); + +@@ -272,10 +272,10 @@ _func_enter_; + + if(pcmdpriv){ + if (pcmdpriv->cmd_allocated_buf) +- rtw_mfree(pcmdpriv->cmd_allocated_buf, MAX_CMDSZ + CMDBUFF_ALIGN_SZ); ++ kfree(pcmdpriv->cmd_allocated_buf); + + if (pcmdpriv->rsp_allocated_buf) +- rtw_mfree(pcmdpriv->rsp_allocated_buf, MAX_RSPSZ + 4); ++ kfree(pcmdpriv->rsp_allocated_buf); + + mutex_destroy(&pcmdpriv->sctx_mutex); + } +@@ -301,13 +301,13 @@ _func_enter_; + if (obj == NULL) + goto exit; + +- //_enter_critical_bh(&queue->lock, &irqL); +- _enter_critical(&queue->lock, &irqL); ++ //spin_lock_bh(&queue->lock); ++ spin_lock_irqsave(&queue->lock, irqL); + +- rtw_list_insert_tail(&obj->list, &queue->queue); ++ list_add_tail(&obj->list, &queue->queue); + +- //_exit_critical_bh(&queue->lock, &irqL); +- _exit_critical(&queue->lock, &irqL); ++ //spin_unlock_bh(&queue->lock); ++ spin_unlock_irqrestore(&queue->lock, irqL); + + exit: + +@@ -323,18 +323,18 @@ struct cmd_obj *_rtw_dequeue_cmd(_queue + + _func_enter_; + +- //_enter_critical_bh(&(queue->lock), &irqL); +- _enter_critical(&queue->lock, &irqL); +- if (rtw_is_list_empty(&(queue->queue))) ++ //spin_lock_bh(&(queue->lock)); ++ spin_lock_irqsave(&queue->lock, irqL); ++ if (list_empty(&(queue->queue))) + obj = NULL; + else + { + obj = LIST_CONTAINOR(get_next(&(queue->queue)), struct cmd_obj, list); +- rtw_list_delete(&obj->list); ++ list_del_init(&obj->list); + } + +- //_exit_critical_bh(&(queue->lock), &irqL); +- _exit_critical(&queue->lock, &irqL); ++ //spin_unlock_bh(&(queue->lock)); ++ spin_unlock_irqrestore(&queue->lock, irqL); + + _func_exit_; + +@@ -442,14 +442,6 @@ _func_exit_; + return cmd_obj; + } + +-void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv) +-{ +-_func_enter_; +- pcmdpriv->cmd_done_cnt++; +- //up(&(pcmdpriv->cmd_done_sema)); +-_func_exit_; +-} +- + void rtw_free_cmd_obj(struct cmd_obj *pcmd) + { + _func_enter_; +@@ -457,7 +449,7 @@ _func_enter_; + if((pcmd->cmdcode!=_JoinBss_CMD_) &&(pcmd->cmdcode!= _CreateBss_CMD_)) + { + //free parmbuf in cmd_obj +- rtw_mfree((unsigned char*)pcmd->parmbuf, pcmd->cmdsz); ++ kfree((unsigned char*)pcmd->parmbuf); + } + + if(pcmd->rsp!=NULL) +@@ -465,12 +457,12 @@ _func_enter_; + if(pcmd->rspsz!= 0) + { + //free rsp in cmd_obj +- rtw_mfree((unsigned char*)pcmd->rsp, pcmd->rspsz); ++ kfree((unsigned char*)pcmd->rsp); + } + } + + //free cmd_obj +- rtw_mfree((unsigned char*)pcmd, sizeof(struct cmd_obj)); ++ kfree((unsigned char*)pcmd); + + _func_exit_; + } +@@ -533,7 +525,7 @@ _func_enter_; + break; + } + +- if(rtw_is_list_empty(&(pcmdpriv->cmd_queue.queue))) ++ if(list_empty(&(pcmdpriv->cmd_queue.queue))) + { + //DBG_871X("%s: cmd queue is empty!\n", __func__); + continue; +@@ -573,7 +565,7 @@ _next: + + memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); + +- if(pcmd->cmdcode < (sizeof(wlancmds) /sizeof(struct cmd_hdl))) ++ if(pcmd->cmdcode < ARRAY_SIZE(wlancmds)) + { + cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; + +@@ -594,18 +586,18 @@ _next: + + post_process: + +- _enter_critical_mutex(&(pcmd->padapter->cmdpriv.sctx_mutex), NULL); +- if (pcmd->sctx) { +- DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pcmd->sctx\n", +- FUNC_ADPT_ARG(pcmd->padapter)); +- +- if (pcmd->res == H2C_SUCCESS) +- rtw_sctx_done(&pcmd->sctx); +- else +- rtw_sctx_done_err(&pcmd->sctx, RTW_SCTX_DONE_CMD_ERROR); ++ if (mutex_lock_interruptible(&(pcmd->padapter->cmdpriv.sctx_mutex)) == 0) { ++ if (pcmd->sctx) { ++ DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pcmd->sctx\n", ++ FUNC_ADPT_ARG(pcmd->padapter)); ++ ++ if (pcmd->res == H2C_SUCCESS) ++ rtw_sctx_done(&pcmd->sctx); ++ else ++ rtw_sctx_done_err(&pcmd->sctx, RTW_SCTX_DONE_CMD_ERROR); ++ } ++ mutex_unlock(&(pcmd->padapter->cmdpriv.sctx_mutex)); + } +- _exit_critical_mutex(&(pcmd->padapter->cmdpriv.sctx_mutex), NULL); +- + + if((cmd_process_time = jiffies_to_msecs(jiffies - cmd_start_time)) > 1000) + { +@@ -627,7 +619,7 @@ post_process: + } + + //call callback function for post-processed +- if(pcmd->cmdcode < (sizeof(rtw_cmd_callback) /sizeof(struct _cmd_callback))) ++ if(pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) + { + pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; + if(pcmd_callback == NULL) +@@ -666,7 +658,7 @@ post_process: + if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { + extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf; + if(extra_parm->pbuf && extra_parm->size > 0) { +- rtw_mfree(extra_parm->pbuf, extra_parm->size); ++ kfree(extra_parm->pbuf); + } + } + +@@ -682,42 +674,6 @@ _func_exit_; + + } + +-u8 rtw_setstandby_cmd(_adapter *padapter, uint action) +-{ +- struct cmd_obj* ph2c; +- struct usb_suspend_parm* psetusbsuspend; +- struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +- +- u8 ret = _SUCCESS; +- +-_func_enter_; +- +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if (ph2c == NULL) { +- ret = _FAIL; +- goto exit; +- } +- +- psetusbsuspend = (struct usb_suspend_parm*)rtw_zmalloc(sizeof(struct usb_suspend_parm)); +- if (psetusbsuspend == NULL) { +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); +- ret = _FAIL; +- goto exit; +- } +- +- psetusbsuspend->action = action; +- +- init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend)); +- +- ret = rtw_enqueue_cmd(pcmdpriv, ph2c); +- +-exit: +- +-_func_exit_; +- +- return ret; +-} +- + /* + rtw_sitesurvey_cmd(~) + ### NOTE:#### (!!!!) +@@ -744,7 +700,7 @@ _func_enter_; + + psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm)); + if (psurveyPara == NULL) { +- rtw_mfree((unsigned char*) ph2c, sizeof(struct cmd_obj)); ++ kfree((unsigned char*) ph2c); + return _FAIL; + } + +@@ -793,8 +749,6 @@ _func_enter_; + + pmlmepriv->scan_start_time = jiffies; + _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT); +- +- rtw_led_control(padapter, LED_CTL_SITE_SURVEY); + } else { + _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); + } +@@ -821,7 +775,7 @@ _func_enter_; + + pbsetdataratepara = (struct setdatarate_parm*)rtw_zmalloc(sizeof(struct setdatarate_parm)); + if (pbsetdataratepara == NULL) { +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); ++ kfree((u8 *) ph2c); + res = _FAIL; + goto exit; + } +@@ -838,243 +792,17 @@ _func_exit_; + return res; + } + +-u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset) +-{ +- struct cmd_obj* ph2c; +- struct setbasicrate_parm* pssetbasicratepara; +- struct cmd_priv* pcmdpriv=&padapter->cmdpriv; +- u8 res = _SUCCESS; +- +-_func_enter_; +- +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if (ph2c == NULL) { +- res= _FAIL; +- goto exit; +- } +- pssetbasicratepara = (struct setbasicrate_parm*)rtw_zmalloc(sizeof(struct setbasicrate_parm)); +- +- if (pssetbasicratepara == NULL) { +- rtw_mfree((u8*) ph2c, sizeof(struct cmd_obj)); +- res = _FAIL; +- goto exit; +- } +- +- init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_); +- +- memcpy(pssetbasicratepara->basicrates, rateset, NumRates); +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +-exit: +- +-_func_exit_; +- +- return res; +-} +- +- +-/* +-unsigned char rtw_setphy_cmd(unsigned char *adapter) +- +-1. be called only after rtw_update_registrypriv_dev_network( ~) or mp testing program +-2. for AdHoc/Ap mode or mp mode? +- +-*/ +-u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch) +-{ +- struct cmd_obj* ph2c; +- struct setphy_parm* psetphypara; +- struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +-// struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +-// struct registry_priv* pregistry_priv = &padapter->registrypriv; +- u8 res=_SUCCESS; +- +-_func_enter_; +- +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(ph2c==NULL){ +- res= _FAIL; +- goto exit; +- } +- psetphypara = (struct setphy_parm*)rtw_zmalloc(sizeof(struct setphy_parm)); +- +- if(psetphypara==NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); +- res= _FAIL; +- goto exit; +- } +- +- init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_); +- +- RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("CH=%d, modem=%d", ch, modem)); +- +- psetphypara->modem = modem; +- psetphypara->rfchannel = ch; +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +-exit: +-_func_exit_; +- return res; +-} +- +-u8 rtw_setbbreg_cmd(_adapter*padapter, u8 offset, u8 val) +-{ +- struct cmd_obj* ph2c; +- struct writeBB_parm* pwritebbparm; +- struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +- u8 res=_SUCCESS; +-_func_enter_; +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(ph2c==NULL){ +- res= _FAIL; +- goto exit; +- } +- pwritebbparm = (struct writeBB_parm*)rtw_zmalloc(sizeof(struct writeBB_parm)); +- +- if(pwritebbparm==NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); +- res= _FAIL; +- goto exit; +- } +- +- init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg)); +- +- pwritebbparm->offset = offset; +- pwritebbparm->value = val; +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +-exit: +-_func_exit_; +- return res; +-} +- +-u8 rtw_getbbreg_cmd(_adapter *padapter, u8 offset, u8 *pval) +-{ +- struct cmd_obj* ph2c; +- struct readBB_parm* prdbbparm; +- struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +- u8 res=_SUCCESS; +- +-_func_enter_; +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(ph2c==NULL){ +- res=_FAIL; +- goto exit; +- } +- prdbbparm = (struct readBB_parm*)rtw_zmalloc(sizeof(struct readBB_parm)); +- +- if(prdbbparm ==NULL){ +- rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); +- return _FAIL; +- } +- +- _rtw_init_listhead(&ph2c->list); +- ph2c->cmdcode =GEN_CMD_CODE(_GetBBReg); +- ph2c->parmbuf = (unsigned char *)prdbbparm; +- ph2c->cmdsz = sizeof(struct readBB_parm); +- ph2c->rsp = pval; +- ph2c->rspsz = sizeof(struct readBB_rsp); +- +- prdbbparm ->offset = offset; +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +-exit: +-_func_exit_; +- return res; +-} +- +-u8 rtw_setrfreg_cmd(_adapter *padapter, u8 offset, u32 val) +-{ +- struct cmd_obj* ph2c; +- struct writeRF_parm* pwriterfparm; +- struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +- u8 res=_SUCCESS; +-_func_enter_; +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(ph2c==NULL){ +- res= _FAIL; +- goto exit; +- } +- pwriterfparm = (struct writeRF_parm*)rtw_zmalloc(sizeof(struct writeRF_parm)); +- +- if(pwriterfparm==NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); +- res= _FAIL; +- goto exit; +- } +- +- init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); +- +- pwriterfparm->offset = offset; +- pwriterfparm->value = val; +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +-exit: +-_func_exit_; +- return res; +-} +- +-u8 rtw_getrfreg_cmd(_adapter *padapter, u8 offset, u8 *pval) +-{ +- struct cmd_obj* ph2c; +- struct readRF_parm* prdrfparm; +- struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +- u8 res=_SUCCESS; +- +-_func_enter_; +- +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(ph2c==NULL){ +- res= _FAIL; +- goto exit; +- } +- +- prdrfparm = (struct readRF_parm*)rtw_zmalloc(sizeof(struct readRF_parm)); +- if(prdrfparm ==NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); +- res= _FAIL; +- goto exit; +- } +- +- _rtw_init_listhead(&ph2c->list); +- ph2c->cmdcode =GEN_CMD_CODE(_GetRFReg); +- ph2c->parmbuf = (unsigned char *)prdrfparm; +- ph2c->cmdsz = sizeof(struct readRF_parm); +- ph2c->rsp = pval; +- ph2c->rspsz = sizeof(struct readRF_rsp); +- +- prdrfparm ->offset = offset; +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +- +-exit: +- +-_func_exit_; +- +- return res; +-} +- + void rtw_getbbrfreg_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) + { + _func_enter_; + + //rtw_free_cmd_obj(pcmd); +- rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz); +- rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj)); ++ kfree((unsigned char*) pcmd->parmbuf); ++ kfree((unsigned char*) pcmd); + + _func_exit_; + } + +-void rtw_readtssi_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +-{ +- _func_enter_; +- +- rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz); +- rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj)); +- +-_func_exit_; +-} +- + u8 rtw_createbss_cmd(_adapter *padapter) + { + struct cmd_obj* pcmd; +@@ -1085,8 +813,6 @@ u8 rtw_createbss_cmd(_adapter *padapter + + _func_enter_; + +- rtw_led_control(padapter, LED_CTL_START_TO_LINK); +- + if (pmlmepriv->assoc_ssid.SsidLength == 0){ + RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,(" createbss for Any SSid:%s\n",pmlmepriv->assoc_ssid.Ssid)); + } else { +@@ -1099,7 +825,7 @@ _func_enter_; + goto exit; + } + +- _rtw_init_listhead(&pcmd->list); ++ INIT_LIST_HEAD(&pcmd->list); + pcmd->cmdcode = _CreateBss_CMD_; + pcmd->parmbuf = (unsigned char *)pdev_network; + pcmd->cmdsz = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX*)pdev_network); +@@ -1117,36 +843,6 @@ _func_exit_; + return res; + } + +-u8 rtw_createbss_cmd_ex(_adapter *padapter, unsigned char *pbss, unsigned int sz) +-{ +- struct cmd_obj* pcmd; +- struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +- u8 res=_SUCCESS; +- +-_func_enter_; +- +- pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(pcmd==NULL){ +- res= _FAIL; +- goto exit; +- } +- +- _rtw_init_listhead(&pcmd->list); +- pcmd->cmdcode = GEN_CMD_CODE(_CreateBss); +- pcmd->parmbuf = pbss; +- pcmd->cmdsz = sz; +- pcmd->rsp = NULL; +- pcmd->rspsz = 0; +- +- res = rtw_enqueue_cmd(pcmdpriv, pcmd); +- +-exit: +- +-_func_exit_; +- +- return res; +-} +- + u8 rtw_startbss_cmd(_adapter *padapter, int flags) + { + struct cmd_obj* pcmd; +@@ -1167,7 +863,7 @@ _func_enter_; + goto exit; + } + +- _rtw_init_listhead(&pcmd->list); ++ INIT_LIST_HEAD(&pcmd->list); + pcmd->cmdcode = GEN_CMD_CODE(_CreateBss); + pcmd->parmbuf = NULL; + pcmd->cmdsz = 0; +@@ -1183,10 +879,11 @@ _func_enter_; + + if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { + rtw_sctx_wait(&sctx, __func__); +- _enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL); +- if (sctx.status == RTW_SCTX_SUBMITTED) +- pcmd->sctx = NULL; +- _exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL); ++ if (mutex_lock_interruptible(&pcmdpriv->sctx_mutex) == 0) { ++ if (sctx.status == RTW_SCTX_SUBMITTED) ++ pcmd->sctx = NULL; ++ mutex_unlock(&pcmdpriv->sctx_mutex); ++ } + } + } + +@@ -1216,8 +913,6 @@ u8 rtw_joinbss_cmd(_adapter *padapter, + u8 *ptmp=NULL; + _func_enter_; + +- rtw_led_control(padapter, LED_CTL_START_TO_LINK); +- + if (pmlmepriv->assoc_ssid.SsidLength == 0){ + RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); + } else { +@@ -1267,7 +962,7 @@ _func_enter_; + if(psecnetwork==NULL) + { + if(pcmd !=NULL) +- rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)pcmd); + + res=_FAIL; + +@@ -1348,7 +1043,7 @@ _func_enter_; + + pcmd->cmdsz = get_WLAN_BSSID_EX_sz(psecnetwork);//get cmdsz before endian conversion + +- _rtw_init_listhead(&pcmd->list); ++ INIT_LIST_HEAD(&pcmd->list); + pcmd->cmdcode = _JoinBss_CMD_;//GEN_CMD_CODE(_JoinBss) + pcmd->parmbuf = (unsigned char *)psecnetwork; + pcmd->rsp = NULL; +@@ -1387,7 +1082,7 @@ _func_enter_; + cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj)); + if (cmdobj == NULL) { + res = _FAIL; +- rtw_mfree((u8 *)param, sizeof(*param)); ++ kfree((u8 *)param); + goto exit; + } + init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_); +@@ -1396,7 +1091,7 @@ _func_enter_; + /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ + if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param)) + res = _FAIL; +- rtw_mfree((u8 *)param, sizeof(*param)); ++ kfree((u8 *)param); + } + + exit: +@@ -1426,7 +1121,7 @@ _func_enter_; + if(enqueue){ + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(ph2c==NULL){ +- rtw_mfree((u8 *)psetop, sizeof(*psetop)); ++ kfree((u8 *)psetop); + res= _FAIL; + goto exit; + } +@@ -1436,7 +1131,7 @@ _func_enter_; + } + else{ + setopmode_hdl(padapter, (u8 *)psetop); +- rtw_mfree((u8 *)psetop, sizeof(*psetop)); ++ kfree((u8 *)psetop); + } + exit: + +@@ -1486,15 +1181,15 @@ _func_enter_; + { + ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if ( ph2c == NULL){ +- rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); ++ kfree((u8 *) psetstakey_para); + res= _FAIL; + goto exit; + } + + psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp)); + if(psetstakey_rsp == NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); +- rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); ++ kfree((u8 *) ph2c); ++ kfree((u8 *) psetstakey_para); + res=_FAIL; + goto exit; + } +@@ -1506,7 +1201,7 @@ _func_enter_; + } + else{ + set_stakey_hdl(padapter, (u8 *)psetstakey_para); +- rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); ++ kfree((u8 *) psetstakey_para); + } + exit: + +@@ -1546,15 +1241,15 @@ _func_enter_; + + psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm)); + if(psetstakey_para==NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); ++ kfree((u8 *) ph2c); + res=_FAIL; + goto exit; + } + + psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp)); + if(psetstakey_rsp == NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); +- rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm)); ++ kfree((u8 *) ph2c); ++ kfree((u8 *) psetstakey_para); + res=_FAIL; + goto exit; + } +@@ -1578,123 +1273,6 @@ _func_exit_; + return res; + } + +-u8 rtw_setrttbl_cmd(_adapter *padapter, struct setratable_parm *prate_table) +-{ +- struct cmd_obj* ph2c; +- struct setratable_parm * psetrttblparm; +- struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +- u8 res=_SUCCESS; +-_func_enter_; +- +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(ph2c==NULL){ +- res= _FAIL; +- goto exit; +- } +- psetrttblparm = (struct setratable_parm*)rtw_zmalloc(sizeof(struct setratable_parm)); +- +- if(psetrttblparm==NULL){ +- rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); +- res= _FAIL; +- goto exit; +- } +- +- init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); +- +- memcpy(psetrttblparm,prate_table,sizeof(struct setratable_parm)); +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +-exit: +-_func_exit_; +- return res; +- +-} +- +-u8 rtw_getrttbl_cmd(_adapter *padapter, struct getratable_rsp *pval) +-{ +- struct cmd_obj* ph2c; +- struct getratable_parm * pgetrttblparm; +- struct cmd_priv *pcmdpriv=&padapter->cmdpriv; +- u8 res=_SUCCESS; +-_func_enter_; +- +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(ph2c==NULL){ +- res= _FAIL; +- goto exit; +- } +- pgetrttblparm = (struct getratable_parm*)rtw_zmalloc(sizeof(struct getratable_parm)); +- +- if(pgetrttblparm==NULL){ +- rtw_mfree((unsigned char *) ph2c, sizeof(struct cmd_obj)); +- res= _FAIL; +- goto exit; +- } +- +-// init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); +- +- _rtw_init_listhead(&ph2c->list); +- ph2c->cmdcode =GEN_CMD_CODE(_GetRaTable); +- ph2c->parmbuf = (unsigned char *)pgetrttblparm; +- ph2c->cmdsz = sizeof(struct getratable_parm); +- ph2c->rsp = (u8*)pval; +- ph2c->rspsz = sizeof(struct getratable_rsp); +- +- pgetrttblparm ->rsvd = 0x0; +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +-exit: +-_func_exit_; +- return res; +- +-} +- +-u8 rtw_setassocsta_cmd(_adapter *padapter, u8 *mac_addr) +-{ +- struct cmd_priv *pcmdpriv = &padapter->cmdpriv; +- struct cmd_obj* ph2c; +- struct set_assocsta_parm *psetassocsta_para; +- struct set_stakey_rsp *psetassocsta_rsp = NULL; +- +- u8 res=_SUCCESS; +- +-_func_enter_; +- +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(ph2c==NULL){ +- res= _FAIL; +- goto exit; +- } +- +- psetassocsta_para = (struct set_assocsta_parm*)rtw_zmalloc(sizeof(struct set_assocsta_parm)); +- if(psetassocsta_para==NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); +- res=_FAIL; +- goto exit; +- } +- +- psetassocsta_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_assocsta_rsp)); +- if(psetassocsta_rsp==NULL){ +- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj)); +- rtw_mfree((u8 *) psetassocsta_para, sizeof(struct set_assocsta_parm)); +- return _FAIL; +- } +- +- init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_); +- ph2c->rsp = (u8 *) psetassocsta_rsp; +- ph2c->rspsz = sizeof(struct set_assocsta_rsp); +- +- memcpy(psetassocsta_para->addr, mac_addr,ETH_ALEN); +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +- +-exit: +- +-_func_exit_; +- +- return res; +- } +- + u8 rtw_addbareq_cmd(_adapter*padapter, u8 tid, u8 *addr) + { + struct cmd_priv *pcmdpriv = &padapter->cmdpriv; +@@ -1713,7 +1291,7 @@ _func_enter_; + + paddbareq_parm = (struct addBaReq_parm*)rtw_zmalloc(sizeof(struct addBaReq_parm)); + if(paddbareq_parm==NULL){ +- rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)ph2c); + res= _FAIL; + goto exit; + } +@@ -1752,7 +1330,7 @@ _func_enter_; + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ +- rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)ph2c); + res= _FAIL; + goto exit; + } +@@ -1793,7 +1371,7 @@ _func_enter_; + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ +- rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)ph2c); + res= _FAIL; + goto exit; + } +@@ -1835,7 +1413,7 @@ _func_enter_; + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ +- rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)ph2c); + res= _FAIL; + goto exit; + } +@@ -1858,61 +1436,6 @@ _func_exit_; + + } + +-u8 rtw_set_ch_cmd(_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue) +-{ +- struct cmd_obj *pcmdobj; +- struct set_ch_parm *set_ch_parm; +- struct cmd_priv *pcmdpriv = &padapter->cmdpriv; +- +- u8 res=_SUCCESS; +- +-_func_enter_; +- +- DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", +- FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset); +- +- /* check input parameter */ +- +- /* prepare cmd parameter */ +- set_ch_parm = (struct set_ch_parm *)rtw_zmalloc(sizeof(*set_ch_parm)); +- if (set_ch_parm == NULL) { +- res= _FAIL; +- goto exit; +- } +- set_ch_parm->ch = ch; +- set_ch_parm->bw = bw; +- set_ch_parm->ch_offset = ch_offset; +- +- if (enqueue) { +- /* need enqueue, prepare cmd_obj and enqueue */ +- pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(pcmdobj == NULL){ +- rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm)); +- res=_FAIL; +- goto exit; +- } +- +- init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel)); +- res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); +- } else { +- /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ +- if( H2C_SUCCESS !=set_ch_hdl(padapter, (u8 *)set_ch_parm) ) +- res = _FAIL; +- +- rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm)); +- } +- +- /* do something based on res... */ +- +-exit: +- +- DBG_871X(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res); +- +-_func_exit_; +- +- return res; +-} +- + u8 rtw_set_chplan_cmd(_adapter*padapter, u8 chplan, u8 enqueue, u8 swconfig) + { + struct cmd_obj* pcmdobj; +@@ -1951,7 +1474,7 @@ _func_enter_; + //need enqueue, prepare cmd_obj and enqueue + pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); + if(pcmdobj == NULL){ +- rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param)); ++ kfree((u8 *)setChannelPlan_param); + res=_FAIL; + goto exit; + } +@@ -1965,7 +1488,7 @@ _func_enter_; + if( H2C_SUCCESS !=set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param) ) + res = _FAIL; + +- rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param)); ++ kfree((u8 *)setChannelPlan_param); + } + + //do something based on res... +@@ -1979,92 +1502,6 @@ _func_exit_; + return res; + } + +-u8 rtw_led_blink_cmd(_adapter*padapter, void * pLed) +-{ +- struct cmd_obj* pcmdobj; +- struct LedBlink_param *ledBlink_param; +- struct cmd_priv *pcmdpriv = &padapter->cmdpriv; +- +- u8 res=_SUCCESS; +- +-_func_enter_; +- +- RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_led_blink_cmd\n")); +- +- pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(pcmdobj == NULL){ +- res=_FAIL; +- goto exit; +- } +- +- ledBlink_param = (struct LedBlink_param *)rtw_zmalloc(sizeof(struct LedBlink_param)); +- if(ledBlink_param == NULL) { +- rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj)); +- res= _FAIL; +- goto exit; +- } +- +- ledBlink_param->pLed=pLed; +- +- init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink)); +- res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); +- +-exit: +- +-_func_exit_; +- +- return res; +-} +- +-u8 rtw_set_csa_cmd(_adapter*padapter, u8 new_ch_no) +-{ +- struct cmd_obj* pcmdobj; +- struct SetChannelSwitch_param*setChannelSwitch_param; +- struct mlme_priv *pmlmepriv = &padapter->mlmepriv; +- struct cmd_priv *pcmdpriv = &padapter->cmdpriv; +- +- u8 res=_SUCCESS; +- +-_func_enter_; +- +- RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_csa_cmd\n")); +- +- pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(pcmdobj == NULL){ +- res=_FAIL; +- goto exit; +- } +- +- setChannelSwitch_param = (struct SetChannelSwitch_param *)rtw_zmalloc(sizeof(struct SetChannelSwitch_param)); +- if(setChannelSwitch_param == NULL) { +- rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj)); +- res= _FAIL; +- goto exit; +- } +- +- setChannelSwitch_param->new_ch_no=new_ch_no; +- +- init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch)); +- res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); +- +-exit: +- +-_func_exit_; +- +- return res; +-} +- +-u8 rtw_tdls_cmd(_adapter *padapter, u8 *addr, u8 option) +-{ +- u8 res=_SUCCESS; +- +-_func_enter_; +- +-_func_exit_; +- +- return res; +-} +- + static void collect_traffic_statistics(_adapter *padapter) + { + struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); +@@ -2150,8 +1587,6 @@ u8 traffic_status_watchdog(_adapter *pad + TRAFFIC_PROTECT_PERIOD_MS, + link_detect->NumTxOkInPeriod, + link_detect->NumRxUnicastOkInPeriod); +- +- rtw_lock_traffic_suspend_timeout(TRAFFIC_PROTECT_PERIOD_MS); + } + #endif + +@@ -2250,12 +1685,10 @@ static void dynamic_chk_wk_hdl(_adapter + struct mlme_priv *pmlmepriv; + pmlmepriv = &(padapter->mlmepriv); + +-#ifdef CONFIG_AP_MODE + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) + { + expire_timeout_chk(padapter); + } +-#endif + + //for debug purpose + _linked_info_dump(padapter); +@@ -2370,7 +1803,7 @@ _func_enter_; + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ +- rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)ph2c); + res= _FAIL; + goto exit; + } +@@ -2418,7 +1851,7 @@ u8 rtw_dm_in_lps_wk_cmd(_adapter*padapte + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ +- rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)ph2c); + res= _FAIL; + goto exit; + } +@@ -2470,43 +1903,6 @@ static void rtw_lps_change_dtim_hdl(_ada + up(&pwrpriv->lock); + } + +-u8 rtw_lps_change_dtim_cmd(_adapter*padapter, u8 dtim) +-{ +- struct cmd_obj *ph2c; +- struct drvextra_cmd_parm *pdrvextra_cmd_parm; +- struct cmd_priv *pcmdpriv = &padapter->cmdpriv; +- u8 res = _SUCCESS; +- +- { +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if(ph2c==NULL){ +- res= _FAIL; +- goto exit; +- } +- +- pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); +- if(pdrvextra_cmd_parm==NULL){ +- rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); +- res= _FAIL; +- goto exit; +- } +- +- pdrvextra_cmd_parm->ec_id = LPS_CHANGE_DTIM_CID; +- pdrvextra_cmd_parm->type = dtim; +- pdrvextra_cmd_parm->size = 0; +- pdrvextra_cmd_parm->pbuf = NULL; +- +- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +- } +- +-exit: +- +- return res; +- +-} +- + static void rtw_dm_ra_mask_hdl(_adapter *padapter, struct sta_info *psta) + { + if (psta) { +@@ -2530,7 +1926,7 @@ u8 rtw_dm_ra_mask_wk_cmd(_adapter*padapt + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ +- rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)ph2c); + res= _FAIL; + goto exit; + } +@@ -2583,7 +1979,7 @@ _func_enter_; + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ +- rtw_mfree((unsigned char *)ppscmd, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)ppscmd); + res= _FAIL; + goto exit; + } +@@ -2604,8 +2000,6 @@ _func_exit_; + + } + +-#ifdef CONFIG_AP_MODE +- + extern u32 g_wait_hiq_empty; + + static void rtw_chk_hi_queue_hdl(_adapter *padapter) +@@ -2666,7 +2060,7 @@ u8 rtw_chk_hi_queue_cmd(_adapter*padapte + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if(pdrvextra_cmd_parm==NULL){ +- rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj)); ++ kfree((unsigned char *)ph2c); + res= _FAIL; + goto exit; + } +@@ -2685,7 +2079,6 @@ exit: + return res; + + } +-#endif + + struct btinfo { + u8 cid; +@@ -2751,50 +2144,6 @@ static void rtw_btinfo_hdl(_adapter *ada + rtw_btcoex_BtInfoNotify(adapter ,len+1, &buf[1]); + } + +-u8 rtw_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len) +-{ +- struct cmd_obj *ph2c; +- struct drvextra_cmd_parm *pdrvextra_cmd_parm; +- u8 *btinfo; +- struct cmd_priv *pcmdpriv = &adapter->cmdpriv; +- u8 res = _SUCCESS; +- +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if (ph2c == NULL) { +- res = _FAIL; +- goto exit; +- } +- +- pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); +- if (pdrvextra_cmd_parm == NULL) { +- rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); +- res = _FAIL; +- goto exit; +- } +- +- btinfo = rtw_zmalloc(len); +- if (btinfo == NULL) { +- rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); +- rtw_mfree((u8*)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm)); +- res = _FAIL; +- goto exit; +- } +- +- pdrvextra_cmd_parm->ec_id = BTINFO_WK_CID; +- pdrvextra_cmd_parm->type = 0; +- pdrvextra_cmd_parm->size = len; +- pdrvextra_cmd_parm->pbuf = btinfo; +- +- memcpy(btinfo, buf, len); +- +- init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +- +-exit: +- return res; +-} +- + u8 rtw_c2h_packet_wk_cmd(PADAPTER padapter, u8 *pbuf, u16 length) + { + struct cmd_obj *ph2c; +@@ -2810,7 +2159,7 @@ u8 rtw_c2h_packet_wk_cmd(PADAPTER padapt + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { +- rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); ++ kfree((u8*)ph2c); + res = _FAIL; + goto exit; + } +@@ -2845,7 +2194,7 @@ u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 + + pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + if (pdrvextra_cmd_parm == NULL) { +- rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); ++ kfree((u8*)ph2c); + res = _FAIL; + goto exit; + } +@@ -2864,42 +2213,6 @@ exit: + return res; + } + +-u8 rtw_run_in_thread_cmd(PADAPTER padapter, void (*func)(void*), void* context) +-{ +- struct cmd_priv *pcmdpriv; +- struct cmd_obj *ph2c; +- struct RunInThread_param *parm; +- s32 res = _SUCCESS; +- +-_func_enter_; +- +- pcmdpriv = &padapter->cmdpriv; +- +- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj)); +- if (NULL == ph2c) { +- res = _FAIL; +- goto exit; +- } +- +- parm = (struct RunInThread_param*)rtw_zmalloc(sizeof(struct RunInThread_param)); +- if (NULL == parm) { +- rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj)); +- res = _FAIL; +- goto exit; +- } +- +- parm->func = func; +- parm->context = context; +- init_h2fwcmd_w_parm_no_rsp(ph2c, parm, GEN_CMD_CODE(_RunInThreadCMD)); +- +- res = rtw_enqueue_cmd(pcmdpriv, ph2c); +-exit: +- +-_func_exit_; +- +- return res; +-} +- + static void c2h_wk_callback(_workitem *work) + { + struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk); +@@ -2916,7 +2229,7 @@ static void c2h_wk_callback(_workitem *w + } else if ((c2h_evt = (u8 *)rtw_malloc(16)) != NULL) { + /* This C2H event is not read, read & clear now */ + if (rtw_hal_c2h_evt_read(adapter, c2h_evt) != _SUCCESS) { +- rtw_mfree(c2h_evt, 16); ++ kfree(c2h_evt); + continue; + } + } +@@ -2926,14 +2239,14 @@ static void c2h_wk_callback(_workitem *w + continue; + + if (!rtw_hal_c2h_valid(adapter, c2h_evt)) { +- rtw_mfree(c2h_evt, 16); ++ kfree(c2h_evt); + continue; + } + + if (ccx_id_filter(c2h_evt) == true) { + /* Handle CCX report here */ + rtw_hal_c2h_handler(adapter, c2h_evt); +- rtw_mfree(c2h_evt, 16); ++ kfree(c2h_evt); + } else { + /* Enqueue into cmd_thread for others */ + rtw_c2h_wk_cmd(adapter, c2h_evt); +@@ -2969,11 +2282,9 @@ u8 rtw_drvextra_cmd_hdl(_adapter *padapt + case LPS_CHANGE_DTIM_CID: + rtw_lps_change_dtim_hdl(padapter, (u8)pdrvextra_cmd->type); + break; +-#ifdef CONFIG_AP_MODE + case CHECK_HIQ_WK_CID: + rtw_chk_hi_queue_hdl(padapter); + break; +-#endif //CONFIG_AP_MODE + #ifdef CONFIG_INTEL_WIDI + case INTEl_WIDI_WK_CID: + intel_widi_wk_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf); +@@ -3001,7 +2312,7 @@ u8 rtw_drvextra_cmd_hdl(_adapter *padapt + + if (pdrvextra_cmd->pbuf && pdrvextra_cmd->size>0) + { +- rtw_mfree(pdrvextra_cmd->pbuf, pdrvextra_cmd->size); ++ kfree(pdrvextra_cmd->pbuf); + } + + return H2C_SUCCESS; +@@ -3038,9 +2349,9 @@ _func_enter_; + + if (pcmd->res != H2C_SUCCESS) + { +- _enter_critical_bh(&pmlmepriv->lock, &irqL); ++ spin_lock_bh(&pmlmepriv->lock); + set_fwstate(pmlmepriv, _FW_LINKED); +- _exit_critical_bh(&pmlmepriv->lock, &irqL); ++ spin_unlock_bh(&pmlmepriv->lock); + + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ***Error: disconnect_cmd_callback Fail ***\n.")); + +@@ -3100,7 +2411,7 @@ _func_enter_; + + _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); + +- _enter_critical_bh(&pmlmepriv->lock, &irqL); ++ spin_lock_bh(&pmlmepriv->lock); + + + if(check_fwstate(pmlmepriv, WIFI_AP_STATE) ) +@@ -3123,28 +2434,28 @@ _func_enter_; + _irqL irqL; + + pwlan = _rtw_alloc_network(pmlmepriv); +- _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); ++ spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); + if ( pwlan == NULL) + { + pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); + if( pwlan == NULL) + { + RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n Error: can't get pwlan in rtw_joinbss_event_callback \n")); +- _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); ++ spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + goto createbss_cmd_fail; + } + pwlan->last_scanned = jiffies; + } + else + { +- rtw_list_insert_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); ++ list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); + } + + pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork); + memcpy(&(pwlan->network), pnetwork, pnetwork->Length); + //pwlan->fixed = true; + +- //rtw_list_insert_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); ++ //list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); + + // copy pdev_network information to pmlmepriv->cur_network + memcpy(&tgt_network->network, pnetwork, (get_WLAN_BSSID_EX_sz(pnetwork))); +@@ -3154,14 +2465,14 @@ _func_enter_; + + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + +- _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); ++ spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + // we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) + + } + + createbss_cmd_fail: + +- _exit_critical_bh(&pmlmepriv->lock, &irqL); ++ spin_unlock_bh(&pmlmepriv->lock); + exit: + rtw_free_cmd_obj(pcmd); + +@@ -3214,28 +2525,16 @@ _func_enter_; + + psta->aid = psta->mac_id = passocsta_rsp->cam_id; + +- _enter_critical_bh(&pmlmepriv->lock, &irqL); ++ spin_lock_bh(&pmlmepriv->lock); + + if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)) + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); + + set_fwstate(pmlmepriv, _FW_LINKED); +- _exit_critical_bh(&pmlmepriv->lock, &irqL); ++ spin_unlock_bh(&pmlmepriv->lock); + + exit: + rtw_free_cmd_obj(pcmd); + + _func_exit_; + } +- +-void rtw_getrttbl_cmd_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd); +-void rtw_getrttbl_cmd_cmdrsp_callback(_adapter* padapter, struct cmd_obj *pcmd) +-{ +-_func_enter_; +- +- rtw_free_cmd_obj(pcmd); +- +-_func_exit_; +- +-} +- +diff -Nurp linux/3rdparty/rtl8723bs.old/core/rtw_debug.c linux/3rdparty/rtl8723bs/core/rtw_debug.c +--- linux/3rdparty/rtl8723bs.old/core/rtw_debug.c 2015-05-10 14:36:05.666667879 +0300 ++++ linux/3rdparty/rtl8723bs/core/rtw_debug.c 2015-05-07 17:46:55.000000000 +0300 +@@ -62,7 +62,7 @@ u32 GlobalDebugLevel = _drv_err_; + + void dump_drv_version(void *sel) + { +- DBG_871X_SEL_NL(sel, "%s %s\n", DRV_NAME, DRIVERVERSION); ++ DBG_871X_SEL_NL(sel, "%s %s\n", "rtl8723bs", DRIVERVERSION); + } + + void dump_log_level(void *sel) +@@ -309,7 +309,6 @@ int proc_get_mlmext_state(struct seq_fil + return 0; + } + +-#ifdef CONFIG_LAYER2_ROAMING + int proc_get_roam_flags(struct seq_file *m, void *v) + { + struct net_device *dev = m->private; +@@ -411,7 +410,6 @@ ssize_t proc_set_roam_tgt_addr(struct fi + + return count; + } +-#endif /* CONFIG_LAYER2_ROAMING */ + + int proc_get_qos_option(struct seq_file *m, void *v) + { +@@ -463,18 +461,19 @@ int proc_get_survey_info(struct seq_file + s16 notify_noise = 0; + u16 index = 0; + +- _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); ++ spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); + phead = get_list_head(queue); ++ plist = phead ? get_next(phead) : NULL; + plist = get_next(phead); + if ((!phead) || (!plist)) { +- _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); ++ spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + return 0; + } + + DBG_871X_SEL_NL(m, "%5s %-17s %3s %-3s %-4s %-4s %5s %s\n","index", "bssid", "ch", "RSSI", "SdBm", "Noise", "age", "ssid"); + while(1) + { +- if (rtw_end_of_queue_search(phead,plist)== true) ++ if (phead == plist) + break; + + pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); +@@ -504,7 +503,7 @@ int proc_get_survey_info(struct seq_file + pnetwork->network.Ssid.Ssid); + plist = get_next(plist); + } +- _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL); ++ spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + + return 0; + } +@@ -1325,9 +1324,6 @@ ssize_t proc_set_rssi_disp(struct file * + + } + +- +-#ifdef CONFIG_AP_MODE +- + int proc_get_all_sta_info(struct seq_file *m, void *v) + { + struct net_device *dev = m->private; +@@ -1341,14 +1337,14 @@ int proc_get_all_sta_info(struct seq_fil + + DBG_871X_SEL_NL(m, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap); + +- _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL); ++ spin_lock_bh(&pstapriv->sta_hash_lock); + + for(i=0; i< NUM_STA; i++) + { + phead = &(pstapriv->sta_hash[i]); + plist = get_next(phead); + +- while ((rtw_end_of_queue_search(phead, plist)) == false) ++ while (phead != plist) + { + psta = LIST_CONTAINOR(plist, struct sta_info, hash_list); + +@@ -1394,12 +1390,10 @@ int proc_get_all_sta_info(struct seq_fil + + } + +- _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL); ++ spin_unlock_bh(&pstapriv->sta_hash_lock); + + return 0; + } +- +-#endif + + int proc_get_btcoex_dbg(struct seq_file *m, void *v) + { +@@ -1497,7 +1491,7 @@ int proc_get_btcoex_info(struct seq_file + + DBG_871X_SEL(m, "%s\n", pbuf); + +- rtw_mfree(pbuf, bufsize); ++ kfree(pbuf); + + return 0; + } +diff -Nurp linux/3rdparty/rtl8723bs.old/core/rtw_eeprom.c linux/3rdparty/rtl8723bs/core/rtw_eeprom.c +--- linux/3rdparty/rtl8723bs.old/core/rtw_eeprom.c 2015-05-10 14:36:05.666667879 +0300 ++++ linux/3rdparty/rtl8723bs/core/rtw_eeprom.c 1970-01-01 02:00:00.000000000 +0200 +@@ -1,381 +0,0 @@ +-/****************************************************************************** +- * +- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. +- * +- * This program is free software; you can redistribute it and/or modify it +- * under the terms of version 2 of the GNU General Public License as +- * published by the Free Software Foundation. +- * +- * This program is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +- * more details. +- * +- * You should have received a copy of the GNU General Public License along with +- * this program; if not, write to the Free Software Foundation, Inc., +- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +- * +- * +- ******************************************************************************/ +-#define _RTW_EEPROM_C_ +- +-#include +-#include +-#include +- +-void up_clk(_adapter* padapter, u16 *x) +-{ +-_func_enter_; +- *x = *x | _EESK; +- rtw_write8(padapter, EE_9346CR, (u8)*x); +- udelay(CLOCK_RATE); +- +-_func_exit_; +- +-} +- +-void down_clk(_adapter * padapter, u16 *x ) +-{ +-_func_enter_; +- *x = *x & ~_EESK; +- rtw_write8(padapter, EE_9346CR, (u8)*x); +- udelay(CLOCK_RATE); +-_func_exit_; +-} +- +-void shift_out_bits(_adapter * padapter, u16 data, u16 count) +-{ +- u16 x,mask; +-_func_enter_; +- +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- mask = 0x01 << (count - 1); +- x = rtw_read8(padapter, EE_9346CR); +- +- x &= ~(_EEDO | _EEDI); +- +- do +- { +- x &= ~_EEDI; +- if(data & mask) +- x |= _EEDI; +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- rtw_write8(padapter, EE_9346CR, (u8)x); +- udelay(CLOCK_RATE); +- up_clk(padapter, &x); +- down_clk(padapter, &x); +- mask = mask >> 1; +- } while(mask); +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- x &= ~_EEDI; +- rtw_write8(padapter, EE_9346CR, (u8)x); +-out: +-_func_exit_; +-} +- +-u16 shift_in_bits (_adapter * padapter) +-{ +- u16 x,d=0,i; +-_func_enter_; +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- x = rtw_read8(padapter, EE_9346CR); +- +- x &= ~( _EEDO | _EEDI); +- d = 0; +- +- for(i=0; i<16; i++) +- { +- d = d << 1; +- up_clk(padapter, &x); +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- x = rtw_read8(padapter, EE_9346CR); +- +- x &= ~(_EEDI); +- if(x & _EEDO) +- d |= 1; +- +- down_clk(padapter, &x); +- } +-out: +-_func_exit_; +- +- return d; +-} +- +-void standby(_adapter * padapter ) +-{ +- u8 x; +-_func_enter_; +- x = rtw_read8(padapter, EE_9346CR); +- +- x &= ~(_EECS | _EESK); +- rtw_write8(padapter, EE_9346CR,x); +- +- udelay(CLOCK_RATE); +- x |= _EECS; +- rtw_write8(padapter, EE_9346CR, x); +- udelay(CLOCK_RATE); +-_func_exit_; +-} +- +-u16 wait_eeprom_cmd_done(_adapter* padapter) +-{ +- u8 x; +- u16 i,res=false; +-_func_enter_; +- standby(padapter ); +- for (i=0; i<200; i++) +- { +- x = rtw_read8(padapter, EE_9346CR); +- if (x & _EEDO){ +- res=true; +- goto exit; +- } +- udelay(CLOCK_RATE); +- } +-exit: +-_func_exit_; +- return res; +-} +- +-void eeprom_clean(_adapter * padapter) +-{ +- u16 x; +-_func_enter_; +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- x = rtw_read8(padapter, EE_9346CR); +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- x &= ~(_EECS | _EEDI); +- rtw_write8(padapter, EE_9346CR, (u8)x); +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- up_clk(padapter, &x); +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- down_clk(padapter, &x); +-out: +-_func_exit_; +-} +- +-void eeprom_write16(_adapter * padapter, u16 reg, u16 data) +-{ +- u8 x; +- +-_func_enter_; +- +- x = rtw_read8(padapter, EE_9346CR); +- +- x &= ~(_EEDI | _EEDO | _EESK | _EEM0); +- x |= _EEM1 | _EECS; +- rtw_write8(padapter, EE_9346CR, x); +- +- shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5); +- +- if(padapter->EepromAddressSize==8) //CF+ and SDIO +- shift_out_bits(padapter, 0, 6); +- else //USB +- shift_out_bits(padapter, 0, 4); +- +- standby( padapter); +- +-// Commented out by rcnjko, 2004.0 +-// // Erase this particular word. Write the erase opcode and register +-// // number in that order. The opcode is 3bits in length; reg is 6 bits long. +-// shift_out_bits(Adapter, EEPROM_ERASE_OPCODE, 3); +-// shift_out_bits(Adapter, reg, Adapter->EepromAddressSize); +-// +-// if (wait_eeprom_cmd_done(Adapter ) == false) +-// { +-// return; +-// } +- +- +- standby(padapter ); +- +- // write the new word to the EEPROM +- +- // send the write opcode the EEPORM +- shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3); +- +- // select which word in the EEPROM that we are writing to. +- shift_out_bits(padapter, reg, padapter->EepromAddressSize); +- +- // write the data to the selected EEPROM word. +- shift_out_bits(padapter, data, 16); +- +- if (wait_eeprom_cmd_done(padapter ) == false) +- { +- +- goto exit; +- } +- +- standby(padapter ); +- +- shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5); +- shift_out_bits(padapter, reg, 4); +- +- eeprom_clean(padapter ); +-exit: +-_func_exit_; +- return; +-} +- +-u16 eeprom_read16(_adapter * padapter, u16 reg) //ReadEEprom +-{ +- +- u16 x; +- u16 data=0; +- +-_func_enter_; +- +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- // select EEPROM, reset bits, set _EECS +- x = rtw_read8(padapter, EE_9346CR); +- +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- +- x &= ~(_EEDI | _EEDO | _EESK | _EEM0); +- x |= _EEM1 | _EECS; +- rtw_write8(padapter, EE_9346CR, (unsigned char)x); +- +- // write the read opcode and register number in that order +- // The opcode is 3bits in length, reg is 6 bits long +- shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); +- shift_out_bits(padapter, reg, padapter->EepromAddressSize); +- +- // Now read the data (16 bits) in from the selected EEPROM word +- data = shift_in_bits(padapter); +- +- eeprom_clean(padapter); +-out: +-_func_exit_; +- return data; +- +- +-} +- +- +- +- +-//From even offset +-void eeprom_read_sz(_adapter * padapter, u16 reg, u8* data, u32 sz) +-{ +- +- u16 x, data16; +- u32 i; +-_func_enter_; +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- // select EEPROM, reset bits, set _EECS +- x = rtw_read8(padapter, EE_9346CR); +- +- if(padapter->bSurpriseRemoved==true){ +- RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==true")); +- goto out; +- } +- +- x &= ~(_EEDI | _EEDO | _EESK | _EEM0); +- x |= _EEM1 | _EECS; +- rtw_write8(padapter, EE_9346CR, (unsigned char)x); +- +- // write the read opcode and register number in that order +- // The opcode is 3bits in length, reg is 6 bits long +- shift_out_bits(padapter, EEPROM_READ_OPCODE, 3); +- shift_out_bits(padapter, reg, padapter->EepromAddressSize); +- +- +- for(i=0; i>8; +- } +- +- eeprom_clean(padapter); +-out: +-_func_exit_; +- +- +- +-} +- +- +-//addr_off : address offset of the entry in eeprom (not the tuple number of eeprom (reg); that is addr_off !=reg) +-u8 eeprom_read(_adapter * padapter, u32 addr_off, u8 sz, u8* rbuf) +-{ +- u8 quotient, remainder, addr_2align_odd; +- u16 reg, stmp , i=0, idx = 0; +-_func_enter_; +- reg = (u16)(addr_off >> 1); +- addr_2align_odd = (u8)(addr_off & 0x1); +- +- if(addr_2align_odd) //read that start at high part: e.g 1,3,5,7,9,... +- { +- stmp = eeprom_read16(padapter, reg); +- rbuf[idx++] = (u8) ((stmp>>8)&0xff); //return hogh-part of the short +- reg++; sz--; +- } +- +- quotient = sz >> 1; +- remainder = sz & 0x1; +- +- for( i=0 ; i < quotient; i++) +- { +- stmp = eeprom_read16(padapter, reg+i); +- rbuf[idx++] = (u8) (stmp&0xff); +- rbuf[idx++] = (u8) ((stmp>>8)&0xff); +- } +- +- reg = reg+i; +- if(remainder){ //end of read at lower part of short : 0,2,4,6,... +- stmp = eeprom_read16(padapter, reg); +- rbuf[idx] = (u8)(stmp & 0xff); +- } +-_func_exit_; +- return true; +-} +- +- +- +-void read_eeprom_content(_adapter * padapter) +-{ +- +-_func_enter_; +- +- +-_func_exit_; +-} +- +diff -Nurp linux/3rdparty/rtl8723bs.old/core/rtw_efuse.c linux/3rdparty/rtl8723bs/core/rtw_efuse.c +--- linux/3rdparty/rtl8723bs.old/core/rtw_efuse.c 2015-05-10 14:36:05.666667879 +0300 ++++ linux/3rdparty/rtl8723bs/core/rtw_efuse.c 2015-05-07 17:46:55.000000000 +0300 +@@ -121,18 +121,8 @@ Efuse_PowerSwitch( + pAdapter->HalFunc.EfusePowerSwitch(pAdapter, bWrite, PwrState); + } + +-void +-BTEfuse_PowerSwitch( +- IN PADAPTER pAdapter, +- IN u8 bWrite, +- IN u8 PwrState) +-{ +- if(pAdapter->HalFunc.BTEfusePowerSwitch) +- pAdapter->HalFunc.BTEfusePowerSwitch(pAdapter, bWrite, PwrState); +-} +- + /*----------------------------------------------------------------------------- +- * Function: efuse_GetCurrentSize ++ * Function: Efuse_GetCurrentSize + * + * Overview: Get current efuse size!!! + * +@@ -174,68 +164,6 @@ Efuse_CalculateWordCnts(IN u8 word_en) + + // + // Description: +-// Execute E-Fuse read byte operation. +-// Refered from SD1 Richard. +-// +-// Assumption: +-// 1. Boot from E-Fuse and successfully auto-load. +-// 2. PASSIVE_LEVEL (USB interface) +-// +-// Created by Roger, 2008.10.21. +-// +-void +-ReadEFuseByte( +- PADAPTER Adapter, +- u16 _offset, +- u8 *pbuf, +- IN bool bPseudoTest) +-{ +- u32 value32; +- u8 readbyte; +- u16 retry; +- +- if(bPseudoTest) +- { +- Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf); +- return; +- } +- // <20130121, Kordan> For SMIC S55 EFUSE specificatoin. +- //0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) +- PHY_SetMacReg(Adapter, EFUSE_TEST, BIT11, 0); +- +- //Write Address +- rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff)); +- readbyte = rtw_read8(Adapter, EFUSE_CTRL+2); +- rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc)); +- +- //Write bit 32 0 +- readbyte = rtw_read8(Adapter, EFUSE_CTRL+3); +- rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f)); +- +- //Check bit 32 read-ready +- retry = 0; +- value32 = rtw_read32(Adapter, EFUSE_CTRL); +- //while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) +- while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10000)) +- { +- value32 = rtw_read32(Adapter, EFUSE_CTRL); +- retry++; +- } +- +- // 20100205 Joseph: Add delay suggested by SD1 Victor. +- // This fix the problem that Efuse read error in high temperature condition. +- // Designer says that there shall be some delay after ready bit is set, or the +- // result will always stay on last data we read. +- udelay(50); +- value32 = rtw_read32(Adapter, EFUSE_CTRL); +- +- *pbuf = (u8)(value32 & 0xff); +- //DBG_871X("ReadEFuseByte _offset:%08u, in %d ms\n",_offset ,jiffies_to_msecs(jiffies - start)); +- +-} +- +-// +-// Description: + // 1. Execute E-Fuse read byte operation according as map offset and + // save to E-Fuse table. + // 2. Refered from SD1 Richard. +@@ -350,76 +278,6 @@ EFUSE_Read1Byte( + + }/* EFUSE_Read1Byte */ + +-/*----------------------------------------------------------------------------- +- * Function: EFUSE_Write1Byte +- * +- * Overview: Copy from WMAC fot EFUSE write 1 byte. +- * +- * Input: NONE +- * +- * Output: NONE +- * +- * Return: NONE +- * +- * Revised History: +- * When Who Remark +- * 09/23/2008 MHC Copy from WMAC. +- * +- *---------------------------------------------------------------------------*/ +- +-void +-EFUSE_Write1Byte( +- IN PADAPTER Adapter, +- IN u16 Address, +- IN u8 Value); +-void +-EFUSE_Write1Byte( +- IN PADAPTER Adapter, +- IN u16 Address, +- IN u8 Value) +-{ +- u8 Bytetemp = {0x00}; +- u8 temp = {0x00}; +- u32 k=0; +- u16 contentLen=0; +- +- //RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr=%x Data =%x\n", Address, Value)); +- EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false); +- +- if( Address < contentLen) //E-fuse 512Byte +- { +- rtw_write8(Adapter, EFUSE_CTRL, Value); +- +- //Write E-fuse Register address bit0~7 +- temp = Address & 0xFF; +- rtw_write8(Adapter, EFUSE_CTRL+1, temp); +- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2); +- +- //Write E-fuse Register address bit8~9 +- temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); +- rtw_write8(Adapter, EFUSE_CTRL+2, temp); +- +- //Write 0x30[31]=1 +- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); +- temp = Bytetemp | 0x80; +- rtw_write8(Adapter, EFUSE_CTRL+3, temp); +- +- //Wait Write-ready (0x30[31]=0) +- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); +- while(Bytetemp & 0x80) +- { +- Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); +- k++; +- if(k==100) +- { +- k=0; +- break; +- } +- } +- } +-}/* EFUSE_Write1Byte */ +- +- + /* 11/16/2008 MH Read one byte from real Efuse. */ + u8 + efuse_OneByteRead( +@@ -642,289 +500,6 @@ Efuse_WordEnableDataWrite( IN PADAPTER p + return ret; + } + +-static u8 efuse_read8(PADAPTER padapter, u16 address, u8 *value) +-{ +- return efuse_OneByteRead(padapter,address, value, false); +-} +- +-static u8 efuse_write8(PADAPTER padapter, u16 address, u8 *value) +-{ +- return efuse_OneByteWrite(padapter,address, *value, false); +-} +- +-/* +- * read/wirte raw efuse data +- */ +-u8 rtw_efuse_access(PADAPTER padapter, u8 bWrite, u16 start_addr, u16 cnts, u8 *data) +-{ +- int i = 0; +- u16 real_content_len = 0, max_available_size = 0; +- u8 res = _FAIL ; +- u8 (*rw8)(PADAPTER, u16, u8*); +- +- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&real_content_len, false); +- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_available_size, false); +- +- if (start_addr > real_content_len) +- return _FAIL; +- +- if (true == bWrite) { +- if ((start_addr + cnts) > max_available_size) +- return _FAIL; +- rw8 = &efuse_write8; +- } else +- rw8 = &efuse_read8; +- +- Efuse_PowerSwitch(padapter, bWrite, true); +- +- // e-fuse one byte read / write +- for (i = 0; i < cnts; i++) { +- if (start_addr >= real_content_len) { +- res = _FAIL; +- break; +- } +- +- res = rw8(padapter, start_addr++, data++); +- if (_FAIL == res) break; +- } +- +- Efuse_PowerSwitch(padapter, bWrite, false); +- +- return res; +-} +-//------------------------------------------------------------------------------ +-u16 efuse_GetMaxSize(PADAPTER padapter) +-{ +- u16 max_size; +- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (void *)&max_size, false); +- return max_size; +-} +-//------------------------------------------------------------------------------ +-u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size) +-{ +- Efuse_PowerSwitch(padapter, false, true); +- *size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, false); +- Efuse_PowerSwitch(padapter, false, false); +- +- return _SUCCESS; +-} +-//------------------------------------------------------------------------------ +-u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data) +-{ +- u16 mapLen=0; +- +- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); +- +- if ((addr + cnts) > mapLen) +- return _FAIL; +- +- Efuse_PowerSwitch(padapter, false, true); +- +- efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, false); +- +- Efuse_PowerSwitch(padapter, false, false); +- +- return _SUCCESS; +-} +- +-u8 rtw_BT_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data) +-{ +- u16 mapLen=0; +- +- EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); +- +- if ((addr + cnts) > mapLen) +- return _FAIL; +- +- Efuse_PowerSwitch(padapter, false, true); +- +- efuse_ReadEFuse(padapter, EFUSE_BT, addr, cnts, data, false); +- +- Efuse_PowerSwitch(padapter, false, false); +- +- return _SUCCESS; +-} +-//------------------------------------------------------------------------------ +-u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data) +-{ +-#define RT_ASSERT_RET(expr) \ +- if(!(expr)) { \ +- printk( "Assertion failed! %s at ......\n", #expr); \ +- printk( " ......%s,%s,line=%d\n",__FILE__,__FUNCTION__,__LINE__); \ +- return _FAIL; \ +- } +- +- u8 offset, word_en; +- u8 *map; +- u8 newdata[PGPKT_DATA_SIZE]; +- s32 i, j, idx; +- u8 ret = _SUCCESS; +- u16 mapLen=0; +- EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); +- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +- +- EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, false); +- +- if ((addr + cnts) > mapLen) +- return _FAIL; +- +- RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); // have to be 8 byte alignment +- RT_ASSERT_RET((mapLen & 0x7) == 0); // have to be PGPKT_DATA_SIZE alignment for memcpy +- +- map = rtw_zmalloc(mapLen); +- if(map == NULL){ +- return _FAIL; +- } +- +- memset(map, 0xFF, mapLen); +- +- ret = rtw_efuse_map_read(padapter, 0, mapLen, map); +- if (ret == _FAIL) goto exit; +- +- Efuse_PowerSwitch(padapter, true, true); +- +- idx = 0; +- offset = (addr >> 3); +- while (idx < cnts) +- { +- word_en = 0xF; +- j = (addr + idx) & 0x7; +- memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE); +- for (i = j; i> 1); +- newdata[i] = data[idx]; +- +- if( addr + idx == 0x8) +- { +- if (IS_C_CUT(pHalData->VersionID) || IS_B_CUT(pHalData->VersionID)) +- { +- if(pEEPROM->adjuseVoltageVal == 6) +- { +- newdata[i] = map[addr + idx]; +- DBG_8192C(" %s ,\n adjuseVoltageVal = %d ,newdata[%d] = %x \n",__func__,pEEPROM->adjuseVoltageVal,i,newdata[i]); +- } +- } +- } +- } +- } +- +- if (word_en != 0xF) { +- ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, false); +- DBG_871X("offset=%x \n",offset); +- DBG_871X("word_en=%x \n",word_en); +- +- for(i=0;i mapLen) +- return _FAIL; +- +- RT_ASSERT_RET(PGPKT_DATA_SIZE == 8); // have to be 8 byte alignment +- RT_ASSERT_RET((mapLen & 0x7) == 0); // have to be PGPKT_DATA_SIZE alignment for memcpy +- +- map = rtw_zmalloc(mapLen); +- if(map == NULL){ +- return _FAIL; +- } +- +- ret = rtw_BT_efuse_map_read(padapter, 0, mapLen, map); +- if (ret == _FAIL) goto exit; +- DBG_871X("OFFSET\tVALUE(hex)\n"); +- for (i=0; i<1024; i+=16) // set 512 because the iwpriv's extra size have limit 0x7FF +- { +- DBG_871X("0x%03x\t", i); +- for (j=0; j<8; j++) { +- DBG_871X("%02X ", map[i+j]); +- } +- DBG_871X("\t"); +- for (; j<16; j++) { +- DBG_871X("%02X ", map[i+j]); +- } +- DBG_871X("\n"); +- } +- DBG_871X("\n"); +- Efuse_PowerSwitch(padapter, true, true); +- +- idx = 0; +- offset = (addr >> 3); +- while (idx < cnts) +- { +- word_en = 0xF; +- j = (addr + idx) & 0x7; +- memcpy(newdata, &map[offset << 3], PGPKT_DATA_SIZE); +- for (i = j; i> 1); +- newdata[i] = data[idx]; +- } +- } +- +- if (word_en != 0xF) { +- DBG_871X("offset=%x \n",offset); +- DBG_871X("word_en=%x \n",word_en); +- DBG_871X("%s: data=", __FUNCTION__); +- for(i=0;i

Setting the serial port speed over 115,200bps

++
++If you have motherboard which has VIA VT82C686A or VT82C686B chipset ++you can set serial ports in high speed mode with this kernel module. ++I use module with external ISDN-TA and haven't had any problems ++so far but I cannot guarantee that you won't have buffer overflows if ++you use full 230K or 460K speed all the time (FIFO's are still 16550A size). ++ISDN with two channels maxes out at 128 Kb which means that it doesn't ++really stress serial ports at 230400. Unlike SHSMOD-patches you don't have ++to patch serial driver and module takes only 1KB of memory when it's ++loaded which should leave enough room for other programs. It should ++be also possible to make this work from userspace but accessing ++pci devices is so much easier from kernel. ++ ++

How to use module

++Get the
package ++and compile it using included makefiles. ++

For 2.4

++If you have kernel in some other location than /usr/src/linux edit Makefile ++before compiling. You can also install module with "make install". After ++you have loaded module in kernel (use modprobe or insmod) you can set serial ++ports to use high speed modes with setserial.
++

For 2.5/2.6

++Copy Makefile-2.6 on top of Makefile and do make. After loading module set ++serial speed with setserial. (NOTE: This gives a warning on depracated ++method). ++ ++
++# setserial /dev/ttyS0 spd_cust divisor 0x8002 ++

++which sets COM1: speed to 230400. With 0x8001 you should get 460800 ++but I haven't tested it. If you want to use COM2: use ttyS1 instead of ttyS0. ++ ++After this you should set program which you are using to use 38400 bps ++speed which is now actually 230K or 460K. For more information check ++setserial man page (spd_cust). ++ ++You can use serial port work as normal if you do
++
++# setserial /dev/ttyS0 spd_normal

++After this you can also remove viahss module with rmmod if you need to. Module doesn't intefere with normal serial port usage so you can leave ++it loaded if you don't need that extra 1KB which module uses. ++

Download

++viahss-0.92.tar.gz ++ ++

Acknowledgments

++ ++Thanks to Kimmo Rintala for help with divisor settings.
++I also like to thank Jeff Garzik for help with VIA datasheets.
++Port to 2.5/2.6 by Kingsly John with the help of LWN ++ ++

Version History

++0.90 First release
++0.91 Fixed Makefile
++0.92 Fixed for 2.5/2.6
++ ++

Contact

++ ++You can reach me by email: jrauti@iki.fi ++ ++ +diff -Nurp linux-2.6.37/3rdparty/viahss/viahss.c linux-2.6.37.3rdparty/3rdparty/viahss/viahss.c +--- linux-2.6.37/3rdparty/viahss/viahss.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3rdparty/3rdparty/viahss/viahss.c 2003-07-17 09:49:59.000000000 +0300 +@@ -0,0 +1,83 @@ ++/* ++ * VIA VT 82c686[AB] high speed serial port enabler ++ * Version 0.92 ++ * Copyright (c) 2000-2001 Juhani Rautiainen ++ * ++ * 0.92: ++ * Ported to 2.5/2.6 by Kingsly John ++ * - Corrected locking (no more cli() and sti()) ++ * - New makefile ++ * ++ * Can be freely distributed and used under the terms of the GNU GPL. ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++ ++const unsigned short confindex=0x3F0,confdata=0x3F1; ++const unsigned char spcidx=0xEE; ++ ++spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; ++ ++static int __init viahss_init(void) ++{ ++ struct pci_dev *pcidev = NULL; ++ unsigned char confval,val; ++ pcidev = pci_find_device (PCI_VENDOR_ID_VIA,PCI_DEVICE_ID_VIA_82C686,NULL); ++ if (pcidev) { ++ spin_lock_irq(&driver_lock); ++ /* start config */ ++ pci_read_config_byte(pcidev,0x85,&confval); ++ confval |= 0x2; ++ pci_write_config_byte (pcidev, 0x85,confval); ++ /* activate high speed bits */ ++ outb(spcidx,confindex); /* set index */ ++ val = (unsigned char) inb(confdata); ++ val |= 0xC0; /* both ports on high speed*/ ++ outb (spcidx,confindex); ++ outb (val,confdata); ++ /*stop config*/ ++ confval &= ~0x2; ++ pci_write_config_byte(pcidev, 0x85, confval); ++ spin_unlock_irq(&driver_lock); ++ printk (KERN_INFO "VIA VT82C686[AB] serial port high speed enabled\n"); ++ } ++ else { ++ printk (KERN_INFO "Couldn't locate VIA chipset\n"); ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++static void __exit viahss_exit(void) ++{ ++ struct pci_dev *pcidev = NULL; ++ unsigned char confval,val; ++ pcidev = pci_find_device (PCI_VENDOR_ID_VIA,PCI_DEVICE_ID_VIA_82C686,NULL); ++ if (pcidev) { ++ spin_lock_irq(&driver_lock); ++ /* start config */ ++ pci_read_config_byte(pcidev,0x85,&confval); ++ confval |= 0x2; ++ pci_write_config_byte (pcidev, 0x85,confval); ++ /* activate high speed bits */ ++ outb(spcidx,confindex); /* set index */ ++ val = (unsigned char) inb(confdata); ++ val &= ~0xC0; /* both ports off high speed*/ ++ outb (spcidx,confindex); ++ outb (val,confdata); ++ /*stop config*/ ++ confval &= ~0x2; ++ pci_write_config_byte(pcidev, 0x85, confval); ++ spin_unlock_irq(&driver_lock); ++ printk (KERN_INFO "VIA VT82C686[AB] serial port high speed disabled\n"); ++ } ++} ++ ++module_init(viahss_init); ++module_exit(viahss_exit); ++MODULE_DESCRIPTION("VIA VT82C686[AB] high speed serial port enabler"); ++MODULE_AUTHOR("Juhani Rautiainen "); diff --git a/kernel/kernel/files/patches/mageia/3rd-viahss-2.6.35-buildfix.patch b/kernel/kernel/files/patches/mageia/3rd-viahss-2.6.35-buildfix.patch new file mode 100644 index 00000000..5ae42e92 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-viahss-2.6.35-buildfix.patch @@ -0,0 +1,20 @@ +--- linux-2.6.35-rc6-git-mnb0.1/3rdparty/viahss/viahss.c.orig 2010-07-30 21:17:30.000000000 +0300 ++++ linux-2.6.35-rc6-git-mnb0.1/3rdparty/viahss/viahss.c 2010-07-30 23:10:21.324978822 +0300 +@@ -25,7 +25,7 @@ static int __init viahss_init(void) + { + struct pci_dev *pcidev = NULL; + unsigned char confval,val; +- pcidev = pci_find_device (PCI_VENDOR_ID_VIA,PCI_DEVICE_ID_VIA_82C686,NULL); ++ pcidev = pci_get_device (PCI_VENDOR_ID_VIA,PCI_DEVICE_ID_VIA_82C686,NULL); + if (pcidev) { + spin_lock_irq(&driver_lock); + /* start config */ +@@ -55,7 +55,7 @@ static void __exit viahss_exit(void) + { + struct pci_dev *pcidev = NULL; + unsigned char confval,val; +- pcidev = pci_find_device (PCI_VENDOR_ID_VIA,PCI_DEVICE_ID_VIA_82C686,NULL); ++ pcidev = pci_get_device (PCI_VENDOR_ID_VIA,PCI_DEVICE_ID_VIA_82C686,NULL); + if (pcidev) { + spin_lock_irq(&driver_lock); + /* start config */ diff --git a/kernel/kernel/files/patches/mageia/3rd-viahss-3.0-buildfix.patch b/kernel/kernel/files/patches/mageia/3rd-viahss-3.0-buildfix.patch new file mode 100644 index 00000000..7db73881 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-viahss-3.0-buildfix.patch @@ -0,0 +1,19 @@ + +fix build with 3.0 + +Signed-off-by: Thomas Backlund + + 3rdparty/viahss/viahss.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/3rdparty/viahss/viahss.c.orig 2011-07-15 02:37:27.000000000 +0300 ++++ a/3rdparty/viahss/viahss.c 2011-07-15 13:48:13.204291256 +0300 +@@ -19,7 +19,7 @@ + const unsigned short confindex=0x3F0,confdata=0x3F1; + const unsigned char spcidx=0xEE; + +-spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; ++DEFINE_SPINLOCK(driver_lock); + + static int __init viahss_init(void) + { diff --git a/kernel/kernel/files/patches/mageia/3rd-viahss-config.patch b/kernel/kernel/files/patches/mageia/3rd-viahss-config.patch new file mode 100644 index 00000000..0d1bdbd3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-viahss-config.patch @@ -0,0 +1,18 @@ +linux/config.h is gone in 2.6.21 + +--- + 3rdparty/viahss/viahss.c | 1 0 + 1 - 0 ! + 1 files changed, 1 deletion(-) + +Index: linux-2.6.21/3rdparty/viahss/viahss.c +=================================================================== +--- linux-2.6.21.orig/3rdparty/viahss/viahss.c 2003-07-17 08:49:59.000000000 +0200 ++++ linux-2.6.21/3rdparty/viahss/viahss.c 2007-05-14 17:06:56.000000000 +0200 +@@ -12,7 +12,6 @@ + */ + + #include +-#include + #include + #include + #include diff --git a/kernel/kernel/files/patches/mageia/3rd-viahss-module-license.patch b/kernel/kernel/files/patches/mageia/3rd-viahss-module-license.patch new file mode 100644 index 00000000..540538f2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rd-viahss-module-license.patch @@ -0,0 +1,7 @@ +--- linux-2.6.25/3rdparty/viahss/viahss.c.orig 2008-06-28 22:50:05.000000000 +0300 ++++ linux-2.6.25/3rdparty/viahss/viahss.c 2008-06-29 14:26:55.000000000 +0300 +@@ -80,3 +80,4 @@ module_init(viahss_init); + module_exit(viahss_exit); + MODULE_DESCRIPTION("VIA VT82C686[AB] high speed serial port enabler"); + MODULE_AUTHOR("Juhani Rautiainen "); ++MODULE_LICENSE("GPL"); diff --git a/kernel/kernel/files/patches/mageia/3rdparty.series b/kernel/kernel/files/patches/mageia/3rdparty.series new file mode 100644 index 00000000..17ace736 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/3rdparty.series @@ -0,0 +1,3 @@ +# Mageia SVN does not like binaries in /packages tree +# it can still be used for out ov svn builds + diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-disable-changing-resolution-rate-scale.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-disable-changing-resolution-rate-scale.patch new file mode 100644 index 00000000..ef5539be --- /dev/null +++ b/kernel/kernel/files/patches/mageia/Input-psmouse-disable-changing-resolution-rate-scale.patch @@ -0,0 +1,128 @@ +From 4ec212f003d2430b0b2748b8a3008255f39cfe13 Mon Sep 17 00:00:00 2001 +From: Mathias Gottschlag +Date: Sat, 7 Mar 2015 13:31:45 -0800 +Subject: [PATCH 3/4] Input: psmouse - disable changing resolution/rate/scale + for FocalTech + +These PS/2 commands make some touchpads stop responding, so this commit +adds some dummy functions to replace the generic implementation. Because +scale changes were not encapsulated in a method of struct psmouse yet, this +commit adds a method set_scale to psmouse. + +Signed-off-by: Mathias Gottschlag +Signed-off-by: Dmitry Torokhov +--- + drivers/input/mouse/focaltech.c | 25 +++++++++++++++++++++++++ + drivers/input/mouse/psmouse-base.c | 14 +++++++++++++- + drivers/input/mouse/psmouse.h | 6 ++++++ + 3 files changed, 44 insertions(+), 1 deletion(-) + +diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c +index c66e0e0..891a271 100644 +--- a/drivers/input/mouse/focaltech.c ++++ b/drivers/input/mouse/focaltech.c +@@ -386,6 +386,23 @@ static int focaltech_read_size(struct psmouse *psmouse) + + return 0; + } ++ ++void focaltech_set_resolution(struct psmouse *psmouse, unsigned int resolution) ++{ ++ /* not supported yet */ ++} ++ ++static void focaltech_set_rate(struct psmouse *psmouse, unsigned int rate) ++{ ++ /* not supported yet */ ++} ++ ++static void focaltech_set_scale(struct psmouse *psmouse, ++ enum psmouse_scale scale) ++{ ++ /* not supported yet */ ++} ++ + int focaltech_init(struct psmouse *psmouse) + { + struct focaltech_data *priv; +@@ -420,6 +437,14 @@ int focaltech_init(struct psmouse *psmouse) + psmouse->cleanup = focaltech_reset; + /* resync is not supported yet */ + psmouse->resync_time = 0; ++ /* ++ * rate/resolution/scale changes are not supported yet, and ++ * the generic implementations of these functions seem to ++ * confuse some touchpads ++ */ ++ psmouse->set_resolution = focaltech_set_resolution; ++ psmouse->set_rate = focaltech_set_rate; ++ psmouse->set_scale = focaltech_set_scale; + + return 0; + +diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c +index 4ccd01d..8bc6123 100644 +--- a/drivers/input/mouse/psmouse-base.c ++++ b/drivers/input/mouse/psmouse-base.c +@@ -454,6 +454,17 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) + } + + /* ++ * Here we set the mouse scaling. ++ */ ++ ++static void psmouse_set_scale(struct psmouse *psmouse, enum psmouse_scale scale) ++{ ++ ps2_command(&psmouse->ps2dev, NULL, ++ scale == PSMOUSE_SCALE21 ? PSMOUSE_CMD_SETSCALE21 : ++ PSMOUSE_CMD_SETSCALE11); ++} ++ ++/* + * psmouse_poll() - default poll handler. Everyone except for ALPS uses it. + */ + +@@ -689,6 +700,7 @@ static void psmouse_apply_defaults(struct psmouse *psmouse) + + psmouse->set_rate = psmouse_set_rate; + psmouse->set_resolution = psmouse_set_resolution; ++ psmouse->set_scale = psmouse_set_scale; + psmouse->poll = psmouse_poll; + psmouse->protocol_handler = psmouse_process_byte; + psmouse->pktsize = 3; +@@ -1160,7 +1172,7 @@ static void psmouse_initialize(struct psmouse *psmouse) + if (psmouse_max_proto != PSMOUSE_PS2) { + psmouse->set_rate(psmouse, psmouse->rate); + psmouse->set_resolution(psmouse, psmouse->resolution); +- ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11); ++ psmouse->set_scale(psmouse, PSMOUSE_SCALE11); + } + } + +diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h +index c2ff137..d02e1bd 100644 +--- a/drivers/input/mouse/psmouse.h ++++ b/drivers/input/mouse/psmouse.h +@@ -36,6 +36,11 @@ typedef enum { + PSMOUSE_FULL_PACKET + } psmouse_ret_t; + ++enum psmouse_scale { ++ PSMOUSE_SCALE11, ++ PSMOUSE_SCALE21 ++}; ++ + struct psmouse { + void *private; + struct input_dev *dev; +@@ -67,6 +72,7 @@ struct psmouse { + psmouse_ret_t (*protocol_handler)(struct psmouse *psmouse); + void (*set_rate)(struct psmouse *psmouse, unsigned int rate); + void (*set_resolution)(struct psmouse *psmouse, unsigned int resolution); ++ void (*set_scale)(struct psmouse *psmouse, enum psmouse_scale scale); + + int (*reconnect)(struct psmouse *psmouse); + void (*disconnect)(struct psmouse *psmouse); +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-disable-palm-detection-in-the-focaltec.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-disable-palm-detection-in-the-focaltec.patch new file mode 100644 index 00000000..a149f053 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/Input-psmouse-disable-palm-detection-in-the-focaltec.patch @@ -0,0 +1,41 @@ +From 4eb8d6e7e5aa14572bc389e554aad9869188cdcd Mon Sep 17 00:00:00 2001 +From: Mathias Gottschlag +Date: Sat, 7 Mar 2015 13:38:27 -0800 +Subject: [PATCH 4/4] Input: psmouse - disable "palm detection" in the + focaltech driver + +Apparently, the threshold for large contact area seems to be rather low on +some devices, causing the touchpad to frequently freeze during normal +usage. Because we do now know how we are supposed to use the value in +question, this commit just drops the related code completely. + +Signed-off-by: Mathias Gottschlag +Signed-off-by: Dmitry Torokhov +--- + drivers/input/mouse/focaltech.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c +index 891a271..23d2594 100644 +--- a/drivers/input/mouse/focaltech.c ++++ b/drivers/input/mouse/focaltech.c +@@ -185,16 +185,6 @@ static void focaltech_process_abs_packet(struct psmouse *psmouse, + + state->pressed = (packet[0] >> 4) & 1; + +- /* +- * packet[5] contains some kind of tool size in the most +- * significant nibble. 0xff is a special value (latching) that +- * signals a large contact area. +- */ +- if (packet[5] == 0xff) { +- state->fingers[finger].valid = false; +- return; +- } +- + state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2]; + state->fingers[finger].y = (packet[3] << 8) | packet[4]; + state->fingers[finger].valid = true; +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-ensure-that-focaltech-reports-consiste.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-ensure-that-focaltech-reports-consiste.patch new file mode 100644 index 00000000..149d2d03 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/Input-psmouse-ensure-that-focaltech-reports-consiste.patch @@ -0,0 +1,44 @@ +From 679d83ea9390636ded518f533af0cefbade317c7 Mon Sep 17 00:00:00 2001 +From: Mathias Gottschlag +Date: Sat, 7 Mar 2015 13:26:43 -0800 +Subject: [PATCH 2/4] Input: psmouse - ensure that focaltech reports consistent + coordinates + +We don't know whether x_max or y_max really hold the maximum possible +coordinates, and we don't know for sure whether we correctly interpret the +coordinates sent by the touchpad, so we clamp the reported values to +prevent confusion in userspace code. + +Signed-off-by: Mathias Gottschlag +Signed-off-by: Dmitry Torokhov +--- + drivers/input/mouse/focaltech.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c +index e8fafe8..c66e0e0 100644 +--- a/drivers/input/mouse/focaltech.c ++++ b/drivers/input/mouse/focaltech.c +@@ -126,9 +126,17 @@ static void focaltech_report_state(struct psmouse *psmouse) + input_mt_slot(dev, i); + input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); + if (active) { +- input_report_abs(dev, ABS_MT_POSITION_X, finger->x); ++ unsigned int clamped_x, clamped_y; ++ /* ++ * The touchpad might report invalid data, so we clamp ++ * the resulting values so that we do not confuse ++ * userspace. ++ */ ++ clamped_x = clamp(finger->x, 0U, priv->x_max); ++ clamped_y = clamp(finger->y, 0U, priv->y_max); ++ input_report_abs(dev, ABS_MT_POSITION_X, clamped_x); + input_report_abs(dev, ABS_MT_POSITION_Y, +- priv->y_max - finger->y); ++ priv->y_max - clamped_y); + } + } + input_mt_report_pointer_emulation(dev, true); +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-remove-hardcoded-touchpad-size-from-th.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-remove-hardcoded-touchpad-size-from-th.patch new file mode 100644 index 00000000..4fbb78e2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/Input-psmouse-remove-hardcoded-touchpad-size-from-th.patch @@ -0,0 +1,41 @@ +From 3e9845251926723319fb60c9e546fe42d3d11687 Mon Sep 17 00:00:00 2001 +From: Mathias Gottschlag +Date: Sat, 7 Mar 2015 13:26:06 -0800 +Subject: [PATCH 1/4] Input: psmouse - remove hardcoded touchpad size from the + focaltech driver + +The size has in most cases already been fetched from the touchpad, the +hardcoded values should have been removed. + +Signed-off-by: Mathias Gottschlag +Signed-off-by: Dmitry Torokhov +--- + drivers/input/mouse/focaltech.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c +index 757f78a..e8fafe8 100644 +--- a/drivers/input/mouse/focaltech.c ++++ b/drivers/input/mouse/focaltech.c +@@ -67,9 +67,6 @@ static void focaltech_reset(struct psmouse *psmouse) + + #define FOC_MAX_FINGERS 5 + +-#define FOC_MAX_X 2431 +-#define FOC_MAX_Y 1663 +- + /* + * Current state of a single finger on the touchpad. + */ +@@ -131,7 +128,7 @@ static void focaltech_report_state(struct psmouse *psmouse) + if (active) { + input_report_abs(dev, ABS_MT_POSITION_X, finger->x); + input_report_abs(dev, ABS_MT_POSITION_Y, +- FOC_MAX_Y - finger->y); ++ priv->y_max - finger->y); + } + } + input_mt_report_pointer_emulation(dev, true); +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/Input-psmouse-support-for-the-FocalTech-PS-2-protoco.patch b/kernel/kernel/files/patches/mageia/Input-psmouse-support-for-the-FocalTech-PS-2-protoco.patch new file mode 100644 index 00000000..8dde13fa --- /dev/null +++ b/kernel/kernel/files/patches/mageia/Input-psmouse-support-for-the-FocalTech-PS-2-protoco.patch @@ -0,0 +1,585 @@ +From 05be1d079ec0b3691783e4384b1ada82149ff7d2 Mon Sep 17 00:00:00 2001 +From: Mathias Gottschlag +Date: Mon, 29 Dec 2014 09:26:10 -0800 +Subject: [PATCH] Input: psmouse - support for the FocalTech PS/2 protocol + extensions + +Most of the protocol for these touchpads has been reverse engineered. This +commit adds a basic multitouch-capable driver. + +A lot of the protocol is still unknown. Especially, we don't know how to +identify the device yet apart from the PNP ID. + +The previous workaround for these devices has been left in place in case +the driver is not compiled into the kernel or in case some other device +with the same PNP ID is not recognized by the driver yet still has the same +problems with the device probing code. + +Signed-off-by: Mathias Gottschlag +Reviewed-by: Hans de Goede +Signed-off-by: Dmitry Torokhov +--- + drivers/input/mouse/Kconfig | 10 + + drivers/input/mouse/focaltech.c | 408 ++++++++++++++++++++++++++++++++++++- + drivers/input/mouse/focaltech.h | 2 + + drivers/input/mouse/psmouse-base.c | 32 ++- + drivers/input/mouse/psmouse.h | 1 + + 5 files changed, 436 insertions(+), 17 deletions(-) + +diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig +index d8b46b0..2541bfa 100644 +--- a/drivers/input/mouse/Kconfig ++++ b/drivers/input/mouse/Kconfig +@@ -146,6 +146,16 @@ config MOUSE_PS2_OLPC + + If unsure, say N. + ++config MOUSE_PS2_FOCALTECH ++ bool "FocalTech PS/2 mouse protocol extension" if EXPERT ++ default y ++ depends on MOUSE_PS2 ++ help ++ Say Y here if you have a FocalTech PS/2 TouchPad connected to ++ your system. ++ ++ If unsure, say Y. ++ + config MOUSE_SERIAL + tristate "Serial mouse" + select SERIO +diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c +index f4d657e..fca38ba 100644 +--- a/drivers/input/mouse/focaltech.c ++++ b/drivers/input/mouse/focaltech.c +@@ -2,6 +2,7 @@ + * Focaltech TouchPad PS/2 mouse driver + * + * Copyright (c) 2014 Red Hat Inc. ++ * Copyright (c) 2014 Mathias Gottschlag + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -13,15 +14,14 @@ + * Hans de Goede + */ + +-/* +- * The Focaltech PS/2 touchpad protocol is unknown. This drivers deals with +- * detection only, to avoid further detection attempts confusing the touchpad +- * this way it at least works in PS/2 mouse compatibility mode. +- */ + + #include + #include ++#include ++#include ++#include + #include "psmouse.h" ++#include "focaltech.h" + + static const char * const focaltech_pnp_ids[] = { + "FLT0101", +@@ -30,6 +30,12 @@ static const char * const focaltech_pnp_ids[] = { + NULL + }; + ++/* ++ * Even if the kernel is built without support for Focaltech PS/2 touchpads (or ++ * when the real driver fails to recognize the device), we still have to detect ++ * them in order to avoid further detection attempts confusing the touchpad. ++ * This way it at least works in PS/2 mouse compatibility mode. ++ */ + int focaltech_detect(struct psmouse *psmouse, bool set_properties) + { + if (!psmouse_matches_pnp_id(psmouse, focaltech_pnp_ids)) +@@ -37,16 +43,404 @@ int focaltech_detect(struct psmouse *psmouse, bool set_properties) + + if (set_properties) { + psmouse->vendor = "FocalTech"; +- psmouse->name = "FocalTech Touchpad in mouse emulation mode"; ++ psmouse->name = "FocalTech Touchpad"; + } + + return 0; + } + +-int focaltech_init(struct psmouse *psmouse) ++static void focaltech_reset(struct psmouse *psmouse) + { + ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); + psmouse_reset(psmouse); ++} ++ ++#ifdef CONFIG_MOUSE_PS2_FOCALTECH ++ ++/* ++ * Packet types - the numbers are not consecutive, so we might be missing ++ * something here. ++ */ ++#define FOC_TOUCH 0x3 /* bitmap of active fingers */ ++#define FOC_ABS 0x6 /* absolute position of one finger */ ++#define FOC_REL 0x9 /* relative position of 1-2 fingers */ ++ ++#define FOC_MAX_FINGERS 5 ++ ++#define FOC_MAX_X 2431 ++#define FOC_MAX_Y 1663 ++ ++/* ++ * Current state of a single finger on the touchpad. ++ */ ++struct focaltech_finger_state { ++ /* The touchpad has generated a touch event for the finger */ ++ bool active; ++ ++ /* ++ * The touchpad has sent position data for the finger. The ++ * flag is 0 when the finger is not active, and there is a ++ * time between the first touch event for the finger and the ++ * following absolute position packet for the finger where the ++ * touchpad has declared the finger to be valid, but we do not ++ * have any valid position yet. ++ */ ++ bool valid; ++ ++ /* ++ * Absolute position (from the bottom left corner) of the ++ * finger. ++ */ ++ unsigned int x; ++ unsigned int y; ++}; ++ ++/* ++ * Description of the current state of the touchpad hardware. ++ */ ++struct focaltech_hw_state { ++ /* ++ * The touchpad tracks the positions of the fingers for us, ++ * the array indices correspond to the finger indices returned ++ * in the report packages. ++ */ ++ struct focaltech_finger_state fingers[FOC_MAX_FINGERS]; ++ ++ /* True if the clickpad has been pressed. */ ++ bool pressed; ++}; ++ ++struct focaltech_data { ++ unsigned int x_max, y_max; ++ struct focaltech_hw_state state; ++}; ++ ++static void focaltech_report_state(struct psmouse *psmouse) ++{ ++ struct focaltech_data *priv = psmouse->private; ++ struct focaltech_hw_state *state = &priv->state; ++ struct input_dev *dev = psmouse->dev; ++ int i; ++ ++ for (i = 0; i < FOC_MAX_FINGERS; i++) { ++ struct focaltech_finger_state *finger = &state->fingers[i]; ++ bool active = finger->active && finger->valid; ++ ++ input_mt_slot(dev, i); ++ input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); ++ if (active) { ++ input_report_abs(dev, ABS_MT_POSITION_X, finger->x); ++ input_report_abs(dev, ABS_MT_POSITION_Y, ++ FOC_MAX_Y - finger->y); ++ } ++ } ++ input_mt_report_pointer_emulation(dev, true); ++ ++ input_report_key(psmouse->dev, BTN_LEFT, state->pressed); ++ input_sync(psmouse->dev); ++} ++ ++static void focaltech_process_touch_packet(struct psmouse *psmouse, ++ unsigned char *packet) ++{ ++ struct focaltech_data *priv = psmouse->private; ++ struct focaltech_hw_state *state = &priv->state; ++ unsigned char fingers = packet[1]; ++ int i; ++ ++ state->pressed = (packet[0] >> 4) & 1; ++ ++ /* the second byte contains a bitmap of all fingers touching the pad */ ++ for (i = 0; i < FOC_MAX_FINGERS; i++) { ++ state->fingers[i].active = fingers & 0x1; ++ if (!state->fingers[i].active) { ++ /* ++ * Even when the finger becomes active again, we still ++ * will have to wait for the first valid position. ++ */ ++ state->fingers[i].valid = false; ++ } ++ fingers >>= 1; ++ } ++} ++ ++static void focaltech_process_abs_packet(struct psmouse *psmouse, ++ unsigned char *packet) ++{ ++ struct focaltech_data *priv = psmouse->private; ++ struct focaltech_hw_state *state = &priv->state; ++ unsigned int finger; ++ ++ finger = (packet[1] >> 4) - 1; ++ if (finger >= FOC_MAX_FINGERS) { ++ psmouse_err(psmouse, "Invalid finger in abs packet: %d\n", ++ finger); ++ return; ++ } ++ ++ state->pressed = (packet[0] >> 4) & 1; ++ ++ /* ++ * packet[5] contains some kind of tool size in the most ++ * significant nibble. 0xff is a special value (latching) that ++ * signals a large contact area. ++ */ ++ if (packet[5] == 0xff) { ++ state->fingers[finger].valid = false; ++ return; ++ } ++ ++ state->fingers[finger].x = ((packet[1] & 0xf) << 8) | packet[2]; ++ state->fingers[finger].y = (packet[3] << 8) | packet[4]; ++ state->fingers[finger].valid = true; ++} ++ ++static void focaltech_process_rel_packet(struct psmouse *psmouse, ++ unsigned char *packet) ++{ ++ struct focaltech_data *priv = psmouse->private; ++ struct focaltech_hw_state *state = &priv->state; ++ int finger1, finger2; ++ ++ state->pressed = packet[0] >> 7; ++ finger1 = ((packet[0] >> 4) & 0x7) - 1; ++ if (finger1 < FOC_MAX_FINGERS) { ++ state->fingers[finger1].x += (char)packet[1]; ++ state->fingers[finger1].y += (char)packet[2]; ++ } else { ++ psmouse_err(psmouse, "First finger in rel packet invalid: %d\n", ++ finger1); ++ } ++ ++ /* ++ * If there is an odd number of fingers, the last relative ++ * packet only contains one finger. In this case, the second ++ * finger index in the packet is 0 (we subtract 1 in the lines ++ * above to create array indices, so the finger will overflow ++ * and be above FOC_MAX_FINGERS). ++ */ ++ finger2 = ((packet[3] >> 4) & 0x7) - 1; ++ if (finger2 < FOC_MAX_FINGERS) { ++ state->fingers[finger2].x += (char)packet[4]; ++ state->fingers[finger2].y += (char)packet[5]; ++ } ++} ++ ++static void focaltech_process_packet(struct psmouse *psmouse) ++{ ++ unsigned char *packet = psmouse->packet; ++ ++ switch (packet[0] & 0xf) { ++ case FOC_TOUCH: ++ focaltech_process_touch_packet(psmouse, packet); ++ break; ++ ++ case FOC_ABS: ++ focaltech_process_abs_packet(psmouse, packet); ++ break; ++ ++ case FOC_REL: ++ focaltech_process_rel_packet(psmouse, packet); ++ break; ++ ++ default: ++ psmouse_err(psmouse, "Unknown packet type: %02x\n", packet[0]); ++ break; ++ } ++ ++ focaltech_report_state(psmouse); ++} ++ ++static psmouse_ret_t focaltech_process_byte(struct psmouse *psmouse) ++{ ++ if (psmouse->pktcnt >= 6) { /* Full packet received */ ++ focaltech_process_packet(psmouse); ++ return PSMOUSE_FULL_PACKET; ++ } ++ ++ /* ++ * We might want to do some validation of the data here, but ++ * we do not know the protocol well enough ++ */ ++ return PSMOUSE_GOOD_DATA; ++} ++ ++static int focaltech_switch_protocol(struct psmouse *psmouse) ++{ ++ struct ps2dev *ps2dev = &psmouse->ps2dev; ++ unsigned char param[3]; ++ ++ param[0] = 0; ++ if (ps2_command(ps2dev, param, 0x10f8)) ++ return -EIO; ++ ++ if (ps2_command(ps2dev, param, 0x10f8)) ++ return -EIO; ++ ++ if (ps2_command(ps2dev, param, 0x10f8)) ++ return -EIO; ++ ++ param[0] = 1; ++ if (ps2_command(ps2dev, param, 0x10f8)) ++ return -EIO; ++ ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11)) ++ return -EIO; ++ ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_ENABLE)) ++ return -EIO; ++ ++ return 0; ++} ++ ++static void focaltech_disconnect(struct psmouse *psmouse) ++{ ++ focaltech_reset(psmouse); ++ kfree(psmouse->private); ++ psmouse->private = NULL; ++} ++ ++static int focaltech_reconnect(struct psmouse *psmouse) ++{ ++ int error; ++ ++ focaltech_reset(psmouse); ++ ++ error = focaltech_switch_protocol(psmouse); ++ if (error) { ++ psmouse_err(psmouse, "Unable to initialize the device\n"); ++ return error; ++ } ++ ++ return 0; ++} ++ ++static void focaltech_set_input_params(struct psmouse *psmouse) ++{ ++ struct input_dev *dev = psmouse->dev; ++ struct focaltech_data *priv = psmouse->private; ++ ++ /* ++ * Undo part of setup done for us by psmouse core since touchpad ++ * is not a relative device. ++ */ ++ __clear_bit(EV_REL, dev->evbit); ++ __clear_bit(REL_X, dev->relbit); ++ __clear_bit(REL_Y, dev->relbit); ++ __clear_bit(BTN_RIGHT, dev->keybit); ++ __clear_bit(BTN_MIDDLE, dev->keybit); ++ ++ /* ++ * Now set up our capabilities. ++ */ ++ __set_bit(EV_ABS, dev->evbit); ++ input_set_abs_params(dev, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0); ++ input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0); ++ input_mt_init_slots(dev, 5, INPUT_MT_POINTER); ++ __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); ++} ++ ++static int focaltech_read_register(struct ps2dev *ps2dev, int reg, ++ unsigned char *param) ++{ ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETSCALE11)) ++ return -EIO; ++ ++ param[0] = 0; ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) ++ return -EIO; ++ ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) ++ return -EIO; ++ ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) ++ return -EIO; ++ ++ param[0] = reg; ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) ++ return -EIO; ++ ++ if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) ++ return -EIO; ++ ++ return 0; ++} ++ ++static int focaltech_read_size(struct psmouse *psmouse) ++{ ++ struct ps2dev *ps2dev = &psmouse->ps2dev; ++ struct focaltech_data *priv = psmouse->private; ++ char param[3]; ++ ++ if (focaltech_read_register(ps2dev, 2, param)) ++ return -EIO; ++ ++ /* not sure whether this is 100% correct */ ++ priv->x_max = (unsigned char)param[1] * 128; ++ priv->y_max = (unsigned char)param[2] * 128; ++ ++ return 0; ++} ++int focaltech_init(struct psmouse *psmouse) ++{ ++ struct focaltech_data *priv; ++ int error; ++ ++ psmouse->private = priv = kzalloc(sizeof(struct focaltech_data), ++ GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ focaltech_reset(psmouse); ++ ++ error = focaltech_read_size(psmouse); ++ if (error) { ++ psmouse_err(psmouse, ++ "Unable to read the size of the touchpad\n"); ++ goto fail; ++ } ++ ++ error = focaltech_switch_protocol(psmouse); ++ if (error) { ++ psmouse_err(psmouse, "Unable to initialize the device\n"); ++ goto fail; ++ } ++ ++ focaltech_set_input_params(psmouse); ++ ++ psmouse->protocol_handler = focaltech_process_byte; ++ psmouse->pktsize = 6; ++ psmouse->disconnect = focaltech_disconnect; ++ psmouse->reconnect = focaltech_reconnect; ++ psmouse->cleanup = focaltech_reset; ++ /* resync is not supported yet */ ++ psmouse->resync_time = 0; + + return 0; ++ ++fail: ++ focaltech_reset(psmouse); ++ kfree(priv); ++ return error; + } ++ ++bool focaltech_supported(void) ++{ ++ return true; ++} ++ ++#else /* CONFIG_MOUSE_PS2_FOCALTECH */ ++ ++int focaltech_init(struct psmouse *psmouse) ++{ ++ focaltech_reset(psmouse); ++ ++ return 0; ++} ++ ++bool focaltech_supported(void) ++{ ++ return false; ++} ++ ++#endif /* CONFIG_MOUSE_PS2_FOCALTECH */ +diff --git a/drivers/input/mouse/focaltech.h b/drivers/input/mouse/focaltech.h +index 498650c..71870a9 100644 +--- a/drivers/input/mouse/focaltech.h ++++ b/drivers/input/mouse/focaltech.h +@@ -2,6 +2,7 @@ + * Focaltech TouchPad PS/2 mouse driver + * + * Copyright (c) 2014 Red Hat Inc. ++ * Copyright (c) 2014 Mathias Gottschlag + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -18,5 +19,6 @@ + + int focaltech_detect(struct psmouse *psmouse, bool set_properties); + int focaltech_init(struct psmouse *psmouse); ++bool focaltech_supported(void); + + #endif +diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c +index 26994f6..4a9de33 100644 +--- a/drivers/input/mouse/psmouse-base.c ++++ b/drivers/input/mouse/psmouse-base.c +@@ -725,16 +725,19 @@ static int psmouse_extensions(struct psmouse *psmouse, + + /* Always check for focaltech, this is safe as it uses pnp-id matching */ + if (psmouse_do_detect(focaltech_detect, psmouse, set_properties) == 0) { +- if (!set_properties || focaltech_init(psmouse) == 0) { +- /* +- * Not supported yet, use bare protocol. +- * Note that we need to also restrict +- * psmouse_max_proto so that psmouse_initialize() +- * does not try to reset rate and resolution, +- * because even that upsets the device. +- */ +- psmouse_max_proto = PSMOUSE_PS2; +- return PSMOUSE_PS2; ++ if (max_proto > PSMOUSE_IMEX) { ++ if (!set_properties || focaltech_init(psmouse) == 0) { ++ if (focaltech_supported()) ++ return PSMOUSE_FOCALTECH; ++ /* ++ * Note that we need to also restrict ++ * psmouse_max_proto so that psmouse_initialize() ++ * does not try to reset rate and resolution, ++ * because even that upsets the device. ++ */ ++ psmouse_max_proto = PSMOUSE_PS2; ++ return PSMOUSE_PS2; ++ } + } + } + +@@ -1063,6 +1066,15 @@ static const struct psmouse_protocol psmouse_protocols[] = { + .alias = "cortps", + .detect = cortron_detect, + }, ++#ifdef CONFIG_MOUSE_PS2_FOCALTECH ++ { ++ .type = PSMOUSE_FOCALTECH, ++ .name = "FocalTechPS/2", ++ .alias = "focaltech", ++ .detect = focaltech_detect, ++ .init = focaltech_init, ++ }, ++#endif + { + .type = PSMOUSE_AUTO, + .name = "auto", +diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h +index f4cf664..c2ff137 100644 +--- a/drivers/input/mouse/psmouse.h ++++ b/drivers/input/mouse/psmouse.h +@@ -96,6 +96,7 @@ enum psmouse_type { + PSMOUSE_FSP, + PSMOUSE_SYNAPTICS_RELATIVE, + PSMOUSE_CYPRESS, ++ PSMOUSE_FOCALTECH, + PSMOUSE_AUTO /* This one should always be last */ + }; + +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/KVM-ia64-drop-kvm.h-from-installed-user-headers.patch b/kernel/kernel/files/patches/mageia/KVM-ia64-drop-kvm.h-from-installed-user-headers.patch new file mode 100644 index 00000000..e8cbed47 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/KVM-ia64-drop-kvm.h-from-installed-user-headers.patch @@ -0,0 +1,28 @@ +From 6557bada461afeaa920a189fae2cff7c8fdce39f Mon Sep 17 00:00:00 2001 +From: Mike Frysinger +Date: Mon, 9 Feb 2015 14:24:47 -0500 +Subject: [PATCH] KVM: ia64: drop kvm.h from installed user headers + +The header was deleted, so stop trying to install it. + +Signed-off-by: Mike Frysinger +Signed-off-by: Paolo Bonzini +--- + arch/ia64/include/uapi/asm/Kbuild | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/ia64/include/uapi/asm/Kbuild b/arch/ia64/include/uapi/asm/Kbuild +index 1b3f5eb..891002b 100644 +--- a/arch/ia64/include/uapi/asm/Kbuild ++++ b/arch/ia64/include/uapi/asm/Kbuild +@@ -18,7 +18,6 @@ header-y += intrinsics.h + header-y += ioctl.h + header-y += ioctls.h + header-y += ipcbuf.h +-header-y += kvm.h + header-y += kvm_para.h + header-y += mman.h + header-y += msgbuf.h +-- +2.3.0 + diff --git a/kernel/kernel/files/patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch b/kernel/kernel/files/patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch new file mode 100644 index 00000000..c3fffdfa --- /dev/null +++ b/kernel/kernel/files/patches/mageia/Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch @@ -0,0 +1,32 @@ +From 88299efb05387c2c94120fdc9661aab2ec3a1ad8 Mon Sep 17 00:00:00 2001 +From: Thomas Backlund +Date: Fri, 3 Apr 2015 00:10:34 +0259 +Subject: [PATCH] Revert "cpufreq: pcc: Enable autoload of pcc-cpufreq for ACPI + processors" + +This reverts commit 7e7e8fe69820c6fa31395dbbd8e348e3c69cd2a9. +--- + drivers/cpufreq/pcc-cpufreq.c | 7 ------- + 1 file changed, 7 deletions(-) + +diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c +index 2a0d589..4d2c8e8 100644 +--- a/drivers/cpufreq/pcc-cpufreq.c ++++ b/drivers/cpufreq/pcc-cpufreq.c +@@ -603,13 +603,6 @@ static void __exit pcc_cpufreq_exit(void) + free_percpu(pcc_cpu_info); + } + +-static const struct acpi_device_id processor_device_ids[] = { +- {ACPI_PROCESSOR_OBJECT_HID, }, +- {ACPI_PROCESSOR_DEVICE_HID, }, +- {}, +-}; +-MODULE_DEVICE_TABLE(acpi, processor_device_ids); +- + MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar"); + MODULE_VERSION(PCC_VERSION); + MODULE_DESCRIPTION("Processor Clocking Control interface driver"); +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/acpi-ACPICA-Add-Windows-2015-string-to-_OSI-support.patch b/kernel/kernel/files/patches/mageia/acpi-ACPICA-Add-Windows-2015-string-to-_OSI-support.patch new file mode 100644 index 00000000..a665e11d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/acpi-ACPICA-Add-Windows-2015-string-to-_OSI-support.patch @@ -0,0 +1,45 @@ +From 796888e942b34cbbd738d9e5478b7d103ee38061 Mon Sep 17 00:00:00 2001 +From: Bob Moore +Date: Mon, 13 Apr 2015 11:50:37 +0800 +Subject: [PATCH] ACPICA: Add "Windows 2015" string to _OSI support. + +ACPICA commit b293f602a67da478ae0bec129e68bd99787d9908 + +This change adds this string for Windows 10. + +Link: https://github.com/acpica/acpica/commit/b293f602 +Signed-off-by: Bob Moore +Signed-off-by: Lv Zheng +Signed-off-by: Rafael J. Wysocki +--- + drivers/acpi/acpica/utosi.c | 1 + + include/acpi/actypes.h | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c +index 574cd31..44035ab 100644 +--- a/drivers/acpi/acpica/utosi.c ++++ b/drivers/acpi/acpica/utosi.c +@@ -100,6 +100,7 @@ static struct acpi_interface_info acpi_default_supported_interfaces[] = { + {"Windows 2009", NULL, 0, ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ + {"Windows 2012", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8 and Server 2012 - Added 08/2012 */ + {"Windows 2013", NULL, 0, ACPI_OSI_WIN_8}, /* Windows 8.1 and Server 2012 R2 - Added 01/2014 */ ++ {"Windows 2015", NULL, 0, ACPI_OSI_WIN_10}, /* Windows 10 - Added 03/2015 */ + + /* Feature Group Strings */ + +diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h +index f18b7a8..ace520f 100644 +--- a/include/acpi/actypes.h ++++ b/include/acpi/actypes.h +@@ -1274,6 +1274,7 @@ struct acpi_memory_list { + #define ACPI_OSI_WIN_VISTA_SP2 0x0A + #define ACPI_OSI_WIN_7 0x0B + #define ACPI_OSI_WIN_8 0x0C ++#define ACPI_OSI_WIN_10 0x0D + + /* Definitions of file IO */ + +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch b/kernel/kernel/files/patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch new file mode 100644 index 00000000..1ac3254c --- /dev/null +++ b/kernel/kernel/files/patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch @@ -0,0 +1,28 @@ +Subject: CLEVO M360S acpi irq workaround + +Some Hardware vendor use CLEVO M360S Laptop OEM. +This acpi IRQ routing is not correct. we use normal IRQ routing for default. + +Signed-off-by: Go Taniguchi + +--- + arch/x86/kernel/acpi/boot.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -1615,6 +1615,14 @@ static struct dmi_system_id __initdata a + }, + }, + { ++ .callback = disable_acpi_irq, ++ .ident = "CLEVO M360S", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "M360S"), ++ }, ++ }, ++ { + /* + * Latest BIOS for IBM 600E (1.16) has bad pcinum + * for LPC bridge, which is needed for the PCI diff --git a/kernel/kernel/files/patches/mageia/acpi-PNP-add-two-IDs-to-list-for-PNPACPI-device-enum.patch b/kernel/kernel/files/patches/mageia/acpi-PNP-add-two-IDs-to-list-for-PNPACPI-device-enum.patch new file mode 100644 index 00000000..538e0036 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/acpi-PNP-add-two-IDs-to-list-for-PNPACPI-device-enum.patch @@ -0,0 +1,42 @@ +From 622532bb2fad8fe342fb685727ae0be566f6be5d Mon Sep 17 00:00:00 2001 +From: Witold Szczeponik +Date: Fri, 1 May 2015 19:05:20 +0200 +Subject: [PATCH] ACPI / PNP: add two IDs to list for PNPACPI device + enumeration + +Commit eec15edbb0e1 (ACPI / PNP: use device ID list for PNPACPI device +enumeration) changed the way how ACPI devices are enumerated and when +they are added to the PNP bus. + +However, it broke the sound card support on (at least) a vintage +IBM ThinkPad 600E: with said commit applied, two of the necessary +"CSC01xx" devices are not added to the PNP bus and hence can not be +found during the initialization of the "snd-cs4236" module. As a +consequence, loading "snd-cs4236" causes null pointer exceptions. +The attached patch fixes the problem end re-enables sound on the +IBM ThinkPad 600E. + +Fixes: eec15edbb0e1 (ACPI / PNP: use device ID list for PNPACPI device enumeration) +Signed-off-by: Witold Szczeponik +Cc: 3.16+ # 3.16+ +Signed-off-by: Rafael J. Wysocki +--- + drivers/acpi/acpi_pnp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/acpi/acpi_pnp.c b/drivers/acpi/acpi_pnp.c +index b193f84..ff6d8ad 100644 +--- a/drivers/acpi/acpi_pnp.c ++++ b/drivers/acpi/acpi_pnp.c +@@ -304,6 +304,8 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = { + {"PNPb006"}, + /* cs423x-pnpbios */ + {"CSC0100"}, ++ {"CSC0103"}, ++ {"CSC0110"}, + {"CSC0000"}, + {"GIM0100"}, /* Guillemot Turtlebeach something appears to be cs4232 compatible */ + /* es18xx-pnpbios */ +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/acpi-SBS-Add-5-us-delay-to-fix-SBS-hangs-on-MacBook.patch b/kernel/kernel/files/patches/mageia/acpi-SBS-Add-5-us-delay-to-fix-SBS-hangs-on-MacBook.patch new file mode 100644 index 00000000..8e932279 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/acpi-SBS-Add-5-us-delay-to-fix-SBS-hangs-on-MacBook.patch @@ -0,0 +1,85 @@ +From 3349fb64b2927407017d970dd5c4daf3c5ad69f8 Mon Sep 17 00:00:00 2001 +From: Chris Bainbridge +Date: Wed, 29 Apr 2015 21:21:40 +0100 +Subject: [PATCH] ACPI / SBS: Add 5 us delay to fix SBS hangs on MacBook + +Commit 7bc5a2bad0b8 'ACPI: Support _OSI("Darwin") correctly' caused +the MacBook firmware to expose the SBS, resulting in intermittent +hangs of several minutes on boot, and failure to detect or report +the battery. Fix this by adding a 5 us delay to the start of each +SMBUS transaction. This timing is the result of experimentation - +hangs were observed with 3 us but never with 5 us. + +Fixes: 7bc5a2bad0b8 'ACPI: Support _OSI("Darwin") correctly' +Link: https://bugzilla.kernel.org/show_bug.cgi?id=94651 +Signed-off-by: Chris Bainbridge +Cc: 3.18+ # 3.18+ +[ rjw: Subject and changelog ] +Signed-off-by: Rafael J. Wysocki +--- + drivers/acpi/sbshc.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c +index 26e5b50..bf034f8 100644 +--- a/drivers/acpi/sbshc.c ++++ b/drivers/acpi/sbshc.c +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include "sbshc.h" + + #define PREFIX "ACPI: " +@@ -87,6 +88,8 @@ enum acpi_smb_offset { + ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */ + }; + ++static bool macbook; ++ + static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data) + { + return ec_read(hc->offset + address, data); +@@ -132,6 +135,8 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, + } + + mutex_lock(&hc->lock); ++ if (macbook) ++ udelay(5); + if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp)) + goto end; + if (temp) { +@@ -257,12 +262,29 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, + acpi_handle handle, acpi_ec_query_func func, + void *data); + ++static int macbook_dmi_match(const struct dmi_system_id *d) ++{ ++ pr_debug("Detected MacBook, enabling workaround\n"); ++ macbook = true; ++ return 0; ++} ++ ++static struct dmi_system_id acpi_smbus_dmi_table[] = { ++ { macbook_dmi_match, "Apple MacBook", { ++ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") }, ++ }, ++ { }, ++}; ++ + static int acpi_smbus_hc_add(struct acpi_device *device) + { + int status; + unsigned long long val; + struct acpi_smb_hc *hc; + ++ dmi_check_system(acpi_smbus_dmi_table); ++ + if (!device) + return -EINVAL; + +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/acpi-init-Fix-the-ordering-of-acpi_reserve_resources.patch b/kernel/kernel/files/patches/mageia/acpi-init-Fix-the-ordering-of-acpi_reserve_resources.patch new file mode 100644 index 00000000..a42c2876 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/acpi-init-Fix-the-ordering-of-acpi_reserve_resources.patch @@ -0,0 +1,56 @@ +From b9a5e5e18fbf223502c0b2264c15024e393da928 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Thu, 7 May 2015 21:19:39 +0200 +Subject: ACPI / init: Fix the ordering of acpi_reserve_resources() + +Since acpi_reserve_resources() is defined as a device_initcall(), +there's no guarantee that it will be executed in the right order +with respect to the rest of the ACPI initialization code. On some +systems this leads to breakage if, for example, the address range +that should be reserved for the ACPI fixed registers is given to +the PCI host bridge instead if the race is won by the wrong code +path. + +Fix this by turning acpi_reserve_resources() into a void function +and calling it directly from within the ACPI initialization sequence. + +Reported-and-tested-by: George McCollister +Link: http://marc.info/?t=143092384600002&r=1&w=2 +Cc: All applicable +Signed-off-by: Rafael J. Wysocki + +diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c +index 39748bb..7ccba39 100644 +--- a/drivers/acpi/osl.c ++++ b/drivers/acpi/osl.c +@@ -182,7 +182,7 @@ static void __init acpi_request_region (struct acpi_generic_address *gas, + request_mem_region(addr, length, desc); + } + +-static int __init acpi_reserve_resources(void) ++static void __init acpi_reserve_resources(void) + { + acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length, + "ACPI PM1a_EVT_BLK"); +@@ -211,10 +211,7 @@ static int __init acpi_reserve_resources(void) + if (!(acpi_gbl_FADT.gpe1_block_length & 0x1)) + acpi_request_region(&acpi_gbl_FADT.xgpe1_block, + acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK"); +- +- return 0; + } +-device_initcall(acpi_reserve_resources); + + void acpi_os_printf(const char *fmt, ...) + { +@@ -1845,6 +1842,7 @@ acpi_status __init acpi_os_initialize(void) + + acpi_status __init acpi_os_initialize1(void) + { ++ acpi_reserve_resources(); + kacpid_wq = alloc_workqueue("kacpid", 0, 1); + kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1); + kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0); +-- +cgit v0.10.2 + diff --git a/kernel/kernel/files/patches/mageia/acpi-processor-M720SR-limit-to-C2.patch b/kernel/kernel/files/patches/mageia/acpi-processor-M720SR-limit-to-C2.patch new file mode 100644 index 00000000..a3608628 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/acpi-processor-M720SR-limit-to-C2.patch @@ -0,0 +1,21 @@ +Limit Clevo M720SR to C2, going to C3 makes the machine freeze. This +needs more investigation, sis chipset/bios problem may be? + +Signed-off-by: Herton Ronaldo Krzesinski + +--- + drivers/acpi/processor_idle.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- linux-2.6.33-rc8-git4-t2/drivers/acpi/processor_idle.c.orig 2010-02-20 12:45:35.000000000 +0200 ++++ linux-2.6.33-rc8-git4-t2/drivers/acpi/processor_idle.c 2010-02-20 12:53:39.679099592 +0200 +@@ -110,6 +110,9 @@ static struct dmi_system_id __cpuinitdat + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, + (void *)2}, ++ { set_max_cstate, "Clevo M720SR", { ++ DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), ++ DMI_MATCH(DMI_PRODUCT_NAME,"M720SR")}, (void *)2}, + { set_max_cstate, "Pavilion zv5000", { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME,"Pavilion zv5000 (DS502A#ABA)")}, diff --git a/kernel/kernel/files/patches/mageia/acpi-sbs-enable-battery-manager-when-present.patch b/kernel/kernel/files/patches/mageia/acpi-sbs-enable-battery-manager-when-present.patch new file mode 100644 index 00000000..f376d0a2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/acpi-sbs-enable-battery-manager-when-present.patch @@ -0,0 +1,34 @@ +From 61f8ff693923e4b19748b0e8287b99778f2661c7 Mon Sep 17 00:00:00 2001 +From: Chris Bainbridge +Date: Wed, 22 Apr 2015 16:40:21 +0100 +Subject: ACPI / SBS: Enable battery manager when present + +From: Chris Bainbridge + +commit 61f8ff693923e4b19748b0e8287b99778f2661c7 upstream. + +Commit 9faf6136ff46 (ACPI / SBS: Disable smart battery manager on +Apple) introduced a regression disabling the SBS battery manager. +The battery manager should be marked as present when +acpi_manager_get_info() returns 0. + +Fixes: 9faf6136ff46 (ACPI / SBS: Disable smart battery manager on Apple) +Signed-off-by: Chris Bainbridge +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/acpi/sbs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/acpi/sbs.c ++++ b/drivers/acpi/sbs.c +@@ -670,7 +670,7 @@ static int acpi_sbs_add(struct acpi_devi + if (!sbs_manager_broken) { + result = acpi_manager_get_info(sbs); + if (!result) { +- sbs->manager_present = 0; ++ sbs->manager_present = 1; + for (id = 0; id < MAX_SBS_BAT; ++id) + if ((sbs->batteries_supported & (1 << id))) + acpi_battery_add(sbs, id); diff --git a/kernel/kernel/files/patches/mageia/acpi-table-Use-pr_debug-instead-of-pr_info-for-MADT-.patch b/kernel/kernel/files/patches/mageia/acpi-table-Use-pr_debug-instead-of-pr_info-for-MADT-.patch new file mode 100644 index 00000000..ae6d55d1 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/acpi-table-Use-pr_debug-instead-of-pr_info-for-MADT-.patch @@ -0,0 +1,106 @@ +From 07f438df22886432ff50772446768f65fbbf3ee0 Mon Sep 17 00:00:00 2001 +From: Hanjun Guo +Date: Tue, 24 Mar 2015 14:02:34 +0000 +Subject: [PATCH] ACPI / table: Use pr_debug() instead of pr_info() for MADT + table scanning + +For a normal 8 cpu sockets system, it will up to 240 cpu threads (Xeon E7 +v2 family for now), and we need 240 entries for local apic or local x2apic +in MADT table, so it will be much verbose information printed with a slow +uart console when system booted, this will be even worse with large system +with 16/32 cpu sockets. + +This patch just use pr_debug() instead of pr_info() for ioapic/iosapic, +local apic/x2apic/sapic structures when scanning the MADT table to remove +those verbose information, but leave other structures unchanged. + +CC: Rafael J Wysocki +Acked-by: Rafael J. Wysocki +Acked-by: Olof Johansson +Acked-by: Grant Likely +Tested-by: Timur Tabi +Signed-off-by: Hanjun Guo +Signed-off-by: Will Deacon +--- + drivers/acpi/tables.c | 30 ++++++++++++++++-------------- + 1 file changed, 16 insertions(+), 14 deletions(-) + +diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c +index 93b8152..f4e5b88 100644 +--- a/drivers/acpi/tables.c ++++ b/drivers/acpi/tables.c +@@ -23,6 +23,8 @@ + * + */ + ++/* Uncomment next line to get verbose printout */ ++/* #define DEBUG */ + #define pr_fmt(fmt) "ACPI: " fmt + + #include +@@ -61,9 +63,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) + { + struct acpi_madt_local_apic *p = + (struct acpi_madt_local_apic *)header; +- pr_info("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", +- p->processor_id, p->id, +- (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); ++ pr_debug("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n", ++ p->processor_id, p->id, ++ (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + } + break; + +@@ -71,9 +73,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) + { + struct acpi_madt_local_x2apic *p = + (struct acpi_madt_local_x2apic *)header; +- pr_info("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n", +- p->local_apic_id, p->uid, +- (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); ++ pr_debug("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n", ++ p->local_apic_id, p->uid, ++ (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + } + break; + +@@ -81,8 +83,8 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) + { + struct acpi_madt_io_apic *p = + (struct acpi_madt_io_apic *)header; +- pr_info("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", +- p->id, p->address, p->global_irq_base); ++ pr_debug("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n", ++ p->id, p->address, p->global_irq_base); + } + break; + +@@ -155,9 +157,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) + { + struct acpi_madt_io_sapic *p = + (struct acpi_madt_io_sapic *)header; +- pr_info("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", +- p->id, (void *)(unsigned long)p->address, +- p->global_irq_base); ++ pr_debug("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n", ++ p->id, (void *)(unsigned long)p->address, ++ p->global_irq_base); + } + break; + +@@ -165,9 +167,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header) + { + struct acpi_madt_local_sapic *p = + (struct acpi_madt_local_sapic *)header; +- pr_info("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", +- p->processor_id, p->id, p->eid, +- (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); ++ pr_debug("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n", ++ p->processor_id, p->id, p->eid, ++ (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled"); + } + break; + +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/acpi-video-Allow-forcing-native-backlight-on-non-win.patch b/kernel/kernel/files/patches/mageia/acpi-video-Allow-forcing-native-backlight-on-non-win.patch new file mode 100644 index 00000000..676fb105 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/acpi-video-Allow-forcing-native-backlight-on-non-win.patch @@ -0,0 +1,77 @@ +From ff92cfe7cbc05c6c62f5b06c7d9090f4c853cd51 Mon Sep 17 00:00:00 2001 +From: Aaron Lu +Date: Wed, 11 Mar 2015 22:09:57 +0100 +Subject: [PATCH] ACPI / video: Allow forcing native backlight on non win8 + machines + +The native backlight behavior (so not registering both the acpi-video +and the vendor backlight driver) can be useful on some non win8 machines +too, so change the behavior of the video.use_native_backlight=1 or 0 +kernel cmdline option to be: if user has set video.use_native_backlight=1 +or 0, use that no matter if it is a win8 system or not. Also, we will +put some known systems into the DMI table to make them either use native +backlight interface or not, and the use_native_backlight_dmi is used to +reflect that. + +Original-by: Hans de Goede +Acked-by: Hans de Goede +Signed-off-by: Aaron Lu +Signed-off-by: Rafael J. Wysocki +--- + drivers/acpi/video.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c +index 26eb70c..2f45dca 100644 +--- a/drivers/acpi/video.c ++++ b/drivers/acpi/video.c +@@ -82,9 +82,15 @@ module_param(allow_duplicates, bool, 0644); + * For Windows 8 systems: used to decide if video module + * should skip registering backlight interface of its own. + */ +-static int use_native_backlight_param = -1; ++enum { ++ NATIVE_BACKLIGHT_NOT_SET = -1, ++ NATIVE_BACKLIGHT_OFF, ++ NATIVE_BACKLIGHT_ON, ++}; ++ ++static int use_native_backlight_param = NATIVE_BACKLIGHT_NOT_SET; + module_param_named(use_native_backlight, use_native_backlight_param, int, 0444); +-static bool use_native_backlight_dmi = true; ++static int use_native_backlight_dmi = NATIVE_BACKLIGHT_NOT_SET; + + static int register_count; + static struct mutex video_list_lock; +@@ -237,15 +243,16 @@ static void acpi_video_switch_brightness(struct work_struct *work); + + static bool acpi_video_use_native_backlight(void) + { +- if (use_native_backlight_param != -1) ++ if (use_native_backlight_param != NATIVE_BACKLIGHT_NOT_SET) + return use_native_backlight_param; +- else ++ else if (use_native_backlight_dmi != NATIVE_BACKLIGHT_NOT_SET) + return use_native_backlight_dmi; ++ return acpi_osi_is_win8(); + } + + bool acpi_video_verify_backlight_support(void) + { +- if (acpi_osi_is_win8() && acpi_video_use_native_backlight() && ++ if (acpi_video_use_native_backlight() && + backlight_device_registered(BACKLIGHT_RAW)) + return false; + return acpi_video_backlight_support(); +@@ -414,7 +421,7 @@ static int __init video_set_bqc_offset(const struct dmi_system_id *d) + + static int __init video_disable_native_backlight(const struct dmi_system_id *d) + { +- use_native_backlight_dmi = false; ++ use_native_backlight_dmi = NATIVE_BACKLIGHT_OFF; + return 0; + } + +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/alsa-emu10k1-emu10k2-32-bit-dma-mode.patch b/kernel/kernel/files/patches/mageia/alsa-emu10k1-emu10k2-32-bit-dma-mode.patch new file mode 100644 index 00000000..3761d1dc --- /dev/null +++ b/kernel/kernel/files/patches/mageia/alsa-emu10k1-emu10k2-32-bit-dma-mode.patch @@ -0,0 +1,205 @@ +From 7241ea558c6715501e777396b5fc312c372e11d9 Mon Sep 17 00:00:00 2001 +From: Peter Zubaj +Date: Tue, 28 Apr 2015 21:57:29 +0200 +Subject: ALSA: emu10k1: Emu10k2 32 bit DMA mode + +From: Peter Zubaj + +commit 7241ea558c6715501e777396b5fc312c372e11d9 upstream. + +Looks like audigy emu10k2 (probably emu10k1 - sb live too) support two +modes for DMA. Second mode is useful for 64 bit os with more then 2 GB +of ram (fixes problems with big soundfont loading) + +1) 32MB from 2 GB address space using 8192 pages (used now as default) +2) 16MB from 4 GB address space using 4096 pages + +Mode is set using HCFG_EXPANDED_MEM flag in HCFG register. +Also format of emu10k2 page table is then different. + +Signed-off-by: Peter Zubaj +Tested-by: Takashi Iwai +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + include/sound/emu10k1.h | 14 +++++++++----- + sound/pci/emu10k1/emu10k1_callback.c | 4 ++-- + sound/pci/emu10k1/emu10k1_main.c | 17 ++++++++++++----- + sound/pci/emu10k1/emupcm.c | 2 +- + sound/pci/emu10k1/memory.c | 11 ++++++----- + 5 files changed, 30 insertions(+), 18 deletions(-) + +--- a/include/sound/emu10k1.h ++++ b/include/sound/emu10k1.h +@@ -41,7 +41,8 @@ + + #define EMUPAGESIZE 4096 + #define MAXREQVOICES 8 +-#define MAXPAGES 8192 ++#define MAXPAGES0 4096 /* 32 bit mode */ ++#define MAXPAGES1 8192 /* 31 bit mode */ + #define RESERVED 0 + #define NUM_MIDI 16 + #define NUM_G 64 /* use all channels */ +@@ -50,8 +51,7 @@ + + /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */ + #define EMU10K1_DMA_MASK 0x7fffffffUL /* 31bit */ +-#define AUDIGY_DMA_MASK 0x7fffffffUL /* 31bit FIXME - 32 should work? */ +- /* See ALSA bug #1276 - rlrevell */ ++#define AUDIGY_DMA_MASK 0xffffffffUL /* 32bit mode */ + + #define TMEMSIZE 256*1024 + #define TMEMSIZEREG 4 +@@ -466,8 +466,11 @@ + + #define MAPB 0x0d /* Cache map B */ + +-#define MAP_PTE_MASK 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */ +-#define MAP_PTI_MASK 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */ ++#define MAP_PTE_MASK0 0xfffff000 /* The 20 MSBs of the PTE indexed by the PTI */ ++#define MAP_PTI_MASK0 0x00000fff /* The 12 bit index to one of the 4096 PTE dwords */ ++ ++#define MAP_PTE_MASK1 0xffffe000 /* The 19 MSBs of the PTE indexed by the PTI */ ++#define MAP_PTI_MASK1 0x00001fff /* The 13 bit index to one of the 8192 PTE dwords */ + + /* 0x0e, 0x0f: Not used */ + +@@ -1704,6 +1707,7 @@ struct snd_emu10k1 { + unsigned short model; /* subsystem id */ + unsigned int card_type; /* EMU10K1_CARD_* */ + unsigned int ecard_ctrl; /* ecard control bits */ ++ unsigned int address_mode; /* address mode */ + unsigned long dma_mask; /* PCI DMA mask */ + unsigned int delay_pcm_irq; /* in samples */ + int max_cache_pages; /* max memory size / PAGE_SIZE */ +--- a/sound/pci/emu10k1/emu10k1_callback.c ++++ b/sound/pci/emu10k1/emu10k1_callback.c +@@ -415,7 +415,7 @@ start_voice(struct snd_emux_voice *vp) + snd_emu10k1_ptr_write(hw, Z2, ch, 0); + + /* invalidate maps */ +- temp = (hw->silent_page.addr << 1) | MAP_PTI_MASK; ++ temp = (hw->silent_page.addr << hw->address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0); + snd_emu10k1_ptr_write(hw, MAPA, ch, temp); + snd_emu10k1_ptr_write(hw, MAPB, ch, temp); + #if 0 +@@ -436,7 +436,7 @@ start_voice(struct snd_emux_voice *vp) + snd_emu10k1_ptr_write(hw, CDF, ch, sample); + + /* invalidate maps */ +- temp = ((unsigned int)hw->silent_page.addr << 1) | MAP_PTI_MASK; ++ temp = ((unsigned int)hw->silent_page.addr << hw_address_mode) | (hw->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0); + snd_emu10k1_ptr_write(hw, MAPA, ch, temp); + snd_emu10k1_ptr_write(hw, MAPB, ch, temp); + +--- a/sound/pci/emu10k1/emu10k1_main.c ++++ b/sound/pci/emu10k1/emu10k1_main.c +@@ -282,7 +282,7 @@ static int snd_emu10k1_init(struct snd_e + snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */ + snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */ + +- silent_page = (emu->silent_page.addr << 1) | MAP_PTI_MASK; ++ silent_page = (emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0); + for (ch = 0; ch < NUM_G; ch++) { + snd_emu10k1_ptr_write(emu, MAPA, ch, silent_page); + snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page); +@@ -348,6 +348,11 @@ static int snd_emu10k1_init(struct snd_e + outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); + } + ++ if (emu->address_mode == 0) { ++ /* use 16M in 4G */ ++ outl(inl(emu->port + HCFG) | HCFG_EXPANDED_MEM, emu->port + HCFG); ++ } ++ + return 0; + } + +@@ -1877,8 +1882,10 @@ int snd_emu10k1_create(struct snd_card * + + is_audigy = emu->audigy = c->emu10k2_chip; + ++ /* set addressing mode */ ++ emu->address_mode = is_audigy ? 0 : 1; + /* set the DMA transfer mask */ +- emu->dma_mask = is_audigy ? AUDIGY_DMA_MASK : EMU10K1_DMA_MASK; ++ emu->dma_mask = emu->address_mode ? EMU10K1_DMA_MASK : AUDIGY_DMA_MASK; + if (pci_set_dma_mask(pci, emu->dma_mask) < 0 || + pci_set_consistent_dma_mask(pci, emu->dma_mask) < 0) { + dev_err(card->dev, +@@ -1903,7 +1910,7 @@ int snd_emu10k1_create(struct snd_card * + + emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT; + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), +- 32 * 1024, &emu->ptb_pages) < 0) { ++ (emu->address_mode ? 32 : 16) * 1024, &emu->ptb_pages) < 0) { + err = -ENOMEM; + goto error; + } +@@ -2002,8 +2009,8 @@ int snd_emu10k1_create(struct snd_card * + + /* Clear silent pages and set up pointers */ + memset(emu->silent_page.area, 0, PAGE_SIZE); +- silent_page = emu->silent_page.addr << 1; +- for (idx = 0; idx < MAXPAGES; idx++) ++ silent_page = emu->silent_page.addr << emu->address_mode; ++ for (idx = 0; idx < (emu->address_mode ? MAXPAGES1 : MAXPAGES0); idx++) + ((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx); + + /* set up voice indices */ +--- a/sound/pci/emu10k1/emupcm.c ++++ b/sound/pci/emu10k1/emupcm.c +@@ -380,7 +380,7 @@ static void snd_emu10k1_pcm_init_voice(s + snd_emu10k1_ptr_write(emu, Z1, voice, 0); + snd_emu10k1_ptr_write(emu, Z2, voice, 0); + /* invalidate maps */ +- silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK; ++ silent_page = ((unsigned int)emu->silent_page.addr << emu->address_mode) | (emu->address_mode ? MAP_PTI_MASK1 : MAP_PTI_MASK0); + snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page); + snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page); + /* modulation envelope */ +--- a/sound/pci/emu10k1/memory.c ++++ b/sound/pci/emu10k1/memory.c +@@ -34,10 +34,11 @@ + * aligned pages in others + */ + #define __set_ptb_entry(emu,page,addr) \ +- (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << 1) | (page))) ++ (((u32 *)(emu)->ptb_pages.area)[page] = cpu_to_le32(((addr) << (emu->address_mode)) | (page))) + + #define UNIT_PAGES (PAGE_SIZE / EMUPAGESIZE) +-#define MAX_ALIGN_PAGES (MAXPAGES / UNIT_PAGES) ++#define MAX_ALIGN_PAGES0 (MAXPAGES0 / UNIT_PAGES) ++#define MAX_ALIGN_PAGES1 (MAXPAGES1 / UNIT_PAGES) + /* get aligned page from offset address */ + #define get_aligned_page(offset) ((offset) >> PAGE_SHIFT) + /* get offset address from aligned page */ +@@ -124,7 +125,7 @@ static int search_empty_map_area(struct + } + page = blk->mapped_page + blk->pages; + } +- size = MAX_ALIGN_PAGES - page; ++ size = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0) - page; + if (size >= max_size) { + *nextp = pos; + return page; +@@ -181,7 +182,7 @@ static int unmap_memblk(struct snd_emu10 + q = get_emu10k1_memblk(p, mapped_link); + end_page = q->mapped_page; + } else +- end_page = MAX_ALIGN_PAGES; ++ end_page = (emu->address_mode ? MAX_ALIGN_PAGES1 : MAX_ALIGN_PAGES0); + + /* remove links */ + list_del(&blk->mapped_link); +@@ -307,7 +308,7 @@ snd_emu10k1_alloc_pages(struct snd_emu10 + if (snd_BUG_ON(!emu)) + return NULL; + if (snd_BUG_ON(runtime->dma_bytes <= 0 || +- runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE)) ++ runtime->dma_bytes >= (emu->address_mode ? MAXPAGES1 : MAXPAGES0) * EMUPAGESIZE)) + return NULL; + hdr = emu->memhdr; + if (snd_BUG_ON(!hdr)) diff --git a/kernel/kernel/files/patches/mageia/alsa-emu10k1-fix-card-shortname-string-buffer-overflow.patch b/kernel/kernel/files/patches/mageia/alsa-emu10k1-fix-card-shortname-string-buffer-overflow.patch new file mode 100644 index 00000000..c40ddf8b --- /dev/null +++ b/kernel/kernel/files/patches/mageia/alsa-emu10k1-fix-card-shortname-string-buffer-overflow.patch @@ -0,0 +1,62 @@ +From d02260824e2cad626fb2a9d62e27006d34b6dedc Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 27 Apr 2015 13:00:09 +0200 +Subject: ALSA: emu10k1: Fix card shortname string buffer overflow + +From: Takashi Iwai + +commit d02260824e2cad626fb2a9d62e27006d34b6dedc upstream. + +Some models provide too long string for the shortname that has 32bytes +including the terminator, and it results in a non-terminated string +exposed to the user-space. This isn't too critical, though, as the +string is stopped at the succeeding longname string. + +This patch fixes such entries by dropping "SB" prefix (it's enough to +fit within 32 bytes, so far). Meanwhile, it also changes strcpy() +with strlcpy() to make sure that this kind of problem won't happen in +future, too. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/emu10k1/emu10k1.c | 6 ++++-- + sound/pci/emu10k1/emu10k1_main.c | 4 ++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +--- a/sound/pci/emu10k1/emu10k1.c ++++ b/sound/pci/emu10k1/emu10k1.c +@@ -183,8 +183,10 @@ static int snd_card_emu10k1_probe(struct + } + #endif + +- strcpy(card->driver, emu->card_capabilities->driver); +- strcpy(card->shortname, emu->card_capabilities->name); ++ strlcpy(card->driver, emu->card_capabilities->driver, ++ sizeof(card->driver)); ++ strlcpy(card->shortname, emu->card_capabilities->name, ++ sizeof(card->shortname)); + snprintf(card->longname, sizeof(card->longname), + "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", + card->shortname, emu->revision, emu->serial, emu->port, emu->irq); +--- a/sound/pci/emu10k1/emu10k1_main.c ++++ b/sound/pci/emu10k1/emu10k1_main.c +@@ -1421,7 +1421,7 @@ static struct snd_emu_chip_details emu_c + * + */ + {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102, +- .driver = "Audigy2", .name = "SB Audigy 2 ZS Notebook [SB0530]", ++ .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", + .id = "Audigy2", + .emu10k2_chip = 1, + .ca0108_chip = 1, +@@ -1571,7 +1571,7 @@ static struct snd_emu_chip_details emu_c + .adc_1361t = 1, /* 24 bit capture instead of 16bit */ + .ac97_chip = 1} , + {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102, +- .driver = "Audigy2", .name = "SB Audigy 2 Platinum EX [SB0280]", ++ .driver = "Audigy2", .name = "Audigy 2 Platinum EX [SB0280]", + .id = "Audigy2", + .emu10k2_chip = 1, + .ca0102_chip = 1, diff --git a/kernel/kernel/files/patches/mageia/ata-jmicron-disable-broken-async_suspend.patch b/kernel/kernel/files/patches/mageia/ata-jmicron-disable-broken-async_suspend.patch new file mode 100644 index 00000000..f0787f4f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/ata-jmicron-disable-broken-async_suspend.patch @@ -0,0 +1,29 @@ + +Fix broken async_suspend + +https://bugzilla.kernel.org/show_bug.cgi?id=81551 + +--- a/drivers/pci/quirks.c ++++ a/drivers/pci/quirks.c +@@ -29,6 +29,21 @@ + #include "pci.h" + + /* ++ * For JMicron chips, we need to disable the async_suspend method, otherwise ++ * they will hit the power-on issue when doing device resume, add one quick ++ * solution to disable the async_suspend method. ++ */ ++static void pci_async_suspend_fixup(struct pci_dev *pdev) ++{ ++ /* ++ * disabling the async_suspend method for JMicron chips to ++ * avoid device resuming issue. ++ */ ++ device_disable_async_suspend(&pdev->dev); ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, pci_async_suspend_fixup); ++ ++/* + * Decoding should be disabled for a PCI device during BAR sizing to avoid + * conflict. But doing so may cause problems on host bridge and perhaps other + * key system devices. For devices that need to have mmio decoding always-on, diff --git a/kernel/kernel/files/patches/mageia/ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch b/kernel/kernel/files/patches/mageia/ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch new file mode 100644 index 00000000..2990886e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch @@ -0,0 +1,33 @@ +>From 9f04e51293b130474504216a477bb2a73cbf59e1 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Thu, 22 Mar 2012 22:29:11 +0200 +Subject: [PATCH] ata: prefer ata drivers over ide drivers when both are built + +Currently the old IDE drivers are preferred over ATA drivers when both +are built, since ide/ is listed first in drivers/Makefile and therefore +the IDE drivers end up before ATA drivers in modules.order which is used +by depmod/modprobe for module ordering. + +Change it so that ATA drivers are preferred over IDE driver by moving +the ide/ entry under ata/ in drivers/Makefile. + +Signed-off-by: Anssi Hannula +--- + drivers/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/Makefile b/drivers/Makefile +index 932e8bf..e8df3d0 100644 +--- a/drivers/Makefile ++++ b/drivers/Makefile +@@ -64,9 +64,9 @@ obj-y += base/ block/ misc/ mfd/ nfc/ + obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/ + obj-$(CONFIG_NUBUS) += nubus/ + obj-y += macintosh/ +-obj-$(CONFIG_IDE) += ide/ + obj-$(CONFIG_SCSI) += scsi/ + obj-$(CONFIG_ATA) += ata/ ++obj-$(CONFIG_IDE) += ide/ + obj-$(CONFIG_TARGET_CORE) += target/ + obj-$(CONFIG_MTD) += mtd/ + obj-$(CONFIG_SPI) += spi/ diff --git a/kernel/kernel/files/patches/mageia/ata-revert-Disabling-the-async-PM-for-JMicron-chip-363-361.patch b/kernel/kernel/files/patches/mageia/ata-revert-Disabling-the-async-PM-for-JMicron-chip-363-361.patch new file mode 100644 index 00000000..687066be --- /dev/null +++ b/kernel/kernel/files/patches/mageia/ata-revert-Disabling-the-async-PM-for-JMicron-chip-363-361.patch @@ -0,0 +1,68 @@ + +This patch reverts: + +From e6b7e41cdd8cae0591e04d9519b65470110e2d44 Mon Sep 17 00:00:00 2001 +From: Chuansheng Liu +Date: Mon, 1 Sep 2014 08:38:03 +0800 +Subject: [PATCH] ata: Disabling the async PM for JMicron chip 363/361 + + +in favour of the pci quirks based patch: +https://bugzilla.kernel.org/show_bug.cgi?id=81551 + +Signed-off-by: Thomas Backlund + +--- + drivers/ata/ahci.c | 12 ------------ + drivers/ata/pata_jmicron.c | 12 ------------ + 2 files changed, 24 deletions(-) + +diff --git b/drivers/ata/ahci.c a/drivers/ata/ahci.c +index f7da21b..bca3d64 100644 +--- b/drivers/ata/ahci.c ++++ a/drivers/ata/ahci.c +@@ -1337,18 +1337,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000) + ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS; + +- /* +- * The JMicron chip 361/363 contains one SATA controller and one +- * PATA controller,for powering on these both controllers, we must +- * follow the sequence one by one, otherwise one of them can not be +- * powered on successfully, so here we disable the async suspend +- * method for these chips. +- */ +- if (pdev->vendor == PCI_VENDOR_ID_JMICRON && +- (pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 || +- pdev->device == PCI_DEVICE_ID_JMICRON_JMB361)) +- device_disable_async_suspend(&pdev->dev); +- + /* acquire resources */ + rc = pcim_enable_device(pdev); + if (rc) +diff --git b/drivers/ata/pata_jmicron.c a/drivers/ata/pata_jmicron.c +index 47e418b..4d1a5d2 100644 +--- b/drivers/ata/pata_jmicron.c ++++ a/drivers/ata/pata_jmicron.c +@@ -143,18 +143,6 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i + }; + const struct ata_port_info *ppi[] = { &info, NULL }; + +- /* +- * The JMicron chip 361/363 contains one SATA controller and one +- * PATA controller,for powering on these both controllers, we must +- * follow the sequence one by one, otherwise one of them can not be +- * powered on successfully, so here we disable the async suspend +- * method for these chips. +- */ +- if (pdev->vendor == PCI_VENDOR_ID_JMICRON && +- (pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 || +- pdev->device == PCI_DEVICE_ID_JMICRON_JMB361)) +- device_disable_async_suspend(&pdev->dev); +- + return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0); + } + +-- +1.8.5.6 + diff --git a/kernel/kernel/files/patches/mageia/blk-mq-don-t-lose-requests-if-a-stopped-queue-restar.patch b/kernel/kernel/files/patches/mageia/blk-mq-don-t-lose-requests-if-a-stopped-queue-restar.patch new file mode 100644 index 00000000..ec8e4140 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/blk-mq-don-t-lose-requests-if-a-stopped-queue-restar.patch @@ -0,0 +1,49 @@ +From 9ba52e5812e53f20f23600d79449a3ec05a0254f Mon Sep 17 00:00:00 2001 +From: Shaohua Li +Date: Mon, 4 May 2015 14:32:48 -0600 +Subject: [PATCH] blk-mq: don't lose requests if a stopped queue restarts + +Normally if driver is busy to dispatch a request the logic is like below: +block layer: driver: + __blk_mq_run_hw_queue +a. blk_mq_stop_hw_queue +b. rq add to ctx->dispatch + +later: +1. blk_mq_start_hw_queue +2. __blk_mq_run_hw_queue + +But it's possible step 1-2 runs between a and b. And since rq isn't in +ctx->dispatch yet, step 2 will not run rq. The rq might get lost if +there are no subsequent requests kick in. + +Signed-off-by: Shaohua Li +Signed-off-by: Jens Axboe +--- + block/blk-mq.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 76f460e..e68b71b 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -858,6 +858,16 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx) + spin_lock(&hctx->lock); + list_splice(&rq_list, &hctx->dispatch); + spin_unlock(&hctx->lock); ++ /* ++ * the queue is expected stopped with BLK_MQ_RQ_QUEUE_BUSY, but ++ * it's possible the queue is stopped and restarted again ++ * before this. Queue restart will dispatch requests. And since ++ * requests in rq_list aren't added into hctx->dispatch yet, ++ * the requests in rq_list might get lost. ++ * ++ * blk_mq_run_hw_queue() already checks the STOPPED bit ++ **/ ++ blk_mq_run_hw_queue(hctx, true); + } + } + +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/blk-mq-fix-CPU-hotplug-handling.patch b/kernel/kernel/files/patches/mageia/blk-mq-fix-CPU-hotplug-handling.patch new file mode 100644 index 00000000..3f6f2fbf --- /dev/null +++ b/kernel/kernel/files/patches/mageia/blk-mq-fix-CPU-hotplug-handling.patch @@ -0,0 +1,97 @@ +From 2a34c0872adf252f23a6fef2d051a169ac796cef Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Tue, 21 Apr 2015 10:00:20 +0800 +Subject: [PATCH] blk-mq: fix CPU hotplug handling + +hctx->tags has to be set as NULL in case that it is to be unmapped +no matter if set->tags[hctx->queue_num] is NULL or not in blk_mq_map_swqueue() +because shared tags can be freed already from another request queue. + +The same situation has to be considered during handling CPU online too. +Unmapped hw queue can be remapped after CPU topo is changed, so we need +to allocate tags for the hw queue in blk_mq_map_swqueue(). Then tags +allocation for hw queue can be removed in hctx cpu online notifier, and it +is reasonable to do that after mapping is updated. + +Cc: +Reported-by: Dongsu Park +Tested-by: Dongsu Park +Signed-off-by: Ming Lei +Signed-off-by: Jens Axboe +--- + block/blk-mq.c | 34 +++++++++++++--------------------- + 1 file changed, 13 insertions(+), 21 deletions(-) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index 1fccb98..76f460e 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -1574,22 +1574,6 @@ static int blk_mq_hctx_cpu_offline(struc + return NOTIFY_OK; + } + +-static int blk_mq_hctx_cpu_online(struct blk_mq_hw_ctx *hctx, int cpu) +-{ +- struct request_queue *q = hctx->queue; +- struct blk_mq_tag_set *set = q->tag_set; +- +- if (set->tags[hctx->queue_num]) +- return NOTIFY_OK; +- +- set->tags[hctx->queue_num] = blk_mq_init_rq_map(set, hctx->queue_num); +- if (!set->tags[hctx->queue_num]) +- return NOTIFY_STOP; +- +- hctx->tags = set->tags[hctx->queue_num]; +- return NOTIFY_OK; +-} +- + static int blk_mq_hctx_notify(void *data, unsigned long action, + unsigned int cpu) + { +@@ -1597,8 +1581,11 @@ static int blk_mq_hctx_notify(void *data + + if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) + return blk_mq_hctx_cpu_offline(hctx, cpu); +- else if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) +- return blk_mq_hctx_cpu_online(hctx, cpu); ++ ++ /* ++ * In case of CPU online, tags may be reallocated ++ * in blk_mq_map_swqueue() after mapping is updated. ++ */ + + return NOTIFY_OK; + } +@@ -1780,6 +1767,7 @@ static void blk_mq_map_swqueue(struct re + unsigned int i; + struct blk_mq_hw_ctx *hctx; + struct blk_mq_ctx *ctx; ++ struct blk_mq_tag_set *set = q->tag_set; + + queue_for_each_hw_ctx(q, hctx, i) { + cpumask_clear(hctx->cpumask); +@@ -1806,16 +1794,20 @@ static void blk_mq_map_swqueue(struct re + * disable it and free the request entries. + */ + if (!hctx->nr_ctx) { +- struct blk_mq_tag_set *set = q->tag_set; +- + if (set->tags[i]) { + blk_mq_free_rq_map(set, set->tags[i], i); + set->tags[i] = NULL; +- hctx->tags = NULL; + } ++ hctx->tags = NULL; + continue; + } + ++ /* unmapped hw queue can be remapped after CPU topo changed */ ++ if (!set->tags[i]) ++ set->tags[i] = blk_mq_init_rq_map(set, i); ++ hctx->tags = set->tags[i]; ++ WARN_ON(!hctx->tags); ++ + /* + * Initialize batch roundrobin counts + */ diff --git a/kernel/kernel/files/patches/mageia/blk-mq-fix-FUA-request-hang.patch b/kernel/kernel/files/patches/mageia/blk-mq-fix-FUA-request-hang.patch new file mode 100644 index 00000000..46d66ddb --- /dev/null +++ b/kernel/kernel/files/patches/mageia/blk-mq-fix-FUA-request-hang.patch @@ -0,0 +1,38 @@ +From b2387ddcced8de3e6471a2fb16a409577063016f Mon Sep 17 00:00:00 2001 +From: Shaohua Li +Date: Fri, 1 May 2015 09:59:44 -0700 +Subject: [PATCH] blk-mq: fix FUA request hang + +When a FUA request enters its DATA stage of flush pipeline, the +request is added to mq requeue list, the request will then be added to +ctx->rq_list. blk_mq_attempt_merge() might merge the request with a bio. +Later when the request is finished the flush pipeline, the +request->__data_len is 0. Then I only saw the bio gets endio called, the +original request never finish. + +Adding REQ_FLUSH_SEQ into REQ_NOMERGE_FLAGS looks an easy fix. + +stable: 3.15+ + +Signed-off-by: Shaohua Li +Signed-off-by: Jens Axboe +--- + include/linux/blk_types.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h +index a1b25e3..b7299fe 100644 +--- a/include/linux/blk_types.h ++++ b/include/linux/blk_types.h +@@ -220,7 +220,7 @@ enum rq_flag_bits { + + /* This mask is used for both bio and request merge checking */ + #define REQ_NOMERGE_FLAGS \ +- (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA) ++ (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_FLUSH_SEQ) + + #define REQ_RAHEAD (1ULL << __REQ_RAHEAD) + #define REQ_THROTTLED (1ULL << __REQ_THROTTLED) +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/blk-mq-fix-race-between-timeout-and-CPU-hotplug.patch b/kernel/kernel/files/patches/mageia/blk-mq-fix-race-between-timeout-and-CPU-hotplug.patch new file mode 100644 index 00000000..cedd2137 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/blk-mq-fix-race-between-timeout-and-CPU-hotplug.patch @@ -0,0 +1,62 @@ +From f054b56c951bf1731ba7314a4c7f1cc0b2977cc9 Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Tue, 21 Apr 2015 10:00:19 +0800 +Subject: [PATCH] blk-mq: fix race between timeout and CPU hotplug + +Firstly during CPU hotplug, even queue is freezed, timeout +handler still may come and access hctx->tags, which may cause +use after free, so this patch deactivates timeout handler +inside CPU hotplug notifier. + +Secondly, tags can be shared by more than one queues, so we +have to check if the hctx has been unmapped, otherwise +still use-after-free on tags can be triggered. + +Cc: +Reported-by: Dongsu Park +Tested-by: Dongsu Park +Signed-off-by: Ming Lei +Signed-off-by: Jens Axboe +--- + block/blk-mq.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/block/blk-mq.c b/block/blk-mq.c +index ade8a2d..1fccb98 100644 +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -677,8 +677,11 @@ static void blk_mq_rq_timer(unsigned long priv) + data.next = blk_rq_timeout(round_jiffies_up(data.next)); + mod_timer(&q->timeout, data.next); + } else { +- queue_for_each_hw_ctx(q, hctx, i) +- blk_mq_tag_idle(hctx); ++ queue_for_each_hw_ctx(q, hctx, i) { ++ /* the hctx may be unmapped, so check it here */ ++ if (blk_mq_hw_queue_mapped(hctx)) ++ blk_mq_tag_idle(hctx); ++ } + } + } + +@@ -2090,9 +2093,16 @@ static int blk_mq_queue_reinit_notify(struct notifier_block *nb, + */ + list_for_each_entry(q, &all_q_list, all_q_node) + blk_mq_freeze_queue_start(q); +- list_for_each_entry(q, &all_q_list, all_q_node) ++ list_for_each_entry(q, &all_q_list, all_q_node) { + blk_mq_freeze_queue_wait(q); + ++ /* ++ * timeout handler can't touch hw queue during the ++ * reinitialization ++ */ ++ del_timer_sync(&q->timeout); ++ } ++ + list_for_each_entry(q, &all_q_list, all_q_node) + blk_mq_queue_reinit(q); + +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/block-floppy-disable-pnp-modalias.patch b/kernel/kernel/files/patches/mageia/block-floppy-disable-pnp-modalias.patch new file mode 100644 index 00000000..c994472a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/block-floppy-disable-pnp-modalias.patch @@ -0,0 +1,21 @@ + +Disable floppy autoloading as it makes systems without real hw, +but that has the pnp headers hang. + +See https://bugs.mageia.org/show_bug.cgi?id=4696 + +Signed-off-by: Thomas Backlund + +diff -Nurp linux-3.3.3-rc1/drivers/block/floppy.c.orig linux-3.3.3-rc1/drivers/block/floppy.c +--- linux-3.3.3-rc1/drivers/block/floppy.c.orig 2012-03-19 01:15:34.000000000 +0200 ++++ linux-3.3.3-rc1/drivers/block/floppy.c 2012-04-22 02:58:10.238498303 +0300 +@@ -4621,8 +4621,7 @@ static const struct pnp_device_id floppy + {"PNP0700", 0}, + {} + }; +- +-MODULE_DEVICE_TABLE(pnp, floppy_pnpids); ++/* MODULE_DEVICE_TABLE(pnp, floppy_pnpids); */ + + #else + diff --git a/kernel/kernel/files/patches/mageia/bluetooth-hci_usb-disable-isoc-transfers.patch b/kernel/kernel/files/patches/mageia/bluetooth-hci_usb-disable-isoc-transfers.patch new file mode 100644 index 00000000..34ced55d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/bluetooth-hci_usb-disable-isoc-transfers.patch @@ -0,0 +1,23 @@ +Add quirk to disable ISOC transfers for device +"ID 1131:1001 Integrated System Solution Corp. KY-BT100 Bluetooth Adapter" +http://qa.mandriva.com/show_bug.cgi?id=30638 + +Signed-off-by: Herton Ronaldo Krzesinski +--- + drivers/bluetooth/btusb.c | 3 +++ + 1 file changed, 3 insertions(+) + +(status: submitted upstream to bluez-devel ML on 2007-09-29) + +--- linux-2.6.28/drivers/bluetooth/btusb.c.orig 2009-02-11 10:29:20.000000000 -0500 ++++ linux-2.6.28/drivers/bluetooth/btusb.c 2009-02-11 10:30:27.000000000 -0500 +@@ -120,6 +120,9 @@ static struct usb_device_id blacklist_ta + /* Kensington Bluetooth USB adapter */ + { USB_DEVICE(0x047d, 0x105e), .driver_info = BTUSB_WRONG_SCO_MTU }, + ++ /* ISSC Bluetooth Adapter v3.1 */ ++ { USB_DEVICE(0x1131, 0x1001), .driver_info = BTUSB_BROKEN_ISOC }, ++ + /* RTX Telecom based adapters with buggy SCO support */ + { USB_DEVICE(0x0400, 0x0807), .driver_info = BTUSB_BROKEN_ISOC }, + { USB_DEVICE(0x0400, 0x080a), .driver_info = BTUSB_BROKEN_ISOC }, diff --git a/kernel/kernel/files/patches/mageia/char-agp-intel-new-Q57-id.patch b/kernel/kernel/files/patches/mageia/char-agp-intel-new-Q57-id.patch new file mode 100644 index 00000000..7093e9c0 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/char-agp-intel-new-Q57-id.patch @@ -0,0 +1,35 @@ + +agp/intel: add new host bridge id for Q57 system + +Add new Host Bridge ID found on a Q57 based system from Positivo. I +don't know what abbreviation id for this would be best, may be Q_HB +instead of UNKNOWN currently used would be better. + +Signed-off-by: Herton Ronaldo Krzesinski + +[ rebased for 3.8-rc3 /tmb ] +Signed-off-by: Thomas Backlund + +Removed the parts of the patch that are already applied in the kernel by +the commit 67384fe3fd450536342330f684ea1f7dcaef8130: + "char/agp: add another Ironlake host bridge" + +Rediffed for kernel 3.10.24. + +Signed-off-by: Eugene A. Shatokhin + + drivers/char/agp/intel-gtt.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff -Nurp linux-3.8-rc3/drivers/char/agp/intel-gtt.c linux-3.8-rc3.q57/drivers/char/agp/intel-gtt.c +--- linux-3.8-rc3/drivers/char/agp/intel-gtt.c 2013-01-10 08:17:09.690594184 +0200 ++++ linux-3.8-rc3.q57/drivers/char/agp/intel-gtt.c 2013-01-10 08:38:56.649888839 +0200 +@@ -1303,6 +1303,8 @@ static const struct intel_gtt_driver_des + &g4x_gtt_driver }, + { PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, + "HD Graphics", &ironlake_gtt_driver }, ++ { PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB, ++ "HD Graphics", &ironlake_gtt_driver }, + { PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, + "HD Graphics", &ironlake_gtt_driver }, + { 0, NULL, NULL } diff --git a/kernel/kernel/files/patches/mageia/dm-raid-aliases.patch b/kernel/kernel/files/patches/mageia/dm-raid-aliases.patch new file mode 100644 index 00000000..febdb720 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/dm-raid-aliases.patch @@ -0,0 +1,20 @@ + +This patch adds module aliases for matching the old dm-raid45 patch +by heinzm@redhat.com carried by kernel-tmb series in order to make +sure there is an upgrade path. + +Signed-off-by: Thomas Backlund + + drivers/md/dm-raid.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- linux-2.6.38.2-mga2/drivers/md/dm-raid.c.orig 2011-03-15 03:20:32.000000000 +0200 ++++ linux-2.6.38.2-mga2/drivers/md/dm-raid.c 2011-04-02 21:52:21.331302590 +0300 +@@ -693,5 +693,7 @@ MODULE_DESCRIPTION(DM_NAME " raid4/5/6 t + MODULE_ALIAS("dm-raid4"); + MODULE_ALIAS("dm-raid5"); + MODULE_ALIAS("dm-raid6"); ++MODULE_ALIAS("dm-raid45"); ++MODULE_ALIAS("dm-raid4-5"); + MODULE_AUTHOR("Neil Brown "); + MODULE_LICENSE("GPL"); diff --git a/kernel/kernel/files/patches/mageia/firewire-ieee1394-module-aliases.patch b/kernel/kernel/files/patches/mageia/firewire-ieee1394-module-aliases.patch new file mode 100644 index 00000000..34c4d489 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/firewire-ieee1394-module-aliases.patch @@ -0,0 +1,29 @@ + +This patch adds missing module aliases for the old ieee1394 stack +to make it easier for endusers. + +Note: firewire-sbp2 and firewire-ohci already contains the needed aliases. + +Signed-off-by: Thomas Backlund + +diff -Nurp linux-2.6.38.4/drivers/firewire/core-transaction.c linux-2.6.38.4.fw/drivers/firewire/core-transaction.c +--- linux-2.6.38.4/drivers/firewire/core-transaction.c 2011-03-15 03:20:32.000000000 +0200 ++++ linux-2.6.38.4.fw/drivers/firewire/core-transaction.c 2011-04-22 16:22:28.461386738 +0300 +@@ -1174,6 +1174,9 @@ static struct fw_address_handler registe + MODULE_AUTHOR("Kristian Hoegsberg "); + MODULE_DESCRIPTION("Core IEEE1394 transaction logic"); + MODULE_LICENSE("GPL"); ++MODULE_ALIAS("ieee1394"); ++MODULE_ALIAS("raw1394"); ++MODULE_ALIAS("video1394"); + + static const u32 vendor_textual_descriptor[] = { + /* textual descriptor leaf () */ +diff -Nurp linux-2.6.38.4/drivers/firewire/net.c linux-2.6.38.4.fw/drivers/firewire/net.c +--- linux-2.6.38.4/drivers/firewire/net.c 2011-03-15 03:20:32.000000000 +0200 ++++ linux-2.6.38.4.fw/drivers/firewire/net.c 2011-04-22 16:20:34.008883920 +0300 +@@ -1719,3 +1719,4 @@ MODULE_AUTHOR("Jay Fenlason +Date: Tue, 21 Apr 2015 16:46:28 +0300 +Subject: [PATCH] efi: Fix error handling in add_sysfs_runtime_map_entry() + +I spotted two (difficult to hit) bugs while reviewing this. + +1) There is a double free bug because we unregister "map_kset" in + add_sysfs_runtime_map_entry() and also efi_runtime_map_init(). +2) If we fail to allocate "entry" then we should return + ERR_PTR(-ENOMEM) instead of NULL. + +Signed-off-by: Dan Carpenter +Cc: Dave Young +Cc: Guangyu Sun +Cc: +Signed-off-by: Matt Fleming +--- + drivers/firmware/efi/runtime-map.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c +index 87b8e3b..5c55227 100644 +--- a/drivers/firmware/efi/runtime-map.c ++++ b/drivers/firmware/efi/runtime-map.c +@@ -120,7 +120,8 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr) + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) { + kset_unregister(map_kset); +- return entry; ++ map_kset = NULL; ++ return ERR_PTR(-ENOMEM); + } + + memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size, +@@ -132,6 +133,7 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr) + if (ret) { + kobject_put(&entry->kobj); + kset_unregister(map_kset); ++ map_kset = NULL; + return ERR_PTR(ret); + } + +@@ -195,8 +197,6 @@ out_add_entry: + entry = *(map_entries + j); + kobject_put(&entry->kobj); + } +- if (map_kset) +- kset_unregister(map_kset); + out: + return ret; + } +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/fs-aufs-3.19-modular.patch b/kernel/kernel/files/patches/mageia/fs-aufs-3.19-modular.patch new file mode 100644 index 00000000..d172ebbc --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-aufs-3.19-modular.patch @@ -0,0 +1,290 @@ + + fs/aufs/Kconfig | 2 +- + fs/dcache.c | 1 + + fs/inode.c | 2 ++ + fs/namespace.c | 2 ++ + fs/notify/group.c | 4 ++++ + fs/notify/mark.c | 4 ++++ + fs/open.c | 1 + + fs/splice.c | 2 ++ + security/commoncap.c | 2 ++ + security/device_cgroup.c | 2 ++ + security/security.c | 10 ++++++++++ + 11 files changed, 31 insertions(+), 1 deletion(-) + +diff -Nurp linux-3.19-aufs/fs/aufs/Kconfig linux-3.19-aufs-modular/fs/aufs/Kconfig +--- linux-3.19-aufs/fs/aufs/Kconfig 2015-02-22 23:16:18.302926737 +0200 ++++ linux-3.19-aufs-modular/fs/aufs/Kconfig 2015-02-22 23:23:41.617919334 +0200 +@@ -1,5 +1,5 @@ + config AUFS_FS +- bool "Aufs (Advanced multi layered unification filesystem) support" ++ tristate "Aufs (Advanced multi layered unification filesystem) support" + help + Aufs is a stackable unification filesystem such as Unionfs, + which unifies several directories and provides a merged single +diff -Nurp linux-3.19-aufs/fs/dcache.c linux-3.19-aufs-modular/fs/dcache.c +--- linux-3.19-aufs/fs/dcache.c 2015-02-22 23:16:18.313926786 +0200 ++++ linux-3.19-aufs-modular/fs/dcache.c 2015-02-22 23:23:41.620919348 +0200 +@@ -1124,6 +1124,7 @@ rename_retry: + seq = 1; + goto again; + } ++EXPORT_SYMBOL_GPL(d_walk); + + /* + * Search for at least 1 mount point in the dentry's subdirs. +diff -Nurp linux-3.19-aufs/fs/inode.c linux-3.19-aufs-modular/fs/inode.c +--- linux-3.19-aufs/fs/inode.c 2015-02-22 23:16:18.314926790 +0200 ++++ linux-3.19-aufs-modular/fs/inode.c 2015-02-22 23:23:41.617919334 +0200 +@@ -57,6 +57,7 @@ static struct hlist_head *inode_hashtabl + static __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_hash_lock); + + __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_sb_list_lock); ++EXPORT_SYMBOL(inode_sb_list_lock); + + /* + * Empty aops. Can be used for the cases where the user does not +@@ -1515,6 +1516,7 @@ int update_time(struct inode *inode, str + mark_inode_dirty_sync(inode); + return 0; + } ++EXPORT_SYMBOL(update_time); + + /** + * touch_atime - update the access time +diff -Nurp linux-3.19-aufs/fs/namespace.c linux-3.19-aufs-modular/fs/namespace.c +--- linux-3.19-aufs/fs/namespace.c 2015-02-09 04:54:22.000000000 +0200 ++++ linux-3.19-aufs-modular/fs/namespace.c 2015-02-22 23:23:41.618919339 +0200 +@@ -454,6 +454,7 @@ void __mnt_drop_write(struct vfsmount *m + mnt_dec_writers(real_mount(mnt)); + preempt_enable(); + } ++EXPORT_SYMBOL_GPL(__mnt_drop_write); + + /** + * mnt_drop_write - give up write access to a mount +@@ -1728,6 +1729,7 @@ int iterate_mounts(int (*f)(struct vfsmo + } + return 0; + } ++EXPORT_SYMBOL(iterate_mounts); + + static void cleanup_group_ids(struct mount *mnt, struct mount *end) + { +diff -Nurp linux-3.19-aufs/fs/notify/group.c linux-3.19-aufs-modular/fs/notify/group.c +--- linux-3.19-aufs/fs/notify/group.c 2015-02-09 04:54:22.000000000 +0200 ++++ linux-3.19-aufs-modular/fs/notify/group.c 2015-02-22 23:23:41.618919339 +0200 +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + + #include + #include "fsnotify.h" +@@ -72,6 +73,7 @@ void fsnotify_get_group(struct fsnotify_ + { + atomic_inc(&group->refcnt); + } ++EXPORT_SYMBOL(fsnotify_get_group); + + /* + * Drop a reference to a group. Free it if it's through. +@@ -81,6 +83,7 @@ void fsnotify_put_group(struct fsnotify_ + if (atomic_dec_and_test(&group->refcnt)) + fsnotify_final_destroy_group(group); + } ++EXPORT_SYMBOL(fsnotify_put_group); + + /* + * Create a new fsnotify_group and hold a reference for the group returned. +@@ -109,6 +112,7 @@ struct fsnotify_group *fsnotify_alloc_gr + + return group; + } ++EXPORT_SYMBOL(fsnotify_alloc_group); + + int fsnotify_fasync(int fd, struct file *file, int on) + { +diff -Nurp linux-3.19-aufs/fs/notify/mark.c linux-3.19-aufs-modular/fs/notify/mark.c +--- linux-3.19-aufs/fs/notify/mark.c 2015-02-09 04:54:22.000000000 +0200 ++++ linux-3.19-aufs-modular/fs/notify/mark.c 2015-02-22 23:23:41.618919339 +0200 +@@ -109,6 +109,7 @@ void fsnotify_put_mark(struct fsnotify_m + mark->free_mark(mark); + } + } ++EXPORT_SYMBOL(fsnotify_put_mark); + + /* Calculate mask of events for a list of marks */ + u32 fsnotify_recalc_mask(struct hlist_head *head) +@@ -202,6 +203,7 @@ void fsnotify_destroy_mark(struct fsnoti + fsnotify_destroy_mark_locked(mark, group); + mutex_unlock(&group->mark_mutex); + } ++EXPORT_SYMBOL(fsnotify_destroy_mark); + + /* + * Destroy all marks in the given list. The marks must be already detached from +@@ -386,6 +388,7 @@ int fsnotify_add_mark(struct fsnotify_ma + mutex_unlock(&group->mark_mutex); + return ret; + } ++EXPORT_SYMBOL(fsnotify_add_mark); + + /* + * Given a list of marks, find the mark associated with given group. If found +@@ -455,6 +458,7 @@ void fsnotify_init_mark(struct fsnotify_ + atomic_set(&mark->refcnt, 1); + mark->free_mark = free_mark; + } ++EXPORT_SYMBOL(fsnotify_init_mark); + + static int fsnotify_mark_destroy(void *ignored) + { +diff -Nurp linux-3.19-aufs/fs/open.c linux-3.19-aufs-modular/fs/open.c +--- linux-3.19-aufs/fs/open.c 2015-02-09 04:54:22.000000000 +0200 ++++ linux-3.19-aufs-modular/fs/open.c 2015-02-22 23:23:41.618919339 +0200 +@@ -62,6 +62,7 @@ int do_truncate(struct dentry *dentry, l + mutex_unlock(&dentry->d_inode->i_mutex); + return ret; + } ++EXPORT_SYMBOL(do_truncate); + + long vfs_truncate(struct path *path, loff_t length) + { +diff -Nurp linux-3.19-aufs/fs/splice.c linux-3.19-aufs-modular/fs/splice.c +--- linux-3.19-aufs/fs/splice.c 2015-02-22 23:16:18.315926795 +0200 ++++ linux-3.19-aufs-modular/fs/splice.c 2015-02-22 23:23:41.619919343 +0200 +@@ -1127,6 +1127,7 @@ long do_splice_from(struct pipe_inode_in + + return splice_write(pipe, out, ppos, len, flags); + } ++EXPORT_SYMBOL(do_splice_from); + + /* + * Attempt to initiate a splice from a file to a pipe. +@@ -1153,6 +1154,7 @@ long do_splice_to(struct file *in, loff_ + + return splice_read(in, ppos, pipe, len, flags); + } ++EXPORT_SYMBOL(do_splice_to); + + /** + * splice_direct_to_actor - splices data directly between two non-pipes +diff -Nurp linux-3.19-aufs/security/commoncap.c linux-3.19-aufs-modular/security/commoncap.c +--- linux-3.19-aufs/security/commoncap.c 2015-02-09 04:54:22.000000000 +0200 ++++ linux-3.19-aufs-modular/security/commoncap.c 2015-02-22 23:23:41.619919343 +0200 +@@ -979,9 +979,11 @@ int cap_mmap_addr(unsigned long addr) + } + return ret; + } ++EXPORT_SYMBOL(cap_mmap_addr); + + int cap_mmap_file(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags) + { + return 0; + } ++EXPORT_SYMBOL(cap_mmap_file); +diff -Nurp linux-3.19-aufs/security/device_cgroup.c linux-3.19-aufs-modular/security/device_cgroup.c +--- linux-3.19-aufs/security/device_cgroup.c 2015-02-09 04:54:22.000000000 +0200 ++++ linux-3.19-aufs-modular/security/device_cgroup.c 2015-02-22 23:23:41.619919343 +0200 +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct + return __devcgroup_check_permission(type, imajor(inode), iminor(inode), + access); + } ++EXPORT_SYMBOL(__devcgroup_inode_permission); + + int devcgroup_inode_mknod(int mode, dev_t dev) + { +diff -Nurp linux-3.19-aufs/security/security.c linux-3.19-aufs-modular/security/security.c +--- linux-3.19-aufs/security/security.c 2015-02-09 04:54:22.000000000 +0200 ++++ linux-3.19-aufs-modular/security/security.c 2015-02-22 23:23:41.619919343 +0200 +@@ -407,6 +407,7 @@ int security_path_rmdir(struct path *dir + return 0; + return security_ops->path_rmdir(dir, dentry); + } ++EXPORT_SYMBOL(security_path_rmdir); + + int security_path_unlink(struct path *dir, struct dentry *dentry) + { +@@ -423,6 +424,7 @@ int security_path_symlink(struct path *d + return 0; + return security_ops->path_symlink(dir, dentry, old_name); + } ++EXPORT_SYMBOL(security_path_symlink); + + int security_path_link(struct dentry *old_dentry, struct path *new_dir, + struct dentry *new_dentry) +@@ -431,6 +433,7 @@ int security_path_link(struct dentry *ol + return 0; + return security_ops->path_link(old_dentry, new_dir, new_dentry); + } ++EXPORT_SYMBOL(security_path_link); + + int security_path_rename(struct path *old_dir, struct dentry *old_dentry, + struct path *new_dir, struct dentry *new_dentry, +@@ -458,6 +461,7 @@ int security_path_truncate(struct path * + return 0; + return security_ops->path_truncate(path); + } ++EXPORT_SYMBOL(security_path_truncate); + + int security_path_chmod(struct path *path, umode_t mode) + { +@@ -465,6 +469,7 @@ int security_path_chmod(struct path *pat + return 0; + return security_ops->path_chmod(path, mode); + } ++EXPORT_SYMBOL(security_path_chmod); + + int security_path_chown(struct path *path, kuid_t uid, kgid_t gid) + { +@@ -472,6 +477,7 @@ int security_path_chown(struct path *pat + return 0; + return security_ops->path_chown(path, uid, gid); + } ++EXPORT_SYMBOL(security_path_chown); + + int security_path_chroot(struct path *path) + { +@@ -557,6 +563,7 @@ int security_inode_readlink(struct dentr + return 0; + return security_ops->inode_readlink(dentry); + } ++EXPORT_SYMBOL(security_inode_readlink); + + int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) + { +@@ -571,6 +578,7 @@ int security_inode_permission(struct ino + return 0; + return security_ops->inode_permission(inode, mask); + } ++EXPORT_SYMBOL(security_inode_permission); + + int security_inode_setattr(struct dentry *dentry, struct iattr *attr) + { +@@ -693,6 +701,7 @@ int security_file_permission(struct file + + return fsnotify_perm(file, mask); + } ++EXPORT_SYMBOL(security_file_permission); + + int security_file_alloc(struct file *file) + { +@@ -753,6 +762,7 @@ int security_mmap_file(struct file *file + return ret; + return ima_file_mmap(file, prot); + } ++EXPORT_SYMBOL(security_mmap_file); + + int security_mmap_addr(unsigned long addr) + { diff --git a/kernel/kernel/files/patches/mageia/fs-aufs-3.19.patch b/kernel/kernel/files/patches/mageia/fs-aufs-3.19.patch new file mode 100644 index 00000000..858eaefb --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-aufs-3.19.patch @@ -0,0 +1,34020 @@ + + Documentation/ABI/testing/debugfs-aufs | 50 + + Documentation/ABI/testing/sysfs-aufs | 31 + + Documentation/filesystems/aufs/README | 389 +++++ + Documentation/filesystems/aufs/design/01intro.txt | 148 ++ + Documentation/filesystems/aufs/design/02struct.txt | 238 +++ + Documentation/filesystems/aufs/design/03lookup.txt | 120 ++ + Documentation/filesystems/aufs/design/04branch.txt | 62 + + .../filesystems/aufs/design/05wbr_policy.txt | 51 + + Documentation/filesystems/aufs/design/06fhsm.txt | 105 ++ + Documentation/filesystems/aufs/design/06mmap.txt | 33 + + Documentation/filesystems/aufs/design/06xattr.txt | 81 + + Documentation/filesystems/aufs/design/07export.txt | 45 + + Documentation/filesystems/aufs/design/08shwh.txt | 39 + + Documentation/filesystems/aufs/design/10dynop.txt | 33 + + Documentation/filesystems/aufs/design/99plan.txt | 45 + + MAINTAINERS | 14 + + drivers/block/loop.c | 18 + + fs/Kconfig | 1 + + fs/Makefile | 1 + + fs/aufs/Kconfig | 185 ++ + fs/aufs/Makefile | 36 + + fs/aufs/aufs.h | 46 + + fs/aufs/branch.c | 1397 +++++++++++++++ + fs/aufs/branch.h | 254 +++ + fs/aufs/cpup.c | 1290 ++++++++++++++ + fs/aufs/cpup.h | 81 + + fs/aufs/dbgaufs.c | 419 +++++ + fs/aufs/dbgaufs.h | 35 + + fs/aufs/dcsub.c | 211 +++ + fs/aufs/dcsub.h | 112 ++ + fs/aufs/debug.c | 509 ++++++ + fs/aufs/debug.h | 249 +++ + fs/aufs/dentry.c | 1083 ++++++++++++ + fs/aufs/dentry.h | 220 +++ + fs/aufs/dinfo.c | 531 ++++++ + fs/aufs/dir.c | 632 +++++++ + fs/aufs/dir.h | 117 ++ + fs/aufs/dynop.c | 366 ++++ + fs/aufs/dynop.h | 62 + + fs/aufs/export.c | 818 +++++++++ + fs/aufs/f_op.c | 801 +++++++++ + fs/aufs/fhsm.c | 412 +++++ + fs/aufs/file.c | 816 +++++++++ + fs/aufs/file.h | 271 +++ + fs/aufs/finfo.c | 143 ++ + fs/aufs/fstype.h | 456 +++++ + fs/aufs/hfsnotify.c | 275 +++ + fs/aufs/hfsplus.c | 43 + + fs/aufs/hnotify.c | 701 ++++++++ + fs/aufs/i_op.c | 1286 ++++++++++++++ + fs/aufs/i_op_add.c | 878 ++++++++++ + fs/aufs/i_op_del.c | 494 ++++++ + fs/aufs/i_op_ren.c | 1021 +++++++++++ + fs/aufs/iinfo.c | 264 +++ + fs/aufs/inode.c | 483 +++++ + fs/aufs/inode.h | 654 +++++++ + fs/aufs/ioctl.c | 206 +++ + fs/aufs/loop.c | 132 ++ + fs/aufs/loop.h | 39 + + fs/aufs/magic.mk | 54 + + fs/aufs/module.c | 196 +++ + fs/aufs/module.h | 91 + + fs/aufs/mvdown.c | 681 ++++++++ + fs/aufs/opts.c | 1837 ++++++++++++++++++++ + fs/aufs/opts.h | 200 +++ + fs/aufs/plink.c | 519 ++++++ + fs/aufs/poll.c | 42 + + fs/aufs/posix_acl.c | 86 + + fs/aufs/procfs.c | 156 ++ + fs/aufs/rdu.c | 375 ++++ + fs/aufs/rwsem.h | 178 ++ + fs/aufs/sbinfo.c | 340 ++++ + fs/aufs/spl.h | 98 ++ + fs/aufs/super.c | 996 +++++++++++ + fs/aufs/super.h | 628 +++++++ + fs/aufs/sysaufs.c | 91 + + fs/aufs/sysaufs.h | 88 + + fs/aufs/sysfs.c | 336 ++++ + fs/aufs/sysrq.c | 144 ++ + fs/aufs/vdir.c | 876 ++++++++++ + fs/aufs/vfsub.c | 783 +++++++++ + fs/aufs/vfsub.h | 288 +++ + fs/aufs/wbr_policy.c | 752 ++++++++ + fs/aufs/whout.c | 1048 +++++++++++ + fs/aufs/whout.h | 72 + + fs/aufs/wkq.c | 200 +++ + fs/aufs/wkq.h | 78 + + fs/aufs/xattr.c | 321 ++++ + fs/aufs/xino.c | 1305 ++++++++++++++ + fs/buffer.c | 2 +- + fs/dcache.c | 2 +- + fs/inode.c | 2 +- + fs/proc/base.c | 2 +- + fs/proc/nommu.c | 5 +- + fs/proc/task_mmu.c | 7 +- + fs/proc/task_nommu.c | 5 +- + fs/splice.c | 10 +- + include/linux/fs.h | 1 + + include/linux/mm.h | 22 + + include/linux/mm_types.h | 2 + + include/linux/splice.h | 6 + + include/uapi/linux/Kbuild | 1 + + include/uapi/linux/aufs_type.h | 406 +++++ + kernel/fork.c | 2 +- + mm/Makefile | 2 +- + mm/filemap.c | 2 +- + mm/fremap.c | 16 +- + mm/madvise.c | 4 +- + mm/memory.c | 2 +- + mm/mmap.c | 12 +- + mm/msync.c | 4 +- + mm/nommu.c | 10 +- + mm/prfile.c | 86 + + 113 files changed, 32970 insertions(+), 34 deletions(-) + +diff --git a/Documentation/ABI/testing/debugfs-aufs b/Documentation/ABI/testing/debugfs-aufs +new file mode 100644 +index 0000000..99642d1 +--- /dev/null ++++ b/Documentation/ABI/testing/debugfs-aufs +@@ -0,0 +1,50 @@ ++What: /debug/aufs/si_/ ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ Under /debug/aufs, a directory named si_ is created ++ per aufs mount, where is a unique id generated ++ internally. ++ ++What: /debug/aufs/si_/plink ++Date: Apr 2013 ++Contact: J. R. Okajima ++Description: ++ It has three lines and shows the information about the ++ pseudo-link. The first line is a single number ++ representing a number of buckets. The second line is a ++ number of pseudo-links per buckets (separated by a ++ blank). The last line is a single number representing a ++ total number of psedo-links. ++ When the aufs mount option 'noplink' is specified, it ++ will show "1\n0\n0\n". ++ ++What: /debug/aufs/si_/xib ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the consumed blocks by xib (External Inode Number ++ Bitmap), its block size and file size. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see the aufs manual. ++ ++What: /debug/aufs/si_/xino0, xino1 ... xinoN ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the consumed blocks by xino (External Inode Number ++ Translation Table), its link count, block size and file ++ size. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see the aufs manual. ++ ++What: /debug/aufs/si_/xigen ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the consumed blocks by xigen (External Inode ++ Generation Table), its block size and file size. ++ If CONFIG_AUFS_EXPORT is disabled, this entry will not ++ be created. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see the aufs manual. +diff --git a/Documentation/ABI/testing/sysfs-aufs b/Documentation/ABI/testing/sysfs-aufs +new file mode 100644 +index 0000000..82f9518 +--- /dev/null ++++ b/Documentation/ABI/testing/sysfs-aufs +@@ -0,0 +1,31 @@ ++What: /sys/fs/aufs/si_/ ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ Under /sys/fs/aufs, a directory named si_ is created ++ per aufs mount, where is a unique id generated ++ internally. ++ ++What: /sys/fs/aufs/si_/br0, br1 ... brN ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the abolute path of a member directory (which ++ is called branch) in aufs, and its permission. ++ ++What: /sys/fs/aufs/si_/brid0, brid1 ... bridN ++Date: July 2013 ++Contact: J. R. Okajima ++Description: ++ It shows the id of a member directory (which is called ++ branch) in aufs. ++ ++What: /sys/fs/aufs/si_/xi_path ++Date: March 2009 ++Contact: J. R. Okajima ++Description: ++ It shows the abolute path of XINO (External Inode Number ++ Bitmap, Translation Table and Generation Table) file ++ even if it is the default path. ++ When the aufs mount option 'noxino' is specified, it ++ will be empty. About XINO files, see the aufs manual. +diff --git a/Documentation/filesystems/aufs/README b/Documentation/filesystems/aufs/README +new file mode 100644 +index 0000000..b81588a +--- /dev/null ++++ b/Documentation/filesystems/aufs/README +@@ -0,0 +1,389 @@ ++ ++Aufs3 -- advanced multi layered unification filesystem version 3.x ++http://aufs.sf.net ++Junjiro R. Okajima ++ ++ ++0. Introduction ++---------------------------------------- ++In the early days, aufs was entirely re-designed and re-implemented ++Unionfs Version 1.x series. After many original ideas, approaches, ++improvements and implementations, it becomes totally different from ++Unionfs while keeping the basic features. ++Recently, Unionfs Version 2.x series begin taking some of the same ++approaches to aufs1's. ++Unionfs is being developed by Professor Erez Zadok at Stony Brook ++University and his team. ++ ++Aufs3 supports linux-3.0 and later. ++If you want older kernel version support, try aufs2-2.6.git or ++aufs2-standalone.git repository, aufs1 from CVS on SourceForge. ++ ++Note: it becomes clear that "Aufs was rejected. Let's give it up." ++ According to Christoph Hellwig, linux rejects all union-type ++ filesystems but UnionMount. ++ ++ ++PS. Al Viro seems have a plan to merge aufs as well as overlayfs and ++ UnionMount, and he pointed out an issue around a directory mutex ++ lock and aufs addressed it. But it is still unsure whether aufs will ++ be merged (or any other union solution). ++ ++ ++ ++1. Features ++---------------------------------------- ++- unite several directories into a single virtual filesystem. The member ++ directory is called as a branch. ++- you can specify the permission flags to the branch, which are 'readonly', ++ 'readwrite' and 'whiteout-able.' ++- by upper writable branch, internal copyup and whiteout, files/dirs on ++ readonly branch are modifiable logically. ++- dynamic branch manipulation, add, del. ++- etc... ++ ++Also there are many enhancements in aufs1, such as: ++- readdir(3) in userspace. ++- keep inode number by external inode number table ++- keep the timestamps of file/dir in internal copyup operation ++- seekable directory, supporting NFS readdir. ++- whiteout is hardlinked in order to reduce the consumption of inodes ++ on branch ++- do not copyup, nor create a whiteout when it is unnecessary ++- revert a single systemcall when an error occurs in aufs ++- remount interface instead of ioctl ++- maintain /etc/mtab by an external command, /sbin/mount.aufs. ++- loopback mounted filesystem as a branch ++- kernel thread for removing the dir who has a plenty of whiteouts ++- support copyup sparse file (a file which has a 'hole' in it) ++- default permission flags for branches ++- selectable permission flags for ro branch, whether whiteout can ++ exist or not ++- export via NFS. ++- support /fs/aufs and /aufs. ++- support multiple writable branches, some policies to select one ++ among multiple writable branches. ++- a new semantics for link(2) and rename(2) to support multiple ++ writable branches. ++- no glibc changes are required. ++- pseudo hardlink (hardlink over branches) ++- allow a direct access manually to a file on branch, e.g. bypassing aufs. ++ including NFS or remote filesystem branch. ++- userspace wrapper for pathconf(3)/fpathconf(3) with _PC_LINK_MAX. ++- and more... ++ ++Currently these features are dropped temporary from aufs3. ++See design/08plan.txt in detail. ++- test only the highest one for the directory permission (dirperm1) ++- copyup on open (coo=) ++- nested mount, i.e. aufs as readonly no-whiteout branch of another aufs ++ (robr) ++- statistics of aufs thread (/sys/fs/aufs/stat) ++- delegation mode (dlgt) ++ a delegation of the internal branch access to support task I/O ++ accounting, which also supports Linux Security Modules (LSM) mainly ++ for Suse AppArmor. ++- intent.open/create (file open in a single lookup) ++ ++Features or just an idea in the future (see also design/*.txt), ++- reorder the branch index without del/re-add. ++- permanent xino files for NFSD ++- an option for refreshing the opened files after add/del branches ++- 'move' policy for copy-up between two writable branches, after ++ checking free space. ++- light version, without branch manipulation. (unnecessary?) ++- copyup in userspace ++- inotify in userspace ++- readv/writev ++- xattr, acl ++ ++ ++2. Download ++---------------------------------------- ++There were three GIT trees for aufs3, aufs3-linux.git, ++aufs3-standalone.git, and aufs-util.git. Note that there is no "3" in ++"aufs-util.git." ++While the aufs-util is always necessary, you need either of aufs3-linux ++or aufs3-standalone. ++ ++The aufs3-linux tree includes the whole linux mainline GIT tree, ++git://git.kernel.org/.../torvalds/linux.git. ++And you cannot select CONFIG_AUFS_FS=m for this version, eg. you cannot ++build aufs3 as an external kernel module. ++Several extra patches are not included in this tree. Only ++aufs3-standalong tree contains them. They are describe in the later ++section "Configuration and Compilation." ++ ++On the other hand, the aufs3-standalone tree has only aufs source files ++and necessary patches, and you can select CONFIG_AUFS_FS=m. ++But you need to apply all aufs patches manually. ++ ++You will find GIT branches whose name is in form of "aufs3.x" where "x" ++represents the linux kernel version, "linux-3.x". For instance, ++"aufs3.0" is for linux-3.0. For latest "linux-3.x-rcN", use ++"aufs3.x-rcN" branch. ++ ++o aufs3-linux tree ++$ git clone --reference /your/linux/git/tree \ ++ git://git.code.sf.net/p/aufs/aufs3-linux aufs3-linux.git ++- if you don't have linux GIT tree, then remove "--reference ..." ++$ cd aufs3-linux.git ++$ git checkout origin/aufs3.0 ++ ++Or You may want to directly git-pull aufs into your linux GIT tree, and ++leave the patch-work to GIT. ++$ cd /your/linux/git/tree ++$ git remote add aufs3 https://github.com/sfjro/aufs3-linux.git ++- aufs3-linux.git tree also exists on github. ++$ git fetch aufs3 ++$ git checkout -b my3.14 v3.14 ++$ (add your change...) ++$ git pull aufs3 aufs3.14 ++- now you have v3.14 + your_changes + aufs3.14 in you my3.14 branch. ++- you may need to solve some conflicts between your_changes and ++ aufs3.14. in this case, git-rerere is recommended so that you can ++ solve the similar confilicts automatically when you upgrade to 3.15 or ++ later in the future. ++ ++o aufs3-standalone tree ++$ git clone git://git.code.sf.net/p/aufs/aufs3-standalone \ ++ aufs3-standalone.git ++$ cd aufs3-standalone.git ++$ git checkout origin/aufs3.0 ++ ++o aufs-util tree ++$ git clone git://git.code.sf.net/p/aufs/aufs-util \ ++ aufs-util.git ++$ cd aufs-util.git ++$ git checkout origin/aufs3.0 ++ ++Note: The 3.x-rcN branch is to be used with `rc' kernel versions ONLY. ++The minor version number, 'x' in '3.x', of aufs may not always ++follow the minor version number of the kernel. ++Because changes in the kernel that cause the use of a new ++minor version number do not always require changes to aufs-util. ++ ++Since aufs-util has its own minor version number, you may not be ++able to find a GIT branch in aufs-util for your kernel's ++exact minor version number. ++In this case, you should git-checkout the branch for the ++nearest lower number. ++ ++For (an unreleased) example: ++If you are using "linux-3.10" and the "aufs3.10" branch ++does not exist in aufs-util repository, then "aufs3.9", "aufs3.8" ++or something numerically smaller is the branch for your kernel. ++ ++Also you can view all branches by ++ $ git branch -a ++ ++ ++3. Configuration and Compilation ++---------------------------------------- ++Make sure you have git-checkout'ed the correct branch. ++ ++For aufs3-linux tree, ++- enable CONFIG_AUFS_FS. ++- set other aufs configurations if necessary. ++ ++For aufs3-standalone tree, ++There are several ways to build. ++ ++1. ++- apply ./aufs3-kbuild.patch to your kernel source files. ++- apply ./aufs3-base.patch too. ++- apply ./aufs3-mmap.patch too. ++- apply ./aufs3-standalone.patch too, if you have a plan to set ++ CONFIG_AUFS_FS=m. otherwise you don't need ./aufs3-standalone.patch. ++- copy ./{Documentation,fs,include/uapi/linux/aufs_type.h} files to your ++ kernel source tree. Never copy $PWD/include/uapi/linux/Kbuild. ++- enable CONFIG_AUFS_FS, you can select either ++ =m or =y. ++- and build your kernel as usual. ++- install the built kernel. ++ Note: Since linux-3.9, every filesystem module requires an alias ++ "fs-". You should make sure that "fs-aufs" is listed in your ++ modules.aliases file if you set CONFIG_AUFS_FS=m. ++- install the header files too by "make headers_install" to the ++ directory where you specify. By default, it is $PWD/usr. ++ "make help" shows a brief note for headers_install. ++- and reboot your system. ++ ++2. ++- module only (CONFIG_AUFS_FS=m). ++- apply ./aufs3-base.patch to your kernel source files. ++- apply ./aufs3-mmap.patch too. ++- apply ./aufs3-standalone.patch too. ++- build your kernel, don't forget "make headers_install", and reboot. ++- edit ./config.mk and set other aufs configurations if necessary. ++ Note: You should read $PWD/fs/aufs/Kconfig carefully which describes ++ every aufs configurations. ++- build the module by simple "make". ++ Note: Since linux-3.9, every filesystem module requires an alias ++ "fs-". You should make sure that "fs-aufs" is listed in your ++ modules.aliases file. ++- you can specify ${KDIR} make variable which points to your kernel ++ source tree. ++- install the files ++ + run "make install" to install the aufs module, or copy the built ++ $PWD/aufs.ko to /lib/modules/... and run depmod -a (or reboot simply). ++ + run "make install_headers" (instead of headers_install) to install ++ the modified aufs header file (you can specify DESTDIR which is ++ available in aufs standalone version's Makefile only), or copy ++ $PWD/usr/include/linux/aufs_type.h to /usr/include/linux or wherever ++ you like manually. By default, the target directory is $PWD/usr. ++- no need to apply aufs3-kbuild.patch, nor copying source files to your ++ kernel source tree. ++ ++Note: The header file aufs_type.h is necessary to build aufs-util ++ as well as "make headers_install" in the kernel source tree. ++ headers_install is subject to be forgotten, but it is essentially ++ necessary, not only for building aufs-util. ++ You may not meet problems without headers_install in some older ++ version though. ++ ++And then, ++- read README in aufs-util, build and install it ++- note that your distribution may contain an obsoleted version of ++ aufs_type.h in /usr/include/linux or something. When you build aufs ++ utilities, make sure that your compiler refers the correct aufs header ++ file which is built by "make headers_install." ++- if you want to use readdir(3) in userspace or pathconf(3) wrapper, ++ then run "make install_ulib" too. And refer to the aufs manual in ++ detail. ++ ++There several other patches in aufs3-standalone.git. They are all ++optional. When you meet some problems, they will help you. ++- aufs3-loopback.patch ++ Supports a nested loopback mount in a branch-fs. This patch is ++ unnecessary until aufs produces a message like "you may want to try ++ another patch for loopback file". ++- vfs-ino.patch ++ Modifies a system global kernel internal function get_next_ino() in ++ order to stop assigning 0 for an inode-number. Not directly related to ++ aufs, but recommended generally. ++- tmpfs-idr.patch ++ Keeps the tmpfs inode number as the lowest value. Effective to reduce ++ the size of aufs XINO files for tmpfs branch. Also it prevents the ++ duplication of inode number, which is important for backup tools and ++ other utilities. When you find aufs XINO files for tmpfs branch ++ growing too much, try this patch. ++ ++ ++4. Usage ++---------------------------------------- ++At first, make sure aufs-util are installed, and please read the aufs ++manual, aufs.5 in aufs-util.git tree. ++$ man -l aufs.5 ++ ++And then, ++$ mkdir /tmp/rw /tmp/aufs ++# mount -t aufs -o br=/tmp/rw:${HOME} none /tmp/aufs ++ ++Here is another example. The result is equivalent. ++# mount -t aufs -o br=/tmp/rw=rw:${HOME}=ro none /tmp/aufs ++ Or ++# mount -t aufs -o br:/tmp/rw none /tmp/aufs ++# mount -o remount,append:${HOME} /tmp/aufs ++ ++Then, you can see whole tree of your home dir through /tmp/aufs. If ++you modify a file under /tmp/aufs, the one on your home directory is ++not affected, instead the same named file will be newly created under ++/tmp/rw. And all of your modification to a file will be applied to ++the one under /tmp/rw. This is called the file based Copy on Write ++(COW) method. ++Aufs mount options are described in aufs.5. ++If you run chroot or something and make your aufs as a root directory, ++then you need to customize the shutdown script. See the aufs manual in ++detail. ++ ++Additionally, there are some sample usages of aufs which are a ++diskless system with network booting, and LiveCD over NFS. ++See sample dir in CVS tree on SourceForge. ++ ++ ++5. Contact ++---------------------------------------- ++When you have any problems or strange behaviour in aufs, please let me ++know with: ++- /proc/mounts (instead of the output of mount(8)) ++- /sys/module/aufs/* ++- /sys/fs/aufs/* (if you have them) ++- /debug/aufs/* (if you have them) ++- linux kernel version ++ if your kernel is not plain, for example modified by distributor, ++ the url where i can download its source is necessary too. ++- aufs version which was printed at loading the module or booting the ++ system, instead of the date you downloaded. ++- configuration (define/undefine CONFIG_AUFS_xxx) ++- kernel configuration or /proc/config.gz (if you have it) ++- behaviour which you think to be incorrect ++- actual operation, reproducible one is better ++- mailto: aufs-users at lists.sourceforge.net ++ ++Usually, I don't watch the Public Areas(Bugs, Support Requests, Patches, ++and Feature Requests) on SourceForge. Please join and write to ++aufs-users ML. ++ ++ ++6. Acknowledgements ++---------------------------------------- ++Thanks to everyone who have tried and are using aufs, whoever ++have reported a bug or any feedback. ++ ++Especially donators: ++Tomas Matejicek(slax.org) made a donation (much more than once). ++ Since Apr 2010, Tomas M (the author of Slax and Linux Live ++ scripts) is making "doubling" donations. ++ Unfortunately I cannot list all of the donators, but I really ++ appreciate. ++ It ends Aug 2010, but the ordinary donation URL is still available. ++ ++Dai Itasaka made a donation (2007/8). ++Chuck Smith made a donation (2008/4, 10 and 12). ++Henk Schoneveld made a donation (2008/9). ++Chih-Wei Huang, ASUS, CTC donated Eee PC 4G (2008/10). ++Francois Dupoux made a donation (2008/11). ++Bruno Cesar Ribas and Luis Carlos Erpen de Bona, C3SL serves public ++ aufs2 GIT tree (2009/2). ++William Grant made a donation (2009/3). ++Patrick Lane made a donation (2009/4). ++The Mail Archive (mail-archive.com) made donations (2009/5). ++Nippy Networks (Ed Wildgoose) made a donation (2009/7). ++New Dream Network, LLC (www.dreamhost.com) made a donation (2009/11). ++Pavel Pronskiy made a donation (2011/2). ++Iridium and Inmarsat satellite phone retailer (www.mailasail.com), Nippy ++ Networks (Ed Wildgoose) made a donation for hardware (2011/3). ++Max Lekomcev (DOM-TV project) made a donation (2011/7, 12, 2012/3, 6 and ++11). ++Sam Liddicott made a donation (2011/9). ++Era Scarecrow made a donation (2013/4). ++Bor Ratajc made a donation (2013/4). ++Alessandro Gorreta made a donation (2013/4). ++POIRETTE Marc made a donation (2013/4). ++Alessandro Gorreta made a donation (2013/4). ++lauri kasvandik made a donation (2013/5). ++"pemasu from Finland" made a donation (2013/7). ++The Parted Magic Project made a donation (2013/9 and 11). ++Pavel Barta made a donation (2013/10). ++Nikolay Pertsev made a donation (2014/5). ++James B made a donation (2014/7). ++Stefano Di Biase made a donation (2014/8). ++Daniel Epellei made a donation (2015/1). ++ ++Thank you very much. ++Donations are always, including future donations, very important and ++helpful for me to keep on developing aufs. ++ ++ ++7. ++---------------------------------------- ++If you are an experienced user, no explanation is needed. Aufs is ++just a linux filesystem. ++ ++ ++Enjoy! ++ ++# Local variables: ; ++# mode: text; ++# End: ; +diff --git a/Documentation/filesystems/aufs/design/01intro.txt b/Documentation/filesystems/aufs/design/01intro.txt +new file mode 100644 +index 0000000..7f491fb +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/01intro.txt +@@ -0,0 +1,148 @@ ++ ++# Copyright (C) 2005-2015 Junjiro R. Okajima ++ ++Introduction ++---------------------------------------- ++ ++aufs [ei ju: ef es] | [a u f s] ++1. abbrev. for "advanced multi-layered unification filesystem". ++2. abbrev. for "another unionfs". ++3. abbrev. for "auf das" in German which means "on the" in English. ++ Ex. "Butter aufs Brot"(G) means "butter onto bread"(E). ++ But "Filesystem aufs Filesystem" is hard to understand. ++ ++AUFS is a filesystem with features: ++- multi layered stackable unification filesystem, the member directory ++ is called as a branch. ++- branch permission and attribute, 'readonly', 'real-readonly', ++ 'readwrite', 'whiteout-able', 'link-able whiteout' and their ++ combination. ++- internal "file copy-on-write". ++- logical deletion, whiteout. ++- dynamic branch manipulation, adding, deleting and changing permission. ++- allow bypassing aufs, user's direct branch access. ++- external inode number translation table and bitmap which maintains the ++ persistent aufs inode number. ++- seekable directory, including NFS readdir. ++- file mapping, mmap and sharing pages. ++- pseudo-link, hardlink over branches. ++- loopback mounted filesystem as a branch. ++- several policies to select one among multiple writable branches. ++- revert a single systemcall when an error occurs in aufs. ++- and more... ++ ++ ++Multi Layered Stackable Unification Filesystem ++---------------------------------------------------------------------- ++Most people already knows what it is. ++It is a filesystem which unifies several directories and provides a ++merged single directory. When users access a file, the access will be ++passed/re-directed/converted (sorry, I am not sure which English word is ++correct) to the real file on the member filesystem. The member ++filesystem is called 'lower filesystem' or 'branch' and has a mode ++'readonly' and 'readwrite.' And the deletion for a file on the lower ++readonly branch is handled by creating 'whiteout' on the upper writable ++branch. ++ ++On LKML, there have been discussions about UnionMount (Jan Blunck, ++Bharata B Rao and Valerie Aurora) and Unionfs (Erez Zadok). They took ++different approaches to implement the merged-view. ++The former tries putting it into VFS, and the latter implements as a ++separate filesystem. ++(If I misunderstand about these implementations, please let me know and ++I shall correct it. Because it is a long time ago when I read their ++source files last time). ++ ++UnionMount's approach will be able to small, but may be hard to share ++branches between several UnionMount since the whiteout in it is ++implemented in the inode on branch filesystem and always ++shared. According to Bharata's post, readdir does not seems to be ++finished yet. ++There are several missing features known in this implementations such as ++- for users, the inode number may change silently. eg. copy-up. ++- link(2) may break by copy-up. ++- read(2) may get an obsoleted filedata (fstat(2) too). ++- fcntl(F_SETLK) may be broken by copy-up. ++- unnecessary copy-up may happen, for example mmap(MAP_PRIVATE) after ++ open(O_RDWR). ++ ++Unionfs has a longer history. When I started implementing a stacking filesystem ++(Aug 2005), it already existed. It has virtual super_block, inode, ++dentry and file objects and they have an array pointing lower same kind ++objects. After contributing many patches for Unionfs, I re-started my ++project AUFS (Jun 2006). ++ ++In AUFS, the structure of filesystem resembles to Unionfs, but I ++implemented my own ideas, approaches and enhancements and it became ++totally different one. ++ ++Comparing DM snapshot and fs based implementation ++- the number of bytes to be copied between devices is much smaller. ++- the type of filesystem must be one and only. ++- the fs must be writable, no readonly fs, even for the lower original ++ device. so the compression fs will not be usable. but if we use ++ loopback mount, we may address this issue. ++ for instance, ++ mount /cdrom/squashfs.img /sq ++ losetup /sq/ext2.img ++ losetup /somewhere/cow ++ dmsetup "snapshot /dev/loop0 /dev/loop1 ..." ++- it will be difficult (or needs more operations) to extract the ++ difference between the original device and COW. ++- DM snapshot-merge may help a lot when users try merging. in the ++ fs-layer union, users will use rsync(1). ++ ++ ++Several characters/aspects of aufs ++---------------------------------------------------------------------- ++ ++Aufs has several characters or aspects. ++1. a filesystem, callee of VFS helper ++2. sub-VFS, caller of VFS helper for branches ++3. a virtual filesystem which maintains persistent inode number ++4. reader/writer of files on branches such like an application ++ ++1. Callee of VFS Helper ++As an ordinary linux filesystem, aufs is a callee of VFS. For instance, ++unlink(2) from an application reaches sys_unlink() kernel function and ++then vfs_unlink() is called. vfs_unlink() is one of VFS helper and it ++calls filesystem specific unlink operation. Actually aufs implements the ++unlink operation but it behaves like a redirector. ++ ++2. Caller of VFS Helper for Branches ++aufs_unlink() passes the unlink request to the branch filesystem as if ++it were called from VFS. So the called unlink operation of the branch ++filesystem acts as usual. As a caller of VFS helper, aufs should handle ++every necessary pre/post operation for the branch filesystem. ++- acquire the lock for the parent dir on a branch ++- lookup in a branch ++- revalidate dentry on a branch ++- mnt_want_write() for a branch ++- vfs_unlink() for a branch ++- mnt_drop_write() for a branch ++- release the lock on a branch ++ ++3. Persistent Inode Number ++One of the most important issue for a filesystem is to maintain inode ++numbers. This is particularly important to support exporting a ++filesystem via NFS. Aufs is a virtual filesystem which doesn't have a ++backend block device for its own. But some storage is necessary to ++maintain inode number. It may be a large space and may not suit to keep ++in memory. Aufs rents some space from its first writable branch ++filesystem (by default) and creates file(s) on it. These files are ++created by aufs internally and removed soon (currently) keeping opened. ++Note: Because these files are removed, they are totally gone after ++ unmounting aufs. It means the inode numbers are not persistent ++ across unmount or reboot. I have a plan to make them really ++ persistent which will be important for aufs on NFS server. ++ ++4. Read/Write Files Internally (copy-on-write) ++Because a branch can be readonly, when you write a file on it, aufs will ++"copy-up" it to the upper writable branch internally. And then write the ++originally requested thing to the file. Generally kernel doesn't ++open/read/write file actively. In aufs, even a single write may cause a ++internal "file copy". This behaviour is very similar to cp(1) command. ++ ++Some people may think it is better to pass such work to user space ++helper, instead of doing in kernel space. Actually I am still thinking ++about it. But currently I have implemented it in kernel space. +diff --git a/Documentation/filesystems/aufs/design/02struct.txt b/Documentation/filesystems/aufs/design/02struct.txt +new file mode 100644 +index 0000000..f185393 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/02struct.txt +@@ -0,0 +1,238 @@ ++ ++# Copyright (C) 2005-2015 Junjiro R. Okajima ++ ++Basic Aufs Internal Structure ++ ++Superblock/Inode/Dentry/File Objects ++---------------------------------------------------------------------- ++As like an ordinary filesystem, aufs has its own ++superblock/inode/dentry/file objects. All these objects have a ++dynamically allocated array and store the same kind of pointers to the ++lower filesystem, branch. ++For example, when you build a union with one readwrite branch and one ++readonly, mounted /au, /rw and /ro respectively. ++- /au = /rw + /ro ++- /ro/fileA exists but /rw/fileA ++ ++Aufs lookup operation finds /ro/fileA and gets dentry for that. These ++pointers are stored in a aufs dentry. The array in aufs dentry will be, ++- [0] = NULL ++- [1] = /ro/fileA ++ ++This style of an array is essentially same to the aufs ++superblock/inode/dentry/file objects. ++ ++Because aufs supports manipulating branches, ie. add/delete/change ++dynamically, these objects has its own generation. When branches are ++changed, the generation in aufs superblock is incremented. And a ++generation in other object are compared when it is accessed. ++When a generation in other objects are obsoleted, aufs refreshes the ++internal array. ++ ++ ++Superblock ++---------------------------------------------------------------------- ++Additionally aufs superblock has some data for policies to select one ++among multiple writable branches, XIB files, pseudo-links and kobject. ++See below in detail. ++About the policies which supports copy-down a directory, see policy.txt ++too. ++ ++ ++Branch and XINO(External Inode Number Translation Table) ++---------------------------------------------------------------------- ++Every branch has its own xino (external inode number translation table) ++file. The xino file is created and unlinked by aufs internally. When two ++members of a union exist on the same filesystem, they share the single ++xino file. ++The struct of a xino file is simple, just a sequence of aufs inode ++numbers which is indexed by the lower inode number. ++In the above sample, assume the inode number of /ro/fileA is i111 and ++aufs assigns the inode number i999 for fileA. Then aufs writes 999 as ++4(8) bytes at 111 * 4(8) bytes offset in the xino file. ++ ++When the inode numbers are not contiguous, the xino file will be sparse ++which has a hole in it and doesn't consume as much disk space as it ++might appear. If your branch filesystem consumes disk space for such ++holes, then you should specify 'xino=' option at mounting aufs. ++ ++Also a writable branch has three kinds of "whiteout bases". All these ++are existed when the branch is joined to aufs and the names are ++whiteout-ed doubly, so that users will never see their names in aufs ++hierarchy. ++1. a regular file which will be linked to all whiteouts. ++2. a directory to store a pseudo-link. ++3. a directory to store an "orphan-ed" file temporary. ++ ++1. Whiteout Base ++ When you remove a file on a readonly branch, aufs handles it as a ++ logical deletion and creates a whiteout on the upper writable branch ++ as a hardlink of this file in order not to consume inode on the ++ writable branch. ++2. Pseudo-link Dir ++ See below, Pseudo-link. ++3. Step-Parent Dir ++ When "fileC" exists on the lower readonly branch only and it is ++ opened and removed with its parent dir, and then user writes ++ something into it, then aufs copies-up fileC to this ++ directory. Because there is no other dir to store fileC. After ++ creating a file under this dir, the file is unlinked. ++ ++Because aufs supports manipulating branches, ie. add/delete/change ++dynamically, a branch has its own id. When the branch order changes, aufs ++finds the new index by searching the branch id. ++ ++ ++Pseudo-link ++---------------------------------------------------------------------- ++Assume "fileA" exists on the lower readonly branch only and it is ++hardlinked to "fileB" on the branch. When you write something to fileA, ++aufs copies-up it to the upper writable branch. Additionally aufs ++creates a hardlink under the Pseudo-link Directory of the writable ++branch. The inode of a pseudo-link is kept in aufs super_block as a ++simple list. If fileB is read after unlinking fileA, aufs returns ++filedata from the pseudo-link instead of the lower readonly ++branch. Because the pseudo-link is based upon the inode, to keep the ++inode number by xino (see above) is important. ++ ++All the hardlinks under the Pseudo-link Directory of the writable branch ++should be restored in a proper location later. Aufs provides a utility ++to do this. The userspace helpers executed at remounting and unmounting ++aufs by default. ++During this utility is running, it puts aufs into the pseudo-link ++maintenance mode. In this mode, only the process which began the ++maintenance mode (and its child processes) is allowed to operate in ++aufs. Some other processes which are not related to the pseudo-link will ++be allowed to run too, but the rest have to return an error or wait ++until the maintenance mode ends. If a process already acquires an inode ++mutex (in VFS), it has to return an error. ++ ++ ++XIB(external inode number bitmap) ++---------------------------------------------------------------------- ++Addition to the xino file per a branch, aufs has an external inode number ++bitmap in a superblock object. It is also a file such like a xino file. ++It is a simple bitmap to mark whether the aufs inode number is in-use or ++not. ++To reduce the file I/O, aufs prepares a single memory page to cache xib. ++ ++Aufs implements a feature to truncate/refresh both of xino and xib to ++reduce the number of consumed disk blocks for these files. ++ ++ ++Virtual or Vertical Dir, and Readdir in Userspace ++---------------------------------------------------------------------- ++In order to support multiple layers (branches), aufs readdir operation ++constructs a virtual dir block on memory. For readdir, aufs calls ++vfs_readdir() internally for each dir on branches, merges their entries ++with eliminating the whiteout-ed ones, and sets it to file (dir) ++object. So the file object has its entry list until it is closed. The ++entry list will be updated when the file position is zero and becomes ++old. This decision is made in aufs automatically. ++ ++The dynamically allocated memory block for the name of entries has a ++unit of 512 bytes (by default) and stores the names contiguously (no ++padding). Another block for each entry is handled by kmem_cache too. ++During building dir blocks, aufs creates hash list and judging whether ++the entry is whiteouted by its upper branch or already listed. ++The merged result is cached in the corresponding inode object and ++maintained by a customizable life-time option. ++ ++Some people may call it can be a security hole or invite DoS attack ++since the opened and once readdir-ed dir (file object) holds its entry ++list and becomes a pressure for system memory. But I'd say it is similar ++to files under /proc or /sys. The virtual files in them also holds a ++memory page (generally) while they are opened. When an idea to reduce ++memory for them is introduced, it will be applied to aufs too. ++For those who really hate this situation, I've developed readdir(3) ++library which operates this merging in userspace. You just need to set ++LD_PRELOAD environment variable, and aufs will not consume no memory in ++kernel space for readdir(3). ++ ++ ++Workqueue ++---------------------------------------------------------------------- ++Aufs sometimes requires privilege access to a branch. For instance, ++in copy-up/down operation. When a user process is going to make changes ++to a file which exists in the lower readonly branch only, and the mode ++of one of ancestor directories may not be writable by a user ++process. Here aufs copy-up the file with its ancestors and they may ++require privilege to set its owner/group/mode/etc. ++This is a typical case of a application character of aufs (see ++Introduction). ++ ++Aufs uses workqueue synchronously for this case. It creates its own ++workqueue. The workqueue is a kernel thread and has privilege. Aufs ++passes the request to call mkdir or write (for example), and wait for ++its completion. This approach solves a problem of a signal handler ++simply. ++If aufs didn't adopt the workqueue and changed the privilege of the ++process, and if the mkdir/write call arises SIGXFSZ or other signal, ++then the user process might gain a privilege or the generated core file ++was owned by a superuser. ++ ++Also aufs uses the system global workqueue ("events" kernel thread) too ++for asynchronous tasks, such like handling inotify/fsnotify, re-creating a ++whiteout base and etc. This is unrelated to a privilege. ++Most of aufs operation tries acquiring a rw_semaphore for aufs ++superblock at the beginning, at the same time waits for the completion ++of all queued asynchronous tasks. ++ ++ ++Whiteout ++---------------------------------------------------------------------- ++The whiteout in aufs is very similar to Unionfs's. That is represented ++by its filename. UnionMount takes an approach of a file mode, but I am ++afraid several utilities (find(1) or something) will have to support it. ++ ++Basically the whiteout represents "logical deletion" which stops aufs to ++lookup further, but also it represents "dir is opaque" which also stop ++lookup. ++ ++In aufs, rmdir(2) and rename(2) for dir uses whiteout alternatively. ++In order to make several functions in a single systemcall to be ++revertible, aufs adopts an approach to rename a directory to a temporary ++unique whiteouted name. ++For example, in rename(2) dir where the target dir already existed, aufs ++renames the target dir to a temporary unique whiteouted name before the ++actual rename on a branch and then handles other actions (make it opaque, ++update the attributes, etc). If an error happens in these actions, aufs ++simply renames the whiteouted name back and returns an error. If all are ++succeeded, aufs registers a function to remove the whiteouted unique ++temporary name completely and asynchronously to the system global ++workqueue. ++ ++ ++Copy-up ++---------------------------------------------------------------------- ++It is a well-known feature or concept. ++When user modifies a file on a readonly branch, aufs operate "copy-up" ++internally and makes change to the new file on the upper writable branch. ++When the trigger systemcall does not update the timestamps of the parent ++dir, aufs reverts it after copy-up. ++ ++ ++Move-down (aufs3.9 and later) ++---------------------------------------------------------------------- ++"Copy-up" is one of the essential feature in aufs. It copies a file from ++the lower readonly branch to the upper writable branch when a user ++changes something about the file. ++"Move-down" is an opposite action of copy-up. Basically this action is ++ran manually instead of automatically and internally. ++For desgin and implementation, aufs has to consider these issues. ++- whiteout for the file may exist on the lower branch. ++- ancestor directories may not exist on the lower branch. ++- diropq for the ancestor directories may exist on the upper branch. ++- free space on the lower branch will reduce. ++- another access to the file may happen during moving-down, including ++ UDBA. ++- the file should not be hard-linked nor pseudo-linked. they should be ++ handled by auplink utility later. ++ ++Sometimes users want to move-down a file from the upper writable branch ++to the lower readonly or writable branch. For instance, ++- the free space of the upper writable branch is going to run out. ++- create a new intermediate branch between the upper and lower branch. ++- etc. ++ ++For this purpose, use "aumvdown" command in aufs-util.git. +diff --git a/Documentation/filesystems/aufs/design/03lookup.txt b/Documentation/filesystems/aufs/design/03lookup.txt +new file mode 100644 +index 0000000..55ade95 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/03lookup.txt +@@ -0,0 +1,120 @@ ++ ++# Copyright (C) 2005-2015 Junjiro R. Okajima ++ ++Lookup in a Branch ++---------------------------------------------------------------------- ++Since aufs has a character of sub-VFS (see Introduction), it operates ++lookup for branches as VFS does. It may be a heavy work. Generally ++speaking struct nameidata is a bigger structure and includes many ++information. But almost all lookup operation in aufs is the simplest ++case, ie. lookup only an entry directly connected to its parent. Digging ++down the directory hierarchy is unnecessary. ++ ++VFS has a function lookup_one_len() for that use, but it is not usable ++for a branch filesystem which requires struct nameidata. So aufs ++implements a simple lookup wrapper function. When a branch filesystem ++allows NULL as nameidata, it calls lookup_one_len(). Otherwise it builds ++a simplest nameidata and calls lookup_hash(). ++Here aufs applies "a principle in NFSD", ie. if the filesystem supports ++NFS-export, then it has to support NULL as a nameidata parameter for ++->create(), ->lookup() and ->d_revalidate(). So the lookup wrapper in ++aufs tests if ->s_export_op in the branch is NULL or not. ++ ++When a branch is a remote filesystem, aufs basically trusts its ++->d_revalidate(), also aufs forces the hardest revalidate tests for ++them. ++For d_revalidate, aufs implements three levels of revalidate tests. See ++"Revalidate Dentry and UDBA" in detail. ++ ++ ++Test Only the Highest One for the Directory Permission (dirperm1 option) ++---------------------------------------------------------------------- ++Let's try case study. ++- aufs has two branches, upper readwrite and lower readonly. ++ /au = /rw + /ro ++- "dirA" exists under /ro, but /rw. and its mode is 0700. ++- user invoked "chmod a+rx /au/dirA" ++- the internal copy-up is activated and "/rw/dirA" is created and its ++ permission bits are set to world readble. ++- then "/au/dirA" becomes world readable? ++ ++In this case, /ro/dirA is still 0700 since it exists in readonly branch, ++or it may be a natively readonly filesystem. If aufs respects the lower ++branch, it should not respond readdir request from other users. But user ++allowed it by chmod. Should really aufs rejects showing the entries ++under /ro/dirA? ++ ++To be honest, I don't have a best solution for this case. So aufs ++implements 'dirperm1' and 'nodirperm1' and leave it to users. ++When dirperm1 is specified, aufs checks only the highest one for the ++directory permission, and shows the entries. Otherwise, as usual, checks ++every dir existing on all branches and rejects the request. ++ ++As a side effect, dirperm1 option improves the performance of aufs ++because the number of permission check is reduced when the number of ++branch is many. ++ ++ ++Loopback Mount ++---------------------------------------------------------------------- ++Basically aufs supports any type of filesystem and block device for a ++branch (actually there are some exceptions). But it is prohibited to add ++a loopback mounted one whose backend file exists in a filesystem which is ++already added to aufs. The reason is to protect aufs from a recursive ++lookup. If it was allowed, the aufs lookup operation might re-enter a ++lookup for the loopback mounted branch in the same context, and will ++cause a deadlock. ++ ++ ++Revalidate Dentry and UDBA (User's Direct Branch Access) ++---------------------------------------------------------------------- ++Generally VFS helpers re-validate a dentry as a part of lookup. ++0. digging down the directory hierarchy. ++1. lock the parent dir by its i_mutex. ++2. lookup the final (child) entry. ++3. revalidate it. ++4. call the actual operation (create, unlink, etc.) ++5. unlock the parent dir ++ ++If the filesystem implements its ->d_revalidate() (step 3), then it is ++called. Actually aufs implements it and checks the dentry on a branch is ++still valid. ++But it is not enough. Because aufs has to release the lock for the ++parent dir on a branch at the end of ->lookup() (step 2) and ++->d_revalidate() (step 3) while the i_mutex of the aufs dir is still ++held by VFS. ++If the file on a branch is changed directly, eg. bypassing aufs, after ++aufs released the lock, then the subsequent operation may cause ++something unpleasant result. ++ ++This situation is a result of VFS architecture, ->lookup() and ++->d_revalidate() is separated. But I never say it is wrong. It is a good ++design from VFS's point of view. It is just not suitable for sub-VFS ++character in aufs. ++ ++Aufs supports such case by three level of revalidation which is ++selectable by user. ++1. Simple Revalidate ++ Addition to the native flow in VFS's, confirm the child-parent ++ relationship on the branch just after locking the parent dir on the ++ branch in the "actual operation" (step 4). When this validation ++ fails, aufs returns EBUSY. ->d_revalidate() (step 3) in aufs still ++ checks the validation of the dentry on branches. ++2. Monitor Changes Internally by Inotify/Fsnotify ++ Addition to above, in the "actual operation" (step 4) aufs re-lookup ++ the dentry on the branch, and returns EBUSY if it finds different ++ dentry. ++ Additionally, aufs sets the inotify/fsnotify watch for every dir on branches ++ during it is in cache. When the event is notified, aufs registers a ++ function to kernel 'events' thread by schedule_work(). And the ++ function sets some special status to the cached aufs dentry and inode ++ private data. If they are not cached, then aufs has nothing to ++ do. When the same file is accessed through aufs (step 0-3) later, ++ aufs will detect the status and refresh all necessary data. ++ In this mode, aufs has to ignore the event which is fired by aufs ++ itself. ++3. No Extra Validation ++ This is the simplest test and doesn't add any additional revalidation ++ test, and skip therevalidatin in step 4. It is useful and improves ++ aufs performance when system surely hide the aufs branches from user, ++ by over-mounting something (or another method). +diff --git a/Documentation/filesystems/aufs/design/04branch.txt b/Documentation/filesystems/aufs/design/04branch.txt +new file mode 100644 +index 0000000..644ceb1 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/04branch.txt +@@ -0,0 +1,62 @@ ++ ++# Copyright (C) 2005-2015 Junjiro R. Okajima ++ ++Branch Manipulation ++ ++Since aufs supports dynamic branch manipulation, ie. add/remove a branch ++and changing its permission/attribute, there are a lot of works to do. ++ ++ ++Add a Branch ++---------------------------------------------------------------------- ++o Confirm the adding dir exists outside of aufs, including loopback ++ mount. ++- and other various attributes... ++o Initialize the xino file and whiteout bases if necessary. ++ See struct.txt. ++ ++o Check the owner/group/mode of the directory ++ When the owner/group/mode of the adding directory differs from the ++ existing branch, aufs issues a warning because it may impose a ++ security risk. ++ For example, when a upper writable branch has a world writable empty ++ top directory, a malicious user can create any files on the writable ++ branch directly, like copy-up and modify manually. If something like ++ /etc/{passwd,shadow} exists on the lower readonly branch but the upper ++ writable branch, and the writable branch is world-writable, then a ++ malicious guy may create /etc/passwd on the writable branch directly ++ and the infected file will be valid in aufs. ++ I am afraid it can be a security issue, but nothing to do except ++ producing a warning. ++ ++ ++Delete a Branch ++---------------------------------------------------------------------- ++o Confirm the deleting branch is not busy ++ To be general, there is one merit to adopt "remount" interface to ++ manipulate branches. It is to discard caches. At deleting a branch, ++ aufs checks the still cached (and connected) dentries and inodes. If ++ there are any, then they are all in-use. An inode without its ++ corresponding dentry can be alive alone (for example, inotify/fsnotify case). ++ ++ For the cached one, aufs checks whether the same named entry exists on ++ other branches. ++ If the cached one is a directory, because aufs provides a merged view ++ to users, as long as one dir is left on any branch aufs can show the ++ dir to users. In this case, the branch can be removed from aufs. ++ Otherwise aufs rejects deleting the branch. ++ ++ If any file on the deleting branch is opened by aufs, then aufs ++ rejects deleting. ++ ++ ++Modify the Permission of a Branch ++---------------------------------------------------------------------- ++o Re-initialize or remove the xino file and whiteout bases if necessary. ++ See struct.txt. ++ ++o rw --> ro: Confirm the modifying branch is not busy ++ Aufs rejects the request if any of these conditions are true. ++ - a file on the branch is mmap-ed. ++ - a regular file on the branch is opened for write and there is no ++ same named entry on the upper branch. +diff --git a/Documentation/filesystems/aufs/design/05wbr_policy.txt b/Documentation/filesystems/aufs/design/05wbr_policy.txt +new file mode 100644 +index 0000000..fc64d70 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt +@@ -0,0 +1,51 @@ ++ ++# Copyright (C) 2005-2015 Junjiro R. Okajima ++ ++Policies to Select One among Multiple Writable Branches ++---------------------------------------------------------------------- ++When the number of writable branch is more than one, aufs has to decide ++the target branch for file creation or copy-up. By default, the highest ++writable branch which has the parent (or ancestor) dir of the target ++file is chosen (top-down-parent policy). ++By user's request, aufs implements some other policies to select the ++writable branch, for file creation two policies, round-robin and ++most-free-space policies. For copy-up three policies, top-down-parent, ++bottom-up-parent and bottom-up policies. ++ ++As expected, the round-robin policy selects the branch in circular. When ++you have two writable branches and creates 10 new files, 5 files will be ++created for each branch. mkdir(2) systemcall is an exception. When you ++create 10 new directories, all will be created on the same branch. ++And the most-free-space policy selects the one which has most free ++space among the writable branches. The amount of free space will be ++checked by aufs internally, and users can specify its time interval. ++ ++The policies for copy-up is more simple, ++top-down-parent is equivalent to the same named on in create policy, ++bottom-up-parent selects the writable branch where the parent dir ++exists and the nearest upper one from the copyup-source, ++bottom-up selects the nearest upper writable branch from the ++copyup-source, regardless the existence of the parent dir. ++ ++There are some rules or exceptions to apply these policies. ++- If there is a readonly branch above the policy-selected branch and ++ the parent dir is marked as opaque (a variation of whiteout), or the ++ target (creating) file is whiteout-ed on the upper readonly branch, ++ then the result of the policy is ignored and the target file will be ++ created on the nearest upper writable branch than the readonly branch. ++- If there is a writable branch above the policy-selected branch and ++ the parent dir is marked as opaque or the target file is whiteouted ++ on the branch, then the result of the policy is ignored and the target ++ file will be created on the highest one among the upper writable ++ branches who has diropq or whiteout. In case of whiteout, aufs removes ++ it as usual. ++- link(2) and rename(2) systemcalls are exceptions in every policy. ++ They try selecting the branch where the source exists as possible ++ since copyup a large file will take long time. If it can't be, ++ ie. the branch where the source exists is readonly, then they will ++ follow the copyup policy. ++- There is an exception for rename(2) when the target exists. ++ If the rename target exists, aufs compares the index of the branches ++ where the source and the target exists and selects the higher ++ one. If the selected branch is readonly, then aufs follows the ++ copyup policy. +diff --git a/Documentation/filesystems/aufs/design/06fhsm.txt b/Documentation/filesystems/aufs/design/06fhsm.txt +new file mode 100644 +index 0000000..6cf01ae +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/06fhsm.txt +@@ -0,0 +1,105 @@ ++ ++# Copyright (C) 2011-2015 Junjiro R. Okajima ++ ++File-based Hierarchical Storage Management (FHSM) ++---------------------------------------------------------------------- ++Hierarchical Storage Management (or HSM) is a well-known feature in the ++storage world. Aufs provides this feature as file-based with multiple ++writable branches, based upon the principle of "Colder-Lower". ++Here the word "colder" means that the less used files, and "lower" means ++that the position in the order of the stacked branches. ++These multiple writable branches are prioritized, ie. the topmost one ++should be the fastest drive and be used heavily. ++ ++o Characters in aufs FHSM story ++- aufs itself and a new branch attribute. ++- a new ioctl interface to move-down and to establish a connection with ++ the daemon ("move-down" is a converse of "copy-up"). ++- userspace tool and daemon. ++ ++The userspace daemon establishes a connection with aufs and waits for ++the notification. The notified information is very similar to struct ++statfs containing the number of consumed blocks and inodes. ++When the consumed blocks/inodes of a branch exceeds the user-specified ++upper watermark, the daemon activates its move-down process until the ++consumed blocks/inodes reaches the user-specified lower watermark. ++ ++The actual move-down is done by aufs based upon the request from ++user-space since we need to maintain the inode number and the internal ++pointer arrays in aufs. ++ ++Currently aufs FHSM handles the regular files only. Additionally they ++must not be hard-linked nor pseudo-linked. ++ ++ ++o Cowork of aufs and the user-space daemon ++ During the userspace daemon established the connection, aufs sends a ++ small notification to it whenever aufs writes something into the ++ writable branch. But it may cost high since aufs issues statfs(2) ++ internally. So user can specify a new option to cache the ++ info. Actually the notification is controlled by these factors. ++ + the specified cache time. ++ + classified as "force" by aufs internally. ++ Until the specified time expires, aufs doesn't send the info ++ except the forced cases. When aufs decide forcing, the info is always ++ notified to userspace. ++ For example, the number of free inodes is generally large enough and ++ the shortage of it happens rarely. So aufs doesn't force the ++ notification when creating a new file, directory and others. This is ++ the typical case which aufs doesn't force. ++ When aufs writes the actual filedata and the files consumes any of new ++ blocks, the aufs forces notifying. ++ ++ ++o Interfaces in aufs ++- New branch attribute. ++ + fhsm ++ Specifies that the branch is managed by FHSM feature. In other word, ++ participant in the FHSM. ++ When nofhsm is set to the branch, it will not be the source/target ++ branch of the move-down operation. This attribute is set ++ independently from coo and moo attributes, and if you want full ++ FHSM, you should specify them as well. ++- New mount option. ++ + fhsm_sec ++ Specifies a second to suppress many less important info to be ++ notified. ++- New ioctl. ++ + AUFS_CTL_FHSM_FD ++ create a new file descriptor which userspace can read the notification ++ (a subset of struct statfs) from aufs. ++- Module parameter 'brs' ++ It has to be set to 1. Otherwise the new mount option 'fhsm' will not ++ be set. ++- mount helpers /sbin/mount.aufs and /sbin/umount.aufs ++ When there are two or more branches with fhsm attributes, ++ /sbin/mount.aufs invokes the user-space daemon and /sbin/umount.aufs ++ terminates it. As a result of remounting and branch-manipulation, the ++ number of branches with fhsm attribute can be one. In this case, ++ /sbin/mount.aufs will terminate the user-space daemon. ++ ++ ++Finally the operation is done as these steps in kernel-space. ++- make sure that, ++ + no one else is using the file. ++ + the file is not hard-linked. ++ + the file is not pseudo-linked. ++ + the file is a regular file. ++ + the parent dir is not opaqued. ++- find the target writable branch. ++- make sure the file is not whiteout-ed by the upper (than the target) ++ branch. ++- make the parent dir on the target branch. ++- mutex lock the inode on the branch. ++- unlink the whiteout on the target branch (if exists). ++- lookup and create the whiteout-ed temporary name on the target branch. ++- copy the file as the whiteout-ed temporary name on the target branch. ++- rename the whiteout-ed temporary name to the original name. ++- unlink the file on the source branch. ++- maintain the internal pointer array and the external inode number ++ table (XINO). ++- maintain the timestamps and other attributes of the parent dir and the ++ file. ++ ++And of course, in every step, an error may happen. So the operation ++should restore the original file state after an error happens. +diff --git a/Documentation/filesystems/aufs/design/06mmap.txt b/Documentation/filesystems/aufs/design/06mmap.txt +new file mode 100644 +index 0000000..9abea60 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/06mmap.txt +@@ -0,0 +1,33 @@ ++ ++# Copyright (C) 2005-2015 Junjiro R. Okajima ++ ++mmap(2) -- File Memory Mapping ++---------------------------------------------------------------------- ++In aufs, the file-mapped pages are handled by a branch fs directly, no ++interaction with aufs. It means aufs_mmap() calls the branch fs's ++->mmap(). ++This approach is simple and good, but there is one problem. ++Under /proc, several entries show the mmap-ped files by its path (with ++device and inode number), and the printed path will be the path on the ++branch fs's instead of virtual aufs's. ++This is not a problem in most cases, but some utilities lsof(1) (and its ++user) may expect the path on aufs. ++ ++To address this issue, aufs adds a new member called vm_prfile in struct ++vm_area_struct (and struct vm_region). The original vm_file points to ++the file on the branch fs in order to handle everything correctly as ++usual. The new vm_prfile points to a virtual file in aufs, and the ++show-functions in procfs refers to vm_prfile if it is set. ++Also we need to maintain several other places where touching vm_file ++such like ++- fork()/clone() copies vma and the reference count of vm_file is ++ incremented. ++- merging vma maintains the ref count too. ++ ++This is not a good approach. It just faking the printed path. But it ++leaves all behaviour around f_mapping unchanged. This is surely an ++advantage. ++Actually aufs had adopted another complicated approach which calls ++generic_file_mmap() and handles struct vm_operations_struct. In this ++approach, aufs met a hard problem and I could not solve it without ++switching the approach. +diff --git a/Documentation/filesystems/aufs/design/06xattr.txt b/Documentation/filesystems/aufs/design/06xattr.txt +new file mode 100644 +index 0000000..d16f822 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/06xattr.txt +@@ -0,0 +1,81 @@ ++ ++# Copyright (C) 2014-2015 Junjiro R. Okajima ++ ++Listing XATTR/EA and getting the value ++---------------------------------------------------------------------- ++For the inode standard attributes (owner, group, timestamps, etc.), aufs ++shows the values from the topmost existing file. This behaviour is good ++for the non-dir entreis since the bahaviour exactly matches the shown ++information. But for the directories, aufs considers all the same named ++entries on the lower branches. Which means, if one of the lower entry ++rejects readdir call, then aufs returns an error even if the topmost ++entry allows it. This behaviour is necessary to respect the branch fs's ++security, but can make users confused since the user-visible standard ++attributes don't match the behaviour. ++To address this issue, aufs has a mount option called dirperm1 which ++checks the permission for the topmost entry only, and ignores the lower ++entry's permission. ++ ++A similar issue can happen around XATTR. ++getxattr(2) and listxattr(2) families behave as if dirperm1 option is ++always set. Otherwise these very unpleasant situation can happen. ++- listxattr(2) may return the duplicated entires. ++- users may not be able to remove or reset the XATTR forever, ++ ++ ++XATTR/EA support in the internal (copy,move)-(up,down) ++---------------------------------------------------------------------- ++Generally the extended attributes of inode are categorazied as these. ++- "security" for LSM and capability. ++- "system" for posix ACL, 'acl' mount option is required for the branch ++ fs generally. ++- "trusted" for userspace, CAP_SYS_ADMIN is required. ++- "user" for userspace, 'user_xattr' mount option is required for the ++ branch fs generally. ++ ++Moreover there are some other categories. Aufs handles these rather ++unpopular categories as the ordinary ones, ie. there is no special ++condition nor exception. ++ ++In copy-up, the support for XATTR on the dst branch may differ from the ++src branch. In this case, the copy-up operation will get an error and ++the original user operation which triggered the copy-up fails. It can ++happen that even all copy-up will fail. ++When both of src and dst branches support XATTR and if an error occurs ++during copying XATTR, then the copy-up should fail obviously. That is a ++good reason and aufs should return an error to userspace. But when only ++the src branch support XATTR, aufs should not return an error. ++For example, the src branch supports ACL but the dst branch doesn't ++because the dst branch may natively un-support it or temporary ++un-support it due to "noacl" mount option. Of course, the dst branch fs ++may NOT return an error even if the XATTR is not supported. It is ++totally up to the branch fs. ++ ++Anyway when the aufs internal copy-up gets an error from the dst branch ++fs, then aufs tries removing the just copied entry and returns the error ++to the userspace. The worst case of this situation will be all copy-up ++will fail. ++ ++For the copy-up operation, there two basic approaches. ++- copy the specified XATTR only (by category above), and return the ++ error if it happens inconditionally. ++- copy all XATTR, and ignore the error on the specified category only. ++ ++In order to support XATTR and to implement the correct behaviour, aufs ++chooses the latter approach and introduces some attributes for its ++branch, "icexsec", "icexsys", "icextr", "icexusr", and "icexoth". ++They correspond to the XATTR namespaces (see above). Additionally, to be ++convenient, "icex" is also provided which means all "ix*" attributes are ++set. ++ ++The meaning of these attributes is to ignore the error from setting ++XATTR on that branch. ++Note that aufs tries copying all XATTR unconditionally, and ignores the ++error from the dst branch according to the specified attributes. ++ ++Some XATTR may have its default value. The default value may come from ++the parent dir or the environment. If the default value is set at the ++file creating-time, it will be overwritten by copy-up. ++Some contradiction may happen I am afraid. ++Do we need another attribute to stop copying XATTR? I am unsure. For ++now, aufs implements the branch attributes to ignore the error. +diff --git a/Documentation/filesystems/aufs/design/07export.txt b/Documentation/filesystems/aufs/design/07export.txt +new file mode 100644 +index 0000000..50744ea +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/07export.txt +@@ -0,0 +1,45 @@ ++ ++# Copyright (C) 2005-2015 Junjiro R. Okajima ++ ++Export Aufs via NFS ++---------------------------------------------------------------------- ++Here is an approach. ++- like xino/xib, add a new file 'xigen' which stores aufs inode ++ generation. ++- iget_locked(): initialize aufs inode generation for a new inode, and ++ store it in xigen file. ++- destroy_inode(): increment aufs inode generation and store it in xigen ++ file. it is necessary even if it is not unlinked, because any data of ++ inode may be changed by UDBA. ++- encode_fh(): for a root dir, simply return FILEID_ROOT. otherwise ++ build file handle by ++ + branch id (4 bytes) ++ + superblock generation (4 bytes) ++ + inode number (4 or 8 bytes) ++ + parent dir inode number (4 or 8 bytes) ++ + inode generation (4 bytes)) ++ + return value of exportfs_encode_fh() for the parent on a branch (4 ++ bytes) ++ + file handle for a branch (by exportfs_encode_fh()) ++- fh_to_dentry(): ++ + find the index of a branch from its id in handle, and check it is ++ still exist in aufs. ++ + 1st level: get the inode number from handle and search it in cache. ++ + 2nd level: if not found, get the parent inode number from handle and ++ search it in cache. and then open the parent dir, find the matching ++ inode number by vfs_readdir() and get its name, and call ++ lookup_one_len() for the target dentry. ++ + 3rd level: if the parent dir is not cached, call ++ exportfs_decode_fh() for a branch and get the parent on a branch, ++ build a pathname of it, convert it a pathname in aufs, call ++ path_lookup(). now aufs gets a parent dir dentry, then handle it as ++ the 2nd level. ++ + to open the dir, aufs needs struct vfsmount. aufs keeps vfsmount ++ for every branch, but not itself. to get this, (currently) aufs ++ searches in current->nsproxy->mnt_ns list. it may not be a good ++ idea, but I didn't get other approach. ++ + test the generation of the gotten inode. ++- every inode operation: they may get EBUSY due to UDBA. in this case, ++ convert it into ESTALE for NFSD. ++- readdir(): call lockdep_on/off() because filldir in NFSD calls ++ lookup_one_len(), vfs_getattr(), encode_fh() and others. +diff --git a/Documentation/filesystems/aufs/design/08shwh.txt b/Documentation/filesystems/aufs/design/08shwh.txt +new file mode 100644 +index 0000000..181dc02 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/08shwh.txt +@@ -0,0 +1,39 @@ ++ ++# Copyright (C) 2005-2015 Junjiro R. Okajima ++ ++Show Whiteout Mode (shwh) ++---------------------------------------------------------------------- ++Generally aufs hides the name of whiteouts. But in some cases, to show ++them is very useful for users. For instance, creating a new middle layer ++(branch) by merging existing layers. ++ ++(borrowing aufs1 HOW-TO from a user, Michael Towers) ++When you have three branches, ++- Bottom: 'system', squashfs (underlying base system), read-only ++- Middle: 'mods', squashfs, read-only ++- Top: 'overlay', ram (tmpfs), read-write ++ ++The top layer is loaded at boot time and saved at shutdown, to preserve ++the changes made to the system during the session. ++When larger changes have been made, or smaller changes have accumulated, ++the size of the saved top layer data grows. At this point, it would be ++nice to be able to merge the two overlay branches ('mods' and 'overlay') ++and rewrite the 'mods' squashfs, clearing the top layer and thus ++restoring save and load speed. ++ ++This merging is simplified by the use of another aufs mount, of just the ++two overlay branches using the 'shwh' option. ++# mount -t aufs -o ro,shwh,br:/livesys/overlay=ro+wh:/livesys/mods=rr+wh \ ++ aufs /livesys/merge_union ++ ++A merged view of these two branches is then available at ++/livesys/merge_union, and the new feature is that the whiteouts are ++visible! ++Note that in 'shwh' mode the aufs mount must be 'ro', which will disable ++writing to all branches. Also the default mode for all branches is 'ro'. ++It is now possible to save the combined contents of the two overlay ++branches to a new squashfs, e.g.: ++# mksquashfs /livesys/merge_union /path/to/newmods.squash ++ ++This new squashfs archive can be stored on the boot device and the ++initramfs will use it to replace the old one at the next boot. +diff --git a/Documentation/filesystems/aufs/design/10dynop.txt b/Documentation/filesystems/aufs/design/10dynop.txt +new file mode 100644 +index 0000000..0e40da0 +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/10dynop.txt +@@ -0,0 +1,33 @@ ++ ++# Copyright (C) 2010-2015 Junjiro R. Okajima ++ ++Dynamically customizable FS operations ++---------------------------------------------------------------------- ++Generally FS operations (struct inode_operations, struct ++address_space_operations, struct file_operations, etc.) are defined as ++"static const", but it never means that FS have only one set of ++operation. Some FS have multiple sets of them. For instance, ext2 has ++three sets, one for XIP, for NOBH, and for normal. ++Since aufs overrides and redirects these operations, sometimes aufs has ++to change its behaviour according to the branch FS type. More imporantly ++VFS acts differently if a function (member in the struct) is set or ++not. It means aufs should have several sets of operations and select one ++among them according to the branch FS definition. ++ ++In order to solve this problem and not to affect the behavour of VFS, ++aufs defines these operations dynamically. For instance, aufs defines ++aio_read function for struct file_operations, but it may not be set to ++the file_operations. When the branch FS doesn't have it, aufs doesn't ++set it to its file_operations while the function definition itself is ++still alive. So the behaviour of io_submit(2) will not change, and it ++will return an error when aio_read is not defined. ++ ++The lifetime of these dynamically generated operation object is ++maintained by aufs branch object. When the branch is removed from aufs, ++the reference counter of the object is decremented. When it reaches ++zero, the dynamically generated operation object will be freed. ++ ++This approach is designed to support AIO (io_submit), Direcit I/O and ++XIP mainly. ++Currently this approach is applied to file_operations and ++vm_operations_struct for regular files only. +diff --git a/Documentation/filesystems/aufs/design/99plan.txt b/Documentation/filesystems/aufs/design/99plan.txt +new file mode 100644 +index 0000000..73a8fae +--- /dev/null ++++ b/Documentation/filesystems/aufs/design/99plan.txt +@@ -0,0 +1,45 @@ ++ ++# Copyright (C) 2005-2015 Junjiro R. Okajima ++ ++Plan ++ ++Restoring some features which was implemented in aufs1. ++They were dropped in aufs2 in order to make source files simpler and ++easier to be reviewed. ++ ++ ++Being Another Aufs's Readonly Branch (robr) ++---------------------------------------------------------------------- ++Aufs1 allows aufs to be another aufs's readonly branch. ++This feature was developed by a user's request. But it may not be used ++currecnly. ++ ++ ++Refresh the Opened File (refrof) ++---------------------------------------------------------------------- ++This option is implemented in aufs1 but incomplete. ++ ++When user reads from a file, he expects to get its latest filedata ++generally. If the file is removed and a new same named file is created, ++the content he gets is unchanged, ie. the unlinked filedata. ++ ++Let's try case study again. ++- aufs has two branches. ++ /au = /rw + /ro ++- "fileA" exists under /ro, but /rw. ++- user opened "/au/fileA". ++- he or someone else inserts a branch (/new) between /rw and /ro. ++ /au = /rw + /new + /ro ++- the new branch has "fileA". ++- user reads from the opened "fileA" ++- which filedata should aufs return, from /ro or /new? ++ ++Some people says it has to be "from /ro" and it is a semantics of Unix. ++The others say it should be "from /new" because the file is not removed ++and it is equivalent to the case of someone else modifies the file. ++ ++Here again I don't have a best and final answer. I got an idea to ++implement 'refrof' and 'norefrof' option. When 'refrof' (REFResh the ++Opened File) is specified (by default), aufs returns the filedata from ++/new. ++Otherwise from /new. +diff --git a/MAINTAINERS b/MAINTAINERS +index d66a97d..1c113a4 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1833,6 +1833,20 @@ F: include/linux/audit.h + F: include/uapi/linux/audit.h + F: kernel/audit* + ++AUFS (advanced multi layered unification filesystem) FILESYSTEM ++M: "J. R. Okajima" ++L: linux-unionfs@vger.kernel.org ++L: aufs-users@lists.sourceforge.net (members only) ++W: http://aufs.sourceforge.net ++T: git://git.code.sf.net/p/aufs/aufs3-linux ++T: git://github.com/sfjro/aufs3-linux.git ++S: Supported ++F: Documentation/filesystems/aufs/ ++F: Documentation/ABI/testing/debugfs-aufs ++F: Documentation/ABI/testing/sysfs-aufs ++F: fs/aufs/ ++F: include/uapi/linux/aufs_type.h ++ + AUXILIARY DISPLAY DRIVERS + M: Miguel Ojeda Sandonis + W: http://miguelojeda.es/auxdisplay.htm +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 6cb1beb..30efd68 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -692,6 +692,24 @@ static inline int is_loop_device(struct file *file) + return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; + } + ++/* ++ * for AUFS ++ * no get/put for file. ++ */ ++struct file *loop_backing_file(struct super_block *sb) ++{ ++ struct file *ret; ++ struct loop_device *l; ++ ++ ret = NULL; ++ if (MAJOR(sb->s_dev) == LOOP_MAJOR) { ++ l = sb->s_bdev->bd_disk->private_data; ++ ret = l->lo_backing_file; ++ } ++ return ret; ++} ++EXPORT_SYMBOL(loop_backing_file); ++ + /* loop sysfs attributes */ + + static ssize_t loop_attr_show(struct device *dev, char *page, +diff --git a/fs/Kconfig b/fs/Kconfig +index 664991a..1481093 100644 +--- a/fs/Kconfig ++++ b/fs/Kconfig +@@ -210,6 +210,7 @@ source "fs/ufs/Kconfig" + source "fs/exofs/Kconfig" + source "fs/f2fs/Kconfig" + source "fs/efivarfs/Kconfig" ++source "fs/aufs/Kconfig" + + endif # MISC_FILESYSTEMS + +diff --git a/fs/Makefile b/fs/Makefile +index bedff48..9e7c0b7 100644 +--- a/fs/Makefile ++++ b/fs/Makefile +@@ -126,3 +126,4 @@ obj-y += exofs/ # Multiple modules + obj-$(CONFIG_CEPH_FS) += ceph/ + obj-$(CONFIG_PSTORE) += pstore/ + obj-$(CONFIG_EFIVAR_FS) += efivarfs/ ++obj-$(CONFIG_AUFS_FS) += aufs/ +diff --git a/fs/aufs/Kconfig b/fs/aufs/Kconfig +new file mode 100644 +index 0000000..a4efb8b +--- /dev/null ++++ b/fs/aufs/Kconfig +@@ -0,0 +1,185 @@ ++config AUFS_FS ++ bool "Aufs (Advanced multi layered unification filesystem) support" ++ help ++ Aufs is a stackable unification filesystem such as Unionfs, ++ which unifies several directories and provides a merged single ++ directory. ++ In the early days, aufs was entirely re-designed and ++ re-implemented Unionfs Version 1.x series. Introducing many ++ original ideas, approaches and improvements, it becomes totally ++ different from Unionfs while keeping the basic features. ++ ++if AUFS_FS ++choice ++ prompt "Maximum number of branches" ++ default AUFS_BRANCH_MAX_127 ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_127 ++ bool "127" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_511 ++ bool "511" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_1023 ++ bool "1023" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++config AUFS_BRANCH_MAX_32767 ++ bool "32767" ++ help ++ Specifies the maximum number of branches (or member directories) ++ in a single aufs. The larger value consumes more system ++ resources and has a minor impact to performance. ++endchoice ++ ++config AUFS_SBILIST ++ bool ++ depends on AUFS_MAGIC_SYSRQ || PROC_FS ++ default y ++ help ++ Automatic configuration for internal use. ++ When aufs supports Magic SysRq or /proc, enabled automatically. ++ ++config AUFS_HNOTIFY ++ bool "Detect direct branch access (bypassing aufs)" ++ help ++ If you want to modify files on branches directly, eg. bypassing aufs, ++ and want aufs to detect the changes of them fully, then enable this ++ option and use 'udba=notify' mount option. ++ Currently there is only one available configuration, "fsnotify". ++ It will have a negative impact to the performance. ++ See detail in aufs.5. ++ ++choice ++ prompt "method" if AUFS_HNOTIFY ++ default AUFS_HFSNOTIFY ++config AUFS_HFSNOTIFY ++ bool "fsnotify" ++ select FSNOTIFY ++endchoice ++ ++config AUFS_EXPORT ++ bool "NFS-exportable aufs" ++ depends on EXPORTFS = y ++ help ++ If you want to export your mounted aufs via NFS, then enable this ++ option. There are several requirements for this configuration. ++ See detail in aufs.5. ++ ++config AUFS_INO_T_64 ++ bool ++ depends on AUFS_EXPORT ++ depends on 64BIT && !(ALPHA || S390) ++ default y ++ help ++ Automatic configuration for internal use. ++ /* typedef unsigned long/int __kernel_ino_t */ ++ /* alpha and s390x are int */ ++ ++config AUFS_XATTR ++ bool "support for XATTR/EA (including Security Labels)" ++ help ++ If your branch fs supports XATTR/EA and you want to make them ++ available in aufs too, then enable this opsion and specify the ++ branch attributes for EA. ++ See detail in aufs.5. ++ ++config AUFS_FHSM ++ bool "File-based Hierarchical Storage Management" ++ help ++ Hierarchical Storage Management (or HSM) is a well-known feature ++ in the storage world. Aufs provides this feature as file-based. ++ with multiple branches. ++ These multiple branches are prioritized, ie. the topmost one ++ should be the fastest drive and be used heavily. ++ ++config AUFS_RDU ++ bool "Readdir in userspace" ++ help ++ Aufs has two methods to provide a merged view for a directory, ++ by a user-space library and by kernel-space natively. The latter ++ is always enabled but sometimes large and slow. ++ If you enable this option, install the library in aufs2-util ++ package, and set some environment variables for your readdir(3), ++ then the work will be handled in user-space which generally ++ shows better performance in most cases. ++ See detail in aufs.5. ++ ++config AUFS_SHWH ++ bool "Show whiteouts" ++ help ++ If you want to make the whiteouts in aufs visible, then enable ++ this option and specify 'shwh' mount option. Although it may ++ sounds like philosophy or something, but in technically it ++ simply shows the name of whiteout with keeping its behaviour. ++ ++config AUFS_BR_RAMFS ++ bool "Ramfs (initramfs/rootfs) as an aufs branch" ++ help ++ If you want to use ramfs as an aufs branch fs, then enable this ++ option. Generally tmpfs is recommended. ++ Aufs prohibited them to be a branch fs by default, because ++ initramfs becomes unusable after switch_root or something ++ generally. If you sets initramfs as an aufs branch and boot your ++ system by switch_root, you will meet a problem easily since the ++ files in initramfs may be inaccessible. ++ Unless you are going to use ramfs as an aufs branch fs without ++ switch_root or something, leave it N. ++ ++config AUFS_BR_FUSE ++ bool "Fuse fs as an aufs branch" ++ depends on FUSE_FS ++ select AUFS_POLL ++ help ++ If you want to use fuse-based userspace filesystem as an aufs ++ branch fs, then enable this option. ++ It implements the internal poll(2) operation which is ++ implemented by fuse only (curretnly). ++ ++config AUFS_POLL ++ bool ++ help ++ Automatic configuration for internal use. ++ ++config AUFS_BR_HFSPLUS ++ bool "Hfsplus as an aufs branch" ++ depends on HFSPLUS_FS ++ default y ++ help ++ If you want to use hfsplus fs as an aufs branch fs, then enable ++ this option. This option introduces a small overhead at ++ copying-up a file on hfsplus. ++ ++config AUFS_BDEV_LOOP ++ bool ++ depends on BLK_DEV_LOOP ++ default y ++ help ++ Automatic configuration for internal use. ++ Convert =[ym] into =y. ++ ++config AUFS_DEBUG ++ bool "Debug aufs" ++ help ++ Enable this to compile aufs internal debug code. ++ It will have a negative impact to the performance. ++ ++config AUFS_MAGIC_SYSRQ ++ bool ++ depends on AUFS_DEBUG && MAGIC_SYSRQ ++ default y ++ help ++ Automatic configuration for internal use. ++ When aufs supports Magic SysRq, enabled automatically. ++endif +diff --git a/fs/aufs/Makefile b/fs/aufs/Makefile +new file mode 100644 +index 0000000..c7efb62 +--- /dev/null ++++ b/fs/aufs/Makefile +@@ -0,0 +1,36 @@ ++ ++include ${srctree}/${src}/magic.mk ++ ++# cf. include/linux/kernel.h ++# enable pr_debug ++ccflags-y += -DDEBUG ++# sparse requires the full pathname ++ccflags-y += -include ${srctree}/include/uapi/linux/aufs_type.h ++ ++obj-$(CONFIG_AUFS_FS) += aufs.o ++aufs-y := module.o sbinfo.o super.o branch.o xino.o sysaufs.o opts.o \ ++ wkq.o vfsub.o dcsub.o \ ++ cpup.o whout.o wbr_policy.o \ ++ dinfo.o dentry.o \ ++ dynop.o \ ++ finfo.o file.o f_op.o \ ++ dir.o vdir.o \ ++ iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ ++ mvdown.o ioctl.o ++ ++# all are boolean ++aufs-$(CONFIG_PROC_FS) += procfs.o plink.o ++aufs-$(CONFIG_SYSFS) += sysfs.o ++aufs-$(CONFIG_DEBUG_FS) += dbgaufs.o ++aufs-$(CONFIG_AUFS_BDEV_LOOP) += loop.o ++aufs-$(CONFIG_AUFS_HNOTIFY) += hnotify.o ++aufs-$(CONFIG_AUFS_HFSNOTIFY) += hfsnotify.o ++aufs-$(CONFIG_AUFS_EXPORT) += export.o ++aufs-$(CONFIG_AUFS_XATTR) += xattr.o ++aufs-$(CONFIG_FS_POSIX_ACL) += posix_acl.o ++aufs-$(CONFIG_AUFS_FHSM) += fhsm.o ++aufs-$(CONFIG_AUFS_POLL) += poll.o ++aufs-$(CONFIG_AUFS_RDU) += rdu.o ++aufs-$(CONFIG_AUFS_BR_HFSPLUS) += hfsplus.o ++aufs-$(CONFIG_AUFS_DEBUG) += debug.o ++aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o +diff --git a/fs/aufs/aufs.h b/fs/aufs/aufs.h +new file mode 100644 +index 0000000..75290bd +--- /dev/null ++++ b/fs/aufs/aufs.h +@@ -0,0 +1,46 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * all header files ++ */ ++ ++#ifndef __AUFS_H__ ++#define __AUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#define AuStub(type, name, body, ...) \ ++ static inline type name(__VA_ARGS__) { body; } ++ ++#define AuStubVoid(name, ...) \ ++ AuStub(void, name, , __VA_ARGS__) ++#define AuStubInt0(name, ...) \ ++ AuStub(int, name, return 0, __VA_ARGS__) ++ ++#include "debug.h" ++ ++#include "branch.h" ++#include "cpup.h" ++#include "dcsub.h" ++#include "dbgaufs.h" ++#include "dentry.h" ++#include "dir.h" ++#include "dynop.h" ++#include "file.h" ++#include "fstype.h" ++#include "inode.h" ++#include "loop.h" ++#include "module.h" ++#include "opts.h" ++#include "rwsem.h" ++#include "spl.h" ++#include "super.h" ++#include "sysaufs.h" ++#include "vfsub.h" ++#include "whout.h" ++#include "wkq.h" ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_H__ */ +diff --git a/fs/aufs/branch.c b/fs/aufs/branch.c +new file mode 100644 +index 0000000..cf61201 +--- /dev/null ++++ b/fs/aufs/branch.c +@@ -0,0 +1,1397 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * branch management ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++/* ++ * free a single branch ++ */ ++static void au_br_do_free(struct au_branch *br) ++{ ++ int i; ++ struct au_wbr *wbr; ++ struct au_dykey **key; ++ ++ au_hnotify_fin_br(br); ++ ++ if (br->br_xino.xi_file) ++ fput(br->br_xino.xi_file); ++ mutex_destroy(&br->br_xino.xi_nondir_mtx); ++ ++ AuDebugOn(atomic_read(&br->br_count)); ++ ++ wbr = br->br_wbr; ++ if (wbr) { ++ for (i = 0; i < AuBrWh_Last; i++) ++ dput(wbr->wbr_wh[i]); ++ AuDebugOn(atomic_read(&wbr->wbr_wh_running)); ++ AuRwDestroy(&wbr->wbr_wh_rwsem); ++ } ++ ++ if (br->br_fhsm) { ++ au_br_fhsm_fin(br->br_fhsm); ++ kfree(br->br_fhsm); ++ } ++ ++ key = br->br_dykey; ++ for (i = 0; i < AuBrDynOp; i++, key++) ++ if (*key) ++ au_dy_put(*key); ++ else ++ break; ++ ++ /* recursive lock, s_umount of branch's */ ++ lockdep_off(); ++ path_put(&br->br_path); ++ lockdep_on(); ++ kfree(wbr); ++ kfree(br); ++} ++ ++/* ++ * frees all branches ++ */ ++void au_br_free(struct au_sbinfo *sbinfo) ++{ ++ aufs_bindex_t bmax; ++ struct au_branch **br; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ bmax = sbinfo->si_bend + 1; ++ br = sbinfo->si_branch; ++ while (bmax--) ++ au_br_do_free(*br++); ++} ++ ++/* ++ * find the index of a branch which is specified by @br_id. ++ */ ++int au_br_index(struct super_block *sb, aufs_bindex_t br_id) ++{ ++ aufs_bindex_t bindex, bend; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (au_sbr_id(sb, bindex) == br_id) ++ return bindex; ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * add a branch ++ */ ++ ++static int test_overlap(struct super_block *sb, struct dentry *h_adding, ++ struct dentry *h_root) ++{ ++ if (unlikely(h_adding == h_root ++ || au_test_loopback_overlap(sb, h_adding))) ++ return 1; ++ if (h_adding->d_sb != h_root->d_sb) ++ return 0; ++ return au_test_subdir(h_adding, h_root) ++ || au_test_subdir(h_root, h_adding); ++} ++ ++/* ++ * returns a newly allocated branch. @new_nbranch is a number of branches ++ * after adding a branch. ++ */ ++static struct au_branch *au_br_alloc(struct super_block *sb, int new_nbranch, ++ int perm) ++{ ++ struct au_branch *add_branch; ++ struct dentry *root; ++ int err; ++ ++ err = -ENOMEM; ++ root = sb->s_root; ++ add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS); ++ if (unlikely(!add_branch)) ++ goto out; ++ ++ err = au_hnotify_init_br(add_branch, perm); ++ if (unlikely(err)) ++ goto out_br; ++ ++ add_branch->br_wbr = NULL; ++ if (au_br_writable(perm)) { ++ /* may be freed separately at changing the branch permission */ ++ add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr), ++ GFP_NOFS); ++ if (unlikely(!add_branch->br_wbr)) ++ goto out_hnotify; ++ } ++ ++ add_branch->br_fhsm = NULL; ++ if (au_br_fhsm(perm)) { ++ err = au_fhsm_br_alloc(add_branch); ++ if (unlikely(err)) ++ goto out_wbr; ++ } ++ ++ err = au_sbr_realloc(au_sbi(sb), new_nbranch); ++ if (!err) ++ err = au_di_realloc(au_di(root), new_nbranch); ++ if (!err) ++ err = au_ii_realloc(au_ii(root->d_inode), new_nbranch); ++ if (!err) ++ return add_branch; /* success */ ++ ++out_wbr: ++ kfree(add_branch->br_wbr); ++out_hnotify: ++ au_hnotify_fin_br(add_branch); ++out_br: ++ kfree(add_branch); ++out: ++ return ERR_PTR(err); ++} ++ ++/* ++ * test if the branch permission is legal or not. ++ */ ++static int test_br(struct inode *inode, int brperm, char *path) ++{ ++ int err; ++ ++ err = (au_br_writable(brperm) && IS_RDONLY(inode)); ++ if (!err) ++ goto out; ++ ++ err = -EINVAL; ++ pr_err("write permission for readonly mount or inode, %s\n", path); ++ ++out: ++ return err; ++} ++ ++/* ++ * returns: ++ * 0: success, the caller will add it ++ * plus: success, it is already unified, the caller should ignore it ++ * minus: error ++ */ ++static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct dentry *root; ++ struct inode *inode, *h_inode; ++ ++ root = sb->s_root; ++ bend = au_sbend(sb); ++ if (unlikely(bend >= 0 ++ && au_find_dbindex(root, add->path.dentry) >= 0)) { ++ err = 1; ++ if (!remount) { ++ err = -EINVAL; ++ pr_err("%s duplicated\n", add->pathname); ++ } ++ goto out; ++ } ++ ++ err = -ENOSPC; /* -E2BIG; */ ++ if (unlikely(AUFS_BRANCH_MAX <= add->bindex ++ || AUFS_BRANCH_MAX - 1 <= bend)) { ++ pr_err("number of branches exceeded %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EDOM; ++ if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) { ++ pr_err("bad index %d\n", add->bindex); ++ goto out; ++ } ++ ++ inode = add->path.dentry->d_inode; ++ err = -ENOENT; ++ if (unlikely(!inode->i_nlink)) { ++ pr_err("no existence %s\n", add->pathname); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ if (unlikely(inode->i_sb == sb)) { ++ pr_err("%s must be outside\n", add->pathname); ++ goto out; ++ } ++ ++ if (unlikely(au_test_fs_unsuppoted(inode->i_sb))) { ++ pr_err("unsupported filesystem, %s (%s)\n", ++ add->pathname, au_sbtype(inode->i_sb)); ++ goto out; ++ } ++ ++ if (unlikely(inode->i_sb->s_stack_depth)) { ++ pr_err("already stacked, %s (%s)\n", ++ add->pathname, au_sbtype(inode->i_sb)); ++ goto out; ++ } ++ ++ err = test_br(add->path.dentry->d_inode, add->perm, add->pathname); ++ if (unlikely(err)) ++ goto out; ++ ++ if (bend < 0) ++ return 0; /* success */ ++ ++ err = -EINVAL; ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (unlikely(test_overlap(sb, add->path.dentry, ++ au_h_dptr(root, bindex)))) { ++ pr_err("%s is overlapped\n", add->pathname); ++ goto out; ++ } ++ ++ err = 0; ++ if (au_opt_test(au_mntflags(sb), WARN_PERM)) { ++ h_inode = au_h_dptr(root, 0)->d_inode; ++ if ((h_inode->i_mode & S_IALLUGO) != (inode->i_mode & S_IALLUGO) ++ || !uid_eq(h_inode->i_uid, inode->i_uid) ++ || !gid_eq(h_inode->i_gid, inode->i_gid)) ++ pr_warn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", ++ add->pathname, ++ i_uid_read(inode), i_gid_read(inode), ++ (inode->i_mode & S_IALLUGO), ++ i_uid_read(h_inode), i_gid_read(h_inode), ++ (h_inode->i_mode & S_IALLUGO)); ++ } ++ ++out: ++ return err; ++} ++ ++/* ++ * initialize or clean the whiteouts for an adding branch ++ */ ++static int au_br_init_wh(struct super_block *sb, struct au_branch *br, ++ int new_perm) ++{ ++ int err, old_perm; ++ aufs_bindex_t bindex; ++ struct mutex *h_mtx; ++ struct au_wbr *wbr; ++ struct au_hinode *hdir; ++ ++ err = vfsub_mnt_want_write(au_br_mnt(br)); ++ if (unlikely(err)) ++ goto out; ++ ++ wbr = br->br_wbr; ++ old_perm = br->br_perm; ++ br->br_perm = new_perm; ++ hdir = NULL; ++ h_mtx = NULL; ++ bindex = au_br_index(sb, br->br_id); ++ if (0 <= bindex) { ++ hdir = au_hi(sb->s_root->d_inode, bindex); ++ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ } else { ++ h_mtx = &au_br_dentry(br)->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_PARENT); ++ } ++ if (!wbr) ++ err = au_wh_init(br, sb); ++ else { ++ wbr_wh_write_lock(wbr); ++ err = au_wh_init(br, sb); ++ wbr_wh_write_unlock(wbr); ++ } ++ if (hdir) ++ au_hn_imtx_unlock(hdir); ++ else ++ mutex_unlock(h_mtx); ++ vfsub_mnt_drop_write(au_br_mnt(br)); ++ br->br_perm = old_perm; ++ ++ if (!err && wbr && !au_br_writable(new_perm)) { ++ kfree(wbr); ++ br->br_wbr = NULL; ++ } ++ ++out: ++ return err; ++} ++ ++static int au_wbr_init(struct au_branch *br, struct super_block *sb, ++ int perm) ++{ ++ int err; ++ struct kstatfs kst; ++ struct au_wbr *wbr; ++ ++ wbr = br->br_wbr; ++ au_rw_init(&wbr->wbr_wh_rwsem); ++ memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh)); ++ atomic_set(&wbr->wbr_wh_running, 0); ++ wbr->wbr_bytes = 0; ++ ++ /* ++ * a limit for rmdir/rename a dir ++ * cf. AUFS_MAX_NAMELEN in include/uapi/linux/aufs_type.h ++ */ ++ err = vfs_statfs(&br->br_path, &kst); ++ if (unlikely(err)) ++ goto out; ++ err = -EINVAL; ++ if (kst.f_namelen >= NAME_MAX) ++ err = au_br_init_wh(sb, br, perm); ++ else ++ pr_err("%pd(%s), unsupported namelen %ld\n", ++ au_br_dentry(br), ++ au_sbtype(au_br_dentry(br)->d_sb), kst.f_namelen); ++ ++out: ++ return err; ++} ++ ++/* initialize a new branch */ ++static int au_br_init(struct au_branch *br, struct super_block *sb, ++ struct au_opt_add *add) ++{ ++ int err; ++ ++ err = 0; ++ memset(&br->br_xino, 0, sizeof(br->br_xino)); ++ mutex_init(&br->br_xino.xi_nondir_mtx); ++ br->br_perm = add->perm; ++ br->br_path = add->path; /* set first, path_get() later */ ++ spin_lock_init(&br->br_dykey_lock); ++ memset(br->br_dykey, 0, sizeof(br->br_dykey)); ++ atomic_set(&br->br_count, 0); ++ atomic_set(&br->br_xino_running, 0); ++ br->br_id = au_new_br_id(sb); ++ AuDebugOn(br->br_id < 0); ++ ++ if (au_br_writable(add->perm)) { ++ err = au_wbr_init(br, sb, add->perm); ++ if (unlikely(err)) ++ goto out_err; ++ } ++ ++ if (au_opt_test(au_mntflags(sb), XINO)) { ++ err = au_xino_br(sb, br, add->path.dentry->d_inode->i_ino, ++ au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1); ++ if (unlikely(err)) { ++ AuDebugOn(br->br_xino.xi_file); ++ goto out_err; ++ } ++ } ++ ++ sysaufs_br_init(br); ++ path_get(&br->br_path); ++ goto out; /* success */ ++ ++out_err: ++ memset(&br->br_path, 0, sizeof(br->br_path)); ++out: ++ return err; ++} ++ ++static void au_br_do_add_brp(struct au_sbinfo *sbinfo, aufs_bindex_t bindex, ++ struct au_branch *br, aufs_bindex_t bend, ++ aufs_bindex_t amount) ++{ ++ struct au_branch **brp; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ brp = sbinfo->si_branch + bindex; ++ memmove(brp + 1, brp, sizeof(*brp) * amount); ++ *brp = br; ++ sbinfo->si_bend++; ++ if (unlikely(bend < 0)) ++ sbinfo->si_bend = 0; ++} ++ ++static void au_br_do_add_hdp(struct au_dinfo *dinfo, aufs_bindex_t bindex, ++ aufs_bindex_t bend, aufs_bindex_t amount) ++{ ++ struct au_hdentry *hdp; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ hdp = dinfo->di_hdentry + bindex; ++ memmove(hdp + 1, hdp, sizeof(*hdp) * amount); ++ au_h_dentry_init(hdp); ++ dinfo->di_bend++; ++ if (unlikely(bend < 0)) ++ dinfo->di_bstart = 0; ++} ++ ++static void au_br_do_add_hip(struct au_iinfo *iinfo, aufs_bindex_t bindex, ++ aufs_bindex_t bend, aufs_bindex_t amount) ++{ ++ struct au_hinode *hip; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ hip = iinfo->ii_hinode + bindex; ++ memmove(hip + 1, hip, sizeof(*hip) * amount); ++ hip->hi_inode = NULL; ++ au_hn_init(hip); ++ iinfo->ii_bend++; ++ if (unlikely(bend < 0)) ++ iinfo->ii_bstart = 0; ++} ++ ++static void au_br_do_add(struct super_block *sb, struct au_branch *br, ++ aufs_bindex_t bindex) ++{ ++ struct dentry *root, *h_dentry; ++ struct inode *root_inode; ++ aufs_bindex_t bend, amount; ++ ++ root = sb->s_root; ++ root_inode = root->d_inode; ++ bend = au_sbend(sb); ++ amount = bend + 1 - bindex; ++ h_dentry = au_br_dentry(br); ++ au_sbilist_lock(); ++ au_br_do_add_brp(au_sbi(sb), bindex, br, bend, amount); ++ au_br_do_add_hdp(au_di(root), bindex, bend, amount); ++ au_br_do_add_hip(au_ii(root_inode), bindex, bend, amount); ++ au_set_h_dptr(root, bindex, dget(h_dentry)); ++ au_set_h_iptr(root_inode, bindex, au_igrab(h_dentry->d_inode), ++ /*flags*/0); ++ au_sbilist_unlock(); ++} ++ ++int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount) ++{ ++ int err; ++ aufs_bindex_t bend, add_bindex; ++ struct dentry *root, *h_dentry; ++ struct inode *root_inode; ++ struct au_branch *add_branch; ++ ++ root = sb->s_root; ++ root_inode = root->d_inode; ++ IMustLock(root_inode); ++ err = test_add(sb, add, remount); ++ if (unlikely(err < 0)) ++ goto out; ++ if (err) { ++ err = 0; ++ goto out; /* success */ ++ } ++ ++ bend = au_sbend(sb); ++ add_branch = au_br_alloc(sb, bend + 2, add->perm); ++ err = PTR_ERR(add_branch); ++ if (IS_ERR(add_branch)) ++ goto out; ++ ++ err = au_br_init(add_branch, sb, add); ++ if (unlikely(err)) { ++ au_br_do_free(add_branch); ++ goto out; ++ } ++ ++ add_bindex = add->bindex; ++ if (!remount) ++ au_br_do_add(sb, add_branch, add_bindex); ++ else { ++ sysaufs_brs_del(sb, add_bindex); ++ au_br_do_add(sb, add_branch, add_bindex); ++ sysaufs_brs_add(sb, add_bindex); ++ } ++ ++ h_dentry = add->path.dentry; ++ if (!add_bindex) { ++ au_cpup_attr_all(root_inode, /*force*/1); ++ sb->s_maxbytes = h_dentry->d_sb->s_maxbytes; ++ } else ++ au_add_nlink(root_inode, h_dentry->d_inode); ++ ++ /* ++ * this test/set prevents aufs from handling unnecesary notify events ++ * of xino files, in case of re-adding a writable branch which was ++ * once detached from aufs. ++ */ ++ if (au_xino_brid(sb) < 0 ++ && au_br_writable(add_branch->br_perm) ++ && !au_test_fs_bad_xino(h_dentry->d_sb) ++ && add_branch->br_xino.xi_file ++ && add_branch->br_xino.xi_file->f_path.dentry->d_parent == h_dentry) ++ au_xino_brid_set(sb, add_branch->br_id); ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static unsigned long long au_farray_cb(void *a, ++ unsigned long long max __maybe_unused, ++ void *arg) ++{ ++ unsigned long long n; ++ struct file **p, *f; ++ struct au_sphlhead *files; ++ struct au_finfo *finfo; ++ struct super_block *sb = arg; ++ ++ n = 0; ++ p = a; ++ files = &au_sbi(sb)->si_files; ++ spin_lock(&files->spin); ++ hlist_for_each_entry(finfo, &files->head, fi_hlist) { ++ f = finfo->fi_file; ++ if (file_count(f) ++ && !special_file(file_inode(f)->i_mode)) { ++ get_file(f); ++ *p++ = f; ++ n++; ++ AuDebugOn(n > max); ++ } ++ } ++ spin_unlock(&files->spin); ++ ++ return n; ++} ++ ++static struct file **au_farray_alloc(struct super_block *sb, ++ unsigned long long *max) ++{ ++ *max = atomic_long_read(&au_sbi(sb)->si_nfiles); ++ return au_array_alloc(max, au_farray_cb, sb); ++} ++ ++static void au_farray_free(struct file **a, unsigned long long max) ++{ ++ unsigned long long ull; ++ ++ for (ull = 0; ull < max; ull++) ++ if (a[ull]) ++ fput(a[ull]); ++ au_array_free(a); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * delete a branch ++ */ ++ ++/* to show the line number, do not make it inlined function */ ++#define AuVerbose(do_info, fmt, ...) do { \ ++ if (do_info) \ ++ pr_info(fmt, ##__VA_ARGS__); \ ++} while (0) ++ ++static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart, ++ aufs_bindex_t bend) ++{ ++ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend; ++} ++ ++static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart, ++ aufs_bindex_t bend) ++{ ++ return au_test_ibusy(dentry->d_inode, bstart, bend); ++} ++ ++/* ++ * test if the branch is deletable or not. ++ */ ++static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex, ++ unsigned int sigen, const unsigned int verbose) ++{ ++ int err, i, j, ndentry; ++ aufs_bindex_t bstart, bend; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry *d; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, root, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ for (i = 0; !err && i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ ndentry = dpage->ndentry; ++ for (j = 0; !err && j < ndentry; j++) { ++ d = dpage->dentries[j]; ++ AuDebugOn(au_dcount(d) <= 0); ++ if (!au_digen_test(d, sigen)) { ++ di_read_lock_child(d, AuLock_IR); ++ if (unlikely(au_dbrange_test(d))) { ++ di_read_unlock(d, AuLock_IR); ++ continue; ++ } ++ } else { ++ di_write_lock_child(d); ++ if (unlikely(au_dbrange_test(d))) { ++ di_write_unlock(d); ++ continue; ++ } ++ err = au_reval_dpath(d, sigen); ++ if (!err) ++ di_downgrade_lock(d, AuLock_IR); ++ else { ++ di_write_unlock(d); ++ break; ++ } ++ } ++ ++ /* AuDbgDentry(d); */ ++ bstart = au_dbstart(d); ++ bend = au_dbend(d); ++ if (bstart <= bindex ++ && bindex <= bend ++ && au_h_dptr(d, bindex) ++ && au_test_dbusy(d, bstart, bend)) { ++ err = -EBUSY; ++ AuVerbose(verbose, "busy %pd\n", d); ++ AuDbgDentry(d); ++ } ++ di_read_unlock(d, AuLock_IR); ++ } ++ } ++ ++out_dpages: ++ au_dpages_free(&dpages); ++out: ++ return err; ++} ++ ++static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex, ++ unsigned int sigen, const unsigned int verbose) ++{ ++ int err; ++ unsigned long long max, ull; ++ struct inode *i, **array; ++ aufs_bindex_t bstart, bend; ++ ++ array = au_iarray_alloc(sb, &max); ++ err = PTR_ERR(array); ++ if (IS_ERR(array)) ++ goto out; ++ ++ err = 0; ++ AuDbg("b%d\n", bindex); ++ for (ull = 0; !err && ull < max; ull++) { ++ i = array[ull]; ++ if (unlikely(!i)) ++ break; ++ if (i->i_ino == AUFS_ROOT_INO) ++ continue; ++ ++ /* AuDbgInode(i); */ ++ if (au_iigen(i, NULL) == sigen) ++ ii_read_lock_child(i); ++ else { ++ ii_write_lock_child(i); ++ err = au_refresh_hinode_self(i); ++ au_iigen_dec(i); ++ if (!err) ++ ii_downgrade_lock(i); ++ else { ++ ii_write_unlock(i); ++ break; ++ } ++ } ++ ++ bstart = au_ibstart(i); ++ bend = au_ibend(i); ++ if (bstart <= bindex ++ && bindex <= bend ++ && au_h_iptr(i, bindex) ++ && au_test_ibusy(i, bstart, bend)) { ++ err = -EBUSY; ++ AuVerbose(verbose, "busy i%lu\n", i->i_ino); ++ AuDbgInode(i); ++ } ++ ii_read_unlock(i); ++ } ++ au_iarray_free(array, max); ++ ++out: ++ return err; ++} ++ ++static int test_children_busy(struct dentry *root, aufs_bindex_t bindex, ++ const unsigned int verbose) ++{ ++ int err; ++ unsigned int sigen; ++ ++ sigen = au_sigen(root->d_sb); ++ DiMustNoWaiters(root); ++ IiMustNoWaiters(root->d_inode); ++ di_write_unlock(root); ++ err = test_dentry_busy(root, bindex, sigen, verbose); ++ if (!err) ++ err = test_inode_busy(root->d_sb, bindex, sigen, verbose); ++ di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */ ++ ++ return err; ++} ++ ++static int test_dir_busy(struct file *file, aufs_bindex_t br_id, ++ struct file **to_free, int *idx) ++{ ++ int err; ++ unsigned char matched, root; ++ aufs_bindex_t bindex, bend; ++ struct au_fidir *fidir; ++ struct au_hfile *hfile; ++ ++ err = 0; ++ root = IS_ROOT(file->f_path.dentry); ++ if (root) { ++ get_file(file); ++ to_free[*idx] = file; ++ (*idx)++; ++ goto out; ++ } ++ ++ matched = 0; ++ fidir = au_fi(file)->fi_hdir; ++ AuDebugOn(!fidir); ++ bend = au_fbend_dir(file); ++ for (bindex = au_fbstart(file); bindex <= bend; bindex++) { ++ hfile = fidir->fd_hfile + bindex; ++ if (!hfile->hf_file) ++ continue; ++ ++ if (hfile->hf_br->br_id == br_id) { ++ matched = 1; ++ break; ++ } ++ } ++ if (matched) ++ err = -EBUSY; ++ ++out: ++ return err; ++} ++ ++static int test_file_busy(struct super_block *sb, aufs_bindex_t br_id, ++ struct file **to_free, int opened) ++{ ++ int err, idx; ++ unsigned long long ull, max; ++ aufs_bindex_t bstart; ++ struct file *file, **array; ++ struct inode *inode; ++ struct dentry *root; ++ struct au_hfile *hfile; ++ ++ array = au_farray_alloc(sb, &max); ++ err = PTR_ERR(array); ++ if (IS_ERR(array)) ++ goto out; ++ ++ err = 0; ++ idx = 0; ++ root = sb->s_root; ++ di_write_unlock(root); ++ for (ull = 0; ull < max; ull++) { ++ file = array[ull]; ++ if (unlikely(!file)) ++ break; ++ ++ /* AuDbg("%pD\n", file); */ ++ fi_read_lock(file); ++ bstart = au_fbstart(file); ++ inode = file_inode(file); ++ if (!S_ISDIR(inode->i_mode)) { ++ hfile = &au_fi(file)->fi_htop; ++ if (hfile->hf_br->br_id == br_id) ++ err = -EBUSY; ++ } else ++ err = test_dir_busy(file, br_id, to_free, &idx); ++ fi_read_unlock(file); ++ if (unlikely(err)) ++ break; ++ } ++ di_write_lock_child(root); ++ au_farray_free(array, max); ++ AuDebugOn(idx > opened); ++ ++out: ++ return err; ++} ++ ++static void br_del_file(struct file **to_free, unsigned long long opened, ++ aufs_bindex_t br_id) ++{ ++ unsigned long long ull; ++ aufs_bindex_t bindex, bstart, bend, bfound; ++ struct file *file; ++ struct au_fidir *fidir; ++ struct au_hfile *hfile; ++ ++ for (ull = 0; ull < opened; ull++) { ++ file = to_free[ull]; ++ if (unlikely(!file)) ++ break; ++ ++ /* AuDbg("%pD\n", file); */ ++ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode)); ++ bfound = -1; ++ fidir = au_fi(file)->fi_hdir; ++ AuDebugOn(!fidir); ++ fi_write_lock(file); ++ bstart = au_fbstart(file); ++ bend = au_fbend_dir(file); ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ hfile = fidir->fd_hfile + bindex; ++ if (!hfile->hf_file) ++ continue; ++ ++ if (hfile->hf_br->br_id == br_id) { ++ bfound = bindex; ++ break; ++ } ++ } ++ AuDebugOn(bfound < 0); ++ au_set_h_fptr(file, bfound, NULL); ++ if (bfound == bstart) { ++ for (bstart++; bstart <= bend; bstart++) ++ if (au_hf_dir(file, bstart)) { ++ au_set_fbstart(file, bstart); ++ break; ++ } ++ } ++ fi_write_unlock(file); ++ } ++} ++ ++static void au_br_do_del_brp(struct au_sbinfo *sbinfo, ++ const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_branch **brp, **p; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ brp = sbinfo->si_branch + bindex; ++ if (bindex < bend) ++ memmove(brp, brp + 1, sizeof(*brp) * (bend - bindex)); ++ sbinfo->si_branch[0 + bend] = NULL; ++ sbinfo->si_bend--; ++ ++ p = krealloc(sbinfo->si_branch, sizeof(*p) * bend, AuGFP_SBILIST); ++ if (p) ++ sbinfo->si_branch = p; ++ /* harmless error */ ++} ++ ++static void au_br_do_del_hdp(struct au_dinfo *dinfo, const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_hdentry *hdp, *p; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ hdp = dinfo->di_hdentry; ++ if (bindex < bend) ++ memmove(hdp + bindex, hdp + bindex + 1, ++ sizeof(*hdp) * (bend - bindex)); ++ hdp[0 + bend].hd_dentry = NULL; ++ dinfo->di_bend--; ++ ++ p = krealloc(hdp, sizeof(*p) * bend, AuGFP_SBILIST); ++ if (p) ++ dinfo->di_hdentry = p; ++ /* harmless error */ ++} ++ ++static void au_br_do_del_hip(struct au_iinfo *iinfo, const aufs_bindex_t bindex, ++ const aufs_bindex_t bend) ++{ ++ struct au_hinode *hip, *p; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ hip = iinfo->ii_hinode + bindex; ++ if (bindex < bend) ++ memmove(hip, hip + 1, sizeof(*hip) * (bend - bindex)); ++ iinfo->ii_hinode[0 + bend].hi_inode = NULL; ++ au_hn_init(iinfo->ii_hinode + bend); ++ iinfo->ii_bend--; ++ ++ p = krealloc(iinfo->ii_hinode, sizeof(*p) * bend, AuGFP_SBILIST); ++ if (p) ++ iinfo->ii_hinode = p; ++ /* harmless error */ ++} ++ ++static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_branch *br) ++{ ++ aufs_bindex_t bend; ++ struct au_sbinfo *sbinfo; ++ struct dentry *root, *h_root; ++ struct inode *inode, *h_inode; ++ struct au_hinode *hinode; ++ ++ SiMustWriteLock(sb); ++ ++ root = sb->s_root; ++ inode = root->d_inode; ++ sbinfo = au_sbi(sb); ++ bend = sbinfo->si_bend; ++ ++ h_root = au_h_dptr(root, bindex); ++ hinode = au_hi(inode, bindex); ++ h_inode = au_igrab(hinode->hi_inode); ++ au_hiput(hinode); ++ ++ au_sbilist_lock(); ++ au_br_do_del_brp(sbinfo, bindex, bend); ++ au_br_do_del_hdp(au_di(root), bindex, bend); ++ au_br_do_del_hip(au_ii(inode), bindex, bend); ++ au_sbilist_unlock(); ++ ++ dput(h_root); ++ iput(h_inode); ++ au_br_do_free(br); ++} ++ ++static unsigned long long empty_cb(void *array, unsigned long long max, ++ void *arg) ++{ ++ return max; ++} ++ ++int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount) ++{ ++ int err, rerr, i; ++ unsigned long long opened; ++ unsigned int mnt_flags; ++ aufs_bindex_t bindex, bend, br_id; ++ unsigned char do_wh, verbose; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ struct dentry *root; ++ struct file **to_free; ++ ++ err = 0; ++ opened = 0; ++ to_free = NULL; ++ root = sb->s_root; ++ bindex = au_find_dbindex(root, del->h_path.dentry); ++ if (bindex < 0) { ++ if (remount) ++ goto out; /* success */ ++ err = -ENOENT; ++ pr_err("%s no such branch\n", del->pathname); ++ goto out; ++ } ++ AuDbg("bindex b%d\n", bindex); ++ ++ err = -EBUSY; ++ mnt_flags = au_mntflags(sb); ++ verbose = !!au_opt_test(mnt_flags, VERBOSE); ++ bend = au_sbend(sb); ++ if (unlikely(!bend)) { ++ AuVerbose(verbose, "no more branches left\n"); ++ goto out; ++ } ++ br = au_sbr(sb, bindex); ++ AuDebugOn(!path_equal(&br->br_path, &del->h_path)); ++ ++ br_id = br->br_id; ++ opened = atomic_read(&br->br_count); ++ if (unlikely(opened)) { ++ to_free = au_array_alloc(&opened, empty_cb, NULL); ++ err = PTR_ERR(to_free); ++ if (IS_ERR(to_free)) ++ goto out; ++ ++ err = test_file_busy(sb, br_id, to_free, opened); ++ if (unlikely(err)) { ++ AuVerbose(verbose, "%llu file(s) opened\n", opened); ++ goto out; ++ } ++ } ++ ++ wbr = br->br_wbr; ++ do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_orph); ++ if (do_wh) { ++ /* instead of WbrWhMustWriteLock(wbr) */ ++ SiMustWriteLock(sb); ++ for (i = 0; i < AuBrWh_Last; i++) { ++ dput(wbr->wbr_wh[i]); ++ wbr->wbr_wh[i] = NULL; ++ } ++ } ++ ++ err = test_children_busy(root, bindex, verbose); ++ if (unlikely(err)) { ++ if (do_wh) ++ goto out_wh; ++ goto out; ++ } ++ ++ err = 0; ++ if (to_free) { ++ /* ++ * now we confirmed the branch is deletable. ++ * let's free the remaining opened dirs on the branch. ++ */ ++ di_write_unlock(root); ++ br_del_file(to_free, opened, br_id); ++ di_write_lock_child(root); ++ } ++ ++ if (!remount) ++ au_br_do_del(sb, bindex, br); ++ else { ++ sysaufs_brs_del(sb, bindex); ++ au_br_do_del(sb, bindex, br); ++ sysaufs_brs_add(sb, bindex); ++ } ++ ++ if (!bindex) { ++ au_cpup_attr_all(root->d_inode, /*force*/1); ++ sb->s_maxbytes = au_sbr_sb(sb, 0)->s_maxbytes; ++ } else ++ au_sub_nlink(root->d_inode, del->h_path.dentry->d_inode); ++ if (au_opt_test(mnt_flags, PLINK)) ++ au_plink_half_refresh(sb, br_id); ++ ++ if (au_xino_brid(sb) == br_id) ++ au_xino_brid_set(sb, -1); ++ goto out; /* success */ ++ ++out_wh: ++ /* revert */ ++ rerr = au_br_init_wh(sb, br, br->br_perm); ++ if (rerr) ++ pr_warn("failed re-creating base whiteout, %s. (%d)\n", ++ del->pathname, rerr); ++out: ++ if (to_free) ++ au_farray_free(to_free, opened); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg) ++{ ++ int err; ++ aufs_bindex_t bstart, bend; ++ struct aufs_ibusy ibusy; ++ struct inode *inode, *h_inode; ++ ++ err = -EPERM; ++ if (unlikely(!capable(CAP_SYS_ADMIN))) ++ goto out; ++ ++ err = copy_from_user(&ibusy, arg, sizeof(ibusy)); ++ if (!err) ++ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ si_read_lock(sb, AuLock_FLUSH); ++ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb))) ++ goto out_unlock; ++ ++ err = 0; ++ ibusy.h_ino = 0; /* invalid */ ++ inode = ilookup(sb, ibusy.ino); ++ if (!inode ++ || inode->i_ino == AUFS_ROOT_INO ++ || is_bad_inode(inode)) ++ goto out_unlock; ++ ++ ii_read_lock_child(inode); ++ bstart = au_ibstart(inode); ++ bend = au_ibend(inode); ++ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) { ++ h_inode = au_h_iptr(inode, ibusy.bindex); ++ if (h_inode && au_test_ibusy(inode, bstart, bend)) ++ ibusy.h_ino = h_inode->i_ino; ++ } ++ ii_read_unlock(inode); ++ iput(inode); ++ ++out_unlock: ++ si_read_unlock(sb); ++ if (!err) { ++ err = __put_user(ibusy.h_ino, &arg->h_ino); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ } ++ } ++out: ++ return err; ++} ++ ++long au_ibusy_ioctl(struct file *file, unsigned long arg) ++{ ++ return au_ibusy(file->f_path.dentry->d_sb, (void __user *)arg); ++} ++ ++#ifdef CONFIG_COMPAT ++long au_ibusy_compat_ioctl(struct file *file, unsigned long arg) ++{ ++ return au_ibusy(file->f_path.dentry->d_sb, compat_ptr(arg)); ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * change a branch permission ++ */ ++ ++static void au_warn_ima(void) ++{ ++#ifdef CONFIG_IMA ++ /* since it doesn't support mark_files_ro() */ ++ AuWarn1("RW -> RO makes IMA to produce wrong message\n"); ++#endif ++} ++ ++static int do_need_sigen_inc(int a, int b) ++{ ++ return au_br_whable(a) && !au_br_whable(b); ++} ++ ++static int need_sigen_inc(int old, int new) ++{ ++ return do_need_sigen_inc(old, new) ++ || do_need_sigen_inc(new, old); ++} ++ ++static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err, do_warn; ++ unsigned int mnt_flags; ++ unsigned long long ull, max; ++ aufs_bindex_t br_id; ++ unsigned char verbose, writer; ++ struct file *file, *hf, **array; ++ struct inode *inode; ++ struct au_hfile *hfile; ++ ++ mnt_flags = au_mntflags(sb); ++ verbose = !!au_opt_test(mnt_flags, VERBOSE); ++ ++ array = au_farray_alloc(sb, &max); ++ err = PTR_ERR(array); ++ if (IS_ERR(array)) ++ goto out; ++ ++ do_warn = 0; ++ br_id = au_sbr_id(sb, bindex); ++ for (ull = 0; ull < max; ull++) { ++ file = array[ull]; ++ if (unlikely(!file)) ++ break; ++ ++ /* AuDbg("%pD\n", file); */ ++ fi_read_lock(file); ++ if (unlikely(au_test_mmapped(file))) { ++ err = -EBUSY; ++ AuVerbose(verbose, "mmapped %pD\n", file); ++ AuDbgFile(file); ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ goto out_array; ++ } ++ ++ inode = file_inode(file); ++ hfile = &au_fi(file)->fi_htop; ++ hf = hfile->hf_file; ++ if (!S_ISREG(inode->i_mode) ++ || !(file->f_mode & FMODE_WRITE) ++ || hfile->hf_br->br_id != br_id ++ || !(hf->f_mode & FMODE_WRITE)) ++ array[ull] = NULL; ++ else { ++ do_warn = 1; ++ get_file(file); ++ } ++ ++ FiMustNoWaiters(file); ++ fi_read_unlock(file); ++ fput(file); ++ } ++ ++ err = 0; ++ if (do_warn) ++ au_warn_ima(); ++ ++ for (ull = 0; ull < max; ull++) { ++ file = array[ull]; ++ if (!file) ++ continue; ++ ++ /* todo: already flushed? */ ++ /* ++ * fs/super.c:mark_files_ro() is gone, but aufs keeps its ++ * approach which resets f_mode and calls mnt_drop_write() and ++ * file_release_write() for each file, because the branch ++ * attribute in aufs world is totally different from the native ++ * fs rw/ro mode. ++ */ ++ /* fi_read_lock(file); */ ++ hfile = &au_fi(file)->fi_htop; ++ hf = hfile->hf_file; ++ /* fi_read_unlock(file); */ ++ spin_lock(&hf->f_lock); ++ writer = !!(hf->f_mode & FMODE_WRITER); ++ hf->f_mode &= ~(FMODE_WRITE | FMODE_WRITER); ++ spin_unlock(&hf->f_lock); ++ if (writer) { ++ put_write_access(file_inode(hf)); ++ __mnt_drop_write(hf->f_path.mnt); ++ } ++ } ++ ++out_array: ++ au_farray_free(array, max); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, ++ int *do_refresh) ++{ ++ int err, rerr; ++ aufs_bindex_t bindex; ++ struct dentry *root; ++ struct au_branch *br; ++ struct au_br_fhsm *bf; ++ ++ root = sb->s_root; ++ bindex = au_find_dbindex(root, mod->h_root); ++ if (bindex < 0) { ++ if (remount) ++ return 0; /* success */ ++ err = -ENOENT; ++ pr_err("%s no such branch\n", mod->path); ++ goto out; ++ } ++ AuDbg("bindex b%d\n", bindex); ++ ++ err = test_br(mod->h_root->d_inode, mod->perm, mod->path); ++ if (unlikely(err)) ++ goto out; ++ ++ br = au_sbr(sb, bindex); ++ AuDebugOn(mod->h_root != au_br_dentry(br)); ++ if (br->br_perm == mod->perm) ++ return 0; /* success */ ++ ++ /* pre-allocate for non-fhsm --> fhsm */ ++ bf = NULL; ++ if (!au_br_fhsm(br->br_perm) && au_br_fhsm(mod->perm)) { ++ err = au_fhsm_br_alloc(br); ++ if (unlikely(err)) ++ goto out; ++ bf = br->br_fhsm; ++ br->br_fhsm = NULL; ++ } ++ ++ if (au_br_writable(br->br_perm)) { ++ /* remove whiteout base */ ++ err = au_br_init_wh(sb, br, mod->perm); ++ if (unlikely(err)) ++ goto out_bf; ++ ++ if (!au_br_writable(mod->perm)) { ++ /* rw --> ro, file might be mmapped */ ++ DiMustNoWaiters(root); ++ IiMustNoWaiters(root->d_inode); ++ di_write_unlock(root); ++ err = au_br_mod_files_ro(sb, bindex); ++ /* aufs_write_lock() calls ..._child() */ ++ di_write_lock_child(root); ++ ++ if (unlikely(err)) { ++ rerr = -ENOMEM; ++ br->br_wbr = kmalloc(sizeof(*br->br_wbr), ++ GFP_NOFS); ++ if (br->br_wbr) ++ rerr = au_wbr_init(br, sb, br->br_perm); ++ if (unlikely(rerr)) { ++ AuIOErr("nested error %d (%d)\n", ++ rerr, err); ++ br->br_perm = mod->perm; ++ } ++ } ++ } ++ } else if (au_br_writable(mod->perm)) { ++ /* ro --> rw */ ++ err = -ENOMEM; ++ br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS); ++ if (br->br_wbr) { ++ err = au_wbr_init(br, sb, mod->perm); ++ if (unlikely(err)) { ++ kfree(br->br_wbr); ++ br->br_wbr = NULL; ++ } ++ } ++ } ++ if (unlikely(err)) ++ goto out_bf; ++ ++ if (au_br_fhsm(br->br_perm)) { ++ if (!au_br_fhsm(mod->perm)) { ++ /* fhsm --> non-fhsm */ ++ au_br_fhsm_fin(br->br_fhsm); ++ kfree(br->br_fhsm); ++ br->br_fhsm = NULL; ++ } ++ } else if (au_br_fhsm(mod->perm)) ++ /* non-fhsm --> fhsm */ ++ br->br_fhsm = bf; ++ ++ *do_refresh |= need_sigen_inc(br->br_perm, mod->perm); ++ br->br_perm = mod->perm; ++ goto out; /* success */ ++ ++out_bf: ++ kfree(bf); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs) ++{ ++ int err; ++ struct kstatfs kstfs; ++ ++ err = vfs_statfs(&br->br_path, &kstfs); ++ if (!err) { ++ stfs->f_blocks = kstfs.f_blocks; ++ stfs->f_bavail = kstfs.f_bavail; ++ stfs->f_files = kstfs.f_files; ++ stfs->f_ffree = kstfs.f_ffree; ++ } ++ ++ return err; ++} +diff --git a/fs/aufs/branch.h b/fs/aufs/branch.h +new file mode 100644 +index 0000000..61f5ca1 +--- /dev/null ++++ b/fs/aufs/branch.h +@@ -0,0 +1,254 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * branch filesystems and xino for them ++ */ ++ ++#ifndef __AUFS_BRANCH_H__ ++#define __AUFS_BRANCH_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include "dynop.h" ++#include "rwsem.h" ++#include "super.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* a xino file */ ++struct au_xino_file { ++ struct file *xi_file; ++ struct mutex xi_nondir_mtx; ++ ++ /* todo: make xino files an array to support huge inode number */ ++ ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *xi_dbgaufs; ++#endif ++}; ++ ++/* File-based Hierarchical Storage Management */ ++struct au_br_fhsm { ++#ifdef CONFIG_AUFS_FHSM ++ struct mutex bf_lock; ++ unsigned long bf_jiffy; ++ struct aufs_stfs bf_stfs; ++ int bf_readable; ++#endif ++}; ++ ++/* members for writable branch only */ ++enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_ORPH, AuBrWh_Last}; ++struct au_wbr { ++ struct au_rwsem wbr_wh_rwsem; ++ struct dentry *wbr_wh[AuBrWh_Last]; ++ atomic_t wbr_wh_running; ++#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */ ++#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */ ++#define wbr_orph wbr_wh[AuBrWh_ORPH] /* dir for orphans */ ++ ++ /* mfs mode */ ++ unsigned long long wbr_bytes; ++}; ++ ++/* ext2 has 3 types of operations at least, ext3 has 4 */ ++#define AuBrDynOp (AuDyLast * 4) ++ ++#ifdef CONFIG_AUFS_HFSNOTIFY ++/* support for asynchronous destruction */ ++struct au_br_hfsnotify { ++ struct fsnotify_group *hfsn_group; ++}; ++#endif ++ ++/* sysfs entries */ ++struct au_brsysfs { ++ char name[16]; ++ struct attribute attr; ++}; ++ ++enum { ++ AuBrSysfs_BR, ++ AuBrSysfs_BRID, ++ AuBrSysfs_Last ++}; ++ ++/* protected by superblock rwsem */ ++struct au_branch { ++ struct au_xino_file br_xino; ++ ++ aufs_bindex_t br_id; ++ ++ int br_perm; ++ struct path br_path; ++ spinlock_t br_dykey_lock; ++ struct au_dykey *br_dykey[AuBrDynOp]; ++ atomic_t br_count; ++ ++ struct au_wbr *br_wbr; ++ struct au_br_fhsm *br_fhsm; ++ ++ /* xino truncation */ ++ atomic_t br_xino_running; ++ ++#ifdef CONFIG_AUFS_HFSNOTIFY ++ struct au_br_hfsnotify *br_hfsn; ++#endif ++ ++#ifdef CONFIG_SYSFS ++ /* entries under sysfs per mount-point */ ++ struct au_brsysfs br_sysfs[AuBrSysfs_Last]; ++#endif ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct vfsmount *au_br_mnt(struct au_branch *br) ++{ ++ return br->br_path.mnt; ++} ++ ++static inline struct dentry *au_br_dentry(struct au_branch *br) ++{ ++ return br->br_path.dentry; ++} ++ ++static inline struct super_block *au_br_sb(struct au_branch *br) ++{ ++ return au_br_mnt(br)->mnt_sb; ++} ++ ++static inline int au_br_rdonly(struct au_branch *br) ++{ ++ return ((au_br_sb(br)->s_flags & MS_RDONLY) ++ || !au_br_writable(br->br_perm)) ++ ? -EROFS : 0; ++} ++ ++static inline int au_br_hnotifyable(int brperm __maybe_unused) ++{ ++#ifdef CONFIG_AUFS_HNOTIFY ++ return !(brperm & AuBrPerm_RR); ++#else ++ return 0; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* branch.c */ ++struct au_sbinfo; ++void au_br_free(struct au_sbinfo *sinfo); ++int au_br_index(struct super_block *sb, aufs_bindex_t br_id); ++struct au_opt_add; ++int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); ++struct au_opt_del; ++int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); ++long au_ibusy_ioctl(struct file *file, unsigned long arg); ++#ifdef CONFIG_COMPAT ++long au_ibusy_compat_ioctl(struct file *file, unsigned long arg); ++#endif ++struct au_opt_mod; ++int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, ++ int *do_refresh); ++struct aufs_stfs; ++int au_br_stfs(struct au_branch *br, struct aufs_stfs *stfs); ++ ++/* xino.c */ ++static const loff_t au_loff_max = LLONG_MAX; ++ ++int au_xib_trunc(struct super_block *sb); ++ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos); ++ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos); ++struct file *au_xino_create2(struct file *base_file, struct file *copy_src); ++struct file *au_xino_create(struct super_block *sb, char *fname, int silent); ++ino_t au_xino_new_ino(struct super_block *sb); ++void au_xino_delete_inode(struct inode *inode, const int unlinked); ++int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino); ++int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t *ino); ++int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino, ++ struct file *base_file, int do_test); ++int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex); ++ ++struct au_opt_xino; ++int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount); ++void au_xino_clr(struct super_block *sb); ++struct file *au_xino_def(struct super_block *sb); ++int au_xino_path(struct seq_file *seq, struct file *file); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Superblock to branch */ ++static inline ++aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_id; ++} ++ ++static inline ++struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_br_mnt(au_sbr(sb, bindex)); ++} ++ ++static inline ++struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_br_sb(au_sbr(sb, bindex)); ++} ++ ++static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ atomic_dec(&au_sbr(sb, bindex)->br_count); ++} ++ ++static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_sbr(sb, bindex)->br_perm; ++} ++ ++static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ return au_br_whable(au_sbr_perm(sb, bindex)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * wbr_wh_read_lock, wbr_wh_write_lock ++ * wbr_wh_read_unlock, wbr_wh_write_unlock, wbr_wh_downgrade_lock ++ */ ++AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, &wbr->wbr_wh_rwsem); ++ ++#define WbrWhMustNoWaiters(wbr) AuRwMustNoWaiters(&wbr->wbr_wh_rwsem) ++#define WbrWhMustAnyLock(wbr) AuRwMustAnyLock(&wbr->wbr_wh_rwsem) ++#define WbrWhMustWriteLock(wbr) AuRwMustWriteLock(&wbr->wbr_wh_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_FHSM ++static inline void au_br_fhsm_init(struct au_br_fhsm *brfhsm) ++{ ++ mutex_init(&brfhsm->bf_lock); ++ brfhsm->bf_jiffy = 0; ++ brfhsm->bf_readable = 0; ++} ++ ++static inline void au_br_fhsm_fin(struct au_br_fhsm *brfhsm) ++{ ++ mutex_destroy(&brfhsm->bf_lock); ++} ++#else ++AuStubVoid(au_br_fhsm_init, struct au_br_fhsm *brfhsm) ++AuStubVoid(au_br_fhsm_fin, struct au_br_fhsm *brfhsm) ++#endif ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_BRANCH_H__ */ +diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c +new file mode 100644 +index 0000000..26ee630 +--- /dev/null ++++ b/fs/aufs/cpup.c +@@ -0,0 +1,1290 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * copy-up functions, see wbr_policy.c for copy-down ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++void au_cpup_attr_flags(struct inode *dst, unsigned int iflags) ++{ ++ const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE ++ | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT; ++ ++ BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags)); ++ ++ dst->i_flags |= iflags & ~mask; ++ if (au_test_fs_notime(dst->i_sb)) ++ dst->i_flags |= S_NOATIME | S_NOCMTIME; ++} ++ ++void au_cpup_attr_timesizes(struct inode *inode) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ fsstack_copy_attr_times(inode, h_inode); ++ fsstack_copy_inode_size(inode, h_inode); ++} ++ ++void au_cpup_attr_nlink(struct inode *inode, int force) ++{ ++ struct inode *h_inode; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend; ++ ++ sb = inode->i_sb; ++ bindex = au_ibstart(inode); ++ h_inode = au_h_iptr(inode, bindex); ++ if (!force ++ && !S_ISDIR(h_inode->i_mode) ++ && au_opt_test(au_mntflags(sb), PLINK) ++ && au_plink_test(inode)) ++ return; ++ ++ /* ++ * 0 can happen in revalidating. ++ * h_inode->i_mutex may not be held here, but it is harmless since once ++ * i_nlink reaches 0, it will never become positive except O_TMPFILE ++ * case. ++ * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause ++ * the incorrect link count. ++ */ ++ set_nlink(inode, h_inode->i_nlink); ++ ++ /* ++ * fewer nlink makes find(1) noisy, but larger nlink doesn't. ++ * it may includes whplink directory. ++ */ ++ if (S_ISDIR(h_inode->i_mode)) { ++ bend = au_ibend(inode); ++ for (bindex++; bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode) ++ au_add_nlink(inode, h_inode); ++ } ++ } ++} ++ ++void au_cpup_attr_changeable(struct inode *inode) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ inode->i_mode = h_inode->i_mode; ++ inode->i_uid = h_inode->i_uid; ++ inode->i_gid = h_inode->i_gid; ++ au_cpup_attr_timesizes(inode); ++ au_cpup_attr_flags(inode, h_inode->i_flags); ++} ++ ++void au_cpup_igen(struct inode *inode, struct inode *h_inode) ++{ ++ struct au_iinfo *iinfo = au_ii(inode); ++ ++ IiMustWriteLock(inode); ++ ++ iinfo->ii_higen = h_inode->i_generation; ++ iinfo->ii_hsb1 = h_inode->i_sb; ++} ++ ++void au_cpup_attr_all(struct inode *inode, int force) ++{ ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ au_cpup_attr_changeable(inode); ++ if (inode->i_nlink > 0) ++ au_cpup_attr_nlink(inode, force); ++ inode->i_rdev = h_inode->i_rdev; ++ inode->i_blkbits = h_inode->i_blkbits; ++ au_cpup_igen(inode, h_inode); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */ ++ ++/* keep the timestamps of the parent dir when cpup */ ++void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, ++ struct path *h_path) ++{ ++ struct inode *h_inode; ++ ++ dt->dt_dentry = dentry; ++ dt->dt_h_path = *h_path; ++ h_inode = h_path->dentry->d_inode; ++ dt->dt_atime = h_inode->i_atime; ++ dt->dt_mtime = h_inode->i_mtime; ++ /* smp_mb(); */ ++} ++ ++void au_dtime_revert(struct au_dtime *dt) ++{ ++ struct iattr attr; ++ int err; ++ ++ attr.ia_atime = dt->dt_atime; ++ attr.ia_mtime = dt->dt_mtime; ++ attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET ++ | ATTR_ATIME | ATTR_ATIME_SET; ++ ++ /* no delegation since this is a directory */ ++ err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL); ++ if (unlikely(err)) ++ pr_warn("restoring timestamps failed(%d). ignored\n", err); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* internal use only */ ++struct au_cpup_reg_attr { ++ int valid; ++ struct kstat st; ++ unsigned int iflags; /* inode->i_flags */ ++}; ++ ++static noinline_for_stack ++int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src, ++ struct au_cpup_reg_attr *h_src_attr) ++{ ++ int err, sbits, icex; ++ struct iattr ia; ++ struct path h_path; ++ struct inode *h_isrc, *h_idst; ++ struct kstat *h_st; ++ struct au_branch *br; ++ ++ h_path.dentry = au_h_dptr(dst, bindex); ++ h_idst = h_path.dentry->d_inode; ++ br = au_sbr(dst->d_sb, bindex); ++ h_path.mnt = au_br_mnt(br); ++ h_isrc = h_src->d_inode; ++ ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID ++ | ATTR_ATIME | ATTR_MTIME ++ | ATTR_ATIME_SET | ATTR_MTIME_SET; ++ if (h_src_attr && h_src_attr->valid) { ++ h_st = &h_src_attr->st; ++ ia.ia_uid = h_st->uid; ++ ia.ia_gid = h_st->gid; ++ ia.ia_atime = h_st->atime; ++ ia.ia_mtime = h_st->mtime; ++ if (h_idst->i_mode != h_st->mode ++ && !S_ISLNK(h_idst->i_mode)) { ++ ia.ia_valid |= ATTR_MODE; ++ ia.ia_mode = h_st->mode; ++ } ++ sbits = !!(h_st->mode & (S_ISUID | S_ISGID)); ++ au_cpup_attr_flags(h_idst, h_src_attr->iflags); ++ } else { ++ ia.ia_uid = h_isrc->i_uid; ++ ia.ia_gid = h_isrc->i_gid; ++ ia.ia_atime = h_isrc->i_atime; ++ ia.ia_mtime = h_isrc->i_mtime; ++ if (h_idst->i_mode != h_isrc->i_mode ++ && !S_ISLNK(h_idst->i_mode)) { ++ ia.ia_valid |= ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ } ++ sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID)); ++ au_cpup_attr_flags(h_idst, h_isrc->i_flags); ++ } ++ /* no delegation since it is just created */ ++ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); ++ ++ /* is this nfs only? */ ++ if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) { ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); ++ } ++ ++ icex = br->br_perm & AuBrAttr_ICEX; ++ if (!err) ++ err = au_cpup_xattr(h_path.dentry, h_src, icex); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_copy_file(struct file *dst, struct file *src, loff_t len, ++ char *buf, unsigned long blksize) ++{ ++ int err; ++ size_t sz, rbytes, wbytes; ++ unsigned char all_zero; ++ char *p, *zp; ++ struct mutex *h_mtx; ++ /* reduce stack usage */ ++ struct iattr *ia; ++ ++ zp = page_address(ZERO_PAGE(0)); ++ if (unlikely(!zp)) ++ return -ENOMEM; /* possible? */ ++ ++ err = 0; ++ all_zero = 0; ++ while (len) { ++ AuDbg("len %lld\n", len); ++ sz = blksize; ++ if (len < blksize) ++ sz = len; ++ ++ rbytes = 0; ++ /* todo: signal_pending? */ ++ while (!rbytes || err == -EAGAIN || err == -EINTR) { ++ rbytes = vfsub_read_k(src, buf, sz, &src->f_pos); ++ err = rbytes; ++ } ++ if (unlikely(err < 0)) ++ break; ++ ++ all_zero = 0; ++ if (len >= rbytes && rbytes == blksize) ++ all_zero = !memcmp(buf, zp, rbytes); ++ if (!all_zero) { ++ wbytes = rbytes; ++ p = buf; ++ while (wbytes) { ++ size_t b; ++ ++ b = vfsub_write_k(dst, p, wbytes, &dst->f_pos); ++ err = b; ++ /* todo: signal_pending? */ ++ if (unlikely(err == -EAGAIN || err == -EINTR)) ++ continue; ++ if (unlikely(err < 0)) ++ break; ++ wbytes -= b; ++ p += b; ++ } ++ if (unlikely(err < 0)) ++ break; ++ } else { ++ loff_t res; ++ ++ AuLabel(hole); ++ res = vfsub_llseek(dst, rbytes, SEEK_CUR); ++ err = res; ++ if (unlikely(res < 0)) ++ break; ++ } ++ len -= rbytes; ++ err = 0; ++ } ++ ++ /* the last block may be a hole */ ++ if (!err && all_zero) { ++ AuLabel(last hole); ++ ++ err = 1; ++ if (au_test_nfs(dst->f_path.dentry->d_sb)) { ++ /* nfs requires this step to make last hole */ ++ /* is this only nfs? */ ++ do { ++ /* todo: signal_pending? */ ++ err = vfsub_write_k(dst, "\0", 1, &dst->f_pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ if (err == 1) ++ dst->f_pos--; ++ } ++ ++ if (err == 1) { ++ ia = (void *)buf; ++ ia->ia_size = dst->f_pos; ++ ia->ia_valid = ATTR_SIZE | ATTR_FILE; ++ ia->ia_file = dst; ++ h_mtx = &file_inode(dst)->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2); ++ /* no delegation since it is just created */ ++ err = vfsub_notify_change(&dst->f_path, ia, ++ /*delegated*/NULL); ++ mutex_unlock(h_mtx); ++ } ++ } ++ ++ return err; ++} ++ ++int au_copy_file(struct file *dst, struct file *src, loff_t len) ++{ ++ int err; ++ unsigned long blksize; ++ unsigned char do_kfree; ++ char *buf; ++ ++ err = -ENOMEM; ++ blksize = dst->f_path.dentry->d_sb->s_blocksize; ++ if (!blksize || PAGE_SIZE < blksize) ++ blksize = PAGE_SIZE; ++ AuDbg("blksize %lu\n", blksize); ++ do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *)); ++ if (do_kfree) ++ buf = kmalloc(blksize, GFP_NOFS); ++ else ++ buf = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!buf)) ++ goto out; ++ ++ if (len > (1 << 22)) ++ AuDbg("copying a large file %lld\n", (long long)len); ++ ++ src->f_pos = 0; ++ dst->f_pos = 0; ++ err = au_do_copy_file(dst, src, len, buf, blksize); ++ if (do_kfree) ++ kfree(buf); ++ else ++ free_page((unsigned long)buf); ++ ++out: ++ return err; ++} ++ ++/* ++ * to support a sparse file which is opened with O_APPEND, ++ * we need to close the file. ++ */ ++static int au_cp_regular(struct au_cp_generic *cpg) ++{ ++ int err, i; ++ enum { SRC, DST }; ++ struct { ++ aufs_bindex_t bindex; ++ unsigned int flags; ++ struct dentry *dentry; ++ int force_wr; ++ struct file *file; ++ void *label; ++ } *f, file[] = { ++ { ++ .bindex = cpg->bsrc, ++ .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, ++ .label = &&out ++ }, ++ { ++ .bindex = cpg->bdst, ++ .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, ++ .force_wr = !!au_ftest_cpup(cpg->flags, RWDST), ++ .label = &&out_src ++ } ++ }; ++ struct super_block *sb; ++ ++ /* bsrc branch can be ro/rw. */ ++ sb = cpg->dentry->d_sb; ++ f = file; ++ for (i = 0; i < 2; i++, f++) { ++ f->dentry = au_h_dptr(cpg->dentry, f->bindex); ++ f->file = au_h_open(cpg->dentry, f->bindex, f->flags, ++ /*file*/NULL, f->force_wr); ++ err = PTR_ERR(f->file); ++ if (IS_ERR(f->file)) ++ goto *f->label; ++ } ++ ++ /* try stopping to update while we copyup */ ++ IMustLock(file[SRC].dentry->d_inode); ++ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len); ++ ++ fput(file[DST].file); ++ au_sbr_put(sb, file[DST].bindex); ++ ++out_src: ++ fput(file[SRC].file); ++ au_sbr_put(sb, file[SRC].bindex); ++out: ++ return err; ++} ++ ++static int au_do_cpup_regular(struct au_cp_generic *cpg, ++ struct au_cpup_reg_attr *h_src_attr) ++{ ++ int err, rerr; ++ loff_t l; ++ struct path h_path; ++ struct inode *h_src_inode, *h_dst_inode; ++ ++ err = 0; ++ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc); ++ l = i_size_read(h_src_inode); ++ if (cpg->len == -1 || l < cpg->len) ++ cpg->len = l; ++ if (cpg->len) { ++ /* try stopping to update while we are referencing */ ++ mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD); ++ au_pin_hdir_unlock(cpg->pin); ++ ++ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc); ++ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc); ++ h_src_attr->iflags = h_src_inode->i_flags; ++ err = vfs_getattr(&h_path, &h_src_attr->st); ++ if (unlikely(err)) { ++ mutex_unlock(&h_src_inode->i_mutex); ++ goto out; ++ } ++ h_src_attr->valid = 1; ++ err = au_cp_regular(cpg); ++ mutex_unlock(&h_src_inode->i_mutex); ++ rerr = au_pin_hdir_relock(cpg->pin); ++ if (!err && rerr) ++ err = rerr; ++ } ++ if (!err && (h_src_inode->i_state & I_LINKABLE)) { ++ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst); ++ h_dst_inode = h_path.dentry->d_inode; ++ spin_lock(&h_dst_inode->i_lock); ++ h_dst_inode->i_state |= I_LINKABLE; ++ spin_unlock(&h_dst_inode->i_lock); ++ } ++ ++out: ++ return err; ++} ++ ++static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, ++ struct inode *h_dir) ++{ ++ int err, symlen; ++ mm_segment_t old_fs; ++ union { ++ char *k; ++ char __user *u; ++ } sym; ++ ++ err = -ENOSYS; ++ if (unlikely(!h_src->d_inode->i_op->readlink)) ++ goto out; ++ ++ err = -ENOMEM; ++ sym.k = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!sym.k)) ++ goto out; ++ ++ /* unnecessary to support mmap_sem since symlink is not mmap-able */ ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ symlen = h_src->d_inode->i_op->readlink(h_src, sym.u, PATH_MAX); ++ err = symlen; ++ set_fs(old_fs); ++ ++ if (symlen > 0) { ++ sym.k[symlen] = 0; ++ err = vfsub_symlink(h_dir, h_path, sym.k); ++ } ++ free_page((unsigned long)sym.k); ++ ++out: ++ return err; ++} ++ ++static noinline_for_stack ++int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent, ++ struct au_cpup_reg_attr *h_src_attr) ++{ ++ int err; ++ umode_t mode; ++ unsigned int mnt_flags; ++ unsigned char isdir, isreg, force; ++ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME); ++ struct au_dtime dt; ++ struct path h_path; ++ struct dentry *h_src, *h_dst, *h_parent; ++ struct inode *h_inode, *h_dir; ++ struct super_block *sb; ++ ++ /* bsrc branch can be ro/rw. */ ++ h_src = au_h_dptr(cpg->dentry, cpg->bsrc); ++ h_inode = h_src->d_inode; ++ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc)); ++ ++ /* try stopping to be referenced while we are creating */ ++ h_dst = au_h_dptr(cpg->dentry, cpg->bdst); ++ if (au_ftest_cpup(cpg->flags, RENAME)) ++ AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX, ++ AUFS_WH_PFX_LEN)); ++ h_parent = h_dst->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ AuDebugOn(h_parent != h_dst->d_parent); ++ ++ sb = cpg->dentry->d_sb; ++ h_path.mnt = au_sbr_mnt(sb, cpg->bdst); ++ if (do_dt) { ++ h_path.dentry = h_parent; ++ au_dtime_store(&dt, dst_parent, &h_path); ++ } ++ h_path.dentry = h_dst; ++ ++ isreg = 0; ++ isdir = 0; ++ mode = h_inode->i_mode; ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ isreg = 1; ++ err = vfsub_create(h_dir, &h_path, mode | S_IWUSR, ++ /*want_excl*/true); ++ if (!err) ++ err = au_do_cpup_regular(cpg, h_src_attr); ++ break; ++ case S_IFDIR: ++ isdir = 1; ++ err = vfsub_mkdir(h_dir, &h_path, mode); ++ if (!err) { ++ /* ++ * strange behaviour from the users view, ++ * particularry setattr case ++ */ ++ if (au_ibstart(dst_parent->d_inode) == cpg->bdst) ++ au_cpup_attr_nlink(dst_parent->d_inode, ++ /*force*/1); ++ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1); ++ } ++ break; ++ case S_IFLNK: ++ err = au_do_cpup_symlink(&h_path, h_src, h_dir); ++ break; ++ case S_IFCHR: ++ case S_IFBLK: ++ AuDebugOn(!capable(CAP_MKNOD)); ++ /*FALLTHROUGH*/ ++ case S_IFIFO: ++ case S_IFSOCK: ++ err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); ++ break; ++ default: ++ AuIOErr("Unknown inode type 0%o\n", mode); ++ err = -EIO; ++ } ++ ++ mnt_flags = au_mntflags(sb); ++ if (!au_opt_test(mnt_flags, UDBA_NONE) ++ && !isdir ++ && au_opt_test(mnt_flags, XINO) ++ && (h_inode->i_nlink == 1 ++ || (h_inode->i_state & I_LINKABLE)) ++ /* todo: unnecessary? */ ++ /* && cpg->dentry->d_inode->i_nlink == 1 */ ++ && cpg->bdst < cpg->bsrc ++ && !au_ftest_cpup(cpg->flags, KEEPLINO)) ++ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0); ++ /* ignore this error */ ++ ++ if (!err) { ++ force = 0; ++ if (isreg) { ++ force = !!cpg->len; ++ if (cpg->len == -1) ++ force = !!i_size_read(h_inode); ++ } ++ au_fhsm_wrote(sb, cpg->bdst, force); ++ } ++ ++ if (do_dt) ++ au_dtime_revert(&dt); ++ return err; ++} ++ ++static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path) ++{ ++ int err; ++ struct dentry *dentry, *h_dentry, *h_parent, *parent; ++ struct inode *h_dir; ++ aufs_bindex_t bdst; ++ ++ dentry = cpg->dentry; ++ bdst = cpg->bdst; ++ h_dentry = au_h_dptr(dentry, bdst); ++ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) { ++ dget(h_dentry); ++ au_set_h_dptr(dentry, bdst, NULL); ++ err = au_lkup_neg(dentry, bdst, /*wh*/0); ++ if (!err) ++ h_path->dentry = dget(au_h_dptr(dentry, bdst)); ++ au_set_h_dptr(dentry, bdst, h_dentry); ++ } else { ++ err = 0; ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ dput(parent); ++ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent); ++ if (IS_ERR(h_path->dentry)) ++ err = PTR_ERR(h_path->dentry); ++ } ++ if (unlikely(err)) ++ goto out; ++ ++ h_parent = h_dentry->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ AuDbg("%pd %pd\n", h_dentry, h_path->dentry); ++ /* no delegation since it is just created */ ++ err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL); ++ dput(h_path->dentry); ++ ++out: ++ return err; ++} ++ ++/* ++ * copyup the @dentry from @bsrc to @bdst. ++ * the caller must set the both of lower dentries. ++ * @len is for truncating when it is -1 copyup the entire file. ++ * in link/rename cases, @dst_parent may be different from the real one. ++ * basic->bsrc can be larger than basic->bdst. ++ */ ++static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) ++{ ++ int err, rerr; ++ aufs_bindex_t old_ibstart; ++ unsigned char isdir, plink; ++ struct dentry *h_src, *h_dst, *h_parent; ++ struct inode *dst_inode, *h_dir, *inode, *delegated; ++ struct super_block *sb; ++ struct au_branch *br; ++ /* to reuduce stack size */ ++ struct { ++ struct au_dtime dt; ++ struct path h_path; ++ struct au_cpup_reg_attr h_src_attr; ++ } *a; ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ a->h_src_attr.valid = 0; ++ ++ sb = cpg->dentry->d_sb; ++ br = au_sbr(sb, cpg->bdst); ++ a->h_path.mnt = au_br_mnt(br); ++ h_dst = au_h_dptr(cpg->dentry, cpg->bdst); ++ h_parent = h_dst->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ h_src = au_h_dptr(cpg->dentry, cpg->bsrc); ++ inode = cpg->dentry->d_inode; ++ ++ if (!dst_parent) ++ dst_parent = dget_parent(cpg->dentry); ++ else ++ dget(dst_parent); ++ ++ plink = !!au_opt_test(au_mntflags(sb), PLINK); ++ dst_inode = au_h_iptr(inode, cpg->bdst); ++ if (dst_inode) { ++ if (unlikely(!plink)) { ++ err = -EIO; ++ AuIOErr("hi%lu(i%lu) exists on b%d " ++ "but plink is disabled\n", ++ dst_inode->i_ino, inode->i_ino, cpg->bdst); ++ goto out_parent; ++ } ++ ++ if (dst_inode->i_nlink) { ++ const int do_dt = au_ftest_cpup(cpg->flags, DTIME); ++ ++ h_src = au_plink_lkup(inode, cpg->bdst); ++ err = PTR_ERR(h_src); ++ if (IS_ERR(h_src)) ++ goto out_parent; ++ if (unlikely(!h_src->d_inode)) { ++ err = -EIO; ++ AuIOErr("i%lu exists on a upper branch " ++ "but not pseudo-linked\n", ++ inode->i_ino); ++ dput(h_src); ++ goto out_parent; ++ } ++ ++ if (do_dt) { ++ a->h_path.dentry = h_parent; ++ au_dtime_store(&a->dt, dst_parent, &a->h_path); ++ } ++ ++ a->h_path.dentry = h_dst; ++ delegated = NULL; ++ err = vfsub_link(h_src, h_dir, &a->h_path, &delegated); ++ if (!err && au_ftest_cpup(cpg->flags, RENAME)) ++ err = au_do_ren_after_cpup(cpg, &a->h_path); ++ if (do_dt) ++ au_dtime_revert(&a->dt); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal link\n"); ++ iput(delegated); ++ } ++ dput(h_src); ++ goto out_parent; ++ } else ++ /* todo: cpup_wh_file? */ ++ /* udba work */ ++ au_update_ibrange(inode, /*do_put_zero*/1); ++ } ++ ++ isdir = S_ISDIR(inode->i_mode); ++ old_ibstart = au_ibstart(inode); ++ err = cpup_entry(cpg, dst_parent, &a->h_src_attr); ++ if (unlikely(err)) ++ goto out_rev; ++ dst_inode = h_dst->d_inode; ++ mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2); ++ /* todo: necessary? */ ++ /* au_pin_hdir_unlock(cpg->pin); */ ++ ++ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr); ++ if (unlikely(err)) { ++ /* todo: necessary? */ ++ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */ ++ mutex_unlock(&dst_inode->i_mutex); ++ goto out_rev; ++ } ++ ++ if (cpg->bdst < old_ibstart) { ++ if (S_ISREG(inode->i_mode)) { ++ err = au_dy_iaop(inode, cpg->bdst, dst_inode); ++ if (unlikely(err)) { ++ /* ignore an error */ ++ /* au_pin_hdir_relock(cpg->pin); */ ++ mutex_unlock(&dst_inode->i_mutex); ++ goto out_rev; ++ } ++ } ++ au_set_ibstart(inode, cpg->bdst); ++ } else ++ au_set_ibend(inode, cpg->bdst); ++ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode), ++ au_hi_flags(inode, isdir)); ++ ++ /* todo: necessary? */ ++ /* err = au_pin_hdir_relock(cpg->pin); */ ++ mutex_unlock(&dst_inode->i_mutex); ++ if (unlikely(err)) ++ goto out_rev; ++ ++ if (!isdir ++ && (h_src->d_inode->i_nlink > 1 ++ || h_src->d_inode->i_state & I_LINKABLE) ++ && plink) ++ au_plink_append(inode, cpg->bdst, h_dst); ++ ++ if (au_ftest_cpup(cpg->flags, RENAME)) { ++ a->h_path.dentry = h_dst; ++ err = au_do_ren_after_cpup(cpg, &a->h_path); ++ } ++ if (!err) ++ goto out_parent; /* success */ ++ ++ /* revert */ ++out_rev: ++ a->h_path.dentry = h_parent; ++ au_dtime_store(&a->dt, dst_parent, &a->h_path); ++ a->h_path.dentry = h_dst; ++ rerr = 0; ++ if (h_dst->d_inode) { ++ if (!isdir) { ++ /* no delegation since it is just created */ ++ rerr = vfsub_unlink(h_dir, &a->h_path, ++ /*delegated*/NULL, /*force*/0); ++ } else ++ rerr = vfsub_rmdir(h_dir, &a->h_path); ++ } ++ au_dtime_revert(&a->dt); ++ if (rerr) { ++ AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); ++ err = -EIO; ++ } ++out_parent: ++ dput(dst_parent); ++ kfree(a); ++out: ++ return err; ++} ++ ++#if 0 /* unused */ ++struct au_cpup_single_args { ++ int *errp; ++ struct au_cp_generic *cpg; ++ struct dentry *dst_parent; ++}; ++ ++static void au_call_cpup_single(void *args) ++{ ++ struct au_cpup_single_args *a = args; ++ ++ au_pin_hdir_acquire_nest(a->cpg->pin); ++ *a->errp = au_cpup_single(a->cpg, a->dst_parent); ++ au_pin_hdir_release(a->cpg->pin); ++} ++#endif ++ ++/* ++ * prevent SIGXFSZ in copy-up. ++ * testing CAP_MKNOD is for generic fs, ++ * but CAP_FSETID is for xfs only, currently. ++ */ ++static int au_cpup_sio_test(struct au_pin *pin, umode_t mode) ++{ ++ int do_sio; ++ struct super_block *sb; ++ struct inode *h_dir; ++ ++ do_sio = 0; ++ sb = au_pinned_parent(pin)->d_sb; ++ if (!au_wkq_test() ++ && (!au_sbi(sb)->si_plink_maint_pid ++ || au_plink_maint(sb, AuLock_NOPLM))) { ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ /* no condition about RLIMIT_FSIZE and the file size */ ++ do_sio = 1; ++ break; ++ case S_IFCHR: ++ case S_IFBLK: ++ do_sio = !capable(CAP_MKNOD); ++ break; ++ } ++ if (!do_sio) ++ do_sio = ((mode & (S_ISUID | S_ISGID)) ++ && !capable(CAP_FSETID)); ++ /* this workaround may be removed in the future */ ++ if (!do_sio) { ++ h_dir = au_pinned_h_dir(pin); ++ do_sio = h_dir->i_mode & S_ISVTX; ++ } ++ } ++ ++ return do_sio; ++} ++ ++#if 0 /* unused */ ++int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) ++{ ++ int err, wkq_err; ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc); ++ if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode)) ++ err = au_cpup_single(cpg, dst_parent); ++ else { ++ struct au_cpup_single_args args = { ++ .errp = &err, ++ .cpg = cpg, ++ .dst_parent = dst_parent ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_single, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++#endif ++ ++/* ++ * copyup the @dentry from the first active lower branch to @bdst, ++ * using au_cpup_single(). ++ */ ++static int au_cpup_simple(struct au_cp_generic *cpg) ++{ ++ int err; ++ unsigned int flags_orig; ++ struct dentry *dentry; ++ ++ AuDebugOn(cpg->bsrc < 0); ++ ++ dentry = cpg->dentry; ++ DiMustWriteLock(dentry); ++ ++ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1); ++ if (!err) { ++ flags_orig = cpg->flags; ++ au_fset_cpup(cpg->flags, RENAME); ++ err = au_cpup_single(cpg, NULL); ++ cpg->flags = flags_orig; ++ if (!err) ++ return 0; /* success */ ++ ++ /* revert */ ++ au_set_h_dptr(dentry, cpg->bdst, NULL); ++ au_set_dbstart(dentry, cpg->bsrc); ++ } ++ ++ return err; ++} ++ ++struct au_cpup_simple_args { ++ int *errp; ++ struct au_cp_generic *cpg; ++}; ++ ++static void au_call_cpup_simple(void *args) ++{ ++ struct au_cpup_simple_args *a = args; ++ ++ au_pin_hdir_acquire_nest(a->cpg->pin); ++ *a->errp = au_cpup_simple(a->cpg); ++ au_pin_hdir_release(a->cpg->pin); ++} ++ ++static int au_do_sio_cpup_simple(struct au_cp_generic *cpg) ++{ ++ int err, wkq_err; ++ struct dentry *dentry, *parent; ++ struct file *h_file; ++ struct inode *h_dir; ++ ++ dentry = cpg->dentry; ++ h_file = NULL; ++ if (au_ftest_cpup(cpg->flags, HOPEN)) { ++ AuDebugOn(cpg->bsrc < 0); ++ h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ } ++ ++ parent = dget_parent(dentry); ++ h_dir = au_h_iptr(parent->d_inode, cpg->bdst); ++ if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE) ++ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode)) ++ err = au_cpup_simple(cpg); ++ else { ++ struct au_cpup_simple_args args = { ++ .errp = &err, ++ .cpg = cpg ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_simple, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ dput(parent); ++ if (h_file) ++ au_h_open_post(dentry, cpg->bsrc, h_file); ++ ++out: ++ return err; ++} ++ ++int au_sio_cpup_simple(struct au_cp_generic *cpg) ++{ ++ aufs_bindex_t bsrc, bend; ++ struct dentry *dentry, *h_dentry; ++ ++ if (cpg->bsrc < 0) { ++ dentry = cpg->dentry; ++ bend = au_dbend(dentry); ++ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) { ++ h_dentry = au_h_dptr(dentry, bsrc); ++ if (h_dentry) { ++ AuDebugOn(!h_dentry->d_inode); ++ break; ++ } ++ } ++ AuDebugOn(bsrc > bend); ++ cpg->bsrc = bsrc; ++ } ++ AuDebugOn(cpg->bsrc <= cpg->bdst); ++ return au_do_sio_cpup_simple(cpg); ++} ++ ++int au_sio_cpdown_simple(struct au_cp_generic *cpg) ++{ ++ AuDebugOn(cpg->bdst <= cpg->bsrc); ++ return au_do_sio_cpup_simple(cpg); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * copyup the deleted file for writing. ++ */ ++static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry, ++ struct file *file) ++{ ++ int err; ++ unsigned int flags_orig; ++ aufs_bindex_t bsrc_orig; ++ struct dentry *h_d_dst, *h_d_start; ++ struct au_dinfo *dinfo; ++ struct au_hdentry *hdp; ++ ++ dinfo = au_di(cpg->dentry); ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ bsrc_orig = cpg->bsrc; ++ cpg->bsrc = dinfo->di_bstart; ++ hdp = dinfo->di_hdentry; ++ h_d_dst = hdp[0 + cpg->bdst].hd_dentry; ++ dinfo->di_bstart = cpg->bdst; ++ hdp[0 + cpg->bdst].hd_dentry = wh_dentry; ++ h_d_start = NULL; ++ if (file) { ++ h_d_start = hdp[0 + cpg->bsrc].hd_dentry; ++ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_path.dentry; ++ } ++ flags_orig = cpg->flags; ++ cpg->flags = !AuCpup_DTIME; ++ err = au_cpup_single(cpg, /*h_parent*/NULL); ++ cpg->flags = flags_orig; ++ if (file) { ++ if (!err) ++ err = au_reopen_nondir(file); ++ hdp[0 + cpg->bsrc].hd_dentry = h_d_start; ++ } ++ hdp[0 + cpg->bdst].hd_dentry = h_d_dst; ++ dinfo->di_bstart = cpg->bsrc; ++ cpg->bsrc = bsrc_orig; ++ ++ return err; ++} ++ ++static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file) ++{ ++ int err; ++ aufs_bindex_t bdst; ++ struct au_dtime dt; ++ struct dentry *dentry, *parent, *h_parent, *wh_dentry; ++ struct au_branch *br; ++ struct path h_path; ++ ++ dentry = cpg->dentry; ++ bdst = cpg->bdst; ++ br = au_sbr(dentry->d_sb, bdst); ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ h_path.dentry = h_parent; ++ h_path.mnt = au_br_mnt(br); ++ au_dtime_store(&dt, parent, &h_path); ++ err = au_do_cpup_wh(cpg, wh_dentry, file); ++ if (unlikely(err)) ++ goto out_wh; ++ ++ dget(wh_dentry); ++ h_path.dentry = wh_dentry; ++ if (!S_ISDIR(wh_dentry->d_inode->i_mode)) { ++ /* no delegation since it is just created */ ++ err = vfsub_unlink(h_parent->d_inode, &h_path, ++ /*delegated*/NULL, /*force*/0); ++ } else ++ err = vfsub_rmdir(h_parent->d_inode, &h_path); ++ if (unlikely(err)) { ++ AuIOErr("failed remove copied-up tmp file %pd(%d)\n", ++ wh_dentry, err); ++ err = -EIO; ++ } ++ au_dtime_revert(&dt); ++ au_set_hi_wh(dentry->d_inode, bdst, wh_dentry); ++ ++out_wh: ++ dput(wh_dentry); ++out: ++ dput(parent); ++ return err; ++} ++ ++struct au_cpup_wh_args { ++ int *errp; ++ struct au_cp_generic *cpg; ++ struct file *file; ++}; ++ ++static void au_call_cpup_wh(void *args) ++{ ++ struct au_cpup_wh_args *a = args; ++ ++ au_pin_hdir_acquire_nest(a->cpg->pin); ++ *a->errp = au_cpup_wh(a->cpg, a->file); ++ au_pin_hdir_release(a->cpg->pin); ++} ++ ++int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file) ++{ ++ int err, wkq_err; ++ aufs_bindex_t bdst; ++ struct dentry *dentry, *parent, *h_orph, *h_parent; ++ struct inode *dir, *h_dir, *h_tmpdir; ++ struct au_wbr *wbr; ++ struct au_pin wh_pin, *pin_orig; ++ ++ dentry = cpg->dentry; ++ bdst = cpg->bdst; ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ h_orph = NULL; ++ h_parent = NULL; ++ h_dir = au_igrab(au_h_iptr(dir, bdst)); ++ h_tmpdir = h_dir; ++ pin_orig = NULL; ++ if (!h_dir->i_nlink) { ++ wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; ++ h_orph = wbr->wbr_orph; ++ ++ h_parent = dget(au_h_dptr(parent, bdst)); ++ au_set_h_dptr(parent, bdst, dget(h_orph)); ++ h_tmpdir = h_orph->d_inode; ++ au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); ++ ++ mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3); ++ /* todo: au_h_open_pre()? */ ++ ++ pin_orig = cpg->pin; ++ au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT, ++ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED); ++ cpg->pin = &wh_pin; ++ } ++ ++ if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE) ++ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode)) ++ err = au_cpup_wh(cpg, file); ++ else { ++ struct au_cpup_wh_args args = { ++ .errp = &err, ++ .cpg = cpg, ++ .file = file ++ }; ++ wkq_err = au_wkq_wait(au_call_cpup_wh, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ if (h_orph) { ++ mutex_unlock(&h_tmpdir->i_mutex); ++ /* todo: au_h_open_post()? */ ++ au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); ++ au_set_h_dptr(parent, bdst, h_parent); ++ AuDebugOn(!pin_orig); ++ cpg->pin = pin_orig; ++ } ++ iput(h_dir); ++ dput(parent); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * generic routine for both of copy-up and copy-down. ++ */ ++/* cf. revalidate function in file.c */ ++int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, ++ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, ++ struct au_pin *pin, ++ struct dentry *h_parent, void *arg), ++ void *arg) ++{ ++ int err; ++ struct au_pin pin; ++ struct dentry *d, *parent, *h_parent, *real_parent; ++ ++ err = 0; ++ parent = dget_parent(dentry); ++ if (IS_ROOT(parent)) ++ goto out; ++ ++ au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2, ++ au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE); ++ ++ /* do not use au_dpage */ ++ real_parent = parent; ++ while (1) { ++ dput(parent); ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ if (h_parent) ++ goto out; /* success */ ++ ++ /* find top dir which is necessary to cpup */ ++ do { ++ d = parent; ++ dput(parent); ++ parent = dget_parent(d); ++ di_read_lock_parent3(parent, !AuLock_IR); ++ h_parent = au_h_dptr(parent, bdst); ++ di_read_unlock(parent, !AuLock_IR); ++ } while (!h_parent); ++ ++ if (d != real_parent) ++ di_write_lock_child3(d); ++ ++ /* somebody else might create while we were sleeping */ ++ if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) { ++ if (au_h_dptr(d, bdst)) ++ au_update_dbstart(d); ++ ++ au_pin_set_dentry(&pin, d); ++ err = au_do_pin(&pin); ++ if (!err) { ++ err = cp(d, bdst, &pin, h_parent, arg); ++ au_unpin(&pin); ++ } ++ } ++ ++ if (d != real_parent) ++ di_write_unlock(d); ++ if (unlikely(err)) ++ break; ++ } ++ ++out: ++ dput(parent); ++ return err; ++} ++ ++static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, ++ struct au_pin *pin, ++ struct dentry *h_parent __maybe_unused, ++ void *arg __maybe_unused) ++{ ++ struct au_cp_generic cpg = { ++ .dentry = dentry, ++ .bdst = bdst, ++ .bsrc = -1, ++ .len = 0, ++ .pin = pin, ++ .flags = AuCpup_DTIME ++ }; ++ return au_sio_cpup_simple(&cpg); ++} ++ ++int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); ++} ++ ++int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ int err; ++ struct dentry *parent; ++ struct inode *dir; ++ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ err = 0; ++ if (au_h_iptr(dir, bdst)) ++ goto out; ++ ++ di_read_unlock(parent, AuLock_IR); ++ di_write_lock_parent(parent); ++ /* someone else might change our inode while we were sleeping */ ++ if (!au_h_iptr(dir, bdst)) ++ err = au_cpup_dirs(dentry, bdst); ++ di_downgrade_lock(parent, AuLock_IR); ++ ++out: ++ dput(parent); ++ return err; ++} +diff --git a/fs/aufs/cpup.h b/fs/aufs/cpup.h +new file mode 100644 +index 0000000..3355f08 +--- /dev/null ++++ b/fs/aufs/cpup.h +@@ -0,0 +1,81 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * copy-up/down functions ++ */ ++ ++#ifndef __AUFS_CPUP_H__ ++#define __AUFS_CPUP_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++struct inode; ++struct file; ++struct au_pin; ++ ++void au_cpup_attr_flags(struct inode *dst, unsigned int iflags); ++void au_cpup_attr_timesizes(struct inode *inode); ++void au_cpup_attr_nlink(struct inode *inode, int force); ++void au_cpup_attr_changeable(struct inode *inode); ++void au_cpup_igen(struct inode *inode, struct inode *h_inode); ++void au_cpup_attr_all(struct inode *inode, int force); ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_cp_generic { ++ struct dentry *dentry; ++ aufs_bindex_t bdst, bsrc; ++ loff_t len; ++ struct au_pin *pin; ++ unsigned int flags; ++}; ++ ++/* cpup flags */ ++#define AuCpup_DTIME 1 /* do dtime_store/revert */ ++#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, ++ for link(2) */ ++#define AuCpup_RENAME (1 << 2) /* rename after cpup */ ++#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in ++ cpup */ ++#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the ++ existing entry */ ++#define AuCpup_RWDST (1 << 5) /* force write target even if ++ the branch is marked as RO */ ++ ++#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) ++#define au_fset_cpup(flags, name) \ ++ do { (flags) |= AuCpup_##name; } while (0) ++#define au_fclr_cpup(flags, name) \ ++ do { (flags) &= ~AuCpup_##name; } while (0) ++ ++int au_copy_file(struct file *dst, struct file *src, loff_t len); ++int au_sio_cpup_simple(struct au_cp_generic *cpg); ++int au_sio_cpdown_simple(struct au_cp_generic *cpg); ++int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file); ++ ++int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, ++ int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, ++ struct au_pin *pin, ++ struct dentry *h_parent, void *arg), ++ void *arg); ++int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* keep timestamps when copyup */ ++struct au_dtime { ++ struct dentry *dt_dentry; ++ struct path dt_h_path; ++ struct timespec dt_atime, dt_mtime; ++}; ++void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, ++ struct path *h_path); ++void au_dtime_revert(struct au_dtime *dt); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_CPUP_H__ */ +diff --git a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c +new file mode 100644 +index 0000000..68af344 +--- /dev/null ++++ b/fs/aufs/dbgaufs.c +@@ -0,0 +1,419 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * debugfs interface ++ */ ++ ++#include ++#include "aufs.h" ++ ++#ifndef CONFIG_SYSFS ++#error DEBUG_FS depends upon SYSFS ++#endif ++ ++static struct dentry *dbgaufs; ++static const mode_t dbgaufs_mode = S_IRUSR | S_IRGRP | S_IROTH; ++ ++/* 20 is max digits length of ulong 64 */ ++struct dbgaufs_arg { ++ int n; ++ char a[20 * 4]; ++}; ++ ++/* ++ * common function for all XINO files ++ */ ++static int dbgaufs_xi_release(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ kfree(file->private_data); ++ return 0; ++} ++ ++static int dbgaufs_xi_open(struct file *xf, struct file *file, int do_fcnt) ++{ ++ int err; ++ struct kstat st; ++ struct dbgaufs_arg *p; ++ ++ err = -ENOMEM; ++ p = kmalloc(sizeof(*p), GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ ++ err = 0; ++ p->n = 0; ++ file->private_data = p; ++ if (!xf) ++ goto out; ++ ++ err = vfs_getattr(&xf->f_path, &st); ++ if (!err) { ++ if (do_fcnt) ++ p->n = snprintf ++ (p->a, sizeof(p->a), "%ld, %llux%lu %lld\n", ++ (long)file_count(xf), st.blocks, st.blksize, ++ (long long)st.size); ++ else ++ p->n = snprintf(p->a, sizeof(p->a), "%llux%lu %lld\n", ++ st.blocks, st.blksize, ++ (long long)st.size); ++ AuDebugOn(p->n >= sizeof(p->a)); ++ } else { ++ p->n = snprintf(p->a, sizeof(p->a), "err %d\n", err); ++ err = 0; ++ } ++ ++out: ++ return err; ++ ++} ++ ++static ssize_t dbgaufs_xi_read(struct file *file, char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dbgaufs_arg *p; ++ ++ p = file->private_data; ++ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dbgaufs_plink_arg { ++ int n; ++ char a[]; ++}; ++ ++static int dbgaufs_plink_release(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ free_page((unsigned long)file->private_data); ++ return 0; ++} ++ ++static int dbgaufs_plink_open(struct inode *inode, struct file *file) ++{ ++ int err, i, limit; ++ unsigned long n, sum; ++ struct dbgaufs_plink_arg *p; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ struct au_sphlhead *sphl; ++ ++ err = -ENOMEM; ++ p = (void *)get_zeroed_page(GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ ++ err = -EFBIG; ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ if (au_opt_test(au_mntflags(sb), PLINK)) { ++ limit = PAGE_SIZE - sizeof(p->n); ++ ++ /* the number of buckets */ ++ n = snprintf(p->a + p->n, limit, "%d\n", AuPlink_NHASH); ++ p->n += n; ++ limit -= n; ++ ++ sum = 0; ++ for (i = 0, sphl = sbinfo->si_plink; ++ i < AuPlink_NHASH; ++ i++, sphl++) { ++ n = au_sphl_count(sphl); ++ sum += n; ++ ++ n = snprintf(p->a + p->n, limit, "%lu ", n); ++ p->n += n; ++ limit -= n; ++ if (unlikely(limit <= 0)) ++ goto out_free; ++ } ++ p->a[p->n - 1] = '\n'; ++ ++ /* the sum of plinks */ ++ n = snprintf(p->a + p->n, limit, "%lu\n", sum); ++ p->n += n; ++ limit -= n; ++ if (unlikely(limit <= 0)) ++ goto out_free; ++ } else { ++#define str "1\n0\n0\n" ++ p->n = sizeof(str) - 1; ++ strcpy(p->a, str); ++#undef str ++ } ++ si_read_unlock(sb); ++ ++ err = 0; ++ file->private_data = p; ++ goto out; /* success */ ++ ++out_free: ++ free_page((unsigned long)p); ++out: ++ return err; ++} ++ ++static ssize_t dbgaufs_plink_read(struct file *file, char __user *buf, ++ size_t count, loff_t *ppos) ++{ ++ struct dbgaufs_plink_arg *p; ++ ++ p = file->private_data; ++ return simple_read_from_buffer(buf, count, ppos, p->a, p->n); ++} ++ ++static const struct file_operations dbgaufs_plink_fop = { ++ .owner = THIS_MODULE, ++ .open = dbgaufs_plink_open, ++ .release = dbgaufs_plink_release, ++ .read = dbgaufs_plink_read ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int dbgaufs_xib_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ err = dbgaufs_xi_open(sbinfo->si_xib, file, /*do_fcnt*/0); ++ si_read_unlock(sb); ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xib_fop = { ++ .owner = THIS_MODULE, ++ .open = dbgaufs_xib_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define DbgaufsXi_PREFIX "xi" ++ ++static int dbgaufs_xino_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ long l; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ struct file *xf; ++ struct qstr *name; ++ ++ err = -ENOENT; ++ xf = NULL; ++ name = &file->f_path.dentry->d_name; ++ if (unlikely(name->len < sizeof(DbgaufsXi_PREFIX) ++ || memcmp(name->name, DbgaufsXi_PREFIX, ++ sizeof(DbgaufsXi_PREFIX) - 1))) ++ goto out; ++ err = kstrtol(name->name + sizeof(DbgaufsXi_PREFIX) - 1, 10, &l); ++ if (unlikely(err)) ++ goto out; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ if (l <= au_sbend(sb)) { ++ xf = au_sbr(sb, (aufs_bindex_t)l)->br_xino.xi_file; ++ err = dbgaufs_xi_open(xf, file, /*do_fcnt*/1); ++ } else ++ err = -ENOENT; ++ si_read_unlock(sb); ++ ++out: ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xino_fop = { ++ .owner = THIS_MODULE, ++ .open = dbgaufs_xino_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ aufs_bindex_t bend; ++ struct au_branch *br; ++ struct au_xino_file *xi; ++ ++ if (!au_sbi(sb)->si_dbgaufs) ++ return; ++ ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ xi = &br->br_xino; ++ debugfs_remove(xi->xi_dbgaufs); ++ xi->xi_dbgaufs = NULL; ++ } ++} ++ ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ struct au_sbinfo *sbinfo; ++ struct dentry *parent; ++ struct au_branch *br; ++ struct au_xino_file *xi; ++ aufs_bindex_t bend; ++ char name[sizeof(DbgaufsXi_PREFIX) + 5]; /* "xi" bindex NULL */ ++ ++ sbinfo = au_sbi(sb); ++ parent = sbinfo->si_dbgaufs; ++ if (!parent) ++ return; ++ ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ snprintf(name, sizeof(name), DbgaufsXi_PREFIX "%d", bindex); ++ br = au_sbr(sb, bindex); ++ xi = &br->br_xino; ++ AuDebugOn(xi->xi_dbgaufs); ++ xi->xi_dbgaufs = debugfs_create_file(name, dbgaufs_mode, parent, ++ sbinfo, &dbgaufs_xino_fop); ++ /* ignore an error */ ++ if (unlikely(!xi->xi_dbgaufs)) ++ AuWarn1("failed %s under debugfs\n", name); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++static int dbgaufs_xigen_open(struct inode *inode, struct file *file) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ ++ sbinfo = inode->i_private; ++ sb = sbinfo->si_sb; ++ si_noflush_read_lock(sb); ++ err = dbgaufs_xi_open(sbinfo->si_xigen, file, /*do_fcnt*/0); ++ si_read_unlock(sb); ++ return err; ++} ++ ++static const struct file_operations dbgaufs_xigen_fop = { ++ .owner = THIS_MODULE, ++ .open = dbgaufs_xigen_open, ++ .release = dbgaufs_xi_release, ++ .read = dbgaufs_xi_read ++}; ++ ++static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ ++ /* ++ * This function is a dynamic '__init' function actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++ ++ err = -EIO; ++ sbinfo->si_dbgaufs_xigen = debugfs_create_file ++ ("xigen", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, ++ &dbgaufs_xigen_fop); ++ if (sbinfo->si_dbgaufs_xigen) ++ err = 0; ++ ++ return err; ++} ++#else ++static int dbgaufs_xigen_init(struct au_sbinfo *sbinfo) ++{ ++ return 0; ++} ++#endif /* CONFIG_AUFS_EXPORT */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo) ++{ ++ /* ++ * This function is a dynamic '__init' function actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++ ++ debugfs_remove_recursive(sbinfo->si_dbgaufs); ++ sbinfo->si_dbgaufs = NULL; ++ kobject_put(&sbinfo->si_kobj); ++} ++ ++int dbgaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ char name[SysaufsSiNameLen]; ++ ++ /* ++ * This function is a dynamic '__init' function actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++ ++ err = -ENOENT; ++ if (!dbgaufs) { ++ AuErr1("/debug/aufs is uninitialized\n"); ++ goto out; ++ } ++ ++ err = -EIO; ++ sysaufs_name(sbinfo, name); ++ sbinfo->si_dbgaufs = debugfs_create_dir(name, dbgaufs); ++ if (unlikely(!sbinfo->si_dbgaufs)) ++ goto out; ++ kobject_get(&sbinfo->si_kobj); ++ ++ sbinfo->si_dbgaufs_xib = debugfs_create_file ++ ("xib", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, ++ &dbgaufs_xib_fop); ++ if (unlikely(!sbinfo->si_dbgaufs_xib)) ++ goto out_dir; ++ ++ sbinfo->si_dbgaufs_plink = debugfs_create_file ++ ("plink", dbgaufs_mode, sbinfo->si_dbgaufs, sbinfo, ++ &dbgaufs_plink_fop); ++ if (unlikely(!sbinfo->si_dbgaufs_plink)) ++ goto out_dir; ++ ++ err = dbgaufs_xigen_init(sbinfo); ++ if (!err) ++ goto out; /* success */ ++ ++out_dir: ++ dbgaufs_si_fin(sbinfo); ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void dbgaufs_fin(void) ++{ ++ debugfs_remove(dbgaufs); ++} ++ ++int __init dbgaufs_init(void) ++{ ++ int err; ++ ++ err = -EIO; ++ dbgaufs = debugfs_create_dir(AUFS_NAME, NULL); ++ if (dbgaufs) ++ err = 0; ++ return err; ++} +diff --git a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h +new file mode 100644 +index 0000000..efa9a4d +--- /dev/null ++++ b/fs/aufs/dbgaufs.h +@@ -0,0 +1,35 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * debugfs interface ++ */ ++ ++#ifndef __DBGAUFS_H__ ++#define __DBGAUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++struct super_block; ++struct au_sbinfo; ++ ++#ifdef CONFIG_DEBUG_FS ++/* dbgaufs.c */ ++void dbgaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); ++void dbgaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); ++void dbgaufs_si_fin(struct au_sbinfo *sbinfo); ++int dbgaufs_si_init(struct au_sbinfo *sbinfo); ++void dbgaufs_fin(void); ++int __init dbgaufs_init(void); ++#else ++AuStubVoid(dbgaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex) ++AuStubVoid(dbgaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex) ++AuStubVoid(dbgaufs_si_fin, struct au_sbinfo *sbinfo) ++AuStubInt0(dbgaufs_si_init, struct au_sbinfo *sbinfo) ++AuStubVoid(dbgaufs_fin, void) ++AuStubInt0(__init dbgaufs_init, void) ++#endif /* CONFIG_DEBUG_FS */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __DBGAUFS_H__ */ +diff --git a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c +new file mode 100644 +index 0000000..f9d9d52 +--- /dev/null ++++ b/fs/aufs/dcsub.c +@@ -0,0 +1,211 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * sub-routines for dentry cache ++ */ ++ ++#include "aufs.h" ++ ++static void au_dpage_free(struct au_dpage *dpage) ++{ ++ int i; ++ struct dentry **p; ++ ++ p = dpage->dentries; ++ for (i = 0; i < dpage->ndentry; i++) ++ dput(*p++); ++ free_page((unsigned long)dpage->dentries); ++} ++ ++int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) ++{ ++ int err; ++ void *p; ++ ++ err = -ENOMEM; ++ dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp); ++ if (unlikely(!dpages->dpages)) ++ goto out; ++ ++ p = (void *)__get_free_page(gfp); ++ if (unlikely(!p)) ++ goto out_dpages; ++ ++ dpages->dpages[0].ndentry = 0; ++ dpages->dpages[0].dentries = p; ++ dpages->ndpage = 1; ++ return 0; /* success */ ++ ++out_dpages: ++ kfree(dpages->dpages); ++out: ++ return err; ++} ++ ++void au_dpages_free(struct au_dcsub_pages *dpages) ++{ ++ int i; ++ struct au_dpage *p; ++ ++ p = dpages->dpages; ++ for (i = 0; i < dpages->ndpage; i++) ++ au_dpage_free(p++); ++ kfree(dpages->dpages); ++} ++ ++static int au_dpages_append(struct au_dcsub_pages *dpages, ++ struct dentry *dentry, gfp_t gfp) ++{ ++ int err, sz; ++ struct au_dpage *dpage; ++ void *p; ++ ++ dpage = dpages->dpages + dpages->ndpage - 1; ++ sz = PAGE_SIZE / sizeof(dentry); ++ if (unlikely(dpage->ndentry >= sz)) { ++ AuLabel(new dpage); ++ err = -ENOMEM; ++ sz = dpages->ndpage * sizeof(*dpages->dpages); ++ p = au_kzrealloc(dpages->dpages, sz, ++ sz + sizeof(*dpages->dpages), gfp); ++ if (unlikely(!p)) ++ goto out; ++ ++ dpages->dpages = p; ++ dpage = dpages->dpages + dpages->ndpage; ++ p = (void *)__get_free_page(gfp); ++ if (unlikely(!p)) ++ goto out; ++ ++ dpage->ndentry = 0; ++ dpage->dentries = p; ++ dpages->ndpage++; ++ } ++ ++ AuDebugOn(au_dcount(dentry) <= 0); ++ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry); ++ return 0; /* success */ ++ ++out: ++ return err; ++} ++ ++/* todo: BAD approach */ ++/* copied from linux/fs/dcache.c */ ++enum d_walk_ret { ++ D_WALK_CONTINUE, ++ D_WALK_QUIT, ++ D_WALK_NORETRY, ++ D_WALK_SKIP, ++}; ++ ++extern void d_walk(struct dentry *parent, void *data, ++ enum d_walk_ret (*enter)(void *, struct dentry *), ++ void (*finish)(void *)); ++ ++struct ac_dpages_arg { ++ int err; ++ struct au_dcsub_pages *dpages; ++ struct super_block *sb; ++ au_dpages_test test; ++ void *arg; ++}; ++ ++static enum d_walk_ret au_call_dpages_append(void *_arg, struct dentry *dentry) ++{ ++ enum d_walk_ret ret; ++ struct ac_dpages_arg *arg = _arg; ++ ++ ret = D_WALK_CONTINUE; ++ if (dentry->d_sb == arg->sb ++ && !IS_ROOT(dentry) ++ && au_dcount(dentry) > 0 ++ && au_di(dentry) ++ && (!arg->test || arg->test(dentry, arg->arg))) { ++ arg->err = au_dpages_append(arg->dpages, dentry, GFP_ATOMIC); ++ if (unlikely(arg->err)) ++ ret = D_WALK_QUIT; ++ } ++ ++ return ret; ++} ++ ++int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, ++ au_dpages_test test, void *arg) ++{ ++ struct ac_dpages_arg args = { ++ .err = 0, ++ .dpages = dpages, ++ .sb = root->d_sb, ++ .test = test, ++ .arg = arg ++ }; ++ ++ d_walk(root, &args, au_call_dpages_append, NULL); ++ ++ return args.err; ++} ++ ++int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, ++ int do_include, au_dpages_test test, void *arg) ++{ ++ int err; ++ ++ err = 0; ++ write_seqlock(&rename_lock); ++ spin_lock(&dentry->d_lock); ++ if (do_include ++ && au_dcount(dentry) > 0 ++ && (!test || test(dentry, arg))) ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ spin_unlock(&dentry->d_lock); ++ if (unlikely(err)) ++ goto out; ++ ++ /* ++ * RCU for vfsmount is unnecessary since this is a traverse in a single ++ * mount ++ */ ++ while (!IS_ROOT(dentry)) { ++ dentry = dentry->d_parent; /* rename_lock is locked */ ++ spin_lock(&dentry->d_lock); ++ if (au_dcount(dentry) > 0 ++ && (!test || test(dentry, arg))) ++ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); ++ spin_unlock(&dentry->d_lock); ++ if (unlikely(err)) ++ break; ++ } ++ ++out: ++ write_sequnlock(&rename_lock); ++ return err; ++} ++ ++static inline int au_dcsub_dpages_aufs(struct dentry *dentry, void *arg) ++{ ++ return au_di(dentry) && dentry->d_sb == arg; ++} ++ ++int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages, ++ struct dentry *dentry, int do_include) ++{ ++ return au_dcsub_pages_rev(dpages, dentry, do_include, ++ au_dcsub_dpages_aufs, dentry->d_sb); ++} ++ ++int au_test_subdir(struct dentry *d1, struct dentry *d2) ++{ ++ struct path path[2] = { ++ { ++ .dentry = d1 ++ }, ++ { ++ .dentry = d2 ++ } ++ }; ++ ++ return path_is_under(path + 0, path + 1); ++} +diff --git a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h +new file mode 100644 +index 0000000..3d18314 +--- /dev/null ++++ b/fs/aufs/dcsub.h +@@ -0,0 +1,112 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * sub-routines for dentry cache ++ */ ++ ++#ifndef __AUFS_DCSUB_H__ ++#define __AUFS_DCSUB_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++ ++struct dentry; ++ ++struct au_dpage { ++ int ndentry; ++ struct dentry **dentries; ++}; ++ ++struct au_dcsub_pages { ++ int ndpage; ++ struct au_dpage *dpages; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dcsub.c */ ++int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp); ++void au_dpages_free(struct au_dcsub_pages *dpages); ++typedef int (*au_dpages_test)(struct dentry *dentry, void *arg); ++int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, ++ au_dpages_test test, void *arg); ++int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, ++ int do_include, au_dpages_test test, void *arg); ++int au_dcsub_pages_rev_aufs(struct au_dcsub_pages *dpages, ++ struct dentry *dentry, int do_include); ++int au_test_subdir(struct dentry *d1, struct dentry *d2); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * todo: in linux-3.13, several similar (but faster) helpers are added to ++ * include/linux/dcache.h. Try them (in the future). ++ */ ++ ++static inline int au_d_hashed_positive(struct dentry *d) ++{ ++ int err; ++ struct inode *inode = d->d_inode; ++ ++ err = 0; ++ if (unlikely(d_unhashed(d) || !inode || !inode->i_nlink)) ++ err = -ENOENT; ++ return err; ++} ++ ++static inline int au_d_linkable(struct dentry *d) ++{ ++ int err; ++ struct inode *inode = d->d_inode; ++ ++ err = au_d_hashed_positive(d); ++ if (err ++ && inode ++ && (inode->i_state & I_LINKABLE)) ++ err = 0; ++ return err; ++} ++ ++static inline int au_d_alive(struct dentry *d) ++{ ++ int err; ++ struct inode *inode; ++ ++ err = 0; ++ if (!IS_ROOT(d)) ++ err = au_d_hashed_positive(d); ++ else { ++ inode = d->d_inode; ++ if (unlikely(d_unlinked(d) || !inode || !inode->i_nlink)) ++ err = -ENOENT; ++ } ++ return err; ++} ++ ++static inline int au_alive_dir(struct dentry *d) ++{ ++ int err; ++ ++ err = au_d_alive(d); ++ if (unlikely(err || IS_DEADDIR(d->d_inode))) ++ err = -ENOENT; ++ return err; ++} ++ ++static inline int au_qstreq(struct qstr *a, struct qstr *b) ++{ ++ return a->len == b->len ++ && !memcmp(a->name, b->name, a->len); ++} ++ ++static inline int au_dcount(struct dentry *d) ++{ ++ return (int)d_count(d); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DCSUB_H__ */ +diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c +new file mode 100644 +index 0000000..b60f242 +--- /dev/null ++++ b/fs/aufs/debug.c +@@ -0,0 +1,509 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * debug print functions ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* Returns 0, or -errno. arg is in kp->arg. */ ++static int param_atomic_t_set(const char *val, const struct kernel_param *kp) ++{ ++ int err, n; ++ ++ err = kstrtoint(val, 0, &n); ++ if (!err) { ++ if (n > 0) ++ au_debug_on(); ++ else ++ au_debug_off(); ++ } ++ return err; ++} ++ ++/* Returns length written or -errno. Buffer is 4k (ie. be short!) */ ++static int param_atomic_t_get(char *buffer, const struct kernel_param *kp) ++{ ++ atomic_t *a; ++ ++ a = kp->arg; ++ return sprintf(buffer, "%d", atomic_read(a)); ++} ++ ++static struct kernel_param_ops param_ops_atomic_t = { ++ .set = param_atomic_t_set, ++ .get = param_atomic_t_get ++ /* void (*free)(void *arg) */ ++}; ++ ++atomic_t aufs_debug = ATOMIC_INIT(0); ++MODULE_PARM_DESC(debug, "debug print"); ++module_param_named(debug, aufs_debug, atomic_t, S_IRUGO | S_IWUSR | S_IWGRP); ++ ++DEFINE_MUTEX(au_dbg_mtx); /* just to serialize the dbg msgs */ ++char *au_plevel = KERN_DEBUG; ++#define dpri(fmt, ...) do { \ ++ if ((au_plevel \ ++ && strcmp(au_plevel, KERN_DEBUG)) \ ++ || au_debug_test()) \ ++ printk("%s" fmt, au_plevel, ##__VA_ARGS__); \ ++} while (0) ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dpri_whlist(struct au_nhash *whlist) ++{ ++ unsigned long ul, n; ++ struct hlist_head *head; ++ struct au_vdir_wh *pos; ++ ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (ul = 0; ul < n; ul++) { ++ hlist_for_each_entry(pos, head, wh_hash) ++ dpri("b%d, %.*s, %d\n", ++ pos->wh_bindex, ++ pos->wh_str.len, pos->wh_str.name, ++ pos->wh_str.len); ++ head++; ++ } ++} ++ ++void au_dpri_vdir(struct au_vdir *vdir) ++{ ++ unsigned long ul; ++ union au_vdir_deblk_p p; ++ unsigned char *o; ++ ++ if (!vdir || IS_ERR(vdir)) { ++ dpri("err %ld\n", PTR_ERR(vdir)); ++ return; ++ } ++ ++ dpri("deblk %u, nblk %lu, deblk %p, last{%lu, %p}, ver %lu\n", ++ vdir->vd_deblk_sz, vdir->vd_nblk, vdir->vd_deblk, ++ vdir->vd_last.ul, vdir->vd_last.p.deblk, vdir->vd_version); ++ for (ul = 0; ul < vdir->vd_nblk; ul++) { ++ p.deblk = vdir->vd_deblk[ul]; ++ o = p.deblk; ++ dpri("[%lu]: %p\n", ul, o); ++ } ++} ++ ++static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, int hn, ++ struct dentry *wh) ++{ ++ char *n = NULL; ++ int l = 0; ++ ++ if (!inode || IS_ERR(inode)) { ++ dpri("i%d: err %ld\n", bindex, PTR_ERR(inode)); ++ return -1; ++ } ++ ++ /* the type of i_blocks depends upon CONFIG_LBDAF */ ++ BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) ++ && sizeof(inode->i_blocks) != sizeof(u64)); ++ if (wh) { ++ n = (void *)wh->d_name.name; ++ l = wh->d_name.len; ++ } ++ ++ dpri("i%d: %p, i%lu, %s, cnt %d, nl %u, 0%o, sz %llu, blk %llu," ++ " hn %d, ct %lld, np %lu, st 0x%lx, f 0x%x, v %llu, g %x%s%.*s\n", ++ bindex, inode, ++ inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", ++ atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, ++ i_size_read(inode), (unsigned long long)inode->i_blocks, ++ hn, (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff, ++ inode->i_mapping ? inode->i_mapping->nrpages : 0, ++ inode->i_state, inode->i_flags, inode->i_version, ++ inode->i_generation, ++ l ? ", wh " : "", l, n); ++ return 0; ++} ++ ++void au_dpri_inode(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ aufs_bindex_t bindex; ++ int err, hn; ++ ++ err = do_pri_inode(-1, inode, -1, NULL); ++ if (err || !au_test_aufs(inode->i_sb)) ++ return; ++ ++ iinfo = au_ii(inode); ++ if (!iinfo) ++ return; ++ dpri("i-1: bstart %d, bend %d, gen %d\n", ++ iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode, NULL)); ++ if (iinfo->ii_bstart < 0) ++ return; ++ hn = 0; ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) { ++ hn = !!au_hn(iinfo->ii_hinode + bindex); ++ do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, hn, ++ iinfo->ii_hinode[0 + bindex].hi_whdentry); ++ } ++} ++ ++void au_dpri_dalias(struct inode *inode) ++{ ++ struct dentry *d; ++ ++ spin_lock(&inode->i_lock); ++ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) ++ au_dpri_dentry(d); ++ spin_unlock(&inode->i_lock); ++} ++ ++static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry) ++{ ++ struct dentry *wh = NULL; ++ int hn; ++ struct au_iinfo *iinfo; ++ ++ if (!dentry || IS_ERR(dentry)) { ++ dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); ++ return -1; ++ } ++ /* do not call dget_parent() here */ ++ /* note: access d_xxx without d_lock */ ++ dpri("d%d: %p, %pd2?, %s, cnt %d, flags 0x%x, %shashed\n", ++ bindex, dentry, dentry, ++ dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", ++ au_dcount(dentry), dentry->d_flags, ++ d_unhashed(dentry) ? "un" : ""); ++ hn = -1; ++ if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) { ++ iinfo = au_ii(dentry->d_inode); ++ if (iinfo) { ++ hn = !!au_hn(iinfo->ii_hinode + bindex); ++ wh = iinfo->ii_hinode[0 + bindex].hi_whdentry; ++ } ++ } ++ do_pri_inode(bindex, dentry->d_inode, hn, wh); ++ return 0; ++} ++ ++void au_dpri_dentry(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ aufs_bindex_t bindex; ++ int err; ++ struct au_hdentry *hdp; ++ ++ err = do_pri_dentry(-1, dentry); ++ if (err || !au_test_aufs(dentry->d_sb)) ++ return; ++ ++ dinfo = au_di(dentry); ++ if (!dinfo) ++ return; ++ dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d, tmp %d\n", ++ dinfo->di_bstart, dinfo->di_bend, ++ dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry), ++ dinfo->di_tmpfile); ++ if (dinfo->di_bstart < 0) ++ return; ++ hdp = dinfo->di_hdentry; ++ for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++) ++ do_pri_dentry(bindex, hdp[0 + bindex].hd_dentry); ++} ++ ++static int do_pri_file(aufs_bindex_t bindex, struct file *file) ++{ ++ char a[32]; ++ ++ if (!file || IS_ERR(file)) { ++ dpri("f%d: err %ld\n", bindex, PTR_ERR(file)); ++ return -1; ++ } ++ a[0] = 0; ++ if (bindex < 0 ++ && file->f_path.dentry ++ && au_test_aufs(file->f_path.dentry->d_sb) ++ && au_fi(file)) ++ snprintf(a, sizeof(a), ", gen %d, mmapped %d", ++ au_figen(file), atomic_read(&au_fi(file)->fi_mmapped)); ++ dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, v %llu, pos %llu%s\n", ++ bindex, file->f_mode, file->f_flags, (long)file_count(file), ++ file->f_version, file->f_pos, a); ++ if (file->f_path.dentry) ++ do_pri_dentry(bindex, file->f_path.dentry); ++ return 0; ++} ++ ++void au_dpri_file(struct file *file) ++{ ++ struct au_finfo *finfo; ++ struct au_fidir *fidir; ++ struct au_hfile *hfile; ++ aufs_bindex_t bindex; ++ int err; ++ ++ err = do_pri_file(-1, file); ++ if (err ++ || !file->f_path.dentry ++ || !au_test_aufs(file->f_path.dentry->d_sb)) ++ return; ++ ++ finfo = au_fi(file); ++ if (!finfo) ++ return; ++ if (finfo->fi_btop < 0) ++ return; ++ fidir = finfo->fi_hdir; ++ if (!fidir) ++ do_pri_file(finfo->fi_btop, finfo->fi_htop.hf_file); ++ else ++ for (bindex = finfo->fi_btop; ++ bindex >= 0 && bindex <= fidir->fd_bbot; ++ bindex++) { ++ hfile = fidir->fd_hfile + bindex; ++ do_pri_file(bindex, hfile ? hfile->hf_file : NULL); ++ } ++} ++ ++static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br) ++{ ++ struct vfsmount *mnt; ++ struct super_block *sb; ++ ++ if (!br || IS_ERR(br)) ++ goto out; ++ mnt = au_br_mnt(br); ++ if (!mnt || IS_ERR(mnt)) ++ goto out; ++ sb = mnt->mnt_sb; ++ if (!sb || IS_ERR(sb)) ++ goto out; ++ ++ dpri("s%d: {perm 0x%x, id %d, cnt %d, wbr %p}, " ++ "%s, dev 0x%02x%02x, flags 0x%lx, cnt %d, active %d, " ++ "xino %d\n", ++ bindex, br->br_perm, br->br_id, atomic_read(&br->br_count), ++ br->br_wbr, au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev), ++ sb->s_flags, sb->s_count, ++ atomic_read(&sb->s_active), !!br->br_xino.xi_file); ++ return 0; ++ ++out: ++ dpri("s%d: err %ld\n", bindex, PTR_ERR(br)); ++ return -1; ++} ++ ++void au_dpri_sb(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ aufs_bindex_t bindex; ++ int err; ++ /* to reuduce stack size */ ++ struct { ++ struct vfsmount mnt; ++ struct au_branch fake; ++ } *a; ++ ++ /* this function can be called from magic sysrq */ ++ a = kzalloc(sizeof(*a), GFP_ATOMIC); ++ if (unlikely(!a)) { ++ dpri("no memory\n"); ++ return; ++ } ++ ++ a->mnt.mnt_sb = sb; ++ a->fake.br_perm = 0; ++ a->fake.br_path.mnt = &a->mnt; ++ a->fake.br_xino.xi_file = NULL; ++ atomic_set(&a->fake.br_count, 0); ++ smp_mb(); /* atomic_set */ ++ err = do_pri_br(-1, &a->fake); ++ kfree(a); ++ dpri("dev 0x%x\n", sb->s_dev); ++ if (err || !au_test_aufs(sb)) ++ return; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ dpri("nw %d, gen %u, kobj %d\n", ++ atomic_read(&sbinfo->si_nowait.nw_len), sbinfo->si_generation, ++ atomic_read(&sbinfo->si_kobj.kref.refcount)); ++ for (bindex = 0; bindex <= sbinfo->si_bend; bindex++) ++ do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_dbg_sleep_jiffy(int jiffy) ++{ ++ while (jiffy) ++ jiffy = schedule_timeout_uninterruptible(jiffy); ++} ++ ++void au_dbg_iattr(struct iattr *ia) ++{ ++#define AuBit(name) \ ++ do { \ ++ if (ia->ia_valid & ATTR_ ## name) \ ++ dpri(#name "\n"); \ ++ } while (0) ++ AuBit(MODE); ++ AuBit(UID); ++ AuBit(GID); ++ AuBit(SIZE); ++ AuBit(ATIME); ++ AuBit(MTIME); ++ AuBit(CTIME); ++ AuBit(ATIME_SET); ++ AuBit(MTIME_SET); ++ AuBit(FORCE); ++ AuBit(ATTR_FLAG); ++ AuBit(KILL_SUID); ++ AuBit(KILL_SGID); ++ AuBit(FILE); ++ AuBit(KILL_PRIV); ++ AuBit(OPEN); ++ AuBit(TIMES_SET); ++#undef AuBit ++ dpri("ia_file %p\n", ia->ia_file); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line) ++{ ++ struct inode *h_inode, *inode = dentry->d_inode; ++ struct dentry *h_dentry; ++ aufs_bindex_t bindex, bend, bi; ++ ++ if (!inode /* || au_di(dentry)->di_lsc == AuLsc_DI_TMP */) ++ return; ++ ++ bend = au_dbend(dentry); ++ bi = au_ibend(inode); ++ if (bi < bend) ++ bend = bi; ++ bindex = au_dbstart(dentry); ++ bi = au_ibstart(inode); ++ if (bi > bindex) ++ bindex = bi; ++ ++ for (; bindex <= bend; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ h_inode = au_h_iptr(inode, bindex); ++ if (unlikely(h_inode != h_dentry->d_inode)) { ++ au_debug_on(); ++ AuDbg("b%d, %s:%d\n", bindex, func, line); ++ AuDbgDentry(dentry); ++ AuDbgInode(inode); ++ au_debug_off(); ++ BUG(); ++ } ++ } ++} ++ ++void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen) ++{ ++ struct dentry *parent; ++ ++ parent = dget_parent(dentry); ++ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode)); ++ AuDebugOn(IS_ROOT(dentry)); ++ AuDebugOn(au_digen_test(parent, sigen)); ++ dput(parent); ++} ++ ++void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen) ++{ ++ struct dentry *parent; ++ struct inode *inode; ++ ++ parent = dget_parent(dentry); ++ inode = dentry->d_inode; ++ AuDebugOn(inode && S_ISDIR(dentry->d_inode->i_mode)); ++ AuDebugOn(au_digen_test(parent, sigen)); ++ dput(parent); ++} ++ ++void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen) ++{ ++ int err, i, j; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ AuDebugOn(err); ++ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/1); ++ AuDebugOn(err); ++ for (i = dpages.ndpage - 1; !err && i >= 0; i--) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ for (j = dpage->ndentry - 1; !err && j >= 0; j--) ++ AuDebugOn(au_digen_test(dentries[j], sigen)); ++ } ++ au_dpages_free(&dpages); ++} ++ ++void au_dbg_verify_kthread(void) ++{ ++ if (au_wkq_test()) { ++ au_dbg_blocked(); ++ /* ++ * It may be recursive, but udba=notify between two aufs mounts, ++ * where a single ro branch is shared, is not a problem. ++ */ ++ /* WARN_ON(1); */ ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_debug_sbinfo_init(struct au_sbinfo *sbinfo __maybe_unused) ++{ ++#ifdef AuForceNoPlink ++ au_opt_clr(sbinfo->si_mntflags, PLINK); ++#endif ++#ifdef AuForceNoXino ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++#endif ++#ifdef AuForceNoRefrof ++ au_opt_clr(sbinfo->si_mntflags, REFROF); ++#endif ++#ifdef AuForceHnotify ++ au_opt_set_udba(sbinfo->si_mntflags, UDBA_HNOTIFY); ++#endif ++#ifdef AuForceRd0 ++ sbinfo->si_rdblk = 0; ++ sbinfo->si_rdhash = 0; ++#endif ++} ++ ++int __init au_debug_init(void) ++{ ++ aufs_bindex_t bindex; ++ struct au_vdir_destr destr; ++ ++ bindex = -1; ++ AuDebugOn(bindex >= 0); ++ ++ destr.len = -1; ++ AuDebugOn(destr.len < NAME_MAX); ++ ++#ifdef CONFIG_4KSTACKS ++ pr_warn("CONFIG_4KSTACKS is defined.\n"); ++#endif ++ ++#ifdef AuForceNoBrs ++ sysaufs_brs = 0; ++#endif ++ ++ return 0; ++} +diff --git a/fs/aufs/debug.h b/fs/aufs/debug.h +new file mode 100644 +index 0000000..67a34f7 +--- /dev/null ++++ b/fs/aufs/debug.h +@@ -0,0 +1,249 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * debug print functions ++ */ ++ ++#ifndef __AUFS_DEBUG_H__ ++#define __AUFS_DEBUG_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_AUFS_DEBUG ++#define AuDebugOn(a) BUG_ON(a) ++ ++/* module parameter */ ++extern atomic_t aufs_debug; ++static inline void au_debug_on(void) ++{ ++ atomic_inc(&aufs_debug); ++} ++static inline void au_debug_off(void) ++{ ++ atomic_dec_if_positive(&aufs_debug); ++} ++ ++static inline int au_debug_test(void) ++{ ++ return atomic_read(&aufs_debug) > 0; ++} ++#else ++#define AuDebugOn(a) do {} while (0) ++AuStubVoid(au_debug_on, void) ++AuStubVoid(au_debug_off, void) ++AuStubInt0(au_debug_test, void) ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++#define param_check_atomic_t(name, p) __param_check(name, p, atomic_t) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* debug print */ ++ ++#define AuDbg(fmt, ...) do { \ ++ if (au_debug_test()) \ ++ pr_debug("DEBUG: " fmt, ##__VA_ARGS__); \ ++} while (0) ++#define AuLabel(l) AuDbg(#l "\n") ++#define AuIOErr(fmt, ...) pr_err("I/O Error, " fmt, ##__VA_ARGS__) ++#define AuWarn1(fmt, ...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ pr_warn(fmt, ##__VA_ARGS__); \ ++} while (0) ++ ++#define AuErr1(fmt, ...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ pr_err(fmt, ##__VA_ARGS__); \ ++} while (0) ++ ++#define AuIOErr1(fmt, ...) do { \ ++ static unsigned char _c; \ ++ if (!_c++) \ ++ AuIOErr(fmt, ##__VA_ARGS__); \ ++} while (0) ++ ++#define AuUnsupportMsg "This operation is not supported." \ ++ " Please report this application to aufs-users ML." ++#define AuUnsupport(fmt, ...) do { \ ++ pr_err(AuUnsupportMsg "\n" fmt, ##__VA_ARGS__); \ ++ dump_stack(); \ ++} while (0) ++ ++#define AuTraceErr(e) do { \ ++ if (unlikely((e) < 0)) \ ++ AuDbg("err %d\n", (int)(e)); \ ++} while (0) ++ ++#define AuTraceErrPtr(p) do { \ ++ if (IS_ERR(p)) \ ++ AuDbg("err %ld\n", PTR_ERR(p)); \ ++} while (0) ++ ++/* dirty macros for debug print, use with "%.*s" and caution */ ++#define AuLNPair(qstr) (qstr)->len, (qstr)->name ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_sbinfo; ++struct au_finfo; ++struct dentry; ++#ifdef CONFIG_AUFS_DEBUG ++extern struct mutex au_dbg_mtx; ++extern char *au_plevel; ++struct au_nhash; ++void au_dpri_whlist(struct au_nhash *whlist); ++struct au_vdir; ++void au_dpri_vdir(struct au_vdir *vdir); ++struct inode; ++void au_dpri_inode(struct inode *inode); ++void au_dpri_dalias(struct inode *inode); ++void au_dpri_dentry(struct dentry *dentry); ++struct file; ++void au_dpri_file(struct file *filp); ++struct super_block; ++void au_dpri_sb(struct super_block *sb); ++ ++void au_dbg_sleep_jiffy(int jiffy); ++struct iattr; ++void au_dbg_iattr(struct iattr *ia); ++ ++#define au_dbg_verify_dinode(d) __au_dbg_verify_dinode(d, __func__, __LINE__) ++void __au_dbg_verify_dinode(struct dentry *dentry, const char *func, int line); ++void au_dbg_verify_dir_parent(struct dentry *dentry, unsigned int sigen); ++void au_dbg_verify_nondir_parent(struct dentry *dentry, unsigned int sigen); ++void au_dbg_verify_gen(struct dentry *parent, unsigned int sigen); ++void au_dbg_verify_kthread(void); ++ ++int __init au_debug_init(void); ++void au_debug_sbinfo_init(struct au_sbinfo *sbinfo); ++#define AuDbgWhlist(w) do { \ ++ mutex_lock(&au_dbg_mtx); \ ++ AuDbg(#w "\n"); \ ++ au_dpri_whlist(w); \ ++ mutex_unlock(&au_dbg_mtx); \ ++} while (0) ++ ++#define AuDbgVdir(v) do { \ ++ mutex_lock(&au_dbg_mtx); \ ++ AuDbg(#v "\n"); \ ++ au_dpri_vdir(v); \ ++ mutex_unlock(&au_dbg_mtx); \ ++} while (0) ++ ++#define AuDbgInode(i) do { \ ++ mutex_lock(&au_dbg_mtx); \ ++ AuDbg(#i "\n"); \ ++ au_dpri_inode(i); \ ++ mutex_unlock(&au_dbg_mtx); \ ++} while (0) ++ ++#define AuDbgDAlias(i) do { \ ++ mutex_lock(&au_dbg_mtx); \ ++ AuDbg(#i "\n"); \ ++ au_dpri_dalias(i); \ ++ mutex_unlock(&au_dbg_mtx); \ ++} while (0) ++ ++#define AuDbgDentry(d) do { \ ++ mutex_lock(&au_dbg_mtx); \ ++ AuDbg(#d "\n"); \ ++ au_dpri_dentry(d); \ ++ mutex_unlock(&au_dbg_mtx); \ ++} while (0) ++ ++#define AuDbgFile(f) do { \ ++ mutex_lock(&au_dbg_mtx); \ ++ AuDbg(#f "\n"); \ ++ au_dpri_file(f); \ ++ mutex_unlock(&au_dbg_mtx); \ ++} while (0) ++ ++#define AuDbgSb(sb) do { \ ++ mutex_lock(&au_dbg_mtx); \ ++ AuDbg(#sb "\n"); \ ++ au_dpri_sb(sb); \ ++ mutex_unlock(&au_dbg_mtx); \ ++} while (0) ++ ++#define AuDbgSleep(sec) do { \ ++ AuDbg("sleep %d sec\n", sec); \ ++ ssleep(sec); \ ++} while (0) ++ ++#define AuDbgSleepJiffy(jiffy) do { \ ++ AuDbg("sleep %d jiffies\n", jiffy); \ ++ au_dbg_sleep_jiffy(jiffy); \ ++} while (0) ++ ++#define AuDbgIAttr(ia) do { \ ++ AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \ ++ au_dbg_iattr(ia); \ ++} while (0) ++ ++#define AuDbgSym(addr) do { \ ++ char sym[KSYM_SYMBOL_LEN]; \ ++ sprint_symbol(sym, (unsigned long)addr); \ ++ AuDbg("%s\n", sym); \ ++} while (0) ++ ++#define AuInfoSym(addr) do { \ ++ char sym[KSYM_SYMBOL_LEN]; \ ++ sprint_symbol(sym, (unsigned long)addr); \ ++ AuInfo("%s\n", sym); \ ++} while (0) ++#else ++AuStubVoid(au_dbg_verify_dinode, struct dentry *dentry) ++AuStubVoid(au_dbg_verify_dir_parent, struct dentry *dentry, unsigned int sigen) ++AuStubVoid(au_dbg_verify_nondir_parent, struct dentry *dentry, ++ unsigned int sigen) ++AuStubVoid(au_dbg_verify_gen, struct dentry *parent, unsigned int sigen) ++AuStubVoid(au_dbg_verify_kthread, void) ++AuStubInt0(__init au_debug_init, void) ++AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo) ++ ++#define AuDbgWhlist(w) do {} while (0) ++#define AuDbgVdir(v) do {} while (0) ++#define AuDbgInode(i) do {} while (0) ++#define AuDbgDAlias(i) do {} while (0) ++#define AuDbgDentry(d) do {} while (0) ++#define AuDbgFile(f) do {} while (0) ++#define AuDbgSb(sb) do {} while (0) ++#define AuDbgSleep(sec) do {} while (0) ++#define AuDbgSleepJiffy(jiffy) do {} while (0) ++#define AuDbgIAttr(ia) do {} while (0) ++#define AuDbgSym(addr) do {} while (0) ++#define AuInfoSym(addr) do {} while (0) ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_MAGIC_SYSRQ ++int __init au_sysrq_init(void); ++void au_sysrq_fin(void); ++ ++#ifdef CONFIG_HW_CONSOLE ++#define au_dbg_blocked() do { \ ++ WARN_ON(1); \ ++ handle_sysrq('w'); \ ++} while (0) ++#else ++AuStubVoid(au_dbg_blocked, void) ++#endif ++ ++#else ++AuStubInt0(__init au_sysrq_init, void) ++AuStubVoid(au_sysrq_fin, void) ++AuStubVoid(au_dbg_blocked, void) ++#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DEBUG_H__ */ +diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c +new file mode 100644 +index 0000000..dd7514b +--- /dev/null ++++ b/fs/aufs/dentry.c +@@ -0,0 +1,1083 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * lookup and dentry operations ++ */ ++ ++#include ++#include "aufs.h" ++ ++#define AuLkup_ALLOW_NEG 1 ++#define AuLkup_IGNORE_PERM (1 << 1) ++#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) ++#define au_fset_lkup(flags, name) \ ++ do { (flags) |= AuLkup_##name; } while (0) ++#define au_fclr_lkup(flags, name) \ ++ do { (flags) &= ~AuLkup_##name; } while (0) ++ ++struct au_do_lookup_args { ++ unsigned int flags; ++ mode_t type; ++}; ++ ++/* ++ * returns positive/negative dentry, NULL or an error. ++ * NULL means whiteout-ed or not-found. ++ */ ++static struct dentry* ++au_do_lookup(struct dentry *h_parent, struct dentry *dentry, ++ aufs_bindex_t bindex, struct qstr *wh_name, ++ struct au_do_lookup_args *args) ++{ ++ struct dentry *h_dentry; ++ struct inode *h_inode, *inode; ++ struct au_branch *br; ++ int wh_found, opq; ++ unsigned char wh_able; ++ const unsigned char allow_neg = !!au_ftest_lkup(args->flags, ALLOW_NEG); ++ const unsigned char ignore_perm = !!au_ftest_lkup(args->flags, ++ IGNORE_PERM); ++ ++ wh_found = 0; ++ br = au_sbr(dentry->d_sb, bindex); ++ wh_able = !!au_br_whable(br->br_perm); ++ if (wh_able) ++ wh_found = au_wh_test(h_parent, wh_name, /*try_sio*/0); ++ h_dentry = ERR_PTR(wh_found); ++ if (!wh_found) ++ goto real_lookup; ++ if (unlikely(wh_found < 0)) ++ goto out; ++ ++ /* We found a whiteout */ ++ /* au_set_dbend(dentry, bindex); */ ++ au_set_dbwh(dentry, bindex); ++ if (!allow_neg) ++ return NULL; /* success */ ++ ++real_lookup: ++ if (!ignore_perm) ++ h_dentry = vfsub_lkup_one(&dentry->d_name, h_parent); ++ else ++ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent); ++ if (IS_ERR(h_dentry)) ++ goto out; ++ ++ h_inode = h_dentry->d_inode; ++ if (!h_inode) { ++ if (!allow_neg) ++ goto out_neg; ++ } else if (wh_found ++ || (args->type && args->type != (h_inode->i_mode & S_IFMT))) ++ goto out_neg; ++ ++ if (au_dbend(dentry) <= bindex) ++ au_set_dbend(dentry, bindex); ++ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) ++ au_set_dbstart(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, h_dentry); ++ ++ inode = dentry->d_inode; ++ if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able ++ || (inode && !S_ISDIR(inode->i_mode))) ++ goto out; /* success */ ++ ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ opq = au_diropq_test(h_dentry); ++ mutex_unlock(&h_inode->i_mutex); ++ if (opq > 0) ++ au_set_dbdiropq(dentry, bindex); ++ else if (unlikely(opq < 0)) { ++ au_set_h_dptr(dentry, bindex, NULL); ++ h_dentry = ERR_PTR(opq); ++ } ++ goto out; ++ ++out_neg: ++ dput(h_dentry); ++ h_dentry = NULL; ++out: ++ return h_dentry; ++} ++ ++static int au_test_shwh(struct super_block *sb, const struct qstr *name) ++{ ++ if (unlikely(!au_opt_test(au_mntflags(sb), SHWH) ++ && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))) ++ return -EPERM; ++ return 0; ++} ++ ++/* ++ * returns the number of lower positive dentries, ++ * otherwise an error. ++ * can be called at unlinking with @type is zero. ++ */ ++int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type) ++{ ++ int npositive, err; ++ aufs_bindex_t bindex, btail, bdiropq; ++ unsigned char isdir, dirperm1; ++ struct qstr whname; ++ struct au_do_lookup_args args = { ++ .flags = 0, ++ .type = type ++ }; ++ const struct qstr *name = &dentry->d_name; ++ struct dentry *parent; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ err = au_test_shwh(sb, name); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_wh_name_alloc(&whname, name); ++ if (unlikely(err)) ++ goto out; ++ ++ inode = dentry->d_inode; ++ isdir = !!(inode && S_ISDIR(inode->i_mode)); ++ if (!type) ++ au_fset_lkup(args.flags, ALLOW_NEG); ++ dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1); ++ ++ npositive = 0; ++ parent = dget_parent(dentry); ++ btail = au_dbtaildir(parent); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ struct dentry *h_parent, *h_dentry; ++ struct inode *h_inode, *h_dir; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry) { ++ if (h_dentry->d_inode) ++ npositive++; ++ if (type != S_IFDIR) ++ break; ++ continue; ++ } ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent) ++ continue; ++ h_dir = h_parent->d_inode; ++ if (!h_dir || !S_ISDIR(h_dir->i_mode)) ++ continue; ++ ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname, ++ &args); ++ mutex_unlock(&h_dir->i_mutex); ++ err = PTR_ERR(h_dentry); ++ if (IS_ERR(h_dentry)) ++ goto out_parent; ++ au_fclr_lkup(args.flags, ALLOW_NEG); ++ if (dirperm1) ++ au_fset_lkup(args.flags, IGNORE_PERM); ++ ++ if (au_dbwh(dentry) >= 0) ++ break; ++ if (!h_dentry) ++ continue; ++ h_inode = h_dentry->d_inode; ++ if (!h_inode) ++ continue; ++ npositive++; ++ if (!args.type) ++ args.type = h_inode->i_mode & S_IFMT; ++ if (args.type != S_IFDIR) ++ break; ++ else if (isdir) { ++ /* the type of lower may be different */ ++ bdiropq = au_dbdiropq(dentry); ++ if (bdiropq >= 0 && bdiropq <= bindex) ++ break; ++ } ++ } ++ ++ if (npositive) { ++ AuLabel(positive); ++ au_update_dbstart(dentry); ++ } ++ err = npositive; ++ if (unlikely(!au_opt_test(au_mntflags(sb), UDBA_NONE) ++ && au_dbstart(dentry) < 0)) { ++ err = -EIO; ++ AuIOErr("both of real entry and whiteout found, %pd, err %d\n", ++ dentry, err); ++ } ++ ++out_parent: ++ dput(parent); ++ kfree(whname.name); ++out: ++ return err; ++} ++ ++struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent) ++{ ++ struct dentry *dentry; ++ int wkq_err; ++ ++ if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC)) ++ dentry = vfsub_lkup_one(name, parent); ++ else { ++ struct vfsub_lkup_one_args args = { ++ .errp = &dentry, ++ .name = name, ++ .parent = parent ++ }; ++ ++ wkq_err = au_wkq_wait(vfsub_call_lkup_one, &args); ++ if (unlikely(wkq_err)) ++ dentry = ERR_PTR(wkq_err); ++ } ++ ++ return dentry; ++} ++ ++/* ++ * lookup @dentry on @bindex which should be negative. ++ */ ++int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh) ++{ ++ int err; ++ struct dentry *parent, *h_parent, *h_dentry; ++ struct au_branch *br; ++ ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bindex); ++ br = au_sbr(dentry->d_sb, bindex); ++ if (wh) ++ h_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); ++ else ++ h_dentry = au_sio_lkup_one(&dentry->d_name, h_parent); ++ err = PTR_ERR(h_dentry); ++ if (IS_ERR(h_dentry)) ++ goto out; ++ if (unlikely(h_dentry->d_inode)) { ++ err = -EIO; ++ AuIOErr("%pd should be negative on b%d.\n", h_dentry, bindex); ++ dput(h_dentry); ++ goto out; ++ } ++ ++ err = 0; ++ if (bindex < au_dbstart(dentry)) ++ au_set_dbstart(dentry, bindex); ++ if (au_dbend(dentry) < bindex) ++ au_set_dbend(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, h_dentry); ++ ++out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* subset of struct inode */ ++struct au_iattr { ++ unsigned long i_ino; ++ /* unsigned int i_nlink; */ ++ kuid_t i_uid; ++ kgid_t i_gid; ++ u64 i_version; ++/* ++ loff_t i_size; ++ blkcnt_t i_blocks; ++*/ ++ umode_t i_mode; ++}; ++ ++static void au_iattr_save(struct au_iattr *ia, struct inode *h_inode) ++{ ++ ia->i_ino = h_inode->i_ino; ++ /* ia->i_nlink = h_inode->i_nlink; */ ++ ia->i_uid = h_inode->i_uid; ++ ia->i_gid = h_inode->i_gid; ++ ia->i_version = h_inode->i_version; ++/* ++ ia->i_size = h_inode->i_size; ++ ia->i_blocks = h_inode->i_blocks; ++*/ ++ ia->i_mode = (h_inode->i_mode & S_IFMT); ++} ++ ++static int au_iattr_test(struct au_iattr *ia, struct inode *h_inode) ++{ ++ return ia->i_ino != h_inode->i_ino ++ /* || ia->i_nlink != h_inode->i_nlink */ ++ || !uid_eq(ia->i_uid, h_inode->i_uid) ++ || !gid_eq(ia->i_gid, h_inode->i_gid) ++ || ia->i_version != h_inode->i_version ++/* ++ || ia->i_size != h_inode->i_size ++ || ia->i_blocks != h_inode->i_blocks ++*/ ++ || ia->i_mode != (h_inode->i_mode & S_IFMT); ++} ++ ++static int au_h_verify_dentry(struct dentry *h_dentry, struct dentry *h_parent, ++ struct au_branch *br) ++{ ++ int err; ++ struct au_iattr ia; ++ struct inode *h_inode; ++ struct dentry *h_d; ++ struct super_block *h_sb; ++ ++ err = 0; ++ memset(&ia, -1, sizeof(ia)); ++ h_sb = h_dentry->d_sb; ++ h_inode = h_dentry->d_inode; ++ if (h_inode) ++ au_iattr_save(&ia, h_inode); ++ else if (au_test_nfs(h_sb) || au_test_fuse(h_sb)) ++ /* nfs d_revalidate may return 0 for negative dentry */ ++ /* fuse d_revalidate always return 0 for negative dentry */ ++ goto out; ++ ++ /* main purpose is namei.c:cached_lookup() and d_revalidate */ ++ h_d = vfsub_lkup_one(&h_dentry->d_name, h_parent); ++ err = PTR_ERR(h_d); ++ if (IS_ERR(h_d)) ++ goto out; ++ ++ err = 0; ++ if (unlikely(h_d != h_dentry ++ || h_d->d_inode != h_inode ++ || (h_inode && au_iattr_test(&ia, h_inode)))) ++ err = au_busy_or_stale(); ++ dput(h_d); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, ++ struct dentry *h_parent, struct au_branch *br) ++{ ++ int err; ++ ++ err = 0; ++ if (udba == AuOpt_UDBA_REVAL ++ && !au_test_fs_remote(h_dentry->d_sb)) { ++ IMustLock(h_dir); ++ err = (h_dentry->d_parent->d_inode != h_dir); ++ } else if (udba != AuOpt_UDBA_NONE) ++ err = au_h_verify_dentry(h_dentry, h_parent, br); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent) ++{ ++ int err; ++ aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq; ++ struct au_hdentry tmp, *p, *q; ++ struct au_dinfo *dinfo; ++ struct super_block *sb; ++ ++ DiMustWriteLock(dentry); ++ ++ sb = dentry->d_sb; ++ dinfo = au_di(dentry); ++ bend = dinfo->di_bend; ++ bwh = dinfo->di_bwh; ++ bdiropq = dinfo->di_bdiropq; ++ p = dinfo->di_hdentry + dinfo->di_bstart; ++ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) { ++ if (!p->hd_dentry) ++ continue; ++ ++ new_bindex = au_br_index(sb, p->hd_id); ++ if (new_bindex == bindex) ++ continue; ++ ++ if (dinfo->di_bwh == bindex) ++ bwh = new_bindex; ++ if (dinfo->di_bdiropq == bindex) ++ bdiropq = new_bindex; ++ if (new_bindex < 0) { ++ au_hdput(p); ++ p->hd_dentry = NULL; ++ continue; ++ } ++ ++ /* swap two lower dentries, and loop again */ ++ q = dinfo->di_hdentry + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hd_dentry) { ++ bindex--; ++ p--; ++ } ++ } ++ ++ dinfo->di_bwh = -1; ++ if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh)) ++ dinfo->di_bwh = bwh; ++ ++ dinfo->di_bdiropq = -1; ++ if (bdiropq >= 0 ++ && bdiropq <= au_sbend(sb) ++ && au_sbr_whable(sb, bdiropq)) ++ dinfo->di_bdiropq = bdiropq; ++ ++ err = -EIO; ++ dinfo->di_bstart = -1; ++ dinfo->di_bend = -1; ++ bend = au_dbend(parent); ++ p = dinfo->di_hdentry; ++ for (bindex = 0; bindex <= bend; bindex++, p++) ++ if (p->hd_dentry) { ++ dinfo->di_bstart = bindex; ++ break; ++ } ++ ++ if (dinfo->di_bstart >= 0) { ++ p = dinfo->di_hdentry + bend; ++ for (bindex = bend; bindex >= 0; bindex--, p--) ++ if (p->hd_dentry) { ++ dinfo->di_bend = bindex; ++ err = 0; ++ break; ++ } ++ } ++ ++ return err; ++} ++ ++static void au_do_hide(struct dentry *dentry) ++{ ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ if (inode) { ++ if (!S_ISDIR(inode->i_mode)) { ++ if (inode->i_nlink && !d_unhashed(dentry)) ++ drop_nlink(inode); ++ } else { ++ clear_nlink(inode); ++ /* stop next lookup */ ++ inode->i_flags |= S_DEAD; ++ } ++ smp_mb(); /* necessary? */ ++ } ++ d_drop(dentry); ++} ++ ++static int au_hide_children(struct dentry *parent) ++{ ++ int err, i, j, ndentry; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry *dentry; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, parent, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ /* in reverse order */ ++ for (i = dpages.ndpage - 1; i >= 0; i--) { ++ dpage = dpages.dpages + i; ++ ndentry = dpage->ndentry; ++ for (j = ndentry - 1; j >= 0; j--) { ++ dentry = dpage->dentries[j]; ++ if (dentry != parent) ++ au_do_hide(dentry); ++ } ++ } ++ ++out_dpages: ++ au_dpages_free(&dpages); ++out: ++ return err; ++} ++ ++static void au_hide(struct dentry *dentry) ++{ ++ int err; ++ struct inode *inode; ++ ++ AuDbgDentry(dentry); ++ inode = dentry->d_inode; ++ if (inode && S_ISDIR(inode->i_mode)) { ++ /* shrink_dcache_parent(dentry); */ ++ err = au_hide_children(dentry); ++ if (unlikely(err)) ++ AuIOErr("%pd, failed hiding children, ignored %d\n", ++ dentry, err); ++ } ++ au_do_hide(dentry); ++} ++ ++/* ++ * By adding a dirty branch, a cached dentry may be affected in various ways. ++ * ++ * a dirty branch is added ++ * - on the top of layers ++ * - in the middle of layers ++ * - to the bottom of layers ++ * ++ * on the added branch there exists ++ * - a whiteout ++ * - a diropq ++ * - a same named entry ++ * + exist ++ * * negative --> positive ++ * * positive --> positive ++ * - type is unchanged ++ * - type is changed ++ * + doesn't exist ++ * * negative --> negative ++ * * positive --> negative (rejected by au_br_del() for non-dir case) ++ * - none ++ */ ++static int au_refresh_by_dinfo(struct dentry *dentry, struct au_dinfo *dinfo, ++ struct au_dinfo *tmp) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct { ++ struct dentry *dentry; ++ struct inode *inode; ++ mode_t mode; ++ } orig_h, tmp_h; ++ struct au_hdentry *hd; ++ struct inode *inode, *h_inode; ++ struct dentry *h_dentry; ++ ++ err = 0; ++ AuDebugOn(dinfo->di_bstart < 0); ++ orig_h.dentry = dinfo->di_hdentry[dinfo->di_bstart].hd_dentry; ++ orig_h.inode = orig_h.dentry->d_inode; ++ orig_h.mode = 0; ++ if (orig_h.inode) ++ orig_h.mode = orig_h.inode->i_mode & S_IFMT; ++ memset(&tmp_h, 0, sizeof(tmp_h)); ++ if (tmp->di_bstart >= 0) { ++ tmp_h.dentry = tmp->di_hdentry[tmp->di_bstart].hd_dentry; ++ tmp_h.inode = tmp_h.dentry->d_inode; ++ if (tmp_h.inode) ++ tmp_h.mode = tmp_h.inode->i_mode & S_IFMT; ++ } ++ ++ inode = dentry->d_inode; ++ if (!orig_h.inode) { ++ AuDbg("nagative originally\n"); ++ if (inode) { ++ au_hide(dentry); ++ goto out; ++ } ++ AuDebugOn(inode); ++ AuDebugOn(dinfo->di_bstart != dinfo->di_bend); ++ AuDebugOn(dinfo->di_bdiropq != -1); ++ ++ if (!tmp_h.inode) { ++ AuDbg("negative --> negative\n"); ++ /* should have only one negative lower */ ++ if (tmp->di_bstart >= 0 ++ && tmp->di_bstart < dinfo->di_bstart) { ++ AuDebugOn(tmp->di_bstart != tmp->di_bend); ++ AuDebugOn(dinfo->di_bstart != dinfo->di_bend); ++ au_set_h_dptr(dentry, dinfo->di_bstart, NULL); ++ au_di_cp(dinfo, tmp); ++ hd = tmp->di_hdentry + tmp->di_bstart; ++ au_set_h_dptr(dentry, tmp->di_bstart, ++ dget(hd->hd_dentry)); ++ } ++ au_dbg_verify_dinode(dentry); ++ } else { ++ AuDbg("negative --> positive\n"); ++ /* ++ * similar to the behaviour of creating with bypassing ++ * aufs. ++ * unhash it in order to force an error in the ++ * succeeding create operation. ++ * we should not set S_DEAD here. ++ */ ++ d_drop(dentry); ++ /* au_di_swap(tmp, dinfo); */ ++ au_dbg_verify_dinode(dentry); ++ } ++ } else { ++ AuDbg("positive originally\n"); ++ /* inode may be NULL */ ++ AuDebugOn(inode && (inode->i_mode & S_IFMT) != orig_h.mode); ++ if (!tmp_h.inode) { ++ AuDbg("positive --> negative\n"); ++ /* or bypassing aufs */ ++ au_hide(dentry); ++ if (tmp->di_bwh >= 0 && tmp->di_bwh <= dinfo->di_bstart) ++ dinfo->di_bwh = tmp->di_bwh; ++ if (inode) ++ err = au_refresh_hinode_self(inode); ++ au_dbg_verify_dinode(dentry); ++ } else if (orig_h.mode == tmp_h.mode) { ++ AuDbg("positive --> positive, same type\n"); ++ if (!S_ISDIR(orig_h.mode) ++ && dinfo->di_bstart > tmp->di_bstart) { ++ /* ++ * similar to the behaviour of removing and ++ * creating. ++ */ ++ au_hide(dentry); ++ if (inode) ++ err = au_refresh_hinode_self(inode); ++ au_dbg_verify_dinode(dentry); ++ } else { ++ /* fill empty slots */ ++ if (dinfo->di_bstart > tmp->di_bstart) ++ dinfo->di_bstart = tmp->di_bstart; ++ if (dinfo->di_bend < tmp->di_bend) ++ dinfo->di_bend = tmp->di_bend; ++ dinfo->di_bwh = tmp->di_bwh; ++ dinfo->di_bdiropq = tmp->di_bdiropq; ++ hd = tmp->di_hdentry; ++ bend = dinfo->di_bend; ++ for (bindex = tmp->di_bstart; bindex <= bend; ++ bindex++) { ++ if (au_h_dptr(dentry, bindex)) ++ continue; ++ h_dentry = hd[bindex].hd_dentry; ++ if (!h_dentry) ++ continue; ++ h_inode = h_dentry->d_inode; ++ AuDebugOn(!h_inode); ++ AuDebugOn(orig_h.mode ++ != (h_inode->i_mode ++ & S_IFMT)); ++ au_set_h_dptr(dentry, bindex, ++ dget(h_dentry)); ++ } ++ err = au_refresh_hinode(inode, dentry); ++ au_dbg_verify_dinode(dentry); ++ } ++ } else { ++ AuDbg("positive --> positive, different type\n"); ++ /* similar to the behaviour of removing and creating */ ++ au_hide(dentry); ++ if (inode) ++ err = au_refresh_hinode_self(inode); ++ au_dbg_verify_dinode(dentry); ++ } ++ } ++ ++out: ++ return err; ++} ++ ++int au_refresh_dentry(struct dentry *dentry, struct dentry *parent) ++{ ++ int err, ebrange; ++ unsigned int sigen; ++ struct au_dinfo *dinfo, *tmp; ++ struct super_block *sb; ++ struct inode *inode; ++ ++ DiMustWriteLock(dentry); ++ AuDebugOn(IS_ROOT(dentry)); ++ AuDebugOn(!parent->d_inode); ++ ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ sigen = au_sigen(sb); ++ err = au_digen_test(parent, sigen); ++ if (unlikely(err)) ++ goto out; ++ ++ dinfo = au_di(dentry); ++ err = au_di_realloc(dinfo, au_sbend(sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ ebrange = au_dbrange_test(dentry); ++ if (!ebrange) ++ ebrange = au_do_refresh_hdentry(dentry, parent); ++ ++ if (d_unhashed(dentry) || ebrange /* || dinfo->di_tmpfile */) { ++ AuDebugOn(au_dbstart(dentry) < 0 && au_dbend(dentry) >= 0); ++ if (inode) ++ err = au_refresh_hinode_self(inode); ++ au_dbg_verify_dinode(dentry); ++ if (!err) ++ goto out_dgen; /* success */ ++ goto out; ++ } ++ ++ /* temporary dinfo */ ++ AuDbgDentry(dentry); ++ err = -ENOMEM; ++ tmp = au_di_alloc(sb, AuLsc_DI_TMP); ++ if (unlikely(!tmp)) ++ goto out; ++ au_di_swap(tmp, dinfo); ++ /* returns the number of positive dentries */ ++ /* ++ * if current working dir is removed, it returns an error. ++ * but the dentry is legal. ++ */ ++ err = au_lkup_dentry(dentry, /*bstart*/0, /*type*/0); ++ AuDbgDentry(dentry); ++ au_di_swap(tmp, dinfo); ++ if (err == -ENOENT) ++ err = 0; ++ if (err >= 0) { ++ /* compare/refresh by dinfo */ ++ AuDbgDentry(dentry); ++ err = au_refresh_by_dinfo(dentry, dinfo, tmp); ++ au_dbg_verify_dinode(dentry); ++ AuTraceErr(err); ++ } ++ au_rw_write_unlock(&tmp->di_rwsem); ++ au_di_free(tmp); ++ if (unlikely(err)) ++ goto out; ++ ++out_dgen: ++ au_update_digen(dentry); ++out: ++ if (unlikely(err && !(dentry->d_flags & DCACHE_NFSFS_RENAMED))) { ++ AuIOErr("failed refreshing %pd, %d\n", dentry, err); ++ AuDbgDentry(dentry); ++ } ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_do_h_d_reval(struct dentry *h_dentry, unsigned int flags, ++ struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ int err, valid; ++ ++ err = 0; ++ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE)) ++ goto out; ++ ++ AuDbg("b%d\n", bindex); ++ /* ++ * gave up supporting LOOKUP_CREATE/OPEN for lower fs, ++ * due to whiteout and branch permission. ++ */ ++ flags &= ~(/*LOOKUP_PARENT |*/ LOOKUP_OPEN | LOOKUP_CREATE ++ | LOOKUP_FOLLOW | LOOKUP_EXCL); ++ /* it may return tri-state */ ++ valid = h_dentry->d_op->d_revalidate(h_dentry, flags); ++ ++ if (unlikely(valid < 0)) ++ err = valid; ++ else if (!valid) ++ err = -EINVAL; ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* todo: remove this */ ++static int h_d_revalidate(struct dentry *dentry, struct inode *inode, ++ unsigned int flags, int do_udba) ++{ ++ int err; ++ umode_t mode, h_mode; ++ aufs_bindex_t bindex, btail, bstart, ibs, ibe; ++ unsigned char plus, unhashed, is_root, h_plus, h_nfs, tmpfile; ++ struct inode *h_inode, *h_cached_inode; ++ struct dentry *h_dentry; ++ struct qstr *name, *h_name; ++ ++ err = 0; ++ plus = 0; ++ mode = 0; ++ ibs = -1; ++ ibe = -1; ++ unhashed = !!d_unhashed(dentry); ++ is_root = !!IS_ROOT(dentry); ++ name = &dentry->d_name; ++ tmpfile = au_di(dentry)->di_tmpfile; ++ ++ /* ++ * Theoretically, REVAL test should be unnecessary in case of ++ * {FS,I}NOTIFY. ++ * But {fs,i}notify doesn't fire some necessary events, ++ * IN_ATTRIB for atime/nlink/pageio ++ * Let's do REVAL test too. ++ */ ++ if (do_udba && inode) { ++ mode = (inode->i_mode & S_IFMT); ++ plus = (inode->i_nlink > 0); ++ ibs = au_ibstart(inode); ++ ibe = au_ibend(inode); ++ } ++ ++ bstart = au_dbstart(dentry); ++ btail = bstart; ++ if (inode && S_ISDIR(inode->i_mode)) ++ btail = au_dbtaildir(dentry); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ ++ AuDbg("b%d, %pd\n", bindex, h_dentry); ++ h_nfs = !!au_test_nfs(h_dentry->d_sb); ++ spin_lock(&h_dentry->d_lock); ++ h_name = &h_dentry->d_name; ++ if (unlikely(do_udba ++ && !is_root ++ && ((!h_nfs ++ && (unhashed != !!d_unhashed(h_dentry) ++ || (!tmpfile ++ && !au_qstreq(name, h_name)) ++ )) ++ || (h_nfs ++ && !(flags & LOOKUP_OPEN) ++ && (h_dentry->d_flags ++ & DCACHE_NFSFS_RENAMED))) ++ )) { ++ int h_unhashed; ++ ++ h_unhashed = d_unhashed(h_dentry); ++ spin_unlock(&h_dentry->d_lock); ++ AuDbg("unhash 0x%x 0x%x, %pd %pd\n", ++ unhashed, h_unhashed, dentry, h_dentry); ++ goto err; ++ } ++ spin_unlock(&h_dentry->d_lock); ++ ++ err = au_do_h_d_reval(h_dentry, flags, dentry, bindex); ++ if (unlikely(err)) ++ /* do not goto err, to keep the errno */ ++ break; ++ ++ /* todo: plink too? */ ++ if (!do_udba) ++ continue; ++ ++ /* UDBA tests */ ++ h_inode = h_dentry->d_inode; ++ if (unlikely(!!inode != !!h_inode)) ++ goto err; ++ ++ h_plus = plus; ++ h_mode = mode; ++ h_cached_inode = h_inode; ++ if (h_inode) { ++ h_mode = (h_inode->i_mode & S_IFMT); ++ h_plus = (h_inode->i_nlink > 0); ++ } ++ if (inode && ibs <= bindex && bindex <= ibe) ++ h_cached_inode = au_h_iptr(inode, bindex); ++ ++ if (!h_nfs) { ++ if (unlikely(plus != h_plus && !tmpfile)) ++ goto err; ++ } else { ++ if (unlikely(!(h_dentry->d_flags & DCACHE_NFSFS_RENAMED) ++ && !is_root ++ && !IS_ROOT(h_dentry) ++ && unhashed != d_unhashed(h_dentry))) ++ goto err; ++ } ++ if (unlikely(mode != h_mode ++ || h_cached_inode != h_inode)) ++ goto err; ++ continue; ++ ++err: ++ err = -EINVAL; ++ break; ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* todo: consolidate with do_refresh() and au_reval_for_attr() */ ++static int simple_reval_dpath(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct dentry *parent; ++ ++ if (!au_digen_test(dentry, sigen)) ++ return 0; ++ ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ AuDebugOn(au_digen_test(parent, sigen)); ++ au_dbg_verify_gen(parent, sigen); ++ err = au_refresh_dentry(dentry, parent); ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_reval_dpath(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct dentry *d, *parent; ++ struct inode *inode; ++ ++ if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR)) ++ return simple_reval_dpath(dentry, sigen); ++ ++ /* slow loop, keep it simple and stupid */ ++ /* cf: au_cpup_dirs() */ ++ err = 0; ++ parent = NULL; ++ while (au_digen_test(dentry, sigen)) { ++ d = dentry; ++ while (1) { ++ dput(parent); ++ parent = dget_parent(d); ++ if (!au_digen_test(parent, sigen)) ++ break; ++ d = parent; ++ } ++ ++ inode = d->d_inode; ++ if (d != dentry) ++ di_write_lock_child2(d); ++ ++ /* someone might update our dentry while we were sleeping */ ++ if (au_digen_test(d, sigen)) { ++ /* ++ * todo: consolidate with simple_reval_dpath(), ++ * do_refresh() and au_reval_for_attr(). ++ */ ++ di_read_lock_parent(parent, AuLock_IR); ++ err = au_refresh_dentry(d, parent); ++ di_read_unlock(parent, AuLock_IR); ++ } ++ ++ if (d != dentry) ++ di_write_unlock(d); ++ dput(parent); ++ if (unlikely(err)) ++ break; ++ } ++ ++ return err; ++} ++ ++/* ++ * if valid returns 1, otherwise 0. ++ */ ++static int aufs_d_revalidate(struct dentry *dentry, unsigned int flags) ++{ ++ int valid, err; ++ unsigned int sigen; ++ unsigned char do_udba; ++ struct super_block *sb; ++ struct inode *inode; ++ ++ /* todo: support rcu-walk? */ ++ if (flags & LOOKUP_RCU) ++ return -ECHILD; ++ ++ valid = 0; ++ if (unlikely(!au_di(dentry))) ++ goto out; ++ ++ valid = 1; ++ sb = dentry->d_sb; ++ /* ++ * todo: very ugly ++ * i_mutex of parent dir may be held, ++ * but we should not return 'invalid' due to busy. ++ */ ++ err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW | AuLock_NOPLM); ++ if (unlikely(err)) { ++ valid = err; ++ AuTraceErr(err); ++ goto out; ++ } ++ inode = dentry->d_inode; ++ if (unlikely(inode && is_bad_inode(inode))) { ++ err = -EINVAL; ++ AuTraceErr(err); ++ goto out_dgrade; ++ } ++ if (unlikely(au_dbrange_test(dentry))) { ++ err = -EINVAL; ++ AuTraceErr(err); ++ goto out_dgrade; ++ } ++ ++ sigen = au_sigen(sb); ++ if (au_digen_test(dentry, sigen)) { ++ AuDebugOn(IS_ROOT(dentry)); ++ err = au_reval_dpath(dentry, sigen); ++ if (unlikely(err)) { ++ AuTraceErr(err); ++ goto out_dgrade; ++ } ++ } ++ di_downgrade_lock(dentry, AuLock_IR); ++ ++ err = -EINVAL; ++ if (!(flags & (LOOKUP_OPEN | LOOKUP_EMPTY)) ++ && inode ++ && !(inode->i_state && I_LINKABLE) ++ && (IS_DEADDIR(inode) || !inode->i_nlink)) ++ goto out_inval; ++ ++ do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE); ++ if (do_udba && inode) { ++ aufs_bindex_t bstart = au_ibstart(inode); ++ struct inode *h_inode; ++ ++ if (bstart >= 0) { ++ h_inode = au_h_iptr(inode, bstart); ++ if (h_inode && au_test_higen(inode, h_inode)) ++ goto out_inval; ++ } ++ } ++ ++ err = h_d_revalidate(dentry, inode, flags, do_udba); ++ if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) { ++ err = -EIO; ++ AuDbg("both of real entry and whiteout found, %p, err %d\n", ++ dentry, err); ++ } ++ goto out_inval; ++ ++out_dgrade: ++ di_downgrade_lock(dentry, AuLock_IR); ++out_inval: ++ aufs_read_unlock(dentry, AuLock_IR); ++ AuTraceErr(err); ++ valid = !err; ++out: ++ if (!valid) { ++ AuDbg("%pd invalid, %d\n", dentry, valid); ++ d_drop(dentry); ++ } ++ return valid; ++} ++ ++static void aufs_d_release(struct dentry *dentry) ++{ ++ if (au_di(dentry)) { ++ au_di_fin(dentry); ++ au_hn_di_reinit(dentry); ++ } ++} ++ ++const struct dentry_operations aufs_dop = { ++ .d_revalidate = aufs_d_revalidate, ++ .d_weak_revalidate = aufs_d_revalidate, ++ .d_release = aufs_d_release ++}; +diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h +new file mode 100644 +index 0000000..6516146 +--- /dev/null ++++ b/fs/aufs/dentry.h +@@ -0,0 +1,220 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * lookup and dentry operations ++ */ ++ ++#ifndef __AUFS_DENTRY_H__ ++#define __AUFS_DENTRY_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include "rwsem.h" ++ ++struct au_hdentry { ++ struct dentry *hd_dentry; ++ aufs_bindex_t hd_id; ++}; ++ ++struct au_dinfo { ++ atomic_t di_generation; ++ ++ struct au_rwsem di_rwsem; ++ aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq; ++ unsigned char di_tmpfile; /* to allow the different name */ ++ struct au_hdentry *di_hdentry; ++} ____cacheline_aligned_in_smp; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dentry.c */ ++extern const struct dentry_operations aufs_dop; ++struct au_branch; ++struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent); ++int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, ++ struct dentry *h_parent, struct au_branch *br); ++ ++int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type); ++int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh); ++int au_refresh_dentry(struct dentry *dentry, struct dentry *parent); ++int au_reval_dpath(struct dentry *dentry, unsigned int sigen); ++ ++/* dinfo.c */ ++void au_di_init_once(void *_di); ++struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc); ++void au_di_free(struct au_dinfo *dinfo); ++void au_di_swap(struct au_dinfo *a, struct au_dinfo *b); ++void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src); ++int au_di_init(struct dentry *dentry); ++void au_di_fin(struct dentry *dentry); ++int au_di_realloc(struct au_dinfo *dinfo, int nbr); ++ ++void di_read_lock(struct dentry *d, int flags, unsigned int lsc); ++void di_read_unlock(struct dentry *d, int flags); ++void di_downgrade_lock(struct dentry *d, int flags); ++void di_write_lock(struct dentry *d, unsigned int lsc); ++void di_write_unlock(struct dentry *d); ++void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir); ++void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir); ++void di_write_unlock2(struct dentry *d1, struct dentry *d2); ++ ++struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex); ++struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex); ++aufs_bindex_t au_dbtail(struct dentry *dentry); ++aufs_bindex_t au_dbtaildir(struct dentry *dentry); ++ ++void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++int au_digen_test(struct dentry *dentry, unsigned int sigen); ++int au_dbrange_test(struct dentry *dentry); ++void au_update_digen(struct dentry *dentry); ++void au_update_dbrange(struct dentry *dentry, int do_put_zero); ++void au_update_dbstart(struct dentry *dentry); ++void au_update_dbend(struct dentry *dentry); ++int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_dinfo *au_di(struct dentry *dentry) ++{ ++ return dentry->d_fsdata; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for dinfo */ ++enum { ++ AuLsc_DI_CHILD, /* child first */ ++ AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hnotify */ ++ AuLsc_DI_CHILD3, /* copyup dirs */ ++ AuLsc_DI_PARENT, ++ AuLsc_DI_PARENT2, ++ AuLsc_DI_PARENT3, ++ AuLsc_DI_TMP /* temp for replacing dinfo */ ++}; ++ ++/* ++ * di_read_lock_child, di_write_lock_child, ++ * di_read_lock_child2, di_write_lock_child2, ++ * di_read_lock_child3, di_write_lock_child3, ++ * di_read_lock_parent, di_write_lock_parent, ++ * di_read_lock_parent2, di_write_lock_parent2, ++ * di_read_lock_parent3, di_write_lock_parent3, ++ */ ++#define AuReadLockFunc(name, lsc) \ ++static inline void di_read_lock_##name(struct dentry *d, int flags) \ ++{ di_read_lock(d, flags, AuLsc_DI_##lsc); } ++ ++#define AuWriteLockFunc(name, lsc) \ ++static inline void di_write_lock_##name(struct dentry *d) \ ++{ di_write_lock(d, AuLsc_DI_##lsc); } ++ ++#define AuRWLockFuncs(name, lsc) \ ++ AuReadLockFunc(name, lsc) \ ++ AuWriteLockFunc(name, lsc) ++ ++AuRWLockFuncs(child, CHILD); ++AuRWLockFuncs(child2, CHILD2); ++AuRWLockFuncs(child3, CHILD3); ++AuRWLockFuncs(parent, PARENT); ++AuRWLockFuncs(parent2, PARENT2); ++AuRWLockFuncs(parent3, PARENT3); ++ ++#undef AuReadLockFunc ++#undef AuWriteLockFunc ++#undef AuRWLockFuncs ++ ++#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem) ++#define DiMustAnyLock(d) AuRwMustAnyLock(&au_di(d)->di_rwsem) ++#define DiMustWriteLock(d) AuRwMustWriteLock(&au_di(d)->di_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: memory barrier? */ ++static inline unsigned int au_digen(struct dentry *d) ++{ ++ return atomic_read(&au_di(d)->di_generation); ++} ++ ++static inline void au_h_dentry_init(struct au_hdentry *hdentry) ++{ ++ hdentry->hd_dentry = NULL; ++} ++ ++static inline void au_hdput(struct au_hdentry *hd) ++{ ++ if (hd) ++ dput(hd->hd_dentry); ++} ++ ++static inline aufs_bindex_t au_dbstart(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bstart; ++} ++ ++static inline aufs_bindex_t au_dbend(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bend; ++} ++ ++static inline aufs_bindex_t au_dbwh(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bwh; ++} ++ ++static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry) ++{ ++ DiMustAnyLock(dentry); ++ return au_di(dentry)->di_bdiropq; ++} ++ ++/* todo: hard/soft set? */ ++static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ au_di(dentry)->di_bstart = bindex; ++} ++ ++static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ au_di(dentry)->di_bend = bindex; ++} ++ ++static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ /* dbwh can be outside of bstart - bend range */ ++ au_di(dentry)->di_bwh = bindex; ++} ++ ++static inline void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ DiMustWriteLock(dentry); ++ au_di(dentry)->di_bdiropq = bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_HNOTIFY ++static inline void au_digen_dec(struct dentry *d) ++{ ++ atomic_dec(&au_di(d)->di_generation); ++} ++ ++static inline void au_hn_di_reinit(struct dentry *dentry) ++{ ++ dentry->d_fsdata = NULL; ++} ++#else ++AuStubVoid(au_hn_di_reinit, struct dentry *dentry __maybe_unused) ++#endif /* CONFIG_AUFS_HNOTIFY */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DENTRY_H__ */ +diff --git a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c +new file mode 100644 +index 0000000..cd29ce0 +--- /dev/null ++++ b/fs/aufs/dinfo.c +@@ -0,0 +1,531 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * dentry private data ++ */ ++ ++#include "aufs.h" ++ ++void au_di_init_once(void *_dinfo) ++{ ++ struct au_dinfo *dinfo = _dinfo; ++ static struct lock_class_key aufs_di; ++ ++ au_rw_init(&dinfo->di_rwsem); ++ au_rw_class(&dinfo->di_rwsem, &aufs_di); ++} ++ ++struct au_dinfo *au_di_alloc(struct super_block *sb, unsigned int lsc) ++{ ++ struct au_dinfo *dinfo; ++ int nbr, i; ++ ++ dinfo = au_cache_alloc_dinfo(); ++ if (unlikely(!dinfo)) ++ goto out; ++ ++ nbr = au_sbend(sb) + 1; ++ if (nbr <= 0) ++ nbr = 1; ++ dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), GFP_NOFS); ++ if (dinfo->di_hdentry) { ++ au_rw_write_lock_nested(&dinfo->di_rwsem, lsc); ++ dinfo->di_bstart = -1; ++ dinfo->di_bend = -1; ++ dinfo->di_bwh = -1; ++ dinfo->di_bdiropq = -1; ++ dinfo->di_tmpfile = 0; ++ for (i = 0; i < nbr; i++) ++ dinfo->di_hdentry[i].hd_id = -1; ++ goto out; ++ } ++ ++ au_cache_free_dinfo(dinfo); ++ dinfo = NULL; ++ ++out: ++ return dinfo; ++} ++ ++void au_di_free(struct au_dinfo *dinfo) ++{ ++ struct au_hdentry *p; ++ aufs_bindex_t bend, bindex; ++ ++ /* dentry may not be revalidated */ ++ bindex = dinfo->di_bstart; ++ if (bindex >= 0) { ++ bend = dinfo->di_bend; ++ p = dinfo->di_hdentry + bindex; ++ while (bindex++ <= bend) ++ au_hdput(p++); ++ } ++ kfree(dinfo->di_hdentry); ++ au_cache_free_dinfo(dinfo); ++} ++ ++void au_di_swap(struct au_dinfo *a, struct au_dinfo *b) ++{ ++ struct au_hdentry *p; ++ aufs_bindex_t bi; ++ ++ AuRwMustWriteLock(&a->di_rwsem); ++ AuRwMustWriteLock(&b->di_rwsem); ++ ++#define DiSwap(v, name) \ ++ do { \ ++ v = a->di_##name; \ ++ a->di_##name = b->di_##name; \ ++ b->di_##name = v; \ ++ } while (0) ++ ++ DiSwap(p, hdentry); ++ DiSwap(bi, bstart); ++ DiSwap(bi, bend); ++ DiSwap(bi, bwh); ++ DiSwap(bi, bdiropq); ++ /* smp_mb(); */ ++ ++#undef DiSwap ++} ++ ++void au_di_cp(struct au_dinfo *dst, struct au_dinfo *src) ++{ ++ AuRwMustWriteLock(&dst->di_rwsem); ++ AuRwMustWriteLock(&src->di_rwsem); ++ ++ dst->di_bstart = src->di_bstart; ++ dst->di_bend = src->di_bend; ++ dst->di_bwh = src->di_bwh; ++ dst->di_bdiropq = src->di_bdiropq; ++ /* smp_mb(); */ ++} ++ ++int au_di_init(struct dentry *dentry) ++{ ++ int err; ++ struct super_block *sb; ++ struct au_dinfo *dinfo; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ dinfo = au_di_alloc(sb, AuLsc_DI_CHILD); ++ if (dinfo) { ++ atomic_set(&dinfo->di_generation, au_sigen(sb)); ++ /* smp_mb(); */ /* atomic_set */ ++ dentry->d_fsdata = dinfo; ++ } else ++ err = -ENOMEM; ++ ++ return err; ++} ++ ++void au_di_fin(struct dentry *dentry) ++{ ++ struct au_dinfo *dinfo; ++ ++ dinfo = au_di(dentry); ++ AuRwDestroy(&dinfo->di_rwsem); ++ au_di_free(dinfo); ++} ++ ++int au_di_realloc(struct au_dinfo *dinfo, int nbr) ++{ ++ int err, sz; ++ struct au_hdentry *hdp; ++ ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*hdp) * (dinfo->di_bend + 1); ++ if (!sz) ++ sz = sizeof(*hdp); ++ hdp = au_kzrealloc(dinfo->di_hdentry, sz, sizeof(*hdp) * nbr, GFP_NOFS); ++ if (hdp) { ++ dinfo->di_hdentry = hdp; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void do_ii_write_lock(struct inode *inode, unsigned int lsc) ++{ ++ switch (lsc) { ++ case AuLsc_DI_CHILD: ++ ii_write_lock_child(inode); ++ break; ++ case AuLsc_DI_CHILD2: ++ ii_write_lock_child2(inode); ++ break; ++ case AuLsc_DI_CHILD3: ++ ii_write_lock_child3(inode); ++ break; ++ case AuLsc_DI_PARENT: ++ ii_write_lock_parent(inode); ++ break; ++ case AuLsc_DI_PARENT2: ++ ii_write_lock_parent2(inode); ++ break; ++ case AuLsc_DI_PARENT3: ++ ii_write_lock_parent3(inode); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++static void do_ii_read_lock(struct inode *inode, unsigned int lsc) ++{ ++ switch (lsc) { ++ case AuLsc_DI_CHILD: ++ ii_read_lock_child(inode); ++ break; ++ case AuLsc_DI_CHILD2: ++ ii_read_lock_child2(inode); ++ break; ++ case AuLsc_DI_CHILD3: ++ ii_read_lock_child3(inode); ++ break; ++ case AuLsc_DI_PARENT: ++ ii_read_lock_parent(inode); ++ break; ++ case AuLsc_DI_PARENT2: ++ ii_read_lock_parent2(inode); ++ break; ++ case AuLsc_DI_PARENT3: ++ ii_read_lock_parent3(inode); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++void di_read_lock(struct dentry *d, int flags, unsigned int lsc) ++{ ++ au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc); ++ if (d->d_inode) { ++ if (au_ftest_lock(flags, IW)) ++ do_ii_write_lock(d->d_inode, lsc); ++ else if (au_ftest_lock(flags, IR)) ++ do_ii_read_lock(d->d_inode, lsc); ++ } ++} ++ ++void di_read_unlock(struct dentry *d, int flags) ++{ ++ if (d->d_inode) { ++ if (au_ftest_lock(flags, IW)) { ++ au_dbg_verify_dinode(d); ++ ii_write_unlock(d->d_inode); ++ } else if (au_ftest_lock(flags, IR)) { ++ au_dbg_verify_dinode(d); ++ ii_read_unlock(d->d_inode); ++ } ++ } ++ au_rw_read_unlock(&au_di(d)->di_rwsem); ++} ++ ++void di_downgrade_lock(struct dentry *d, int flags) ++{ ++ if (d->d_inode && au_ftest_lock(flags, IR)) ++ ii_downgrade_lock(d->d_inode); ++ au_rw_dgrade_lock(&au_di(d)->di_rwsem); ++} ++ ++void di_write_lock(struct dentry *d, unsigned int lsc) ++{ ++ au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc); ++ if (d->d_inode) ++ do_ii_write_lock(d->d_inode, lsc); ++} ++ ++void di_write_unlock(struct dentry *d) ++{ ++ au_dbg_verify_dinode(d); ++ if (d->d_inode) ++ ii_write_unlock(d->d_inode); ++ au_rw_write_unlock(&au_di(d)->di_rwsem); ++} ++ ++void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir) ++{ ++ AuDebugOn(d1 == d2 ++ || d1->d_inode == d2->d_inode ++ || d1->d_sb != d2->d_sb); ++ ++ if (isdir && au_test_subdir(d1, d2)) { ++ di_write_lock_child(d1); ++ di_write_lock_child2(d2); ++ } else { ++ /* there should be no races */ ++ di_write_lock_child(d2); ++ di_write_lock_child2(d1); ++ } ++} ++ ++void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) ++{ ++ AuDebugOn(d1 == d2 ++ || d1->d_inode == d2->d_inode ++ || d1->d_sb != d2->d_sb); ++ ++ if (isdir && au_test_subdir(d1, d2)) { ++ di_write_lock_parent(d1); ++ di_write_lock_parent2(d2); ++ } else { ++ /* there should be no races */ ++ di_write_lock_parent(d2); ++ di_write_lock_parent2(d1); ++ } ++} ++ ++void di_write_unlock2(struct dentry *d1, struct dentry *d2) ++{ ++ di_write_unlock(d1); ++ if (d1->d_inode == d2->d_inode) ++ au_rw_write_unlock(&au_di(d2)->di_rwsem); ++ else ++ di_write_unlock(d2); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ struct dentry *d; ++ ++ DiMustAnyLock(dentry); ++ ++ if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) ++ return NULL; ++ AuDebugOn(bindex < 0); ++ d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry; ++ AuDebugOn(d && au_dcount(d) <= 0); ++ return d; ++} ++ ++/* ++ * extended version of au_h_dptr(). ++ * returns a hashed and positive (or linkable) h_dentry in bindex, NULL, or ++ * error. ++ */ ++struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ struct dentry *h_dentry; ++ struct inode *inode, *h_inode; ++ ++ inode = dentry->d_inode; ++ AuDebugOn(!inode); ++ ++ h_dentry = NULL; ++ if (au_dbstart(dentry) <= bindex ++ && bindex <= au_dbend(dentry)) ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && !au_d_linkable(h_dentry)) { ++ dget(h_dentry); ++ goto out; /* success */ ++ } ++ ++ AuDebugOn(bindex < au_ibstart(inode)); ++ AuDebugOn(au_ibend(inode) < bindex); ++ h_inode = au_h_iptr(inode, bindex); ++ h_dentry = d_find_alias(h_inode); ++ if (h_dentry) { ++ if (!IS_ERR(h_dentry)) { ++ if (!au_d_linkable(h_dentry)) ++ goto out; /* success */ ++ dput(h_dentry); ++ } else ++ goto out; ++ } ++ ++ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) { ++ h_dentry = au_plink_lkup(inode, bindex); ++ AuDebugOn(!h_dentry); ++ if (!IS_ERR(h_dentry)) { ++ if (!au_d_hashed_positive(h_dentry)) ++ goto out; /* success */ ++ dput(h_dentry); ++ h_dentry = NULL; ++ } ++ } ++ ++out: ++ AuDbgDentry(h_dentry); ++ return h_dentry; ++} ++ ++aufs_bindex_t au_dbtail(struct dentry *dentry) ++{ ++ aufs_bindex_t bend, bwh; ++ ++ bend = au_dbend(dentry); ++ if (0 <= bend) { ++ bwh = au_dbwh(dentry); ++ if (!bwh) ++ return bwh; ++ if (0 < bwh && bwh < bend) ++ return bwh - 1; ++ } ++ return bend; ++} ++ ++aufs_bindex_t au_dbtaildir(struct dentry *dentry) ++{ ++ aufs_bindex_t bend, bopq; ++ ++ bend = au_dbtail(dentry); ++ if (0 <= bend) { ++ bopq = au_dbdiropq(dentry); ++ if (0 <= bopq && bopq < bend) ++ bend = bopq; ++ } ++ return bend; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_dentry) ++{ ++ struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; ++ struct au_branch *br; ++ ++ DiMustWriteLock(dentry); ++ ++ au_hdput(hd); ++ hd->hd_dentry = h_dentry; ++ if (h_dentry) { ++ br = au_sbr(dentry->d_sb, bindex); ++ hd->hd_id = br->br_id; ++ } ++} ++ ++int au_dbrange_test(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bstart, bend; ++ ++ err = 0; ++ bstart = au_dbstart(dentry); ++ bend = au_dbend(dentry); ++ if (bstart >= 0) ++ AuDebugOn(bend < 0 && bstart > bend); ++ else { ++ err = -EIO; ++ AuDebugOn(bend >= 0); ++ } ++ ++ return err; ++} ++ ++int au_digen_test(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ ++ err = 0; ++ if (unlikely(au_digen(dentry) != sigen ++ || au_iigen_test(dentry->d_inode, sigen))) ++ err = -EIO; ++ ++ return err; ++} ++ ++void au_update_digen(struct dentry *dentry) ++{ ++ atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++void au_update_dbrange(struct dentry *dentry, int do_put_zero) ++{ ++ struct au_dinfo *dinfo; ++ struct dentry *h_d; ++ struct au_hdentry *hdp; ++ ++ DiMustWriteLock(dentry); ++ ++ dinfo = au_di(dentry); ++ if (!dinfo || dinfo->di_bstart < 0) ++ return; ++ ++ hdp = dinfo->di_hdentry; ++ if (do_put_zero) { ++ aufs_bindex_t bindex, bend; ++ ++ bend = dinfo->di_bend; ++ for (bindex = dinfo->di_bstart; bindex <= bend; bindex++) { ++ h_d = hdp[0 + bindex].hd_dentry; ++ if (h_d && !h_d->d_inode) ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++ } ++ ++ dinfo->di_bstart = -1; ++ while (++dinfo->di_bstart <= dinfo->di_bend) ++ if (hdp[0 + dinfo->di_bstart].hd_dentry) ++ break; ++ if (dinfo->di_bstart > dinfo->di_bend) { ++ dinfo->di_bstart = -1; ++ dinfo->di_bend = -1; ++ return; ++ } ++ ++ dinfo->di_bend++; ++ while (0 <= --dinfo->di_bend) ++ if (hdp[0 + dinfo->di_bend].hd_dentry) ++ break; ++ AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0); ++} ++ ++void au_update_dbstart(struct dentry *dentry) ++{ ++ aufs_bindex_t bindex, bend; ++ struct dentry *h_dentry; ++ ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ if (h_dentry->d_inode) { ++ au_set_dbstart(dentry, bindex); ++ return; ++ } ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++} ++ ++void au_update_dbend(struct dentry *dentry) ++{ ++ aufs_bindex_t bindex, bstart; ++ struct dentry *h_dentry; ++ ++ bstart = au_dbstart(dentry); ++ for (bindex = au_dbend(dentry); bindex >= bstart; bindex--) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ if (h_dentry->d_inode) { ++ au_set_dbend(dentry, bindex); ++ return; ++ } ++ au_set_h_dptr(dentry, bindex, NULL); ++ } ++} ++ ++int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry) ++{ ++ aufs_bindex_t bindex, bend; ++ ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) ++ if (au_h_dptr(dentry, bindex) == h_dentry) ++ return bindex; ++ return -1; ++} +diff --git a/fs/aufs/dir.c b/fs/aufs/dir.c +new file mode 100644 +index 0000000..ffee6b4 +--- /dev/null ++++ b/fs/aufs/dir.c +@@ -0,0 +1,632 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * directory operations ++ */ ++ ++#include ++#include "aufs.h" ++ ++void au_add_nlink(struct inode *dir, struct inode *h_dir) ++{ ++ unsigned int nlink; ++ ++ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); ++ ++ nlink = dir->i_nlink; ++ nlink += h_dir->i_nlink - 2; ++ if (h_dir->i_nlink < 2) ++ nlink += 2; ++ smp_mb(); /* for i_nlink */ ++ /* 0 can happen in revaliding */ ++ set_nlink(dir, nlink); ++} ++ ++void au_sub_nlink(struct inode *dir, struct inode *h_dir) ++{ ++ unsigned int nlink; ++ ++ AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); ++ ++ nlink = dir->i_nlink; ++ nlink -= h_dir->i_nlink - 2; ++ if (h_dir->i_nlink < 2) ++ nlink -= 2; ++ smp_mb(); /* for i_nlink */ ++ /* nlink == 0 means the branch-fs is broken */ ++ set_nlink(dir, nlink); ++} ++ ++loff_t au_dir_size(struct file *file, struct dentry *dentry) ++{ ++ loff_t sz; ++ aufs_bindex_t bindex, bend; ++ struct file *h_file; ++ struct dentry *h_dentry; ++ ++ sz = 0; ++ if (file) { ++ AuDebugOn(!file_inode(file)); ++ AuDebugOn(!S_ISDIR(file_inode(file)->i_mode)); ++ ++ bend = au_fbend_dir(file); ++ for (bindex = au_fbstart(file); ++ bindex <= bend && sz < KMALLOC_MAX_SIZE; ++ bindex++) { ++ h_file = au_hf_dir(file, bindex); ++ if (h_file && file_inode(h_file)) ++ sz += vfsub_f_size_read(h_file); ++ } ++ } else { ++ AuDebugOn(!dentry); ++ AuDebugOn(!dentry->d_inode); ++ AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode)); ++ ++ bend = au_dbtaildir(dentry); ++ for (bindex = au_dbstart(dentry); ++ bindex <= bend && sz < KMALLOC_MAX_SIZE; ++ bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) ++ sz += i_size_read(h_dentry->d_inode); ++ } ++ } ++ if (sz < KMALLOC_MAX_SIZE) ++ sz = roundup_pow_of_two(sz); ++ if (sz > KMALLOC_MAX_SIZE) ++ sz = KMALLOC_MAX_SIZE; ++ else if (sz < NAME_MAX) { ++ BUILD_BUG_ON(AUFS_RDBLK_DEF < NAME_MAX); ++ sz = AUFS_RDBLK_DEF; ++ } ++ return sz; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int reopen_dir(struct file *file) ++{ ++ int err; ++ unsigned int flags; ++ aufs_bindex_t bindex, btail, bstart; ++ struct dentry *dentry, *h_dentry; ++ struct file *h_file; ++ ++ /* open all lower dirs */ ++ dentry = file->f_path.dentry; ++ bstart = au_dbstart(dentry); ++ for (bindex = au_fbstart(file); bindex < bstart; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbstart(file, bstart); ++ ++ btail = au_dbtaildir(dentry); ++ for (bindex = au_fbend_dir(file); btail < bindex; bindex--) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbend_dir(file, btail); ++ ++ flags = vfsub_file_flags(file); ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ h_file = au_hf_dir(file, bindex); ++ if (h_file) ++ continue; ++ ++ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; /* close all? */ ++ au_set_h_fptr(file, bindex, h_file); ++ } ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ err = 0; ++ ++out: ++ return err; ++} ++ ++static int do_open_dir(struct file *file, int flags) ++{ ++ int err; ++ aufs_bindex_t bindex, btail; ++ struct dentry *dentry, *h_dentry; ++ struct file *h_file; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ dentry = file->f_path.dentry; ++ file->f_version = dentry->d_inode->i_version; ++ bindex = au_dbstart(dentry); ++ au_set_fbstart(file, bindex); ++ btail = au_dbtaildir(dentry); ++ au_set_fbend_dir(file, btail); ++ for (; !err && bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!h_dentry) ++ continue; ++ ++ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); ++ if (IS_ERR(h_file)) { ++ err = PTR_ERR(h_file); ++ break; ++ } ++ au_set_h_fptr(file, bindex, h_file); ++ } ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ if (!err) ++ return 0; /* success */ ++ ++ /* close all */ ++ for (bindex = au_fbstart(file); bindex <= btail; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ au_set_fbstart(file, -1); ++ au_set_fbend_dir(file, -1); ++ ++ return err; ++} ++ ++static int aufs_open_dir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ int err; ++ struct super_block *sb; ++ struct au_fidir *fidir; ++ ++ err = -ENOMEM; ++ sb = file->f_path.dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ fidir = au_fidir_alloc(sb); ++ if (fidir) { ++ err = au_do_open(file, do_open_dir, fidir); ++ if (unlikely(err)) ++ kfree(fidir); ++ } ++ si_read_unlock(sb); ++ return err; ++} ++ ++static int aufs_release_dir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ struct au_vdir *vdir_cache; ++ struct au_finfo *finfo; ++ struct au_fidir *fidir; ++ aufs_bindex_t bindex, bend; ++ ++ finfo = au_fi(file); ++ fidir = finfo->fi_hdir; ++ if (fidir) { ++ au_sphl_del(&finfo->fi_hlist, ++ &au_sbi(file->f_path.dentry->d_sb)->si_files); ++ vdir_cache = fidir->fd_vdir_cache; /* lock-free */ ++ if (vdir_cache) ++ au_vdir_free(vdir_cache); ++ ++ bindex = finfo->fi_btop; ++ if (bindex >= 0) { ++ /* ++ * calls fput() instead of filp_close(), ++ * since no dnotify or lock for the lower file. ++ */ ++ bend = fidir->fd_bbot; ++ for (; bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ } ++ kfree(fidir); ++ finfo->fi_hdir = NULL; ++ } ++ au_finfo_fin(file); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_flush_dir(struct file *file, fl_owner_t id) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct file *h_file; ++ ++ err = 0; ++ bend = au_fbend_dir(file); ++ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { ++ h_file = au_hf_dir(file, bindex); ++ if (h_file) ++ err = vfsub_flush(h_file, id); ++ } ++ return err; ++} ++ ++static int aufs_flush_dir(struct file *file, fl_owner_t id) ++{ ++ return au_do_flush(file, id, au_do_flush_dir); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_fsync_dir_no_file(struct dentry *dentry, int datasync) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) { ++ struct path h_path; ++ ++ if (au_test_ro(sb, bindex, inode)) ++ continue; ++ h_path.dentry = au_h_dptr(dentry, bindex); ++ if (!h_path.dentry) ++ continue; ++ ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_fsync(NULL, &h_path, datasync); ++ } ++ ++ return err; ++} ++ ++static int au_do_fsync_dir(struct file *file, int datasync) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct file *h_file; ++ struct super_block *sb; ++ struct inode *inode; ++ ++ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ sb = file->f_path.dentry->d_sb; ++ inode = file_inode(file); ++ bend = au_fbend_dir(file); ++ for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { ++ h_file = au_hf_dir(file, bindex); ++ if (!h_file || au_test_ro(sb, bindex, inode)) ++ continue; ++ ++ err = vfsub_fsync(h_file, &h_file->f_path, datasync); ++ } ++ ++out: ++ return err; ++} ++ ++/* ++ * @file may be NULL ++ */ ++static int aufs_fsync_dir(struct file *file, loff_t start, loff_t end, ++ int datasync) ++{ ++ int err; ++ struct dentry *dentry; ++ struct super_block *sb; ++ struct mutex *mtx; ++ ++ err = 0; ++ dentry = file->f_path.dentry; ++ mtx = &dentry->d_inode->i_mutex; ++ mutex_lock(mtx); ++ sb = dentry->d_sb; ++ si_noflush_read_lock(sb); ++ if (file) ++ err = au_do_fsync_dir(file, datasync); ++ else { ++ di_write_lock_child(dentry); ++ err = au_do_fsync_dir_no_file(dentry, datasync); ++ } ++ au_cpup_attr_timesizes(dentry->d_inode); ++ di_write_unlock(dentry); ++ if (file) ++ fi_write_unlock(file); ++ ++ si_read_unlock(sb); ++ mutex_unlock(mtx); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_iterate(struct file *file, struct dir_context *ctx) ++{ ++ int err; ++ struct dentry *dentry; ++ struct inode *inode, *h_inode; ++ struct super_block *sb; ++ ++ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos); ++ ++ dentry = file->f_path.dentry; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ err = au_alive_dir(dentry); ++ if (!err) ++ err = au_vdir_init(file); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ if (!au_test_nfsd()) { ++ err = au_vdir_fill_de(file, ctx); ++ fsstack_copy_attr_atime(inode, h_inode); ++ } else { ++ /* ++ * nfsd filldir may call lookup_one_len(), vfs_getattr(), ++ * encode_fh() and others. ++ */ ++ atomic_inc(&h_inode->i_count); ++ di_read_unlock(dentry, AuLock_IR); ++ si_read_unlock(sb); ++ err = au_vdir_fill_de(file, ctx); ++ fsstack_copy_attr_atime(inode, h_inode); ++ fi_write_unlock(file); ++ iput(h_inode); ++ ++ AuTraceErr(err); ++ return err; ++ } ++ ++out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuTestEmpty_WHONLY 1 ++#define AuTestEmpty_CALLED (1 << 1) ++#define AuTestEmpty_SHWH (1 << 2) ++#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) ++#define au_fset_testempty(flags, name) \ ++ do { (flags) |= AuTestEmpty_##name; } while (0) ++#define au_fclr_testempty(flags, name) \ ++ do { (flags) &= ~AuTestEmpty_##name; } while (0) ++ ++#ifndef CONFIG_AUFS_SHWH ++#undef AuTestEmpty_SHWH ++#define AuTestEmpty_SHWH 0 ++#endif ++ ++struct test_empty_arg { ++ struct dir_context ctx; ++ struct au_nhash *whlist; ++ unsigned int flags; ++ int err; ++ aufs_bindex_t bindex; ++}; ++ ++static int test_empty_cb(struct dir_context *ctx, const char *__name, ++ int namelen, loff_t offset __maybe_unused, u64 ino, ++ unsigned int d_type) ++{ ++ struct test_empty_arg *arg = container_of(ctx, struct test_empty_arg, ++ ctx); ++ char *name = (void *)__name; ++ ++ arg->err = 0; ++ au_fset_testempty(arg->flags, CALLED); ++ /* smp_mb(); */ ++ if (name[0] == '.' ++ && (namelen == 1 || (name[1] == '.' && namelen == 2))) ++ goto out; /* success */ ++ ++ if (namelen <= AUFS_WH_PFX_LEN ++ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ if (au_ftest_testempty(arg->flags, WHONLY) ++ && !au_nhash_test_known_wh(arg->whlist, name, namelen)) ++ arg->err = -ENOTEMPTY; ++ goto out; ++ } ++ ++ name += AUFS_WH_PFX_LEN; ++ namelen -= AUFS_WH_PFX_LEN; ++ if (!au_nhash_test_known_wh(arg->whlist, name, namelen)) ++ arg->err = au_nhash_append_wh ++ (arg->whlist, name, namelen, ino, d_type, arg->bindex, ++ au_ftest_testempty(arg->flags, SHWH)); ++ ++out: ++ /* smp_mb(); */ ++ AuTraceErr(arg->err); ++ return arg->err; ++} ++ ++static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg) ++{ ++ int err; ++ struct file *h_file; ++ ++ h_file = au_h_open(dentry, arg->bindex, ++ O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE, ++ /*file*/NULL, /*force_wr*/0); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out; ++ ++ err = 0; ++ if (!au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE) ++ && !file_inode(h_file)->i_nlink) ++ goto out_put; ++ ++ do { ++ arg->err = 0; ++ au_fclr_testempty(arg->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_iterate_dir(h_file, &arg->ctx); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err && au_ftest_testempty(arg->flags, CALLED)); ++ ++out_put: ++ fput(h_file); ++ au_sbr_put(dentry->d_sb, arg->bindex); ++out: ++ return err; ++} ++ ++struct do_test_empty_args { ++ int *errp; ++ struct dentry *dentry; ++ struct test_empty_arg *arg; ++}; ++ ++static void call_do_test_empty(void *args) ++{ ++ struct do_test_empty_args *a = args; ++ *a->errp = do_test_empty(a->dentry, a->arg); ++} ++ ++static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg) ++{ ++ int err, wkq_err; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, arg->bindex); ++ h_inode = h_dentry->d_inode; ++ /* todo: i_mode changes anytime? */ ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ); ++ mutex_unlock(&h_inode->i_mutex); ++ if (!err) ++ err = do_test_empty(dentry, arg); ++ else { ++ struct do_test_empty_args args = { ++ .errp = &err, ++ .dentry = dentry, ++ .arg = arg ++ }; ++ unsigned int flags = arg->flags; ++ ++ wkq_err = au_wkq_wait(call_do_test_empty, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ arg->flags = flags; ++ } ++ ++ return err; ++} ++ ++int au_test_empty_lower(struct dentry *dentry) ++{ ++ int err; ++ unsigned int rdhash; ++ aufs_bindex_t bindex, bstart, btail; ++ struct au_nhash whlist; ++ struct test_empty_arg arg = { ++ .ctx = { ++ .actor = test_empty_cb ++ } ++ }; ++ int (*test_empty)(struct dentry *dentry, struct test_empty_arg *arg); ++ ++ SiMustAnyLock(dentry->d_sb); ++ ++ rdhash = au_sbi(dentry->d_sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, dentry)); ++ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ ++ arg.flags = 0; ++ arg.whlist = &whlist; ++ bstart = au_dbstart(dentry); ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) ++ au_fset_testempty(arg.flags, SHWH); ++ test_empty = do_test_empty; ++ if (au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1)) ++ test_empty = sio_test_empty; ++ arg.bindex = bstart; ++ err = test_empty(dentry, &arg); ++ if (unlikely(err)) ++ goto out_whlist; ++ ++ au_fset_testempty(arg.flags, WHONLY); ++ btail = au_dbtaildir(dentry); ++ for (bindex = bstart + 1; !err && bindex <= btail; bindex++) { ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) { ++ arg.bindex = bindex; ++ err = test_empty(dentry, &arg); ++ } ++ } ++ ++out_whlist: ++ au_nhash_wh_free(&whlist); ++out: ++ return err; ++} ++ ++int au_test_empty(struct dentry *dentry, struct au_nhash *whlist) ++{ ++ int err; ++ struct test_empty_arg arg = { ++ .ctx = { ++ .actor = test_empty_cb ++ } ++ }; ++ aufs_bindex_t bindex, btail; ++ ++ err = 0; ++ arg.whlist = whlist; ++ arg.flags = AuTestEmpty_WHONLY; ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH)) ++ au_fset_testempty(arg.flags, SHWH); ++ btail = au_dbtaildir(dentry); ++ for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) { ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry && h_dentry->d_inode) { ++ arg.bindex = bindex; ++ err = sio_test_empty(dentry, &arg); ++ } ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++const struct file_operations aufs_dir_fop = { ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++ .read = generic_read_dir, ++ .iterate = aufs_iterate, ++ .unlocked_ioctl = aufs_ioctl_dir, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = aufs_compat_ioctl_dir, ++#endif ++ .open = aufs_open_dir, ++ .release = aufs_release_dir, ++ .flush = aufs_flush_dir, ++ .fsync = aufs_fsync_dir ++}; +diff --git a/fs/aufs/dir.h b/fs/aufs/dir.h +new file mode 100644 +index 0000000..cefad5a +--- /dev/null ++++ b/fs/aufs/dir.h +@@ -0,0 +1,117 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * directory operations ++ */ ++ ++#ifndef __AUFS_DIR_H__ ++#define __AUFS_DIR_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* need to be faster and smaller */ ++ ++struct au_nhash { ++ unsigned int nh_num; ++ struct hlist_head *nh_head; ++}; ++ ++struct au_vdir_destr { ++ unsigned char len; ++ unsigned char name[0]; ++} __packed; ++ ++struct au_vdir_dehstr { ++ struct hlist_node hash; ++ struct au_vdir_destr *str; ++} ____cacheline_aligned_in_smp; ++ ++struct au_vdir_de { ++ ino_t de_ino; ++ unsigned char de_type; ++ /* caution: packed */ ++ struct au_vdir_destr de_str; ++} __packed; ++ ++struct au_vdir_wh { ++ struct hlist_node wh_hash; ++#ifdef CONFIG_AUFS_SHWH ++ ino_t wh_ino; ++ aufs_bindex_t wh_bindex; ++ unsigned char wh_type; ++#else ++ aufs_bindex_t wh_bindex; ++#endif ++ /* caution: packed */ ++ struct au_vdir_destr wh_str; ++} __packed; ++ ++union au_vdir_deblk_p { ++ unsigned char *deblk; ++ struct au_vdir_de *de; ++}; ++ ++struct au_vdir { ++ unsigned char **vd_deblk; ++ unsigned long vd_nblk; ++ struct { ++ unsigned long ul; ++ union au_vdir_deblk_p p; ++ } vd_last; ++ ++ unsigned long vd_version; ++ unsigned int vd_deblk_sz; ++ unsigned long vd_jiffy; ++} ____cacheline_aligned_in_smp; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dir.c */ ++extern const struct file_operations aufs_dir_fop; ++void au_add_nlink(struct inode *dir, struct inode *h_dir); ++void au_sub_nlink(struct inode *dir, struct inode *h_dir); ++loff_t au_dir_size(struct file *file, struct dentry *dentry); ++int au_test_empty_lower(struct dentry *dentry); ++int au_test_empty(struct dentry *dentry, struct au_nhash *whlist); ++ ++/* vdir.c */ ++unsigned int au_rdhash_est(loff_t sz); ++int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp); ++void au_nhash_wh_free(struct au_nhash *whlist); ++int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, ++ int limit); ++int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen); ++int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, ++ unsigned int d_type, aufs_bindex_t bindex, ++ unsigned char shwh); ++void au_vdir_free(struct au_vdir *vdir); ++int au_vdir_init(struct file *file); ++int au_vdir_fill_de(struct file *file, struct dir_context *ctx); ++ ++/* ioctl.c */ ++long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg); ++ ++#ifdef CONFIG_AUFS_RDU ++/* rdu.c */ ++long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg); ++#ifdef CONFIG_COMPAT ++long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg); ++#endif ++#else ++AuStub(long, au_rdu_ioctl, return -EINVAL, struct file *file, ++ unsigned int cmd, unsigned long arg) ++#ifdef CONFIG_COMPAT ++AuStub(long, au_rdu_compat_ioctl, return -EINVAL, struct file *file, ++ unsigned int cmd, unsigned long arg) ++#endif ++#endif ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DIR_H__ */ +diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c +new file mode 100644 +index 0000000..b1052e9 +--- /dev/null ++++ b/fs/aufs/dynop.c +@@ -0,0 +1,366 @@ ++/* ++ * Copyright (C) 2010-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * dynamically customizable operations for regular files ++ */ ++ ++#include "aufs.h" ++ ++#define DyPrSym(key) AuDbgSym(key->dk_op.dy_hop) ++ ++/* ++ * How large will these lists be? ++ * Usually just a few elements, 20-30 at most for each, I guess. ++ */ ++static struct au_splhead dynop[AuDyLast]; ++ ++static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op) ++{ ++ struct au_dykey *key, *tmp; ++ struct list_head *head; ++ ++ key = NULL; ++ head = &spl->head; ++ rcu_read_lock(); ++ list_for_each_entry_rcu(tmp, head, dk_list) ++ if (tmp->dk_op.dy_hop == h_op) { ++ key = tmp; ++ kref_get(&key->dk_kref); ++ break; ++ } ++ rcu_read_unlock(); ++ ++ return key; ++} ++ ++static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key) ++{ ++ struct au_dykey **k, *found; ++ const void *h_op = key->dk_op.dy_hop; ++ int i; ++ ++ found = NULL; ++ k = br->br_dykey; ++ for (i = 0; i < AuBrDynOp; i++) ++ if (k[i]) { ++ if (k[i]->dk_op.dy_hop == h_op) { ++ found = k[i]; ++ break; ++ } ++ } else ++ break; ++ if (!found) { ++ spin_lock(&br->br_dykey_lock); ++ for (; i < AuBrDynOp; i++) ++ if (k[i]) { ++ if (k[i]->dk_op.dy_hop == h_op) { ++ found = k[i]; ++ break; ++ } ++ } else { ++ k[i] = key; ++ break; ++ } ++ spin_unlock(&br->br_dykey_lock); ++ BUG_ON(i == AuBrDynOp); /* expand the array */ ++ } ++ ++ return found; ++} ++ ++/* kref_get() if @key is already added */ ++static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key) ++{ ++ struct au_dykey *tmp, *found; ++ struct list_head *head; ++ const void *h_op = key->dk_op.dy_hop; ++ ++ found = NULL; ++ head = &spl->head; ++ spin_lock(&spl->spin); ++ list_for_each_entry(tmp, head, dk_list) ++ if (tmp->dk_op.dy_hop == h_op) { ++ kref_get(&tmp->dk_kref); ++ found = tmp; ++ break; ++ } ++ if (!found) ++ list_add_rcu(&key->dk_list, head); ++ spin_unlock(&spl->spin); ++ ++ if (!found) ++ DyPrSym(key); ++ return found; ++} ++ ++static void dy_free_rcu(struct rcu_head *rcu) ++{ ++ struct au_dykey *key; ++ ++ key = container_of(rcu, struct au_dykey, dk_rcu); ++ DyPrSym(key); ++ kfree(key); ++} ++ ++static void dy_free(struct kref *kref) ++{ ++ struct au_dykey *key; ++ struct au_splhead *spl; ++ ++ key = container_of(kref, struct au_dykey, dk_kref); ++ spl = dynop + key->dk_op.dy_type; ++ au_spl_del_rcu(&key->dk_list, spl); ++ call_rcu(&key->dk_rcu, dy_free_rcu); ++} ++ ++void au_dy_put(struct au_dykey *key) ++{ ++ kref_put(&key->dk_kref, dy_free); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define DyDbgSize(cnt, op) AuDebugOn(cnt != sizeof(op)/sizeof(void *)) ++ ++#ifdef CONFIG_AUFS_DEBUG ++#define DyDbgDeclare(cnt) unsigned int cnt = 0 ++#define DyDbgInc(cnt) do { cnt++; } while (0) ++#else ++#define DyDbgDeclare(cnt) do {} while (0) ++#define DyDbgInc(cnt) do {} while (0) ++#endif ++ ++#define DySet(func, dst, src, h_op, h_sb) do { \ ++ DyDbgInc(cnt); \ ++ if (h_op->func) { \ ++ if (src.func) \ ++ dst.func = src.func; \ ++ else \ ++ AuDbg("%s %s\n", au_sbtype(h_sb), #func); \ ++ } \ ++} while (0) ++ ++#define DySetForce(func, dst, src) do { \ ++ AuDebugOn(!src.func); \ ++ DyDbgInc(cnt); \ ++ dst.func = src.func; \ ++} while (0) ++ ++#define DySetAop(func) \ ++ DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb) ++#define DySetAopForce(func) \ ++ DySetForce(func, dyaop->da_op, aufs_aop) ++ ++static void dy_aop(struct au_dykey *key, const void *h_op, ++ struct super_block *h_sb __maybe_unused) ++{ ++ struct au_dyaop *dyaop = (void *)key; ++ const struct address_space_operations *h_aop = h_op; ++ DyDbgDeclare(cnt); ++ ++ AuDbg("%s\n", au_sbtype(h_sb)); ++ ++ DySetAop(writepage); ++ DySetAopForce(readpage); /* force */ ++ DySetAop(writepages); ++ DySetAop(set_page_dirty); ++ DySetAop(readpages); ++ DySetAop(write_begin); ++ DySetAop(write_end); ++ DySetAop(bmap); ++ DySetAop(invalidatepage); ++ DySetAop(releasepage); ++ DySetAop(freepage); ++ /* these two will be changed according to an aufs mount option */ ++ DySetAop(direct_IO); ++ DySetAop(get_xip_mem); ++ DySetAop(migratepage); ++ DySetAop(launder_page); ++ DySetAop(is_partially_uptodate); ++ DySetAop(is_dirty_writeback); ++ DySetAop(error_remove_page); ++ DySetAop(swap_activate); ++ DySetAop(swap_deactivate); ++ ++ DyDbgSize(cnt, *h_aop); ++ dyaop->da_get_xip_mem = h_aop->get_xip_mem; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void dy_bug(struct kref *kref) ++{ ++ BUG(); ++} ++ ++static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br) ++{ ++ struct au_dykey *key, *old; ++ struct au_splhead *spl; ++ struct op { ++ unsigned int sz; ++ void (*set)(struct au_dykey *key, const void *h_op, ++ struct super_block *h_sb __maybe_unused); ++ }; ++ static const struct op a[] = { ++ [AuDy_AOP] = { ++ .sz = sizeof(struct au_dyaop), ++ .set = dy_aop ++ } ++ }; ++ const struct op *p; ++ ++ spl = dynop + op->dy_type; ++ key = dy_gfind_get(spl, op->dy_hop); ++ if (key) ++ goto out_add; /* success */ ++ ++ p = a + op->dy_type; ++ key = kzalloc(p->sz, GFP_NOFS); ++ if (unlikely(!key)) { ++ key = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ ++ key->dk_op.dy_hop = op->dy_hop; ++ kref_init(&key->dk_kref); ++ p->set(key, op->dy_hop, au_br_sb(br)); ++ old = dy_gadd(spl, key); ++ if (old) { ++ kfree(key); ++ key = old; ++ } ++ ++out_add: ++ old = dy_bradd(br, key); ++ if (old) ++ /* its ref-count should never be zero here */ ++ kref_put(&key->dk_kref, dy_bug); ++out: ++ return key; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * Aufs prohibits O_DIRECT by defaut even if the branch supports it. ++ * This behaviour is necessary to return an error from open(O_DIRECT) instead ++ * of the succeeding I/O. The dio mount option enables O_DIRECT and makes ++ * open(O_DIRECT) always succeed, but the succeeding I/O may return an error. ++ * See the aufs manual in detail. ++ * ++ * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the ++ * performance of fadvise() and madvise() may be affected. ++ */ ++static void dy_adx(struct au_dyaop *dyaop, int do_dx) ++{ ++ if (!do_dx) { ++ dyaop->da_op.direct_IO = NULL; ++ dyaop->da_op.get_xip_mem = NULL; ++ } else { ++ dyaop->da_op.direct_IO = aufs_aop.direct_IO; ++ dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem; ++ if (!dyaop->da_get_xip_mem) ++ dyaop->da_op.get_xip_mem = NULL; ++ } ++} ++ ++static struct au_dyaop *dy_aget(struct au_branch *br, ++ const struct address_space_operations *h_aop, ++ int do_dx) ++{ ++ struct au_dyaop *dyaop; ++ struct au_dynop op; ++ ++ op.dy_type = AuDy_AOP; ++ op.dy_haop = h_aop; ++ dyaop = (void *)dy_get(&op, br); ++ if (IS_ERR(dyaop)) ++ goto out; ++ dy_adx(dyaop, do_dx); ++ ++out: ++ return dyaop; ++} ++ ++int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode) ++{ ++ int err, do_dx; ++ struct super_block *sb; ++ struct au_branch *br; ++ struct au_dyaop *dyaop; ++ ++ AuDebugOn(!S_ISREG(h_inode->i_mode)); ++ IiMustWriteLock(inode); ++ ++ sb = inode->i_sb; ++ br = au_sbr(sb, bindex); ++ do_dx = !!au_opt_test(au_mntflags(sb), DIO); ++ dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx); ++ err = PTR_ERR(dyaop); ++ if (IS_ERR(dyaop)) ++ /* unnecessary to call dy_fput() */ ++ goto out; ++ ++ err = 0; ++ inode->i_mapping->a_ops = &dyaop->da_op; ++ ++out: ++ return err; ++} ++ ++/* ++ * Is it safe to replace a_ops during the inode/file is in operation? ++ * Yes, I hope so. ++ */ ++int au_dy_irefresh(struct inode *inode) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct inode *h_inode; ++ ++ err = 0; ++ if (S_ISREG(inode->i_mode)) { ++ bstart = au_ibstart(inode); ++ h_inode = au_h_iptr(inode, bstart); ++ err = au_dy_iaop(inode, bstart, h_inode); ++ } ++ return err; ++} ++ ++void au_dy_arefresh(int do_dx) ++{ ++ struct au_splhead *spl; ++ struct list_head *head; ++ struct au_dykey *key; ++ ++ spl = dynop + AuDy_AOP; ++ head = &spl->head; ++ spin_lock(&spl->spin); ++ list_for_each_entry(key, head, dk_list) ++ dy_adx((void *)key, do_dx); ++ spin_unlock(&spl->spin); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void __init au_dy_init(void) ++{ ++ int i; ++ ++ /* make sure that 'struct au_dykey *' can be any type */ ++ BUILD_BUG_ON(offsetof(struct au_dyaop, da_key)); ++ ++ for (i = 0; i < AuDyLast; i++) ++ au_spl_init(dynop + i); ++} ++ ++void au_dy_fin(void) ++{ ++ int i; ++ ++ for (i = 0; i < AuDyLast; i++) ++ WARN_ON(!list_empty(&dynop[i].head)); ++} +diff --git a/fs/aufs/dynop.h b/fs/aufs/dynop.h +new file mode 100644 +index 0000000..d68ec7a +--- /dev/null ++++ b/fs/aufs/dynop.h +@@ -0,0 +1,62 @@ ++/* ++ * Copyright (C) 2010-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * dynamically customizable operations (for regular files only) ++ */ ++ ++#ifndef __AUFS_DYNOP_H__ ++#define __AUFS_DYNOP_H__ ++ ++#ifdef __KERNEL__ ++ ++#include "inode.h" ++ ++enum {AuDy_AOP, AuDyLast}; ++ ++struct au_dynop { ++ int dy_type; ++ union { ++ const void *dy_hop; ++ const struct address_space_operations *dy_haop; ++ }; ++}; ++ ++struct au_dykey { ++ union { ++ struct list_head dk_list; ++ struct rcu_head dk_rcu; ++ }; ++ struct au_dynop dk_op; ++ ++ /* ++ * during I am in the branch local array, kref is gotten. when the ++ * branch is removed, kref is put. ++ */ ++ struct kref dk_kref; ++}; ++ ++/* stop unioning since their sizes are very different from each other */ ++struct au_dyaop { ++ struct au_dykey da_key; ++ struct address_space_operations da_op; /* not const */ ++ int (*da_get_xip_mem)(struct address_space *, pgoff_t, int, ++ void **, unsigned long *); ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dynop.c */ ++struct au_branch; ++void au_dy_put(struct au_dykey *key); ++int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode); ++int au_dy_irefresh(struct inode *inode); ++void au_dy_arefresh(int do_dio); ++ ++void __init au_dy_init(void); ++void au_dy_fin(void); ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_DYNOP_H__ */ +diff --git a/fs/aufs/export.c b/fs/aufs/export.c +new file mode 100644 +index 0000000..61501e1 +--- /dev/null ++++ b/fs/aufs/export.c +@@ -0,0 +1,818 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * export via nfs ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "../fs/mount.h" ++#include "aufs.h" ++ ++union conv { ++#ifdef CONFIG_AUFS_INO_T_64 ++ __u32 a[2]; ++#else ++ __u32 a[1]; ++#endif ++ ino_t ino; ++}; ++ ++static ino_t decode_ino(__u32 *a) ++{ ++ union conv u; ++ ++ BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a)); ++ u.a[0] = a[0]; ++#ifdef CONFIG_AUFS_INO_T_64 ++ u.a[1] = a[1]; ++#endif ++ return u.ino; ++} ++ ++static void encode_ino(__u32 *a, ino_t ino) ++{ ++ union conv u; ++ ++ u.ino = ino; ++ a[0] = u.a[0]; ++#ifdef CONFIG_AUFS_INO_T_64 ++ a[1] = u.a[1]; ++#endif ++} ++ ++/* NFS file handle */ ++enum { ++ Fh_br_id, ++ Fh_sigen, ++#ifdef CONFIG_AUFS_INO_T_64 ++ /* support 64bit inode number */ ++ Fh_ino1, ++ Fh_ino2, ++ Fh_dir_ino1, ++ Fh_dir_ino2, ++#else ++ Fh_ino1, ++ Fh_dir_ino1, ++#endif ++ Fh_igen, ++ Fh_h_type, ++ Fh_tail, ++ ++ Fh_ino = Fh_ino1, ++ Fh_dir_ino = Fh_dir_ino1 ++}; ++ ++static int au_test_anon(struct dentry *dentry) ++{ ++ /* note: read d_flags without d_lock */ ++ return !!(dentry->d_flags & DCACHE_DISCONNECTED); ++} ++ ++int au_test_nfsd(void) ++{ ++ int ret; ++ struct task_struct *tsk = current; ++ char comm[sizeof(tsk->comm)]; ++ ++ ret = 0; ++ if (tsk->flags & PF_KTHREAD) { ++ get_task_comm(comm, tsk); ++ ret = !strcmp(comm, "nfsd"); ++ } ++ ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* inode generation external table */ ++ ++void au_xigen_inc(struct inode *inode) ++{ ++ loff_t pos; ++ ssize_t sz; ++ __u32 igen; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ sb = inode->i_sb; ++ AuDebugOn(!au_opt_test(au_mntflags(sb), XINO)); ++ ++ sbinfo = au_sbi(sb); ++ pos = inode->i_ino; ++ pos *= sizeof(igen); ++ igen = inode->i_generation + 1; ++ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen, ++ sizeof(igen), &pos); ++ if (sz == sizeof(igen)) ++ return; /* success */ ++ ++ if (unlikely(sz >= 0)) ++ AuIOErr("xigen error (%zd)\n", sz); ++} ++ ++int au_xigen_new(struct inode *inode) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ err = 0; ++ /* todo: dirty, at mount time */ ++ if (inode->i_ino == AUFS_ROOT_INO) ++ goto out; ++ sb = inode->i_sb; ++ SiMustAnyLock(sb); ++ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) ++ goto out; ++ ++ err = -EFBIG; ++ pos = inode->i_ino; ++ if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) { ++ AuIOErr1("too large i%lld\n", pos); ++ goto out; ++ } ++ pos *= sizeof(inode->i_generation); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ file = sbinfo->si_xigen; ++ BUG_ON(!file); ++ ++ if (vfsub_f_size_read(file) ++ < pos + sizeof(inode->i_generation)) { ++ inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next); ++ sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, ++ sizeof(inode->i_generation), &pos); ++ } else ++ sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, ++ sizeof(inode->i_generation), &pos); ++ if (sz == sizeof(inode->i_generation)) ++ goto out; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xigen error (%zd)\n", sz); ++ } ++ ++out: ++ return err; ++} ++ ++int au_xigen_set(struct super_block *sb, struct file *base) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ file = au_xino_create2(base, sbinfo->si_xigen); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ err = 0; ++ if (sbinfo->si_xigen) ++ fput(sbinfo->si_xigen); ++ sbinfo->si_xigen = file; ++ ++out: ++ return err; ++} ++ ++void au_xigen_clr(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ if (sbinfo->si_xigen) { ++ fput(sbinfo->si_xigen); ++ sbinfo->si_xigen = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino, ++ ino_t dir_ino) ++{ ++ struct dentry *dentry, *d; ++ struct inode *inode; ++ unsigned int sigen; ++ ++ dentry = NULL; ++ inode = ilookup(sb, ino); ++ if (!inode) ++ goto out; ++ ++ dentry = ERR_PTR(-ESTALE); ++ sigen = au_sigen(sb); ++ if (unlikely(is_bad_inode(inode) ++ || IS_DEADDIR(inode) ++ || sigen != au_iigen(inode, NULL))) ++ goto out_iput; ++ ++ dentry = NULL; ++ if (!dir_ino || S_ISDIR(inode->i_mode)) ++ dentry = d_find_alias(inode); ++ else { ++ spin_lock(&inode->i_lock); ++ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) { ++ spin_lock(&d->d_lock); ++ if (!au_test_anon(d) ++ && d->d_parent->d_inode->i_ino == dir_ino) { ++ dentry = dget_dlock(d); ++ spin_unlock(&d->d_lock); ++ break; ++ } ++ spin_unlock(&d->d_lock); ++ } ++ spin_unlock(&inode->i_lock); ++ } ++ if (unlikely(dentry && au_digen_test(dentry, sigen))) { ++ /* need to refresh */ ++ dput(dentry); ++ dentry = NULL; ++ } ++ ++out_iput: ++ iput(inode); ++out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: dirty? */ ++/* if exportfs_decode_fh() passed vfsmount*, we could be happy */ ++ ++struct au_compare_mnt_args { ++ /* input */ ++ struct super_block *sb; ++ ++ /* output */ ++ struct vfsmount *mnt; ++}; ++ ++static int au_compare_mnt(struct vfsmount *mnt, void *arg) ++{ ++ struct au_compare_mnt_args *a = arg; ++ ++ if (mnt->mnt_sb != a->sb) ++ return 0; ++ a->mnt = mntget(mnt); ++ return 1; ++} ++ ++static struct vfsmount *au_mnt_get(struct super_block *sb) ++{ ++ int err; ++ struct path root; ++ struct au_compare_mnt_args args = { ++ .sb = sb ++ }; ++ ++ get_fs_root(current->fs, &root); ++ rcu_read_lock(); ++ err = iterate_mounts(au_compare_mnt, &args, root.mnt); ++ rcu_read_unlock(); ++ path_put(&root); ++ AuDebugOn(!err); ++ AuDebugOn(!args.mnt); ++ return args.mnt; ++} ++ ++struct au_nfsd_si_lock { ++ unsigned int sigen; ++ aufs_bindex_t bindex, br_id; ++ unsigned char force_lock; ++}; ++ ++static int si_nfsd_read_lock(struct super_block *sb, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ ++ si_read_lock(sb, AuLock_FLUSH); ++ ++ /* branch id may be wrapped around */ ++ err = 0; ++ bindex = au_br_index(sb, nsi_lock->br_id); ++ if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb)) ++ goto out; /* success */ ++ ++ err = -ESTALE; ++ bindex = -1; ++ if (!nsi_lock->force_lock) ++ si_read_unlock(sb); ++ ++out: ++ nsi_lock->bindex = bindex; ++ return err; ++} ++ ++struct find_name_by_ino { ++ struct dir_context ctx; ++ int called, found; ++ ino_t ino; ++ char *name; ++ int namelen; ++}; ++ ++static int ++find_name_by_ino(struct dir_context *ctx, const char *name, int namelen, ++ loff_t offset, u64 ino, unsigned int d_type) ++{ ++ struct find_name_by_ino *a = container_of(ctx, struct find_name_by_ino, ++ ctx); ++ ++ a->called++; ++ if (a->ino != ino) ++ return 0; ++ ++ memcpy(a->name, name, namelen); ++ a->namelen = namelen; ++ a->found = 1; ++ return 1; ++} ++ ++static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry, *parent; ++ struct file *file; ++ struct inode *dir; ++ struct find_name_by_ino arg = { ++ .ctx = { ++ .actor = find_name_by_ino ++ } ++ }; ++ int err; ++ ++ parent = path->dentry; ++ if (nsi_lock) ++ si_read_unlock(parent->d_sb); ++ file = vfsub_dentry_open(path, au_dir_roflags); ++ dentry = (void *)file; ++ if (IS_ERR(file)) ++ goto out; ++ ++ dentry = ERR_PTR(-ENOMEM); ++ arg.name = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!arg.name)) ++ goto out_file; ++ arg.ino = ino; ++ arg.found = 0; ++ do { ++ arg.called = 0; ++ /* smp_mb(); */ ++ err = vfsub_iterate_dir(file, &arg.ctx); ++ } while (!err && !arg.found && arg.called); ++ dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_name; ++ /* instead of ENOENT */ ++ dentry = ERR_PTR(-ESTALE); ++ if (!arg.found) ++ goto out_name; ++ ++ /* do not call vfsub_lkup_one() */ ++ dir = parent->d_inode; ++ mutex_lock(&dir->i_mutex); ++ dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen); ++ mutex_unlock(&dir->i_mutex); ++ AuTraceErrPtr(dentry); ++ if (IS_ERR(dentry)) ++ goto out_name; ++ AuDebugOn(au_test_anon(dentry)); ++ if (unlikely(!dentry->d_inode)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ENOENT); ++ } ++ ++out_name: ++ free_page((unsigned long)arg.name); ++out_file: ++ fput(file); ++out: ++ if (unlikely(nsi_lock ++ && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0)) ++ if (!IS_ERR(dentry)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino, ++ ino_t dir_ino, ++ struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry; ++ struct path path; ++ ++ if (dir_ino != AUFS_ROOT_INO) { ++ path.dentry = decode_by_ino(sb, dir_ino, 0); ++ dentry = path.dentry; ++ if (!path.dentry || IS_ERR(path.dentry)) ++ goto out; ++ AuDebugOn(au_test_anon(path.dentry)); ++ } else ++ path.dentry = dget(sb->s_root); ++ ++ path.mnt = au_mnt_get(sb); ++ dentry = au_lkup_by_ino(&path, ino, nsi_lock); ++ path_put(&path); ++ ++out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int h_acceptable(void *expv, struct dentry *dentry) ++{ ++ return 1; ++} ++ ++static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath, ++ char *buf, int len, struct super_block *sb) ++{ ++ char *p; ++ int n; ++ struct path path; ++ ++ p = d_path(h_rootpath, buf, len); ++ if (IS_ERR(p)) ++ goto out; ++ n = strlen(p); ++ ++ path.mnt = h_rootpath->mnt; ++ path.dentry = h_parent; ++ p = d_path(&path, buf, len); ++ if (IS_ERR(p)) ++ goto out; ++ if (n != 1) ++ p += n; ++ ++ path.mnt = au_mnt_get(sb); ++ path.dentry = sb->s_root; ++ p = d_path(&path, buf, len - strlen(p)); ++ mntput(path.mnt); ++ if (IS_ERR(p)) ++ goto out; ++ if (n != 1) ++ p[strlen(p)] = '/'; ++ ++out: ++ AuTraceErrPtr(p); ++ return p; ++} ++ ++static ++struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh, ++ int fh_len, struct au_nfsd_si_lock *nsi_lock) ++{ ++ struct dentry *dentry, *h_parent, *root; ++ struct super_block *h_sb; ++ char *pathname, *p; ++ struct vfsmount *h_mnt; ++ struct au_branch *br; ++ int err; ++ struct path path; ++ ++ br = au_sbr(sb, nsi_lock->bindex); ++ h_mnt = au_br_mnt(br); ++ h_sb = h_mnt->mnt_sb; ++ /* todo: call lower fh_to_dentry()? fh_to_parent()? */ ++ h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail), ++ fh_len - Fh_tail, fh[Fh_h_type], ++ h_acceptable, /*context*/NULL); ++ dentry = h_parent; ++ if (unlikely(!h_parent || IS_ERR(h_parent))) { ++ AuWarn1("%s decode_fh failed, %ld\n", ++ au_sbtype(h_sb), PTR_ERR(h_parent)); ++ goto out; ++ } ++ dentry = NULL; ++ if (unlikely(au_test_anon(h_parent))) { ++ AuWarn1("%s decode_fh returned a disconnected dentry\n", ++ au_sbtype(h_sb)); ++ goto out_h_parent; ++ } ++ ++ dentry = ERR_PTR(-ENOMEM); ++ pathname = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!pathname)) ++ goto out_h_parent; ++ ++ root = sb->s_root; ++ path.mnt = h_mnt; ++ di_read_lock_parent(root, !AuLock_IR); ++ path.dentry = au_h_dptr(root, nsi_lock->bindex); ++ di_read_unlock(root, !AuLock_IR); ++ p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb); ++ dentry = (void *)p; ++ if (IS_ERR(p)) ++ goto out_pathname; ++ ++ si_read_unlock(sb); ++ err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); ++ dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_relock; ++ ++ dentry = ERR_PTR(-ENOENT); ++ AuDebugOn(au_test_anon(path.dentry)); ++ if (unlikely(!path.dentry->d_inode)) ++ goto out_path; ++ ++ if (ino != path.dentry->d_inode->i_ino) ++ dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL); ++ else ++ dentry = dget(path.dentry); ++ ++out_path: ++ path_put(&path); ++out_relock: ++ if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0)) ++ if (!IS_ERR(dentry)) { ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++ } ++out_pathname: ++ free_page((unsigned long)pathname); ++out_h_parent: ++ dput(h_parent); ++out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry * ++aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, ++ int fh_type) ++{ ++ struct dentry *dentry; ++ __u32 *fh = fid->raw; ++ struct au_branch *br; ++ ino_t ino, dir_ino; ++ struct au_nfsd_si_lock nsi_lock = { ++ .force_lock = 0 ++ }; ++ ++ dentry = ERR_PTR(-ESTALE); ++ /* it should never happen, but the file handle is unreliable */ ++ if (unlikely(fh_len < Fh_tail)) ++ goto out; ++ nsi_lock.sigen = fh[Fh_sigen]; ++ nsi_lock.br_id = fh[Fh_br_id]; ++ ++ /* branch id may be wrapped around */ ++ br = NULL; ++ if (unlikely(si_nfsd_read_lock(sb, &nsi_lock))) ++ goto out; ++ nsi_lock.force_lock = 1; ++ ++ /* is this inode still cached? */ ++ ino = decode_ino(fh + Fh_ino); ++ /* it should never happen */ ++ if (unlikely(ino == AUFS_ROOT_INO)) ++ goto out; ++ ++ dir_ino = decode_ino(fh + Fh_dir_ino); ++ dentry = decode_by_ino(sb, ino, dir_ino); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (dentry) ++ goto accept; ++ ++ /* is the parent dir cached? */ ++ br = au_sbr(sb, nsi_lock.bindex); ++ atomic_inc(&br->br_count); ++ dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (dentry) ++ goto accept; ++ ++ /* lookup path */ ++ dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock); ++ if (IS_ERR(dentry)) ++ goto out_unlock; ++ if (unlikely(!dentry)) ++ /* todo?: make it ESTALE */ ++ goto out_unlock; ++ ++accept: ++ if (!au_digen_test(dentry, au_sigen(sb)) ++ && dentry->d_inode->i_generation == fh[Fh_igen]) ++ goto out_unlock; /* success */ ++ ++ dput(dentry); ++ dentry = ERR_PTR(-ESTALE); ++out_unlock: ++ if (br) ++ atomic_dec(&br->br_count); ++ si_read_unlock(sb); ++out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++#if 0 /* reserved for future use */ ++/* support subtreecheck option */ ++static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid, ++ int fh_len, int fh_type) ++{ ++ struct dentry *parent; ++ __u32 *fh = fid->raw; ++ ino_t dir_ino; ++ ++ dir_ino = decode_ino(fh + Fh_dir_ino); ++ parent = decode_by_ino(sb, dir_ino, 0); ++ if (IS_ERR(parent)) ++ goto out; ++ if (!parent) ++ parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]), ++ dir_ino, fh, fh_len); ++ ++out: ++ AuTraceErrPtr(parent); ++ return parent; ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_encode_fh(struct inode *inode, __u32 *fh, int *max_len, ++ struct inode *dir) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct super_block *sb, *h_sb; ++ struct dentry *dentry, *parent, *h_parent; ++ struct inode *h_dir; ++ struct au_branch *br; ++ ++ err = -ENOSPC; ++ if (unlikely(*max_len <= Fh_tail)) { ++ AuWarn1("NFSv2 client (max_len %d)?\n", *max_len); ++ goto out; ++ } ++ ++ err = FILEID_ROOT; ++ if (inode->i_ino == AUFS_ROOT_INO) { ++ AuDebugOn(inode->i_ino != AUFS_ROOT_INO); ++ goto out; ++ } ++ ++ h_parent = NULL; ++ sb = inode->i_sb; ++ err = si_read_lock(sb, AuLock_FLUSH); ++ if (unlikely(err)) ++ goto out; ++ ++#ifdef CONFIG_AUFS_DEBUG ++ if (unlikely(!au_opt_test(au_mntflags(sb), XINO))) ++ AuWarn1("NFS-exporting requires xino\n"); ++#endif ++ err = -EIO; ++ parent = NULL; ++ ii_read_lock_child(inode); ++ bindex = au_ibstart(inode); ++ if (!dir) { ++ dentry = d_find_any_alias(inode); ++ if (unlikely(!dentry)) ++ goto out_unlock; ++ AuDebugOn(au_test_anon(dentry)); ++ parent = dget_parent(dentry); ++ dput(dentry); ++ if (unlikely(!parent)) ++ goto out_unlock; ++ dir = parent->d_inode; ++ } ++ ++ ii_read_lock_parent(dir); ++ h_dir = au_h_iptr(dir, bindex); ++ ii_read_unlock(dir); ++ if (unlikely(!h_dir)) ++ goto out_parent; ++ h_parent = d_find_any_alias(h_dir); ++ if (unlikely(!h_parent)) ++ goto out_hparent; ++ ++ err = -EPERM; ++ br = au_sbr(sb, bindex); ++ h_sb = au_br_sb(br); ++ if (unlikely(!h_sb->s_export_op)) { ++ AuErr1("%s branch is not exportable\n", au_sbtype(h_sb)); ++ goto out_hparent; ++ } ++ ++ fh[Fh_br_id] = br->br_id; ++ fh[Fh_sigen] = au_sigen(sb); ++ encode_ino(fh + Fh_ino, inode->i_ino); ++ encode_ino(fh + Fh_dir_ino, dir->i_ino); ++ fh[Fh_igen] = inode->i_generation; ++ ++ *max_len -= Fh_tail; ++ fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail), ++ max_len, ++ /*connectable or subtreecheck*/0); ++ err = fh[Fh_h_type]; ++ *max_len += Fh_tail; ++ /* todo: macros? */ ++ if (err != FILEID_INVALID) ++ err = 99; ++ else ++ AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb)); ++ ++out_hparent: ++ dput(h_parent); ++out_parent: ++ dput(parent); ++out_unlock: ++ ii_read_unlock(inode); ++ si_read_unlock(sb); ++out: ++ if (unlikely(err < 0)) ++ err = FILEID_INVALID; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_commit_metadata(struct inode *inode) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct super_block *sb; ++ struct inode *h_inode; ++ int (*f)(struct inode *inode); ++ ++ sb = inode->i_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ ii_write_lock_child(inode); ++ bindex = au_ibstart(inode); ++ AuDebugOn(bindex < 0); ++ h_inode = au_h_iptr(inode, bindex); ++ ++ f = h_inode->i_sb->s_export_op->commit_metadata; ++ if (f) ++ err = f(h_inode); ++ else { ++ struct writeback_control wbc = { ++ .sync_mode = WB_SYNC_ALL, ++ .nr_to_write = 0 /* metadata only */ ++ }; ++ ++ err = sync_inode(h_inode, &wbc); ++ } ++ ++ au_cpup_attr_timesizes(inode); ++ ii_write_unlock(inode); ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct export_operations aufs_export_op = { ++ .fh_to_dentry = aufs_fh_to_dentry, ++ /* .fh_to_parent = aufs_fh_to_parent, */ ++ .encode_fh = aufs_encode_fh, ++ .commit_metadata = aufs_commit_metadata ++}; ++ ++void au_export_init(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ __u32 u; ++ ++ sb->s_export_op = &aufs_export_op; ++ sbinfo = au_sbi(sb); ++ sbinfo->si_xigen = NULL; ++ get_random_bytes(&u, sizeof(u)); ++ BUILD_BUG_ON(sizeof(u) != sizeof(int)); ++ atomic_set(&sbinfo->si_xigen_next, u); ++} +diff --git a/fs/aufs/f_op.c b/fs/aufs/f_op.c +new file mode 100644 +index 0000000..41c4c4a +--- /dev/null ++++ b/fs/aufs/f_op.c +@@ -0,0 +1,801 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * file and vm operations ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++int au_do_open_nondir(struct file *file, int flags) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct au_finfo *finfo; ++ struct inode *h_inode; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ dentry = file->f_path.dentry; ++ finfo = au_fi(file); ++ memset(&finfo->fi_htop, 0, sizeof(finfo->fi_htop)); ++ atomic_set(&finfo->fi_mmapped, 0); ++ bindex = au_dbstart(dentry); ++ h_file = au_h_open(dentry, bindex, flags, file, /*force_wr*/0); ++ if (IS_ERR(h_file)) ++ err = PTR_ERR(h_file); ++ else { ++ if ((flags & __O_TMPFILE) ++ && !(flags & O_EXCL)) { ++ h_inode = file_inode(h_file); ++ spin_lock(&h_inode->i_lock); ++ h_inode->i_state |= I_LINKABLE; ++ spin_unlock(&h_inode->i_lock); ++ } ++ au_set_fbstart(file, bindex); ++ au_set_h_fptr(file, bindex, h_file); ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ } ++ ++ return err; ++} ++ ++static int aufs_open_nondir(struct inode *inode __maybe_unused, ++ struct file *file) ++{ ++ int err; ++ struct super_block *sb; ++ ++ AuDbg("%pD, f_flags 0x%x, f_mode 0x%x\n", ++ file, vfsub_file_flags(file), file->f_mode); ++ ++ sb = file->f_path.dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ err = au_do_open(file, au_do_open_nondir, /*fidir*/NULL); ++ si_read_unlock(sb); ++ return err; ++} ++ ++int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file) ++{ ++ struct au_finfo *finfo; ++ aufs_bindex_t bindex; ++ ++ finfo = au_fi(file); ++ au_sphl_del(&finfo->fi_hlist, ++ &au_sbi(file->f_path.dentry->d_sb)->si_files); ++ bindex = finfo->fi_btop; ++ if (bindex >= 0) ++ au_set_h_fptr(file, bindex, NULL); ++ ++ au_finfo_fin(file); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_do_flush_nondir(struct file *file, fl_owner_t id) ++{ ++ int err; ++ struct file *h_file; ++ ++ err = 0; ++ h_file = au_hf_top(file); ++ if (h_file) ++ err = vfsub_flush(h_file, id); ++ return err; ++} ++ ++static int aufs_flush_nondir(struct file *file, fl_owner_t id) ++{ ++ return au_do_flush(file, id, au_do_flush_nondir); ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * read and write functions acquire [fdi]_rwsem once, but release before ++ * mmap_sem. This is because to stop a race condition between mmap(2). ++ * Releasing these aufs-rwsem should be safe, no branch-mamagement (by keeping ++ * si_rwsem), no harmful copy-up should happen. Actually copy-up may happen in ++ * read functions after [fdi]_rwsem are released, but it should be harmless. ++ */ ++ ++static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ struct dentry *dentry; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ /* filedata may be obsoleted by concurrent copyup, but no problem */ ++ err = vfsub_read_u(h_file, buf, count, ppos); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ /* update without lock, I don't think it a problem */ ++ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file)); ++ fput(h_file); ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ++ * todo: very ugly ++ * it locks both of i_mutex and si_rwsem for read in safe. ++ * if the plink maintenance mode continues forever (that is the problem), ++ * may loop forever. ++ */ ++static void au_mtx_and_read_lock(struct inode *inode) ++{ ++ int err; ++ struct super_block *sb = inode->i_sb; ++ ++ while (1) { ++ mutex_lock(&inode->i_mutex); ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (!err) ++ break; ++ mutex_unlock(&inode->i_mutex); ++ si_read_lock(sb, AuLock_NOPLMW); ++ si_read_unlock(sb); ++ } ++} ++ ++static ssize_t aufs_write(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ blkcnt_t blks; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode, *h_inode; ++ struct super_block *sb; ++ struct file *h_file; ++ char __user *buf = (char __user *)ubuf; ++ ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ au_mtx_and_read_lock(inode); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) { ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ goto out; ++ } ++ ++ bstart = au_fbstart(file); ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ h_inode = file_inode(h_file); ++ blks = h_inode->i_blocks; ++ au_unpin(&pin); ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ ++ err = vfsub_write_u(h_file, buf, count, ppos); ++ ii_write_lock_child(inode); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = file_inode(h_file)->i_mode; ++ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); ++ if (err > 0) ++ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks); ++ ii_write_unlock(inode); ++ fput(h_file); ++ ++out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static ssize_t au_do_iter(struct file *h_file, int rw, struct kiocb *kio, ++ struct iov_iter *iov_iter) ++{ ++ ssize_t err; ++ struct file *file; ++ ssize_t (*iter)(struct kiocb *, struct iov_iter *); ++ ssize_t (*aio)(struct kiocb *, const struct iovec *, unsigned long, ++ loff_t); ++ ++ err = security_file_permission(h_file, rw); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -ENOSYS; ++ iter = NULL; ++ aio = NULL; ++ if (rw == MAY_READ) { ++ iter = h_file->f_op->read_iter; ++ aio = h_file->f_op->aio_read; ++ } else if (rw == MAY_WRITE) { ++ iter = h_file->f_op->write_iter; ++ aio = h_file->f_op->aio_write; ++ } ++ ++ file = kio->ki_filp; ++ kio->ki_filp = h_file; ++ if (iter) { ++ lockdep_off(); ++ err = iter(kio, iov_iter); ++ lockdep_on(); ++ } else if (aio) { ++ lockdep_off(); ++ err = aio(kio, iov_iter->iov, iov_iter->nr_segs, kio->ki_pos); ++ lockdep_on(); ++ } else ++ /* currently there is no such fs */ ++ WARN_ON_ONCE(1); ++ kio->ki_filp = file; ++ ++out: ++ return err; ++} ++ ++static ssize_t aufs_read_iter(struct kiocb *kio, struct iov_iter *iov_iter) ++{ ++ ssize_t err; ++ struct file *file, *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ file = kio->ki_filp; ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ err = au_do_iter(h_file, MAY_READ, kio, iov_iter); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ /* update without lock, I don't think it a problem */ ++ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file)); ++ fput(h_file); ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t aufs_write_iter(struct kiocb *kio, struct iov_iter *iov_iter) ++{ ++ ssize_t err; ++ blkcnt_t blks; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode, *h_inode; ++ struct file *file, *h_file; ++ struct super_block *sb; ++ ++ file = kio->ki_filp; ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ au_mtx_and_read_lock(inode); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) { ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ goto out; ++ } ++ ++ bstart = au_fbstart(file); ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ h_inode = file_inode(h_file); ++ blks = h_inode->i_blocks; ++ au_unpin(&pin); ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ ++ err = au_do_iter(h_file, MAY_WRITE, kio, iov_iter); ++ ii_write_lock_child(inode); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = file_inode(h_file)->i_mode; ++ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); ++ if (err > 0) ++ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks); ++ ii_write_unlock(inode); ++ fput(h_file); ++ ++out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) ++{ ++ ssize_t err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -EINVAL; ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ if (au_test_loopback_kthread()) { ++ au_warn_loopback(h_file->f_path.dentry->d_sb); ++ if (file->f_mapping != h_file->f_mapping) { ++ file->f_mapping = h_file->f_mapping; ++ smp_mb(); /* unnecessary? */ ++ } ++ } ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++ err = vfsub_splice_to(h_file, ppos, pipe, len, flags); ++ /* todo: necessasry? */ ++ /* file->f_ra = h_file->f_ra; */ ++ /* update without lock, I don't think it a problem */ ++ fsstack_copy_attr_atime(dentry->d_inode, file_inode(h_file)); ++ fput(h_file); ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++static ssize_t ++aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, ++ size_t len, unsigned int flags) ++{ ++ ssize_t err; ++ blkcnt_t blks; ++ aufs_bindex_t bstart; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode, *h_inode; ++ struct super_block *sb; ++ struct file *h_file; ++ ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ au_mtx_and_read_lock(inode); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) { ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ goto out; ++ } ++ ++ bstart = au_fbstart(file); ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ h_inode = file_inode(h_file); ++ blks = h_inode->i_blocks; ++ au_unpin(&pin); ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ ++ err = vfsub_splice_from(pipe, h_file, ppos, len, flags); ++ ii_write_lock_child(inode); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = file_inode(h_file)->i_mode; ++ AuDbg("blks %llu, %llu\n", (u64)blks, (u64)h_inode->i_blocks); ++ if (err > 0) ++ au_fhsm_wrote(sb, bstart, /*force*/h_inode->i_blocks > blks); ++ ii_write_unlock(inode); ++ fput(h_file); ++ ++out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++static long aufs_fallocate(struct file *file, int mode, loff_t offset, ++ loff_t len) ++{ ++ long err; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct super_block *sb; ++ struct inode *inode; ++ struct file *h_file; ++ ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ inode = dentry->d_inode; ++ au_mtx_and_read_lock(inode); ++ ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) { ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ goto out; ++ } ++ ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ au_unpin(&pin); ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++ ++ lockdep_off(); ++ err = vfs_fallocate(h_file, mode, offset, len); ++ lockdep_on(); ++ ii_write_lock_child(inode); ++ au_cpup_attr_timesizes(inode); ++ inode->i_mode = file_inode(h_file)->i_mode; ++ ii_write_unlock(inode); ++ fput(h_file); ++ ++out: ++ si_read_unlock(sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * The locking order around current->mmap_sem. ++ * - in most and regular cases ++ * file I/O syscall -- aufs_read() or something ++ * -- si_rwsem for read -- mmap_sem ++ * (Note that [fdi]i_rwsem are released before mmap_sem). ++ * - in mmap case ++ * mmap(2) -- mmap_sem -- aufs_mmap() -- si_rwsem for read -- [fdi]i_rwsem ++ * This AB-BA order is definitly bad, but is not a problem since "si_rwsem for ++ * read" allows muliple processes to acquire it and [fdi]i_rwsem are not held in ++ * file I/O. Aufs needs to stop lockdep in aufs_mmap() though. ++ * It means that when aufs acquires si_rwsem for write, the process should never ++ * acquire mmap_sem. ++ * ++ * Actually aufs_iterate() holds [fdi]i_rwsem before mmap_sem, but this is not a ++ * problem either since any directory is not able to be mmap-ed. ++ * The similar scenario is applied to aufs_readlink() too. ++ */ ++ ++#if 0 /* stop calling security_file_mmap() */ ++/* cf. linux/include/linux/mman.h: calc_vm_prot_bits() */ ++#define AuConv_VM_PROT(f, b) _calc_vm_trans(f, VM_##b, PROT_##b) ++ ++static unsigned long au_arch_prot_conv(unsigned long flags) ++{ ++ /* currently ppc64 only */ ++#ifdef CONFIG_PPC64 ++ /* cf. linux/arch/powerpc/include/asm/mman.h */ ++ AuDebugOn(arch_calc_vm_prot_bits(-1) != VM_SAO); ++ return AuConv_VM_PROT(flags, SAO); ++#else ++ AuDebugOn(arch_calc_vm_prot_bits(-1)); ++ return 0; ++#endif ++} ++ ++static unsigned long au_prot_conv(unsigned long flags) ++{ ++ return AuConv_VM_PROT(flags, READ) ++ | AuConv_VM_PROT(flags, WRITE) ++ | AuConv_VM_PROT(flags, EXEC) ++ | au_arch_prot_conv(flags); ++} ++ ++/* cf. linux/include/linux/mman.h: calc_vm_flag_bits() */ ++#define AuConv_VM_MAP(f, b) _calc_vm_trans(f, VM_##b, MAP_##b) ++ ++static unsigned long au_flag_conv(unsigned long flags) ++{ ++ return AuConv_VM_MAP(flags, GROWSDOWN) ++ | AuConv_VM_MAP(flags, DENYWRITE) ++ | AuConv_VM_MAP(flags, LOCKED); ++} ++#endif ++ ++static int aufs_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ const unsigned char wlock ++ = (file->f_mode & FMODE_WRITE) && (vma->vm_flags & VM_SHARED); ++ struct dentry *dentry; ++ struct super_block *sb; ++ struct file *h_file; ++ struct au_branch *br; ++ struct au_pin pin; ++ ++ AuDbgVmRegion(file, vma); ++ ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ lockdep_off(); ++ si_read_lock(sb, AuLock_NOPLMW); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ if (wlock) { ++ err = au_ready_to_write(file, -1, &pin); ++ di_write_unlock(dentry); ++ if (unlikely(err)) { ++ fi_write_unlock(file); ++ goto out; ++ } ++ au_unpin(&pin); ++ } else ++ di_write_unlock(dentry); ++ ++ bstart = au_fbstart(file); ++ br = au_sbr(sb, bstart); ++ h_file = au_hf_top(file); ++ get_file(h_file); ++ au_set_mmapped(file); ++ fi_write_unlock(file); ++ lockdep_on(); ++ ++ au_vm_file_reset(vma, h_file); ++ /* ++ * we cannot call security_mmap_file() here since it may acquire ++ * mmap_sem or i_mutex. ++ * ++ * err = security_mmap_file(h_file, au_prot_conv(vma->vm_flags), ++ * au_flag_conv(vma->vm_flags)); ++ */ ++ if (!err) ++ err = h_file->f_op->mmap(h_file, vma); ++ if (unlikely(err)) ++ goto out_reset; ++ ++ au_vm_prfile_set(vma, file); ++ /* update without lock, I don't think it a problem */ ++ fsstack_copy_attr_atime(file_inode(file), file_inode(h_file)); ++ goto out_fput; /* success */ ++ ++out_reset: ++ au_unset_mmapped(file); ++ au_vm_file_reset(vma, file); ++out_fput: ++ fput(h_file); ++ lockdep_off(); ++out: ++ si_read_unlock(sb); ++ lockdep_on(); ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_fsync_nondir(struct file *file, loff_t start, loff_t end, ++ int datasync) ++{ ++ int err; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct file *h_file; ++ struct super_block *sb; ++ ++ dentry = file->f_path.dentry; ++ inode = dentry->d_inode; ++ sb = dentry->d_sb; ++ mutex_lock(&inode->i_mutex); ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (unlikely(err)) ++ goto out; ++ ++ err = 0; /* -EBADF; */ /* posix? */ ++ if (unlikely(!(file->f_mode & FMODE_WRITE))) ++ goto out_si; ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out_si; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ ++ err = -EINVAL; ++ h_file = au_hf_top(file); ++ err = vfsub_fsync(h_file, &h_file->f_path, datasync); ++ au_cpup_attr_timesizes(inode); ++ ++out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++out_si: ++ si_read_unlock(sb); ++out: ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++ ++/* no one supports this operation, currently */ ++#if 0 ++static int aufs_aio_fsync_nondir(struct kiocb *kio, int datasync) ++{ ++ int err; ++ struct au_pin pin; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct file *file, *h_file; ++ ++ file = kio->ki_filp; ++ dentry = file->f_path.dentry; ++ inode = dentry->d_inode; ++ au_mtx_and_read_lock(inode); ++ ++ err = 0; /* -EBADF; */ /* posix? */ ++ if (unlikely(!(file->f_mode & FMODE_WRITE))) ++ goto out; ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_ready_to_write(file, -1, &pin); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (unlikely(err)) ++ goto out_unlock; ++ au_unpin(&pin); ++ ++ err = -ENOSYS; ++ h_file = au_hf_top(file); ++ if (h_file->f_op->aio_fsync) { ++ struct mutex *h_mtx; ++ ++ h_mtx = &file_inode(h_file)->i_mutex; ++ if (!is_sync_kiocb(kio)) { ++ get_file(h_file); ++ fput(file); ++ } ++ kio->ki_filp = h_file; ++ err = h_file->f_op->aio_fsync(kio, datasync); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ if (!err) ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); ++ /*ignore*/ ++ au_cpup_attr_timesizes(inode); ++ mutex_unlock(h_mtx); ++ } ++ ++out_unlock: ++ di_read_unlock(dentry, AuLock_IR); ++ fi_write_unlock(file); ++out: ++ si_read_unlock(inode->sb); ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} ++#endif ++ ++static int aufs_fasync(int fd, struct file *file, int flag) ++{ ++ int err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ h_file = au_hf_top(file); ++ if (h_file->f_op->fasync) ++ err = h_file->f_op->fasync(fd, h_file, flag); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* no one supports this operation, currently */ ++#if 0 ++static ssize_t aufs_sendpage(struct file *file, struct page *page, int offset, ++ size_t len, loff_t *pos, int more) ++{ ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++const struct file_operations aufs_file_fop = { ++ .owner = THIS_MODULE, ++ ++ .llseek = default_llseek, ++ ++ .read = aufs_read, ++ .write = aufs_write, ++ .read_iter = aufs_read_iter, ++ .write_iter = aufs_write_iter, ++ ++#ifdef CONFIG_AUFS_POLL ++ .poll = aufs_poll, ++#endif ++ .unlocked_ioctl = aufs_ioctl_nondir, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = aufs_compat_ioctl_nondir, ++#endif ++ .mmap = aufs_mmap, ++ .open = aufs_open_nondir, ++ .flush = aufs_flush_nondir, ++ .release = aufs_release_nondir, ++ .fsync = aufs_fsync_nondir, ++ /* .aio_fsync = aufs_aio_fsync_nondir, */ ++ .fasync = aufs_fasync, ++ /* .sendpage = aufs_sendpage, */ ++ .splice_write = aufs_splice_write, ++ .splice_read = aufs_splice_read, ++#if 0 ++ .aio_splice_write = aufs_aio_splice_write, ++ .aio_splice_read = aufs_aio_splice_read, ++#endif ++ .fallocate = aufs_fallocate ++}; +diff --git a/fs/aufs/fhsm.c b/fs/aufs/fhsm.c +new file mode 100644 +index 0000000..47106cb +--- /dev/null ++++ b/fs/aufs/fhsm.c +@@ -0,0 +1,412 @@ ++/* ++ * Copyright (C) 2011-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * File-based Hierarchy Storage Management ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++static aufs_bindex_t au_fhsm_bottom(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ struct au_fhsm *fhsm; ++ ++ SiMustAnyLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ fhsm = &sbinfo->si_fhsm; ++ AuDebugOn(!fhsm); ++ return fhsm->fhsm_bottom; ++} ++ ++void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ struct au_sbinfo *sbinfo; ++ struct au_fhsm *fhsm; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ fhsm = &sbinfo->si_fhsm; ++ AuDebugOn(!fhsm); ++ fhsm->fhsm_bottom = bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_fhsm_test_jiffy(struct au_sbinfo *sbinfo, struct au_branch *br) ++{ ++ struct au_br_fhsm *bf; ++ ++ bf = br->br_fhsm; ++ MtxMustLock(&bf->bf_lock); ++ ++ return !bf->bf_readable ++ || time_after(jiffies, ++ bf->bf_jiffy + sbinfo->si_fhsm.fhsm_expire); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_fhsm_notify(struct super_block *sb, int val) ++{ ++ struct au_sbinfo *sbinfo; ++ struct au_fhsm *fhsm; ++ ++ SiMustAnyLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ fhsm = &sbinfo->si_fhsm; ++ if (au_fhsm_pid(fhsm) ++ && atomic_read(&fhsm->fhsm_readable) != -1) { ++ atomic_set(&fhsm->fhsm_readable, val); ++ if (val) ++ wake_up(&fhsm->fhsm_wqh); ++ } ++} ++ ++static int au_fhsm_stfs(struct super_block *sb, aufs_bindex_t bindex, ++ struct aufs_stfs *rstfs, int do_lock, int do_notify) ++{ ++ int err; ++ struct au_branch *br; ++ struct au_br_fhsm *bf; ++ ++ br = au_sbr(sb, bindex); ++ AuDebugOn(au_br_rdonly(br)); ++ bf = br->br_fhsm; ++ AuDebugOn(!bf); ++ ++ if (do_lock) ++ mutex_lock(&bf->bf_lock); ++ else ++ MtxMustLock(&bf->bf_lock); ++ ++ /* sb->s_root for NFS is unreliable */ ++ err = au_br_stfs(br, &bf->bf_stfs); ++ if (unlikely(err)) { ++ AuErr1("FHSM failed (%d), b%d, ignored.\n", bindex, err); ++ goto out; ++ } ++ ++ bf->bf_jiffy = jiffies; ++ bf->bf_readable = 1; ++ if (do_notify) ++ au_fhsm_notify(sb, /*val*/1); ++ if (rstfs) ++ *rstfs = bf->bf_stfs; ++ ++out: ++ if (do_lock) ++ mutex_unlock(&bf->bf_lock); ++ au_fhsm_notify(sb, /*val*/1); ++ ++ return err; ++} ++ ++void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ struct au_fhsm *fhsm; ++ struct au_branch *br; ++ struct au_br_fhsm *bf; ++ ++ AuDbg("b%d, force %d\n", bindex, force); ++ SiMustAnyLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ fhsm = &sbinfo->si_fhsm; ++ if (!au_ftest_si(sbinfo, FHSM) ++ || fhsm->fhsm_bottom == bindex) ++ return; ++ ++ br = au_sbr(sb, bindex); ++ bf = br->br_fhsm; ++ AuDebugOn(!bf); ++ mutex_lock(&bf->bf_lock); ++ if (force ++ || au_fhsm_pid(fhsm) ++ || au_fhsm_test_jiffy(sbinfo, br)) ++ err = au_fhsm_stfs(sb, bindex, /*rstfs*/NULL, /*do_lock*/0, ++ /*do_notify*/1); ++ mutex_unlock(&bf->bf_lock); ++} ++ ++void au_fhsm_wrote_all(struct super_block *sb, int force) ++{ ++ aufs_bindex_t bindex, bend; ++ struct au_branch *br; ++ ++ /* exclude the bottom */ ++ bend = au_fhsm_bottom(sb); ++ for (bindex = 0; bindex < bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_fhsm(br->br_perm)) ++ au_fhsm_wrote(sb, bindex, force); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static unsigned int au_fhsm_poll(struct file *file, ++ struct poll_table_struct *wait) ++{ ++ unsigned int mask; ++ struct au_sbinfo *sbinfo; ++ struct au_fhsm *fhsm; ++ ++ mask = 0; ++ sbinfo = file->private_data; ++ fhsm = &sbinfo->si_fhsm; ++ poll_wait(file, &fhsm->fhsm_wqh, wait); ++ if (atomic_read(&fhsm->fhsm_readable)) ++ mask = POLLIN /* | POLLRDNORM */; ++ ++ AuTraceErr((int)mask); ++ return mask; ++} ++ ++static int au_fhsm_do_read_one(struct aufs_stbr __user *stbr, ++ struct aufs_stfs *stfs, __s16 brid) ++{ ++ int err; ++ ++ err = copy_to_user(&stbr->stfs, stfs, sizeof(*stfs)); ++ if (!err) ++ err = __put_user(brid, &stbr->brid); ++ if (unlikely(err)) ++ err = -EFAULT; ++ ++ return err; ++} ++ ++static ssize_t au_fhsm_do_read(struct super_block *sb, ++ struct aufs_stbr __user *stbr, size_t count) ++{ ++ ssize_t err; ++ int nstbr; ++ aufs_bindex_t bindex, bend; ++ struct au_branch *br; ++ struct au_br_fhsm *bf; ++ ++ /* except the bottom branch */ ++ err = 0; ++ nstbr = 0; ++ bend = au_fhsm_bottom(sb); ++ for (bindex = 0; !err && bindex < bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (!au_br_fhsm(br->br_perm)) ++ continue; ++ ++ bf = br->br_fhsm; ++ mutex_lock(&bf->bf_lock); ++ if (bf->bf_readable) { ++ err = -EFAULT; ++ if (count >= sizeof(*stbr)) ++ err = au_fhsm_do_read_one(stbr++, &bf->bf_stfs, ++ br->br_id); ++ if (!err) { ++ bf->bf_readable = 0; ++ count -= sizeof(*stbr); ++ nstbr++; ++ } ++ } ++ mutex_unlock(&bf->bf_lock); ++ } ++ if (!err) ++ err = sizeof(*stbr) * nstbr; ++ ++ return err; ++} ++ ++static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count, ++ loff_t *pos) ++{ ++ ssize_t err; ++ int readable; ++ aufs_bindex_t nfhsm, bindex, bend; ++ struct au_sbinfo *sbinfo; ++ struct au_fhsm *fhsm; ++ struct au_branch *br; ++ struct super_block *sb; ++ ++ err = 0; ++ sbinfo = file->private_data; ++ fhsm = &sbinfo->si_fhsm; ++need_data: ++ spin_lock_irq(&fhsm->fhsm_wqh.lock); ++ if (!atomic_read(&fhsm->fhsm_readable)) { ++ if (vfsub_file_flags(file) & O_NONBLOCK) ++ err = -EAGAIN; ++ else ++ err = wait_event_interruptible_locked_irq ++ (fhsm->fhsm_wqh, ++ atomic_read(&fhsm->fhsm_readable)); ++ } ++ spin_unlock_irq(&fhsm->fhsm_wqh.lock); ++ if (unlikely(err)) ++ goto out; ++ ++ /* sb may already be dead */ ++ au_rw_read_lock(&sbinfo->si_rwsem); ++ readable = atomic_read(&fhsm->fhsm_readable); ++ if (readable > 0) { ++ sb = sbinfo->si_sb; ++ AuDebugOn(!sb); ++ /* exclude the bottom branch */ ++ nfhsm = 0; ++ bend = au_fhsm_bottom(sb); ++ for (bindex = 0; bindex < bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_fhsm(br->br_perm)) ++ nfhsm++; ++ } ++ err = -EMSGSIZE; ++ if (nfhsm * sizeof(struct aufs_stbr) <= count) { ++ atomic_set(&fhsm->fhsm_readable, 0); ++ err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf, ++ count); ++ } ++ } ++ au_rw_read_unlock(&sbinfo->si_rwsem); ++ if (!readable) ++ goto need_data; ++ ++out: ++ return err; ++} ++ ++static int au_fhsm_release(struct inode *inode, struct file *file) ++{ ++ struct au_sbinfo *sbinfo; ++ struct au_fhsm *fhsm; ++ ++ /* sb may already be dead */ ++ sbinfo = file->private_data; ++ fhsm = &sbinfo->si_fhsm; ++ spin_lock(&fhsm->fhsm_spin); ++ fhsm->fhsm_pid = 0; ++ spin_unlock(&fhsm->fhsm_spin); ++ kobject_put(&sbinfo->si_kobj); ++ ++ return 0; ++} ++ ++static const struct file_operations au_fhsm_fops = { ++ .owner = THIS_MODULE, ++ .llseek = noop_llseek, ++ .read = au_fhsm_read, ++ .poll = au_fhsm_poll, ++ .release = au_fhsm_release ++}; ++ ++int au_fhsm_fd(struct super_block *sb, int oflags) ++{ ++ int err, fd; ++ struct au_sbinfo *sbinfo; ++ struct au_fhsm *fhsm; ++ ++ err = -EPERM; ++ if (unlikely(!capable(CAP_SYS_ADMIN))) ++ goto out; ++ ++ err = -EINVAL; ++ if (unlikely(oflags & ~(O_CLOEXEC | O_NONBLOCK))) ++ goto out; ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ fhsm = &sbinfo->si_fhsm; ++ spin_lock(&fhsm->fhsm_spin); ++ if (!fhsm->fhsm_pid) ++ fhsm->fhsm_pid = current->pid; ++ else ++ err = -EBUSY; ++ spin_unlock(&fhsm->fhsm_spin); ++ if (unlikely(err)) ++ goto out; ++ ++ oflags |= O_RDONLY; ++ /* oflags |= FMODE_NONOTIFY; */ ++ fd = anon_inode_getfd("[aufs_fhsm]", &au_fhsm_fops, sbinfo, oflags); ++ err = fd; ++ if (unlikely(fd < 0)) ++ goto out_pid; ++ ++ /* succeed reglardless 'fhsm' status */ ++ kobject_get(&sbinfo->si_kobj); ++ si_noflush_read_lock(sb); ++ if (au_ftest_si(sbinfo, FHSM)) ++ au_fhsm_wrote_all(sb, /*force*/0); ++ si_read_unlock(sb); ++ goto out; /* success */ ++ ++out_pid: ++ spin_lock(&fhsm->fhsm_spin); ++ fhsm->fhsm_pid = 0; ++ spin_unlock(&fhsm->fhsm_spin); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_fhsm_br_alloc(struct au_branch *br) ++{ ++ int err; ++ ++ err = 0; ++ br->br_fhsm = kmalloc(sizeof(*br->br_fhsm), GFP_NOFS); ++ if (br->br_fhsm) ++ au_br_fhsm_init(br->br_fhsm); ++ else ++ err = -ENOMEM; ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_fhsm_fin(struct super_block *sb) ++{ ++ au_fhsm_notify(sb, /*val*/-1); ++} ++ ++void au_fhsm_init(struct au_sbinfo *sbinfo) ++{ ++ struct au_fhsm *fhsm; ++ ++ fhsm = &sbinfo->si_fhsm; ++ spin_lock_init(&fhsm->fhsm_spin); ++ init_waitqueue_head(&fhsm->fhsm_wqh); ++ atomic_set(&fhsm->fhsm_readable, 0); ++ fhsm->fhsm_expire ++ = msecs_to_jiffies(AUFS_FHSM_CACHE_DEF_SEC * MSEC_PER_SEC); ++ fhsm->fhsm_bottom = -1; ++} ++ ++void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec) ++{ ++ sbinfo->si_fhsm.fhsm_expire ++ = msecs_to_jiffies(sec * MSEC_PER_SEC); ++} ++ ++void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo) ++{ ++ unsigned int u; ++ ++ if (!au_ftest_si(sbinfo, FHSM)) ++ return; ++ ++ u = jiffies_to_msecs(sbinfo->si_fhsm.fhsm_expire) / MSEC_PER_SEC; ++ if (u != AUFS_FHSM_CACHE_DEF_SEC) ++ seq_printf(seq, ",fhsm_sec=%u", u); ++} +diff --git a/fs/aufs/file.c b/fs/aufs/file.c +new file mode 100644 +index 0000000..cf680cb +--- /dev/null ++++ b/fs/aufs/file.c +@@ -0,0 +1,816 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * handling file/dir, and address_space operation ++ */ ++ ++#ifdef CONFIG_AUFS_DEBUG ++#include ++#endif ++#include ++#include "aufs.h" ++ ++/* drop flags for writing */ ++unsigned int au_file_roflags(unsigned int flags) ++{ ++ flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC); ++ flags |= O_RDONLY | O_NOATIME; ++ return flags; ++} ++ ++/* common functions to regular file and dir */ ++struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, ++ struct file *file, int force_wr) ++{ ++ struct file *h_file; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ struct super_block *sb; ++ struct au_branch *br; ++ struct path h_path; ++ int err, exec_flag; ++ ++ /* a race condition can happen between open and unlink/rmdir */ ++ h_file = ERR_PTR(-ENOENT); ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (au_test_nfsd() && !h_dentry) ++ goto out; ++ h_inode = h_dentry->d_inode; ++ if (au_test_nfsd() && !h_inode) ++ goto out; ++ spin_lock(&h_dentry->d_lock); ++ err = (!d_unhashed(dentry) && d_unlinked(h_dentry)) ++ || !h_inode ++ /* || !dentry->d_inode->i_nlink */ ++ ; ++ spin_unlock(&h_dentry->d_lock); ++ if (unlikely(err)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, bindex); ++ h_file = ERR_PTR(-EACCES); ++ exec_flag = flags & __FMODE_EXEC; ++ if (exec_flag && (au_br_mnt(br)->mnt_flags & MNT_NOEXEC)) ++ goto out; ++ ++ /* drop flags for writing */ ++ if (au_test_ro(sb, bindex, dentry->d_inode)) { ++ if (force_wr && !(flags & O_WRONLY)) ++ force_wr = 0; ++ flags = au_file_roflags(flags); ++ if (force_wr) { ++ h_file = ERR_PTR(-EROFS); ++ flags = au_file_roflags(flags); ++ if (unlikely(vfsub_native_ro(h_inode) ++ || IS_APPEND(h_inode))) ++ goto out; ++ flags &= ~O_ACCMODE; ++ flags |= O_WRONLY; ++ } ++ } ++ flags &= ~O_CREAT; ++ atomic_inc(&br->br_count); ++ h_path.dentry = h_dentry; ++ h_path.mnt = au_br_mnt(br); ++ h_file = vfsub_dentry_open(&h_path, flags); ++ if (IS_ERR(h_file)) ++ goto out_br; ++ ++ if (exec_flag) { ++ err = deny_write_access(h_file); ++ if (unlikely(err)) { ++ fput(h_file); ++ h_file = ERR_PTR(err); ++ goto out_br; ++ } ++ } ++ fsnotify_open(h_file); ++ goto out; /* success */ ++ ++out_br: ++ atomic_dec(&br->br_count); ++out: ++ return h_file; ++} ++ ++static int au_cmoo(struct dentry *dentry) ++{ ++ int err, cmoo; ++ unsigned int udba; ++ struct path h_path; ++ struct au_pin pin; ++ struct au_cp_generic cpg = { ++ .dentry = dentry, ++ .bdst = -1, ++ .bsrc = -1, ++ .len = -1, ++ .pin = &pin, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN ++ }; ++ struct inode *inode, *delegated; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ struct au_fhsm *fhsm; ++ pid_t pid; ++ struct au_branch *br; ++ struct dentry *parent; ++ struct au_hinode *hdir; ++ ++ DiMustWriteLock(dentry); ++ inode = dentry->d_inode; ++ IiMustWriteLock(inode); ++ ++ err = 0; ++ if (IS_ROOT(dentry)) ++ goto out; ++ cpg.bsrc = au_dbstart(dentry); ++ if (!cpg.bsrc) ++ goto out; ++ ++ sb = dentry->d_sb; ++ sbinfo = au_sbi(sb); ++ fhsm = &sbinfo->si_fhsm; ++ pid = au_fhsm_pid(fhsm); ++ if (pid ++ && (current->pid == pid ++ || current->real_parent->pid == pid)) ++ goto out; ++ ++ br = au_sbr(sb, cpg.bsrc); ++ cmoo = au_br_cmoo(br->br_perm); ++ if (!cmoo) ++ goto out; ++ if (!S_ISREG(inode->i_mode)) ++ cmoo &= AuBrAttr_COO_ALL; ++ if (!cmoo) ++ goto out; ++ ++ parent = dget_parent(dentry); ++ di_write_lock_parent(parent); ++ err = au_wbr_do_copyup_bu(dentry, cpg.bsrc - 1); ++ cpg.bdst = err; ++ if (unlikely(err < 0)) { ++ err = 0; /* there is no upper writable branch */ ++ goto out_dgrade; ++ } ++ AuDbg("bsrc %d, bdst %d\n", cpg.bsrc, cpg.bdst); ++ ++ /* do not respect the coo attrib for the target branch */ ++ err = au_cpup_dirs(dentry, cpg.bdst); ++ if (unlikely(err)) ++ goto out_dgrade; ++ ++ di_downgrade_lock(parent, AuLock_IR); ++ udba = au_opt_udba(sb); ++ err = au_pin(&pin, dentry, cpg.bdst, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ err = au_sio_cpup_simple(&cpg); ++ au_unpin(&pin); ++ if (unlikely(err)) ++ goto out_parent; ++ if (!(cmoo & AuBrWAttr_MOO)) ++ goto out_parent; /* success */ ++ ++ err = au_pin(&pin, dentry, cpg.bsrc, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ h_path.mnt = au_br_mnt(br); ++ h_path.dentry = au_h_dptr(dentry, cpg.bsrc); ++ hdir = au_hi(parent->d_inode, cpg.bsrc); ++ delegated = NULL; ++ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, /*force*/1); ++ au_unpin(&pin); ++ /* todo: keep h_dentry or not? */ ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal unlink\n"); ++ iput(delegated); ++ } ++ if (unlikely(err)) { ++ pr_err("unlink %pd after coo failed (%d), ignored\n", ++ dentry, err); ++ err = 0; ++ } ++ goto out_parent; /* success */ ++ ++out_dgrade: ++ di_downgrade_lock(parent, AuLock_IR); ++out_parent: ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_do_open(struct file *file, int (*open)(struct file *file, int flags), ++ struct au_fidir *fidir) ++{ ++ int err; ++ struct dentry *dentry; ++ struct au_finfo *finfo; ++ ++ err = au_finfo_init(file, fidir); ++ if (unlikely(err)) ++ goto out; ++ ++ dentry = file->f_path.dentry; ++ di_write_lock_child(dentry); ++ err = au_cmoo(dentry); ++ di_downgrade_lock(dentry, AuLock_IR); ++ if (!err) ++ err = open(file, vfsub_file_flags(file)); ++ di_read_unlock(dentry, AuLock_IR); ++ ++ finfo = au_fi(file); ++ if (!err) { ++ finfo->fi_file = file; ++ au_sphl_add(&finfo->fi_hlist, ++ &au_sbi(file->f_path.dentry->d_sb)->si_files); ++ } ++ fi_write_unlock(file); ++ if (unlikely(err)) { ++ finfo->fi_hdir = NULL; ++ au_finfo_fin(file); ++ } ++ ++out: ++ return err; ++} ++ ++int au_reopen_nondir(struct file *file) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct dentry *dentry; ++ struct file *h_file, *h_file_tmp; ++ ++ dentry = file->f_path.dentry; ++ bstart = au_dbstart(dentry); ++ h_file_tmp = NULL; ++ if (au_fbstart(file) == bstart) { ++ h_file = au_hf_top(file); ++ if (file->f_mode == h_file->f_mode) ++ return 0; /* success */ ++ h_file_tmp = h_file; ++ get_file(h_file_tmp); ++ au_set_h_fptr(file, bstart, NULL); ++ } ++ AuDebugOn(au_fi(file)->fi_hdir); ++ /* ++ * it can happen ++ * file exists on both of rw and ro ++ * open --> dbstart and fbstart are both 0 ++ * prepend a branch as rw, "rw" become ro ++ * remove rw/file ++ * delete the top branch, "rw" becomes rw again ++ * --> dbstart is 1, fbstart is still 0 ++ * write --> fbstart is 0 but dbstart is 1 ++ */ ++ /* AuDebugOn(au_fbstart(file) < bstart); */ ++ ++ h_file = au_h_open(dentry, bstart, vfsub_file_flags(file) & ~O_TRUNC, ++ file, /*force_wr*/0); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) { ++ if (h_file_tmp) { ++ atomic_inc(&au_sbr(dentry->d_sb, bstart)->br_count); ++ au_set_h_fptr(file, bstart, h_file_tmp); ++ h_file_tmp = NULL; ++ } ++ goto out; /* todo: close all? */ ++ } ++ ++ err = 0; ++ au_set_fbstart(file, bstart); ++ au_set_h_fptr(file, bstart, h_file); ++ au_update_figen(file); ++ /* todo: necessary? */ ++ /* file->f_ra = h_file->f_ra; */ ++ ++out: ++ if (h_file_tmp) ++ fput(h_file_tmp); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_reopen_wh(struct file *file, aufs_bindex_t btgt, ++ struct dentry *hi_wh) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ struct au_dinfo *dinfo; ++ struct dentry *h_dentry; ++ struct au_hdentry *hdp; ++ ++ dinfo = au_di(file->f_path.dentry); ++ AuRwMustWriteLock(&dinfo->di_rwsem); ++ ++ bstart = dinfo->di_bstart; ++ dinfo->di_bstart = btgt; ++ hdp = dinfo->di_hdentry; ++ h_dentry = hdp[0 + btgt].hd_dentry; ++ hdp[0 + btgt].hd_dentry = hi_wh; ++ err = au_reopen_nondir(file); ++ hdp[0 + btgt].hd_dentry = h_dentry; ++ dinfo->di_bstart = bstart; ++ ++ return err; ++} ++ ++static int au_ready_to_write_wh(struct file *file, loff_t len, ++ aufs_bindex_t bcpup, struct au_pin *pin) ++{ ++ int err; ++ struct inode *inode, *h_inode; ++ struct dentry *h_dentry, *hi_wh; ++ struct au_cp_generic cpg = { ++ .dentry = file->f_path.dentry, ++ .bdst = bcpup, ++ .bsrc = -1, ++ .len = len, ++ .pin = pin ++ }; ++ ++ au_update_dbstart(cpg.dentry); ++ inode = cpg.dentry->d_inode; ++ h_inode = NULL; ++ if (au_dbstart(cpg.dentry) <= bcpup ++ && au_dbend(cpg.dentry) >= bcpup) { ++ h_dentry = au_h_dptr(cpg.dentry, bcpup); ++ if (h_dentry) ++ h_inode = h_dentry->d_inode; ++ } ++ hi_wh = au_hi_wh(inode, bcpup); ++ if (!hi_wh && !h_inode) ++ err = au_sio_cpup_wh(&cpg, file); ++ else ++ /* already copied-up after unlink */ ++ err = au_reopen_wh(file, bcpup, hi_wh); ++ ++ if (!err ++ && (inode->i_nlink > 1 ++ || (inode->i_state & I_LINKABLE)) ++ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK)) ++ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup)); ++ ++ return err; ++} ++ ++/* ++ * prepare the @file for writing. ++ */ ++int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin) ++{ ++ int err; ++ aufs_bindex_t dbstart; ++ struct dentry *parent; ++ struct inode *inode; ++ struct super_block *sb; ++ struct file *h_file; ++ struct au_cp_generic cpg = { ++ .dentry = file->f_path.dentry, ++ .bdst = -1, ++ .bsrc = -1, ++ .len = len, ++ .pin = pin, ++ .flags = AuCpup_DTIME ++ }; ++ ++ sb = cpg.dentry->d_sb; ++ inode = cpg.dentry->d_inode; ++ cpg.bsrc = au_fbstart(file); ++ err = au_test_ro(sb, cpg.bsrc, inode); ++ if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) { ++ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE, ++ /*flags*/0); ++ goto out; ++ } ++ ++ /* need to cpup or reopen */ ++ parent = dget_parent(cpg.dentry); ++ di_write_lock_parent(parent); ++ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); ++ cpg.bdst = err; ++ if (unlikely(err < 0)) ++ goto out_dgrade; ++ err = 0; ++ ++ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) { ++ err = au_cpup_dirs(cpg.dentry, cpg.bdst); ++ if (unlikely(err)) ++ goto out_dgrade; ++ } ++ ++ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_dgrade; ++ ++ dbstart = au_dbstart(cpg.dentry); ++ if (dbstart <= cpg.bdst) ++ cpg.bsrc = cpg.bdst; ++ ++ if (dbstart <= cpg.bdst /* just reopen */ ++ || !d_unhashed(cpg.dentry) /* copyup and reopen */ ++ ) { ++ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc, /*force_wr*/0); ++ if (IS_ERR(h_file)) ++ err = PTR_ERR(h_file); ++ else { ++ di_downgrade_lock(parent, AuLock_IR); ++ if (dbstart > cpg.bdst) ++ err = au_sio_cpup_simple(&cpg); ++ if (!err) ++ err = au_reopen_nondir(file); ++ au_h_open_post(cpg.dentry, cpg.bsrc, h_file); ++ } ++ } else { /* copyup as wh and reopen */ ++ /* ++ * since writable hfsplus branch is not supported, ++ * h_open_pre/post() are unnecessary. ++ */ ++ err = au_ready_to_write_wh(file, len, cpg.bdst, pin); ++ di_downgrade_lock(parent, AuLock_IR); ++ } ++ ++ if (!err) { ++ au_pin_set_parent_lflag(pin, /*lflag*/0); ++ goto out_dput; /* success */ ++ } ++ au_unpin(pin); ++ goto out_unlock; ++ ++out_dgrade: ++ di_downgrade_lock(parent, AuLock_IR); ++out_unlock: ++ di_read_unlock(parent, AuLock_IR); ++out_dput: ++ dput(parent); ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_do_flush(struct file *file, fl_owner_t id, ++ int (*flush)(struct file *file, fl_owner_t id)) ++{ ++ int err; ++ struct super_block *sb; ++ struct inode *inode; ++ ++ inode = file_inode(file); ++ sb = inode->i_sb; ++ si_noflush_read_lock(sb); ++ fi_read_lock(file); ++ ii_read_lock_child(inode); ++ ++ err = flush(file, id); ++ au_cpup_attr_timesizes(inode); ++ ++ ii_read_unlock(inode); ++ fi_read_unlock(file); ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_file_refresh_by_inode(struct file *file, int *need_reopen) ++{ ++ int err; ++ struct au_pin pin; ++ struct au_finfo *finfo; ++ struct dentry *parent, *hi_wh; ++ struct inode *inode; ++ struct super_block *sb; ++ struct au_cp_generic cpg = { ++ .dentry = file->f_path.dentry, ++ .bdst = -1, ++ .bsrc = -1, ++ .len = -1, ++ .pin = &pin, ++ .flags = AuCpup_DTIME ++ }; ++ ++ FiMustWriteLock(file); ++ ++ err = 0; ++ finfo = au_fi(file); ++ sb = cpg.dentry->d_sb; ++ inode = cpg.dentry->d_inode; ++ cpg.bdst = au_ibstart(inode); ++ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry)) ++ goto out; ++ ++ parent = dget_parent(cpg.dentry); ++ if (au_test_ro(sb, cpg.bdst, inode)) { ++ di_read_lock_parent(parent, !AuLock_IR); ++ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); ++ cpg.bdst = err; ++ di_read_unlock(parent, !AuLock_IR); ++ if (unlikely(err < 0)) ++ goto out_parent; ++ err = 0; ++ } ++ ++ di_read_lock_parent(parent, AuLock_IR); ++ hi_wh = au_hi_wh(inode, cpg.bdst); ++ if (!S_ISDIR(inode->i_mode) ++ && au_opt_test(au_mntflags(sb), PLINK) ++ && au_plink_test(inode) ++ && !d_unhashed(cpg.dentry) ++ && cpg.bdst < au_dbstart(cpg.dentry)) { ++ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ /* always superio. */ ++ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (!err) { ++ err = au_sio_cpup_simple(&cpg); ++ au_unpin(&pin); ++ } ++ } else if (hi_wh) { ++ /* already copied-up after unlink */ ++ err = au_reopen_wh(file, cpg.bdst, hi_wh); ++ *need_reopen = 0; ++ } ++ ++out_unlock: ++ di_read_unlock(parent, AuLock_IR); ++out_parent: ++ dput(parent); ++out: ++ return err; ++} ++ ++static void au_do_refresh_dir(struct file *file) ++{ ++ aufs_bindex_t bindex, bend, new_bindex, brid; ++ struct au_hfile *p, tmp, *q; ++ struct au_finfo *finfo; ++ struct super_block *sb; ++ struct au_fidir *fidir; ++ ++ FiMustWriteLock(file); ++ ++ sb = file->f_path.dentry->d_sb; ++ finfo = au_fi(file); ++ fidir = finfo->fi_hdir; ++ AuDebugOn(!fidir); ++ p = fidir->fd_hfile + finfo->fi_btop; ++ brid = p->hf_br->br_id; ++ bend = fidir->fd_bbot; ++ for (bindex = finfo->fi_btop; bindex <= bend; bindex++, p++) { ++ if (!p->hf_file) ++ continue; ++ ++ new_bindex = au_br_index(sb, p->hf_br->br_id); ++ if (new_bindex == bindex) ++ continue; ++ if (new_bindex < 0) { ++ au_set_h_fptr(file, bindex, NULL); ++ continue; ++ } ++ ++ /* swap two lower inode, and loop again */ ++ q = fidir->fd_hfile + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hf_file) { ++ bindex--; ++ p--; ++ } ++ } ++ ++ p = fidir->fd_hfile; ++ if (!au_test_mmapped(file) && !d_unlinked(file->f_path.dentry)) { ++ bend = au_sbend(sb); ++ for (finfo->fi_btop = 0; finfo->fi_btop <= bend; ++ finfo->fi_btop++, p++) ++ if (p->hf_file) { ++ if (file_inode(p->hf_file)) ++ break; ++ au_hfput(p, file); ++ } ++ } else { ++ bend = au_br_index(sb, brid); ++ for (finfo->fi_btop = 0; finfo->fi_btop < bend; ++ finfo->fi_btop++, p++) ++ if (p->hf_file) ++ au_hfput(p, file); ++ bend = au_sbend(sb); ++ } ++ ++ p = fidir->fd_hfile + bend; ++ for (fidir->fd_bbot = bend; fidir->fd_bbot >= finfo->fi_btop; ++ fidir->fd_bbot--, p--) ++ if (p->hf_file) { ++ if (file_inode(p->hf_file)) ++ break; ++ au_hfput(p, file); ++ } ++ AuDebugOn(fidir->fd_bbot < finfo->fi_btop); ++} ++ ++/* ++ * after branch manipulating, refresh the file. ++ */ ++static int refresh_file(struct file *file, int (*reopen)(struct file *file)) ++{ ++ int err, need_reopen; ++ aufs_bindex_t bend, bindex; ++ struct dentry *dentry; ++ struct au_finfo *finfo; ++ struct au_hfile *hfile; ++ ++ dentry = file->f_path.dentry; ++ finfo = au_fi(file); ++ if (!finfo->fi_hdir) { ++ hfile = &finfo->fi_htop; ++ AuDebugOn(!hfile->hf_file); ++ bindex = au_br_index(dentry->d_sb, hfile->hf_br->br_id); ++ AuDebugOn(bindex < 0); ++ if (bindex != finfo->fi_btop) ++ au_set_fbstart(file, bindex); ++ } else { ++ err = au_fidir_realloc(finfo, au_sbend(dentry->d_sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ au_do_refresh_dir(file); ++ } ++ ++ err = 0; ++ need_reopen = 1; ++ if (!au_test_mmapped(file)) ++ err = au_file_refresh_by_inode(file, &need_reopen); ++ if (!err && need_reopen && !d_unlinked(dentry)) ++ err = reopen(file); ++ if (!err) { ++ au_update_figen(file); ++ goto out; /* success */ ++ } ++ ++ /* error, close all lower files */ ++ if (finfo->fi_hdir) { ++ bend = au_fbend_dir(file); ++ for (bindex = au_fbstart(file); bindex <= bend; bindex++) ++ au_set_h_fptr(file, bindex, NULL); ++ } ++ ++out: ++ return err; ++} ++ ++/* common function to regular file and dir */ ++int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), ++ int wlock) ++{ ++ int err; ++ unsigned int sigen, figen; ++ aufs_bindex_t bstart; ++ unsigned char pseudo_link; ++ struct dentry *dentry; ++ struct inode *inode; ++ ++ err = 0; ++ dentry = file->f_path.dentry; ++ inode = dentry->d_inode; ++ sigen = au_sigen(dentry->d_sb); ++ fi_write_lock(file); ++ figen = au_figen(file); ++ di_write_lock_child(dentry); ++ bstart = au_dbstart(dentry); ++ pseudo_link = (bstart != au_ibstart(inode)); ++ if (sigen == figen && !pseudo_link && au_fbstart(file) == bstart) { ++ if (!wlock) { ++ di_downgrade_lock(dentry, AuLock_IR); ++ fi_downgrade_lock(file); ++ } ++ goto out; /* success */ ++ } ++ ++ AuDbg("sigen %d, figen %d\n", sigen, figen); ++ if (au_digen_test(dentry, sigen)) { ++ err = au_reval_dpath(dentry, sigen); ++ AuDebugOn(!err && au_digen_test(dentry, sigen)); ++ } ++ ++ if (!err) ++ err = refresh_file(file, reopen); ++ if (!err) { ++ if (!wlock) { ++ di_downgrade_lock(dentry, AuLock_IR); ++ fi_downgrade_lock(file); ++ } ++ } else { ++ di_write_unlock(dentry); ++ fi_write_unlock(file); ++ } ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* cf. aufs_nopage() */ ++/* for madvise(2) */ ++static int aufs_readpage(struct file *file __maybe_unused, struct page *page) ++{ ++ unlock_page(page); ++ return 0; ++} ++ ++/* it will never be called, but necessary to support O_DIRECT */ ++static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb, ++ struct iov_iter *iter, loff_t offset) ++{ BUG(); return 0; } ++ ++/* ++ * it will never be called, but madvise and fadvise behaves differently ++ * when get_xip_mem is defined ++ */ ++static int aufs_get_xip_mem(struct address_space *mapping, pgoff_t pgoff, ++ int create, void **kmem, unsigned long *pfn) ++{ BUG(); return 0; } ++ ++/* they will never be called. */ ++#ifdef CONFIG_AUFS_DEBUG ++static int aufs_write_begin(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned flags, ++ struct page **pagep, void **fsdata) ++{ AuUnsupport(); return 0; } ++static int aufs_write_end(struct file *file, struct address_space *mapping, ++ loff_t pos, unsigned len, unsigned copied, ++ struct page *page, void *fsdata) ++{ AuUnsupport(); return 0; } ++static int aufs_writepage(struct page *page, struct writeback_control *wbc) ++{ AuUnsupport(); return 0; } ++ ++static int aufs_set_page_dirty(struct page *page) ++{ AuUnsupport(); return 0; } ++static void aufs_invalidatepage(struct page *page, unsigned int offset, ++ unsigned int length) ++{ AuUnsupport(); } ++static int aufs_releasepage(struct page *page, gfp_t gfp) ++{ AuUnsupport(); return 0; } ++static int aufs_migratepage(struct address_space *mapping, struct page *newpage, ++ struct page *page, enum migrate_mode mode) ++{ AuUnsupport(); return 0; } ++static int aufs_launder_page(struct page *page) ++{ AuUnsupport(); return 0; } ++static int aufs_is_partially_uptodate(struct page *page, ++ unsigned long from, ++ unsigned long count) ++{ AuUnsupport(); return 0; } ++static void aufs_is_dirty_writeback(struct page *page, bool *dirty, ++ bool *writeback) ++{ AuUnsupport(); } ++static int aufs_error_remove_page(struct address_space *mapping, ++ struct page *page) ++{ AuUnsupport(); return 0; } ++static int aufs_swap_activate(struct swap_info_struct *sis, struct file *file, ++ sector_t *span) ++{ AuUnsupport(); return 0; } ++static void aufs_swap_deactivate(struct file *file) ++{ AuUnsupport(); } ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++const struct address_space_operations aufs_aop = { ++ .readpage = aufs_readpage, ++ .direct_IO = aufs_direct_IO, ++ .get_xip_mem = aufs_get_xip_mem, ++#ifdef CONFIG_AUFS_DEBUG ++ .writepage = aufs_writepage, ++ /* no writepages, because of writepage */ ++ .set_page_dirty = aufs_set_page_dirty, ++ /* no readpages, because of readpage */ ++ .write_begin = aufs_write_begin, ++ .write_end = aufs_write_end, ++ /* no bmap, no block device */ ++ .invalidatepage = aufs_invalidatepage, ++ .releasepage = aufs_releasepage, ++ .migratepage = aufs_migratepage, ++ .launder_page = aufs_launder_page, ++ .is_partially_uptodate = aufs_is_partially_uptodate, ++ .is_dirty_writeback = aufs_is_dirty_writeback, ++ .error_remove_page = aufs_error_remove_page, ++ .swap_activate = aufs_swap_activate, ++ .swap_deactivate = aufs_swap_deactivate ++#endif /* CONFIG_AUFS_DEBUG */ ++}; +diff --git a/fs/aufs/file.h b/fs/aufs/file.h +new file mode 100644 +index 0000000..643c6f4 +--- /dev/null ++++ b/fs/aufs/file.h +@@ -0,0 +1,271 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * file operations ++ */ ++ ++#ifndef __AUFS_FILE_H__ ++#define __AUFS_FILE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include "rwsem.h" ++ ++struct au_branch; ++struct au_hfile { ++ struct file *hf_file; ++ struct au_branch *hf_br; ++}; ++ ++struct au_vdir; ++struct au_fidir { ++ aufs_bindex_t fd_bbot; ++ aufs_bindex_t fd_nent; ++ struct au_vdir *fd_vdir_cache; ++ struct au_hfile fd_hfile[]; ++}; ++ ++static inline int au_fidir_sz(int nent) ++{ ++ AuDebugOn(nent < 0); ++ return sizeof(struct au_fidir) + sizeof(struct au_hfile) * nent; ++} ++ ++struct au_finfo { ++ atomic_t fi_generation; ++ ++ struct au_rwsem fi_rwsem; ++ aufs_bindex_t fi_btop; ++ ++ /* do not union them */ ++ struct { /* for non-dir */ ++ struct au_hfile fi_htop; ++ atomic_t fi_mmapped; ++ }; ++ struct au_fidir *fi_hdir; /* for dir only */ ++ ++ struct hlist_node fi_hlist; ++ struct file *fi_file; /* very ugly */ ++} ____cacheline_aligned_in_smp; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* file.c */ ++extern const struct address_space_operations aufs_aop; ++unsigned int au_file_roflags(unsigned int flags); ++struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, ++ struct file *file, int force_wr); ++int au_do_open(struct file *file, int (*open)(struct file *file, int flags), ++ struct au_fidir *fidir); ++int au_reopen_nondir(struct file *file); ++struct au_pin; ++int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin); ++int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), ++ int wlock); ++int au_do_flush(struct file *file, fl_owner_t id, ++ int (*flush)(struct file *file, fl_owner_t id)); ++ ++/* poll.c */ ++#ifdef CONFIG_AUFS_POLL ++unsigned int aufs_poll(struct file *file, poll_table *wait); ++#endif ++ ++#ifdef CONFIG_AUFS_BR_HFSPLUS ++/* hfsplus.c */ ++struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex, ++ int force_wr); ++void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex, ++ struct file *h_file); ++#else ++AuStub(struct file *, au_h_open_pre, return NULL, struct dentry *dentry, ++ aufs_bindex_t bindex, int force_wr) ++AuStubVoid(au_h_open_post, struct dentry *dentry, aufs_bindex_t bindex, ++ struct file *h_file); ++#endif ++ ++/* f_op.c */ ++extern const struct file_operations aufs_file_fop; ++int au_do_open_nondir(struct file *file, int flags); ++int aufs_release_nondir(struct inode *inode __maybe_unused, struct file *file); ++ ++/* finfo.c */ ++void au_hfput(struct au_hfile *hf, struct file *file); ++void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, ++ struct file *h_file); ++ ++void au_update_figen(struct file *file); ++struct au_fidir *au_fidir_alloc(struct super_block *sb); ++int au_fidir_realloc(struct au_finfo *finfo, int nbr); ++ ++void au_fi_init_once(void *_fi); ++void au_finfo_fin(struct file *file); ++int au_finfo_init(struct file *file, struct au_fidir *fidir); ++ ++/* ioctl.c */ ++long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg); ++#ifdef CONFIG_COMPAT ++long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, ++ unsigned long arg); ++long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, ++ unsigned long arg); ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_finfo *au_fi(struct file *file) ++{ ++ return file->private_data; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * fi_read_lock, fi_write_lock, ++ * fi_read_unlock, fi_write_unlock, fi_downgrade_lock ++ */ ++AuSimpleRwsemFuncs(fi, struct file *f, &au_fi(f)->fi_rwsem); ++ ++#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem) ++#define FiMustAnyLock(f) AuRwMustAnyLock(&au_fi(f)->fi_rwsem) ++#define FiMustWriteLock(f) AuRwMustWriteLock(&au_fi(f)->fi_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: hard/soft set? */ ++static inline aufs_bindex_t au_fbstart(struct file *file) ++{ ++ FiMustAnyLock(file); ++ return au_fi(file)->fi_btop; ++} ++ ++static inline aufs_bindex_t au_fbend_dir(struct file *file) ++{ ++ FiMustAnyLock(file); ++ AuDebugOn(!au_fi(file)->fi_hdir); ++ return au_fi(file)->fi_hdir->fd_bbot; ++} ++ ++static inline struct au_vdir *au_fvdir_cache(struct file *file) ++{ ++ FiMustAnyLock(file); ++ AuDebugOn(!au_fi(file)->fi_hdir); ++ return au_fi(file)->fi_hdir->fd_vdir_cache; ++} ++ ++static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex) ++{ ++ FiMustWriteLock(file); ++ au_fi(file)->fi_btop = bindex; ++} ++ ++static inline void au_set_fbend_dir(struct file *file, aufs_bindex_t bindex) ++{ ++ FiMustWriteLock(file); ++ AuDebugOn(!au_fi(file)->fi_hdir); ++ au_fi(file)->fi_hdir->fd_bbot = bindex; ++} ++ ++static inline void au_set_fvdir_cache(struct file *file, ++ struct au_vdir *vdir_cache) ++{ ++ FiMustWriteLock(file); ++ AuDebugOn(!au_fi(file)->fi_hdir); ++ au_fi(file)->fi_hdir->fd_vdir_cache = vdir_cache; ++} ++ ++static inline struct file *au_hf_top(struct file *file) ++{ ++ FiMustAnyLock(file); ++ AuDebugOn(au_fi(file)->fi_hdir); ++ return au_fi(file)->fi_htop.hf_file; ++} ++ ++static inline struct file *au_hf_dir(struct file *file, aufs_bindex_t bindex) ++{ ++ FiMustAnyLock(file); ++ AuDebugOn(!au_fi(file)->fi_hdir); ++ return au_fi(file)->fi_hdir->fd_hfile[0 + bindex].hf_file; ++} ++ ++/* todo: memory barrier? */ ++static inline unsigned int au_figen(struct file *f) ++{ ++ return atomic_read(&au_fi(f)->fi_generation); ++} ++ ++static inline void au_set_mmapped(struct file *f) ++{ ++ if (atomic_inc_return(&au_fi(f)->fi_mmapped)) ++ return; ++ pr_warn("fi_mmapped wrapped around\n"); ++ while (!atomic_inc_return(&au_fi(f)->fi_mmapped)) ++ ; ++} ++ ++static inline void au_unset_mmapped(struct file *f) ++{ ++ atomic_dec(&au_fi(f)->fi_mmapped); ++} ++ ++static inline int au_test_mmapped(struct file *f) ++{ ++ return atomic_read(&au_fi(f)->fi_mmapped); ++} ++ ++/* customize vma->vm_file */ ++ ++static inline void au_do_vm_file_reset(struct vm_area_struct *vma, ++ struct file *file) ++{ ++ struct file *f; ++ ++ f = vma->vm_file; ++ get_file(file); ++ vma->vm_file = file; ++ fput(f); ++} ++ ++#ifdef CONFIG_MMU ++#define AuDbgVmRegion(file, vma) do {} while (0) ++ ++static inline void au_vm_file_reset(struct vm_area_struct *vma, ++ struct file *file) ++{ ++ au_do_vm_file_reset(vma, file); ++} ++#else ++#define AuDbgVmRegion(file, vma) \ ++ AuDebugOn((vma)->vm_region && (vma)->vm_region->vm_file != (file)) ++ ++static inline void au_vm_file_reset(struct vm_area_struct *vma, ++ struct file *file) ++{ ++ struct file *f; ++ ++ au_do_vm_file_reset(vma, file); ++ f = vma->vm_region->vm_file; ++ get_file(file); ++ vma->vm_region->vm_file = file; ++ fput(f); ++} ++#endif /* CONFIG_MMU */ ++ ++/* handle vma->vm_prfile */ ++static inline void au_vm_prfile_set(struct vm_area_struct *vma, ++ struct file *file) ++{ ++ get_file(file); ++ vma->vm_prfile = file; ++#ifndef CONFIG_MMU ++ get_file(file); ++ vma->vm_region->vm_prfile = file; ++#endif ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_FILE_H__ */ +diff --git a/fs/aufs/finfo.c b/fs/aufs/finfo.c +new file mode 100644 +index 0000000..61e39eb +--- /dev/null ++++ b/fs/aufs/finfo.c +@@ -0,0 +1,143 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * file private data ++ */ ++ ++#include "aufs.h" ++ ++void au_hfput(struct au_hfile *hf, struct file *file) ++{ ++ /* todo: direct access f_flags */ ++ if (vfsub_file_flags(file) & __FMODE_EXEC) ++ allow_write_access(hf->hf_file); ++ fput(hf->hf_file); ++ hf->hf_file = NULL; ++ atomic_dec(&hf->hf_br->br_count); ++ hf->hf_br = NULL; ++} ++ ++void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val) ++{ ++ struct au_finfo *finfo = au_fi(file); ++ struct au_hfile *hf; ++ struct au_fidir *fidir; ++ ++ fidir = finfo->fi_hdir; ++ if (!fidir) { ++ AuDebugOn(finfo->fi_btop != bindex); ++ hf = &finfo->fi_htop; ++ } else ++ hf = fidir->fd_hfile + bindex; ++ ++ if (hf && hf->hf_file) ++ au_hfput(hf, file); ++ if (val) { ++ FiMustWriteLock(file); ++ hf->hf_file = val; ++ hf->hf_br = au_sbr(file->f_path.dentry->d_sb, bindex); ++ } ++} ++ ++void au_update_figen(struct file *file) ++{ ++ atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_path.dentry)); ++ /* smp_mb(); */ /* atomic_set */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_fidir *au_fidir_alloc(struct super_block *sb) ++{ ++ struct au_fidir *fidir; ++ int nbr; ++ ++ nbr = au_sbend(sb) + 1; ++ if (nbr < 2) ++ nbr = 2; /* initial allocate for 2 branches */ ++ fidir = kzalloc(au_fidir_sz(nbr), GFP_NOFS); ++ if (fidir) { ++ fidir->fd_bbot = -1; ++ fidir->fd_nent = nbr; ++ fidir->fd_vdir_cache = NULL; ++ } ++ ++ return fidir; ++} ++ ++int au_fidir_realloc(struct au_finfo *finfo, int nbr) ++{ ++ int err; ++ struct au_fidir *fidir, *p; ++ ++ AuRwMustWriteLock(&finfo->fi_rwsem); ++ fidir = finfo->fi_hdir; ++ AuDebugOn(!fidir); ++ ++ err = -ENOMEM; ++ p = au_kzrealloc(fidir, au_fidir_sz(fidir->fd_nent), au_fidir_sz(nbr), ++ GFP_NOFS); ++ if (p) { ++ p->fd_nent = nbr; ++ finfo->fi_hdir = p; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_finfo_fin(struct file *file) ++{ ++ struct au_finfo *finfo; ++ ++ au_nfiles_dec(file->f_path.dentry->d_sb); ++ ++ finfo = au_fi(file); ++ AuDebugOn(finfo->fi_hdir); ++ AuRwDestroy(&finfo->fi_rwsem); ++ au_cache_free_finfo(finfo); ++} ++ ++void au_fi_init_once(void *_finfo) ++{ ++ struct au_finfo *finfo = _finfo; ++ static struct lock_class_key aufs_fi; ++ ++ au_rw_init(&finfo->fi_rwsem); ++ au_rw_class(&finfo->fi_rwsem, &aufs_fi); ++} ++ ++int au_finfo_init(struct file *file, struct au_fidir *fidir) ++{ ++ int err; ++ struct au_finfo *finfo; ++ struct dentry *dentry; ++ ++ err = -ENOMEM; ++ dentry = file->f_path.dentry; ++ finfo = au_cache_alloc_finfo(); ++ if (unlikely(!finfo)) ++ goto out; ++ ++ err = 0; ++ au_nfiles_inc(dentry->d_sb); ++ /* verbose coding for lock class name */ ++ if (!fidir) ++ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcNonDir_FIINFO); ++ else ++ au_rw_class(&finfo->fi_rwsem, au_lc_key + AuLcDir_FIINFO); ++ au_rw_write_lock(&finfo->fi_rwsem); ++ finfo->fi_btop = -1; ++ finfo->fi_hdir = fidir; ++ atomic_set(&finfo->fi_generation, au_digen(dentry)); ++ /* smp_mb(); */ /* atomic_set */ ++ ++ file->private_data = finfo; ++ ++out: ++ return err; ++} +diff --git a/fs/aufs/fstype.h b/fs/aufs/fstype.h +new file mode 100644 +index 0000000..6893432 +--- /dev/null ++++ b/fs/aufs/fstype.h +@@ -0,0 +1,456 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * judging filesystem type ++ */ ++ ++#ifndef __AUFS_FSTYPE_H__ ++#define __AUFS_FSTYPE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++ ++static inline int au_test_aufs(struct super_block *sb) ++{ ++ return sb->s_magic == AUFS_SUPER_MAGIC; ++} ++ ++static inline const char *au_sbtype(struct super_block *sb) ++{ ++ return sb->s_type->name; ++} ++ ++static inline int au_test_iso9660(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE) ++ return sb->s_magic == ISOFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_romfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE) ++ return sb->s_magic == ROMFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_cramfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) ++ return sb->s_magic == CRAMFS_MAGIC; ++#endif ++ return 0; ++} ++ ++static inline int au_test_nfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_NFS_FS) || defined(CONFIG_NFS_FS_MODULE) ++ return sb->s_magic == NFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_fuse(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_FUSE_FS) || defined(CONFIG_FUSE_FS_MODULE) ++ return sb->s_magic == FUSE_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_xfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_XFS_FS) || defined(CONFIG_XFS_FS_MODULE) ++ return sb->s_magic == XFS_SB_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_tmpfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_TMPFS ++ return sb->s_magic == TMPFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ecryptfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_ECRYPT_FS) || defined(CONFIG_ECRYPT_FS_MODULE) ++ return !strcmp(au_sbtype(sb), "ecryptfs"); ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ocfs2(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE) ++ return sb->s_magic == OCFS2_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ocfs2_dlmfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_OCFS2_FS_O2CB) || defined(CONFIG_OCFS2_FS_O2CB_MODULE) ++ return sb->s_magic == DLMFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_coda(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CODA_FS) || defined(CONFIG_CODA_FS_MODULE) ++ return sb->s_magic == CODA_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_v9fs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_9P_FS) || defined(CONFIG_9P_FS_MODULE) ++ return sb->s_magic == V9FS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ext4(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_EXT4_FS) || defined(CONFIG_EXT4_FS_MODULE) ++ return sb->s_magic == EXT4_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_sysv(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SYSV_FS) || defined(CONFIG_SYSV_FS_MODULE) ++ return !strcmp(au_sbtype(sb), "sysv"); ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_ramfs(struct super_block *sb) ++{ ++ return sb->s_magic == RAMFS_MAGIC; ++} ++ ++static inline int au_test_ubifs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_UBIFS_FS) || defined(CONFIG_UBIFS_FS_MODULE) ++ return sb->s_magic == UBIFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_procfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_PROC_FS ++ return sb->s_magic == PROC_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_sysfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_SYSFS ++ return sb->s_magic == SYSFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_configfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CONFIGFS_FS) || defined(CONFIG_CONFIGFS_FS_MODULE) ++ return sb->s_magic == CONFIGFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_minix(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_MINIX_FS) || defined(CONFIG_MINIX_FS_MODULE) ++ return sb->s_magic == MINIX3_SUPER_MAGIC ++ || sb->s_magic == MINIX2_SUPER_MAGIC ++ || sb->s_magic == MINIX2_SUPER_MAGIC2 ++ || sb->s_magic == MINIX_SUPER_MAGIC ++ || sb->s_magic == MINIX_SUPER_MAGIC2; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_cifs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_CIFS_FS) || defined(CONFIGCIFS_FS_MODULE) ++ return sb->s_magic == CIFS_MAGIC_NUMBER; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_fat(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_FAT_FS) || defined(CONFIG_FAT_FS_MODULE) ++ return sb->s_magic == MSDOS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_msdos(struct super_block *sb) ++{ ++ return au_test_fat(sb); ++} ++ ++static inline int au_test_vfat(struct super_block *sb) ++{ ++ return au_test_fat(sb); ++} ++ ++static inline int au_test_securityfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_SECURITYFS ++ return sb->s_magic == SECURITYFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_squashfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_SQUASHFS) || defined(CONFIG_SQUASHFS_MODULE) ++ return sb->s_magic == SQUASHFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_btrfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_BTRFS_FS) || defined(CONFIG_BTRFS_FS_MODULE) ++ return sb->s_magic == BTRFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_xenfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_XENFS) || defined(CONFIG_XENFS_MODULE) ++ return sb->s_magic == XENFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_debugfs(struct super_block *sb __maybe_unused) ++{ ++#ifdef CONFIG_DEBUG_FS ++ return sb->s_magic == DEBUGFS_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_nilfs(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_NILFS) || defined(CONFIG_NILFS_MODULE) ++ return sb->s_magic == NILFS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++static inline int au_test_hfsplus(struct super_block *sb __maybe_unused) ++{ ++#if defined(CONFIG_HFSPLUS_FS) || defined(CONFIG_HFSPLUS_FS_MODULE) ++ return sb->s_magic == HFSPLUS_SUPER_MAGIC; ++#else ++ return 0; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * they can't be an aufs branch. ++ */ ++static inline int au_test_fs_unsuppoted(struct super_block *sb) ++{ ++ return ++#ifndef CONFIG_AUFS_BR_RAMFS ++ au_test_ramfs(sb) || ++#endif ++ au_test_procfs(sb) ++ || au_test_sysfs(sb) ++ || au_test_configfs(sb) ++ || au_test_debugfs(sb) ++ || au_test_securityfs(sb) ++ || au_test_xenfs(sb) ++ || au_test_ecryptfs(sb) ++ /* || !strcmp(au_sbtype(sb), "unionfs") */ ++ || au_test_aufs(sb); /* will be supported in next version */ ++} ++ ++static inline int au_test_fs_remote(struct super_block *sb) ++{ ++ return !au_test_tmpfs(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ && !au_test_ramfs(sb) ++#endif ++ && !(sb->s_type->fs_flags & FS_REQUIRES_DEV); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * Note: these functions (below) are created after reading ->getattr() in all ++ * filesystems under linux/fs. it means we have to do so in every update... ++ */ ++ ++/* ++ * some filesystems require getattr to refresh the inode attributes before ++ * referencing. ++ * in most cases, we can rely on the inode attribute in NFS (or every remote fs) ++ * and leave the work for d_revalidate() ++ */ ++static inline int au_test_fs_refresh_iattr(struct super_block *sb) ++{ ++ return au_test_nfs(sb) ++ || au_test_fuse(sb) ++ /* || au_test_ocfs2(sb) */ /* untested */ ++ /* || au_test_btrfs(sb) */ /* untested */ ++ /* || au_test_coda(sb) */ /* untested */ ++ /* || au_test_v9fs(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which don't maintain i_size or i_blocks. ++ */ ++static inline int au_test_fs_bad_iattr_size(struct super_block *sb) ++{ ++ return au_test_xfs(sb) ++ || au_test_btrfs(sb) ++ || au_test_ubifs(sb) ++ || au_test_hfsplus(sb) /* maintained, but incorrect */ ++ /* || au_test_ext4(sb) */ /* untested */ ++ /* || au_test_ocfs2(sb) */ /* untested */ ++ /* || au_test_ocfs2_dlmfs(sb) */ /* untested */ ++ /* || au_test_sysv(sb) */ /* untested */ ++ /* || au_test_minix(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which don't store the correct value in some of their inode ++ * attributes. ++ */ ++static inline int au_test_fs_bad_iattr(struct super_block *sb) ++{ ++ return au_test_fs_bad_iattr_size(sb) ++ /* || au_test_cifs(sb) */ /* untested */ ++ || au_test_fat(sb) ++ || au_test_msdos(sb) ++ || au_test_vfat(sb); ++} ++ ++/* they don't check i_nlink in link(2) */ ++static inline int au_test_fs_no_limit_nlink(struct super_block *sb) ++{ ++ return au_test_tmpfs(sb) ++#ifdef CONFIG_AUFS_BR_RAMFS ++ || au_test_ramfs(sb) ++#endif ++ || au_test_ubifs(sb) ++ || au_test_hfsplus(sb); ++} ++ ++/* ++ * filesystems which sets S_NOATIME and S_NOCMTIME. ++ */ ++static inline int au_test_fs_notime(struct super_block *sb) ++{ ++ return au_test_nfs(sb) ++ || au_test_fuse(sb) ++ || au_test_ubifs(sb) ++ /* || au_test_cifs(sb) */ /* untested */ ++ ; ++} ++ ++/* ++ * filesystems which requires replacing i_mapping. ++ */ ++static inline int au_test_fs_bad_mapping(struct super_block *sb) ++{ ++ return au_test_fuse(sb) ++ || au_test_ubifs(sb); ++} ++ ++/* temporary support for i#1 in cramfs */ ++static inline int au_test_fs_unique_ino(struct inode *inode) ++{ ++ if (au_test_cramfs(inode->i_sb)) ++ return inode->i_ino != 1; ++ return 1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * the filesystem where the xino files placed must support i/o after unlink and ++ * maintain i_size and i_blocks. ++ */ ++static inline int au_test_fs_bad_xino(struct super_block *sb) ++{ ++ return au_test_fs_remote(sb) ++ || au_test_fs_bad_iattr_size(sb) ++ /* don't want unnecessary work for xino */ ++ || au_test_aufs(sb) ++ || au_test_ecryptfs(sb) ++ || au_test_nilfs(sb); ++} ++ ++static inline int au_test_fs_trunc_xino(struct super_block *sb) ++{ ++ return au_test_tmpfs(sb) ++ || au_test_ramfs(sb); ++} ++ ++/* ++ * test if the @sb is real-readonly. ++ */ ++static inline int au_test_fs_rr(struct super_block *sb) ++{ ++ return au_test_squashfs(sb) ++ || au_test_iso9660(sb) ++ || au_test_cramfs(sb) ++ || au_test_romfs(sb); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_FSTYPE_H__ */ +diff --git a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c +new file mode 100644 +index 0000000..2dd7419 +--- /dev/null ++++ b/fs/aufs/hfsnotify.c +@@ -0,0 +1,275 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * fsnotify for the lower directories ++ */ ++ ++#include "aufs.h" ++ ++/* FS_IN_IGNORED is unnecessary */ ++static const __u32 AuHfsnMask = (FS_MOVED_TO | FS_MOVED_FROM | FS_DELETE ++ | FS_CREATE | FS_EVENT_ON_CHILD); ++static DECLARE_WAIT_QUEUE_HEAD(au_hfsn_wq); ++static __cacheline_aligned_in_smp atomic64_t au_hfsn_ifree = ATOMIC64_INIT(0); ++ ++static void au_hfsn_free_mark(struct fsnotify_mark *mark) ++{ ++ struct au_hnotify *hn = container_of(mark, struct au_hnotify, ++ hn_mark); ++ AuDbg("here\n"); ++ au_cache_free_hnotify(hn); ++ smp_mb__before_atomic(); ++ if (atomic64_dec_and_test(&au_hfsn_ifree)) ++ wake_up(&au_hfsn_wq); ++} ++ ++static int au_hfsn_alloc(struct au_hinode *hinode) ++{ ++ int err; ++ struct au_hnotify *hn; ++ struct super_block *sb; ++ struct au_branch *br; ++ struct fsnotify_mark *mark; ++ aufs_bindex_t bindex; ++ ++ hn = hinode->hi_notify; ++ sb = hn->hn_aufs_inode->i_sb; ++ bindex = au_br_index(sb, hinode->hi_id); ++ br = au_sbr(sb, bindex); ++ AuDebugOn(!br->br_hfsn); ++ ++ mark = &hn->hn_mark; ++ fsnotify_init_mark(mark, au_hfsn_free_mark); ++ mark->mask = AuHfsnMask; ++ /* ++ * by udba rename or rmdir, aufs assign a new inode to the known ++ * h_inode, so specify 1 to allow dups. ++ */ ++ lockdep_off(); ++ err = fsnotify_add_mark(mark, br->br_hfsn->hfsn_group, hinode->hi_inode, ++ /*mnt*/NULL, /*allow_dups*/1); ++ /* even if err */ ++ fsnotify_put_mark(mark); ++ lockdep_on(); ++ ++ return err; ++} ++ ++static int au_hfsn_free(struct au_hinode *hinode, struct au_hnotify *hn) ++{ ++ struct fsnotify_mark *mark; ++ unsigned long long ull; ++ struct fsnotify_group *group; ++ ++ ull = atomic64_inc_return(&au_hfsn_ifree); ++ BUG_ON(!ull); ++ ++ mark = &hn->hn_mark; ++ spin_lock(&mark->lock); ++ group = mark->group; ++ fsnotify_get_group(group); ++ spin_unlock(&mark->lock); ++ lockdep_off(); ++ fsnotify_destroy_mark(mark, group); ++ fsnotify_put_group(group); ++ lockdep_on(); ++ ++ /* free hn by myself */ ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_hfsn_ctl(struct au_hinode *hinode, int do_set) ++{ ++ struct fsnotify_mark *mark; ++ ++ mark = &hinode->hi_notify->hn_mark; ++ spin_lock(&mark->lock); ++ if (do_set) { ++ AuDebugOn(mark->mask & AuHfsnMask); ++ mark->mask |= AuHfsnMask; ++ } else { ++ AuDebugOn(!(mark->mask & AuHfsnMask)); ++ mark->mask &= ~AuHfsnMask; ++ } ++ spin_unlock(&mark->lock); ++ /* fsnotify_recalc_inode_mask(hinode->hi_inode); */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* #define AuDbgHnotify */ ++#ifdef AuDbgHnotify ++static char *au_hfsn_name(u32 mask) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++#define test_ret(flag) \ ++ do { \ ++ if (mask & flag) \ ++ return #flag; \ ++ } while (0) ++ test_ret(FS_ACCESS); ++ test_ret(FS_MODIFY); ++ test_ret(FS_ATTRIB); ++ test_ret(FS_CLOSE_WRITE); ++ test_ret(FS_CLOSE_NOWRITE); ++ test_ret(FS_OPEN); ++ test_ret(FS_MOVED_FROM); ++ test_ret(FS_MOVED_TO); ++ test_ret(FS_CREATE); ++ test_ret(FS_DELETE); ++ test_ret(FS_DELETE_SELF); ++ test_ret(FS_MOVE_SELF); ++ test_ret(FS_UNMOUNT); ++ test_ret(FS_Q_OVERFLOW); ++ test_ret(FS_IN_IGNORED); ++ test_ret(FS_IN_ISDIR); ++ test_ret(FS_IN_ONESHOT); ++ test_ret(FS_EVENT_ON_CHILD); ++ return ""; ++#undef test_ret ++#else ++ return "??"; ++#endif ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_hfsn_free_group(struct fsnotify_group *group) ++{ ++ struct au_br_hfsnotify *hfsn = group->private; ++ ++ AuDbg("here\n"); ++ kfree(hfsn); ++} ++ ++static int au_hfsn_handle_event(struct fsnotify_group *group, ++ struct inode *inode, ++ struct fsnotify_mark *inode_mark, ++ struct fsnotify_mark *vfsmount_mark, ++ u32 mask, void *data, int data_type, ++ const unsigned char *file_name, u32 cookie) ++{ ++ int err; ++ struct au_hnotify *hnotify; ++ struct inode *h_dir, *h_inode; ++ struct qstr h_child_qstr = QSTR_INIT(file_name, strlen(file_name)); ++ ++ AuDebugOn(data_type != FSNOTIFY_EVENT_INODE); ++ ++ err = 0; ++ /* if FS_UNMOUNT happens, there must be another bug */ ++ AuDebugOn(mask & FS_UNMOUNT); ++ if (mask & (FS_IN_IGNORED | FS_UNMOUNT)) ++ goto out; ++ ++ h_dir = inode; ++ h_inode = NULL; ++#ifdef AuDbgHnotify ++ au_debug_on(); ++ if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1 ++ || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) { ++ AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n", ++ h_dir->i_ino, mask, au_hfsn_name(mask), ++ AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0); ++ /* WARN_ON(1); */ ++ } ++ au_debug_off(); ++#endif ++ ++ AuDebugOn(!inode_mark); ++ hnotify = container_of(inode_mark, struct au_hnotify, hn_mark); ++ err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode); ++ ++out: ++ return err; ++} ++ ++static struct fsnotify_ops au_hfsn_ops = { ++ .handle_event = au_hfsn_handle_event, ++ .free_group_priv = au_hfsn_free_group ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_hfsn_fin_br(struct au_branch *br) ++{ ++ struct au_br_hfsnotify *hfsn; ++ ++ hfsn = br->br_hfsn; ++ if (hfsn) { ++ lockdep_off(); ++ fsnotify_put_group(hfsn->hfsn_group); ++ lockdep_on(); ++ } ++} ++ ++static int au_hfsn_init_br(struct au_branch *br, int perm) ++{ ++ int err; ++ struct fsnotify_group *group; ++ struct au_br_hfsnotify *hfsn; ++ ++ err = 0; ++ br->br_hfsn = NULL; ++ if (!au_br_hnotifyable(perm)) ++ goto out; ++ ++ err = -ENOMEM; ++ hfsn = kmalloc(sizeof(*hfsn), GFP_NOFS); ++ if (unlikely(!hfsn)) ++ goto out; ++ ++ err = 0; ++ group = fsnotify_alloc_group(&au_hfsn_ops); ++ if (IS_ERR(group)) { ++ err = PTR_ERR(group); ++ pr_err("fsnotify_alloc_group() failed, %d\n", err); ++ goto out_hfsn; ++ } ++ ++ group->private = hfsn; ++ hfsn->hfsn_group = group; ++ br->br_hfsn = hfsn; ++ goto out; /* success */ ++ ++out_hfsn: ++ kfree(hfsn); ++out: ++ return err; ++} ++ ++static int au_hfsn_reset_br(unsigned int udba, struct au_branch *br, int perm) ++{ ++ int err; ++ ++ err = 0; ++ if (!br->br_hfsn) ++ err = au_hfsn_init_br(br, perm); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_hfsn_fin(void) ++{ ++ AuDbg("au_hfsn_ifree %lld\n", (long long)atomic64_read(&au_hfsn_ifree)); ++ wait_event(au_hfsn_wq, !atomic64_read(&au_hfsn_ifree)); ++} ++ ++const struct au_hnotify_op au_hnotify_op = { ++ .ctl = au_hfsn_ctl, ++ .alloc = au_hfsn_alloc, ++ .free = au_hfsn_free, ++ ++ .fin = au_hfsn_fin, ++ ++ .reset_br = au_hfsn_reset_br, ++ .fin_br = au_hfsn_fin_br, ++ .init_br = au_hfsn_init_br ++}; +diff --git a/fs/aufs/hfsplus.c b/fs/aufs/hfsplus.c +new file mode 100644 +index 0000000..78ec26f +--- /dev/null ++++ b/fs/aufs/hfsplus.c +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (C) 2010-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * special support for filesystems which aqucires an inode mutex ++ * at final closing a file, eg, hfsplus. ++ * ++ * This trick is very simple and stupid, just to open the file before really ++ * neceeary open to tell hfsplus that this is not the final closing. ++ * The caller should call au_h_open_pre() after acquiring the inode mutex, ++ * and au_h_open_post() after releasing it. ++ */ ++ ++#include "aufs.h" ++ ++struct file *au_h_open_pre(struct dentry *dentry, aufs_bindex_t bindex, ++ int force_wr) ++{ ++ struct file *h_file; ++ struct dentry *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ AuDebugOn(!h_dentry); ++ AuDebugOn(!h_dentry->d_inode); ++ ++ h_file = NULL; ++ if (au_test_hfsplus(h_dentry->d_sb) ++ && S_ISREG(h_dentry->d_inode->i_mode)) ++ h_file = au_h_open(dentry, bindex, ++ O_RDONLY | O_NOATIME | O_LARGEFILE, ++ /*file*/NULL, force_wr); ++ return h_file; ++} ++ ++void au_h_open_post(struct dentry *dentry, aufs_bindex_t bindex, ++ struct file *h_file) ++{ ++ if (h_file) { ++ fput(h_file); ++ au_sbr_put(dentry->d_sb, bindex); ++ } ++} +diff --git a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c +new file mode 100644 +index 0000000..a07e4f2 +--- /dev/null ++++ b/fs/aufs/hnotify.c +@@ -0,0 +1,701 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * abstraction to notify the direct changes on lower directories ++ */ ++ ++#include "aufs.h" ++ ++int au_hn_alloc(struct au_hinode *hinode, struct inode *inode) ++{ ++ int err; ++ struct au_hnotify *hn; ++ ++ err = -ENOMEM; ++ hn = au_cache_alloc_hnotify(); ++ if (hn) { ++ hn->hn_aufs_inode = inode; ++ hinode->hi_notify = hn; ++ err = au_hnotify_op.alloc(hinode); ++ AuTraceErr(err); ++ if (unlikely(err)) { ++ hinode->hi_notify = NULL; ++ au_cache_free_hnotify(hn); ++ /* ++ * The upper dir was removed by udba, but the same named ++ * dir left. In this case, aufs assignes a new inode ++ * number and set the monitor again. ++ * For the lower dir, the old monitnor is still left. ++ */ ++ if (err == -EEXIST) ++ err = 0; ++ } ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++void au_hn_free(struct au_hinode *hinode) ++{ ++ struct au_hnotify *hn; ++ ++ hn = hinode->hi_notify; ++ if (hn) { ++ hinode->hi_notify = NULL; ++ if (au_hnotify_op.free(hinode, hn)) ++ au_cache_free_hnotify(hn); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_hn_ctl(struct au_hinode *hinode, int do_set) ++{ ++ if (hinode->hi_notify) ++ au_hnotify_op.ctl(hinode, do_set); ++} ++ ++void au_hn_reset(struct inode *inode, unsigned int flags) ++{ ++ aufs_bindex_t bindex, bend; ++ struct inode *hi; ++ struct dentry *iwhdentry; ++ ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { ++ hi = au_h_iptr(inode, bindex); ++ if (!hi) ++ continue; ++ ++ /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */ ++ iwhdentry = au_hi_wh(inode, bindex); ++ if (iwhdentry) ++ dget(iwhdentry); ++ au_igrab(hi); ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ au_set_h_iptr(inode, bindex, au_igrab(hi), ++ flags & ~AuHi_XINO); ++ iput(hi); ++ dput(iwhdentry); ++ /* mutex_unlock(&hi->i_mutex); */ ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int hn_xino(struct inode *inode, struct inode *h_inode) ++{ ++ int err; ++ aufs_bindex_t bindex, bend, bfound, bstart; ++ struct inode *h_i; ++ ++ err = 0; ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ pr_warn("branch root dir was changed\n"); ++ goto out; ++ } ++ ++ bfound = -1; ++ bend = au_ibend(inode); ++ bstart = au_ibstart(inode); ++#if 0 /* reserved for future use */ ++ if (bindex == bend) { ++ /* keep this ino in rename case */ ++ goto out; ++ } ++#endif ++ for (bindex = bstart; bindex <= bend; bindex++) ++ if (au_h_iptr(inode, bindex) == h_inode) { ++ bfound = bindex; ++ break; ++ } ++ if (bfound < 0) ++ goto out; ++ ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ h_i = au_h_iptr(inode, bindex); ++ if (!h_i) ++ continue; ++ ++ err = au_xino_write(inode->i_sb, bindex, h_i->i_ino, /*ino*/0); ++ /* ignore this error */ ++ /* bad action? */ ++ } ++ ++ /* children inode number will be broken */ ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int hn_gen_tree(struct dentry *dentry) ++{ ++ int err, i, j, ndentry; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, dentry, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) { ++ struct dentry *d; ++ ++ d = dentries[j]; ++ if (IS_ROOT(d)) ++ continue; ++ ++ au_digen_dec(d); ++ if (d->d_inode) ++ /* todo: reset children xino? ++ cached children only? */ ++ au_iigen_dec(d->d_inode); ++ } ++ } ++ ++out_dpages: ++ au_dpages_free(&dpages); ++ ++#if 0 ++ /* discard children */ ++ dentry_unhash(dentry); ++ dput(dentry); ++#endif ++out: ++ return err; ++} ++ ++/* ++ * return 0 if processed. ++ */ ++static int hn_gen_by_inode(char *name, unsigned int nlen, struct inode *inode, ++ const unsigned int isdir) ++{ ++ int err; ++ struct dentry *d; ++ struct qstr *dname; ++ ++ err = 1; ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ pr_warn("branch root dir was changed\n"); ++ err = 0; ++ goto out; ++ } ++ ++ if (!isdir) { ++ AuDebugOn(!name); ++ au_iigen_dec(inode); ++ spin_lock(&inode->i_lock); ++ hlist_for_each_entry(d, &inode->i_dentry, d_u.d_alias) { ++ spin_lock(&d->d_lock); ++ dname = &d->d_name; ++ if (dname->len != nlen ++ && memcmp(dname->name, name, nlen)) { ++ spin_unlock(&d->d_lock); ++ continue; ++ } ++ err = 0; ++ au_digen_dec(d); ++ spin_unlock(&d->d_lock); ++ break; ++ } ++ spin_unlock(&inode->i_lock); ++ } else { ++ au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR); ++ d = d_find_any_alias(inode); ++ if (!d) { ++ au_iigen_dec(inode); ++ goto out; ++ } ++ ++ spin_lock(&d->d_lock); ++ dname = &d->d_name; ++ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) { ++ spin_unlock(&d->d_lock); ++ err = hn_gen_tree(d); ++ spin_lock(&d->d_lock); ++ } ++ spin_unlock(&d->d_lock); ++ dput(d); ++ } ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int hn_gen_by_name(struct dentry *dentry, const unsigned int isdir) ++{ ++ int err; ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ if (IS_ROOT(dentry) ++ /* || (inode && inode->i_ino == AUFS_ROOT_INO) */ ++ ) { ++ pr_warn("branch root dir was changed\n"); ++ return 0; ++ } ++ ++ err = 0; ++ if (!isdir) { ++ au_digen_dec(dentry); ++ if (inode) ++ au_iigen_dec(inode); ++ } else { ++ au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIR); ++ if (inode) ++ err = hn_gen_tree(dentry); ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* hnotify job flags */ ++#define AuHnJob_XINO0 1 ++#define AuHnJob_GEN (1 << 1) ++#define AuHnJob_DIRENT (1 << 2) ++#define AuHnJob_ISDIR (1 << 3) ++#define AuHnJob_TRYXINO0 (1 << 4) ++#define AuHnJob_MNTPNT (1 << 5) ++#define au_ftest_hnjob(flags, name) ((flags) & AuHnJob_##name) ++#define au_fset_hnjob(flags, name) \ ++ do { (flags) |= AuHnJob_##name; } while (0) ++#define au_fclr_hnjob(flags, name) \ ++ do { (flags) &= ~AuHnJob_##name; } while (0) ++ ++enum { ++ AuHn_CHILD, ++ AuHn_PARENT, ++ AuHnLast ++}; ++ ++struct au_hnotify_args { ++ struct inode *h_dir, *dir, *h_child_inode; ++ u32 mask; ++ unsigned int flags[AuHnLast]; ++ unsigned int h_child_nlen; ++ char h_child_name[]; ++}; ++ ++struct hn_job_args { ++ unsigned int flags; ++ struct inode *inode, *h_inode, *dir, *h_dir; ++ struct dentry *dentry; ++ char *h_name; ++ int h_nlen; ++}; ++ ++static int hn_job(struct hn_job_args *a) ++{ ++ const unsigned int isdir = au_ftest_hnjob(a->flags, ISDIR); ++ int e; ++ ++ /* reset xino */ ++ if (au_ftest_hnjob(a->flags, XINO0) && a->inode) ++ hn_xino(a->inode, a->h_inode); /* ignore this error */ ++ ++ if (au_ftest_hnjob(a->flags, TRYXINO0) ++ && a->inode ++ && a->h_inode) { ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ if (!a->h_inode->i_nlink ++ && !(a->h_inode->i_state & I_LINKABLE)) ++ hn_xino(a->inode, a->h_inode); /* ignore this error */ ++ mutex_unlock(&a->h_inode->i_mutex); ++ } ++ ++ /* make the generation obsolete */ ++ if (au_ftest_hnjob(a->flags, GEN)) { ++ e = -1; ++ if (a->inode) ++ e = hn_gen_by_inode(a->h_name, a->h_nlen, a->inode, ++ isdir); ++ if (e && a->dentry) ++ hn_gen_by_name(a->dentry, isdir); ++ /* ignore this error */ ++ } ++ ++ /* make dir entries obsolete */ ++ if (au_ftest_hnjob(a->flags, DIRENT) && a->inode) { ++ struct au_vdir *vdir; ++ ++ vdir = au_ivdir(a->inode); ++ if (vdir) ++ vdir->vd_jiffy = 0; ++ /* IMustLock(a->inode); */ ++ /* a->inode->i_version++; */ ++ } ++ ++ /* can do nothing but warn */ ++ if (au_ftest_hnjob(a->flags, MNTPNT) ++ && a->dentry ++ && d_mountpoint(a->dentry)) ++ pr_warn("mount-point %pd is removed or renamed\n", a->dentry); ++ ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen, ++ struct inode *dir) ++{ ++ struct dentry *dentry, *d, *parent; ++ struct qstr *dname; ++ ++ parent = d_find_any_alias(dir); ++ if (!parent) ++ return NULL; ++ ++ dentry = NULL; ++ spin_lock(&parent->d_lock); ++ list_for_each_entry(d, &parent->d_subdirs, d_child) { ++ /* AuDbg("%pd\n", d); */ ++ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); ++ dname = &d->d_name; ++ if (dname->len != nlen || memcmp(dname->name, name, nlen)) ++ goto cont_unlock; ++ if (au_di(d)) ++ au_digen_dec(d); ++ else ++ goto cont_unlock; ++ if (au_dcount(d) > 0) { ++ dentry = dget_dlock(d); ++ spin_unlock(&d->d_lock); ++ break; ++ } ++ ++cont_unlock: ++ spin_unlock(&d->d_lock); ++ } ++ spin_unlock(&parent->d_lock); ++ dput(parent); ++ ++ if (dentry) ++ di_write_lock_child(dentry); ++ ++ return dentry; ++} ++ ++static struct inode *lookup_wlock_by_ino(struct super_block *sb, ++ aufs_bindex_t bindex, ino_t h_ino) ++{ ++ struct inode *inode; ++ ino_t ino; ++ int err; ++ ++ inode = NULL; ++ err = au_xino_read(sb, bindex, h_ino, &ino); ++ if (!err && ino) ++ inode = ilookup(sb, ino); ++ if (!inode) ++ goto out; ++ ++ if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { ++ pr_warn("wrong root branch\n"); ++ iput(inode); ++ inode = NULL; ++ goto out; ++ } ++ ++ ii_write_lock_child(inode); ++ ++out: ++ return inode; ++} ++ ++static void au_hn_bh(void *_args) ++{ ++ struct au_hnotify_args *a = _args; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend, bfound; ++ unsigned char xino, try_iput; ++ int err; ++ struct inode *inode; ++ ino_t h_ino; ++ struct hn_job_args args; ++ struct dentry *dentry; ++ struct au_sbinfo *sbinfo; ++ ++ AuDebugOn(!_args); ++ AuDebugOn(!a->h_dir); ++ AuDebugOn(!a->dir); ++ AuDebugOn(!a->mask); ++ AuDbg("mask 0x%x, i%lu, hi%lu, hci%lu\n", ++ a->mask, a->dir->i_ino, a->h_dir->i_ino, ++ a->h_child_inode ? a->h_child_inode->i_ino : 0); ++ ++ inode = NULL; ++ dentry = NULL; ++ /* ++ * do not lock a->dir->i_mutex here ++ * because of d_revalidate() may cause a deadlock. ++ */ ++ sb = a->dir->i_sb; ++ AuDebugOn(!sb); ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!sbinfo); ++ si_write_lock(sb, AuLock_NOPLMW); ++ ++ ii_read_lock_parent(a->dir); ++ bfound = -1; ++ bend = au_ibend(a->dir); ++ for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++) ++ if (au_h_iptr(a->dir, bindex) == a->h_dir) { ++ bfound = bindex; ++ break; ++ } ++ ii_read_unlock(a->dir); ++ if (unlikely(bfound < 0)) ++ goto out; ++ ++ xino = !!au_opt_test(au_mntflags(sb), XINO); ++ h_ino = 0; ++ if (a->h_child_inode) ++ h_ino = a->h_child_inode->i_ino; ++ ++ if (a->h_child_nlen ++ && (au_ftest_hnjob(a->flags[AuHn_CHILD], GEN) ++ || au_ftest_hnjob(a->flags[AuHn_CHILD], MNTPNT))) ++ dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, ++ a->dir); ++ try_iput = 0; ++ if (dentry) ++ inode = dentry->d_inode; ++ if (xino && !inode && h_ino ++ && (au_ftest_hnjob(a->flags[AuHn_CHILD], XINO0) ++ || au_ftest_hnjob(a->flags[AuHn_CHILD], TRYXINO0) ++ || au_ftest_hnjob(a->flags[AuHn_CHILD], GEN))) { ++ inode = lookup_wlock_by_ino(sb, bfound, h_ino); ++ try_iput = 1; ++ } ++ ++ args.flags = a->flags[AuHn_CHILD]; ++ args.dentry = dentry; ++ args.inode = inode; ++ args.h_inode = a->h_child_inode; ++ args.dir = a->dir; ++ args.h_dir = a->h_dir; ++ args.h_name = a->h_child_name; ++ args.h_nlen = a->h_child_nlen; ++ err = hn_job(&args); ++ if (dentry) { ++ if (au_di(dentry)) ++ di_write_unlock(dentry); ++ dput(dentry); ++ } ++ if (inode && try_iput) { ++ ii_write_unlock(inode); ++ iput(inode); ++ } ++ ++ ii_write_lock_parent(a->dir); ++ args.flags = a->flags[AuHn_PARENT]; ++ args.dentry = NULL; ++ args.inode = a->dir; ++ args.h_inode = a->h_dir; ++ args.dir = NULL; ++ args.h_dir = NULL; ++ args.h_name = NULL; ++ args.h_nlen = 0; ++ err = hn_job(&args); ++ ii_write_unlock(a->dir); ++ ++out: ++ iput(a->h_child_inode); ++ iput(a->h_dir); ++ iput(a->dir); ++ si_write_unlock(sb); ++ au_nwt_done(&sbinfo->si_nowait); ++ kfree(a); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, ++ struct qstr *h_child_qstr, struct inode *h_child_inode) ++{ ++ int err, len; ++ unsigned int flags[AuHnLast], f; ++ unsigned char isdir, isroot, wh; ++ struct inode *dir; ++ struct au_hnotify_args *args; ++ char *p, *h_child_name; ++ ++ err = 0; ++ AuDebugOn(!hnotify || !hnotify->hn_aufs_inode); ++ dir = igrab(hnotify->hn_aufs_inode); ++ if (!dir) ++ goto out; ++ ++ isroot = (dir->i_ino == AUFS_ROOT_INO); ++ wh = 0; ++ h_child_name = (void *)h_child_qstr->name; ++ len = h_child_qstr->len; ++ if (h_child_name) { ++ if (len > AUFS_WH_PFX_LEN ++ && !memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ h_child_name += AUFS_WH_PFX_LEN; ++ len -= AUFS_WH_PFX_LEN; ++ wh = 1; ++ } ++ } ++ ++ isdir = 0; ++ if (h_child_inode) ++ isdir = !!S_ISDIR(h_child_inode->i_mode); ++ flags[AuHn_PARENT] = AuHnJob_ISDIR; ++ flags[AuHn_CHILD] = 0; ++ if (isdir) ++ flags[AuHn_CHILD] = AuHnJob_ISDIR; ++ au_fset_hnjob(flags[AuHn_PARENT], DIRENT); ++ au_fset_hnjob(flags[AuHn_CHILD], GEN); ++ switch (mask & FS_EVENTS_POSS_ON_CHILD) { ++ case FS_MOVED_FROM: ++ case FS_MOVED_TO: ++ au_fset_hnjob(flags[AuHn_CHILD], XINO0); ++ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT); ++ /*FALLTHROUGH*/ ++ case FS_CREATE: ++ AuDebugOn(!h_child_name); ++ break; ++ ++ case FS_DELETE: ++ /* ++ * aufs never be able to get this child inode. ++ * revalidation should be in d_revalidate() ++ * by checking i_nlink, i_generation or d_unhashed(). ++ */ ++ AuDebugOn(!h_child_name); ++ au_fset_hnjob(flags[AuHn_CHILD], TRYXINO0); ++ au_fset_hnjob(flags[AuHn_CHILD], MNTPNT); ++ break; ++ ++ default: ++ AuDebugOn(1); ++ } ++ ++ if (wh) ++ h_child_inode = NULL; ++ ++ err = -ENOMEM; ++ /* iput() and kfree() will be called in au_hnotify() */ ++ args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS); ++ if (unlikely(!args)) { ++ AuErr1("no memory\n"); ++ iput(dir); ++ goto out; ++ } ++ args->flags[AuHn_PARENT] = flags[AuHn_PARENT]; ++ args->flags[AuHn_CHILD] = flags[AuHn_CHILD]; ++ args->mask = mask; ++ args->dir = dir; ++ args->h_dir = igrab(h_dir); ++ if (h_child_inode) ++ h_child_inode = igrab(h_child_inode); /* can be NULL */ ++ args->h_child_inode = h_child_inode; ++ args->h_child_nlen = len; ++ if (len) { ++ p = (void *)args; ++ p += sizeof(*args); ++ memcpy(p, h_child_name, len); ++ p[len] = 0; ++ } ++ ++ /* NFS fires the event for silly-renamed one from kworker */ ++ f = 0; ++ if (!dir->i_nlink ++ || (au_test_nfs(h_dir->i_sb) && (mask & FS_DELETE))) ++ f = AuWkq_NEST; ++ err = au_wkq_nowait(au_hn_bh, args, dir->i_sb, f); ++ if (unlikely(err)) { ++ pr_err("wkq %d\n", err); ++ iput(args->h_child_inode); ++ iput(args->h_dir); ++ iput(args->dir); ++ kfree(args); ++ } ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm) ++{ ++ int err; ++ ++ AuDebugOn(!(udba & AuOptMask_UDBA)); ++ ++ err = 0; ++ if (au_hnotify_op.reset_br) ++ err = au_hnotify_op.reset_br(udba, br, perm); ++ ++ return err; ++} ++ ++int au_hnotify_init_br(struct au_branch *br, int perm) ++{ ++ int err; ++ ++ err = 0; ++ if (au_hnotify_op.init_br) ++ err = au_hnotify_op.init_br(br, perm); ++ ++ return err; ++} ++ ++void au_hnotify_fin_br(struct au_branch *br) ++{ ++ if (au_hnotify_op.fin_br) ++ au_hnotify_op.fin_br(br); ++} ++ ++static void au_hn_destroy_cache(void) ++{ ++ kmem_cache_destroy(au_cachep[AuCache_HNOTIFY]); ++ au_cachep[AuCache_HNOTIFY] = NULL; ++} ++ ++int __init au_hnotify_init(void) ++{ ++ int err; ++ ++ err = -ENOMEM; ++ au_cachep[AuCache_HNOTIFY] = AuCache(au_hnotify); ++ if (au_cachep[AuCache_HNOTIFY]) { ++ err = 0; ++ if (au_hnotify_op.init) ++ err = au_hnotify_op.init(); ++ if (unlikely(err)) ++ au_hn_destroy_cache(); ++ } ++ AuTraceErr(err); ++ return err; ++} ++ ++void au_hnotify_fin(void) ++{ ++ if (au_hnotify_op.fin) ++ au_hnotify_op.fin(); ++ /* cf. au_cache_fin() */ ++ if (au_cachep[AuCache_HNOTIFY]) ++ au_hn_destroy_cache(); ++} +diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c +new file mode 100644 +index 0000000..e33cbec +--- /dev/null ++++ b/fs/aufs/i_op.c +@@ -0,0 +1,1286 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode operations (except add/del/rename) ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++static int h_permission(struct inode *h_inode, int mask, ++ struct vfsmount *h_mnt, int brperm) ++{ ++ int err; ++ const unsigned char write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); ++ ++ err = -EACCES; ++ if ((write_mask && IS_IMMUTABLE(h_inode)) ++ || ((mask & MAY_EXEC) ++ && S_ISREG(h_inode->i_mode) ++ && ((h_mnt->mnt_flags & MNT_NOEXEC) ++ || !(h_inode->i_mode & S_IXUGO)))) ++ goto out; ++ ++ /* ++ * - skip the lower fs test in the case of write to ro branch. ++ * - nfs dir permission write check is optimized, but a policy for ++ * link/rename requires a real check. ++ */ ++ if ((write_mask && !au_br_writable(brperm)) ++ || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) ++ && write_mask && !(mask & MAY_READ)) ++ || !h_inode->i_op->permission) { ++ /* AuLabel(generic_permission); */ ++ err = generic_permission(h_inode, mask); ++ } else { ++ /* AuLabel(h_inode->permission); */ ++ err = h_inode->i_op->permission(h_inode, mask); ++ AuTraceErr(err); ++ } ++ ++ if (!err) ++ err = devcgroup_inode_permission(h_inode, mask); ++ if (!err) ++ err = security_inode_permission(h_inode, mask); ++ ++#if 0 ++ if (!err) { ++ /* todo: do we need to call ima_path_check()? */ ++ struct path h_path = { ++ .dentry = ++ .mnt = h_mnt ++ }; ++ err = ima_path_check(&h_path, ++ mask & (MAY_READ | MAY_WRITE | MAY_EXEC), ++ IMA_COUNT_LEAVE); ++ } ++#endif ++ ++out: ++ return err; ++} ++ ++static int aufs_permission(struct inode *inode, int mask) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ const unsigned char isdir = !!S_ISDIR(inode->i_mode), ++ write_mask = !!(mask & (MAY_WRITE | MAY_APPEND)); ++ struct inode *h_inode; ++ struct super_block *sb; ++ struct au_branch *br; ++ ++ /* todo: support rcu-walk? */ ++ if (mask & MAY_NOT_BLOCK) ++ return -ECHILD; ++ ++ sb = inode->i_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ii_read_lock_child(inode); ++#if 0 ++ err = au_iigen_test(inode, au_sigen(sb)); ++ if (unlikely(err)) ++ goto out; ++#endif ++ ++ if (!isdir ++ || write_mask ++ || au_opt_test(au_mntflags(sb), DIRPERM1)) { ++ err = au_busy_or_stale(); ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ if (unlikely(!h_inode ++ || (h_inode->i_mode & S_IFMT) ++ != (inode->i_mode & S_IFMT))) ++ goto out; ++ ++ err = 0; ++ bindex = au_ibstart(inode); ++ br = au_sbr(sb, bindex); ++ err = h_permission(h_inode, mask, au_br_mnt(br), br->br_perm); ++ if (write_mask ++ && !err ++ && !special_file(h_inode->i_mode)) { ++ /* test whether the upper writable branch exists */ ++ err = -EROFS; ++ for (; bindex >= 0; bindex--) ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = 0; ++ break; ++ } ++ } ++ goto out; ++ } ++ ++ /* non-write to dir */ ++ err = 0; ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (h_inode) { ++ err = au_busy_or_stale(); ++ if (unlikely(!S_ISDIR(h_inode->i_mode))) ++ break; ++ ++ br = au_sbr(sb, bindex); ++ err = h_permission(h_inode, mask, au_br_mnt(br), ++ br->br_perm); ++ } ++ } ++ ++out: ++ ii_read_unlock(inode); ++ si_read_unlock(sb); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, ++ unsigned int flags) ++{ ++ struct dentry *ret, *parent; ++ struct inode *inode; ++ struct super_block *sb; ++ int err, npositive; ++ ++ IMustLock(dir); ++ ++ /* todo: support rcu-walk? */ ++ ret = ERR_PTR(-ECHILD); ++ if (flags & LOOKUP_RCU) ++ goto out; ++ ++ ret = ERR_PTR(-ENAMETOOLONG); ++ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) ++ goto out; ++ ++ sb = dir->i_sb; ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ ret = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_di_init(dentry); ++ ret = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_si; ++ ++ inode = NULL; ++ npositive = 0; /* suppress a warning */ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_read_lock_parent(parent, AuLock_IR); ++ err = au_alive_dir(parent); ++ if (!err) ++ err = au_digen_test(parent, au_sigen(sb)); ++ if (!err) { ++ npositive = au_lkup_dentry(dentry, au_dbstart(parent), ++ /*type*/0); ++ err = npositive; ++ } ++ di_read_unlock(parent, AuLock_IR); ++ ret = ERR_PTR(err); ++ if (unlikely(err < 0)) ++ goto out_unlock; ++ ++ if (npositive) { ++ inode = au_new_inode(dentry, /*must_new*/0); ++ if (IS_ERR(inode)) { ++ ret = (void *)inode; ++ inode = NULL; ++ goto out_unlock; ++ } ++ } ++ ++ if (inode) ++ atomic_inc(&inode->i_count); ++ ret = d_splice_alias(inode, dentry); ++#if 0 ++ if (unlikely(d_need_lookup(dentry))) { ++ spin_lock(&dentry->d_lock); ++ dentry->d_flags &= ~DCACHE_NEED_LOOKUP; ++ spin_unlock(&dentry->d_lock); ++ } else ++#endif ++ if (inode) { ++ if (!IS_ERR(ret)) { ++ iput(inode); ++ if (ret && ret != dentry) ++ ii_write_unlock(inode); ++ } else { ++ ii_write_unlock(inode); ++ iput(inode); ++ inode = NULL; ++ } ++ } ++ ++out_unlock: ++ di_write_unlock(dentry); ++ if (inode) { ++ /* verbose coding for lock class name */ ++ if (unlikely(S_ISLNK(inode->i_mode))) ++ au_rw_class(&au_di(dentry)->di_rwsem, ++ au_lc_key + AuLcSymlink_DIINFO); ++ else if (unlikely(S_ISDIR(inode->i_mode))) ++ au_rw_class(&au_di(dentry)->di_rwsem, ++ au_lc_key + AuLcDir_DIINFO); ++ else /* likely */ ++ au_rw_class(&au_di(dentry)->di_rwsem, ++ au_lc_key + AuLcNonDir_DIINFO); ++ } ++out_si: ++ si_read_unlock(sb); ++out: ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_wr_dir_cpup(struct dentry *dentry, struct dentry *parent, ++ const unsigned char add_entry, aufs_bindex_t bcpup, ++ aufs_bindex_t bstart) ++{ ++ int err; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ ++ if (add_entry) ++ IMustLock(parent->d_inode); ++ else ++ di_write_lock_parent(parent); ++ ++ err = 0; ++ if (!au_h_dptr(parent, bcpup)) { ++ if (bstart > bcpup) ++ err = au_cpup_dirs(dentry, bcpup); ++ else if (bstart < bcpup) ++ err = au_cpdown_dirs(dentry, bcpup); ++ else ++ BUG(); ++ } ++ if (!err && add_entry && !au_ftest_wrdir(add_entry, TMPFILE)) { ++ h_parent = au_h_dptr(parent, bcpup); ++ h_dir = h_parent->d_inode; ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ err = au_lkup_neg(dentry, bcpup, ++ au_ftest_wrdir(add_entry, TMP_WHENTRY)); ++ /* todo: no unlock here */ ++ mutex_unlock(&h_dir->i_mutex); ++ ++ AuDbg("bcpup %d\n", bcpup); ++ if (!err) { ++ if (!dentry->d_inode) ++ au_set_h_dptr(dentry, bstart, NULL); ++ au_update_dbrange(dentry, /*do_put_zero*/0); ++ } ++ } ++ ++ if (!add_entry) ++ di_write_unlock(parent); ++ if (!err) ++ err = bcpup; /* success */ ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ++ * decide the branch and the parent dir where we will create a new entry. ++ * returns new bindex or an error. ++ * copyup the parent dir if needed. ++ */ ++int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, ++ struct au_wr_dir_args *args) ++{ ++ int err; ++ unsigned int flags; ++ aufs_bindex_t bcpup, bstart, src_bstart; ++ const unsigned char add_entry ++ = au_ftest_wrdir(args->flags, ADD_ENTRY) ++ | au_ftest_wrdir(args->flags, TMP_WHENTRY) ++ | au_ftest_wrdir(args->flags, TMPFILE); ++ struct super_block *sb; ++ struct dentry *parent; ++ struct au_sbinfo *sbinfo; ++ ++ sb = dentry->d_sb; ++ sbinfo = au_sbi(sb); ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(dentry); ++ bcpup = bstart; ++ if (args->force_btgt < 0) { ++ if (src_dentry) { ++ src_bstart = au_dbstart(src_dentry); ++ if (src_bstart < bstart) ++ bcpup = src_bstart; ++ } else if (add_entry) { ++ flags = 0; ++ if (au_ftest_wrdir(args->flags, ISDIR)) ++ au_fset_wbr(flags, DIR); ++ err = AuWbrCreate(sbinfo, dentry, flags); ++ bcpup = err; ++ } ++ ++ if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) { ++ if (add_entry) ++ err = AuWbrCopyup(sbinfo, dentry); ++ else { ++ if (!IS_ROOT(dentry)) { ++ di_read_lock_parent(parent, !AuLock_IR); ++ err = AuWbrCopyup(sbinfo, dentry); ++ di_read_unlock(parent, !AuLock_IR); ++ } else ++ err = AuWbrCopyup(sbinfo, dentry); ++ } ++ bcpup = err; ++ if (unlikely(err < 0)) ++ goto out; ++ } ++ } else { ++ bcpup = args->force_btgt; ++ AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode)); ++ } ++ ++ AuDbg("bstart %d, bcpup %d\n", bstart, bcpup); ++ err = bcpup; ++ if (bcpup == bstart) ++ goto out; /* success */ ++ ++ /* copyup the new parent into the branch we process */ ++ err = au_wr_dir_cpup(dentry, parent, add_entry, bcpup, bstart); ++ if (err >= 0) { ++ if (!dentry->d_inode) { ++ au_set_h_dptr(dentry, bstart, NULL); ++ au_set_dbstart(dentry, bcpup); ++ au_set_dbend(dentry, bcpup); ++ } ++ AuDebugOn(add_entry ++ && !au_ftest_wrdir(args->flags, TMPFILE) ++ && !au_h_dptr(dentry, bcpup)); ++ } ++ ++out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_pin_hdir_unlock(struct au_pin *p) ++{ ++ if (p->hdir) ++ au_hn_imtx_unlock(p->hdir); ++} ++ ++int au_pin_hdir_lock(struct au_pin *p) ++{ ++ int err; ++ ++ err = 0; ++ if (!p->hdir) ++ goto out; ++ ++ /* even if an error happens later, keep this lock */ ++ au_hn_imtx_lock_nested(p->hdir, p->lsc_hi); ++ ++ err = -EBUSY; ++ if (unlikely(p->hdir->hi_inode != p->h_parent->d_inode)) ++ goto out; ++ ++ err = 0; ++ if (p->h_dentry) ++ err = au_h_verify(p->h_dentry, p->udba, p->hdir->hi_inode, ++ p->h_parent, p->br); ++ ++out: ++ return err; ++} ++ ++int au_pin_hdir_relock(struct au_pin *p) ++{ ++ int err, i; ++ struct inode *h_i; ++ struct dentry *h_d[] = { ++ p->h_dentry, ++ p->h_parent ++ }; ++ ++ err = au_pin_hdir_lock(p); ++ if (unlikely(err)) ++ goto out; ++ ++ for (i = 0; !err && i < sizeof(h_d)/sizeof(*h_d); i++) { ++ if (!h_d[i]) ++ continue; ++ h_i = h_d[i]->d_inode; ++ if (h_i) ++ err = !h_i->i_nlink; ++ } ++ ++out: ++ return err; ++} ++ ++void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task) ++{ ++#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP) ++ p->hdir->hi_inode->i_mutex.owner = task; ++#endif ++} ++ ++void au_pin_hdir_acquire_nest(struct au_pin *p) ++{ ++ if (p->hdir) { ++ mutex_acquire_nest(&p->hdir->hi_inode->i_mutex.dep_map, ++ p->lsc_hi, 0, NULL, _RET_IP_); ++ au_pin_hdir_set_owner(p, current); ++ } ++} ++ ++void au_pin_hdir_release(struct au_pin *p) ++{ ++ if (p->hdir) { ++ au_pin_hdir_set_owner(p, p->task); ++ mutex_release(&p->hdir->hi_inode->i_mutex.dep_map, 1, _RET_IP_); ++ } ++} ++ ++struct dentry *au_pinned_h_parent(struct au_pin *pin) ++{ ++ if (pin && pin->parent) ++ return au_h_dptr(pin->parent, pin->bindex); ++ return NULL; ++} ++ ++void au_unpin(struct au_pin *p) ++{ ++ if (p->hdir) ++ au_pin_hdir_unlock(p); ++ if (p->h_mnt && au_ftest_pin(p->flags, MNT_WRITE)) ++ vfsub_mnt_drop_write(p->h_mnt); ++ if (!p->hdir) ++ return; ++ ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_unlock(p->parent, AuLock_IR); ++ iput(p->hdir->hi_inode); ++ dput(p->parent); ++ p->parent = NULL; ++ p->hdir = NULL; ++ p->h_mnt = NULL; ++ /* do not clear p->task */ ++} ++ ++int au_do_pin(struct au_pin *p) ++{ ++ int err; ++ struct super_block *sb; ++ struct inode *h_dir; ++ ++ err = 0; ++ sb = p->dentry->d_sb; ++ p->br = au_sbr(sb, p->bindex); ++ if (IS_ROOT(p->dentry)) { ++ if (au_ftest_pin(p->flags, MNT_WRITE)) { ++ p->h_mnt = au_br_mnt(p->br); ++ err = vfsub_mnt_want_write(p->h_mnt); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ goto out_err; ++ } ++ } ++ goto out; ++ } ++ ++ p->h_dentry = NULL; ++ if (p->bindex <= au_dbend(p->dentry)) ++ p->h_dentry = au_h_dptr(p->dentry, p->bindex); ++ ++ p->parent = dget_parent(p->dentry); ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_lock(p->parent, AuLock_IR, p->lsc_di); ++ ++ h_dir = NULL; ++ p->h_parent = au_h_dptr(p->parent, p->bindex); ++ p->hdir = au_hi(p->parent->d_inode, p->bindex); ++ if (p->hdir) ++ h_dir = p->hdir->hi_inode; ++ ++ /* ++ * udba case, or ++ * if DI_LOCKED is not set, then p->parent may be different ++ * and h_parent can be NULL. ++ */ ++ if (unlikely(!p->hdir || !h_dir || !p->h_parent)) { ++ err = -EBUSY; ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_unlock(p->parent, AuLock_IR); ++ dput(p->parent); ++ p->parent = NULL; ++ goto out_err; ++ } ++ ++ if (au_ftest_pin(p->flags, MNT_WRITE)) { ++ p->h_mnt = au_br_mnt(p->br); ++ err = vfsub_mnt_want_write(p->h_mnt); ++ if (unlikely(err)) { ++ au_fclr_pin(p->flags, MNT_WRITE); ++ if (!au_ftest_pin(p->flags, DI_LOCKED)) ++ di_read_unlock(p->parent, AuLock_IR); ++ dput(p->parent); ++ p->parent = NULL; ++ goto out_err; ++ } ++ } ++ ++ au_igrab(h_dir); ++ err = au_pin_hdir_lock(p); ++ if (!err) ++ goto out; /* success */ ++ ++ au_unpin(p); ++ ++out_err: ++ pr_err("err %d\n", err); ++ err = au_busy_or_stale(); ++out: ++ return err; ++} ++ ++void au_pin_init(struct au_pin *p, struct dentry *dentry, ++ aufs_bindex_t bindex, int lsc_di, int lsc_hi, ++ unsigned int udba, unsigned char flags) ++{ ++ p->dentry = dentry; ++ p->udba = udba; ++ p->lsc_di = lsc_di; ++ p->lsc_hi = lsc_hi; ++ p->flags = flags; ++ p->bindex = bindex; ++ ++ p->parent = NULL; ++ p->hdir = NULL; ++ p->h_mnt = NULL; ++ ++ p->h_dentry = NULL; ++ p->h_parent = NULL; ++ p->br = NULL; ++ p->task = current; ++} ++ ++int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int udba, unsigned char flags) ++{ ++ au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2, ++ udba, flags); ++ return au_do_pin(pin); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * ->setattr() and ->getattr() are called in various cases. ++ * chmod, stat: dentry is revalidated. ++ * fchmod, fstat: file and dentry are not revalidated, additionally they may be ++ * unhashed. ++ * for ->setattr(), ia->ia_file is passed from ftruncate only. ++ */ ++/* todo: consolidate with do_refresh() and simple_reval_dpath() */ ++int au_reval_for_attr(struct dentry *dentry, unsigned int sigen) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *parent; ++ ++ err = 0; ++ inode = dentry->d_inode; ++ if (au_digen_test(dentry, sigen)) { ++ parent = dget_parent(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ err = au_refresh_dentry(dentry, parent); ++ di_read_unlock(parent, AuLock_IR); ++ dput(parent); ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, ++ struct au_icpup_args *a) ++{ ++ int err; ++ loff_t sz; ++ aufs_bindex_t bstart, ibstart; ++ struct dentry *hi_wh, *parent; ++ struct inode *inode; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = 0 ++ }; ++ ++ bstart = au_dbstart(dentry); ++ inode = dentry->d_inode; ++ if (S_ISDIR(inode->i_mode)) ++ au_fset_wrdir(wr_dir_args.flags, ISDIR); ++ /* plink or hi_wh() case */ ++ ibstart = au_ibstart(inode); ++ if (bstart != ibstart && !au_test_ro(inode->i_sb, ibstart, inode)) ++ wr_dir_args.force_btgt = ibstart; ++ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); ++ if (unlikely(err < 0)) ++ goto out; ++ a->btgt = err; ++ if (err != bstart) ++ au_fset_icpup(a->flags, DID_CPUP); ++ ++ err = 0; ++ a->pin_flags = AuPin_MNT_WRITE; ++ parent = NULL; ++ if (!IS_ROOT(dentry)) { ++ au_fset_pin(a->pin_flags, DI_LOCKED); ++ parent = dget_parent(dentry); ++ di_write_lock_parent(parent); ++ } ++ ++ err = au_pin(&a->pin, dentry, a->btgt, a->udba, a->pin_flags); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ a->h_path.dentry = au_h_dptr(dentry, bstart); ++ a->h_inode = a->h_path.dentry->d_inode; ++ sz = -1; ++ if (ia && (ia->ia_valid & ATTR_SIZE)) { ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ if (ia->ia_size < i_size_read(a->h_inode)) ++ sz = ia->ia_size; ++ mutex_unlock(&a->h_inode->i_mutex); ++ } ++ ++ hi_wh = NULL; ++ if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) { ++ hi_wh = au_hi_wh(inode, a->btgt); ++ if (!hi_wh) { ++ struct au_cp_generic cpg = { ++ .dentry = dentry, ++ .bdst = a->btgt, ++ .bsrc = -1, ++ .len = sz, ++ .pin = &a->pin ++ }; ++ err = au_sio_cpup_wh(&cpg, /*file*/NULL); ++ if (unlikely(err)) ++ goto out_unlock; ++ hi_wh = au_hi_wh(inode, a->btgt); ++ /* todo: revalidate hi_wh? */ ++ } ++ } ++ ++ if (parent) { ++ au_pin_set_parent_lflag(&a->pin, /*lflag*/0); ++ di_downgrade_lock(parent, AuLock_IR); ++ dput(parent); ++ parent = NULL; ++ } ++ if (!au_ftest_icpup(a->flags, DID_CPUP)) ++ goto out; /* success */ ++ ++ if (!d_unhashed(dentry)) { ++ struct au_cp_generic cpg = { ++ .dentry = dentry, ++ .bdst = a->btgt, ++ .bsrc = bstart, ++ .len = sz, ++ .pin = &a->pin, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN ++ }; ++ err = au_sio_cpup_simple(&cpg); ++ if (!err) ++ a->h_path.dentry = au_h_dptr(dentry, a->btgt); ++ } else if (!hi_wh) ++ a->h_path.dentry = au_h_dptr(dentry, a->btgt); ++ else ++ a->h_path.dentry = hi_wh; /* do not dget here */ ++ ++out_unlock: ++ a->h_inode = a->h_path.dentry->d_inode; ++ if (!err) ++ goto out; /* success */ ++ au_unpin(&a->pin); ++out_parent: ++ if (parent) { ++ di_write_unlock(parent); ++ dput(parent); ++ } ++out: ++ if (!err) ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ return err; ++} ++ ++static int aufs_setattr(struct dentry *dentry, struct iattr *ia) ++{ ++ int err; ++ struct inode *inode, *delegated; ++ struct super_block *sb; ++ struct file *file; ++ struct au_icpup_args *a; ++ ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) ++ ia->ia_valid &= ~ATTR_MODE; ++ ++ file = NULL; ++ sb = dentry->d_sb; ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (unlikely(err)) ++ goto out_kfree; ++ ++ if (ia->ia_valid & ATTR_FILE) { ++ /* currently ftruncate(2) only */ ++ AuDebugOn(!S_ISREG(inode->i_mode)); ++ file = ia->ia_file; ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1); ++ if (unlikely(err)) ++ goto out_si; ++ ia->ia_file = au_hf_top(file); ++ a->udba = AuOpt_UDBA_NONE; ++ } else { ++ /* fchmod() doesn't pass ia_file */ ++ a->udba = au_opt_udba(sb); ++ di_write_lock_child(dentry); ++ /* no d_unlinked(), to set UDBA_NONE for root */ ++ if (d_unhashed(dentry)) ++ a->udba = AuOpt_UDBA_NONE; ++ if (a->udba != AuOpt_UDBA_NONE) { ++ AuDebugOn(IS_ROOT(dentry)); ++ err = au_reval_for_attr(dentry, au_sigen(sb)); ++ if (unlikely(err)) ++ goto out_dentry; ++ } ++ } ++ ++ err = au_pin_and_icpup(dentry, ia, a); ++ if (unlikely(err < 0)) ++ goto out_dentry; ++ if (au_ftest_icpup(a->flags, DID_CPUP)) { ++ ia->ia_file = NULL; ++ ia->ia_valid &= ~ATTR_FILE; ++ } ++ ++ a->h_path.mnt = au_sbr_mnt(sb, a->btgt); ++ if ((ia->ia_valid & (ATTR_MODE | ATTR_CTIME)) ++ == (ATTR_MODE | ATTR_CTIME)) { ++ err = security_path_chmod(&a->h_path, ia->ia_mode); ++ if (unlikely(err)) ++ goto out_unlock; ++ } else if ((ia->ia_valid & (ATTR_UID | ATTR_GID)) ++ && (ia->ia_valid & ATTR_CTIME)) { ++ err = security_path_chown(&a->h_path, ia->ia_uid, ia->ia_gid); ++ if (unlikely(err)) ++ goto out_unlock; ++ } ++ ++ if (ia->ia_valid & ATTR_SIZE) { ++ struct file *f; ++ ++ if (ia->ia_size < i_size_read(inode)) ++ /* unmap only */ ++ truncate_setsize(inode, ia->ia_size); ++ ++ f = NULL; ++ if (ia->ia_valid & ATTR_FILE) ++ f = ia->ia_file; ++ mutex_unlock(&a->h_inode->i_mutex); ++ err = vfsub_trunc(&a->h_path, ia->ia_size, ia->ia_valid, f); ++ mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); ++ } else { ++ delegated = NULL; ++ while (1) { ++ err = vfsub_notify_change(&a->h_path, ia, &delegated); ++ if (delegated) { ++ err = break_deleg_wait(&delegated); ++ if (!err) ++ continue; ++ } ++ break; ++ } ++ } ++ if (!err) ++ au_cpup_attr_changeable(inode); ++ ++out_unlock: ++ mutex_unlock(&a->h_inode->i_mutex); ++ au_unpin(&a->pin); ++ if (unlikely(err)) ++ au_update_dbstart(dentry); ++out_dentry: ++ di_write_unlock(dentry); ++ if (file) { ++ fi_write_unlock(file); ++ ia->ia_file = file; ++ ia->ia_valid |= ATTR_FILE; ++ } ++out_si: ++ si_read_unlock(sb); ++out_kfree: ++ kfree(a); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) ++static int au_h_path_to_set_attr(struct dentry *dentry, ++ struct au_icpup_args *a, struct path *h_path) ++{ ++ int err; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ a->udba = au_opt_udba(sb); ++ /* no d_unlinked(), to set UDBA_NONE for root */ ++ if (d_unhashed(dentry)) ++ a->udba = AuOpt_UDBA_NONE; ++ if (a->udba != AuOpt_UDBA_NONE) { ++ AuDebugOn(IS_ROOT(dentry)); ++ err = au_reval_for_attr(dentry, au_sigen(sb)); ++ if (unlikely(err)) ++ goto out; ++ } ++ err = au_pin_and_icpup(dentry, /*ia*/NULL, a); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ h_path->dentry = a->h_path.dentry; ++ h_path->mnt = au_sbr_mnt(sb, a->btgt); ++ ++out: ++ return err; ++} ++ ++ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg) ++{ ++ int err; ++ struct path h_path; ++ struct super_block *sb; ++ struct au_icpup_args *a; ++ struct inode *inode, *h_inode; ++ ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (unlikely(err)) ++ goto out_kfree; ++ ++ h_path.dentry = NULL; /* silence gcc */ ++ di_write_lock_child(dentry); ++ err = au_h_path_to_set_attr(dentry, a, &h_path); ++ if (unlikely(err)) ++ goto out_di; ++ ++ mutex_unlock(&a->h_inode->i_mutex); ++ switch (arg->type) { ++ case AU_XATTR_SET: ++ err = vfsub_setxattr(h_path.dentry, ++ arg->u.set.name, arg->u.set.value, ++ arg->u.set.size, arg->u.set.flags); ++ break; ++ case AU_XATTR_REMOVE: ++ err = vfsub_removexattr(h_path.dentry, arg->u.remove.name); ++ break; ++ case AU_ACL_SET: ++ err = -EOPNOTSUPP; ++ h_inode = h_path.dentry->d_inode; ++ if (h_inode->i_op->set_acl) ++ err = h_inode->i_op->set_acl(h_inode, ++ arg->u.acl_set.acl, ++ arg->u.acl_set.type); ++ break; ++ } ++ if (!err) ++ au_cpup_attr_timesizes(inode); ++ ++ au_unpin(&a->pin); ++ if (unlikely(err)) ++ au_update_dbstart(dentry); ++ ++out_di: ++ di_write_unlock(dentry); ++ si_read_unlock(sb); ++out_kfree: ++ kfree(a); ++out: ++ AuTraceErr(err); ++ return err; ++} ++#endif ++ ++static void au_refresh_iattr(struct inode *inode, struct kstat *st, ++ unsigned int nlink) ++{ ++ unsigned int n; ++ ++ inode->i_mode = st->mode; ++ /* don't i_[ug]id_write() here */ ++ inode->i_uid = st->uid; ++ inode->i_gid = st->gid; ++ inode->i_atime = st->atime; ++ inode->i_mtime = st->mtime; ++ inode->i_ctime = st->ctime; ++ ++ au_cpup_attr_nlink(inode, /*force*/0); ++ if (S_ISDIR(inode->i_mode)) { ++ n = inode->i_nlink; ++ n -= nlink; ++ n += st->nlink; ++ smp_mb(); /* for i_nlink */ ++ /* 0 can happen */ ++ set_nlink(inode, n); ++ } ++ ++ spin_lock(&inode->i_lock); ++ inode->i_blocks = st->blocks; ++ i_size_write(inode, st->size); ++ spin_unlock(&inode->i_lock); ++} ++ ++/* ++ * common routine for aufs_getattr() and aufs_getxattr(). ++ * returns zero or negative (an error). ++ * @dentry will be read-locked in success. ++ */ ++int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path) ++{ ++ int err; ++ unsigned int mnt_flags, sigen; ++ unsigned char udba_none; ++ aufs_bindex_t bindex; ++ struct super_block *sb, *h_sb; ++ struct inode *inode; ++ ++ h_path->mnt = NULL; ++ h_path->dentry = NULL; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ mnt_flags = au_mntflags(sb); ++ udba_none = !!au_opt_test(mnt_flags, UDBA_NONE); ++ ++ /* support fstat(2) */ ++ if (!d_unlinked(dentry) && !udba_none) { ++ sigen = au_sigen(sb); ++ err = au_digen_test(dentry, sigen); ++ if (!err) { ++ di_read_lock_child(dentry, AuLock_IR); ++ err = au_dbrange_test(dentry); ++ if (unlikely(err)) { ++ di_read_unlock(dentry, AuLock_IR); ++ goto out; ++ } ++ } else { ++ AuDebugOn(IS_ROOT(dentry)); ++ di_write_lock_child(dentry); ++ err = au_dbrange_test(dentry); ++ if (!err) ++ err = au_reval_for_attr(dentry, sigen); ++ if (!err) ++ di_downgrade_lock(dentry, AuLock_IR); ++ else { ++ di_write_unlock(dentry); ++ goto out; ++ } ++ } ++ } else ++ di_read_lock_child(dentry, AuLock_IR); ++ ++ inode = dentry->d_inode; ++ bindex = au_ibstart(inode); ++ h_path->mnt = au_sbr_mnt(sb, bindex); ++ h_sb = h_path->mnt->mnt_sb; ++ if (!force ++ && !au_test_fs_bad_iattr(h_sb) ++ && udba_none) ++ goto out; /* success */ ++ ++ if (au_dbstart(dentry) == bindex) ++ h_path->dentry = au_h_dptr(dentry, bindex); ++ else if (au_opt_test(mnt_flags, PLINK) && au_plink_test(inode)) { ++ h_path->dentry = au_plink_lkup(inode, bindex); ++ if (IS_ERR(h_path->dentry)) ++ /* pretending success */ ++ h_path->dentry = NULL; ++ else ++ dput(h_path->dentry); ++ } ++ ++out: ++ return err; ++} ++ ++static int aufs_getattr(struct vfsmount *mnt __maybe_unused, ++ struct dentry *dentry, struct kstat *st) ++{ ++ int err; ++ unsigned char positive; ++ struct path h_path; ++ struct inode *inode; ++ struct super_block *sb; ++ ++ inode = dentry->d_inode; ++ sb = dentry->d_sb; ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (unlikely(err)) ++ goto out; ++ err = au_h_path_getattr(dentry, /*force*/0, &h_path); ++ if (unlikely(err)) ++ goto out_si; ++ if (unlikely(!h_path.dentry)) ++ /* illegally overlapped or something */ ++ goto out_fill; /* pretending success */ ++ ++ positive = !!h_path.dentry->d_inode; ++ if (positive) ++ err = vfs_getattr(&h_path, st); ++ if (!err) { ++ if (positive) ++ au_refresh_iattr(inode, st, ++ h_path.dentry->d_inode->i_nlink); ++ goto out_fill; /* success */ ++ } ++ AuTraceErr(err); ++ goto out_di; ++ ++out_fill: ++ generic_fillattr(inode, st); ++out_di: ++ di_read_unlock(dentry, AuLock_IR); ++out_si: ++ si_read_unlock(sb); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int h_readlink(struct dentry *dentry, int bindex, char __user *buf, ++ int bufsiz) ++{ ++ int err; ++ struct super_block *sb; ++ struct dentry *h_dentry; ++ ++ err = -EINVAL; ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (unlikely(!h_dentry->d_inode->i_op->readlink)) ++ goto out; ++ ++ err = security_inode_readlink(h_dentry); ++ if (unlikely(err)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ if (!au_test_ro(sb, bindex, dentry->d_inode)) { ++ vfsub_touch_atime(au_sbr_mnt(sb, bindex), h_dentry); ++ fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode); ++ } ++ err = h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz); ++ ++out: ++ return err; ++} ++ ++static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) ++{ ++ int err; ++ ++ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN); ++ if (unlikely(err)) ++ goto out; ++ err = au_d_hashed_positive(dentry); ++ if (!err) ++ err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz); ++ aufs_read_unlock(dentry, AuLock_IR); ++ ++out: ++ return err; ++} ++ ++static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd) ++{ ++ int err; ++ mm_segment_t old_fs; ++ union { ++ char *k; ++ char __user *u; ++ } buf; ++ ++ err = -ENOMEM; ++ buf.k = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!buf.k)) ++ goto out; ++ ++ err = aufs_read_lock(dentry, AuLock_IR | AuLock_GEN); ++ if (unlikely(err)) ++ goto out_name; ++ ++ err = au_d_hashed_positive(dentry); ++ if (!err) { ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = h_readlink(dentry, au_dbstart(dentry), buf.u, PATH_MAX); ++ set_fs(old_fs); ++ } ++ aufs_read_unlock(dentry, AuLock_IR); ++ ++ if (err >= 0) { ++ buf.k[err] = 0; ++ /* will be freed by put_link */ ++ nd_set_link(nd, buf.k); ++ return NULL; /* success */ ++ } ++ ++out_name: ++ free_page((unsigned long)buf.k); ++out: ++ AuTraceErr(err); ++ return ERR_PTR(err); ++} ++ ++static void aufs_put_link(struct dentry *dentry __maybe_unused, ++ struct nameidata *nd, void *cookie __maybe_unused) ++{ ++ char *p; ++ ++ p = nd_get_link(nd); ++ if (!IS_ERR_OR_NULL(p)) ++ free_page((unsigned long)p); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_update_time(struct inode *inode, struct timespec *ts, int flags) ++{ ++ int err; ++ struct super_block *sb; ++ struct inode *h_inode; ++ ++ sb = inode->i_sb; ++ /* mmap_sem might be acquired already, cf. aufs_mmap() */ ++ lockdep_off(); ++ si_read_lock(sb, AuLock_FLUSH); ++ ii_write_lock_child(inode); ++ lockdep_on(); ++ h_inode = au_h_iptr(inode, au_ibstart(inode)); ++ err = vfsub_update_time(h_inode, ts, flags); ++ lockdep_off(); ++ if (!err) ++ au_cpup_attr_timesizes(inode); ++ ii_write_unlock(inode); ++ si_read_unlock(sb); ++ lockdep_on(); ++ ++ if (!err && (flags & S_VERSION)) ++ inode_inc_iversion(inode); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct inode_operations aufs_symlink_iop = { ++ .permission = aufs_permission, ++#ifdef CONFIG_FS_POSIX_ACL ++ .get_acl = aufs_get_acl, ++ .set_acl = aufs_set_acl, /* unsupport for symlink? */ ++#endif ++ ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr, ++ ++#ifdef CONFIG_AUFS_XATTR ++ .setxattr = aufs_setxattr, ++ .getxattr = aufs_getxattr, ++ .listxattr = aufs_listxattr, ++ .removexattr = aufs_removexattr, ++#endif ++ ++ .readlink = aufs_readlink, ++ .follow_link = aufs_follow_link, ++ .put_link = aufs_put_link, ++ ++ /* .update_time = aufs_update_time */ ++}; ++ ++struct inode_operations aufs_dir_iop = { ++ .create = aufs_create, ++ .lookup = aufs_lookup, ++ .link = aufs_link, ++ .unlink = aufs_unlink, ++ .symlink = aufs_symlink, ++ .mkdir = aufs_mkdir, ++ .rmdir = aufs_rmdir, ++ .mknod = aufs_mknod, ++ .rename = aufs_rename, ++ ++ .permission = aufs_permission, ++#ifdef CONFIG_FS_POSIX_ACL ++ .get_acl = aufs_get_acl, ++ .set_acl = aufs_set_acl, ++#endif ++ ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr, ++ ++#ifdef CONFIG_AUFS_XATTR ++ .setxattr = aufs_setxattr, ++ .getxattr = aufs_getxattr, ++ .listxattr = aufs_listxattr, ++ .removexattr = aufs_removexattr, ++#endif ++ ++ .update_time = aufs_update_time, ++ /* no support for atomic_open() */ ++ ++ .tmpfile = aufs_tmpfile ++}; ++ ++struct inode_operations aufs_iop = { ++ .permission = aufs_permission, ++#ifdef CONFIG_FS_POSIX_ACL ++ .get_acl = aufs_get_acl, ++ .set_acl = aufs_set_acl, ++#endif ++ ++ .setattr = aufs_setattr, ++ .getattr = aufs_getattr, ++ ++#ifdef CONFIG_AUFS_XATTR ++ .setxattr = aufs_setxattr, ++ .getxattr = aufs_getxattr, ++ .listxattr = aufs_listxattr, ++ .removexattr = aufs_removexattr, ++#endif ++ ++ .update_time = aufs_update_time ++}; +diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c +new file mode 100644 +index 0000000..a76e11d6 +--- /dev/null ++++ b/fs/aufs/i_op_add.c +@@ -0,0 +1,878 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode operations (add entry) ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * final procedure of adding a new entry, except link(2). ++ * remove whiteout, instantiate, copyup the parent dir's times and size ++ * and update version. ++ * if it failed, re-create the removed whiteout. ++ */ ++static int epilog(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct dentry *dentry) ++{ ++ int err, rerr; ++ aufs_bindex_t bwh; ++ struct path h_path; ++ struct super_block *sb; ++ struct inode *inode, *h_dir; ++ struct dentry *wh; ++ ++ bwh = -1; ++ sb = dir->i_sb; ++ if (wh_dentry) { ++ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(h_dir); ++ AuDebugOn(au_h_iptr(dir, bindex) != h_dir); ++ bwh = au_dbwh(dentry); ++ h_path.dentry = wh_dentry; ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ err = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ inode = au_new_inode(dentry, /*must_new*/1); ++ if (!IS_ERR(inode)) { ++ d_instantiate(dentry, inode); ++ dir = dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(dir); ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ dir->i_version++; ++ au_fhsm_wrote(sb, bindex, /*force*/0); ++ return 0; /* success */ ++ } ++ ++ err = PTR_ERR(inode); ++ if (!wh_dentry) ++ goto out; ++ ++ /* revert */ ++ /* dir inode is locked */ ++ wh = au_wh_create(dentry, bwh, wh_dentry->d_parent); ++ rerr = PTR_ERR(wh); ++ if (IS_ERR(wh)) { ++ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", ++ dentry, err, rerr); ++ err = -EIO; ++ } else ++ dput(wh); ++ ++out: ++ return err; ++} ++ ++static int au_d_may_add(struct dentry *dentry) ++{ ++ int err; ++ ++ err = 0; ++ if (unlikely(d_unhashed(dentry))) ++ err = -ENOENT; ++ if (unlikely(dentry->d_inode)) ++ err = -EEXIST; ++ return err; ++} ++ ++/* ++ * simple tests for the adding inode operations. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir) ++{ ++ int err; ++ umode_t h_mode; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ ++ err = -ENAMETOOLONG; ++ if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) ++ goto out; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ h_inode = h_dentry->d_inode; ++ if (!dentry->d_inode) { ++ err = -EEXIST; ++ if (unlikely(h_inode)) ++ goto out; ++ } else { ++ /* rename(2) case */ ++ err = -EIO; ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ ++ h_mode = h_inode->i_mode; ++ if (!isdir) { ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(h_mode))) ++ goto out; ++ } else if (unlikely(!S_ISDIR(h_mode))) { ++ err = -ENOTDIR; ++ goto out; ++ } ++ } ++ ++ err = 0; ++ /* expected parent dir is locked */ ++ if (unlikely(h_parent != h_dentry->d_parent)) ++ err = -EIO; ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ++ * initial procedure of adding a new entry. ++ * prepare writable branch and the parent dir, lock it, ++ * and lookup whiteout for the new entry. ++ */ ++static struct dentry* ++lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, ++ struct dentry *src_dentry, struct au_pin *pin, ++ struct au_wr_dir_args *wr_dir_args) ++{ ++ struct dentry *wh_dentry, *h_parent; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ unsigned int udba; ++ aufs_bindex_t bcpup; ++ ++ AuDbg("%pd\n", dentry); ++ ++ err = au_wr_dir(dentry, src_dentry, wr_dir_args); ++ bcpup = err; ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ udba = au_opt_udba(sb); ++ err = au_pin(pin, dentry, bcpup, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ h_parent = au_pinned_h_parent(pin); ++ if (udba != AuOpt_UDBA_NONE ++ && au_dbstart(dentry) == bcpup) ++ err = au_may_add(dentry, bcpup, h_parent, ++ au_ftest_wrdir(wr_dir_args->flags, ISDIR)); ++ else if (unlikely(dentry->d_name.len > AUFS_MAX_NAMELEN)) ++ err = -ENAMETOOLONG; ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_unpin; ++ ++ br = au_sbr(sb, bcpup); ++ if (dt) { ++ struct path tmp = { ++ .dentry = h_parent, ++ .mnt = au_br_mnt(br) ++ }; ++ au_dtime_store(dt, au_pinned_parent(pin), &tmp); ++ } ++ ++ wh_dentry = NULL; ++ if (bcpup != au_dbwh(dentry)) ++ goto out; /* success */ ++ ++ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, br); ++ ++out_unpin: ++ if (IS_ERR(wh_dentry)) ++ au_unpin(pin); ++out: ++ return wh_dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { Mknod, Symlink, Creat }; ++struct simple_arg { ++ int type; ++ union { ++ struct { ++ umode_t mode; ++ bool want_excl; ++ } c; ++ struct { ++ const char *symname; ++ } s; ++ struct { ++ umode_t mode; ++ dev_t dev; ++ } m; ++ } u; ++}; ++ ++static int add_simple(struct inode *dir, struct dentry *dentry, ++ struct simple_arg *arg) ++{ ++ int err, rerr; ++ aufs_bindex_t bstart; ++ unsigned char created; ++ struct dentry *wh_dentry, *parent; ++ struct inode *h_dir; ++ /* to reuduce stack size */ ++ struct { ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ struct au_wr_dir_args wr_dir_args; ++ } *a; ++ ++ AuDbg("%pd\n", dentry); ++ IMustLock(dir); ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ a->wr_dir_args.force_btgt = -1; ++ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); ++ if (unlikely(err)) ++ goto out_free; ++ err = au_d_may_add(dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, ++ &a->pin, &a->wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_parent; ++ ++ bstart = au_dbstart(dentry); ++ a->h_path.dentry = au_h_dptr(dentry, bstart); ++ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ h_dir = au_pinned_h_dir(&a->pin); ++ switch (arg->type) { ++ case Creat: ++ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode, ++ arg->u.c.want_excl); ++ break; ++ case Symlink: ++ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname); ++ break; ++ case Mknod: ++ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode, ++ arg->u.m.dev); ++ break; ++ default: ++ BUG(); ++ } ++ created = !err; ++ if (!err) ++ err = epilog(dir, bstart, wh_dentry, dentry); ++ ++ /* revert */ ++ if (unlikely(created && err && a->h_path.dentry->d_inode)) { ++ /* no delegation since it is just created */ ++ rerr = vfsub_unlink(h_dir, &a->h_path, /*delegated*/NULL, ++ /*force*/0); ++ if (rerr) { ++ AuIOErr("%pd revert failure(%d, %d)\n", ++ dentry, err, rerr); ++ err = -EIO; ++ } ++ au_dtime_revert(&a->dt); ++ } ++ ++ au_unpin(&a->pin); ++ dput(wh_dentry); ++ ++out_parent: ++ di_write_unlock(parent); ++out_unlock: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ aufs_read_unlock(dentry, AuLock_DW); ++out_free: ++ kfree(a); ++out: ++ return err; ++} ++ ++int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, ++ dev_t dev) ++{ ++ struct simple_arg arg = { ++ .type = Mknod, ++ .u.m = { ++ .mode = mode, ++ .dev = dev ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) ++{ ++ struct simple_arg arg = { ++ .type = Symlink, ++ .u.s.symname = symname ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool want_excl) ++{ ++ struct simple_arg arg = { ++ .type = Creat, ++ .u.c = { ++ .mode = mode, ++ .want_excl = want_excl ++ } ++ }; ++ return add_simple(dir, dentry, &arg); ++} ++ ++int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent, *h_dentry; ++ struct inode *h_dir, *inode; ++ struct vfsmount *h_mnt; ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_TMPFILE ++ }; ++ ++ /* copy-up may happen */ ++ mutex_lock(&dir->i_mutex); ++ ++ sb = dir->i_sb; ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_di_init(dentry); ++ if (unlikely(err)) ++ goto out_si; ++ ++ err = -EBUSY; ++ parent = d_find_any_alias(dir); ++ AuDebugOn(!parent); ++ di_write_lock_parent(parent); ++ if (unlikely(parent->d_inode != dir)) ++ goto out_parent; ++ ++ err = au_digen_test(parent, au_sigen(sb)); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ bindex = au_dbstart(parent); ++ au_set_dbstart(dentry, bindex); ++ au_set_dbend(dentry, bindex); ++ err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); ++ bindex = err; ++ if (unlikely(err < 0)) ++ goto out_parent; ++ ++ err = -EOPNOTSUPP; ++ h_dir = au_h_iptr(dir, bindex); ++ if (unlikely(!h_dir->i_op->tmpfile)) ++ goto out_parent; ++ ++ h_mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_mnt_want_write(h_mnt); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ h_parent = au_h_dptr(parent, bindex); ++ err = inode_permission(h_parent->d_inode, MAY_WRITE | MAY_EXEC); ++ if (unlikely(err)) ++ goto out_mnt; ++ ++ err = -ENOMEM; ++ h_dentry = d_alloc(h_parent, &dentry->d_name); ++ if (unlikely(!h_dentry)) ++ goto out_mnt; ++ ++ err = h_dir->i_op->tmpfile(h_dir, h_dentry, mode); ++ if (unlikely(err)) ++ goto out_dentry; ++ ++ au_set_dbstart(dentry, bindex); ++ au_set_dbend(dentry, bindex); ++ au_set_h_dptr(dentry, bindex, dget(h_dentry)); ++ inode = au_new_inode(dentry, /*must_new*/1); ++ if (IS_ERR(inode)) { ++ err = PTR_ERR(inode); ++ au_set_h_dptr(dentry, bindex, NULL); ++ au_set_dbstart(dentry, -1); ++ au_set_dbend(dentry, -1); ++ } else { ++ if (!inode->i_nlink) ++ set_nlink(inode, 1); ++ d_tmpfile(dentry, inode); ++ au_di(dentry)->di_tmpfile = 1; ++ ++ /* update without i_mutex */ ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ } ++ ++out_dentry: ++ dput(h_dentry); ++out_mnt: ++ vfsub_mnt_drop_write(h_mnt); ++out_parent: ++ di_write_unlock(parent); ++ dput(parent); ++ di_write_unlock(dentry); ++ if (!err) ++#if 0 ++ /* verbose coding for lock class name */ ++ au_rw_class(&au_di(dentry)->di_rwsem, ++ au_lc_key + AuLcNonDir_DIINFO); ++#else ++ ; ++#endif ++ else { ++ au_di_fin(dentry); ++ dentry->d_fsdata = NULL; ++ } ++out_si: ++ si_read_unlock(sb); ++out: ++ mutex_unlock(&dir->i_mutex); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_link_args { ++ aufs_bindex_t bdst, bsrc; ++ struct au_pin pin; ++ struct path h_path; ++ struct dentry *src_parent, *parent; ++}; ++ ++static int au_cpup_before_link(struct dentry *src_dentry, ++ struct au_link_args *a) ++{ ++ int err; ++ struct dentry *h_src_dentry; ++ struct au_cp_generic cpg = { ++ .dentry = src_dentry, ++ .bdst = a->bdst, ++ .bsrc = a->bsrc, ++ .len = -1, ++ .pin = &a->pin, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */ ++ }; ++ ++ di_read_lock_parent(a->src_parent, AuLock_IR); ++ err = au_test_and_cpup_dirs(src_dentry, a->bdst); ++ if (unlikely(err)) ++ goto out; ++ ++ h_src_dentry = au_h_dptr(src_dentry, a->bsrc); ++ err = au_pin(&a->pin, src_dentry, a->bdst, ++ au_opt_udba(src_dentry->d_sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_sio_cpup_simple(&cpg); ++ au_unpin(&a->pin); ++ ++out: ++ di_read_unlock(a->src_parent, AuLock_IR); ++ return err; ++} ++ ++static int au_cpup_or_link(struct dentry *src_dentry, struct dentry *dentry, ++ struct au_link_args *a) ++{ ++ int err; ++ unsigned char plink; ++ aufs_bindex_t bend; ++ struct dentry *h_src_dentry; ++ struct inode *h_inode, *inode, *delegated; ++ struct super_block *sb; ++ struct file *h_file; ++ ++ plink = 0; ++ h_inode = NULL; ++ sb = src_dentry->d_sb; ++ inode = src_dentry->d_inode; ++ if (au_ibstart(inode) <= a->bdst) ++ h_inode = au_h_iptr(inode, a->bdst); ++ if (!h_inode || !h_inode->i_nlink) { ++ /* copyup src_dentry as the name of dentry. */ ++ bend = au_dbend(dentry); ++ if (bend < a->bsrc) ++ au_set_dbend(dentry, a->bsrc); ++ au_set_h_dptr(dentry, a->bsrc, ++ dget(au_h_dptr(src_dentry, a->bsrc))); ++ dget(a->h_path.dentry); ++ au_set_h_dptr(dentry, a->bdst, NULL); ++ AuDbg("temporary d_inode...\n"); ++ spin_lock(&dentry->d_lock); ++ dentry->d_inode = src_dentry->d_inode; /* tmp */ ++ spin_unlock(&dentry->d_lock); ++ h_file = au_h_open_pre(dentry, a->bsrc, /*force_wr*/0); ++ if (IS_ERR(h_file)) ++ err = PTR_ERR(h_file); ++ else { ++ struct au_cp_generic cpg = { ++ .dentry = dentry, ++ .bdst = a->bdst, ++ .bsrc = -1, ++ .len = -1, ++ .pin = &a->pin, ++ .flags = AuCpup_KEEPLINO ++ }; ++ err = au_sio_cpup_simple(&cpg); ++ au_h_open_post(dentry, a->bsrc, h_file); ++ if (!err) { ++ dput(a->h_path.dentry); ++ a->h_path.dentry = au_h_dptr(dentry, a->bdst); ++ } else ++ au_set_h_dptr(dentry, a->bdst, ++ a->h_path.dentry); ++ } ++ spin_lock(&dentry->d_lock); ++ dentry->d_inode = NULL; /* restore */ ++ spin_unlock(&dentry->d_lock); ++ AuDbg("temporary d_inode...done\n"); ++ au_set_h_dptr(dentry, a->bsrc, NULL); ++ au_set_dbend(dentry, bend); ++ } else { ++ /* the inode of src_dentry already exists on a.bdst branch */ ++ h_src_dentry = d_find_alias(h_inode); ++ if (!h_src_dentry && au_plink_test(inode)) { ++ plink = 1; ++ h_src_dentry = au_plink_lkup(inode, a->bdst); ++ err = PTR_ERR(h_src_dentry); ++ if (IS_ERR(h_src_dentry)) ++ goto out; ++ ++ if (unlikely(!h_src_dentry->d_inode)) { ++ dput(h_src_dentry); ++ h_src_dentry = NULL; ++ } ++ ++ } ++ if (h_src_dentry) { ++ delegated = NULL; ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path, &delegated); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal link\n"); ++ iput(delegated); ++ } ++ dput(h_src_dentry); ++ } else { ++ AuIOErr("no dentry found for hi%lu on b%d\n", ++ h_inode->i_ino, a->bdst); ++ err = -EIO; ++ } ++ } ++ ++ if (!err && !plink) ++ au_plink_append(inode, a->bdst, a->h_path.dentry); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry) ++{ ++ int err, rerr; ++ struct au_dtime dt; ++ struct au_link_args *a; ++ struct dentry *wh_dentry, *h_src_dentry; ++ struct inode *inode, *delegated; ++ struct super_block *sb; ++ struct au_wr_dir_args wr_dir_args = { ++ /* .force_btgt = -1, */ ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ IMustLock(dir); ++ inode = src_dentry->d_inode; ++ IMustLock(inode); ++ ++ err = -ENOMEM; ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ a->parent = dentry->d_parent; /* dir inode is locked */ ++ err = aufs_read_and_write_lock2(dentry, src_dentry, ++ AuLock_NOPLM | AuLock_GEN); ++ if (unlikely(err)) ++ goto out_kfree; ++ err = au_d_linkable(src_dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ err = au_d_may_add(dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ a->src_parent = dget_parent(src_dentry); ++ wr_dir_args.force_btgt = au_ibstart(inode); ++ ++ di_write_lock_parent(a->parent); ++ wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, ++ &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_parent; ++ ++ err = 0; ++ sb = dentry->d_sb; ++ a->bdst = au_dbstart(dentry); ++ a->h_path.dentry = au_h_dptr(dentry, a->bdst); ++ a->h_path.mnt = au_sbr_mnt(sb, a->bdst); ++ a->bsrc = au_ibstart(inode); ++ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); ++ if (!h_src_dentry && au_di(src_dentry)->di_tmpfile) ++ h_src_dentry = dget(au_hi_wh(inode, a->bsrc)); ++ if (!h_src_dentry) { ++ a->bsrc = au_dbstart(src_dentry); ++ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc); ++ AuDebugOn(!h_src_dentry); ++ } else if (IS_ERR(h_src_dentry)) { ++ err = PTR_ERR(h_src_dentry); ++ goto out_parent; ++ } ++ ++ if (au_opt_test(au_mntflags(sb), PLINK)) { ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) ++ err = au_cpup_or_link(src_dentry, dentry, a); ++ else { ++ delegated = NULL; ++ err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), ++ &a->h_path, &delegated); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal link\n"); ++ iput(delegated); ++ } ++ } ++ dput(h_src_dentry); ++ } else { ++ /* ++ * copyup src_dentry to the branch we process, ++ * and then link(2) to it. ++ */ ++ dput(h_src_dentry); ++ if (a->bdst < a->bsrc ++ /* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) { ++ au_unpin(&a->pin); ++ di_write_unlock(a->parent); ++ err = au_cpup_before_link(src_dentry, a); ++ di_write_lock_parent(a->parent); ++ if (!err) ++ err = au_pin(&a->pin, dentry, a->bdst, ++ au_opt_udba(sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (unlikely(err)) ++ goto out_wh; ++ } ++ if (!err) { ++ h_src_dentry = au_h_dptr(src_dentry, a->bdst); ++ err = -ENOENT; ++ if (h_src_dentry && h_src_dentry->d_inode) { ++ delegated = NULL; ++ err = vfsub_link(h_src_dentry, ++ au_pinned_h_dir(&a->pin), ++ &a->h_path, &delegated); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry" ++ " for NFSv4 delegation" ++ " for an internal link\n"); ++ iput(delegated); ++ } ++ } ++ } ++ } ++ if (unlikely(err)) ++ goto out_unpin; ++ ++ if (wh_dentry) { ++ a->h_path.dentry = wh_dentry; ++ err = au_wh_unlink_dentry(au_pinned_h_dir(&a->pin), &a->h_path, ++ dentry); ++ if (unlikely(err)) ++ goto out_revert; ++ } ++ ++ dir->i_version++; ++ if (au_ibstart(dir) == au_dbstart(dentry)) ++ au_cpup_attr_timesizes(dir); ++ inc_nlink(inode); ++ inode->i_ctime = dir->i_ctime; ++ d_instantiate(dentry, au_igrab(inode)); ++ if (d_unhashed(a->h_path.dentry)) ++ /* some filesystem calls d_drop() */ ++ d_drop(dentry); ++ /* some filesystems consume an inode even hardlink */ ++ au_fhsm_wrote(sb, a->bdst, /*force*/0); ++ goto out_unpin; /* success */ ++ ++out_revert: ++ /* no delegation since it is just created */ ++ rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), &a->h_path, ++ /*delegated*/NULL, /*force*/0); ++ if (unlikely(rerr)) { ++ AuIOErr("%pd reverting failed(%d, %d)\n", dentry, err, rerr); ++ err = -EIO; ++ } ++ au_dtime_revert(&dt); ++out_unpin: ++ au_unpin(&a->pin); ++out_wh: ++ dput(wh_dentry); ++out_parent: ++ di_write_unlock(a->parent); ++ dput(a->src_parent); ++out_unlock: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ aufs_read_and_write_unlock2(dentry, src_dentry); ++out_kfree: ++ kfree(a); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ++{ ++ int err, rerr; ++ aufs_bindex_t bindex; ++ unsigned char diropq; ++ struct path h_path; ++ struct dentry *wh_dentry, *parent, *opq_dentry; ++ struct mutex *h_mtx; ++ struct super_block *sb; ++ struct { ++ struct au_pin pin; ++ struct au_dtime dt; ++ } *a; /* reduce the stack usage */ ++ struct au_wr_dir_args wr_dir_args = { ++ .force_btgt = -1, ++ .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR ++ }; ++ ++ IMustLock(dir); ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); ++ if (unlikely(err)) ++ goto out_free; ++ err = au_d_may_add(dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, ++ &a->pin, &wr_dir_args); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_parent; ++ ++ sb = dentry->d_sb; ++ bindex = au_dbstart(dentry); ++ h_path.dentry = au_h_dptr(dentry, bindex); ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ err = vfsub_mkdir(au_pinned_h_dir(&a->pin), &h_path, mode); ++ if (unlikely(err)) ++ goto out_unpin; ++ ++ /* make the dir opaque */ ++ diropq = 0; ++ h_mtx = &h_path.dentry->d_inode->i_mutex; ++ if (wh_dentry ++ || au_opt_test(au_mntflags(sb), ALWAYS_DIROPQ)) { ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ opq_dentry = au_diropq_create(dentry, bindex); ++ mutex_unlock(h_mtx); ++ err = PTR_ERR(opq_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out_dir; ++ dput(opq_dentry); ++ diropq = 1; ++ } ++ ++ err = epilog(dir, bindex, wh_dentry, dentry); ++ if (!err) { ++ inc_nlink(dir); ++ goto out_unpin; /* success */ ++ } ++ ++ /* revert */ ++ if (diropq) { ++ AuLabel(revert opq); ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(dentry, bindex); ++ mutex_unlock(h_mtx); ++ if (rerr) { ++ AuIOErr("%pd reverting diropq failed(%d, %d)\n", ++ dentry, err, rerr); ++ err = -EIO; ++ } ++ } ++ ++out_dir: ++ AuLabel(revert dir); ++ rerr = vfsub_rmdir(au_pinned_h_dir(&a->pin), &h_path); ++ if (rerr) { ++ AuIOErr("%pd reverting dir failed(%d, %d)\n", ++ dentry, err, rerr); ++ err = -EIO; ++ } ++ au_dtime_revert(&a->dt); ++out_unpin: ++ au_unpin(&a->pin); ++ dput(wh_dentry); ++out_parent: ++ di_write_unlock(parent); ++out_unlock: ++ if (unlikely(err)) { ++ au_update_dbstart(dentry); ++ d_drop(dentry); ++ } ++ aufs_read_unlock(dentry, AuLock_DW); ++out_free: ++ kfree(a); ++out: ++ return err; ++} +diff --git a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c +new file mode 100644 +index 0000000..fcf377f +--- /dev/null ++++ b/fs/aufs/i_op_del.c +@@ -0,0 +1,494 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode operations (del entry) ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * decide if a new whiteout for @dentry is necessary or not. ++ * when it is necessary, prepare the parent dir for the upper branch whose ++ * branch index is @bcpup for creation. the actual creation of the whiteout will ++ * be done by caller. ++ * return value: ++ * 0: wh is unnecessary ++ * plus: wh is necessary ++ * minus: error ++ */ ++int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) ++{ ++ int need_wh, err; ++ aufs_bindex_t bstart; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ if (*bcpup < 0) { ++ *bcpup = bstart; ++ if (au_test_ro(sb, bstart, dentry->d_inode)) { ++ err = AuWbrCopyup(au_sbi(sb), dentry); ++ *bcpup = err; ++ if (unlikely(err < 0)) ++ goto out; ++ } ++ } else ++ AuDebugOn(bstart < *bcpup ++ || au_test_ro(sb, *bcpup, dentry->d_inode)); ++ AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart); ++ ++ if (*bcpup != bstart) { ++ err = au_cpup_dirs(dentry, *bcpup); ++ if (unlikely(err)) ++ goto out; ++ need_wh = 1; ++ } else { ++ struct au_dinfo *dinfo, *tmp; ++ ++ need_wh = -ENOMEM; ++ dinfo = au_di(dentry); ++ tmp = au_di_alloc(sb, AuLsc_DI_TMP); ++ if (tmp) { ++ au_di_cp(tmp, dinfo); ++ au_di_swap(tmp, dinfo); ++ /* returns the number of positive dentries */ ++ need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0); ++ au_di_swap(tmp, dinfo); ++ au_rw_write_unlock(&tmp->di_rwsem); ++ au_di_free(tmp); ++ } ++ } ++ AuDbg("need_wh %d\n", need_wh); ++ err = need_wh; ++ ++out: ++ return err; ++} ++ ++/* ++ * simple tests for the del-entry operations. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir) ++{ ++ int err; ++ umode_t h_mode; ++ struct dentry *h_dentry, *h_latest; ++ struct inode *h_inode; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ h_inode = h_dentry->d_inode; ++ if (dentry->d_inode) { ++ err = -ENOENT; ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ ++ h_mode = h_inode->i_mode; ++ if (!isdir) { ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(h_mode))) ++ goto out; ++ } else if (unlikely(!S_ISDIR(h_mode))) { ++ err = -ENOTDIR; ++ goto out; ++ } ++ } else { ++ /* rename(2) case */ ++ err = -EIO; ++ if (unlikely(h_inode)) ++ goto out; ++ } ++ ++ err = -ENOENT; ++ /* expected parent dir is locked */ ++ if (unlikely(h_parent != h_dentry->d_parent)) ++ goto out; ++ err = 0; ++ ++ /* ++ * rmdir a dir may break the consistency on some filesystem. ++ * let's try heavy test. ++ */ ++ err = -EACCES; ++ if (unlikely(!au_opt_test(au_mntflags(dentry->d_sb), DIRPERM1) ++ && au_test_h_perm(h_parent->d_inode, ++ MAY_EXEC | MAY_WRITE))) ++ goto out; ++ ++ h_latest = au_sio_lkup_one(&dentry->d_name, h_parent); ++ err = -EIO; ++ if (IS_ERR(h_latest)) ++ goto out; ++ if (h_latest == h_dentry) ++ err = 0; ++ dput(h_latest); ++ ++out: ++ return err; ++} ++ ++/* ++ * decide the branch where we operate for @dentry. the branch index will be set ++ * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent ++ * dir for reverting. ++ * when a new whiteout is necessary, create it. ++ */ ++static struct dentry* ++lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup, ++ struct au_dtime *dt, struct au_pin *pin) ++{ ++ struct dentry *wh_dentry; ++ struct super_block *sb; ++ struct path h_path; ++ int err, need_wh; ++ unsigned int udba; ++ aufs_bindex_t bcpup; ++ ++ need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup); ++ wh_dentry = ERR_PTR(need_wh); ++ if (unlikely(need_wh < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ udba = au_opt_udba(sb); ++ bcpup = *rbcpup; ++ err = au_pin(pin, dentry, bcpup, udba, ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ h_path.dentry = au_pinned_h_parent(pin); ++ if (udba != AuOpt_UDBA_NONE ++ && au_dbstart(dentry) == bcpup) { ++ err = au_may_del(dentry, bcpup, h_path.dentry, isdir); ++ wh_dentry = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out_unpin; ++ } ++ ++ h_path.mnt = au_sbr_mnt(sb, bcpup); ++ au_dtime_store(dt, au_pinned_parent(pin), &h_path); ++ wh_dentry = NULL; ++ if (!need_wh) ++ goto out; /* success, no need to create whiteout */ ++ ++ wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_unpin; ++ ++ /* returns with the parent is locked and wh_dentry is dget-ed */ ++ goto out; /* success */ ++ ++out_unpin: ++ au_unpin(pin); ++out: ++ return wh_dentry; ++} ++ ++/* ++ * when removing a dir, rename it to a unique temporary whiteout-ed name first ++ * in order to be revertible and save time for removing many child whiteouts ++ * under the dir. ++ * returns 1 when there are too many child whiteout and caller should remove ++ * them asynchronously. returns 0 when the number of children is enough small to ++ * remove now or the branch fs is a remote fs. ++ * otherwise return an error. ++ */ ++static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex, ++ struct au_nhash *whlist, struct inode *dir) ++{ ++ int rmdir_later, err, dirwh; ++ struct dentry *h_dentry; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ SiMustAnyLock(sb); ++ h_dentry = au_h_dptr(dentry, bindex); ++ err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex)); ++ if (unlikely(err)) ++ goto out; ++ ++ /* stop monitoring */ ++ au_hn_free(au_hi(dentry->d_inode, bindex)); ++ ++ if (!au_test_fs_remote(h_dentry->d_sb)) { ++ dirwh = au_sbi(sb)->si_dirwh; ++ rmdir_later = (dirwh <= 1); ++ if (!rmdir_later) ++ rmdir_later = au_nhash_test_longer_wh(whlist, bindex, ++ dirwh); ++ if (rmdir_later) ++ return rmdir_later; ++ } ++ ++ err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist); ++ if (unlikely(err)) { ++ AuIOErr("rmdir %pd, b%d failed, %d. ignored\n", ++ h_dentry, bindex, err); ++ err = 0; ++ } ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ++ * final procedure for deleting a entry. ++ * maintain dentry and iattr. ++ */ ++static void epilog(struct inode *dir, struct dentry *dentry, ++ aufs_bindex_t bindex) ++{ ++ struct inode *inode; ++ ++ inode = dentry->d_inode; ++ d_drop(dentry); ++ inode->i_ctime = dir->i_ctime; ++ ++ if (au_ibstart(dir) == bindex) ++ au_cpup_attr_timesizes(dir); ++ dir->i_version++; ++} ++ ++/* ++ * when an error happened, remove the created whiteout and revert everything. ++ */ ++static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex, ++ aufs_bindex_t bwh, struct dentry *wh_dentry, ++ struct dentry *dentry, struct au_dtime *dt) ++{ ++ int rerr; ++ struct path h_path = { ++ .dentry = wh_dentry, ++ .mnt = au_sbr_mnt(dir->i_sb, bindex) ++ }; ++ ++ rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry); ++ if (!rerr) { ++ au_set_dbwh(dentry, bwh); ++ au_dtime_revert(dt); ++ return 0; ++ } ++ ++ AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry, err, rerr); ++ return -EIO; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int aufs_unlink(struct inode *dir, struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bwh, bindex, bstart; ++ struct inode *inode, *h_dir, *delegated; ++ struct dentry *parent, *wh_dentry; ++ /* to reuduce stack size */ ++ struct { ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ } *a; ++ ++ IMustLock(dir); ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); ++ if (unlikely(err)) ++ goto out_free; ++ err = au_d_hashed_positive(dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(inode->i_mode))) ++ goto out_unlock; /* possible? */ ++ ++ bstart = au_dbstart(dentry); ++ bwh = au_dbwh(dentry); ++ bindex = -1; ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt, ++ &a->pin); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_parent; ++ ++ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ a->h_path.dentry = au_h_dptr(dentry, bstart); ++ dget(a->h_path.dentry); ++ if (bindex == bstart) { ++ h_dir = au_pinned_h_dir(&a->pin); ++ delegated = NULL; ++ err = vfsub_unlink(h_dir, &a->h_path, &delegated, /*force*/0); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal unlink\n"); ++ iput(delegated); ++ } ++ } else { ++ /* dir inode is locked */ ++ h_dir = wh_dentry->d_parent->d_inode; ++ IMustLock(h_dir); ++ err = 0; ++ } ++ ++ if (!err) { ++ vfsub_drop_nlink(inode); ++ epilog(dir, dentry, bindex); ++ ++ /* update target timestamps */ ++ if (bindex == bstart) { ++ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); ++ /*ignore*/ ++ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime; ++ } else ++ /* todo: this timestamp may be reverted later */ ++ inode->i_ctime = h_dir->i_ctime; ++ goto out_unpin; /* success */ ++ } ++ ++ /* revert */ ++ if (wh_dentry) { ++ int rerr; ++ ++ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, ++ &a->dt); ++ if (rerr) ++ err = rerr; ++ } ++ ++out_unpin: ++ au_unpin(&a->pin); ++ dput(wh_dentry); ++ dput(a->h_path.dentry); ++out_parent: ++ di_write_unlock(parent); ++out_unlock: ++ aufs_read_unlock(dentry, AuLock_DW); ++out_free: ++ kfree(a); ++out: ++ return err; ++} ++ ++int aufs_rmdir(struct inode *dir, struct dentry *dentry) ++{ ++ int err, rmdir_later; ++ aufs_bindex_t bwh, bindex, bstart; ++ struct inode *inode; ++ struct dentry *parent, *wh_dentry, *h_dentry; ++ struct au_whtmp_rmdir *args; ++ /* to reuduce stack size */ ++ struct { ++ struct au_dtime dt; ++ struct au_pin pin; ++ } *a; ++ ++ IMustLock(dir); ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN); ++ if (unlikely(err)) ++ goto out_free; ++ err = au_alive_dir(dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ inode = dentry->d_inode; ++ IMustLock(inode); ++ err = -ENOTDIR; ++ if (unlikely(!S_ISDIR(inode->i_mode))) ++ goto out_unlock; /* possible? */ ++ ++ err = -ENOMEM; ++ args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS); ++ if (unlikely(!args)) ++ goto out_unlock; ++ ++ parent = dentry->d_parent; /* dir inode is locked */ ++ di_write_lock_parent(parent); ++ err = au_test_empty(dentry, &args->whlist); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ bstart = au_dbstart(dentry); ++ bwh = au_dbwh(dentry); ++ bindex = -1; ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt, ++ &a->pin); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out_parent; ++ ++ h_dentry = au_h_dptr(dentry, bstart); ++ dget(h_dentry); ++ rmdir_later = 0; ++ if (bindex == bstart) { ++ err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir); ++ if (err > 0) { ++ rmdir_later = err; ++ err = 0; ++ } ++ } else { ++ /* stop monitoring */ ++ au_hn_free(au_hi(inode, bstart)); ++ ++ /* dir inode is locked */ ++ IMustLock(wh_dentry->d_parent->d_inode); ++ err = 0; ++ } ++ ++ if (!err) { ++ vfsub_dead_dir(inode); ++ au_set_dbdiropq(dentry, -1); ++ epilog(dir, dentry, bindex); ++ ++ if (rmdir_later) { ++ au_whtmp_kick_rmdir(dir, bstart, h_dentry, args); ++ args = NULL; ++ } ++ ++ goto out_unpin; /* success */ ++ } ++ ++ /* revert */ ++ AuLabel(revert); ++ if (wh_dentry) { ++ int rerr; ++ ++ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, ++ &a->dt); ++ if (rerr) ++ err = rerr; ++ } ++ ++out_unpin: ++ au_unpin(&a->pin); ++ dput(wh_dentry); ++ dput(h_dentry); ++out_parent: ++ di_write_unlock(parent); ++ if (args) ++ au_whtmp_rmdir_free(args); ++out_unlock: ++ aufs_read_unlock(dentry, AuLock_DW); ++out_free: ++ kfree(a); ++out: ++ AuTraceErr(err); ++ return err; ++} +diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c +new file mode 100644 +index 0000000..cbe78c8 +--- /dev/null ++++ b/fs/aufs/i_op_ren.c +@@ -0,0 +1,1021 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode operation (rename entry) ++ * todo: this is crazy monster ++ */ ++ ++#include "aufs.h" ++ ++enum { AuSRC, AuDST, AuSrcDst }; ++enum { AuPARENT, AuCHILD, AuParentChild }; ++ ++#define AuRen_ISDIR 1 ++#define AuRen_ISSAMEDIR (1 << 1) ++#define AuRen_WHSRC (1 << 2) ++#define AuRen_WHDST (1 << 3) ++#define AuRen_MNT_WRITE (1 << 4) ++#define AuRen_DT_DSTDIR (1 << 5) ++#define AuRen_DIROPQ (1 << 6) ++#define AuRen_CPUP (1 << 7) ++#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) ++#define au_fset_ren(flags, name) \ ++ do { (flags) |= AuRen_##name; } while (0) ++#define au_fclr_ren(flags, name) \ ++ do { (flags) &= ~AuRen_##name; } while (0) ++ ++struct au_ren_args { ++ struct { ++ struct dentry *dentry, *h_dentry, *parent, *h_parent, ++ *wh_dentry; ++ struct inode *dir, *inode; ++ struct au_hinode *hdir; ++ struct au_dtime dt[AuParentChild]; ++ aufs_bindex_t bstart; ++ } sd[AuSrcDst]; ++ ++#define src_dentry sd[AuSRC].dentry ++#define src_dir sd[AuSRC].dir ++#define src_inode sd[AuSRC].inode ++#define src_h_dentry sd[AuSRC].h_dentry ++#define src_parent sd[AuSRC].parent ++#define src_h_parent sd[AuSRC].h_parent ++#define src_wh_dentry sd[AuSRC].wh_dentry ++#define src_hdir sd[AuSRC].hdir ++#define src_h_dir sd[AuSRC].hdir->hi_inode ++#define src_dt sd[AuSRC].dt ++#define src_bstart sd[AuSRC].bstart ++ ++#define dst_dentry sd[AuDST].dentry ++#define dst_dir sd[AuDST].dir ++#define dst_inode sd[AuDST].inode ++#define dst_h_dentry sd[AuDST].h_dentry ++#define dst_parent sd[AuDST].parent ++#define dst_h_parent sd[AuDST].h_parent ++#define dst_wh_dentry sd[AuDST].wh_dentry ++#define dst_hdir sd[AuDST].hdir ++#define dst_h_dir sd[AuDST].hdir->hi_inode ++#define dst_dt sd[AuDST].dt ++#define dst_bstart sd[AuDST].bstart ++ ++ struct dentry *h_trap; ++ struct au_branch *br; ++ struct au_hinode *src_hinode; ++ struct path h_path; ++ struct au_nhash whlist; ++ aufs_bindex_t btgt, src_bwh, src_bdiropq; ++ ++ unsigned int flags; ++ ++ struct au_whtmp_rmdir *thargs; ++ struct dentry *h_dst; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * functions for reverting. ++ * when an error happened in a single rename systemcall, we should revert ++ * everything as if nothing happend. ++ * we don't need to revert the copied-up/down the parent dir since they are ++ * harmless. ++ */ ++ ++#define RevertFailure(fmt, ...) do { \ ++ AuIOErr("revert failure: " fmt " (%d, %d)\n", \ ++ ##__VA_ARGS__, err, rerr); \ ++ err = -EIO; \ ++} while (0) ++ ++static void au_ren_rev_diropq(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(a->src_dentry, a->btgt); ++ au_hn_imtx_unlock(a->src_hinode); ++ au_set_dbdiropq(a->src_dentry, a->src_bdiropq); ++ if (rerr) ++ RevertFailure("remove diropq %pd", a->src_dentry); ++} ++ ++static void au_ren_rev_rename(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ struct inode *delegated; ++ ++ a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name, ++ a->src_h_parent); ++ rerr = PTR_ERR(a->h_path.dentry); ++ if (IS_ERR(a->h_path.dentry)) { ++ RevertFailure("lkup one %pd", a->src_dentry); ++ return; ++ } ++ ++ delegated = NULL; ++ rerr = vfsub_rename(a->dst_h_dir, ++ au_h_dptr(a->src_dentry, a->btgt), ++ a->src_h_dir, &a->h_path, &delegated); ++ if (unlikely(rerr == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal rename\n"); ++ iput(delegated); ++ } ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ ++ if (rerr) ++ RevertFailure("rename %pd", a->src_dentry); ++} ++ ++static void au_ren_rev_cpup(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = a->dst_h_dentry; ++ /* no delegation since it is just created */ ++ rerr = vfsub_unlink(a->dst_h_dir, &a->h_path, /*delegated*/NULL, ++ /*force*/0); ++ au_set_h_dptr(a->src_dentry, a->btgt, NULL); ++ au_set_dbstart(a->src_dentry, a->src_bstart); ++ if (rerr) ++ RevertFailure("unlink %pd", a->dst_h_dentry); ++} ++ ++static void au_ren_rev_whtmp(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ struct inode *delegated; ++ ++ a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name, ++ a->dst_h_parent); ++ rerr = PTR_ERR(a->h_path.dentry); ++ if (IS_ERR(a->h_path.dentry)) { ++ RevertFailure("lkup one %pd", a->dst_dentry); ++ return; ++ } ++ if (a->h_path.dentry->d_inode) { ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ return; ++ } ++ ++ delegated = NULL; ++ rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path, ++ &delegated); ++ if (unlikely(rerr == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal rename\n"); ++ iput(delegated); ++ } ++ d_drop(a->h_path.dentry); ++ dput(a->h_path.dentry); ++ if (!rerr) ++ au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst)); ++ else ++ RevertFailure("rename %pd", a->h_dst); ++} ++ ++static void au_ren_rev_whsrc(int err, struct au_ren_args *a) ++{ ++ int rerr; ++ ++ a->h_path.dentry = a->src_wh_dentry; ++ rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry); ++ au_set_dbwh(a->src_dentry, a->src_bwh); ++ if (rerr) ++ RevertFailure("unlink %pd", a->src_wh_dentry); ++} ++#undef RevertFailure ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * when we have to copyup the renaming entry, do it with the rename-target name ++ * in order to minimize the cost (the later actual rename is unnecessary). ++ * otherwise rename it on the target branch. ++ */ ++static int au_ren_or_cpup(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *d; ++ struct inode *delegated; ++ ++ d = a->src_dentry; ++ if (au_dbstart(d) == a->btgt) { ++ a->h_path.dentry = a->dst_h_dentry; ++ if (au_ftest_ren(a->flags, DIROPQ) ++ && au_dbdiropq(d) == a->btgt) ++ au_fclr_ren(a->flags, DIROPQ); ++ AuDebugOn(au_dbstart(d) != a->btgt); ++ delegated = NULL; ++ err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt), ++ a->dst_h_dir, &a->h_path, &delegated); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal rename\n"); ++ iput(delegated); ++ } ++ } else ++ BUG(); ++ ++ if (!err && a->h_dst) ++ /* it will be set to dinfo later */ ++ dget(a->h_dst); ++ ++ return err; ++} ++ ++/* cf. aufs_rmdir() */ ++static int au_ren_del_whtmp(struct au_ren_args *a) ++{ ++ int err; ++ struct inode *dir; ++ ++ dir = a->dst_dir; ++ SiMustAnyLock(dir->i_sb); ++ if (!au_nhash_test_longer_wh(&a->whlist, a->btgt, ++ au_sbi(dir->i_sb)->si_dirwh) ++ || au_test_fs_remote(a->h_dst->d_sb)) { ++ err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist); ++ if (unlikely(err)) ++ pr_warn("failed removing whtmp dir %pd (%d), " ++ "ignored.\n", a->h_dst, err); ++ } else { ++ au_nhash_wh_free(&a->thargs->whlist); ++ a->thargs->whlist = a->whlist; ++ a->whlist.nh_num = 0; ++ au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs); ++ dput(a->h_dst); ++ a->thargs = NULL; ++ } ++ ++ return 0; ++} ++ ++/* make it 'opaque' dir. */ ++static int au_ren_diropq(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *diropq; ++ ++ err = 0; ++ a->src_bdiropq = au_dbdiropq(a->src_dentry); ++ a->src_hinode = au_hi(a->src_inode, a->btgt); ++ au_hn_imtx_lock_nested(a->src_hinode, AuLsc_I_CHILD); ++ diropq = au_diropq_create(a->src_dentry, a->btgt); ++ au_hn_imtx_unlock(a->src_hinode); ++ if (IS_ERR(diropq)) ++ err = PTR_ERR(diropq); ++ else ++ dput(diropq); ++ ++ return err; ++} ++ ++static int do_rename(struct au_ren_args *a) ++{ ++ int err; ++ struct dentry *d, *h_d; ++ ++ /* prepare workqueue args for asynchronous rmdir */ ++ h_d = a->dst_h_dentry; ++ if (au_ftest_ren(a->flags, ISDIR) && h_d->d_inode) { ++ err = -ENOMEM; ++ a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS); ++ if (unlikely(!a->thargs)) ++ goto out; ++ a->h_dst = dget(h_d); ++ } ++ ++ /* create whiteout for src_dentry */ ++ if (au_ftest_ren(a->flags, WHSRC)) { ++ a->src_bwh = au_dbwh(a->src_dentry); ++ AuDebugOn(a->src_bwh >= 0); ++ a->src_wh_dentry ++ = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent); ++ err = PTR_ERR(a->src_wh_dentry); ++ if (IS_ERR(a->src_wh_dentry)) ++ goto out_thargs; ++ } ++ ++ /* lookup whiteout for dentry */ ++ if (au_ftest_ren(a->flags, WHDST)) { ++ h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name, ++ a->br); ++ err = PTR_ERR(h_d); ++ if (IS_ERR(h_d)) ++ goto out_whsrc; ++ if (!h_d->d_inode) ++ dput(h_d); ++ else ++ a->dst_wh_dentry = h_d; ++ } ++ ++ /* rename dentry to tmpwh */ ++ if (a->thargs) { ++ err = au_whtmp_ren(a->dst_h_dentry, a->br); ++ if (unlikely(err)) ++ goto out_whdst; ++ ++ d = a->dst_dentry; ++ au_set_h_dptr(d, a->btgt, NULL); ++ err = au_lkup_neg(d, a->btgt, /*wh*/0); ++ if (unlikely(err)) ++ goto out_whtmp; ++ a->dst_h_dentry = au_h_dptr(d, a->btgt); ++ } ++ ++ BUG_ON(a->dst_h_dentry->d_inode && a->src_bstart != a->btgt); ++ ++ /* rename by vfs_rename or cpup */ ++ d = a->dst_dentry; ++ if (au_ftest_ren(a->flags, ISDIR) ++ && (a->dst_wh_dentry ++ || au_dbdiropq(d) == a->btgt ++ /* hide the lower to keep xino */ ++ || a->btgt < au_dbend(d) ++ || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ))) ++ au_fset_ren(a->flags, DIROPQ); ++ err = au_ren_or_cpup(a); ++ if (unlikely(err)) ++ /* leave the copied-up one */ ++ goto out_whtmp; ++ ++ /* make dir opaque */ ++ if (au_ftest_ren(a->flags, DIROPQ)) { ++ err = au_ren_diropq(a); ++ if (unlikely(err)) ++ goto out_rename; ++ } ++ ++ /* update target timestamps */ ++ AuDebugOn(au_dbstart(a->src_dentry) != a->btgt); ++ a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt); ++ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ ++ a->src_inode->i_ctime = a->h_path.dentry->d_inode->i_ctime; ++ ++ /* remove whiteout for dentry */ ++ if (a->dst_wh_dentry) { ++ a->h_path.dentry = a->dst_wh_dentry; ++ err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path, ++ a->dst_dentry); ++ if (unlikely(err)) ++ goto out_diropq; ++ } ++ ++ /* remove whtmp */ ++ if (a->thargs) ++ au_ren_del_whtmp(a); /* ignore this error */ ++ ++ au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0); ++ err = 0; ++ goto out_success; ++ ++out_diropq: ++ if (au_ftest_ren(a->flags, DIROPQ)) ++ au_ren_rev_diropq(err, a); ++out_rename: ++ if (!au_ftest_ren(a->flags, CPUP)) ++ au_ren_rev_rename(err, a); ++ else ++ au_ren_rev_cpup(err, a); ++ dput(a->h_dst); ++out_whtmp: ++ if (a->thargs) ++ au_ren_rev_whtmp(err, a); ++out_whdst: ++ dput(a->dst_wh_dentry); ++ a->dst_wh_dentry = NULL; ++out_whsrc: ++ if (a->src_wh_dentry) ++ au_ren_rev_whsrc(err, a); ++out_success: ++ dput(a->src_wh_dentry); ++ dput(a->dst_wh_dentry); ++out_thargs: ++ if (a->thargs) { ++ dput(a->h_dst); ++ au_whtmp_rmdir_free(a->thargs); ++ a->thargs = NULL; ++ } ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * test if @dentry dir can be rename destination or not. ++ * success means, it is a logically empty dir. ++ */ ++static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist) ++{ ++ return au_test_empty(dentry, whlist); ++} ++ ++/* ++ * test if @dentry dir can be rename source or not. ++ * if it can, return 0 and @children is filled. ++ * success means, ++ * - it is a logically empty dir. ++ * - or, it exists on writable branch and has no children including whiteouts ++ * on the lower branch. ++ */ ++static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt) ++{ ++ int err; ++ unsigned int rdhash; ++ aufs_bindex_t bstart; ++ ++ bstart = au_dbstart(dentry); ++ if (bstart != btgt) { ++ struct au_nhash whlist; ++ ++ SiMustAnyLock(dentry->d_sb); ++ rdhash = au_sbi(dentry->d_sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, ++ dentry)); ++ err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_test_empty(dentry, &whlist); ++ au_nhash_wh_free(&whlist); ++ goto out; ++ } ++ ++ if (bstart == au_dbtaildir(dentry)) ++ return 0; /* success */ ++ ++ err = au_test_empty_lower(dentry); ++ ++out: ++ if (err == -ENOTEMPTY) { ++ AuWarn1("renaming dir who has child(ren) on multiple branches," ++ " is not supported\n"); ++ err = -EXDEV; ++ } ++ return err; ++} ++ ++/* side effect: sets whlist and h_dentry */ ++static int au_ren_may_dir(struct au_ren_args *a) ++{ ++ int err; ++ unsigned int rdhash; ++ struct dentry *d; ++ ++ d = a->dst_dentry; ++ SiMustAnyLock(d->d_sb); ++ ++ err = 0; ++ if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) { ++ rdhash = au_sbi(d->d_sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d)); ++ err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ ++ au_set_dbstart(d, a->dst_bstart); ++ err = may_rename_dstdir(d, &a->whlist); ++ au_set_dbstart(d, a->btgt); ++ } ++ a->dst_h_dentry = au_h_dptr(d, au_dbstart(d)); ++ if (unlikely(err)) ++ goto out; ++ ++ d = a->src_dentry; ++ a->src_h_dentry = au_h_dptr(d, au_dbstart(d)); ++ if (au_ftest_ren(a->flags, ISDIR)) { ++ err = may_rename_srcdir(d, a->btgt); ++ if (unlikely(err)) { ++ au_nhash_wh_free(&a->whlist); ++ a->whlist.nh_num = 0; ++ } ++ } ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * simple tests for rename. ++ * following the checks in vfs, plus the parent-child relationship. ++ */ ++static int au_may_ren(struct au_ren_args *a) ++{ ++ int err, isdir; ++ struct inode *h_inode; ++ ++ if (a->src_bstart == a->btgt) { ++ err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent, ++ au_ftest_ren(a->flags, ISDIR)); ++ if (unlikely(err)) ++ goto out; ++ err = -EINVAL; ++ if (unlikely(a->src_h_dentry == a->h_trap)) ++ goto out; ++ } ++ ++ err = 0; ++ if (a->dst_bstart != a->btgt) ++ goto out; ++ ++ err = -ENOTEMPTY; ++ if (unlikely(a->dst_h_dentry == a->h_trap)) ++ goto out; ++ ++ err = -EIO; ++ h_inode = a->dst_h_dentry->d_inode; ++ isdir = !!au_ftest_ren(a->flags, ISDIR); ++ if (!a->dst_dentry->d_inode) { ++ if (unlikely(h_inode)) ++ goto out; ++ err = au_may_add(a->dst_dentry, a->btgt, a->dst_h_parent, ++ isdir); ++ } else { ++ if (unlikely(!h_inode || !h_inode->i_nlink)) ++ goto out; ++ err = au_may_del(a->dst_dentry, a->btgt, a->dst_h_parent, ++ isdir); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++out: ++ if (unlikely(err == -ENOENT || err == -EEXIST)) ++ err = -EIO; ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * locking order ++ * (VFS) ++ * - src_dir and dir by lock_rename() ++ * - inode if exitsts ++ * (aufs) ++ * - lock all ++ * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, ++ * + si_read_lock ++ * + di_write_lock2_child() ++ * + di_write_lock_child() ++ * + ii_write_lock_child() ++ * + di_write_lock_child2() ++ * + ii_write_lock_child2() ++ * + src_parent and parent ++ * + di_write_lock_parent() ++ * + ii_write_lock_parent() ++ * + di_write_lock_parent2() ++ * + ii_write_lock_parent2() ++ * + lower src_dir and dir by vfsub_lock_rename() ++ * + verify the every relationships between child and parent. if any ++ * of them failed, unlock all and return -EBUSY. ++ */ ++static void au_ren_unlock(struct au_ren_args *a) ++{ ++ vfsub_unlock_rename(a->src_h_parent, a->src_hdir, ++ a->dst_h_parent, a->dst_hdir); ++ if (au_ftest_ren(a->flags, MNT_WRITE)) ++ vfsub_mnt_drop_write(au_br_mnt(a->br)); ++} ++ ++static int au_ren_lock(struct au_ren_args *a) ++{ ++ int err; ++ unsigned int udba; ++ ++ err = 0; ++ a->src_h_parent = au_h_dptr(a->src_parent, a->btgt); ++ a->src_hdir = au_hi(a->src_dir, a->btgt); ++ a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt); ++ a->dst_hdir = au_hi(a->dst_dir, a->btgt); ++ ++ err = vfsub_mnt_want_write(au_br_mnt(a->br)); ++ if (unlikely(err)) ++ goto out; ++ au_fset_ren(a->flags, MNT_WRITE); ++ a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir, ++ a->dst_h_parent, a->dst_hdir); ++ udba = au_opt_udba(a->src_dentry->d_sb); ++ if (unlikely(a->src_hdir->hi_inode != a->src_h_parent->d_inode ++ || a->dst_hdir->hi_inode != a->dst_h_parent->d_inode)) ++ err = au_busy_or_stale(); ++ if (!err && au_dbstart(a->src_dentry) == a->btgt) ++ err = au_h_verify(a->src_h_dentry, udba, ++ a->src_h_parent->d_inode, a->src_h_parent, ++ a->br); ++ if (!err && au_dbstart(a->dst_dentry) == a->btgt) ++ err = au_h_verify(a->dst_h_dentry, udba, ++ a->dst_h_parent->d_inode, a->dst_h_parent, ++ a->br); ++ if (!err) ++ goto out; /* success */ ++ ++ err = au_busy_or_stale(); ++ au_ren_unlock(a); ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_ren_refresh_dir(struct au_ren_args *a) ++{ ++ struct inode *dir; ++ ++ dir = a->dst_dir; ++ dir->i_version++; ++ if (au_ftest_ren(a->flags, ISDIR)) { ++ /* is this updating defined in POSIX? */ ++ au_cpup_attr_timesizes(a->src_inode); ++ au_cpup_attr_nlink(dir, /*force*/1); ++ } ++ ++ if (au_ibstart(dir) == a->btgt) ++ au_cpup_attr_timesizes(dir); ++ ++ if (au_ftest_ren(a->flags, ISSAMEDIR)) ++ return; ++ ++ dir = a->src_dir; ++ dir->i_version++; ++ if (au_ftest_ren(a->flags, ISDIR)) ++ au_cpup_attr_nlink(dir, /*force*/1); ++ if (au_ibstart(dir) == a->btgt) ++ au_cpup_attr_timesizes(dir); ++} ++ ++static void au_ren_refresh(struct au_ren_args *a) ++{ ++ aufs_bindex_t bend, bindex; ++ struct dentry *d, *h_d; ++ struct inode *i, *h_i; ++ struct super_block *sb; ++ ++ d = a->dst_dentry; ++ d_drop(d); ++ if (a->h_dst) ++ /* already dget-ed by au_ren_or_cpup() */ ++ au_set_h_dptr(d, a->btgt, a->h_dst); ++ ++ i = a->dst_inode; ++ if (i) { ++ if (!au_ftest_ren(a->flags, ISDIR)) ++ vfsub_drop_nlink(i); ++ else { ++ vfsub_dead_dir(i); ++ au_cpup_attr_timesizes(i); ++ } ++ au_update_dbrange(d, /*do_put_zero*/1); ++ } else { ++ bend = a->btgt; ++ for (bindex = au_dbstart(d); bindex < bend; bindex++) ++ au_set_h_dptr(d, bindex, NULL); ++ bend = au_dbend(d); ++ for (bindex = a->btgt + 1; bindex <= bend; bindex++) ++ au_set_h_dptr(d, bindex, NULL); ++ au_update_dbrange(d, /*do_put_zero*/0); ++ } ++ ++ d = a->src_dentry; ++ au_set_dbwh(d, -1); ++ bend = au_dbend(d); ++ for (bindex = a->btgt + 1; bindex <= bend; bindex++) { ++ h_d = au_h_dptr(d, bindex); ++ if (h_d) ++ au_set_h_dptr(d, bindex, NULL); ++ } ++ au_set_dbend(d, a->btgt); ++ ++ sb = d->d_sb; ++ i = a->src_inode; ++ if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i)) ++ return; /* success */ ++ ++ bend = au_ibend(i); ++ for (bindex = a->btgt + 1; bindex <= bend; bindex++) { ++ h_i = au_h_iptr(i, bindex); ++ if (h_i) { ++ au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0); ++ /* ignore this error */ ++ au_set_h_iptr(i, bindex, NULL, 0); ++ } ++ } ++ au_set_ibend(i, a->btgt); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* mainly for link(2) and rename(2) */ ++int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) ++{ ++ aufs_bindex_t bdiropq, bwh; ++ struct dentry *parent; ++ struct au_branch *br; ++ ++ parent = dentry->d_parent; ++ IMustLock(parent->d_inode); /* dir is locked */ ++ ++ bdiropq = au_dbdiropq(parent); ++ bwh = au_dbwh(dentry); ++ br = au_sbr(dentry->d_sb, btgt); ++ if (au_br_rdonly(br) ++ || (0 <= bdiropq && bdiropq < btgt) ++ || (0 <= bwh && bwh < btgt)) ++ btgt = -1; ++ ++ AuDbg("btgt %d\n", btgt); ++ return btgt; ++} ++ ++/* sets src_bstart, dst_bstart and btgt */ ++static int au_ren_wbr(struct au_ren_args *a) ++{ ++ int err; ++ struct au_wr_dir_args wr_dir_args = { ++ /* .force_btgt = -1, */ ++ .flags = AuWrDir_ADD_ENTRY ++ }; ++ ++ a->src_bstart = au_dbstart(a->src_dentry); ++ a->dst_bstart = au_dbstart(a->dst_dentry); ++ if (au_ftest_ren(a->flags, ISDIR)) ++ au_fset_wrdir(wr_dir_args.flags, ISDIR); ++ wr_dir_args.force_btgt = a->src_bstart; ++ if (a->dst_inode && a->dst_bstart < a->src_bstart) ++ wr_dir_args.force_btgt = a->dst_bstart; ++ wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt); ++ err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args); ++ a->btgt = err; ++ ++ return err; ++} ++ ++static void au_ren_dt(struct au_ren_args *a) ++{ ++ a->h_path.dentry = a->src_h_parent; ++ au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path); ++ if (!au_ftest_ren(a->flags, ISSAMEDIR)) { ++ a->h_path.dentry = a->dst_h_parent; ++ au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path); ++ } ++ ++ au_fclr_ren(a->flags, DT_DSTDIR); ++ if (!au_ftest_ren(a->flags, ISDIR)) ++ return; ++ ++ a->h_path.dentry = a->src_h_dentry; ++ au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path); ++ if (a->dst_h_dentry->d_inode) { ++ au_fset_ren(a->flags, DT_DSTDIR); ++ a->h_path.dentry = a->dst_h_dentry; ++ au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path); ++ } ++} ++ ++static void au_ren_rev_dt(int err, struct au_ren_args *a) ++{ ++ struct dentry *h_d; ++ struct mutex *h_mtx; ++ ++ au_dtime_revert(a->src_dt + AuPARENT); ++ if (!au_ftest_ren(a->flags, ISSAMEDIR)) ++ au_dtime_revert(a->dst_dt + AuPARENT); ++ ++ if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) { ++ h_d = a->src_dt[AuCHILD].dt_h_path.dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_dtime_revert(a->src_dt + AuCHILD); ++ mutex_unlock(h_mtx); ++ ++ if (au_ftest_ren(a->flags, DT_DSTDIR)) { ++ h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; ++ h_mtx = &h_d->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD); ++ au_dtime_revert(a->dst_dt + AuCHILD); ++ mutex_unlock(h_mtx); ++ } ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry, ++ struct inode *_dst_dir, struct dentry *_dst_dentry) ++{ ++ int err, flags; ++ /* reduce stack space */ ++ struct au_ren_args *a; ++ ++ AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry); ++ IMustLock(_src_dir); ++ IMustLock(_dst_dir); ++ ++ err = -ENOMEM; ++ BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE); ++ a = kzalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ a->src_dir = _src_dir; ++ a->src_dentry = _src_dentry; ++ a->src_inode = a->src_dentry->d_inode; ++ a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */ ++ a->dst_dir = _dst_dir; ++ a->dst_dentry = _dst_dentry; ++ a->dst_inode = a->dst_dentry->d_inode; ++ a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */ ++ if (a->dst_inode) { ++ IMustLock(a->dst_inode); ++ au_igrab(a->dst_inode); ++ } ++ ++ err = -ENOTDIR; ++ flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN; ++ if (S_ISDIR(a->src_inode->i_mode)) { ++ au_fset_ren(a->flags, ISDIR); ++ if (unlikely(a->dst_inode && !S_ISDIR(a->dst_inode->i_mode))) ++ goto out_free; ++ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, ++ AuLock_DIR | flags); ++ } else ++ err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, ++ flags); ++ if (unlikely(err)) ++ goto out_free; ++ ++ err = au_d_hashed_positive(a->src_dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ err = -ENOENT; ++ if (a->dst_inode) { ++ /* ++ * If it is a dir, VFS unhash dst_dentry before this ++ * function. It means we cannot rely upon d_unhashed(). ++ */ ++ if (unlikely(!a->dst_inode->i_nlink)) ++ goto out_unlock; ++ if (!S_ISDIR(a->dst_inode->i_mode)) { ++ err = au_d_hashed_positive(a->dst_dentry); ++ if (unlikely(err)) ++ goto out_unlock; ++ } else if (unlikely(IS_DEADDIR(a->dst_inode))) ++ goto out_unlock; ++ } else if (unlikely(d_unhashed(a->dst_dentry))) ++ goto out_unlock; ++ ++ /* ++ * is it possible? ++ * yes, it happend (in linux-3.3-rcN) but I don't know why. ++ * there may exist a problem somewhere else. ++ */ ++ err = -EINVAL; ++ if (unlikely(a->dst_parent->d_inode == a->src_dentry->d_inode)) ++ goto out_unlock; ++ ++ au_fset_ren(a->flags, ISSAMEDIR); /* temporary */ ++ di_write_lock_parent(a->dst_parent); ++ ++ /* which branch we process */ ++ err = au_ren_wbr(a); ++ if (unlikely(err < 0)) ++ goto out_parent; ++ a->br = au_sbr(a->dst_dentry->d_sb, a->btgt); ++ a->h_path.mnt = au_br_mnt(a->br); ++ ++ /* are they available to be renamed */ ++ err = au_ren_may_dir(a); ++ if (unlikely(err)) ++ goto out_children; ++ ++ /* prepare the writable parent dir on the same branch */ ++ if (a->dst_bstart == a->btgt) { ++ au_fset_ren(a->flags, WHDST); ++ } else { ++ err = au_cpup_dirs(a->dst_dentry, a->btgt); ++ if (unlikely(err)) ++ goto out_children; ++ } ++ ++ if (a->src_dir != a->dst_dir) { ++ /* ++ * this temporary unlock is safe, ++ * because both dir->i_mutex are locked. ++ */ ++ di_write_unlock(a->dst_parent); ++ di_write_lock_parent(a->src_parent); ++ err = au_wr_dir_need_wh(a->src_dentry, ++ au_ftest_ren(a->flags, ISDIR), ++ &a->btgt); ++ di_write_unlock(a->src_parent); ++ di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1); ++ au_fclr_ren(a->flags, ISSAMEDIR); ++ } else ++ err = au_wr_dir_need_wh(a->src_dentry, ++ au_ftest_ren(a->flags, ISDIR), ++ &a->btgt); ++ if (unlikely(err < 0)) ++ goto out_children; ++ if (err) ++ au_fset_ren(a->flags, WHSRC); ++ ++ /* cpup src */ ++ if (a->src_bstart != a->btgt) { ++ struct au_pin pin; ++ ++ err = au_pin(&pin, a->src_dentry, a->btgt, ++ au_opt_udba(a->src_dentry->d_sb), ++ AuPin_DI_LOCKED | AuPin_MNT_WRITE); ++ if (!err) { ++ struct au_cp_generic cpg = { ++ .dentry = a->src_dentry, ++ .bdst = a->btgt, ++ .bsrc = a->src_bstart, ++ .len = -1, ++ .pin = &pin, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN ++ }; ++ AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart); ++ err = au_sio_cpup_simple(&cpg); ++ au_unpin(&pin); ++ } ++ if (unlikely(err)) ++ goto out_children; ++ a->src_bstart = a->btgt; ++ a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt); ++ au_fset_ren(a->flags, WHSRC); ++ } ++ ++ /* lock them all */ ++ err = au_ren_lock(a); ++ if (unlikely(err)) ++ /* leave the copied-up one */ ++ goto out_children; ++ ++ if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) ++ err = au_may_ren(a); ++ else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN)) ++ err = -ENAMETOOLONG; ++ if (unlikely(err)) ++ goto out_hdir; ++ ++ /* store timestamps to be revertible */ ++ au_ren_dt(a); ++ ++ /* here we go */ ++ err = do_rename(a); ++ if (unlikely(err)) ++ goto out_dt; ++ ++ /* update dir attributes */ ++ au_ren_refresh_dir(a); ++ ++ /* dput/iput all lower dentries */ ++ au_ren_refresh(a); ++ ++ goto out_hdir; /* success */ ++ ++out_dt: ++ au_ren_rev_dt(err, a); ++out_hdir: ++ au_ren_unlock(a); ++out_children: ++ au_nhash_wh_free(&a->whlist); ++ if (err && a->dst_inode && a->dst_bstart != a->btgt) { ++ AuDbg("bstart %d, btgt %d\n", a->dst_bstart, a->btgt); ++ au_set_h_dptr(a->dst_dentry, a->btgt, NULL); ++ au_set_dbstart(a->dst_dentry, a->dst_bstart); ++ } ++out_parent: ++ if (!err) ++ d_move(a->src_dentry, a->dst_dentry); ++ else { ++ au_update_dbstart(a->dst_dentry); ++ if (!a->dst_inode) ++ d_drop(a->dst_dentry); ++ } ++ if (au_ftest_ren(a->flags, ISSAMEDIR)) ++ di_write_unlock(a->dst_parent); ++ else ++ di_write_unlock2(a->src_parent, a->dst_parent); ++out_unlock: ++ aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry); ++out_free: ++ iput(a->dst_inode); ++ if (a->thargs) ++ au_whtmp_rmdir_free(a->thargs); ++ kfree(a); ++out: ++ AuTraceErr(err); ++ return err; ++} +diff --git a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c +new file mode 100644 +index 0000000..b8efd45 +--- /dev/null ++++ b/fs/aufs/iinfo.c +@@ -0,0 +1,264 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode private data ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct inode *h_inode; ++ ++ IiMustAnyLock(inode); ++ ++ h_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ return h_inode; ++} ++ ++/* todo: hard/soft set? */ ++void au_hiput(struct au_hinode *hinode) ++{ ++ au_hn_free(hinode); ++ dput(hinode->hi_whdentry); ++ iput(hinode->hi_inode); ++} ++ ++unsigned int au_hi_flags(struct inode *inode, int isdir) ++{ ++ unsigned int flags; ++ const unsigned int mnt_flags = au_mntflags(inode->i_sb); ++ ++ flags = 0; ++ if (au_opt_test(mnt_flags, XINO)) ++ au_fset_hi(flags, XINO); ++ if (isdir && au_opt_test(mnt_flags, UDBA_HNOTIFY)) ++ au_fset_hi(flags, HNOTIFY); ++ return flags; ++} ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags) ++{ ++ struct au_hinode *hinode; ++ struct inode *hi; ++ struct au_iinfo *iinfo = au_ii(inode); ++ ++ IiMustWriteLock(inode); ++ ++ hinode = iinfo->ii_hinode + bindex; ++ hi = hinode->hi_inode; ++ AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); ++ ++ if (hi) ++ au_hiput(hinode); ++ hinode->hi_inode = h_inode; ++ if (h_inode) { ++ int err; ++ struct super_block *sb = inode->i_sb; ++ struct au_branch *br; ++ ++ AuDebugOn(inode->i_mode ++ && (h_inode->i_mode & S_IFMT) ++ != (inode->i_mode & S_IFMT)); ++ if (bindex == iinfo->ii_bstart) ++ au_cpup_igen(inode, h_inode); ++ br = au_sbr(sb, bindex); ++ hinode->hi_id = br->br_id; ++ if (au_ftest_hi(flags, XINO)) { ++ err = au_xino_write(sb, bindex, h_inode->i_ino, ++ inode->i_ino); ++ if (unlikely(err)) ++ AuIOErr1("failed au_xino_write() %d\n", err); ++ } ++ ++ if (au_ftest_hi(flags, HNOTIFY) ++ && au_br_hnotifyable(br->br_perm)) { ++ err = au_hn_alloc(hinode, inode); ++ if (unlikely(err)) ++ AuIOErr1("au_hn_alloc() %d\n", err); ++ } ++ } ++} ++ ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh) ++{ ++ struct au_hinode *hinode; ++ ++ IiMustWriteLock(inode); ++ ++ hinode = au_ii(inode)->ii_hinode + bindex; ++ AuDebugOn(hinode->hi_whdentry); ++ hinode->hi_whdentry = h_wh; ++} ++ ++void au_update_iigen(struct inode *inode, int half) ++{ ++ struct au_iinfo *iinfo; ++ struct au_iigen *iigen; ++ unsigned int sigen; ++ ++ sigen = au_sigen(inode->i_sb); ++ iinfo = au_ii(inode); ++ iigen = &iinfo->ii_generation; ++ spin_lock(&iinfo->ii_genspin); ++ iigen->ig_generation = sigen; ++ if (half) ++ au_ig_fset(iigen->ig_flags, HALF_REFRESHED); ++ else ++ au_ig_fclr(iigen->ig_flags, HALF_REFRESHED); ++ spin_unlock(&iinfo->ii_genspin); ++} ++ ++/* it may be called at remount time, too */ ++void au_update_ibrange(struct inode *inode, int do_put_zero) ++{ ++ struct au_iinfo *iinfo; ++ aufs_bindex_t bindex, bend; ++ ++ iinfo = au_ii(inode); ++ if (!iinfo) ++ return; ++ ++ IiMustWriteLock(inode); ++ ++ if (do_put_zero && iinfo->ii_bstart >= 0) { ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++) { ++ struct inode *h_i; ++ ++ h_i = iinfo->ii_hinode[0 + bindex].hi_inode; ++ if (h_i ++ && !h_i->i_nlink ++ && !(h_i->i_state & I_LINKABLE)) ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ } ++ } ++ ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ bend = au_sbend(inode->i_sb); ++ for (bindex = 0; bindex <= bend; bindex++) ++ if (iinfo->ii_hinode[0 + bindex].hi_inode) { ++ iinfo->ii_bstart = bindex; ++ break; ++ } ++ if (iinfo->ii_bstart >= 0) ++ for (bindex = bend; bindex >= iinfo->ii_bstart; bindex--) ++ if (iinfo->ii_hinode[0 + bindex].hi_inode) { ++ iinfo->ii_bend = bindex; ++ break; ++ } ++ AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_icntnr_init_once(void *_c) ++{ ++ struct au_icntnr *c = _c; ++ struct au_iinfo *iinfo = &c->iinfo; ++ static struct lock_class_key aufs_ii; ++ ++ spin_lock_init(&iinfo->ii_genspin); ++ au_rw_init(&iinfo->ii_rwsem); ++ au_rw_class(&iinfo->ii_rwsem, &aufs_ii); ++ inode_init_once(&c->vfs_inode); ++} ++ ++int au_iinfo_init(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ struct super_block *sb; ++ int nbr, i; ++ ++ sb = inode->i_sb; ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ nbr = au_sbend(sb) + 1; ++ if (unlikely(nbr <= 0)) ++ nbr = 1; ++ iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); ++ if (iinfo->ii_hinode) { ++ au_ninodes_inc(sb); ++ for (i = 0; i < nbr; i++) ++ iinfo->ii_hinode[i].hi_id = -1; ++ ++ iinfo->ii_generation.ig_generation = au_sigen(sb); ++ iinfo->ii_bstart = -1; ++ iinfo->ii_bend = -1; ++ iinfo->ii_vdir = NULL; ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr) ++{ ++ int err, sz; ++ struct au_hinode *hip; ++ ++ AuRwMustWriteLock(&iinfo->ii_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*hip) * (iinfo->ii_bend + 1); ++ if (!sz) ++ sz = sizeof(*hip); ++ hip = au_kzrealloc(iinfo->ii_hinode, sz, sizeof(*hip) * nbr, GFP_NOFS); ++ if (hip) { ++ iinfo->ii_hinode = hip; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++void au_iinfo_fin(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ struct au_hinode *hi; ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend; ++ const unsigned char unlinked = !inode->i_nlink; ++ ++ iinfo = au_ii(inode); ++ /* bad_inode case */ ++ if (!iinfo) ++ return; ++ ++ sb = inode->i_sb; ++ au_ninodes_dec(sb); ++ if (si_pid_test(sb)) ++ au_xino_delete_inode(inode, unlinked); ++ else { ++ /* ++ * it is safe to hide the dependency between sbinfo and ++ * sb->s_umount. ++ */ ++ lockdep_off(); ++ si_noflush_read_lock(sb); ++ au_xino_delete_inode(inode, unlinked); ++ si_read_unlock(sb); ++ lockdep_on(); ++ } ++ ++ if (iinfo->ii_vdir) ++ au_vdir_free(iinfo->ii_vdir); ++ ++ bindex = iinfo->ii_bstart; ++ if (bindex >= 0) { ++ hi = iinfo->ii_hinode + bindex; ++ bend = iinfo->ii_bend; ++ while (bindex++ <= bend) { ++ if (hi->hi_inode) ++ au_hiput(hi); ++ hi++; ++ } ++ } ++ kfree(iinfo->ii_hinode); ++ iinfo->ii_hinode = NULL; ++ AuRwDestroy(&iinfo->ii_rwsem); ++} +diff --git a/fs/aufs/inode.c b/fs/aufs/inode.c +new file mode 100644 +index 0000000..f58367d +--- /dev/null ++++ b/fs/aufs/inode.c +@@ -0,0 +1,483 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode functions ++ */ ++ ++#include "aufs.h" ++ ++struct inode *au_igrab(struct inode *inode) ++{ ++ if (inode) { ++ AuDebugOn(!atomic_read(&inode->i_count)); ++ ihold(inode); ++ } ++ return inode; ++} ++ ++static void au_refresh_hinode_attr(struct inode *inode, int do_version) ++{ ++ au_cpup_attr_all(inode, /*force*/0); ++ au_update_iigen(inode, /*half*/1); ++ if (do_version) ++ inode->i_version++; ++} ++ ++static int au_ii_refresh(struct inode *inode, int *update) ++{ ++ int err, e; ++ umode_t type; ++ aufs_bindex_t bindex, new_bindex; ++ struct super_block *sb; ++ struct au_iinfo *iinfo; ++ struct au_hinode *p, *q, tmp; ++ ++ IiMustWriteLock(inode); ++ ++ *update = 0; ++ sb = inode->i_sb; ++ type = inode->i_mode & S_IFMT; ++ iinfo = au_ii(inode); ++ err = au_ii_realloc(iinfo, au_sbend(sb) + 1); ++ if (unlikely(err)) ++ goto out; ++ ++ AuDebugOn(iinfo->ii_bstart < 0); ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; ++ bindex++, p++) { ++ if (!p->hi_inode) ++ continue; ++ ++ AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT)); ++ new_bindex = au_br_index(sb, p->hi_id); ++ if (new_bindex == bindex) ++ continue; ++ ++ if (new_bindex < 0) { ++ *update = 1; ++ au_hiput(p); ++ p->hi_inode = NULL; ++ continue; ++ } ++ ++ if (new_bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = new_bindex; ++ if (iinfo->ii_bend < new_bindex) ++ iinfo->ii_bend = new_bindex; ++ /* swap two lower inode, and loop again */ ++ q = iinfo->ii_hinode + new_bindex; ++ tmp = *q; ++ *q = *p; ++ *p = tmp; ++ if (tmp.hi_inode) { ++ bindex--; ++ p--; ++ } ++ } ++ au_update_ibrange(inode, /*do_put_zero*/0); ++ e = au_dy_irefresh(inode); ++ if (unlikely(e && !err)) ++ err = e; ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_refresh_hinode_self(struct inode *inode) ++{ ++ int err, update; ++ ++ err = au_ii_refresh(inode, &update); ++ if (!err) ++ au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry) ++{ ++ int err, e, update; ++ unsigned int flags; ++ umode_t mode; ++ aufs_bindex_t bindex, bend; ++ unsigned char isdir; ++ struct au_hinode *p; ++ struct au_iinfo *iinfo; ++ ++ err = au_ii_refresh(inode, &update); ++ if (unlikely(err)) ++ goto out; ++ ++ update = 0; ++ iinfo = au_ii(inode); ++ p = iinfo->ii_hinode + iinfo->ii_bstart; ++ mode = (inode->i_mode & S_IFMT); ++ isdir = S_ISDIR(mode); ++ flags = au_hi_flags(inode, isdir); ++ bend = au_dbend(dentry); ++ for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { ++ struct inode *h_i; ++ struct dentry *h_d; ++ ++ h_d = au_h_dptr(dentry, bindex); ++ if (!h_d || !h_d->d_inode) ++ continue; ++ ++ AuDebugOn(mode != (h_d->d_inode->i_mode & S_IFMT)); ++ if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) { ++ h_i = au_h_iptr(inode, bindex); ++ if (h_i) { ++ if (h_i == h_d->d_inode) ++ continue; ++ err = -EIO; ++ break; ++ } ++ } ++ if (bindex < iinfo->ii_bstart) ++ iinfo->ii_bstart = bindex; ++ if (iinfo->ii_bend < bindex) ++ iinfo->ii_bend = bindex; ++ au_set_h_iptr(inode, bindex, au_igrab(h_d->d_inode), flags); ++ update = 1; ++ } ++ au_update_ibrange(inode, /*do_put_zero*/0); ++ e = au_dy_irefresh(inode); ++ if (unlikely(e && !err)) ++ err = e; ++ if (!err) ++ au_refresh_hinode_attr(inode, update && isdir); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int set_inode(struct inode *inode, struct dentry *dentry) ++{ ++ int err; ++ unsigned int flags; ++ umode_t mode; ++ aufs_bindex_t bindex, bstart, btail; ++ unsigned char isdir; ++ struct dentry *h_dentry; ++ struct inode *h_inode; ++ struct au_iinfo *iinfo; ++ ++ IiMustWriteLock(inode); ++ ++ err = 0; ++ isdir = 0; ++ bstart = au_dbstart(dentry); ++ h_inode = au_h_dptr(dentry, bstart)->d_inode; ++ mode = h_inode->i_mode; ++ switch (mode & S_IFMT) { ++ case S_IFREG: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_iop; ++ inode->i_fop = &aufs_file_fop; ++ err = au_dy_iaop(inode, bstart, h_inode); ++ if (unlikely(err)) ++ goto out; ++ break; ++ case S_IFDIR: ++ isdir = 1; ++ btail = au_dbtaildir(dentry); ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ break; ++ case S_IFLNK: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_symlink_iop; ++ break; ++ case S_IFBLK: ++ case S_IFCHR: ++ case S_IFIFO: ++ case S_IFSOCK: ++ btail = au_dbtail(dentry); ++ inode->i_op = &aufs_iop; ++ init_special_inode(inode, mode, h_inode->i_rdev); ++ break; ++ default: ++ AuIOErr("Unknown file type 0%o\n", mode); ++ err = -EIO; ++ goto out; ++ } ++ ++ /* do not set hnotify for whiteouted dirs (SHWH mode) */ ++ flags = au_hi_flags(inode, isdir); ++ if (au_opt_test(au_mntflags(dentry->d_sb), SHWH) ++ && au_ftest_hi(flags, HNOTIFY) ++ && dentry->d_name.len > AUFS_WH_PFX_LEN ++ && !memcmp(dentry->d_name.name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) ++ au_fclr_hi(flags, HNOTIFY); ++ iinfo = au_ii(inode); ++ iinfo->ii_bstart = bstart; ++ iinfo->ii_bend = btail; ++ for (bindex = bstart; bindex <= btail; bindex++) { ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (h_dentry) ++ au_set_h_iptr(inode, bindex, ++ au_igrab(h_dentry->d_inode), flags); ++ } ++ au_cpup_attr_all(inode, /*force*/1); ++ /* ++ * to force calling aufs_get_acl() every time, ++ * do not call cache_no_acl() for aufs inode. ++ */ ++ ++out: ++ return err; ++} ++ ++/* ++ * successful returns with iinfo write_locked ++ * minus: errno ++ * zero: success, matched ++ * plus: no error, but unmatched ++ */ ++static int reval_inode(struct inode *inode, struct dentry *dentry) ++{ ++ int err; ++ unsigned int gen; ++ struct au_iigen iigen; ++ aufs_bindex_t bindex, bend; ++ struct inode *h_inode, *h_dinode; ++ ++ /* ++ * before this function, if aufs got any iinfo lock, it must be only ++ * one, the parent dir. ++ * it can happen by UDBA and the obsoleted inode number. ++ */ ++ err = -EIO; ++ if (unlikely(inode->i_ino == parent_ino(dentry))) ++ goto out; ++ ++ err = 1; ++ ii_write_lock_new_child(inode); ++ h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode; ++ bend = au_ibend(inode); ++ for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { ++ h_inode = au_h_iptr(inode, bindex); ++ if (!h_inode || h_inode != h_dinode) ++ continue; ++ ++ err = 0; ++ gen = au_iigen(inode, &iigen); ++ if (gen == au_digen(dentry) ++ && !au_ig_ftest(iigen.ig_flags, HALF_REFRESHED)) ++ break; ++ ++ /* fully refresh inode using dentry */ ++ err = au_refresh_hinode(inode, dentry); ++ if (!err) ++ au_update_iigen(inode, /*half*/0); ++ break; ++ } ++ ++ if (unlikely(err)) ++ ii_write_unlock(inode); ++out: ++ return err; ++} ++ ++int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino) ++{ ++ int err; ++ struct mutex *mtx; ++ ++ /* prevent hardlinked inode number from race condition */ ++ mtx = NULL; ++ if (d_type != DT_DIR) { ++ mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx; ++ mutex_lock(mtx); ++ } ++ err = au_xino_read(sb, bindex, h_ino, ino); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!*ino) { ++ err = -EIO; ++ *ino = au_xino_new_ino(sb); ++ if (unlikely(!*ino)) ++ goto out; ++ err = au_xino_write(sb, bindex, h_ino, *ino); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++out: ++ if (mtx) ++ mutex_unlock(mtx); ++ return err; ++} ++ ++/* successful returns with iinfo write_locked */ ++/* todo: return with unlocked? */ ++struct inode *au_new_inode(struct dentry *dentry, int must_new) ++{ ++ struct inode *inode, *h_inode; ++ struct dentry *h_dentry; ++ struct super_block *sb; ++ struct mutex *mtx; ++ ino_t h_ino, ino; ++ int err; ++ aufs_bindex_t bstart; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ h_dentry = au_h_dptr(dentry, bstart); ++ h_inode = h_dentry->d_inode; ++ h_ino = h_inode->i_ino; ++ ++ /* ++ * stop 'race'-ing between hardlinks under different ++ * parents. ++ */ ++ mtx = NULL; ++ if (!S_ISDIR(h_inode->i_mode)) ++ mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx; ++ ++new_ino: ++ if (mtx) ++ mutex_lock(mtx); ++ err = au_xino_read(sb, bstart, h_ino, &ino); ++ inode = ERR_PTR(err); ++ if (unlikely(err)) ++ goto out; ++ ++ if (!ino) { ++ ino = au_xino_new_ino(sb); ++ if (unlikely(!ino)) { ++ inode = ERR_PTR(-EIO); ++ goto out; ++ } ++ } ++ ++ AuDbg("i%lu\n", (unsigned long)ino); ++ inode = au_iget_locked(sb, ino); ++ err = PTR_ERR(inode); ++ if (IS_ERR(inode)) ++ goto out; ++ ++ AuDbg("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); ++ if (inode->i_state & I_NEW) { ++ /* verbose coding for lock class name */ ++ if (unlikely(S_ISLNK(h_inode->i_mode))) ++ au_rw_class(&au_ii(inode)->ii_rwsem, ++ au_lc_key + AuLcSymlink_IIINFO); ++ else if (unlikely(S_ISDIR(h_inode->i_mode))) ++ au_rw_class(&au_ii(inode)->ii_rwsem, ++ au_lc_key + AuLcDir_IIINFO); ++ else /* likely */ ++ au_rw_class(&au_ii(inode)->ii_rwsem, ++ au_lc_key + AuLcNonDir_IIINFO); ++ ++ ii_write_lock_new_child(inode); ++ err = set_inode(inode, dentry); ++ if (!err) { ++ unlock_new_inode(inode); ++ goto out; /* success */ ++ } ++ ++ /* ++ * iget_failed() calls iput(), but we need to call ++ * ii_write_unlock() after iget_failed(). so dirty hack for ++ * i_count. ++ */ ++ atomic_inc(&inode->i_count); ++ iget_failed(inode); ++ ii_write_unlock(inode); ++ au_xino_write(sb, bstart, h_ino, /*ino*/0); ++ /* ignore this error */ ++ goto out_iput; ++ } else if (!must_new && !IS_DEADDIR(inode) && inode->i_nlink) { ++ /* ++ * horrible race condition between lookup, readdir and copyup ++ * (or something). ++ */ ++ if (mtx) ++ mutex_unlock(mtx); ++ err = reval_inode(inode, dentry); ++ if (unlikely(err < 0)) { ++ mtx = NULL; ++ goto out_iput; ++ } ++ ++ if (!err) { ++ mtx = NULL; ++ goto out; /* success */ ++ } else if (mtx) ++ mutex_lock(mtx); ++ } ++ ++ if (unlikely(au_test_fs_unique_ino(h_dentry->d_inode))) ++ AuWarn1("Warning: Un-notified UDBA or repeatedly renamed dir," ++ " b%d, %s, %pd, hi%lu, i%lu.\n", ++ bstart, au_sbtype(h_dentry->d_sb), dentry, ++ (unsigned long)h_ino, (unsigned long)ino); ++ ino = 0; ++ err = au_xino_write(sb, bstart, h_ino, /*ino*/0); ++ if (!err) { ++ iput(inode); ++ if (mtx) ++ mutex_unlock(mtx); ++ goto new_ino; ++ } ++ ++out_iput: ++ iput(inode); ++ inode = ERR_PTR(err); ++out: ++ if (mtx) ++ mutex_unlock(mtx); ++ return inode; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode) ++{ ++ int err; ++ struct inode *hi; ++ ++ err = au_br_rdonly(au_sbr(sb, bindex)); ++ ++ /* pseudo-link after flushed may happen out of bounds */ ++ if (!err ++ && inode ++ && au_ibstart(inode) <= bindex ++ && bindex <= au_ibend(inode)) { ++ /* ++ * permission check is unnecessary since vfsub routine ++ * will be called later ++ */ ++ hi = au_h_iptr(inode, bindex); ++ if (hi) ++ err = IS_IMMUTABLE(hi) ? -EROFS : 0; ++ } ++ ++ return err; ++} ++ ++int au_test_h_perm(struct inode *h_inode, int mask) ++{ ++ if (uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) ++ return 0; ++ return inode_permission(h_inode, mask); ++} ++ ++int au_test_h_perm_sio(struct inode *h_inode, int mask) ++{ ++ if (au_test_nfs(h_inode->i_sb) ++ && (mask & MAY_WRITE) ++ && S_ISDIR(h_inode->i_mode)) ++ mask |= MAY_READ; /* force permission check */ ++ return au_test_h_perm(h_inode, mask); ++} +diff --git a/fs/aufs/inode.h b/fs/aufs/inode.h +new file mode 100644 +index 0000000..7552346 +--- /dev/null ++++ b/fs/aufs/inode.h +@@ -0,0 +1,654 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * inode operations ++ */ ++ ++#ifndef __AUFS_INODE_H__ ++#define __AUFS_INODE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include "rwsem.h" ++ ++struct vfsmount; ++ ++struct au_hnotify { ++#ifdef CONFIG_AUFS_HNOTIFY ++#ifdef CONFIG_AUFS_HFSNOTIFY ++ /* never use fsnotify_add_vfsmount_mark() */ ++ struct fsnotify_mark hn_mark; ++#endif ++ struct inode *hn_aufs_inode; /* no get/put */ ++#endif ++} ____cacheline_aligned_in_smp; ++ ++struct au_hinode { ++ struct inode *hi_inode; ++ aufs_bindex_t hi_id; ++#ifdef CONFIG_AUFS_HNOTIFY ++ struct au_hnotify *hi_notify; ++#endif ++ ++ /* reference to the copied-up whiteout with get/put */ ++ struct dentry *hi_whdentry; ++}; ++ ++/* ig_flags */ ++#define AuIG_HALF_REFRESHED 1 ++#define au_ig_ftest(flags, name) ((flags) & AuIG_##name) ++#define au_ig_fset(flags, name) \ ++ do { (flags) |= AuIG_##name; } while (0) ++#define au_ig_fclr(flags, name) \ ++ do { (flags) &= ~AuIG_##name; } while (0) ++ ++struct au_iigen { ++ __u32 ig_generation, ig_flags; ++}; ++ ++struct au_vdir; ++struct au_iinfo { ++ spinlock_t ii_genspin; ++ struct au_iigen ii_generation; ++ struct super_block *ii_hsb1; /* no get/put */ ++ ++ struct au_rwsem ii_rwsem; ++ aufs_bindex_t ii_bstart, ii_bend; ++ __u32 ii_higen; ++ struct au_hinode *ii_hinode; ++ struct au_vdir *ii_vdir; ++}; ++ ++struct au_icntnr { ++ struct au_iinfo iinfo; ++ struct inode vfs_inode; ++} ____cacheline_aligned_in_smp; ++ ++/* au_pin flags */ ++#define AuPin_DI_LOCKED 1 ++#define AuPin_MNT_WRITE (1 << 1) ++#define au_ftest_pin(flags, name) ((flags) & AuPin_##name) ++#define au_fset_pin(flags, name) \ ++ do { (flags) |= AuPin_##name; } while (0) ++#define au_fclr_pin(flags, name) \ ++ do { (flags) &= ~AuPin_##name; } while (0) ++ ++struct au_pin { ++ /* input */ ++ struct dentry *dentry; ++ unsigned int udba; ++ unsigned char lsc_di, lsc_hi, flags; ++ aufs_bindex_t bindex; ++ ++ /* output */ ++ struct dentry *parent; ++ struct au_hinode *hdir; ++ struct vfsmount *h_mnt; ++ ++ /* temporary unlock/relock for copyup */ ++ struct dentry *h_dentry, *h_parent; ++ struct au_branch *br; ++ struct task_struct *task; ++}; ++ ++void au_pin_hdir_unlock(struct au_pin *p); ++int au_pin_hdir_lock(struct au_pin *p); ++int au_pin_hdir_relock(struct au_pin *p); ++void au_pin_hdir_set_owner(struct au_pin *p, struct task_struct *task); ++void au_pin_hdir_acquire_nest(struct au_pin *p); ++void au_pin_hdir_release(struct au_pin *p); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_iinfo *au_ii(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = &(container_of(inode, struct au_icntnr, vfs_inode)->iinfo); ++ if (iinfo->ii_hinode) ++ return iinfo; ++ return NULL; /* debugging bad_inode case */ ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* inode.c */ ++struct inode *au_igrab(struct inode *inode); ++int au_refresh_hinode_self(struct inode *inode); ++int au_refresh_hinode(struct inode *inode, struct dentry *dentry); ++int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ unsigned int d_type, ino_t *ino); ++struct inode *au_new_inode(struct dentry *dentry, int must_new); ++int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, ++ struct inode *inode); ++int au_test_h_perm(struct inode *h_inode, int mask); ++int au_test_h_perm_sio(struct inode *h_inode, int mask); ++ ++static inline int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ++ ino_t h_ino, unsigned int d_type, ino_t *ino) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ return au_ino(sb, bindex, h_ino, d_type, ino); ++#else ++ return 0; ++#endif ++} ++ ++/* i_op.c */ ++extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop; ++ ++/* au_wr_dir flags */ ++#define AuWrDir_ADD_ENTRY 1 ++#define AuWrDir_TMP_WHENTRY (1 << 1) ++#define AuWrDir_ISDIR (1 << 2) ++#define AuWrDir_TMPFILE (1 << 3) ++#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) ++#define au_fset_wrdir(flags, name) \ ++ do { (flags) |= AuWrDir_##name; } while (0) ++#define au_fclr_wrdir(flags, name) \ ++ do { (flags) &= ~AuWrDir_##name; } while (0) ++ ++struct au_wr_dir_args { ++ aufs_bindex_t force_btgt; ++ unsigned char flags; ++}; ++int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, ++ struct au_wr_dir_args *args); ++ ++struct dentry *au_pinned_h_parent(struct au_pin *pin); ++void au_pin_init(struct au_pin *pin, struct dentry *dentry, ++ aufs_bindex_t bindex, int lsc_di, int lsc_hi, ++ unsigned int udba, unsigned char flags); ++int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int udba, unsigned char flags) __must_check; ++int au_do_pin(struct au_pin *pin) __must_check; ++void au_unpin(struct au_pin *pin); ++int au_reval_for_attr(struct dentry *dentry, unsigned int sigen); ++ ++#define AuIcpup_DID_CPUP 1 ++#define au_ftest_icpup(flags, name) ((flags) & AuIcpup_##name) ++#define au_fset_icpup(flags, name) \ ++ do { (flags) |= AuIcpup_##name; } while (0) ++#define au_fclr_icpup(flags, name) \ ++ do { (flags) &= ~AuIcpup_##name; } while (0) ++ ++struct au_icpup_args { ++ unsigned char flags; ++ unsigned char pin_flags; ++ aufs_bindex_t btgt; ++ unsigned int udba; ++ struct au_pin pin; ++ struct path h_path; ++ struct inode *h_inode; ++}; ++ ++int au_pin_and_icpup(struct dentry *dentry, struct iattr *ia, ++ struct au_icpup_args *a); ++ ++int au_h_path_getattr(struct dentry *dentry, int force, struct path *h_path); ++ ++/* i_op_add.c */ ++int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, ++ dev_t dev); ++int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); ++int aufs_create(struct inode *dir, struct dentry *dentry, umode_t mode, ++ bool want_excl); ++int aufs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode); ++int aufs_link(struct dentry *src_dentry, struct inode *dir, ++ struct dentry *dentry); ++int aufs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode); ++ ++/* i_op_del.c */ ++int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); ++int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent, int isdir); ++int aufs_unlink(struct inode *dir, struct dentry *dentry); ++int aufs_rmdir(struct inode *dir, struct dentry *dentry); ++ ++/* i_op_ren.c */ ++int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); ++int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, ++ struct inode *dir, struct dentry *dentry); ++ ++/* iinfo.c */ ++struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); ++void au_hiput(struct au_hinode *hinode); ++void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_wh); ++unsigned int au_hi_flags(struct inode *inode, int isdir); ++ ++/* hinode flags */ ++#define AuHi_XINO 1 ++#define AuHi_HNOTIFY (1 << 1) ++#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) ++#define au_fset_hi(flags, name) \ ++ do { (flags) |= AuHi_##name; } while (0) ++#define au_fclr_hi(flags, name) \ ++ do { (flags) &= ~AuHi_##name; } while (0) ++ ++#ifndef CONFIG_AUFS_HNOTIFY ++#undef AuHi_HNOTIFY ++#define AuHi_HNOTIFY 0 ++#endif ++ ++void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, ++ struct inode *h_inode, unsigned int flags); ++ ++void au_update_iigen(struct inode *inode, int half); ++void au_update_ibrange(struct inode *inode, int do_put_zero); ++ ++void au_icntnr_init_once(void *_c); ++int au_iinfo_init(struct inode *inode); ++void au_iinfo_fin(struct inode *inode); ++int au_ii_realloc(struct au_iinfo *iinfo, int nbr); ++ ++#ifdef CONFIG_PROC_FS ++/* plink.c */ ++int au_plink_maint(struct super_block *sb, int flags); ++void au_plink_maint_leave(struct au_sbinfo *sbinfo); ++int au_plink_maint_enter(struct super_block *sb); ++#ifdef CONFIG_AUFS_DEBUG ++void au_plink_list(struct super_block *sb); ++#else ++AuStubVoid(au_plink_list, struct super_block *sb) ++#endif ++int au_plink_test(struct inode *inode); ++struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex); ++void au_plink_append(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++void au_plink_put(struct super_block *sb, int verbose); ++void au_plink_clean(struct super_block *sb, int verbose); ++void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); ++#else ++AuStubInt0(au_plink_maint, struct super_block *sb, int flags); ++AuStubVoid(au_plink_maint_leave, struct au_sbinfo *sbinfo); ++AuStubInt0(au_plink_maint_enter, struct super_block *sb); ++AuStubVoid(au_plink_list, struct super_block *sb); ++AuStubInt0(au_plink_test, struct inode *inode); ++AuStub(struct dentry *, au_plink_lkup, return NULL, ++ struct inode *inode, aufs_bindex_t bindex); ++AuStubVoid(au_plink_append, struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry); ++AuStubVoid(au_plink_put, struct super_block *sb, int verbose); ++AuStubVoid(au_plink_clean, struct super_block *sb, int verbose); ++AuStubVoid(au_plink_half_refresh, struct super_block *sb, aufs_bindex_t br_id); ++#endif /* CONFIG_PROC_FS */ ++ ++#ifdef CONFIG_AUFS_XATTR ++/* xattr.c */ ++int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags); ++ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size); ++ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value, ++ size_t size); ++int aufs_setxattr(struct dentry *dentry, const char *name, const void *value, ++ size_t size, int flags); ++int aufs_removexattr(struct dentry *dentry, const char *name); ++ ++/* void au_xattr_init(struct super_block *sb); */ ++#else ++AuStubInt0(au_cpup_xattr, struct dentry *h_dst, struct dentry *h_src, ++ int ignore_flags); ++/* AuStubVoid(au_xattr_init, struct super_block *sb); */ ++#endif ++ ++#ifdef CONFIG_FS_POSIX_ACL ++struct posix_acl *aufs_get_acl(struct inode *inode, int type); ++int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type); ++#endif ++ ++#if IS_ENABLED(CONFIG_AUFS_XATTR) || IS_ENABLED(CONFIG_FS_POSIX_ACL) ++enum { ++ AU_XATTR_SET, ++ AU_XATTR_REMOVE, ++ AU_ACL_SET ++}; ++ ++struct au_srxattr { ++ int type; ++ union { ++ struct { ++ const char *name; ++ const void *value; ++ size_t size; ++ int flags; ++ } set; ++ struct { ++ const char *name; ++ } remove; ++ struct { ++ struct posix_acl *acl; ++ int type; ++ } acl_set; ++ } u; ++}; ++ssize_t au_srxattr(struct dentry *dentry, struct au_srxattr *arg); ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for iinfo */ ++enum { ++ AuLsc_II_CHILD, /* child first */ ++ AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hnotify */ ++ AuLsc_II_CHILD3, /* copyup dirs */ ++ AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ ++ AuLsc_II_PARENT2, ++ AuLsc_II_PARENT3, /* copyup dirs */ ++ AuLsc_II_NEW_CHILD ++}; ++ ++/* ++ * ii_read_lock_child, ii_write_lock_child, ++ * ii_read_lock_child2, ii_write_lock_child2, ++ * ii_read_lock_child3, ii_write_lock_child3, ++ * ii_read_lock_parent, ii_write_lock_parent, ++ * ii_read_lock_parent2, ii_write_lock_parent2, ++ * ii_read_lock_parent3, ii_write_lock_parent3, ++ * ii_read_lock_new_child, ii_write_lock_new_child, ++ */ ++#define AuReadLockFunc(name, lsc) \ ++static inline void ii_read_lock_##name(struct inode *i) \ ++{ \ ++ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuWriteLockFunc(name, lsc) \ ++static inline void ii_write_lock_##name(struct inode *i) \ ++{ \ ++ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); \ ++} ++ ++#define AuRWLockFuncs(name, lsc) \ ++ AuReadLockFunc(name, lsc) \ ++ AuWriteLockFunc(name, lsc) ++ ++AuRWLockFuncs(child, CHILD); ++AuRWLockFuncs(child2, CHILD2); ++AuRWLockFuncs(child3, CHILD3); ++AuRWLockFuncs(parent, PARENT); ++AuRWLockFuncs(parent2, PARENT2); ++AuRWLockFuncs(parent3, PARENT3); ++AuRWLockFuncs(new_child, NEW_CHILD); ++ ++#undef AuReadLockFunc ++#undef AuWriteLockFunc ++#undef AuRWLockFuncs ++ ++/* ++ * ii_read_unlock, ii_write_unlock, ii_downgrade_lock ++ */ ++AuSimpleUnlockRwsemFuncs(ii, struct inode *i, &au_ii(i)->ii_rwsem); ++ ++#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) ++#define IiMustAnyLock(i) AuRwMustAnyLock(&au_ii(i)->ii_rwsem) ++#define IiMustWriteLock(i) AuRwMustWriteLock(&au_ii(i)->ii_rwsem) ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void au_icntnr_init(struct au_icntnr *c) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++ c->vfs_inode.i_mode = 0; ++#endif ++} ++ ++static inline unsigned int au_iigen(struct inode *inode, struct au_iigen *iigen) ++{ ++ unsigned int gen; ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ spin_lock(&iinfo->ii_genspin); ++ if (iigen) ++ *iigen = iinfo->ii_generation; ++ gen = iinfo->ii_generation.ig_generation; ++ spin_unlock(&iinfo->ii_genspin); ++ ++ return gen; ++} ++ ++/* tiny test for inode number */ ++/* tmpfs generation is too rough */ ++static inline int au_test_higen(struct inode *inode, struct inode *h_inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ AuRwMustAnyLock(&iinfo->ii_rwsem); ++ return !(iinfo->ii_hsb1 == h_inode->i_sb ++ && iinfo->ii_higen == h_inode->i_generation); ++} ++ ++static inline void au_iigen_dec(struct inode *inode) ++{ ++ struct au_iinfo *iinfo; ++ ++ iinfo = au_ii(inode); ++ spin_lock(&iinfo->ii_genspin); ++ iinfo->ii_generation.ig_generation--; ++ spin_unlock(&iinfo->ii_genspin); ++} ++ ++static inline int au_iigen_test(struct inode *inode, unsigned int sigen) ++{ ++ int err; ++ ++ err = 0; ++ if (unlikely(inode && au_iigen(inode, NULL) != sigen)) ++ err = -EIO; ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline aufs_bindex_t au_ii_br_id(struct inode *inode, ++ aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_id; ++} ++ ++static inline aufs_bindex_t au_ibstart(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_bstart; ++} ++ ++static inline aufs_bindex_t au_ibend(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_bend; ++} ++ ++static inline struct au_vdir *au_ivdir(struct inode *inode) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_vdir; ++} ++ ++static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode[0 + bindex].hi_whdentry; ++} ++ ++static inline void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_bstart = bindex; ++} ++ ++static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_bend = bindex; ++} ++ ++static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) ++{ ++ IiMustWriteLock(inode); ++ au_ii(inode)->ii_vdir = vdir; ++} ++ ++static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) ++{ ++ IiMustAnyLock(inode); ++ return au_ii(inode)->ii_hinode + bindex; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct dentry *au_pinned_parent(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->parent; ++ return NULL; ++} ++ ++static inline struct inode *au_pinned_h_dir(struct au_pin *pin) ++{ ++ if (pin && pin->hdir) ++ return pin->hdir->hi_inode; ++ return NULL; ++} ++ ++static inline struct au_hinode *au_pinned_hdir(struct au_pin *pin) ++{ ++ if (pin) ++ return pin->hdir; ++ return NULL; ++} ++ ++static inline void au_pin_set_dentry(struct au_pin *pin, struct dentry *dentry) ++{ ++ if (pin) ++ pin->dentry = dentry; ++} ++ ++static inline void au_pin_set_parent_lflag(struct au_pin *pin, ++ unsigned char lflag) ++{ ++ if (pin) { ++ if (lflag) ++ au_fset_pin(pin->flags, DI_LOCKED); ++ else ++ au_fclr_pin(pin->flags, DI_LOCKED); ++ } ++} ++ ++static inline void au_pin_set_parent(struct au_pin *pin, struct dentry *parent) ++{ ++ if (pin) { ++ dput(pin->parent); ++ pin->parent = dget(parent); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_branch; ++#ifdef CONFIG_AUFS_HNOTIFY ++struct au_hnotify_op { ++ void (*ctl)(struct au_hinode *hinode, int do_set); ++ int (*alloc)(struct au_hinode *hinode); ++ ++ /* ++ * if it returns true, the the caller should free hinode->hi_notify, ++ * otherwise ->free() frees it. ++ */ ++ int (*free)(struct au_hinode *hinode, ++ struct au_hnotify *hn) __must_check; ++ ++ void (*fin)(void); ++ int (*init)(void); ++ ++ int (*reset_br)(unsigned int udba, struct au_branch *br, int perm); ++ void (*fin_br)(struct au_branch *br); ++ int (*init_br)(struct au_branch *br, int perm); ++}; ++ ++/* hnotify.c */ ++int au_hn_alloc(struct au_hinode *hinode, struct inode *inode); ++void au_hn_free(struct au_hinode *hinode); ++void au_hn_ctl(struct au_hinode *hinode, int do_set); ++void au_hn_reset(struct inode *inode, unsigned int flags); ++int au_hnotify(struct inode *h_dir, struct au_hnotify *hnotify, u32 mask, ++ struct qstr *h_child_qstr, struct inode *h_child_inode); ++int au_hnotify_reset_br(unsigned int udba, struct au_branch *br, int perm); ++int au_hnotify_init_br(struct au_branch *br, int perm); ++void au_hnotify_fin_br(struct au_branch *br); ++int __init au_hnotify_init(void); ++void au_hnotify_fin(void); ++ ++/* hfsnotify.c */ ++extern const struct au_hnotify_op au_hnotify_op; ++ ++static inline ++void au_hn_init(struct au_hinode *hinode) ++{ ++ hinode->hi_notify = NULL; ++} ++ ++static inline struct au_hnotify *au_hn(struct au_hinode *hinode) ++{ ++ return hinode->hi_notify; ++} ++ ++#else ++AuStub(int, au_hn_alloc, return -EOPNOTSUPP, ++ struct au_hinode *hinode __maybe_unused, ++ struct inode *inode __maybe_unused) ++AuStub(struct au_hnotify *, au_hn, return NULL, struct au_hinode *hinode) ++AuStubVoid(au_hn_free, struct au_hinode *hinode __maybe_unused) ++AuStubVoid(au_hn_ctl, struct au_hinode *hinode __maybe_unused, ++ int do_set __maybe_unused) ++AuStubVoid(au_hn_reset, struct inode *inode __maybe_unused, ++ unsigned int flags __maybe_unused) ++AuStubInt0(au_hnotify_reset_br, unsigned int udba __maybe_unused, ++ struct au_branch *br __maybe_unused, ++ int perm __maybe_unused) ++AuStubInt0(au_hnotify_init_br, struct au_branch *br __maybe_unused, ++ int perm __maybe_unused) ++AuStubVoid(au_hnotify_fin_br, struct au_branch *br __maybe_unused) ++AuStubInt0(__init au_hnotify_init, void) ++AuStubVoid(au_hnotify_fin, void) ++AuStubVoid(au_hn_init, struct au_hinode *hinode __maybe_unused) ++#endif /* CONFIG_AUFS_HNOTIFY */ ++ ++static inline void au_hn_suspend(struct au_hinode *hdir) ++{ ++ au_hn_ctl(hdir, /*do_set*/0); ++} ++ ++static inline void au_hn_resume(struct au_hinode *hdir) ++{ ++ au_hn_ctl(hdir, /*do_set*/1); ++} ++ ++static inline void au_hn_imtx_lock(struct au_hinode *hdir) ++{ ++ mutex_lock(&hdir->hi_inode->i_mutex); ++ au_hn_suspend(hdir); ++} ++ ++static inline void au_hn_imtx_lock_nested(struct au_hinode *hdir, ++ unsigned int sc __maybe_unused) ++{ ++ mutex_lock_nested(&hdir->hi_inode->i_mutex, sc); ++ au_hn_suspend(hdir); ++} ++ ++static inline void au_hn_imtx_unlock(struct au_hinode *hdir) ++{ ++ au_hn_resume(hdir); ++ mutex_unlock(&hdir->hi_inode->i_mutex); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_INODE_H__ */ +diff --git a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c +new file mode 100644 +index 0000000..87e3ddc +--- /dev/null ++++ b/fs/aufs/ioctl.c +@@ -0,0 +1,206 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * ioctl ++ * plink-management and readdir in userspace. ++ * assist the pathconf(3) wrapper library. ++ * move-down ++ * File-based Hierarchical Storage Management. ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg) ++{ ++ int err, fd; ++ aufs_bindex_t wbi, bindex, bend; ++ struct file *h_file; ++ struct super_block *sb; ++ struct dentry *root; ++ struct au_branch *br; ++ struct aufs_wbr_fd wbrfd = { ++ .oflags = au_dir_roflags, ++ .brid = -1 ++ }; ++ const int valid = O_RDONLY | O_NONBLOCK | O_LARGEFILE | O_DIRECTORY ++ | O_NOATIME | O_CLOEXEC; ++ ++ AuDebugOn(wbrfd.oflags & ~valid); ++ ++ if (arg) { ++ err = copy_from_user(&wbrfd, arg, sizeof(wbrfd)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ goto out; ++ } ++ ++ err = -EINVAL; ++ AuDbg("wbrfd{0%o, %d}\n", wbrfd.oflags, wbrfd.brid); ++ wbrfd.oflags |= au_dir_roflags; ++ AuDbg("0%o\n", wbrfd.oflags); ++ if (unlikely(wbrfd.oflags & ~valid)) ++ goto out; ++ } ++ ++ fd = get_unused_fd_flags(0); ++ err = fd; ++ if (unlikely(fd < 0)) ++ goto out; ++ ++ h_file = ERR_PTR(-EINVAL); ++ wbi = 0; ++ br = NULL; ++ sb = path->dentry->d_sb; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_IR); ++ bend = au_sbend(sb); ++ if (wbrfd.brid >= 0) { ++ wbi = au_br_index(sb, wbrfd.brid); ++ if (unlikely(wbi < 0 || wbi > bend)) ++ goto out_unlock; ++ } ++ ++ h_file = ERR_PTR(-ENOENT); ++ br = au_sbr(sb, wbi); ++ if (!au_br_writable(br->br_perm)) { ++ if (arg) ++ goto out_unlock; ++ ++ bindex = wbi + 1; ++ wbi = -1; ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_writable(br->br_perm)) { ++ wbi = bindex; ++ br = au_sbr(sb, wbi); ++ break; ++ } ++ } ++ } ++ AuDbg("wbi %d\n", wbi); ++ if (wbi >= 0) ++ h_file = au_h_open(root, wbi, wbrfd.oflags, NULL, ++ /*force_wr*/0); ++ ++out_unlock: ++ aufs_read_unlock(root, AuLock_IR); ++ err = PTR_ERR(h_file); ++ if (IS_ERR(h_file)) ++ goto out_fd; ++ ++ atomic_dec(&br->br_count); /* cf. au_h_open() */ ++ fd_install(fd, h_file); ++ err = fd; ++ goto out; /* success */ ++ ++out_fd: ++ put_unused_fd(fd); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err; ++ struct dentry *dentry; ++ ++ switch (cmd) { ++ case AUFS_CTL_RDU: ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_ioctl(file, cmd, arg); ++ break; ++ ++ case AUFS_CTL_WBR_FD: ++ err = au_wbr_fd(&file->f_path, (void __user *)arg); ++ break; ++ ++ case AUFS_CTL_IBUSY: ++ err = au_ibusy_ioctl(file, arg); ++ break; ++ ++ case AUFS_CTL_BRINFO: ++ err = au_brinfo_ioctl(file, arg); ++ break; ++ ++ case AUFS_CTL_FHSM_FD: ++ dentry = file->f_path.dentry; ++ if (IS_ROOT(dentry)) ++ err = au_fhsm_fd(dentry->d_sb, arg); ++ else ++ err = -ENOTTY; ++ break; ++ ++ default: ++ /* do not call the lower */ ++ AuDbg("0x%x\n", cmd); ++ err = -ENOTTY; ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err; ++ ++ switch (cmd) { ++ case AUFS_CTL_MVDOWN: ++ err = au_mvdown(file->f_path.dentry, (void __user *)arg); ++ break; ++ ++ case AUFS_CTL_WBR_FD: ++ err = au_wbr_fd(&file->f_path, (void __user *)arg); ++ break; ++ ++ default: ++ /* do not call the lower */ ++ AuDbg("0x%x\n", cmd); ++ err = -ENOTTY; ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++#ifdef CONFIG_COMPAT ++long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ long err; ++ ++ switch (cmd) { ++ case AUFS_CTL_RDU: ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_compat_ioctl(file, cmd, arg); ++ break; ++ ++ case AUFS_CTL_IBUSY: ++ err = au_ibusy_compat_ioctl(file, arg); ++ break; ++ ++ case AUFS_CTL_BRINFO: ++ err = au_brinfo_compat_ioctl(file, arg); ++ break; ++ ++ default: ++ err = aufs_ioctl_dir(file, cmd, arg); ++ } ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); ++} ++#endif +diff --git a/fs/aufs/loop.c b/fs/aufs/loop.c +new file mode 100644 +index 0000000..69f7e96 +--- /dev/null ++++ b/fs/aufs/loop.c +@@ -0,0 +1,132 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * support for loopback block device as a branch ++ */ ++ ++#include "aufs.h" ++ ++/* added into drivers/block/loop.c */ ++static struct file *(*backing_file_func)(struct super_block *sb); ++ ++/* ++ * test if two lower dentries have overlapping branches. ++ */ ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding) ++{ ++ struct super_block *h_sb; ++ struct file *backing_file; ++ ++ if (unlikely(!backing_file_func)) { ++ /* don't load "loop" module here */ ++ backing_file_func = symbol_get(loop_backing_file); ++ if (unlikely(!backing_file_func)) ++ /* "loop" module is not loaded */ ++ return 0; ++ } ++ ++ h_sb = h_adding->d_sb; ++ backing_file = backing_file_func(h_sb); ++ if (!backing_file) ++ return 0; ++ ++ h_adding = backing_file->f_path.dentry; ++ /* ++ * h_adding can be local NFS. ++ * in this case aufs cannot detect the loop. ++ */ ++ if (unlikely(h_adding->d_sb == sb)) ++ return 1; ++ return !!au_test_subdir(h_adding, sb->s_root); ++} ++ ++/* true if a kernel thread named 'loop[0-9].*' accesses a file */ ++int au_test_loopback_kthread(void) ++{ ++ int ret; ++ struct task_struct *tsk = current; ++ char c, comm[sizeof(tsk->comm)]; ++ ++ ret = 0; ++ if (tsk->flags & PF_KTHREAD) { ++ get_task_comm(comm, tsk); ++ c = comm[4]; ++ ret = ('0' <= c && c <= '9' ++ && !strncmp(comm, "loop", 4)); ++ } ++ ++ return ret; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define au_warn_loopback_step 16 ++static int au_warn_loopback_nelem = au_warn_loopback_step; ++static unsigned long *au_warn_loopback_array; ++ ++void au_warn_loopback(struct super_block *h_sb) ++{ ++ int i, new_nelem; ++ unsigned long *a, magic; ++ static DEFINE_SPINLOCK(spin); ++ ++ magic = h_sb->s_magic; ++ spin_lock(&spin); ++ a = au_warn_loopback_array; ++ for (i = 0; i < au_warn_loopback_nelem && *a; i++) ++ if (a[i] == magic) { ++ spin_unlock(&spin); ++ return; ++ } ++ ++ /* h_sb is new to us, print it */ ++ if (i < au_warn_loopback_nelem) { ++ a[i] = magic; ++ goto pr; ++ } ++ ++ /* expand the array */ ++ new_nelem = au_warn_loopback_nelem + au_warn_loopback_step; ++ a = au_kzrealloc(au_warn_loopback_array, ++ au_warn_loopback_nelem * sizeof(unsigned long), ++ new_nelem * sizeof(unsigned long), GFP_ATOMIC); ++ if (a) { ++ au_warn_loopback_nelem = new_nelem; ++ au_warn_loopback_array = a; ++ a[i] = magic; ++ goto pr; ++ } ++ ++ spin_unlock(&spin); ++ AuWarn1("realloc failed, ignored\n"); ++ return; ++ ++pr: ++ spin_unlock(&spin); ++ pr_warn("you may want to try another patch for loopback file " ++ "on %s(0x%lx) branch\n", au_sbtype(h_sb), magic); ++} ++ ++int au_loopback_init(void) ++{ ++ int err; ++ struct super_block *sb __maybe_unused; ++ ++ AuDebugOn(sizeof(sb->s_magic) != sizeof(unsigned long)); ++ ++ err = 0; ++ au_warn_loopback_array = kcalloc(au_warn_loopback_step, ++ sizeof(unsigned long), GFP_NOFS); ++ if (unlikely(!au_warn_loopback_array)) ++ err = -ENOMEM; ++ ++ return err; ++} ++ ++void au_loopback_fin(void) ++{ ++ symbol_put(loop_backing_file); ++ kfree(au_warn_loopback_array); ++} +diff --git a/fs/aufs/loop.h b/fs/aufs/loop.h +new file mode 100644 +index 0000000..6d9864d +--- /dev/null ++++ b/fs/aufs/loop.h +@@ -0,0 +1,39 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * support for loopback mount as a branch ++ */ ++ ++#ifndef __AUFS_LOOP_H__ ++#define __AUFS_LOOP_H__ ++ ++#ifdef __KERNEL__ ++ ++struct dentry; ++struct super_block; ++ ++#ifdef CONFIG_AUFS_BDEV_LOOP ++/* drivers/block/loop.c */ ++struct file *loop_backing_file(struct super_block *sb); ++ ++/* loop.c */ ++int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding); ++int au_test_loopback_kthread(void); ++void au_warn_loopback(struct super_block *h_sb); ++ ++int au_loopback_init(void); ++void au_loopback_fin(void); ++#else ++AuStubInt0(au_test_loopback_overlap, struct super_block *sb, ++ struct dentry *h_adding) ++AuStubInt0(au_test_loopback_kthread, void) ++AuStubVoid(au_warn_loopback, struct super_block *h_sb) ++ ++AuStubInt0(au_loopback_init, void) ++AuStubVoid(au_loopback_fin, void) ++#endif /* BLK_DEV_LOOP */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_LOOP_H__ */ +diff --git a/fs/aufs/magic.mk b/fs/aufs/magic.mk +new file mode 100644 +index 0000000..3e6387b +--- /dev/null ++++ b/fs/aufs/magic.mk +@@ -0,0 +1,54 @@ ++ ++# defined in ${srctree}/fs/fuse/inode.c ++# tristate ++ifdef CONFIG_FUSE_FS ++ccflags-y += -DFUSE_SUPER_MAGIC=0x65735546 ++endif ++ ++# defined in ${srctree}/fs/ocfs2/ocfs2_fs.h ++# tristate ++ifdef CONFIG_OCFS2_FS ++ccflags-y += -DOCFS2_SUPER_MAGIC=0x7461636f ++endif ++ ++# defined in ${srctree}/fs/ocfs2/dlm/userdlm.h ++# tristate ++ifdef CONFIG_OCFS2_FS_O2CB ++ccflags-y += -DDLMFS_MAGIC=0x76a9f425 ++endif ++ ++# defined in ${srctree}/fs/cifs/cifsfs.c ++# tristate ++ifdef CONFIG_CIFS_FS ++ccflags-y += -DCIFS_MAGIC_NUMBER=0xFF534D42 ++endif ++ ++# defined in ${srctree}/fs/xfs/xfs_sb.h ++# tristate ++ifdef CONFIG_XFS_FS ++ccflags-y += -DXFS_SB_MAGIC=0x58465342 ++endif ++ ++# defined in ${srctree}/fs/configfs/mount.c ++# tristate ++ifdef CONFIG_CONFIGFS_FS ++ccflags-y += -DCONFIGFS_MAGIC=0x62656570 ++endif ++ ++# defined in ${srctree}/fs/9p/v9fs.h ++# tristate ++ifdef CONFIG_9P_FS ++ccflags-y += -DV9FS_MAGIC=0x01021997 ++endif ++ ++# defined in ${srctree}/fs/ubifs/ubifs.h ++# tristate ++ifdef CONFIG_UBIFS_FS ++ccflags-y += -DUBIFS_SUPER_MAGIC=0x24051905 ++endif ++ ++# defined in ${srctree}/fs/hfsplus/hfsplus_raw.h ++# tristate ++ifdef CONFIG_HFSPLUS_FS ++ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b ++endif +diff --git a/fs/aufs/module.c b/fs/aufs/module.c +new file mode 100644 +index 0000000..64b6fdc +--- /dev/null ++++ b/fs/aufs/module.c +@@ -0,0 +1,196 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * module global variables and operations ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp) ++{ ++ if (new_sz <= nused) ++ return p; ++ ++ p = krealloc(p, new_sz, gfp); ++ if (p) ++ memset(p + nused, 0, new_sz - nused); ++ return p; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * aufs caches ++ */ ++struct kmem_cache *au_cachep[AuCache_Last]; ++static int __init au_cache_init(void) ++{ ++ au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once); ++ if (au_cachep[AuCache_DINFO]) ++ /* SLAB_DESTROY_BY_RCU */ ++ au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr, ++ au_icntnr_init_once); ++ if (au_cachep[AuCache_ICNTNR]) ++ au_cachep[AuCache_FINFO] = AuCacheCtor(au_finfo, ++ au_fi_init_once); ++ if (au_cachep[AuCache_FINFO]) ++ au_cachep[AuCache_VDIR] = AuCache(au_vdir); ++ if (au_cachep[AuCache_VDIR]) ++ au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); ++ if (au_cachep[AuCache_DEHSTR]) ++ return 0; ++ ++ return -ENOMEM; ++} ++ ++static void au_cache_fin(void) ++{ ++ int i; ++ ++ /* ++ * Make sure all delayed rcu free inodes are flushed before we ++ * destroy cache. ++ */ ++ rcu_barrier(); ++ ++ /* excluding AuCache_HNOTIFY */ ++ BUILD_BUG_ON(AuCache_HNOTIFY + 1 != AuCache_Last); ++ for (i = 0; i < AuCache_HNOTIFY; i++) ++ if (au_cachep[i]) { ++ kmem_cache_destroy(au_cachep[i]); ++ au_cachep[i] = NULL; ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_dir_roflags; ++ ++#ifdef CONFIG_AUFS_SBILIST ++/* ++ * iterate_supers_type() doesn't protect us from ++ * remounting (branch management) ++ */ ++struct au_splhead au_sbilist; ++#endif ++ ++struct lock_class_key au_lc_key[AuLcKey_Last]; ++ ++/* ++ * functions for module interface. ++ */ ++MODULE_LICENSE("GPL"); ++/* MODULE_LICENSE("GPL v2"); */ ++MODULE_AUTHOR("Junjiro R. Okajima "); ++MODULE_DESCRIPTION(AUFS_NAME ++ " -- Advanced multi layered unification filesystem"); ++MODULE_VERSION(AUFS_VERSION); ++ ++/* this module parameter has no meaning when SYSFS is disabled */ ++int sysaufs_brs = 1; ++MODULE_PARM_DESC(brs, "use /fs/aufs/si_*/brN"); ++module_param_named(brs, sysaufs_brs, int, S_IRUGO); ++ ++/* this module parameter has no meaning when USER_NS is disabled */ ++static bool au_userns; ++MODULE_PARM_DESC(allow_userns, "allow unprivileged to mount under userns"); ++module_param_named(allow_userns, au_userns, bool, S_IRUGO); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */ ++ ++int au_seq_path(struct seq_file *seq, struct path *path) ++{ ++ return seq_path(seq, path, au_esc_chars); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int __init aufs_init(void) ++{ ++ int err, i; ++ char *p; ++ ++ p = au_esc_chars; ++ for (i = 1; i <= ' '; i++) ++ *p++ = i; ++ *p++ = '\\'; ++ *p++ = '\x7f'; ++ *p = 0; ++ ++ au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); ++ ++ au_sbilist_init(); ++ sysaufs_brs_init(); ++ au_debug_init(); ++ au_dy_init(); ++ err = sysaufs_init(); ++ if (unlikely(err)) ++ goto out; ++ err = au_procfs_init(); ++ if (unlikely(err)) ++ goto out_sysaufs; ++ err = au_wkq_init(); ++ if (unlikely(err)) ++ goto out_procfs; ++ err = au_loopback_init(); ++ if (unlikely(err)) ++ goto out_wkq; ++ err = au_hnotify_init(); ++ if (unlikely(err)) ++ goto out_loopback; ++ err = au_sysrq_init(); ++ if (unlikely(err)) ++ goto out_hin; ++ err = au_cache_init(); ++ if (unlikely(err)) ++ goto out_sysrq; ++ ++ aufs_fs_type.fs_flags |= au_userns ? FS_USERNS_MOUNT : 0; ++ err = register_filesystem(&aufs_fs_type); ++ if (unlikely(err)) ++ goto out_cache; ++ ++ /* since we define pr_fmt, call printk directly */ ++ printk(KERN_INFO AUFS_NAME " " AUFS_VERSION "\n"); ++ goto out; /* success */ ++ ++out_cache: ++ au_cache_fin(); ++out_sysrq: ++ au_sysrq_fin(); ++out_hin: ++ au_hnotify_fin(); ++out_loopback: ++ au_loopback_fin(); ++out_wkq: ++ au_wkq_fin(); ++out_procfs: ++ au_procfs_fin(); ++out_sysaufs: ++ sysaufs_fin(); ++ au_dy_fin(); ++out: ++ return err; ++} ++ ++static void __exit aufs_exit(void) ++{ ++ unregister_filesystem(&aufs_fs_type); ++ au_cache_fin(); ++ au_sysrq_fin(); ++ au_hnotify_fin(); ++ au_loopback_fin(); ++ au_wkq_fin(); ++ au_procfs_fin(); ++ sysaufs_fin(); ++ au_dy_fin(); ++} ++ ++module_init(aufs_init); ++module_exit(aufs_exit); +diff --git a/fs/aufs/module.h b/fs/aufs/module.h +new file mode 100644 +index 0000000..adee827 +--- /dev/null ++++ b/fs/aufs/module.h +@@ -0,0 +1,91 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * module initialization and module-global ++ */ ++ ++#ifndef __AUFS_MODULE_H__ ++#define __AUFS_MODULE_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++struct path; ++struct seq_file; ++ ++/* module parameters */ ++extern int sysaufs_brs; ++ ++/* ---------------------------------------------------------------------- */ ++ ++extern int au_dir_roflags; ++ ++enum { ++ AuLcNonDir_FIINFO, ++ AuLcNonDir_DIINFO, ++ AuLcNonDir_IIINFO, ++ ++ AuLcDir_FIINFO, ++ AuLcDir_DIINFO, ++ AuLcDir_IIINFO, ++ ++ AuLcSymlink_DIINFO, ++ AuLcSymlink_IIINFO, ++ ++ AuLcKey_Last ++}; ++extern struct lock_class_key au_lc_key[AuLcKey_Last]; ++ ++void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp); ++int au_seq_path(struct seq_file *seq, struct path *path); ++ ++#ifdef CONFIG_PROC_FS ++/* procfs.c */ ++int __init au_procfs_init(void); ++void au_procfs_fin(void); ++#else ++AuStubInt0(au_procfs_init, void); ++AuStubVoid(au_procfs_fin, void); ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* kmem cache */ ++enum { ++ AuCache_DINFO, ++ AuCache_ICNTNR, ++ AuCache_FINFO, ++ AuCache_VDIR, ++ AuCache_DEHSTR, ++ AuCache_HNOTIFY, /* must be last */ ++ AuCache_Last ++}; ++ ++#define AuCacheFlags (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD) ++#define AuCache(type) KMEM_CACHE(type, AuCacheFlags) ++#define AuCacheCtor(type, ctor) \ ++ kmem_cache_create(#type, sizeof(struct type), \ ++ __alignof__(struct type), AuCacheFlags, ctor) ++ ++extern struct kmem_cache *au_cachep[]; ++ ++#define AuCacheFuncs(name, index) \ ++static inline struct au_##name *au_cache_alloc_##name(void) \ ++{ return kmem_cache_alloc(au_cachep[AuCache_##index], GFP_NOFS); } \ ++static inline void au_cache_free_##name(struct au_##name *p) \ ++{ kmem_cache_free(au_cachep[AuCache_##index], p); } ++ ++AuCacheFuncs(dinfo, DINFO); ++AuCacheFuncs(icntnr, ICNTNR); ++AuCacheFuncs(finfo, FINFO); ++AuCacheFuncs(vdir, VDIR); ++AuCacheFuncs(vdir_dehstr, DEHSTR); ++#ifdef CONFIG_AUFS_HNOTIFY ++AuCacheFuncs(hnotify, HNOTIFY); ++#endif ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_MODULE_H__ */ +diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c +new file mode 100644 +index 0000000..ca4e078 +--- /dev/null ++++ b/fs/aufs/mvdown.c +@@ -0,0 +1,681 @@ ++/* ++ * Copyright (C) 2011-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * move-down, opposite of copy-up ++ */ ++ ++#include "aufs.h" ++ ++struct au_mvd_args { ++ struct { ++ struct super_block *h_sb; ++ struct dentry *h_parent; ++ struct au_hinode *hdir; ++ struct inode *h_dir, *h_inode; ++ struct au_pin pin; ++ } info[AUFS_MVDOWN_NARRAY]; ++ ++ struct aufs_mvdown mvdown; ++ struct dentry *dentry, *parent; ++ struct inode *inode, *dir; ++ struct super_block *sb; ++ aufs_bindex_t bopq, bwh, bfound; ++ unsigned char rename_lock; ++}; ++ ++#define mvd_errno mvdown.au_errno ++#define mvd_bsrc mvdown.stbr[AUFS_MVDOWN_UPPER].bindex ++#define mvd_src_brid mvdown.stbr[AUFS_MVDOWN_UPPER].brid ++#define mvd_bdst mvdown.stbr[AUFS_MVDOWN_LOWER].bindex ++#define mvd_dst_brid mvdown.stbr[AUFS_MVDOWN_LOWER].brid ++ ++#define mvd_h_src_sb info[AUFS_MVDOWN_UPPER].h_sb ++#define mvd_h_src_parent info[AUFS_MVDOWN_UPPER].h_parent ++#define mvd_hdir_src info[AUFS_MVDOWN_UPPER].hdir ++#define mvd_h_src_dir info[AUFS_MVDOWN_UPPER].h_dir ++#define mvd_h_src_inode info[AUFS_MVDOWN_UPPER].h_inode ++#define mvd_pin_src info[AUFS_MVDOWN_UPPER].pin ++ ++#define mvd_h_dst_sb info[AUFS_MVDOWN_LOWER].h_sb ++#define mvd_h_dst_parent info[AUFS_MVDOWN_LOWER].h_parent ++#define mvd_hdir_dst info[AUFS_MVDOWN_LOWER].hdir ++#define mvd_h_dst_dir info[AUFS_MVDOWN_LOWER].h_dir ++#define mvd_h_dst_inode info[AUFS_MVDOWN_LOWER].h_inode ++#define mvd_pin_dst info[AUFS_MVDOWN_LOWER].pin ++ ++#define AU_MVD_PR(flag, ...) do { \ ++ if (flag) \ ++ pr_err(__VA_ARGS__); \ ++ } while (0) ++ ++static int find_lower_writable(struct au_mvd_args *a) ++{ ++ struct super_block *sb; ++ aufs_bindex_t bindex, bend; ++ struct au_branch *br; ++ ++ sb = a->sb; ++ bindex = a->mvd_bsrc; ++ bend = au_sbend(sb); ++ if (a->mvdown.flags & AUFS_MVDOWN_FHSM_LOWER) ++ for (bindex++; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_fhsm(br->br_perm) ++ && (!(au_br_sb(br)->s_flags & MS_RDONLY))) ++ return bindex; ++ } ++ else if (!(a->mvdown.flags & AUFS_MVDOWN_ROLOWER)) ++ for (bindex++; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (!au_br_rdonly(br)) ++ return bindex; ++ } ++ else ++ for (bindex++; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (!(au_br_sb(br)->s_flags & MS_RDONLY)) { ++ if (au_br_rdonly(br)) ++ a->mvdown.flags ++ |= AUFS_MVDOWN_ROLOWER_R; ++ return bindex; ++ } ++ } ++ ++ return -1; ++} ++ ++/* make the parent dir on bdst */ ++static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ ++ err = 0; ++ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc); ++ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst); ++ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc); ++ a->mvd_h_dst_parent = NULL; ++ if (au_dbend(a->parent) >= a->mvd_bdst) ++ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); ++ if (!a->mvd_h_dst_parent) { ++ err = au_cpdown_dirs(a->dentry, a->mvd_bdst); ++ if (unlikely(err)) { ++ AU_MVD_PR(dmsg, "cpdown_dirs failed\n"); ++ goto out; ++ } ++ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); ++ } ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* lock them all */ ++static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct dentry *h_trap; ++ ++ a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc); ++ a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst); ++ err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst, ++ au_opt_udba(a->sb), ++ AuPin_MNT_WRITE | AuPin_DI_LOCKED); ++ AuTraceErr(err); ++ if (unlikely(err)) { ++ AU_MVD_PR(dmsg, "pin_dst failed\n"); ++ goto out; ++ } ++ ++ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) { ++ a->rename_lock = 0; ++ au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, ++ AuLsc_DI_PARENT, AuLsc_I_PARENT3, ++ au_opt_udba(a->sb), ++ AuPin_MNT_WRITE | AuPin_DI_LOCKED); ++ err = au_do_pin(&a->mvd_pin_src); ++ AuTraceErr(err); ++ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode; ++ if (unlikely(err)) { ++ AU_MVD_PR(dmsg, "pin_src failed\n"); ++ goto out_dst; ++ } ++ goto out; /* success */ ++ } ++ ++ a->rename_lock = 1; ++ au_pin_hdir_unlock(&a->mvd_pin_dst); ++ err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, ++ au_opt_udba(a->sb), ++ AuPin_MNT_WRITE | AuPin_DI_LOCKED); ++ AuTraceErr(err); ++ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode; ++ if (unlikely(err)) { ++ AU_MVD_PR(dmsg, "pin_src failed\n"); ++ au_pin_hdir_lock(&a->mvd_pin_dst); ++ goto out_dst; ++ } ++ au_pin_hdir_unlock(&a->mvd_pin_src); ++ h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, ++ a->mvd_h_dst_parent, a->mvd_hdir_dst); ++ if (h_trap) { ++ err = (h_trap != a->mvd_h_src_parent); ++ if (err) ++ err = (h_trap != a->mvd_h_dst_parent); ++ } ++ BUG_ON(err); /* it should never happen */ ++ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) { ++ err = -EBUSY; ++ AuTraceErr(err); ++ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, ++ a->mvd_h_dst_parent, a->mvd_hdir_dst); ++ au_pin_hdir_lock(&a->mvd_pin_src); ++ au_unpin(&a->mvd_pin_src); ++ au_pin_hdir_lock(&a->mvd_pin_dst); ++ goto out_dst; ++ } ++ goto out; /* success */ ++ ++out_dst: ++ au_unpin(&a->mvd_pin_dst); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ if (!a->rename_lock) ++ au_unpin(&a->mvd_pin_src); ++ else { ++ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, ++ a->mvd_h_dst_parent, a->mvd_hdir_dst); ++ au_pin_hdir_lock(&a->mvd_pin_src); ++ au_unpin(&a->mvd_pin_src); ++ au_pin_hdir_lock(&a->mvd_pin_dst); ++ } ++ au_unpin(&a->mvd_pin_dst); ++} ++ ++/* copy-down the file */ ++static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct au_cp_generic cpg = { ++ .dentry = a->dentry, ++ .bdst = a->mvd_bdst, ++ .bsrc = a->mvd_bsrc, ++ .len = -1, ++ .pin = &a->mvd_pin_dst, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN ++ }; ++ ++ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst); ++ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER) ++ au_fset_cpup(cpg.flags, OVERWRITE); ++ if (a->mvdown.flags & AUFS_MVDOWN_ROLOWER) ++ au_fset_cpup(cpg.flags, RWDST); ++ err = au_sio_cpdown_simple(&cpg); ++ if (unlikely(err)) ++ AU_MVD_PR(dmsg, "cpdown failed\n"); ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ++ * unlink the whiteout on bdst if exist which may be created by UDBA while we ++ * were sleeping ++ */ ++static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct path h_path; ++ struct au_branch *br; ++ struct inode *delegated; ++ ++ br = au_sbr(a->sb, a->mvd_bdst); ++ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) { ++ AU_MVD_PR(dmsg, "wh_lkup failed\n"); ++ goto out; ++ } ++ ++ err = 0; ++ if (h_path.dentry->d_inode) { ++ h_path.mnt = au_br_mnt(br); ++ delegated = NULL; ++ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path, ++ &delegated, /*force*/0); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal unlink\n"); ++ iput(delegated); ++ } ++ if (unlikely(err)) ++ AU_MVD_PR(dmsg, "wh_unlink failed\n"); ++ } ++ dput(h_path.dentry); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ++ * unlink the topmost h_dentry ++ */ ++static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct path h_path; ++ struct inode *delegated; ++ ++ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc); ++ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc); ++ delegated = NULL; ++ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, &delegated, /*force*/0); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal unlink\n"); ++ iput(delegated); ++ } ++ if (unlikely(err)) ++ AU_MVD_PR(dmsg, "unlink failed\n"); ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* Since mvdown succeeded, we ignore an error of this function */ ++static void au_do_stfs(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct au_branch *br; ++ ++ a->mvdown.flags |= AUFS_MVDOWN_STFS_FAILED; ++ br = au_sbr(a->sb, a->mvd_bsrc); ++ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_UPPER].stfs); ++ if (!err) { ++ br = au_sbr(a->sb, a->mvd_bdst); ++ a->mvdown.stbr[AUFS_MVDOWN_LOWER].brid = br->br_id; ++ err = au_br_stfs(br, &a->mvdown.stbr[AUFS_MVDOWN_LOWER].stfs); ++ } ++ if (!err) ++ a->mvdown.flags &= ~AUFS_MVDOWN_STFS_FAILED; ++ else ++ AU_MVD_PR(dmsg, "statfs failed (%d), ignored\n", err); ++} ++ ++/* ++ * copy-down the file and unlink the bsrc file. ++ * - unlink the bdst whout if exist ++ * - copy-down the file (with whtmp name and rename) ++ * - unlink the bsrc file ++ */ ++static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ ++ err = au_do_mkdir(dmsg, a); ++ if (!err) ++ err = au_do_lock(dmsg, a); ++ if (unlikely(err)) ++ goto out; ++ ++ /* ++ * do not revert the activities we made on bdst since they should be ++ * harmless in aufs. ++ */ ++ ++ err = au_do_cpdown(dmsg, a); ++ if (!err) ++ err = au_do_unlink_wh(dmsg, a); ++ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) ++ err = au_do_unlink(dmsg, a); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ AuDbg("%pd2, 0x%x, %d --> %d\n", ++ a->dentry, a->mvdown.flags, a->mvd_bsrc, a->mvd_bdst); ++ if (find_lower_writable(a) < 0) ++ a->mvdown.flags |= AUFS_MVDOWN_BOTTOM; ++ ++ if (a->mvdown.flags & AUFS_MVDOWN_STFS) ++ au_do_stfs(dmsg, a); ++ ++ /* maintain internal array */ ++ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) { ++ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL); ++ au_set_dbstart(a->dentry, a->mvd_bdst); ++ au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0); ++ au_set_ibstart(a->inode, a->mvd_bdst); ++ } ++ if (au_dbend(a->dentry) < a->mvd_bdst) ++ au_set_dbend(a->dentry, a->mvd_bdst); ++ if (au_ibend(a->inode) < a->mvd_bdst) ++ au_set_ibend(a->inode, a->mvd_bdst); ++ ++out_unlock: ++ au_do_unlock(dmsg, a); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* make sure the file is idle */ ++static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err, plinked; ++ ++ err = 0; ++ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK); ++ if (au_dbstart(a->dentry) == a->mvd_bsrc ++ && au_dcount(a->dentry) == 1 ++ && atomic_read(&a->inode->i_count) == 1 ++ /* && a->mvd_h_src_inode->i_nlink == 1 */ ++ && (!plinked || !au_plink_test(a->inode)) ++ && a->inode->i_nlink == 1) ++ goto out; ++ ++ err = -EBUSY; ++ AU_MVD_PR(dmsg, ++ "b%d, d{b%d, c%d?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n", ++ a->mvd_bsrc, au_dbstart(a->dentry), au_dcount(a->dentry), ++ atomic_read(&a->inode->i_count), a->inode->i_nlink, ++ a->mvd_h_src_inode->i_nlink, ++ plinked, plinked ? au_plink_test(a->inode) : 0); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* make sure the parent dir is fine */ ++static int au_mvd_args_parent(const unsigned char dmsg, ++ struct au_mvd_args *a) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ ++ err = 0; ++ if (unlikely(au_alive_dir(a->parent))) { ++ err = -ENOENT; ++ AU_MVD_PR(dmsg, "parent dir is dead\n"); ++ goto out; ++ } ++ ++ a->bopq = au_dbdiropq(a->parent); ++ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst); ++ AuDbg("b%d\n", bindex); ++ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst) ++ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) { ++ err = -EINVAL; ++ a->mvd_errno = EAU_MVDOWN_OPAQUE; ++ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n", ++ a->bopq, a->mvd_bdst); ++ } ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_mvd_args_intermediate(const unsigned char dmsg, ++ struct au_mvd_args *a) ++{ ++ int err; ++ struct au_dinfo *dinfo, *tmp; ++ ++ /* lookup the next lower positive entry */ ++ err = -ENOMEM; ++ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP); ++ if (unlikely(!tmp)) ++ goto out; ++ ++ a->bfound = -1; ++ a->bwh = -1; ++ dinfo = au_di(a->dentry); ++ au_di_cp(tmp, dinfo); ++ au_di_swap(tmp, dinfo); ++ ++ /* returns the number of positive dentries */ ++ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0); ++ if (!err) ++ a->bwh = au_dbwh(a->dentry); ++ else if (err > 0) ++ a->bfound = au_dbstart(a->dentry); ++ ++ au_di_swap(tmp, dinfo); ++ au_rw_write_unlock(&tmp->di_rwsem); ++ au_di_free(tmp); ++ if (unlikely(err < 0)) ++ AU_MVD_PR(dmsg, "failed look-up lower\n"); ++ ++ /* ++ * here, we have these cases. ++ * bfound == -1 ++ * no positive dentry under bsrc. there are more sub-cases. ++ * bwh < 0 ++ * there no whiteout, we can safely move-down. ++ * bwh <= bsrc ++ * impossible ++ * bsrc < bwh && bwh < bdst ++ * there is a whiteout on RO branch. cannot proceed. ++ * bwh == bdst ++ * there is a whiteout on the RW target branch. it should ++ * be removed. ++ * bdst < bwh ++ * there is a whiteout somewhere unrelated branch. ++ * -1 < bfound && bfound <= bsrc ++ * impossible. ++ * bfound < bdst ++ * found, but it is on RO branch between bsrc and bdst. cannot ++ * proceed. ++ * bfound == bdst ++ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return ++ * error. ++ * bdst < bfound ++ * found, after we create the file on bdst, it will be hidden. ++ */ ++ ++ AuDebugOn(a->bfound == -1 ++ && a->bwh != -1 ++ && a->bwh <= a->mvd_bsrc); ++ AuDebugOn(-1 < a->bfound ++ && a->bfound <= a->mvd_bsrc); ++ ++ err = -EINVAL; ++ if (a->bfound == -1 ++ && a->mvd_bsrc < a->bwh ++ && a->bwh != -1 ++ && a->bwh < a->mvd_bdst) { ++ a->mvd_errno = EAU_MVDOWN_WHITEOUT; ++ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n", ++ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh); ++ goto out; ++ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) { ++ a->mvd_errno = EAU_MVDOWN_UPPER; ++ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n", ++ a->mvd_bdst, a->bfound); ++ goto out; ++ } ++ ++ err = 0; /* success */ ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ ++ err = 0; ++ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER) ++ && a->bfound == a->mvd_bdst) ++ err = -EEXIST; ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct au_branch *br; ++ ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(a->inode->i_mode))) ++ goto out; ++ ++ err = -EINVAL; ++ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_UPPER)) ++ a->mvd_bsrc = au_ibstart(a->inode); ++ else { ++ a->mvd_bsrc = au_br_index(a->sb, a->mvd_src_brid); ++ if (unlikely(a->mvd_bsrc < 0 ++ || (a->mvd_bsrc < au_dbstart(a->dentry) ++ || au_dbend(a->dentry) < a->mvd_bsrc ++ || !au_h_dptr(a->dentry, a->mvd_bsrc)) ++ || (a->mvd_bsrc < au_ibstart(a->inode) ++ || au_ibend(a->inode) < a->mvd_bsrc ++ || !au_h_iptr(a->inode, a->mvd_bsrc)))) { ++ a->mvd_errno = EAU_MVDOWN_NOUPPER; ++ AU_MVD_PR(dmsg, "no upper\n"); ++ goto out; ++ } ++ } ++ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) { ++ a->mvd_errno = EAU_MVDOWN_BOTTOM; ++ AU_MVD_PR(dmsg, "on the bottom\n"); ++ goto out; ++ } ++ a->mvd_h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc); ++ br = au_sbr(a->sb, a->mvd_bsrc); ++ err = au_br_rdonly(br); ++ if (!(a->mvdown.flags & AUFS_MVDOWN_ROUPPER)) { ++ if (unlikely(err)) ++ goto out; ++ } else if (!(vfsub_native_ro(a->mvd_h_src_inode) ++ || IS_APPEND(a->mvd_h_src_inode))) { ++ if (err) ++ a->mvdown.flags |= AUFS_MVDOWN_ROUPPER_R; ++ /* go on */ ++ } else ++ goto out; ++ ++ err = -EINVAL; ++ if (!(a->mvdown.flags & AUFS_MVDOWN_BRID_LOWER)) { ++ a->mvd_bdst = find_lower_writable(a); ++ if (unlikely(a->mvd_bdst < 0)) { ++ a->mvd_errno = EAU_MVDOWN_BOTTOM; ++ AU_MVD_PR(dmsg, "no writable lower branch\n"); ++ goto out; ++ } ++ } else { ++ a->mvd_bdst = au_br_index(a->sb, a->mvd_dst_brid); ++ if (unlikely(a->mvd_bdst < 0 ++ || au_sbend(a->sb) < a->mvd_bdst)) { ++ a->mvd_errno = EAU_MVDOWN_NOLOWERBR; ++ AU_MVD_PR(dmsg, "no lower brid\n"); ++ goto out; ++ } ++ } ++ ++ err = au_mvd_args_busy(dmsg, a); ++ if (!err) ++ err = au_mvd_args_parent(dmsg, a); ++ if (!err) ++ err = au_mvd_args_intermediate(dmsg, a); ++ if (!err) ++ err = au_mvd_args_exist(dmsg, a); ++ if (!err) ++ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) ++{ ++ int err, e; ++ unsigned char dmsg; ++ struct au_mvd_args *args; ++ ++ err = -EPERM; ++ if (unlikely(!capable(CAP_SYS_ADMIN))) ++ goto out; ++ ++ err = -ENOMEM; ++ args = kmalloc(sizeof(*args), GFP_NOFS); ++ if (unlikely(!args)) ++ goto out; ++ ++ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown)); ++ if (!err) ++ err = !access_ok(VERIFY_WRITE, uarg, sizeof(*uarg)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out_free; ++ } ++ AuDbg("flags 0x%x\n", args->mvdown.flags); ++ args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R); ++ args->mvdown.au_errno = 0; ++ args->dentry = dentry; ++ args->inode = dentry->d_inode; ++ args->sb = dentry->d_sb; ++ ++ err = -ENOENT; ++ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG); ++ args->parent = dget_parent(dentry); ++ args->dir = args->parent->d_inode; ++ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT); ++ dput(args->parent); ++ if (unlikely(args->parent != dentry->d_parent)) { ++ AU_MVD_PR(dmsg, "parent dir is moved\n"); ++ goto out_dir; ++ } ++ ++ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD); ++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH); ++ if (unlikely(err)) ++ goto out_inode; ++ ++ di_write_lock_parent(args->parent); ++ err = au_mvd_args(dmsg, args); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ err = au_do_mvdown(dmsg, args); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ au_cpup_attr_timesizes(args->dir); ++ au_cpup_attr_timesizes(args->inode); ++ au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst)); ++ /* au_digen_dec(dentry); */ ++ ++out_parent: ++ di_write_unlock(args->parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++out_inode: ++ mutex_unlock(&args->inode->i_mutex); ++out_dir: ++ mutex_unlock(&args->dir->i_mutex); ++out_free: ++ e = copy_to_user(uarg, &args->mvdown, sizeof(args->mvdown)); ++ if (unlikely(e)) ++ err = -EFAULT; ++ kfree(args); ++out: ++ AuTraceErr(err); ++ return err; ++} +diff --git a/fs/aufs/opts.c b/fs/aufs/opts.c +new file mode 100644 +index 0000000..78bb06c +--- /dev/null ++++ b/fs/aufs/opts.c +@@ -0,0 +1,1837 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * mount options/flags ++ */ ++ ++#include ++#include /* a distribution requires */ ++#include ++#include "aufs.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { ++ Opt_br, ++ Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend, ++ Opt_idel, Opt_imod, Opt_ireorder, ++ Opt_dirwh, Opt_rdcache, Opt_rdblk, Opt_rdhash, Opt_rendir, ++ Opt_rdblk_def, Opt_rdhash_def, ++ Opt_xino, Opt_zxino, Opt_noxino, ++ Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, ++ Opt_trunc_xino_path, Opt_itrunc_xino, ++ Opt_trunc_xib, Opt_notrunc_xib, ++ Opt_shwh, Opt_noshwh, ++ Opt_plink, Opt_noplink, Opt_list_plink, ++ Opt_udba, ++ Opt_dio, Opt_nodio, ++ /* Opt_lock, Opt_unlock, */ ++ Opt_cmd, Opt_cmd_args, ++ Opt_diropq_a, Opt_diropq_w, ++ Opt_warn_perm, Opt_nowarn_perm, ++ Opt_wbr_copyup, Opt_wbr_create, ++ Opt_fhsm_sec, ++ Opt_refrof, Opt_norefrof, ++ Opt_verbose, Opt_noverbose, ++ Opt_sum, Opt_nosum, Opt_wsum, ++ Opt_dirperm1, Opt_nodirperm1, ++ Opt_acl, Opt_noacl, ++ Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err ++}; ++ ++static match_table_t options = { ++ {Opt_br, "br=%s"}, ++ {Opt_br, "br:%s"}, ++ ++ {Opt_add, "add=%d:%s"}, ++ {Opt_add, "add:%d:%s"}, ++ {Opt_add, "ins=%d:%s"}, ++ {Opt_add, "ins:%d:%s"}, ++ {Opt_append, "append=%s"}, ++ {Opt_append, "append:%s"}, ++ {Opt_prepend, "prepend=%s"}, ++ {Opt_prepend, "prepend:%s"}, ++ ++ {Opt_del, "del=%s"}, ++ {Opt_del, "del:%s"}, ++ /* {Opt_idel, "idel:%d"}, */ ++ {Opt_mod, "mod=%s"}, ++ {Opt_mod, "mod:%s"}, ++ /* {Opt_imod, "imod:%d:%s"}, */ ++ ++ {Opt_dirwh, "dirwh=%d"}, ++ ++ {Opt_xino, "xino=%s"}, ++ {Opt_noxino, "noxino"}, ++ {Opt_trunc_xino, "trunc_xino"}, ++ {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, ++ {Opt_notrunc_xino, "notrunc_xino"}, ++ {Opt_trunc_xino_path, "trunc_xino=%s"}, ++ {Opt_itrunc_xino, "itrunc_xino=%d"}, ++ /* {Opt_zxino, "zxino=%s"}, */ ++ {Opt_trunc_xib, "trunc_xib"}, ++ {Opt_notrunc_xib, "notrunc_xib"}, ++ ++#ifdef CONFIG_PROC_FS ++ {Opt_plink, "plink"}, ++#else ++ {Opt_ignore_silent, "plink"}, ++#endif ++ ++ {Opt_noplink, "noplink"}, ++ ++#ifdef CONFIG_AUFS_DEBUG ++ {Opt_list_plink, "list_plink"}, ++#endif ++ ++ {Opt_udba, "udba=%s"}, ++ ++ {Opt_dio, "dio"}, ++ {Opt_nodio, "nodio"}, ++ ++#ifdef CONFIG_AUFS_FHSM ++ {Opt_fhsm_sec, "fhsm_sec=%d"}, ++#else ++ {Opt_ignore_silent, "fhsm_sec=%d"}, ++#endif ++ ++ {Opt_diropq_a, "diropq=always"}, ++ {Opt_diropq_a, "diropq=a"}, ++ {Opt_diropq_w, "diropq=whiteouted"}, ++ {Opt_diropq_w, "diropq=w"}, ++ ++ {Opt_warn_perm, "warn_perm"}, ++ {Opt_nowarn_perm, "nowarn_perm"}, ++ ++ /* keep them temporary */ ++ {Opt_ignore_silent, "nodlgt"}, ++ {Opt_ignore_silent, "clean_plink"}, ++ ++#ifdef CONFIG_AUFS_SHWH ++ {Opt_shwh, "shwh"}, ++#endif ++ {Opt_noshwh, "noshwh"}, ++ ++ {Opt_dirperm1, "dirperm1"}, ++ {Opt_nodirperm1, "nodirperm1"}, ++ ++ {Opt_rendir, "rendir=%d"}, ++ ++ {Opt_refrof, "refrof"}, ++ {Opt_norefrof, "norefrof"}, ++ ++ {Opt_verbose, "verbose"}, ++ {Opt_verbose, "v"}, ++ {Opt_noverbose, "noverbose"}, ++ {Opt_noverbose, "quiet"}, ++ {Opt_noverbose, "q"}, ++ {Opt_noverbose, "silent"}, ++ ++ {Opt_sum, "sum"}, ++ {Opt_nosum, "nosum"}, ++ {Opt_wsum, "wsum"}, ++ ++ {Opt_rdcache, "rdcache=%d"}, ++ {Opt_rdblk, "rdblk=%d"}, ++ {Opt_rdblk_def, "rdblk=def"}, ++ {Opt_rdhash, "rdhash=%d"}, ++ {Opt_rdhash_def, "rdhash=def"}, ++ ++ {Opt_wbr_create, "create=%s"}, ++ {Opt_wbr_create, "create_policy=%s"}, ++ {Opt_wbr_copyup, "cpup=%s"}, ++ {Opt_wbr_copyup, "copyup=%s"}, ++ {Opt_wbr_copyup, "copyup_policy=%s"}, ++ ++ /* generic VFS flag */ ++#ifdef CONFIG_FS_POSIX_ACL ++ {Opt_acl, "acl"}, ++ {Opt_noacl, "noacl"}, ++#else ++ {Opt_ignore_silent, "acl"}, ++ {Opt_ignore_silent, "noacl"}, ++#endif ++ ++ /* internal use for the scripts */ ++ {Opt_ignore_silent, "si=%s"}, ++ ++ {Opt_br, "dirs=%s"}, ++ {Opt_ignore, "debug=%d"}, ++ {Opt_ignore, "delete=whiteout"}, ++ {Opt_ignore, "delete=all"}, ++ {Opt_ignore, "imap=%s"}, ++ ++ /* temporary workaround, due to old mount(8)? */ ++ {Opt_ignore_silent, "relatime"}, ++ ++ {Opt_err, NULL} ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static const char *au_parser_pattern(int val, match_table_t tbl) ++{ ++ struct match_token *p; ++ ++ p = tbl; ++ while (p->pattern) { ++ if (p->token == val) ++ return p->pattern; ++ p++; ++ } ++ BUG(); ++ return "??"; ++} ++ ++static const char *au_optstr(int *val, match_table_t tbl) ++{ ++ struct match_token *p; ++ int v; ++ ++ v = *val; ++ p = tbl; ++ while (p->token) { ++ if ((v & p->token) == p->token) { ++ *val &= ~p->token; ++ return p->pattern; ++ } ++ p++; ++ } ++ return NULL; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t brperm = { ++ {AuBrPerm_RO, AUFS_BRPERM_RO}, ++ {AuBrPerm_RR, AUFS_BRPERM_RR}, ++ {AuBrPerm_RW, AUFS_BRPERM_RW}, ++ {0, NULL} ++}; ++ ++static match_table_t brattr = { ++ /* general */ ++ {AuBrAttr_COO_REG, AUFS_BRATTR_COO_REG}, ++ {AuBrAttr_COO_ALL, AUFS_BRATTR_COO_ALL}, ++ /* 'unpin' attrib is meaningless since linux-3.18-rc1 */ ++ {AuBrAttr_UNPIN, AUFS_BRATTR_UNPIN}, ++ {AuBrAttr_FHSM, AUFS_BRATTR_FHSM}, ++ {AuBrAttr_ICEX, AUFS_BRATTR_ICEX}, ++ {AuBrAttr_ICEX_SEC, AUFS_BRATTR_ICEX_SEC}, ++ {AuBrAttr_ICEX_SYS, AUFS_BRATTR_ICEX_SYS}, ++ {AuBrAttr_ICEX_TR, AUFS_BRATTR_ICEX_TR}, ++ {AuBrAttr_ICEX_USR, AUFS_BRATTR_ICEX_USR}, ++ {AuBrAttr_ICEX_OTH, AUFS_BRATTR_ICEX_OTH}, ++ ++ /* ro/rr branch */ ++ {AuBrRAttr_WH, AUFS_BRRATTR_WH}, ++ ++ /* rw branch */ ++ {AuBrWAttr_MOO, AUFS_BRWATTR_MOO}, ++ {AuBrWAttr_NoLinkWH, AUFS_BRWATTR_NLWH}, ++ ++ {0, NULL} ++}; ++ ++static int br_attr_val(char *str, match_table_t table, substring_t args[]) ++{ ++ int attr, v; ++ char *p; ++ ++ attr = 0; ++ do { ++ p = strchr(str, '+'); ++ if (p) ++ *p = 0; ++ v = match_token(str, table, args); ++ if (v) { ++ if (v & AuBrAttr_CMOO_Mask) ++ attr &= ~AuBrAttr_CMOO_Mask; ++ attr |= v; ++ } else { ++ if (p) ++ *p = '+'; ++ pr_warn("ignored branch attribute %s\n", str); ++ break; ++ } ++ if (p) ++ str = p + 1; ++ } while (p); ++ ++ return attr; ++} ++ ++static int au_do_optstr_br_attr(au_br_perm_str_t *str, int perm) ++{ ++ int sz; ++ const char *p; ++ char *q; ++ ++ q = str->a; ++ *q = 0; ++ p = au_optstr(&perm, brattr); ++ if (p) { ++ sz = strlen(p); ++ memcpy(q, p, sz + 1); ++ q += sz; ++ } else ++ goto out; ++ ++ do { ++ p = au_optstr(&perm, brattr); ++ if (p) { ++ *q++ = '+'; ++ sz = strlen(p); ++ memcpy(q, p, sz + 1); ++ q += sz; ++ } ++ } while (p); ++ ++out: ++ return q - str->a; ++} ++ ++static int noinline_for_stack br_perm_val(char *perm) ++{ ++ int val, bad, sz; ++ char *p; ++ substring_t args[MAX_OPT_ARGS]; ++ au_br_perm_str_t attr; ++ ++ p = strchr(perm, '+'); ++ if (p) ++ *p = 0; ++ val = match_token(perm, brperm, args); ++ if (!val) { ++ if (p) ++ *p = '+'; ++ pr_warn("ignored branch permission %s\n", perm); ++ val = AuBrPerm_RO; ++ goto out; ++ } ++ if (!p) ++ goto out; ++ ++ val |= br_attr_val(p + 1, brattr, args); ++ ++ bad = 0; ++ switch (val & AuBrPerm_Mask) { ++ case AuBrPerm_RO: ++ case AuBrPerm_RR: ++ bad = val & AuBrWAttr_Mask; ++ val &= ~AuBrWAttr_Mask; ++ break; ++ case AuBrPerm_RW: ++ bad = val & AuBrRAttr_Mask; ++ val &= ~AuBrRAttr_Mask; ++ break; ++ } ++ ++ /* ++ * 'unpin' attrib becomes meaningless since linux-3.18-rc1, but aufs ++ * does not treat it as an error, just warning. ++ * this is a tiny guard for the user operation. ++ */ ++ if (val & AuBrAttr_UNPIN) { ++ bad |= AuBrAttr_UNPIN; ++ val &= ~AuBrAttr_UNPIN; ++ } ++ ++ if (unlikely(bad)) { ++ sz = au_do_optstr_br_attr(&attr, bad); ++ AuDebugOn(!sz); ++ pr_warn("ignored branch attribute %s\n", attr.a); ++ } ++ ++out: ++ return val; ++} ++ ++void au_optstr_br_perm(au_br_perm_str_t *str, int perm) ++{ ++ au_br_perm_str_t attr; ++ const char *p; ++ char *q; ++ int sz; ++ ++ q = str->a; ++ p = au_optstr(&perm, brperm); ++ AuDebugOn(!p || !*p); ++ sz = strlen(p); ++ memcpy(q, p, sz + 1); ++ q += sz; ++ ++ sz = au_do_optstr_br_attr(&attr, perm); ++ if (sz) { ++ *q++ = '+'; ++ memcpy(q, attr.a, sz + 1); ++ } ++ ++ AuDebugOn(strlen(str->a) >= sizeof(str->a)); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t udbalevel = { ++ {AuOpt_UDBA_REVAL, "reval"}, ++ {AuOpt_UDBA_NONE, "none"}, ++#ifdef CONFIG_AUFS_HNOTIFY ++ {AuOpt_UDBA_HNOTIFY, "notify"}, /* abstraction */ ++#ifdef CONFIG_AUFS_HFSNOTIFY ++ {AuOpt_UDBA_HNOTIFY, "fsnotify"}, ++#endif ++#endif ++ {-1, NULL} ++}; ++ ++static int noinline_for_stack udba_val(char *str) ++{ ++ substring_t args[MAX_OPT_ARGS]; ++ ++ return match_token(str, udbalevel, args); ++} ++ ++const char *au_optstr_udba(int udba) ++{ ++ return au_parser_pattern(udba, udbalevel); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static match_table_t au_wbr_create_policy = { ++ {AuWbrCreate_TDP, "tdp"}, ++ {AuWbrCreate_TDP, "top-down-parent"}, ++ {AuWbrCreate_RR, "rr"}, ++ {AuWbrCreate_RR, "round-robin"}, ++ {AuWbrCreate_MFS, "mfs"}, ++ {AuWbrCreate_MFS, "most-free-space"}, ++ {AuWbrCreate_MFSV, "mfs:%d"}, ++ {AuWbrCreate_MFSV, "most-free-space:%d"}, ++ ++ {AuWbrCreate_MFSRR, "mfsrr:%d"}, ++ {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"}, ++ {AuWbrCreate_PMFS, "pmfs"}, ++ {AuWbrCreate_PMFSV, "pmfs:%d"}, ++ {AuWbrCreate_PMFSRR, "pmfsrr:%d"}, ++ {AuWbrCreate_PMFSRRV, "pmfsrr:%d:%d"}, ++ ++ {-1, NULL} ++}; ++ ++/* ++ * cf. linux/lib/parser.c and cmdline.c ++ * gave up calling memparse() since it uses simple_strtoull() instead of ++ * kstrto...(). ++ */ ++static int noinline_for_stack ++au_match_ull(substring_t *s, unsigned long long *result) ++{ ++ int err; ++ unsigned int len; ++ char a[32]; ++ ++ err = -ERANGE; ++ len = s->to - s->from; ++ if (len + 1 <= sizeof(a)) { ++ memcpy(a, s->from, len); ++ a[len] = '\0'; ++ err = kstrtoull(a, 0, result); ++ } ++ return err; ++} ++ ++static int au_wbr_mfs_wmark(substring_t *arg, char *str, ++ struct au_opt_wbr_create *create) ++{ ++ int err; ++ unsigned long long ull; ++ ++ err = 0; ++ if (!au_match_ull(arg, &ull)) ++ create->mfsrr_watermark = ull; ++ else { ++ pr_err("bad integer in %s\n", str); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++static int au_wbr_mfs_sec(substring_t *arg, char *str, ++ struct au_opt_wbr_create *create) ++{ ++ int n, err; ++ ++ err = 0; ++ if (!match_int(arg, &n) && 0 <= n && n <= AUFS_MFS_MAX_SEC) ++ create->mfs_second = n; ++ else { ++ pr_err("bad integer in %s\n", str); ++ err = -EINVAL; ++ } ++ ++ return err; ++} ++ ++static int noinline_for_stack ++au_wbr_create_val(char *str, struct au_opt_wbr_create *create) ++{ ++ int err, e; ++ substring_t args[MAX_OPT_ARGS]; ++ ++ err = match_token(str, au_wbr_create_policy, args); ++ create->wbr_create = err; ++ switch (err) { ++ case AuWbrCreate_MFSRRV: ++ case AuWbrCreate_PMFSRRV: ++ e = au_wbr_mfs_wmark(&args[0], str, create); ++ if (!e) ++ e = au_wbr_mfs_sec(&args[1], str, create); ++ if (unlikely(e)) ++ err = e; ++ break; ++ case AuWbrCreate_MFSRR: ++ case AuWbrCreate_PMFSRR: ++ e = au_wbr_mfs_wmark(&args[0], str, create); ++ if (unlikely(e)) { ++ err = e; ++ break; ++ } ++ /*FALLTHROUGH*/ ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_PMFS: ++ create->mfs_second = AUFS_MFS_DEF_SEC; ++ break; ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFSV: ++ e = au_wbr_mfs_sec(&args[0], str, create); ++ if (unlikely(e)) ++ err = e; ++ break; ++ } ++ ++ return err; ++} ++ ++const char *au_optstr_wbr_create(int wbr_create) ++{ ++ return au_parser_pattern(wbr_create, au_wbr_create_policy); ++} ++ ++static match_table_t au_wbr_copyup_policy = { ++ {AuWbrCopyup_TDP, "tdp"}, ++ {AuWbrCopyup_TDP, "top-down-parent"}, ++ {AuWbrCopyup_BUP, "bup"}, ++ {AuWbrCopyup_BUP, "bottom-up-parent"}, ++ {AuWbrCopyup_BU, "bu"}, ++ {AuWbrCopyup_BU, "bottom-up"}, ++ {-1, NULL} ++}; ++ ++static int noinline_for_stack au_wbr_copyup_val(char *str) ++{ ++ substring_t args[MAX_OPT_ARGS]; ++ ++ return match_token(str, au_wbr_copyup_policy, args); ++} ++ ++const char *au_optstr_wbr_copyup(int wbr_copyup) ++{ ++ return au_parser_pattern(wbr_copyup, au_wbr_copyup_policy); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; ++ ++static void dump_opts(struct au_opts *opts) ++{ ++#ifdef CONFIG_AUFS_DEBUG ++ /* reduce stack space */ ++ union { ++ struct au_opt_add *add; ++ struct au_opt_del *del; ++ struct au_opt_mod *mod; ++ struct au_opt_xino *xino; ++ struct au_opt_xino_itrunc *xino_itrunc; ++ struct au_opt_wbr_create *create; ++ } u; ++ struct au_opt *opt; ++ ++ opt = opts->opt; ++ while (opt->type != Opt_tail) { ++ switch (opt->type) { ++ case Opt_add: ++ u.add = &opt->add; ++ AuDbg("add {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_del: ++ case Opt_idel: ++ u.del = &opt->del; ++ AuDbg("del {%s, %p}\n", ++ u.del->pathname, u.del->h_path.dentry); ++ break; ++ case Opt_mod: ++ case Opt_imod: ++ u.mod = &opt->mod; ++ AuDbg("mod {%s, 0x%x, %p}\n", ++ u.mod->path, u.mod->perm, u.mod->h_root); ++ break; ++ case Opt_append: ++ u.add = &opt->add; ++ AuDbg("append {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_prepend: ++ u.add = &opt->add; ++ AuDbg("prepend {b%d, %s, 0x%x, %p}\n", ++ u.add->bindex, u.add->pathname, u.add->perm, ++ u.add->path.dentry); ++ break; ++ case Opt_dirwh: ++ AuDbg("dirwh %d\n", opt->dirwh); ++ break; ++ case Opt_rdcache: ++ AuDbg("rdcache %d\n", opt->rdcache); ++ break; ++ case Opt_rdblk: ++ AuDbg("rdblk %u\n", opt->rdblk); ++ break; ++ case Opt_rdblk_def: ++ AuDbg("rdblk_def\n"); ++ break; ++ case Opt_rdhash: ++ AuDbg("rdhash %u\n", opt->rdhash); ++ break; ++ case Opt_rdhash_def: ++ AuDbg("rdhash_def\n"); ++ break; ++ case Opt_xino: ++ u.xino = &opt->xino; ++ AuDbg("xino {%s %pD}\n", u.xino->path, u.xino->file); ++ break; ++ case Opt_trunc_xino: ++ AuLabel(trunc_xino); ++ break; ++ case Opt_notrunc_xino: ++ AuLabel(notrunc_xino); ++ break; ++ case Opt_trunc_xino_path: ++ case Opt_itrunc_xino: ++ u.xino_itrunc = &opt->xino_itrunc; ++ AuDbg("trunc_xino %d\n", u.xino_itrunc->bindex); ++ break; ++ ++ case Opt_noxino: ++ AuLabel(noxino); ++ break; ++ case Opt_trunc_xib: ++ AuLabel(trunc_xib); ++ break; ++ case Opt_notrunc_xib: ++ AuLabel(notrunc_xib); ++ break; ++ case Opt_shwh: ++ AuLabel(shwh); ++ break; ++ case Opt_noshwh: ++ AuLabel(noshwh); ++ break; ++ case Opt_dirperm1: ++ AuLabel(dirperm1); ++ break; ++ case Opt_nodirperm1: ++ AuLabel(nodirperm1); ++ break; ++ case Opt_plink: ++ AuLabel(plink); ++ break; ++ case Opt_noplink: ++ AuLabel(noplink); ++ break; ++ case Opt_list_plink: ++ AuLabel(list_plink); ++ break; ++ case Opt_udba: ++ AuDbg("udba %d, %s\n", ++ opt->udba, au_optstr_udba(opt->udba)); ++ break; ++ case Opt_dio: ++ AuLabel(dio); ++ break; ++ case Opt_nodio: ++ AuLabel(nodio); ++ break; ++ case Opt_diropq_a: ++ AuLabel(diropq_a); ++ break; ++ case Opt_diropq_w: ++ AuLabel(diropq_w); ++ break; ++ case Opt_warn_perm: ++ AuLabel(warn_perm); ++ break; ++ case Opt_nowarn_perm: ++ AuLabel(nowarn_perm); ++ break; ++ case Opt_refrof: ++ AuLabel(refrof); ++ break; ++ case Opt_norefrof: ++ AuLabel(norefrof); ++ break; ++ case Opt_verbose: ++ AuLabel(verbose); ++ break; ++ case Opt_noverbose: ++ AuLabel(noverbose); ++ break; ++ case Opt_sum: ++ AuLabel(sum); ++ break; ++ case Opt_nosum: ++ AuLabel(nosum); ++ break; ++ case Opt_wsum: ++ AuLabel(wsum); ++ break; ++ case Opt_wbr_create: ++ u.create = &opt->wbr_create; ++ AuDbg("create %d, %s\n", u.create->wbr_create, ++ au_optstr_wbr_create(u.create->wbr_create)); ++ switch (u.create->wbr_create) { ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFSV: ++ AuDbg("%d sec\n", u.create->mfs_second); ++ break; ++ case AuWbrCreate_MFSRR: ++ AuDbg("%llu watermark\n", ++ u.create->mfsrr_watermark); ++ break; ++ case AuWbrCreate_MFSRRV: ++ case AuWbrCreate_PMFSRRV: ++ AuDbg("%llu watermark, %d sec\n", ++ u.create->mfsrr_watermark, ++ u.create->mfs_second); ++ break; ++ } ++ break; ++ case Opt_wbr_copyup: ++ AuDbg("copyup %d, %s\n", opt->wbr_copyup, ++ au_optstr_wbr_copyup(opt->wbr_copyup)); ++ break; ++ case Opt_fhsm_sec: ++ AuDbg("fhsm_sec %u\n", opt->fhsm_second); ++ break; ++ case Opt_acl: ++ AuLabel(acl); ++ break; ++ case Opt_noacl: ++ AuLabel(noacl); ++ break; ++ default: ++ BUG(); ++ } ++ opt++; ++ } ++#endif ++} ++ ++void au_opts_free(struct au_opts *opts) ++{ ++ struct au_opt *opt; ++ ++ opt = opts->opt; ++ while (opt->type != Opt_tail) { ++ switch (opt->type) { ++ case Opt_add: ++ case Opt_append: ++ case Opt_prepend: ++ path_put(&opt->add.path); ++ break; ++ case Opt_del: ++ case Opt_idel: ++ path_put(&opt->del.h_path); ++ break; ++ case Opt_mod: ++ case Opt_imod: ++ dput(opt->mod.h_root); ++ break; ++ case Opt_xino: ++ fput(opt->xino.file); ++ break; ++ } ++ opt++; ++ } ++} ++ ++static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags, ++ aufs_bindex_t bindex) ++{ ++ int err; ++ struct au_opt_add *add = &opt->add; ++ char *p; ++ ++ add->bindex = bindex; ++ add->perm = AuBrPerm_RO; ++ add->pathname = opt_str; ++ p = strchr(opt_str, '='); ++ if (p) { ++ *p++ = 0; ++ if (*p) ++ add->perm = br_perm_val(p); ++ } ++ ++ err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path); ++ if (!err) { ++ if (!p) { ++ add->perm = AuBrPerm_RO; ++ if (au_test_fs_rr(add->path.dentry->d_sb)) ++ add->perm = AuBrPerm_RR; ++ else if (!bindex && !(sb_flags & MS_RDONLY)) ++ add->perm = AuBrPerm_RW; ++ } ++ opt->type = Opt_add; ++ goto out; ++ } ++ pr_err("lookup failed %s (%d)\n", add->pathname, err); ++ err = -EINVAL; ++ ++out: ++ return err; ++} ++ ++static int au_opts_parse_del(struct au_opt_del *del, substring_t args[]) ++{ ++ int err; ++ ++ del->pathname = args[0].from; ++ AuDbg("del path %s\n", del->pathname); ++ ++ err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path); ++ if (unlikely(err)) ++ pr_err("lookup failed %s (%d)\n", del->pathname, err); ++ ++ return err; ++} ++ ++#if 0 /* reserved for future use */ ++static int au_opts_parse_idel(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_opt_del *del, substring_t args[]) ++{ ++ int err; ++ struct dentry *root; ++ ++ err = -EINVAL; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (bindex < 0 || au_sbend(sb) < bindex) { ++ pr_err("out of bounds, %d\n", bindex); ++ goto out; ++ } ++ ++ err = 0; ++ del->h_path.dentry = dget(au_h_dptr(root, bindex)); ++ del->h_path.mnt = mntget(au_sbr_mnt(sb, bindex)); ++ ++out: ++ aufs_read_unlock(root, !AuLock_IR); ++ return err; ++} ++#endif ++ ++static int noinline_for_stack ++au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[]) ++{ ++ int err; ++ struct path path; ++ char *p; ++ ++ err = -EINVAL; ++ mod->path = args[0].from; ++ p = strchr(mod->path, '='); ++ if (unlikely(!p)) { ++ pr_err("no permssion %s\n", args[0].from); ++ goto out; ++ } ++ ++ *p++ = 0; ++ err = vfsub_kern_path(mod->path, lkup_dirflags, &path); ++ if (unlikely(err)) { ++ pr_err("lookup failed %s (%d)\n", mod->path, err); ++ goto out; ++ } ++ ++ mod->perm = br_perm_val(p); ++ AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p); ++ mod->h_root = dget(path.dentry); ++ path_put(&path); ++ ++out: ++ return err; ++} ++ ++#if 0 /* reserved for future use */ ++static int au_opts_parse_imod(struct super_block *sb, aufs_bindex_t bindex, ++ struct au_opt_mod *mod, substring_t args[]) ++{ ++ int err; ++ struct dentry *root; ++ ++ err = -EINVAL; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (bindex < 0 || au_sbend(sb) < bindex) { ++ pr_err("out of bounds, %d\n", bindex); ++ goto out; ++ } ++ ++ err = 0; ++ mod->perm = br_perm_val(args[1].from); ++ AuDbg("mod path %s, perm 0x%x, %s\n", ++ mod->path, mod->perm, args[1].from); ++ mod->h_root = dget(au_h_dptr(root, bindex)); ++ ++out: ++ aufs_read_unlock(root, !AuLock_IR); ++ return err; ++} ++#endif ++ ++static int au_opts_parse_xino(struct super_block *sb, struct au_opt_xino *xino, ++ substring_t args[]) ++{ ++ int err; ++ struct file *file; ++ ++ file = au_xino_create(sb, args[0].from, /*silent*/0); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ ++ err = -EINVAL; ++ if (unlikely(file->f_path.dentry->d_sb == sb)) { ++ fput(file); ++ pr_err("%s must be outside\n", args[0].from); ++ goto out; ++ } ++ ++ err = 0; ++ xino->file = file; ++ xino->path = args[0].from; ++ ++out: ++ return err; ++} ++ ++static int noinline_for_stack ++au_opts_parse_xino_itrunc_path(struct super_block *sb, ++ struct au_opt_xino_itrunc *xino_itrunc, ++ substring_t args[]) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct path path; ++ struct dentry *root; ++ ++ err = vfsub_kern_path(args[0].from, lkup_dirflags, &path); ++ if (unlikely(err)) { ++ pr_err("lookup failed %s (%d)\n", args[0].from, err); ++ goto out; ++ } ++ ++ xino_itrunc->bindex = -1; ++ root = sb->s_root; ++ aufs_read_lock(root, AuLock_FLUSH); ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ if (au_h_dptr(root, bindex) == path.dentry) { ++ xino_itrunc->bindex = bindex; ++ break; ++ } ++ } ++ aufs_read_unlock(root, !AuLock_IR); ++ path_put(&path); ++ ++ if (unlikely(xino_itrunc->bindex < 0)) { ++ pr_err("no such branch %s\n", args[0].from); ++ err = -EINVAL; ++ } ++ ++out: ++ return err; ++} ++ ++/* called without aufs lock */ ++int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts) ++{ ++ int err, n, token; ++ aufs_bindex_t bindex; ++ unsigned char skipped; ++ struct dentry *root; ++ struct au_opt *opt, *opt_tail; ++ char *opt_str; ++ /* reduce the stack space */ ++ union { ++ struct au_opt_xino_itrunc *xino_itrunc; ++ struct au_opt_wbr_create *create; ++ } u; ++ struct { ++ substring_t args[MAX_OPT_ARGS]; ++ } *a; ++ ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ ++ root = sb->s_root; ++ err = 0; ++ bindex = 0; ++ opt = opts->opt; ++ opt_tail = opt + opts->max_opt - 1; ++ opt->type = Opt_tail; ++ while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { ++ err = -EINVAL; ++ skipped = 0; ++ token = match_token(opt_str, options, a->args); ++ switch (token) { ++ case Opt_br: ++ err = 0; ++ while (!err && (opt_str = strsep(&a->args[0].from, ":")) ++ && *opt_str) { ++ err = opt_add(opt, opt_str, opts->sb_flags, ++ bindex++); ++ if (unlikely(!err && ++opt > opt_tail)) { ++ err = -E2BIG; ++ break; ++ } ++ opt->type = Opt_tail; ++ skipped = 1; ++ } ++ break; ++ case Opt_add: ++ if (unlikely(match_int(&a->args[0], &n))) { ++ pr_err("bad integer in %s\n", opt_str); ++ break; ++ } ++ bindex = n; ++ err = opt_add(opt, a->args[1].from, opts->sb_flags, ++ bindex); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_append: ++ err = opt_add(opt, a->args[0].from, opts->sb_flags, ++ /*dummy bindex*/1); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_prepend: ++ err = opt_add(opt, a->args[0].from, opts->sb_flags, ++ /*bindex*/0); ++ if (!err) ++ opt->type = token; ++ break; ++ case Opt_del: ++ err = au_opts_parse_del(&opt->del, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#if 0 /* reserved for future use */ ++ case Opt_idel: ++ del->pathname = "(indexed)"; ++ if (unlikely(match_int(&args[0], &n))) { ++ pr_err("bad integer in %s\n", opt_str); ++ break; ++ } ++ err = au_opts_parse_idel(sb, n, &opt->del, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#endif ++ case Opt_mod: ++ err = au_opts_parse_mod(&opt->mod, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#ifdef IMOD /* reserved for future use */ ++ case Opt_imod: ++ u.mod->path = "(indexed)"; ++ if (unlikely(match_int(&a->args[0], &n))) { ++ pr_err("bad integer in %s\n", opt_str); ++ break; ++ } ++ err = au_opts_parse_imod(sb, n, &opt->mod, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++#endif ++ case Opt_xino: ++ err = au_opts_parse_xino(sb, &opt->xino, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++ ++ case Opt_trunc_xino_path: ++ err = au_opts_parse_xino_itrunc_path ++ (sb, &opt->xino_itrunc, a->args); ++ if (!err) ++ opt->type = token; ++ break; ++ ++ case Opt_itrunc_xino: ++ u.xino_itrunc = &opt->xino_itrunc; ++ if (unlikely(match_int(&a->args[0], &n))) { ++ pr_err("bad integer in %s\n", opt_str); ++ break; ++ } ++ u.xino_itrunc->bindex = n; ++ aufs_read_lock(root, AuLock_FLUSH); ++ if (n < 0 || au_sbend(sb) < n) { ++ pr_err("out of bounds, %d\n", n); ++ aufs_read_unlock(root, !AuLock_IR); ++ break; ++ } ++ aufs_read_unlock(root, !AuLock_IR); ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_dirwh: ++ if (unlikely(match_int(&a->args[0], &opt->dirwh))) ++ break; ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_rdcache: ++ if (unlikely(match_int(&a->args[0], &n))) { ++ pr_err("bad integer in %s\n", opt_str); ++ break; ++ } ++ if (unlikely(n > AUFS_RDCACHE_MAX)) { ++ pr_err("rdcache must be smaller than %d\n", ++ AUFS_RDCACHE_MAX); ++ break; ++ } ++ opt->rdcache = n; ++ err = 0; ++ opt->type = token; ++ break; ++ case Opt_rdblk: ++ if (unlikely(match_int(&a->args[0], &n) ++ || n < 0 ++ || n > KMALLOC_MAX_SIZE)) { ++ pr_err("bad integer in %s\n", opt_str); ++ break; ++ } ++ if (unlikely(n && n < NAME_MAX)) { ++ pr_err("rdblk must be larger than %d\n", ++ NAME_MAX); ++ break; ++ } ++ opt->rdblk = n; ++ err = 0; ++ opt->type = token; ++ break; ++ case Opt_rdhash: ++ if (unlikely(match_int(&a->args[0], &n) ++ || n < 0 ++ || n * sizeof(struct hlist_head) ++ > KMALLOC_MAX_SIZE)) { ++ pr_err("bad integer in %s\n", opt_str); ++ break; ++ } ++ opt->rdhash = n; ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_trunc_xino: ++ case Opt_notrunc_xino: ++ case Opt_noxino: ++ case Opt_trunc_xib: ++ case Opt_notrunc_xib: ++ case Opt_shwh: ++ case Opt_noshwh: ++ case Opt_dirperm1: ++ case Opt_nodirperm1: ++ case Opt_plink: ++ case Opt_noplink: ++ case Opt_list_plink: ++ case Opt_dio: ++ case Opt_nodio: ++ case Opt_diropq_a: ++ case Opt_diropq_w: ++ case Opt_warn_perm: ++ case Opt_nowarn_perm: ++ case Opt_refrof: ++ case Opt_norefrof: ++ case Opt_verbose: ++ case Opt_noverbose: ++ case Opt_sum: ++ case Opt_nosum: ++ case Opt_wsum: ++ case Opt_rdblk_def: ++ case Opt_rdhash_def: ++ case Opt_acl: ++ case Opt_noacl: ++ err = 0; ++ opt->type = token; ++ break; ++ ++ case Opt_udba: ++ opt->udba = udba_val(a->args[0].from); ++ if (opt->udba >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ pr_err("wrong value, %s\n", opt_str); ++ break; ++ ++ case Opt_wbr_create: ++ u.create = &opt->wbr_create; ++ u.create->wbr_create ++ = au_wbr_create_val(a->args[0].from, u.create); ++ if (u.create->wbr_create >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ pr_err("wrong value, %s\n", opt_str); ++ break; ++ case Opt_wbr_copyup: ++ opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); ++ if (opt->wbr_copyup >= 0) { ++ err = 0; ++ opt->type = token; ++ } else ++ pr_err("wrong value, %s\n", opt_str); ++ break; ++ ++ case Opt_fhsm_sec: ++ if (unlikely(match_int(&a->args[0], &n) ++ || n < 0)) { ++ pr_err("bad integer in %s\n", opt_str); ++ break; ++ } ++ if (sysaufs_brs) { ++ opt->fhsm_second = n; ++ opt->type = token; ++ } else ++ pr_warn("ignored %s\n", opt_str); ++ err = 0; ++ break; ++ ++ case Opt_ignore: ++ pr_warn("ignored %s\n", opt_str); ++ /*FALLTHROUGH*/ ++ case Opt_ignore_silent: ++ skipped = 1; ++ err = 0; ++ break; ++ case Opt_err: ++ pr_err("unknown option %s\n", opt_str); ++ break; ++ } ++ ++ if (!err && !skipped) { ++ if (unlikely(++opt > opt_tail)) { ++ err = -E2BIG; ++ opt--; ++ opt->type = Opt_tail; ++ break; ++ } ++ opt->type = Opt_tail; ++ } ++ } ++ ++ kfree(a); ++ dump_opts(opts); ++ if (unlikely(err)) ++ au_opts_free(opts); ++ ++out: ++ return err; ++} ++ ++static int au_opt_wbr_create(struct super_block *sb, ++ struct au_opt_wbr_create *create) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 1; /* handled */ ++ sbinfo = au_sbi(sb); ++ if (sbinfo->si_wbr_create_ops->fin) { ++ err = sbinfo->si_wbr_create_ops->fin(sb); ++ if (!err) ++ err = 1; ++ } ++ ++ sbinfo->si_wbr_create = create->wbr_create; ++ sbinfo->si_wbr_create_ops = au_wbr_create_ops + create->wbr_create; ++ switch (create->wbr_create) { ++ case AuWbrCreate_MFSRRV: ++ case AuWbrCreate_MFSRR: ++ case AuWbrCreate_PMFSRR: ++ case AuWbrCreate_PMFSRRV: ++ sbinfo->si_wbr_mfs.mfsrr_watermark = create->mfsrr_watermark; ++ /*FALLTHROUGH*/ ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_MFSV: ++ case AuWbrCreate_PMFS: ++ case AuWbrCreate_PMFSV: ++ sbinfo->si_wbr_mfs.mfs_expire ++ = msecs_to_jiffies(create->mfs_second * MSEC_PER_SEC); ++ break; ++ } ++ ++ if (sbinfo->si_wbr_create_ops->init) ++ sbinfo->si_wbr_create_ops->init(sb); /* ignore */ ++ ++ return err; ++} ++ ++/* ++ * returns, ++ * plus: processed without an error ++ * zero: unprocessed ++ */ ++static int au_opt_simple(struct super_block *sb, struct au_opt *opt, ++ struct au_opts *opts) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 1; /* handled */ ++ sbinfo = au_sbi(sb); ++ switch (opt->type) { ++ case Opt_udba: ++ sbinfo->si_mntflags &= ~AuOptMask_UDBA; ++ sbinfo->si_mntflags |= opt->udba; ++ opts->given_udba |= opt->udba; ++ break; ++ ++ case Opt_plink: ++ au_opt_set(sbinfo->si_mntflags, PLINK); ++ break; ++ case Opt_noplink: ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_put(sb, /*verbose*/1); ++ au_opt_clr(sbinfo->si_mntflags, PLINK); ++ break; ++ case Opt_list_plink: ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_list(sb); ++ break; ++ ++ case Opt_dio: ++ au_opt_set(sbinfo->si_mntflags, DIO); ++ au_fset_opts(opts->flags, REFRESH_DYAOP); ++ break; ++ case Opt_nodio: ++ au_opt_clr(sbinfo->si_mntflags, DIO); ++ au_fset_opts(opts->flags, REFRESH_DYAOP); ++ break; ++ ++ case Opt_fhsm_sec: ++ au_fhsm_set(sbinfo, opt->fhsm_second); ++ break; ++ ++ case Opt_diropq_a: ++ au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ); ++ break; ++ case Opt_diropq_w: ++ au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ); ++ break; ++ ++ case Opt_warn_perm: ++ au_opt_set(sbinfo->si_mntflags, WARN_PERM); ++ break; ++ case Opt_nowarn_perm: ++ au_opt_clr(sbinfo->si_mntflags, WARN_PERM); ++ break; ++ ++ case Opt_refrof: ++ au_opt_set(sbinfo->si_mntflags, REFROF); ++ break; ++ case Opt_norefrof: ++ au_opt_clr(sbinfo->si_mntflags, REFROF); ++ break; ++ ++ case Opt_verbose: ++ au_opt_set(sbinfo->si_mntflags, VERBOSE); ++ break; ++ case Opt_noverbose: ++ au_opt_clr(sbinfo->si_mntflags, VERBOSE); ++ break; ++ ++ case Opt_sum: ++ au_opt_set(sbinfo->si_mntflags, SUM); ++ break; ++ case Opt_wsum: ++ au_opt_clr(sbinfo->si_mntflags, SUM); ++ au_opt_set(sbinfo->si_mntflags, SUM_W); ++ case Opt_nosum: ++ au_opt_clr(sbinfo->si_mntflags, SUM); ++ au_opt_clr(sbinfo->si_mntflags, SUM_W); ++ break; ++ ++ case Opt_wbr_create: ++ err = au_opt_wbr_create(sb, &opt->wbr_create); ++ break; ++ case Opt_wbr_copyup: ++ sbinfo->si_wbr_copyup = opt->wbr_copyup; ++ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup; ++ break; ++ ++ case Opt_dirwh: ++ sbinfo->si_dirwh = opt->dirwh; ++ break; ++ ++ case Opt_rdcache: ++ sbinfo->si_rdcache ++ = msecs_to_jiffies(opt->rdcache * MSEC_PER_SEC); ++ break; ++ case Opt_rdblk: ++ sbinfo->si_rdblk = opt->rdblk; ++ break; ++ case Opt_rdblk_def: ++ sbinfo->si_rdblk = AUFS_RDBLK_DEF; ++ break; ++ case Opt_rdhash: ++ sbinfo->si_rdhash = opt->rdhash; ++ break; ++ case Opt_rdhash_def: ++ sbinfo->si_rdhash = AUFS_RDHASH_DEF; ++ break; ++ ++ case Opt_shwh: ++ au_opt_set(sbinfo->si_mntflags, SHWH); ++ break; ++ case Opt_noshwh: ++ au_opt_clr(sbinfo->si_mntflags, SHWH); ++ break; ++ ++ case Opt_dirperm1: ++ au_opt_set(sbinfo->si_mntflags, DIRPERM1); ++ break; ++ case Opt_nodirperm1: ++ au_opt_clr(sbinfo->si_mntflags, DIRPERM1); ++ break; ++ ++ case Opt_trunc_xino: ++ au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); ++ break; ++ case Opt_notrunc_xino: ++ au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO); ++ break; ++ ++ case Opt_trunc_xino_path: ++ case Opt_itrunc_xino: ++ err = au_xino_trunc(sb, opt->xino_itrunc.bindex); ++ if (!err) ++ err = 1; ++ break; ++ ++ case Opt_trunc_xib: ++ au_fset_opts(opts->flags, TRUNC_XIB); ++ break; ++ case Opt_notrunc_xib: ++ au_fclr_opts(opts->flags, TRUNC_XIB); ++ break; ++ ++ case Opt_acl: ++ sb->s_flags |= MS_POSIXACL; ++ break; ++ case Opt_noacl: ++ sb->s_flags &= ~MS_POSIXACL; ++ break; ++ ++ default: ++ err = 0; ++ break; ++ } ++ ++ return err; ++} ++ ++/* ++ * returns tri-state. ++ * plus: processed without an error ++ * zero: unprocessed ++ * minus: error ++ */ ++static int au_opt_br(struct super_block *sb, struct au_opt *opt, ++ struct au_opts *opts) ++{ ++ int err, do_refresh; ++ ++ err = 0; ++ switch (opt->type) { ++ case Opt_append: ++ opt->add.bindex = au_sbend(sb) + 1; ++ if (opt->add.bindex < 0) ++ opt->add.bindex = 0; ++ goto add; ++ case Opt_prepend: ++ opt->add.bindex = 0; ++ add: /* indented label */ ++ case Opt_add: ++ err = au_br_add(sb, &opt->add, ++ au_ftest_opts(opts->flags, REMOUNT)); ++ if (!err) { ++ err = 1; ++ au_fset_opts(opts->flags, REFRESH); ++ } ++ break; ++ ++ case Opt_del: ++ case Opt_idel: ++ err = au_br_del(sb, &opt->del, ++ au_ftest_opts(opts->flags, REMOUNT)); ++ if (!err) { ++ err = 1; ++ au_fset_opts(opts->flags, TRUNC_XIB); ++ au_fset_opts(opts->flags, REFRESH); ++ } ++ break; ++ ++ case Opt_mod: ++ case Opt_imod: ++ err = au_br_mod(sb, &opt->mod, ++ au_ftest_opts(opts->flags, REMOUNT), ++ &do_refresh); ++ if (!err) { ++ err = 1; ++ if (do_refresh) ++ au_fset_opts(opts->flags, REFRESH); ++ } ++ break; ++ } ++ ++ return err; ++} ++ ++static int au_opt_xino(struct super_block *sb, struct au_opt *opt, ++ struct au_opt_xino **opt_xino, ++ struct au_opts *opts) ++{ ++ int err; ++ aufs_bindex_t bend, bindex; ++ struct dentry *root, *parent, *h_root; ++ ++ err = 0; ++ switch (opt->type) { ++ case Opt_xino: ++ err = au_xino_set(sb, &opt->xino, ++ !!au_ftest_opts(opts->flags, REMOUNT)); ++ if (unlikely(err)) ++ break; ++ ++ *opt_xino = &opt->xino; ++ au_xino_brid_set(sb, -1); ++ ++ /* safe d_parent access */ ++ parent = opt->xino.file->f_path.dentry->d_parent; ++ root = sb->s_root; ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ h_root = au_h_dptr(root, bindex); ++ if (h_root == parent) { ++ au_xino_brid_set(sb, au_sbr_id(sb, bindex)); ++ break; ++ } ++ } ++ break; ++ ++ case Opt_noxino: ++ au_xino_clr(sb); ++ au_xino_brid_set(sb, -1); ++ *opt_xino = (void *)-1; ++ break; ++ } ++ ++ return err; ++} ++ ++int au_opts_verify(struct super_block *sb, unsigned long sb_flags, ++ unsigned int pending) ++{ ++ int err, fhsm; ++ aufs_bindex_t bindex, bend; ++ unsigned char do_plink, skip, do_free; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ struct dentry *root; ++ struct inode *dir, *h_dir; ++ struct au_sbinfo *sbinfo; ++ struct au_hinode *hdir; ++ ++ SiMustAnyLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!(sbinfo->si_mntflags & AuOptMask_UDBA)); ++ ++ if (!(sb_flags & MS_RDONLY)) { ++ if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) ++ pr_warn("first branch should be rw\n"); ++ if (unlikely(au_opt_test(sbinfo->si_mntflags, SHWH))) ++ pr_warn("shwh should be used with ro\n"); ++ } ++ ++ if (au_opt_test((sbinfo->si_mntflags | pending), UDBA_HNOTIFY) ++ && !au_opt_test(sbinfo->si_mntflags, XINO)) ++ pr_warn("udba=*notify requires xino\n"); ++ ++ if (au_opt_test(sbinfo->si_mntflags, DIRPERM1)) ++ pr_warn("dirperm1 breaks the protection" ++ " by the permission bits on the lower branch\n"); ++ ++ err = 0; ++ fhsm = 0; ++ root = sb->s_root; ++ dir = root->d_inode; ++ do_plink = !!au_opt_test(sbinfo->si_mntflags, PLINK); ++ bend = au_sbend(sb); ++ for (bindex = 0; !err && bindex <= bend; bindex++) { ++ skip = 0; ++ h_dir = au_h_iptr(dir, bindex); ++ br = au_sbr(sb, bindex); ++ ++ if ((br->br_perm & AuBrAttr_ICEX) ++ && !h_dir->i_op->listxattr) ++ br->br_perm &= ~AuBrAttr_ICEX; ++#if 0 ++ if ((br->br_perm & AuBrAttr_ICEX_SEC) ++ && (au_br_sb(br)->s_flags & MS_NOSEC)) ++ br->br_perm &= ~AuBrAttr_ICEX_SEC; ++#endif ++ ++ do_free = 0; ++ wbr = br->br_wbr; ++ if (wbr) ++ wbr_wh_read_lock(wbr); ++ ++ if (!au_br_writable(br->br_perm)) { ++ do_free = !!wbr; ++ skip = (!wbr ++ || (!wbr->wbr_whbase ++ && !wbr->wbr_plink ++ && !wbr->wbr_orph)); ++ } else if (!au_br_wh_linkable(br->br_perm)) { ++ /* skip = (!br->br_whbase && !br->br_orph); */ ++ skip = (!wbr || !wbr->wbr_whbase); ++ if (skip && wbr) { ++ if (do_plink) ++ skip = !!wbr->wbr_plink; ++ else ++ skip = !wbr->wbr_plink; ++ } ++ } else { ++ /* skip = (br->br_whbase && br->br_ohph); */ ++ skip = (wbr && wbr->wbr_whbase); ++ if (skip) { ++ if (do_plink) ++ skip = !!wbr->wbr_plink; ++ else ++ skip = !wbr->wbr_plink; ++ } ++ } ++ if (wbr) ++ wbr_wh_read_unlock(wbr); ++ ++ if (au_br_fhsm(br->br_perm)) { ++ fhsm++; ++ AuDebugOn(!br->br_fhsm); ++ } ++ ++ if (skip) ++ continue; ++ ++ hdir = au_hi(dir, bindex); ++ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ if (wbr) ++ wbr_wh_write_lock(wbr); ++ err = au_wh_init(br, sb); ++ if (wbr) ++ wbr_wh_write_unlock(wbr); ++ au_hn_imtx_unlock(hdir); ++ ++ if (!err && do_free) { ++ kfree(wbr); ++ br->br_wbr = NULL; ++ } ++ } ++ ++ if (fhsm >= 2) { ++ au_fset_si(sbinfo, FHSM); ++ for (bindex = bend; bindex >= 0; bindex--) { ++ br = au_sbr(sb, bindex); ++ if (au_br_fhsm(br->br_perm)) { ++ au_fhsm_set_bottom(sb, bindex); ++ break; ++ } ++ } ++ } else { ++ au_fclr_si(sbinfo, FHSM); ++ au_fhsm_set_bottom(sb, -1); ++ } ++ ++ return err; ++} ++ ++int au_opts_mount(struct super_block *sb, struct au_opts *opts) ++{ ++ int err; ++ unsigned int tmp; ++ aufs_bindex_t bindex, bend; ++ struct au_opt *opt; ++ struct au_opt_xino *opt_xino, xino; ++ struct au_sbinfo *sbinfo; ++ struct au_branch *br; ++ struct inode *dir; ++ ++ SiMustWriteLock(sb); ++ ++ err = 0; ++ opt_xino = NULL; ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) ++ err = au_opt_simple(sb, opt++, opts); ++ if (err > 0) ++ err = 0; ++ else if (unlikely(err < 0)) ++ goto out; ++ ++ /* disable xino and udba temporary */ ++ sbinfo = au_sbi(sb); ++ tmp = sbinfo->si_mntflags; ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++ au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL); ++ ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) ++ err = au_opt_br(sb, opt++, opts); ++ if (err > 0) ++ err = 0; ++ else if (unlikely(err < 0)) ++ goto out; ++ ++ bend = au_sbend(sb); ++ if (unlikely(bend < 0)) { ++ err = -EINVAL; ++ pr_err("no branches\n"); ++ goto out; ++ } ++ ++ if (au_opt_test(tmp, XINO)) ++ au_opt_set(sbinfo->si_mntflags, XINO); ++ opt = opts->opt; ++ while (!err && opt->type != Opt_tail) ++ err = au_opt_xino(sb, opt++, &opt_xino, opts); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_opts_verify(sb, sb->s_flags, tmp); ++ if (unlikely(err)) ++ goto out; ++ ++ /* restore xino */ ++ if (au_opt_test(tmp, XINO) && !opt_xino) { ++ xino.file = au_xino_def(sb); ++ err = PTR_ERR(xino.file); ++ if (IS_ERR(xino.file)) ++ goto out; ++ ++ err = au_xino_set(sb, &xino, /*remount*/0); ++ fput(xino.file); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ /* restore udba */ ++ tmp &= AuOptMask_UDBA; ++ sbinfo->si_mntflags &= ~AuOptMask_UDBA; ++ sbinfo->si_mntflags |= tmp; ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ err = au_hnotify_reset_br(tmp, br, br->br_perm); ++ if (unlikely(err)) ++ AuIOErr("hnotify failed on br %d, %d, ignored\n", ++ bindex, err); ++ /* go on even if err */ ++ } ++ if (au_opt_test(tmp, UDBA_HNOTIFY)) { ++ dir = sb->s_root->d_inode; ++ au_hn_reset(dir, au_hi_flags(dir, /*isdir*/1) & ~AuHi_XINO); ++ } ++ ++out: ++ return err; ++} ++ ++int au_opts_remount(struct super_block *sb, struct au_opts *opts) ++{ ++ int err, rerr; ++ struct inode *dir; ++ struct au_opt_xino *opt_xino; ++ struct au_opt *opt; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ dir = sb->s_root->d_inode; ++ sbinfo = au_sbi(sb); ++ err = 0; ++ opt_xino = NULL; ++ opt = opts->opt; ++ while (err >= 0 && opt->type != Opt_tail) { ++ err = au_opt_simple(sb, opt, opts); ++ if (!err) ++ err = au_opt_br(sb, opt, opts); ++ if (!err) ++ err = au_opt_xino(sb, opt, &opt_xino, opts); ++ opt++; ++ } ++ if (err > 0) ++ err = 0; ++ AuTraceErr(err); ++ /* go on even err */ ++ ++ rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0); ++ if (unlikely(rerr && !err)) ++ err = rerr; ++ ++ if (au_ftest_opts(opts->flags, TRUNC_XIB)) { ++ rerr = au_xib_trunc(sb); ++ if (unlikely(rerr && !err)) ++ err = rerr; ++ } ++ ++ /* will be handled by the caller */ ++ if (!au_ftest_opts(opts->flags, REFRESH) ++ && (opts->given_udba || au_opt_test(sbinfo->si_mntflags, XINO))) ++ au_fset_opts(opts->flags, REFRESH); ++ ++ AuDbg("status 0x%x\n", opts->flags); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++unsigned int au_opt_udba(struct super_block *sb) ++{ ++ return au_mntflags(sb) & AuOptMask_UDBA; ++} +diff --git a/fs/aufs/opts.h b/fs/aufs/opts.h +new file mode 100644 +index 0000000..929ebc3 +--- /dev/null ++++ b/fs/aufs/opts.h +@@ -0,0 +1,200 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * mount options/flags ++ */ ++ ++#ifndef __AUFS_OPTS_H__ ++#define __AUFS_OPTS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include "branch.h" ++ ++struct file; ++struct super_block; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* mount flags */ ++#define AuOpt_XINO 1 /* external inode number bitmap ++ and translation table */ ++#define AuOpt_TRUNC_XINO (1 << 1) /* truncate xino files */ ++#define AuOpt_UDBA_NONE (1 << 2) /* users direct branch access */ ++#define AuOpt_UDBA_REVAL (1 << 3) ++#define AuOpt_UDBA_HNOTIFY (1 << 4) ++#define AuOpt_SHWH (1 << 5) /* show whiteout */ ++#define AuOpt_PLINK (1 << 6) /* pseudo-link */ ++#define AuOpt_DIRPERM1 (1 << 7) /* ignore the lower dir's perm ++ bits */ ++#define AuOpt_REFROF (1 << 8) /* unimplemented */ ++#define AuOpt_ALWAYS_DIROPQ (1 << 9) /* policy to creating diropq */ ++#define AuOpt_SUM (1 << 10) /* summation for statfs(2) */ ++#define AuOpt_SUM_W (1 << 11) /* unimplemented */ ++#define AuOpt_WARN_PERM (1 << 12) /* warn when add-branch */ ++#define AuOpt_VERBOSE (1 << 13) /* busy inode when del-branch */ ++#define AuOpt_DIO (1 << 14) /* direct io */ ++ ++#ifndef CONFIG_AUFS_HNOTIFY ++#undef AuOpt_UDBA_HNOTIFY ++#define AuOpt_UDBA_HNOTIFY 0 ++#endif ++#ifndef CONFIG_AUFS_SHWH ++#undef AuOpt_SHWH ++#define AuOpt_SHWH 0 ++#endif ++ ++#define AuOpt_Def (AuOpt_XINO \ ++ | AuOpt_UDBA_REVAL \ ++ | AuOpt_PLINK \ ++ /* | AuOpt_DIRPERM1 */ \ ++ | AuOpt_WARN_PERM) ++#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ ++ | AuOpt_UDBA_REVAL \ ++ | AuOpt_UDBA_HNOTIFY) ++ ++#define au_opt_test(flags, name) (flags & AuOpt_##name) ++#define au_opt_set(flags, name) do { \ ++ BUILD_BUG_ON(AuOpt_##name & AuOptMask_UDBA); \ ++ ((flags) |= AuOpt_##name); \ ++} while (0) ++#define au_opt_set_udba(flags, name) do { \ ++ (flags) &= ~AuOptMask_UDBA; \ ++ ((flags) |= AuOpt_##name); \ ++} while (0) ++#define au_opt_clr(flags, name) do { \ ++ ((flags) &= ~AuOpt_##name); \ ++} while (0) ++ ++static inline unsigned int au_opts_plink(unsigned int mntflags) ++{ ++#ifdef CONFIG_PROC_FS ++ return mntflags; ++#else ++ return mntflags & ~AuOpt_PLINK; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies to select one among multiple writable branches */ ++enum { ++ AuWbrCreate_TDP, /* top down parent */ ++ AuWbrCreate_RR, /* round robin */ ++ AuWbrCreate_MFS, /* most free space */ ++ AuWbrCreate_MFSV, /* mfs with seconds */ ++ AuWbrCreate_MFSRR, /* mfs then rr */ ++ AuWbrCreate_MFSRRV, /* mfs then rr with seconds */ ++ AuWbrCreate_PMFS, /* parent and mfs */ ++ AuWbrCreate_PMFSV, /* parent and mfs with seconds */ ++ AuWbrCreate_PMFSRR, /* parent, mfs and round-robin */ ++ AuWbrCreate_PMFSRRV, /* plus seconds */ ++ ++ AuWbrCreate_Def = AuWbrCreate_TDP ++}; ++ ++enum { ++ AuWbrCopyup_TDP, /* top down parent */ ++ AuWbrCopyup_BUP, /* bottom up parent */ ++ AuWbrCopyup_BU, /* bottom up */ ++ ++ AuWbrCopyup_Def = AuWbrCopyup_TDP ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_opt_add { ++ aufs_bindex_t bindex; ++ char *pathname; ++ int perm; ++ struct path path; ++}; ++ ++struct au_opt_del { ++ char *pathname; ++ struct path h_path; ++}; ++ ++struct au_opt_mod { ++ char *path; ++ int perm; ++ struct dentry *h_root; ++}; ++ ++struct au_opt_xino { ++ char *path; ++ struct file *file; ++}; ++ ++struct au_opt_xino_itrunc { ++ aufs_bindex_t bindex; ++}; ++ ++struct au_opt_wbr_create { ++ int wbr_create; ++ int mfs_second; ++ unsigned long long mfsrr_watermark; ++}; ++ ++struct au_opt { ++ int type; ++ union { ++ struct au_opt_xino xino; ++ struct au_opt_xino_itrunc xino_itrunc; ++ struct au_opt_add add; ++ struct au_opt_del del; ++ struct au_opt_mod mod; ++ int dirwh; ++ int rdcache; ++ unsigned int rdblk; ++ unsigned int rdhash; ++ int udba; ++ struct au_opt_wbr_create wbr_create; ++ int wbr_copyup; ++ unsigned int fhsm_second; ++ }; ++}; ++ ++/* opts flags */ ++#define AuOpts_REMOUNT 1 ++#define AuOpts_REFRESH (1 << 1) ++#define AuOpts_TRUNC_XIB (1 << 2) ++#define AuOpts_REFRESH_DYAOP (1 << 3) ++#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) ++#define au_fset_opts(flags, name) \ ++ do { (flags) |= AuOpts_##name; } while (0) ++#define au_fclr_opts(flags, name) \ ++ do { (flags) &= ~AuOpts_##name; } while (0) ++ ++struct au_opts { ++ struct au_opt *opt; ++ int max_opt; ++ ++ unsigned int given_udba; ++ unsigned int flags; ++ unsigned long sb_flags; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_optstr_br_perm(au_br_perm_str_t *str, int perm); ++const char *au_optstr_udba(int udba); ++const char *au_optstr_wbr_copyup(int wbr_copyup); ++const char *au_optstr_wbr_create(int wbr_create); ++ ++void au_opts_free(struct au_opts *opts); ++int au_opts_parse(struct super_block *sb, char *str, struct au_opts *opts); ++int au_opts_verify(struct super_block *sb, unsigned long sb_flags, ++ unsigned int pending); ++int au_opts_mount(struct super_block *sb, struct au_opts *opts); ++int au_opts_remount(struct super_block *sb, struct au_opts *opts); ++ ++unsigned int au_opt_udba(struct super_block *sb); ++ ++/* ---------------------------------------------------------------------- */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_OPTS_H__ */ +diff --git a/fs/aufs/plink.c b/fs/aufs/plink.c +new file mode 100644 +index 0000000..3e4fe87 +--- /dev/null ++++ b/fs/aufs/plink.c +@@ -0,0 +1,519 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * pseudo-link ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * the pseudo-link maintenance mode. ++ * during a user process maintains the pseudo-links, ++ * prohibit adding a new plink and branch manipulation. ++ * ++ * Flags ++ * NOPLM: ++ * For entry functions which will handle plink, and i_mutex is already held ++ * in VFS. ++ * They cannot wait and should return an error at once. ++ * Callers has to check the error. ++ * NOPLMW: ++ * For entry functions which will handle plink, but i_mutex is not held ++ * in VFS. ++ * They can wait the plink maintenance mode to finish. ++ * ++ * They behave like F_SETLK and F_SETLKW. ++ * If the caller never handle plink, then both flags are unnecessary. ++ */ ++ ++int au_plink_maint(struct super_block *sb, int flags) ++{ ++ int err; ++ pid_t pid, ppid; ++ struct au_sbinfo *sbi; ++ ++ SiMustAnyLock(sb); ++ ++ err = 0; ++ if (!au_opt_test(au_mntflags(sb), PLINK)) ++ goto out; ++ ++ sbi = au_sbi(sb); ++ pid = sbi->si_plink_maint_pid; ++ if (!pid || pid == current->pid) ++ goto out; ++ ++ /* todo: it highly depends upon /sbin/mount.aufs */ ++ rcu_read_lock(); ++ ppid = task_pid_vnr(rcu_dereference(current->real_parent)); ++ rcu_read_unlock(); ++ if (pid == ppid) ++ goto out; ++ ++ if (au_ftest_lock(flags, NOPLMW)) { ++ /* if there is no i_mutex lock in VFS, we don't need to wait */ ++ /* AuDebugOn(!lockdep_depth(current)); */ ++ while (sbi->si_plink_maint_pid) { ++ si_read_unlock(sb); ++ /* gave up wake_up_bit() */ ++ wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid); ++ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&sbi->si_nowait); ++ si_noflush_read_lock(sb); ++ } ++ } else if (au_ftest_lock(flags, NOPLM)) { ++ AuDbg("ppid %d, pid %d\n", ppid, pid); ++ err = -EAGAIN; ++ } ++ ++out: ++ return err; ++} ++ ++void au_plink_maint_leave(struct au_sbinfo *sbinfo) ++{ ++ spin_lock(&sbinfo->si_plink_maint_lock); ++ sbinfo->si_plink_maint_pid = 0; ++ spin_unlock(&sbinfo->si_plink_maint_lock); ++ wake_up_all(&sbinfo->si_plink_wq); ++} ++ ++int au_plink_maint_enter(struct super_block *sb) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ /* make sure i am the only one in this fs */ ++ si_write_lock(sb, AuLock_FLUSH); ++ if (au_opt_test(au_mntflags(sb), PLINK)) { ++ spin_lock(&sbinfo->si_plink_maint_lock); ++ if (!sbinfo->si_plink_maint_pid) ++ sbinfo->si_plink_maint_pid = current->pid; ++ else ++ err = -EBUSY; ++ spin_unlock(&sbinfo->si_plink_maint_lock); ++ } ++ si_write_unlock(sb); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_DEBUG ++void au_plink_list(struct super_block *sb) ++{ ++ int i; ++ struct au_sbinfo *sbinfo; ++ struct hlist_head *plink_hlist; ++ struct pseudo_link *plink; ++ ++ SiMustAnyLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); ++ ++ for (i = 0; i < AuPlink_NHASH; i++) { ++ plink_hlist = &sbinfo->si_plink[i].head; ++ rcu_read_lock(); ++ hlist_for_each_entry_rcu(plink, plink_hlist, hlist) ++ AuDbg("%lu\n", plink->inode->i_ino); ++ rcu_read_unlock(); ++ } ++} ++#endif ++ ++/* is the inode pseudo-linked? */ ++int au_plink_test(struct inode *inode) ++{ ++ int found, i; ++ struct au_sbinfo *sbinfo; ++ struct hlist_head *plink_hlist; ++ struct pseudo_link *plink; ++ ++ sbinfo = au_sbi(inode->i_sb); ++ AuRwMustAnyLock(&sbinfo->si_rwsem); ++ AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK)); ++ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM)); ++ ++ found = 0; ++ i = au_plink_hash(inode->i_ino); ++ plink_hlist = &sbinfo->si_plink[i].head; ++ rcu_read_lock(); ++ hlist_for_each_entry_rcu(plink, plink_hlist, hlist) ++ if (plink->inode == inode) { ++ found = 1; ++ break; ++ } ++ rcu_read_unlock(); ++ return found; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * generate a name for plink. ++ * the file will be stored under AUFS_WH_PLINKDIR. ++ */ ++/* 20 is max digits length of ulong 64 */ ++#define PLINK_NAME_LEN ((20 + 1) * 2) ++ ++static int plink_name(char *name, int len, struct inode *inode, ++ aufs_bindex_t bindex) ++{ ++ int rlen; ++ struct inode *h_inode; ++ ++ h_inode = au_h_iptr(inode, bindex); ++ rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino); ++ return rlen; ++} ++ ++struct au_do_plink_lkup_args { ++ struct dentry **errp; ++ struct qstr *tgtname; ++ struct dentry *h_parent; ++ struct au_branch *br; ++}; ++ ++static struct dentry *au_do_plink_lkup(struct qstr *tgtname, ++ struct dentry *h_parent, ++ struct au_branch *br) ++{ ++ struct dentry *h_dentry; ++ struct mutex *h_mtx; ++ ++ h_mtx = &h_parent->d_inode->i_mutex; ++ mutex_lock_nested(h_mtx, AuLsc_I_CHILD2); ++ h_dentry = vfsub_lkup_one(tgtname, h_parent); ++ mutex_unlock(h_mtx); ++ return h_dentry; ++} ++ ++static void au_call_do_plink_lkup(void *args) ++{ ++ struct au_do_plink_lkup_args *a = args; ++ *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br); ++} ++ ++/* lookup the plink-ed @inode under the branch at @bindex */ ++struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex) ++{ ++ struct dentry *h_dentry, *h_parent; ++ struct au_branch *br; ++ struct inode *h_dir; ++ int wkq_err; ++ char a[PLINK_NAME_LEN]; ++ struct qstr tgtname = QSTR_INIT(a, 0); ++ ++ AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM)); ++ ++ br = au_sbr(inode->i_sb, bindex); ++ h_parent = br->br_wbr->wbr_plink; ++ h_dir = h_parent->d_inode; ++ tgtname.len = plink_name(a, sizeof(a), inode, bindex); ++ ++ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) { ++ struct au_do_plink_lkup_args args = { ++ .errp = &h_dentry, ++ .tgtname = &tgtname, ++ .h_parent = h_parent, ++ .br = br ++ }; ++ ++ wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args); ++ if (unlikely(wkq_err)) ++ h_dentry = ERR_PTR(wkq_err); ++ } else ++ h_dentry = au_do_plink_lkup(&tgtname, h_parent, br); ++ ++ return h_dentry; ++} ++ ++/* create a pseudo-link */ ++static int do_whplink(struct qstr *tgt, struct dentry *h_parent, ++ struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = au_br_mnt(br) ++ }; ++ struct inode *h_dir, *delegated; ++ ++ h_dir = h_parent->d_inode; ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); ++again: ++ h_path.dentry = vfsub_lkup_one(tgt, h_parent); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ err = 0; ++ /* wh.plink dir is not monitored */ ++ /* todo: is it really safe? */ ++ if (h_path.dentry->d_inode ++ && h_path.dentry->d_inode != h_dentry->d_inode) { ++ delegated = NULL; ++ err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal unlink\n"); ++ iput(delegated); ++ } ++ dput(h_path.dentry); ++ h_path.dentry = NULL; ++ if (!err) ++ goto again; ++ } ++ if (!err && !h_path.dentry->d_inode) { ++ delegated = NULL; ++ err = vfsub_link(h_dentry, h_dir, &h_path, &delegated); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal link\n"); ++ iput(delegated); ++ } ++ } ++ dput(h_path.dentry); ++ ++out: ++ mutex_unlock(&h_dir->i_mutex); ++ return err; ++} ++ ++struct do_whplink_args { ++ int *errp; ++ struct qstr *tgt; ++ struct dentry *h_parent; ++ struct dentry *h_dentry; ++ struct au_branch *br; ++}; ++ ++static void call_do_whplink(void *args) ++{ ++ struct do_whplink_args *a = args; ++ *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br); ++} ++ ++static int whplink(struct dentry *h_dentry, struct inode *inode, ++ aufs_bindex_t bindex, struct au_branch *br) ++{ ++ int err, wkq_err; ++ struct au_wbr *wbr; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ char a[PLINK_NAME_LEN]; ++ struct qstr tgtname = QSTR_INIT(a, 0); ++ ++ wbr = au_sbr(inode->i_sb, bindex)->br_wbr; ++ h_parent = wbr->wbr_plink; ++ h_dir = h_parent->d_inode; ++ tgtname.len = plink_name(a, sizeof(a), inode, bindex); ++ ++ /* always superio. */ ++ if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) { ++ struct do_whplink_args args = { ++ .errp = &err, ++ .tgt = &tgtname, ++ .h_parent = h_parent, ++ .h_dentry = h_dentry, ++ .br = br ++ }; ++ wkq_err = au_wkq_wait(call_do_whplink, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } else ++ err = do_whplink(&tgtname, h_parent, h_dentry, br); ++ ++ return err; ++} ++ ++/* free a single plink */ ++static void do_put_plink(struct pseudo_link *plink, int do_del) ++{ ++ if (do_del) ++ hlist_del(&plink->hlist); ++ iput(plink->inode); ++ kfree(plink); ++} ++ ++static void do_put_plink_rcu(struct rcu_head *rcu) ++{ ++ struct pseudo_link *plink; ++ ++ plink = container_of(rcu, struct pseudo_link, rcu); ++ iput(plink->inode); ++ kfree(plink); ++} ++ ++/* ++ * create a new pseudo-link for @h_dentry on @bindex. ++ * the linked inode is held in aufs @inode. ++ */ ++void au_plink_append(struct inode *inode, aufs_bindex_t bindex, ++ struct dentry *h_dentry) ++{ ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ struct hlist_head *plink_hlist; ++ struct pseudo_link *plink, *tmp; ++ struct au_sphlhead *sphl; ++ int found, err, cnt, i; ++ ++ sb = inode->i_sb; ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); ++ ++ found = au_plink_test(inode); ++ if (found) ++ return; ++ ++ i = au_plink_hash(inode->i_ino); ++ sphl = sbinfo->si_plink + i; ++ plink_hlist = &sphl->head; ++ tmp = kmalloc(sizeof(*plink), GFP_NOFS); ++ if (tmp) ++ tmp->inode = au_igrab(inode); ++ else { ++ err = -ENOMEM; ++ goto out; ++ } ++ ++ spin_lock(&sphl->spin); ++ hlist_for_each_entry(plink, plink_hlist, hlist) { ++ if (plink->inode == inode) { ++ found = 1; ++ break; ++ } ++ } ++ if (!found) ++ hlist_add_head_rcu(&tmp->hlist, plink_hlist); ++ spin_unlock(&sphl->spin); ++ if (!found) { ++ cnt = au_sphl_count(sphl); ++#define msg "unexpectedly unblanced or too many pseudo-links" ++ if (cnt > AUFS_PLINK_WARN) ++ AuWarn1(msg ", %d\n", cnt); ++#undef msg ++ err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex)); ++ } else { ++ do_put_plink(tmp, 0); ++ return; ++ } ++ ++out: ++ if (unlikely(err)) { ++ pr_warn("err %d, damaged pseudo link.\n", err); ++ if (tmp) { ++ au_sphl_del_rcu(&tmp->hlist, sphl); ++ call_rcu(&tmp->rcu, do_put_plink_rcu); ++ } ++ } ++} ++ ++/* free all plinks */ ++void au_plink_put(struct super_block *sb, int verbose) ++{ ++ int i, warned; ++ struct au_sbinfo *sbinfo; ++ struct hlist_head *plink_hlist; ++ struct hlist_node *tmp; ++ struct pseudo_link *plink; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); ++ ++ /* no spin_lock since sbinfo is write-locked */ ++ warned = 0; ++ for (i = 0; i < AuPlink_NHASH; i++) { ++ plink_hlist = &sbinfo->si_plink[i].head; ++ if (!warned && verbose && !hlist_empty(plink_hlist)) { ++ pr_warn("pseudo-link is not flushed"); ++ warned = 1; ++ } ++ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) ++ do_put_plink(plink, 0); ++ INIT_HLIST_HEAD(plink_hlist); ++ } ++} ++ ++void au_plink_clean(struct super_block *sb, int verbose) ++{ ++ struct dentry *root; ++ ++ root = sb->s_root; ++ aufs_write_lock(root); ++ if (au_opt_test(au_mntflags(sb), PLINK)) ++ au_plink_put(sb, verbose); ++ aufs_write_unlock(root); ++} ++ ++static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id) ++{ ++ int do_put; ++ aufs_bindex_t bstart, bend, bindex; ++ ++ do_put = 0; ++ bstart = au_ibstart(inode); ++ bend = au_ibend(inode); ++ if (bstart >= 0) { ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ if (!au_h_iptr(inode, bindex) ++ || au_ii_br_id(inode, bindex) != br_id) ++ continue; ++ au_set_h_iptr(inode, bindex, NULL, 0); ++ do_put = 1; ++ break; ++ } ++ if (do_put) ++ for (bindex = bstart; bindex <= bend; bindex++) ++ if (au_h_iptr(inode, bindex)) { ++ do_put = 0; ++ break; ++ } ++ } else ++ do_put = 1; ++ ++ return do_put; ++} ++ ++/* free the plinks on a branch specified by @br_id */ ++void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id) ++{ ++ struct au_sbinfo *sbinfo; ++ struct hlist_head *plink_hlist; ++ struct hlist_node *tmp; ++ struct pseudo_link *plink; ++ struct inode *inode; ++ int i, do_put; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); ++ AuDebugOn(au_plink_maint(sb, AuLock_NOPLM)); ++ ++ /* no spin_lock since sbinfo is write-locked */ ++ for (i = 0; i < AuPlink_NHASH; i++) { ++ plink_hlist = &sbinfo->si_plink[i].head; ++ hlist_for_each_entry_safe(plink, tmp, plink_hlist, hlist) { ++ inode = au_igrab(plink->inode); ++ ii_write_lock_child(inode); ++ do_put = au_plink_do_half_refresh(inode, br_id); ++ if (do_put) ++ do_put_plink(plink, 1); ++ ii_write_unlock(inode); ++ iput(inode); ++ } ++ } ++} +diff --git a/fs/aufs/poll.c b/fs/aufs/poll.c +new file mode 100644 +index 0000000..9a1fbbd +--- /dev/null ++++ b/fs/aufs/poll.c +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * poll operation ++ * There is only one filesystem which implements ->poll operation, currently. ++ */ ++ ++#include "aufs.h" ++ ++unsigned int aufs_poll(struct file *file, poll_table *wait) ++{ ++ unsigned int mask; ++ int err; ++ struct file *h_file; ++ struct dentry *dentry; ++ struct super_block *sb; ++ ++ /* We should pretend an error happened. */ ++ mask = POLLERR /* | POLLIN | POLLOUT */; ++ dentry = file->f_path.dentry; ++ sb = dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW); ++ err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0); ++ if (unlikely(err)) ++ goto out; ++ ++ /* it is not an error if h_file has no operation */ ++ mask = DEFAULT_POLLMASK; ++ h_file = au_hf_top(file); ++ if (h_file->f_op->poll) ++ mask = h_file->f_op->poll(h_file, wait); ++ ++ di_read_unlock(dentry, AuLock_IR); ++ fi_read_unlock(file); ++ ++out: ++ si_read_unlock(sb); ++ AuTraceErr((int)mask); ++ return mask; ++} +diff --git a/fs/aufs/posix_acl.c b/fs/aufs/posix_acl.c +new file mode 100644 +index 0000000..d9ce957 +--- /dev/null ++++ b/fs/aufs/posix_acl.c +@@ -0,0 +1,86 @@ ++/* ++ * Copyright (C) 2014-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * posix acl operations ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++struct posix_acl *aufs_get_acl(struct inode *inode, int type) ++{ ++ struct posix_acl *acl; ++ int err; ++ aufs_bindex_t bindex; ++ struct inode *h_inode; ++ struct super_block *sb; ++ ++ acl = NULL; ++ sb = inode->i_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ ii_read_lock_child(inode); ++ if (!(sb->s_flags & MS_POSIXACL)) ++ goto out; ++ ++ bindex = au_ibstart(inode); ++ h_inode = au_h_iptr(inode, bindex); ++ if (unlikely(!h_inode ++ || ((h_inode->i_mode & S_IFMT) ++ != (inode->i_mode & S_IFMT)))) { ++ err = au_busy_or_stale(); ++ acl = ERR_PTR(err); ++ goto out; ++ } ++ ++ /* always topmost only */ ++ acl = get_acl(h_inode, type); ++ ++out: ++ ii_read_unlock(inode); ++ si_read_unlock(sb); ++ ++ AuTraceErrPtr(acl); ++ return acl; ++} ++ ++int aufs_set_acl(struct inode *inode, struct posix_acl *acl, int type) ++{ ++ int err; ++ ssize_t ssz; ++ struct dentry *dentry; ++ struct au_srxattr arg = { ++ .type = AU_ACL_SET, ++ .u.acl_set = { ++ .acl = acl, ++ .type = type ++ }, ++ }; ++ ++ mutex_lock(&inode->i_mutex); ++ if (inode->i_ino == AUFS_ROOT_INO) ++ dentry = dget(inode->i_sb->s_root); ++ else { ++ dentry = d_find_alias(inode); ++ if (!dentry) ++ dentry = d_find_any_alias(inode); ++ if (!dentry) { ++ pr_warn("cannot handle this inode, " ++ "please report to aufs-users ML\n"); ++ err = -ENOENT; ++ goto out; ++ } ++ } ++ ++ ssz = au_srxattr(dentry, &arg); ++ dput(dentry); ++ err = ssz; ++ if (ssz >= 0) ++ err = 0; ++ ++out: ++ mutex_unlock(&inode->i_mutex); ++ return err; ++} +diff --git a/fs/aufs/procfs.c b/fs/aufs/procfs.c +new file mode 100644 +index 0000000..ead2a00 +--- /dev/null ++++ b/fs/aufs/procfs.c +@@ -0,0 +1,156 @@ ++/* ++ * Copyright (C) 2010-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * procfs interfaces ++ */ ++ ++#include ++#include "aufs.h" ++ ++static int au_procfs_plm_release(struct inode *inode, struct file *file) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = file->private_data; ++ if (sbinfo) { ++ au_plink_maint_leave(sbinfo); ++ kobject_put(&sbinfo->si_kobj); ++ } ++ ++ return 0; ++} ++ ++static void au_procfs_plm_write_clean(struct file *file) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = file->private_data; ++ if (sbinfo) ++ au_plink_clean(sbinfo->si_sb, /*verbose*/0); ++} ++ ++static int au_procfs_plm_write_si(struct file *file, unsigned long id) ++{ ++ int err; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ err = -EBUSY; ++ if (unlikely(file->private_data)) ++ goto out; ++ ++ sb = NULL; ++ /* don't use au_sbilist_lock() here */ ++ spin_lock(&au_sbilist.spin); ++ list_for_each_entry(sbinfo, &au_sbilist.head, si_list) ++ if (id == sysaufs_si_id(sbinfo)) { ++ kobject_get(&sbinfo->si_kobj); ++ sb = sbinfo->si_sb; ++ break; ++ } ++ spin_unlock(&au_sbilist.spin); ++ ++ err = -EINVAL; ++ if (unlikely(!sb)) ++ goto out; ++ ++ err = au_plink_maint_enter(sb); ++ if (!err) ++ /* keep kobject_get() */ ++ file->private_data = sbinfo; ++ else ++ kobject_put(&sbinfo->si_kobj); ++out: ++ return err; ++} ++ ++/* ++ * Accept a valid "si=xxxx" only. ++ * Once it is accepted successfully, accept "clean" too. ++ */ ++static ssize_t au_procfs_plm_write(struct file *file, const char __user *ubuf, ++ size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ unsigned long id; ++ /* last newline is allowed */ ++ char buf[3 + sizeof(unsigned long) * 2 + 1]; ++ ++ err = -EACCES; ++ if (unlikely(!capable(CAP_SYS_ADMIN))) ++ goto out; ++ ++ err = -EINVAL; ++ if (unlikely(count > sizeof(buf))) ++ goto out; ++ ++ err = copy_from_user(buf, ubuf, count); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ goto out; ++ } ++ buf[count] = 0; ++ ++ err = -EINVAL; ++ if (!strcmp("clean", buf)) { ++ au_procfs_plm_write_clean(file); ++ goto out_success; ++ } else if (unlikely(strncmp("si=", buf, 3))) ++ goto out; ++ ++ err = kstrtoul(buf + 3, 16, &id); ++ if (unlikely(err)) ++ goto out; ++ ++ err = au_procfs_plm_write_si(file, id); ++ if (unlikely(err)) ++ goto out; ++ ++out_success: ++ err = count; /* success */ ++out: ++ return err; ++} ++ ++static const struct file_operations au_procfs_plm_fop = { ++ .write = au_procfs_plm_write, ++ .release = au_procfs_plm_release, ++ .owner = THIS_MODULE ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct proc_dir_entry *au_procfs_dir; ++ ++void au_procfs_fin(void) ++{ ++ remove_proc_entry(AUFS_PLINK_MAINT_NAME, au_procfs_dir); ++ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL); ++} ++ ++int __init au_procfs_init(void) ++{ ++ int err; ++ struct proc_dir_entry *entry; ++ ++ err = -ENOMEM; ++ au_procfs_dir = proc_mkdir(AUFS_PLINK_MAINT_DIR, NULL); ++ if (unlikely(!au_procfs_dir)) ++ goto out; ++ ++ entry = proc_create(AUFS_PLINK_MAINT_NAME, S_IFREG | S_IWUSR, ++ au_procfs_dir, &au_procfs_plm_fop); ++ if (unlikely(!entry)) ++ goto out_dir; ++ ++ err = 0; ++ goto out; /* success */ ++ ++ ++out_dir: ++ remove_proc_entry(AUFS_PLINK_MAINT_DIR, NULL); ++out: ++ return err; ++} +diff --git a/fs/aufs/rdu.c b/fs/aufs/rdu.c +new file mode 100644 +index 0000000..6a34e48 +--- /dev/null ++++ b/fs/aufs/rdu.c +@@ -0,0 +1,375 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * readdir in userspace. ++ */ ++ ++#include ++#include ++#include ++#include "aufs.h" ++ ++/* bits for struct aufs_rdu.flags */ ++#define AuRdu_CALLED 1 ++#define AuRdu_CONT (1 << 1) ++#define AuRdu_FULL (1 << 2) ++#define au_ftest_rdu(flags, name) ((flags) & AuRdu_##name) ++#define au_fset_rdu(flags, name) \ ++ do { (flags) |= AuRdu_##name; } while (0) ++#define au_fclr_rdu(flags, name) \ ++ do { (flags) &= ~AuRdu_##name; } while (0) ++ ++struct au_rdu_arg { ++ struct dir_context ctx; ++ struct aufs_rdu *rdu; ++ union au_rdu_ent_ul ent; ++ unsigned long end; ++ ++ struct super_block *sb; ++ int err; ++}; ++ ++static int au_rdu_fill(struct dir_context *ctx, const char *name, int nlen, ++ loff_t offset, u64 h_ino, unsigned int d_type) ++{ ++ int err, len; ++ struct au_rdu_arg *arg = container_of(ctx, struct au_rdu_arg, ctx); ++ struct aufs_rdu *rdu = arg->rdu; ++ struct au_rdu_ent ent; ++ ++ err = 0; ++ arg->err = 0; ++ au_fset_rdu(rdu->cookie.flags, CALLED); ++ len = au_rdu_len(nlen); ++ if (arg->ent.ul + len < arg->end) { ++ ent.ino = h_ino; ++ ent.bindex = rdu->cookie.bindex; ++ ent.type = d_type; ++ ent.nlen = nlen; ++ if (unlikely(nlen > AUFS_MAX_NAMELEN)) ++ ent.type = DT_UNKNOWN; ++ ++ /* unnecessary to support mmap_sem since this is a dir */ ++ err = -EFAULT; ++ if (copy_to_user(arg->ent.e, &ent, sizeof(ent))) ++ goto out; ++ if (copy_to_user(arg->ent.e->name, name, nlen)) ++ goto out; ++ /* the terminating NULL */ ++ if (__put_user(0, arg->ent.e->name + nlen)) ++ goto out; ++ err = 0; ++ /* AuDbg("%p, %.*s\n", arg->ent.p, nlen, name); */ ++ arg->ent.ul += len; ++ rdu->rent++; ++ } else { ++ err = -EFAULT; ++ au_fset_rdu(rdu->cookie.flags, FULL); ++ rdu->full = 1; ++ rdu->tail = arg->ent; ++ } ++ ++out: ++ /* AuTraceErr(err); */ ++ return err; ++} ++ ++static int au_rdu_do(struct file *h_file, struct au_rdu_arg *arg) ++{ ++ int err; ++ loff_t offset; ++ struct au_rdu_cookie *cookie = &arg->rdu->cookie; ++ ++ /* we don't have to care (FMODE_32BITHASH | FMODE_64BITHASH) for ext4 */ ++ offset = vfsub_llseek(h_file, cookie->h_pos, SEEK_SET); ++ err = offset; ++ if (unlikely(offset != cookie->h_pos)) ++ goto out; ++ ++ err = 0; ++ do { ++ arg->err = 0; ++ au_fclr_rdu(cookie->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_iterate_dir(h_file, &arg->ctx); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err ++ && au_ftest_rdu(cookie->flags, CALLED) ++ && !au_ftest_rdu(cookie->flags, FULL)); ++ cookie->h_pos = h_file->f_pos; ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_rdu(struct file *file, struct aufs_rdu *rdu) ++{ ++ int err; ++ aufs_bindex_t bend; ++ struct au_rdu_arg arg = { ++ .ctx = { ++ .actor = au_rdu_fill ++ } ++ }; ++ struct dentry *dentry; ++ struct inode *inode; ++ struct file *h_file; ++ struct au_rdu_cookie *cookie = &rdu->cookie; ++ ++ err = !access_ok(VERIFY_WRITE, rdu->ent.e, rdu->sz); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out; ++ } ++ rdu->rent = 0; ++ rdu->tail = rdu->ent; ++ rdu->full = 0; ++ arg.rdu = rdu; ++ arg.ent = rdu->ent; ++ arg.end = arg.ent.ul; ++ arg.end += rdu->sz; ++ ++ err = -ENOTDIR; ++ if (unlikely(!file->f_op->iterate)) ++ goto out; ++ ++ err = security_file_permission(file, MAY_READ); ++ AuTraceErr(err); ++ if (unlikely(err)) ++ goto out; ++ ++ dentry = file->f_path.dentry; ++ inode = dentry->d_inode; ++#if 1 ++ mutex_lock(&inode->i_mutex); ++#else ++ err = mutex_lock_killable(&inode->i_mutex); ++ AuTraceErr(err); ++ if (unlikely(err)) ++ goto out; ++#endif ++ ++ arg.sb = inode->i_sb; ++ err = si_read_lock(arg.sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (unlikely(err)) ++ goto out_mtx; ++ err = au_alive_dir(dentry); ++ if (unlikely(err)) ++ goto out_si; ++ /* todo: reval? */ ++ fi_read_lock(file); ++ ++ err = -EAGAIN; ++ if (unlikely(au_ftest_rdu(cookie->flags, CONT) ++ && cookie->generation != au_figen(file))) ++ goto out_unlock; ++ ++ err = 0; ++ if (!rdu->blk) { ++ rdu->blk = au_sbi(arg.sb)->si_rdblk; ++ if (!rdu->blk) ++ rdu->blk = au_dir_size(file, /*dentry*/NULL); ++ } ++ bend = au_fbstart(file); ++ if (cookie->bindex < bend) ++ cookie->bindex = bend; ++ bend = au_fbend_dir(file); ++ /* AuDbg("b%d, b%d\n", cookie->bindex, bend); */ ++ for (; !err && cookie->bindex <= bend; ++ cookie->bindex++, cookie->h_pos = 0) { ++ h_file = au_hf_dir(file, cookie->bindex); ++ if (!h_file) ++ continue; ++ ++ au_fclr_rdu(cookie->flags, FULL); ++ err = au_rdu_do(h_file, &arg); ++ AuTraceErr(err); ++ if (unlikely(au_ftest_rdu(cookie->flags, FULL) || err)) ++ break; ++ } ++ AuDbg("rent %llu\n", rdu->rent); ++ ++ if (!err && !au_ftest_rdu(cookie->flags, CONT)) { ++ rdu->shwh = !!au_opt_test(au_sbi(arg.sb)->si_mntflags, SHWH); ++ au_fset_rdu(cookie->flags, CONT); ++ cookie->generation = au_figen(file); ++ } ++ ++ ii_read_lock_child(inode); ++ fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode))); ++ ii_read_unlock(inode); ++ ++out_unlock: ++ fi_read_unlock(file); ++out_si: ++ si_read_unlock(arg.sb); ++out_mtx: ++ mutex_unlock(&inode->i_mutex); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_rdu_ino(struct file *file, struct aufs_rdu *rdu) ++{ ++ int err; ++ ino_t ino; ++ unsigned long long nent; ++ union au_rdu_ent_ul *u; ++ struct au_rdu_ent ent; ++ struct super_block *sb; ++ ++ err = 0; ++ nent = rdu->nent; ++ u = &rdu->ent; ++ sb = file->f_path.dentry->d_sb; ++ si_read_lock(sb, AuLock_FLUSH); ++ while (nent-- > 0) { ++ /* unnecessary to support mmap_sem since this is a dir */ ++ err = copy_from_user(&ent, u->e, sizeof(ent)); ++ if (!err) ++ err = !access_ok(VERIFY_WRITE, &u->e->ino, sizeof(ino)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ break; ++ } ++ ++ /* AuDbg("b%d, i%llu\n", ent.bindex, ent.ino); */ ++ if (!ent.wh) ++ err = au_ino(sb, ent.bindex, ent.ino, ent.type, &ino); ++ else ++ err = au_wh_ino(sb, ent.bindex, ent.ino, ent.type, ++ &ino); ++ if (unlikely(err)) { ++ AuTraceErr(err); ++ break; ++ } ++ ++ err = __put_user(ino, &u->e->ino); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ break; ++ } ++ u->ul += au_rdu_len(ent.nlen); ++ } ++ si_read_unlock(sb); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_rdu_verify(struct aufs_rdu *rdu) ++{ ++ AuDbg("rdu{%llu, %p, %u | %u | %llu, %u, %u | " ++ "%llu, b%d, 0x%x, g%u}\n", ++ rdu->sz, rdu->ent.e, rdu->verify[AufsCtlRduV_SZ], ++ rdu->blk, ++ rdu->rent, rdu->shwh, rdu->full, ++ rdu->cookie.h_pos, rdu->cookie.bindex, rdu->cookie.flags, ++ rdu->cookie.generation); ++ ++ if (rdu->verify[AufsCtlRduV_SZ] == sizeof(*rdu)) ++ return 0; ++ ++ AuDbg("%u:%u\n", ++ rdu->verify[AufsCtlRduV_SZ], (unsigned int)sizeof(*rdu)); ++ return -EINVAL; ++} ++ ++long au_rdu_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err, e; ++ struct aufs_rdu rdu; ++ void __user *p = (void __user *)arg; ++ ++ err = copy_from_user(&rdu, p, sizeof(rdu)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out; ++ } ++ err = au_rdu_verify(&rdu); ++ if (unlikely(err)) ++ goto out; ++ ++ switch (cmd) { ++ case AUFS_CTL_RDU: ++ err = au_rdu(file, &rdu); ++ if (unlikely(err)) ++ break; ++ ++ e = copy_to_user(p, &rdu, sizeof(rdu)); ++ if (unlikely(e)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ } ++ break; ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_ino(file, &rdu); ++ break; ++ ++ default: ++ /* err = -ENOTTY; */ ++ err = -EINVAL; ++ } ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++#ifdef CONFIG_COMPAT ++long au_rdu_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ long err, e; ++ struct aufs_rdu rdu; ++ void __user *p = compat_ptr(arg); ++ ++ /* todo: get_user()? */ ++ err = copy_from_user(&rdu, p, sizeof(rdu)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out; ++ } ++ rdu.ent.e = compat_ptr(rdu.ent.ul); ++ err = au_rdu_verify(&rdu); ++ if (unlikely(err)) ++ goto out; ++ ++ switch (cmd) { ++ case AUFS_CTL_RDU: ++ err = au_rdu(file, &rdu); ++ if (unlikely(err)) ++ break; ++ ++ rdu.ent.ul = ptr_to_compat(rdu.ent.e); ++ rdu.tail.ul = ptr_to_compat(rdu.tail.e); ++ e = copy_to_user(p, &rdu, sizeof(rdu)); ++ if (unlikely(e)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ } ++ break; ++ case AUFS_CTL_RDU_INO: ++ err = au_rdu_ino(file, &rdu); ++ break; ++ ++ default: ++ /* err = -ENOTTY; */ ++ err = -EINVAL; ++ } ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++#endif +diff --git a/fs/aufs/rwsem.h b/fs/aufs/rwsem.h +new file mode 100644 +index 0000000..171ee0c +--- /dev/null ++++ b/fs/aufs/rwsem.h +@@ -0,0 +1,178 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * simple read-write semaphore wrappers ++ */ ++ ++#ifndef __AUFS_RWSEM_H__ ++#define __AUFS_RWSEM_H__ ++ ++#ifdef __KERNEL__ ++ ++#include "debug.h" ++ ++struct au_rwsem { ++ struct rw_semaphore rwsem; ++#ifdef CONFIG_AUFS_DEBUG ++ /* just for debugging, not almighty counter */ ++ atomic_t rcnt, wcnt; ++#endif ++}; ++ ++#ifdef CONFIG_AUFS_DEBUG ++#define AuDbgCntInit(rw) do { \ ++ atomic_set(&(rw)->rcnt, 0); \ ++ atomic_set(&(rw)->wcnt, 0); \ ++ smp_mb(); /* atomic set */ \ ++} while (0) ++ ++#define AuDbgRcntInc(rw) atomic_inc(&(rw)->rcnt) ++#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0) ++#define AuDbgWcntInc(rw) atomic_inc(&(rw)->wcnt) ++#define AuDbgWcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->wcnt) < 0) ++#else ++#define AuDbgCntInit(rw) do {} while (0) ++#define AuDbgRcntInc(rw) do {} while (0) ++#define AuDbgRcntDec(rw) do {} while (0) ++#define AuDbgWcntInc(rw) do {} while (0) ++#define AuDbgWcntDec(rw) do {} while (0) ++#endif /* CONFIG_AUFS_DEBUG */ ++ ++/* to debug easier, do not make them inlined functions */ ++#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list)) ++/* rwsem_is_locked() is unusable */ ++#define AuRwMustReadLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0) ++#define AuRwMustWriteLock(rw) AuDebugOn(atomic_read(&(rw)->wcnt) <= 0) ++#define AuRwMustAnyLock(rw) AuDebugOn(atomic_read(&(rw)->rcnt) <= 0 \ ++ && atomic_read(&(rw)->wcnt) <= 0) ++#define AuRwDestroy(rw) AuDebugOn(atomic_read(&(rw)->rcnt) \ ++ || atomic_read(&(rw)->wcnt)) ++ ++#define au_rw_class(rw, key) lockdep_set_class(&(rw)->rwsem, key) ++ ++static inline void au_rw_init(struct au_rwsem *rw) ++{ ++ AuDbgCntInit(rw); ++ init_rwsem(&rw->rwsem); ++} ++ ++static inline void au_rw_init_wlock(struct au_rwsem *rw) ++{ ++ au_rw_init(rw); ++ down_write(&rw->rwsem); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_init_wlock_nested(struct au_rwsem *rw, ++ unsigned int lsc) ++{ ++ au_rw_init(rw); ++ down_write_nested(&rw->rwsem, lsc); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_read_lock(struct au_rwsem *rw) ++{ ++ down_read(&rw->rwsem); ++ AuDbgRcntInc(rw); ++} ++ ++static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc) ++{ ++ down_read_nested(&rw->rwsem, lsc); ++ AuDbgRcntInc(rw); ++} ++ ++static inline void au_rw_read_unlock(struct au_rwsem *rw) ++{ ++ AuRwMustReadLock(rw); ++ AuDbgRcntDec(rw); ++ up_read(&rw->rwsem); ++} ++ ++static inline void au_rw_dgrade_lock(struct au_rwsem *rw) ++{ ++ AuRwMustWriteLock(rw); ++ AuDbgRcntInc(rw); ++ AuDbgWcntDec(rw); ++ downgrade_write(&rw->rwsem); ++} ++ ++static inline void au_rw_write_lock(struct au_rwsem *rw) ++{ ++ down_write(&rw->rwsem); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_write_lock_nested(struct au_rwsem *rw, ++ unsigned int lsc) ++{ ++ down_write_nested(&rw->rwsem, lsc); ++ AuDbgWcntInc(rw); ++} ++ ++static inline void au_rw_write_unlock(struct au_rwsem *rw) ++{ ++ AuRwMustWriteLock(rw); ++ AuDbgWcntDec(rw); ++ up_write(&rw->rwsem); ++} ++ ++/* why is not _nested version defined */ ++static inline int au_rw_read_trylock(struct au_rwsem *rw) ++{ ++ int ret; ++ ++ ret = down_read_trylock(&rw->rwsem); ++ if (ret) ++ AuDbgRcntInc(rw); ++ return ret; ++} ++ ++static inline int au_rw_write_trylock(struct au_rwsem *rw) ++{ ++ int ret; ++ ++ ret = down_write_trylock(&rw->rwsem); ++ if (ret) ++ AuDbgWcntInc(rw); ++ return ret; ++} ++ ++#undef AuDbgCntInit ++#undef AuDbgRcntInc ++#undef AuDbgRcntDec ++#undef AuDbgWcntInc ++#undef AuDbgWcntDec ++ ++#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ ++static inline void prefix##_read_lock(param) \ ++{ au_rw_read_lock(rwsem); } \ ++static inline void prefix##_write_lock(param) \ ++{ au_rw_write_lock(rwsem); } \ ++static inline int prefix##_read_trylock(param) \ ++{ return au_rw_read_trylock(rwsem); } \ ++static inline int prefix##_write_trylock(param) \ ++{ return au_rw_write_trylock(rwsem); } ++/* why is not _nested version defined */ ++/* static inline void prefix##_read_trylock_nested(param, lsc) ++{ au_rw_read_trylock_nested(rwsem, lsc)); } ++static inline void prefix##_write_trylock_nestd(param, lsc) ++{ au_rw_write_trylock_nested(rwsem, lsc); } */ ++ ++#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \ ++static inline void prefix##_read_unlock(param) \ ++{ au_rw_read_unlock(rwsem); } \ ++static inline void prefix##_write_unlock(param) \ ++{ au_rw_write_unlock(rwsem); } \ ++static inline void prefix##_downgrade_lock(param) \ ++{ au_rw_dgrade_lock(rwsem); } ++ ++#define AuSimpleRwsemFuncs(prefix, param, rwsem) \ ++ AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ ++ AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_RWSEM_H__ */ +diff --git a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c +new file mode 100644 +index 0000000..34ef9fb +--- /dev/null ++++ b/fs/aufs/sbinfo.c +@@ -0,0 +1,340 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * superblock private data ++ */ ++ ++#include "aufs.h" ++ ++/* ++ * they are necessary regardless sysfs is disabled. ++ */ ++void au_si_free(struct kobject *kobj) ++{ ++ int i; ++ struct au_sbinfo *sbinfo; ++ char *locked __maybe_unused; /* debug only */ ++ ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ for (i = 0; i < AuPlink_NHASH; i++) ++ AuDebugOn(!hlist_empty(&sbinfo->si_plink[i].head)); ++ AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len)); ++ ++ au_rw_write_lock(&sbinfo->si_rwsem); ++ au_br_free(sbinfo); ++ au_rw_write_unlock(&sbinfo->si_rwsem); ++ ++ AuDebugOn(radix_tree_gang_lookup ++ (&sbinfo->au_si_pid.tree, (void **)&locked, ++ /*first_index*/PID_MAX_DEFAULT - 1, ++ /*max_items*/sizeof(locked)/sizeof(*locked))); ++ ++ kfree(sbinfo->si_branch); ++ kfree(sbinfo->au_si_pid.bitmap); ++ mutex_destroy(&sbinfo->si_xib_mtx); ++ AuRwDestroy(&sbinfo->si_rwsem); ++ ++ kfree(sbinfo); ++} ++ ++int au_si_alloc(struct super_block *sb) ++{ ++ int err, i; ++ struct au_sbinfo *sbinfo; ++ static struct lock_class_key aufs_si; ++ ++ err = -ENOMEM; ++ sbinfo = kzalloc(sizeof(*sbinfo), GFP_NOFS); ++ if (unlikely(!sbinfo)) ++ goto out; ++ ++ BUILD_BUG_ON(sizeof(unsigned long) != ++ sizeof(*sbinfo->au_si_pid.bitmap)); ++ sbinfo->au_si_pid.bitmap = kcalloc(BITS_TO_LONGS(PID_MAX_DEFAULT), ++ sizeof(*sbinfo->au_si_pid.bitmap), ++ GFP_NOFS); ++ if (unlikely(!sbinfo->au_si_pid.bitmap)) ++ goto out_sbinfo; ++ ++ /* will be reallocated separately */ ++ sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); ++ if (unlikely(!sbinfo->si_branch)) ++ goto out_pidmap; ++ ++ err = sysaufs_si_init(sbinfo); ++ if (unlikely(err)) ++ goto out_br; ++ ++ au_nwt_init(&sbinfo->si_nowait); ++ au_rw_init_wlock(&sbinfo->si_rwsem); ++ au_rw_class(&sbinfo->si_rwsem, &aufs_si); ++ spin_lock_init(&sbinfo->au_si_pid.tree_lock); ++ INIT_RADIX_TREE(&sbinfo->au_si_pid.tree, GFP_ATOMIC | __GFP_NOFAIL); ++ ++ atomic_long_set(&sbinfo->si_ninodes, 0); ++ atomic_long_set(&sbinfo->si_nfiles, 0); ++ ++ sbinfo->si_bend = -1; ++ sbinfo->si_last_br_id = AUFS_BRANCH_MAX / 2; ++ ++ sbinfo->si_wbr_copyup = AuWbrCopyup_Def; ++ sbinfo->si_wbr_create = AuWbrCreate_Def; ++ sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + sbinfo->si_wbr_copyup; ++ sbinfo->si_wbr_create_ops = au_wbr_create_ops + sbinfo->si_wbr_create; ++ ++ au_fhsm_init(sbinfo); ++ ++ sbinfo->si_mntflags = au_opts_plink(AuOpt_Def); ++ ++ sbinfo->si_xino_jiffy = jiffies; ++ sbinfo->si_xino_expire ++ = msecs_to_jiffies(AUFS_XINO_DEF_SEC * MSEC_PER_SEC); ++ mutex_init(&sbinfo->si_xib_mtx); ++ sbinfo->si_xino_brid = -1; ++ /* leave si_xib_last_pindex and si_xib_next_bit */ ++ ++ sbinfo->si_rdcache = msecs_to_jiffies(AUFS_RDCACHE_DEF * MSEC_PER_SEC); ++ sbinfo->si_rdblk = AUFS_RDBLK_DEF; ++ sbinfo->si_rdhash = AUFS_RDHASH_DEF; ++ sbinfo->si_dirwh = AUFS_DIRWH_DEF; ++ ++ for (i = 0; i < AuPlink_NHASH; i++) ++ au_sphl_init(sbinfo->si_plink + i); ++ init_waitqueue_head(&sbinfo->si_plink_wq); ++ spin_lock_init(&sbinfo->si_plink_maint_lock); ++ ++ au_sphl_init(&sbinfo->si_files); ++ ++ /* leave other members for sysaufs and si_mnt. */ ++ sbinfo->si_sb = sb; ++ sb->s_fs_info = sbinfo; ++ si_pid_set(sb); ++ au_debug_sbinfo_init(sbinfo); ++ return 0; /* success */ ++ ++out_br: ++ kfree(sbinfo->si_branch); ++out_pidmap: ++ kfree(sbinfo->au_si_pid.bitmap); ++out_sbinfo: ++ kfree(sbinfo); ++out: ++ return err; ++} ++ ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr) ++{ ++ int err, sz; ++ struct au_branch **brp; ++ ++ AuRwMustWriteLock(&sbinfo->si_rwsem); ++ ++ err = -ENOMEM; ++ sz = sizeof(*brp) * (sbinfo->si_bend + 1); ++ if (unlikely(!sz)) ++ sz = sizeof(*brp); ++ brp = au_kzrealloc(sbinfo->si_branch, sz, sizeof(*brp) * nbr, GFP_NOFS); ++ if (brp) { ++ sbinfo->si_branch = brp; ++ err = 0; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++unsigned int au_sigen_inc(struct super_block *sb) ++{ ++ unsigned int gen; ++ ++ SiMustWriteLock(sb); ++ ++ gen = ++au_sbi(sb)->si_generation; ++ au_update_digen(sb->s_root); ++ au_update_iigen(sb->s_root->d_inode, /*half*/0); ++ sb->s_root->d_inode->i_version++; ++ return gen; ++} ++ ++aufs_bindex_t au_new_br_id(struct super_block *sb) ++{ ++ aufs_bindex_t br_id; ++ int i; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ for (i = 0; i <= AUFS_BRANCH_MAX; i++) { ++ br_id = ++sbinfo->si_last_br_id; ++ AuDebugOn(br_id < 0); ++ if (br_id && au_br_index(sb, br_id) < 0) ++ return br_id; ++ } ++ ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* it is ok that new 'nwt' tasks are appended while we are sleeping */ ++int si_read_lock(struct super_block *sb, int flags) ++{ ++ int err; ++ ++ err = 0; ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ ++ si_noflush_read_lock(sb); ++ err = au_plink_maint(sb, flags); ++ if (unlikely(err)) ++ si_read_unlock(sb); ++ ++ return err; ++} ++ ++int si_write_lock(struct super_block *sb, int flags) ++{ ++ int err; ++ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ ++ si_noflush_write_lock(sb); ++ err = au_plink_maint(sb, flags); ++ if (unlikely(err)) ++ si_write_unlock(sb); ++ ++ return err; ++} ++ ++/* dentry and super_block lock. call at entry point */ ++int aufs_read_lock(struct dentry *dentry, int flags) ++{ ++ int err; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ err = si_read_lock(sb, flags); ++ if (unlikely(err)) ++ goto out; ++ ++ if (au_ftest_lock(flags, DW)) ++ di_write_lock_child(dentry); ++ else ++ di_read_lock_child(dentry, flags); ++ ++ if (au_ftest_lock(flags, GEN)) { ++ err = au_digen_test(dentry, au_sigen(sb)); ++ AuDebugOn(!err && au_dbrange_test(dentry)); ++ if (unlikely(err)) ++ aufs_read_unlock(dentry, flags); ++ } ++ ++out: ++ return err; ++} ++ ++void aufs_read_unlock(struct dentry *dentry, int flags) ++{ ++ if (au_ftest_lock(flags, DW)) ++ di_write_unlock(dentry); ++ else ++ di_read_unlock(dentry, flags); ++ si_read_unlock(dentry->d_sb); ++} ++ ++void aufs_write_lock(struct dentry *dentry) ++{ ++ si_write_lock(dentry->d_sb, AuLock_FLUSH | AuLock_NOPLMW); ++ di_write_lock_child(dentry); ++} ++ ++void aufs_write_unlock(struct dentry *dentry) ++{ ++ di_write_unlock(dentry); ++ si_write_unlock(dentry->d_sb); ++} ++ ++int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags) ++{ ++ int err; ++ unsigned int sigen; ++ struct super_block *sb; ++ ++ sb = d1->d_sb; ++ err = si_read_lock(sb, flags); ++ if (unlikely(err)) ++ goto out; ++ ++ di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR)); ++ ++ if (au_ftest_lock(flags, GEN)) { ++ sigen = au_sigen(sb); ++ err = au_digen_test(d1, sigen); ++ AuDebugOn(!err && au_dbrange_test(d1)); ++ if (!err) { ++ err = au_digen_test(d2, sigen); ++ AuDebugOn(!err && au_dbrange_test(d2)); ++ } ++ if (unlikely(err)) ++ aufs_read_and_write_unlock2(d1, d2); ++ } ++ ++out: ++ return err; ++} ++ ++void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2) ++{ ++ di_write_unlock2(d1, d2); ++ si_read_unlock(d1->d_sb); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int si_pid_test_slow(struct super_block *sb) ++{ ++ void *p; ++ ++ rcu_read_lock(); ++ p = radix_tree_lookup(&au_sbi(sb)->au_si_pid.tree, current->pid); ++ rcu_read_unlock(); ++ ++ return (long)!!p; ++} ++ ++void si_pid_set_slow(struct super_block *sb) ++{ ++ int err; ++ struct au_sbinfo *sbinfo; ++ ++ AuDebugOn(si_pid_test_slow(sb)); ++ ++ sbinfo = au_sbi(sb); ++ err = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL); ++ AuDebugOn(err); ++ spin_lock(&sbinfo->au_si_pid.tree_lock); ++ err = radix_tree_insert(&sbinfo->au_si_pid.tree, current->pid, ++ /*any valid ptr*/sb); ++ spin_unlock(&sbinfo->au_si_pid.tree_lock); ++ AuDebugOn(err); ++ radix_tree_preload_end(); ++} ++ ++void si_pid_clr_slow(struct super_block *sb) ++{ ++ void *p; ++ struct au_sbinfo *sbinfo; ++ ++ AuDebugOn(!si_pid_test_slow(sb)); ++ ++ sbinfo = au_sbi(sb); ++ spin_lock(&sbinfo->au_si_pid.tree_lock); ++ p = radix_tree_delete(&sbinfo->au_si_pid.tree, current->pid); ++ spin_unlock(&sbinfo->au_si_pid.tree_lock); ++} +diff --git a/fs/aufs/spl.h b/fs/aufs/spl.h +new file mode 100644 +index 0000000..a66d39e +--- /dev/null ++++ b/fs/aufs/spl.h +@@ -0,0 +1,98 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * simple list protected by a spinlock ++ */ ++ ++#ifndef __AUFS_SPL_H__ ++#define __AUFS_SPL_H__ ++ ++#ifdef __KERNEL__ ++ ++struct au_splhead { ++ spinlock_t spin; ++ struct list_head head; ++}; ++ ++static inline void au_spl_init(struct au_splhead *spl) ++{ ++ spin_lock_init(&spl->spin); ++ INIT_LIST_HEAD(&spl->head); ++} ++ ++static inline void au_spl_add(struct list_head *list, struct au_splhead *spl) ++{ ++ spin_lock(&spl->spin); ++ list_add(list, &spl->head); ++ spin_unlock(&spl->spin); ++} ++ ++static inline void au_spl_del(struct list_head *list, struct au_splhead *spl) ++{ ++ spin_lock(&spl->spin); ++ list_del(list); ++ spin_unlock(&spl->spin); ++} ++ ++static inline void au_spl_del_rcu(struct list_head *list, ++ struct au_splhead *spl) ++{ ++ spin_lock(&spl->spin); ++ list_del_rcu(list); ++ spin_unlock(&spl->spin); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_sphlhead { ++ spinlock_t spin; ++ struct hlist_head head; ++}; ++ ++static inline void au_sphl_init(struct au_sphlhead *sphl) ++{ ++ spin_lock_init(&sphl->spin); ++ INIT_HLIST_HEAD(&sphl->head); ++} ++ ++static inline void au_sphl_add(struct hlist_node *hlist, ++ struct au_sphlhead *sphl) ++{ ++ spin_lock(&sphl->spin); ++ hlist_add_head(hlist, &sphl->head); ++ spin_unlock(&sphl->spin); ++} ++ ++static inline void au_sphl_del(struct hlist_node *hlist, ++ struct au_sphlhead *sphl) ++{ ++ spin_lock(&sphl->spin); ++ hlist_del(hlist); ++ spin_unlock(&sphl->spin); ++} ++ ++static inline void au_sphl_del_rcu(struct hlist_node *hlist, ++ struct au_sphlhead *sphl) ++{ ++ spin_lock(&sphl->spin); ++ hlist_del_rcu(hlist); ++ spin_unlock(&sphl->spin); ++} ++ ++static inline unsigned long au_sphl_count(struct au_sphlhead *sphl) ++{ ++ unsigned long cnt; ++ struct hlist_node *pos; ++ ++ cnt = 0; ++ spin_lock(&sphl->spin); ++ hlist_for_each(pos, &sphl->head) ++ cnt++; ++ spin_unlock(&sphl->spin); ++ return cnt; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_SPL_H__ */ +diff --git a/fs/aufs/super.c b/fs/aufs/super.c +new file mode 100644 +index 0000000..9acda0e +--- /dev/null ++++ b/fs/aufs/super.c +@@ -0,0 +1,996 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * mount and super_block operations ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++/* ++ * super_operations ++ */ ++static struct inode *aufs_alloc_inode(struct super_block *sb __maybe_unused) ++{ ++ struct au_icntnr *c; ++ ++ c = au_cache_alloc_icntnr(); ++ if (c) { ++ au_icntnr_init(c); ++ c->vfs_inode.i_version = 1; /* sigen(sb); */ ++ c->iinfo.ii_hinode = NULL; ++ return &c->vfs_inode; ++ } ++ return NULL; ++} ++ ++static void aufs_destroy_inode_cb(struct rcu_head *head) ++{ ++ struct inode *inode = container_of(head, struct inode, i_rcu); ++ ++ INIT_HLIST_HEAD(&inode->i_dentry); ++ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); ++} ++ ++static void aufs_destroy_inode(struct inode *inode) ++{ ++ au_iinfo_fin(inode); ++ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb); ++} ++ ++struct inode *au_iget_locked(struct super_block *sb, ino_t ino) ++{ ++ struct inode *inode; ++ int err; ++ ++ inode = iget_locked(sb, ino); ++ if (unlikely(!inode)) { ++ inode = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ if (!(inode->i_state & I_NEW)) ++ goto out; ++ ++ err = au_xigen_new(inode); ++ if (!err) ++ err = au_iinfo_init(inode); ++ if (!err) ++ inode->i_version++; ++ else { ++ iget_failed(inode); ++ inode = ERR_PTR(err); ++ } ++ ++out: ++ /* never return NULL */ ++ AuDebugOn(!inode); ++ AuTraceErrPtr(inode); ++ return inode; ++} ++ ++/* lock free root dinfo */ ++static int au_show_brs(struct seq_file *seq, struct super_block *sb) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ struct path path; ++ struct au_hdentry *hdp; ++ struct au_branch *br; ++ au_br_perm_str_t perm; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ hdp = au_di(sb->s_root)->di_hdentry; ++ for (bindex = 0; !err && bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ path.mnt = au_br_mnt(br); ++ path.dentry = hdp[bindex].hd_dentry; ++ err = au_seq_path(seq, &path); ++ if (err > 0) { ++ au_optstr_br_perm(&perm, br->br_perm); ++ err = seq_printf(seq, "=%s", perm.a); ++ if (err == -1) ++ err = -E2BIG; ++ } ++ if (!err && bindex != bend) ++ err = seq_putc(seq, ':'); ++ } ++ ++ return err; ++} ++ ++static void au_show_wbr_create(struct seq_file *m, int v, ++ struct au_sbinfo *sbinfo) ++{ ++ const char *pat; ++ ++ AuRwMustAnyLock(&sbinfo->si_rwsem); ++ ++ seq_puts(m, ",create="); ++ pat = au_optstr_wbr_create(v); ++ switch (v) { ++ case AuWbrCreate_TDP: ++ case AuWbrCreate_RR: ++ case AuWbrCreate_MFS: ++ case AuWbrCreate_PMFS: ++ seq_puts(m, pat); ++ break; ++ case AuWbrCreate_MFSV: ++ seq_printf(m, /*pat*/"mfs:%lu", ++ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire) ++ / MSEC_PER_SEC); ++ break; ++ case AuWbrCreate_PMFSV: ++ seq_printf(m, /*pat*/"pmfs:%lu", ++ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire) ++ / MSEC_PER_SEC); ++ break; ++ case AuWbrCreate_MFSRR: ++ seq_printf(m, /*pat*/"mfsrr:%llu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark); ++ break; ++ case AuWbrCreate_MFSRRV: ++ seq_printf(m, /*pat*/"mfsrr:%llu:%lu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark, ++ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire) ++ / MSEC_PER_SEC); ++ break; ++ case AuWbrCreate_PMFSRR: ++ seq_printf(m, /*pat*/"pmfsrr:%llu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark); ++ break; ++ case AuWbrCreate_PMFSRRV: ++ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu", ++ sbinfo->si_wbr_mfs.mfsrr_watermark, ++ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire) ++ / MSEC_PER_SEC); ++ break; ++ } ++} ++ ++static int au_show_xino(struct seq_file *seq, struct super_block *sb) ++{ ++#ifdef CONFIG_SYSFS ++ return 0; ++#else ++ int err; ++ const int len = sizeof(AUFS_XINO_FNAME) - 1; ++ aufs_bindex_t bindex, brid; ++ struct qstr *name; ++ struct file *f; ++ struct dentry *d, *h_root; ++ struct au_hdentry *hdp; ++ ++ AuRwMustAnyLock(&sbinfo->si_rwsem); ++ ++ err = 0; ++ f = au_sbi(sb)->si_xib; ++ if (!f) ++ goto out; ++ ++ /* stop printing the default xino path on the first writable branch */ ++ h_root = NULL; ++ brid = au_xino_brid(sb); ++ if (brid >= 0) { ++ bindex = au_br_index(sb, brid); ++ hdp = au_di(sb->s_root)->di_hdentry; ++ h_root = hdp[0 + bindex].hd_dentry; ++ } ++ d = f->f_path.dentry; ++ name = &d->d_name; ++ /* safe ->d_parent because the file is unlinked */ ++ if (d->d_parent == h_root ++ && name->len == len ++ && !memcmp(name->name, AUFS_XINO_FNAME, len)) ++ goto out; ++ ++ seq_puts(seq, ",xino="); ++ err = au_xino_path(seq, f); ++ ++out: ++ return err; ++#endif ++} ++ ++/* seq_file will re-call me in case of too long string */ ++static int aufs_show_options(struct seq_file *m, struct dentry *dentry) ++{ ++ int err; ++ unsigned int mnt_flags, v; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++#define AuBool(name, str) do { \ ++ v = au_opt_test(mnt_flags, name); \ ++ if (v != au_opt_test(AuOpt_Def, name)) \ ++ seq_printf(m, ",%s" #str, v ? "" : "no"); \ ++} while (0) ++ ++#define AuStr(name, str) do { \ ++ v = mnt_flags & AuOptMask_##name; \ ++ if (v != (AuOpt_Def & AuOptMask_##name)) \ ++ seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ ++} while (0) ++ ++#define AuUInt(name, str, val) do { \ ++ if (val != AUFS_##name##_DEF) \ ++ seq_printf(m, "," #str "=%u", val); \ ++} while (0) ++ ++ sb = dentry->d_sb; ++ if (sb->s_flags & MS_POSIXACL) ++ seq_puts(m, ",acl"); ++ ++ /* lock free root dinfo */ ++ si_noflush_read_lock(sb); ++ sbinfo = au_sbi(sb); ++ seq_printf(m, ",si=%lx", sysaufs_si_id(sbinfo)); ++ ++ mnt_flags = au_mntflags(sb); ++ if (au_opt_test(mnt_flags, XINO)) { ++ err = au_show_xino(m, sb); ++ if (unlikely(err)) ++ goto out; ++ } else ++ seq_puts(m, ",noxino"); ++ ++ AuBool(TRUNC_XINO, trunc_xino); ++ AuStr(UDBA, udba); ++ AuBool(SHWH, shwh); ++ AuBool(PLINK, plink); ++ AuBool(DIO, dio); ++ AuBool(DIRPERM1, dirperm1); ++ /* AuBool(REFROF, refrof); */ ++ ++ v = sbinfo->si_wbr_create; ++ if (v != AuWbrCreate_Def) ++ au_show_wbr_create(m, v, sbinfo); ++ ++ v = sbinfo->si_wbr_copyup; ++ if (v != AuWbrCopyup_Def) ++ seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); ++ ++ v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); ++ if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) ++ seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); ++ ++ AuUInt(DIRWH, dirwh, sbinfo->si_dirwh); ++ ++ v = jiffies_to_msecs(sbinfo->si_rdcache) / MSEC_PER_SEC; ++ AuUInt(RDCACHE, rdcache, v); ++ ++ AuUInt(RDBLK, rdblk, sbinfo->si_rdblk); ++ AuUInt(RDHASH, rdhash, sbinfo->si_rdhash); ++ ++ au_fhsm_show(m, sbinfo); ++ ++ AuBool(SUM, sum); ++ /* AuBool(SUM_W, wsum); */ ++ AuBool(WARN_PERM, warn_perm); ++ AuBool(VERBOSE, verbose); ++ ++out: ++ /* be sure to print "br:" last */ ++ if (!sysaufs_brs) { ++ seq_puts(m, ",br:"); ++ au_show_brs(m, sb); ++ } ++ si_read_unlock(sb); ++ return 0; ++ ++#undef AuBool ++#undef AuStr ++#undef AuUInt ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* sum mode which returns the summation for statfs(2) */ ++ ++static u64 au_add_till_max(u64 a, u64 b) ++{ ++ u64 old; ++ ++ old = a; ++ a += b; ++ if (old <= a) ++ return a; ++ return ULLONG_MAX; ++} ++ ++static u64 au_mul_till_max(u64 a, long mul) ++{ ++ u64 old; ++ ++ old = a; ++ a *= mul; ++ if (old <= a) ++ return a; ++ return ULLONG_MAX; ++} ++ ++static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf) ++{ ++ int err; ++ long bsize, factor; ++ u64 blocks, bfree, bavail, files, ffree; ++ aufs_bindex_t bend, bindex, i; ++ unsigned char shared; ++ struct path h_path; ++ struct super_block *h_sb; ++ ++ err = 0; ++ bsize = LONG_MAX; ++ files = 0; ++ ffree = 0; ++ blocks = 0; ++ bfree = 0; ++ bavail = 0; ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ h_path.mnt = au_sbr_mnt(sb, bindex); ++ h_sb = h_path.mnt->mnt_sb; ++ shared = 0; ++ for (i = 0; !shared && i < bindex; i++) ++ shared = (au_sbr_sb(sb, i) == h_sb); ++ if (shared) ++ continue; ++ ++ /* sb->s_root for NFS is unreliable */ ++ h_path.dentry = h_path.mnt->mnt_root; ++ err = vfs_statfs(&h_path, buf); ++ if (unlikely(err)) ++ goto out; ++ ++ if (bsize > buf->f_bsize) { ++ /* ++ * we will reduce bsize, so we have to expand blocks ++ * etc. to match them again ++ */ ++ factor = (bsize / buf->f_bsize); ++ blocks = au_mul_till_max(blocks, factor); ++ bfree = au_mul_till_max(bfree, factor); ++ bavail = au_mul_till_max(bavail, factor); ++ bsize = buf->f_bsize; ++ } ++ ++ factor = (buf->f_bsize / bsize); ++ blocks = au_add_till_max(blocks, ++ au_mul_till_max(buf->f_blocks, factor)); ++ bfree = au_add_till_max(bfree, ++ au_mul_till_max(buf->f_bfree, factor)); ++ bavail = au_add_till_max(bavail, ++ au_mul_till_max(buf->f_bavail, factor)); ++ files = au_add_till_max(files, buf->f_files); ++ ffree = au_add_till_max(ffree, buf->f_ffree); ++ } ++ ++ buf->f_bsize = bsize; ++ buf->f_blocks = blocks; ++ buf->f_bfree = bfree; ++ buf->f_bavail = bavail; ++ buf->f_files = files; ++ buf->f_ffree = ffree; ++ buf->f_frsize = 0; ++ ++out: ++ return err; ++} ++ ++static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) ++{ ++ int err; ++ struct path h_path; ++ struct super_block *sb; ++ ++ /* lock free root dinfo */ ++ sb = dentry->d_sb; ++ si_noflush_read_lock(sb); ++ if (!au_opt_test(au_mntflags(sb), SUM)) { ++ /* sb->s_root for NFS is unreliable */ ++ h_path.mnt = au_sbr_mnt(sb, 0); ++ h_path.dentry = h_path.mnt->mnt_root; ++ err = vfs_statfs(&h_path, buf); ++ } else ++ err = au_statfs_sum(sb, buf); ++ si_read_unlock(sb); ++ ++ if (!err) { ++ buf->f_type = AUFS_SUPER_MAGIC; ++ buf->f_namelen = AUFS_MAX_NAMELEN; ++ memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); ++ } ++ /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int aufs_sync_fs(struct super_block *sb, int wait) ++{ ++ int err, e; ++ aufs_bindex_t bend, bindex; ++ struct au_branch *br; ++ struct super_block *h_sb; ++ ++ err = 0; ++ si_noflush_read_lock(sb); ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (!au_br_writable(br->br_perm)) ++ continue; ++ ++ h_sb = au_sbr_sb(sb, bindex); ++ if (h_sb->s_op->sync_fs) { ++ e = h_sb->s_op->sync_fs(h_sb, wait); ++ if (unlikely(e && !err)) ++ err = e; ++ /* go on even if an error happens */ ++ } ++ } ++ si_read_unlock(sb); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* final actions when unmounting a file system */ ++static void aufs_put_super(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ if (!sbinfo) ++ return; ++ ++ dbgaufs_si_fin(sbinfo); ++ kobject_put(&sbinfo->si_kobj); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_array_free(void *array) ++{ ++ if (array) { ++ if (!is_vmalloc_addr(array)) ++ kfree(array); ++ else ++ vfree(array); ++ } ++} ++ ++void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg) ++{ ++ void *array; ++ unsigned long long n, sz; ++ ++ array = NULL; ++ n = 0; ++ if (!*hint) ++ goto out; ++ ++ if (*hint > ULLONG_MAX / sizeof(array)) { ++ array = ERR_PTR(-EMFILE); ++ pr_err("hint %llu\n", *hint); ++ goto out; ++ } ++ ++ sz = sizeof(array) * *hint; ++ array = kzalloc(sz, GFP_NOFS); ++ if (unlikely(!array)) ++ array = vzalloc(sz); ++ if (unlikely(!array)) { ++ array = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ ++ n = cb(array, *hint, arg); ++ AuDebugOn(n > *hint); ++ ++out: ++ *hint = n; ++ return array; ++} ++ ++static unsigned long long au_iarray_cb(void *a, ++ unsigned long long max __maybe_unused, ++ void *arg) ++{ ++ unsigned long long n; ++ struct inode **p, *inode; ++ struct list_head *head; ++ ++ n = 0; ++ p = a; ++ head = arg; ++ spin_lock(&inode_sb_list_lock); ++ list_for_each_entry(inode, head, i_sb_list) { ++ if (!is_bad_inode(inode) ++ && au_ii(inode)->ii_bstart >= 0) { ++ spin_lock(&inode->i_lock); ++ if (atomic_read(&inode->i_count)) { ++ au_igrab(inode); ++ *p++ = inode; ++ n++; ++ AuDebugOn(n > max); ++ } ++ spin_unlock(&inode->i_lock); ++ } ++ } ++ spin_unlock(&inode_sb_list_lock); ++ ++ return n; ++} ++ ++struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max) ++{ ++ *max = atomic_long_read(&au_sbi(sb)->si_ninodes); ++ return au_array_alloc(max, au_iarray_cb, &sb->s_inodes); ++} ++ ++void au_iarray_free(struct inode **a, unsigned long long max) ++{ ++ unsigned long long ull; ++ ++ for (ull = 0; ull < max; ull++) ++ iput(a[ull]); ++ au_array_free(a); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * refresh dentry and inode at remount time. ++ */ ++/* todo: consolidate with simple_reval_dpath() and au_reval_for_attr() */ ++static int au_do_refresh(struct dentry *dentry, unsigned int dir_flags, ++ struct dentry *parent) ++{ ++ int err; ++ ++ di_write_lock_child(dentry); ++ di_read_lock_parent(parent, AuLock_IR); ++ err = au_refresh_dentry(dentry, parent); ++ if (!err && dir_flags) ++ au_hn_reset(dentry->d_inode, dir_flags); ++ di_read_unlock(parent, AuLock_IR); ++ di_write_unlock(dentry); ++ ++ return err; ++} ++ ++static int au_do_refresh_d(struct dentry *dentry, unsigned int sigen, ++ struct au_sbinfo *sbinfo, ++ const unsigned int dir_flags) ++{ ++ int err; ++ struct dentry *parent; ++ struct inode *inode; ++ ++ err = 0; ++ parent = dget_parent(dentry); ++ if (!au_digen_test(parent, sigen) && au_digen_test(dentry, sigen)) { ++ inode = dentry->d_inode; ++ if (inode) { ++ if (!S_ISDIR(inode->i_mode)) ++ err = au_do_refresh(dentry, /*dir_flags*/0, ++ parent); ++ else { ++ err = au_do_refresh(dentry, dir_flags, parent); ++ if (unlikely(err)) ++ au_fset_si(sbinfo, FAILED_REFRESH_DIR); ++ } ++ } else ++ err = au_do_refresh(dentry, /*dir_flags*/0, parent); ++ AuDbgDentry(dentry); ++ } ++ dput(parent); ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_refresh_d(struct super_block *sb) ++{ ++ int err, i, j, ndentry, e; ++ unsigned int sigen; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries, *d; ++ struct au_sbinfo *sbinfo; ++ struct dentry *root = sb->s_root; ++ const unsigned int dir_flags = au_hi_flags(root->d_inode, /*isdir*/1); ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_dcsub_pages(&dpages, root, NULL, NULL); ++ if (unlikely(err)) ++ goto out_dpages; ++ ++ sigen = au_sigen(sb); ++ sbinfo = au_sbi(sb); ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) { ++ d = dentries[j]; ++ e = au_do_refresh_d(d, sigen, sbinfo, dir_flags); ++ if (unlikely(e && !err)) ++ err = e; ++ /* go on even err */ ++ } ++ } ++ ++out_dpages: ++ au_dpages_free(&dpages); ++out: ++ return err; ++} ++ ++static int au_refresh_i(struct super_block *sb) ++{ ++ int err, e; ++ unsigned int sigen; ++ unsigned long long max, ull; ++ struct inode *inode, **array; ++ ++ array = au_iarray_alloc(sb, &max); ++ err = PTR_ERR(array); ++ if (IS_ERR(array)) ++ goto out; ++ ++ err = 0; ++ sigen = au_sigen(sb); ++ for (ull = 0; ull < max; ull++) { ++ inode = array[ull]; ++ if (unlikely(!inode)) ++ break; ++ if (au_iigen(inode, NULL) != sigen) { ++ ii_write_lock_child(inode); ++ e = au_refresh_hinode_self(inode); ++ ii_write_unlock(inode); ++ if (unlikely(e)) { ++ pr_err("error %d, i%lu\n", e, inode->i_ino); ++ if (!err) ++ err = e; ++ /* go on even if err */ ++ } ++ } ++ } ++ ++ au_iarray_free(array, max); ++ ++out: ++ return err; ++} ++ ++static void au_remount_refresh(struct super_block *sb) ++{ ++ int err, e; ++ unsigned int udba; ++ aufs_bindex_t bindex, bend; ++ struct dentry *root; ++ struct inode *inode; ++ struct au_branch *br; ++ ++ au_sigen_inc(sb); ++ au_fclr_si(au_sbi(sb), FAILED_REFRESH_DIR); ++ ++ root = sb->s_root; ++ DiMustNoWaiters(root); ++ inode = root->d_inode; ++ IiMustNoWaiters(inode); ++ ++ udba = au_opt_udba(sb); ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ err = au_hnotify_reset_br(udba, br, br->br_perm); ++ if (unlikely(err)) ++ AuIOErr("hnotify failed on br %d, %d, ignored\n", ++ bindex, err); ++ /* go on even if err */ ++ } ++ au_hn_reset(inode, au_hi_flags(inode, /*isdir*/1)); ++ ++ di_write_unlock(root); ++ err = au_refresh_d(sb); ++ e = au_refresh_i(sb); ++ if (unlikely(e && !err)) ++ err = e; ++ /* aufs_write_lock() calls ..._child() */ ++ di_write_lock_child(root); ++ ++ au_cpup_attr_all(inode, /*force*/1); ++ ++ if (unlikely(err)) ++ AuIOErr("refresh failed, ignored, %d\n", err); ++} ++ ++/* stop extra interpretation of errno in mount(8), and strange error messages */ ++static int cvt_err(int err) ++{ ++ AuTraceErr(err); ++ ++ switch (err) { ++ case -ENOENT: ++ case -ENOTDIR: ++ case -EEXIST: ++ case -EIO: ++ err = -EINVAL; ++ } ++ return err; ++} ++ ++static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) ++{ ++ int err, do_dx; ++ unsigned int mntflags; ++ struct au_opts opts; ++ struct dentry *root; ++ struct inode *inode; ++ struct au_sbinfo *sbinfo; ++ ++ err = 0; ++ root = sb->s_root; ++ if (!data || !*data) { ++ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (!err) { ++ di_write_lock_child(root); ++ err = au_opts_verify(sb, *flags, /*pending*/0); ++ aufs_write_unlock(root); ++ } ++ goto out; ++ } ++ ++ err = -ENOMEM; ++ memset(&opts, 0, sizeof(opts)); ++ opts.opt = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!opts.opt)) ++ goto out; ++ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); ++ opts.flags = AuOpts_REMOUNT; ++ opts.sb_flags = *flags; ++ ++ /* parse it before aufs lock */ ++ err = au_opts_parse(sb, data, &opts); ++ if (unlikely(err)) ++ goto out_opts; ++ ++ sbinfo = au_sbi(sb); ++ inode = root->d_inode; ++ mutex_lock(&inode->i_mutex); ++ err = si_write_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (unlikely(err)) ++ goto out_mtx; ++ di_write_lock_child(root); ++ ++ /* au_opts_remount() may return an error */ ++ err = au_opts_remount(sb, &opts); ++ au_opts_free(&opts); ++ ++ if (au_ftest_opts(opts.flags, REFRESH)) ++ au_remount_refresh(sb); ++ ++ if (au_ftest_opts(opts.flags, REFRESH_DYAOP)) { ++ mntflags = au_mntflags(sb); ++ do_dx = !!au_opt_test(mntflags, DIO); ++ au_dy_arefresh(do_dx); ++ } ++ ++ au_fhsm_wrote_all(sb, /*force*/1); /* ?? */ ++ aufs_write_unlock(root); ++ ++out_mtx: ++ mutex_unlock(&inode->i_mutex); ++out_opts: ++ free_page((unsigned long)opts.opt); ++out: ++ err = cvt_err(err); ++ AuTraceErr(err); ++ return err; ++} ++ ++static const struct super_operations aufs_sop = { ++ .alloc_inode = aufs_alloc_inode, ++ .destroy_inode = aufs_destroy_inode, ++ /* always deleting, no clearing */ ++ .drop_inode = generic_delete_inode, ++ .show_options = aufs_show_options, ++ .statfs = aufs_statfs, ++ .put_super = aufs_put_super, ++ .sync_fs = aufs_sync_fs, ++ .remount_fs = aufs_remount_fs ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int alloc_root(struct super_block *sb) ++{ ++ int err; ++ struct inode *inode; ++ struct dentry *root; ++ ++ err = -ENOMEM; ++ inode = au_iget_locked(sb, AUFS_ROOT_INO); ++ err = PTR_ERR(inode); ++ if (IS_ERR(inode)) ++ goto out; ++ ++ inode->i_op = &aufs_dir_iop; ++ inode->i_fop = &aufs_dir_fop; ++ inode->i_mode = S_IFDIR; ++ set_nlink(inode, 2); ++ unlock_new_inode(inode); ++ ++ root = d_make_root(inode); ++ if (unlikely(!root)) ++ goto out; ++ err = PTR_ERR(root); ++ if (IS_ERR(root)) ++ goto out; ++ ++ err = au_di_init(root); ++ if (!err) { ++ sb->s_root = root; ++ return 0; /* success */ ++ } ++ dput(root); ++ ++out: ++ return err; ++} ++ ++static int aufs_fill_super(struct super_block *sb, void *raw_data, ++ int silent __maybe_unused) ++{ ++ int err; ++ struct au_opts opts; ++ struct dentry *root; ++ struct inode *inode; ++ char *arg = raw_data; ++ ++ if (unlikely(!arg || !*arg)) { ++ err = -EINVAL; ++ pr_err("no arg\n"); ++ goto out; ++ } ++ ++ err = -ENOMEM; ++ memset(&opts, 0, sizeof(opts)); ++ opts.opt = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!opts.opt)) ++ goto out; ++ opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); ++ opts.sb_flags = sb->s_flags; ++ ++ err = au_si_alloc(sb); ++ if (unlikely(err)) ++ goto out_opts; ++ ++ /* all timestamps always follow the ones on the branch */ ++ sb->s_flags |= MS_NOATIME | MS_NODIRATIME; ++ sb->s_op = &aufs_sop; ++ sb->s_d_op = &aufs_dop; ++ sb->s_magic = AUFS_SUPER_MAGIC; ++ sb->s_maxbytes = 0; ++ sb->s_stack_depth = 1; ++ au_export_init(sb); ++ /* au_xattr_init(sb); */ ++ ++ err = alloc_root(sb); ++ if (unlikely(err)) { ++ si_write_unlock(sb); ++ goto out_info; ++ } ++ root = sb->s_root; ++ inode = root->d_inode; ++ ++ /* ++ * actually we can parse options regardless aufs lock here. ++ * but at remount time, parsing must be done before aufs lock. ++ * so we follow the same rule. ++ */ ++ ii_write_lock_parent(inode); ++ aufs_write_unlock(root); ++ err = au_opts_parse(sb, arg, &opts); ++ if (unlikely(err)) ++ goto out_root; ++ ++ /* lock vfs_inode first, then aufs. */ ++ mutex_lock(&inode->i_mutex); ++ aufs_write_lock(root); ++ err = au_opts_mount(sb, &opts); ++ au_opts_free(&opts); ++ aufs_write_unlock(root); ++ mutex_unlock(&inode->i_mutex); ++ if (!err) ++ goto out_opts; /* success */ ++ ++out_root: ++ dput(root); ++ sb->s_root = NULL; ++out_info: ++ dbgaufs_si_fin(au_sbi(sb)); ++ kobject_put(&au_sbi(sb)->si_kobj); ++ sb->s_fs_info = NULL; ++out_opts: ++ free_page((unsigned long)opts.opt); ++out: ++ AuTraceErr(err); ++ err = cvt_err(err); ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct dentry *aufs_mount(struct file_system_type *fs_type, int flags, ++ const char *dev_name __maybe_unused, ++ void *raw_data) ++{ ++ struct dentry *root; ++ struct super_block *sb; ++ ++ /* all timestamps always follow the ones on the branch */ ++ /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ ++ root = mount_nodev(fs_type, flags, raw_data, aufs_fill_super); ++ if (IS_ERR(root)) ++ goto out; ++ ++ sb = root->d_sb; ++ si_write_lock(sb, !AuLock_FLUSH); ++ sysaufs_brs_add(sb, 0); ++ si_write_unlock(sb); ++ au_sbilist_add(sb); ++ ++out: ++ return root; ++} ++ ++static void aufs_kill_sb(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ sbinfo = au_sbi(sb); ++ if (sbinfo) { ++ au_sbilist_del(sb); ++ aufs_write_lock(sb->s_root); ++ au_fhsm_fin(sb); ++ if (sbinfo->si_wbr_create_ops->fin) ++ sbinfo->si_wbr_create_ops->fin(sb); ++ if (au_opt_test(sbinfo->si_mntflags, UDBA_HNOTIFY)) { ++ au_opt_set_udba(sbinfo->si_mntflags, UDBA_NONE); ++ au_remount_refresh(sb); ++ } ++ if (au_opt_test(sbinfo->si_mntflags, PLINK)) ++ au_plink_put(sb, /*verbose*/1); ++ au_xino_clr(sb); ++ sbinfo->si_sb = NULL; ++ aufs_write_unlock(sb->s_root); ++ au_nwt_flush(&sbinfo->si_nowait); ++ } ++ kill_anon_super(sb); ++} ++ ++struct file_system_type aufs_fs_type = { ++ .name = AUFS_FSTYPE, ++ /* a race between rename and others */ ++ .fs_flags = FS_RENAME_DOES_D_MOVE, ++ .mount = aufs_mount, ++ .kill_sb = aufs_kill_sb, ++ /* no need to __module_get() and module_put(). */ ++ .owner = THIS_MODULE, ++}; +diff --git a/fs/aufs/super.h b/fs/aufs/super.h +new file mode 100644 +index 0000000..0514a13 +--- /dev/null ++++ b/fs/aufs/super.h +@@ -0,0 +1,628 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * super_block operations ++ */ ++ ++#ifndef __AUFS_SUPER_H__ ++#define __AUFS_SUPER_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include "rwsem.h" ++#include "spl.h" ++#include "wkq.h" ++ ++typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *); ++typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t, ++ loff_t *); ++ ++/* policies to select one among multiple writable branches */ ++struct au_wbr_copyup_operations { ++ int (*copyup)(struct dentry *dentry); ++}; ++ ++#define AuWbr_DIR 1 /* target is a dir */ ++#define AuWbr_PARENT (1 << 1) /* always require a parent */ ++ ++#define au_ftest_wbr(flags, name) ((flags) & AuWbr_##name) ++#define au_fset_wbr(flags, name) { (flags) |= AuWbr_##name; } ++#define au_fclr_wbr(flags, name) { (flags) &= ~AuWbr_##name; } ++ ++struct au_wbr_create_operations { ++ int (*create)(struct dentry *dentry, unsigned int flags); ++ int (*init)(struct super_block *sb); ++ int (*fin)(struct super_block *sb); ++}; ++ ++struct au_wbr_mfs { ++ struct mutex mfs_lock; /* protect this structure */ ++ unsigned long mfs_jiffy; ++ unsigned long mfs_expire; ++ aufs_bindex_t mfs_bindex; ++ ++ unsigned long long mfsrr_bytes; ++ unsigned long long mfsrr_watermark; ++}; ++ ++struct pseudo_link { ++ union { ++ struct hlist_node hlist; ++ struct rcu_head rcu; ++ }; ++ struct inode *inode; ++}; ++ ++#define AuPlink_NHASH 100 ++static inline int au_plink_hash(ino_t ino) ++{ ++ return ino % AuPlink_NHASH; ++} ++ ++/* File-based Hierarchical Storage Management */ ++struct au_fhsm { ++#ifdef CONFIG_AUFS_FHSM ++ /* allow only one process who can receive the notification */ ++ spinlock_t fhsm_spin; ++ pid_t fhsm_pid; ++ wait_queue_head_t fhsm_wqh; ++ atomic_t fhsm_readable; ++ ++ /* these are protected by si_rwsem */ ++ unsigned long fhsm_expire; ++ aufs_bindex_t fhsm_bottom; ++#endif ++}; ++ ++struct au_branch; ++struct au_sbinfo { ++ /* nowait tasks in the system-wide workqueue */ ++ struct au_nowait_tasks si_nowait; ++ ++ /* ++ * tried sb->s_umount, but failed due to the dependecy between i_mutex. ++ * rwsem for au_sbinfo is necessary. ++ */ ++ struct au_rwsem si_rwsem; ++ ++ /* prevent recursive locking in deleting inode */ ++ struct { ++ unsigned long *bitmap; ++ spinlock_t tree_lock; ++ struct radix_tree_root tree; ++ } au_si_pid; ++ ++ /* ++ * dirty approach to protect sb->sb_inodes and ->s_files (gone) from ++ * remount. ++ */ ++ atomic_long_t si_ninodes, si_nfiles; ++ ++ /* branch management */ ++ unsigned int si_generation; ++ ++ /* see above flags */ ++ unsigned char au_si_status; ++ ++ aufs_bindex_t si_bend; ++ ++ /* dirty trick to keep br_id plus */ ++ unsigned int si_last_br_id : ++ sizeof(aufs_bindex_t) * BITS_PER_BYTE - 1; ++ struct au_branch **si_branch; ++ ++ /* policy to select a writable branch */ ++ unsigned char si_wbr_copyup; ++ unsigned char si_wbr_create; ++ struct au_wbr_copyup_operations *si_wbr_copyup_ops; ++ struct au_wbr_create_operations *si_wbr_create_ops; ++ ++ /* round robin */ ++ atomic_t si_wbr_rr_next; ++ ++ /* most free space */ ++ struct au_wbr_mfs si_wbr_mfs; ++ ++ /* File-based Hierarchical Storage Management */ ++ struct au_fhsm si_fhsm; ++ ++ /* mount flags */ ++ /* include/asm-ia64/siginfo.h defines a macro named si_flags */ ++ unsigned int si_mntflags; ++ ++ /* external inode number (bitmap and translation table) */ ++ au_readf_t si_xread; ++ au_writef_t si_xwrite; ++ struct file *si_xib; ++ struct mutex si_xib_mtx; /* protect xib members */ ++ unsigned long *si_xib_buf; ++ unsigned long si_xib_last_pindex; ++ int si_xib_next_bit; ++ aufs_bindex_t si_xino_brid; ++ unsigned long si_xino_jiffy; ++ unsigned long si_xino_expire; ++ /* reserved for future use */ ++ /* unsigned long long si_xib_limit; */ /* Max xib file size */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++ /* i_generation */ ++ struct file *si_xigen; ++ atomic_t si_xigen_next; ++#endif ++ ++ /* vdir parameters */ ++ unsigned long si_rdcache; /* max cache time in jiffies */ ++ unsigned int si_rdblk; /* deblk size */ ++ unsigned int si_rdhash; /* hash size */ ++ ++ /* ++ * If the number of whiteouts are larger than si_dirwh, leave all of ++ * them after au_whtmp_ren to reduce the cost of rmdir(2). ++ * future fsck.aufs or kernel thread will remove them later. ++ * Otherwise, remove all whiteouts and the dir in rmdir(2). ++ */ ++ unsigned int si_dirwh; ++ ++ /* ++ * rename(2) a directory with all children. ++ */ ++ /* reserved for future use */ ++ /* int si_rendir; */ ++ ++ /* pseudo_link list */ ++ struct au_sphlhead si_plink[AuPlink_NHASH]; ++ wait_queue_head_t si_plink_wq; ++ spinlock_t si_plink_maint_lock; ++ pid_t si_plink_maint_pid; ++ ++ /* file list */ ++ struct au_sphlhead si_files; ++ ++ /* ++ * sysfs and lifetime management. ++ * this is not a small structure and it may be a waste of memory in case ++ * of sysfs is disabled, particulary when many aufs-es are mounted. ++ * but using sysfs is majority. ++ */ ++ struct kobject si_kobj; ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *si_dbgaufs; ++ struct dentry *si_dbgaufs_plink; ++ struct dentry *si_dbgaufs_xib; ++#ifdef CONFIG_AUFS_EXPORT ++ struct dentry *si_dbgaufs_xigen; ++#endif ++#endif ++ ++#ifdef CONFIG_AUFS_SBILIST ++ struct list_head si_list; ++#endif ++ ++ /* dirty, necessary for unmounting, sysfs and sysrq */ ++ struct super_block *si_sb; ++}; ++ ++/* sbinfo status flags */ ++/* ++ * set true when refresh_dirs() failed at remount time. ++ * then try refreshing dirs at access time again. ++ * if it is false, refreshing dirs at access time is unnecesary ++ */ ++#define AuSi_FAILED_REFRESH_DIR 1 ++ ++#define AuSi_FHSM (1 << 1) /* fhsm is active now */ ++ ++#ifndef CONFIG_AUFS_FHSM ++#undef AuSi_FHSM ++#define AuSi_FHSM 0 ++#endif ++ ++static inline unsigned char au_do_ftest_si(struct au_sbinfo *sbi, ++ unsigned int flag) ++{ ++ AuRwMustAnyLock(&sbi->si_rwsem); ++ return sbi->au_si_status & flag; ++} ++#define au_ftest_si(sbinfo, name) au_do_ftest_si(sbinfo, AuSi_##name) ++#define au_fset_si(sbinfo, name) do { \ ++ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ ++ (sbinfo)->au_si_status |= AuSi_##name; \ ++} while (0) ++#define au_fclr_si(sbinfo, name) do { \ ++ AuRwMustWriteLock(&(sbinfo)->si_rwsem); \ ++ (sbinfo)->au_si_status &= ~AuSi_##name; \ ++} while (0) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policy to select one among writable branches */ ++#define AuWbrCopyup(sbinfo, ...) \ ++ ((sbinfo)->si_wbr_copyup_ops->copyup(__VA_ARGS__)) ++#define AuWbrCreate(sbinfo, ...) \ ++ ((sbinfo)->si_wbr_create_ops->create(__VA_ARGS__)) ++ ++/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ ++#define AuLock_DW 1 /* write-lock dentry */ ++#define AuLock_IR (1 << 1) /* read-lock inode */ ++#define AuLock_IW (1 << 2) /* write-lock inode */ ++#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ ++#define AuLock_DIR (1 << 4) /* target is a dir */ ++#define AuLock_NOPLM (1 << 5) /* return err in plm mode */ ++#define AuLock_NOPLMW (1 << 6) /* wait for plm mode ends */ ++#define AuLock_GEN (1 << 7) /* test digen/iigen */ ++#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) ++#define au_fset_lock(flags, name) \ ++ do { (flags) |= AuLock_##name; } while (0) ++#define au_fclr_lock(flags, name) \ ++ do { (flags) &= ~AuLock_##name; } while (0) ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* super.c */ ++extern struct file_system_type aufs_fs_type; ++struct inode *au_iget_locked(struct super_block *sb, ino_t ino); ++typedef unsigned long long (*au_arraycb_t)(void *array, unsigned long long max, ++ void *arg); ++void au_array_free(void *array); ++void *au_array_alloc(unsigned long long *hint, au_arraycb_t cb, void *arg); ++struct inode **au_iarray_alloc(struct super_block *sb, unsigned long long *max); ++void au_iarray_free(struct inode **a, unsigned long long max); ++ ++/* sbinfo.c */ ++void au_si_free(struct kobject *kobj); ++int au_si_alloc(struct super_block *sb); ++int au_sbr_realloc(struct au_sbinfo *sbinfo, int nbr); ++ ++unsigned int au_sigen_inc(struct super_block *sb); ++aufs_bindex_t au_new_br_id(struct super_block *sb); ++ ++int si_read_lock(struct super_block *sb, int flags); ++int si_write_lock(struct super_block *sb, int flags); ++int aufs_read_lock(struct dentry *dentry, int flags); ++void aufs_read_unlock(struct dentry *dentry, int flags); ++void aufs_write_lock(struct dentry *dentry); ++void aufs_write_unlock(struct dentry *dentry); ++int aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags); ++void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); ++ ++int si_pid_test_slow(struct super_block *sb); ++void si_pid_set_slow(struct super_block *sb); ++void si_pid_clr_slow(struct super_block *sb); ++ ++/* wbr_policy.c */ ++extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; ++extern struct au_wbr_create_operations au_wbr_create_ops[]; ++int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex); ++int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart); ++ ++/* mvdown.c */ ++int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg); ++ ++#ifdef CONFIG_AUFS_FHSM ++/* fhsm.c */ ++ ++static inline pid_t au_fhsm_pid(struct au_fhsm *fhsm) ++{ ++ pid_t pid; ++ ++ spin_lock(&fhsm->fhsm_spin); ++ pid = fhsm->fhsm_pid; ++ spin_unlock(&fhsm->fhsm_spin); ++ ++ return pid; ++} ++ ++void au_fhsm_wrote(struct super_block *sb, aufs_bindex_t bindex, int force); ++void au_fhsm_wrote_all(struct super_block *sb, int force); ++int au_fhsm_fd(struct super_block *sb, int oflags); ++int au_fhsm_br_alloc(struct au_branch *br); ++void au_fhsm_set_bottom(struct super_block *sb, aufs_bindex_t bindex); ++void au_fhsm_fin(struct super_block *sb); ++void au_fhsm_init(struct au_sbinfo *sbinfo); ++void au_fhsm_set(struct au_sbinfo *sbinfo, unsigned int sec); ++void au_fhsm_show(struct seq_file *seq, struct au_sbinfo *sbinfo); ++#else ++AuStubVoid(au_fhsm_wrote, struct super_block *sb, aufs_bindex_t bindex, ++ int force) ++AuStubVoid(au_fhsm_wrote_all, struct super_block *sb, int force) ++AuStub(int, au_fhsm_fd, return -EOPNOTSUPP, struct super_block *sb, int oflags) ++AuStub(pid_t, au_fhsm_pid, return 0, struct au_fhsm *fhsm) ++AuStubInt0(au_fhsm_br_alloc, struct au_branch *br) ++AuStubVoid(au_fhsm_set_bottom, struct super_block *sb, aufs_bindex_t bindex) ++AuStubVoid(au_fhsm_fin, struct super_block *sb) ++AuStubVoid(au_fhsm_init, struct au_sbinfo *sbinfo) ++AuStubVoid(au_fhsm_set, struct au_sbinfo *sbinfo, unsigned int sec) ++AuStubVoid(au_fhsm_show, struct seq_file *seq, struct au_sbinfo *sbinfo) ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct au_sbinfo *au_sbi(struct super_block *sb) ++{ ++ return sb->s_fs_info; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_EXPORT ++int au_test_nfsd(void); ++void au_export_init(struct super_block *sb); ++void au_xigen_inc(struct inode *inode); ++int au_xigen_new(struct inode *inode); ++int au_xigen_set(struct super_block *sb, struct file *base); ++void au_xigen_clr(struct super_block *sb); ++ ++static inline int au_busy_or_stale(void) ++{ ++ if (!au_test_nfsd()) ++ return -EBUSY; ++ return -ESTALE; ++} ++#else ++AuStubInt0(au_test_nfsd, void) ++AuStubVoid(au_export_init, struct super_block *sb) ++AuStubVoid(au_xigen_inc, struct inode *inode) ++AuStubInt0(au_xigen_new, struct inode *inode) ++AuStubInt0(au_xigen_set, struct super_block *sb, struct file *base) ++AuStubVoid(au_xigen_clr, struct super_block *sb) ++AuStub(int, au_busy_or_stale, return -EBUSY, void) ++#endif /* CONFIG_AUFS_EXPORT */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_SBILIST ++/* module.c */ ++extern struct au_splhead au_sbilist; ++ ++static inline void au_sbilist_init(void) ++{ ++ au_spl_init(&au_sbilist); ++} ++ ++static inline void au_sbilist_add(struct super_block *sb) ++{ ++ au_spl_add(&au_sbi(sb)->si_list, &au_sbilist); ++} ++ ++static inline void au_sbilist_del(struct super_block *sb) ++{ ++ au_spl_del(&au_sbi(sb)->si_list, &au_sbilist); ++} ++ ++#ifdef CONFIG_AUFS_MAGIC_SYSRQ ++static inline void au_sbilist_lock(void) ++{ ++ spin_lock(&au_sbilist.spin); ++} ++ ++static inline void au_sbilist_unlock(void) ++{ ++ spin_unlock(&au_sbilist.spin); ++} ++#define AuGFP_SBILIST GFP_ATOMIC ++#else ++AuStubVoid(au_sbilist_lock, void) ++AuStubVoid(au_sbilist_unlock, void) ++#define AuGFP_SBILIST GFP_NOFS ++#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ ++#else ++AuStubVoid(au_sbilist_init, void) ++AuStubVoid(au_sbilist_add, struct super_block *sb) ++AuStubVoid(au_sbilist_del, struct super_block *sb) ++AuStubVoid(au_sbilist_lock, void) ++AuStubVoid(au_sbilist_unlock, void) ++#define AuGFP_SBILIST GFP_NOFS ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void dbgaufs_si_null(struct au_sbinfo *sbinfo) ++{ ++ /* ++ * This function is a dynamic '__init' function actually, ++ * so the tiny check for si_rwsem is unnecessary. ++ */ ++ /* AuRwMustWriteLock(&sbinfo->si_rwsem); */ ++#ifdef CONFIG_DEBUG_FS ++ sbinfo->si_dbgaufs = NULL; ++ sbinfo->si_dbgaufs_plink = NULL; ++ sbinfo->si_dbgaufs_xib = NULL; ++#ifdef CONFIG_AUFS_EXPORT ++ sbinfo->si_dbgaufs_xigen = NULL; ++#endif ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline pid_t si_pid_bit(void) ++{ ++ /* the origin of pid is 1, but the bitmap's is 0 */ ++ return current->pid - 1; ++} ++ ++static inline int si_pid_test(struct super_block *sb) ++{ ++ pid_t bit; ++ ++ bit = si_pid_bit(); ++ if (bit < PID_MAX_DEFAULT) ++ return test_bit(bit, au_sbi(sb)->au_si_pid.bitmap); ++ return si_pid_test_slow(sb); ++} ++ ++static inline void si_pid_set(struct super_block *sb) ++{ ++ pid_t bit; ++ ++ bit = si_pid_bit(); ++ if (bit < PID_MAX_DEFAULT) { ++ AuDebugOn(test_bit(bit, au_sbi(sb)->au_si_pid.bitmap)); ++ set_bit(bit, au_sbi(sb)->au_si_pid.bitmap); ++ /* smp_mb(); */ ++ } else ++ si_pid_set_slow(sb); ++} ++ ++static inline void si_pid_clr(struct super_block *sb) ++{ ++ pid_t bit; ++ ++ bit = si_pid_bit(); ++ if (bit < PID_MAX_DEFAULT) { ++ AuDebugOn(!test_bit(bit, au_sbi(sb)->au_si_pid.bitmap)); ++ clear_bit(bit, au_sbi(sb)->au_si_pid.bitmap); ++ /* smp_mb(); */ ++ } else ++ si_pid_clr_slow(sb); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock superblock. mainly for entry point functions */ ++/* ++ * __si_read_lock, __si_write_lock, ++ * __si_read_unlock, __si_write_unlock, __si_downgrade_lock ++ */ ++AuSimpleRwsemFuncs(__si, struct super_block *sb, &au_sbi(sb)->si_rwsem); ++ ++#define SiMustNoWaiters(sb) AuRwMustNoWaiters(&au_sbi(sb)->si_rwsem) ++#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem) ++#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem) ++ ++static inline void si_noflush_read_lock(struct super_block *sb) ++{ ++ __si_read_lock(sb); ++ si_pid_set(sb); ++} ++ ++static inline int si_noflush_read_trylock(struct super_block *sb) ++{ ++ int locked; ++ ++ locked = __si_read_trylock(sb); ++ if (locked) ++ si_pid_set(sb); ++ return locked; ++} ++ ++static inline void si_noflush_write_lock(struct super_block *sb) ++{ ++ __si_write_lock(sb); ++ si_pid_set(sb); ++} ++ ++static inline int si_noflush_write_trylock(struct super_block *sb) ++{ ++ int locked; ++ ++ locked = __si_write_trylock(sb); ++ if (locked) ++ si_pid_set(sb); ++ return locked; ++} ++ ++#if 0 /* unused */ ++static inline int si_read_trylock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ return si_noflush_read_trylock(sb); ++} ++#endif ++ ++static inline void si_read_unlock(struct super_block *sb) ++{ ++ si_pid_clr(sb); ++ __si_read_unlock(sb); ++} ++ ++#if 0 /* unused */ ++static inline int si_write_trylock(struct super_block *sb, int flags) ++{ ++ if (au_ftest_lock(flags, FLUSH)) ++ au_nwt_flush(&au_sbi(sb)->si_nowait); ++ return si_noflush_write_trylock(sb); ++} ++#endif ++ ++static inline void si_write_unlock(struct super_block *sb) ++{ ++ si_pid_clr(sb); ++ __si_write_unlock(sb); ++} ++ ++#if 0 /* unused */ ++static inline void si_downgrade_lock(struct super_block *sb) ++{ ++ __si_downgrade_lock(sb); ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline aufs_bindex_t au_sbend(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_bend; ++} ++ ++static inline unsigned int au_mntflags(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_mntflags; ++} ++ ++static inline unsigned int au_sigen(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_generation; ++} ++ ++static inline void au_ninodes_inc(struct super_block *sb) ++{ ++ atomic_long_inc(&au_sbi(sb)->si_ninodes); ++} ++ ++static inline void au_ninodes_dec(struct super_block *sb) ++{ ++ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_ninodes)); ++ atomic_long_dec(&au_sbi(sb)->si_ninodes); ++} ++ ++static inline void au_nfiles_inc(struct super_block *sb) ++{ ++ atomic_long_inc(&au_sbi(sb)->si_nfiles); ++} ++ ++static inline void au_nfiles_dec(struct super_block *sb) ++{ ++ AuDebugOn(!atomic_long_read(&au_sbi(sb)->si_nfiles)); ++ atomic_long_dec(&au_sbi(sb)->si_nfiles); ++} ++ ++static inline struct au_branch *au_sbr(struct super_block *sb, ++ aufs_bindex_t bindex) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_branch[0 + bindex]; ++} ++ ++static inline void au_xino_brid_set(struct super_block *sb, aufs_bindex_t brid) ++{ ++ SiMustWriteLock(sb); ++ au_sbi(sb)->si_xino_brid = brid; ++} ++ ++static inline aufs_bindex_t au_xino_brid(struct super_block *sb) ++{ ++ SiMustAnyLock(sb); ++ return au_sbi(sb)->si_xino_brid; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_SUPER_H__ */ +diff --git a/fs/aufs/sysaufs.c b/fs/aufs/sysaufs.c +new file mode 100644 +index 0000000..29ac6fa +--- /dev/null ++++ b/fs/aufs/sysaufs.c +@@ -0,0 +1,91 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * sysfs interface and lifetime management ++ * they are necessary regardless sysfs is disabled. ++ */ ++ ++#include ++#include "aufs.h" ++ ++unsigned long sysaufs_si_mask; ++struct kset *sysaufs_kset; ++ ++#define AuSiAttr(_name) { \ ++ .attr = { .name = __stringify(_name), .mode = 0444 }, \ ++ .show = sysaufs_si_##_name, \ ++} ++ ++static struct sysaufs_si_attr sysaufs_si_attr_xi_path = AuSiAttr(xi_path); ++struct attribute *sysaufs_si_attrs[] = { ++ &sysaufs_si_attr_xi_path.attr, ++ NULL, ++}; ++ ++static const struct sysfs_ops au_sbi_ops = { ++ .show = sysaufs_si_show ++}; ++ ++static struct kobj_type au_sbi_ktype = { ++ .release = au_si_free, ++ .sysfs_ops = &au_sbi_ops, ++ .default_attrs = sysaufs_si_attrs ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int sysaufs_si_init(struct au_sbinfo *sbinfo) ++{ ++ int err; ++ ++ sbinfo->si_kobj.kset = sysaufs_kset; ++ /* cf. sysaufs_name() */ ++ err = kobject_init_and_add ++ (&sbinfo->si_kobj, &au_sbi_ktype, /*&sysaufs_kset->kobj*/NULL, ++ SysaufsSiNamePrefix "%lx", sysaufs_si_id(sbinfo)); ++ ++ dbgaufs_si_null(sbinfo); ++ if (!err) { ++ err = dbgaufs_si_init(sbinfo); ++ if (unlikely(err)) ++ kobject_put(&sbinfo->si_kobj); ++ } ++ return err; ++} ++ ++void sysaufs_fin(void) ++{ ++ dbgaufs_fin(); ++ sysfs_remove_group(&sysaufs_kset->kobj, sysaufs_attr_group); ++ kset_unregister(sysaufs_kset); ++} ++ ++int __init sysaufs_init(void) ++{ ++ int err; ++ ++ do { ++ get_random_bytes(&sysaufs_si_mask, sizeof(sysaufs_si_mask)); ++ } while (!sysaufs_si_mask); ++ ++ err = -EINVAL; ++ sysaufs_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj); ++ if (unlikely(!sysaufs_kset)) ++ goto out; ++ err = PTR_ERR(sysaufs_kset); ++ if (IS_ERR(sysaufs_kset)) ++ goto out; ++ err = sysfs_create_group(&sysaufs_kset->kobj, sysaufs_attr_group); ++ if (unlikely(err)) { ++ kset_unregister(sysaufs_kset); ++ goto out; ++ } ++ ++ err = dbgaufs_init(); ++ if (unlikely(err)) ++ sysaufs_fin(); ++out: ++ return err; ++} +diff --git a/fs/aufs/sysaufs.h b/fs/aufs/sysaufs.h +new file mode 100644 +index 0000000..feb78fd +--- /dev/null ++++ b/fs/aufs/sysaufs.h +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * sysfs interface and mount lifetime management ++ */ ++ ++#ifndef __SYSAUFS_H__ ++#define __SYSAUFS_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include "module.h" ++ ++struct super_block; ++struct au_sbinfo; ++ ++struct sysaufs_si_attr { ++ struct attribute attr; ++ int (*show)(struct seq_file *seq, struct super_block *sb); ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* sysaufs.c */ ++extern unsigned long sysaufs_si_mask; ++extern struct kset *sysaufs_kset; ++extern struct attribute *sysaufs_si_attrs[]; ++int sysaufs_si_init(struct au_sbinfo *sbinfo); ++int __init sysaufs_init(void); ++void sysaufs_fin(void); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* some people doesn't like to show a pointer in kernel */ ++static inline unsigned long sysaufs_si_id(struct au_sbinfo *sbinfo) ++{ ++ return sysaufs_si_mask ^ (unsigned long)sbinfo; ++} ++ ++#define SysaufsSiNamePrefix "si_" ++#define SysaufsSiNameLen (sizeof(SysaufsSiNamePrefix) + 16) ++static inline void sysaufs_name(struct au_sbinfo *sbinfo, char *name) ++{ ++ snprintf(name, SysaufsSiNameLen, SysaufsSiNamePrefix "%lx", ++ sysaufs_si_id(sbinfo)); ++} ++ ++struct au_branch; ++#ifdef CONFIG_SYSFS ++/* sysfs.c */ ++extern struct attribute_group *sysaufs_attr_group; ++ ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb); ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf); ++long au_brinfo_ioctl(struct file *file, unsigned long arg); ++#ifdef CONFIG_COMPAT ++long au_brinfo_compat_ioctl(struct file *file, unsigned long arg); ++#endif ++ ++void sysaufs_br_init(struct au_branch *br); ++void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); ++void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); ++ ++#define sysaufs_brs_init() do {} while (0) ++ ++#else ++#define sysaufs_attr_group NULL ++ ++AuStubInt0(sysaufs_si_xi_path, struct seq_file *seq, struct super_block *sb) ++AuStub(ssize_t, sysaufs_si_show, return 0, struct kobject *kobj, ++ struct attribute *attr, char *buf) ++AuStubVoid(sysaufs_br_init, struct au_branch *br) ++AuStubVoid(sysaufs_brs_add, struct super_block *sb, aufs_bindex_t bindex) ++AuStubVoid(sysaufs_brs_del, struct super_block *sb, aufs_bindex_t bindex) ++ ++static inline void sysaufs_brs_init(void) ++{ ++ sysaufs_brs = 0; ++} ++ ++#endif /* CONFIG_SYSFS */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __SYSAUFS_H__ */ +diff --git a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c +new file mode 100644 +index 0000000..75cc82a +--- /dev/null ++++ b/fs/aufs/sysfs.c +@@ -0,0 +1,336 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * sysfs interface ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++static struct attribute *au_attr[] = { ++ NULL, /* need to NULL terminate the list of attributes */ ++}; ++ ++static struct attribute_group sysaufs_attr_group_body = { ++ .attrs = au_attr ++}; ++ ++struct attribute_group *sysaufs_attr_group = &sysaufs_attr_group_body; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int sysaufs_si_xi_path(struct seq_file *seq, struct super_block *sb) ++{ ++ int err; ++ ++ SiMustAnyLock(sb); ++ ++ err = 0; ++ if (au_opt_test(au_mntflags(sb), XINO)) { ++ err = au_xino_path(seq, au_sbi(sb)->si_xib); ++ seq_putc(seq, '\n'); ++ } ++ return err; ++} ++ ++/* ++ * the lifetime of branch is independent from the entry under sysfs. ++ * sysfs handles the lifetime of the entry, and never call ->show() after it is ++ * unlinked. ++ */ ++static int sysaufs_si_br(struct seq_file *seq, struct super_block *sb, ++ aufs_bindex_t bindex, int idx) ++{ ++ int err; ++ struct path path; ++ struct dentry *root; ++ struct au_branch *br; ++ au_br_perm_str_t perm; ++ ++ AuDbg("b%d\n", bindex); ++ ++ err = 0; ++ root = sb->s_root; ++ di_read_lock_parent(root, !AuLock_IR); ++ br = au_sbr(sb, bindex); ++ ++ switch (idx) { ++ case AuBrSysfs_BR: ++ path.mnt = au_br_mnt(br); ++ path.dentry = au_h_dptr(root, bindex); ++ au_seq_path(seq, &path); ++ au_optstr_br_perm(&perm, br->br_perm); ++ err = seq_printf(seq, "=%s\n", perm.a); ++ break; ++ case AuBrSysfs_BRID: ++ err = seq_printf(seq, "%d\n", br->br_id); ++ break; ++ } ++ di_read_unlock(root, !AuLock_IR); ++ if (err == -1) ++ err = -E2BIG; ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static struct seq_file *au_seq(char *p, ssize_t len) ++{ ++ struct seq_file *seq; ++ ++ seq = kzalloc(sizeof(*seq), GFP_NOFS); ++ if (seq) { ++ /* mutex_init(&seq.lock); */ ++ seq->buf = p; ++ seq->size = len; ++ return seq; /* success */ ++ } ++ ++ seq = ERR_PTR(-ENOMEM); ++ return seq; ++} ++ ++#define SysaufsBr_PREFIX "br" ++#define SysaufsBrid_PREFIX "brid" ++ ++/* todo: file size may exceed PAGE_SIZE */ ++ssize_t sysaufs_si_show(struct kobject *kobj, struct attribute *attr, ++ char *buf) ++{ ++ ssize_t err; ++ int idx; ++ long l; ++ aufs_bindex_t bend; ++ struct au_sbinfo *sbinfo; ++ struct super_block *sb; ++ struct seq_file *seq; ++ char *name; ++ struct attribute **cattr; ++ ++ sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); ++ sb = sbinfo->si_sb; ++ ++ /* ++ * prevent a race condition between sysfs and aufs. ++ * for instance, sysfs_file_read() calls sysfs_get_active_two() which ++ * prohibits maintaining the sysfs entries. ++ * hew we acquire read lock after sysfs_get_active_two(). ++ * on the other hand, the remount process may maintain the sysfs/aufs ++ * entries after acquiring write lock. ++ * it can cause a deadlock. ++ * simply we gave up processing read here. ++ */ ++ err = -EBUSY; ++ if (unlikely(!si_noflush_read_trylock(sb))) ++ goto out; ++ ++ seq = au_seq(buf, PAGE_SIZE); ++ err = PTR_ERR(seq); ++ if (IS_ERR(seq)) ++ goto out_unlock; ++ ++ name = (void *)attr->name; ++ cattr = sysaufs_si_attrs; ++ while (*cattr) { ++ if (!strcmp(name, (*cattr)->name)) { ++ err = container_of(*cattr, struct sysaufs_si_attr, attr) ++ ->show(seq, sb); ++ goto out_seq; ++ } ++ cattr++; ++ } ++ ++ if (!strncmp(name, SysaufsBrid_PREFIX, ++ sizeof(SysaufsBrid_PREFIX) - 1)) { ++ idx = AuBrSysfs_BRID; ++ name += sizeof(SysaufsBrid_PREFIX) - 1; ++ } else if (!strncmp(name, SysaufsBr_PREFIX, ++ sizeof(SysaufsBr_PREFIX) - 1)) { ++ idx = AuBrSysfs_BR; ++ name += sizeof(SysaufsBr_PREFIX) - 1; ++ } else ++ BUG(); ++ ++ err = kstrtol(name, 10, &l); ++ if (!err) { ++ bend = au_sbend(sb); ++ if (l <= bend) ++ err = sysaufs_si_br(seq, sb, (aufs_bindex_t)l, idx); ++ else ++ err = -ENOENT; ++ } ++ ++out_seq: ++ if (!err) { ++ err = seq->count; ++ /* sysfs limit */ ++ if (unlikely(err == PAGE_SIZE)) ++ err = -EFBIG; ++ } ++ kfree(seq); ++out_unlock: ++ si_read_unlock(sb); ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_brinfo(struct super_block *sb, union aufs_brinfo __user *arg) ++{ ++ int err; ++ int16_t brid; ++ aufs_bindex_t bindex, bend; ++ size_t sz; ++ char *buf; ++ struct seq_file *seq; ++ struct au_branch *br; ++ ++ si_read_lock(sb, AuLock_FLUSH); ++ bend = au_sbend(sb); ++ err = bend + 1; ++ if (!arg) ++ goto out; ++ ++ err = -ENOMEM; ++ buf = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!buf)) ++ goto out; ++ ++ seq = au_seq(buf, PAGE_SIZE); ++ err = PTR_ERR(seq); ++ if (IS_ERR(seq)) ++ goto out_buf; ++ ++ sz = sizeof(*arg) - offsetof(union aufs_brinfo, path); ++ for (bindex = 0; bindex <= bend; bindex++, arg++) { ++ err = !access_ok(VERIFY_WRITE, arg, sizeof(*arg)); ++ if (unlikely(err)) ++ break; ++ ++ br = au_sbr(sb, bindex); ++ brid = br->br_id; ++ BUILD_BUG_ON(sizeof(brid) != sizeof(arg->id)); ++ err = __put_user(brid, &arg->id); ++ if (unlikely(err)) ++ break; ++ ++ BUILD_BUG_ON(sizeof(br->br_perm) != sizeof(arg->perm)); ++ err = __put_user(br->br_perm, &arg->perm); ++ if (unlikely(err)) ++ break; ++ ++ au_seq_path(seq, &br->br_path); ++ err = seq_putc(seq, '\0'); ++ if (!err && seq->count <= sz) { ++ err = copy_to_user(arg->path, seq->buf, seq->count); ++ seq->count = 0; ++ if (unlikely(err)) ++ break; ++ } else { ++ err = -E2BIG; ++ goto out_seq; ++ } ++ } ++ if (unlikely(err)) ++ err = -EFAULT; ++ ++out_seq: ++ kfree(seq); ++out_buf: ++ free_page((unsigned long)buf); ++out: ++ si_read_unlock(sb); ++ return err; ++} ++ ++long au_brinfo_ioctl(struct file *file, unsigned long arg) ++{ ++ return au_brinfo(file->f_path.dentry->d_sb, (void __user *)arg); ++} ++ ++#ifdef CONFIG_COMPAT ++long au_brinfo_compat_ioctl(struct file *file, unsigned long arg) ++{ ++ return au_brinfo(file->f_path.dentry->d_sb, compat_ptr(arg)); ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ ++void sysaufs_br_init(struct au_branch *br) ++{ ++ int i; ++ struct au_brsysfs *br_sysfs; ++ struct attribute *attr; ++ ++ br_sysfs = br->br_sysfs; ++ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { ++ attr = &br_sysfs->attr; ++ sysfs_attr_init(attr); ++ attr->name = br_sysfs->name; ++ attr->mode = S_IRUGO; ++ br_sysfs++; ++ } ++} ++ ++void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ struct au_branch *br; ++ struct kobject *kobj; ++ struct au_brsysfs *br_sysfs; ++ int i; ++ aufs_bindex_t bend; ++ ++ dbgaufs_brs_del(sb, bindex); ++ ++ if (!sysaufs_brs) ++ return; ++ ++ kobj = &au_sbi(sb)->si_kobj; ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ br_sysfs = br->br_sysfs; ++ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { ++ sysfs_remove_file(kobj, &br_sysfs->attr); ++ br_sysfs++; ++ } ++ } ++} ++ ++void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err, i; ++ aufs_bindex_t bend; ++ struct kobject *kobj; ++ struct au_branch *br; ++ struct au_brsysfs *br_sysfs; ++ ++ dbgaufs_brs_add(sb, bindex); ++ ++ if (!sysaufs_brs) ++ return; ++ ++ kobj = &au_sbi(sb)->si_kobj; ++ bend = au_sbend(sb); ++ for (; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ br_sysfs = br->br_sysfs; ++ snprintf(br_sysfs[AuBrSysfs_BR].name, sizeof(br_sysfs->name), ++ SysaufsBr_PREFIX "%d", bindex); ++ snprintf(br_sysfs[AuBrSysfs_BRID].name, sizeof(br_sysfs->name), ++ SysaufsBrid_PREFIX "%d", bindex); ++ for (i = 0; i < ARRAY_SIZE(br->br_sysfs); i++) { ++ err = sysfs_create_file(kobj, &br_sysfs->attr); ++ if (unlikely(err)) ++ pr_warn("failed %s under sysfs(%d)\n", ++ br_sysfs->name, err); ++ br_sysfs++; ++ } ++ } ++} +diff --git a/fs/aufs/sysrq.c b/fs/aufs/sysrq.c +new file mode 100644 +index 0000000..e9fd963 +--- /dev/null ++++ b/fs/aufs/sysrq.c +@@ -0,0 +1,144 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * magic sysrq hanlder ++ */ ++ ++/* #include */ ++#include ++#include "aufs.h" ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void sysrq_sb(struct super_block *sb) ++{ ++ char *plevel; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ struct au_sphlhead *files; ++ struct au_finfo *finfo; ++ ++ plevel = au_plevel; ++ au_plevel = KERN_WARNING; ++ ++ /* since we define pr_fmt, call printk directly */ ++#define pr(str) printk(KERN_WARNING AUFS_NAME ": " str) ++ ++ sbinfo = au_sbi(sb); ++ printk(KERN_WARNING "si=%lx\n", sysaufs_si_id(sbinfo)); ++ pr("superblock\n"); ++ au_dpri_sb(sb); ++ ++#if 0 ++ pr("root dentry\n"); ++ au_dpri_dentry(sb->s_root); ++ pr("root inode\n"); ++ au_dpri_inode(sb->s_root->d_inode); ++#endif ++ ++#if 0 ++ do { ++ int err, i, j, ndentry; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ ++ err = au_dpages_init(&dpages, GFP_ATOMIC); ++ if (unlikely(err)) ++ break; ++ err = au_dcsub_pages(&dpages, sb->s_root, NULL, NULL); ++ if (!err) ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) ++ au_dpri_dentry(dpage->dentries[j]); ++ } ++ au_dpages_free(&dpages); ++ } while (0); ++#endif ++ ++#if 1 ++ { ++ struct inode *i; ++ ++ pr("isolated inode\n"); ++ spin_lock(&inode_sb_list_lock); ++ list_for_each_entry(i, &sb->s_inodes, i_sb_list) { ++ spin_lock(&i->i_lock); ++ if (1 || hlist_empty(&i->i_dentry)) ++ au_dpri_inode(i); ++ spin_unlock(&i->i_lock); ++ } ++ spin_unlock(&inode_sb_list_lock); ++ } ++#endif ++ pr("files\n"); ++ files = &au_sbi(sb)->si_files; ++ spin_lock(&files->spin); ++ hlist_for_each_entry(finfo, &files->head, fi_hlist) { ++ umode_t mode; ++ ++ file = finfo->fi_file; ++ mode = file_inode(file)->i_mode; ++ if (!special_file(mode)) ++ au_dpri_file(file); ++ } ++ spin_unlock(&files->spin); ++ pr("done\n"); ++ ++#undef pr ++ au_plevel = plevel; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* module parameter */ ++static char *aufs_sysrq_key = "a"; ++module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO); ++MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME); ++ ++static void au_sysrq(int key __maybe_unused) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ lockdep_off(); ++ au_sbilist_lock(); ++ list_for_each_entry(sbinfo, &au_sbilist.head, si_list) ++ sysrq_sb(sbinfo->si_sb); ++ au_sbilist_unlock(); ++ lockdep_on(); ++} ++ ++static struct sysrq_key_op au_sysrq_op = { ++ .handler = au_sysrq, ++ .help_msg = "Aufs", ++ .action_msg = "Aufs", ++ .enable_mask = SYSRQ_ENABLE_DUMP ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++int __init au_sysrq_init(void) ++{ ++ int err; ++ char key; ++ ++ err = -1; ++ key = *aufs_sysrq_key; ++ if ('a' <= key && key <= 'z') ++ err = register_sysrq_key(key, &au_sysrq_op); ++ if (unlikely(err)) ++ pr_err("err %d, sysrq=%c\n", err, key); ++ return err; ++} ++ ++void au_sysrq_fin(void) ++{ ++ int err; ++ ++ err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op); ++ if (unlikely(err)) ++ pr_err("err %d (ignored)\n", err); ++} +diff --git a/fs/aufs/vdir.c b/fs/aufs/vdir.c +new file mode 100644 +index 0000000..c61a77f +--- /dev/null ++++ b/fs/aufs/vdir.c +@@ -0,0 +1,876 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * virtual or vertical directory ++ */ ++ ++#include "aufs.h" ++ ++static unsigned int calc_size(int nlen) ++{ ++ return ALIGN(sizeof(struct au_vdir_de) + nlen, sizeof(ino_t)); ++} ++ ++static int set_deblk_end(union au_vdir_deblk_p *p, ++ union au_vdir_deblk_p *deblk_end) ++{ ++ if (calc_size(0) <= deblk_end->deblk - p->deblk) { ++ p->de->de_str.len = 0; ++ /* smp_mb(); */ ++ return 0; ++ } ++ return -1; /* error */ ++} ++ ++/* returns true or false */ ++static int is_deblk_end(union au_vdir_deblk_p *p, ++ union au_vdir_deblk_p *deblk_end) ++{ ++ if (calc_size(0) <= deblk_end->deblk - p->deblk) ++ return !p->de->de_str.len; ++ return 1; ++} ++ ++static unsigned char *last_deblk(struct au_vdir *vdir) ++{ ++ return vdir->vd_deblk[vdir->vd_nblk - 1]; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* estimate the apropriate size for name hash table */ ++unsigned int au_rdhash_est(loff_t sz) ++{ ++ unsigned int n; ++ ++ n = UINT_MAX; ++ sz >>= 10; ++ if (sz < n) ++ n = sz; ++ if (sz < AUFS_RDHASH_DEF) ++ n = AUFS_RDHASH_DEF; ++ /* pr_info("n %u\n", n); */ ++ return n; ++} ++ ++/* ++ * the allocated memory has to be freed by ++ * au_nhash_wh_free() or au_nhash_de_free(). ++ */ ++int au_nhash_alloc(struct au_nhash *nhash, unsigned int num_hash, gfp_t gfp) ++{ ++ struct hlist_head *head; ++ unsigned int u; ++ size_t sz; ++ ++ sz = sizeof(*nhash->nh_head) * num_hash; ++ head = kmalloc(sz, gfp); ++ if (head) { ++ nhash->nh_num = num_hash; ++ nhash->nh_head = head; ++ for (u = 0; u < num_hash; u++) ++ INIT_HLIST_HEAD(head++); ++ return 0; /* success */ ++ } ++ ++ return -ENOMEM; ++} ++ ++static void nhash_count(struct hlist_head *head) ++{ ++#if 0 ++ unsigned long n; ++ struct hlist_node *pos; ++ ++ n = 0; ++ hlist_for_each(pos, head) ++ n++; ++ pr_info("%lu\n", n); ++#endif ++} ++ ++static void au_nhash_wh_do_free(struct hlist_head *head) ++{ ++ struct au_vdir_wh *pos; ++ struct hlist_node *node; ++ ++ hlist_for_each_entry_safe(pos, node, head, wh_hash) ++ kfree(pos); ++} ++ ++static void au_nhash_de_do_free(struct hlist_head *head) ++{ ++ struct au_vdir_dehstr *pos; ++ struct hlist_node *node; ++ ++ hlist_for_each_entry_safe(pos, node, head, hash) ++ au_cache_free_vdir_dehstr(pos); ++} ++ ++static void au_nhash_do_free(struct au_nhash *nhash, ++ void (*free)(struct hlist_head *head)) ++{ ++ unsigned int n; ++ struct hlist_head *head; ++ ++ n = nhash->nh_num; ++ if (!n) ++ return; ++ ++ head = nhash->nh_head; ++ while (n-- > 0) { ++ nhash_count(head); ++ free(head++); ++ } ++ kfree(nhash->nh_head); ++} ++ ++void au_nhash_wh_free(struct au_nhash *whlist) ++{ ++ au_nhash_do_free(whlist, au_nhash_wh_do_free); ++} ++ ++static void au_nhash_de_free(struct au_nhash *delist) ++{ ++ au_nhash_do_free(delist, au_nhash_de_do_free); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, ++ int limit) ++{ ++ int num; ++ unsigned int u, n; ++ struct hlist_head *head; ++ struct au_vdir_wh *pos; ++ ++ num = 0; ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (u = 0; u < n; u++, head++) ++ hlist_for_each_entry(pos, head, wh_hash) ++ if (pos->wh_bindex == btgt && ++num > limit) ++ return 1; ++ return 0; ++} ++ ++static struct hlist_head *au_name_hash(struct au_nhash *nhash, ++ unsigned char *name, ++ unsigned int len) ++{ ++ unsigned int v; ++ /* const unsigned int magic_bit = 12; */ ++ ++ AuDebugOn(!nhash->nh_num || !nhash->nh_head); ++ ++ v = 0; ++ while (len--) ++ v += *name++; ++ /* v = hash_long(v, magic_bit); */ ++ v %= nhash->nh_num; ++ return nhash->nh_head + v; ++} ++ ++static int au_nhash_test_name(struct au_vdir_destr *str, const char *name, ++ int nlen) ++{ ++ return str->len == nlen && !memcmp(str->name, name, nlen); ++} ++ ++/* returns found or not */ ++int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int nlen) ++{ ++ struct hlist_head *head; ++ struct au_vdir_wh *pos; ++ struct au_vdir_destr *str; ++ ++ head = au_name_hash(whlist, name, nlen); ++ hlist_for_each_entry(pos, head, wh_hash) { ++ str = &pos->wh_str; ++ AuDbg("%.*s\n", str->len, str->name); ++ if (au_nhash_test_name(str, name, nlen)) ++ return 1; ++ } ++ return 0; ++} ++ ++/* returns found(true) or not */ ++static int test_known(struct au_nhash *delist, char *name, int nlen) ++{ ++ struct hlist_head *head; ++ struct au_vdir_dehstr *pos; ++ struct au_vdir_destr *str; ++ ++ head = au_name_hash(delist, name, nlen); ++ hlist_for_each_entry(pos, head, hash) { ++ str = pos->str; ++ AuDbg("%.*s\n", str->len, str->name); ++ if (au_nhash_test_name(str, name, nlen)) ++ return 1; ++ } ++ return 0; ++} ++ ++static void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino, ++ unsigned char d_type) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ wh->wh_ino = ino; ++ wh->wh_type = d_type; ++#endif ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_nhash_append_wh(struct au_nhash *whlist, char *name, int nlen, ino_t ino, ++ unsigned int d_type, aufs_bindex_t bindex, ++ unsigned char shwh) ++{ ++ int err; ++ struct au_vdir_destr *str; ++ struct au_vdir_wh *wh; ++ ++ AuDbg("%.*s\n", nlen, name); ++ AuDebugOn(!whlist->nh_num || !whlist->nh_head); ++ ++ err = -ENOMEM; ++ wh = kmalloc(sizeof(*wh) + nlen, GFP_NOFS); ++ if (unlikely(!wh)) ++ goto out; ++ ++ err = 0; ++ wh->wh_bindex = bindex; ++ if (shwh) ++ au_shwh_init_wh(wh, ino, d_type); ++ str = &wh->wh_str; ++ str->len = nlen; ++ memcpy(str->name, name, nlen); ++ hlist_add_head(&wh->wh_hash, au_name_hash(whlist, name, nlen)); ++ /* smp_mb(); */ ++ ++out: ++ return err; ++} ++ ++static int append_deblk(struct au_vdir *vdir) ++{ ++ int err; ++ unsigned long ul; ++ const unsigned int deblk_sz = vdir->vd_deblk_sz; ++ union au_vdir_deblk_p p, deblk_end; ++ unsigned char **o; ++ ++ err = -ENOMEM; ++ o = krealloc(vdir->vd_deblk, sizeof(*o) * (vdir->vd_nblk + 1), ++ GFP_NOFS); ++ if (unlikely(!o)) ++ goto out; ++ ++ vdir->vd_deblk = o; ++ p.deblk = kmalloc(deblk_sz, GFP_NOFS); ++ if (p.deblk) { ++ ul = vdir->vd_nblk++; ++ vdir->vd_deblk[ul] = p.deblk; ++ vdir->vd_last.ul = ul; ++ vdir->vd_last.p.deblk = p.deblk; ++ deblk_end.deblk = p.deblk + deblk_sz; ++ err = set_deblk_end(&p, &deblk_end); ++ } ++ ++out: ++ return err; ++} ++ ++static int append_de(struct au_vdir *vdir, char *name, int nlen, ino_t ino, ++ unsigned int d_type, struct au_nhash *delist) ++{ ++ int err; ++ unsigned int sz; ++ const unsigned int deblk_sz = vdir->vd_deblk_sz; ++ union au_vdir_deblk_p p, *room, deblk_end; ++ struct au_vdir_dehstr *dehstr; ++ ++ p.deblk = last_deblk(vdir); ++ deblk_end.deblk = p.deblk + deblk_sz; ++ room = &vdir->vd_last.p; ++ AuDebugOn(room->deblk < p.deblk || deblk_end.deblk <= room->deblk ++ || !is_deblk_end(room, &deblk_end)); ++ ++ sz = calc_size(nlen); ++ if (unlikely(sz > deblk_end.deblk - room->deblk)) { ++ err = append_deblk(vdir); ++ if (unlikely(err)) ++ goto out; ++ ++ p.deblk = last_deblk(vdir); ++ deblk_end.deblk = p.deblk + deblk_sz; ++ /* smp_mb(); */ ++ AuDebugOn(room->deblk != p.deblk); ++ } ++ ++ err = -ENOMEM; ++ dehstr = au_cache_alloc_vdir_dehstr(); ++ if (unlikely(!dehstr)) ++ goto out; ++ ++ dehstr->str = &room->de->de_str; ++ hlist_add_head(&dehstr->hash, au_name_hash(delist, name, nlen)); ++ room->de->de_ino = ino; ++ room->de->de_type = d_type; ++ room->de->de_str.len = nlen; ++ memcpy(room->de->de_str.name, name, nlen); ++ ++ err = 0; ++ room->deblk += sz; ++ if (unlikely(set_deblk_end(room, &deblk_end))) ++ err = append_deblk(vdir); ++ /* smp_mb(); */ ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_vdir_free(struct au_vdir *vdir) ++{ ++ unsigned char **deblk; ++ ++ deblk = vdir->vd_deblk; ++ while (vdir->vd_nblk--) ++ kfree(*deblk++); ++ kfree(vdir->vd_deblk); ++ au_cache_free_vdir(vdir); ++} ++ ++static struct au_vdir *alloc_vdir(struct file *file) ++{ ++ struct au_vdir *vdir; ++ struct super_block *sb; ++ int err; ++ ++ sb = file->f_path.dentry->d_sb; ++ SiMustAnyLock(sb); ++ ++ err = -ENOMEM; ++ vdir = au_cache_alloc_vdir(); ++ if (unlikely(!vdir)) ++ goto out; ++ ++ vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS); ++ if (unlikely(!vdir->vd_deblk)) ++ goto out_free; ++ ++ vdir->vd_deblk_sz = au_sbi(sb)->si_rdblk; ++ if (!vdir->vd_deblk_sz) { ++ /* estimate the apropriate size for deblk */ ++ vdir->vd_deblk_sz = au_dir_size(file, /*dentry*/NULL); ++ /* pr_info("vd_deblk_sz %u\n", vdir->vd_deblk_sz); */ ++ } ++ vdir->vd_nblk = 0; ++ vdir->vd_version = 0; ++ vdir->vd_jiffy = 0; ++ err = append_deblk(vdir); ++ if (!err) ++ return vdir; /* success */ ++ ++ kfree(vdir->vd_deblk); ++ ++out_free: ++ au_cache_free_vdir(vdir); ++out: ++ vdir = ERR_PTR(err); ++ return vdir; ++} ++ ++static int reinit_vdir(struct au_vdir *vdir) ++{ ++ int err; ++ union au_vdir_deblk_p p, deblk_end; ++ ++ while (vdir->vd_nblk > 1) { ++ kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); ++ /* vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; */ ++ vdir->vd_nblk--; ++ } ++ p.deblk = vdir->vd_deblk[0]; ++ deblk_end.deblk = p.deblk + vdir->vd_deblk_sz; ++ err = set_deblk_end(&p, &deblk_end); ++ /* keep vd_dblk_sz */ ++ vdir->vd_last.ul = 0; ++ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; ++ vdir->vd_version = 0; ++ vdir->vd_jiffy = 0; ++ /* smp_mb(); */ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuFillVdir_CALLED 1 ++#define AuFillVdir_WHABLE (1 << 1) ++#define AuFillVdir_SHWH (1 << 2) ++#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) ++#define au_fset_fillvdir(flags, name) \ ++ do { (flags) |= AuFillVdir_##name; } while (0) ++#define au_fclr_fillvdir(flags, name) \ ++ do { (flags) &= ~AuFillVdir_##name; } while (0) ++ ++#ifndef CONFIG_AUFS_SHWH ++#undef AuFillVdir_SHWH ++#define AuFillVdir_SHWH 0 ++#endif ++ ++struct fillvdir_arg { ++ struct dir_context ctx; ++ struct file *file; ++ struct au_vdir *vdir; ++ struct au_nhash delist; ++ struct au_nhash whlist; ++ aufs_bindex_t bindex; ++ unsigned int flags; ++ int err; ++}; ++ ++static int fillvdir(struct dir_context *ctx, const char *__name, int nlen, ++ loff_t offset __maybe_unused, u64 h_ino, ++ unsigned int d_type) ++{ ++ struct fillvdir_arg *arg = container_of(ctx, struct fillvdir_arg, ctx); ++ char *name = (void *)__name; ++ struct super_block *sb; ++ ino_t ino; ++ const unsigned char shwh = !!au_ftest_fillvdir(arg->flags, SHWH); ++ ++ arg->err = 0; ++ sb = arg->file->f_path.dentry->d_sb; ++ au_fset_fillvdir(arg->flags, CALLED); ++ /* smp_mb(); */ ++ if (nlen <= AUFS_WH_PFX_LEN ++ || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { ++ if (test_known(&arg->delist, name, nlen) ++ || au_nhash_test_known_wh(&arg->whlist, name, nlen)) ++ goto out; /* already exists or whiteouted */ ++ ++ sb = arg->file->f_path.dentry->d_sb; ++ arg->err = au_ino(sb, arg->bindex, h_ino, d_type, &ino); ++ if (!arg->err) { ++ if (unlikely(nlen > AUFS_MAX_NAMELEN)) ++ d_type = DT_UNKNOWN; ++ arg->err = append_de(arg->vdir, name, nlen, ino, ++ d_type, &arg->delist); ++ } ++ } else if (au_ftest_fillvdir(arg->flags, WHABLE)) { ++ name += AUFS_WH_PFX_LEN; ++ nlen -= AUFS_WH_PFX_LEN; ++ if (au_nhash_test_known_wh(&arg->whlist, name, nlen)) ++ goto out; /* already whiteouted */ ++ ++ if (shwh) ++ arg->err = au_wh_ino(sb, arg->bindex, h_ino, d_type, ++ &ino); ++ if (!arg->err) { ++ if (nlen <= AUFS_MAX_NAMELEN + AUFS_WH_PFX_LEN) ++ d_type = DT_UNKNOWN; ++ arg->err = au_nhash_append_wh ++ (&arg->whlist, name, nlen, ino, d_type, ++ arg->bindex, shwh); ++ } ++ } ++ ++out: ++ if (!arg->err) ++ arg->vdir->vd_jiffy = jiffies; ++ /* smp_mb(); */ ++ AuTraceErr(arg->err); ++ return arg->err; ++} ++ ++static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir, ++ struct au_nhash *whlist, struct au_nhash *delist) ++{ ++#ifdef CONFIG_AUFS_SHWH ++ int err; ++ unsigned int nh, u; ++ struct hlist_head *head; ++ struct au_vdir_wh *pos; ++ struct hlist_node *n; ++ char *p, *o; ++ struct au_vdir_destr *destr; ++ ++ AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH)); ++ ++ err = -ENOMEM; ++ o = p = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ ++ err = 0; ++ nh = whlist->nh_num; ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ p += AUFS_WH_PFX_LEN; ++ for (u = 0; u < nh; u++) { ++ head = whlist->nh_head + u; ++ hlist_for_each_entry_safe(pos, n, head, wh_hash) { ++ destr = &pos->wh_str; ++ memcpy(p, destr->name, destr->len); ++ err = append_de(vdir, o, destr->len + AUFS_WH_PFX_LEN, ++ pos->wh_ino, pos->wh_type, delist); ++ if (unlikely(err)) ++ break; ++ } ++ } ++ ++ free_page((unsigned long)o); ++ ++out: ++ AuTraceErr(err); ++ return err; ++#else ++ return 0; ++#endif ++} ++ ++static int au_do_read_vdir(struct fillvdir_arg *arg) ++{ ++ int err; ++ unsigned int rdhash; ++ loff_t offset; ++ aufs_bindex_t bend, bindex, bstart; ++ unsigned char shwh; ++ struct file *hf, *file; ++ struct super_block *sb; ++ ++ file = arg->file; ++ sb = file->f_path.dentry->d_sb; ++ SiMustAnyLock(sb); ++ ++ rdhash = au_sbi(sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = au_rdhash_est(au_dir_size(file, /*dentry*/NULL)); ++ err = au_nhash_alloc(&arg->delist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ err = au_nhash_alloc(&arg->whlist, rdhash, GFP_NOFS); ++ if (unlikely(err)) ++ goto out_delist; ++ ++ err = 0; ++ arg->flags = 0; ++ shwh = 0; ++ if (au_opt_test(au_mntflags(sb), SHWH)) { ++ shwh = 1; ++ au_fset_fillvdir(arg->flags, SHWH); ++ } ++ bstart = au_fbstart(file); ++ bend = au_fbend_dir(file); ++ for (bindex = bstart; !err && bindex <= bend; bindex++) { ++ hf = au_hf_dir(file, bindex); ++ if (!hf) ++ continue; ++ ++ offset = vfsub_llseek(hf, 0, SEEK_SET); ++ err = offset; ++ if (unlikely(offset)) ++ break; ++ ++ arg->bindex = bindex; ++ au_fclr_fillvdir(arg->flags, WHABLE); ++ if (shwh ++ || (bindex != bend ++ && au_br_whable(au_sbr_perm(sb, bindex)))) ++ au_fset_fillvdir(arg->flags, WHABLE); ++ do { ++ arg->err = 0; ++ au_fclr_fillvdir(arg->flags, CALLED); ++ /* smp_mb(); */ ++ err = vfsub_iterate_dir(hf, &arg->ctx); ++ if (err >= 0) ++ err = arg->err; ++ } while (!err && au_ftest_fillvdir(arg->flags, CALLED)); ++ ++ /* ++ * dir_relax() may be good for concurrency, but aufs should not ++ * use it since it will cause a lockdep problem. ++ */ ++ } ++ ++ if (!err && shwh) ++ err = au_handle_shwh(sb, arg->vdir, &arg->whlist, &arg->delist); ++ ++ au_nhash_wh_free(&arg->whlist); ++ ++out_delist: ++ au_nhash_de_free(&arg->delist); ++out: ++ return err; ++} ++ ++static int read_vdir(struct file *file, int may_read) ++{ ++ int err; ++ unsigned long expire; ++ unsigned char do_read; ++ struct fillvdir_arg arg = { ++ .ctx = { ++ .actor = fillvdir ++ } ++ }; ++ struct inode *inode; ++ struct au_vdir *vdir, *allocated; ++ ++ err = 0; ++ inode = file_inode(file); ++ IMustLock(inode); ++ SiMustAnyLock(inode->i_sb); ++ ++ allocated = NULL; ++ do_read = 0; ++ expire = au_sbi(inode->i_sb)->si_rdcache; ++ vdir = au_ivdir(inode); ++ if (!vdir) { ++ do_read = 1; ++ vdir = alloc_vdir(file); ++ err = PTR_ERR(vdir); ++ if (IS_ERR(vdir)) ++ goto out; ++ err = 0; ++ allocated = vdir; ++ } else if (may_read ++ && (inode->i_version != vdir->vd_version ++ || time_after(jiffies, vdir->vd_jiffy + expire))) { ++ do_read = 1; ++ err = reinit_vdir(vdir); ++ if (unlikely(err)) ++ goto out; ++ } ++ ++ if (!do_read) ++ return 0; /* success */ ++ ++ arg.file = file; ++ arg.vdir = vdir; ++ err = au_do_read_vdir(&arg); ++ if (!err) { ++ /* file->f_pos = 0; */ /* todo: ctx->pos? */ ++ vdir->vd_version = inode->i_version; ++ vdir->vd_last.ul = 0; ++ vdir->vd_last.p.deblk = vdir->vd_deblk[0]; ++ if (allocated) ++ au_set_ivdir(inode, allocated); ++ } else if (allocated) ++ au_vdir_free(allocated); ++ ++out: ++ return err; ++} ++ ++static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src) ++{ ++ int err, rerr; ++ unsigned long ul, n; ++ const unsigned int deblk_sz = src->vd_deblk_sz; ++ ++ AuDebugOn(tgt->vd_nblk != 1); ++ ++ err = -ENOMEM; ++ if (tgt->vd_nblk < src->vd_nblk) { ++ unsigned char **p; ++ ++ p = krealloc(tgt->vd_deblk, sizeof(*p) * src->vd_nblk, ++ GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ tgt->vd_deblk = p; ++ } ++ ++ if (tgt->vd_deblk_sz != deblk_sz) { ++ unsigned char *p; ++ ++ tgt->vd_deblk_sz = deblk_sz; ++ p = krealloc(tgt->vd_deblk[0], deblk_sz, GFP_NOFS); ++ if (unlikely(!p)) ++ goto out; ++ tgt->vd_deblk[0] = p; ++ } ++ memcpy(tgt->vd_deblk[0], src->vd_deblk[0], deblk_sz); ++ tgt->vd_version = src->vd_version; ++ tgt->vd_jiffy = src->vd_jiffy; ++ ++ n = src->vd_nblk; ++ for (ul = 1; ul < n; ul++) { ++ tgt->vd_deblk[ul] = kmemdup(src->vd_deblk[ul], deblk_sz, ++ GFP_NOFS); ++ if (unlikely(!tgt->vd_deblk[ul])) ++ goto out; ++ tgt->vd_nblk++; ++ } ++ tgt->vd_nblk = n; ++ tgt->vd_last.ul = tgt->vd_last.ul; ++ tgt->vd_last.p.deblk = tgt->vd_deblk[tgt->vd_last.ul]; ++ tgt->vd_last.p.deblk += src->vd_last.p.deblk ++ - src->vd_deblk[src->vd_last.ul]; ++ /* smp_mb(); */ ++ return 0; /* success */ ++ ++out: ++ rerr = reinit_vdir(tgt); ++ BUG_ON(rerr); ++ return err; ++} ++ ++int au_vdir_init(struct file *file) ++{ ++ int err; ++ struct inode *inode; ++ struct au_vdir *vdir_cache, *allocated; ++ ++ /* test file->f_pos here instead of ctx->pos */ ++ err = read_vdir(file, !file->f_pos); ++ if (unlikely(err)) ++ goto out; ++ ++ allocated = NULL; ++ vdir_cache = au_fvdir_cache(file); ++ if (!vdir_cache) { ++ vdir_cache = alloc_vdir(file); ++ err = PTR_ERR(vdir_cache); ++ if (IS_ERR(vdir_cache)) ++ goto out; ++ allocated = vdir_cache; ++ } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { ++ /* test file->f_pos here instead of ctx->pos */ ++ err = reinit_vdir(vdir_cache); ++ if (unlikely(err)) ++ goto out; ++ } else ++ return 0; /* success */ ++ ++ inode = file_inode(file); ++ err = copy_vdir(vdir_cache, au_ivdir(inode)); ++ if (!err) { ++ file->f_version = inode->i_version; ++ if (allocated) ++ au_set_fvdir_cache(file, allocated); ++ } else if (allocated) ++ au_vdir_free(allocated); ++ ++out: ++ return err; ++} ++ ++static loff_t calc_offset(struct au_vdir *vdir) ++{ ++ loff_t offset; ++ union au_vdir_deblk_p p; ++ ++ p.deblk = vdir->vd_deblk[vdir->vd_last.ul]; ++ offset = vdir->vd_last.p.deblk - p.deblk; ++ offset += vdir->vd_deblk_sz * vdir->vd_last.ul; ++ return offset; ++} ++ ++/* returns true or false */ ++static int seek_vdir(struct file *file, struct dir_context *ctx) ++{ ++ int valid; ++ unsigned int deblk_sz; ++ unsigned long ul, n; ++ loff_t offset; ++ union au_vdir_deblk_p p, deblk_end; ++ struct au_vdir *vdir_cache; ++ ++ valid = 1; ++ vdir_cache = au_fvdir_cache(file); ++ offset = calc_offset(vdir_cache); ++ AuDbg("offset %lld\n", offset); ++ if (ctx->pos == offset) ++ goto out; ++ ++ vdir_cache->vd_last.ul = 0; ++ vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0]; ++ if (!ctx->pos) ++ goto out; ++ ++ valid = 0; ++ deblk_sz = vdir_cache->vd_deblk_sz; ++ ul = div64_u64(ctx->pos, deblk_sz); ++ AuDbg("ul %lu\n", ul); ++ if (ul >= vdir_cache->vd_nblk) ++ goto out; ++ ++ n = vdir_cache->vd_nblk; ++ for (; ul < n; ul++) { ++ p.deblk = vdir_cache->vd_deblk[ul]; ++ deblk_end.deblk = p.deblk + deblk_sz; ++ offset = ul; ++ offset *= deblk_sz; ++ while (!is_deblk_end(&p, &deblk_end) && offset < ctx->pos) { ++ unsigned int l; ++ ++ l = calc_size(p.de->de_str.len); ++ offset += l; ++ p.deblk += l; ++ } ++ if (!is_deblk_end(&p, &deblk_end)) { ++ valid = 1; ++ vdir_cache->vd_last.ul = ul; ++ vdir_cache->vd_last.p = p; ++ break; ++ } ++ } ++ ++out: ++ /* smp_mb(); */ ++ AuTraceErr(!valid); ++ return valid; ++} ++ ++int au_vdir_fill_de(struct file *file, struct dir_context *ctx) ++{ ++ unsigned int l, deblk_sz; ++ union au_vdir_deblk_p deblk_end; ++ struct au_vdir *vdir_cache; ++ struct au_vdir_de *de; ++ ++ vdir_cache = au_fvdir_cache(file); ++ if (!seek_vdir(file, ctx)) ++ return 0; ++ ++ deblk_sz = vdir_cache->vd_deblk_sz; ++ while (1) { ++ deblk_end.deblk = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; ++ deblk_end.deblk += deblk_sz; ++ while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) { ++ de = vdir_cache->vd_last.p.de; ++ AuDbg("%.*s, off%lld, i%lu, dt%d\n", ++ de->de_str.len, de->de_str.name, ctx->pos, ++ (unsigned long)de->de_ino, de->de_type); ++ if (unlikely(!dir_emit(ctx, de->de_str.name, ++ de->de_str.len, de->de_ino, ++ de->de_type))) { ++ /* todo: ignore the error caused by udba? */ ++ /* return err; */ ++ return 0; ++ } ++ ++ l = calc_size(de->de_str.len); ++ vdir_cache->vd_last.p.deblk += l; ++ ctx->pos += l; ++ } ++ if (vdir_cache->vd_last.ul < vdir_cache->vd_nblk - 1) { ++ vdir_cache->vd_last.ul++; ++ vdir_cache->vd_last.p.deblk ++ = vdir_cache->vd_deblk[vdir_cache->vd_last.ul]; ++ ctx->pos = deblk_sz * vdir_cache->vd_last.ul; ++ continue; ++ } ++ break; ++ } ++ ++ /* smp_mb(); */ ++ return 0; ++} +diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c +new file mode 100644 +index 0000000..b233552 +--- /dev/null ++++ b/fs/aufs/vfsub.c +@@ -0,0 +1,783 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * sub-routines for VFS ++ */ ++ ++#include ++#include ++#include ++#include ++#include "aufs.h" ++ ++int vfsub_update_h_iattr(struct path *h_path, int *did) ++{ ++ int err; ++ struct kstat st; ++ struct super_block *h_sb; ++ ++ /* for remote fs, leave work for its getattr or d_revalidate */ ++ /* for bad i_attr fs, handle them in aufs_getattr() */ ++ /* still some fs may acquire i_mutex. we need to skip them */ ++ err = 0; ++ if (!did) ++ did = &err; ++ h_sb = h_path->dentry->d_sb; ++ *did = (!au_test_fs_remote(h_sb) && au_test_fs_refresh_iattr(h_sb)); ++ if (*did) ++ err = vfs_getattr(h_path, &st); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct file *vfsub_dentry_open(struct path *path, int flags) ++{ ++ struct file *file; ++ ++ file = dentry_open(path, flags /* | __FMODE_NONOTIFY */, ++ current_cred()); ++ if (!IS_ERR_OR_NULL(file) ++ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) ++ i_readcount_inc(path->dentry->d_inode); ++ ++ return file; ++} ++ ++struct file *vfsub_filp_open(const char *path, int oflags, int mode) ++{ ++ struct file *file; ++ ++ lockdep_off(); ++ file = filp_open(path, ++ oflags /* | __FMODE_NONOTIFY */, ++ mode); ++ lockdep_on(); ++ if (IS_ERR(file)) ++ goto out; ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ ++out: ++ return file; ++} ++ ++int vfsub_kern_path(const char *name, unsigned int flags, struct path *path) ++{ ++ int err; ++ ++ err = kern_path(name, flags, path); ++ if (!err && path->dentry->d_inode) ++ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, ++ int len) ++{ ++ struct path path = { ++ .mnt = NULL ++ }; ++ ++ /* VFS checks it too, but by WARN_ON_ONCE() */ ++ IMustLock(parent->d_inode); ++ ++ path.dentry = lookup_one_len(name, parent, len); ++ if (IS_ERR(path.dentry)) ++ goto out; ++ if (path.dentry->d_inode) ++ vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/ ++ ++out: ++ AuTraceErrPtr(path.dentry); ++ return path.dentry; ++} ++ ++void vfsub_call_lkup_one(void *args) ++{ ++ struct vfsub_lkup_one_args *a = args; ++ *a->errp = vfsub_lkup_one(a->name, a->parent); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2) ++{ ++ struct dentry *d; ++ ++ lockdep_off(); ++ d = lock_rename(d1, d2); ++ lockdep_on(); ++ au_hn_suspend(hdir1); ++ if (hdir1 != hdir2) ++ au_hn_suspend(hdir2); ++ ++ return d; ++} ++ ++void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2) ++{ ++ au_hn_resume(hdir1); ++ if (hdir1 != hdir2) ++ au_hn_resume(hdir2); ++ lockdep_off(); ++ unlock_rename(d1, d2); ++ lockdep_on(); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int vfsub_create(struct inode *dir, struct path *path, int mode, bool want_excl) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mknod(path, d, mode, 0); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_create(dir, path->dentry, mode, want_excl); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++out: ++ return err; ++} ++ ++int vfsub_symlink(struct inode *dir, struct path *path, const char *symname) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_symlink(path, d, symname); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_symlink(dir, path->dentry, symname); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++out: ++ return err; ++} ++ ++int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mknod(path, d, mode, new_encode_dev(dev)); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_mknod(dir, path->dentry, mode, dev); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++out: ++ return err; ++} ++ ++static int au_test_nlink(struct inode *inode) ++{ ++ const unsigned int link_max = UINT_MAX >> 1; /* rough margin */ ++ ++ if (!au_test_fs_no_limit_nlink(inode->i_sb) ++ || inode->i_nlink < link_max) ++ return 0; ++ return -EMLINK; ++} ++ ++int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path, ++ struct inode **delegated_inode) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ err = au_test_nlink(src_dentry->d_inode); ++ if (unlikely(err)) ++ return err; ++ ++ /* we don't call may_linkat() */ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_link(src_dentry, path, d); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_link(src_dentry, dir, path->dentry, delegated_inode); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ /* fuse has different memory inode for the same inumber */ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ tmp.dentry = src_dentry; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++out: ++ return err; ++} ++ ++int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, ++ struct inode *dir, struct path *path, ++ struct inode **delegated_inode) ++{ ++ int err; ++ struct path tmp = { ++ .mnt = path->mnt ++ }; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ IMustLock(src_dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ tmp.dentry = src_dentry->d_parent; ++ err = security_path_rename(&tmp, src_dentry, path, d, /*flags*/0); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_rename(src_dir, src_dentry, dir, path->dentry, ++ delegated_inode, /*flags*/0); ++ lockdep_on(); ++ if (!err) { ++ int did; ++ ++ tmp.dentry = d->d_parent; ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = src_dentry; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ tmp.dentry = src_dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++out: ++ return err; ++} ++ ++int vfsub_mkdir(struct inode *dir, struct path *path, int mode) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_mkdir(path, d, mode); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_mkdir(dir, path->dentry, mode); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = *path; ++ int did; ++ ++ vfsub_update_h_iattr(&tmp, &did); ++ if (did) { ++ tmp.dentry = path->dentry->d_parent; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); ++ } ++ /*ignore*/ ++ } ++ ++out: ++ return err; ++} ++ ++int vfsub_rmdir(struct inode *dir, struct path *path) ++{ ++ int err; ++ struct dentry *d; ++ ++ IMustLock(dir); ++ ++ d = path->dentry; ++ path->dentry = d->d_parent; ++ err = security_path_rmdir(path, d); ++ path->dentry = d; ++ if (unlikely(err)) ++ goto out; ++ ++ lockdep_off(); ++ err = vfs_rmdir(dir, path->dentry); ++ lockdep_on(); ++ if (!err) { ++ struct path tmp = { ++ .dentry = path->dentry->d_parent, ++ .mnt = path->mnt ++ }; ++ ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ ++ } ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* todo: support mmap_sem? */ ++ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ ++ lockdep_off(); ++ err = vfs_read(file, ubuf, count, ppos); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++/* todo: kernel_read()? */ ++ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ union { ++ void *k; ++ char __user *u; ++ } buf; ++ ++ buf.k = kbuf; ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = vfsub_read_u(file, buf.u, count, ppos); ++ set_fs(oldfs); ++ return err; ++} ++ ++ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, ++ loff_t *ppos) ++{ ++ ssize_t err; ++ ++ lockdep_off(); ++ err = vfs_write(file, ubuf, count, ppos); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ union { ++ void *k; ++ const char __user *u; ++ } buf; ++ ++ buf.k = kbuf; ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ err = vfsub_write_u(file, buf.u, count, ppos); ++ set_fs(oldfs); ++ return err; ++} ++ ++int vfsub_flush(struct file *file, fl_owner_t id) ++{ ++ int err; ++ ++ err = 0; ++ if (file->f_op->flush) { ++ if (!au_test_nfs(file->f_path.dentry->d_sb)) ++ err = file->f_op->flush(file, id); ++ else { ++ lockdep_off(); ++ err = file->f_op->flush(file, id); ++ lockdep_on(); ++ } ++ if (!err) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); ++ /*ignore*/ ++ } ++ return err; ++} ++ ++int vfsub_iterate_dir(struct file *file, struct dir_context *ctx) ++{ ++ int err; ++ ++ AuDbg("%pD, ctx{%pf, %llu}\n", file, ctx->actor, ctx->pos); ++ ++ lockdep_off(); ++ err = iterate_dir(file, ctx); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++long vfsub_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) ++{ ++ long err; ++ ++ lockdep_off(); ++ err = do_splice_to(in, ppos, pipe, len, flags); ++ lockdep_on(); ++ file_accessed(in); ++ if (err >= 0) ++ vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) ++{ ++ long err; ++ ++ lockdep_off(); ++ err = do_splice_from(pipe, out, ppos, len, flags); ++ lockdep_on(); ++ if (err >= 0) ++ vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/ ++ return err; ++} ++ ++int vfsub_fsync(struct file *file, struct path *path, int datasync) ++{ ++ int err; ++ ++ /* file can be NULL */ ++ lockdep_off(); ++ err = vfs_fsync(file, datasync); ++ lockdep_on(); ++ if (!err) { ++ if (!path) { ++ AuDebugOn(!file); ++ path = &file->f_path; ++ } ++ vfsub_update_h_iattr(path, /*did*/NULL); /*ignore*/ ++ } ++ return err; ++} ++ ++/* cf. open.c:do_sys_truncate() and do_sys_ftruncate() */ ++int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, ++ struct file *h_file) ++{ ++ int err; ++ struct inode *h_inode; ++ struct super_block *h_sb; ++ ++ if (!h_file) { ++ err = vfsub_truncate(h_path, length); ++ goto out; ++ } ++ ++ h_inode = h_path->dentry->d_inode; ++ h_sb = h_inode->i_sb; ++ lockdep_off(); ++ sb_start_write(h_sb); ++ lockdep_on(); ++ err = locks_verify_truncate(h_inode, h_file, length); ++ if (!err) ++ err = security_path_truncate(h_path); ++ if (!err) { ++ lockdep_off(); ++ err = do_truncate(h_path->dentry, length, attr, h_file); ++ lockdep_on(); ++ } ++ lockdep_off(); ++ sb_end_write(h_sb); ++ lockdep_on(); ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_vfsub_mkdir_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++ int mode; ++}; ++ ++static void au_call_vfsub_mkdir(void *args) ++{ ++ struct au_vfsub_mkdir_args *a = args; ++ *a->errp = vfsub_mkdir(a->dir, a->path, a->mode); ++} ++ ++int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode) ++{ ++ int err, do_sio, wkq_err; ++ ++ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) { ++ lockdep_off(); ++ err = vfsub_mkdir(dir, path, mode); ++ lockdep_on(); ++ } else { ++ struct au_vfsub_mkdir_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path, ++ .mode = mode ++ }; ++ wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++struct au_vfsub_rmdir_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++}; ++ ++static void au_call_vfsub_rmdir(void *args) ++{ ++ struct au_vfsub_rmdir_args *a = args; ++ *a->errp = vfsub_rmdir(a->dir, a->path); ++} ++ ++int vfsub_sio_rmdir(struct inode *dir, struct path *path) ++{ ++ int err, do_sio, wkq_err; ++ ++ do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE); ++ if (!do_sio) { ++ lockdep_off(); ++ err = vfsub_rmdir(dir, path); ++ lockdep_on(); ++ } else { ++ struct au_vfsub_rmdir_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path ++ }; ++ wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct notify_change_args { ++ int *errp; ++ struct path *path; ++ struct iattr *ia; ++ struct inode **delegated_inode; ++}; ++ ++static void call_notify_change(void *args) ++{ ++ struct notify_change_args *a = args; ++ struct inode *h_inode; ++ ++ h_inode = a->path->dentry->d_inode; ++ IMustLock(h_inode); ++ ++ *a->errp = -EPERM; ++ if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { ++ lockdep_off(); ++ *a->errp = notify_change(a->path->dentry, a->ia, ++ a->delegated_inode); ++ lockdep_on(); ++ if (!*a->errp) ++ vfsub_update_h_iattr(a->path, /*did*/NULL); /*ignore*/ ++ } ++ AuTraceErr(*a->errp); ++} ++ ++int vfsub_notify_change(struct path *path, struct iattr *ia, ++ struct inode **delegated_inode) ++{ ++ int err; ++ struct notify_change_args args = { ++ .errp = &err, ++ .path = path, ++ .ia = ia, ++ .delegated_inode = delegated_inode ++ }; ++ ++ call_notify_change(&args); ++ ++ return err; ++} ++ ++int vfsub_sio_notify_change(struct path *path, struct iattr *ia, ++ struct inode **delegated_inode) ++{ ++ int err, wkq_err; ++ struct notify_change_args args = { ++ .errp = &err, ++ .path = path, ++ .ia = ia, ++ .delegated_inode = delegated_inode ++ }; ++ ++ wkq_err = au_wkq_wait(call_notify_change, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct unlink_args { ++ int *errp; ++ struct inode *dir; ++ struct path *path; ++ struct inode **delegated_inode; ++}; ++ ++static void call_unlink(void *args) ++{ ++ struct unlink_args *a = args; ++ struct dentry *d = a->path->dentry; ++ struct inode *h_inode; ++ const int stop_sillyrename = (au_test_nfs(d->d_sb) ++ && au_dcount(d) == 1); ++ ++ IMustLock(a->dir); ++ ++ a->path->dentry = d->d_parent; ++ *a->errp = security_path_unlink(a->path, d); ++ a->path->dentry = d; ++ if (unlikely(*a->errp)) ++ return; ++ ++ if (!stop_sillyrename) ++ dget(d); ++ h_inode = d->d_inode; ++ if (h_inode) ++ ihold(h_inode); ++ ++ lockdep_off(); ++ *a->errp = vfs_unlink(a->dir, d, a->delegated_inode); ++ lockdep_on(); ++ if (!*a->errp) { ++ struct path tmp = { ++ .dentry = d->d_parent, ++ .mnt = a->path->mnt ++ }; ++ vfsub_update_h_iattr(&tmp, /*did*/NULL); /*ignore*/ ++ } ++ ++ if (!stop_sillyrename) ++ dput(d); ++ if (h_inode) ++ iput(h_inode); ++ ++ AuTraceErr(*a->errp); ++} ++ ++/* ++ * @dir: must be locked. ++ * @dentry: target dentry. ++ */ ++int vfsub_unlink(struct inode *dir, struct path *path, ++ struct inode **delegated_inode, int force) ++{ ++ int err; ++ struct unlink_args args = { ++ .errp = &err, ++ .dir = dir, ++ .path = path, ++ .delegated_inode = delegated_inode ++ }; ++ ++ if (!force) ++ call_unlink(&args); ++ else { ++ int wkq_err; ++ ++ wkq_err = au_wkq_wait(call_unlink, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} +diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h +new file mode 100644 +index 0000000..6493d90 +--- /dev/null ++++ b/fs/aufs/vfsub.h +@@ -0,0 +1,288 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * sub-routines for VFS ++ */ ++ ++#ifndef __AUFS_VFSUB_H__ ++#define __AUFS_VFSUB_H__ ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include ++#include "debug.h" ++ ++/* copied from linux/fs/internal.h */ ++/* todo: BAD approach!! */ ++extern void __mnt_drop_write(struct vfsmount *); ++extern spinlock_t inode_sb_list_lock; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* lock subclass for lower inode */ ++/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */ ++/* reduce? gave up. */ ++enum { ++ AuLsc_I_Begin = I_MUTEX_PARENT2, /* 5 */ ++ AuLsc_I_PARENT, /* lower inode, parent first */ ++ AuLsc_I_PARENT2, /* copyup dirs */ ++ AuLsc_I_PARENT3, /* copyup wh */ ++ AuLsc_I_CHILD, ++ AuLsc_I_CHILD2, ++ AuLsc_I_End ++}; ++ ++/* to debug easier, do not make them inlined functions */ ++#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) ++#define IMustLock(i) MtxMustLock(&(i)->i_mutex) ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline void vfsub_drop_nlink(struct inode *inode) ++{ ++ AuDebugOn(!inode->i_nlink); ++ drop_nlink(inode); ++} ++ ++static inline void vfsub_dead_dir(struct inode *inode) ++{ ++ AuDebugOn(!S_ISDIR(inode->i_mode)); ++ inode->i_flags |= S_DEAD; ++ clear_nlink(inode); ++} ++ ++static inline int vfsub_native_ro(struct inode *inode) ++{ ++ return (inode->i_sb->s_flags & MS_RDONLY) ++ || IS_RDONLY(inode) ++ /* || IS_APPEND(inode) */ ++ || IS_IMMUTABLE(inode); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int vfsub_update_h_iattr(struct path *h_path, int *did); ++struct file *vfsub_dentry_open(struct path *path, int flags); ++struct file *vfsub_filp_open(const char *path, int oflags, int mode); ++int vfsub_kern_path(const char *name, unsigned int flags, struct path *path); ++ ++struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, ++ int len); ++ ++struct vfsub_lkup_one_args { ++ struct dentry **errp; ++ struct qstr *name; ++ struct dentry *parent; ++}; ++ ++static inline struct dentry *vfsub_lkup_one(struct qstr *name, ++ struct dentry *parent) ++{ ++ return vfsub_lookup_one_len(name->name, parent, name->len); ++} ++ ++void vfsub_call_lkup_one(void *args); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline int vfsub_mnt_want_write(struct vfsmount *mnt) ++{ ++ int err; ++ ++ lockdep_off(); ++ err = mnt_want_write(mnt); ++ lockdep_on(); ++ return err; ++} ++ ++static inline void vfsub_mnt_drop_write(struct vfsmount *mnt) ++{ ++ lockdep_off(); ++ mnt_drop_write(mnt); ++ lockdep_on(); ++} ++ ++static inline void vfsub_mnt_drop_write_file(struct file *file) ++{ ++ lockdep_off(); ++ mnt_drop_write_file(file); ++ lockdep_on(); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_hinode; ++struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2); ++void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1, ++ struct dentry *d2, struct au_hinode *hdir2); ++ ++int vfsub_create(struct inode *dir, struct path *path, int mode, ++ bool want_excl); ++int vfsub_symlink(struct inode *dir, struct path *path, ++ const char *symname); ++int vfsub_mknod(struct inode *dir, struct path *path, int mode, dev_t dev); ++int vfsub_link(struct dentry *src_dentry, struct inode *dir, ++ struct path *path, struct inode **delegated_inode); ++int vfsub_rename(struct inode *src_hdir, struct dentry *src_dentry, ++ struct inode *hdir, struct path *path, ++ struct inode **delegated_inode); ++int vfsub_mkdir(struct inode *dir, struct path *path, int mode); ++int vfsub_rmdir(struct inode *dir, struct path *path); ++ ++/* ---------------------------------------------------------------------- */ ++ ++ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, ++ loff_t *ppos); ++ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, ++ loff_t *ppos); ++int vfsub_flush(struct file *file, fl_owner_t id); ++int vfsub_iterate_dir(struct file *file, struct dir_context *ctx); ++ ++static inline loff_t vfsub_f_size_read(struct file *file) ++{ ++ return i_size_read(file_inode(file)); ++} ++ ++static inline unsigned int vfsub_file_flags(struct file *file) ++{ ++ unsigned int flags; ++ ++ spin_lock(&file->f_lock); ++ flags = file->f_flags; ++ spin_unlock(&file->f_lock); ++ ++ return flags; ++} ++ ++static inline void vfsub_file_accessed(struct file *h_file) ++{ ++ file_accessed(h_file); ++ vfsub_update_h_iattr(&h_file->f_path, /*did*/NULL); /*ignore*/ ++} ++ ++static inline void vfsub_touch_atime(struct vfsmount *h_mnt, ++ struct dentry *h_dentry) ++{ ++ struct path h_path = { ++ .dentry = h_dentry, ++ .mnt = h_mnt ++ }; ++ touch_atime(&h_path); ++ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ ++} ++ ++static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts, ++ int flags) ++{ ++ return update_time(h_inode, ts, flags); ++ /* no vfsub_update_h_iattr() since we don't have struct path */ ++} ++ ++long vfsub_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); ++long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++ ++static inline long vfsub_truncate(struct path *path, loff_t length) ++{ ++ long err; ++ ++ lockdep_off(); ++ err = vfs_truncate(path, length); ++ lockdep_on(); ++ return err; ++} ++ ++int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr, ++ struct file *h_file); ++int vfsub_fsync(struct file *file, struct path *path, int datasync); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin) ++{ ++ loff_t err; ++ ++ lockdep_off(); ++ err = vfs_llseek(file, offset, origin); ++ lockdep_on(); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* dirty workaround for strict type of fmode_t */ ++union vfsub_fmu { ++ fmode_t fm; ++ unsigned int ui; ++}; ++ ++static inline unsigned int vfsub_fmode_to_uint(fmode_t fm) ++{ ++ union vfsub_fmu u = { ++ .fm = fm ++ }; ++ ++ BUILD_BUG_ON(sizeof(u.fm) != sizeof(u.ui)); ++ ++ return u.ui; ++} ++ ++static inline fmode_t vfsub_uint_to_fmode(unsigned int ui) ++{ ++ union vfsub_fmu u = { ++ .ui = ui ++ }; ++ ++ return u.fm; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int vfsub_sio_mkdir(struct inode *dir, struct path *path, int mode); ++int vfsub_sio_rmdir(struct inode *dir, struct path *path); ++int vfsub_sio_notify_change(struct path *path, struct iattr *ia, ++ struct inode **delegated_inode); ++int vfsub_notify_change(struct path *path, struct iattr *ia, ++ struct inode **delegated_inode); ++int vfsub_unlink(struct inode *dir, struct path *path, ++ struct inode **delegated_inode, int force); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline int vfsub_setxattr(struct dentry *dentry, const char *name, ++ const void *value, size_t size, int flags) ++{ ++ int err; ++ ++ lockdep_off(); ++ err = vfs_setxattr(dentry, name, value, size, flags); ++ lockdep_on(); ++ ++ return err; ++} ++ ++static inline int vfsub_removexattr(struct dentry *dentry, const char *name) ++{ ++ int err; ++ ++ lockdep_off(); ++ err = vfs_removexattr(dentry, name); ++ lockdep_on(); ++ ++ return err; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_VFSUB_H__ */ +diff --git a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c +new file mode 100644 +index 0000000..7ce1cf1 +--- /dev/null ++++ b/fs/aufs/wbr_policy.c +@@ -0,0 +1,752 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * policies for selecting one among multiple writable branches ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* subset of cpup_attr() */ ++static noinline_for_stack ++int au_cpdown_attr(struct path *h_path, struct dentry *h_src) ++{ ++ int err, sbits; ++ struct iattr ia; ++ struct inode *h_isrc; ++ ++ h_isrc = h_src->d_inode; ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID; ++ ia.ia_mode = h_isrc->i_mode; ++ ia.ia_uid = h_isrc->i_uid; ++ ia.ia_gid = h_isrc->i_gid; ++ sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); ++ au_cpup_attr_flags(h_path->dentry->d_inode, h_isrc->i_flags); ++ /* no delegation since it is just created */ ++ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL); ++ ++ /* is this nfs only? */ ++ if (!err && sbits && au_test_nfs(h_path->dentry->d_sb)) { ++ ia.ia_valid = ATTR_FORCE | ATTR_MODE; ++ ia.ia_mode = h_isrc->i_mode; ++ err = vfsub_sio_notify_change(h_path, &ia, /*delegated*/NULL); ++ } ++ ++ return err; ++} ++ ++#define AuCpdown_PARENT_OPQ 1 ++#define AuCpdown_WHED (1 << 1) ++#define AuCpdown_MADE_DIR (1 << 2) ++#define AuCpdown_DIROPQ (1 << 3) ++#define au_ftest_cpdown(flags, name) ((flags) & AuCpdown_##name) ++#define au_fset_cpdown(flags, name) \ ++ do { (flags) |= AuCpdown_##name; } while (0) ++#define au_fclr_cpdown(flags, name) \ ++ do { (flags) &= ~AuCpdown_##name; } while (0) ++ ++static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst, ++ unsigned int *flags) ++{ ++ int err; ++ struct dentry *opq_dentry; ++ ++ opq_dentry = au_diropq_create(dentry, bdst); ++ err = PTR_ERR(opq_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out; ++ dput(opq_dentry); ++ au_fset_cpdown(*flags, DIROPQ); ++ ++out: ++ return err; ++} ++ ++static int au_cpdown_dir_wh(struct dentry *dentry, struct dentry *h_parent, ++ struct inode *dir, aufs_bindex_t bdst) ++{ ++ int err; ++ struct path h_path; ++ struct au_branch *br; ++ ++ br = au_sbr(dentry->d_sb, bdst); ++ h_path.dentry = au_wh_lkup(h_parent, &dentry->d_name, br); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ err = 0; ++ if (h_path.dentry->d_inode) { ++ h_path.mnt = au_br_mnt(br); ++ err = au_wh_unlink_dentry(au_h_iptr(dir, bdst), &h_path, ++ dentry); ++ } ++ dput(h_path.dentry); ++ ++out: ++ return err; ++} ++ ++static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst, ++ struct au_pin *pin, ++ struct dentry *h_parent, void *arg) ++{ ++ int err, rerr; ++ aufs_bindex_t bopq, bstart; ++ struct path h_path; ++ struct dentry *parent; ++ struct inode *h_dir, *h_inode, *inode, *dir; ++ unsigned int *flags = arg; ++ ++ bstart = au_dbstart(dentry); ++ /* dentry is di-locked */ ++ parent = dget_parent(dentry); ++ dir = parent->d_inode; ++ h_dir = h_parent->d_inode; ++ AuDebugOn(h_dir != au_h_iptr(dir, bdst)); ++ IMustLock(h_dir); ++ ++ err = au_lkup_neg(dentry, bdst, /*wh*/0); ++ if (unlikely(err < 0)) ++ goto out; ++ h_path.dentry = au_h_dptr(dentry, bdst); ++ h_path.mnt = au_sbr_mnt(dentry->d_sb, bdst); ++ err = vfsub_sio_mkdir(au_h_iptr(dir, bdst), &h_path, ++ S_IRWXU | S_IRUGO | S_IXUGO); ++ if (unlikely(err)) ++ goto out_put; ++ au_fset_cpdown(*flags, MADE_DIR); ++ ++ bopq = au_dbdiropq(dentry); ++ au_fclr_cpdown(*flags, WHED); ++ au_fclr_cpdown(*flags, DIROPQ); ++ if (au_dbwh(dentry) == bdst) ++ au_fset_cpdown(*flags, WHED); ++ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst) ++ au_fset_cpdown(*flags, PARENT_OPQ); ++ h_inode = h_path.dentry->d_inode; ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ if (au_ftest_cpdown(*flags, WHED)) { ++ err = au_cpdown_dir_opq(dentry, bdst, flags); ++ if (unlikely(err)) { ++ mutex_unlock(&h_inode->i_mutex); ++ goto out_dir; ++ } ++ } ++ ++ err = au_cpdown_attr(&h_path, au_h_dptr(dentry, bstart)); ++ mutex_unlock(&h_inode->i_mutex); ++ if (unlikely(err)) ++ goto out_opq; ++ ++ if (au_ftest_cpdown(*flags, WHED)) { ++ err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst); ++ if (unlikely(err)) ++ goto out_opq; ++ } ++ ++ inode = dentry->d_inode; ++ if (au_ibend(inode) < bdst) ++ au_set_ibend(inode, bdst); ++ au_set_h_iptr(inode, bdst, au_igrab(h_inode), ++ au_hi_flags(inode, /*isdir*/1)); ++ au_fhsm_wrote(dentry->d_sb, bdst, /*force*/0); ++ goto out; /* success */ ++ ++ /* revert */ ++out_opq: ++ if (au_ftest_cpdown(*flags, DIROPQ)) { ++ mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); ++ rerr = au_diropq_remove(dentry, bdst); ++ mutex_unlock(&h_inode->i_mutex); ++ if (unlikely(rerr)) { ++ AuIOErr("failed removing diropq for %pd b%d (%d)\n", ++ dentry, bdst, rerr); ++ err = -EIO; ++ goto out; ++ } ++ } ++out_dir: ++ if (au_ftest_cpdown(*flags, MADE_DIR)) { ++ rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path); ++ if (unlikely(rerr)) { ++ AuIOErr("failed removing %pd b%d (%d)\n", ++ dentry, bdst, rerr); ++ err = -EIO; ++ } ++ } ++out_put: ++ au_set_h_dptr(dentry, bdst, NULL); ++ if (au_dbend(dentry) == bdst) ++ au_update_dbend(dentry); ++out: ++ dput(parent); ++ return err; ++} ++ ++int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) ++{ ++ int err; ++ unsigned int flags; ++ ++ flags = 0; ++ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies for create */ ++ ++int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ int err, i, j, ndentry; ++ aufs_bindex_t bopq; ++ struct au_dcsub_pages dpages; ++ struct au_dpage *dpage; ++ struct dentry **dentries, *parent, *d; ++ ++ err = au_dpages_init(&dpages, GFP_NOFS); ++ if (unlikely(err)) ++ goto out; ++ parent = dget_parent(dentry); ++ err = au_dcsub_pages_rev_aufs(&dpages, parent, /*do_include*/0); ++ if (unlikely(err)) ++ goto out_free; ++ ++ err = bindex; ++ for (i = 0; i < dpages.ndpage; i++) { ++ dpage = dpages.dpages + i; ++ dentries = dpage->dentries; ++ ndentry = dpage->ndentry; ++ for (j = 0; j < ndentry; j++) { ++ d = dentries[j]; ++ di_read_lock_parent2(d, !AuLock_IR); ++ bopq = au_dbdiropq(d); ++ di_read_unlock(d, !AuLock_IR); ++ if (bopq >= 0 && bopq < err) ++ err = bopq; ++ } ++ } ++ ++out_free: ++ dput(parent); ++ au_dpages_free(&dpages); ++out: ++ return err; ++} ++ ++static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ for (; bindex >= 0; bindex--) ++ if (!au_br_rdonly(au_sbr(sb, bindex))) ++ return bindex; ++ return -EROFS; ++} ++ ++/* top down parent */ ++static int au_wbr_create_tdp(struct dentry *dentry, ++ unsigned int flags __maybe_unused) ++{ ++ int err; ++ aufs_bindex_t bstart, bindex; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent; ++ ++ sb = dentry->d_sb; ++ bstart = au_dbstart(dentry); ++ err = bstart; ++ if (!au_br_rdonly(au_sbr(sb, bstart))) ++ goto out; ++ ++ err = -EROFS; ++ parent = dget_parent(dentry); ++ for (bindex = au_dbstart(parent); bindex < bstart; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = bindex; ++ break; ++ } ++ } ++ dput(parent); ++ ++ /* bottom up here */ ++ if (unlikely(err < 0)) { ++ err = au_wbr_bu(sb, bstart - 1); ++ if (err >= 0) ++ err = au_wbr_nonopq(dentry, err); ++ } ++ ++out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* an exception for the policy other than tdp */ ++static int au_wbr_create_exp(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bwh, bdiropq; ++ struct dentry *parent; ++ ++ err = -1; ++ bwh = au_dbwh(dentry); ++ parent = dget_parent(dentry); ++ bdiropq = au_dbdiropq(parent); ++ if (bwh >= 0) { ++ if (bdiropq >= 0) ++ err = min(bdiropq, bwh); ++ else ++ err = bwh; ++ AuDbg("%d\n", err); ++ } else if (bdiropq >= 0) { ++ err = bdiropq; ++ AuDbg("%d\n", err); ++ } ++ dput(parent); ++ ++ if (err >= 0) ++ err = au_wbr_nonopq(dentry, err); ++ ++ if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err))) ++ err = -1; ++ ++ AuDbg("%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* round robin */ ++static int au_wbr_create_init_rr(struct super_block *sb) ++{ ++ int err; ++ ++ err = au_wbr_bu(sb, au_sbend(sb)); ++ atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */ ++ /* smp_mb(); */ ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_rr(struct dentry *dentry, unsigned int flags) ++{ ++ int err, nbr; ++ unsigned int u; ++ aufs_bindex_t bindex, bend; ++ struct super_block *sb; ++ atomic_t *next; ++ ++ err = au_wbr_create_exp(dentry); ++ if (err >= 0) ++ goto out; ++ ++ sb = dentry->d_sb; ++ next = &au_sbi(sb)->si_wbr_rr_next; ++ bend = au_sbend(sb); ++ nbr = bend + 1; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ if (!au_ftest_wbr(flags, DIR)) { ++ err = atomic_dec_return(next) + 1; ++ /* modulo for 0 is meaningless */ ++ if (unlikely(!err)) ++ err = atomic_dec_return(next) + 1; ++ } else ++ err = atomic_read(next); ++ AuDbg("%d\n", err); ++ u = err; ++ err = u % nbr; ++ AuDbg("%d\n", err); ++ if (!au_br_rdonly(au_sbr(sb, err))) ++ break; ++ err = -EROFS; ++ } ++ ++ if (err >= 0) ++ err = au_wbr_nonopq(dentry, err); ++ ++out: ++ AuDbg("%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* most free space */ ++static void au_mfs(struct dentry *dentry, struct dentry *parent) ++{ ++ struct super_block *sb; ++ struct au_branch *br; ++ struct au_wbr_mfs *mfs; ++ struct dentry *h_parent; ++ aufs_bindex_t bindex, bend; ++ int err; ++ unsigned long long b, bavail; ++ struct path h_path; ++ /* reduce the stack usage */ ++ struct kstatfs *st; ++ ++ st = kmalloc(sizeof(*st), GFP_NOFS); ++ if (unlikely(!st)) { ++ AuWarn1("failed updating mfs(%d), ignored\n", -ENOMEM); ++ return; ++ } ++ ++ bavail = 0; ++ sb = dentry->d_sb; ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ MtxMustLock(&mfs->mfs_lock); ++ mfs->mfs_bindex = -EROFS; ++ mfs->mfsrr_bytes = 0; ++ if (!parent) { ++ bindex = 0; ++ bend = au_sbend(sb); ++ } else { ++ bindex = au_dbstart(parent); ++ bend = au_dbtaildir(parent); ++ } ++ ++ for (; bindex <= bend; bindex++) { ++ if (parent) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ } ++ br = au_sbr(sb, bindex); ++ if (au_br_rdonly(br)) ++ continue; ++ ++ /* sb->s_root for NFS is unreliable */ ++ h_path.mnt = au_br_mnt(br); ++ h_path.dentry = h_path.mnt->mnt_root; ++ err = vfs_statfs(&h_path, st); ++ if (unlikely(err)) { ++ AuWarn1("failed statfs, b%d, %d\n", bindex, err); ++ continue; ++ } ++ ++ /* when the available size is equal, select the lower one */ ++ BUILD_BUG_ON(sizeof(b) < sizeof(st->f_bavail) ++ || sizeof(b) < sizeof(st->f_bsize)); ++ b = st->f_bavail * st->f_bsize; ++ br->br_wbr->wbr_bytes = b; ++ if (b >= bavail) { ++ bavail = b; ++ mfs->mfs_bindex = bindex; ++ mfs->mfs_jiffy = jiffies; ++ } ++ } ++ ++ mfs->mfsrr_bytes = bavail; ++ AuDbg("b%d\n", mfs->mfs_bindex); ++ kfree(st); ++} ++ ++static int au_wbr_create_mfs(struct dentry *dentry, unsigned int flags) ++{ ++ int err; ++ struct dentry *parent; ++ struct super_block *sb; ++ struct au_wbr_mfs *mfs; ++ ++ err = au_wbr_create_exp(dentry); ++ if (err >= 0) ++ goto out; ++ ++ sb = dentry->d_sb; ++ parent = NULL; ++ if (au_ftest_wbr(flags, PARENT)) ++ parent = dget_parent(dentry); ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mutex_lock(&mfs->mfs_lock); ++ if (time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) ++ || mfs->mfs_bindex < 0 ++ || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex))) ++ au_mfs(dentry, parent); ++ mutex_unlock(&mfs->mfs_lock); ++ err = mfs->mfs_bindex; ++ dput(parent); ++ ++ if (err >= 0) ++ err = au_wbr_nonopq(dentry, err); ++ ++out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_init_mfs(struct super_block *sb) ++{ ++ struct au_wbr_mfs *mfs; ++ ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mutex_init(&mfs->mfs_lock); ++ mfs->mfs_jiffy = 0; ++ mfs->mfs_bindex = -EROFS; ++ ++ return 0; ++} ++ ++static int au_wbr_create_fin_mfs(struct super_block *sb __maybe_unused) ++{ ++ mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock); ++ return 0; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* most free space and then round robin */ ++static int au_wbr_create_mfsrr(struct dentry *dentry, unsigned int flags) ++{ ++ int err; ++ struct au_wbr_mfs *mfs; ++ ++ err = au_wbr_create_mfs(dentry, flags); ++ if (err >= 0) { ++ mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs; ++ mutex_lock(&mfs->mfs_lock); ++ if (mfs->mfsrr_bytes < mfs->mfsrr_watermark) ++ err = au_wbr_create_rr(dentry, flags); ++ mutex_unlock(&mfs->mfs_lock); ++ } ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_create_init_mfsrr(struct super_block *sb) ++{ ++ int err; ++ ++ au_wbr_create_init_mfs(sb); /* ignore */ ++ err = au_wbr_create_init_rr(sb); ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* top down parent and most free space */ ++static int au_wbr_create_pmfs(struct dentry *dentry, unsigned int flags) ++{ ++ int err, e2; ++ unsigned long long b; ++ aufs_bindex_t bindex, bstart, bend; ++ struct super_block *sb; ++ struct dentry *parent, *h_parent; ++ struct au_branch *br; ++ ++ err = au_wbr_create_tdp(dentry, flags); ++ if (unlikely(err < 0)) ++ goto out; ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(parent); ++ bend = au_dbtaildir(parent); ++ if (bstart == bend) ++ goto out_parent; /* success */ ++ ++ e2 = au_wbr_create_mfs(dentry, flags); ++ if (e2 < 0) ++ goto out_parent; /* success */ ++ ++ /* when the available size is equal, select upper one */ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, err); ++ b = br->br_wbr->wbr_bytes; ++ AuDbg("b%d, %llu\n", err, b); ++ ++ for (bindex = bstart; bindex <= bend; bindex++) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ br = au_sbr(sb, bindex); ++ if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) { ++ b = br->br_wbr->wbr_bytes; ++ err = bindex; ++ AuDbg("b%d, %llu\n", err, b); ++ } ++ } ++ ++ if (err >= 0) ++ err = au_wbr_nonopq(dentry, err); ++ ++out_parent: ++ dput(parent); ++out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * - top down parent ++ * - most free space with parent ++ * - most free space round-robin regardless parent ++ */ ++static int au_wbr_create_pmfsrr(struct dentry *dentry, unsigned int flags) ++{ ++ int err; ++ unsigned long long watermark; ++ struct super_block *sb; ++ struct au_branch *br; ++ struct au_wbr_mfs *mfs; ++ ++ err = au_wbr_create_pmfs(dentry, flags | AuWbr_PARENT); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, err); ++ mfs = &au_sbi(sb)->si_wbr_mfs; ++ mutex_lock(&mfs->mfs_lock); ++ watermark = mfs->mfsrr_watermark; ++ mutex_unlock(&mfs->mfs_lock); ++ if (br->br_wbr->wbr_bytes < watermark) ++ /* regardless the parent dir */ ++ err = au_wbr_create_mfsrr(dentry, flags); ++ ++out: ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* policies for copyup */ ++ ++/* top down parent */ ++static int au_wbr_copyup_tdp(struct dentry *dentry) ++{ ++ return au_wbr_create_tdp(dentry, /*flags, anything is ok*/0); ++} ++ ++/* bottom up parent */ ++static int au_wbr_copyup_bup(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bindex, bstart; ++ struct dentry *parent, *h_parent; ++ struct super_block *sb; ++ ++ err = -EROFS; ++ sb = dentry->d_sb; ++ parent = dget_parent(dentry); ++ bstart = au_dbstart(parent); ++ for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) { ++ h_parent = au_h_dptr(parent, bindex); ++ if (!h_parent || !h_parent->d_inode) ++ continue; ++ ++ if (!au_br_rdonly(au_sbr(sb, bindex))) { ++ err = bindex; ++ break; ++ } ++ } ++ dput(parent); ++ ++ /* bottom up here */ ++ if (unlikely(err < 0)) ++ err = au_wbr_bu(sb, bstart - 1); ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++/* bottom up */ ++int au_wbr_do_copyup_bu(struct dentry *dentry, aufs_bindex_t bstart) ++{ ++ int err; ++ ++ err = au_wbr_bu(dentry->d_sb, bstart); ++ AuDbg("b%d\n", err); ++ if (err > bstart) ++ err = au_wbr_nonopq(dentry, err); ++ ++ AuDbg("b%d\n", err); ++ return err; ++} ++ ++static int au_wbr_copyup_bu(struct dentry *dentry) ++{ ++ int err; ++ aufs_bindex_t bstart; ++ ++ bstart = au_dbstart(dentry); ++ err = au_wbr_do_copyup_bu(dentry, bstart); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_wbr_copyup_operations au_wbr_copyup_ops[] = { ++ [AuWbrCopyup_TDP] = { ++ .copyup = au_wbr_copyup_tdp ++ }, ++ [AuWbrCopyup_BUP] = { ++ .copyup = au_wbr_copyup_bup ++ }, ++ [AuWbrCopyup_BU] = { ++ .copyup = au_wbr_copyup_bu ++ } ++}; ++ ++struct au_wbr_create_operations au_wbr_create_ops[] = { ++ [AuWbrCreate_TDP] = { ++ .create = au_wbr_create_tdp ++ }, ++ [AuWbrCreate_RR] = { ++ .create = au_wbr_create_rr, ++ .init = au_wbr_create_init_rr ++ }, ++ [AuWbrCreate_MFS] = { ++ .create = au_wbr_create_mfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSV] = { ++ .create = au_wbr_create_mfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSRR] = { ++ .create = au_wbr_create_mfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_MFSRRV] = { ++ .create = au_wbr_create_mfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFS] = { ++ .create = au_wbr_create_pmfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFSV] = { ++ .create = au_wbr_create_pmfs, ++ .init = au_wbr_create_init_mfs, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFSRR] = { ++ .create = au_wbr_create_pmfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ }, ++ [AuWbrCreate_PMFSRRV] = { ++ .create = au_wbr_create_pmfsrr, ++ .init = au_wbr_create_init_mfsrr, ++ .fin = au_wbr_create_fin_mfs ++ } ++}; +diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c +new file mode 100644 +index 0000000..21a264f +--- /dev/null ++++ b/fs/aufs/whout.c +@@ -0,0 +1,1048 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * whiteout for logical deletion and opaque directory ++ */ ++ ++#include "aufs.h" ++ ++#define WH_MASK S_IRUGO ++ ++/* ++ * If a directory contains this file, then it is opaque. We start with the ++ * .wh. flag so that it is blocked by lookup. ++ */ ++static struct qstr diropq_name = QSTR_INIT(AUFS_WH_DIROPQ, ++ sizeof(AUFS_WH_DIROPQ) - 1); ++ ++/* ++ * generate whiteout name, which is NOT terminated by NULL. ++ * @name: original d_name.name ++ * @len: original d_name.len ++ * @wh: whiteout qstr ++ * returns zero when succeeds, otherwise error. ++ * succeeded value as wh->name should be freed by kfree(). ++ */ ++int au_wh_name_alloc(struct qstr *wh, const struct qstr *name) ++{ ++ char *p; ++ ++ if (unlikely(name->len > PATH_MAX - AUFS_WH_PFX_LEN)) ++ return -ENAMETOOLONG; ++ ++ wh->len = name->len + AUFS_WH_PFX_LEN; ++ p = kmalloc(wh->len, GFP_NOFS); ++ wh->name = p; ++ if (p) { ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ memcpy(p + AUFS_WH_PFX_LEN, name->name, name->len); ++ /* smp_mb(); */ ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * test if the @wh_name exists under @h_parent. ++ * @try_sio specifies the necessary of super-io. ++ */ ++int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio) ++{ ++ int err; ++ struct dentry *wh_dentry; ++ ++ if (!try_sio) ++ wh_dentry = vfsub_lkup_one(wh_name, h_parent); ++ else ++ wh_dentry = au_sio_lkup_one(wh_name, h_parent); ++ err = PTR_ERR(wh_dentry); ++ if (IS_ERR(wh_dentry)) ++ goto out; ++ ++ err = 0; ++ if (!wh_dentry->d_inode) ++ goto out_wh; /* success */ ++ ++ err = 1; ++ if (S_ISREG(wh_dentry->d_inode->i_mode)) ++ goto out_wh; /* success */ ++ ++ err = -EIO; ++ AuIOErr("%pd Invalid whiteout entry type 0%o.\n", ++ wh_dentry, wh_dentry->d_inode->i_mode); ++ ++out_wh: ++ dput(wh_dentry); ++out: ++ return err; ++} ++ ++/* ++ * test if the @h_dentry sets opaque or not. ++ */ ++int au_diropq_test(struct dentry *h_dentry) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ h_dir = h_dentry->d_inode; ++ err = au_wh_test(h_dentry, &diropq_name, ++ au_test_h_perm_sio(h_dir, MAY_EXEC)); ++ return err; ++} ++ ++/* ++ * returns a negative dentry whose name is unique and temporary. ++ */ ++struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, ++ struct qstr *prefix) ++{ ++ struct dentry *dentry; ++ int i; ++ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1], ++ *name, *p; ++ /* strict atomic_t is unnecessary here */ ++ static unsigned short cnt; ++ struct qstr qs; ++ ++ BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN); ++ ++ name = defname; ++ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1; ++ if (unlikely(prefix->len > DNAME_INLINE_LEN)) { ++ dentry = ERR_PTR(-ENAMETOOLONG); ++ if (unlikely(qs.len > NAME_MAX)) ++ goto out; ++ dentry = ERR_PTR(-ENOMEM); ++ name = kmalloc(qs.len + 1, GFP_NOFS); ++ if (unlikely(!name)) ++ goto out; ++ } ++ ++ /* doubly whiteout-ed */ ++ memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2); ++ p = name + AUFS_WH_PFX_LEN * 2; ++ memcpy(p, prefix->name, prefix->len); ++ p += prefix->len; ++ *p++ = '.'; ++ AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN); ++ ++ qs.name = name; ++ for (i = 0; i < 3; i++) { ++ sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++); ++ dentry = au_sio_lkup_one(&qs, h_parent); ++ if (IS_ERR(dentry) || !dentry->d_inode) ++ goto out_name; ++ dput(dentry); ++ } ++ /* pr_warn("could not get random name\n"); */ ++ dentry = ERR_PTR(-EEXIST); ++ AuDbg("%.*s\n", AuLNPair(&qs)); ++ BUG(); ++ ++out_name: ++ if (name != defname) ++ kfree(name); ++out: ++ AuTraceErrPtr(dentry); ++ return dentry; ++} ++ ++/* ++ * rename the @h_dentry on @br to the whiteouted temporary name. ++ */ ++int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = au_br_mnt(br) ++ }; ++ struct inode *h_dir, *delegated; ++ struct dentry *h_parent; ++ ++ h_parent = h_dentry->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) ++ goto out; ++ ++ /* under the same dir, no need to lock_rename() */ ++ delegated = NULL; ++ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path, &delegated); ++ AuTraceErr(err); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal rename\n"); ++ iput(delegated); ++ } ++ dput(h_path.dentry); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * functions for removing a whiteout ++ */ ++ ++static int do_unlink_wh(struct inode *h_dir, struct path *h_path) ++{ ++ int err, force; ++ struct inode *delegated; ++ ++ /* ++ * forces superio when the dir has a sticky bit. ++ * this may be a violation of unix fs semantics. ++ */ ++ force = (h_dir->i_mode & S_ISVTX) ++ && !uid_eq(current_fsuid(), h_path->dentry->d_inode->i_uid); ++ delegated = NULL; ++ err = vfsub_unlink(h_dir, h_path, &delegated, force); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal unlink\n"); ++ iput(delegated); ++ } ++ return err; ++} ++ ++int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, ++ struct dentry *dentry) ++{ ++ int err; ++ ++ err = do_unlink_wh(h_dir, h_path); ++ if (!err && dentry) ++ au_set_dbwh(dentry, -1); ++ ++ return err; ++} ++ ++static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh, ++ struct au_branch *br) ++{ ++ int err; ++ struct path h_path = { ++ .mnt = au_br_mnt(br) ++ }; ++ ++ err = 0; ++ h_path.dentry = vfsub_lkup_one(wh, h_parent); ++ if (IS_ERR(h_path.dentry)) ++ err = PTR_ERR(h_path.dentry); ++ else { ++ if (h_path.dentry->d_inode ++ && S_ISREG(h_path.dentry->d_inode->i_mode)) ++ err = do_unlink_wh(h_parent->d_inode, &h_path); ++ dput(h_path.dentry); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * initialize/clean whiteout for a branch ++ */ ++ ++static void au_wh_clean(struct inode *h_dir, struct path *whpath, ++ const int isdir) ++{ ++ int err; ++ struct inode *delegated; ++ ++ if (!whpath->dentry->d_inode) ++ return; ++ ++ if (isdir) ++ err = vfsub_rmdir(h_dir, whpath); ++ else { ++ delegated = NULL; ++ err = vfsub_unlink(h_dir, whpath, &delegated, /*force*/0); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal unlink\n"); ++ iput(delegated); ++ } ++ } ++ if (unlikely(err)) ++ pr_warn("failed removing %pd (%d), ignored.\n", ++ whpath->dentry, err); ++} ++ ++static int test_linkable(struct dentry *h_root) ++{ ++ struct inode *h_dir = h_root->d_inode; ++ ++ if (h_dir->i_op->link) ++ return 0; ++ ++ pr_err("%pd (%s) doesn't support link(2), use noplink and rw+nolwh\n", ++ h_root, au_sbtype(h_root->d_sb)); ++ return -ENOSYS; ++} ++ ++/* todo: should this mkdir be done in /sbin/mount.aufs helper? */ ++static int au_whdir(struct inode *h_dir, struct path *path) ++{ ++ int err; ++ ++ err = -EEXIST; ++ if (!path->dentry->d_inode) { ++ int mode = S_IRWXU; ++ ++ if (au_test_nfs(path->dentry->d_sb)) ++ mode |= S_IXUGO; ++ err = vfsub_mkdir(h_dir, path, mode); ++ } else if (S_ISDIR(path->dentry->d_inode->i_mode)) ++ err = 0; ++ else ++ pr_err("unknown %pd exists\n", path->dentry); ++ ++ return err; ++} ++ ++struct au_wh_base { ++ const struct qstr *name; ++ struct dentry *dentry; ++}; ++ ++static void au_wh_init_ro(struct inode *h_dir, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/0); ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++} ++ ++/* ++ * returns tri-state, ++ * minus: error, caller should print the message ++ * zero: succuess ++ * plus: error, caller should NOT print the message ++ */ ++static int au_wh_init_rw_nolink(struct dentry *h_root, struct au_wbr *wbr, ++ int do_plink, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ h_dir = h_root->d_inode; ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ au_wh_clean(h_dir, h_path, /*isdir*/0); ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ if (do_plink) { ++ err = test_linkable(h_root); ++ if (unlikely(err)) { ++ err = 1; ++ goto out; ++ } ++ ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); ++ } else ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); ++ ++out: ++ return err; ++} ++ ++/* ++ * for the moment, aufs supports the branch filesystem which does not support ++ * link(2). testing on FAT which does not support i_op->setattr() fully either, ++ * copyup failed. finally, such filesystem will not be used as the writable ++ * branch. ++ * ++ * returns tri-state, see above. ++ */ ++static int au_wh_init_rw(struct dentry *h_root, struct au_wbr *wbr, ++ int do_plink, struct au_wh_base base[], ++ struct path *h_path) ++{ ++ int err; ++ struct inode *h_dir; ++ ++ WbrWhMustWriteLock(wbr); ++ ++ err = test_linkable(h_root); ++ if (unlikely(err)) { ++ err = 1; ++ goto out; ++ } ++ ++ /* ++ * todo: should this create be done in /sbin/mount.aufs helper? ++ */ ++ err = -EEXIST; ++ h_dir = h_root->d_inode; ++ if (!base[AuBrWh_BASE].dentry->d_inode) { ++ h_path->dentry = base[AuBrWh_BASE].dentry; ++ err = vfsub_create(h_dir, h_path, WH_MASK, /*want_excl*/true); ++ } else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode)) ++ err = 0; ++ else ++ pr_err("unknown %pd2 exists\n", base[AuBrWh_BASE].dentry); ++ if (unlikely(err)) ++ goto out; ++ ++ h_path->dentry = base[AuBrWh_PLINK].dentry; ++ if (do_plink) { ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); ++ } else ++ au_wh_clean(h_dir, h_path, /*isdir*/1); ++ wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry); ++ ++ h_path->dentry = base[AuBrWh_ORPH].dentry; ++ err = au_whdir(h_dir, h_path); ++ if (unlikely(err)) ++ goto out; ++ wbr->wbr_orph = dget(base[AuBrWh_ORPH].dentry); ++ ++out: ++ return err; ++} ++ ++/* ++ * initialize the whiteout base file/dir for @br. ++ */ ++int au_wh_init(struct au_branch *br, struct super_block *sb) ++{ ++ int err, i; ++ const unsigned char do_plink ++ = !!au_opt_test(au_mntflags(sb), PLINK); ++ struct inode *h_dir; ++ struct path path = br->br_path; ++ struct dentry *h_root = path.dentry; ++ struct au_wbr *wbr = br->br_wbr; ++ static const struct qstr base_name[] = { ++ [AuBrWh_BASE] = QSTR_INIT(AUFS_BASE_NAME, ++ sizeof(AUFS_BASE_NAME) - 1), ++ [AuBrWh_PLINK] = QSTR_INIT(AUFS_PLINKDIR_NAME, ++ sizeof(AUFS_PLINKDIR_NAME) - 1), ++ [AuBrWh_ORPH] = QSTR_INIT(AUFS_ORPHDIR_NAME, ++ sizeof(AUFS_ORPHDIR_NAME) - 1) ++ }; ++ struct au_wh_base base[] = { ++ [AuBrWh_BASE] = { ++ .name = base_name + AuBrWh_BASE, ++ .dentry = NULL ++ }, ++ [AuBrWh_PLINK] = { ++ .name = base_name + AuBrWh_PLINK, ++ .dentry = NULL ++ }, ++ [AuBrWh_ORPH] = { ++ .name = base_name + AuBrWh_ORPH, ++ .dentry = NULL ++ } ++ }; ++ ++ if (wbr) ++ WbrWhMustWriteLock(wbr); ++ ++ for (i = 0; i < AuBrWh_Last; i++) { ++ /* doubly whiteouted */ ++ struct dentry *d; ++ ++ d = au_wh_lkup(h_root, (void *)base[i].name, br); ++ err = PTR_ERR(d); ++ if (IS_ERR(d)) ++ goto out; ++ ++ base[i].dentry = d; ++ AuDebugOn(wbr ++ && wbr->wbr_wh[i] ++ && wbr->wbr_wh[i] != base[i].dentry); ++ } ++ ++ if (wbr) ++ for (i = 0; i < AuBrWh_Last; i++) { ++ dput(wbr->wbr_wh[i]); ++ wbr->wbr_wh[i] = NULL; ++ } ++ ++ err = 0; ++ if (!au_br_writable(br->br_perm)) { ++ h_dir = h_root->d_inode; ++ au_wh_init_ro(h_dir, base, &path); ++ } else if (!au_br_wh_linkable(br->br_perm)) { ++ err = au_wh_init_rw_nolink(h_root, wbr, do_plink, base, &path); ++ if (err > 0) ++ goto out; ++ else if (err) ++ goto out_err; ++ } else { ++ err = au_wh_init_rw(h_root, wbr, do_plink, base, &path); ++ if (err > 0) ++ goto out; ++ else if (err) ++ goto out_err; ++ } ++ goto out; /* success */ ++ ++out_err: ++ pr_err("an error(%d) on the writable branch %pd(%s)\n", ++ err, h_root, au_sbtype(h_root->d_sb)); ++out: ++ for (i = 0; i < AuBrWh_Last; i++) ++ dput(base[i].dentry); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++/* ++ * whiteouts are all hard-linked usually. ++ * when its link count reaches a ceiling, we create a new whiteout base ++ * asynchronously. ++ */ ++ ++struct reinit_br_wh { ++ struct super_block *sb; ++ struct au_branch *br; ++}; ++ ++static void reinit_br_wh(void *arg) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct path h_path; ++ struct reinit_br_wh *a = arg; ++ struct au_wbr *wbr; ++ struct inode *dir, *delegated; ++ struct dentry *h_root; ++ struct au_hinode *hdir; ++ ++ err = 0; ++ wbr = a->br->br_wbr; ++ /* big aufs lock */ ++ si_noflush_write_lock(a->sb); ++ if (!au_br_writable(a->br->br_perm)) ++ goto out; ++ bindex = au_br_index(a->sb, a->br->br_id); ++ if (unlikely(bindex < 0)) ++ goto out; ++ ++ di_read_lock_parent(a->sb->s_root, AuLock_IR); ++ dir = a->sb->s_root->d_inode; ++ hdir = au_hi(dir, bindex); ++ h_root = au_h_dptr(a->sb->s_root, bindex); ++ AuDebugOn(h_root != au_br_dentry(a->br)); ++ ++ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ wbr_wh_write_lock(wbr); ++ err = au_h_verify(wbr->wbr_whbase, au_opt_udba(a->sb), hdir->hi_inode, ++ h_root, a->br); ++ if (!err) { ++ h_path.dentry = wbr->wbr_whbase; ++ h_path.mnt = au_br_mnt(a->br); ++ delegated = NULL; ++ err = vfsub_unlink(hdir->hi_inode, &h_path, &delegated, ++ /*force*/0); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal unlink\n"); ++ iput(delegated); ++ } ++ } else { ++ pr_warn("%pd is moved, ignored\n", wbr->wbr_whbase); ++ err = 0; ++ } ++ dput(wbr->wbr_whbase); ++ wbr->wbr_whbase = NULL; ++ if (!err) ++ err = au_wh_init(a->br, a->sb); ++ wbr_wh_write_unlock(wbr); ++ au_hn_imtx_unlock(hdir); ++ di_read_unlock(a->sb->s_root, AuLock_IR); ++ if (!err) ++ au_fhsm_wrote(a->sb, bindex, /*force*/0); ++ ++out: ++ if (wbr) ++ atomic_dec(&wbr->wbr_wh_running); ++ atomic_dec(&a->br->br_count); ++ si_write_unlock(a->sb); ++ au_nwt_done(&au_sbi(a->sb)->si_nowait); ++ kfree(arg); ++ if (unlikely(err)) ++ AuIOErr("err %d\n", err); ++} ++ ++static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br) ++{ ++ int do_dec, wkq_err; ++ struct reinit_br_wh *arg; ++ ++ do_dec = 1; ++ if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1) ++ goto out; ++ ++ /* ignore ENOMEM */ ++ arg = kmalloc(sizeof(*arg), GFP_NOFS); ++ if (arg) { ++ /* ++ * dec(wh_running), kfree(arg) and dec(br_count) ++ * in reinit function ++ */ ++ arg->sb = sb; ++ arg->br = br; ++ atomic_inc(&br->br_count); ++ wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*flags*/0); ++ if (unlikely(wkq_err)) { ++ atomic_dec(&br->br_wbr->wbr_wh_running); ++ atomic_dec(&br->br_count); ++ kfree(arg); ++ } ++ do_dec = 0; ++ } ++ ++out: ++ if (do_dec) ++ atomic_dec(&br->br_wbr->wbr_wh_running); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create the whiteout @wh. ++ */ ++static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex, ++ struct dentry *wh) ++{ ++ int err; ++ struct path h_path = { ++ .dentry = wh ++ }; ++ struct au_branch *br; ++ struct au_wbr *wbr; ++ struct dentry *h_parent; ++ struct inode *h_dir, *delegated; ++ ++ h_parent = wh->d_parent; /* dir inode is locked */ ++ h_dir = h_parent->d_inode; ++ IMustLock(h_dir); ++ ++ br = au_sbr(sb, bindex); ++ h_path.mnt = au_br_mnt(br); ++ wbr = br->br_wbr; ++ wbr_wh_read_lock(wbr); ++ if (wbr->wbr_whbase) { ++ delegated = NULL; ++ err = vfsub_link(wbr->wbr_whbase, h_dir, &h_path, &delegated); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal link\n"); ++ iput(delegated); ++ } ++ if (!err || err != -EMLINK) ++ goto out; ++ ++ /* link count full. re-initialize br_whbase. */ ++ kick_reinit_br_wh(sb, br); ++ } ++ ++ /* return this error in this context */ ++ err = vfsub_create(h_dir, &h_path, WH_MASK, /*want_excl*/true); ++ if (!err) ++ au_fhsm_wrote(sb, bindex, /*force*/0); ++ ++out: ++ wbr_wh_read_unlock(wbr); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create or remove the diropq. ++ */ ++static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags) ++{ ++ struct dentry *opq_dentry, *h_dentry; ++ struct super_block *sb; ++ struct au_branch *br; ++ int err; ++ ++ sb = dentry->d_sb; ++ br = au_sbr(sb, bindex); ++ h_dentry = au_h_dptr(dentry, bindex); ++ opq_dentry = vfsub_lkup_one(&diropq_name, h_dentry); ++ if (IS_ERR(opq_dentry)) ++ goto out; ++ ++ if (au_ftest_diropq(flags, CREATE)) { ++ err = link_or_create_wh(sb, bindex, opq_dentry); ++ if (!err) { ++ au_set_dbdiropq(dentry, bindex); ++ goto out; /* success */ ++ } ++ } else { ++ struct path tmp = { ++ .dentry = opq_dentry, ++ .mnt = au_br_mnt(br) ++ }; ++ err = do_unlink_wh(au_h_iptr(dentry->d_inode, bindex), &tmp); ++ if (!err) ++ au_set_dbdiropq(dentry, -1); ++ } ++ dput(opq_dentry); ++ opq_dentry = ERR_PTR(err); ++ ++out: ++ return opq_dentry; ++} ++ ++struct do_diropq_args { ++ struct dentry **errp; ++ struct dentry *dentry; ++ aufs_bindex_t bindex; ++ unsigned int flags; ++}; ++ ++static void call_do_diropq(void *args) ++{ ++ struct do_diropq_args *a = args; ++ *a->errp = do_diropq(a->dentry, a->bindex, a->flags); ++} ++ ++struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags) ++{ ++ struct dentry *diropq, *h_dentry; ++ ++ h_dentry = au_h_dptr(dentry, bindex); ++ if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE)) ++ diropq = do_diropq(dentry, bindex, flags); ++ else { ++ int wkq_err; ++ struct do_diropq_args args = { ++ .errp = &diropq, ++ .dentry = dentry, ++ .bindex = bindex, ++ .flags = flags ++ }; ++ ++ wkq_err = au_wkq_wait(call_do_diropq, &args); ++ if (unlikely(wkq_err)) ++ diropq = ERR_PTR(wkq_err); ++ } ++ ++ return diropq; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * lookup whiteout dentry. ++ * @h_parent: lower parent dentry which must exist and be locked ++ * @base_name: name of dentry which will be whiteouted ++ * returns dentry for whiteout. ++ */ ++struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, ++ struct au_branch *br) ++{ ++ int err; ++ struct qstr wh_name; ++ struct dentry *wh_dentry; ++ ++ err = au_wh_name_alloc(&wh_name, base_name); ++ wh_dentry = ERR_PTR(err); ++ if (!err) { ++ wh_dentry = vfsub_lkup_one(&wh_name, h_parent); ++ kfree(wh_name.name); ++ } ++ return wh_dentry; ++} ++ ++/* ++ * link/create a whiteout for @dentry on @bindex. ++ */ ++struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent) ++{ ++ struct dentry *wh_dentry; ++ struct super_block *sb; ++ int err; ++ ++ sb = dentry->d_sb; ++ wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, au_sbr(sb, bindex)); ++ if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) { ++ err = link_or_create_wh(sb, bindex, wh_dentry); ++ if (!err) { ++ au_set_dbwh(dentry, bindex); ++ au_fhsm_wrote(sb, bindex, /*force*/0); ++ } else { ++ dput(wh_dentry); ++ wh_dentry = ERR_PTR(err); ++ } ++ } ++ ++ return wh_dentry; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* Delete all whiteouts in this directory on branch bindex. */ ++static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist, ++ aufs_bindex_t bindex, struct au_branch *br) ++{ ++ int err; ++ unsigned long ul, n; ++ struct qstr wh_name; ++ char *p; ++ struct hlist_head *head; ++ struct au_vdir_wh *pos; ++ struct au_vdir_destr *str; ++ ++ err = -ENOMEM; ++ p = (void *)__get_free_page(GFP_NOFS); ++ wh_name.name = p; ++ if (unlikely(!wh_name.name)) ++ goto out; ++ ++ err = 0; ++ memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); ++ p += AUFS_WH_PFX_LEN; ++ n = whlist->nh_num; ++ head = whlist->nh_head; ++ for (ul = 0; !err && ul < n; ul++, head++) { ++ hlist_for_each_entry(pos, head, wh_hash) { ++ if (pos->wh_bindex != bindex) ++ continue; ++ ++ str = &pos->wh_str; ++ if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) { ++ memcpy(p, str->name, str->len); ++ wh_name.len = AUFS_WH_PFX_LEN + str->len; ++ err = unlink_wh_name(h_dentry, &wh_name, br); ++ if (!err) ++ continue; ++ break; ++ } ++ AuIOErr("whiteout name too long %.*s\n", ++ str->len, str->name); ++ err = -EIO; ++ break; ++ } ++ } ++ free_page((unsigned long)wh_name.name); ++ ++out: ++ return err; ++} ++ ++struct del_wh_children_args { ++ int *errp; ++ struct dentry *h_dentry; ++ struct au_nhash *whlist; ++ aufs_bindex_t bindex; ++ struct au_branch *br; ++}; ++ ++static void call_del_wh_children(void *args) ++{ ++ struct del_wh_children_args *a = args; ++ *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->br); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp) ++{ ++ struct au_whtmp_rmdir *whtmp; ++ int err; ++ unsigned int rdhash; ++ ++ SiMustAnyLock(sb); ++ ++ whtmp = kmalloc(sizeof(*whtmp), gfp); ++ if (unlikely(!whtmp)) { ++ whtmp = ERR_PTR(-ENOMEM); ++ goto out; ++ } ++ ++ whtmp->dir = NULL; ++ whtmp->br = NULL; ++ whtmp->wh_dentry = NULL; ++ /* no estimation for dir size */ ++ rdhash = au_sbi(sb)->si_rdhash; ++ if (!rdhash) ++ rdhash = AUFS_RDHASH_DEF; ++ err = au_nhash_alloc(&whtmp->whlist, rdhash, gfp); ++ if (unlikely(err)) { ++ kfree(whtmp); ++ whtmp = ERR_PTR(err); ++ } ++ ++out: ++ return whtmp; ++} ++ ++void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp) ++{ ++ if (whtmp->br) ++ atomic_dec(&whtmp->br->br_count); ++ dput(whtmp->wh_dentry); ++ iput(whtmp->dir); ++ au_nhash_wh_free(&whtmp->whlist); ++ kfree(whtmp); ++} ++ ++/* ++ * rmdir the whiteouted temporary named dir @h_dentry. ++ * @whlist: whiteouted children. ++ */ ++int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_nhash *whlist) ++{ ++ int err; ++ unsigned int h_nlink; ++ struct path h_tmp; ++ struct inode *wh_inode, *h_dir; ++ struct au_branch *br; ++ ++ h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ ++ IMustLock(h_dir); ++ ++ br = au_sbr(dir->i_sb, bindex); ++ wh_inode = wh_dentry->d_inode; ++ mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD); ++ ++ /* ++ * someone else might change some whiteouts while we were sleeping. ++ * it means this whlist may have an obsoleted entry. ++ */ ++ if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE)) ++ err = del_wh_children(wh_dentry, whlist, bindex, br); ++ else { ++ int wkq_err; ++ struct del_wh_children_args args = { ++ .errp = &err, ++ .h_dentry = wh_dentry, ++ .whlist = whlist, ++ .bindex = bindex, ++ .br = br ++ }; ++ ++ wkq_err = au_wkq_wait(call_del_wh_children, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ mutex_unlock(&wh_inode->i_mutex); ++ ++ if (!err) { ++ h_tmp.dentry = wh_dentry; ++ h_tmp.mnt = au_br_mnt(br); ++ h_nlink = h_dir->i_nlink; ++ err = vfsub_rmdir(h_dir, &h_tmp); ++ /* some fs doesn't change the parent nlink in some cases */ ++ h_nlink -= h_dir->i_nlink; ++ } ++ ++ if (!err) { ++ if (au_ibstart(dir) == bindex) { ++ /* todo: dir->i_mutex is necessary */ ++ au_cpup_attr_timesizes(dir); ++ if (h_nlink) ++ vfsub_drop_nlink(dir); ++ } ++ return 0; /* success */ ++ } ++ ++ pr_warn("failed removing %pd(%d), ignored\n", wh_dentry, err); ++ return err; ++} ++ ++static void call_rmdir_whtmp(void *args) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ struct au_whtmp_rmdir *a = args; ++ struct super_block *sb; ++ struct dentry *h_parent; ++ struct inode *h_dir; ++ struct au_hinode *hdir; ++ ++ /* rmdir by nfsd may cause deadlock with this i_mutex */ ++ /* mutex_lock(&a->dir->i_mutex); */ ++ err = -EROFS; ++ sb = a->dir->i_sb; ++ si_read_lock(sb, !AuLock_FLUSH); ++ if (!au_br_writable(a->br->br_perm)) ++ goto out; ++ bindex = au_br_index(sb, a->br->br_id); ++ if (unlikely(bindex < 0)) ++ goto out; ++ ++ err = -EIO; ++ ii_write_lock_parent(a->dir); ++ h_parent = dget_parent(a->wh_dentry); ++ h_dir = h_parent->d_inode; ++ hdir = au_hi(a->dir, bindex); ++ err = vfsub_mnt_want_write(au_br_mnt(a->br)); ++ if (unlikely(err)) ++ goto out_mnt; ++ au_hn_imtx_lock_nested(hdir, AuLsc_I_PARENT); ++ err = au_h_verify(a->wh_dentry, au_opt_udba(sb), h_dir, h_parent, ++ a->br); ++ if (!err) ++ err = au_whtmp_rmdir(a->dir, bindex, a->wh_dentry, &a->whlist); ++ au_hn_imtx_unlock(hdir); ++ vfsub_mnt_drop_write(au_br_mnt(a->br)); ++ ++out_mnt: ++ dput(h_parent); ++ ii_write_unlock(a->dir); ++out: ++ /* mutex_unlock(&a->dir->i_mutex); */ ++ au_whtmp_rmdir_free(a); ++ si_read_unlock(sb); ++ au_nwt_done(&au_sbi(sb)->si_nowait); ++ if (unlikely(err)) ++ AuIOErr("err %d\n", err); ++} ++ ++void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_whtmp_rmdir *args) ++{ ++ int wkq_err; ++ struct super_block *sb; ++ ++ IMustLock(dir); ++ ++ /* all post-process will be done in do_rmdir_whtmp(). */ ++ sb = dir->i_sb; ++ args->dir = au_igrab(dir); ++ args->br = au_sbr(sb, bindex); ++ atomic_inc(&args->br->br_count); ++ args->wh_dentry = dget(wh_dentry); ++ wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, sb, /*flags*/0); ++ if (unlikely(wkq_err)) { ++ pr_warn("rmdir error %pd (%d), ignored\n", wh_dentry, wkq_err); ++ au_whtmp_rmdir_free(args); ++ } ++} +diff --git a/fs/aufs/whout.h b/fs/aufs/whout.h +new file mode 100644 +index 0000000..14155f5 +--- /dev/null ++++ b/fs/aufs/whout.h +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * whiteout for logical deletion and opaque directory ++ */ ++ ++#ifndef __AUFS_WHOUT_H__ ++#define __AUFS_WHOUT_H__ ++ ++#ifdef __KERNEL__ ++ ++#include "dir.h" ++ ++/* whout.c */ ++int au_wh_name_alloc(struct qstr *wh, const struct qstr *name); ++struct au_branch; ++int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio); ++int au_diropq_test(struct dentry *h_dentry); ++struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br, ++ struct qstr *prefix); ++int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br); ++int au_wh_unlink_dentry(struct inode *h_dir, struct path *h_path, ++ struct dentry *dentry); ++int au_wh_init(struct au_branch *br, struct super_block *sb); ++ ++/* diropq flags */ ++#define AuDiropq_CREATE 1 ++#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name) ++#define au_fset_diropq(flags, name) \ ++ do { (flags) |= AuDiropq_##name; } while (0) ++#define au_fclr_diropq(flags, name) \ ++ do { (flags) &= ~AuDiropq_##name; } while (0) ++ ++struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, ++ unsigned int flags); ++struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, ++ struct au_branch *br); ++struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, ++ struct dentry *h_parent); ++ ++/* real rmdir for the whiteout-ed dir */ ++struct au_whtmp_rmdir { ++ struct inode *dir; ++ struct au_branch *br; ++ struct dentry *wh_dentry; ++ struct au_nhash whlist; ++}; ++ ++struct au_whtmp_rmdir *au_whtmp_rmdir_alloc(struct super_block *sb, gfp_t gfp); ++void au_whtmp_rmdir_free(struct au_whtmp_rmdir *whtmp); ++int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_nhash *whlist); ++void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, ++ struct dentry *wh_dentry, struct au_whtmp_rmdir *args); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline struct dentry *au_diropq_create(struct dentry *dentry, ++ aufs_bindex_t bindex) ++{ ++ return au_diropq_sio(dentry, bindex, AuDiropq_CREATE); ++} ++ ++static inline int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex) ++{ ++ return PTR_ERR(au_diropq_sio(dentry, bindex, !AuDiropq_CREATE)); ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_WHOUT_H__ */ +diff --git a/fs/aufs/wkq.c b/fs/aufs/wkq.c +new file mode 100644 +index 0000000..08870ec +--- /dev/null ++++ b/fs/aufs/wkq.c +@@ -0,0 +1,200 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * workqueue for asynchronous/super-io operations ++ * todo: try new dredential scheme ++ */ ++ ++#include ++#include "aufs.h" ++ ++/* internal workqueue named AUFS_WKQ_NAME */ ++ ++static struct workqueue_struct *au_wkq; ++ ++struct au_wkinfo { ++ struct work_struct wk; ++ struct kobject *kobj; ++ ++ unsigned int flags; /* see wkq.h */ ++ ++ au_wkq_func_t func; ++ void *args; ++ ++ struct completion *comp; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void wkq_func(struct work_struct *wk) ++{ ++ struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk); ++ ++ AuDebugOn(!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)); ++ AuDebugOn(rlimit(RLIMIT_FSIZE) != RLIM_INFINITY); ++ ++ wkinfo->func(wkinfo->args); ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) ++ complete(wkinfo->comp); ++ else { ++ kobject_put(wkinfo->kobj); ++ module_put(THIS_MODULE); /* todo: ?? */ ++ kfree(wkinfo); ++ } ++} ++ ++/* ++ * Since struct completion is large, try allocating it dynamically. ++ */ ++#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */ ++#define AuWkqCompDeclare(name) struct completion *comp = NULL ++ ++static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) ++{ ++ *comp = kmalloc(sizeof(**comp), GFP_NOFS); ++ if (*comp) { ++ init_completion(*comp); ++ wkinfo->comp = *comp; ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++static void au_wkq_comp_free(struct completion *comp) ++{ ++ kfree(comp); ++} ++ ++#else ++ ++/* no braces */ ++#define AuWkqCompDeclare(name) \ ++ DECLARE_COMPLETION_ONSTACK(_ ## name); \ ++ struct completion *comp = &_ ## name ++ ++static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) ++{ ++ wkinfo->comp = *comp; ++ return 0; ++} ++ ++static void au_wkq_comp_free(struct completion *comp __maybe_unused) ++{ ++ /* empty */ ++} ++#endif /* 4KSTACKS */ ++ ++static void au_wkq_run(struct au_wkinfo *wkinfo) ++{ ++ if (au_ftest_wkq(wkinfo->flags, NEST)) { ++ if (au_wkq_test()) { ++ AuWarn1("wkq from wkq, unless silly-rename on NFS," ++ " due to a dead dir by UDBA?\n"); ++ AuDebugOn(au_ftest_wkq(wkinfo->flags, WAIT)); ++ } ++ } else ++ au_dbg_verify_kthread(); ++ ++ if (au_ftest_wkq(wkinfo->flags, WAIT)) { ++ INIT_WORK_ONSTACK(&wkinfo->wk, wkq_func); ++ queue_work(au_wkq, &wkinfo->wk); ++ } else { ++ INIT_WORK(&wkinfo->wk, wkq_func); ++ schedule_work(&wkinfo->wk); ++ } ++} ++ ++/* ++ * Be careful. It is easy to make deadlock happen. ++ * processA: lock, wkq and wait ++ * processB: wkq and wait, lock in wkq ++ * --> deadlock ++ */ ++int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args) ++{ ++ int err; ++ AuWkqCompDeclare(comp); ++ struct au_wkinfo wkinfo = { ++ .flags = flags, ++ .func = func, ++ .args = args ++ }; ++ ++ err = au_wkq_comp_alloc(&wkinfo, &comp); ++ if (!err) { ++ au_wkq_run(&wkinfo); ++ /* no timeout, no interrupt */ ++ wait_for_completion(wkinfo.comp); ++ au_wkq_comp_free(comp); ++ destroy_work_on_stack(&wkinfo.wk); ++ } ++ ++ return err; ++ ++} ++ ++/* ++ * Note: dget/dput() in func for aufs dentries are not supported. It will be a ++ * problem in a concurrent umounting. ++ */ ++int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, ++ unsigned int flags) ++{ ++ int err; ++ struct au_wkinfo *wkinfo; ++ ++ atomic_inc(&au_sbi(sb)->si_nowait.nw_len); ++ ++ /* ++ * wkq_func() must free this wkinfo. ++ * it highly depends upon the implementation of workqueue. ++ */ ++ err = 0; ++ wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS); ++ if (wkinfo) { ++ wkinfo->kobj = &au_sbi(sb)->si_kobj; ++ wkinfo->flags = flags & ~AuWkq_WAIT; ++ wkinfo->func = func; ++ wkinfo->args = args; ++ wkinfo->comp = NULL; ++ kobject_get(wkinfo->kobj); ++ __module_get(THIS_MODULE); /* todo: ?? */ ++ ++ au_wkq_run(wkinfo); ++ } else { ++ err = -ENOMEM; ++ au_nwt_done(&au_sbi(sb)->si_nowait); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++void au_nwt_init(struct au_nowait_tasks *nwt) ++{ ++ atomic_set(&nwt->nw_len, 0); ++ /* smp_mb(); */ /* atomic_set */ ++ init_waitqueue_head(&nwt->nw_wq); ++} ++ ++void au_wkq_fin(void) ++{ ++ destroy_workqueue(au_wkq); ++} ++ ++int __init au_wkq_init(void) ++{ ++ int err; ++ ++ err = 0; ++ au_wkq = alloc_workqueue(AUFS_WKQ_NAME, 0, WQ_DFL_ACTIVE); ++ if (IS_ERR(au_wkq)) ++ err = PTR_ERR(au_wkq); ++ else if (!au_wkq) ++ err = -ENOMEM; ++ ++ return err; ++} +diff --git a/fs/aufs/wkq.h b/fs/aufs/wkq.h +new file mode 100644 +index 0000000..8f01343 +--- /dev/null ++++ b/fs/aufs/wkq.h +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * workqueue for asynchronous/super-io operations ++ * todo: try new credentials management scheme ++ */ ++ ++#ifndef __AUFS_WKQ_H__ ++#define __AUFS_WKQ_H__ ++ ++#ifdef __KERNEL__ ++ ++struct super_block; ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * in the next operation, wait for the 'nowait' tasks in system-wide workqueue ++ */ ++struct au_nowait_tasks { ++ atomic_t nw_len; ++ wait_queue_head_t nw_wq; ++}; ++ ++/* ---------------------------------------------------------------------- */ ++ ++typedef void (*au_wkq_func_t)(void *args); ++ ++/* wkq flags */ ++#define AuWkq_WAIT 1 ++#define AuWkq_NEST (1 << 1) ++#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) ++#define au_fset_wkq(flags, name) \ ++ do { (flags) |= AuWkq_##name; } while (0) ++#define au_fclr_wkq(flags, name) \ ++ do { (flags) &= ~AuWkq_##name; } while (0) ++ ++#ifndef CONFIG_AUFS_HNOTIFY ++#undef AuWkq_NEST ++#define AuWkq_NEST 0 ++#endif ++ ++/* wkq.c */ ++int au_wkq_do_wait(unsigned int flags, au_wkq_func_t func, void *args); ++int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, ++ unsigned int flags); ++void au_nwt_init(struct au_nowait_tasks *nwt); ++int __init au_wkq_init(void); ++void au_wkq_fin(void); ++ ++/* ---------------------------------------------------------------------- */ ++ ++static inline int au_wkq_test(void) ++{ ++ return current->flags & PF_WQ_WORKER; ++} ++ ++static inline int au_wkq_wait(au_wkq_func_t func, void *args) ++{ ++ return au_wkq_do_wait(AuWkq_WAIT, func, args); ++} ++ ++static inline void au_nwt_done(struct au_nowait_tasks *nwt) ++{ ++ if (atomic_dec_and_test(&nwt->nw_len)) ++ wake_up_all(&nwt->nw_wq); ++} ++ ++static inline int au_nwt_flush(struct au_nowait_tasks *nwt) ++{ ++ wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); ++ return 0; ++} ++ ++#endif /* __KERNEL__ */ ++#endif /* __AUFS_WKQ_H__ */ +diff --git a/fs/aufs/xattr.c b/fs/aufs/xattr.c +new file mode 100644 +index 0000000..78b34d9 +--- /dev/null ++++ b/fs/aufs/xattr.c +@@ -0,0 +1,321 @@ ++/* ++ * Copyright (C) 2014-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * handling xattr functions ++ */ ++ ++#include ++#include "aufs.h" ++ ++static int au_xattr_ignore(int err, char *name, unsigned int ignore_flags) ++{ ++ if (!ignore_flags) ++ goto out; ++ switch (err) { ++ case -ENOMEM: ++ case -EDQUOT: ++ goto out; ++ } ++ ++ if ((ignore_flags & AuBrAttr_ICEX) == AuBrAttr_ICEX) { ++ err = 0; ++ goto out; ++ } ++ ++#define cmp(brattr, prefix) do { \ ++ if (!strncmp(name, XATTR_##prefix##_PREFIX, \ ++ XATTR_##prefix##_PREFIX_LEN)) { \ ++ if (ignore_flags & AuBrAttr_ICEX_##brattr) \ ++ err = 0; \ ++ goto out; \ ++ } \ ++ } while (0) ++ ++ cmp(SEC, SECURITY); ++ cmp(SYS, SYSTEM); ++ cmp(TR, TRUSTED); ++ cmp(USR, USER); ++#undef cmp ++ ++ if (ignore_flags & AuBrAttr_ICEX_OTH) ++ err = 0; ++ ++out: ++ return err; ++} ++ ++static const int au_xattr_out_of_list = AuBrAttr_ICEX_OTH << 1; ++ ++static int au_do_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, ++ char *name, char **buf, unsigned int ignore_flags) ++{ ++ int err; ++ ssize_t ssz; ++ struct inode *h_idst; ++ ++ ssz = vfs_getxattr_alloc(h_src, name, buf, 0, GFP_NOFS); ++ err = ssz; ++ if (unlikely(err <= 0)) { ++ AuTraceErr(err); ++ if (err == -ENODATA ++ || (err == -EOPNOTSUPP ++ && (ignore_flags & au_xattr_out_of_list))) ++ err = 0; ++ goto out; ++ } ++ ++ /* unlock it temporary */ ++ h_idst = h_dst->d_inode; ++ mutex_unlock(&h_idst->i_mutex); ++ err = vfsub_setxattr(h_dst, name, *buf, ssz, /*flags*/0); ++ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2); ++ if (unlikely(err)) { ++ AuDbg("%s, err %d\n", name, err); ++ err = au_xattr_ignore(err, name, ignore_flags); ++ } ++ ++out: ++ return err; ++} ++ ++int au_cpup_xattr(struct dentry *h_dst, struct dentry *h_src, int ignore_flags) ++{ ++ int err, unlocked, acl_access, acl_default; ++ ssize_t ssz; ++ struct inode *h_isrc, *h_idst; ++ char *value, *p, *o, *e; ++ ++ /* try stopping to update the source inode while we are referencing */ ++ /* there should not be the parent-child relation ship between them */ ++ h_isrc = h_src->d_inode; ++ h_idst = h_dst->d_inode; ++ mutex_unlock(&h_idst->i_mutex); ++ mutex_lock_nested(&h_isrc->i_mutex, AuLsc_I_CHILD); ++ mutex_lock_nested(&h_idst->i_mutex, AuLsc_I_CHILD2); ++ unlocked = 0; ++ ++ /* some filesystems don't list POSIX ACL, for example tmpfs */ ++ ssz = vfs_listxattr(h_src, NULL, 0); ++ err = ssz; ++ if (unlikely(err < 0)) { ++ AuTraceErr(err); ++ if (err == -ENODATA ++ || err == -EOPNOTSUPP) ++ err = 0; /* ignore */ ++ goto out; ++ } ++ ++ err = 0; ++ p = NULL; ++ o = NULL; ++ if (ssz) { ++ err = -ENOMEM; ++ p = kmalloc(ssz, GFP_NOFS); ++ o = p; ++ if (unlikely(!p)) ++ goto out; ++ err = vfs_listxattr(h_src, p, ssz); ++ } ++ mutex_unlock(&h_isrc->i_mutex); ++ unlocked = 1; ++ AuDbg("err %d, ssz %zd\n", err, ssz); ++ if (unlikely(err < 0)) ++ goto out_free; ++ ++ err = 0; ++ e = p + ssz; ++ value = NULL; ++ acl_access = 0; ++ acl_default = 0; ++ while (!err && p < e) { ++ acl_access |= !strncmp(p, XATTR_NAME_POSIX_ACL_ACCESS, ++ sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1); ++ acl_default |= !strncmp(p, XATTR_NAME_POSIX_ACL_DEFAULT, ++ sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) ++ - 1); ++ err = au_do_cpup_xattr(h_dst, h_src, p, &value, ignore_flags); ++ p += strlen(p) + 1; ++ } ++ AuTraceErr(err); ++ ignore_flags |= au_xattr_out_of_list; ++ if (!err && !acl_access) { ++ err = au_do_cpup_xattr(h_dst, h_src, ++ XATTR_NAME_POSIX_ACL_ACCESS, &value, ++ ignore_flags); ++ AuTraceErr(err); ++ } ++ if (!err && !acl_default) { ++ err = au_do_cpup_xattr(h_dst, h_src, ++ XATTR_NAME_POSIX_ACL_DEFAULT, &value, ++ ignore_flags); ++ AuTraceErr(err); ++ } ++ ++ kfree(value); ++ ++out_free: ++ kfree(o); ++out: ++ if (!unlocked) ++ mutex_unlock(&h_isrc->i_mutex); ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++enum { ++ AU_XATTR_LIST, ++ AU_XATTR_GET ++}; ++ ++struct au_lgxattr { ++ int type; ++ union { ++ struct { ++ char *list; ++ size_t size; ++ } list; ++ struct { ++ const char *name; ++ void *value; ++ size_t size; ++ } get; ++ } u; ++}; ++ ++static ssize_t au_lgxattr(struct dentry *dentry, struct au_lgxattr *arg) ++{ ++ ssize_t err; ++ struct path h_path; ++ struct super_block *sb; ++ ++ sb = dentry->d_sb; ++ err = si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLM); ++ if (unlikely(err)) ++ goto out; ++ err = au_h_path_getattr(dentry, /*force*/1, &h_path); ++ if (unlikely(err)) ++ goto out_si; ++ if (unlikely(!h_path.dentry)) ++ /* illegally overlapped or something */ ++ goto out_di; /* pretending success */ ++ ++ /* always topmost entry only */ ++ switch (arg->type) { ++ case AU_XATTR_LIST: ++ err = vfs_listxattr(h_path.dentry, ++ arg->u.list.list, arg->u.list.size); ++ break; ++ case AU_XATTR_GET: ++ err = vfs_getxattr(h_path.dentry, ++ arg->u.get.name, arg->u.get.value, ++ arg->u.get.size); ++ break; ++ } ++ ++out_di: ++ di_read_unlock(dentry, AuLock_IR); ++out_si: ++ si_read_unlock(sb); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t size) ++{ ++ struct au_lgxattr arg = { ++ .type = AU_XATTR_LIST, ++ .u.list = { ++ .list = list, ++ .size = size ++ }, ++ }; ++ ++ return au_lgxattr(dentry, &arg); ++} ++ ++ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value, ++ size_t size) ++{ ++ struct au_lgxattr arg = { ++ .type = AU_XATTR_GET, ++ .u.get = { ++ .name = name, ++ .value = value, ++ .size = size ++ }, ++ }; ++ ++ return au_lgxattr(dentry, &arg); ++} ++ ++int aufs_setxattr(struct dentry *dentry, const char *name, const void *value, ++ size_t size, int flags) ++{ ++ struct au_srxattr arg = { ++ .type = AU_XATTR_SET, ++ .u.set = { ++ .name = name, ++ .value = value, ++ .size = size, ++ .flags = flags ++ }, ++ }; ++ ++ return au_srxattr(dentry, &arg); ++} ++ ++int aufs_removexattr(struct dentry *dentry, const char *name) ++{ ++ struct au_srxattr arg = { ++ .type = AU_XATTR_REMOVE, ++ .u.remove = { ++ .name = name ++ }, ++ }; ++ ++ return au_srxattr(dentry, &arg); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++#if 0 ++static size_t au_xattr_list(struct dentry *dentry, char *list, size_t list_size, ++ const char *name, size_t name_len, int type) ++{ ++ return aufs_listxattr(dentry, list, list_size); ++} ++ ++static int au_xattr_get(struct dentry *dentry, const char *name, void *buffer, ++ size_t size, int type) ++{ ++ return aufs_getxattr(dentry, name, buffer, size); ++} ++ ++static int au_xattr_set(struct dentry *dentry, const char *name, ++ const void *value, size_t size, int flags, int type) ++{ ++ return aufs_setxattr(dentry, name, value, size, flags); ++} ++ ++static const struct xattr_handler au_xattr_handler = { ++ /* no prefix, no flags */ ++ .list = au_xattr_list, ++ .get = au_xattr_get, ++ .set = au_xattr_set ++ /* why no remove? */ ++}; ++ ++static const struct xattr_handler *au_xattr_handlers[] = { ++ &au_xattr_handler ++}; ++ ++void au_xattr_init(struct super_block *sb) ++{ ++ /* sb->s_xattr = au_xattr_handlers; */ ++} ++#endif +diff --git a/fs/aufs/xino.c b/fs/aufs/xino.c +new file mode 100644 +index 0000000..c053d55 +--- /dev/null ++++ b/fs/aufs/xino.c +@@ -0,0 +1,1305 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++/* ++ * external inode number translation table and bitmap ++ */ ++ ++#include ++#include ++#include "aufs.h" ++ ++/* todo: unnecessary to support mmap_sem since kernel-space? */ ++ssize_t xino_fread(au_readf_t func, struct file *file, void *kbuf, size_t size, ++ loff_t *pos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ union { ++ void *k; ++ char __user *u; ++ } buf; ++ ++ buf.k = kbuf; ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ do { ++ /* todo: signal_pending? */ ++ err = func(file, buf.u, size, pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ set_fs(oldfs); ++ ++#if 0 /* reserved for future use */ ++ if (err > 0) ++ fsnotify_access(file->f_path.dentry); ++#endif ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *kbuf, ++ size_t size, loff_t *pos) ++{ ++ ssize_t err; ++ mm_segment_t oldfs; ++ union { ++ void *k; ++ const char __user *u; ++ } buf; ++ ++ buf.k = kbuf; ++ oldfs = get_fs(); ++ set_fs(KERNEL_DS); ++ do { ++ /* todo: signal_pending? */ ++ err = func(file, buf.u, size, pos); ++ } while (err == -EAGAIN || err == -EINTR); ++ set_fs(oldfs); ++ ++#if 0 /* reserved for future use */ ++ if (err > 0) ++ fsnotify_modify(file->f_path.dentry); ++#endif ++ ++ return err; ++} ++ ++struct do_xino_fwrite_args { ++ ssize_t *errp; ++ au_writef_t func; ++ struct file *file; ++ void *buf; ++ size_t size; ++ loff_t *pos; ++}; ++ ++static void call_do_xino_fwrite(void *args) ++{ ++ struct do_xino_fwrite_args *a = args; ++ *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); ++} ++ ++ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, ++ loff_t *pos) ++{ ++ ssize_t err; ++ ++ /* todo: signal block and no wkq? */ ++ if (rlimit(RLIMIT_FSIZE) == RLIM_INFINITY) { ++ lockdep_off(); ++ err = do_xino_fwrite(func, file, buf, size, pos); ++ lockdep_on(); ++ } else { ++ /* ++ * it breaks RLIMIT_FSIZE and normal user's limit, ++ * users should care about quota and real 'filesystem full.' ++ */ ++ int wkq_err; ++ struct do_xino_fwrite_args args = { ++ .errp = &err, ++ .func = func, ++ .file = file, ++ .buf = buf, ++ .size = size, ++ .pos = pos ++ }; ++ ++ wkq_err = au_wkq_wait(call_do_xino_fwrite, &args); ++ if (unlikely(wkq_err)) ++ err = wkq_err; ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create a new xinofile at the same place/path as @base_file. ++ */ ++struct file *au_xino_create2(struct file *base_file, struct file *copy_src) ++{ ++ struct file *file; ++ struct dentry *base, *parent; ++ struct inode *dir, *delegated; ++ struct qstr *name; ++ struct path path; ++ int err; ++ ++ base = base_file->f_path.dentry; ++ parent = base->d_parent; /* dir inode is locked */ ++ dir = parent->d_inode; ++ IMustLock(dir); ++ ++ file = ERR_PTR(-EINVAL); ++ name = &base->d_name; ++ path.dentry = vfsub_lookup_one_len(name->name, parent, name->len); ++ if (IS_ERR(path.dentry)) { ++ file = (void *)path.dentry; ++ pr_err("%pd lookup err %ld\n", ++ base, PTR_ERR(path.dentry)); ++ goto out; ++ } ++ ++ /* no need to mnt_want_write() since we call dentry_open() later */ ++ err = vfs_create(dir, path.dentry, S_IRUGO | S_IWUGO, NULL); ++ if (unlikely(err)) { ++ file = ERR_PTR(err); ++ pr_err("%pd create err %d\n", base, err); ++ goto out_dput; ++ } ++ ++ path.mnt = base_file->f_path.mnt; ++ file = vfsub_dentry_open(&path, ++ O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE ++ /* | __FMODE_NONOTIFY */); ++ if (IS_ERR(file)) { ++ pr_err("%pd open err %ld\n", base, PTR_ERR(file)); ++ goto out_dput; ++ } ++ ++ delegated = NULL; ++ err = vfsub_unlink(dir, &file->f_path, &delegated, /*force*/0); ++ if (unlikely(err == -EWOULDBLOCK)) { ++ pr_warn("cannot retry for NFSv4 delegation" ++ " for an internal unlink\n"); ++ iput(delegated); ++ } ++ if (unlikely(err)) { ++ pr_err("%pd unlink err %d\n", base, err); ++ goto out_fput; ++ } ++ ++ if (copy_src) { ++ /* no one can touch copy_src xino */ ++ err = au_copy_file(file, copy_src, vfsub_f_size_read(copy_src)); ++ if (unlikely(err)) { ++ pr_err("%pd copy err %d\n", base, err); ++ goto out_fput; ++ } ++ } ++ goto out_dput; /* success */ ++ ++out_fput: ++ fput(file); ++ file = ERR_PTR(err); ++out_dput: ++ dput(path.dentry); ++out: ++ return file; ++} ++ ++struct au_xino_lock_dir { ++ struct au_hinode *hdir; ++ struct dentry *parent; ++ struct mutex *mtx; ++}; ++ ++static void au_xino_lock_dir(struct super_block *sb, struct file *xino, ++ struct au_xino_lock_dir *ldir) ++{ ++ aufs_bindex_t brid, bindex; ++ ++ ldir->hdir = NULL; ++ bindex = -1; ++ brid = au_xino_brid(sb); ++ if (brid >= 0) ++ bindex = au_br_index(sb, brid); ++ if (bindex >= 0) { ++ ldir->hdir = au_hi(sb->s_root->d_inode, bindex); ++ au_hn_imtx_lock_nested(ldir->hdir, AuLsc_I_PARENT); ++ } else { ++ ldir->parent = dget_parent(xino->f_path.dentry); ++ ldir->mtx = &ldir->parent->d_inode->i_mutex; ++ mutex_lock_nested(ldir->mtx, AuLsc_I_PARENT); ++ } ++} ++ ++static void au_xino_unlock_dir(struct au_xino_lock_dir *ldir) ++{ ++ if (ldir->hdir) ++ au_hn_imtx_unlock(ldir->hdir); ++ else { ++ mutex_unlock(ldir->mtx); ++ dput(ldir->parent); ++ } ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* trucate xino files asynchronously */ ++ ++int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ int err; ++ unsigned long jiffy; ++ blkcnt_t blocks; ++ aufs_bindex_t bi, bend; ++ struct kstatfs *st; ++ struct au_branch *br; ++ struct file *new_xino, *file; ++ struct super_block *h_sb; ++ struct au_xino_lock_dir ldir; ++ ++ err = -ENOMEM; ++ st = kzalloc(sizeof(*st), GFP_NOFS); ++ if (unlikely(!st)) ++ goto out; ++ ++ err = -EINVAL; ++ bend = au_sbend(sb); ++ if (unlikely(bindex < 0 || bend < bindex)) ++ goto out_st; ++ br = au_sbr(sb, bindex); ++ file = br->br_xino.xi_file; ++ if (!file) ++ goto out_st; ++ ++ err = vfs_statfs(&file->f_path, st); ++ if (unlikely(err)) ++ AuErr1("statfs err %d, ignored\n", err); ++ jiffy = jiffies; ++ blocks = file_inode(file)->i_blocks; ++ pr_info("begin truncating xino(b%d), ib%llu, %llu/%llu free blks\n", ++ bindex, (u64)blocks, st->f_bfree, st->f_blocks); ++ ++ au_xino_lock_dir(sb, file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ new_xino = au_xino_create2(file, file); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(new_xino); ++ if (IS_ERR(new_xino)) { ++ pr_err("err %d, ignored\n", err); ++ goto out_st; ++ } ++ err = 0; ++ fput(file); ++ br->br_xino.xi_file = new_xino; ++ ++ h_sb = au_br_sb(br); ++ for (bi = 0; bi <= bend; bi++) { ++ if (unlikely(bi == bindex)) ++ continue; ++ br = au_sbr(sb, bi); ++ if (au_br_sb(br) != h_sb) ++ continue; ++ ++ fput(br->br_xino.xi_file); ++ br->br_xino.xi_file = new_xino; ++ get_file(new_xino); ++ } ++ ++ err = vfs_statfs(&new_xino->f_path, st); ++ if (!err) { ++ pr_info("end truncating xino(b%d), ib%llu, %llu/%llu free blks\n", ++ bindex, (u64)file_inode(new_xino)->i_blocks, ++ st->f_bfree, st->f_blocks); ++ if (file_inode(new_xino)->i_blocks < blocks) ++ au_sbi(sb)->si_xino_jiffy = jiffy; ++ } else ++ AuErr1("statfs err %d, ignored\n", err); ++ ++out_st: ++ kfree(st); ++out: ++ return err; ++} ++ ++struct xino_do_trunc_args { ++ struct super_block *sb; ++ struct au_branch *br; ++}; ++ ++static void xino_do_trunc(void *_args) ++{ ++ struct xino_do_trunc_args *args = _args; ++ struct super_block *sb; ++ struct au_branch *br; ++ struct inode *dir; ++ int err; ++ aufs_bindex_t bindex; ++ ++ err = 0; ++ sb = args->sb; ++ dir = sb->s_root->d_inode; ++ br = args->br; ++ ++ si_noflush_write_lock(sb); ++ ii_read_lock_parent(dir); ++ bindex = au_br_index(sb, br->br_id); ++ err = au_xino_trunc(sb, bindex); ++ ii_read_unlock(dir); ++ if (unlikely(err)) ++ pr_warn("err b%d, (%d)\n", bindex, err); ++ atomic_dec(&br->br_xino_running); ++ atomic_dec(&br->br_count); ++ si_write_unlock(sb); ++ au_nwt_done(&au_sbi(sb)->si_nowait); ++ kfree(args); ++} ++ ++static int xino_trunc_test(struct super_block *sb, struct au_branch *br) ++{ ++ int err; ++ struct kstatfs st; ++ struct au_sbinfo *sbinfo; ++ ++ /* todo: si_xino_expire and the ratio should be customizable */ ++ sbinfo = au_sbi(sb); ++ if (time_before(jiffies, ++ sbinfo->si_xino_jiffy + sbinfo->si_xino_expire)) ++ return 0; ++ ++ /* truncation border */ ++ err = vfs_statfs(&br->br_xino.xi_file->f_path, &st); ++ if (unlikely(err)) { ++ AuErr1("statfs err %d, ignored\n", err); ++ return 0; ++ } ++ if (div64_u64(st.f_bfree * 100, st.f_blocks) >= AUFS_XINO_DEF_TRUNC) ++ return 0; ++ ++ return 1; ++} ++ ++static void xino_try_trunc(struct super_block *sb, struct au_branch *br) ++{ ++ struct xino_do_trunc_args *args; ++ int wkq_err; ++ ++ if (!xino_trunc_test(sb, br)) ++ return; ++ ++ if (atomic_inc_return(&br->br_xino_running) > 1) ++ goto out; ++ ++ /* lock and kfree() will be called in trunc_xino() */ ++ args = kmalloc(sizeof(*args), GFP_NOFS); ++ if (unlikely(!args)) { ++ AuErr1("no memory\n"); ++ goto out_args; ++ } ++ ++ atomic_inc(&br->br_count); ++ args->sb = sb; ++ args->br = br; ++ wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*flags*/0); ++ if (!wkq_err) ++ return; /* success */ ++ ++ pr_err("wkq %d\n", wkq_err); ++ atomic_dec(&br->br_count); ++ ++out_args: ++ kfree(args); ++out: ++ atomic_dec(&br->br_xino_running); ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int au_xino_do_write(au_writef_t write, struct file *file, ++ ino_t h_ino, ino_t ino) ++{ ++ loff_t pos; ++ ssize_t sz; ++ ++ pos = h_ino; ++ if (unlikely(au_loff_max / sizeof(ino) - 1 < pos)) { ++ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); ++ return -EFBIG; ++ } ++ pos *= sizeof(ino); ++ sz = xino_fwrite(write, file, &ino, sizeof(ino), &pos); ++ if (sz == sizeof(ino)) ++ return 0; /* success */ ++ ++ AuIOErr("write failed (%zd)\n", sz); ++ return -EIO; ++} ++ ++/* ++ * write @ino to the xinofile for the specified branch{@sb, @bindex} ++ * at the position of @h_ino. ++ * even if @ino is zero, it is written to the xinofile and means no entry. ++ * if the size of the xino file on a specific filesystem exceeds the watermark, ++ * try truncating it. ++ */ ++int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t ino) ++{ ++ int err; ++ unsigned int mnt_flags; ++ struct au_branch *br; ++ ++ BUILD_BUG_ON(sizeof(long long) != sizeof(au_loff_max) ++ || ((loff_t)-1) > 0); ++ SiMustAnyLock(sb); ++ ++ mnt_flags = au_mntflags(sb); ++ if (!au_opt_test(mnt_flags, XINO)) ++ return 0; ++ ++ br = au_sbr(sb, bindex); ++ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, ++ h_ino, ino); ++ if (!err) { ++ if (au_opt_test(mnt_flags, TRUNC_XINO) ++ && au_test_fs_trunc_xino(au_br_sb(br))) ++ xino_try_trunc(sb, br); ++ return 0; /* success */ ++ } ++ ++ AuIOErr("write failed (%d)\n", err); ++ return -EIO; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* aufs inode number bitmap */ ++ ++static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE; ++static ino_t xib_calc_ino(unsigned long pindex, int bit) ++{ ++ ino_t ino; ++ ++ AuDebugOn(bit < 0 || page_bits <= bit); ++ ino = AUFS_FIRST_INO + pindex * page_bits + bit; ++ return ino; ++} ++ ++static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit) ++{ ++ AuDebugOn(ino < AUFS_FIRST_INO); ++ ino -= AUFS_FIRST_INO; ++ *pindex = ino / page_bits; ++ *bit = ino % page_bits; ++} ++ ++static int xib_pindex(struct super_block *sb, unsigned long pindex) ++{ ++ int err; ++ loff_t pos; ++ ssize_t sz; ++ struct au_sbinfo *sbinfo; ++ struct file *xib; ++ unsigned long *p; ++ ++ sbinfo = au_sbi(sb); ++ MtxMustLock(&sbinfo->si_xib_mtx); ++ AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE ++ || !au_opt_test(sbinfo->si_mntflags, XINO)); ++ ++ if (pindex == sbinfo->si_xib_last_pindex) ++ return 0; ++ ++ xib = sbinfo->si_xib; ++ p = sbinfo->si_xib_buf; ++ pos = sbinfo->si_xib_last_pindex; ++ pos *= PAGE_SIZE; ++ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ if (unlikely(sz != PAGE_SIZE)) ++ goto out; ++ ++ pos = pindex; ++ pos *= PAGE_SIZE; ++ if (vfsub_f_size_read(xib) >= pos + PAGE_SIZE) ++ sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); ++ else { ++ memset(p, 0, PAGE_SIZE); ++ sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); ++ } ++ if (sz == PAGE_SIZE) { ++ sbinfo->si_xib_last_pindex = pindex; ++ return 0; /* success */ ++ } ++ ++out: ++ AuIOErr1("write failed (%zd)\n", sz); ++ err = sz; ++ if (sz >= 0) ++ err = -EIO; ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static void au_xib_clear_bit(struct inode *inode) ++{ ++ int err, bit; ++ unsigned long pindex; ++ struct super_block *sb; ++ struct au_sbinfo *sbinfo; ++ ++ AuDebugOn(inode->i_nlink); ++ ++ sb = inode->i_sb; ++ xib_calc_bit(inode->i_ino, &pindex, &bit); ++ AuDebugOn(page_bits <= bit); ++ sbinfo = au_sbi(sb); ++ mutex_lock(&sbinfo->si_xib_mtx); ++ err = xib_pindex(sb, pindex); ++ if (!err) { ++ clear_bit(bit, sbinfo->si_xib_buf); ++ sbinfo->si_xib_next_bit = bit; ++ } ++ mutex_unlock(&sbinfo->si_xib_mtx); ++} ++ ++/* for s_op->delete_inode() */ ++void au_xino_delete_inode(struct inode *inode, const int unlinked) ++{ ++ int err; ++ unsigned int mnt_flags; ++ aufs_bindex_t bindex, bend, bi; ++ unsigned char try_trunc; ++ struct au_iinfo *iinfo; ++ struct super_block *sb; ++ struct au_hinode *hi; ++ struct inode *h_inode; ++ struct au_branch *br; ++ au_writef_t xwrite; ++ ++ sb = inode->i_sb; ++ mnt_flags = au_mntflags(sb); ++ if (!au_opt_test(mnt_flags, XINO) ++ || inode->i_ino == AUFS_ROOT_INO) ++ return; ++ ++ if (unlinked) { ++ au_xigen_inc(inode); ++ au_xib_clear_bit(inode); ++ } ++ ++ iinfo = au_ii(inode); ++ if (!iinfo) ++ return; ++ ++ bindex = iinfo->ii_bstart; ++ if (bindex < 0) ++ return; ++ ++ xwrite = au_sbi(sb)->si_xwrite; ++ try_trunc = !!au_opt_test(mnt_flags, TRUNC_XINO); ++ hi = iinfo->ii_hinode + bindex; ++ bend = iinfo->ii_bend; ++ for (; bindex <= bend; bindex++, hi++) { ++ h_inode = hi->hi_inode; ++ if (!h_inode ++ || (!unlinked && h_inode->i_nlink)) ++ continue; ++ ++ /* inode may not be revalidated */ ++ bi = au_br_index(sb, hi->hi_id); ++ if (bi < 0) ++ continue; ++ ++ br = au_sbr(sb, bi); ++ err = au_xino_do_write(xwrite, br->br_xino.xi_file, ++ h_inode->i_ino, /*ino*/0); ++ if (!err && try_trunc ++ && au_test_fs_trunc_xino(au_br_sb(br))) ++ xino_try_trunc(sb, br); ++ } ++} ++ ++/* get an unused inode number from bitmap */ ++ino_t au_xino_new_ino(struct super_block *sb) ++{ ++ ino_t ino; ++ unsigned long *p, pindex, ul, pend; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ int free_bit, err; ++ ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return iunique(sb, AUFS_FIRST_INO); ++ ++ sbinfo = au_sbi(sb); ++ mutex_lock(&sbinfo->si_xib_mtx); ++ p = sbinfo->si_xib_buf; ++ free_bit = sbinfo->si_xib_next_bit; ++ if (free_bit < page_bits && !test_bit(free_bit, p)) ++ goto out; /* success */ ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ ++ pindex = sbinfo->si_xib_last_pindex; ++ for (ul = pindex - 1; ul < ULONG_MAX; ul--) { ++ err = xib_pindex(sb, ul); ++ if (unlikely(err)) ++ goto out_err; ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ } ++ ++ file = sbinfo->si_xib; ++ pend = vfsub_f_size_read(file) / PAGE_SIZE; ++ for (ul = pindex + 1; ul <= pend; ul++) { ++ err = xib_pindex(sb, ul); ++ if (unlikely(err)) ++ goto out_err; ++ free_bit = find_first_zero_bit(p, page_bits); ++ if (free_bit < page_bits) ++ goto out; /* success */ ++ } ++ BUG(); ++ ++out: ++ set_bit(free_bit, p); ++ sbinfo->si_xib_next_bit = free_bit + 1; ++ pindex = sbinfo->si_xib_last_pindex; ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ ino = xib_calc_ino(pindex, free_bit); ++ AuDbg("i%lu\n", (unsigned long)ino); ++ return ino; ++out_err: ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ AuDbg("i0\n"); ++ return 0; ++} ++ ++/* ++ * read @ino from xinofile for the specified branch{@sb, @bindex} ++ * at the position of @h_ino. ++ * if @ino does not exist and @do_new is true, get new one. ++ */ ++int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, ++ ino_t *ino) ++{ ++ int err; ++ ssize_t sz; ++ loff_t pos; ++ struct file *file; ++ struct au_sbinfo *sbinfo; ++ ++ *ino = 0; ++ if (!au_opt_test(au_mntflags(sb), XINO)) ++ return 0; /* no xino */ ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ pos = h_ino; ++ if (unlikely(au_loff_max / sizeof(*ino) - 1 < pos)) { ++ AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); ++ return -EFBIG; ++ } ++ pos *= sizeof(*ino); ++ ++ file = au_sbr(sb, bindex)->br_xino.xi_file; ++ if (vfsub_f_size_read(file) < pos + sizeof(*ino)) ++ return 0; /* no ino */ ++ ++ sz = xino_fread(sbinfo->si_xread, file, ino, sizeof(*ino), &pos); ++ if (sz == sizeof(*ino)) ++ return 0; /* success */ ++ ++ err = sz; ++ if (unlikely(sz >= 0)) { ++ err = -EIO; ++ AuIOErr("xino read error (%zd)\n", sz); ++ } ++ ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* create and set a new xino file */ ++ ++struct file *au_xino_create(struct super_block *sb, char *fname, int silent) ++{ ++ struct file *file; ++ struct dentry *h_parent, *d; ++ struct inode *h_dir; ++ int err; ++ ++ /* ++ * at mount-time, and the xino file is the default path, ++ * hnotify is disabled so we have no notify events to ignore. ++ * when a user specified the xino, we cannot get au_hdir to be ignored. ++ */ ++ file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE ++ /* | __FMODE_NONOTIFY */, ++ S_IRUGO | S_IWUGO); ++ if (IS_ERR(file)) { ++ if (!silent) ++ pr_err("open %s(%ld)\n", fname, PTR_ERR(file)); ++ return file; ++ } ++ ++ /* keep file count */ ++ h_parent = dget_parent(file->f_path.dentry); ++ h_dir = h_parent->d_inode; ++ mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); ++ /* mnt_want_write() is unnecessary here */ ++ /* no delegation since it is just created */ ++ err = vfsub_unlink(h_dir, &file->f_path, /*delegated*/NULL, /*force*/0); ++ mutex_unlock(&h_dir->i_mutex); ++ dput(h_parent); ++ if (unlikely(err)) { ++ if (!silent) ++ pr_err("unlink %s(%d)\n", fname, err); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ d = file->f_path.dentry; ++ if (unlikely(sb == d->d_sb)) { ++ if (!silent) ++ pr_err("%s must be outside\n", fname); ++ goto out; ++ } ++ if (unlikely(au_test_fs_bad_xino(d->d_sb))) { ++ if (!silent) ++ pr_err("xino doesn't support %s(%s)\n", ++ fname, au_sbtype(d->d_sb)); ++ goto out; ++ } ++ return file; /* success */ ++ ++out: ++ fput(file); ++ file = ERR_PTR(err); ++ return file; ++} ++ ++/* ++ * find another branch who is on the same filesystem of the specified ++ * branch{@btgt}. search until @bend. ++ */ ++static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt, ++ aufs_bindex_t bend) ++{ ++ aufs_bindex_t bindex; ++ struct super_block *tgt_sb = au_sbr_sb(sb, btgt); ++ ++ for (bindex = 0; bindex < btgt; bindex++) ++ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) ++ return bindex; ++ for (bindex++; bindex <= bend; bindex++) ++ if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) ++ return bindex; ++ return -1; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * initialize the xinofile for the specified branch @br ++ * at the place/path where @base_file indicates. ++ * test whether another branch is on the same filesystem or not, ++ * if @do_test is true. ++ */ ++int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino, ++ struct file *base_file, int do_test) ++{ ++ int err; ++ ino_t ino; ++ aufs_bindex_t bend, bindex; ++ struct au_branch *shared_br, *b; ++ struct file *file; ++ struct super_block *tgt_sb; ++ ++ shared_br = NULL; ++ bend = au_sbend(sb); ++ if (do_test) { ++ tgt_sb = au_br_sb(br); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ b = au_sbr(sb, bindex); ++ if (tgt_sb == au_br_sb(b)) { ++ shared_br = b; ++ break; ++ } ++ } ++ } ++ ++ if (!shared_br || !shared_br->br_xino.xi_file) { ++ struct au_xino_lock_dir ldir; ++ ++ au_xino_lock_dir(sb, base_file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ file = au_xino_create2(base_file, NULL); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ br->br_xino.xi_file = file; ++ } else { ++ br->br_xino.xi_file = shared_br->br_xino.xi_file; ++ get_file(br->br_xino.xi_file); ++ } ++ ++ ino = AUFS_ROOT_INO; ++ err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, ++ h_ino, ino); ++ if (unlikely(err)) { ++ fput(br->br_xino.xi_file); ++ br->br_xino.xi_file = NULL; ++ } ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* trucate a xino bitmap file */ ++ ++/* todo: slow */ ++static int do_xib_restore(struct super_block *sb, struct file *file, void *page) ++{ ++ int err, bit; ++ ssize_t sz; ++ unsigned long pindex; ++ loff_t pos, pend; ++ struct au_sbinfo *sbinfo; ++ au_readf_t func; ++ ino_t *ino; ++ unsigned long *p; ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ MtxMustLock(&sbinfo->si_xib_mtx); ++ p = sbinfo->si_xib_buf; ++ func = sbinfo->si_xread; ++ pend = vfsub_f_size_read(file); ++ pos = 0; ++ while (pos < pend) { ++ sz = xino_fread(func, file, page, PAGE_SIZE, &pos); ++ err = sz; ++ if (unlikely(sz <= 0)) ++ goto out; ++ ++ err = 0; ++ for (ino = page; sz > 0; ino++, sz -= sizeof(ino)) { ++ if (unlikely(*ino < AUFS_FIRST_INO)) ++ continue; ++ ++ xib_calc_bit(*ino, &pindex, &bit); ++ AuDebugOn(page_bits <= bit); ++ err = xib_pindex(sb, pindex); ++ if (!err) ++ set_bit(bit, p); ++ else ++ goto out; ++ } ++ } ++ ++out: ++ return err; ++} ++ ++static int xib_restore(struct super_block *sb) ++{ ++ int err; ++ aufs_bindex_t bindex, bend; ++ void *page; ++ ++ err = -ENOMEM; ++ page = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!page)) ++ goto out; ++ ++ err = 0; ++ bend = au_sbend(sb); ++ for (bindex = 0; !err && bindex <= bend; bindex++) ++ if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) ++ err = do_xib_restore ++ (sb, au_sbr(sb, bindex)->br_xino.xi_file, page); ++ else ++ AuDbg("b%d\n", bindex); ++ free_page((unsigned long)page); ++ ++out: ++ return err; ++} ++ ++int au_xib_trunc(struct super_block *sb) ++{ ++ int err; ++ ssize_t sz; ++ loff_t pos; ++ struct au_xino_lock_dir ldir; ++ struct au_sbinfo *sbinfo; ++ unsigned long *p; ++ struct file *file; ++ ++ SiMustWriteLock(sb); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ if (!au_opt_test(sbinfo->si_mntflags, XINO)) ++ goto out; ++ ++ file = sbinfo->si_xib; ++ if (vfsub_f_size_read(file) <= PAGE_SIZE) ++ goto out; ++ ++ au_xino_lock_dir(sb, file, &ldir); ++ /* mnt_want_write() is unnecessary here */ ++ file = au_xino_create2(sbinfo->si_xib, NULL); ++ au_xino_unlock_dir(&ldir); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = file; ++ ++ p = sbinfo->si_xib_buf; ++ memset(p, 0, PAGE_SIZE); ++ pos = 0; ++ sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos); ++ if (unlikely(sz != PAGE_SIZE)) { ++ err = sz; ++ AuIOErr("err %d\n", err); ++ if (sz >= 0) ++ err = -EIO; ++ goto out; ++ } ++ ++ mutex_lock(&sbinfo->si_xib_mtx); ++ /* mnt_want_write() is unnecessary here */ ++ err = xib_restore(sb); ++ mutex_unlock(&sbinfo->si_xib_mtx); ++ ++out: ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * xino mount option handlers ++ */ ++static au_readf_t find_readf(struct file *h_file) ++{ ++ const struct file_operations *fop = h_file->f_op; ++ ++ if (fop->read) ++ return fop->read; ++ if (fop->aio_read) ++ return do_sync_read; ++ if (fop->read_iter) ++ return new_sync_read; ++ return ERR_PTR(-ENOSYS); ++} ++ ++static au_writef_t find_writef(struct file *h_file) ++{ ++ const struct file_operations *fop = h_file->f_op; ++ ++ if (fop->write) ++ return fop->write; ++ if (fop->aio_write) ++ return do_sync_write; ++ if (fop->write_iter) ++ return new_sync_write; ++ return ERR_PTR(-ENOSYS); ++} ++ ++/* xino bitmap */ ++static void xino_clear_xib(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++ if (sbinfo->si_xib) ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = NULL; ++ free_page((unsigned long)sbinfo->si_xib_buf); ++ sbinfo->si_xib_buf = NULL; ++} ++ ++static int au_xino_set_xib(struct super_block *sb, struct file *base) ++{ ++ int err; ++ loff_t pos; ++ struct au_sbinfo *sbinfo; ++ struct file *file; ++ ++ SiMustWriteLock(sb); ++ ++ sbinfo = au_sbi(sb); ++ file = au_xino_create2(base, sbinfo->si_xib); ++ err = PTR_ERR(file); ++ if (IS_ERR(file)) ++ goto out; ++ if (sbinfo->si_xib) ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = file; ++ sbinfo->si_xread = find_readf(file); ++ sbinfo->si_xwrite = find_writef(file); ++ ++ err = -ENOMEM; ++ if (!sbinfo->si_xib_buf) ++ sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS); ++ if (unlikely(!sbinfo->si_xib_buf)) ++ goto out_unset; ++ ++ sbinfo->si_xib_last_pindex = 0; ++ sbinfo->si_xib_next_bit = 0; ++ if (vfsub_f_size_read(file) < PAGE_SIZE) { ++ pos = 0; ++ err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf, ++ PAGE_SIZE, &pos); ++ if (unlikely(err != PAGE_SIZE)) ++ goto out_free; ++ } ++ err = 0; ++ goto out; /* success */ ++ ++out_free: ++ free_page((unsigned long)sbinfo->si_xib_buf); ++ sbinfo->si_xib_buf = NULL; ++ if (err >= 0) ++ err = -EIO; ++out_unset: ++ fput(sbinfo->si_xib); ++ sbinfo->si_xib = NULL; ++ sbinfo->si_xread = NULL; ++ sbinfo->si_xwrite = NULL; ++out: ++ return err; ++} ++ ++/* xino for each branch */ ++static void xino_clear_br(struct super_block *sb) ++{ ++ aufs_bindex_t bindex, bend; ++ struct au_branch *br; ++ ++ bend = au_sbend(sb); ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (!br || !br->br_xino.xi_file) ++ continue; ++ ++ fput(br->br_xino.xi_file); ++ br->br_xino.xi_file = NULL; ++ } ++} ++ ++static int au_xino_set_br(struct super_block *sb, struct file *base) ++{ ++ int err; ++ ino_t ino; ++ aufs_bindex_t bindex, bend, bshared; ++ struct { ++ struct file *old, *new; ++ } *fpair, *p; ++ struct au_branch *br; ++ struct inode *inode; ++ au_writef_t writef; ++ ++ SiMustWriteLock(sb); ++ ++ err = -ENOMEM; ++ bend = au_sbend(sb); ++ fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS); ++ if (unlikely(!fpair)) ++ goto out; ++ ++ inode = sb->s_root->d_inode; ++ ino = AUFS_ROOT_INO; ++ writef = au_sbi(sb)->si_xwrite; ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { ++ br = au_sbr(sb, bindex); ++ bshared = is_sb_shared(sb, bindex, bindex - 1); ++ if (bshared >= 0) { ++ /* shared xino */ ++ *p = fpair[bshared]; ++ get_file(p->new); ++ } ++ ++ if (!p->new) { ++ /* new xino */ ++ p->old = br->br_xino.xi_file; ++ p->new = au_xino_create2(base, br->br_xino.xi_file); ++ err = PTR_ERR(p->new); ++ if (IS_ERR(p->new)) { ++ p->new = NULL; ++ goto out_pair; ++ } ++ } ++ ++ err = au_xino_do_write(writef, p->new, ++ au_h_iptr(inode, bindex)->i_ino, ino); ++ if (unlikely(err)) ++ goto out_pair; ++ } ++ ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { ++ br = au_sbr(sb, bindex); ++ if (br->br_xino.xi_file) ++ fput(br->br_xino.xi_file); ++ get_file(p->new); ++ br->br_xino.xi_file = p->new; ++ } ++ ++out_pair: ++ for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) ++ if (p->new) ++ fput(p->new); ++ else ++ break; ++ kfree(fpair); ++out: ++ return err; ++} ++ ++void au_xino_clr(struct super_block *sb) ++{ ++ struct au_sbinfo *sbinfo; ++ ++ au_xigen_clr(sb); ++ xino_clear_xib(sb); ++ xino_clear_br(sb); ++ sbinfo = au_sbi(sb); ++ /* lvalue, do not call au_mntflags() */ ++ au_opt_clr(sbinfo->si_mntflags, XINO); ++} ++ ++int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount) ++{ ++ int err, skip; ++ struct dentry *parent, *cur_parent; ++ struct qstr *dname, *cur_name; ++ struct file *cur_xino; ++ struct inode *dir; ++ struct au_sbinfo *sbinfo; ++ ++ SiMustWriteLock(sb); ++ ++ err = 0; ++ sbinfo = au_sbi(sb); ++ parent = dget_parent(xino->file->f_path.dentry); ++ if (remount) { ++ skip = 0; ++ dname = &xino->file->f_path.dentry->d_name; ++ cur_xino = sbinfo->si_xib; ++ if (cur_xino) { ++ cur_parent = dget_parent(cur_xino->f_path.dentry); ++ cur_name = &cur_xino->f_path.dentry->d_name; ++ skip = (cur_parent == parent ++ && au_qstreq(dname, cur_name)); ++ dput(cur_parent); ++ } ++ if (skip) ++ goto out; ++ } ++ ++ au_opt_set(sbinfo->si_mntflags, XINO); ++ dir = parent->d_inode; ++ mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); ++ /* mnt_want_write() is unnecessary here */ ++ err = au_xino_set_xib(sb, xino->file); ++ if (!err) ++ err = au_xigen_set(sb, xino->file); ++ if (!err) ++ err = au_xino_set_br(sb, xino->file); ++ mutex_unlock(&dir->i_mutex); ++ if (!err) ++ goto out; /* success */ ++ ++ /* reset all */ ++ AuIOErr("failed creating xino(%d).\n", err); ++ au_xigen_clr(sb); ++ xino_clear_xib(sb); ++ ++out: ++ dput(parent); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ++ * create a xinofile at the default place/path. ++ */ ++struct file *au_xino_def(struct super_block *sb) ++{ ++ struct file *file; ++ char *page, *p; ++ struct au_branch *br; ++ struct super_block *h_sb; ++ struct path path; ++ aufs_bindex_t bend, bindex, bwr; ++ ++ br = NULL; ++ bend = au_sbend(sb); ++ bwr = -1; ++ for (bindex = 0; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (au_br_writable(br->br_perm) ++ && !au_test_fs_bad_xino(au_br_sb(br))) { ++ bwr = bindex; ++ break; ++ } ++ } ++ ++ if (bwr >= 0) { ++ file = ERR_PTR(-ENOMEM); ++ page = (void *)__get_free_page(GFP_NOFS); ++ if (unlikely(!page)) ++ goto out; ++ path.mnt = au_br_mnt(br); ++ path.dentry = au_h_dptr(sb->s_root, bwr); ++ p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME)); ++ file = (void *)p; ++ if (!IS_ERR(p)) { ++ strcat(p, "/" AUFS_XINO_FNAME); ++ AuDbg("%s\n", p); ++ file = au_xino_create(sb, p, /*silent*/0); ++ if (!IS_ERR(file)) ++ au_xino_brid_set(sb, br->br_id); ++ } ++ free_page((unsigned long)page); ++ } else { ++ file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); ++ if (IS_ERR(file)) ++ goto out; ++ h_sb = file->f_path.dentry->d_sb; ++ if (unlikely(au_test_fs_bad_xino(h_sb))) { ++ pr_err("xino doesn't support %s(%s)\n", ++ AUFS_XINO_DEFPATH, au_sbtype(h_sb)); ++ fput(file); ++ file = ERR_PTR(-EINVAL); ++ } ++ if (!IS_ERR(file)) ++ au_xino_brid_set(sb, -1); ++ } ++ ++out: ++ return file; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++int au_xino_path(struct seq_file *seq, struct file *file) ++{ ++ int err; ++ ++ err = au_seq_path(seq, &file->f_path); ++ if (unlikely(err < 0)) ++ goto out; ++ ++ err = 0; ++#define Deleted "\\040(deleted)" ++ seq->count -= sizeof(Deleted) - 1; ++ AuDebugOn(memcmp(seq->buf + seq->count, Deleted, ++ sizeof(Deleted) - 1)); ++#undef Deleted ++ ++out: ++ return err; ++} +diff --git a/fs/buffer.c b/fs/buffer.c +index 20805db..363569f 100644 +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -2450,7 +2450,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, + * Update file times before taking page lock. We may end up failing the + * fault so this update may be superfluous but who really cares... + */ +- file_update_time(vma->vm_file); ++ vma_file_update_time(vma); + + ret = __block_page_mkwrite(vma, vmf, get_block); + sb_end_pagefault(sb); +diff --git a/fs/dcache.c b/fs/dcache.c +index e368d4f..eaed72c 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1019,7 +1019,7 @@ enum d_walk_ret { + * + * The @enter() and @finish() callbacks are called with d_lock held. + */ +-static void d_walk(struct dentry *parent, void *data, ++void d_walk(struct dentry *parent, void *data, + enum d_walk_ret (*enter)(void *, struct dentry *), + void (*finish)(void *)) + { +diff --git a/fs/inode.c b/fs/inode.c +index aa149e7..98d87de 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1499,7 +1499,7 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode, + * This does the actual work of updating an inodes time or version. Must have + * had called mnt_want_write() before calling this. + */ +-static int update_time(struct inode *inode, struct timespec *time, int flags) ++int update_time(struct inode *inode, struct timespec *time, int flags) + { + if (inode->i_op->update_time) + return inode->i_op->update_time(inode, time, flags); +diff --git a/fs/proc/base.c b/fs/proc/base.c +index 3f3d7ae..426bcc7 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -1735,7 +1735,7 @@ static int proc_map_files_get_link(struct dentry *dentry, struct path *path) + down_read(&mm->mmap_sem); + vma = find_exact_vma(mm, vm_start, vm_end); + if (vma && vma->vm_file) { +- *path = vma->vm_file->f_path; ++ *path = vma_pr_or_file(vma)->f_path; + path_get(path); + rc = 0; + } +diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c +index d4a3574..1397181 100644 +--- a/fs/proc/nommu.c ++++ b/fs/proc/nommu.c +@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region) + file = region->vm_file; + + if (file) { +- struct inode *inode = file_inode(region->vm_file); ++ struct inode *inode; ++ ++ file = vmr_pr_or_file(region); ++ inode = file_inode(file); + dev = inode->i_sb->s_dev; + ino = inode->i_ino; + } +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index 246eae8..dfd0875 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -276,7 +276,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) + const char *name = NULL; + + if (file) { +- struct inode *inode = file_inode(vma->vm_file); ++ struct inode *inode; ++ ++ file = vma_pr_or_file(vma); ++ inode = file_inode(file); + dev = inode->i_sb->s_dev; + ino = inode->i_ino; + pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; +@@ -1475,7 +1478,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) + struct proc_maps_private *proc_priv = &numa_priv->proc_maps; + struct vm_area_struct *vma = v; + struct numa_maps *md = &numa_priv->md; +- struct file *file = vma->vm_file; ++ struct file *file = vma_pr_or_file(vma); + struct mm_struct *mm = vma->vm_mm; + struct mm_walk walk = {}; + struct mempolicy *pol; +diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c +index 599ec2e..de6cd6e 100644 +--- a/fs/proc/task_nommu.c ++++ b/fs/proc/task_nommu.c +@@ -160,7 +160,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma, + file = vma->vm_file; + + if (file) { +- struct inode *inode = file_inode(vma->vm_file); ++ struct inode *inode; ++ ++ file = vma_pr_or_file(file); ++ inode = file_inode(file); + dev = inode->i_sb->s_dev; + ino = inode->i_ino; + pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; +diff --git a/fs/splice.c b/fs/splice.c +index 75c6058..619359a 100644 +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -1114,8 +1114,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); + /* + * Attempt to initiate a splice from pipe to file. + */ +-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +- loff_t *ppos, size_t len, unsigned int flags) ++long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) + { + ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, + loff_t *, size_t, unsigned int); +@@ -1131,9 +1131,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + /* + * Attempt to initiate a splice from a file to a pipe. + */ +-static long do_splice_to(struct file *in, loff_t *ppos, +- struct pipe_inode_info *pipe, size_t len, +- unsigned int flags) ++long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) + { + ssize_t (*splice_read)(struct file *, loff_t *, + struct pipe_inode_info *, size_t, unsigned int); +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 42efe13..f634198 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -2690,6 +2690,7 @@ extern int inode_change_ok(const struct inode *, struct iattr *); + extern int inode_newsize_ok(const struct inode *, loff_t offset); + extern void setattr_copy(struct inode *inode, const struct iattr *attr); + ++extern int update_time(struct inode *, struct timespec *, int); + extern int file_update_time(struct file *file); + + extern int generic_show_options(struct seq_file *m, struct dentry *root); +diff --git a/include/linux/mm.h b/include/linux/mm.h +index dd5ea30..445d798 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1224,6 +1224,28 @@ static inline int fixup_user_fault(struct task_struct *tsk, + } + #endif + ++#ifdef CONFIG_MMU ++extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int); ++extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[], ++ int); ++extern void vma_do_get_file(struct vm_area_struct *, const char[], int); ++extern void vma_do_fput(struct vm_area_struct *, const char[], int); ++ ++#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \ ++ __LINE__) ++#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \ ++ __LINE__) ++#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__) ++#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__) ++#else ++extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int); ++extern void vmr_do_fput(struct vm_region *, const char[], int); ++ ++#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \ ++ __LINE__) ++#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__) ++#endif /* CONFIG_MMU */ ++ + extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); + extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, + void *buf, int len, int write); +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index 6d34aa2..f13dd51 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -233,6 +233,7 @@ struct vm_region { + unsigned long vm_top; /* region allocated to here */ + unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ + struct file *vm_file; /* the backing file or NULL */ ++ struct file *vm_prfile; /* the virtual backing file or NULL */ + + int vm_usage; /* region usage count (access under nommu_region_sem) */ + bool vm_icache_flushed : 1; /* true if the icache has been flushed for +@@ -301,6 +302,7 @@ struct vm_area_struct { + unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE + units, *not* PAGE_CACHE_SIZE */ + struct file * vm_file; /* File we map to (can be NULL). */ ++ struct file *vm_prfile; /* shadow of vm_file */ + void * vm_private_data; /* was vm_pte (shared mem) */ + + #ifndef CONFIG_MMU +diff --git a/include/linux/splice.h b/include/linux/splice.h +index da2751d..2e0fca6 100644 +--- a/include/linux/splice.h ++++ b/include/linux/splice.h +@@ -83,4 +83,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); + extern void spd_release_page(struct splice_pipe_desc *, unsigned int); + + extern const struct pipe_buf_operations page_cache_pipe_buf_ops; ++ ++extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++extern long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); + #endif +diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild +index 00b10002..f4a389c 100644 +--- a/include/uapi/linux/Kbuild ++++ b/include/uapi/linux/Kbuild +@@ -57,6 +57,7 @@ header-y += atmsvc.h + header-y += atm_tcp.h + header-y += atm_zatm.h + header-y += audit.h ++header-y += aufs_type.h + header-y += auto_fs4.h + header-y += auto_fs.h + header-y += auxvec.h +diff --git a/include/uapi/linux/aufs_type.h b/include/uapi/linux/aufs_type.h +new file mode 100644 +index 0000000..d6abed8 +--- /dev/null ++++ b/include/uapi/linux/aufs_type.h +@@ -0,0 +1,406 @@ ++/* ++ * Copyright (C) 2005-2015 Junjiro R. Okajima ++ */ ++ ++#ifndef __AUFS_TYPE_H__ ++#define __AUFS_TYPE_H__ ++ ++#define AUFS_NAME "aufs" ++ ++#ifdef __KERNEL__ ++/* ++ * define it before including all other headers. ++ * sched.h may use pr_* macros before defining "current", so define the ++ * no-current version first, and re-define later. ++ */ ++#define pr_fmt(fmt) AUFS_NAME " %s:%d: " fmt, __func__, __LINE__ ++#include ++#undef pr_fmt ++#define pr_fmt(fmt) \ ++ AUFS_NAME " %s:%d:%.*s[%d]: " fmt, __func__, __LINE__, \ ++ (int)sizeof(current->comm), current->comm, current->pid ++#else ++#include ++#include ++#endif /* __KERNEL__ */ ++ ++#include ++ ++#define AUFS_VERSION "3.19" ++ ++/* todo? move this to linux-2.6.19/include/magic.h */ ++#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') ++ ++/* ---------------------------------------------------------------------- */ ++ ++#ifdef CONFIG_AUFS_BRANCH_MAX_127 ++typedef int8_t aufs_bindex_t; ++#define AUFS_BRANCH_MAX 127 ++#else ++typedef int16_t aufs_bindex_t; ++#ifdef CONFIG_AUFS_BRANCH_MAX_511 ++#define AUFS_BRANCH_MAX 511 ++#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) ++#define AUFS_BRANCH_MAX 1023 ++#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) ++#define AUFS_BRANCH_MAX 32767 ++#endif ++#endif ++ ++#ifdef __KERNEL__ ++#ifndef AUFS_BRANCH_MAX ++#error unknown CONFIG_AUFS_BRANCH_MAX value ++#endif ++#endif /* __KERNEL__ */ ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AUFS_FSTYPE AUFS_NAME ++ ++#define AUFS_ROOT_INO 2 ++#define AUFS_FIRST_INO 11 ++ ++#define AUFS_WH_PFX ".wh." ++#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) ++#define AUFS_WH_TMP_LEN 4 ++/* a limit for rmdir/rename a dir and copyup */ ++#define AUFS_MAX_NAMELEN (NAME_MAX \ ++ - AUFS_WH_PFX_LEN * 2 /* doubly whiteouted */\ ++ - 1 /* dot */\ ++ - AUFS_WH_TMP_LEN) /* hex */ ++#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" ++#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME ++#define AUFS_XINO_DEF_SEC 30 /* seconds */ ++#define AUFS_XINO_DEF_TRUNC 45 /* percentage */ ++#define AUFS_DIRWH_DEF 3 ++#define AUFS_RDCACHE_DEF 10 /* seconds */ ++#define AUFS_RDCACHE_MAX 3600 /* seconds */ ++#define AUFS_RDBLK_DEF 512 /* bytes */ ++#define AUFS_RDHASH_DEF 32 ++#define AUFS_WKQ_NAME AUFS_NAME "d" ++#define AUFS_MFS_DEF_SEC 30 /* seconds */ ++#define AUFS_MFS_MAX_SEC 3600 /* seconds */ ++#define AUFS_FHSM_CACHE_DEF_SEC 30 /* seconds */ ++#define AUFS_PLINK_WARN 50 /* number of plinks in a single bucket */ ++ ++/* pseudo-link maintenace under /proc */ ++#define AUFS_PLINK_MAINT_NAME "plink_maint" ++#define AUFS_PLINK_MAINT_DIR "fs/" AUFS_NAME ++#define AUFS_PLINK_MAINT_PATH AUFS_PLINK_MAINT_DIR "/" AUFS_PLINK_MAINT_NAME ++ ++#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ ++#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME ++ ++#define AUFS_BASE_NAME AUFS_WH_PFX AUFS_NAME ++#define AUFS_PLINKDIR_NAME AUFS_WH_PFX "plnk" ++#define AUFS_ORPHDIR_NAME AUFS_WH_PFX "orph" ++ ++/* doubly whiteouted */ ++#define AUFS_WH_BASE AUFS_WH_PFX AUFS_BASE_NAME ++#define AUFS_WH_PLINKDIR AUFS_WH_PFX AUFS_PLINKDIR_NAME ++#define AUFS_WH_ORPHDIR AUFS_WH_PFX AUFS_ORPHDIR_NAME ++ ++/* branch permissions and attributes */ ++#define AUFS_BRPERM_RW "rw" ++#define AUFS_BRPERM_RO "ro" ++#define AUFS_BRPERM_RR "rr" ++#define AUFS_BRATTR_COO_REG "coo_reg" ++#define AUFS_BRATTR_COO_ALL "coo_all" ++#define AUFS_BRATTR_FHSM "fhsm" ++#define AUFS_BRATTR_UNPIN "unpin" ++#define AUFS_BRATTR_ICEX "icex" ++#define AUFS_BRATTR_ICEX_SEC "icexsec" ++#define AUFS_BRATTR_ICEX_SYS "icexsys" ++#define AUFS_BRATTR_ICEX_TR "icextr" ++#define AUFS_BRATTR_ICEX_USR "icexusr" ++#define AUFS_BRATTR_ICEX_OTH "icexoth" ++#define AUFS_BRRATTR_WH "wh" ++#define AUFS_BRWATTR_NLWH "nolwh" ++#define AUFS_BRWATTR_MOO "moo" ++ ++#define AuBrPerm_RW 1 /* writable, hardlinkable wh */ ++#define AuBrPerm_RO (1 << 1) /* readonly */ ++#define AuBrPerm_RR (1 << 2) /* natively readonly */ ++#define AuBrPerm_Mask (AuBrPerm_RW | AuBrPerm_RO | AuBrPerm_RR) ++ ++#define AuBrAttr_COO_REG (1 << 3) /* copy-up on open */ ++#define AuBrAttr_COO_ALL (1 << 4) ++#define AuBrAttr_COO_Mask (AuBrAttr_COO_REG | AuBrAttr_COO_ALL) ++ ++#define AuBrAttr_FHSM (1 << 5) /* file-based hsm */ ++#define AuBrAttr_UNPIN (1 << 6) /* rename-able top dir of ++ branch. meaningless since ++ linux-3.18-rc1 */ ++ ++/* ignore error in copying XATTR */ ++#define AuBrAttr_ICEX_SEC (1 << 7) ++#define AuBrAttr_ICEX_SYS (1 << 8) ++#define AuBrAttr_ICEX_TR (1 << 9) ++#define AuBrAttr_ICEX_USR (1 << 10) ++#define AuBrAttr_ICEX_OTH (1 << 11) ++#define AuBrAttr_ICEX (AuBrAttr_ICEX_SEC \ ++ | AuBrAttr_ICEX_SYS \ ++ | AuBrAttr_ICEX_TR \ ++ | AuBrAttr_ICEX_USR \ ++ | AuBrAttr_ICEX_OTH) ++ ++#define AuBrRAttr_WH (1 << 12) /* whiteout-able */ ++#define AuBrRAttr_Mask AuBrRAttr_WH ++ ++#define AuBrWAttr_NoLinkWH (1 << 13) /* un-hardlinkable whiteouts */ ++#define AuBrWAttr_MOO (1 << 14) /* move-up on open */ ++#define AuBrWAttr_Mask (AuBrWAttr_NoLinkWH | AuBrWAttr_MOO) ++ ++#define AuBrAttr_CMOO_Mask (AuBrAttr_COO_Mask | AuBrWAttr_MOO) ++ ++/* #warning test userspace */ ++#ifdef __KERNEL__ ++#ifndef CONFIG_AUFS_FHSM ++#undef AuBrAttr_FHSM ++#define AuBrAttr_FHSM 0 ++#endif ++#ifndef CONFIG_AUFS_XATTR ++#undef AuBrAttr_ICEX ++#define AuBrAttr_ICEX 0 ++#undef AuBrAttr_ICEX_SEC ++#define AuBrAttr_ICEX_SEC 0 ++#undef AuBrAttr_ICEX_SYS ++#define AuBrAttr_ICEX_SYS 0 ++#undef AuBrAttr_ICEX_TR ++#define AuBrAttr_ICEX_TR 0 ++#undef AuBrAttr_ICEX_USR ++#define AuBrAttr_ICEX_USR 0 ++#undef AuBrAttr_ICEX_OTH ++#define AuBrAttr_ICEX_OTH 0 ++#endif ++#endif ++ ++/* the longest combination */ ++/* AUFS_BRATTR_ICEX and AUFS_BRATTR_ICEX_TR don't affect here */ ++#define AuBrPermStrSz sizeof(AUFS_BRPERM_RW \ ++ "+" AUFS_BRATTR_COO_REG \ ++ "+" AUFS_BRATTR_FHSM \ ++ "+" AUFS_BRATTR_UNPIN \ ++ "+" AUFS_BRATTR_ICEX_SEC \ ++ "+" AUFS_BRATTR_ICEX_SYS \ ++ "+" AUFS_BRATTR_ICEX_USR \ ++ "+" AUFS_BRATTR_ICEX_OTH \ ++ "+" AUFS_BRWATTR_NLWH) ++ ++typedef struct { ++ char a[AuBrPermStrSz]; ++} au_br_perm_str_t; ++ ++static inline int au_br_writable(int brperm) ++{ ++ return brperm & AuBrPerm_RW; ++} ++ ++static inline int au_br_whable(int brperm) ++{ ++ return brperm & (AuBrPerm_RW | AuBrRAttr_WH); ++} ++ ++static inline int au_br_wh_linkable(int brperm) ++{ ++ return !(brperm & AuBrWAttr_NoLinkWH); ++} ++ ++static inline int au_br_cmoo(int brperm) ++{ ++ return brperm & AuBrAttr_CMOO_Mask; ++} ++ ++static inline int au_br_fhsm(int brperm) ++{ ++ return brperm & AuBrAttr_FHSM; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* ioctl */ ++enum { ++ /* readdir in userspace */ ++ AuCtl_RDU, ++ AuCtl_RDU_INO, ++ ++ AuCtl_WBR_FD, /* pathconf wrapper */ ++ AuCtl_IBUSY, /* busy inode */ ++ AuCtl_MVDOWN, /* move-down */ ++ AuCtl_BR, /* info about branches */ ++ AuCtl_FHSM_FD /* connection for fhsm */ ++}; ++ ++/* borrowed from linux/include/linux/kernel.h */ ++#ifndef ALIGN ++#define ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a)-1) ++#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) ++#endif ++ ++/* borrowed from linux/include/linux/compiler-gcc3.h */ ++#ifndef __aligned ++#define __aligned(x) __attribute__((aligned(x))) ++#endif ++ ++#ifdef __KERNEL__ ++#ifndef __packed ++#define __packed __attribute__((packed)) ++#endif ++#endif ++ ++struct au_rdu_cookie { ++ uint64_t h_pos; ++ int16_t bindex; ++ uint8_t flags; ++ uint8_t pad; ++ uint32_t generation; ++} __aligned(8); ++ ++struct au_rdu_ent { ++ uint64_t ino; ++ int16_t bindex; ++ uint8_t type; ++ uint8_t nlen; ++ uint8_t wh; ++ char name[0]; ++} __aligned(8); ++ ++static inline int au_rdu_len(int nlen) ++{ ++ /* include the terminating NULL */ ++ return ALIGN(sizeof(struct au_rdu_ent) + nlen + 1, ++ sizeof(uint64_t)); ++} ++ ++union au_rdu_ent_ul { ++ struct au_rdu_ent __user *e; ++ uint64_t ul; ++}; ++ ++enum { ++ AufsCtlRduV_SZ, ++ AufsCtlRduV_End ++}; ++ ++struct aufs_rdu { ++ /* input */ ++ union { ++ uint64_t sz; /* AuCtl_RDU */ ++ uint64_t nent; /* AuCtl_RDU_INO */ ++ }; ++ union au_rdu_ent_ul ent; ++ uint16_t verify[AufsCtlRduV_End]; ++ ++ /* input/output */ ++ uint32_t blk; ++ ++ /* output */ ++ union au_rdu_ent_ul tail; ++ /* number of entries which were added in a single call */ ++ uint64_t rent; ++ uint8_t full; ++ uint8_t shwh; ++ ++ struct au_rdu_cookie cookie; ++} __aligned(8); ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct aufs_wbr_fd { ++ uint32_t oflags; ++ int16_t brid; ++} __aligned(8); ++ ++/* ---------------------------------------------------------------------- */ ++ ++struct aufs_ibusy { ++ uint64_t ino, h_ino; ++ int16_t bindex; ++} __aligned(8); ++ ++/* ---------------------------------------------------------------------- */ ++ ++/* error code for move-down */ ++/* the actual message strings are implemented in aufs-util.git */ ++enum { ++ EAU_MVDOWN_OPAQUE = 1, ++ EAU_MVDOWN_WHITEOUT, ++ EAU_MVDOWN_UPPER, ++ EAU_MVDOWN_BOTTOM, ++ EAU_MVDOWN_NOUPPER, ++ EAU_MVDOWN_NOLOWERBR, ++ EAU_Last ++}; ++ ++/* flags for move-down */ ++#define AUFS_MVDOWN_DMSG 1 ++#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */ ++#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */ ++#define AUFS_MVDOWN_ROLOWER (1 << 3) /* do even if lower is RO */ ++#define AUFS_MVDOWN_ROLOWER_R (1 << 4) /* did on lower RO */ ++#define AUFS_MVDOWN_ROUPPER (1 << 5) /* do even if upper is RO */ ++#define AUFS_MVDOWN_ROUPPER_R (1 << 6) /* did on upper RO */ ++#define AUFS_MVDOWN_BRID_UPPER (1 << 7) /* upper brid */ ++#define AUFS_MVDOWN_BRID_LOWER (1 << 8) /* lower brid */ ++#define AUFS_MVDOWN_FHSM_LOWER (1 << 9) /* find fhsm attr for lower */ ++#define AUFS_MVDOWN_STFS (1 << 10) /* req. stfs */ ++#define AUFS_MVDOWN_STFS_FAILED (1 << 11) /* output: stfs is unusable */ ++#define AUFS_MVDOWN_BOTTOM (1 << 12) /* output: no more lowers */ ++ ++/* index for move-down */ ++enum { ++ AUFS_MVDOWN_UPPER, ++ AUFS_MVDOWN_LOWER, ++ AUFS_MVDOWN_NARRAY ++}; ++ ++/* ++ * additional info of move-down ++ * number of free blocks and inodes. ++ * subset of struct kstatfs, but smaller and always 64bit. ++ */ ++struct aufs_stfs { ++ uint64_t f_blocks; ++ uint64_t f_bavail; ++ uint64_t f_files; ++ uint64_t f_ffree; ++}; ++ ++struct aufs_stbr { ++ int16_t brid; /* optional input */ ++ int16_t bindex; /* output */ ++ struct aufs_stfs stfs; /* output when AUFS_MVDOWN_STFS set */ ++} __aligned(8); ++ ++struct aufs_mvdown { ++ uint32_t flags; /* input/output */ ++ struct aufs_stbr stbr[AUFS_MVDOWN_NARRAY]; /* input/output */ ++ int8_t au_errno; /* output */ ++} __aligned(8); ++ ++/* ---------------------------------------------------------------------- */ ++ ++union aufs_brinfo { ++ /* PATH_MAX may differ between kernel-space and user-space */ ++ char _spacer[4096]; ++ struct { ++ int16_t id; ++ int perm; ++ char path[0]; ++ }; ++} __aligned(8); ++ ++/* ---------------------------------------------------------------------- */ ++ ++#define AuCtlType 'A' ++#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu) ++#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu) ++#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \ ++ struct aufs_wbr_fd) ++#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy) ++#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \ ++ struct aufs_mvdown) ++#define AUFS_CTL_BRINFO _IOW(AuCtlType, AuCtl_BR, union aufs_brinfo) ++#define AUFS_CTL_FHSM_FD _IOW(AuCtlType, AuCtl_FHSM_FD, int) ++ ++#endif /* __AUFS_TYPE_H__ */ +diff --git a/kernel/fork.c b/kernel/fork.c +index 4dc2dda..5984c61 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -430,7 +430,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) + struct inode *inode = file_inode(file); + struct address_space *mapping = file->f_mapping; + +- get_file(file); ++ vma_get_file(tmp); + if (tmp->vm_flags & VM_DENYWRITE) + atomic_dec(&inode->i_writecount); + i_mmap_lock_write(mapping); +diff --git a/mm/Makefile b/mm/Makefile +index 4bf586e..59bd276 100644 +--- a/mm/Makefile ++++ b/mm/Makefile +@@ -18,7 +18,7 @@ obj-y := filemap.o mempool.o oom_kill.o \ + mm_init.o mmu_context.o percpu.o slab_common.o \ + compaction.o vmacache.o \ + interval_tree.o list_lru.o workingset.o \ +- iov_iter.o debug.o $(mmu-y) ++ iov_iter.o prfile.o debug.o $(mmu-y) + + obj-y += init-mm.o + +diff --git a/mm/filemap.c b/mm/filemap.c +index 673e458..a623932 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -2063,7 +2063,7 @@ int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) + int ret = VM_FAULT_LOCKED; + + sb_start_pagefault(inode->i_sb); +- file_update_time(vma->vm_file); ++ vma_file_update_time(vma); + lock_page(page); + if (page->mapping != inode->i_mapping) { + unlock_page(page); +diff --git a/mm/fremap.c b/mm/fremap.c +index 2805d71..1b011b0 100644 +--- a/mm/fremap.c ++++ b/mm/fremap.c +@@ -224,16 +224,28 @@ get_write_lock: + */ + if (mapping_cap_account_dirty(mapping)) { + unsigned long addr; +- struct file *file = get_file(vma->vm_file); ++ struct file *file = vma->vm_file, ++ *prfile = vma->vm_prfile; ++ + /* mmap_region may free vma; grab the info now */ + vm_flags = vma->vm_flags; + ++ vma_get_file(vma); + addr = mmap_region(file, start, size, vm_flags, pgoff); +- fput(file); ++ vma_fput(vma); + if (IS_ERR_VALUE(addr)) { + err = addr; + } else { + BUG_ON(addr != start); ++ if (prfile) { ++ struct vm_area_struct *new_vma; ++ ++ new_vma = find_vma(mm, addr); ++ if (!new_vma->vm_prfile) ++ new_vma->vm_prfile = prfile; ++ if (new_vma != vma) ++ get_file(prfile); ++ } + err = 0; + } + goto out_freed; +diff --git a/mm/madvise.c b/mm/madvise.c +index a271adc..29a932f 100644 +--- a/mm/madvise.c ++++ b/mm/madvise.c +@@ -324,12 +324,12 @@ static long madvise_remove(struct vm_area_struct *vma, + * vma's reference to the file) can go away as soon as we drop + * mmap_sem. + */ +- get_file(f); ++ vma_get_file(vma); + up_read(¤t->mm->mmap_sem); + error = vfs_fallocate(f, + FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + offset, end - start); +- fput(f); ++ vma_fput(vma); + down_read(¤t->mm->mmap_sem); + return error; + } +diff --git a/mm/memory.c b/mm/memory.c +index 2c3536c..444bb1d 100644 +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -2157,7 +2157,7 @@ reuse: + + /* file_update_time outside page_lock */ + if (vma->vm_file) +- file_update_time(vma->vm_file); ++ vma_file_update_time(vma); + } + put_page(dirty_page); + if (page_mkwrite) { +diff --git a/mm/mmap.c b/mm/mmap.c +index 7f684d5..ffa1b91 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -277,7 +277,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + mpol_put(vma_policy(vma)); + kmem_cache_free(vm_area_cachep, vma); + return next; +@@ -897,7 +897,7 @@ again: remove_next = 1 + (end > next->vm_end); + if (remove_next) { + if (file) { + uprobe_munmap(next, next->vm_start, next->vm_end); +- fput(file); ++ vma_fput(vma); + } + if (next->anon_vma) + anon_vma_merge(vma, next); +@@ -1682,8 +1682,8 @@ out: + return addr; + + unmap_and_free_vma: ++ vma_fput(vma); + vma->vm_file = NULL; +- fput(file); + + /* Undo any partial mapping done by a device driver. */ + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); +@@ -2484,7 +2484,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, + goto out_free_mpol; + + if (new->vm_file) +- get_file(new->vm_file); ++ vma_get_file(new); + + if (new->vm_ops && new->vm_ops->open) + new->vm_ops->open(new); +@@ -2503,7 +2503,7 @@ static int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, + if (new->vm_ops && new->vm_ops->close) + new->vm_ops->close(new); + if (new->vm_file) +- fput(new->vm_file); ++ vma_fput(new); + unlink_anon_vmas(new); + out_free_mpol: + mpol_put(vma_policy(new)); +@@ -2895,7 +2895,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, + if (anon_vma_clone(new_vma, vma)) + goto out_free_mempol; + if (new_vma->vm_file) +- get_file(new_vma->vm_file); ++ vma_get_file(new_vma); + if (new_vma->vm_ops && new_vma->vm_ops->open) + new_vma->vm_ops->open(new_vma); + vma_link(mm, new_vma, prev, rb_link, rb_parent); +diff --git a/mm/msync.c b/mm/msync.c +index 992a167..ce1915b 100644 +--- a/mm/msync.c ++++ b/mm/msync.c +@@ -84,13 +84,13 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) + start = vma->vm_end; + if ((flags & MS_SYNC) && file && + (vma->vm_flags & VM_SHARED)) { +- get_file(file); ++ vma_get_file(vma); + up_read(&mm->mmap_sem); + if (vma->vm_flags & VM_NONLINEAR) + error = vfs_fsync(file, 1); + else + error = vfs_fsync_range(file, fstart, fend, 1); +- fput(file); ++ vma_fput(vma); + if (error || start >= end) + goto out; + down_read(&mm->mmap_sem); +diff --git a/mm/nommu.c b/mm/nommu.c +index 28bd8c4..3c0ace2 100644 +--- a/mm/nommu.c ++++ b/mm/nommu.c +@@ -659,7 +659,7 @@ static void __put_nommu_region(struct vm_region *region) + up_write(&nommu_region_sem); + + if (region->vm_file) +- fput(region->vm_file); ++ vmr_fput(region); + + /* IO memory and memory shared directly out of the pagecache + * from ramfs/tmpfs mustn't be released here */ +@@ -824,7 +824,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma) + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + put_nommu_region(vma->vm_region); + kmem_cache_free(vm_area_cachep, vma); + } +@@ -1375,7 +1375,7 @@ unsigned long do_mmap_pgoff(struct file *file, + goto error_just_free; + } + } +- fput(region->vm_file); ++ vmr_fput(region); + kmem_cache_free(vm_region_jar, region); + region = pregion; + result = start; +@@ -1451,10 +1451,10 @@ error_just_free: + up_write(&nommu_region_sem); + error: + if (region->vm_file) +- fput(region->vm_file); ++ vmr_fput(region); + kmem_cache_free(vm_region_jar, region); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + kmem_cache_free(vm_area_cachep, vma); + kleave(" = %d", ret); + return ret; +diff --git a/mm/prfile.c b/mm/prfile.c +new file mode 100644 +index 0000000..fc708d2 +--- /dev/null ++++ b/mm/prfile.c +@@ -0,0 +1,86 @@ ++/* ++ * Mainly for aufs which mmap(2) diffrent file and wants to print different path ++ * in /proc/PID/maps. ++ * Call these functions via macros defined in linux/mm.h. ++ * ++ * See Documentation/filesystems/aufs/design/06mmap.txt ++ * ++ * Copyright (c) 2014 Junjro R. Okajima ++ * Copyright (c) 2014 Ian Campbell ++ */ ++ ++#include ++#include ++#include ++ ++/* #define PRFILE_TRACE */ ++static inline void prfile_trace(struct file *f, struct file *pr, ++ const char func[], int line, const char func2[]) ++{ ++#ifdef PRFILE_TRACE ++ if (pr) ++ pr_info("%s:%d: %s, %p\n", func, line, func2, ++ f ? (char *)f->f_dentry->d_name.name : "(null)"); ++#endif ++} ++ ++#ifdef CONFIG_MMU ++void vma_do_file_update_time(struct vm_area_struct *vma, const char func[], ++ int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ file_update_time(f); ++ if (f && pr) ++ file_update_time(pr); ++} ++ ++struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[], ++ int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ return (f && pr) ? pr : f; ++} ++ ++void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ get_file(f); ++ if (f && pr) ++ get_file(pr); ++} ++ ++void vma_do_fput(struct vm_area_struct *vma, const char func[], int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ fput(f); ++ if (f && pr) ++ fput(pr); ++} ++#else ++struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[], ++ int line) ++{ ++ struct file *f = region->vm_file, *pr = region->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ return (f && pr) ? pr : f; ++} ++ ++void vmr_do_fput(struct vm_region *region, const char func[], int line) ++{ ++ struct file *f = region->vm_file, *pr = region->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ fput(f); ++ if (f && pr) ++ fput(pr); ++} ++#endif /* CONFIG_MMU */ diff --git a/kernel/kernel/files/patches/mageia/fs-btrfs-fix-BUG_ON-in-btrfs_orphan_add-when-delete-unu.patch b/kernel/kernel/files/patches/mageia/fs-btrfs-fix-BUG_ON-in-btrfs_orphan_add-when-delete-unu.patch new file mode 100644 index 00000000..31d25c9c --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-btrfs-fix-BUG_ON-in-btrfs_orphan_add-when-delete-unu.patch @@ -0,0 +1,96 @@ +From 3d84be799194147e04c0e3129ed44a948773b80a Mon Sep 17 00:00:00 2001 +From: Forrest Liu +Date: Wed, 11 Feb 2015 14:23:47 +0800 +Subject: [PATCH] Btrfs: fix BUG_ON in btrfs_orphan_add() when delete unused + block group + +Removing large amount of block group in a transaction may encounters +BUG_ON() in btrfs_orphan_add(). That is because btrfs_orphan_reserve_metadata() +will grab metadata reservation from transaction handle, and +btrfs_delete_unused_bgs() didn't reserve metadata for trnasaction handle when +delete unused block group. + +The problem can be reproduce by following script + + mntpath=/btrfs + loopdev=/dev/loop0 + filepath=/home/forrest/image + + umount $mntpath + losetup -d $loopdev + truncate --size 1000g $filepath + losetup $loopdev $filepath + mkfs.btrfs -f $loopdev + mount $loopdev $mntpath + + for j in `seq 1 1 1000`; do + fallocate -l 1g $mntpath/$j + done + # wait cleaner thread remove unused block group + sleep 300 + +The call trace that results from the BUG_ON() is: + +[ 613.093084] ------------[ cut here ]------------ +[ 613.097928] kernel BUG at fs/btrfs/inode.c:3142! +[ 613.105855] invalid opcode: 0000 [#1] SMP +[ 613.112702] Modules linked in: coretemp(E) crc32_pclmul(E) ghash_clmulni_intel(E) aesni_intel(E) snd_ens1371(E) snd_ac97_codec(E) aes_x86_64(E) lrw(E) gf128mul(E) glue_helper(E) ppdev(E) ac97_bus(E) ablk_helper(E) gameport(E) cryptd(E) snd_rawmidi(E) snd_seq_device(E) snd_pcm(E) vmw_balloon(E) snd_timer(E) snd(E) soundcore(E) serio_raw(E) vmwgfx(E) ttm(E) drm_kms_helper(E) drm(E) vmw_vmci(E) parport_pc(E) shpchp(E) i2c_piix4(E) mac_hid(E) lp(E) parport(E) btrfs(E) xor(E) raid6_pq(E) hid_generic(E) usbhid(E) hid(E) psmouse(E) ahci(E) libahci(E) e1000(E) mptspi(E) mptscsih(E) mptbase(E) floppy(E) vmw_pvscsi(E) vmxnet3(E) +[ 613.144196] CPU: 0 PID: 1480 Comm: btrfs-cleaner Tainted: G E 3.19.0-rc7-custom #2 +[ 613.148501] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013 +[ 613.152694] task: ffff880035cdb1a0 ti: ffff880039cf4000 task.ti: ffff880039cf4000 +[ 613.154969] RIP: 0010:[] [] btrfs_orphan_add+0x1d2/0x1e0 [btrfs] +[ 613.157780] RSP: 0018:ffff880039cf7c48 EFLAGS: 00010286 +[ 613.159560] RAX: 00000000ffffffe4 RBX: ffff88003bd981a0 RCX: ffff88003c9e4000 +[ 613.161904] RDX: 0000000000002244 RSI: 0000000000040000 RDI: ffff88003c9e4138 +[ 613.164264] RBP: ffff880039cf7c88 R08: 000060ffc0000850 R09: 0000000000000000 +[ 613.166507] R10: ffff88003bc4b7a0 R11: ffffea0000eb6740 R12: ffff88003c9c0000 +[ 613.168681] R13: ffff88003c102160 R14: ffff88003c9c0458 R15: 0000000000000001 +[ 613.170932] FS: 0000000000000000(0000) GS:ffff88003f600000(0000) knlGS:0000000000000000 +[ 613.173316] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 613.175227] CR2: 00007f6343537000 CR3: 0000000036329000 CR4: 00000000000407f0 +[ 613.177554] Stack: +[ 613.178712] ffff880039cf7c88 ffffffffa0182a54 ffff88003c9e4b04 ffff88003c9c7800 +[ 613.181297] ffff88003bc4b7a0 ffff88003bd981a0 ffff88003c8db200 ffff88003c2fcc60 +[ 613.183782] ffff880039cf7d18 ffffffffa012da97 ffff88003bc4b7a4 ffff88003bc4b7a0 +[ 613.186171] Call Trace: +[ 613.187493] [] ? lookup_free_space_inode+0x44/0x100 [btrfs] +[ 613.189801] [] btrfs_remove_block_group+0x137/0x740 [btrfs] +[ 613.192126] [] btrfs_remove_chunk+0x672/0x780 [btrfs] +[ 613.194267] [] btrfs_delete_unused_bgs+0x25f/0x280 [btrfs] +[ 613.196567] [] cleaner_kthread+0x12c/0x190 [btrfs] +[ 613.198687] [] ? check_leaf+0x350/0x350 [btrfs] +[ 613.200758] [] kthread+0xd2/0xf0 +[ 613.202616] [] ? kthread_create_on_node+0x180/0x180 +[ 613.204738] [] ret_from_fork+0x7c/0xb0 +[ 613.206652] [] ? kthread_create_on_node+0x180/0x180 +[ 613.208741] Code: ff ff 0f 1f 80 00 00 00 00 89 45 c8 3e 80 63 80 fd 48 89 df e8 d0 23 fe ff 8b 45 c8 e9 14 ff ff ff b8 f4 ff ff ff e9 12 ff ff ff <0f> 0b 66 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 +[ 613.216562] RIP [] btrfs_orphan_add+0x1d2/0x1e0 [btrfs] +[ 613.218828] RSP +[ 613.220382] ---[ end trace 71073106deb8a457 ]--- + +This patch replace btrfs_join_transaction() with btrfs_start_transaction() in +btrfs_delete_unused_bgs() to revent BUG_ON() in btrfs_orphan_add() + +Signed-off-by: Forrest Liu +Signed-off-by: Chris Mason +--- + fs/btrfs/extent-tree.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c +index 0f67370..28ce5c8 100644 +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -9555,7 +9555,8 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) + * Want to do this before we do anything else so we can recover + * properly if we fail to join the transaction. + */ +- trans = btrfs_join_transaction(root); ++ /* 1 for btrfs_orphan_reserve_metadata() */ ++ trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + btrfs_set_block_group_rw(root, block_group); + ret = PTR_ERR(trans); +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/fs-btrfs-unlock-i_mutex-after-attempting-to-delete-subvolume-during-send.patch b/kernel/kernel/files/patches/mageia/fs-btrfs-unlock-i_mutex-after-attempting-to-delete-subvolume-during-send.patch new file mode 100644 index 00000000..92cb2cd6 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-btrfs-unlock-i_mutex-after-attempting-to-delete-subvolume-during-send.patch @@ -0,0 +1,53 @@ +From 909e26dce3f7600f5e293ac0522c28790a0c8c9c Mon Sep 17 00:00:00 2001 +From: Omar Sandoval +Date: Fri, 10 Apr 2015 14:20:40 -0700 +Subject: btrfs: unlock i_mutex after attempting to delete subvolume during send + +From: Omar Sandoval + +commit 909e26dce3f7600f5e293ac0522c28790a0c8c9c upstream. + +Whenever the check for a send in progress introduced in commit +521e0546c970 (btrfs: protect snapshots from deleting during send) is +hit, we return without unlocking inode->i_mutex. This is easy to see +with lockdep enabled: + +[ +0.000059] ================================================ +[ +0.000028] [ BUG: lock held when returning to user space! ] +[ +0.000029] 4.0.0-rc5-00096-g3c435c1 #93 Not tainted +[ +0.000026] ------------------------------------------------ +[ +0.000029] btrfs/211 is leaving the kernel with locks still held! +[ +0.000029] 1 lock held by btrfs/211: +[ +0.000023] #0: (&type->i_mutex_dir_key){+.+.+.}, at: [] btrfs_ioctl_snap_destroy+0x2df/0x7a0 + +Make sure we unlock it in the error path. + +Reviewed-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: Omar Sandoval +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ioctl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -2403,7 +2403,7 @@ static noinline int btrfs_ioctl_snap_des + "Attempt to delete subvolume %llu during send", + dest->root_key.objectid); + err = -EPERM; +- goto out_dput; ++ goto out_unlock_inode; + } + + d_invalidate(dentry); +@@ -2498,6 +2498,7 @@ out_up_write: + root_flags & ~BTRFS_ROOT_SUBVOL_DEAD); + spin_unlock(&dest->root_item_lock); + } ++out_unlock_inode: + mutex_unlock(&inode->i_mutex); + if (!err) { + shrink_dcache_sb(root->fs_info->sb); diff --git a/kernel/kernel/files/patches/mageia/fs-efivarfs-Ensure-VariableName-is-NUL-terminated.patch b/kernel/kernel/files/patches/mageia/fs-efivarfs-Ensure-VariableName-is-NUL-terminated.patch new file mode 100644 index 00000000..5de75876 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-efivarfs-Ensure-VariableName-is-NUL-terminated.patch @@ -0,0 +1,41 @@ +From: Ross Lagerwall +Subject: [PATCH RESEND] efivarfs: Ensure VariableName is NUL-terminated +Date: Thu, 2 Apr 2015 08:39:00 +0100 + +Some buggy firmware implementations update VariableNameSize on success +such that it does not include the final NUL character which results in +garbage in the efivarfs name entries. Use kzalloc on the efivar_entry +(as is done in efivars.c) to ensure that the name is always +NUL-terminated. + +The buggy firmware is: +BIOS Information + Vendor: Intel Corp. + Version: S1200RP.86B.02.02.0005.102320140911 + Release Date: 10/23/2014 + BIOS Revision: 4.6 +System Information + Manufacturer: Intel Corporation + Product Name: S1200RP_SE + +Signed-off-by: Ross Lagerwall +--- + fs/efivarfs/super.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c +index ddbce42..acf9a67 100644 +--- a/fs/efivarfs/super.c ++++ b/fs/efivarfs/super.c +@@ -121,7 +121,7 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, + int len, i; + int err = -ENOMEM; + +- entry = kmalloc(sizeof(*entry), GFP_KERNEL); ++ entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return err; + +-- +2.1.0 + diff --git a/kernel/kernel/files/patches/mageia/fs-ext4-fix-data-corruption-caused-by-unwritten-and-del.patch b/kernel/kernel/files/patches/mageia/fs-ext4-fix-data-corruption-caused-by-unwritten-and-del.patch new file mode 100644 index 00000000..5281eaec --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-ext4-fix-data-corruption-caused-by-unwritten-and-del.patch @@ -0,0 +1,93 @@ +From d2dc317d564a46dfc683978a2e5a4f91434e9711 Mon Sep 17 00:00:00 2001 +From: Lukas Czerner +Date: Sat, 2 May 2015 21:36:55 -0400 +Subject: [PATCH] ext4: fix data corruption caused by unwritten and delayed + extents + +Currently it is possible to lose whole file system block worth of data +when we hit the specific interaction with unwritten and delayed extents +in status extent tree. + +The problem is that when we insert delayed extent into extent status +tree the only way to get rid of it is when we write out delayed buffer. +However there is a limitation in the extent status tree implementation +so that when inserting unwritten extent should there be even a single +delayed block the whole unwritten extent would be marked as delayed. + +At this point, there is no way to get rid of the delayed extents, +because there are no delayed buffers to write out. So when a we write +into said unwritten extent we will convert it to written, but it still +remains delayed. + +When we try to write into that block later ext4_da_map_blocks() will set +the buffer new and delayed and map it to invalid block which causes +the rest of the block to be zeroed loosing already written data. + +For now we can fix this by simply not allowing to set delayed status on +written extent in the extent status tree. Also add WARN_ON() to make +sure that we notice if this happens in the future. + +This problem can be easily reproduced by running the following xfs_io. + +xfs_io -f -c "pwrite -S 0xaa 4096 2048" \ + -c "falloc 0 131072" \ + -c "pwrite -S 0xbb 65536 2048" \ + -c "fsync" /mnt/test/fff + +echo 3 > /proc/sys/vm/drop_caches +xfs_io -c "pwrite -S 0xdd 67584 2048" /mnt/test/fff + +This can be theoretically also reproduced by at random by running fsx, +but it's not very reliable, though on machines with bigger page size +(like ppc) this can be seen more often (especially xfstest generic/127) + +Signed-off-by: Lukas Czerner +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +--- + fs/ext4/extents_status.c | 8 ++++++++ + fs/ext4/inode.c | 2 ++ + 2 files changed, 10 insertions(+) + +diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c +index d33d5a6..26724ae 100644 +--- a/fs/ext4/extents_status.c ++++ b/fs/ext4/extents_status.c +@@ -703,6 +703,14 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, + + BUG_ON(end < lblk); + ++ if ((status & EXTENT_STATUS_DELAYED) && ++ (status & EXTENT_STATUS_WRITTEN)) { ++ ext4_warning(inode->i_sb, "Inserting extent [%u/%u] as " ++ " delayed and written which can potentially " ++ " cause data loss.\n", lblk, len); ++ WARN_ON(1); ++ } ++ + newes.es_lblk = lblk; + newes.es_len = len; + ext4_es_store_pblock_status(&newes, pblk, status); +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index f6b35d8..4415cea 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -532,6 +532,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, + status = map->m_flags & EXT4_MAP_UNWRITTEN ? + EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; + if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) && ++ !(status & EXTENT_STATUS_WRITTEN) && + ext4_find_delalloc_range(inode, map->m_lblk, + map->m_lblk + map->m_len - 1)) + status |= EXTENT_STATUS_DELAYED; +@@ -636,6 +637,7 @@ found: + status = map->m_flags & EXT4_MAP_UNWRITTEN ? + EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; + if (!(flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) && ++ !(status & EXTENT_STATUS_WRITTEN) && + ext4_find_delalloc_range(inode, map->m_lblk, + map->m_lblk + map->m_len - 1)) + status |= EXTENT_STATUS_DELAYED; +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/fs-ext4-move-check-under-lock-scope-to-close-a-race.patch b/kernel/kernel/files/patches/mageia/fs-ext4-move-check-under-lock-scope-to-close-a-race.patch new file mode 100644 index 00000000..fdcda8b2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-ext4-move-check-under-lock-scope-to-close-a-race.patch @@ -0,0 +1,53 @@ +From 280227a75b56ab5d35854f3a77ef74a7ad56a203 Mon Sep 17 00:00:00 2001 +From: Davide Italiano +Date: Sat, 2 May 2015 23:21:15 -0400 +Subject: ext4: move check under lock scope to close a race. + +From: Davide Italiano + +commit 280227a75b56ab5d35854f3a77ef74a7ad56a203 upstream. + +fallocate() checks that the file is extent-based and returns +EOPNOTSUPP in case is not. Other tasks can convert from and to +indirect and extent so it's safe to check only after grabbing +the inode mutex. + +Signed-off-by: Davide Italiano +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/extents.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -4934,13 +4934,6 @@ long ext4_fallocate(struct file *file, i + if (ret) + return ret; + +- /* +- * currently supporting (pre)allocate mode for extent-based +- * files _only_ +- */ +- if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) +- return -EOPNOTSUPP; +- + if (mode & FALLOC_FL_COLLAPSE_RANGE) + return ext4_collapse_range(inode, offset, len); + +@@ -4962,6 +4955,14 @@ long ext4_fallocate(struct file *file, i + + mutex_lock(&inode->i_mutex); + ++ /* ++ * We only support preallocation for extent-based files only ++ */ ++ if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { ++ ret = -EOPNOTSUPP; ++ goto out; ++ } ++ + if (!(mode & FALLOC_FL_KEEP_SIZE) && + offset + len > i_size_read(inode)) { + new_size = offset + len; diff --git a/kernel/kernel/files/patches/mageia/fs-mnt-Fail-collect_mounts-when-applied-to-unmounted-mo.patch b/kernel/kernel/files/patches/mageia/fs-mnt-Fail-collect_mounts-when-applied-to-unmounted-mo.patch new file mode 100644 index 00000000..b2f9ee94 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-mnt-Fail-collect_mounts-when-applied-to-unmounted-mo.patch @@ -0,0 +1,49 @@ +From cd4a40174b71acd021877341684d8bb1dc8ea4ae Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Wed, 7 Jan 2015 14:28:26 -0600 +Subject: [PATCH] mnt: Fail collect_mounts when applied to unmounted mounts + +The only users of collect_mounts are in audit_tree.c + +In audit_trim_trees and audit_add_tree_rule the path passed into +collect_mounts is generated from kern_path passed an audit_tree +pathname which is guaranteed to be an absolute path. In those cases +collect_mounts is obviously intended to work on mounted paths and +if a race results in paths that are unmounted when collect_mounts +it is reasonable to fail early. + +The paths passed into audit_tag_tree don't have the absolute path +check. But are used to play with fsnotify and otherwise interact with +the audit_trees, so again operating only on mounted paths appears +reasonable. + +Avoid having to worry about what happens when we try and audit +unmounted filesystems by restricting collect_mounts to mounts +that appear in the mount tree. + +Signed-off-by: "Eric W. Biederman" +--- + fs/namespace.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/fs/namespace.c b/fs/namespace.c +index 2b12b7a..acc5583 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -1669,8 +1669,11 @@ struct vfsmount *collect_mounts(struct path *path) + { + struct mount *tree; + namespace_lock(); +- tree = copy_tree(real_mount(path->mnt), path->dentry, +- CL_COPY_ALL | CL_PRIVATE); ++ if (!check_mnt(real_mount(path->mnt))) ++ tree = ERR_PTR(-EINVAL); ++ else ++ tree = copy_tree(real_mount(path->mnt), path->dentry, ++ CL_COPY_ALL | CL_PRIVATE); + namespace_unlock(); + if (IS_ERR(tree)) + return ERR_CAST(tree); +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/fs-mnt-Fix-fs_fully_visible-to-verify-the-root-director.patch b/kernel/kernel/files/patches/mageia/fs-mnt-Fix-fs_fully_visible-to-verify-the-root-director.patch new file mode 100644 index 00000000..0a8a5e8f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-mnt-Fix-fs_fully_visible-to-verify-the-root-director.patch @@ -0,0 +1,36 @@ +From 7e96c1b0e0f495c5a7450dc4aa7c9a24ba4305bd Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 8 May 2015 16:36:50 -0500 +Subject: [PATCH] mnt: Fix fs_fully_visible to verify the root directory is + visible + +This fixes a dumb bug in fs_fully_visible that allows proc or sys to +be mounted if there is a bind mount of part of /proc/ or /sys/ visible. + +Cc: stable@vger.kernel.org +Reported-by: Eric Windisch +Signed-off-by: "Eric W. Biederman" +--- + fs/namespace.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/fs/namespace.c b/fs/namespace.c +index 1f4f9da..1b9e111 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -3179,6 +3179,12 @@ bool fs_fully_visible(struct file_system_type *type) + if (mnt->mnt.mnt_sb->s_type != type) + continue; + ++ /* This mount is not fully visible if it's root directory ++ * is not the root directory of the filesystem. ++ */ ++ if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) ++ continue; ++ + /* This mount is not fully visible if there are any child mounts + * that cover anything except for empty directories. + */ +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/fs-path_openat-fix-double-fput.patch b/kernel/kernel/files/patches/mageia/fs-path_openat-fix-double-fput.patch new file mode 100644 index 00000000..6a4d81ed --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-path_openat-fix-double-fput.patch @@ -0,0 +1,36 @@ +From f15133df088ecadd141ea1907f2c96df67c729f0 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Fri, 8 May 2015 22:53:15 -0400 +Subject: [PATCH] path_openat(): fix double fput() + +path_openat() jumps to the wrong place after do_tmpfile() - it has +already done path_cleanup() (as part of path_lookupat() called by +do_tmpfile()), so doing that again can lead to double fput(). + +Cc: stable@vger.kernel.org # v3.11+ +Signed-off-by: Al Viro +--- + fs/namei.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/namei.c b/fs/namei.c +index f67cf6c..fe30d3b 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -3209,7 +3209,7 @@ static struct file *path_openat(int dfd, + + if (unlikely(file->f_flags & __O_TMPFILE)) { + error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened); +- goto out; ++ goto out2; + } + + error = path_init(dfd, pathname->name, flags, nd); +@@ -3239,6 +3239,7 @@ static struct file *path_openat(int dfd, + } + out: + path_cleanup(nd); ++out2: + if (!(opened & FILE_OPENED)) { + BUG_ON(!error); + put_filp(file); diff --git a/kernel/kernel/files/patches/mageia/fs-splice-sendfile-at-once-fails-for-big-files.patch b/kernel/kernel/files/patches/mageia/fs-splice-sendfile-at-once-fails-for-big-files.patch new file mode 100644 index 00000000..369de1d1 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/fs-splice-sendfile-at-once-fails-for-big-files.patch @@ -0,0 +1,136 @@ +From 0ff28d9f4674d781e492bcff6f32f0fe48cf0fed Mon Sep 17 00:00:00 2001 +From: Christophe Leroy +Date: Wed, 6 May 2015 17:26:47 +0200 +Subject: [PATCH] splice: sendfile() at once fails for big files + +Using sendfile with below small program to get MD5 sums of some files, +it appear that big files (over 64kbytes with 4k pages system) get a +wrong MD5 sum while small files get the correct sum. +This program uses sendfile() to send a file to an AF_ALG socket +for hashing. + +/* md5sum2.c */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + int sk = socket(AF_ALG, SOCK_SEQPACKET, 0); + struct stat st; + struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "hash", + .salg_name = "md5", + }; + int n; + + bind(sk, (struct sockaddr*)&sa, sizeof(sa)); + + for (n = 1; n < argc; n++) { + int size; + int offset = 0; + char buf[4096]; + int fd; + int sko; + int i; + + fd = open(argv[n], O_RDONLY); + sko = accept(sk, NULL, 0); + fstat(fd, &st); + size = st.st_size; + sendfile(sko, fd, &offset, size); + size = read(sko, buf, sizeof(buf)); + for (i = 0; i < size; i++) + printf("%2.2x", buf[i]); + printf(" %s\n", argv[n]); + close(fd); + close(sko); + } + exit(0); +} + +Test below is done using official linux patch files. First result is +with a software based md5sum. Second result is with the program above. + +root@vgoip:~# ls -l patch-3.6.* +-rw-r--r-- 1 root root 64011 Aug 24 12:01 patch-3.6.2.gz +-rw-r--r-- 1 root root 94131 Aug 24 12:01 patch-3.6.3.gz + +root@vgoip:~# md5sum patch-3.6.* +b3ffb9848196846f31b2ff133d2d6443 patch-3.6.2.gz +c5e8f687878457db77cb7158c38a7e43 patch-3.6.3.gz + +root@vgoip:~# ./md5sum2 patch-3.6.* +b3ffb9848196846f31b2ff133d2d6443 patch-3.6.2.gz +5fd77b24e68bb24dcc72d6e57c64790e patch-3.6.3.gz + +After investivation, it appears that sendfile() sends the files by blocks +of 64kbytes (16 times PAGE_SIZE). The problem is that at the end of each +block, the SPLICE_F_MORE flag is missing, therefore the hashing operation +is reset as if it was the end of the file. + +This patch adds SPLICE_F_MORE to the flags when more data is pending. + +With the patch applied, we get the correct sums: + +root@vgoip:~# md5sum patch-3.6.* +b3ffb9848196846f31b2ff133d2d6443 patch-3.6.2.gz +c5e8f687878457db77cb7158c38a7e43 patch-3.6.3.gz + +root@vgoip:~# ./md5sum2 patch-3.6.* +b3ffb9848196846f31b2ff133d2d6443 patch-3.6.2.gz +c5e8f687878457db77cb7158c38a7e43 patch-3.6.3.gz + +Signed-off-by: Christophe Leroy +Signed-off-by: Jens Axboe +--- + fs/splice.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/fs/splice.c b/fs/splice.c +index 476024b..bfe62ae 100644 +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -1161,7 +1161,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, + long ret, bytes; + umode_t i_mode; + size_t len; +- int i, flags; ++ int i, flags, more; + + /* + * We require the input being a regular file, as we don't want to +@@ -1204,6 +1204,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, + * Don't block on output, we have to drain the direct pipe. + */ + sd->flags &= ~SPLICE_F_NONBLOCK; ++ more = sd->flags & SPLICE_F_MORE; + + while (len) { + size_t read_len; +@@ -1217,6 +1218,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, + sd->total_len = read_len; + + /* ++ * If more data is pending, set SPLICE_F_MORE ++ * If this is the last data and SPLICE_F_MORE was not set ++ * initially, clears it. ++ */ ++ if (read_len < len) ++ sd->flags |= SPLICE_F_MORE; ++ else if (!more) ++ sd->flags &= ~SPLICE_F_MORE; ++ /* + * NOTE: nonblocking mode only applies to the input. We + * must not do the output in nonblocking mode as then we + * could get stuck data in the internal pipe: +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/genirq-Fix-null-pointer-reference-in-irq_set_affinit.patch b/kernel/kernel/files/patches/mageia/genirq-Fix-null-pointer-reference-in-irq_set_affinit.patch new file mode 100644 index 00000000..458a93c7 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/genirq-Fix-null-pointer-reference-in-irq_set_affinit.patch @@ -0,0 +1,37 @@ +From 4fe7ffb7e17ca6ad9173b8de35f260c9c8fc2f79 Mon Sep 17 00:00:00 2001 +From: Jesse Brandeburg +Date: Wed, 28 Jan 2015 10:57:14 -0800 +Subject: [PATCH] genirq: Fix null pointer reference in irq_set_affinity_hint() + +The recent set_affinity commit by me introduced some null +pointer dereferences on driver unload, because some drivers +call this function with a NULL argument. This fixes the issue +by just checking for null before setting the affinity mask. + +Fixes: e2e64a932556 ("genirq: Set initial affinity in irq_set_affinity_hint()") +Reported-by: Yinghai Lu +Signed-off-by: Jesse Brandeburg +CC: netdev@vger.kernel.org +Link: http://lkml.kernel.org/r/20150128185739.9689.84588.stgit@jbrandeb-cp2.jf.intel.com +Signed-off-by: Ingo Molnar +--- + kernel/irq/manage.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index f038e58..196a06f 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -244,7 +244,8 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m) + desc->affinity_hint = m; + irq_put_desc_unlock(desc, flags); + /* set the initial affinity to prevent every interrupt being on CPU0 */ +- __irq_set_affinity(irq, m, false); ++ if (m) ++ __irq_set_affinity(irq, m, false); + return 0; + } + EXPORT_SYMBOL_GPL(irq_set_affinity_hint); +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/genirq-Set-initial-affinity-in-irq_set_affinity_hint.patch b/kernel/kernel/files/patches/mageia/genirq-Set-initial-affinity-in-irq_set_affinity_hint.patch new file mode 100644 index 00000000..ca1c7fa7 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/genirq-Set-initial-affinity-in-irq_set_affinity_hint.patch @@ -0,0 +1,69 @@ +From e2e64a932556cdfae455497dbe94a8db151fc9fa Mon Sep 17 00:00:00 2001 +From: Jesse Brandeburg +Date: Thu, 18 Dec 2014 17:21:41 -0800 +Subject: [PATCH] genirq: Set initial affinity in irq_set_affinity_hint() + +Problem: +The default behavior of the kernel is somewhat undesirable as all +requested interrupts end up on CPU0 after registration. A user can +run irqbalance daemon, or can manually configure smp_affinity via the +proc filesystem, but the default affinity of the interrupts for all +devices is always CPU zero, this can cause performance problems or +very heavy cpu use of only one core if not noticed and fixed by the +user. + +Solution: +Enable the setting of the initial affinity directly when the driver +sets a hint. + +This enabling means that kernel drivers can include an initial +affinity setting for the interrupt, instead of all interrupts starting +out life on CPU0. Of course if irqbalance is still running then the +interrupts will get moved as before. + +This function is currently called by drivers in block, crypto, +infiniband, ethernet and scsi trees, but only a handful, so these will +be the devices affected by this change. + +Tested on i40e, and default interrupts were spread across the CPUs +according to the hint. + +drivers/block/mtip32xx/mtip32xx.c:3 +drivers/block/nvme-core.c:2 +drivers/crypto/qat/qat_dh895xcc/adf_isr.c:3 +drivers/infiniband/hw/qib/qib_iba7322.c:2 +drivers/net/ethernet/intel/i40e/i40e_main.c:3 +drivers/net/ethernet/intel/i40evf/i40evf_main.c:3 +drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:3 +drivers/net/ethernet/mellanox/mlx4/en_cq.c:2 +drivers/scsi/hpsa.c:3 +drivers/scsi/lpfc/lpfc_init.c:3 +drivers/scsi/megaraid/megaraid_sas_base.c:8 +drivers/soc/ti/knav_qmss_acc.c:1 +drivers/soc/ti/knav_qmss_queue.c:2 +drivers/virtio/virtio_pci_common.c:2 + +Signed-off-by: Jesse Brandeburg +Cc: netdev@vger.kernel.org +Link: http://lkml.kernel.org/r/20141219012206.4220.27491.stgit@jbrandeb-cp2.jf.intel.com +Signed-off-by: Thomas Gleixner +--- + kernel/irq/manage.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c +index 8069237..f038e58 100644 +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -243,6 +243,8 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m) + return -EINVAL; + desc->affinity_hint = m; + irq_put_desc_unlock(desc, flags); ++ /* set the initial affinity to prevent every interrupt being on CPU0 */ ++ __irq_set_affinity(irq, m, false); + return 0; + } + EXPORT_SYMBOL_GPL(irq_set_affinity_hint); +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Enable-the-HiZ-RAW-Stall-Optimization-on-Broadwell.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Enable-the-HiZ-RAW-Stall-Optimization-on-Broadwell.patch new file mode 100644 index 00000000..ae55de1c --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Enable-the-HiZ-RAW-Stall-Optimization-on-Broadwell.patch @@ -0,0 +1,45 @@ +From 2701fc43562b55f5db0139ef6a7b13c2518ed6c0 Mon Sep 17 00:00:00 2001 +From: Kenneth Graunke +Date: Tue, 13 Jan 2015 12:46:52 -0800 +Subject: drm/i915: Enable the HiZ RAW Stall Optimization on Broadwell. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is an important optimization for avoiding read-after-write (RAW) +stalls in the HiZ buffer. Certain workloads would run very slowly with +HiZ enabled, but run much faster with the "hiz=false" driconf option. +With this patch, they run at full speed even with HiZ. + +Improves performance in OglVSInstancing by 3.2x on Broadwell GT3e +(Iris Pro 6200). + +Thanks to Jesse Barnes and Ben Widawsky for their help in tracking this +down. Thanks to Chris Wilson for showing me the new workarounds system. + +Signed-off-by: Kenneth Graunke +Cc: Jesse Barnes +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index dabc1d8..0df15a4 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -767,6 +767,16 @@ static int bdw_init_workarounds(struct i + HDC_FORCE_NON_COHERENT | + (IS_BDW_GT3(dev) ? HDC_FENCE_DEST_SLM_DISABLE : 0)); + ++ /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0: ++ * "The Hierarchical Z RAW Stall Optimization allows non-overlapping ++ * polygons in the same 8x4 pixel/sample area to be processed without ++ * stalling waiting for the earlier ones to write to Hierarchical Z ++ * buffer." ++ * ++ * This optimization is off by default for Broadwell; turn it on. ++ */ ++ WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); ++ + /* Wa4x4STCOptimizationDisable:bdw */ + WA_SET_BIT_MASKED(CACHE_MODE_1, + GEN8_4x4_STC_OPTIMIZATION_DISABLE); diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Ensure-the-HiZ-RAW-Stall-Optimization-is-on-for-Cherryview.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Ensure-the-HiZ-RAW-Stall-Optimization-is-on-for-Cherryview.patch new file mode 100644 index 00000000..598cfe20 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Ensure-the-HiZ-RAW-Stall-Optimization-is-on-for-Cherryview.patch @@ -0,0 +1,35 @@ +From 973a5b06a096f1a9494ebe94c78d809459f4dc74 Mon Sep 17 00:00:00 2001 +From: Kenneth Graunke +Date: Tue, 13 Jan 2015 12:46:53 -0800 +Subject: drm/i915: Ensure the HiZ RAW Stall Optimization is on for Cherryview. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This is an important optimization for avoiding read-after-write (RAW) +stalls in the HiZ buffer. Certain workloads would run very slowly with +HiZ enabled, but run much faster with the "hiz=false" driconf option. +With this patch, they run at full speed even with HiZ. + +Increases performance in OglVSInstancing by about 2.7x on Braswell. + +Signed-off-by: Kenneth Graunke +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 0df15a4..23020d6 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -817,6 +817,11 @@ static int chv_init_workarounds(struct i + HDC_FORCE_NON_COHERENT | + HDC_DONOT_FETCH_MEM_WHEN_MASKED); + ++ /* According to the CACHE_MODE_0 default value documentation, some ++ * CHV platforms disable this optimization by default. Turn it on. ++ */ ++ WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE); ++ + /* Improve HiZ throughput on CHV. */ + WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X); + diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Improve-HiZ-throughput-on-Cherryview.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Improve-HiZ-throughput-on-Cherryview.patch new file mode 100644 index 00000000..83f98e45 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Improve-HiZ-throughput-on-Cherryview.patch @@ -0,0 +1,47 @@ +From d60de81da48aa25b06a015b839906243710e7253 Mon Sep 17 00:00:00 2001 +From: Kenneth Graunke +Date: Sat, 10 Jan 2015 18:02:22 -0800 +Subject: drm/i915: Improve HiZ throughput on Cherryview. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Found by reading the HIZ_CHICKEN documentation. + +Improves performance in a HiZ microbenchmark by around 50%. +Improves performance in OglZBuffer by around 18%. + +Thanks to Chris Wilson for helping me figure out where to put this. + +Signed-off-by: Kenneth Graunke +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 0f32fd1a..a39bb03 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -5158,6 +5158,9 @@ enum punit_power_well { + #define COMMON_SLICE_CHICKEN2 0x7014 + # define GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE (1<<0) + ++#define HIZ_CHICKEN 0x7018 ++# define CHV_HZ_8X8_MODE_IN_1X (1<<15) ++ + #define GEN7_L3SQCREG1 0xB010 + #define VLV_B0_WA_L3SQCREG1_VALUE 0x00D30000 + +diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c +index 12a36f0..dabc1d8 100644 +--- a/drivers/gpu/drm/i915/intel_ringbuffer.c ++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c +@@ -807,6 +807,9 @@ static int chv_init_workarounds(struct i + HDC_FORCE_NON_COHERENT | + HDC_DONOT_FETCH_MEM_WHEN_MASKED); + ++ /* Improve HiZ throughput on CHV. */ ++ WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X); ++ + return 0; + } + diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-Make-sample_c-messages-go-faster-on-Haswell.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Make-sample_c-messages-go-faster-on-Haswell.patch new file mode 100644 index 00000000..05f60a0b --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-i915-Make-sample_c-messages-go-faster-on-Haswell.patch @@ -0,0 +1,69 @@ +From c44c70983107257f33f2b9d1c6a5aaf3d2eb670a Mon Sep 17 00:00:00 2001 +From: Kenneth Graunke +Date: Wed, 31 Dec 2014 16:23:00 -0800 +Subject: drm/i915: Make sample_c messages go faster on Haswell. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Haswell significantly improved the performance of sampler_c messages, +but the optimization appears to be off by default. Later platforms +remove this bit, and apparently always enable the optimization. + +Improves performance in "Counter Strike: Global Offensive" by 18% +at default settings on Iris Pro. + +This may break sampling of paletted formats (P8/A8P8/P8A8). It's +unclear whether it affects sampling of paletted formats in general, +or just the sample_c message (which is never used). + +While libva does have support for using paletted formats (primarily +for OSDs), that support appears to have been broken for at least a +year, so I couldn't observe a regression from this: + +I tried to get libva-intel to use paletted formats, and observe a +regression...but the only thing I found that used it was mplayer's OSD +(on screen display). Even without my patch, the colors were totally +wrong with that, and it's according to a few distro wikis, that's been +the case for over a year. + +If libva's code for paletted formats /is/ broken, they could always +add code to disable this bit using the command validator when fixing +it. + +Signed-off-by: Kenneth Graunke +[danvet: Add wa name from Ville's review to the comment and copypaste +the explanation why we don't care about libva (already broken) from +Ken.] +Reviewed-by: Ville Syrjälä +Signed-off-by: Daniel Vetter + +diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h +index 1fdda42..0cb0067 100644 +--- a/drivers/gpu/drm/i915/i915_reg.h ++++ b/drivers/gpu/drm/i915/i915_reg.h +@@ -6119,6 +6119,7 @@ enum punit_power_well { + #define HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE (1 << 6) + + #define HALF_SLICE_CHICKEN3 0xe184 ++#define HSW_SAMPLE_C_PERFORMANCE (1<<9) + #define GEN8_CENTROID_PIXEL_OPT_DIS (1<<8) + #define GEN8_SAMPLER_POWER_BYPASS_DIS (1<<1) + +diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c +index 4254e91..0918604 100644 +--- a/drivers/gpu/drm/i915/intel_pm.c ++++ b/drivers/gpu/drm/i915/intel_pm.c +@@ -6710,6 +6710,10 @@ static void haswell_init_clock_gating(st + I915_WRITE(GEN7_GT_MODE, + _MASKED_FIELD(GEN6_WIZ_HASHING_MASK, GEN6_WIZ_HASHING_16x4)); + ++ /* WaSampleCChickenBitEnable:hsw */ ++ I915_WRITE(HALF_SLICE_CHICKEN3, ++ _MASKED_BIT_ENABLE(HSW_SAMPLE_C_PERFORMANCE)); ++ + /* WaSwitchSolVfFArbitrationPriority:hsw */ + I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL); + +-- +cgit v0.10.2 diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-i915-fix-vlv-crash.patch b/kernel/kernel/files/patches/mageia/gpu-drm-i915-fix-vlv-crash.patch new file mode 100644 index 00000000..2d5c684f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-i915-fix-vlv-crash.patch @@ -0,0 +1,24 @@ + +Revert back to legacy turbo for vlv, fixes random crashes. + +Reported by Timothée Giet on dev@ ml. + +https://bugs.freedesktop.org/show_bug.cgi?id=88012#c33 + + +--- linux/drivers/gpu/drm/i915/i915_irq.c.orig ++++ linux/drivers/gpu/drm/i915/i915_irq.c +@@ -4361,12 +4361,7 @@ void intel_irq_init(struct drm_i915_priv + INIT_WORK(&dev_priv->rps.work, gen6_pm_rps_work); + INIT_WORK(&dev_priv->l3_parity.error_work, ivybridge_parity_work); + +- /* Let's track the enabled rps events */ +- if (IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) +- /* WaGsvRC0ResidencyMethod:vlv */ +- dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; +- else +- dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; ++ dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; + + setup_timer(&dev_priv->gpu_error.hangcheck_timer, + i915_hangcheck_elapsed, diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.31.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.31.patch new file mode 100644 index 00000000..ac0254e5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.31.patch @@ -0,0 +1,100 @@ +Adapt mach64 to build with 2.6.31 series kernels + +Signed-off-by: Thomas Backlund + +diff -urp linux-2.6.31-rc3-git5-mnb1/drivers/gpu/drm/mach64/mach64_dma.c linux-2.6.31-rc3-git5-mnb1/drivers/gpu/drm/mach64.fixed/mach64_dma.c +--- linux-2.6.31-rc3-git5-mnb1/drivers/gpu/drm/mach64/mach64_dma.c 2009-07-23 00:24:12.000000000 +0300 ++++ linux-2.6.31-rc3-git5-mnb1/drivers/gpu/drm/mach64.fixed/mach64_dma.c 2009-07-23 02:28:21.000000000 +0300 +@@ -1006,7 +1006,7 @@ static int mach64_do_dma_init(struct drm + + DRM_DEBUG("\n"); + +- dev_priv = drm_alloc(sizeof(drm_mach64_private_t), DRM_MEM_DRIVER); ++ dev_priv = kmalloc(sizeof(drm_mach64_private_t), GFP_KERNEL); + if (dev_priv == NULL) + return -ENOMEM; + +@@ -1386,8 +1386,7 @@ int mach64_do_cleanup_dma(struct drm_dev + + mach64_destroy_freelist(dev); + +- drm_free(dev_priv, sizeof(drm_mach64_private_t), +- DRM_MEM_DRIVER); ++ kfree(dev_priv); + dev->dev_private = NULL; + } + +@@ -1476,8 +1475,8 @@ int mach64_init_freelist(struct drm_devi + for (i = 0; i < dma->buf_count; i++) { + if ((entry = + (drm_mach64_freelist_t *) +- drm_alloc(sizeof(drm_mach64_freelist_t), +- DRM_MEM_BUFLISTS)) == NULL) ++ kmalloc(sizeof(drm_mach64_freelist_t), ++ GFP_KERNEL)) == NULL) + return -ENOMEM; + memset(entry, 0, sizeof(drm_mach64_freelist_t)); + entry->buf = dma->buflist[i]; +@@ -1500,18 +1499,18 @@ void mach64_destroy_freelist(struct drm_ + list_for_each_safe(ptr, tmp, &dev_priv->pending) { + list_del(ptr); + entry = list_entry(ptr, drm_mach64_freelist_t, list); +- drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS); ++ kfree(entry); + } + list_for_each_safe(ptr, tmp, &dev_priv->placeholders) { + list_del(ptr); + entry = list_entry(ptr, drm_mach64_freelist_t, list); +- drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS); ++ kfree(entry); + } + + list_for_each_safe(ptr, tmp, &dev_priv->free_list) { + list_del(ptr); + entry = list_entry(ptr, drm_mach64_freelist_t, list); +- drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS); ++ kfree(entry); + } + } + +diff -urp linux-2.6.31-rc3-git5-mnb1/drivers/gpu/drm/mach64/mach64_state.c linux-2.6.31-rc3-git5-mnb1/drivers/gpu/drm/mach64.fixed/mach64_state.c +--- linux-2.6.31-rc3-git5-mnb1/drivers/gpu/drm/mach64/mach64_state.c 2009-07-23 00:24:12.000000000 +0300 ++++ linux-2.6.31-rc3-git5-mnb1/drivers/gpu/drm/mach64.fixed/mach64_state.c 2009-07-23 02:29:24.000000000 +0300 +@@ -490,12 +490,12 @@ static __inline__ int copy_from_user_ver + unsigned long n = bytes; /* dwords remaining in buffer */ + u32 *from, *orig_from; + +- from = drm_alloc(bytes, DRM_MEM_DRIVER); ++ from = kmalloc(bytes, GFP_KERNEL); + if (from == NULL) + return -ENOMEM; + + if (DRM_COPY_FROM_USER(from, ufrom, bytes)) { +- drm_free(from, bytes, DRM_MEM_DRIVER); ++ kfree(from); + return -EFAULT; + } + orig_from = from; /* we'll be modifying the "from" ptr, so save it */ +@@ -526,19 +526,19 @@ static __inline__ int copy_from_user_ver + to += count; + } else { + DRM_ERROR("Got bad command: 0x%04x\n", reg); +- drm_free(orig_from, bytes, DRM_MEM_DRIVER); ++ kfree(orig_from); + return -EACCES; + } + } else { + DRM_ERROR + ("Got bad command count(=%u) dwords remaining=%lu\n", + count, n); +- drm_free(orig_from, bytes, DRM_MEM_DRIVER); ++ kfree(orig_from); + return -EINVAL; + } + } + +- drm_free(orig_from, bytes, DRM_MEM_DRIVER); ++ kfree(orig_from); + if (n == 0) + return 0; + else { diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.36-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.36-buildfix.patch new file mode 100644 index 00000000..ef428983 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.36-buildfix.patch @@ -0,0 +1,27 @@ +--- linux-2.6.35/drivers/gpu/drm/mach64/mach64_state.c.orig 2010-10-03 13:29:10.000000000 +0300 ++++ linux-2.6.35/drivers/gpu/drm/mach64/mach64_state.c 2010-10-03 14:04:45.991164007 +0300 +@@ -41,15 +41,15 @@ + * + */ + struct drm_ioctl_desc mach64_ioctls[] = { +- DRM_IOCTL_DEF(DRM_MACH64_INIT, mach64_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), +- DRM_IOCTL_DEF(DRM_MACH64_CLEAR, mach64_dma_clear, DRM_AUTH), +- DRM_IOCTL_DEF(DRM_MACH64_SWAP, mach64_dma_swap, DRM_AUTH), +- DRM_IOCTL_DEF(DRM_MACH64_IDLE, mach64_dma_idle, DRM_AUTH), +- DRM_IOCTL_DEF(DRM_MACH64_RESET, mach64_engine_reset, DRM_AUTH), +- DRM_IOCTL_DEF(DRM_MACH64_VERTEX, mach64_dma_vertex, DRM_AUTH), +- DRM_IOCTL_DEF(DRM_MACH64_BLIT, mach64_dma_blit, DRM_AUTH), +- DRM_IOCTL_DEF(DRM_MACH64_FLUSH, mach64_dma_flush, DRM_AUTH), +- DRM_IOCTL_DEF(DRM_MACH64_GETPARAM, mach64_get_param, DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(MACH64_INIT, mach64_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), ++ DRM_IOCTL_DEF_DRV(MACH64_CLEAR, mach64_dma_clear, DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(MACH64_SWAP, mach64_dma_swap, DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(MACH64_IDLE, mach64_dma_idle, DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(MACH64_RESET, mach64_engine_reset, DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(MACH64_VERTEX, mach64_dma_vertex, DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(MACH64_BLIT, mach64_dma_blit, DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(MACH64_FLUSH, mach64_dma_flush, DRM_AUTH), ++ DRM_IOCTL_DEF_DRV(MACH64_GETPARAM, mach64_get_param, DRM_AUTH), + }; + + int mach64_max_ioctl = DRM_ARRAY_SIZE(mach64_ioctls); diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.37-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.37-buildfix.patch new file mode 100644 index 00000000..43dc70ec --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-2.6.37-buildfix.patch @@ -0,0 +1,24 @@ + +Fix build for 2.6.37 + +Signed-off-by: Thomas Backlund + +--- a/drivers/gpu/drm/mach64/mach64_drv.c.orig 2011-01-02 16:55:48.000000000 +0200 ++++ a/drivers/gpu/drm/mach64/mach64_drv.c 2011-01-02 17:53:54.808775632 +0200 +@@ -51,8 +51,6 @@ static struct drm_driver driver = { + .irq_uninstall = mach64_driver_irq_uninstall, + .irq_handler = mach64_driver_irq_handler, + .reclaim_buffers = drm_core_reclaim_buffers, +- .get_map_ofs = drm_core_get_map_ofs, +- .get_reg_ofs = drm_core_get_reg_ofs, + .ioctls = mach64_ioctls, + .dma_ioctl = mach64_dma_buffers, + .fops = { +@@ -63,6 +61,7 @@ static struct drm_driver driver = { + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, ++ .llseek = noop_llseek, + }, + .pci_driver = { + .name = DRIVER_NAME, diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.0-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.0-buildfix.patch new file mode 100644 index 00000000..9d7538a9 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.0-buildfix.patch @@ -0,0 +1,44 @@ + +fix build with linux-3.0 + +Signed-off-by: Thomas Backlund + + drivers/gpu/drm/mach64/mach64_drv.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/mach64/mach64_drv.c.orig 2011-07-15 02:48:40.000000000 +0300 ++++ a/drivers/gpu/drm/mach64/mach64_drv.c 2011-07-15 13:24:41.454753025 +0300 +@@ -63,10 +63,6 @@ static struct drm_driver driver = { + .fasync = drm_fasync, + .llseek = noop_llseek, + }, +- .pci_driver = { +- .name = DRIVER_NAME, +- .id_table = pciidlist, +- }, + + .name = DRIVER_NAME, + .desc = DRIVER_DESC, +@@ -76,15 +72,20 @@ static struct drm_driver driver = { + .patchlevel = DRIVER_PATCHLEVEL, + }; + ++static struct pci_driver mach64_pci_driver = { ++ .name = DRIVER_NAME, ++ .id_table = pciidlist, ++}; ++ + static int __init mach64_init(void) + { + driver.num_ioctls = mach64_max_ioctl; +- return drm_init(&driver); ++ return drm_pci_init(&driver, &mach64_pci_driver); + } + + static void __exit mach64_exit(void) + { +- drm_exit(&driver); ++ drm_pci_exit(&driver, &mach64_pci_driver); + } + + module_init(mach64_init); diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.12-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.12-buildfix.patch new file mode 100644 index 00000000..5ec06698 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.12-buildfix.patch @@ -0,0 +1,17 @@ +--- linux/drivers/gpu/drm/mach64/mach64_drv.c.orig 2013-10-13 12:19:41.000000000 +0300 ++++ linux/drivers/gpu/drm/mach64/mach64_drv.c 2013-10-13 14:27:25.684247911 +0300 +@@ -46,13 +46,12 @@ static const struct file_operations mach + .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, +- .fasync = drm_fasync, + .llseek = noop_llseek, + }; + + static struct drm_driver driver = { + .driver_features = +- DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA ++ DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_HAVE_DMA + | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, + .lastclose = mach64_driver_lastclose, + .get_vblank_counter = mach64_get_vblank_counter, diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.17-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.17-buildfix.patch new file mode 100644 index 00000000..6b7b3780 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.17-buildfix.patch @@ -0,0 +1,31 @@ + +Adapt for kernel-3.17 + +DRM_ARRAY_SIZE is a duplicate of ARRAY_SIZE and have been dropped. + +drm_dev_to_irq has been dropped, so call dev->pdev->irq directly +for code simplicity. + +Signed-off-by: Thomas Backlund + +diff -urp linux/drivers/gpu/drm/mach64/mach64_state.c.orig linux/drivers/gpu/drm/mach64/mach64_state.c +--- linux/drivers/gpu/drm/mach64/mach64_state.c.orig ++++ linux/drivers/gpu/drm/mach64/mach64_state.c +@@ -52,7 +52,7 @@ struct drm_ioctl_desc mach64_ioctls[] = + DRM_IOCTL_DEF_DRV(MACH64_GETPARAM, mach64_get_param, DRM_AUTH), + }; + +-int mach64_max_ioctl = DRM_ARRAY_SIZE(mach64_ioctls); ++int mach64_max_ioctl = ARRAY_SIZE(mach64_ioctls); + + /* ================================================================ + * DMA hardware state programming functions +@@ -895,7 +895,7 @@ int mach64_get_param(struct drm_device * + value = mach64_do_get_frames_queued(dev_priv); + break; + case MACH64_PARAM_IRQ_NR: +- value = drm_dev_to_irq(dev); ++ value = dev->pdev->irq; + break; + default: + return -EINVAL; diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.18-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.18-buildfix.patch new file mode 100644 index 00000000..bc0d4606 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.18-buildfix.patch @@ -0,0 +1,142 @@ + +Fix build with kernel 3.18 + +Signed-off-by: Thomas Backlund + +diff -urp linux/drivers/gpu/drm/mach64.orig/mach64_dma.c linux/drivers/gpu/drm/mach64/mach64_dma.c +--- linux/drivers/gpu/drm/mach64.orig/mach64_dma.c 2014-11-29 22:01:54.000000000 +0200 ++++ linux/drivers/gpu/drm/mach64/mach64_dma.c 2014-11-30 00:02:06.906821818 +0200 +@@ -1038,21 +1038,21 @@ static int mach64_do_dma_init(struct drm + INIT_LIST_HEAD(&dev_priv->placeholders); + INIT_LIST_HEAD(&dev_priv->pending); + +- dev_priv->sarea = drm_getsarea(dev); ++ dev_priv->sarea = drm_legacy_getsarea(dev); + if (!dev_priv->sarea) { + DRM_ERROR("can not find sarea!\n"); + dev->dev_private = (void *)dev_priv; + mach64_do_cleanup_dma(dev); + return -EINVAL; + } +- dev_priv->fb = drm_core_findmap(dev, init->fb_offset); ++ dev_priv->fb = drm_legacy_findmap(dev, init->fb_offset); + if (!dev_priv->fb) { + DRM_ERROR("can not find frame buffer map!\n"); + dev->dev_private = (void *)dev_priv; + mach64_do_cleanup_dma(dev); + return -EINVAL; + } +- dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); ++ dev_priv->mmio = drm_legacy_findmap(dev, init->mmio_offset); + if (!dev_priv->mmio) { + DRM_ERROR("can not find mmio map!\n"); + dev->dev_private = (void *)dev_priv; +@@ -1060,7 +1060,7 @@ static int mach64_do_dma_init(struct drm + return -EINVAL; + } + +- dev_priv->ring_map = drm_core_findmap(dev, init->ring_offset); ++ dev_priv->ring_map = drm_legacy_findmap(dev, init->ring_offset); + if (!dev_priv->ring_map) { + DRM_ERROR("can not find ring map!\n"); + dev->dev_private = (void *)dev_priv; +@@ -1072,7 +1072,7 @@ static int mach64_do_dma_init(struct drm + ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); + + if (!dev_priv->is_pci) { +- drm_core_ioremap(dev_priv->ring_map, dev); ++ drm_legacy_ioremap(dev_priv->ring_map, dev); + if (!dev_priv->ring_map->handle) { + DRM_ERROR("can not ioremap virtual address for" + " descriptor ring\n"); +@@ -1082,7 +1082,7 @@ static int mach64_do_dma_init(struct drm + } + dev->agp_buffer_token = init->buffers_offset; + dev->agp_buffer_map = +- drm_core_findmap(dev, init->buffers_offset); ++ drm_legacy_findmap(dev, init->buffers_offset); + if (!dev->agp_buffer_map) { + DRM_ERROR("can not find dma buffer map!\n"); + dev->dev_private = (void *)dev_priv; +@@ -1093,7 +1093,7 @@ static int mach64_do_dma_init(struct drm + dev isn't passed all the way though the mach64 - DA */ + dev_priv->dev_buffers = dev->agp_buffer_map; + +- drm_core_ioremap(dev->agp_buffer_map, dev); ++ drm_legacy_ioremap(dev->agp_buffer_map, dev); + if (!dev->agp_buffer_map->handle) { + DRM_ERROR("can not ioremap virtual address for" + " dma buffer\n"); +@@ -1102,7 +1102,7 @@ static int mach64_do_dma_init(struct drm + return -ENOMEM; + } + dev_priv->agp_textures = +- drm_core_findmap(dev, init->agp_textures_offset); ++ drm_legacy_findmap(dev, init->agp_textures_offset); + if (!dev_priv->agp_textures) { + DRM_ERROR("can not find agp texture region!\n"); + dev->dev_private = (void *)dev_priv; +@@ -1376,10 +1376,10 @@ int mach64_do_cleanup_dma(struct drm_dev + + if (!dev_priv->is_pci) { + if (dev_priv->ring_map) +- drm_core_ioremapfree(dev_priv->ring_map, dev); ++ drm_legacy_ioremapfree(dev_priv->ring_map, dev); + + if (dev->agp_buffer_map) { +- drm_core_ioremapfree(dev->agp_buffer_map, dev); ++ drm_legacy_ioremapfree(dev->agp_buffer_map, dev); + dev->agp_buffer_map = NULL; + } + } +diff -urp linux/drivers/gpu/drm/mach64.orig/mach64_drv.c linux/drivers/gpu/drm/mach64/mach64_drv.c +--- linux/drivers/gpu/drm/mach64.orig/mach64_drv.c 2014-11-29 22:01:54.000000000 +0200 ++++ linux/drivers/gpu/drm/mach64/mach64_drv.c 2014-11-29 23:14:21.918009653 +0200 +@@ -34,6 +34,7 @@ + #include "mach64_drv.h" + + #include ++#include + + static struct pci_device_id pciidlist[] = { + mach64_PCI_IDS +@@ -44,7 +45,7 @@ static const struct file_operations mach + .open = drm_open, + .release = drm_release, + .unlocked_ioctl = drm_ioctl, +- .mmap = drm_mmap, ++ .mmap = drm_legacy_mmap, + .poll = drm_poll, + .llseek = noop_llseek, + }; +diff -urp linux/drivers/gpu/drm/mach64.orig/mach64_drv.h linux/drivers/gpu/drm/mach64/mach64_drv.h +--- linux/drivers/gpu/drm/mach64.orig/mach64_drv.h 2014-11-29 22:01:54.000000000 +0200 ++++ linux/drivers/gpu/drm/mach64/mach64_drv.h 2014-11-29 23:58:20.111491646 +0200 +@@ -35,6 +35,8 @@ + #ifndef __MACH64_DRV_H__ + #define __MACH64_DRV_H__ + ++#include ++ + /* General customization: + */ + +@@ -102,12 +104,12 @@ typedef struct drm_mach64_private { + u32 back_offset_pitch; + u32 depth_offset_pitch; + +- drm_local_map_t *sarea; +- drm_local_map_t *fb; +- drm_local_map_t *mmio; +- drm_local_map_t *ring_map; +- drm_local_map_t *dev_buffers; /* this is a pointer to a structure in dev */ +- drm_local_map_t *agp_textures; ++ struct drm_local_map *sarea; ++ struct drm_local_map *fb; ++ struct drm_local_map *mmio; ++ struct drm_local_map *ring_map; ++ struct drm_local_map *dev_buffers; /* this is a pointer to a structure in dev */ ++ struct drm_local_map *agp_textures; + } drm_mach64_private_t; + + extern struct drm_ioctl_desc mach64_ioctls[]; diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.3-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.3-buildfix.patch new file mode 100644 index 00000000..824b9552 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.3-buildfix.patch @@ -0,0 +1,47 @@ + +This moves the .fops to a separate struct as required by kernel-3.3 + +Signed-off-by: Thomas Backlund + + b/drivers/gpu/drm/mach64/mach64_drv.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/mach64/mach64_drv.c ++++ b/drivers/gpu/drm/mach64/mach64_drv.c +@@ -39,6 +39,17 @@ static struct pci_device_id pciidlist[] + mach64_PCI_IDS + }; + ++static const struct file_operations mach64_driver_fops = { ++ .owner = THIS_MODULE, ++ .open = drm_open, ++ .release = drm_release, ++ .unlocked_ioctl = drm_ioctl, ++ .mmap = drm_mmap, ++ .poll = drm_poll, ++ .fasync = drm_fasync, ++ .llseek = noop_llseek, ++}; ++ + static struct drm_driver driver = { + .driver_features = + DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA +@@ -54,17 +65,7 @@ static struct drm_driver driver = { + .reclaim_buffers = drm_core_reclaim_buffers, + .ioctls = mach64_ioctls, + .dma_ioctl = mach64_dma_buffers, +- .fops = { +- .owner = THIS_MODULE, +- .open = drm_open, +- .release = drm_release, +- .unlocked_ioctl = drm_ioctl, +- .mmap = drm_mmap, +- .poll = drm_poll, +- .fasync = drm_fasync, +- .llseek = noop_llseek, +- }, +- ++ .fops = &mach64_driver_fops, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.6-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.6-buildfix.patch new file mode 100644 index 00000000..c7df6444 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.6-buildfix.patch @@ -0,0 +1,15 @@ + +reclaim_buffers is gone in 3.6 + +Signed-off-by: Thomas Backlund + +--- linux/drivers/gpu/drm/mach64/mach64_drv.c.orig 2012-10-17 22:26:58.000000000 +0300 ++++ linux/drivers/gpu/drm/mach64/mach64_drv.c 2012-10-17 23:05:10.212566630 +0300 +@@ -62,7 +62,6 @@ static struct drm_driver driver = { + .irq_postinstall = mach64_driver_irq_postinstall, + .irq_uninstall = mach64_driver_irq_uninstall, + .irq_handler = mach64_driver_irq_handler, +- .reclaim_buffers = drm_core_reclaim_buffers, + .ioctls = mach64_ioctls, + .dma_ioctl = mach64_dma_buffers, + .fops = &mach64_driver_fops, diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.7-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.7-buildfix.patch new file mode 100644 index 00000000..cc1c5b27 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-3.7-buildfix.patch @@ -0,0 +1,61 @@ +diff -Nurp linux-3.7-rc8/drivers/gpu/drm/mach64.orig/mach64_dma.c linux-3.7-rc8/drivers/gpu/drm/mach64/mach64_dma.c +--- linux-3.7-rc8/drivers/gpu/drm/mach64.orig/mach64_dma.c 2012-12-06 19:50:10.000000000 +0200 ++++ linux-3.7-rc8/drivers/gpu/drm/mach64/mach64_dma.c 2012-12-06 20:19:10.590681644 +0200 +@@ -34,8 +34,8 @@ + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +-#include "drmP.h" +-#include "drm.h" ++#include ++#include + #include "mach64_drm.h" + #include "mach64_drv.h" + +diff -Nurp linux-3.7-rc8/drivers/gpu/drm/mach64.orig/mach64_drv.c linux-3.7-rc8/drivers/gpu/drm/mach64/mach64_drv.c +--- linux-3.7-rc8/drivers/gpu/drm/mach64.orig/mach64_drv.c 2012-12-06 19:50:10.000000000 +0200 ++++ linux-3.7-rc8/drivers/gpu/drm/mach64/mach64_drv.c 2012-12-06 20:20:13.062073838 +0200 +@@ -28,12 +28,12 @@ + */ + + #include +-#include "drmP.h" +-#include "drm.h" ++#include ++#include + #include "mach64_drm.h" + #include "mach64_drv.h" + +-#include "drm_pciids.h" ++#include + + static struct pci_device_id pciidlist[] = { + mach64_PCI_IDS +diff -Nurp linux-3.7-rc8/drivers/gpu/drm/mach64.orig/mach64_irq.c linux-3.7-rc8/drivers/gpu/drm/mach64/mach64_irq.c +--- linux-3.7-rc8/drivers/gpu/drm/mach64.orig/mach64_irq.c 2012-12-06 19:50:10.000000000 +0200 ++++ linux-3.7-rc8/drivers/gpu/drm/mach64/mach64_irq.c 2012-12-06 20:20:40.192678476 +0200 +@@ -35,8 +35,8 @@ + * Leif Delgass + */ + +-#include "drmP.h" +-#include "drm.h" ++#include ++#include + #include "mach64_drm.h" + #include "mach64_drv.h" + +diff -Nurp linux-3.7-rc8/drivers/gpu/drm/mach64.orig/mach64_state.c linux-3.7-rc8/drivers/gpu/drm/mach64/mach64_state.c +--- linux-3.7-rc8/drivers/gpu/drm/mach64.orig/mach64_state.c 2012-12-06 19:50:10.000000000 +0200 ++++ linux-3.7-rc8/drivers/gpu/drm/mach64/mach64_state.c 2012-12-06 20:21:00.783137370 +0200 +@@ -30,8 +30,8 @@ + * José Fonseca + */ + +-#include "drmP.h" +-#include "drm.h" ++#include ++#include + #include "mach64_drm.h" + #include "mach64_drv.h" + diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-fix-for-changed-drm_ioctl.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-fix-for-changed-drm_ioctl.patch new file mode 100644 index 00000000..951eabb9 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-fix-for-changed-drm_ioctl.patch @@ -0,0 +1,20 @@ +Update mach64 for changes in drm_ioctl done in 2.6.33: +"drm: convert drm_ioctl to unlocked_ioctl" (commit ed8b670) + +Signed-off-by: Herton Ronaldo Krzesinski +--- + drivers/gpu/drm/mach64/mach64_drv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff -p -up linux-2.6.33/drivers/gpu/drm/mach64/mach64_drv.c.orig linux-2.6.33/drivers/gpu/drm/mach64/mach64_drv.c +--- linux-2.6.33/drivers/gpu/drm/mach64/mach64_drv.c.orig 2010-03-16 19:27:22.517068880 -0300 ++++ linux-2.6.33/drivers/gpu/drm/mach64/mach64_drv.c 2010-03-16 19:27:54.890318416 -0300 +@@ -59,7 +59,7 @@ static struct drm_driver driver = { + .owner = THIS_MODULE, + .open = drm_open, + .release = drm_release, +- .ioctl = drm_ioctl, ++ .unlocked_ioctl = drm_ioctl, + .mmap = drm_mmap, + .poll = drm_poll, + .fasync = drm_fasync, diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-fix-for-changed-drm_pci_alloc.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-fix-for-changed-drm_pci_alloc.patch new file mode 100644 index 00000000..b67cecab --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-fix-for-changed-drm_pci_alloc.patch @@ -0,0 +1,12 @@ +diff -p -up linux-2.6.32/drivers/gpu/drm/mach64/mach64_dma.c.orig linux-2.6.32/drivers/gpu/drm/mach64/mach64_dma.c +--- linux-2.6.32/drivers/gpu/drm/mach64/mach64_dma.c.orig 2010-01-06 11:35:13.784843304 -0200 ++++ linux-2.6.32/drivers/gpu/drm/mach64/mach64_dma.c 2010-01-06 11:37:50.793843502 -0200 +@@ -835,7 +835,7 @@ static int mach64_bm_dma_test(struct drm + /* FIXME: get a dma buffer from the freelist here */ + DRM_DEBUG("Allocating data memory ...\n"); + cpu_addr_dmah = +- drm_pci_alloc(dev, 0x1000, 0x1000, 0xfffffffful); ++ drm_pci_alloc(dev, 0x1000, 0x1000); + if (!cpu_addr_dmah) { + DRM_INFO("data-memory allocation failed!\n"); + return -ENOMEM; diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-fixes.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-fixes.patch new file mode 100644 index 00000000..0ea07cd7 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-fixes.patch @@ -0,0 +1,97 @@ +Fix/cleanup mach64 drm module for building with current kernel. + +Signed-off-by: Herton Ronaldo Krzesinski + +--- + drivers/gpu/drm/mach64/mach64_dma.c | 9 +-------- + drivers/gpu/drm/mach64/mach64_drv.c | 11 +---------- + drivers/gpu/drm/mach64/mach64_state.c | 4 ++-- + 3 files changed, 4 insertions(+), 20 deletions(-) + +diff -p -up linux-2.6.28/drivers/gpu/drm/mach64/mach64_dma.c.orig linux-2.6.28/drivers/gpu/drm/mach64/mach64_dma.c +--- linux-2.6.28/drivers/gpu/drm/mach64/mach64_dma.c.orig 2008-12-10 12:19:14.000000000 -0500 ++++ linux-2.6.28/drivers/gpu/drm/mach64/mach64_dma.c 2008-12-10 13:34:19.000000000 -0500 +@@ -834,14 +834,8 @@ static int mach64_bm_dma_test(struct drm + + /* FIXME: get a dma buffer from the freelist here */ + DRM_DEBUG("Allocating data memory ...\n"); +-#ifdef __FreeBSD__ +- DRM_UNLOCK(); +-#endif + cpu_addr_dmah = + drm_pci_alloc(dev, 0x1000, 0x1000, 0xfffffffful); +-#ifdef __FreeBSD__ +- DRM_LOCK(); +-#endif + if (!cpu_addr_dmah) { + DRM_INFO("data-memory allocation failed!\n"); + return -ENOMEM; +@@ -1375,8 +1369,7 @@ int mach64_do_cleanup_dma(struct drm_dev + * may not have been called from userspace and after dev_private + * is freed, it's too late. + */ +- if (dev->irq) +- drm_irq_uninstall(dev); ++ drm_irq_uninstall(dev); + + if (dev->dev_private) { + drm_mach64_private_t *dev_priv = dev->dev_private; +diff -p -up linux-2.6.28/drivers/gpu/drm/mach64/mach64_drv.c.orig linux-2.6.28/drivers/gpu/drm/mach64/mach64_drv.c +--- linux-2.6.28/drivers/gpu/drm/mach64/mach64_drv.c.orig 2008-12-10 12:13:13.000000000 -0500 ++++ linux-2.6.28/drivers/gpu/drm/mach64/mach64_drv.c 2008-12-10 12:16:54.000000000 -0500 +@@ -38,7 +38,6 @@ static struct pci_device_id pciidlist[] + mach64_PCI_IDS + }; + +-static int probe(struct pci_dev *pdev, const struct pci_device_id *ent); + static struct drm_driver driver = { + .driver_features = + DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA +@@ -68,8 +67,6 @@ static struct drm_driver driver = { + .pci_driver = { + .name = DRIVER_NAME, + .id_table = pciidlist, +- .probe = probe, +- .remove = __devexit_p(drm_cleanup_pci), + }, + + .name = DRIVER_NAME, +@@ -80,16 +77,10 @@ static struct drm_driver driver = { + .patchlevel = DRIVER_PATCHLEVEL, + }; + +-static int probe(struct pci_dev *pdev, const struct pci_device_id *ent) +-{ +- return drm_get_dev(pdev, ent, &driver); +-} +- +- + static int __init mach64_init(void) + { + driver.num_ioctls = mach64_max_ioctl; +- return drm_init(&driver, pciidlist); ++ return drm_init(&driver); + } + + static void __exit mach64_exit(void) +diff -p -up linux-2.6.28/drivers/gpu/drm/mach64/mach64_state.c.orig linux-2.6.28/drivers/gpu/drm/mach64/mach64_state.c +--- linux-2.6.28/drivers/gpu/drm/mach64/mach64_state.c.orig 2008-12-10 12:13:13.000000000 -0500 ++++ linux-2.6.28/drivers/gpu/drm/mach64/mach64_state.c 2008-12-10 13:38:54.000000000 -0500 +@@ -455,7 +455,7 @@ static int mach64_do_get_frames_queued(d + head = ring->head; + + start = (MACH64_MAX_QUEUED_FRAMES - +- DRM_MIN(MACH64_MAX_QUEUED_FRAMES, sarea_priv->frames_queued)); ++ min(MACH64_MAX_QUEUED_FRAMES, sarea_priv->frames_queued)); + + if (head == tail) { + sarea_priv->frames_queued = 0; +@@ -895,7 +895,7 @@ int mach64_get_param(struct drm_device * + value = mach64_do_get_frames_queued(dev_priv); + break; + case MACH64_PARAM_IRQ_NR: +- value = dev->irq; ++ value = drm_dev_to_irq(dev); + break; + default: + return -EINVAL; diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-include-module.h.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-include-module.h.patch new file mode 100644 index 00000000..9c1163d5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-include-module.h.patch @@ -0,0 +1,10 @@ +--- linux/drivers/gpu/drm/mach64/mach64_drv.c.orig 2011-12-25 00:48:42.814932355 +0200 ++++ linux/drivers/gpu/drm/mach64/mach64_drv.c 2011-12-25 00:47:43.393625260 +0200 +@@ -27,6 +27,7 @@ + * Leif Delgass + */ + ++#include + #include "drmP.h" + #include "drm.h" + #include "mach64_drm.h" diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch new file mode 100644 index 00000000..80010d3a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-linux-3.14-buildfix.patch @@ -0,0 +1,102 @@ + +Fix build with kernel-3.14 + +Signed-off-by: Thomas Backlund + + drivers/gpu/drm/mach64/mach64_dma.c | 10 +++++----- + drivers/gpu/drm/mach64/mach64_drv.h | 2 +- + drivers/gpu/drm/mach64/mach64_irq.c | 2 +- + drivers/gpu/drm/mach64/mach64_state.c | 6 +++--- + 4 files changed, 10 insertions(+), 10 deletions(-) + +diff -urp linux/drivers/gpu/drm/mach64.orig/mach64_dma.c linux/drivers/gpu/drm/mach64/mach64_dma.c +--- linux/drivers/gpu/drm/mach64.orig/mach64_dma.c 2014-04-26 19:10:55.000000000 +0300 ++++ linux/drivers/gpu/drm/mach64/mach64_dma.c 2014-04-26 20:26:05.263501325 +0300 +@@ -696,9 +696,9 @@ do { \ + DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ + _ring_write, _ring_tail ); \ + } \ +- DRM_MEMORYBARRIER(); \ ++ mb(); \ + mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] ); \ +- DRM_MEMORYBARRIER(); \ ++ mb(); \ + dev_priv->ring.tail = _ring_write; \ + mach64_ring_tick( dev_priv, &(dev_priv)->ring ); \ + } while (0) +@@ -912,7 +912,7 @@ static int mach64_bm_dma_test(struct drm + DRM_DEBUG(" data[%d] = 0x%08x\n", i, data[i]); + } + +- DRM_MEMORYBARRIER(); ++ mb(); + + DRM_DEBUG("waiting for idle...\n"); + if ((i = mach64_do_wait_for_idle(dev_priv))) { +@@ -1716,10 +1716,10 @@ static int mach64_dma_get_buffers(struct + + buf->file_priv = file_priv; + +- if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, ++ if (copy_to_user(&d->request_indices[i], &buf->idx, + sizeof(buf->idx))) + return -EFAULT; +- if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, ++ if (copy_to_user(&d->request_sizes[i], &buf->total, + sizeof(buf->total))) + return -EFAULT; + +diff -urp linux/drivers/gpu/drm/mach64.orig/mach64_drv.h linux/drivers/gpu/drm/mach64/mach64_drv.h +--- linux/drivers/gpu/drm/mach64.orig/mach64_drv.h 2014-04-26 19:10:55.000000000 +0300 ++++ linux/drivers/gpu/drm/mach64/mach64_drv.h 2014-04-26 20:28:43.693457652 +0300 +@@ -166,7 +166,7 @@ extern int mach64_get_param(struct drm_d + extern u32 mach64_get_vblank_counter(struct drm_device *dev, int crtc); + extern int mach64_enable_vblank(struct drm_device *dev, int crtc); + extern void mach64_disable_vblank(struct drm_device *dev, int crtc); +-extern irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS); ++extern irqreturn_t mach64_driver_irq_handler(int irq, void *arg); + extern void mach64_driver_irq_preinstall(struct drm_device *dev); + extern int mach64_driver_irq_postinstall(struct drm_device *dev); + extern void mach64_driver_irq_uninstall(struct drm_device *dev); +diff -urp linux/drivers/gpu/drm/mach64.orig/mach64_irq.c linux/drivers/gpu/drm/mach64/mach64_irq.c +--- linux/drivers/gpu/drm/mach64.orig/mach64_irq.c 2014-04-26 19:10:55.000000000 +0300 ++++ linux/drivers/gpu/drm/mach64/mach64_irq.c 2014-04-26 20:32:01.464898140 +0300 +@@ -40,7 +40,7 @@ + #include "mach64_drm.h" + #include "mach64_drv.h" + +-irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS) ++irqreturn_t mach64_driver_irq_handler(int irq, void *arg) + { + struct drm_device *dev = arg; + drm_mach64_private_t *dev_priv = dev->dev_private; +diff -urp linux/drivers/gpu/drm/mach64.orig/mach64_state.c linux/drivers/gpu/drm/mach64/mach64_state.c +--- linux/drivers/gpu/drm/mach64.orig/mach64_state.c 2014-04-26 19:10:55.000000000 +0300 ++++ linux/drivers/gpu/drm/mach64/mach64_state.c 2014-04-26 20:07:16.701527488 +0300 +@@ -494,7 +494,7 @@ static __inline__ int copy_from_user_ver + if (from == NULL) + return -ENOMEM; + +- if (DRM_COPY_FROM_USER(from, ufrom, bytes)) { ++ if (copy_from_user(from, ufrom, bytes)) { + kfree(from); + return -EFAULT; + } +@@ -640,7 +640,7 @@ static __inline__ int copy_from_user_bli + { + to = (u32 *)((char *)to + MACH64_HOSTDATA_BLIT_OFFSET); + +- if (DRM_COPY_FROM_USER(to, ufrom, bytes)) { ++ if (copy_from_user(to, ufrom, bytes)) { + return -EFAULT; + } + +@@ -901,7 +901,7 @@ int mach64_get_param(struct drm_device * + return -EINVAL; + } + +- if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { ++ if (copy_to_user(param->value, &value, sizeof(int))) { + DRM_ERROR("copy_to_user\n"); + return -EFAULT; + } diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64-restore-mach64_PCI_IDS.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-restore-mach64_PCI_IDS.patch new file mode 100644 index 00000000..651d7631 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64-restore-mach64_PCI_IDS.patch @@ -0,0 +1,38 @@ +Theese got dropped in 3.12-rc + +Restore for now to get the mach64 driver to build + +TODO: Need to check mesa & drm if it's dropped there too... + +--- linux/include/drm/drm_pciids.h.orig 2013-10-13 11:05:33.000000000 +0300 ++++ linux/include/drm/drm_pciids.h 2013-10-13 14:30:43.625995248 +0300 +@@ -711,6 +711,29 @@ + {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \ + {0, 0, 0} + ++#define mach64_PCI_IDS \ ++ {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4742, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4744, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4c49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4c50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4c51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4c42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4c44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x474c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x474f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x474d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x474e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4c52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ ++ {0, 0, 0} ++ + #define sisdrv_PCI_IDS \ + {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ diff --git a/kernel/kernel/files/patches/mageia/gpu-drm-mach64.patch b/kernel/kernel/files/patches/mageia/gpu-drm-mach64.patch new file mode 100644 index 00000000..be3e1631 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/gpu-drm-mach64.patch @@ -0,0 +1,4144 @@ +mach64 driver from git://anongit.freedesktop.org/git/mesa/drm +head: c99566fb810c9d8cae5e9cd39d1772b55e2f514c + +--- + drivers/gpu/drm/Kconfig | 11 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/mach64/Makefile | 8 + drivers/gpu/drm/Kconfig | 11 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/mach64/Makefile | 8 + drivers/gpu/drm/mach64/mach64_dma.c | 1778 ++++++++++++++++++++++++++++++++++ + drivers/gpu/drm/mach64/mach64_drm.h | 256 ++++ + drivers/gpu/drm/mach64/mach64_drv.c | 105 ++ + drivers/gpu/drm/mach64/mach64_drv.h | 859 ++++++++++++++++ + drivers/gpu/drm/mach64/mach64_irq.c | 159 +++ + drivers/gpu/drm/mach64/mach64_state.c | 910 +++++++++++++++++ + 9 files changed, 4087 insertions(+) + +--- /dev/null ++++ b/drivers/gpu/drm/mach64/Makefile +@@ -0,0 +1,8 @@ ++# ++# Makefile for the drm device driver. This driver provides support for the ++# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ++ ++ccflags-y = -Iinclude/drm ++mach64-y := mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o ++ ++obj-$(CONFIG_DRM_MACH64) += mach64.o +--- /dev/null ++++ b/drivers/gpu/drm/mach64/mach64_dma.c +@@ -0,0 +1,1778 @@ ++/* mach64_dma.c -- DMA support for mach64 (Rage Pro) driver -*- linux-c -*- */ ++/** ++ * \file mach64_dma.c ++ * DMA support for mach64 (Rage Pro) driver ++ * ++ * \author Gareth Hughes ++ * \author Frank C. Earl ++ * \author Leif Delgass ++ * \author José Fonseca ++ */ ++ ++/* ++ * Copyright 2000 Gareth Hughes ++ * Copyright 2002 Frank C. Earl ++ * Copyright 2002-2003 Leif Delgass ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT OWNER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ++ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "mach64_drm.h" ++#include "mach64_drv.h" ++ ++/*******************************************************************/ ++/** \name Engine, FIFO control */ ++/*@{*/ ++ ++/** ++ * Waits for free entries in the FIFO. ++ * ++ * \note Most writes to Mach64 registers are automatically routed through ++ * command FIFO which is 16 entry deep. Prior to writing to any draw engine ++ * register one has to ensure that enough FIFO entries are available by calling ++ * this function. Failure to do so may cause the engine to lock. ++ * ++ * \param dev_priv pointer to device private data structure. ++ * \param entries number of free entries in the FIFO to wait for. ++ * ++ * \returns zero on success, or -EBUSY if the timeout (specificed by ++ * drm_mach64_private::usec_timeout) occurs. ++ */ ++int mach64_do_wait_for_fifo(drm_mach64_private_t *dev_priv, int entries) ++{ ++ int slots = 0, i; ++ ++ for (i = 0; i < dev_priv->usec_timeout; i++) { ++ slots = (MACH64_READ(MACH64_FIFO_STAT) & MACH64_FIFO_SLOT_MASK); ++ if (slots <= (0x8000 >> entries)) ++ return 0; ++ DRM_UDELAY(1); ++ } ++ ++ DRM_INFO("failed! slots=%d entries=%d\n", slots, entries); ++ return -EBUSY; ++} ++ ++/** ++ * Wait for the draw engine to be idle. ++ */ ++int mach64_do_wait_for_idle(drm_mach64_private_t *dev_priv) ++{ ++ int i, ret; ++ ++ ret = mach64_do_wait_for_fifo(dev_priv, 16); ++ if (ret < 0) ++ return ret; ++ ++ for (i = 0; i < dev_priv->usec_timeout; i++) { ++ if (!(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE)) ++ return 0; ++ DRM_UDELAY(1); ++ } ++ ++ DRM_INFO("failed! GUI_STAT=0x%08x\n", MACH64_READ(MACH64_GUI_STAT)); ++ mach64_dump_ring_info(dev_priv); ++ return -EBUSY; ++} ++ ++/** ++ * Wait for free entries in the ring buffer. ++ * ++ * The Mach64 bus master can be configured to act as a virtual FIFO, using a ++ * circular buffer (commonly referred as "ring buffer" in other drivers) with ++ * pointers to engine commands. This allows the CPU to do other things while ++ * the graphics engine is busy, i.e., DMA mode. ++ * ++ * This function should be called before writing new entries to the ring ++ * buffer. ++ * ++ * \param dev_priv pointer to device private data structure. ++ * \param n number of free entries in the ring buffer to wait for. ++ * ++ * \returns zero on success, or -EBUSY if the timeout (specificed by ++ * drm_mach64_private_t::usec_timeout) occurs. ++ * ++ * \sa mach64_dump_ring_info() ++ */ ++int mach64_wait_ring(drm_mach64_private_t *dev_priv, int n) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ int i; ++ ++ for (i = 0; i < dev_priv->usec_timeout; i++) { ++ mach64_update_ring_snapshot(dev_priv); ++ if (ring->space >= n) { ++ if (i > 0) ++ DRM_DEBUG("%d usecs\n", i); ++ return 0; ++ } ++ DRM_UDELAY(1); ++ } ++ ++ /* FIXME: This is being ignored... */ ++ DRM_ERROR("failed!\n"); ++ mach64_dump_ring_info(dev_priv); ++ return -EBUSY; ++} ++ ++/** ++ * Wait until all DMA requests have been processed... ++ * ++ * \sa mach64_wait_ring() ++ */ ++static int mach64_ring_idle(drm_mach64_private_t *dev_priv) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ u32 head; ++ int i; ++ ++ head = ring->head; ++ i = 0; ++ while (i < dev_priv->usec_timeout) { ++ mach64_update_ring_snapshot(dev_priv); ++ if (ring->head == ring->tail && ++ !(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE)) { ++ if (i > 0) ++ DRM_DEBUG("%d usecs\n", i); ++ return 0; ++ } ++ if (ring->head == head) { ++ ++i; ++ } else { ++ head = ring->head; ++ i = 0; ++ } ++ DRM_UDELAY(1); ++ } ++ ++ DRM_INFO("failed! GUI_STAT=0x%08x\n", MACH64_READ(MACH64_GUI_STAT)); ++ mach64_dump_ring_info(dev_priv); ++ return -EBUSY; ++} ++ ++/** ++ * Reset the the ring buffer descriptors. ++ * ++ * \sa mach64_do_engine_reset() ++ */ ++static void mach64_ring_reset(drm_mach64_private_t *dev_priv) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ ++ mach64_do_release_used_buffers(dev_priv); ++ ring->head_addr = ring->start_addr; ++ ring->head = ring->tail = 0; ++ ring->space = ring->size; ++ ++ MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD, ++ ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB); ++ ++ dev_priv->ring_running = 0; ++} ++ ++/** ++ * Ensure the all the queued commands will be processed. ++ */ ++int mach64_do_dma_flush(drm_mach64_private_t *dev_priv) ++{ ++ /* FIXME: It's not necessary to wait for idle when flushing ++ * we just need to ensure the ring will be completely processed ++ * in finite time without another ioctl ++ */ ++ return mach64_ring_idle(dev_priv); ++} ++ ++/** ++ * Stop all DMA activity. ++ */ ++int mach64_do_dma_idle(drm_mach64_private_t *dev_priv) ++{ ++ int ret; ++ ++ /* wait for completion */ ++ if ((ret = mach64_ring_idle(dev_priv)) < 0) { ++ DRM_ERROR("failed BM_GUI_TABLE=0x%08x tail: %u\n", ++ MACH64_READ(MACH64_BM_GUI_TABLE), ++ dev_priv->ring.tail); ++ return ret; ++ } ++ ++ mach64_ring_stop(dev_priv); ++ ++ /* clean up after pass */ ++ mach64_do_release_used_buffers(dev_priv); ++ return 0; ++} ++ ++/** ++ * Reset the engine. This will stop the DMA if it is running. ++ */ ++int mach64_do_engine_reset(drm_mach64_private_t *dev_priv) ++{ ++ u32 tmp; ++ ++ DRM_DEBUG("\n"); ++ ++ /* Kill off any outstanding DMA transfers. ++ */ ++ tmp = MACH64_READ(MACH64_BUS_CNTL); ++ MACH64_WRITE(MACH64_BUS_CNTL, tmp | MACH64_BUS_MASTER_DIS); ++ ++ /* Reset the GUI engine (high to low transition). ++ */ ++ tmp = MACH64_READ(MACH64_GEN_TEST_CNTL); ++ MACH64_WRITE(MACH64_GEN_TEST_CNTL, tmp & ~MACH64_GUI_ENGINE_ENABLE); ++ /* Enable the GUI engine ++ */ ++ tmp = MACH64_READ(MACH64_GEN_TEST_CNTL); ++ MACH64_WRITE(MACH64_GEN_TEST_CNTL, tmp | MACH64_GUI_ENGINE_ENABLE); ++ ++ /* ensure engine is not locked up by clearing any FIFO or HOST errors ++ */ ++ tmp = MACH64_READ(MACH64_BUS_CNTL); ++ MACH64_WRITE(MACH64_BUS_CNTL, tmp | 0x00a00000); ++ ++ /* Once GUI engine is restored, disable bus mastering */ ++ MACH64_WRITE(MACH64_SRC_CNTL, 0); ++ ++ /* Reset descriptor ring */ ++ mach64_ring_reset(dev_priv); ++ ++ return 0; ++} ++ ++/*@}*/ ++ ++ ++/*******************************************************************/ ++/** \name Debugging output */ ++/*@{*/ ++ ++/** ++ * Dump engine registers values. ++ */ ++void mach64_dump_engine_info(drm_mach64_private_t *dev_priv) ++{ ++ DRM_INFO("\n"); ++ if (!dev_priv->is_pci) { ++ DRM_INFO(" AGP_BASE = 0x%08x\n", ++ MACH64_READ(MACH64_AGP_BASE)); ++ DRM_INFO(" AGP_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_AGP_CNTL)); ++ } ++ DRM_INFO(" ALPHA_TST_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_ALPHA_TST_CNTL)); ++ DRM_INFO("\n"); ++ DRM_INFO(" BM_COMMAND = 0x%08x\n", ++ MACH64_READ(MACH64_BM_COMMAND)); ++ DRM_INFO("BM_FRAME_BUF_OFFSET = 0x%08x\n", ++ MACH64_READ(MACH64_BM_FRAME_BUF_OFFSET)); ++ DRM_INFO(" BM_GUI_TABLE = 0x%08x\n", ++ MACH64_READ(MACH64_BM_GUI_TABLE)); ++ DRM_INFO(" BM_STATUS = 0x%08x\n", ++ MACH64_READ(MACH64_BM_STATUS)); ++ DRM_INFO(" BM_SYSTEM_MEM_ADDR = 0x%08x\n", ++ MACH64_READ(MACH64_BM_SYSTEM_MEM_ADDR)); ++ DRM_INFO(" BM_SYSTEM_TABLE = 0x%08x\n", ++ MACH64_READ(MACH64_BM_SYSTEM_TABLE)); ++ DRM_INFO(" BUS_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_BUS_CNTL)); ++ DRM_INFO("\n"); ++ /* DRM_INFO( " CLOCK_CNTL = 0x%08x\n", MACH64_READ( MACH64_CLOCK_CNTL ) ); */ ++ DRM_INFO(" CLR_CMP_CLR = 0x%08x\n", ++ MACH64_READ(MACH64_CLR_CMP_CLR)); ++ DRM_INFO(" CLR_CMP_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_CLR_CMP_CNTL)); ++ /* DRM_INFO( " CLR_CMP_MSK = 0x%08x\n", MACH64_READ( MACH64_CLR_CMP_MSK ) ); */ ++ DRM_INFO(" CONFIG_CHIP_ID = 0x%08x\n", ++ MACH64_READ(MACH64_CONFIG_CHIP_ID)); ++ DRM_INFO(" CONFIG_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_CONFIG_CNTL)); ++ DRM_INFO(" CONFIG_STAT0 = 0x%08x\n", ++ MACH64_READ(MACH64_CONFIG_STAT0)); ++ DRM_INFO(" CONFIG_STAT1 = 0x%08x\n", ++ MACH64_READ(MACH64_CONFIG_STAT1)); ++ DRM_INFO(" CONFIG_STAT2 = 0x%08x\n", ++ MACH64_READ(MACH64_CONFIG_STAT2)); ++ DRM_INFO(" CRC_SIG = 0x%08x\n", MACH64_READ(MACH64_CRC_SIG)); ++ DRM_INFO(" CUSTOM_MACRO_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_CUSTOM_MACRO_CNTL)); ++ DRM_INFO("\n"); ++ /* DRM_INFO( " DAC_CNTL = 0x%08x\n", MACH64_READ( MACH64_DAC_CNTL ) ); */ ++ /* DRM_INFO( " DAC_REGS = 0x%08x\n", MACH64_READ( MACH64_DAC_REGS ) ); */ ++ DRM_INFO(" DP_BKGD_CLR = 0x%08x\n", ++ MACH64_READ(MACH64_DP_BKGD_CLR)); ++ DRM_INFO(" DP_FRGD_CLR = 0x%08x\n", ++ MACH64_READ(MACH64_DP_FRGD_CLR)); ++ DRM_INFO(" DP_MIX = 0x%08x\n", MACH64_READ(MACH64_DP_MIX)); ++ DRM_INFO(" DP_PIX_WIDTH = 0x%08x\n", ++ MACH64_READ(MACH64_DP_PIX_WIDTH)); ++ DRM_INFO(" DP_SRC = 0x%08x\n", MACH64_READ(MACH64_DP_SRC)); ++ DRM_INFO(" DP_WRITE_MASK = 0x%08x\n", ++ MACH64_READ(MACH64_DP_WRITE_MASK)); ++ DRM_INFO(" DSP_CONFIG = 0x%08x\n", ++ MACH64_READ(MACH64_DSP_CONFIG)); ++ DRM_INFO(" DSP_ON_OFF = 0x%08x\n", ++ MACH64_READ(MACH64_DSP_ON_OFF)); ++ DRM_INFO(" DST_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_DST_CNTL)); ++ DRM_INFO(" DST_OFF_PITCH = 0x%08x\n", ++ MACH64_READ(MACH64_DST_OFF_PITCH)); ++ DRM_INFO("\n"); ++ /* DRM_INFO( " EXT_DAC_REGS = 0x%08x\n", MACH64_READ( MACH64_EXT_DAC_REGS ) ); */ ++ DRM_INFO(" EXT_MEM_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_EXT_MEM_CNTL)); ++ DRM_INFO("\n"); ++ DRM_INFO(" FIFO_STAT = 0x%08x\n", ++ MACH64_READ(MACH64_FIFO_STAT)); ++ DRM_INFO("\n"); ++ DRM_INFO(" GEN_TEST_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_GEN_TEST_CNTL)); ++ /* DRM_INFO( " GP_IO = 0x%08x\n", MACH64_READ( MACH64_GP_IO ) ); */ ++ DRM_INFO(" GUI_CMDFIFO_DATA = 0x%08x\n", ++ MACH64_READ(MACH64_GUI_CMDFIFO_DATA)); ++ DRM_INFO(" GUI_CMDFIFO_DEBUG = 0x%08x\n", ++ MACH64_READ(MACH64_GUI_CMDFIFO_DEBUG)); ++ DRM_INFO(" GUI_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_GUI_CNTL)); ++ DRM_INFO(" GUI_STAT = 0x%08x\n", ++ MACH64_READ(MACH64_GUI_STAT)); ++ DRM_INFO(" GUI_TRAJ_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_GUI_TRAJ_CNTL)); ++ DRM_INFO("\n"); ++ DRM_INFO(" HOST_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_HOST_CNTL)); ++ DRM_INFO(" HW_DEBUG = 0x%08x\n", ++ MACH64_READ(MACH64_HW_DEBUG)); ++ DRM_INFO("\n"); ++ DRM_INFO(" MEM_ADDR_CONFIG = 0x%08x\n", ++ MACH64_READ(MACH64_MEM_ADDR_CONFIG)); ++ DRM_INFO(" MEM_BUF_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_MEM_BUF_CNTL)); ++ DRM_INFO("\n"); ++ DRM_INFO(" PAT_REG0 = 0x%08x\n", ++ MACH64_READ(MACH64_PAT_REG0)); ++ DRM_INFO(" PAT_REG1 = 0x%08x\n", ++ MACH64_READ(MACH64_PAT_REG1)); ++ DRM_INFO("\n"); ++ DRM_INFO(" SC_LEFT = 0x%08x\n", MACH64_READ(MACH64_SC_LEFT)); ++ DRM_INFO(" SC_RIGHT = 0x%08x\n", ++ MACH64_READ(MACH64_SC_RIGHT)); ++ DRM_INFO(" SC_TOP = 0x%08x\n", MACH64_READ(MACH64_SC_TOP)); ++ DRM_INFO(" SC_BOTTOM = 0x%08x\n", ++ MACH64_READ(MACH64_SC_BOTTOM)); ++ DRM_INFO("\n"); ++ DRM_INFO(" SCALE_3D_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_SCALE_3D_CNTL)); ++ DRM_INFO(" SCRATCH_REG0 = 0x%08x\n", ++ MACH64_READ(MACH64_SCRATCH_REG0)); ++ DRM_INFO(" SCRATCH_REG1 = 0x%08x\n", ++ MACH64_READ(MACH64_SCRATCH_REG1)); ++ DRM_INFO(" SETUP_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_SETUP_CNTL)); ++ DRM_INFO(" SRC_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_SRC_CNTL)); ++ DRM_INFO("\n"); ++ DRM_INFO(" TEX_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_TEX_CNTL)); ++ DRM_INFO(" TEX_SIZE_PITCH = 0x%08x\n", ++ MACH64_READ(MACH64_TEX_SIZE_PITCH)); ++ DRM_INFO(" TIMER_CONFIG = 0x%08x\n", ++ MACH64_READ(MACH64_TIMER_CONFIG)); ++ DRM_INFO("\n"); ++ DRM_INFO(" Z_CNTL = 0x%08x\n", MACH64_READ(MACH64_Z_CNTL)); ++ DRM_INFO(" Z_OFF_PITCH = 0x%08x\n", ++ MACH64_READ(MACH64_Z_OFF_PITCH)); ++ DRM_INFO("\n"); ++} ++ ++#define MACH64_DUMP_CONTEXT 3 ++ ++/** ++ * Used by mach64_dump_ring_info() to dump the contents of the current buffer ++ * pointed by the ring head. ++ */ ++static void mach64_dump_buf_info(drm_mach64_private_t *dev_priv, ++ struct drm_buf *buf) ++{ ++ u32 addr = GETBUFADDR(buf); ++ u32 used = buf->used >> 2; ++ u32 sys_addr = MACH64_READ(MACH64_BM_SYSTEM_MEM_ADDR); ++ u32 *p = GETBUFPTR(buf); ++ int skipped = 0; ++ ++ DRM_INFO("buffer contents:\n"); ++ ++ while (used) { ++ u32 reg, count; ++ ++ reg = le32_to_cpu(*p++); ++ if (addr <= GETBUFADDR(buf) + MACH64_DUMP_CONTEXT * 4 || ++ (addr >= sys_addr - MACH64_DUMP_CONTEXT * 4 && ++ addr <= sys_addr + MACH64_DUMP_CONTEXT * 4) || ++ addr >= ++ GETBUFADDR(buf) + buf->used - MACH64_DUMP_CONTEXT * 4) { ++ DRM_INFO("%08x: 0x%08x\n", addr, reg); ++ } ++ addr += 4; ++ used--; ++ ++ count = (reg >> 16) + 1; ++ reg = reg & 0xffff; ++ reg = MMSELECT(reg); ++ while (count && used) { ++ if (addr <= GETBUFADDR(buf) + MACH64_DUMP_CONTEXT * 4 || ++ (addr >= sys_addr - MACH64_DUMP_CONTEXT * 4 && ++ addr <= sys_addr + MACH64_DUMP_CONTEXT * 4) || ++ addr >= ++ GETBUFADDR(buf) + buf->used - ++ MACH64_DUMP_CONTEXT * 4) { ++ DRM_INFO("%08x: 0x%04x = 0x%08x\n", addr, ++ reg, le32_to_cpu(*p)); ++ skipped = 0; ++ } else { ++ if (!skipped) { ++ DRM_INFO(" ...\n"); ++ skipped = 1; ++ } ++ } ++ p++; ++ addr += 4; ++ used--; ++ ++ reg += 4; ++ count--; ++ } ++ } ++ ++ DRM_INFO("\n"); ++} ++ ++/** ++ * Dump the ring state and contents, including the contents of the buffer being ++ * processed by the graphics engine. ++ */ ++void mach64_dump_ring_info(drm_mach64_private_t *dev_priv) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ int i, skipped; ++ ++ DRM_INFO("\n"); ++ ++ DRM_INFO("ring contents:\n"); ++ DRM_INFO(" head_addr: 0x%08x head: %u tail: %u\n\n", ++ ring->head_addr, ring->head, ring->tail); ++ ++ skipped = 0; ++ for (i = 0; i < ring->size / sizeof(u32); i += 4) { ++ if (i <= MACH64_DUMP_CONTEXT * 4 || ++ i >= ring->size / sizeof(u32) - MACH64_DUMP_CONTEXT * 4 || ++ (i >= ring->tail - MACH64_DUMP_CONTEXT * 4 && ++ i <= ring->tail + MACH64_DUMP_CONTEXT * 4) || ++ (i >= ring->head - MACH64_DUMP_CONTEXT * 4 && ++ i <= ring->head + MACH64_DUMP_CONTEXT * 4)) { ++ DRM_INFO(" 0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x%s%s\n", ++ (u32)(ring->start_addr + i * sizeof(u32)), ++ le32_to_cpu(((u32 *) ring->start)[i + 0]), ++ le32_to_cpu(((u32 *) ring->start)[i + 1]), ++ le32_to_cpu(((u32 *) ring->start)[i + 2]), ++ le32_to_cpu(((u32 *) ring->start)[i + 3]), ++ i == ring->head ? " (head)" : "", ++ i == ring->tail ? " (tail)" : ""); ++ skipped = 0; ++ } else { ++ if (!skipped) { ++ DRM_INFO(" ...\n"); ++ skipped = 1; ++ } ++ } ++ } ++ ++ DRM_INFO("\n"); ++ ++ if (ring->head >= 0 && ring->head < ring->size / sizeof(u32)) { ++ struct list_head *ptr; ++ u32 addr = le32_to_cpu(((u32 *) ring->start)[ring->head + 1]); ++ ++ list_for_each(ptr, &dev_priv->pending) { ++ drm_mach64_freelist_t *entry = ++ list_entry(ptr, drm_mach64_freelist_t, list); ++ struct drm_buf *buf = entry->buf; ++ ++ u32 buf_addr = GETBUFADDR(buf); ++ ++ if (buf_addr <= addr && addr < buf_addr + buf->used) ++ mach64_dump_buf_info(dev_priv, buf); ++ } ++ } ++ ++ DRM_INFO("\n"); ++ DRM_INFO(" BM_GUI_TABLE = 0x%08x\n", ++ MACH64_READ(MACH64_BM_GUI_TABLE)); ++ DRM_INFO("\n"); ++ DRM_INFO("BM_FRAME_BUF_OFFSET = 0x%08x\n", ++ MACH64_READ(MACH64_BM_FRAME_BUF_OFFSET)); ++ DRM_INFO(" BM_SYSTEM_MEM_ADDR = 0x%08x\n", ++ MACH64_READ(MACH64_BM_SYSTEM_MEM_ADDR)); ++ DRM_INFO(" BM_COMMAND = 0x%08x\n", ++ MACH64_READ(MACH64_BM_COMMAND)); ++ DRM_INFO("\n"); ++ DRM_INFO(" BM_STATUS = 0x%08x\n", ++ MACH64_READ(MACH64_BM_STATUS)); ++ DRM_INFO(" BUS_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_BUS_CNTL)); ++ DRM_INFO(" FIFO_STAT = 0x%08x\n", ++ MACH64_READ(MACH64_FIFO_STAT)); ++ DRM_INFO(" GUI_STAT = 0x%08x\n", ++ MACH64_READ(MACH64_GUI_STAT)); ++ DRM_INFO(" SRC_CNTL = 0x%08x\n", ++ MACH64_READ(MACH64_SRC_CNTL)); ++} ++ ++/*@}*/ ++ ++ ++/*******************************************************************/ ++/** \name DMA descriptor ring macros */ ++/*@{*/ ++ ++/** ++ * Add the end mark to the ring's new tail position. ++ * ++ * The bus master engine will keep processing the DMA buffers listed in the ring ++ * until it finds this mark, making it stop. ++ * ++ * \sa mach64_clear_dma_eol ++ */ ++static __inline__ void mach64_set_dma_eol(volatile u32 *addr) ++{ ++#if defined(__i386__) ++ int nr = 31; ++ ++ /* Taken from include/asm-i386/bitops.h linux header */ ++ __asm__ __volatile__("lock;" "btsl %1,%0":"=m"(*addr) ++ :"Ir"(nr)); ++#elif defined(__powerpc__) ++ u32 old; ++ u32 mask = cpu_to_le32(MACH64_DMA_EOL); ++ ++ /* Taken from the include/asm-ppc/bitops.h linux header */ ++ __asm__ __volatile__("\n\ ++1: lwarx %0,0,%3 \n\ ++ or %0,%0,%2 \n\ ++ stwcx. %0,0,%3 \n\ ++ bne- 1b":"=&r"(old), "=m"(*addr) ++ :"r"(mask), "r"(addr), "m"(*addr) ++ :"cc"); ++#elif defined(__alpha__) ++ u32 temp; ++ u32 mask = MACH64_DMA_EOL; ++ ++ /* Taken from the include/asm-alpha/bitops.h linux header */ ++ __asm__ __volatile__("1: ldl_l %0,%3\n" ++ " bis %0,%2,%0\n" ++ " stl_c %0,%1\n" ++ " beq %0,2f\n" ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous":"=&r"(temp), "=m"(*addr) ++ :"Ir"(mask), "m"(*addr)); ++#else ++ u32 mask = cpu_to_le32(MACH64_DMA_EOL); ++ ++ *addr |= mask; ++#endif ++} ++ ++/** ++ * Remove the end mark from the ring's old tail position. ++ * ++ * It should be called after calling mach64_set_dma_eol to mark the ring's new ++ * tail position. ++ * ++ * We update the end marks while the bus master engine is in operation. Since ++ * the bus master engine may potentially be reading from the same position ++ * that we write, we must change atomically to avoid having intermediary bad ++ * data. ++ */ ++static __inline__ void mach64_clear_dma_eol(volatile u32 *addr) ++{ ++#if defined(__i386__) ++ int nr = 31; ++ ++ /* Taken from include/asm-i386/bitops.h linux header */ ++ __asm__ __volatile__("lock;" "btrl %1,%0":"=m"(*addr) ++ :"Ir"(nr)); ++#elif defined(__powerpc__) ++ u32 old; ++ u32 mask = cpu_to_le32(MACH64_DMA_EOL); ++ ++ /* Taken from the include/asm-ppc/bitops.h linux header */ ++ __asm__ __volatile__("\n\ ++1: lwarx %0,0,%3 \n\ ++ andc %0,%0,%2 \n\ ++ stwcx. %0,0,%3 \n\ ++ bne- 1b":"=&r"(old), "=m"(*addr) ++ :"r"(mask), "r"(addr), "m"(*addr) ++ :"cc"); ++#elif defined(__alpha__) ++ u32 temp; ++ u32 mask = ~MACH64_DMA_EOL; ++ ++ /* Taken from the include/asm-alpha/bitops.h linux header */ ++ __asm__ __volatile__("1: ldl_l %0,%3\n" ++ " and %0,%2,%0\n" ++ " stl_c %0,%1\n" ++ " beq %0,2f\n" ++ ".subsection 2\n" ++ "2: br 1b\n" ++ ".previous":"=&r"(temp), "=m"(*addr) ++ :"Ir"(mask), "m"(*addr)); ++#else ++ u32 mask = cpu_to_le32(~MACH64_DMA_EOL); ++ ++ *addr &= mask; ++#endif ++} ++ ++#define RING_LOCALS \ ++ int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring ++ ++#define RING_WRITE_OFS _ring_write ++ ++#define BEGIN_RING(n) \ ++ do { \ ++ if (MACH64_VERBOSE) { \ ++ DRM_INFO( "BEGIN_RING( %d ) \n", \ ++ (n) ); \ ++ } \ ++ if (dev_priv->ring.space <= (n) * sizeof(u32)) { \ ++ int ret; \ ++ if ((ret = mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) { \ ++ DRM_ERROR( "wait_ring failed, resetting engine\n"); \ ++ mach64_dump_engine_info( dev_priv ); \ ++ mach64_do_engine_reset( dev_priv ); \ ++ return ret; \ ++ } \ ++ } \ ++ dev_priv->ring.space -= (n) * sizeof(u32); \ ++ _ring = (u32 *) dev_priv->ring.start; \ ++ _ring_tail = _ring_write = dev_priv->ring.tail; \ ++ _ring_mask = dev_priv->ring.tail_mask; \ ++ } while (0) ++ ++#define OUT_RING( x ) \ ++do { \ ++ if (MACH64_VERBOSE) { \ ++ DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ ++ (unsigned int)(x), _ring_write ); \ ++ } \ ++ _ring[_ring_write++] = cpu_to_le32( x ); \ ++ _ring_write &= _ring_mask; \ ++} while (0) ++ ++#define ADVANCE_RING() \ ++do { \ ++ if (MACH64_VERBOSE) { \ ++ DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \ ++ _ring_write, _ring_tail ); \ ++ } \ ++ DRM_MEMORYBARRIER(); \ ++ mach64_clear_dma_eol( &_ring[(_ring_tail - 2) & _ring_mask] ); \ ++ DRM_MEMORYBARRIER(); \ ++ dev_priv->ring.tail = _ring_write; \ ++ mach64_ring_tick( dev_priv, &(dev_priv)->ring ); \ ++} while (0) ++ ++/** ++ * Queue a DMA buffer of registers writes into the ring buffer. ++ */ ++int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv, ++ drm_mach64_freelist_t *entry) ++{ ++ int bytes, pages, remainder; ++ u32 address, page; ++ int i; ++ struct drm_buf *buf = entry->buf; ++ RING_LOCALS; ++ ++ bytes = buf->used; ++ address = GETBUFADDR( buf ); ++ pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE; ++ ++ BEGIN_RING( pages * 4 ); ++ ++ for ( i = 0 ; i < pages-1 ; i++ ) { ++ page = address + i * MACH64_DMA_CHUNKSIZE; ++ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); ++ OUT_RING( page ); ++ OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET ); ++ OUT_RING( 0 ); ++ } ++ ++ /* generate the final descriptor for any remaining commands in this buffer */ ++ page = address + i * MACH64_DMA_CHUNKSIZE; ++ remainder = bytes - i * MACH64_DMA_CHUNKSIZE; ++ ++ /* Save dword offset of last descriptor for this buffer. ++ * This is needed to check for completion of the buffer in freelist_get ++ */ ++ entry->ring_ofs = RING_WRITE_OFS; ++ ++ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); ++ OUT_RING( page ); ++ OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL ); ++ OUT_RING( 0 ); ++ ++ ADVANCE_RING(); ++ ++ return 0; ++} ++ ++/** ++ * Queue DMA buffer controlling host data tranfers (e.g., blit). ++ * ++ * Almost identical to mach64_add_buf_to_ring. ++ */ ++int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv, ++ drm_mach64_freelist_t *entry) ++{ ++ int bytes, pages, remainder; ++ u32 address, page; ++ int i; ++ struct drm_buf *buf = entry->buf; ++ RING_LOCALS; ++ ++ bytes = buf->used - MACH64_HOSTDATA_BLIT_OFFSET; ++ pages = (bytes + MACH64_DMA_CHUNKSIZE - 1) / MACH64_DMA_CHUNKSIZE; ++ address = GETBUFADDR( buf ); ++ ++ BEGIN_RING( 4 + pages * 4 ); ++ ++ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_ADDR ); ++ OUT_RING( address ); ++ OUT_RING( MACH64_HOSTDATA_BLIT_OFFSET | MACH64_DMA_HOLD_OFFSET ); ++ OUT_RING( 0 ); ++ address += MACH64_HOSTDATA_BLIT_OFFSET; ++ ++ for ( i = 0 ; i < pages-1 ; i++ ) { ++ page = address + i * MACH64_DMA_CHUNKSIZE; ++ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA ); ++ OUT_RING( page ); ++ OUT_RING( MACH64_DMA_CHUNKSIZE | MACH64_DMA_HOLD_OFFSET ); ++ OUT_RING( 0 ); ++ } ++ ++ /* generate the final descriptor for any remaining commands in this buffer */ ++ page = address + i * MACH64_DMA_CHUNKSIZE; ++ remainder = bytes - i * MACH64_DMA_CHUNKSIZE; ++ ++ /* Save dword offset of last descriptor for this buffer. ++ * This is needed to check for completion of the buffer in freelist_get ++ */ ++ entry->ring_ofs = RING_WRITE_OFS; ++ ++ OUT_RING( MACH64_APERTURE_OFFSET + MACH64_BM_HOSTDATA ); ++ OUT_RING( page ); ++ OUT_RING( remainder | MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL ); ++ OUT_RING( 0 ); ++ ++ ADVANCE_RING(); ++ ++ return 0; ++} ++ ++/*@}*/ ++ ++ ++/*******************************************************************/ ++/** \name DMA test and initialization */ ++/*@{*/ ++ ++/** ++ * Perform a simple DMA operation using the pattern registers to test whether ++ * DMA works. ++ * ++ * \return zero if successful. ++ * ++ * \note This function was the testbed for many experiences regarding Mach64 ++ * DMA operation. It is left here since it so tricky to get DMA operating ++ * properly in some architectures and hardware. ++ */ ++static int mach64_bm_dma_test(struct drm_device * dev) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_dma_handle_t *cpu_addr_dmah; ++ u32 data_addr; ++ u32 *table, *data; ++ u32 expected[2]; ++ u32 src_cntl, pat_reg0, pat_reg1; ++ int i, count, failed; ++ ++ DRM_DEBUG("\n"); ++ ++ table = (u32 *) dev_priv->ring.start; ++ ++ /* FIXME: get a dma buffer from the freelist here */ ++ DRM_DEBUG("Allocating data memory ...\n"); ++#ifdef __FreeBSD__ ++ DRM_UNLOCK(); ++#endif ++ cpu_addr_dmah = ++ drm_pci_alloc(dev, 0x1000, 0x1000, 0xfffffffful); ++#ifdef __FreeBSD__ ++ DRM_LOCK(); ++#endif ++ if (!cpu_addr_dmah) { ++ DRM_INFO("data-memory allocation failed!\n"); ++ return -ENOMEM; ++ } else { ++ data = (u32 *) cpu_addr_dmah->vaddr; ++ data_addr = (u32) cpu_addr_dmah->busaddr; ++ } ++ ++ /* Save the X server's value for SRC_CNTL and restore it ++ * in case our test fails. This prevents the X server ++ * from disabling it's cache for this register ++ */ ++ src_cntl = MACH64_READ(MACH64_SRC_CNTL); ++ pat_reg0 = MACH64_READ(MACH64_PAT_REG0); ++ pat_reg1 = MACH64_READ(MACH64_PAT_REG1); ++ ++ mach64_do_wait_for_fifo(dev_priv, 3); ++ ++ MACH64_WRITE(MACH64_SRC_CNTL, 0); ++ MACH64_WRITE(MACH64_PAT_REG0, 0x11111111); ++ MACH64_WRITE(MACH64_PAT_REG1, 0x11111111); ++ ++ mach64_do_wait_for_idle(dev_priv); ++ ++ for (i = 0; i < 2; i++) { ++ u32 reg; ++ reg = MACH64_READ((MACH64_PAT_REG0 + i * 4)); ++ DRM_DEBUG("(Before DMA Transfer) reg %d = 0x%08x\n", i, reg); ++ if (reg != 0x11111111) { ++ DRM_INFO("Error initializing test registers\n"); ++ DRM_INFO("resetting engine ...\n"); ++ mach64_do_engine_reset(dev_priv); ++ DRM_INFO("freeing data buffer memory.\n"); ++ drm_pci_free(dev, cpu_addr_dmah); ++ return -EIO; ++ } ++ } ++ ++ /* fill up a buffer with sets of 2 consecutive writes starting with PAT_REG0 */ ++ count = 0; ++ ++ data[count++] = cpu_to_le32(DMAREG(MACH64_PAT_REG0) | (1 << 16)); ++ data[count++] = expected[0] = 0x22222222; ++ data[count++] = expected[1] = 0xaaaaaaaa; ++ ++ while (count < 1020) { ++ data[count++] = ++ cpu_to_le32(DMAREG(MACH64_PAT_REG0) | (1 << 16)); ++ data[count++] = 0x22222222; ++ data[count++] = 0xaaaaaaaa; ++ } ++ data[count++] = cpu_to_le32(DMAREG(MACH64_SRC_CNTL) | (0 << 16)); ++ data[count++] = 0; ++ ++ DRM_DEBUG("Preparing table ...\n"); ++ table[MACH64_DMA_FRAME_BUF_OFFSET] = cpu_to_le32(MACH64_BM_ADDR + ++ MACH64_APERTURE_OFFSET); ++ table[MACH64_DMA_SYS_MEM_ADDR] = cpu_to_le32(data_addr); ++ table[MACH64_DMA_COMMAND] = cpu_to_le32(count * sizeof(u32) ++ | MACH64_DMA_HOLD_OFFSET ++ | MACH64_DMA_EOL); ++ table[MACH64_DMA_RESERVED] = 0; ++ ++ DRM_DEBUG("table[0] = 0x%08x\n", table[0]); ++ DRM_DEBUG("table[1] = 0x%08x\n", table[1]); ++ DRM_DEBUG("table[2] = 0x%08x\n", table[2]); ++ DRM_DEBUG("table[3] = 0x%08x\n", table[3]); ++ ++ for (i = 0; i < 6; i++) { ++ DRM_DEBUG(" data[%d] = 0x%08x\n", i, data[i]); ++ } ++ DRM_DEBUG(" ...\n"); ++ for (i = count - 5; i < count; i++) { ++ DRM_DEBUG(" data[%d] = 0x%08x\n", i, data[i]); ++ } ++ ++ DRM_MEMORYBARRIER(); ++ ++ DRM_DEBUG("waiting for idle...\n"); ++ if ((i = mach64_do_wait_for_idle(dev_priv))) { ++ DRM_INFO("mach64_do_wait_for_idle failed (result=%d)\n", i); ++ DRM_INFO("resetting engine ...\n"); ++ mach64_do_engine_reset(dev_priv); ++ mach64_do_wait_for_fifo(dev_priv, 3); ++ MACH64_WRITE(MACH64_SRC_CNTL, src_cntl); ++ MACH64_WRITE(MACH64_PAT_REG0, pat_reg0); ++ MACH64_WRITE(MACH64_PAT_REG1, pat_reg1); ++ DRM_INFO("freeing data buffer memory.\n"); ++ drm_pci_free(dev, cpu_addr_dmah); ++ return i; ++ } ++ DRM_DEBUG("waiting for idle...done\n"); ++ ++ DRM_DEBUG("BUS_CNTL = 0x%08x\n", MACH64_READ(MACH64_BUS_CNTL)); ++ DRM_DEBUG("SRC_CNTL = 0x%08x\n", MACH64_READ(MACH64_SRC_CNTL)); ++ DRM_DEBUG("\n"); ++ DRM_DEBUG("data bus addr = 0x%08x\n", data_addr); ++ DRM_DEBUG("table bus addr = 0x%08x\n", dev_priv->ring.start_addr); ++ ++ DRM_DEBUG("starting DMA transfer...\n"); ++ MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD, ++ dev_priv->ring.start_addr | MACH64_CIRCULAR_BUF_SIZE_16KB); ++ ++ MACH64_WRITE(MACH64_SRC_CNTL, ++ MACH64_SRC_BM_ENABLE | MACH64_SRC_BM_SYNC | ++ MACH64_SRC_BM_OP_SYSTEM_TO_REG); ++ ++ /* Kick off the transfer */ ++ DRM_DEBUG("starting DMA transfer... done.\n"); ++ MACH64_WRITE(MACH64_DST_HEIGHT_WIDTH, 0); ++ ++ DRM_DEBUG("waiting for idle...\n"); ++ ++ if ((i = mach64_do_wait_for_idle(dev_priv))) { ++ /* engine locked up, dump register state and reset */ ++ DRM_INFO("mach64_do_wait_for_idle failed (result=%d)\n", i); ++ mach64_dump_engine_info(dev_priv); ++ DRM_INFO("resetting engine ...\n"); ++ mach64_do_engine_reset(dev_priv); ++ mach64_do_wait_for_fifo(dev_priv, 3); ++ MACH64_WRITE(MACH64_SRC_CNTL, src_cntl); ++ MACH64_WRITE(MACH64_PAT_REG0, pat_reg0); ++ MACH64_WRITE(MACH64_PAT_REG1, pat_reg1); ++ DRM_INFO("freeing data buffer memory.\n"); ++ drm_pci_free(dev, cpu_addr_dmah); ++ return i; ++ } ++ ++ DRM_DEBUG("waiting for idle...done\n"); ++ ++ /* restore SRC_CNTL */ ++ mach64_do_wait_for_fifo(dev_priv, 1); ++ MACH64_WRITE(MACH64_SRC_CNTL, src_cntl); ++ ++ failed = 0; ++ ++ /* Check register values to see if the GUI master operation succeeded */ ++ for (i = 0; i < 2; i++) { ++ u32 reg; ++ reg = MACH64_READ((MACH64_PAT_REG0 + i * 4)); ++ DRM_DEBUG("(After DMA Transfer) reg %d = 0x%08x\n", i, reg); ++ if (reg != expected[i]) { ++ failed = -1; ++ } ++ } ++ ++ /* restore pattern registers */ ++ mach64_do_wait_for_fifo(dev_priv, 2); ++ MACH64_WRITE(MACH64_PAT_REG0, pat_reg0); ++ MACH64_WRITE(MACH64_PAT_REG1, pat_reg1); ++ ++ DRM_DEBUG("freeing data buffer memory.\n"); ++ drm_pci_free(dev, cpu_addr_dmah); ++ DRM_DEBUG("returning ...\n"); ++ ++ return failed; ++} ++ ++/** ++ * Called during the DMA initialization ioctl to initialize all the necessary ++ * software and hardware state for DMA operation. ++ */ ++static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init) ++{ ++ drm_mach64_private_t *dev_priv; ++ u32 tmp; ++ int i, ret; ++ ++ DRM_DEBUG("\n"); ++ ++ dev_priv = drm_alloc(sizeof(drm_mach64_private_t), DRM_MEM_DRIVER); ++ if (dev_priv == NULL) ++ return -ENOMEM; ++ ++ memset(dev_priv, 0, sizeof(drm_mach64_private_t)); ++ ++ dev_priv->is_pci = init->is_pci; ++ ++ dev_priv->fb_bpp = init->fb_bpp; ++ dev_priv->front_offset = init->front_offset; ++ dev_priv->front_pitch = init->front_pitch; ++ dev_priv->back_offset = init->back_offset; ++ dev_priv->back_pitch = init->back_pitch; ++ ++ dev_priv->depth_bpp = init->depth_bpp; ++ dev_priv->depth_offset = init->depth_offset; ++ dev_priv->depth_pitch = init->depth_pitch; ++ ++ dev_priv->front_offset_pitch = (((dev_priv->front_pitch / 8) << 22) | ++ (dev_priv->front_offset >> 3)); ++ dev_priv->back_offset_pitch = (((dev_priv->back_pitch / 8) << 22) | ++ (dev_priv->back_offset >> 3)); ++ dev_priv->depth_offset_pitch = (((dev_priv->depth_pitch / 8) << 22) | ++ (dev_priv->depth_offset >> 3)); ++ ++ dev_priv->usec_timeout = 1000000; ++ ++ /* Set up the freelist, placeholder list and pending list */ ++ INIT_LIST_HEAD(&dev_priv->free_list); ++ INIT_LIST_HEAD(&dev_priv->placeholders); ++ INIT_LIST_HEAD(&dev_priv->pending); ++ ++ dev_priv->sarea = drm_getsarea(dev); ++ if (!dev_priv->sarea) { ++ DRM_ERROR("can not find sarea!\n"); ++ dev->dev_private = (void *)dev_priv; ++ mach64_do_cleanup_dma(dev); ++ return -EINVAL; ++ } ++ dev_priv->fb = drm_core_findmap(dev, init->fb_offset); ++ if (!dev_priv->fb) { ++ DRM_ERROR("can not find frame buffer map!\n"); ++ dev->dev_private = (void *)dev_priv; ++ mach64_do_cleanup_dma(dev); ++ return -EINVAL; ++ } ++ dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset); ++ if (!dev_priv->mmio) { ++ DRM_ERROR("can not find mmio map!\n"); ++ dev->dev_private = (void *)dev_priv; ++ mach64_do_cleanup_dma(dev); ++ return -EINVAL; ++ } ++ ++ dev_priv->ring_map = drm_core_findmap(dev, init->ring_offset); ++ if (!dev_priv->ring_map) { ++ DRM_ERROR("can not find ring map!\n"); ++ dev->dev_private = (void *)dev_priv; ++ mach64_do_cleanup_dma(dev); ++ return -EINVAL; ++ } ++ ++ dev_priv->sarea_priv = (drm_mach64_sarea_t *) ++ ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset); ++ ++ if (!dev_priv->is_pci) { ++ drm_core_ioremap(dev_priv->ring_map, dev); ++ if (!dev_priv->ring_map->handle) { ++ DRM_ERROR("can not ioremap virtual address for" ++ " descriptor ring\n"); ++ dev->dev_private = (void *)dev_priv; ++ mach64_do_cleanup_dma(dev); ++ return -ENOMEM; ++ } ++ dev->agp_buffer_token = init->buffers_offset; ++ dev->agp_buffer_map = ++ drm_core_findmap(dev, init->buffers_offset); ++ if (!dev->agp_buffer_map) { ++ DRM_ERROR("can not find dma buffer map!\n"); ++ dev->dev_private = (void *)dev_priv; ++ mach64_do_cleanup_dma(dev); ++ return -EINVAL; ++ } ++ /* there might be a nicer way to do this - ++ dev isn't passed all the way though the mach64 - DA */ ++ dev_priv->dev_buffers = dev->agp_buffer_map; ++ ++ drm_core_ioremap(dev->agp_buffer_map, dev); ++ if (!dev->agp_buffer_map->handle) { ++ DRM_ERROR("can not ioremap virtual address for" ++ " dma buffer\n"); ++ dev->dev_private = (void *)dev_priv; ++ mach64_do_cleanup_dma(dev); ++ return -ENOMEM; ++ } ++ dev_priv->agp_textures = ++ drm_core_findmap(dev, init->agp_textures_offset); ++ if (!dev_priv->agp_textures) { ++ DRM_ERROR("can not find agp texture region!\n"); ++ dev->dev_private = (void *)dev_priv; ++ mach64_do_cleanup_dma(dev); ++ return -EINVAL; ++ } ++ } ++ ++ dev->dev_private = (void *)dev_priv; ++ ++ dev_priv->driver_mode = init->dma_mode; ++ ++ /* changing the FIFO size from the default causes problems with DMA */ ++ tmp = MACH64_READ(MACH64_GUI_CNTL); ++ if ((tmp & MACH64_CMDFIFO_SIZE_MASK) != MACH64_CMDFIFO_SIZE_128) { ++ DRM_INFO("Setting FIFO size to 128 entries\n"); ++ /* FIFO must be empty to change the FIFO depth */ ++ if ((ret = mach64_do_wait_for_idle(dev_priv))) { ++ DRM_ERROR ++ ("wait for idle failed before changing FIFO depth!\n"); ++ mach64_do_cleanup_dma(dev); ++ return ret; ++ } ++ MACH64_WRITE(MACH64_GUI_CNTL, ((tmp & ~MACH64_CMDFIFO_SIZE_MASK) ++ | MACH64_CMDFIFO_SIZE_128)); ++ /* need to read GUI_STAT for proper sync according to docs */ ++ if ((ret = mach64_do_wait_for_idle(dev_priv))) { ++ DRM_ERROR ++ ("wait for idle failed when changing FIFO depth!\n"); ++ mach64_do_cleanup_dma(dev); ++ return ret; ++ } ++ } ++ ++ dev_priv->ring.size = 0x4000; /* 16KB */ ++ dev_priv->ring.start = dev_priv->ring_map->handle; ++ dev_priv->ring.start_addr = (u32) dev_priv->ring_map->offset; ++ ++ memset(dev_priv->ring.start, 0, dev_priv->ring.size); ++ DRM_INFO("descriptor ring: cpu addr %p, bus addr: 0x%08x\n", ++ dev_priv->ring.start, dev_priv->ring.start_addr); ++ ++ ret = 0; ++ if (dev_priv->driver_mode != MACH64_MODE_MMIO) { ++ ++ /* enable block 1 registers and bus mastering */ ++ MACH64_WRITE(MACH64_BUS_CNTL, ((MACH64_READ(MACH64_BUS_CNTL) ++ | MACH64_BUS_EXT_REG_EN) ++ & ~MACH64_BUS_MASTER_DIS)); ++ ++ /* try a DMA GUI-mastering pass and fall back to MMIO if it fails */ ++ DRM_DEBUG("Starting DMA test...\n"); ++ if ((ret = mach64_bm_dma_test(dev))) { ++ dev_priv->driver_mode = MACH64_MODE_MMIO; ++ } ++ } ++ ++ switch (dev_priv->driver_mode) { ++ case MACH64_MODE_MMIO: ++ MACH64_WRITE(MACH64_BUS_CNTL, (MACH64_READ(MACH64_BUS_CNTL) ++ | MACH64_BUS_EXT_REG_EN ++ | MACH64_BUS_MASTER_DIS)); ++ if (init->dma_mode == MACH64_MODE_MMIO) ++ DRM_INFO("Forcing pseudo-DMA mode\n"); ++ else ++ DRM_INFO ++ ("DMA test failed (ret=%d), using pseudo-DMA mode\n", ++ ret); ++ break; ++ case MACH64_MODE_DMA_SYNC: ++ DRM_INFO("DMA test succeeded, using synchronous DMA mode\n"); ++ break; ++ case MACH64_MODE_DMA_ASYNC: ++ default: ++ DRM_INFO("DMA test succeeded, using asynchronous DMA mode\n"); ++ } ++ ++ dev_priv->ring_running = 0; ++ ++ /* setup offsets for physical address of table start and end */ ++ dev_priv->ring.head_addr = dev_priv->ring.start_addr; ++ dev_priv->ring.head = dev_priv->ring.tail = 0; ++ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; ++ dev_priv->ring.space = dev_priv->ring.size; ++ ++ /* setup physical address and size of descriptor table */ ++ mach64_do_wait_for_fifo(dev_priv, 1); ++ MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD, ++ (dev_priv->ring. ++ head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB)); ++ ++ /* init frame counter */ ++ dev_priv->sarea_priv->frames_queued = 0; ++ for (i = 0; i < MACH64_MAX_QUEUED_FRAMES; i++) { ++ dev_priv->frame_ofs[i] = ~0; /* All ones indicates placeholder */ ++ } ++ ++ /* Allocate the DMA buffer freelist */ ++ if ((ret = mach64_init_freelist(dev))) { ++ DRM_ERROR("Freelist allocation failed\n"); ++ mach64_do_cleanup_dma(dev); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/*******************************************************************/ ++/** MMIO Pseudo-DMA (intended primarily for debugging, not performance) ++ */ ++ ++int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t *dev_priv) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ volatile u32 *ring_read; ++ struct list_head *ptr; ++ drm_mach64_freelist_t *entry; ++ struct drm_buf *buf = NULL; ++ u32 *buf_ptr; ++ u32 used, reg, target; ++ int fifo, count, found, ret, no_idle_wait; ++ ++ fifo = count = reg = no_idle_wait = 0; ++ target = MACH64_BM_ADDR; ++ ++ if ((ret = mach64_do_wait_for_idle(dev_priv)) < 0) { ++ DRM_INFO("idle failed before pseudo-dma dispatch, resetting engine\n"); ++ mach64_dump_engine_info(dev_priv); ++ mach64_do_engine_reset(dev_priv); ++ return ret; ++ } ++ ++ ring_read = (u32 *) ring->start; ++ ++ while (ring->tail != ring->head) { ++ u32 buf_addr, new_target, offset; ++ u32 bytes, remaining, head, eol; ++ ++ head = ring->head; ++ ++ new_target = ++ le32_to_cpu(ring_read[head++]) - MACH64_APERTURE_OFFSET; ++ buf_addr = le32_to_cpu(ring_read[head++]); ++ eol = le32_to_cpu(ring_read[head]) & MACH64_DMA_EOL; ++ bytes = le32_to_cpu(ring_read[head++]) ++ & ~(MACH64_DMA_HOLD_OFFSET | MACH64_DMA_EOL); ++ head++; ++ head &= ring->tail_mask; ++ ++ /* can't wait for idle between a blit setup descriptor ++ * and a HOSTDATA descriptor or the engine will lock ++ */ ++ if (new_target == MACH64_BM_HOSTDATA ++ && target == MACH64_BM_ADDR) ++ no_idle_wait = 1; ++ ++ target = new_target; ++ ++ found = 0; ++ offset = 0; ++ list_for_each(ptr, &dev_priv->pending) { ++ entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ buf = entry->buf; ++ offset = buf_addr - GETBUFADDR(buf); ++ if (offset >= 0 && offset < MACH64_BUFFER_SIZE) { ++ found = 1; ++ break; ++ } ++ } ++ ++ if (!found || buf == NULL) { ++ DRM_ERROR ++ ("Couldn't find pending buffer: head: %u tail: %u buf_addr: 0x%08x %s\n", ++ head, ring->tail, buf_addr, (eol ? "eol" : "")); ++ mach64_dump_ring_info(dev_priv); ++ mach64_do_engine_reset(dev_priv); ++ return -EINVAL; ++ } ++ ++ /* Hand feed the buffer to the card via MMIO, waiting for the fifo ++ * every 16 writes ++ */ ++ DRM_DEBUG("target: (0x%08x) %s\n", target, ++ (target == ++ MACH64_BM_HOSTDATA ? "BM_HOSTDATA" : "BM_ADDR")); ++ DRM_DEBUG("offset: %u bytes: %u used: %u\n", offset, bytes, ++ buf->used); ++ ++ remaining = (buf->used - offset) >> 2; /* dwords remaining in buffer */ ++ used = bytes >> 2; /* dwords in buffer for this descriptor */ ++ buf_ptr = (u32 *) ((char *)GETBUFPTR(buf) + offset); ++ ++ while (used) { ++ ++ if (count == 0) { ++ if (target == MACH64_BM_HOSTDATA) { ++ reg = DMAREG(MACH64_HOST_DATA0); ++ count = ++ (remaining > 16) ? 16 : remaining; ++ fifo = 0; ++ } else { ++ reg = le32_to_cpu(*buf_ptr++); ++ used--; ++ count = (reg >> 16) + 1; ++ } ++ ++ reg = reg & 0xffff; ++ reg = MMSELECT(reg); ++ } ++ while (count && used) { ++ if (!fifo) { ++ if (no_idle_wait) { ++ if ((ret = ++ mach64_do_wait_for_fifo ++ (dev_priv, 16)) < 0) { ++ no_idle_wait = 0; ++ return ret; ++ } ++ } else { ++ if ((ret = ++ mach64_do_wait_for_idle ++ (dev_priv)) < 0) { ++ return ret; ++ } ++ } ++ fifo = 16; ++ } ++ --fifo; ++ MACH64_WRITE(reg, le32_to_cpu(*buf_ptr++)); ++ used--; ++ remaining--; ++ ++ reg += 4; ++ count--; ++ } ++ } ++ ring->head = head; ++ ring->head_addr = ring->start_addr + (ring->head * sizeof(u32)); ++ ring->space += (4 * sizeof(u32)); ++ } ++ ++ if ((ret = mach64_do_wait_for_idle(dev_priv)) < 0) { ++ return ret; ++ } ++ MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD, ++ ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB); ++ ++ DRM_DEBUG("completed\n"); ++ return 0; ++} ++ ++/*@}*/ ++ ++ ++/*******************************************************************/ ++/** \name DMA cleanup */ ++/*@{*/ ++ ++int mach64_do_cleanup_dma(struct drm_device * dev) ++{ ++ DRM_DEBUG("\n"); ++ ++ /* Make sure interrupts are disabled here because the uninstall ioctl ++ * may not have been called from userspace and after dev_private ++ * is freed, it's too late. ++ */ ++ if (dev->irq) ++ drm_irq_uninstall(dev); ++ ++ if (dev->dev_private) { ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ ++ if (!dev_priv->is_pci) { ++ if (dev_priv->ring_map) ++ drm_core_ioremapfree(dev_priv->ring_map, dev); ++ ++ if (dev->agp_buffer_map) { ++ drm_core_ioremapfree(dev->agp_buffer_map, dev); ++ dev->agp_buffer_map = NULL; ++ } ++ } ++ ++ mach64_destroy_freelist(dev); ++ ++ drm_free(dev_priv, sizeof(drm_mach64_private_t), ++ DRM_MEM_DRIVER); ++ dev->dev_private = NULL; ++ } ++ ++ return 0; ++} ++ ++/*@}*/ ++ ++ ++/*******************************************************************/ ++/** \name IOCTL handlers */ ++/*@{*/ ++ ++int mach64_dma_init(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_init_t *init = data; ++ ++ DRM_DEBUG("\n"); ++ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ switch (init->func) { ++ case DRM_MACH64_INIT_DMA: ++ return mach64_do_dma_init(dev, init); ++ case DRM_MACH64_CLEANUP_DMA: ++ return mach64_do_cleanup_dma(dev); ++ } ++ ++ return -EINVAL; ++} ++ ++int mach64_dma_idle(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ ++ DRM_DEBUG("\n"); ++ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ return mach64_do_dma_idle(dev_priv); ++} ++ ++int mach64_dma_flush(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ ++ DRM_DEBUG("\n"); ++ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ return mach64_do_dma_flush(dev_priv); ++} ++ ++int mach64_engine_reset(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ ++ DRM_DEBUG("\n"); ++ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ return mach64_do_engine_reset(dev_priv); ++} ++ ++/*@}*/ ++ ++ ++/*******************************************************************/ ++/** \name Freelist management */ ++/*@{*/ ++ ++int mach64_init_freelist(struct drm_device * dev) ++{ ++ struct drm_device_dma *dma = dev->dma; ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_freelist_t *entry; ++ struct list_head *ptr; ++ int i; ++ ++ DRM_DEBUG("adding %d buffers to freelist\n", dma->buf_count); ++ ++ for (i = 0; i < dma->buf_count; i++) { ++ if ((entry = ++ (drm_mach64_freelist_t *) ++ drm_alloc(sizeof(drm_mach64_freelist_t), ++ DRM_MEM_BUFLISTS)) == NULL) ++ return -ENOMEM; ++ memset(entry, 0, sizeof(drm_mach64_freelist_t)); ++ entry->buf = dma->buflist[i]; ++ ptr = &entry->list; ++ list_add_tail(ptr, &dev_priv->free_list); ++ } ++ ++ return 0; ++} ++ ++void mach64_destroy_freelist(struct drm_device * dev) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_freelist_t *entry; ++ struct list_head *ptr; ++ struct list_head *tmp; ++ ++ DRM_DEBUG("\n"); ++ ++ list_for_each_safe(ptr, tmp, &dev_priv->pending) { ++ list_del(ptr); ++ entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS); ++ } ++ list_for_each_safe(ptr, tmp, &dev_priv->placeholders) { ++ list_del(ptr); ++ entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS); ++ } ++ ++ list_for_each_safe(ptr, tmp, &dev_priv->free_list) { ++ list_del(ptr); ++ entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ drm_free(entry, sizeof(*entry), DRM_MEM_BUFLISTS); ++ } ++} ++ ++/* IMPORTANT: This function should only be called when the engine is idle or locked up, ++ * as it assumes all buffers in the pending list have been completed by the hardware. ++ */ ++int mach64_do_release_used_buffers(drm_mach64_private_t *dev_priv) ++{ ++ struct list_head *ptr; ++ struct list_head *tmp; ++ drm_mach64_freelist_t *entry; ++ int i; ++ ++ if (list_empty(&dev_priv->pending)) ++ return 0; ++ ++ /* Iterate the pending list and move all buffers into the freelist... */ ++ i = 0; ++ list_for_each_safe(ptr, tmp, &dev_priv->pending) { ++ entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ if (entry->discard) { ++ entry->buf->pending = 0; ++ list_del(ptr); ++ list_add_tail(ptr, &dev_priv->free_list); ++ i++; ++ } ++ } ++ ++ DRM_DEBUG("released %d buffers from pending list\n", i); ++ ++ return 0; ++} ++ ++static int mach64_do_reclaim_completed(drm_mach64_private_t *dev_priv) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ struct list_head *ptr; ++ struct list_head *tmp; ++ drm_mach64_freelist_t *entry; ++ u32 head, tail, ofs; ++ ++ mach64_ring_tick(dev_priv, ring); ++ head = ring->head; ++ tail = ring->tail; ++ ++ if (head == tail) { ++#if MACH64_EXTRA_CHECKING ++ if (MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE) { ++ DRM_ERROR("Empty ring with non-idle engine!\n"); ++ mach64_dump_ring_info(dev_priv); ++ return -1; ++ } ++#endif ++ /* last pass is complete, so release everything */ ++ mach64_do_release_used_buffers(dev_priv); ++ DRM_DEBUG("idle engine, freed all buffers.\n"); ++ if (list_empty(&dev_priv->free_list)) { ++ DRM_ERROR("Freelist empty with idle engine\n"); ++ return -1; ++ } ++ return 0; ++ } ++ /* Look for a completed buffer and bail out of the loop ++ * as soon as we find one -- don't waste time trying ++ * to free extra bufs here, leave that to do_release_used_buffers ++ */ ++ list_for_each_safe(ptr, tmp, &dev_priv->pending) { ++ entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ ofs = entry->ring_ofs; ++ if (entry->discard && ++ ((head < tail && (ofs < head || ofs >= tail)) || ++ (head > tail && (ofs < head && ofs >= tail)))) { ++#if MACH64_EXTRA_CHECKING ++ int i; ++ ++ for (i = head; i != tail; i = (i + 4) & ring->tail_mask) ++ { ++ u32 o1 = le32_to_cpu(((u32 *) ring-> ++ start)[i + 1]); ++ u32 o2 = GETBUFADDR(entry->buf); ++ ++ if (o1 == o2) { ++ DRM_ERROR ++ ("Attempting to free used buffer: " ++ "i=%d buf=0x%08x\n", ++ i, o1); ++ mach64_dump_ring_info(dev_priv); ++ return -1; ++ } ++ } ++#endif ++ /* found a processed buffer */ ++ entry->buf->pending = 0; ++ list_del(ptr); ++ list_add_tail(ptr, &dev_priv->free_list); ++ DRM_DEBUG ++ ("freed processed buffer (head=%d tail=%d " ++ "buf ring ofs=%d).\n", ++ head, tail, ofs); ++ return 0; ++ } ++ } ++ ++ return 1; ++} ++ ++struct drm_buf *mach64_freelist_get(drm_mach64_private_t *dev_priv) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ drm_mach64_freelist_t *entry; ++ struct list_head *ptr; ++ int t; ++ ++ if (list_empty(&dev_priv->free_list)) { ++ if (list_empty(&dev_priv->pending)) { ++ DRM_ERROR ++ ("Couldn't get buffer - pending and free lists empty\n"); ++ t = 0; ++ list_for_each(ptr, &dev_priv->placeholders) { ++ t++; ++ } ++ DRM_INFO("Placeholders: %d\n", t); ++ return NULL; ++ } ++ ++ for (t = 0; t < dev_priv->usec_timeout; t++) { ++ int ret; ++ ++ ret = mach64_do_reclaim_completed(dev_priv); ++ if (ret == 0) ++ goto _freelist_entry_found; ++ if (ret < 0) ++ return NULL; ++ ++ DRM_UDELAY(1); ++ } ++ mach64_dump_ring_info(dev_priv); ++ DRM_ERROR ++ ("timeout waiting for buffers: ring head_addr: 0x%08x head: %d tail: %d\n", ++ ring->head_addr, ring->head, ring->tail); ++ return NULL; ++ } ++ ++ _freelist_entry_found: ++ ptr = dev_priv->free_list.next; ++ list_del(ptr); ++ entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ entry->buf->used = 0; ++ list_add_tail(ptr, &dev_priv->placeholders); ++ return entry->buf; ++} ++ ++int mach64_freelist_put(drm_mach64_private_t *dev_priv, struct drm_buf *copy_buf) ++{ ++ struct list_head *ptr; ++ drm_mach64_freelist_t *entry; ++ ++#if MACH64_EXTRA_CHECKING ++ list_for_each(ptr, &dev_priv->pending) { ++ entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ if (copy_buf == entry->buf) { ++ DRM_ERROR("Trying to release a pending buf\n"); ++ return -EFAULT; ++ } ++ } ++#endif ++ ptr = dev_priv->placeholders.next; ++ entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ copy_buf->pending = 0; ++ copy_buf->used = 0; ++ entry->buf = copy_buf; ++ entry->discard = 1; ++ list_del(ptr); ++ list_add_tail(ptr, &dev_priv->free_list); ++ ++ return 0; ++} ++ ++/*@}*/ ++ ++ ++/*******************************************************************/ ++/** \name DMA buffer request and submission IOCTL handler */ ++/*@{*/ ++ ++static int mach64_dma_get_buffers(struct drm_device *dev, ++ struct drm_file *file_priv, ++ struct drm_dma * d) ++{ ++ int i; ++ struct drm_buf *buf; ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ ++ for (i = d->granted_count; i < d->request_count; i++) { ++ buf = mach64_freelist_get(dev_priv); ++#if MACH64_EXTRA_CHECKING ++ if (!buf) ++ return -EFAULT; ++#else ++ if (!buf) ++ return -EAGAIN; ++#endif ++ ++ buf->file_priv = file_priv; ++ ++ if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx, ++ sizeof(buf->idx))) ++ return -EFAULT; ++ if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total, ++ sizeof(buf->total))) ++ return -EFAULT; ++ ++ d->granted_count++; ++ } ++ return 0; ++} ++ ++int mach64_dma_buffers(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ struct drm_device_dma *dma = dev->dma; ++ struct drm_dma *d = data; ++ int ret = 0; ++ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ /* Please don't send us buffers. ++ */ ++ if (d->send_count != 0) { ++ DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n", ++ DRM_CURRENTPID, d->send_count); ++ return -EINVAL; ++ } ++ ++ /* We'll send you buffers. ++ */ ++ if (d->request_count < 0 || d->request_count > dma->buf_count) { ++ DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n", ++ DRM_CURRENTPID, d->request_count, dma->buf_count); ++ ret = -EINVAL; ++ } ++ ++ d->granted_count = 0; ++ ++ if (d->request_count) { ++ ret = mach64_dma_get_buffers(dev, file_priv, d); ++ } ++ ++ return ret; ++} ++ ++void mach64_driver_lastclose(struct drm_device * dev) ++{ ++ mach64_do_cleanup_dma(dev); ++} ++ ++/*@}*/ +--- /dev/null ++++ b/drivers/gpu/drm/mach64/mach64_drm.h +@@ -0,0 +1,256 @@ ++/* mach64_drm.h -- Public header for the mach64 driver -*- linux-c -*- ++ * Created: Thu Nov 30 20:04:32 2000 by gareth@valinux.com ++ */ ++/* ++ * Copyright 2000 Gareth Hughes ++ * Copyright 2002 Frank C. Earl ++ * Copyright 2002-2003 Leif Delgass ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT OWNER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ++ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * Gareth Hughes ++ * Frank C. Earl ++ * Leif Delgass ++ */ ++ ++#ifndef __MACH64_DRM_H__ ++#define __MACH64_DRM_H__ ++ ++/* WARNING: If you change any of these defines, make sure to change the ++ * defines in the Xserver file (mach64_sarea.h) ++ */ ++#ifndef __MACH64_SAREA_DEFINES__ ++#define __MACH64_SAREA_DEFINES__ ++ ++/* What needs to be changed for the current vertex buffer? ++ * GH: We're going to be pedantic about this. We want the card to do as ++ * little as possible, so let's avoid having it fetch a whole bunch of ++ * register values that don't change all that often, if at all. ++ */ ++#define MACH64_UPLOAD_DST_OFF_PITCH 0x0001 ++#define MACH64_UPLOAD_Z_OFF_PITCH 0x0002 ++#define MACH64_UPLOAD_Z_ALPHA_CNTL 0x0004 ++#define MACH64_UPLOAD_SCALE_3D_CNTL 0x0008 ++#define MACH64_UPLOAD_DP_FOG_CLR 0x0010 ++#define MACH64_UPLOAD_DP_WRITE_MASK 0x0020 ++#define MACH64_UPLOAD_DP_PIX_WIDTH 0x0040 ++#define MACH64_UPLOAD_SETUP_CNTL 0x0080 ++#define MACH64_UPLOAD_MISC 0x0100 ++#define MACH64_UPLOAD_TEXTURE 0x0200 ++#define MACH64_UPLOAD_TEX0IMAGE 0x0400 ++#define MACH64_UPLOAD_TEX1IMAGE 0x0800 ++#define MACH64_UPLOAD_CLIPRECTS 0x1000 /* handled client-side */ ++#define MACH64_UPLOAD_CONTEXT 0x00ff ++#define MACH64_UPLOAD_ALL 0x1fff ++ ++/* DMA buffer size ++ */ ++#define MACH64_BUFFER_SIZE 16384 ++ ++/* Max number of swaps allowed on the ring ++ * before the client must wait ++ */ ++#define MACH64_MAX_QUEUED_FRAMES 3U ++ ++/* Byte offsets for host blit buffer data ++ */ ++#define MACH64_HOSTDATA_BLIT_OFFSET 104 ++ ++/* Keep these small for testing. ++ */ ++#define MACH64_NR_SAREA_CLIPRECTS 8 ++ ++#define MACH64_CARD_HEAP 0 ++#define MACH64_AGP_HEAP 1 ++#define MACH64_NR_TEX_HEAPS 2 ++#define MACH64_NR_TEX_REGIONS 64 ++#define MACH64_LOG_TEX_GRANULARITY 16 ++ ++#define MACH64_TEX_MAXLEVELS 1 ++ ++#define MACH64_NR_CONTEXT_REGS 15 ++#define MACH64_NR_TEXTURE_REGS 4 ++ ++#endif /* __MACH64_SAREA_DEFINES__ */ ++ ++typedef struct { ++ unsigned int dst_off_pitch; ++ ++ unsigned int z_off_pitch; ++ unsigned int z_cntl; ++ unsigned int alpha_tst_cntl; ++ ++ unsigned int scale_3d_cntl; ++ ++ unsigned int sc_left_right; ++ unsigned int sc_top_bottom; ++ ++ unsigned int dp_fog_clr; ++ unsigned int dp_write_mask; ++ unsigned int dp_pix_width; ++ unsigned int dp_mix; ++ unsigned int dp_src; ++ ++ unsigned int clr_cmp_cntl; ++ unsigned int gui_traj_cntl; ++ ++ unsigned int setup_cntl; ++ ++ unsigned int tex_size_pitch; ++ unsigned int tex_cntl; ++ unsigned int secondary_tex_off; ++ unsigned int tex_offset; ++} drm_mach64_context_regs_t; ++ ++typedef struct drm_mach64_sarea { ++ /* The channel for communication of state information to the kernel ++ * on firing a vertex dma buffer. ++ */ ++ drm_mach64_context_regs_t context_state; ++ unsigned int dirty; ++ unsigned int vertsize; ++ ++ /* The current cliprects, or a subset thereof. ++ */ ++ struct drm_clip_rect boxes[MACH64_NR_SAREA_CLIPRECTS]; ++ unsigned int nbox; ++ ++ /* Counters for client-side throttling of rendering clients. ++ */ ++ unsigned int frames_queued; ++ ++ /* Texture memory LRU. ++ */ ++ struct drm_tex_region tex_list[MACH64_NR_TEX_HEAPS][MACH64_NR_TEX_REGIONS + ++ 1]; ++ unsigned int tex_age[MACH64_NR_TEX_HEAPS]; ++ int ctx_owner; ++} drm_mach64_sarea_t; ++ ++/* WARNING: If you change any of these defines, make sure to change the ++ * defines in the Xserver file (mach64_common.h) ++ */ ++ ++/* Mach64 specific ioctls ++ * The device specific ioctl range is 0x40 to 0x79. ++ */ ++ ++#define DRM_MACH64_INIT 0x00 ++#define DRM_MACH64_IDLE 0x01 ++#define DRM_MACH64_RESET 0x02 ++#define DRM_MACH64_SWAP 0x03 ++#define DRM_MACH64_CLEAR 0x04 ++#define DRM_MACH64_VERTEX 0x05 ++#define DRM_MACH64_BLIT 0x06 ++#define DRM_MACH64_FLUSH 0x07 ++#define DRM_MACH64_GETPARAM 0x08 ++ ++#define DRM_IOCTL_MACH64_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MACH64_INIT, drm_mach64_init_t) ++#define DRM_IOCTL_MACH64_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_MACH64_IDLE ) ++#define DRM_IOCTL_MACH64_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MACH64_RESET ) ++#define DRM_IOCTL_MACH64_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MACH64_SWAP ) ++#define DRM_IOCTL_MACH64_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MACH64_CLEAR, drm_mach64_clear_t) ++#define DRM_IOCTL_MACH64_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_MACH64_VERTEX, drm_mach64_vertex_t) ++#define DRM_IOCTL_MACH64_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MACH64_BLIT, drm_mach64_blit_t) ++#define DRM_IOCTL_MACH64_FLUSH DRM_IO( DRM_COMMAND_BASE + DRM_MACH64_FLUSH ) ++#define DRM_IOCTL_MACH64_GETPARAM DRM_IOWR( DRM_COMMAND_BASE + DRM_MACH64_GETPARAM, drm_mach64_getparam_t) ++ ++/* Buffer flags for clears ++ */ ++#define MACH64_FRONT 0x1 ++#define MACH64_BACK 0x2 ++#define MACH64_DEPTH 0x4 ++ ++/* Primitive types for vertex buffers ++ */ ++#define MACH64_PRIM_POINTS 0x00000000 ++#define MACH64_PRIM_LINES 0x00000001 ++#define MACH64_PRIM_LINE_LOOP 0x00000002 ++#define MACH64_PRIM_LINE_STRIP 0x00000003 ++#define MACH64_PRIM_TRIANGLES 0x00000004 ++#define MACH64_PRIM_TRIANGLE_STRIP 0x00000005 ++#define MACH64_PRIM_TRIANGLE_FAN 0x00000006 ++#define MACH64_PRIM_QUADS 0x00000007 ++#define MACH64_PRIM_QUAD_STRIP 0x00000008 ++#define MACH64_PRIM_POLYGON 0x00000009 ++ ++typedef enum _drm_mach64_dma_mode_t { ++ MACH64_MODE_DMA_ASYNC, ++ MACH64_MODE_DMA_SYNC, ++ MACH64_MODE_MMIO ++} drm_mach64_dma_mode_t; ++ ++typedef struct drm_mach64_init { ++ enum { ++ DRM_MACH64_INIT_DMA = 0x01, ++ DRM_MACH64_CLEANUP_DMA = 0x02 ++ } func; ++ ++ unsigned long sarea_priv_offset; ++ int is_pci; ++ drm_mach64_dma_mode_t dma_mode; ++ ++ unsigned int fb_bpp; ++ unsigned int front_offset, front_pitch; ++ unsigned int back_offset, back_pitch; ++ ++ unsigned int depth_bpp; ++ unsigned int depth_offset, depth_pitch; ++ ++ unsigned long fb_offset; ++ unsigned long mmio_offset; ++ unsigned long ring_offset; ++ unsigned long buffers_offset; ++ unsigned long agp_textures_offset; ++} drm_mach64_init_t; ++ ++typedef struct drm_mach64_clear { ++ unsigned int flags; ++ int x, y, w, h; ++ unsigned int clear_color; ++ unsigned int clear_depth; ++} drm_mach64_clear_t; ++ ++typedef struct drm_mach64_vertex { ++ int prim; ++ void *buf; /* Address of vertex buffer */ ++ unsigned long used; /* Number of bytes in buffer */ ++ int discard; /* Client finished with buffer? */ ++} drm_mach64_vertex_t; ++ ++typedef struct drm_mach64_blit { ++ void *buf; ++ int pitch; ++ int offset; ++ int format; ++ unsigned short x, y; ++ unsigned short width, height; ++} drm_mach64_blit_t; ++ ++typedef struct drm_mach64_getparam { ++ enum { ++ MACH64_PARAM_FRAMES_QUEUED = 0x01, ++ MACH64_PARAM_IRQ_NR = 0x02 ++ } param; ++ void *value; ++} drm_mach64_getparam_t; ++ ++#endif +--- /dev/null ++++ b/drivers/gpu/drm/mach64/mach64_drv.c +@@ -0,0 +1,105 @@ ++/* mach64_drv.c -- mach64 (Rage Pro) driver -*- linux-c -*- ++ * Created: Fri Nov 24 18:34:32 2000 by gareth@valinux.com ++ * ++ * Copyright 2000 Gareth Hughes ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * GARETH HUGHES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ++ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * Gareth Hughes ++ * Leif Delgass ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "mach64_drm.h" ++#include "mach64_drv.h" ++ ++#include "drm_pciids.h" ++ ++static struct pci_device_id pciidlist[] = { ++ mach64_PCI_IDS ++}; ++ ++static int probe(struct pci_dev *pdev, const struct pci_device_id *ent); ++static struct drm_driver driver = { ++ .driver_features = ++ DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_HAVE_DMA ++ | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED, ++ .lastclose = mach64_driver_lastclose, ++ .get_vblank_counter = mach64_get_vblank_counter, ++ .enable_vblank = mach64_enable_vblank, ++ .disable_vblank = mach64_disable_vblank, ++ .irq_preinstall = mach64_driver_irq_preinstall, ++ .irq_postinstall = mach64_driver_irq_postinstall, ++ .irq_uninstall = mach64_driver_irq_uninstall, ++ .irq_handler = mach64_driver_irq_handler, ++ .reclaim_buffers = drm_core_reclaim_buffers, ++ .get_map_ofs = drm_core_get_map_ofs, ++ .get_reg_ofs = drm_core_get_reg_ofs, ++ .ioctls = mach64_ioctls, ++ .dma_ioctl = mach64_dma_buffers, ++ .fops = { ++ .owner = THIS_MODULE, ++ .open = drm_open, ++ .release = drm_release, ++ .ioctl = drm_ioctl, ++ .mmap = drm_mmap, ++ .poll = drm_poll, ++ .fasync = drm_fasync, ++ }, ++ .pci_driver = { ++ .name = DRIVER_NAME, ++ .id_table = pciidlist, ++ .probe = probe, ++ .remove = __devexit_p(drm_cleanup_pci), ++ }, ++ ++ .name = DRIVER_NAME, ++ .desc = DRIVER_DESC, ++ .date = DRIVER_DATE, ++ .major = DRIVER_MAJOR, ++ .minor = DRIVER_MINOR, ++ .patchlevel = DRIVER_PATCHLEVEL, ++}; ++ ++static int probe(struct pci_dev *pdev, const struct pci_device_id *ent) ++{ ++ return drm_get_dev(pdev, ent, &driver); ++} ++ ++ ++static int __init mach64_init(void) ++{ ++ driver.num_ioctls = mach64_max_ioctl; ++ return drm_init(&driver, pciidlist); ++} ++ ++static void __exit mach64_exit(void) ++{ ++ drm_exit(&driver); ++} ++ ++module_init(mach64_init); ++module_exit(mach64_exit); ++ ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE("GPL and additional rights"); +--- /dev/null ++++ b/drivers/gpu/drm/mach64/mach64_drv.h +@@ -0,0 +1,859 @@ ++/* mach64_drv.h -- Private header for mach64 driver -*- linux-c -*- ++ * Created: Fri Nov 24 22:07:58 2000 by gareth@valinux.com ++ */ ++/* ++ * Copyright 2000 Gareth Hughes ++ * Copyright 2002 Frank C. Earl ++ * Copyright 2002-2003 Leif Delgass ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT OWNER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ++ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * Gareth Hughes ++ * Frank C. Earl ++ * Leif Delgass ++ * José Fonseca ++ */ ++ ++#ifndef __MACH64_DRV_H__ ++#define __MACH64_DRV_H__ ++ ++/* General customization: ++ */ ++ ++#define DRIVER_AUTHOR "Gareth Hughes, Leif Delgass, José Fonseca" ++ ++#define DRIVER_NAME "mach64" ++#define DRIVER_DESC "DRM module for the ATI Rage Pro" ++#define DRIVER_DATE "20060718" ++ ++#define DRIVER_MAJOR 2 ++#define DRIVER_MINOR 0 ++#define DRIVER_PATCHLEVEL 0 ++ ++/* FIXME: remove these when not needed */ ++/* Development driver options */ ++#define MACH64_EXTRA_CHECKING 0 /* Extra sanity checks for DMA/freelist management */ ++#define MACH64_VERBOSE 0 /* Verbose debugging output */ ++ ++typedef struct drm_mach64_freelist { ++ struct list_head list; /* List pointers for free_list, placeholders, or pending list */ ++ struct drm_buf *buf; /* Pointer to the buffer */ ++ int discard; /* This flag is set when we're done (re)using a buffer */ ++ u32 ring_ofs; /* dword offset in ring of last descriptor for this buffer */ ++} drm_mach64_freelist_t; ++ ++typedef struct drm_mach64_descriptor_ring { ++ void *start; /* write pointer (cpu address) to start of descriptor ring */ ++ u32 start_addr; /* bus address of beginning of descriptor ring */ ++ int size; /* size of ring in bytes */ ++ ++ u32 head_addr; /* bus address of descriptor ring head */ ++ u32 head; /* dword offset of descriptor ring head */ ++ u32 tail; /* dword offset of descriptor ring tail */ ++ u32 tail_mask; /* mask used to wrap ring */ ++ int space; /* number of free bytes in ring */ ++} drm_mach64_descriptor_ring_t; ++ ++typedef struct drm_mach64_private { ++ drm_mach64_sarea_t *sarea_priv; ++ ++ int is_pci; ++ drm_mach64_dma_mode_t driver_mode; /* Async DMA, sync DMA, or MMIO */ ++ ++ int usec_timeout; /* Timeout for the wait functions */ ++ ++ drm_mach64_descriptor_ring_t ring; /* DMA descriptor table (ring buffer) */ ++ int ring_running; /* Is bus mastering is enabled */ ++ ++ struct list_head free_list; /* Free-list head */ ++ struct list_head placeholders; /* Placeholder list for buffers held by clients */ ++ struct list_head pending; /* Buffers pending completion */ ++ ++ u32 frame_ofs[MACH64_MAX_QUEUED_FRAMES]; /* dword ring offsets of most recent frame swaps */ ++ ++ unsigned int fb_bpp; ++ unsigned int front_offset, front_pitch; ++ unsigned int back_offset, back_pitch; ++ ++ unsigned int depth_bpp; ++ unsigned int depth_offset, depth_pitch; ++ ++ atomic_t vbl_received; /**< Number of vblanks received. */ ++ ++ u32 front_offset_pitch; ++ u32 back_offset_pitch; ++ u32 depth_offset_pitch; ++ ++ drm_local_map_t *sarea; ++ drm_local_map_t *fb; ++ drm_local_map_t *mmio; ++ drm_local_map_t *ring_map; ++ drm_local_map_t *dev_buffers; /* this is a pointer to a structure in dev */ ++ drm_local_map_t *agp_textures; ++} drm_mach64_private_t; ++ ++extern struct drm_ioctl_desc mach64_ioctls[]; ++extern int mach64_max_ioctl; ++ ++ /* mach64_dma.c */ ++extern int mach64_dma_init(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int mach64_dma_idle(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int mach64_dma_flush(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int mach64_engine_reset(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int mach64_dma_buffers(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern void mach64_driver_lastclose(struct drm_device * dev); ++ ++extern int mach64_init_freelist(struct drm_device * dev); ++extern void mach64_destroy_freelist(struct drm_device * dev); ++extern struct drm_buf *mach64_freelist_get(drm_mach64_private_t * dev_priv); ++extern int mach64_freelist_put(drm_mach64_private_t * dev_priv, ++ struct drm_buf * copy_buf); ++ ++extern int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv, ++ int entries); ++extern int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv); ++extern int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n); ++extern int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv); ++extern int mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv); ++extern void mach64_dump_engine_info(drm_mach64_private_t * dev_priv); ++extern void mach64_dump_ring_info(drm_mach64_private_t * dev_priv); ++extern int mach64_do_engine_reset(drm_mach64_private_t * dev_priv); ++ ++extern int mach64_add_buf_to_ring(drm_mach64_private_t *dev_priv, ++ drm_mach64_freelist_t *_entry); ++extern int mach64_add_hostdata_buf_to_ring(drm_mach64_private_t *dev_priv, ++ drm_mach64_freelist_t *_entry); ++ ++extern int mach64_do_dma_idle(drm_mach64_private_t * dev_priv); ++extern int mach64_do_dma_flush(drm_mach64_private_t * dev_priv); ++extern int mach64_do_cleanup_dma(struct drm_device * dev); ++ ++ /* mach64_state.c */ ++extern int mach64_dma_clear(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int mach64_dma_swap(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int mach64_dma_vertex(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int mach64_dma_blit(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++extern int mach64_get_param(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++ ++extern u32 mach64_get_vblank_counter(struct drm_device *dev, int crtc); ++extern int mach64_enable_vblank(struct drm_device *dev, int crtc); ++extern void mach64_disable_vblank(struct drm_device *dev, int crtc); ++extern irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS); ++extern void mach64_driver_irq_preinstall(struct drm_device *dev); ++extern int mach64_driver_irq_postinstall(struct drm_device *dev); ++extern void mach64_driver_irq_uninstall(struct drm_device *dev); ++ ++/* ================================================================ ++ * Registers ++ */ ++ ++#define MACH64_AGP_BASE 0x0148 ++#define MACH64_AGP_CNTL 0x014c ++#define MACH64_ALPHA_TST_CNTL 0x0550 ++ ++#define MACH64_DSP_CONFIG 0x0420 ++#define MACH64_DSP_ON_OFF 0x0424 ++#define MACH64_EXT_MEM_CNTL 0x04ac ++#define MACH64_GEN_TEST_CNTL 0x04d0 ++#define MACH64_HW_DEBUG 0x047c ++#define MACH64_MEM_ADDR_CONFIG 0x0434 ++#define MACH64_MEM_BUF_CNTL 0x042c ++#define MACH64_MEM_CNTL 0x04b0 ++ ++#define MACH64_BM_ADDR 0x0648 ++#define MACH64_BM_COMMAND 0x0188 ++#define MACH64_BM_DATA 0x0648 ++#define MACH64_BM_FRAME_BUF_OFFSET 0x0180 ++#define MACH64_BM_GUI_TABLE 0x01b8 ++#define MACH64_BM_GUI_TABLE_CMD 0x064c ++# define MACH64_CIRCULAR_BUF_SIZE_16KB (0 << 0) ++# define MACH64_CIRCULAR_BUF_SIZE_32KB (1 << 0) ++# define MACH64_CIRCULAR_BUF_SIZE_64KB (2 << 0) ++# define MACH64_CIRCULAR_BUF_SIZE_128KB (3 << 0) ++# define MACH64_LAST_DESCRIPTOR (1 << 31) ++#define MACH64_BM_HOSTDATA 0x0644 ++#define MACH64_BM_STATUS 0x018c ++#define MACH64_BM_SYSTEM_MEM_ADDR 0x0184 ++#define MACH64_BM_SYSTEM_TABLE 0x01bc ++#define MACH64_BUS_CNTL 0x04a0 ++# define MACH64_BUS_MSTR_RESET (1 << 1) ++# define MACH64_BUS_APER_REG_DIS (1 << 4) ++# define MACH64_BUS_FLUSH_BUF (1 << 2) ++# define MACH64_BUS_MASTER_DIS (1 << 6) ++# define MACH64_BUS_EXT_REG_EN (1 << 27) ++ ++#define MACH64_CLR_CMP_CLR 0x0700 ++#define MACH64_CLR_CMP_CNTL 0x0708 ++#define MACH64_CLR_CMP_MASK 0x0704 ++#define MACH64_CONFIG_CHIP_ID 0x04e0 ++#define MACH64_CONFIG_CNTL 0x04dc ++#define MACH64_CONFIG_STAT0 0x04e4 ++#define MACH64_CONFIG_STAT1 0x0494 ++#define MACH64_CONFIG_STAT2 0x0498 ++#define MACH64_CONTEXT_LOAD_CNTL 0x072c ++#define MACH64_CONTEXT_MASK 0x0720 ++#define MACH64_COMPOSITE_SHADOW_ID 0x0798 ++#define MACH64_CRC_SIG 0x04e8 ++#define MACH64_CUSTOM_MACRO_CNTL 0x04d4 ++ ++#define MACH64_DP_BKGD_CLR 0x06c0 ++#define MACH64_DP_FOG_CLR 0x06c4 ++#define MACH64_DP_FGRD_BKGD_CLR 0x06e0 ++#define MACH64_DP_FRGD_CLR 0x06c4 ++#define MACH64_DP_FGRD_CLR_MIX 0x06dc ++ ++#define MACH64_DP_MIX 0x06d4 ++# define BKGD_MIX_NOT_D (0 << 0) ++# define BKGD_MIX_ZERO (1 << 0) ++# define BKGD_MIX_ONE (2 << 0) ++# define MACH64_BKGD_MIX_D (3 << 0) ++# define BKGD_MIX_NOT_S (4 << 0) ++# define BKGD_MIX_D_XOR_S (5 << 0) ++# define BKGD_MIX_NOT_D_XOR_S (6 << 0) ++# define MACH64_BKGD_MIX_S (7 << 0) ++# define BKGD_MIX_NOT_D_OR_NOT_S (8 << 0) ++# define BKGD_MIX_D_OR_NOT_S (9 << 0) ++# define BKGD_MIX_NOT_D_OR_S (10 << 0) ++# define BKGD_MIX_D_OR_S (11 << 0) ++# define BKGD_MIX_D_AND_S (12 << 0) ++# define BKGD_MIX_NOT_D_AND_S (13 << 0) ++# define BKGD_MIX_D_AND_NOT_S (14 << 0) ++# define BKGD_MIX_NOT_D_AND_NOT_S (15 << 0) ++# define BKGD_MIX_D_PLUS_S_DIV2 (23 << 0) ++# define FRGD_MIX_NOT_D (0 << 16) ++# define FRGD_MIX_ZERO (1 << 16) ++# define FRGD_MIX_ONE (2 << 16) ++# define FRGD_MIX_D (3 << 16) ++# define FRGD_MIX_NOT_S (4 << 16) ++# define FRGD_MIX_D_XOR_S (5 << 16) ++# define FRGD_MIX_NOT_D_XOR_S (6 << 16) ++# define MACH64_FRGD_MIX_S (7 << 16) ++# define FRGD_MIX_NOT_D_OR_NOT_S (8 << 16) ++# define FRGD_MIX_D_OR_NOT_S (9 << 16) ++# define FRGD_MIX_NOT_D_OR_S (10 << 16) ++# define FRGD_MIX_D_OR_S (11 << 16) ++# define FRGD_MIX_D_AND_S (12 << 16) ++# define FRGD_MIX_NOT_D_AND_S (13 << 16) ++# define FRGD_MIX_D_AND_NOT_S (14 << 16) ++# define FRGD_MIX_NOT_D_AND_NOT_S (15 << 16) ++# define FRGD_MIX_D_PLUS_S_DIV2 (23 << 16) ++ ++#define MACH64_DP_PIX_WIDTH 0x06d0 ++# define MACH64_HOST_TRIPLE_ENABLE (1 << 13) ++# define MACH64_BYTE_ORDER_MSB_TO_LSB (0 << 24) ++# define MACH64_BYTE_ORDER_LSB_TO_MSB (1 << 24) ++ ++#define MACH64_DP_SRC 0x06d8 ++# define MACH64_BKGD_SRC_BKGD_CLR (0 << 0) ++# define MACH64_BKGD_SRC_FRGD_CLR (1 << 0) ++# define MACH64_BKGD_SRC_HOST (2 << 0) ++# define MACH64_BKGD_SRC_BLIT (3 << 0) ++# define MACH64_BKGD_SRC_PATTERN (4 << 0) ++# define MACH64_BKGD_SRC_3D (5 << 0) ++# define MACH64_FRGD_SRC_BKGD_CLR (0 << 8) ++# define MACH64_FRGD_SRC_FRGD_CLR (1 << 8) ++# define MACH64_FRGD_SRC_HOST (2 << 8) ++# define MACH64_FRGD_SRC_BLIT (3 << 8) ++# define MACH64_FRGD_SRC_PATTERN (4 << 8) ++# define MACH64_FRGD_SRC_3D (5 << 8) ++# define MACH64_MONO_SRC_ONE (0 << 16) ++# define MACH64_MONO_SRC_PATTERN (1 << 16) ++# define MACH64_MONO_SRC_HOST (2 << 16) ++# define MACH64_MONO_SRC_BLIT (3 << 16) ++ ++#define MACH64_DP_WRITE_MASK 0x06c8 ++ ++#define MACH64_DST_CNTL 0x0530 ++# define MACH64_DST_X_RIGHT_TO_LEFT (0 << 0) ++# define MACH64_DST_X_LEFT_TO_RIGHT (1 << 0) ++# define MACH64_DST_Y_BOTTOM_TO_TOP (0 << 1) ++# define MACH64_DST_Y_TOP_TO_BOTTOM (1 << 1) ++# define MACH64_DST_X_MAJOR (0 << 2) ++# define MACH64_DST_Y_MAJOR (1 << 2) ++# define MACH64_DST_X_TILE (1 << 3) ++# define MACH64_DST_Y_TILE (1 << 4) ++# define MACH64_DST_LAST_PEL (1 << 5) ++# define MACH64_DST_POLYGON_ENABLE (1 << 6) ++# define MACH64_DST_24_ROTATION_ENABLE (1 << 7) ++ ++#define MACH64_DST_HEIGHT_WIDTH 0x0518 ++#define MACH64_DST_OFF_PITCH 0x0500 ++#define MACH64_DST_WIDTH_HEIGHT 0x06ec ++#define MACH64_DST_X_Y 0x06e8 ++#define MACH64_DST_Y_X 0x050c ++ ++#define MACH64_FIFO_STAT 0x0710 ++# define MACH64_FIFO_SLOT_MASK 0x0000ffff ++# define MACH64_FIFO_ERR (1 << 31) ++ ++#define MACH64_GEN_TEST_CNTL 0x04d0 ++# define MACH64_GUI_ENGINE_ENABLE (1 << 8) ++#define MACH64_GUI_CMDFIFO_DEBUG 0x0170 ++#define MACH64_GUI_CMDFIFO_DATA 0x0174 ++#define MACH64_GUI_CNTL 0x0178 ++# define MACH64_CMDFIFO_SIZE_MASK 0x00000003ul ++# define MACH64_CMDFIFO_SIZE_192 0x00000000ul ++# define MACH64_CMDFIFO_SIZE_128 0x00000001ul ++# define MACH64_CMDFIFO_SIZE_64 0x00000002ul ++#define MACH64_GUI_STAT 0x0738 ++# define MACH64_GUI_ACTIVE (1 << 0) ++#define MACH64_GUI_TRAJ_CNTL 0x0730 ++ ++#define MACH64_HOST_CNTL 0x0640 ++#define MACH64_HOST_DATA0 0x0600 ++ ++#define MACH64_ONE_OVER_AREA 0x029c ++#define MACH64_ONE_OVER_AREA_UC 0x0300 ++ ++#define MACH64_PAT_REG0 0x0680 ++#define MACH64_PAT_REG1 0x0684 ++ ++#define MACH64_SC_LEFT 0x06a0 ++#define MACH64_SC_RIGHT 0x06a4 ++#define MACH64_SC_LEFT_RIGHT 0x06a8 ++#define MACH64_SC_TOP 0x06ac ++#define MACH64_SC_BOTTOM 0x06b0 ++#define MACH64_SC_TOP_BOTTOM 0x06b4 ++ ++#define MACH64_SCALE_3D_CNTL 0x05fc ++#define MACH64_SCRATCH_REG0 0x0480 ++#define MACH64_SCRATCH_REG1 0x0484 ++#define MACH64_SECONDARY_TEX_OFF 0x0778 ++#define MACH64_SETUP_CNTL 0x0304 ++#define MACH64_SRC_CNTL 0x05b4 ++# define MACH64_SRC_BM_ENABLE (1 << 8) ++# define MACH64_SRC_BM_SYNC (1 << 9) ++# define MACH64_SRC_BM_OP_FRAME_TO_SYSTEM (0 << 10) ++# define MACH64_SRC_BM_OP_SYSTEM_TO_FRAME (1 << 10) ++# define MACH64_SRC_BM_OP_REG_TO_SYSTEM (2 << 10) ++# define MACH64_SRC_BM_OP_SYSTEM_TO_REG (3 << 10) ++#define MACH64_SRC_HEIGHT1 0x0594 ++#define MACH64_SRC_HEIGHT2 0x05ac ++#define MACH64_SRC_HEIGHT1_WIDTH1 0x0598 ++#define MACH64_SRC_HEIGHT2_WIDTH2 0x05b0 ++#define MACH64_SRC_OFF_PITCH 0x0580 ++#define MACH64_SRC_WIDTH1 0x0590 ++#define MACH64_SRC_Y_X 0x058c ++ ++#define MACH64_TEX_0_OFF 0x05c0 ++#define MACH64_TEX_CNTL 0x0774 ++#define MACH64_TEX_SIZE_PITCH 0x0770 ++#define MACH64_TIMER_CONFIG 0x0428 ++ ++#define MACH64_VERTEX_1_ARGB 0x0254 ++#define MACH64_VERTEX_1_S 0x0240 ++#define MACH64_VERTEX_1_SECONDARY_S 0x0328 ++#define MACH64_VERTEX_1_SECONDARY_T 0x032c ++#define MACH64_VERTEX_1_SECONDARY_W 0x0330 ++#define MACH64_VERTEX_1_SPEC_ARGB 0x024c ++#define MACH64_VERTEX_1_T 0x0244 ++#define MACH64_VERTEX_1_W 0x0248 ++#define MACH64_VERTEX_1_X_Y 0x0258 ++#define MACH64_VERTEX_1_Z 0x0250 ++#define MACH64_VERTEX_2_ARGB 0x0274 ++#define MACH64_VERTEX_2_S 0x0260 ++#define MACH64_VERTEX_2_SECONDARY_S 0x0334 ++#define MACH64_VERTEX_2_SECONDARY_T 0x0338 ++#define MACH64_VERTEX_2_SECONDARY_W 0x033c ++#define MACH64_VERTEX_2_SPEC_ARGB 0x026c ++#define MACH64_VERTEX_2_T 0x0264 ++#define MACH64_VERTEX_2_W 0x0268 ++#define MACH64_VERTEX_2_X_Y 0x0278 ++#define MACH64_VERTEX_2_Z 0x0270 ++#define MACH64_VERTEX_3_ARGB 0x0294 ++#define MACH64_VERTEX_3_S 0x0280 ++#define MACH64_VERTEX_3_SECONDARY_S 0x02a0 ++#define MACH64_VERTEX_3_SECONDARY_T 0x02a4 ++#define MACH64_VERTEX_3_SECONDARY_W 0x02a8 ++#define MACH64_VERTEX_3_SPEC_ARGB 0x028c ++#define MACH64_VERTEX_3_T 0x0284 ++#define MACH64_VERTEX_3_W 0x0288 ++#define MACH64_VERTEX_3_X_Y 0x0298 ++#define MACH64_VERTEX_3_Z 0x0290 ++ ++#define MACH64_Z_CNTL 0x054c ++#define MACH64_Z_OFF_PITCH 0x0548 ++ ++#define MACH64_CRTC_VLINE_CRNT_VLINE 0x0410 ++# define MACH64_CRTC_VLINE_MASK 0x000007ff ++# define MACH64_CRTC_CRNT_VLINE_MASK 0x07ff0000 ++#define MACH64_CRTC_OFF_PITCH 0x0414 ++#define MACH64_CRTC_INT_CNTL 0x0418 ++# define MACH64_CRTC_VBLANK (1 << 0) ++# define MACH64_CRTC_VBLANK_INT_EN (1 << 1) ++# define MACH64_CRTC_VBLANK_INT (1 << 2) ++# define MACH64_CRTC_VLINE_INT_EN (1 << 3) ++# define MACH64_CRTC_VLINE_INT (1 << 4) ++# define MACH64_CRTC_VLINE_SYNC (1 << 5) /* 0=even, 1=odd */ ++# define MACH64_CRTC_FRAME (1 << 6) /* 0=even, 1=odd */ ++# define MACH64_CRTC_SNAPSHOT_INT_EN (1 << 7) ++# define MACH64_CRTC_SNAPSHOT_INT (1 << 8) ++# define MACH64_CRTC_I2C_INT_EN (1 << 9) ++# define MACH64_CRTC_I2C_INT (1 << 10) ++# define MACH64_CRTC2_VBLANK (1 << 11) /* LT Pro */ ++# define MACH64_CRTC2_VBLANK_INT_EN (1 << 12) /* LT Pro */ ++# define MACH64_CRTC2_VBLANK_INT (1 << 13) /* LT Pro */ ++# define MACH64_CRTC2_VLINE_INT_EN (1 << 14) /* LT Pro */ ++# define MACH64_CRTC2_VLINE_INT (1 << 15) /* LT Pro */ ++# define MACH64_CRTC_CAPBUF0_INT_EN (1 << 16) ++# define MACH64_CRTC_CAPBUF0_INT (1 << 17) ++# define MACH64_CRTC_CAPBUF1_INT_EN (1 << 18) ++# define MACH64_CRTC_CAPBUF1_INT (1 << 19) ++# define MACH64_CRTC_OVERLAY_EOF_INT_EN (1 << 20) ++# define MACH64_CRTC_OVERLAY_EOF_INT (1 << 21) ++# define MACH64_CRTC_ONESHOT_CAP_INT_EN (1 << 22) ++# define MACH64_CRTC_ONESHOT_CAP_INT (1 << 23) ++# define MACH64_CRTC_BUSMASTER_EOL_INT_EN (1 << 24) ++# define MACH64_CRTC_BUSMASTER_EOL_INT (1 << 25) ++# define MACH64_CRTC_GP_INT_EN (1 << 26) ++# define MACH64_CRTC_GP_INT (1 << 27) ++# define MACH64_CRTC2_VLINE_SYNC (1 << 28) /* LT Pro */ /* 0=even, 1=odd */ ++# define MACH64_CRTC_SNAPSHOT2_INT_EN (1 << 29) /* LT Pro */ ++# define MACH64_CRTC_SNAPSHOT2_INT (1 << 30) /* LT Pro */ ++# define MACH64_CRTC_VBLANK2_INT (1 << 31) ++# define MACH64_CRTC_INT_ENS \ ++ ( \ ++ MACH64_CRTC_VBLANK_INT_EN | \ ++ MACH64_CRTC_VLINE_INT_EN | \ ++ MACH64_CRTC_SNAPSHOT_INT_EN | \ ++ MACH64_CRTC_I2C_INT_EN | \ ++ MACH64_CRTC2_VBLANK_INT_EN | \ ++ MACH64_CRTC2_VLINE_INT_EN | \ ++ MACH64_CRTC_CAPBUF0_INT_EN | \ ++ MACH64_CRTC_CAPBUF1_INT_EN | \ ++ MACH64_CRTC_OVERLAY_EOF_INT_EN | \ ++ MACH64_CRTC_ONESHOT_CAP_INT_EN | \ ++ MACH64_CRTC_BUSMASTER_EOL_INT_EN | \ ++ MACH64_CRTC_GP_INT_EN | \ ++ MACH64_CRTC_SNAPSHOT2_INT_EN | \ ++ 0 \ ++ ) ++# define MACH64_CRTC_INT_ACKS \ ++ ( \ ++ MACH64_CRTC_VBLANK_INT | \ ++ MACH64_CRTC_VLINE_INT | \ ++ MACH64_CRTC_SNAPSHOT_INT | \ ++ MACH64_CRTC_I2C_INT | \ ++ MACH64_CRTC2_VBLANK_INT | \ ++ MACH64_CRTC2_VLINE_INT | \ ++ MACH64_CRTC_CAPBUF0_INT | \ ++ MACH64_CRTC_CAPBUF1_INT | \ ++ MACH64_CRTC_OVERLAY_EOF_INT | \ ++ MACH64_CRTC_ONESHOT_CAP_INT | \ ++ MACH64_CRTC_BUSMASTER_EOL_INT | \ ++ MACH64_CRTC_GP_INT | \ ++ MACH64_CRTC_SNAPSHOT2_INT | \ ++ MACH64_CRTC_VBLANK2_INT | \ ++ 0 \ ++ ) ++ ++#define MACH64_DATATYPE_CI8 2 ++#define MACH64_DATATYPE_ARGB1555 3 ++#define MACH64_DATATYPE_RGB565 4 ++#define MACH64_DATATYPE_ARGB8888 6 ++#define MACH64_DATATYPE_RGB332 7 ++#define MACH64_DATATYPE_Y8 8 ++#define MACH64_DATATYPE_RGB8 9 ++#define MACH64_DATATYPE_VYUY422 11 ++#define MACH64_DATATYPE_YVYU422 12 ++#define MACH64_DATATYPE_AYUV444 14 ++#define MACH64_DATATYPE_ARGB4444 15 ++ ++#define MACH64_READ(reg) DRM_READ32(dev_priv->mmio, (reg) ) ++#define MACH64_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio, (reg), (val) ) ++ ++#define DWMREG0 0x0400 ++#define DWMREG0_END 0x07ff ++#define DWMREG1 0x0000 ++#define DWMREG1_END 0x03ff ++ ++#define ISREG0(r) (((r) >= DWMREG0) && ((r) <= DWMREG0_END)) ++#define DMAREG0(r) (((r) - DWMREG0) >> 2) ++#define DMAREG1(r) ((((r) - DWMREG1) >> 2 ) | 0x0100) ++#define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r)) ++ ++#define MMREG0 0x0000 ++#define MMREG0_END 0x00ff ++ ++#define ISMMREG0(r) (((r) >= MMREG0) && ((r) <= MMREG0_END)) ++#define MMSELECT0(r) (((r) << 2) + DWMREG0) ++#define MMSELECT1(r) (((((r) & 0xff) << 2) + DWMREG1)) ++#define MMSELECT(r) (ISMMREG0(r) ? MMSELECT0(r) : MMSELECT1(r)) ++ ++/* ================================================================ ++ * DMA constants ++ */ ++ ++/* DMA descriptor field indices: ++ * The descriptor fields are loaded into the read-only ++ * BM_* system bus master registers during a bus-master operation ++ */ ++#define MACH64_DMA_FRAME_BUF_OFFSET 0 /* BM_FRAME_BUF_OFFSET */ ++#define MACH64_DMA_SYS_MEM_ADDR 1 /* BM_SYSTEM_MEM_ADDR */ ++#define MACH64_DMA_COMMAND 2 /* BM_COMMAND */ ++#define MACH64_DMA_RESERVED 3 /* BM_STATUS */ ++ ++/* BM_COMMAND descriptor field flags */ ++#define MACH64_DMA_HOLD_OFFSET (1<<30) /* Don't increment DMA_FRAME_BUF_OFFSET */ ++#define MACH64_DMA_EOL (1<<31) /* End of descriptor list flag */ ++ ++#define MACH64_DMA_CHUNKSIZE 0x1000 /* 4kB per DMA descriptor */ ++#define MACH64_APERTURE_OFFSET 0x7ff800 /* frame-buffer offset for gui-masters */ ++ ++/* ================================================================ ++ * Ring operations ++ * ++ * Since the Mach64 bus master engine requires polling, these functions end ++ * up being called frequently, hence being inline. ++ */ ++ ++static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ ++ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n", ++ ring->head_addr, ring->head, ring->tail, ring->space); ++ ++ if (mach64_do_wait_for_idle(dev_priv) < 0) { ++ mach64_do_engine_reset(dev_priv); ++ } ++ ++ if (dev_priv->driver_mode != MACH64_MODE_MMIO) { ++ /* enable bus mastering and block 1 registers */ ++ MACH64_WRITE(MACH64_BUS_CNTL, ++ (MACH64_READ(MACH64_BUS_CNTL) & ++ ~MACH64_BUS_MASTER_DIS) ++ | MACH64_BUS_EXT_REG_EN); ++ mach64_do_wait_for_idle(dev_priv); ++ } ++ ++ /* reset descriptor table ring head */ ++ MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD, ++ ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB); ++ ++ dev_priv->ring_running = 1; ++} ++ ++static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv, ++ drm_mach64_descriptor_ring_t * ring) ++{ ++ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n", ++ ring->head_addr, ring->head, ring->tail, ring->space); ++ ++ /* reset descriptor table ring head */ ++ MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD, ++ ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB); ++ ++ if (dev_priv->driver_mode == MACH64_MODE_MMIO) { ++ mach64_do_dispatch_pseudo_dma(dev_priv); ++ } else { ++ /* enable GUI bus mastering, and sync the bus master to the GUI */ ++ MACH64_WRITE(MACH64_SRC_CNTL, ++ MACH64_SRC_BM_ENABLE | MACH64_SRC_BM_SYNC | ++ MACH64_SRC_BM_OP_SYSTEM_TO_REG); ++ ++ /* kick off the transfer */ ++ MACH64_WRITE(MACH64_DST_HEIGHT_WIDTH, 0); ++ if (dev_priv->driver_mode == MACH64_MODE_DMA_SYNC) { ++ if ((mach64_do_wait_for_idle(dev_priv)) < 0) { ++ DRM_ERROR("idle failed, resetting engine\n"); ++ mach64_dump_engine_info(dev_priv); ++ mach64_do_engine_reset(dev_priv); ++ return; ++ } ++ mach64_do_release_used_buffers(dev_priv); ++ } ++ } ++} ++ ++/** ++ * Poll the ring head and make sure the bus master is alive. ++ * ++ * Mach64's bus master engine will stop if there are no more entries to process. ++ * This function polls the engine for the last processed entry and calls ++ * mach64_ring_resume if there is an unprocessed entry. ++ * ++ * Note also that, since we update the ring tail while the bus master engine is ++ * in operation, it is possible that the last tail update was too late to be ++ * processed, and the bus master engine stops at the previous tail position. ++ * Therefore it is important to call this function frequently. ++ */ ++static __inline__ void mach64_ring_tick(drm_mach64_private_t * dev_priv, ++ drm_mach64_descriptor_ring_t * ring) ++{ ++ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n", ++ ring->head_addr, ring->head, ring->tail, ring->space); ++ ++ if (!dev_priv->ring_running) { ++ mach64_ring_start(dev_priv); ++ ++ if (ring->head != ring->tail) { ++ mach64_ring_resume(dev_priv, ring); ++ } ++ } else { ++ /* GUI_ACTIVE must be read before BM_GUI_TABLE to ++ * correctly determine the ring head ++ */ ++ int gui_active = ++ MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE; ++ ++ ring->head_addr = MACH64_READ(MACH64_BM_GUI_TABLE) & 0xfffffff0; ++ ++ if (gui_active) { ++ /* If not idle, BM_GUI_TABLE points one descriptor ++ * past the current head ++ */ ++ if (ring->head_addr == ring->start_addr) { ++ ring->head_addr += ring->size; ++ } ++ ring->head_addr -= 4 * sizeof(u32); ++ } ++ ++ if (ring->head_addr < ring->start_addr || ++ ring->head_addr >= ring->start_addr + ring->size) { ++ DRM_ERROR("bad ring head address: 0x%08x\n", ++ ring->head_addr); ++ mach64_dump_ring_info(dev_priv); ++ mach64_do_engine_reset(dev_priv); ++ return; ++ } ++ ++ ring->head = (ring->head_addr - ring->start_addr) / sizeof(u32); ++ ++ if (!gui_active && ring->head != ring->tail) { ++ mach64_ring_resume(dev_priv, ring); ++ } ++ } ++} ++ ++static __inline__ void mach64_ring_stop(drm_mach64_private_t * dev_priv) ++{ ++ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n", ++ dev_priv->ring.head_addr, dev_priv->ring.head, ++ dev_priv->ring.tail, dev_priv->ring.space); ++ ++ /* restore previous SRC_CNTL to disable busmastering */ ++ mach64_do_wait_for_fifo(dev_priv, 1); ++ MACH64_WRITE(MACH64_SRC_CNTL, 0); ++ ++ /* disable busmastering but keep the block 1 registers enabled */ ++ mach64_do_wait_for_idle(dev_priv); ++ MACH64_WRITE(MACH64_BUS_CNTL, MACH64_READ(MACH64_BUS_CNTL) ++ | MACH64_BUS_MASTER_DIS | MACH64_BUS_EXT_REG_EN); ++ ++ dev_priv->ring_running = 0; ++} ++ ++static __inline__ void ++mach64_update_ring_snapshot(drm_mach64_private_t * dev_priv) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ ++ DRM_DEBUG("\n"); ++ ++ mach64_ring_tick(dev_priv, ring); ++ ++ ring->space = (ring->head - ring->tail) * sizeof(u32); ++ if (ring->space <= 0) { ++ ring->space += ring->size; ++ } ++} ++ ++/* ================================================================ ++ * DMA macros ++ * ++ * Mach64's ring buffer doesn't take register writes directly. These ++ * have to be written indirectly in DMA buffers. These macros simplify ++ * the task of setting up a buffer, writing commands to it, and ++ * queuing the buffer in the ring. ++ */ ++ ++#define DMALOCALS \ ++ drm_mach64_freelist_t *_entry = NULL; \ ++ struct drm_buf *_buf = NULL; \ ++ u32 *_buf_wptr; int _outcount ++ ++#define GETBUFPTR( __buf ) \ ++((dev_priv->is_pci) ? \ ++ ((u32 *)(__buf)->address) : \ ++ ((u32 *)((char *)dev_priv->dev_buffers->handle + (__buf)->offset))) ++ ++#define GETBUFADDR( __buf ) ((u32)(__buf)->bus_address) ++ ++#define GETRINGOFFSET() (_entry->ring_ofs) ++ ++static __inline__ int mach64_find_pending_buf_entry(drm_mach64_private_t * ++ dev_priv, ++ drm_mach64_freelist_t ** ++ entry, struct drm_buf * buf) ++{ ++ struct list_head *ptr; ++#if MACH64_EXTRA_CHECKING ++ if (list_empty(&dev_priv->pending)) { ++ DRM_ERROR("Empty pending list in \n"); ++ return -EINVAL; ++ } ++#endif ++ ptr = dev_priv->pending.prev; ++ *entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ while ((*entry)->buf != buf) { ++ if (ptr == &dev_priv->pending) { ++ return -EFAULT; ++ } ++ ptr = ptr->prev; ++ *entry = list_entry(ptr, drm_mach64_freelist_t, list); ++ } ++ return 0; ++} ++ ++#define DMASETPTR( _p ) \ ++do { \ ++ _buf = (_p); \ ++ _outcount = 0; \ ++ _buf_wptr = GETBUFPTR( _buf ); \ ++} while(0) ++ ++/* FIXME: use a private set of smaller buffers for state emits, clears, and swaps? */ ++#define DMAGETPTR( file_priv, dev_priv, n ) \ ++do { \ ++ if ( MACH64_VERBOSE ) { \ ++ DRM_INFO( "DMAGETPTR( %d )\n", (n) ); \ ++ } \ ++ _buf = mach64_freelist_get( dev_priv ); \ ++ if (_buf == NULL) { \ ++ DRM_ERROR("couldn't get buffer in DMAGETPTR\n"); \ ++ return -EAGAIN; \ ++ } \ ++ if (_buf->pending) { \ ++ DRM_ERROR("pending buf in DMAGETPTR\n"); \ ++ return -EFAULT; \ ++ } \ ++ _buf->file_priv = file_priv; \ ++ _outcount = 0; \ ++ \ ++ _buf_wptr = GETBUFPTR( _buf ); \ ++} while (0) ++ ++#define DMAOUTREG( reg, val ) \ ++do { \ ++ if ( MACH64_VERBOSE ) { \ ++ DRM_INFO( " DMAOUTREG( 0x%x = 0x%08x )\n", \ ++ reg, val ); \ ++ } \ ++ _buf_wptr[_outcount++] = cpu_to_le32(DMAREG(reg)); \ ++ _buf_wptr[_outcount++] = cpu_to_le32((val)); \ ++ _buf->used += 8; \ ++} while (0) ++ ++#define DMAADVANCE( dev_priv, _discard ) \ ++ do { \ ++ struct list_head *ptr; \ ++ int ret; \ ++ \ ++ if ( MACH64_VERBOSE ) { \ ++ DRM_INFO( "DMAADVANCE() in \n" ); \ ++ } \ ++ \ ++ if (_buf->used <= 0) { \ ++ DRM_ERROR( "DMAADVANCE(): sending empty buf %d\n", \ ++ _buf->idx ); \ ++ return -EFAULT; \ ++ } \ ++ if (_buf->pending) { \ ++ /* This is a resued buffer, so we need to find it in the pending list */ \ ++ if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \ ++ DRM_ERROR( "DMAADVANCE(): couldn't find pending buf %d\n", _buf->idx ); \ ++ return ret; \ ++ } \ ++ if (_entry->discard) { \ ++ DRM_ERROR( "DMAADVANCE(): sending discarded pending buf %d\n", _buf->idx ); \ ++ return -EFAULT; \ ++ } \ ++ } else { \ ++ if (list_empty(&dev_priv->placeholders)) { \ ++ DRM_ERROR( "DMAADVANCE(): empty placeholder list\n"); \ ++ return -EFAULT; \ ++ } \ ++ ptr = dev_priv->placeholders.next; \ ++ list_del(ptr); \ ++ _entry = list_entry(ptr, drm_mach64_freelist_t, list); \ ++ _buf->pending = 1; \ ++ _entry->buf = _buf; \ ++ list_add_tail(ptr, &dev_priv->pending); \ ++ } \ ++ _entry->discard = (_discard); \ ++ if ((ret = mach64_add_buf_to_ring( dev_priv, _entry ))) \ ++ return ret; \ ++ } while (0) ++ ++#define DMADISCARDBUF() \ ++ do { \ ++ if (_entry == NULL) { \ ++ int ret; \ ++ if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \ ++ DRM_ERROR( "couldn't find pending buf %d\n", \ ++ _buf->idx ); \ ++ return ret; \ ++ } \ ++ } \ ++ _entry->discard = 1; \ ++ } while(0) ++ ++#define DMAADVANCEHOSTDATA( dev_priv ) \ ++ do { \ ++ struct list_head *ptr; \ ++ int ret; \ ++ \ ++ if ( MACH64_VERBOSE ) { \ ++ DRM_INFO( "DMAADVANCEHOSTDATA() in \n" ); \ ++ } \ ++ \ ++ if (_buf->used <= 0) { \ ++ DRM_ERROR( "DMAADVANCEHOSTDATA(): sending empty buf %d\n", _buf->idx ); \ ++ return -EFAULT; \ ++ } \ ++ if (list_empty(&dev_priv->placeholders)) { \ ++ DRM_ERROR( "empty placeholder list in DMAADVANCEHOSTDATA()\n" ); \ ++ return -EFAULT; \ ++ } \ ++ \ ++ ptr = dev_priv->placeholders.next; \ ++ list_del(ptr); \ ++ _entry = list_entry(ptr, drm_mach64_freelist_t, list); \ ++ _entry->buf = _buf; \ ++ _entry->buf->pending = 1; \ ++ list_add_tail(ptr, &dev_priv->pending); \ ++ _entry->discard = 1; \ ++ if ((ret = mach64_add_hostdata_buf_to_ring( dev_priv, _entry ))) \ ++ return ret; \ ++ } while (0) ++ ++#endif /* __MACH64_DRV_H__ */ +--- /dev/null ++++ b/drivers/gpu/drm/mach64/mach64_irq.c +@@ -0,0 +1,159 @@ ++/* mach64_irq.c -- IRQ handling for ATI Mach64 -*- linux-c -*- ++ * Created: Tue Feb 25, 2003 by Leif Delgass, based on radeon_irq.c/r128_irq.c ++ */ ++/*- ++ * Copyright (C) The Weather Channel, Inc. 2002. ++ * Copyright 2003 Leif Delgass ++ * All Rights Reserved. ++ * ++ * The Weather Channel (TM) funded Tungsten Graphics to develop the ++ * initial release of the Radeon 8500 driver under the XFree86 license. ++ * This notice must be preserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * Keith Whitwell ++ * Eric Anholt ++ * Leif Delgass ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "mach64_drm.h" ++#include "mach64_drv.h" ++ ++irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS) ++{ ++ struct drm_device *dev = arg; ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ int status; ++ ++ status = MACH64_READ(MACH64_CRTC_INT_CNTL); ++ ++ /* VBLANK interrupt */ ++ if (status & MACH64_CRTC_VBLANK_INT) { ++ /* Mask off all interrupt ack bits before setting the ack bit, since ++ * there may be other handlers outside the DRM. ++ * ++ * NOTE: On mach64, you need to keep the enable bits set when doing ++ * the ack, despite what the docs say about not acking and enabling ++ * in a single write. ++ */ ++ MACH64_WRITE(MACH64_CRTC_INT_CNTL, ++ (status & ~MACH64_CRTC_INT_ACKS) ++ | MACH64_CRTC_VBLANK_INT); ++ ++ atomic_inc(&dev_priv->vbl_received); ++ drm_handle_vblank(dev, 0); ++ return IRQ_HANDLED; ++ } ++ return IRQ_NONE; ++} ++ ++u32 mach64_get_vblank_counter(struct drm_device * dev, int crtc) ++{ ++ const drm_mach64_private_t *const dev_priv = dev->dev_private; ++ ++ if (crtc != 0) ++ return 0; ++ ++ return atomic_read(&dev_priv->vbl_received); ++} ++ ++int mach64_enable_vblank(struct drm_device * dev, int crtc) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL); ++ ++ if (crtc != 0) { ++ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", ++ crtc); ++ return -EINVAL; ++ } ++ ++ DRM_DEBUG("before enable vblank CRTC_INT_CTNL: 0x%08x\n", status); ++ ++ /* Turn on VBLANK interrupt */ ++ MACH64_WRITE(MACH64_CRTC_INT_CNTL, MACH64_READ(MACH64_CRTC_INT_CNTL) ++ | MACH64_CRTC_VBLANK_INT_EN); ++ ++ return 0; ++} ++ ++void mach64_disable_vblank(struct drm_device * dev, int crtc) ++{ ++ if (crtc != 0) { ++ DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", ++ crtc); ++ return; ++ } ++ ++ /* ++ * FIXME: implement proper interrupt disable by using the vblank ++ * counter register (if available). ++ */ ++} ++ ++static void mach64_disable_vblank_local(struct drm_device * dev, int crtc) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL); ++ ++ if (crtc != 0) { ++ DRM_ERROR("tried to disable vblank on non-existent crtc %d\n", ++ crtc); ++ return; ++ } ++ ++ DRM_DEBUG("before disable vblank CRTC_INT_CTNL: 0x%08x\n", status); ++ ++ /* Disable and clear VBLANK interrupt */ ++ MACH64_WRITE(MACH64_CRTC_INT_CNTL, (status & ~MACH64_CRTC_VBLANK_INT_EN) ++ | MACH64_CRTC_VBLANK_INT); ++} ++ ++void mach64_driver_irq_preinstall(struct drm_device * dev) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ ++ u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL); ++ ++ DRM_DEBUG("before install CRTC_INT_CTNL: 0x%08x\n", status); ++ ++ mach64_disable_vblank_local(dev, 0); ++} ++ ++int mach64_driver_irq_postinstall(struct drm_device * dev) ++{ ++ return drm_vblank_init(dev, 1); ++} ++ ++void mach64_driver_irq_uninstall(struct drm_device * dev) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ if (!dev_priv) ++ return; ++ ++ mach64_disable_vblank_local(dev, 0); ++ ++ DRM_DEBUG("after uninstall CRTC_INT_CTNL: 0x%08x\n", ++ MACH64_READ(MACH64_CRTC_INT_CNTL)); ++} +--- /dev/null ++++ b/drivers/gpu/drm/mach64/mach64_state.c +@@ -0,0 +1,910 @@ ++/* mach64_state.c -- State support for mach64 (Rage Pro) driver -*- linux-c -*- ++ * Created: Sun Dec 03 19:20:26 2000 by gareth@valinux.com ++ */ ++/* ++ * Copyright 2000 Gareth Hughes ++ * Copyright 2002-2003 Leif Delgass ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT OWNER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ++ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: ++ * Gareth Hughes ++ * Leif Delgass ++ * José Fonseca ++ */ ++ ++#include "drmP.h" ++#include "drm.h" ++#include "mach64_drm.h" ++#include "mach64_drv.h" ++ ++/* Interface history: ++ * ++ * 1.0 - Initial mach64 DRM ++ * ++ */ ++struct drm_ioctl_desc mach64_ioctls[] = { ++ DRM_IOCTL_DEF(DRM_MACH64_INIT, mach64_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), ++ DRM_IOCTL_DEF(DRM_MACH64_CLEAR, mach64_dma_clear, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_MACH64_SWAP, mach64_dma_swap, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_MACH64_IDLE, mach64_dma_idle, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_MACH64_RESET, mach64_engine_reset, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_MACH64_VERTEX, mach64_dma_vertex, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_MACH64_BLIT, mach64_dma_blit, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_MACH64_FLUSH, mach64_dma_flush, DRM_AUTH), ++ DRM_IOCTL_DEF(DRM_MACH64_GETPARAM, mach64_get_param, DRM_AUTH), ++}; ++ ++int mach64_max_ioctl = DRM_ARRAY_SIZE(mach64_ioctls); ++ ++/* ================================================================ ++ * DMA hardware state programming functions ++ */ ++ ++static void mach64_print_dirty(const char *msg, unsigned int flags) ++{ ++ DRM_DEBUG("%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s\n", ++ msg, ++ flags, ++ (flags & MACH64_UPLOAD_DST_OFF_PITCH) ? "dst_off_pitch, " : ++ "", ++ (flags & MACH64_UPLOAD_Z_ALPHA_CNTL) ? "z_alpha_cntl, " : "", ++ (flags & MACH64_UPLOAD_SCALE_3D_CNTL) ? "scale_3d_cntl, " : ++ "", (flags & MACH64_UPLOAD_DP_FOG_CLR) ? "dp_fog_clr, " : "", ++ (flags & MACH64_UPLOAD_DP_WRITE_MASK) ? "dp_write_mask, " : ++ "", ++ (flags & MACH64_UPLOAD_DP_PIX_WIDTH) ? "dp_pix_width, " : "", ++ (flags & MACH64_UPLOAD_SETUP_CNTL) ? "setup_cntl, " : "", ++ (flags & MACH64_UPLOAD_MISC) ? "misc, " : "", ++ (flags & MACH64_UPLOAD_TEXTURE) ? "texture, " : "", ++ (flags & MACH64_UPLOAD_TEX0IMAGE) ? "tex0 image, " : "", ++ (flags & MACH64_UPLOAD_TEX1IMAGE) ? "tex1 image, " : "", ++ (flags & MACH64_UPLOAD_CLIPRECTS) ? "cliprects, " : ""); ++} ++ ++/* Mach64 doesn't have hardware cliprects, just one hardware scissor, ++ * so the GL scissor is intersected with each cliprect here ++ */ ++/* This function returns 0 on success, 1 for no intersection, and ++ * negative for an error ++ */ ++static int mach64_emit_cliprect(struct drm_file *file_priv, ++ drm_mach64_private_t * dev_priv, ++ struct drm_clip_rect * box) ++{ ++ u32 sc_left_right, sc_top_bottom; ++ struct drm_clip_rect scissor; ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ drm_mach64_context_regs_t *regs = &sarea_priv->context_state; ++ DMALOCALS; ++ ++ DRM_DEBUG("box=%p\n", box); ++ ++ /* Get GL scissor */ ++ /* FIXME: store scissor in SAREA as a cliprect instead of in ++ * hardware format, or do intersection client-side ++ */ ++ scissor.x1 = regs->sc_left_right & 0xffff; ++ scissor.x2 = (regs->sc_left_right & 0xffff0000) >> 16; ++ scissor.y1 = regs->sc_top_bottom & 0xffff; ++ scissor.y2 = (regs->sc_top_bottom & 0xffff0000) >> 16; ++ ++ /* Intersect GL scissor with cliprect */ ++ if (box->x1 > scissor.x1) ++ scissor.x1 = box->x1; ++ if (box->y1 > scissor.y1) ++ scissor.y1 = box->y1; ++ if (box->x2 < scissor.x2) ++ scissor.x2 = box->x2; ++ if (box->y2 < scissor.y2) ++ scissor.y2 = box->y2; ++ /* positive return means skip */ ++ if (scissor.x1 >= scissor.x2) ++ return 1; ++ if (scissor.y1 >= scissor.y2) ++ return 1; ++ ++ DMAGETPTR(file_priv, dev_priv, 2); /* returns on failure to get buffer */ ++ ++ sc_left_right = ((scissor.x1 << 0) | (scissor.x2 << 16)); ++ sc_top_bottom = ((scissor.y1 << 0) | (scissor.y2 << 16)); ++ ++ DMAOUTREG(MACH64_SC_LEFT_RIGHT, sc_left_right); ++ DMAOUTREG(MACH64_SC_TOP_BOTTOM, sc_top_bottom); ++ ++ DMAADVANCE(dev_priv, 1); ++ ++ return 0; ++} ++ ++static __inline__ int mach64_emit_state(struct drm_file *file_priv, ++ drm_mach64_private_t * dev_priv) ++{ ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ drm_mach64_context_regs_t *regs = &sarea_priv->context_state; ++ unsigned int dirty = sarea_priv->dirty; ++ u32 offset = ((regs->tex_size_pitch & 0xf0) >> 2); ++ DMALOCALS; ++ ++ if (MACH64_VERBOSE) { ++ mach64_print_dirty(__FUNCTION__, dirty); ++ } else { ++ DRM_DEBUG("dirty=0x%08x\n", dirty); ++ } ++ ++ DMAGETPTR(file_priv, dev_priv, 17); /* returns on failure to get buffer */ ++ ++ if (dirty & MACH64_UPLOAD_MISC) { ++ DMAOUTREG(MACH64_DP_MIX, regs->dp_mix); ++ DMAOUTREG(MACH64_DP_SRC, regs->dp_src); ++ DMAOUTREG(MACH64_CLR_CMP_CNTL, regs->clr_cmp_cntl); ++ DMAOUTREG(MACH64_GUI_TRAJ_CNTL, regs->gui_traj_cntl); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_MISC; ++ } ++ ++ if (dirty & MACH64_UPLOAD_DST_OFF_PITCH) { ++ DMAOUTREG(MACH64_DST_OFF_PITCH, regs->dst_off_pitch); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_DST_OFF_PITCH; ++ } ++ if (dirty & MACH64_UPLOAD_Z_OFF_PITCH) { ++ DMAOUTREG(MACH64_Z_OFF_PITCH, regs->z_off_pitch); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_Z_OFF_PITCH; ++ } ++ if (dirty & MACH64_UPLOAD_Z_ALPHA_CNTL) { ++ DMAOUTREG(MACH64_Z_CNTL, regs->z_cntl); ++ DMAOUTREG(MACH64_ALPHA_TST_CNTL, regs->alpha_tst_cntl); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_Z_ALPHA_CNTL; ++ } ++ if (dirty & MACH64_UPLOAD_SCALE_3D_CNTL) { ++ DMAOUTREG(MACH64_SCALE_3D_CNTL, regs->scale_3d_cntl); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_SCALE_3D_CNTL; ++ } ++ if (dirty & MACH64_UPLOAD_DP_FOG_CLR) { ++ DMAOUTREG(MACH64_DP_FOG_CLR, regs->dp_fog_clr); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_DP_FOG_CLR; ++ } ++ if (dirty & MACH64_UPLOAD_DP_WRITE_MASK) { ++ DMAOUTREG(MACH64_DP_WRITE_MASK, regs->dp_write_mask); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_DP_WRITE_MASK; ++ } ++ if (dirty & MACH64_UPLOAD_DP_PIX_WIDTH) { ++ DMAOUTREG(MACH64_DP_PIX_WIDTH, regs->dp_pix_width); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_DP_PIX_WIDTH; ++ } ++ if (dirty & MACH64_UPLOAD_SETUP_CNTL) { ++ DMAOUTREG(MACH64_SETUP_CNTL, regs->setup_cntl); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_SETUP_CNTL; ++ } ++ ++ if (dirty & MACH64_UPLOAD_TEXTURE) { ++ DMAOUTREG(MACH64_TEX_SIZE_PITCH, regs->tex_size_pitch); ++ DMAOUTREG(MACH64_TEX_CNTL, regs->tex_cntl); ++ DMAOUTREG(MACH64_SECONDARY_TEX_OFF, regs->secondary_tex_off); ++ DMAOUTREG(MACH64_TEX_0_OFF + offset, regs->tex_offset); ++ sarea_priv->dirty &= ~MACH64_UPLOAD_TEXTURE; ++ } ++ ++ DMAADVANCE(dev_priv, 1); ++ ++ sarea_priv->dirty &= MACH64_UPLOAD_CLIPRECTS; ++ ++ return 0; ++ ++} ++ ++/* ================================================================ ++ * DMA command dispatch functions ++ */ ++ ++static int mach64_dma_dispatch_clear(struct drm_device * dev, ++ struct drm_file *file_priv, ++ unsigned int flags, ++ int cx, int cy, int cw, int ch, ++ unsigned int clear_color, ++ unsigned int clear_depth) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ drm_mach64_context_regs_t *ctx = &sarea_priv->context_state; ++ int nbox = sarea_priv->nbox; ++ struct drm_clip_rect *pbox = sarea_priv->boxes; ++ u32 fb_bpp, depth_bpp; ++ int i; ++ DMALOCALS; ++ ++ DRM_DEBUG("\n"); ++ ++ switch (dev_priv->fb_bpp) { ++ case 16: ++ fb_bpp = MACH64_DATATYPE_RGB565; ++ break; ++ case 32: ++ fb_bpp = MACH64_DATATYPE_ARGB8888; ++ break; ++ default: ++ return -EINVAL; ++ } ++ switch (dev_priv->depth_bpp) { ++ case 16: ++ depth_bpp = MACH64_DATATYPE_RGB565; ++ break; ++ case 24: ++ case 32: ++ depth_bpp = MACH64_DATATYPE_ARGB8888; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (!nbox) ++ return 0; ++ ++ DMAGETPTR(file_priv, dev_priv, nbox * 31); /* returns on failure to get buffer */ ++ ++ for (i = 0; i < nbox; i++) { ++ int x = pbox[i].x1; ++ int y = pbox[i].y1; ++ int w = pbox[i].x2 - x; ++ int h = pbox[i].y2 - y; ++ ++ DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n", ++ pbox[i].x1, pbox[i].y1, ++ pbox[i].x2, pbox[i].y2, flags); ++ ++ if (flags & (MACH64_FRONT | MACH64_BACK)) { ++ /* Setup for color buffer clears ++ */ ++ ++ DMAOUTREG(MACH64_Z_CNTL, 0); ++ DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); ++ ++ DMAOUTREG(MACH64_SC_LEFT_RIGHT, ctx->sc_left_right); ++ DMAOUTREG(MACH64_SC_TOP_BOTTOM, ctx->sc_top_bottom); ++ ++ DMAOUTREG(MACH64_CLR_CMP_CNTL, 0); ++ DMAOUTREG(MACH64_GUI_TRAJ_CNTL, ++ (MACH64_DST_X_LEFT_TO_RIGHT | ++ MACH64_DST_Y_TOP_TO_BOTTOM)); ++ ++ DMAOUTREG(MACH64_DP_PIX_WIDTH, ((fb_bpp << 0) | ++ (fb_bpp << 4) | ++ (fb_bpp << 8) | ++ (fb_bpp << 16) | ++ (fb_bpp << 28))); ++ ++ DMAOUTREG(MACH64_DP_FRGD_CLR, clear_color); ++ DMAOUTREG(MACH64_DP_WRITE_MASK, ctx->dp_write_mask); ++ DMAOUTREG(MACH64_DP_MIX, (MACH64_BKGD_MIX_D | ++ MACH64_FRGD_MIX_S)); ++ DMAOUTREG(MACH64_DP_SRC, (MACH64_BKGD_SRC_FRGD_CLR | ++ MACH64_FRGD_SRC_FRGD_CLR | ++ MACH64_MONO_SRC_ONE)); ++ ++ } ++ ++ if (flags & MACH64_FRONT) { ++ ++ DMAOUTREG(MACH64_DST_OFF_PITCH, ++ dev_priv->front_offset_pitch); ++ DMAOUTREG(MACH64_DST_X_Y, (y << 16) | x); ++ DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (h << 16) | w); ++ ++ } ++ ++ if (flags & MACH64_BACK) { ++ ++ DMAOUTREG(MACH64_DST_OFF_PITCH, ++ dev_priv->back_offset_pitch); ++ DMAOUTREG(MACH64_DST_X_Y, (y << 16) | x); ++ DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (h << 16) | w); ++ ++ } ++ ++ if (flags & MACH64_DEPTH) { ++ /* Setup for depth buffer clear ++ */ ++ DMAOUTREG(MACH64_Z_CNTL, 0); ++ DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); ++ ++ DMAOUTREG(MACH64_SC_LEFT_RIGHT, ctx->sc_left_right); ++ DMAOUTREG(MACH64_SC_TOP_BOTTOM, ctx->sc_top_bottom); ++ ++ DMAOUTREG(MACH64_CLR_CMP_CNTL, 0); ++ DMAOUTREG(MACH64_GUI_TRAJ_CNTL, ++ (MACH64_DST_X_LEFT_TO_RIGHT | ++ MACH64_DST_Y_TOP_TO_BOTTOM)); ++ ++ DMAOUTREG(MACH64_DP_PIX_WIDTH, ((depth_bpp << 0) | ++ (depth_bpp << 4) | ++ (depth_bpp << 8) | ++ (depth_bpp << 16) | ++ (depth_bpp << 28))); ++ ++ DMAOUTREG(MACH64_DP_FRGD_CLR, clear_depth); ++ DMAOUTREG(MACH64_DP_WRITE_MASK, 0xffffffff); ++ DMAOUTREG(MACH64_DP_MIX, (MACH64_BKGD_MIX_D | ++ MACH64_FRGD_MIX_S)); ++ DMAOUTREG(MACH64_DP_SRC, (MACH64_BKGD_SRC_FRGD_CLR | ++ MACH64_FRGD_SRC_FRGD_CLR | ++ MACH64_MONO_SRC_ONE)); ++ ++ DMAOUTREG(MACH64_DST_OFF_PITCH, ++ dev_priv->depth_offset_pitch); ++ DMAOUTREG(MACH64_DST_X_Y, (y << 16) | x); ++ DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (h << 16) | w); ++ } ++ } ++ ++ DMAADVANCE(dev_priv, 1); ++ ++ return 0; ++} ++ ++static int mach64_dma_dispatch_swap(struct drm_device * dev, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ int nbox = sarea_priv->nbox; ++ struct drm_clip_rect *pbox = sarea_priv->boxes; ++ u32 fb_bpp; ++ int i; ++ DMALOCALS; ++ ++ DRM_DEBUG("\n"); ++ ++ switch (dev_priv->fb_bpp) { ++ case 16: ++ fb_bpp = MACH64_DATATYPE_RGB565; ++ break; ++ case 32: ++ default: ++ fb_bpp = MACH64_DATATYPE_ARGB8888; ++ break; ++ } ++ ++ if (!nbox) ++ return 0; ++ ++ DMAGETPTR(file_priv, dev_priv, 13 + nbox * 4); /* returns on failure to get buffer */ ++ ++ DMAOUTREG(MACH64_Z_CNTL, 0); ++ DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); ++ ++ DMAOUTREG(MACH64_SC_LEFT_RIGHT, 0 | (8191 << 16)); /* no scissor */ ++ DMAOUTREG(MACH64_SC_TOP_BOTTOM, 0 | (16383 << 16)); ++ ++ DMAOUTREG(MACH64_CLR_CMP_CNTL, 0); ++ DMAOUTREG(MACH64_GUI_TRAJ_CNTL, (MACH64_DST_X_LEFT_TO_RIGHT | ++ MACH64_DST_Y_TOP_TO_BOTTOM)); ++ ++ DMAOUTREG(MACH64_DP_PIX_WIDTH, ((fb_bpp << 0) | ++ (fb_bpp << 4) | ++ (fb_bpp << 8) | ++ (fb_bpp << 16) | (fb_bpp << 28))); ++ ++ DMAOUTREG(MACH64_DP_WRITE_MASK, 0xffffffff); ++ DMAOUTREG(MACH64_DP_MIX, (MACH64_BKGD_MIX_D | MACH64_FRGD_MIX_S)); ++ DMAOUTREG(MACH64_DP_SRC, (MACH64_BKGD_SRC_BKGD_CLR | ++ MACH64_FRGD_SRC_BLIT | MACH64_MONO_SRC_ONE)); ++ ++ DMAOUTREG(MACH64_SRC_OFF_PITCH, dev_priv->back_offset_pitch); ++ DMAOUTREG(MACH64_DST_OFF_PITCH, dev_priv->front_offset_pitch); ++ ++ for (i = 0; i < nbox; i++) { ++ int x = pbox[i].x1; ++ int y = pbox[i].y1; ++ int w = pbox[i].x2 - x; ++ int h = pbox[i].y2 - y; ++ ++ DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", ++ pbox[i].x1, pbox[i].y1, pbox[i].x2, pbox[i].y2); ++ ++ DMAOUTREG(MACH64_SRC_WIDTH1, w); ++ DMAOUTREG(MACH64_SRC_Y_X, (x << 16) | y); ++ DMAOUTREG(MACH64_DST_Y_X, (x << 16) | y); ++ DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (h << 16) | w); ++ ++ } ++ ++ DMAADVANCE(dev_priv, 1); ++ ++ if (dev_priv->driver_mode == MACH64_MODE_DMA_ASYNC) { ++ for (i = 0; i < MACH64_MAX_QUEUED_FRAMES - 1; i++) { ++ dev_priv->frame_ofs[i] = dev_priv->frame_ofs[i + 1]; ++ } ++ dev_priv->frame_ofs[i] = GETRINGOFFSET(); ++ ++ dev_priv->sarea_priv->frames_queued++; ++ } ++ ++ return 0; ++} ++ ++static int mach64_do_get_frames_queued(drm_mach64_private_t * dev_priv) ++{ ++ drm_mach64_descriptor_ring_t *ring = &dev_priv->ring; ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ int i, start; ++ u32 head, tail, ofs; ++ ++ DRM_DEBUG("\n"); ++ ++ if (sarea_priv->frames_queued == 0) ++ return 0; ++ ++ tail = ring->tail; ++ mach64_ring_tick(dev_priv, ring); ++ head = ring->head; ++ ++ start = (MACH64_MAX_QUEUED_FRAMES - ++ DRM_MIN(MACH64_MAX_QUEUED_FRAMES, sarea_priv->frames_queued)); ++ ++ if (head == tail) { ++ sarea_priv->frames_queued = 0; ++ for (i = start; i < MACH64_MAX_QUEUED_FRAMES; i++) { ++ dev_priv->frame_ofs[i] = ~0; ++ } ++ return 0; ++ } ++ ++ for (i = start; i < MACH64_MAX_QUEUED_FRAMES; i++) { ++ ofs = dev_priv->frame_ofs[i]; ++ DRM_DEBUG("frame_ofs[%d] ofs: %d\n", i, ofs); ++ if (ofs == ~0 || ++ (head < tail && (ofs < head || ofs >= tail)) || ++ (head > tail && (ofs < head && ofs >= tail))) { ++ sarea_priv->frames_queued = ++ (MACH64_MAX_QUEUED_FRAMES - 1) - i; ++ dev_priv->frame_ofs[i] = ~0; ++ } ++ } ++ ++ return sarea_priv->frames_queued; ++} ++ ++/* Copy and verify a client submited buffer. ++ * FIXME: Make an assembly optimized version ++ */ ++static __inline__ int copy_from_user_vertex(u32 *to, ++ const u32 __user *ufrom, ++ unsigned long bytes) ++{ ++ unsigned long n = bytes; /* dwords remaining in buffer */ ++ u32 *from, *orig_from; ++ ++ from = drm_alloc(bytes, DRM_MEM_DRIVER); ++ if (from == NULL) ++ return -ENOMEM; ++ ++ if (DRM_COPY_FROM_USER(from, ufrom, bytes)) { ++ drm_free(from, bytes, DRM_MEM_DRIVER); ++ return -EFAULT; ++ } ++ orig_from = from; /* we'll be modifying the "from" ptr, so save it */ ++ ++ n >>= 2; ++ ++ while (n > 1) { ++ u32 data, reg, count; ++ ++ data = *from++; ++ ++ n--; ++ ++ reg = le32_to_cpu(data); ++ count = (reg >> 16) + 1; ++ if (count <= n) { ++ n -= count; ++ reg &= 0xffff; ++ ++ /* This is an exact match of Mach64's Setup Engine registers, ++ * excluding SETUP_CNTL (1_C1). ++ */ ++ if ((reg >= 0x0190 && reg < 0x01c1) || ++ (reg >= 0x01ca && reg <= 0x01cf)) { ++ *to++ = data; ++ memcpy(to, from, count << 2); ++ from += count; ++ to += count; ++ } else { ++ DRM_ERROR("Got bad command: 0x%04x\n", reg); ++ drm_free(orig_from, bytes, DRM_MEM_DRIVER); ++ return -EACCES; ++ } ++ } else { ++ DRM_ERROR ++ ("Got bad command count(=%u) dwords remaining=%lu\n", ++ count, n); ++ drm_free(orig_from, bytes, DRM_MEM_DRIVER); ++ return -EINVAL; ++ } ++ } ++ ++ drm_free(orig_from, bytes, DRM_MEM_DRIVER); ++ if (n == 0) ++ return 0; ++ else { ++ DRM_ERROR("Bad buf->used(=%lu)\n", bytes); ++ return -EINVAL; ++ } ++} ++ ++static int mach64_dma_dispatch_vertex(struct drm_device * dev, ++ struct drm_file *file_priv, ++ drm_mach64_vertex_t * vertex) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ struct drm_buf *copy_buf; ++ void *buf = vertex->buf; ++ unsigned long used = vertex->used; ++ int ret = 0; ++ int i = 0; ++ int done = 0; ++ int verify_ret = 0; ++ DMALOCALS; ++ ++ DRM_DEBUG("buf=%p used=%lu nbox=%d\n", ++ buf, used, sarea_priv->nbox); ++ ++ if (!used) ++ goto _vertex_done; ++ ++ copy_buf = mach64_freelist_get(dev_priv); ++ if (copy_buf == NULL) { ++ DRM_ERROR("couldn't get buffer\n"); ++ return -EAGAIN; ++ } ++ ++ /* Mach64's vertex data is actually register writes. To avoid security ++ * compromises these register writes have to be verified and copied from ++ * user space into a private DMA buffer. ++ */ ++ verify_ret = copy_from_user_vertex(GETBUFPTR(copy_buf), buf, used); ++ ++ if (verify_ret != 0) { ++ mach64_freelist_put(dev_priv, copy_buf); ++ goto _vertex_done; ++ } ++ ++ copy_buf->used = used; ++ ++ DMASETPTR(copy_buf); ++ ++ if (sarea_priv->dirty & ~MACH64_UPLOAD_CLIPRECTS) { ++ ret = mach64_emit_state(file_priv, dev_priv); ++ if (ret < 0) ++ return ret; ++ } ++ ++ do { ++ /* Emit the next cliprect */ ++ if (i < sarea_priv->nbox) { ++ ret = mach64_emit_cliprect(file_priv, dev_priv, ++ &sarea_priv->boxes[i]); ++ if (ret < 0) { ++ /* failed to get buffer */ ++ return ret; ++ } else if (ret != 0) { ++ /* null intersection with scissor */ ++ continue; ++ } ++ } ++ if ((i >= sarea_priv->nbox - 1)) ++ done = 1; ++ ++ /* Add the buffer to the DMA queue */ ++ DMAADVANCE(dev_priv, done); ++ ++ } while (++i < sarea_priv->nbox); ++ ++ if (!done) { ++ if (copy_buf->pending) { ++ DMADISCARDBUF(); ++ } else { ++ /* This buffer wasn't used (no cliprects), so place it ++ * back on the free list ++ */ ++ mach64_freelist_put(dev_priv, copy_buf); ++ } ++ } ++ ++_vertex_done: ++ sarea_priv->dirty &= ~MACH64_UPLOAD_CLIPRECTS; ++ sarea_priv->nbox = 0; ++ ++ return verify_ret; ++} ++ ++static __inline__ int copy_from_user_blit(u32 *to, ++ const u32 __user *ufrom, ++ unsigned long bytes) ++{ ++ to = (u32 *)((char *)to + MACH64_HOSTDATA_BLIT_OFFSET); ++ ++ if (DRM_COPY_FROM_USER(to, ufrom, bytes)) { ++ return -EFAULT; ++ } ++ ++ return 0; ++} ++ ++static int mach64_dma_dispatch_blit(struct drm_device * dev, ++ struct drm_file *file_priv, ++ drm_mach64_blit_t * blit) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ int dword_shift, dwords; ++ unsigned long used; ++ struct drm_buf *copy_buf; ++ int verify_ret = 0; ++ DMALOCALS; ++ ++ /* The compiler won't optimize away a division by a variable, ++ * even if the only legal values are powers of two. Thus, we'll ++ * use a shift instead. ++ */ ++ switch (blit->format) { ++ case MACH64_DATATYPE_ARGB8888: ++ dword_shift = 0; ++ break; ++ case MACH64_DATATYPE_ARGB1555: ++ case MACH64_DATATYPE_RGB565: ++ case MACH64_DATATYPE_VYUY422: ++ case MACH64_DATATYPE_YVYU422: ++ case MACH64_DATATYPE_ARGB4444: ++ dword_shift = 1; ++ break; ++ case MACH64_DATATYPE_CI8: ++ case MACH64_DATATYPE_RGB8: ++ dword_shift = 2; ++ break; ++ default: ++ DRM_ERROR("invalid blit format %d\n", blit->format); ++ return -EINVAL; ++ } ++ ++ /* Set buf->used to the bytes of blit data based on the blit dimensions ++ * and verify the size. When the setup is emitted to the buffer with ++ * the DMA* macros below, buf->used is incremented to include the bytes ++ * used for setup as well as the blit data. ++ */ ++ dwords = (blit->width * blit->height) >> dword_shift; ++ used = dwords << 2; ++ if (used <= 0 || ++ used > MACH64_BUFFER_SIZE - MACH64_HOSTDATA_BLIT_OFFSET) { ++ DRM_ERROR("Invalid blit size: %lu bytes\n", used); ++ return -EINVAL; ++ } ++ ++ copy_buf = mach64_freelist_get(dev_priv); ++ if (copy_buf == NULL) { ++ DRM_ERROR("couldn't get buffer\n"); ++ return -EAGAIN; ++ } ++ ++ /* Copy the blit data from userspace. ++ * ++ * XXX: This is overkill. The most efficient solution would be having ++ * two sets of buffers (one set private for vertex data, the other set ++ * client-writable for blits). However that would bring more complexity ++ * and would break backward compatability. The solution currently ++ * implemented is keeping all buffers private, allowing to secure the ++ * driver, without increasing complexity at the expense of some speed ++ * transfering data. ++ */ ++ verify_ret = copy_from_user_blit(GETBUFPTR(copy_buf), blit->buf, used); ++ ++ if (verify_ret != 0) { ++ mach64_freelist_put(dev_priv, copy_buf); ++ goto _blit_done; ++ } ++ ++ copy_buf->used = used; ++ ++ /* FIXME: Use a last buffer flag and reduce the state emitted for subsequent, ++ * continuation buffers? ++ */ ++ ++ /* Blit via BM_HOSTDATA (gui-master) - like HOST_DATA[0-15], but doesn't require ++ * a register command every 16 dwords. State setup is added at the start of the ++ * buffer -- the client leaves space for this based on MACH64_HOSTDATA_BLIT_OFFSET ++ */ ++ DMASETPTR(copy_buf); ++ ++ DMAOUTREG(MACH64_Z_CNTL, 0); ++ DMAOUTREG(MACH64_SCALE_3D_CNTL, 0); ++ ++ DMAOUTREG(MACH64_SC_LEFT_RIGHT, 0 | (8191 << 16)); /* no scissor */ ++ DMAOUTREG(MACH64_SC_TOP_BOTTOM, 0 | (16383 << 16)); ++ ++ DMAOUTREG(MACH64_CLR_CMP_CNTL, 0); /* disable */ ++ DMAOUTREG(MACH64_GUI_TRAJ_CNTL, ++ MACH64_DST_X_LEFT_TO_RIGHT | MACH64_DST_Y_TOP_TO_BOTTOM); ++ ++ DMAOUTREG(MACH64_DP_PIX_WIDTH, (blit->format << 0) /* dst pix width */ ++ |(blit->format << 4) /* composite pix width */ ++ |(blit->format << 8) /* src pix width */ ++ |(blit->format << 16) /* host data pix width */ ++ |(blit->format << 28) /* scaler/3D pix width */ ++ ); ++ ++ DMAOUTREG(MACH64_DP_WRITE_MASK, 0xffffffff); /* enable all planes */ ++ DMAOUTREG(MACH64_DP_MIX, MACH64_BKGD_MIX_D | MACH64_FRGD_MIX_S); ++ DMAOUTREG(MACH64_DP_SRC, ++ MACH64_BKGD_SRC_BKGD_CLR ++ | MACH64_FRGD_SRC_HOST | MACH64_MONO_SRC_ONE); ++ ++ DMAOUTREG(MACH64_DST_OFF_PITCH, ++ (blit->pitch << 22) | (blit->offset >> 3)); ++ DMAOUTREG(MACH64_DST_X_Y, (blit->y << 16) | blit->x); ++ DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (blit->height << 16) | blit->width); ++ ++ DRM_DEBUG("%lu bytes\n", used); ++ ++ /* Add the buffer to the queue */ ++ DMAADVANCEHOSTDATA(dev_priv); ++ ++_blit_done: ++ return verify_ret; ++} ++ ++/* ================================================================ ++ * IOCTL functions ++ */ ++ ++int mach64_dma_clear(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ drm_mach64_clear_t *clear = data; ++ int ret; ++ ++ DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); ++ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ if (sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS) ++ sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; ++ ++ ret = mach64_dma_dispatch_clear(dev, file_priv, clear->flags, ++ clear->x, clear->y, clear->w, clear->h, ++ clear->clear_color, ++ clear->clear_depth); ++ ++ /* Make sure we restore the 3D state next time. ++ */ ++ sarea_priv->dirty |= (MACH64_UPLOAD_CONTEXT | MACH64_UPLOAD_MISC); ++ return ret; ++} ++ ++int mach64_dma_swap(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ int ret; ++ ++ DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); ++ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ if (sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS) ++ sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; ++ ++ ret = mach64_dma_dispatch_swap(dev, file_priv); ++ ++ /* Make sure we restore the 3D state next time. ++ */ ++ sarea_priv->dirty |= (MACH64_UPLOAD_CONTEXT | MACH64_UPLOAD_MISC); ++ return ret; ++} ++ ++int mach64_dma_vertex(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ drm_mach64_vertex_t *vertex = data; ++ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ if (!dev_priv) { ++ DRM_ERROR("called with no initialization\n"); ++ return -EINVAL; ++ } ++ ++ DRM_DEBUG("pid=%d buf=%p used=%lu discard=%d\n", ++ DRM_CURRENTPID, ++ vertex->buf, vertex->used, vertex->discard); ++ ++ if (vertex->prim < 0 || vertex->prim > MACH64_PRIM_POLYGON) { ++ DRM_ERROR("buffer prim %d\n", vertex->prim); ++ return -EINVAL; ++ } ++ ++ if (vertex->used > MACH64_BUFFER_SIZE || (vertex->used & 3) != 0) { ++ DRM_ERROR("Invalid vertex buffer size: %lu bytes\n", ++ vertex->used); ++ return -EINVAL; ++ } ++ ++ if (sarea_priv->nbox > MACH64_NR_SAREA_CLIPRECTS) ++ sarea_priv->nbox = MACH64_NR_SAREA_CLIPRECTS; ++ ++ return mach64_dma_dispatch_vertex(dev, file_priv, vertex); ++} ++ ++int mach64_dma_blit(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv; ++ drm_mach64_blit_t *blit = data; ++ int ret; ++ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ ++ ret = mach64_dma_dispatch_blit(dev, file_priv, blit); ++ ++ /* Make sure we restore the 3D state next time. ++ */ ++ sarea_priv->dirty |= (MACH64_UPLOAD_CONTEXT | ++ MACH64_UPLOAD_MISC | MACH64_UPLOAD_CLIPRECTS); ++ ++ return ret; ++} ++ ++int mach64_get_param(struct drm_device *dev, void *data, ++ struct drm_file *file_priv) ++{ ++ drm_mach64_private_t *dev_priv = dev->dev_private; ++ drm_mach64_getparam_t *param = data; ++ int value; ++ ++ DRM_DEBUG("\n"); ++ ++ if (!dev_priv) { ++ DRM_ERROR("called with no initialization\n"); ++ return -EINVAL; ++ } ++ ++ switch (param->param) { ++ case MACH64_PARAM_FRAMES_QUEUED: ++ /* Needs lock since it calls mach64_ring_tick() */ ++ LOCK_TEST_WITH_RETURN(dev, file_priv); ++ value = mach64_do_get_frames_queued(dev_priv); ++ break; ++ case MACH64_PARAM_IRQ_NR: ++ value = dev->irq; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) { ++ DRM_ERROR("copy_to_user\n"); ++ return -EFAULT; ++ } ++ ++ return 0; ++} +--- linux/drivers/gpu/drm/Kconfig.gpu-drm-mach64.orig 2014-03-08 18:52:34.979768492 +0200 ++++ linux/drivers/gpu/drm/Kconfig 2014-03-08 18:55:18.769681473 +0200 +@@ -130,6 +130,17 @@ config DRM_I810 + + source "drivers/gpu/drm/i915/Kconfig" + ++config DRM_MACH64 ++ tristate "ATI Rage Pro (Mach64)" ++ depends on DRM && PCI ++ help ++ Choose this option if you have an ATI Rage Pro (mach64 chipset) ++ graphics card. Example cards include: 3D Rage Pro, Xpert 98, ++ 3D Rage LT Pro, 3D Rage XL/XC, and 3D Rage Mobility (P/M, M1). ++ Cards earlier than ATI Rage Pro (e.g. Rage II) are not supported. ++ If M is selected, the module will be called mach64. AGP support for ++ this card is strongly suggested (unless you have a PCI version). ++ + config DRM_MGA + tristate "Matrox g200/g400" + depends on DRM && PCI +--- linux/drivers/gpu/drm/Makefile.gpu-drm-mach64.orig ++++ linux/drivers/gpu/drm/Makefile +@@ -39,6 +39,7 @@ obj-$(CONFIG_DRM_TDFX) += tdfx/ + obj-$(CONFIG_DRM_R128) += r128/ + obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ + obj-$(CONFIG_DRM_RADEON)+= radeon/ ++obj-$(CONFIG_DRM_MACH64)+= mach64/ + obj-$(CONFIG_DRM_MGA) += mga/ + obj-$(CONFIG_DRM_I810) += i810/ + obj-$(CONFIG_DRM_I915) += i915/ diff --git a/kernel/kernel/files/patches/mageia/hid-usbhid-IBM-BladeCenterHS20-quirk.patch b/kernel/kernel/files/patches/mageia/hid-usbhid-IBM-BladeCenterHS20-quirk.patch new file mode 100644 index 00000000..d8e7fa4d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/hid-usbhid-IBM-BladeCenterHS20-quirk.patch @@ -0,0 +1,37 @@ +Subject: Add blacklist of usb hid modules + +IBM Blade Center HS20 can connect PS2 kerboard and mouse, It is USB emulation. +This devices need HID_QUIRK_IGNORE option. + +This patch is workaround. + +[ rediffed for 2.6.28 -- herton ] +Signed-off-by: Go Taniguchi + +--- + drivers/hid/hid-core.c | 2 ++ + drivers/hid/hid-ids.h | 2 ++ + 2 files changed, 4 insertions(+) + +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -2062,6 +2062,8 @@ static const struct hid_device_id hid_ig + { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_IBM, 0x4001) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_IBM, 0x4002) }, + { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, + { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_410) }, + { HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_510) }, +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -46,6 +46,8 @@ + #define USB_VENDOR_ID_AFATECH 0x15a4 + #define USB_DEVICE_ID_AFATECH_AF9016 0x9016 + ++#define USB_VENDOR_ID_IBM 0x04b3 ++ + #define USB_VENDOR_ID_AIPTEK 0x08ca + #define USB_DEVICE_ID_AIPTEK_01 0x0001 + #define USB_DEVICE_ID_AIPTEK_10 0x0010 diff --git a/kernel/kernel/files/patches/mageia/ide-pci-sis5513-965.patch b/kernel/kernel/files/patches/mageia/ide-pci-sis5513-965.patch new file mode 100644 index 00000000..9c54ab70 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/ide-pci-sis5513-965.patch @@ -0,0 +1,23 @@ +--- + drivers/ide/sis5513.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff -p -up linux-2.6.28/drivers/ide/sis5513.c.orig linux-2.6.28/drivers/ide/sis5513.c +--- linux-2.6.28/drivers/ide/sis5513.c.orig 2008-12-08 12:41:13.000000000 -0500 ++++ linux-2.6.28/drivers/ide/sis5513.c 2008-12-08 12:51:32.000000000 -0500 +@@ -412,6 +412,15 @@ static int __devinit sis_find_family(str + pci_name(dev)); + } + } ++ else if (trueid == 0x180) { /* sis965L */ ++ u16 pci_command; ++ pci_read_config_word(dev, PCI_COMMAND, &pci_command); ++ pci_command &= ~PCI_COMMAND_INTX_DISABLE; ++ pci_write_config_word(dev, PCI_COMMAND, pci_command); ++ chipset_family = ATA_133; ++ printk(KERN_INFO DRV_NAME " %s: SiS 965 IDE UDMA133 controller\n", ++ pci_name(dev)); ++ } + } + + if (!chipset_family) { /* Belongs to pci-quirks */ diff --git a/kernel/kernel/files/patches/mageia/include-kbuild-export-pci_ids.patch b/kernel/kernel/files/patches/mageia/include-kbuild-export-pci_ids.patch new file mode 100644 index 00000000..ebcf9832 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/include-kbuild-export-pci_ids.patch @@ -0,0 +1,19 @@ +From Thierry Vignaud (Mandriva) + +We now lacks /usr/include/linux/pci_ids.h which break ldetect build... +Can you readd it please? +Thanks +--- + include/linux/Kbuild | 1 + + 1 file changed, 1 insertion(+) + +--- linux/include/uapi/linux/Kbuild.include-kbuild-export-pci_ids.orig ++++ linux/include/uapi/linux/Kbuild +@@ -277,6 +277,7 @@ header-y += param.h + header-y += parport.h + header-y += patchkey.h + header-y += pci.h ++header-y += pci_ids.h + header-y += pci_regs.h + header-y += perf_event.h + header-y += personality.h diff --git a/kernel/kernel/files/patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch b/kernel/kernel/files/patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch new file mode 100644 index 00000000..2ed76671 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch @@ -0,0 +1,47 @@ +From 993b3a3f80a7842a48cd46c2b41e1b3ef6302468 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 24 Oct 2014 14:55:24 -0700 +Subject: [PATCH] Input: i8042 - quirks for Fujitsu Lifebook A544 and Lifebook + AH544 + +These models need i8042.notimeout, otherwise the touchpad will not work. + +BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=69731 +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1111138 +Cc: stable@vger.kernel.org +Signed-off-by: Hans de Goede +Signed-off-by: Dmitry Torokhov +--- + drivers/input/serio/i8042-x86ia64io.h | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index a0bcbb6..aa9b299 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -364,6 +364,22 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { + }, + }, + { ++ /* Fujitsu A544 laptop */ ++ /* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"), ++ }, ++ }, ++ { ++ /* Fujitsu AH544 laptop */ ++ /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"), ++ }, ++ }, ++ { + /* Fujitsu U574 laptop */ + /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ + .matches = { +-- +2.1.2 + diff --git a/kernel/kernel/files/patches/mageia/iommu-vt-d-Remove-unused-variable.patch b/kernel/kernel/files/patches/mageia/iommu-vt-d-Remove-unused-variable.patch new file mode 100644 index 00000000..d6826897 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/iommu-vt-d-Remove-unused-variable.patch @@ -0,0 +1,29 @@ +From 509fca899d5682a6eee3d1fb70bba7c89439034b Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Mon, 23 Mar 2015 19:49:56 -0600 +Subject: [PATCH] iommu/vt-d: Remove unused variable + +Unused after commit 71684406905f ("iommu/vt-d: Detach domain *only* +from attached iommus"). Reported by 0-day builder. + +Signed-off-by: Alex Williamson +Signed-off-by: Joerg Roedel +--- + drivers/iommu/intel-iommu.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index a83c965..2d1e05b 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -1742,7 +1742,6 @@ static int domain_init(struct dmar_domain *domain, int guest_width) + + static void domain_exit(struct dmar_domain *domain) + { +- struct dmar_drhd_unit *drhd; + struct page *freelist = NULL; + int i; + +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/md-raid5-dont-record-new-size-if-resize_stripes-fails.patch b/kernel/kernel/files/patches/mageia/md-raid5-dont-record-new-size-if-resize_stripes-fails.patch new file mode 100644 index 00000000..0e1c1439 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/md-raid5-dont-record-new-size-if-resize_stripes-fails.patch @@ -0,0 +1,36 @@ +From: NeilBrown +Subject: [PATCH 5/7] md/raid5: don't record new size if resize_stripes fails. +Date: Fri, 08 May 2015 18:56:11 +1000 + +If any memory allocation in resize_stripes fails we will return +-ENOMEM, but in some cases we update conf->pool_size anyway. + +This means that if we try again, the allocations will be assumed +to be larger than they are, and badness results. + +So only update pool_size if there is no error. + +This bug was introduced in 2.6.17 and the patch is suitable for +-stable. + +Fixes: ad01c9e3752f ("[PATCH] md: Allow stripes to be expanded in preparation for expanding an array") +Cc: stable@vger.kernel.org (v2.6.17+) +Signed-off-by: NeilBrown +--- + drivers/md/raid5.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 85dc0e67fb88..9748e525e4c0 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -2216,7 +2216,8 @@ static int resize_stripes(struct r5conf *conf, int newsize) + + conf->slab_cache = sc; + conf->active_name = 1-conf->active_name; +- conf->pool_size = newsize; ++ if (!err) ++ conf->pool_size = newsize; + return err; + } + diff --git a/kernel/kernel/files/patches/mageia/media-usb-pwc-lie-in-proc-usb-devices.patch b/kernel/kernel/files/patches/mageia/media-usb-pwc-lie-in-proc-usb-devices.patch new file mode 100644 index 00000000..32d496e3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/media-usb-pwc-lie-in-proc-usb-devices.patch @@ -0,0 +1,13 @@ +diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c +index f976df4..32c883b 100644 +--- a/drivers/media/usb/pwc/pwc-if.c ++++ b/drivers/media/usb/pwc/pwc-if.c +@@ -119,7 +119,7 @@ static void usb_pwc_disconnect(struct us + static void pwc_isoc_cleanup(struct pwc_device *pdev); + + static struct usb_driver pwc_driver = { +- .name = "Philips webcam", /* name */ ++ .name = "pwc", /* name */ + .id_table = pwc_device_table, + .probe = usb_pwc_probe, /* probe() */ + .disconnect = usb_pwc_disconnect, /* disconnect() */ diff --git a/kernel/kernel/files/patches/mageia/mm-vmscan-wake-up-all-pfmemalloc-throttled-processes.patch b/kernel/kernel/files/patches/mageia/mm-vmscan-wake-up-all-pfmemalloc-throttled-processes.patch new file mode 100644 index 00000000..5c3ffae1 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/mm-vmscan-wake-up-all-pfmemalloc-throttled-processes.patch @@ -0,0 +1,44 @@ +From cfc511557945812280699a92f171ddd2d254aca6 Mon Sep 17 00:00:00 2001 +From: Vlastimil Babka +Date: Wed, 11 Feb 2015 15:24:47 -0800 +Subject: [PATCH] mm, vmscan: wake up all pfmemalloc-throttled processes at + once + +Kswapd in balance_pgdate() currently uses wake_up() on processes waiting +in throttle_direct_reclaim(), which only wakes up a single process. This +might leave processes waiting for longer than necessary, until the check +is reached in the next loop iteration. Processes might also be left +waiting if zone was fully balanced in single iteration. Note that the +comment in balance_pgdat() also says "Wake them", so waking up a single +process does not seem intentional. + +Thus, replace wake_up() with wake_up_all(). + +Signed-off-by: Vlastimil Babka +Cc: Mel Gorman +Cc: Johannes Weiner +Cc: Michal Hocko +Cc: Vladimir Davydov +Acked-by: Rik van Riel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +--- + mm/vmscan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mm/vmscan.c b/mm/vmscan.c +index dcd90c8..f756a20 100644 +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -3175,7 +3175,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, + */ + if (waitqueue_active(&pgdat->pfmemalloc_wait) && + pfmemalloc_watermark_ok(pgdat)) +- wake_up(&pgdat->pfmemalloc_wait); ++ wake_up_all(&pgdat->pfmemalloc_wait); + + /* + * Fragmentation may mean that the system cannot be rebalanced +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/mm-writeback-use-1-instead-of-1-to-protect-against-div-.patch b/kernel/kernel/files/patches/mageia/mm-writeback-use-1-instead-of-1-to-protect-against-div-.patch new file mode 100644 index 00000000..e54d0773 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/mm-writeback-use-1-instead-of-1-to-protect-against-div-.patch @@ -0,0 +1,68 @@ +From 464d1387acb94dc43ba772b35242345e3d2ead1b Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Tue, 21 Apr 2015 16:49:13 -0400 +Subject: [PATCH] writeback: use |1 instead of +1 to protect against div by + zero + +mm/page-writeback.c has several places where 1 is added to the divisor +to prevent division by zero exceptions; however, if the original +divisor is equivalent to -1, adding 1 leads to division by zero. + +There are three places where +1 is used for this purpose - one in +pos_ratio_polynom() and two in bdi_position_ratio(). The second one +in bdi_position_ratio() actually triggered div-by-zero oops on a +machine running a 3.10 kernel. The divisor is + + x_intercept - bdi_setpoint + 1 == span + 1 + +span is confirmed to be (u32)-1. It isn't clear how it ended up that +but it could be from write bandwidth calculation underflow fixed by +c72efb658f7c ("writeback: fix possible underflow in write bandwidth +calculation"). + +At any rate, +1 isn't a proper protection against div-by-zero. This +patch converts all +1 protections to |1. Note that +bdi_update_dirty_ratelimit() was already using |1 before this patch. + +Signed-off-by: Tejun Heo +Cc: stable@vger.kernel.org +Reviewed-by: Jan Kara +Signed-off-by: Jens Axboe +--- + mm/page-writeback.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/mm/page-writeback.c b/mm/page-writeback.c +index 5daf556..eb59f7e 100644 +--- a/mm/page-writeback.c ++++ b/mm/page-writeback.c +@@ -580,7 +580,7 @@ static long long pos_ratio_polynom(unsigned long setpoint, + long x; + + x = div64_s64(((s64)setpoint - (s64)dirty) << RATELIMIT_CALC_SHIFT, +- limit - setpoint + 1); ++ (limit - setpoint) | 1); + pos_ratio = x; + pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT; + pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT; +@@ -807,7 +807,7 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi, + * scale global setpoint to bdi's: + * bdi_setpoint = setpoint * bdi_thresh / thresh + */ +- x = div_u64((u64)bdi_thresh << 16, thresh + 1); ++ x = div_u64((u64)bdi_thresh << 16, thresh | 1); + bdi_setpoint = setpoint * (u64)x >> 16; + /* + * Use span=(8*write_bw) in single bdi case as indicated by +@@ -822,7 +822,7 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi, + + if (bdi_dirty < x_intercept - span / 4) { + pos_ratio = div64_u64(pos_ratio * (x_intercept - bdi_dirty), +- x_intercept - bdi_setpoint + 1); ++ (x_intercept - bdi_setpoint) | 1); + } else + pos_ratio /= 4; + +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/mpt-vmware-fix.patch b/kernel/kernel/files/patches/mageia/mpt-vmware-fix.patch new file mode 100644 index 00000000..0b90277c --- /dev/null +++ b/kernel/kernel/files/patches/mageia/mpt-vmware-fix.patch @@ -0,0 +1,49 @@ +Subject: mpt scsi modules for VMWare's emulated + +The attached patch is a workaround for a bug in VMWare's emulated LSI +Fusion SCSI HBA. The emulated firmware returns zero for the maximum +number of attached devices; the real firmware returns a positive +number. Therefore, the kernel that boots and works fine on bare metal +will fail on VMWare because this firmware value is handed to the SCSI +midlayer, which then skips the entire bus scan. + +F7 bz 241935 + +The patch below was submitted by Eric Moore of LSI to the linux-scsi +mailing list: + +http://marc.info/?l=linux-scsi&m=117432237404247 + +then immediately rejected by Christoph Hellwig, who prefers that +VMWare fix their emulation instead. + +This patch is workaround. + +--- + drivers/message/fusion/mptbase.c | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/message/fusion/mptbase.c ++++ b/drivers/message/fusion/mptbase.c +@@ -3051,8 +3051,19 @@ GetPortFacts(MPT_ADAPTER *ioc, int portn + pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); + pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); + +- max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID : +- pfacts->MaxDevices; ++ switch (ioc->bus_type) { ++ case SAS: ++ max_id = pfacts->PortSCSIID; ++ break; ++ case FC: ++ max_id = pfacts->MaxDevices; ++ break; ++ case SPI: ++ default: ++ max_id = MPT_MAX_SCSI_DEVICES; ++ break; ++ } ++ + ioc->devices_per_bus = (max_id > 255) ? 256 : max_id; + ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256; + diff --git a/kernel/kernel/files/patches/mageia/net-ipv4-netfilter-ipt_IFWLOG-3.6-buildfix.patch b/kernel/kernel/files/patches/mageia/net-ipv4-netfilter-ipt_IFWLOG-3.6-buildfix.patch new file mode 100644 index 00000000..51041b6f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-ipv4-netfilter-ipt_IFWLOG-3.6-buildfix.patch @@ -0,0 +1,33 @@ + +Adapt to netlink changes in 3.6 + +Signed-off-by: Thomas Backlund + +--- linux/net/ipv4/netfilter/ipt_IFWLOG.c.orig 2012-10-17 22:44:57.000000000 +0300 ++++ linux/net/ipv4/netfilter/ipt_IFWLOG.c 2012-10-17 23:17:10.012725918 +0300 +@@ -56,9 +56,9 @@ static void send_packet(const struct nl_ + return; + } + +- nlh = NLMSG_PUT(skb, 0, 0, 0, size - sizeof(*nlh)); ++ nlh = nlmsg_put(skb, 0, 0, 0, size - sizeof(*nlh), 0); + +- memcpy(NLMSG_DATA(nlh), (const void *) msg, sizeof(*msg)); ++ memcpy(nlmsg_data(nlh), (const void *) msg, sizeof(*msg)); + + NETLINK_CB(skb).pid = 0; /* from kernel */ + NETLINK_CB(skb).dst_group = IFWLOGNLGRP_DEF; +@@ -169,9 +169,11 @@ static struct xt_target ipt_IFWLOG = { + static int __init ipt_ifwlog_init(void) + { + int err; ++ struct netlink_kernel_cfg cfg = { ++ .groups = IFWLOGNLGRP_MAX, ++ }; + +- nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, IFWLOGNLGRP_MAX, +- NULL, NULL, THIS_MODULE); ++ nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, THIS_MODULE, &cfg); + if (!nl) { + PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n"); + return -ENOMEM; diff --git a/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-2.6.35-buildfix.patch b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-2.6.35-buildfix.patch new file mode 100644 index 00000000..99d4d063 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-2.6.35-buildfix.patch @@ -0,0 +1,32 @@ +--- linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_IFWLOG.c.orig 2010-07-30 21:17:30.000000000 +0300 ++++ linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_IFWLOG.c 2010-07-31 13:46:33.834611944 +0300 +@@ -135,7 +135,7 @@ static void ipt_IFWLOG_packet(const stru + } + + static unsigned int ipt_IFWLOG_target(struct sk_buff *skb, +- const struct xt_target_param *target_param) ++ const struct xt_action_param *target_param) + { + const struct ipt_IFWLOG_info *info = target_param->targinfo; + +@@ -144,17 +144,17 @@ static unsigned int ipt_IFWLOG_target(st + return IPT_CONTINUE; + } + +-static bool ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param) ++static int ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param) + { + const struct ipt_IFWLOG_info *info = tgchk_param->targinfo; + + if (info->prefix[sizeof(info->prefix)-1] != '\0') { + DEBUGP("IFWLOG: prefix term %i\n", + info->prefix[sizeof(info->prefix)-1]); +- return false; ++ return -EINVAL; + } + +- return true; ++ return 0; + } + + static struct xt_target ipt_IFWLOG = { diff --git a/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-2.6.37-buildfix.patch b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-2.6.37-buildfix.patch new file mode 100644 index 00000000..0ae95aa3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-2.6.37-buildfix.patch @@ -0,0 +1,15 @@ + + net/ipv4/netfilter/ipt_IFWLOG.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.37-rc3-git1-tmb0.3/net/ipv4/netfilter/ipt_IFWLOG.c.orig 2010-11-24 21:58:36.000000000 +0200 ++++ linux-2.6.37-rc3-git1-tmb0.3/net/ipv4/netfilter/ipt_IFWLOG.c 2010-11-25 13:08:55.719379646 +0200 +@@ -141,7 +141,7 @@ static unsigned int ipt_IFWLOG_target(st + + ipt_IFWLOG_packet(skb, target_param->in, target_param->out, info); + +- return IPT_CONTINUE; ++ return XT_CONTINUE; + } + + static int ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param) diff --git a/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-3.7-buildfix.patch b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-3.7-buildfix.patch new file mode 100644 index 00000000..744e840f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-3.7-buildfix.patch @@ -0,0 +1,20 @@ +--- linux-3.7-rc8/net/ipv4/netfilter/ipt_IFWLOG.c.orig 2012-12-06 19:50:10.000000000 +0200 ++++ linux-3.7-rc8/net/ipv4/netfilter/ipt_IFWLOG.c 2012-12-06 20:55:23.669152916 +0200 +@@ -60,7 +60,7 @@ static void send_packet(const struct nl_ + + memcpy(nlmsg_data(nlh), (const void *) msg, sizeof(*msg)); + +- NETLINK_CB(skb).pid = 0; /* from kernel */ ++ NETLINK_CB(skb).portid = 0; /* from kernel */ + NETLINK_CB(skb).dst_group = IFWLOGNLGRP_DEF; + + if (nl) { +@@ -173,7 +173,7 @@ static int __init ipt_ifwlog_init(void) + .groups = IFWLOGNLGRP_MAX, + }; + +- nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, THIS_MODULE, &cfg); ++ nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, &cfg); + if (!nl) { + PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n"); + return -ENOMEM; diff --git a/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-mdv.patch b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-mdv.patch new file mode 100644 index 00000000..5ecc0151 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG-mdv.patch @@ -0,0 +1,264 @@ +ipt_IFWLOG: Mandriva changes + +This patch holds all the Mandriva changes done in ipt_IFWLOG +netfilter module. + +This work is mostly done by Thomas Backlund, Herton R. Krzesinski +and Luiz Fernando N. Capitulino. + +Signed-off-by: Luiz Fernando N. Capitulino +Signed-off-by: Herton Ronaldo Krzesinski + +--- + include/linux/netfilter_ipv4/Kbuild | 1 + include/linux/netfilter_ipv4/ipt_IFWLOG.h | 23 +++++- + net/ipv4/netfilter/ipt_IFWLOG.c | 108 +++++++++++++++--------------- + 3 files changed, 77 insertions(+), 55 deletions(-) + +diff -p -up linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h.orig linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h +--- linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h.orig 2008-12-12 10:55:07.000000000 -0500 ++++ linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h 2008-12-12 10:56:30.000000000 -0500 +@@ -1,10 +1,25 @@ +-#ifndef _IPT_IFWLOG_H +-#define _IPT_IFWLOG_H ++#ifndef _LINUX_IPT_IFWLOG_H ++#define _LINUX_IPT_IFWLOG_H + + #ifndef NETLINK_IFWLOG +-#define NETLINK_IFWLOG 19 ++#define NETLINK_IFWLOG 20 + #endif + ++#ifndef __KERNEL__ ++/* Multicast groups - backwards compatiblility for userspace */ ++#define IFWLOG_NLGRP_NONE 0x00000000 ++#define IFWLOG_NLGRP_DEF 0x00000001 /* default message group */ ++#endif ++ ++enum { ++ IFWLOGNLGRP_NONE, ++#define IFWLOGNLGRP_NONE IFWLOGNLGRP_NONE ++ IFWLOGNLGRP_DEF, ++#define IFWLOGNLGRP_DEF IFWLOGNLGRP_DEF ++ __IFWLOGNLGRP_MAX ++}; ++#define IFWLOGNLGRP_MAX (__IFWLOGNLGRP_MAX - 1) ++ + #define PREFSIZ 32 + + struct nl_msg { /* Netlink message */ +@@ -23,4 +38,4 @@ struct ipt_IFWLOG_info { + char prefix[PREFSIZ]; + }; + +-#endif /* _IPT_IFWLOG_H */ ++#endif /* _LINUX_IPT_IFWLOG_H */ +diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c.orig linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c +--- linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c.orig 2008-12-12 10:55:07.000000000 -0500 ++++ linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c 2008-12-12 10:57:16.000000000 -0500 +@@ -4,6 +4,14 @@ + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. ++ * ++ * 2007-10-10 Thomas Backlund : build fixes for 2.6.22.9 ++ * 2007-11-11 Herton Krzesinski : build fixes for 2.6.24-rc ++ * 2007-12-03 Luiz Capitulino : v1.1 ++ * - Better multicast group usage ++ * - Coding style fixes ++ * - Do not return -EINVAL by default in ipt_ifwlog_init() ++ * - Minor refinements + */ + + #include +@@ -19,12 +27,10 @@ + #include + + #include ++#include + #include + #include + +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Samir Bellabes "); +-MODULE_DESCRIPTION("Interactive firewall logging and module"); + + #if 0 + #define DEBUGP PRINTR +@@ -36,44 +42,41 @@ MODULE_DESCRIPTION("Interactive firewall + + static struct sock *nl; + +-#define GROUP 10 +- + /* send struct to userspace */ +-static void send_packet(struct nl_msg msg) ++static void send_packet(const struct nl_msg *msg) + { + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; ++ unsigned int size; + +- skb = alloc_skb(NLMSG_SPACE(sizeof(struct nl_msg)), GFP_ATOMIC); ++ size = NLMSG_SPACE(sizeof(*msg)); ++ skb = alloc_skb(size, GFP_ATOMIC); + if (!skb) { + PRINTR(KERN_WARNING "IFWLOG: OOM can't allocate skb\n"); +- return ; ++ return; + } + +- nlh = NLMSG_PUT(skb, 0, 0, 0, sizeof(struct nl_msg) - sizeof(*nlh)); ++ nlh = NLMSG_PUT(skb, 0, 0, 0, size - sizeof(*nlh)); + +- memcpy(NLMSG_DATA(nlh), (const void*)&msg, sizeof(struct nl_msg)); ++ memcpy(NLMSG_DATA(nlh), (const void *) msg, sizeof(*msg)); + + NETLINK_CB(skb).pid = 0; /* from kernel */ +- NETLINK_CB(skb).dst_pid = 0; /* multicast */ +- NETLINK_CB(skb).dst_group = 10; ++ NETLINK_CB(skb).dst_group = IFWLOGNLGRP_DEF; + + if (nl) { + DEBUGP(KERN_WARNING + "IFWLOG: nlmsg_len=%ld\nnlmsg_type=%d nlmsg_flags=%d\nnlmsg_seq=%ld nlmsg_pid = %ld\n", + (long)nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_flags, + (long)nlh->nlmsg_seq, (long)nlh->nlmsg_pid); +- DEBUGP(KERN_WARNING "prefix : %s\n", msg.prefix); ++ DEBUGP(KERN_WARNING "prefix : %s\n", msg->prefix); + +- netlink_broadcast(nl, skb, 0, 10, GFP_ATOMIC); +- return ; ++ netlink_broadcast(nl, skb, 0, IFWLOGNLGRP_DEF, GFP_ATOMIC); ++ return; + } + +- nlmsg_failure: +- if (skb) +- kfree_skb(skb); +- PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n"); +- return ; ++nlmsg_failure: ++ kfree_skb(skb); ++ PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n"); + } + + /* fill struct for userspace */ +@@ -128,73 +131,76 @@ static void ipt_IFWLOG_packet(const stru + do_gettimeofday((struct timeval *)&tv); + msg.timestamp_sec = tv.tv_sec; + +- send_packet(msg); ++ send_packet(&msg); + } + +-static unsigned int ipt_IFWLOG_target(struct sk_buff **pskb, +- const struct net_device *in, +- const struct net_device *out, +- unsigned int hooknum, +- const void *targinfo, +- void *userinfo) ++static unsigned int ipt_IFWLOG_target(struct sk_buff *skb, ++ const struct xt_target_param *target_param) + { +- const struct ipt_IFWLOG_info *info = targinfo; ++ const struct ipt_IFWLOG_info *info = target_param->targinfo; + +- ipt_IFWLOG_packet(*pskb, in, out, info); ++ ipt_IFWLOG_packet(skb, target_param->in, target_param->out, info); + + return IPT_CONTINUE; + } + +-static int ipt_IFWLOG_checkentry(const char *tablename, +- const struct ipt_entry *e, +- void *targinfo, +- unsigned int targinfosize, +- unsigned int hook_mask) ++static bool ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param) + { +- const struct ipt_IFWLOG_info *info = targinfo; ++ const struct ipt_IFWLOG_info *info = tgchk_param->targinfo; + + if (info->prefix[sizeof(info->prefix)-1] != '\0') { + DEBUGP("IFWLOG: prefix term %i\n", + info->prefix[sizeof(info->prefix)-1]); +- return 0; ++ return false; + } + +- return 1; ++ return true; + } + +-static struct ipt_target ipt_IFWLOG = { ++static struct xt_target ipt_IFWLOG = { + .name = "IFWLOG", ++ .family = AF_INET, + .target = ipt_IFWLOG_target, + .targetsize = sizeof(struct ipt_IFWLOG_info), + .checkentry = ipt_IFWLOG_checkentry, + .me = THIS_MODULE, + }; + +-static int __init init(void) ++static int __init ipt_ifwlog_init(void) + { +- nl = (struct sock*) netlink_kernel_create(NETLINK_IFWLOG, GROUP, NULL, THIS_MODULE); +- if (!nl) { +- PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n"); +- return -EINVAL; +- } ++ int err; + +- if (ipt_register_target(&ipt_IFWLOG)) { ++ nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, IFWLOGNLGRP_MAX, ++ NULL, NULL, THIS_MODULE); ++ if (!nl) { ++ PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n"); ++ return -ENOMEM; ++ } ++ ++ err = xt_register_target(&ipt_IFWLOG); ++ if (err) { + if (nl && nl->sk_socket) + sock_release(nl->sk_socket); +- return -EINVAL; ++ return err; + } + + PRINTR(KERN_INFO "IFWLOG: register target\n"); + return 0; + } + +-static void __exit fini(void) ++static void __exit ipt_ifwlog_fini(void) + { + if (nl && nl->sk_socket) +- sock_release(nl->sk_socket); ++ sock_release(nl->sk_socket); + PRINTR(KERN_INFO "IFWLOG: unregister target\n"); +- ipt_unregister_target(&ipt_IFWLOG); ++ xt_unregister_target(&ipt_IFWLOG); + } + +-module_init(init); +-module_exit(fini); ++module_init(ipt_ifwlog_init); ++module_exit(ipt_ifwlog_fini); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Samir Bellabes "); ++MODULE_AUTHOR("Luiz Capitulino "); ++MODULE_DESCRIPTION("Interactive firewall logging and module"); ++MODULE_VERSION("v1.1"); +--- linux/include/uapi/linux/netfilter_ipv4/Kbuild.net-netfilter-IFWLOG-mdv.orig ++++ linux/include/uapi/linux/netfilter_ipv4/Kbuild +@@ -2,6 +2,7 @@ header-y += ip_queue.h + header-y += ip_tables.h + header-y += ipt_CLUSTERIP.h + header-y += ipt_ECN.h ++header-y += ipt_IFWLOG.h + header-y += ipt_LOG.h + header-y += ipt_REJECT.h + header-y += ipt_TTL.h diff --git a/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG.patch b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG.patch new file mode 100644 index 00000000..c8654422 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-netfilter-IFWLOG.patch @@ -0,0 +1,269 @@ +--- + include/linux/netfilter_ipv4/ipt_IFWLOG.h | 26 +++ + net/ipv4/netfilter/Kconfig | 11 + + net/ipv4/netfilter/Makefile | 1 + net/ipv4/netfilter/ipt_IFWLOG.c | 200 ++++++++++++++++++++++++++++++ + 4 files changed, 238 insertions(+) + +--- /dev/null ++++ b/net/ipv4/netfilter/ipt_IFWLOG.c +@@ -0,0 +1,200 @@ ++/* Interactive Firewall for Mandriva ++ * Samir Bellabes ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Samir Bellabes "); ++MODULE_DESCRIPTION("Interactive firewall logging and module"); ++ ++#if 0 ++#define DEBUGP PRINTR ++#else ++#define DEBUGP(format, args...) ++#endif ++ ++#define PRINTR(format, args...) do { if(net_ratelimit()) printk(format, ##args); } while(0) ++ ++static struct sock *nl; ++ ++#define GROUP 10 ++ ++/* send struct to userspace */ ++static void send_packet(struct nl_msg msg) ++{ ++ struct sk_buff *skb = NULL; ++ struct nlmsghdr *nlh; ++ ++ skb = alloc_skb(NLMSG_SPACE(sizeof(struct nl_msg)), GFP_ATOMIC); ++ if (!skb) { ++ PRINTR(KERN_WARNING "IFWLOG: OOM can't allocate skb\n"); ++ return ; ++ } ++ ++ nlh = NLMSG_PUT(skb, 0, 0, 0, sizeof(struct nl_msg) - sizeof(*nlh)); ++ ++ memcpy(NLMSG_DATA(nlh), (const void*)&msg, sizeof(struct nl_msg)); ++ ++ NETLINK_CB(skb).pid = 0; /* from kernel */ ++ NETLINK_CB(skb).dst_pid = 0; /* multicast */ ++ NETLINK_CB(skb).dst_group = 10; ++ ++ if (nl) { ++ DEBUGP(KERN_WARNING ++ "IFWLOG: nlmsg_len=%ld\nnlmsg_type=%d nlmsg_flags=%d\nnlmsg_seq=%ld nlmsg_pid = %ld\n", ++ (long)nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_flags, ++ (long)nlh->nlmsg_seq, (long)nlh->nlmsg_pid); ++ DEBUGP(KERN_WARNING "prefix : %s\n", msg.prefix); ++ ++ netlink_broadcast(nl, skb, 0, 10, GFP_ATOMIC); ++ return ; ++ } ++ ++ nlmsg_failure: ++ if (skb) ++ kfree_skb(skb); ++ PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n"); ++ return ; ++} ++ ++/* fill struct for userspace */ ++static void ipt_IFWLOG_packet(const struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ const struct ipt_IFWLOG_info *info) ++{ ++ struct iphdr iph; ++ struct tcphdr tcph; ++ struct udphdr udph; ++ struct nl_msg msg; ++ struct iphdr _iph, *ih; ++ struct timeval tv; ++ ++ memset(&msg, 0, sizeof(struct nl_msg)); ++ ++ ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); ++ if (ih == NULL) { ++ PRINTR(KERN_WARNING "IFWLOG: skb truncated"); ++ return; ++ } ++ ++ /* save interface name */ ++ if (in) ++ strcpy(msg.indev_name, in->name); ++ if (out) ++ strcpy(msg.outdev_name, out->name); ++ ++ /* save log-prefix */ ++ strcpy(msg.prefix, info->prefix); ++ ++ /* save ip header */ ++ skb_copy_bits(skb, 0, &iph, sizeof(iph)); ++ memcpy(&msg.ip, &iph, sizeof(struct iphdr)); ++ ++ /* save transport header */ ++ switch (iph.protocol){ ++ case IPPROTO_TCP: ++ skb_copy_bits(skb, iph.ihl*4 , &tcph, sizeof(tcph)); ++ memcpy(&msg.h.th, &tcph, sizeof(struct tcphdr)); ++ break; ++ case IPPROTO_UDP: ++ skb_copy_bits(skb, iph.ihl*4 , &udph, sizeof(udph)); ++ memcpy(&msg.h.uh, &udph, sizeof(struct udphdr)); ++ break; ++ default: ++ break; ++ } ++ ++ /* save timetamp */ ++ do_gettimeofday((struct timeval *)&tv); ++ msg.timestamp_sec = tv.tv_sec; ++ ++ send_packet(msg); ++} ++ ++static unsigned int ipt_IFWLOG_target(struct sk_buff **pskb, ++ const struct net_device *in, ++ const struct net_device *out, ++ unsigned int hooknum, ++ const void *targinfo, ++ void *userinfo) ++{ ++ const struct ipt_IFWLOG_info *info = targinfo; ++ ++ ipt_IFWLOG_packet(*pskb, in, out, info); ++ ++ return IPT_CONTINUE; ++} ++ ++static int ipt_IFWLOG_checkentry(const char *tablename, ++ const struct ipt_entry *e, ++ void *targinfo, ++ unsigned int targinfosize, ++ unsigned int hook_mask) ++{ ++ const struct ipt_IFWLOG_info *info = targinfo; ++ ++ if (info->prefix[sizeof(info->prefix)-1] != '\0') { ++ DEBUGP("IFWLOG: prefix term %i\n", ++ info->prefix[sizeof(info->prefix)-1]); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct ipt_target ipt_IFWLOG = { ++ .name = "IFWLOG", ++ .target = ipt_IFWLOG_target, ++ .targetsize = sizeof(struct ipt_IFWLOG_info), ++ .checkentry = ipt_IFWLOG_checkentry, ++ .me = THIS_MODULE, ++}; ++ ++static int __init init(void) ++{ ++ nl = (struct sock*) netlink_kernel_create(NETLINK_IFWLOG, GROUP, NULL, THIS_MODULE); ++ if (!nl) { ++ PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n"); ++ return -EINVAL; ++ } ++ ++ if (ipt_register_target(&ipt_IFWLOG)) { ++ if (nl && nl->sk_socket) ++ sock_release(nl->sk_socket); ++ return -EINVAL; ++ } ++ ++ PRINTR(KERN_INFO "IFWLOG: register target\n"); ++ return 0; ++} ++ ++static void __exit fini(void) ++{ ++ if (nl && nl->sk_socket) ++ sock_release(nl->sk_socket); ++ PRINTR(KERN_INFO "IFWLOG: unregister target\n"); ++ ipt_unregister_target(&ipt_IFWLOG); ++} ++ ++module_init(init); ++module_exit(fini); +--- a/net/ipv4/netfilter/Kconfig ++++ b/net/ipv4/netfilter/Kconfig +@@ -331,6 +331,17 @@ config IP_NF_TARGET_TTL + (e.g. when running oldconfig). It selects + CONFIG_NETFILTER_XT_TARGET_HL. + ++config IP_NF_TARGET_IFWLOG ++ tristate 'IFWLOG target support' ++ depends on IP_NF_IPTABLES ++ help ++ This option adds a `IFWLOG' target, which is used by ++ Interactive Firewall for sending informations to a userspace ++ daemon ++ ++ If you want to compile it as a module, say M here and read ++ Documentation/modules.txt. If unsure, say `N'. ++ + # raw + specific targets + config IP_NF_RAW + tristate 'raw table support (required for NOTRACK/TRACE)' +--- /dev/null ++++ b/include/linux/netfilter_ipv4/ipt_IFWLOG.h +@@ -0,0 +1,26 @@ ++#ifndef _IPT_IFWLOG_H ++#define _IPT_IFWLOG_H ++ ++#ifndef NETLINK_IFWLOG ++#define NETLINK_IFWLOG 19 ++#endif ++ ++#define PREFSIZ 32 ++ ++struct nl_msg { /* Netlink message */ ++ long timestamp_sec; /* time packet */ ++ char indev_name[IFNAMSIZ]; /* name of the ingoing interface */ ++ char outdev_name[IFNAMSIZ]; /* name of the outgoing interface */ ++ unsigned char prefix[PREFSIZ]; /* informations on the logging reason */ ++ struct iphdr ip; ++ union { ++ struct tcphdr th; ++ struct udphdr uh; ++ } h; ++}; ++ ++struct ipt_IFWLOG_info { ++ char prefix[PREFSIZ]; ++}; ++ ++#endif /* _IPT_IFWLOG_H */ +--- linux/net/ipv4/netfilter/Makefile.net-netfilter-IFWLOG.orig 2013-10-13 11:29:08.799136037 +0300 ++++ linux/net/ipv4/netfilter/Makefile 2013-10-13 11:30:28.085842333 +0300 +@@ -44,6 +44,7 @@ obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ip + # targets + obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o + obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o ++obj-$(CONFIG_IP_NF_TARGET_IFWLOG) += ipt_IFWLOG.o + obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o + obj-$(CONFIG_IP_NF_TARGET_SYNPROXY) += ipt_SYNPROXY.o diff --git a/kernel/kernel/files/patches/mageia/net-netfilter-psd-2.6.35-buildfix.patch b/kernel/kernel/files/patches/mageia/net-netfilter-psd-2.6.35-buildfix.patch new file mode 100644 index 00000000..218031c4 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-netfilter-psd-2.6.35-buildfix.patch @@ -0,0 +1,11 @@ +--- linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_psd.c.orig 2010-07-30 21:17:30.000000000 +0300 ++++ linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_psd.c 2010-07-31 13:29:00.623601957 +0300 +@@ -98,7 +98,7 @@ static inline int hashfunc(struct in_add + + static bool + ipt_psd_match(const struct sk_buff *pskb, +- const struct xt_match_param *match_param) ++ struct xt_action_param *match_param) + { + struct iphdr *ip_hdr; + struct tcphdr *tcp_hdr; diff --git a/kernel/kernel/files/patches/mageia/net-netfilter-psd-mdv.patch b/kernel/kernel/files/patches/mageia/net-netfilter-psd-mdv.patch new file mode 100644 index 00000000..3b5c94d5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-netfilter-psd-mdv.patch @@ -0,0 +1,233 @@ +ipt_psd: Mandriva changes + +This patch holds all the Mandriva changes done in ipt_psd +netfilter module. + +Most of the time they're just upgrades to match with new +API in the kernel. + +This work is mostly done by Thomas Backlund, Herton R. +Krzesinski and Luiz Fernando N. Capitulino. + +Signed-off-by: Luiz Fernando N. Capitulino +Signed-off-by: Herton Ronaldo Krzesinski + +--- + include/linux/netfilter_ipv4/Kbuild | 1 + net/ipv4/netfilter/Kconfig | 8 ++ + net/ipv4/netfilter/ipt_psd.c | 113 ++++++++++++++---------------------- + 3 files changed, 55 insertions(+), 67 deletions(-) + +diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig linux-2.6.28/net/ipv4/netfilter/ipt_psd.c +--- linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig 2008-12-12 11:03:05.000000000 -0500 ++++ linux-2.6.28/net/ipv4/netfilter/ipt_psd.c 2008-12-12 11:04:03.000000000 -0500 +@@ -1,21 +1,24 @@ + /* +- This is a module which is used for PSD (portscan detection) +- Derived from scanlogd v2.1 written by Solar Designer +- and LOG target module. +- +- Copyright (C) 2000,2001 astaro AG +- +- This file is distributed under the terms of the GNU General Public +- License (GPL). Copies of the GPL can be obtained from: +- ftp://prep.ai.mit.edu/pub/gnu/GPL +- +- 2000-05-04 Markus Hennig : initial +- 2000-08-18 Dennis Koslowski : first release +- 2000-12-01 Dennis Koslowski : UDP scans detection added +- 2001-01-02 Dennis Koslowski : output modified +- 2001-02-04 Jan Rekorajski : converted from target to match +- 2004-05-05 Martijn Lievaart : ported to 2.6 +-*/ ++ * This is a module which is used for PSD (portscan detection) ++ * Derived from scanlogd v2.1 written by Solar Designer ++ * and LOG target module. ++ * ++ * Copyright (C) 2000,2001 astaro AG ++ * ++ * This file is distributed under the terms of the GNU General Public ++ * License (GPL). Copies of the GPL can be obtained from: ++ * ftp://prep.ai.mit.edu/pub/gnu/GPL ++ * ++ * 2000-05-04 Markus Hennig : initial ++ * 2000-08-18 Dennis Koslowski : first release ++ * 2000-12-01 Dennis Koslowski : UDP scans detection added ++ * 2001-01-02 Dennis Koslowski : output modified ++ * 2001-02-04 Jan Rekorajski : converted from target to match ++ * 2004-05-05 Martijn Lievaart : ported to 2.6 ++ * 2007-10-10 Thomas Backlund : 2.6.22 update ++ * 2007-11-14 Luiz Capitulino : 2.6.22 API usage fixes ++ * 2007-11-26 Herton Ronaldo Krzesinski : switch xt_match->match to bool ++ */ + + #include + #include +@@ -54,7 +57,7 @@ struct port { + */ + struct host { + struct host *next; /* Next entry with the same hash */ +- clock_t timestamp; /* Last update time */ ++ unsigned long timestamp; /* Last update time */ + struct in_addr src_addr; /* Source address */ + struct in_addr dest_addr; /* Destination address */ + unsigned short src_port; /* Source port */ +@@ -93,33 +96,29 @@ static inline int hashfunc(struct in_add + return hash & (HASH_SIZE - 1); + } + +-static int ++static bool + ipt_psd_match(const struct sk_buff *pskb, +- const struct net_device *in, +- const struct net_device *out, +- const void *matchinfo, +- int offset, +- int *hotdrop) ++ const struct xt_match_param *match_param) + { + struct iphdr *ip_hdr; + struct tcphdr *tcp_hdr; + struct in_addr addr; + u_int16_t src_port,dest_port; + u_int8_t tcp_flags, proto; +- clock_t now; ++ unsigned long now; + struct host *curr, *last, **head; + int hash, index, count; + + /* Parameters from userspace */ +- const struct ipt_psd_info *psdinfo = matchinfo; ++ const struct ipt_psd_info *psdinfo = match_param->matchinfo; + + /* IP header */ +- ip_hdr = pskb->nh.iph; ++ ip_hdr = ipip_hdr(pskb); + + /* Sanity check */ + if (ntohs(ip_hdr->frag_off) & IP_OFFSET) { + DEBUGP("PSD: sanity check failed\n"); +- return 0; ++ return false; + } + + /* TCP or UDP ? */ +@@ -127,7 +126,7 @@ ipt_psd_match(const struct sk_buff *pskb + + if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) { + DEBUGP("PSD: protocol not supported\n"); +- return 0; ++ return false; + } + + /* Get the source address, source & destination ports, and TCP flags */ +@@ -151,7 +150,7 @@ ipt_psd_match(const struct sk_buff *pskb + * them spoof us. [DHCP needs this feature - HW] */ + if (!addr.s_addr) { + DEBUGP("PSD: spoofed source address (0.0.0.0)\n"); +- return 0; ++ return false; + } + + /* Use jiffies here not to depend on someone setting the time while we're +@@ -298,46 +297,26 @@ ipt_psd_match(const struct sk_buff *pskb + + out_no_match: + spin_unlock(&state.lock); +- return 0; ++ return false; + + out_match: + spin_unlock(&state.lock); +- return 1; ++ DEBUGP("PSD: Dropping packets from "NIPQUAD_FMT" \n", ++ NIPQUAD(curr->src_addr.s_addr)); ++ return true; + } + +-static int ipt_psd_checkentry(const char *tablename, +- const struct ipt_ip *e, +- void *matchinfo, +- unsigned int matchsize, +- unsigned int hook_mask) +-{ +-/* const struct ipt_psd_info *psdinfo = targinfo;*/ +- +- /* we accept TCP only */ +-/* if (e->ip.proto != IPPROTO_TCP) { */ +-/* DEBUGP("PSD: specified protocol may be TCP only\n"); */ +-/* return 0; */ +-/* } */ +- +- if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) { +- DEBUGP("PSD: matchsize %u != %u\n", +- matchsize, +- IPT_ALIGN(sizeof(struct ipt_psd_info))); +- return 0; +- } +- +- return 1; +-} +- +-static struct ipt_match ipt_psd_reg = { +- .name = "psd", +- .match = ipt_psd_match, +- .checkentry = ipt_psd_checkentry, +- .me = THIS_MODULE }; ++static struct xt_match ipt_psd_reg = { ++ .name = "psd", ++ .family = AF_INET, ++ .match = ipt_psd_match, ++ .matchsize = sizeof(struct ipt_psd_info), ++ .me = THIS_MODULE ++}; + +-static int __init init(void) ++static int __init ipt_psd_init(void) + { +- if (ipt_register_match(&ipt_psd_reg)) ++ if (xt_register_match(&ipt_psd_reg)) + return -EINVAL; + + memset(&state, 0, sizeof(state)); +@@ -348,11 +327,11 @@ static int __init init(void) + return 0; + } + +-static void __exit fini(void) ++static void __exit ipt_psd_fini(void) + { +- ipt_unregister_match(&ipt_psd_reg); ++ xt_unregister_match(&ipt_psd_reg); + printk("netfilter PSD unloaded - (c) astaro AG\n"); + } + +-module_init(init); +-module_exit(fini); ++module_init(ipt_psd_init); ++module_exit(ipt_psd_fini); +--- a/net/ipv4/netfilter/Kconfig ++++ b/net/ipv4/netfilter/Kconfig +@@ -69,6 +69,14 @@ config IP_NF_MATCH_ECN + (e.g. when running oldconfig). It selects + CONFIG_NETFILTER_XT_MATCH_ECN. + ++config IP_NF_MATCH_PSD ++ tristate 'Port scanner detection support' ++ depends on NETFILTER_ADVANCED ++ help ++ Module used for PSD (portscan detection). ++ ++ To compile it as a module, choose M here. If unsure, say N. ++ + config IP_NF_MATCH_RPFILTER + tristate '"rpfilter" reverse path filter match support' + depends on NETFILTER_ADVANCED && (IP_NF_MANGLE || IP_NF_RAW) +--- linux/include/uapi/linux/netfilter_ipv4/Kbuild.orig ++++ linux/include/uapi/linux/netfilter_ipv4/Kbuild +@@ -8,4 +8,5 @@ header-y += ipt_REJECT.h + header-y += ipt_TTL.h + header-y += ipt_ah.h + header-y += ipt_ecn.h ++header-y += ipt_psd.h + header-y += ipt_ttl.h diff --git a/kernel/kernel/files/patches/mageia/net-netfilter-psd.patch b/kernel/kernel/files/patches/mageia/net-netfilter-psd.patch new file mode 100644 index 00000000..8ec326ff --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-netfilter-psd.patch @@ -0,0 +1,420 @@ +--- + include/linux/netfilter_ipv4/ipt_psd.h | 40 +++ + net/ipv4/netfilter/Makefile | 1 + net/ipv4/netfilter/ipt_psd.c | 358 +++++++++++++++++++++++++++++++++ + 3 files changed, 399 insertions(+) + +--- /dev/null ++++ b/net/ipv4/netfilter/ipt_psd.c +@@ -0,0 +1,358 @@ ++/* ++ This is a module which is used for PSD (portscan detection) ++ Derived from scanlogd v2.1 written by Solar Designer ++ and LOG target module. ++ ++ Copyright (C) 2000,2001 astaro AG ++ ++ This file is distributed under the terms of the GNU General Public ++ License (GPL). Copies of the GPL can be obtained from: ++ ftp://prep.ai.mit.edu/pub/gnu/GPL ++ ++ 2000-05-04 Markus Hennig : initial ++ 2000-08-18 Dennis Koslowski : first release ++ 2000-12-01 Dennis Koslowski : UDP scans detection added ++ 2001-01-02 Dennis Koslowski : output modified ++ 2001-02-04 Jan Rekorajski : converted from target to match ++ 2004-05-05 Martijn Lievaart : ported to 2.6 ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if 0 ++#define DEBUGP printk ++#else ++#define DEBUGP(format, args...) ++#endif ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Dennis Koslowski "); ++ ++#define HF_DADDR_CHANGING 0x01 ++#define HF_SPORT_CHANGING 0x02 ++#define HF_TOS_CHANGING 0x04 ++#define HF_TTL_CHANGING 0x08 ++ ++/* ++ * Information we keep per each target port ++ */ ++struct port { ++ u_int16_t number; /* port number */ ++ u_int8_t proto; /* protocol number */ ++ u_int8_t and_flags; /* tcp ANDed flags */ ++ u_int8_t or_flags; /* tcp ORed flags */ ++}; ++ ++/* ++ * Information we keep per each source address. ++ */ ++struct host { ++ struct host *next; /* Next entry with the same hash */ ++ clock_t timestamp; /* Last update time */ ++ struct in_addr src_addr; /* Source address */ ++ struct in_addr dest_addr; /* Destination address */ ++ unsigned short src_port; /* Source port */ ++ int count; /* Number of ports in the list */ ++ int weight; /* Total weight of ports in the list */ ++ struct port ports[SCAN_MAX_COUNT - 1]; /* List of ports */ ++ unsigned char tos; /* TOS */ ++ unsigned char ttl; /* TTL */ ++ unsigned char flags; /* HF_ flags bitmask */ ++}; ++ ++/* ++ * State information. ++ */ ++static struct { ++ spinlock_t lock; ++ struct host list[LIST_SIZE]; /* List of source addresses */ ++ struct host *hash[HASH_SIZE]; /* Hash: pointers into the list */ ++ int index; /* Oldest entry to be replaced */ ++} state; ++ ++/* ++ * Convert an IP address into a hash table index. ++ */ ++static inline int hashfunc(struct in_addr addr) ++{ ++ unsigned int value; ++ int hash; ++ ++ value = addr.s_addr; ++ hash = 0; ++ do { ++ hash ^= value; ++ } while ((value >>= HASH_LOG)); ++ ++ return hash & (HASH_SIZE - 1); ++} ++ ++static int ++ipt_psd_match(const struct sk_buff *pskb, ++ const struct net_device *in, ++ const struct net_device *out, ++ const void *matchinfo, ++ int offset, ++ int *hotdrop) ++{ ++ struct iphdr *ip_hdr; ++ struct tcphdr *tcp_hdr; ++ struct in_addr addr; ++ u_int16_t src_port,dest_port; ++ u_int8_t tcp_flags, proto; ++ clock_t now; ++ struct host *curr, *last, **head; ++ int hash, index, count; ++ ++ /* Parameters from userspace */ ++ const struct ipt_psd_info *psdinfo = matchinfo; ++ ++ /* IP header */ ++ ip_hdr = pskb->nh.iph; ++ ++ /* Sanity check */ ++ if (ntohs(ip_hdr->frag_off) & IP_OFFSET) { ++ DEBUGP("PSD: sanity check failed\n"); ++ return 0; ++ } ++ ++ /* TCP or UDP ? */ ++ proto = ip_hdr->protocol; ++ ++ if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) { ++ DEBUGP("PSD: protocol not supported\n"); ++ return 0; ++ } ++ ++ /* Get the source address, source & destination ports, and TCP flags */ ++ ++ addr.s_addr = ip_hdr->saddr; ++ ++ tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl); ++ ++ /* Yep, it´s dirty */ ++ src_port = tcp_hdr->source; ++ dest_port = tcp_hdr->dest; ++ ++ if (proto == IPPROTO_TCP) { ++ tcp_flags = *((u_int8_t*)tcp_hdr + 13); ++ } ++ else { ++ tcp_flags = 0x00; ++ } ++ ++ /* We're using IP address 0.0.0.0 for a special purpose here, so don't let ++ * them spoof us. [DHCP needs this feature - HW] */ ++ if (!addr.s_addr) { ++ DEBUGP("PSD: spoofed source address (0.0.0.0)\n"); ++ return 0; ++ } ++ ++ /* Use jiffies here not to depend on someone setting the time while we're ++ * running; we need to be careful with possible return value overflows. */ ++ now = jiffies; ++ ++ spin_lock(&state.lock); ++ ++ /* Do we know this source address already? */ ++ count = 0; ++ last = NULL; ++ if ((curr = *(head = &state.hash[hash = hashfunc(addr)]))) ++ do { ++ if (curr->src_addr.s_addr == addr.s_addr) break; ++ count++; ++ if (curr->next) last = curr; ++ } while ((curr = curr->next)); ++ ++ if (curr) { ++ ++ /* We know this address, and the entry isn't too old. Update it. */ ++ if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 && ++ time_after_eq(now, curr->timestamp)) { ++ ++ /* Just update the appropriate list entry if we've seen this port already */ ++ for (index = 0; index < curr->count; index++) { ++ if (curr->ports[index].number == dest_port) { ++ curr->ports[index].proto = proto; ++ curr->ports[index].and_flags &= tcp_flags; ++ curr->ports[index].or_flags |= tcp_flags; ++ goto out_no_match; ++ } ++ } ++ ++ /* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */ ++ if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst)) ++ goto out_no_match; ++ ++ /* Packet to a new port, and not TCP/ACK: update the timestamp */ ++ curr->timestamp = now; ++ ++ /* Logged this scan already? Then drop the packet. */ ++ if (curr->weight >= psdinfo->weight_threshold) ++ goto out_match; ++ ++ /* Specify if destination address, source port, TOS or TTL are not fixed */ ++ if (curr->dest_addr.s_addr != ip_hdr->daddr) ++ curr->flags |= HF_DADDR_CHANGING; ++ if (curr->src_port != src_port) ++ curr->flags |= HF_SPORT_CHANGING; ++ if (curr->tos != ip_hdr->tos) ++ curr->flags |= HF_TOS_CHANGING; ++ if (curr->ttl != ip_hdr->ttl) ++ curr->flags |= HF_TTL_CHANGING; ++ ++ /* Update the total weight */ ++ curr->weight += (ntohs(dest_port) < 1024) ? ++ psdinfo->lo_ports_weight : psdinfo->hi_ports_weight; ++ ++ /* Got enough destination ports to decide that this is a scan? */ ++ /* Then log it and drop the packet. */ ++ if (curr->weight >= psdinfo->weight_threshold) ++ goto out_match; ++ ++ /* Remember the new port */ ++ if (curr->count < SCAN_MAX_COUNT) { ++ curr->ports[curr->count].number = dest_port; ++ curr->ports[curr->count].proto = proto; ++ curr->ports[curr->count].and_flags = tcp_flags; ++ curr->ports[curr->count].or_flags = tcp_flags; ++ curr->count++; ++ } ++ ++ goto out_no_match; ++ } ++ ++ /* We know this address, but the entry is outdated. Mark it unused, and ++ * remove from the hash table. We'll allocate a new entry instead since ++ * this one might get re-used too soon. */ ++ curr->src_addr.s_addr = 0; ++ if (last) ++ last->next = last->next->next; ++ else if (*head) ++ *head = (*head)->next; ++ last = NULL; ++ } ++ ++ /* We don't need an ACK from a new source address */ ++ if (proto == IPPROTO_TCP && tcp_hdr->ack) ++ goto out_no_match; ++ ++ /* Got too many source addresses with the same hash value? Then remove the ++ * oldest one from the hash table, so that they can't take too much of our ++ * CPU time even with carefully chosen spoofed IP addresses. */ ++ if (count >= HASH_MAX && last) last->next = NULL; ++ ++ /* We're going to re-use the oldest list entry, so remove it from the hash ++ * table first (if it is really already in use, and isn't removed from the ++ * hash table already because of the HASH_MAX check above). */ ++ ++ /* First, find it */ ++ if (state.list[state.index].src_addr.s_addr) ++ head = &state.hash[hashfunc(state.list[state.index].src_addr)]; ++ else ++ head = &last; ++ last = NULL; ++ if ((curr = *head)) ++ do { ++ if (curr == &state.list[state.index]) break; ++ last = curr; ++ } while ((curr = curr->next)); ++ ++ /* Then, remove it */ ++ if (curr) { ++ if (last) ++ last->next = last->next->next; ++ else if (*head) ++ *head = (*head)->next; ++ } ++ ++ /* Get our list entry */ ++ curr = &state.list[state.index++]; ++ if (state.index >= LIST_SIZE) state.index = 0; ++ ++ /* Link it into the hash table */ ++ head = &state.hash[hash]; ++ curr->next = *head; ++ *head = curr; ++ ++ /* And fill in the fields */ ++ curr->timestamp = now; ++ curr->src_addr = addr; ++ curr->dest_addr.s_addr = ip_hdr->daddr; ++ curr->src_port = src_port; ++ curr->count = 1; ++ curr->weight = (ntohs(dest_port) < 1024) ? ++ psdinfo->lo_ports_weight : psdinfo->hi_ports_weight; ++ curr->ports[0].number = dest_port; ++ curr->ports[0].proto = proto; ++ curr->ports[0].and_flags = tcp_flags; ++ curr->ports[0].or_flags = tcp_flags; ++ curr->tos = ip_hdr->tos; ++ curr->ttl = ip_hdr->ttl; ++ ++out_no_match: ++ spin_unlock(&state.lock); ++ return 0; ++ ++out_match: ++ spin_unlock(&state.lock); ++ return 1; ++} ++ ++static int ipt_psd_checkentry(const char *tablename, ++ const struct ipt_ip *e, ++ void *matchinfo, ++ unsigned int matchsize, ++ unsigned int hook_mask) ++{ ++/* const struct ipt_psd_info *psdinfo = targinfo;*/ ++ ++ /* we accept TCP only */ ++/* if (e->ip.proto != IPPROTO_TCP) { */ ++/* DEBUGP("PSD: specified protocol may be TCP only\n"); */ ++/* return 0; */ ++/* } */ ++ ++ if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) { ++ DEBUGP("PSD: matchsize %u != %u\n", ++ matchsize, ++ IPT_ALIGN(sizeof(struct ipt_psd_info))); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct ipt_match ipt_psd_reg = { ++ .name = "psd", ++ .match = ipt_psd_match, ++ .checkentry = ipt_psd_checkentry, ++ .me = THIS_MODULE }; ++ ++static int __init init(void) ++{ ++ if (ipt_register_match(&ipt_psd_reg)) ++ return -EINVAL; ++ ++ memset(&state, 0, sizeof(state)); ++ ++ spin_lock_init(&(state.lock)); ++ ++ printk("netfilter PSD loaded - (c) astaro AG\n"); ++ return 0; ++} ++ ++static void __exit fini(void) ++{ ++ ipt_unregister_match(&ipt_psd_reg); ++ printk("netfilter PSD unloaded - (c) astaro AG\n"); ++} ++ ++module_init(init); ++module_exit(fini); +--- /dev/null ++++ b/include/linux/netfilter_ipv4/ipt_psd.h +@@ -0,0 +1,40 @@ ++#ifndef _IPT_PSD_H ++#define _IPT_PSD_H ++ ++#include ++#include ++ ++/* ++ * High port numbers have a lower weight to reduce the frequency of false ++ * positives, such as from passive mode FTP transfers. ++ */ ++#define PORT_WEIGHT_PRIV 3 ++#define PORT_WEIGHT_HIGH 1 ++ ++/* ++ * Port scan detection thresholds: at least COUNT ports need to be scanned ++ * from the same source, with no longer than DELAY ticks between ports. ++ */ ++#define SCAN_MIN_COUNT 7 ++#define SCAN_MAX_COUNT (SCAN_MIN_COUNT * PORT_WEIGHT_PRIV) ++#define SCAN_WEIGHT_THRESHOLD SCAN_MAX_COUNT ++#define SCAN_DELAY_THRESHOLD (300) /* old usage of HZ here was erroneously and broke under uml */ ++ ++/* ++ * Keep track of up to LIST_SIZE source addresses, using a hash table of ++ * HASH_SIZE entries for faster lookups, but limiting hash collisions to ++ * HASH_MAX source addresses per the same hash value. ++ */ ++#define LIST_SIZE 0x100 ++#define HASH_LOG 9 ++#define HASH_SIZE (1 << HASH_LOG) ++#define HASH_MAX 0x10 ++ ++struct ipt_psd_info { ++ unsigned int weight_threshold; ++ unsigned int delay_threshold; ++ unsigned short lo_ports_weight; ++ unsigned short hi_ports_weight; ++}; ++ ++#endif /*_IPT_PSD_H*/ +--- a/net/ipv4/netfilter/Makefile ++++ b/net/ipv4/netfilter/Makefile +@@ -49,6 +49,7 @@ + + # matches + obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o ++obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o + obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ipt_rpfilter.o + + # targets diff --git a/kernel/kernel/files/patches/mageia/net-sis190-fix-list-usage.patch b/kernel/kernel/files/patches/mageia/net-sis190-fix-list-usage.patch new file mode 100644 index 00000000..eda13d1d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-sis190-fix-list-usage.patch @@ -0,0 +1,30 @@ +--- + drivers/net/ethernet/sis/sis190.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- linux/drivers/net/ethernet/sis/sis190.c.net-sis190-fix-list-usage.orig ++++ linux/drivers/net/ethernet/sis/sis190.c +@@ -1252,6 +1252,7 @@ static u16 sis190_default_phy(struct net + struct sis190_private *tp = netdev_priv(dev); + struct mii_if_info *mii_if = &tp->mii_if; + void __iomem *ioaddr = tp->mmio_addr; ++ struct list_head *l; + u16 status; + + phy_home = phy_default = phy_lan = NULL; +@@ -1280,9 +1281,12 @@ static u16 sis190_default_phy(struct net + phy_default = phy_home; + else if (phy_lan) + phy_default = phy_lan; +- else +- phy_default = list_first_entry(&tp->first_phy, +- struct sis190_phy, list); ++ else { ++ l = &tp->first_phy; ++ l = l->next; ++ phy_default = list_first_entry(l, struct sis190_phy, list); ++ ++ } + } + + if (mii_if->phy_id != phy_default->phy_id) { diff --git a/kernel/kernel/files/patches/mageia/net-wireless-ath9k-Update-PCI-IDs-for-AR9565.patch b/kernel/kernel/files/patches/mageia/net-wireless-ath9k-Update-PCI-IDs-for-AR9565.patch new file mode 100644 index 00000000..601890ef --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-wireless-ath9k-Update-PCI-IDs-for-AR9565.patch @@ -0,0 +1,177 @@ +From: Sujith Manoharan +To: linux-wireless@vger.kernel.org +Cc: ath9k-devel@qca.qualcomm.com +Subject: [PATCH] ath9k: Update PCI IDs for AR9565 +Date: Mon, 5 Jan 2015 11:14:25 +0530 + +From: Sujith Manoharan + +This patch adds several new PCI IDs for AR9565. + +Signed-off-by: Sujith Manoharan +--- + drivers/net/wireless/ath/ath9k/pci.c | 85 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 85 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c +index f009b5b..cc5c681 100644 +--- a/drivers/net/wireless/ath/ath9k/pci.c ++++ b/drivers/net/wireless/ath/ath9k/pci.c +@@ -427,6 +427,11 @@ static const struct pci_device_id ath_pci_id_table[] = { + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, + 0x11AD, /* LITEON */ ++ 0x1842), ++ .driver_data = ATH9K_PCI_AR9565_1ANT }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ 0x11AD, /* LITEON */ + 0x6671), + .driver_data = ATH9K_PCI_AR9565_1ANT }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, +@@ -446,9 +451,19 @@ static const struct pci_device_id ath_pci_id_table[] = { + .driver_data = ATH9K_PCI_AR9565_1ANT }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, ++ 0x1B9A, /* XAVI */ ++ 0x28A3), ++ .driver_data = ATH9K_PCI_AR9565_1ANT }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, + PCI_VENDOR_ID_AZWAVE, + 0x218A), + .driver_data = ATH9K_PCI_AR9565_1ANT }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x2F8A), ++ .driver_data = ATH9K_PCI_AR9565_1ANT }, + + /* WB335 1-ANT / Antenna Diversity */ + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, +@@ -508,6 +523,11 @@ static const struct pci_device_id ath_pci_id_table[] = { + .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x213C), ++ .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, + PCI_VENDOR_ID_HP, + 0x18E3), + .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, +@@ -555,6 +575,16 @@ static const struct pci_device_id ath_pci_id_table[] = { + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, ++ PCI_VENDOR_ID_SAMSUNG, ++ 0x4129), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ PCI_VENDOR_ID_SAMSUNG, ++ 0x412A), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, + PCI_VENDOR_ID_ATHEROS, + 0x3027), + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, +@@ -586,10 +616,25 @@ static const struct pci_device_id ath_pci_id_table[] = { + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, + 0x11AD, /* LITEON */ ++ 0x1832), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ 0x11AD, /* LITEON */ + 0x0692), + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, ++ 0x11AD, /* LITEON */ ++ 0x0803), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ 0x11AD, /* LITEON */ ++ 0x0813), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, + PCI_VENDOR_ID_AZWAVE, + 0x2130), + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, +@@ -605,6 +650,21 @@ static const struct pci_device_id ath_pci_id_table[] = { + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x218B), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x218C), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x2F82), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, + 0x144F, /* ASKEY */ + 0x7202), + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, +@@ -616,10 +676,20 @@ static const struct pci_device_id ath_pci_id_table[] = { + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, + 0x1B9A, /* XAVI */ ++ 0x2813), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ 0x1B9A, /* XAVI */ + 0x28A2), + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, ++ 0x1B9A, /* XAVI */ ++ 0x28A4), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, + 0x185F, /* WNC */ + 0x3027), + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, +@@ -636,10 +706,25 @@ static const struct pci_device_id ath_pci_id_table[] = { + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, + PCI_VENDOR_ID_FOXCONN, ++ 0xE08F), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ PCI_VENDOR_ID_FOXCONN, + 0xE081), + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, + 0x0036, ++ PCI_VENDOR_ID_FOXCONN, ++ 0xE091), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, ++ PCI_VENDOR_ID_FOXCONN, ++ 0xE099), ++ .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0036, + PCI_VENDOR_ID_LENOVO, + 0x3026), + .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, +-- +2.2.1 diff --git a/kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-Add-support-for-bcm43340_1-wireless-chipsets.patch b/kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-Add-support-for-bcm43340_1-wireless-chipsets.patch new file mode 100644 index 00000000..691edd29 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-Add-support-for-bcm43340_1-wireless-chipsets.patch @@ -0,0 +1,116 @@ +From 8b3a38daff6f50027039d6979b9eb026907508eb Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Tue, 23 Dec 2014 19:04:23 +0100 +Subject: brcmfmac: Add support for bcm43340/1 wireless chipsets + +This patch adds support for the bcm43340 and bcm43341 wireless +chipsets. These two chipsets are identical from wireless parts +perspective. As such they use the same firmware image. + +Cc: Samuel Ortiz +Cc: Rob Herring +Signed-off-by: John Stultz +[arend@broadcom.com: squash to single commit, remove 43341 chipid] +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo + +diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +index 9880dae..dffd9e4 100644 +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -1005,6 +1005,8 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { + BRCMF_SDIO_DEVICE(BRCM_SDIO_4329_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_4330_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_4334_DEVICE_ID), ++ BRCMF_SDIO_DEVICE(BRCM_SDIO_43340_DEVICE_ID), ++ BRCMF_SDIO_DEVICE(BRCM_SDIO_43341_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_43362_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_4335_4339_DEVICE_ID), + BRCMF_SDIO_DEVICE(BRCM_SDIO_4354_DEVICE_ID), +diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +index 519b79e..04d2ca0 100644 +--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c +@@ -481,6 +481,7 @@ static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) + ci->pub.ramsize = 0x48000; + break; + case BRCM_CC_4334_CHIP_ID: ++ case BRCM_CC_43340_CHIP_ID: + ci->pub.ramsize = 0x80000; + break; + case BRCM_CC_4335_CHIP_ID: +diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +index 0b0d51a..551da35 100644 +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -608,6 +608,8 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { + #define BCM4330_NVRAM_NAME "brcm/brcmfmac4330-sdio.txt" + #define BCM4334_FIRMWARE_NAME "brcm/brcmfmac4334-sdio.bin" + #define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" ++#define BCM43340_FIRMWARE_NAME "brcm/brcmfmac43340-sdio.bin" ++#define BCM43340_NVRAM_NAME "brcm/brcmfmac43340-sdio.txt" + #define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" + #define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" + #define BCM43362_FIRMWARE_NAME "brcm/brcmfmac43362-sdio.bin" +@@ -629,6 +631,8 @@ MODULE_FIRMWARE(BCM4330_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM4330_NVRAM_NAME); + MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM4334_NVRAM_NAME); ++MODULE_FIRMWARE(BCM43340_FIRMWARE_NAME); ++MODULE_FIRMWARE(BCM43340_NVRAM_NAME); + MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); + MODULE_FIRMWARE(BCM4335_NVRAM_NAME); + MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); +@@ -660,6 +664,7 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = { + { BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, + { BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, + { BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, ++ { BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43340) }, + { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, + { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, + { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, +diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +index 6996fcc..00215ef 100644 +--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +@@ -34,6 +34,7 @@ + #define BRCM_CC_4329_CHIP_ID 0x4329 + #define BRCM_CC_4330_CHIP_ID 0x4330 + #define BRCM_CC_4334_CHIP_ID 0x4334 ++#define BRCM_CC_43340_CHIP_ID 43340 + #define BRCM_CC_43362_CHIP_ID 43362 + #define BRCM_CC_4335_CHIP_ID 0x4335 + #define BRCM_CC_4339_CHIP_ID 0x4339 +@@ -51,6 +52,8 @@ + #define BRCM_SDIO_4329_DEVICE_ID BRCM_CC_4329_CHIP_ID + #define BRCM_SDIO_4330_DEVICE_ID BRCM_CC_4330_CHIP_ID + #define BRCM_SDIO_4334_DEVICE_ID BRCM_CC_4334_CHIP_ID ++#define BRCM_SDIO_43340_DEVICE_ID BRCM_CC_43340_CHIP_ID ++#define BRCM_SDIO_43341_DEVICE_ID 43341 + #define BRCM_SDIO_43362_DEVICE_ID BRCM_CC_43362_CHIP_ID + #define BRCM_SDIO_4335_4339_DEVICE_ID BRCM_CC_4335_CHIP_ID + #define BRCM_SDIO_4354_DEVICE_ID BRCM_CC_4354_CHIP_ID +diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h +index 0f01fe0..9968079 100644 +--- a/include/linux/mmc/sdio_ids.h ++++ b/include/linux/mmc/sdio_ids.h +@@ -24,13 +24,15 @@ + * Vendors and devices. Sort key: vendor first, device next. + */ + #define SDIO_VENDOR_ID_BROADCOM 0x02d0 +-#define SDIO_DEVICE_ID_BROADCOM_43143 43143 ++#define SDIO_DEVICE_ID_BROADCOM_43143 0xa887 + #define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 + #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 + #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 + #define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 ++#define SDIO_DEVICE_ID_BROADCOM_43340 0xa94c ++#define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d + #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 +-#define SDIO_DEVICE_ID_BROADCOM_43362 43362 ++#define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 + #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 + + #define SDIO_VENDOR_ID_INTEL 0x0089 diff --git a/kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch b/kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch new file mode 100644 index 00000000..2707f66f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch @@ -0,0 +1,53 @@ +From c2b3fb54bf2952b0a41d13cb1df592d9aa0ecf9e Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Fri, 1 May 2015 09:59:35 +0200 +Subject: [PATCH] brcmfmac: avoid null pointer access when + brcmf_msgbuf_get_pktid() fails + +The function brcmf_msgbuf_get_pktid() may return a NULL pointer so +the callers should check the return pointer before accessing it. + +Signed-off-by: Arend van Spriel +--- + drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +index 6262612..7a3231d 100644 +--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +@@ -510,11 +510,9 @@ static int brcmf_msgbuf_query_dcmd(struc + msgbuf->rx_pktids, + msgbuf->ioctl_resp_pktid); + if (msgbuf->ioctl_resp_ret_len != 0) { +- if (!skb) { +- brcmf_err("Invalid packet id idx recv'd %d\n", +- msgbuf->ioctl_resp_pktid); ++ if (!skb) + return -EBADF; +- } ++ + memcpy(buf, skb->data, (len < msgbuf->ioctl_resp_ret_len) ? + len : msgbuf->ioctl_resp_ret_len); + } +@@ -865,10 +863,8 @@ brcmf_msgbuf_process_txstatus(struct brc + flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS; + skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, + msgbuf->tx_pktids, idx); +- if (!skb) { +- brcmf_err("Invalid packet id idx recv'd %d\n", idx); ++ if (!skb) + return; +- } + + set_bit(flowid, msgbuf->txstatus_done_map); + +@@ -1145,6 +1141,8 @@ brcmf_msgbuf_process_rx_complete(struct + + skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev, + msgbuf->rx_pktids, idx); ++ if (!skb) ++ return; + + if (data_offset) + skb_pull(skb, data_offset); diff --git a/kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-check-result-of-USB-firmware-request.patch b/kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-check-result-of-USB-firmware-request.patch new file mode 100644 index 00000000..027cd3f7 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/net-wireless-brcmfmac-check-result-of-USB-firmware-request.patch @@ -0,0 +1,42 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +To: Kalle Valo , linux-wireless@vger.kernel.org +Cc: Brett Rudley , Arend van Spriel , + "Franky (Zhenhui) Lin" , + Hante Meuleman , + brcm80211-dev-list@broadcom.com, + =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Subject: [PATCH] brcmfmac: check result of USB firmware request +Date: Thu, 7 May 2015 14:13:03 +0200 + +This prevents silence failures with driver waiting (infinitely) for a +callback. + +Signed-off-by: Rafał Miłecki +--- +I don't really have any opinion if this should go for next or as a fix. +--- + drivers/net/wireless/brcm80211/brcmfmac/usb.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c +index 5df6aa7..daba86d 100644 +--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c +@@ -1270,8 +1270,13 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) + bus->chiprev = bus_pub->chiprev; + + /* request firmware here */ +- brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL, +- brcmf_usb_probe_phase2); ++ ret = brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), ++ NULL, brcmf_usb_probe_phase2); ++ if (ret) { ++ brcmf_err("firmware request failed: %d\n", ret); ++ goto fail; ++ } ++ + return 0; + + fail: +-- +1.8.4.5 diff --git a/kernel/kernel/files/patches/mageia/pci-Add-Wellsburg-X99-to-Intel-PCH-root-port-ACS-qui.patch b/kernel/kernel/files/patches/mageia/pci-Add-Wellsburg-X99-to-Intel-PCH-root-port-ACS-qui.patch new file mode 100644 index 00000000..4620ec3c --- /dev/null +++ b/kernel/kernel/files/patches/mageia/pci-Add-Wellsburg-X99-to-Intel-PCH-root-port-ACS-qui.patch @@ -0,0 +1,33 @@ +From 78e883585db49aa6d86b8817b770d7717699ab4e Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Thu, 22 Jan 2015 11:15:43 -0700 +Subject: [PATCH] PCI: Add Wellsburg (X99) to Intel PCH root port ACS quirk + +Intel has confirmed that the Wellsburg chipset, while not reporting ACS, +does provide the proper isolation through the RCBA/BSPR registers, so the +same quirk works for this set of device IDs. + +Signed-off-by: Alex Williamson +Signed-off-by: Bjorn Helgaas +Acked-by: Don Dugger +--- + drivers/pci/quirks.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 45bd870..e248a11 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3703,6 +3703,9 @@ static const u16 pci_quirk_intel_pch_acs_ids[] = { + 0x9c98, 0x9c99, 0x9c9a, 0x9c9b, + /* Patsburg (X79) PCH */ + 0x1d10, 0x1d12, 0x1d14, 0x1d16, 0x1d18, 0x1d1a, 0x1d1c, 0x1d1e, ++ /* Wellsburg (X99) PCH */ ++ 0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15, 0x8d16, 0x8d17, ++ 0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d1d, 0x8d1e, + }; + + static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev) +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/pci-acs-quirks-for-Intel-9-series-PCH-root-ports.patch b/kernel/kernel/files/patches/mageia/pci-acs-quirks-for-Intel-9-series-PCH-root-ports.patch new file mode 100644 index 00000000..937447d3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/pci-acs-quirks-for-Intel-9-series-PCH-root-ports.patch @@ -0,0 +1,28 @@ +From: Alex Williamson +Subject: [PATCH] PCI: ACS quirks for Intel 9-series PCH root ports +Date: Fri, 01 May 2015 13:20:13 -0600 + +Intel confirms that 9-series chipset root ports provide ACS-equivalent +isolation when configured via the existing Intel PCH ACS quirk setup. + +Signed-off-by: Alex Williamson +Acked-by: Don Dugger + +--- + drivers/pci/quirks.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index c6dc1df..f126bd6 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -3740,6 +3740,8 @@ static const u16 pci_quirk_intel_pch_acs_ids[] = { + /* Wellsburg (X99) PCH */ + 0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15, 0x8d16, 0x8d17, + 0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d1d, 0x8d1e, ++ /* Lynx Point (9 series) PCH */ ++ 0x8c90, 0x8c92, 0x8c94, 0x8c96, 0x8c98, 0x8c9a, 0x8c9c, 0x8c9e, + }; + + static bool pci_quirk_intel_pch_acs_match(struct pci_dev *dev) + diff --git a/kernel/kernel/files/patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch b/kernel/kernel/files/patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch new file mode 100644 index 00000000..47e1a2f5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch @@ -0,0 +1,60 @@ +PCI: Add ALI M5229 comaptibility mode quirk + +The libata driver will not work with an M5229 set into native IDE +mode (the old drivers/pci one does) if the M5229 does not provide +it's own IRQ. + +The M5229 implementation embedded into the ALI M1543 uses the +M1543's ISA PIC to provide the interrupts and thus does not have +an valid PCI IRQ set. This quirk detects the abscence of IRQ and +sets the M5229 back into compatibility mode to use IRQs 14 and 15 +so that libata works correctly. + +Note, I belive that the check for an valid interrupt line is +correct, I only have an M5229 in an ALI M1543 to check this +on. It would be useful to confirm that a M5229 with an valid IRQ +does not trigger this quirk. + +Signed-off-by: Ben Dooks + +--- + drivers/pci/quirks.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -964,6 +964,34 @@ static void __devinit quirk_svwks_csb5id + } + DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide); + ++/* Some systems set the ALI M5229 in the ALI M1543 bridge to native mode, ++ * which cannot be supported by the pata_ali.c driver (the old drivers/ide ++ * makes a compatibility effort to change the IDE interrupts). ++ */ ++static void __devinit quirk_ali_ide_compatibility(struct pci_dev *pdev) ++{ ++ u8 tmp; ++ ++ /* pdev->irq and pdev->pin have yet to be initialised, so check ++ * by reading from the configuration header to see if we've got ++ * a valid interrupt line. */ ++ ++ pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp); ++ if (tmp != 0xff) ++ return; ++ ++ pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp); ++ if (tmp & 0x5) { ++ dev_info(&pdev->dev, "quirk: changing to IDE compatibility mode\n"); ++ ++ tmp &= ~0x05; ++ pdev->class &= ~0x05; ++ pci_write_config_byte(pdev, PCI_CLASS_PROG, tmp); ++ } ++} ++ ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, quirk_ali_ide_compatibility); ++ + /* + * Intel 82801CAM ICH3-M datasheet says IDE modes must be the same + */ diff --git a/kernel/kernel/files/patches/mageia/pci-quirks-drop-devinit-exit.patch b/kernel/kernel/files/patches/mageia/pci-quirks-drop-devinit-exit.patch new file mode 100644 index 00000000..c8eeeda0 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/pci-quirks-drop-devinit-exit.patch @@ -0,0 +1,11 @@ +--- ./drivers/pci/quirks.c.orig 2013-01-16 18:13:57.000000000 +0200 ++++ ./drivers/pci/quirks.c 2013-01-16 18:42:24.331008402 +0200 +@@ -1083,7 +1083,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SE + * which cannot be supported by the pata_ali.c driver (the old drivers/ide + * makes a compatibility effort to change the IDE interrupts). + */ +-static void __devinit quirk_ali_ide_compatibility(struct pci_dev *pdev) ++static void quirk_ali_ide_compatibility(struct pci_dev *pdev) + { + u8 tmp; + diff --git a/kernel/kernel/files/patches/mageia/platform-x86-add-shuttle-wmi-driver.patch b/kernel/kernel/files/patches/mageia/platform-x86-add-shuttle-wmi-driver.patch new file mode 100644 index 00000000..2361b737 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/platform-x86-add-shuttle-wmi-driver.patch @@ -0,0 +1,1437 @@ + + Documentation/ABI/testing/sysfs-platform-shuttle-wmi | 72 + + MAINTAINERS | 6 + drivers/platform/x86/Kconfig | 15 + drivers/platform/x86/Makefile | 1 + drivers/platform/x86/shuttle-wmi.c | 1297 +++++++++++++++++++ + 5 files changed, 1391 insertions(+) + +diff -Nurp linux-3.14.2/Documentation/ABI/testing/sysfs-platform-shuttle-wmi linux-3.14.2-shuttle/Documentation/ABI/testing/sysfs-platform-shuttle-wmi +--- linux-3.14.2/Documentation/ABI/testing/sysfs-platform-shuttle-wmi 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.14.2-shuttle/Documentation/ABI/testing/sysfs-platform-shuttle-wmi 2014-04-26 18:33:26.867761088 +0300 +@@ -0,0 +1,72 @@ ++What: /sys/devices/platform/shuttle_wmi/lcd_auto_adjust ++Date: December 2010 ++KernelVersion: 2.6.36 ++Contact: "Herton Ronaldo Krzesinski" ++Description: ++ This is a write only option (accepts any single value, eg. ++ "echo 1 > lcd_auto_adjust") that starts LCD auto-adjust ++ function, if the machine has this function enabled. Some ++ shuttle machines have LCD attached to analog VGA connector, ++ so uses/needs auto-adjust. ++ ++What: /sys/devices/platform/shuttle_wmi/model_name ++Date: December 2010 ++KernelVersion: 2.6.36 ++Contact: "Herton Ronaldo Krzesinski" ++Description: ++ This is a read only attribute which outputs a string with model ++ name of the machine. When shuttle-wmi can't determine which ++ model it is, "Unknown" is returned. Otherwise, the possible ++ models are "Shuttle MA", "Shuttle DA18IE", "Shuttle DA18IM", ++ "Shuttle X50 V2", "Positivo A14IE01", "Positivo P13", ++ "Positivo P14". ++ ++What: /sys/devices/platform/shuttle_wmi/panel_set_default ++Date: December 2010 ++KernelVersion: 2.6.36 ++Contact: "Herton Ronaldo Krzesinski" ++Description: ++ This is a write only option (accepts any single value, eg. ++ "echo 1 > panel_set_default"). Probably resets panel/lcd to ++ default configuration, function not explained in shuttle wmi ++ documentation. It also starts an auto adjust and color adjust ++ cycle. The function should only work in shuttle machines with ++ LCD attached to an analog VGA connector. ++ ++What: /sys/devices/platform/shuttle_wmi/powersave ++Date: December 2010 ++KernelVersion: 2.6.36 ++Contact: "Herton Ronaldo Krzesinski" ++Description: ++ Control powersave state. 1 means on, 0 means off. ++ When enabled, it basically forces the cpu to stay on powersave ++ state (only works if cpu has P-states support, it is similar to ++ powersave governor in cpufreq) when machine is only running on ++ battery. If not running on battery, this function isn't expected ++ to work, any attempt to enable this returns -EIO. ++ ++What: /sys/devices/platform/shuttle_wmi/touchpad_off ++Date: December 2010 ++KernelVersion: 2.6.36 ++Contact: "Herton Ronaldo Krzesinski" ++Description: ++ Control touchpad state. 1 means off, 0 means on. ++ ++What: /sys/devices/platform/shuttle_wmi/webcam ++Date: December 2010 ++KernelVersion: 2.6.36 ++Contact: "Herton Ronaldo Krzesinski" ++Description: ++ Control webcam state. 1 means on, 0 means off. ++ ++What: /sys/devices/platform/shuttle_wmi/white_balance ++Date: December 2010 ++KernelVersion: 2.6.36 ++Contact: "Herton Ronaldo Krzesinski" ++Description: ++ This is a write only option (accepts any single value, eg. ++ "echo 1 > white_balance"). Probably triggers an automatic ++ white balance adjustment for lcd, function not explained in ++ shuttle wmi documentation. It also starts an auto adjust and ++ color adjust cycle. The function should only work in shuttle ++ machines with LCD attached to an analog VGA connector. +diff -Nurp linux-3.14.2/drivers/platform/x86/Kconfig linux-3.14.2-shuttle/drivers/platform/x86/Kconfig +--- linux-3.14.2/drivers/platform/x86/Kconfig 2014-03-31 06:40:15.000000000 +0300 ++++ linux-3.14.2-shuttle/drivers/platform/x86/Kconfig 2014-04-26 18:33:26.867761088 +0300 +@@ -811,6 +811,21 @@ config INTEL_SMARTCONNECT + This driver checks to determine whether the device has Intel Smart + Connect enabled, and if so disables it. + ++config SHUTTLE_WMI ++ tristate "Shuttle WMI Extras Driver" ++ depends on ACPI_WMI ++ depends on BACKLIGHT_CLASS_DEVICE ++ depends on RFKILL ++ depends on INPUT ++ select INPUT_SPARSEKMAP ++ ---help--- ++ This is a driver for the WMI interface present on some Shuttle ++ machines. It adds controls for wireless, bluetooth and 3g radios, ++ webcam switch, backlight controls, among others. ++ ++ If you have a Shuttle machine with ACPI-WMI interface say Y or M ++ here. ++ + config PVPANIC + tristate "pvpanic device support" + depends on ACPI +diff -Nurp linux-3.14.2/drivers/platform/x86/Makefile linux-3.14.2-shuttle/drivers/platform/x86/Makefile +--- linux-3.15/drivers/platform/x86/Makefile ++++ linux-3.15-shuttle/drivers/platform/x86/Makefile +@@ -53,6 +53,7 @@ obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10 + obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o + obj-$(CONFIG_INTEL_RST) += intel-rst.o + obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o ++obj-$(CONFIG_SHUTTLE_WMI) += shuttle-wmi.o + + obj-$(CONFIG_PVPANIC) += pvpanic.o + obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o +diff -Nurp linux-3.14.2/drivers/platform/x86/shuttle-wmi.c linux-3.14.2-shuttle/drivers/platform/x86/shuttle-wmi.c +--- linux-3.14.2/drivers/platform/x86/shuttle-wmi.c 1970-01-01 02:00:00.000000000 +0200 ++++ linux-3.14.2-shuttle/drivers/platform/x86/shuttle-wmi.c 2014-04-26 18:33:26.868761096 +0300 +@@ -0,0 +1,1297 @@ ++/* ++ * ACPI-WMI driver for Shuttle WMI interface ++ * ++ * Copyright (c) 2010 Herton Ronaldo Krzesinski ++ * ++ * Development of this driver was funded by Positivo Informatica S.A. ++ * Parts of the driver were based on some WMI documentation provided by Shuttle ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Herton Ronaldo Krzesinski"); ++MODULE_DESCRIPTION("Shuttle WMI Extras Driver"); ++MODULE_LICENSE("GPL"); ++ ++#define SHUTTLE_WMI_SETGET_GUID "abbc0f6f-8ea1-11d1-00a0-c90629100000" ++#define SHUTTLE_WMI_EVENT_GUID "abbc0f72-8ea1-11d1-00a0-c90629100000" ++MODULE_ALIAS("wmi:"SHUTTLE_WMI_SETGET_GUID); ++MODULE_ALIAS("wmi:"SHUTTLE_WMI_EVENT_GUID); ++ ++#define CMD_WRITEEC 0x00 ++#define CMD_READEC 0x01 ++#define CMD_SCMD 0x02 ++#define CMD_INT15 0x03 ++#define CMD_HWSW 0x07 ++#define CMD_LCTRL 0x09 ++#define CMD_CUTLVDS 0x11 ++#define CMD_MA 0x18 ++#define CMD_DA18IE 0x19 ++#define CMD_DA18IM 0x20 ++ ++#define ECRAM_ER0 0x443 ++#define ECRAM_ER1 0x45a ++#define ECRAM_ER2 0x47b ++#define ECRAM_ER3 0x758 ++#define ECRAM_ER4 0x759 ++ ++struct shuttle_ecram { ++ unsigned short addr; ++ u32 mask; ++}; ++ ++struct shuttle_state { ++ struct shuttle_ecram ecram; ++ struct device_attribute *dev_attr; ++}; ++ ++static struct shuttle_state state_powersave = { ++ .ecram = { ++ .addr = ECRAM_ER3, ++ .mask = 0x10, ++ }, ++}; ++ ++static struct shuttle_state state_touchpad_off = { ++ .ecram = { ++ .addr = ECRAM_ER2, ++ .mask = 0x02, ++ }, ++}; ++ ++static struct shuttle_state state_webcam = { ++ .ecram = { ++ .addr = ECRAM_ER2, ++ .mask = 0x10, ++ }, ++}; ++ ++struct shuttle_rfkill { ++ struct rfkill *rfk; ++ enum rfkill_type type; ++ struct shuttle_ecram ecram_state; ++ struct shuttle_ecram ecram_present; ++ /* lists of rf state switch notification codes */ ++ u32 rf_on[3]; ++ u32 rf_off[3]; ++}; ++ ++static struct shuttle_rfkill srfk_3g = { ++ .type = RFKILL_TYPE_WWAN, ++ .ecram_state = { ++ .addr = ECRAM_ER2, ++ .mask = 0x40, ++ }, ++ .rf_on = { 0x10, 0x29 }, ++ .rf_off = { 0x11, 0x2a }, ++}; ++ ++static struct shuttle_rfkill srfk_bluetooth = { ++ .type = RFKILL_TYPE_BLUETOOTH, ++ .ecram_state = { ++ .addr = ECRAM_ER2, ++ .mask = 0x20, ++ }, ++ .rf_on = { 0x0c, 0x29 }, ++ .rf_off = { 0x0d, 0x2a }, ++}; ++ ++static struct shuttle_rfkill srfk_wlan = { ++ .type = RFKILL_TYPE_WLAN, ++ .ecram_state = { ++ .addr = ECRAM_ER2, ++ .mask = 0x80, ++ }, ++ .ecram_present = { ++ .addr = ECRAM_ER1, ++ .mask = 0x80, ++ }, ++ .rf_on = { 0x08 }, ++ .rf_off = { 0x09 }, ++}; ++ ++enum fn_type { ++ FN_CMD, ++ FN_CMD_DEBUG, ++ FN_RFKILL, ++ FN_STATE ++}; ++ ++struct shuttle_fn_map { ++ char *name; ++ enum fn_type type; ++ unsigned short cmd; ++ unsigned short arg; ++ unsigned short fn; ++ void *data; ++}; ++ ++static struct shuttle_fn_map unknown_fn_map[] = { ++ { "fn_f1", FN_CMD_DEBUG, CMD_SCMD, 0, 0x01, NULL }, ++ { "fn_f2", FN_CMD_DEBUG, CMD_SCMD, 0, 0x02, NULL }, ++ { "fn_f3", FN_CMD_DEBUG, CMD_SCMD, 0, 0x03, NULL }, ++ { "fn_f4", FN_CMD_DEBUG, CMD_SCMD, 0, 0x04, NULL }, ++ { "fn_f5", FN_CMD_DEBUG, CMD_SCMD, 0, 0x05, NULL }, ++ { "fn_f6", FN_CMD_DEBUG, CMD_SCMD, 0, 0x06, NULL }, ++ { "fn_f7", FN_CMD_DEBUG, CMD_SCMD, 0, 0x07, NULL }, ++ { "fn_f8", FN_CMD_DEBUG, CMD_SCMD, 0, 0x08, NULL }, ++ { "fn_f9", FN_CMD_DEBUG, CMD_SCMD, 0, 0x09, NULL }, ++ { "fn_f10", FN_CMD_DEBUG, CMD_SCMD, 0, 0x0a, NULL }, ++ { "fn_f11", FN_CMD_DEBUG, CMD_SCMD, 0, 0x0b, NULL }, ++ { "fn_f12", FN_CMD_DEBUG, CMD_SCMD, 0, 0x0c, NULL }, ++ { "fn_f13", FN_CMD_DEBUG, CMD_SCMD, 0, 0x0d, NULL }, ++ { "fn_f14", FN_CMD_DEBUG, CMD_SCMD, 0, 0x0e, NULL }, ++ { "fn_f15", FN_CMD_DEBUG, CMD_SCMD, 0, 0x0f, NULL }, ++ { "lcd_auto_adjust", FN_CMD, CMD_SCMD, 0, 0x81, NULL }, ++ { "lightbar_brightness_down", FN_CMD_DEBUG, CMD_LCTRL, 1, 0x00, NULL }, ++ { "lightbar_brightness_up", FN_CMD_DEBUG, CMD_LCTRL, 1, 0x01, NULL }, ++ { "panel_set_default", FN_CMD, CMD_SCMD, 0, 0x83, NULL }, ++ { "video_output_on", FN_CMD_DEBUG, CMD_CUTLVDS, 0, 0x01, NULL}, ++ { "video_output_off", FN_CMD_DEBUG, CMD_CUTLVDS, 0, 0x00, NULL}, ++ { "white_balance", FN_CMD, CMD_SCMD, 0, 0x82, NULL }, ++ { } ++}; ++ ++static struct shuttle_fn_map fn_map_1[] = { ++ { "brightness_down", FN_CMD_DEBUG, CMD_SCMD, 0, 0x0b, NULL }, ++ { "brightness_up", FN_CMD_DEBUG, CMD_SCMD, 0, 0x0c, NULL }, ++ { "lcd_auto_adjust", FN_CMD, CMD_SCMD, 0, 0x81, NULL }, ++ { "lightbar_brightness_down", FN_CMD_DEBUG, CMD_LCTRL, 1, 0x00, NULL }, ++ { "lightbar_brightness_up", FN_CMD_DEBUG, CMD_LCTRL, 1, 0x01, NULL }, ++ { "panel_set_default", FN_CMD, CMD_SCMD, 0, 0x83, NULL }, ++ { "powersave", FN_STATE, CMD_SCMD, 0, 0x02, &state_powersave }, ++ { "shuttle_3g", FN_RFKILL, CMD_SCMD, 0, 0x05, &srfk_3g }, ++ { "shuttle_bluetooth", FN_RFKILL, CMD_SCMD, 0, 0x0d, &srfk_bluetooth }, ++ { "shuttle_wlan", FN_RFKILL, CMD_SCMD, 0, 0x04, &srfk_wlan }, ++ { "sleep", FN_CMD_DEBUG, CMD_SCMD, 0, 0x01, NULL }, ++ { "sound_mute", FN_CMD_DEBUG, CMD_SCMD, 0, 0x08, NULL }, ++ { "switch_video", FN_CMD_DEBUG, CMD_SCMD, 0, 0x03, NULL }, ++ { "touchpad_off", FN_STATE, CMD_SCMD, 0, 0x06, &state_touchpad_off }, ++ { "volume_down", FN_CMD_DEBUG, CMD_SCMD, 0, 0x09, NULL }, ++ { "volume_up", FN_CMD_DEBUG, CMD_SCMD, 0, 0x0a, NULL }, ++ { "video_output_on", FN_CMD_DEBUG, CMD_CUTLVDS, 0, 0x01, NULL}, ++ { "video_output_off", FN_CMD_DEBUG, CMD_CUTLVDS, 0, 0x00, NULL}, ++ { "webcam", FN_STATE, CMD_SCMD, 0, 0x07, &state_webcam }, ++ { "white_balance", FN_CMD, CMD_SCMD, 0, 0x82, NULL }, ++ { } ++}; ++ ++static struct shuttle_fn_map fn_map_2[] = { ++ { "brightness_down", FN_CMD_DEBUG, CMD_SCMD, 0, 0x08, NULL }, ++ { "brightness_up", FN_CMD_DEBUG, CMD_SCMD, 0, 0x09, NULL }, ++ { "video_output", FN_CMD_DEBUG, CMD_SCMD, 0, 0x02, NULL }, ++ { "video_output_on", FN_CMD_DEBUG, CMD_CUTLVDS, 0, 0x01, NULL}, ++ { "video_output_off", FN_CMD_DEBUG, CMD_CUTLVDS, 0, 0x00, NULL}, ++ { "shuttle_wlan", FN_RFKILL, CMD_SCMD, 0, 0x0b, &srfk_wlan }, ++ { "sleep", FN_CMD_DEBUG, CMD_SCMD, 0, 0x03, NULL }, ++ { "sound_mute", FN_CMD_DEBUG, CMD_SCMD, 0, 0x04, NULL }, ++ { "switch_video", FN_CMD_DEBUG, CMD_SCMD, 0, 0x07, NULL }, ++ { "touchpad_off", FN_STATE, CMD_SCMD, 0, 0x01, &state_touchpad_off }, ++ { "volume_down", FN_CMD_DEBUG, CMD_SCMD, 0, 0x05, NULL }, ++ { "volume_up", FN_CMD_DEBUG, CMD_SCMD, 0, 0x06, NULL }, ++ { "webcam", FN_STATE, CMD_SCMD, 0, 0x0a, &state_webcam }, ++ { } ++}; ++ ++struct shuttle_backlight { ++ u8 ec_addr; ++ struct shuttle_fn_map *fn_bl_down; ++ struct shuttle_fn_map *fn_bl_up; ++}; ++ ++static struct shuttle_backlight common_bl_desc = { ++ .ec_addr = 0x79, ++}; ++ ++static struct shuttle_backlight quirk_bl_desc = { ++ .ec_addr = 0x79, ++ .fn_bl_down = &fn_map_1[0], ++ .fn_bl_up = &fn_map_1[1], ++}; ++ ++struct shuttle_id { ++ unsigned char cmd_id; ++ const char *model_name; ++ struct shuttle_backlight *bl_desc; ++ struct shuttle_fn_map *fn_map; ++}; ++ ++static struct shuttle_id shuttle_ids[] = { ++ { CMD_MA, "Shuttle MA", &common_bl_desc, fn_map_1 }, ++ { CMD_DA18IE, "Shuttle DA18IE", &quirk_bl_desc, fn_map_1 }, ++ { CMD_DA18IM, "Shuttle DA18IM", &common_bl_desc, fn_map_1 } ++}; ++ ++static struct shuttle_id id_unknown = { ++ .model_name = "Unknown", ++ .fn_map = unknown_fn_map, ++}; ++ ++static struct shuttle_id shuttle_dmi_id; ++ ++static int shuttle_dmi_matched(const struct dmi_system_id *dmi) ++{ ++ shuttle_dmi_id.model_name = dmi->ident; ++ shuttle_dmi_id.bl_desc = &common_bl_desc; ++ shuttle_dmi_id.fn_map = dmi->driver_data; ++ return 1; ++} ++ ++static struct dmi_system_id shuttle_dmi_ids[] = { ++ { ++ .callback = shuttle_dmi_matched, ++ .ident = "Shuttle X50 V2", ++ .matches = { ++ DMI_MATCH(DMI_PRODUCT_NAME, "X50-V2"), ++ }, ++ .driver_data = fn_map_1, ++ }, ++ { ++ .callback = shuttle_dmi_matched, ++ .ident = "Positivo A14IE01", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "POSITIVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "A14IE01"), ++ }, ++ .driver_data = fn_map_2, ++ }, ++ { ++ .callback = shuttle_dmi_matched, ++ .ident = "Positivo P13", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "POSITIVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "P13"), ++ }, ++ .driver_data = fn_map_2, ++ }, ++ { ++ .callback = shuttle_dmi_matched, ++ .ident = "Positivo P14", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "POSITIVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "P14"), ++ }, ++ .driver_data = fn_map_2, ++ }, ++ {} ++}; ++ ++static struct dmi_system_id __devinitdata shuttle_quirk_bl_dmi_ids[] = { ++ { ++ .ident = "Positivo M13", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "POSITIVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "M13"), ++ }, ++ }, ++ { ++ .ident = "Positivo M14", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "POSITIVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "M14"), ++ }, ++ }, ++ { ++ .ident = "Positivo A14IM01", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "POSITIVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "A14IM01"), ++ }, ++ }, ++ { ++ .ident = "Positivo J14IM21", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "POSITIVO"), ++ DMI_MATCH(DMI_BOARD_NAME, "J14IM21"), ++ }, ++ }, ++ {} ++}; ++ ++struct shuttle_wmi { ++ struct platform_device *pdev; ++ struct shuttle_id *id; ++ struct dentry *dbg_root; ++ struct attribute_group *attr_group; ++ struct input_dev *inputdev; ++ struct backlight_device *bd; ++}; ++ ++struct shuttle_cmd { ++ u16 param2; ++ u16 param1; ++ u8 arg; ++ u8 cmd; ++ u16 hdr; ++}; ++ ++static int wmi_setget_mtd(struct shuttle_cmd *scmd, u32 *res) ++{ ++ acpi_status status; ++ union acpi_object *obj; ++ struct acpi_buffer input; ++ static DEFINE_MUTEX(mtd_lock); ++ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; ++ ++ input.length = sizeof(struct shuttle_cmd); ++ scmd->hdr = 0xec00; ++ input.pointer = (u8 *) scmd; ++ ++ /* We must serialize access to wmi_evaluate_method: the wmi interface ++ * functions in the bios save its parameters on a common shared buffer, ++ * which gets overwritten on parallel calls with unpredicted results; ++ * AML code doesn't have any locking, so we must do this here */ ++ mutex_lock(&mtd_lock); ++ status = wmi_evaluate_method(SHUTTLE_WMI_SETGET_GUID, 0, 2, ++ &input, &output); ++ mutex_unlock(&mtd_lock); ++ if (ACPI_FAILURE(status)) ++ return -1; ++ ++ obj = output.pointer; ++ if (obj) { ++ if (obj->type == ACPI_TYPE_INTEGER) { ++ if (res) ++ *res = obj->integer.value; ++ } else { ++ pr_err("Unsupported object returned (%s)", __func__); ++ res = NULL; ++ } ++ kfree(obj); ++ } else { ++ if (res) { ++ pr_warning("No result from WMI method (%s)", __func__); ++ res = NULL; ++ } ++ } ++ ++ return (res) ? 0 : 1; ++} ++ ++static int wmi_ec_cmd(unsigned char cmd, unsigned char arg, ++ unsigned short param1, unsigned short param2, ++ u32 *res) ++{ ++ struct shuttle_cmd scmd = { ++ .cmd = cmd, ++ .arg = arg, ++ .param1 = param1, ++ .param2 = param2 ++ }; ++ ++ return wmi_setget_mtd(&scmd, res); ++} ++ ++static int wmi_ec_state(struct shuttle_ecram *ecram) ++{ ++ u32 val; ++ ++ if (wmi_ec_cmd(CMD_READEC, 0, 0, ecram->addr, &val)) ++ return -EIO; ++ return (val & ecram->mask) ? 1 : 0; ++} ++ ++static int rfkill_common_set_block(void *data, bool blocked) ++{ ++ int sw; ++ struct shuttle_fn_map *fn_map = data; ++ struct shuttle_rfkill *srfk = fn_map->data; ++ ++ sw = wmi_ec_state(&srfk->ecram_state); ++ if (sw < 0) ++ return sw; ++ ++ if (blocked == sw) ++ wmi_ec_cmd(fn_map->cmd, fn_map->arg, 0, fn_map->fn, NULL); ++ else ++ return 0; ++ ++ sw = wmi_ec_state(&srfk->ecram_state); ++ if (sw < 0) ++ return sw; ++ ++ return (sw != blocked) ? 0 : -EIO; ++} ++ ++static const struct rfkill_ops rfkill_common_ops = { ++ .set_block = rfkill_common_set_block, ++}; ++ ++static void pr_possible_dev_state(void) ++{ ++ static bool pr; ++ u32 val; ++ ++ if (!pr) { ++ pr = true; ++ pr_info("need to unblock some rfkills to check device" ++ " presence\n"); ++ if (!wmi_ec_cmd(CMD_READEC, 0, 0, ECRAM_ER1, &val)) ++ pr_info("possible device present state at address" ++ " 0x%04x is 0x%08x\n", ECRAM_ER1, val); ++ } ++} ++ ++static int shuttle_rfkill_init(struct shuttle_fn_map *fn_map, ++ struct device *dev) ++{ ++ int rc; ++ struct shuttle_rfkill *srfk = fn_map->data; ++ ++ /* Try to detect if device controlled by this rfkill is present, to ++ * avoid having an rfkill switch when not needed */ ++ if (srfk->ecram_present.mask && srfk->ecram_present.addr) { ++ /* we have an address to read to check if device is present */ ++ rc = wmi_ec_state(&srfk->ecram_present); ++ if (rc <= 0) ++ return rc; ++ ++ rc = wmi_ec_state(&srfk->ecram_state); ++ if (rc < 0) ++ return rc; ++ } else { ++ /* print only once the possible value of devices presence, for ++ * extra information (useful to check if really device presence ++ * is or isn't available at usual ECRAM_ER1 address) */ ++ pr_possible_dev_state(); ++ ++ /* no address/mask to check, detect if device is available by ++ * trying to enable it, in case it's disabled */ ++ rc = wmi_ec_state(&srfk->ecram_state); ++ if (rc < 0) ++ return rc; ++ if (!rc) { ++ if (rfkill_common_set_block(fn_map, false)) ++ return 0; ++ ++ /* after check, reset to initial setting; should be ++ * unlikely this returns with error, but really check if ++ * we could reset to initial blocked setting, otherwise ++ * don't make it a fatal error and assume rfkill not ++ * blocked */ ++ if (rfkill_common_set_block(fn_map, true)) ++ rc = 1; ++ } ++ } ++ ++ srfk->rfk = rfkill_alloc(fn_map->name, dev, srfk->type, ++ &rfkill_common_ops, fn_map); ++ if (!srfk->rfk) ++ return -ENOMEM; ++ ++ rfkill_init_sw_state(srfk->rfk, !rc); ++ ++ rc = rfkill_register(srfk->rfk); ++ if (rc) { ++ rfkill_destroy(srfk->rfk); ++ srfk->rfk = NULL; ++ return rc; ++ } ++ ++ return 0; ++} ++ ++static void shuttle_rfkill_remove(struct shuttle_fn_map *fn_map) ++{ ++ struct shuttle_rfkill *srfk = fn_map->data; ++ ++ if (srfk->rfk) { ++ rfkill_unregister(srfk->rfk); ++ rfkill_destroy(srfk->rfk); ++ srfk->rfk = NULL; ++ } ++} ++ ++static int shuttle_rfkill_resume(struct device *dev) ++{ ++ struct shuttle_fn_map *fn_map; ++ struct shuttle_rfkill *srfk; ++ int rc; ++ struct platform_device *pdev = to_platform_device(dev); ++ struct shuttle_wmi *priv = platform_get_drvdata(pdev); ++ ++ for (fn_map = priv->id->fn_map; fn_map->name; fn_map++) { ++ if (fn_map->type != FN_RFKILL) ++ continue; ++ ++ srfk = fn_map->data; ++ if (srfk->rfk) { ++ rc = wmi_ec_state(&srfk->ecram_state); ++ if (rc < 0) ++ return rc; ++ rfkill_set_sw_state(srfk->rfk, rc); ++ } ++ } ++ return 0; ++} ++ ++static bool set_rfkill_sw(u32 *list, u32 code, struct rfkill *rfk, bool blocked) ++{ ++ while (*list) { ++ if (*list == code) { ++ rfkill_set_sw_state(rfk, blocked); ++ return true; ++ } ++ list++; ++ } ++ return false; ++} ++ ++static bool notify_switch_rfkill(struct shuttle_wmi *priv, u32 code) ++{ ++ struct shuttle_fn_map *fn_map; ++ struct shuttle_rfkill *srfk; ++ struct rfkill *rfk; ++ bool res = false; ++ ++ for (fn_map = priv->id->fn_map; fn_map->name; fn_map++) { ++ if (fn_map->type != FN_RFKILL) ++ continue; ++ ++ srfk = fn_map->data; ++ rfk = srfk->rfk; ++ if (!rfk) ++ continue; ++ ++ /* check if notification code means radio turned on, looking ++ * at list_on array of "on" notification codes for this rfkill; ++ * if code is in this list, we notify rfkill core (set_rfkill_sw ++ * does the check, notification and returns true) and we can ++ * skip to next rfkill on the list (some notification codes are ++ * shared, firmware may want to turn on two radios at same time, ++ * so we must check all rfkills with this code) */ ++ if (set_rfkill_sw(srfk->rf_on, code, rfk, false)) { ++ res = true; ++ continue; ++ } ++ ++ /* same as above, but we check the list_off to see if ++ * notification code means radio turned off */ ++ if (set_rfkill_sw(srfk->rf_off, code, rfk, true)) ++ res = true; ++ } ++ /* if we found that notification code was indeed a radio on/off event, ++ * return true here */ ++ return res; ++} ++ ++static bool notify_switch_attr(struct platform_device *pdev, u32 code) ++{ ++ int i; ++ struct shuttle_switch { ++ u32 switch_on; ++ u32 switch_off; ++ char *sys_attr; ++ }; ++ static const struct shuttle_switch codes[] = { ++ { 0x04, 0x05, "touchpad_off" }, ++ { 0x12, 0x13, "webcam" }, ++ { 0x31, 0x32, "powersave" } ++ }; ++ ++ for (i = 0; i < ARRAY_SIZE(codes); i++) { ++ if (codes[i].switch_on == code || codes[i].switch_off == code) { ++ sysfs_notify(&pdev->dev.kobj, NULL, codes[i].sys_attr); ++ return true; ++ } ++ } ++ return false; ++} ++ ++static void shuttle_wmi_notify(u32 value, void *data) ++{ ++ acpi_status status; ++ union acpi_object *obj; ++ u8 type; ++ u32 code; ++ struct acpi_buffer res = { ACPI_ALLOCATE_BUFFER, NULL }; ++ struct shuttle_wmi *priv = data; ++ ++ status = wmi_get_event_data(value, &res); ++ if (status != AE_OK) { ++ pr_warning("unable to retrieve wmi event status" ++ " (error=0x%x)\n", status); ++ return; ++ } ++ ++ obj = (union acpi_object *) res.pointer; ++ if (!obj) ++ return; ++ if (obj->type != ACPI_TYPE_INTEGER) { ++ pr_info("unknown object returned in wmi event\n"); ++ goto notify_exit; ++ } ++ ++ type = (obj->integer.value >> 24) & 0xFF; ++ switch (type) { ++ case 0: /* OSD/Scancode event */ ++ code = obj->integer.value & 0xFFFFFF; ++ ++ /* update rfkill switches */ ++ if (notify_switch_rfkill(priv, code)) ++ break; ++ ++ /* send notification on state switch attributes */ ++ if (notify_switch_attr(priv->pdev, code)) ++ break; ++ ++ if (priv->bd && (code == 0x14 || code == 0x15)) { ++ backlight_force_update(priv->bd, ++ BACKLIGHT_UPDATE_HOTKEY); ++ break; ++ } ++ ++ if (!sparse_keymap_report_event(priv->inputdev, code, 1, true)) ++ pr_info("unhandled scancode (0x%06x)\n", code); ++ break; ++ case 1: /* Power management event */ ++ /* Events not used. ++ * Possible values for obj->integer.value: ++ * 0x01000000 - silent mode ++ * 0x01010000 - brightness sync */ ++ case 2: /* i-PowerXross event */ ++ /* i-PowerXross is a overclocking feature, not ++ * implemented, there are no further details, possible ++ * values for obj->integer.value in documentation: ++ * 0x02000000 - idle mode ++ * 0x02010000 - action mode ++ * 0x02020000 - entry s3 */ ++ break; ++ case 0xec: /* Lost event */ ++ if (printk_ratelimit()) ++ pr_warning("lost event because of buggy BIOS"); ++ break; ++ default: ++ pr_info("unknown wmi notification type (0x%02x)\n", type); ++ } ++ ++notify_exit: ++ kfree(obj); ++} ++ ++static const struct key_entry shuttle_wmi_keymap[] = { ++ { KE_IGNORE, 0x14, { KEY_BRIGHTNESSUP } }, ++ { KE_IGNORE, 0x15, { KEY_BRIGHTNESSDOWN } }, ++ { KE_KEY, 0x16, { KEY_FASTFORWARD } }, ++ { KE_KEY, 0x17, { KEY_REWIND } }, ++ { KE_KEY, 0x18, { KEY_F13 } }, /* OSD Beep */ ++ { KE_KEY, 0x2b, { KEY_F14 } }, /* OSD menu 1 */ ++ { KE_KEY, 0x2c, { KEY_F15 } }, /* OSD menu 2 */ ++ { KE_KEY, 0x2d, { KEY_F16 } }, /* OSD menu 3 */ ++ { KE_KEY, 0x2e, { KEY_F17 } }, /* OSD menu 4 */ ++ { KE_KEY, 0x33, { KEY_F18 } }, /* Update OSD bar status */ ++ { KE_KEY, 0x90, { KEY_WWW } }, ++ { KE_KEY, 0x95, { KEY_PREVIOUSSONG } }, ++ { KE_KEY, 0xa0, { KEY_PROG1 } }, /* Call OSD software */ ++ { KE_KEY, 0xa1, { KEY_VOLUMEDOWN } }, ++ { KE_KEY, 0xa3, { KEY_MUTE } }, ++ { KE_KEY, 0xb2, { KEY_VOLUMEUP } }, ++ { KE_KEY, 0xb4, { KEY_PLAYPAUSE } }, ++ { KE_KEY, 0xbb, { KEY_STOPCD } }, ++ { KE_KEY, 0xc8, { KEY_MAIL } }, ++ { KE_KEY, 0xcd, { KEY_NEXTSONG } }, ++ { KE_KEY, 0xd0, { KEY_MEDIA } }, ++ ++ /* Known non hotkey events don't handled, that we don't care or ++ * which we must ignore */ ++ { KE_IGNORE, 0x01, }, /* Caps Lock toggled */ ++ { KE_IGNORE, 0x02, }, /* Num Lock toggled */ ++ { KE_IGNORE, 0x03, }, /* Scroll Lock toggled */ ++ { KE_IGNORE, 0x06, }, /* Downclock/Silent on */ ++ { KE_IGNORE, 0x07, }, /* Downclock/Silent off */ ++ { KE_IGNORE, 0x0a, }, /* WiMax on */ ++ { KE_IGNORE, 0x0b, }, /* WiMax off */ ++ { KE_IGNORE, 0x0e, }, /* RF on */ ++ { KE_IGNORE, 0x0f, }, /* RF off */ ++ { KE_IGNORE, 0x1a, }, /* Auto Brightness on */ ++ { KE_IGNORE, 0x1b, }, /* Auto Brightness off */ ++ { KE_IGNORE, 0x1c, }, /* Auto-KB Brightness on */ ++ { KE_IGNORE, 0x1d, }, /* Auto-KB Brightness off */ ++ { KE_IGNORE, 0x1e, }, /* Light Bar Brightness up */ ++ { KE_IGNORE, 0x1f, }, /* Light Bar Brightness down */ ++ { KE_IGNORE, 0x20, }, /* China Telecom AP enable */ ++ { KE_IGNORE, 0x21, }, /* China Mobile AP enable */ ++ { KE_IGNORE, 0x22, }, /* Huawei AP enable */ ++ { KE_IGNORE, 0x23, }, /* Docking in */ ++ { KE_IGNORE, 0x24, }, /* Docking out */ ++ { KE_IGNORE, 0x25, }, /* Device no function */ ++ { KE_IGNORE, 0x26, }, /* i-PowerXross OverClocking */ ++ { KE_IGNORE, 0x27, }, /* i-PowerXross PowerSaving */ ++ { KE_IGNORE, 0x28, }, /* i-PowerXross off */ ++ { KE_IGNORE, 0x2f, }, /* Optimus on */ ++ { KE_IGNORE, 0x30, }, /* Optimus off */ ++ { KE_IGNORE, 0x91, }, /* ICO 2 on */ ++ { KE_IGNORE, 0x92, }, /* ICO 2 off */ ++ ++ { KE_END, 0 } ++}; ++ ++static int shuttle_wmi_input_init(struct shuttle_wmi *priv) ++{ ++ struct input_dev *input; ++ int rc; ++ ++ input = input_allocate_device(); ++ if (!input) ++ return -ENOMEM; ++ ++ input->name = "Shuttle WMI hotkeys"; ++ input->phys = KBUILD_MODNAME "/input0"; ++ input->id.bustype = BUS_HOST; ++ ++ rc = sparse_keymap_setup(input, shuttle_wmi_keymap, NULL); ++ if (rc) ++ goto err_free_dev; ++ ++ rc = input_register_device(input); ++ if (rc) ++ goto err_free_keymap; ++ ++ priv->inputdev = input; ++ return 0; ++ ++err_free_keymap: ++ sparse_keymap_free(input); ++err_free_dev: ++ input_free_device(input); ++ return rc; ++} ++ ++static void shuttle_wmi_input_remove(struct shuttle_wmi *priv) ++{ ++ struct input_dev *input = priv->inputdev; ++ ++ sparse_keymap_free(input); ++ input_unregister_device(input); ++} ++ ++static int shuttle_wmi_get_bl(struct backlight_device *bd) ++{ ++ u8 val; ++ int rc; ++ struct shuttle_wmi *priv = bl_get_data(bd); ++ struct shuttle_backlight *sbl = priv->id->bl_desc; ++ ++ rc = ec_read(sbl->ec_addr, &val); ++ if (rc) ++ return rc; ++ return val & 7; ++} ++ ++static int shuttle_wmi_update_bl(struct backlight_device *bd) ++{ ++ int rc, steps; ++ u8 val; ++ struct shuttle_fn_map *fn_down, *fn_up; ++ struct shuttle_wmi *priv = bl_get_data(bd); ++ struct shuttle_backlight *sbl = priv->id->bl_desc; ++ ++ fn_down = sbl->fn_bl_down; ++ fn_up = sbl->fn_bl_up; ++ if (!fn_down || !fn_up) { ++ rc = ec_write(sbl->ec_addr, bd->props.brightness); ++ if (rc) ++ return rc; ++ } else { ++ /* change brightness by steps, this is a quirk for shuttle ++ * machines which don't accept direct write to ec for this */ ++ rc = ec_read(sbl->ec_addr, &val); ++ if (rc) ++ return rc; ++ steps = bd->props.brightness - (val & 7); ++ while (steps > 0) { ++ wmi_ec_cmd(fn_up->cmd, fn_up->arg, 0, fn_up->fn, NULL); ++ steps--; ++ } ++ while (steps < 0) { ++ wmi_ec_cmd(fn_down->cmd, fn_down->arg, 0, fn_down->fn, ++ NULL); ++ steps++; ++ } ++ } ++ ++ wmi_ec_cmd(CMD_CUTLVDS, 0, 0, ++ (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0, ++ NULL); ++ ++ return 0; ++} ++ ++static const struct backlight_ops shuttle_wmi_bl_ops = { ++ .get_brightness = shuttle_wmi_get_bl, ++ .update_status = shuttle_wmi_update_bl, ++}; ++ ++static int shuttle_wmi_backlight_init(struct shuttle_wmi *priv) ++{ ++ int rc; ++ u8 val; ++ struct backlight_properties props; ++ struct backlight_device *bd; ++ struct shuttle_backlight *sbl = priv->id->bl_desc; ++ ++ rc = ec_read(sbl->ec_addr, &val); ++ if (rc) ++ return rc; ++ memset(&props, 0, sizeof(struct backlight_properties)); ++ props.max_brightness = 7; ++ props.brightness = val & 7; ++ props.power = FB_BLANK_UNBLANK; ++ ++ bd = backlight_device_register(KBUILD_MODNAME, &priv->pdev->dev, priv, ++ &shuttle_wmi_bl_ops, &props); ++ if (IS_ERR(bd)) ++ return PTR_ERR(bd); ++ priv->bd = bd; ++ return 0; ++} ++ ++static void shuttle_wmi_backlight_exit(struct shuttle_wmi *priv) ++{ ++ if (priv->bd) ++ backlight_device_unregister(priv->bd); ++} ++ ++static ssize_t store_fn_cmd(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct shuttle_wmi *priv = platform_get_drvdata(pdev); ++ struct shuttle_fn_map *fn_map; ++ ++ for (fn_map = priv->id->fn_map; fn_map->name; fn_map++) { ++ if (fn_map->name == attr->attr.name) { ++ wmi_ec_cmd(fn_map->cmd, fn_map->arg, 0, fn_map->fn, ++ NULL); ++ return count; ++ } ++ } ++ return -EIO; ++} ++ ++static int set_fn_cmd_debug(void *data, u64 val) ++{ ++ struct shuttle_fn_map *fn_map = data; ++ ++ wmi_ec_cmd(fn_map->cmd, fn_map->arg, 0, fn_map->fn, NULL); ++ /* we don't know yet how many brightness values or maximum brightness ++ * values for lightbar, for now print possible brightness value change ++ * to aid in discovering these */ ++ if (fn_map->cmd == CMD_LCTRL) { ++ u32 val; ++ if (!wmi_ec_cmd(CMD_READEC, 0, 0, ECRAM_ER4, &val)) ++ pr_info("possible lightbar brightness change to value" ++ " 0x%08x\n", val); ++ } ++ return 0; ++} ++DEFINE_SIMPLE_ATTRIBUTE(fops_fn_cmd_debug, NULL, set_fn_cmd_debug, "%llu"); ++ ++static ssize_t show_fn_state(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct shuttle_fn_map *fn_map; ++ struct shuttle_state *state; ++ int sw; ++ struct platform_device *pdev = to_platform_device(dev); ++ struct shuttle_wmi *priv = platform_get_drvdata(pdev); ++ ++ for (fn_map = priv->id->fn_map; fn_map->name; fn_map++) { ++ if (fn_map->name != attr->attr.name) ++ continue; ++ ++ state = fn_map->data; ++ sw = wmi_ec_state(&state->ecram); ++ if (sw < 0) ++ return sw; ++ return sprintf(buf, "%d\n", sw); ++ } ++ return -EIO; ++} ++ ++static ssize_t store_fn_state(struct device *dev, struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ int enable, sw; ++ struct shuttle_fn_map *fn_map; ++ struct shuttle_state *state; ++ struct platform_device *pdev = to_platform_device(dev); ++ struct shuttle_wmi *priv = platform_get_drvdata(pdev); ++ ++ if (sscanf(buf, "%i", &enable) != 1) ++ return -EINVAL; ++ ++ for (fn_map = priv->id->fn_map; fn_map->name; fn_map++) { ++ if (fn_map->name != attr->attr.name) ++ continue; ++ ++ state = fn_map->data; ++ sw = wmi_ec_state(&state->ecram); ++ if (sw < 0) ++ return sw; ++ enable = enable ? 1 : 0; ++ if (enable != sw) { ++ wmi_ec_cmd(fn_map->cmd, fn_map->arg, 0, fn_map->fn, ++ NULL); ++ sw = wmi_ec_state(&state->ecram); ++ if (sw < 0) ++ return sw; ++ if (enable != sw) ++ return -EIO; ++ } ++ return count; ++ } ++ return -EIO; ++} ++ ++static void shuttle_fn_exit(struct shuttle_wmi *priv) ++{ ++ struct shuttle_fn_map *fn_map; ++ struct dentry *dbg_entry; ++ struct shuttle_state *state; ++ ++ if (priv->attr_group) { ++ sysfs_remove_group(&priv->pdev->dev.kobj, priv->attr_group); ++ kfree(priv->attr_group->attrs); ++ kfree(priv->attr_group); ++ priv->attr_group = NULL; ++ } ++ ++ fn_map = priv->id->fn_map; ++ while (fn_map->name) { ++ switch (fn_map->type) { ++ case FN_CMD: ++ kfree(fn_map->data); ++ fn_map->data = NULL; ++ break; ++ case FN_CMD_DEBUG: ++ dbg_entry = fn_map->data; ++ if (dbg_entry) { ++ debugfs_remove(dbg_entry); ++ fn_map->data = NULL; ++ } ++ break; ++ case FN_RFKILL: ++ shuttle_rfkill_remove(fn_map); ++ break; ++ case FN_STATE: ++ state = fn_map->data; ++ kfree(state->dev_attr); ++ state->dev_attr = NULL; ++ break; ++ } ++ fn_map++; ++ } ++} ++ ++static struct device_attribute *new_dev_attr(struct shuttle_fn_map *fn_map) ++{ ++ struct device_attribute *dev_attr; ++ ++ dev_attr = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); ++ if (!dev_attr) ++ return NULL; ++ dev_attr->attr.name = fn_map->name; ++ return dev_attr; ++} ++ ++static int shuttle_fn_init(struct shuttle_wmi *priv) ++{ ++ struct shuttle_fn_map *fn_map; ++ struct device_attribute *dev_attr; ++ struct dentry *dbg_entry; ++ struct shuttle_state *state; ++ struct attribute **attr; ++ int nattr = 0; ++ int rc = -ENOMEM; ++ ++ fn_map = priv->id->fn_map; ++ while (fn_map->name) { ++ switch (fn_map->type) { ++ case FN_CMD: ++ dev_attr = new_dev_attr(fn_map); ++ if (!dev_attr) ++ goto fn_init_err; ++ dev_attr->attr.mode = 0200; ++ dev_attr->store = store_fn_cmd; ++ fn_map->data = dev_attr; ++ nattr++; ++ break; ++ case FN_CMD_DEBUG: ++ dbg_entry = debugfs_create_file(fn_map->name, 0200, ++ priv->dbg_root, fn_map, ++ &fops_fn_cmd_debug); ++ if (!dbg_entry) ++ goto fn_init_err; ++ fn_map->data = dbg_entry; ++ break; ++ case FN_RFKILL: ++ rc = shuttle_rfkill_init(fn_map, &priv->pdev->dev); ++ if (rc) ++ goto fn_init_err; ++ break; ++ case FN_STATE: ++ dev_attr = new_dev_attr(fn_map); ++ if (!dev_attr) ++ goto fn_init_err; ++ dev_attr->attr.mode = 0644; ++ dev_attr->show = show_fn_state; ++ dev_attr->store = store_fn_state; ++ state = fn_map->data; ++ state->dev_attr = dev_attr; ++ nattr++; ++ break; ++ } ++ fn_map++; ++ } ++ ++ /* create array of sysfs attributes (FN_CMD and FN_STATE types) */ ++ if (nattr > 0) { ++ priv->attr_group = kzalloc(sizeof(struct attribute_group), ++ GFP_KERNEL); ++ if (!priv->attr_group) ++ goto fn_init_err; ++ priv->attr_group->attrs = kzalloc(sizeof(struct attribute *) * ++ (nattr + 1), GFP_KERNEL); ++ if (!priv->attr_group->attrs) ++ goto fn_attrs_err; ++ attr = priv->attr_group->attrs; ++ fn_map = priv->id->fn_map; ++ while (fn_map->name) { ++ if (fn_map->type == FN_CMD) { ++ dev_attr = fn_map->data; ++ *attr = &dev_attr->attr; ++ attr++; ++ } else if (fn_map->type == FN_STATE) { ++ state = fn_map->data; ++ *attr = &state->dev_attr->attr; ++ attr++; ++ } ++ fn_map++; ++ } ++ rc = sysfs_create_group(&priv->pdev->dev.kobj, ++ priv->attr_group); ++ if (rc) ++ goto fn_grp_err; ++ } ++ ++ return 0; ++ ++fn_grp_err: ++ kfree(priv->attr_group->attrs); ++fn_attrs_err: ++ kfree(priv->attr_group); ++ priv->attr_group = NULL; ++fn_init_err: ++ shuttle_fn_exit(priv); ++ return rc; ++} ++ ++static int __devinit shuttle_wmi_probe(struct platform_device *pdev) ++{ ++ struct shuttle_wmi *priv; ++ int rc, i; ++ acpi_status status; ++ u32 val; ++ ++ priv = kzalloc(sizeof(struct shuttle_wmi), GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ priv->pdev = pdev; ++ platform_set_drvdata(pdev, priv); ++ ++ for (i = 0; i < ARRAY_SIZE(shuttle_ids); i++) { ++ rc = wmi_ec_cmd(shuttle_ids[i].cmd_id, 0, 0, 0, &val); ++ if (!rc && val == 1) { ++ priv->id = &shuttle_ids[i]; ++ break; ++ } ++ } ++ /* If we can't identify the system using a WMI command, try using a DMI ++ * match, otherwise set id to unknown model */ ++ if (i == ARRAY_SIZE(shuttle_ids)) { ++ if (dmi_check_system(shuttle_dmi_ids)) ++ priv->id = &shuttle_dmi_id; ++ else ++ priv->id = &id_unknown; ++ } ++ ++ /* Process backlight quirks for some models based on DA18IM */ ++ if (priv->id->cmd_id == CMD_DA18IM) { ++ if (dmi_check_system(shuttle_quirk_bl_dmi_ids)) ++ priv->id->bl_desc = &quirk_bl_desc; ++ } ++ ++ priv->dbg_root = debugfs_create_dir(KBUILD_MODNAME, NULL); ++ if (!priv->dbg_root) { ++ rc = -ENOMEM; ++ goto err_debugfs; ++ } ++ ++ rc = shuttle_fn_init(priv); ++ if (rc) ++ goto err_fn; ++ ++ rc = shuttle_wmi_input_init(priv); ++ if (rc) ++ goto err_input; ++ ++ status = wmi_install_notify_handler(SHUTTLE_WMI_EVENT_GUID, ++ shuttle_wmi_notify, priv); ++ if (ACPI_FAILURE(status)) { ++ rc = -EIO; ++ goto err_notify; ++ } ++ ++ if (!acpi_video_backlight_support()) { ++ rc = shuttle_wmi_backlight_init(priv); ++ if (rc) ++ goto err_backlight; ++ } ++ return 0; ++ ++err_backlight: ++ wmi_remove_notify_handler(SHUTTLE_WMI_EVENT_GUID); ++err_notify: ++ shuttle_wmi_input_remove(priv); ++err_input: ++ shuttle_fn_exit(priv); ++err_fn: ++ debugfs_remove(priv->dbg_root); ++err_debugfs: ++ kfree(priv); ++ return rc; ++} ++ ++static int __devexit shuttle_wmi_remove(struct platform_device *pdev) ++{ ++ struct shuttle_wmi *priv = platform_get_drvdata(pdev); ++ ++ shuttle_wmi_backlight_exit(priv); ++ wmi_remove_notify_handler(SHUTTLE_WMI_EVENT_GUID); ++ shuttle_wmi_input_remove(priv); ++ shuttle_fn_exit(priv); ++ debugfs_remove(priv->dbg_root); ++ kfree(priv); ++ return 0; ++} ++ ++static int shuttle_wmi_resume(struct device *dev) ++{ ++ return shuttle_rfkill_resume(dev); ++} ++ ++static const struct dev_pm_ops shuttle_wmi_pm_ops = { ++ .restore = shuttle_wmi_resume, ++ .resume = shuttle_wmi_resume, ++}; ++ ++static struct platform_driver shuttle_wmi_driver = { ++ .driver = { ++ .name = KBUILD_MODNAME, ++ .owner = THIS_MODULE, ++ .pm = &shuttle_wmi_pm_ops, ++ }, ++ .probe = shuttle_wmi_probe, ++ .remove = __devexit_p(shuttle_wmi_remove), ++}; ++ ++static struct platform_device *shuttle_wmi_device; ++ ++static ssize_t show_model_name(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct shuttle_wmi *priv = platform_get_drvdata(pdev); ++ ++ return sprintf(buf, "%s\n", priv->id->model_name); ++} ++ ++static DEVICE_ATTR(model_name, 0444, show_model_name, NULL); ++ ++static struct attribute *shuttle_platform_attributes[] = { ++ &dev_attr_model_name.attr, ++ NULL ++}; ++ ++static struct attribute_group shuttle_attribute_group = { ++ .attrs = shuttle_platform_attributes ++}; ++ ++static int __init shuttle_wmi_init(void) ++{ ++ int rc; ++ u32 val; ++ ++ if (!wmi_has_guid(SHUTTLE_WMI_SETGET_GUID) || ++ !wmi_has_guid(SHUTTLE_WMI_EVENT_GUID)) { ++ pr_err("Required WMI GUID not available\n"); ++ return -ENODEV; ++ } ++ ++ /* Check that we are really on a shuttle BIOS */ ++ rc = wmi_ec_cmd(CMD_INT15, 0, 0, 0, &val); ++ if (rc || val != 0x534c) { ++ pr_err("Shuttle WMI device not found or unsupported" ++ " (val=0x%08x)\n", val); ++ return -ENODEV; ++ } ++ ++ rc = platform_driver_register(&shuttle_wmi_driver); ++ if (rc) ++ goto err_driver_register; ++ shuttle_wmi_device = platform_device_alloc(KBUILD_MODNAME, -1); ++ if (!shuttle_wmi_device) { ++ rc = -ENOMEM; ++ goto err_device_alloc; ++ } ++ rc = platform_device_add(shuttle_wmi_device); ++ if (rc) ++ goto err_device_add; ++ ++ rc = sysfs_create_group(&shuttle_wmi_device->dev.kobj, ++ &shuttle_attribute_group); ++ if (rc) ++ goto err_sysfs; ++ ++ return 0; ++ ++err_sysfs: ++ platform_device_del(shuttle_wmi_device); ++err_device_add: ++ platform_device_put(shuttle_wmi_device); ++err_device_alloc: ++ platform_driver_unregister(&shuttle_wmi_driver); ++err_driver_register: ++ return rc; ++} ++ ++static void __exit shuttle_wmi_exit(void) ++{ ++ sysfs_remove_group(&shuttle_wmi_device->dev.kobj, ++ &shuttle_attribute_group); ++ platform_device_unregister(shuttle_wmi_device); ++ platform_driver_unregister(&shuttle_wmi_driver); ++} ++ ++module_init(shuttle_wmi_init); ++module_exit(shuttle_wmi_exit); +diff -Nurp linux-3.14.2/MAINTAINERS linux-3.14.2-shuttle/MAINTAINERS +--- linux-3.14.2/MAINTAINERS 2014-03-31 06:40:15.000000000 +0300 ++++ linux-3.14.2-shuttle/MAINTAINERS 2014-04-26 18:33:26.869761100 +0300 +@@ -7880,6 +7880,12 @@ S: Odd Fixes + F: drivers/media/platform/sh_vou.c + F: include/media/sh_vou.h + ++SHUTTLE WMI EXTRAS DRIVER ++M: Herton Ronaldo Krzesinski ++L: platform-driver-x86@vger.kernel.org ++S: Maintained ++F: drivers/platform/x86/shuttle-wmi.c ++ + SIMPLE FIRMWARE INTERFACE (SFI) + M: Len Brown + L: sfi-devel@simplefirmware.org diff --git a/kernel/kernel/files/patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch b/kernel/kernel/files/patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch new file mode 100644 index 00000000..17128641 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch @@ -0,0 +1,38 @@ +--- ./drivers/platform/x86/shuttle-wmi.c.orig 2013-01-16 18:13:57.000000000 +0200 ++++ ./drivers/platform/x86/shuttle-wmi.c 2013-01-16 18:41:13.676433242 +0200 +@@ -294,7 +294,7 @@ static struct dmi_system_id shuttle_dmi_ + {} + }; + +-static struct dmi_system_id __devinitdata shuttle_quirk_bl_dmi_ids[] = { ++static struct dmi_system_id shuttle_quirk_bl_dmi_ids[] = { + { + .ident = "Positivo M13", + .matches = { +@@ -1105,7 +1105,7 @@ fn_init_err: + return rc; + } + +-static int __devinit shuttle_wmi_probe(struct platform_device *pdev) ++static int shuttle_wmi_probe(struct platform_device *pdev) + { + struct shuttle_wmi *priv; + int rc, i; +@@ -1181,7 +1181,7 @@ err_debugfs: + return rc; + } + +-static int __devexit shuttle_wmi_remove(struct platform_device *pdev) ++static int shuttle_wmi_remove(struct platform_device *pdev) + { + struct shuttle_wmi *priv = platform_get_drvdata(pdev); + +@@ -1211,7 +1211,7 @@ static struct platform_driver shuttle_wm + .pm = &shuttle_wmi_pm_ops, + }, + .probe = shuttle_wmi_probe, +- .remove = __devexit_p(shuttle_wmi_remove), ++ .remove = shuttle_wmi_remove, + }; + + static struct platform_device *shuttle_wmi_device; diff --git a/kernel/kernel/files/patches/mageia/pnp-isapnp-async-init.patch b/kernel/kernel/files/patches/mageia/pnp-isapnp-async-init.patch new file mode 100644 index 00000000..ccd356f4 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/pnp-isapnp-async-init.patch @@ -0,0 +1,54 @@ +From: Andy Whitcroft +Date: Wed, 2 Dec 2009 14:41:53 +0000 (+0000) +Subject: UBUNTU: SAUCE: isapnp_init: make isa PNP scans occur async +X-Git-Tag: Ubuntu-2.6.32-8.12~27 +X-Git-Url: http://kernel.ubuntu.com/git?p=ubuntu%2Fubuntu-lucid.git;a=commitdiff_plain;h=da0e50d81022edb2bbef538fd7adf90381f8eb01 + +UBUNTU: SAUCE: isapnp_init: make isa PNP scans occur async + +The results of scanning for devices is to trigger udev events therefore +we can push this processing async. + +This reduces kernel initialisation time (the time from bootloader to +starting userspace) by several 10ths of a second x86 32bit systems. + +Signed-off-by: Andy Whitcroft +--- + +diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c +index e851160..7e4c8cd 100644 +--- a/drivers/pnp/isapnp/core.c ++++ b/drivers/pnp/isapnp/core.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + #include + + #include "../base.h" +@@ -1002,7 +1003,7 @@ struct pnp_protocol isapnp_protocol = { + .disable = isapnp_disable_resources, + }; + +-static int __init isapnp_init(void) ++static int __init real_isapnp_init(void) + { + int cards; + struct pnp_card *card; +@@ -1096,6 +1097,15 @@ static int __init isapnp_init(void) + return 0; + } + ++static void __init async_isapnp_init(void *unused, async_cookie_t cookie) ++{ ++ (void)real_isapnp_init(); ++} ++ ++static int __init isapnp_init(void) ++{ ++ async_schedule(async_isapnp_init, NULL); ++} + device_initcall(isapnp_init); + + /* format is: noisapnp */ diff --git a/kernel/kernel/files/patches/mageia/pnp-pnpbios-off-by-default.patch b/kernel/kernel/files/patches/mageia/pnp-pnpbios-off-by-default.patch new file mode 100644 index 00000000..b859c2a7 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/pnp-pnpbios-off-by-default.patch @@ -0,0 +1,15 @@ +-- + drivers/pnp/pnpbios/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pnp/pnpbios/core.c ++++ b/drivers/pnp/pnpbios/core.c +@@ -403,7 +403,7 @@ static void __init build_devlist(void) + * + */ + +-static int pnpbios_disabled; ++static int pnpbios_disabled = 1; + int pnpbios_dont_use_current_config; + + static int __init pnpbios_setup(char *str) diff --git a/kernel/kernel/files/patches/mageia/rcu-Fix-rcu_barrier-race-that-could-result-in-too-sh.patch b/kernel/kernel/files/patches/mageia/rcu-Fix-rcu_barrier-race-that-could-result-in-too-sh.patch new file mode 100644 index 00000000..ca1db7e5 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/rcu-Fix-rcu_barrier-race-that-could-result-in-too-sh.patch @@ -0,0 +1,206 @@ +From 41050a009640f9f330a5b916563ca7faf853a98c Mon Sep 17 00:00:00 2001 +From: "Paul E. McKenney" +Date: Thu, 18 Dec 2014 12:31:02 -0800 +Subject: [PATCH] rcu: Fix rcu_barrier() race that could result in too-short + wait + +The rcu_barrier() no-callbacks check for no-CBs CPUs has race conditions. +It checks a given CPU's lists of callbacks, and if all three no-CBs lists +are empty, ignores that CPU. However, these three lists could potentially +be empty even when callbacks are present if the check executed just as +the callbacks were being moved from one list to another. It turns out +that recent versions of rcutorture can spot this race. + +This commit plugs this hole by consolidating the per-list counts of +no-CBs callbacks into a single count, which is incremented before +the corresponding callback is posted and after it is invoked. Then +rcu_barrier() checks this single count to reliably determine whether +the corresponding CPU has no-CBs callbacks. + +Signed-off-by: Paul E. McKenney +--- + kernel/rcu/tree.c | 1 + + kernel/rcu/tree.h | 29 +++++++---------------------- + kernel/rcu/tree_plugin.h | 45 ++++++++++++++++++++++++++++----------------- + 3 files changed, 36 insertions(+), 39 deletions(-) + +diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c +index 203b50d..5b9f3b9 100644 +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -3344,6 +3344,7 @@ static void _rcu_barrier(struct rcu_state *rsp) + } else { + _rcu_barrier_trace(rsp, "OnlineNoCB", cpu, + rsp->n_barrier_done); ++ smp_mb__before_atomic(); + atomic_inc(&rsp->barrier_cpu_count); + __call_rcu(&rdp->barrier_head, + rcu_barrier_callback, rsp, cpu, 0); +diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h +index 8e7b184..cb59086 100644 +--- a/kernel/rcu/tree.h ++++ b/kernel/rcu/tree.h +@@ -340,14 +340,10 @@ struct rcu_data { + #ifdef CONFIG_RCU_NOCB_CPU + struct rcu_head *nocb_head; /* CBs waiting for kthread. */ + struct rcu_head **nocb_tail; +- atomic_long_t nocb_q_count; /* # CBs waiting for kthread */ +- atomic_long_t nocb_q_count_lazy; /* (approximate). */ ++ atomic_long_t nocb_q_count; /* # CBs waiting for nocb */ ++ atomic_long_t nocb_q_count_lazy; /* invocation (all stages). */ + struct rcu_head *nocb_follower_head; /* CBs ready to invoke. */ + struct rcu_head **nocb_follower_tail; +- atomic_long_t nocb_follower_count; /* # CBs ready to invoke. */ +- atomic_long_t nocb_follower_count_lazy; /* (approximate). */ +- int nocb_p_count; /* # CBs being invoked by kthread */ +- int nocb_p_count_lazy; /* (approximate). */ + wait_queue_head_t nocb_wq; /* For nocb kthreads to sleep on. */ + struct task_struct *nocb_kthread; + int nocb_defer_wakeup; /* Defer wakeup of nocb_kthread. */ +@@ -356,8 +352,6 @@ struct rcu_data { + struct rcu_head *nocb_gp_head ____cacheline_internodealigned_in_smp; + /* CBs waiting for GP. */ + struct rcu_head **nocb_gp_tail; +- long nocb_gp_count; +- long nocb_gp_count_lazy; + bool nocb_leader_sleep; /* Is the nocb leader thread asleep? */ + struct rcu_data *nocb_next_follower; + /* Next follower in wakeup chain. */ +@@ -622,24 +616,15 @@ static void rcu_dynticks_task_exit(void); + #endif /* #ifndef RCU_TREE_NONCORE */ + + #ifdef CONFIG_RCU_TRACE +-#ifdef CONFIG_RCU_NOCB_CPU +-/* Sum up queue lengths for tracing. */ ++/* Read out queue lengths for tracing. */ + static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll) + { +- *ql = atomic_long_read(&rdp->nocb_q_count) + +- rdp->nocb_p_count + +- atomic_long_read(&rdp->nocb_follower_count) + +- rdp->nocb_p_count + rdp->nocb_gp_count; +- *qll = atomic_long_read(&rdp->nocb_q_count_lazy) + +- rdp->nocb_p_count_lazy + +- atomic_long_read(&rdp->nocb_follower_count_lazy) + +- rdp->nocb_p_count_lazy + rdp->nocb_gp_count_lazy; +-} ++#ifdef CONFIG_RCU_NOCB_CPU ++ *ql = atomic_long_read(&rdp->nocb_q_count); ++ *qll = atomic_long_read(&rdp->nocb_q_count_lazy); + #else /* #ifdef CONFIG_RCU_NOCB_CPU */ +-static inline void rcu_nocb_q_lengths(struct rcu_data *rdp, long *ql, long *qll) +-{ + *ql = 0; + *qll = 0; +-} + #endif /* #else #ifdef CONFIG_RCU_NOCB_CPU */ ++} + #endif /* #ifdef CONFIG_RCU_TRACE */ +diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h +index 3ec85cb..e5c43b7 100644 +--- a/kernel/rcu/tree_plugin.h ++++ b/kernel/rcu/tree_plugin.h +@@ -2056,9 +2056,26 @@ static void wake_nocb_leader(struct rcu_data *rdp, bool force) + static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu) + { + struct rcu_data *rdp = per_cpu_ptr(rsp->rda, cpu); ++ unsigned long ret; ++#ifdef CONFIG_PROVE_RCU + struct rcu_head *rhp; ++#endif /* #ifdef CONFIG_PROVE_RCU */ ++ ++ /* ++ * Check count of all no-CBs callbacks awaiting invocation. ++ * There needs to be a barrier before this function is called, ++ * but associated with a prior determination that no more ++ * callbacks would be posted. In the worst case, the first ++ * barrier in _rcu_barrier() suffices (but the caller cannot ++ * necessarily rely on this, not a substitute for the caller ++ * getting the concurrency design right!). There must also be ++ * a barrier between the following load an posting of a callback ++ * (if a callback is in fact needed). This is associated with an ++ * atomic_inc() in the caller. ++ */ ++ ret = atomic_long_read(&rdp->nocb_q_count); + +- /* No-CBs CPUs might have callbacks on any of three lists. */ ++#ifdef CONFIG_PROVE_RCU + rhp = ACCESS_ONCE(rdp->nocb_head); + if (!rhp) + rhp = ACCESS_ONCE(rdp->nocb_gp_head); +@@ -2072,8 +2089,9 @@ static bool rcu_nocb_cpu_needs_barrier(struct rcu_state *rsp, int cpu) + cpu, rhp->func); + WARN_ON_ONCE(1); + } ++#endif /* #ifdef CONFIG_PROVE_RCU */ + +- return !!rhp; ++ return !!ret; + } + + /* +@@ -2095,9 +2113,10 @@ static void __call_rcu_nocb_enqueue(struct rcu_data *rdp, + struct task_struct *t; + + /* Enqueue the callback on the nocb list and update counts. */ ++ atomic_long_add(rhcount, &rdp->nocb_q_count); ++ /* rcu_barrier() relies on ->nocb_q_count add before xchg. */ + old_rhpp = xchg(&rdp->nocb_tail, rhtp); + ACCESS_ONCE(*old_rhpp) = rhp; +- atomic_long_add(rhcount, &rdp->nocb_q_count); + atomic_long_add(rhcount_lazy, &rdp->nocb_q_count_lazy); + smp_mb__after_atomic(); /* Store *old_rhpp before _wake test. */ + +@@ -2288,9 +2307,6 @@ wait_again: + /* Move callbacks to wait-for-GP list, which is empty. */ + ACCESS_ONCE(rdp->nocb_head) = NULL; + rdp->nocb_gp_tail = xchg(&rdp->nocb_tail, &rdp->nocb_head); +- rdp->nocb_gp_count = atomic_long_xchg(&rdp->nocb_q_count, 0); +- rdp->nocb_gp_count_lazy = +- atomic_long_xchg(&rdp->nocb_q_count_lazy, 0); + gotcbs = true; + } + +@@ -2338,9 +2354,6 @@ wait_again: + /* Append callbacks to follower's "done" list. */ + tail = xchg(&rdp->nocb_follower_tail, rdp->nocb_gp_tail); + *tail = rdp->nocb_gp_head; +- atomic_long_add(rdp->nocb_gp_count, &rdp->nocb_follower_count); +- atomic_long_add(rdp->nocb_gp_count_lazy, +- &rdp->nocb_follower_count_lazy); + smp_mb__after_atomic(); /* Store *tail before wakeup. */ + if (rdp != my_rdp && tail == &rdp->nocb_follower_head) { + /* +@@ -2415,13 +2428,11 @@ static int rcu_nocb_kthread(void *arg) + trace_rcu_nocb_wake(rdp->rsp->name, rdp->cpu, "WokeNonEmpty"); + ACCESS_ONCE(rdp->nocb_follower_head) = NULL; + tail = xchg(&rdp->nocb_follower_tail, &rdp->nocb_follower_head); +- c = atomic_long_xchg(&rdp->nocb_follower_count, 0); +- cl = atomic_long_xchg(&rdp->nocb_follower_count_lazy, 0); +- rdp->nocb_p_count += c; +- rdp->nocb_p_count_lazy += cl; + + /* Each pass through the following loop invokes a callback. */ +- trace_rcu_batch_start(rdp->rsp->name, cl, c, -1); ++ trace_rcu_batch_start(rdp->rsp->name, ++ atomic_long_read(&rdp->nocb_q_count_lazy), ++ atomic_long_read(&rdp->nocb_q_count), -1); + c = cl = 0; + while (list) { + next = list->next; +@@ -2443,9 +2454,9 @@ static int rcu_nocb_kthread(void *arg) + list = next; + } + trace_rcu_batch_end(rdp->rsp->name, c, !!list, 0, 0, 1); +- ACCESS_ONCE(rdp->nocb_p_count) = rdp->nocb_p_count - c; +- ACCESS_ONCE(rdp->nocb_p_count_lazy) = +- rdp->nocb_p_count_lazy - cl; ++ smp_mb__before_atomic(); /* _add after CB invocation. */ ++ atomic_long_add(-c, &rdp->nocb_q_count); ++ atomic_long_add(-cl, &rdp->nocb_q_count_lazy); + rdp->n_nocbs_invoked += c; + } + return 0; +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/scsi-add-1024-max-sectors-black-list-flag.patch b/kernel/kernel/files/patches/mageia/scsi-add-1024-max-sectors-black-list-flag.patch new file mode 100644 index 00000000..091f152f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/scsi-add-1024-max-sectors-black-list-flag.patch @@ -0,0 +1,94 @@ +From 35e9a9f93994d7f7d12afa41169c7ba05513721b Mon Sep 17 00:00:00 2001 +From: Mike Christie +Date: Mon, 20 Apr 2015 22:42:24 -0500 +Subject: SCSI: add 1024 max sectors black list flag + +From: Mike Christie + +commit 35e9a9f93994d7f7d12afa41169c7ba05513721b upstream. + +This works around a issue with qnap iscsi targets not handling large IOs +very well. + +The target returns: + +VPD INQUIRY: Block limits page (SBC) + Maximum compare and write length: 1 blocks + Optimal transfer length granularity: 1 blocks + Maximum transfer length: 4294967295 blocks + Optimal transfer length: 4294967295 blocks + Maximum prefetch, xdread, xdwrite transfer length: 0 blocks + Maximum unmap LBA count: 8388607 + Maximum unmap block descriptor count: 1 + Optimal unmap granularity: 16383 + Unmap granularity alignment valid: 0 + Unmap granularity alignment: 0 + Maximum write same length: 0xffffffff blocks + Maximum atomic transfer length: 0 + Atomic alignment: 0 + Atomic transfer length granularity: 0 + +and it is *sometimes* able to handle at least one IO of size up to 8 MB. We +have seen in traces where it will sometimes work, but other times it +looks like it fails and it looks like it returns failures if we send +multiple large IOs sometimes. Also it looks like it can return 2 different +errors. It will sometimes send iscsi reject errors indicating out of +resources or it will send invalid cdb illegal requests check conditions. +And then when it sends iscsi rejects it does not seem to handle retries +when there are command sequence holes, so I could not just add code to +try and gracefully handle that error code. + +The problem is that we do not have a good contact for the company, +so we are not able to determine under what conditions it returns +which error and why it sometimes works. + +So, this patch just adds a new black list flag to set targets like this to +the old max safe sectors of 1024. The max_hw_sectors changes added in 3.19 +caused this regression, so I also ccing stable. + +Reported-by: Christian Hesse +Signed-off-by: Mike Christie +Reviewed-by: Christoph Hellwig +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/scsi_devinfo.c | 1 + + drivers/scsi/scsi_scan.c | 6 ++++++ + include/scsi/scsi_devinfo.h | 1 + + 3 files changed, 8 insertions(+) + +--- a/drivers/scsi/scsi_devinfo.c ++++ b/drivers/scsi/scsi_devinfo.c +@@ -226,6 +226,7 @@ static struct { + {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, + {"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC}, + {"Promise", "", NULL, BLIST_SPARSELUN}, ++ {"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024}, + {"QUANTUM", "XP34301", "1071", BLIST_NOTQ}, + {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, + {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, +--- a/drivers/scsi/scsi_scan.c ++++ b/drivers/scsi/scsi_scan.c +@@ -897,6 +897,12 @@ static int scsi_add_lun(struct scsi_devi + */ + if (*bflags & BLIST_MAX_512) + blk_queue_max_hw_sectors(sdev->request_queue, 512); ++ /* ++ * Max 1024 sector transfer length for targets that report incorrect ++ * max/optimal lengths and relied on the old block layer safe default ++ */ ++ else if (*bflags & BLIST_MAX_1024) ++ blk_queue_max_hw_sectors(sdev->request_queue, 1024); + + /* + * Some devices may not want to have a start command automatically +--- a/include/scsi/scsi_devinfo.h ++++ b/include/scsi/scsi_devinfo.h +@@ -36,5 +36,6 @@ + for sequential scan */ + #define BLIST_TRY_VPD_PAGES 0x10000000 /* Attempt to read VPD pages */ + #define BLIST_NO_RSOC 0x20000000 /* don't try to issue RSOC */ ++#define BLIST_MAX_1024 0x40000000 /* maximum 1024 sector cdb length */ + + #endif diff --git a/kernel/kernel/files/patches/mageia/scsi-megaraid-new-sysfs-name.patch b/kernel/kernel/files/patches/mageia/scsi-megaraid-new-sysfs-name.patch new file mode 100644 index 00000000..c750150f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/scsi-megaraid-new-sysfs-name.patch @@ -0,0 +1,15 @@ +--- + drivers/scsi/megaraid/megaraid_mbox.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-3.8-rc3-mga0.1/drivers/scsi/megaraid/megaraid_mbox.c.scsi-megaraid-new-sysfs-name.orig 2013-01-10 08:17:11.000000000 +0200 ++++ linux-3.8-rc3-mga0.1/drivers/scsi/megaraid/megaraid_mbox.c 2013-01-10 08:30:19.908301909 +0200 +@@ -302,7 +302,7 @@ MODULE_DEVICE_TABLE(pci, pci_id_table_g) + + + static struct pci_driver megaraid_pci_driver = { +- .name = "megaraid", ++ .name = "megaraid_mbox", + .id_table = pci_id_table_g, + .probe = megaraid_probe_one, + .remove = megaraid_detach_one, diff --git a/kernel/kernel/files/patches/mageia/scsi-ppscsi-2.6.2.patch b/kernel/kernel/files/patches/mageia/scsi-ppscsi-2.6.2.patch new file mode 100644 index 00000000..bf7be4ba --- /dev/null +++ b/kernel/kernel/files/patches/mageia/scsi-ppscsi-2.6.2.patch @@ -0,0 +1,5083 @@ +--- + drivers/scsi/Kconfig | 36 + + drivers/scsi/Makefile | 10 + drivers/scsi/epsa2.c | 507 +++++++++++++++++++ + drivers/scsi/epst.c | 478 ++++++++++++++++++ + drivers/scsi/onscsi.c | 544 ++++++++++++++++++++ + drivers/scsi/ppscsi.c | 1294 +++++++++++++++++++++++++++++++++++++++++++++++++ + drivers/scsi/ppscsi.h | 356 +++++++++++++ + drivers/scsi/sparcsi.c | 389 ++++++++++++++ + drivers/scsi/t348.c | 318 ++++++++++++ + drivers/scsi/t358.c | 394 ++++++++++++++ + drivers/scsi/vpi0.c | 276 ++++++++++ + drivers/scsi/vpi2.c | 418 +++++++++++++++ + 12 files changed, 5020 insertions(+) + +--- /dev/null ++++ b/drivers/scsi/vpi2.c +@@ -0,0 +1,418 @@ ++/* ++ vpi2.c (c) 1995-1999 Grant Guenther ++ (c) 1997-1999 David Campbell ++ (c) 2000 Tim Waugh ++ ++ This is the ppSCSI protocol module for the Iomega VPI2 adapter ++ found in the newer ZIP-100 drives. ++ ++*/ ++ ++#error "This doesn't work yet." ++ ++#define VPI2_VERSION "0.91" ++ ++#define PPSC_BASE ++#define PPSC_HA_MODULE ++ ++#include "ppscsi.h" ++ ++static char vpi2_map[256]; /* status bits permutation */ ++ ++static void vpi2_init (PHA *pha) ++{ ++ ++/* *** No MSG line on the VPI2 ! *** */ /* tmw: is this true for VPI2? */ ++ ++/* { REQ, BSY, MSG, CD, IO} */ ++ ++ char key[5] = {0x80,0x40,0x00,0x20,0x10}; ++ ++ ppsc_make_map(vpi2_map,key,0); ++ sprintf(pha->ident,"vpi2 %s (%s) ",VPI2_VERSION,PPSC_H_VERSION); ++} ++ ++#define j44(a,b) ((a&0xf0)|((b>>4)&0x0f)) ++ ++#define CST(v) w2(0xc);w0(v);w2(4);w2(6);w2(4);w2(0xc); ++#define DST(v) w2(0xc);w0(v);w2(0xc);w2(0xe);w2(0xc);w2(4);w2(0xc); ++ ++static inline int imm_cpp (PHA *pha, unsigned char b) ++{ ++ unsigned char s1, s2, s3; ++ ++ w2(0xc); ++ udelay(2); /* 1 usec - infinite */ ++ w0(0xaa); ++ udelay(10); /* 7 usec - infinite */ ++ w0(0x55); ++ udelay(10); /* 7 usec - infinite */ ++ w0(0x00); ++ udelay(10); /* 7 usec - infinite */ ++ w0(0xff); ++ udelay(10); /* 7 usec - infinite */ ++ s1 = r1() & 0xb8; ++ w0(0x87); ++ udelay(10); /* 7 usec - infinite */ ++ s2 = r1() & 0xb8; ++ w0(0x78); ++ udelay(10); ++ s3 = r1() & 0x38; ++ /* ++ * Values for b are: ++ * 0000 00aa Assign address aa to current device ++ * 0010 00aa Select device aa in EPP Winbond mode ++ * 0010 10aa Select device aa in EPP mode ++ * 0011 xxxx Deselect all devices ++ * 0110 00aa Test device aa ++ * 1101 00aa Select device aa in ECP mode ++ * 1110 00aa Select device aa in Compatible mode ++ */ ++ w0(b); ++ udelay(2); /* 1 usec - infinite */ ++ w2(0x0c); ++ udelay(10); /* 7 usec - infinite */ ++ w2(0x0d); ++ udelay(2); /* 1 usec - infinite */ ++ w2(0x0c); ++ udelay(10); /* 7 usec - infinite */ ++ w0(0xff); ++ udelay(10); /* 7 usec - infinite */ ++ ++ /* ++ * The following table is electrical pin values. ++ * (BSY is inverted at the CTR register) ++ * ++ * BSY ACK POut SEL Fault ++ * S1 0 X 1 1 1 ++ * S2 1 X 0 1 1 ++ * S3 L X 1 1 S ++ * ++ * L => Last device in chain ++ * S => Selected ++ * ++ * Observered values for S1,S2,S3 are: ++ * Disconnect => f8/58/78 ++ * Connect => f8/58/70 ++ */ ++ if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x30)) ++ return 1; /* Connected */ ++ if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x38)) ++ return 0; /* Disconnected */ ++ ++ return -1; /* No device present */ ++} ++ ++static inline int do_vpi2_connect (PHA *pha) ++{ ++ pha->saved_r0 = r0(); ++ pha->saved_r2 = r2(); ++ ++ imm_cpp(pha, 0xe0); /* Select device 0 in compatible mode */ ++ imm_cpp(pha, 0x30); /* Disconnect all devices */ ++ ++ if (pha->mode >= 2) ++ /* Select device 0 in EPP mode */ ++ return imm_cpp (pha, 0x28); ++ ++ /* Select device 0 in compatible mode */ ++ return imm_cpp (pha, 0xe0); ++} ++ ++static void vpi2_connect (PHA *pha) ++{ ++ printk ("--> vpi2_connect\n"); ++ do_vpi2_connect (pha); ++ printk ("<--\n"); ++} ++ ++static void vpi2_disconnect (PHA *pha) ++{ ++ printk ("--> vpi2_disconnect\n"); ++ imm_cpp (pha, 0x30); /* Disconnect all devices */ ++ ++ w2(pha->saved_r2); ++ w0(pha->saved_r0); ++ printk ("<--\n"); ++} ++ ++ ++/* There are no data-transfer tests available, just this simple ++ check that we are talking to a VPI2. */ ++static int vpi2_test_proto (PHA *pha) ++{ ++ int e = 1; ++ ++ printk ("--> vpi2_test_proto\n"); ++ if (do_vpi2_connect(pha) == 1) ++ e--; ++ ++ vpi2_disconnect (pha); ++ printk ("<-- %d\n", e); ++ return e; ++} ++ ++static int vpi2_select (PHA *pha, int initiator, int target) ++{ ++ printk ("--> vpi2_select\n"); ++ w2(0xc); ++ if (r1() & 0x08) { ++ printk ("<-- -1 (busy)\n"); ++ return -1; /* bus busy */ ++ } ++ ++ /* ++ * Now assert the SCSI ID (HOST and TARGET) on the data bus ++ */ ++ w2(0x4); ++ w0(0x80 | (1 << target)); ++ udelay (1); ++ ++ /* ++ * Deassert SELIN first followed by STROBE ++ */ ++ w2(0xc); ++ w2(0xd); ++ ++ printk ("<-- 0\n"); ++ return 0; ++ ++} ++ ++static int vpi2_test_select (PHA *pha) ++{ ++ int val = r1() & 0x08; ++ printk ("--> vpi2_test_select\n<-- %d\n", val); ++ return val; /* BSY asserted ? */ ++} ++ ++static void vpi2_select_finish (PHA *pha) ++{ ++ printk ("--> vpi2_select_finish\n<--\n"); ++ w2(0xc); ++} ++ ++static void vpi2_deselect (PHA *pha) ++{ ++ printk ("--> vpi2_deselect\n<--\n"); ++ w2(0xc); ++} ++ ++static int vpi2_get_bus_status (PHA *pha) ++{ ++ int val; ++ printk ("--> vpi2_get_bus_status\n"); ++ w2(0xc); ++ val = vpi2_map[r1()]; ++ printk ("<-- %d\n", val); ++ return val; ++} ++ ++/* These functions are inlined so the C optimiser can move the switches ++ outside of loops where possible, am I dreaming ? */ ++ ++static inline int vpi2_read (PHA *pha, int first) ++{ ++ int l, h; ++ ++ printk ("--> vpi2_read\n<--\n"); ++ ++ switch (pha->mode) { ++ ++ case 0: if (first) w2(4); ++ w2(0x6); h = r1(); ++ w2(0x5); l = r1(); w2(4); ++ return j44(h,l); ++ ++ case 1: if (first) w2(0x25); ++ w2(0x26); ++ l = r0(); ++ w2(0x25); ++ return l; ++ ++ case 2: if (first) w2(0x24); ++ return r4(); ++ ++ default: return -1; ++ ++ } ++} ++ ++static inline void vpi2_write (PHA *pha, int v, int first ) ++{ ++ static int alternate; ++ ++ printk ("--> vpi2_write\n"); ++ ++ switch (pha->mode) { ++ ++ case 0: ++ case 1: ++ if (first) { ++ w2(0xc); ++ alternate = 0; ++ } ++ w0(v); ++ if (alternate) ++ w2(0x0); ++ else ++ w2(0x5); ++ alternate = 1 - alternate; ++ break; ++ ++ case 2: if (first) w2(0x4); ++ w4(v); ++ break; ++ ++ } ++ printk ("<--\n"); ++} ++ ++static void vpi2_slow_start (PHA *pha, char *val) ++{ ++ int r; ++ ++ printk ("--> vpi2_slow_start\n"); ++ ++ w2(0xc); ++ ++ r = (r1() & 0x10); ++ ++ if (r) *val = vpi2_read(pha,1); ++ else vpi2_write(pha,*val,1); ++ ++ printk ("<--\n"); ++} ++ ++static int vpi2_slow_done (PHA *pha) ++{ ++ printk ("--> vpi2_slow_done\n<--\n"); ++ return 1; /* vpi2 does its own REQ/ACK handshaking */ ++} ++ ++static void vpi2_slow_end (PHA *pha) ++{ ++ printk ("--> vpi2_slow_end\n<--\n"); ++ w2(0xc); ++} ++ ++static void vpi2_start_block (PHA *pha, int rd) ++{ ++ printk ("--> vpi2_start_block\n<--\n"); ++ pha->priv_flag = rd; ++} ++ ++static int vpi2_transfer_ready (PHA *pha) ++{ ++ int b; ++ ++ printk ("--> vpi2_transfer_ready\n<--\n"); ++ b = vpi2_get_bus_status(pha); ++ if ((b & PPSC_PH_STAT) == PPSC_PH_STAT) return -1; ++ if (b == (PPSC_REQ|PPSC_BSY| pha->priv_flag)) return 128; ++ return 0; ++} ++ ++static int vpi2_transfer_block (PHA *pha, char * buf, int buflen, int rd) ++{ ++ int k, n, i; ++ ++ printk ("--> vpi2_transfer_block\n"); ++ k = 0; ++ while (k < buflen) { ++ n = vpi2_transfer_ready(pha); ++ if (n <= 0 ) break; ++ if (n > (buflen-k)) n = buflen-k; ++ for (i=0;i vpi2_transfer_done\n<-- 1\n"); ++ return 1; ++} ++ ++static void vpi2_end_block (PHA *pha, int rd) ++{ ++ printk ("--> vpi2_end_block\n<--\n"); ++ w2(0xc); ++} ++ ++static void vpi2_reset_bus (PHA *pha) ++{ ++ printk ("--> vpi2_reset_bus\n<--\n"); ++ w2(0xc); ++ w0(0x40); w2(8); udelay(60); ++ w2(0xc); ++} ++ ++/* Make these correspond to the actual modes supported by the adapter */ ++ ++static char *(mode_strings[3]) = {"Nybble","PS/2","EPP"}; ++ ++static struct ppsc_protocol vpi2_psp = { ++ ++ {&host0,&host1,&host2,&host3}, /* params */ ++ &host_structs, /* hosts */ ++ 3, /* num_modes */ ++ 2, /* epp_first */ ++ 1, /* default_delay */ ++ 0, /* can_message */ ++ 16, /* sg_tablesize */ ++ mode_strings, ++ vpi2_init, ++ NULL, ++ vpi2_connect, ++ vpi2_disconnect, ++ vpi2_test_proto, ++ vpi2_select, ++ vpi2_test_select, ++ vpi2_select_finish, ++ vpi2_deselect, ++ vpi2_get_bus_status, ++ vpi2_slow_start, ++ vpi2_slow_done, ++ vpi2_slow_end, ++ vpi2_start_block, ++ vpi2_transfer_block, ++ vpi2_transfer_ready, ++ vpi2_transfer_done, ++ vpi2_end_block, ++ vpi2_reset_bus ++}; ++ ++int vpi2_detect (struct scsi_host_template *tpnt) ++{ ++ int val; ++ printk ("--> vpi2_detect\n"); ++ val = ppsc_detect( &vpi2_psp, tpnt, verbose); ++ printk ("<-- %d\n", val); ++ return val; ++} ++ ++#ifdef MODULE ++ ++struct scsi_host_template driver_template = PPSC_TEMPLATE(vpi2); ++ ++#include "scsi_module.c" ++ ++MODULE_LICENSE("GPL"); ++ ++#else ++ ++void vpi2_setup (char *str, int *ints) ++{ ++ printk ("--> vpi2_setup\n"); ++ ppsc_gen_setup(stt,4,str); ++ printk ("<--\n"); ++} ++ ++#endif ++ ++/* end of vpi2.c */ +--- /dev/null ++++ b/drivers/scsi/vpi0.c +@@ -0,0 +1,276 @@ ++/* ++ vpi0.c (c) 1995-1999 Grant Guenther ++ (c) 1997-1999 David Campbell ++ ++ This is the ppSCSI protocol module for the Iomega VPI0 adapter ++ found in the original ZIP-100 drives and the Jaz Traveller. ++ ++*/ ++ ++#define VPI0_VERSION "0.91" ++ ++#define PPSC_BASE ++#define PPSC_HA_MODULE ++ ++#include "ppscsi.h" ++ ++static char vpi0_map[256]; /* status bits permutation */ ++ ++static void vpi0_init (PHA *pha) ++{ ++ ++/* *** No MSG line on the VPI0 ! *** */ ++ ++/* { REQ, BSY, MSG, CD, IO} */ ++ ++ char key[5] = {0x80,0x40,0x00,0x20,0x10}; ++ ++ ppsc_make_map(vpi0_map,key,0); ++ sprintf(pha->ident,"vpi0 %s (%s) ",VPI0_VERSION,PPSC_H_VERSION); ++} ++ ++#define j44(a,b) ((a&0xf0)|((b>>4)&0x0f)) ++ ++#define CST(v) w2(0xc);w0(v);w2(4);w2(6);w2(4);w2(0xc); ++#define DST(v) w2(0xc);w0(v);w2(0xc);w2(0xe);w2(0xc);w2(4);w2(0xc); ++ ++static void vpi0_connect (PHA *pha) ++{ ++ pha->saved_r0 = r0(); ++ pha->saved_r2 = r2(); ++ ++ CST(0); CST(0x3c); CST(0x20); ++ if (pha->mode >= 2) { CST(0xcf) } else { CST(0x8f) } ++} ++ ++static void vpi0_disconnect (PHA *pha) ++{ ++ DST(0); DST(0x3c); DST(0x20); DST(0xf); ++ ++ w2(pha->saved_r2); ++ w0(pha->saved_r0); ++} ++ ++ ++/* There are no data-transfer tests available, just this simple ++ check that we are talking to a VPI0. */ ++static int vpi0_test_proto (PHA *pha) ++{ ++ int e = 2; ++ ++ vpi0_connect(pha); ++ w2(0xe); ++ if ((r1() & 8) == 8) e--; ++ w2(0xc); ++ if ((r1() & 8) == 0) e--; ++ vpi0_disconnect(pha); ++ return e; ++} ++ ++static int vpi0_select (PHA *pha, int initiator, int target) ++{ ++ w2(0xc); ++ if (r1() & 0x40) return -1; /* bus busy */ ++ ++ w0(1<mode) { ++ ++ case 0: if (first) w2(4); ++ h = r1(); w2(6); ++ l = r1(); w2(4); ++ return j44(h,l); ++ ++ case 1: if (first) w2(0x25); ++ l = r0(); ++ w2(0x27); w2(0x25); ++ return l; ++ ++ case 2: if (first) w2(0x24); ++ return r4(); ++ ++ default: return -1; ++ ++ } ++} ++ ++static inline void vpi0_write (PHA *pha, int v, int first ) ++{ ++ switch (pha->mode) { ++ ++ case 0: ++ case 1: if (first) w2(0xc); ++ w0(v); w2(0xe); w2(0xc); ++ break; ++ ++ case 2: if (first) w2(0x4); ++ w4(v); ++ break; ++ ++ } ++} ++ ++static void vpi0_slow_start (PHA *pha, char *val) ++{ ++ int r; ++ ++ w2(0xc); ++ ++ r = (r1() & 0x10); ++ ++ if (r) *val = vpi0_read(pha,1); ++ else vpi0_write(pha,*val,1); ++ ++} ++ ++static int vpi0_slow_done (PHA *pha) ++{ ++ return 1; /* vpi0 does its own REQ/ACK handshaking */ ++} ++ ++static void vpi0_slow_end (PHA *pha) ++{ ++ w2(0xc); ++} ++ ++static void vpi0_start_block (PHA *pha, int rd) ++{ ++ pha->priv_flag = rd; ++} ++ ++static int vpi0_transfer_ready (PHA *pha) ++{ ++ int b; ++ ++ b = vpi0_get_bus_status(pha); ++ if ((b & PPSC_PH_STAT) == PPSC_PH_STAT) return -1; ++ if (b == (PPSC_REQ|PPSC_BSY| pha->priv_flag)) return 128; ++ return 0; ++} ++ ++static int vpi0_transfer_block (PHA *pha, char * buf, int buflen, int rd) ++{ ++ int k, n, i; ++ ++ k = 0; ++ while (k < buflen) { ++ n = vpi0_transfer_ready(pha); ++ if (n <= 0 ) break; ++ if (n > (buflen-k)) n = buflen-k; ++ for (i=0;i ++ ++ This is the low-level protocol module for the Adaptec APA-348 ++ (aka Trantor T348) parallel port SCSI adapter. It forms part ++ of the 'ppSCSI' suite of drivers. ++ ++*/ ++ ++#define T348_VERSION "0.92" ++ ++#define PPSC_BASE ++#define PPSC_HA_MODULE ++ ++#include "ppscsi.h" ++ ++#define j44(a,b) (((a<<1)&0xf0)+((b>>3)&0x0f)) ++ ++static char t348_map[256]; /* status bits permutation */ ++ ++static void t348_init (PHA *pha) ++{ ++ ++/* { REQ, BSY, MSG, CD, IO} */ ++ ++ char key[5] = {0x20,0x40,0x10,0x08,0x04}; ++ ++ ppsc_make_map(t348_map,key,0); ++ sprintf(pha->ident,"t348 %s (%s), Adaptec APA-348", ++ T348_VERSION,PPSC_H_VERSION); ++} ++ ++static void t348_write_regr (PHA *pha, int regr, int value) ++{ ++ w0(0x40+regr); w2(1); w2(0); w0(value); w2(8); w2(0); ++} ++ ++static int t348_read_regr (PHA *pha, int regr) ++{ ++ int s,a,b; ++ ++ w0(0x10+regr); s = r2(); w2(s|1); w2(s); w2(8); ++ w0(0x80); a = r1(); w0(0); b = r1(); w2(0); ++ return j44(a,b); ++} ++ ++static void t348_connect (PHA *pha) ++{ ++ int t; ++ ++ pha->saved_r0 = r0(); ++ w0(0); ++ t = r2(); ++ w2(t%16); w0(0xfe); w2(t%4); w2((t%4)+8); w2(0); ++ pha->saved_r2 = t; ++} ++ ++static void t348_disconnect (PHA *pha) ++{ ++ w0(0x71); w2(1); w2(0); ++ w0(pha->saved_r0); ++ w2(pha->saved_r2); ++} ++ ++static int t348_test_proto (PHA *pha) ++{ ++ int k, e, a, b; ++ int wnt[3] = {0x6c, 0x55, 0xaa}; ++ ++ e = 0; ++ ++ t348_connect(pha); ++ ++ switch (pha->mode) { ++ ++ case 0: w0(0x70); w2(1); w2(0); w0(0); ++ for (k=0;k<3;k++) { ++ w2(8); a = r1(); w2(0); ++ w2(8); w2(8); w2(8); w2(8); w2(8); ++ b = r1(); w2(0); ++ if (j44(b,a) != wnt[k]) e++; ++ } ++ break; ++ ++ case 1: w0(0x50); w2(1); w2(0); ++ for (k=0;k<3;k++) { ++ w2(0xe0); w2(0xe8); ++ if (r0() != wnt[k]) e++; ++ w2(0xe0); w2(0xe8); ++ } ++ ++ } ++ ++ t348_disconnect(pha); ++ ++ return e; ++} ++ ++/* The T348 appears to contain a NCR 5380 core. The following ++ functions use the 5380 registers. See NCR5380.h for clues. ++*/ ++ ++#define WR(r,v) t348_write_regr(pha,r,v) ++#define RR(r) (t348_read_regr(pha,r)) ++ ++static int t348_select (PHA *pha, int initiator, int target) ++{ ++ WR(3,0); WR(1,1); ++ WR(0,(1 << initiator)); WR(2,1); udelay(100); ++ if (RR(1) != 0x41) { ++ WR(1,0); ++ return -1; ++ } ++ ++ WR(1,5); WR(0,(1 << initiator)|(1 << target)); ++ WR(2,0); WR(2,0); WR(2,0); ++ return 0; ++} ++ ++static int t348_test_select (PHA *pha) ++{ ++ return ((RR(4) & 0x42) == 0x42); ++} ++ ++static void t348_select_finish (PHA *pha) ++{ ++ WR(3,2); WR(1,5); WR(1,1); ++} ++ ++static void t348_deselect (PHA *pha) ++{ ++ WR(1,0); ++} ++ ++static int t348_get_bus_status (PHA *pha) ++{ ++ int s; ++ ++ s = RR(4); ++ return t348_map[s]; ++} ++ ++static void t348_slow_start (PHA *pha, char *val) ++{ ++ int ph, io; ++ ++ ph = ((RR(4)>>2)&7); ++ io = (ph & 1); ++ ++ WR(3,ph); ++ WR(1,1-io); ++ if (io) *val = RR(0); else WR(0,*val); ++ WR(1,0x10+(1-io)); ++} ++ ++static int t348_slow_done (PHA *pha) ++{ ++ return ((RR(4) & 0x20) == 0); ++} ++ ++static void t348_slow_end (PHA *pha) ++{ ++ int io; ++ ++ io = ((RR(4)>>2)&1); ++ ++ WR(1,1-io); ++} ++ ++static void t348_start_block (PHA *pha, int rd) ++{ ++ if (rd) { ++ ++ WR(3,1); WR(1,0); ++ WR(2,2); WR(7,3); ++ WR(3,1); WR(1,0); ++ ++ switch (pha->mode) { ++ ++ case 0: w0(0x31); w2(1); w2(0); w0(0x80); w2(8); ++ break; ++ ++ case 1: w0(0x21); w2(1); w2(0); w2(0xe8); ++ break; ++ } ++ ++ } else { ++ ++ WR(3,0); WR(1,1); ++ WR(2,2); WR(5,0); ++ WR(3,0); WR(1,1); ++ ++ w0(0x61); w2(1); w2(0); ++ } ++} ++ ++static int t348_transfer_ready (PHA *pha) ++{ ++ if (r1() & 0x80) return 1; ++ ++ if (pha->data_dir == 0) return 0; ++ return -1; ++} ++ ++static int t348_transfer_block (PHA *pha, char * buf, int buflen, int rd) ++{ ++ int k, a, b; ++ ++ k = 0; ++ while (k < buflen) { ++ ++ if (t348_transfer_ready(pha) <= 0) break; ++ ++ if (rd) { ++ switch(pha->mode) { ++ ++ case 0: a = r1(); w0(0); b = r1(); w0(0xc0); ++ buf[k++] = j44(a,b); ++ a = r1(); w0(0x40); b = r1(); w0(0x80); ++ buf[k++] = j44(a,b); ++ break; ++ ++ case 1: buf[k++] = r0(); w2(0xea); ++ buf[k++] = r0(); w2(0xe8); ++ break; ++ } ++ ++ } else { ++ ++ w0(buf[k++]); w2(2); ++ w0(buf[k++]); w2(0); ++ } ++ ++ } ++ ++ return k; ++} ++ ++static int t348_transfer_done (PHA *pha) ++{ ++ return 1; ++} ++ ++static void t348_end_block (PHA *pha, int rd) ++{ ++ w2(0); ++ WR(2,0); ++} ++ ++ ++static void t348_reset_bus (PHA *pha) ++{ ++ WR(1,1); WR(3,0); ++ WR(2,0); ++ WR(1,0x80); udelay(60); ++ WR(1,0); ++ WR(2,0); ++ WR(1,1); WR(3,0); ++ WR(2,0); ++} ++ ++static char *(mode_strings[2]) = {"Nybble","PS/2"}; ++ ++static struct ppsc_protocol t348_psp = { ++ ++ {&host0,&host1,&host2,&host3}, /* params */ ++ &host_structs, /* hosts */ ++ 2, /* num_modes */ ++ 2, /* epp_first */ ++ 1, /* default_delay */ ++ 1, /* can_message */ ++ 0, /* sg_tablesize */ ++ mode_strings, ++ t348_init, ++ NULL, ++ t348_connect, ++ t348_disconnect, ++ t348_test_proto, ++ t348_select, ++ t348_test_select, ++ t348_select_finish, ++ t348_deselect, ++ t348_get_bus_status, ++ t348_slow_start, ++ t348_slow_done, ++ t348_slow_end, ++ t348_start_block, ++ t348_transfer_block, ++ t348_transfer_ready, ++ t348_transfer_done, ++ t348_end_block, ++ t348_reset_bus ++}; ++ ++int t348_detect (struct scsi_host_template *tpnt) ++{ ++ return ppsc_detect( &t348_psp, tpnt, verbose); ++} ++ ++#ifdef MODULE ++ ++struct scsi_host_template driver_template = PPSC_TEMPLATE(t348); ++ ++#include "scsi_module.c" ++ ++MODULE_LICENSE("GPL"); ++ ++#else ++ ++void t348_setup (char *str, int *ints) ++{ ++ ppsc_gen_setup(stt,4,str); ++} ++ ++#endif ++ ++/* end of t348.c */ ++ +--- /dev/null ++++ b/drivers/scsi/t358.c +@@ -0,0 +1,394 @@ ++/* ++ t358.c (c) 1997-1999 Grant Guenther ++ ++ This is the low-level protocol module for the Adaptec APA-358 ++ (aka Trantor T358) parallel port SCSI adapter. It forms part ++ of the 'ppSCSI' suite of drivers. ++ ++*/ ++ ++#define T358_VERSION "0.91" ++ ++#define PPSC_BASE ++#define PPSC_HA_MODULE ++ ++#include "ppscsi.h" ++ ++#define j44(a,b) (((a<<1)&0xf0)+((b>>3)&0x0f)) ++ ++static char t358_map[256]; /* status bits permutation */ ++ ++static void t358_init (PHA *pha) ++{ ++ ++/* { REQ, BSY, MSG, CD, IO} */ ++ ++ char key[5] = {0x20,0x40,0x10,0x08,0x04}; ++ ++ ppsc_make_map(t358_map,key,0); ++ sprintf(pha->ident,"t358 %s (%s), Adaptec APA-358", ++ T358_VERSION,PPSC_H_VERSION); ++} ++ ++static void t358_write_regr (PHA *pha, int regr, int value) ++{ ++ int x; ++ ++ switch (pha->mode) { ++ ++ case 0: ++ case 1: w0(regr); x = r2(); w2(1); w2(9); w2(0); w2(0); ++ w0(value); w2(1); w2(3); w2(0); w2(x); ++ break; ++ ++ case 2: w2(0xc0); w3(regr); w4(value); ++ break; ++ ++ } ++} ++ ++static int t358_read_regr (PHA *pha, int regr) ++{ ++ int h, l; ++ ++ switch (pha->mode) { ++ ++ case 0: w0(regr); w2(1); w2(9); w2(0); w2(0); ++ w0(0x80); w2(2); h = r1(); ++ w0(0); l = r1(); w2(0); ++ return j44(h,l); ++ ++ case 1: w0(regr); h = r2(); w2(1); w2(9); w2(0); w2(0); ++ w2(0xe2); l = r0(); w2(h); ++ return l; ++ ++ case 2: h = r2(); w2(0xe0); w3(regr); w2(0xe0); ++ l = r4(); w2(h); ++ return l; ++ } ++ ++ return 0; ++} ++ ++static void t358_read_block (PHA *pha, char *buf, int len) ++{ ++ int k, h, l; ++ ++ switch (pha->mode) { ++ ++ case 0: w0(0x10); w2(1); w2(9); w2(0); w2(0); ++ for (k=0;kmode) { ++ ++ case 0: ++ case 1: w0(0x10); x = r2(); ++ w2(1); w2(9); w2(0); w2(0); ++ for (k=0;ksaved_r0 = r0(); ++ w0(0); ++ pha->saved_r2 = r2(); ++ b = pha->saved_r2 % 4; ++ w0(0xf7); w2(b+4); w2(b); w2(b+8); w2(b); w2(0); ++ ++ if (pha->mode) { w0(0x80); w2(1); w2(9); w2(1); w2(0); } ++ else { w0(0xa0); w2(1); w2(9); w2(0); } ++} ++ ++static void t358_disconnect (PHA *pha) ++{ ++ w0(pha->saved_r0); ++ w2(pha->saved_r2); ++} ++ ++static int t358_test_proto (PHA *pha) ++{ ++ int h, l, a, b; ++ int j = 0, k = 0, e = 0; ++ ++ t358_connect(pha); ++ ++ switch (pha->mode) { ++ ++ case 0: w0(0x80); w2(8); h = r1(); w0(0); l = r1(); ++ w2(0); w2(8); a = r1(); w0(0); b = r1(); w2(0); ++ k = j44(h,l); j = j44(a,b); ++ break; ++ ++ case 1: w2(0xe0); w0(0); w2(0xe8); k = r0(); ++ w2(0xe0); w2(0xe8); j = r0(); w2(0xe0); ++ break; ++ ++ case 2: w0(0xa0); w2(1); w2(9); w2(0); ++ w0(0x80); w2(8); h = r1(); w0(0); l = r1(); ++ w2(0); w2(8); a = r1(); w0(0); b = r1(); w2(0); ++ k = j44(h,l); j = j44(a,b); ++ w0(0x80); w2(1); w2(9); w2(1); w2(0); ++ ++ } ++ ++ if (V_PROBE) printk("%s: Signature: %x %x\n",pha->device,k,j); ++ ++ if ((k != 0xe8) || (j != 0xff)) e++; ++ ++ t358_disconnect(pha); ++ ++ if (!e) { ++ ++ t358_connect(pha); ++ ++ for (j=0;j<256;j++) { ++ t358_write_regr(pha,0,j); ++ k = t358_read_regr(pha,0); ++ if (k != j) e++; ++ } ++ ++ t358_disconnect(pha); ++ ++ } ++ ++ return e; ++} ++ ++/* The T358 appears to contain a NCR 53c400 core. Check NCR5380.h ++ for hints about the regrs ... */ ++ ++#define WR(r,v) t358_write_regr(pha,r+8,v) ++#define RR(r) (t358_read_regr(pha,r+8)) ++ ++static int t358_select (PHA *pha, int initiator, int target) ++{ ++ WR(3,0); WR(1,1); ++ WR(0,(1 << initiator)); WR(2,1); udelay(100); ++ if (RR(1) != 0x41) { ++ WR(1,0); ++ return -1; ++ } ++ ++ WR(1,5); WR(0,(1 << initiator)|(1 << target)); ++ WR(2,0); WR(2,0); WR(2,0); ++ return 0; ++} ++ ++static int t358_test_select (PHA *pha) ++{ ++ return ((RR(4) & 0x42) == 0x42); ++} ++ ++static void t358_select_finish (PHA *pha) ++{ ++ WR(3,2); WR(1,5); WR(1,1); ++} ++ ++static void t358_deselect (PHA *pha) ++{ ++ WR(1,0); ++} ++ ++static int t358_get_bus_status (PHA *pha) ++{ ++ int s; ++ ++ s = RR(4); ++ return t358_map[s]; ++} ++ ++static void t358_slow_start (PHA *pha, char *val) ++{ ++ int ph, io; ++ ++ ph = ((RR(4)>>2)&7); ++ io = (ph & 1); ++ ++ WR(3,ph); ++ WR(1,1-io); ++ if (io) *val = RR(0); else WR(0,*val); ++ WR(1,0x10+(1-io)); ++} ++ ++static int t358_slow_done (PHA *pha) ++{ ++ return ((RR(4) & 0x20) == 0); ++} ++ ++static void t358_slow_end (PHA *pha) ++{ ++ int io; ++ ++ io = ((RR(4)>>2)&1); ++ ++ WR(1,1-io); ++} ++ ++static void t358_start_block (PHA *pha, int rd) ++{ ++ if (rd) { ++ WR(3,1); WR(1,0); ++ WR(2,2); ++ WR(0x10,0x40); WR(2,0); WR(2,0xa); ++ WR(3,1); WR(1,0); WR(7,3); ++ } else { ++ WR(3,0); WR(1,1); ++ WR(2,2); ++ WR(0x10,0); WR(2,0); WR(2,0xa); ++ WR(3,0); WR(1,1); WR(5,0); ++ } ++ WR(0x11,pha->tlen/128); ++} ++ ++static int t358_transfer_ready (PHA *pha) ++{ ++ int r; ++ ++ r = RR(0x10); ++ ++ if (!(r & 4)) return 128; /* 4 is host buffer not ready */ ++ ++ if (r & 1) return -1; /* last block transferred */ ++ ++ return 0; ++} ++ ++static int t358_transfer_block (PHA *pha, char * buf, int buflen, int rd) ++{ ++ int k, n; ++ ++ k = 0; ++ while (k < buflen) { ++ ++ n = t358_transfer_ready(pha); ++ ++ if (n <= 0) break; ++ ++ if (n > (buflen - k)) n = buflen - k; ++ ++ if (rd) t358_read_block(pha,buf,n); ++ else t358_write_block(pha,buf,n); ++ ++ k += n; buf += n; ++ ++ } ++ ++ return k; ++} ++ ++static int t358_transfer_done (PHA *pha) ++{ ++ if (RR(0x10) & 1) return 1; /* last block transferred */ ++ return 0; ++} ++ ++static void t358_end_block (PHA *pha, int rd) ++{ ++ WR(2,0); ++} ++ ++ ++static void t358_reset_bus (PHA *pha) ++{ ++ WR(1,1); WR(3,0); ++ WR(2,0); ++ WR(1,0x80); udelay(60); ++ WR(1,0); ++ WR(2,0); ++ WR(1,1); WR(3,0); ++ WR(2,0); ++} ++ ++static char *(mode_strings[3]) = {"Nybble","PS/2","EPP"}; ++ ++static struct ppsc_protocol t358_psp = { ++ ++ {&host0,&host1,&host2,&host3}, /* params */ ++ &host_structs, /* hosts */ ++ 3, /* num_modes */ ++ 2, /* epp_first */ ++ 1, /* default_delay */ ++ 1, /* can_message */ ++ 16, /* sg_tablesize */ ++ mode_strings, ++ t358_init, ++ NULL, ++ t358_connect, ++ t358_disconnect, ++ t358_test_proto, ++ t358_select, ++ t358_test_select, ++ t358_select_finish, ++ t358_deselect, ++ t358_get_bus_status, ++ t358_slow_start, ++ t358_slow_done, ++ t358_slow_end, ++ t358_start_block, ++ t358_transfer_block, ++ t358_transfer_ready, ++ t358_transfer_done, ++ t358_end_block, ++ t358_reset_bus ++}; ++ ++int t358_detect (struct scsi_host_template *tpnt ) ++{ ++ return ppsc_detect( &t358_psp, tpnt, verbose); ++} ++ ++#ifdef MODULE ++ ++struct scsi_host_template driver_template = PPSC_TEMPLATE(t358); ++ ++#include "scsi_module.c" ++ ++MODULE_LICENSE("GPL"); ++ ++#else ++ ++void t358_setup (char *str, int *ints) ++{ ++ ppsc_gen_setup(stt,4,str); ++} ++ ++#endif ++ ++/* end of t358.c */ ++ +--- a/drivers/scsi/Makefile ++++ b/drivers/scsi/Makefile +@@ -129,6 +129,16 @@ obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libisc + + obj-$(CONFIG_ARM) += arm/ + ++obj-$(CONFIG_PPSCSI) += ppscsi.o ++obj-$(CONFIG_PPSCSI_T348) += t348.o ++obj-$(CONFIG_PPSCSI_T358) += t358.o ++obj-$(CONFIG_PPSCSI_ONSCSI) += onscsi.o ++obj-$(CONFIG_PPSCSI_EPSA2) += epsa2.o ++obj-$(CONFIG_PPSCSI_EPST) += epst.o ++obj-$(CONFIG_PPSCSI_VPI0) += vpi0.o ++obj-$(CONFIG_PPSCSI_VPI2) += vpi2.o ++obj-$(CONFIG_PPSCSI_SPARCSI) += sparcsi.o ++ + obj-$(CONFIG_CHR_DEV_ST) += st.o + obj-$(CONFIG_CHR_DEV_OSST) += osst.o + obj-$(CONFIG_BLK_DEV_SD) += sd_mod.o +--- /dev/null ++++ b/drivers/scsi/epst.c +@@ -0,0 +1,478 @@ ++/* ++ epst.c (c) 1996-1999 Grant Guenther ++ ++ This is the ppSCSI protocol module for the Shuttle ++ Technologies EPST parallel port SCSI adapter. ++ ++*/ ++ ++#define EPST_VERSION "0.92" ++ ++#define PPSC_BASE ++#define PPSC_HA_MODULE ++ ++#include "ppscsi.h" ++ ++#define EPST_VER_CODE 0xb2 ++ ++#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0)) ++#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0)) ++ ++static char epst_map[256]; /* status bits permutation */ ++ ++static void epst_init (PHA *pha) ++{ ++ ++/* { REQ, BSY, MSG, CD, IO} */ ++ ++ char key[5] = {0x20,0x40,0x04,0x02,0x01}; ++ ++ ppsc_make_map(epst_map,key,0); ++ sprintf(pha->ident,"epst %s (%s), Shuttle EPST", ++ EPST_VERSION,PPSC_H_VERSION); ++} ++ ++static void epst_write_regr (PHA *pha, int regr, int value) ++{ ++ switch (pha->mode) { ++ ++ case 0: ++ case 1: ++ case 2: w0(0x60+regr); w2(1); w0(value); w2(4); ++ break; ++ ++ case 3: ++ case 4: ++ case 5: w3(0x40+regr); w4(value); ++ break; ++ ++ } ++} ++ ++static int epst_read_regr (PHA *pha, int regr) ++{ ++ int a, b; ++ ++ switch (pha->mode) { ++ ++ case 0: w0(regr); w2(1); w2(3); ++ a = r1(); w2(4); b = r1(); ++ return j44(a,b); ++ ++ case 1: w0(0x40+regr); w2(1); w2(4); ++ a = r1(); b = r2(); w0(0xff); ++ return j53(a,b); ++ ++ case 2: w0(0x20+regr); w2(1); w2(0x25); ++ a = r0(); w2(4); ++ return a; ++ ++ case 3: ++ case 4: ++ case 5: w3(regr); w2(0x24); a = r4(); ++ return a; ++ ++ } ++ ++ return -1; ++} ++ ++/* for performance reasons, these block transfer functions make ++ some assumptions about the behaviour of the SCSI devices. In ++ particular, DMA transfers are assumed not to stall within the ++ last few bytes of a block ... ++*/ ++ ++static int epst_read_block (PHA *pha, char *buf, int len) ++{ ++ int t, k, p, a, b; ++ ++ k = 0; ++ ++ switch (pha->mode) { ++ ++ case 0: w0(7); w2(1); w2(3); w0(0xff); ++ p = 1; ++ while (k < len) { ++ w2(6+p); a = r1(); ++ if (a & 8) b = a; else { w2(4+p); b = r1(); } ++ buf[k++] = j44(a,b); ++ p = 1 - p; ++ if (!(k % 16)) { ++ w0(0xfe); t = r1(); w0(0xff); ++ if (t & 8) break; ++ } ++ } ++ w0(0); w2(4); ++ break; ++ ++ case 1: w0(0x47); w2(1); w2(5); w0(0xff); ++ p = 0; ++ while (k < len) { ++ a = r1(); b = r2(); ++ buf[k++] = j53(a,b); ++ w2(4+p); ++ p = 1 - p; ++ if (!(k % 16)) { ++ w0(0xfe); t = r1(); w0(0xff); ++ if (t & 8) break; ++ } ++ } ++ w0(0); w2(4); ++ break; ++ ++ case 2: w0(0x27); w2(1); ++ p = 1; ++ while (k < len) { ++ w2(0x24+p); ++ buf[k++] = r0(); ++ p = 1 - p; ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(6); w2(4); ++ break; ++ ++ case 3: w3(0x80); w2(0x24); ++ while (k < len) { ++ buf[k++] = r4(); ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ ++ case 4: w3(0x80); w2(0x24); ++ while (k < len) { ++ if ((len - k) > 1) { ++ *((u16 *)(&buf[k])) = r4w(); ++ k += 2; ++ } else { ++ buf[k++] = r4(); ++ } ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ ++ case 5: w3(0x80); w2(0x24); ++ while (k < len) { ++ if ((len - k) > 3) { ++ *((u32 *)(&buf[k])) = r4l(); ++ k += 4; ++ } else { ++ buf[k++] = r4(); ++ } ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ } ++ ++ return k; ++} ++ ++static int epst_write_block (PHA *pha, char *buf, int len) ++{ ++ int p, k; ++ ++ k = 0; ++ ++ switch (pha->mode) { ++ ++ case 0: ++ case 1: ++ case 2: w0(0x67); w2(1); ++ p = 1; ++ while (k < len) { ++ w2(4+p); ++ w0(buf[k++]); ++ p = 1 - p; ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(5); w2(7); w2(4); ++ break; ++ ++ case 3: w3(0xc0); ++ while (k < len) { ++ w4(buf[k++]); ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ ++ case 4: w3(0xc0); ++ while (k < len) { ++ if ((len - k) > 1) { ++ w4w(*((u16 *)(&buf[k]))); ++ k += 2; ++ } else { ++ w4(buf[k++]); ++ } ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ ++ case 5: w3(0xc0); ++ while (k < len) { ++ if ((len - k) > 3) { ++ w4l(*((u32 *)(&buf[k]))); ++ k += 4; ++ } else { ++ w4(buf[k++]); ++ } ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ } ++ ++ return k; ++} ++ ++#define WR(r,v) epst_write_regr(pha,r,v) ++#define RR(r) (epst_read_regr(pha,r)) ++ ++#define CPP(x) w2(4);w0(0x22);w0(0xaa);w0(0x55);w0(0);w0(0xff);\ ++ w0(0x87);w0(0x78);w0(x);w2(5);w2(4);w0(0xff); ++ ++static void epst_connect (PHA *pha) ++{ ++ w2(4); ++ CPP(0x40); CPP(0xe0); ++ w0(0); w2(1); w2(3); w2(4); ++ ++ if (pha->mode >= 3) { ++ w0(0); w2(1); w2(3); w2(4); w2(0xc); ++ w0(0x40); w2(6); w2(7); w2(4); ++ } ++ ++ WR(0x1d,0x20); WR(0x1d,0); /* clear the ring buffer */ ++ WR(0xa,0x1e); /* set up PDMA */ ++ WR(0xc,4); /* enable status bits */ ++ WR(8,2); /* deglitch timing */ ++} ++ ++static void epst_disconnect (PHA *pha) ++{ ++ CPP(0x30); w2(4); ++ CPP(0x40); w2(4); ++} ++ ++#define Wsr(r,v) WR(0x18+r,v) ++#define Rsr(r) (RR(0x18+r)) ++ ++static int epst_test_proto (PHA *pha) ++{ ++ int i, j, e; ++ char wb[16], rb[16]; ++ ++ e = 0; ++ ++ epst_connect(pha); ++ i = RR(0xb); ++ if (V_PROBE) printk("%s: version code reads: 0x%x\n",pha->device,i); ++ epst_disconnect(pha); ++ ++ if (i != EPST_VER_CODE) return 1; ++ ++ epst_connect(pha); ++ ++ for (j=0;j<200;j++) { ++ for (i=0;i<16;i++) { wb[i] = i+j; rb[i] = i+j+6; } ++ Wsr(5,1); ++ epst_write_block(pha,wb,16); ++ Wsr(5,0x11); ++ epst_read_block(pha,rb,16); ++ for (i=0;i<16;i++) if (wb[i] != rb[i]) e++; ++ } ++ ++ epst_disconnect(pha); ++ ++ if (V_FULL) ++ printk("%s: test port 0x%x mode %d errors %d\n", ++ pha->device,pha->port,pha->mode,e); ++ ++ return e; ++} ++ ++/* The EPST contains a core SCSI controller that is very ++ similar to the NCR 5380. Some bits have been shuffled ++ around, but the basic structure is the same. ++*/ ++ ++static int epst_select (PHA *pha, int initiator, int target) ++{ ++ Wsr(4,(1< ++ ++ This is the low-level protocol module for the WBS-11A parallel ++ port SCSI adapter. This adapter has been marketed by LinkSys ++ as the "ParaSCSI+" and by Shining Technologies as the "SparCSI". ++ The device is constructed from the KBIC-951A ISA replicator ++ chip from KingByte and the NCR 5380. ++ ++*/ ++ ++#define SPARCSI_VERSION "0.91" ++ ++#define PPSC_BASE ++#define PPSC_HA_MODULE ++ ++#include "ppscsi.h" ++ ++#define r12w() (delay_p,inw(pha->port+1)&0xffff) ++ ++#define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88) ++#define j53(w) (((w>>3)&0x1f)|((w>>4)&0xe0)) ++ ++static char sparcsi_map[256]; /* status bits permutation */ ++ ++static void sparcsi_init (PHA *pha) ++{ ++ ++/* { REQ, BSY, MSG, CD, IO} */ ++ ++ char key[5] = {0x20,0x40,0x10,0x08,0x04}; ++ ++ ppsc_make_map(sparcsi_map,key,0); ++ sprintf(pha->ident,"sparcsi %s (%s), WBS-11A", ++ SPARCSI_VERSION,PPSC_H_VERSION); ++} ++ ++static void sparcsi_write_regr (PHA *pha, int regr, int value) ++{ ++ switch (pha->mode) { ++ ++ case 0: ++ case 1: ++ case 2: w0(regr|0x10); w2(4); w2(6); w2(4); ++ w0(value); w2(5); w2(4); ++ break; ++ ++ case 3: w0(0x20); w2(4); w2(6); w2(4); w3(regr); ++ w4(value); w2(4); w2(0); w2(4); ++ break; ++ ++ } ++} ++ ++static int sparcsi_read_regr (PHA *pha, int regr) ++{ ++ int a, b; ++ ++ switch (pha->mode) { ++ ++ case 0: w0(regr|0x18); w2(4); w2(6); w2(4); w2(5); ++ a = r1(); w0(0x58); b = r1(); w2(4); ++ return j44(a,b); ++ ++ case 1: w0(regr|0x58); w2(4); w2(6); w2(4); w2(5); ++ a = r12w(); w2(4); ++ return j53(a); ++ ++ case 2: w0(regr|0x98); w2(4); w2(6); w2(4); w2(0xa5); ++ a = r0(); w2(4); ++ return a; ++ ++ case 3: w0(0x20); w2(4); w2(6); w2(4); w3(regr); ++ w2(0xe4); a = r4(); w2(4); w2(0); w2(4); ++ return a; ++ ++ } ++ return -1; ++} ++ ++static void sparcsi_read_block (PHA *pha, char *buf, int len) ++{ ++ int k, a, b; ++ ++ switch (pha->mode) { ++ ++ case 0: w0(8); w2(4); w2(6); w2(4); ++ for (k=0;kmode) { ++ ++ case 0: ++ case 1: ++ case 2: w0(0); w2(4); w2(6); w2(4); ++ for(k=0;ksaved_r0 = r0(); ++ pha->saved_r2 = r2(); ++ w2(4); ++} ++ ++static void sparcsi_disconnect (PHA *pha) ++{ ++ w0(pha->saved_r0); ++ w2(pha->saved_r2); ++} ++ ++#define WR(r,v) sparcsi_write_regr(pha,r,v) ++#define RR(r) (sparcsi_read_regr(pha,r)) ++ ++static int sparcsi_test_proto (PHA *pha) ++{ ++ int k, e; ++ ++ e = 0; ++ ++ sparcsi_connect(pha); ++ ++ if (!pha->private[0]) { /* reset the SCSI bus on first sight */ ++ ++ if (V_FULL) printk("%s: SCSI reset ...\n",pha->device); ++ ++ WR(1,0x80); udelay(60); ++ WR(1,0); ++ scsi_sleep(5*HZ); ++ pha->private[0] = 1; ++ } ++ ++ WR(1,0); ++ WR(1,1); ++ ++ if (V_PROBE) ++ printk("%s: 5380 regrs [4]=%x [5]=%x\n",pha->device,RR(4),RR(5)); ++ ++ for (k=0;k<256;k++) { ++ WR(0,k); ++ if (RR(0) != k) e++; ++ WR(0,255-k); ++ if (RR(0) != (255-k)) e++; ++ } ++ ++ WR(1,0); ++ ++ sparcsi_disconnect(pha); ++ ++ return e; ++} ++ ++static int sparcsi_select (PHA *pha, int initiator, int target) ++{ ++ WR(3,0); WR(1,1); ++ WR(0,(1 << initiator)); WR(2,1); udelay(100); ++ if (RR(1) != 0x41) { ++ WR(1,0); ++ return -1; ++ } ++ ++ WR(1,5); WR(0,(1 << initiator)|(1 << target)); ++ WR(2,0); WR(2,0); WR(2,0); ++ return 0; ++} ++ ++static int sparcsi_test_select (PHA *pha) ++{ ++ return ((RR(4) & 0x42) == 0x42); ++} ++ ++static void sparcsi_select_finish (PHA *pha) ++{ ++ WR(3,2); WR(1,5); WR(1,1); ++} ++ ++static void sparcsi_deselect (PHA *pha) ++{ ++ WR(1,0); ++} ++ ++static int sparcsi_get_bus_status (PHA *pha) ++{ ++ int s; ++ ++ s = RR(4); ++ return sparcsi_map[s]; ++} ++ ++static void sparcsi_slow_start (PHA *pha, char *val) ++{ ++ int ph, io; ++ ++ ph = ((RR(4)>>2)&7); ++ io = (ph & 1); ++ ++ WR(3,ph); ++ WR(1,1-io); ++ if (io) *val = RR(0); else WR(0,*val); ++ WR(1,0x10+(1-io)); ++} ++ ++static int sparcsi_slow_done (PHA *pha) ++{ ++ return ((RR(4) & 0x20) == 0); ++} ++ ++static void sparcsi_slow_end (PHA *pha) ++{ ++ int io; ++ ++ io = ((RR(4)>>2)&1); ++ ++ WR(1,1-io); ++} ++ ++static void sparcsi_start_block (PHA *pha, int rd) ++{ ++ if (rd) { ++ ++ WR(3,1); WR(1,0); ++ WR(2,2); WR(7,3); ++ WR(3,1); WR(1,0); ++ ++ } else { ++ ++ WR(3,0); WR(1,1); ++ WR(2,2); WR(5,0); ++ WR(3,0); WR(1,1); ++ ++ } ++ pha->priv_flag = rd; ++} ++ ++static int sparcsi_transfer_ready (PHA *pha) ++{ ++ int chunk; ++ ++ chunk = 512; ++ if ((pha->data_count == 0) && (!pha->priv_flag)) chunk++; ++ ++ if (r1() & 0x40) return chunk; ++ if (!(RR(5) & 8)) return -1; ++ return 0; ++} ++ ++static int sparcsi_transfer_block (PHA *pha, char * buf, int buflen, int rd) ++{ ++ int k, n; ++ ++ k = 0; ++ while (k < buflen) { ++ ++ n = sparcsi_transfer_ready(pha); ++ ++ if (n <= 0) break; ++ ++ if (n > (buflen - k)) n = buflen - k; ++ ++ if (rd) sparcsi_read_block(pha,buf,n); ++ else sparcsi_write_block(pha,buf,n); ++ ++ k += n; buf += n; ++ } ++ ++ return k; ++} ++ ++static int sparcsi_transfer_done (PHA *pha) ++{ ++ return 1; ++} ++ ++static void sparcsi_end_block (PHA *pha, int rd) ++{ ++ char buf[2] = {0,0}; ++ ++ if (!rd) sparcsi_write_block(pha,buf,1); ++ ++ WR(2,0); ++} ++ ++static void sparcsi_reset_bus (PHA *pha) ++{ ++ WR(1,1); WR(3,0); ++ WR(2,0); ++ WR(1,0x80); udelay(60); ++ WR(1,0); ++ WR(2,0); ++ WR(1,1); WR(3,0); ++ WR(2,0); ++} ++ ++static char *(mode_strings[4]) = {"Nybble","KBIC 5/3","PS/2","EPP"}; ++ ++static struct ppsc_protocol sparcsi_psp = { ++ ++ {&host0,&host1,&host2,&host3}, /* params */ ++ &host_structs, /* hosts */ ++ 4, /* num_modes */ ++ 3, /* epp_first */ ++ 1, /* default_delay */ ++ 1, /* can_message */ ++ 16, /* sg_tablesize */ ++ mode_strings, ++ sparcsi_init, ++ NULL, ++ sparcsi_connect, ++ sparcsi_disconnect, ++ sparcsi_test_proto, ++ sparcsi_select, ++ sparcsi_test_select, ++ sparcsi_select_finish, ++ sparcsi_deselect, ++ sparcsi_get_bus_status, ++ sparcsi_slow_start, ++ sparcsi_slow_done, ++ sparcsi_slow_end, ++ sparcsi_start_block, ++ sparcsi_transfer_block, ++ sparcsi_transfer_ready, ++ sparcsi_transfer_done, ++ sparcsi_end_block, ++ sparcsi_reset_bus ++}; ++ ++int sparcsi_detect (Scsi_Host_Template *tpnt) ++{ ++ return ppsc_detect( &sparcsi_psp, tpnt, verbose); ++} ++ ++#ifdef MODULE ++ ++Scsi_Host_Template driver_template = PPSC_TEMPLATE(sparcsi); ++ ++#include "scsi_module.c" ++ ++MODULE_LICENSE("GPL"); ++ ++#else ++ ++void sparcsi_setup (char *str, int *ints) ++{ ++ ppsc_gen_setup(stt,4,str); ++} ++ ++#endif ++ ++/* end of sparcsi.c */ ++ +--- /dev/null ++++ b/drivers/scsi/epsa2.c +@@ -0,0 +1,507 @@ ++/* ++ epsa2.c (c) 1996-1999 Grant Guenther ++ ++ This is the ppSCSI protocol module for the Shuttle ++ Technologies EPSA2 parallel port SCSI adapter. EPSA2 is ++ a predecessor to the EPST. It uses slightly different ++ command encoding and has a less elaborate internal register ++ model. ++ ++*/ ++ ++#define EPSA2_VERSION "0.91" ++ ++#define PPSC_BASE ++#define PPSC_HA_MODULE ++ ++#include "ppscsi.h" ++ ++#define EPSA2_VER_CODE 0xb1 ++ ++#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0)) ++#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0)) ++ ++static char epsa2_map[256]; /* status bits permutation */ ++ ++static void epsa2_init( PHA *pha) ++{ ++ ++/* { REQ, BSY, MSG, CD, IO} */ ++ ++ char key[5] = {0x20,0x40,0x04,0x02,0x01}; ++ ++ ppsc_make_map(epsa2_map,key,0); ++ sprintf(pha->ident,"epsa2 %s (%s), Shuttle EPSA2", ++ EPSA2_VERSION,PPSC_H_VERSION); ++} ++ ++static void epsa2_write_regr (PHA *pha, int regr, int value) ++{ ++ switch (pha->mode) { ++ ++ case 0: ++ case 1: ++ case 2: w0(0x70+regr); w2(1); w0(value); w2(4); ++ break; ++ ++ case 3: ++ case 4: ++ case 5: w3(0x40+regr); w4(value); w2(4); ++ break; ++ ++ } ++} ++ ++static int epsa2_read_regr (PHA *pha, int regr) ++{ ++ int a, b; ++ ++ switch (pha->mode) { ++ ++ case 0: w0(0x40+regr); w2(1); w2(3); ++ a = r1(); w2(4); b = r1(); ++ return j44(a,b); ++ ++ case 1: w0(0x60+regr); w2(1); w2(4); ++ a = r1(); b = r2(); w0(0xff); ++ return j53(a,b); ++ ++ case 2: w0(0x50+regr); w2(1); w2(0x25); ++ a = r0(); w2(4); ++ return a; ++ ++ case 3: ++ case 4: ++ case 5: w3(regr); w2(0x24); a = r4(); w2(4); ++ return a; ++ ++ } ++ ++ return -1; ++} ++ ++/* for performance reasons, these block transfer functions make ++ some assumptions about the behaviour of the SCSI devices. In ++ particular, DMA transfers are assumed not to stall within the ++ last few bytes of a block ... ++*/ ++ ++static int epsa2_read_block (PHA *pha, char *buf, int len) ++{ ++ int t, k, p, a, b; ++ ++ k = 0; ++ ++ switch (pha->mode) { ++ ++ case 0: w0(7); w2(1); w2(3); w0(0xff); ++ p = 1; ++ while (k < len) { ++ w2(6+p); a = r1(); ++ if (a & 8) b = a; else { w2(4+p); b = r1(); } ++ buf[k++] = j44(a,b); ++ p = 1 - p; ++ if (!(k % 16)) { ++ w0(0xfe); t = r1(); w0(0xff); ++ if (t & 8) break; ++ } ++ } ++ w0(0); w2(4); ++ break; ++ ++ case 1: w0(0x27); w2(1); w2(5); w0(0xff); ++ p = 0; ++ while (k < len) { ++ a = r1(); b = r2(); ++ buf[k++] = j53(a,b); ++ w2(4+p); ++ p = 1 - p; ++ if (!(k % 16)) { ++ w0(0xfe); t = r1(); w0(0xff); ++ if (t & 8) break; ++ } ++ } ++ w0(0); w2(4); ++ break; ++ ++ case 2: w0(0x17); w2(1); ++ p = 1; ++ while (k < len) { ++ w2(0x24+p); ++ buf[k++] = r0(); ++ p = 1 - p; ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(6); w2(4); ++ break; ++ ++ case 3: w3(6); w2(0x24); ++ while (k < len) { ++ buf[k++] = r4(); ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ ++ case 4: w3(6); w2(0x24); ++ while (k < len) { ++ if ((len - k) > 1) { ++ *((u16 *)(&buf[k])) = r4w(); ++ k += 2; ++ } else { ++ buf[k++] = r4(); ++ } ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ ++ case 5: w3(6); w2(0x24); ++ while (k < len) { ++ if ((len - k) > 3) { ++ *((u32 *)(&buf[k])) = r4l(); ++ k += 4; ++ } else { ++ buf[k++] = r4(); ++ } ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ } ++ ++ return k; ++} ++ ++static int epsa2_write_block (PHA *pha, char *buf, int len) ++{ ++ int p, k; ++ ++ k = 0; ++ ++ switch (pha->mode) { ++ ++ case 0: ++ case 1: ++ case 2: w0(0x37); w2(1); ++ p = 1; ++ while (k < len) { ++ w2(4+p); ++ w0(buf[k++]); ++ p = 1 - p; ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(5); w2(7); w2(4); ++ break; ++ ++ case 3: w3(0x46); ++ while (k < len) { ++ w4(buf[k++]); ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ ++ case 4: w3(0x46); ++ while (k < len) { ++ if ((len - k) > 1) { ++ w4w(*((u16 *)(&buf[k]))); ++ k += 2; ++ } else { ++ w4(buf[k++]); ++ } ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ ++ case 5: w3(0x46); ++ while (k < len) { ++ if ((len - k) > 3) { ++ w4l(*((u32 *)(&buf[k]))); ++ k += 4; ++ } else { ++ w4(buf[k++]); ++ } ++ if ((!(k % 16)) && (r1() & 8)) break; ++ } ++ w2(4); ++ break; ++ } ++ ++ return k; ++} ++ ++#define WR(r,v) epsa2_write_regr(pha,r,v) ++#define RR(r) (epsa2_read_regr(pha,r)) ++ ++#define CPP(x) w2(4);w0(0x22);w0(0xaa);w0(0x55);w0(0);w0(0xff);\ ++ w0(0x87);w0(0x78);w0(x);w2(5);w2(4);w0(0xff); ++ ++static void epsa2_connect (PHA *pha) ++{ ++ CPP(0x40); CPP(0xe0); ++ ++ w0(0x73); w2(1); w0(0); w2(4); ++ w0(0x72); w2(1); w0(0x40); w2(4); ++ ++ w0(0); w2(1); w2(4); ++ ++ CPP(0x50); CPP(0x48); ++ ++ switch (pha->mode) { ++ ++ case 0: WR(7,0x82); ++ break; ++ ++ case 1: ++ case 2: WR(7,0xa2); ++ break; ++ ++ case 3: ++ case 4: ++ case 5: CPP(0x30); CPP(0x20); ++ WR(7,0xa3); ++ break; ++ } ++ ++ w2(4); ++} ++ ++static void epsa2_disconnect (PHA *pha) ++{ ++ switch (pha->mode) { ++ ++ case 0: WR(7,2); WR(2,0); ++ break; ++ ++ case 1: ++ case 2: WR(7,0x22); WR(2,0); ++ break; ++ ++ case 3: ++ case 4: ++ case 5: WR(7,0x23); w2(4); ++ w0(0x72); w2(1); w0(0); w2(4); ++ break; ++ } ++ ++ CPP(0x30); CPP(0x40); ++} ++ ++static int epsa2_test_proto (PHA *pha) ++{ ++ int i, j, e; ++ char wb[16], rb[16]; ++ ++ e = 0; ++ ++ epsa2_connect(pha); ++ i = RR(7); ++ if (V_PROBE) printk("%s: version code reads: 0x%x\n",pha->device,i); ++ epsa2_disconnect(pha); ++ ++ if (i != EPSA2_VER_CODE) return 1; ++ ++ epsa2_connect(pha); ++ ++ for (j=0;j<200;j++) { ++ for (i=0;i<16;i++) { wb[i] = i+j; rb[i] = i+j+6; } ++ WR(5,1); ++ epsa2_write_block(pha,wb,16); ++ udelay(100); ++ WR(5,0x11); ++ epsa2_read_block(pha,rb,16); ++ for (i=0;i<16;i++) if (wb[i] != rb[i]) e++; ++ } ++ ++ epsa2_disconnect(pha); ++ ++ if (V_FULL) ++ printk("%s: test port 0x%x mode %d errors %d\n", ++ pha->device,pha->port,pha->mode,e); ++ ++ return e; ++} ++ ++/* The EPSA2 contains a core SCSI controller that is very ++ similar to the NCR 5380. Some bits have been shuffled ++ around, but the basic structure is the same. ++*/ ++ ++static int epsa2_select (PHA *pha, int initiator, int target) ++{ ++ WR(4,(1< ++ (C) 2000 Tim Waugh ++ Under the terms of the GNU general public license. ++ ++ This is the common code shared by the PPSCSI family of ++ low-level drivers for parallel port SCSI host adapters. ++ ++ ++ To use one of the ppSCSI drivers, you must first have this module ++ built-in to your kernel, or loaded. Then, you can load the ++ appropriate protocol module. All protocol modules accept the ++ same parameters: ++ ++ verbose=N determines the logging level where N= ++ 0 only serious errors are logged ++ 1 report progress messages while probing adapters ++ 2 log the scsi commands sent to adapters ++ 3 basic debugging information ++ 4 full debugging (generates lots of output) ++ ++ hostN=,,,,, ++ ++ sets per-host-adapter parameters where ++ ++ N is between 0 and 3, each protocol can ++ support up to four separate adapters. ++ ++ The parport for this adapter, eg: ++ 0 for parport0. ++ ++ Protocol dependent mode number. Usually ++ probed to determine the fastest available ++ mode. ++ ++ microseconds of delay per port access. ++ Default is protocol dependent. ++ ++ Determines this host's ability to load ++ the system. Default 0. Set to 1 or 2 ++ to reduce load at the expense of device ++ performance. ++ ++ scatter-gather table size. ++ ++ bit mask of targets on which to force ++ all commands to use explicit REQ/ACK ++ handshaking, rather than adapter buffers. ++ ++*/ ++ ++#define PPSC_VERSION "0.92" ++ ++#define PPSC_BASE ++#include "ppscsi.h" ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define PPSC_GEN_TMO 40*HZ ++#define PPSC_SELECT_TMO HZ/10 ++#define PPSC_PROBE_TMO HZ/2 ++#define PPSC_RESET_TMO 4*HZ ++#define PPSC_SLOW_LOOPS 30 ++#define PPSC_BUSY_SNOOZE HZ; ++ ++#define PPSC_DEF_NICE 0 ++#define PPSC_INITIATOR 7 ++ ++spinlock_t ppsc_spinlock = SPIN_LOCK_UNLOCKED; ++ ++static char ppsc_bulk_map[256]; ++ ++struct ppsc_port_list_struct { ++ struct parport *port; ++ struct ppsc_port_list_struct *next; ++}; ++static struct ppsc_port_list_struct *ppsc_port_list; ++ ++/* ppsc_attach and ppsc_detach are for keeping a list of currently ++ * available ports, held under a mutex. We do this rather than ++ * using parport_enumerate because it stops a load of races. ++ */ ++ ++static void ppsc_attach (struct parport *port) ++{ ++ struct ppsc_port_list_struct *add; ++ ++ add = kmalloc (sizeof (struct ppsc_port_list_struct), GFP_KERNEL); ++ if (!add) { ++ printk (KERN_WARNING "ppscsi: memory squeeze\n"); ++ return; ++ } ++ ++ add->port = parport_get_port (port); ++ add->next = ppsc_port_list; ++ wmb (); ++ ppsc_port_list = add; ++} ++ ++static void ppsc_detach (struct parport *port) ++{ ++ /* Do nothing. We have a reference to the port already, so ++ * it won't go away. We'll clean up the port list when we ++ * unload. */ ++} ++ ++static struct parport_driver ppsc_driver = { ++ name: "ppscsi", ++ attach: ppsc_attach, ++ detach: ppsc_detach ++}; ++ ++void ppsc_make_map (char map[256], char key[5], int inv) ++{ ++ int i, j; ++ ++ for (i=0;i<256;i++) { ++ map[i] = 0; ++ for (j=0;j<5;j++) ++ map[i] = (map[i] << 1) | ((i & key[j]) != inv*key[j]); ++ } ++} ++ ++void ppsc_gen_setup (STT t[], int n, char *ss) ++{ ++ int j, k, sgn; ++ ++ k = 0; ++ for (j=0;jcontinuation = continuation; ++ pha->ready = ready; ++ if (timeout) ++ pha->timeout = jiffies + timeout; ++ else pha->timeout = pha->then + pha->tmo; ++ ++ if (!pha->nice && !pha->wq_active) { ++#ifdef HAVE_DISABLE_HLT ++ disable_hlt(); ++#endif ++ pha->wq_active = 1; ++ schedule_work (&pha->wq); ++ } ++ ++ if (!pha->timer_active) { ++ pha->timer_active = 1; ++ pha->timer.expires = jiffies + ((pha->nice>0)?(pha->nice-1):0); ++ add_timer(&pha->timer); ++ } ++ ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++} ++ ++static void ppsc_tq_int (void *data) ++{ ++ void (*con)(PHA *); ++ unsigned long flags; ++ PHA *pha = (PHA *)data; ++ ++ spin_lock_irqsave(&ppsc_spinlock,flags); ++ ++ con = pha->continuation; ++ ++#ifdef HAVE_DISABLE_HLT ++ enable_hlt(); ++#endif ++ ++ pha->wq_active = 0; ++ ++ if (!con) { ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++ return; ++ } ++ pha->timedout = time_after_eq (jiffies, pha->timeout); ++ if (!pha->ready || pha->ready(pha) || pha->timedout) { ++ pha->continuation = NULL; ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++ con(pha); ++ return; ++ } ++ ++#ifdef HAVE_DISABLE_HLT ++ disable_hlt(); ++#endif ++ ++ pha->wq_active = 1; ++ schedule_work (&pha->wq); ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++} ++ ++static void ppsc_timer_int (unsigned long data) ++{ ++ void (*con)(PHA *); ++ unsigned long flags; ++ PHA *pha = (PHA *)data; ++ ++ spin_lock_irqsave(&ppsc_spinlock,flags); ++ ++ con = pha->continuation; ++ pha->timer_active = 0; ++ if (!con) { ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++ return; ++ } ++ pha->timedout = time_after_eq (jiffies, pha->timeout); ++ if (!pha->ready || pha->ready(pha) || pha->timedout) { ++ pha->continuation = NULL; ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++ con(pha); ++ return; ++ } ++ pha->timer_active = 1; ++ pha->timer.expires = jiffies + ((pha->nice>0)?(pha->nice-1):0); ++ add_timer(&pha->timer); ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++} ++ ++static void ppsc_wake_up( void *p) ++{ ++ PHA *pha = (PHA *) p; ++ unsigned long flags; ++ void (*cont)(PHA *) = NULL; ++ ++ spin_lock_irqsave(&ppsc_spinlock,flags); ++ ++ if (pha->claim_cont && ++ !parport_claim(pha->pardev)) { ++ cont = pha->claim_cont; ++ pha->claim_cont = NULL; ++ pha->claimed = 1; ++ } ++ ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++ ++ wake_up(&(pha->parq)); ++ ++ if (cont) cont(pha); ++} ++ ++void ppsc_do_claimed (PHA *pha, void(*cont)(PHA *)) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ppsc_spinlock,flags); ++ ++ if (!parport_claim(pha->pardev)) { ++ pha->claimed = 1; ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++ cont(pha); ++ } else { ++ pha->claim_cont = cont; ++ spin_unlock_irqrestore(&ppsc_spinlock,flags); ++ } ++} ++ ++static void ppsc_claim (PHA *pha) ++{ ++ if (pha->claimed) return; ++ pha->claimed = 1; ++ ++ wait_event (pha->parq, !parport_claim (pha->pardev)); ++} ++ ++static void ppsc_unclaim (PHA *pha) ++{ ++ pha->claimed = 0; ++ parport_release(pha->pardev); ++} ++ ++static void ppsc_unregister_parport (PHA *pha) ++{ ++ parport_unregister_device(pha->pardev); ++ pha->pardev = NULL; ++} ++ ++static int ppsc_register_parport (PHA *pha, int verbose) ++{ ++ struct ppsc_port_list_struct *ports; ++ struct parport *port = NULL; ++ ++ ports = ppsc_port_list; ++ while((ports)&&(ports->port->number != pha->port)) ++ ports = ports->next; ++ if (ports) { ++ port = ports->port; ++ pha->pardev = parport_register_device(port, pha->device, ++ NULL, ppsc_wake_up, NULL, ++ 0, (void *)pha); ++ } else { ++ printk (KERN_DEBUG "%s: no such device: parport%d\n", ++ pha->device, pha->port); ++ return 1; ++ } ++ ++ if (!pha->pardev) { ++ printk (KERN_DEBUG "%s: couldn't register device\n", ++ pha->device); ++ return 1; ++ } ++ ++ init_waitqueue_head (&pha->parq); ++ ++ /* For now, cache the port base address. Won't need this ++ after transition to parport_xxx_yyy. */ ++ pha->port = port->base; ++ ++ if (verbose) ++ printk("%s: 0x%x is %s\n",pha->device,pha->port, ++ port->name); ++ pha->parname = port->name; ++ return 0; ++} ++ ++/* Here's the actual core SCSI stuff ... */ ++ ++#define PPSC_FAIL(err,msg) { ppsc_fail_command(pha,err,msg); return; } ++ ++static void ppsc_start (PHA *pha); ++static void ppsc_select_intr (PHA *pha); ++static void ppsc_engine (PHA *pha); ++static void ppsc_transfer (PHA *pha); ++static void ppsc_transfer_done (PHA *pha); ++static int ppsc_slow (PHA *pha, char *val); ++static void ppsc_slow_done (PHA *pha); ++static void ppsc_cleanup (PHA *pha); ++static void ppsc_fail_command (PHA *pha, int err_code, char *msg); ++static int ppsc_ready (PHA *pha); ++ ++/* synchronous interface is deprecated, but we maintain it for ++ internal use. It just starts an asynchronous command and waits ++ for it to complete. ++*/ ++ ++int ppsc_command (struct scsi_cmnd *cmd) ++{ ++ PHA *pha = (PHA *) cmd->device->host->hostdata[0]; ++ ++ pha->cur_cmd = cmd; ++ pha->done = NULL; ++ pha->then = jiffies; ++ ++ ppsc_do_claimed(pha,ppsc_start); ++ ++ while (pha->cur_cmd) scsi_sleep(1); ++ ++ return cmd->result; ++} ++ ++int ppsc_queuecommand (struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) ++{ ++ PHA *pha = (PHA *) cmd->device->host->hostdata[0]; ++ ++ if (pha->cur_cmd) { ++ printk("%s: Driver is busy\n",pha->device); ++ return 0; ++ } ++ ++ pha->cur_cmd = cmd; ++ pha->done = done; ++ pha->then = jiffies; ++ ++ ppsc_do_claimed(pha,ppsc_start); ++ ++ return 0; ++} ++ ++static void ppsc_arb_fail (PHA *pha) ++{ ++ PPSC_FAIL(DID_BUS_BUSY,"Arbitration failure"); ++} ++ ++static void ppsc_start (PHA *pha) ++{ ++ int k, r, b, bf; ++ struct scatterlist *p; ++ ++ pha->last_phase = PPSC_PH_NONE; ++ pha->return_code = (DID_OK << 16); ++ pha->overflow = 0; ++ pha->protocol_error = 0; ++ pha->cmd_count = 0; ++ ++ k = pha->cur_cmd->cmnd[0]; ++ bf = ppsc_bulk_map[k]; ++ ++ bf &= (!((1<cur_cmd->device->id) & pha->slow_targets)); ++ ++ r = pha->cur_cmd->use_sg; ++ if (r) { ++ b = 0; ++ p = (struct scatterlist *)pha->cur_cmd->request_buffer; ++ for (k=0;klength; ++ p++; ++ } ++ } else { ++ b = pha->cur_cmd->request_bufflen; ++ } ++ ++ bf &= (b > 127); ++ ++ if (V_DEBUG) ++ printk("%s: Target %d, bl=%d us=%d bf=%d cm=%x\n", ++ pha->device,pha->cur_cmd->device->id,b,r,bf,k); ++ ++ pha->bulk = bf; ++ pha->tlen = b; ++ ++ pha->proto->connect(pha); ++ ++ r = 0; ++ while (r++ < 5) { ++ k = pha->proto->select(pha,PPSC_INITIATOR,pha->cur_cmd->device->id); ++ if (k != -1) break; ++ udelay(200); ++ } ++ ++ if (k == -1) { ++ ppsc_set_intr(pha,ppsc_arb_fail,NULL,1); ++ return; ++ } ++ ++ ppsc_set_intr(pha,ppsc_select_intr,pha->proto->test_select, ++ PPSC_SELECT_TMO); ++} ++ ++static void ppsc_select_intr (PHA *pha) ++{ ++ if (!pha->proto->test_select(pha)) { ++ pha->return_code = DID_NO_CONNECT << 16; ++ ppsc_cleanup(pha); ++ return; ++ } ++ if (pha->proto->select_finish) ++ pha->proto->select_finish(pha); ++ ++ if (V_FULL) ++ printk("%s: selected target\n",pha->device); ++ ++ pha->timedout = 0; ++ ppsc_engine(pha); ++} ++ ++static void ppsc_update_sg (PHA *pha) ++{ ++ if ((!pha->cur_len) && pha->sg_count) { ++ pha->sg_count--; ++ pha->sg_list++; ++ pha->cur_buf = page_address(pha->sg_list->page) + pha->sg_list->offset; ++ pha->cur_len = pha->sg_list->length; ++ } ++} ++ ++static void ppsc_engine (PHA *pha) ++{ ++ int phase, i; ++ char *sb; ++ ++ while (1) { ++ if ((pha->last_phase == PPSC_PH_MSGIN) || ++ ((pha->last_phase == PPSC_PH_STAT) ++ && (!pha->proto->can_message))) { ++ pha->return_code |= (pha->status_byte & STATUS_MASK) ++ | (pha->message_byte << 8); ++ ppsc_cleanup(pha); ++ return; ++ } ++ ++ phase = pha->proto->get_bus_status(pha); ++ ++ if (pha->abort_flag) ++ PPSC_FAIL(DID_ABORT,"Command aborted"); ++ ++ if (pha->protocol_error) ++ PPSC_FAIL(DID_ERROR,"Adapter protocol failure"); ++ ++ if (!(phase & PPSC_BSY)) { ++ if (pha->last_phase == PPSC_PH_STAT) { ++ if (V_DEBUG) printk("%s: No msg phase ?\n", pha->device); ++ pha->return_code |= (pha->status_byte & STATUS_MASK); ++ ppsc_cleanup(pha); ++ return; ++ } ++ PPSC_FAIL(DID_ERROR,"Unexpected bus free"); ++ } ++ ++ if (!(phase & PPSC_REQ)) { ++ if (pha->timedout) ++ PPSC_FAIL(DID_TIME_OUT,"Pseudo-interrupt timeout"); ++ ppsc_set_intr(pha,ppsc_engine,ppsc_ready,0); ++ return; ++ } ++ ++ switch (phase) { ++ ++ case PPSC_PH_CMD: ++ ++ if (phase != pha->last_phase) { ++ if (pha->last_phase != PPSC_PH_NONE) ++ PPSC_FAIL(DID_ERROR,"Phase sequence error 1"); ++ pha->cmd_count = 0; ++ if (V_TRACE) { ++ printk("%s: Command to %d (%d): ", ++ pha->device, pha->cur_cmd->device->id, ++ pha->cur_cmd->cmd_len); ++ for (i=0;icur_cmd->cmd_len;i++) ++ printk("%2x ",pha->cur_cmd->cmnd[i]); ++ printk("\n"); ++ } ++ } ++ ++ pha->last_phase = phase; ++ ++ if (pha->cmd_count >= pha->cur_cmd->cmd_len) ++ PPSC_FAIL(DID_ERROR,"Command buffer overrun"); ++ ++ if (!ppsc_slow(pha,&(pha->cur_cmd->cmnd[pha->cmd_count++]))) ++ return; ++ ++ break; ++ ++ case PPSC_PH_READ: ++ case PPSC_PH_WRITE: ++ ++ if (phase != pha->last_phase) { ++ if (pha->last_phase != PPSC_PH_CMD) ++ PPSC_FAIL(DID_ERROR,"Phase sequence error 2"); ++ pha->data_dir = phase & PPSC_IO; ++ pha->data_count = 0; ++ ++ pha->sg_count = pha->cur_cmd->use_sg; ++ if (pha->sg_count) { ++ pha->sg_count--; ++ pha->sg_list = ++ (struct scatterlist *)pha->cur_cmd->request_buffer; ++ pha->cur_buf = page_address(pha->sg_list->page) + pha->sg_list->offset; ++ pha->cur_len = pha->sg_list->length; ++ } else { ++ pha->cur_buf = pha->cur_cmd->request_buffer; ++ pha->cur_len = pha->cur_cmd->request_bufflen; ++ } ++ ++ pha->last_phase = phase; ++ ++ } ++ ++ if ((pha->bulk) && (pha->cur_len > 0 )) { ++ pha->proto->start_block(pha,pha->data_dir); ++ ppsc_transfer(pha); ++ return; ++ } ++ ++ ppsc_update_sg(pha); ++ ++ if (!pha->cur_len) { ++ pha->cur_len = 1; ++ pha->cur_buf = (char *)&i; ++ i = 0x5a; ++ pha->overflow++; ++ } ++ ++ pha->cur_len--; ++ pha->data_count++; ++ ++ if (!ppsc_slow(pha,pha->cur_buf++)) return; ++ ++ break; ++ ++ case PPSC_PH_STAT: ++ ++ if ((pha->last_phase != PPSC_PH_CMD) && ++ (pha->last_phase != PPSC_PH_READ) && ++ (pha->last_phase != PPSC_PH_WRITE)) ++ PPSC_FAIL(DID_ERROR,"Phase sequence error 3"); ++ ++ if ((pha->last_phase != PPSC_PH_CMD) && ++ (V_DEBUG)) { ++ printk("%s: %s%s %d bytes\n", ++ pha->device, ++ pha->bulk?"":"slow ", ++ pha->data_dir?"read":"write", ++ pha->data_count); ++ ++ if (pha->cur_cmd->cmnd[0] == REQUEST_SENSE) { ++ ++ sb = (char *)pha->cur_cmd->request_buffer; ++ printk("%s: Sense key: %x ASC: %x ASCQ: %x\n", ++ pha->device, sb[2] & 0xff, ++ sb[12] & 0xff, sb[13] & 0xff); ++ } ++ } ++ ++ if (pha->overflow) ++ printk("%s: WARNING: data %s overran by %d/%d bytes\n", ++ pha->device,pha->data_dir?"read":"write", ++ pha->overflow,pha->data_count); ++ ++ pha->last_phase = phase; ++ ++ if (!ppsc_slow(pha,&pha->status_byte)) return; ++ ++ break; ++ ++ case PPSC_PH_MSGIN: ++ ++ if (pha->last_phase != PPSC_PH_STAT) ++ PPSC_FAIL(DID_ERROR,"Phase sequence error 4"); ++ ++ pha->last_phase = phase; ++ ++ if (V_FULL) ++ printk("%s: status = %x\n",pha->device,pha->status_byte); ++ ++ if (!ppsc_slow(pha,&pha->message_byte)) return; ++ ++ break; ++ ++ default: ++ ++ PPSC_FAIL(DID_ERROR,"Unexpected bus phase"); ++ ++ } ++ } ++} ++ ++static void ppsc_transfer (PHA *pha) ++{ ++ int i, j; ++ ++ if (pha->timedout) ++ PPSC_FAIL(DID_TIME_OUT,"PDMA timeout"); ++ ++ while(1) { ++ ++ if (!(j=pha->proto->transfer_ready(pha))) { ++ ppsc_set_intr(pha,ppsc_transfer, ++ pha->proto->transfer_ready,0); ++ return; ++ } ++ ++ if (j < 0) { ++ if (V_DEBUG) ++ printk("%s: short transfer\n",pha->device); ++ ppsc_set_intr(pha,ppsc_transfer_done, ++ pha->proto->transfer_done,0); ++ return; ++ } ++ ++ i = pha->proto->transfer_block(pha,pha->cur_buf, ++ pha->cur_len,pha->data_dir); ++ ++ if (V_FULL) ++ printk("%s: Fragment %d\n",pha->device,i); ++ ++ if ((i < 0) || (i > pha->cur_len)) ++ PPSC_FAIL(DID_ERROR,"Block transfer error"); ++ ++ pha->cur_len -= i; ++ pha->cur_buf += i; ++ pha->data_count += i; ++ ++ ppsc_update_sg(pha); ++ ++ if (pha->cur_len == 0 ) { ++ ppsc_set_intr(pha,ppsc_transfer_done, ++ pha->proto->transfer_done,0); ++ return; ++ } ++ } ++} ++ ++static void ppsc_transfer_done (PHA *pha) ++{ ++ if (pha->timedout) PPSC_FAIL(DID_TIME_OUT,"PDMA done timeout"); ++ ++ pha->proto->end_block(pha,pha->data_dir); ++ ppsc_engine(pha); ++} ++ ++static int ppsc_slow (PHA *pha, char *val) ++{ ++ int k; ++ ++ pha->proto->slow_start(pha,val); ++ ++ k = 0; ++ while (k++ < PPSC_SLOW_LOOPS) ++ if (pha->proto->slow_done(pha)) { ++ pha->proto->slow_end(pha); ++ return 1; ++ } ++ ++ ppsc_set_intr(pha,ppsc_slow_done,pha->proto->slow_done,0); ++ return 0; ++} ++ ++static void ppsc_slow_done (PHA *pha) ++{ ++ int k; ++ ++ if (pha->timedout) PPSC_FAIL(DID_TIME_OUT,"PIO timeout"); ++ ++ pha->proto->slow_end(pha); ++ ++ k = 0; ++ while (k++ < PPSC_SLOW_LOOPS) ++ if (ppsc_ready(pha)) break; ++ ++ ppsc_engine(pha); ++} ++ ++static void ppsc_try_again (unsigned long data ) ++{ ++ PHA *pha = (PHA *)data; ++ ++ ppsc_do_claimed(pha,ppsc_start); ++} ++ ++static void ppsc_cleanup (PHA *pha) ++{ ++ struct scsi_cmnd *cmd; ++ void (*done)(struct scsi_cmnd *); ++ unsigned long saved_flags; ++ ++ pha->tot_bytes += pha->data_count; ++ ++ cmd = pha->cur_cmd; ++ done = pha->done; ++ cmd->result = pha->return_code; ++ pha->cur_cmd = 0; ++ ++ pha->proto->deselect(pha); ++ pha->proto->disconnect(pha); ++ ++ if (V_FULL) printk("%s: releasing parport\n",pha->device); ++ ++ ppsc_unclaim(pha); ++ ++ if (pha->abort_flag) { ++ ++ if (V_DEBUG) printk("%s: command aborted !\n",pha->device); ++ ++ return; /* kill the thread */ ++ } ++ ++ if (V_DEBUG) ++ printk("%s: Command status %08x last phase %o\n", ++ pha->device,cmd->result,pha->last_phase); ++ ++ if (status_byte(pha->return_code) == BUSY) { ++ ++ pha->cur_cmd = cmd; ++ ++ if (V_FULL) ++ printk("%s: BUSY, sleeping before retry ...\n", ++ pha->device); ++ ++ init_timer (&pha->sleeper); ++ pha->sleeper.data = (unsigned long) pha; ++ pha->sleeper.function = ppsc_try_again; ++ pha->sleeper.expires = jiffies + PPSC_BUSY_SNOOZE; ++ add_timer(&pha->sleeper); ++ ++ return; ++ ++ } ++ ++ pha->tot_cmds++; ++ ++ if ((cmd->cmnd[0] != REQUEST_SENSE) && ++ (status_byte(pha->return_code) == CHECK_CONDITION)) { ++ ++ if (V_FULL) ++ printk("%s: Requesting sense data\n",pha->device); ++ ++ cmd->cmnd[0] = REQUEST_SENSE; ++ cmd->cmnd[1] &= 0xe0; ++ cmd->cmnd[2] = 0; ++ cmd->cmnd[3] = 0; ++ cmd->cmnd[4] = sizeof(cmd->sense_buffer); ++ cmd->cmnd[5] = 0; ++ cmd->cmd_len = 6; ++ cmd->use_sg = 0; ++ cmd->request_buffer = (char *) cmd->sense_buffer; ++ cmd->request_bufflen = sizeof(cmd->sense_buffer); ++ ++ pha->cur_cmd = cmd; ++ ppsc_do_claimed(pha,ppsc_start); ++ ++ return; ++ } ++ ++ if (done) { ++ ++ spin_lock_irqsave(pha->host_ptr->host_lock,saved_flags); ++ done(cmd); ++ spin_unlock_irqrestore(pha->host_ptr->host_lock,saved_flags); ++ ++ } ++ ++} ++ ++static void ppsc_fail_command (PHA *pha, int err_code, char *msg) ++{ ++ int bs; ++ ++ pha->tot_errs++; ++ ++ bs = pha->proto->get_bus_status(pha); ++ ++ pha->return_code = err_code << 16; ++ if (!pha->quiet) ++ printk("%s: %s, bs=%o cb=%d db=%d bu=%d sg=%d " ++ "rd=%d lp=%o pe=%d cc=%d\n", ++ pha->device, msg, bs, ++ pha->cmd_count, pha->data_count, ++ pha->bulk, pha->sg_count, pha->data_dir, ++ pha->last_phase, pha->protocol_error, pha->tot_cmds); ++ ++ ppsc_cleanup(pha); ++} ++ ++static int ppsc_ready (PHA *pha) ++{ ++ int bs; ++ ++ if (pha->abort_flag || pha->protocol_error) return 1; ++ bs = pha->proto->get_bus_status(pha); ++ ++ if ( (bs & (PPSC_REQ|PPSC_BSY)) != PPSC_BSY) return 1; ++ ++ return 0; ++} ++ ++int ppsc_abort (struct scsi_cmnd * cmd) ++{ ++ PHA *pha = (PHA *)cmd->device->host->hostdata[0]; ++ ++ printk("%s: Command abort not supported\n",pha->device); ++ return FAILED; ++} ++ ++static void ppsc_reset_pha (PHA *pha) ++{ ++ if (!pha->proto->reset_bus) { ++ printk("%s: No reset method available\n",pha->device); ++ return; ++ } ++ ++ ppsc_claim(pha); ++ pha->proto->connect(pha); ++ pha->proto->reset_bus(pha); ++ scsi_sleep(4*HZ); ++ pha->proto->disconnect(pha); ++ ppsc_unclaim(pha); ++ ++ if (!pha->quiet) printk("%s: Bus reset\n",pha->device); ++} ++ ++int ppsc_reset (struct scsi_cmnd * cmd) ++{ ++ PHA *pha = (PHA *)cmd->device->host->hostdata[0]; ++ int k = 0; ++ ++ if (!pha->proto->reset_bus) ++ return FAILED; ++ ++ if (pha->cur_cmd) ++ pha->abort_flag = PPSC_DO_RESET; ++ ++ while (pha->cur_cmd && (k < PPSC_RESET_TMO)) { ++ scsi_sleep(HZ/10); ++ k += HZ/10; ++ } ++ ++ if (pha->cur_cmd) { ++ printk("%s: Driver won't give up for reset\n",pha->device); ++ return FAILED; ++ } ++ ++ ppsc_reset_pha(pha); ++ ++ return SUCCESS; ++} ++ ++#define PROCIN(n,var) \ ++ if ((length>n+1)&&(strncmp(buffer,#var"=",n+1)==0)) { \ ++ pha->var = simple_strtoul(buffer+n+1,NULL,0); \ ++ return length; \ ++ } ++ ++#define PROCOUT(fmt,val) len+=sprintf(buffer+len,fmt"\n",val); ++ ++int ppsc_proc_info(struct Scsi_Host *p, char *buffer, char **start, off_t offset, ++ int length, int inout) ++{ ++ int len = 0; ++ PHA *pha; ++ ++ if (!p) return 0; /* should never happen */ ++ pha = (PHA *)p->hostdata[0]; ++ ++ if (inout) { ++ ++ PROCIN(4,mode); ++ PROCIN(5,delay); ++ PROCIN(7,verbose); ++ PROCIN(10,abort_flag); ++ PROCIN(4,nice); ++ ++ return (-EINVAL); ++ } ++ ++ PROCOUT("ident: %s",pha->ident); ++ PROCOUT("base port: 0x%03x",pha->port); ++ PROCOUT("mode: %d",pha->mode); ++ if (pha->proto->mode_names) ++ PROCOUT("mode name: %s",pha->proto->mode_names[pha->mode]); ++ PROCOUT("delay: %d",pha->delay); ++ PROCOUT("nice: %d",pha->nice); ++ PROCOUT("verbose: %d",pha->verbose); ++ PROCOUT("quiet: %d",pha->quiet); ++ PROCOUT("tot_cmds: %d",pha->tot_cmds); ++ PROCOUT("tot_bytes: %ld",pha->tot_bytes); ++ PROCOUT("tot_errs: %d",pha->tot_errs); ++ ++ if (pha->pardev) { ++ PROCOUT("parport device: %s",pha->parname); ++ PROCOUT("claimed: %d",pha->claimed); ++ } ++ if (V_DEBUG) { ++ PROCOUT("then: %ld",pha->then); ++ PROCOUT("timeout: %ld",pha->timeout); ++ PROCOUT("now: %ld",jiffies); ++ PROCOUT("timer active: %d",pha->timer_active); ++ PROCOUT("wq_active: %d",pha->wq_active); ++ PROCOUT("abort_flag: %d",pha->abort_flag); ++ PROCOUT("return_code: %08x",pha->return_code); ++ PROCOUT("last_phase: %o",pha->last_phase); ++ PROCOUT("cmd_count: %d",pha->cmd_count); ++ PROCOUT("data_count: %d",pha->data_count); ++ PROCOUT("data_dir: %d",pha->data_dir); ++ PROCOUT("bulk: %d",pha->bulk); ++ PROCOUT("tlen: %d",pha->tlen); ++ PROCOUT("overflow: %d",pha->overflow); ++ } ++ ++ if (offset > len) return 0; ++ ++ *start = buffer+offset; len -= offset; ++ if (len > length) len = length; ++ return len; ++} ++ ++int ppsc_biosparam (struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int ip[]) ++{ ++ ip[0] = 0x40; ++ ip[1] = 0x20; ++ ip[2] = (capacity +1) / (ip[0] * ip[1]); ++ if (ip[2] > 1024) { ++ ip[0] = 0xff; ++ ip[1] = 0x3f; ++ ip[2] = (capacity +1) / (ip[0] * ip[1]); ++ if (ip[2] > 1023) ++ ip[2] = 1023; ++ } ++ return 0; ++} ++ ++static int ppsc_inquire (PHA *pha, int target, char *buf) ++{ ++ char inq[6] = {0x12,0,0,0,36,0}; ++ int i; ++ struct scsi_cmnd cmd; ++ struct scsi_device dev; ++ ++ dev.host = pha->host_ptr; ++ dev.id = target; ++ cmd.device = &dev; ++ cmd.cmd_len = 6; ++ for (i=0;i<6;i++) cmd.cmnd[i] = inq[i]; ++ cmd.use_sg = 0; ++ cmd.request_buffer = buf; ++ cmd.request_bufflen = 36; ++ ++ return ppsc_command(&cmd); ++} ++ ++static void ppsc_test_mode (PHA *pha, int mode) ++{ ++ int i, t, s, e, f, g, ok, old_mode; ++ char ibuf[38]; ++ ++ if ((mode >= pha->proto->epp_first) && ++ !(pha->pardev->port->modes & PARPORT_MODE_EPP)) ++ return; ++ ++ old_mode = pha->mode; ++ pha->mode = mode; ++ ++ e = -1; f = -1; g = 0; ++ ++ if (pha->proto->test_proto) { ++ ppsc_claim(pha); ++ e = pha->proto->test_proto(pha); ++ ppsc_unclaim(pha); ++ } ++ ++ if (e <= 0) { ++ f = 0; ++ for (t=0;t<8;t++) { ++ s = ppsc_inquire(pha,t,ibuf); ++ if (s == DID_NO_CONNECT << 16) continue; ++ if (s) { ++ f++; ++ break; ++ } ++ if (V_FULL) { ++ for (i=0;i<36;i++) ++ if ((ibuf[i] < ' ') || (ibuf[i] >= '~')) ibuf[i] = '.'; ++ ibuf[36] = 0; ++ printk("%s: port 0x%x mode %d targ %d: %s\n", ++ pha->device,pha->port,mode,t,ibuf); ++ } ++ g++; ++ } ++ if (f) ppsc_reset_pha(pha); ++ } ++ ++ ok = (e<=0) && (f == 0); ++ ++ if (!ok) pha->mode = old_mode; ++ ++ if (V_PROBE) printk("%s: port 0x%3x mode %d test %s (%d,%d,%d)\n", ++ pha->device,pha->port,mode,ok?"passed":"failed",e,f,g); ++} ++ ++ ++int ppsc_release_pha (PHA *pha) ++{ ++ if (pha->proto->release) pha->proto->release(pha); ++ ++ ppsc_unregister_parport(pha); ++ ++ /* MOD_DEC_USE_COUNT; */ ++ ++ return 0; ++} ++ ++ ++int ppsc_detect (PSP *proto, Scsi_Host_Template *tpnt, int verbose) ++{ ++ int i, m, p, d, n, s, z; ++ struct ppsc_port_list_struct *next_port = NULL; /* shut gcc up */ ++ int user_specified = 1; ++ PHA *pha; ++ int host_count = 0; ++ struct Scsi_Host *hreg; ++ ++ m = 0; ++ for (i=0;i<4;i++) if ((*proto->params[i])[PPSC_PARM_PORT] != -1) m++; ++ ++ if (!m) { ++ /* Just take parports from the list as they come. */ ++ next_port = ppsc_port_list; ++ user_specified = 0; ++ } ++ ++ tpnt->this_id = PPSC_INITIATOR; ++ ++ for (i=0;i<4;i++) { ++ if (!user_specified) { ++ if (!next_port) ++ break; ++ ++ p = next_port->port->number; ++ next_port = next_port->next; ++ } ++ else { ++ p = (*proto->params[i])[PPSC_PARM_PORT]; ++ if (p < 0) ++ continue; ++ } ++ ++ m = (*proto->params[i])[PPSC_PARM_MODE]; ++ n = (*proto->params[i])[PPSC_PARM_NICE]; ++ if (n == -1) n = PPSC_DEF_NICE; ++ d = (*proto->params[i])[PPSC_PARM_DLY]; ++ if (d == -1) d = proto->default_delay; ++ s = (*proto->params[i])[PPSC_PARM_SGTS]; ++ if (s == -1) s = proto->default_sg_tablesize; ++ z = (*proto->params[i])[PPSC_PARM_SLOW]; ++ if (z == -1) z = 0; ++ ++ /* MOD_INC_USE_COUNT; */ ++ ++ pha = &(((*proto->hosts)[i])); ++ ++ pha->proto = proto; ++ ++ pha->port = p; ++ pha->delay = d; ++ pha->nice = n; ++ ++ d = sizeof(pha->device)-3; ++ p = strlen(tpnt->name); ++ if (p > d) p = d; ++ for (n=0;ndevice[n] = tpnt->name[n]; ++ pha->device[p] = '.'; ++ pha->device[p+1] = '0' + i; ++ pha->device[p+2] = 0; ++ ++ INIT_WORK(&pha->wq, ppsc_tq_int, pha); ++ ++ init_timer (&pha->timer); ++ pha->timer.data = (unsigned long) pha; ++ pha->timer.function = ppsc_timer_int; ++ ++ init_waitqueue_head (&pha->parq); ++ pha->pardev = NULL; ++ pha->claimed = 0; ++ pha->claim_cont = NULL; ++ pha->timer_active = 0; ++ pha->wq_active = 0; ++ pha->timedout = 0; ++ ++ pha->cur_cmd = NULL; ++ pha->done = NULL; ++ pha->abort_flag = 0; ++ pha->protocol_error = 0; ++ pha->tot_errs = 0; ++ pha->tot_cmds = 0; ++ pha->tot_bytes = 0; ++ ++ for (n=0;n<8;n++) pha->private[n] = 0; ++ ++ pha->slow_targets = z; ++ ++ if (ppsc_register_parport(pha,verbose)) { ++ /* MOD_DEC_USE_COUNT; */ ++ continue; ++ } ++ ++ pha->proto->init(pha); ++ ++ pha->verbose = verbose; ++ pha->quiet = 1; /* no errors until probe over */ ++ if (V_FULL) pha->quiet = 0; /* unless we want them ... */ ++ ++ pha->tmo = PPSC_PROBE_TMO; ++ ++ hreg = scsi_register(tpnt,sizeof(PHA*)); ++ hreg->dma_channel = -1; ++ hreg->n_io_port = 0; ++ hreg->unique_id = (int) pha; /* What should we put in here??? */ ++ hreg->sg_tablesize = s; ++ hreg->hostdata[0]=(unsigned long)pha; /* Will be our pointer */ ++ ++ pha->host_ptr = hreg; ++ ++ pha->mode = -1; ++ ++ if (m == -1) for (m=0;mnum_modes;m++) ++ ppsc_test_mode(pha,m); ++ else ppsc_test_mode(pha,m); ++ ++ if (pha->mode != -1) { ++ ++ pha->quiet = 0; /* enable PPSC_FAIL msgs */ ++ pha->tmo = PPSC_GEN_TMO; ++ host_count++; ++ ++ printk("%s: %s at 0x%3x mode %d (%s) dly %d nice %d sg %d\n", ++ pha->device, ++ pha->ident, ++ pha->port, ++ pha->mode, ++ (pha->proto->mode_names)? ++ pha->proto->mode_names[pha->mode]:"", ++ pha->delay, ++ pha->nice, ++ hreg->sg_tablesize); ++ ++ } else { ++ ++ scsi_unregister(hreg); ++ ppsc_release_pha(pha); ++ ++ } ++ } ++ return host_count; ++} ++ ++int ppsc_release (struct Scsi_Host *host) ++{ ++ PHA *pha = (PHA *) host->hostdata[0]; ++ ++ return ppsc_release_pha(pha); ++} ++ ++int ppsc_initialise (void) ++{ ++ int i; ++ ++ for (i=0;i<256;i++) ppsc_bulk_map[i] = 0; ++ ++/* commands marked in this map will use pseudo-DMA transfers, while ++ the rest will use the slow handshaking. ++*/ ++ ++ ppsc_bulk_map[READ_6] = 1; ++ ppsc_bulk_map[READ_10] = 1; ++ ppsc_bulk_map[READ_BUFFER] = 1; ++ ppsc_bulk_map[WRITE_6] = 1; ++ ppsc_bulk_map[WRITE_10] = 1; ++ ppsc_bulk_map[WRITE_BUFFER] = 1; ++ ++ if (parport_register_driver (&ppsc_driver)) { ++ printk (KERN_WARNING "ppscsi: couldn't register driver\n"); ++ return -EIO; ++ } ++ ++ printk("ppSCSI %s (%s) installed\n",PPSC_VERSION,PPSC_H_VERSION); ++ return 0; ++} ++ ++#ifdef MODULE ++ ++int init_module (void) ++{ ++ return ppsc_initialise(); ++} ++ ++void cleanup_module (void) ++{ ++ struct ppsc_port_list_struct *ports, *next; ++ parport_unregister_driver (&ppsc_driver); ++ for (ports = ppsc_port_list; ports; ports = next) { ++ next = ports->next; ++ parport_put_port (ports->port); ++ kfree (ports); ++ } ++} ++ ++MODULE_LICENSE("GPL"); ++ ++#endif ++ ++EXPORT_SYMBOL(ppsc_make_map); ++EXPORT_SYMBOL(ppsc_queuecommand); ++EXPORT_SYMBOL(ppsc_abort); ++EXPORT_SYMBOL(ppsc_reset); ++EXPORT_SYMBOL(ppsc_proc_info); ++EXPORT_SYMBOL(ppsc_biosparam); ++EXPORT_SYMBOL(ppsc_detect); ++EXPORT_SYMBOL(ppsc_release); ++ ++/* end of ppscsi.c */ +--- /dev/null ++++ b/drivers/scsi/ppscsi.h +@@ -0,0 +1,356 @@ ++#ifndef _PPSC_H ++#define _PPSC_H ++ ++/* ++ ppscsi.h (c) 1999 Grant Guenther ++ Under the terms of the GNU public license. ++ ++ This header file defines a common interface for constructing ++ low-level SCSI drivers for parallel port SCSI adapters. ++ ++*/ ++ ++#define PPSC_H_VERSION "0.92" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "scsi.h" ++#include "hosts.h" ++ ++ ++/* ppscsi global functions */ ++ ++extern void ppsc_make_map( char map[256], char key[5], int inv); ++ ++extern int ppsc_proc_info(struct Scsi_Host *, char *,char **,off_t,int,int); ++extern int ppsc_command(struct scsi_cmnd *); ++extern int ppsc_queuecommand(struct scsi_cmnd *, void (* done)(struct scsi_cmnd *)); ++extern int ppsc_abort(struct scsi_cmnd *); ++extern int ppsc_reset(struct scsi_cmnd *); ++extern int ppsc_biosparam(struct scsi_device *, struct block_device *, sector_t capacity, int[]); ++extern int ppsc_release(struct Scsi_Host *); ++ ++#ifndef PPSC_BASE ++ ++/* imports for hosts.c */ ++ ++#ifdef CONFIG_PPSCSI_T348 ++extern int t348_detect( Scsi_Host_Template *); ++#endif ++ ++#ifdef CONFIG_PPSCSI_T358 ++extern int t358_detect( Scsi_Host_Template *); ++#endif ++ ++#ifdef CONFIG_PPSCSI_ONSCSI ++extern int onscsi_detect( Scsi_Host_Template *); ++#endif ++ ++#ifdef CONFIG_PPSCSI_EPST ++extern int epst_detect( Scsi_Host_Template *); ++#endif ++ ++#ifdef CONFIG_PPSCSI_EPSA2 ++extern int epsa2_detect( Scsi_Host_Template *); ++#endif ++ ++#ifdef CONFIG_PPSCSI_VPI0 ++extern int vpi0_detect( Scsi_Host_Template *); ++#endif ++ ++#ifdef CONFIG_PPSCSI_SPARCSI ++extern int sparcsi_detect( Scsi_Host_Template *); ++#endif ++ ++#endif ++ ++#define PPSC_TEMPLATE(proto){ \ ++ .name = #proto, \ ++ .detect = proto##_detect, \ ++ .release = ppsc_release, \ ++ .proc_name = #proto, \ ++ .proc_info = ppsc_proc_info, \ ++ .queuecommand = ppsc_queuecommand, \ ++ .eh_abort_handler = ppsc_abort, \ ++ .eh_bus_reset_handler = ppsc_reset, \ ++ .eh_host_reset_handler = ppsc_reset, \ ++ .bios_param = ppsc_biosparam, \ ++ .can_queue = 1, \ ++ .sg_tablesize = SG_NONE, \ ++ .cmd_per_lun = 1, \ ++ .use_clustering = DISABLE_CLUSTERING \ ++} ++ ++/* types used by the actual driver modules */ ++ ++#ifdef PPSC_BASE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++struct setup_tab_t { ++ ++ char *tag; /* variable name */ ++ int size; /* number of elements in array */ ++ int *iv; /* pointer to variable */ ++}; ++ ++typedef struct setup_tab_t STT; ++ ++extern void ppsc_gen_setup( STT t[], int n, char *ss ); ++ ++typedef struct ppsc_host_adapter PHA; ++ ++struct ppsc_host_adapter { ++ ++ char ident[80]; /* Adapter name and version info */ ++ ++ char device[12]; /* device name for messages */ ++ ++ struct Scsi_Host *host_ptr; /* SCSI host structure */ ++ struct ppsc_protocol *proto; /* adapter protocol */ ++ ++ int port; /* parallel port base address */ ++ int mode; /* transfer mode in use */ ++ int delay; /* parallel port settling delay */ ++ int saved_r0; /* saved port state */ ++ int saved_r2; /* saved port state */ ++ ++ int reserved; /* number of ports reserved */ ++ int tmo; /* default command timeout */ ++ int verbose; /* logging level */ ++ int quiet; /* do not log PPSC_FAIL msgs */ ++ ++ int slow_targets; /* bit mask for disabling block mode */ ++ ++ wait_queue_head_t parq; /* semaphore for parport sharing */ ++ struct pardevice *pardev; /* pointer to pardevice */ ++ const char *parname; /* parport name */ ++ int claimed; /* parport has been claimed */ ++ void (*claim_cont)(PHA *); /* continuation for parport wait */ ++ ++ void (*continuation)(PHA *); /* next "interrupt" handler */ ++ int (*ready)(PHA *); /* current ready test */ ++ unsigned long then; /* jiffies at start of last wait */ ++ unsigned long timeout; /* when to timeout this wait */ ++ int timedout; /* timeout was seen */ ++ int timer_active; /* we're using a timer */ ++ int wq_active; /* we have a task queued */ ++ int nice; /* tune the CPU load */ ++ struct timer_list timer; /* timer queue element */ ++ struct work_struct wq; /* task queue element */ ++ ++ int private[8]; /* for the protocol layer, if needed */ ++ char *priv_ptr; ++ int priv_flag; ++ ++ struct scsi_cmnd *cur_cmd; /* current command on this host */ ++ void (*done)(struct scsi_cmnd *); /* current "done" function */ ++ ++ int overflow; /* excess bytes transferred */ ++ int bulk; /* should we use block mode ? */ ++ int tlen; /* total transfer length */ ++ int abort_flag; /* abort=1 reset=2 requested */ ++ int return_code; /* build return value here */ ++ ++ struct scatterlist *sg_list; /* current fragment, if any */ ++ int sg_count; /* remaining fragments */ ++ char *cur_buf; /* current buffer pointer */ ++ int cur_len; /* remaining bytes in buffer */ ++ ++ struct timer_list sleeper; /* for BUSY handling */ ++ ++ int last_phase; /* to detect phase changes */ ++ char message_byte; ++ char status_byte; ++ ++ int cmd_count; /* bytes of command transfered */ ++ int data_count; /* bytes of data transferred */ ++ int data_dir; /* direction of transfer */ ++ ++ int tot_cmds; /* number of commands processed */ ++ long tot_bytes; /* total bytes transferred */ ++ int tot_errs; /* number of failed commands */ ++ ++ int protocol_error; /* Some protocols can set this ++ != zero to signal a fatal error ++ we report it and expect to die ++ */ ++}; ++ ++/* constants for 'verbose' */ ++ ++#define PPSC_VERB_NORMAL 0 ++#define PPSC_VERB_PROBE 1 ++#define PPSC_VERB_TRACE 2 ++#define PPSC_VERB_DEBUG 3 ++#define PPSC_VERB_FULL 4 ++ ++#define V_PROBE (pha->verbose >= PPSC_VERB_PROBE) ++#define V_TRACE (pha->verbose >= PPSC_VERB_TRACE) ++#define V_DEBUG (pha->verbose >= PPSC_VERB_DEBUG) ++#define V_FULL (pha->verbose >= PPSC_VERB_FULL) ++ ++/* constants for abort_flag */ ++ ++#define PPSC_DO_ABORT 1 ++#define PPSC_DO_RESET 2 ++ ++ ++struct ppsc_protocol { ++ ++ int (*params[4])[8]; /* hostN tuning parameters */ ++ ++ PHA (*hosts)[4]; /* actual PHA structs */ ++ ++ int num_modes; /* number of modes*/ ++ int epp_first; /* modes >= this use 8 ports */ ++ int default_delay; /* delay parameter if not specified */ ++ ++ int can_message; /* adapter can send/rcv SCSI msgs */ ++ int default_sg_tablesize; /* sg_tablesize if not specified */ ++ ++ char **mode_names; /* printable names of comm. modes */ ++ ++/* first two functions are NOT called with the port claimed. */ ++ ++ void (*init)(PHA *); /* (pha) ++ protocol initialisation ++ should fill in pha->ident */ ++ void (*release)(PHA *); /* (pha) optional ++ protocol no longer in use */ ++ void (*connect)(PHA *); /* (pha) ++ connect to adapter */ ++ void (*disconnect)(PHA *); /* (pha) ++ release adapter */ ++ int (*test_proto)(PHA *); /* (pha) optional ++ test protocol in current settings, ++ returns error count */ ++ int (*select)(PHA *,int,int); /* (pha,initiator,target) ++ start artibration and selection ++ 0 = OK, -1 = arb. failed */ ++ int (*test_select)(PHA *); /* (pha) ++ test for selection to complete ++ 1 = OK, 0 try again */ ++ void (*select_finish)(PHA *); /* (pha) optional ++ called after successful select */ ++ void (*deselect)(PHA *); /* (pha) ++ release SCSI bus */ ++ int (*get_bus_status)(PHA *); /* (pha) ++ return (REQ,BSY,MSG,C/D,I/O) */ ++ void (*slow_start)(PHA *,char *); /* (pha,byte) ++ start transfer of one byte using ++ explicit handshaking */ ++ int (*slow_done)(PHA *); /* (pha) ++ has the device acked the byte ? */ ++ void (*slow_end)(PHA *); /* (pha) ++ shut down the slow transfer */ ++ void (*start_block)(PHA *,int); /* (pha,read) ++ start data transfer */ ++ int (*transfer_block)(PHA *,char *,int,int); ++ /* (pha,buf,len,read) ++ transfer as much as possible and ++ return count of bytes ++ can return -1 if error detected */ ++ int (*transfer_ready)(PHA *pha);/* (pha) ++ can we go again yet ? ++ >0 = yes, 0 = try again, -1 = done */ ++ int (*transfer_done)(PHA *pha); /* (pha) ++ has all data been flushed ? ++ 1 = yes, 0 = try again */ ++ void (*end_block)(PHA *,int); /* (pha,read) ++ shut down block transfer */ ++ void (*reset_bus)(PHA *); /* (pha) optional ++ reset SCSI bus if possible */ ++ ++}; ++ ++/* constants for the params array */ ++ ++#define PPSC_PARM_PORT 0 ++#define PPSC_PARM_MODE 1 ++#define PPSC_PARM_DLY 2 ++#define PPSC_PARM_NICE 3 ++#define PPSC_PARM_SGTS 4 ++#define PPSC_PARM_SLOW 5 ++ ++/* constants for get_bus_status */ ++ ++#define PPSC_REQ 16 ++#define PPSC_BSY 8 ++#define PPSC_MSG 4 ++#define PPSC_CD 2 ++#define PPSC_IO 1 ++ ++/* phases */ ++ ++#define PPSC_PH_NONE 0 ++#define PPSC_PH_WRITE (PPSC_REQ|PPSC_BSY) ++#define PPSC_PH_READ (PPSC_PH_WRITE|PPSC_IO) ++#define PPSC_PH_CMD (PPSC_PH_WRITE|PPSC_CD) ++#define PPSC_PH_STAT (PPSC_PH_READ|PPSC_CD) ++#define PPSC_PH_MSGIN (PPSC_PH_STAT|PPSC_MSG) ++ ++typedef struct ppsc_protocol PSP; ++ ++extern int ppsc_detect( PSP *, Scsi_Host_Template *, int); ++ ++#ifdef PPSC_HA_MODULE ++ ++static int verbose = PPSC_VERB_NORMAL; ++ ++static int host0[8] = {-1,-1,-1,-1,-1,-1,-1,-1}; ++static int host1[8] = {-1,-1,-1,-1,-1,-1,-1,-1}; ++static int host2[8] = {-1,-1,-1,-1,-1,-1,-1,-1}; ++static int host3[8] = {-1,-1,-1,-1,-1,-1,-1,-1}; ++ ++#ifndef MODULE ++ ++static STT stt[4] = { {"host0",8,host0}, ++ {"host1",8,host1}, ++ {"host2",8,host2}, ++ {"host3",8,host3} }; ++#endif ++ ++MODULE_PARM(host0,"1-8i"); ++MODULE_PARM(host1,"1-8i"); ++MODULE_PARM(host2,"1-8i"); ++MODULE_PARM(host3,"1-8i"); ++MODULE_PARM(verbose,"i"); ++ ++static struct ppsc_host_adapter host_structs[4]; ++ ++#define delay_p (pha->delay?udelay(pha->delay):0) ++#define out_p(offs,byte) outb(byte,pha->port+offs); delay_p; ++#define in_p(offs) (delay_p,inb(pha->port+offs)) ++ ++#define w0(byte) do {out_p(0,byte);} while (0) ++#define r0() (in_p(0) & 0xff) ++#define w1(byte) do {out_p(1,byte);} while (0) ++#define r1() (in_p(1) & 0xff) ++#define w2(byte) do {out_p(2,byte);} while (0) ++#define r2() (in_p(2) & 0xff) ++#define w3(byte) do {out_p(3,byte);} while (0) ++#define w4(byte) do {out_p(4,byte);} while (0) ++#define r4() (in_p(4) & 0xff) ++#define w4w(data) do {outw(data,pha->port+4); delay_p;} while (0) ++#define w4l(data) do {outl(data,pha->port+4); delay_p;} while (0) ++#define r4w() (delay_p,inw(pha->port+4)&0xffff) ++#define r4l() (delay_p,inl(pha->port+4)&0xffffffff) ++ ++#endif /* PPSC_HA_MODULE */ ++#endif /* PPSC_BASE */ ++#endif /* _PPSC_H */ ++ ++/* end of ppscsi.h */ ++ +--- /dev/null ++++ b/drivers/scsi/onscsi.c +@@ -0,0 +1,544 @@ ++/* ++ onscsi.c (c) 1999 Grant Guenther ++ ++ This is the ppSCSI protocol module for the OnSpec 90c26 ++ in its SCSI adapter mode. ++*/ ++ ++#define ONSCSI_VERSION "0.91" ++ ++#define PPSC_BASE ++#define PPSC_HA_MODULE ++ ++#include "ppscsi.h" ++ ++#define ONSCSI_REP_COUNT 256 ++ ++#define TOGL pha->private[0] ++ ++static char onscsi_map[256]; /* status bits permutation */ ++ ++static void onscsi_init (PHA *pha) ++{ ++ ++/* { REQ, BSY, MSG, CD, IO} */ ++ ++ char key[5] = {0x10,0x01,0x20,0x40,0x80}; ++ ++ ppsc_make_map(onscsi_map,key,0); ++ sprintf(pha->ident,"onscsi %s (%s), OnSpec 90c26", ++ ONSCSI_VERSION,PPSC_H_VERSION); ++} ++ ++#define j44(a,b) ((b&0xf0)|((a>>4)&0x0f)) ++ ++#define CMD(x) w0(x);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4); ++#define VAL(v) w0(v);w2(5);w2(7);w2(5);w2(4); ++ ++static inline void onscsi_opcode (PHA *pha, int x ) ++{ ++ if (pha->mode < 2) { ++ CMD(x); ++ } else { ++ w3(x); ++ } ++} ++ ++#define OP(x) onscsi_opcode(pha,x) ++#define FULLBYTE (pha->mode > 0) ++ ++static void onscsi_write_regr (PHA *pha, int r, int v) ++{ ++ onscsi_opcode(pha,r); ++ ++ if (pha->mode < 2) { ++ VAL(v); ++ } else { ++ w2(5); w4(v); w2(4); ++ } ++} ++ ++static inline int onscsi_read_nybble (PHA *pha) ++{ ++ int a, b; ++ ++ w2(6); a = r1(); w2(4); ++ w2(6); b = r1(); w2(4); ++ ++ return j44(a,b); ++} ++ ++static int onscsi_read_regr (PHA *pha, int r) ++{ ++ int v = -1; ++ ++ onscsi_opcode(pha,r); ++ ++ switch (pha->mode) { ++ ++ case 0: v = onscsi_read_nybble(pha); ++ break; ++ ++ case 1: w2(0x26); v = r0(); w2(4); ++ break; ++ ++ case 2: ++ case 3: ++ case 4: w2(0x24); v = r4(); w2(4); ++ break; ++ ++ } ++ ++ return v; ++} ++ ++#define RR(r) onscsi_read_regr(pha,r) ++#define WR(r,v) onscsi_write_regr(pha,r,v) ++ ++static void onscsi_write_block (PHA *pha, char *buf, int n) ++{ ++ int i; ++ ++ w2(5+TOGL); ++ ++ switch (pha->mode) { ++ ++ case 0: ++ case 1: for (i=0;imode) { ++ ++ case 0: w2(4); ++ for (i=0;isaved_r0 = r0(); ++ pha->saved_r2 = r2(); ++ ++ CPP(0x20,4); ++ ++ CMD(2); VAL(0); ++ CMD(2); VAL(FULLBYTE); ++ ++ WR(2,FULLBYTE); ++} ++ ++static void onscsi_disconnect (PHA *pha) ++{ ++ WR(3,0); WR(7,0x48); ++ OP(4); ++ CPP(0x30,pha->saved_r2); ++ ++ w0(pha->saved_r0); ++ w2(pha->saved_r2); ++} ++ ++static int onscsi_test_proto (PHA *pha) ++{ ++ int i, k, j; ++ char wbuf[16], rbuf[16]; ++ int e = 0; ++ ++ pha->saved_r0 = r0(); ++ pha->saved_r2 = r2(); ++ ++ CPP(0x30,pha->saved_r2); ++ CPP(0x0,pha->saved_r2); ++ ++ w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff); ++ i = ((r1() & 0xf0) << 4); w0(0x87); ++ i |= (r1() & 0xf0); w0(0x78); ++ w0(0x20);w2(5); ++ i |= ((r1() & 0xf0) >> 4); ++ w2(4);w0(0xff); ++ ++ if (V_PROBE) printk("%s: signature 0x%x\n",pha->device,i); ++ ++ if (i == 0xb5f) { ++ ++ CMD(2); VAL(FULLBYTE); ++ ++ w2(4); w2(0xc); udelay(100); w2(4); udelay(100); ++ ++ CMD(2); VAL(0); ++ CMD(2); VAL(FULLBYTE); ++ ++ WR(2,FULLBYTE); ++ ++ k = RR(4); ++ ++ if (V_PROBE) ++ printk("%s: OnSpec 90c26 version %x\n",pha->device,k); ++ } ++ ++ CPP(0x30,pha->saved_r2); ++ ++ w0(pha->saved_r0); ++ w2(pha->saved_r2); ++ ++ if (i != 0xb5f) return 1; ++ ++ onscsi_connect(pha); ++ ++ for (k=0;kmode == 0) WR(2,0x30); ++ if (pha->mode == 1) WR(2,0x10); ++ ++ WR(3,0); WR(7,0x48); ++ ++ WR(3,1); WR(7,0x48); OP(5); ++ TOGL = 0; ++ onscsi_write_block(pha,wbuf,16); ++ w2(4); ++ ++ if (pha->mode == 0) WR(2,0); ++ if (pha->mode == 1) WR(2,0x11); ++ ++ WR(3,5); WR(7,0x48); OP(5); ++ TOGL = 0; ++ onscsi_read_block(pha,rbuf,16); ++ w2(4); ++ ++ for (j=0;j<16;j++) ++ if (rbuf[j] != wbuf[j]) e++; ++ ++ } ++ ++ onscsi_disconnect(pha); ++ ++#ifdef EXPERIMENT ++ ++ /* enable this to see how the buffer status bits work */ ++ ++ if (pha->mode == 2) { ++ ++ onscsi_connect(pha); ++ ++ WR(3,0); WR(7,0x48); ++ WR(3,1); WR(7,0x48); OP(5); ++ w2(5); ++ ++ for (k=0;k<16;k++) { ++ j = r1(); w4(k); ++ printk("%2x:%d ",j,k); ++ } ++ printk("\n"); ++ ++ w2(4); WR(3,5); WR(7,0x48); OP(5); ++ w2(0x24); ++ ++ for (k=0;k<16;k++) { ++ j = r1(); ++ printk("%2x:%d ",j,r4()); ++ } ++ printk("\n"); ++ ++ w2(4); ++ ++ onscsi_disconnect(pha); ++ } ++ ++ if (pha->mode == 1) { ++ ++ onscsi_connect(pha); ++ ++ WR(2,0x11); ++ WR(3,0); WR(7,0x48); ++ WR(3,1); WR(7,0x48); OP(5); ++ w2(5); i = 0; ++ ++ for (k=0;k<16;k++) { ++ j = r1(); w0(k); i = 2 - i; w2(5+i); ++ printk("%2x:%d ",j,k); ++ } ++ printk("%2x.\n",r1()); ++ ++ w2(4); ++ ++ WR(2,0x11); ++ WR(3,0); WR(7,0x48); ++ WR(3,5); WR(7,0x48); OP(5); ++ w2(0x24); i = 0; ++ ++ printk("%2x ",r1()); ++ for (k=0;k<16;k++) { ++ i = 2 - i; w2(0x24+i); j = r1(); ++ printk("%2x:%d ",j,r0()); ++ } ++ printk("\n"); ++ ++ w2(4); ++ ++ onscsi_disconnect(pha); ++ } ++ ++#endif ++ ++ if (V_FULL) ++ printk("%s: test port 0x%x mode %d errors %d\n", ++ pha->device,pha->port,pha->mode,e); ++ ++ return e; ++} ++ ++static int onscsi_select (PHA *pha, int initiator, int target) ++{ ++ WR(1,0); ++ WR(2,0x80+FULLBYTE); ++ if (RR(1) != 0) return -1; ++ WR(0,((1 << initiator) | (1 << target))); ++ WR(1,2); ++ return 0; ++} ++ ++static int onscsi_test_select (PHA *pha) ++{ ++ return ((RR(1) & 3) == 3); ++} ++ ++static void onscsi_select_finish (PHA *pha) ++{ ++ WR(1,0); ++} ++ ++static void onscsi_deselect (PHA *pha) ++{ ++ WR(1,0); ++ /* WR(2,0x20+FULLBYTE); */ ++ WR(2,FULLBYTE); ++ WR(3,0); WR(7,0x48); ++} ++ ++static int onscsi_get_bus_status (PHA *pha) ++{ ++ WR(2,0x20+FULLBYTE); ++ return onscsi_map[RR(1)]; ++} ++ ++static void onscsi_slow_start (PHA *pha, char *val) ++{ ++ pha->priv_flag = (RR(1) & 0x80); ++ pha->priv_ptr = val; ++ ++ if (pha->priv_flag) WR(2,0x20); else WR(2,0x21); ++ ++ OP(0); ++ ++ if (pha->priv_flag) { ++ w2(6); ++ } else { ++ w0(*val); w2(5); w2(7); ++ } ++} ++ ++static int onscsi_slow_done (PHA *pha) ++{ ++ return (!(r1() & 8)); ++} ++ ++static void onscsi_slow_end (PHA *pha) ++{ ++ if (pha->priv_flag) { ++ *pha->priv_ptr = onscsi_read_nybble(pha); ++ } else { ++ w2(5); w2(4); ++ } ++} ++ ++static void onscsi_start_block (PHA *pha, int rd) ++{ ++ pha->priv_flag = rd; ++ ++ if (rd) { ++ WR(3,5); WR(7,0x48); ++ if (pha->mode == 1) WR(2,0x31); ++ OP(5); ++ w2(5); w0(0xff); w2(4); ++ } else { ++ WR(3,1); WR(7,0x48); ++ if (pha->mode == 1) WR(2,0x31); ++ OP(5); ++ } ++ TOGL = 0; ++} ++ ++static int onscsi_transfer_done (PHA *pha) ++{ ++ int x; ++ ++ if (pha->priv_flag) return 1; ++ ++ if (pha->mode == 0) { WR(2,0x20); OP(5); } ++ x = r1(); x = r1(); ++ if (pha->mode == 0) { WR(2,0x30); OP(5); } ++ ++ if ((x & 0xf0) == 0x80) return 16; ++ return 0; ++} ++ ++static int onscsi_transfer_ready (PHA *pha) ++{ ++ int x; ++ ++ if (pha->priv_flag) { ++ x = r1(); x = r1(); ++ if ((x & 0xf0) == 0xf0) return 16; ++ if ((x & 0xf0) == 0xb0) return 8; ++ if ((x & 0xf0) == 0x90) return 1; ++ if ((x & 0xf8) == 0x88) return -1; ++ if ((x & 0xf8) == 0x08) return -1; ++ if ((x & 0xf8) == 0x0) return 1; ++ ++ if ((x & 0xf8) != 0x80) printk("DEBUG: %x\n",x); ++ ++ return 0; ++ } ++ ++ return onscsi_transfer_done(pha); ++} ++ ++ ++static int onscsi_transfer_block (PHA *pha, char * buf, int buflen, int rd) ++{ ++ int k, b; ++ ++ k = 0; ++ while ( k < buflen) { ++ ++ if ((b=onscsi_transfer_ready(pha)) <= 0) break; ++ if (b > (buflen-k)) b = buflen-k; ++ ++ if (rd) onscsi_read_block(pha,buf,b); ++ else onscsi_write_block(pha,buf,b); ++ ++ k += b; buf += b; ++ } ++ ++ return k; ++} ++ ++static void onscsi_end_block (PHA *pha, int rd) ++{ ++ w2(4); WR(3,0); WR(7,0x48); ++} ++ ++static void onscsi_reset_bus (PHA *pha) ++{ ++ WR(2,2); ++ udelay(500); ++ WR(2,0); ++ WR(2,FULLBYTE); ++} ++ ++static char *(mode_strings[5]) = {"Nybble","PS/2","EPP","EPP-16","EPP-32"}; ++ ++static struct ppsc_protocol onscsi_psp = { ++ ++ {&host0,&host1,&host2,&host3}, /* params */ ++ &host_structs, /* hosts */ ++ 5, /* num_modes */ ++ 2, /* epp_first */ ++ 1, /* default_delay */ ++ 1, /* can_message */ ++ 16, /* sg_tablesize */ ++ mode_strings, ++ onscsi_init, ++ NULL, /* release */ ++ onscsi_connect, ++ onscsi_disconnect, ++ onscsi_test_proto, ++ onscsi_select, ++ onscsi_test_select, ++ onscsi_select_finish, ++ onscsi_deselect, ++ onscsi_get_bus_status, ++ onscsi_slow_start, ++ onscsi_slow_done, ++ onscsi_slow_end, ++ onscsi_start_block, ++ onscsi_transfer_block, ++ onscsi_transfer_ready, ++ onscsi_transfer_done, ++ onscsi_end_block, ++ onscsi_reset_bus ++}; ++ ++int onscsi_detect (struct scsi_host_template *tpnt ) ++{ ++ return ppsc_detect( &onscsi_psp, tpnt, verbose); ++} ++ ++#ifdef MODULE ++ ++struct scsi_host_template driver_template = PPSC_TEMPLATE(onscsi); ++ ++#include "scsi_module.c" ++ ++MODULE_LICENSE("GPL"); ++ ++#else ++ ++void onscsi_setup (char *str, int *ints) ++{ ++ ppsc_gen_setup(stt,4,str); ++} ++ ++#endif ++ ++/* end of onscsi.c */ +--- linux-2.6.31-rc3-git5.mnb1/drivers/scsi/Kconfig.scsi-ppscsi-2.6.2.orig 2009-07-22 01:11:12.000000000 +0300 ++++ linux-2.6.31-rc3-git5.mnb1/drivers/scsi/Kconfig 2009-07-22 21:54:04.000000000 +0300 +@@ -1062,6 +1062,42 @@ config SCSI_IZIP_SLOW_CTR + + Generally, saying N is fine. + ++config PPSCSI ++ tristate "Parallel Port SCSI adapters" ++ depends on SCSI && PARPORT ++ ++config PPSCSI_T348 ++ tristate "Adaptec APA-348 adapter" ++ depends on PPSCSI ++ ++config PPSCSI_T358 ++ tristate "Adaptec APA-358 adapter" ++ depends on PPSCSI ++ ++config PPSCSI_VPI0 ++ tristate "Iomega VPI0 adapter" ++ depends on PPSCSI ++ ++config PPSCSI_VPI2 ++ tristate "Iomega VPI2 adapter (EXPERIMENTAL)" ++ depends on PPSCSI && EXPERIMENTAL ++ ++config PPSCSI_ONSCSI ++ tristate "OnSpec 90c26 adapter" ++ depends on PPSCSI ++ ++config PPSCSI_SPARCSI ++ tristate "Shining SparSCI adapter" ++ depends on PPSCSI ++ ++config PPSCSI_EPSA2 ++ tristate "Shuttle EPSA-2 adapter" ++ depends on PPSCSI ++ ++config PPSCSI_EPST ++ tristate "Shuttle EPST adapter" ++ depends on PPSCSI ++ + config SCSI_NCR53C406A + tristate "NCR53c406a SCSI support" + depends on ISA && SCSI diff --git a/kernel/kernel/files/patches/mageia/scsi-ppscsi-3.0-buildfix.patch b/kernel/kernel/files/patches/mageia/scsi-ppscsi-3.0-buildfix.patch new file mode 100644 index 00000000..c0be53e2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/scsi-ppscsi-3.0-buildfix.patch @@ -0,0 +1,19 @@ + +fix build with 3.0 + +Signed-off-by: Thomas Backlund + + drivers/scsi/ppscsi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/ppscsi.c.orig 2011-07-15 02:37:27.000000000 +0300 ++++ a/drivers/scsi/ppscsi.c 2011-07-15 13:44:29.514928985 +0300 +@@ -72,7 +72,7 @@ + #define PPSC_DEF_NICE 0 + #define PPSC_INITIATOR 7 + +-spinlock_t ppsc_spinlock = SPIN_LOCK_UNLOCKED; ++DEFINE_SPINLOCK(ppsc_spinlock); + + static char ppsc_bulk_map[256]; + diff --git a/kernel/kernel/files/patches/mageia/scsi-ppscsi-mdvbz45393.patch b/kernel/kernel/files/patches/mageia/scsi-ppscsi-mdvbz45393.patch new file mode 100644 index 00000000..2e919ea6 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/scsi-ppscsi-mdvbz45393.patch @@ -0,0 +1,31 @@ +Fix for https://qa.mandriva.com/show_bug.cgi?id=45393 + +cmnd field of struct scsi_cmnd changed after commit "[SCSI] Let +scsi_cmnd->cmnd use request->cmd buffer" +(64a87b244b9297667ca80264aab849a36f494884) + +Signed-off-by: Herton Ronaldo Krzesinski + +--- + drivers/scsi/ppscsi.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/scsi/ppscsi.c ++++ b/drivers/scsi/ppscsi.c +@@ -1009,7 +1009,6 @@ int ppsc_biosparam (struct scsi_device * + static int ppsc_inquire (PHA *pha, int target, char *buf) + { + char inq[6] = {0x12,0,0,0,36,0}; +- int i; + struct scsi_cmnd cmd; + struct scsi_device dev; + +@@ -1017,7 +1016,7 @@ static int ppsc_inquire (PHA *pha, int t + dev.id = target; + cmd.device = &dev; + cmd.cmd_len = 6; +- for (i=0;i<6;i++) cmd.cmnd[i] = inq[i]; ++ cmd.cmnd = inq; + cmd.sdb.table.nents = 0; + cmd.sdb.table.sgl = (void *) buf; + cmd.sdb.length = 36; diff --git a/kernel/kernel/files/patches/mageia/scsi-ppscsi-sg-helper-update.patch b/kernel/kernel/files/patches/mageia/scsi-ppscsi-sg-helper-update.patch new file mode 100644 index 00000000..defdcefe --- /dev/null +++ b/kernel/kernel/files/patches/mageia/scsi-ppscsi-sg-helper-update.patch @@ -0,0 +1,36 @@ +Update ppscsi for 2.6.24 changes. + +Signed-off-by: Herton Ronaldo Krzesinski + +--- + drivers/scsi/ppscsi.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/ppscsi.c ++++ b/drivers/scsi/ppscsi.c +@@ -58,6 +58,7 @@ + #include + #include + #include ++#include + + #include + +@@ -484,7 +485,7 @@ static void ppsc_update_sg (PHA *pha) + if ((!pha->cur_len) && pha->sg_count) { + pha->sg_count--; + pha->sg_list++; +- pha->cur_buf = page_address(pha->sg_list->page) + pha->sg_list->offset; ++ pha->cur_buf = sg_virt(pha->sg_list); + pha->cur_len = pha->sg_list->length; + } + } +@@ -571,7 +572,7 @@ static void ppsc_engine (PHA *pha) + pha->sg_count--; + pha->sg_list = + (struct scatterlist *)pha->cur_cmd->request_buffer; +- pha->cur_buf = page_address(pha->sg_list->page) + pha->sg_list->offset; ++ pha->cur_buf = sg_virt(pha->sg_list); + pha->cur_len = pha->sg_list->length; + } else { + pha->cur_buf = pha->cur_cmd->request_buffer; diff --git a/kernel/kernel/files/patches/mageia/scsi-ppscsi-update-for-scsi_data_buffer.patch b/kernel/kernel/files/patches/mageia/scsi-ppscsi-update-for-scsi_data_buffer.patch new file mode 100644 index 00000000..496326e3 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/scsi-ppscsi-update-for-scsi_data_buffer.patch @@ -0,0 +1,88 @@ +Update ppscsi for "[SCSI] implement scsi_data_buffer" change on Linux 2.6.25 +(commit 30b0c37b27485a9cb897bfe3824f6f517b8c80d6) + +Signed-off-by: Herton Ronaldo Krzesinski + +--- + drivers/scsi/ppscsi.c | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +--- a/drivers/scsi/ppscsi.c ++++ b/drivers/scsi/ppscsi.c +@@ -424,16 +424,16 @@ static void ppsc_start (PHA *pha) + + bf &= (!((1<cur_cmd->device->id) & pha->slow_targets)); + +- r = pha->cur_cmd->use_sg; ++ r = scsi_sg_count(pha->cur_cmd); + if (r) { + b = 0; +- p = (struct scatterlist *)pha->cur_cmd->request_buffer; ++ p = scsi_sglist(pha->cur_cmd); + for (k=0;klength; + p++; + } + } else { +- b = pha->cur_cmd->request_bufflen; ++ b = scsi_bufflen(pha->cur_cmd); + } + + bf &= (b > 127); +@@ -567,16 +567,16 @@ static void ppsc_engine (PHA *pha) + pha->data_dir = phase & PPSC_IO; + pha->data_count = 0; + +- pha->sg_count = pha->cur_cmd->use_sg; ++ pha->sg_count = scsi_sg_count(pha->cur_cmd); + if (pha->sg_count) { + pha->sg_count--; +- pha->sg_list = +- (struct scatterlist *)pha->cur_cmd->request_buffer; ++ pha->sg_list = scsi_sglist(pha->cur_cmd); + pha->cur_buf = sg_virt(pha->sg_list); + pha->cur_len = pha->sg_list->length; + } else { +- pha->cur_buf = pha->cur_cmd->request_buffer; +- pha->cur_len = pha->cur_cmd->request_bufflen; ++ pha->cur_buf = ++ (char *)pha->cur_cmd->sdb.table.sgl; ++ pha->cur_len = scsi_bufflen(pha->cur_cmd); + } + + pha->last_phase = phase; +@@ -622,7 +622,7 @@ static void ppsc_engine (PHA *pha) + + if (pha->cur_cmd->cmnd[0] == REQUEST_SENSE) { + +- sb = (char *)pha->cur_cmd->request_buffer; ++ sb = (char *)pha->cur_cmd->sdb.table.sgl; + printk("%s: Sense key: %x ASC: %x ASCQ: %x\n", + pha->device, sb[2] & 0xff, + sb[12] & 0xff, sb[13] & 0xff); +@@ -819,9 +819,9 @@ static void ppsc_cleanup (PHA *pha) + cmd->cmnd[4] = sizeof(cmd->sense_buffer); + cmd->cmnd[5] = 0; + cmd->cmd_len = 6; +- cmd->use_sg = 0; +- cmd->request_buffer = (char *) cmd->sense_buffer; +- cmd->request_bufflen = sizeof(cmd->sense_buffer); ++ cmd->sdb.table.nents = 0; ++ cmd->sdb.table.sgl = (void *) cmd->sense_buffer; ++ cmd->sdb.length = sizeof(cmd->sense_buffer); + + pha->cur_cmd = cmd; + ppsc_do_claimed(pha,ppsc_start); +@@ -1018,9 +1018,9 @@ static int ppsc_inquire (PHA *pha, int t + cmd.device = &dev; + cmd.cmd_len = 6; + for (i=0;i<6;i++) cmd.cmnd[i] = inq[i]; +- cmd.use_sg = 0; +- cmd.request_buffer = buf; +- cmd.request_bufflen = 36; ++ cmd.sdb.table.nents = 0; ++ cmd.sdb.table.sgl = (void *) buf; ++ cmd.sdb.length = 36; + + return ppsc_command(&cmd); + } diff --git a/kernel/kernel/files/patches/mageia/scsi-ppscsi_fixes.patch b/kernel/kernel/files/patches/mageia/scsi-ppscsi_fixes.patch new file mode 100644 index 00000000..acc011e9 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/scsi-ppscsi_fixes.patch @@ -0,0 +1,226 @@ +--- + drivers/scsi/Makefile | 2 +- + drivers/scsi/ppscsi.c | 22 ++++++++++++---------- + drivers/scsi/ppscsi.h | 34 ++++++++++++++++++---------------- + drivers/scsi/sparcsi.c | 6 +++--- + 4 files changed, 34 insertions(+), 30 deletions(-) + +--- a/drivers/scsi/ppscsi.c ++++ b/drivers/scsi/ppscsi.c +@@ -57,6 +57,7 @@ + #include + #include + #include ++#include + + #include + +@@ -95,7 +96,8 @@ static void ppsc_attach (struct parport + return; + } + +- add->port = parport_get_port (port); ++ atomic_inc(&port->ref_count); ++ add->port = port; + add->next = ppsc_port_list; + wmb (); + ppsc_port_list = add; +@@ -187,11 +189,11 @@ static void ppsc_set_intr (PHA *pha, voi + spin_unlock_irqrestore(&ppsc_spinlock,flags); + } + +-static void ppsc_tq_int (void *data) ++static void ppsc_tq_int (struct work_struct *work) + { + void (*con)(PHA *); + unsigned long flags; +- PHA *pha = (PHA *)data; ++ PHA *pha = container_of(work, PHA, wq); + + spin_lock_irqsave(&ppsc_spinlock,flags); + +@@ -377,7 +379,7 @@ int ppsc_command (struct scsi_cmnd *cmd) + + ppsc_do_claimed(pha,ppsc_start); + +- while (pha->cur_cmd) scsi_sleep(1); ++ while (pha->cur_cmd) ssleep(1); + + return cmd->result; + } +@@ -886,7 +888,7 @@ static void ppsc_reset_pha (PHA *pha) + ppsc_claim(pha); + pha->proto->connect(pha); + pha->proto->reset_bus(pha); +- scsi_sleep(4*HZ); ++ ssleep(4*HZ); + pha->proto->disconnect(pha); + ppsc_unclaim(pha); + +@@ -905,7 +907,7 @@ int ppsc_reset (struct scsi_cmnd * cmd) + pha->abort_flag = PPSC_DO_RESET; + + while (pha->cur_cmd && (k < PPSC_RESET_TMO)) { +- scsi_sleep(HZ/10); ++ ssleep(HZ/10); + k += HZ/10; + } + +@@ -992,11 +994,11 @@ int ppsc_biosparam (struct scsi_device * + { + ip[0] = 0x40; + ip[1] = 0x20; +- ip[2] = (capacity +1) / (ip[0] * ip[1]); ++ ip[2] = (unsigned int)(capacity +1) >> 11; + if (ip[2] > 1024) { + ip[0] = 0xff; + ip[1] = 0x3f; +- ip[2] = (capacity +1) / (ip[0] * ip[1]); ++ ip[2] = (unsigned int)(capacity +1) / (0xff * 0x3f); + if (ip[2] > 1023) + ip[2] = 1023; + } +@@ -1084,7 +1086,7 @@ int ppsc_release_pha (PHA *pha) + } + + +-int ppsc_detect (PSP *proto, Scsi_Host_Template *tpnt, int verbose) ++int ppsc_detect (PSP *proto, struct scsi_host_template *tpnt, int verbose) + { + int i, m, p, d, n, s, z; + struct ppsc_port_list_struct *next_port = NULL; /* shut gcc up */ +@@ -1146,7 +1148,7 @@ int ppsc_detect (PSP *proto, Scsi_Host_T + pha->device[p+1] = '0' + i; + pha->device[p+2] = 0; + +- INIT_WORK(&pha->wq, ppsc_tq_int, pha); ++ INIT_WORK(&pha->wq, ppsc_tq_int); + + init_timer (&pha->timer); + pha->timer.data = (unsigned long) pha; +--- a/drivers/scsi/sparcsi.c ++++ b/drivers/scsi/sparcsi.c +@@ -165,7 +165,7 @@ static int sparcsi_test_proto (PHA *pha) + + WR(1,0x80); udelay(60); + WR(1,0); +- scsi_sleep(5*HZ); ++ ssleep(5*HZ); + pha->private[0] = 1; + } + +@@ -363,14 +363,14 @@ static struct ppsc_protocol sparcsi_psp + sparcsi_reset_bus + }; + +-int sparcsi_detect (Scsi_Host_Template *tpnt) ++int sparcsi_detect (struct scsi_host_template *tpnt) + { + return ppsc_detect( &sparcsi_psp, tpnt, verbose); + } + + #ifdef MODULE + +-Scsi_Host_Template driver_template = PPSC_TEMPLATE(sparcsi); ++struct scsi_host_template driver_template = PPSC_TEMPLATE(sparcsi); + + #include "scsi_module.c" + +--- a/drivers/scsi/ppscsi.h ++++ b/drivers/scsi/ppscsi.h +@@ -13,14 +13,16 @@ + #define PPSC_H_VERSION "0.92" + + #include +-#include ++#include + #include + #include + #include + #include + +-#include "scsi.h" +-#include "hosts.h" ++#include ++#include ++#include ++#include + + + /* ppscsi global functions */ +@@ -40,31 +42,31 @@ extern int ppsc_release(struct Scsi_Host + /* imports for hosts.c */ + + #ifdef CONFIG_PPSCSI_T348 +-extern int t348_detect( Scsi_Host_Template *); ++extern int t348_detect( struct scsi_host_template *); + #endif + + #ifdef CONFIG_PPSCSI_T358 +-extern int t358_detect( Scsi_Host_Template *); ++extern int t358_detect( struct scsi_host_template *); + #endif + + #ifdef CONFIG_PPSCSI_ONSCSI +-extern int onscsi_detect( Scsi_Host_Template *); ++extern int onscsi_detect( struct scsi_host_template *); + #endif + + #ifdef CONFIG_PPSCSI_EPST +-extern int epst_detect( Scsi_Host_Template *); ++extern int epst_detect( struct scsi_host_template *); + #endif + + #ifdef CONFIG_PPSCSI_EPSA2 +-extern int epsa2_detect( Scsi_Host_Template *); ++extern int epsa2_detect( struct scsi_host_template *); + #endif + + #ifdef CONFIG_PPSCSI_VPI0 +-extern int vpi0_detect( Scsi_Host_Template *); ++extern int vpi0_detect( struct scsi_host_template *); + #endif + + #ifdef CONFIG_PPSCSI_SPARCSI +-extern int sparcsi_detect( Scsi_Host_Template *); ++extern int sparcsi_detect( struct scsi_host_template *); + #endif + + #endif +@@ -303,7 +305,7 @@ struct ppsc_protocol { + + typedef struct ppsc_protocol PSP; + +-extern int ppsc_detect( PSP *, Scsi_Host_Template *, int); ++extern int ppsc_detect( PSP *, struct scsi_host_template *, int); + + #ifdef PPSC_HA_MODULE + +@@ -322,11 +324,11 @@ static STT stt[4] = { {"host0",8,host0}, + {"host3",8,host3} }; + #endif + +-MODULE_PARM(host0,"1-8i"); +-MODULE_PARM(host1,"1-8i"); +-MODULE_PARM(host2,"1-8i"); +-MODULE_PARM(host3,"1-8i"); +-MODULE_PARM(verbose,"i"); ++module_param_array(host0, int, NULL, 0); ++module_param_array(host1, int, NULL, 0); ++module_param_array(host2, int, NULL, 0); ++module_param_array(host3, int, NULL, 0); ++module_param(verbose, int, 0); + + static struct ppsc_host_adapter host_structs[4]; + +--- a/drivers/scsi/Makefile ++++ b/drivers/scsi/Makefile +@@ -136,7 +136,7 @@ obj-$(CONFIG_PPSCSI_ONSCSI) += onscsi.o + obj-$(CONFIG_PPSCSI_EPSA2) += epsa2.o + obj-$(CONFIG_PPSCSI_EPST) += epst.o + obj-$(CONFIG_PPSCSI_VPI0) += vpi0.o +-obj-$(CONFIG_PPSCSI_VPI2) += vpi2.o ++obj-n += vpi2.o + obj-$(CONFIG_PPSCSI_SPARCSI) += sparcsi.o + + obj-$(CONFIG_CHR_DEV_ST) += st.o diff --git a/kernel/kernel/files/patches/mageia/series b/kernel/kernel/files/patches/mageia/series new file mode 100644 index 00000000..686f9f76 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/series @@ -0,0 +1,478 @@ +# +# Mageia kernel series file +# +# This file describes the order in which patches should be applied +# in the kernel and why the patch is needed. +# +# Luiz Fernando N. Capitulino +# + +### +### Upstream git +### + +### +### Stable Queue +### + +### +### Arch x86 +### + +# laptop needing pci=assign-busses (#18989, needs to be submitted upstream) +x86-pci-toshiba-equium-a60-assign-busses.patch + +# If users choose a bad video mode, allow to jump to +# a working one (TTL: forever) +x86-boot-video-80x25-if-break.patch + +# Allow poweroff on UP machines running SMP kernels +x86-default_poweroff_up_machines.patch + +# Fix #38760, need to be revised and submitted upstream +# BROKEN: x86-cpufreq-speedstep-dothan-3.patch + +# raise vmalloc to fix https://bugs.mageia.org/show_bug.cgi?id=904 +x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch + +# slows down boot +Revert-cpufreq-pcc-Enable-autoload-of-pcc-cpufreq-fo.patch + +# regression fix +x86-spinlocks-Fix-regression-in-spinlock-contention-.patch + +### +### Core +### +genirq-Set-initial-affinity-in-irq_set_affinity_hint.patch +genirq-Fix-null-pointer-reference-in-irq_set_affinit.patch + +iommu-vt-d-Remove-unused-variable.patch + +rcu-Fix-rcu_barrier-race-that-could-result-in-too-sh.patch + +# efi fixes +x86-efi-Store-upper-bits-of-command-line-buffer-addr.patch +firmware-efi-Fix-error-handling-in-add_sysfs_runtime_map_entr.patch + +### +### i2c +### + +### +### PCI core +### + +# BROKEN: pci-pciprobe-CardBusNo.patch + +# http://lkml.org/lkml/2008/9/12/52 +pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch +pci-quirks-drop-devinit-exit.patch + +# Intel ACS quirks +pci-Add-Wellsburg-X99-to-Intel-PCH-root-port-ACS-qui.patch +pci-acs-quirks-for-Intel-9-series-PCH-root-ports.patch + +### +### PNP core +### + +# Turns pnpbios off by default, useful, since pnpbios +# is know to cause problems (TTL: forever) +pnp-pnpbios-off-by-default.patch + +pnp-isapnp-async-init.patch + +### +### ACPI +### + +# CLEVO M360S acpi irq workaround +acpi-CLEVO-M360S-disable_acpi_irq.patch + +# Clevo M720SR freezes with C3 +acpi-processor-M720SR-limit-to-C2.patch + +# fixes boot regression on some hw since kernel 3.11 +acpi-init-Fix-the-ordering-of-acpi_reserve_resources.patch +# audio regression +acpi-PNP-add-two-IDs-to-list-for-PNPACPI-device-enum.patch +# MB regression +acpi-SBS-Add-5-us-delay-to-fix-SBS-hangs-on-MacBook.patch +acpi-sbs-enable-battery-manager-when-present.patch +# backlight override +acpi-video-Allow-forcing-native-backlight-on-non-win.patch +# fix booting on new hw +acpi-ACPICA-Add-Windows-2015-string-to-_OSI-support.patch +# less log flooding +acpi-table-Use-pr_debug-instead-of-pr_info-for-MADT-.patch + +### +### Block +### + +# epsa2 SCSI driver, don't know from where it came +scsi-ppscsi-2.6.2.patch + +# epsa2 is far behind +scsi-ppscsi_fixes.patch + +# Fix build of ppscsi on 2.6.24 +scsi-ppscsi-sg-helper-update.patch + +# Update/fix for ppscsi on 2.6.25 +scsi-ppscsi-update-for-scsi_data_buffer.patch + +# https://qa.mandriva.com/show_bug.cgi?id=45393 +scsi-ppscsi-mdvbz45393.patch + +# epsa2 3.0 buildfix +scsi-ppscsi-3.0-buildfix.patch + +# Don't know know why this is needed +scsi-megaraid-new-sysfs-name.patch + +# Looks like fixes from Arnaud, not sure why they're needed +ide-pci-sis5513-965.patch + +mpt-vmware-fix.patch + +# adds aliases to support upgrade from old dm-raid45 patch +dm-raid-aliases.patch + +# disable floppy autoloading (mga #4696) +block-floppy-disable-pnp-modalias.patch + +# prefer ata over ide drivers +ata-prefer-ata-drivers-over-ide-drivers-when-both-are-built.patch + +# korg #81551 +ata-revert-Disabling-the-async-PM-for-JMicron-chip-363-361.patch +ata-jmicron-disable-broken-async_suspend.patch + +# raid fixes +md-raid5-dont-record-new-size-if-resize_stripes-fails.patch + +# blk-mq +blk-mq-fix-CPU-hotplug-handling.patch +blk-mq-fix-race-between-timeout-and-CPU-hotplug.patch +blk-mq-fix-FUA-request-hang.patch +blk-mq-don-t-lose-requests-if-a-stopped-queue-restar.patch + +# QNAP fix +scsi-add-1024-max-sectors-black-list-flag.patch + +### +### File-system +### + +# aufs from: http://aufs.sourceforge.net/ (mga#8314) +fs-aufs-3.19.patch +fs-aufs-3.19-modular.patch + +# btrfs crash +fs-btrfs-fix-BUG_ON-in-btrfs_orphan_add-when-delete-unu.patch +fs-btrfs-unlock-i_mutex-after-attempting-to-delete-subvolume-during-send.patch + +# efi fix +fs-efivarfs-Ensure-VariableName-is-NUL-terminated.patch + +# ext4 fix +fs-ext4-fix-data-corruption-caused-by-unwritten-and-del.patch +fs-ext4-move-check-under-lock-scope-to-close-a-race.patch + +# core +fs-mnt-Fix-fs_fully_visible-to-verify-the-root-director.patch +fs-mnt-Fail-collect_mounts-when-applied-to-unmounted-mo.patch +fs-path_openat-fix-double-fput.patch +fs-splice-sendfile-at-once-fails-for-big-files.patch + +### +### FireWire +### + +# adding module aliases to ease upgrade from ieee1394 +firewire-ieee1394-module-aliases.patch + +### +### GPU/DRM +### + +# new Q57 Host Bridge id +char-agp-intel-new-Q57-id.patch + +# External mach64 drm support from git://anongit.freedesktop.org/git/mesa/drm +gpu-drm-mach64.patch +gpu-drm-mach64-fixes.patch +gpu-drm-mach64-2.6.31.patch +gpu-drm-mach64-fix-for-changed-drm_pci_alloc.patch +gpu-drm-mach64-fix-for-changed-drm_ioctl.patch +gpu-drm-mach64-2.6.36-buildfix.patch +gpu-drm-mach64-2.6.37-buildfix.patch +gpu-drm-mach64-3.0-buildfix.patch +gpu-drm-mach64-include-module.h.patch +gpu-drm-mach64-3.3-buildfix.patch +gpu-drm-mach64-3.6-buildfix.patch +gpu-drm-mach64-3.7-buildfix.patch +gpu-drm-mach64-3.12-buildfix.patch +gpu-drm-mach64-restore-mach64_PCI_IDS.patch +gpu-drm-mach64-linux-3.14-buildfix.patch +gpu-drm-mach64-3.17-buildfix.patch +gpu-drm-mach64-3.18-buildfix.patch + +# i915, nice speedups +gpu-drm-i915-Make-sample_c-messages-go-faster-on-Haswell.patch +gpu-drm-i915-Improve-HiZ-throughput-on-Cherryview.patch +gpu-drm-i915-Enable-the-HiZ-RAW-Stall-Optimization-on-Broadwell.patch +gpu-drm-i915-Ensure-the-HiZ-RAW-Stall-Optimization-is-on-for-Cherryview.patch +# i915, vlv crash +gpu-drm-i915-fix-vlv-crash.patch + +### +### Hardware Monitoring +### + +### +### Input +### + +input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch + +# mga #14897 +Input-psmouse-support-for-the-FocalTech-PS-2-protoco.patch +Input-psmouse-remove-hardcoded-touchpad-size-from-th.patch +Input-psmouse-ensure-that-focaltech-reports-consiste.patch +Input-psmouse-disable-changing-resolution-rate-scale.patch +Input-psmouse-disable-palm-detection-in-the-focaltec.patch + +### +### idle +### + +### +### Kbuild +### + +### +### Media +### + +### +### Misc +### + +### +### MM +### + +mm-vmscan-wake-up-all-pfmemalloc-throttled-processes.patch + +# div/0 fix +mm-writeback-use-1-instead-of-1-to-protect-against-div-.patch + +### +### Network +### + +# SiS 190 fixes +net-sis190-fix-list-usage.patch + +# netfilter IFWLOG support +net-netfilter-IFWLOG.patch +net-netfilter-IFWLOG-mdv.patch +net-netfilter-IFWLOG-2.6.35-buildfix.patch +net-netfilter-IFWLOG-2.6.37-buildfix.patch +net-ipv4-netfilter-ipt_IFWLOG-3.6-buildfix.patch +net-netfilter-IFWLOG-3.7-buildfix.patch + +# netfilter psd support +net-netfilter-psd.patch +net-netfilter-psd-mdv.patch +net-netfilter-psd-2.6.35-buildfix.patch + +# ath9k +net-wireless-ath9k-Update-PCI-IDs-for-AR9565.patch + +# brcmfmac +net-wireless-brcmfmac-Add-support-for-bcm43340_1-wireless-chipsets.patch +net-wireless-brcmfmac-avoid-null-pointer-access-when-brcmf_msgbuf.patch +net-wireless-brcmfmac-check-result-of-USB-firmware-request.patch + +### +### Platform drivers +### + +# Allow access to Shuttle WMI interface controls +# (Mainly allow turning on/off webcam and wireless on Shuttle DA18IE and DA18IM) +platform-x86-add-shuttle-wmi-driver.patch +platform-x86-shuttle-wmi-drop-devinit-exit.patch + +### +### RTC +### + +### +### Serial +### + +# Export pci_ids.h to user space, needed by ldetect +include-kbuild-export-pci_ids.patch + +### +### Sound +### + +# adds bluetooth sco support +sound-bluetooth-SCO-support.patch + +# VT1613 +sound-alsa-add-VT1613-AC97-codec-support.patch + +# Alsa updates for Dell +sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC256.patch +sound-alsa-hda-realtek-Support-headset-mode-for-ALC286-288.patch +sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC288.patch + +# emu10k +alsa-emu10k1-emu10k2-32-bit-dma-mode.patch +alsa-emu10k1-fix-card-shortname-string-buffer-overflow.patch + +### +### Staging +### + + +### +### TTY +### + +### +### USB +### + +# http://qa.mandriva.com/show_bug.cgi?id=30638 +bluetooth-hci_usb-disable-isoc-transfers.patch + +hid-usbhid-IBM-BladeCenterHS20-quirk.patch + +usb-storage-unusual_devs-add-id.patch +usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch + +# xhci fixes +usb-xhci-remove-unused-parameter-xhci-in-function-xhci-handshake.patch +usb-xhci-clean-up-work-to-remove-unused-parameters-for-functions-in-xhci-mem.c.patch +usb-xhci-fix-isoc-endpoint-dequeue-from-advancing-too-far-on-transaction-error.patch +usb-xhci-Solve-full-event-ring-by-increasing-TRBS_PER_SEGMENT-to-256.patch +usb-xhci-gracefully-handle-xhci_irq-dead-device.patch + +# uas +uas-allow-uas_use_uas_driver-to-return-usb-storage-flags.patch +uas-add-us_fl_max_sectors_240-flag.patch +uas-set-max_sectors_240-quirk-for-asm1053-devices.patch + +# misc fixes +usb-cdc-acm-prevent-infinite-loop-when-parsing-cdc-headers.patch +usb-chipidea-otg-remove-mutex-unlock-and-lock-while-stop-and-start-role.patch + +### +### V4L +### + +# pwc driver name in /proc/bus/devices, /sys fix and "advertisement" removal +media-usb-pwc-lie-in-proc-usb-devices.patch + +### +### Video +### + +# Mageia framebuffer boot logo +video-mageia-logo.patch + +# https://qa.mandriva.com/show_bug.cgi?id=59260 +# https://bugzilla.kernel.org/show_bug.cgi?id=26232 +# DISABLED: video-fb-avoid-oops-when-fw-fb-is-removed.patch +# DISABLED: video-fb-avoid-deadlock-caused-by-fb_set_suspend.patch + +# fbdev oops +video-fbdev-fix-possible-null-dereference.patch +# fbdev fixes +video-fbdev-Add-additional-vesa-modes.patch +video-fbdev-Check-Standard-Timing-against-DMT.patch +video-fbdev-Validate-mode-timing-against-monspec.patch +video-fbdev-Fix-sparse-warning-messages.patch +video-fbdev-fix-CVT-vertical-front-and-back-porch-values.patch +video-fbdev-fix-sys_copyarea.patch + +### +### 3rdparty +### + +3rd-3rdparty-1.0-tree.patch + +# TODO: fix up patch below to include all archs? +3rd-3rdparty-merge.patch + +# acerhk +3rd-acerhk-0.5.35.patch +3rd-acerhk-kbuild.patch +3rd-acerhk-extra-cflags.patch +3rd-acerhk-proc_dir_entry-owner.patch +3rd-acerhk-fix-build-with-function-tracer.patch +3rd-acerhk-2.6.36-buildfix.patch +3rd-acerhk-fix-include.patch + +# aes2501 +3rd-aes2501-r19.patch +3rd-aes2501-kbuild.patch +3rd-aes2501-rmmod-oops-fix.patch + +# ndiswrapper +3rd-ndiswrapper-1.59.patch +3rd-ndiswrapper-Kconfig.patch +3rd-ndiswrapper-Makefile-build-fix.patch +3rd-ndiswrapper-linux-3.14-buildfix.patch + +# rfswitch +3rd-rfswitch-1.3.patch +3rd-rfswitch-build-fix.patch +3rd-rfswitch-3.0-buildfix.patch + +# viahss +3rd-viahss-0.92.patch +3rd-viahss-config.patch +3rd-viahss-module-license.patch +3rd-viahss-2.6.35-buildfix.patch +3rd-viahss-3.0-buildfix.patch + +# add rtl8723bs support (mga#15874) +3rd-rtl8723bs.patch +3rd-rtl8723bs-buildfix.patch +3rd-rtl8723bs-updates.patch +3rd-rtl8723bs-revert-4.0-changes.patch + +### +### Security +### + +### +### Smack fixes +### + +### +### XEN +### + +### +### ARM +### + +### +### IA64 +### + +# fix broken header generation +KVM-ia64-drop-kvm.h-from-installed-user-headers.patch + +### +### Tools +### diff --git a/kernel/kernel/files/patches/mageia/sound-alsa-add-VT1613-AC97-codec-support.patch b/kernel/kernel/files/patches/mageia/sound-alsa-add-VT1613-AC97-codec-support.patch new file mode 100644 index 00000000..4d15be89 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/sound-alsa-add-VT1613-AC97-codec-support.patch @@ -0,0 +1,69 @@ +From: "Maciej S. Szmigiero" +Newsgroups: gmane.linux.kernel,gmane.linux.alsa.devel +Subject: [PATCH]Add VT1613 AC97 codec support +Date: Fri, 06 Mar 2015 16:59:00 +0100 + +Patch to add an VT1613 AC97 codec support. + +This codec has additional DC offset removal control, +headphone output and no video input. + +Signed-off-by: Maciej Szmigiero + +diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c +index 5ee2f17..5bca1a3 100644 +--- a/sound/pci/ac97/ac97_codec.c ++++ b/sound/pci/ac97/ac97_codec.c +@@ -177,6 +177,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { + { 0x54524123, 0xffffffff, "TR28602", NULL, NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)] + { 0x54584e03, 0xffffffff, "TLV320AIC27", NULL, NULL }, + { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, ++{ 0x56494120, 0xfffffff0, "VIA1613", patch_vt1613, NULL }, + { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF + { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF + { 0x56494182, 0xffffffff, "VIA1618", patch_vt1618, NULL }, +diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c +index ceaac1c..eca2210 100644 +--- a/sound/pci/ac97/ac97_patch.c ++++ b/sound/pci/ac97/ac97_patch.c +@@ -3352,6 +3352,39 @@ static int patch_cm9780(struct snd_ac97 *ac97) + } + + /* ++ * VIA VT1613 codec ++ */ ++static const struct snd_kcontrol_new snd_ac97_controls_vt1613[] = { ++AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0), ++}; ++ ++static int patch_vt1613_specific(struct snd_ac97 *ac97) ++{ ++ int err; ++ ++ err = patch_build_controls(ac97, &snd_ac97_controls_vt1613[0], ++ ARRAY_SIZE(snd_ac97_controls_vt1613)); ++ if (err) ++ return err; ++ ++ return 0; ++}; ++ ++static const struct snd_ac97_build_ops patch_vt1613_ops = { ++ .build_specific = patch_vt1613_specific ++}; ++ ++static int patch_vt1613(struct snd_ac97 *ac97) ++{ ++ ac97->build_ops = &patch_vt1613_ops; ++ ++ ac97->flags |= AC97_HAS_NO_VIDEO; ++ ac97->caps |= AC97_BC_HEADPHONE; ++ ++ return 0; ++} ++ ++/* + * VIA VT1616 codec + */ + static const struct snd_kcontrol_new snd_ac97_controls_vt1616[] = { + diff --git a/kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC256.patch b/kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC256.patch new file mode 100644 index 00000000..07b2c7e1 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC256.patch @@ -0,0 +1,65 @@ +From 7081adf3f98f4c39dc6758208775b2aa48f51f8a Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Mon, 30 Mar 2015 17:05:37 +0800 +Subject: ALSA: hda/realtek - Support Dell headset mode for ALC256 + +Dell new platform of ALC256 audio codec. +Support headset mode for Dell ALC256 platform. + +Signed-off-by: Kailang Yang +Cc: +Signed-off-by: Takashi Iwai + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 7438213..f75c127 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -3587,6 +3587,7 @@ static void alc_headset_mode_mic_in(stru + + switch (codec->vendor_id) { + case 0x10ec0255: ++ case 0x10ec0256: + alc_write_coef_idx(codec, 0x45, 0xc489); + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + alc_process_coef_fw(codec, coef0255); +@@ -3656,6 +3657,7 @@ static void alc_headset_mode_default(str + + switch (codec->vendor_id) { + case 0x10ec0255: ++ case 0x10ec0256: + alc_process_coef_fw(codec, coef0255); + break; + case 0x10ec0233: +@@ -3764,6 +3766,7 @@ static void alc_headset_mode_omtp(struct + + switch (codec->vendor_id) { + case 0x10ec0255: ++ case 0x10ec0256: + alc_process_coef_fw(codec, coef0255); + break; + case 0x10ec0233: +@@ -3809,6 +3812,7 @@ static void alc_determine_headset_type(s + + switch (codec->vendor_id) { + case 0x10ec0255: ++ case 0x10ec0256: + alc_process_coef_fw(codec, coef0255); + msleep(300); + val = alc_read_coef_idx(codec, 0x46); +@@ -5121,6 +5125,16 @@ static const struct snd_hda_pin_quirk al + {0x17, 0x40000000}, + {0x1d, 0x40700001}, + {0x21, 0x02211050}), ++ SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ++ {0x12, 0x90a60140}, ++ {0x13, 0x40000000}, ++ {0x14, 0x90170110}, ++ {0x19, 0x411111f0}, ++ {0x1a, 0x411111f0}, ++ {0x1b, 0x411111f0}, ++ {0x1d, 0x40700001}, ++ {0x1e, 0x411111f0}, ++ {0x21, 0x02211020}), + SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, + {0x12, 0x90a60130}, + {0x13, 0x40000000}, diff --git a/kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC288.patch b/kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC288.patch new file mode 100644 index 00000000..3069bb9d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-Dell-headset-mode-for-ALC288.patch @@ -0,0 +1,119 @@ +From e1e62b98ebddc3234f3259019d3236f66fc667f8 Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Wed, 8 Apr 2015 16:01:22 +0800 +Subject: ALSA: hda/realtek - Support Dell headset mode for ALC288 + +Dell create new platform with ALC288 codec. +This patch will enable headset mode for Dino platform. + +[slight code refactoring and compile fix by tiwai] + +Signed-off-by: Kailang Yang +Signed-off-by: Takashi Iwai + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index ceb599a..7b5c93e 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4089,6 +4089,29 @@ static void alc_fixup_headset_mode_alc25 + alc_fixup_headset_mode(codec, fix, action); + } + ++static void alc288_update_headset_jack_cb(struct hda_codec *codec, ++ struct hda_jack_callback *jack) ++{ ++ struct alc_spec *spec = codec->spec; ++ int present; ++ ++ alc_update_headset_jack_cb(codec, jack); ++ /* Headset Mic enable or disable, only for Dell Dino */ ++ present = spec->gen.hp_jack_present ? 0x40 : 0; ++ snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, ++ present); ++} ++ ++static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec, ++ const struct hda_fixup *fix, int action) ++{ ++ alc_fixup_headset_mode(codec, fix, action); ++ if (action == HDA_FIXUP_ACT_PROBE) { ++ struct alc_spec *spec = codec->spec; ++ spec->gen.hp_automute_hook = alc288_update_headset_jack_cb; ++ } ++} ++ + static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, + const struct hda_fixup *fix, int action) + { +@@ -4427,6 +4450,9 @@ enum { + ALC282_FIXUP_ASPIRE_V5_PINS, + ALC280_FIXUP_HP_GPIO4, + ALC286_FIXUP_HP_GPIO_LED, ++ ALC288_FIXUP_DELL_HEADSET_MODE, ++ ALC288_FIXUP_DELL1_MIC_NO_PRESENCE, ++ ALC288_FIXUP_DELL_XPS_13_GPIO6, + }; + + static const struct hda_fixup alc269_fixups[] = { +@@ -4907,6 +4933,33 @@ static const struct hda_fixup alc269_fix + .type = HDA_FIXUP_FUNC, + .v.func = alc286_fixup_hp_gpio_led, + }, ++ [ALC288_FIXUP_DELL_HEADSET_MODE] = { ++ .type = HDA_FIXUP_FUNC, ++ .v.func = alc_fixup_headset_mode_dell_alc288, ++ .chained = true, ++ .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED ++ }, ++ [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ ++ { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE ++ }, ++ [ALC288_FIXUP_DELL_XPS_13_GPIO6] = { ++ .type = HDA_FIXUP_VERBS, ++ .v.verbs = (const struct hda_verb[]) { ++ {0x01, AC_VERB_SET_GPIO_MASK, 0x40}, ++ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40}, ++ {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -5131,6 +5184,13 @@ static const struct hda_model_fixup alc2 + {0x1b, 0x411111f0}, \ + {0x1e, 0x411111f0} + ++#define ALC288_STANDARD_PINS \ ++ {0x17, 0x411111f0}, \ ++ {0x18, 0x411111f0}, \ ++ {0x19, 0x411111f0}, \ ++ {0x1a, 0x411111f0}, \ ++ {0x1e, 0x411111f0} ++ + #define ALC290_STANDARD_PINS \ + {0x12, 0x99a30130}, \ + {0x13, 0x40000000}, \ +@@ -5326,6 +5386,13 @@ static const struct snd_hda_pin_quirk al + {0x19, 0x03a11020}, + {0x1d, 0x40e00001}, + {0x21, 0x0321101f}), ++ SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6, ++ ALC288_STANDARD_PINS, ++ {0x12, 0x90a60120}, ++ {0x13, 0x40000000}, ++ {0x14, 0x90170110}, ++ {0x1d, 0x4076832d}, ++ {0x21, 0x0321101f}), + SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1, + ALC290_STANDARD_PINS, + {0x14, 0x411111f0}, diff --git a/kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-headset-mode-for-ALC286-288.patch b/kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-headset-mode-for-ALC286-288.patch new file mode 100644 index 00000000..faaad70b --- /dev/null +++ b/kernel/kernel/files/patches/mageia/sound-alsa-hda-realtek-Support-headset-mode-for-ALC286-288.patch @@ -0,0 +1,178 @@ +From f3b703326541d0c1ce85f5e570f6d2b6bd4296ec Mon Sep 17 00:00:00 2001 +From: Kailang Yang +Date: Wed, 8 Apr 2015 15:01:17 +0800 +Subject: ALSA: hda/realtek - Support headset mode for ALC286/288 + +Support headset mode for ALC286 and ALC288 platforms. + +Signed-off-by: Kailang Yang +Signed-off-by: Takashi Iwai + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 7f46d06..ceb599a 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -3542,6 +3542,14 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) + WRITE_COEF(0x32, 0x42a3), + {} + }; ++ static struct coef_fw coef0288[] = { ++ UPDATE_COEF(0x4f, 0xfcc0, 0xc400), ++ UPDATE_COEF(0x50, 0x2000, 0x2000), ++ UPDATE_COEF(0x56, 0x0006, 0x0006), ++ UPDATE_COEF(0x66, 0x0008, 0), ++ UPDATE_COEF(0x67, 0x2000, 0), ++ {} ++ }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x76, 0x000e), + WRITE_COEF(0x6c, 0x2400), +@@ -3573,6 +3581,10 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) + case 0x10ec0283: + alc_process_coef_fw(codec, coef0233); + break; ++ case 0x10ec0286: ++ case 0x10ec0288: ++ alc_process_coef_fw(codec, coef0288); ++ break; + case 0x10ec0292: + alc_process_coef_fw(codec, coef0292); + break; +@@ -3602,6 +3614,14 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, + WRITE_COEF(0x26, 0x008c), + {} + }; ++ static struct coef_fw coef0288[] = { ++ UPDATE_COEF(0x50, 0x2000, 0), ++ UPDATE_COEF(0x56, 0x0006, 0), ++ UPDATE_COEF(0x4f, 0xfcc0, 0xc400), ++ UPDATE_COEF(0x66, 0x0008, 0x0008), ++ UPDATE_COEF(0x67, 0x2000, 0x2000), ++ {} ++ }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x19, 0xa208), + WRITE_COEF(0x2e, 0xacf0), +@@ -3635,6 +3655,13 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, + alc_process_coef_fw(codec, coef0233); + snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); + break; ++ case 0x10ec0286: ++ case 0x10ec0288: ++ alc_update_coef_idx(codec, 0x4f, 0x000c, 0); ++ snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); ++ alc_process_coef_fw(codec, coef0288); ++ snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); ++ break; + case 0x10ec0292: + snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); + alc_process_coef_fw(codec, coef0292); +@@ -3670,6 +3697,14 @@ static void alc_headset_mode_default(struct hda_codec *codec) + WRITE_COEF(0x32, 0x4ea3), + {} + }; ++ static struct coef_fw coef0288[] = { ++ UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */ ++ UPDATE_COEF(0x50, 0x2000, 0x2000), ++ UPDATE_COEF(0x56, 0x0006, 0x0006), ++ UPDATE_COEF(0x66, 0x0008, 0), ++ UPDATE_COEF(0x67, 0x2000, 0), ++ {} ++ }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x76, 0x000e), + WRITE_COEF(0x6c, 0x2400), +@@ -3699,6 +3734,11 @@ static void alc_headset_mode_default(struct hda_codec *codec) + case 0x10ec0283: + alc_process_coef_fw(codec, coef0233); + break; ++ case 0x10ec0286: ++ case 0x10ec0288: ++ alc_process_coef_fw(codec, coef0288); ++ break; ++ break; + case 0x10ec0292: + alc_process_coef_fw(codec, coef0292); + break; +@@ -3727,6 +3767,13 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) + WRITE_COEF(0x32, 0x4ea3), + {} + }; ++ static struct coef_fw coef0288[] = { ++ UPDATE_COEF(0x50, 0x2000, 0x2000), ++ UPDATE_COEF(0x56, 0x0006, 0x0006), ++ UPDATE_COEF(0x66, 0x0008, 0), ++ UPDATE_COEF(0x67, 0x2000, 0), ++ {} ++ }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x6b, 0xd429), + WRITE_COEF(0x76, 0x0008), +@@ -3754,6 +3801,12 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) + case 0x10ec0283: + alc_process_coef_fw(codec, coef0233); + break; ++ case 0x10ec0286: ++ case 0x10ec0288: ++ alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400); ++ msleep(300); ++ alc_process_coef_fw(codec, coef0288); ++ break; + case 0x10ec0292: + alc_process_coef_fw(codec, coef0292); + break; +@@ -3782,6 +3835,13 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) + WRITE_COEF(0x32, 0x4ea3), + {} + }; ++ static struct coef_fw coef0288[] = { ++ UPDATE_COEF(0x50, 0x2000, 0x2000), ++ UPDATE_COEF(0x56, 0x0006, 0x0006), ++ UPDATE_COEF(0x66, 0x0008, 0), ++ UPDATE_COEF(0x67, 0x2000, 0), ++ {} ++ }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x6b, 0xe429), + WRITE_COEF(0x76, 0x0008), +@@ -3809,6 +3869,12 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) + case 0x10ec0283: + alc_process_coef_fw(codec, coef0233); + break; ++ case 0x10ec0286: ++ case 0x10ec0288: ++ alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400); ++ msleep(300); ++ alc_process_coef_fw(codec, coef0288); ++ break; + case 0x10ec0292: + alc_process_coef_fw(codec, coef0292); + break; +@@ -3833,6 +3899,10 @@ static void alc_determine_headset_type(struct hda_codec *codec) + conteol) */ + {} + }; ++ static struct coef_fw coef0288[] = { ++ UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */ ++ {} ++ }; + static struct coef_fw coef0293[] = { + UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */ + WRITE_COEF(0x45, 0xD429), /* Set to ctia type */ +@@ -3861,6 +3931,13 @@ static void alc_determine_headset_type(struct hda_codec *codec) + val = alc_read_coef_idx(codec, 0x46); + is_ctia = (val & 0x0070) == 0x0070; + break; ++ case 0x10ec0286: ++ case 0x10ec0288: ++ alc_process_coef_fw(codec, coef0288); ++ msleep(350); ++ val = alc_read_coef_idx(codec, 0x50); ++ is_ctia = (val & 0x0070) == 0x0070; ++ break; + case 0x10ec0292: + alc_write_coef_idx(codec, 0x6b, 0xd429); + msleep(300); +-- +cgit v0.10.2 + diff --git a/kernel/kernel/files/patches/mageia/sound-bluetooth-SCO-support.patch b/kernel/kernel/files/patches/mageia/sound-bluetooth-SCO-support.patch new file mode 100644 index 00000000..3fe7325a --- /dev/null +++ b/kernel/kernel/files/patches/mageia/sound-bluetooth-SCO-support.patch @@ -0,0 +1,1296 @@ +Subject: Support a Bluetooth SCO. + +This patch is need of supporting it with an SCO(Synchronous +Connection Oriented links) device. +The SCO of Bluetooth sound device. + +This patch has to change configuration of kernel. + +Signed-off-by: Go Taniguchi + +--- + sound/drivers/Kconfig | 6 + sound/drivers/Makefile | 1 + sound/drivers/btsco.c | 1252 +++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 1259 insertions(+) + +--- a/sound/drivers/Kconfig ++++ b/sound/drivers/Kconfig +@@ -113,6 +113,12 @@ config SND_MTS64 + To compile this driver as a module, chose 'M' here: the module + will be called snd-mts64. + ++config SND_BT_SCO ++ tristate "bluetooth SCO audio support" ++ select SND_HWDEP ++ help ++ Say 'Y' or 'M' to include support for bluetooth SCO audio support ++ + config SND_SERIAL_U16550 + tristate "UART16550 serial MIDI driver" + select SND_RAWMIDI +--- a/sound/drivers/Makefile ++++ b/sound/drivers/Makefile +@@ -7,6 +7,7 @@ snd-dummy-objs := dummy.o + snd-aloop-objs := aloop.o + snd-mtpav-objs := mtpav.o + snd-mts64-objs := mts64.o ++snd-bt-sco-objs := btsco.o + snd-portman2x4-objs := portman2x4.o + snd-serial-u16550-objs := serial-u16550.o + snd-virmidi-objs := virmidi.o +--- /dev/null ++++ b/sound/drivers/btsco.c +@@ -0,0 +1,1252 @@ ++/* ++ * Bluetooth SCO soundcard ++ * Copyright (c) 2003, 2004 by Jonathan Paisley ++ * ++ * Based on dummy.c which is ++ * Copyright (c) by Jaroslav Kysela ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++ ++/* note: defining these two independently is not tested, ++ * thus not recommended ++ */ ++ ++/* enable dynamic compression */ ++#define DYNAMIC_COMPRESSION ++/* enable automatic endianness fixup */ ++#define AUTO_FIXUP_BYTESHIFT ++ ++ ++#ifdef DYNAMIC_COMPRESSION ++/* Autoadjust mic at most this often in 1/8000s */ ++#define GRABSAMPLES 400 ++/* Maximum push for the mike 16= 1:1 - default 20:1 = 320 */ ++#define COMPRESSION_MAX_16 320 ++/* Minimum push for the mike 1= 1:16 */ ++#define COMPRESSION_MIN_16 1 ++#endif ++ ++#define chip_t snd_card_bt_sco_t ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#define SNDRV_GET_ID ++#include ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) ++#include ++#else ++#define mutex semaphore ++#define mutex_init init_MUTEX ++#define mutex_lock down ++#define mutex_unlock up ++#endif ++ ++#ifndef SNDRV_HWDEP_IFACE_BLUETOOTH ++#define SNDRV_HWDEP_IFACE_BLUETOOTH (SNDRV_HWDEP_IFACE_EMUX_WAVETABLE + 1) ++#endif ++ ++#ifndef SNDRV_HWDEP_IFACE_BT_SCO ++#define SNDRV_HWDEP_IFACE_BT_SCO (SNDRV_HWDEP_IFACE_BLUETOOTH + 1) ++#endif ++ ++#define SNDRV_BT_SCO_IOCTL_SET_SCO_SOCKET _IOW ('H', 0x10, int) ++#define SNDRV_BT_SCO_IOCTL_REQ_INFO _IO ('H', 0x11) ++ ++MODULE_AUTHOR("Jonathan Paisley "); ++MODULE_DESCRIPTION("Bluetooth SCO Headset Soundcard"); ++MODULE_LICENSE("GPL"); ++MODULE_SUPPORTED_DEVICE("{{ALSA,Bluetooth SCO Soundcard}}"); ++ ++static char *mod_revision = "$Revision: 1.13 $"; ++ ++static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */ ++ ++module_param_array(index, int, NULL, 0444); ++MODULE_PARM_DESC(index, "Index value for Bluetooth SCO Headset Soundcard."); ++ ++#undef dprintk ++#if 1 ++#define dprintk(fmt...) printk(KERN_INFO "snd-bt-sco: " fmt) ++#else ++#define dprintk(fmt...) do {} while(0) ++#endif ++ ++#define MAX_BUFFER_SIZE (32*1024) ++ ++#define MIXER_ADDR_MASTER 0 ++#define MIXER_ADDR_MIC 1 ++#define MIXER_ADDR_LAST 1 ++ ++#define MIXER_MASK_MASTER 1 ++#define MIXER_MASK_MIC 2 ++ ++#define MIXER_MIN_VOLUME 1 ++#define MIXER_MAX_VOLUME 15 ++ ++struct snd_card_bt_sco_pcm; ++ ++typedef struct snd_card_bt_sco_info { ++ int mixer_volume[MIXER_ADDR_LAST + 1]; ++ int playback_count, capture_count; ++} snd_card_bt_sco_info_t; ++ ++typedef struct snd_card_bt_sco { ++ snd_card_t *card; ++ spinlock_t mixer_lock; ++ int mixer_volume[MIXER_ADDR_LAST + 1]; ++#ifdef DYNAMIC_COMPRESSION ++ snd_kcontrol_t *mixer_controls[MIXER_ADDR_LAST + 2 + 1]; /* also loopback and agc */ ++#else ++ snd_kcontrol_t *mixer_controls[MIXER_ADDR_LAST + 2 ]; /* also loopback */ ++#endif ++ volatile int loopback; ++#ifdef DYNAMIC_COMPRESSION ++ volatile int agc; ++#endif ++ atomic_t playback_count, capture_count; ++ volatile int count_changed; ++ spinlock_t count_changed_lock; ++ ++ spinlock_t mixer_changed_lock; ++ volatile int mixer_changed; ++ wait_queue_head_t hwdep_wait; ++ ++ int thread_pid; ++ struct completion thread_done; ++ ++ volatile int thread_exit; ++ struct mutex thread_sem; ++ ++ volatile struct socket *sco_sock; ++ struct mutex sock_sem; ++ wait_queue_head_t wait; ++ ++ struct mutex playback_sem; ++ struct snd_card_bt_sco_pcm *playback; ++ struct mutex capture_sem; ++ struct snd_card_bt_sco_pcm *capture; ++} snd_card_bt_sco_t; ++ ++typedef struct snd_card_bt_sco_pcm { ++ snd_card_bt_sco_t *bt_sco; ++ spinlock_t lock; ++ unsigned int pcm_size; ++ unsigned int pcm_count; ++ unsigned int pcm_bps; /* bytes per second */ ++ unsigned int pcm_irq_pos; /* IRQ position */ ++ unsigned int pcm_buf_pos; /* position in buffer */ ++ snd_pcm_substream_t *substream; ++} snd_card_bt_sco_pcm_t; ++ ++static snd_card_t *snd_bt_sco_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; ++ ++static int snd_card_bt_sco_playback_trigger(snd_pcm_substream_t * ++ substream, int cmd) ++{ ++ snd_pcm_runtime_t *runtime = substream->runtime; ++ snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; ++ snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); ++ ++ dprintk("playback_trigger %d\n", cmd); ++ ++ if (cmd == SNDRV_PCM_TRIGGER_START) { ++ bt_sco->playback = bspcm; ++ dprintk("setting playback to bspcm\n"); ++ } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { ++ bt_sco->playback = NULL; ++ dprintk("setting playback to NULL\n"); ++ } else { ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int snd_card_bt_sco_capture_trigger(snd_pcm_substream_t * ++ substream, int cmd) ++{ ++ snd_pcm_runtime_t *runtime = substream->runtime; ++ snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; ++ snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); ++ ++ dprintk("capture_trigger %d\n", cmd); ++ ++ if (cmd == SNDRV_PCM_TRIGGER_START) { ++ bt_sco->capture = bspcm; ++ dprintk("setting capture to bspcm\n"); ++ } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { ++ bt_sco->capture = NULL; ++ dprintk("setting capture to NULL\n"); ++ } else { ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static int snd_card_bt_sco_pcm_prepare(snd_pcm_substream_t * substream) ++{ ++ snd_pcm_runtime_t *runtime = substream->runtime; ++ snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; ++ unsigned int bps; ++ ++ bps = runtime->rate * runtime->channels; ++ bps *= snd_pcm_format_width(runtime->format); ++ bps /= 8; ++ if (bps <= 0) ++ return -EINVAL; ++ bspcm->pcm_bps = bps; ++ bspcm->pcm_size = snd_pcm_lib_buffer_bytes(substream); ++ bspcm->pcm_count = snd_pcm_lib_period_bytes(substream); ++ bspcm->pcm_irq_pos = 0; ++ bspcm->pcm_buf_pos = 0; ++ dprintk("prepare ok bps: %d size: %d count: %d\n", ++ bspcm->pcm_bps, bspcm->pcm_size, bspcm->pcm_count); ++ return 0; ++} ++ ++static int snd_card_bt_sco_playback_prepare(snd_pcm_substream_t * substream) ++{ ++ return snd_card_bt_sco_pcm_prepare(substream); ++} ++ ++static int snd_card_bt_sco_capture_prepare(snd_pcm_substream_t * substream) ++{ ++ dprintk("capture_prepare\n"); ++ return snd_card_bt_sco_pcm_prepare(substream); ++} ++ ++static void snd_card_bt_sco_pcm_receive(snd_card_bt_sco_pcm_t * bspcm, ++ unsigned char *data, unsigned int len) ++{ ++ unsigned long flags; ++ unsigned int oldptr; ++ ++ spin_lock_irqsave(&bspcm->lock, flags); ++ oldptr = bspcm->pcm_buf_pos; ++ bspcm->pcm_irq_pos += len; ++ bspcm->pcm_buf_pos += len; ++ bspcm->pcm_buf_pos %= bspcm->pcm_size; ++ spin_unlock_irqrestore(&bspcm->lock, flags); ++ /* copy a data chunk */ ++ if (oldptr + len > bspcm->pcm_size) { ++ unsigned int cnt = bspcm->pcm_size - oldptr; ++ memcpy(bspcm->substream->runtime->dma_area + oldptr, data, cnt); ++ memcpy(bspcm->substream->runtime->dma_area, data + cnt, ++ len - cnt); ++ } else { ++ memcpy(bspcm->substream->runtime->dma_area + oldptr, data, len); ++ } ++ /* update the pointer, call callback if necessary */ ++ spin_lock_irqsave(&bspcm->lock, flags); ++ if (bspcm->pcm_irq_pos >= bspcm->pcm_count) { ++ bspcm->pcm_irq_pos %= bspcm->pcm_count; ++ spin_unlock_irqrestore(&bspcm->lock, flags); ++ snd_pcm_period_elapsed(bspcm->substream); ++ } else ++ spin_unlock_irqrestore(&bspcm->lock, flags); ++ ++} ++ ++static void snd_card_bt_sco_pcm_send(snd_card_bt_sco_pcm_t * bspcm, ++ unsigned char *data, unsigned int len) ++{ ++ unsigned long flags; ++ unsigned int oldptr; ++ ++ spin_lock_irqsave(&bspcm->lock, flags); ++ oldptr = bspcm->pcm_buf_pos; ++ bspcm->pcm_irq_pos += len; ++ bspcm->pcm_buf_pos += len; ++ bspcm->pcm_buf_pos %= bspcm->pcm_size; ++ spin_unlock_irqrestore(&bspcm->lock, flags); ++ /* copy a data chunk */ ++ if (oldptr + len > bspcm->pcm_size) { ++ unsigned int cnt = bspcm->pcm_size - oldptr; ++ memcpy(data, bspcm->substream->runtime->dma_area + oldptr, cnt); ++ memcpy(data + cnt, bspcm->substream->runtime->dma_area, ++ len - cnt); ++ } else { ++ memcpy(data, bspcm->substream->runtime->dma_area + oldptr, len); ++ } ++ /* update the pointer, call callback if necessary */ ++ spin_lock_irqsave(&bspcm->lock, flags); ++ if (bspcm->pcm_irq_pos >= bspcm->pcm_count) { ++ bspcm->pcm_irq_pos %= bspcm->pcm_count; ++ spin_unlock_irqrestore(&bspcm->lock, flags); ++ snd_pcm_period_elapsed(bspcm->substream); ++ } else ++ spin_unlock_irqrestore(&bspcm->lock, flags); ++} ++ ++static snd_pcm_uframes_t ++snd_card_bt_sco_playback_pointer(snd_pcm_substream_t * substream) ++{ ++ snd_pcm_runtime_t *runtime = substream->runtime; ++ snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; ++ ++ return bytes_to_frames(runtime, bspcm->pcm_buf_pos); ++} ++ ++static snd_pcm_uframes_t ++snd_card_bt_sco_capture_pointer(snd_pcm_substream_t * substream) ++{ ++ snd_pcm_runtime_t *runtime = substream->runtime; ++ snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; ++ ++ return bytes_to_frames(runtime, bspcm->pcm_buf_pos); ++} ++ ++static snd_pcm_hardware_t snd_card_bt_sco_playback = { ++ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_MMAP_VALID), ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = SNDRV_PCM_RATE_8000, ++ .rate_min = 8000, ++ .rate_max = 8000, ++ .channels_min = 1, ++ .channels_max = 1, ++ .buffer_bytes_max = MAX_BUFFER_SIZE, ++ .period_bytes_min = 24, ++ .period_bytes_max = MAX_BUFFER_SIZE, ++ .periods_min = 1, ++ .periods_max = 4 * 8000 / 24, ++ .fifo_size = 0, ++}; ++ ++static snd_pcm_hardware_t snd_card_bt_sco_capture = { ++ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_MMAP_VALID), ++ .formats = SNDRV_PCM_FMTBIT_S16_LE, ++ .rates = SNDRV_PCM_RATE_8000, ++ .rate_min = 8000, ++ .rate_max = 8000, ++ .channels_min = 1, ++ .channels_max = 1, ++ .buffer_bytes_max = MAX_BUFFER_SIZE, ++ .period_bytes_min = 24, ++ .period_bytes_max = MAX_BUFFER_SIZE, ++ .periods_min = 1, ++ .periods_max = 4 * 8000 / 24, ++ .fifo_size = 0, ++}; ++ ++static void snd_card_bt_sco_runtime_free(snd_pcm_runtime_t * runtime) ++{ ++ snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; ++ kfree(bspcm); ++} ++ ++static int snd_card_bt_sco_playback_open(snd_pcm_substream_t * substream) ++{ ++ snd_pcm_runtime_t *runtime = substream->runtime; ++ snd_card_bt_sco_pcm_t *bspcm; ++ snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); ++ ++ dprintk("playback_open\n"); ++ ++ bspcm = kmalloc(sizeof(*bspcm), GFP_KERNEL); ++ if (bspcm == NULL) ++ return -ENOMEM; ++ memset(bspcm, 0, sizeof(*bspcm)); ++ if ((runtime->dma_area = ++ snd_malloc_pages(MAX_BUFFER_SIZE, GFP_KERNEL)) == NULL) { ++ kfree(bspcm); ++ return -ENOMEM; ++ } ++ runtime->dma_bytes = MAX_BUFFER_SIZE; ++ spin_lock_init(&bspcm->lock); ++ bspcm->substream = substream; ++ runtime->private_data = bspcm; ++ runtime->private_free = snd_card_bt_sco_runtime_free; ++ runtime->hw = snd_card_bt_sco_playback; ++ ++ atomic_inc(&bt_sco->playback_count); ++ spin_lock_irq(&bt_sco->count_changed_lock); ++ bt_sco->count_changed = 1; ++ spin_unlock_irq(&bt_sco->count_changed_lock); ++ wake_up(&bt_sco->hwdep_wait); ++ ++ return 0; ++} ++ ++static int snd_card_bt_sco_capture_open(snd_pcm_substream_t * substream) ++{ ++ snd_pcm_runtime_t *runtime = substream->runtime; ++ snd_card_bt_sco_pcm_t *bspcm; ++ snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); ++ ++ dprintk("capture_open\n"); ++ ++ bspcm = kmalloc(sizeof(*bspcm), GFP_KERNEL); ++ if (bspcm == NULL) ++ return -ENOMEM; ++ memset(bspcm, 0, sizeof(*bspcm)); ++ if ((runtime->dma_area = ++ snd_malloc_pages(MAX_BUFFER_SIZE, GFP_KERNEL)) == NULL) { ++ kfree(bspcm); ++ return -ENOMEM; ++ } ++ runtime->dma_bytes = MAX_BUFFER_SIZE; ++ memset(runtime->dma_area, 0, runtime->dma_bytes); ++ spin_lock_init(&bspcm->lock); ++ bspcm->substream = substream; ++ runtime->private_data = bspcm; ++ runtime->private_free = snd_card_bt_sco_runtime_free; ++ runtime->hw = snd_card_bt_sco_capture; ++ ++ atomic_inc(&bt_sco->capture_count); ++ spin_lock_irq(&bt_sco->count_changed_lock); ++ bt_sco->count_changed = 1; ++ spin_unlock_irq(&bt_sco->count_changed_lock); ++ wake_up(&bt_sco->hwdep_wait); ++ ++ return 0; ++} ++ ++static int snd_card_bt_sco_playback_close(snd_pcm_substream_t * substream) ++{ ++ snd_pcm_runtime_t *runtime = substream->runtime; ++ snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); ++ ++ snd_assert(bt_sco->playback == NULL,; ++ ); ++ ++ /* Ensure any references to this in our thread have finished */ ++ mutex_lock(&bt_sco->playback_sem); ++ mutex_unlock(&bt_sco->playback_sem); ++ ++ atomic_dec(&bt_sco->playback_count); ++ spin_lock_irq(&bt_sco->count_changed_lock); ++ bt_sco->count_changed = 1; ++ spin_unlock_irq(&bt_sco->count_changed_lock); ++ wake_up(&bt_sco->hwdep_wait); ++ ++ snd_free_pages(runtime->dma_area, runtime->dma_bytes); ++ return 0; ++} ++ ++static int snd_card_bt_sco_capture_close(snd_pcm_substream_t * substream) ++{ ++ snd_pcm_runtime_t *runtime = substream->runtime; ++ struct snd_card_bt_sco *bt_sco = ++ (struct snd_card_bt_sco *)substream->private_data; ++ ++ snd_assert(bt_sco->capture == NULL,; ++ ); ++ ++ /* Ensure any references to this in our thread have finished */ ++ mutex_lock(&bt_sco->capture_sem); ++ mutex_unlock(&bt_sco->capture_sem); ++ ++ atomic_dec(&bt_sco->capture_count); ++ spin_lock_irq(&bt_sco->count_changed_lock); ++ bt_sco->count_changed = 1; ++ spin_unlock_irq(&bt_sco->count_changed_lock); ++ wake_up(&bt_sco->hwdep_wait); ++ ++ snd_free_pages(runtime->dma_area, runtime->dma_bytes); ++ return 0; ++} ++ ++static snd_pcm_ops_t snd_card_bt_sco_playback_ops = { ++ .open = snd_card_bt_sco_playback_open, ++ .close = snd_card_bt_sco_playback_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .prepare = snd_card_bt_sco_playback_prepare, ++ .trigger = snd_card_bt_sco_playback_trigger, ++ .pointer = snd_card_bt_sco_playback_pointer, ++}; ++ ++static snd_pcm_ops_t snd_card_bt_sco_capture_ops = { ++ .open = snd_card_bt_sco_capture_open, ++ .close = snd_card_bt_sco_capture_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .prepare = snd_card_bt_sco_capture_prepare, ++ .trigger = snd_card_bt_sco_capture_trigger, ++ .pointer = snd_card_bt_sco_capture_pointer, ++}; ++ ++static int __init snd_card_bt_sco_pcm(snd_card_bt_sco_t * bt_sco) ++{ ++ snd_pcm_t *pcm; ++ int err; ++ ++ if ((err = ++ snd_pcm_new(bt_sco->card, "Bluetooth SCO PCM", 0, 1, 1, &pcm)) < 0) ++ return err; ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ++ &snd_card_bt_sco_playback_ops); ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, ++ &snd_card_bt_sco_capture_ops); ++ pcm->private_data = bt_sco; ++ pcm->info_flags = 0; ++ strcpy(pcm->name, "BT SCO PCM"); ++ return 0; ++} ++ ++#define BT_SCO_VOLUME(xname, xindex, addr) \ ++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ ++ .info = snd_bt_sco_volume_info, \ ++ .get = snd_bt_sco_volume_get, .put = snd_bt_sco_volume_put, \ ++ .private_value = addr } ++ ++static int snd_bt_sco_volume_info(snd_kcontrol_t * kcontrol, ++ snd_ctl_elem_info_t * uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; ++ uinfo->count = 1; ++ uinfo->value.integer.min = MIXER_MIN_VOLUME; ++ uinfo->value.integer.max = MIXER_MAX_VOLUME; ++ return 0; ++} ++ ++static int snd_bt_sco_volume_get(snd_kcontrol_t * kcontrol, ++ snd_ctl_elem_value_t * ucontrol) ++{ ++ snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); ++ unsigned long flags; ++ int addr = kcontrol->private_value; ++ ++ spin_lock_irqsave(&bt_sco->mixer_lock, flags); ++ ucontrol->value.integer.value[0] = bt_sco->mixer_volume[addr]; ++ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); ++ return 0; ++} ++ ++static int snd_bt_sco_volume_put(snd_kcontrol_t * kcontrol, ++ snd_ctl_elem_value_t * ucontrol) ++{ ++ snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); ++ unsigned long flags; ++ int changed, addr = kcontrol->private_value; ++ int vol; ++ ++ vol = ucontrol->value.integer.value[0]; ++ if (vol < MIXER_MIN_VOLUME) ++ vol = MIXER_MIN_VOLUME; ++ if (vol > MIXER_MAX_VOLUME) ++ vol = MIXER_MAX_VOLUME; ++ spin_lock_irqsave(&bt_sco->mixer_lock, flags); ++ changed = bt_sco->mixer_volume[addr] != vol; ++ bt_sco->mixer_volume[addr] = vol; ++ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); ++ if (changed) { ++ spin_lock_irqsave(&bt_sco->mixer_changed_lock, flags); ++ bt_sco->mixer_changed = 1; ++ spin_unlock_irqrestore(&bt_sco->mixer_changed_lock, flags); ++ wake_up(&bt_sco->hwdep_wait); ++ } ++ return changed; ++} ++ ++static int snd_bt_sco_boolean_info(snd_kcontrol_t * kcontrol, ++ snd_ctl_elem_info_t * uinfo) ++{ ++ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; ++ uinfo->count = 1; ++ uinfo->value.integer.min = 0; ++ uinfo->value.integer.max = 1; ++ return 0; ++} ++ ++static int snd_bt_sco_loopback_get(snd_kcontrol_t * kcontrol, ++ snd_ctl_elem_value_t * ucontrol) ++{ ++ snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&bt_sco->mixer_lock, flags); ++ ucontrol->value.integer.value[0] = bt_sco->loopback; ++ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); ++ return 0; ++} ++ ++static int snd_bt_sco_loopback_put(snd_kcontrol_t * kcontrol, ++ snd_ctl_elem_value_t * ucontrol) ++{ ++ snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); ++ unsigned long flags; ++ int changed; ++ int loopback; ++ ++ loopback = !!ucontrol->value.integer.value[0]; ++ ++ spin_lock_irqsave(&bt_sco->mixer_lock, flags); ++ changed = bt_sco->loopback != loopback; ++ bt_sco->loopback = loopback; ++ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); ++ return changed; ++} ++ ++#ifdef DYNAMIC_COMPRESSION ++static int snd_bt_sco_agc_get(snd_kcontrol_t * kcontrol, ++ snd_ctl_elem_value_t * ucontrol) ++{ ++ snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&bt_sco->mixer_lock, flags); ++ ucontrol->value.integer.value[0] = bt_sco->agc; ++ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); ++ return 0; ++} ++ ++static int snd_bt_sco_agc_put(snd_kcontrol_t * kcontrol, ++ snd_ctl_elem_value_t * ucontrol) ++{ ++ snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); ++ unsigned long flags; ++ int changed; ++ int agc; ++ ++ agc = !!ucontrol->value.integer.value[0]; ++ ++ spin_lock_irqsave(&bt_sco->mixer_lock, flags); ++ changed = bt_sco->agc != agc; ++ bt_sco->agc = agc; ++ spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); ++ return changed; ++} ++#endif ++ ++#define BT_SCO_CONTROLS (sizeof(snd_bt_sco_controls)/sizeof(snd_kcontrol_new_t)) ++ ++static snd_kcontrol_new_t snd_bt_sco_controls[] = { ++ BT_SCO_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER), ++ BT_SCO_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC), ++ {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "Loopback Switch", ++ .index = 0, ++ .info = snd_bt_sco_boolean_info, ++ .get = snd_bt_sco_loopback_get, ++ .put = snd_bt_sco_loopback_put, ++ } ++#ifdef DYNAMIC_COMPRESSION ++ , ++ {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, ++ .name = "AGC Switch", ++ .index = 0, ++ .info = snd_bt_sco_boolean_info, ++ .get = snd_bt_sco_agc_get, ++ .put = snd_bt_sco_agc_put, ++ } ++#endif ++}; ++ ++int __init snd_card_bt_sco_new_mixer(snd_card_bt_sco_t * bt_sco) ++{ ++ snd_card_t *card = bt_sco->card; ++ ++ unsigned int idx; ++ int err; ++ ++ snd_assert(bt_sco != NULL, return -EINVAL); ++ spin_lock_init(&bt_sco->mixer_lock); ++ strcpy(card->mixername, "BT Headset Mixer"); ++ ++ for (idx = 0; idx < BT_SCO_CONTROLS; idx++) { ++ bt_sco->mixer_controls[idx] = ++ snd_ctl_new1(&snd_bt_sco_controls[idx], bt_sco); ++ ++ if ((err = snd_ctl_add(card, bt_sco->mixer_controls[idx])) < 0) ++ return err; ++ } ++ return 0; ++} ++ ++static int snd_card_bt_open(snd_hwdep_t * hw, struct file *file) ++{ ++ return 0; ++} ++ ++static int snd_card_bt_release(snd_hwdep_t * hw, struct file *file) ++{ ++ return 0; ++} ++ ++static int snd_card_bt_ioctl(snd_hwdep_t * hw, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ snd_card_bt_sco_t *bt_sco = hw->card->private_data; ++ struct socket *sock; ++ int err = -ENOTTY; ++ int fd = arg; ++ ++ switch (cmd) { ++ case SNDRV_BT_SCO_IOCTL_SET_SCO_SOCKET: ++ err = 0; ++ /* Interrupt any socket operations, so that we may ++ * change the socket */ ++ mutex_lock(&bt_sco->sock_sem); ++ kill_proc(bt_sco->thread_pid, SIGINT, 1); ++ if (bt_sco->sco_sock) { ++ dprintk("Disposing of previous socket count %d\n", ++ file_count(bt_sco->sco_sock->file)); ++ /* Extra brackets needed here since sockfd_put is a poorly implemented macro */ ++ sockfd_put(((struct socket *)bt_sco->sco_sock)); ++ ++ bt_sco->sco_sock = NULL; ++ } ++ ++ if (fd >= 0) { ++ err = -EINVAL; ++ sock = sockfd_lookup(fd, &err); ++ if (sock) { ++ if (sock->sk->sk_family == PF_BLUETOOTH && ++ sock->sk->sk_protocol == BTPROTO_SCO) { ++ bt_sco->sco_sock = sock; ++ wake_up(&bt_sco->wait); ++ err = 0; ++ } else { ++ dprintk ++ ("Not a bluetooth SCO socket %d:%d\n", ++ sock->sk->sk_family, ++ sock->sk->sk_protocol); ++ sockfd_put(sock); ++ } ++ } ++ } ++ mutex_unlock(&bt_sco->sock_sem); ++ break; ++ case SNDRV_BT_SCO_IOCTL_REQ_INFO: ++ spin_lock_irq(&bt_sco->count_changed_lock); ++ bt_sco->count_changed = 1; ++ spin_unlock_irq(&bt_sco->count_changed_lock); ++ wake_up(&bt_sco->hwdep_wait); ++ break; ++ } ++ return err; ++} ++ ++static long snd_card_bt_write(snd_hwdep_t * hw, const char *buf, long count, ++ loff_t * offset) ++{ ++ snd_card_bt_sco_t *bt_sco = hw->card->private_data; ++ int mixer_volume[MIXER_ADDR_LAST + 1]; ++ int retval; ++ int i; ++ ++ if (count != sizeof(mixer_volume)) ++ return -EINVAL; ++ ++ if (copy_from_user(mixer_volume, buf, sizeof(mixer_volume))) ++ return -EFAULT; ++ ++ retval = sizeof(mixer_volume); ++ ++ spin_lock_irq(&bt_sco->mixer_lock); ++ for (i = 0; i <= MIXER_ADDR_LAST; i++) { ++ int vol = mixer_volume[i]; ++ if (vol > MIXER_MAX_VOLUME) ++ vol = MIXER_MAX_VOLUME; ++ if (vol < MIXER_MIN_VOLUME) ++ vol = MIXER_MIN_VOLUME; ++ if (bt_sco->mixer_volume[i] != vol) { ++ bt_sco->mixer_volume[i] = vol; ++ snd_ctl_notify(bt_sco->card, ++ SNDRV_CTL_EVENT_MASK_VALUE, ++ &bt_sco->mixer_controls[i]->id); ++ } ++ } ++ spin_unlock_irq(&bt_sco->mixer_lock); ++ ++ return retval; ++} ++ ++static long snd_card_bt_read(snd_hwdep_t * hw, char *buf, long count, ++ loff_t * offset) ++{ ++ snd_card_bt_sco_t *bt_sco = hw->card->private_data; ++ DECLARE_WAITQUEUE(wait, current); ++ ssize_t retval; ++ int changed; ++ snd_card_bt_sco_info_t infobuf; ++ ++ if (count < sizeof(bt_sco->mixer_volume)) ++ return -EINVAL; ++ ++ add_wait_queue(&bt_sco->hwdep_wait, &wait); ++ current->state = TASK_INTERRUPTIBLE; ++ do { ++ changed = 0; ++ spin_lock_irq(&bt_sco->mixer_changed_lock); ++ if(bt_sco->mixer_changed) ++ changed = 1; ++ bt_sco->mixer_changed = 0; ++ spin_unlock_irq(&bt_sco->mixer_changed_lock); ++ ++ spin_lock_irq(&bt_sco->count_changed_lock); ++ if(bt_sco->count_changed) ++ changed = 1; ++ bt_sco->count_changed = 0; ++ spin_unlock_irq(&bt_sco->count_changed_lock); ++ ++ if (changed != 0) ++ break; ++ ++ if (signal_pending(current)) { ++ retval = -ERESTARTSYS; ++ goto out; ++ } ++ schedule(); ++ } while (1); ++ ++ memcpy(infobuf.mixer_volume, bt_sco->mixer_volume, sizeof(infobuf.mixer_volume)); ++ infobuf.playback_count = atomic_read(&bt_sco->playback_count); ++ infobuf.capture_count = atomic_read(&bt_sco->capture_count); ++ ++ if (copy_to_user ++ (buf, &infobuf, sizeof(infobuf))) ++ retval = -EFAULT; ++ else ++ retval = sizeof(infobuf); ++ ++ out: ++ current->state = TASK_RUNNING; ++ remove_wait_queue(&bt_sco->hwdep_wait, &wait); ++ return retval; ++} ++ ++static unsigned int snd_card_bt_poll(snd_hwdep_t * hw, ++ struct file *file, poll_table * wait) ++{ ++ snd_card_bt_sco_t *bt_sco = hw->card->private_data; ++ int ret; ++ ++ poll_wait(file, &bt_sco->hwdep_wait, wait); ++ ++ ret = 0; ++ spin_lock_irq(&bt_sco->mixer_changed_lock); ++ if(bt_sco->mixer_changed) ++ ret |= POLLIN | POLLRDNORM; ++ spin_unlock_irq(&bt_sco->mixer_changed_lock); ++ ++ spin_lock_irq(&bt_sco->count_changed_lock); ++ if(bt_sco->count_changed) ++ ret |= POLLIN | POLLRDNORM; ++ spin_unlock_irq(&bt_sco->count_changed_lock); ++ ++ return ret; ++} ++ ++static int snd_card_bt_sco_thread(void *data) ++{ ++ snd_card_t *card = (snd_card_t *) data; ++ snd_card_bt_sco_t *bt_sco = card->private_data; ++ struct socket *sock; ++ int len; ++#define BUF_SIZE 256 ++ unsigned char buf[BUF_SIZE]; ++ struct msghdr msg; ++ struct iovec iov; ++ sigset_t unblocked; ++#if defined(DYNAMIC_COMPRESSION) || defined(AUTO_FIXUP_BYTESHIFT) ++ int i; ++#endif ++#ifdef DYNAMIC_COMPRESSION ++ static int factor=16; ++ static int maxvalsmoothed=0; ++ static int maxvalgrablen=GRABSAMPLES; /* adjust volume at most 4 times/second */ ++#endif ++#ifdef AUTO_FIXUP_BYTESHIFT ++ static int shift=0; ++ static unsigned char lastbyte; ++#endif ++ ++ lock_kernel(); ++ ++ daemonize("snd-bt-scod"); ++ sigemptyset(&unblocked); ++ sigaddset(&unblocked, SIGINT); ++ sigaddset(&unblocked, SIGTERM); ++ sigprocmask(SIG_UNBLOCK, &unblocked, NULL); ++ ++ /* Pretend so that copy_to_user and friends work */ ++ set_fs(KERNEL_DS); ++ ++ dprintk("snd-bt-scod thread starting\n"); ++ mutex_unlock(&bt_sco->thread_sem); ++ ++ do { ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)) ++ try_to_freeze(); ++#else ++ if (current->flags & PF_FREEZE) ++ refrigerator(PF_FREEZE); ++#endif ++ ++ if (signal_pending(current)) ++ flush_signals(current); ++ ++ /* This may be woken up by a wake_up() when ++ * a new socket is installed, or by a signal. ++ * Signals are sent to terminate the thread, ++ * in which case thread_exit is set, and to force ++ * recvmesg() to wake up (from the ioctl handler) ++ */ ++ wait_event_interruptible(bt_sco->wait, bt_sco->sco_sock != 0); ++ if (bt_sco->thread_exit) ++ break; ++ ++ mutex_lock(&bt_sco->sock_sem); ++ sock = (struct socket *)bt_sco->sco_sock; ++ if (sock) ++ get_file(sock->file); ++ mutex_unlock(&bt_sco->sock_sem); ++ ++ if (!sock) ++ continue; ++ ++ /* We have a socket, let's read from it and write to it... */ ++ ++ memset(&msg, 0, sizeof(msg)); ++ msg.msg_iov = &iov; ++ iov.iov_base = buf; ++ iov.iov_len = BUF_SIZE; ++ ++ /* This will block until we receive data or a signal */ ++ len = sock_recvmsg(sock, &msg, BUF_SIZE, 0); ++ if (len > 0) { ++ ++#if defined (AUTO_FIXUP_BYTESHIFT) || defined (DYNAMIC_COMPRESSION) ++ ++#ifdef AUTO_FIXUP_BYTESHIFT ++ int lostatcnt=0; ++#endif ++ if (len&1) dprintk("odd len %d\n",len); ++#ifdef AUTO_FIXUP_BYTESHIFT ++ if (shift) { ++ unsigned char newlastbyte; ++ newlastbyte=buf[len-1]; ++ memmove(buf+1,buf,len-1); ++ buf[0]=lastbyte; ++ lastbyte=newlastbyte; ++ } ++#endif ++ for(i=0;i0x7fff) { ++ k=0x7fff; ++ if (bt_sco->agc&&factor>COMPRESSION_MIN_16) factor--; ++ } else if (k<-0x8000) { ++ k=0x8000; ++ if (bt_sco->agc&&factor>COMPRESSION_MIN_16) factor--; ++ } ++ buf[i+1]=(k>>8)&0xff; ++ buf[i ]=k&0xff; ++ ++ /* find the highest absolute value in a ++ * GRABSAMPLES long interval. ++ */ ++ if (k<0) k=-j; ++ if (k>maxvalsmoothed) maxvalsmoothed=k; ++ /* if the interval is over, recalculate ++ * the compression factor. Move it slowly. ++ */ ++ if (maxvalgrablen--<=0) { ++ maxvalgrablen=GRABSAMPLES; ++ /* If the noise goes up over 1000, we stop ++ * pushing the software gain ++ */ ++ if (maxvalsmoothed<1000&&factoragc) factor=16; ++ maxvalsmoothed=0; ++ } ++#endif ++ } ++#ifdef AUTO_FIXUP_BYTESHIFT ++ if (lostatcnt==len/2&&len>32) { ++ shift=!shift; ++ //dprintk("Shift problem detected! Fixing to %d.\n",shift); ++ } ++#endif ++#endif /* any of them */ ++ mutex_lock(&bt_sco->capture_sem); ++ if (bt_sco->capture) { ++ snd_card_bt_sco_pcm_receive ++ (bt_sco->capture, buf, len); ++ } ++ mutex_unlock(&bt_sco->capture_sem); ++ ++ mutex_lock(&bt_sco->playback_sem); ++ ++ if (bt_sco->playback || !bt_sco->loopback) { ++ memset(buf, 0, len); ++#if 0 ++ /* fill with tone instead of silence */ ++ int i; ++ ++ for (i = 0; i < len / 2; i++) { ++ buf[i] = 0; ++ } ++ for (i = len / 2; i < len; i++) { ++ buf[i] = 127; ++ } ++#endif ++ } ++ if (bt_sco->playback) { ++ int i, notzero = -1; ++ ++ snd_card_bt_sco_pcm_send ++ (bt_sco->playback, buf, len); ++ ++ /* Strangely, when the device is open but no audio is ++ being written by the app, there's an occasional glitch ++ in the silence data. This hack eliminates it. */ ++ ++ for (i = 0; i < len; i++) { ++ if (buf[i] != 0) { ++ if (notzero >= 0) ++ break; ++ notzero = i; ++ } ++ } ++ if (notzero >= 0 && i >= len) { ++ buf[notzero] = 0; ++ } ++ } ++ mutex_unlock(&bt_sco->playback_sem); ++ ++#if 0 ++ /* This chunk of code lets us record (using arecord) ++ what data alsa is sending out. ++ ++ e.g., when idle, we'd expect something like: ++ ++ 8080 8080 8080 8080 8483 8281 8182 8384 ++ 8080 8080 8080 8080 8080 8080 8080 8080 ++ 8080 8080 8080 8080 8483 8281 8182 8384 ++ 8080 8080 8080 8080 8080 8080 8080 8080 ++ ++ (this is from 'xxd' of a wav file, that data in ++ which is unsigned, whereas we are dealing with signed). ++ */ ++ ++ mutex_lock(&bt_sco->capture_sem); ++ if (bt_sco->capture) { ++ snd_card_bt_sco_pcm_receive ++ (bt_sco->capture, "\001\002\003\004", 4); ++ snd_card_bt_sco_pcm_receive ++ (bt_sco->capture, buf, len); ++ snd_card_bt_sco_pcm_receive ++ (bt_sco->capture, "\004\003\002\001", 4); ++ } ++ mutex_unlock(&bt_sco->capture_sem); ++#endif ++ msg.msg_flags = 0; ++ msg.msg_iov = &iov; ++ iov.iov_base = buf; ++ iov.iov_len = BUF_SIZE; ++ sock_sendmsg(sock, &msg, len); ++ } ++ ++ /* Expect this to be 3 because we (this thead) have a copy, ++ the driver process keeps one, and the app has the socket open. ++ */ ++ if (file_count(sock->file) != 3) { ++ dprintk("file_count is %d (expected 3)\n", ++ file_count(sock->file)); ++ } ++ fput(sock->file); ++ ++ schedule(); ++ } while (!bt_sco->thread_exit); ++ ++ dprintk("thread exiting\n"); ++ ++ unlock_kernel(); ++ complete_and_exit(&bt_sco->thread_done, 0); ++} ++ ++static void snd_card_bt_private_free(snd_card_t * card) ++{ ++ snd_card_bt_sco_t *bt_sco = card->private_data; ++ ++ dprintk("private_free, killing thread\n"); ++ bt_sco->thread_exit = 1; ++ kill_proc(bt_sco->thread_pid, SIGTERM, 1); ++ wait_for_completion(&bt_sco->thread_done); ++ dprintk("private_free, thread exited\n"); ++ ++ if (bt_sco->sco_sock) { ++ dprintk("shutdown: freeing socket count %d\n", ++ file_count(bt_sco->sco_sock->file)); ++ ++ sockfd_put(((struct socket *)bt_sco->sco_sock)); ++ } ++ ++ kfree(bt_sco); ++} ++ ++static int __init snd_card_bt_sco_probe(int dev) ++{ ++ snd_card_t *card; ++ snd_card_bt_sco_t *bt_sco; ++ int err; ++ snd_hwdep_t *hw; ++ ++ card = ++ snd_card_new(index[dev], SNDRV_DEFAULT_STR1, ++ THIS_MODULE, 0); ++ if (card == NULL) ++ return -ENOMEM; ++ ++ bt_sco = kmalloc(sizeof(*bt_sco), GFP_KERNEL); ++ if(bt_sco == NULL) ++ return -ENOMEM; ++ memset(bt_sco, 0, sizeof(*bt_sco)); ++ card->private_data = bt_sco; ++ card->private_free = snd_card_bt_private_free; ++ ++ bt_sco->card = card; ++ ++ init_completion(&bt_sco->thread_done); ++ mutex_init(&bt_sco->thread_sem); ++ mutex_lock(&bt_sco->thread_sem); ++ mutex_init(&bt_sco->sock_sem); ++ mutex_init(&bt_sco->capture_sem); ++ mutex_init(&bt_sco->playback_sem); ++ init_waitqueue_head(&bt_sco->wait); ++ init_waitqueue_head(&bt_sco->hwdep_wait); ++ spin_lock_init(&bt_sco->mixer_changed_lock); ++ spin_lock_init(&bt_sco->count_changed_lock); ++ ++ /* These clone flags copied from some other driver. ++ Not sure that they're really correct... */ ++ bt_sco->thread_pid = ++ kernel_thread(snd_card_bt_sco_thread, card, CLONE_KERNEL); ++ if (bt_sco->thread_pid < 0) { ++ err = bt_sco->thread_pid; ++ goto __nodev; ++ } ++ ++ mutex_lock(&bt_sco->thread_sem); ++ ++ if ((err = snd_card_bt_sco_pcm(bt_sco)) < 0) ++ goto __nodev; ++ if ((err = snd_card_bt_sco_new_mixer(bt_sco)) < 0) ++ goto __nodev; ++ strcpy(card->driver, "Bluetooth SCO"); ++ strcpy(card->shortname, "BT Headset"); ++ sprintf(card->longname, "BT Headset %i", dev + 1); ++ ++ err = snd_hwdep_new(card, "BTSCO", 0, &hw); ++ if (err < 0) ++ goto __nodev; ++ ++ sprintf(hw->name, "BTSCO"); ++ hw->iface = SNDRV_HWDEP_IFACE_BT_SCO; ++ hw->ops.open = snd_card_bt_open; ++ hw->ops.ioctl = snd_card_bt_ioctl; ++ hw->ops.release = snd_card_bt_release; ++ hw->ops.read = snd_card_bt_read; ++ hw->ops.write = snd_card_bt_write; ++ hw->ops.poll = snd_card_bt_poll; ++ ++ if ((err = snd_card_register(card)) == 0) { ++ snd_bt_sco_cards[dev] = card; ++ return 0; ++ } ++ __nodev: ++ snd_card_free(card); ++ return err; ++} ++ ++static int __init alsa_card_bt_sco_init(void) ++{ ++ printk(KERN_INFO "snd-bt-sco revision %s\n", mod_revision + 11); ++ ++ if (snd_card_bt_sco_probe(0) < 0) { ++#ifdef MODULE ++ printk(KERN_ERR ++ "Bluetooth SCO soundcard not found or device busy\n"); ++#endif ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++static void __exit alsa_card_bt_sco_exit(void) ++{ ++ int idx; ++ ++ for (idx = 0; idx < SNDRV_CARDS; idx++) ++ snd_card_free(snd_bt_sco_cards[idx]); ++} ++ ++module_init(alsa_card_bt_sco_init) ++ module_exit(alsa_card_bt_sco_exit) ++#ifndef MODULE ++static int __init alsa_card_bt_sco_setup(char *str) ++{ ++ static unsigned __initdata nr_dev = 0; ++ ++ if (nr_dev >= SNDRV_CARDS) ++ return 0; ++ nr_dev++; ++ return 1; ++} ++ ++__setup("snd-bt-sco=", alsa_card_bt_sco_setup); ++ ++#endif /* ifndef MODULE */ diff --git a/kernel/kernel/files/patches/mageia/uas-add-us_fl_max_sectors_240-flag.patch b/kernel/kernel/files/patches/mageia/uas-add-us_fl_max_sectors_240-flag.patch new file mode 100644 index 00000000..0a4fc4a6 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/uas-add-us_fl_max_sectors_240-flag.patch @@ -0,0 +1,98 @@ +From ee136af4a064c2f61e2025873584d2c7ec93f4ae Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 21 Apr 2015 11:20:31 +0200 +Subject: uas: Add US_FL_MAX_SECTORS_240 flag + +From: Hans de Goede + +commit ee136af4a064c2f61e2025873584d2c7ec93f4ae upstream. + +The usb-storage driver sets max_sectors = 240 in its scsi-host template, +for uas we do not want to do that for all devices, but testing has shown +that some devices need it. + +This commit adds a US_FL_MAX_SECTORS_240 flag for such devices, and +implements support for it in uas.c, while at it it also adds support +for US_FL_MAX_SECTORS_64 to uas.c. + +Signed-off-by: Hans de Goede +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/kernel-parameters.txt | 2 ++ + drivers/usb/storage/uas.c | 10 +++++++++- + drivers/usb/storage/usb.c | 6 +++++- + include/linux/usb_usual.h | 2 ++ + 4 files changed, 18 insertions(+), 2 deletions(-) + +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -3746,6 +3746,8 @@ bytes respectively. Such letter suffixes + READ_CAPACITY_16 command); + f = NO_REPORT_OPCODES (don't use report opcodes + command, uas only); ++ g = MAX_SECTORS_240 (don't transfer more than ++ 240 sectors at a time, uas only); + h = CAPACITY_HEURISTICS (decrease the + reported device capacity by one + sector if the number is odd); +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -759,7 +759,10 @@ static int uas_eh_bus_reset_handler(stru + + static int uas_slave_alloc(struct scsi_device *sdev) + { +- sdev->hostdata = (void *)sdev->host->hostdata; ++ struct uas_dev_info *devinfo = ++ (struct uas_dev_info *)sdev->host->hostdata; ++ ++ sdev->hostdata = devinfo; + + /* USB has unusual DMA-alignment requirements: Although the + * starting address of each scatter-gather element doesn't matter, +@@ -778,6 +781,11 @@ static int uas_slave_alloc(struct scsi_d + */ + blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); + ++ if (devinfo->flags & US_FL_MAX_SECTORS_64) ++ blk_queue_max_hw_sectors(sdev->request_queue, 64); ++ else if (devinfo->flags & US_FL_MAX_SECTORS_240) ++ blk_queue_max_hw_sectors(sdev->request_queue, 240); ++ + return 0; + } + +--- a/drivers/usb/storage/usb.c ++++ b/drivers/usb/storage/usb.c +@@ -479,7 +479,8 @@ void usb_stor_adjust_quirks(struct usb_d + US_FL_SINGLE_LUN | US_FL_NO_WP_DETECT | + US_FL_NO_READ_DISC_INFO | US_FL_NO_READ_CAPACITY_16 | + US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE | +- US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES); ++ US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES | ++ US_FL_MAX_SECTORS_240); + + p = quirks; + while (*p) { +@@ -520,6 +521,9 @@ void usb_stor_adjust_quirks(struct usb_d + case 'f': + f |= US_FL_NO_REPORT_OPCODES; + break; ++ case 'g': ++ f |= US_FL_MAX_SECTORS_240; ++ break; + case 'h': + f |= US_FL_CAPACITY_HEURISTICS; + break; +--- a/include/linux/usb_usual.h ++++ b/include/linux/usb_usual.h +@@ -77,6 +77,8 @@ + /* Cannot handle ATA_12 or ATA_16 CDBs */ \ + US_FLAG(NO_REPORT_OPCODES, 0x04000000) \ + /* Cannot handle MI_REPORT_SUPPORTED_OPERATION_CODES */ \ ++ US_FLAG(MAX_SECTORS_240, 0x08000000) \ ++ /* Sets max_sectors to 240 */ \ + + #define US_FLAG(name, value) US_FL_##name = value , + enum { US_DO_ALL_FLAGS }; diff --git a/kernel/kernel/files/patches/mageia/uas-allow-uas_use_uas_driver-to-return-usb-storage-flags.patch b/kernel/kernel/files/patches/mageia/uas-allow-uas_use_uas_driver-to-return-usb-storage-flags.patch new file mode 100644 index 00000000..beb6a750 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/uas-allow-uas_use_uas_driver-to-return-usb-storage-flags.patch @@ -0,0 +1,79 @@ +From a5011d44f0e1117a6db14b19b57c51f8be5673a0 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 21 Apr 2015 11:20:30 +0200 +Subject: uas: Allow uas_use_uas_driver to return usb-storage flags + +From: Hans de Goede + +commit a5011d44f0e1117a6db14b19b57c51f8be5673a0 upstream. + +uas_use_uas_driver may set some US_FL_foo flags during detection, currently +these are stored in a local variable and then throw away, but these may be +of interest to the caller, so add an extra parameter to (optionally) return +the detected flags, and use this in the uas driver. + +Signed-off-by: Hans de Goede +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/uas-detect.h | 6 +++++- + drivers/usb/storage/uas.c | 6 +++--- + drivers/usb/storage/usb.c | 2 +- + 3 files changed, 9 insertions(+), 5 deletions(-) + +--- a/drivers/usb/storage/uas-detect.h ++++ b/drivers/usb/storage/uas-detect.h +@@ -51,7 +51,8 @@ static int uas_find_endpoints(struct usb + } + + static int uas_use_uas_driver(struct usb_interface *intf, +- const struct usb_device_id *id) ++ const struct usb_device_id *id, ++ unsigned long *flags_ret) + { + struct usb_host_endpoint *eps[4] = { }; + struct usb_device *udev = interface_to_usbdev(intf); +@@ -132,5 +133,8 @@ static int uas_use_uas_driver(struct usb + return 0; + } + ++ if (flags_ret) ++ *flags_ret = flags; ++ + return 1; + } +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -887,8 +887,9 @@ static int uas_probe(struct usb_interfac + struct Scsi_Host *shost = NULL; + struct uas_dev_info *devinfo; + struct usb_device *udev = interface_to_usbdev(intf); ++ unsigned long dev_flags; + +- if (!uas_use_uas_driver(intf, id)) ++ if (!uas_use_uas_driver(intf, id, &dev_flags)) + return -ENODEV; + + if (uas_switch_interface(udev, intf)) +@@ -910,8 +911,7 @@ static int uas_probe(struct usb_interfac + devinfo->udev = udev; + devinfo->resetting = 0; + devinfo->shutdown = 0; +- devinfo->flags = id->driver_info; +- usb_stor_adjust_quirks(udev, &devinfo->flags); ++ devinfo->flags = dev_flags; + init_usb_anchor(&devinfo->cmd_urbs); + init_usb_anchor(&devinfo->sense_urbs); + init_usb_anchor(&devinfo->data_urbs); +--- a/drivers/usb/storage/usb.c ++++ b/drivers/usb/storage/usb.c +@@ -1080,7 +1080,7 @@ static int storage_probe(struct usb_inte + + /* If uas is enabled and this device can do uas then ignore it. */ + #if IS_ENABLED(CONFIG_USB_UAS) +- if (uas_use_uas_driver(intf, id)) ++ if (uas_use_uas_driver(intf, id, NULL)) + return -ENXIO; + #endif + diff --git a/kernel/kernel/files/patches/mageia/uas-set-max_sectors_240-quirk-for-asm1053-devices.patch b/kernel/kernel/files/patches/mageia/uas-set-max_sectors_240-quirk-for-asm1053-devices.patch new file mode 100644 index 00000000..6a00d620 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/uas-set-max_sectors_240-quirk-for-asm1053-devices.patch @@ -0,0 +1,43 @@ +From 8e779c6c4a398763c21371fe40f649206041dc1e Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 21 Apr 2015 11:20:32 +0200 +Subject: uas: Set max_sectors_240 quirk for ASM1053 devices + +From: Hans de Goede + +commit 8e779c6c4a398763c21371fe40f649206041dc1e upstream. + +Testing has shown that ASM1053 devices do not work properly with transfers +larger than 240 sectors, so set max_sectors to 240 on these. + +Reported-by: Steve Bangert +Signed-off-by: Hans de Goede +Tested-by: Steve Bangert +Acked-by: Alan Stern +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/uas-detect.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/usb/storage/uas-detect.h ++++ b/drivers/usb/storage/uas-detect.h +@@ -74,7 +74,7 @@ static int uas_use_uas_driver(struct usb + * this writing the following versions exist: + * ASM1051 - no uas support version + * ASM1051 - with broken (*) uas support +- * ASM1053 - with working uas support ++ * ASM1053 - with working uas support, but problems with large xfers + * ASM1153 - with working uas support + * + * Devices with these chips re-use a number of device-ids over the +@@ -104,6 +104,9 @@ static int uas_use_uas_driver(struct usb + } else if (usb_ss_max_streams(&eps[1]->ss_ep_comp) == 32) { + /* Possibly an ASM1051, disable uas */ + flags |= US_FL_IGNORE_UAS; ++ } else { ++ /* ASM1053, these have issues with large transfers */ ++ flags |= US_FL_MAX_SECTORS_240; + } + } + diff --git a/kernel/kernel/files/patches/mageia/usb-cdc-acm-prevent-infinite-loop-when-parsing-cdc-headers.patch b/kernel/kernel/files/patches/mageia/usb-cdc-acm-prevent-infinite-loop-when-parsing-cdc-headers.patch new file mode 100644 index 00000000..d80a6f77 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/usb-cdc-acm-prevent-infinite-loop-when-parsing-cdc-headers.patch @@ -0,0 +1,56 @@ +From 0d3bba0287d4e284c3ec7d3397e81eec920d5e7e Mon Sep 17 00:00:00 2001 +From: Quentin Casasnovas +Date: Tue, 14 Apr 2015 11:25:43 +0200 +Subject: cdc-acm: prevent infinite loop when parsing CDC headers. + +From: Quentin Casasnovas + +commit 0d3bba0287d4e284c3ec7d3397e81eec920d5e7e upstream. + +Phil and I found out a problem with commit: + + 7e860a6e7aa6 ("cdc-acm: add sanity checks") + +It added some sanity checks to ignore potential garbage in CDC headers but +also introduced a potential infinite loop. This can happen at the first +loop iteration (elength = 0 in that case) if the description isn't a +DT_CS_INTERFACE or later if 'buffer[0]' is zero. + +It should also be noted that the wrong length was being added to 'buffer' +in case 'buffer[1]' was not a DT_CS_INTERFACE descriptor, since elength was +assigned after that check in the loop. + +A specially crafted USB device could be used to trigger this infinite loop. + +Fixes: 7e860a6e7aa6 ("cdc-acm: add sanity checks") +Signed-off-by: Phil Turnbull +Signed-off-by: Quentin Casasnovas +CC: Sergei Shtylyov +CC: Oliver Neukum +CC: Adam Lee +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1133,11 +1133,16 @@ static int acm_probe(struct usb_interfac + } + + while (buflen > 0) { ++ elength = buffer[0]; ++ if (!elength) { ++ dev_err(&intf->dev, "skipping garbage byte\n"); ++ elength = 1; ++ goto next_desc; ++ } + if (buffer[1] != USB_DT_CS_INTERFACE) { + dev_err(&intf->dev, "skipping garbage\n"); + goto next_desc; + } +- elength = buffer[0]; + + switch (buffer[2]) { + case USB_CDC_UNION_TYPE: /* we've found it */ diff --git a/kernel/kernel/files/patches/mageia/usb-chipidea-otg-remove-mutex-unlock-and-lock-while-stop-and-start-role.patch b/kernel/kernel/files/patches/mageia/usb-chipidea-otg-remove-mutex-unlock-and-lock-while-stop-and-start-role.patch new file mode 100644 index 00000000..03ac59ec --- /dev/null +++ b/kernel/kernel/files/patches/mageia/usb-chipidea-otg-remove-mutex-unlock-and-lock-while-stop-and-start-role.patch @@ -0,0 +1,53 @@ +From a5a356cee89f86ff86cc3ce24136ca1f802c1bf1 Mon Sep 17 00:00:00 2001 +From: Li Jun +Date: Sun, 12 Apr 2015 17:51:02 +0800 +Subject: usb: chipidea: otg: remove mutex unlock and lock while stop and start role + +From: Li Jun + +commit a5a356cee89f86ff86cc3ce24136ca1f802c1bf1 upstream. + +Wrongly release mutex lock during otg_statemachine may result in re-enter +otg_statemachine, which is not allowed, we should do next state transtition +after previous one completed. + +Fixes: 826cfe751f3e ("usb: chipidea: add OTG fsm operation functions implementation") +Signed-off-by: Li Jun +Signed-off-by: Peter Chen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/chipidea/otg_fsm.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/drivers/usb/chipidea/otg_fsm.c ++++ b/drivers/usb/chipidea/otg_fsm.c +@@ -537,7 +537,6 @@ static int ci_otg_start_host(struct otg_ + { + struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); + +- mutex_unlock(&fsm->lock); + if (on) { + ci_role_stop(ci); + ci_role_start(ci, CI_ROLE_HOST); +@@ -546,7 +545,6 @@ static int ci_otg_start_host(struct otg_ + hw_device_reset(ci); + ci_role_start(ci, CI_ROLE_GADGET); + } +- mutex_lock(&fsm->lock); + return 0; + } + +@@ -554,12 +552,10 @@ static int ci_otg_start_gadget(struct ot + { + struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm); + +- mutex_unlock(&fsm->lock); + if (on) + usb_gadget_vbus_connect(&ci->gadget); + else + usb_gadget_vbus_disconnect(&ci->gadget); +- mutex_lock(&fsm->lock); + + return 0; + } diff --git a/kernel/kernel/files/patches/mageia/usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch b/kernel/kernel/files/patches/mageia/usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch new file mode 100644 index 00000000..fa6655de --- /dev/null +++ b/kernel/kernel/files/patches/mageia/usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch @@ -0,0 +1,46 @@ +--- linux/drivers/usb/storage/unusual_devs.h.orig 2012-12-06 18:26:48.639813048 +0200 ++++ linux/drivers/usb/storage/unusual_devs.h 2012-12-06 18:27:16.570440504 +0200 +@@ -2046,16 +2046,16 @@ UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0 + UNUSUAL_DEV( 0x0584, 0x0001, 0x0100, 0x0102, + "RATOCSystems", + "Compact Flash Adapter", +- US_SC_SCSI, US_PR_BULK, NULL, ++ USB_SC_SCSI, USB_PR_BULK, NULL, + US_FL_SINGLE_LUN | US_FL_MAX_SECTORS_MIN), + + /* + * Panasonic/OEMs compact USB CDROMs status + * KXL-840(CD-ROM11): usb_stor_Bulk_max_lun() is danger, need US_FL_SINGLE_LUN + * KXL-RW11(CDRRW02): usb_stor_Bulk_max_lun() is danger, need US_FL_SINGLE_LUN +- * KXL-RW20(CDRRW03): original IClass is 0xFF, use US_PR_CB and need init reset ++ * KXL-RW20(CDRRW03): original IClass is 0xFF, use USB_PR_CB and need init reset + * KXL-RW31(CDRRW05): work fine with current code +- * KXL-RW21(CDRRW06): original IClass is 0xFF, use US_PR_CB and need init reset ++ * KXL-RW21(CDRRW06): original IClass is 0xFF, use USB_PR_CB and need init reset + * KXL-RW32(CDRRW09): work fine with current code + * KXL-RW40(CDRRW10): work fine with current code + * Checked: Go Taniguchi +@@ -2063,19 +2063,19 @@ UNUSUAL_DEV( 0x0584, 0x0001, 0x0100, 0x0 + UNUSUAL_DEV( 0x04da, 0x0d01, 0x0000, 0xffff, + "Panasonic", + "CD-ROM11", +- US_SC_8020, US_PR_BULK, NULL, US_FL_SINGLE_LUN), ++ USB_SC_8020, USB_PR_BULK, NULL, US_FL_SINGLE_LUN), + UNUSUAL_DEV( 0x04da, 0x0d02, 0x0000, 0xffff, + "Panasonic", + "CDRRW02", +- US_SC_8020, US_PR_BULK, NULL, US_FL_SINGLE_LUN), ++ USB_SC_8020, USB_PR_BULK, NULL, US_FL_SINGLE_LUN), + UNUSUAL_DEV( 0x04da, 0x0d03, 0x0000, 0xffff, + "Panasonic", + "CDRRW03", +- US_SC_8020, US_PR_CB, NULL, US_FL_MAX_SECTORS_MIN), ++ USB_SC_8020, USB_PR_CB, NULL, US_FL_MAX_SECTORS_MIN), + UNUSUAL_DEV( 0x04da, 0x0d06, 0x0000, 0xffff, + "Panasonic", + "CDRRW06", +- US_SC_8020, US_PR_CB, NULL, US_FL_MAX_SECTORS_MIN), ++ USB_SC_8020, USB_PR_CB, NULL, US_FL_MAX_SECTORS_MIN), + + /* Control/Bulk transport for all SubClass values */ + USUAL_DEV(USB_SC_RBC, USB_PR_CB), diff --git a/kernel/kernel/files/patches/mageia/usb-storage-unusual_devs-add-id.patch b/kernel/kernel/files/patches/mageia/usb-storage-unusual_devs-add-id.patch new file mode 100644 index 00000000..b9fc0200 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/usb-storage-unusual_devs-add-id.patch @@ -0,0 +1,55 @@ +Subject: Change to usb storage of unusual_dev. + +This patch is japanease unique USB devices quirks. +There are many unique USB CD, which probides by Panasonic. +I try to use all models. all devices worked fine. + +Signed-off-by: Go Taniguchi + +--- + drivers/usb/storage/unusual_devs.h | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +--- linux/drivers/usb/storage/unusual_devs.h.orig 2014-06-03 21:48:03.211099341 +0300 ++++ linux/drivers/usb/storage/unusual_devs.h 2014-06-04 21:57:21.546299167 +0300 +@@ -2105,6 +2105,40 @@ UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0 + #include "unusual_uas.h" + #endif + ++UNUSUAL_DEV( 0x0584, 0x0001, 0x0100, 0x0102, ++ "RATOCSystems", ++ "Compact Flash Adapter", ++ US_SC_SCSI, US_PR_BULK, NULL, ++ US_FL_SINGLE_LUN | US_FL_MAX_SECTORS_MIN), ++ ++/* ++ * Panasonic/OEMs compact USB CDROMs status ++ * KXL-840(CD-ROM11): usb_stor_Bulk_max_lun() is danger, need US_FL_SINGLE_LUN ++ * KXL-RW11(CDRRW02): usb_stor_Bulk_max_lun() is danger, need US_FL_SINGLE_LUN ++ * KXL-RW20(CDRRW03): original IClass is 0xFF, use US_PR_CB and need init reset ++ * KXL-RW31(CDRRW05): work fine with current code ++ * KXL-RW21(CDRRW06): original IClass is 0xFF, use US_PR_CB and need init reset ++ * KXL-RW32(CDRRW09): work fine with current code ++ * KXL-RW40(CDRRW10): work fine with current code ++ * Checked: Go Taniguchi ++ */ ++UNUSUAL_DEV( 0x04da, 0x0d01, 0x0000, 0xffff, ++ "Panasonic", ++ "CD-ROM11", ++ US_SC_8020, US_PR_BULK, NULL, US_FL_SINGLE_LUN), ++UNUSUAL_DEV( 0x04da, 0x0d02, 0x0000, 0xffff, ++ "Panasonic", ++ "CDRRW02", ++ US_SC_8020, US_PR_BULK, NULL, US_FL_SINGLE_LUN), ++UNUSUAL_DEV( 0x04da, 0x0d03, 0x0000, 0xffff, ++ "Panasonic", ++ "CDRRW03", ++ US_SC_8020, US_PR_CB, NULL, US_FL_MAX_SECTORS_MIN), ++UNUSUAL_DEV( 0x04da, 0x0d06, 0x0000, 0xffff, ++ "Panasonic", ++ "CDRRW06", ++ US_SC_8020, US_PR_CB, NULL, US_FL_MAX_SECTORS_MIN), ++ + /* Control/Bulk transport for all SubClass values */ + USUAL_DEV(USB_SC_RBC, USB_PR_CB), + USUAL_DEV(USB_SC_8020, USB_PR_CB), diff --git a/kernel/kernel/files/patches/mageia/usb-xhci-Solve-full-event-ring-by-increasing-TRBS_PER_SEGMENT-to-256.patch b/kernel/kernel/files/patches/mageia/usb-xhci-Solve-full-event-ring-by-increasing-TRBS_PER_SEGMENT-to-256.patch new file mode 100644 index 00000000..2224e77b --- /dev/null +++ b/kernel/kernel/files/patches/mageia/usb-xhci-Solve-full-event-ring-by-increasing-TRBS_PER_SEGMENT-to-256.patch @@ -0,0 +1,49 @@ +From 18cc2f4cbbaf825a4fedcf2d60fd388d291e0a38 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 30 Apr 2015 17:16:03 +0300 +Subject: xhci: Solve full event ring by increasing TRBS_PER_SEGMENT to 256 + +Our event ring consists of only one segment, and we risk filling +the event ring in case we get isoc transfers with short intervals +such as webcams that fill a TD every microframe (125us) + +With 64 TRB segment size one usb camera could fill the event ring in 8ms. +A setup with several cameras and other devices can fill up the +event ring as it is shared between all devices. +This has occurred when uvcvideo queues 5 * 32TD URBs which then +get cancelled when the video mode changes. The cancelled URBs are returned +in the xhci interrupt context and blocks the interrupt handler from +handling the new events. + +A full event ring will block xhci from scheduling traffic and affect all +devices conneted to the xhci, will see errors such as Missed Service +Intervals for isoc devices, and and Split transaction errors for LS/FS +interrupt devices. + +Increasing the TRB_PER_SEGMENT will also increase the default endpoint ring +size, which is welcome as for most isoc transfer we had to dynamically +expand the endpoint ring anyway to be able to queue the 5 * 32TDs uvcvideo +queues. + +The default size used to be 64 TRBs per segment + +Cc: +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 8e421b8..ea75e8c 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1267,7 +1267,7 @@ union xhci_trb { + * since the command ring is 64-byte aligned. + * It must also be greater than 16. + */ +-#define TRBS_PER_SEGMENT 64 ++#define TRBS_PER_SEGMENT 256 + /* Allow two commands + a link TRB, along with any reserved command TRBs */ + #define MAX_RSVD_CMD_TRBS (TRBS_PER_SEGMENT - 3) + #define TRB_SEGMENT_SIZE (TRBS_PER_SEGMENT*16) +-- +cgit v0.10.2 + diff --git a/kernel/kernel/files/patches/mageia/usb-xhci-clean-up-work-to-remove-unused-parameters-for-functions-in-xhci-mem.c.patch b/kernel/kernel/files/patches/mageia/usb-xhci-clean-up-work-to-remove-unused-parameters-for-functions-in-xhci-mem.c.patch new file mode 100644 index 00000000..f58d0c68 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/usb-xhci-clean-up-work-to-remove-unused-parameters-for-functions-in-xhci-mem.c.patch @@ -0,0 +1,339 @@ +From 4daf9df51fbfb03b8c2bcb538cb467f7c7af1f11 Mon Sep 17 00:00:00 2001 +From: Lin Wang +Date: Fri, 9 Jan 2015 16:06:31 +0200 +Subject: xhci: clean up work to remove unused parameters for functions in + xhci-mem.c + +Some parameters are not used by functions in xhci-mem.c, just +remove it. + +Changes compared to v1: +- Rebase to the latest usb-next branch + +Signed-off-by: Lin Wang +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c +index bb89175..745717e 100644 +--- a/drivers/usb/host/xhci-dbg.c ++++ b/drivers/usb/host/xhci-dbg.c +@@ -552,7 +552,7 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci, + + if (ctx->type == XHCI_CTX_TYPE_INPUT) { + struct xhci_input_control_ctx *ctrl_ctx = +- xhci_get_input_control_ctx(xhci, ctx); ++ xhci_get_input_control_ctx(ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "Could not get input context, bad type.\n"); + return; +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index e72265c..f833640 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -535,7 +535,7 @@ static void xhci_free_container_ctx(struct xhci_hcd *xhci, + kfree(ctx); + } + +-struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, ++struct xhci_input_control_ctx *xhci_get_input_control_ctx( + struct xhci_container_ctx *ctx) + { + if (ctx->type != XHCI_CTX_TYPE_INPUT) +@@ -784,8 +784,7 @@ void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci, + * Reinstalls the "normal" endpoint ring (at its previous dequeue mark, + * not at the beginning of the ring). + */ +-void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, +- struct xhci_ep_ctx *ep_ctx, ++void xhci_setup_no_streams_ep_input_ctx(struct xhci_ep_ctx *ep_ctx, + struct xhci_virt_ep *ep) + { + dma_addr_t addr; +@@ -1341,8 +1340,7 @@ static u32 xhci_get_endpoint_mult(struct usb_device *udev, + return ep->ss_ep_comp.bmAttributes; + } + +-static u32 xhci_get_endpoint_type(struct usb_device *udev, +- struct usb_host_endpoint *ep) ++static u32 xhci_get_endpoint_type(struct usb_host_endpoint *ep) + { + int in; + u32 type; +@@ -1375,8 +1373,7 @@ static u32 xhci_get_endpoint_type(struct usb_device *udev, + * Basically, this is the maxpacket size, multiplied by the burst size + * and mult size. + */ +-static u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, +- struct usb_device *udev, ++static u32 xhci_get_max_esit_payload(struct usb_device *udev, + struct usb_host_endpoint *ep) + { + int max_burst; +@@ -1417,7 +1414,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, + ep_index = xhci_get_endpoint_index(&ep->desc); + ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); + +- endpoint_type = xhci_get_endpoint_type(udev, ep); ++ endpoint_type = xhci_get_endpoint_type(ep); + if (!endpoint_type) + return -EINVAL; + ep_ctx->ep_info2 = cpu_to_le32(endpoint_type); +@@ -1483,7 +1480,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, + } + ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) | + MAX_BURST(max_burst)); +- max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep); ++ max_esit_payload = xhci_get_max_esit_payload(udev, ep); + ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload)); + + /* +@@ -1772,7 +1769,7 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, + return command; + } + +-void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv) ++void xhci_urb_free_priv(struct urb_priv *urb_priv) + { + if (urb_priv) { + kfree(urb_priv->td[0]); +@@ -1925,7 +1922,7 @@ static int xhci_test_trb_in_td(struct xhci_hcd *xhci, + } + + /* TRB math checks for xhci_trb_in_td(), using the command and event rings. */ +-static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci, gfp_t mem_flags) ++static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci) + { + struct { + dma_addr_t input_dma; +@@ -2451,7 +2448,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) + flags); + if (!xhci->event_ring) + goto fail; +- if (xhci_check_trb_in_td_math(xhci, flags) < 0) ++ if (xhci_check_trb_in_td_math(xhci) < 0) + goto fail; + + xhci->erst.entries = dma_alloc_coherent(dev, +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index c84a959..067f18a 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -609,7 +609,7 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, + + spin_unlock(&xhci->lock); + usb_hcd_giveback_urb(hcd, urb, status); +- xhci_urb_free_priv(xhci, urb_priv); ++ xhci_urb_free_priv(urb_priv); + spin_lock(&xhci->lock); + } + } +@@ -1110,7 +1110,7 @@ static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id, + * is not waiting on the configure endpoint command. + */ + virt_dev = xhci->devs[slot_id]; +- ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "Could not get input context, bad type.\n"); + return; +@@ -2497,7 +2497,7 @@ cleanup: + urb = td->urb; + urb_priv = urb->hcpriv; + +- xhci_urb_free_priv(xhci, urb_priv); ++ xhci_urb_free_priv(urb_priv); + + usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); + if ((urb->actual_length != urb->transfer_buffer_length && +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 1e3f39c..e282765 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1275,7 +1275,7 @@ static int xhci_check_maxpacket(struct x + return -ENOMEM; + + command->in_ctx = xhci->devs[slot_id]->in_ctx; +- ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +@@ -1373,7 +1373,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd + ret = xhci_check_maxpacket(xhci, slot_id, + ep_index, urb); + if (ret < 0) { +- xhci_urb_free_priv(xhci, urb_priv); ++ xhci_urb_free_priv(urb_priv); + urb->hcpriv = NULL; + return ret; + } +@@ -1439,7 +1439,7 @@ dying: + urb->ep->desc.bEndpointAddress, urb); + ret = -ESHUTDOWN; + free_priv: +- xhci_urb_free_priv(xhci, urb_priv); ++ xhci_urb_free_priv(urb_priv); + urb->hcpriv = NULL; + spin_unlock_irqrestore(&xhci->lock, flags); + return ret; +@@ -1552,7 +1552,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd + usb_hcd_unlink_urb_from_ep(hcd, urb); + spin_unlock_irqrestore(&xhci->lock, flags); + usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN); +- xhci_urb_free_priv(xhci, urb_priv); ++ xhci_urb_free_priv(urb_priv); + return ret; + } + if ((xhci->xhc_state & XHCI_STATE_DYING) || +@@ -1659,7 +1659,7 @@ int xhci_drop_endpoint(struct usb_hcd *h + + in_ctx = xhci->devs[udev->slot_id]->in_ctx; + out_ctx = xhci->devs[udev->slot_id]->out_ctx; +- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +@@ -1745,7 +1745,7 @@ int xhci_add_endpoint(struct usb_hcd *hc + virt_dev = xhci->devs[udev->slot_id]; + in_ctx = virt_dev->in_ctx; + out_ctx = virt_dev->out_ctx; +- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +@@ -1815,7 +1815,7 @@ static void xhci_zero_in_ctx(struct xhci + struct xhci_slot_ctx *slot_ctx; + int i; + +- ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +@@ -2541,7 +2541,7 @@ static int xhci_reserve_bandwidth(struct + if (virt_dev->tt_info) + old_active_eps = virt_dev->tt_info->active_eps; + +- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +@@ -2638,7 +2638,7 @@ static int xhci_configure_endpoint(struc + spin_lock_irqsave(&xhci->lock, flags); + virt_dev = xhci->devs[udev->slot_id]; + +- ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); + if (!ctrl_ctx) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", +@@ -2757,7 +2757,7 @@ int xhci_check_bandwidth(struct usb_hcd + command->in_ctx = virt_dev->in_ctx; + + /* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */ +- ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +@@ -2882,7 +2882,7 @@ static void xhci_setup_input_ctx_for_qui + dma_addr_t addr; + + in_ctx = xhci->devs[slot_id]->in_ctx; +- ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +@@ -3172,7 +3172,7 @@ int xhci_alloc_streams(struct usb_hcd *h + xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); + return -ENOMEM; + } +- ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(config_cmd->in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +@@ -3327,7 +3327,7 @@ int xhci_free_streams(struct usb_hcd *hc + */ + ep_index = xhci_get_endpoint_index(&eps[0]->desc); + command = vdev->eps[ep_index].stream_info->free_streams_command; +- ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); + if (!ctrl_ctx) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", +@@ -3345,7 +3345,7 @@ int xhci_free_streams(struct usb_hcd *hc + + xhci_endpoint_copy(xhci, command->in_ctx, + vdev->out_ctx, ep_index); +- xhci_setup_no_streams_ep_input_ctx(xhci, ep_ctx, ++ xhci_setup_no_streams_ep_input_ctx(ep_ctx, + &vdev->eps[ep_index]); + } + xhci_setup_input_ctx_for_config_ep(xhci, command->in_ctx, +@@ -3819,7 +3819,7 @@ static int xhci_setup_device(struct usb_ + command->completion = &xhci->addr_dev; + + slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); +- ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +@@ -4002,7 +4002,7 @@ static int __maybe_unused xhci_change_ma + + /* Attempt to issue an Evaluate Context command to change the MEL. */ + command = xhci->lpm_command; +- ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); + if (!ctrl_ctx) { + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", +@@ -4740,7 +4740,7 @@ int xhci_update_hub_device(struct usb_hc + xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); + return -ENOMEM; + } +- ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx); ++ ctrl_ctx = xhci_get_input_control_ctx(config_cmd->in_ctx); + if (!ctrl_ctx) { + xhci_warn(xhci, "%s: Could not get input context, bad type.\n", + __func__); +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index eeea5c0..e23f31d 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1712,8 +1712,7 @@ void xhci_free_stream_info(struct xhci_hcd *xhci, + void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci, + struct xhci_ep_ctx *ep_ctx, + struct xhci_stream_info *stream_info); +-void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci, +- struct xhci_ep_ctx *ep_ctx, ++void xhci_setup_no_streams_ep_input_ctx(struct xhci_ep_ctx *ep_ctx, + struct xhci_virt_ep *ep); + void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci, + struct xhci_virt_device *virt_dev, bool drop_control_ep); +@@ -1727,7 +1726,7 @@ struct xhci_ring *xhci_stream_id_to_ring( + struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci, + bool allocate_in_ctx, bool allocate_completion, + gfp_t mem_flags); +-void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv); ++void xhci_urb_free_priv(struct urb_priv *urb_priv); + void xhci_free_command(struct xhci_hcd *xhci, + struct xhci_command *command); + +@@ -1863,7 +1862,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, + void xhci_ring_device(struct xhci_hcd *xhci, int slot_id); + + /* xHCI contexts */ +-struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); ++struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_container_ctx *ctx); + struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); + struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); + +-- +cgit v0.10.2 diff --git a/kernel/kernel/files/patches/mageia/usb-xhci-fix-isoc-endpoint-dequeue-from-advancing-too-far-on-transaction-error.patch b/kernel/kernel/files/patches/mageia/usb-xhci-fix-isoc-endpoint-dequeue-from-advancing-too-far-on-transaction-error.patch new file mode 100644 index 00000000..33804781 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/usb-xhci-fix-isoc-endpoint-dequeue-from-advancing-too-far-on-transaction-error.patch @@ -0,0 +1,43 @@ +From d104d0152a97fade389f47635b73a9ccc7295d0b Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 30 Apr 2015 17:16:02 +0300 +Subject: xhci: fix isoc endpoint dequeue from advancing too far on transaction + error + +Isoc TDs usually consist of one TRB, sometimes two. When all goes well we +receive only one success event for a TD, and move the dequeue pointer to +the next TD. + +This fails if the TD consists of two TRBs and we get a transfer error +on the first TRB, we will then see two events for that TD. + +Fix this by making sure the event we get is for the last TRB in that TD +before moving the dequeue pointer to the next TD. This will resolve some +of the uvc and dvb issues with the +"ERROR Transfer event TRB DMA ptr not part of current TD" error message + +Cc: +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index f5397a5..ae0894c 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -2026,8 +2026,13 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, + break; + case COMP_DEV_ERR: + case COMP_STALL: ++ frame->status = -EPROTO; ++ skip_td = true; ++ break; + case COMP_TX_ERR: + frame->status = -EPROTO; ++ if (event_trb != td->last_trb) ++ return 0; + skip_td = true; + break; + case COMP_STOP: +-- +cgit v0.10.2 + diff --git a/kernel/kernel/files/patches/mageia/usb-xhci-gracefully-handle-xhci_irq-dead-device.patch b/kernel/kernel/files/patches/mageia/usb-xhci-gracefully-handle-xhci_irq-dead-device.patch new file mode 100644 index 00000000..9685e1f9 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/usb-xhci-gracefully-handle-xhci_irq-dead-device.patch @@ -0,0 +1,30 @@ +From 948fa13504f80b9765d2b753691ab94c83a10341 Mon Sep 17 00:00:00 2001 +From: Joe Lawrence +Date: Thu, 30 Apr 2015 17:16:04 +0300 +Subject: xhci: gracefully handle xhci_irq dead device + +If the xHCI host controller has died (ie, device removed) or suffered +other serious fatal error (STS_FATAL), then xhci_irq should handle this +condition with IRQ_HANDLED instead of -ESHUTDOWN. + +Signed-off-by: Joe Lawrence +Cc: +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index ae0894c..7d34cbf 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -2645,7 +2645,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) + xhci_halt(xhci); + hw_died: + spin_unlock(&xhci->lock); +- return -ESHUTDOWN; ++ return IRQ_HANDLED; + } + + /* +-- +cgit v0.10.2 + diff --git a/kernel/kernel/files/patches/mageia/usb-xhci-remove-unused-parameter-xhci-in-function-xhci-handshake.patch b/kernel/kernel/files/patches/mageia/usb-xhci-remove-unused-parameter-xhci-in-function-xhci-handshake.patch new file mode 100644 index 00000000..f55e6489 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/usb-xhci-remove-unused-parameter-xhci-in-function-xhci-handshake.patch @@ -0,0 +1,128 @@ +From dc0b177cf8be1e7371cfb92cfbccac595bf8dac8 Mon Sep 17 00:00:00 2001 +From: Lin Wang +Date: Fri, 9 Jan 2015 16:06:28 +0200 +Subject: xhci: remove unused parameter 'xhci' in function xhci_handshake(). + +Parameter 'xhci' is no longer be used in function xhci_handshake(), +just remove it. + +Signed-off-by: Lin Wang +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman + +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index e692e76..c84a959 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -299,7 +299,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) + * seconds), then it should assume that the there are + * larger problems with the xHC and assert HCRST. + */ +- ret = xhci_handshake(xhci, &xhci->op_regs->cmd_ring, ++ ret = xhci_handshake(&xhci->op_regs->cmd_ring, + CMD_RING_RUNNING, 0, 5 * 1000 * 1000); + if (ret < 0) { + xhci_err(xhci, "Stopped the command ring failed, " +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 93200db..5ec74e2 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -60,8 +60,7 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); + * handshake done). There are two failure modes: "usec" have passed (major + * hardware flakeout), or the register reads as all-ones (hardware removed). + */ +-int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, +- u32 mask, u32 done, int usec) ++int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec) + { + u32 result; + +@@ -111,7 +110,7 @@ int xhci_halt(struct xhci_hcd *xhci) + xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Halt the HC"); + xhci_quiesce(xhci); + +- ret = xhci_handshake(xhci, &xhci->op_regs->status, ++ ret = xhci_handshake(&xhci->op_regs->status, + STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); + if (!ret) { + xhci->xhc_state |= XHCI_STATE_HALTED; +@@ -140,7 +139,7 @@ static int xhci_start(struct xhci_hcd *xhci) + * Wait for the HCHalted Status bit to be 0 to indicate the host is + * running. + */ +- ret = xhci_handshake(xhci, &xhci->op_regs->status, ++ ret = xhci_handshake(&xhci->op_regs->status, + STS_HALT, 0, XHCI_MAX_HALT_USEC); + if (ret == -ETIMEDOUT) + xhci_err(xhci, "Host took too long to start, " +@@ -175,7 +174,7 @@ int xhci_reset(struct xhci_hcd *xhci) + command |= CMD_RESET; + writel(command, &xhci->op_regs->command); + +- ret = xhci_handshake(xhci, &xhci->op_regs->command, ++ ret = xhci_handshake(&xhci->op_regs->command, + CMD_RESET, 0, 10 * 1000 * 1000); + if (ret) + return ret; +@@ -186,7 +185,7 @@ int xhci_reset(struct xhci_hcd *xhci) + * xHCI cannot write to any doorbells or operational registers other + * than status until the "Controller Not Ready" flag is cleared. + */ +- ret = xhci_handshake(xhci, &xhci->op_regs->status, ++ ret = xhci_handshake(&xhci->op_regs->status, + STS_CNR, 0, 10 * 1000 * 1000); + + for (i = 0; i < 2; ++i) { +@@ -929,7 +928,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) + /* Some chips from Fresco Logic need an extraordinary delay */ + delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1; + +- if (xhci_handshake(xhci, &xhci->op_regs->status, ++ if (xhci_handshake(&xhci->op_regs->status, + STS_HALT, STS_HALT, delay)) { + xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n"); + spin_unlock_irq(&xhci->lock); +@@ -944,7 +943,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) + command = readl(&xhci->op_regs->command); + command |= CMD_CSS; + writel(command, &xhci->op_regs->command); +- if (xhci_handshake(xhci, &xhci->op_regs->status, ++ if (xhci_handshake(&xhci->op_regs->status, + STS_SAVE, 0, 10 * 1000)) { + xhci_warn(xhci, "WARN: xHC save state timeout\n"); + spin_unlock_irq(&xhci->lock); +@@ -1011,7 +1010,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + command = readl(&xhci->op_regs->command); + command |= CMD_CRS; + writel(command, &xhci->op_regs->command); +- if (xhci_handshake(xhci, &xhci->op_regs->status, ++ if (xhci_handshake(&xhci->op_regs->status, + STS_RESTORE, 0, 10 * 1000)) { + xhci_warn(xhci, "WARN: xHC restore state timeout\n"); + spin_unlock_irq(&xhci->lock); +@@ -1082,7 +1081,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + command = readl(&xhci->op_regs->command); + command |= CMD_RUN; + writel(command, &xhci->op_regs->command); +- xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT, ++ xhci_handshake(&xhci->op_regs->status, STS_HALT, + 0, 250 * 1000); + + /* step 5: walk topology and initialize portsc, +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index cc7c5bb..eeea5c0 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1733,8 +1733,7 @@ void xhci_free_command(struct xhci_hcd *xhci, + + /* xHCI host controller glue */ + typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); +-int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr, +- u32 mask, u32 done, int usec); ++int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); + void xhci_quiesce(struct xhci_hcd *xhci); + int xhci_halt(struct xhci_hcd *xhci); + int xhci_reset(struct xhci_hcd *xhci); +-- +cgit v0.10.2 + diff --git a/kernel/kernel/files/patches/mageia/video-fbdev-Add-additional-vesa-modes.patch b/kernel/kernel/files/patches/mageia/video-fbdev-Add-additional-vesa-modes.patch new file mode 100644 index 00000000..3dce1000 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/video-fbdev-Add-additional-vesa-modes.patch @@ -0,0 +1,68 @@ +From 37715f556a0776356300391f8ac41ace91bea447 Mon Sep 17 00:00:00 2001 +From: David Ung +Date: Tue, 13 Jan 2015 19:04:00 -0800 +Subject: [PATCH 1/4] video: fbdev: Add additional vesa modes + +Add high resolution modes to vesa_modes struct. + +Signed-off-by: David Ung +Signed-off-by: Tomi Valkeinen +--- + drivers/video/fbdev/core/modedb.c | 27 +++++++++++++++++++++++++++ + include/linux/fb.h | 2 +- + 2 files changed, 28 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c +index 388f797..0b57c1df 100644 +--- a/drivers/video/fbdev/core/modedb.c ++++ b/drivers/video/fbdev/core/modedb.c +@@ -468,6 +468,33 @@ const struct fb_videomode vesa_modes[] = { + /* 33 1920x1440-75 VESA */ + { NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3, + FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, ++ /* 34 1920x1200-60 RB VESA */ ++ { NULL, 60, 1920, 1200, 6493, 80, 48, 26, 3, 32, 6, ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, ++ /* 35 1920x1200-60 VESA */ ++ { NULL, 60, 1920, 1200, 5174, 336, 136, 36, 3, 200, 6, ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, ++ /* 36 1920x1200-75 VESA */ ++ { NULL, 75, 1920, 1200, 4077, 344, 136, 46, 3, 208, 6, ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, ++ /* 37 1920x1200-85 VESA */ ++ { NULL, 85, 1920, 1200, 3555, 352, 144, 53, 3, 208, 6, ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, ++ /* 38 2560x1600-60 RB VESA */ ++ { NULL, 60, 2560, 1600, 3724, 80, 48, 37, 3, 32, 6, ++ FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, ++ /* 39 2560x1600-60 VESA */ ++ { NULL, 60, 2560, 1600, 2869, 472, 192, 49, 3, 280, 6, ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, ++ /* 40 2560x1600-75 VESA */ ++ { NULL, 75, 2560, 1600, 2256, 488, 208, 63, 3, 280, 6, ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, ++ /* 41 2560x1600-85 VESA */ ++ { NULL, 85, 2560, 1600, 1979, 488, 208, 73, 3, 280, 6, ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, ++ /* 42 2560x1600-120 RB VESA */ ++ { NULL, 120, 2560, 1600, 1809, 80, 48, 85, 3, 32, 6, ++ FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + }; + EXPORT_SYMBOL(vesa_modes); + #endif /* CONFIG_FB_MODE_HELPERS */ +diff --git a/include/linux/fb.h b/include/linux/fb.h +index 09bb7a1..882dbd1 100644 +--- a/include/linux/fb.h ++++ b/include/linux/fb.h +@@ -726,7 +726,7 @@ extern int fb_videomode_from_videomode(const struct videomode *vm, + struct fb_videomode *fbmode); + + /* drivers/video/modedb.c */ +-#define VESA_MODEDB_SIZE 34 ++#define VESA_MODEDB_SIZE 43 + extern void fb_var_to_videomode(struct fb_videomode *mode, + const struct fb_var_screeninfo *var); + extern void fb_videomode_to_var(struct fb_var_screeninfo *var, +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/video-fbdev-Check-Standard-Timing-against-DMT.patch b/kernel/kernel/files/patches/mageia/video-fbdev-Check-Standard-Timing-against-DMT.patch new file mode 100644 index 00000000..1bcbd0e0 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/video-fbdev-Check-Standard-Timing-against-DMT.patch @@ -0,0 +1,239 @@ +From 8f5ee77bb8d162abe28ff8cd56f36e825d143207 Mon Sep 17 00:00:00 2001 +From: David Ung +Date: Tue, 13 Jan 2015 19:04:01 -0800 +Subject: [PATCH 2/4] video: fbdev: Check Standard Timing against DMT + +Add the VESA Display Monitor Timing (DMT) table. +During parsing of Standard Timings, it compare the 2 byte STD code +with DMT to see what the VESA mode should be. If there is no entry +in the vesa_modes table or no match found, it fallsback to the +GTF timings. + +Signed-off-by: David Ung +Signed-off-by: Tomi Valkeinen +--- + drivers/video/fbdev/core/fbmon.c | 76 +++++++++++++++++++---------------- + drivers/video/fbdev/core/modedb.c | 84 +++++++++++++++++++++++++++++++++++++++ + include/linux/fb.h | 10 +++++ + 3 files changed, 136 insertions(+), 34 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c +index 5b0e313..0f234c1 100644 +--- a/drivers/video/fbdev/core/fbmon.c ++++ b/drivers/video/fbdev/core/fbmon.c +@@ -498,44 +498,52 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode) + static int get_std_timing(unsigned char *block, struct fb_videomode *mode, + int ver, int rev) + { +- int xres, yres = 0, refresh, ratio, i; +- +- xres = (block[0] + 31) * 8; +- if (xres <= 256) +- return 0; ++ int i; + +- ratio = (block[1] & 0xc0) >> 6; +- switch (ratio) { +- case 0: +- /* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */ +- if (ver < 1 || (ver == 1 && rev < 3)) +- yres = xres; +- else +- yres = (xres * 10)/16; +- break; +- case 1: +- yres = (xres * 3)/4; +- break; +- case 2: +- yres = (xres * 4)/5; +- break; +- case 3: +- yres = (xres * 9)/16; +- break; ++ for (i = 0; i < DMT_SIZE; i++) { ++ u32 std_2byte_code = block[0] << 8 | block[1]; ++ if (std_2byte_code == dmt_modes[i].std_2byte_code) ++ break; + } +- refresh = (block[1] & 0x3f) + 60; +- +- DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh); +- for (i = 0; i < VESA_MODEDB_SIZE; i++) { +- if (vesa_modes[i].xres == xres && +- vesa_modes[i].yres == yres && +- vesa_modes[i].refresh == refresh) { +- *mode = vesa_modes[i]; +- mode->flag |= FB_MODE_IS_STANDARD; +- return 1; ++ ++ if (i < DMT_SIZE && dmt_modes[i].mode) { ++ /* DMT mode found */ ++ *mode = *dmt_modes[i].mode; ++ mode->flag |= FB_MODE_IS_STANDARD; ++ DPRINTK(" DMT id=%d\n", dmt_modes[i].dmt_id); ++ ++ } else { ++ int xres, yres = 0, refresh, ratio; ++ ++ xres = (block[0] + 31) * 8; ++ if (xres <= 256) ++ return 0; ++ ++ ratio = (block[1] & 0xc0) >> 6; ++ switch (ratio) { ++ case 0: ++ /* in EDID 1.3 the meaning of 0 changed to 16:10 (prior 1:1) */ ++ if (ver < 1 || (ver == 1 && rev < 3)) ++ yres = xres; ++ else ++ yres = (xres * 10)/16; ++ break; ++ case 1: ++ yres = (xres * 3)/4; ++ break; ++ case 2: ++ yres = (xres * 4)/5; ++ break; ++ case 3: ++ yres = (xres * 9)/16; ++ break; + } ++ refresh = (block[1] & 0x3f) + 60; ++ DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh); ++ ++ calc_mode_timings(xres, yres, refresh, mode); + } +- calc_mode_timings(xres, yres, refresh, mode); ++ + return 1; + } + +diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c +index 0b57c1df..858a97e 100644 +--- a/drivers/video/fbdev/core/modedb.c ++++ b/drivers/video/fbdev/core/modedb.c +@@ -497,6 +497,90 @@ const struct fb_videomode vesa_modes[] = { + FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, + }; + EXPORT_SYMBOL(vesa_modes); ++ ++const struct dmt_videomode dmt_modes[DMT_SIZE] = { ++ { 0x01, 0x0000, 0x000000, &vesa_modes[0] }, ++ { 0x02, 0x3119, 0x000000, &vesa_modes[1] }, ++ { 0x03, 0x0000, 0x000000, &vesa_modes[2] }, ++ { 0x04, 0x3140, 0x000000, &vesa_modes[3] }, ++ { 0x05, 0x314c, 0x000000, &vesa_modes[4] }, ++ { 0x06, 0x314f, 0x000000, &vesa_modes[5] }, ++ { 0x07, 0x3159, 0x000000, &vesa_modes[6] }, ++ { 0x08, 0x0000, 0x000000, &vesa_modes[7] }, ++ { 0x09, 0x4540, 0x000000, &vesa_modes[8] }, ++ { 0x0a, 0x454c, 0x000000, &vesa_modes[9] }, ++ { 0x0b, 0x454f, 0x000000, &vesa_modes[10] }, ++ { 0x0c, 0x4559, 0x000000, &vesa_modes[11] }, ++ { 0x0d, 0x0000, 0x000000, 0 }, ++ { 0x0e, 0x0000, 0x000000, 0 }, ++ { 0x0f, 0x0000, 0x000000, &vesa_modes[12] }, ++ { 0x10, 0x6140, 0x000000, &vesa_modes[13] }, ++ { 0x11, 0x614a, 0x000000, &vesa_modes[14] }, ++ { 0x12, 0x614f, 0x000000, &vesa_modes[15] }, ++ { 0x13, 0x6159, 0x000000, &vesa_modes[16] }, ++ { 0x14, 0x0000, 0x000000, 0 }, ++ { 0x15, 0x714f, 0x000000, &vesa_modes[17] }, ++ { 0x16, 0x0000, 0x7f1c21, 0 }, ++ { 0x17, 0x0000, 0x7f1c28, 0 }, ++ { 0x18, 0x0000, 0x7f1c44, 0 }, ++ { 0x19, 0x0000, 0x7f1c62, 0 }, ++ { 0x1a, 0x0000, 0x000000, 0 }, ++ { 0x1b, 0x0000, 0x8f1821, 0 }, ++ { 0x1c, 0x8100, 0x8f1828, 0 }, ++ { 0x1d, 0x810f, 0x8f1844, 0 }, ++ { 0x1e, 0x8119, 0x8f1862, 0 }, ++ { 0x1f, 0x0000, 0x000000, 0 }, ++ { 0x20, 0x8140, 0x000000, &vesa_modes[18] }, ++ { 0x21, 0x8159, 0x000000, &vesa_modes[19] }, ++ { 0x22, 0x0000, 0x000000, 0 }, ++ { 0x23, 0x8180, 0x000000, &vesa_modes[20] }, ++ { 0x24, 0x818f, 0x000000, &vesa_modes[21] }, ++ { 0x25, 0x8199, 0x000000, &vesa_modes[22] }, ++ { 0x26, 0x0000, 0x000000, 0 }, ++ { 0x27, 0x0000, 0x000000, 0 }, ++ { 0x28, 0x0000, 0x000000, 0 }, ++ { 0x29, 0x0000, 0x0c2021, 0 }, ++ { 0x2a, 0x9040, 0x0c2028, 0 }, ++ { 0x2b, 0x904f, 0x0c2044, 0 }, ++ { 0x2c, 0x9059, 0x0c2062, 0 }, ++ { 0x2d, 0x0000, 0x000000, 0 }, ++ { 0x2e, 0x9500, 0xc11821, 0 }, ++ { 0x2f, 0x9500, 0xc11828, 0 }, ++ { 0x30, 0x950f, 0xc11844, 0 }, ++ { 0x31, 0x9519, 0xc11868, 0 }, ++ { 0x32, 0x0000, 0x000000, 0 }, ++ { 0x33, 0xa940, 0x000000, &vesa_modes[23] }, ++ { 0x34, 0xa945, 0x000000, &vesa_modes[24] }, ++ { 0x35, 0xa94a, 0x000000, &vesa_modes[25] }, ++ { 0x36, 0xa94f, 0x000000, &vesa_modes[26] }, ++ { 0x37, 0xa959, 0x000000, &vesa_modes[27] }, ++ { 0x38, 0x0000, 0x000000, 0 }, ++ { 0x39, 0x0000, 0x0c2821, 0 }, ++ { 0x3a, 0xb300, 0x0c2828, 0 }, ++ { 0x3b, 0xb30f, 0x0c2844, 0 }, ++ { 0x3c, 0xb319, 0x0c2868, 0 }, ++ { 0x3d, 0x0000, 0x000000, 0 }, ++ { 0x3e, 0xc140, 0x000000, &vesa_modes[28] }, ++ { 0x3f, 0xc14f, 0x000000, &vesa_modes[29] }, ++ { 0x40, 0x0000, 0x000000, 0 }, ++ { 0x41, 0xc940, 0x000000, &vesa_modes[30] }, ++ { 0x42, 0xc94f, 0x000000, &vesa_modes[31] }, ++ { 0x43, 0x0000, 0x000000, 0 }, ++ { 0x44, 0x0000, 0x572821, &vesa_modes[34] }, ++ { 0x45, 0xd100, 0x572828, &vesa_modes[35] }, ++ { 0x46, 0xd10f, 0x572844, &vesa_modes[36] }, ++ { 0x47, 0xd119, 0x572862, &vesa_modes[37] }, ++ { 0x48, 0x0000, 0x000000, 0 }, ++ { 0x49, 0xd140, 0x000000, &vesa_modes[32] }, ++ { 0x4a, 0xd14f, 0x000000, &vesa_modes[33] }, ++ { 0x4b, 0x0000, 0x000000, 0 }, ++ { 0x4c, 0x0000, 0x1f3821, &vesa_modes[38] }, ++ { 0x4d, 0x0000, 0x1f3828, &vesa_modes[39] }, ++ { 0x4e, 0x0000, 0x1f3844, &vesa_modes[40] }, ++ { 0x4f, 0x0000, 0x1f3862, &vesa_modes[41] }, ++ { 0x50, 0x0000, 0x000000, &vesa_modes[42] }, ++}; ++EXPORT_SYMBOL(dmt_modes); + #endif /* CONFIG_FB_MODE_HELPERS */ + + /** +diff --git a/include/linux/fb.h b/include/linux/fb.h +index 882dbd1..043f328 100644 +--- a/include/linux/fb.h ++++ b/include/linux/fb.h +@@ -727,6 +727,8 @@ extern int fb_videomode_from_videomode(const struct videomode *vm, + + /* drivers/video/modedb.c */ + #define VESA_MODEDB_SIZE 43 ++#define DMT_SIZE 0x50 ++ + extern void fb_var_to_videomode(struct fb_videomode *mode, + const struct fb_var_screeninfo *var); + extern void fb_videomode_to_var(struct fb_var_screeninfo *var, +@@ -777,9 +779,17 @@ struct fb_videomode { + u32 flag; + }; + ++struct dmt_videomode { ++ u32 dmt_id; ++ u32 std_2byte_code; ++ u32 cvt_3byte_code; ++ const struct fb_videomode *mode; ++}; ++ + extern const char *fb_mode_option; + extern const struct fb_videomode vesa_modes[]; + extern const struct fb_videomode cea_modes[64]; ++extern const struct dmt_videomode dmt_modes[]; + + struct fb_modelist { + struct list_head list; +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/video-fbdev-Fix-sparse-warning-messages.patch b/kernel/kernel/files/patches/mageia/video-fbdev-Fix-sparse-warning-messages.patch new file mode 100644 index 00000000..dbf9f834 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/video-fbdev-Fix-sparse-warning-messages.patch @@ -0,0 +1,128 @@ +From ba59bab7530cf98b40b7c4e1c8f86dc3d7f2b47f Mon Sep 17 00:00:00 2001 +From: David Ung +Date: Fri, 16 Jan 2015 16:39:35 -0800 +Subject: [PATCH 4/4] video: fbdev: Fix sparse warning messages + +Use NULL instead of 0 for the last entry of dmt_modes struct. +Supresses "sparse: Using plain integer as NULL pointer" warning. + +Signed-off-by: David Ung +Signed-off-by: Tomi Valkeinen +--- + drivers/video/fbdev/core/modedb.c | 74 +++++++++++++++++++-------------------- + 1 file changed, 37 insertions(+), 37 deletions(-) + +diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c +index 858a97e..7d07cf8 100644 +--- a/drivers/video/fbdev/core/modedb.c ++++ b/drivers/video/fbdev/core/modedb.c +@@ -511,69 +511,69 @@ const struct dmt_videomode dmt_modes[DMT_SIZE] = { + { 0x0a, 0x454c, 0x000000, &vesa_modes[9] }, + { 0x0b, 0x454f, 0x000000, &vesa_modes[10] }, + { 0x0c, 0x4559, 0x000000, &vesa_modes[11] }, +- { 0x0d, 0x0000, 0x000000, 0 }, +- { 0x0e, 0x0000, 0x000000, 0 }, ++ { 0x0d, 0x0000, 0x000000, NULL }, ++ { 0x0e, 0x0000, 0x000000, NULL }, + { 0x0f, 0x0000, 0x000000, &vesa_modes[12] }, + { 0x10, 0x6140, 0x000000, &vesa_modes[13] }, + { 0x11, 0x614a, 0x000000, &vesa_modes[14] }, + { 0x12, 0x614f, 0x000000, &vesa_modes[15] }, + { 0x13, 0x6159, 0x000000, &vesa_modes[16] }, +- { 0x14, 0x0000, 0x000000, 0 }, ++ { 0x14, 0x0000, 0x000000, NULL }, + { 0x15, 0x714f, 0x000000, &vesa_modes[17] }, +- { 0x16, 0x0000, 0x7f1c21, 0 }, +- { 0x17, 0x0000, 0x7f1c28, 0 }, +- { 0x18, 0x0000, 0x7f1c44, 0 }, +- { 0x19, 0x0000, 0x7f1c62, 0 }, +- { 0x1a, 0x0000, 0x000000, 0 }, +- { 0x1b, 0x0000, 0x8f1821, 0 }, +- { 0x1c, 0x8100, 0x8f1828, 0 }, +- { 0x1d, 0x810f, 0x8f1844, 0 }, +- { 0x1e, 0x8119, 0x8f1862, 0 }, +- { 0x1f, 0x0000, 0x000000, 0 }, ++ { 0x16, 0x0000, 0x7f1c21, NULL }, ++ { 0x17, 0x0000, 0x7f1c28, NULL }, ++ { 0x18, 0x0000, 0x7f1c44, NULL }, ++ { 0x19, 0x0000, 0x7f1c62, NULL }, ++ { 0x1a, 0x0000, 0x000000, NULL }, ++ { 0x1b, 0x0000, 0x8f1821, NULL }, ++ { 0x1c, 0x8100, 0x8f1828, NULL }, ++ { 0x1d, 0x810f, 0x8f1844, NULL }, ++ { 0x1e, 0x8119, 0x8f1862, NULL }, ++ { 0x1f, 0x0000, 0x000000, NULL }, + { 0x20, 0x8140, 0x000000, &vesa_modes[18] }, + { 0x21, 0x8159, 0x000000, &vesa_modes[19] }, +- { 0x22, 0x0000, 0x000000, 0 }, ++ { 0x22, 0x0000, 0x000000, NULL }, + { 0x23, 0x8180, 0x000000, &vesa_modes[20] }, + { 0x24, 0x818f, 0x000000, &vesa_modes[21] }, + { 0x25, 0x8199, 0x000000, &vesa_modes[22] }, +- { 0x26, 0x0000, 0x000000, 0 }, +- { 0x27, 0x0000, 0x000000, 0 }, +- { 0x28, 0x0000, 0x000000, 0 }, +- { 0x29, 0x0000, 0x0c2021, 0 }, +- { 0x2a, 0x9040, 0x0c2028, 0 }, +- { 0x2b, 0x904f, 0x0c2044, 0 }, +- { 0x2c, 0x9059, 0x0c2062, 0 }, +- { 0x2d, 0x0000, 0x000000, 0 }, +- { 0x2e, 0x9500, 0xc11821, 0 }, +- { 0x2f, 0x9500, 0xc11828, 0 }, +- { 0x30, 0x950f, 0xc11844, 0 }, +- { 0x31, 0x9519, 0xc11868, 0 }, +- { 0x32, 0x0000, 0x000000, 0 }, ++ { 0x26, 0x0000, 0x000000, NULL }, ++ { 0x27, 0x0000, 0x000000, NULL }, ++ { 0x28, 0x0000, 0x000000, NULL }, ++ { 0x29, 0x0000, 0x0c2021, NULL }, ++ { 0x2a, 0x9040, 0x0c2028, NULL }, ++ { 0x2b, 0x904f, 0x0c2044, NULL }, ++ { 0x2c, 0x9059, 0x0c2062, NULL }, ++ { 0x2d, 0x0000, 0x000000, NULL }, ++ { 0x2e, 0x9500, 0xc11821, NULL }, ++ { 0x2f, 0x9500, 0xc11828, NULL }, ++ { 0x30, 0x950f, 0xc11844, NULL }, ++ { 0x31, 0x9519, 0xc11868, NULL }, ++ { 0x32, 0x0000, 0x000000, NULL }, + { 0x33, 0xa940, 0x000000, &vesa_modes[23] }, + { 0x34, 0xa945, 0x000000, &vesa_modes[24] }, + { 0x35, 0xa94a, 0x000000, &vesa_modes[25] }, + { 0x36, 0xa94f, 0x000000, &vesa_modes[26] }, + { 0x37, 0xa959, 0x000000, &vesa_modes[27] }, +- { 0x38, 0x0000, 0x000000, 0 }, +- { 0x39, 0x0000, 0x0c2821, 0 }, +- { 0x3a, 0xb300, 0x0c2828, 0 }, +- { 0x3b, 0xb30f, 0x0c2844, 0 }, +- { 0x3c, 0xb319, 0x0c2868, 0 }, +- { 0x3d, 0x0000, 0x000000, 0 }, ++ { 0x38, 0x0000, 0x000000, NULL }, ++ { 0x39, 0x0000, 0x0c2821, NULL }, ++ { 0x3a, 0xb300, 0x0c2828, NULL }, ++ { 0x3b, 0xb30f, 0x0c2844, NULL }, ++ { 0x3c, 0xb319, 0x0c2868, NULL }, ++ { 0x3d, 0x0000, 0x000000, NULL }, + { 0x3e, 0xc140, 0x000000, &vesa_modes[28] }, + { 0x3f, 0xc14f, 0x000000, &vesa_modes[29] }, +- { 0x40, 0x0000, 0x000000, 0 }, ++ { 0x40, 0x0000, 0x000000, NULL}, + { 0x41, 0xc940, 0x000000, &vesa_modes[30] }, + { 0x42, 0xc94f, 0x000000, &vesa_modes[31] }, +- { 0x43, 0x0000, 0x000000, 0 }, ++ { 0x43, 0x0000, 0x000000, NULL }, + { 0x44, 0x0000, 0x572821, &vesa_modes[34] }, + { 0x45, 0xd100, 0x572828, &vesa_modes[35] }, + { 0x46, 0xd10f, 0x572844, &vesa_modes[36] }, + { 0x47, 0xd119, 0x572862, &vesa_modes[37] }, +- { 0x48, 0x0000, 0x000000, 0 }, ++ { 0x48, 0x0000, 0x000000, NULL }, + { 0x49, 0xd140, 0x000000, &vesa_modes[32] }, + { 0x4a, 0xd14f, 0x000000, &vesa_modes[33] }, +- { 0x4b, 0x0000, 0x000000, 0 }, ++ { 0x4b, 0x0000, 0x000000, NULL }, + { 0x4c, 0x0000, 0x1f3821, &vesa_modes[38] }, + { 0x4d, 0x0000, 0x1f3828, &vesa_modes[39] }, + { 0x4e, 0x0000, 0x1f3844, &vesa_modes[40] }, +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/video-fbdev-Validate-mode-timing-against-monspec.patch b/kernel/kernel/files/patches/mageia/video-fbdev-Validate-mode-timing-against-monspec.patch new file mode 100644 index 00000000..afdf4ae1 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/video-fbdev-Validate-mode-timing-against-monspec.patch @@ -0,0 +1,107 @@ +From 72bbf10bf0fdaa097252149ef3a9b74c48a0d683 Mon Sep 17 00:00:00 2001 +From: David Ung +Date: Tue, 13 Jan 2015 19:04:02 -0800 +Subject: [PATCH 3/4] video: fbdev: Validate mode timing against monspec + +fbmon may generate mode timings that are out of spec of the monitor. +eg DELL U2410 has a max clock 170mhz but advertises a resolutions of +1920x1200@60 in its Standard Timings using 2byte code of D1 00. +When this is looked up in the DMT table it gives it a 193mhz clock. +Although the DELL monitor supports 1920x1200@60, it can only run with +reduced timings at 154mhz or DMT id 0x44 which has no STD 2byte code. +This patch checks to see if the mode can be supported by the monitor +by comparing against monspecs.dclkmax. + +Signed-off-by: David Ung +Signed-off-by: Tomi Valkeinen +--- + drivers/video/fbdev/core/fbmon.c | 27 ++++++++++++++++++--------- + 1 file changed, 18 insertions(+), 9 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c +index 0f234c1..9533859 100644 +--- a/drivers/video/fbdev/core/fbmon.c ++++ b/drivers/video/fbdev/core/fbmon.c +@@ -496,7 +496,7 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode) + } + + static int get_std_timing(unsigned char *block, struct fb_videomode *mode, +- int ver, int rev) ++ int ver, int rev, const struct fb_monspecs *specs) + { + int i; + +@@ -544,16 +544,23 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode, + calc_mode_timings(xres, yres, refresh, mode); + } + ++ /* Check the mode we got is within valid spec of the monitor */ ++ if (specs && specs->dclkmax ++ && PICOS2KHZ(mode->pixclock) * 1000 > specs->dclkmax) { ++ DPRINTK(" mode exceed max DCLK\n"); ++ return 0; ++ } ++ + return 1; + } + +-static int get_dst_timing(unsigned char *block, +- struct fb_videomode *mode, int ver, int rev) ++static int get_dst_timing(unsigned char *block, struct fb_videomode *mode, ++ int ver, int rev, const struct fb_monspecs *specs) + { + int j, num = 0; + + for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE) +- num += get_std_timing(block, &mode[num], ver, rev); ++ num += get_std_timing(block, &mode[num], ver, rev, specs); + + return num; + } +@@ -609,7 +616,8 @@ static void get_detailed_timing(unsigned char *block, + * This function builds a mode database using the contents of the EDID + * data + */ +-static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) ++static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, ++ const struct fb_monspecs *specs) + { + struct fb_videomode *mode, *m; + unsigned char *block; +@@ -651,12 +659,13 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) + DPRINTK(" Standard Timings\n"); + block = edid + STD_TIMING_DESCRIPTIONS_START; + for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) +- num += get_std_timing(block, &mode[num], ver, rev); ++ num += get_std_timing(block, &mode[num], ver, rev, specs); + + block = edid + DETAILED_TIMING_DESCRIPTIONS_START; + for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { + if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) +- num += get_dst_timing(block + 5, &mode[num], ver, rev); ++ num += get_dst_timing(block + 5, &mode[num], ++ ver, rev, specs); + } + + /* Yikes, EDID data is totally useless */ +@@ -715,7 +724,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) + int num_modes, hz, hscan, pixclock; + int vtotal, htotal; + +- modes = fb_create_modedb(edid, &num_modes); ++ modes = fb_create_modedb(edid, &num_modes, specs); + if (!modes) { + DPRINTK("None Available\n"); + return 1; +@@ -972,7 +981,7 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) + DPRINTK(" Display Characteristics:\n"); + get_monspecs(edid, specs); + +- specs->modedb = fb_create_modedb(edid, &specs->modedb_len); ++ specs->modedb = fb_create_modedb(edid, &specs->modedb_len, specs); + + /* + * Workaround for buggy EDIDs that sets that the first +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/video-fbdev-fix-CVT-vertical-front-and-back-porch-values.patch b/kernel/kernel/files/patches/mageia/video-fbdev-fix-CVT-vertical-front-and-back-porch-values.patch new file mode 100644 index 00000000..fdcd789f --- /dev/null +++ b/kernel/kernel/files/patches/mageia/video-fbdev-fix-CVT-vertical-front-and-back-porch-values.patch @@ -0,0 +1,44 @@ +From 4d073292a74b31ea00443d7778a95c209140aa42 Mon Sep 17 00:00:00 2001 +From: Tomi Valkeinen +Date: Wed, 21 Jan 2015 09:37:51 +0200 +Subject: [PATCH] fbdev: fix CVT vertical front and back porch values + +CVT v1.1 spec says: "the vertical front porch shall in all cases be +fixed to 3 lines". The code in fbcvt.c instead sets the _back_ porch to +3 (plus margin). + +After swapping cvt.v_front_porch and cvt.v_back_porch the resulting +timings were in line with CVT timings in VESA DMT spec. + +The bug seems to be more than 9 years old, but I presume it has not been +noticed as usually the video timings come from the EDID or from the +timing tables in fbdev, and probably swapped values for vfp and vbp work +fine for most of the displays. + +Signed-off-by: Tomi Valkeinen +Acked-by: David Ung +Cc: Antonino A. Daplas +--- + drivers/video/fbdev/core/fbcvt.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c +index 7cb715d..55d2bd0 100644 +--- a/drivers/video/fbdev/core/fbcvt.c ++++ b/drivers/video/fbdev/core/fbcvt.c +@@ -369,9 +369,9 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb) + cvt.h_back_porch = cvt.hblank/2 + cvt.h_margin; + cvt.h_front_porch = cvt.hblank - cvt.hsync - cvt.h_back_porch + + 2 * cvt.h_margin; +- cvt.v_back_porch = 3 + cvt.v_margin; +- cvt.v_front_porch = cvt.vtotal - cvt.yres/cvt.interlace - +- cvt.v_back_porch - cvt.vsync; ++ cvt.v_front_porch = 3 + cvt.v_margin; ++ cvt.v_back_porch = cvt.vtotal - cvt.yres/cvt.interlace - ++ cvt.v_front_porch - cvt.vsync; + fb_cvt_print_name(&cvt); + fb_cvt_convert_to_mode(&cvt, mode); + +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/video-fbdev-fix-possible-null-dereference.patch b/kernel/kernel/files/patches/mageia/video-fbdev-fix-possible-null-dereference.patch new file mode 100644 index 00000000..0131de78 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/video-fbdev-fix-possible-null-dereference.patch @@ -0,0 +1,42 @@ +From d746b40c64619f5064ebbe545938062481ef5183 Mon Sep 17 00:00:00 2001 +From: Sudip Mukherjee +Date: Thu, 12 Feb 2015 21:17:11 +0530 +Subject: [PATCH] video: fbdev: fix possible null dereference + +we were dereferencing edid first and the NULL check was after +accessing that. now we are using edid only if we know that +it is not NULL. + +Signed-off-by: Sudip Mukherjee +Signed-off-by: Tomi Valkeinen +--- + drivers/video/fbdev/core/fbmon.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c +index 9533859..868facd 100644 +--- a/drivers/video/fbdev/core/fbmon.c ++++ b/drivers/video/fbdev/core/fbmon.c +@@ -624,9 +624,6 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, + int num = 0, i, first = 1; + int ver, rev; + +- ver = edid[EDID_STRUCT_VERSION]; +- rev = edid[EDID_STRUCT_REVISION]; +- + mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); + if (mode == NULL) + return NULL; +@@ -637,6 +634,9 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, + return NULL; + } + ++ ver = edid[EDID_STRUCT_VERSION]; ++ rev = edid[EDID_STRUCT_REVISION]; ++ + *dbsize = 0; + + DPRINTK(" Detailed Timings\n"); +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/video-fbdev-fix-sys_copyarea.patch b/kernel/kernel/files/patches/mageia/video-fbdev-fix-sys_copyarea.patch new file mode 100644 index 00000000..03c3dc6d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/video-fbdev-fix-sys_copyarea.patch @@ -0,0 +1,332 @@ +From ee06bd155b081a1895f995ec2777094c7e746152 Mon Sep 17 00:00:00 2001 +From: Mans Rullgard +Date: Thu, 22 Jan 2015 01:19:24 +0000 +Subject: [PATCH] video: fbdev: fix sys_copyarea + +The sys_copyarea() function performs the same operation as +cfb_copyarea() but using normal memory access instead of I/O +accessors. Since the introduction of sys_copyarea(), there +have been two fixes to cfb_copyarea(): + +- 00a9d699 ("framebuffer: fix cfb_copyarea") +- 5b789da8 ("framebuffer: fix screen corruption when copying") + +This patch incorporates the fixes into sys_copyarea() as well. + +Signed-off-by: Mans Rullgard +Signed-off-by: Tomi Valkeinen +--- + drivers/video/fbdev/core/syscopyarea.c | 137 ++++++++++++++++----------------- + 1 file changed, 65 insertions(+), 72 deletions(-) + +diff --git a/drivers/video/fbdev/core/syscopyarea.c b/drivers/video/fbdev/core/syscopyarea.c +index 844a32f..c1eda31 100644 +--- a/drivers/video/fbdev/core/syscopyarea.c ++++ b/drivers/video/fbdev/core/syscopyarea.c +@@ -25,8 +25,8 @@ + */ + + static void +-bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx, +- const unsigned long *src, int src_idx, int bits, unsigned n) ++bitcpy(struct fb_info *p, unsigned long *dst, unsigned dst_idx, ++ const unsigned long *src, unsigned src_idx, int bits, unsigned n) + { + unsigned long first, last; + int const shift = dst_idx-src_idx; +@@ -86,15 +86,15 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx, + first &= last; + if (shift > 0) { + /* Single source word */ +- *dst = comp(*src >> right, *dst, first); ++ *dst = comp(*src << left, *dst, first); + } else if (src_idx+n <= bits) { + /* Single source word */ +- *dst = comp(*src << left, *dst, first); ++ *dst = comp(*src >> right, *dst, first); + } else { + /* 2 source words */ + d0 = *src++; + d1 = *src; +- *dst = comp(d0 << left | d1 >> right, *dst, ++ *dst = comp(d0 >> right | d1 << left, *dst, + first); + } + } else { +@@ -109,13 +109,14 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx, + /* Leading bits */ + if (shift > 0) { + /* Single source word */ +- *dst = comp(d0 >> right, *dst, first); ++ *dst = comp(d0 << left, *dst, first); + dst++; + n -= bits - dst_idx; + } else { + /* 2 source words */ + d1 = *src++; +- *dst = comp(d0 << left | *dst >> right, *dst, first); ++ *dst = comp(d0 >> right | d1 << left, *dst, ++ first); + d0 = d1; + dst++; + n -= bits - dst_idx; +@@ -126,36 +127,36 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx, + n /= bits; + while (n >= 4) { + d1 = *src++; +- *dst++ = d0 << left | d1 >> right; ++ *dst++ = d0 >> right | d1 << left; + d0 = d1; + d1 = *src++; +- *dst++ = d0 << left | d1 >> right; ++ *dst++ = d0 >> right | d1 << left; + d0 = d1; + d1 = *src++; +- *dst++ = d0 << left | d1 >> right; ++ *dst++ = d0 >> right | d1 << left; + d0 = d1; + d1 = *src++; +- *dst++ = d0 << left | d1 >> right; ++ *dst++ = d0 >> right | d1 << left; + d0 = d1; + n -= 4; + } + while (n--) { + d1 = *src++; +- *dst++ = d0 << left | d1 >> right; ++ *dst++ = d0 >> right | d1 << left; + d0 = d1; + } + + /* Trailing bits */ +- if (last) { +- if (m <= right) { ++ if (m) { ++ if (m <= bits - right) { + /* Single source word */ +- *dst = comp(d0 << left, *dst, last); ++ d0 >>= right; + } else { + /* 2 source words */ + d1 = *src; +- *dst = comp(d0 << left | d1 >> right, +- *dst, last); ++ d0 = d0 >> right | d1 << left; + } ++ *dst = comp(d0, *dst, last); + } + } + } +@@ -166,40 +167,35 @@ bitcpy(struct fb_info *p, unsigned long *dst, int dst_idx, + */ + + static void +-bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx, +- const unsigned long *src, int src_idx, int bits, unsigned n) ++bitcpy_rev(struct fb_info *p, unsigned long *dst, unsigned dst_idx, ++ const unsigned long *src, unsigned src_idx, unsigned bits, ++ unsigned n) + { + unsigned long first, last; + int shift; + +- dst += (n-1)/bits; +- src += (n-1)/bits; +- if ((n-1) % bits) { +- dst_idx += (n-1) % bits; +- dst += dst_idx >> (ffs(bits) - 1); +- dst_idx &= bits - 1; +- src_idx += (n-1) % bits; +- src += src_idx >> (ffs(bits) - 1); +- src_idx &= bits - 1; +- } ++ dst += (dst_idx + n - 1) / bits; ++ src += (src_idx + n - 1) / bits; ++ dst_idx = (dst_idx + n - 1) % bits; ++ src_idx = (src_idx + n - 1) % bits; + + shift = dst_idx-src_idx; + +- first = FB_SHIFT_LOW(p, ~0UL, bits - 1 - dst_idx); +- last = ~(FB_SHIFT_LOW(p, ~0UL, bits - 1 - ((dst_idx-n) % bits))); ++ first = ~FB_SHIFT_HIGH(p, ~0UL, (dst_idx + 1) % bits); ++ last = FB_SHIFT_HIGH(p, ~0UL, (bits + dst_idx + 1 - n) % bits); + + if (!shift) { + /* Same alignment for source and dest */ + if ((unsigned long)dst_idx+1 >= n) { + /* Single word */ +- if (last) +- first &= last; +- *dst = comp(*src, *dst, first); ++ if (first) ++ last &= first; ++ *dst = comp(*src, *dst, last); + } else { + /* Multiple destination words */ + + /* Leading bits */ +- if (first != ~0UL) { ++ if (first) { + *dst = comp(*src, *dst, first); + dst--; + src--; +@@ -222,29 +218,29 @@ bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx, + while (n--) + *dst-- = *src--; + /* Trailing bits */ +- if (last) ++ if (last != -1UL) + *dst = comp(*src, *dst, last); + } + } else { + /* Different alignment for source and dest */ + +- int const left = -shift & (bits-1); +- int const right = shift & (bits-1); ++ int const left = shift & (bits-1); ++ int const right = -shift & (bits-1); + + if ((unsigned long)dst_idx+1 >= n) { + /* Single destination word */ +- if (last) +- first &= last; ++ if (first) ++ last &= first; + if (shift < 0) { + /* Single source word */ +- *dst = comp(*src << left, *dst, first); ++ *dst = comp(*src >> right, *dst, last); + } else if (1+(unsigned long)src_idx >= n) { + /* Single source word */ +- *dst = comp(*src >> right, *dst, first); ++ *dst = comp(*src << left, *dst, last); + } else { + /* 2 source words */ +- *dst = comp(*src >> right | *(src-1) << left, +- *dst, first); ++ *dst = comp(*src << left | *(src-1) >> right, ++ *dst, last); + } + } else { + /* Multiple destination words */ +@@ -261,14 +257,18 @@ bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx, + /* Leading bits */ + if (shift < 0) { + /* Single source word */ +- *dst = comp(d0 << left, *dst, first); ++ d1 = d0; ++ d0 >>= right; + } else { + /* 2 source words */ + d1 = *src--; +- *dst = comp(d0 >> right | d1 << left, *dst, +- first); +- d0 = d1; ++ d0 = d0 << left | d1 >> right; + } ++ if (!first) ++ *dst = d0; ++ else ++ *dst = comp(d0, *dst, first); ++ d0 = d1; + dst--; + n -= dst_idx+1; + +@@ -277,36 +277,36 @@ bitcpy_rev(struct fb_info *p, unsigned long *dst, int dst_idx, + n /= bits; + while (n >= 4) { + d1 = *src--; +- *dst-- = d0 >> right | d1 << left; ++ *dst-- = d0 << left | d1 >> right; + d0 = d1; + d1 = *src--; +- *dst-- = d0 >> right | d1 << left; ++ *dst-- = d0 << left | d1 >> right; + d0 = d1; + d1 = *src--; +- *dst-- = d0 >> right | d1 << left; ++ *dst-- = d0 << left | d1 >> right; + d0 = d1; + d1 = *src--; +- *dst-- = d0 >> right | d1 << left; ++ *dst-- = d0 << left | d1 >> right; + d0 = d1; + n -= 4; + } + while (n--) { + d1 = *src--; +- *dst-- = d0 >> right | d1 << left; ++ *dst-- = d0 << left | d1 >> right; + d0 = d1; + } + + /* Trailing bits */ +- if (last) { +- if (m <= left) { ++ if (m) { ++ if (m <= bits - left) { + /* Single source word */ +- *dst = comp(d0 >> right, *dst, last); ++ d0 <<= left; + } else { + /* 2 source words */ + d1 = *src; +- *dst = comp(d0 >> right | d1 << left, +- *dst, last); ++ d0 = d0 << left | d1 >> right; + } ++ *dst = comp(d0, *dst, last); + } + } + } +@@ -317,9 +317,9 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area) + u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy; + u32 height = area->height, width = area->width; + unsigned long const bits_per_line = p->fix.line_length*8u; +- unsigned long *dst = NULL, *src = NULL; ++ unsigned long *base = NULL; + int bits = BITS_PER_LONG, bytes = bits >> 3; +- int dst_idx = 0, src_idx = 0, rev_copy = 0; ++ unsigned dst_idx = 0, src_idx = 0, rev_copy = 0; + + if (p->state != FBINFO_STATE_RUNNING) + return; +@@ -334,8 +334,7 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area) + + /* split the base of the framebuffer into a long-aligned address and + the index of the first bit */ +- dst = src = (unsigned long *)((unsigned long)p->screen_base & +- ~(bytes-1)); ++ base = (unsigned long *)((unsigned long)p->screen_base & ~(bytes-1)); + dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1)); + /* add offset of source and target area */ + dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel; +@@ -348,20 +347,14 @@ void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area) + while (height--) { + dst_idx -= bits_per_line; + src_idx -= bits_per_line; +- dst += dst_idx >> (ffs(bits) - 1); +- dst_idx &= (bytes - 1); +- src += src_idx >> (ffs(bits) - 1); +- src_idx &= (bytes - 1); +- bitcpy_rev(p, dst, dst_idx, src, src_idx, bits, ++ bitcpy_rev(p, base + (dst_idx / bits), dst_idx % bits, ++ base + (src_idx / bits), src_idx % bits, bits, + width*p->var.bits_per_pixel); + } + } else { + while (height--) { +- dst += dst_idx >> (ffs(bits) - 1); +- dst_idx &= (bytes - 1); +- src += src_idx >> (ffs(bits) - 1); +- src_idx &= (bytes - 1); +- bitcpy(p, dst, dst_idx, src, src_idx, bits, ++ bitcpy(p, base + (dst_idx / bits), dst_idx % bits, ++ base + (src_idx / bits), src_idx % bits, bits, + width*p->var.bits_per_pixel); + dst_idx += bits_per_line; + src_idx += bits_per_line; +-- +2.3.1 + diff --git a/kernel/kernel/files/patches/mageia/video-mageia-logo.patch b/kernel/kernel/files/patches/mageia/video-mageia-logo.patch new file mode 100644 index 00000000..efc5307e --- /dev/null +++ b/kernel/kernel/files/patches/mageia/video-mageia-logo.patch @@ -0,0 +1,949 @@ + +Mageia framebuffer boot logo + +Signed-off-by: Thomas Backlund + + drivers/video/logo/Kconfig | 5 + drivers/video/logo/Makefile | 1 + drivers/video/logo/logo.c | 5 + drivers/video/logo/logo_mageia_clut224.ppm | 883 +++++++++++++++++++++++++++++ + include/linux/linux_logo.h | 1 + 5 files changed, 895 insertions(+) + +diff -Nurp linux-2.6.37.3/drivers/video/logo/Kconfig linux-2.6.37.3.mga/drivers/video/logo/Kconfig +--- linux-2.6.37.3/drivers/video/logo/Kconfig 2011-01-05 02:50:19.000000000 +0200 ++++ linux-2.6.37.3.mga/drivers/video/logo/Kconfig 2011-03-08 21:50:08.077611366 +0200 +@@ -82,4 +82,9 @@ config LOGO_M32R_CLUT224 + depends on M32R + default y + ++config LOGO_MAGEIA_CLUT224 ++ bool "224-color Mageia logo" ++ depends on LOGO ++ default y ++ + endif # LOGO +diff -Nurp linux-2.6.37.3/drivers/video/logo/logo.c linux-2.6.37.3.mga/drivers/video/logo/logo.c +--- linux-2.6.37.3/drivers/video/logo/logo.c 2011-01-05 02:50:19.000000000 +0200 ++++ linux-2.6.37.3.mga/drivers/video/logo/logo.c 2011-03-08 21:51:27.042063947 +0200 +@@ -63,6 +63,11 @@ const struct linux_logo * __init_refok f + } + + if (depth >= 8) { ++#ifdef CONFIG_LOGO_MAGEIA_CLUT224 ++ /* Mageia logo */ ++ logo = &logo_mageia_clut224; ++ return logo; ++#endif + #ifdef CONFIG_LOGO_LINUX_CLUT224 + /* Generic Linux logo */ + logo = &logo_linux_clut224; +diff -Nurp linux-2.6.37.3/drivers/video/logo/logo_mageia_clut224.ppm linux-2.6.37.3.mga/drivers/video/logo/logo_mageia_clut224.ppm +--- linux-2.6.37.3/drivers/video/logo/logo_mageia_clut224.ppm 1970-01-01 02:00:00.000000000 +0200 ++++ linux-2.6.37.3.mga/drivers/video/logo/logo_mageia_clut224.ppm 2011-03-08 23:47:47.000000000 +0200 +@@ -0,0 +1,883 @@ ++P3 ++80 80 ++255 ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 11 16 9 14 29 ++9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 ++9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 ++9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 ++9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 ++9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 ++9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 ++9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 ++9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 9 14 29 ++9 14 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++ ++0 0 0 0 0 0 0 0 0 0 0 0 8 23 42 32 55 114 37 56 117 37 56 117 ++37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 ++37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 ++37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 ++37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 ++37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 ++37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 ++37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 ++37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 37 56 117 ++37 56 117 37 56 117 18 45 91 9 14 29 0 0 0 0 0 0 0 0 0 0 0 0 ++ ++0 0 0 0 0 0 0 0 0 18 45 91 37 56 117 37 56 117 36 57 118 36 57 118 ++36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 ++36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 ++36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 ++36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 ++36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 ++36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 ++36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 ++36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 36 57 118 ++36 57 118 36 57 118 37 56 117 36 57 118 17 36 71 0 0 0 0 0 0 0 0 0 ++ ++0 0 0 3 11 16 18 45 91 35 58 120 35 58 119 35 58 119 35 58 119 35 58 119 ++35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 ++35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 ++35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 ++35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 ++35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 ++35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 ++35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 ++35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 35 58 119 ++35 58 119 35 58 119 35 58 119 35 58 119 35 58 120 17 36 71 0 0 0 0 0 0 ++ ++0 0 0 11 38 58 37 56 117 34 59 122 35 58 119 35 58 120 35 58 120 35 58 120 ++35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 ++35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 ++35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 ++35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 ++35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 ++35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 ++35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 ++35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 ++35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 35 58 120 9 14 29 0 0 0 ++ ++0 0 0 32 55 114 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 ++34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 ++34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 ++34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 ++34 59 122 34 59 122 34 59 122 35 58 119 63 96 153 63 96 153 63 96 153 34 59 122 ++34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 ++34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 ++34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 ++34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 ++34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 34 59 122 18 45 91 0 0 0 ++ ++8 23 42 34 59 122 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 ++33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 ++33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 ++33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 ++33 60 123 33 60 123 33 60 123 125 157 204 191 220 251 194 222 252 191 218 250 108 152 201 ++32 55 114 32 62 125 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 ++33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 ++33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 ++33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 ++33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 33 60 123 34 59 122 0 0 0 ++ ++11 38 58 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 ++32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 ++32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 ++32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 ++32 61 124 32 62 125 63 96 153 170 209 245 168 209 245 168 209 245 170 209 245 164 205 243 ++63 96 153 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 ++32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 ++32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 ++32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 ++32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 61 124 32 62 125 8 16 31 ++ ++17 36 71 33 60 123 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 ++32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 ++32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 ++32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 ++32 62 125 32 62 125 86 129 181 148 198 240 145 197 239 145 197 239 145 197 239 145 197 239 ++63 96 153 32 61 124 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 ++32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 ++32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 ++32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 ++32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 32 62 125 8 16 31 ++ ++11 38 58 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 ++31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 ++31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 ++31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 ++31 63 126 30 65 129 63 96 153 123 185 232 123 185 232 123 185 232 123 185 232 122 182 230 ++41 91 154 31 63 126 31 63 126 31 63 126 31 63 126 63 96 153 40 74 135 31 63 126 ++31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 ++31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 ++31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 ++31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 31 63 126 8 16 31 ++ ++17 36 71 31 63 126 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 ++30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 ++30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 ++30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 ++30 64 128 30 64 128 30 65 129 85 139 195 97 172 225 100 173 226 100 173 226 85 139 195 ++32 61 124 30 64 128 30 64 128 86 129 181 184 213 246 201 225 254 201 225 254 142 183 225 ++40 74 135 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 ++30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 ++30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 ++30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 30 64 128 8 16 31 ++ ++17 36 71 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 ++30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 ++30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 ++30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 ++30 65 129 30 65 129 29 66 130 31 63 126 58 114 175 58 114 175 41 91 154 29 66 130 ++30 65 129 28 68 132 40 74 135 178 210 243 176 212 247 173 211 246 176 212 247 176 212 247 ++125 157 204 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 ++30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 ++30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 ++30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 30 65 129 8 16 31 ++ ++17 36 71 30 64 128 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 ++29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 ++29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 ++29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 ++29 66 130 29 66 130 29 66 130 29 66 130 30 64 128 28 67 131 29 66 130 29 66 130 ++29 66 130 29 66 130 85 139 195 158 203 242 154 201 241 155 202 241 155 202 241 155 202 241 ++154 201 241 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 ++29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 ++29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 ++29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 29 66 130 6 18 34 ++ ++17 36 71 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 ++28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 ++28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 ++28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 ++28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 ++28 67 131 28 67 131 86 129 181 134 191 236 134 191 236 134 191 236 134 191 236 134 191 236 ++134 191 236 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 ++28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 ++28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 ++28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 28 67 131 6 18 34 ++ ++17 36 71 28 67 131 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 ++28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 ++28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 ++28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 ++28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 ++28 68 132 28 68 132 40 74 135 117 182 230 115 181 230 115 181 230 115 181 230 115 181 230 ++85 139 195 27 69 133 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 ++28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 ++28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 ++28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 28 68 132 6 18 34 ++ ++17 36 71 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 ++27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 ++27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 ++27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 ++27 69 133 27 69 133 27 69 133 27 69 133 26 71 136 63 96 153 108 152 201 142 183 225 ++86 129 181 27 69 133 27 69 133 58 114 175 95 170 224 95 170 224 97 172 225 77 152 208 ++41 91 154 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 ++27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 ++27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 ++27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 27 69 133 6 18 34 ++ ++11 38 71 27 69 133 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 ++26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 ++26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 ++26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 ++26 70 135 26 70 135 26 70 135 26 70 135 86 129 181 197 223 253 188 217 249 188 217 249 ++191 220 251 152 193 232 40 74 135 26 70 135 23 75 141 41 91 154 41 91 154 26 70 135 ++27 69 133 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 ++26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 ++26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 ++26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 26 70 135 6 18 34 ++ ++11 38 71 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 ++26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 ++26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 ++26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 ++26 71 136 26 71 136 26 70 135 41 91 154 172 210 246 170 209 245 170 209 245 170 209 245 ++168 209 245 178 210 243 85 139 195 26 71 136 26 71 136 25 72 137 26 71 136 26 71 136 ++26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 ++26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 ++26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 ++26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 26 71 136 6 18 34 ++ ++11 38 71 26 71 136 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 ++25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 ++25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 ++25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 ++25 72 137 25 72 137 25 72 137 86 129 181 151 200 240 152 200 240 152 200 240 152 200 240 ++152 200 240 151 200 240 122 172 221 27 69 133 24 73 138 25 72 137 25 72 137 25 72 137 ++25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 ++25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 ++25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 ++25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 25 72 137 6 18 34 ++ ++11 38 71 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 ++24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 ++24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 ++24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 ++24 73 138 24 73 138 25 72 137 58 114 175 134 191 236 134 191 236 134 191 236 134 191 236 ++134 191 236 134 191 236 108 152 201 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 ++24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 ++24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 ++24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 ++24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 24 73 138 6 18 34 ++ ++11 38 71 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 ++23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 ++23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 ++23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 ++23 74 139 23 74 139 23 74 139 41 91 154 115 181 230 115 181 230 115 181 230 115 181 230 ++115 181 230 115 181 230 60 128 188 24 73 138 23 74 139 23 74 139 23 74 139 23 74 139 ++23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 ++23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 ++23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 ++23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 23 74 139 5 19 36 ++ ++11 38 71 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 ++23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 ++23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 ++23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 ++23 75 141 23 75 141 23 75 141 23 74 139 58 114 175 97 172 225 97 172 225 97 172 225 ++97 172 225 77 152 208 24 73 138 23 75 141 41 91 154 125 157 204 152 193 232 142 183 225 ++86 129 181 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 ++23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 ++23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 ++23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 23 75 141 5 19 36 ++ ++11 38 71 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 ++22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 ++22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 ++22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 ++22 76 142 22 76 142 22 76 142 22 76 142 21 76 143 30 98 155 58 114 175 60 128 188 ++42 114 176 23 74 139 21 76 143 63 96 153 176 212 247 188 218 250 188 218 250 188 217 249 ++191 218 250 125 157 204 21 77 144 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 ++22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 ++22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 ++22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 22 76 142 5 19 36 ++ ++11 38 71 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 ++21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 ++21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 ++21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 23 75 141 ++58 114 175 125 157 204 152 193 232 108 152 201 41 91 154 21 77 144 21 77 144 21 76 143 ++21 76 143 21 76 143 21 76 143 131 179 222 172 210 246 172 210 246 172 210 246 172 210 246 ++172 210 246 170 209 245 86 129 181 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 ++21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 ++21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 ++21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 21 76 143 5 19 36 ++ ++11 38 71 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 ++21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 ++21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 ++21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 125 157 204 ++194 222 252 191 220 251 191 220 251 191 220 251 184 213 246 86 129 181 21 77 144 21 77 144 ++21 77 144 21 77 144 22 89 156 155 202 241 155 202 242 155 202 242 155 202 242 155 202 242 ++155 202 242 155 202 242 122 172 221 21 76 143 21 77 144 21 77 144 21 77 144 21 77 144 ++21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 ++21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 ++21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 21 77 144 5 19 36 ++ ++11 38 71 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 ++20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 ++20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 ++20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 21 77 144 85 139 195 176 212 247 ++176 212 247 176 212 247 176 212 247 176 212 247 176 212 247 164 205 243 41 91 154 20 78 145 ++20 78 145 20 78 145 41 91 154 140 193 237 140 193 237 140 193 237 140 193 237 140 193 237 ++137 192 236 143 192 235 100 169 221 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 ++20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 ++20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 ++20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 20 78 145 5 19 36 ++ ++11 38 71 19 80 148 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 ++19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 ++19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 ++19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 131 179 222 161 204 243 ++160 204 243 160 204 243 160 204 243 160 204 243 160 204 243 160 204 243 85 139 195 19 79 147 ++19 79 147 19 79 147 19 79 147 111 178 227 123 185 232 121 184 232 122 185 232 122 185 232 ++122 185 232 122 185 232 85 139 195 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 ++19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 ++19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 ++19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 19 79 147 5 19 36 ++ ++11 38 71 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 ++19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 ++19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 ++19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 145 196 239 145 196 239 ++145 196 239 145 196 239 145 196 239 145 196 239 145 196 239 145 196 239 85 139 195 19 80 148 ++19 80 148 19 80 148 19 79 147 60 128 188 106 176 228 106 176 228 106 176 228 106 176 228 ++106 176 228 100 172 225 22 89 156 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 ++19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 ++19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 ++19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 19 80 148 5 19 36 ++ ++11 38 71 17 82 150 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 ++18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 ++18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 ++18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 111 178 227 132 189 234 ++130 189 235 130 189 235 130 189 235 130 189 235 130 189 235 130 189 235 85 139 195 17 82 150 ++18 81 149 18 81 149 18 81 149 18 81 149 42 114 176 88 166 221 87 167 223 89 168 223 ++77 152 208 30 98 155 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 ++18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 ++18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 ++18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 18 81 149 5 19 36 ++ ++11 38 71 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 ++17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 ++17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 ++17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 16 83 151 85 139 195 115 181 230 ++115 181 230 115 181 230 115 181 230 115 181 230 117 182 230 111 178 227 42 114 176 17 82 150 ++17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 18 81 149 23 96 163 22 89 156 ++18 81 149 16 83 151 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 ++17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 ++17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 ++17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 17 82 150 4 21 38 ++ ++9 48 78 17 82 150 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 ++16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 ++16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 ++16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 22 89 156 83 162 217 ++100 172 225 100 173 226 100 173 226 100 173 226 100 173 226 62 142 198 19 79 147 16 83 151 ++16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 ++16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 ++16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 ++16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 ++16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 16 83 151 4 21 38 ++ ++9 48 78 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 ++16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 ++16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 ++16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 14 87 156 ++60 128 188 77 152 208 84 165 222 65 151 210 42 114 176 16 84 153 16 84 153 16 84 153 ++16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 ++16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 ++16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 ++16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 ++16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 16 84 153 4 21 38 ++ ++9 48 78 16 84 153 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 ++15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 ++15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 ++15 85 154 15 85 154 15 85 154 58 114 175 42 114 176 16 84 153 15 85 154 15 85 154 ++15 85 154 14 86 155 15 85 154 16 84 153 15 85 154 15 85 154 15 85 154 15 85 154 ++15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 ++15 85 154 15 85 154 15 85 154 58 114 175 42 114 176 16 83 151 15 85 154 15 85 154 ++15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 ++15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 ++15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 15 85 154 4 21 38 ++ ++9 48 78 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 ++14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 ++14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 ++15 85 154 42 114 176 178 210 243 204 226 255 204 226 255 178 210 243 42 114 176 14 86 155 ++14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 ++14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 ++14 86 155 85 139 195 191 218 250 204 226 255 201 225 254 142 183 225 23 96 163 14 86 155 ++14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 ++14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 ++14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 14 86 155 4 21 38 ++ ++9 48 78 14 86 155 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 ++14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 ++14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 ++42 114 176 191 218 250 201 225 254 201 225 254 201 225 254 201 225 254 201 225 254 108 152 201 ++13 88 157 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 ++14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 23 96 163 ++142 183 225 201 225 254 201 225 254 201 225 254 201 225 254 201 225 254 163 199 237 23 96 163 ++14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 ++14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 ++14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 14 87 156 4 21 38 ++ ++9 48 78 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 ++13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 ++13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 14 87 156 42 114 176 ++184 213 246 197 223 253 197 223 253 197 223 253 197 223 253 197 223 253 197 223 253 196 222 253 ++178 210 243 60 128 188 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 ++13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 23 96 163 91 153 206 184 213 246 ++197 223 253 197 223 253 197 223 253 197 223 253 197 223 253 197 223 253 197 223 253 163 199 237 ++23 96 163 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 ++13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 ++13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 13 88 157 4 21 38 ++ ++9 48 78 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 ++12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 ++12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 28 113 174 184 213 246 ++194 222 252 194 222 252 194 222 252 194 222 252 194 222 252 194 222 252 194 222 252 194 222 252 ++194 222 252 196 222 253 172 207 243 125 157 204 60 128 188 13 88 157 12 89 158 12 89 158 ++12 89 158 12 89 158 23 96 163 60 128 188 122 172 221 184 213 246 194 222 252 194 222 252 ++194 222 252 194 222 252 194 222 252 194 222 252 194 222 252 194 222 252 194 222 252 194 222 252 ++163 199 237 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 ++12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 ++12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 12 89 158 4 21 38 ++ ++9 48 78 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 ++12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 ++12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 13 88 157 163 199 237 191 220 251 ++191 220 251 191 220 251 191 220 251 191 220 251 191 220 251 191 220 251 191 220 251 191 220 251 ++191 220 251 191 220 251 191 220 251 188 218 250 191 218 250 191 220 251 178 210 243 152 193 232 ++142 183 225 191 220 251 191 220 251 194 222 252 191 220 251 191 220 251 191 220 251 191 220 251 ++191 220 251 191 220 251 191 220 251 191 220 251 191 220 251 191 220 251 191 220 251 191 220 251 ++185 217 250 125 157 204 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 ++12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 ++12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 12 90 160 1 24 42 ++ ++9 48 78 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 ++11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 ++11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 91 153 206 188 218 250 188 218 250 ++188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 ++188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 ++188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 ++188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 188 218 250 ++188 218 250 188 218 250 60 128 188 12 89 158 11 91 161 11 91 161 11 91 161 11 91 161 ++11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 ++11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 11 91 161 1 24 42 ++ ++9 48 78 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 ++10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 ++10 92 162 10 92 162 10 92 162 11 91 161 28 113 174 188 218 250 185 217 250 185 217 250 ++185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 ++185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 ++185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 ++185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 185 217 250 ++185 217 250 185 217 250 163 199 237 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 ++10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 ++10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 10 92 162 1 24 42 ++ ++2 50 86 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 ++9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 ++9 92 163 9 92 163 9 92 163 9 92 163 122 172 221 179 214 248 182 215 249 182 215 249 ++182 215 249 182 215 249 182 215 249 182 215 249 152 193 232 182 215 249 182 215 249 182 215 249 ++182 215 249 182 215 249 182 215 249 182 215 249 182 215 249 182 215 249 182 215 249 182 215 249 ++182 215 249 182 215 249 182 215 249 182 215 249 182 215 249 182 215 249 182 215 249 182 215 249 ++182 215 249 182 215 249 172 207 243 163 199 237 182 215 249 182 215 249 182 215 249 182 215 249 ++182 215 249 182 215 249 182 215 249 85 139 195 8 94 166 9 92 163 9 92 163 9 92 163 ++9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 ++9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 9 92 163 1 24 42 ++ ++9 48 78 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 ++9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 ++9 93 164 9 93 164 9 92 163 28 113 174 179 214 248 179 214 248 179 214 248 179 214 248 ++179 214 248 179 214 248 179 214 248 122 172 221 11 91 161 40 129 186 142 183 225 179 214 248 ++179 214 248 179 214 248 179 214 248 179 214 248 179 214 248 179 214 248 179 214 248 179 214 248 ++179 214 248 179 214 248 179 214 248 179 214 248 179 214 248 179 214 248 179 214 248 179 214 248 ++176 212 247 122 172 221 28 113 174 18 102 171 163 199 237 179 214 248 179 214 248 179 214 248 ++179 214 248 179 214 248 179 214 248 154 201 241 9 93 164 9 93 164 9 93 164 9 93 164 ++9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 ++9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 9 93 164 1 24 42 ++ ++2 50 86 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 ++8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 ++8 94 166 8 94 166 8 94 166 107 172 224 178 210 243 176 212 247 176 212 247 176 212 247 ++176 212 247 176 212 247 164 205 243 18 102 171 8 94 166 8 94 166 8 94 166 28 113 174 ++92 162 218 163 199 237 173 211 246 176 212 247 176 212 247 176 212 247 176 212 247 176 212 247 ++176 212 247 176 212 247 176 212 247 176 212 247 176 212 247 176 212 247 143 192 235 85 139 195 ++18 102 171 8 94 166 8 94 166 8 94 166 40 129 186 176 212 247 176 212 247 176 212 247 ++176 212 247 176 212 247 176 212 247 176 212 247 62 142 198 9 93 164 8 94 166 8 94 166 ++8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 ++8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 8 94 166 1 24 42 ++ ++2 50 86 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 ++7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 ++7 95 167 7 95 167 8 94 166 161 204 243 173 211 246 173 211 246 173 211 246 173 211 246 ++172 210 246 178 210 243 62 142 198 7 95 167 7 95 167 7 95 167 7 95 167 8 94 166 ++8 94 166 8 94 166 28 119 185 85 139 195 92 162 218 131 179 222 131 179 222 131 179 222 ++131 179 222 131 179 222 131 179 222 91 153 206 62 142 198 28 113 174 7 95 167 7 96 168 ++7 95 167 7 95 167 7 95 167 7 96 168 9 93 164 107 172 224 173 211 246 173 211 246 ++173 211 246 173 211 246 173 211 246 173 211 246 122 172 221 7 95 167 7 95 167 7 95 167 ++7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 ++7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 7 95 167 1 24 42 ++ ++2 50 86 7 95 167 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 ++7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 ++7 96 168 7 96 168 60 128 188 170 209 245 170 209 245 170 209 245 170 209 245 170 209 245 ++170 209 245 145 196 239 8 94 166 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 ++7 96 168 7 96 168 7 96 168 6 97 169 7 96 168 7 96 168 6 97 169 7 96 168 ++6 97 169 7 96 168 6 97 169 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 ++7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 28 113 174 170 209 245 170 209 245 ++170 209 245 170 209 245 170 209 245 170 209 245 170 209 245 18 102 171 7 96 168 7 96 168 ++7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 ++7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 7 96 168 1 24 42 ++ ++2 50 86 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 ++6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 ++6 97 169 7 96 168 92 162 218 167 207 244 167 207 244 167 207 244 167 207 244 167 207 244 ++167 207 244 91 153 206 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 ++6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 ++6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 ++6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 5 99 172 131 179 222 167 207 244 ++167 207 244 167 207 244 167 207 244 167 207 244 168 209 245 60 128 188 6 97 169 6 97 169 ++6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 ++6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 6 97 169 1 24 42 ++ ++2 50 86 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 ++5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 ++5 98 170 5 98 170 132 189 234 164 205 243 164 205 243 164 205 243 164 205 243 164 205 243 ++164 205 243 28 113 174 5 99 172 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 ++5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 ++5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 ++5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 62 142 198 164 205 243 ++164 205 243 164 205 243 164 205 243 164 205 243 164 205 243 92 162 218 5 98 170 5 98 170 ++5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 ++5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 5 98 170 1 24 42 ++ ++2 50 86 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 ++5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 ++5 99 172 5 99 172 161 204 243 161 204 243 161 204 243 161 204 243 161 204 243 161 204 243 ++139 191 235 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 ++5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 ++5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 ++5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 4 100 173 28 113 174 161 204 243 ++161 204 243 161 204 243 161 204 243 161 204 243 161 204 243 122 172 221 5 99 172 5 99 172 ++5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 ++5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 5 99 172 1 24 42 ++ ++2 50 86 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 ++4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 ++4 100 173 28 119 185 160 204 243 158 203 242 158 203 242 158 203 242 158 203 242 158 203 242 ++100 169 221 5 98 170 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 ++4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 ++4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 ++4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 3 101 174 139 191 235 ++158 203 242 158 203 242 158 203 242 158 203 242 158 203 242 148 198 240 4 100 173 4 100 173 ++4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 ++4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 4 100 173 1 24 42 ++ ++2 50 86 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 ++3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 ++3 101 174 40 129 186 154 201 241 154 201 241 154 201 241 154 201 241 154 201 241 154 201 241 ++77 152 208 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 ++3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 ++3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 ++3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 5 99 172 111 178 227 ++154 201 241 154 201 241 154 201 241 154 201 241 154 201 241 154 201 241 3 101 174 3 101 174 ++3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 ++3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 3 101 174 0 26 44 ++ ++2 50 86 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 ++3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 ++3 102 175 40 129 186 151 200 240 151 200 240 151 200 240 151 200 240 151 200 240 151 200 240 ++62 142 198 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 ++3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 ++3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 ++3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 107 172 224 ++151 200 240 151 200 240 151 200 240 151 200 240 151 200 240 151 200 240 3 102 175 3 102 175 ++3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 ++3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 3 102 175 0 26 44 ++ ++2 50 86 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 ++2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 ++1 104 177 40 129 186 148 198 240 148 198 240 148 198 240 148 198 240 148 198 240 148 198 240 ++40 129 186 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 ++2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 ++2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 ++2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 77 152 208 ++148 198 240 148 198 240 148 198 240 148 198 240 148 198 240 148 198 240 2 103 176 2 103 176 ++2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 ++2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 2 103 176 0 26 44 ++ ++2 50 86 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 ++1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 ++1 104 177 40 129 186 145 196 239 145 197 239 145 197 239 145 197 239 145 197 239 145 197 239 ++51 141 199 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 ++1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 ++1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 ++1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 100 169 221 ++145 196 239 145 197 239 145 197 239 145 197 239 145 197 239 145 197 239 1 104 177 1 104 177 ++1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 ++1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 1 104 177 0 26 44 ++ ++2 50 86 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 ++0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 ++1 106 180 27 129 189 145 196 239 140 193 237 140 193 237 140 193 237 140 193 237 140 193 237 ++77 152 208 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 ++0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 ++0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 ++0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 107 172 224 ++145 196 239 140 193 237 140 193 237 140 193 237 140 193 237 140 193 237 0 105 179 0 105 179 ++0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 ++0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 105 179 0 26 44 ++ ++4 57 93 0 105 179 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 ++1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 ++1 106 180 28 119 185 140 193 237 140 193 237 140 193 237 140 193 237 140 193 237 140 193 237 ++83 162 217 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 ++1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 ++1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 ++1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 122 182 230 ++140 193 237 140 193 237 140 193 237 140 193 237 140 193 237 132 189 234 1 106 180 1 106 180 ++1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 ++1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 1 106 180 0 26 44 ++ ++4 57 93 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 ++2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 ++2 108 181 2 108 181 137 192 236 137 192 236 137 192 236 137 192 236 137 192 236 137 192 236 ++111 178 227 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 ++2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 ++2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 ++2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 8 115 186 137 192 236 ++137 192 236 137 192 236 137 192 236 137 192 236 137 192 236 100 169 221 2 108 181 2 108 181 ++2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 ++2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 2 108 181 0 26 44 ++ ++4 57 93 2 108 181 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 ++4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 ++4 110 182 4 110 182 107 172 224 134 191 236 134 191 236 134 191 236 134 191 236 134 191 236 ++132 189 234 17 119 189 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 ++4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 ++4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 ++4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 51 141 199 134 191 236 ++134 191 236 134 191 236 134 191 236 134 191 236 134 191 236 77 152 208 4 110 182 4 110 182 ++4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 ++4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 4 110 182 0 26 44 ++ ++4 57 93 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 ++5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 ++5 112 184 5 112 184 83 162 217 130 189 234 130 189 234 130 189 234 130 189 234 130 189 234 ++127 187 234 65 151 210 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 ++5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 ++5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 ++5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 92 162 218 130 189 234 ++130 189 234 130 189 234 130 189 234 130 189 234 130 189 235 51 141 199 5 112 184 5 112 184 ++5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 ++5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 5 112 184 6 113 185 0 26 44 ++ ++4 57 93 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 ++6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 ++6 113 185 6 113 185 42 139 203 127 187 234 127 187 234 127 187 234 127 187 234 127 187 234 ++127 187 234 111 178 227 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 ++6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 ++6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 ++6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 19 124 193 127 187 234 127 187 234 ++127 187 234 127 187 234 127 187 234 127 187 234 127 187 234 17 119 189 6 113 185 6 113 185 ++6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 ++6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 6 113 185 3 30 48 ++ ++4 57 93 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 ++8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 ++8 115 186 8 115 186 17 119 189 117 182 230 124 186 233 124 186 233 124 186 233 124 186 233 ++124 186 233 124 186 233 51 141 199 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 ++8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 ++8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 ++8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 79 161 217 124 186 233 124 186 233 ++124 186 233 124 186 233 124 186 233 124 186 233 95 168 221 8 115 186 8 115 186 8 115 186 ++8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 ++8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 8 115 186 3 30 48 ++ ++4 57 93 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 ++9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 ++9 117 188 9 117 188 9 117 188 79 161 217 121 184 232 121 184 232 121 184 232 121 184 232 ++121 184 232 121 184 232 106 176 228 17 119 189 9 117 188 9 117 188 9 117 188 9 117 188 ++9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 ++9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 ++9 117 188 9 117 188 9 117 188 9 117 188 27 133 194 122 182 230 121 184 232 121 184 232 ++121 184 232 121 184 232 121 184 232 121 184 232 51 141 199 9 117 188 9 117 188 9 117 188 ++9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 ++9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 9 117 188 3 30 48 ++ ++4 57 93 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 ++11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 ++11 119 189 11 119 189 11 119 189 27 133 194 117 182 230 117 182 230 117 182 230 117 182 230 ++117 182 230 117 182 230 117 182 230 79 161 217 11 119 189 11 119 189 11 119 189 11 119 189 ++11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 ++11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 ++11 119 189 11 119 189 11 119 189 17 119 189 100 172 225 117 182 230 117 182 230 117 182 230 ++117 182 230 117 182 230 117 182 230 111 178 227 11 119 189 11 119 189 11 119 189 11 119 189 ++11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 ++11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 11 119 189 3 30 48 ++ ++4 57 93 13 122 191 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 ++12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 ++12 121 190 12 121 190 12 121 190 13 122 191 88 166 221 115 181 230 115 181 230 115 181 230 ++115 181 230 115 181 230 115 181 230 115 181 230 51 141 199 13 122 191 12 121 190 12 121 190 ++12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 ++12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 ++12 121 190 12 121 190 12 121 190 79 161 217 115 181 230 115 181 230 115 181 230 115 181 230 ++115 181 230 115 181 230 115 181 230 65 151 210 12 121 190 12 121 190 12 121 190 12 121 190 ++12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 ++12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 12 121 190 3 30 48 ++ ++4 57 93 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 ++13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 ++13 122 191 13 122 191 13 122 191 13 122 191 27 133 194 112 180 229 112 180 229 112 180 229 ++112 180 229 112 180 229 112 180 229 112 180 229 112 180 229 51 141 199 13 122 191 13 122 191 ++13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 ++13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 ++13 122 191 12 121 190 79 161 217 112 180 229 112 180 229 112 180 229 112 180 229 112 180 229 ++112 180 229 112 180 229 100 172 225 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 ++13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 ++13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 13 122 191 3 30 48 ++ ++12 68 101 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 ++15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 ++15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 65 151 210 109 178 229 109 178 229 ++109 178 229 109 178 229 109 178 229 109 178 229 109 178 229 109 178 229 65 151 210 15 124 193 ++15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 ++15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 ++17 128 195 79 161 217 109 178 229 109 178 229 109 178 229 109 178 229 109 178 229 109 178 229 ++109 178 229 109 178 229 42 139 203 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 ++15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 ++15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 15 124 193 3 30 48 ++ ++4 57 93 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 ++16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 ++16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 89 168 223 106 176 228 ++106 176 228 106 176 228 106 176 228 106 176 228 106 176 228 106 176 228 106 176 228 81 164 221 ++27 133 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 ++16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 42 139 203 ++94 170 224 106 176 228 106 176 228 106 176 228 106 176 228 106 176 228 106 176 228 106 176 228 ++106 176 228 65 151 210 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 ++16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 ++16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 16 126 194 3 30 48 ++ ++12 68 101 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 ++17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 ++17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 28 137 198 97 172 225 ++103 175 227 103 175 227 103 175 227 103 175 227 103 175 227 103 175 227 103 175 227 103 175 227 ++103 175 227 65 151 210 28 137 198 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 ++17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 42 139 203 79 161 217 103 175 227 ++103 175 227 103 175 227 103 175 227 103 175 227 103 175 227 103 175 227 103 175 227 103 175 227 ++88 166 221 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 ++17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 ++17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 17 128 195 3 30 48 ++ ++12 68 101 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 ++19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 ++19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 31 139 202 ++95 170 224 100 173 226 100 173 226 100 173 226 100 173 226 100 173 226 100 173 226 100 173 226 ++100 173 226 100 173 226 100 173 226 81 164 221 65 151 210 42 139 203 42 139 203 19 130 197 ++22 132 197 42 139 203 42 139 203 65 151 210 89 168 223 100 173 226 100 173 226 100 173 226 ++100 173 226 100 173 226 100 173 226 100 173 226 100 173 226 100 173 226 100 173 226 84 165 222 ++22 132 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 ++19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 ++19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 19 130 197 20 131 198 3 30 48 ++ ++12 68 101 19 130 197 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 ++20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 ++20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 ++31 139 202 93 169 223 97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 ++97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 ++97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 ++97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 97 172 225 81 164 221 23 135 201 ++20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 ++20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 ++20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 20 131 198 3 30 48 ++ ++12 68 101 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 ++21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 ++21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 ++23 135 201 31 139 202 89 168 223 94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 ++94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 ++94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 ++94 170 224 94 170 224 94 170 224 94 170 224 94 170 224 81 164 221 24 137 202 21 133 199 ++21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 ++21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 ++21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 21 133 199 23 135 201 3 30 48 ++ ++12 68 101 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 ++23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 ++23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 ++22 130 192 21 125 186 28 122 176 77 152 208 89 168 223 90 169 224 90 169 224 90 169 224 ++90 169 224 90 169 224 90 169 224 90 169 224 90 169 224 90 169 224 90 169 224 90 169 224 ++90 169 224 90 169 224 90 169 224 90 169 224 90 169 224 90 169 224 90 169 224 90 169 224 ++90 169 224 90 169 224 90 169 224 90 169 224 62 142 198 17 118 175 21 125 186 22 132 197 ++23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 ++23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 ++23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 23 135 201 3 30 48 ++ ++12 68 101 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 ++24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 ++24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 22 130 192 17 118 175 21 111 162 ++21 111 162 21 111 162 21 111 162 21 111 162 40 129 186 83 162 217 87 167 223 87 167 223 ++87 167 223 87 167 223 87 167 223 87 167 223 87 167 223 87 167 223 87 167 223 87 167 223 ++87 167 223 87 167 223 87 167 223 87 167 223 87 167 223 87 167 223 87 167 223 87 167 223 ++87 167 223 87 167 223 77 152 208 28 122 176 21 111 162 21 111 162 21 111 162 21 111 162 ++22 114 165 17 118 175 22 132 197 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 ++24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 ++24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 24 137 202 26 139 203 3 30 48 ++ ++12 68 101 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 ++26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 ++26 139 203 26 139 203 26 139 203 26 139 203 28 122 176 21 111 162 21 111 162 21 111 162 ++21 111 162 21 111 162 21 111 162 21 111 162 21 111 162 24 115 166 51 141 199 79 161 217 ++84 166 222 84 166 222 84 166 222 84 166 222 84 166 222 84 166 222 84 166 222 84 166 222 ++84 166 222 84 166 222 84 166 222 84 166 222 84 166 222 84 166 222 84 166 222 84 166 222 ++79 161 217 40 129 186 22 112 163 21 111 162 21 111 162 21 111 162 21 111 162 21 111 162 ++21 111 162 22 112 163 21 111 162 22 130 192 26 139 203 26 139 203 26 139 203 26 139 203 ++26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 ++26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 26 139 203 3 30 48 ++ ++9 48 78 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 ++27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 ++27 140 204 27 140 204 27 140 204 27 140 204 17 118 175 22 112 163 22 112 163 22 112 163 ++22 112 163 22 112 163 22 112 163 22 112 163 22 112 163 22 112 163 22 112 163 21 111 162 ++40 129 186 62 142 198 79 161 217 81 164 221 81 164 221 81 164 221 81 164 221 81 164 221 ++81 164 221 81 164 221 81 164 221 81 164 221 81 164 221 79 161 217 62 142 198 28 122 176 ++22 112 163 22 112 163 22 112 163 22 112 163 22 112 163 22 112 163 22 112 163 22 112 163 ++22 112 163 22 112 163 22 112 163 21 125 186 27 140 204 27 140 204 27 140 204 27 140 204 ++27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 ++27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 27 140 204 4 18 26 ++ ++4 18 26 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 ++28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 ++28 142 206 28 142 206 28 142 206 28 142 206 28 137 198 28 122 176 22 114 165 22 114 165 ++22 114 165 22 114 165 22 114 165 22 114 165 22 114 165 22 114 165 22 114 165 22 114 165 ++22 114 165 22 114 165 22 114 165 28 122 176 40 129 186 51 141 199 51 141 199 51 141 199 ++51 141 199 51 141 199 51 141 199 28 122 176 28 122 176 22 112 163 22 114 165 22 114 165 ++22 114 165 22 114 165 22 114 165 22 114 165 22 114 165 22 114 165 22 114 165 22 114 165 ++22 114 165 22 114 165 28 122 176 27 140 204 28 142 206 28 142 206 28 142 206 28 142 206 ++28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 ++28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 142 206 28 122 176 0 0 0 ++ ++0 0 0 19 91 130 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 ++30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 ++30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 28 140 203 27 129 189 ++28 122 176 25 117 166 24 115 166 24 115 166 24 115 166 24 115 166 24 115 166 24 115 166 ++24 115 166 24 115 166 24 115 166 24 115 166 24 115 166 22 112 163 24 115 166 22 112 163 ++24 115 166 22 112 163 24 115 166 25 117 166 24 115 166 24 115 166 24 115 166 24 115 166 ++24 115 166 24 115 166 24 115 166 24 115 166 24 115 166 22 114 165 28 122 176 28 122 176 ++27 133 194 29 142 204 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 ++30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 ++30 144 207 30 144 207 30 144 207 30 144 207 30 144 207 31 146 208 9 48 78 0 0 0 ++ ++0 0 0 4 18 26 28 137 198 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 ++31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 ++31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 ++31 146 208 32 148 210 30 144 206 28 137 198 27 133 194 27 129 189 27 129 189 28 122 176 ++28 122 176 28 122 176 25 117 166 25 117 166 25 117 166 25 117 166 25 117 166 25 117 166 ++25 117 166 25 117 166 25 117 166 25 117 166 25 117 166 25 117 166 28 122 176 28 122 176 ++28 122 176 27 129 189 27 129 189 28 137 198 28 137 198 31 146 208 31 146 208 31 146 208 ++31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 ++31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 ++31 146 208 31 146 208 31 146 208 31 146 208 31 146 208 25 117 166 0 0 0 0 0 0 ++ ++0 0 0 0 0 0 8 23 42 28 137 198 32 148 210 32 148 210 32 148 210 32 148 210 ++32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 ++32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 ++32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 ++32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 ++32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 ++32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 ++32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 ++32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 32 148 210 ++32 148 210 32 148 210 32 148 210 32 148 210 25 117 166 3 11 16 0 0 0 0 0 0 ++ ++0 0 0 0 0 0 0 0 0 4 18 26 19 91 130 34 149 211 34 149 211 34 149 211 ++34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 ++34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 ++34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 ++34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 ++34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 ++34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 ++34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 ++34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 34 149 211 ++34 149 211 34 149 211 31 139 202 18 76 106 3 11 16 0 0 0 0 0 0 0 0 0 ++ ++0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 18 26 9 48 78 18 76 106 ++18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 ++18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 ++18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 ++18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 ++18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 ++18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 ++18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 ++18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 18 76 106 ++18 76 106 11 38 58 3 11 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++ +diff -Nurp linux-2.6.37.3/drivers/video/logo/Makefile linux-2.6.37.3.mga/drivers/video/logo/Makefile +--- linux-2.6.37.3/drivers/video/logo/Makefile 2011-01-05 02:50:19.000000000 +0200 ++++ linux-2.6.37.3.mga/drivers/video/logo/Makefile 2011-03-08 21:51:35.728113700 +0200 +@@ -15,6 +15,7 @@ obj-$(CONFIG_LOGO_SUPERH_MONO) += logo_ + obj-$(CONFIG_LOGO_SUPERH_VGA16) += logo_superh_vga16.o + obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o + obj-$(CONFIG_LOGO_M32R_CLUT224) += logo_m32r_clut224.o ++obj-$(CONFIG_LOGO_MAGEIA_CLUT224) += logo_mageia_clut224.o + + obj-$(CONFIG_SPU_BASE) += logo_spe_clut224.o + +diff -Nurp linux-2.6.37.3/include/linux/linux_logo.h linux-2.6.37.3.mga/include/linux/linux_logo.h +--- linux-2.6.37.3/include/linux/linux_logo.h 2011-01-05 02:50:19.000000000 +0200 ++++ linux-2.6.37.3.mga/include/linux/linux_logo.h 2011-03-08 21:51:20.263024073 +0200 +@@ -47,6 +47,7 @@ extern const struct linux_logo logo_supe + extern const struct linux_logo logo_superh_clut224; + extern const struct linux_logo logo_m32r_clut224; + extern const struct linux_logo logo_spe_clut224; ++extern const struct linux_logo logo_mageia_clut224; + + extern const struct linux_logo *fb_find_logo(int depth); + #ifdef CONFIG_FB_LOGO_EXTRA diff --git a/kernel/kernel/files/patches/mageia/x86-boot-video-80x25-if-break.patch b/kernel/kernel/files/patches/mageia/x86-boot-video-80x25-if-break.patch new file mode 100644 index 00000000..e7e92f47 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/x86-boot-video-80x25-if-break.patch @@ -0,0 +1,24 @@ +Automatically switches textmode if the user selects a wrong one. + +Original author of the idea/first patch is unknown. + +Signed-off-by: Herton Ronaldo Krzesinski +Signed-off-by: Luiz Fernando N. Capitulino + +-- + arch/x86/boot/video.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/x86/boot/video.c ++++ b/arch/x86/boot/video.c +@@ -325,8 +325,8 @@ void set_video(void) + if (!set_mode(mode)) + break; + +- printf("Undefined video mode number: %x\n", mode); +- mode = ASK_VGA; ++ printf("Undefined video mode number: %x, jump to 80x25\n", mode); ++ mode = VIDEO_80x25; + } + boot_params.hdr.vid_mode = mode; + vesa_store_edid(); diff --git a/kernel/kernel/files/patches/mageia/x86-default_poweroff_up_machines.patch b/kernel/kernel/files/patches/mageia/x86-default_poweroff_up_machines.patch new file mode 100644 index 00000000..28ce1a0d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/x86-default_poweroff_up_machines.patch @@ -0,0 +1,58 @@ +From: Olaf Dabrunz +Subject: [apm] default to "power_off" when SMP kernel is used on single processo +r machines +Reference: SUSE221667 + +This patch turns on support for the APM power_off function by default when the +SMP kernel is used on single processor machines. + +It is a bit ugly to use a separate variable to make sure the default value is +only used when needed and the power_off variable is not initialized twice. But +I did not find a better way to do this with the way the current initialization +system works. + +Signed-off-by: Olaf Dabrunz + + + arch/x86/kernel/apm_32.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/apm_32.c ++++ b/arch/x86/kernel/apm_32.c +@@ -388,6 +388,7 @@ static bool smp __read_mostly; + static int apm_disabled = -1; + #ifdef CONFIG_SMP + static bool power_off; ++static int power_off_set; + #else + static bool power_off = 1; + #endif +@@ -1843,6 +1844,14 @@ static int apm(void *unused) + } + } + ++#ifdef CONFIG_SMP ++ if (!power_off_set) { ++ power_off = (num_online_cpus() == 1); ++ /* remember not to initialize (with default value) again */ ++ power_off_set = 1; ++ } ++#endif ++ + /* Install our power off handler.. */ + if (power_off) + pm_power_off = apm_power_off; +@@ -1886,8 +1895,12 @@ static int __init apm_setup(char *str) + if (strncmp(str, "debug", 5) == 0) + debug = !invert; + if ((strncmp(str, "power-off", 9) == 0) || +- (strncmp(str, "power_off", 9) == 0)) ++ (strncmp(str, "power_off", 9) == 0)) { + power_off = !invert; ++#ifdef CONFIG_SMP ++ power_off_set = 1; ++#endif ++ } + if (strncmp(str, "smp", 3) == 0) { + smp = !invert; + idle_threshold = 100; diff --git a/kernel/kernel/files/patches/mageia/x86-efi-Store-upper-bits-of-command-line-buffer-addr.patch b/kernel/kernel/files/patches/mageia/x86-efi-Store-upper-bits-of-command-line-buffer-addr.patch new file mode 100644 index 00000000..8120a59d --- /dev/null +++ b/kernel/kernel/files/patches/mageia/x86-efi-Store-upper-bits-of-command-line-buffer-addr.patch @@ -0,0 +1,39 @@ +From 98b228f55014870092c15d7d168fecac69f2f12a Mon Sep 17 00:00:00 2001 +From: Roy Franz +Date: Wed, 15 Apr 2015 16:32:24 -0700 +Subject: [PATCH] x86/efi: Store upper bits of command line buffer address in + ext_cmd_line_ptr + +Until now, the EFI stub was only setting the 32 bit cmd_line_ptr in +the setup_header structure, so on 64 bit platforms this could be truncated. +This patch adds setting the upper bits of the buffer address in +ext_cmd_line_ptr. This case was likely never hit, as the allocation +for this buffer is done at the lowest available address. Only +x86_64 kernels have this problem, as the 1-1 mapping mandated +by EFI ensures that all memory is 32 bit addressable on 32 bit +platforms. The EFI stub does not support mixed mode, so the +32 bit kernel on 64 bit firmware case does not need to be handled. + +Signed-off-by: Roy Franz +Cc: +Signed-off-by: Matt Fleming +--- + arch/x86/boot/compressed/eboot.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c +index 92b9a5f..5999980 100644 +--- a/arch/x86/boot/compressed/eboot.c ++++ b/arch/x86/boot/compressed/eboot.c +@@ -1110,6 +1110,8 @@ struct boot_params *make_boot_params(struct efi_config *c) + if (!cmdline_ptr) + goto fail; + hdr->cmd_line_ptr = (unsigned long)cmdline_ptr; ++ /* Fill in upper bits of command line address, NOP on 32 bit */ ++ boot_params->ext_cmd_line_ptr = (u64)(unsigned long)cmdline_ptr >> 32; + + hdr->ramdisk_image = 0; + hdr->ramdisk_size = 0; +-- +2.3.2 + diff --git a/kernel/kernel/files/patches/mageia/x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch b/kernel/kernel/files/patches/mageia/x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch new file mode 100644 index 00000000..05d57ee2 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/x86-increase-default-minimum-vmalloc-area-by-64MB-to-192MB.patch @@ -0,0 +1,28 @@ +From 2db91ae7c0862bc83c1fe8b8bd14b8de3e2c02b8 Mon Sep 17 00:00:00 2001 +From: Anssi Hannula +Date: Sat, 30 Apr 2011 17:09:04 +0300 +Subject: [PATCH] x86: increase default minimum vmalloc area by 64MB to 192MB + +This fixes issues like https://bugs.mageia.org/show_bug.cgi?id=904. + +Signed-off-by: Anssi Hannula +--- + arch/x86/mm/pgtable_32.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c +index cac7184..5801fb7 100644 +--- a/arch/x86/mm/pgtable_32.c ++++ b/arch/x86/mm/pgtable_32.c +@@ -19,7 +19,7 @@ + #include + #include + +-unsigned int __VMALLOC_RESERVE = 128 << 20; ++unsigned int __VMALLOC_RESERVE = 192 << 20; + + /* + * Associate a virtual page frame with a given physical page frame +-- +1.7.3 + diff --git a/kernel/kernel/files/patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch b/kernel/kernel/files/patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch new file mode 100644 index 00000000..f9b4b1c7 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/x86-pci-toshiba-equium-a60-assign-busses.patch @@ -0,0 +1,29 @@ + +The Toshiba Equium A6 Laptop needs pci-assign-busses in order to detect +the Wireless card Netgear MA521 + +More info here: http://qa.mandriva.com/show_bug.cgi?id=18989 + +Signed-off-by: Thomas Backlund + +--- + arch/x86/pci/common.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/x86/pci/common.c ++++ b/arch/x86/pci/common.c +@@ -245,6 +245,14 @@ static const struct dmi_system_id __devi + DMI_MATCH(DMI_PRODUCT_NAME, "SX20S"), + }, + }, ++ { ++ .callback = assign_all_busses, ++ .ident = "Toshiba Equium A6 Laptop", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Equium A60"), ++ }, ++ }, + #endif /* __i386__ */ + { + .callback = set_bf_sort, diff --git a/kernel/kernel/files/patches/mageia/x86-spinlocks-Fix-regression-in-spinlock-contention-.patch b/kernel/kernel/files/patches/mageia/x86-spinlocks-Fix-regression-in-spinlock-contention-.patch new file mode 100644 index 00000000..fb41fb52 --- /dev/null +++ b/kernel/kernel/files/patches/mageia/x86-spinlocks-Fix-regression-in-spinlock-contention-.patch @@ -0,0 +1,46 @@ +From e8a4a2696fecb398b0288c43c0e0dbb91e265bb2 Mon Sep 17 00:00:00 2001 +From: Tahsin Erdogan +Date: Mon, 4 May 2015 21:15:31 -0700 +Subject: [PATCH] x86/spinlocks: Fix regression in spinlock contention + detection + +A spinlock is regarded as contended when there is at least one waiter. +Currently, the code that checks whether there are any waiters rely on +tail value being greater than head. However, this is not true if tail +reaches the max value and wraps back to zero, so arch_spin_is_contended() +incorrectly returns 0 (not contended) when tail is smaller than head. + +The original code (before regression) handled this case by casting the +(tail - head) to an unsigned value. This change simply restores that +behavior. + +Fixes: d6abfdb20223 ("x86/spinlocks/paravirt: Fix memory corruption on unlock") +Signed-off-by: Tahsin Erdogan +Cc: peterz@infradead.org +Cc: Waiman.Long@hp.com +Cc: borntraeger@de.ibm.com +Cc: oleg@redhat.com +Cc: raghavendra.kt@linux.vnet.ibm.com +Cc: stable@vger.kernel.org +Link: http://lkml.kernel.org/r/1430799331-20445-1-git-send-email-tahsin@google.com +Signed-off-by: Thomas Gleixner +--- + arch/x86/include/asm/spinlock.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h +index cf87de3..64b6117 100644 +--- a/arch/x86/include/asm/spinlock.h ++++ b/arch/x86/include/asm/spinlock.h +@@ -169,7 +169,7 @@ static inline int arch_spin_is_contended(arch_spinlock_t *lock) + struct __raw_tickets tmp = READ_ONCE(lock->tickets); + + tmp.head &= ~TICKET_SLOWPATH_FLAG; +- return (tmp.tail - tmp.head) > TICKET_LOCK_INC; ++ return (__ticket_t)(tmp.tail - tmp.head) > TICKET_LOCK_INC; + } + #define arch_spin_is_contended arch_spin_is_contended + +-- +2.3.2 + diff --git a/kernel/kernel/files/scripts/generate-module-list b/kernel/kernel/files/scripts/generate-module-list new file mode 100644 index 00000000..253cecd9 --- /dev/null +++ b/kernel/kernel/files/scripts/generate-module-list @@ -0,0 +1,39 @@ +#!/bin/bash + +# Generate modules.{networking, block, drm, modesetting} +# lists for further usage +# Adapted from Fedora +# +# Ozan Caglayan (C) 2010 + +collect_modules_list() +{ + sed -r -n -e "s/^([^ ]+) \\.?($2)\$/\\1/p" $TMP_MODUNDEF | + LC_ALL=C sort -u > modules.$1 +} + +MOD_DIR=$1 +TMP_MODNAMES=`mktemp` +TMP_MODUNDEF=`mktemp` + +find $MOD_DIR -name "*.ko" -type f > $TMP_MODNAMES + +cat $TMP_MODNAMES | xargs nm -upA | + sed -n 's,^.*/\([^/]*\.ko\): *U \(.*\)$,\1 \2,p' > $TMP_MODUNDEF + +# Start collecting module lists +# based on undefined symbols + +cd $MOD_DIR + +collect_modules_list networking \ + 'register_netdev|ieee80211_register_hw|usbnet_probe|phy_driver_register' +collect_modules_list block \ + 'ata_scsi_ioctl|scsi_add_host|scsi_add_host_with_dma|blk_init_queue|register_mtd_blktrans|scsi_esp_register|scsi_register_device_handler' +collect_modules_list drm \ + 'drm_open|drm_init' +collect_modules_list modesetting \ + 'drm_crtc_init' + +# Clean temporary files +rm -f $TMP_MODNAMES $TMP_MODUNDEF diff --git a/kernel/kernel/pspec.xml b/kernel/kernel/pspec.xml new file mode 100644 index 00000000..64664d58 --- /dev/null +++ b/kernel/kernel/pspec.xml @@ -0,0 +1,660 @@ + + + + + kernel + http://www.kernel.org + + Ertuğrul Erata + ertugrulerata@gmail.com + + GPLv2 + kernel + The Linux kernel (the core of the Linux operating system) for Pisi Linux + kernel contains the Linux kernel, the core of any Linux operating system. The kernel handles the basic functions of the operating system: memory allocation, process allocation, device input and output, etc. + https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.0.tar.gz + + configs/kernel-i686-config + configs/kernel-x86_64-config + scripts/generate-module-list + + + bc + pisi + cpio + unifdef + elfutils + diffutils + xmlto + asciidoc + pciutils-devel + numactl-devel + + + + patches/linux/patch-4.0.3.gz + + + + + + + + + kernel + + pisi + mkinitramfs + linux-firmware + grub2 + + + /boot + /lib/modules + /etc/kernel + + + System.Package + + + noDelta + + + + + kernel-module-headers + Kernel header files for external module building + kernel-module-headers includes the C header files and the necessary Kbuild files for being able to build external kernel modules. + + /usr/src/linux-headers* + /tmp-headers* + + + + + kernel-headers + system.devel + Header files for the Linux kernel for use by glibc + kernel-headers includes the C header files that specify the interface between the Linux kernel and userspace libraries and programs. The header files define structures and constants that are needed for building most standard programs and are also needed for rebuilding the glibc package. + + /usr/include + + + + + kernel-docs + Documentation and scripts for the Linux kernel + kernel-docs includes several documentation files and scripts for managing several debugging and other tasks. + + /usr/src/linux-headers*/Documentation + + + + + + 2015-05-14 + 4.0.3 + Version bump to 4.0.3 https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.0.3 + security + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-05-14 + 3.19.8 + Version bump to 3.19.8 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.19.8 + security + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-05-05 + 3.19.6 + Version bump to 3.19.6 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.19.6 + security + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-04-24 + 3.19.5 + Version bump to 3.19.5 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-04-16 + 3.19.4 + Version bump to 3.19.4 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-03-21 + 3.19.3 + Version bump to 3.19.3 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-03-08 + 3.19.1 + Version bump to 3.19.1 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-03-01 + 3.19.0 + Version bump to 3.19 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-01-26 + 3.18.3 + Version bump to 3.18.3 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.18.3 + security + + systemRestart + + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-01-08 + 3.18.1 + Version bump to 3.18.1 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.18.1 + security + + systemRestart + + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-11-28 + 3.17.4 + Version bump to 3.17.4 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.17.4 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-10-18 + 3.17.1 + Version bump to 3.17.1 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.17.1 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-09-19 + 3.16.3 + Version bump to 3.16.3 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.16.3 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-09-03 + 3.16.1 + Version bump to 3.16.1 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.16.1 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-07-24 + 3.15.6 + Version bump to 3.15.6 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.15.6 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-06-15 + 3.15.0 + Version bump to 3.15 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.15 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-27 + 3.14.4 + Version bump to 3.14.4 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.14.4 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-02 + 3.14.2 + Version bump to 3.14.2 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.14.2 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-04-15 + 3.13.10 + Version bump to 3.13.10 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.13.10 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-03-22 + 3.13.6 + Version bump to 3.13.6 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.13.6 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-03-01 + 3.12.13 + Version bump to 3.12.13 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.12.13 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-01-16 + 3.12.8 + Version bump to 3.12.8 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.12.8 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-12-17 + 3.12.5 + Add Maegia patch series and some cpu usage improvements. + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-12-12 + 3.12.5 + Version bump to 3.12.5 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.12.5 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-11-23 + 3.10.20 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.20 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-11-05 + 3.10.18 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.18 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-07 + 3.10.15 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.15 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-09-27 + 3.10.13 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.13 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-09-15 + 3.10.12 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.12 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-08-29 + 3.10.10 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.10 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-08-20 + 3.10.9 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.9 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-08-12 + 3.10.6 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.6 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-08-11 + 3.10.5 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.5 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-08-01 + 3.10.4 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.4 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-07-17 + 3.10.2 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.2 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-17 + 3.10.1 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.1 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-07-04 + 3.10.0 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-06-21 + 3.8.13 + Fix TSC calibration failure + security + + systemRestart + + Marcin Bojara + marcin@pisilinux.org + + + 2013-06-15 + 3.8.13 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.13 + security + + systemRestart + + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-04-18 + 3.8.8 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.8 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-03-31 + 3.8.5 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.5 + security + + systemRestart + + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-03-25 + 3.8.4 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.4 + security + + systemRestart + + Yoyo Fernández + admins@pisilinux.org + + + 2013-03-14 + 3.8.3 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.3 + security + + systemRestart + + Richard de Bruin + admins@pisilinux.org + + + 2013-03-06 + 3.8.2 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.2 + security + + systemRestart + + Erdinç Gültekin + admins@pisilinux.org + + + 2013-03-03 + 3.8.1 + update to current line + security + + systemRestart + + Erdinç Gültekin + admins@pisilinux.org + + + 2013-02-22 + 3.8.0 + update to final line with patch + security + + systemRestart + + Erdinç Gültekin + admins@pisilinux.org + + + 2013-02-17 + 3.8.0 + obsoletemans wifi fixing + security + + systemRestart + + Erdinç Gültekin + admins@pisilinux.org + + + 2013-02-12 + 3.8.0 + bump to -rc7 + security + + systemRestart + + Erdinç Gültekin + admins@pisilinux.org + + + 2013-02-06 + 3.7.6 + http://www.kernel.org/pub/linux/kernel/v3.0/ChangeLog-3.7.6 + security + + systemRestart + + Erdinç Gültekin + admins@pisilinux.org + + + 2013-01-28 + 3.7.5 + http://www.kernel.org/pub/linux/kernel/v3.0/ChangeLog-3.7.5 + security + + systemRestart + + Erdinç Gültekin + admins@pisilinux.org + + + 2013-01-18 + 3.7.4 + http://www.kernel.org/pub/linux/kernel/v3.0/ChangeLog-3.7.4 + security + + systemRestart + + Erdinç Gültekin + admins@pisilinux.org + + + 2013-01-15 + 3.7.2 + First release + security + + systemRestart + + Erdinç Gültekin + admins@pisilinux.org + + + diff --git a/kernel/kernel/translations.xml b/kernel/kernel/translations.xml new file mode 100644 index 00000000..86927932 --- /dev/null +++ b/kernel/kernel/translations.xml @@ -0,0 +1,41 @@ + + + + kernel + Pisi Linux için Linux çekirdeği + Noyau Linux Pisi Linux pour machine monoprocesseur. + El kernel de Linux (el núcleo del sistema operativo Linux) de Pisi Linux + + + + kernel-docs + Pisi Linux çekirdeği için betikler ve belgeler + kernel-docs, bazı betikler ve belgelendirme dosyaları içerir. + + + + kernel-headers + glibc ve diğer kullanıcı uzayı uygulamaları tarafından kullanılan başlık dosyaları + kernel-headers, Linux çekirdeği ve kullanıcı uzayı uygulamaları ve kütüphaneleri arasındaki arabirimi oluşturan başlık dosyalarını içerir. glibc'nin ve diğer standart uygulamaların derlenebilmesi için gerekli tanımlamalar bu başlık dosyaları tarafından sağlanmaktadır. + Fichiers d'entête du noyau Linux Pisi + Archivos de cabecera de Linux para uso con glibc + + + + kernel-module-headers + Pisi Linux çekirdeği için başlık dosyaları + kernel-module-headers, harici çekirdek modüllerinin derlenebilmesi için gereken başlık dosyaları ve Kbuild sistemini içeren pakettir. + + + + cpupowertools + CPU güç/frekans yönetim araçları + cpupowertools, işlemcinin çeşitli güç ve frekans parametrelerinin yönetilmesini sağlayan çeşitli araçları içeren bir pakettir. + + + + perf + Linux performans sayaçları sistemini efektif olarak kullanan bir performans analiz aracı + perf, Linux performans sayaçları sistemini kullanarak tüm sistemi, uygulamaları ve iş yüklerini analiz ederek ölçen bir araçtır. + + diff --git a/multimedia/component.xml b/multimedia/component.xml new file mode 100644 index 00000000..345f24ab --- /dev/null +++ b/multimedia/component.xml @@ -0,0 +1,3 @@ + + multimedia + diff --git a/multimedia/graphics/component.xml b/multimedia/graphics/component.xml new file mode 100644 index 00000000..4215a068 --- /dev/null +++ b/multimedia/graphics/component.xml @@ -0,0 +1,3 @@ + + multimedia.graphics + diff --git a/system/base/libpng/actions.py b/multimedia/graphics/libpng/actions.py similarity index 100% rename from system/base/libpng/actions.py rename to multimedia/graphics/libpng/actions.py diff --git a/system/base/libpng/files/libpng-1.6.10-apng.patch.gz b/multimedia/graphics/libpng/files/libpng-1.6.10-apng.patch.gz similarity index 100% rename from system/base/libpng/files/libpng-1.6.10-apng.patch.gz rename to multimedia/graphics/libpng/files/libpng-1.6.10-apng.patch.gz diff --git a/system/base/libpng/files/libpng-1.6.12-apng.patch.gz b/multimedia/graphics/libpng/files/libpng-1.6.12-apng.patch.gz similarity index 100% rename from system/base/libpng/files/libpng-1.6.12-apng.patch.gz rename to multimedia/graphics/libpng/files/libpng-1.6.12-apng.patch.gz diff --git a/system/base/libpng/files/libpng-1.6.15-apng.patch.gz b/multimedia/graphics/libpng/files/libpng-1.6.15-apng.patch.gz similarity index 100% rename from system/base/libpng/files/libpng-1.6.15-apng.patch.gz rename to multimedia/graphics/libpng/files/libpng-1.6.15-apng.patch.gz diff --git a/system/base/libpng/files/libpng-multilib.patch b/multimedia/graphics/libpng/files/libpng-multilib.patch similarity index 100% rename from system/base/libpng/files/libpng-multilib.patch rename to multimedia/graphics/libpng/files/libpng-multilib.patch diff --git a/system/base/libpng/pspec.xml b/multimedia/graphics/libpng/pspec.xml similarity index 91% rename from system/base/libpng/pspec.xml rename to multimedia/graphics/libpng/pspec.xml index 64772177..fda01eb8 100644 --- a/system/base/libpng/pspec.xml +++ b/multimedia/graphics/libpng/pspec.xml @@ -12,7 +12,7 @@ library Portable Network Graphics library The Portable Network Graphics (PNG) format was designed to replace the older and simpler GIF format and, to some extent, the much more complex TIFF format. Project's main aim is to concentrate on two major uses: the World Wide Web (WWW) and image-editing. - mirrors://sourceforge/libpng/libpng-1.6.15.tar.xz + mirrors://sourceforge/libpng/libpng-1.6.16.tar.xz zlib @@ -35,7 +35,6 @@ libpng-devel - system.devel Development files for libpng libpng @@ -67,6 +66,13 @@ + + 2015-04-04 + 1.6.16 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-12-05 1.6.15 @@ -117,4 +123,4 @@ admins@pisilinux.org - \ No newline at end of file + diff --git a/system/base/libpng/translations.xml b/multimedia/graphics/libpng/translations.xml similarity index 100% rename from system/base/libpng/translations.xml rename to multimedia/graphics/libpng/translations.xml diff --git a/pisi-index.xml b/pisi-index.xml index 28307681..dc88f38c 100644 --- a/pisi-index.xml +++ b/pisi-index.xml @@ -9,6 +9,9 @@ Core PisiLinux + xorg-video-modesetting + glamor-egl + glamor-egl-devel kdeadmin kdenetwork kdenetwork-devel @@ -364,1158 +367,163 @@ libusbx-devel libusbx-32bit labltk + udev + libudev + libgudev1 + libudev-devel + libgudev1-devel + libudev-32bit + libgudev1-32bit + mdbtools-gui + module-nvidia96 + xorg-video-nvidia96 + module-nvidia173 + xorg-video-nvidia173 + libfm + libfm-devel + lxappearance + lxappearance-devel + lxappearance-obconf + lxde-common + lxde-menu-cache + lxde-menu-cache-devel + lxinput + lxmenu-data + lxpanel + lxpanel-devel + lxpolkit + lxrandr + lxsession + lxtask + lxterminal + pcmanfm + pcmanfm-devel + gpicview + lxlauncher + screengrab - icecream - http://en.opensuse.org/Icecream + libpng + http://www.libpng.org/ PisiLinux Community admins@pisilinux.org - GPLv2 - service - system.devel - Distributed C(++) compiling tool - Dağıtık C(++) derleme aracı - Herramienta de compilación C(++) distribuida - Icecream est un programme de compilation de code C/C++ distribuée sur plusieurs machines basé sur le code et les idées directrices de distcc. - Icecream is a program for distributed compiling of C/C++ code across several machines based on ideas and code by distcc. - Icecream; C/C++ kaynak kodunun, birden fazla makinede dağıtık olarak derlenmesi fikrine dayanan, "distcc" kodu temelinde yazılmış bir uygulamadır. - Icecream es un programa para compilación de código C/C++ distribuida en varios servidores, basado en ideas y código de distcc. - ftp://ftp.suse.com/pub/projects/icecream/icecc-1.0.1.tar.bz2 + as-is + library + multimedia.graphics + Portable Network Graphics library + PNG kütüphanesi + Le format de Graphique Réseau Portable (Portable Network Graphics - PNG) a été conçu pour remplacer le format GIF plus simple et vieillissant ainsi que, d'une certaine manière, le format TIFF beaucoup plus complexe. L'objectif principal du projet est de se concentrer sur deux aspects majeurs : La toile mondiale (World Wide Web - WWW) et l'édition d'image. + The Portable Network Graphics (PNG) format was designed to replace the older and simpler GIF format and, to some extent, the much more complex TIFF format. Project's main aim is to concentrate on two major uses: the World Wide Web (WWW) and image-editing. + Taşınabilir Ağ Grafikleri (PNG) formatı eski ve daha basit GIF formatının yerine geçmek ve daha karmaşık yapıdaki TIFF formatını biraz daha genişletmek için tasarlanmıştır. Projenin ana hedefi iki önemli parça üzerine konsantre olmaktır: World Wide Web (WWW) ve resim düzenleme. + mirrors://sourceforge/libpng/libpng-1.6.16.tar.xz - librsync-devel + zlib - system/devel/icecream/pspec.xml - - - icecream - - librsync - libgcc - libcap-ng - - - /opt/icecream/sbin/iceccd - /opt/icecream/bin/icecc - /usr/libexec/icecc - /opt/icecream/lib - /opt/icecream/bin - /opt/icecream/include/ - /usr/share/doc - /usr/share/icecc - /usr/share/man - /lib/systemd/system/icecream-daemon.service - - - System.Service - - - icecream-daemon.service - - - - icecream-scheduler - Icecream scheduler which should only run on the master icecream node - - icecream - libgcc - - - /opt/icecream/sbin/icecc-scheduler - /lib/systemd/system/icecream-scheduler.service - - - System.Service - - - icecream-scheduler.service - - - - - 2014-05-11 - 1.0.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-22 - 1.0.1 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-24 - 1.0.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-18 - 0.9.98.3 - v.bump - PisiLinux Community - admins@pisilinux.org - - - 2012-10-09 - 0.9.7 - First release - Erdem Artan - admins@pisilinux.org - - - - - - libseccomp - http://sourceforge.net/projects/libseccomp/ - - Aydın Demirel - aydin.demirel@pisilinux.org - - LGPLv2.1 - app:library - system.devel - Enhanced seccomp library - Gelişmiş seccomp kütüphanesi - High level interface to the Linux Kernel's seccomp filter. - Linux Kernel'in seccomp süzgecine yüksek seviyeli arayüz - http://downloads.sourceforge.net/project/libseccomp/libseccomp-2.1.1/libseccomp-2.1.1.tar.gz - - glibc - - system/devel/libseccomp/pspec.xml - - - libseccomp - - /usr/bin - /usr/share/man - /usr/lib/* - - - - libseccomp-devel - - /usr/include - - - - - 2014-06-27 - 2.1.1 - First release - Aydın Demirel - aydin.demirel@pisilinux.org - - - - - - unifdef - http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/unifdef/ - - PisiLinux Community - admins@pisilinux.org - - BSD - app:console - system.devel - The unifdef utility selectively processes conditional cpp(1) directives - L'utilitaire unifdef traite sélectivement les directives conditionnelles cpp(1). Il supprime d'un fichier les directives ainsi que le texte additionnel qu'elles indiquent comme à supprimer tout en laissant le reste du fichier intact. - The unifdef utility selectively processes conditional cpp(1) directives. It removes from a file both the directives and any additional text that they specify should be removed, while otherwise leaving the file alone. - http://dotat.at/prog/unifdef/unifdef-2.10.tar.gz - system/devel/unifdef/pspec.xml - - - unifdef - - /usr/bin - /usr/share/man - /usr/share/doc/unifdef - - - - - 2014-05-11 - 2.10 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 2.10 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-07-24 - 2.9 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-09-17 - 2.6 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - chrpath - http://freshmeat.net/projects/chrpath/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.devel - Change the dynamic library load path (rpath) of binaries - Dinamik kitaplık yükleme yolunu (rpath) değiştirme aracı - chrpath allows you to modify the dynamic library load path (rpath and runpath) of compiled programs and libraries. - chrpath ile derlenmiş kitaplıkların ve programların dinamik kitaplık yükleme yolunu (rpath ve runpath) değiştirebilirsiniz. - http://source.pisilinux.org/1.0/chrpath-0.16.tar.gz - docdir.patch + libpng-1.6.15-apng.patch.gz + libpng-multilib.patch - system/devel/chrpath/pspec.xml + multimedia/graphics/libpng/pspec.xml - chrpath - - /usr/bin - /usr/share/doc - /usr/share/man - - - - - 2014-05-11 - 0.16 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 0.16 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-28 - 0.13 - Clean chrpath - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-07-14 - 0.13 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - quilt - http://savannah.nongnu.org/projects/quilt - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.devel - Scripts for working with series of patches - Yama serileriyle çalışmak için betik araçları - quilt allow one to manage a series of patches by keeping track of the changes each patch makes. - quilt, yamaları yığın yapısına göre düzenleyen, kolayca yama uygulamayı ve kaldırmayı sağlayan bir yama yönetim uygulamasıdır. - http://mirror.rackdc.com/savannah/quilt/quilt-0.61.tar.gz - - gawk - gettext - util-linux - - system/devel/quilt/pspec.xml - - - quilt + libpng - diffstat - - - /etc - /usr/bin - /usr/lib - /usr/share/locale - /usr/share/man - /usr/share/doc - /usr/share/quilt - - - - - 2014-05-11 - 0.61 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 0.61 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-31 - 0.60 - Clean quilt. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-05-30 - 0.60 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - autogen - http://www.gnu.org/software/autogen - - PisiLinux Community - admins@pisilinux.org - - GPLv3 - app:console - system.devel - The automated text and program generation tool - Otomatik metin ve program üretme aracı - Herramienta para simplificar creación y mantenimiento de programas que contienen muchos textos repetitivos - autogen is a tool designed to simplify the creation and maintenance of programs that contain large amounts of repetitious text. - autogen büyük miktarda tekrarlı metin içeren uygulamaların otomatik üretilmesini sağlayan bir araçtır. - ftp://ftp.gnu.org/gnu/autogen/rel5.18.4/autogen-5.18.4.tar.xz - - guile-devel - libxml2-devel - - system/devel/autogen/pspec.xml - - - autogen - - guile - libxml2 + zlib /usr/lib /usr/share/doc - /usr/share/man - /usr/bin - /usr/share/info - /usr/share/autogen - autogen-devel - Development files for autogen - autogen için geliştirme dosyaları + libpng-devel + Development files for libpng + libpng için geliştirme dosyaları - autogen + libpng + /usr/bin /usr/include - /usr/share/aclocal /usr/lib/pkgconfig - /usr/share/man/man3 - /usr/bin/autoopts-config - /usr/share/man/man1/autoopts-config.1 - - - - - 2014-11-23 - 5.18.4 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-24 - 5.18 - Rebuild for gcc. - PisiLinux Community - admins@pisilinux.org - - - 2014-05-11 - 5.18 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-27 - 5.18 - Clean autogen. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-22 - 5.18 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-17 - 5.17.1 - New release - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-10-04 - 5.16.2 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - flex - http://flex.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - FLEX - app:console - system.devel - GNU lexical analyser generator - GNU sözcüksel analiz üreteci - Flex est un outil de génération d'analyseur (scanner). Un analyseur (également appelé tokenizer en anglais) est un programme qui repère les motifs lexicaux (ou lexème) dans du texte. - Flex is a tool for generating scanners. A scanner, sometimes called a tokenizer, is a program which recognizes lexical patterns in text - Flex, metin içindeki sözcüksel kalıpları tanıyan, analiz aracı üretecidir. - mirrors://sourceforge/flex/flex-2.5.39.tar.gz - - patch - - - flex-2.5.37-notex.patch - - system/devel/flex/pspec.xml - - - flex - - /usr/bin - /usr/lib - /usr/share/doc + /usr/lib32/pkgconfig /usr/share/man - /usr/share/info - /usr/include - /usr/share/locale + + + + libpng-32bit + 32-bit shared libraries for libpng + libpng için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + zlib-32bit + + + libpng + zlib-32bit + + + /usr/lib32 + + 2015-04-04 + 1.6.16 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-12-05 + 1.6.15 + Version bump. + Osman Erkan + osman.erkan@pisilinux.org + - 2014-06-02 - 2.5.39 + 2014-07-07 + 1.6.12 Version bump. Vedat Demir vedat@pisilinux.org 2014-05-11 - 2.5.38 + 1.6.10 Release bump. Marcin Bojara marcin@pisilinux.org 2014-03-29 - 2.5.38 + 1.6.10 Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-28 - 2.5.37 - Clean flex. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-18 - 2.5.37 - v.bump PisiLinux Community admins@pisilinux.org - - 2012-07-14 - 2.5.35 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - diffstat - http://invisible-island.net/diffstat/ - - PisiLinux Community - admins@pisilinux.org - - as-is - app:console - system.devel - Diffstat reads the output of the diff command and displays a histogram of the insertions, deletions, and modifications in each file - Diffstat reads the output of the diff command and displays a histogram of the insertions, deletions, and modifications in each file.Diffstat is commonly used to provide a summary of the changes in large, complex patch files. - Diffstat lee la salida del comando diff y muestra un histograma de inserciones, borrados y modificaciones en cada archivo. Se usa comúnmente para mostrar un resumen de las modificaciones en archivos lagos y complejos. - ftp://invisible-island.net/diffstat/diffstat-1.59.tgz - - xz - gzip - bzip2 - ncompress - - system/devel/diffstat/pspec.xml - - - diffstat - - /usr/bin - /usr/share/doc - /usr/share/man - - - - - 2014-11-23 - 1.59 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 1.58 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 1.58 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-22 - 1.57 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - 2013-02-18 - 1.56 - version bump - PisiLinux Community - admins@pisilinux.org - - - 2012-08-15 - 1.55 - First release - Ramazan Utku - admins@pisilinux.org - - - - - - libmpc - http://www.multiprecision.org/ - - Serdar Soytetir - kaptan@pisilinux.org - - LGPLv2.1 - library - system.devel - High precision and correct rounding library - Yüksek hassasiyet ve yuvarlama kitaplığı - libmpc is a library for arithmetic of complex numbers with arbitrarily high precision and correct rounding. - libmpc aritmetik kompleks sayılarla yüksek hassasiyette ve doğru yuvarlama ile işlem yapılmasını sağlayan bir kitaplıktır. - ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.2.tar.gz - - gmp-devel - mpfr-devel - - system/devel/libmpc/pspec.xml - - - libmpc - - gmp - mpfr - - - /usr/lib - /usr/share/doc/libmpc - /usr/share/info - - - - libmpc-devel - Development files for libmpc - libmpc için geliştirme dosyaları - - libmpc - - - /usr/include - - - - - 2014-09-06 - 1.0.2 - Rebuild with new mpfr for new gcc. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 1.0.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-30 - 1.0.2 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-27 - 1.0.1 - Clean libpmc. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-09-09 - 1.0.1 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - gobject-introspection - http://live.gnome.org/GObjectIntrospection - - Pisi Linux Admins - admins@pisilinux.org - - LGPLv2+ - GPLv2+ - library - app:console - system.devel - Introspection system for GObject-based libraries - gobject-introspection can scan C header and source files in order to generate introspection typelib files. It also provides an API to examine typelib files, useful for creating language bindings among other things. - mirrors://gnome/gobject-introspection/1.40/gobject-introspection-1.40.0.tar.xz - - cairo-devel - python-devel - python-mako - - system/devel/gobject-introspection/pspec.xml - - - gobject-introspection - - libffi - glib2 - - - /usr/lib/lib*.so* - /usr/lib/girepository-1.0/*.typelib - /usr/share/locale - /usr/share/doc - - - - gobject-introspection-devel - Development files for gobject-introspection - - gobject-introspection - - - /usr/include - /usr/lib/gobject-introspection - /usr/bin/g-ir-* - /usr/lib/pkgconfig - /usr/share/gir-1.0 - /usr/share/aclocal - /usr/share/gobject-introspection-1.0 - /usr/share/man - - - - - 2014-05-11 - 1.40.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-14 - 1.40.0 + 2013-10-30 + 1.5.17 Version bump. Yusuf Aydemir yusuf.aydemir@pisilinux.org - - 2014-04-06 - 1.38.0 - Rebuild - Varol Maksutoğlu - waroi@pisilinux.org - - - 2014-02-01 - 1.38.0 - Rebuild Unused - Varol Maksutoğlu - waroi@pisilinux.org - - - 2013-10.12 - 1.38.0 - V.Bump - PisiLinux Community - admins@pisilinux.org - - - 2013-07-24 - 1.37.4 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-04-07 - 1.36.0 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-24 - 1.35.8 - V.Bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-02-04 - 1.35.4 - New version bump to 1.35.4. - Idris Kalp - admins@pisilinux.org - - - 2012-12-31 - 1.34.2 - First release - Idris Kalp - yaralikurt15@hotmail.com - - - - - - xorg-proto - http://x.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.devel - Entêtes de protocole de X.Org. - X.Org Protocol Headers - X.Org Protokol Başlıkları - X.Org Protokoll Header - This package includes the protocol headers needed for X11 development. - Bu paket, X11 geliştirme için gerekli protokol başlıklarını içerir. - mirrors://xorg/individual/proto/bigreqsproto-1.1.2.tar.bz2 - mirrors://xorg/individual/proto/presentproto-1.0.tar.bz2 - mirrors://xorg/individual/proto/compositeproto-0.4.2.tar.bz2 - mirrors://xorg/individual/proto/damageproto-1.2.1.tar.bz2 - mirrors://xorg/individual/proto/dmxproto-2.3.1.tar.bz2 - mirrors://xorg/individual/proto/dri2proto-2.8.tar.bz2 - mirrors://xorg/individual/proto/dri3proto-1.0.tar.bz2 - mirrors://xorg/individual/proto/fixesproto-5.0.tar.bz2 - mirrors://xorg/individual/proto/fontsproto-2.1.3.tar.bz2 - mirrors://xorg/individual/proto/glproto-1.4.17.tar.bz2 - mirrors://xorg/individual/proto/inputproto-2.3.1.tar.bz2 - mirrors://xorg/individual/proto/kbproto-1.0.6.tar.bz2 - mirrors://xorg/individual/proto/printproto-1.0.5.tar.bz2 - mirrors://xorg/individual/proto/randrproto-1.4.0.tar.bz2 - mirrors://xorg/individual/proto/recordproto-1.14.2.tar.bz2 - mirrors://xorg/individual/proto/renderproto-0.11.1.tar.bz2 - mirrors://xorg/individual/proto/resourceproto-1.2.0.tar.bz2 - mirrors://xorg/individual/proto/scrnsaverproto-1.2.2.tar.bz2 - mirrors://xorg/individual/proto/videoproto-2.3.2.tar.bz2 - mirrors://xorg/individual/proto/xcmiscproto-1.2.2.tar.bz2 - mirrors://xorg/individual/proto/xextproto-7.3.0.tar.bz2 - mirrors://xorg/individual/proto/xf86bigfontproto-1.2.0.tar.bz2 - mirrors://xorg/individual/proto/xf86dgaproto-2.1.tar.bz2 - mirrors://xorg/individual/proto/xf86driproto-2.1.1.tar.bz2 - mirrors://xorg/individual/proto/xf86vidmodeproto-2.3.1.tar.bz2 - mirrors://xorg/individual/proto/xineramaproto-1.2.1.tar.bz2 - mirrors://xorg/individual/proto/xproto-7.0.27.tar.bz2 - mirrors://xorg/individual/proto/xproxymanagementprotocol-1.0.3.tar.bz2 - https://github.com/bbidulock/vncproto/releases/download/vncproto-1.1/vncproto-1.1.tar.bz2 - - util-macros - libXau-devel - - - docdir.patch - - system/devel/xorg-proto/pspec.xml - - - xorg-proto - - libXau-devel - - - /usr/include - /usr/lib/pkgconfig - /usr/share/doc - /usr/share/man/man7/Xprint.7 - - - - - 2015-01-27 - 7.6 - Update xproto - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-09-20 - 7.6 - Update vncproto, fix dependencies. - Marcin Bojara - marcin@pisilinux.org - - - 2014-08-31 - 7.6 - Update. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 7.6 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-15 - 7.6 - xproto fontsproto version bump - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-03-07 - 7.6 - add presentproto dri3proto - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-04-13 - 7.6 - Update: - xproto to version 7.0.24 - inputproto to version 2.3 (needed for xorg-server-0.14.0) - Marcin Bojara - marcin@pisilinux.org - - - 2012-10-15 - 7.6 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - libarchive - http://code.google.com/p/libarchive/ - - PisiLinux Community - admins@pisilinux.org - - BSD - library - system.devel - Library for reading and writing streaming archives - Birçok farklı akış arşiv formatını yaratan ve okuyan programlama kitaplığı - libarchive includes a library and command-line tools for reading and writing tar, cpio, zip, ISO, and other archive formats. - libarchive, tar, cpio, zip, ISO ve diğer arşiv biçimlerini okumak ve yazmak için bir kitaplık ve komut satırı araçları içerir. - http://www.libarchive.org/downloads/libarchive-3.1.2.tar.gz - - acl-devel - attr-devel - bzip2 - libxml2-devel - openssl-devel - xz-devel - lzo-devel - zlib-devel - - system/devel/libarchive/pspec.xml - - - libarchive - - lzo - nettle - xz - acl - zlib - attr - bzip2 - libxml2 - - - /usr/lib - /usr/share/man - /usr/share/doc/libarchive - - - - libarchive-devel - Development files for libarchive - libarchive için geliştirme dosyaları - - libarchive - - - /usr/include - /usr/lib/pkgconfig - /usr/share/man/man3 - - - - - 2014-05-11 - 3.1.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-01-28 - 3.1.2 - unused fix. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-08-28 - 3.1.2 - Clean libarchive. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-01 - 3.1.2 - Fix deps. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-18 - 3.1.2 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2012-08-19 - 3.0.4 - First release - Ramazan Utku - admins@pisilinux.org - - - - - - gmp - http://gmplib.org/ - - Serdar Soytetir - kaptan@pisilinux.org - - LGPLv3+ - library - system.devel - Arbitrary precision arithmetic library - İstenilen duyarlıkta çalışabilen aritmetik işlem kitaplığı - GMP est une librairie libre pour l'arithmétique à précision arbitraire, opérant sur : les entiers signés, les nombres rationnels et les nombres à virgule flottante. Il n'y a aucune limite pratique sur la précision des calculs exceptée celle impliquée par la mémoire présente sur la machine exécutant GMP. GMP est dotée d'un large panel de fonctions, dotées d'interfaces régulières. - GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers. There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on. GMP has a rich set of functions, and the functions have a regular interface. - GMP işaretli tamsayılar, rasyonel ve ondalık sayılar üzerinde istenilen kadar duyarlı aritmetik işlemler yapan bir kitaplıktır. Yüklü olduğu makinenin hafıza sınırı dışında herhangi bir duyarlılık limiti yoktur. Zengin fonksiyonları ve düzenli bir arabirimi vardır. - GMP es una librería libre para aritmética con precisión arbitraria, operando con signed integers, números racionales, y punto flotante. Practicamente no hay límite de precisión excepto los de la memoria disponible en el equipo donde se está ejecutando GMP. GMP tiene un amplio conjunto de funciones y las funciones tienen una interfaz regular. - mirrors://gnu/gmp/gmp-6.0.0a.tar.xz - system/devel/gmp/pspec.xml - - - gmp - - libgcc - - - /usr/lib - /usr/share/doc - /usr/share/info - - - - gmp-devel - Development files for gmp - gmp için geliştirme dosyaları - - gmp - - - /usr/include - /usr/lib/*.a - - - - gmp-32bit - 32-bit shared libraries for gmp - emul32 - emul32 - - gmp - - - /usr/lib32 - - - - - 2014-09-06 - 6.0.0 - Rebuild with new options, fix version number. - Clean up actions.py, remove unneeded lines, we have auto-emul32 :) - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 6.0.0a - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-01 - 6.0.0a - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-22 - 5.1.3 - Minor version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-27 - 5.1.2 - Clean gmp. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-23 - 5.1.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-16 - 5.1.1 + + 2013-01-14 + 1.5.14 New release - Serdar Soytetir - kaptan@pisilinux.org + PisiLinux Community + admins@pisilinux.org - - 2012-09-30 - 5.0.5 + + 2012-11-03 + 1.5.13 First release Erdem Artan admins@pisilinux.org @@ -1524,786 +532,1030 @@ - ppl - http://www.cs.unipr.it/ppl/ + kernel + http://www.kernel.org + + Ertuğrul Erata + ertugrulerata@gmail.com + + GPLv2 + kernel + kernel + Noyau Linux Pisi Linux pour machine monoprocesseur. + The Linux kernel (the core of the Linux operating system) for Pisi Linux + Pisi Linux için Linux çekirdeği + El kernel de Linux (el núcleo del sistema operativo Linux) de Pisi Linux + kernel contains the Linux kernel, the core of any Linux operating system. The kernel handles the basic functions of the operating system: memory allocation, process allocation, device input and output, etc. + https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.0.tar.gz + + configs/kernel-i686-config + configs/kernel-x86_64-config + scripts/generate-module-list + + + bc + pisi + cpio + unifdef + elfutils + diffutils + xmlto + asciidoc + pciutils-devel + numactl-devel + + + patches/linux/patch-4.0.3.gz + + kernel/kernel/pspec.xml + + + kernel + + noDelta + + + pisi + mkinitramfs + linux-firmware + grub2 + + + /boot + /lib/modules + /etc/kernel + + + System.Package + + + + kernel-module-headers + Kernel header files for external module building + Pisi Linux çekirdeği için başlık dosyaları + kernel-module-headers includes the C header files and the necessary Kbuild files for being able to build external kernel modules. + kernel-module-headers, harici çekirdek modüllerinin derlenebilmesi için gereken başlık dosyaları ve Kbuild sistemini içeren pakettir. + + /usr/src/linux-headers* + /tmp-headers* + + + + kernel-headers + Fichiers d'entête du noyau Linux Pisi + Header files for the Linux kernel for use by glibc + glibc ve diğer kullanıcı uzayı uygulamaları tarafından kullanılan başlık dosyaları + Archivos de cabecera de Linux para uso con glibc + kernel-headers includes the C header files that specify the interface between the Linux kernel and userspace libraries and programs. The header files define structures and constants that are needed for building most standard programs and are also needed for rebuilding the glibc package. + kernel-headers, Linux çekirdeği ve kullanıcı uzayı uygulamaları ve kütüphaneleri arasındaki arabirimi oluşturan başlık dosyalarını içerir. glibc'nin ve diğer standart uygulamaların derlenebilmesi için gerekli tanımlamalar bu başlık dosyaları tarafından sağlanmaktadır. + system.devel + + /usr/include + + + + kernel-docs + Documentation and scripts for the Linux kernel + Pisi Linux çekirdeği için betikler ve belgeler + kernel-docs includes several documentation files and scripts for managing several debugging and other tasks. + kernel-docs, bazı betikler ve belgelendirme dosyaları içerir. + + /usr/src/linux-headers*/Documentation + + + + + security + 2015-05-14 + 4.0.3 + Version bump to 4.0.3 https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.0.3 + Ertuğrul Erata + ertugrulerata@gmail.com + + + security + 2015-05-14 + 3.19.8 + Version bump to 3.19.8 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.19.8 + Ertuğrul Erata + ertugrulerata@gmail.com + + + security + 2015-05-05 + 3.19.6 + Version bump to 3.19.6 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.19.6 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-04-24 + 3.19.5 + Version bump to 3.19.5 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-04-16 + 3.19.4 + Version bump to 3.19.4 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-03-21 + 3.19.3 + Version bump to 3.19.3 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-03-08 + 3.19.1 + Version bump to 3.19.1 + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-03-01 + 3.19.0 + Version bump to 3.19 + Ertuğrul Erata + ertugrulerata@gmail.com + + + security + 2015-01-26 + 3.18.3 + Version bump to 3.18.3 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.18.3 + Ertuğrul Erata + ertugrulerata@gmail.com + + systemRestart + + + + security + 2015-01-08 + 3.18.1 + Version bump to 3.18.1 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.18.1 + Ertuğrul Erata + ertugrulerata@gmail.com + + systemRestart + + + + security + 2014-11-28 + 3.17.4 + Version bump to 3.17.4 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.17.4 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-10-18 + 3.17.1 + Version bump to 3.17.1 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.17.1 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-09-19 + 3.16.3 + Version bump to 3.16.3 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.16.3 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-09-03 + 3.16.1 + Version bump to 3.16.1 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.16.1 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-07-24 + 3.15.6 + Version bump to 3.15.6 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.15.6 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-06-15 + 3.15.0 + Version bump to 3.15 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.15 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-05-27 + 3.14.4 + Version bump to 3.14.4 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.14.4 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-05-02 + 3.14.2 + Version bump to 3.14.2 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.14.2 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-04-15 + 3.13.10 + Version bump to 3.13.10 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.13.10 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-03-22 + 3.13.6 + Version bump to 3.13.6 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.13.6 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-03-01 + 3.12.13 + Version bump to 3.12.13 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.12.13 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2014-01-16 + 3.12.8 + Version bump to 3.12.8 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.12.8 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2013-12-17 + 3.12.5 + Add Maegia patch series and some cpu usage improvements. + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2013-12-12 + 3.12.5 + Version bump to 3.12.5 https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.12.5 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2013-11-23 + 3.10.20 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.20 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2013-11-05 + 3.10.18 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.18 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2013-10-07 + 3.10.15 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.15 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-09-27 + 3.10.13 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.13 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-09-15 + 3.10.12 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.12 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-08-29 + 3.10.10 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.10 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-08-20 + 3.10.9 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.9 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-08-12 + 3.10.6 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.6 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-08-11 + 3.10.5 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.5 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-08-01 + 3.10.4 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.4 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-07-17 + 3.10.2 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.2 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2013-07-17 + 3.10.1 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10.1 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-07-04 + 3.10.0 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.10 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-06-21 + 3.8.13 + Fix TSC calibration failure + Marcin Bojara + marcin@pisilinux.org + + systemRestart + + + + security + 2013-06-15 + 3.8.13 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.13 + Serdar Soytetir + kaptan@pisilinux.org + + systemRestart + + + + security + 2013-04-18 + 3.8.8 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.8 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-03-31 + 3.8.5 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.5 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + systemRestart + + + + security + 2013-03-25 + 3.8.4 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.4 + Yoyo Fernández + admins@pisilinux.org + + systemRestart + + + + security + 2013-03-14 + 3.8.3 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.3 + Richard de Bruin + admins@pisilinux.org + + systemRestart + + + + security + 2013-03-06 + 3.8.2 + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.8.2 + Erdinç Gültekin + admins@pisilinux.org + + systemRestart + + + + security + 2013-03-03 + 3.8.1 + update to current line + Erdinç Gültekin + admins@pisilinux.org + + systemRestart + + + + security + 2013-02-22 + 3.8.0 + update to final line with patch + Erdinç Gültekin + admins@pisilinux.org + + systemRestart + + + + security + 2013-02-17 + 3.8.0 + obsoletemans wifi fixing + Erdinç Gültekin + admins@pisilinux.org + + systemRestart + + + + security + 2013-02-12 + 3.8.0 + bump to -rc7 + Erdinç Gültekin + admins@pisilinux.org + + systemRestart + + + + security + 2013-02-06 + 3.7.6 + http://www.kernel.org/pub/linux/kernel/v3.0/ChangeLog-3.7.6 + Erdinç Gültekin + admins@pisilinux.org + + systemRestart + + + + security + 2013-01-28 + 3.7.5 + http://www.kernel.org/pub/linux/kernel/v3.0/ChangeLog-3.7.5 + Erdinç Gültekin + admins@pisilinux.org + + systemRestart + + + + security + 2013-01-18 + 3.7.4 + http://www.kernel.org/pub/linux/kernel/v3.0/ChangeLog-3.7.4 + Erdinç Gültekin + admins@pisilinux.org + + systemRestart + + + + security + 2013-01-15 + 3.7.2 + First release + Erdinç Gültekin + admins@pisilinux.org + + systemRestart + + + + + + + grub2 + http://www.gnu.org/software/grub/ Serdar Soytetir kaptan@pisilinux.org GPLv3 - app:console - library - system.devel - Pharma Polyhedra library - Pharma Polyhedra kitaplığı - ppl is the Parma Polyhedra Library that provides numerical abstractions for analysis of complex systems. - ppl, kompleks sistemlerin analizi için sayısal ayrım sağlayan Pharma Polyhedra kitaplığıdır. - http://bugseng.com/external/ppl/download/ftp/releases/1.1/ppl-1.1.tar.xz + app:gui + system.base + GNU GRUB is a Multiboot boot loader. + GNU GRUB (short for GNU GRand Unified Bootloader) is a boot loader package from the GNU Project. + ftp://alpha.gnu.org/gnu/grub/grub-2.02~beta2.tar.xz + http://source.pisilinux.org/1.0/grub2_extras_915resolution_r10.tar.xz + http://ftp.gnu.org/gnu/unifont/unifont-6.3.20131217/unifont-6.3.20131217.bdf.gz + http://source.pisilinux.org/1.0/grub2-theme-pisilinux-0.2.tar.xz - gmp-devel - glpk-devel + autogen + binutils + bison + flex + gcc + help2man + texinfo + freetype-devel + freetype + zlib-devel + ncurses-devel + xz-devel + fuse-devel + lvm2-devel + device-mapper-devel + gettext-devel + dejavu-fonts - system/devel/ppl/pspec.xml + + pisi_name_and_initramfs.patch + mkconfig-fix.patch + + system/boot/grub2/pspec.xml - ppl + grub2 - gmp - glpk - libgcc + freetype + xz + fuse + lvm2 + device-mapper + os-prober + + + /usr/bin + /usr/sbin + /usr/lib/grub/i386-pc/ + /usr/share/doc + /usr/share/grub + /usr/share/info + /boot/grub2 + /usr/share/locale + /usr/share/man/man1 + /usr/share/man/man8 + /etc/bash_completion.d + /etc/grub.d + /etc/default + + + pisi-grub-bg.png + grub-defaults + + + + + 2014-07-20 + 2.02_beta2 + New artwork. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 2.02_beta2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-21 + 2.02_beta2 + Version bump + Marcin Bojara + marcin@pisilinux.org + + + 2013-12-31 + 2.00_5148 + Fix finding other distros. + Fix build with current freetype. + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-02 + 2.00_5148 + Version bump + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-24 + 2.00 + Comment GRUB_GFXPAYLOAD_LINUX=keep out. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-28 + 2.00 + Fix deps. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-06-17 + 2.00 + Set default grub2 resolution to 1024x768 + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-03-03 + 2.00 + Add default Pisi Linux theme + Remove unneeded unifont dep + Manually create Dejavu pf2 fonts + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-09 + 2.00 + Enable splash again. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-11-28 + 2.00 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + perl + http://www.perl.org/ + + PisiLinux Community + admins@pisilinux.org + + Artistic + GPLv2 + app:console + system.base + Larry Wall's Practical Extraction and Reporting Language + Perl dili + Perl est un langage de programmation multi-plateforme stable. + Perl is a high-level programming language with roots in C, sed, awk and shell scripting. Perl is good at handling processes and files, and is especially good at handling text. Perl's hallmarks are practicality and efficiency. While it is used to do a lot of different things, Perl's most common applications are system administration utilities and web programming. A large proportion of the CGI scripts on the web are written in Perl. You need the perl package installed on your system so that your system can handle Perl scripts. + Perl kararlı, platform bağımsız programlama dilidir. + Perl ist eine stabile, plattformunabhängige Programmiersprache + http://www.cpan.org/src/5.0/perl-5.20.0.tar.bz2 + + db-devel + gdbm-devel + zlib-devel + + + perl-vutil-revert.patch + + system/base/perl/pspec.xml + + + perl-docs + Documentation files for perl + programming.language.perl + + /usr/share/doc/html + /usr/share/doc/perl/html + /usr/share/man/ + + + + perl + + db + gdbm + zlib /usr/bin /usr/lib - /usr/share/doc/COPYING - /usr/share/doc/CREDITS - /usr/share/doc/README - /usr/share/doc/NEWS - /usr/share/man - - - - ppl-docs - Documentation for ppl - ppl kitaplığı belgeleri - system.doc - - ppl - - - /usr/share/doc/ppl - - - - ppl-devel - Development files for ppl - ppl için geliştirme dosyaları - - ppl - gmp-devel - - - /usr/bin/ppl-config - /usr/include - /usr/share/aclocal - /usr/share/man/man3 + /usr/share/doc + + Turkish.pm + - 2014-09-06 - 1.1 - Rebuild. + 2014-09-10 + 5.20.0 + Version bump. Serdar Soytetir kaptan@pisilinux.org 2014-05-11 - 1.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 1.1 + 5.18.2 Version bump. - Serdar Soytetir - kaptan@pisilinux.org + Yusuf Aydemir + yusuf.aydemir@pisilinux.org - 2013-08-27 - 1.0 - Clean ppl, version bump. + 2013-08-28 + 5.18.1 + Version bump, clean perl. Serdar Soytetir kaptan@pisilinux.org - 2013-08-01 - 1.0 - Fix deps. + 2013-07-26 + 5.16.2 + Release bump, rebuild. Serdar Soytetir kaptan@pisilinux.org 2013-02-19 - 1.0 - Add patch for gmp 5.10. - Serdar Soytetir - kaptan@pisilinux.org + 5.16.2 + First release + PisiLinux Community + admins@pisilinux.org - 2012-07-13 - 1.0 + 2012-09-06 + 5.16.1 First release - Serdar Soytetir - kaptan@pisilinux.org + PisiLinux Community + admins@pisilinux.org - autoconf - http://www.gnu.org/software/autoconf/autoconf.html + perl-Locale-gettext + http://search.cpan.org/dist/gettext PisiLinux Community admins@pisilinux.org - GPLv3 - app:console - system.devel - Used to create autoconfiguration files - Used to create autoconfiguration files, Autoconf is an extensible package of m4 macros that produce shell scripts to automatically configure software source code packages. - mirrors://gnu/autoconf/autoconf-2.69.tar.xz + Artistic + library + system.base + A Perl module for accessing the GNU locale utilities + GNU yerel araçlarına erişim için Perl modülü + The gettext module permits access from Perl to the gettext() family of functions for retrieving message strings from databases constructed to internationalize software. + Bu modül, çoklu dil desteğini sağlayan gettext() ailesine Perl üzerinden erişimi sağlar. + El módulo gettext permite Perl acceder a la familia de funciones gettext() para obtener cadenas de mensajes (traducidos) desde bases de datos para la internacionalización de software. + http://search.cpan.org/CPAN/authors/id/P/PV/PVANDRY/gettext-1.05.tar.gz - texinfo - m4 perl - system/devel/autoconf/pspec.xml + system/base/perl-Locale-gettext/pspec.xml - autoconf + perl-Locale-gettext - texinfo - m4 + perl - /usr/bin - /usr/share/doc - /usr/share/man - /usr/share/info - /usr/share/autoconf - - - - - 2014-11-30 - 2.69 - Rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 2.69 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-27 - 2.69 - Clean autoconf. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-07-14 - 2.69 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - bison - http://www.gnu.org/software/bison/bison.html - - Serdar Soytetir - kaptan@pisilinux.org - - GPLv2 - app:console - system.devel - A yacc-compatible parser generator - Yacc uyumlu yazım ayrıştırma üreteci - Un générateur d'analyseur syntaxique compatible avec yacc. Une fois que vous maîtrisez Bison, vous pouvez l'utiliser pour développer des analyseur léxicaux pour un grand nombres de langages, de ceux qui sont utilisés dans les simples calculatrices de bureau aux complexes langages de programmation. - A yacc-compatible parser generator. Once you are proficient with Bison, you can use it to develop a wide range of language parsers, from those used in simple desk calculators to complex programming languages - Yacc uyumlu yazım ayrıştırma üreteci. Bison'da ustalık kazandığınızda, basit hesap makinalarından, karmaşık programlama dillerine kadar uzanan geniş yazım ayrıştırıcılar geliştirebilirsiniz. - mirrors://gnu/bison/bison-3.0.2.tar.xz - - m4 - gettext - patch - - system/devel/bison/pspec.xml - - - bison - - m4 - gettext - - - /usr/bin /usr/lib - /usr/share/doc - /usr/share/man - /usr/share/aclocal - /usr/share/info - /usr/share/bison - /usr/share/locale - - - - - 2014-09-06 - 3.0.2 - Rebuild, fix pspec.xml. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 3.0.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-24 - 3.0.2 - Version bump - Burak Fazıl Ertürk - burakerturk@pisilinux.org - - - 2013-11-18 - 3.0.1 - Version bump - Richard de Bruin - richdb@pisilinux.org - - - 2013-08-27 - 3.0 - Version bump, clean. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-23 - 2.7.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-16 - 2.7 - Version bump - Ertan Güven - ertangvn@istanbul.com - - - 2012-10-24 - 2.6.4 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - ccache - http://ccache.samba.org/ - - PisiLinux Community - admins@pisilinux.org - - GPLv3+ - app:console - system.devel - Fast C/C++ compiler cache - Hızlı C/C++ derleme önbelleği - Cache veloz de compilador - Cache de Compilation rapide - ccache is a compiler cache. It speeds up recompilation of C/C++ code by caching previous compiles and detecting when the same compile is being done. - ccache bir derleme önbelleğidir. Önceki derlemeleri önbelleğinde saklayıp, aynı derlemelerde bu önbelleği kullanarak C/C++ kodlarının yeniden derlenmelerini hızlandırır. - http://samba.org/ftp/ccache/ccache-3.2.tar.xz - system/devel/ccache/pspec.xml - - - ccache - - gcc - zlib - - - /usr/bin - /usr/lib/ccache/bin + /usr/share/perl /usr/share/doc /usr/share/man - - 2014-11-23 - 3.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 3.1.9 + + 2014-09-10 + 1.05 Release bump. Marcin Bojara marcin@pisilinux.org - - 2013-10-22 - 3.1.9 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - 2013-08-01 - 3.1.9 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-16 - 3.1.9 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2012-12-15 - 3.1.8 - First release - canatan - admins@pisilinux.org - - - - - - pkgconfig - http://www.freedesktop.org/software/pkgconfig/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.devel - Package Config system that manages compile/link flags for libraries - Kütüphaneler için derleme bayraklarını yöneten bir paket yapılandırma sistemi - Sistema de configuración de paquetes que soporta banderas de compilación/link para librerías - Paquet de configuration système qui gère les fanions (flags) de compilation et chaînage (link) pour les librairies. Il aide à insérer les options adéquates dans la ligne de commande d'appel au compilateur. - Package Config system that manages compile/link flags for libraries. It helps you insert the correct compiler options on the command line. - Kütüphaneler için derleme bayraklarını yöneten, bir paket yapılandırma sistemi. Komut satırından, doğru derleme seçenekleri sunma olanağı sağlar - Sistema de configuración de paquetes que soporta banderas de compilación/link para librerías. Facilita la inserción de las opciones correctos de compilador en línea de comando - http://pkgconfig.freedesktop.org/releases/pkg-config-0.28.tar.gz - - gnuconfig - - system/devel/pkgconfig/pspec.xml - - - pkgconfig - - glib2 - - - /usr/bin - /usr/share/doc - /usr/share/man - /usr/share/aclocal - /usr/share/pkgconfig - /usr/lib/pkgconfig - - - - 2014-05-11 - 0.28 + 1.05 Release bump. Marcin Bojara marcin@pisilinux.org - - 2013-08-31 - 0.28 - Clean pkgconfig. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-01 - 0.28 - Fix deps. - PisiLinux Community - admins@pisilinux.org - - 2013-02-18 - 0.28 - Fixed - PisiLinux Community - admins@pisilinux.org - - - 2012-09-15 - 0.27.1 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - gnuconfig - http://savannah.gnu.org/projects/config - - Serdar Soytetir - kaptan@pisilinux.org - - GPLv2+ - data - system.devel - Base config files for autofoo - Autofoo için temel config dosyaları - fichiers GNU config.sub et config.guess mis à jour. - gnuconfig contains updated config.sub and config.guess files from GNU. - gnuconfig güncel GNU config.sub ve config.guess dosyaları içerir. - http://source.pisilinux.org/1.0/config-20141105.tar.gz - system/devel/gnuconfig/pspec.xml - - - gnuconfig - - /usr/share/gnuconfig - /usr/share/doc - - - - - 2014-12-04 - 20141105 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 20140511 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-04-01 - 20140401 - New git snapshot. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-27 - 20130930 - Clean, new git snapshot. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-04-07 - 20130212 - Fix git archive - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-27 - 20130217 - New git archive - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-23 - 20130123 - bump - Erdinç Gültekin - admins@pisilinux.org - - - 2012-07-13 - 20120712 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - cmake - http://www.cmake.org - - PisiLinux Community - admins@pisilinux.org - - BSD - app:console - system.devel - Cross-platform, open-source make system - Cmake, açık kaynak kodlu ve birden fazla platformda çalışan bir 'make' sistemidir. - CMake, système make open-source et multi-plateforme. CMake est utilisé pour contrôler le processus de compilation de logiciel en utilisant une plate-forme de fichiers de configuration simple et indépendante de compilateur. CMake génère des makefiles et un environnement de travail natifs pouvant être utilisés dans l'environnement du compilateur de votre choix. - CMake, the cross-platform, open-source make system. CMake is used to control the software compilation process using simple platform and compiler independent configuration files. CMake generates native makefiles and workspaces that can be used in the compiler environment of your choice. - Cmake, açık kaynak kodlu ve birden fazla platformda çalışan bir 'make' sistemidir. Yazılım derleme sürecini kontrol etmek için kullanılan CMake, derleyici bağımsız yapılandırma dosyalarının oluşturulmasını sağlar. - http://www.cmake.org/files/v3.0/cmake-3.0.2.tar.gz - - curl-devel - expat-devel - libarchive-devel - ncurses-devel - zlib-devel - - system/devel/cmake/pspec.xml - - - cmake - - curl - expat - libarchive - libgcc - ncurses - zlib - - - /usr/bin - /usr/share/cmake - /usr/share/aclocal/ - /usr/share/doc - /usr/share/man - - - - - 2014-12-17 - 3.0.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-08-23 - 3.0.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 2.8.12.2 + 2013-09-04 + 1.05 Release bump. Marcin Bojara marcin@pisilinux.org - - 2014-03-29 - 2.8.12.2 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-12-11 - 2.8.12.1 - Fix finding freetype issue. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-11-24 - 2.8.12.1 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-23 - 2.8.12 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-08-28 - 2.8.11.2 - Clean cmake. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-01 - 2.8.10.2 - Fix deps. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-17 - 2.8.10.2 - Version bump - Ertan Güven - ertan@pisilinux.org - - 2012-12-01 - 2.8.10 + 2012-10-07 + 1.05 First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org + Marcin Bojara + marcin@pisilinux.org - xcb-proto - http://xcb.freedesktop.org/ + pypolkit + http://www.pisilinux.org PisiLinux Community admins@pisilinux.org MIT - data - system.devel - XCB protocol descriptions - XCB protokol tanımlamaları - XCB is a project to enable efficient language bindings to the X11 protocol. This package contains the protocol descriptions themselves. Language bindings use these protocol descriptions to generate code for marshalling the protocol. - http://xcb.freedesktop.org/dist/xcb-proto-1.11.tar.bz2 - - libxml2 - - system/devel/xcb-proto/pspec.xml - - - xcb-proto - - /usr/lib/pkgconfig - /usr/lib/python* - /usr/share/doc - /usr/share/xcb - - - - - 2014-09-02 - 1.11 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 1.10 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-02-03 - 1.10 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-10-22 - 1.8 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-11-18 - 1.8 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-11-18 - 1.8 - First release - Erdinç Gültekin - admins@pisilinux.org - - - - - - catbox - http://pisilinux.org - - PisiLinux Community - admins@pisilinux.org - - GPLv2 library - system.devel - Python sandboxing module - Python için sandbox modülü - catbox is a Python sandboxing module commonly used by the package management system of PiSi Linux, PiSi. - https://github.com/baris/catbox/archive/catbox-1.6.1.tar.gz - system/devel/catbox/pspec.xml + system.base + Python binding of PolicyKit + PolicyKit için Python bağlayıcısı + pypolkit is a Python binding for the PolicyKit library. + pypolkit PolicyKit için geliştirilmiş bir Python bağlayıcısıdır. + http://source.pisilinux.org/1.0/pypolkit-1.0.2.tar.gz + + glib2-devel + python-devel + polkit-devel + + system/base/pypolkit/pspec.xml - catbox + pypolkit + glib2 + polkit python - /usr/bin /usr/lib /usr/share/doc + 2015-05-08 + 1.0.2 + Rebuild. + Ertuğrul Erata + ertugrulerata@gmail.com + + 2014-05-11 - 1.6.1 + 1.0.2 Release bump. Marcin Bojara marcin@pisilinux.org - - 2013-02-08 - 1.6.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - 2013-10-22 - 1.6 + 2014-04-01 + 1.0.2 Rebuild. Serdar Soytetir kaptan@pisilinux.org - 2013-07-24 - 1.6 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org + 2013-10-30 + 1.0.2 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org - 2010-10-11 - 1.2 + 2010-11-26 + 1.0.2 First release Pisi Linux Admins admins@pisilinux.org @@ -2312,88 +1564,86 @@ - m4 - http://www.gnu.org/software/m4/m4.html + libestr + http://libestr.adiscon.com - PisiLinux Community - admins@pisilinux.org + Marcin Bojara + marcin@pisilinux.org - GPLv3 - app:console - system.devel - GNU macro processor - GNU makro işleyicisi - L'utilitaire m4 est processeur de macro permettant de lire un ou plusieurs fichiers, les traiter en fonction leurs directives macro puis écrire le résultat dans la sortie standard. - The m4 utility is a macro processor that shall read one or more text files, process them according to their included macro statements, and write the results to standard output - m4, bir ya da daha fazla metin dosyasını okuyan; içerdikleri makro kurallarına göre bu dosyaları işleyen ve sonuçlarını standart çıktıya ileten bir makro işlemcisidir. - mirrors://gnu/m4/m4-1.4.17.tar.gz - - gettext-devel - libsigsegv - - system/devel/m4/pspec.xml + LGPLv2.1 + library + system.base + Library for some string essentials + libestr - some essentials for string handling (and a bit more) + http://libestr.adiscon.com/files/download/libestr-0.1.9.tar.gz + system/base/libestr/pspec.xml - m4 + libestr + + /usr/lib/libestr.so* + /usr/share/doc/libestr + + + + libestr-devel + Development files for libestr + system.devel - libsigsegv + libestr - /usr/bin - /usr/share/doc - /usr/share/info - /usr/share/man + /usr/include/libestr.h + /usr/lib/pkgconfig/libestr.pc 2014-05-11 - 1.4.17 + 0.1.9 Release bump. Marcin Bojara marcin@pisilinux.org - 2013-10-23 - 1.4.17 + 2013-10-29 + 0.1.9 Version bump. Yusuf Aydemir yusuf.aydemir@pisilinux.org - 2012-07-12 - 1.4.16 + 2012-11-21 + 0.1.4 First release - Serdar Soytetir - kaptan@pisilinux.org + Marcin Bojara + marcin@pisilinux.org - patch - http://www.gnu.org/software/patch/patch.html + zip + http://www.info-zip.org/Zip.html PisiLinux Community admins@pisilinux.org - GPLv2 + Info-ZIP app:console - system.devel - Applies patch files - Yama dosyalarını uygular - Aplicación de archivos de parches - Permet d'appliquer un patch générer par la commande diff aux fichiers originels, obtenant ainsi les fichiers patchés. - Patch takes a patch file generated by diff command, and applies it to the original files, thus producing patched files. - Özgün dosyaları, diff komutu ile üretilmiş yama dosyasını uygulayarak, yeni biçimlerine çevirir. - Recibe una archivo de parche generado por el comando diff y lo aplica a los archivos originales, así produciendo archivos parcheados. - ftp://ftp.gnu.org/gnu/patch/patch-2.7.4.tar.xz - system/devel/patch/pspec.xml + system.base + Info ZIP (encryption support) + ZIP programı (şifreleme desteği ile birlikte) + Zip est un outil de compression et d'archivage/packaging. Zip est utile pour distribuer un ensemble de fichier sous forme de paquets, et pour sauvegarder de l'espace disque en compressant temporairement les fichiers et répertoires inutilisés. + Zip is a compression and file packaging/archive utility. Zip is useful for packaging a set of files for distribution, for archiving files, and for saving disk space by temporarily compressing unused files or directories. + Zip bir sıkıştırma ve dosya paketleme/arşivleme uygulamasıdır. Zip dosyaları dağıtmak, arşivlemek ve kullanılmayan dosyaları ve dizinleri geçici olarak sıkıştırarak disk boşluğundan tasarruf için kullanılabilecek kullanışlı bir uygulamadır. + mirrors://sourceforge/infozip/Zip%203.x%20%28latest%29/3.0/zip30.tar.gz + system/base/zip/pspec.xml - patch + zip - attr + bzip2 /usr/bin @@ -2402,430 +1652,423 @@ - - 2015-02-01 - 2.7.4 - Version bump. - Hakan Yıldız - hknyldz93@gmail.com - - 2014-05-11 - 2.7.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org + 2014-10-01 + 3.0 + Cleanup,rebuild. + Serdar Soytetir + kaptan@pisilinux.org - 2013-08-27 - 2.7.1 - Add patch. - Serdar Soytetir - kaptan@pisilinux.org + 2014-05-11 + 3.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org - 2013-08-01 - 2.7.1 - Fix deps. - Serdar Soytetir - kaptan@pisilinux.org + 2013-10-28 + 3.0 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org - 2013-02-17 - 2.7.1 - New release + 2013-07-26 + 3.0 + Release bump for rebuild. Serdar Soytetir kaptan@pisilinux.org - 2012-09-23 - 2.7 + 2010-10-11 + 3.0 First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org + Pisi Linux Admins + admins@pisilinux.org - libtool - http://www.gnu.org/software/libtool/libtool.html + pciutils + http://atrey.karlin.mff.cuni.cz/~mj/pciutils.html - Serdar Soytetir - kaptan@pisilinux.org + PisiLinux Community + admins@pisilinux.org GPLv2 - library - system.devel - A shared library tool for developers - Program geliştiriciler için ortak kütüphane aracı - Libtool est une librairie utilitaire partagée pour développeurs. - Libtool is a shared library tool for developers. - Libtool, program geliştiriciler için bir paylaşımlı kütüphane aracıdır. - mirrors://gnu/libtool/libtool-2.4.2.tar.xz - - gnuconfig - autoconf - automake - - system/devel/libtool/pspec.xml + app:console + system.base + Various utilities dealing with the PCI bus + PCI veriyolu işlevleri ile ilgili çeşitli programlar + Les utilitaires PCI sont une collection de programmes d'inspection et de manipulation de la configuration des périphériques PCI. + The PCI Utilities are a collection of programs for inspecting and manipulating configuration of PCI devices. + Pakette bulunan PCI araçları, PCI veriyolunu kullanan donanımlarınızın görüntülenmesi ve ayarlanması işlevini yürütür. + ftp://ftp.kernel.org/pub/software/utils/pciutils/pciutils-3.2.1.tar.xz + + pci.ids + + + pciutils-nogz.patch + pciutils-remove-update-pciids.patch + makefile.patch + + system/base/pciutils/pspec.xml - libtool-ltdl - system.base + pciutils + /usr/sbin /usr/lib + /usr/share/man + /usr/share/misc - libtool + pciutils-devel + Development files for pciutils + pciutils için geliştirme dosyaları + system.devel - gnuconfig + pciutils - /usr/bin - /lib - /usr/share/doc - /usr/share/info - /usr/share/man + /usr/lib/pkgconfig /usr/include - /usr/share/libtool - /usr/share/aclocal + + + + + 2014-05-11 + 3.2.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-03 + 3.2.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-10-30 + 3.1.10 + Rebuild + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-10-05 + 3.1.10 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + libgcrypt + http://www.gnupg.org/ + + PisiLinux Community + admins@pisilinux.org + + LGPLv2.1 + library + system.base + Librairie générale de cryptographie basée sur le code utilisé dans GnuPG. + General purpose crypto library + Genel amaçlı bir şifreleme kitaplığı + Libgcrypt is a general purpose crypto library based on the code used in GNU Privacy Guard. + Libgcrypt, GNU Privacy Guard kodunu temel alan genel amaçlı bir şifreleme kitaplığıdır. + http://source.pisilinux.org/1.0/libgcrypt-1.6.3.tar.bz2 + + libgpg-error-devel + + system/base/libgcrypt/pspec.xml + + + libgcrypt + + libgpg-error + + + /usr/lib + /usr/share/man + /usr/share/doc + /etc/gcrypt + /usr/bin + /usr/share/info - libtool-ltdl-32bit - 32-bit shared libraries for libtool-ltdl - libtool için 32-bit paylaşımlı kitaplıklar + libgcrypt-devel + Development files for libgcrypt + libgcrypt için geliştirme dosyaları + system.devel + + libgcrypt + libgpg-error-devel + + + /usr/include + /usr/lib/pkgconfig + /usr/share/aclocal + /usr/lib32/pkgconfig + /usr/bin/*-config + + + + libgcrypt-32bit + 32-bit shared libraries for libgcrypt + libgcrypt için 32-bit paylaşımlı kitaplıklar emul32 emul32 + + libgpg-error-32bit + glibc-32bit + - libtool-ltdl + libgpg-error-32bit + glibc-32bit + libgcrypt /usr/lib32 - - 2014-11-28 - 2.4.2 - Rebuild for new gcc. - Serdar Soytetir - kaptan@pisilinux.org - - 2014-09-12 - 2.4.2 - Rebuild for new gcc. - Serdar Soytetir - kaptan@pisilinux.org + 2015-04-13 + 1.6.3 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com 2014-05-11 - 2.4.2 + 1.6.1 Release bump. Marcin Bojara marcin@pisilinux.org - 2013-08-27 - 2.4.2 - Clean libtool. - Serdar Soytetir - kaptan@pisilinux.org + 2014-04-03 + 1.6.1 + Version bump. + PisiLinux Community + admins@pisilinux.org - 2012-07-14 - 2.4.2 + 2011-05-03 + 1.5.0 First release - Serdar Soytetir - kaptan@pisilinux.org + Pisi Linux Admins + admins@pisilinux.org - xtrans - http://www.x.org/ + gzip + http://www.gnu.org/software/gzip PisiLinux Community admins@pisilinux.org - MIT - library - system.devel - Librairie trans de X.Org. - X.Org trans library - X.Org trans kitaplığı. - X.Org trans Bibliothek - xtrans includes a number of routines to make X implementations transport-independent. - xtrans, X gerçeklemelerini taşıma türünden bağımsız yapmak için kullanılan bazı yordamları içerir. - mirrors://xorg/individual/lib/xtrans-1.3.4.tar.bz2 - - xorg-proto - - system/devel/xtrans/pspec.xml - - - xtrans - - /usr/include/X11/Xtrans - /usr/share/aclocal - /usr/share/pkgconfig - - - - - 2014-07-11 - 1.3.4 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 1.3.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-02-05 - 1.3.3 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-01-17 - 1.3.2 - Version bump - Richard de Bruin - richdb@pisilinux.org - - - 2012-08-19 - 1.2.7 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - xorg-util - http://www.x.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - app:console - system.devel - Utilitaires de X.Org - X.Org utilities - X.Org araçları - X.Org Werkzeuge - xorg-util contains some Xorg X11 command-line utilities, but more importantly, X11 configuration and rule files. - mirrors://xorg/individual/util/gccmakedep-1.0.3.tar.bz2 - mirrors://xorg/individual/util/imake-1.0.7.tar.bz2 - mirrors://xorg/individual/util/lndir-1.0.3.tar.bz2 - mirrors://xorg/individual/util/makedepend-1.0.5.tar.bz2 - mirrors://xorg/individual/util/xorg-cf-files-1.0.5.tar.bz2 - - host-defaults.patch - - system/devel/xorg-util/pspec.xml - - - xorg-util - - /usr/bin - /usr/share/X11/config - /usr/share/man - - - - - 2014-08-31 - 7.6 - Update. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 7.6 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-07 - 7.6 - Release bump - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-08-19 - 7.6 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - isl - http://www.kotnet.org/~skimo/isl/ - - Serdar Soytetir - kaptan@pisilinux.org - + GPLv2 LGPLv2.1 - library - system.devel - Integer Set Library - isl is a library for manipulating sets and relations of integer points bounded by linear constraints. - http://isl.gforge.inria.fr/isl-0.13.tar.bz2 - system/devel/isl/pspec.xml + app:console + system.base + Standard GNU compressor + GNU dosya arşiv aracı + gzip (GNU zip) est un programme populaire de compression de donnée écrit pour le projet GNU. + gzip (GNU zip) is a popular data compression program written for the GNU project. + Gzip (GNU zip) GNU projesi için geliştirilmiş popüler bir veri sıkıştırma programıdır. + http://ftp.gnu.org/gnu/gzip/gzip-1.6.tar.xz + system/base/gzip/pspec.xml - isl - - gmp - + gzip - /usr/lib + /bin /usr/share/doc - - - - isl-devel - Development files for isl - isl için geliştirme dosyaları - - isl - - - /usr/include - /usr/lib/pkgconfig + /usr/share/man + /usr/share/info - - 2014-09-06 - 0.13 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - + 2014-05-11 - 0.12.2 + 1.6 Release bump. Marcin Bojara marcin@pisilinux.org - - 2014-03-29 - 0.12.2 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-22 - 0.12.1 - New release - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-28 - 0.12 - Move pc files to devel pack, rebuild - PisiLinux Community - admins@pisilinux.org - - - 2013-07-24 - 0.12 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - 2013-02-16 - 0.11.1 - New release + 2013-08-31 + 1.6 + Version bumm, clean gzip. Serdar Soytetir kaptan@pisilinux.org - 2012-09-05 - 0.10 + 2012-08-23 + 1.5 First release - Erdem Artan + PisiLinux Community admins@pisilinux.org - dietlibc - http://www.fefe.de/dietlibc + grep + http://www.gnu.org/software/grep/grep.html + + PisiLinux Community + admins@pisilinux.org + + GPLv3 + app:console + system.base + GNU regular expression matcher + Grep düzenli ifade eşleme aracı + La commande grep recherche dans un ou plusieurs fichiers les lignes correspondant à un motif défini. Par défaut grep affiche les lignes éligibles. + The grep command searches one or more input files for lines containing a match to a specified pattern. By default, grep prints the matching lines. + Grep komutu bir veya daha fazla verilen dosyada aranan parçayı bulmaya yarayan bir programdır. Ön tanımlı olarak grep eşleşen satırları çıktıya verir. + http://ftp.gnu.org/gnu/grep/grep-2.20.tar.xz + + gettext + libpcre-devel + + system/base/grep/pspec.xml + + + grep + + libpcre + + + /bin + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/locale + + + + + 2014-06-04 + 2.20 + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 2.18 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 2.18 + Version bump + PisiLinux Community + admins@pisilinux.org + + + 2013-10-27 + 2.15 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-10-22 + 2.14 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2010-10-11 + 2.14 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + comar-api + http://www.pisilinux.org PisiLinux Community admins@pisilinux.org GPLv2 library - system.devel - A libc optimized for small size - Düşük boyut için optimize edilmiş C kütüphanesi - dietlibc is a libc that is optimized for small size. It can be used to create small statically linked binaries for Linux on various architectures. - dietlibc, düşük boyutlu olması için optimize edilmiş bir C kütüphanesidir. Farklı mimarilerde statik bağlanmış ve düşük boyutlu ikili dosyalar oluşturmak için kullanılabilir. - http://pkgs.fedoraproject.org/repo/pkgs/dietlibc/dietlibc-0.33.20120825.tar.xz/016865b8c40d40a57b2ddb5862f2e338/dietlibc-0.33.20120825.tar.xz - http://pkgs.fedoraproject.org/repo/pkgs/dietlibc/dietlibc-github-c3f1cf67fcc186bb859e64a085bf98aaa6182a82.patch.gz/734e14b59b7f017ae5843ee9b9b6d34e/dietlibc-github-c3f1cf67fcc186bb859e64a085bf98aaa6182a82.patch.gz - - dietlibc-0.33-biarch.patch - - system/devel/dietlibc/pspec.xml + system.base + Utility functions for Comar scripts + Çomar betikleri için yardımcı fonksiyonlar + Librairie utilitaire générique pour les opérations communes de scripts Comar. + Generic utility library for common Comar script operations. + Çomar betiklerinde sıkça yapılan ortak işlemler için yardımcı fonksiyonlar kitaplığı. + http://source.pisilinux.org/1.0/comar-api-2.4.9.tar.gz + + python + + + run_dir.patch + pisilinux.patch + add-stopdependencies.patch + + system/base/comar-api/pspec.xml - dietlibc + comar-api + + python + pisilinux-python + - /usr/bin - /usr/lib/dietlibc/include - /usr/lib/dietlibc/lib-i386 - /usr/lib/dietlibc/lib-x86_64 - /usr/share/man - /usr/share/doc + /usr/lib/pisilinux + /usr/lib/python2.7 + + 2014-08-20 + 2.4.9 + Fix paths. + Marcin Bojara + marcin@pisilinux.org + 2014-05-11 - 0.33.20120825 + 2.4.9 Release bump. Marcin Bojara marcin@pisilinux.org - 2013-11-03 - 0.33.20120825 - Version bump - Marcin Bojara - marcin@pisilinux.org + 2013-08-31 + 2.4.9 + Release bump, clean comar-api. + Serdar Soytetir + kaptan@pisilinux.org - 2010-10-11 - 0.32 + 2010-11-29 + 2.4.9 First release Pisi Linux Admins admins@pisilinux.org @@ -2834,148 +2077,135 @@ - mpfr - http://www.mpfr.org + pisilinux-python + http://www.pisilinux.org - Serdar Soytetir - kaptan@pisilinux.org + PisiLinux Community + admins@pisilinux.org - GPLv2+ - LGPLv2+ + GPLv2 library - system.devel - Multiple precision floating point library - La librairie MPFR est une librairie C pour les calculs à virgules flottantes à précisions multiples à arrondi exact (également appelé arrondi correct). Elle est basée sur la librairie à précision multiple GMP. - The MPFR library is a C library for multiple-precision floating-point computations with exact rounding (also called correct rounding). It is based on the GMP multiple-precision library. - MPFR es una librería en C para computaciones de punto flotante de múltiple precisión con redondeo exacto (también llamado redondeo correcto). Está basada en la librería de múltiple precisión GMP. - http://ftp.gnu.org/gnu/mpfr/mpfr-3.1.2.tar.xz + system.base + Python modules for Pisi Linux + PiSi Linux için Python modülleri + Python modules for Pisi Linux provides functions for common task, with the aim of easing development. + PiSi Linux için Python modülleri genel işler için fonksiyonlar sunarak geliştirme işini kolaylaştırmayı amaçlamaktadır. + Módulos Python para PiSi Linux facilitan funciones para tareas comunes, para simplificar el desarrollo. + http://source.pisilinux.org/1.0/pisilinux-python-0.4.8.tar.gz - gmp-devel + python-devel - mpfr-3.1.2-p10.patch + remove_libX11_dep.patch - system/devel/mpfr/pspec.xml + system/base/pisilinux-python/pspec.xml - mpfr + pisilinux-python - gmp + python /usr/lib - /usr/share/info - /usr/share/doc/mpfr - - - - mpfr-devel - Development files for mpfr - mpfr için geliştirme dosyaları - - mpfr - - - /usr/include - /usr/share/doc/mpfr/examples - /usr/share/doc/mpfr/html + /usr/share/doc + /usr/share/locale - - 2014-09-06 - 3.1.2_p10 - Patch version bump to 10. - Serdar Soytetir - kaptan@pisilinux.org - + 2015-03-11 + 0.4.8 + Remove libX11 dependency. + Ertuğrul Erata + ertugrulerata@gmail.com + + 2014-05-11 - 3.1.2_p5 + 0.4.8 Release bump. Marcin Bojara marcin@pisilinux.org - - 2014-04-01 - 3.1.2_p5 - Version bump to patch level 5. - Serdar Soytetir - kaptan@pisilinux.org - - 2013-08-27 - 3.1.2 - Clean mpfr. + 2014-03-07 + 0.4.8 + Release bump. Serdar Soytetir kaptan@pisilinux.org - 2013-07-23 - 3.1.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-07-13 - 3.1.1 - First release + 2013-09-04 + 0.4.8 + Release bump. Serdar Soytetir kaptan@pisilinux.org + + 2010-12-09 + 0.4.8 + First release + Pisi Linux Admins + admins@pisilinux.org + - yacc - http://dinosaur.compilertools.net/#yacc + popt + http://www.rpm5.org/ PisiLinux Community admins@pisilinux.org as-is app:console - system.devel - Yacc: Yet Another Compiler-Compiler - Yacc: Yet Another Compiler-Compiler - Yacc fourni un outil général de description d'entrée pour un logiciel. L'utilisateur de Yacc spécifie la structure de l'entrée avec le code à invoquer lorsque de tels structures sont reconnues. Yacc transforme ce qui a été spécifié en sous-routine gérant le processus d'entrée. - Yacc provides a general tool for describing the input to a computer program. The Yacc user specifies the structures of his input, together with code to be invoked as each such structure is recognized. Yacc turns such a specification into a subroutine that handles the input process - Yacc, bir uygulamaya girdi açıklamasını yapan bir araçtır. Yacc kullanıcısı, girdinin yapısını ve bu yapının her seferinde tanındığı kodu belirtir. Yacc; bu tür bir belirlemeyi, girdi sürecini işleyen bir alt yordama çevirir. - ftp://metalab.unc.edu/pub/Linux/devel/compiler-tools/yacc-1.9.1.tar.Z - - mkstemp.patch - skeleton.c.diff - yacc-1.9.1-ia64.patch - - system/devel/yacc/pspec.xml + library + system.base + Popt command line option parser + Popt komut satırında çalıştıran bir seçenek ayrıştırıcıdır. + La librairie popt existe essentiellement pour analyser des options de ligne de commande. Elle procure de nombreux avantages tels que l'absence de variables globales, la possibilité d'analyser un tableau arbitraire d'éléments de type argv, d'exécuter des filtres d'options extérieurs, la génération automaituqe des messages d'aide et d'utilisation ainsi qu'un méthode standard pour synonymes d'options. + The popt library exists essentially for parsing command line options with advantages such as there are no global variables, ability to parse an arbitrary array of argv-style elements, to exec external option filters, and automatic generation of help and usage messages, a standard method of option aliasing. + Popt, komut satırında seçenek ayrıştırma için gerekli bir kütüphanedir. Genel değişken olmaması, dağınık dizi bileşenlerini ayrıştırabilmesi, harici uygulama filtreleri kullanabilmesi, otomatik mesaj ve yardım dosyaları üretimi gibi başarılı özellikleri bulunur. + ftp://anduin.linuxfromscratch.org/BLFS/svn/p/popt-1.16.tar.gz + system/base/popt/pspec.xml - yacc + popt + + gettext + - /usr/bin + /usr/lib /usr/share/doc /usr/share/man + /usr/share/locale + + + + popt-devel + Development files for popt + popt için geliştirme dosyaları + system.devel + + popt + + + /usr/include/popt.h + /usr/share/man/man3 + /usr/lib/pkgconfig - + 2014-05-11 - 1.9.1 + 1.16 Release bump. Marcin Bojara marcin@pisilinux.org - - 2014-01-17 - 1.9.1 - Rebuild for 1.0 - Richard de Bruin - richdb@pisilinux.org - 2010-10-11 - 1.9.1 + 1.16 First release Pisi Linux Admins admins@pisilinux.org @@ -2984,80 +2214,284 @@ - scons - http://www.scons.org + sysvinit + http://freshmeat.net/projects/sysvinit/ PisiLinux Community admins@pisilinux.org - MIT + GPLv2 app:console - system.devel - An Open Source software construction tool - Python temelli, esnek, geliştirilebilir inşa aracı - Utilitaire extensible écrit en python. On peut considérer SCons comme un substitut amélioré multi-plateforme de Make intégrant des fonctionnalités similaires à celles d'autoconf/automake et un gestionnaire de cache de compilateur tel ccache. - Think of SCons as an improved, cross-platform substitute for the classic Make utility with integrated functionality similar to autoconf/automake and compiler caches such as ccache. - Python temelli, esnek, geliştirilebilir inşa aracı. SCons, klasik "make" aracına "autconf/automake" özellikleri ve "ccache" gibi derleyici önbelleği eklenmiş, gelişmiş bir araç olarak düşünülebilir. - mirrors://sourceforge/scons/scons-2.3.1.tar.gz - - python - + system.base + Programs which control basic system processes + sysvinit package contains a group of utilities that control the very basic functions of your system. sysvinit contains the init program, the first program started by the Linux kernel when the system boots. + http://download.savannah.gnu.org/releases/sysvinit/sysvinit-2.88dsf.tar.bz2 - scons-1.0.0-qt-handle-missing-moc-files.patch - fix-gnu-link-handling.patch + sysvinit-2.86-ctrlc.patch + sysvinit-2.78-man.patch + sysvinit-2.86-loginshell.patch + sysvinit-2.86-single.patch + sysvinit-2.88-quiet.patch + sysvinit-2.88-ipv6.patch + sysvinit-2.88-omit.patch + sysvinit-2.88-wall-maxlines.patch - system/devel/scons/pspec.xml + system/base/sysvinit/pspec.xml - scons - - python - + sysvinit + /bin + /sbin /usr/bin - /usr/lib /usr/share/man - /usr/share/doc + /usr/include + + + System.Package + + + + sysvinit-tools + Tools used for process and utmp management + Süreç ve utmp yönetim araçları + + /bin/mountpoint + /sbin/pidof + /sbin/killall5 + /sbin/sulogin + /usr/bin/wall + /usr/bin/last + /usr/bin/lastb + /usr/bin/mesg + /usr/bin/utmpdump + /usr/share/man/man1 + /usr/share/man/man8/killall5* + /usr/share/man/man8/pidof* + /usr/share/man/man8/sulogin* - + 2014-05-11 - 2.3.1 + 2.88 Release bump. Marcin Bojara marcin@pisilinux.org - - 2014-03-29 - 2.3.1 - Version bump + + 2011-06-01 + 2.88 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + diffutils + http://www.gnu.org/software/diffutils/diffutils.html + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + Tools to make diffs and compare files + Dosyaları karşılaştırmak ve fark dosyaları oluşturmak için kullanılan araçlar + Vous pouvez utiliser la commande diff pour voir les différences entre deux fichiers en particulier, ou les différences entre deux répertoires fichiers par fichier. Diff peut afficher les différences entre fichiers ligne par ligne dans différents formats pouvant être choisis avec les options de la ligne de commande. + You can use the diff command to show differences between two files, or each corresponding file in two directories. diff outputs differences between files line by line in any of several formats, selectable by command line options. + İki dosya arasındaki ya da iki klasör içindeki dosyaları karşılaştırarak farklılıkları belirleyebileceğiniz araç. Farklılıkları satır satır olarak, komut satırı seçenekleri ile farklı formatta dosyalara yazdırabilirsiniz. + http://ftp.gnu.org/gnu/diffutils/diffutils-3.3.tar.xz + + patch + + system/base/diffutils/pspec.xml + + + diffutils + + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/locale + + + + + 2014-05-11 + 3.3 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-01 + 3.3 + Version bump, clean diffutils. Serdar Soytetir kaptan@pisilinux.org + + 2012-08-23 + 3.2 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + man-pages + http://www.win.tue.nl/~aeb/linux/man/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + data:doc + system.base + Une collection de pages de manuel Linux compréhensibles d'une certaine manière. + A somewhat comprehensive collection of Linux man pages + Kapsamlı Linux kılavuz dökümanları + A large collection of man pages (documentation) from the Linux Documentation Project (LDP). + https://www.kernel.org/pub/linux/docs/man-pages/man-pages-3.81.tar.xz + http://www.kernel.org/pub/linux/docs/man-pages/man-pages-posix/man-pages-posix-2003-a.tar.xz + system/base/man-pages/pspec.xml + + + man-pages + + man-db + + + /usr/share/doc + /usr/share/man + + + man1/getent.1 + man1/sprof.1 + + + + + 2015-03-09 + 3.81 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-07-13 + 3.70 + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 3.55 + Release bump. + Marcin Bojara + marcin@pisilinux.org + - 2013-10-22 - 2.3.0 - Rebuild. + 2013-10-28 + 3.55 + Version bump. Serdar Soytetir kaptan@pisilinux.org - 2013-07-24 - 2.3.0 + 2013-10-28 + 3.47 Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org + Serdar Soytetir + kaptan@pisilinux.org - 2013-02-17 - 2.2.0 - Version bump - Ertan Güven - ertan@pisilinux.org + 2013-03-04 + 3.47 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org - 2011-12-14 + 2011-01-04 + 3.32 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + sysfsutils + http://linux-diag.sourceforge.net/Sysfsutils.html + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + System Utilities Based on Sysfs + Çeşitli sistem araç ve gereçleri + Ceci est un ensemble d'utilitaires se basant sur sysfsm un nouveau système de fichier virtuel des noyaux Linux 2.5 et + exposant l'arbre des périphériques du système. + These are a set of utilites built upon sysfs, a new virtual filesystem in Linux kernel versions 2.5+ that exposes a system's device tree. + sysfsutils sysfs sanal dosya sistemi üzerine kurulu bir araç setidir. + mirrors://sourceforge/linux-diag/sysfsutils-2.1.0.tar.gz + + sysfsutils-2.0.0-class-dup.patch + sysfsutils-2.1.0-get_link.patch + + system/base/sysfsutils/pspec.xml + + + sysfsutils + + /usr/bin + /lib + /usr/lib + /usr/share/doc + /usr/share/man + + + + sysfsutils-devel + Development files for sysfsutils + sysfsutils için geliştirme dosyaları + system.devel + + sysfsutils + + + /usr/include + /usr/share/man/man3 + + + + + 2014-05-11 + 2.1.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-29 + 2.1.0 + Rebuild + Pisi Linux Admins + admins@pisilinux.org + + + 2010-10-11 2.1.0 First release Pisi Linux Admins @@ -3067,1790 +2501,558 @@ - libsigsegv - http://libsigsegv.sourceforge.net/ + miscfiles + http://freshmeat.net/projects/miscfiles/ PisiLinux Community admins@pisilinux.org GPLv2 - library - system.devel - Une librairie pour gérer les erreurs de pagination en mode utilisateur. - A library for handling page faults in user mode - Oluşan bellek hatalarının kullanıcı kipinde işlenmesini sağlayan bir kitaplık - This is a library for handling page faults in user mode. A page fault occurs when a program tries to access to a region of memory that is currently not available. - libsigsegv, oluşan bellek hatalarının kullanıcı kipinde işlenmesini sağlayan bir kitaplıktır. - mirrors://gnu/libsigsegv/libsigsegv-2.10.tar.gz - system/devel/libsigsegv/pspec.xml + data + system.base + Fichiers divers. + Miscellaneous files + Çeşitli dosyalar + Verschiedene Dateien + miscfiles is a collection of data files for freely available information, like airport, country, currencies, city information, and codes. It also includes the Unicode character database. + miscfiles havalanı, ülke, para birimi, şehir bilgisi ve kodları gibi bir çok ulaşılabilir bilgiyi veri dosyaları halinde tutmaktadır. + http://ftp.gnu.org/gnu/miscfiles/miscfiles-1.5.tar.gz + system/base/miscfiles/pspec.xml - libsigsegv + miscfiles - /usr/lib - /usr/share/doc - - - - libsigsegv-devel - Development files for libsigsegv - libsigsegv için geliştirme dosyaları - - libsigsegv - - - /usr/include - - - - - 2014-05-11 - 2.10 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-15 - 2.10 - Release bump - Burak Ertürk - burakerturk@pisilinux.org - - - 2013-10-22 - 2.10 - Rebuild. - Pisi Linux Admins - admins@pisilinux.org - - - 2011-12-09 - 2.10 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - swig - http://www.swig.org/ - - PisiLinux Community - admins@pisilinux.org - - GPLv3+ - BSD - app:console - system.devel - Connects C/C++/Objective C to some high-level programming languages - Basitleştirilmiş arayüz oluşturucu - Simplified Wrapper and Interface Generator (Générateur d'interface de scripts d'enrobage simplifié), SWIG est un outil de développement qui connecte des programmes écrits en C et C++ avec divers langages de programmation de haut niveau. SWIG est utilisé avec différents type de langages incluant les langages de script habituels tels que Perl, PHP, Python, Tcl, Ruby. - Simplified Wrapper and Interface Generator, SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is used with different types of languages including common scripting languages such as Perl, PHP, Python, Tcl, Ruby and PHP - SWIG, C ve C++ ile yazılmış uygulamaları çeşitli üst düzey programlama dilleri ile bağlayan bir yazılım geliştirme aracıdır. SWIG, genel betik dilleri olan Perl, PHP, Python, Tcl, Ruby gibi farklı diller ile kullanılır. - mirrors://sourceforge/swig/swig-3.0.2.tar.gz - - python - perl - - system/devel/swig/pspec.xml - - - swig - - zlib - libgcc - libpcre - - - /usr/bin - /usr/lib - /usr/share/swig - /usr/share/doc - /usr/share/man - - - - - 2014-12-22 - 3.0.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 3.0.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 3.0.0 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-23 - 2.0.11 - Clean swig. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-24 - 2.0.10 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-17 - 2.0.9 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2012-09-15 - 2.0.8 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - libunwind - http://www.nongnu.org/libunwind/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.devel - Call chain tracer of a program - Yazılım çağrıları geri izleme aracı - libunwind is a portable and efficient C programming interface (API) to determine the call chain of a program. - libunwind bir yazılımın çağrı sıralamasını takip etmek için kullanılan, hızlı çalışan ve taşınabilir bir C programlama arabirimidir. - http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz - - xz-devel - - system/devel/libunwind/pspec.xml - - - libunwind - - xz - - - /usr/lib - /usr/share/doc/libunwind - /usr/share/man - /usr/share/man/man3 - - - - libunwind-devel - Development files for libunwind - libunwind için geliştirme dosyaları - - libunwind - - - /usr/include - /usr/lib/pkgconfig - - - - - 2015-01-30 - 1.1 - Rebuild. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2014-05-11 - 1.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-02-20 - 1.1 - Rebuild Unused - Varol Maksutoğlu - waroi@pisilinux.org - - - 2013-07-27 - 1.1 - Move pc files to devel pack, rebuild - PisiLinux Community - admins@pisilinux.org - - - 2013-02-16 - 1.1 - New release - Serdar Soytetir - kaptan@pisilinux.org - - - 2011-12-09 - 1.0.1 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - elfutils - http://www.redhat.com/ - - PisiLinux Community - admins@pisilinux.org - - OpenSoftware - app:console - library - system.devel - Libraries/utilities to handle ELF objects - Derlenmiş objeleri işlemek için gereken aletler koleksiyonu - elfutils contains libraries and utilities to handle ELF objects and is a replacement for libelf. - elfutils derlenmiş objeleri işlemek için gereken çeşitli araçlar içerir. - https://fedorahosted.org/releases/e/l/elfutils/0.160/elfutils-0.160.tar.bz2 - - bzip2 - xz-devel - zlib-devel - - system/devel/elfutils/pspec.xml - - - elfutils - - xz - zlib - bzip2 - - - /usr/bin - /usr/lib - /usr/share/doc - /usr/include - - - - - 2014-11-23 - 0.160 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 0.158 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-29 - 0.158 - Add upstream patch. - Marcin Bojara - marcin@pisilinux.org - - - 2014-02-22 - 0.158 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-08-27 - 0.156 - Clean elfutils. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-01 - 0.156 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-16 - 0.155 - New release - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-07-30 - 0.154 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - nasm - http://nasm.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - BSD - app:console - system.devel - Groovy little assembler - Assembler derleyicisi - NASM est l'assembleur Netwide, un assembleur libre et portable pour les processeurs des séries Intel 80x86 - NASM is the Netwide Assembler, a free portable assembler for the Intel 80x86 microprocessor series. - Intel 80x86 mikroişlemci serisi için aktarılabilir Assembler derleyicisi. - http://www.nasm.us/pub/nasm/releasebuilds/2.11.01/nasm-2.11.01.tar.xz - - texinfo - - system/devel/nasm/pspec.xml - - - nasm - - /usr/bin - /usr/share/doc - /usr/share/man - - - - - 2014-05-11 - 2.11.01 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 2.11.01 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-22 - 2.10.09 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-24 - 2.10.09 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-18 - 2.10.07 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2012-09-15 - 2.10.05 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - glpk - http://www.gnu.org/software/glpk/glpk.html - - Serdar Soytetir - kaptan@pisilinux.org - - GPLv2 - library - system.devel - GNU Linear Programming Kit - GNU Doğrusal Programlama Kiti - Le paquet GLPK (GNU Linear Programming Kit - Kit de Programmation Linéaire) a pour objectif de résoudre le problème de programmation linéaire (LP) de grande envergure, la programmation d'entiers mixés (MIP), et autres problèmes de la sorte. Il s'agit d'un ensemble de routines écrites en C ANSI et organisées de manière à former une librairie que l'on peut appeler. - The GLPK (GNU Linear Programming Kit) package is intended for solving large-scale linear programming (LP), mixed integer programming (MIP), and other related problems. It is a set of routines written in ANSI C and organized in the form of a callable library. - mirrors://gnu/glpk/glpk-4.55.tar.gz - system/devel/glpk/pspec.xml - - - glpk - - /usr/bin - /usr/lib - /usr/share/doc - - - - glpk-devel - Development files for glpk - glpk için geliştirme dosyaları - - glpk - - - /usr/include - - - - - 2014-09-06 - 4.55 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 4.54 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-02-27 - 4.52 - Rebuild Unused - Varol Maksutoğlu - waroi@pisilinux.org - - - 2013-08-28 - 4.52 - Version bump, clean glpk. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-18 - 4.48 - v.bump - PisiLinux Community - admins@pisilinux.org - - - 2012-08-16 - 4.47 - First release - Ramazan Utku - admins@pisilinux.org - - - - - - python-setuptools - http://pypi.python.org/pypi/setuptools - - PisiLinux Community - admins@pisilinux.org - - PSF-2.2 - library - system.devel - Python setuptools - Python kurulum araçları - python-setuptools is a collection of enhancements to the Python distutils that allow you to more easily build and distribute Python packages, especially ones that have dependencies on other packages. - python-setuptools, Python distutils'e yapılan, özellikle başka paketlere bağımlılığı olan Python paketlerini daha kolay oluşturmaya ve dağıtmaya yarayan iyileştirmeler koleksiyonudur. - http://pypi.python.org/packages/source/d/distribute/distribute-0.6.49.tar.gz - system/devel/python-setuptools/pspec.xml - - - python-setuptools - - /usr/bin - /usr/lib/python* - /usr/share/doc - - - - - 2014-05-11 - 0.6.49 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-24 - 0.6.49 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-17 - 0.6.35 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2012-08-19 - 0.6.28 - First release - Ramazan Utku - admins@pisilinux.org - - - - - - yasm - http://www.tortall.net/projects/yasm/ - - PisiLinux Community - admins@pisilinux.org - - BSD - GPLv2 - LGPLv2 - Artistic - app:console - system.devel - Assembler that supports many syntaxes and architectures - Bir çok sentaks ve mimari destekleyen Assembler - A complete rewrite of the NASM assembler under the "new" BSD License. Yasm currently supports the x86 and AMD64 instruction sets, accepts NASM and GAS assembler syntaxes, outputs binary, ELF32, ELF64, 32 and 64-bit Mach-O, RDOFF2, COFF, Win32, and Win64 object formats and generates source debugging information in STABS, DWARF 2, and CodeView? 8 formats. - NASM Assembler programının yeni BSD lisansı ile baştan yazılmış bir Assembler. En önemli özellikleri x86 ve AMD64 komutsetlerini, NASM ve GAS sentaksını desteklemesidir. İkilik, ELF32, ELF64, 32 ve 64-bit Mach-O, RDOFF2, COFF, Win32 ve Win64 obje formatlarında çıktı üretebilir, hata ayıklamak için STABS, DWARF 2 ve CodeView? 8 formatlarını desteklemektedir. - http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz - system/devel/yasm/pspec.xml - - - yasm - - /usr/bin - /usr/lib - /usr/share/doc - /usr/share/man - - - - yasm-devel - Development files for yasm - yasm için geliştirme dosyaları - - yasm - - - /usr/include - /usr/lib/libyasm.a + /usr/share/doc + /usr/share/rfc + /usr/share/dict + /usr/share/misc 2014-05-11 - 1.2.0 + 1.5 Release bump. Marcin Bojara marcin@pisilinux.org - 2013-10-22 - 1.2.0 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2011-12-09 - 1.2.0 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - cloog - http://www.cloog.org/ - - Serdar Soytetir - kaptan@pisilinux.org - - GPLv2+ - app:console - library - system.devel - Chunky Loop Generator - cloog is CLooG is a free software and library to generate code for scanning Z-polyhedra. It is used by the GCC Graphite optimization framework. - http://www.bastoul.net/cloog/pages/download/cloog-0.18.1.tar.gz - - gmp-devel - ppl-devel - - - cloog-0.18.1-isl-compat.patch - - system/devel/cloog/pspec.xml - - - cloog - - gmp - isl - - - /usr/bin - /usr/lib - /usr/share/doc/cloog/ - /usr/share/info - - - - cloog-devel - Development files for cloog - - cloog - - - /usr/include - /usr/lib/pkgconfig/cloog.pc - - - - - 2014-09-06 - 0.18.1 - Rebuild for new isl and new toolchain. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 0.18.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 0.18.1 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-27 - 0.18.0 - Clean cloog. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-26 - 0.18.0 - Move pc files to devel pack, rebuild. - Erdinç Gültekin - erdincgultekin@pisilinux.org - - - 2013-04-23 - 0.18.0 - Dep fixed - PisiLinux Community - admins@pisilinux.org - - - 2012-02-16 - 0.18.0 - New release - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-06-22 - 0.17.0 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - binutils - http://www.gnu.org/software/binutils/ - - Serdar Soytetir - kaptan@pisilinux.org - - GPLv2 - app:console - system.devel - Assembler and linker tools - Makine dili derleme ve bağlama araçları - Contient des commandes telles que as, ld, nm, objdump, ar, ranlib pour compiler du code assembleur en langage machine ainsi que pour chaîner (link) et manipuler les fichiers binaires objets. - Contains commands like as, ld, nm, objdump, ar, ranlib for compiling assembly code to the machine language, and for linking and manipulating the binary object files. - Assembly kodlarını makine diline derlemek, oluşan obje dosyalarını bağlamak ve ikili dosyalar üzerinde işlemler yapmak için kullanılan as, ld, nm, objdump, ar, ranlib gibi komutları içermektedir. - http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.bz2 - - binutils-2.24-lto-testsuite.patch - binutils-2.24-gold-testsuite-plugin.patch - binutils-2.24-shared-pie.patch - binutils-2.24-CVE-2014-8484.patch - binutils-2.24-CVE-2014-8485.patch - binutils-2.24-CVE-2014-8501.patch - binutils-2.24-CVE-2014-8502.patch - binutils-2.24-CVE-2014-8503.patch - binutils-2.24-CVE-2014-8504.patch - binutils-2.24-CVE-2014-8737.patch - binutils-2.24-CVE-2014-8738.patch - binutils-2.24-strings-all-default.patch - - system/devel/binutils/pspec.xml - - - binutils - - zlib - - - /usr/bin - /usr/lib - /usr/include - /usr/share/info - /usr/share/man - - - - - 2014-11-28 - 2.24 - Fix CVE issues. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-09-12 - 2.24 - Rebuild for new glibc. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-09-06 - 2.24 - Rebuild for new gcc, add pie and lto testsuite patch. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-14 - 2.24 - Add upstream patch. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-30 - 2.24 - Rebuild for new gcc. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-03-29 - 2.24 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-27 - 2.23.2 - Back to 2.23.2, cleanup. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-23 - 2.23.52.0.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-16 - 2.23.51.0.9 - New release. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-16 - 2.23.51.0.8 - New toolchain up. - Erdinç Gültekin - admins@pisilinux.org - - - - - - guile - http://www.gnu.org/software/guile/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2+ - LGPLv2+ - app:console - library - system.devel - Interpréteur et librairie GNU Scheme. - GNU Scheme interpreter and library - GNU Scheme yorumlayıcısı ve kitaplığı - Język GNU Extension language. - GUILE (GNU's Ubiquitous Intelligent Language for Extension) is a library implementation of the Scheme programming language, written in C. GUILE provides a machine-independent execution platform that can be linked in as a library during the building of extensible programs. - mirrors://gnu/guile/guile-2.0.11.tar.xz - - gc-devel - - system/devel/guile/pspec.xml - - - guile - - gc - gmp - libffi - libtool-ltdl - libunistring - - - /etc - /usr/share/doc - /usr/share/man - /usr/bin - /usr/share/info - /usr/lib/lib* - /usr/share/guile - /usr/share/emacs - /usr/lib/guile/2.0 - - - - guile-devel - Development files for guile - guile için geliştirme dosyaları - Pliki nagłówkowe guile. - - guile - - - /usr/include - /usr/lib/pkgconfig - /usr/share/aclocal - /usr/bin/guile-snarf - /usr/bin/guile-config - - - - - 2014-11-30 - 2.0.11 + 2013-10-30 + 1.5 Rebuild Yusuf Aydemir yusuf.aydemir@pisilinux.org - - 2014-05-24 - 2.0.11 - Rebuild for gcc. - PisiLinux Community - admins@pisilinux.org - - - 2014-05-11 - 2.0.9 - Release bump. + + 2012-11-24 + 1.5 + First release Marcin Bojara marcin@pisilinux.org - - 2014-02-25 - 2.0.9 - Rebuild Unused - Varol Maksutoğlu - waroi@pisilinux.org - - - 2013-08-27 - 2.0.9 - Clean guile. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-22 - 2.09 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-18 - 2.0.7 - v.bump - PisiLinux Community - admins@pisilinux.org - - - 2012-10-03 - 2.0.6 - First release - Pisi Linux Admins - admins@pisilinux.org - - make - http://www.gnu.org/software/make/make.html + slang + http://www.jedsoft.org/slang/ PisiLinux Community admins@pisilinux.org GPLv2 + Artistic app:console - system.devel - Standard tool to compile source trees - Geleneksel kaynak kod ağaçlarını derleme aracı - Herramienta estándar para compilación de arboles de fuentes - Outil standard de compilation de hiérarchie de sources. Make détermine ce qu'il faut faire pour construire votre programme à partir d'un fichier appelé makefile. Une fois votre programme écrit, il suffit d'éditer un makefile pour lui afin de pouvoir utiliser Make pour le compiler et l'installer. - Standard tool to compile source trees. Make gets its knowledge of how to build your program from a file called the makefile. When you write a program, you should write a makefile for it, so that it is possible to use Make to build and install the program - Geleneksel kaynak kod ağaçlarını derleme aracı. Make, programınızı nasıl derleyeceği konusundaki bilgiyi "makefile" dosyasından alır. Bir uygulama yazdığınızda bunun için "makefile" dosyasını da hazırlamalısınız ki uygulamanız derlenebilsin ve yüklenebilsin. - mirrors://gnu/make/make-4.1.tar.gz + system.base + Console display library used by most text viewer + Bir çok metin gösterici yazılım tarfından kullanılan konsol görüntüleme kütüphanesi + S-Lang est une librarie de programmation multi-plateforme conçue pour permettre aux développeur de développer des logiciels robustes et portables. Elle fournit les mécanismes requis pour développer une application interactive telle que la gestion d'affichages/écrans, entrées clavier, disposition de touches et ainsi de suite. La fonctionnalité la plus attractive de cette librairie reste l'interpréteur slang qui peut être embarqué au sein même d'un programme pour le rendre extensible. + S-Lang is a multi-platform programmer's library designed to allow a developer to create robust multi-platform software. It provides facilities required by interactive applications such as display/screen management, keyboard input, keymaps, and so on. The most exciting feature of the library is the slang interpreter that may be easily embedded into a program to make it extensible. + S-lang, yazılım geliştiricilerin bütün işletim sistemlerinde çalışabilen güçlü uygulamalar geliştirmesine yardımcı olan bir uygulama kitaplığıdır. İnteraktif uygulamalar için ekran yönetimi ve klavye girişi gibi araçlar sunar. Kitaplığın en ilginç özelliği programların içine kolayca gömülebilen ve programı genişletilebilir kılan slang yorumlayıcısıdır. + ftp://ftp.ntua.gr/pub/lang/slang/slang/v2.2/slang-2.2.4.tar.bz2 - gettext - gnuconfig - patch - gc-devel - guile-devel + libpng-devel + libpcre-devel + ncurses-devel + readline-devel + zlib-devel - system/devel/make/pspec.xml + system/base/slang/pspec.xml - make + slang - guile + libpng + libpcre + zlib + /etc /usr/bin - /usr/share/doc + /usr/share/slsh + /usr/lib + /usr/share/doc/slang /usr/share/man - /usr/share/info - /usr/share/locale + + + + slang-devel + Development files for slang + slang için geliştirme dosyaları + system.devel + + slang + + /usr/include - - - - - 2015-02-21 - 4.1 - Version bump - denizgu - denizgu@users.noreply.github.com - - - 2014-05-11 - 4.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-23 - 4.0 - Cleanup, bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-10-24 - 3.82 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - intltool - http://www.gnome.org/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.devel - Utility for internationalizing various kinds of data files - Çeşitli kaynak kod dosyalarından satırları ayıklamak için kullanılan betikler - Scripts d'extraction depuis divers fichiers sources de chaînes traduisibles. - intltool automatically extracts translatable strings from oaf, glade, bonobo ui, nautilus theme, .desktop files, etc. and puts them in the po files. - Çeşitli kaynak kod dosyalarından satırları ayıklamak için kullanılan betikler. - http://source.pisilinux.org/1.0/intltool-0.50.2.tar.gz - - perl - perl-XML-Parser - - system/devel/intltool/pspec.xml - - - intltool - - perl-XML-Parser - - - /usr/bin - /usr/share/aclocal - /usr/share/intltool - /usr/share/man - /usr/share/doc + /usr/lib/pkgconfig + /usr/share/doc/slang/html + /usr/share/man/man3 2014-05-11 - 0.50.2 + 2.2.4 Release bump. Marcin Bojara marcin@pisilinux.org - 2013-08-28 - 0.50.2 - Clean intltool. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-09-19 - 0.50.2 - First release + 2013-10-31 + 2.2.4 + rebuild. Yusuf Aydemir yusuf.aydemir@pisilinux.org + + 2012-08-23 + 2.2.4 + First release + PisiLinux Community + admins@pisilinux.org + - util-macros - http://www.x.org/ + libssh2 + http://www.libssh2.org/ PisiLinux Community admins@pisilinux.org - MIT + BSD library - system.devel - Macros X.Org utilisées pour compiler X.Org - X.Org X11 Autotools macros - X.Org X11 Autotools makroları - X.Org Makros zum Kompilieren von X.Org - X.Org X11 autotools macros are required for building the various packages that comprise the X Window System. - X.Org X11 Autotools makroları, X pencere sistemini oluşturan çeşitli paketleri derlemek için gereklidir. - http://xorg.freedesktop.org/releases/individual/util/util-macros-1.19.0.tar.bz2 - - doc.patch - - system/devel/util-macros/pspec.xml + system.base + A library implementing the SSH2 protocol + SSH2 protokolü için kütüphane + libssh2 is a library implementing the SSH2 protocol as defined by Internet Drafts: SECSH-TRANS, SECSH-USERAUTH, SECSH-CONNECTION, SECSH-ARCH, SECSH-FILEXFER, SECSH-DHGEX, SECSH-NUMBERS, and SECSH-PUBLICKEY. + libssh2, SECSH-TRANS, SECSH-USERAUTH, SECSH-CONNECTION, SECSH-ARCH, SECSH-FILEXFER, SECSH-DHGEX, SECSH-NUMBERS ve SECSH-PUBLICKEY gibi Internet Taslakları tarafından belirlenen SSH2 protokolü için geliştirilmiş bir kütüphanedir. + http://www.libssh2.org/download/libssh2-1.4.3.tar.gz + + openssl-devel + zlib-devel + + system/base/libssh2/pspec.xml - util-macros + libssh2 + + openssl + zlib + - /usr/share/aclocal - /usr/share/pkgconfig + /usr/lib /usr/share/doc - - - 2014-07-11 - 1.19.0 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 1.18.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-07 - 1.18.0 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-10-08 - 1.17.1 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-09-12 - 1.17.1 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-08-19 - 1.17 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - automake - http://www.gnu.org/software/automake/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2+ - app:console - system.devel - A tool for automatically generating Makefile.in files compliant with the GNU Coding Standards - Makefile.am yapılandırma dosyalarından Makefile.in dosyası üreten program - Automake est un outil de génération automatique de Makefiles compatibles avec les standards de Codage GNU. Vous aurez également besoin d'installer le paquet GNU AutoConf - Automake is a tool for automatically generating Makefile.in files compliant with the GNU Coding Standards. - Makefile.am yapılandırma dosyalarından GNU kodlama standartlarına uygun Makefile.in dosyası üreten program. Bununla birlikte Autoconf paketini de yüklemelisiniz. - mirrors://gnu/automake/automake-1.15.tar.xz - - perl - autoconf - gnuconfig - patch - - system/devel/automake/pspec.xml - - automake + libssh2-devel + Development files for libssh2 + libssh2 için geliştirme dosyaları + system.devel - perl - autoconf + libssh2 - /usr/bin - /usr/share/automake-* - /usr/share/aclocal-* - /usr/share/aclocal - /usr/share/info - /usr/share/doc + /usr/include + /usr/lib/pkgconfig /usr/share/man - - 2015-01-28 - 1.15 - Version bump. - Hakan Yıldız - hknyldz93@gmail.com - - - 2014-11-30 - 1.14 - Rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - + 2014-05-11 - 1.14.1 + 1.4.3 Release bump. Marcin Bojara marcin@pisilinux.org - - 2014-03-30 - 1.14.1 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-27 - 1.14 - Clean automake. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-22 - 1.14 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - 2013-02-16 - 1.13.1 + 2013-02-15 + 1.4.3 Version bump Ertan Güven ertan@pisilinux.org - 2012-08-13 - 1.12.2 - First release - Ramazan Utku - admins@pisilinux.org - - - - - - uClibc - http://www.uclibc.org - - PisiLinux Community - admins@pisilinux.org - - LGPLv2.1 - library - system.devel - A C library for embedded Linux - Düşük boyut için optimize edilmiş standart C kitaplığı - uClibc is a C library for developing embedded Linux systems. It is much smaller than the GNU C Library but nearly all applications supported by glibc also work perfectly with uClibc. - uClibc, düşük boyutlu olması için optimize edilmiş bir C kitaplığıdır. Farklı mimarilerde statik bağlanmış ve düşük boyutlu ikili dosyalar oluşturmak için kullanılabilir. - http://www.uclibc.org/downloads/uClibc-0.9.33.2.tar.xz - - mandriva/uClibc-0.9.30.2-add-rpmatch-function.patch - mandriva/uClibc-0.9.30.1-add-scanf-a-flag.patch - pisilinux/linux-3.10-add___kernel_long_and___kernel_ulong.patch - suse/uClibc.fix-pthread-warnings.patch - shared-config.patch - - system/devel/uClibc/pspec.xml - - - uClibc - - /usr/lib/uClibc/sbin/ldconfig - /usr/lib/uClibc/bin - /usr/lib/uClibc - /usr/lib/uClibc/lib - /usr/lib/uClibc/usr/lib - /usr/lib/uClibc/etc - /usr/share/doc - - - System.PackageHandler - - - - uClibc-devel - Development files for uClibc - uClibc için geliştirme başlıkları - - uClibc - - - /usr/lib/uClibc/usr/include - /usr/lib/uClibc/usr/lib/*.o - /usr/lib/uClibc/usr/lib/*.a - /usr/lib/uClibc/usr/bin - /usr/bin - - - - - 2014-05-11 - 0.9.33.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-05 - 0.9.33.2 - build for kernel 3.10 - Erdinç Gültekin - erdincgultekin@pisilinux.org - - - 2013-09-05 - 0.9.33.2 - Add missing method to pakhandler.py - Marcin Bojara - marcin@pisilinux.org - - - 2012-08-19 - 0.9.33.2 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - perl-XML-Parser - http://search.cpan.org/dist/XML-Parser/ - - PisiLinux Community - admins@pisilinux.org - - Artistic - library - system.devel - A Perl extension interface to James Clark's XML parser, expat - James Clark'ın XML ayırıştırıcısına bir Perl uzantısı arayüzü - Una extensión Perl al parseador XML de James Clark, expat - This module provides an interface to James Clark's XML parser, expat. As in expat, a single instance of the parser can only parse one document. Calls to parsestring after the first for a given instance will die. - Bu modül James Clark'ın XML ayrıştırıcısı expat için bir arayüz sağlar. Expat'ta olduğu gibi ayrıştırıcıdan türetilen her nesne sadece bir dosyayı ayrıştırabilir. - Este módulo facilita una interfaz al parser XML de James Clark, expat. Como en expat, una sola instancia del parser puede analizar solamente un documento. Llamadas a parsestring después del primero de una instancia determinada morirán. - mirrors://cpan/authors/id/T/TO/TODDR/XML-Parser-2.41.tar.gz - - expat-devel - perl - - system/devel/perl-XML-Parser/pspec.xml - - - perl-XML-Parser - - expat - perl - - - /usr/share/doc - /usr/lib - /usr/share/man - - - - - 2014-09-12 - 2.41 - Release bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 2.41 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-28 - 2.41 - New release. - Serdar Soytetir - kaptan@pisilinux.org - - - 2011-12-09 - 2.41 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - btyacc - http://www.siber.com/btyacc - - PisiLinux Community - admins@pisilinux.org - - freedist - app:console - system.devel - Backtracking YACC - modified from Berkeley YACC - This is original Berkeley Yacc modified to better fit production environment (and to have less bugs, too). - http://www.siber.com/btyacc/btyacc-3-0.tar.gz - - btyacc-3.0-includes.patch - btyacc-3.0-makefile.patch - - system/devel/btyacc/pspec.xml - - - btyacc - - /usr/bin - /usr/share/man - /usr/share/doc - - - - - 2014-05-11 - 3.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-11-13 - 3.0 - Release bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-10-15 - 3.0 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - klibc - http://www.zytor.com/mailman/listinfo/klibc - - PisiLinux Community - admins@pisilinux.org - - LGPLv2.1 - GPLv2 - library - system.devel - A minimal libc subset for use with initramfs - Küçük bir C kütüphanesi (libc) uyarlaması - klibc ou "espace utilisateur tôt", est une librairie résultante de l'effort pour transférer autant de code d'initialisation de Linux que possible hors du noyau. - klibc, or "early userspace", is library part of an effort which tries to move as much initialization code in Linux as possible out of the kernel. - klibc, sistem başlangıcı için gerekli olan kodların mümkün olduğunca çok kısmını Linux çekirdeği dışına atma hedefiyle oluşturulmuş bir kütüphanedir. - https://www.kernel.org/pub/linux/libs/klibc/2.0/klibc-2.0.3.tar.xz - - perl - kernel-module-headers - - system/devel/klibc/pspec.xml - - - klibc - - /lib - /usr/bin - /usr/lib/klibc/bin - /usr/lib/klibc/include - /usr/lib/klibc/lib - /usr/share/aclocal - /usr/share/doc - /usr/share/man/ - - - klibc.m4 - - - - - 2014-05-11 - 2.0.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-28 - 2.0.3 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-22 - 2.0.2 - Rebuild, cleanup. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-04 - 2.0.2 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - gcc - http://gcc.gnu.org - - Serdar Soytetir - kaptan@pisilinux.org - - GPLv3+ - LGPLv3+ - app:console - library - system.devel - The GNU Compiler Collection, includes C, C++, Objective-C and Fortran compilers - C/C++ ve Fortran derleyicisi - La collection de compilateurs GNU inclus des façades pour le C, C++, Objective-C, Fortran, hava et Ada ainsi que des librairies pour ces langages (libstdc++, libgcj...) - The GNU Compiler Collection includes front ends for C, C++, Objective-C, Fortran, as well as libraries for these languages - C, C++, Objective-C, Fortran programlama dilleri ile bu dillere ait kütüphaneleri içeren, GNU derleyici paketi - ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.9.2/gcc-4.9.2.tar.bz2 - - binutils - bison - gettext - ncurses - zlib - gnuconfig - patch - sed - texinfo - gmp - mpfr - libmpc - ppl - cloog - isl - elfutils - - - pisilinux/64.patch - gcc-4.9-isl-0.13-hack.patch - pisilinux/gcc-4.8-filename-output.patch - pisilinux/gcc_47_based-record_gcc_options.patch - - system/devel/gcc/pspec.xml - - - libquadmath - The GNU Fortran Compiler Quadmath Runtime Library - library - system.base - - /usr/lib/libquadmath.so* - /usr/lib/libquadmath.spec* - /usr/lib32/libquadmath.so* - /usr/lib32/libquadmath.spec* - /usr/share/info/libquadmath.info - - - - libgcc - Contains a shared library of support routines used by GCC's runtime, and thus by every program on the system - library - system.base - - /etc - /usr/lib/libstdc++.so* - /usr/lib/libgcc_s.so* - /usr/lib32/libstdc++.so* - /usr/lib32/libgcc_s.so* - /usr/share/gcc-* - /usr/share/gdb - - - - libgomp - Contains GCC shared support library which is needed for OpenMP 2.5 support - library - - /usr/lib/libgomp.so* - /usr/lib/libgomp.spec* - /usr/lib32/libgomp.so* - /usr/lib32/libgomp.spec* - /usr/share/info/libgomp.info - - - - libgfortran - Contains GCC shared support library for gfortran - library - - libquadmath - - - /usr/lib/libgfortran.so* - /usr/lib32/libgfortran.so* - - - - libobjc - Contains GCC shared support library for objc - library - - /usr/lib/libobjc.so* - /usr/lib32/libobjc.so* - - - - gcc-l10n - Contains available GCC localization files, includes also turkish translations - system.locale - - gcc - - - /usr/share/locale - - - - gcc - - gmp - isl - mpfr - cloog - libmpc - - - /lib - /usr/bin - /usr/lib - /usr/lib32 - /usr/libexec - /usr/include - /usr/share/man - /usr/share/info - - - gfilt - gSTLFilt.pl - - - - - 2014-11-28 - 4.9.2 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-09-12 - 4.9.1 - Rebuild for new glibc. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-09-06 - 4.9.1 - Version bump, cleanup. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 4.9.0 - Rebuild, add patch. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-04-28 - 4.9.0 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-04-01 - 4.8.2 - Rebuild for dependency changes. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-11-11 - 4.8.2 - backport ICE fix - http://gcc.gnu.org/bugzilla//show_bug.cgi?id=56710 - commit 3d1f8279 - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57653 - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-10-22 - 4.8.2 - Cleanup, version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-14 - 4.8.1 - Rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-07-23 - 4.8.1 - Version bump, cleanup patches. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-10-14 - 4.7.2 - Cleanup package, add some patches. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-10-14 - 4.7.2 + 2012-06-12 + 1.4.2 First release Erdem Artan admins@pisilinux.org + + + e2fsprogs + http://e2fsprogs.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + Standard ext2/3/4 filesystem utilities + Standart ext2, ext3, ext4 dosya sistemi uygulamaları + e2frprogs fournit les outils de système de fichier à utiliser avec les systèmes de fichier de type ext2. Il prend également en charge les système de fichier de type ext3/4 avec support de la journalisation. + e2fsprogs provides the filesystem utilities for use with the ext2 filesystem. It also supports the ext3/4 filesystem with journaling support. + e2fsprogs ext2 dosya sistemi için standart dosya sistemi uygulamaları sağlar. ext3/4 dosya sistemlerinin günlüğe kaydetme özelliklerini de destekler. + mirrors://sourceforge/e2fsprogs/e2fsprogs-1.42.12.tar.gz + + libutil-linux-devel + libutil-linux + gettext + util-linux + + + ntfs-3g.patch + e2fsprogs-1.41.8-strip-me.patch + + system/base/e2fsprogs/pspec.xml + + + e2fsprogs + + libutil-linux + + + /etc + /bin + /usr/bin + /lib + /usr/lib + /sbin + /usr/sbin + /usr/share/et + /usr/share/ss + /usr/share/locale + /usr/share/info + /usr/share/man + /usr/share/doc + + + + e2fsprogs-devel + Development files for e2fsprogs + e2fsprogs için geliştirme dosyaları + system.devel + + e2fsprogs + + + /usr/include + /usr/lib/pkgconfig + /usr/share/man/man3 + + + + + 2015-04-30 + 1.42.12 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-07-10 + 1.42.11 + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 1.42.9 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-03 + 1.42.9 + Version bump + PisiLinux Community + admins@pisilinux.org + + + 2013-10-28 + 1.42.8 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-07-26 + 1.42.8 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-02-15 + 1.42.7 + New version + Ertan Güven + ertan@pisilinux.org + + + 2012-11-25 + 1.42.6 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + dbus-glib + http://dbus.freedesktop.org/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + AFL-2.1 + library + system.base + Glib bindings for D-Bus + D-Bus için GLib bağlayıcıları + dbus-glib is an add-on library to integrate the standard D-Bus library with the GLib thread abstraction and main loop. + dbus-glib, standart D-Bus kitaplığını GLib ana döngüsüyle bütünleştirmek için kullanılan bir kitaplıktır. + http://dbus.freedesktop.org/releases/dbus-glib/dbus-glib-0.104.tar.gz + + dbus-devel + glib2-devel + libpcre-devel + expat-devel + libxml2 + + system/base/dbus-glib/pspec.xml + + + dbus-glib + + dbus + glib2 + expat + libxml2 + + + /usr/bin + /usr/libexec/dbus-bash-completion-helper + /usr/lib + /usr/share/doc + /usr/share/man/man1 + /etc/bash_completion.d + /usr/share/bash-completion + /usr/libexec + + + + dbus-glib-devel + Development files for dbus-glib + dbus-glib için geliştirme dosyaları + system.devel + + dbus-glib + dbus-devel + glib2-devel + + + /usr/include/dbus-1.0 + /usr/lib/pkgconfig + /usr/share/man/man3 + + + + + 2015-05-12 + 0.104 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-04-01 + 0.102 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-18 + 0.102 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-11 + 0.100.1 + Güncellendi. + PisiLinux Community + admins@pisilinux.org + + + 2012-08-23 + 0.100 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + run-parts + http://packages.qa.debian.org/d/debianutils.html + + PisiLinux Community + osman.erkan@yandex.com + + GPLv2+ + system.base + run scripts or programs in a directory + run scripts or programs in a directory + https://sources.archlinux.org/other/run-parts/debianutils_4.4.tar.gz + system/base/run-parts/pspec.xml + + + run-parts + + /usr/share/man + /usr/bin + /usr/sbin + + + + + 2015-04-11 + 4.4 + Release bump, fix source url + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-02 + 4.4 + rm unneeded files. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-04-01 + 4.4 + Release bump for component change. + PisiLinux Community + osman.erkan@yandex.com + + + 2014-03-02 + 4.4 + First Release + PisiLinux Community + osman.erkan@yandex.com + + + + + + biosdevname + http://linux.dell.com/biosdevname/ + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv2 + app:gui + system.base + Biosdevname is a udev helper utility developed + Biosdevname is a udev helper utility developed by Dell and released under the GNU General Public License (GPL). It provides a consistent naming mechanism for network devices based on their physical location as suggested by the system BIOS. + http://linux.dell.com/biosdevname/biosdevname-0.6.1/biosdevname-0.6.1.tar.gz + + pciutils-devel + glibc-devel + zlib-devel + + system/base/biosdevname/pspec.xml + + + biosdevname + + pciutils + + + /sbin + /lib/udev/rules.d + /usr/sbin + /usr/share/doc + /usr/share/man + + + + + 2015-03-30 + 0.6.1 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 0.6.0 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 0.4.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-19 + 0.4.1 + Rebuild + Stefan Gronewold(groni) + groni@pisilinux.org + + + 2012-10-05 + 0.4.1 + First release + PisiLinux Community + admins@pisilinux.org + + + pcmciautils @@ -4868,9 +3070,9 @@ Verschiedene Werkzeuge, um mit dem PCMCIA Bus umzugehen pcmciautils contains the initialization tools necessary to allow the PCMCIA subsystem to behave as every other hotpluggable bus system. pcmciautils PCMCIA altyapısının tak/çıkar veriyolları gibi davranmasını sağlayan araçları içerir. - http://ftp.task.gda.pl/vol/d0s0/ftp.kernel.org/pub/linux/utils/kernel/pcmcia/pcmciautils-018.tar.bz2 + https://sources.archlinux.org/other/pcmciautils/pcmciautils-018.tar.xz - sysfsutils + sysfsutils-devel system/base/pcmciautils/pspec.xml @@ -4919,6 +3121,901 @@ + + + libffi + http://sourceware.org/libffi + + PisiLinux Community + admins@pisilinux.org + + BSD + library + system.base + A portable foreign function interface library + Yabancı işlev arayüzleri için taşınabilir bir kitaplık + The libffi library provides a portable, high level programming interface to various calling conventions. + libffi kitaplığı, çeşitli işlev çağırma konvansiyonları için taşınabilir ve yüksek düzeyli bir programlama arayüzü sunar. + ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz + system/base/libffi/pspec.xml + + + libffi + + /usr/lib/libffi.* + /usr/share/doc + + + + libffi-devel + Development files for libffi + libffi için geliştirme dosyaları + system.devel + + libffi + + + /usr/lib/libffi-* + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + /usr/share/info + /usr/share/man + + + + libffi-32bit + 32-bit shared libraries for libffi + libffi için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + libffi + + + /usr/lib32/libffi.* + /usr/lib32/libffi-* + + + + + 2014-12-02 + 3.2.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 3.0.13 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-31 + 3.0.13 + Version bump, clean libffi. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-17 + 3.0.12 + New Release + PisiLinux Community + admins@pisilinux.org + + + 2012-07-11 + 3.0.11 + First release + Erdem Artan + admins@pisilinux.org + + + + + + help2man + http://www.gnu.org/software/help2man + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + GNU utility to convert program --help output to a man page + Geleneksel --help çıktılarını man sayfalarına dönüştüren bir GNU yazılımı + Help2man is a tool which generate man page from help text of programs. + Help2man programların help çıktılarını man sayfalarına dönüştüren bir araçtır. + http://ftp.gnu.org/gnu/help2man/help2man-1.46.4.tar.xz + + perl-Locale-gettext + + system/base/help2man/pspec.xml + + + help2man + + perl-Locale-gettext + + + /usr/bin + /usr/lib + /usr/share/doc + /usr/share/info + /usr/share/locale + /usr/share/man + + + + + 2015-02-12 + 1.46.4 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + + + 2014-05-11 + 1.41.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-01-14 + 1.41.1 + New release + PisiLinux Community + admins@pisilinux.org + + + 2011-09-07 + 1.40.4 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + polkit + http://www.freedesktop.org/wiki/Software/PolicyKit + + PisiLinux Community + admins@pisilinux.org + + LGPLv2+ + service + library + app:console + system.base + PolicyKit Authorization Framework + Sistem bileşenleri için erişim politikası servisi + polkit est un cadre de développement (framework) pour définir des politiques à appliquer à des composants du système ainsi que fournir à des parties du bureau la possibilité de les configurer. + polkit is a toolkit for defining and handling authorizations. It is used for allowing unprivileged processes to speak to privileged processes. + polkit, sistem genelindeki bileşenlerin ve masaüstü bileşenlerinin ayarlayabileceği şekilde ilkeler tanımlamak için araçlardan oluşur. + http://www.freedesktop.org/software/polkit/releases/polkit-0.112.tar.gz + + pam-devel + dbus-devel + glib2-devel + expat-devel + dbus-glib-devel + spidermonkey-devel + intltool + + + disable-docs.patch + use-system-locale-in-gobject-api.diff + + system/base/polkit/pspec.xml + + + polkit-devel + Development headers for polkit + polkit geliştirme başlıkları + system.devel + + polkit + glib2-devel + + + /usr/include + /usr/lib/pkgconfig + + + + polkit + + pam + dbus + glib2 + expat + dbus-glib + spidermonkey + + + /etc + /usr/lib + /usr/libexec + /usr/bin + /usr/sbin + /usr/share/locale + /usr/share/polkit-1 + /usr/share/dbus-1 + /usr/share/gir-1.0 + /var/lib/polkit-1 + /lib/systemd + /usr/share/man + /usr/share/doc + + + man/pklocalauthority.8 + man/polkit.8 + man/polkitd.8 + man/pkaction.1 + man/pkcheck.1 + man/pkexec.1 + 70-desktop-policy.conf + + + + + 2015-05-08 + 0.112 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-06-10 + 0.112 + Release bump. + Alihan Öztürk + alihan@pisilinux.org + + + 2014-05-11 + 0.112 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-01 + 0.112 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-28 + 0.111 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-02-11 + 0.110 + Güncellendi. + PisiLinux Community + admins@pisilinux.org + + + 2013-01-11 + 0.107 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + util-linux + http://userweb.kernel.org/~kzak/util-linux-ng/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + library + system.base + Divers utilitaires Linux utiles. + Various useful Linux utilities + Çeşitli kullanışlı Linux araçları + The util-linux package contains a large variety of low-level system utilities that are necessary for a Linux system to function. + util-linux paketi, bir Linux sisteminin işlevsel olması için gerekli olan birçok düşük seviye sistem uygulamasını içerir. + https://www.kernel.org/pub/linux/utils/util-linux/v2.26/util-linux-2.26.1.tar.xz + + zlib-devel + eudev-devel + python-devel + shadow + ncurses-devel + libcap-ng-devel + glibc-32bit + + + upstream/util-linux-ng-2.21-login-lastlog.patch + + system/base/util-linux/pspec.xml + + + util-linux + + libutil-linux + zlib + perl + ncurses + eudev + libcap-ng + + + /etc + /bin + /sbin + /usr/bin + /usr/sbin + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/misc + /usr/share/getopt + /usr/share/bash-completion/completions + /usr/share/locale + + + util-linux + + + + uuidd + Helper daemon to guarantee uniqueness of time-based UUIDs + Zaman tabanlı UUID'lerin benzersizliğini garantileyen sistem hizmeti + service + app:console + util.misc + + libutil-linux + + + /usr/bin/uuidgen + /usr/sbin/uuidd + /usr/lib/tmpfiles.d/uuidd.conf + /usr/share/man/man1/uuidgen.1 + /usr/share/man/man8/uuidd.8 + + + uuidd + + + uuidd.tmpfiles + + + + libutil-linux + util-linux runtime library + util-linux için kitaplıklar + library + + python + + + /lib + /usr/lib + /usr/share/man/man3/uuid* + /usr/share/man/man3/libblkid* + /usr/share/man/man8/blkid* + + + libblkid + libuuid + + + libblkid + libuuid + + + + libutil-linux-devel + libutil-linux header files + util-linux kitaplıkları için başlık dosyaları + header + system.devel + + libutil-linux + + + /usr/include/ + /usr/lib/pkgconfig/*.pc + + + libblkid-devel + libuuid-devel + + + libblkid-devel + libuuid-devel + + + + libutil-linux-32bit + 32-bit shared libraries for libutil-linux + util-linux için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + glibc-32bit + + + /usr/lib32/ + + + libblkid-32bit + libuuid-32bit + + + libblkid-32bit + libuuid-32bit + + + + + 2015-04-29 + 2.26.1 + Version bump, change pisi + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-04-01 + 2.26.1 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 2.24.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-08 + 2.24.1 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-20 + 2.24 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-27 + 2.22.2 + Move pc files to devel pack, rebuild + PisiLinux Community + admins@pisilinux.org + + + 2013-07-26 + 2.22.2 + Release bump for rebuild. + PisiLinux Community + admins@pisilinux.org + + + 2013-01-14 + 2.22.2 + New release + PisiLinux Community + admins@pisilinux.org + + + 2012-11-17 + 2.22.1 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + which + http://www.xs4all.nl/~carlo17/which/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + Prints the location of specified executable in your path + Verilen komutun çalıştırma yolundaki önceliğe göre yerini gösterir + which, localise un programme dans le chemin de l'utilisateur. + which , Locates a program file in the user's path. + which, kullanıcı dizinindeki program dosyalarının yarini bulur. + which, findet eine Anwendungsdatei im Benutzerverzeichnis + mirrors://gnu/which/which-2.21.tar.gz + system/base/which/pspec.xml + + + which + + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/info + + + + + 2015-04-06 + 2.21 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + + + 2014-05-11 + 2.20 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 2.20 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2010-10-11 + 2.20 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + json-c + http://oss.metaparadigm.com/json-c + + PisiLinux Community + admins@pisilinux.org + + MIT + library + system.base + A JSON implementation in C + C dilinde JSON gerçeklemesi + json-c implements a reference counting object model that allows you to easily construct JSON objects in C, output them as JSON formatted strings and parse JSON formatted strings back into the C representation of JSON objects. + json-c, C dilinde kolayca JSON nesneleri yaratılmasını sağlayan bir referans sayma modeli gerçekleyen bir kitaplıktır. + https://github.com/json-c/json-c/archive/json-c-0.12-20140410.tar.gz + + wno-werror.patch + + system/base/json-c/pspec.xml + + + json-c + + /usr/share/doc + /usr/share/man + /usr/lib + + + + json-c-devel + Development files for json-c + json-c için geliştirme dosyaları + system.devel + + json-c + + + /usr/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + + + + json-c-32bit + 32-bit shared libraries for json-c + emul32 + emul32 + + glibc-32bit + + + /usr/lib32 + + + + + 2015-04-30 + 0.12 + Version bump and security update(CVE-2013-6371, CVE-2013-6370). + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 0.11 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 0.11 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-07-09 + 0.11 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2012-04-02 + 0.9 + First release + Erdinç Gültekin + admins@pisilinux.org + + + + + + urlgrabber + http://urlgrabber.baseurl.org/ + + PisiLinux Community + admins@pisilinux.org + + LGPLv2.1 + library + system.base + High level cross-protocol url-grabber library for Python + Python için yüksek seviyeli, platform bağımsız bir url-grabber kütüphanesi + urlgrabber provides a clean library interface to protocol-independant file-access for Python programs + urlgrabber Python uygulamaları için protokol bağımsız dosya erişimi sağlayan temiz bir kütüphanedir. + http://urlgrabber.baseurl.org/download/urlgrabber-3.10.1.tar.gz + + python + + system/base/urlgrabber/pspec.xml + + + urlgrabber + + python + pycurl + + + /usr/lib + /usr/libexec + /usr/share/doc + + + + + 2014-05-11 + 3.10.1 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2013-10-28 + 3.10 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-03-12 + 3.9.1 + Fix pisi https issue + Pisi Linux Admins + marcin@pisilinux.org + + + 2010-10-11 + 3.9.1 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + readline + http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.base + Another cute console display library + Diğer bir şirin konsol gösterim kütüphanesi + La librairie GNU Readline fourni un ensemble de fonctions utilisables par des applications permettant aux utilisateurs d'éditer les lignes de commandes en cours de frappe. Les modes d'éditions Emacs et vi sont disponibles. La librairie Readline inclus des fonctions supplémentaires de mémorisation de la liste de commandes entrées précédemment, afin de le rappeler et éventuellement les rééditer, ainsi que l'expansion d'historiques de commandes précédentes à la mode csh. + The GNU Readline library provides a set of functions for use by applications that allow users to edit command lines as they are typed in. Both Emacs and vi editing modes are available. The Readline library includes additional functions to maintain a list of previously-entered command lines, to recall and perhaps reedit those lines, and perform csh-like history expansion on previous commands. + GNU Readline kütüphanesi uygulamalara sanki kullanıcılar kendileri yazıyormuş gibi komut satırı girişlerini düzenleme imkanı veren işlev setini sunar. Readline kütüphanesi daha önce girilmiş bir komut satırları listesini düzenleme, tekrar çağırma ve belki de bu satırları tekrar düzenleme ve csh tipi geçmiş bilgisi genişletmelerindeki önceki komutları yürütme imkanı sağlayan ek işlevler sağlar. + mirrors://gnu/readline/readline-6.3.tar.gz + + ncurses-devel + + + readline63-001.patch + readline63-002.patch + readline63-003.patch + + system/base/readline/pspec.xml + + + readline + + ncurses + + + /usr/lib + /usr/share/doc + /usr/share/man + /usr/share/info + + + + readline-devel + Development files for readline + readline için geliştirme dosyaları + system.devel + + glibc-32bit + + + readline + + + /usr/include + /usr/share/man/man3 + + + + readline-32bit + 32-bit shared libraries for readline + readline için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + ncurses-32bit + + + readline + ncurses-32bit + glibc-32bit + + + /usr/lib32 + + + + + 2014-05-11 + 6.3 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-05 + 6.3 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-31 + 6.2_004 + Clean readline. + Marcin Bojara + marcin@pisilinux.org + + + 2012-08-31 + 6.2 + First release + Erdem Artan + admins@pisilinux.org + + + + + + unzip + ftp://ftp.info-zip.org/pub/infozip/UnZip.html + + PisiLinux Community + admins@pisilinux.org + + Info-ZIP + app:console + system.base + Unzipper for pkzip-compressed files + pkzip ile sıkıştırılmış dosyalar için açıcı + Unzip nous permet d'extraires des archives compressées aux format .zip (également appelées "fichiers zip"). + UnZip enables us to extract archives compressed in .zip format (also called "zipfiles"). + UnZip, zip formatında sıkıştırılmış dosyaları açmamızı sağlar. + mirrors://sourceforge/infozip/unzip610b.zip + + unzip-6.0-attribs-overflow.patch + unzip-6.0-exec-shield.patch + unzip-6.0-close.patch + + system/base/unzip/pspec.xml + + + unzip + + /usr/bin + /usr/share/doc + /usr/share/man + + + + + 2014-05-11 + 610b + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-29 + 610b + Rebuild + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-01-14 + 610b + New release + PisiLinux Community + admins@pisilinux.org + + + 2010-10-11 + 6.0 + First release + Pisi Linux Admins + admins@pisilinux.org + + + snappy @@ -4937,6 +4034,7 @@ http://snappy.googlecode.com/files/snappy-1.1.1.tar.gz lzo-devel + zlib-devel snappy-unittest.patch @@ -4945,6 +4043,9 @@ snappy + + libgcc + /usr/lib /usr/share/doc @@ -4980,78 +4081,258 @@ - comar - http://www.pisilinux.org + bzip2 + http://www.bzip.org/ PisiLinux Community admins@pisilinux.org - GPLv2 - service + BZIP2 + app:console system.base - Manages system configuration - Sistem yapılandırmasını yönetir - Les programmes Pisi Linux sont mis sous forme de paquets à l'aide de petits scripts. Ces derniers les configure afin qu'ils s'intègrent entre eux et avec le système. Çomar est l'outil qui gère et exécute ces scripts. - Pisi Linux programs are packaged with small scripts which configures them to entegrate with system and each other. Çomar is the tool which manages and executes these scripts. - Pisi Linux yazılımları, birbirleri ve sistemle otomatik olarak uyum sağlayabilmek için yanlarında ufak programcıklar ile paketlenmektedir. Bu programcıkların yönetimi ve işletilmesi Çomar aracı tarafından yapılmaktadır. - Pisi Linux Programme werden mit einem kleinen Skript paketiert, welches sie konfiguriert, um die Integrität mit dem System und anderen Programmen sicherzustellen. Comar ist das Werkzeug, das diese Skripte verwaltet und ausführt. - http://source.pisilinux.org/1.0/comar-3.0.3.tar.bz2 - - dbus - python - + A high-quality data compressor + Yüksek kaliteli bir veri sıkıştırma uygulaması + bzip2 est un compresseur de données de très grand qualité. Il compresse typiquement les fichiers à un ratio entre 10 et 15% des meilleurs techniques disponibles (la famille des compresseurs statistiques de famille PPM) tout en étant environ deux fois plus rapide à la compression et six fois plus rapide à la décompression. + bzip2 is high-quality data compressor. It typically compresses files to within 10% to 15% of the best available techniques (the PPM family of statistical compressors), whilst being around twice as fast at compression and six times faster at decompression. + bzip2 yüksek kaliteli bir veri sıkıştırma programıdır. Program genellikle dosyaları mümkün olan en iyi teknikler ile (PPM istatistiksel sıkıştırıcı ailesi) %10 - %15'e kadar sıkışıtırabilmektedir. Sıkıştırma işleminde iki kata kadar hızlı iken açma hızında yaklaşık altı kat daha hızlıdır. + bzip2 ist ein hochwertiger Daten-Kompressor. Es komprimiert Dateien üblicherweise auf 10% bis 15% der bestmöglichen Techniken (die PPM Familie der statistischen Kompressoren), während es ungefähr doppelt so schnell komprimiert und sechsfach schneller extrahiert + http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz - run_dir.patch - fix-flags.patch - update-system-manager-model.patch + bzip2-1.0.2-progress.patch + bzip2-1.0.4-bzip2recover.patch + bzip2-1.0.4-man-links.patch + bzip2-1.0.6-saneso.patch + manpath.patch - system/base/comar/pspec.xml + system/base/bzip2/pspec.xml - comar - - dbus - python - polkit - + bzip2 - /usr/bin - /usr/sbin - /etc - /usr/share/dbus-1/system-services - /usr/share/polkit-1/actions - /usr/share/doc/ - /var/db + /bin + /lib + /usr/lib + /usr/share/doc + /usr/share/man + /usr/include - - System.Package - - 2014-08-19 - 3.0.3 - Fix run dir path. - Marcin Bojara - marcin@pisilinux.org + 2014-09-30 + 1.0.6 + Rebuild,cleanup, enable tests. + Serdar Soytetir + kaptan@pisilinux.org 2014-05-11 - 3.0.3 + 1.0.6 Release bump. Marcin Bojara marcin@pisilinux.org - 2013-08-31 - 3.0.3 - Release bump, clean comar. + 2013-08-28 + 1.0.6 + Release bump,clean bzip2. Serdar Soytetir kaptan@pisilinux.org - 2011-05-18 - 3.0.3 + 2010-10-11 + 1.0.6 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + ntfs-3g + http://www.tuxera.com/community/ntfs-3g-download + + PisiLinux Community + admins@pisilinux.org + + GPLv2+ + LGPLv2+ + library + app:console + system.base + Userspace driver for NTFS read/write support + NTFS dosya sistemlerine okuma/yazma erişimi için bir sürücü + ntfs-3g allows regular users read/write access to NTFS filesystems. + ntfs-3g kullanıcıların NTFS biçimli disk bölümlerine hem okuma hem yazma erişimi yapabilmesine imkan veren bir sürücüdür. + http://tuxera.com/opensource/ntfs-3g_ntfsprogs-2015.3.14.tgz + + ntfsprogs_destdir.patch + + system/base/ntfs-3g/pspec.xml + + + ntfs-3g + + fuse + glibc + + + /bin + /sbin + /lib + /usr/lib + /usr/include + /usr/lib/pkgconfig + /usr/share/doc/ntfs-3g + /usr/share/man/man8/mount* + /usr/share/man/man8/ntfs-3g* + + + + ntfsprogs + Userspace tools for NTFS filesystems + NTFS dosya sistemi için kullanıcı araçları + Userspace tools for NTFS filesystems. The goals of the Linux-NTFS project are to develop reliable and full-featured access to NTFS by the Linux kernel driver and to provide a wide collection of NTFS utilities. + NTFS dosya sistemi için kullanıcı araçları içerir. Bu araçların amacı Linux çekirdeğine NTFS dosya sistemlerine güvenilir ve tam erişim sağlayacak NTFS araçlarını sağlamaktır. + hardware.disk + + ntfs-3g + fuse + glibc + libutil-linux + + + /sbin/mkfs.ntfs + /usr/bin + /usr/sbin + /usr/share/doc/ntfsprogs + /usr/share/man/man8 + + + + + 2015-05-06 + 2015.3.14 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-12-13 + 2014.2.15 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 2013.1.13 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-30 + 2013.1.13 + Rebuild + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-01-30 + 2013.1.13 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2012-11-14 + 0.0_2012.01.15 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + tcp-wrappers + http://ftp.porcupine.org/pub/security/index.html + + PisiLinux Community + admins@pisilinux.org + + BSD + app:console + system.base + TCP Wrappers + TCP Wrappers + Avec ce paquet, vous pouvez surveiller et filtrer les requêtes entrante pour les services réseaux SYSTAT, FINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK et autres. Il supporte à la fois les canaux de communication (sockets) de type 4.3BSD et TLI de type System V.4. + With this package you can monitor and filter incoming requests for the SYSTAT, FINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK, and other network services. It supports both 4.3BSD-style sockets and System V.4-style TLI. + Bu paket ile birlikte SYSTAT, FINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK ve diğer ağ servisleri için gelen istekleri izleyebilir ve süzebilirsiniz. Program 4.3BSD-tipi soketler ve System V.4-tipi TLI'ın ikisini de destekler. + http://ftp.porcupine.org/pub/security/tcp_wrappers_7.6.tar.gz + + sed + + + Makefile-Pisi.patch + tcp-wrappers-7.6-makefile.patch + tcp_wrappers-7.6-ldflags.patch + 01_all_redhat-bug11881.patch + 02_all_redhat-bug17795.patch + 03_all_wildcard.patch + 04_all_fixgethostbyname.patch + 07_all_sig.patch + 08_all_strerror.patch + 09_all_gcc-3.4.patch + 10_all_more-headers.patch + tcp-wrappers-7.6-ipv6-1.14.diff + tcp-wrappers-7.6-shared.patch + host.allow.example.patch + match-port.patch + + system/base/tcp-wrappers/pspec.xml + + + tcp-wrappers + + /usr/sbin + /usr/lib + /lib + /etc + /usr/share/man + /usr/share/doc + + + hosts.allow + hosts.deny + + + + tcp-wrappers-devel + Development files for tcp-wrappers + tcp-wrappers için geliştirme dosyaları + system.devel + + tcp-wrappers + + + /usr/include + /usr/share/man/man3 + + + + + 2014-05-11 + 7.6 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2010-10-11 + 7.6 First release Pisi Linux Admins admins@pisilinux.org @@ -5060,33 +4341,34 @@ - piksemel - http://pisilinux.org + plyvel + https://pypi.python.org/pypi/plyvel - PisiLinux Community - admins@pisilinux.org + Alihan Öztürk + alihan@pisilinux.org - GPLv2 - library + BSD + app:console system.base - Python binding for iksemel - iksemel için python desteği - Un analyseur XML simple, rapide, petit et robuste pour Python basé sur iksemel. - A simple, fast, small and robust XML parser for Python, based on iksemel. - Python için basit, hızlı, ufak ve sağlam bir XML ayrıştırıcısı, iksemel tabanlıdır. - http://source.pisilinux.org/1.0/piksemel-1.3.1.tar.gz + Plyvel, a fast and feature-rich Python interface to LevelDB. + Plyvel, LevelDB için, hızlı ve zengin özellikli Python arabirimi. + Plyvel has a rich feature set, high performance, and a friendly Pythonic API. + Plyvel zengin özelliklere sahip bir set, yüksek performanslı, ve kullanıcı dostu bir Pythonic API. + https://pypi.python.org/packages/source/p/plyvel/plyvel-0.8.tar.gz - python + cython + python-devel + leveldb-devel + python-setuptools - - symbol-visibility.patch - - system/base/piksemel/pspec.xml + system/base/plyvel/pspec.xml - piksemel + plyvel + libgcc python + leveldb /usr/lib @@ -5094,23 +4376,1867 @@ + + 2014-06-08 + 0.8 + Rebuild. + Aydın Demirel + aydin.demirel@pisilinux.org + + + 2014-06-01 + 0.8 + First release. + Alihan Öztürk + alihan@pisilinux.org + + + + + + dbus-python + http://dbus.freedesktop.org/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + AFL-2.1 + library + system.base + D-Bus Python bindings + D-Bus için Python bağlayıcıları + dbus-python provides a Python module which wraps the D-Bus programming API. + http://dbus.freedesktop.org/releases/dbus-python/dbus-python-1.2.0.tar.gz + + python-devel + python3 + dbus-devel + dbus-glib-devel + glib2-devel + libpcre-devel + + + suppress-warnings.patch + + system/base/dbus-python/pspec.xml + + + dbus-python-common + Common dbus-python files shared between dbus-python and dbus-python3 + + dbus + + + /usr/include + /usr/lib/pkgconfig + /usr/share/doc + + + + dbus-python + + dbus-python-common + python + dbus + glib2 + dbus-glib + + + /usr/lib/python2* + + + + dbus-python3 + D-Bus Python3 bindings + programming.language.python + + dbus-python-common + python3 + dbus + glib2 + dbus-glib + + + /usr/lib/python3* + + + + + 2015-04-01 + 1.2.0 + Release bump. + Kamil Atlı + suvarice@gmail.com + + + 2014-05-11 + 1.2.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 1.2.0 + rebuild. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-23 + 1.2.0 + Version bump. Remove dbus-devel from runtime dependencies. + Marcin Bojara + marcin@pisilinux.org + + + 2013-04-25 + 1.1.1 + Dep Fixed. + PisiLinux Community + admins@pisilinux.org + + + 2012-11-10 + 1.1.1 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + acl + http://acl.bestbits.at/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2+ + LGPLv2.1 + app:console + library + system.base + Utilitaires, librairies et fichiers d'entête de liste de contrôle d'accès. + Access control list utilities + Erişim denetim listesi için çeşitli araçlar + acl contains the getfacl and setfacl utilities needed for manipulating access control lists along with the needed libraries. + acl erişim denetim listelerini yönetmeye yarayan getfacl ve setfacl araçlarıyla gerekli kütüphaneleri içeren bir pakettir. + http://download.savannah.gnu.org/releases-noredirect/acl/acl-2.2.52.src.tar.gz + + attr-devel + + system/base/acl/pspec.xml + + + acl + + attr + + + /bin + /lib + /usr/share/locale + /usr/share/doc + /usr/share/man + + + + acl-devel + Development files for acl + acl için geliştirme dosyaları + system.devel + + acl + + + /usr/include + /usr/share/man/man3 + + + + + 2015-03-15 + 2.2.52 + fix build deps. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-09-30 + 2.2.52 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + 2014-05-11 - 1.3.1 + 2.2.52 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-28 + 2.2.52 + Version bump, clean acl. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-06-04 + 2.2.51 + First release + Erdem Artan + admins@pisilinux.org + + + + + + gawk + http://www.gnu.org/software/gawk/gawk.html + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + GNU awk pattern-matching language + Metin işleme uygulaması olan awk'ın GNU versiyonu + L'outil awk interprète un langage de programmation spécifique permettant d'effectuer les tâches de modifications simples de données en quelques lignes de code. Il vous permet de faire des changements dans différents fichiers texte lorsqu'un certain patron apparaît ou d'extraire des données de fragments de lignes tout en laissant de côté le reste. Gawk est l'implémentation GNU d'awk. + The awk utility interprets a special-purpose programming language that makes it possible to handle simple data-reformatting jobs with just a few lines of code. It helps you to make changes in various text files wherever certain patterns appear, or extract data from parts of certain lines while discarding the rest. Gawk is the GNU implementation of awk. + awk uygulaması az bir kod ile basit veri formatı düzenleme işlerinizi yapabilmenize olanak sağlayan özel amaçlı bir programlama dilidir. Uygulama birçok farklı metin dosyası içinde aradığınız parçaları bulup değiştirmenize veya diğer satırlardan ayırarak işlemenize yardımcı olur. Gawk programı awk'ın GNU sürümüdür. + http://ftp.gnu.org/gnu/gawk/gawk-4.1.1.tar.xz + + gettext-devel + + + gawk-4.1.1-sandbox_issue.patch + gawk-4.1.1-sigpipe.patch + + system/base/gawk/pspec.xml + + + gawk + + readline + gmp + mpfr + + + /usr/bin + /usr/libexec + /usr/lib/gawk + /usr/include + /usr/share/awk + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/locale + + + + + 2014-05-11 + 4.1.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-03-10 + 4.1.0 + Release bump for update eror + Burak Fazıl Ertürk + burakerturk@pisilinux.org + + + 2014-01-05 + 4.1.0 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-26 + 4.0.2 + Fix dep, release bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-14 + 4.0.2 + Version bump + Ertan Güven + ertan@pisilinux.org + + + 2012-08-23 + 4.01 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + baselayout + http://www.pisilinux.org + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + library + data + system.base + Filesystem baselayout + Dosya sisteminin temel planı + Ce paquet crée la hiérarchie du système de fichier principal de Pisi Linux. + baselayout creates the Pisi Linux Linux main filesystem hierarchy. + Bu paket, Pisi Linux dosya sisteminin temelini oluşturur. + http://source.pisilinux.org/1.0/baselayout-3.10.0.tar.gz + system/base/baselayout/pspec.xml + + + baselayout + + pypolkit + + + /bin + /sbin + /lib* + /etc + /etc/pisilinux-release + /media + /boot + /proc + /home + /mnt + /opt + /dev + /run + /sys + /srv + /tmp + /usr + /var + /usr/lib/tmpfiles.d/baselayout.conf + + + System.PackageHandler + System.Package + User.Manager + Network.Stack + + + baselayout.conf + services + protocols + sysctl.conf + pisilinux-release + start-stop-daemon.8 + + + + + 2015-03-04 + 3.10.0 + Release bump + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-07-16 + 3.10.0 + Add vboxusers + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-07-16 + 3.10.0 + Release Pisi Linux 1.0 + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 3.10.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-15 + 3.10.0 + Rebuild. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-19 + 3.10.0 + Update baselayout.conf + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-08 + 3.10.0 + Add baselayout.conf + Marcin Bojara + marcin@pisilinux.org + + + 2013-12-20 + 3.10.0 + Release Pisi Linux Rc2 + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-27 + 3.10.0 + Add gdm user and group, apply chmod 1777 to dev/shm aka run/shm. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-09-10 + 3.10.0 + Add shm dir to run, new archive. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-09-05 + 3.8.0 + Add missing method to pakhandler.py + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-31 + 3.8.0 + release Izmir + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-03-24 + 3.8.0 + Pisi Linux changes. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-01-11 + 3.7.1 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + mingetty + ftp://ftp.suse.com/pub/projects/init/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + A compact getty program for virtual consoles only + Sadece sanal konsollar için yekpare bir getty programı + mingetty, est getty poids plume minimaliste à utiliser exclusivement sur les consoles virtuelles. + mingetty, is a lightweight, minimalist getty for use on virtual consoles only. + mingetty yalnızca sanal konsollar için tasarlanmış basit ve yalın getty uygulamasıdır. + http://sourceforge.net/projects/mingetty/files/mingetty/1.08/mingetty-1.08.tar.gz + + gettext + + + tr.patch + + system/base/mingetty/pspec.xml + + + mingetty + + glibc + + + /sbin + /usr/share/locale + /usr/share/man + /usr/share/doc + + + + + 2014-05-11 + 1.0.8 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-09 + 1.0.8 + Rebuild + Kamil Atlı + suvarice@gmail.com + + + 2012-08-23 + 1.0.8 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + attr + http://acl.bestbits.at/ + + Pisi Linux Admins + admins@pisilinux.org + + LGPLv2.1 + app:console + library + system.base + Utilities for managing filesystems extended attributes + Gelişkin öznitelikler araçları + attr offre des utilitaires qui servent à manipuler les attributs étendus des objects de système de fichier. + attr contains a set of tools for manipulating extended attributes on filesystem objects, in particular getfattr and setfattr. + attr dosya sistemi nesnelerinin özniteliklerini değiştirmek için gerekli bir dizi araç sunar. + http://download.savannah.gnu.org/releases-noredirect/attr/attr-2.4.47.src.tar.gz + system/base/attr/pspec.xml + + + attr + + /bin + /lib + /usr/share/locale + /usr/share/doc + /usr/share/man + + + + attr-devel + Development files for attr + attr için geliştirme dosyaları + system.devel + + attr + + + /usr/include + /usr/share/man/man3 + + + + attr-32bit + 32-bit shared libraries for attr + emul32 + emul32 + + glibc-32bit + + + glibc-32bit + attr + + + /lib32 + + + + + 2015-03-15 + 2.4.47 + fix build emul32. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-09-30 + 2.4.47 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 2.4.47 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-28 + 2.4.47 + Version bump, clean attr. + Marcin Bojara + marcin@pisilinux.org + + + 2013-01-24 + 2.4.46 + Add emul32 + Marcin Bojara + marcin@pisilinux.org + + + 2012-06-04 + 2.4.46 + First release + Erdem Artan + admins@pisilinux.org + + + + + + texinfo + http://www.gnu.org/software/texinfo/ + + PisiLinux Community + admins@pisilinux.org + + GPLv3 + app:console + system.base + programme et utilitaires GNU info. + The GNU info program and utilities + GNU info (bilgi) programı ve araçları + GNU Info Prgramm und Werkzeuge + Texinfo is a documentation system that can produce both online information and printed output from a single source file. The GNU Project uses the Texinfo file format for most of its documentation. + mirrors://gnu/texinfo/texinfo-5.2.tar.gz + + ncurses + + system/base/texinfo/pspec.xml + + + texinfo + + ncurses + + + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/texinfo + /usr/share/texmf/tex/texinfo + /usr/share/locale + /usr/share/texmf/ + + + System.PackageHandler + + + + + 2014-05-25 + 5.2 + Release bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 5.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-22 + 5.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-09-05 + 4.13 + Add missing method to pakhandler.py + Marcin Bojara + marcin@pisilinux.org + + + 2010-10-11 + 4.13 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + libcap-ng + http://people.redhat.com/sgrubb/libcap-ng + + PisiLinux Community + admins@pisilinux.org + + LGPLv2+ + library + system.base + An alternate POSIX capabilities library + Alternatif bir POSIX yetenekleri kütüphanesi + libcap-ng is a library that makes using POSIX capabilities easier. + libcap-ng POSIX yeteneklerinin yönetimini kolaylaştıran bir kütüphanedir. + http://people.redhat.com/sgrubb/libcap-ng/libcap-ng-0.7.3.tar.gz + + attr + python + + system/base/libcap-ng/pspec.xml + + + libcap-ng + + /usr/lib + /usr/share/doc + + + + python-libcap-ng + Python bindings for libcap-ng + Python için libcap-ng bağlayıcıları + programming.language.python + + libcap-ng + + + /usr/lib/python* + + + + libcap-ng-utils + Utilities to analyse the POSIX capabilities on running processes + Çalışan süreçlerin sahip olduğu POSIX yeteneklerini incelemeye yarayan araçlar + util.admin + + libcap-ng + + + /usr/bin + /usr/share/man/man8/* + + + + libcap-ng-devel + Development files for libcap-ng + libcap-ng için geliştirme dosyaları + system.devel + + libcap-ng + + + /usr/share/aclocal + /usr/include + /usr/lib/pkgconfig + /usr/share/man/man3 + + + + + 2014-05-11 + 0.7.3 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-29 + 0.7.3 + Rebuild + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-11 + 0.7.3 + Güncellendi. + PisiLinux Community + admins@pisilinux.org + + + 2012-08-23 + 0.7 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + glib2 + http://www.gtk.org/ + + PisiLinux Community + admins@pisilinux.org + + LGPLv2.1 + library + system.base + La librairie GLib2 de routines C. + A library of handy utility functions + C programlama dili için glib kütüphanesi + glib2 is the low-level core library that forms the basis for projects such as GTK+ and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system. + glib2, GTK+ ve GNOME gibi projelerin temelini oluşturan düşük seviyeli çekirdek kütüphanedir. C için veri yapıları, taşınabilirlik katmanları ve çeşitli çalışma zamanı işlevleri için arabirimler sunar. + mirrors://gnome/glib/2.44/glib-2.44.0.tar.xz + + libpcre-devel + zlib-devel + libffi-devel + + + revert-warn-glib-compile-schemas.patch + + system/base/glib2/pspec.xml + + + glib2 + + libpcre + zlib + libffi + + + /etc/profile.d + /usr/bin + /usr/lib + /usr/share/bash-completion/completions/ + /usr/share/locale + /usr/share/man + /usr/share/doc + /usr/share/glib-2.0 + /usr/share/systemtap + /usr/share/glib-2.0/schemas + + + System.PackageHandler + + + glib2.sh + glib2.csh + + + + glib2-devel + Development files for glib2 + glib2 için geliştirme dosyaları + system.devel + + glib2 + libpcre-devel + + + /usr/bin/gtester + /usr/bin/gtester-report + /usr/bin/gobject-query + /usr/bin/glib-genmarshal + /usr/bin/glib-gettextize + /usr/bin/glib-mkenums + /usr/include + /usr/lib/glib-2.0/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + /usr/share/aclocal + /usr/share/glib-2.0/schemas/gschema.dtd + /usr/share/glib-2.0/gettext + /usr/share/glib-2.0/gdb + /usr/share/gdb/auto-load/libglib-2.0.so.*-gdb.py* + /usr/share/gdb/auto-load/libgobject-2.0.so.*-gdb.py* + /usr/share/man/man3 + /usr/share/man/man1/glib-genmarshal.1 + /usr/share/man/man1/glib-gettextize.1 + /usr/share/man/man1/glib-mkenums.1 + /usr/share/man/man1/gobject-query.1 + /usr/share/man/man1/gtester-report.1 + /usr/share/man/man1/gtester.1 + + + + glib2-32bit + 32-bit shared libraries for glib2 + glib2 için 32-bit paylaşımlı kitaplıklar + emul32 + _emul32 + + libpcre-32bit + zlib-32bit + libffi-32bit + dbus-32bit + glibc-32bit + + + glib2 + libpcre-32bit + zlib-32bit + libffi-32bit + dbus-32bit + glibc-32bit + + + /usr/bin/32 + /usr/lib32 + + + System.PackageHandler + + + + glib2-docs + Documentation files for glib2 + Extensive documentation for developers wanting to use the GLib Library + + /usr/share/gtk-doc + + + + + 2015-04-08 + 2.44.0 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + + + 2014-10-01 + 2.42.0 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 2.40.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-15 + 2.40.0 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-03-29 + 2.38.2 + Minor version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-22 + 2.38.1 + Minor version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-10 + 2.38.0 + Bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-09-05 + 2.36.3 + Add missing method to pakhandler.py + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-26 + 2.36.3 + Fix dep, release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-14 + 2.36.3 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-06-11 + 2.36.0 + add missing dep. + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-05-16 + 2.36.0 + Path Fixed. + PisiLinux Community + admins@pisilinux.org + + + 2013-03-30 + 2.36.0 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2012-11-21 + 2.35.2 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + libxml2 + http://www.xmlsoft.org/ + + PisiLinux Community + admins@pisilinux.org + + MIT + library + system.base + Version 2 of the library to manipulate XML files + XML türü dosyaları işlemeye aracılık eden kütüphanenin 2. sürümü + Libxml2 est l'analyseur et la boîte à outils XML écrit en C pour le projet Gnome (mais utilisable en dehors de la plateforme Gnome). + Libxml2 is the XML C parser and toolkit developed for the Gnome project (but usable outside of the Gnome platform). + Libxml2, Gnome projesi için geliştirilmiş C dilinde XML ayrıştırıcısıdır. Gnome platformu olmadan da kullanılabilir. + ftp://xmlsoft.org/libxml2/libxml2-2.9.1.tar.gz + + python-devel + xz-devel + zlib-devel + readline-devel + + + CVE-2014-0191.patch + + system/base/libxml2/pspec.xml + + + libxml2-docs + system.doc + + libxml2 + + + /usr/share/doc + + + + libxml2 + + xz + zlib + python + readline + + + /usr/bin + /usr/lib + /usr/share/man + + + + libxml2-devel + Development files for libxml2 + libxml2 için geliştirme dosyaları + system.devel + + libxml2 + + + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + /usr/include + /usr/share/aclocal + /usr/share/man/man3 + + + + libxml2-32bit + 32-bit shared libraries for libxml2 + libxml2 için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + xz-32bit + zlib-32bit + readline-32bit + glibc-32bit + + + libxml2 + xz-32bit + zlib-32bit + + + /usr/lib32 + + + + + 2014-07-06 + 2.9.1 + Security update(CVE-2014-0191). + Vedta Demir + vedat@pisilinux.org + + + 2014-05-24 + 2.9.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 2.9.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-11-11 + 2.9.0 + Fix dep,release bump, binary file goes to main package. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-31 + 2.9.1 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-26 + 2.9.0 + Fix dep,release bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-10-22 + 2.9.0 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + tar + http://www.gnu.org/software/tar/ + + PisiLinux Community + admins@pisilinux.org + + GPLv3+ + app:console + system.base + A GNU file archiving program + GNU dosya arşivleme uygulaması + Le programme tar fournit la possibilité de manipuler des archives de type tar. Vous pouvez l'utiliser pour créer ou extraires des archives. Ajouter des fichiers à des archives existantes, les mettre à jour ou tout simplement lister leur contenu. + The GNU tar program saves many files together in one archive and can restore individual files (or all of the files) from that archive. + GNU tar birden fazla dosyayı tek bir arşiv dosyasında birleştiren ve daha sonra bu arşiv dosyasından geri çıkartabilen bir uygulamadır. + http://ftp.gnu.org/gnu/tar/tar-1.27.1.tar.xz + + tar.1 + + + gzip + bzip2 + gettext + ncompress + + system/base/tar/pspec.xml + + + tar + + acl + glibc + + + /bin + /sbin + /usr/share/doc + /usr/share/man + /usr/share/locale + /usr/share/info + + + + + 2014-05-11 + 1.27.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-11-23 + 1.27.1 + Version bump + Richard de Bruin + richdb@pisilinux.org + + + 2013-10-24 + 1.27 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2013-07-31 + 1.26 + Fix deps. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-08-23 + 1.26 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + spidermonkey + http://www.mozilla.org/js/spidermonkey/ + + PisiLinux Community + admins@pisilinux.org + + NPL-1.1 + library + system.base + Stand-alone JavaScript C Library + Javascript C Kitaplığı + Spidermonkey est l'Implémentation C de Javascript par Mozilla. + Spidermonkey is Mozilla's C implementation of JavaScript. + Mozilla'nın Javascript'in C implementasyonu. + Spidermonkey es la implementación de JavaScript con C de Mozilla. + http://ftp.mozilla.org/pub/mozilla.org/js/mozjs17.0.0.tar.gz + + zlib-devel + nspr-devel + readline-devel + libffi-devel + + system/base/spidermonkey/pspec.xml + + + spidermonkey + + nspr + zlib + libgcc + readline + + + /usr/bin + /usr/lib + /usr/share/doc + + + + spidermonkey-devel + Development files for spidermonkey + spidermonkey için geliştirme dosyaları + system.devel + + spidermonkey + nspr-devel + + + /usr/include + /usr/lib/pkgconfig + /usr/bin/js17-config + + + + + 2015-05-08 + 17.0.0 + Rebuild. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 17.0.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-30 + 17.0.0 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-28 + 17.0.0 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-28 + 1.8.5 + Move pc files to devel pack,rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-20 + 1.8.5 + Release bump for rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-20 + 1.8.5 + Cleanup package, bump for new build + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-09-20 + 1.8.5 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + libpcre + http://www.pcre.org/ + + PisiLinux Community + admins@pisilinux.org + + BSD + library + system.base + Perl-compatible regular expression library + Perl-uyumlu sıradan ifade kütüphanesi + La librairie PCRE (Expressions Régulières Compatible avec Perl) est un ensemble de fonctions implémentant la recherche de motifs de texte à l'aide d'expressions régulières utilisant la même syntaxe et la même sémantique que Perl5. + The PCRE (Perl Compatible Regular Expressions) library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5. + PCRE kütüphanesi, Perl 5 programlama dili sözdizimi ve semantiği ile kalıp eşleştirme (pattern matching) görevini yürüten fonksiyonları barındırır. + http://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.bz2 + + readline-devel + + system/base/libpcre/pspec.xml + + + libpcre + + libgcc + readline + + + /usr/lib + /usr/share/man + /usr/share/doc + /usr/bin + + + + libpcre-devel + Development files for libpcre + libpcre için geliştirme dosyaları + system.devel + + libpcre + + + /usr/include + /usr/share/man/man3 + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + /usr/share/doc/libpcre/html + /usr/bin/pcre-config + /usr/share/man/man1/pcre-config.1* + /usr/share/doc/libpcre/pcre-config.txt + + + + libpcre-32bit + 32-bit shared libraries for libpcre + libpcre için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + readline-32bit + glibc-32bit + + + libgcc + readline + libpcre + + + /usr/lib32 + + + + + 2015-01-25 + 8.36 + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 8.34 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-03 + 8.34 + Version bump. + Osman Erkan + osman.erkan@pisilinux.org + + + 2013-09-01 + 8.33 + Version bump, clean pcre. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-28 + 8.32 + Fix deps. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-05-20 + 8.32 + adress fixed + Osman Erkan + osman.erkan@pisilinux.org + + + 2013-02-16 + 8.32 + Update + Osman Erkan + osman.erkan@pisilinux.org + + + 2011-03-11 + 8.31 + First release + Erdem Artan + admins@pisilinux.org + + + + + + os-prober + http://joey.kitenet.net/code/os-prober/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2+ + app:console + system.base + Utility to detect other OSes on a set of drives + Narzędzie do wykrywania innych systemów operacyjnych na dyskach + os-probe detects other OSes available on a system and outputs the results in a generic machine-readable format. Support for new OSes and Linux distributions can be added easily. + os-prober wykrywa inne systemy operacyjne dostępne na komputerze i przekazuje rezultaty w standardowym, odczytywalnym maszynowo, formacie. + http://http.debian.net/debian/pool/main/o/os-prober/os-prober_1.65.tar.xz + system/base/os-prober/pspec.xml + + + os-prober + + /usr/bin + /usr/lib + /var/lib/os-prober + /usr/share/os-prober + /usr/share/doc/os-prober + + + + + 2015-05-03 + 1.65 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 1.63 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-24 + 1.63 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-07-28 + 1.58 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-01-03 + 1.57 + First release + Erdinç Gültekin + admins@pisilinux.org + + + + + + alternatives + http://git.fedorahosted.org/git/?p=chkconfig.git;a=summary + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + Alternative management system + Alternatif yönetim sistemi + alternatives creates, removes, maintains and displays information about the symbolic links comprising the alternatives system. Alternatives system determines the defaults when several programs fulfilling the same or similar functions to be installed on a single system at the same time. + alternatives, alternatives sisteminin parçası olan sembolik bağlantıları oluşturan, silen, yöneten ve bunlar hakkında bilgi gösteren araçtır. Alternatives sistemi, birbirine benzer ya da aynı işlevleri sunan programların aynı anda aynı sisteme kurulduğu zamanlarda öntanımlıları belirler. + https://git.fedorahosted.org/cgit/chkconfig.git/snapshot/chkconfig-1.3.62.tar.xz + + popt-devel + + system/base/alternatives/pspec.xml + + + alternatives + + /etc + /usr/sbin + /usr/share/locale + /usr/share/man + /usr/share/doc + /var + + + + + 2015-04-01 + 1.3.62 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 1.3.58 Release bump. Marcin Bojara marcin@pisilinux.org 2013-10-28 - 1.3.1 - rebuild - Pisi Linux Admins + 1.3.58 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-05-03 + 1.3.58 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + groff + http://www.gnu.org/software/groff/groff.html + + PisiLinux Community + admins@pisilinux.org + + GPLv3+ + BSD + MIT + app:console + system.base + S'occupe de la mise en forme de texte utilisé pour les pages de manuel + A document formatting system + Belge biçimlendirme sistemi + Text Formatierer für man pages + groff is a document formatting system. Groff takes standard text and formatting commands as input and produces formatted output. + groff bir belge biçimlendirme sistemidir. Groff standart metni ve biçimlendirme komutlarını alır ve biçimlendirilmiş çıktı oluşturur. + http://ftp.gnu.org/gnu/groff/groff-1.22.3.tar.gz + + texinfo + + + groff-1.19.2-man-unicode-dashes.patch + groff-1.22.3-parallel-mom.patch + + system/base/groff/pspec.xml + + + groff + + texinfo + libgcc + + + /etc + /usr/bin + /usr/lib + /usr/share/groff + + + + groff-doc + system.doc + + groff + + + /usr/share/doc + /usr/share/man + /usr/share/info + + + + + 2015-04-02 + 1.22.3 + Release bump, remove X builddep. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 1.22.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-29 + 1.22.2 + Rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-07-26 + 1.22.2 + Fix dep, release bump. + PisiLinux Community + admins@pisilinux.org + + + 2013-02-16 + 1.22.2 + Updated + PisiLinux Community admins@pisilinux.org + + 2012-11-25 + 1.21 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + ncompress + http://ncompress.sourceforge.net + + PisiLinux Community + admins@pisilinux.org + + public-domain + app:console + system.base + Un autre outil de décompression de données pour compatibilité + Another uncompressor for compatibility + Bir başka sıkışmış dosya açma programı + Ein weiterer Nichtkompressor zu Kompatibilitätszwecken + The ncompress package contains the compress and uncompress file compression and decompression utilities, which are compatible with the original UNIX compress utility (.Z file extensions). These utilities can't handle gzipped (.gz file extensions) files, but gzip can handle compressed files. + mirrors://sourceforge/ncompress/ncompress-4.2.4.4.tar.gz + + ncompress-4.2.4-make.patch + ncompress-4.2.4-lfs2.patch + ncompress-2GB.patch + ncompress-4.2.4-endians.patch + + system/base/ncompress/pspec.xml + + + ncompress + + /usr/bin + /usr/share/man + + + + + 2014-05-11 + 4.2.4.4 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2011-12-20 + 4.2.4.4 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + pycurl + http://pycurl.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + LGPLv2.1 + library + system.base + Python cURL Module + Python cURL Modülü + PycURL is a Python interface to libcurl. PycURL can be used to fetch objects identified by a URL from a Python program. + PycURL, python libcurl için python arayüzüdür. PycURL, URL tarafında tanımlanan nesneleri indirmek için bir python programı tarafından kullanılabilir. + http://pycurl.sourceforge.net/download/pycurl-7.19.3.1.tar.gz + + curl-devel + python-devel + openssl-devel + + system/base/pycurl/pspec.xml + + + pycurl + + curl + python + openssl + + + /usr/lib + /usr/share/doc + + + + + 2014-05-11 + 7.19.3.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-01 + 7.19.3.1 + Version bump. + Kamil Atlı + suvarice@gmail.com + + + 2013-12-19 + 7.19.0.2 + Rebuild + Stefan Gronewold(groni) + groni@pisilinux.org + + + 2013-03-12 + 7.19.0.2 + Version bum. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-03-12 + 7.19.0 + Fix pisi https issue + Pisi Linux Admins + marcin@pisilinux.org + 2010-10-11 - 1.3.1 + 7.19.0 First release Pisi Linux Admins admins@pisilinux.org @@ -5196,61 +6322,306 @@ - unzip - ftp://ftp.info-zip.org/pub/infozip/UnZip.html + shadow + http://pkg-shadow.alioth.debian.org/ PisiLinux Community admins@pisilinux.org - Info-ZIP + BSD app:console system.base - Unzipper for pkzip-compressed files - pkzip ile sıkıştırılmış dosyalar için açıcı - Unzip nous permet d'extraires des archives compressées aux format .zip (également appelées "fichiers zip"). - UnZip enables us to extract archives compressed in .zip format (also called "zipfiles"). - UnZip, zip formatında sıkıştırılmış dosyaları açmamızı sağlar. - mirrors://sourceforge/infozip/unzip610b.zip + Utilities to deal with user accounts + Kullanıcı hesapları yönetimi için araçlar + Le paquet des utilitaires pour le fichier de mot de passe Shadow regroupe les programmes nécessaires à convertir les fichiers de mots de passe traditionnels V7*NIX au format de mot passe shadow SVR4 ainsi que d'autres outils destinés à la gestion des fichiers des groupes et de mots de passe (qui fonctionnent aussi bien pour les mots de passe shadow que non-shadow). + The Shadow password file utilities package includes programs necessary to convert traditional V7 *NIX password files to the SVR4 shadow password format, and additional tools to maintain password and group files (that work with both shadow and non-shadow passwords). + Shadow parola dosyası yardımcı uygulamalar paketi, geleneksel V7 *nix parola dosyalarını SVR4 shadow parola biçimine dönüştüren programlar ile parola ve grup dosyalarının bakımı için ilave araçlar içerir. + http://pkg-shadow.alioth.debian.org/releases/shadow-4.2.1.tar.xz + + pam-devel + gettext-devel + - unzip-6.0-attribs-overflow.patch - unzip-6.0-exec-shield.patch - unzip-6.0-close.patch + shadow-strncpy-usage.patch + xstrdup.patch - system/base/unzip/pspec.xml + system/base/shadow/pspec.xml - unzip + shadow + Utilitaires pour gérer les comptes utilisateurs + Kullanıcı hesaplarını düzenlemek için araçlar. + + acl + attr + pam + + /bin /usr/bin - /usr/share/doc + /sbin + /usr/sbin + /etc + /lib /usr/share/man + /usr/share/doc + /usr/share/info + /usr/share/locale + + securetty + default/useradd + pam.d/login + pam.d/other + pam.d/passwd + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/shadow + pam.d/su + pam.d/system-auth + login.defs + - + + 2015-04-01 + 4.2.1 + Version bump., remove build with audit + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + 2014-05-11 - 610b + 4.1.5.1 Release bump. Marcin Bojara marcin@pisilinux.org - + 2013-10-29 - 610b - Rebuild - Yusuf Aydemir - yusuf.aydemir@pisilinux.org + 4.1.5.1 + Rebuild without-libcrack, clean shadow, fix login defs. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-30 + 4.1.5.1 + Rebuild with-libcrack, clean shadow. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-26 + 4.1.5.1 + Release bump for rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-08-23 + 4.1.5.1 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + kbd + http://freshmeat.net/projects/kbd/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + Keyboard and console utilities + Klavye ve konsol araçları + Le paquet kbd contient les fichiers de configuration de touches ainsi que divers utilitaires pour claviers compatible avec le noyau 1.1.54 et suivants. + The kbd package contains keytable files and keyboard utilities compatible with kernel version 1.1.54 and later. + Kbd paketi, çekirdek sürüm 1.1.54 ve sonraki sürümlerle uyumlu anahtar tablo dosyaları ve klavye yardımcı uygulamaları içerir. + https://www.kernel.org/pub/linux/utils/kbd/kbd-2.0.2.tar.xz + http://source.pisilinux.org/1.0/kbd-latarcyrheb-16-fixed.tar.bz2 + http://source.pisilinux.org/1.0/kbd-latsun-fonts.tar.bz2 + http://source.pisilinux.org/1.0/ro_maps.tar.bz2 + + gettext + gzip + pam-devel + check-devel + + + mandriva/kbd-1.15-mandriva.patch + mandriva/kbd-1.15-tilde_twosuperior_french_kbd.patch + mandriva/kbd-1.12-data_thai.patch + mandriva/kbd-1.15-remove-unneeded-calls.patch + archlinux/fix-dvorak-es.patch + archlinux/fix-euro2.patch + pisilinux/unicode_start-default-font.patch + pisilinux/tr-keypad-comma.patch + pisilinux/tr-no-meta_space.patch + pisilinux/trq-capslock-fix.patch + pisilinux/currency.patch + pisilinux/trf-keymap-fixes.patch + pisilinux/trf-capslock-fix.patch + + system/base/kbd/pspec.xml + + + kbd + + pam + + + /bin + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/kbd/keymaps + /usr/share/kbd/locale + /usr/share/kbd/unimaps + /usr/share/kbd/consolefonts + /usr/share/kbd/consoletrans + + + pisilinux/lat5u-12.psf.gz + pisilinux/lat5u-14.psf.gz + pisilinux/lat5u-16.psf.gz + mandriva/mac-fr-ext_new.kmap.gz + + + + + 2015-05-08 + 2.0.2 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 1.15.5 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 1.15.5 + rebuild. + PisiLinux Community + admins@pisilinux.org + + + 2013-07-26 + 1.15.5 + Fix dep, release bump. + PisiLinux Community + admins@pisilinux.org + + + 2013-05-30 + 1.15.5 + Fix dep, release bump. + PisiLinux Community + admins@pisilinux.org 2013-01-14 - 610b + 1.15.5 New release PisiLinux Community admins@pisilinux.org + + 2012-08-23 + 1.15.2 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + vixie-cron + http://www.gentoo.org/ + + PisiLinux Community + admins@pisilinux.org + + as-is + service + system.base + Paul Vixie's cron daemon, a fully featured crond implementation + Tam teşekküllü bir crond uyarlaması + Vixie cron (Cron est un daemon qui lance des tâches planifiées) est une implémentation riche basée sur le cron SysV. Chaque utilisateur possède sa propre table de planification (ou crontab - la CRON TABle de Crontab) est un fichier qui contient le planning de cron) et a la possibilité de spécifier des variables d'environnement au sein de la table. + Vixie cron (Cron is a daemon that runs scheduled tasks.) is a full featured cron implementation based on SysV cron. Each user has his own crontab ( Crontab (CRON TABle) is a file which contains the schedule of cron) and is allowed to specify environment variables within that crontab. + Vixie-cron (cron, zamanlanmış görevleri çalıştıran dinleyici programdır.) SysV cron tabanlı tam sürüm cron uygulamasıdır. Her kullanıcı kendi crontab 'ına (crontab cron listesini içeren dosyadır.) sahiptir ve bu crontab içinde ortam değişkenlerini yazmasına müsade edilmiştir. + ftp://ftp.linux.org.tr/pub/gentoo/distfiles/vixie-cron-4.1.tar.bz2 + + sed + pam-devel + + + vixie-cron-4.1-gentoo-r4.patch.bz2 + crontab.5.diff + vixie-cron-4.1-commandline.patch + vixie-cron-4.1-pam.patch + vixie-cron-4.1-CAN-2005-1038.patch + CVE-2006-2607.patch + CVE-2007-1856.patch + + system/base/vixie-cron/pspec.xml + + + vixie-cron + + pam + comar-api + + + /usr/sbin + /usr/bin + /etc + /var/spool + /usr/share/doc + /usr/share/man + + + System.Package + System.Service + + + run-crons-0.3.1 + crontab + vixie-cron-4.1-cron.deny + cron.pam.d + + + + + 2015-05-04 + 4.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + 2010-10-11 - 6.0 + 4.1 First release Pisi Linux Admins admins@pisilinux.org @@ -5259,8 +6630,576 @@ - sysvinit - http://freshmeat.net/projects/sysvinit/ + leveldb + https://code.google.com/p/leveldb + + Alihan Öztürk + alihan@pisilinux.org + + BSD + app:console + system.base + A fast and lightweight key/value database library + Hızlı ve hafif bir anahtar/değer veri kütüphanesi + LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values. + LevelDB dize değerleri ile dize anahtarlarını eşleme sağlayan, Google'da yazılmış hızlı bir anahtar-değer depolama kütüphanesidir. + http://source.pisilinux.org/1.0/leveldb-e353fbc7ea81.tar.gz + + gperftools-devel + snappy-devel + + system/base/leveldb/pspec.xml + + + leveldb + + libgcc + snappy + gperftools + + + /usr/lib + /usr/share/doc + + + + leveldb-devel + + leveldb + + + /usr/include + + + + + 2014-06-02 + 1.17 + First release + Alihan Öztürk + alihan@pisilinux.org + + + + + + ca-certificates + http://packages.qa.debian.org/c/ca-certificates.html + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + MPL-1.1 + app:web + system.base + Common CA certificates + Common CA certificates + http://ftp.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_20141019.tar.xz + system/base/ca-certificates/pspec.xml + + + ca-certificates + + run-parts + + + /etc + /usr/share/man + /usr/sbin + /usr/share/ca-certificates + + + System.Package + + + + + 2015-01-10 + 20141019 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-01-10 + 20141019 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 20140325 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-01 + 20140325 + Version bump, fix installation. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-03-03 + 20130906 + First Release + PisiLinux Community + admins@pisilinux.org + + + + + + python + http://www.python.org/ + + PisiLinux Community + admins@pisilinux.org + + PSF-2.2 + app:console + system.base + An interpreted, interactive, object-orientated programming language + Nesneye yönelik bir programlama dili + Python est un langage de programmation dynamique orienté objet pouvant être utilisé pour différents types de développements logiciels. Il offre une intégration renforcée aussi bien avec les autres langages qu'avec des outils. Il est livré avec des librairies standards couvrant un large périmètre et peut être appris en quelques jours. + Python is a dynamic object-oriented programming language that can be used for many kinds of software development. It offers strong support for integration with other languages and tools, comes with extensive standard libraries, and can be learned in a few days. + Python, yazılım geliştirmenin birçok aşamasında kullanılabilen, dinamik nesne tabanlı bir programlama dilidir. Diğer programlama dilleriyle bütünleşme için sağlam bir destek sunar, kapsamlı standart kütüphanelerle sunulur ve birkaç günde öğrenilebilir. + http://www.python.org/ftp/python/2.7.9/Python-2.7.9.tar.xz + + bzip2 + gdbm-devel + zlib-devel + expat-devel + libffi-devel + sqlite-devel + ncurses-devel + openssl-devel + readline-devel + + + pisilinux_platform.patch + add-pisilinux-to-search-path.patch + default-utf8.patch + disable-egginfo.patch + trfix_emaillib.patch + + system/base/python/pspec.xml + + + python + + noDelta + + + gdbm + zlib + bzip2 + expat + libffi + sqlite + ncurses + openssl + readline + + + /etc + /usr/bin + /usr/include/python2.7/pyconfig.h + /usr/lib + /usr/share/doc + /usr/share/man + + + System.PackageHandler + + + pythonstart + 04python + + + + python-devel + Development files for python + python için geliştirme dosyaları + system.devel + + python + + + /usr/include + /usr/lib/pkgconfig + + + + + 2014-12-12 + 2.7.9 + Version bump and security fixes. + Vedat Demir + vedat@pisilinux.org + + + 2014-07-05 + 2.7.8 + Version bump and security fixes. + Vedat Demir + vedat@pisilinux.org + + + 2014-06-02 + 2.7.7 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 2.7.6 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-25 + 2.7.6 + Add upstream patch. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-20 + 2.7.6 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-09-05 + 2.7.5 + Add missing method to pakhandler.py + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-31 + 2.7.5 + Clean python. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-21 + 2.7.5 + Add some patches. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-16 + 2.7.5 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2012-07-11 + 2.7.3 + First release + Erdem Artan + admins@pisilinux.org + + + + + + python-psutil + https://github.com/giampaolo/psutil + + PisiLinux Community + admins@pisilinux.org + + BSD + library + system.base + A cross-platform process utilities module for Python + Platform bağımsız, süreçler hakkında bilgi sağlayan bir Python modülü + python-psutil is a module providing an interface for retrieving information on all running processes and system utilization (CPU, memory) in a portable way by using Python, implementing many functionalities offered by command line tools like ps, top, kill, lsof and netstat. + python-psutil, bütün çalışan süreçler ve sistem kullanımı (MİB - Merkezi İşlem Birim(CPU) ve hafıza gibi) hakkında bilgilere erişimek için arayüz sunan bir Python modülüdür. ps, top, kill, lsof, netstat gibi bir çok komut satırı araçlarının sunduğu işlevselliği sağlamaktadır. + https://github.com/giampaolo/psutil/archive/release-2.2.1.tar.gz + + python-devel + + system/base/python-psutil/pspec.xml + + + python-psutil + + python + + + /usr/lib + /usr/share/doc + + + + + 2015-04-12 + 2.2.1 + Version bump + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2013-11-19 + 1.1.3 + Version bump + Burak Fazıl Ertürk + burakerturk@pisilinux.org + + + 2012-11-16 + 0.6.1 + First release + Erdinç Gültekin + admins@pisilinux.org + + + + + + gdbm + http://www.gnu.org/software/gdbm/gdbm.html + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.base + Standard GNU database libraries included for compatibility with Perl + Perl uyumlu standart GNU veritabanı kütüphaneleri + GNU dbm est un ensemble de routines de base de données utilisant extensivement les dictionnaires (hashing). Il fonctionne de manière similaire aux routines dbm UNIX standards. + GNU dbm is a set of database routines that use extensible hashing. It works similar to the standard UNIX dbm routines. + GNU dbm genişletilebilir hash yapabilen veritabanı işlevleri sağlar. Standart UNIX dbm uygulamaları ile aynı şekilde çalışır. + mirrors://gnu/gdbm/gdbm-1.11.tar.gz + + gdbm-1.10-zeroheaders.patch + + system/base/gdbm/pspec.xml + + + gdbm + + /usr/bin + /usr/lib + /usr/share/doc + /usr/share/locale + /usr/share/man + /usr/share/info + + + + gdbm-devel + Development files for gdbm + gdbm için geliştirme dosyaları + system.devel + + gdbm + + + /usr/include + + + + + 2014-05-11 + 1.11 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 1.11 + Version bump + PisiLinux Community + admins@pisilinux.org + + + 2013-08-29 + 1.10 + Clean gdbm. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-08-31 + 1.10 + First release + Erdem Artan + admins@pisilinux.org + + + + + + cpio + http://www.gnu.org/software/cpio/cpio.html + + PisiLinux Community + admins@pisilinux.org + + GPLv3 + app:console + system.base + A file archival tool which can also read and write tar files + Tar ve cpio dosyaları içine yazıp okuyabilen bir dosya arşivleme uygulaması + GNU cpio permet de copier des fichiers du système dans une archive cpio ou tar et vice-versa. L'archive peut être un simple fichier sur le disque, une cassette magnétique, ou un tuyau unix (pipe). GNU cpio gère les formats d'archive suivant : binaire, ASCII ancien, ASCII nouveau, crc, binaire HPUX, ASCII ancien HPUX, tar ancien et tar POSIX.1. + GNU cpio copies files into or out of a cpio or tar archive. The archive can be another file on the disk, a magnetic tape, or a pipe. GNU cpio supports the following archive formats: binary, old ASCII, new ASCII, crc, HPUX binary, HPUX old ASCII, old tar, and POSIX.1 tar. + GNU cpio dosyaları cpio veya tar arşivlerine kopyalamaya veya bu arşivlerden çıkarmak için tasarlanmıştır. Arşiv diskteki başka bir dosya, manyetik bir teyp veya bir boru sistemi olabilir. GNU cpio şu arşiv formatlarını destekler: ikili, eski ASCII, yeni ASCII, crc, HPUX ikili, HPUX eski ASCII, eski tar ve POSIX.1 tar. + mirrors://gnu/cpio/cpio-2.11.tar.bz2 + + cpio-2.7-svr4compat.patch + cpio-2.9-exitCode.patch + CVE-2010-0624-rpatelib-overflow.patch + + system/base/cpio/pspec.xml + + + cpio + + /bin + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/locale + + + + + 2014-05-11 + 2.11 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 2.11 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-08-24 + 2.11 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + expat + http://expat.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + as-is + library + system.base + librairies d'analyse XML + XML parsing libraries + XML ayrıştırıcı kütüphaneleri + XML Parser Bibliotheken + This is expat, the C library for parsing XML, written by James Clark. Expat is a stream oriented XML parser. This means that you register handlers with the parser prior to starting the parse. These handlers are called when the parser discovers the associated structures in the document being parsed. A start tag is an example of the kind of structures for which you may register handlers. + mirrors://sourceforge/expat/expat-2.1.0.tar.gz + + gnuconfig + glibc-devel + + system/base/expat/pspec.xml + + + expat + + /usr/bin + /usr/lib + /usr/share/doc + /usr/share/man + + + + expat-devel + Development files for expat + expat için geliştirme dosyaları + system.devel + + glibc-32bit + + + expat + + + /usr/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + /usr/share/doc/expat/html + + + + expat-32bit + 32-bit shared libraries for expat + expat için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + expat + + + /usr/lib32 + + + + + 2014-05-11 + 2.1.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-27 + 2.1.0 + Move pc files to devel pack, rebuild + PisiLinux Community + admins@pisilinux.org + + + 2013-01-21 + 2.1.0 + Remove patch which causing test error for perl-XML-Parser. + Marcin Bojara + marcin@pisilinux.org + + + 2011-03-01 + 2.1.0 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + net-tools + http://sites.inka.de/lina/linux/NetTools/ PisiLinux Community admins@pisilinux.org @@ -5268,65 +7207,742 @@ GPLv2 app:console system.base - Programs which control basic system processes - sysvinit package contains a group of utilities that control the very basic functions of your system. sysvinit contains the init program, the first program started by the Linux kernel when the system boots. - http://download.savannah.gnu.org/releases/sysvinit/sysvinit-2.88dsf.tar.bz2 + Standard Linux networking tools + Linux ağ araçları + net-tools est une collection de programmes représentant les outils réseau de base du système d'exploitation Linux. S'y trouvent arp, hostname, ifconfig, ipmaddr, iptunnel, mii-tool, nameif, netstat, plipconfig, rarp, route et slattach. + net-tools is a collection of programs that form the base set of the networking tools for the Linux operating system. It includes arp, hostname, ifconfig, ipmaddr, iptunnel, mii-tool, nameif, netstat, plipconfig, rarp, route and slattach. + Net-tools, Linux işletim sisteminde kullanılan ağ ile ilgili temel araçların bir birleşimidir. Arp, hostname, ifconfig, ipmaddr, iptunnel, mii-tool, nameif, netstat, plipconfig, rarp, route ve slattach programlarını içerir. + ftp://ftp.linux.org.tr/pub/mirrors/gentoo/distfiles/net-tools-1.60.tar.bz2 - sysvinit-2.86-ctrlc.patch - sysvinit-2.78-man.patch - sysvinit-2.86-loginshell.patch - sysvinit-2.86-single.patch - sysvinit-2.88-quiet.patch - sysvinit-2.88-ipv6.patch - sysvinit-2.88-omit.patch - sysvinit-2.88-wall-maxlines.patch + 01_all_net-tools-1.60-2.6-compilefix.patch.bz2 + 02_all_net-tools-1.60-gcc34.patch.bz2 + 03_all_net-tools-1.60-cleanup-list-handling.patch.bz2 + 04_all_net-tools-1.60-get_name.patch.bz2 + 20_all_net-tools-1.54-ipvs.patch.bz2 + 21_all_net-tools-1.57-bug22040.patch.bz2 + 22_all_net-tools-1.60-manydevs.patch.bz2 + 23_all_net-tools-1.60-miiioctl.patch.bz2 + 24_all_net-tools-1.60-virtualname.patch.bz2 + 25_all_net-tools-1.60-cycle.patch.bz2 + 26_all_net-tools-1.60-overflow.patch.bz2 + 27_all_net-tools-1.60-netstat_ulong.patch.bz2 + 50_all_net-tools-1.60-multiline-string.patch.bz2 + 51_all_net-tools-1.60-man.patch.bz2 + 52_all_net-tools-1.60-numeric-ports.patch.bz2 + 53_all_net-tools-1.60-appletalk.patch.bz2 + 54_all_net-tools-1.60-wide.patch.bz2 + 55_all_net-tools-1.60-Makefile.patch.bz2 + 56_all_net-tools-1.60-ipv6-hostname.patch.bz2 + 57_all_net-tools-1.60-ifconfig-infiniband.patch.bz2 + 60_all_net-tools-1.60-headers.patch.bz2 + net-tools-missing.patch + kernel_headers.patch + gcc-4.3.patch + large-buffer.patch - system/base/sysvinit/pspec.xml + system/base/net-tools/pspec.xml - sysvinit + net-tools + + comar + comar-api + /bin /sbin /usr/bin + /usr/sbin + /usr/share/doc /usr/share/man - /usr/include + /usr/share/locale + + + + + 2014-05-11 + 1.60 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-30 + 1.60 + Rebuild + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-10-13 + 1.60 + First release + Erdem Artan + admins@pisilinux.org + + + + + + libunwind + http://www.nongnu.org/libunwind/ + + PisiLinux Community + admins@pisilinux.org + + MIT + library + system.base + Call chain tracer of a program + Yazılım çağrıları geri izleme aracı + libunwind is a portable and efficient C programming interface (API) to determine the call chain of a program. + libunwind bir yazılımın çağrı sıralamasını takip etmek için kullanılan, hızlı çalışan ve taşınabilir bir C programlama arabirimidir. + http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz + + xz-devel + + system/base/libunwind/pspec.xml + + + libunwind + + xz + + + /usr/lib + /usr/share/doc/libunwind + /usr/share/man + /usr/share/man/man3 - - System.Package - - sysvinit-tools - Tools used for process and utmp management - Süreç ve utmp yönetim araçları + libunwind-devel + Development files for libunwind + libunwind için geliştirme dosyaları + + libunwind + - /bin/mountpoint - /sbin/pidof - /sbin/killall5 - /sbin/sulogin - /usr/bin/wall - /usr/bin/last - /usr/bin/lastb - /usr/bin/mesg - /usr/bin/utmpdump - /usr/share/man/man1 - /usr/share/man/man8/killall5* - /usr/share/man/man8/pidof* - /usr/share/man/man8/sulogin* + /usr/include + /usr/lib/pkgconfig + + + + + 2015-01-30 + 1.1 + Rebuild. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 1.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-20 + 1.1 + Rebuild Unused + Varol Maksutoğlu + waroi@pisilinux.org + + + 2013-07-27 + 1.1 + Move pc files to devel pack, rebuild + PisiLinux Community + admins@pisilinux.org + + + 2013-02-16 + 1.1 + New release + Serdar Soytetir + kaptan@pisilinux.org + + + 2011-12-09 + 1.0.1 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + libusb + http://libusb.org/ + + PisiLinux Community + admins@pisilinux.org + + LGPLv2.1 + library + system.base + Userspace access to USB devices + Project's main aim is to create a library for use by user level applications to access USB devices regardless of OS. + http://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-1.0.19/libusb-1.0.19.tar.bz2 + + eudev-devel + + system/base/libusb/pspec.xml + + + libusb + + eudev + + + /usr/bin + /usr/lib + /usr/share/doc + + + libusbx + + + libusbx + + + + libusb-devel + Development files for libusb + system.devel + + libusb + + + /usr/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + + + libusbx-devel + + + libusbx-devel + + + + libusb-32bit + 32-bit shared libraries for libusb + emul32 + emul32 + + glibc-32bit + + + libusb + eudev-32bit + glibc-32bit + + + /usr/lib32 + + + libusbx-32bit + + + libusbx-32bit + + + + + 2014-04-30 + 1.0.19 + rename libusbx to libusb like upsteam + version bump to 19 + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-16 + 1.0.18 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-29 + 1.0.17 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-07-27 + 1.0.16 + Move pc files to devel pack, rebuild + PisiLinux Community + admins@pisilinux.org + + + 2013-07-27 + 1.0.16 + Move .pc files to devel package + Fatih Turgel + hitaf@pisilinux.org + + + 2013-07-23 + 1.0.16 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2012-10-12 + 1.0.14 + First release + Erdem Artan + admins@pisilinux.org + + + + + + liblogging + http://www.liblogging.org + + Marcin Bojara + marcin@pisilinux.org + + BSD-2 + library + system.base + Easy to use, portable, open source library for system logging + Liblogging offers an enhanced replacement for the syslog() call, but retains its ease of use. + http://download.rsyslog.com/liblogging/liblogging-1.0.3.tar.gz + system/base/liblogging/pspec.xml + + + liblogging + + /usr/lib + /usr/bin + /usr/share/man + /usr/share/doc/liblogging + + + + liblogging-devel + Development files for liblogging + system.devel + + liblogging + + + /usr/include/liblogging/stdlog.h + /usr/lib/pkgconfig/liblogging-stdlog.pc 2014-05-11 - 2.88 + 1.0.3 Release bump. Marcin Bojara marcin@pisilinux.org - 2011-06-01 - 2.88 + 2014-03-30 + 1.0.3 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + python-pyliblzma + http://pypi.python.org/pypi/pyliblzma + + PisiLinux Community + admins@pisilinux.org + + LGPLv3 + library + system.base + Python bindings for lzma + Python için lzma bağlayıcıları + pyliblzma provides a python interface for the liblzma library to read/write data that has been compressed/decompressed with lzma utils. + pyliblzma, lzma araçlarıyla sıkıştırılmış verileri açmak ve lzma kitaplığı kullanarak veri sıkıştırmak için python programlama arayüzü sunan bir pakettir. + http://pypi.python.org/packages/source/p/pyliblzma/pyliblzma-0.5.3.tar.bz2 + + xz-devel + python-setuptools + python-devel + + system/base/python-pyliblzma/pspec.xml + + + python-pyliblzma + + xz + python + + + /usr/lib/python2* + /usr/share/doc + + + + + 2014-05-11 + 0.5.3 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 0.5.3 + rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-28 + 0.5.3 + Fix deps. + Serdar Soytetir + kaptan@pisilinux.org + + + 2010-10-11 + 0.5.3 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + gperf + http://www.gnu.org/software/gperf/gperf.html + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + A perfect hash function generator + Mükemmel hash üreticisi + gperf is a perfect hash function generator. For a given list of strings, it produces a hash function and hash table, in form of C or C++ code, for looking up a value depending on the input string. The hash function is perfect, which means that the hash table has no collisions, and the hash table lookup needs a single string comparison only. + gperf mükemmel hash fonksiyonu üretecidir. Verilen bir katar listesi için C ve C++ kodu biçiminde bir hash fonksiyonu ve hash tablosu üretir. + GNU gperf es un generador de perfect hash. Produce una función hash y una tabla hash a base de una lista de cadenas, en forma de código C o C++ , para revisar valores dependiendo de una cadena de entrada. La función de hash es perfecta, lo que quiere decir que no hay colisiones en la tabla de hash, y para la búsqueda en la tabla hash se necesita solamente una comparación. + mirrors://gnu/gperf/gperf-3.0.4.tar.gz + system/base/gperf/pspec.xml + + + gperf + + libgcc + + + /usr/bin + /usr/share/doc + /usr/share/info + /usr/share/man + + + + + 2014-05-11 + 3.0.4 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-24 + 3.0.4 + Rebuild. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2013-07-26 + 3.0.4 + Fix dep,release bump. + PisiLinux Community + admins@pisilinux.org + + + 2012-08-23 + 3.0.4 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + psmisc + http://psmisc.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + A set of tools that use the proc filesystem + proc dosya sistemi kullanan bir araç takımı + PSmisc est une collection de petits utilitaires utilisant le système de fichier /proc, et assiste l'administrateur système dans ses tâches habituelles. + PSmisc is a collection of small utilities using /proc file system, and providing the system administrator with some help in common tasks. + PSmisc, /proc dosya sistemini kullanan küçük araçlar yardımıyla sistem yöneticisine bazı genel görevlerde yardımcı olmayı amaçlar. + PSmisc ist eine Sammlung von kleinen Anwendungen, die das /proc Dateisystem verwenden und dem System Administrator Hilfe für gängige Aufgaben bieten. + mirrors://sourceforge/psmisc/psmisc-22.21.tar.gz + + ncurses-devel + gettext + + + psmisc-fuser.patch + + system/base/psmisc/pspec.xml + + + psmisc + + ncurses + + + /bin + /usr/bin + /usr/share/man + /usr/share/doc + /usr/share/locale + + + + + 2015-05-03 + 22.21 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 22.20 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-02-14 + 22.20 + New version + Ertan Güven + ertan@pisilinux.org + + + 2012-08-24 + 22.19 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + libunistring + http://www.gnu.org/software/libunistring + + PisiLinux Community + admins@pisilinux.org + + GPLv3 + LGPLv3 + library + system.base + Unicode string library + Unicode karakter dizisi kitaplığı + This library provides functions for manipulating Unicode strings and for manipulating C strings according to the Unicode standard. + Bu kitaplığı unicode standartına göre unicode ve C karakter dizilerinde değişiklik yapmak için kullanılabilecek fonksiyonlar sunar. + mirrors://gnu/libunistring/libunistring-0.9.3.tar.gz + system/base/libunistring/pspec.xml + + + libunistring + + /usr/lib + /usr/share/doc + /usr/share/info + + + + libunistring-devel + Development files for libunistring + libunistring için geliştirme dosyaları + system.devel + + libunistring + + + /usr/include + + + + + 2014-05-11 + 0.9.3 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-30 + 0.9.3 + Rebuild + Pisi Linux Admins + admins@pisilinux.org + + + 2011-02-10 + 0.9.3 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + nss-mdns + http://0pointer.de/lennart/projects/nss-mdns/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.base + Name Service Switch module + İsim servisi değiştirme modülü + Module d'échange de service de nom pour le DNS Multicast. + Name Service Switch module for Multicast DNS. + Çoklu gönderim yapan DNS'ler için isim servisi seçme modülü. + http://0pointer.de/lennart/projects/nss-mdns/nss-mdns-0.10.tar.gz + + nss-mdns-0.8-avahi-socket.patch + + system/base/nss-mdns/pspec.xml + + + nss-mdns + + /etc + /usr/lib + /usr/share/doc + + + mdns.allow + + + + + 2014-05-11 + 0.10 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-29 + 0.10 + Rebuild + Pisi Linux Admins + admins@pisilinux.org + + + 2010-10-11 + 0.10 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + sed + http://sed.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + GNU Stream Editor + GNU stream düzenleyici + Sed est un éditeur de flux. Un éditeur de flux est utilisé pour réaliser des opérations basiques de modification de texte sur un flux d'entrée (un fichier ou un tuyau unix). + Sed is a stream editor. A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline). + Sed bir dosyadan veya standart girdiden (klavyeden) bilgi okur ve standart çıktıya (ekrana) okuduğu bilgileri kullanıcının belirlediği düzene sokarak yazar. + mirrors://gnu/sed/sed-4.2.2.tar.gz + + gettext-devel + + system/base/sed/pspec.xml + + + sed + + acl + + + /bin + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/locale + + + + + 2014-05-11 + 4.2.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-27 + 4.2.2 + Clean sed. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-01-14 + 4.2.2 + Release bump for rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-01-14 + 4.2.2 + New release + PisiLinux Community + admins@pisilinux.org + + + 2010-10-11 + 4.2.1 First release Pisi Linux Admins admins@pisilinux.org @@ -5352,11 +7968,11 @@ udev ermöglicht Linux Benutzern ein dynamisches /dev Verzeichnis und beständige Gerätenamen http://www.freedesktop.org/software/systemd/systemd-214.tar.xz - glib2 + glib2-devel gperf acl-devel libkmod-devel - libblkid-devel + libutil-linux-devel system/base/udev/pspec.xml @@ -5366,7 +7982,7 @@ libudev acl libkmod - libblkid + libutil-linux util-linux @@ -5474,7 +8090,7 @@ emul32 libkmod-32bit - libblkid-32bit + libutil-linux-32bit libudev @@ -5503,7 +8119,7 @@ - 2014-07-01 + 2015-05-01 214 Version bump. Marcin Bojara @@ -5616,6 +8232,200 @@ + + + bc + http://www.gnu.org/software/bc + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + Console-based calculator utility + Konsol temelli hesap makinesi + bc est un langage de calcul numérique à précision arbitraire qui peut être utilisé comme calculatrice. La syntaxe est similaire au C, avec quelques différences notables. Il supporte par exemple l'exécution interactive de commandes. + bc is an arbitrary precision numeric processing language and can be used as a calculator. Syntax is similar to C, but differs in many substantial areas. For example, it supports interactive execution of statements. + bc, herhangi bir keskinlikte sayısal işlemler yapmayı sağlayan bir programlama dilidir ve bir hesap makinesi olarak kullanılabilir. Sözdizimi C programlama diline benzer, ancak C'den birçok önemli farkları vardır. Örneğin, ifadelerin etkileşimli bir şekilde çalışmasına olanak tanır. + ftp://alpha.gnu.org/gnu/bc/bc-1.06.95.tar.bz2 + + flex + texinfo + readline-devel + + + fedora/bc-1.06.95-memleak.patch + fedora/bc-1.06-dc_ibase.patch + fedora/bc-1.06.95-matlib.patch + + system/base/bc/pspec.xml + + + bc + + readline + + + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/info + + + + + 2014-05-11 + 1.06.95 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 1.06.95 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2011-01-02 + 1.06.95 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + bash + http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html + + Pisi Linux Admins + admins@pisilinux.org + + GPLv2 + app:console + system.base + The standard GNU Bourne again shell + GNU Bource again kabuğu + Bash est le Bourne Again SHell du projet GNU, une implémentation complête du POSIX IEEE et des spécifications d'interprétation de commande (shell) de l'Open Group, avec édition interactive de ligne de commande et des fonctionnalités à la csh tels que la substitution dans l'historique de commande. + Bash is the GNU Project's Bourne Again SHell, a complete implementation of the IEEE POSIX and Open Group shell specification with interactive command line editing, csh-like features such as history substitution. + Bash, IEEE POSIX ve Open Group'un interaktif komut satırı düzenleme, geçmiş komutları tamamlama gibi csh tipi özellikler gibi kabuk uygulamaları tariflerinin tam olarak uygulayan GNU Projesinin Bourne Again SHell kabuk programıdır. + mirrors://gnu/bash/bash-4.3.30.tar.gz + + ncurses-devel + + + official/bash43-031.tar.gz + official/bash43-032.tar.gz + official/bash43-033.tar.gz + fedora/bash-2.02-security.patch + fedora/bash-2.03-paths.patch + fedora/bash-2.03-profile.patch + fedora/bash-2.05a-interpreter.patch + fedora/bash-2.05b-debuginfo.patch + fedora/bash-2.05b-manso.patch + fedora/bash-2.05b-pgrp_sync.patch + fedora/bash-2.05b-readline-oom.patch + fedora/bash-2.05b-xcc.patch + fedora/bash-3.2-audit.patch + fedora/bash-3.2-ssh_source_bash.patch + fedora/bash-4.0-nobits.patch + fedora/bash-4.1-broken_pipe.patch + fedora/bash-4.1-defer-sigchld-trap.patch + fedora/bash-4.1-examples.patch + fedora/bash-4.2-coverity.patch + fedora/bash-4.2-manpage_trap.patch + fedora/bash-4.2-rc2-logout.patch + fedora/bash-4.2-size_type.patch + fedora/bash-bashbug.patch + fedora/bash-infotags.patch + fedora/bash-requires.patch + fedora/bash-setlocale.patch + fedora/bash-tty-tests.patch + + system/base/bash/pspec.xml + + + bash + + ncurses + + + /etc + /bin + /usr/bin + /usr/share/doc + /usr/share/info + /usr/share/man + /usr/share/locale + + + bashrc + command-not-found.sh + + + + + 2015-08-20 + 4.3_p33 + Update + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-10-13 + 4.3_p30 + Update + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-09-27 + 4.3_p26 + Update + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 4.3_p8 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-03 + 4.3_p8 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-28 + 4.2_p45 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-11-24 + 4.2_p45 + Update + Marcin Bojara + marcin@pisilinux.org + + + 2012-11-24 + 4.2_p39 + First release + Marcin Bojara + marcin@pisilinux.org + + + cracklib @@ -5706,6 +8516,2557 @@ + + + less + http://www.greenwoodsoftware.com/ + + PisiLinux Community + admins@pisilinux.org + + GPLv3 + app:console + system.base + Excellent lecteur de fichier texte + Excellent text file viewer + Mükemmel bir metin görüntüleyici + Ausgezeichneter Textbetrachter + The less utility is a text file browser that resembles more, but has more capabilities. Less allows you to move backwards in the file as well as forwards. Since less doesn't have to read the entire input file before it starts, less starts up more quickly than text editors (for example, vi). + http://www.greenwoodsoftware.com/less/less-458.tar.gz + + ncurses-devel + + system/base/less/pspec.xml + + + less + + ncurses + + + /etc/env.d + /usr/bin + /usr/share/doc + /usr/share/man + + + lesspipe.sh + 70less + code2color + + + + + 2014-05-11 + 458 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-24 + 458 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2012-09-15 + 451 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + lsb-release + http://www.linuxbase.org + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + LSB version query program + LSB sürüm sorgulama aracı + lsb-release prints certain LSB (Linux Standard Base) and distribution information. + lsb-release bazı dağıtıma özel tanımlayıcı bilgileri ekrana basan bir terminal aracıdır. + mirrors://sourceforge/project/lsb/lsb_release/1.4/lsb-release-1.4.tar.gz + + util-linux + + system/base/lsb-release/pspec.xml + + + lsb-release + + /usr/bin + /etc + /usr/share/man + /usr/share/doc + + + lsb-release + + + + + 2015-01-16 + 1.4 + Release Pisi Linux 1.2 + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-11-03 + 1.4 + Release Pisi Linux 1.1 + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-07-16 + 1.4 + Release Pisi Linux 1.0 + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 1.4 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-16 + 1.4 + Rc2 name Erdinc for Erdinç Gültekin. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-12-20 + 1.4 + Rc2 + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-20 + 1.4 + RC1 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-08-11 + 1.4 + sueno + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2012-08-23 + 1.4 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + nettle + http://www.gnu.org + + PisiLinux Community + admins@pisilinux.org + + LGPLv2.1 + library + system.base + The Nettle package contains the low-level cryptographic library. + Nettle - biblioteka kryptograficzna. + The Nettle package contains the low-level cryptographic library that is designed to fit easily in many contexts. + ftp://ftp.gnu.org/gnu/nettle/nettle-2.7.1.tar.gz + + gmp-devel + + system/base/nettle/pspec.xml + + + nettle + + gmp + + + /usr/bin + /usr/lib + /usr/share/info + /usr/share/doc + + + + nettle-devel + Nettle için geliştirme dosyaları + nettle için geliştirme dosyaları. + Pliki nagłówkowe biblioteki nettle. + + nettle + + + /usr/include + /usr/lib/pkgconfig/nettle.pc + /usr/lib/pkgconfig/hogweed.pc + /usr/lib32/pkgconfig/nettle.pc + /usr/lib32/pkgconfig/hogweed.pc + + + + nettle-32bit + 32-bit shared libraries for nettle + emul32 + emul32 + + gmp-32bit + glibc-32bit + + + nettle + glibc-32bit + gmp + + + /usr/lib32/ + + + + + 2014-05-11 + 2.7.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-28 + 2.7.1 + Version bump, clean nettle. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-26 + 2.6 + Move pc files to devel pack, rebuild. + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-02-14 + 2.6 + Version bump + Ertan Güven + ertan@pisilinux.org + + + 2012-09-29 + 2.5 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + db + http://www.oracle.com/technology/products/berkeley-db/db/index.html + + PisiLinux Community + admins@pisilinux.org + + DB + app:console + system.base + Quatrième version de Berkeley DB + Oracle Berkeley DB + Oracle Berkeley DB + Ein einbettbares Datenbank Engine, dass die Entwickler mit schnellen, zuverlässigen und lokalen Persistenz unterstützt und null Administration erfordert. + The Berkeley Database (Berkeley DB) is a programmatic toolkit that provides embedded database support for both traditional and client/server applications. The Berkeley DB includes B+tree, Extended Linear Hashing, Fixed and Variable-length record access methods, transactions, locking, logging, shared memory caching, and database recovery. The Berkeley DB supports C, C++, Java, and Perl APIs. It is used by many applications, including Python and Perl, so this should be installed on all systems. + Berkeley DB geliştiricilere yerel süreklilik sağlayan ve herhangi bir ayar gerektirmeden (zero administration) kullanılan, hızlı ve gömülebilir bir veritabanı motorudur. + http://download.oracle.com/berkeley-db/db-5.3.28.tar.gz + system/base/db/pspec.xml + + + db + + libgcc + + + /usr/bin + /usr/lib + /usr/sbin + + + db5 + + + + db-devel + Development files for db + + db + + + /usr/include + + + db5-devel + + + + db-docs + Documentation for db + system.doc + + db + + + /usr/share/doc + + + db5-docs + + + + + 2014-09-10 + 5.3.28 + Rebuild for component change. + Perl depends on db, so we need it in system.base. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-07-15 + 5.3.28 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 5.3.28 + Version bump + PisiLinux Community + admins@pisilinux.org + + + 2013-08-29 + 5.3.21 + Rename and clean db pack. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-26 + 5.3.21 + Fix dep, release bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-08-31 + 5.3.21 + First release + Erdem Artan + admins@pisilinux.org + + + + + + fuse + http://fuse.sourceforge.net + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.base + Interface implémentée dans l'environnement utilisateur (userpace) pour les systèmes de fichier. + An interface for filesystems implemented in userspace + Kullanıcı düzeyinde dosya sistemi oluştumaya yarayan kitaplık + Una interfaz para sistemas de archivos implementados en el espacio de usuario + fuse is a backend allowing regular users to (un)mount filesystems for their own use. + FUSE, kullanıcıların kendileri için dosya sistemleri oluşturmasına, bağlamasına ve bağı koparmasına imkân veren bir arkauç kitaplıktır. + mirrors://sourceforge/project/fuse/fuse-2.X/2.9.3/fuse-2.9.3.tar.gz + + gettext-devel + + + skip_umount_test.patch + + system/base/fuse/pspec.xml + + + fuse + + glibc + + + /bin + /sbin + /usr/bin + /lib + /usr/share/doc + /usr/share/man + + + + fuse-devel + Development files for fuse + fuse için geliştirme dosyaları + system.devel + + fuse + + + /usr/include + /usr/lib/pkgconfig + + + + + 2014-05-11 + 2.9.3 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-24 + 2.9.3 + Rebuild + Stefan Gronewold(groni) + groni@pisilinux.org + + + 2014-01-20 + 2.9.3 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2012-20-21 + 2.9.2 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + coreutils + http://www.gnu.org/software/coreutils/ + + Pisi Linux Admins + admins@pisilinux.org + + GPLv3+ + app:console + system.base + A set of basic GNU tools commonly used in shell scripts + Standart dosya, metin ve kabuk uygulamaları + Utilitaires standards GNU pour fichiers (chmod, cp, dd, dir, ls...), utilitaires texte (sort, tr, head, wc...) et utilitaires d'interpréteur de commande (shell) (whoami, who...) + GNU dosya uygulamaları (chmod, cp, dd, dir, ls...), sh uygulamaları (whoami, who,...) ve metin uygulamalarının (sort, tr, head, wc..) birlikteliğinden oluşmaktadır. + http://ftp.gnu.org/gnu/coreutils/coreutils-8.23.tar.xz + + acl-devel + attr-devel + perl + shadow + gettext-devel + ncurses-devel + texinfo + + + remove_am_silent_rules.patch + + system/base/coreutils/pspec.xml + + + coreutils + + acl + attr + gmp + libcap + + + /bin + /etc + /usr/bin + /usr/libexec + /usr/lib + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/locale + + + + + 2015-04-01 + 8.23 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 8.22 + Rebuild, add patch. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-04-02 + 8.22 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-31 + 8.21 + Clean coreutils. + Serdar Soytetir + kaptanan@pisilinux.org + + + 2013-07-26 + 8.21 + Fix deps, release bump. + Serdar Soytetir + kaptanan@pisilinux.org + + + 2013-02-11 + 8.21 + Güncellendi. + PisiLinux Community + admins@pisilinux.org + + + 2012-08-31 + 8.19 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + gettext + http://www.gnu.org/software/gettext/gettext.html + + PisiLinux Community + admins@pisilinux.org + + GPLv3+ + app:console + library + system.base + GNU libraries and utilities for producing multi-lingual messages + Farklı dillerde ileti katalogları üretmek için gerekli GNU araçları ve kütüphaneleri + gettext est une librairie d'internationalisation GNU. + The GNU gettext package provides a set of tools and documentation for producing multi-lingual messages in programs. Tools include a set of conventions about how programs should be written to support message catalogs, a directory and file naming organization for the message catalogs, a runtime library which supports the retrieval of translated messages, and stand-alone programs for handling the translatable and the already translated strings. Gettext provides an easy to use library and tools for creating, using, and modifying natural language catalogs and is a powerful and simple method for internationalizing programs. + gettext, uygulamalarda farklı dillerde iletiler kullanılmasını sağlayan yerelleştirme araçları ve kütüphanelerini içerir. + gettext ist eine GNU Bibliothek für Internationalisierung + http://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.4.tar.gz + + acl-devel + glib2-devel + ncurses + + system/base/gettext/pspec.xml + + + gettext-docs + system.doc + + gettext + + + /usr/share/doc/gettext/html + + + + gettext + + acl + glib2 + ncurses + libgcc + libunistring + libgomp + libxml2 + + + /usr/bin + /usr/lib + /usr/share/gettext + /usr/share/locale + /usr/share/info + /usr/share/man + /usr/share/doc + + + + gettext-devel + Development files for gettext + gettext için geliştirme dosyaları + system.devel + + gettext + + + /usr/share/aclocal + /usr/include + /usr/share/man/man3 + + + + + 2015-04-03 + 0.19.4 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + + + 2014-05-11 + 0.18.3.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 0.18.3.2 + Minor version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-27 + 0.18.3.1 + Version bump, clean gettext. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-11 + 0.18.2 + Fix dep, release bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-11 + 0.18.2 + Güncellendi. + PisiLinux Community + admins@pisilinux.org + + + 2010-10-11 + 0.18.1.1 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + libcap + http://www.kernel.org/pub/linux/libs/security/linux-privs/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + BSD + library + system.base + capacités POSIX 1003.1e. + POSIX 1003.1e capabilities library + POSIX 1003.1e desteği + libcap is a library for getting and setting POSIX.1e (formerly POSIX 6) draft 15 capabilities. + https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-2.24.tar.xz + + attr-devel + pam-devel + + system/base/libcap/pspec.xml + + + libcap + + pam + attr + + + /sbin + /lib + /usr/lib + /usr/share/man + /usr/share/doc + /etc + + + + libcap-devel + Development files for libcap + libcap için geliştirme dosyaları + system.devel + + libcap + + + /usr/include + /usr/share/man/man3 + + + + libcap-32bit + 32-bit shared libraries for libcap + libcap için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + attr-32bit + glibc-32bit + + + glibc-32bit + attr-32bit + + + /usr/lib32 + + + + + 2015-03-16 + 2.24 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 2.24 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-03 + 2.24 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-29 + 2.22 + Rebuild + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-01-24 + 2.22 + Use flags form pisi.conf, fix emul32 + Marcin Bojara + marcin@pisilinux.org + + + 2012-10-01 + 2.22 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + timezone + ftp://elsie.nci.nih.gov/pub/ + + PisiLinux Community + admins@pisilinux.org + + BSD + public-domain + app:console + data + system.base + Timezone data files and tools + Zamandilimi veri dosyaları ve araçları + timezone includes timezone data files and tools to use them. Package contents are synchronized with glibc tree. + timezone zamandilimi veri dosyaları ve bu dosyaları kullanmak için gerekli araçları içerir. Paket içeriği glibc gelişim ağacından oluşturulmaktadır. + http://www.iana.org/time-zones/repository/releases/tzdata2015d.tar.gz + + perl + gawk + + + timezone-data-2015c-makefile.patch + + system/base/timezone/pspec.xml + + + timezone + + /usr/share/zoneinfo + + + + + 2015-05-09 + 2015d + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 2014b + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 2014b + Version bump. + Burak Fazıl Ertürk + burakerturk@pisilinux.org + + + 2012-09-27 + 0.0_20120927 + First release + Erdem Artan + admins@pisilinux.org + + + + + + ncurses + http://www.gnu.org/software/ncurses/ncurses.html + + PisiLinux Community + admins@pisilinux.org + + MIT + library + system.base + Console display library + Konsol görsel kütüphanesi + NCurses est une librairie de fonction gérant l'affichage des applications pour terminaux en mode caractères. La libraries NCurses défini de nombreuses fonctionalités telles le mouvement de la souris et du curseur, la disposition du clavier et l'affichage en couleur. + The NCurses is a library of functions that manage an application's display on character-cell terminals. The NCurses library defines many functions such as moving mouse and cursor, keyboard mapping and dispaying in color. + NCurses, bir uygulamanın karakter tabanlı uçbirimlerde görüntüleri üzerinde çalışabilmeyi sağlayan işlevler kütüphanesidir. Uygulama programları için imleci hareket ettirmek, pencereler oluşturmak, renkler üretmek, fare ile oynamak v.b. işlevler sağlamaktadır. + mirrors://gnu/ncurses/ncurses-5.9.tar.gz + + gnuconfig + + system/base/ncurses/pspec.xml + + + ncurses + + /etc + /lib + /usr/bin + /usr/lib + /usr/share/terminfo + /usr/share/tabset + /usr/share/man + /usr/share/doc + + + + ncurses-devel + Development files for ncurses + ncurses için geliştirme dosyaları + system.devel + + ncurses + + + /usr/include + /usr/lib/static + /usr/lib32/static + /usr/share/man/man3 + + + + ncurses-32bit + 32-bit shared libraries for ncurses + emul32 + _emul32 + + glibc-32bit + + + ncurses + + + /usr/lib32 + /usr/lib32/pkgconfig + + + + + 2014-09-14 + 5.9 + Fix build .pc files. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 5.9 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-31 + 5.9 + Rebuild. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-27 + 5.9_20121110 + Clean ncurses + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-11-14 + 5.9_20121110 + First release + Erdinç Gültekin + admins@pisilinux.org + + + + + + time + ftp://prep.ai.mit.edu/pub/gnu/time + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + A GNU utility for monitoring a program's use of system resources + Bir programın sistem kaynak kullanımını izleyen GNU aracı + time utility runs another program, collects information about the resources used by that program while it is running, and displays the results. + time başka bir programı çalıştırarak o programın sistem kaynaklarını nasıl kullandığını izler ve topladığı bilgileri ekrana basar. + ftp://prep.ai.mit.edu/pub/gnu/time/time-1.7.tar.gz + + time-1.7-destdir.patch + + system/base/time/pspec.xml + + + time + + /usr/bin/ + /usr/share/info + + + + + 2014-05-11 + 1.7 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-01 + 1.7 + Clean time, add patches. + Serdar Soytetir + kaptan@pisilinux.org + + + 2010-10-11 + 1.7 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + file + http://www.darwinsys.com/file/ + + PisiLinux Community + admins@pisilinux.org + + as-is + app:console + system.base + Program to identify a file's format by scanning binary data for patterns + Dosya tipini belirlemek için kullanılan bir uygulamadır + Programme servant à identifiant le format d'un fichier en analysant les données binaires en cherchant des patrons connus. + Program to identify a file's format by scanning binary data for patterns. + İkili veri taraması kullanarak (dosya uzantısına bakmadan) dosya biçimini tanımlamaya yarayan bir uygulamadır. + ftp://ftp.astron.com/pub/file/file-5.22.tar.gz + + zlib + python-devel + + system/base/file/pspec.xml + + + file + + zlib + python + + + /usr/bin + /usr/lib + /usr/share/doc + /usr/share/man + /usr/share/misc + /usr/include + + + + + 2015-04-02 + 5.22 + Release bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 5.18 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 5.18 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-22 + 5.15 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-03-04 + 5.13 + Version bump + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-16 + 5.12 + New Release + PisiLinux Community + admins@pisilinux.org + + + 2012-11-22 + 5.11 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + mudur + http://www.pisilinux.org + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + Pisi Linux boot and initialization system + Pisi Linux açılış sistemi + Gère le montage de systèmes de fichier, le chargement de pilotes de périphérique, le démarrage des services système et d'autres tâches pendant les séquences de démarrage et d'arrêt de Pisi Linux. + mudur handles mounting of the filesystems, loading of the device drivers, starting of the system services, and other jobs during the Pisi Linux boot and shutdown sequences. + Pisi Linux açılış ve kapanışı sırasında, dosya sistemlerinin bağlanması, donanım sürücülerinin yüklenmesi, servislerin başlatılması gibi işleri yürütür. + http://source.pisilinux.org/1.0/mudur-4.4.0.tar.xz + + set_file_mode.patch + no_err-no_msg.patch + recreate_dir_if_new_uid_or_gid.patch + boot_option.patch + mount_cgroupfs.patch + + system/base/mudur/pspec.xml + + + mudur + + kbd + bash + dbus + kmod + eudev + comar + procps + python + rsyslog + sysvinit + coreutils + e2fsprogs + net-tools + baselayout + util-linux + wireless-tools + pisilinux-python + + + /etc/conf.d + /etc/mudur/services + /etc/init.d + /sbin + /bin + /usr/share/locale + + + System.PackageHandler + System.Service + System.Package + System.Settings + Disk.Manager + + + + + 2015-05-13 + 4.4.0 + fix issue #562, rebuild, depend new kbd and eudev, mount cgroups + Marcin Bojara + marcin@pisilinux.org + + + 2014-08-03 + 4.4.0 + Set mode for newly created files. + Marcin Bojara + marcin@pisilinux.org + + + 2014-06-11 + 4.4.0 + Recreate dir if uid or gid has been changed. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 4.4.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-06 + 4.4.0 + No error line in log file when tmpfiles created successfully. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-16 + 4.4.0 + Remove /dev/shm line from /etc/fstab. + Add mounting /run to fstab for fresh installed system. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-07 + 4.4.0 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-02-13 + 4.3.1 + Mount or remount tmpfs at /run. + Starts with kmod.conf and baselayout.conf at the begining. + Strip mudur_tmpfiles output. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-10 + 4.3.1 + Try to fix D-Bus start issue using cleanup_run. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-01-21 + 4.3.1 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-19 + 4.3.0 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 4.2.0 + rebuild + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-10 + 4.2.0 + Run udev after remount rootfs. + Fix /run/shm mode. + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-05 + 4.2.0 + Add missing method to pakhandler.py + Marcin Bojara + marcin@pisilinux.org + + + 2013-06-26 + 4.2.0 + Fix migration from /var/run to /run + Marcin Bojara + marcin@pisilinux.org + + + 2013-05-15 + 4.2.0 + Fix default groups for /sbin/useradd + Marcin Bojara + marcin@pisilinux.org + + + 2012-12-02 + 4.2.0 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + nspr + http://www.mozilla.org/projects/nspr/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.base + Netscape Portable Runtime + Netscape Taşınabilir Çalışma Zamanı + Netscape Portable Runtime (NSPR -- Exécutable Portable Netscape) fourni une API neutre au sens de la plate-forme pour les fonctions de niveau système ou de type libc. Cette API est utilisée au sein du client Mozilla ainsi que de nombreuses solutions logicielles de Netscape/AOL/iPlanet. + Netscape Portable Runtime (NSPR) provides a platform-neutral API for system level and libc like functions. The API is used in the Mozilla client, many of Netscape/AOL/iPlanet's and other software offerings. + Netscape Taşınabilir çalışma Zamanı (NSPR) sistem seviyesindeki libc ve benzeri fonksiyonlar için platform bağımsız bir programlama arayüzü sunar. Bu arayüz, Mozilla istemcilerinde, Netscape/AOL/iPlanet'in diğer yazılımlarında kullanılmaktadır. + Netscape Portable Runtime (NSPR) provee un API independiente de la plataforma a nivel de sistema y funciones como libc. El API está usado en el cliente Mozilla, y muchos otros software de Netscape/AOL/iPlanet. + ftp://ftp.mozilla.org/pub/mozilla.org/nspr/releases/v4.10.8/src/nspr-4.10.8.tar.gz + + nspr.pc.in + generate-pc-config.sh + + system/base/nspr/pspec.xml + + + nspr + + /usr/lib + + + + nspr-devel + Development files for nspr + nspr için geliştirme dosyaları + system.devel + + nspr + + + /usr/include + /usr/lib/pkgconfig + /usr/bin + + + + + 2015-04-02 + 4.10.8 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + + + 2014-12-06 + 4.10.7 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-07-05 + 4.10.6 + Release bump. + PisiLinux Community + admins@pisilinux.org + + + 2014-05-11 + 4.10.4 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 4.10.4 + Version bump. + PisiLinux Community + admins@pisilinux.org + + + 2013-11-18 + 4.10.2 + Version bump. + PisiLinux Community + admins@pisilinux.org + + + 2013-10-23 + 4.10.1 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2013-07-18 + 4.10 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-05-17 + 4.9.6 + v.bump + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-01-14 + 4.9.5 + New release + PisiLinux Community + admins@pisilinux.org + + + 2012-11-25 + 4.9.4 + First release + Erdinç Gültekin + admins@pisilinux.org + + + + + + libuser + https://fedorahosted.org/libuser + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.base + A user and group account administration library + Kullanıcı ve grup hesap yönetim kitaplığı + libuser implements a standardized interface for manipulating and administering user and group accounts. The library uses pluggable back-ends to interface to its data sources. + libuser kullanıcı ve grup hesaplarını yönetmek ve işlemek için standart bir arayüz sunar. Kitaplık, sağladığı arayüzün verilere erişimi için genişletilebilir arkauçlar kullanmaktadır. + https://fedorahosted.org/releases/l/i/libuser/libuser-0.61.tar.xz + + pam-devel + popt-devel + glib2-devel + python-devel + + + libuser-0.56.15-fix_blowfish.patch + libuser-0.56.9-fix-str-fmt.patch + + system/base/libuser/pspec.xml + + + libuser + + pam + popt + glib2 + python + + + /etc + /usr/share/man + /usr/share/doc + /usr/share/locale + /usr/bin + /usr/sbin + /usr/lib + + + + libuser-devel + Development files for libuser + libuser için geliştirme dosyaları + system.devel + + libuser + glib2-devel + + + /usr/include + /usr/lib/pkgconfig + + + + + 2015-04-07 + 0.61 + Version bump, build without-sasl + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 0.60 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 0.60 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-07-28 + 0.59 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-01-14 + 0.58.0 + New release + PisiLinux Community + admins@pisilinux.org + + + 2012-08-23 + 0.57.6 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + procps + http://procps.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + Standard informational utilities and process-handling tools + Geleneksel bilgilendirme yardımcı programları ve süreç işleme araçları + procps est un paquet regroupant une multitude de petits utilitaires utiles donnant des informations concernant les process en utilisant le système de fichier /proc. Le paquet inclus les programmes ps, top, vmstat, w, kill, free, slabtop et skill. + procps is the package that has a bunch of small useful utilities that give information about processes using the /proc filesystem. The package includes the programs ps, top, vmstat, w, kill, free, slabtop, and skill. + Procps /proc dosya sistemini kullanarak çalışan süreçler hakkında bilgi vermeye yarayan bazı kullanışlı uygulamaları içeren bir pakettir. Paket ps, top, vmstat, w, kill, free, slabtop ve skill gibi uygulamaları içerir. + http://procps.sf.net/procps-3.2.8.tar.gz + + ncurses-devel + + + procps-3.2.5-proc-mount.patch + nohz.patch + procps-3.2.5-eof.diff + procps-3.2.2-top-termsize.patch + procps-3.2.2-w-simply-work.diff + procps-3.2.7-top.1.diff + pwdx-bufferoverflow.diff + procps-3.2.7-libselinux.patch + procps-3.2.7-ps-libselinux.patch + procps-3.2.7-misc.patch + procps-3.2.7-FAQ.patch + procps-3.2.7-noproc.patch + procps-3.2.7-pseudo.patch + procps-3.2.7-0x9b.patch + procps-3.2.7-sysctl-writeonly.patch + procps-3.2.7-top-rc.patch + procps-3.2.7-top-remcpu.patch + procps-3.2.7-top-env-vmsize.patch + procps-3.2.7-top-env-cpuloop.patch + procps-3.2.7-vmstat-cpusteal.patch + procps-3.2.7-longcmd.patch + procps-3.2.7-vmstat-pgpg.patch + procps-3.2.7-sysctl-ignore.patch + procps-3.2.7-top-sorthigh.path + procps-3.2.7-w-best.patch + procps-3.2.7-watch-unicode.patch + procps-3.2.7-ps-stime.patch + procps-3.2.7-ps-eip64.patch + procps-3.2.7-psman.patch + procps-3.2.7-top-cpu0.patch + procps-3.2.7-top-cpuint.patch + procps-3.2.7-top-manpage.patch + procps-3.2.7-top-clrscr.patch + procps-3.2.7-ps-man-fmt.patch + procps-3.2.7-vmstat-partstats-long.patch + procps-3.2.7-vmstat-header.patch + procps-3.2.7-slabtop-once.patch + procps-3.2.7-vmstat-timestamp.patch + procps-3.2.7-vmstat-timestamp-manpage.patch + procps-3.2.7-ps-cgroup.patch + procps-3.2.7-vmstat-partstats-reqwrites.patch + procps-3.2.7-free-hlmem.patch + procps-3.2.8-threads.patch + procps-enable-core.patch + procps-3.2.8-setlocale.patch + procps-pmap-smaps.patch + procps-3.2.8-vmstat-getopt.patch + procps-3.2.8-ps-cgroup-suppress-root-group.patch + procps-3.2.8-make.patch + procps-3.2.8-constructor-order.patch + + system/base/procps/pspec.xml + + + procps + + ncurses + + + /bin + /sbin + /lib + /usr/bin + /usr/share/doc + /usr/share/man + /usr/include + + + + + 2014-05-11 + 3.2.8 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2010-10-12 + 3.2.8 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + mailcap + http://git.fedorahosted.org/git/mailcap.git + + PisiLinux Community + admins@pisilinux.org + + MIT + public-domain + data + system.base + Helper application and MIME type associations for file types + Dosya türleri için yardımcı uygulama ve MIME türü ilişkilendirmeleri + mailcap file is used by the metamail program. Metamail reads the mailcap file to determine how it should display non-text or multimedia material. + mailcap dosyası metamail ve bazı diğer uygulamalar tarafından, metin olmayan dosyaların ya da çokluortam dosyalarının nasıl açılacağını keşfetmek için kullanılır. + https://fedorahosted.org/released/mailcap/mailcap-2.1.42.tar.xz + + extend-mailcap.patch + + system/base/mailcap/pspec.xml + + + mailcap + + /etc + /usr/share/doc + /usr/share/man + + + + + 2014-05-11 + 2.1.42 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-29 + 2.1.42 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2011-06-01 + 2.1.37 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + pisi + http://www.pisilinux.org/ + + Marcin Bojara + marcin@pisilinux.org + + GPLv2 + app:console + system.base + PISI is the package management system of Pisi Linux + PİSİ PiSi Linux'un paket yönetim sistemidir + PiSi – menadżer pakietów dla PiSi Linux. + PISI est gestionnaire de paquets moderne implémenté en Python.Ces principales fonctionnalités sont les suivantes : - Les paquets sources sont écrits en XML et en python - Implemente tout les fonctions à travers une API simple d'utilisation - Intègre aussi bien les fonctionnalités de bas niveaux que de haut niveau de gestion de paquets. + PISI is a modern package management system implemented in Python. Some of its main features are: package sources are written in XML and python, implements all functions through a simple-to-use API, integrates low-level and high-level package management features. + PİSİ Python'da yazılmış modern bir paket yöneticisidir. Bazı ana özellikleri: Paket kaynakları XML ve python kullanılarak yazılır, bütün işlevleri kullanması kolay bir API ile sağlar ve düşük ve yüksek seviyeli paket yönetim işlevlerini birleştirir. + PISI jest podstawowym narzędziem do instalacji, aktualizacji i usuwania pakietów. Obsługuje zależności dla poszczególnych pakietów, bibliotek i zadań ÇOMAR-a. Instalacja oprogramowania odbywa się w łatwy i przyjazny sposób. Do przechowywania informacji o pakietach wykorzystuje bazę Berkeley DP, co zapewnia większą stabilność i szybkość. + http://source.pisilinux.org/1.0/pisi-2.6.tar.xz + + pisi.conf-i686 + pisi.conf-x86_64 + + + comar + plyvel + python + gettext + intltool + leveldb-devel + + + initialize_filesdb_once.patch + no_clean_if_ignore_comar.patch + orphaned_pkgs.patch + improve_pisi_ix.patch + fix_emul32_flags.patch + pisi-2.6-pisitools.dopixmaps-add.patch + + system/base/pisi/pspec.xml + + + pisi + + tar + file + comar + plyvel + python + gettext + leveldb + piksemel + comar-api + urlgrabber + python-psutil + libunwind + python-pyliblzma + mudur + + + /usr/bin + /usr/sbin + /usr/lib/pardus/pisi + /usr/lib/pisilinux/pisi + /usr/share/locale + /usr/share/doc + /etc/pisi + /usr/share/mime/packages + /usr/lib/tmpfiles.d/pisi.conf + /run/lock/files.ldb/LOCK + /var/lib/pisi/info/files.ldb/LOCK + + + System.Package + System.Manager + + + mirrors.conf + sandbox.conf + pisi.xml + pkgconfig.py + tmpfiles.conf + qt5.py + + + + + 2015-05-04 + 2.6 + Add qt5 api + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + + + 2014-12-07 + 2.6 + Add new pisitools.dopixmaps + Osman Erkan + osman.erkan@pisilinux.org + + + 2014-09-15 + 2.6 + Add new pisi commands: list-orphaned and remove-orphaned. + Improve pisi index. + Marcin Bojara + marcin@pisilinux.org + + + 2014-08-04 + 2.6 + pisi search-file works without sudo now. + Marcin Bojara + marcin@pisilinux.org + + + 2014-07-25 + 2.6 + Rebuild for version number. + Aydın Demirel + aydin.demirel@pisilinux.org + + + 2014-06-24 + 2.6 + Add patch for initialize filesdb once. + Marcin Bojara + marcin@pisilinux.org + + + 2014-06-15 + 2.6 + Version bump. + revdep-rebuild rewritten in python. + Marcin Bojara + marcin@pisilinux.org + + + 2014-06-08 + 2.5 + Add case sensitive for 'pisi sr'. + Change install path. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-27 + 2.5 + Add patch level auto detection feature, + sha1sum for install.tar.xz file, + check sha1sum for upgrade. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 2.5 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 2.5 + Some improvements for buildfarm. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-04 + 2.5 + Handle error for file command. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-16 + 2.5 + Workaround for update espeak package. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-07 + 2.5 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-02-28 + 2.4 + Fix pisitools.dosed output. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-13 + 2.4 + Workaround for the case where old dir /a/b/c is replaced by file c in /a/b dir. + Marcin Bojara + marcin@pisilinux.org + + + 2013-11-12 + 2.4 + Fix stripping issues, in file info: LSB executable, LSB shared syntax. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-22 + 2.4 + Disable python_installation patch to check python upgrading breaks pisi or not. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-25 + 2.4 + Fix autocompletion for local uncompressed index file. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-21 + 2.4 + Fix upgrading python package. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-01 + 2.4 + Improve managing CFLAGS, CXXFLAGS and LDFLAGS, + export HOME=get.workDIR() as default. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-25 + 2.4 + Fix and improve kerneltools. + Avoid double slashes pisi error. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-11 + 2.4 + adjust takeback to new dir structure. + Marcin Bojara + marcin@pisilinux.org + + + 2013-06-21 + 2.4 + No capital letters in directory names. + Marcin Bojara + marcin@pisilinux.org + + + 2013-06-17 + 2.4 + Fix overwrite 64bit libs by 32bit for some packages + Marcin Bojara + marcin@pisilinux.org + + + 2013-06-02 + 2.4 + Add sorting packages for pisi ix + Marcin Bojara + marcin@pisilinux.org + + + 2013-05-15 + 2.4 + Add pisitools.flags() and pisitools.ldflags() + Marcin Bojara + marcin@pisilinux.org + + + 2013-05-12 + 2.4 + Sandbox.conf edit. + PisiLinux Community + admins@pisilinux.org + + + 2013-03-20 + 2.4 + Add patch for speed up packaging process + Marcin Bojara + marcin@pisilinux.org + + + 2013-03-14 + 2.4 + Improve dosed + Marcin Bojara + marcin@pisilinux.org + + + 2013-02-14 + 2.4 + Add assign-devel-and-doc-packages.patch. + Marcin Bojara + marcin@pisilinux.org + + + 2013-01-18 + 2.4 + First release. + Marcin Bojara + marcin@pisilinux.org + + + + + + wireless-tools + http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + A collection of tools to configure wireless lan cards + Kablosuz ağ kartlarını yapılandırmak için kullanılan bir araç seti + Les outils sans fil (Wireless Tools ou WT) est un ensemble d'outils permettant de manipuler les extensions sans fil, c'est une interface de programmation d'application (API) générique permettant à un pilote d'exposer à l'espace utilisateur la configuration ainsi que des statistiques spécifiques aux LANs sans fil communs. Ils utilisent une interface textuelle assez rugueuse, mais ont pour objectif de couvrir la totalité de l'extension sans fil. + The Wireless Tools (WT) is a set of tools allowing to manipulate the Wireless Extensions, a generic application programming interface allowing a driver to expose to the user space configuration and statistics specific to common Wireless LANs. They use a textual interface and are rather crude, but aim to support the full Wireless Extension. + Wireless Extensions, sürücülerin bilinen kablosuz ağların ayarlarını yapmak ve istatistiklerini görüntülemek amacıyla kullandığı bir yazılım programlama arayüzüdür. Wireless Tools ise Wireless Extensions ayarlarını modifiye etmek için kullanılan araçları içeren bir pakettir. Grafik arayüzü bulunmaz, biraz da kabadır; ancak Wireless Extension'u tam olarak desteklemeyi hedefler. + http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/wireless_tools.30.pre9.tar.gz + + no-ldconfig.patch + wireless_tools.27-wireless-man-upd.patch + wireless-tools-29-makefile.patch + + system/base/wireless-tools/pspec.xml + + + wireless-tools + + comar + + + /sbin + /usr/lib + /usr/share/man + /usr/share/doc + + + + wireless-tools-devel + Development files for wireless-tools + wireless-tools için geliştirme dosyaları + system.devel + + wireless-tools + + + /usr/include + /usr/share/man/man3 + + + + + 2015-05-08 + 30 + Release bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 30 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 30 + Güncellendi. + PisiLinux Community + admins@pisilinux.org + + + 2013-02-11 + 30 + Güncellendi. + PisiLinux Community + admins@pisilinux.org + + + 2011-06-01 + 29 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + libee + http://www.libee.org/ + + Marcin Bojara + marcin@pisilinux.org + + LGPLv2.1 + library + system.base + An Event Expression Library inspired by CEE + Libee - An Event Expression Library inspired by CEE + http://www.libee.org/download/files/download/libee-0.4.1.tar.gz + + libestr-devel + + system/base/libee/pspec.xml + + + libee + + libestr + + + /usr/sbin + /usr/lib/libee.so* + /usr/share/doc/libee + + + + libee-devel + Development files for libestr + system.devel + + libee + + + /usr/include/libee + /usr/lib/pkgconfig/libee.pc + + + + + 2014-05-11 + 0.4.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 0.4.1 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-11-21 + 0.4.1 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + busybox + http://www.busybox.net + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + Statically linked binary providing simplified versions of system commands + Statik bağlanmış sistem komutları bütünü + busybox is a single binary which includes versions of a large number of system commands, including a shell. + busybox, kabuk da dahil olmak üzere çeşitli sistem komutlarını içeren tek bir çalıştırılabilir dosyadır. + http://busybox.net/downloads/busybox-1.22.1.tar.bz2 + + config + + + udhcp-rootpath-rq.patch + suppress-job-control-warning.patch + fix-include.patch + + system/base/busybox/pspec.xml + + + busybox + + /bin + + + + + 2014-05-11 + 1.22.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-03-29 + 1.22.1 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-01-14 + 1.21.0 + New release + PisiLinux Community + admins@pisilinux.org + + + 2012-08-23 + 1.20.2 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + lzo + http://www.oberhumer.com/opensource/lzo/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.base + An extremely fast compression and decompression library + Çok hızlı bir sıkıştırma/açma kütüphanesi + lzo is a library with very high compression and decompression speeds and very small memory usage. Provides low compression ratios but very high speeds. + lzo hızlı bir sıkıştırma/açma kütüphanesidir. Düşük sıkıştırma oranları verir fakat hem sıkıştırma hem açma işleminde bellek kullanımı çok düşüktür ve işlem hızı yüksektir. + http://www.oberhumer.com/opensource/lzo/download/lzo-2.09.tar.gz + system/base/lzo/pspec.xml + + + lzo + + /usr/lib + /usr/share/doc + + + + lzo-devel + Development files for lzo + lzo için geliştirme dosyaları + + lzo + + + /usr/include + + + + lzo-32bit + 32-bit shared libraries for lzo + emul32 + emul32 + + glibc-32bit + + + glibc-32bit + + + /usr/lib32 + + + + + 2015-04-12 + 2.09 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-07-03 + 2.08 + Version bump and security update (CVE-2014-4607). + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 2.06 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-28 + 2.06 + Clean lzo. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-10-23 + 2.06 + First release + Erdinç Gültekin + admins@pisilinux.org + + + + + + libusb-compat + http://libusb.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + LGPLv2.1 + library + system.base + Userspace access to USB devices + Project's main aim is to create a library for use by user level applications to access USB devices regardless of OS. + mirrors://sourceforge/libusb/libusb-compat-0.1.5.tar.bz2 + + libtool + libusb-devel + + system/base/libusb-compat/pspec.xml + + + libusb-compat + + libusb + + + /usr/lib + /usr/share/doc + + + + libusb-compat-devel + Development files for libusb + system.devel + + libusb-devel + libusb-compat + + + /usr/bin + /usr/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + + + + libusb-compat-32bit + 32-bit shared libraries for libXt + emul32 + emul32 + + libusb-32bit + glibc-32bit + + + libusb-32bit + libusb + glibc-32bit + libusb-compat + + + /usr/lib32 + + + + + 2015-05-05 + 0.1.5 + Rebuild for libusbx libusb changes + Use auto-emul32, cleanup actions.py + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 0.1.5 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-29 + 0.1.5 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-07-21 + 0.1.4 + First release + Erdinç Gültekin + admins@pisilinux.org + + + + + + dhcpcd + http://roy.marples.name/dhcpcd + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.base + A dhcp client only + DHCP protokolü için istemci + Un client daemon DHCP conforme aux RFC2131 et RFC1541. dhcpcd obtient une adresse IP ainsi que d'autres informations depuis le serveur DHCP correspondant, configure l'interface réseau automatiquement et essaie de renouveler le bail selont les RFC2131 et EFC1541 en fonction des options de la ligne de commande. + An RFC2131 and RFC1541 compliant DHCP client daemon. dhcpcd gets an IP address and other information from a corresponding DHCP server, configures the network interface automatically, and tries to renew the lease time according to RFC2131 or RFC1541 depending on the command line option. + RFC2131 ve RFC1541 uyumlu bir DHCP istemci servisi.dhcpcd ilgili bir DHCP sunucusundan bir IP adresi ve gerekli diğer bilgileri alır, ağ arayüzünü otomatik olarak yapılandırır ve RFC2131 veya RFC1541 komut satırı özelliğine bağlı olarak kiralama zamanını yenilemeyi dener. + http://ftp.osuosl.org/pub/blfs/conglomeration/dhcpcd/dhcpcd-6.8.1.tar.bz2 + system/base/dhcpcd/pspec.xml + + + dhcpcd + + /etc + /lib/dhcpcd + /usr/lib/dhcpcd/dev/udev.so + /sbin + /usr/share/doc + /usr/share/man + /var/lib/dhcpcd + + + + + 2015-05-03 + 6.8.1 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-02-03 + 6.7.1 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + + + 2014-05-11 + 6.3.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-03 + 6.3.2 + Version bump. + PisiLinux Community + admins@pisilinux.org + + + 2013-10-31 + 6.0.5 + Really revert back to 6.0.5. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-28 + 6.0.5 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-01-14 + 5.6.7 + New release + PisiLinux Community + admins@pisilinux.org + + + 2012-08-23 + 5.6.1 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + findutils + http://www.gnu.org/software/findutils/findutils.html + + PisiLinux Community + admins@pisilinux.org + + GPLv3+ + app:console + system.base + GNU utilities to find files + Dosya bulmak için kullanılan GNU uygulamaları + Les utilitaires de recherche GNU sont les utilitaire de recherche de répertoire basique du système d'exploitation GNU. Ces programmes sont typiquement associés à d'autres programmes pour leur fournir une capacité de recherche de fichier et de répertoire puissante et modulaire à d'autres commandes. + The GNU Find Utilities are the basic directory searching utilities of the GNU operating system. These programs are typically used in conjunction with other programs to provide modular and powerful directory search and file locating capabilities to other commands. + GNU Find Utilities GNU işletim sisteminin temel dizin arama uygulamalarıdır. Bu uygulamalar diğer komutlara başka programlar ile birlikte çalışarak modüler ve güçlü dizin ve dosya arama yetenekleri sunar. + http://ftp.gnu.org/pub/gnu/findutils/findutils-4.4.2.tar.gz + + gettext-devel + + system/base/findutils/pspec.xml + + + findutils + + /usr/bin + /usr/lib/find + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/locale + + + + + 2014-05-11 + 4.4.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-01 + 4.4.2 + Revert back to stable version, clean findutils. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-09-14 + 4.5.9 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + gperftools @@ -5800,267 +11161,586 @@ - nettle - http://www.gnu.org + openssl + http://www.openssl.org/ + + PisiLinux Community + admins@pisilinux.org + + as-is + app:console + library + system.base + Toolkit for SSL v2/v3 and TLS v1 + SSL v2/v3 ve TLS v1 için araç kiti + OpenSSL est un outil cryptographique implémentant une couche de communication sécurisée (SSL v2/v3) et une couche de transport sécurisée (TLS v1) + OpenSSL is a cryptography toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) network protocols and related cryptography standards required by them. + OpenSSL, Güvenlik Soketleri Katmanı (SSL v2/v3) ve Aktarım Katmanı Güvenliği (TLSv1) ağ protokolleri ile bu protokollerin gerektirdiği şifreleme standartlarını uygulayan bir şifreleme aracıdır. + OpenSSL ist ein Kryptographie Werkzeug, das die Netzwerkprotokolle Secure Sockets Layer (SSL v2/v3) und Transport Layer Security (TLS v1) sowie deren erforderliche zugehörige Kryptographie Standards implementiert. + ftp://ftp.openssl.org/source/openssl-1.0.2a.tar.gz + + openssl-1.0.0-beta4-ca-dir.patch + + + zlib-devel + xorg-util + perl + sed + + + openssl-1.0.0a-ldflags-norpath.patch + openssl-1.0.0-beta4-ca-dir.patch + openssl-1.0.0-beta5-enginesdir.patch + openssl-1.0.2-ipv6.patch + openssl-1.0.2-s_client-verify.patch + openssl-include.patch + openssl_fix_for_x32.patch + + system/base/openssl/pspec.xml + + + openssl + + zlib + ca-certificates + + + /etc + /usr/bin + /usr/lib + /usr/share/doc + + + System.Package + + + + openssl-devel + Development files for openssl + openssl için geliştirme dosyaları + system.devel + + openssl + + + /usr/include + /usr/share/man + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + + + + openssl-32bit + 32-bit shared libraries for openssl + openssl için 32-bit paylaşımlı kitaplıklar + emul32 + _emul32 + + zlib-32bit + + + openssl + zlib-32bit + glibc-32bit + + + /usr/lib32 + + + + + 2015-04-11 + 1.0.2a + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-02-17 + 1.0.2 + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-11-05 + 1.0.1j + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-06-05 + 1.0.1h + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 1.0.1g + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-09 + 1.0.1g + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-02-02 + 1.0.1f + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-28 + 1.0.1e + Clean openssl. + Serdar Soytetir + kaptan@pisilinux.org + + + security + 2013-01-14 + 1.0.1e + New release + PisiLinux Community + admins@pisilinux.org + + + security + 2012-08-31 + 1.0.1c + First release + Erdem Artan + admins@pisilinux.org + + + + + + kmod + http://git.kernel.org/?p=utils/kernel/kmod/kmod.git;a=summary + + PisiLinux Community + admins@pisilinux.org + + GPLv2+ + app:console + system.base + Linux kernel module management utilities + Linux kernel modülleri yönetim araçları + Linux kernel module management utilities + Linux kernel modülleri yönetim araçları + https://www.kernel.org/pub/linux/utils/kernel/kmod/kmod-20.tar.xz + + chrpath + xz-32bit + xz-devel + zlib-32bit + zlib-devel + kernel-module-headers + + + kmod-15-dynamic-kmod.patch + + system/base/kmod/pspec.xml + + + kmod + + xz + zlib + glibc + libkmod + + + /usr/bin + /bin + /sbin + /usr/share/man + /usr/share/doc + /etc + /usr/share/bash-completion/completions/kmod + + + Boot.Modules + System.PackageHandler + + + blacklist/blacklist.conf + blacklist/blacklist-firewire.conf + blacklist/blacklist-framebuffer.conf + blacklist/blacklist-watchdog.conf + modprobe.conf + depmod.conf + depmod-search.conf + + + + libkmod-devel + system.devel + + libkmod + + + /usr/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + + + + libkmod + kmod libraries + + xz + zlib + + + /usr/lib + + + + libkmod-32bit + 32bit libraries of libkmod + emul32 + emul32 + + xz-32bit + zlib-32bit + glibc-32bit + + + /usr/lib32 + + + + + 2015-03-26 + 20 + Version bump,add patch and fix deps. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-11-18 + 19 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-23 + 17 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 16 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-21 + 16 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-05 + 15 + Add missing method to pakhandler.py + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-31 + 15 + Version bump, clean kmod. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-20 + 14 + rebuild for kernel 3.10.9 + PisiLinux Community + admins@pisilinux.org + + + 2013-08-11 + 14 + rebuild for kernel 3.10.5 + PisiLinux Community + admins@pisilinux.org + + + 2013-07-27 + 14 + Move pc files to devel pack, rebuild + PisiLinux Community + admins@pisilinux.org + + + 2013-07-04 + 14 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-04-14 + 13 + Version bump + Marcin Bojara + marcin@pisilinux.org + + + 2013-01-22 + 12 + Version bump, add comar scripts + Marcin Bojara + marcin@pisilinux.org + + + 2012-11-15 + 11 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + cryptsetup + https://gitlab.com/cryptsetup/cryptsetup + + Erdem Artan + admins@pisilinux.org + + GPLv2 + app:cli + system.base + Userspace setup tool for transparent encryption of block devices using dm-crypt + Şifreli dosya sistemleri yaratmak için bir araç + Userspace setup tool for transparent encryption of block devices using dm-crypt + cryptsetup device mapper kullanarak şifrelenmiş dosya sistemleri yaratmak için gerekli bir araçtır. + cryptsetup + https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.7.tar.xz + + device-mapper-devel + libgpg-error-devel + libgcrypt-devel + python-devel + libutil-linux-devel + popt-devel + popt + + system/base/cryptsetup/pspec.xml + + + cryptsetup + + libcryptsetup + popt + + + /sbin + /usr/share/man + /usr/share/locale + /usr/share/doc + + + + libcryptsetup + cryptsetup libraries + cryptsetup kütüphaneleri + + device-mapper + libgpg-error + libgcrypt + libutil-linux + + + /lib/libcryptsetup.so* + + + + libcryptsetup-devel + libcryptsetup devel files + libcryptsetup için geliştirme dosyaları + + libcryptsetup + + + /usr/include + /usr/lib/pkgconfig/libcryptsetup.pc + + + + python-pycryptsetup + Python backend for cryptsetup + cryptsetup Python bağlayıcısı + programming.language.python + + python + libcryptsetup + + + /usr/lib/python2.7/site-packages/pycryptsetup.so + + + + + 2015-04-30 + 1.6.7 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-04-01 + 1.6.4 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-03 + 1.6.4 + Version bump + PisiLinux Community + admins@pisilinux.org + + + 2014-03-06 + 1.6.0 + Rebuild Unused + Varol Maksutoğlu + waroi@pisilinux.org + + + 2013-07-26 + 1.6.0 + Fix dep, release bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-15 + 1.6.0 + New version + Ertan Güven + ertan@pisilinux.org + + + 2012-10-05 + 1.5.0 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + libidn + http://www.gnu.org/software/libidn PisiLinux Community admins@pisilinux.org LGPLv2.1 + GPLv3 + app:console library - util.crypt - The Nettle package contains the low-level cryptographic library. - Nettle - biblioteka kryptograficzna. - The Nettle package contains the low-level cryptographic library that is designed to fit easily in many contexts. - ftp://ftp.gnu.org/gnu/nettle/nettle-2.7.1.tar.gz - - gmp-devel - - system/base/nettle/pspec.xml + system.base + Internationalized Domain Names (IDN) implementation + Uluslararası Alan Adları (IDN) destek kütüphanesi + GNU Libidn est une implémentation de Stringprep, Punycode et des spécifications IDNA définies par le groupe de travail Internationalized Domain Names (IDN) de l'IETF servant pour les noms de domaines internationalisés. La librairie C est disponible sous la Licence Publique Générale Lesser. + GNU Libidn is an implementation of the Stringprep, Punycode and IDNA specifications defined by the IETF Internationalized Domain Names (IDN) working group, used for internationalized domain names. The C library is available under the GNU Lesser General Public License. + GNU Libidn, IETF Uluslararasılaştırılmış Domain Adları (IDN) çalışma grubu tarafından tanımlanmış Stringgrep, Punycode ve IDNA tariflerinin bir uygulamasıdır, uluslararası domain adlarının kullanımına olanak sağlar. C kütüphanesi GNU Lesser General Public License altında sağlanabilir. + http://ftp.gnu.org/gnu/libidn/libidn-1.28.tar.gz + system/base/libidn/pspec.xml - nettle - - gmp - + libidn /usr/bin - /usr/lib - /usr/share/info - /usr/share/doc - - - - nettle-devel - Nettle için geliştirme dosyaları - nettle için geliştirme dosyaları. - Pliki nagłówkowe biblioteki nettle. - - nettle - - - /usr/include - /usr/lib/pkgconfig/nettle.pc - /usr/lib/pkgconfig/hogweed.pc - /usr/lib32/pkgconfig/nettle.pc - /usr/lib32/pkgconfig/hogweed.pc - - - - nettle-32bit - 32-bit shared libraries for nettle - emul32 - emul32 - - gmp-32bit - - - nettle-devel - gmp-32bit - - - /usr/lib32/ - - - - - 2014-05-11 - 2.7.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-28 - 2.7.1 - Version bump, clean nettle. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-26 - 2.6 - Move pc files to devel pack, rebuild. - Erdinç Gültekin - erdincgultekin@pisilinux.org - - - 2013-02-14 - 2.6 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2012-09-29 - 2.5 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - mingetty - ftp://ftp.suse.com/pub/projects/init/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - A compact getty program for virtual consoles only - Sadece sanal konsollar için yekpare bir getty programı - mingetty, est getty poids plume minimaliste à utiliser exclusivement sur les consoles virtuelles. - mingetty, is a lightweight, minimalist getty for use on virtual consoles only. - mingetty yalnızca sanal konsollar için tasarlanmış basit ve yalın getty uygulamasıdır. - http://sourceforge.net/projects/mingetty/files/mingetty/1.08/mingetty-1.08.tar.gz - - gettext - - - tr.patch - - system/base/mingetty/pspec.xml - - - mingetty - - glibc - - - /sbin + /usr/lib/libidn* + /usr/share/emacs /usr/share/locale - /usr/share/man + /usr/share/man/man1 + /usr/share/info /usr/share/doc - - - 2014-05-11 - 1.0.8 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-02-09 - 1.0.8 - Rebuild - Kamil Atlı - suvarice@gmail.com - - - 2012-08-23 - 1.0.8 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - libcap - http://www.kernel.org/pub/linux/libs/security/linux-privs/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - BSD - library - system.base - capacités POSIX 1003.1e. - POSIX 1003.1e capabilities library - POSIX 1003.1e desteği - libcap is a library for getting and setting POSIX.1e (formerly POSIX 6) draft 15 capabilities. - https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-2.24.tar.xz - - attr-devel - pam - - system/base/libcap/pspec.xml - - libcap - - pam - attr - - - /sbin - /lib - /usr/lib - /usr/share/man - /usr/share/doc - /etc - - - - libcap-devel - Development files for libcap - libcap için geliştirme dosyaları + libidn-devel + Development files for libidn + libidn için geliştirme dosyaları system.devel + + glibc-32bit + - libcap + libidn /usr/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig /usr/share/man/man3 - libcap-32bit - 32-bit shared libraries for libcap - libcap için 32-bit paylaşımlı kitaplıklar + libidn-32bit + 32-bit shared libraries for libidn + libidn için 32-bit paylaşımlı kitaplıklar emul32 emul32 - - attr-32bit - - libcap - attr-32bit + libidn - /usr/lib32 + /usr/lib32/libidn* - - 2014-05-11 - 2.24 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - 2014-04-03 - 2.24 - Version bump. + 2014-05-11 + 1.28 + Release bump. Marcin Bojara marcin@pisilinux.org 2013-10-29 - 2.22 - Rebuild + 1.28 + Version bump. Yusuf Aydemir yusuf.aydemir@pisilinux.org - 2013-01-24 - 2.22 - Use flags form pisi.conf, fix emul32 - Marcin Bojara - marcin@pisilinux.org + 2013-01-14 + 1.26 + New release + PisiLinux Community + admins@pisilinux.org - 2012-10-01 - 2.22 + 2012-08-23 + 1.25 First release PisiLinux Community admins@pisilinux.org @@ -6069,519 +11749,802 @@ - man-pages - http://www.win.tue.nl/~aeb/linux/man/ + zlib + http://www.gzip.org/zlib/ PisiLinux Community admins@pisilinux.org - GPLv2 - data:doc + ZLIB + library system.base - Une collection de pages de manuel Linux compréhensibles d'une certaine manière. - A somewhat comprehensive collection of Linux man pages - Kapsamlı Linux kılavuz dökümanları - A large collection of man pages (documentation) from the Linux Documentation Project (LDP). - http://ftp.kernel.org/pub/linux/docs/man-pages/man-pages-3.70.tar.xz - http://www.kernel.org/pub/linux/docs/man-pages/man-pages-posix/man-pages-posix-2003-a.tar.xz - system/base/man-pages/pspec.xml + Librairie de compression/extraction standard + Standard (de)compression library + Standart sıkıştırma/açma kütüphanesi + Zlib is a general-purpose, patent-free, lossless data compression library which is used by many different programs. + mirrors://sourceforge/libpng/zlib-1.2.8.tar.xz + + dont-call-ldconfig.patch + + system/base/zlib/pspec.xml - man-pages + minizip + Library for manipulating files from a zip archive + zip arşivlerindeki dosyaları yönetmek için kitaplık + util.archive + minizip - man-db + zlib + /usr/lib/libminizip* + + + + minizip-devel + Development files for minizip + minizip için geliştirme dosyaları + util.archive + minizip + + minizip + zlib-devel + + + /usr/include/minizip + /usr/lib/pkgconfig/minizip.pc + + + + zlib + + /lib/libz.so* + /usr/lib/libz.so* /usr/share/doc /usr/share/man - - man1/getent.1 - man1/sprof.1 - + + + zlib-devel + Development files for zlib + zlib için geliştirme dosyaları + system.devel + + zlib + + + /usr/lib/pkgconfig/zlib.pc + /usr/lib32/pkgconfig + /usr/include/z*.h + /usr/share/man/man3 + /usr/share/doc/zlib/algorithm.txt + /usr/share/doc/zlib/example.c + + + + zlib-32bit + 32-bit shared libraries for zlib + zlib için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + glibc-32bit + + + glibc-32bit + zlib + + + /usr/lib32/libz.so* + - - 2014-07-13 - 3.70 - Version bump. - Vedat Demir - vedat@pisilinux.org - - + 2014-05-11 - 3.55 + 1.2.8 Release bump. Marcin Bojara marcin@pisilinux.org - - 2013-10-28 - 3.55 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - 2013-10-28 - 3.47 - Version bump. + 2013-08-27 + 1.2.8 + Clean zlib. Serdar Soytetir kaptan@pisilinux.org - 2013-03-04 - 3.47 + 2013-06-29 + 1.2.8 Version bump. - Serdar Soytetir - kaptan@pisilinux.org + Marcin Bojara + marcin@pisilinux.org - 2011-01-04 - 3.32 + 2012-06-03 + 1.2.7 First release - Pisi Linux Admins + Erdem Artan admins@pisilinux.org - readline - http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html + comar + http://www.pisilinux.org PisiLinux Community admins@pisilinux.org GPLv2 - library + service system.base - Another cute console display library - Diğer bir şirin konsol gösterim kütüphanesi - La librairie GNU Readline fourni un ensemble de fonctions utilisables par des applications permettant aux utilisateurs d'éditer les lignes de commandes en cours de frappe. Les modes d'éditions Emacs et vi sont disponibles. La librairie Readline inclus des fonctions supplémentaires de mémorisation de la liste de commandes entrées précédemment, afin de le rappeler et éventuellement les rééditer, ainsi que l'expansion d'historiques de commandes précédentes à la mode csh. - The GNU Readline library provides a set of functions for use by applications that allow users to edit command lines as they are typed in. Both Emacs and vi editing modes are available. The Readline library includes additional functions to maintain a list of previously-entered command lines, to recall and perhaps reedit those lines, and perform csh-like history expansion on previous commands. - GNU Readline kütüphanesi uygulamalara sanki kullanıcılar kendileri yazıyormuş gibi komut satırı girişlerini düzenleme imkanı veren işlev setini sunar. Readline kütüphanesi daha önce girilmiş bir komut satırları listesini düzenleme, tekrar çağırma ve belki de bu satırları tekrar düzenleme ve csh tipi geçmiş bilgisi genişletmelerindeki önceki komutları yürütme imkanı sağlayan ek işlevler sağlar. - mirrors://gnu/readline/readline-6.3.tar.gz + Manages system configuration + Sistem yapılandırmasını yönetir + Les programmes Pisi Linux sont mis sous forme de paquets à l'aide de petits scripts. Ces derniers les configure afin qu'ils s'intègrent entre eux et avec le système. Çomar est l'outil qui gère et exécute ces scripts. + Pisi Linux programs are packaged with small scripts which configures them to entegrate with system and each other. Çomar is the tool which manages and executes these scripts. + Pisi Linux yazılımları, birbirleri ve sistemle otomatik olarak uyum sağlayabilmek için yanlarında ufak programcıklar ile paketlenmektedir. Bu programcıkların yönetimi ve işletilmesi Çomar aracı tarafından yapılmaktadır. + Pisi Linux Programme werden mit einem kleinen Skript paketiert, welches sie konfiguriert, um die Integrität mit dem System und anderen Programmen sicherzustellen. Comar ist das Werkzeug, das diese Skripte verwaltet und ausführt. + http://source.pisilinux.org/1.0/comar-3.0.3.tar.bz2 - ncurses-devel + dbus-devel + python-devel - readline63-001.patch - readline63-002.patch - readline63-003.patch + run_dir.patch + fix-flags.patch + update-system-manager-model.patch - system/base/readline/pspec.xml + system/base/comar/pspec.xml - readline + comar - ncurses + dbus + python + polkit - /usr/lib - /usr/share/doc - /usr/share/man - /usr/share/info - - - - readline-devel - Development files for readline - readline için geliştirme dosyaları - system.devel - - readline - - - /usr/include - /usr/share/man/man3 - - - - readline-32bit - 32-bit shared libraries for readline - readline için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - ncurses-32bit - - - readline - ncurses-32bit - - - /usr/lib32 + /usr/bin + /usr/sbin + /etc + /usr/share/dbus-1/system-services + /usr/share/polkit-1/actions + /usr/share/doc/ + /var/db + + System.Package + - 2014-05-11 - 6.3 - Release bump. + 2015-04-01 + 3.0.3 + Fix run dir path. Marcin Bojara marcin@pisilinux.org - 2014-04-05 - 6.3 - Version bump. + 2014-05-11 + 3.0.3 + Release bump. Marcin Bojara marcin@pisilinux.org 2013-08-31 - 6.2_004 - Clean readline. - Marcin Bojara - marcin@pisilinux.org + 3.0.3 + Release bump, clean comar. + Serdar Soytetir + kaptan@pisilinux.org - 2012-08-31 - 6.2 + 2011-05-18 + 3.0.3 First release - Erdem Artan + Pisi Linux Admins admins@pisilinux.org - lsb-release - http://www.linuxbase.org + rsyslog + http://www.rsyslog.com PisiLinux Community admins@pisilinux.org - GPLv2 - app:console + GPLv3+ + service system.base - LSB version query program - LSB sürüm sorgulama aracı - lsb-release prints certain LSB (Linux Standard Base) and distribution information. - lsb-release bazı dağıtıma özel tanımlayıcı bilgileri ekrana basan bir terminal aracıdır. - mirrors://sourceforge/project/lsb/lsb_release/1.4/lsb-release-1.4.tar.gz - system/base/lsb-release/pspec.xml + Enhanced system logging and kernel message trapping daemons + Gelişmiş sistem günlükleme hizmeti + rsyslog is an enhanced multi-threaded syslogd supporting, among others, MySQL, syslog/tcp, RFC 3195, permitted sender lists, filtering on any message part, and fine grain output format control. It is quite compatible with stock sysklogd and can be used as a drop-in replacement. + rsyslog, çoklu iş parçacığı, MySQL, syslog/tcp, RFC 3195, izin verilen gönderici listesi, gelişmiş ileti filtreleme gibi özelliklere sahip gelişmiş bir sistem günlükleme hizmetidir. + http://www.rsyslog.com/files/download/rsyslog/rsyslog-8.9.0.tar.gz + + zlib-devel + json-c-devel + libestr-devel + libgcrypt-devel + liblogging-devel + + system/base/rsyslog/pspec.xml - lsb-release + rsyslog + + zlib + json-c + libestr + libgcrypt + liblogging + - /usr/bin - /etc + /usr/bin/rsyslogd + /usr/lib/rsyslog /usr/share/man /usr/share/doc + /etc/logrotate.d + /etc/conf.d + /etc/rsyslog.d + /etc/rsyslog.conf + + System.Service + - lsb-release + rsyslog.logrotate + rsyslog.conf + 50-default.conf + rsyslog.sysconfig - - 2015-01-16 - 1.4 - Release Pisi Linux 1.2 - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-11-03 - 1.4 - Release Pisi Linux 1.1 - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - 2014-07-16 - 1.4 - Release Pisi Linux 1.0 - Serdar Soytetir - kaptan@pisilinux.org + 2015-05-05 + 8.9.0 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com 2014-05-11 - 1.4 + 7.6.3 Release bump. Marcin Bojara marcin@pisilinux.org - 2014-03-16 - 1.4 - Rc2 name Erdinc for Erdinç Gültekin. + 2014-03-30 + 7.6.3 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-13 + 7.2.5 + Rebuild Unused + Varol Maksutoğlu + waroi@pisilinux.org + + + 2013-07-26 + 7.2.5 + Release bump, fix dep. Serdar Soytetir kaptan@pisilinux.org + + 2013-01-14 + 7.2.5 + New release + PisiLinux Community + admins@pisilinux.org + + + 2012-11-21 + 7.2.3 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + v86d + http://dev.gentoo.org/~spock/projects/uvesafb/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + service + system.base + Userspace helper for uvesafb + uvesafb için kullanıcı uzayı yardımcısı + Program pomocniczy uvesafb uruchamiający kod x86 w emulowanym środowisku + v86d is a userspace helper that runs x86 code in an emulated environment. It is used by the kernel framebuffer driver uvesafb. + v86d, öykünmüş bir ortamda x86 kodu çalıştıran yardımcı bir kullanıcı uzayı yardımcısıdır. Çekirdekteki uvesafb framebuffer sürücüsü tarafından kullanılır. + v86d to działający w przestrzeni użytkownika program pomocniczy uruchamiający kod x86. Jest wykorzystywany przez sterownik jądra Linuksa uvesafb. + http://source.pisilinux.org/1.0/v86d-0.1.10.tar.bz2 + system/base/v86d/pspec.xml + + + v86d + + /sbin + /usr/share/doc + + + + + 2014-05-11 + 0.1.10 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-29 + 0.1.10 + Rebuild + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-12-19 + 0.1.10 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + libpipeline + http://libpipeline.nongnu.org + + PisiLinux Community + admins@pisilinux.org + + GPLv3+ + library + system.base + pipeline manipulation library + pipeline yönetim kitaplığı + libpipeline is a C library for manipulating pipelines of subprocesses in a flexible and convenient way. + libpipeline, alt-süreç girdi/çıktı hatlarını (pipeline) yönetmek için geliştirilmiş bir C kitaplığıdır. + http://download.savannah.gnu.org/releases/libpipeline/libpipeline-1.3.0.tar.gz + system/base/libpipeline/pspec.xml + + + libpipeline + + /usr/lib + /usr/share/doc + + + + libpipeline-devel + Development files for libpipeline + libpipeline için geliştirme dosyaları + system.devel + + libpipeline + + + /usr/include + /usr/lib/pkgconfig + /usr/share/man + + + + + 2014-05-11 + 1.3.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + - 2013-12-20 - 1.4 - Rc2 + 2014-03-29 + 1.3.0 + Version bump Serdar Soytetir kaptan@pisilinux.org - 2013-08-20 - 1.4 - RC1 - Erdinç Gültekin - erdincgultekin@pisilinux.org + 2013-10-24 + 1.2.4 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com - 2013-08-11 - 1.4 - sueno - Erdinç Gültekin - erdincgultekin@pisilinux.org + 2013-01-14 + 1.2.2 + New release + PisiLinux Community + admins@pisilinux.org - 2012-08-23 - 1.4 + 2011-12-16 + 1.2.0 First release - PisiLinux Community + Pisi Linux Admins admins@pisilinux.org - libusb - http://libusb.org/ + piksemel + http://pisilinux.org PisiLinux Community admins@pisilinux.org - LGPLv2.1 + GPLv2 library system.base - Userspace access to USB devices - Project's main aim is to create a library for use by user level applications to access USB devices regardless of OS. - http://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-1.0.19/libusb-1.0.19.tar.bz2 + Python binding for iksemel + iksemel için python desteği + Un analyseur XML simple, rapide, petit et robuste pour Python basé sur iksemel. + A simple, fast, small and robust XML parser for Python, based on iksemel. + Python için basit, hızlı, ufak ve sağlam bir XML ayrıştırıcısı, iksemel tabanlıdır. + http://source.pisilinux.org/1.0/piksemel-1.3.1.tar.gz - libudev-devel + python-devel - system/base/libusb/pspec.xml + + symbol-visibility.patch + + system/base/piksemel/pspec.xml - libusb + piksemel - libudev + python + + + /usr/lib + /usr/share/doc + + + + + 2014-05-11 + 1.3.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 1.3.1 + rebuild + Pisi Linux Admins + admins@pisilinux.org + + + 2010-10-11 + 1.3.1 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + eudev + https://www.gentoo.org/proj/en/eudev/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + console + system.base + eudev is a fork of system-udev + eudev sistemd-udev uygulamasının çatalı + eudev is a fork of system-udev with the goal of obtaining better compatibility with existing software such as OpenRC and Upstart, older kernels, various toolchains and anything else required by users and various distributions. + eudev sistem-udev uygulamasının OpenRC, Upstart gibi başlangıç sistemleri ile uyumu için hazırlanmış çatalı + https://github.com/gentoo/eudev/archive/v3.0.tar.gz + + config.cache + + + glibc-devel + libkmod-devel + glib2-devel + libpcre-devel + gperf + + system/base/eudev/pspec.xml + + + eudev + + libkmod + glib2 + + + /bin + /sbin + /usr/bin + /usr/sbin + /lib/udev + /lib + /usr/lib + /etc + /usr/lib/tmpfiles.d/udev.conf + /run/udev + /lib/systemd + /etc/udev/rules.d + /lib/udev/rules.d + /usr/share/doc + /usr/share/man + + + udev + libudev + libgudev1 + + + udev + libudev + libgudev1 + + + System.Package + + + tmpfiles.conf + + + + eudev-devel + Development files for eudev + system.devel + + eudev + glib2-devel + + + /usr/include/ + /usr/lib/pkgconfig + /usr/share/pkgconfig + + + udev-devel + libudev-devel + libgudev1-devel + + + + eudev-32bit + 32-bit shared libraries for eudev + emul32 + emul32 + + glibc-32bit + libkmod-32bit + glib2-32bit + + + glibc-32bit + glib2-32bit + + + /lib32 + /usr/lib32 + + + libudev-32bit + libgudev1-32bit + + + libudev-32bit + libgudev1-32bit + + + + + 2015-05-11 + 3.0 + build emul32 and static too. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-03-29 + 3.0 + First release. + Ertuğrul Erata + ertugrulerata@gmail.com + + + + + + sqlite + http://www.sqlite.org/ + + PisiLinux Community + admins@pisilinux.org + + as-is + library + system.base + An SQL Database Engine in a C Library + Bir C kütüphanesi içindeki bir SQL veritabanı motoru + SQLite est une petite librairie C implémentant un moteur de base de données SQL auto-configurée, auto-suffisante, pouvant être embarquée. Gère des bases de données de tailles allant jusqu'à 2 téraOctets. + SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine. Supports databases up to 2 terabytes in size. + SQLite hiçbir ayar gerektirmeyen, başka programların içine gömülebilir bir SQL veritabanı motorudur. 2 terabayta kadar büyüklükteki veritabanlarını tutabilir. + http://www.sqlite.org/2015/sqlite-autoconf-3080803.tar.gz + http://www.sqlite.org/2015/sqlite-doc-3080803.zip + + readline-devel + + system/base/sqlite/pspec.xml + + + sqlite + + readline /usr/bin /usr/lib /usr/share/doc + /usr/share/man - - libusbx - - - libusbx - - libusb-devel - Development files for libusb + sqlite-devel + Development files for sqlite + sqlite için geliştirme dosyaları system.devel - libusb + sqlite /usr/include /usr/lib/pkgconfig /usr/lib32/pkgconfig - - libusbx-devel - - - libusbx-devel - - libusb-32bit - 32-bit shared libraries for libusb + sqlite-32bit + 32-bit shared libraries for sqlite emul32 emul32 - libudev-32bit + glibc-32bit - libusb - libudev-32bit + sqlite + glibc-32bit /usr/lib32 - - libusbx-32bit - - - libusbx-32bit - + + + sqlite-tcl + + tcl-devel + + + sqlite + + + /usr/lib/sqlite3.8.8.3 + + + + sqlite-tcl-32bit + + glibc-32bit + + + sqlite + glibc-32bit + + + /usr/lib32/sqlite3.8.8.3/ + + + 2015-02-28 + 3.8.8.3 + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2015-01-31 + 3.8.8.2 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + + + 2015-01-24 + 3.8.8.1 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + + + 2014-12-05 + 3.8.7.2 + Version bump. + Osman Erkan + osman.erkan@pisilinux.org + + + 2014-07-09 + 3.8.5 + Version bump. + Vedat Demir + vedat@pisilinux.org + - 2014-09-08 - 1.0.19 - rename libusbx to libusb like upsteam - version bump to 19 - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-16 - 1.0.18 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-29 - 1.0.17 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-07-27 - 1.0.16 - Move pc files to devel pack, rebuild - PisiLinux Community - admins@pisilinux.org - - - 2013-07-27 - 1.0.16 - Move .pc files to devel package - Fatih Turgel - hitaf@pisilinux.org - - - 2013-07-23 - 1.0.16 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-10-12 - 1.0.14 - First release - Erdem Artan - admins@pisilinux.org - - - - - - libxcb - http://xcb.freedesktop.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.base - The X protocol C-language Binding (XCB) - X protokolü için C dili bağlayıcısı (XCB) - The X protocol C-language Binding (XCB) is a replacement for Xlib featuring a small footprint, latency hiding, direct access to the protocol, improved threading support, and extensibility. - http://xcb.freedesktop.org/dist/libxcb-1.11.tar.bz2 - - libXau-devel - libXdmcp-devel - libxslt - xcb-proto - - system/base/libxcb/pspec.xml - - - libxcb - - libXau - libXdmcp - glibc - - - /usr/lib - /usr/share/man - /usr/share/doc - - - - libxcb-devel - Development files for libxcb - libxcb için geliştirme dosyaları - system.devel - - libxcb - - - /usr/include/xcb - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - - - pthread-stubs.pc - - - - libxcb-32bit - 32-bit shared libraries for libxcb - libxcb için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - libXau-32bit - libXdmcp-32bit - - - libxcb - libXau-32bit - libXdmcp-32bit - - - /usr/lib32 - - - - - 2014-09-02 - 1.11 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - 2014-05-11 - 1.10 - Release bump. + 3.8.4.3 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-03-29 + 3.8.4.2 + Version bump. Marcin Bojara marcin@pisilinux.org - - 2014-03-07 - 1.10 + + 2013-10-28 + 3.8.1 Version bump. Yusuf Aydemir yusuf.aydemir@pisilinux.org - - 2013-10-08 - 1.9.1 - Rebuild. + + 2013-06-28 + 3.7.17 + Move pc files to devel pack, increase release no. Serdar Soytetir kaptan@pisilinux.org - - 2013-07-28 - 1.9.1 - Version bump. + + 2013-06-28 + 3.7.17 + Version bump Marcin Bojara marcin@pisilinux.org + + 2013-01-21 + 3.7.15.2 + bump + Erdinç Gültekin + admins@pisilinux.org + - 2012-11-18 - 1.9 + 2012-12-15 + 3.7.14 First release Erdinç Gültekin admins@pisilinux.org @@ -6590,61 +12553,490 @@ - nss-mdns - http://0pointer.de/lennart/projects/nss-mdns/ + pam + http://www.kernel.org/pub/linux/libs/pam/ PisiLinux Community admins@pisilinux.org - GPLv2 + PAM library system.base - Name Service Switch module - İsim servisi değiştirme modülü - Module d'échange de service de nom pour le DNS Multicast. - Name Service Switch module for Multicast DNS. - Çoklu gönderim yapan DNS'ler için isim servisi seçme modülü. - http://0pointer.de/lennart/projects/nss-mdns/nss-mdns-0.10.tar.gz + Modules d'Authentification en Greffon (Pluggable Authentication Modules) + Pluggable Authentication Modules + PAM - Eklenebilir Yetkilendirme Modülleri + PAM (Pluggable Authentication Modules) is a system security tool that allows system administrators to set authentication policy without having to recompile programs that handle authentication. + http://www.linux-pam.org/library/Linux-PAM-1.1.8.tar.bz2 + + dlopen.sh + dlopen-test.sh + + + perl + gettext + cracklib + - nss-mdns-0.8-avahi-socket.patch + no-lib64.patch + nosex-libtirpc-underlinking.patch + pam-1.1.8-cve-2013-7041.patch + pam-1.1.8-cve-2014-2583.patch - system/base/nss-mdns/pspec.xml + system/base/pam/pspec.xml - nss-mdns + pam + + cracklib + /etc + /lib + /var/run/console /usr/lib + /sbin + /usr/sbin /usr/share/doc + /usr/share/man + /usr/share/locale + + System.Package + - mdns.allow + 90-nproc.conf + + pam-devel + Development files for pam + pam için geliştirme dosyaları + system.devel + + pam + + + /usr/include + /usr/share/man/man3 + + - + + 2015-04-01 + 1.1.8 + Rebuild, remove unused. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-06-10 + 1.1.8 + Add patch CVE. + Alihan Öztürk + alihan@pisilinux.org + + 2014-05-11 - 0.10 + 1.1.8 Release bump. Marcin Bojara marcin@pisilinux.org + + 2013-10-22 + 1.1.8 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-05-16 + 1.1.6 + Sandbox fixed. + PisiLinux Community + admins@pisilinux.org + - 2013-10-29 - 0.10 - Rebuild - Pisi Linux Admins + 2013-02-21 + 1.1.6 + Build with new automake, enable tests. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-09-13 + 1.1.6 + First release + Erdem Artan + admins@pisilinux.org + + + + + + curl + http://curl.haxx.se/ + + PisiLinux Community + admins@pisilinux.org + + MIT + X11 + app:console + library + system.base + Un client qui maîtrise tout ce qui concerne les URLs + A utility for getting files from remote servers + Uzak sunuculardan dosya indirmek için bir araç + Ein Client, der URLs versteht + curl is a command line tool for transferring data with URL syntax, supporting various protocols. + curl çeşitli protokolleri destekleyen, URL söz dizimini kullanarak uzak sunuculardan veri aktarmak için kullanılan bir komut satırı aracıdır. + http://curl.haxx.se/download/curl-7.42.1.tar.bz2 + + glibc-devel + zlib-devel + openssl-devel + libidn-devel + libssh2-devel + ca-certificates + + system/base/curl/pspec.xml + + + curl + + zlib + libidn + libssh2 + openssl + ca-certificates + + + /usr/bin + /usr/lib + /usr/share/doc/ + /usr/share/man/ + /usr/share/curl + + + curl-devel + + + + curl-devel + Development files for curl + curl için geliştirme dosyaları + system.devel + + curl + + + /usr/lib/pkgconfig + /usr/bin/curl-config + /usr/include/curl + /usr/share/aclocal + + + + + 2015-05-01 + 7.42.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2015-04-27 + 7.42.0 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2015-01-11 + 7.40.0 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-01-10 + 7.39.0 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-07-18 + 7.37.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-29 + 7.37.0 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 7.36 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 7.36 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-12-19 + 7.34.0 + Version bump. + Stefan Gronewold(groni) + groni@pisilinux.org + + + 2013-10-25 + 7.33.0 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-06-28 + 7.31.0 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-02-11 + 7.28.1 + Güncellendi. + PisiLinux Community admins@pisilinux.org - 2010-10-11 - 0.10 + 2012-08-23 + 7.27.0 First release - Pisi Linux Admins + PisiLinux Community admins@pisilinux.org + + + xz + http://tukaani.org/xz/ + + PisiLinux Community + admins@pisilinux.org + + LGPLv2+ + GPLv2+ + GPLv3 + app:console + library + system.base + XZ compression utilities + XZ sıkıştırma araçları + XZ Utils provide a general purpose data compression library and command line tools. The .xz format supports multiple compression algorithms, which are called "filters" in context of XZ Utils. The primary filter is currently LZMA2. + xz, genel amaçlı bir veri sıkıştırma kütüphanesi ve konut satırı araçları içerir. xz dosya biçimi filtre adı verilen sıkıştırma algoritmalarını destekler, öntanımlı filtre ise LZMA2 algoritmasıdır. + http://tukaani.org/xz/xz-5.2.1.tar.xz + system/base/xz/pspec.xml + + + xz + + /usr/bin + /usr/lib + /usr/share/man + /usr/share/doc + /usr/share/locale + + + + xz-devel + Development files for XZ + XZ için geliştirme dosyaları + system.devel + + xz + + + /usr/include + /usr/lib/pkgconfig + /usr/lib32/pkgconfig + + + + xz-32bit + 32bit shared libraries for xz + XZ için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + glibc-32bit + + + glibc-32bit + xz + + + /usr/lib32 + + + + + 2015-03-08 + 5.2.1 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-10-01 + 5.0.7 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 5.0.5 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-28 + 5.0.5 + Version bump, clean xz. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-26 + 5.0.4 + Move pc files to devel pack, increase release no. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-08-24 + 5.0.4 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + man-db + http://www.nongnu.org/man-db/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2+ + GPLv3+ + app:console + data:doc + system.base + Application to read Linux man pages + Kapsamlı Linux kılavuzları + Man package consists of programs which is used to read most of the documentation available in linux system. For example, you can write "man nameoftheprogram" into the konsole or "man:nameoftheprogram" into the konqueror to get a detailed usage information for many programs. + man-db paketi Linux ile ilgili yazılmış dökümanların büyük çoğunluğunu okunması için gerekli programları sunar. Örneğin, konsola "man programadı" ya da konquerora "man:programadı" yazarak birçok program hakkında detaylı kullanım bilgisi alabilirsiniz. + http://download.savannah.gnu.org/releases/man-db/man-db-2.6.3.tar.xz + + less + gzip + groff + gdbm-devel + zlib-devel + gettext-devel + libpipeline-devel + + + man-db-2.5.9-sgr.patch + man-db-2.6.1-locale-fallback.patch + man-db-2.6.1-so-links.patch + man-db-2.6.1-wildcards.patch + man-db-2.6.2-invalid-cache.patch + man-db-2.6.3-overrides.patch + + system/base/man-db/pspec.xml + + + man-db + + gdbm + zlib + gettext + libpipeline + + + /etc + /usr/lib + /usr/bin + /usr/sbin + /usr/libexec + /usr/share/locale + /usr/share/doc + /usr/share/man + /var/cache + + + mandb.conf + mandb.cron.daily + + + + + 2014-05-11 + 2.6.3 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-03 + 2.6.3 + Rebuild for openjdk. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-28 + 2.6.3 + rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-03-04 + 2.6.3 + Add some patches, cleanup. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-09-27 + 2.6.3 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + glibc @@ -6662,7 +13054,7 @@ Glibc, La librairie GNU X est utilisée comme la librairie C dans le système GNU et la plupart des système utilisant le noyau Linux. Elle définit les appels système et autres fonctionnalités du langage de programmation C. The GNU C library is used as the C library in the GNU system and most systems with the Linux kernel. It defines the system calls and other basic C programming language facilities. Glibc, GNU C kitaplığı, GNU sisteminde ve Linux dağıtımlarının büyük çoğunluğunda C programlama dili kütüphanesi olarak kullanılır. İçinde sistem çağrıları ve C programlama dili için temel fonksiyonları bulundurur. - http://ftp.gnu.org/gnu/libc/glibc-2.20.tar.xz + http://ftp.gnu.org/gnu/libc/glibc-2.21.tar.xz kernel-headers gettext @@ -6670,7 +13062,7 @@ locale-no-archive.patch - glibc-2.20-roundup.patch + glibc-2.21-roundup.patch system/base/glibc/pspec.xml @@ -6727,7 +13119,7 @@ system.base emul32 - glibc + glibc /etc/ld.so.conf.d/60-glibc-32bit.conf @@ -8239,6 +14631,13 @@ + + 2015-04-04 + 2.21 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + 2014-11-28 2.20 @@ -8314,4496 +14713,76 @@ - comar-api - http://www.pisilinux.org + nano + http://www.nano-editor.org/ PisiLinux Community admins@pisilinux.org - GPLv2 - library - system.base - Utility functions for Comar scripts - Çomar betikleri için yardımcı fonksiyonlar - Librairie utilitaire générique pour les opérations communes de scripts Comar. - Generic utility library for common Comar script operations. - Çomar betiklerinde sıkça yapılan ortak işlemler için yardımcı fonksiyonlar kitaplığı. - http://source.pisilinux.org/1.0/comar-api-2.4.9.tar.gz - - python - - - run_dir.patch - pisilinux.patch - add-stopdependencies.patch - - system/base/comar-api/pspec.xml - - - comar-api - - python - pisilinux-python - - - /usr/lib/pisilinux - /usr/lib/python2.7 - - - - - 2014-08-20 - 2.4.9 - Fix paths. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 2.4.9 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-31 - 2.4.9 - Release bump, clean comar-api. - Serdar Soytetir - kaptan@pisilinux.org - - - 2010-11-29 - 2.4.9 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - bash - http://cnswww.cns.cwru.edu/~chet/bash/bashtop.html - - Pisi Linux Admins - admins@pisilinux.org - - GPLv2 + GPLv3 app:console system.base - The standard GNU Bourne again shell - GNU Bource again kabuğu - Bash est le Bourne Again SHell du projet GNU, une implémentation complête du POSIX IEEE et des spécifications d'interprétation de commande (shell) de l'Open Group, avec édition interactive de ligne de commande et des fonctionnalités à la csh tels que la substitution dans l'historique de commande. - Bash is the GNU Project's Bourne Again SHell, a complete implementation of the IEEE POSIX and Open Group shell specification with interactive command line editing, csh-like features such as history substitution. - Bash, IEEE POSIX ve Open Group'un interaktif komut satırı düzenleme, geçmiş komutları tamamlama gibi csh tipi özellikler gibi kabuk uygulamaları tariflerinin tam olarak uygulayan GNU Projesinin Bourne Again SHell kabuk programıdır. - mirrors://gnu/bash/bash-4.3.tar.gz + GNU GPL'd Pico clone with more functionality + Konsol ortamında kullanabileceğiniz bir metin düzenleyicidir. + Nano est un petit éditeur libre et convivial qui a pour but de remplacer Pico, l'éditeur par défaut inclus dans le paquet non-libre Pine. Plutôt que juste copier l'apparence et le ressenti de Pico, nan implémente également certaines fonctionnalité manquantes (ou désactivées par défaut), tel que "rechercher et remplacer" ou "allez à la ligne numéro". + Nano is a small, free and friendly editor which aims to replace Pico, the default editor included in the non-free Pine package. Rather than just copying Pico's look and feel, nano also implements some missing (or disabled by default) features in Pico, such as "search and replace" and "go to line number". + Nano özgür olmayan Pine paketinin içindeki metin düzenleme programı olan Pico'nun yerine geçme hedefini güden küçük, özgür ve kullanışlı bir metin düzenleme programıdır. Pico'nun görünüşünü ve işlevini kopyalamaktan çok, Nano aynı zamanda "ara ve değiştir" ve "satır numarasına git" gibi Pico'da olmayan (veya ön tanımlı olarak kapalı) bazı özellikleri sunar. + http://www.nano-editor.org/dist/v2.3/nano-2.3.5.tar.gz ncurses-devel - - - official/bash43-001.tar.gz - official/bash43-002.tar.gz - official/bash43-003.tar.gz - official/bash43-004.tar.gz - official/bash43-005.tar.gz - official/bash43-006.tar.gz - official/bash43-007.tar.gz - official/bash43-008.tar.gz - official/bash43-009.tar.gz - official/bash43-010.tar.gz - official/bash43-011.tar.gz - official/bash43-012.tar.gz - official/bash43-013.tar.gz - official/bash43-014.tar.gz - official/bash43-015.tar.gz - official/bash43-016.tar.gz - official/bash43-017.tar.gz - official/bash43-018.tar.gz - official/bash43-019.tar.gz - official/bash43-020.tar.gz - official/bash43-021.tar.gz - official/bash43-022.tar.gz - official/bash43-023.tar.gz - official/bash43-024.tar.gz - official/bash43-025.tar.gz - official/bash43-026.tar.gz - official/bash43-027.tar.gz - official/bash43-028.tar.gz - official/bash43-029.tar.gz - official/bash43-030.tar.gz - fedora/bash-2.02-security.patch - fedora/bash-2.03-paths.patch - fedora/bash-2.03-profile.patch - fedora/bash-2.05a-interpreter.patch - fedora/bash-2.05b-debuginfo.patch - fedora/bash-2.05b-manso.patch - fedora/bash-2.05b-pgrp_sync.patch - fedora/bash-2.05b-readline-oom.patch - fedora/bash-2.05b-xcc.patch - fedora/bash-3.2-audit.patch - fedora/bash-3.2-ssh_source_bash.patch - fedora/bash-4.0-nobits.patch - fedora/bash-4.1-broken_pipe.patch - fedora/bash-4.1-defer-sigchld-trap.patch - fedora/bash-4.1-examples.patch - fedora/bash-4.2-coverity.patch - fedora/bash-4.2-manpage_trap.patch - fedora/bash-4.2-rc2-logout.patch - fedora/bash-4.2-size_type.patch - fedora/bash-bashbug.patch - fedora/bash-infotags.patch - fedora/bash-requires.patch - fedora/bash-setlocale.patch - fedora/bash-tty-tests.patch - - system/base/bash/pspec.xml - - - bash - - ncurses - - - /etc - /bin - /usr/bin - /usr/share/doc - /usr/share/info - /usr/share/man - /usr/share/locale - - - bashrc - command-not-found.sh - - - - - 2014-10-13 - 4.3_p30 - Update - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-09-27 - 4.3_p26 - Update - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 4.3_p8 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-03 - 4.3_p8 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-28 - 4.2_p45 - rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-11-24 - 4.2_p45 - Update - Marcin Bojara - marcin@pisilinux.org - - - 2012-11-24 - 4.2_p39 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - gettext - http://www.gnu.org/software/gettext/gettext.html - - PisiLinux Community - admins@pisilinux.org - - GPLv3+ - app:console - library - system.base - GNU libraries and utilities for producing multi-lingual messages - Farklı dillerde ileti katalogları üretmek için gerekli GNU araçları ve kütüphaneleri - gettext est une librairie d'internationalisation GNU. - The GNU gettext package provides a set of tools and documentation for producing multi-lingual messages in programs. Tools include a set of conventions about how programs should be written to support message catalogs, a directory and file naming organization for the message catalogs, a runtime library which supports the retrieval of translated messages, and stand-alone programs for handling the translatable and the already translated strings. Gettext provides an easy to use library and tools for creating, using, and modifying natural language catalogs and is a powerful and simple method for internationalizing programs. - gettext, uygulamalarda farklı dillerde iletiler kullanılmasını sağlayan yerelleştirme araçları ve kütüphanelerini içerir. - gettext ist eine GNU Bibliothek für Internationalisierung - http://ftp.gnu.org/pub/gnu/gettext/gettext-0.18.3.2.tar.gz - - acl-devel - glib2-devel - ncurses - - system/base/gettext/pspec.xml - - - gettext-docs - system.doc - - gettext - - - /usr/share/doc/gettext/html - - - - gettext - - acl - glib2 - ncurses - libgcc - libunistring - libgomp - libxml2 - - - /usr/bin - /usr/lib - /usr/share/gettext - /usr/share/locale - /usr/share/info - /usr/share/man - /usr/share/doc - - - - gettext-devel - Development files for gettext - gettext için geliştirme dosyaları - system.devel - - gettext - - - /usr/share/aclocal - /usr/include - /usr/share/man/man3 - - - - - 2014-05-11 - 0.18.3.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 0.18.3.2 - Minor version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-27 - 0.18.3.1 - Version bump, clean gettext. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-11 - 0.18.2 - Fix dep, release bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-11 - 0.18.2 - Güncellendi. - PisiLinux Community - admins@pisilinux.org - - - 2010-10-11 - 0.18.1.1 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - libX11 - http://www.x.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.base - Librairie X11 de X.Org. - X.Org X11 library - X.Org X11 kitaplığı - X.Org X11 Bibliothek - Core X11 protocol client library. - mirrors://xorg/individual/lib/libX11-1.6.2.tar.bz2 - - libxcb-devel - xorg-proto - xtrans - - - fix-segfault.diff - fix-null-pointer.patch - - system/base/libX11/pspec.xml - - - libX11 - - libxcb - - - /usr/lib/libX11* - /usr/lib/X11 - /usr/share/X11 - /usr/share/doc/libX11 - - - - libX11-devel - Development files for X11 library - libX11 için geliştirme dosyaları - system.devel - - libX11 - libxcb-devel - xorg-proto - - - /usr/include/X11 - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/man - - - - libX11-32bit - 32-bit shared libraries for libX11 - libX11 için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - libxcb-32bit - - - libX11 - libxcb-32bit - - - /usr/lib32 - - - - - 2014-05-11 - 1.6.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-07 - 1.6.2 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-09-12 - 1.6.2 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-30 - 1.6.1 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-06-21 - 1.6.0 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-11-24 - 1.5.0 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - alternatives - http://git.fedorahosted.org/git/?p=chkconfig.git;a=summary - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - Alternative management system - Alternatif yönetim sistemi - alternatives creates, removes, maintains and displays information about the symbolic links comprising the alternatives system. Alternatives system determines the defaults when several programs fulfilling the same or similar functions to be installed on a single system at the same time. - alternatives, alternatives sisteminin parçası olan sembolik bağlantıları oluşturan, silen, yöneten ve bunlar hakkında bilgi gösteren araçtır. Alternatives sistemi, birbirine benzer ya da aynı işlevleri sunan programların aynı anda aynı sisteme kurulduğu zamanlarda öntanımlıları belirler. - https://git.fedorahosted.org/cgit/chkconfig.git/snapshot/chkconfig-1.3.62.tar.xz - system/base/alternatives/pspec.xml - - - alternatives - - /etc - /usr/sbin - /usr/share/locale - /usr/share/man - /usr/share/doc - /var - - - - - 2014-05-11 - 1.3.62 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 1.3.58 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 1.3.58 - rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-05-03 - 1.3.58 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - pypolkit - http://www.pisilinux.org - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.base - Python binding of PolicyKit - PolicyKit için Python bağlayıcısı - pypolkit is a Python binding for the PolicyKit library. - pypolkit PolicyKit için geliştirilmiş bir Python bağlayıcısıdır. - http://source.pisilinux.org/1.0/pypolkit-1.0.2.tar.gz - - glib2 - python - polkit-devel - - system/base/pypolkit/pspec.xml - - - pypolkit - - glib2 - polkit - python - - - /usr/lib - /usr/share/doc - - - - - 2014-05-11 - 1.0.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-01 - 1.0.2 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-30 - 1.0.2 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2010-11-26 - 1.0.2 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - gzip - http://www.gnu.org/software/gzip - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - LGPLv2.1 - app:console - system.base - Standard GNU compressor - GNU dosya arşiv aracı - gzip (GNU zip) est un programme populaire de compression de donnée écrit pour le projet GNU. - gzip (GNU zip) is a popular data compression program written for the GNU project. - Gzip (GNU zip) GNU projesi için geliştirilmiş popüler bir veri sıkıştırma programıdır. - http://ftp.gnu.org/gnu/gzip/gzip-1.6.tar.xz - system/base/gzip/pspec.xml - - - gzip - - /bin - /usr/share/doc - /usr/share/man - /usr/share/info - - - - - 2014-05-11 - 1.6 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-31 - 1.6 - Version bumm, clean gzip. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-08-23 - 1.5 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - curl - http://curl.haxx.se/ - - PisiLinux Community - admins@pisilinux.org - - MIT - X11 - app:console - library - system.base - Un client qui maîtrise tout ce qui concerne les URLs - A utility for getting files from remote servers - Uzak sunuculardan dosya indirmek için bir araç - Ein Client, der URLs versteht - curl is a command line tool for transferring data with URL syntax, supporting various protocols. - curl çeşitli protokolleri destekleyen, URL söz dizimini kullanarak uzak sunuculardan veri aktarmak için kullanılan bir komut satırı aracıdır. - http://curl.haxx.se/download/curl-7.40.0.tar.bz2 - - zlib-devel - openssl-devel - libidn-devel - libssh2-devel - ca-certificates - - system/base/curl/pspec.xml - - - curl - - zlib - libidn - libssh2 - openssl - ca-certificates - - - /usr/bin - /usr/lib - /usr/share/doc/ - /usr/share/man/ - /usr/share/curl - - - curl-devel - - - - curl-devel - Development files for curl - curl için geliştirme dosyaları - system.devel - - curl - - - /usr/lib/pkgconfig - /usr/bin/curl-config - /usr/include/curl - /usr/share/aclocal - - - - - 2015-01-11 - 7.40.0 - Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2015-01-10 - 7.39.0 - Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2014-07-18 - 7.37.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-29 - 7.37.0 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 7.36 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 7.36 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-12-19 - 7.34.0 - Version bump. - Stefan Gronewold(groni) - groni@pisilinux.org - - - 2013-10-25 - 7.33.0 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-06-28 - 7.31.0 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-11 - 7.28.1 - Güncellendi. - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 7.27.0 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - libXdmcp - http://x.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.base - Librairie Xdmcp de X.Org. - X.Org Xdmcp library - X.Org Xdmcp kitaplığı. - X.Org Xdmcp Bibliothek - LibXdmcp is the X Display Manager Control Protocol library. - LibXdmcp, X Ekran Yöneticisi Denetim Protokolü kitaplığıdır. - http://xorg.freedesktop.org/archive/individual/lib/libXdmcp-1.1.1.tar.bz2 - system/base/libXdmcp/pspec.xml - - - libXdmcp - - /usr/lib - /usr/share/doc - - - - libXdmcp-devel - Development files for libXdmcp - libXdmcp için geliştirme dosyaları - system.devel - - libXdmcp - - - /usr/include/X11 - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/doc/*/*.xml - - - - libXdmcp-32bit - 32-bit shared libraries for libXdmcp - libXdmcp için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - libXdmcp - - - /usr/lib32 - - - - - 2014-05-11 - 1.1.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-08 - 1.1.1 - Rebuild, clean actions.py. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-08-23 - 1.1.1 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - v86d - http://dev.gentoo.org/~spock/projects/uvesafb/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - service - system.base - Userspace helper for uvesafb - uvesafb için kullanıcı uzayı yardımcısı - Program pomocniczy uvesafb uruchamiający kod x86 w emulowanym środowisku - v86d is a userspace helper that runs x86 code in an emulated environment. It is used by the kernel framebuffer driver uvesafb. - v86d, öykünmüş bir ortamda x86 kodu çalıştıran yardımcı bir kullanıcı uzayı yardımcısıdır. Çekirdekteki uvesafb framebuffer sürücüsü tarafından kullanılır. - v86d to działający w przestrzeni użytkownika program pomocniczy uruchamiający kod x86. Jest wykorzystywany przez sterownik jądra Linuksa uvesafb. - http://source.pisilinux.org/1.0/v86d-0.1.10.tar.bz2 - system/base/v86d/pspec.xml - - - v86d - - /sbin - /usr/share/doc - - - - - 2014-05-11 - 0.1.10 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 0.1.10 - Rebuild - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-12-19 - 0.1.10 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - pciutils - http://atrey.karlin.mff.cuni.cz/~mj/pciutils.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - Various utilities dealing with the PCI bus - PCI veriyolu işlevleri ile ilgili çeşitli programlar - Les utilitaires PCI sont une collection de programmes d'inspection et de manipulation de la configuration des périphériques PCI. - The PCI Utilities are a collection of programs for inspecting and manipulating configuration of PCI devices. - Pakette bulunan PCI araçları, PCI veriyolunu kullanan donanımlarınızın görüntülenmesi ve ayarlanması işlevini yürütür. - ftp://ftp.kernel.org/pub/software/utils/pciutils/pciutils-3.2.1.tar.xz - - pci.ids - - - pciutils-nogz.patch - pciutils-remove-update-pciids.patch - makefile.patch - - system/base/pciutils/pspec.xml - - - pciutils - - /usr/sbin - /usr/lib - /usr/share/man - /usr/share/misc - - - - pciutils-devel - Development files for pciutils - pciutils için geliştirme dosyaları - system.devel - - pciutils - - - /usr/lib/pkgconfig - /usr/include - - - - - 2014-05-11 - 3.2.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-03 - 3.2.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-10-30 - 3.1.10 - Rebuild - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-10-05 - 3.1.10 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - libestr - http://libestr.adiscon.com - - Marcin Bojara - marcin@pisilinux.org - - LGPLv2.1 - library - system.base - Library for some string essentials - libestr - some essentials for string handling (and a bit more) - http://libestr.adiscon.com/files/download/libestr-0.1.9.tar.gz - system/base/libestr/pspec.xml - - - libestr - - /usr/lib/libestr.so* - /usr/share/doc/libestr - - - - libestr-devel - Development files for libestr - system.devel - - libestr - - - /usr/include/libestr.h - /usr/lib/pkgconfig/libestr.pc - - - - - 2014-05-11 - 0.1.9 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 0.1.9 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-11-21 - 0.1.4 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - coreutils - http://www.gnu.org/software/coreutils/ - - Pisi Linux Admins - admins@pisilinux.org - - GPLv3+ - app:console - system.base - A set of basic GNU tools commonly used in shell scripts - Standart dosya, metin ve kabuk uygulamaları - Utilitaires standards GNU pour fichiers (chmod, cp, dd, dir, ls...), utilitaires texte (sort, tr, head, wc...) et utilitaires d'interpréteur de commande (shell) (whoami, who...) - GNU dosya uygulamaları (chmod, cp, dd, dir, ls...), sh uygulamaları (whoami, who,...) ve metin uygulamalarının (sort, tr, head, wc..) birlikteliğinden oluşmaktadır. - http://ftp.gnu.org/gnu/coreutils/coreutils-8.23.tar.xz - - acl-devel - attr-devel - perl - shadow gettext-devel - ncurses-devel + slang - - remove_am_silent_rules.patch - - system/base/coreutils/pspec.xml + system/base/nano/pspec.xml - coreutils + nano - acl - attr - gmp - libcap + ncurses + file - /bin /etc - /usr/bin - /usr/libexec - /usr/lib - /usr/share/doc + /usr/share/locale + /usr/share/doc/nano /usr/share/man /usr/share/info - /usr/share/locale - - - - - 2014-12-12 - 8.23 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 8.22 - Rebuild, add patch. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-04-02 - 8.22 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-31 - 8.21 - Clean coreutils. - Serdar Soytetir - kaptanan@pisilinux.org - - - 2013-07-26 - 8.21 - Fix deps, release bump. - Serdar Soytetir - kaptanan@pisilinux.org - - - 2013-02-11 - 8.21 - Güncellendi. - PisiLinux Community - admins@pisilinux.org - - - 2012-08-31 - 8.19 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - mkinitramfs - http://www.busybox.net - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - A tool to create the initramfs image - initramfs image dosyası yaratmak için araç - Un outil pour créer les images initramfs - mkinitramfs contains a tool to create the initramfs image with busybox. - initramfs image dosyası yaratmak için araç - http://source.pisilinux.org/1.0/README.mkinitramfs - system/base/mkinitramfs/pspec.xml - - - mkinitramfs - - disktype - busybox - - - /etc - /sbin - /lib/initramfs - /usr/share/doc/mkinitramfs - - - System.PackageHandler - - - mkinitramfs - init - udhcpc.script - hotplug - profile.rc - initramfs.conf - - - - - 2014-05-11 - 1.0.7 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-10 - 1.0.7 - Fix probing LVM devices - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-10 - 1.0.7 - Disable mount tmpfs on /run - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-05 - 1.0.7 - Add missing method to pakhandler.py - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-03 - 1.0.7 - Fix default plymouth theme name. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-06-17 - 1.0.7 - Fix resume path. - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-13 - 1.0.7 - Change loopbackimage address and name. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-13 - 1.0.7 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - dnsmasq - http://www.thekelleys.org.uk/dnsmasq/doc.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - GPLv3 - service - system.base - Lightweight, easy to configure DNS forwarder and DHCP server - Hafif, kolay yapılandırılabilir DNS yönlendirici ve DHCP sunucu - dnsmasq is a DNS forwarder and DHCP server that can serve the names of local machines which are not in the global DNS. The DHCP server integrates with the DNS server and allows machines with DHCP-allocated addresses to appear in the DNS with names configured in each host. - dnsmasq, global DNS'te bulunmayan yerel makine isimlerini sunabilen bir DNS yönlendirici ve DHCP sunucudur. - http://www.thekelleys.org.uk/dnsmasq/dnsmasq-2.70.tar.xz - - dnsmasq.py - - - dbus - - system/base/dnsmasq/pspec.xml - - - dnsmasq - - dbus - - - /etc - /usr/sbin - /usr/lib - /usr/share - /usr/share/man - /usr/share/doc - /var/lib/dnsmasq - - - Network.Stack - System.Service - - - dnsmasq.conf - uk.org.thekelleys.dnsmasq.service - - - - - 2014-05-11 - 2.70 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-24 - 2.70 - Version bump. - PisiLinux Community - admins@pisilinux.org - - - 2014-04-03 - 2.68 - Version bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-10-26 - 2.67 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-14 - 2.65 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 2.63 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - libpipeline - http://libpipeline.nongnu.org - - PisiLinux Community - admins@pisilinux.org - - GPLv3+ - library - system.base - pipeline manipulation library - pipeline yönetim kitaplığı - libpipeline is a C library for manipulating pipelines of subprocesses in a flexible and convenient way. - libpipeline, alt-süreç girdi/çıktı hatlarını (pipeline) yönetmek için geliştirilmiş bir C kitaplığıdır. - http://download.savannah.gnu.org/releases/libpipeline/libpipeline-1.3.0.tar.gz - system/base/libpipeline/pspec.xml - - - libpipeline - - /usr/lib - /usr/share/doc - - - - libpipeline-devel - Development files for libpipeline - libpipeline için geliştirme dosyaları - system.devel - - libpipeline - - - /usr/include - /usr/lib/pkgconfig - /usr/share/man - - - - - 2014-05-11 - 1.3.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 1.3.0 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-24 - 1.2.4 - Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2013-01-14 - 1.2.2 - New release - PisiLinux Community - admins@pisilinux.org - - - 2011-12-16 - 1.2.0 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - pisilinux-python - http://www.pisilinux.org - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - library - system.base - Python modules for Pisi Linux - PiSi Linux için Python modülleri - Python modules for Pisi Linux provides functions for common task, with the aim of easing development. - PiSi Linux için Python modülleri genel işler için fonksiyonlar sunarak geliştirme işini kolaylaştırmayı amaçlamaktadır. - Módulos Python para PiSi Linux facilitan funciones para tareas comunes, para simplificar el desarrollo. - http://source.pisilinux.org/1.0/pisilinux-python-0.4.8.tar.gz - - python - libX11-devel - - system/base/pisilinux-python/pspec.xml - - - pisilinux-python - - python - libX11 - - - /usr/lib - /usr/share/doc - /usr/share/locale - - - - - 2014-05-11 - 0.4.8 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-07 - 0.4.8 - Release bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-09-04 - 0.4.8 - Release bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2010-12-09 - 0.4.8 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - procps - http://procps.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - Standard informational utilities and process-handling tools - Geleneksel bilgilendirme yardımcı programları ve süreç işleme araçları - procps est un paquet regroupant une multitude de petits utilitaires utiles donnant des informations concernant les process en utilisant le système de fichier /proc. Le paquet inclus les programmes ps, top, vmstat, w, kill, free, slabtop et skill. - procps is the package that has a bunch of small useful utilities that give information about processes using the /proc filesystem. The package includes the programs ps, top, vmstat, w, kill, free, slabtop, and skill. - Procps /proc dosya sistemini kullanarak çalışan süreçler hakkında bilgi vermeye yarayan bazı kullanışlı uygulamaları içeren bir pakettir. Paket ps, top, vmstat, w, kill, free, slabtop ve skill gibi uygulamaları içerir. - http://procps.sf.net/procps-3.2.8.tar.gz - - ncurses - - - procps-3.2.5-proc-mount.patch - nohz.patch - procps-3.2.5-eof.diff - procps-3.2.2-top-termsize.patch - procps-3.2.2-w-simply-work.diff - procps-3.2.7-top.1.diff - pwdx-bufferoverflow.diff - procps-3.2.7-libselinux.patch - procps-3.2.7-ps-libselinux.patch - procps-3.2.7-misc.patch - procps-3.2.7-FAQ.patch - procps-3.2.7-noproc.patch - procps-3.2.7-pseudo.patch - procps-3.2.7-0x9b.patch - procps-3.2.7-sysctl-writeonly.patch - procps-3.2.7-top-rc.patch - procps-3.2.7-top-remcpu.patch - procps-3.2.7-top-env-vmsize.patch - procps-3.2.7-top-env-cpuloop.patch - procps-3.2.7-vmstat-cpusteal.patch - procps-3.2.7-longcmd.patch - procps-3.2.7-vmstat-pgpg.patch - procps-3.2.7-sysctl-ignore.patch - procps-3.2.7-top-sorthigh.path - procps-3.2.7-w-best.patch - procps-3.2.7-watch-unicode.patch - procps-3.2.7-ps-stime.patch - procps-3.2.7-ps-eip64.patch - procps-3.2.7-psman.patch - procps-3.2.7-top-cpu0.patch - procps-3.2.7-top-cpuint.patch - procps-3.2.7-top-manpage.patch - procps-3.2.7-top-clrscr.patch - procps-3.2.7-ps-man-fmt.patch - procps-3.2.7-vmstat-partstats-long.patch - procps-3.2.7-vmstat-header.patch - procps-3.2.7-slabtop-once.patch - procps-3.2.7-vmstat-timestamp.patch - procps-3.2.7-vmstat-timestamp-manpage.patch - procps-3.2.7-ps-cgroup.patch - procps-3.2.7-vmstat-partstats-reqwrites.patch - procps-3.2.7-free-hlmem.patch - procps-3.2.8-threads.patch - procps-enable-core.patch - procps-3.2.8-setlocale.patch - procps-pmap-smaps.patch - procps-3.2.8-vmstat-getopt.patch - procps-3.2.8-ps-cgroup-suppress-root-group.patch - procps-3.2.8-make.patch - procps-3.2.8-constructor-order.patch - - system/base/procps/pspec.xml - - - procps - - ncurses - - - /bin - /sbin - /lib + /usr/share/nano /usr/bin - /usr/share/doc - /usr/share/man - /usr/include - - - - - 2014-05-11 - 3.2.8 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2010-10-12 - 3.2.8 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - urlgrabber - http://urlgrabber.baseurl.org/ - - PisiLinux Community - admins@pisilinux.org - - LGPLv2.1 - library - system.base - High level cross-protocol url-grabber library for Python - Python için yüksek seviyeli, platform bağımsız bir url-grabber kütüphanesi - urlgrabber provides a clean library interface to protocol-independant file-access for Python programs - urlgrabber Python uygulamaları için protokol bağımsız dosya erişimi sağlayan temiz bir kütüphanedir. - http://urlgrabber.baseurl.org/download/urlgrabber-3.10.1.tar.gz - - python - - system/base/urlgrabber/pspec.xml - - - urlgrabber - - python - pycurl - - - /usr/lib - /usr/libexec - /usr/share/doc + /bin - 2014-05-11 - 3.10.1 + 2014-07-11 + 2.3.5 Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com + Vedat Demir + vedat@pisilinux.org - 2013-10-28 - 3.10 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-03-12 - 3.9.1 - Fix pisi https issue - Pisi Linux Admins - marcin@pisilinux.org - - - 2010-10-11 - 3.9.1 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - cryptsetup - https://code.google.com/p/cryptsetup/ - - Erdem Artan - admins@pisilinux.org - - GPLv2 - app:cli - system.base - Userspace setup tool for transparent encryption of block devices using dm-crypt - Şifreli dosya sistemleri yaratmak için bir araç - Userspace setup tool for transparent encryption of block devices using dm-crypt - cryptsetup device mapper kullanarak şifrelenmiş dosya sistemleri yaratmak için gerekli bir araçtır. - cryptsetup - https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.4.tar.xz - - device-mapper-devel - libgpg-error-devel - libgcrypt-devel - - system/base/cryptsetup/pspec.xml - - - cryptsetup - - libcryptsetup - popt - - - /sbin - /usr/share/man - /usr/share/locale - /usr/share/doc - - - - libcryptsetup - cryptsetup libraries - cryptsetup kütüphaneleri - - device-mapper - libgpg-error - libgcrypt - libuuid - - - /lib/libcryptsetup.so* - - - - libcryptsetup-devel - libcryptsetup devel files - libcryptsetup için geliştirme dosyaları - - libcryptsetup - - - /usr/include - /usr/lib/pkgconfig/libcryptsetup.pc - - - - python-pycryptsetup - Python backend for cryptsetup - cryptsetup Python bağlayıcısı - programming.language.python - - python - libcryptsetup - - - /usr/lib/python2.7/site-packages/pycryptsetup.so - - - - 2014-05-11 - 1.6.4 + 2.3.1 Release bump. Marcin Bojara marcin@pisilinux.org - - 2014-04-03 - 1.6.4 - Version bump - PisiLinux Community - admins@pisilinux.org - - - 2014-03-06 - 1.6.0 - Rebuild Unused - Varol Maksutoğlu - waroi@pisilinux.org - - + 2013-07-26 - 1.6.0 + 2.3.1 Fix dep, release bump. Serdar Soytetir kaptan@pisilinux.org - - 2013-02-15 - 1.6.0 - New version - Ertan Güven - ertan@pisilinux.org - - 2012-10-05 - 1.5.0 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - leveldb - https://code.google.com/p/leveldb - - Alihan Öztürk - alihan@pisilinux.org - - BSD - app:console - system.base - A fast and lightweight key/value database library - Hızlı ve hafif bir anahtar/değer veri kütüphanesi - LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values. - LevelDB dize değerleri ile dize anahtarlarını eşleme sağlayan, Google'da yazılmış hızlı bir anahtar-değer depolama kütüphanesidir. - http://source.pisilinux.org/1.0/leveldb-e353fbc7ea81.tar.gz - - gperftools-devel - snappy-devel - - system/base/leveldb/pspec.xml - - - leveldb - - libgcc - snappy - gperftools - - - /usr/lib - /usr/share/doc - - - - leveldb-devel - - leveldb - - - /usr/include - - - - - 2014-06-02 - 1.17 - First release - Alihan Öztürk - alihan@pisilinux.org - - - - - - libffi - http://sourceware.org/libffi - - PisiLinux Community - admins@pisilinux.org - - BSD - library - system.base - A portable foreign function interface library - Yabancı işlev arayüzleri için taşınabilir bir kitaplık - The libffi library provides a portable, high level programming interface to various calling conventions. - libffi kitaplığı, çeşitli işlev çağırma konvansiyonları için taşınabilir ve yüksek düzeyli bir programlama arayüzü sunar. - ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz - system/base/libffi/pspec.xml - - - libffi - - /usr/lib/libffi.* - /usr/share/doc - - - - libffi-devel - Development files for libffi - libffi için geliştirme dosyaları - system.devel - - libffi - - - /usr/lib/libffi-* - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/info - /usr/share/man - - - - libffi-32bit - 32-bit shared libraries for libffi - libffi için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - libffi - - - /usr/lib32/libffi.* - /usr/lib32/libffi-* - - - - - 2014-12-02 - 3.2.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 3.0.13 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-31 - 3.0.13 - Version bump, clean libffi. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-17 - 3.0.12 - New Release - PisiLinux Community - admins@pisilinux.org - - - 2012-07-11 - 3.0.11 - First release - Erdem Artan - admins@pisilinux.org - - - - - - man-db - http://www.nongnu.org/man-db/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2+ - GPLv3+ - app:console - data:doc - system.base - Application to read Linux man pages - Kapsamlı Linux kılavuzları - Man package consists of programs which is used to read most of the documentation available in linux system. For example, you can write "man nameoftheprogram" into the konsole or "man:nameoftheprogram" into the konqueror to get a detailed usage information for many programs. - man-db paketi Linux ile ilgili yazılmış dökümanların büyük çoğunluğunu okunması için gerekli programları sunar. Örneğin, konsola "man programadı" ya da konquerora "man:programadı" yazarak birçok program hakkında detaylı kullanım bilgisi alabilirsiniz. - http://download.savannah.gnu.org/releases/man-db/man-db-2.6.3.tar.xz - - less - gzip - groff - gdbm-devel - zlib-devel - gettext-devel - libpipeline-devel - - - man-db-2.5.9-sgr.patch - man-db-2.6.1-locale-fallback.patch - man-db-2.6.1-so-links.patch - man-db-2.6.1-wildcards.patch - man-db-2.6.2-invalid-cache.patch - man-db-2.6.3-overrides.patch - - system/base/man-db/pspec.xml - - - man-db - - gdbm - zlib - gettext - libpipeline - - - /etc - /usr/lib - /usr/bin - /usr/sbin - /usr/libexec - /usr/share/locale - /usr/share/doc - /usr/share/man - /var/cache - - - mandb.conf - mandb.cron.daily - - - - - 2014-05-11 - 2.6.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-03 - 2.6.3 - Rebuild for openjdk. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-28 - 2.6.3 - rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-03-04 - 2.6.3 - Add some patches, cleanup. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-09-27 - 2.6.3 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - tcp-wrappers - http://ftp.porcupine.org/pub/security/index.html - - PisiLinux Community - admins@pisilinux.org - - BSD - app:console - system.base - TCP Wrappers - TCP Wrappers - Avec ce paquet, vous pouvez surveiller et filtrer les requêtes entrante pour les services réseaux SYSTAT, FINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK et autres. Il supporte à la fois les canaux de communication (sockets) de type 4.3BSD et TLI de type System V.4. - With this package you can monitor and filter incoming requests for the SYSTAT, FINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK, and other network services. It supports both 4.3BSD-style sockets and System V.4-style TLI. - Bu paket ile birlikte SYSTAT, FINGER, FTP, TELNET, RLOGIN, RSH, EXEC, TFTP, TALK ve diğer ağ servisleri için gelen istekleri izleyebilir ve süzebilirsiniz. Program 4.3BSD-tipi soketler ve System V.4-tipi TLI'ın ikisini de destekler. - http://ftp.porcupine.org/pub/security/tcp_wrappers_7.6.tar.gz - - sed - - - Makefile-Pisi.patch - tcp-wrappers-7.6-makefile.patch - tcp_wrappers-7.6-ldflags.patch - 01_all_redhat-bug11881.patch - 02_all_redhat-bug17795.patch - 03_all_wildcard.patch - 04_all_fixgethostbyname.patch - 07_all_sig.patch - 08_all_strerror.patch - 09_all_gcc-3.4.patch - 10_all_more-headers.patch - tcp-wrappers-7.6-ipv6-1.14.diff - tcp-wrappers-7.6-shared.patch - host.allow.example.patch - match-port.patch - - system/base/tcp-wrappers/pspec.xml - - - tcp-wrappers - - /usr/sbin - /usr/lib - /lib - /etc - /usr/share/man - /usr/share/doc - - - hosts.allow - hosts.deny - - - - tcp-wrappers-devel - Development files for tcp-wrappers - tcp-wrappers için geliştirme dosyaları - system.devel - - tcp-wrappers - - - /usr/include - /usr/share/man/man3 - - - - - 2014-05-11 - 7.6 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2010-10-11 - 7.6 + 2011-06-27 + 2.3.1 First release Pisi Linux Admins admins@pisilinux.org - - - help2man - http://www.gnu.org/software/help2man - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - GNU utility to convert program --help output to a man page - Geleneksel --help çıktılarını man sayfalarına dönüştüren bir GNU yazılımı - Help2man is a tool which generate man page from help text of programs. - Help2man programların help çıktılarını man sayfalarına dönüştüren bir araçtır. - http://ftp.gnu.org/gnu/help2man/help2man-1.46.4.tar.xz - - perl-Locale-gettext - - system/base/help2man/pspec.xml - - - help2man - - perl-Locale-gettext - - - /usr/bin - /usr/lib - /usr/share/doc - /usr/share/info - /usr/share/locale - /usr/share/man - - - - - 2015-02-12 - 1.46.4 - Version bump. - Hakan Yıldız - hknyldz93@gmail.com - - - 2014-05-11 - 1.41.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-01-14 - 1.41.1 - New release - PisiLinux Community - admins@pisilinux.org - - - 2011-09-07 - 1.40.4 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - python-pyliblzma - http://pypi.python.org/pypi/pyliblzma - - PisiLinux Community - admins@pisilinux.org - - LGPLv3 - library - system.base - Python bindings for lzma - Python için lzma bağlayıcıları - pyliblzma provides a python interface for the liblzma library to read/write data that has been compressed/decompressed with lzma utils. - pyliblzma, lzma araçlarıyla sıkıştırılmış verileri açmak ve lzma kitaplığı kullanarak veri sıkıştırmak için python programlama arayüzü sunan bir pakettir. - http://pypi.python.org/packages/source/p/pyliblzma/pyliblzma-0.5.3.tar.bz2 - - xz - - system/base/python-pyliblzma/pspec.xml - - - python-pyliblzma - - xz - python - - - /usr/lib/python2* - /usr/share/doc - - - - - 2014-05-11 - 0.5.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 0.5.3 - rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-28 - 0.5.3 - Fix deps. - Serdar Soytetir - kaptan@pisilinux.org - - - 2010-10-11 - 0.5.3 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - libidn - http://www.gnu.org/software/libidn - - PisiLinux Community - admins@pisilinux.org - - LGPLv2.1 - GPLv3 - app:console - library - system.base - Internationalized Domain Names (IDN) implementation - Uluslararası Alan Adları (IDN) destek kütüphanesi - GNU Libidn est une implémentation de Stringprep, Punycode et des spécifications IDNA définies par le groupe de travail Internationalized Domain Names (IDN) de l'IETF servant pour les noms de domaines internationalisés. La librairie C est disponible sous la Licence Publique Générale Lesser. - GNU Libidn is an implementation of the Stringprep, Punycode and IDNA specifications defined by the IETF Internationalized Domain Names (IDN) working group, used for internationalized domain names. The C library is available under the GNU Lesser General Public License. - GNU Libidn, IETF Uluslararasılaştırılmış Domain Adları (IDN) çalışma grubu tarafından tanımlanmış Stringgrep, Punycode ve IDNA tariflerinin bir uygulamasıdır, uluslararası domain adlarının kullanımına olanak sağlar. C kütüphanesi GNU Lesser General Public License altında sağlanabilir. - http://ftp.gnu.org/gnu/libidn/libidn-1.28.tar.gz - system/base/libidn/pspec.xml - - - libidn - - /usr/bin - /usr/lib/libidn* - /usr/share/emacs - /usr/share/locale - /usr/share/man/man1 - /usr/share/info - /usr/share/doc - - - - libidn-devel - Development files for libidn - libidn için geliştirme dosyaları - system.devel - - libidn - - - /usr/include - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/man/man3 - - - - libidn-32bit - 32-bit shared libraries for libidn - libidn için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - libidn - - - /usr/lib32/libidn* - - - - - 2014-05-11 - 1.28 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 1.28 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-01-14 - 1.26 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 1.25 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - popt - http://www.rpm5.org/ - - PisiLinux Community - admins@pisilinux.org - - as-is - app:console - library - system.base - Popt command line option parser - Popt komut satırında çalıştıran bir seçenek ayrıştırıcıdır. - La librairie popt existe essentiellement pour analyser des options de ligne de commande. Elle procure de nombreux avantages tels que l'absence de variables globales, la possibilité d'analyser un tableau arbitraire d'éléments de type argv, d'exécuter des filtres d'options extérieurs, la génération automaituqe des messages d'aide et d'utilisation ainsi qu'un méthode standard pour synonymes d'options. - The popt library exists essentially for parsing command line options with advantages such as there are no global variables, ability to parse an arbitrary array of argv-style elements, to exec external option filters, and automatic generation of help and usage messages, a standard method of option aliasing. - Popt, komut satırında seçenek ayrıştırma için gerekli bir kütüphanedir. Genel değişken olmaması, dağınık dizi bileşenlerini ayrıştırabilmesi, harici uygulama filtreleri kullanabilmesi, otomatik mesaj ve yardım dosyaları üretimi gibi başarılı özellikleri bulunur. - ftp://anduin.linuxfromscratch.org/BLFS/svn/p/popt-1.16.tar.gz - system/base/popt/pspec.xml - - - popt - - gettext - - - /usr/lib - /usr/share/doc - /usr/share/man - /usr/share/locale - - - - popt-devel - Development files for popt - popt için geliştirme dosyaları - system.devel - - popt - - - /usr/include/popt.h - /usr/share/man/man3 - /usr/lib/pkgconfig - - - - - 2014-05-11 - 1.16 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2010-10-11 - 1.16 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - lzo - http://www.oberhumer.com/opensource/lzo/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - library - system.base - An extremely fast compression and decompression library - Çok hızlı bir sıkıştırma/açma kütüphanesi - lzo is a library with very high compression and decompression speeds and very small memory usage. Provides low compression ratios but very high speeds. - lzo hızlı bir sıkıştırma/açma kütüphanesidir. Düşük sıkıştırma oranları verir fakat hem sıkıştırma hem açma işleminde bellek kullanımı çok düşüktür ve işlem hızı yüksektir. - http://www.oberhumer.com/opensource/lzo/download/lzo-2.08.tar.gz - system/base/lzo/pspec.xml - - - lzo - - /usr/lib - /usr/share/doc - - - - lzo-devel - Development files for lzo - lzo için geliştirme dosyaları - - lzo - - - /usr/include - - - - lzo-32bit - 32-bit shared libraries for lzo - emul32 - emul32 - - /usr/lib32 - - - - - 2014-07-03 - 2.08 - Version bump and security update (CVE-2014-4607). - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 2.06 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-28 - 2.06 - Clean lzo. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-10-23 - 2.06 - First release - Erdinç Gültekin - admins@pisilinux.org - - - - - - libssh2 - http://www.libssh2.org/ - - PisiLinux Community - admins@pisilinux.org - - BSD - library - system.base - A library implementing the SSH2 protocol - SSH2 protokolü için kütüphane - libssh2 is a library implementing the SSH2 protocol as defined by Internet Drafts: SECSH-TRANS, SECSH-USERAUTH, SECSH-CONNECTION, SECSH-ARCH, SECSH-FILEXFER, SECSH-DHGEX, SECSH-NUMBERS, and SECSH-PUBLICKEY. - libssh2, SECSH-TRANS, SECSH-USERAUTH, SECSH-CONNECTION, SECSH-ARCH, SECSH-FILEXFER, SECSH-DHGEX, SECSH-NUMBERS ve SECSH-PUBLICKEY gibi Internet Taslakları tarafından belirlenen SSH2 protokolü için geliştirilmiş bir kütüphanedir. - http://www.libssh2.org/download/libssh2-1.4.3.tar.gz - - openssl-devel - zlib-devel - - system/base/libssh2/pspec.xml - - - libssh2 - - openssl - zlib - - - /usr/lib - /usr/share/doc - - - - libssh2-devel - Development files for libssh2 - libssh2 için geliştirme dosyaları - system.devel - - libssh2 - - - /usr/include - /usr/lib/pkgconfig - /usr/share/man - - - - - 2014-05-11 - 1.4.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-15 - 1.4.3 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2012-06-12 - 1.4.2 - First release - Erdem Artan - admins@pisilinux.org - - - - - - liblogging - http://www.liblogging.org - - Marcin Bojara - marcin@pisilinux.org - - BSD-2 - library - system.base - Easy to use, portable, open source library for system logging - Liblogging offers an enhanced replacement for the syslog() call, but retains its ease of use. - http://download.rsyslog.com/liblogging/liblogging-1.0.3.tar.gz - system/base/liblogging/pspec.xml - - - liblogging - - /usr/lib - /usr/bin - /usr/share/man - /usr/share/doc/liblogging - - - - liblogging-devel - Development files for liblogging - system.devel - - liblogging - - - /usr/include/liblogging/stdlog.h - /usr/lib/pkgconfig/liblogging-stdlog.pc - - - - - 2014-05-11 - 1.0.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-30 - 1.0.3 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - miscfiles - http://freshmeat.net/projects/miscfiles/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - data - system.base - Fichiers divers. - Miscellaneous files - Çeşitli dosyalar - Verschiedene Dateien - miscfiles is a collection of data files for freely available information, like airport, country, currencies, city information, and codes. It also includes the Unicode character database. - miscfiles havalanı, ülke, para birimi, şehir bilgisi ve kodları gibi bir çok ulaşılabilir bilgiyi veri dosyaları halinde tutmaktadır. - http://ftp.gnu.org/gnu/miscfiles/miscfiles-1.5.tar.gz - system/base/miscfiles/pspec.xml - - - miscfiles - - /usr/share/doc - /usr/share/rfc - /usr/share/dict - /usr/share/misc - - - - - 2014-05-11 - 1.5 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-30 - 1.5 - Rebuild - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-11-24 - 1.5 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - file - http://www.darwinsys.com/file/ - - PisiLinux Community - admins@pisilinux.org - - as-is - app:console - system.base - Program to identify a file's format by scanning binary data for patterns - Dosya tipini belirlemek için kullanılan bir uygulamadır - Programme servant à identifiant le format d'un fichier en analysant les données binaires en cherchant des patrons connus. - Program to identify a file's format by scanning binary data for patterns. - İkili veri taraması kullanarak (dosya uzantısına bakmadan) dosya biçimini tanımlamaya yarayan bir uygulamadır. - ftp://ftp.astron.com/pub/file/file-5.18.tar.gz - - zlib - python-devel - - - git_fixes.patch - - system/base/file/pspec.xml - - - file - - zlib - python - - - /usr/bin - /usr/lib - /usr/share/doc - /usr/share/man - /usr/share/misc - /usr/include - - - - - 2014-05-11 - 5.18 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 5.18 - Version bump - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-22 - 5.15 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-03-04 - 5.13 - Version bump - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-16 - 5.12 - New Release - PisiLinux Community - admins@pisilinux.org - - - 2012-11-22 - 5.11 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - biosdevname - http://linux.dell.com/biosdevname/ - - Serdar Soytetir - kaptan@pisilinux.org - - GPLv2 - app:gui - system.base - Biosdevname is a udev helper utility developed - Biosdevname is a udev helper utility developed by Dell and released under the GNU General Public License (GPL). It provides a consistent naming mechanism for network devices based on their physical location as suggested by the system BIOS. - http://linux.dell.com/biosdevname/biosdevname-0.6.0/biosdevname-0.6.0.tar.gz - - pciutils-devel - glibc-devel - - system/base/biosdevname/pspec.xml - - - biosdevname - - pciutils - glibc - - - /lib/udev/rules.d - /usr/sbin - /usr/share/doc - /usr/share/man - - - - - 2014-05-11 - 0.6.0 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 0.4.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-01-19 - 0.4.1 - Rebuild - Stefan Gronewold(groni) - groni@pisilinux.org - - - 2012-10-05 - 0.4.1 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - pam - http://www.kernel.org/pub/linux/libs/pam/ - - PisiLinux Community - admins@pisilinux.org - - PAM - library - system.base - Modules d'Authentification en Greffon (Pluggable Authentication Modules) - Pluggable Authentication Modules - PAM - Eklenebilir Yetkilendirme Modülleri - PAM (Pluggable Authentication Modules) is a system security tool that allows system administrators to set authentication policy without having to recompile programs that handle authentication. - http://www.linux-pam.org/library/Linux-PAM-1.1.8.tar.bz2 - - dlopen.sh - dlopen-test.sh - - - perl - gettext - cracklib - audit-devel - - - no-lib64.patch - nosex-libtirpc-underlinking.patch - pam-1.1.8-cve-2013-7041.patch - pam-1.1.8-cve-2014-2583.patch - - system/base/pam/pspec.xml - - - pam - - audit - cracklib - - - /etc - /lib - /var/run/console - /usr/lib - /sbin - /usr/sbin - /usr/share/doc - /usr/share/man - /usr/share/locale - - - System.Package - - - 90-nproc.conf - - - - pam-devel - Development files for pam - pam için geliştirme dosyaları - system.devel - - pam - - - /usr/include - /usr/share/man/man3 - - - - - 2014-06-10 - 1.1.8 - Add patch CVE. - Alihan Öztürk - alihan@pisilinux.org - - - 2014-05-11 - 1.1.8 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-22 - 1.1.8 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-05-16 - 1.1.6 - Sandbox fixed. - PisiLinux Community - admins@pisilinux.org - - - 2013-02-21 - 1.1.6 - Build with new automake, enable tests. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-09-13 - 1.1.6 - First release - Erdem Artan - admins@pisilinux.org - - - - - - sqlite - http://www.sqlite.org/ - - PisiLinux Community - admins@pisilinux.org - - as-is - library - system.base - An SQL Database Engine in a C Library - Bir C kütüphanesi içindeki bir SQL veritabanı motoru - SQLite est une petite librairie C implémentant un moteur de base de données SQL auto-configurée, auto-suffisante, pouvant être embarquée. Gère des bases de données de tailles allant jusqu'à 2 téraOctets. - SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine. Supports databases up to 2 terabytes in size. - SQLite hiçbir ayar gerektirmeyen, başka programların içine gömülebilir bir SQL veritabanı motorudur. 2 terabayta kadar büyüklükteki veritabanlarını tutabilir. - http://www.sqlite.org/2014/sqlite-autoconf-3080702.tar.gz - - readline-devel - - system/base/sqlite/pspec.xml - - - sqlite - - readline - - - /usr/bin - /usr/lib - /usr/share/doc - /usr/share/man - - - - sqlite-devel - Development files for sqlite - sqlite için geliştirme dosyaları - system.devel - - sqlite - - - /usr/include - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - - - - sqlite-32bit - 32-bit shared libraries for sqlite - emul32 - emul32 - - sqlite - - - /usr/lib32 - - - - - 2015-01-31 - 3.8.8.2 - Version bump. - Hakan Yıldız - hknyldz93@gmail.com - - - 2015-01-24 - 3.8.8.1 - Version bump. - Hakan Yıldız - hknyldz93@gmail.com - - - 2014-12-05 - 3.8.7.2 - Version bump. - Osman Erkan - osman.erkan@pisilinux.org - - - 2014-07-09 - 3.8.5 - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 3.8.4.3 - Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2014-03-29 - 3.8.4.2 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 3.8.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-06-28 - 3.7.17 - Move pc files to devel pack, increase release no. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-06-28 - 3.7.17 - Version bump - Marcin Bojara - marcin@pisilinux.org - - - 2013-01-21 - 3.7.15.2 - bump - Erdinç Gültekin - admins@pisilinux.org - - - 2012-12-15 - 3.7.14 - First release - Erdinç Gültekin - admins@pisilinux.org - - - - - - kmod - http://git.kernel.org/?p=utils/kernel/kmod/kmod.git;a=summary - - PisiLinux Community - admins@pisilinux.org - - GPLv2+ - app:console - system.base - Linux kernel module management utilities - Linux kernel modülleri yönetim araçları - Linux kernel module management utilities - Linux kernel modülleri yönetim araçları - ftp://ftp.kernel.org/pub/linux/utils/kernel/kmod/kmod-19.tar.xz - - chrpath - libxslt - - system/base/kmod/pspec.xml - - - kmod - - xz - zlib - glibc - libkmod - - - /usr/bin - /bin - /sbin - /usr/share/man - /usr/share/doc - /etc - /usr/share/bash-completion/completions/kmod - - - Boot.Modules - System.PackageHandler - - - blacklist/blacklist.conf - blacklist/blacklist-firewire.conf - blacklist/blacklist-framebuffer.conf - blacklist/blacklist-watchdog.conf - modprobe.conf - depmod.conf - - - - libkmod-devel - system.devel - - libkmod - - - /usr/include - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - - - - libkmod - kmod libraries - - xz - zlib - - - /usr/lib - - - - libkmod-32bit - 32bit libraries of libkmod - emul32 - emul32 - - xz-32bit - zlib-32bit - - - /usr/lib32 - - - - - 2014-11-18 - 19 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-23 - 17 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 16 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-01-21 - 16 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-05 - 15 - Add missing method to pakhandler.py - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-31 - 15 - Version bump, clean kmod. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-20 - 14 - rebuild for kernel 3.10.9 - PisiLinux Community - admins@pisilinux.org - - - 2013-08-11 - 14 - rebuild for kernel 3.10.5 - PisiLinux Community - admins@pisilinux.org - - - 2013-07-27 - 14 - Move pc files to devel pack, rebuild - PisiLinux Community - admins@pisilinux.org - - - 2013-07-04 - 14 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-04-14 - 13 - Version bump - Marcin Bojara - marcin@pisilinux.org - - - 2013-01-22 - 12 - Version bump, add comar scripts - Marcin Bojara - marcin@pisilinux.org - - - 2012-11-15 - 11 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - vixie-cron - http://www.gentoo.org/ - - PisiLinux Community - admins@pisilinux.org - - as-is - service - system.base - Paul Vixie's cron daemon, a fully featured crond implementation - Tam teşekküllü bir crond uyarlaması - Vixie cron (Cron est un daemon qui lance des tâches planifiées) est une implémentation riche basée sur le cron SysV. Chaque utilisateur possède sa propre table de planification (ou crontab - la CRON TABle de Crontab) est un fichier qui contient le planning de cron) et a la possibilité de spécifier des variables d'environnement au sein de la table. - Vixie cron (Cron is a daemon that runs scheduled tasks.) is a full featured cron implementation based on SysV cron. Each user has his own crontab ( Crontab (CRON TABle) is a file which contains the schedule of cron) and is allowed to specify environment variables within that crontab. - Vixie-cron (cron, zamanlanmış görevleri çalıştıran dinleyici programdır.) SysV cron tabanlı tam sürüm cron uygulamasıdır. Her kullanıcı kendi crontab 'ına (crontab cron listesini içeren dosyadır.) sahiptir ve bu crontab içinde ortam değişkenlerini yazmasına müsade edilmiştir. - ftp://ftp.linux.org.tr/pub/gentoo/distfiles/vixie-cron-4.1.tar.bz2 - - sed - pam - - - vixie-cron-4.1-gentoo-r4.patch.bz2 - crontab.5.diff - vixie-cron-4.1-commandline.patch - vixie-cron-4.1-pam.patch - vixie-cron-4.1-CAN-2005-1038.patch - CVE-2006-2607.patch - CVE-2007-1856.patch - - system/base/vixie-cron/pspec.xml - - - vixie-cron - - pam - comar-api - - - /usr/sbin - /usr/bin - /etc - /var/spool - /usr/share/doc - /usr/share/man - - - System.Package - System.Service - - - run-crons-0.3.1 - crontab - vixie-cron-4.1-cron.deny - cron.pam.d - - - - - 2014-05-11 - 4.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2010-10-11 - 4.1 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - expat - http://expat.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - as-is - library - system.base - librairies d'analyse XML - XML parsing libraries - XML ayrıştırıcı kütüphaneleri - XML Parser Bibliotheken - This is expat, the C library for parsing XML, written by James Clark. Expat is a stream oriented XML parser. This means that you register handlers with the parser prior to starting the parse. These handlers are called when the parser discovers the associated structures in the document being parsed. A start tag is an example of the kind of structures for which you may register handlers. - mirrors://sourceforge/expat/expat-2.1.0.tar.gz - - gnuconfig - - system/base/expat/pspec.xml - - - expat - - /usr/bin - /usr/lib - /usr/share/doc - /usr/share/man - - - - expat-devel - Development files for expat - expat için geliştirme dosyaları - system.devel - - expat - - - /usr/include - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/doc/expat/html - - - - expat-32bit - 32-bit shared libraries for expat - expat için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - expat - - - /usr/lib32 - - - - - 2014-05-11 - 2.1.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-27 - 2.1.0 - Move pc files to devel pack, rebuild - PisiLinux Community - admins@pisilinux.org - - - 2013-01-21 - 2.1.0 - Remove patch which causing test error for perl-XML-Parser. - Marcin Bojara - marcin@pisilinux.org - - - 2011-03-01 - 2.1.0 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - less - http://www.greenwoodsoftware.com/ - - PisiLinux Community - admins@pisilinux.org - - GPLv3 - app:console - system.base - Excellent lecteur de fichier texte - Excellent text file viewer - Mükemmel bir metin görüntüleyici - Ausgezeichneter Textbetrachter - The less utility is a text file browser that resembles more, but has more capabilities. Less allows you to move backwards in the file as well as forwards. Since less doesn't have to read the entire input file before it starts, less starts up more quickly than text editors (for example, vi). - http://www.greenwoodsoftware.com/less/less-458.tar.gz - - ncurses-devel - - system/base/less/pspec.xml - - - less - - ncurses - - - /etc/env.d - /usr/bin - /usr/share/doc - /usr/share/man - - - lesspipe.sh - 70less - code2color - - - - - 2014-05-11 - 458 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-24 - 458 - Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2012-09-15 - 451 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - perl - http://www.perl.org/ - - PisiLinux Community - admins@pisilinux.org - - Artistic - GPLv2 - app:console - system.base - Larry Wall's Practical Extraction and Reporting Language - Perl dili - Perl est un langage de programmation multi-plateforme stable. - Perl is a high-level programming language with roots in C, sed, awk and shell scripting. Perl is good at handling processes and files, and is especially good at handling text. Perl's hallmarks are practicality and efficiency. While it is used to do a lot of different things, Perl's most common applications are system administration utilities and web programming. A large proportion of the CGI scripts on the web are written in Perl. You need the perl package installed on your system so that your system can handle Perl scripts. - Perl kararlı, platform bağımsız programlama dilidir. - Perl ist eine stabile, plattformunabhängige Programmiersprache - http://www.cpan.org/src/5.0/perl-5.20.0.tar.bz2 - - db-devel - gdbm-devel - zlib-devel - - - perl-vutil-revert.patch - - system/base/perl/pspec.xml - - - perl-docs - Documentation files for perl - programming.language.perl - - /usr/share/doc/html - /usr/share/doc/perl/html - /usr/share/man/ - - - - perl - - db - gdbm - zlib - - - /usr/bin - /usr/lib - /usr/share/doc - - - Turkish.pm - - - - - 2014-09-10 - 5.20.0 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 5.18.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-08-28 - 5.18.1 - Version bump, clean perl. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-26 - 5.16.2 - Release bump, rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-19 - 5.16.2 - First release - PisiLinux Community - admins@pisilinux.org - - - 2012-09-06 - 5.16.1 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - texinfo - http://www.gnu.org/software/texinfo/ - - PisiLinux Community - admins@pisilinux.org - - GPLv3 - app:console - system.base - programme et utilitaires GNU info. - The GNU info program and utilities - GNU info (bilgi) programı ve araçları - GNU Info Prgramm und Werkzeuge - Texinfo is a documentation system that can produce both online information and printed output from a single source file. The GNU Project uses the Texinfo file format for most of its documentation. - mirrors://gnu/texinfo/texinfo-5.2.tar.gz - - ncurses - - system/base/texinfo/pspec.xml - - - texinfo - - ncurses - - - /usr/bin - /usr/share/doc - /usr/share/man - /usr/share/info - /usr/share/texinfo - /usr/share/texmf/tex/texinfo - /usr/share/locale - /usr/share/texmf/ - - - System.PackageHandler - - - - - 2014-05-25 - 5.2 - Release bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 5.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-22 - 5.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-09-05 - 4.13 - Add missing method to pakhandler.py - Marcin Bojara - marcin@pisilinux.org - - - 2010-10-11 - 4.13 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - spidermonkey - http://www.mozilla.org/js/spidermonkey/ - - PisiLinux Community - admins@pisilinux.org - - NPL-1.1 - library - system.base - Stand-alone JavaScript C Library - Javascript C Kitaplığı - Spidermonkey est l'Implémentation C de Javascript par Mozilla. - Spidermonkey is Mozilla's C implementation of JavaScript. - Mozilla'nın Javascript'in C implementasyonu. - Spidermonkey es la implementación de JavaScript con C de Mozilla. - http://ftp.mozilla.org/pub/mozilla.org/js/mozjs17.0.0.tar.gz - - zlib-devel - nspr-devel - readline-devel - - system/base/spidermonkey/pspec.xml - - - spidermonkey - - nspr - zlib - libgcc - readline - - - /usr/bin - /usr/lib - /usr/share/doc - - - - spidermonkey-devel - Development files for spidermonkey - spidermonkey için geliştirme dosyaları - system.devel - - spidermonkey - nspr-devel - - - /usr/include - /usr/lib/pkgconfig - /usr/bin/js17-config - - - - - 2014-05-11 - 17.0.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-30 - 17.0.0 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-28 - 17.0.0 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-28 - 1.8.5 - Move pc files to devel pack,rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-20 - 1.8.5 - Release bump for rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-20 - 1.8.5 - Cleanup package, bump for new build - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-09-20 - 1.8.5 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - mailcap - http://git.fedorahosted.org/git/mailcap.git - - PisiLinux Community - admins@pisilinux.org - - MIT - public-domain - data - system.base - Helper application and MIME type associations for file types - Dosya türleri için yardımcı uygulama ve MIME türü ilişkilendirmeleri - mailcap file is used by the metamail program. Metamail reads the mailcap file to determine how it should display non-text or multimedia material. - mailcap dosyası metamail ve bazı diğer uygulamalar tarafından, metin olmayan dosyaların ya da çokluortam dosyalarının nasıl açılacağını keşfetmek için kullanılır. - https://fedorahosted.org/released/mailcap/mailcap-2.1.42.tar.xz - - extend-mailcap.patch - - system/base/mailcap/pspec.xml - - - mailcap - - /etc - /usr/share/doc - /usr/share/man - - - - - 2014-05-11 - 2.1.42 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 2.1.42 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2011-06-01 - 2.1.37 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - attr - http://acl.bestbits.at/ - - Pisi Linux Admins - admins@pisilinux.org - - LGPLv2.1 - app:console - library - system.base - Utilities for managing filesystems extended attributes - Gelişkin öznitelikler araçları - attr offre des utilitaires qui servent à manipuler les attributs étendus des objects de système de fichier. - attr contains a set of tools for manipulating extended attributes on filesystem objects, in particular getfattr and setfattr. - attr dosya sistemi nesnelerinin özniteliklerini değiştirmek için gerekli bir dizi araç sunar. - http://download.savannah.gnu.org/releases-noredirect/attr/attr-2.4.47.src.tar.gz - system/base/attr/pspec.xml - - - attr - - /bin - /lib - /usr/share/locale - /usr/share/doc - /usr/share/man - - - - attr-devel - Development files for attr - attr için geliştirme dosyaları - system.devel - - attr - - - /usr/include - /usr/share/man/man3 - - - - attr-32bit - 32-bit shared libraries for attr - emul32 - emul32 - - attr - - - /lib32 - - - - - 2014-09-30 - 2.4.47 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 2.4.47 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-28 - 2.4.47 - Version bump, clean attr. - Marcin Bojara - marcin@pisilinux.org - - - 2013-01-24 - 2.4.46 - Add emul32 - Marcin Bojara - marcin@pisilinux.org - - - 2012-06-04 - 2.4.46 - First release - Erdem Artan - admins@pisilinux.org - - - - - - acl - http://acl.bestbits.at/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2+ - LGPLv2.1 - app:console - library - system.base - Utilitaires, librairies et fichiers d'entête de liste de contrôle d'accès. - Access control list utilities - Erişim denetim listesi için çeşitli araçlar - acl contains the getfacl and setfacl utilities needed for manipulating access control lists along with the needed libraries. - acl erişim denetim listelerini yönetmeye yarayan getfacl ve setfacl araçlarıyla gerekli kütüphaneleri içeren bir pakettir. - http://download.savannah.gnu.org/releases-noredirect/acl/acl-2.2.52.src.tar.gz - - attr - - system/base/acl/pspec.xml - - - acl - - attr - - - /bin - /lib - /usr/share/locale - /usr/share/doc - /usr/share/man - - - - acl-devel - Development files for acl - acl için geliştirme dosyaları - system.devel - - acl - - - /usr/include - /usr/share/man/man3 - - - - - 2014-09-30 - 2.2.52 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 2.2.52 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-28 - 2.2.52 - Version bump, clean acl. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-06-04 - 2.2.51 - First release - Erdem Artan - admins@pisilinux.org - - - - - - busybox - http://www.busybox.net - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - Statically linked binary providing simplified versions of system commands - Statik bağlanmış sistem komutları bütünü - busybox is a single binary which includes versions of a large number of system commands, including a shell. - busybox, kabuk da dahil olmak üzere çeşitli sistem komutlarını içeren tek bir çalıştırılabilir dosyadır. - http://busybox.net/downloads/busybox-1.22.1.tar.bz2 - - config - - - udhcp-rootpath-rq.patch - suppress-job-control-warning.patch - fix-include.patch - - system/base/busybox/pspec.xml - - - busybox - - /bin - - - - - 2014-05-11 - 1.22.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-03-29 - 1.22.1 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-14 - 1.21.0 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 1.20.2 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - grep - http://www.gnu.org/software/grep/grep.html - - PisiLinux Community - admins@pisilinux.org - - GPLv3 - app:console - system.base - GNU regular expression matcher - Grep düzenli ifade eşleme aracı - La commande grep recherche dans un ou plusieurs fichiers les lignes correspondant à un motif défini. Par défaut grep affiche les lignes éligibles. - The grep command searches one or more input files for lines containing a match to a specified pattern. By default, grep prints the matching lines. - Grep komutu bir veya daha fazla verilen dosyada aranan parçayı bulmaya yarayan bir programdır. Ön tanımlı olarak grep eşleşen satırları çıktıya verir. - http://ftp.gnu.org/gnu/grep/grep-2.20.tar.xz - - gettext - libpcre-devel - - system/base/grep/pspec.xml - - - grep - - libpcre - - - /bin - /usr/share/doc - /usr/share/man - /usr/share/info - /usr/share/locale - - - - - 2014-06-04 - 2.20 - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 2.18 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 2.18 - Version bump - PisiLinux Community - admins@pisilinux.org - - - 2013-10-27 - 2.15 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-10-22 - 2.14 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2010-10-11 - 2.14 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - zlib - http://www.gzip.org/zlib/ - - PisiLinux Community - admins@pisilinux.org - - ZLIB - library - system.base - Librairie de compression/extraction standard - Standard (de)compression library - Standart sıkıştırma/açma kütüphanesi - Zlib is a general-purpose, patent-free, lossless data compression library which is used by many different programs. - mirrors://sourceforge/libpng/zlib-1.2.8.tar.xz - - dont-call-ldconfig.patch - - system/base/zlib/pspec.xml - - - minizip - Library for manipulating files from a zip archive - zip arşivlerindeki dosyaları yönetmek için kitaplık - util.archive - minizip - - zlib - - - /usr/lib/libminizip* - - - - minizip-devel - Development files for minizip - minizip için geliştirme dosyaları - util.archive - minizip - - minizip - zlib-devel - - - /usr/include/minizip - /usr/lib/pkgconfig/minizip.pc - - - - zlib - - /lib/libz.so* - /usr/lib/libz.so* - /usr/share/doc - /usr/share/man - - - - zlib-devel - Development files for zlib - zlib için geliştirme dosyaları - system.devel - - zlib - - - /usr/lib/pkgconfig/zlib.pc - /usr/lib32/pkgconfig - /usr/include/z*.h - /usr/share/man/man3 - /usr/share/doc/zlib/algorithm.txt - /usr/share/doc/zlib/example.c - - - - zlib-32bit - 32-bit shared libraries for zlib - zlib için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - zlib - - - /usr/lib32/libz.so* - - - - - 2014-05-11 - 1.2.8 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-27 - 1.2.8 - Clean zlib. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-06-29 - 1.2.8 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-06-03 - 1.2.7 - First release - Erdem Artan - admins@pisilinux.org - - - - - - kbd - http://freshmeat.net/projects/kbd/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - Keyboard and console utilities - Klavye ve konsol araçları - Le paquet kbd contient les fichiers de configuration de touches ainsi que divers utilitaires pour claviers compatible avec le noyau 1.1.54 et suivants. - The kbd package contains keytable files and keyboard utilities compatible with kernel version 1.1.54 and later. - Kbd paketi, çekirdek sürüm 1.1.54 ve sonraki sürümlerle uyumlu anahtar tablo dosyaları ve klavye yardımcı uygulamaları içerir. - ftp://ftp.altlinux.org/pub/people/legion/kbd/kbd-1.15.5.tar.gz - http://source.pisilinux.org/1.0/kbd-latarcyrheb-16-fixed.tar.bz2 - http://source.pisilinux.org/1.0/kbd-latsun-fonts.tar.bz2 - http://source.pisilinux.org/1.0/ro_maps.tar.bz2 - - gettext - gzip - - - kbd-1.15.5-loadkeys-parse.patch - mandriva/kbd-1.15-mandriva.patch - mandriva/kbd-1.15-tilde_twosuperior_french_kbd.patch - mandriva/kbd-1.12-data_thai.patch - mandriva/kbd-1.15-remove-unneeded-calls.patch - fedora/kbd-1.15-keycodes-man.patch - pisilinux/unicode_start-default-font.patch - pisilinux/tr-keypad-comma.patch - pisilinux/tr-no-meta_space.patch - pisilinux/trq-capslock-fix.patch - pisilinux/currency.patch - pisilinux/trf-keymap-fixes.patch - pisilinux/trf-capslock-fix.patch - - system/base/kbd/pspec.xml - - - kbd - - pam - - - /bin - /usr/bin - /usr/share/doc - /usr/share/man - /usr/share/keymaps - /usr/share/locale - /usr/share/unimaps - /usr/share/consolefonts - /usr/share/consoletrans - - - pisilinux/lat5u-12.psf.gz - pisilinux/lat5u-14.psf.gz - pisilinux/lat5u-16.psf.gz - mandriva/mac-fr-ext_new.kmap.gz - - - - - 2014-05-11 - 1.15.5 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 1.15.5 - rebuild. - PisiLinux Community - admins@pisilinux.org - - - 2013-07-26 - 1.15.5 - Fix dep, release bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-05-30 - 1.15.5 - Fix dep, release bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-01-14 - 1.15.5 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 1.15.2 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - tar - http://www.gnu.org/software/tar/ - - PisiLinux Community - admins@pisilinux.org - - GPLv3+ - app:console - system.base - A GNU file archiving program - GNU dosya arşivleme uygulaması - Le programme tar fournit la possibilité de manipuler des archives de type tar. Vous pouvez l'utiliser pour créer ou extraires des archives. Ajouter des fichiers à des archives existantes, les mettre à jour ou tout simplement lister leur contenu. - The GNU tar program saves many files together in one archive and can restore individual files (or all of the files) from that archive. - GNU tar birden fazla dosyayı tek bir arşiv dosyasında birleştiren ve daha sonra bu arşiv dosyasından geri çıkartabilen bir uygulamadır. - http://ftp.gnu.org/gnu/tar/tar-1.27.1.tar.xz - - tar.1 - - - gzip - bzip2 - gettext - ncompress - - system/base/tar/pspec.xml - - - tar - - acl - glibc - - - /bin - /sbin - /usr/share/doc - /usr/share/man - /usr/share/locale - /usr/share/info - - - - - 2014-05-11 - 1.27.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-11-23 - 1.27.1 - Version bump - Richard de Bruin - richdb@pisilinux.org - - - 2013-10-24 - 1.27 - Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2013-07-31 - 1.26 - Fix deps. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-08-23 - 1.26 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - bzip2 - http://www.bzip.org/ - - PisiLinux Community - admins@pisilinux.org - - BZIP2 - app:console - system.base - A high-quality data compressor - Yüksek kaliteli bir veri sıkıştırma uygulaması - bzip2 est un compresseur de données de très grand qualité. Il compresse typiquement les fichiers à un ratio entre 10 et 15% des meilleurs techniques disponibles (la famille des compresseurs statistiques de famille PPM) tout en étant environ deux fois plus rapide à la compression et six fois plus rapide à la décompression. - bzip2 is high-quality data compressor. It typically compresses files to within 10% to 15% of the best available techniques (the PPM family of statistical compressors), whilst being around twice as fast at compression and six times faster at decompression. - bzip2 yüksek kaliteli bir veri sıkıştırma programıdır. Program genellikle dosyaları mümkün olan en iyi teknikler ile (PPM istatistiksel sıkıştırıcı ailesi) %10 - %15'e kadar sıkışıtırabilmektedir. Sıkıştırma işleminde iki kata kadar hızlı iken açma hızında yaklaşık altı kat daha hızlıdır. - bzip2 ist ein hochwertiger Daten-Kompressor. Es komprimiert Dateien üblicherweise auf 10% bis 15% der bestmöglichen Techniken (die PPM Familie der statistischen Kompressoren), während es ungefähr doppelt so schnell komprimiert und sechsfach schneller extrahiert - http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz - - bzip2-1.0.2-progress.patch - bzip2-1.0.4-bzip2recover.patch - bzip2-1.0.4-man-links.patch - bzip2-1.0.6-saneso.patch - manpath.patch - - system/base/bzip2/pspec.xml - - - bzip2 - - /bin - /lib - /usr/lib - /usr/share/doc - /usr/share/man - /usr/include - - - - - 2014-09-30 - 1.0.6 - Rebuild,cleanup, enable tests. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 1.0.6 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-28 - 1.0.6 - Release bump,clean bzip2. - Serdar Soytetir - kaptan@pisilinux.org - - - 2010-10-11 - 1.0.6 - First release - PisiLinux Community - admins@pisilinux.org - - - dbus @@ -12821,13 +14800,11 @@ D-Bus fourni à la fois un daemon système (pour les événements els que l'"ajout d'un nouveau périphérique" ou "file d'impression changée") et un daemon propre à chaque session utilisateur (pour les besoins généraux de communication entre processus utilisateurs). De plus, le bus de message est construit en se basant sur un framework (cadre de développement) de passage de message de un-vers-un pouvant être utilisé par n'importe quelles applications pour communiquer directement (sans passer par le daemon de bus de message). Pour l'instant les applications pouvant communiquer doivent être situées sur le même ordinateur, mais l'option TCP/IP est disponible et le support de processus distant est prévu. D-Bus supplies both a system daemon (for events such as "new hardware device added" or "printer queue changed") and a per-user-login-session daemon (for general IPC needs among user applications). Also, the message bus is built on top of a general one-to-one message passing framework, which can be used by any two apps to communicate directly (without going through the message bus daemon). Currently the communicating applications are on one computer, but TCP/IP option is available and remote support planned. D-Bus, sistem ve kullanıcılar için olmak üzere iki tane artalan süreci (daemon) sunar. Mesaj yolu, bire bir mesaj geçiş araçları üzerine inşa edilmiştir. Bu sayede iki program birbiriyle bir mesaj yolu artalan süreci kullanmadan, direkt olarak haberleşebilir. Şu an için haberleşme araçları aynı bilgisayar üzerinde çalışabilmektedir, fakat TCP/IP ile uzaktan haberleşme de planlanmaktadır. - http://dbus.freedesktop.org/releases/dbus/dbus-1.9.10.tar.gz + http://dbus.freedesktop.org/releases/dbus/dbus-1.9.14.tar.gz expat-devel libX11-devel - doxygen libcap-ng-devel - xmlto system/base/dbus/pspec.xml @@ -12835,8 +14812,8 @@ dbus expat - libX11 libcap-ng + libX11 /etc/dbus-1 @@ -12858,13 +14835,24 @@ tmpfiles.conf + + dbus-x11 + x11.util + + libX11 + dbus + + + /usr/bin/dbus-launch + + dbus-devel Development files for dbus dbus için geliştirme dosyaları system.devel - dbus + dbus /usr/include @@ -12882,15 +14870,23 @@ emul32 expat-32bit + glibc-32bit - dbus + glibc-32bit /usr/lib32 + + 2015-05-11 + 1.9.14 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2015-02-15 1.9.10 @@ -12970,74 +14966,6 @@ - - - zip - http://www.info-zip.org/Zip.html - - PisiLinux Community - admins@pisilinux.org - - Info-ZIP - app:console - system.base - Info ZIP (encryption support) - ZIP programı (şifreleme desteği ile birlikte) - Zip est un outil de compression et d'archivage/packaging. Zip est utile pour distribuer un ensemble de fichier sous forme de paquets, et pour sauvegarder de l'espace disque en compressant temporairement les fichiers et répertoires inutilisés. - Zip is a compression and file packaging/archive utility. Zip is useful for packaging a set of files for distribution, for archiving files, and for saving disk space by temporarily compressing unused files or directories. - Zip bir sıkıştırma ve dosya paketleme/arşivleme uygulamasıdır. Zip dosyaları dağıtmak, arşivlemek ve kullanılmayan dosyaları ve dizinleri geçici olarak sıkıştırarak disk boşluğundan tasarruf için kullanılabilecek kullanışlı bir uygulamadır. - mirrors://sourceforge/infozip/Zip%203.x%20%28latest%29/3.0/zip30.tar.gz - system/base/zip/pspec.xml - - - zip - - bzip2 - - - /usr/bin - /usr/share/doc - /usr/share/man - - - - - 2014-10-01 - 3.0 - Cleanup,rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 3.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 3.0 - rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-07-26 - 3.0 - Release bump for rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2010-10-11 - 3.0 - First release - Pisi Linux Admins - admins@pisilinux.org - - - libgpg-error @@ -13055,7 +14983,7 @@ GnuPG bileşenlerinin kullandığı hata değerleri için kitaplık libgpg-error is a library that defines common error values for all GnuPG components. libgpg-error, tüm GnuPG bileşenleri için ortak olan hata değerlerini tanımlayan bir kitaplıktır. - ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.12.tar.bz2 + ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.19.tar.bz2 system/base/libgpg-error/pspec.xml @@ -13064,6 +14992,8 @@ /usr/bin /usr/lib /usr/share/doc + /usr/share/info + /usr/share/man /usr/share/locale @@ -13073,10 +15003,10 @@ libgpg-error için geliştirme dosyaları system.devel - libgpg-error + libgpg-error - /usr/bin/*-config + /usr/bin/gpg-error-config /usr/include /usr/lib/pkgconfig /usr/lib32/pkgconfig @@ -13089,14 +15019,25 @@ libgpg-error için 32-bit paylaşımlı kitaplıklar emul32 emul32 + + glibc-32bit + - libgpg-error + libgpg-error + glibc-32bit /usr/lib32 + + 2015-04-13 + 1.19 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 1.12 @@ -13122,54 +15063,582 @@ - which - http://www.xs4all.nl/~carlo17/which/ + patch + http://www.gnu.org/software/patch/patch.html PisiLinux Community admins@pisilinux.org GPLv2 app:console - system.base - Prints the location of specified executable in your path - Verilen komutun çalıştırma yolundaki önceliğe göre yerini gösterir - which, localise un programme dans le chemin de l'utilisateur. - which , Locates a program file in the user's path. - which, kullanıcı dizinindeki program dosyalarının yarini bulur. - which, findet eine Anwendungsdatei im Benutzerverzeichnis - mirrors://gnu/which/which-2.20.tar.gz - - which-gentoo.patch - - system/base/which/pspec.xml + system.devel + Applies patch files + Yama dosyalarını uygular + Aplicación de archivos de parches + Permet d'appliquer un patch générer par la commande diff aux fichiers originels, obtenant ainsi les fichiers patchés. + Patch takes a patch file generated by diff command, and applies it to the original files, thus producing patched files. + Özgün dosyaları, diff komutu ile üretilmiş yama dosyasını uygulayarak, yeni biçimlerine çevirir. + Recibe una archivo de parche generado por el comando diff y lo aplica a los archivos originales, así produciendo archivos parcheados. + ftp://ftp.gnu.org/gnu/patch/patch-2.7.4.tar.xz + system/devel/patch/pspec.xml - which + patch + + attr + /usr/bin /usr/share/doc /usr/share/man + + + + + 2015-02-01 + 2.7.4 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + + + 2014-05-11 + 2.7.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-27 + 2.7.1 + Add patch. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-01 + 2.7.1 + Fix deps. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-17 + 2.7.1 + New release + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-09-23 + 2.7 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + flex + http://flex.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + FLEX + app:console + system.devel + GNU lexical analyser generator + GNU sözcüksel analiz üreteci + Flex est un outil de génération d'analyseur (scanner). Un analyseur (également appelé tokenizer en anglais) est un programme qui repère les motifs lexicaux (ou lexème) dans du texte. + Flex is a tool for generating scanners. A scanner, sometimes called a tokenizer, is a program which recognizes lexical patterns in text + Flex, metin içindeki sözcüksel kalıpları tanıyan, analiz aracı üretecidir. + mirrors://sourceforge/flex/flex-2.5.39.tar.gz + + patch + + + flex-2.5.37-notex.patch + + system/devel/flex/pspec.xml + + + flex + + /usr/bin + /usr/lib + /usr/share/doc + /usr/share/man /usr/share/info + /usr/include + /usr/share/locale + + + + + 2014-06-02 + 2.5.39 + Version bump. + Vedat Demir + vedat@pisilinux.org + + + 2014-05-11 + 2.5.38 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 2.5.38 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-28 + 2.5.37 + Clean flex. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-18 + 2.5.37 + v.bump + PisiLinux Community + admins@pisilinux.org + + + 2012-07-14 + 2.5.35 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + xtrans + http://www.x.org/ + + PisiLinux Community + admins@pisilinux.org + + MIT + library + system.devel + Librairie trans de X.Org. + X.Org trans library + X.Org trans kitaplığı. + X.Org trans Bibliothek + xtrans includes a number of routines to make X implementations transport-independent. + xtrans, X gerçeklemelerini taşıma türünden bağımsız yapmak için kullanılan bazı yordamları içerir. + mirrors://xorg/individual/lib/xtrans-1.3.5.tar.bz2 + + util-macros + + system/devel/xtrans/pspec.xml + + + xtrans + + /usr/include/X11/Xtrans + /usr/share/aclocal + /usr/share/pkgconfig + + + + + 2015-05-05 + 1.3.5 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-07-11 + 1.3.4 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 1.3.3 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-05 + 1.3.3 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-01-17 + 1.3.2 + Version bump + Richard de Bruin + richdb@pisilinux.org + + + 2012-08-19 + 1.2.7 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + intltool + http://www.gnome.org/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.devel + Utility for internationalizing various kinds of data files + Çeşitli kaynak kod dosyalarından satırları ayıklamak için kullanılan betikler + Scripts d'extraction depuis divers fichiers sources de chaînes traduisibles. + intltool automatically extracts translatable strings from oaf, glade, bonobo ui, nautilus theme, .desktop files, etc. and puts them in the po files. + Çeşitli kaynak kod dosyalarından satırları ayıklamak için kullanılan betikler. + http://source.pisilinux.org/1.0/intltool-0.50.2.tar.gz + + perl + perl-XML-Parser + + system/devel/intltool/pspec.xml + + + intltool + + perl-XML-Parser + + + /usr/bin + /usr/share/aclocal + /usr/share/intltool + /usr/share/man + /usr/share/doc 2014-05-11 - 2.20 + 0.50.2 Release bump. Marcin Bojara marcin@pisilinux.org - 2013-10-28 - 2.20 - rebuild. + 2013-08-28 + 0.50.2 + Clean intltool. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-09-19 + 0.50.2 + First release Yusuf Aydemir yusuf.aydemir@pisilinux.org + + + + + cmake + http://www.cmake.org + + PisiLinux Community + admins@pisilinux.org + + BSD + app:console + system.devel + Cross-platform, open-source make system + Cmake, açık kaynak kodlu ve birden fazla platformda çalışan bir 'make' sistemidir. + CMake, système make open-source et multi-plateforme. CMake est utilisé pour contrôler le processus de compilation de logiciel en utilisant une plate-forme de fichiers de configuration simple et indépendante de compilateur. CMake génère des makefiles et un environnement de travail natifs pouvant être utilisés dans l'environnement du compilateur de votre choix. + CMake, the cross-platform, open-source make system. CMake is used to control the software compilation process using simple platform and compiler independent configuration files. CMake generates native makefiles and workspaces that can be used in the compiler environment of your choice. + Cmake, açık kaynak kodlu ve birden fazla platformda çalışan bir 'make' sistemidir. Yazılım derleme sürecini kontrol etmek için kullanılan CMake, derleyici bağımsız yapılandırma dosyalarının oluşturulmasını sağlar. + http://www.cmake.org/files/v3.2/cmake-3.2.2.tar.gz + + curl-devel + expat-devel + libarchive-devel + ncurses-devel + zlib-devel + + system/devel/cmake/pspec.xml + + + cmake + + curl + expat + libarchive + libgcc + ncurses + zlib + + + /usr/bin + /usr/share/cmake + /usr/share/aclocal/ + /usr/share/doc + /usr/share/man + + + + + 2015-04-17 + 3.2.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2015-04-04 + 3.2.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2015-02-27 + 3.1.3 + Version bump. + Stefan Gronewold(groni) + groni@pisilinux.org + + + 2014-12-17 + 3.0.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-08-23 + 3.0.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 2.8.12.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 2.8.12.2 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-12-11 + 2.8.12.1 + Fix finding freetype issue. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-11-24 + 2.8.12.1 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-23 + 2.8.12 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-08-28 + 2.8.11.2 + Clean cmake. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-01 + 2.8.10.2 + Fix deps. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-17 + 2.8.10.2 + Version bump + Ertan Güven + ertan@pisilinux.org + - 2010-10-11 - 2.20 + 2012-12-01 + 2.8.10 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + pkgconfig + http://www.freedesktop.org/software/pkgconfig/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.devel + Package Config system that manages compile/link flags for libraries + Kütüphaneler için derleme bayraklarını yöneten bir paket yapılandırma sistemi + Sistema de configuración de paquetes que soporta banderas de compilación/link para librerías + Paquet de configuration système qui gère les fanions (flags) de compilation et chaînage (link) pour les librairies. Il aide à insérer les options adéquates dans la ligne de commande d'appel au compilateur. + Package Config system that manages compile/link flags for libraries. It helps you insert the correct compiler options on the command line. + Kütüphaneler için derleme bayraklarını yöneten, bir paket yapılandırma sistemi. Komut satırından, doğru derleme seçenekleri sunma olanağı sağlar + Sistema de configuración de paquetes que soporta banderas de compilación/link para librerías. Facilita la inserción de las opciones correctos de compilador en línea de comando + http://pkgconfig.freedesktop.org/releases/pkg-config-0.28.tar.gz + + gnuconfig + + system/devel/pkgconfig/pspec.xml + + + pkgconfig + + glib2 + + + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/aclocal + /usr/share/pkgconfig + /usr/lib/pkgconfig + + + + + 2014-05-11 + 0.28 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-31 + 0.28 + Clean pkgconfig. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-01 + 0.28 + Fix deps. + PisiLinux Community + admins@pisilinux.org + + + 2013-02-18 + 0.28 + Fixed + PisiLinux Community + admins@pisilinux.org + + + 2012-09-15 + 0.27.1 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + libsigsegv + http://libsigsegv.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.devel + Une librairie pour gérer les erreurs de pagination en mode utilisateur. + A library for handling page faults in user mode + Oluşan bellek hatalarının kullanıcı kipinde işlenmesini sağlayan bir kitaplık + This is a library for handling page faults in user mode. A page fault occurs when a program tries to access to a region of memory that is currently not available. + libsigsegv, oluşan bellek hatalarının kullanıcı kipinde işlenmesini sağlayan bir kitaplıktır. + mirrors://gnu/libsigsegv/libsigsegv-2.10.tar.gz + system/devel/libsigsegv/pspec.xml + + + libsigsegv + + /usr/lib + /usr/share/doc + + + + libsigsegv-devel + Development files for libsigsegv + libsigsegv için geliştirme dosyaları + + libsigsegv + + + /usr/include + + + + + 2014-05-11 + 2.10 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-15 + 2.10 + Release bump + Burak Ertürk + burakerturk@pisilinux.org + + + 2013-10-22 + 2.10 + Rebuild. + Pisi Linux Admins + admins@pisilinux.org + + + 2011-12-09 + 2.10 First release Pisi Linux Admins admins@pisilinux.org @@ -13178,29 +15647,2915 @@ - disktype - http://disktype.sourceforge.net/ + gcc + http://gcc.gnu.org + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv3+ + LGPLv3+ + app:console + library + system.devel + The GNU Compiler Collection, includes C, C++, Objective-C and Fortran compilers + C/C++ ve Fortran derleyicisi + La collection de compilateurs GNU inclus des façades pour le C, C++, Objective-C, Fortran, hava et Ada ainsi que des librairies pour ces langages (libstdc++, libgcj...) + The GNU Compiler Collection includes front ends for C, C++, Objective-C, Fortran, as well as libraries for these languages + C, C++, Objective-C, Fortran programlama dilleri ile bu dillere ait kütüphaneleri içeren, GNU derleyici paketi + ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.9.2/gcc-4.9.2.tar.bz2 + + binutils + bison + gettext + ncurses + zlib + gnuconfig + patch + sed + texinfo + gmp + mpfr + libmpc + ppl + cloog + isl + elfutils + + + pisilinux/64.patch + gcc-4.9-isl-0.13-hack.patch + pisilinux/gcc-4.8-filename-output.patch + pisilinux/gcc_47_based-record_gcc_options.patch + + system/devel/gcc/pspec.xml + + + libquadmath + The GNU Fortran Compiler Quadmath Runtime Library + library + system.base + + /usr/lib/libquadmath.so* + /usr/lib/libquadmath.spec* + /usr/lib32/libquadmath.so* + /usr/lib32/libquadmath.spec* + /usr/share/info/libquadmath.info + + + + libgcc + Contains a shared library of support routines used by GCC's runtime, and thus by every program on the system + library + system.base + + /etc + /usr/lib/libstdc++.so* + /usr/lib/libgcc_s.so* + /usr/lib32/libstdc++.so* + /usr/lib32/libgcc_s.so* + /usr/share/gcc-* + /usr/share/gdb + + + + libgomp + Contains GCC shared support library which is needed for OpenMP 2.5 support + library + + /usr/lib/libgomp.so* + /usr/lib/libgomp.spec* + /usr/lib32/libgomp.so* + /usr/lib32/libgomp.spec* + /usr/share/info/libgomp.info + + + + libgfortran + Contains GCC shared support library for gfortran + library + + libquadmath + + + /usr/lib/libgfortran.so* + /usr/lib32/libgfortran.so* + + + + libobjc + Contains GCC shared support library for objc + library + + /usr/lib/libobjc.so* + /usr/lib32/libobjc.so* + + + + gcc-l10n + Contains available GCC localization files, includes also turkish translations + system.locale + + gcc + + + /usr/share/locale + + + + gcc + + gmp + isl + mpfr + cloog + libmpc + + + /lib + /usr/bin + /usr/lib + /usr/lib32 + /usr/libexec + /usr/include + /usr/share/man + /usr/share/info + + + gfilt + gSTLFilt.pl + + + + + 2014-11-28 + 4.9.2 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-09-12 + 4.9.1 + Rebuild for new glibc. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-09-06 + 4.9.1 + Version bump, cleanup. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 4.9.0 + Rebuild, add patch. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-04-28 + 4.9.0 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-04-01 + 4.8.2 + Rebuild for dependency changes. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-11-11 + 4.8.2 + backport ICE fix + http://gcc.gnu.org/bugzilla//show_bug.cgi?id=56710 - commit 3d1f8279 + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57653 + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-10-22 + 4.8.2 + Cleanup, version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-14 + 4.8.1 + Rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-07-23 + 4.8.1 + Version bump, cleanup patches. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-10-14 + 4.7.2 + Cleanup package, add some patches. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-10-14 + 4.7.2 + First release + Erdem Artan + admins@pisilinux.org + + + + + + perl-XML-Parser + http://search.cpan.org/dist/XML-Parser/ + + PisiLinux Community + admins@pisilinux.org + + Artistic + library + system.devel + A Perl extension interface to James Clark's XML parser, expat + James Clark'ın XML ayırıştırıcısına bir Perl uzantısı arayüzü + Una extensión Perl al parseador XML de James Clark, expat + This module provides an interface to James Clark's XML parser, expat. As in expat, a single instance of the parser can only parse one document. Calls to parsestring after the first for a given instance will die. + Bu modül James Clark'ın XML ayrıştırıcısı expat için bir arayüz sağlar. Expat'ta olduğu gibi ayrıştırıcıdan türetilen her nesne sadece bir dosyayı ayrıştırabilir. + Este módulo facilita una interfaz al parser XML de James Clark, expat. Como en expat, una sola instancia del parser puede analizar solamente un documento. Llamadas a parsestring después del primero de una instancia determinada morirán. + mirrors://cpan/authors/id/T/TO/TODDR/XML-Parser-2.41.tar.gz + + expat-devel + perl + + system/devel/perl-XML-Parser/pspec.xml + + + perl-XML-Parser + + expat + perl + + + /usr/share/doc + /usr/lib + /usr/share/man + + + + + 2014-09-12 + 2.41 + Release bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 2.41 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-28 + 2.41 + New release. + Serdar Soytetir + kaptan@pisilinux.org + + + 2011-12-09 + 2.41 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + python-setuptools + http://pypi.python.org/pypi/setuptools + + PisiLinux Community + admins@pisilinux.org + + PSF-2.2 + library + system.devel + Python setuptools + Python kurulum araçları + python-setuptools is a collection of enhancements to the Python distutils that allow you to more easily build and distribute Python packages, especially ones that have dependencies on other packages. + python-setuptools, Python distutils'e yapılan, özellikle başka paketlere bağımlılığı olan Python paketlerini daha kolay oluşturmaya ve dağıtmaya yarayan iyileştirmeler koleksiyonudur. + http://pypi.python.org/packages/source/d/distribute/distribute-0.6.49.tar.gz + system/devel/python-setuptools/pspec.xml + + + python-setuptools + + /usr/bin + /usr/lib/python* + /usr/share/doc + + + + + 2014-05-11 + 0.6.49 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-24 + 0.6.49 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-17 + 0.6.35 + Version bump + Ertan Güven + ertan@pisilinux.org + + + 2012-08-19 + 0.6.28 + First release + Ramazan Utku + admins@pisilinux.org + + + + + + gobject-introspection + http://live.gnome.org/GObjectIntrospection + + Pisi Linux Admins + admins@pisilinux.org + + LGPLv2+ + GPLv2+ + library + app:console + system.devel + Introspection system for GObject-based libraries + gobject-introspection can scan C header and source files in order to generate introspection typelib files. It also provides an API to examine typelib files, useful for creating language bindings among other things. + mirrors://gnome/gobject-introspection/1.44/gobject-introspection-1.44.0.tar.xz + + cairo-devel + python-devel + python-mako + glib2-devel + + system/devel/gobject-introspection/pspec.xml + + + gobject-introspection + + libffi + glib2 + + + /usr/lib/lib*.so* + /usr/lib/girepository-1.0/*.typelib + /usr/share/locale + /usr/share/doc + + + + gobject-introspection-devel + Development files for gobject-introspection + + gobject-introspection + + + /usr/include + /usr/lib/gobject-introspection + /usr/bin/g-ir-* + /usr/lib/pkgconfig + /usr/share/gir-1.0 + /usr/share/aclocal + /usr/share/gobject-introspection-1.0 + /usr/share/man + + + + + 2015-04-06 + 1.44.0 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + + + 2014-05-11 + 1.40.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-14 + 1.40.0 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-04-06 + 1.38.0 + Rebuild + Varol Maksutoğlu + waroi@pisilinux.org + + + 2014-02-01 + 1.38.0 + Rebuild Unused + Varol Maksutoğlu + waroi@pisilinux.org + + + 2013-10.12 + 1.38.0 + V.Bump + PisiLinux Community + admins@pisilinux.org + + + 2013-07-24 + 1.37.4 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-04-07 + 1.36.0 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-02-24 + 1.35.8 + V.Bump. + PisiLinux Community + admins@pisilinux.org + + + 2013-02-04 + 1.35.4 + New version bump to 1.35.4. + Idris Kalp + admins@pisilinux.org + + + 2012-12-31 + 1.34.2 + First release + Idris Kalp + yaralikurt15@hotmail.com + + + + + + glpk + http://www.gnu.org/software/glpk/glpk.html + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv2 + library + system.devel + GNU Linear Programming Kit + GNU Doğrusal Programlama Kiti + Le paquet GLPK (GNU Linear Programming Kit - Kit de Programmation Linéaire) a pour objectif de résoudre le problème de programmation linéaire (LP) de grande envergure, la programmation d'entiers mixés (MIP), et autres problèmes de la sorte. Il s'agit d'un ensemble de routines écrites en C ANSI et organisées de manière à former une librairie que l'on peut appeler. + The GLPK (GNU Linear Programming Kit) package is intended for solving large-scale linear programming (LP), mixed integer programming (MIP), and other related problems. It is a set of routines written in ANSI C and organized in the form of a callable library. + mirrors://gnu/glpk/glpk-4.55.tar.gz + system/devel/glpk/pspec.xml + + + glpk + + /usr/bin + /usr/lib + /usr/share/doc + + + + glpk-devel + Development files for glpk + glpk için geliştirme dosyaları + + glpk + + + /usr/include + + + + + 2014-09-06 + 4.55 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 4.54 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-02-27 + 4.52 + Rebuild Unused + Varol Maksutoğlu + waroi@pisilinux.org + + + 2013-08-28 + 4.52 + Version bump, clean glpk. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-18 + 4.48 + v.bump + PisiLinux Community + admins@pisilinux.org + + + 2012-08-16 + 4.47 + First release + Ramazan Utku + admins@pisilinux.org + + + + + + binutils + http://www.gnu.org/software/binutils/ + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv2 + app:console + system.devel + Assembler and linker tools + Makine dili derleme ve bağlama araçları + Contient des commandes telles que as, ld, nm, objdump, ar, ranlib pour compiler du code assembleur en langage machine ainsi que pour chaîner (link) et manipuler les fichiers binaires objets. + Contains commands like as, ld, nm, objdump, ar, ranlib for compiling assembly code to the machine language, and for linking and manipulating the binary object files. + Assembly kodlarını makine diline derlemek, oluşan obje dosyalarını bağlamak ve ikili dosyalar üzerinde işlemler yapmak için kullanılan as, ld, nm, objdump, ar, ranlib gibi komutları içermektedir. + http://ftp.gnu.org/gnu/binutils/binutils-2.25.tar.bz2 + + glibc-32bit + + + binutils-2.25-roundup.patch + + system/devel/binutils/pspec.xml + + + binutils + + zlib + + + /usr/bin + /usr/lib + /usr/include + /usr/share/info + /usr/share/man + + + + + 2015-03-09 + 2.25 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-11-28 + 2.24 + Fix CVE issues. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-09-12 + 2.24 + Rebuild for new glibc. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-09-06 + 2.24 + Rebuild for new gcc, add pie and lto testsuite patch. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-14 + 2.24 + Add upstream patch. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-30 + 2.24 + Rebuild for new gcc. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-03-29 + 2.24 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-27 + 2.23.2 + Back to 2.23.2, cleanup. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-23 + 2.23.52.0.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-16 + 2.23.51.0.9 + New release. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-01-16 + 2.23.51.0.8 + New toolchain up. + Erdinç Gültekin + admins@pisilinux.org + + + + + + guile + http://www.gnu.org/software/guile/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2+ + LGPLv2+ + app:console + library + system.devel + Interpréteur et librairie GNU Scheme. + GNU Scheme interpreter and library + GNU Scheme yorumlayıcısı ve kitaplığı + Język GNU Extension language. + GUILE (GNU's Ubiquitous Intelligent Language for Extension) is a library implementation of the Scheme programming language, written in C. GUILE provides a machine-independent execution platform that can be linked in as a library during the building of extensible programs. + mirrors://gnu/guile/guile-2.0.11.tar.xz + + gc-devel + gettext-devel + gmp-devel + + system/devel/guile/pspec.xml + + + guile + + gc + gmp + libffi + libtool-ltdl + libunistring + readline + + + /etc + /usr/share/doc + /usr/share/man + /usr/bin + /usr/share/info + /usr/lib/lib* + /usr/share/guile + /usr/share/emacs + /usr/share/gdb/auto-load + /usr/lib/guile/2.0 + + + + guile-devel + Development files for guile + guile için geliştirme dosyaları + Pliki nagłówkowe guile. + + guile + + + /usr/include + /usr/lib/pkgconfig + /usr/share/aclocal + /usr/bin/guile-snarf + /usr/bin/guile-config + + + + + 2014-11-30 + 2.0.11 + Rebuild + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-24 + 2.0.11 + Rebuild for gcc. + PisiLinux Community + admins@pisilinux.org + + + 2014-05-11 + 2.0.9 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-25 + 2.0.9 + Rebuild Unused + Varol Maksutoğlu + waroi@pisilinux.org + + + 2013-08-27 + 2.0.9 + Clean guile. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-22 + 2.09 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-18 + 2.0.7 + v.bump + PisiLinux Community + admins@pisilinux.org + + + 2012-10-03 + 2.0.6 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + automake + http://www.gnu.org/software/automake/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2+ + app:console + system.devel + A tool for automatically generating Makefile.in files compliant with the GNU Coding Standards + Makefile.am yapılandırma dosyalarından Makefile.in dosyası üreten program + Automake est un outil de génération automatique de Makefiles compatibles avec les standards de Codage GNU. Vous aurez également besoin d'installer le paquet GNU AutoConf + Automake is a tool for automatically generating Makefile.in files compliant with the GNU Coding Standards. + Makefile.am yapılandırma dosyalarından GNU kodlama standartlarına uygun Makefile.in dosyası üreten program. Bununla birlikte Autoconf paketini de yüklemelisiniz. + mirrors://gnu/automake/automake-1.15.tar.xz + + perl + autoconf + gnuconfig + patch + + system/devel/automake/pspec.xml + + + automake + + perl + autoconf + + + /usr/bin + /usr/share/automake-* + /usr/share/aclocal-* + /usr/share/aclocal + /usr/share/info + /usr/share/doc + /usr/share/man + + + + + 2015-01-28 + 1.15 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + + + 2014-11-30 + 1.14 + Rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 1.14.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-30 + 1.14.1 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-27 + 1.14 + Clean automake. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-22 + 1.14 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-16 + 1.13.1 + Version bump + Ertan Güven + ertan@pisilinux.org + + + 2012-08-13 + 1.12.2 + First release + Ramazan Utku + admins@pisilinux.org + + + + + + btyacc + http://www.siber.com/btyacc + + PisiLinux Community + admins@pisilinux.org + + freedist + app:console + system.devel + Backtracking YACC - modified from Berkeley YACC + This is original Berkeley Yacc modified to better fit production environment (and to have less bugs, too). + http://www.siber.com/btyacc/btyacc-3-0.tar.gz + + btyacc-3.0-includes.patch + btyacc-3.0-makefile.patch + + system/devel/btyacc/pspec.xml + + + btyacc + + /usr/bin + /usr/share/man + /usr/share/doc + + + + + 2014-05-11 + 3.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-11-13 + 3.0 + Release bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-10-15 + 3.0 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + libseccomp + http://sourceforge.net/projects/libseccomp/ + + Aydın Demirel + aydin.demirel@pisilinux.org + + LGPLv2.1 + app:library + system.devel + Enhanced seccomp library + Gelişmiş seccomp kütüphanesi + High level interface to the Linux Kernel's seccomp filter. + Linux Kernel'in seccomp süzgecine yüksek seviyeli arayüz + http://downloads.sourceforge.net/project/libseccomp/libseccomp-2.1.1/libseccomp-2.1.1.tar.gz + + glibc + + system/devel/libseccomp/pspec.xml + + + libseccomp + + /usr/bin + /usr/share/man + /usr/lib/* + + + + libseccomp-devel + + /usr/include + + + + + 2014-06-27 + 2.1.1 + First release + Aydın Demirel + aydin.demirel@pisilinux.org + + + + + + libtool + http://www.gnu.org/software/libtool/libtool.html + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv2 + library + system.devel + A shared library tool for developers + Program geliştiriciler için ortak kütüphane aracı + Libtool est une librairie utilitaire partagée pour développeurs. + Libtool is a shared library tool for developers. + Libtool, program geliştiriciler için bir paylaşımlı kütüphane aracıdır. + mirrors://gnu/libtool/libtool-2.4.2.tar.xz + + gnuconfig + autoconf + automake + + system/devel/libtool/pspec.xml + + + libtool-ltdl + system.base + + /usr/lib + + + + libtool + + gnuconfig + + + /usr/bin + /lib + /usr/share/doc + /usr/share/info + /usr/share/man + /usr/include + /usr/share/libtool + /usr/share/aclocal + + + + libtool-ltdl-32bit + 32-bit shared libraries for libtool-ltdl + libtool için 32-bit paylaşımlı kitaplıklar + emul32 + emul32 + + libtool-ltdl + + + /usr/lib32 + + + + + 2014-11-28 + 2.4.2 + Rebuild for new gcc. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-09-12 + 2.4.2 + Rebuild for new gcc. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 2.4.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-27 + 2.4.2 + Clean libtool. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-07-14 + 2.4.2 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + autoconf + http://www.gnu.org/software/autoconf/autoconf.html + + PisiLinux Community + admins@pisilinux.org + + GPLv3 + app:console + system.devel + Used to create autoconfiguration files + Used to create autoconfiguration files, Autoconf is an extensible package of m4 macros that produce shell scripts to automatically configure software source code packages. + mirrors://gnu/autoconf/autoconf-2.69.tar.xz + + texinfo + m4 + perl + + system/devel/autoconf/pspec.xml + + + autoconf + + texinfo + m4 + + + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/autoconf + + + + + 2014-11-30 + 2.69 + Rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 2.69 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-27 + 2.69 + Clean autoconf. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-07-14 + 2.69 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + icecream + http://en.opensuse.org/Icecream + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + service + system.devel + Distributed C(++) compiling tool + Dağıtık C(++) derleme aracı + Herramienta de compilación C(++) distribuida + Icecream est un programme de compilation de code C/C++ distribuée sur plusieurs machines basé sur le code et les idées directrices de distcc. + Icecream is a program for distributed compiling of C/C++ code across several machines based on ideas and code by distcc. + Icecream; C/C++ kaynak kodunun, birden fazla makinede dağıtık olarak derlenmesi fikrine dayanan, "distcc" kodu temelinde yazılmış bir uygulamadır. + Icecream es un programa para compilación de código C/C++ distribuida en varios servidores, basado en ideas y código de distcc. + ftp://ftp.suse.com/pub/projects/icecream/icecc-1.0.1.tar.bz2 + + librsync-devel + + system/devel/icecream/pspec.xml + + + icecream + + librsync + libgcc + libcap-ng + + + /opt/icecream/sbin/iceccd + /opt/icecream/bin/icecc + /usr/libexec/icecc + /opt/icecream/lib + /opt/icecream/bin + /opt/icecream/include/ + /usr/share/doc + /usr/share/icecc + /usr/share/man + /lib/systemd/system/icecream-daemon.service + + + System.Service + + + icecream-daemon.service + + + + icecream-scheduler + Icecream scheduler which should only run on the master icecream node + + icecream + libgcc + + + /opt/icecream/sbin/icecc-scheduler + /lib/systemd/system/icecream-scheduler.service + + + System.Service + + + icecream-scheduler.service + + + + + 2014-05-11 + 1.0.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-22 + 1.0.1 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-24 + 1.0.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-18 + 0.9.98.3 + v.bump + PisiLinux Community + admins@pisilinux.org + + + 2012-10-09 + 0.9.7 + First release + Erdem Artan + admins@pisilinux.org + + + + + + libmpc + http://www.multiprecision.org/ + + Serdar Soytetir + kaptan@pisilinux.org + + LGPLv2.1 + library + system.devel + High precision and correct rounding library + Yüksek hassasiyet ve yuvarlama kitaplığı + libmpc is a library for arithmetic of complex numbers with arbitrarily high precision and correct rounding. + libmpc aritmetik kompleks sayılarla yüksek hassasiyette ve doğru yuvarlama ile işlem yapılmasını sağlayan bir kitaplıktır. + ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz + + gmp-devel + mpfr-devel + + system/devel/libmpc/pspec.xml + + + libmpc + + gmp + mpfr + + + /usr/lib + /usr/share/doc/libmpc + /usr/share/info + + + + libmpc-devel + Development files for libmpc + libmpc için geliştirme dosyaları + + libmpc + + + /usr/include + + + + + 2015-03-08 + 1.0.3 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-09-06 + 1.0.2 + Rebuild with new mpfr for new gcc. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 1.0.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-30 + 1.0.2 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-27 + 1.0.1 + Clean libpmc. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-09-09 + 1.0.1 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + libarchive + http://code.google.com/p/libarchive/ + + PisiLinux Community + admins@pisilinux.org + + BSD + library + system.devel + Library for reading and writing streaming archives + Birçok farklı akış arşiv formatını yaratan ve okuyan programlama kitaplığı + libarchive includes a library and command-line tools for reading and writing tar, cpio, zip, ISO, and other archive formats. + libarchive, tar, cpio, zip, ISO ve diğer arşiv biçimlerini okumak ve yazmak için bir kitaplık ve komut satırı araçları içerir. + http://www.libarchive.org/downloads/libarchive-3.1.2.tar.gz + + acl-devel + attr-devel + bzip2 + libxml2-devel + openssl-devel + xz-devel + lzo-devel + zlib-devel + + system/devel/libarchive/pspec.xml + + + libarchive + + lzo + nettle + xz + acl + zlib + attr + bzip2 + libxml2 + + + /usr/lib + /usr/share/man + /usr/share/doc/libarchive + + + + libarchive-devel + Development files for libarchive + libarchive için geliştirme dosyaları + + libarchive + + + /usr/include + /usr/lib/pkgconfig + /usr/share/man/man3 + + + + + 2014-05-11 + 3.1.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-28 + 3.1.2 + unused fix. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-08-28 + 3.1.2 + Clean libarchive. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-01 + 3.1.2 + Fix deps. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-18 + 3.1.2 + Version bump + Ertan Güven + ertan@pisilinux.org + + + 2012-08-19 + 3.0.4 + First release + Ramazan Utku + admins@pisilinux.org + + + + + + gmp + http://gmplib.org/ + + Serdar Soytetir + kaptan@pisilinux.org + + LGPLv3+ + library + system.devel + Arbitrary precision arithmetic library + İstenilen duyarlıkta çalışabilen aritmetik işlem kitaplığı + GMP est une librairie libre pour l'arithmétique à précision arbitraire, opérant sur : les entiers signés, les nombres rationnels et les nombres à virgule flottante. Il n'y a aucune limite pratique sur la précision des calculs exceptée celle impliquée par la mémoire présente sur la machine exécutant GMP. GMP est dotée d'un large panel de fonctions, dotées d'interfaces régulières. + GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating point numbers. There is no practical limit to the precision except the ones implied by the available memory in the machine GMP runs on. GMP has a rich set of functions, and the functions have a regular interface. + GMP işaretli tamsayılar, rasyonel ve ondalık sayılar üzerinde istenilen kadar duyarlı aritmetik işlemler yapan bir kitaplıktır. Yüklü olduğu makinenin hafıza sınırı dışında herhangi bir duyarlılık limiti yoktur. Zengin fonksiyonları ve düzenli bir arabirimi vardır. + GMP es una librería libre para aritmética con precisión arbitraria, operando con signed integers, números racionales, y punto flotante. Practicamente no hay límite de precisión excepto los de la memoria disponible en el equipo donde se está ejecutando GMP. GMP tiene un amplio conjunto de funciones y las funciones tienen una interfaz regular. + mirrors://gnu/gmp/gmp-6.0.0a.tar.xz + system/devel/gmp/pspec.xml + + + gmp + + libgcc + + + /usr/lib + /usr/share/doc + /usr/share/info + + + + gmp-devel + Development files for gmp + gmp için geliştirme dosyaları + + gmp + + + /usr/include + /usr/lib/*.a + + + + gmp-32bit + 32-bit shared libraries for gmp + emul32 + emul32 + + glibc-32bit + + + gmp + + + /usr/lib32 + + + + + 2014-09-06 + 6.0.0 + Rebuild with new options, fix version number. + Clean up actions.py, remove unneeded lines, we have auto-emul32 :) + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 6.0.0a + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-01 + 6.0.0a + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-22 + 5.1.3 + Minor version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-27 + 5.1.2 + Clean gmp. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-23 + 5.1.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-16 + 5.1.1 + New release + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-09-30 + 5.0.5 + First release + Erdem Artan + admins@pisilinux.org + + + + + + dietlibc + http://www.fefe.de/dietlibc + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.devel + A libc optimized for small size + Düşük boyut için optimize edilmiş C kütüphanesi + dietlibc is a libc that is optimized for small size. It can be used to create small statically linked binaries for Linux on various architectures. + dietlibc, düşük boyutlu olması için optimize edilmiş bir C kütüphanesidir. Farklı mimarilerde statik bağlanmış ve düşük boyutlu ikili dosyalar oluşturmak için kullanılabilir. + http://pkgs.fedoraproject.org/repo/pkgs/dietlibc/dietlibc-0.33.20120825.tar.xz/016865b8c40d40a57b2ddb5862f2e338/dietlibc-0.33.20120825.tar.xz + http://pkgs.fedoraproject.org/repo/pkgs/dietlibc/dietlibc-github-c3f1cf67fcc186bb859e64a085bf98aaa6182a82.patch.gz/734e14b59b7f017ae5843ee9b9b6d34e/dietlibc-github-c3f1cf67fcc186bb859e64a085bf98aaa6182a82.patch.gz + + dietlibc-0.33-biarch.patch + + system/devel/dietlibc/pspec.xml + + + dietlibc + + /usr/bin + /usr/lib/dietlibc/include + /usr/lib/dietlibc/lib-i386 + /usr/lib/dietlibc/lib-x86_64 + /usr/share/man + /usr/share/doc + + + + + 2014-05-11 + 0.33.20120825 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-11-03 + 0.33.20120825 + Version bump + Marcin Bojara + marcin@pisilinux.org + + + 2010-10-11 + 0.32 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + util-macros + http://www.x.org/ + + PisiLinux Community + admins@pisilinux.org + + MIT + library + system.devel + Macros X.Org utilisées pour compiler X.Org + X.Org X11 Autotools macros + X.Org X11 Autotools makroları + X.Org Makros zum Kompilieren von X.Org + X.Org X11 autotools macros are required for building the various packages that comprise the X Window System. + X.Org X11 Autotools makroları, X pencere sistemini oluşturan çeşitli paketleri derlemek için gereklidir. + http://xorg.freedesktop.org/releases/individual/util/util-macros-1.19.0.tar.bz2 + + doc.patch + + system/devel/util-macros/pspec.xml + + + util-macros + + /usr/share/aclocal + /usr/share/pkgconfig + /usr/share/doc + + + + + 2014-07-11 + 1.19.0 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 1.18.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-07 + 1.18.0 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-10-08 + 1.17.1 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-09-12 + 1.17.1 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2012-08-19 + 1.17 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + elfutils + http://www.redhat.com/ + + PisiLinux Community + admins@pisilinux.org + + OpenSoftware + app:console + library + system.devel + Libraries/utilities to handle ELF objects + Derlenmiş objeleri işlemek için gereken aletler koleksiyonu + elfutils contains libraries and utilities to handle ELF objects and is a replacement for libelf. + elfutils derlenmiş objeleri işlemek için gereken çeşitli araçlar içerir. + https://fedorahosted.org/releases/e/l/elfutils/0.161/elfutils-0.161.tar.bz2 + + bzip2 + xz-devel + zlib-devel + + system/devel/elfutils/pspec.xml + + + elfutils + + xz + zlib + bzip2 + libgcc + + + /usr/bin + /usr/lib + /usr/share/doc + /usr/include + + + + + 2015-04-09 + 0.161 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + + + 2014-11-23 + 0.160 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 0.158 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-29 + 0.158 + Add upstream patch. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-22 + 0.158 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-08-27 + 0.156 + Clean elfutils. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-01 + 0.156 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-02-16 + 0.155 + New release + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-07-30 + 0.154 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + xorg-util + http://www.x.org/ + + PisiLinux Community + admins@pisilinux.org + + MIT + app:console + system.devel + Utilitaires de X.Org + X.Org utilities + X.Org araçları + X.Org Werkzeuge + xorg-util contains some Xorg X11 command-line utilities, but more importantly, X11 configuration and rule files. + mirrors://xorg/individual/util/gccmakedep-1.0.3.tar.bz2 + mirrors://xorg/individual/util/imake-1.0.7.tar.bz2 + mirrors://xorg/individual/util/lndir-1.0.3.tar.bz2 + mirrors://xorg/individual/util/makedepend-1.0.5.tar.bz2 + mirrors://xorg/individual/util/xorg-cf-files-1.0.5.tar.bz2 + + host-defaults.patch + + system/devel/xorg-util/pspec.xml + + + xorg-util + + /usr/bin + /usr/share/X11/config + /usr/share/man + + + + + 2014-08-31 + 7.6 + Update. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 7.6 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-07 + 7.6 + Release bump + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-08-19 + 7.6 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + xcb-proto + http://xcb.freedesktop.org/ + + PisiLinux Community + admins@pisilinux.org + + MIT + data + system.devel + XCB protocol descriptions + XCB protokol tanımlamaları + XCB is a project to enable efficient language bindings to the X11 protocol. This package contains the protocol descriptions themselves. Language bindings use these protocol descriptions to generate code for marshalling the protocol. + http://xcb.freedesktop.org/dist/xcb-proto-1.11.tar.bz2 + + libxml2 + + system/devel/xcb-proto/pspec.xml + + + xcb-proto + + /usr/lib/pkgconfig + /usr/lib/python* + /usr/share/doc + /usr/share/xcb + + + + + 2014-09-02 + 1.11 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 1.10 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-03 + 1.10 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-10-22 + 1.8 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-11-18 + 1.8 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-11-18 + 1.8 + First release + Erdinç Gültekin + admins@pisilinux.org + + + + + + ccache + http://ccache.samba.org/ + + PisiLinux Community + admins@pisilinux.org + + GPLv3+ + app:console + system.devel + Fast C/C++ compiler cache + Hızlı C/C++ derleme önbelleği + Cache veloz de compilador + Cache de Compilation rapide + ccache is a compiler cache. It speeds up recompilation of C/C++ code by caching previous compiles and detecting when the same compile is being done. + ccache bir derleme önbelleğidir. Önceki derlemeleri önbelleğinde saklayıp, aynı derlemelerde bu önbelleği kullanarak C/C++ kodlarının yeniden derlenmelerini hızlandırır. + http://samba.org/ftp/ccache/ccache-3.2.tar.xz + + zlib-devel + + system/devel/ccache/pspec.xml + + + ccache + + gcc + zlib + + + /usr/bin + /usr/lib/ccache/bin + /usr/share/doc + /usr/share/man + + + + + 2014-11-23 + 3.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 3.1.9 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-22 + 3.1.9 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-01 + 3.1.9 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-16 + 3.1.9 + Version bump + Ertan Güven + ertan@pisilinux.org + + + 2012-12-15 + 3.1.8 + First release + canatan + admins@pisilinux.org + + + + + + chrpath + http://freshmeat.net/projects/chrpath/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.devel + Change the dynamic library load path (rpath) of binaries + Dinamik kitaplık yükleme yolunu (rpath) değiştirme aracı + chrpath allows you to modify the dynamic library load path (rpath and runpath) of compiled programs and libraries. + chrpath ile derlenmiş kitaplıkların ve programların dinamik kitaplık yükleme yolunu (rpath ve runpath) değiştirebilirsiniz. + http://source.pisilinux.org/1.0/chrpath-0.16.tar.gz + + docdir.patch + + system/devel/chrpath/pspec.xml + + + chrpath + + /usr/bin + /usr/share/doc + /usr/share/man + + + + + 2014-05-11 + 0.16 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 0.16 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-28 + 0.13 + Clean chrpath + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-07-14 + 0.13 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + yasm + http://www.tortall.net/projects/yasm/ + + PisiLinux Community + admins@pisilinux.org + + BSD + GPLv2 + LGPLv2 + Artistic + app:console + system.devel + Assembler that supports many syntaxes and architectures + Bir çok sentaks ve mimari destekleyen Assembler + A complete rewrite of the NASM assembler under the "new" BSD License. Yasm currently supports the x86 and AMD64 instruction sets, accepts NASM and GAS assembler syntaxes, outputs binary, ELF32, ELF64, 32 and 64-bit Mach-O, RDOFF2, COFF, Win32, and Win64 object formats and generates source debugging information in STABS, DWARF 2, and CodeView? 8 formats. + NASM Assembler programının yeni BSD lisansı ile baştan yazılmış bir Assembler. En önemli özellikleri x86 ve AMD64 komutsetlerini, NASM ve GAS sentaksını desteklemesidir. İkilik, ELF32, ELF64, 32 ve 64-bit Mach-O, RDOFF2, COFF, Win32 ve Win64 obje formatlarında çıktı üretebilir, hata ayıklamak için STABS, DWARF 2 ve CodeView? 8 formatlarını desteklemektedir. + http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz + system/devel/yasm/pspec.xml + + + yasm + + /usr/bin + /usr/lib + /usr/share/doc + /usr/share/man + + + + yasm-devel + Development files for yasm + yasm için geliştirme dosyaları + + yasm + + + /usr/include + /usr/lib/libyasm.a + + + + + 2014-05-11 + 1.2.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-22 + 1.2.0 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2011-12-09 + 1.2.0 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + quilt + http://savannah.nongnu.org/projects/quilt + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.devel + Scripts for working with series of patches + Yama serileriyle çalışmak için betik araçları + quilt allow one to manage a series of patches by keeping track of the changes each patch makes. + quilt, yamaları yığın yapısına göre düzenleyen, kolayca yama uygulamayı ve kaldırmayı sağlayan bir yama yönetim uygulamasıdır. + http://mirror.rackdc.com/savannah/quilt/quilt-0.64.tar.gz + + gawk + gettext + util-linux + + system/devel/quilt/pspec.xml + + + quilt + + diffstat + + + /etc + /usr/bin + /usr/lib + /usr/share/locale + /usr/share/man + /usr/share/doc + /usr/share/quilt + + + + + 2015-03-01 + 0.64 + Version bump. + Stefan Gronewold(groni) + groni@pisilinux.org + + + 2014-05-11 + 0.61 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 0.61 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-31 + 0.60 + Clean quilt. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-05-30 + 0.60 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + cloog + http://www.cloog.org/ + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv2+ + app:console + library + system.devel + Chunky Loop Generator + cloog is CLooG is a free software and library to generate code for scanning Z-polyhedra. It is used by the GCC Graphite optimization framework. + http://www.bastoul.net/cloog/pages/download/cloog-0.18.1.tar.gz + + gmp-devel + ppl-devel + isl-devel + + + cloog-0.18.1-isl-compat.patch + + system/devel/cloog/pspec.xml + + + cloog + + gmp + isl + + + /usr/bin + /usr/lib + /usr/share/doc/cloog/ + /usr/share/info + + + + cloog-devel + Development files for cloog + + cloog + + + /usr/include + /usr/lib/pkgconfig/cloog.pc + + + + + 2014-09-06 + 0.18.1 + Rebuild for new isl and new toolchain. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 0.18.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 0.18.1 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-27 + 0.18.0 + Clean cloog. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-26 + 0.18.0 + Move pc files to devel pack, rebuild. + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-04-23 + 0.18.0 + Dep fixed + PisiLinux Community + admins@pisilinux.org + + + 2012-02-16 + 0.18.0 + New release + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-06-22 + 0.17.0 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + unifdef + http://www.freebsd.org/cgi/cvsweb.cgi/src/usr.bin/unifdef/ PisiLinux Community admins@pisilinux.org BSD app:console - system.base - Detect the content format of a disk or disk image - Disk veya disk görüntüsünün biçimsel içeriğini saptar - The purpose of disktype is to detect the content format of a disk or disk image. It knows about common file systems, partition tables, and boot codes.The program is written in C and is designed to compile on any modern Unix flavour. - Disktype'ın amacı disk veya disk görüntüsünün içerik yapısını denetlemektir. Yaygın dosya sistemlerini, bölümleme tablolarını ve önyükleme kodlarını bilir. C dilinde yazılmış, herhangi bir modern Unix derleme tadında tasarlanmıştır. - mirrors://sourceforge/disktype/disktype-9.tar.gz - - disktype.patch - vfat.patch - ext4.patch - - system/base/disktype/pspec.xml + system.devel + The unifdef utility selectively processes conditional cpp(1) directives + L'utilitaire unifdef traite sélectivement les directives conditionnelles cpp(1). Il supprime d'un fichier les directives ainsi que le texte additionnel qu'elles indiquent comme à supprimer tout en laissant le reste du fichier intact. + The unifdef utility selectively processes conditional cpp(1) directives. It removes from a file both the directives and any additional text that they specify should be removed, while otherwise leaving the file alone. + http://dotat.at/prog/unifdef/unifdef-2.10.tar.gz + system/devel/unifdef/pspec.xml - disktype + unifdef + + /usr/bin + /usr/share/man + /usr/share/doc/unifdef + + + + + 2014-05-11 + 2.10 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 2.10 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-07-24 + 2.9 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-09-17 + 2.6 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + scons + http://www.scons.org + + PisiLinux Community + admins@pisilinux.org + + MIT + app:console + system.devel + An Open Source software construction tool + Python temelli, esnek, geliştirilebilir inşa aracı + Utilitaire extensible écrit en python. On peut considérer SCons comme un substitut amélioré multi-plateforme de Make intégrant des fonctionnalités similaires à celles d'autoconf/automake et un gestionnaire de cache de compilateur tel ccache. + Think of SCons as an improved, cross-platform substitute for the classic Make utility with integrated functionality similar to autoconf/automake and compiler caches such as ccache. + Python temelli, esnek, geliştirilebilir inşa aracı. SCons, klasik "make" aracına "autconf/automake" özellikleri ve "ccache" gibi derleyici önbelleği eklenmiş, gelişmiş bir araç olarak düşünülebilir. + mirrors://sourceforge/scons/scons-2.3.1.tar.gz + + python + + + scons-1.0.0-qt-handle-missing-moc-files.patch + fix-gnu-link-handling.patch + + system/devel/scons/pspec.xml + + + scons + + python + + + /usr/bin + /usr/lib + /usr/share/man + /usr/share/doc + + + + + 2014-05-11 + 2.3.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 2.3.1 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-22 + 2.3.0 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-24 + 2.3.0 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-17 + 2.2.0 + Version bump + Ertan Güven + ertan@pisilinux.org + + + 2011-12-14 + 2.1.0 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + catbox + http://pisilinux.org + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + system.devel + Python sandboxing module + Python için sandbox modülü + catbox is a Python sandboxing module commonly used by the package management system of PiSi Linux, PiSi. + https://github.com/baris/catbox/archive/catbox-1.6.1.tar.gz + + python-setuptools + python-devel + + system/devel/catbox/pspec.xml + + + catbox + + python + + + /usr/bin + /usr/lib + /usr/share/doc + + + + + 2015-03-19 + 1.6.1 + Fix Buildeps. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 1.6.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-02-08 + 1.6.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-10-22 + 1.6 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-24 + 1.6 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2010-10-11 + 1.2 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + mpfr + http://www.mpfr.org + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv2+ + LGPLv2+ + library + system.devel + Multiple precision floating point library + La librairie MPFR est une librairie C pour les calculs à virgules flottantes à précisions multiples à arrondi exact (également appelé arrondi correct). Elle est basée sur la librairie à précision multiple GMP. + The MPFR library is a C library for multiple-precision floating-point computations with exact rounding (also called correct rounding). It is based on the GMP multiple-precision library. + MPFR es una librería en C para computaciones de punto flotante de múltiple precisión con redondeo exacto (también llamado redondeo correcto). Está basada en la librería de múltiple precisión GMP. + http://ftp.gnu.org/gnu/mpfr/mpfr-3.1.2.tar.xz + + gmp-devel + + + mpfr-3.1.2-p10.patch + + system/devel/mpfr/pspec.xml + + + mpfr + + gmp + + + /usr/lib + /usr/share/info + /usr/share/doc/mpfr + + + + mpfr-devel + Development files for mpfr + mpfr için geliştirme dosyaları + + mpfr + + + /usr/include + /usr/share/doc/mpfr/examples + /usr/share/doc/mpfr/html + + + + + 2014-09-06 + 3.1.2_p10 + Patch version bump to 10. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 3.1.2_p5 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-01 + 3.1.2_p5 + Version bump to patch level 5. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-27 + 3.1.2 + Clean mpfr. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-23 + 3.1.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2012-07-13 + 3.1.1 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + bison + http://www.gnu.org/software/bison/bison.html + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv2 + app:console + system.devel + A yacc-compatible parser generator + Yacc uyumlu yazım ayrıştırma üreteci + Un générateur d'analyseur syntaxique compatible avec yacc. Une fois que vous maîtrisez Bison, vous pouvez l'utiliser pour développer des analyseur léxicaux pour un grand nombres de langages, de ceux qui sont utilisés dans les simples calculatrices de bureau aux complexes langages de programmation. + A yacc-compatible parser generator. Once you are proficient with Bison, you can use it to develop a wide range of language parsers, from those used in simple desk calculators to complex programming languages + Yacc uyumlu yazım ayrıştırma üreteci. Bison'da ustalık kazandığınızda, basit hesap makinalarından, karmaşık programlama dillerine kadar uzanan geniş yazım ayrıştırıcılar geliştirebilirsiniz. + mirrors://gnu/bison/bison-3.0.4.tar.xz + + m4 + gettext + patch + + system/devel/bison/pspec.xml + + + bison + + m4 + gettext + + + /usr/bin + /usr/lib + /usr/share/doc + /usr/share/man + /usr/share/aclocal + /usr/share/info + /usr/share/bison + /usr/share/locale + + + + + 2015-03-01 + 3.0.4 + Version bump. + Stefan Gronewold(groni) + groni@pisilinux.org + + + 2014-09-06 + 3.0.2 + Rebuild, fix pspec.xml. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 3.0.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-24 + 3.0.2 + Version bump + Burak Fazıl Ertürk + burakerturk@pisilinux.org + + + 2013-11-18 + 3.0.1 + Version bump + Richard de Bruin + richdb@pisilinux.org + + + 2013-08-27 + 3.0 + Version bump, clean. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-23 + 2.7.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-16 + 2.7 + Version bump + Ertan Güven + ertangvn@istanbul.com + + + 2012-10-24 + 2.6.4 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + autogen + http://www.gnu.org/software/autogen + + PisiLinux Community + admins@pisilinux.org + + GPLv3 + app:console + system.devel + The automated text and program generation tool + Otomatik metin ve program üretme aracı + Herramienta para simplificar creación y mantenimiento de programas que contienen muchos textos repetitivos + autogen is a tool designed to simplify the creation and maintenance of programs that contain large amounts of repetitious text. + autogen büyük miktarda tekrarlı metin içeren uygulamaların otomatik üretilmesini sağlayan bir araçtır. + ftp://ftp.gnu.org/gnu/autogen/rel5.18.4/autogen-5.18.4.tar.xz + + gc-devel + gmp-devel + guile-devel + libxml2-devel + which + + system/devel/autogen/pspec.xml + + + autogen + + guile + libxml2 + + + /usr/lib + /usr/share/doc + /usr/share/man + /usr/bin + /usr/share/info + /usr/share/autogen + + + + autogen-devel + Development files for autogen + autogen için geliştirme dosyaları + + autogen + + + /usr/include + /usr/share/aclocal + /usr/lib/pkgconfig + /usr/share/man/man3 + /usr/bin/autoopts-config + /usr/share/man/man1/autoopts-config.1 + + + + + 2014-11-23 + 5.18.4 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-24 + 5.18 + Rebuild for gcc. + PisiLinux Community + admins@pisilinux.org + + + 2014-05-11 + 5.18 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-08-27 + 5.18 + Clean autogen. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-22 + 5.18 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-17 + 5.17.1 + New release + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-10-04 + 5.16.2 + First release + PisiLinux Community + admins@pisilinux.org + + + + + + yacc + http://dinosaur.compilertools.net/#yacc + + PisiLinux Community + admins@pisilinux.org + + as-is + app:console + system.devel + Yacc: Yet Another Compiler-Compiler + Yacc: Yet Another Compiler-Compiler + Yacc fourni un outil général de description d'entrée pour un logiciel. L'utilisateur de Yacc spécifie la structure de l'entrée avec le code à invoquer lorsque de tels structures sont reconnues. Yacc transforme ce qui a été spécifié en sous-routine gérant le processus d'entrée. + Yacc provides a general tool for describing the input to a computer program. The Yacc user specifies the structures of his input, together with code to be invoked as each such structure is recognized. Yacc turns such a specification into a subroutine that handles the input process + Yacc, bir uygulamaya girdi açıklamasını yapan bir araçtır. Yacc kullanıcısı, girdinin yapısını ve bu yapının her seferinde tanındığı kodu belirtir. Yacc; bu tür bir belirlemeyi, girdi sürecini işleyen bir alt yordama çevirir. + ftp://metalab.unc.edu/pub/Linux/devel/compiler-tools/yacc-1.9.1.tar.Z + + mkstemp.patch + skeleton.c.diff + yacc-1.9.1-ia64.patch + + system/devel/yacc/pspec.xml + + + yacc /usr/bin /usr/share/doc @@ -13210,21 +18565,1103 @@ 2014-05-11 - 9 + 1.9.1 Release bump. Marcin Bojara marcin@pisilinux.org - 2013-10-29 - 9 - Rebuild + 2014-01-17 + 1.9.1 + Rebuild for 1.0 + Richard de Bruin + richdb@pisilinux.org + + + 2010-10-11 + 1.9.1 + First release + Pisi Linux Admins + admins@pisilinux.org + + + + + + isl + http://www.kotnet.org/~skimo/isl/ + + Serdar Soytetir + kaptan@pisilinux.org + + LGPLv2.1 + library + system.devel + Integer Set Library + isl is a library for manipulating sets and relations of integer points bounded by linear constraints. + http://isl.gforge.inria.fr/isl-0.13.tar.bz2 + + gmp-devel + + system/devel/isl/pspec.xml + + + isl + + gmp + + + /usr/lib + /usr/share/doc + + + + isl-devel + Development files for isl + isl için geliştirme dosyaları + + isl + + + /usr/include + /usr/lib/pkgconfig + + + + + 2015-05-05 + 0.13 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 0.12.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 0.12.2 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-22 + 0.12.1 + New release + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-28 + 0.12 + Move pc files to devel pack, rebuild + PisiLinux Community + admins@pisilinux.org + + + 2013-07-24 + 0.12 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-16 + 0.11.1 + New release + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-09-05 + 0.10 + First release + Erdem Artan + admins@pisilinux.org + + + + + + swig + http://www.swig.org/ + + PisiLinux Community + admins@pisilinux.org + + GPLv3+ + BSD + app:console + system.devel + Connects C/C++/Objective C to some high-level programming languages + Basitleştirilmiş arayüz oluşturucu + Simplified Wrapper and Interface Generator (Générateur d'interface de scripts d'enrobage simplifié), SWIG est un outil de développement qui connecte des programmes écrits en C et C++ avec divers langages de programmation de haut niveau. SWIG est utilisé avec différents type de langages incluant les langages de script habituels tels que Perl, PHP, Python, Tcl, Ruby. + Simplified Wrapper and Interface Generator, SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is used with different types of languages including common scripting languages such as Perl, PHP, Python, Tcl, Ruby and PHP + SWIG, C ve C++ ile yazılmış uygulamaları çeşitli üst düzey programlama dilleri ile bağlayan bir yazılım geliştirme aracıdır. SWIG, genel betik dilleri olan Perl, PHP, Python, Tcl, Ruby gibi farklı diller ile kullanılır. + mirrors://sourceforge/swig/swig-3.0.2.tar.gz + + python + perl + + system/devel/swig/pspec.xml + + + swig + + zlib + libgcc + libpcre + + + /usr/bin + /usr/lib + /usr/share/swig + /usr/share/doc + /usr/share/man + + + + + 2014-12-22 + 3.0.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 3.0.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 3.0.0 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-23 + 2.0.11 + Clean swig. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-24 + 2.0.10 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-17 + 2.0.9 + Version bump + Ertan Güven + ertan@pisilinux.org + + + 2012-09-15 + 2.0.8 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + m4 + http://www.gnu.org/software/m4/m4.html + + PisiLinux Community + admins@pisilinux.org + + GPLv3 + app:console + system.devel + GNU macro processor + GNU makro işleyicisi + L'utilitaire m4 est processeur de macro permettant de lire un ou plusieurs fichiers, les traiter en fonction leurs directives macro puis écrire le résultat dans la sortie standard. + The m4 utility is a macro processor that shall read one or more text files, process them according to their included macro statements, and write the results to standard output + m4, bir ya da daha fazla metin dosyasını okuyan; içerdikleri makro kurallarına göre bu dosyaları işleyen ve sonuçlarını standart çıktıya ileten bir makro işlemcisidir. + mirrors://gnu/m4/m4-1.4.17.tar.gz + + gettext-devel + libsigsegv + + system/devel/m4/pspec.xml + + + m4 + + libsigsegv + + + /usr/bin + /usr/share/doc + /usr/share/info + /usr/share/man + + + + + 2014-05-11 + 1.4.17 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-23 + 1.4.17 + Version bump. Yusuf Aydemir yusuf.aydemir@pisilinux.org - 2012-08-23 - 9 + 2012-07-12 + 1.4.16 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + diffstat + http://invisible-island.net/diffstat/ + + PisiLinux Community + admins@pisilinux.org + + as-is + app:console + system.devel + Diffstat reads the output of the diff command and displays a histogram of the insertions, deletions, and modifications in each file + Diffstat reads the output of the diff command and displays a histogram of the insertions, deletions, and modifications in each file.Diffstat is commonly used to provide a summary of the changes in large, complex patch files. + Diffstat lee la salida del comando diff y muestra un histograma de inserciones, borrados y modificaciones en cada archivo. Se usa comúnmente para mostrar un resumen de las modificaciones en archivos lagos y complejos. + ftp://invisible-island.net/diffstat/diffstat-1.59.tgz + + xz + gzip + bzip2 + ncompress + + system/devel/diffstat/pspec.xml + + + diffstat + + /usr/bin + /usr/share/doc + /usr/share/man + + + + + 2014-11-23 + 1.59 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-11 + 1.58 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 1.58 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-22 + 1.57 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-18 + 1.56 + version bump + PisiLinux Community + admins@pisilinux.org + + + 2012-08-15 + 1.55 + First release + Ramazan Utku + admins@pisilinux.org + + + + + + ppl + http://www.cs.unipr.it/ppl/ + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv3 + app:console + library + system.devel + Pharma Polyhedra library + Pharma Polyhedra kitaplığı + ppl is the Parma Polyhedra Library that provides numerical abstractions for analysis of complex systems. + ppl, kompleks sistemlerin analizi için sayısal ayrım sağlayan Pharma Polyhedra kitaplığıdır. + http://bugseng.com/external/ppl/download/ftp/releases/1.1/ppl-1.1.tar.xz + + gmp-devel + glpk-devel + + system/devel/ppl/pspec.xml + + + ppl + + gmp + glpk + libgcc + + + /usr/bin + /usr/lib + /usr/share/doc/COPYING + /usr/share/doc/CREDITS + /usr/share/doc/README + /usr/share/doc/NEWS + /usr/share/man + + + + ppl-docs + Documentation for ppl + ppl kitaplığı belgeleri + system.doc + + ppl + + + /usr/share/doc/ppl + + + + ppl-devel + Development files for ppl + ppl için geliştirme dosyaları + + ppl + gmp-devel + + + /usr/bin/ppl-config + /usr/include + /usr/share/aclocal + /usr/share/man/man3 + + + + + 2014-09-06 + 1.1 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 1.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 1.1 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-27 + 1.0 + Clean ppl, version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-01 + 1.0 + Fix deps. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-19 + 1.0 + Add patch for gmp 5.10. + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-07-13 + 1.0 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + uClibc + http://www.uclibc.org + + PisiLinux Community + admins@pisilinux.org + + LGPLv2.1 + library + system.devel + A C library for embedded Linux + Düşük boyut için optimize edilmiş standart C kitaplığı + uClibc is a C library for developing embedded Linux systems. It is much smaller than the GNU C Library but nearly all applications supported by glibc also work perfectly with uClibc. + uClibc, düşük boyutlu olması için optimize edilmiş bir C kitaplığıdır. Farklı mimarilerde statik bağlanmış ve düşük boyutlu ikili dosyalar oluşturmak için kullanılabilir. + http://www.uclibc.org/downloads/uClibc-0.9.33.2.tar.xz + + mandriva/uClibc-0.9.30.2-add-rpmatch-function.patch + mandriva/uClibc-0.9.30.1-add-scanf-a-flag.patch + pisilinux/linux-3.10-add___kernel_long_and___kernel_ulong.patch + suse/uClibc.fix-pthread-warnings.patch + shared-config.patch + + system/devel/uClibc/pspec.xml + + + uClibc + + /usr/lib/uClibc/sbin/ldconfig + /usr/lib/uClibc/bin + /usr/lib/uClibc + /usr/lib/uClibc/lib + /usr/lib/uClibc/usr/lib + /usr/lib/uClibc/etc + /usr/share/doc + + + System.PackageHandler + + + + uClibc-devel + Development files for uClibc + uClibc için geliştirme başlıkları + + uClibc + + + /usr/lib/uClibc/usr/include + /usr/lib/uClibc/usr/lib/*.o + /usr/lib/uClibc/usr/lib/*.a + /usr/lib/uClibc/usr/bin + /usr/bin + + + + + 2014-05-11 + 0.9.33.2 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-05 + 0.9.33.2 + build for kernel 3.10 + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-09-05 + 0.9.33.2 + Add missing method to pakhandler.py + Marcin Bojara + marcin@pisilinux.org + + + 2012-08-19 + 0.9.33.2 + First release + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + + + + make + http://www.gnu.org/software/make/make.html + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + system.devel + Standard tool to compile source trees + Geleneksel kaynak kod ağaçlarını derleme aracı + Herramienta estándar para compilación de arboles de fuentes + Outil standard de compilation de hiérarchie de sources. Make détermine ce qu'il faut faire pour construire votre programme à partir d'un fichier appelé makefile. Une fois votre programme écrit, il suffit d'éditer un makefile pour lui afin de pouvoir utiliser Make pour le compiler et l'installer. + Standard tool to compile source trees. Make gets its knowledge of how to build your program from a file called the makefile. When you write a program, you should write a makefile for it, so that it is possible to use Make to build and install the program + Geleneksel kaynak kod ağaçlarını derleme aracı. Make, programınızı nasıl derleyeceği konusundaki bilgiyi "makefile" dosyasından alır. Bir uygulama yazdığınızda bunun için "makefile" dosyasını da hazırlamalısınız ki uygulamanız derlenebilsin ve yüklenebilsin. + mirrors://gnu/make/make-4.1.tar.gz + + gettext + gnuconfig + patch + gc-devel + guile-devel + + system/devel/make/pspec.xml + + + make + + guile + + + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/locale + /usr/include + + + + + 2015-02-21 + 4.1 + Version bump + denizgu + denizgu@users.noreply.github.com + + + 2014-05-11 + 4.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-23 + 4.0 + Cleanup, bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2012-10-24 + 3.82 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + nasm + http://nasm.sourceforge.net/ + + PisiLinux Community + admins@pisilinux.org + + BSD + app:console + system.devel + Groovy little assembler + Assembler derleyicisi + NASM est l'assembleur Netwide, un assembleur libre et portable pour les processeurs des séries Intel 80x86 + NASM is the Netwide Assembler, a free portable assembler for the Intel 80x86 microprocessor series. + Intel 80x86 mikroişlemci serisi için aktarılabilir Assembler derleyicisi. + http://www.nasm.us/pub/nasm/releasebuilds/2.11.01/nasm-2.11.01.tar.xz + + texinfo + + system/devel/nasm/pspec.xml + + + nasm + + /usr/bin + /usr/share/doc + /usr/share/man + + + + + 2014-05-11 + 2.11.01 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-29 + 2.11.01 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-22 + 2.10.09 + Rebuild. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-07-24 + 2.10.09 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-02-18 + 2.10.07 + Version bump + Ertan Güven + ertan@pisilinux.org + + + 2012-09-15 + 2.10.05 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + gnuconfig + http://savannah.gnu.org/projects/config + + Serdar Soytetir + kaptan@pisilinux.org + + GPLv2+ + data + system.devel + Base config files for autofoo + Autofoo için temel config dosyaları + fichiers GNU config.sub et config.guess mis à jour. + gnuconfig contains updated config.sub and config.guess files from GNU. + gnuconfig güncel GNU config.sub ve config.guess dosyaları içerir. + http://source.pisilinux.org/1.0/config-20141105.tar.gz + system/devel/gnuconfig/pspec.xml + + + gnuconfig + + /usr/share/gnuconfig + /usr/share/doc + + + + + 2014-12-04 + 20141105 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-05-11 + 20140511 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-04-01 + 20140401 + New git snapshot. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-08-27 + 20130930 + Clean, new git snapshot. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-04-07 + 20130212 + Fix git archive + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-02-27 + 20130217 + New git archive + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-01-23 + 20130123 + bump + Erdinç Gültekin + admins@pisilinux.org + + + 2012-07-13 + 20120712 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + + + + klibc + http://www.zytor.com/mailman/listinfo/klibc + + PisiLinux Community + admins@pisilinux.org + + LGPLv2.1 + GPLv2 + library + system.devel + A minimal libc subset for use with initramfs + Küçük bir C kütüphanesi (libc) uyarlaması + klibc ou "espace utilisateur tôt", est une librairie résultante de l'effort pour transférer autant de code d'initialisation de Linux que possible hors du noyau. + klibc, or "early userspace", is library part of an effort which tries to move as much initialization code in Linux as possible out of the kernel. + klibc, sistem başlangıcı için gerekli olan kodların mümkün olduğunca çok kısmını Linux çekirdeği dışına atma hedefiyle oluşturulmuş bir kütüphanedir. + https://www.kernel.org/pub/linux/libs/klibc/2.0/klibc-2.0.3.tar.xz + + perl + kernel-module-headers + + system/devel/klibc/pspec.xml + + + klibc + + /lib + /usr/bin + /usr/lib/klibc/bin + /usr/lib/klibc/include + /usr/lib/klibc/lib + /usr/share/aclocal + /usr/share/doc + /usr/share/man/ + + + klibc.m4 + + + + + 2014-05-11 + 2.0.3 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-28 + 2.0.3 + Version bump + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-10-22 + 2.0.2 + Rebuild, cleanup. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-01-04 + 2.0.2 + First release + Marcin Bojara + marcin@pisilinux.org + + + + + + linux-firmware + http://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/ + + PisiLinux Community + admins@pisilinux.org + + ipw2100-fw + ipw2200-fw + freedist + GPLv2+ + GPLv2 + MIT + data + hardware.firmware + Firmware files used by the Linux kernel + Linux çekirdeği tarafından kullanılan firmware dosyaları + linux-firmware contains different firmware files required for some devices to operate correctly. + linux-firmware, bazı aygıtların düzgün çalışabilmesi için gerekli firmware dosyalarını içerir. + http://source.pisilinux.org/1.0/linux-firmware/linux-firmware-20150320.tar.bz2 + http://source.pisilinux.org/erdinc/common-fw.tar.xz + http://source.pisilinux.org/erdinc/firmware-ipw.tar.xz + http://source.pisilinux.org/erdinc/firmware/firmware-nonfreebox-2-tar.bz2 + http://source.pisilinux.org/erdinc/firmware/ar9170.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/ipw2x00-firmware.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/aic94xx-seq.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/zd12x1-firmware.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/accessrunner-firmware.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/rtl8192se-firmware.tar.bz2 + http://source.pisilinux.org/erdinc/firmware/nouveau-1.tar.xz + + fw/ibt-hw-37.7.10-fw-1.80.2.3.d.bseq + + hardware/firmware/linux-firmware/pspec.xml + + + linux-firmware + + noDelta + + + /lib/firmware + /usr/share/doc + + + + + 2015-03-26 + 20150320 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-02-14 + 20150214 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-12-16 + 20141216 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-11-07 + 20141107 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-07-23 + 20140603 + Version bump. + Marcin Bojara + marcin.bojara@pisilinux.org + + + 2014-04-02 + 20140316 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-03-01 + 20140217 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-11-30 + 20131013 + Remove unneeded build dep,fix unpack problem. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2013-11-23 + 20131013 + Version bump to 20131013 git. + Serdar Soytetir + kaptan@pisilinux.org + + + 2013-09-30 + 20130811 + add update Intel-Bluetooth patchs + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-08-11 + 20130811 + add update patchs + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-07-19 + 20130609 + add update patchs + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-06-09 + 20130609 + bump + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-04-07 + 20130421 + bump + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2013-03-07 + 20130224 + bump + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + 2012-12-12 + 20121212 + First release + Erdinç Gültekin + erdincgultekin@pisilinux.org + + + + + + mdadm + http://www.kernel.org/pub/linux/utils/raid/mdadm + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + hardware.disk + Utility to control Linux MD devices (software RAID arrays) + MD aygıtlarını (Yazılımsal RAID) denetleme aracı + mdadm is used to create, manage, and monitor Linux MD (software RAID) devices. + mdadm Linux MD (yazılımsal RAID) aygıtları yaratmak, yönetmek ve izlemek için kullanılan bir araçtır. + https://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-3.3.2.tar.xz + hardware/disk/mdadm/pspec.xml + + + mdadm + + /sbin/mdadm + /sbin/mdmon + /lib/udev/rules.d + /usr/lib/tmpfiles.d + /usr/share/man + /usr/share/doc + /etc + + + System.Service + + + mdadm.tmpfiles.conf + scripts/raid-check + mdadm.confd + mdadm.rules + + + + mdadm-static + Statik linklemiş Raid denetleme aracı + mdadm Linux MD (yazılımsal RAID) aygıtları yaratmak, yönetmek ve izlemek için kullanılan bir araçtır. + system.base + + /sbin/mdadm.static + /sbin/mdassemble.static + + + + + 2014-12-13 + 3.3.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2014-05-17 + 3.3 + Rebuild. Fixed service.py file + Aydın Demirel + aydin.demirel@pisilinux.org + + + 2014-04-13 + 3.3 + mdadm-static is a part of system.base now. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-31 + 3.3 + Ver. bump, rebuild + Kamil Atlı + admins@pisilinux.org + + + 2012-11-14 + 3.2.6 First release PisiLinux Community admins@pisilinux.org @@ -13241,23 +19678,17 @@ GPLv2 app:console - system.base + hardware.disk Userland logical volume management tools Mantıksal Hacim Yönetimi aracı LVM2 includes all of the support for handling read/write operations physical and logical volumes. LVM fiziksel ve mantıksal hacimler üzerinde gerçekleştirilen bütün okuma/yazma işlemlerini destekleyen araçları içerir. - ftp://sources.redhat.com/pub/lvm2/LVM2.2.02.111.tgz + ftp://sources.redhat.com/pub/lvm2/LVM2.2.02.118.tgz - libuuid-devel - libblkid-devel + libutil-linux-devel + eudev-devel - - lvm2-2.02.63-always-make-static-libdm.patch - lvm2-2.02.92-dynamic-static-ldflags.patch - lvm2-2.02.105-pthread-pkgconfig.patch - lvm2-2.02.106-static-pkgconfig-libs.patch - - system/base/lvm2/pspec.xml + hardware/disk/lvm2/pspec.xml device-mapper @@ -13266,7 +19697,7 @@ Device-mapper includes the driver enables the definition of new block devices composed of ranges of sectors of existing devices to define disk partitions or logical volumes. device-mapper mevcut aygıtlardan yeni blok aygıtları yada mantıksal hacimler yaratır. - libudev + eudev /usr/sbin/dmsetup @@ -13287,7 +19718,8 @@ Device-mapper-devel contains files needed to develop applications that use the device-mapper libraries. system.devel - device-mapper + device-mapper + eudev-devel /usr/include/libdevmapper.h @@ -13300,7 +19732,7 @@ Device mapper durum servisi This package contains the dmeventd daemon for monitoring the state of device-mapper devices. - device-mapper + device-mapper /usr/sbin/dmeventd @@ -13318,7 +19750,7 @@ This contains contains files needed to develop applications that use the device-mapper event library. system.devel - device-mapper-event + device-mapper-event /usr/include/libdevmapper-event.h @@ -13330,10 +19762,10 @@ Userland logical volume management tools LVM2 includes all of the support for handling read/write operations on physical volumes,creating volume groups from one or more physical volumes and creating one or more logical volumes in volume groups. - device-mapper - device-mapper-event - libudev - libblkid + device-mapper + device-mapper-event + libutil-linux + eudev /sbin/lvmconf @@ -13360,7 +19792,7 @@ /usr/lib/tmpfiles.d/lvm2.conf /usr/share/doc /usr/share/man/man5/lvm.conf.5 - /usr/share/man/man7/lvmthin.7 + /usr/share/man/man7 /usr/share/man/man8/fsadm.8 /usr/share/man/man8/blkdeactivate.8 /usr/share/man/man8/*pv* @@ -13381,9 +19813,10 @@ This package contains files needed to develop applications that use the lvm2 libraries. system.devel - lvm2 - device-mapper-devel - device-mapper-event-devel + libutil-linux-devel + lvm2 + device-mapper-devel + device-mapper-event-devel /usr/include/lvm2cmd.h @@ -13423,6 +19856,13 @@ + + 2015-05-02 + 2.02.118 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-09-04 2.02.111 @@ -13469,1167 +19909,60 @@ - audit - http://people.redhat.com/sgrubb/audit/ + dejavu-fonts + http://www.dejavu-fonts.org - PisiLinux Community - admins@pisilinux.org + Sezai Yeniay + sezaiyeniay@pisilinux.org - GPLv2+ - app:console - library - service - system.base - User space tools for kernel auditing - Linux çekirdeğinin 2.6 sürümü için inceleme/denetleme araçları - audit contains the user space utilities for storing and searching the audit records generated by the audit subsystem in the Linux 2.6 kernel. - audit Linux çekirdeğinin 2.6 sürümünün inceleme altyapısı tarafından üretilen inceleme kayıtlarını aramak ve saklamak için kullanılan araçları içerir. - http://people.redhat.com/sgrubb/audit/audit-2.3.7.tar.gz + as-is + data:font + desktop.font + DejaVu yazıtipleri + DejaVu fonts + DejaVu fonts + DejaVu yazıtipleri + Les fontes DejaVu basées sur des fontes Bitstream avec des améliorations. + Contains DejaVu fonts that are based on Bitstream fonts, with improvements. + Bevat de DejaVu fonts die zijn gebasserd op de Bitstream fonts, met verbeteringen. + mirrors://sourceforge/dejavu/dejavu-fonts-2.34.tar.bz2 - python-devel - kernel-headers - libcap-ng-devel - tcp-wrappers-devel + fontforge + perl-Font-TTF + unicode-ucd - - without_openldap.patch - - system/base/audit/pspec.xml + desktop/font/dejavu-fonts/pspec.xml - audit - - libcap-ng - - - /etc - /usr/share/doc - /usr/lib - /usr/sbin - /usr/bin - /usr/share/man - /var/log/audit - /var/spool/audit - - - System.Service - System.Package - - - - python-audit - Python bindings for audit - audit için Python bağlayıcısı - - audit - - - /usr/lib/python* - - - - audit-devel - Development files for audit - audit için geliştirme dosyaları - system.devel - - audit - - - /usr/include - /usr/share/man/man3 - - - - - 2014-09-30 - 2.3.7 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-06-06 - 2.3.6 - Rebuild. - Aydın Demirel - aydin.demirel@pisilinux.org - - - 2014-05-16 - 2.3.6 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 2.3.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-22 - 2.3.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-14 - 2.2.2 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2011-12-20 - 2.2.1 - First release - Yusuf Aydemir - Yusuf Aydemir - - - - - - libxml2 - http://www.xmlsoft.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.base - Version 2 of the library to manipulate XML files - XML türü dosyaları işlemeye aracılık eden kütüphanenin 2. sürümü - Libxml2 est l'analyseur et la boîte à outils XML écrit en C pour le projet Gnome (mais utilisable en dehors de la plateforme Gnome). - Libxml2 is the XML C parser and toolkit developed for the Gnome project (but usable outside of the Gnome platform). - Libxml2, Gnome projesi için geliştirilmiş C dilinde XML ayrıştırıcısıdır. Gnome platformu olmadan da kullanılabilir. - ftp://xmlsoft.org/libxml2/libxml2-2.9.1.tar.gz - - python - xz-devel - zlib-devel - readline-devel - - - CVE-2014-0191.patch - - system/base/libxml2/pspec.xml - - - libxml2-docs - system.doc - - libxml2 - + dejavu-fonts + /etc/fonts + /etc/X11/fontpath.d/dejavu + /usr/share/fonts /usr/share/doc - - libxml2 - - xz - zlib - python - readline - - - /usr/bin - /usr/lib - /usr/share/man - - - - libxml2-devel - Development files for libxml2 - libxml2 için geliştirme dosyaları - system.devel - - libxml2 - - - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/include - /usr/share/aclocal - /usr/share/man/man3 - - - - libxml2-32bit - 32-bit shared libraries for libxml2 - libxml2 için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - xz-32bit - zlib-32bit - readline-32bit - - - libxml2 - xz-32bit - zlib-32bit - - - /usr/lib32 - - - - - 2014-07-06 - 2.9.1 - Security update(CVE-2014-0191). - Vedta Demir - vedat@pisilinux.org - - - 2014-05-24 - 2.9.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 2.9.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-11-11 - 2.9.0 - Fix dep,release bump, binary file goes to main package. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-31 - 2.9.1 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-26 - 2.9.0 - Fix dep,release bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-10-22 - 2.9.0 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - ca-certificates - http://packages.qa.debian.org/c/ca-certificates.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - MPL-1.1 - app:web - system.base - Common CA certificates - Common CA certificates - http://ftp.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_20141019.tar.xz - system/base/ca-certificates/pspec.xml - - - ca-certificates - - run-parts - - - /etc - /usr/share/man - /usr/sbin - /usr/share/ca-certificates - - - System.Package - - - - - 2015-01-10 - 20141019 - Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2015-01-10 - 20141019 - Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2014-05-11 - 20140325 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-01 - 20140325 - Version bump, fix installation. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-03-03 - 20130906 - First Release - PisiLinux Community - admins@pisilinux.org - - - - - - sysfsutils - http://linux-diag.sourceforge.net/Sysfsutils.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - System Utilities Based on Sysfs - Çeşitli sistem araç ve gereçleri - Ceci est un ensemble d'utilitaires se basant sur sysfsm un nouveau système de fichier virtuel des noyaux Linux 2.5 et + exposant l'arbre des périphériques du système. - These are a set of utilites built upon sysfs, a new virtual filesystem in Linux kernel versions 2.5+ that exposes a system's device tree. - sysfsutils sysfs sanal dosya sistemi üzerine kurulu bir araç setidir. - mirrors://sourceforge/linux-diag/sysfsutils-2.1.0.tar.gz - - sysfsutils-2.0.0-class-dup.patch - sysfsutils-2.1.0-get_link.patch - - system/base/sysfsutils/pspec.xml - - - sysfsutils - - /usr/bin - /lib - /usr/lib - /usr/share/doc - /usr/share/man - - - - sysfsutils-devel - Development files for sysfsutils - sysfsutils için geliştirme dosyaları - system.devel - - sysfsutils - - - /usr/include - /usr/share/man/man3 - - - 2014-05-11 - 2.1.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 2.1.0 - Rebuild - Pisi Linux Admins - admins@pisilinux.org - - - 2010-10-11 - 2.1.0 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - ntfs-3g - http://www.tuxera.com/community/ntfs-3g-download - - PisiLinux Community - admins@pisilinux.org - - GPLv2+ - LGPLv2+ - library - app:console - system.base - Userspace driver for NTFS read/write support - NTFS dosya sistemlerine okuma/yazma erişimi için bir sürücü - ntfs-3g allows regular users read/write access to NTFS filesystems. - ntfs-3g kullanıcıların NTFS biçimli disk bölümlerine hem okuma hem yazma erişimi yapabilmesine imkan veren bir sürücüdür. - http://tuxera.com/opensource/ntfs-3g_ntfsprogs-2014.2.15.tgz - system/base/ntfs-3g/pspec.xml - - - ntfs-3g - - fuse - glibc - - - /bin - /sbin - /lib - /usr/lib - /usr/include - /usr/lib/pkgconfig - /usr/share/doc/ntfs-3g - /usr/share/man/man8/mount* - /usr/share/man/man8/ntfs-3g* - - - - ntfsprogs - Userspace tools for NTFS filesystems - NTFS dosya sistemi için kullanıcı araçları - Userspace tools for NTFS filesystems. The goals of the Linux-NTFS project are to develop reliable and full-featured access to NTFS by the Linux kernel driver and to provide a wide collection of NTFS utilities. - NTFS dosya sistemi için kullanıcı araçları içerir. Bu araçların amacı Linux çekirdeğine NTFS dosya sistemlerine güvenilir ve tam erişim sağlayacak NTFS araçlarını sağlamaktır. - hardware.disk - - ntfs-3g - glibc - libuuid - - - /sbin/mkfs.ntfs - /usr/bin - /usr/sbin - /usr/share/doc/ntfsprogs - /usr/share/man/man8 - - - - - 2014-12-13 - 2014.2.15 + 2014-01-27 + 2.34 Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 2013.1.13 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-30 - 2013.1.13 - Rebuild - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-01-30 - 2013.1.13 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-11-14 - 0.0_2012.01.15 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - gawk - http://www.gnu.org/software/gawk/gawk.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - GNU awk pattern-matching language - Metin işleme uygulaması olan awk'ın GNU versiyonu - L'outil awk interprète un langage de programmation spécifique permettant d'effectuer les tâches de modifications simples de données en quelques lignes de code. Il vous permet de faire des changements dans différents fichiers texte lorsqu'un certain patron apparaît ou d'extraire des données de fragments de lignes tout en laissant de côté le reste. Gawk est l'implémentation GNU d'awk. - The awk utility interprets a special-purpose programming language that makes it possible to handle simple data-reformatting jobs with just a few lines of code. It helps you to make changes in various text files wherever certain patterns appear, or extract data from parts of certain lines while discarding the rest. Gawk is the GNU implementation of awk. - awk uygulaması az bir kod ile basit veri formatı düzenleme işlerinizi yapabilmenize olanak sağlayan özel amaçlı bir programlama dilidir. Uygulama birçok farklı metin dosyası içinde aradığınız parçaları bulup değiştirmenize veya diğer satırlardan ayırarak işlemenize yardımcı olur. Gawk programı awk'ın GNU sürümüdür. - http://ftp.gnu.org/gnu/gawk/gawk-4.1.1.tar.xz - - gettext-devel - - - gawk-4.1.1-sandbox_issue.patch - gawk-4.1.1-sigpipe.patch - - system/base/gawk/pspec.xml - - - gawk - - readline - gmp - mpfr - - - /usr/bin - /usr/libexec - /usr/lib/gawk - /usr/include - /usr/share/awk - /usr/share/doc - /usr/share/man - /usr/share/info - /usr/share/locale - - - - - 2014-05-11 - 4.1.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-03-10 - 4.1.0 - Release bump for update eror - Burak Fazıl Ertürk - burakerturk@pisilinux.org - - - 2014-01-05 - 4.1.0 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-26 - 4.0.2 - Fix dep, release bump. Serdar Soytetir kaptan@pisilinux.org - 2013-02-14 - 4.0.2 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2012-08-23 - 4.01 + 2012-05-24 + 2.33.2514 First release PisiLinux Community admins@pisilinux.org - - - - - net-tools - http://sites.inka.de/lina/linux/NetTools/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - Standard Linux networking tools - Linux ağ araçları - net-tools est une collection de programmes représentant les outils réseau de base du système d'exploitation Linux. S'y trouvent arp, hostname, ifconfig, ipmaddr, iptunnel, mii-tool, nameif, netstat, plipconfig, rarp, route et slattach. - net-tools is a collection of programs that form the base set of the networking tools for the Linux operating system. It includes arp, hostname, ifconfig, ipmaddr, iptunnel, mii-tool, nameif, netstat, plipconfig, rarp, route and slattach. - Net-tools, Linux işletim sisteminde kullanılan ağ ile ilgili temel araçların bir birleşimidir. Arp, hostname, ifconfig, ipmaddr, iptunnel, mii-tool, nameif, netstat, plipconfig, rarp, route ve slattach programlarını içerir. - ftp://ftp.linux.org.tr/pub/mirrors/gentoo/distfiles/net-tools-1.60.tar.bz2 - - 01_all_net-tools-1.60-2.6-compilefix.patch.bz2 - 02_all_net-tools-1.60-gcc34.patch.bz2 - 03_all_net-tools-1.60-cleanup-list-handling.patch.bz2 - 04_all_net-tools-1.60-get_name.patch.bz2 - 20_all_net-tools-1.54-ipvs.patch.bz2 - 21_all_net-tools-1.57-bug22040.patch.bz2 - 22_all_net-tools-1.60-manydevs.patch.bz2 - 23_all_net-tools-1.60-miiioctl.patch.bz2 - 24_all_net-tools-1.60-virtualname.patch.bz2 - 25_all_net-tools-1.60-cycle.patch.bz2 - 26_all_net-tools-1.60-overflow.patch.bz2 - 27_all_net-tools-1.60-netstat_ulong.patch.bz2 - 50_all_net-tools-1.60-multiline-string.patch.bz2 - 51_all_net-tools-1.60-man.patch.bz2 - 52_all_net-tools-1.60-numeric-ports.patch.bz2 - 53_all_net-tools-1.60-appletalk.patch.bz2 - 54_all_net-tools-1.60-wide.patch.bz2 - 55_all_net-tools-1.60-Makefile.patch.bz2 - 56_all_net-tools-1.60-ipv6-hostname.patch.bz2 - 57_all_net-tools-1.60-ifconfig-infiniband.patch.bz2 - 60_all_net-tools-1.60-headers.patch.bz2 - net-tools-missing.patch - kernel_headers.patch - gcc-4.3.patch - large-buffer.patch - - system/base/net-tools/pspec.xml - - - net-tools - - comar - comar-api - - - /bin - /sbin - /usr/bin - /usr/sbin - /usr/share/doc - /usr/share/man - /usr/share/locale - - - - - 2014-05-11 - 1.60 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-30 - 1.60 - Rebuild - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-10-13 - 1.60 - First release - Erdem Artan - admins@pisilinux.org - - - - - - timezone - ftp://elsie.nci.nih.gov/pub/ - - PisiLinux Community - admins@pisilinux.org - - BSD - public-domain - app:console - data - system.base - Timezone data files and tools - Zamandilimi veri dosyaları ve araçları - timezone includes timezone data files and tools to use them. Package contents are synchronized with glibc tree. - timezone zamandilimi veri dosyaları ve bu dosyaları kullanmak için gerekli araçları içerir. Paket içeriği glibc gelişim ağacından oluşturulmaktadır. - http://www.iana.org/time-zones/repository/releases/tzdata2014b.tar.gz - - perl - gawk - - system/base/timezone/pspec.xml - - - timezone - - /usr/share/zoneinfo - - - - - 2014-05-11 - 2014b - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 2014b - Version bump. - Burak Fazıl Ertürk - burakerturk@pisilinux.org - - - 2012-09-27 - 0.0_20120927 - First release - Erdem Artan - admins@pisilinux.org - - - - - - libgcrypt - http://www.gnupg.org/ - - PisiLinux Community - admins@pisilinux.org - - LGPLv2.1 - library - system.base - Librairie générale de cryptographie basée sur le code utilisé dans GnuPG. - General purpose crypto library - Genel amaçlı bir şifreleme kitaplığı - Libgcrypt is a general purpose crypto library based on the code used in GNU Privacy Guard. - Libgcrypt, GNU Privacy Guard kodunu temel alan genel amaçlı bir şifreleme kitaplığıdır. - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.1.tar.bz2 - - libgpg-error-devel - - system/base/libgcrypt/pspec.xml - - - libgcrypt - - libgpg-error - - - /usr/lib - /usr/share/man - /usr/share/doc - /etc/gcrypt - /usr/bin - /usr/share/info - - - - libgcrypt-devel - Development files for libgcrypt - libgcrypt için geliştirme dosyaları - system.devel - - libgcrypt - libgpg-error-devel - - - /usr/include - /usr/lib/pkgconfig - /usr/share/aclocal - /usr/lib32/pkgconfig - /usr/bin/*-config - - - - libgcrypt-32bit - 32-bit shared libraries for libgcrypt - libgcrypt için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - libgpg-error-32bit - - - libgpg-error-32bit - libgcrypt - - - /usr/lib32 - - - - - 2014-05-11 - 1.6.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-03 - 1.6.1 - Version bump. - PisiLinux Community - admins@pisilinux.org - - 2011-05-03 - 1.5.0 + 2012-05-24 + 2.33 First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - fuse - http://fuse.sourceforge.net - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - library - system.base - Interface implémentée dans l'environnement utilisateur (userpace) pour les systèmes de fichier. - An interface for filesystems implemented in userspace - Kullanıcı düzeyinde dosya sistemi oluştumaya yarayan kitaplık - Una interfaz para sistemas de archivos implementados en el espacio de usuario - fuse is a backend allowing regular users to (un)mount filesystems for their own use. - FUSE, kullanıcıların kendileri için dosya sistemleri oluşturmasına, bağlamasına ve bağı koparmasına imkân veren bir arkauç kitaplıktır. - mirrors://sourceforge/project/fuse/fuse-2.X/2.9.3/fuse-2.9.3.tar.gz - - skip_umount_test.patch - - system/base/fuse/pspec.xml - - - fuse - - glibc - - - /bin - /sbin - /usr/bin - /lib - /usr/share/doc - /usr/share/man - - - - fuse-devel - Development files for fuse - fuse için geliştirme dosyaları - system.devel - - fuse - - - /usr/include - /usr/lib/pkgconfig - - - - - 2014-05-11 - 2.9.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-01-24 - 2.9.3 - Rebuild - Stefan Gronewold(groni) - groni@pisilinux.org - - - 2014-01-20 - 2.9.3 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-20-21 - 2.9.2 - First release - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - - - - os-prober - http://joey.kitenet.net/code/os-prober/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2+ - app:console - system.base - Utility to detect other OSes on a set of drives - Narzędzie do wykrywania innych systemów operacyjnych na dyskach - os-probe detects other OSes available on a system and outputs the results in a generic machine-readable format. Support for new OSes and Linux distributions can be added easily. - os-prober wykrywa inne systemy operacyjne dostępne na komputerze i przekazuje rezultaty w standardowym, odczytywalnym maszynowo, formacie. - ftp://ftp.debian.org/debian/pool/main/o/os-prober/os-prober_1.63.tar.gz - system/base/os-prober/pspec.xml - - - os-prober - - /usr/bin - /usr/lib - /var/lib/os-prober - /usr/share/os-prober - /usr/share/doc/os-prober - - - - - 2014-05-11 - 1.63 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-24 - 1.63 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-07-28 - 1.58 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-01-03 - 1.57 - First release - Erdinç Gültekin - admins@pisilinux.org - - - - - - slang - http://www.jedsoft.org/slang/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - Artistic - app:console - system.base - Console display library used by most text viewer - Bir çok metin gösterici yazılım tarfından kullanılan konsol görüntüleme kütüphanesi - S-Lang est une librarie de programmation multi-plateforme conçue pour permettre aux développeur de développer des logiciels robustes et portables. Elle fournit les mécanismes requis pour développer une application interactive telle que la gestion d'affichages/écrans, entrées clavier, disposition de touches et ainsi de suite. La fonctionnalité la plus attractive de cette librairie reste l'interpréteur slang qui peut être embarqué au sein même d'un programme pour le rendre extensible. - S-Lang is a multi-platform programmer's library designed to allow a developer to create robust multi-platform software. It provides facilities required by interactive applications such as display/screen management, keyboard input, keymaps, and so on. The most exciting feature of the library is the slang interpreter that may be easily embedded into a program to make it extensible. - S-lang, yazılım geliştiricilerin bütün işletim sistemlerinde çalışabilen güçlü uygulamalar geliştirmesine yardımcı olan bir uygulama kitaplığıdır. İnteraktif uygulamalar için ekran yönetimi ve klavye girişi gibi araçlar sunar. Kitaplığın en ilginç özelliği programların içine kolayca gömülebilen ve programı genişletilebilir kılan slang yorumlayıcısıdır. - ftp://ftp.ntua.gr/pub/lang/slang/slang/v2.2/slang-2.2.4.tar.bz2 - - libpng-devel - libpcre-devel - ncurses-devel - readline-devel - zlib-devel - - system/base/slang/pspec.xml - - - slang - - libpng - libpcre - zlib - - - /etc - /usr/bin - /usr/share/slsh - /usr/lib - /usr/share/doc/slang - /usr/share/man - - - - slang-devel - Development files for slang - slang için geliştirme dosyaları - system.devel - - slang - - - /usr/include - /usr/lib/pkgconfig - /usr/share/doc/slang/html - /usr/share/man/man3 - - - - - 2014-05-11 - 2.2.4 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-31 - 2.2.4 - rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-08-23 - 2.2.4 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - shadow - http://pkg-shadow.alioth.debian.org/ - - PisiLinux Community - admins@pisilinux.org - - BSD - app:console - system.base - Utilities to deal with user accounts - Kullanıcı hesapları yönetimi için araçlar - Le paquet des utilitaires pour le fichier de mot de passe Shadow regroupe les programmes nécessaires à convertir les fichiers de mots de passe traditionnels V7*NIX au format de mot passe shadow SVR4 ainsi que d'autres outils destinés à la gestion des fichiers des groupes et de mots de passe (qui fonctionnent aussi bien pour les mots de passe shadow que non-shadow). - The Shadow password file utilities package includes programs necessary to convert traditional V7 *NIX password files to the SVR4 shadow password format, and additional tools to maintain password and group files (that work with both shadow and non-shadow passwords). - Shadow parola dosyası yardımcı uygulamalar paketi, geleneksel V7 *nix parola dosyalarını SVR4 shadow parola biçimine dönüştüren programlar ile parola ve grup dosyalarının bakımı için ilave araçlar içerir. - http://pkg-shadow.alioth.debian.org/releases/shadow-4.2.1.tar.xz - - pam-devel - audit-devel - gettext-devel - skey-devel - - - shadow-strncpy-usage.patch - xstrdup.patch - - system/base/shadow/pspec.xml - - - shadow - Utilitaires pour gérer les comptes utilisateurs - Kullanıcı hesaplarını düzenlemek için araçlar. - - acl - attr - pam - audit - - - /bin - /usr/bin - /sbin - /usr/sbin - /etc - /lib - /usr/share/man - /usr/share/doc - /usr/share/info - /usr/share/locale - - - securetty - default/useradd - pam.d/login - pam.d/other - pam.d/passwd - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/shadow - pam.d/su - pam.d/system-auth - login.defs - - - - - 2014-12-13 - 4.2.1 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-05-11 - 4.1.5.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 4.1.5.1 - Rebuild without-libcrack, clean shadow, fix login defs. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-30 - 4.1.5.1 - Rebuild with-libcrack, clean shadow. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-26 - 4.1.5.1 - Release bump for rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-08-23 - 4.1.5.1 - First release - PisiLinux Community - admins@pisilinux.org + Sezai Yeniay + sezaiyeniay@pisilinux.org @@ -14644,25 +19977,19 @@ FTL GPLv2 library - system.base + desktop.font A high-quality and portable font engine Yüksek kaliteli ve taşınabilir yazıtipi düzeneği FreeType2 est un moteur logiciel de fontes conçu pour être petit, efficace, très flexible et portable tout en étant capable de produire une sortie de très haute qualité. Il peut être utilisé dans les librairies graphiques, les serveurs d'affichage, les outils de conversion, les outils de génération d'images textuelles, ainsi que beaucoup d'autres produits. FreeType 2 is a software font engine that is designed to be small, efficient, highly customizable, and portable while capable of producing high-quality output. It can be used in graphics libraries, display servers, font conversion tools, text image generation tools, and many other products as well. FreeType 2; küçük, verimli, özelleştirilebilir, taşınabilir ve yüksek kaliteli çıktı oluşturan bir yazıtipi düzeneğidir. Grafik kütüphaneleri, görüntü sunucuları ve yazıtipi değiştirme araçları gibi birçok üründe kullanılabilir. - mirrors://sourceforge/freetype/freetype-2.5.3.tar.bz2 + mirrors://sourceforge/freetype/freetype-2.5.5.tar.bz2 zlib-devel bzip2 libpng-devel - - freetype-2.2.1-enable-valid.patch - freetype-2.5.1-enable-sph.patch - freetype-2.5.1-enable-spr.patch - fix_segfault_with_harfbuzz.diff - - system/base/freetype/pspec.xml + desktop/font/freetype/pspec.xml freetype @@ -14681,10 +20008,9 @@ freetype-devel Development files for freetype freetype için geliştirme dosyaları - system.devel - freetype - harfbuzz-devel + zlib-devel + libpng-devel /usr/bin @@ -14703,10 +20029,9 @@ zlib-32bit libpng-32bit - harfbuzz-32bit - freetype + glibc-32bit zlib-32bit libpng-32bit @@ -14715,6 +20040,13 @@ + + 2015-03-11 + 2.5.5 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + 2014-05-11 2.5.3 @@ -14780,4489 +20112,6 @@ - - - xz - http://tukaani.org/xz/ - - PisiLinux Community - admins@pisilinux.org - - LGPLv2+ - GPLv2+ - GPLv3 - app:console - library - system.base - XZ compression utilities - XZ sıkıştırma araçları - XZ Utils provide a general purpose data compression library and command line tools. The .xz format supports multiple compression algorithms, which are called "filters" in context of XZ Utils. The primary filter is currently LZMA2. - xz, genel amaçlı bir veri sıkıştırma kütüphanesi ve konut satırı araçları içerir. xz dosya biçimi filtre adı verilen sıkıştırma algoritmalarını destekler, öntanımlı filtre ise LZMA2 algoritmasıdır. - http://tukaani.org/xz/xz-5.0.7.tar.gz - system/base/xz/pspec.xml - - - xz - - /usr/bin - /usr/lib - /usr/share/man - /usr/share/doc - /usr/share/locale - - - - xz-devel - Development files for XZ - XZ için geliştirme dosyaları - system.devel - - xz - - - /usr/include - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - - - - xz-32bit - 32bit shared libraries for xz - XZ için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - xz - - - /usr/lib32 - - - - - 2014-10-01 - 5.0.7 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 5.0.5 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-28 - 5.0.5 - Version bump, clean xz. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-26 - 5.0.4 - Move pc files to devel pack, increase release no. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-08-24 - 5.0.4 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - gperf - http://www.gnu.org/software/gperf/gperf.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - A perfect hash function generator - Mükemmel hash üreticisi - gperf is a perfect hash function generator. For a given list of strings, it produces a hash function and hash table, in form of C or C++ code, for looking up a value depending on the input string. The hash function is perfect, which means that the hash table has no collisions, and the hash table lookup needs a single string comparison only. - gperf mükemmel hash fonksiyonu üretecidir. Verilen bir katar listesi için C ve C++ kodu biçiminde bir hash fonksiyonu ve hash tablosu üretir. - GNU gperf es un generador de perfect hash. Produce una función hash y una tabla hash a base de una lista de cadenas, en forma de código C o C++ , para revisar valores dependiendo de una cadena de entrada. La función de hash es perfecta, lo que quiere decir que no hay colisiones en la tabla de hash, y para la búsqueda en la tabla hash se necesita solamente una comparación. - mirrors://gnu/gperf/gperf-3.0.4.tar.gz - system/base/gperf/pspec.xml - - - gperf - - libgcc - - - /usr/bin - /usr/share/doc - /usr/share/info - /usr/share/man - - - - - 2014-05-11 - 3.0.4 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-24 - 3.0.4 - Rebuild. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2013-07-26 - 3.0.4 - Fix dep,release bump. - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 3.0.4 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - openssl - http://www.openssl.org/ - - PisiLinux Community - admins@pisilinux.org - - as-is - app:console - library - system.base - Toolkit for SSL v2/v3 and TLS v1 - SSL v2/v3 ve TLS v1 için araç kiti - OpenSSL est un outil cryptographique implémentant une couche de communication sécurisée (SSL v2/v3) et une couche de transport sécurisée (TLS v1) - OpenSSL is a cryptography toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) network protocols and related cryptography standards required by them. - OpenSSL, Güvenlik Soketleri Katmanı (SSL v2/v3) ve Aktarım Katmanı Güvenliği (TLSv1) ağ protokolleri ile bu protokollerin gerektirdiği şifreleme standartlarını uygulayan bir şifreleme aracıdır. - OpenSSL ist ein Kryptographie Werkzeug, das die Netzwerkprotokolle Secure Sockets Layer (SSL v2/v3) und Transport Layer Security (TLS v1) sowie deren erforderliche zugehörige Kryptographie Standards implementiert. - ftp://ftp.openssl.org/source/openssl-1.0.2.tar.gz - - openssl-1.0.0-beta4-ca-dir.patch - - - zlib - perl - sed - - - openssl-1.0.0a-ldflags-norpath.patch - openssl-1.0.0-beta4-ca-dir.patch - openssl-1.0.0-beta5-enginesdir.patch - openssl-1.0.2-parallel-build.patch - openssl-1.0.2-ipv6.patch - openssl-1.0.2-s_client-verify.patch - openssl-include.patch - openssl_fix_for_x32.patch - openssl-optflags.patch - - system/base/openssl/pspec.xml - - - openssl - - zlib - ca-certificates - - - /etc - /usr/bin - /usr/lib - /usr/share/doc - - - System.Package - - - - openssl-devel - Development files for openssl - openssl için geliştirme dosyaları - system.devel - - openssl - - - /usr/include - /usr/share/man - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - - - - openssl-32bit - 32-bit shared libraries for openssl - openssl için 32-bit paylaşımlı kitaplıklar - emul32 - _emul32 - - zlib-32bit - - - openssl - zlib-32bit - - - /usr/lib32 - - - - - 2015-02-17 - 1.0.2 - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-11-05 - 1.0.1j - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-06-05 - 1.0.1h - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 1.0.1g - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-09 - 1.0.1g - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-02-02 - 1.0.1f - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-28 - 1.0.1e - Clean openssl. - Serdar Soytetir - kaptan@pisilinux.org - - - security - 2013-01-14 - 1.0.1e - New release - PisiLinux Community - admins@pisilinux.org - - - security - 2012-08-31 - 1.0.1c - First release - Erdem Artan - admins@pisilinux.org - - - - - - libunistring - http://www.gnu.org/software/libunistring - - PisiLinux Community - admins@pisilinux.org - - GPLv3 - LGPLv3 - library - system.base - Unicode string library - Unicode karakter dizisi kitaplığı - This library provides functions for manipulating Unicode strings and for manipulating C strings according to the Unicode standard. - Bu kitaplığı unicode standartına göre unicode ve C karakter dizilerinde değişiklik yapmak için kullanılabilecek fonksiyonlar sunar. - mirrors://gnu/libunistring/libunistring-0.9.3.tar.gz - system/base/libunistring/pspec.xml - - - libunistring - - /usr/lib - /usr/share/doc - /usr/share/info - - - - libunistring-devel - Development files for libunistring - libunistring için geliştirme dosyaları - system.devel - - libunistring - - - /usr/include - - - - - 2014-05-11 - 0.9.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-30 - 0.9.3 - Rebuild - Pisi Linux Admins - admins@pisilinux.org - - - 2011-02-10 - 0.9.3 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - plyvel - https://pypi.python.org/pypi/plyvel - - Alihan Öztürk - alihan@pisilinux.org - - BSD - app:console - system.base - Plyvel, a fast and feature-rich Python interface to LevelDB. - Plyvel, LevelDB için, hızlı ve zengin özellikli Python arabirimi. - Plyvel has a rich feature set, high performance, and a friendly Pythonic API. - Plyvel zengin özelliklere sahip bir set, yüksek performanslı, ve kullanıcı dostu bir Pythonic API. - https://pypi.python.org/packages/source/p/plyvel/plyvel-0.8.tar.gz - - cython - - system/base/plyvel/pspec.xml - - - plyvel - - libgcc - python - leveldb - - - /usr/lib - /usr/share/doc - - - - - 2014-06-08 - 0.8 - Rebuild. - Aydın Demirel - aydin.demirel@pisilinux.org - - - 2014-06-01 - 0.8 - First release. - Alihan Öztürk - alihan@pisilinux.org - - - - - - baselayout - http://www.pisilinux.org - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - library - data - system.base - Filesystem baselayout - Dosya sisteminin temel planı - Ce paquet crée la hiérarchie du système de fichier principal de Pisi Linux. - baselayout creates the Pisi Linux Linux main filesystem hierarchy. - Bu paket, Pisi Linux dosya sisteminin temelini oluşturur. - http://source.pisilinux.org/1.0/baselayout-3.10.0.tar.gz - system/base/baselayout/pspec.xml - - - baselayout - - pypolkit - - - /bin - /sbin - /lib* - /etc - /etc/pisilinux-release - /media - /boot - /proc - /home - /mnt - /opt - /dev - /run - /sys - /srv - /tmp - /usr - /var - /usr/lib/tmpfiles.d/baselayout.conf - - - System.PackageHandler - System.Package - User.Manager - Network.Stack - - - baselayout.conf - services - protocols - sysctl.conf - pisilinux-release - start-stop-daemon.8 - - - - - 2014-07-16 - 3.10.0 - Add vboxusers - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-07-16 - 3.10.0 - Release Pisi Linux 1.0 - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 3.10.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-15 - 3.10.0 - Rebuild. - Marcin Bojara - marcin@pisilinux.org - - - 2014-01-19 - 3.10.0 - Update baselayout.conf - Marcin Bojara - marcin@pisilinux.org - - - 2014-01-08 - 3.10.0 - Add baselayout.conf - Marcin Bojara - marcin@pisilinux.org - - - 2013-12-20 - 3.10.0 - Release Pisi Linux Rc2 - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-27 - 3.10.0 - Add gdm user and group, apply chmod 1777 to dev/shm aka run/shm. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-09-10 - 3.10.0 - Add shm dir to run, new archive. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-09-05 - 3.8.0 - Add missing method to pakhandler.py - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-31 - 3.8.0 - release Izmir - Erdinç Gültekin - erdincgultekin@pisilinux.org - - - 2013-03-24 - 3.8.0 - Pisi Linux changes. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-11 - 3.7.1 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - wireless-tools - http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - A collection of tools to configure wireless lan cards - Kablosuz ağ kartlarını yapılandırmak için kullanılan bir araç seti - Les outils sans fil (Wireless Tools ou WT) est un ensemble d'outils permettant de manipuler les extensions sans fil, c'est une interface de programmation d'application (API) générique permettant à un pilote d'exposer à l'espace utilisateur la configuration ainsi que des statistiques spécifiques aux LANs sans fil communs. Ils utilisent une interface textuelle assez rugueuse, mais ont pour objectif de couvrir la totalité de l'extension sans fil. - The Wireless Tools (WT) is a set of tools allowing to manipulate the Wireless Extensions, a generic application programming interface allowing a driver to expose to the user space configuration and statistics specific to common Wireless LANs. They use a textual interface and are rather crude, but aim to support the full Wireless Extension. - Wireless Extensions, sürücülerin bilinen kablosuz ağların ayarlarını yapmak ve istatistiklerini görüntülemek amacıyla kullandığı bir yazılım programlama arayüzüdür. Wireless Tools ise Wireless Extensions ayarlarını modifiye etmek için kullanılan araçları içeren bir pakettir. Grafik arayüzü bulunmaz, biraz da kabadır; ancak Wireless Extension'u tam olarak desteklemeyi hedefler. - http://svn.mandriva.com/svn/packages/cooker/wireless-tools/current/SOURCES/wireless_tools.30.pre9.tar.gz - - no-ldconfig.patch - wireless_tools.27-wireless-man-upd.patch - wireless-tools-29-makefile.patch - - system/base/wireless-tools/pspec.xml - - - wireless-tools - - comar - - - /sbin - /usr/lib - /usr/share/man - /usr/share/doc - - - - wireless-tools-devel - Development files for wireless-tools - wireless-tools için geliştirme dosyaları - system.devel - - wireless-tools - - - /usr/include - /usr/share/man/man3 - - - - - 2014-05-11 - 30 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 30 - Güncellendi. - PisiLinux Community - admins@pisilinux.org - - - 2013-02-11 - 30 - Güncellendi. - PisiLinux Community - admins@pisilinux.org - - - 2011-06-01 - 29 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - libee - http://www.libee.org/ - - Marcin Bojara - marcin@pisilinux.org - - LGPLv2.1 - library - system.base - An Event Expression Library inspired by CEE - Libee - An Event Expression Library inspired by CEE - http://www.libee.org/download/files/download/libee-0.4.1.tar.gz - - libestr-devel - - system/base/libee/pspec.xml - - - libee - - libestr - - - /usr/sbin - /usr/lib/libee.so* - /usr/share/doc/libee - - - - libee-devel - Development files for libestr - system.devel - - libee - - - /usr/include/libee - /usr/lib/pkgconfig/libee.pc - - - - - 2014-05-11 - 0.4.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 0.4.1 - rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-11-21 - 0.4.1 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - pisi - http://www.pisilinux.org/ - - Marcin Bojara - marcin@pisilinux.org - - GPLv2 - app:console - system.base - PISI is the package management system of Pisi Linux - PİSİ PiSi Linux'un paket yönetim sistemidir - PiSi – menadżer pakietów dla PiSi Linux. - PISI est gestionnaire de paquets moderne implémenté en Python.Ces principales fonctionnalités sont les suivantes : - Les paquets sources sont écrits en XML et en python - Implemente tout les fonctions à travers une API simple d'utilisation - Intègre aussi bien les fonctionnalités de bas niveaux que de haut niveau de gestion de paquets. - PISI is a modern package management system implemented in Python. Some of its main features are: package sources are written in XML and python, implements all functions through a simple-to-use API, integrates low-level and high-level package management features. - PİSİ Python'da yazılmış modern bir paket yöneticisidir. Bazı ana özellikleri: Paket kaynakları XML ve python kullanılarak yazılır, bütün işlevleri kullanması kolay bir API ile sağlar ve düşük ve yüksek seviyeli paket yönetim işlevlerini birleştirir. - PISI jest podstawowym narzędziem do instalacji, aktualizacji i usuwania pakietów. Obsługuje zależności dla poszczególnych pakietów, bibliotek i zadań ÇOMAR-a. Instalacja oprogramowania odbywa się w łatwy i przyjazny sposób. Do przechowywania informacji o pakietach wykorzystuje bazę Berkeley DP, co zapewnia większą stabilność i szybkość. - http://source.pisilinux.org/1.0/pisi-2.6.tar.xz - - pisi.conf-i686 - pisi.conf-x86_64 - - - comar - plyvel - python - gettext - leveldb-devel - - - initialize_filesdb_once.patch - no_clean_if_ignore_comar.patch - orphaned_pkgs.patch - improve_pisi_ix.patch - fix_emul32_flags.patch - pisi-2.6-pisitools.dopixmaps-add.patch - - system/base/pisi/pspec.xml - - - pisi - - tar - file - comar - plyvel - python - gettext - leveldb - piksemel - comar-api - urlgrabber - python-psutil - python-pyliblzma - mudur - - - /usr/bin - /usr/sbin - /usr/lib/pardus/pisi - /usr/lib/pisilinux/pisi - /usr/share/locale - /usr/share/doc - /etc/pisi - /usr/share/mime/packages - /usr/lib/tmpfiles.d/pisi.conf - /run/lock/files.ldb/LOCK - /var/lib/pisi/info/files.ldb/LOCK - - - System.Package - System.Manager - - - mirrors.conf - sandbox.conf - pisi.xml - pkgconfig.py - tmpfiles.conf - - - - - 2014-12-07 - 2.6 - Add new pisitools.dopixmaps - Osman Erkan - osman.erkan@pisilinux.org - - - 2014-09-15 - 2.6 - Add new pisi commands: list-orphaned and remove-orphaned. - Improve pisi index. - Marcin Bojara - marcin@pisilinux.org - - - 2014-08-04 - 2.6 - pisi search-file works without sudo now. - Marcin Bojara - marcin@pisilinux.org - - - 2014-07-25 - 2.6 - Rebuild for version number. - Aydın Demirel - aydin.demirel@pisilinux.org - - - 2014-06-24 - 2.6 - Add patch for initialize filesdb once. - Marcin Bojara - marcin@pisilinux.org - - - 2014-06-15 - 2.6 - Version bump. - revdep-rebuild rewritten in python. - Marcin Bojara - marcin@pisilinux.org - - - 2014-06-08 - 2.5 - Add case sensitive for 'pisi sr'. - Change install path. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-27 - 2.5 - Add patch level auto detection feature, - sha1sum for install.tar.xz file, - check sha1sum for upgrade. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 2.5 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 2.5 - Some improvements for buildfarm. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-04 - 2.5 - Handle error for file command. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-16 - 2.5 - Workaround for update espeak package. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-07 - 2.5 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-02-28 - 2.4 - Fix pisitools.dosed output. - Marcin Bojara - marcin@pisilinux.org - - - 2014-02-13 - 2.4 - Workaround for the case where old dir /a/b/c is replaced by file c in /a/b dir. - Marcin Bojara - marcin@pisilinux.org - - - 2013-11-12 - 2.4 - Fix stripping issues, in file info: LSB executable, LSB shared syntax. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-22 - 2.4 - Disable python_installation patch to check python upgrading breaks pisi or not. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-08-25 - 2.4 - Fix autocompletion for local uncompressed index file. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-21 - 2.4 - Fix upgrading python package. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-01 - 2.4 - Improve managing CFLAGS, CXXFLAGS and LDFLAGS, - export HOME=get.workDIR() as default. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-25 - 2.4 - Fix and improve kerneltools. - Avoid double slashes pisi error. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-11 - 2.4 - adjust takeback to new dir structure. - Marcin Bojara - marcin@pisilinux.org - - - 2013-06-21 - 2.4 - No capital letters in directory names. - Marcin Bojara - marcin@pisilinux.org - - - 2013-06-17 - 2.4 - Fix overwrite 64bit libs by 32bit for some packages - Marcin Bojara - marcin@pisilinux.org - - - 2013-06-02 - 2.4 - Add sorting packages for pisi ix - Marcin Bojara - marcin@pisilinux.org - - - 2013-05-15 - 2.4 - Add pisitools.flags() and pisitools.ldflags() - Marcin Bojara - marcin@pisilinux.org - - - 2013-05-12 - 2.4 - Sandbox.conf edit. - PisiLinux Community - admins@pisilinux.org - - - 2013-03-20 - 2.4 - Add patch for speed up packaging process - Marcin Bojara - marcin@pisilinux.org - - - 2013-03-14 - 2.4 - Improve dosed - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-14 - 2.4 - Add assign-devel-and-doc-packages.patch. - Marcin Bojara - marcin@pisilinux.org - - - 2013-01-18 - 2.4 - First release. - Marcin Bojara - marcin@pisilinux.org - - - - - - ncurses - http://www.gnu.org/software/ncurses/ncurses.html - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.base - Console display library - Konsol görsel kütüphanesi - NCurses est une librairie de fonction gérant l'affichage des applications pour terminaux en mode caractères. La libraries NCurses défini de nombreuses fonctionalités telles le mouvement de la souris et du curseur, la disposition du clavier et l'affichage en couleur. - The NCurses is a library of functions that manage an application's display on character-cell terminals. The NCurses library defines many functions such as moving mouse and cursor, keyboard mapping and dispaying in color. - NCurses, bir uygulamanın karakter tabanlı uçbirimlerde görüntüleri üzerinde çalışabilmeyi sağlayan işlevler kütüphanesidir. Uygulama programları için imleci hareket ettirmek, pencereler oluşturmak, renkler üretmek, fare ile oynamak v.b. işlevler sağlamaktadır. - mirrors://gnu/ncurses/ncurses-5.9.tar.gz - - gnuconfig - - system/base/ncurses/pspec.xml - - - ncurses - - /etc - /lib - /usr/bin - /usr/lib - /usr/share/terminfo - /usr/share/tabset - /usr/share/man - /usr/share/doc - - - - ncurses-devel - Development files for ncurses - ncurses için geliştirme dosyaları - system.devel - - ncurses - - - /usr/include - /usr/lib/static - /usr/lib32/static - /usr/share/man/man3 - - - - ncurses-32bit - 32-bit shared libraries for ncurses - emul32 - _emul32 - - ncurses - - - /usr/lib32 - /usr/lib32/pkgconfig - - - - - 2014-09-14 - 5.9 - Fix build .pc files. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 5.9 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-31 - 5.9 - Rebuild. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-27 - 5.9_20121110 - Clean ncurses - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-11-14 - 5.9_20121110 - First release - Erdinç Gültekin - admins@pisilinux.org - - - - - - python - http://www.python.org/ - - PisiLinux Community - admins@pisilinux.org - - PSF-2.2 - app:console - system.base - An interpreted, interactive, object-orientated programming language - Nesneye yönelik bir programlama dili - Python est un langage de programmation dynamique orienté objet pouvant être utilisé pour différents types de développements logiciels. Il offre une intégration renforcée aussi bien avec les autres langages qu'avec des outils. Il est livré avec des librairies standards couvrant un large périmètre et peut être appris en quelques jours. - Python is a dynamic object-oriented programming language that can be used for many kinds of software development. It offers strong support for integration with other languages and tools, comes with extensive standard libraries, and can be learned in a few days. - Python, yazılım geliştirmenin birçok aşamasında kullanılabilen, dinamik nesne tabanlı bir programlama dilidir. Diğer programlama dilleriyle bütünleşme için sağlam bir destek sunar, kapsamlı standart kütüphanelerle sunulur ve birkaç günde öğrenilebilir. - http://www.python.org/ftp/python/2.7.9/Python-2.7.9.tar.xz - - bzip2 - tcl-devel - gdbm-devel - zlib-devel - expat-devel - tcltk-devel - libffi-devel - sqlite-devel - ncurses-devel - openssl-devel - readline-devel - - - pisilinux_platform.patch - add-pisilinux-to-search-path.patch - default-utf8.patch - disable-egginfo.patch - trfix_emaillib.patch - - system/base/python/pspec.xml - - - python - - noDelta - - - gdbm - zlib - bzip2 - expat - libffi - sqlite - ncurses - openssl - readline - - - /etc - /usr/bin - /usr/include/python2.7/pyconfig.h - /usr/lib - /usr/share/doc - /usr/share/man - - - System.PackageHandler - - - pythonstart - 04python - - - - python-devel - Development files for python - python için geliştirme dosyaları - system.devel - - python - - - /usr/include - /usr/lib/pkgconfig - - - - python-tk - Python modules for Tk - Tk için Python modülleri - library - programming.language.python - - tcl - tcltk - - - /usr/lib/python*/lib-tk - /usr/lib/python*/lib-dynload/_tkinter.so - - - - idle - An Integrated Development Environment for Python - Python için Tümleşik Geliştirme Ortamı - app:gui - programming.environment - idle - - python-tk - - - /usr/bin/idle - /usr/lib/python*/idlelib - /usr/share/applications - /usr/share/pixmaps - - - python-logo.png - idle.desktop - - - - - 2014-12-12 - 2.7.9 - Version bump and security fixes. - Vedat Demir - vedat@pisilinux.org - - - 2014-07-05 - 2.7.8 - Version bump and security fixes. - Vedat Demir - vedat@pisilinux.org - - - 2014-06-02 - 2.7.7 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 2.7.6 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-25 - 2.7.6 - Add upstream patch. - Marcin Bojara - marcin@pisilinux.org - - - 2014-02-20 - 2.7.6 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-09-05 - 2.7.5 - Add missing method to pakhandler.py - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-31 - 2.7.5 - Clean python. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-21 - 2.7.5 - Add some patches. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-16 - 2.7.5 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-07-11 - 2.7.3 - First release - Erdem Artan - admins@pisilinux.org - - - - - - cpio - http://www.gnu.org/software/cpio/cpio.html - - PisiLinux Community - admins@pisilinux.org - - GPLv3 - app:console - system.base - A file archival tool which can also read and write tar files - Tar ve cpio dosyaları içine yazıp okuyabilen bir dosya arşivleme uygulaması - GNU cpio permet de copier des fichiers du système dans une archive cpio ou tar et vice-versa. L'archive peut être un simple fichier sur le disque, une cassette magnétique, ou un tuyau unix (pipe). GNU cpio gère les formats d'archive suivant : binaire, ASCII ancien, ASCII nouveau, crc, binaire HPUX, ASCII ancien HPUX, tar ancien et tar POSIX.1. - GNU cpio copies files into or out of a cpio or tar archive. The archive can be another file on the disk, a magnetic tape, or a pipe. GNU cpio supports the following archive formats: binary, old ASCII, new ASCII, crc, HPUX binary, HPUX old ASCII, old tar, and POSIX.1 tar. - GNU cpio dosyaları cpio veya tar arşivlerine kopyalamaya veya bu arşivlerden çıkarmak için tasarlanmıştır. Arşiv diskteki başka bir dosya, manyetik bir teyp veya bir boru sistemi olabilir. GNU cpio şu arşiv formatlarını destekler: ikili, eski ASCII, yeni ASCII, crc, HPUX ikili, HPUX eski ASCII, eski tar ve POSIX.1 tar. - mirrors://gnu/cpio/cpio-2.11.tar.bz2 - - cpio-2.7-svr4compat.patch - cpio-2.9-exitCode.patch - CVE-2010-0624-rpatelib-overflow.patch - - system/base/cpio/pspec.xml - - - cpio - - /bin - /usr/share/doc - /usr/share/man - /usr/share/info - /usr/share/locale - - - - - 2014-05-11 - 2.11 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 2.11 - rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-08-24 - 2.11 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - findutils - http://www.gnu.org/software/findutils/findutils.html - - PisiLinux Community - admins@pisilinux.org - - GPLv3+ - app:console - system.base - GNU utilities to find files - Dosya bulmak için kullanılan GNU uygulamaları - Les utilitaires de recherche GNU sont les utilitaire de recherche de répertoire basique du système d'exploitation GNU. Ces programmes sont typiquement associés à d'autres programmes pour leur fournir une capacité de recherche de fichier et de répertoire puissante et modulaire à d'autres commandes. - The GNU Find Utilities are the basic directory searching utilities of the GNU operating system. These programs are typically used in conjunction with other programs to provide modular and powerful directory search and file locating capabilities to other commands. - GNU Find Utilities GNU işletim sisteminin temel dizin arama uygulamalarıdır. Bu uygulamalar diğer komutlara başka programlar ile birlikte çalışarak modüler ve güçlü dizin ve dosya arama yetenekleri sunar. - http://ftp.gnu.org/pub/gnu/findutils/findutils-4.4.2.tar.gz - - gettext-devel - - system/base/findutils/pspec.xml - - - findutils - - /usr/bin - /usr/lib/find - /usr/share/doc - /usr/share/man - /usr/share/info - /usr/share/locale - - - - - 2014-05-11 - 4.4.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-01 - 4.4.2 - Revert back to stable version, clean findutils. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-09-14 - 4.5.9 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - rsyslog - http://www.rsyslog.com - - PisiLinux Community - admins@pisilinux.org - - GPLv3+ - service - system.base - Enhanced system logging and kernel message trapping daemons - Gelişmiş sistem günlükleme hizmeti - rsyslog is an enhanced multi-threaded syslogd supporting, among others, MySQL, syslog/tcp, RFC 3195, permitted sender lists, filtering on any message part, and fine grain output format control. It is quite compatible with stock sysklogd and can be used as a drop-in replacement. - rsyslog, çoklu iş parçacığı, MySQL, syslog/tcp, RFC 3195, izin verilen gönderici listesi, gelişmiş ileti filtreleme gibi özelliklere sahip gelişmiş bir sistem günlükleme hizmetidir. - http://www.rsyslog.com/files/download/rsyslog/rsyslog-7.6.3.tar.gz - - zlib-devel - json-c-devel - libestr-devel - libgcrypt-devel - liblogging-devel - - system/base/rsyslog/pspec.xml - - - rsyslog - - zlib - json-c - libestr - libuuid - libgcrypt - liblogging - - - /usr/bin/rsyslogd - /usr/lib/rsyslog - /usr/share/man - /usr/share/doc - /etc/logrotate.d - /etc/conf.d - /etc/rsyslog.conf - - - System.Service - - - rsyslog.logrotate - rsyslog.conf - rsyslog.sysconfig - - - - - 2014-05-11 - 7.6.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-30 - 7.6.3 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-02-13 - 7.2.5 - Rebuild Unused - Varol Maksutoğlu - waroi@pisilinux.org - - - 2013-07-26 - 7.2.5 - Release bump, fix dep. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-14 - 7.2.5 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-11-21 - 7.2.3 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - run-parts - http://packages.qa.debian.org/d/debianutils.html - - PisiLinux Community - osman.erkan@yandex.com - - GPLv2+ - system.base - run scripts or programs in a directory - run scripts or programs in a directory - ftp://ftp.archlinux.org/other/run-parts/debianutils_4.4.tar.gz - system/base/run-parts/pspec.xml - - - run-parts - - /usr/share/man - /usr/bin - /usr/sbin - - - - - 2014-05-11 - 4.4 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-02 - 4.4 - rm unneeded files. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2014-04-01 - 4.4 - Release bump for component change. - PisiLinux Community - osman.erkan@yandex.com - - - 2014-03-02 - 4.4 - First Release - PisiLinux Community - osman.erkan@yandex.com - - - - - - sed - http://sed.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - GNU Stream Editor - GNU stream düzenleyici - Sed est un éditeur de flux. Un éditeur de flux est utilisé pour réaliser des opérations basiques de modification de texte sur un flux d'entrée (un fichier ou un tuyau unix). - Sed is a stream editor. A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline). - Sed bir dosyadan veya standart girdiden (klavyeden) bilgi okur ve standart çıktıya (ekrana) okuduğu bilgileri kullanıcının belirlediği düzene sokarak yazar. - mirrors://gnu/sed/sed-4.2.2.tar.gz - - gettext-devel - - system/base/sed/pspec.xml - - - sed - - acl - - - /bin - /usr/bin - /usr/share/doc - /usr/share/man - /usr/share/info - /usr/share/locale - - - - - 2014-05-11 - 4.2.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-27 - 4.2.2 - Clean sed. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-14 - 4.2.2 - Release bump for rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-14 - 4.2.2 - New release - PisiLinux Community - admins@pisilinux.org - - - 2010-10-11 - 4.2.1 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - perl-Locale-gettext - http://search.cpan.org/dist/gettext - - PisiLinux Community - admins@pisilinux.org - - Artistic - library - system.base - A Perl module for accessing the GNU locale utilities - GNU yerel araçlarına erişim için Perl modülü - The gettext module permits access from Perl to the gettext() family of functions for retrieving message strings from databases constructed to internationalize software. - Bu modül, çoklu dil desteğini sağlayan gettext() ailesine Perl üzerinden erişimi sağlar. - El módulo gettext permite Perl acceder a la familia de funciones gettext() para obtener cadenas de mensajes (traducidos) desde bases de datos para la internacionalización de software. - http://search.cpan.org/CPAN/authors/id/P/PV/PVANDRY/gettext-1.05.tar.gz - - perl - - system/base/perl-Locale-gettext/pspec.xml - - - perl-Locale-gettext - - perl - - - /usr/lib - /usr/share/perl - /usr/share/doc - /usr/share/man - - - - - 2014-09-10 - 1.05 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 1.05 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-04 - 1.05 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-10-07 - 1.05 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - pycurl - http://pycurl.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - LGPLv2.1 - library - system.base - Python cURL Module - Python cURL Modülü - PycURL is a Python interface to libcurl. PycURL can be used to fetch objects identified by a URL from a Python program. - PycURL, python libcurl için python arayüzüdür. PycURL, URL tarafında tanımlanan nesneleri indirmek için bir python programı tarafından kullanılabilir. - http://pycurl.sourceforge.net/download/pycurl-7.19.3.1.tar.gz - - curl - python - openssl - - system/base/pycurl/pspec.xml - - - pycurl - - curl - python - openssl - - - /usr/lib - /usr/share/doc - - - - - 2014-05-11 - 7.19.3.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-01 - 7.19.3.1 - Version bump. - Kamil Atlı - suvarice@gmail.com - - - 2013-12-19 - 7.19.0.2 - Rebuild - Stefan Gronewold(groni) - groni@pisilinux.org - - - 2013-03-12 - 7.19.0.2 - Version bum. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-03-12 - 7.19.0 - Fix pisi https issue - Pisi Linux Admins - marcin@pisilinux.org - - - 2010-10-11 - 7.19.0 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - dbus-glib - http://dbus.freedesktop.org/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - AFL-2.1 - library - system.base - Glib bindings for D-Bus - D-Bus için GLib bağlayıcıları - dbus-glib is an add-on library to integrate the standard D-Bus library with the GLib thread abstraction and main loop. - dbus-glib, standart D-Bus kitaplığını GLib ana döngüsüyle bütünleştirmek için kullanılan bir kitaplıktır. - http://dbus.freedesktop.org/releases/dbus-glib/dbus-glib-0.102.tar.gz - - dbus - glib2 - expat - libxml2 - - system/base/dbus-glib/pspec.xml - - - dbus-glib - - dbus - glib2 - expat - libxml2 - - - /usr/bin - /usr/libexec/dbus-bash-completion-helper - /usr/lib - /usr/share/doc - /usr/share/man/man1 - /etc/bash_completion.d - /usr/share/bash-completion - /usr/libexec - - - - dbus-glib-devel - Development files for dbus-glib - dbus-glib için geliştirme dosyaları - system.devel - - dbus-glib - - - /usr/include/dbus-1.0 - /usr/lib/pkgconfig - /usr/share/man/man3 - - - - - 2014-05-11 - 0.102 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-02-18 - 0.102 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-11 - 0.100.1 - Güncellendi. - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 0.100 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - psmisc - http://psmisc.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - A set of tools that use the proc filesystem - proc dosya sistemi kullanan bir araç takımı - PSmisc est une collection de petits utilitaires utilisant le système de fichier /proc, et assiste l'administrateur système dans ses tâches habituelles. - PSmisc is a collection of small utilities using /proc file system, and providing the system administrator with some help in common tasks. - PSmisc, /proc dosya sistemini kullanan küçük araçlar yardımıyla sistem yöneticisine bazı genel görevlerde yardımcı olmayı amaçlar. - PSmisc ist eine Sammlung von kleinen Anwendungen, die das /proc Dateisystem verwenden und dem System Administrator Hilfe für gängige Aufgaben bieten. - mirrors://sourceforge/psmisc/psmisc-22.20.tar.gz - - ncurses - gettext - - system/base/psmisc/pspec.xml - - - psmisc - - ncurses - - - /bin - /usr/bin - /usr/share/man - /usr/share/doc - /usr/share/locale - - - - - 2014-05-11 - 22.20 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-14 - 22.20 - New version - Ertan Güven - ertan@pisilinux.org - - - 2012-08-24 - 22.19 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - db - http://www.oracle.com/technology/products/berkeley-db/db/index.html - - PisiLinux Community - admins@pisilinux.org - - DB - app:console - system.base - Quatrième version de Berkeley DB - Oracle Berkeley DB - Oracle Berkeley DB - Ein einbettbares Datenbank Engine, dass die Entwickler mit schnellen, zuverlässigen und lokalen Persistenz unterstützt und null Administration erfordert. - The Berkeley Database (Berkeley DB) is a programmatic toolkit that provides embedded database support for both traditional and client/server applications. The Berkeley DB includes B+tree, Extended Linear Hashing, Fixed and Variable-length record access methods, transactions, locking, logging, shared memory caching, and database recovery. The Berkeley DB supports C, C++, Java, and Perl APIs. It is used by many applications, including Python and Perl, so this should be installed on all systems. - Berkeley DB geliştiricilere yerel süreklilik sağlayan ve herhangi bir ayar gerektirmeden (zero administration) kullanılan, hızlı ve gömülebilir bir veritabanı motorudur. - http://download.oracle.com/berkeley-db/db-5.3.28.tar.gz - system/base/db/pspec.xml - - - db - - libgcc - - - /usr/bin - /usr/lib - /usr/sbin - - - db5 - - - - db-devel - Development files for db - - db - - - /usr/include - - - db5-devel - - - - db-docs - Documentation for db - system.doc - - db - - - /usr/share/doc - - - db5-docs - - - - - 2014-09-10 - 5.3.28 - Rebuild for component change. - Perl depends on db, so we need it in system.base. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-07-15 - 5.3.28 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 5.3.28 - Version bump - PisiLinux Community - admins@pisilinux.org - - - 2013-08-29 - 5.3.21 - Rename and clean db pack. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-26 - 5.3.21 - Fix dep, release bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-08-31 - 5.3.21 - First release - Erdem Artan - admins@pisilinux.org - - - - - - libXau - http://www.x.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.base - Librairie Au de X.Org. - X.Org Au library - X.Org Au kitaplığı. - X.Org Au Bibliothek - libXau provides functions to manage X authorization files - libXau, X yetkilendirme dosyalarını yönetmek için işlevler sağlar. - http://xorg.freedesktop.org/archive/individual/lib/libXau-1.0.8.tar.gz - - visibility.patch - - system/base/libXau/pspec.xml - - - libXau - - /usr/lib - - - - libXau-devel - Development files for libXau - libXau için geliştirme dosyaları - system.devel - - libXau - - - /usr/include/X11 - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/man - - - - libXau-32bit - 32-bit shared libraries for libXau - libXau için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - libXau - - - /usr/lib32 - - - - - 2014-05-11 - 1.0.8 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-07 - 1.0.8 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-06-21 - 1.0.8 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-08-23 - 1.0.7 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - nspr - http://www.mozilla.org/projects/nspr/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - library - system.base - Netscape Portable Runtime - Netscape Taşınabilir Çalışma Zamanı - Netscape Portable Runtime (NSPR -- Exécutable Portable Netscape) fourni une API neutre au sens de la plate-forme pour les fonctions de niveau système ou de type libc. Cette API est utilisée au sein du client Mozilla ainsi que de nombreuses solutions logicielles de Netscape/AOL/iPlanet. - Netscape Portable Runtime (NSPR) provides a platform-neutral API for system level and libc like functions. The API is used in the Mozilla client, many of Netscape/AOL/iPlanet's and other software offerings. - Netscape Taşınabilir çalışma Zamanı (NSPR) sistem seviyesindeki libc ve benzeri fonksiyonlar için platform bağımsız bir programlama arayüzü sunar. Bu arayüz, Mozilla istemcilerinde, Netscape/AOL/iPlanet'in diğer yazılımlarında kullanılmaktadır. - Netscape Portable Runtime (NSPR) provee un API independiente de la plataforma a nivel de sistema y funciones como libc. El API está usado en el cliente Mozilla, y muchos otros software de Netscape/AOL/iPlanet. - ftp://ftp.mozilla.org/pub/mozilla.org/nspr/releases/v4.10.7/src/nspr-4.10.7.tar.gz - - nspr.pc.in - generate-pc-config.sh - - system/base/nspr/pspec.xml - - - nspr - - /usr/lib - - - - nspr-devel - Development files for nspr - nspr için geliştirme dosyaları - system.devel - - nspr - - - /usr/include - /usr/lib/pkgconfig - /usr/bin - - - - - 2014-12-06 - 4.10.7 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-07-05 - 4.10.6 - Release bump. - PisiLinux Community - admins@pisilinux.org - - - 2014-05-11 - 4.10.4 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 4.10.4 - Version bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-11-18 - 4.10.2 - Version bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-10-23 - 4.10.1 - Version bump. - Ertuğrul Erata - ertugrulerata@gmail.com - - - 2013-07-18 - 4.10 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-05-17 - 4.9.6 - v.bump - Erdinç Gültekin - erdincgultekin@pisilinux.org - - - 2013-01-14 - 4.9.5 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-11-25 - 4.9.4 - First release - Erdinç Gültekin - admins@pisilinux.org - - - - - - grub2 - http://www.gnu.org/software/grub/ - - Serdar Soytetir - kaptan@pisilinux.org - - GPLv3 - app:gui - system.base - GNU GRUB is a Multiboot boot loader. - GNU GRUB (short for GNU GRand Unified Bootloader) is a boot loader package from the GNU Project. - ftp://alpha.gnu.org/gnu/grub/grub-2.02~beta2.tar.xz - http://source.pisilinux.org/1.0/grub2_extras_915resolution_r10.tar.xz - http://ftp.gnu.org/gnu/unifont/unifont-6.3.20131217/unifont-6.3.20131217.bdf.gz - http://source.pisilinux.org/1.0/grub2-theme-pisilinux-0.2.tar.xz - - autogen - binutils - bison - flex - gcc - help2man - texinfo - freetype-devel - zlib-devel - ncurses-devel - xz-devel - fuse-devel - lvm2-devel - device-mapper-devel - gettext-devel - dejavu-fonts - - - pisi_name_and_initramfs.patch - mkconfig-fix.patch - - system/base/grub2/pspec.xml - - - grub2 - - freetype - xz - fuse - lvm2 - device-mapper - os-prober - - - /usr/bin - /usr/sbin - /usr/lib/grub/i386-pc/ - /usr/share/doc - /usr/share/grub - /usr/share/info - /boot/grub2 - /usr/share/locale - /usr/share/man/man1 - /usr/share/man/man8 - /etc/bash_completion.d - /etc/grub.d - /etc/default - - - pisi-grub-bg.png - grub-defaults - - - - - 2014-07-20 - 2.02_beta2 - New artwork. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 2.02_beta2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-01-21 - 2.02_beta2 - Version bump - Marcin Bojara - marcin@pisilinux.org - - - 2013-12-31 - 2.00_5148 - Fix finding other distros. - Fix build with current freetype. - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-02 - 2.00_5148 - Version bump - Marcin Bojara - marcin@pisilinux.org - - - 2013-08-24 - 2.00 - Comment GRUB_GFXPAYLOAD_LINUX=keep out. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-28 - 2.00 - Fix deps. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-06-17 - 2.00 - Set default grub2 resolution to 1024x768 - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-03-03 - 2.00 - Add default Pisi Linux theme - Remove unneeded unifont dep - Manually create Dejavu pf2 fonts - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-02-09 - 2.00 - Enable splash again. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-11-28 - 2.00 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - polkit - http://www.freedesktop.org/wiki/Software/PolicyKit - - PisiLinux Community - admins@pisilinux.org - - LGPLv2+ - service - library - app:console - system.base - PolicyKit Authorization Framework - Sistem bileşenleri için erişim politikası servisi - polkit est un cadre de développement (framework) pour définir des politiques à appliquer à des composants du système ainsi que fournir à des parties du bureau la possibilité de les configurer. - polkit is a toolkit for defining and handling authorizations. It is used for allowing unprivileged processes to speak to privileged processes. - polkit, sistem genelindeki bileşenlerin ve masaüstü bileşenlerinin ayarlayabileceği şekilde ilkeler tanımlamak için araçlardan oluşur. - http://www.freedesktop.org/software/polkit/releases/polkit-0.112.tar.gz - - pam-devel - dbus-devel - glib2-devel - expat-devel - dbus-glib-devel - spidermonkey-devel - - - disable-docs.patch - use-system-locale-in-gobject-api.diff - - system/base/polkit/pspec.xml - - - polkit-devel - Development headers for polkit - polkit geliştirme başlıkları - system.devel - - polkit - glib2-devel - - - /usr/include - /usr/lib/pkgconfig - - - - polkit - - pam - dbus - glib2 - expat - dbus-glib - spidermonkey - - - /etc - /usr/lib - /usr/libexec - /usr/bin - /usr/sbin - /usr/share/locale - /usr/share/polkit-1 - /usr/share/dbus-1 - /usr/share/gir-1.0 - /var/lib/polkit-1 - /lib/systemd - /usr/share/man - /usr/share/doc - - - man/pklocalauthority.8 - man/polkit.8 - man/polkitd.8 - man/pkaction.1 - man/pkcheck.1 - man/pkexec.1 - 70-desktop-policy.conf - - - - - 2014-06-10 - 0.112 - Release bump. - Alihan Öztürk - alihan@pisilinux.org - - - 2014-05-11 - 0.112 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-01 - 0.112 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-28 - 0.111 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-11 - 0.110 - Güncellendi. - PisiLinux Community - admins@pisilinux.org - - - 2013-01-11 - 0.107 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - - - - ConsoleKit2 - http://freedesktop.org/Software/Hal - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - library - system.base - A framework for defining and tracking users, login sessions, and seats - ConsoleKit is a system daemon for tracking what users are logged into the system and how they interact with the computer (e.g. which keyboard and mouse they use). - https://github.com/ConsoleKit2/ConsoleKit2/archive/master.zip - - acl-devel - pam-devel - dbus-devel - udev-devel - zlib-devel - glib2-devel - libX11-devel - polkit-devel - dbus-glib-devel - - system/base/ConsoleKit/pspec.xml - - - ConsoleKit - - acl - pam - dbus - zlib - glib2 - libX11 - polkit - libudev - dbus-glib - - - /etc - /usr/lib/tmpfiles.d/ConsoleKit.conf - /usr/bin - /usr/sbin - /usr/libexec - /lib - /usr/lib - /usr/share/dbus-1 - /usr/share/polkit-1/actions - /usr/share/man - /usr/share/doc - /var - /run - - - ConsoleKit.conf - pam-foreground-compat.ck - - - - ConsoleKit-devel - Development files for ConsoleKit - ConsoleKit için geliştirme dosyaları - system.devel - - ConsoleKit - - - /usr/include - /usr/lib/pkgconfig - - - - - 2015-02-05 - 0.9.2 - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-08-01 - 0.4.6 - Rebuild. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 0.4.6 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-06 - 0.4.6 - Dep Fix - Varol Maksutoğlu - waroi@pisilinux.org - - - 2014-01-09 - 0.4.6 - Add gentoo patches and ConsoleKit.conf - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-08 - 0.4.6 - /var/run => /run - Marcin Bojara - marcin@pisilinux.org - - - 2013-03-04 - 0.4.6 - Version bump - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-08-23 - 0.4.5 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - glib2 - http://www.gtk.org/ - - PisiLinux Community - admins@pisilinux.org - - LGPLv2.1 - library - system.base - La librairie GLib2 de routines C. - A library of handy utility functions - C programlama dili için glib kütüphanesi - glib2 is the low-level core library that forms the basis for projects such as GTK+ and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system. - glib2, GTK+ ve GNOME gibi projelerin temelini oluşturan düşük seviyeli çekirdek kütüphanedir. C için veri yapıları, taşınabilirlik katmanları ve çeşitli çalışma zamanı işlevleri için arabirimler sunar. - mirrors://gnome/glib/2.42/glib-2.42.0.tar.xz - - libpcre-devel - zlib-devel - libxslt - elfutils - docbook-xml - - - revert-warn-glib-compile-schemas.patch - - system/base/glib2/pspec.xml - - - glib2 - - libpcre - zlib - elfutils - libffi - - - /etc/profile.d - /usr/bin - /usr/lib - /usr/share/bash-completion/completions/ - /usr/share/locale - /usr/share/man - /usr/share/doc - /usr/share/glib-2.0 - /usr/share/systemtap - /usr/share/glib-2.0/schemas - - - System.PackageHandler - - - glib2.sh - glib2.csh - - - - glib2-devel - Development files for glib2 - glib2 için geliştirme dosyaları - system.devel - - glib2 - - - /usr/bin/gtester - /usr/bin/gtester-report - /usr/bin/gobject-query - /usr/bin/glib-genmarshal - /usr/bin/glib-gettextize - /usr/bin/glib-mkenums - /usr/include - /usr/lib/glib-2.0/include - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/aclocal - /usr/share/glib-2.0/schemas/gschema.dtd - /usr/share/glib-2.0/gettext - /usr/share/glib-2.0/gdb - /usr/share/gdb/auto-load/libglib-2.0.so.*-gdb.py* - /usr/share/gdb/auto-load/libgobject-2.0.so.*-gdb.py* - /usr/share/man/man3 - /usr/share/man/man1/glib-genmarshal.1 - /usr/share/man/man1/glib-gettextize.1 - /usr/share/man/man1/glib-mkenums.1 - /usr/share/man/man1/gobject-query.1 - /usr/share/man/man1/gtester-report.1 - /usr/share/man/man1/gtester.1 - - - - glib2-32bit - 32-bit shared libraries for glib2 - glib2 için 32-bit paylaşımlı kitaplıklar - emul32 - _emul32 - - libpcre-32bit - zlib-32bit - libffi-32bit - dbus-32bit - - - glib2 - libpcre-32bit - zlib-32bit - libffi-32bit - dbus-32bit - - - /usr/bin/32 - /usr/lib32 - - - System.PackageHandler - - - - glib2-docs - Documentation files for glib2 - Extensive documentation for developers wanting to use the GLib Library - - /usr/share/gtk-doc - - - - - 2014-10-01 - 2.42.0 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 2.40.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-15 - 2.40.0 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-03-29 - 2.38.2 - Minor version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-22 - 2.38.1 - Minor version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-10 - 2.38.0 - Bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-09-05 - 2.36.3 - Add missing method to pakhandler.py - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-26 - 2.36.3 - Fix dep, release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-14 - 2.36.3 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-06-11 - 2.36.0 - add missing dep. - Erdinç Gültekin - erdincgultekin@pisilinux.org - - - 2013-05-16 - 2.36.0 - Path Fixed. - PisiLinux Community - admins@pisilinux.org - - - 2013-03-30 - 2.36.0 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-11-21 - 2.35.2 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - libusb-compat - http://libusb.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - LGPLv2.1 - library - system.base - Userspace access to USB devices - Project's main aim is to create a library for use by user level applications to access USB devices regardless of OS. - mirrors://sourceforge/libusb/libusb-compat-0.1.5.tar.bz2 - - libtool - libusb-devel - - system/base/libusb-compat/pspec.xml - - - libusb-compat - - libusb - - - /usr/lib - /usr/share/doc - - - - libusb-compat-devel - Development files for libusb - system.devel - - libusb-devel - libusb-compat - - - /usr/bin - /usr/include - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - - - - libusb-compat-32bit - 32-bit shared libraries for libXt - emul32 - emul32 - - libusb-32bit - - - libusb-32bit - libusb-compat - - - /usr/lib32 - - - - - 2014-09-08 - 0.1.5 - Rebuild for libusbx libusb changes - Use auto-emul32, cleanup actions.py - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 0.1.5 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 0.1.5 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-07-21 - 0.1.4 - First release - Erdinç Gültekin - admins@pisilinux.org - - - - - - e2fsprogs - http://e2fsprogs.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - Standard ext2/3/4 filesystem utilities - Standart ext2, ext3, ext4 dosya sistemi uygulamaları - e2frprogs fournit les outils de système de fichier à utiliser avec les systèmes de fichier de type ext2. Il prend également en charge les système de fichier de type ext3/4 avec support de la journalisation. - e2fsprogs provides the filesystem utilities for use with the ext2 filesystem. It also supports the ext3/4 filesystem with journaling support. - e2fsprogs ext2 dosya sistemi için standart dosya sistemi uygulamaları sağlar. ext3/4 dosya sistemlerinin günlüğe kaydetme özelliklerini de destekler. - mirrors://sourceforge/e2fsprogs/e2fsprogs-1.42.11.tar.gz - - libblkid-devel - libuuid - gettext - util-linux - - - ntfs-3g.patch - e2fsprogs-1.41.8-strip-me.patch - - system/base/e2fsprogs/pspec.xml - - - e2fsprogs - - libblkid - libuuid - - - /etc - /bin - /usr/bin - /lib - /usr/lib - /sbin - /usr/sbin - /usr/share/et - /usr/share/ss - /usr/share/locale - /usr/share/info - /usr/share/man - /usr/share/doc - - - - e2fsprogs-devel - Development files for e2fsprogs - e2fsprogs için geliştirme dosyaları - system.devel - - e2fsprogs - - - /usr/include - /usr/lib/pkgconfig - /usr/share/man/man3 - - - - - 2014-07-10 - 1.42.11 - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 1.42.9 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-03 - 1.42.9 - Version bump - PisiLinux Community - admins@pisilinux.org - - - 2013-10-28 - 1.42.8 - rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-07-26 - 1.42.8 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-15 - 1.42.7 - New version - Ertan Güven - ertan@pisilinux.org - - - 2012-11-25 - 1.42.6 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - time - ftp://prep.ai.mit.edu/pub/gnu/time - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - A GNU utility for monitoring a program's use of system resources - Bir programın sistem kaynak kullanımını izleyen GNU aracı - time utility runs another program, collects information about the resources used by that program while it is running, and displays the results. - time başka bir programı çalıştırarak o programın sistem kaynaklarını nasıl kullandığını izler ve topladığı bilgileri ekrana basar. - ftp://prep.ai.mit.edu/pub/gnu/time/time-1.7.tar.gz - - time-1.7-destdir.patch - - system/base/time/pspec.xml - - - time - - /usr/bin/ - /usr/share/info - - - - - 2014-05-11 - 1.7 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-01 - 1.7 - Clean time, add patches. - Serdar Soytetir - kaptan@pisilinux.org - - - 2010-10-11 - 1.7 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - json-c - http://oss.metaparadigm.com/json-c - - PisiLinux Community - admins@pisilinux.org - - MIT - library - system.base - A JSON implementation in C - C dilinde JSON gerçeklemesi - json-c implements a reference counting object model that allows you to easily construct JSON objects in C, output them as JSON formatted strings and parse JSON formatted strings back into the C representation of JSON objects. - json-c, C dilinde kolayca JSON nesneleri yaratılmasını sağlayan bir referans sayma modeli gerçekleyen bir kitaplıktır. - https://github.com/json-c/json-c/archive/json-c-0.12-20140410.tar.gz - - wno-werror.patch - - system/base/json-c/pspec.xml - - - json-c - - /usr/share/doc - /usr/share/man - /usr/lib - - - - json-c-devel - Development files for json-c - json-c için geliştirme dosyaları - system.devel - - json-c - - - /usr/include - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - - - - json-c-32bit - 32-bit shared libraries for json-c - emul32 - emul32 - - /usr/lib32 - - - - - 2014-07-04 - 0.12 - Version bump and security update(CVE-2013-6371, CVE-2013-6370). - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 0.11 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 0.11 - rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-07-09 - 0.11 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-04-02 - 0.9 - First release - Erdinç Gültekin - admins@pisilinux.org - - - - - - libpcre - http://www.pcre.org/ - - PisiLinux Community - admins@pisilinux.org - - BSD - library - system.base - Perl-compatible regular expression library - Perl-uyumlu sıradan ifade kütüphanesi - La librairie PCRE (Expressions Régulières Compatible avec Perl) est un ensemble de fonctions implémentant la recherche de motifs de texte à l'aide d'expressions régulières utilisant la même syntaxe et la même sémantique que Perl5. - The PCRE (Perl Compatible Regular Expressions) library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5. - PCRE kütüphanesi, Perl 5 programlama dili sözdizimi ve semantiği ile kalıp eşleştirme (pattern matching) görevini yürüten fonksiyonları barındırır. - http://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.bz2 - - readline-devel - - system/base/libpcre/pspec.xml - - - libpcre - - libgcc - readline - - - /usr/lib - /usr/share/man - /usr/share/doc - /usr/bin - - - - libpcre-devel - Development files for libpcre - libpcre için geliştirme dosyaları - system.devel - - libpcre - - - /usr/include - /usr/share/man/man3 - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/doc/libpcre/html - /usr/bin/pcre-config - /usr/share/man/man1/pcre-config.1* - /usr/share/doc/libpcre/pcre-config.txt - - - - libpcre-32bit - 32-bit shared libraries for libpcre - libpcre için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - readline-32bit - - - libgcc - readline - libpcre - - - /usr/lib32 - - - - - 2015-01-25 - 8.36 - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 8.34 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-03 - 8.34 - Version bump. - Osman Erkan - osman.erkan@pisilinux.org - - - 2013-09-01 - 8.33 - Version bump, clean pcre. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-28 - 8.32 - Fix deps. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-05-20 - 8.32 - adress fixed - Osman Erkan - osman.erkan@pisilinux.org - - - 2013-02-16 - 8.32 - Update - Osman Erkan - osman.erkan@pisilinux.org - - - 2011-03-11 - 8.31 - First release - Erdem Artan - admins@pisilinux.org - - - - - - nano - http://www.nano-editor.org/ - - PisiLinux Community - admins@pisilinux.org - - GPLv3 - app:console - system.base - GNU GPL'd Pico clone with more functionality - Konsol ortamında kullanabileceğiniz bir metin düzenleyicidir. - Nano est un petit éditeur libre et convivial qui a pour but de remplacer Pico, l'éditeur par défaut inclus dans le paquet non-libre Pine. Plutôt que juste copier l'apparence et le ressenti de Pico, nan implémente également certaines fonctionnalité manquantes (ou désactivées par défaut), tel que "rechercher et remplacer" ou "allez à la ligne numéro". - Nano is a small, free and friendly editor which aims to replace Pico, the default editor included in the non-free Pine package. Rather than just copying Pico's look and feel, nano also implements some missing (or disabled by default) features in Pico, such as "search and replace" and "go to line number". - Nano özgür olmayan Pine paketinin içindeki metin düzenleme programı olan Pico'nun yerine geçme hedefini güden küçük, özgür ve kullanışlı bir metin düzenleme programıdır. Pico'nun görünüşünü ve işlevini kopyalamaktan çok, Nano aynı zamanda "ara ve değiştir" ve "satır numarasına git" gibi Pico'da olmayan (veya ön tanımlı olarak kapalı) bazı özellikleri sunar. - http://www.nano-editor.org/dist/v2.3/nano-2.3.5.tar.gz - - ncurses-devel - gettext-devel - slang - - system/base/nano/pspec.xml - - - nano - - ncurses - file - - - /etc - /usr/share/locale - /usr/share/doc/nano - /usr/share/man - /usr/share/info - /usr/share/nano - /usr/bin - /bin - - - - - 2014-07-11 - 2.3.5 - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 2.3.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-26 - 2.3.1 - Fix dep, release bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2011-06-27 - 2.3.1 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - diffutils - http://www.gnu.org/software/diffutils/diffutils.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - Tools to make diffs and compare files - Dosyaları karşılaştırmak ve fark dosyaları oluşturmak için kullanılan araçlar - Vous pouvez utiliser la commande diff pour voir les différences entre deux fichiers en particulier, ou les différences entre deux répertoires fichiers par fichier. Diff peut afficher les différences entre fichiers ligne par ligne dans différents formats pouvant être choisis avec les options de la ligne de commande. - You can use the diff command to show differences between two files, or each corresponding file in two directories. diff outputs differences between files line by line in any of several formats, selectable by command line options. - İki dosya arasındaki ya da iki klasör içindeki dosyaları karşılaştırarak farklılıkları belirleyebileceğiniz araç. Farklılıkları satır satır olarak, komut satırı seçenekleri ile farklı formatta dosyalara yazdırabilirsiniz. - http://ftp.gnu.org/gnu/diffutils/diffutils-3.3.tar.xz - - patch - - system/base/diffutils/pspec.xml - - - diffutils - - /usr/bin - /usr/share/doc - /usr/share/man - /usr/share/info - /usr/share/locale - - - - - 2014-05-11 - 3.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-01 - 3.3 - Version bump, clean diffutils. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-08-23 - 3.2 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - gdbm - http://www.gnu.org/software/gdbm/gdbm.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - library - system.base - Standard GNU database libraries included for compatibility with Perl - Perl uyumlu standart GNU veritabanı kütüphaneleri - GNU dbm est un ensemble de routines de base de données utilisant extensivement les dictionnaires (hashing). Il fonctionne de manière similaire aux routines dbm UNIX standards. - GNU dbm is a set of database routines that use extensible hashing. It works similar to the standard UNIX dbm routines. - GNU dbm genişletilebilir hash yapabilen veritabanı işlevleri sağlar. Standart UNIX dbm uygulamaları ile aynı şekilde çalışır. - mirrors://gnu/gdbm/gdbm-1.11.tar.gz - - gdbm-1.10-zeroheaders.patch - - system/base/gdbm/pspec.xml - - - gdbm - - /usr/bin - /usr/lib - /usr/share/doc - /usr/share/locale - /usr/share/man - /usr/share/info - - - - gdbm-devel - Development files for gdbm - gdbm için geliştirme dosyaları - system.devel - - gdbm - - - /usr/include - - - - - 2014-05-11 - 1.11 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 1.11 - Version bump - PisiLinux Community - admins@pisilinux.org - - - 2013-08-29 - 1.10 - Clean gdbm. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-08-31 - 1.10 - First release - Erdem Artan - admins@pisilinux.org - - - - - - groff - http://www.gnu.org/software/groff/groff.html - - PisiLinux Community - admins@pisilinux.org - - GPLv3+ - BSD - MIT - app:console - system.base - S'occupe de la mise en forme de texte utilisé pour les pages de manuel - A document formatting system - Belge biçimlendirme sistemi - Text Formatierer für man pages - groff is a document formatting system. Groff takes standard text and formatting commands as input and produces formatted output. - groff bir belge biçimlendirme sistemidir. Groff standart metni ve biçimlendirme komutlarını alır ve biçimlendirilmiş çıktı oluşturur. - http://ftp.gnu.org/gnu/groff/groff-1.22.2.tar.gz - - texinfo - - system/base/groff/pspec.xml - - - groff - - texinfo - libgcc - - - /etc - /usr/bin - /usr/lib - /usr/share/groff - /usr/share/X11/app-defaults - - - - groff-doc - system.doc - - groff - - - /usr/share/doc - /usr/share/man - /usr/share/info - - - - - 2014-05-11 - 1.22.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 1.22.2 - Rebuild. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-07-26 - 1.22.2 - Fix dep, release bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-02-16 - 1.22.2 - Updated - PisiLinux Community - admins@pisilinux.org - - - 2012-11-25 - 1.21 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - dhcpcd - http://roy.marples.name/dhcpcd - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - system.base - A dhcp client only - DHCP protokolü için istemci - Un client daemon DHCP conforme aux RFC2131 et RFC1541. dhcpcd obtient une adresse IP ainsi que d'autres informations depuis le serveur DHCP correspondant, configure l'interface réseau automatiquement et essaie de renouveler le bail selont les RFC2131 et EFC1541 en fonction des options de la ligne de commande. - An RFC2131 and RFC1541 compliant DHCP client daemon. dhcpcd gets an IP address and other information from a corresponding DHCP server, configures the network interface automatically, and tries to renew the lease time according to RFC2131 or RFC1541 depending on the command line option. - RFC2131 ve RFC1541 uyumlu bir DHCP istemci servisi.dhcpcd ilgili bir DHCP sunucusundan bir IP adresi ve gerekli diğer bilgileri alır, ağ arayüzünü otomatik olarak yapılandırır ve RFC2131 veya RFC1541 komut satırı özelliğine bağlı olarak kiralama zamanını yenilemeyi dener. - http://ftp.osuosl.org/pub/blfs/conglomeration/dhcpcd/dhcpcd-6.7.1.tar.bz2 - system/base/dhcpcd/pspec.xml - - - dhcpcd - - libudev - - - /etc - /lib/dhcpcd - /usr/lib/dhcpcd/dev/udev.so - /sbin - /usr/share/doc - /usr/share/man - /var/lib/dhcpcd - - - - - 2015-02-03 - 6.7.1 - Version bump. - Hakan Yıldız - hknyldz93@gmail.com - - - 2014-05-11 - 6.3.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-03 - 6.3.2 - Version bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-10-31 - 6.0.5 - Really revert back to 6.0.5. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-10-28 - 6.0.5 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-01-14 - 5.6.7 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 5.6.1 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - libpng - http://www.libpng.org/ - - PisiLinux Community - admins@pisilinux.org - - as-is - library - system.base - Portable Network Graphics library - PNG kütüphanesi - Le format de Graphique Réseau Portable (Portable Network Graphics - PNG) a été conçu pour remplacer le format GIF plus simple et vieillissant ainsi que, d'une certaine manière, le format TIFF beaucoup plus complexe. L'objectif principal du projet est de se concentrer sur deux aspects majeurs : La toile mondiale (World Wide Web - WWW) et l'édition d'image. - The Portable Network Graphics (PNG) format was designed to replace the older and simpler GIF format and, to some extent, the much more complex TIFF format. Project's main aim is to concentrate on two major uses: the World Wide Web (WWW) and image-editing. - Taşınabilir Ağ Grafikleri (PNG) formatı eski ve daha basit GIF formatının yerine geçmek ve daha karmaşık yapıdaki TIFF formatını biraz daha genişletmek için tasarlanmıştır. Projenin ana hedefi iki önemli parça üzerine konsantre olmaktır: World Wide Web (WWW) ve resim düzenleme. - mirrors://sourceforge/libpng/libpng-1.6.15.tar.xz - - zlib - - - libpng-1.6.15-apng.patch.gz - libpng-multilib.patch - - system/base/libpng/pspec.xml - - - libpng - - zlib - - - /usr/lib - /usr/share/doc - - - - libpng-devel - Development files for libpng - libpng için geliştirme dosyaları - system.devel - - libpng - - - /usr/bin - /usr/include - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/man - - - - libpng-32bit - 32-bit shared libraries for libpng - libpng için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - zlib-32bit - - - libpng - zlib-32bit - - - /usr/lib32 - - - - - 2014-12-05 - 1.6.15 - Version bump. - Osman Erkan - osman.erkan@pisilinux.org - - - 2014-07-07 - 1.6.12 - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-05-11 - 1.6.10 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-29 - 1.6.10 - Version bump - PisiLinux Community - admins@pisilinux.org - - - 2013-10-30 - 1.5.17 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-01-14 - 1.5.14 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-11-03 - 1.5.13 - First release - Erdem Artan - admins@pisilinux.org - - - - - - ncompress - http://ncompress.sourceforge.net - - PisiLinux Community - admins@pisilinux.org - - public-domain - app:console - system.base - Un autre outil de décompression de données pour compatibilité - Another uncompressor for compatibility - Bir başka sıkışmış dosya açma programı - Ein weiterer Nichtkompressor zu Kompatibilitätszwecken - The ncompress package contains the compress and uncompress file compression and decompression utilities, which are compatible with the original UNIX compress utility (.Z file extensions). These utilities can't handle gzipped (.gz file extensions) files, but gzip can handle compressed files. - mirrors://sourceforge/ncompress/ncompress-4.2.4.4.tar.gz - - ncompress-4.2.4-make.patch - ncompress-4.2.4-lfs2.patch - ncompress-2GB.patch - ncompress-4.2.4-endians.patch - - system/base/ncompress/pspec.xml - - - ncompress - - /usr/bin - /usr/share/man - - - - - 2014-05-11 - 4.2.4.4 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2011-12-20 - 4.2.4.4 - First release - Pisi Linux Admins - admins@pisilinux.org - - - - - - libcap-ng - http://people.redhat.com/sgrubb/libcap-ng - - PisiLinux Community - admins@pisilinux.org - - LGPLv2+ - library - system.base - An alternate POSIX capabilities library - Alternatif bir POSIX yetenekleri kütüphanesi - libcap-ng is a library that makes using POSIX capabilities easier. - libcap-ng POSIX yeteneklerinin yönetimini kolaylaştıran bir kütüphanedir. - http://people.redhat.com/sgrubb/libcap-ng/libcap-ng-0.7.3.tar.gz - - attr - python - - system/base/libcap-ng/pspec.xml - - - libcap-ng - - /usr/lib - /usr/share/doc - - - - python-libcap-ng - Python bindings for libcap-ng - Python için libcap-ng bağlayıcıları - programming.language.python - - libcap-ng - - - /usr/lib/python* - - - - libcap-ng-utils - Utilities to analyse the POSIX capabilities on running processes - Çalışan süreçlerin sahip olduğu POSIX yeteneklerini incelemeye yarayan araçlar - util.admin - - libcap-ng - - - /usr/bin - /usr/share/man/man8/* - - - - libcap-ng-devel - Development files for libcap-ng - libcap-ng için geliştirme dosyaları - system.devel - - libcap-ng - - - /usr/share/aclocal - /usr/include - /usr/lib/pkgconfig - /usr/share/man/man3 - - - - - 2014-05-11 - 0.7.3 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 0.7.3 - Rebuild - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-11 - 0.7.3 - Güncellendi. - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 0.7 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - dbus-python - http://dbus.freedesktop.org/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - AFL-2.1 - library - system.base - D-Bus Python bindings - D-Bus için Python bağlayıcıları - dbus-python provides a Python module which wraps the D-Bus programming API. - http://dbus.freedesktop.org/releases/dbus-python/dbus-python-1.2.0.tar.gz - - python3 - dbus-devel - dbus-glib - glib2-devel - - - suppress-warnings.patch - - system/base/dbus-python/pspec.xml - - - dbus-python-common - Common dbus-python files shared between dbus-python and dbus-python3 - - dbus - - - /usr/include - /usr/lib/pkgconfig - /usr/share/doc - - - - dbus-python - - dbus-python-common - python - dbus - glib2 - dbus-glib - - - /usr/lib/python2* - - - - dbus-python3 - D-Bus Python3 bindings - programming.language.python - - dbus-python-common - python3 - dbus - glib2 - dbus-glib - - - /usr/lib/python3* - - - - - 2014-05-31 - 1.2.0 - Release bump. - Kamil Atlı - suvarice@gmail.com - - - 2014-05-11 - 1.2.0 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-28 - 1.2.0 - rebuild. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-23 - 1.2.0 - Version bump. Remove dbus-devel from runtime dependencies. - Marcin Bojara - marcin@pisilinux.org - - - 2013-04-25 - 1.1.1 - Dep Fixed. - PisiLinux Community - admins@pisilinux.org - - - 2012-11-10 - 1.1.1 - First release - Marcin Bojara - marcin@pisilinux.org - - - - - - iputils - http://www.linux-ipv6.org - - PisiLinux Community - admins@pisilinux.org - - BSD - app:console - system.base - Network monitoring tools including ping and ping6 - ping ve ping6 uygulamalarını da içeren ağ izleme araçları - Iputils contient les outils de surveillance réseau incluant ping et ping6. - iputils contains network monitoring tools including ping and ping6. - Iputils, ping ve ping6 gibi ağ izleme araçlarını içeren bir pakettir. - http://www.skbuff.net/iputils/iputils-s20121221.tar.bz2 - - ifenslave/ifenslave.c - - - openssl-devel - libidn-devel - gnutls-devel - - - 021109-uclibc-no-ether_ntohost.patch - iputils-20121221-printf-size.patch - iputils-20121221-owl-pingsock.diff - iputils-20121221-openssl.patch - iputils-20121221-makefile.patch - iputils-20121221-crypto-build.patch - iputils-20100418-so_mark.patch - iputils-20071127-nonroot-floodping.patch - iputils-20071127-kernel-ifaddr.patch - fedora/iputils-20020124-countermeasures.patch - fedora/iputils-20020927-ping-subint.patch - fedora/iputils-20070202-traffic_class.patch - fedora/iputils-20100418-convtoint.patch - docs.patch - - system/base/iputils/pspec.xml - - - iputils - - libcap - gnutls - - - /bin - /usr/bin - /usr/sbin - /sbin - /lib/systemd/system - /etc/conf.d/rdisc - /usr/share/doc - /usr/share/man - - - man/arping.8 - man/clockdiff.8 - man/ping.8 - man/rarpd.8 - man/rdisc.8 - man/tracepath.8 - man/traceroute6.8 - ifenslave/ifenslave.8 - ifenslave/README.bonding - fedora/rdisc.sysconfig - fedora/rdisc.service - - - - - 2014-05-11 - 20121221 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-26 - 20121221 - Fix dep, release bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-01-14 - 20121221 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 20101006 - First release - PisiLinux Community - admins@pisilinux.org - - - - - - util-linux - http://userweb.kernel.org/~kzak/util-linux-ng/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - library - system.base - Divers utilitaires Linux utiles. - Various useful Linux utilities - Çeşitli kullanışlı Linux araçları - The util-linux package contains a large variety of low-level system utilities that are necessary for a Linux system to function. - util-linux paketi, bir Linux sisteminin işlevsel olması için gerekli olan birçok düşük seviye sistem uygulamasını içerir. - http://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.1.tar.xz - - zlib - audit - shadow - ncurses - libcap-ng-devel - utempter-devel - - - ntfs-3g.patch - 0001-libmount-FS-id-and-parent-ID-could-be-zero.patch - 0001-switch_root-verify-initramfs-by-f_type-not-devno.patch - move_is_mountinfo.patch - upstream/util-linux-ng-2.21-login-lastlog.patch - - system/base/util-linux/pspec.xml - - - util-linux - - libuuid - libblkid - zlib - perl - audit - ncurses - libudev - utempter - libcap-ng - - - /etc - /bin - /sbin - /usr/bin - /usr/sbin - /usr/share/doc - /usr/share/man - /usr/share/info - /usr/share/misc - /usr/share/getopt - /usr/share/bash-completion/completions - /usr/share/locale - /usr/include - /usr/lib - /lib - - - - uuidd - Helper daemon to guarantee uniqueness of time-based UUIDs - Zaman tabanlı UUID'lerin benzersizliğini garantileyen sistem hizmeti - service - app:console - util.misc - - libuuid - - - /usr/bin/uuidgen - /usr/sbin/uuidd - /usr/share/man/man1/uuidgen.1 - /usr/share/man/man8/uuidd.8 - - - - libuuid - A library for UUID processing - UUID üretimi için bir kitaplık - library - - /usr/share/man/man3/uuid* - /lib/libuuid.* - /usr/lib/libuuid.so - - - - libuuid-devel - libuuid header files - header - system.devel - - libuuid - - - /usr/include/uuid/* - /usr/lib/pkgconfig/ - /usr/lib32/pkgconfig/uuid.pc - /usr/lib32/pkgconfig/blkid.pc - - - - libblkid - A library for block device identifying - Disk tanımlama için bir kitaplık - library - - libuuid - - - /usr/share/man/man3/libblkid* - /usr/share/man/man8/blkid* - /lib/libblkid.* - /usr/lib/libblkid.so - - - - libblkid-devel - libblkid header files - header - system.devel - - libblkid - - - /usr/include/blkid/* - /usr/lib/pkgconfig/blkid.pc - - - - libuuid-32bit - 32-bit shared libraries for libuuid - libuuid için 32-bit paylaşımlı kitaplıklar - emul32 - emul32 - - libuuid - - - /usr/lib32/libuuid.* - - - - libblkid-32bit - 32-bit shared libraries for libblkid - emul32 - emul32 - - libblkid - libuuid-32bit - - - /usr/lib32/libblkid.* - - - - - 2014-05-11 - 2.24.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-08 - 2.24.1 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-01-20 - 2.24 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-27 - 2.22.2 - Move pc files to devel pack, rebuild - PisiLinux Community - admins@pisilinux.org - - - 2013-07-26 - 2.22.2 - Release bump for rebuild. - PisiLinux Community - admins@pisilinux.org - - - 2013-01-14 - 2.22.2 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-11-17 - 2.22.1 - First release - Marcin Bojara - marcin@pisilinux.org - - - system FIXME @@ -20055,6 +20904,17 @@ admins@pisilinux.org + + desktop.toolkit.qt5 + FIXME + FIXME + FIXME + programming + + PisiLinux Community + admins@pisilinux.org + + desktop.toolkit.motif FIXME @@ -20473,39 +21333,6 @@ admins@pisilinux.org - - desktop.lxde - FIXME - FIXME - FIXME - lxde.desktop - - PisiLinux Community - admins@pisilinux.org - - - - desktop.lxde.addon - FIXME - FIXME - FIXME - lxde.addon - - PisiLinux Community - admins@pisilinux.org - - - - desktop.lxde.base - FIXME - FIXME - FIXME - lxde.desktop - - PisiLinux Community - admins@pisilinux.org - - desktop.lxqt FIXME @@ -20561,6 +21388,17 @@ admins@pisilinux.org + + kernel.tools + Kernel Tools + Kernel Tools; perf, cpupowertools + FIXME + system + + PisiLinux Community + admins@pisilinux.org + + x11 FIXME @@ -21883,30 +22721,14 @@ Escritorio Razor-qt razor-qt - - lxde.desktop - Bureau LXDE - LXDE Desktop - LXDE Desktop - LXDE Masaüstü - Skrivbord, LXDE - Escritorio LXDE - preferences-desktop - - - lxde.addon - Lxde Desktop Addons - Lxde Masaüstü Araçları - preferences-desktop - lxqt.desktop - Bureau LXQT - LXQT Desktop - LXQT Desktop - LXQT Masaüstü - Skrivbord, LXQT - Escritorio LXQT + Bureau Lxqt + Lxqt Desktop + Lxqt Desktop + Lxqt Masaüstü + Skrivbord, Lxqt + Escritorio Lxqt preferences-desktop diff --git a/pisi-index.xml.sha1sum b/pisi-index.xml.sha1sum index ecbed250..3309cfa0 100644 --- a/pisi-index.xml.sha1sum +++ b/pisi-index.xml.sha1sum @@ -1 +1 @@ -2706ca17146fbaf0f782335332a3e46b83b5fec0 \ No newline at end of file +90741bd70b3e783d1038397e959a9c83dfd25f81 \ No newline at end of file diff --git a/pisi-index.xml.xz b/pisi-index.xml.xz index d264cb96d6b55b66a05ed6aa3bc224dec20a5198..0579a3957b1d2ffd307fb93c11df6888ceff7a50 100644 GIT binary patch literal 95480 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 literal 93380 zcmV(nK=Qx+H+ooF0004LBHlIv03iV!0000G&sfaq%N6hbT>u^w1tnGy5XnKx*>d2p z#_}gDgt{Xixq0B$#HM)E(}jmL{lXqj=n0eYVR0 zuU~XvlY7t&#{7YaD}Ws7aUcH}KH>GG=1j0v>!Yi28{4}_Ll*v=hK49;1oLTyl6bi_ za{oElroM{GV|@S9v2&wMX!fQKR4~D1tV_9~@F2o;x5Id>M!#1Wrl>t+{q|*jv$+5`cPByjOn*Dm_Aek9kE+_0dSrK z$(1Y51We7M4npewLba_rRojy|I85)Ts%M0F&@gso6%gF(&6+*|S5P<@TD=nGADmL6 z8}@u?E}R7M8`u?yU(_G%1~VbjOQE|nDJ{Y+D}h`a{i8-F-&(B@D6(z6ZojRn&b1g# zitk`V9G?>L3wZQ>CrlH2UY_+#-m0JKA`Vft!usy+2l|H|II!0Sq$=bElqw-B=^HVC z@tut=S!{a|QS%4L^)+5(&f|aM1GeX$C0{evlCJm8`a(ITO7Py06Wau zjAGu3tyKTuym#1}f>kTjnVB@0S{a`y7GhFR{<6Bbb6Dz$s%EFYx-vOSPhc*YeL{ZK3eVt!@ zC1xUOxwm8VGS{(scUgfj=H%mME_$Vew=43IA{0+j=-%7P`P+F*-6tgvZ?+ebYD>`Y ztRq<{{Qr9+RZ`XB>~6oFHJR{pL!u=osWS^HFsHI`cHT2&Ek{Uxa{C@MiV%SV`bt^% zF9-kZ)gD46Ba?oM5S#}rNhl_YWA^IhvG3O|7?SfDwe>!V7zx{8pTI6{Rn4LXi>q9x z6(RD=A_9xb@>81AawdC&YC=bp(s|c3!arK8=df7&Jz8$2F-F-O0<0z3RI+;o5HKoG zMC#j(SGq1hVm+qI9f*2Myqa77NZd%Tuj|Xu?ijyYOby+h9bt8j-&vs0^{GbpCXKI? z$oh~}n6kdZB6jG&=vt(_mso2nJ$|NB$?q^&c+;<*6?Xx^NTQbVn05Qb4Rz$Gq9q$$ z;5-9=R#cV-FYMB6DRxIqj&|_wW>k78Say5_|6OJ1uRjZsZzYqpEuv|Z@p0p@&YVG! z#ztkdHIE;8<`GaAmiDypeB^6o;RqYbg5J7Q;)JH%+1b^?Nvy}Mm(S zu|{%AeUKX=(^k4&UB+>YcDo1Xc(fms!=+Ldm~9|yb`FIz+m)=LX)n#Vg33Vg4%StR z`-#-L8*O2T;e5Hkk@|b?=^eHfk-l(H40XWbHLWR&oG^r~Dpg1^B}4hSmvq?aaBx5- z1>$Kn_nG_4BurVAUd6+xV3U*WZK$O$+K+NuT2c>kE)&SCW1dbO@U|DB_gLiFFqI2H zZn8r5nj@%Etb#0!=@=_`x%qaZ^kzH)AL%IaMd#Ox{@XiklkD&bXQ)Ktx}D7$8E=!E zMAi^>@8TEpliHgoWC*2i{kh4rd4?FrQb=qzG!@B57JoRBygM}IR1fsq!qV#bZP$sx zPAy0@m<#c@$GyCu(kqS-QCu4&Q2R9kvSO*h>#6NE8e|WFZoYyowX^Spy1U(a6e12g zXI2bW+dSX|Dgh9kH~7J)Y}Zs{A^XjSfdHjs7WK0+xz|d4S(|?p>IK#-D;rUv;8j`M zidp8xBg6%R%mD%8ebMc*mwn7MZBITyZjiJzt>k_4ZRC3zhiaz*?JayW`V4!@OtN`V z%gGe6#e`h{l*Nw@*^i~1K;;nsurovx{!6GU%+6v{bba$tNJB>(1$nJ5FACUsUKwJ` z){l#&w&;~UA;stExI|kOzt9O8RowsMGpZbt`uI*(OQS61afMKm)xe_w2RwJp;Kx{H zbIvR3(L08j&GbNd&6>)lxt`$T$3eV_r#ar} zh=qTU7kERAHuM>rUqI1+1UP{&$L`5@8EV;?C1VQvTHX%YB!$5cc-u2j2JbaIq4%KP zrzi41)NeLYLajaWIr=@;>J;g*zo1N+zjJN%1^Jhkss==*y6V4fQTDaXwwR5vj=GQ|KO!(@q3aI!1CMCYB(u3Q z(?LJEX_xCmVWQb^bLu-b0!!^yUDqqQ(vrNrCPd=%<62vgeZa$lExR*2*U0B};z*8| z+JQKlV(5}2W%eH_5UNUT?|>l(cLK*z#5f{-h9Nwn(N(^;QC^tog3=JX=btwEDAXuW z(Q()HaFdq^kY7_D^}<|TBS#a1{e5(Y9|)K1r}4;D1-|WLt49;zp|eh&6P92YZcDYcQ>A*1h}>Wk-gYOao|@Or)H!| z(QV*#Vh8B3qaSulp2F=|SW;=7VMKSfkiKJ9ptj0n)}B;jD-Uwx$tj|{kk1Mc2odgR z3}Q9&R=;7YR`XAyms87HTw^l+gEDt6)jCb|kyj8X)8y_E3`8KV)_c-#%AJx79X0n+ zKE@X&pxJYenKWu)Q|BK(02U60le_8M;wZKV0{)Ajv1k-~B}Fo#g)m$uPl6@pi1c+Z zw`Ti_&kAj88K$pCCXWm1LZa?~VT782w&>$%#~Sc@bzedv)?&0SpjIPyXg!`Vnx=5f zkM+FXeJ^tkOj{2m@Y}oeMI=Xy{pMH8A*~rpp`5RCvIX*Lb^yuhHDJ5m7|y>C+Sk#u zIsy0ePX~VuDUK*fU^Qg|woQCj!^mBumjvb#IVPqIIF#B-s?L?2%w%@i0L9TFW$iv@ zDLp^`jW8lqeo0x5jsgWO=m?llJ6;Uv#cy_j3dlX!|$#zsF+$&TVbw_aBj@wsC+W9?n<&#)sa9o(=Y)WgU+h{B( zQl?G=gDoG~pCh7q93cx2!E0qkfYYv|;|})H|G8>pL~s!OV-eW5f{>f%d~$Wu12SyxW+L~1@3^Mr#!XFnc+5bGxHz0fR2J>#VtWT^~sh} z&Zz0wfPvv9A!?B=?AOWtWn~kl8>yGQ*|&G~vLsKLYRMI$T*d>K13=C9u7oV1#clKQw(*#HS?aEeL*NJUGZz&gAR**Udc# zn|~CAi*~)sIt2~t^%lL;n)pZ;Z8wpWE;#e=T`k0KqX|)7j2hJjO~t#VAGBw(N9yP7 z>oazRNI5kIf>^$8%N7{Y1AR*H34^pO51|J@6>nD47OhJKj;YQ?CS~QFm2I zlnNPWc_f!p>YuSvM&bEx^VJYo8O`IDy$(>rQuQ?C^@if^?`fM(P(Of;$ZoLgd?F<> zscyJ_v!kZq{FkDmLH!atU9+xU3?X7y(F)^4C6biAb%U?HGn>%3{B7JBOAcc5#)qJT zIe8{gPG`;oHM=kyynD^TmT(l72vFbDs#PxPvbp@7+_El119}QRNU2Oi3|R3#RZe2% zE4}S~6|PPOczX8$_3ADxr%8A&1smR%v==CA&fg>yWl=jp5*t|R&2K>ki(j?|49)z7 zoC}|E+b%THh6S#Moka>u8O7TdB5h=V)azz~Londqb8Xi`5@&YctrlFA}GnChaA;6U9A;-bQ_QA1ot<#5}cf74SkH ztKKMfD`ie73-D25DnSc?TRBki3Hk%cF8Wxq=F6J?^fiMg0bi>BPM81!16_?N&LAd> z;}Oeteyd85iOi2*kJb4zy?Q?1pe6tHn4tV!_85l>~ zWX^{~%)UH#h=gespa{Px+6IoyDjPiI6iiU#>B#ubJZ**Qc4s$wGho#%?xbX>rBKQx z|0(f=ST|pmY)v#j{JusJUQpmoZy&)P;Kze5qXA{!MP<#EYFSAtr-zq|{*PKP6ulB% zlfS5=LaygU5Q<*ERg+y+c2cD@(Mbs1FTSjMPhO?!%UiB6){>biJ)`_0*6Nbk@S7tZ zyuZ_KU+awGw~)a{WtI%r{*z(dwxa$5I858wzDKW@eaC*C*XC;ZvEt4NQL(0x7fR@; z4j7?M>ZEydqsS$8Hn;5f5f@E{v$f;vrQb8AlJ4 z%3Dg%al(3wsoi8K&^c=ln0l+Fj&Zt2h(vNb2S9aDPK4wA;yz5ncAf6Oan7D;0nyNW(eoY2S+=?i98P-is9|8YXC-U6(ZkE(b6G?v} zQgpGTbP8p0@h8w?Y6gJEVGd1YkP+xrh^wXp9K)0_f0n^T|o0c9%IU)$N6i1fE53A7L))Y982w7;=lsWC0SYnv3%rpZ3#|`WX zp5=s?sguqi5n0+PtRE}fJe8V?GhWpL{30zgW3zFT87<&{duzbOTRg26mXvaZNsPb# z(9x{p*At@<9?~J{M&IdGXh0!wA=2~*9$S_Ul5E_LWvj+D2x>IEWbld)USC%^f@%>3 zt}sHrE&_r%i3HCnD1r~?dX%c4NKn@v8Y4N#x^c&SSb=KKxl^-5>qTO7QyvX3sXlKv zm$cI}G<*HqHv#Y^Pl2CKHDm_!g3gYjlCAez41T0Q--v#wk)I3&jKA-I5Oo{C&hDSW zC5PZkmuoMTY{cLTrYK61pOC64S679u@CWkiNnVmw)UkJu`Q~Y4+6 z8gD}N@Kx;2j?i=<1RU=jsnF9KaZ&MKJD@>WlTv6|6Eul3^a(A3Q)>$A^0^;=4Q_eL zOBp{7hy(LssDl%)#P5ckbtfHc>nB`7-@1!=iHvad&5sS-1hF)iIU^w6zHcf(-S0qMIilVkktVw;Mz#!<2dAE??m(D#!cr(ieu<`5;b64w;q`j<+NU@r=5;~w}r?0*b%Qz zUjTvN;5Wv7YLB1du<2&tgAa{Qx0!;tdEV$DDmPY)9+1JI$^p3vcP7@ry#R*Rfw*hM z8|PIGwTW1HM=SWJA-B-T?6V!&WbmK1<*l&-EWVi1j|I#U|1d3sd{1gN@7)L-DlZvL z+c_4CsH_Q^lk~zu*i5*%=8l@Wq}#Z?-soEeNpfl|d2gH;p z;=k?UkVI?Kzt1o11I#K2s0JHkBT%JAK45k8HPdr?BzMagu&$k!GgYS)5TTf|za4vf zcR9m_dyKax^REPqhX=^Nr4W9l`JF%=-p>4b(DFvBv2El9ze*1HsOC&E51L}y#foShVeKNekWOB! zml`dCcM}W%)l%X;yW9&{`IE!@wdjh^#1>hQ_Ed{db}L)Nx{mRgyfkTo@FEL`uXLVr z?m6Y?pz}#XB_ok|;j``t*H;Q_;$zm_W@OAXqN6*N*a~-BYMmAKYrAtOW3CT$;_aCH-LQlrw;e4lk`1*>D$)c|b)$0#ex>hPo{s`aYxa~aVBat)(2 z5AjU3cjRFOC8kgqd@P@suNQrfhYlg5Me?Wzqjn4elu|e_-8iY0k@gWrucRrnjzhC} zf)-E>6&(W&$_;=|H$$q6SES{K87Quh$`?01I8 zz(puCW`ODjP5(K8OSYbqmWABX#qKh0MlR7o+#thp!7IwO%9pUU?f%0h(akNW64o*| zDJAE-Ne3Za!9OOpghtutBO*8X==ep&zYm?mx;jVeMrp`jBkweoK1VxEiB1YFM>q0* zwDdW!mP(-UJRpUYz~q`K*$!;)6UZK78RP`wEH60{9{=GAGsTT7<@2QnI*$ILtaE(SrRgfWE+UP8z|pGti}Lx*Dl zlB^N^q+`SWcW>H9V3||mZK7-j6hwHEMFFiQ--VT-gtG|DjI*&4g(5ONRd0@MTNM==ECCdJ)qDW_4M|#l@EW z<3I;Le0@B--xZ8@|NaqG(tg$wJ`Lj=IF3!AIzqdZv+qxYyP|yq!q*UO@QU_c>QNunMY6z z0Vj-ja=c28oVbLZp8GLCq(DW0apb%_tJ)h=SMzB&M^@N@rjrdI|e0@MfG`=fCxsxR}I6A9;fhJj{ndmg15l{I7)FPeh$APnU^PpHQek7ig=ht)%aSX*8Osfu?1+*MWwC*+#8(>A7z5RGEeGvEU zY_0Q{k7aODy_c6pwr*3ZW%6&hIKvzlHnAOhpAfj4im*k(Ep*YX{0FKYrPhfZ0O>*D za?^*;1X47r@S%-pvQ1tY3=L@@b8&F&4?!%RDc|HZD1JI~V2J*sH3@`dMeb&vkad%6XZN3GanpV8wgP;av)D#B&x^+%6z{sj z*k-QJfSoO_Q$yOoASf+Ih$+m+Fp7+?;{KEGI+>Jl-4ldJA)^l+?RT?5S7sbjPCKMB zzVR!&8~QS^gwOy&A5RgF4`tomH+$}*+Sdlc8|R8QUpL9>14w0jq-!n{YtD$J24`eY z3+nxxjzGUy5`w_%Qp>w7;!>jV>~qgqGYD`xh2-QxU1QW-4$1J*7HnulyDO z7vjKrQ_-$)Y^!i{o*Qk|!SgUj!;qK*E?{eGJ?wOWF{$-GXEvTLa*r+<(OUW&Yugm7 zhbhRE!J8zc>2bKBpiJLOgDAKfwL$T}`!_~5MZuA5UH)^It@6Lu)5hDd{1y+sZbB2( z2IxQU@vnyF`T!R+I#~G}4f7%;@bZ$eW=9@|#ENZ3DpAYhPrA@9l1n=?^rt;f+eA(B ztW;ZprdN&J7=K2e%bC&|I^SYeqjcBnURvM73ro3!cB=iTx1sAz zo!*^+Vq0|CWVx7ZC3H@Z#EwiSnH}F|Ol45!JrR9ze+3Fg#CHKT zyb0R^xmYBnoiV1GF~%xryOiFMccapmUM78L!X_4+l8)QOUSi9jV$2)K|L%1#-l>}L z(31AxO8OR`&aD4H83CzPWBic0Pk#LBUQ(np`6es#smo%RU*u_WNiJ2-om)s22m}kr z*C#g1QM7e#JNT_{ir}0A^e+T91RUgJ{Zl;Z(aW6+Z%M*GFR0oSgHrb~Jb-fHnfAP} z(um>?D4o=V#iCbG??pv@+Z%Ozj?$Z?vbGM~$3Dx~3hxN-Tp+y}kA8v6>EUF^C~7D~ z?bXX9D-A5I@>^r(t}uY{fDvug-DeKVbmsTzv8p1?K3_dZfeNhq>H3;EziihFy+%eN zRokS~l4D=O{jkBsAvqU&1G?(FVs`qd!67Cyv5cYm>^{cL(Tw(DXuO@WiIjD}n-p8v7X$gVNOv^D5k*`gzlG3q?xvV; z`wIHefCc#t&6-50e&JiWWN+5?n$Xn!hxl-81jIA4)$X*>27%b}P$T#}c>Zzm!tkyS#X5JTFtg8`i!8fw)LT7YgS z+#0{}eUTEyB&iwm*NjQzfVtAP2?@yISO!b}ac`2s%dxD%P_hcTW*T}X+u zjOvBeI*8-A6(df<8EU$FELpVC7*7zjD9~bW)o)gcH<=ugo9$S@G4dzoLQ`DOKG_2oPm4O@U zgu`wV1Ir=FH>6Fzbstz+2Pz^9tCsJ2q7M?htu2=$SR#++l(XGfW`xZV2PRH?H&7T5 zFhbD_r}!{Pe#2)6v_(`tJ!rVWZgvdoF4|c?OZuj018n|OVex9Q^H}T1EmqVyY0^g` z><+)qxt=Fkq}eh;^R=d)r$CktCG@22u zZ*(kR;d8e^ndCxpRos%RP!h|0tGb}>pGo-2PaGi`itimagqTSD3U2U&X2B*MU2r0N zO-&}fUdqE80bfqp8|my`K+ATEYZf2roa5~oKfZ^3yw}zgCFI}|Elbv?rQ2W)N!t@+G{mtgC(~Ytp&7eZVqn0 zI~MBQ51#6m#+k;T6_kR(Uz=vX7j&hIL}`YAX(eEGSg6s@KYT)tyATnyi|@9&B=Scb ziMVXmK>#$negCEV{@3N$&-^xQukTrHoFzoJ6)+Hcj_IUj`m9bGi#q0YHdDr7 z{`i1iitSk7FY}P$`YDP&{QECXOVpvnHDjf(V$ppP%2RAh3k-)XvKE%>_4=DrDaDJC zTNTlUkQ7F3G3{F5t!(3`Bfp6`ehh9S9Bf_Rj8c4ZY?SFSD`8l2taioYa-lf*HE*@I zld%kC=Bn+qSm)De%;Hj|84Nprt)Q@?RHYqiWBtU((J)ApDk$0Ch)g@1g6pupV(q5r zLSsgjx`(P$FJRbW@=G%uT&wD5#QF!?%WHpWZidXuSwyh%-1vHSNo zE}NujTd*d?0mJ-I8c1KrKTek1a>=2WDu6I^x1(P$L$jB|eD z${^oKoP-OcMu~!C3~v&iHAKtqGh0{lpR~;zh*BRpD@smy-~e7G3tlPXkSA!Z)++|}Z|!58 zfQwq^;vQ8Z;@v991~qhRHo@^&hiQhTf8_wquF>LckeYIo^<73$V+A&T_J+goB`Ed$ zc*fQk_ZbT)9@H9KeA1$r6mtG=01hXiIK9T8$4$%pwuFZaCP~h-!U;`WkdCf`AK%g< zoya!El@MfKW%2{K+Dq0Y*zK}^PiGkRs$q%7Na2DdZ8*d z#8|$+s~>V3IpnG@&g|$0XE>u!2xIU?T#> zhv_#b3jEURE;S-$XOb4-(T2EVKDJ&nGn{EZbn~g)EfIpp_PiywW*@{a6_xU^rK=W}7g*8J9uC*hyoE|xAMeSNtei988<@U|2+geTZFKCMU27_OlqZ-@|Q!Sz( z+h~Y1sJ+Y|NoOUh1+eBi3v=+0UJ>%Oo||*Z+*DP5g(9vFi$@HQH5)fRzCIUFI@`$E z%Ps7fBLVbIE3YAJj%480hhU5ftyva!h?d+UdsqO`+KCi01Jbj{4JF(kb=oqBVvQ5Y zd!b}55S5}?q_yh;D-#EU{1>415|}w>jXr%zO{(rg=f#*n{n!lkd%;t;Nz?z=9Dr&; zHuPZs8A-=h@Kjm8C-ZZ`T_kD|_P+E|_HUJvjGY8`_`E2P9B*WuVv<*kt-VHD6ol)} zQsoM5T1*c&N#~~;f8_GB-%n7lwEQ-`XO^o6)NIP}k)8^Ulzfq7n=XnAkymqGj{{qGZ@3u3z2+} zipQ_#^3a)7sU<*g5^o475(*iv+T^yltYcw@Q^m{h z?B*OHL(@R`hB(sD=aTe!XJZZho*~Fr_wgrtk7$luo81nN6Xij+S-cVg7bMo2cuAK< zRIq_Z##$D{j*z2kLF^jd6md#)x0>xIxE}~euj>_6lq6s@_(yx9t-@d(UsOe59zn-w zW|5b1FcemR0O_447hHguibK{J8R3p7nEofvdT0cQ#SUC4CrmCpr_4C4nxs{WeI}lg zDVAdnYrk=0VLlUaDE4+L;5K#7h~oDbvEU6Z#EmQ zZ-Enqf#G3r3L|nX+6NF@M$(o0RTS)qDx&yt5VpLE)(D_8L_PVWjezLE%zhmFoOuE* zD|)tvak1r^uer)hv#A=Isn%_PjlPSRa&%A@YO#8Gtt2<0@AHla+X34!V7UoNtfS9vD;la- z9-S(#5R>s{K}$avyJRN{C;gvi{JTH3PaarTw`0RDkYpt59aD)__mJOI3`VC@q-5O? z_A*}KEFgL|OUcsO{2fiC7Q3c-VPTjEh+w!pFq_GM;-v|*(Q!JBM1n>qFk1pZC!npx z4}PPj$+=4`;Quz!5D{aq-7?ZV3yFv#=U~?(uCS#v7bmG2E@uLnV&hfS#f{M7-|gLF zg>3Swo?D#wq2Ml`78bQh6stAi3T%K&w{FIZ_~H%g)NgWogIwbFs|cj}-2#Kb)b z(sBK(vzN6-Tr=E88h@-(lid)1o63b0W?U~l8i&rPf`2B75KYOi{ltB7)igcbNu{eL zy(QBd9iR;kABVC>pnf_<2aGfXqID*?S zv#DfEcO`)@DpB{I@kxnef*cJVhu_OGR0F&?0#i(cU}6ZyRPe)Xk>F#91ZfZpa&QfP zfJd|r9Fj_y`|}3usp2X`kP-n6?V7FcoH^vYl+y7V_3Ohwh0cH;FG_6jvk&@)G-jqO zs4)DVFrI6_SqF&1E1t&R9E<1)9@pSY<`E(YKqc+tuHGLer%i_#P0OPaD`+A*-5~q$Cs^L}U&1Z`25(h@DBkS&)rA}BVU2G==4chpfQb`%%d5Eimwd1U-FRmkBw-hnc3H)Cr@( zlM=N29A(TBt9tR2$jNF2R^r-CZG#39g_%A~dXYTqv9DzA+gi2R88MZ@iWakAu3Y+Y z18#q8pF~V(kaCoMU-g~_p%FmFOpmOG*$6-U$NA@ZkN(&WqSAJwRZmR{DM+m-{!KL? z++Tjzi|)_OMbi6#i5dOWq7>Ybwt8ItjtR1rY|h zH{I`eVtjgv;-hM2CaJO_96^G)TBwH1UFWJ?Id9Kq<097qmi+_!YzRS{4U?m7;GMldS)fSCLoH|sZO;Se~Q zZLj2)oADkIS-g6jM1I`&`WDaLS6yz1hy(5u&TAZiU~A5{6@%Z;S$ZYnF6C$PrF)H( zF{9dXKJOi<4md*{WzD?cUDj#w^4*ey1|MxW4o1e0)y}s0P%oNmwzXPaQc2z6KZ7A6?tCQ(1j!7}nL{@3a6fPGWB;&2mxRo?I3J#j0<|xjn`kAVC zZf9&kpC=kxR?3}8B{qO!bqx4u?qZ8ho# zdqH&ng=jsskW9da$ygqWg4PFnt?4lAEagCC#Z5XwDw+|>#t=>> zbL)-wH{Bm+tO$%UHE~Tlwt#P9a?6LN_I(f{THG#NcCzrsLg|A#Rcz4q>!+TXZ$kRn z_}tM-BxXD?ljEk%mKuGU7tZ?geE^cOtI0;tEwIozZJk%9#_qQRLJRQmZXDY;l|P;W zHIGB}vRNg^-#q`v3qsE`lC0XhOBs-g6P}D$E2Sp*Fp$StM0eTG{#hOI!EdPxL%Fal z)Hm<3MZWmoC-`sQo&-wlca50k!RYxt16noHY>nCZ)Nzs>5QdL6p*J)uRL4TGu}=T6 zK9DX9qpegS{i?e=kRB)jX&#QkXoU|K5U5M%kxS8~-rXWTVctKnCOdL^sz|aj3u-)$ zjQK5a{tB2@tdCw%6E_@OLwGa+69QFF*l+=YHsRm)<3cxkTf6u5gw;VHo1{sG+Refg zD~_3p(D*(;BEVO@9?mIoW>1NBIvKzVXf~CC8^O$-zaZQh?+7U=2J&+YlWc`%KuazQ zR)pi~b%BnWqqZwIZx>HGIFB`3r$korPUVeXf|H_@V(h|hd~JGz*hkd{#>kmotSJX* zfn@FtJPdMxfLUPz1u0d`vz}?iTO#cLw(ID81XDNX)=v}zwhrbaRhCUb5%9coUud<9 z#W<+I6C_=)TLv)D#YwKpxPXRwC4&? zNBoq=+4J$Ia$JOsbjP04OZW+Y-A*dn8EAm$oh;#8ssig16dAAG&~h5&=3e;f1m6;* z$+{DolCIy+w-H!bm^QCxY1rMf`e)ns6S7b93;}t!7GUtCncFr@kv$Ke`Z@ zjP%MI%GB)`o+Y3jwM#t(OdBEQnIPVs3Svh|T>eOJPPhcr|J6_RqQ^vquVrpvjq6c8 zH48As848{NIIAt;4>})!M^JqXzqJfdy8uFbUM6p`temtV>%OxLcIa? z3Ps)Vgiaiji^QwHXKj-!A9sMag|U-T`kg!Lu*NaEjm)hSxMla~8-gjfUAKK4b9;=4U#UD{Z1V56jNW(v3LD80{Zb#T8S?mZ}Y4 ze0RA{8wKz~L4+=bfg~!B$cx}#xcZ=+V4(ZA=A&2GR0co7CgQBhQC-2A9|9~iMd@<` ze-~|vO(tgB8YB?%-&b}vS_;B2GH^{AI%6{0j%AlxURz7O+`x?eVz&UgWHtmpfU)eYZDfYE4W(X z9g667JC}|}TZjpI3*4{~C7^}EOt=u3oj6q}H5RVaFJ`KbKZDaBo800Q-E|IBNk_Wg z%fbIaKE1Bd;d6)#Y)no$`|=kHR3FpY1rMF_g3)48YXyKA@iQZD_l7ob6;L56F&}5Z zVcOX04MrBiqj`44BG+xIn>$S$QR4TPeslJ=2wymhl5HWJe&U^MS140xU3(BgXhw6)PU(O zRY9&3?EM(t$IwMxBxU3u<;jnA;S_8x!=3~Pq$1+gyO`UhDHECV5dY+clhHtltv^%b z;*aDlb265MN8&01EL21J5-y?o>)k4mPA_DhkHWu1HT%kf1+p``*PxbpCjp-{H3_4Z zpK4Pv2^q;sQgw^A7Bt$)r*dj==nk$Fbd%*Ur3c9hl;UE%IO)y#lg?4>(S(Ny_KU#5 zK~m>fXafY=buSv%!7q>Lx7L7G<`P1(9Z{KOY8+coufV0@%DnaDNnSEKWy5K!s#gE*GP!OgZI&jNgLkf4Tt zB#`R5e{~IpksTz|!AC4dm$bqJZGS9SaQUC9;P3dUP`T%bPSiWQLZ&p~4ZHW&2B0hF z4PcTl<*|SP@&kRrxg;Lp8P%LhfZ&Zx$e=C8Wr#srQEOomd&oQ7>;D%Hie(L4#uOxC z#9F5SGwp}8&6_44Ma$Xz`2`vqBmUF2MD)|MSTrGI0@ISU^U2<(QBil6L1<~Jz0QG_)Ls;WZl4~NGXvcq?C5(lAm3e8MIBnWepA5qoYMH@3UmT<5Olys z0@;)(2ub3gy3N$F*t^^&febBl2B)DNdDmeXS5Wbi_>Q_)Ev(~utS!aAty-t76gGLC z#lkp(2<~iMDQz7lBGjiLWX_^$n zI7!*LS*c)nXzvg4sx{RX<*CtA6C|2)t)7n%-AXJd>jnJ z56X7L_qS~d-AhmLR9}aB4caq72p0;Jra>ZIPo8k~)U6{5OGOzMIC_p`f(|BUk@No# zhbydOIS_$POo?z-p>Ti~u53T*1h4JTH=8FZkj*^#cym#2PGLC)(tCau$L0yK;f!1; zym8*s{)I8NvB;4Hs|J7c%p!SK+t6A;z9Dt42DD_)Ya@1mzQreNX#xm6+s3f#(qecD zGjzxTymue~=x8|9tlbL!t<95Xj`*QD-5#W+bl1mn8A<@dY9-mw0+56D%XoZ6Un#@8 zI+u|-egRdQ_1gno1}JEF5mRO?d9t0erh}tH4I=KbsBNdOS*2gqKKmKF4nka6k$SrT~Se&x0>$+p%bxBDPZDp1*YPN zH6?oD;fXB~C@)jj21(%VnekXS`A4GtiV-UlOwS$i`WkHjrnaJsFT|(gKpAP?PC|Z&4{$DUd*hSTt#dOz8idYwP`iVQ6)43<*o8T;)*UWBe2`s^C&hD)GBD zrIyGOtMmSy)R4b9GxNYLDr)>FhgIgcHZXdJ%n}VA`qYwLi*paPjrNVuoytV>WVlR2 zVI;5r9ZKa;ozf0npV*B~ z4q@uc#v-&xXVP1fd(L4%y8pyEqT}-C<@Xd$>7@(-9cledU+YH^))Qbd0k zz_*hvmcw7+R~Ls~BFElM5=A5!7`)3@P-R^cH{TQb+ooVv+6q8}&Vori;;mf}6Cr;z zJU{bOgs^t#?I+V<4qIVcA~D4WQ(oN8(DlZ8Xo01&|9mQM^t4Ri>6LRFSo}|+&k!R* zuJno1Z5MP^CvSYS!_sV$zS)UCf)!0w25a^%kR1_ zW#83TZ?0&$M`08E_amD?UaE|C$9<@k=*(FJh14kSnPKlge52a~jiC&M1O9W+I05o!Ag6v$Y%BR_RnCxR1KZlfl+E+y5-$ zce{4Q*izmybXYx~@LA`dS`PywWP`S0IL?*g?n{$^p*_lH;X0ak8hK_m1(^q+KN zE!w<~LaXcOEF4||!#y?nWLIWgueinm*#4s~k_Zp|V2%SC7Yp#02xPDPhT{{jZb8f- zQU;)!91_~x{Z;-a??V2rxgvEP(1(gw`&?@naXM$79Zc`Q-c9=$a}^|$v?Iwj!R>e z8qSigN=KBd+yhATnlI!Xg!t$wO!fqvFWF2lBV1UX&|z63U2N>ZArwstz0D&Mjm&q= zZy$X%C^wWNMm>5Sm-W)E-QRUCwU<6p1;7Ow1ErgOj>E8j)l4$R>G5lcjB~L)v=wqv z;VU6Da*`%?S9*23oAVET{*cMhnd>?eb{m$C>3QkHOf{s6S580qvrfvynyPg5)DW6GQj1?GdqpO|*vG~IW<8C+KnzVM=ukV_tna8V=>&vf!)+;WU z>tb)Wqz-#S)gk#-aUbqk?^sxB`w3u7*lK{y|I@l^xH zO(ZN?hsDT!bZm8xJ5t>6HS7M{_c>&6UViDqd-@gQihf8b7)pPN+w#!ZCW{4JF5BK@ zNr-E7;?aEszOU5f{?H&Ev5M0x?`Y}1TLx#6sKFBEi#dN~_$#$R3ag-2Sm%4yGEteY zw=eYOdC!LaeE5!N$IAEFUPw*QbcX%-DVc=N3zq`&2^uyD`~lIvz>7~fVhG6oB7n`* zA8DzD4qJwVbPDkFt(M`=9#2Z*g4wh~N2CnY2b(ff@I63f1| zA;VQ3IGhmvM}{m2!ze&UA;_X{5)6bGh=j}O5ev5SEJO!Z8{G#W)fbZ`RfC)|762j# zdWR7xj5-y=i(wQ^nz}kp3a-deU?Xa|txF*61~M1m_lCYqK!`~033xERNUu$x=p zF}8BhhF;7mF~>M~Bmn5soW(#t(VNe=Oirinv!NeWC^?L!{&ny~U2UNtx;XqnWD$Az zf|di>=RuyBNtnj#74N??z^C)$S%&h^ZmtudAkJH+DPbq z*vw`>z07%+uf{>_Z^m zYo&hN0L3smy=KtdBd2pKc$(ST(DRq1TGNo7;P@cGtLoor_AVhF(jLOIl3S7XLEwj{ zoH10$Iap8r_b(AK?9x53aqrgG2K=e|y2_Aal!_1kTS<|6%tH3X{*q+degiC3X3%c{ zh09|$N=Ka#DUxOsJSQ7O3CbH=)6b~loVQ#PZoahS?WWmvPx`=6YKRMRY3fQ59-$f+ zGq&}lnUmRkg!k?Y=oC=)x!9$5xm{BUt593!K}}IeZEG2%KoRW9goNa5303+@GangbQH2~W@1}k zN#i4XnF<$ot#AK!8}*?O()3BdPj=~`TTfSEG?OXb6%>}2R$(K?M3q%N4`aVGS2nc( zuf76+*+j)45>S|yZ6N88k>#|>35$bUej(t!nG-Li01ag(1Z?cHn-5Lt@<)Bn(GNnL-^pm^+g!8xXr0qSgpxI z{sa_&a4f21KQwyfdv+2(jmJ`eKDE_P6GfB7${#^tMKroCTW_y-*10QOFb=7>dVeA9 zjeqdZb zE@?J`R?}qvG>$09+^8eRCczFosYhhfO5X zG{jWBwqGPkHhq@Ui?8K=Z^X~6Z6#cVB3KZ9mQ9uK{|?i`G&brDCz*Y7Hx-%83bb0@ z!+#w2oD(YCqosukv(}2|qZBA#;+6YCXC5w|D1>xlX56Zo)z;G~hCSx{W*xpkL39R? zxZ=pKG!~F;F6&RHu zeJ`Nb#4nC0n^)YG9)K=Sqa``G+yD7bMhcCnMGU0l5O!!vna?k_*HM_Dv7F4#qm<1+ zLh}sK%Cd)WQ26DM7_gh16gy|)KDQys@Ev0#G@a!``%4XabiSf~aXwZmTZx=oqKzzB zAr<$2ue1L>7J0Zpw1?|`c!MWAtx#CjSVEd-AuNQtG@H&mr!p^ocq~L?vay({bh;#BcKnn(y9{6~ z29}iC-GtM)IS=l+3$uGO^^B%)&ILEvfbEi_%3f7X8tQp_ z7-@C7ftTYM9FLT0KhCaT=rrwJN_!D_-K@p)d{bLl6YsisGZ_0)G3}lqIHst!VGGdJP%6bb!6vJ$D<&8`ILq$<({ddUtOH+0W({o&5ruazgog#}7vu1a!NPGrBkOD0m0@739axol3Z z^A$|8|A4%Pnd6&BF}NG<@?Jx_ya@+8$)!V~1*l&SrB)Hah$V>aR!lApCpQvMu$(|B z%X|zd)8mr}w>meS@ zh~pdEGq=4J$E=U zjasJMfHBMNehsdgz8lW=mR2;j2?L{~5Bw@=+6L=$*jTlfOt%s(`TIkV3nZuO(a+3-zeRV7 zZ|&1s!0vU7$gyb61Lj6^;6OMVS!?1Aaro6jU7A{x8xzxV*nFalU;v>T4xoAx>ScKs zFVCw#J%JO_hz5*n09chQbt}DBp620bDZmfubb7{^dt>iT3B*d3eg4MQ3U2WI(G5ST z-{*NZ0yOGJt>gFvuD1N;8)q9N=l>5h?=RCW8%#fKw}c~oPtYTA>-q3GbU65CUM7c0 zLYseS`L((*04loUn6XZOc>*k*)e`_F`d!{k*v!(q9hX0QOo5=i@guam!8GwcW&-FS z7NE_=SEYwMy&7!$6QyA$@-$i(8XAEEKU{h(HknQpPB%eO@gSoyeIthaMEw@=l?FjtgG8V2l z&nwtUNNF+U-p-tsexebV3Ptl#v!yTuqJBQ&9Thr={iH5|9488~LG48mz&!=4I1 zBnFrY4QO~U;6XcFd@y<(yRXCDS}{{-Uugw!#qv_(Y`+dE7lwvu@NT(onV45Op&m&D zz{2fh{vXbT*4L`WFSqLMH(h}`uLOmzYExTu4s6e5cvUx&74NOerDW7x`eV%vd56pv zX7wed!cMCDGt7Fe%rx?E_Yu>t9yIK6Bg;EO?qv9y2GQqs+2m0D=GKWDuT;cbdA5)b z$}@9HAGjyL_@8QctzV4~_$VbW7P=@#emxHvF*s`(03eY<5A9X$hq-@Y3 z^XU9NLZCRq)Ldkn?+9G%p21%+5bPF9nA}HAg?~wgv8oVzZ@ipZU!4hz6j7DGRg&5Q zjul>a0xFO3>ieNH6Not@55WzQ2D!E7RnhWo z`+>59(KzLGA|vaeb%rSPbJX^sOa~QYdR8A}C*Kiy?^5becfPEuxZC{&@wd@fxS#U7 zI36+vH@9`%c;eiR5x>lF3yS?9B33=z!iRuxo~1`7++eORM(@#tu0C4q+~le(3y{lb zy=@W593}OPPC)mX#kd@rIfKzTE^L$C@WM}>e19)%=`U}82BfS`sVWKiI}^y+f*SUz z)2lR!OvV-=&cxq8WdJI+#1f-ylvbcM9234+CH^w20@$=`6zh5H8F@dTh1|)$`E}XJ zZ+hOVP(WQx=fjRovHF7d0NL`{{{!t&rMZ!Z@`)coKs`u^M*$4^+{Q!-bW1-AC3dcO zbmW<@J`I3SNF5(t4`+7cX;1C`D&Iu%qw4Dus6Hf zzQo^H&|ba_Y!i>2v}=^%;qY)a-Z&=&a?ydd9jG0lI3%gCvfN5u1L{#gyYJo3byHObK{g%!rQo7=T*+mhsW93rw!ErU`4;QmvdGvVw5}_3B*ETh zKQ6V)YV<}ee43W$=!v7N(qLNu?irKiU7~g~Z%!;y9xFPO(OzPtjn!>n;hfM z1|-1u-36!i+m^gQEcZ)bm#slp^{5u6y)ePojM%bTd9!N^6hyuQ5qykv)VQ_hM#ad? zg(H~d(*bbh*nCQNOPW;J`q}a9yMHXKFDkB-RKQ|fmqR;@y1co z7<#pBC;?<#CYHsNDQaU*NYc!t_N<21(FNdc{?f=24@|}rFQLDQ=jI&Ow`sA#62vpn z%=O0b2`$$!{d~;ph8hEn$M~?BN0D}`72OnD`_##M<5n_!t^3ud7|1X#4k79q%TP+8 zDf2+%4=_9xNnBRc?`|08wx*PSJ*FEVPeoWyn?Cz*b>OCBc}dRY$2m+&6xPE3-2abq zd0KT(#o1N@y@unYY~k4L!bS)R0~QH&8CtP+*6xo(}yu$QhO(Q@@qdRV164eANUO z@y6H$;4p&)tqB;%2?7I!vLtD|6|Fpfn#BR^Cs(0KL&fVJQ=)FaGOC+_qu+yiKEKIl zQ;MZFZMgnvC(MRblPDACI}7>}Gi>GPZiCRM%!()n{J1|J74#`H!-J25eL{CWxUjpS zQ>ksPKuDj0CL#Kn6c)1IVza?vJ%5DJyTO$PY;*-Yck>hZ+!4sbJhi?22ZcX?*^Qw= zQpfYQG*!LJ=VyNkn)a_uOJ%_36HmUb4#X7IpE@L$boHFx$KJpBiGP+H!-aN$sL`D9mE2!zSBr2zA=2u+y8Q?Ao5*H zEF|8nZ!!la>!yQ<%J~{KUqMv*i7MhF(5vkCS1MCG2n$QJAuwlq9YUVJSRKC%&U5@T zX?$%6eh*Oq-qe`1nUCCM_A!k>(8zyJ%6dx+dRBrZo4v1b4xsBU z40e4<+S7NESz{-zWyzkN*of>!k8LVe4A;#&{T0uUZ(5m`qZFCttaC^0m3-Z`#ir4} z!7g(SOT#OeCHvS|sZ&4$?_+94wMwCLCCcP-t1pxJ(*6BvpAWNW$=mW%{OU~PiA!EM z!{I2r6-raHn)kFNCy&BONN zv__N~r?V+mrHP&5x4jr+a@MnC;vEZ!T4U}$#u;(LdB1(6Psk$Zg*+19smTn-1ZkTL znMlAAd?gu&d}{i4<{yxMWu^m|_R>ecWb5sRv>hO^ZYtGZ?sjKkX2DSpW(eSDM#DZZ zVYHpbFJOzm*q~Q^p!2uld;JN42^L?pI{w=XfE?cSC~8d@O-tK6A{M_Cw6FIn#GUQA zL7j{~{P7&V91)ud%H_`aUueygZ;rts%;6B&RCd;WCSRFdru~Sp6&R7lU4nyrD7XdF zw2dp!^zQ-w)hBq9-(++C=Fp@k>v@p&T!paJZ~vhj%rnLXYAE_%$jb?p*hNln*#8RA zmO8$m5KFc*2h#xRR%eUdDd9oNt5+J&Y#ZE)c>^Vs#@g`+AZ(As&SBxjgVet3AvI!a(z3i)V*p z)-G8*7HYH@MVg`?1%H$z(hYW_QN|(|_1{A;gm`-4Jn-dpHPx?im=eG8v1iXxyiCV2 z({}kd%B_^^&c6yUIdc2=Q(l~vzbBX2a+JwUF`pErM(~zzrd1&}gRL6Th@NFKE=EWt zy1;_xy=2@Oot*Qz@Kc0k`iuE@ERkcBL?-oVMW3c&B?mfo*Kp7)(dNdU_)3n?H!s8r zOA4Lzw7zt26ehiX0C}-(*~(OWqbBibBdV*RpS`3eP@9z#^ZF(alMnu8AqkDb%jkm z1GX#Y;2M+$>CbTW=E5KoyQreICz%!&2iJ?w9V_=${WRw)W*p|5YRhW zWthJhKdaoN8K;rC9vd4xumgMcb12pPlR(Mh<{9d_uiSoU5Z}-{Xo8a)q;@Zr(E00y z!KT$ArkLMr;p2oQ(-p6;Q}x##e7!j$3nb>Vo)f%J>d_;lP@_By>m8i=`ayz^yN3xi zy5ahwV!RpA!7P+b^U41~f=#D7m1qi?vbr5jJJ<+m$!a`s)M&bCJ#U7u;1JY@d*+-! z3^;x;kGm68eJia{LCg2zjngU`-PpzldAB`EOBxoPZeR|LOzLycBin_pg!oW(q2F94 zAbW0hfh15z4eTw`GR$j$y(o^4NFhZ1bP+KfYWc@0;heP5_bB(Rn1~8}#nF3qgSh{R z^{O`jT7<^1aR zSE?y)8NQ^D6scNeMvh|Ub_Ld%PB}X6(<8NT!{NZP))PUSyL1UxyPJveqSP=C6&s<& zZ}}rN?SV`G!&y;%*aH=A$s*bItgKQuP&y?Q{cjU$QjmkPbP9b>BA&>lDpk&&+nD zs%YVk%#G@Ms|I_dt5FGEx$$+gz0qk@;fY@Op}k08lzTHQ@qMxk&-M~A0^dI76Xr<+ zV{wk*tR7wf^FB4io#3g&qZQp9`iZ3kz3a%_g_` zEge&6oh;YSzzk`<2^+X(s9p2-?1#J11a#7bJ{2g_3}UY0)dr;`-^O2r>RakR;fNLj zu;uUEZVJJ_D`@5(c;3$F$n&2Nz|5sev>n1PxU+0Uz)pYhVc4p|DOo@hQ_3cppFXyM zvJ?Hifd~jJA%+z^I*ZH#566{`UMbGA~i1eTkLQ2~w}Wus{;y%adY-X+c~duS@0& zZJ9=`G-O$}f;;VypQ4X4H%%9L$BT-$+j>CIcTXb=(3u1I!R`@?VYs>uC84xCMAx}^ zoSlt}Ta84MKm#fs9iHnM!uzyGz4a06i02Dm=`0PfXjLq#qH1I<1Y4X2Qb$tCbbqRI z18nn@PjhqxxEwvACjkTL)T4(jy62M?>__6;n7HmIU470LZAH~U+d1oKg?Z;}AQ=;R z5#b=FEUw%#*`s0gMMymxiJ=g?kE^2z?9`mGq@r2)Wh)b87s0O_nb&k>b#o)O<;QLM zFURpJ*e*-+)5FW@ZNI^*SrSX+zlrbGp-Yma_hnfi!t0VTL* zyUx0x0SDQf{ey0|y`oVWQwU^GhC(HK^u!7p@%CKzA=|LeWsjRW2nyawvTG3+zk7Z$5{cJba zecl$C4^_e3lCNf?Rn;AC-9Sr*_i>`0#X%_V;`5J?VUf^auOwG3b5vxLj3D))yAqlD zTf(_O=@MH)UVn-ITQ){g;x?sks&_K{^47U+j$U-2dk@f3%&;kv3iVi#7EN6(7GN`? z^=KS}43FSR-_g9w&mmDuVs8l>nLo1s!K0m6SDV^%9e%Y>MNvL0o3FMm{+FB|V6bn3 zZ=y^C_?lzfeq>;Or4`?^FQ`jb>|h>2C6t9k7EaHyEOHy_uATS;QgS0Gh86G}hu?Sh zI>CC##t56xi`ffkpElG*PP5)VsP zy^@PMG$>1B^fV{Cjgombi!P~%E&vZSjHlZgRI>1NCsbp0QRyjGO9jkdl zt$vlj`Oxqu{)bq#L6FXh$z<#Go*3~l8Mm~!Y|&lfQq}(Y{-;JVT_DBv=LYG0jQeP} zk@u|Aa0gp}_io2S$3E$eKMKOIL7_K@Hm&;W;V=yla49>R!~_&b>orPV09zj1c`McT z+&v+>17vttK*2Ah2;1eyiKxwO0rVyxu}E$*uLZ46#ZX4(YF6!`0Zk-YXg(1g?|ua&(oo z&%RNCY@@b||GS2woC||SfxEw28T>*ZXj46d=Xwa^Dk}#@3u@ze?)N>|SKtcfFd%-+ zAR!dHgrkh9-9^X*&t-$)wl)=3%3eH{H@O@G1+XllY$I^eV6KS}NxmkM*H>VjsQaS& z+yfJnASh#;OHvfwrYONg+H*+3GK+&cJ(Ldf=qS32X&J}eLu|g{XF*7E8SJk(b>-tD z)vxFA5MO6GxJATJRbY8vg1G7$m2!hwpkQj$*-C>9mZS{Z(4Frw9OfAzj z)gnoY{a7xK0pA7U7h6K%%tsFEC?t@#-{nJao&*8SWyC>PSok4dos+kp2D4PGPCHkZ z1a;{1qYN4o&_tly_k=XO9zc*`e}8LgK+17(4@H}DP*;9L@x`+4@f6`Aa3mRC1>84A z_Uh9*xvQ6SFZh(5@P|#$(=U^TlsWRzTIxw3S|GLhs9N|uTB)UpPFu~ItXdT?c#SA5 z`jUoscV|(JYj%(b%=QKf?!d%-cY~uU?H;pPlWI?ZL3|4C?lY*dd3;OwOXxD8F|NT# zX_*wd%ZkajFFzqmJJH{w6~Ns91?PFC=*PO*f+#6f!l+L!lxX|4A(gmcQ^4uCwS!t< z+(H}LavF`RiU?fC)CJ*&6nB5OJ4bBJ1(5K#3AVyvG~G2C^?UwluX?$O;)sUzuLI(8a2&fWapeNhYrbeOU z9e{LoaYZ->EL{4R9LXv)_<0Q4wDfMn8WK;LkrJLl5UoJ9>QMK0TkLBaR7lvYyz}lR z0%4*<4d?-i>oM$Bnwh`g5i7UR9_NIQu)?{P4Kk#;Q8C1uOl*N`pH;Ql z=6=S1T0L(~frGbXJE3Q+^LDyxe2TNT0W-{*hx<^v3g1B+ESdIAwUxA~Q1u zueal+8cMFR%AbhjSnM29{6c0)5#jU!hRYEl*GTk@VCv@AQC**;M|i!)KFFW zUnbucBi~0+SDZz2h{%1Urm-HYf7Vp5HwDM4y1>@jMA6O9xLiY1^%}c?&frCdb>VuH za3}$zQ7u-#LFoud8ugT(cUaYi#&OE(yQD$+9Vk;leqpyI?F_93kcr*(U(BwPoYoR5vH|<>*W5 zg4ru`TneumzqJorBh?@NRZu*{JbGxbj$vY&q8=OEWWpLu+MVe25DyPj(z$BZ{cIm= z`>kkTe8-r|HodpgPva{ZL+EOKGW{B{Nq)lLW6-AMexJbe_=FX_D{JRV^DSY1=GytP z=)-i{FAZQFoC5ykrtFDa(D0x&9mQ$^u>Fo1>XwpJhxe#z*?kYY3h})jW4t6-f8(v; zhxzA2XfS=7-SwNX4S@3>`_8z7u({v%)nS#~LBDq0ZLy*>n2v)Lu%$ah^K|-Ka>s-w zs^j0_i|P(p+>^39lWBOop$s}SYc-)dlnV_l*im>3t8+Q6Rz`_?v>}2Ii_Xit(<2od zp_HlNwjpl^7~5@V*}#Fvir}rq55Vp=jwOn3?6i@;ufqMs-H+zeW!(qdv>9KqzL&}{IOap#Hl7;ulchdTk% zFUr!6ncpJ1TBj3+3H?ie;?(Z+V2(ouoJ|@`Zo6+a7}f+(i_G*d%~vwX$&2W}4s)UU zkQYaJ?$t&UgRvuh{hMl*8=;9um+t{cgw-*zD$gqN&49;U)179Zp)|58MeEbAGUsSa zj-yg6%9IvnC(N#$TqS1N(CfipdQ@-22N&yT%gVga&19aGcP1H0e*3i9^d;aZ8>h%4 zeV$5Vo$3rBke`*8Xo)@arY^0qf!IC(?LzZJ(cDbGs9`N(JZ$0OS_VkJMURG}1i{*@~m(JlDUHeA~A{>j_;;nJ_o0H=6_9f&pv2 zi}4vb4dUr&t4<0Q4?kFe;_~WaQ<>JA@kG(!;4Z>E&vk#|{`vyhXb(E#QL7iJB4)Sk zo0^bpH0^-W2jx1use>^Kx3=H6Oi=DWJZF8KdA13(rC%8E53DEV38Oo7%_vfcgBO-b z)U8wx6$n8`9ld*b=S=|P&ky<8Tw*aa zp1V50yBAybEiEJ<6KqWh#K(?5G3qRO>JXgRr=Cv9Ai0BC8Xnd+?LjM|#2>oax~5C~ z$RTh?5M^~n_TYL)5r_Dc@pV5hMSn-F2#9Tr3LE8eu1mxAKU;#3!h)%_yG=6jK+5&Y zm<9SpB1=aDwCMaBri4E2_pvid;(keA1udt@k-g_863IA+$g{`;3R}TgL&Z5NhV4A) z)ywZW;=ixe`)SST{2!sH44b(k z|J8Y=>m9a6bWxrb#?-z=H80Bcw**Txgp#N>JQExLU%x%)UQ8z)ly_*UlCv~kLlfv z%+GCPp>KQ9VU|$a$2v1c!PIpx;$PZYMC}&f+?b(v-jz_;QYqP}&XmsH4cT#2^BD!U zvEZ*q)8gk&l4KQbIWH_$r5?Jj(r zohIWz_9+!YHf)q&vUkU%^IT&3^fKX^opx zX%9SrYMW23q`(^xI&v{ITCDC4O#l` z>k?|R1Z3k%zsIj9B_5%1qsQ=MLO(|b{TIC0z?8IFz|kGii@QFv;LAAn zjzE6rK}kdR8O9fogFcaY`=2bmQdQrx z#-?1T);!Woj7k+^1p7g$$)t35j$9^c_{mltLt5f3IFHXOtaK-UM+B*gDgnM}o8qK%Aj=s7Se`K9BM;Qp!A#>4&bQk5T zpLTpml+u(ltl+xJAaIlK2lFXb#-;sH2(V0%&Uqq5v~-$+1G%*3+f9&n>Y?)HC!bQR zWuO$#egA>8XuV4ib-oT``oOjYCWst*m*bBG_h>_Cp(2pV!P5hNs&mqGK_O-!5Po#v zpT_Eh!52Oj7ZN}q%Jw3$ka{grxZ_{ZcXabiiFq~bUAQaHwg7lfw%x_6`7%^+(cn4~ zTE5|31KR&uM%hAs@PlEX7p+y2lfY49A!b@IPc;i$^MP0g$$jt4q!>ZZFr#PPZ_}>` zOa0#H0(t+%e8wPQ;pG5Lwl+Hk*ON%FTKu|IeXTDmWQ`uXbuH|LX~I1qj_*cheLDwK zafoum0LkXGjtFPSOO&X|f|3%VB$P#`h|V0jd7~OS<|@yzto>0VL&1i47GVVb%Dq!N>z5m@ zFGGvaF&`8bHXRu6&(|%qk1XjjVOz?@#~sDr*q;{MTFOc1-lBsw-Ee*Nft3mbO5^8( zV8?~!M>IqU6O}u*3CxOlWI)PlijDQ98T~3w=}|pAXBXt zrsTG$z@j&bCHfVJ0$olLHqZfeGBr;RRb)uLwP+2>c)x_Kgf1P70L3f4@YrmKTx#8| z*|ufqcp6RTUUJ-mxr61=y!O5mfw3+y9sDV$lF!X3aTQMd+L+CbCSv`|j~t*5w#pfg z@9fN55l~k8CKYki2^D%5&EA*q#~lq#8v)as_nKA6HGUJ)2u6-;(EGs0oq%v*AOvbX zK|-ryhmXL3%h)Zq2$PAAAOBHog^k(EHj39}Pr}dB>x(?bLXW6-r!u8gvZlB;HJtDs zvX$5HtS_t6-CF%vs+XO@t*92~_mObe_#@_wc9cmITwqimkNgN=LUrUTJ)!gKS@Ov$*^q6Ig&6imfYX;*Y}F`Y=Faza zrwi&p1BySqga$jKQbN^mAj4rz0|Yf1RGb{t4l)QDNVgQUuB+|}*7nmRgZLx}xGK8! zKnyrfJK&Mo-2bZS!-qV}G4s-{`f)w2Pj{^zm$y#t-0l3jKkG##Hrhn$CSpvcHgJi= zg-i57WY0!96FC+)p5ubn$P?^UPr|*a#iwb?bOnAtP!l52Z}^7{&mj!HYpj)X@vZm^ zrc3{Q{lfQ4x+!>YBZF^Do9B(4ZCvU|1J;0gW`*JqwtgD7P=oYx`dEe$UQexM=)#bN z8PxNJ^jl4;fyD+iDhaG(<4Bd((B&%(LDY5`*d<{0umlU^uE^pKEgjU94M4qy! zMEmHNaStFm`I^B$pq>X~rNbd4mB3Xc#T*blH$qGi-IvzZQCgJyaji_5TVfey?}&kM zB6}kpxQM#5W=JRHD_D)V*UfOTJG7un7%A!>IQ5%LdkvAY&)dW=)E)e&!?s?`F87nnN%GV0nT_*Ec92hlM= z47|(~@6hb*r`YA6K~j2c7of?aQt7#o)fRKA6usOsR(~*I?l}6bbFG+0sHZ~n(Iwhy zm9%H|i2yXbAsD|;s#FhyQoQJG32zs&JQ`3UQ#cmp1?=9PoBBXWjtT#DL~#0K^9qaU z>qajiDSJy9M${rN%-vqd99`rBhgDvn9R2F(DzK1tA5F$`XtV`NcI=M|*ebkIo?yH( zI0`M$N+p1c41I~Kr{mb89he&7<%=IiQdg#os?`~KP%R%$1}gPei$o8lkcxr@SEF|^ z)J7v!i}m4iDx(JMQ#6xq84(dCl4&S5Mph0X%SRRzd-R9GFycIXE^zeGEcG42Qw4)b zRw!$S3ui#O3jGfBmzioLLtDDVj2rbSmafnE$fvwW6x}TLl`n^4i6{sE&za%q=d3U2 zt{(m_mtFS*#eBqB0Q3H10{N2sF$D9$2BsHFql$9t9o^^-cov*}A&JKGaDPLJ%K>Yb z@x^uH1sgFfUA^jk%rw(!OEC2_^<>RNv9UI~$~H0~v%(sW$p(o4#wITm_9dt^t6HLy z2)-bEH=&4Zc!W@_J9brI$t_Dgit*Irh(J`@qji-_WRN5U_$E9@rlEX{l!!qKsaG9r ztyuvvq3<7tU(v8etTz{>g?RPige5046oi3&#U7})RfPB1%qRf4qN%WI&=1_-_Ik4R z^`t03gr5gmsrHgFEl@d!w~USXWx&lXT*cYXF4=~i@X0-B@sbIn`5z~42RkQ0jmaBX z9!wqt{7StaTvad|^c<%Q!xbM5Qz@;Pmy6fT2#PwCNs(p=YDR~!{?(um!30j@IvKY8 zo8pz#&?sJn1f;vr1&U9E*ov`l{h>llo3Vdk`w`lY)xTVnTTvQ-4zSLSFIm@n@Ul!) z7TOfDa-g4xA@#zY#Fiu6BxS5+q+Q+m>fr@d6pUS9MG8=Lk+IHvgkgBF&K)Aw9n6|d zFn-TkQ<&F-5w+ZMx6#OrGfLHNYkx5=p1T~{V?R+;_EgiCuVWeB^D_FNLb+&S@X$YB zU8Ag!sim4`bd&2nx%JHngB4%ita2+vG+=yZEq-3?axXNKhdN8o@Fv#OyJ6u#T7#yr zbG^Fx-o4pI**RVg$_KhU2_5o|z$`5UDhvl2BeGR7J`eYFR|3J1ezero*?2szhf~m>h6OH8Pm>FB_TAx&|0srmV4gx%%gl^!`Omi@=);E-f>UCXipD!MBk3zPX0g0VsGj|nrz^6KI5+NV6N-2~;9 zKspZn&fBY?l8;ivo%Ds|V7Ef)Yq`mH4m{q~{dPiZevA;F_c&1st^0!8#0PWJ7KQ>9VBom z8CiQtLWB-IMB8o|5tHQ45 z6GI1K8;_RdN3t|N(EMzt62(4qxq2h#me14;e{hcg4Mc$ z!B1qhKd4qrMrwhnc3=jt(HNE|Xj5pWUb4(zVXYRJ!?RHy(uK*Yb}L+>z!84opiFCtTudm%hmE=z^?U-u!| zSC1HnC8^;8zDCKHdeX(l!KCXD!I|HJ#q~jI8igD^Y!`_$IGWFoR)oV|^G^|a*eu%n zuphQnF82%3nbvTgEaPrfz{I($A+gD(Xwhf-G#l&TN4=YpQBtl%Xaj$BS70ickQb9e`kGg(+YT#{(B8MT ztUCIWs{rEhx58=q=p1tfQRl(wS%@0>V1y^`=Fb2~f^wNSq_KBSXJoCRSgI_<@Y%1(_l0dwThabZO44L_RM_O~mrNhcU=JOXk6xO__ zEv#z9bd%B)N!}UMJY(e42cR&VW%HJSN&EeeH|ise7r??Sg|_}xjt~@Aq)b~ui~XLm z5QY%pr0YLYB8id;y4SG0l^)_{RRp<2154DW4|QW6v?4E(lk`!zT4P)d@Qr!s1z>F=C{t){tU zbVU{KtQROGDgM3^YA?SxWp#0C&|J6O{>i+E;qM?wOXcl?s-)2HSA3W&TGqMVa6=dQ zaxMi6l}bzfcwhISIDYBmS5T~G&n+AV_q-~vLazRd7B>e&7;CwF?2;EFYLhV{Z!X{W zy1h_EY^AEkr*QNQpP1rDv8bLGbGclo@%q()LFpMD!eN1SQ3m)xAOQImY z9EIXcS$?1%&?mcINo4{KXHxhIoQ&A+AG!;6_Z90N2{_4b|GeMW;0O08Jr51u7=|WN zSU<-#of<^_GzZX%kYEDCB6lch0Y}&@%rd2M1BAWYgK5s)Erg#yinFim+`|=>sV))x z6!Oy0xba^$xJqTSa`~nXh6Fyd)JoutKXKR%aUZI|y?kZI2Av@Gh<@T1@jIDr>Wwtu z?Mv=>mjG2WQ=G>z1jTZ5v4yNU`0EMC`xmFooE~``Cya1INOagN!stiZmfVWCIL@% zHWvSDq*8$QDGZY{qKkk7z%$+f*qnqDyLvf*ajqpolG=tOYA|Z z=4LH%t+rTsT2O?mjDczE*G{ty@(;+^34%7Kgoxu890~fsJum%6$dGP+mYzTnZJMH_ zytCJ2Q=KV1`b7A2Ts(l}2XX|i)4N8&>A}6soRzo|lQM%=t!at7Lgub7=;nfjb{G(V z3y$n|?_v?WcXFBm^c-?kZ!B{2S34+4;Hid9E6d)2r%1(jbp4K#<7@zfzaPqayes% z93s<@4>*L8EeRdz9KCgw2R-*g0z)Nd_naeMRPk0fkX6PAb1IU}bF#J0&W-L^%HT^T zDluOJHqXo<(kg>}X@=tpoY}Mu5pPoCQX+(d@1+jW$`8IKmo1Cjin^qZsFaB`tDq3jB zK&4LEBBiuBhQ4sf-x-u=&nJcwa@5{OU8Qp8xu8yp2u#FO?h+`cY@5FLnZM(65guK5 zs05S~-6T0Uy6quvIuB6u7c`-5MIs^OVGgkx`BfQ=nB}8LCM0MRuQz|H(Ahal!#PoB zOSSwUytqaWGFAi422Htm&Oa0Yd<(fs_%q@L%3aBZ^eOx;eo(j$$-bh^lZ&fjQm!wX zcn>6nt`$uBS~z6VH7#!P!p|P&274Hv7{rs-N^7#^`$G$m$UQPI7zf*l(BA1LCr>XX);?_Sdj)x+fnUI9;? zq%OMue*aIm1oWk%0phWfS7rlu&rgg(6I+O@r8~~xO0|1j3e>3Q;#2u$LG?woppEuo zl!?-F>(j>mtLk2QXQlf|_mDezwGddZq6&=?_lUTgNXM57;KmZLUGn`IM0o=7l_FEa zE~m{(9Q!;Men}yfr`UE4M9_WpGe5a=6ts5lre7xc0&P-%9dOe3+s(79q{XlS9Z*CU zFXw^e?|w0HCJiNGh_1t?-yd9}!;Y z92Gn4SwjIrQ0}5I#9C^`H{|z!_qs1o)MxI}91#4rGFVTZR#AgW@zuJmoYYtXK!whR zs?P9ZA7+PQ2=z8N$0j<3KW4+zQJK^5@6}1j7lHft;S=c(=IkHj<9jE(Ot1C zW$R2wvhrW6%sIZ1fG%-v_+JdNLU>mN!yAcq>sC;OG#Ubd;zL+^WW0ff{qz1f7&~(K z*P@j)SZJ@bz~58;2}+**SGmU4tOq9p9uoGQw)1&T45o1_T7^c7tU`v70uf!%xZ`hr zuh~C8+ebTpb3H*iU$6$6-RGWM$#IpIM32jj2@wzny~^n*To=@%>4h22F@}8z_{hb* z{{kwElur7P^*TWO*zj9`i^;z+}0VTMN$#HlJ1Atu1q zz{9TA0Z-~5*R)yU=X(brQ zLo|U$y_z( z`ofXBReSi@zr1arjYW3Ty+}}jFY*qL^DB;9GU*4UOsxM?KCS?@(PkVj`c)awSi&eQ9S~E7F&TI(@4C|Z0w+YGP=(hUnT!d z;Dl}(9rR}cyWw((++Eu5zFCPYMiaU7h zI^Hs9=Al#DtlM0xn;xusX^`-*Vjw`c^OD45Vs-s%#34$@Uu4xNi;YFIiee}Js?R4Z z@Y1om#0K|Pm~z^>o8?Uu6l61_^fFH3qLO=HQ8~Ellrqe&DJZ>&&Yi+4czibXZ3t(2 z4!Z3$atNEs4r|F8O|!2v>|WC@pvGzIp$M_R;-< zLMv42#6){?2&U)@W{-Tgl2!(msP$KUB@I*A;#y%a$kq^kI-0yAI39!4j0@a~j%65k z3F_VQlG$l+B^|DMKXMO0U07@*00<=&9v+)SoFK!piRD#Zx}w|!poP>PiY6*Qs)MlizYgEh z@5Mm&(C_KC0z=1%3hmEK2%9>`;U$?(DPy{#i7kmi>H0U5AfEjaH=~!#Rm`tf%w|Rv zG{w6`EeLZ4Dg{QOQ9ZP}Tpe@O+&OMK1klrYpWWh>SgadtKY9o5Bxhd$PxGLTWpeqt zx`O4)rE!=JQKmWXn}<+5|D#f4Tma?@Qnm=UeOvT`!9J*rT8sL{`Bj3K^`C|*SyD)W z3o00*qM_bzlk?N!lId-ZcU#-JR}4bZSyk&U2H7|@XDCi#lOyX6FuQtjn^}kIgdGrA`8>y&d{M$84?=N+Np$J$9jp@5BBq^(S zzX|s4Nb@py{B3oyMy&n}Bf?Q8(qiQIp9b%6%2J*rK~h8vi;Gn7gGB)chYkR-f3G-j zHDYe)m=>$ypvD=-JA`aiAL!Zf2SG-{^~vye<%q z+sI$sinuE5+tKC=fAo*fz&&~HexHU9_MB9?%kau4`vSst-%=B@)kG|3^RTs-y&a)!JooiOfV8Vw~>FX7GsfOIA@ zHN0V^Kt5~Kx~VU7=Jnl!!=67rs4Z#VLR9hfof{6a{{eIrz>LSZFG6;1kB>Ds!?-9A zX25wZ!rtF`1)Au2_z5guZa4N?qn&1DJDcMSkt{>-2Rp7dVST~d-Q?ILFzrh>`x)Wg zsbiSCZGMSJ_l9M?koCUKj4x9HVMjO4(EO9KTgVt@yR7o@nl%OQBdjX>Bo#^w9AZ|R zdLDPKKUxz1)Q{}h#4VjiH_T2)S^9I%`{pCG_qOvlvfZ86O$E}@vyhj9I>vLY85qHt z$QfS=@~wf=7&(hmX`yM~w8+RkP1R-l-VC76Ep%jhtb}tZx#&_ z8}hRIQOL4>iWEtSoU1_5B-6Toy#sytg^U@qM+k#?i>?0@4n#dR`ci-7YB&CEZ4>4o z_E{ULjB7gN9VkwJ5FLmASL*~Tc1B+^4*Hk)RYB6jD>^II^`K-4ZhFUsJ-GsKt%Bb} zUw`rUz)v7exn9-&nc(0g(V1e@1dyWyFDd!*0%3Q&6ZZD}Zw3B9aWSp`ohP%(`%a+C zkH$8uKa*fk9E*=hfRmkRU=92!Nw_TpxG{bBUx^vv3wdt>>J#%uh_4)s_Q*_TIb~Eo zB z7p#gRK#yBMJO~c7>mle?+&E-x#wCmr%*$}sSuJ!2z5|~`$YX1WEfj?igmuhJdYI#k z2^av}>(mm~%>2=-#?!zTmUR;m?44G0M_NSm81VS5A`33#d!i0$Q|}*2VUb>l0d4>S z*)+d2`sAWa1BRhM;Q+F!aLhot3ApT_J3#W1@7&hn1bafnKSw7`Yo;OXF5uD|3y2WH z$iYv*m48kz6i$B88S&v~=~$SfxsN;tDBi_WnO?~rr5tEqv46EmbMHzh-!^!S@sK@o zo{PLQEHu)k`6L}#o)Sk04=%uAk_5qAfy%Ps1xQNTN4GfxCsoxxw14WqN>eW7kStl zqx;L=7Ejtu^m=wv-j3HxMGR-)(-cg{T*v46=U~c0;d)&eglUC(A#}5z@hqPv1iCY% zQyTKTQF(OYfSMI*=fA274AnF|J@U9leD#(K>(};H=CUe_UciZpLw@`shxd5^0MOR( z($PAJsg_@Ai+9z)&Jo&x_ZiBTp+9a+!&%`hM5Z(f_8SmjD5>b#A&du31hsovb$A%1 z8c2rRL_APv?5llCIf1N3{&c|%uw!13mkA?bOxt-U0oatjp~dt^H8^sKB`I-!qc%PP z@&O6A*r`{MHY9MkI7f1;p^a)FEsG%-Tc^$%Ifm%(AR;!Xl>6;`mY&ctORcallAYgt z>NEwotjq%#mIRWBA(Fo3$S%^s2~v5_r!)ex8REalkirA9&~KcTKPZ}GZUS#+>{vyT z`0PB`IhnIvc1n}3UpQzl&;k0Kv+833II$}+gZ2jwvW(+-X9PaS%f$jB9J{6b?Gs%{Nel=q(Bi z+lv4PXu+bJMs)2J2YMU1iDNg~iW=ln0@xRk;ZIWdsqwkPZ7_lg{~S6sHE$`=61}%0 z{0_msQE!@T=B6D5YtoCPi+QE$!j$luUhdQG1opR9wEjjJzHQ|f=QhTNoD88#IeQej_&^)B2h1oi=cqaAVD4EStB)9r{L+|aLqtyr~E4!zfW zZ1UodZ+DaY%rqcXRI}qIj%ohJ_CPn;96g*S`FTW%3^co$N$@(R)uX*%`JlH+mU9*k z3)y-QNMSCxx)Gikudl8Q+T~<|drVpA&|Pmix8Bt(YrxntX;%1$)_hkI{Ur=;mwe|q z&!QSkPi0&VMR2wz#+6vV$V&`5w&ve8%5QJ;S(0GWtQ_2Y6;h}f;-^w7DEmeI>aiCz z-q2)a&t-MP+Ox|kZIoAa#MkaDN{puN`|WA*)%h$F@xqrB&|_iodrB5M;Bv-R@x&*1 zSFt3?<5uQR>p=-aX2H@TXWSg}6?8$dZ7cV~GSxF_X>aF}?ymw~7E8g@`h%%|J@^S5 zXL4{v?EbS>{{C2rcF|8*Dk;{5@G8nM4gSbElQrho1utCNyduI|@lHi+(LHy5OuSjX z5B=TPE=n+$8LOt#h+Z}=U^K{{L$l3NQGH%*AXL;r4Cf%-GN9s{3}2t61CG}J+V{{` z{*bEjP*n554!D|X=F$27l0<8a_m)*r)4Td{DR=W?UQyC_CfJpDpNA2yK-Wfu4;|~j zdD0&4-*6+lZ->H1pU_X5^Q8>#Wp%)<>tWQ4v8Ms{999J2of)a5V9{b^Tvn&1gxh!9 zutU$?Ss0s(^M=^>)@5N4!V~-uj?FpgWb<@wL@nzb`e+;9G)}D5w&{zeWs7GC)zQ31 z!*wj^HsE49%dt<|8?F3jZ?se|0X|0GDMXUCj(7Tr3I@4ki%Nu2_K>pFA`f}_7RsLq z1k~se?*&UOHq$6{ZnKJV4t9I=9jp3+rZMtilJl?5*d`Xcb6jLW(U%>V6^YQPG2XQ* zF{2N^#>3aP`BDx|ObZxF>o)YrLEz;=x4`=E;-H3^Y%{%IKk2aEWU9cN{#PBgEKCt| z`C=}0r*9GdHBc`6M5OX<1Xva&pB2lQSBnpY6bwe5bNJpV)_KSiAltc*WEfPk^(vxgbF(L;Zt(-!Lty5!nnT5zlnVhS*&bW%#@eS7EA2ZVB;ziH^$yXOJR& z<&jgb06wf7bVk4rKP;UD{Q|^e3G!fzNdWZLw*I#Y9d-?^zk3v71Po&c&n(!QRQ@SP ziY}5~R16fnu3czQ@1)5vijCI0BQ_lzp0U0u z>CDVlA07W`u6sGAWp8Q}Bv|QO796FgZDia^x|>eQO3csj7GP>{%GWh9t;J=2@osTV zX>*3wNmK8h<`A9h+=!!-Z^RHjvDx68Y#5-Y0th54N-bf~RL%qQc zduj5mG}Ocojv^|0{p$PWxpM^2(JT6o8UP|$D0ZUnyc>#GOVj2rpI#A>Xfir1zPj=Q zy^BIgWxbERMYz>q)%T~6!l0VG@;*`-K-e`fAfu(8|9%z$9yYs~O!X4JgY1GfI-~y^ z1HX?I0k~>~ejeoL;y$NOcDps#xMhJBGskGtW((IZF-bk}`ZYn2D;kAa{KOy*ty}zEul{d7!){9v!mL z-K?ik-9Dk{Wt!&ac#w3fX{_uuqhS5gmQKMc>I(&H8YEM^<3KW2=+W0MHcX*R#l6!? z_iI39A+=p0d5uA|2ND7m?{|uc68vB^q+#{5i0ZW`ccbrZGQta~H&E``wYNoob=)i> zy+DFCNbv-NmBquWV$VX@pjJpO49M@*!8nk!>ohBikkpO5+YmYa%hzwef@olQnP(>nn%^p7?DK3#+pWYUI(&zW$J~8Y(MB^GI4o zd`Z`Z&C(FUha!0_UG%Vz*ye|<+Dmrz3?^8gnINjxzdOhoiH!m+Ib$4zI2%-9Eia~P zJT2<59|DAazcTL@)hE_6iZ~*nk)x0}4MwUM8Kx@)Le+m?w!B zi2E^qH6U-^q!XSl&mU1khAH6BI|QALJt90#O++wh(^gPio3aPC^qJ}(pL=3v zQQPw`0w}R4>(*^FI7CHQF%BKUl+ck)wk>oyY3|MK@~6|r+Mk`u>aV4KBywAv8b+S< z!07O))2JuqeNIJR8G?2Y3CqfsoImZ31p!Pvf$Z&)tREM8h>6Z>_|QH%^Z==ZBU}x- z8eLpL9j1xT6#A+a#0-BVx^HC<$4dYjI#iP1Y{9j?p7S)z#a4@d{Oj+Hpg|@t#V&Q|3=K_$fWZ#LnKzp=ho#PbR*Y< z@Ze9oWVtvZ(1lK%eKvMim+*blzZnCo#89bz4|p-jT5U*-HG^CXXuztZjPibL)~}zG zy65S7{3Hi5{3UffI1!xh@A^m}c+G2WsGjpfm_eCMaBELDmI8AW50&Jk;?+7|Lb7fSzRg)mM<)tI@LT3PKah)xLk2c@&=2r)v)(Nd=@N!2cu z$s>alC^n4ogJB?9=1>+3MbGIxMTip0>AR3(6D||tHP2?j(w>4-hM0-i4{(aMUlZ;6 z*UJ2e>xF}_lL+H9gI!61Nr9~Cuqv%G`6hU8%k{?UXIvgpgU;3milbqoII{m=za*q zVHpWJl%>Taf^dIL>wwm`|iVO-E2Hwdl&Oe1)CQj@`^Xu{y~Yvd9gay1L?Ihw|y_ z`4k*VlLSc22AGhEUtI46uUL^t@>{I?28&t8Cdq@z_VwPuq5d(gs=A|}@Jd=a8VdE6 zS%FZB5@1K}_Wk|uz_r7-l`x` z1AKRO))-Pd%>H7_t92{JeWF=~x{L_AE$>4kukyW5ugc{8^GqUTO?A)M*9K+j%cs5N z33_7)foc*<2B+-g_tMCd+V+>cRzSWg>70Rt_&hIG)gNA_7|qWdA#&$B4YMzRls;s?6XNs@ zG_5hjz=|j!puv-Q`2Fcht~2g5ftH)I3n=U^=x0bL`c@EENin=Xt5<#RyutuhcVTm2 zDJ1E}>7l6Eex$*Bt=ubl5IKUNiO?v><{R3^)Rt)}aG`?BKaG(_e3}DmDi$c8cpT%# zU92keFWC%BL0HfYKiu8BN;7u>%@l(Rd`G5%ddmYT7JAdnWS9QSptLmA2=%8Gj<9tG zw|MrCjj#$2B<5Op6t0%IVt))s=Xn~q6kaYIb;xqlP5ea-?#Be)UEa?P!OABOzShk9 zT3G3YjD;)zVu z-C~DI@OIhX9zLYbe+`JA$~ZFLFH}@_!AHEmf5?~p5Im5lc7_DE_afad4Y2g6gT#pe z*Mi;cl+ju?s@mXEj3+4mgGzU(<5q^Vd`q94)@xEim~HVwTI^H;M;+qEUzuWf(vA{c ztx9ew$AHoEu^v!hajE!$>1;D?S8~Hm?J0aQE%R+9p2IB43{tN&&q!2_Ce%z{EkmtH~13JGeeHL-)lqc5e zOyuZ<8woOx!+3Q%9n=%7JchL_4^Erhn_tBgS=~?`P~hdcsgTBe`6Xl=OUm@*^;zyR z9DGm;0P#jTck653uIIPgGAJ}jw8vU8 znbpAU0?ua}dn!ZFnI*)K5<5D!MG=b73m0nay{C1q0bY$sNc ztY1iSn9x(OuAk^Fiub1WNcl56V3s^TvI6F_2BW`de^K7#?iy$T{iR|P-=AP{dFq1- zaQVS{Np|qeuq%LG=Sch%J+4A#TfYhzy;<_D9iWX-JJPlBU3Cq`%~17WvRIXtMb$Z+ zbsvrKc&w0sSu79!d4&0IRpI88BbJas4`DvIg0jK~d0z#Zu*=sCRh!DOW*1xkr)bby znn&9NRr8AVs9m&`xL4eh#sfr@Rd;YH4sUu<+p-`#+*_JFh*OxWG*H43 zRkQYX`1yx=0{nT&mq$;pBLDxzs>jqyt8)}qo#OO~KmL$DC>OOzmb9GP#U3%fz>8X{~aE$3lCFGU&9v=X^n)-xm(jy531* zL``Vnh7onlHgoE&uD=n_0eDt5$p|s)kUR1|kdNe=Y;ARCr*aQsO;3mW_8g-h5*|P_ zHb`%XyltE{9|dn)b7e89TQ7i@=#0e)PrOFCm_tAC$0GvuFInfOKDuwK^7+IwrG!+Y z3+%}m(K;l()RSs_*mQf|M`7eO)%0DO-2rU%vdd}POip$s!w1wL65HF40dTn#Sq)=K&je{NlfAk65el@Oj`E<`uwBlDT* z-r*pLmZ+z1tQHZ6ndeax-*9{J?$d$^4G&@7`RImv`x?C?X6iaD6z-8Ar+IVJQTQIl z#v@ochhhr5++X04VQR1R5re9V*2#15%ssd@YKNnUy2;?QOftg&)=e^qT&s?VT}(sz zU4ctB9o;>&Kxi^r9RuUnN!~CLNvl=+dApA3k)cX~?~=%eJMvHL0cnM{>9Peuh-V9i zg`sbctO7$SXp8~26NV@I;XQ$4Xq?-D zB8Gt1$9X}v57CuvL~_sQqK$_LtN~8a^cgLOvzs;xyY}}VwFa=C+?G0C{e2IG%zs6R ziKpIQH~HI0emoc7nWsW8c8u4QZE21Z`l7x20&aUl3R5 zKYWX_Bd-|B^srW-cmW{_<cVxL*&cuQwIN#QKuI<#03%g{0||p ze{izLEFA>asN&UhID7DA_9hIwfvPiv!#7^wcNqZ&q`_K~uOq8Uh9$t+8?bqo7>e2) zvQ*$l64nZU1L7H*gj?WYMOMe%Re;rXmG87o+T!kbg7O+;Yli95F9ayrf^Gp&(`5}k z*sIXTvq)xqH2?AyQhi)}*HD8q$XXc8oNQ43%{i8OjL+S$3Ift#Ypwr|s}Hvzua+$1 zj!YH~gYB8TK6J2l_*<0T*yBNw3=?u9>ut-JEtbEE1FZOHv=M zl(3J$Ft8=x1L&R;N6>=r(c!2)vZi7+cx^vv5{Wo+rR{v9l|ct>Da3bPOh(;J<~8Fr zC&;o%plO?%N_^YJB+s6k8!8vYSh5_I)%Gn2Ho(bRAtu^CcH1I#K?L^h1kN^>t9~z_SSqJjV`U>=jTb^jf z?z(qph;W{9LMSIMVW<2Q=OSs~=sCr?Ffv$shhQk?fMjPHb=p58kZg0vgIBgh`$BV+ z-t&Za-fp7om!*rE97qU4paqJ=4RlS6iS)+CfJgLY#b!JOe~9+MhEg1h762D2-}^!V zLfX%kRFpoJ!qqq7&1voR5LCyZz+h2xNI|(8o4f|T)(B_*?xrRKat83S(FSuCduV)s z|FJvsmt@G7ta}L$ENP)=X)a+VB6*!PP5-vJs*78i?L;Fz=~0voS6E+6y_i6#YEIHz z;xr0mWTO(=8BD$L3z8_Oi0oR^V1^tXDh96( zW*WOg4n=8N&3M^9T;wfDC~LrnFP{!#5R^N6udGdj{VtnG2Q0#}Q41CD3G6fi#gl}R zJ!F&_#s=W?#T;OP`C~FgNcAu&kKtZdDnL6x;&ggID{C?;o@PsNDA4bdpylweNZIRg zpCKJ45d?e+ECuOk7r94ZdM$ZcvEe3KneaK#;Up?V$JAX;J));u%53p@MqeN>@gjTh z&wNeo6$b9Pw?d6g*iQqIMu$f}e^}n@X=)>y+gM!-zV1Ax+DS)}0xy!Ub76?ai6pwO zX-I+-1T`VMKH&N>R&m5Jf$`dZR@tqGpNQ}z`F2tQBYGk6;kP>&Ixl|Nlk}vj5UkP$ zAWl=8Z0`MffPGf`!bv?|{nT&Uhk=}qwDmTldx96s63KRe6=#2bU})m8_uBc68_>|%v_8{ z&ISM3TS|a=0k#$@rxfgacJJPe;N#n`RS}w^RsbHSruZnLO+rSQU+w#qrLcx2cCj}J zSsolCsX#j3x6*C-+J9 z9z-nc`&@|R%5Wg4*yXSurQDkOH$3R>V*Svr&+4aVQdmA_#yRydM3@5Vbevw`2|A1$ zWK=*53@0r>%#uXR!-%y-59?@*Zh#_I-UO4UHc|XKgPJ-x%w@3}ggTwQV}j4W2KYQn zGDiwz)GeN~C(TE4B%}cXYOxWLJ)T-*X6?+EcW7uO$F>bwAfI43h><^XRNIoejo*8Y zVs5yL$G&);>wI_O#yNf;KZAW<*S%jJ$wB!2ibP86eQXDqADl@n(ojtRK51XgG>{75MA`?Ql#Jv)pU!``{8>?Y`xAu zI&bqgfXiHRSsiRZ4u0c_rfYy-3HSls(G^He(k}-{Xo~=jJED5+_;FHj zsj>DahW{*X;QYcRO%-OFXjf3uVMX$bNqgk3(KQ4BPKX;opL=;4F)BU73WTt#AKGdQCuF$(b8oa!1_5#M}6;p)~n=E zzp1`Md+IP;a3Ht&y|BIi^Gk2Wj!nhC`!Q%lBU9s3zc1oO z;?J~|W}@9WJU=SX1?o}QLY}7= z$S$Sj#ht)o!A7l(Wka$*o%EeP?LmPimYk}BvH}C1g9UWn?lKEgKze!EO4sYB|HrSg zD^xRrj24V{Nv@%i-8_JNwl@cGR9~8Jw|YU3t7dqAGZ_Z15?Wi!9&~kXpQ3I41)>?* z`)L0^HnQ*K!rPKHo$FWapkV6P*LYh}1#9@duD%Tj9M)lri$CSwoN$HOq_4pUiMGZF z71=Yo){$_sqm?g$ZE`}5{5%!gA&Fc_f(8`GnKyRFu($kyekw67V5SHw{DF; z0hMCq(^lrZa+%%N&h(%L@bsIot~8mdJO8?tC>cs=k5JnM9=&No7^afi%0vvT(EPv9Q%4&#|tyuD3 zP_{we(NmYUuk23Na9V} zWAUr>-?=jswmCKaP6RQHV|7nZ%0^?w!Xkaewz8dzSD_U8qm0F8wz8WO^Qj+dW-KBS zC8#GHE@8`-1Y&u}*)?b7GPY@kWvZkAc@aiB8#aY12F!9z8;>-3@l4j}@93nmc^?T3 zD5=;R#CF&86QZqL38P%8z@E%W#Zsg?19vnB(o=;IFuFXzpHC*BQf$%GTO70;9;sm- zG2-%sz0E}6o~u~2t1qLzrBlt8Tet>%_y_~CP=kCTf^$A4hHhJ6nmU=#uy^+vatDLKWf7=__INFKFYMJs%T^BhBBD%!8$ZWGH;$@_QKEO)Nyt4kRcKb34 zI8Qz}Z98LVB9xfIBg=z#%sCep6nq87E<}*_)AS=@dK&YXdzx4wB5Jf520&DStt?&R%w^hKcFlH(;mm91~ z=|*F_$ToG(2jsi(l2G>3gPo~TGaqN61Tlz`fJOa~xok@F*b)sr=avE$7B1FbgnDGf z7?3Q$&on7$GkrG7_(k!|Br6{wydy;67pA+Oai&-oMtE>2Xzh8`>w_805ISs@0_;LexD5zo%VVctd)6MlqDm2}aw8WK+ZA#K$`|{xDU*g61hOkxpNLg(ctMwx{cn#*8qb%x+6M3OwxBPI~ z3l88z{mR+794wzz5Sj_Tu<`}f9$SL5szR@CgpP2XP-z8gC5DLB^+)#5ePz*m9$Xxw zZ2%Q(2h4uA652R@?I|2aP|b><4D%Na5D%Hhh2m<9b(&s15$D6N^UV0(OS?%b{;T4I z9XuUtMLAu2f?C-yv*3yo!3r<|eZ0=-ouuAq>aYKdjgvFkE5Of2X)ydZ=Fu3n2I_d! zqp0J4K+vMn4ax6dLZ!k-Ut45s(u|Z30@XtwNEr9+>YdOl-p1=6q&$fx9^wd-u z7hT2^yko5(VA%Ee8Vr2P31>RZ{rY&0S0a0e)r9Kn0ou`tX8Orn2<1QqG z?WD}F3JJ&$h2?+hCw&)&M)#PIMWNjC=S#o8tNKYjw=;|?)Fn|Qw{33HBN2f)Ks?w5 z(T}WVbI__V$%Kt@EmJxK#Y!SsJoO-FSez{I8==;BR}Bwkbqoo0)!EIN7}FkmNt(P~ znr5Wpk8i0MgoGEmZliy%>w#JCu2S)+7?E8_$oUNl{?kwPUUg=E1 z!Q|Fobull@tNCg6NhlXD9Rur)Ni{M?iDkKYd1sJ3ddb9mt0cw5n6v8*Z)ocbF!Is!Kg5x?`7mc9U_X9ix)hA=$gds)U5o7@BPS$6%ksDCVhhQUF zuhVj$*kg<&sKGqI=qzmDnW$72YlOO;Bq`P3+3ReI47uLf3b)$V8?z?QdmMkTZApW| z`Efc8#Yk!-ma%>fUGp0WIC8YfBE@aR0ErS5I=dBW3QvKIK;#3t~k2u8zD#TIu?wC)8ne zHHlDt!^ku zKsnchQnC>#nsS_$Mb(&c|E8x$e^hP5Vf@Ir+3{j?5n2} zTvw_`K*k7Ho%i>O(oe695RPFJZ}YM|EYlh5TCQPge@_N0@lGL_jd&7qZ}%(Qc;+o{ zcd&^3ypBSv@YnEw<^?K$>*(zeD^~x&qMsrTg)w$1@%LX#MKR!9vJ`+3UC8Rsphm(% z9VZsuyk!V(Dab5cNdcjrBHocBvXdsac3hW zCW+w|9G3Fe#l*(uW=kZO?90&0lF2PoSa8WSip+-l5jGv9BkZEL&}pCdkDUPNQTyf; z7riC=4vp*MO5QkYUDQ*)r9(}g~eVJCc}fvdrAwctDZ+Ib<3Ntb+$R6zhcK*YbRkxy8dP5)&( zgCo`!VE3(HsHp&VNanllJD=BbJQLh{Or8QXZcc=Ierrlpw6=to4D>Qr1LVzKbkC*R zzZA&#Sz+(Jd7Ya9v#7<$_jlvi)U$I{pO;jmYZm=3CQ9Gv ziV-;+5ZDtV-jL+7#NnQA9`2j@o#{*48kW_b5>R_k{|UCLk=r_6)}8+|d$7+wSAKjQ z&y(Jm@&n)i3S1xLN)HO&jNM!_(C2?Bb4D{G1?zKR^~@`XC^l><^jcARWGS5sq0PK~ zo6L}E;KP0z<*}_5$;U1oUij{G)Sp__;6<%D(}9c1Wx*V6LgXUx9Ls0vo}dmEXZD`N z>J42&*6ZCBVbzi0OU?=4k+NB^$Z!4t7pa|L+JZWqj=~olXM+%evJ zhd=80fS3$>5*jVEf&)<{+msZN&@p0&b+nc*X6Y=yGv2ZnL8dM;M-9#a>uwI*5SkR_Tva)~~q)-f^sa!S}5qlzx6noC= zQ!Q(IKkcAl)3QkM_O~#Uv+COz{g|74Wm-9bz}ECW(b@r)zV-Q}1^bq&S?RK{D5=fP zU)rR*Md2sjjOvXGOYPS_bR44eJX@sKiyY0hf1Pt6inr&@)29)~?0_!*l1vueqM z?ru@_eC@?rL*F~TOK&>uxb9|GC=YSu8x(+TZX$wgMFu;?!`^@%#yJb?R45kd>Fqi1y*)^v=a(SR7#FQppz%TDGO?(Tort@{PM)jNAN zG`x~8Wm*n#TX}l>^;yMH?b(mEiWU3^U>=pk^Ot|>J~7c_&GVV z^#g(XTI>yc@BBd`oHJl69j6RO(UK>rfkc=0^tqX8k=*^rTK?TxYt?=#5}1drt+`s{ zSrsCgt~opfB$VRG^h@IAUY4^9vHR^`VU&pDfOvn6c$QUN3_+2gt#9an&x-X_ICA*k zeZ!}a@1I9I?}6yRH?sO|a!x=sr=l`;M`0Q?|9_hjkdHDkp5rW}#gQtMbNz41&UD*W zIT;|p4fAko<#qYHoXVNjSv4X8noN3ND@x(GeZiN8PLY zw+9ZSYXn-}^!Kg2rA_MN?MAg>-GF);o>2^bc{7;ie*+RMuzN~eY&v*bD6=}WqBUmi zMJh2ka)7EGSeok4j0^2%Nk(5~&<0WN9J?uuHT)V}j`?2(k{2lDOj=e=@_Vz3#V1Sp zT=nMaPdGyDL+iwrs{#0SouZR1CZr?q;J` z__K{Iqg2r~@C}(oX+Ml3gzBcZr5W+EQ*A6K-?dT+Q`g_n&g65-QAHo5(1^h4B|f-U(aMo>FDH^M2i;$YO4Rxe>^$tmhBPN997G1D&(i?_zb)1`Eodb>IJt`h-*{cymv4J znE84|pG;dl9+(ssoUf(f$ajtUWj%#0k#oYWLI(BO$h=%YZ5UQm_bjX7Dy#l|*Q=lU zh_=5j`|(6*zwz%#;jL4cYk9;CeRM{eQVR8qnh<>37&O+n^5O!fh?wsI zp9rkJ`k?owPkr9z1_IBy2E0G%?m+YL&u(d^&<8o}-2^U=$iBU5Kr)uXAV~Y3)a>|_ z*SBHAQZK;_skl%b-OK=<$SdPtRmBugMDJWMXoD2T)&up_9({|E9U1d-n6I%xVN*&U zN*NPM4MeWpE!%*-Ln;D__6`%zg+d0N#jZLH+(U6JOAc+zd^{^4m%M_~%=)%=vySG)#_yIC15idutR=lGnwvP4jSkC*7 z!Rf31)NCl;SQRtAgc#cvc2~nrTvFix5C~K_hy5n*6a^TXERV0x-5_TuzH6I_xa~%d z4H?Y9M4i;qnqS$@N^2fSML|APtbUjkimb3xc239;R%!l3fS|Vr8w#JQYxB*umr z$YIXoa4ex#m}V(KLu|DccQGZF1M$jHhKj#zLnUL1Zv&lJ#VnAmskC@H8kVK*b@%j7 zh<_`{gRfaCj*GY1wl4KfU??`UZ>epOb!%+MF% z07ecd#eIBhUp|U4Xmf8YhiaSjIwRZT;Rm0j=7y=a5?ElbUG1k%$RbrhJR=3$KlbDa z33(zxQ)czOUb<5nipraKp3KJ;y_W_66ZIM#$RBwixe1uvIJ4^ib1#=|Me!v7Kk?l# z|Dr$4K&4iMz3xV-idUl`zlSQA!GzmG5t=|%?!c`cHF8@?=S;>P^Z-G}y#-OX{DADb z8H1&+J2&g=9Qr;*mnTWM~wMl=Jf4=o11Ah3jaFaZOClfd9CXfb$$q{$*BL# z%ksXZg#R?oH!;DcmTb`U5dc2fUjOd2g?7*9FhRtN1=P39rCtn|e<;8kG%yI55R1L;6h*HqkScIQnv*7dzG8GxCz$hEt z^p$C~*`9;%!s4p)55_z#M z_=w?&3U`ZET{<>sT5w?9WWpC*n8l~R5JxNyK%FqIDpnGWhoZGh4%6!Y-jxqxr=*xz z-^mfLHtOoif|ngXg`vnkk%4ks(O_}1A@?OT4X?FNF?esfJ}ssHj+LybN|Xj6XAZ-ccx zYY}5>hp^Naw?5oH!Ddn~q7TJCBB@y? zeUkx;Q=(y`&^WMa*X#-AImUj~oL2{zFYz%~n+1b`P#1f@VNPJqGzzO=YeJeRyVoY| zBA?j7Ou>RC^L}@^ztAkqa6si|>!WmG9PXVsAMCrEX`5+hKz6mkJP~Ngy9wSCGUz8Q zY}8qhE>tP1gpRKbIBu&=Q0>l8lv}b}N%Hbof1!uw^Ln#touZX%N<>I0*xc2v4X}|d zDBaASl3sRz-&GAOBiz+eF=`;?ijWH{<_G&t>-Tk7QhgB;B4hRF<(!H=&Q}*<#`=iS) zP-a%nq!oI1VA~Yty9d)A=+`W zcP`GksF;X|+Qj|M)LZDgHFTbh?oeeqQ#Wc!AKkZYU?Bzh z3sWU)B7(cx1~f+k^xp=((@E37nWbqhPOeYG5DlgC;=JWT@9y~C(O6D|w;^hKWzffAgOYs|~i{tbubb+7Had_M>ufS-i=iUr{xT+maEks8DVmB<_k@iYRB+S2&En zvWO;FQC^)whgF#0mjm;jBJ^%NO&KqMp@7ceaFW-Gv!Jevl{64M{hxZ-NiFwG018Ez z3r407$TZrIx$Vzo8er-0!Tn(a^+3aUvPF7>P2W4Kuy`*>JcPq1!J`yk zJ@#UZx3Oz(cNAN@2#(>XQnfI5m~@quTf}iW$fJFz)+iFDh3!TWUlKB`6Sb`}2xvC} z?MPM4zJr-lt-U}Hu37iNc*fNPH48Smq*2RzJA1#l)dbuR9iPbx4-N-L#_gjpjJ>fV zupX*GnL~``iYg=~VtI$ZhOxwb0&Gw+A%OzPI1`<8P8d1CRPT+EMrjScJm(d5z8_mT3 zY$jRU(X73La;`4lrs*!eNorufHh{J1f%@E^X&|{VyBjLVDiu(Lrd8eR(p0Sp4;Ujt zlaJu;h*C)^BW8bi_kJGC3erblMe_3G63ES~pVTBwmrmrt2tqR@qasVH^q%}8b)pVB zb4YlLtu-!+DoDJ*i%Vhu;<9ql?@VgSFk=s0wQkFpsuI-MXo3iz1i?@O`v=)ncM=RY z=rjHSS?|oV@T*Gj@;?>O;L->n%)unV66bg0m%aoBaF^1@V(lrZ?0W+dynHY7|GE1g zZ3>l5#^u)6rt31>4jRCm%b=q($qBT~S2>7Z*5xn*a?BRCFc*V6rv(s89@2@X{=|${ zi#M&Rs?MErQ=;-}^GPuN&mP($C=pLRMX|XcA;<2t@omf0wBq*5T0+(gPow7Gap1K? zfoG@z-^QwmlA2MEQMC?{^~MDsg_LeRgG16))J5=au>kR0#H#%RPLa|Y8Ot74zodr4 zD4l&j7U^#Vor>u9z#UV}idEmuI8 zXVVQ6f0Nlj>49@7bD$1sUs@KN#&1Y z{xu@KFEQrL>L;t^s(^Js@ATSSs3zclf^5;VNUhWl6dUF;GYAX7fMKpR-rT8!;e$zW zSkl#taLjKbPYd3`)*axx;zx4A{Az;LN4rnzrVulpd{f+zg%q_P$WtYJgK?^y7X`2G zdc+rM$}J`eS+yu8_Wcc@k*G~D2eF?AjuBG3l`b=yd*^BNO^_f&y#-aH@_TqCSTSrC zJ4p57GY&|K)>p2RYybHVP@{FQRHI-QL@*61ziWj9iBfkd5uoM`UtU>%vF^K`3G%M; zB}Bv@FVhZ7-fO0TgdN@1#Pj9Vh)|P5@YsN#=I5N&s$dPcF}T+64n!s&mzD6LuWDN> zEF79_$iR|h72H)zoy(UT|G?3%*!24@&Eu2wQ)VGSs_{tU#7-;<*a>N>BSIls3$-z~ zon_>GmEdx}2%ufBy|-LKj@dd`LSVZg1F@ORjvG>OnQVJYzz< z22%|-6dVqHZ`UA>$HRQpeb*TyUTw*PVXO%o!dd2xrc2dpIqdz=LKl!^FMzWij>&;c zGl$JE_Q$kchz>3`Q1}fbZenz8$DAQftuwux;1Y9m+zu>4_#n&($OTJcTiKYp>iR8& z)hL1^^K$(FS@_;oHwX+JAW;`kmlhYKtaZZx4BswA{t`N&GSj5C2(&;=xCOWQjoDrgU#Cjwm|X zI=f7csSeE91eJ=vNcA2L=;QE3R=9tM9*0gJs1_l(5*to#&6eLQy{y7Z$P@gvQ#erk zQM1mP4>*U7V)cOTb!Z4nA05`oiM&p$gwa0u1fZl9^~^2y*T=9x+)W{;dQZ6fg}`T_ zOp-%YvZjZF>$fLJcAr^`&39KG(_aQ1+%D3`hf-%{5A*D#l=XF~ zuvv~+kT;UVasz_E!70d>BBzpvcct%CuA4x5k!*-GMYvOoc)5<0c6fA!ZLU}@sS3=v zraEA!k1)Rb`gYyv{Mlw~Yc2G(HO;j0HT8c+4@hGio)OFtl1Y$lGMUer z1);1o*Y>qEkO6Y0poloT-i4V}B6<-o5xKC5MLSFmF0r&e3dnfN4>@a_vok)xf&*7S z$Xs4FEIUKz6G8QhSQyR*0N3w~IN()Dj2a8C2wc$sa8HCdRr~^ZA+c)ej`N~K7lv{> z?2b_dQ7gKk{9!90Wr)z73KFb)Szu?@;+oVtU~?p5RqGO$Z4H#J-w%mFhx%1tWB)&6 z7`!Hx#Ekhq$;7cT%P~C+>*5m{drkZ!ieH;ns7vgV#Qia5m|rjkbPAPCFLBC@iFLNG z-RYbibl(k@H|=tY3ryB5rm8J)4!%_SyF#oNCm+JY9{K}qL_*W`u&xFC{aRAk)GD|}Musq*y*e9SEG}SZ%PyF2U9sYKK%#n{-sl;mNML6TAEgBjkBmHYQ1c619 z=QQc87}NxlBYpkfvOZI%IkB>KQI-;+O9)N-xU>A6E48a)!whvUuC*8$@>Z#cjs+a2 z%1CUFZNNZ3S|E+czoUrtD%cNSP~|Z=5Z=1CH!}P@)Q)(Q0ytk_=|~^ytoI(oPym{xCOvpr4AapCW~m+0Jh8A7 zWLt7||2Qj*l7b=zj?%<#Wn(v_N!@-#NEJZ0DXU2q{bY- z2z^_Sq$s)IHV8`zWsjE8s9^t_&DrF)Asa2~(^nUeQo?~vSi?Eg1&}HFl681PPI>Ow zDGTte-=>Pd3^-Au5{_TK6&z1hA!)Q)nCk}H<8&ytqrPoTE=diahz1?r$) zG?r-#O0F&_odVvCczu{Ar>5YpRP^~lP!;8ckltSXJE@OmbW^clI}4G70!RVZjoBNg z?1~nJQW}~b{hl9y#1MTlquXf&*>DvE4P%bhbI!Q_Ngj!H8<99B{dLXXr#j9F@J2N3 zWmdxEGE7Wv)eP)HtsqGoA-0sQ@&KYoD^OWHl9i3%{RIa>S0A`XclcXenHvDZtN{1% z#$LG5Vk_e@xEMs;azI1e$D;g^i5OPhs;f#mX8m}HITwkM&#gzDi!p!)X+`-Q_o;DT zOr{&-E@MQxI-~SgU3NU}h&kB67EN5|niorVqN+BR$%eX`iVVjSQ$+IIt$G^XI;_lW z2HnpvPw!Vls+6(m4A4+NuLxRdt5LKiTPchA-9)Nm{wI=7<~@N!#fzQJg3p+?_cBxJ zXBzhJW=am-UkJO(D<#msvR!;XvPkd?$(-Cvan6E zy0F#?ZCwOE6%HLN9_b9@^Y3ZO1_~?K6wo=O@t9ZP>&T}{S3BzaUIGUU7$8&cfUem` z8JchTwN52vz|?m|RV?ezNX`XtlL_5LmH&Q*?;_wjKCbz&S(TYEREW0lA$=~is7aHa zhp6h_O*V0C|a_;ymGdbF{LEF34sxtlYEp2hq5d%Ck zODl>pJ)!}dFp+e~JP~wH9B$KY9dx}aX-BnhkK#{VfPfu5a5eH}`MxceRldSdp`E9O z^Us5=<%0oJM?(qz0gL4i9-S%TP4Mh$uBJ(B*g>;;EpWUIa9m(C zGL~@PXJAnA;zt=XYnqJ}N+)#rYt9^9YKmSEk?-Dr^_I8~Dyk;Kklb4%)>WT|jbgQZ$T# z+OWwkYXEoql)#+1d1z?A^8`y9p9YqOv!!U~do?M*{shXhvr|^08zi&j6REqR&BF5g zM}653_$JGU`Z$U&l&ue4eZE#^BZy}Sj=2iYHBOreom%IW zLpfCsunlAz2Z~P9Ry2VWHLl*|A{JzQVyQopx}@jm>h#FQ#&*VzE6M7lBGACnD;q4A z$Q<&R=K3YjbH-&jw&J`IJ?R~=nS4SunrXd}vy~S85PEI^d^MG-p*bAp_zM@M2Ye=|vb*NWjq66lgIpvAO#h&BQnNm*(cHnuS!cNMDi_}C zl~9A_27Kf(`xhyGP)KQ|h1cw|_RFaQ>|e2)KH_w+*yYwRoU+(eK&JD7LNE%~7B1B# z%_Q0HQQJo`Wj+so-#2icsgIG{1KD%#dtHvbL3~NjtGL+IDYQH!qM;pyQ~MUNu*K41{Ie zFC}Zz{mzsokgqo0yJ_L&^2QhOh{} zJyRX6Hc}tOS5Kj}0Qt7KytMigk;rpNw8Fu~&mZ9hPUr*Xs2O}Oum#beA|o~jb`y`D z5~i1U3O3_LOOFOD>TnsDv+V>zQvohGNCIUwrSZdq1Tg_S#ht`bj4N|VA@SF^v zc7dlMTI5kJZPwS00jF$r1_qdm2)mo2_m&|z`OH>W3R2l9U<8vhouoH%ImSH{dafI` z>Q?Klc0K*OmKfdGZkZ-bM{LAvZ-x`Ra|mK%<9J;pU)}o%eWdbLkE>V@?gQ(oxi|DIrtOCscR{A<#a~( zDFhG27KsZ>V#}i2uPyJY;PHlUA0qqSK8CT;x-OGOP+13c<{md!%;O)S&`o9vWz*VuzXCrvq2$4~XS;FHIBlum(=Q z_gYBA+P*@tgCocRBThUD$ zW>Cz@Gl;C${z{iv?h|XEwYlm1-kD9zCr9J@6hZ-KpKWB@uO3_pnKiww_ed<1qj$%~$t zj~h^4H*$p4{~0lZn?NX9LrJH@jVDJDl%Ztn4qZZJ7~R7OaLCkenW}hCx6eQRalQqy z>Nq6fQHY|jx6W!j_0E+**)8#ck4dlwa;$}L*U*8oVqfl=^OT2o@u(czeszcU7F_cw z0>J}IX7gIK5s$eL;z(=bwvPN;EUK(Q@_WD;GkN1q2E0YO;m1^;vvDJ z{^KF-M}DV~ZISl-eZ}A*nz2Sov1&OQI#R8E*H5yFF;$<7^3s^NJxI?ue$Bp31rk zS^2b(yrx-?g@u6irj=4 z+w)9h{HbmvyCu|{ay#ex)Y|i0`1}cM#NyW&&aUb;m1_w&x zGmw<=IA)KeH7~_lPDsUXNG+Ar7`OgOOSmrk2boeX#AniB&(j=;O-Y%}!1{87I8TkUr#$#x)rV3 z-nL9-8}i)h3Ws07-`U`=%l&zuRDgBp4T9}DSM$j?Dijo@7BBDqDmkHonS1&F?pP8@ ze^d%Eb<=>s_fsdKB<+f3%$(ba1<&v6I}nX`7+$Ju*ZJmle)b)Jp&h%U853e$%EN6Q zEYF_@N|xmwy_&8hAZ4ddT6pgCRqCuK<=;* zNmJg9o<_7D|IuZCQcUV>KK23E6tSKe5bUEgkhjPOlcJ`N0#T%)^s-{GJF}?b_n*PcEv0=(HFKY$Se$g%fFN)Jr*zDzG#= z)~OB4X^ZLpiPSp8#PFD|Ig#L@AD%82Q8&&*j;Dd+EgB-3_O_`$%?DF50-8NVgvw=o zN_$o7WO&?8Y2%Wx>Zq9afLEoMnt`;ysW!$y+{!#K9|irLT}RyG()z+Di_o2EW+Wj7 zV*&KI2mA`9ImeXPQXf*eHX5#kzF7MZGFI2Fo_7L32tcc0U9!1+a|2p##zdhv{9u~J zUHKdYV_^6UoT66ub?k0}Yne)B6Pu}w4A{z99sT#{IbyU$j%Hz-H)HY_lHTV0V!wl# zy-q%jU}4sF;!u1*@?@G1c(?BjOD9o%!h&~B;};7jA6bufkut)!A698OC1o*`z>(%| z0Hqq-a?XhZ7t13t)IROw#a1!$)iNB1a)SaOX3J(jJ%Fk*U$DiSXss4uu_4w>Nbb`c ziK8|WaZoDK+xJIhgIWvN7&O(^{`1T~9qs^Cr2bZ@rjy>b^I<;RDRgNt^C@^2T5ix+ z#@7rMDJb%>g=HWCoQGDnlpV{M+j>xD@Tmo++#*qam_vfI^1na4;fKn(Sr@OUavQ-3KfOk*^6>5q&f zzWDQW^aUEYDv+q%<^d5|#KKAX~Xpu`Vm8`LJy#TE3xnzQonr0 zJQPR2Y79ZpW7aeM7=%bqxA56NQ1qCV5Irc(je;@w>l^=qbmVJcU5c_!HmM{chu@F~ zH@$0(*L9LnZQsl2n+4y8w5K~5HN1SLE5JX<;s_g?NpS=arUX%wMa8LX9T2@+SRxcZ zv+xr8d6d-^(-DXPTfQZlFTe}w0#yYiPchf&!5=C_lD^Vbn|(gmqr&eI#mS2h?nG!) zG9_qR0=@I8+e);Fi^!qDc2s6k{r4jWG*{oK7^pvC) zeLB2oWHcu3J+-owXm?hK!GX!4u0jaSxMPmK!Q2j+uCr5@LEVOcaDD#K>;{dH|5(_V{g4ajf|GO+#D%S0sexh}iyK8?cQAj)^g7HY%w$yEL8_T zcddG=pASoWpc*L%#2n6se4ej7JCBXAUcAX2^Zci*U`R!j9w`r#uf`p>m6!#zA4okx z_cl8IbMD#t#S;IXsB*73v;e4DVw-nc)U;N(-4}|dw>#WMO4~_y4VUL^@DfGNpfh0} z#8UvV52?iBpuKyU7r;3?^K>H39~aN-HNu1QP@p9o&0opj)X;+=?_B0N_^yS)%vwIdZpG%LIK)UFL63=IV=2d1i-LBq5V~4%4 zb^F`Lm~E$n@o@@cCUM-<&(=YLu^SX=0cq7rxK{Zx33#8|<3lI)hUEx#1WfcY6)&?hgxL|y46INUxC<#7rMpY>GI@5r70V)qQjO@O_%^|;B$#q>)3y| zzHYbC=cf+_#V2$BgpipxkIt{oPH5otySbg~&O1s>282>kWUvoJ*sOS5=tWILYF!PH zN19N8{9J0Ar#1Z3|5fX%l>D)0&hOK->_SyoO~rz|hVx-=ILpX(0!-`dEYD<^$D2S8 zx#f*N+a=FI@(tlbpomG%1~OI`y<}%Dt20bE3DS`g)WyaV2UI#1v6zhbUOlTWJL4Hm zKAc5C<|tECLSYc9g<&%oF4<4jn}7egpqifGpo!UY;~u`9Z1Ze*JWN#4WGu0ulsI3x z$rB|bDPz)H^u!@w{`*>0D1>PaKTWqNdP z<#r7s(%CcZ5hc?(relzSjexwS-R%tV`nBEM&12przZMzVZQ}`mLL-AkvBxmxIjyP? zOUCEXBs9_64x(OyJxV4BEaWiOqgFf!(~Lg{ph_u4d73_-MFo+KRZVJp=_)mlnzsRk z>sFHmO!YhSrC~x{njc?l>^d9Nwj^!=5b&XH;I&3@NRO2D4O?tShZOy3Qj^UuoF>d4 z{C10n^yASD;h)g~R%R{^yS}de)EMHc5UxaN-CvR&T2-@tDUjItPH{-#t7z`*xW~7; zdjeSe_+1qRw(-k>`vEvF4e7!Zuc+72__+OZab@spjMz*$ss#6aFCYPlrD|7=QIe!2 z(#2;t^Z{dl4{;#l5Bi+qrsU?7Fd%#nZn)=7%1YVjfi27DgBClAee&MztJ7eY1(P0^ zVs>H;zcDZ$X?_VX{^-KzBCxV9I@tu#UzUhUAi61|rhn7e8LE_%;llfk*7~4C zpLFvX9xk0e-~>-vc)o|c4S5wUm*9PzMlx8S=I4OPT3_>PKgWgdO; zNy+lLgPL1IjA{#xs{$?$&OY4TlexNr@I-K8`aJ|Xx;om>JyPL?N@(og*#+eq{T1Vw z)RBm4JTv3|vXD`8rIH8rxvwK?mG+_iqCUu0 zE~X1jHE#p?bXZjpwS=|D|LdCwyrT>SreZCGdDh&Mg0fK;Ib~SPm>D4h2fcwYr8Aq@ zU&jArvq@)O_%_J;i^SwXfXef!KP)>9@`f1hzlf#htSfYn`IUIHpon7VQ^D07J%D-k zD-fx%;BW?VroZC~1%nzwfA>~b=F{B}Oz746i z#q#2@`1*kM-R>rSxe&?A2eswkj*0IsHWpCk$*Uo)bteV-p1~2Off77vMzT!R*qgVr z!7ZoV%Vz{bK#!A1lS~jw2}3!TX=M-5sUpa|MbQEOuKBL?KV4|8`xIMmop*%g=404k#YIonN<&x19nsQzZ zw;egRTGy8u07$efRujvG_s4n?YA(f6=)(LWcob6YB&6%id$iORh2}>b#%)YBKjT6E z(58;FBRSy$r=|jDA%xLXG44=Rz5*#Qn;9`Q(UUGnH{LtzZ$5iwJn21e{X%T~ecz36 z=|7@Cwag23PjsrD4h?nS+T=F)ExTUjVB4iI@D#9|81G~rgz>Uu&6^w_Kyo}bjg%<{}M#LNLnLOtl1DaPcDRNJY?ucZr31;V=8U&L7WDRfn zGvbVS-SNkGw&@cNV6Yg2cA2(iHJ9F2;6?IRzn*)!@)ESy_k0u?{dfJ7;4BW0iGHL? z5D416xcE?+Ua+7Ox4yuKdeZ?j`aOW7YSF6rl%n4Z%(H0G82dF0Hp?Z&+A9*ySPP6# z75IHIjj;MQVHNiQ?rMsd*(v?1r3J;fl<$2*iDp`*--+!??JMFsT3{h;Oe#>E1r-;y zZ^Eima4iwz@Dpnx2a*J7cDsMr*g=&-Tqf@^_ebOb2>~Z*&54~|UkWIp z^)YnqoGDwQ_z#QQVr8YQztf>Bil!CVu6Kk#kI45hCSoO3LLB!FT4wLff2#O}&Hb9L@#s7rp1c z51BD?8u{zpm?R^bgMoN+0myo_jF;a+XNrodDL=oBhPu1V0`ZP@QiH29qGp;?sBfpL z4wFr{BURs}UrdtHP$^1i4pT#k)X8fyA0Q;8UM1^nhpXO;S^oOmFb@v*@sft0-hInx z)Mp^p_&+KAeECFZxT`)=*)?8(0yWGlaMn@m@UM`U~IZMeYFe>d;vz+iAAa=WqH-D`)a za6`^xn}3uV)c!tmro(L+e14@HS57J~iUoKIe;ClzPhINZRHl2OOj3bR5`I(YU|?7=L`0mk z+V(>KbGtc6-Y{z%lb+-B2MCRqn8#l3b?M(I!Lin@4IkZCL_}gqbvQ5CbmaZfE9y}D zN5k;9nhWOC#{u;_uExvNRsHmxKp2oNNt(Wb#Vj({qvacYqgCOc8B&TYD~52*6S}u1 zkcGozqU`|{v~OBnC@FnNqr(hI3*8tX!Mx1H(t|jxGr6e;0HT}lkUfJWV!Ujs#0PkG zZgySE$WN=ne5V4gGj=cQpV<;97Iqb4N@YB`b(5LDuYAo z<`UcX&M$+5sH*O{1;yC54FZ^FB}+t(TA%2DL~*xsq_R;xLT3$i-NjWrT|mi9QbB!P zEX=QDxG^`G?s^JEixhK?K%V*#BU)&sD4b%=04@N9{4GATzsWRRtXV< zPDCXj>kGdkAB^emkt z!Kjr@f*0as)0Y5XKMC&|`eSo0eA+Zs?_ZDl#*eTjPzvM~I`zwjAf>vI79ffky1Dq!fNs_qfTJ=H9Z`=yY zpEW&{`}U*2MK-*SPiWrDW?NB~K2P|o&0TR3RX#G|9dh6UcPt11k-HMpjO-x>AFN)n1Zx;hc>re+vt!S9fgi}@lz5dH7sxOnT)OS7)R7Oy zrH8lsrH|4ze73L!i6!NgZ8J_NXsX}MjTJQ~n|1#o2;8(3?KrC6d74A`RGp|AnbTm( zk2n`0;e1ivd;O{NXm=i}>rtwiv}nfGNjWr~*LUP2+M$de&;RAHk#${=gS!BZ`Z{)K z84J5Eso(*Rb=W6OW$S~-u;tM#b@B7`2C#2h`i+7q|JY<&vcE{GlGX5bfVhk~*XqS_ z9wflPd#*vd25Dt0Sj{sxgte_4BOPy=y38>uYoaf}?uu0aqK{F<9(QyV`}CB$WIR?&{U+sgB=v4^!P zSSxI9(@sH{=n(fL?-eiPUFbonF18_n_eo2AR%C#-L6H`@ z^->RmDs*t_B4X-3>2lX(#88g;do3vx-)-qFSo z4gibFLYgLFMTZOWLY+^9t*aSYDX*r7-Uj4#hZK@% zZu8^JG>7cQ#aOM8gz06Q(T5zW{OOJYrz12C**NHGwp^%GC;FLBU|!zyKd?#&uGC11 z44jK)X_z5sB%!)kK{a>O)e;N10i^O$D0wDE~m5eusQyl z=F6rd_?<~Gz*xG-6Z&m_xf+^ zpn9;IG2UvUcsd_R&G8L{rnVOho=IGt2r+HCWvmiB-t@TR=Z-!nZPq4btqK0Ofc<@67vvEVHYmr>o4O{*3aXc@wi-BASz`UWp$Z2nW?I`;>$Q7}fOFsCynV<|FVV zVDVfz2=_epsjx$Ka*y|_JIz{rA)3M!R^zAp%oZFcHp zK>USpV@c>FZWCrKuLCiG*0Q1k&WQW@t~NH?_BF2&7g$ZBbMZoeA*h_*Uqp<%%yd?k z1PX0dDJH=g^~nO)HBh_z4j=r8mgrhNovKx~n|OQ(H6DU-&wKC<;xsbi=HhZ+{A>Qp zyW2DqgGP#*xufpXcJL$I?LPo42l0E!f4AlI(F-Y0ydc!+3w&C@yGA zB%yVS+_B&$D;C;eB%VmX7orjzdmu*&0^&t0n39$gUHLuM_iU|QzEQe0zRs0C+K@}0 zG9ld7W;xe)17C&;ymPH5Ny-bZIb0TDS#7g5OxQ!6tY!RGE&;c7Zke*c;AWqqUtmAg%c*ZLL2_r+?ISz{b`3!P_rj*ACl!8q2dnc>AI#1N zjDq99xy_%9*r(c9)(E&OpESRqXllR3G*2Wx&a2UBKxAnzif7Q}lbZd-m(xE-5ys9# z(P|~Ua<&k~fgqPKGA8IagVWvf3iO=>(LtWmk9}{$rkpRW=mE%T(G0A{nvyIM^RE+G zEA8azbX6{;HMakDr8Of7sL^B=9_A^_+iZYjc9!_Tn4*Z*r|{gMYKDW<>yA{+y*cB@Bs+eV=azt>xC7<1FR9@yA9goKE18M4a{Ii zXuoNeBRO?X6M_@AcHm=1p|xE;P8kL50?sC@*D%>@M?>^6f9-{2J8t(1S9g=Rxo@sk z1J~FVddd!EIEAA8yGtB@#9pH#Se1~&l{1yE^@1P1mi!~RJlT*X?_xasDYc@L*H}Mi zvn!+R>TV_phYQ$E#%ET+;23wT0Aq9VGkL9wVnRHn`{?O9n5O}3VNXj4zn=SLxvPeu zTmBgupkcBF9nQp(<=NNL5my%TCg1!O)>N48%OABk@o?wkI%g5nO=V0fxaWoH27aB) zI(|m2+~<~-nwxu7%?W96d=D?wUcCrx-DY!xX6~Ai1RjzK$znEO%`t5*iH4<(?IsqF zXU@?$B2vmQrl}PtV7x$qcin`nt7QGfjCq~$--1Mf>`E9l z#X|CUbj2ws_fO;`kzz^Q9(E5?&T`&PNlE41t2$!R&?z_4jU@Hiqr*4wk{%iQnuACo z(z2(i?p^UEjFmm>!3g=Iso|lGtPDArzib; zBGe^05@a3;+SXRrA37mt4bwQXvvg)UZU!mc0XM|RY^l9o=*Xj)FjiZdrtYa91jrI3 zDEDvs#q$Z76l`b(Wk2br?faInW;~O`#=nZ$!WP`+d6#w>Lzxff+Xje}C=g$N==##2 zS&R{mJAr&1uc_}>(my3(a7)SB8b z$Z=YX3CjaD!6=>m-7iE(=cT2$@H^hCq6$ zW(TjT(OTB(_5v-(RixgSfQOaxGGkogJx4zEUYI1E^Z;W@jy#4^Jv-PZs+mIrk7LM@gy4Ep(EXo7l)54xZj!Y>6+G|D7Pmd!b53a3s%I1d(!< zA*mJ;P+&wp%$+)?vo*m3uhcD{-g<2HYbfbFokS}dM=VwtmL6l-MJLnr9eR4zAQJ!M zogUTQ|0o}R!&u%ApY$f*~f`kj>0SJ>qn(_(UG$m6gx`lQKSeH zB}UOix$Swj6@4B#6#=S$D{;_}d3s$|&YugXfK&Bi-*q~_)bbrB-+fcj5mf|Cny}!| z!QO`Br&Ny|N7k;9g>0}*@B+b>t5?GdfN{M*j3}}3^O!k~9#)Q9qM2~47wP^}{O)4b zR6%3Tmn$ncifJ9p1FY{0W!gE9vY^VAO-cN5%w0t@rC}ND*6&WT#e=d+AGk`I_-EgM z2Bj9=)-231Y}6Hbyi9+*Gi*W1p_jtkA|{zl0AXOo^4-#`d$*uKMH+(-^urZofkE;k zTMv*1Wqs7%;W!uO9U>(^GA5bzuOH>9A8(~k(1tvQB^HCDb44RU(B{RX3RQ{YZNX2} z;A&?5!~}$HwKnjnp;uA%3mdt25(UfbBM^YO_jZ06XGisox?I#wlnCTHX{?~D8G6-S zn0xl$_HO!HK5uNv5D?+zfk*>dt92H7CZ^O1zh=Y1?X(apykRPB#l+^<1={b*lL<=q zO9e(zNpUt2atBbO+VyBw=IKKa62>{xMKVk`%Cds1aRiP2Sy%BirWu#=LnS%cj2hC` z(=hZXE8fwR4lg_A(xqAvl$2#gTr0LLZrhj%;v=`iIAha8^~3!w#bo-4fQ8yc2MfOz zzk3cK%VXTF91Xm{t*@8Y9eagNNa@|DQ&Y7`6XFP5`|_nA1m5|^^V3hq1*ws1hO~`U zkL&<+i-e^u#hVAD^%d`qqBBPc?mHAGfgV(iOU_m45{^pe)j$kf7}P^;XB3;ch>>sj z%{Kz5nJbwZXocO}NS@`=Y+Ph~d&|^{Y0m7Tzb{Y4DnubqP;!@fYYhR=R9YbCofmMi z5iu{qiOj~Kr>#T@-rZ{ zw#!xib^wc};{ArTfPCKJ680`bE@7sX`QX8m5D0}DS}T^(DupsEXJb43_xG__(Iy4y zRtkq9l0HFcX$`KJJym7`1wjn@=Ehe)T8}%7V+wRT4{=`|D<5L({QM_Zr62uZzxMS& zp+9aiGbzr7Q|$0sYFsbYUHE;oY}|UVHaqhM#PC~ML%bODc<5!ap1Ka;nU9dI;phvh zlO!o2*1HAT$+Fn19YSF$eE87v^?peCT#X#^wIl5Rs=CG|#0QbKNQG|_%vU;*rs*uW z#Dzqd$~iIpPqf}PZlFH{_Tuo-1YIWv1-~l@$#!SCZVtgO1^yb6k7D?ein6pKC-2pe zjXMFXyLH$Fr~?OP7)8rc7RfYgZQY&OZyavV-bwC#zRHb!ZBZGajgo|-~JOhtNLvneYXY@q2HHJji(G_B1O^@XUs~P5>0QH9rbwk2@h8>*+o^mP{ z(uH|?%fAGYpXGCEzpL`;r^&BCK4{iF)@DVsk4p!g0KsS|PdzTlIc0W$h6mRMkujJ!dlhT#G zW#qkw%pW$n4s5k+6!M{VWljW88qP*fb+Y~@?)cC>+B3J17}f?GiL%Ud1U3nk9sv5} z>B7OZ+uWpL2teLbX!&nA(gjK-1E5=tTai+tzv2~#-Zro&p*RIE!evk@kG;GOIvLe?E!W*$|twRPIg`RFVM!88t7%b5a%Eoh75=f!VWc9`e6I=7tn|24sI&5ld7 zek$Tk&rBMqgxpsIQRtk9ctp_VMzy+ODz`T*`mGvc0{JjAkE0e6ul}tvQU02&jsvoP z*1pm*KL#SB4x8@!si4N(+aOGqclhb|X6W;khyt<`$DU#IU6{0#Oz6kZLD38u4s4UZ ztfRI)Pkn6}I-uaSfLYNV9y`?Eo6hlk^&!-3Tl=4WES>Ksa^d4uon8Yvm5aC5_H2YW zSrc0~pA(Sew*T4cZ(if?kg{QAs{40s2r}=MRF&mk(~&RSA2Ehq4LcqJ71wm}D;Rk$ z0@5>x{4K0eZ|Fog)g@uvE>!YDk@OV08oLUDa|g6gY90%gM|Ju@`vuhdoDJg`1ObL6 zzqeq9zDDV+xxvoz3}vFQ0@yN(#Ff7kiiE{AmPq>e4^xNiQ_MgLWKfr~GpLYje0~x? zP_1L*#2UvjeU>$uiOIk}S4H>v*Dg)XaB&CndQ_Qi8BI#IXa7ror8GYaP|rh0rvrW# zugQFbAcaXABIF=NqZvm8O~!THxcX(`K!{v0RKfvSaSc?) zDNyj^nnMcqz;8Ine_KL8gBiOrP&rh|C~-gMv3eF_QDnCbgH}5@oc!Rf3MSruZI`MB zUTZd>!rcp8(?gC=?xuB@1CKlQ4&Ez#MlT~^&9RGrR|pazYh#zu5#PgDPYtM}-8|O8 z;?L0bxUAzHn;{lxJMqPyZd6PpIy_GhPEk?`Ah@(GANmKm?e%!1s?m>9!3 z3w(W1CAlZCtmb`H9G2iJn<&#ZAogfF?U|gKyFQzipuU!!F z^FV2&cS)g6#=;v=zP75nYM{4p{8@WyQbI$lF(P*EPw|Q0LF#Q=W;hpm03AP_MG>J|S zwP(cZMkD{bPXOEc6B4kkI4LENnmaP#`Xo{I!h)#A8vPemO;4q0k$smKc~DjTQxnvm2Ay7TVXzx@Lc#hJ6ee+@|Rh_Nd2JwLE&ik(TB7GbPPmUeg*lK)){OYiT$^Gb84Kb`*>oiwBOD{ewI;q;&5}# zBg9&OxA{k3i>wK|<-ItL`StZhXWF?KlCmE4_zCPq!dcAT8+MaSnK7_Vy#C#3Lc`Lc zQvz}5MNK&Tfz@DYX>UYM$9yBdW+f=NNWrX(?GEUaIOtD~B1*ZnvFM)TCt$L9MCG@- zC>@)POYtNt)LgMS|0qD6lkopBR#_DRbJY+-t;@v{(@(YrY}D<9B3Oz7Cm1%QGIy;b zH8kdj*)1drLvKu5xPJD8Qia^#Q5RK=5cf83lyd{|x>mJc5hjvyMLzVEy!w=0Hg107BS;Hoym_lIdO9b55|fM1*P zj|J4hXQqT5ne4u4HIO`#tC>Q0utBkFa*9fhwbX0&ciXAiN zq4|_;zB_#!!L&EaJ1Toch9MFh;MITHfwnrg#L03=hzlP$?ep7H>$+uL^M|Vdw>X zMV&a_g|!c#=XM*jxc`1h(IJ}O5x?(n z`jeGIs-owGGSLBIwnwjPU}*Z&DEtYbXa;Wm%yp{KDbd?H3$?f~fQ%t=Fo&VFG|H2! zj=ar*z*se#X;)1!Y(R4(o=dBnlMZW!E|1*Su+o8$D7Osz&auUogUWX^BZ|Qh8WfOx zIXNrYyj~CYuxv?*=` zTT&7UAS*7YjBmg8lvEUhfOdw#Bz$l>=^Ns{1twsDBDCt&)Q9JEa2MucIlo3Ix?_|Q zTzK6BxBtmGMJNb^5Z^WSae5HRZkjpq3TdJ>0snq$Nbs3NIOp%md9n#Z7HRxM#NGT< za=KlvF7M&Ua3q@1>bV9Dmw4@d$flxAV8 zQw{8FsO28{8g4(eu1c9-jeNuTF=z0r$!=EPV88Cb=rlwVt)GbL&8;l|xLrNQ$fn)A*Z}QOX?Fx17Knuw}qL zdi$~4{P(5IZrD{8g?bisqxCHETDKG*_un@5`P+6?lC5Tfo=84Uqnn9ikz47}-3D;Y zHELiVMz$~_SUH@$O^n_TCKC;x>cqgAc<9GFp#hAqlkb^6sq|Y1J2mZlx1w5i3U#9a zH`k_C4q&eZ1Y+&L^w}j@y(00Y7 z1nC;NCNa&c%n#|F^k~54-3Z|Q?L&IXhJuAH$g0%66A;n}Do7bJdHW2WV<9(%P;pFb zCV|5mLFK}9nXaS2IJ#-n>tTY-K~ub!;ygClcuNMb(>0AcR?8&#GGxVJO=%8%y;FHX(-vmR*%%5NVO;JhRWdc-WVDeu( z6kf=a`FxQ~IrE}LIpns<;5XQc-uD%< z=8|db9f`|9e^ab;VsW~}H337-N3LNIK-e=DDg$H?7 zFu0%!vqfG$XIym159L!e(QJ(&<{34EPLv($P5$pvmlXgrY-+0AvAB6iBT%(^foteij6f5i3`8(Twm5KA{R)@ALlap%5D?qh5jSN0Tb3 zDmF<7lI+_%GigwS&LLVKM7vruTt?Xp;_h{*%j`^|m`(?^qKYr$fhUC(0&}4_vsL4< zeo!0FF$uW8aiLMh|NKzJbi;_N2+$ICT=nE{q)doZnN8b&+Zt!$-X_XOzc>xFb+nZ; zWY+9s6Z$-#*M>{X{cSC@`5xTb#sfoOX83m!%hrl|bAcU|7v$D8J0l_01z|d1Y#0Y7 z`8435fJ@4gU%l}&K_xrOet1urml0#VJZd{X<0>y^G`6wZ&|HHYIU_|K z&E1w4MvK3^mmmK{D0 zLEP(}n&5r(cEnrf`%Xcp@k)$-^PdIX5^(j4ZM;kEJPztG$%X9-y4QVt`4Z^6 z!(Mu*bl}K^to)9(qAQLziS)V?lN#8|l@c%^;NwbK`H%L_5_@c8*ipCM2<*Gj_G=WF zD(=XpWVKosaPVxisJgX(!8?D~`G5ZjdYco4Pn9Xc(RUtpv5fj@R4~=Q=R$nk7ZJ<1 z$2Syfd#L}eJBAEe;0IWoF2{?aDG_39nc1`%`ew zScDgnl|mFz2BT`mhpqq>UEt^EohvlPowSH5?)x&ZjPG`5zj z|Ki0Dgg3ZZi^FcHBLd6BGTbGi*5$~q$T6jV=46jp^=phZ0evo1$*ukmey$OKq<#1O zgWJ{c6y+zh5PszEVqtl}*pJTR{|U*S<~CYEv30p)pp^Qbxc&qD1b6+#OjDDdY)OJN zmy|@Oo!;pqQyG~e(Ms%HL)2$-tt5vjQWs?oc1xVeiQ7NBNrAFyzSh%oQHkVQp0(Fu zkT$l?o2D`0HuLj~Ya%6S15eM!)CA-3ZRD>9c=o!=wqln87I7YndQs=*aHN^ilu2>? z_<^Wil@7Q~z{ZtFdIg$ZUH?Gk0?8N*4YT2hnw2C`Xv9T>mM5x-aJ$E95;LG+%xK_a zMg@ayBs8mi&p^qasMY67`%a}BCOR`aiya;?JaSHbt(Il*K2NaG$AeV(o)^12 z>Bv;Mt5sl*aG`A?9$}@W%%=gAD&N`dAZzEVfoM_cd~?L;@IHhR=OZO~%{_Au}L165_81m3WInavf0mXEmC6rH=H zEcLCqa2mi(C=iYx{FbgYT5}~O-KHqR=H|A24?^~v<|Ang9;`9!9iZPUaMqJLmK)LL zptz-eW6#KKXMM&{Gl8gLRvE4J`d}gJyC55)KvsXFy1cWg6Z0W_%$%IS`;U0+&b2`_ z{exONfWqK~UB{GY=OJrSqj+kI+<=en0lOLzNS>Q~vA~T~DyRf3ba_p{nM$)%IFKWP zhAJSpch<7t$C!4nK*+eEt*j{X^AqXds8Z=%x4RU1D(C8Od!EaOxUjKxWCBNi+#8C)OnZCDi75=flSgQS6`U++BvW&wQ$vFt= z$CdsxlV<;FjaZAX%X~W1(0Ta?Otef?3T@%9>)mHr!GrRqri9negBx!Gl0hT@dBOuB zJE{r968kWD#X^WxD^|g1u>t@MMlBFePS}T5#MloExpvTd#qikyFwA|Jv*G+M%?p`M zp=H_9b2ZFsEP>q@c8*l6C4Lb}0%(HB^qouiaddKJ62{Dz1g$Qfk4SdjI7_yl|;JhlkYZwtZa?!dLW7@O9~QG%Eg%n_tpzyD%wpc zD-0aC%5)dtn=>zRv$ptXjz+64?&&oClm2JM8o3>M;R=Jza_{wyJh&3Vw{k!CP0xA{ z4?DI-|NF`{i4J+EW}S(JUF`y@27mIDaBiTtSAQX<&~-8XQpC+0!$=_ac5FYQ&e88K zZ*c{Ews>j7y{d22uSSUZmKv4Yp8qpbjX_(hDsR$R_dyj4Qjc0>9god^9e0Iq#ndvz z+IJAy_6n}p!6k`dOb@y?c;3k_Xvh< z%IsJ_|CyLtd-|$=yR;qVt3(y%P?R9YAPHtm&jo0R1xzU*a9`AMC9uI5VYtA&mrw=yOKIEK14)y&BNM;1!hru z0RAeJbh`afXEw8~=iX!fA$IjAkBOC;!Y1h)@ZHOG2G9YIn?)>$Qdt~i|BLfn zX`(m-Gr+OWaI+WX9HC8Ihy1H4R`gtP;mj2xl_|~;+#zb{0O!M_4xClA8Dc{3Gicqn zNlwky78Msoe2bV&^VXFp*R8Mu963rGE+3KUhcHBNHRzs}(5w1YX#02G=K(kkU!5`H znmVYBn{pSi`n^!gJBO&Jh{F8Mu;Tn&kWJhmAdqw%`!L7BxHBDiotylBH;Op&edSz?@xGInd%;- z)Yo4x^sr-3(8WCvj$)tSGRL$ghD|^Kty5OkGH^-(6G4S^s-@Wo7w=fV{W6( z0Haj8d+dAQMN?9IsdkAF)q2^y_?OAFc!?eh2HckN-2?@~F2d5&MK0Mf{cAvz#aC|Y z_89W?H*=ACj(NnbXX#kA3aG;rQgJXB{fG{!>)nhI-fE8TR-dKHyBKIP`Iy1tpp{T+ zDzps5#a7uluqXxn&)o!lWHS8}N1~!*Ss^w_)}w?w?!MebMEDlc*S!R}OwgJeMR@UV z!?@HoTT&uu6!llPDeW*Gx)-vYN~v{EwxI{oZBKNCai}<}chb6zS_4@&{W7=3g=+o? ztuJ!8O%F#CjAYUykF8_Z^Z0>f-?T3umn#4*7P?CK52?6u?x0yC@w&1F6!|zz|4-Eo z?A3aKv1i|_MGo!%KwiSIG3Bv=3fDy0OWxF{zA9c#3}N|`0gqT9Lq7@s#m2oHP?%Ra zog_w#0I>GrjDL~B1o|sIMjdtYexlT7p|pS>=Q8Z#X^@4%C3^kDnwhgVLa!-vq=kNf z#qSC%A;d85^cb4aifB0%ZujV1**ipNRS%|7ZB;h)B^|u?mpGb~AKAjnBWY6JT}{{M<|nnJlc5+Y2+WB+_j5`5&6FyD~SzooSHb^X3?e#L=-HvAxL7 z7ODHmwp~^L*sahsJ4A)`a!__7G;d2#@x@dxOR5R% zp}H@^C&w~kbUrpsyc1s*GSO*|KpM>{DA=}|;XEd*x`mppC3%%=*6`2yB4K$5KY#z0t2oo-K@26q`8h)Ylxn~~$RsA>_CW}A)Z(&L>1A)9fpgGKo z_i6)|*xHwl#4N4?gBj^xG}~&B!Ds?JF}-ynSX-;B3SU;T*r{Hzv_tg=qnXjb)X+d4 zXZH6GO?F$|7lc_?cYBjF3_41RtV@8Qhvjr9L1kJA0h*8)Yj6qMO>CwQ*~l1KL4zZS zmn%N&ZE%TpXMab`6*`-VwLnf}Q~8H-Q#2{o)xi>&zXqo;Kwwh8#>Jq0Oi=br3<58N z{6DL^JuteDIsoWZ3h4$^(+Il6r`ll5U4sN@3vI)%FZU{D$n!~2t@PFJ8l~sJPcnKu?mH$onU&br^-C&pJ#80WX z4fq|6$U@ESfN6}GwClNs^cgmt{!9`z$h%{N^g$JR=5P8#H`N(XycMqi+KSYil4Pqk zjjR9r#P`*TW7cO|E+O#k(>;hosNDI#lmm#p22;zlC`!AS%!tLf!kPrrj$Wf3le}!wo*|B|$=&G@tJ3@C0jvy%RR*E&>L^4F z<{MOi3qJIHr`8o}6_gb|+1aBi&TuNTWyR8F zgbyRoy6bRin#AYht6Zl|_mBx*VZMQVhxFnb zra~absESN2uL=lG(yK?SIu1vQKOBmc2NpJu1}Xdv3XC16eLm&!pJ<~dI;ZHevTk)V ziiNDu1l?VkPGZaCkt2JsNB54y;mK=+w)4lCK1xwPSEP1hCVL&^TTcXCOe`?>l5o;h z$qvF|QdAgmWH}%>RDYThM14}n$7YEbj1lSG>bl2aXI9)?;#22c+uwEM_H3k>_ud_Z4p|Y;vkm(#W(ifW z=Gb44o=g#EHQxmpTFZ$7kr*5$kyjrfXnA!U(n)Ib++?~&)cd%yK|OjU{|OWjha}sC z^^0~lC=owM2^q<^9wD{KE;YIj+UVBtE?#%hbD19#0QPgh`Y3o-au{_Eu}<@~mweoU zR8s}OFH)5{i)x4RTNnpQLQZiPaz@`I#&EFs6LflUc`!h#odl=nvEG^0NO*p3IV&R0 z?>N%)zI}fEabX2M&6PvmCOQCJdxFN_htswYCAf7R?~#fd@oti1p+6mfT*9TM+ z_0w)^>}^i<5Dd8KJb#S#BKF$O(Y4dVP8P4MV7-7(`nJ#_tsG5k6$H4bp>6 zW^~#JcoFhy`RY8K(;f6>A9!~-M@b?9D{sm_{%?Ra_Qq-47!X@+*H?E-JH0WYhFZ1& z9^3Bw`7kG#6CM<%En*mn%vZ zXE-VsKQ)BsIumg7J$eYiJY1gG;o`_3dloxZz#L@n&CD{Ym4GujVz) zY&0jv(ATr8joa;QW*G1N&0puAi^7*hQRUXU3=qLn%ta$#?Wgk<7wp@#L}-Y^wMTKV ztSM|K?zxiL3}bUgjV%!0VQwaozW9E0AER`lW^w- z+bLR~&X^4sY`K{%C-LbH@!kGBiGRFtV)3XWGb2GM+vt`gH+u%p%Ddi#bVYgh745I_qa(zk;=G zrYQ%BQIwV}ZT1}7;Nx?m1_gl=e|fv76`F(a?=BuEfRF?mdr0YU3`&@0NrxNEAU@`J z&KkDsW~)K}$F(iLRl!fSa+3t$vii&FZpppRXi$D4Z7VB^c%qo4iY$1||LTM+ZP?J576=SLG0 zkqkY*ITc^b&yd_qJ)GX+2HMk{C?xfiuqQ2qKe#tgI(XCJAiBA2ww68?4~KS_*4LBp z35m?SCPpTd(V%=2kSXg*(P(z?4;wel8!A+?xh*+vJ@#}v9kUdfjfVk!q**)sPjG5X z9vHII!gJFklYh9St^_ypB2M`wdq0}zUaqPs5qE>E@Rt3Z=79Ydv4eS)ezmkxEXG4{qgt_M4Yv{ zAR3kD%wTQdM5cI=lS%iBJ=BCjx+1H-(iGR@5tR(<5p3N5H7?^g?ieoKjimVGS)~~P z=u(cZVP=yFgK~N{`|++CKwTGSgR%UMb+ILN|6}Jrzo~{j)_NJ}mUyU1S{qHv{Ou(p z9fnIO9Pa#!oj)7xjYhU8=we+lndDCwduw6+x2ckovztHS`?HLQ(R3xpZmu<;y6^LY z5q}<0AAu=^2ddA&)rf=bgb>=XLn{)5Wg~Qai7cwLpBb5ZsMnYiAKe}pL#C^!nGylQ zNH+KZhTZ^UWYWsB<}c6DcAB}wWZDc8G}_raPiz$LY{-$zH`c0}&U@7iwL7g|*pp(R zgB#;Ue*UKF2F2I?&(-Ql4+kfBYfC&ELwv@nn{b8_LhWa_YRi-yKo_p8;u72e{PcH$1k@cxtaJti2aXi3@+(TFd7W6 z*u#-~XbXQKdrlHs+2+UVTFH8BHy2AkKkL=YCzj($cjG2QwJATHprd^G@h!Um)vj+59==8v(aK2ko{3}{c_nvMBdk%jGNV|A&*bJFd;&ep|f1pc-&vb9mfh=tzvO6vZb=hb5 zW50l`rLg02)>H*?CkLbm&x6)>WZntn=dr}x7GVQbWTy9F{v?}FC{8*f-9VEZgqHFc zrcbWZq(2APF^dhG$!0)DSVrW1!9m*^Y%J3pDCUcmNIoR^ z5z(?J5_DrxN>t^tH~=7q-`ZFFkVAnIo= zI7Tr2co(U`HI=-+(TyXMd9c;w{L9#f47LgRaDR{t@lZg8 zz<1IQb`-d!WKi1%rBjM=icnT)A4_8FwM6D+1=%6}8YTt(6P&5w)K~d90A6{^UcK*9 z(5XS(52tiYtvj0skW3Xu<=mjVbBNb)R9zPs0{e_Q!sB*`5rjF0a4J|Wca2kZNTREV zuJiT+fc&DRpLqosdiJ=TUkLt!NYBn0rq7=HnWqwzmP5UCZlyzRuaO;S2nq1f>J!7+ zC$UFbnn1qq+L^IEA|`NR-;M9deo8v3y}98L52|;rKA~n!c3)`9-~(Z;YA! za-JiPimWT3K&d3U!9nvO371fvXshRA?}@*^ipJi_XSs>#=%OG7us2QTk^;dX4d4NL z%9vJ6s~LP8ziF_lo%A>4s!#<6#!y^9Gd`-M`c&lkO&Q%(w!PWi_@PkDGq`hbU*BS> zI-#~2d9fjL=gewKK6rvx`*UQ3gDLLlCMC%3IKXYZe)$+r17gz*zI$gxQD!h{Cf(?v znt!**TTV)pwDax2k%ow%_=BbzTFUy5Z zpmOzaWbkXW8LjDCIKDECAc_o+73wMnoScz?x0E)%dTWx}asoq%Ff|o*)()6i9@})6bbWFE< zf2njS6%O9jLN(1(b%zKwmy;R*VY17zKNI)U%Rui$!8v3dTpRS-MilA~3SjlAU?_10 zkQk@r+7QbdbRjD^bo3|~rH3imna6g|)dpMOF z7=$%Krp3O+5tGX)wC;d}cRbYLQRCE*(gMy&GX0>_5B+h>n4eak{U)}b%5|@7m`Ww$ zo1s64E1UAN;2J-m)or{r1iqW53IhU$=3KJi2mUPNt8t!MzX6!V(TvNwrI{)a(63A5 zADtQ&17n|PKLZy-y?=I|Cdve=m1weB4L@H0L8@sBfEREb-rFpc9UL;uUp_c}5K z_CMJE{HZ1NQ}6|VW!bQ+c_2mzxAlcmuO=AgK)$rCp|RSAt4A$5>L3O6SKoa~s+20R zqKG5~y7#@;c;~ThTeyYXa~BWg+oU>+=Cgey<+HO6{~;KGG^eD(F{TdSU8-4mRPnQw zFb7;DCIn!7NT<}mE46a^wsXUX6dfqqfb;dAr5o^^Fm7ZpV08idz^UhvhHskBf=ZS+tyn6J)2b;MG`T7PYW+pA}5 zyKFsl(F4T>2>U8`jf_R6y^1>O;J&M7ltgm7Hq;Y=ya%!qsgkGex%EKzvzgSsC8jMZd>P+DAHg zEI7I}DAE$VSfoHw9Iv|B78A$p7}lduZ9YS4ls#9H&o5pnKuc18lv-}~f@o@V7Plq+ zfBM^ZVDuy_#x^{JTC&99kVn+$l+|=bXsZZ^7muGLG74F=pSY(Z*8zn@I&hWB%o5oc z1WLG&d2IHgOPY8T@(vYH1Z=dP@a$6nD?j#=9RiB*OUqOLvsmKFkJ)*2>@3rgNZ(Zn zfW|eEw=1UYc{>h-x}M34n7=N*jt-BX41IGdnJooDGEa!ctS=D29=@~cq$c6_xS9Ww zp*$%vSkN~Fg4DzVaDL-V2!MaZu?I$ zle_V#_T_Rh@@6wf5$}fFI_0JIvv4+G`K&*5FjDcbqU4+8MV5{m1`XzcqV*KWDUJ^4Lfb?Dp^ue=lBRc7h zvZ;oXv7iN)6_@z*a*MyOG`ZPI zjP+wU|JivqgV#FJusOf%^UCMcEM(H0iCamqPJXrTLPhe-XL?KQ)iuq`K)T}1&_rkN z7gHI_dau6L!m*{i4qX@Qk%V%};0}5&MWYSsX^h)g_%C03#D+8kS$65>ZCS2o75W{6 zrm@c5&-|9@lC;8d{bv0nD_mXhy`dv;h>Vi>VP`9GF7qHZ|Km4S9*AecpwuKe+{b z>7Xd~J1Kpq9e0t_STg4UH|`%$9?u24w5hRPTzZnZZ)``bs3R1U7lMF!5i1Q(V|_Jm z{2N2AR$pB@jR{+IA9v9roa^Bom-bsY)v&1wrXX0All|!f+4b+i3oyxSJABH2vm4A< zcM^wtQjI`sxT2k`7Z<&mQs@C-boSuM`NQy&q3&~>wDPL$K+JVYL04flW9=DGR4bZ6 zA!P(VL<2xCS~p_$Ayl7?(LKkh;rUa&+Zqo)Q^=2(zExY2&q;Qw7p?cxmtwI<|+ zpAsybCNwQE?Ez8sMn%=>&R@H>O3Mg8UDrd}($ha$2%(pJ`DWBFS$R09J+Dv^@J{r^ zMj%>wMx#^%jiNK2S)l0R+FC?)*u6fVai@&)EqD%XGyGQOLw1CrW%2v&pDY)|LIc4x-O@6SF9rpdz+KQ=nU$FZJ>J%cU9mKrWqg|AaxNiXTx55naEI0_@{!2_H55#$%pK?p;dpHurPJ7ps%ZuiO2%ath5 z7$SQ}Dif{GaZ6c1vlal#xOlBy4SE=n%jT_#!jnH)U$D z!#6+B4%2YUg1z49h%);kvJjmR3}CfiGTeBh+W<}(zDT8R4n4FHlqt*^;#5rV(wNJC zY2`k}oi`QVWY;g6_RCC>Wpe$m9Dfg{+630Y6C5t&Unyas&F)^Vbzkwfj;i$8fM?l} zv5IpWEj&#@-H%jR2O$bAL-{>AkoQ@@G?7aP<~Clm)H|Q2ZrM*7-Rw%Ux|k~Ldy)?4 z@#*8dFJ7&pTGL)&o97VC$X>#4=}im5tCMl$JiO-5vF%2Wj9u%k$x4EMm`p0|4}yzQ zh!peuFX{MDiSVjrV&a0Fm4o<6eS4@&X`cSI)YMCsD@2cq3Qgh(RQIG+U|@}eXn)&i zwi#F7S$<*?bC}d!or3GslI+yhJ%%@}g1( zxIqV;2PrZCST{!c~lnAka7rA67! zxAeUar?=4;?{PRFd_aR_0i0XA49As$0}XtP=kBxx-wRzkCa*mIB5j~}BQyR?6Hg>n zLi?5z)bFo0Jkh1;#=xg0E>KZ0qQPp(*0n#z%j1BhHIEETM^xf{ zzG0^xU?Z&|Fc`fe`^U+WoKNsly1xJTrrq#s40rn0-N%dZwvs=20=w`zAom-mt^7!A z{YQj_TPi_Kvx+~@R|}(4Ytt-9e<#Gm`}p{^gY}{FktDM*a#PT+UKu2&B3xIe zidP41D()o5bZMUvXBBCI>mBPG#_6zZAHU@+Gpgz5U(v2yy@0A!>pf^c?7Crms4TYr zHB!iu0)oghl9`nYEj4FVEt0B zYDg|&Rt;v<`jUt8Ae_1dKN2=79vff!NJa1F8}Rf&5yUw9_;aP!#MAoW5^DWN#7hQE z7E%3RH+n_=0w3Ej>WW2-+C||>oY6PaSD8LSgxvOOtWq|{zNjzN`~{O%l1gBSg5a(= zW%K2@7QcJc1aCMaE@+T!%h@{w8I1cO@(0VTxG2T*F-~z8qkD62`%LTaqomH3Z!FI0 z3Zfjd674#f=nmlNtqtScr2XGnGpzl*vh;&`>gQZ1XFk_zFx2s}wZ?s{YjACmjDOGo zx1^3I1A)8-MJQP-Qhb}T2%VPT_yG)e>Fh?3#_k&CbhsTBmxV*Q=$4m09$F$x2qeBR z18aM2Q=V-0-er<&uOKVQFyvUaU_a$0j|zB@YrBW{wI*z`!4|CGkZBbjJYfJOi{8u> z{cI}v#8nm#?S8UQ%A+1272Y!Xeoe@z&t{aRzSH^~f8qe$f0Q z9n72cNZ^g>UP6A)z&%4Q!m$n#&Q_PhIV0zf-e|9+Ggr8zR4$LBuYn90%)40Y7FTE( zr)f=Nchbx;M#rTqrR7I(;`Sg%XPmTlyM2Urxl(k6^|PUS^)$<|8Qu7&np{DVUQE6& zNf4AB9CC`ZPD?;g#uSpNA8DyzYKPjMn*Rz_MX9BT( z$iXz5Ckd*w{P))hFhaRM26TKIakTZ48$|Z>sir6@doPyX$+uMao`)W*HbXF$h%mRm zV24jv&&P`srZC-9^!A} z$r;hOeR=#$f%k+5;2ZCf8OS4nx+A)U=LQw^GE4nGcjJ86!priXL${w)cXIjzILWe* zBKZ71f6rhbY{{foYAmw-e$TfH2sUmcUvhx6ptgg7(E9|ogdpBRJ$3G%E-E&PzO zzr{S862}7l6tZO^wM36=ycdbCYnS&3;DEN9cvtqmHu-Cup`Ms%3uzAZMc{!g94suqn{Q$Imu&44QdkqCF|!LVf8KRNWc8EJdnFja8SJ~&%NcNaQSggmki#)SpXV$uloU#V+DxXP{5oB2xO-cUXt~{`&!6F zKkq@}5sjZ55@m?)gRPOrhsOXuHSizxw=YS&Sog@wS3Ot{idkk$Q4S+A6-F?g0wt%A z|2%(@l%ZImci+G2F&ho12(#Ov{ikIGn`dNLu^6_aL~-ktPe+v! zlRwmkc#8X08f4G8+d8A5_x-5o{;qKV&mn1hXDr{R=Xl`a_`IlH4h^~Fv20Y8IKL1f zI22}h6Ac@&C1uf(DN4R&4|mUnQCExlt?-9?4}Yq;;!@~fpbW*Pi9@w6%xTL&-K;0Tczn^ACwTCB6ZZwOM>+?CX1OiaqyCsz1{$q{Dkae4$1W{e_g>Ae<9aB^x8pc*dbb^U*;>MoNLQY4W1cajuG9hCB z^X9G+^We?>?8oEg;pZ=k5kf;6=CE3Q1nkD_0$*{{>vx4h?>2Y33z}qm=5t=;W4|=) z@l@mV3CWc^7Mx)%38>250Yy(&=R7tA?kl9#4A+Ak=14Q~Gt=xOF4VS2VZx<7`IKfD zE(?1+zs_kljJp#)mWy#4N8k@WX@X0s`i5~4sB7&Cd zs%^ipV?b3oyV(vd3GqZk@(%IJZKMJoP5~J^Xn&gTS~#|B<+4T^y7xu9_8d?Fx>CyX zZ<8Uzr+sob;Pwh}DedQ1(ut2xQ4!jJ{RHn9!(!&2C>;6DEpxb!&ooI{EBk8hlmNGX z^Mmxb^oHxW^uY6k z)=L)-!&-7aIKW;R^*n+xbPq3!^RLl((r76q;g92&TilLr0KGp- zPqGCEba#Z!RL0T1%076QvwO9P9%6v#;U68;>_Gq>*84*QwL1u($K|Xhi`kGjMG6_K zs2)T7sJWy}&qn1GBfgztW5|Ur-HE&0^*??$Sg8Vg?3^v`s)=?TFA(GMSKG7&7x->Ue( zszjY&1tWCRI>rr2;_9@W3=!9Xt}a9KexZKlG4xutj586dPDx={eVS^Z<$rU*_@58a z@e&pA^Bg0xhRcbRQiN7~^RLkU3?$z-ww9ID@SRhYx}hZ4WITC&*dMrxnL!u=w;&-T z@`FX>hPY#Un|^FcG0`;}GBt|q^1%-7rX95E@&$K?t;ym=d?bW>>g-PVbn0Nm|;}+j6OlK@N=p$JE(m zEtl%woDMhfQU(r$tNYqo>zOY*4Z_i;-GPVD6Vrmq*>=>n%zh79s>>Vx4>&(4jqE9p z+=p44ERNvir7*4A)=BU%NBTvxGG>~4TJ~){K;29eZz|zml=%@&&1t>k2E?8%TqMfS z-+6C$s`5}4uBsWLxv~w!0+~V{>+N_p#&JRRpFnJt#13jMze>g))#I5g(fKmF~qD z1sBZw@J}G|-@nA$W#n-e_|5F@F{<#(8s2^QvjRuJTT%?#ZmCqKg=i^OXdx`G z#gsO{&8h2IF}Ai-&MUpENIFF5Q~WW@H-y9Rbq8PDrkMKHwoc<>I?&|PR$`TUyhZGr zn7u?dhc7E_dJP79v$k$8p<_q&x)c#I(Ssj*Z zl?K9aiT?P>pMG+;>}$M^99tJ;Kar1h2+%zLQ4zvv0q|#X!AWh4X9f_7)LPBpin5`X z&#Bg!kA;*8&%EkR%=v%s!KbR`3cv*a9+dMV<8AK=fl zC%afZa0keS3E1wzrhLFPLU~{f;Kx%|fbRMK1m6RRV6U)4QoVV9MAWRH{zd40e!ug{ zbXpW)pq`5VG!}?5F`j6YEWv8~nbVtyrbNZ1p^G-O%*^iaqu2?Ki<`~|2PPVvm)&{a zdiMu7Aown?DQF0X#?iAk+ByGogLe7KuEhDW>7DJ{8^5K*<=E`#n8TGs@1N+c<4 zMO(mB)p0%#$jX)Wm6P}wYbB6M6<`XtVagk|mg&FxoE2|CAte=WC)wW(x|6QfgFOz-Oc@~^t4NLbXM52hpX$r-14BO`ci1pIOW_PKtM9!XdnnGmzH9o=tLPl z$1rcT(lW?1&CjUFC&}a-r@5N7qhd^)UxDe*Eri8r5UT8Zf(@u0ZEk~r99w0WMYR-4 z&J@L`Yi6yp=^$YvWeAF@oNvA@6d9o*&I;ryXnf_`!|uQ(RyqXm%DS>DXEJ3%39kC5 zt0RP+-5+gE2510`c>McGj{SHxxj+5j0Bb60Z8$n0TzT?=Qca42?4?R~x+(6&jZ)T+ zgZ`sh`q-8zYs6l2cWon@{7?hdd?F`hbk(OB(OivOzzHT|N?C4vR@5)($6Vh8x&0Gy zeagkFnS>!{Lqz(9Kvq*lXG)*6YIMzhBHd#!I-bHbv3|BD>cw4mcem`1t}-);A8=qY ztBd!nBuQ*BwkbFh@q53?sU6YO;c31Lgf$Kxdc8KCZ)6~lFZ^Qhbe5STlTD*NnUb0f)BfCBVx}8aFMK!uBt=MK2*H{ z+`k(ghiRA?i<0yL+?En#L5}rH^ZqPPW-k=bQBN<~kVxbF+j0>lL3D~%^Snj>(wzFo zZo)=ua~maW!XH$)w$3GsX{pIB#?$eXiGdAl)DemiF|1QZ5J)U!rCVybw-fok=Ylsx zxY0qPq&{1b;B$d2jeFi>45T04wBwHB2CdK8-#oa*m`*cfBo7iBQEAJ;*9{2M z1qC*u??h9E8~VMfN1w?hU@)Ge+MS;HXvrHPx^SCvK}RL`;j9=BHM?SF?QJ2|(z(HQ z^9pILHfJC=4Nh&ngWjYH?n5H6_=~EYFU8O74{ad6;5U|$m&~pclMM>KCZu=z8_Ysc z>g+4kg8+OwgnCeFobrF68StOH@XY|z#6i>k>MAs6D-oaNY&yT#0}>=_+Dh-Bp9Hn_ z$GzR_Vf-uuYemQXIr54eojV3ng=>fm&KK(&c3ww9APHFUu#o8hdKzh16C#_dHTJ31-@wsk;K(kB-@6AvR zS;YH)1K^kUad*vot6?39+B|nPp}b)9;{o&U_*;*pc(pRVu6Pc3g5RpqWlBhJ5`X4= z>tWEUy^gDD-p>SglQ|48`O5rp6XcXi>2$aI?%}*TysDW>p1nw;H@vGJiC9{SDdJ~@@$z3Nf<|4&gNc$8VJf01OaUuo6;^QT@aen zC(iTacJcg|rspkldr*fqOB@#s8g}R6yy;rHuZ4CdyLg&=y9bq%KMUu|N?e`|?Q~_t zj!=s@Mcl@x(0bs*>G?&9Fwr=WOPpUobZ%up=f-uuX=TwVOB2ZN&?!53ffxY>Tmn#+ zs05N8AoFmUr6ox}|CbrVWF(d$HwfB$cAdr72+e(R+W^k^Jp(sF?FxGL;|))h_1H7@mW4F$zkXF` z3vUr6{s2sbcG(0+`=^}Rl1jLt3n5s>UT(+AcqL>EX}nX$nE;o-Zw|qQpl`_;I;^W= z#Fa=Kb%tbWjj!Gb{+Ew+2G*0tahOx+6s~0NIRqq*o@D<(j_P}!2uKMk3Dz&9Y~y+z zWRz1La79W`U?5Jr5ok|3G~IF-5vo^74$rk$-LlU^;B=Fn%AoZs9Y^@ttuQpqa(Y^f z(sf@{70scGz-#Kg1=iY%XS_4eu=td>d!b02?=}>&$hqasMxLhxtDPpQgFkt!V(p35L2IvteT31>Y38Q+`bqu!mkB&$qRRk(A%)o^7_PbD;;P>X=D2GId zStV8T$<0_ewxJPb@3dYrIy2_`iWgVOB?dy6FMdy0q}}f3<=k?)iesb|Bq8A(1@QYw zeU>v9sJN02C{rLI_@T#hY^i6%E!y*KU&eHIL=A-W;M@AI_4)3(SSQo?o2HV$CcE(p zNHDLLLg<}9xOZ6OGHbBYvC$<;Ugqk)!3F>2#3Pk?A0@q>;`*k$1&-mZ86H5Br#8kCw5tu_`xqD{_tRX z5nuZ?O?B1{S|feOoz*6vll1$KWoA zzfpns4#5CW_K1jvnOI*=oUN|y`G>c{Fa*$yaLp5Y zk08OC76$Me!__nKW&oJW3K}|&ge5Z`AZyblZlqH{`*Eiha&u)pe@cSTgkMs9wiq{S zx3GgX6kJ!hS87ynhEC8~#+}(_rnCax7%iMWSjSFK>Jpt&gP}`*h=o9p4zEzv34$>)M*(=8;hvG z{#5*QZdP9rKqm%9$*v7IUVYwuK`*ZeCLGt_TH^LhB$DK0$zZ`}5 z88Y(#zK`4Uitboa{aXgIlj_I7lGU&j9@ybz(_nFwYf^zhC2k5P5&-->Cr0n!!~Pi8 z?-Z#=|6{9z428VQZF>8*g!;O4&aWib?&@Xc@0qT|wbhy+=&tnaJaIp1p|AV@KGuW{ z?S_%7iy}0c<*10)xTkI{_=Hp-B7W?h=Tm(G9bPqAF;mh67ok4io*@?Fg7ig=M@9mV z{+xIyFvGMVh^T3WBBM0on#{bkA!rj6SgBfYIa2EN#z(y)3a)n^t)@^ZqRYMd*Zp)g zLv9Q!@QzL4-9pbh8O`eAtJVKu-yiY?FsDiH*8A~AwieOOWtZ6LApaYs6Xp7L9N8}I zK#lmyF>m*2q}+ix&{H1!6}zSFNG_xCTCBQ~#;M1So&)h2TM)r>yY5)ISPqbYMRXj&ph1xG&j*A6Ed0#$=)yE|-UY+t;b-|?Oa-|4r3E3ve@5 z{pV~On~JfoP8pe;nXZ!NKldY4QbdoG`bfL*;k9>0>i^pVD^dfT{qJs#DMoaH@qe4fR$^~kc257^O4Qnax!Pgm zcqind?QN#)6zLd?-0yu2Uy9gh^;&I`f|87blsmc-=!bdJxiiH0^OgKmC(n7OQHn6e z*Vh@}*wNT9J1i~u>Ojd95CCd&CUA|I2*ED}Gd019j6hN!cD1&f@>kG+lnmc5cWQ?f zw%zKKV^cu1$1>k05dr8bvva~YYWjj8`XjfBW`a_< zNb&AE`kp*)ho^0XVf3uEa+0g$uy_?Wxf=2DE$SwLVNKDZv$dB}Qe4_neNvo)ngum% zK=5K_ebqnd*AU`b!F`yRR5tE0{;Bkeb@vU*OzB~|*Im@-S0)w*@XEfg{Nm}(x^HNo z1`vZliM%A?NzNW}x%MrApX|BnqMOWJ_)ZeDhrB&7~d2q zXRJy)lm3bwL^AUbD)QRU@{kZM`Ro+{TVZAd_eMNr{`$lSNc<|M&O6lAAH?f$X+(E+ zOR{`8xErCo5@8mlgcs%qDFFU&^SHUv*4;(vMu&(fXoX%}!G)!j`54eaAsXi^q&h0a z3L^&E`)nA9U1RtytK8WVGGY=B>+;L7rL9acF%IL+;A{Z?jof4ecbQ{znQop}FotRBr6kA0~w=#enT?ybNVv1o)+@7dk~`aWWxl+)-@GqYYljI^CE zEeC~zFSML<)>)KK&0vH>0x+|ODcrS`5IeO)1R|Q`7KZQSS6A~RF;KZq^`s>zxXOJtI8DeQr|Jk5L=hpzw9DJK(JavEiUrnCjyJ~IyraV`0=cuC%#ic!RbFlMZAJTQLbSq&?I`>g z1U><~I`CI0Es&LL1WgtUM(eqw!d^o<{l;qJZZcht5-yyuv7 zi0x)RLr`=C4Zx5R&uVxP-?@eu(s@_$d!a{f@r?P;sjN@fYnFNW6b|Mq2d}p9Wq})| zxW;N$HP*n^I7AU&kbdnNP=OB0r}ee-yO1~WIk`cVxcd!Bt9WBh0AqQPEzC7uU`uAv zihZVeIJ8CPnHc&HZ&Iqp;pcTe&hm~sAYX`5?5jY{;U*!{)L1|qg=DX22nl z=!AbZN0rJq%-AFT8pSnCl>FpR1L)3Uq99S)e*Hovz3=Z)Jj6C+_?jtfy0QTOzps!sMq2T5>kzJsr*zA&oxn*kb!64jZy-&?pu^P^k6H{GP#;=d zEXWfLo6c9Zacx(?3kcHtNLvpNy~C;)!o4`|{^O%Tl%{lwRcSEdqTh;ZOqGt^NRC$>(Q zo_s~nG7VTBJ_M~PZy|Kqwp3`Qr&0;1DsIi)SOr!0w>!>o@q5pz|5@nW5&x44W-&8U zAco+YIra2J{H5PSjf~-nK0smw9GatgZj9Q(hbh1Dh+WB3Ul#x&sH}U z!5n)%TV6*+OSM1V!F~hDcMbX6jM@|7DWNbmdT=k`{)WM|7eZ_zEo0eEI17)+r; z4Zf$ur(x4UbM(I3!1e*6cBe2uTPv-V(I@kX0EmF_Aw8_dDBbv2*%JptpNaG){9}ZB ze|Q^u-gfXrS?)wPWO!inGh4tVG%FDb6q$hwFI?pX71n)wZiihp__C{0qX4SW$OTm!a;$mJm%)o2U<>3$>f0svY(-)BH{c#Vu3;&V51>gNu3DiAC9y4V@ z38w!JH$aEiZ^+#pYdWQhBSXR!58n{{4AuY%{`12GvfABxaBVczSznW-Lsg0&E9SPU z2e?^a9jI33n_}W8x^s=;(PIGL-~k()AB$wXv?GRX65)w@)_cE``9(}$@ggjNQ|klh zged3#Kc|;WPA1Xd^)+8@7m&sqe-1IkMfK5r*O5*wXkz^vx$1YYVUzzkfuqb>dNGw45bNmlN|rGW?e}tfru| zfLyBZ(k3ulrA1v#NaLGk2Op6fc0wyYbnx96yFTV9qgdHh!Uj;qBRfsC%;X0za3D>f zAjbOxJt1;c0OLj-8{D$ /run - #pisitools.dosed("configure.ac", "^(\s+CONSOLE_KIT_PID_FILE=)\$\{localstatedir\}(\/run\/ConsoleKit\/pid)", r"\1\2") - #pisitools.dosed("src/Makefile.am", "\$\(localstatedir\)(\/run\/ConsoleKit)", r"\1") - shelltools.system("sed -i -e '/SystemdService/d' data/org.freedesktop.ConsoleKit.service.in") - - autotools.autoreconf("-fi") - - autotools.configure("\ - --libexecdir=/usr/libexec/ConsoleKit \ - --localstatedir=/var \ - --with-pid-file=/run/ConsoleKit/pid \ - --with-systemdsystemunitdir=no \ - --disable-static \ - --enable-pam-module \ - --enable-udev-acl \ - --enable-pam-module \ - --with-dbus-services=/usr/share/dbus-1/services \ - --with-logrotate-dir=/etc/logrotate.d \ - --with-xinitrc-dir=/etc/X11/xinit/xinitrc \ - --with-pam-module-dir=/lib/security \ - --without-systemdsystemunitdir \ - XMLTO_FLAGS='--skip-validation' \ - ") - -def build(): - autotools.make() - -def install(): - autotools.rawInstall("DESTDIR=%s/" % get.installDIR()) - pisitools.dodir("/run/console") - - pisitools.dodoc("AUTHORS", "README", "COPYING", "HACKING", "NEWS", "TODO") diff --git a/system/base/ConsoleKit/files/ConsoleKit.conf b/system/base/ConsoleKit/files/ConsoleKit.conf deleted file mode 100644 index 0288c791..00000000 --- a/system/base/ConsoleKit/files/ConsoleKit.conf +++ /dev/null @@ -1,2 +0,0 @@ -d /run/ConsoleKit 0755 root root -d /run/console 0755 root root diff --git a/system/base/ConsoleKit/files/pam-foreground-compat.ck b/system/base/ConsoleKit/files/pam-foreground-compat.ck deleted file mode 100644 index 3c1d0744..00000000 --- a/system/base/ConsoleKit/files/pam-foreground-compat.ck +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -TAGDIR=/run/console - -[ -n "$CK_SESSION_USER_UID" ] || exit 1 -[ "$CK_SESSION_IS_LOCAL" = "true" ] || exit 0 - -TAGFILE="$TAGDIR/`getent passwd $CK_SESSION_USER_UID | cut -f 1 -d:`" - -if [ "$1" = "session_added" ]; then - mkdir -p "$TAGDIR" - echo "$CK_SESSION_ID" >> "$TAGFILE" -fi - -if [ "$1" = "session_removed" ] && [ -e "$TAGFILE" ]; then - sed -i "\%^$CK_SESSION_ID\$%d" "$TAGFILE" - [ -s "$TAGFILE" ] || rm -f "$TAGFILE" -fi diff --git a/system/base/ConsoleKit/pspec.xml b/system/base/ConsoleKit/pspec.xml deleted file mode 100644 index 4659fedd..00000000 --- a/system/base/ConsoleKit/pspec.xml +++ /dev/null @@ -1,134 +0,0 @@ - - - - - ConsoleKit2 - http://freedesktop.org/Software/Hal - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - library - A framework for defining and tracking users, login sessions, and seats - ConsoleKit is a system daemon for tracking what users are logged into the system and how they interact with the computer (e.g. which keyboard and mouse they use). - https://github.com/ConsoleKit2/ConsoleKit2/archive/master.zip - - acl-devel - pam-devel - dbus-devel - udev-devel - zlib-devel - glib2-devel - libX11-devel - polkit-devel - dbus-glib-devel - - - - - ConsoleKit - - acl - pam - dbus - zlib - glib2 - libX11 - polkit - libudev - dbus-glib - - - /etc - /usr/lib/tmpfiles.d/ConsoleKit.conf - /usr/bin - /usr/sbin - /usr/libexec - /lib - /usr/lib - /usr/share/dbus-1 - /usr/share/polkit-1/actions - /usr/share/man - /usr/share/doc - /var - /run - - - ConsoleKit.conf - pam-foreground-compat.ck - - - - - ConsoleKit-devel - system.devel - Development files for ConsoleKit - - ConsoleKit - - - /usr/include - /usr/lib/pkgconfig - - - - - - 2015-02-05 - 0.9.2 - Version bump. - Vedat Demir - vedat@pisilinux.org - - - 2014-08-01 - 0.4.6 - Rebuild. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 0.4.6 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-06 - 0.4.6 - Dep Fix - Varol Maksutoğlu - waroi@pisilinux.org - - - 2014-01-09 - 0.4.6 - Add gentoo patches and ConsoleKit.conf - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-08 - 0.4.6 - /var/run => /run - Marcin Bojara - marcin@pisilinux.org - - - 2013-03-04 - 0.4.6 - Version bump - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-08-23 - 0.4.5 - First release - PisiLinux Community - admins@pisilinux.org - - - diff --git a/system/base/ConsoleKit/translations.xml b/system/base/ConsoleKit/translations.xml deleted file mode 100644 index 836acdac..00000000 --- a/system/base/ConsoleKit/translations.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - ConsoleKit - Kullanıcıları, giriş oturumlarını ve koltukları takip etmek ve tanımlamak için bir altyapı - ConsoleKit, sisteme giriş yapmış kullanıcıları ve bu kullanıcıların bilgisayar ile nasıl etkileştiğini izleyen bir sistem hizmetidir. - - - - ConsoleKit-devel - ConsoleKit için geliştirme dosyaları - - diff --git a/system/base/acl/pspec.xml b/system/base/acl/pspec.xml index fa3077e0..b54b2698 100644 --- a/system/base/acl/pspec.xml +++ b/system/base/acl/pspec.xml @@ -16,7 +16,7 @@ acl contains the getfacl and setfacl utilities needed for manipulating access control lists along with the needed libraries. http://download.savannah.gnu.org/releases-noredirect/acl/acl-2.2.52.src.tar.gz - attr + attr-devel @@ -46,6 +46,13 @@ + + 2015-03-15 + 2.2.52 + fix build deps. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-09-30 2.2.52 diff --git a/system/base/alternatives/pspec.xml b/system/base/alternatives/pspec.xml index 4e7629ed..0143f888 100644 --- a/system/base/alternatives/pspec.xml +++ b/system/base/alternatives/pspec.xml @@ -13,6 +13,9 @@ Alternative management system alternatives creates, removes, maintains and displays information about the symbolic links comprising the alternatives system. Alternatives system determines the defaults when several programs fulfilling the same or similar functions to be installed on a single system at the same time. https://git.fedorahosted.org/cgit/chkconfig.git/snapshot/chkconfig-1.3.62.tar.xz + + popt-devel + @@ -29,7 +32,7 @@ - 2014-05-11 + 2015-04-01 1.3.62 Version bump. Serdar Soytetir diff --git a/system/base/attr/pspec.xml b/system/base/attr/pspec.xml index ef079393..da5ff861 100644 --- a/system/base/attr/pspec.xml +++ b/system/base/attr/pspec.xml @@ -45,7 +45,11 @@ emul32 32-bit shared libraries for attr emul32 + + glibc-32bit + + glibc-32bit attr @@ -54,6 +58,13 @@ + + 2015-03-15 + 2.4.47 + fix build emul32. + Serdar Soytetir + kaptan@pisilinux.org + 2014-09-30 2.4.47 diff --git a/system/base/audit/actions.py b/system/base/audit/actions.py deleted file mode 100644 index 8e435035..00000000 --- a/system/base/audit/actions.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Licensed under the GNU General Public License, version 3. -# See the file http://www.gnu.org/licenses/gpl.txt - -from pisi.actionsapi import autotools -from pisi.actionsapi import pisitools -from pisi.actionsapi import get - -def setup(): - autotools.autoreconf("-vif") - autotools.configure("--with-libcap-ng=yes \ - --enable-gssapi-krb5=no \ - --enable-systemd=no \ - --with-python=yes \ - --disable-static") - -def build(): - autotools.make() - -def check(): - autotools.make("-j1 check") - -def install(): - autotools.rawInstall('DESTDIR="%s"' % get.installDIR()) - - # remove RH specific bits - pisitools.removeDir("/etc/sysconfig") - pisitools.removeDir("/etc/rc.d") - - # Create data directories - pisitools.dodir("/var/log/audit") - pisitools.dodir("/var/spool/audit") - - # Disable zos-remote plugin to get rid of deps. like cyrus-sasl - pisitools.remove("/usr/share/man/man8/audispd-zos-remote.8") - pisitools.remove("/usr/share/man/man5/zos-remote.conf.5") - - pisitools.dodoc("AUTHORS", "ChangeLog", "THANKS", "TODO", "README", "COPYING") diff --git a/system/base/audit/comar/package.py b/system/base/audit/comar/package.py deleted file mode 100644 index 9957f0d6..00000000 --- a/system/base/audit/comar/package.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -import os - -def postInstall(fromVersion, fromRelease, toVersion, toRelease): - os.system("ln -s /usr/sbin/audispd /sbin/audispd") - os.system("ln -s /usr/sbin/auditd /sbin/auditd") - os.system("/bin/systemctl enable auditd.service") diff --git a/system/base/audit/comar/service.py b/system/base/audit/comar/service.py deleted file mode 100644 index d4738e8e..00000000 --- a/system/base/audit/comar/service.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -from comar.service import * - -serviceType = "server" -serviceDesc = _({"en": "AUDIT Daemon", - "tr": "AUDIT Servisi"}) -serviceDefault = "on" - -@synchronized -def start(): - reply = startService(command="/usr/sbin/auditd", - pidfile="/run/auditd.pid", - donotify=True) - if reply == 0: - run("/usr/sbin/auditctl -R /etc/audit/rules.d/audit.rules") - -@synchronized -def stop(): - stopService(pidfile="/run/auditd.pid", - donotify=True) - run("/usr/sbin/auditctl -D") - -def status(): - return isServiceRunning("/run/auditd.pid") diff --git a/system/base/audit/files/without_openldap.patch b/system/base/audit/files/without_openldap.patch deleted file mode 100644 index 9f2c8591..00000000 --- a/system/base/audit/files/without_openldap.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff -Nuar audit-2.3.6.orig/audisp/plugins/Makefile.am audit-2.3.6/audisp/plugins/Makefile.am ---- audit-2.3.6.orig/audisp/plugins/Makefile.am 2014-04-11 22:49:23.000000000 +0300 -+++ audit-2.3.6/audisp/plugins/Makefile.am 2014-05-17 01:46:10.260461732 +0300 -@@ -22,7 +22,7 @@ - - CONFIG_CLEAN_FILES = *.loT *.rej *.orig - --SUBDIRS = builtins zos-remote remote -+SUBDIRS = builtins remote - #SUBDIRS = builtins zos-remote - if HAVE_PRELUDE - SUBDIRS += prelude -diff -Nuar audit-2.3.6.orig/configure.ac audit-2.3.6/configure.ac ---- audit-2.3.6.orig/configure.ac 2014-04-11 22:49:33.000000000 +0300 -+++ audit-2.3.6/configure.ac 2014-05-17 01:44:36.753791021 +0300 -@@ -291,7 +291,7 @@ - AC_SUBST(LIBPRELUDE_CFLAGS) - AC_SUBST(LIBPRELUDE_LDFLAGS) - --AC_OUTPUT(Makefile lib/Makefile lib/test/Makefile auparse/Makefile auparse/test/Makefile src/Makefile src/mt/Makefile src/libev/Makefile src/test/Makefile swig/Makefile docs/Makefile init.d/Makefile audisp/Makefile audisp/plugins/Makefile audisp/plugins/builtins/Makefile audisp/plugins/prelude/Makefile audisp/plugins/remote/Makefile audisp/plugins/zos-remote/Makefile bindings/Makefile bindings/python/Makefile tools/Makefile tools/aulast/Makefile tools/aulastlog/Makefile tools/ausyscall/Makefile tools/auvirt/Makefile) -+AC_OUTPUT(Makefile lib/Makefile lib/test/Makefile auparse/Makefile auparse/test/Makefile src/Makefile src/mt/Makefile src/libev/Makefile src/test/Makefile swig/Makefile docs/Makefile init.d/Makefile audisp/Makefile audisp/plugins/Makefile audisp/plugins/builtins/Makefile audisp/plugins/prelude/Makefile audisp/plugins/remote/Makefile bindings/Makefile bindings/python/Makefile tools/Makefile tools/aulast/Makefile tools/aulastlog/Makefile tools/ausyscall/Makefile tools/auvirt/Makefile) - - echo . - echo " - diff --git a/system/base/audit/pspec.xml b/system/base/audit/pspec.xml deleted file mode 100644 index d7de0df8..00000000 --- a/system/base/audit/pspec.xml +++ /dev/null @@ -1,125 +0,0 @@ - - - - - audit - http://people.redhat.com/sgrubb/audit/ - - PisiLinux Community - admins@pisilinux.org - - GPLv2+ - app:console - library - service - User space tools for kernel auditing - audit contains the user space utilities for storing and searching the audit records generated by the audit subsystem in the Linux 2.6 kernel. - http://people.redhat.com/sgrubb/audit/audit-2.3.7.tar.gz - - python-devel - kernel-headers - libcap-ng-devel - tcp-wrappers-devel - - - without_openldap.patch - - - - - audit - - libcap-ng - - - /etc - /usr/share/doc - /usr/lib - /usr/sbin - /usr/bin - /usr/share/man - /var/log/audit - /var/spool/audit - - - System.Service - System.Package - - - - - python-audit - Python bindings for audit - - audit - - - /usr/lib/python* - - - - - audit-devel - system.devel - Development files for audit - - audit - - - /usr/include - /usr/share/man/man3 - - - - - - 2014-09-30 - 2.3.7 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-06-06 - 2.3.6 - Rebuild. - Aydın Demirel - aydin.demirel@pisilinux.org - - - 2014-05-16 - 2.3.6 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2014-05-11 - 2.3.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-22 - 2.3.2 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-02-14 - 2.2.2 - Version bump - Ertan Güven - ertan@pisilinux.org - - - 2011-12-20 - 2.2.1 - First release - Yusuf Aydemir - Yusuf Aydemir - - - diff --git a/system/base/audit/translations.xml b/system/base/audit/translations.xml deleted file mode 100644 index dbefa541..00000000 --- a/system/base/audit/translations.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - audit - Linux çekirdeğinin 2.6 sürümü için inceleme/denetleme araçları - audit Linux çekirdeğinin 2.6 sürümünün inceleme altyapısı tarafından üretilen inceleme kayıtlarını aramak ve saklamak için kullanılan araçları içerir. - - - - python-audit - audit için Python bağlayıcısı - - - - audit-devel - audit için geliştirme dosyaları - - diff --git a/system/base/baselayout/files/pisilinux-release b/system/base/baselayout/files/pisilinux-release index 6c508378..b783eff1 100644 --- a/system/base/baselayout/files/pisilinux-release +++ b/system/base/baselayout/files/pisilinux-release @@ -1 +1 @@ -Pisi_Linux 1.0 +Pisi_Linux 1.2 diff --git a/system/base/baselayout/pspec.xml b/system/base/baselayout/pspec.xml index ed275378..b5bb40e0 100644 --- a/system/base/baselayout/pspec.xml +++ b/system/base/baselayout/pspec.xml @@ -67,6 +67,13 @@ + + 2015-03-04 + 3.10.0 + Release bump + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + 2014-07-16 3.10.0 diff --git a/system/base/bash/files/official/bash43-001.tar.gz b/system/base/bash/files/official/bash43-001.tar.gz deleted file mode 100644 index 2104c27b3b305c07bc700648cdc885f5817d8eec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 829 zcmV-D1H$|tiwFR^xh7Nq1MO99Z__Xk=4B-j7{Rdb57Q56c`{hA*4R4l&|Cp_g$@v!4Nee0O%D6!wZ3Oln_P#9M(Fs#U> z=5u>?5q91kvLkqs%~8_>fzBb#^D`(5T;p&qb3D3YQZS5%j4jcZ z@XW#uBHj=)aZE1CC6X}tEepqLMgrTcDAEf!7dnAYMeVW+(%r%Odc7Vvj%&`gafYtR zb)wEye{AA|HwXh7273-!0c;WwV%fG0YvFVcs25Ti`u=y}y>C&UJn)CRgMdQq0I+JU zVLudy?xY)9_ZtUP@DyT^&8KZAwz1-!$8CV*x|A7gSFp7OBCCWF7&R@>vxDLVV*Hpq z#bI(?d(mOqDS3Pq_8d+pA4U+u>x1#h2sdxG{$hxkT32Mzw*QFiG|TanpHcoB&bO2P zQOAeW-yPCn({WQ(=Kwa#1Xb8B5<={NJ@&wT@G~da08b0a6=(bRRqt`ol07{!p*$NvPVsO$ksE5)|&YBKLoyS~}S6 zla*!>=EAD_&49PhOuoL7%{{Bng6(<{ohphHRQM4wFAk+8-rpSudafDQeRweEn9iG5 z@ObobGzQWr?E%l`A_lhy)9c0Q(bS}xx*AH?GrUVm-mfYB>krxn8*H$_2ET=`DV{)t H01f~ECF+v- diff --git a/system/base/bash/files/official/bash43-002.tar.gz b/system/base/bash/files/official/bash43-002.tar.gz deleted file mode 100644 index db5a69ce4e9b9e1e787ed44493bc10990e76cbc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 776 zcmV+j1NZzNiwFR~xh7Nq1MO8^Z__Xooyo@u&H!tZzWCK z#3GHO*y%KWJ=aOMY26nH214plB&YVZ@44q5H`7q2zGo3aUpyNKAwAy*9Nm7G=#jY1 z?;0NIQ*f#0c0HGLy&e#k_PzcKAkRnX29;D{iBv8tSILt$K%U|1na z#bRrE85kc0gK?EJ2|IJalz#K+n`9pH%#OtT^>W9Il`M}~ecq0Ch4xyx&KExC`$V;i%TIhvgv8O!1=(gl|U#0#ivlPdsD6JlDH z1uNln8^|E&x`FTA3GduSoq0grtpV*qJpq8vCZ9pfW=KDV)`yefWdG#Tcyw~yHaDPw zmUwbiBedN1E5qr)`T04B9E(J$7Cc5p1+LcZ$k>8q&~fzXERXq2XVT=G>^;DD>u0lL zKuhujHg=nKPR66X)3#=Sou0%D?K7!691GpmluMm?1B^dI`(6=!EW`gb5lbeOC|3yG z709P}a{uoL^faYauhvekWwKLkL2BVc2imcIKj`-Fb?oXU^sQ%60u*iT26X$@CjSB7 z(%zOwt^`M9LVS}j6Q#b#s7_qp_vWTGeQec>I4Pq@!UDe*`sPYi;*D+FO`B1L%|_hj zzxMd>%i%G&OXX`B0Ck+)EKZIldaJIhp|tGOGgG2ZQ~K9mt~J(JV~sU_2R{H@G8ugU G4gdgl>U$>u diff --git a/system/base/bash/files/official/bash43-003.tar.gz b/system/base/bash/files/official/bash43-003.tar.gz deleted file mode 100644 index 1fc746040420b4738166267df811f547f090a890..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 844 zcmV-S1GD@eiwFSBxh7Nq1MOAWZreB%?W^?_wf zQwySPM9Qt(e*9cYc7kLu>C8h=6v%-AisaqTk-T6cc5Fha{pj96Dcy4%z||bMRISu( z_YJJQfeEH%o33qA*R_C}*1)kI0lmMHu2BogDlBDPi#oj1j#uK2`?eRjT7MCAIvr3r z8qQDPe0VWBf!X-{Y<8h-Z+^cGO*=x-kQq-o6Wr@Kx~-iv8N}q(vDaB#2@37%2+hi( zl6*-PYp*lRnJiK`FS6omv4R8E?DewUKaVn&qJbUxvEc>vw zvkPlpxG$&f3nH@7yJ0o0hy3XCCu@58H5$n`{KM^xhix>#qB52*1zIUf6xsEiEI{x`3t62?SgfIBLL_;F zF;^^2mgt*H{zVF9c$Flq^FS3Kbgd-?x~weIHGEEF41bo*5h>|!JuI=`?}M%ziZX&M z;tUqXRioPnJ?LQ1HZdu&_Q7;Kci*FXI^6;Ybtu&cA#jJkni+;r{-*0u>mUC8n`mkq zIPUJic?!(|fTrX)oA{%X@#xf_zk2z{a59H(@0s=(FOm?t6{;0z52b7LLDWIOg?J2o zqwxgzwpjuED)leQ7Xj#*;c5|E&p z3pfA@qU1q>?5rC;ldMjeR3ry=C6FgwRd-$fA(ju{zi&DrChY7$H~1pSVVJT=zz&?w z$5Vg)_6V0=+imYgvqc3V%Dt}m|8M-Z9vZcze8p2eRwP;kf7VklspkwlcW{G5cO!z^ zP7U)G1&eyr^sN2=#Jsh)Ytt?7h_om!1%%ifPBBdKCCHe!si4UP-R2SxMGy#B@n*Up zWQDIxPj5$ogMPB)p?bNRPu*nvZae|2<@X8Cmq-H6(!aj+PkiO7`f5ws=;5AAvVUCC W&;H|hzylue%j0h+{7;7f3;+PG`<^TS diff --git a/system/base/bash/files/official/bash43-004.tar.gz b/system/base/bash/files/official/bash43-004.tar.gz deleted file mode 100644 index 71681195041929d9fec663c609a1f47b195dd8a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 759 zcmVz-D~nIzN%8Why>?GN>--P6^&`tS}``YPaz}* ztmd{jVdLNLvs0+rPF-JEHK|8{9e-CJpO|^TSGJ`QV!zoN2q8V&1{@97Az~y({VZX+ zZVwF8G91ewPR|8mn6Bf#0kXfA?ojbED6o}H#jC}Wezf3E*z3K(Zv0Q6C<+Li4!@4! zayb1khRNviVlq{?mcc`)>M4pwo6wjBoO+6_Tk2&{hAZvUnWxNmf37kZ@@O}|vj9!H+76!{qr&0CpHgrJ?nub&+J~2@>#3C+nO~%Nl0_84AWgFpsx-hsD>POV>a&=G>BrB(%nQ4739Uz45FFGVA!5> z?2(>Mwg8RTgs7UP!4vVeM)1g7FdWY$o@L#OcQC$vAF{W8&*}7geUJ-6DQp4FBKB#- zN@T{DJPrm(X+1qU0w2xDV-n;$!3Ou;QL?z!!Oqt)A4BXd2}tT2e;Nb zkdQKAe_5imH^x zjwqE@2`yOY2gOo84fg&#QpW%lT1v~2KYdRVes=oH@COD+P6oiITev(YlOIu9t?z#ea8V@&8|z- zO3Zp+!8J_>Ov^T1+a&wM0b*KR+kFJ&;X>M=6p|Jg%BmFQ;*)x;5T7`&bAg-nJ3*t- z0EI#S;t05Gu_FkvZ;6W!V=F)DrLDvlxzJ_f!a#{$cuNrkR zEX_25^gPG%Ornzy0FAhWG&N0w+xj>aU9gDfc0JSmkAC|$s(0IVuh+31VnZc@4N4p# zpXMxBC#BU%0WUycS#AU!h!;S!RR=^wlLWZ$mxcZlw2d2YMjNJ4j76dXRFy+?ipA>V zmjRcT1ut_rt~v#lWh%?ZYfE(fYA_vNOm}nD>|`}t_ZD_`@O>;vP>^Ct<9VFKay3iX zk|ppQ98+loJee2NXEXc+Nd}J(VRUvnnDmF^*_+F==~(IPE)p6F*n#ues1okom99-H zIkxWb5L$n=T6>sY!{-^MP_kceQ}tt0PuyugVm&{nV}0GC-zCsWmvpZC9}~!|2;p@9 zmq54mZOuAR`i^;*K+Zh`a=WJ4!H2sg&{rYQrk+~@eG>vz_fr+M9w}BJg)GhLRjlYD zk?y&MZX4B9BI+(8re_^|5tXd{j!izIQNsB<0eB6AcS diff --git a/system/base/bash/files/official/bash43-006.tar.gz b/system/base/bash/files/official/bash43-006.tar.gz deleted file mode 100644 index 4af805dcb701b24e054498a32fafb6442ab9c35b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 782 zcmV+p1M&PHiwFSVxh7Nq1MOAqPt!mc_iOuCJcbW$3vI7&8>^@cA!0%zK{R}u*Y4I9 z+g@{b1yTNZpKCW5Q!ttkqv4ljw?41G=jFPX$}I3LLWWNs3+>IhVHlvXJ9&Qq zN0XD+2XMT9^zQh?Txwpd!!&nsX{=*bFe+JO1h#J;QI%xY+r7w$uNMmKniS1yE)<(t z@nvM}&l)Ob9427HuI_wEE5+cD*X%27qq2w_xs#SOFYJVuFBcK!Ot30pZTxKymxp-X zmOH{V^6fVhcSziDXW?v@Y~Aa_@nK|SO4X6$6uDH=POHY|B6X-pvizJmnJNn>Mkh_) z(FrW#Ii*Z-l4IA_>aLhQCKHj@D(6*XniG&2D+*8*BJj=~LZ`teQOQWATH*0BqaQ9kXx)94uMdiP1IBwOj&Z9FZ{c1Dh-X76}P4Ez5#i z=D02%xLewsjDIj6+(w%@@JHb$evP3O0kCQ|#hBA&*L!^welwrq0_St+t#o|a_NZ?d z&HzqNPr`afvv+(1M!6i{Jio(%Pr?~Fa&e9{`k%+jFw{^=Y zxMP;yaMLHtIU)+qKTDW%p%-+XSF?6EyX|XpL9bP!P$r3lb9^!5g~VkScpLh5*9h$J z#*Cpm>t1Vz`yclYA=Dax4V(&gA3Hm}QBDu0+Ev%pQCdv!fhi4tP3dp{Nj%~akN7X~ M9Wa(GRR9bC03*$Npa1{> diff --git a/system/base/bash/files/official/bash43-007.tar.gz b/system/base/bash/files/official/bash43-007.tar.gz deleted file mode 100644 index 00a50290351db87f865201964c4900aa95b3a834..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 806 zcmV+>1KIo^iwFSbxh7Nq1MO7bZ`(Ey?yK}y+|Y;EUPO_SCELn8v`zzLfUyNxvX?Ay zX_=CU$dXD@S&X9p`;L;`tSQj#VZksU9}H8v-}l{#Yp#oN=utX(^=zP&#^W*I$tDrC zCuRM6hhQ9sz=DuPA)|2^17!i)y#o4tB|W0mhAS*(*XlO=rkzmw8~VN%_gj5f=$^eJB=1} z@g|oQC(;N`DpR$js(*YE;QDfzIE67y;`^o4Mw1-vYL)w3rG>l~eqpwyzeXopt8a68 zH1xMR$HC1aV%2@^?}Sd3Y>cd{#C5N=ta8ALo4Tzwz_pfnwH1}okk!h**Qw+NGXPhL z?=+P1PPlHTm=ECQ;dTx;yW9DiD;T9u2X((P#vO_?8k6C+c@CWNnp_)Io}HqEn9sz~Y3>l4wTg0pQUwrLO0B z@WjW`>ai&>me6U!qOW{LU!toanoW;m%Agb2puHdleD+)b=cD}tOB&2UJT$!8tR82v z(ncYFD^u^EV1Sm#K!+#p_tsBlodnk!WxWXCboLQIf(^8F=^$ zX257No+Q!a3o4^M{ZE}b{sRgDO(;u(=|AE>h>t_sv)}b}#I_IMeh05N0^LP_$t=%)J6l3*H2|*#?tBJFK*B z#w^&1u`TbCT&~x5zu8?I3?!7C8ud=)EDgMv!OOt=i$xxXXFOlB{Cw%fbmoPT%@~L4Pz2xsVmJ=tX?2{424rmNW#fo(4#@;W zz<@I$@NqHygktg~HAs{NR#hVp`(B#jYn0MYsai5qQZvxRdc6*o)s%jj7%KFC)Ra1! z(^<%U%deobj!B7WcY(ItR@=4P7AXdpq(w;8G)=f|qeRK1Js>@o9=N2tv9Z27lr=V` z4V$(=ElACJp$+)ktSZuhkJN(NUd>&Zzrgv^(){Peb3pLKJd0r;z5hTzB5h%Cc68o< zV;trpV>a>Tk#M&lf*%XNsOeC&%xyVto38lP-ThXh2>S;jj@0wvqyorJ8 z0E@zn4$maaxByhIUHZHTRb3fW`-9XDm*JCIFT+%3ht@lmKN}haqp);Mg;Ca^P0fmx zFY5a`z?1`Jv<%Y_f#JRv>sLq|mH8Vc#wag7nDpaPznb3L?v3s7a!JCOEs?{i7vB^G z1h{v@Ax?x+-+*fd<0P)>sYF#$P*GHwOm<|f`tl{L0EW@%%d?n$^1*0 zBpJGNmEE-@7RL+ z-cE=w+863m$nWid`pPDSe#t(grVCoxe%VO!IO)?$w_)3za?M?X?_PMV;?0?H7lNpD zG#64f6c}a3Wt_3r#476HSWeYBb9t;pF;To@*~wQtx|JXu^su`ih|DILB>mqm`fpD9 zC&O2Rx5rB7wQMXyvDRARWnlQ)1 zx65k{b%$;`*r}avfo7wB4zK-{7K&24ww!+l+^yW{*$8BNdAN57Z8+p$<%sg_`@q8Y z%~o)mm1t1Ip-#C3-chjzMaj~I1;c;2R#=R3P>M~r)sba$DDEmHZJsF98Jdv}?KB+Q zF5~u)C1H2t)~`?Mx*1`-A}f%0Alt-$b`L0VTOGIEx%KX}zNxr4*+gBOcDzVp5J@S9 zQIcG8bpjNLF1PtH4gpZ_f_?Q+UaWne15%9REjmA!8Wt2K{ITv#`VS(5{;&N3baWxp vRZ{{#Ts|D04vPc1Hfb5Nhcv1Cb(6mLpO=1&ALGaP508HU>Go>W02lxOJPZW( diff --git a/system/base/bash/files/official/bash43-009.tar.gz b/system/base/bash/files/official/bash43-009.tar.gz deleted file mode 100644 index 9c480d71469035a3365b407ff728585a34863137..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 900 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 Os`fV~CwF`R3;+Ok8k^(* diff --git a/system/base/bash/files/official/bash43-012.tar.gz b/system/base/bash/files/official/bash43-012.tar.gz deleted file mode 100644 index edcec478177878e6ccbcc92a3ea1c0029d72e594..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 791 zcmV+y1L*u8iwFP!x+YWr1MO7XPTN2b?Q8rMQ}qEzvAw<#a4+Jjf)uHUUU)QXdlGN! ztS#?4DE+N|LVv8YYeEH;XkSoOiK9r4=e9HFj5p`1iX)c=;j>2rV{9jmfu6x6Vdlw# z;oTxk!UTdaijp7-;v@lTW)dgQfIVJIztAhqJ8EUstA6%i9Cqpf|1b;OKK~PpMk6pd zJos=5=La8;PT}I@{Qbp8XYF}&AC7ZKOXFT(ja*?mioM7==enrev*UD>-!2rz^>Yeq zn@(ft=BspcQue$n8#wUb&=9}iQX@=%d~fmFYx323ulDB)E^4o67H@9~%&Frmg`AU7Ran=M_oCK9!gVETbjWHef>0*cMqXWWp*KJ`VE(|Y>3~z>+D$#zC5>hR z=$y7jjoXf{@NOs9f^uY|AxD!64RK*>Aup<-2 ztu?tV+t{L^$Kx@0o^P0PNpRPCvGl(*x$=t9KwjjAyAZH6iPK=uV`~7>%9!K2F5C%^ z-GDy!-87!0Ecz{cd>6KZDB0WHj&@i8)?_NKO(D>m>zIx0<+YGy)^?4?LT7CwXv;d- zB(Abnv{(y?Tdy7rRei2>#+4FtnJsx|7Kl<_K3H9-%xaz8Xl>81$M|EoM5y=@je5K^ z65x7U6qr;JeMOoToGu#UT@6YOD&D8xxAfPz#M-M2o1sg;aL~!?UX)1bI9x*0lg}qp2!esY7br_HGc0DmyxD1Ha?M~vPq+F%ZcpK#d-~Ux V`V*e;geUw3egZeNIqU!o002-9iHQIJ diff --git a/system/base/bash/files/official/bash43-013.tar.gz b/system/base/bash/files/official/bash43-013.tar.gz deleted file mode 100644 index 22d713b909282fe640a67b01408aa7d4453cd4ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1000 zcmV%s zOO(Y;76p<{mKFK$yOZo@_12`o7Hk82Ff3VjN8UZp@sa15sp80EJbLzI#u%H#G2oR? z$BeFw_rE)fc{~LkM$wo@c*}wDa2ijZ0eiZV?rmjkrm>XUm06V!#tCg6@b|sIr|bX3 z9LE8&kC|hP6stQF!y)#Cdh8Ra5vUO`(Ocs($mUTxNAg32!IV2(-DLlEMSdMpl>W76jSmaUblNnH1Xk<9|MxW)kyp7e~M z1>vR=4OB|Y-&A9>8ZbrGHHAt8qRHm9D4#pif^{8!?yM2;*bMkA;Ri`H@!7@zJ&d`Y=fNZCA*1vtOvd4#(np_LS0SH7 zvwc2^L+BnsZ(Z*#BBe?wr8X7{S+2PyMCYPZ2w9I_K~Z!on`>z#LJfJ9X|umst;QHk zhen9PfK`|dS@AQ9fhc?!1@0aO$r1+nO5+wb?Wj090tPQ$z+S5B^q$(Zr#4-xLZExI z2W)b?BGRq^*gJxCMd^*s+EkUL5q7xF`Pkuk4*>r1{)+$vqen2H75)wke>oSkaI(*5 z5#P*(<4_HF-ffzvtupZP2ry`tmpvFL;i5j3k>c=foh>=DKcXewNqyn1+XXWpTO#4 z_YGg(X&t{0lyta`{vyKUzT3iiOUr^z%W4$i+OJ4@LJvRT0dSVY(_}pTOnSy^<=Rd{ zy^2V$LY6R|gtM>GE95$2f6%I0sb37>VI;mviM$Xgy%2YM!Ju=}dCqeK^xnWX2^gzU z3mi-P$GAwui5C8zxCh+nA diff --git a/system/base/bash/files/official/bash43-014.tar.gz b/system/base/bash/files/official/bash43-014.tar.gz deleted file mode 100644 index cb5a02cf2f44b94c394ca27bc6ee28771f518ab8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1657 zcmV-<28Q_`iwFPNZ90nVkmpV<;rlCz{Xp-jT+WW)_ zBZIHT<}5jBCh32_UCB0(=He%%ndv5B9vu zxC9i+Wm6PeB&p;RbA07h-lu#DpOPfvlPQOnm-_8B=hLR|2hAj%zREWRJms;^mCBcG z)MmMMziqV8cfXxI74(5uX(TzIWk6bdPt(>No+7EAqEc)?pUIgeU19xY5V zxJ4(JmfM<(DW%VC(z#+_+jd2b3_mxDjM+oHG~5A z*9AkV352nqq$&4hbOj`w#FBrN0xoB0X7w^jCmG~ZLqhLl1uYd5V5I%n{D_s zIy^c(9v+;v^;(2tK8vDJu89IX3Nhws%p#~=Ho#K98qVSAD{pAT;}%%@lrVr=WaJ)Q z-x-fy-|aVg{f@ni2Yy*J)hpsr0p=q*CX{-a!12-P!RKbX0diI%NYDZU!Y?ENu5ef+ zA|xQPNU2z`l+8IhNZ5fnllY40ViFGCof4u1m#Cx(^_FswMyn2=KYs>O%i#%=ga8>6 zLRo=P4N@5MPzM%UN?~*{w{^w6n;V!h zv78`}XvYPMGL9~+7T?xAPB=DN?6|8=IDMSzc2=FxwV+ESiLquFk|0$^ML~93A$O!5 zz*5sM4R{968ekh+l^ltAy0@{$cWwdoAfU`EY#_DP*8GB}Sds={osbMewB7|^t^hJg z;!T`lu>!oZSRpj!0s#uOC6gG9RgHvXZC*p^DU4xJ%Gu-!Ax#xX){{1tPO~|WiQtK= zX(|X)j08oT`Ba-pp!7V)N@)Td#Jb#lY@-cQURanDWnTMA8v}vSi*!wDV~Rs^E0UB7 zO@w1?7Aapun2kxfmvVzSkefo+eS#ZPrAA;AjD)IA%?3tO&3^|hG_)jB6jYW6S?m)Z zsi5V269#$sG*K`i&<+-t;n7u(!eyn`mJq;^|e!1z7XG=uxV&XqKy0n;KA}*(Xg}PkyqB;Qcq4U>rAQn zaVhpqzfd@fspY<~peMB=RlnHAM)ZY`#)tsbf}xhn7dpx7LdDZkN9kyga{k?(X+nj| zrEcmf3u@(C$wl|)y9~nP-1K5b%C zQ78zQo-maC)v5$z?%v`x#F_(N@SAGhiM{xkV&{2IT;Pc{AphME^M02BZK Do~S1f diff --git a/system/base/bash/files/official/bash43-015.tar.gz b/system/base/bash/files/official/bash43-015.tar.gz deleted file mode 100644 index 2fd99612dfe5fb8e282b9c595954af93599a2278..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 918 zcmV;H18MvpiwFP@x+YWr1MO99PuoZk?$`KNOjW5(qS#(Lb^y2Bl>#c2xPk&lIh{^9 z#~#P4`X%hH!y)y@-|QMwNL%hI6`f9Egm65&&%8YQ%z7TnJQ&-|3!glgF~%lA0QB@W zLZ+Y0Yu}BH!(alQKOTqP*bBV?nCH{JC%_)Aq|eq!6$>ims*z20?>-drp7pjDxOx6h ztk>&-wl_N`2XMS|x_bcA{o|wQsnxA)ubXAPA<@`VEHIWB^#W&X9mguk?RR@oZ+;^v z+Se>-+p-o4Q+s|D^>&L`e1s2iwSZSC#$r|T^!1{QdEq2=`O`HZLxEL-CfuvtoxRnj zT`&C8qmw$GpX2+p^Ru_{`TMcj|K*_i?d-x6mq&*fmKaZuPu@=X;Z4kvQ<qD+IACS~chDQ{&c4Kot@6mO*0 zx*)eVWlfdn9~4HX&IF<{xcFeC;(+ZqMF?*qNrKZpT$ z2=B7B?OEMaX$yj)2Om2pt;-l>Zq=RXjsR#&%kF9^CExqUk$528I4&tsANT5e{An7I_8Yi z-J})J-Zmx|^vxnUWs*o((RY=|0jUHX^1ukd2=-Zu1jqKPbhv-Ee@M4TOU*N^QX+>0 sJ^Q>mJD6##Zmg~8dUPJTrtqI@`mew8kM?Mf_Gn+)-%85W{QwRC0P6qENdN!< diff --git a/system/base/bash/files/official/bash43-016.tar.gz b/system/base/bash/files/official/bash43-016.tar.gz deleted file mode 100644 index cf8b22446047c9fb680063aa7efce7b2252dd99e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1643 zcmV-x29)_9iwFP~x+YWr1ML@UPuo_sUz1;P+G-^)JANc2n6Z^d2CXuh23q(q$#v|T z*u$|cUk6I7{`Z}8ukAd5u9}9XNnAnfoO|ByOdRfaOhwbTpFP^qG;O=n0etGcu0~Hy zm*2(d>81g?VVYgt)VoFxG~GbFXP`ZvO3Sn0nUkU_w+p_Qeix6W{5$v37AT+plT)cw zfX>1G*$IsH&ks*vJQ%$jpI3{Uz0Fgt9$?ZaV-_-pGpo{3&FaX>Twi%}WK||*LLuH_ zhGm(;O9hqRcGSs>)G51Le-7uzvP5dma@oYg6+?T`=hf< zlb;_RZR=P1$M?gx-BcM~d>Ld-*1L3->F3M&O=K+kgZ=L8?OXO||NU#h@Ikg8#zU*( zXIWyk+hM>nuFj%`8mF_ile&Iz&Dwr858D$YBBR;{X04)i+H*d`1lBZ_uBDMjjJs)& zWI-HR)#`o(>~qEBS-QnIM=D zh8ugVn#C{=cn~3ZlClhf3>=QcUXU_3i_=@+EOAl?U)8FN0@R!&32)&h$b9&e2#}I! zTXn12Xf!}o+hmP`QB%Yv^U(T9o8*cQ)vZWNO~vSgu36oVWtgf~96%pvT2)aLxSy`8 zXa><4NY}qZ*H}M7C*A0@u;xJkh_M9h0KO|#5Z*-h-MGG!+8H!RoQ=wJ*NN;K7i@b} ztChDcSb0U))$6;+quMOk&}Gg8-AFtn0|_rlnt)X81{}uoBnTON5)@$^C#t&z(>Mi; z%PeG=*clT{9T)j?6&h`%eCe@i5HUDB*&kOH5f5e&rURkf?}C26rSIq~F4)l!uwA$S zAYrfvtCmA8Nm>~H7HIX|3TlcO2l155T+6yzO=={pxnaQlcoC8+%)JtJ1ktq<2HqV) z9}9&@n@Ac=Q5-iq4MWTG?n!!9qHmDb6cfs1p#MfM7 z@hXK2Mr5r-RN+vlDKH#;jgjx6c5}Qv;*9=X1li11FHd4kHVYVwkWlS*M zATMkld||uQ=OsZ|W_IMv(b0`5WHc%G%$ zj8jZLC-bHDTi7uv=U!s6$s+ThHn=<=oE{C1?Bn6PgL;{=C8t-f%ARafo)t;_HGiVe zsHm@^D?A|cXmIf1*#4bn<(t#vl3s|5DEAAYB%?A-QuHF;@yx?%*Mb*9MuB6kiL^+I z+E2W`%0>YGh+eel@>lw>;6*K3gkhavg)pHW8W>EMCN2F)5tra^t9Vt|bQD(j>4)L4 zo)_ZR9~c@qq1=BoHP#5l*wA(?vukyGKQuNvW~;NkOf&l0FH)>%zZc`t{&;W-#TjnZ zw;q}XMPFT;1`kYyv21>N(Y|C$DyIN}FV4=#m>@XFsol=SATCj*d)M%b-gtp)7}ml? z;H``mxW>_f>xKGI-I=}Zmf2gGp=Ph&>gd|C=JI}xisbc8nSg(2&Dm9utc)-;mUcmK zutIYxsd(gs5WDUo6&n;Oee`C0HW;D0=YGIth6NnrD5O>$hFF?6K8x0Ck1#mPaCXJz zkibQUlM*r7S{4ev57cI znR8XhlYSrtXb#*2VF+G~4s}yDXXsXEf&r8vs%*&kw&sjRLQ+;@RS`a3ZBk{%dIbGe z-Rwkd(TPHK%|g|uCSoY~hg&0dpH6SHiFEVsvq>admIj7qY5I>YtOnNF%60*`6<%?X z5SYi)Vz9~GTgbu&OP2`buFH#Jrl8^uSQ_$ diff --git a/system/base/bash/files/official/bash43-017.tar.gz b/system/base/bash/files/official/bash43-017.tar.gz deleted file mode 100644 index c369407cf866f63edb4d643f617a70d199563dba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 805 zcmV+=1KRu_iwFQ3x+YWr1MO8^PunmQ-D~nIE zPiJs(G=6smqtlD?(b&BAyk3WC9;0Z;i07P19vQynnHNmODfw^`8PiTs7*{74R*FjT z8JXTi#tAFnMAS*nBpixr!Pu9#$%19M6^q52Rs5V+yokBp?Jx}YozNdxqjWCDqx0eI z`?qo-s$?o|*W)io!^lXLDkIy@GpVGN6t#u1Hml+^TXH*9i`<@KQbW>qQH6vC_ChAu zF?V1!?w0fkmvNPqDicLyn&Xs1EM^>3$`r&EXNpV6Ma*(ovMOWK9M>`xbv}baU;Ls@Wq9A;f<6}<$F*Fy~d9}aix-}bVqrz zvh~a@t@UrK5#Z|b$Qf_V%n4HW3mOh{X9MR8*ezeC1ZkBDYFTmz8oE+eLg!nUS*Sy2kR!^ zBcIcK+RD*^_;&K{E&EI_PJ^@A*(BIY&+s#mk6ze>zf5~FJxZKHsV4FLl1nAMylTB# zZ$Np00dbSbvjJs>^fXP(wM)A5zT=%SC6;LU8Uhygi zsvm@)Ygkdi>AYmnN@G_A16@{Ax7A`3zGRgGxvmub)_3Qv+C+X@u(YItJ%q1Z6_zLp z33c|%9ADa6tKBz#R~D=+VZj$r)e4qWTv*z+8Y*GMCAZg1F#)noQzm8BmgO26CbC*A zbs4TRAkOtqrgkZs=Y?oD-kt4_&Qtn>=gVxap&!DAy!G)UsXwHD)zEH_D=mKXw@V3GvG zztSbx>xZ~g#eVE%U0+DhV+U13#`S8M(RZV@?}8oc)JB=6dVTayQLjEoCG?)`dR^P@ zeR!~7n$Egk%F+0Ad<0}*TmTPPwcr_O-OjJP=ZEKpYZ~in+79M+Ya0H!rhom5zQY~v QaEDvL52o?`egF&r0FeuZMF0Q* diff --git a/system/base/bash/files/official/bash43-019.tar.gz b/system/base/bash/files/official/bash43-019.tar.gz deleted file mode 100644 index e981df3b1c587ba2c9d007db7ab49705871baaf3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1090 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 VcESlKoN&T-@GtoGrIi2<001=V$F=|f diff --git a/system/base/bash/files/official/bash43-022.tar.gz b/system/base/bash/files/official/bash43-022.tar.gz deleted file mode 100644 index a4fa071b7021f5deb022bd4d6e49010dae56d32d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 926 zcmV;P17Z9hiwFQWx+YWr1MOAWZreB%?W^<^x9CG0Ba$dtwi9(hlg22t&ZPKkO6z zCVo3M*6R%h;0O2|4*EKP_`z`KKLhf3kha!HMQem|-^eEWZXB!Scl_;MVDtV%%(5)d zc6R#r1zexryt{zO==y4MW3N50_szD?P&Cej2}UK0tkCV**Hk5Q=kh$VrW-+FTr%PALbQs%43jMc12n5pw>OFZRP^99eUvs>t&MmrA;`qH)W5=FvKt^9A$fDi_`qlQc9hK z-9kNQGO2l`cv(cY{Xz0#1_hG{9x7fj!EpdfuI9V|QI=IZ05xauNl>YD&;gXD07#}F zp#{`THbU8$LUC@EvqDi5kWrj>?Up*|(5e#mZNX2KnQ|&}aEL&<-7dJUr_npewPU<2 z_1GOt8pYxyPu;|7_vJf1AAAz^!>Av)WNqM(J|VW_IPg%`!0}Ij97m)dg(u%+g_za- z)(oB?^vMxELNHUXG9gupJADmH%2k||HFR2H(!-Y+^nz!QvJ81lq4U?(S^Vzm{mtZR zd}u#k70~G7mNKmJxtzxA4l7}gsz$DhRV@CzuE>g%XPfn#BC8quivDscV=V{hV4U7} z5C(lj+&cywIsYGGuM3yiHoIndxj>m{Q6LD&>M~ysaF$L5I|95*R=R*P1HB%Wvj7_* zr$q`>ZuE8_K@$Kg0?>ok6csMO&AO)9rB>REwPkS0uMFjel{6piKmjk3vRJT!qXI$k z96{pd5L(TE;y*_?yb^4ybyKZwib6Mn#=9uFmzPg~xMyd%KGkXG*>6CC9o;W)5RF zcPA9!rzN)6q@HO~!4^!obKPZugTLTJ_hvYZ`ojl%b3X}Nv*!c^0um8F3XXrSH3vsM zveTA$Q+<)3wW&%#C8tJ??GjKoR2$QDi-f@$pz1_C(azKtrx z0ZN3V>JG=hrtFq^6$@;x z{}IXMavl+&p``Q+rr!4ken1NMQ!!IHk_!Ez>_3_o7JTC2}!N+X|2X9w-pi8=h- z_xr>B&!5{?u6f457LA3EO;(qAvm-M6hE(1&NO*Gn%5jk)~4!R_g= z>*N-kCr+gj28=Uf9<7WxomafnUj*m0vf#_GGC?B|O2xuj)k&kWWOK}Gyh++5|i$N zHmY+<>hY>aC-sz>w>E5W*x|$V>O&w{VxS|S%Cia0!01Vy$aAY_p4>o zBGy(B-ofPhy}QmJ2CQi^I7N(N^ac`(__Cv28AQuL%JC+Mru0Hnt7rB~t9gA;nrucT z_sU$1{U*m#%2$}kVz&I0hQTtx&DT{vw-89nEhL3vp)3L_!|2Ry_fJk*y+f7NKkk)T zk&=wky{+1QBudM0F$=vp`(kQ$FUOQe#r7`jARpwRSV#9XWK^!MmWAJ6LNSWnFplQ$ zmx&uk?#$y}=+ZQeQ}|jq==Hn(-nZYK48Q@RDeM`z3)zO;X&lOqvQ3=0?v^&#uJX4A zBhr8GTDb9bv-cWh)7~f9>xPF5^sb<1Zcl?hn?~1uvcUO!gwx5 zIbA03@~&bi`qJ6K3k``8J0%iQcqO?0O1hE@%uuV{L$hl%N+m1P;P9=R-KgbueOyUA>5TEAuZ+2E|^V`fA%3r z@I-=$Co!Hh5GUX%1iFLPu#;`~&y^Q}&HSQ(*C@2+<=!AYvkcr?p}Fa@R=t7YG{{z_ z{&nHVB;F^YYi+Y4+h$15X{ZiimX1GbA57xZY^Q$nq3ya6HqNSOoEE`jn`7R=DigFSMneQ_=$L}by^(&GzW5evul%hFRUm@Mj zyG|D@OH6I=Iqv1Gd*o)FM`60`IuDAedN-!W{;GSDCwY=5xm*4OcEYE902BZK>)4Hg diff --git a/system/base/bash/files/official/bash43-024.tar.gz b/system/base/bash/files/official/bash43-024.tar.gz deleted file mode 100644 index d79cf67814ab397c48ee1cd0758f4653b672ac51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 948 zcmV;l155lLiwFQfx+YWr1MO99Z`(Ey?pNzqT+qR>JxikAtVV5$<;7bJ1dib(8-`)f zD2cX(%A!V6af7z|?K?_w(qvfLFWC!_gJDX%JKl3I50y~4@;#Hd{);CQLdeMX0aqss zh+c`)zBl3pqW~P&3w_^l!q5fcxZ%iq0p#f*-AOGK6$s_Jmi6LMJ0|2K`ZgE1UH>Q2 z>2yHL;lcR{%nmM&PGCNsoy{+dt!DqB7{(zEjX7rpqmo4(-|~zZRq4u{97mnxcA(I% zUZPpWg<_eRTt}TFE?BAZ5@xKv60CqXY1KY`SMjyE=4Gz9$jhab^7Y#r{{=&*lr^Wn z3B056-Z(h6MkF9E@xH?Ea()_hR!UWoZ5O#z(pr|a#l_O5B3q3JgE!K=vG`-}bHzBCv@FARqG zw+GD@fT0HwYuDS*QpLHhd*9e;##3e36WE7}3c6;Bi8v87WpP{2))smt>fl>&hPqdA zE@N4-G^fQ7ey=%B=XQ-VUKD6SRW-!6m5S!2yxZ)*Zji7-vgYB7;j#T$8~yJi&%Tc* zKTI#Dhi8}5+QP8FA_HcW8c0N0uT(}?c`QZE!1^{r(WTm=Z$Yvl(4 z;G6k)tv=kW|9sW9aqR(I)S?8wXo>Jsd@!FM{5+W+gH9U~mQuWFwN5a|C2|Nh$b<#g zvyShJx=c0w@WhVhieO5gr_Vyr>^*GQE_%wks<>pCHc4*iW5K|_1)>Yo7NOg1t6{!v z3a@L``FsPq`|!sd&TTHA{!^3ifVpx+ebIJ#a|mhfxsTqhWAE+lNlb zUC(q0xFjM@aiyv!K7v-Tr(I{tBd3a;1A`%8xNy3oTF-)ZBMSo`Y4T1+?mcxp`kmofd@ WAN^-}mS=euls^Hjn2!7a4gdf3O*r*bX_d$&&MET!?t3n}c5ygzB+arlAfU3EY2`f)h+SWx$)@%!AsfF?Bb zsW89Lb8&j)sBQKr_Y)SUEDEvbBJ9%ye43;l3&CfJpN)}cT*7N0JcMf&1VC@7pQRK8 zx8O&83fChRP>7QVXL1$}Asx{&4X;=dg<~3~Fo+Udrj7)IEcC^W(5C|yGVznw%L)w8 zyf_YSaiequUt-y%$D~q4_tw_dpk7}Wj_8P!fI)6N`|tuIsRLrKOWi-7vwh9MfL5a&5jzzZzDp(FFM_3|pHu+XDQh zmjPbOb5c0#d}<%LC+*X-&T;qXbBWv#lROyj9v>ZdKm7FZ1aRCU<#!9?`xo8az0ST^ z-6EyZ`Wi$b0_FulbiEW>SX+N!KpC=8-|fM^D+^Dm!@iv>BoP|Nc&%>b_V_5ug1-AlHjdpi!cXi5^ojD>6(?Y>U{5Ccfe$rJ`y&vC#CPd|`P=j}XcTwUZ zD)a_lj2fr`iC%d{EE8BDM(ifIMfoHN#mL!4mBHN|1ayd!W_`Ra*nr{9qJ;=;wW?ME z#9o5jD8Z@wXLk1*h}pGC4(%Rx&+m$tgTu3P^kOCV0`piq^qIJqdY*rYQPk%m1QBM| zV*yKV>j1|=AFi-=kr^}^sOzt|!U~@zp~fL#msI+oRkyV&e682(_afCz&Mn4%ok2(k z<9BiRO0^bsxvuA2mB~rHG!V~ZzYWStST#yYgnsn$wH*6 z%8impg|Bhbf?=(FdfNW%e!}W0mv75PFj`8!k7Z1r^>{kTd@WHz7>0v2;gZZJjLy$j zWuWae42M`x%9Jf)wQ4P5n=>2@Bh+d_(<}+emO9#sVh(7)sYG^0359Z9dC3a65}FIf zKwaSaugb3I5tpZ$;rb|lX$YwlM`;-bx?;=~EKhX>$<#1f8E3+gSeX?``bzM|IZg8} zk-Sy(ry4M)KQf`mYAk)Zh}Fu z?04+u(kgRt5$dF&n*>ba5W_KBPtu9GQEQMwBiMo{x>R*F5+u+ONltAAsut7aAa-)! z=f%xbqpwWLeEFaBsPn0F1g51j&ubd?kpqk|cRK1GxH81?V9KXlEYIze{e7SQ Y>;L#K?WMi6m$t0^1u&RAH2@X>065Y&EC2ui diff --git a/system/base/bash/files/official/bash43-026.tar.gz b/system/base/bash/files/official/bash43-026.tar.gz deleted file mode 100644 index 269eca50dd9283fd4e3e7425c89beb96f898afb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 809 zcmV+^1J?W>iwFQpx+YWr1MO8?Z`(E$?yK}GPSJ-Xt|d{F|=nbV-_LxXLAKS(4k5`Id3PiwcIom$~9Lg zR##Gs)LE`$Yr$@E1!wY_mFXIO(q>ux!msN;d3H5gy1csn`A%ykq$s&CHXrR=%xAHc zXHvl8->S5gYDi!~^ABY;6sRi9WUSPDF2l5q?JFfCgO-AL5X zP?adAnxzt-8&PUBR1|#>H==~w30U+M;-`95QqQ0zQfTFb;f|+yfjE5@I`!1KaXrhekk2 zY@V;>d)sK;({U8`aTr3oWlY|0jR9AVZ5rpcl4+76*@>=SZ#1be@idxw_g_2BaI5_(=M zR4}DmU)y3&k+ya>97mf*-d4iG1P&#pFvO4P_Z5Z?`dItBbPOHHq=Ho?L07QK%M^4b zI#{~Xi5{hQihhaGm<;RoXj?cCjF01f~EC^dZ= diff --git a/system/base/bash/files/official/bash43-027.tar.gz b/system/base/bash/files/official/bash43-027.tar.gz deleted file mode 100644 index 4fb6cd509545f91818a15d1d1e708e43a8e2e56f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2221 zcmV;e2vYYSiwFSsCOlLC1MOLRZ`;TbzkjJuF>#PHB~vmUEj~@F)e@idwcTu6VA(CJW7^H8)dACLw(ZU@V16BTR-Z-6-2_>=Orp?# zbRA35N9Lt4kbnLlkEUrr&mRY)V|a5gesv7P!JF5^aYfDSuRoQ_ALumoAq$wBvcA@8 zG%Igh?#=2ahkflLcPL!9xWr{~lyEkwU)=SzqaaFrH-vvMf6fy4%k)Nk`D?-^GnY5K zX#QJ9G-U}3Jw}jgBX5VNeF=TYQZMmi?nfbxjAwodG4TQ3%ndJD3Vg-@X`+cAUIH-& zXvGw!Q3C8%vIWyc=n(?0j=;T+{7JhG+@brqkO=Y1EYMPDF^rMw}nq_LcH3Cg}60lHT1A^La8TIJxk=*6Qi&Au& zCv^J(a7ka4=qL%hMQ;enqZ3qO=309sVwtk-u4&lamQ*(&xXXPHq^tUA9Hq?RY>uAq zCU*{kf#bYEjnABE!k9xI=5VN0t9v5yX_sdT#18`!L^3k}K-3O0Prffe(7jWhO&d^r zL%1a`nILob0}~K#lDK!ceKdE_+nm5hGJ!Wb9-N*!?+%8z`auLDk&!HcBqSNa<%tj`YNca>? zXW&G%xSYWa!%cmxm86v$T0W<8cEK{|m{2j3rA)yr>x(qDCM}Il;0Df;0nmkxs&WNj zkxwvMu@L7*-_)o9qrtm_Q|IjU*~!`Xqk1_$8L1aaw}*qH?Ctg0;MLy_3$`Lg1S&F# z`bP;SPOdY>P$tNIE)l#N4aNuK@o-6OV4>#RQ9<*OUZf4!L?x$YyKOYPZIzsUxM0g^ z=~0olRxp)a)(dSF0XFGjy(CKVRZp*P)YS}3gQw$vM+B4qAI$p#8bfza4$AoEG`Ocx zou07N#}*Zo*;a!mtJQ)u144%>XET$zg!8=|Lu`x)nY`jTuTy@(e5jPLnHB9qfX&%_GZ}K}BN;+jS}Y2d=fn~$+-=E+wY2{_ zOV*E>Bi)NM3NQqnIEgM3caE})oRo*8jxCLU8{9cwlqAgKa^mAh*vzhy^7Hd6|34&H z{sl8^X?xS@V#aN%_D0h_EqB1VSwN%|I!cL0Mf;D>fb(`o7R#%p8WQn)I;gPr-v03|KGEK;iCC6Fa&MJBhmVzK<8NqT3T9%jRiVRJ@z_Y#{ z3$jl#;JY2$X!b0t;8Fjx-SC*1Qdob6{dTe*klI8+vovX;S9;8aL6tk}kUxD>TJIq-24GF2D6FG-|5Bq|NhYm+UHqB*U)Q^*--NOTBBOpIfp1dTUqo zzpM#T=vRmyFJDz3b7idGTb1<9MU`tgn4`yqz%4p&Zp z5}$>bctY7vgmRJ1_)!T_)di>`JL2n=xOe=lu+P;}h;?Jd$kt})U!51?{TY;od}-?L zQR?osJ9)Dr;1($b0y(?qdNcI(yn-|u!o|fxx-dGYf6J?cx1(Ym`W;gDnyI9bOQ~t{ z{=dJTRz$HXDU4Z1w+c=@r)pe!Bt);1w=Un45JsLToLE-o&k$?vl6_ZP!3XS`1&tY9 zm)mvxvwL8f{Z^;n?yOvwx3equb)r_?Y}Rd)?$}MMZ*Shqmv%odjiy<+sSBd$gZ!BT z4;R!}3k}Pk2*h5Xi%A?zJuii8Jit(!m!0x5#iIh%^|kn6=ydRIaEg0L#XP4UKBknP vo#m`^>=3PJg#=H_3yrVJQ|D=(zV#1nKcAn^&*$g!ojv~ro|zJ503rYYqeV<* diff --git a/system/base/bash/files/official/bash43-028.tar.gz b/system/base/bash/files/official/bash43-028.tar.gz deleted file mode 100644 index 5e116d498fe1f1d4a12c77cfb2c003fc95cb1b91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8202 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 diff --git a/system/base/bash/files/official/bash43-029.tar.gz b/system/base/bash/files/official/bash43-029.tar.gz deleted file mode 100644 index 606d16c8b83e1697a4e531c8baa0bef3d36fd1b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 864 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 diff --git a/system/base/bash/files/official/bash43-031.tar.gz b/system/base/bash/files/official/bash43-031.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..33bee99029515aa4641fd3f66ff71806786fbe53 GIT binary patch literal 1452 zcmV;d1ylMTiwFR#1q@XH1MOFBbJ|7_&R6&q>*SdR0Lvi>PVBl<{8H>VZaW?I zkPf7YkceKeNt*xOy*o*O?Zo*|PbM?o5hI=Mc5m<5XIIOZCZ5q&NLzdMXhI0-7zW^7 z>zah$i6+NFx|*qhrW+ldrC0aq^XUc@`+| zKZsN+72vWzI6s23!Nuz%7#*CQjxMUjO#il2tNTbAWyAtT6J}KmwOu`OfTQte}4G=l`!~4vu{U3tKy~U z+-kJ~KS>jH8fIz~Pg^v0Jb%GjUOEd}V^rb?YU#*Wh4fmpWQyc%@2Y%S9`FrIoYV?N3WY-YV8E!QJnk4=-oUt&4NftVM6%G7!34WNyk()Wp#Yft_^slxXFUXJ{<@AA;=ie(1q(L3tVtwM$^@N0@r@(RsB$y z5Pl_URR#=dbUqK3Vg>v&7q65#`MHh2V zrFT_Q2q?rPq^c+iY_8u$70h)@>sV%IW4(dv8=E40FnUca4`Rs8@u3d*q*MWZa@oWW z84S+P?c?8m8J_MBh81#y278rO0}w!m!8C}*G*}NrqjgL7WN>^iIye-n8sVyPwI5C) zjmlV-kfVW}4FiXx)8oQ`e#^ilj%Im~qRG9s0PsSc!+=f`?zISTlEz$}-J~%UyeSEk zs9fty0V)HpIyva3qM1N?mX4s4JD_t^@9M}v8CJV%8OApSN;iqo)J-i97Dz#wgE!#^ zYXTMbJ)HVf-NHG?qcJovTM(T+p>Te5FdW*KgAp_^Q1Nn4Vgn#X(1)6|1>10h14gDt*O>e-VTRgfrrr8K@`2u=1}9nHzDPxtjo1x3>#p_B?-A=PzrRgMQ+p&f5EaABdQh#&9UNvCD0g z7t(1FDBbLI5aeA_q`ECF}`ZlpCHL^9ij+F&#q{J|HT*KrDf#xY&`p=+nOr@JTK z$qg{g=W@)Q!BN0MVUC5aKjC5IbGaKBNb=xb9MBpq!o8Md63qLFz~SW6qS)EOT{|wS zz9d0in&NkgjuPbMtk| zm6=@B2DjujyP0F3U<><2z$L5ikb2CsJl6`C_-xAkn%rVje$a|)v%$`FQr?BBoENgk#EB9GJmlau^1aJzFc`B51e}*E}Wb- zO(0E>=fHz(m3uyD^0q$@+AhxXIe!vqEcnMpE%W~N^tKYVK5a!Opc9K| zmfrie)~D0NQnG4$cuCD0xd@me3 zv*E$z!4TR+_Czwxc(Cl%tbJs2U0LFq8|Cd$ebOHG>3jdteUc}6k|%kR4fziksP}gO G761VEm)0%- literal 0 HcmV?d00001 diff --git a/system/base/bash/files/official/bash43-032.tar.gz b/system/base/bash/files/official/bash43-032.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a8f1d1f8b3193472911f5cd836fd467e8dacdf03 GIT binary patch literal 937 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 W`}e7RYMapp:console

The standard GNU Bourne again shell Bash is the GNU Project's Bourne Again SHell, a complete implementation of the IEEE POSIX and Open Group shell specification with interactive command line editing, csh-like features such as history substitution. - mirrors://gnu/bash/bash-4.3.tar.gz + mirrors://gnu/bash/bash-4.3.30.tar.gz ncurses-devel - official/bash43-001.tar.gz - official/bash43-002.tar.gz - official/bash43-003.tar.gz - official/bash43-004.tar.gz - official/bash43-005.tar.gz - official/bash43-006.tar.gz - official/bash43-007.tar.gz - official/bash43-008.tar.gz - official/bash43-009.tar.gz - official/bash43-010.tar.gz - official/bash43-011.tar.gz - official/bash43-012.tar.gz - official/bash43-013.tar.gz - official/bash43-014.tar.gz - official/bash43-015.tar.gz - official/bash43-016.tar.gz - official/bash43-017.tar.gz - official/bash43-018.tar.gz - official/bash43-019.tar.gz - official/bash43-020.tar.gz - official/bash43-021.tar.gz - official/bash43-022.tar.gz - official/bash43-023.tar.gz - official/bash43-024.tar.gz - official/bash43-025.tar.gz - official/bash43-026.tar.gz - official/bash43-027.tar.gz - official/bash43-028.tar.gz - official/bash43-029.tar.gz - official/bash43-030.tar.gz + official/bash43-031.tar.gz + official/bash43-032.tar.gz + official/bash43-033.tar.gz fedora/bash-2.02-security.patch @@ -99,6 +72,13 @@ + + 2015-08-20 + 4.3_p33 + Update + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + 2014-10-13 4.3_p30 diff --git a/system/base/libXdmcp/actions.py b/system/base/bc/actions.py similarity index 66% rename from system/base/libXdmcp/actions.py rename to system/base/bc/actions.py index 034419ba..09757272 100644 --- a/system/base/libXdmcp/actions.py +++ b/system/base/bc/actions.py @@ -1,3 +1,4 @@ +#!/usr/bin/python # -*- coding: utf-8 -*- # # Licensed under the GNU General Public License, version 3. @@ -8,9 +9,8 @@ from pisi.actionsapi import pisitools from pisi.actionsapi import get def setup(): - autotools.autoreconf("-vif") - autotools.configure("--disable-static \ - --without-xmlto") + autotools.configure("--with-readline \ + --without-libedit") def build(): autotools.make() @@ -18,4 +18,4 @@ def build(): def install(): autotools.rawInstall("DESTDIR=%s" % get.installDIR()) - pisitools.dodoc("AUTHORS", "ChangeLog", "COPYING", "README") + pisitools.dodoc("AUTHORS", "FAQ", "NEWS", "README", "ChangeLog") diff --git a/system/base/bc/files/fedora/bc-1.06-dc_ibase.patch b/system/base/bc/files/fedora/bc-1.06-dc_ibase.patch new file mode 100644 index 00000000..7d5fa20f --- /dev/null +++ b/system/base/bc/files/fedora/bc-1.06-dc_ibase.patch @@ -0,0 +1,58 @@ +--- bc-1.06/dc/numeric.c.dc_ibase 2007-08-22 08:37:57.000000000 +0200 ++++ bc-1.06/dc/numeric.c 2007-08-22 08:37:40.000000000 +0200 +@@ -285,6 +285,8 @@ dc_getnum DC_DECLARG((input, ibase, read + int digit; + int decimal; + int c; ++ int c_buff = 0; ++ int multi = 0; + + bc_init_num(&tmp); + bc_init_num(&build); +@@ -302,6 +304,9 @@ dc_getnum DC_DECLARG((input, ibase, read + } + while (isspace(c)) + c = (*input)(); ++ c_buff = (*input)(); ++ if (isdigit(c_buff) || ('A' <= c_buff && c_buff <= 'F') || c_buff == '.') ++ multi = 1; + for (;;){ + if (isdigit(c)) + digit = c - '0'; +@@ -309,10 +314,15 @@ dc_getnum DC_DECLARG((input, ibase, read + digit = 10 + c - 'A'; + else + break; +- c = (*input)(); ++ digit = multi ? (digit >= ibase ? ibase -1 : digit) : digit; + bc_int2num(&tmp, digit); + bc_multiply(result, base, &result, 0); + bc_add(result, tmp, &result, 0); ++ if (c_buff) { ++ c = c_buff; ++ c_buff = 0; ++ } else ++ c = (*input)(); + } + if (c == '.'){ + bc_free_num(&build); +@@ -321,13 +331,18 @@ dc_getnum DC_DECLARG((input, ibase, read + build = bc_copy_num(_zero_); + decimal = 0; + for (;;){ +- c = (*input)(); ++ if (c_buff) { ++ c = c_buff; ++ c_buff = 0; ++ } else ++ c = (*input)(); + if (isdigit(c)) + digit = c - '0'; + else if ('A' <= c && c <= 'F') + digit = 10 + c - 'A'; + else + break; ++ digit = digit >= ibase ? ibase -1 : digit; + bc_int2num(&tmp, digit); + bc_multiply(build, base, &build, 0); + bc_add(build, tmp, &build, 0); diff --git a/system/base/bc/files/fedora/bc-1.06.95-matlib.patch b/system/base/bc/files/fedora/bc-1.06.95-matlib.patch new file mode 100644 index 00000000..796c5e28 --- /dev/null +++ b/system/base/bc/files/fedora/bc-1.06.95-matlib.patch @@ -0,0 +1,20 @@ +diff -urNp bc-1.06.95-orig/bc/storage.c bc-1.06.95/bc/storage.c +--- bc-1.06.95-orig/bc/storage.c 2006-09-05 04:39:31.000000000 +0200 ++++ bc-1.06.95/bc/storage.c 2010-12-22 10:26:43.805250912 +0100 +@@ -99,6 +99,7 @@ more_functions (VOID) + { + f = &functions[indx]; + f->f_defined = FALSE; ++ f->f_void = FALSE; + f->f_body = (char *) bc_malloc (BC_START_SIZE); + f->f_body_size = BC_START_SIZE; + f->f_code_size = 0; +@@ -179,7 +180,7 @@ more_arrays () + + + /* Initialize the new elements. */ +- for (; indx < v_count; indx++) ++ for (; indx < a_count; indx++) + arrays[indx] = NULL; + + /* Free the old elements. */ diff --git a/system/base/bc/files/fedora/bc-1.06.95-memleak.patch b/system/base/bc/files/fedora/bc-1.06.95-memleak.patch new file mode 100644 index 00000000..0b8fc5be --- /dev/null +++ b/system/base/bc/files/fedora/bc-1.06.95-memleak.patch @@ -0,0 +1,26 @@ +diff --git a/bc/bc.y b/bc/bc.y +index 14dc4be..bd91c38 100644 +--- a/bc/bc.y ++++ b/bc/bc.y +@@ -569,6 +569,7 @@ expression : named_expression ASSIGN_OP + generate (">"); + break; + } ++ free($2); + } + | expression '+' expression + { +diff --git a/bc/util.c b/bc/util.c +index 30beaf9..26e2e85 100644 +--- a/bc/util.c ++++ b/bc/util.c +@@ -602,8 +602,7 @@ lookup (name, namekind) + case FUNCTDEF: + if (id->f_name != 0) + { +- if (namekind != FUNCT) +- free(name); ++ free(name); + /* Check to see if we are redefining a math lib function. */ + if (use_math && namekind == FUNCTDEF && id->f_name <= 6) + id->f_name = next_func++; diff --git a/system/base/bc/pspec.xml b/system/base/bc/pspec.xml new file mode 100644 index 00000000..131c8e31 --- /dev/null +++ b/system/base/bc/pspec.xml @@ -0,0 +1,64 @@ + + + + + bc + http://www.gnu.org/software/bc + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + Console-based calculator utility + bc is an arbitrary precision numeric processing language and can be used as a calculator. Syntax is similar to C, but differs in many substantial areas. For example, it supports interactive execution of statements. + ftp://alpha.gnu.org/gnu/bc/bc-1.06.95.tar.bz2 + + flex + texinfo + readline-devel + + + fedora/bc-1.06.95-memleak.patch + fedora/bc-1.06-dc_ibase.patch + fedora/bc-1.06.95-matlib.patch + + + + + bc + + readline + + + /usr/bin + /usr/share/doc + /usr/share/man + /usr/share/info + + + + + + 2014-05-11 + 1.06.95 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 1.06.95 + rebuild. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2011-01-02 + 1.06.95 + First release + Pisi Linux Admins + admins@pisilinux.org + + + diff --git a/system/base/bc/translations.xml b/system/base/bc/translations.xml new file mode 100644 index 00000000..ea5714d4 --- /dev/null +++ b/system/base/bc/translations.xml @@ -0,0 +1,9 @@ + + + + bc + Konsol temelli hesap makinesi + bc, herhangi bir keskinlikte sayısal işlemler yapmayı sağlayan bir programlama dilidir ve bir hesap makinesi olarak kullanılabilir. Sözdizimi C programlama diline benzer, ancak C'den birçok önemli farkları vardır. Örneğin, ifadelerin etkileşimli bir şekilde çalışmasına olanak tanır. + bc est un langage de calcul numérique à précision arbitraire qui peut être utilisé comme calculatrice. La syntaxe est similaire au C, avec quelques différences notables. Il supporte par exemple l'exécution interactive de commandes. + + diff --git a/system/base/biosdevname/actions.py b/system/base/biosdevname/actions.py index e33ae165..1ade155b 100644 --- a/system/base/biosdevname/actions.py +++ b/system/base/biosdevname/actions.py @@ -15,5 +15,8 @@ def build(): def install(): autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + + #remove after usbmove + pisitools.dosym("/usr/sbin/biosdevname", "/sbin/biosdevname") pisitools.dodoc("AUTHORS", "NEWS", "ChangeLog", "COPYING", "TODO", "README") diff --git a/system/base/biosdevname/pspec.xml b/system/base/biosdevname/pspec.xml index c08d0972..a86fb4ab 100644 --- a/system/base/biosdevname/pspec.xml +++ b/system/base/biosdevname/pspec.xml @@ -13,10 +13,11 @@ app:gui Biosdevname is a udev helper utility developed Biosdevname is a udev helper utility developed by Dell and released under the GNU General Public License (GPL). It provides a consistent naming mechanism for network devices based on their physical location as suggested by the system BIOS. - http://linux.dell.com/biosdevname/biosdevname-0.6.0/biosdevname-0.6.0.tar.gz + http://linux.dell.com/biosdevname/biosdevname-0.6.1/biosdevname-0.6.1.tar.gz pciutils-devel glibc-devel + zlib-devel @@ -24,9 +25,9 @@ biosdevname pciutils - glibc + /sbin /lib/udev/rules.d /usr/sbin /usr/share/doc @@ -35,6 +36,13 @@ + + 2015-03-30 + 0.6.1 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 0.6.0 diff --git a/system/base/comar/pspec.xml b/system/base/comar/pspec.xml index 9a16a09c..f6aaf746 100644 --- a/system/base/comar/pspec.xml +++ b/system/base/comar/pspec.xml @@ -14,8 +14,8 @@ Pisi Linux programs are packaged with small scripts which configures them to entegrate with system and each other. Çomar is the tool which manages and executes these scripts. http://source.pisilinux.org/1.0/comar-3.0.3.tar.bz2 - dbus - python + dbus-devel + python-devel run_dir.patch @@ -47,7 +47,7 @@ - 2014-08-19 + 2015-04-01 3.0.3 Fix run dir path. Marcin Bojara diff --git a/system/base/coreutils/pspec.xml b/system/base/coreutils/pspec.xml index 575405b6..cf6e6ee5 100644 --- a/system/base/coreutils/pspec.xml +++ b/system/base/coreutils/pspec.xml @@ -20,6 +20,7 @@ shadow gettext-devel ncurses-devel + texinfo @@ -53,7 +54,7 @@ - 2014-12-12 + 2015-04-01 8.23 Version bump. Yusuf Aydemir diff --git a/system/base/cryptsetup/pspec.xml b/system/base/cryptsetup/pspec.xml index 1a9d8ecc..6747408b 100644 --- a/system/base/cryptsetup/pspec.xml +++ b/system/base/cryptsetup/pspec.xml @@ -3,7 +3,7 @@ cryptsetup - https://code.google.com/p/cryptsetup/ + https://gitlab.com/cryptsetup/cryptsetup Erdem Artan admins@pisilinux.org @@ -13,11 +13,15 @@ app:cli Userspace setup tool for transparent encryption of block devices using dm-crypt Userspace setup tool for transparent encryption of block devices using dm-crypt - https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.4.tar.xz + https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/cryptsetup-1.6.7.tar.xz - device-mapper-devel + device-mapper-devel libgpg-error-devel libgcrypt-devel + python-devel + libutil-linux-devel + popt-devel + popt @@ -42,7 +46,7 @@ device-mapper libgpg-error libgcrypt - libuuid + libutil-linux /lib/libcryptsetup.so* @@ -75,8 +79,15 @@ + + 2015-04-30 + 1.6.7 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + - 2014-05-11 + 2015-04-01 1.6.4 Release bump. Marcin Bojara diff --git a/system/base/curl/pspec.xml b/system/base/curl/pspec.xml index bf60fad1..a1dae12b 100644 --- a/system/base/curl/pspec.xml +++ b/system/base/curl/pspec.xml @@ -14,8 +14,9 @@ library A utility for getting files from remote servers curl is a command line tool for transferring data with URL syntax, supporting various protocols. - http://curl.haxx.se/download/curl-7.41.0.tar.bz2 + http://curl.haxx.se/download/curl-7.42.1.tar.bz2 + glibc-devel zlib-devel openssl-devel libidn-devel @@ -61,12 +62,19 @@ - - 2015-02-25 - 7.41.0 + + 2015-05-01 + 7.42.1 Version bump. - Dmitry Patsura - talk@dmtry.me + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2015-04-27 + 7.42.0 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org 2015-01-11 diff --git a/system/base/dbus-glib/pspec.xml b/system/base/dbus-glib/pspec.xml index 8f335143..0a76df88 100644 --- a/system/base/dbus-glib/pspec.xml +++ b/system/base/dbus-glib/pspec.xml @@ -13,12 +13,13 @@ library Glib bindings for D-Bus dbus-glib is an add-on library to integrate the standard D-Bus library with the GLib thread abstraction and main loop. - http://dbus.freedesktop.org/releases/dbus-glib/dbus-glib-0.102.tar.gz + http://dbus.freedesktop.org/releases/dbus-glib/dbus-glib-0.104.tar.gz - dbus + dbus-devel - glib2 - expat + glib2-devel + libpcre-devel + expat-devel libxml2 @@ -50,6 +51,8 @@ Development files for dbus-glib dbus-glib + dbus-devel + glib2-devel /usr/include/dbus-1.0 @@ -59,8 +62,15 @@ + + 2015-05-12 + 0.104 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + - 2014-05-11 + 2015-04-01 0.102 Release bump. Marcin Bojara diff --git a/system/base/dbus-python/pspec.xml b/system/base/dbus-python/pspec.xml index de33195a..f6874e3e 100644 --- a/system/base/dbus-python/pspec.xml +++ b/system/base/dbus-python/pspec.xml @@ -15,10 +15,12 @@ dbus-python provides a Python module which wraps the D-Bus programming API. http://dbus.freedesktop.org/releases/dbus-python/dbus-python-1.2.0.tar.gz + python-devel python3 dbus-devel - dbus-glib + dbus-glib-devel glib2-devel + libpcre-devel suppress-warnings.patch @@ -70,7 +72,7 @@ - 2014-05-31 + 2015-04-01 1.2.0 Release bump. Kamil Atlı diff --git a/system/base/dbus/actions.py b/system/base/dbus/actions.py index 32ff4f29..0e995970 100644 --- a/system/base/dbus/actions.py +++ b/system/base/dbus/actions.py @@ -36,8 +36,8 @@ def setup(): if get.buildTYPE() == "emul32": options += "\ - --enable-xml-docs \ - --enable-doxygen-docs" + --disable-xml-docs \ + --disable-doxygen-docs" # Build only libdbus pisitools.dosed("Makefile.am", "(.*SUBDIRS=dbus) .*", "\\1") diff --git a/system/base/dbus/pspec.xml b/system/base/dbus/pspec.xml index 73800639..4e890a14 100644 --- a/system/base/dbus/pspec.xml +++ b/system/base/dbus/pspec.xml @@ -13,13 +13,13 @@ service A message bus system, a simple way for applications to talk to each other D-Bus supplies both a system daemon (for events such as "new hardware device added" or "printer queue changed") and a per-user-login-session daemon (for general IPC needs among user applications). Also, the message bus is built on top of a general one-to-one message passing framework, which can be used by any two apps to communicate directly (without going through the message bus daemon). Currently the communicating applications are on one computer, but TCP/IP option is available and remote support planned. - http://dbus.freedesktop.org/releases/dbus/dbus-1.9.10.tar.gz + http://dbus.freedesktop.org/releases/dbus/dbus-1.9.14.tar.gz expat-devel libX11-devel - doxygen + libcap-ng-devel - xmlto + @@ -27,8 +27,9 @@ dbus expat - libX11 libcap-ng + + libX11 @@ -47,9 +48,21 @@ tmpfiles.conf - + System.Package - + + + + dbus-x11 + x11.util + + libX11 + dbus + + + + /usr/bin/dbus-launch + @@ -75,9 +88,10 @@ emul32 expat-32bit + glibc-32bit - dbus + glibc-32bit /usr/lib32 @@ -85,6 +99,13 @@ + + 2015-05-11 + 1.9.14 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2015-02-15 1.9.10 diff --git a/system/base/dhcpcd/pspec.xml b/system/base/dhcpcd/pspec.xml index b2b2ec4a..d3dcbc14 100644 --- a/system/base/dhcpcd/pspec.xml +++ b/system/base/dhcpcd/pspec.xml @@ -12,14 +12,11 @@ app:console A dhcp client only An RFC2131 and RFC1541 compliant DHCP client daemon. dhcpcd gets an IP address and other information from a corresponding DHCP server, configures the network interface automatically, and tries to renew the lease time according to RFC2131 or RFC1541 depending on the command line option. - http://ftp.osuosl.org/pub/blfs/conglomeration/dhcpcd/dhcpcd-6.7.1.tar.bz2 + http://ftp.osuosl.org/pub/blfs/conglomeration/dhcpcd/dhcpcd-6.8.1.tar.bz2 dhcpcd - - libudev - /etc /lib/dhcpcd @@ -32,6 +29,13 @@ + + 2015-05-03 + 6.8.1 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2015-02-03 6.7.1 diff --git a/system/base/disktype/Makefile içindeki derleyici gcc olarak değiştirildi b/system/base/disktype/Makefile içindeki derleyici gcc olarak değiştirildi deleted file mode 100644 index 8d1c8b69..00000000 --- a/system/base/disktype/Makefile içindeki derleyici gcc olarak değiştirildi +++ /dev/null @@ -1 +0,0 @@ - diff --git a/system/base/disktype/actions.py b/system/base/disktype/actions.py deleted file mode 100644 index 2a353ba2..00000000 --- a/system/base/disktype/actions.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Licensed under the GNU General Public License, version 3. -# See the file http://www.gnu.org/licenses/gpl.txt - -from pisi.actionsapi import autotools -from pisi.actionsapi import pisitools -from pisi.actionsapi import shelltools -from pisi.actionsapi import get - -def build(): - shelltools.export("CCACHE_DIR", "%s" % get.workDIR()) - autotools.make('CFLAGS="%s -fno-stack-protector -fno-strict-aliasing"' % get.CFLAGS()) - -def install(): - pisitools.dobin("disktype") - pisitools.doman("disktype.1") - pisitools.dodoc("README", "HISTORY", "TODO") diff --git a/system/base/disktype/files/disktype.patch b/system/base/disktype/files/disktype.patch deleted file mode 100644 index f130a9d6..00000000 --- a/system/base/disktype/files/disktype.patch +++ /dev/null @@ -1,80 +0,0 @@ -diff -ur disktype-9.orig/linux.c disktype-9/linux.c ---- disktype-9.orig/linux.c 2006-06-04 23:05:06.000000000 +0300 -+++ disktype-9/linux.c 2007-02-14 14:34:36.749572288 +0200 -@@ -43,11 +43,20 @@ - - if (get_le_short(buf + 56) == 0xEF53) { - if (get_le_long(buf + 96) & 0x0008) /* JOURNAL_DEV flag */ -+ { - print_line(level, "Ext3 external journal"); -+ print_line(level, "KERNELMODULE: ext3"); -+ } - else if (get_le_long(buf + 92) & 0x0004) /* HAS_JOURNAL flag */ -+ { - print_line(level, "Ext3 file system"); -+ print_line(level, "KERNELMODULE: ext3"); -+ } - else -+ { - print_line(level, "Ext2 file system"); -+ print_line(level, "KERNELMODULE: ext2"); -+ } - - get_string(buf + 120, 16, s); - if (s[0]) -@@ -93,19 +102,24 @@ - /* check signature */ - if (memcmp(buf + 52, "ReIsErFs", 8) == 0) { - print_line(level, "ReiserFS file system (old 3.5 format, standard journal, starts at %d KiB)", at); -+ print_line(level, "KERNELMODULE: reiserfs"); - newformat = 0; - } else if (memcmp(buf + 52, "ReIsEr2Fs", 9) == 0) { - print_line(level, "ReiserFS file system (new 3.6 format, standard journal, starts at %d KiB)", at); -+ print_line(level, "KERNELMODULE: reiserfs"); - newformat = 1; - } else if (memcmp(buf + 52, "ReIsEr3Fs", 9) == 0) { - newformat = get_le_short(buf + 72); - if (newformat == 0) { - print_line(level, "ReiserFS file system (old 3.5 format, non-standard journal, starts at %d KiB)", at); -+ print_line(level, "KERNELMODULE: reiserfs"); - } else if (newformat == 2) { - print_line(level, "ReiserFS file system (new 3.6 format, non-standard journal, starts at %d KiB)", at); -+ print_line(level, "KERNELMODULE: reiserfs"); - newformat = 1; - } else { - print_line(level, "ReiserFS file system (v3 magic, but unknown version %d, starts at %d KiB)", newformat, at); -+ print_line(level, "KERNELMODULE: reiserfs"); - continue; - } - } else -diff -ur disktype-9.orig/Makefile disktype-9/Makefile ---- disktype-9.orig/Makefile 2006-01-12 19:55:15.000000000 +0200 -+++ disktype-9/Makefile 2007-02-14 14:24:30.917995693 +0200 -@@ -3,7 +3,7 @@ - ### - - RM = rm -f --CC = gcc -+CC = klcc - - OBJS = main.o lib.o \ - buffer.o file.o cdaccess.o cdimage.o vpc.o compressed.o \ -diff -ur disktype-9.orig/unix.c disktype-9/unix.c ---- disktype-9.orig/unix.c 2003-12-30 12:10:41.000000000 +0200 -+++ disktype-9/unix.c 2007-02-14 14:27:48.529848766 +0200 -@@ -49,6 +49,7 @@ - /* tell the user */ - version = get_le_long(buf + 4); - print_line(level, "JFS file system, version %d", version); -+ print_line(level, "KERNELMODULE: jfs"); - - get_string(buf + 101, 11, s); - print_line(level + 1, "Volume name \"%s\"", s); -@@ -82,6 +83,7 @@ - raw_version = get_be_short(buf + 0x64); - version = raw_version & 0x000f; - print_line(level, "XFS file system, version %d", version); -+ print_line(level, "KERNELMODULE: xfs"); - - get_string(buf + 0x6c, 12, s); - print_line(level + 1, "Volume name \"%s\"", s); diff --git a/system/base/disktype/files/ext4.patch b/system/base/disktype/files/ext4.patch deleted file mode 100644 index f67d35fc..00000000 --- a/system/base/disktype/files/ext4.patch +++ /dev/null @@ -1,112 +0,0 @@ - - We first get some sane ext3 poperties and try to match the invert -of these with the filesystems related supoerblock sections. If we find -something not related to ext3 and have journal, we guess the filesystem -is of ext4 type. Then by checking EXT2_FLAGS_TEST_FILESYS in s_flags -section we distinguish ext4 and ext4dev. There may be a better way but -this is the way current e2fsprogs blkid probe does it. Ext4 sections -and flags are taken from the kernel headers of 2.6.25 where ext4 is -still marked as dev. - - Onur Küçük - - -diff -Nur disktype-9-old/detect.c disktype-9/detect.c ---- disktype-9-old/detect.c 2009-03-09 12:38:20.000000000 +0200 -+++ disktype-9/detect.c 2009-03-09 12:38:33.000000000 +0200 -@@ -59,7 +59,7 @@ - void detect_udf(SECTION *section, int level); - - /* in linux.c */ --void detect_ext23(SECTION *section, int level); -+void detect_ext234(SECTION *section, int level); - void detect_reiser(SECTION *section, int level); - void detect_reiser4(SECTION *section, int level); - void detect_linux_raid(SECTION *section, int level); -@@ -136,7 +136,7 @@ - detect_udf, - detect_cdrom_misc, - detect_iso, -- detect_ext23, -+ detect_ext234, - detect_reiser, - detect_reiser4, - detect_linux_raid, -diff -Nur disktype-9-old/linux.c disktype-9/linux.c ---- disktype-9-old/linux.c 2009-03-09 12:38:20.000000000 +0200 -+++ disktype-9/linux.c 2009-03-09 12:38:29.000000000 +0200 -@@ -28,10 +28,43 @@ - #include "global.h" - - /* -- * ext2/ext3 file system -+ * ext2/ext3/ext4 file system - */ - --void detect_ext23(SECTION *section, int level) -+/* for s_flags */ -+#define EXT2_FLAGS_TEST_FILESYS 0x0004 -+ -+/* for s_feature_compat */ -+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 -+ -+/* for s_feature_ro_compat */ -+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 -+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 -+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 -+#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 -+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 -+#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 -+#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 -+ -+/* for s_feature_incompat */ -+#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 -+#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 -+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 -+#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 -+#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 -+#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 -+#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 -+#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 -+ -+#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED ~(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER | \ -+ EXT2_FEATURE_RO_COMPAT_LARGE_FILE | \ -+ EXT2_FEATURE_RO_COMPAT_BTREE_DIR) -+ -+#define EXT3_FEATURE_INCOMPAT_UNSUPPORTED ~(EXT2_FEATURE_INCOMPAT_FILETYPE | \ -+ EXT3_FEATURE_INCOMPAT_RECOVER | \ -+ EXT2_FEATURE_INCOMPAT_META_BG) -+ -+void detect_ext234(SECTION *section, int level) - { - unsigned char *buf; - char s[256]; -@@ -49,8 +82,26 @@ - } - else if (get_le_long(buf + 92) & 0x0004) /* HAS_JOURNAL flag */ - { -- print_line(level, "Ext3 file system"); -- print_line(level, "KERNELMODULE: ext3"); -+ /* Try to find if it is ext4 by checking if there are any unsupported features of ext3 */ -+ if ((get_le_long(buf + 96) & EXT3_FEATURE_INCOMPAT_UNSUPPORTED) && (get_le_long(buf + 100) & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED)) -+ { -+ /* We have ext4 but which version */ -+ if (get_le_long(buf + 352) & EXT2_FLAGS_TEST_FILESYS) -+ { -+ print_line(level, "Ext4dev file system"); -+ print_line(level, "KERNELMODULE: ext4dev"); -+ } -+ else -+ { -+ print_line(level, "Ext4 file system"); -+ print_line(level, "KERNELMODULE: ext4"); -+ } -+ } -+ else -+ { -+ print_line(level, "Ext3 file system"); -+ print_line(level, "KERNELMODULE: ext3"); -+ } - } - else - { diff --git a/system/base/disktype/files/vfat.patch b/system/base/disktype/files/vfat.patch deleted file mode 100644 index 99de689a..00000000 --- a/system/base/disktype/files/vfat.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff -Nur disktype-9-old/dos.c disktype-9/dos.c ---- disktype-9-old/dos.c 2008-07-04 11:06:22.000000000 +0300 -+++ disktype-9/dos.c 2008-07-04 11:22:59.000000000 +0300 -@@ -485,6 +485,7 @@ - strcpy(s, ", ATARI ST bootable"); - print_line(level, "%s file system (hints score %d of %d%s)", - fatnames[fattype], score, 5, s); -+ print_line(level, "KERNELMODULE: vfat"); - - if (sectsize > 512) - print_line(level + 1, "Unusual sector size %lu bytes", sectsize); -@@ -551,6 +552,7 @@ - - /* tell the user */ - print_line(level, "NTFS file system"); -+ print_line(level, "KERNELMODULE: ntfs"); - - format_blocky_size(s, sectcount, sectsize, "sectors", NULL); - print_line(level + 1, "Volume size %s", s); diff --git a/system/base/disktype/pspec.xml b/system/base/disktype/pspec.xml deleted file mode 100644 index 6517b355..00000000 --- a/system/base/disktype/pspec.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - disktype - http://disktype.sourceforge.net/ - - PisiLinux Community - admins@pisilinux.org - - BSD - app:console - Detect the content format of a disk or disk image - The purpose of disktype is to detect the content format of a disk or disk image. It knows about common file systems, partition tables, and boot codes.The program is written in C and is designed to compile on any modern Unix flavour. - mirrors://sourceforge/disktype/disktype-9.tar.gz - - disktype.patch - vfat.patch - ext4.patch - - - - - disktype - - /usr/bin - /usr/share/doc - /usr/share/man - - - - - - 2014-05-11 - 9 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-29 - 9 - Rebuild - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2012-08-23 - 9 - First release - PisiLinux Community - admins@pisilinux.org - - - diff --git a/system/base/disktype/translations.xml b/system/base/disktype/translations.xml deleted file mode 100644 index 2ed94bec..00000000 --- a/system/base/disktype/translations.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - disktype - Disk veya disk görüntüsünün biçimsel içeriğini saptar - Disktype'ın amacı disk veya disk görüntüsünün içerik yapısını denetlemektir. Yaygın dosya sistemlerini, bölümleme tablolarını ve önyükleme kodlarını bilir. C dilinde yazılmış, herhangi bir modern Unix derleme tadında tasarlanmıştır. - - diff --git a/system/base/dnsmasq/actions.py b/system/base/dnsmasq/actions.py deleted file mode 100644 index bc47f1b0..00000000 --- a/system/base/dnsmasq/actions.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Licensed under the GNU General Public License, version 3. -# See the file http://www.gnu.org/licenses/gpl.txt - -from pisi.actionsapi import autotools -from pisi.actionsapi import pisitools -from pisi.actionsapi import get - -def setup(): - pisitools.dosed("src/config.h", "/\* #define HAVE_DBUS \*/", "#define HAVE_DBUS") - - for f in ("dnsmasq.conf.example", "man/dnsmasq.8", "man/es/dnsmasq.8", "src/config.h"): - pisitools.dosed(f, "/var/lib/misc", "/var/lib/dnsmasq") - - - -def build(): - autotools.make() - -def install(): - autotools.rawInstall("PREFIX=%s/usr" % get.installDIR()) - pisitools.insinto("/etc/dbus-1/system.d", "dbus/dnsmasq.conf", "dnsmasq.conf") - - # Install python binding - pisitools.insinto("/usr/lib/%s/site-packages" % get.curPYTHON(), "dnsmasq.py") - - pisitools.dodir("/var/lib/dnsmasq") - - pisitools.dodoc("CHANGELOG", "COPYING", "COPYING-v3", "FAQ") - pisitools.dohtml("doc.html", "setup.html") diff --git a/system/base/dnsmasq/comar/service.py b/system/base/dnsmasq/comar/service.py deleted file mode 100644 index a98719a3..00000000 --- a/system/base/dnsmasq/comar/service.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -from comar.service import * - -serviceType = "local" -serviceDesc = _({"en": "DNS Cache Service", - "tr": "DNS Önbellekleme Servisi"}) - -DNSMASQMESSAGE = "# This line was added by dnsmasq package" -DNSMASQNAMESERVER = "nameserver 127.0.0.1" - -def addLocalNameServerToResolvConf(filename="/etc/resolv.conf"): - dnslist = [] - for line in file(filename): - dnslist.append(line) - line = line.strip() - if line.startswith(DNSMASQNAMESERVER): - return - - dnslist.insert(0, "%s\n" % DNSMASQMESSAGE) - dnslist.insert(1, "%s\n" % DNSMASQNAMESERVER) - - f = file(filename, "w") - try: - for dns in dnslist: - f.write(dns) - finally: - f.close() - -def removeLocalNameServerFromResolvConf(filename="/etc/resolv.conf"): - dnslist = [] - for line in file(filename): - strippedLine = line.strip() - if strippedLine.startswith(DNSMASQMESSAGE): - continue - if strippedLine.startswith(DNSMASQNAMESERVER): - continue - dnslist.append(line) - - f = file(filename, "w") - try: - for dns in dnslist: - f.write(dns) - finally: - f.close() - -@synchronized -def start(): - addLocalNameServerToResolvConf("/etc/resolv.conf") - addLocalNameServerToResolvConf("/etc/resolv.default.conf") - - startService(command="/usr/sbin/dnsmasq", - args="--enable-dbus", - pidfile="/var/run/dnsmasq.pid", - donotify=True) - -@synchronized -def stop(): - removeLocalNameServerFromResolvConf("/etc/resolv.conf") - removeLocalNameServerFromResolvConf("/etc/resolv.default.conf") - - stopService(pidfile="/var/run/dnsmasq.pid", - donotify=True) - -def status(): - return isServiceRunning("/var/run/dnsmasq.pid") diff --git a/system/base/dnsmasq/comar/stack.py b/system/base/dnsmasq/comar/stack.py deleted file mode 100644 index 4f7bcdd3..00000000 --- a/system/base/dnsmasq/comar/stack.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -import os -import string -import subprocess -import dnsmasq - -HEADER_DEFAULT = """# Default DNS settings -# -""" - -HOST_CHARS = string.ascii_letters + string.digits + '.' + '_' + '-' -NAME_PATH = "/etc/env.d/01hostname" -CMD_ENV = "/sbin/update-environment" -HOSTS_PATH = "/etc/hosts" - -RESOLV_USER = "/etc/resolv.default.conf" - -MSG_ERR_INVLCHRSHSNM = {"en": "Invalid character(s) '%s' found in hostname.", - "tr": "Bilgisayar adında geçersiz karakter(ler) ('%s') bulundu.", - } - -# Network.Stack methods - -def getNameServers(): - servers = [] - if not os.access(RESOLV_USER, os.R_OK): - return servers - for line in file(RESOLV_USER): - line = line.strip() - if line.startswith("nameserver"): - ip = line.split()[1] - if ip not in servers: - servers.append(ip) - return servers - -def setNameServers(nameservers, searchdomain): - f = file(RESOLV_USER, "w") - f.write(HEADER_DEFAULT) - - for server in nameservers: - f.write("nameserver %s\n" % server) - - if searchdomain: - f.write("searchdomain %s\n" % searchdomain) - - f.close() - -def registerNameServers(ifname, nameservers, searchdomain): - dnsMasq = dnsmasq.DnsMasq() - for server in nameservers: - dnsMasq.registerNameServer(ifname, server) - dnsMasq.clearCache() - -def unregisterNameServers(ifname, nameservers, searchdomain): - dnsMasq = dnsmasq.DnsMasq() - dnsMasq.unregisterNameServers(ifname) - dnsMasq.clearCache() - -def flushNameCache(): - dnsMasq = dnsmasq.DnsMasq() - dnsMasq.clearCache() - -def getHostName(): - cmd = subprocess.Popen(["/usr/bin/hostname"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - a = cmd.communicate() - if a[1] == "": - return a[0].rstrip("\n") - return "" - -def setHostName(hostname): - if not hostname: - return - invalid = filter(lambda x: not x in HOST_CHARS, hostname) - if len(invalid) > 0: - fail(_(MSG_ERR_INVLCHRSHSNM) % ("".join(invalid))) - - # hostname - if os.path.exists(NAME_PATH): - import re - f = file(NAME_PATH) - data = f.read() - f.close() - data = re.sub('HOSTNAME="(.*)"', 'HOSTNAME="%s"' % hostname, data) - else: - data = 'HOSTNAME="%s"\n' % hostname - f = file(NAME_PATH, "w") - f.write(data) - f.close() - - # hosts - f = file(HOSTS_PATH) - data = f.readlines() - f.close() - f = file(HOSTS_PATH, "w") - flag = 1 - for line in data: - if line.startswith("127.0.0.1"): - line = "127.0.0.1 localhost %s\n" % hostname - flag = 0 - f.write(line) - if flag: - f.write("127.0.0.1 localhost %s\n" % hostname) - f.close() - - # update environment - os.system(CMD_ENV) diff --git a/system/base/dnsmasq/files/dnsmasq.conf b/system/base/dnsmasq/files/dnsmasq.conf deleted file mode 100644 index c13b5557..00000000 --- a/system/base/dnsmasq/files/dnsmasq.conf +++ /dev/null @@ -1,489 +0,0 @@ -# Configuration file for dnsmasq. -# -# Format is one option per line, legal options are the same -# as the long options legal on the command line. See -# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details. - -# The following two options make you a better netizen, since they -# tell dnsmasq to filter out queries which the public DNS cannot -# answer, and which load the servers (especially the root servers) -# uneccessarily. If you have a dial-on-demand link they also stop -# these requests from bringing up the link uneccessarily. - -# Never forward plain names (without a dot or domain part) -domain-needed -# Never forward addresses in the non-routed address spaces. -bogus-priv - - -# Uncomment this to filter useless windows-originated DNS requests -# which can trigger dial-on-demand links needlessly. -# Note that (amongst other things) this blocks all SRV requests, -# so don't use it if you use eg Kerberos, SIP, XMMP or Google-talk. -# This option only affects forwarding, SRV records originating for -# dnsmasq (via srv-host= lines) are not suppressed by it. -#filterwin2k - -# Change this line if you want dns to get its upstream servers from -# somewhere other that /etc/resolv.conf -#resolv-file= - -# By default, dnsmasq will send queries to any of the upstream -# servers it knows about and tries to favour servers to are known -# to be up. Uncommenting this forces dnsmasq to try each query -# with each server strictly in the order they appear in -# /etc/resolv.conf -#strict-order - -# If you don't want dnsmasq to read /etc/resolv.conf or any other -# file, getting its servers from this file instead (see below), then -# uncomment this. -#no-resolv - -# If you don't want dnsmasq to poll /etc/resolv.conf or other resolv -# files for changes and re-read them then uncomment this. -#no-poll - -# Add other name servers here, with domain specs if they are for -# non-public domains. -#server=/localnet/192.168.0.1 - -# Example of routing PTR queries to nameservers: this will send all -# address->name queries for 192.168.3/24 to nameserver 10.1.2.3 -#server=/3.168.192.in-addr.arpa/10.1.2.3 - -# Add local-only domains here, queries in these domains are answered -# from /etc/hosts or DHCP only. -#local=/localnet/ - -# Add domains which you want to force to an IP address here. -# The example below send any host in doubleclick.net to a local -# webserver. -#address=/doubleclick.net/127.0.0.1 - -# --address (and --server) work with IPv6 addresses too. -#address=/www.thekelleys.org.uk/fe80::20d:60ff:fe36:f83 - -# You can control how dnsmasq talks to a server: this forces -# queries to 10.1.2.3 to be routed via eth1 -# --server=10.1.2.3@eth1 - -# and this sets the source (ie local) address used to talk to -# 10.1.2.3 to 192.168.1.1 port 55 (there must be a interface with that -# IP on the machine, obviously). -# --server=10.1.2.3@192.168.1.1#55 - -# If you want dnsmasq to change uid and gid to something other -# than the default, edit the following lines. -#user= -#group= - -# If you want dnsmasq to listen for DHCP and DNS requests only on -# specified interfaces (and the loopback) give the name of the -# interface (eg eth0) here. -# Repeat the line for more than one interface. -#interface= -# Or you can specify which interface _not_ to listen on -#except-interface= -# Or which to listen on by address (remember to include 127.0.0.1 if -# you use this.) -#listen-address= -# If you want dnsmasq to provide only DNS service on an interface, -# configure it as shown above, and then use the following line to -# disable DHCP on it. -#no-dhcp-interface= - -# On systems which support it, dnsmasq binds the wildcard address, -# even when it is listening on only some interfaces. It then discards -# requests that it shouldn't reply to. This has the advantage of -# working even when interfaces come and go and change address. If you -# want dnsmasq to really bind only the interfaces it is listening on, -# uncomment this option. About the only time you may need this is when -# running another nameserver on the same machine. -#bind-interfaces - -# If you don't want dnsmasq to read /etc/hosts, uncomment the -# following line. -#no-hosts -# or if you want it to read another file, as well as /etc/hosts, use -# this. -#addn-hosts=/etc/banner_add_hosts - -# Set this (and domain: see below) if you want to have a domain -# automatically added to simple names in a hosts-file. -#expand-hosts - -# Set the domain for dnsmasq. this is optional, but if it is set, it -# does the following things. -# 1) Allows DHCP hosts to have fully qualified domain names, as long -# as the domain part matches this setting. -# 2) Sets the "domain" DHCP option thereby potentially setting the -# domain of all systems configured by DHCP -# 3) Provides the domain part for "expand-hosts" -#domain=thekelleys.org.uk - -# Set a different domain for a particular subnet -#domain=wireless.thekelleys.org.uk,192.168.2.0/24 - -# Same idea, but range rather then subnet -#domain=reserved.thekelleys.org.uk,192.68.3.100,192.168.3.200 - -# Uncomment this to enable the integrated DHCP server, you need -# to supply the range of addresses available for lease and optionally -# a lease time. If you have more than one network, you will need to -# repeat this for each network on which you want to supply DHCP -# service. -#dhcp-range=192.168.0.50,192.168.0.150,12h - -# This is an example of a DHCP range where the netmask is given. This -# is needed for networks we reach the dnsmasq DHCP server via a relay -# agent. If you don't know what a DHCP relay agent is, you probably -# don't need to worry about this. -#dhcp-range=192.168.0.50,192.168.0.150,255.255.255.0,12h - -# This is an example of a DHCP range with a network-id, so that -# some DHCP options may be set only for this network. -#dhcp-range=red,192.168.0.50,192.168.0.150 - -# Supply parameters for specified hosts using DHCP. There are lots -# of valid alternatives, so we will give examples of each. Note that -# IP addresses DO NOT have to be in the range given above, they just -# need to be on the same network. The order of the parameters in these -# do not matter, it's permissble to give name,adddress and MAC in any order - -# Always allocate the host with ethernet address 11:22:33:44:55:66 -# The IP address 192.168.0.60 -#dhcp-host=11:22:33:44:55:66,192.168.0.60 - -# Always set the name of the host with hardware address -# 11:22:33:44:55:66 to be "fred" -#dhcp-host=11:22:33:44:55:66,fred - -# Always give the host with ethernet address 11:22:33:44:55:66 -# the name fred and IP address 192.168.0.60 and lease time 45 minutes -#dhcp-host=11:22:33:44:55:66,fred,192.168.0.60,45m - -# Give a host with ethernet address 11:22:33:44:55:66 or -# 12:34:56:78:90:12 the IP address 192.168.0.60. Dnsmasq will assume -# that these two ethernet interfaces will never be in use at the same -# time, and give the IP address to the second, even if it is already -# in use by the first. Useful for laptops with wired and wireless -# addresses. -#dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.60 - -# Give the machine which says its name is "bert" IP address -# 192.168.0.70 and an infinite lease -#dhcp-host=bert,192.168.0.70,infinite - -# Always give the host with client identifier 01:02:02:04 -# the IP address 192.168.0.60 -#dhcp-host=id:01:02:02:04,192.168.0.60 - -# Always give the host with client identifier "marjorie" -# the IP address 192.168.0.60 -#dhcp-host=id:marjorie,192.168.0.60 - -# Enable the address given for "judge" in /etc/hosts -# to be given to a machine presenting the name "judge" when -# it asks for a DHCP lease. -#dhcp-host=judge - -# Never offer DHCP service to a machine whose ethernet -# address is 11:22:33:44:55:66 -#dhcp-host=11:22:33:44:55:66,ignore - -# Ignore any client-id presented by the machine with ethernet -# address 11:22:33:44:55:66. This is useful to prevent a machine -# being treated differently when running under different OS's or -# between PXE boot and OS boot. -#dhcp-host=11:22:33:44:55:66,id:* - -# Send extra options which are tagged as "red" to -# the machine with ethernet address 11:22:33:44:55:66 -#dhcp-host=11:22:33:44:55:66,net:red - -# Send extra options which are tagged as "red" to -# any machine with ethernet address starting 11:22:33: -#dhcp-host=11:22:33:*:*:*,net:red - -# Ignore any clients which are specified in dhcp-host lines -# or /etc/ethers. Equivalent to ISC "deny unkown-clients". -# This relies on the special "known" tag which is set when -# a host is matched. -#dhcp-ignore=#known - -# Send extra options which are tagged as "red" to any machine whose -# DHCP vendorclass string includes the substring "Linux" -#dhcp-vendorclass=red,Linux - -# Send extra options which are tagged as "red" to any machine one -# of whose DHCP userclass strings includes the substring "accounts" -#dhcp-userclass=red,accounts - -# Send extra options which are tagged as "red" to any machine whose -# MAC address matches the pattern. -#dhcp-mac=red,00:60:8C:*:*:* - -# If this line is uncommented, dnsmasq will read /etc/ethers and act -# on the ethernet-address/IP pairs found there just as if they had -# been given as --dhcp-host options. Useful if you keep -# MAC-address/host mappings there for other purposes. -#read-ethers - -# Send options to hosts which ask for a DHCP lease. -# See RFC 2132 for details of available options. -# Common options can be given to dnsmasq by name: -# run "dnsmasq --help dhcp" to get a list. -# Note that all the common settings, such as netmask and -# broadcast address, DNS server and default route, are given -# sane defaults by dnsmasq. You very likely will not need -# any dhcp-options. If you use Windows clients and Samba, there -# are some options which are recommended, they are detailed at the -# end of this section. - -# Override the default route supplied by dnsmasq, which assumes the -# router is the same machine as the one running dnsmasq. -#dhcp-option=3,1.2.3.4 - -# Do the same thing, but using the option name -#dhcp-option=option:router,1.2.3.4 - -# Override the default route supplied by dnsmasq and send no default -# route at all. Note that this only works for the options sent by -# default (1, 3, 6, 12, 28) the same line will send a zero-length option -# for all other option numbers. -#dhcp-option=3 - -# Set the NTP time server addresses to 192.168.0.4 and 10.10.0.5 -#dhcp-option=option:ntp-server,192.168.0.4,10.10.0.5 - -# Set the NTP time server address to be the same machine as -# is running dnsmasq -#dhcp-option=42,0.0.0.0 - -# Set the NIS domain name to "welly" -#dhcp-option=40,welly - -# Set the default time-to-live to 50 -#dhcp-option=23,50 - -# Set the "all subnets are local" flag -#dhcp-option=27,1 - -# Send the etherboot magic flag and then etherboot options (a string). -#dhcp-option=128,e4:45:74:68:00:00 -#dhcp-option=129,NIC=eepro100 - -# Specify an option which will only be sent to the "red" network -# (see dhcp-range for the declaration of the "red" network) -# Note that the net: part must precede the option: part. -#dhcp-option = net:red, option:ntp-server, 192.168.1.1 - -# The following DHCP options set up dnsmasq in the same way as is specified -# for the ISC dhcpcd in -# http://www.samba.org/samba/ftp/docs/textdocs/DHCP-Server-Configuration.txt -# adapted for a typical dnsmasq installation where the host running -# dnsmasq is also the host running samba. -# you may want to uncomment some or all of them if you use -# Windows clients and Samba. -#dhcp-option=19,0 # option ip-forwarding off -#dhcp-option=44,0.0.0.0 # set netbios-over-TCP/IP nameserver(s) aka WINS server(s) -#dhcp-option=45,0.0.0.0 # netbios datagram distribution server -#dhcp-option=46,8 # netbios node type - -# Send RFC-3397 DNS domain search DHCP option. WARNING: Your DHCP client -# probably doesn't support this...... -#dhcp-option=option:domain-search,eng.apple.com,marketing.apple.com - -# Send RFC-3442 classless static routes (note the netmask encoding) -#dhcp-option=121,192.168.1.0/24,1.2.3.4,10.0.0.0/8,5.6.7.8 - -# Send vendor-class specific options encapsulated in DHCP option 43. -# The meaning of the options is defined by the vendor-class so -# options are sent only when the client supplied vendor class -# matches the class given here. (A substring match is OK, so "MSFT" -# matches "MSFT" and "MSFT 5.0"). This example sets the -# mtftp address to 0.0.0.0 for PXEClients. -#dhcp-option=vendor:PXEClient,1,0.0.0.0 - -# Send microsoft-specific option to tell windows to release the DHCP lease -# when it shuts down. Note the "i" flag, to tell dnsmasq to send the -# value as a four-byte integer - that's what microsoft wants. See -# http://technet2.microsoft.com/WindowsServer/en/library/a70f1bb7-d2d4-49f0-96d6-4b7414ecfaae1033.mspx?mfr=true -#dhcp-option=vendor:MSFT,2,1i - -# Send the Encapsulated-vendor-class ID needed by some configurations of -# Etherboot to allow is to recognise the DHCP server. -#dhcp-option=vendor:Etherboot,60,"Etherboot" - -# Send options to PXELinux. Note that we need to send the options even -# though they don't appear in the parameter request list, so we need -# to use dhcp-option-force here. -# See http://syslinux.zytor.com/pxe.php#special for details. -# Magic number - needed before anything else is recognised -#dhcp-option-force=208,f1:00:74:7e -# Configuration file name -#dhcp-option-force=209,configs/common -# Path prefix -#dhcp-option-force=210,/tftpboot/pxelinux/files/ -# Reboot time. (Note 'i' to send 32-bit value) -#dhcp-option-force=211,30i - -# Set the boot filename for BOOTP. You will only need -# this is you want to boot machines over the network and you will need -# a TFTP server; either dnsmasq's built in TFTP server or an -# external one. (See below for how to enable the TFTP server.) -#dhcp-boot=pxelinux.0 - -# Boot for Etherboot gPXE. The idea is to send two different -# filenames, the first loads gPXE, and the second tells gPXE what to -# load. The dhcp-match sets the gpxe tag for requests from gPXE. -#dhcp-match=gpxe,175 # gPXE sends a 175 option. -#dhcp-boot=net:#gpxe,undionly.kpxe -#dhcp-boot=mybootimage - -# Enable dnsmasq's built-in TFTP server -#enable-tftp - -# Set the root directory for files availble via FTP. -#tftp-root=/var/ftpd - -# Make the TFTP server more secure: with this set, only files owned by -# the user dnsmasq is running as will be send over the net. -#tftp-secure - -# Set the boot file name only when the "red" tag is set. -#dhcp-boot=net:red,pxelinux.red-net - -# An example of dhcp-boot with an external server: the name and IP -# address of the server are given after the filename. -#dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3 - -# Set the limit on DHCP leases, the default is 150 -#dhcp-lease-max=150 - -# The DHCP server needs somewhere on disk to keep its lease database. -# This defaults to a sane location, but if you want to change it, use -# the line below. -#dhcp-leasefile=/var/lib/misc/dnsmasq.leases - -# Set the DHCP server to authoritative mode. In this mode it will barge in -# and take over the lease for any client which broadcasts on the network, -# whether it has a record of the lease or not. This avoids long timeouts -# when a machine wakes up on a new network. DO NOT enable this if there's -# the slighest chance that you might end up accidentally configuring a DHCP -# server for your campus/company accidentally. The ISC server uses -# the same option, and this URL provides more information: -# http://www.isc.org/index.pl?/sw/dhcp/authoritative.php -#dhcp-authoritative - -# Run an executable when a DHCP lease is created or destroyed. -# The arguments sent to the script are "add" or "del", -# then the MAC address, the IP address and finally the hostname -# if there is one. -#dhcp-script=/bin/echo - -# Set the cachesize here. -cache-size=50 - -# If you want to disable negative caching, uncomment this. -#no-negcache - -# Normally responses which come form /etc/hosts and the DHCP lease -# file have Time-To-Live set as zero, which conventionally means -# do not cache further. If you are happy to trade lower load on the -# server for potentially stale date, you can set a time-to-live (in -# seconds) here. -#local-ttl= - -# If you want dnsmasq to detect attempts by Verisign to send queries -# to unregistered .com and .net hosts to its sitefinder service and -# have dnsmasq instead return the correct NXDOMAIN response, uncomment -# this line. You can add similar lines to do the same for other -# registries which have implemented wildcard A records. -#bogus-nxdomain=64.94.110.11 - -# If you want to fix up DNS results from upstream servers, use the -# alias option. This only works for IPv4. -# This alias makes a result of 1.2.3.4 appear as 5.6.7.8 -#alias=1.2.3.4,5.6.7.8 -# and this maps 1.2.3.x to 5.6.7.x -#alias=1.2.3.0,5.6.7.0,255.255.255.0 - - -# Change these lines if you want dnsmasq to serve MX records. - -# Return an MX record named "maildomain.com" with target -# servermachine.com and preference 50 -#mx-host=maildomain.com,servermachine.com,50 - -# Set the default target for MX records created using the localmx option. -#mx-target=servermachine.com - -# Return an MX record pointing to the mx-target for all local -# machines. -#localmx - -# Return an MX record pointing to itself for all local machines. -#selfmx - -# Change the following lines if you want dnsmasq to serve SRV -# records. These are useful if you want to serve ldap requests for -# Active Directory and other windows-originated DNS requests. -# See RFC 2782. -# You may add multiple srv-host lines. -# The fields are ,,,, -# If the domain part if missing from the name (so that is just has the -# service and protocol sections) then the domain given by the domain= -# config option is used. (Note that expand-hosts does not need to be -# set for this to work.) - -# A SRV record sending LDAP for the example.com domain to -# ldapserver.example.com port 289 -#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389 - -# A SRV record sending LDAP for the example.com domain to -# ldapserver.example.com port 289 (using domain=) -#domain=example.com -#srv-host=_ldap._tcp,ldapserver.example.com,389 - -# Two SRV records for LDAP, each with different priorities -#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1 -#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2 - -# A SRV record indicating that there is no LDAP server for the domain -# example.com -#srv-host=_ldap._tcp.example.com - -# The following line shows how to make dnsmasq serve an arbitrary PTR -# record. This is useful for DNS-SD. (Note that the -# domain-name expansion done for SRV records _does_not -# occur for PTR records.) -#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services" - -# Change the following lines to enable dnsmasq to serve TXT records. -# These are used for things like SPF and zeroconf. (Note that the -# domain-name expansion done for SRV records _does_not -# occur for TXT records.) - -#Example SPF. -#txt-record=example.com,"v=spf1 a -all" - -#Example zeroconf -#txt-record=_http._tcp.example.com,name=value,paper=A4 - -# Provide an alias for a "local" DNS name. Note that this _only_ works -# for targets which are names from DHCP or /etc/hosts. Give host -# "bert" another name, bertrand -#cname=bertand,bert - -# For debugging purposes, log each DNS query as it passes through -# dnsmasq. -#log-queries - -# Log lots of extra information about DHCP transactions. -#log-dhcp - -# Include a another lot of configuration options. -#conf-file=/etc/dnsmasq.more.conf -#conf-dir=/etc/dnsmasq.d diff --git a/system/base/dnsmasq/files/dnsmasq.py b/system/base/dnsmasq/files/dnsmasq.py deleted file mode 100644 index 877ee1e7..00000000 --- a/system/base/dnsmasq/files/dnsmasq.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -import dbus - -class DnsMasq: - bus = None - obj = None - iface = None - - def __init__(self): - self.bus = dbus.SystemBus() - self.obj = self.bus.get_object("uk.org.thekelleys.dnsmasq", "/uk/org/thekelleys/dnsmasq", introspect=False) - self.iface = dbus.Interface(self.obj, "uk.org.thekelleys") - - def __iptodecimal(self, ip): - hexn = ''.join(["%02X" % long(i) for i in ip.split('.')]) - return long(hexn, 16) - - def getVersion(self): - return self.iface.GetVersion(ignore_reply=False) - - def registerNameServer(self, iface, server): - decimalIP = dbus.UInt32(self.__iptodecimal(server)) - self.iface.RegisterServer(iface, decimalIP, ignore_reply=True) - - def unregisterNameServers(self, iface): - self.iface.UnregisterServers(iface, ignore_reply=True) - - def clearCache(self): - self.iface.ClearCache(ignore_reply=True) diff --git a/system/base/dnsmasq/files/uk.org.thekelleys.dnsmasq.service b/system/base/dnsmasq/files/uk.org.thekelleys.dnsmasq.service deleted file mode 100644 index db619364..00000000 --- a/system/base/dnsmasq/files/uk.org.thekelleys.dnsmasq.service +++ /dev/null @@ -1,4 +0,0 @@ -[D-BUS Service] -Name=uk.org.thekelleys.dnsmasq -Exec=/bin/service dnsmasq start -User=root diff --git a/system/base/dnsmasq/pspec.xml b/system/base/dnsmasq/pspec.xml deleted file mode 100644 index cb99d111..00000000 --- a/system/base/dnsmasq/pspec.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - dnsmasq - http://www.thekelleys.org.uk/dnsmasq/doc.html - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - GPLv3 - service - Lightweight, easy to configure DNS forwarder and DHCP server - dnsmasq is a DNS forwarder and DHCP server that can serve the names of local machines which are not in the global DNS. The DHCP server integrates with the DNS server and allows machines with DHCP-allocated addresses to appear in the DNS with names configured in each host. - http://www.thekelleys.org.uk/dnsmasq/dnsmasq-2.70.tar.xz - - dnsmasq.py - - - dbus - - - - - dnsmasq - - dbus - - - /etc - /usr/sbin - /usr/lib - /usr/share - /usr/share/man - /usr/share/doc - /var/lib/dnsmasq - - - dnsmasq.conf - uk.org.thekelleys.dnsmasq.service - - - Network.Stack - System.Service - - - - - - 2014-05-11 - 2.70 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-24 - 2.70 - Version bump. - PisiLinux Community - admins@pisilinux.org - - - 2014-04-03 - 2.68 - Version bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-10-26 - 2.67 - Version bump. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-14 - 2.65 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 2.63 - First release - PisiLinux Community - admins@pisilinux.org - - - diff --git a/system/base/dnsmasq/translations.xml b/system/base/dnsmasq/translations.xml deleted file mode 100644 index 3641cf46..00000000 --- a/system/base/dnsmasq/translations.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - dnsmasq - Hafif, kolay yapılandırılabilir DNS yönlendirici ve DHCP sunucu - dnsmasq, global DNS'te bulunmayan yerel makine isimlerini sunabilen bir DNS yönlendirici ve DHCP sunucudur. - - diff --git a/system/base/e2fsprogs/pspec.xml b/system/base/e2fsprogs/pspec.xml index 557b3231..10c6300b 100644 --- a/system/base/e2fsprogs/pspec.xml +++ b/system/base/e2fsprogs/pspec.xml @@ -12,15 +12,12 @@ app:console Standard ext2/3/4 filesystem utilities e2fsprogs provides the filesystem utilities for use with the ext2 filesystem. It also supports the ext3/4 filesystem with journaling support. - mirrors://sourceforge/e2fsprogs/e2fsprogs-1.42.11.tar.gz + mirrors://sourceforge/e2fsprogs/e2fsprogs-1.42.12.tar.gz - libblkid-devel + libutil-linux-devel - libuuid - + libutil-linux gettext - - util-linux @@ -33,9 +30,9 @@ e2fsprogs - libblkid + libutil-linux - libuuid + /etc @@ -69,6 +66,13 @@ + + 2015-04-30 + 1.42.12 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-07-10 1.42.11 diff --git a/system/base/eudev/actions.py b/system/base/eudev/actions.py new file mode 100644 index 00000000..6aeaeb45 --- /dev/null +++ b/system/base/eudev/actions.py @@ -0,0 +1,73 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Copyright 2015 TUBITAK/UEKAE +# Licensed under the GNU General Public License, version 2. +# See the file http://www.gnu.org/copyleft/gpl.txt. + +from pisi.actionsapi import autotools +from pisi.actionsapi import pisitools +from pisi.actionsapi import shelltools +from pisi.actionsapi import get + +suffix = "32" if get.buildTYPE() == "emul32" else "" + +def setup(): + autotools.autoreconf("-if") + + autotools.configure("--prefix=/usr \ + --bindir=/sbin \ + --sbindir=/sbin \ + --libdir=/usr/lib \ + --sysconfdir=/etc \ + --libexecdir=/lib \ + --with-rootprefix= \ + --with-rootlibdir=/lib \ + --enable-split-usr \ + --disable-introspection \ + --disable-blkid \ + --enable-gudev \ + --enable-static \ + --disable-manpages \ + --disable-gtk-doc \ + --disable-gtk-doc-html") + + pisitools.dosed("libtool", " -shared ", " -Wl,-O1,--as-needed -shared ") + +def build(): + autotools.make() + +def install(): + autotools.rawInstall("-j1 DESTDIR=%s%s" % (get.installDIR(), suffix)) + #autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + + # emul32 stop here + if get.buildTYPE() == "emul32": + shelltools.move("%s%s/lib" % (get.installDIR(), suffix), "%s/lib%s" % (get.installDIR(), suffix)) + shelltools.move("%s%s/usr/lib" % (get.installDIR(), suffix), "%s/usr/lib%s" % (get.installDIR(), suffix)) + #for f in shelltools.ls("%s/usr/lib32/pkgconfig" % get.installDIR()): + # pisitools.dosed("%s/usr/lib32/pkgconfig/%s" % (get.installDIR(), f), "emul32", "usr") + #shelltools.unlinkDir("%s%s" % (get.installDIR(), suffix)) + shelltools.unlink("%s/usr/lib%s/libudev.so" % (get.installDIR(), suffix)) + pisitools.dosym("/lib%s/libudev.so.1.6.0" % suffix, "/usr/lib%s/libudev.so" % suffix) + shelltools.unlinkDir("%s/usr/lib%s/pkgconfig" % (get.installDIR(), suffix)) + shelltools.unlinkDir("%s/lib%s/udev" % (get.installDIR(), suffix)) + return + + #add link + pisitools.dosym("/sbin/udevadm", "/bin/udevadm") + + # Create vol_id and scsi_id symlinks in /sbin probably needed by multipath-tools + pisitools.dosym("/lib/udev/scsi_id", "/sbin/scsi_id") + + # Create /sbin/systemd-udevd -> /sbin/udevd sysmlink, we need it for MUDUR, do not touch this sysmlink. + # pisitools.dosym("/lib/systemd/systemd-udevd", "/sbin/systemd-udevd") + + # Create /etc/udev/rules.d for backward compatibility + pisitools.dodir("/etc/udev/rules.d") + pisitools.dodir("/run/udev") + + # Add man files + pisitools.doman("man/*.5", "man/*.7", "man/*.8") + + pisitools.dodoc("README*", "NOTES") diff --git a/system/base/eudev/comar/package.py b/system/base/eudev/comar/package.py new file mode 100644 index 00000000..19e78ab5 --- /dev/null +++ b/system/base/eudev/comar/package.py @@ -0,0 +1,31 @@ +#!/usr/bin/python + +import os + +def createNode(mode, uid, gid, minor, major, path): + os.system("/bin/mknod --mode=%d %s c %d %d" % (mode, path, minor, major)) + os.system("/bin/chown %s:%s %s" % (uid, gid, path)) + +def postInstall(fromVersion, fromRelease, toVersion, toRelease): + createNode(600, "root", "root", 1, 11, "/lib/udev/devices/kmsg") + createNode(666, "root", "root", 1, 3, "/lib/udev/devices/null") + createNode(666, "root", "root", 1, 5, "/lib/udev/devices/zero") + createNode(600, "root", "root", 10, 130, "/lib/udev/devices/watchdog") + createNode(666, "root", "root", 10, 229, "/lib/udev/devices/fuse") + createNode(600, "root", "tty", 5, 1, "/lib/udev/devices/console") + createNode(666, "root", "tty", 5, 2, "/lib/udev/devices/ptmx") + createNode(666, "root", "tty", 5, 0, "/lib/udev/devices/tty") + createNode(620, "root", "tty", 4, 1, "/lib/udev/devices/tty1") + createNode(600, "root", "root", 10, 200, "/lib/udev/devices/net/tun") + createNode(600, "root", "root", 36, 0, "/lib/udev/devices/route") + createNode(600, "root", "root", 10, 200, "/lib/udev/devices/skip") + createNode(660, "root", "dialout", 108, 0, "/lib/udev/devices/ppp") + + os.system("/sbin/udevadm hwdb --update") + + if os.path.exists("/lib/udev/devices/rtc"): + os.unlink("/lib/udev/devices/rtc") + + # Migrate UDEV database + if fromVersion and int(fromVersion) < 165: + os.system("/sbin/udevadm info --convert-db &> /dev/null") diff --git a/system/base/eudev/files/config.cache b/system/base/eudev/files/config.cache new file mode 100644 index 00000000..7b275d46 --- /dev/null +++ b/system/base/eudev/files/config.cache @@ -0,0 +1,3 @@ +HAVE_BLKID=1 +BLKID_LIBS="-lblkid" +BLKID_CFLAGS="-I/tools/include" diff --git a/system/base/eudev/files/tmpfiles.conf b/system/base/eudev/files/tmpfiles.conf new file mode 100644 index 00000000..9a7ad93d --- /dev/null +++ b/system/base/eudev/files/tmpfiles.conf @@ -0,0 +1 @@ +D /run/udev 0755 root root diff --git a/system/base/eudev/pspec.xml b/system/base/eudev/pspec.xml new file mode 100644 index 00000000..97fd2ea6 --- /dev/null +++ b/system/base/eudev/pspec.xml @@ -0,0 +1,137 @@ + + + + + eudev + https://www.gentoo.org/proj/en/eudev/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + console + eudev is a fork of system-udev + eudev is a fork of system-udev with the goal of obtaining better compatibility with existing software such as OpenRC and Upstart, older kernels, various toolchains and anything else required by users and various distributions. + https://github.com/gentoo/eudev/archive/v3.0.tar.gz + + + config.cache + + + glibc-devel + libkmod-devel + + glib2-devel + libpcre-devel + + gperf + + + + + eudev + + libkmod + + glib2 + + + udev + libudev + libgudev1 + + + udev + libudev + libgudev1 + + + /bin + /sbin + /usr/bin + /usr/sbin + /lib/udev + /lib + /usr/lib + /etc + /usr/lib/tmpfiles.d/udev.conf + /run/udev + /lib/systemd + /etc/udev/rules.d + /lib/udev/rules.d + /usr/share/doc + /usr/share/man + + + tmpfiles.conf + + + System.Package + + + + + eudev-devel + system.devel + Development files for eudev + + eudev + glib2-devel + + + udev-devel + libudev-devel + libgudev1-devel + + + /usr/include/ + /usr/lib/pkgconfig + /usr/share/pkgconfig + + + + + eudev-32bit + + libudev-32bit + libgudev1-32bit + + + libudev-32bit + libgudev1-32bit + + emul32 + 32-bit shared libraries for eudev + emul32 + + glibc-32bit + libkmod-32bit + glib2-32bit + + + glibc-32bit + glib2-32bit + + + /lib32 + /usr/lib32 + + + + + + 2015-05-11 + 3.0 + build emul32 and static too. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-03-29 + 3.0 + First release. + Ertuğrul Erata + ertugrulerata@gmail.com + + + diff --git a/system/base/eudev/translations.xml b/system/base/eudev/translations.xml new file mode 100644 index 00000000..f70f5611 --- /dev/null +++ b/system/base/eudev/translations.xml @@ -0,0 +1,8 @@ + + + + eudev + eudev sistemd-udev uygulamasının çatalı + eudev sistem-udev uygulamasının OpenRC, Upstart gibi başlangıç sistemleri ile uyumu için hazırlanmış çatalı + + diff --git a/system/base/expat/pspec.xml b/system/base/expat/pspec.xml index 19920893..1b39b901 100644 --- a/system/base/expat/pspec.xml +++ b/system/base/expat/pspec.xml @@ -15,6 +15,7 @@ mirrors://sourceforge/expat/expat-2.1.0.tar.gz gnuconfig + glibc-devel @@ -34,6 +35,9 @@ expat-devel system.devel Development files for expat + + glibc-32bit + expat @@ -88,4 +92,4 @@ yusuf.aydemir@pisilinux.org - + \ No newline at end of file diff --git a/system/base/file/pspec.xml b/system/base/file/pspec.xml index ef2f4545..f6f2504d 100644 --- a/system/base/file/pspec.xml +++ b/system/base/file/pspec.xml @@ -12,16 +12,16 @@ app:console Program to identify a file's format by scanning binary data for patterns Program to identify a file's format by scanning binary data for patterns. - ftp://ftp.astron.com/pub/file/file-5.18.tar.gz + ftp://ftp.astron.com/pub/file/file-5.22.tar.gz zlib python-devel - + @@ -41,6 +41,13 @@ + + 2015-04-02 + 5.22 + Release bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 5.18 diff --git a/system/base/freetype/files/fix_segfault_with_harfbuzz.diff b/system/base/freetype/files/fix_segfault_with_harfbuzz.diff deleted file mode 100644 index e256886c..00000000 --- a/system/base/freetype/files/fix_segfault_with_harfbuzz.diff +++ /dev/null @@ -1,27 +0,0 @@ -From 23367ff97f33ef6a2b7e1fced1157c87a46d9596 Mon Sep 17 00:00:00 2001 -From: Werner Lemberg -Date: Mon, 17 Mar 2014 06:33:14 +0000 -Subject: Fix Savannah bug #41869. - -This works around a problem with HarfBuzz (<= 0.9.26), which doesn't -validate glyph indices returned by -`hb_ot_layout_lookup_collect_glyphs'. - -* src/autofit/hbshim.c (af_get_coverage): Guard `idx'. - -* docs/CHANGES: Updated. ---- src/autofit/hbshim.c.orig 2014-03-30 02:39:43.000000000 +0200 -+++ src/autofit/hbshim.c 2014-03-30 02:41:04.818770184 +0200 -@@ -346,6 +346,12 @@ - FT_TRACE4(( " %d", idx )); - count++; - #endif -+ -+ /* HarfBuzz 0.9.26 and older doesn't validate glyph indices */ -+ /* returned by `hb_ot_layout_lookup_collect_glyphs'... */ -+ if ( idx >= (hb_codepoint_t)globals->glyph_count ) -+ continue; -+ - - if ( gstyles[idx] == AF_STYLE_UNASSIGNED ) - gstyles[idx] = (FT_Byte)style_class->style; diff --git a/system/base/freetype/files/freetype-2.2.1-enable-valid.patch b/system/base/freetype/files/freetype-2.2.1-enable-valid.patch deleted file mode 100644 index 0fbd84ac..00000000 --- a/system/base/freetype/files/freetype-2.2.1-enable-valid.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- freetype-2.2.1/modules.cfg.orig 2006-07-07 21:01:09.000000000 -0400 -+++ freetype-2.2.1/modules.cfg 2006-07-07 21:01:54.000000000 -0400 -@@ -110,7 +110,7 @@ - AUX_MODULES += cache - - # TrueType GX/AAT table validation. Needs ftgxval.c below. --# AUX_MODULES += gxvalid -+AUX_MODULES += gxvalid - - # Support for streams compressed with gzip (files with suffix .gz). - # -@@ -124,7 +124,7 @@ - - # OpenType table validation. Needs ftotval.c below. - # --# AUX_MODULES += otvalid -+AUX_MODULES += otvalid - - # Auxiliary PostScript driver component to share common code. - # diff --git a/system/base/freetype/files/freetype-2.5.1-enable-sph.patch b/system/base/freetype/files/freetype-2.5.1-enable-sph.patch deleted file mode 100644 index ca1d5971..00000000 --- a/system/base/freetype/files/freetype-2.5.1-enable-sph.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git i/include/config/ftoption.h w/include/config/ftoption.h -index fe2ba15..1ab4226 100644 ---- i/include/config/ftoption.h -+++ w/include/config/ftoption.h -@@ -591,7 +591,7 @@ FT_BEGIN_HEADER - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ - /* */ --/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ -+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING - - - /************************************************* diff --git a/system/base/freetype/files/freetype-2.5.1-enable-spr.patch b/system/base/freetype/files/freetype-2.5.1-enable-spr.patch deleted file mode 100644 index 7bb1d724..00000000 --- a/system/base/freetype/files/freetype-2.5.1-enable-spr.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git i/include/config/ftoption.h w/include/config/ftoption.h -index fe2ba15..22ce1a3 100644 ---- i/include/config/ftoption.h -+++ w/include/config/ftoption.h -@@ -92,7 +92,7 @@ FT_BEGIN_HEADER - /* This is done to allow FreeType clients to run unmodified, forcing */ - /* them to display normal gray-level anti-aliased glyphs. */ - /* */ --/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ -+#define FT_CONFIG_OPTION_SUBPIXEL_RENDERING - - - /***************************** diff --git a/system/base/fuse/pspec.xml b/system/base/fuse/pspec.xml index 497dfc38..30bf14d7 100644 --- a/system/base/fuse/pspec.xml +++ b/system/base/fuse/pspec.xml @@ -13,6 +13,9 @@ An interface for filesystems implemented in userspace fuse is a backend allowing regular users to (un)mount filesystems for their own use. mirrors://sourceforge/project/fuse/fuse-2.X/2.9.3/fuse-2.9.3.tar.gz + + gettext-devel + skip_umount_test.patch @@ -21,7 +24,7 @@ fuse - glibc + glibc /bin diff --git a/system/base/gettext/pspec.xml b/system/base/gettext/pspec.xml index 11db3ebf..c6ba7901 100644 --- a/system/base/gettext/pspec.xml +++ b/system/base/gettext/pspec.xml @@ -13,7 +13,7 @@ library GNU libraries and utilities for producing multi-lingual messages The GNU gettext package provides a set of tools and documentation for producing multi-lingual messages in programs. Tools include a set of conventions about how programs should be written to support message catalogs, a directory and file naming organization for the message catalogs, a runtime library which supports the retrieval of translated messages, and stand-alone programs for handling the translatable and the already translated strings. Gettext provides an easy to use library and tools for creating, using, and modifying natural language catalogs and is a powerful and simple method for internationalizing programs. - http://ftp.gnu.org/pub/gnu/gettext/gettext-0.18.3.2.tar.gz + http://ftp.gnu.org/pub/gnu/gettext/gettext-0.19.4.tar.gz acl-devel glib2-devel @@ -70,6 +70,13 @@ + + 2015-04-03 + 0.19.4 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + 2014-05-11 0.18.3.2 diff --git a/system/base/glib2/actions.py b/system/base/glib2/actions.py index e77660da..b5271e16 100644 --- a/system/base/glib2/actions.py +++ b/system/base/glib2/actions.py @@ -13,9 +13,11 @@ from pisi.actionsapi import shelltools def setup(): options = "--with-pcre=system \ --disable-fam \ + --disable-libelf \ + --enable-gtk-doc=no \ --disable-static \ --enable-shared \ - --enable-man \ + --disable-man \ --enable-systemtap" @@ -28,7 +30,7 @@ def setup(): shelltools.export("CXX", "%s -m32" % get.CXX()) shelltools.export("PKG_CONFIG_PATH", "/usr/lib32/pkgconfig") - autotools.autoreconf("-vif") + #autotools.autoreconf("-vif") autotools.configure(options) pisitools.dosed("libtool", " -shared ", " -Wl,--as-needed -shared ") @@ -45,4 +47,4 @@ def install(): pisitools.removeDir("/usr/share/gdb") - pisitools.dodoc("AUTHORS", "ChangeLog", "README", "NEWS") \ No newline at end of file + pisitools.dodoc("AUTHORS", "ChangeLog", "README", "NEWS") diff --git a/system/base/glib2/pspec.xml b/system/base/glib2/pspec.xml index 2c47a5dd..a4442408 100644 --- a/system/base/glib2/pspec.xml +++ b/system/base/glib2/pspec.xml @@ -12,13 +12,14 @@ library A library of handy utility functions glib2 is the low-level core library that forms the basis for projects such as GTK+ and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system. - mirrors://gnome/glib/2.42/glib-2.42.0.tar.xz + mirrors://gnome/glib/2.44/glib-2.44.0.tar.xz - libpcre-devel + libpcre-devel zlib-devel - libxslt - elfutils - docbook-xml + libffi-devel + + + revert-warn-glib-compile-schemas.patch @@ -30,7 +31,7 @@ libpcre zlib - elfutils + libffi @@ -60,6 +61,7 @@ Development files for glib2 glib2 + libpcre-devel /usr/bin/gtester @@ -98,6 +100,7 @@ zlib-32bit libffi-32bit dbus-32bit + glibc-32bit glib2 @@ -105,6 +108,7 @@ zlib-32bit libffi-32bit dbus-32bit + glibc-32bit /usr/bin/32 @@ -125,6 +129,13 @@ + + 2015-04-08 + 2.44.0 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + 2014-10-01 2.42.0 diff --git a/system/base/glibc/actions.py b/system/base/glibc/actions.py index e048d316..df32e9cf 100644 --- a/system/base/glibc/actions.py +++ b/system/base/glibc/actions.py @@ -11,7 +11,7 @@ from pisi.actionsapi import get import os -WorkDir = "glibc-2.20" +WorkDir = "glibc-2.21" arch = "x86-64" if get.ARCH() == "x86_64" and not get.buildTYPE() == "emul32" else "i686" defaultflags = "-O3 -g -fasynchronous-unwind-tables -mtune=generic -march=%s" % arch @@ -53,16 +53,13 @@ def setup(): --libexecdir=/usr/lib/misc \ --with-bugurl=https://bugs.pisilinux.org \ --enable-add-ons \ - --enable-bind-now \ - --enable-kernel=2.6.32 \ - --enable-stackguard-randomization \ - --without-selinux \ - --without-gd \ - --disable-profile \ --enable-obsolete-rpc \ + --enable-kernel=2.6.32 \ + --enable-bind-now --disable-profile \ + --enable-stackguard-randomization \ --enable-lock-elision \ --enable-multi-arch \ - --with-tls" + --disable-werror" if get.buildTYPE() == "emul32": options += "\ --libdir=/usr/lib32 \ diff --git a/system/base/glibc/files/glibc-2.21-roundup.patch b/system/base/glibc/files/glibc-2.21-roundup.patch new file mode 100644 index 00000000..66d3454e --- /dev/null +++ b/system/base/glibc/files/glibc-2.21-roundup.patch @@ -0,0 +1,70 @@ +diff --git a/ChangeLog b/ChangeLog +index dc1ed1b..45579de 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,3 +1,9 @@ ++2015-02-10 Evangelos Foutras ++ ++ [BZ #17949] ++ * sysdeps/i386/i686/multiarch/mempcpy_chk.S: Fix position of ++ jump label. ++ + 2015-02-06 Carlos O'Donell + + * version.h (RELEASE): Set to "stable". +@@ -7,6 +13,7 @@ + * sysdeps/unix/sysv/linux/hppa/pthread.h: Sync with pthread.h. + + 2015-02-05 Paul Pluzhnikov ++ Paul Eggert + + [BZ #16618] + * stdio-common/tst-sscanf.c (main): Test for buffer overflow. +diff --git a/NEWS b/NEWS +index 617cdbb..ff79f0d 100644 +--- a/NEWS ++++ b/NEWS +@@ -5,6 +5,12 @@ See the end for copying conditions. + Please send GNU C library bug reports via + using `glibc' in the "product" field. + ++Version 2.21.1 ++ ++* The following bugs are resolved with this release: ++ ++ 17949. ++ + Version 2.21 + + * The following bugs are resolved with this release: +@@ -21,10 +27,11 @@ Version 2.21 + 17801, 17803, 17806, 17834, 17844, 17848, 17868, 17869, 17870, 17885, + 17892. + +-* CVE-2015-1472 Under certain conditions wscanf can allocate too little +- memory for the to-be-scanned arguments and overflow the allocated +- buffer. The implementation now correctly computes the required buffer +- size when using malloc. ++* CVE-2015-1472 CVE-2015-1473 Under certain conditions wscanf can allocate ++ too little memory for the to-be-scanned arguments and overflow the ++ allocated buffer. The implementation now correctly computes the required ++ buffer size when using malloc, and switches to malloc from alloca as ++ intended. + + * A new semaphore algorithm has been implemented in generic C code for all + machines. Previous custom assembly implementations of semaphore were +diff --git a/sysdeps/i386/i686/multiarch/mempcpy_chk.S b/sysdeps/i386/i686/multiarch/mempcpy_chk.S +index 207b648..b6fa202 100644 +--- a/sysdeps/i386/i686/multiarch/mempcpy_chk.S ++++ b/sysdeps/i386/i686/multiarch/mempcpy_chk.S +@@ -36,8 +36,8 @@ ENTRY(__mempcpy_chk) + cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx) + jne 1f + call __init_cpu_features +- leal __mempcpy_chk_ia32@GOTOFF(%ebx), %eax +-1: testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) ++1: leal __mempcpy_chk_ia32@GOTOFF(%ebx), %eax ++ testl $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx) + jz 2f + leal __mempcpy_chk_sse2_unaligned@GOTOFF(%ebx), %eax + testl $bit_Fast_Unaligned_Load, FEATURE_OFFSET+index_Fast_Unaligned_Load+__cpu_features@GOTOFF(%ebx) diff --git a/system/base/glibc/pspec.xml b/system/base/glibc/pspec.xml index 407fd7c6..e800ec97 100644 --- a/system/base/glibc/pspec.xml +++ b/system/base/glibc/pspec.xml @@ -13,7 +13,7 @@ library GNU libc6 (also called glibc2) C library The GNU C library is used as the C library in the GNU system and most systems with the Linux kernel. It defines the system calls and other basic C programming language facilities. - http://ftp.gnu.org/gnu/libc/glibc-2.20.tar.xz + http://ftp.gnu.org/gnu/libc/glibc-2.21.tar.xz kernel-headers gettext @@ -21,7 +21,7 @@ locale-no-archive.patch - glibc-2.20-roundup.patch + glibc-2.21-roundup.patch @@ -1757,6 +1757,13 @@ + + 2015-04-04 + 2.21 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + 2014-11-28 2.20 diff --git a/system/base/groff/actions.py b/system/base/groff/actions.py index bd80689a..029d4230 100644 --- a/system/base/groff/actions.py +++ b/system/base/groff/actions.py @@ -10,13 +10,13 @@ from pisi.actionsapi import shelltools from pisi.actionsapi import get def setup(): - #shelltools.export("CXXFLAGS","%s -fno-rtti -fno-exceptions" % get.CXXFLAGS()) + #autotools.autoreconf("-fi") + shelltools.export("PAGE", "a4") autotools.configure("--prefix=/usr \ - --with-appresdir=/usr/share/X11/app-defaults \ - --with-x") + --without-x") def build(): - shelltools.export("LC_ALL", "C") + #shelltools.export("LC_ALL", "C") autotools.make() def install(): diff --git a/system/base/groff/files/groff-1.19.2-man-unicode-dashes.patch b/system/base/groff/files/groff-1.19.2-man-unicode-dashes.patch new file mode 100644 index 00000000..d85a8330 --- /dev/null +++ b/system/base/groff/files/groff-1.19.2-man-unicode-dashes.patch @@ -0,0 +1,24 @@ +format dashes as dashes so as to not confuse people + +http://bugs.gentoo.org/16108 +http://bugs.gentoo.org/17580 +http://bugs.gentoo.org/121502 + +--- tmac/man.local ++++ tmac/man.local +@@ -1,2 +1,6 @@ + .\" This file is loaded after an-old.tmac. + .\" Put any local modifications to an-old.tmac here. ++.if '\*[.T]'utf8' \{\ ++. char \- \N'45' ++. char - \N'45' ++.\} +--- tmac/mdoc.local ++++ tmac/mdoc.local +@@ -1,2 +1,6 @@ + .\" This file is loaded after doc.tmac. + .\" Put any local modifications to doc.tmac here. ++.if '\*[.T]'utf8' \{\ ++. char \- \N'45' ++. char - \N'45' ++.\} diff --git a/system/base/groff/files/groff-1.22.3-parallel-mom.patch b/system/base/groff/files/groff-1.22.3-parallel-mom.patch new file mode 100644 index 00000000..10661ac2 --- /dev/null +++ b/system/base/groff/files/groff-1.22.3-parallel-mom.patch @@ -0,0 +1,11 @@ +--- groff-1.22.3/Makefile.in ++++ groff-1.22.3/Makefile.in +@@ -864,7 +864,7 @@ + -f $(top_srcdir)/Makefile.ccpg \ + -f Makefile.dep $(do) + +-$(DEVDIRS) $(XDEVDIRS) $(OTHERDEVDIRS) $(TTYDEVDIRS): FORCE \ ++$(DEVDIRS) $(XDEVDIRS) $(OTHERDEVDIRS) $(TTYDEVDIRS) $(SHPROGDIRS): FORCE \ + $(PROGDEPDIRS) $(CCPROGDIRS) $(CPROGDIRS) + @$(ENVSETUP); \ + if test $(srcdir) = .; then \ diff --git a/system/base/groff/files/gropdf.patch b/system/base/groff/files/gropdf.patch new file mode 100644 index 00000000..9044c64a --- /dev/null +++ b/system/base/groff/files/gropdf.patch @@ -0,0 +1,13 @@ +diff --git a/Makefile.in b/Makefile.in +index bc156ce..70c6f85 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -896,6 +896,8 @@ $(GNULIBDIRS): FORCE + $(MAKE) ACLOCAL=: AUTOCONF=: AUTOHEADER=: AUTOMAKE=: $(do) ;; \ + esac + ++$(SHPROGDIRS): $(PROGDEPDIRS) ++ + $(OTHERDIRS): $(PROGDEPDIRS) $(CCPROGDIRS) $(CPROGDIRS) $(SHPROGDIRS) + + $(INCDIRS) $(PROGDEPDIRS) $(SHPROGDIRS) $(OTHERDIRS): FORCE diff --git a/system/base/groff/files/savannah_bug.patch b/system/base/groff/files/savannah_bug.patch new file mode 100644 index 00000000..755f706b --- /dev/null +++ b/system/base/groff/files/savannah_bug.patch @@ -0,0 +1,228193 @@ +diff -Nuar groff-1.22.3.old/acinclude.m4 groff-1.22.3/acinclude.m4 +--- groff-1.22.3.old/acinclude.m4 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/acinclude.m4 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,25 @@ ++# generated automatically by aclocal 1.14 -*- Autoconf -*- ++ ++# Copyright (C) 1996-2013 Free Software Foundation, Inc. ++ ++# This file is free software; the Free Software Foundation ++# gives unlimited permission to copy and/or distribute it, ++# with or without modifications, as long as this notice is preserved. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without ++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A ++# PARTICULAR PURPOSE. ++ ++m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) ++m4_include([m4/ax_compare_version.m4]) ++m4_include([m4/ax_prog_perl_version.m4]) ++m4_include([m4/codeset.m4]) ++m4_include([m4/fcntl-o.m4]) ++m4_include([m4/glibc21.m4]) ++m4_include([m4/groff.m4]) ++m4_include([m4/iconv.m4]) ++m4_include([m4/lib-ld.m4]) ++m4_include([m4/lib-link.m4]) ++m4_include([m4/lib-prefix.m4]) ++m4_include([m4/localcharset.m4]) +diff -Nuar groff-1.22.3.old/aclocal.m4 groff-1.22.3/aclocal.m4 +--- groff-1.22.3.old/aclocal.m4 2014-11-04 10:39:10.174087080 +0200 ++++ groff-1.22.3/aclocal.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,25 +0,0 @@ +-# generated automatically by aclocal 1.14 -*- Autoconf -*- +- +-# Copyright (C) 1996-2013 Free Software Foundation, Inc. +- +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +-# PARTICULAR PURPOSE. +- +-m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +-m4_include([m4/ax_compare_version.m4]) +-m4_include([m4/ax_prog_perl_version.m4]) +-m4_include([m4/codeset.m4]) +-m4_include([m4/fcntl-o.m4]) +-m4_include([m4/glibc21.m4]) +-m4_include([m4/groff.m4]) +-m4_include([m4/iconv.m4]) +-m4_include([m4/lib-ld.m4]) +-m4_include([m4/lib-link.m4]) +-m4_include([m4/lib-prefix.m4]) +-m4_include([m4/localcharset.m4]) +diff -Nuar groff-1.22.3.old/arch/mingw/Makefile.sub groff-1.22.3/arch/mingw/Makefile.sub +--- groff-1.22.3.old/arch/mingw/Makefile.sub 2014-11-04 10:38:35.432521409 +0200 ++++ groff-1.22.3/arch/mingw/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,66 +0,0 @@ +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.sub +-# +-WINSCRIPTS=\ +- afmtodit.cmd \ +- chem.cmd \ +- gperl.cmd \ +- gpinyin.cmd \ +- grap2graph.cmd \ +- groffer.cmd \ +- grog.cmd \ +- gropdf.cmd \ +- mmroff.cmd \ +- neqn.cmd \ +- pdfmom.cmd \ +- roff2dvi.cmd \ +- roff2html.cmd \ +- roff2pdf.cmd \ +- roff2ps.cmd \ +- roff2text.cmd \ +- roff2x.cmd +- +-RM=rm -f +- +-all: $(make_winscripts) +-install_data: $(make_install_winscripts) +-uninstall_sub: $(make_uninstall_winscripts) +- +-winscripts: $(WINSCRIPTS) +- +-install_winscripts: $(WINSCRIPTS) +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- for f in $(WINSCRIPTS); do \ +- $(RM) $(DESTDIR)$(bindir)/$$f; \ +- $(INSTALL_SCRIPT) $(srcdir)/$$f $(DESTDIR)$(bindir)/$$f; \ +- done +- +-uninstall_winscripts: +- -for f in $(WINSCRIPTS); do \ +- $(RM) $(DESTDIR)$(bindir)/$$f; \ +- done +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/arch/mingw/mingw.am groff-1.22.3/arch/mingw/mingw.am +--- groff-1.22.3.old/arch/mingw/mingw.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/arch/mingw/mingw.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,44 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++# mingw.am ++# ++WINSCRIPTS=\ ++ arch/mingw/afmtodit.cmd \ ++ arch/mingw/chem.cmd \ ++ arch/mingw/gperl.cmd \ ++ arch/mingw/gpinyin.cmd \ ++ arch/mingw/grap2graph.cmd \ ++ arch/mingw/groffer.cmd \ ++ arch/mingw/grog.cmd \ ++ arch/mingw/gropdf.cmd \ ++ arch/mingw/mmroff.cmd \ ++ arch/mingw/neqn.cmd \ ++ arch/mingw/pdfmom.cmd \ ++ arch/mingw/roff2dvi.cmd \ ++ arch/mingw/roff2html.cmd \ ++ arch/mingw/roff2pdf.cmd \ ++ arch/mingw/roff2ps.cmd \ ++ arch/mingw/roff2text.cmd \ ++ arch/mingw/roff2x.cmd ++ ++if BUILD_WINSCRIPTS ++bin_SCRIPTS += $(WINSCRIPTS) ++else ++EXTRA_DIST += $(WINSCRIPTS) ++endif +diff -Nuar groff-1.22.3.old/arch/misc/.gitignore groff-1.22.3/arch/misc/.gitignore +--- groff-1.22.3.old/arch/misc/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/arch/misc/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++shdeps.sed +diff -Nuar groff-1.22.3.old/arch/misc/Makefile.sub groff-1.22.3/arch/misc/Makefile.sub +--- groff-1.22.3.old/arch/misc/Makefile.sub 2014-11-04 10:38:35.191524422 +0200 ++++ groff-1.22.3/arch/misc/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,32 +0,0 @@ +-# Copyright (C) 2004-2014 Free Software Foundation, Inc. +-# Written by Keith Marshall (keith.d.marshall@ntlworld.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-MOSTLYCLEANADD=shdeps.sed +- +-all: shdeps.sed +- +-shdeps.sed: $(srcdir)/shdeps.sh +- $(SHELL) $(srcdir)/shdeps.sh "$(RT_SEP)" "$(SH_SEP)" "$(bindir)" > $@ +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/arch/misc/misc.am groff-1.22.3/arch/misc/misc.am +--- groff-1.22.3.old/arch/misc/misc.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/arch/misc/misc.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,25 @@ ++# Copyright (C) 2004-2014 Free Software Foundation, Inc. ++# Original Makefile.sub written by Keith Marshall ++# (keith.d.marshall@ntlworld.com). ++# Adapted to Automake by Bertrand Garrigues ++# (bertrand.garrigues@laposte.net). ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++EXTRA_DIST += arch/misc/shdeps.sh ++MOSTLYCLEANFILES += shdeps.sed ++ ++shdeps.sed: $(top_srcdir)/arch/misc/shdeps.sh ++ $(SHELL) $(top_srcdir)/arch/misc/shdeps.sh "$(RT_SEP)" "$(SH_SEP)" "$(bindir)" > $@ +diff -Nuar groff-1.22.3.old/bootstrap groff-1.22.3/bootstrap +--- groff-1.22.3.old/bootstrap 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/bootstrap 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,999 @@ ++#! /bin/sh ++# Print a version string. ++scriptversion=2013-12-05.23; # UTC ++ ++# Bootstrap this package from checked-out sources. ++ ++# Copyright (C) 2003-2014 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++# Originally written by Paul Eggert. The canonical version of this ++# script is maintained as build-aux/bootstrap in gnulib, however, to ++# be useful to your project, you should place a copy of it under ++# version control in the top-level directory of your project. The ++# intent is that all customization can be done with a bootstrap.conf ++# file also maintained in your version control; gnulib comes with a ++# template build-aux/bootstrap.conf to get you started. ++ ++# Please report bugs or propose patches to bug-gnulib@gnu.org. ++ ++nl=' ++' ++ ++# Ensure file names are sorted consistently across platforms. ++LC_ALL=C ++export LC_ALL ++ ++# Ensure that CDPATH is not set. Otherwise, the output from cd ++# would cause trouble in at least one use below. ++(unset CDPATH) >/dev/null 2>&1 && unset CDPATH ++ ++local_gl_dir=gl ++ ++me=$0 ++ ++usage() { ++ cat <&2 ++} ++ ++# warn_ WORD1... ++warn_ () ++{ ++ # If IFS does not start with ' ', set it and emit the warning in a subshell. ++ case $IFS in ++ ' '*) warnf_ '%s\n' "$*";; ++ *) (IFS=' '; warn_ "$@");; ++ esac ++} ++ ++# die WORD1... ++die() { warn_ "$@"; exit 1; } ++ ++# Configuration. ++ ++# Name of the Makefile.am ++gnulib_mk=gnulib.mk ++ ++# List of gnulib modules needed. ++gnulib_modules= ++ ++# Any gnulib files needed that are not in modules. ++gnulib_files= ++ ++: ${AUTOPOINT=autopoint} ++: ${AUTORECONF=autoreconf} ++ ++# A function to be called right after gnulib-tool is run. ++# Override it via your own definition in bootstrap.conf. ++bootstrap_post_import_hook() { :; } ++ ++# A function to be called after everything else in this script. ++# Override it via your own definition in bootstrap.conf. ++bootstrap_epilogue() { :; } ++ ++# The command to download all .po files for a specified domain into ++# a specified directory. Fill in the first %s is the domain name, and ++# the second with the destination directory. Use rsync's -L and -r ++# options because the latest/%s directory and the .po files within are ++# all symlinks. ++po_download_command_format=\ ++"rsync --delete --exclude '*.s1' -Lrtvz \ ++ 'translationproject.org::tp/latest/%s/' '%s'" ++ ++# Fallback for downloading .po files (if rsync fails). ++po_download_command_format2=\ ++"wget --mirror -nd -q -np -A.po -P '%s' \ ++ http://translationproject.org/latest/%s/" ++ ++# Prefer a non-empty tarname (4th argument of AC_INIT if given), else ++# fall back to the package name (1st argument with munging) ++extract_package_name=' ++ /^AC_INIT(\[*/{ ++ s/// ++ /^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{ ++ s//\1/ ++ s/[],)].*// ++ p ++ q ++ } ++ s/[],)].*// ++ s/^GNU // ++ y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ ++ s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g ++ p ++ } ++' ++package=$(sed -n "$extract_package_name" configure.ac) \ ++ || die 'cannot find package name in configure.ac' ++gnulib_name=lib$package ++ ++build_aux=build-aux ++source_base=lib ++m4_base=m4 ++doc_base=doc ++tests_base=tests ++gnulib_extra_files='' ++ ++# Additional gnulib-tool options to use. Use "\newline" to break lines. ++gnulib_tool_option_extras= ++ ++# Other locale categories that need message catalogs. ++EXTRA_LOCALE_CATEGORIES= ++ ++# Additional xgettext options to use. Use "\\\newline" to break lines. ++XGETTEXT_OPTIONS='\\\ ++ --flag=_:1:pass-c-format\\\ ++ --flag=N_:1:pass-c-format\\\ ++ --flag=error:3:c-format --flag=error_at_line:5:c-format\\\ ++' ++ ++# Package bug report address and copyright holder for gettext files ++COPYRIGHT_HOLDER='Free Software Foundation, Inc.' ++MSGID_BUGS_ADDRESS=bug-$package@gnu.org ++ ++# Files we don't want to import. ++excluded_files= ++ ++# File that should exist in the top directory of a checked out hierarchy, ++# but not in a distribution tarball. ++checkout_only_file=README-hacking ++ ++# Whether to use copies instead of symlinks. ++copy=false ++ ++# Set this to '.cvsignore .gitignore' in bootstrap.conf if you want ++# those files to be generated in directories like lib/, m4/, and po/. ++# Or set it to 'auto' to make this script select which to use based ++# on which version control system (if any) is used in the source directory. ++vc_ignore=auto ++ ++# Set this to true in bootstrap.conf to enable --bootstrap-sync by ++# default. ++bootstrap_sync=false ++ ++# Use git to update gnulib sources ++use_git=true ++ ++check_exists() { ++ ($1 --version /dev/null 2>&1 ++ test $? -lt 126 ++} ++ ++# find_tool ENVVAR NAMES... ++# ------------------------- ++# Search for a required program. Use the value of ENVVAR, if set, ++# otherwise find the first of the NAMES that can be run. ++# If found, set ENVVAR to the program name, die otherwise. ++# ++# FIXME: code duplication, see also gnu-web-doc-update. ++find_tool () ++{ ++ find_tool_envvar=$1 ++ shift ++ find_tool_names=$@ ++ eval "find_tool_res=\$$find_tool_envvar" ++ if test x"$find_tool_res" = x; then ++ for i; do ++ if check_exists $i; then ++ find_tool_res=$i ++ break ++ fi ++ done ++ fi ++ if test x"$find_tool_res" = x; then ++ warn_ "one of these is required: $find_tool_names;" ++ die "alternatively set $find_tool_envvar to a compatible tool" ++ fi ++ eval "$find_tool_envvar=\$find_tool_res" ++ eval "export $find_tool_envvar" ++} ++ ++# Override the default configuration, if necessary. ++# Make sure that bootstrap.conf is sourced from the current directory ++# if we were invoked as "sh bootstrap". ++case "$0" in ++ */*) test -r "$0.conf" && . "$0.conf" ;; ++ *) test -r "$0.conf" && . ./"$0.conf" ;; ++esac ++ ++# Extra files from gnulib, which override files from other sources. ++test -z "${gnulib_extra_files}" && \ ++ gnulib_extra_files=" ++ build-aux/install-sh ++ build-aux/mdate-sh ++ build-aux/texinfo.tex ++ build-aux/depcomp ++ build-aux/config.guess ++ build-aux/config.sub ++ doc/INSTALL ++" ++ ++if test "$vc_ignore" = auto; then ++ vc_ignore= ++ test -d .git && vc_ignore=.gitignore ++ test -d CVS && vc_ignore="$vc_ignore .cvsignore" ++fi ++ ++# Translate configuration into internal form. ++ ++# Parse options. ++ ++for option ++do ++ case $option in ++ --help) ++ usage ++ exit;; ++ --gnulib-srcdir=*) ++ GNULIB_SRCDIR=${option#--gnulib-srcdir=};; ++ --skip-po) ++ SKIP_PO=t;; ++ --force) ++ checkout_only_file=;; ++ --copy) ++ copy=true;; ++ --bootstrap-sync) ++ bootstrap_sync=true;; ++ --no-bootstrap-sync) ++ bootstrap_sync=false;; ++ --no-git) ++ use_git=false;; ++ *) ++ die "$option: unknown option";; ++ esac ++done ++ ++$use_git || test -d "$GNULIB_SRCDIR" \ ++ || die "Error: --no-git requires --gnulib-srcdir" ++ ++if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then ++ die "Bootstrapping from a non-checked-out distribution is risky." ++fi ++ ++# Strip blank and comment lines to leave significant entries. ++gitignore_entries() { ++ sed '/^#/d; /^$/d' "$@" ++} ++ ++# If $STR is not already on a line by itself in $FILE, insert it at the start. ++# Entries are inserted at the start of the ignore list to ensure existing ++# entries starting with ! are not overridden. Such entries support ++# whitelisting exceptions after a more generic blacklist pattern. ++insert_if_absent() { ++ file=$1 ++ str=$2 ++ test -f $file || touch $file ++ test -r $file || die "Error: failed to read ignore file: $file" ++ duplicate_entries=$(gitignore_entries $file | sort | uniq -d) ++ if [ "$duplicate_entries" ] ; then ++ die "Error: Duplicate entries in $file: " $duplicate_entries ++ fi ++ linesold=$(gitignore_entries $file | wc -l) ++ linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l) ++ if [ $linesold != $linesnew ] ; then ++ { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \ ++ || die "insert_if_absent $file $str: failed" ++ fi ++} ++ ++# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with ++# insert_if_absent. ++insert_vc_ignore() { ++ vc_ignore_file="$1" ++ pattern="$2" ++ case $vc_ignore_file in ++ *.gitignore) ++ # A .gitignore entry that does not start with '/' applies ++ # recursively to subdirectories, so prepend '/' to every ++ # .gitignore entry. ++ pattern=$(echo "$pattern" | sed s,^,/,);; ++ esac ++ insert_if_absent "$vc_ignore_file" "$pattern" ++} ++ ++# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac. ++found_aux_dir=no ++grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \ ++ >/dev/null && found_aux_dir=yes ++grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \ ++ >/dev/null && found_aux_dir=yes ++test $found_aux_dir = yes \ ++ || die "configure.ac lacks 'AC_CONFIG_AUX_DIR([$build_aux])'; add it" ++ ++# If $build_aux doesn't exist, create it now, otherwise some bits ++# below will malfunction. If creating it, also mark it as ignored. ++if test ! -d $build_aux; then ++ mkdir $build_aux ++ for dot_ig in x $vc_ignore; do ++ test $dot_ig = x && continue ++ insert_vc_ignore $dot_ig $build_aux ++ done ++fi ++ ++# Note this deviates from the version comparison in automake ++# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a ++# but this should suffice as we won't be specifying old ++# version formats or redundant trailing .0 in bootstrap.conf. ++# If we did want full compatibility then we should probably ++# use m4_version_compare from autoconf. ++sort_ver() { # sort -V is not generally available ++ ver1="$1" ++ ver2="$2" ++ ++ # split on '.' and compare each component ++ i=1 ++ while : ; do ++ p1=$(echo "$ver1" | cut -d. -f$i) ++ p2=$(echo "$ver2" | cut -d. -f$i) ++ if [ ! "$p1" ]; then ++ echo "$1 $2" ++ break ++ elif [ ! "$p2" ]; then ++ echo "$2 $1" ++ break ++ elif [ ! "$p1" = "$p2" ]; then ++ if [ "$p1" -gt "$p2" ] 2>/dev/null; then # numeric comparison ++ echo "$2 $1" ++ elif [ "$p2" -gt "$p1" ] 2>/dev/null; then # numeric comparison ++ echo "$1 $2" ++ else # numeric, then lexicographic comparison ++ lp=$(printf "$p1\n$p2\n" | LANG=C sort -n | tail -n1) ++ if [ "$lp" = "$p2" ]; then ++ echo "$1 $2" ++ else ++ echo "$2 $1" ++ fi ++ fi ++ break ++ fi ++ i=$(($i+1)) ++ done ++} ++ ++get_version() { ++ app=$1 ++ ++ $app --version >/dev/null 2>&1 || return 1 ++ ++ $app --version 2>&1 | ++ sed -n '# Move version to start of line. ++ s/.*[v ]\([0-9]\)/\1/ ++ ++ # Skip lines that do not start with version. ++ /^[0-9]/!d ++ ++ # Remove characters after the version. ++ s/[^.a-z0-9-].*// ++ ++ # The first component must be digits only. ++ s/^\([0-9]*\)[a-z-].*/\1/ ++ ++ #the following essentially does s/5.005/5.5/ ++ s/\.0*\([1-9]\)/.\1/g ++ p ++ q' ++} ++ ++check_versions() { ++ ret=0 ++ ++ while read app req_ver; do ++ # We only need libtoolize from the libtool package. ++ if test "$app" = libtool; then ++ app=libtoolize ++ fi ++ # Exempt git if --no-git is in effect. ++ if test "$app" = git; then ++ $use_git || continue ++ fi ++ # Honor $APP variables ($TAR, $AUTOCONF, etc.) ++ appvar=$(echo $app | LC_ALL=C tr '[a-z]-' '[A-Z]_') ++ test "$appvar" = TAR && appvar=AMTAR ++ case $appvar in ++ GZIP) ;; # Do not use $GZIP: it contains gzip options. ++ *) eval "app=\${$appvar-$app}" ;; ++ esac ++ ++ # Handle the still-experimental Automake-NG programs specially. ++ # They remain named as the mainstream Automake programs ("automake", ++ # and "aclocal") to avoid gratuitous incompatibilities with ++ # pre-existing usages (by, say, autoreconf, or custom autogen.sh ++ # scripts), but correctly identify themselves (as being part of ++ # "GNU automake-ng") when asked their version. ++ case $app in ++ automake-ng|aclocal-ng) ++ app=${app%-ng} ++ ($app --version | grep '(GNU automake-ng)') >/dev/null 2>&1 || { ++ warn_ "Error: '$app' not found or not from Automake-NG" ++ ret=1 ++ continue ++ } ;; ++ esac ++ if [ "$req_ver" = "-" ]; then ++ # Merely require app to exist; not all prereq apps are well-behaved ++ # so we have to rely on $? rather than get_version. ++ if ! check_exists $app; then ++ warn_ "Error: '$app' not found" ++ ret=1 ++ fi ++ else ++ # Require app to produce a new enough version string. ++ inst_ver=$(get_version $app) ++ if [ ! "$inst_ver" ]; then ++ warn_ "Error: '$app' not found" ++ ret=1 ++ else ++ latest_ver=$(sort_ver $req_ver $inst_ver | cut -d' ' -f2) ++ if [ ! "$latest_ver" = "$inst_ver" ]; then ++ warnf_ '%s\n' \ ++ "Error: '$app' version == $inst_ver is too old" \ ++ " '$app' version >= $req_ver is required" ++ ret=1 ++ fi ++ fi ++ fi ++ done ++ ++ return $ret ++} ++ ++print_versions() { ++ echo "Program Min_version" ++ echo "----------------------" ++ printf %s "$buildreq" ++ echo "----------------------" ++ # can't depend on column -t ++} ++ ++# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6. ++# Also find the compatible sha1 utility on the BSDs ++if test x"$SKIP_PO" = x; then ++ find_tool SHA1SUM sha1sum gsha1sum shasum sha1 ++fi ++ ++use_libtool=0 ++# We'd like to use grep -E, to see if any of LT_INIT, ++# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac, ++# but that's not portable enough (e.g., for Solaris). ++grep '^[ ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \ ++ && use_libtool=1 ++grep '^[ ]*LT_INIT' configure.ac >/dev/null \ ++ && use_libtool=1 ++if test $use_libtool = 1; then ++ find_tool LIBTOOLIZE glibtoolize libtoolize ++fi ++ ++# gnulib-tool requires at least automake and autoconf. ++# If either is not listed, add it (with minimum version) as a prerequisite. ++case $buildreq in ++ *automake*) ;; ++ *) buildreq="automake 1.9 ++$buildreq" ;; ++esac ++case $buildreq in ++ *autoconf*) ;; ++ *) buildreq="autoconf 2.59 ++$buildreq" ;; ++esac ++ ++# When we can deduce that gnulib-tool will require patch, ++# and when patch is not already listed as a prerequisite, add it, too. ++if test -d "$local_gl_dir" \ ++ && ! find "$local_gl_dir" -name '*.diff' -exec false {} +; then ++ case $buildreq in ++ *patch*) ;; ++ *) buildreq="patch - ++$buildreq" ;; ++ esac ++fi ++ ++if ! printf "$buildreq" | check_versions; then ++ echo >&2 ++ if test -f README-prereq; then ++ die "See README-prereq for how to get the prerequisite programs" ++ else ++ die "Please install the prerequisite programs" ++ fi ++fi ++ ++# Warn the user if autom4te appears to be broken; this causes known ++# issues with at least gettext 0.18.3. ++probe=$(echo 'm4_quote([hi])' | autom4te -l M4sugar -t 'm4_quote:$%' -) ++if test "x$probe" != xhi; then ++ warn_ "WARNING: your autom4te wrapper eats stdin;" ++ warn_ "if bootstrap fails, consider upgrading your autotools" ++fi ++ ++echo "$0: Bootstrapping from checked-out $package sources..." ++ ++# See if we can use gnulib's git-merge-changelog merge driver. ++if $use_git && test -d .git && check_exists git; then ++ if git config merge.merge-changelog.driver >/dev/null ; then ++ : ++ elif check_exists git-merge-changelog; then ++ echo "$0: initializing git-merge-changelog driver" ++ git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver' ++ git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B' ++ else ++ echo "$0: consider installing git-merge-changelog from gnulib" ++ fi ++fi ++ ++ ++cleanup_gnulib() { ++ status=$? ++ rm -fr "$gnulib_path" ++ exit $status ++} ++ ++git_modules_config () { ++ test -f .gitmodules && git config --file .gitmodules "$@" ++} ++ ++if $use_git; then ++ gnulib_path=$(git_modules_config submodule.gnulib.path) ++ test -z "$gnulib_path" && gnulib_path=gnulib ++fi ++ ++# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a ++# submodule, for use in the rest of the script. ++ ++case ${GNULIB_SRCDIR--} in ++-) ++ # Note that $use_git is necessarily true in this case. ++ if git_modules_config submodule.gnulib.url >/dev/null; then ++ echo "$0: getting gnulib files..." ++ git submodule init || exit $? ++ git submodule update || exit $? ++ ++ elif [ ! -d "$gnulib_path" ]; then ++ echo "$0: getting gnulib files..." ++ ++ trap cleanup_gnulib 1 2 13 15 ++ ++ shallow= ++ git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2' ++ git clone $shallow git://git.sv.gnu.org/gnulib "$gnulib_path" || ++ cleanup_gnulib ++ ++ trap - 1 2 13 15 ++ fi ++ GNULIB_SRCDIR=$gnulib_path ++ ;; ++*) ++ # Use GNULIB_SRCDIR directly or as a reference. ++ if $use_git && test -d "$GNULIB_SRCDIR"/.git && \ ++ git_modules_config submodule.gnulib.url >/dev/null; then ++ echo "$0: getting gnulib files..." ++ if git submodule -h|grep -- --reference > /dev/null; then ++ # Prefer the one-liner available in git 1.6.4 or newer. ++ git submodule update --init --reference "$GNULIB_SRCDIR" \ ++ "$gnulib_path" || exit $? ++ else ++ # This fallback allows at least git 1.5.5. ++ if test -f "$gnulib_path"/gnulib-tool; then ++ # Since file already exists, assume submodule init already complete. ++ git submodule update || exit $? ++ else ++ # Older git can't clone into an empty directory. ++ rmdir "$gnulib_path" 2>/dev/null ++ git clone --reference "$GNULIB_SRCDIR" \ ++ "$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \ ++ && git submodule init && git submodule update \ ++ || exit $? ++ fi ++ fi ++ GNULIB_SRCDIR=$gnulib_path ++ fi ++ ;; ++esac ++ ++# $GNULIB_SRCDIR now points to the version of gnulib to use, and ++# we no longer need to use git or $gnulib_path below here. ++ ++if $bootstrap_sync; then ++ cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || { ++ echo "$0: updating bootstrap and restarting..." ++ case $(sh -c 'echo "$1"' -- a) in ++ a) ignored=--;; ++ *) ignored=ignored;; ++ esac ++ exec sh -c \ ++ 'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \ ++ $ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \ ++ "$0" "$@" --no-bootstrap-sync ++ } ++fi ++ ++gnulib_tool=$GNULIB_SRCDIR/gnulib-tool ++<$gnulib_tool || exit $? ++ ++# Get translations. ++ ++download_po_files() { ++ subdir=$1 ++ domain=$2 ++ echo "$me: getting translations into $subdir for $domain..." ++ cmd=$(printf "$po_download_command_format" "$domain" "$subdir") ++ eval "$cmd" && return ++ # Fallback to HTTP. ++ cmd=$(printf "$po_download_command_format2" "$subdir" "$domain") ++ eval "$cmd" ++} ++ ++# Mirror .po files to $po_dir/.reference and copy only the new ++# or modified ones into $po_dir. Also update $po_dir/LINGUAS. ++# Note po files that exist locally only are left in $po_dir but will ++# not be included in LINGUAS and hence will not be distributed. ++update_po_files() { ++ # Directory containing primary .po files. ++ # Overwrite them only when we're sure a .po file is new. ++ po_dir=$1 ++ domain=$2 ++ ++ # Mirror *.po files into this dir. ++ # Usually contains *.s1 checksum files. ++ ref_po_dir="$po_dir/.reference" ++ ++ test -d $ref_po_dir || mkdir $ref_po_dir || return ++ download_po_files $ref_po_dir $domain \ ++ && ls "$ref_po_dir"/*.po 2>/dev/null | ++ sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return ++ ++ langs=$(cd $ref_po_dir && echo *.po | sed 's/\.po//g') ++ test "$langs" = '*' && langs=x ++ for po in $langs; do ++ case $po in x) continue;; esac ++ new_po="$ref_po_dir/$po.po" ++ cksum_file="$ref_po_dir/$po.s1" ++ if ! test -f "$cksum_file" || ++ ! test -f "$po_dir/$po.po" || ++ ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then ++ echo "$me: updated $po_dir/$po.po..." ++ cp "$new_po" "$po_dir/$po.po" \ ++ && $SHA1SUM < "$new_po" > "$cksum_file" || return ++ fi ++ done ++} ++ ++case $SKIP_PO in ++'') ++ if test -d po; then ++ update_po_files po $package || exit ++ fi ++ ++ if test -d runtime-po; then ++ update_po_files runtime-po $package-runtime || exit ++ fi;; ++esac ++ ++symlink_to_dir() ++{ ++ src=$1/$2 ++ dst=${3-$2} ++ ++ test -f "$src" && { ++ ++ # If the destination directory doesn't exist, create it. ++ # This is required at least for "lib/uniwidth/cjk.h". ++ dst_dir=$(dirname "$dst") ++ if ! test -d "$dst_dir"; then ++ mkdir -p "$dst_dir" ++ ++ # If we've just created a directory like lib/uniwidth, ++ # tell version control system(s) it's ignorable. ++ # FIXME: for now, this does only one level ++ parent=$(dirname "$dst_dir") ++ for dot_ig in x $vc_ignore; do ++ test $dot_ig = x && continue ++ ig=$parent/$dot_ig ++ insert_vc_ignore $ig "${dst_dir##*/}" ++ done ++ fi ++ ++ if $copy; then ++ { ++ test ! -h "$dst" || { ++ echo "$me: rm -f $dst" && ++ rm -f "$dst" ++ } ++ } && ++ test -f "$dst" && ++ cmp -s "$src" "$dst" || { ++ echo "$me: cp -fp $src $dst" && ++ cp -fp "$src" "$dst" ++ } ++ else ++ # Leave any existing symlink alone, if it already points to the source, ++ # so that broken build tools that care about symlink times ++ # aren't confused into doing unnecessary builds. Conversely, if the ++ # existing symlink's time stamp is older than the source, make it afresh, ++ # so that broken tools aren't confused into skipping needed builds. See ++ # . ++ test -h "$dst" && ++ src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 && ++ dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 && ++ test "$src_i" = "$dst_i" && ++ both_ls=$(ls -dt "$src" "$dst") && ++ test "X$both_ls" = "X$dst$nl$src" || { ++ dot_dots= ++ case $src in ++ /*) ;; ++ *) ++ case /$dst/ in ++ *//* | */../* | */./* | /*/*/*/*/*/) ++ die "invalid symlink calculation: $src -> $dst";; ++ /*/*/*/*/) dot_dots=../../../;; ++ /*/*/*/) dot_dots=../../;; ++ /*/*/) dot_dots=../;; ++ esac;; ++ esac ++ ++ echo "$me: ln -fs $dot_dots$src $dst" && ++ ln -fs "$dot_dots$src" "$dst" ++ } ++ fi ++ } ++} ++ ++version_controlled_file() { ++ parent=$1 ++ file=$2 ++ if test -d .git; then ++ git rm -n "$file" > /dev/null 2>&1 ++ elif test -d .svn; then ++ svn log -r HEAD "$file" > /dev/null 2>&1 ++ elif test -d CVS; then ++ grep -F "/${file##*/}/" "$parent/CVS/Entries" 2>/dev/null | ++ grep '^/[^/]*/[0-9]' > /dev/null ++ else ++ warn_ "no version control for $file?" ++ false ++ fi ++} ++ ++# NOTE: we have to be careful to run both autopoint and libtoolize ++# before gnulib-tool, since gnulib-tool is likely to provide newer ++# versions of files "installed" by these two programs. ++# Then, *after* gnulib-tool (see below), we have to be careful to ++# run autoreconf in such a way that it does not run either of these ++# two just-pre-run programs. ++ ++# Import from gettext. ++with_gettext=yes ++grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \ ++ with_gettext=no ++ ++if test $with_gettext = yes || test $use_libtool = 1; then ++ ++ tempbase=.bootstrap$$ ++ trap "rm -f $tempbase.0 $tempbase.1" 1 2 13 15 ++ ++ > $tempbase.0 > $tempbase.1 && ++ find . ! -type d -print | sort > $tempbase.0 || exit ++ ++ if test $with_gettext = yes; then ++ # Released autopoint has the tendency to install macros that have been ++ # obsoleted in current gnulib, so run this before gnulib-tool. ++ echo "$0: $AUTOPOINT --force" ++ $AUTOPOINT --force || exit ++ fi ++ ++ # Autoreconf runs aclocal before libtoolize, which causes spurious ++ # warnings if the initial aclocal is confused by the libtoolized ++ # (or worse out-of-date) macro directory. ++ # libtoolize 1.9b added the --install option; but we support back ++ # to libtoolize 1.5.22, where the install action was default. ++ if test $use_libtool = 1; then ++ install= ++ case $($LIBTOOLIZE --help) in ++ *--install*) install=--install ;; ++ esac ++ echo "running: $LIBTOOLIZE $install --copy" ++ $LIBTOOLIZE $install --copy ++ fi ++ ++ find . ! -type d -print | sort >$tempbase.1 ++ old_IFS=$IFS ++ IFS=$nl ++ for file in $(comm -13 $tempbase.0 $tempbase.1); do ++ IFS=$old_IFS ++ parent=${file%/*} ++ version_controlled_file "$parent" "$file" || { ++ for dot_ig in x $vc_ignore; do ++ test $dot_ig = x && continue ++ ig=$parent/$dot_ig ++ insert_vc_ignore "$ig" "${file##*/}" ++ done ++ } ++ done ++ IFS=$old_IFS ++ ++ rm -f $tempbase.0 $tempbase.1 ++ trap - 1 2 13 15 ++fi ++ ++# Import from gnulib. ++ ++gnulib_tool_options="\ ++ --import\ ++ --no-changelog\ ++ --aux-dir $build_aux\ ++ --doc-base $doc_base\ ++ --lib $gnulib_name\ ++ --m4-base $m4_base/\ ++ --source-base $source_base/\ ++ --tests-base $tests_base\ ++ --local-dir $local_gl_dir\ ++ $gnulib_tool_option_extras\ ++" ++if test $use_libtool = 1; then ++ case "$gnulib_tool_options " in ++ *' --libtool '*) ;; ++ *) gnulib_tool_options="$gnulib_tool_options --libtool" ;; ++ esac ++fi ++echo "$0: $gnulib_tool $gnulib_tool_options --import ..." ++$gnulib_tool $gnulib_tool_options --import $gnulib_modules && ++ ++for file in $gnulib_files; do ++ symlink_to_dir "$GNULIB_SRCDIR" $file \ ++ || die "failed to symlink $file" ++done ++ ++bootstrap_post_import_hook \ ++ || die "bootstrap_post_import_hook failed" ++ ++# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some ++# gnulib-populated directories. Such .m4 files would cause aclocal to fail. ++# The following requires GNU find 4.2.3 or newer. Considering the usual ++# portability constraints of this script, that may seem a very demanding ++# requirement, but it should be ok. Ignore any failure, which is fine, ++# since this is only a convenience to help developers avoid the relatively ++# unusual case in which a symlinked-to .m4 file is git-removed from gnulib ++# between successive runs of this script. ++find "$m4_base" "$source_base" \ ++ -depth \( -name '*.m4' -o -name '*.[ch]' \) \ ++ -type l -xtype l -delete > /dev/null 2>&1 ++ ++# Invoke autoreconf with --force --install to ensure upgrades of tools ++# such as ylwrap. ++AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS" ++ ++# Some systems (RHEL 5) are using ancient autotools, for which the ++# --no-recursive option had not been invented. Detect that lack and ++# omit the option when it's not supported. FIXME in 2017: remove this ++# hack when RHEL 5 autotools are updated, or when they become irrelevant. ++case $($AUTORECONF --help) in ++ *--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";; ++esac ++ ++# Tell autoreconf not to invoke autopoint or libtoolize; they were run above. ++echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS" ++AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \ ++ || die "autoreconf failed" ++ ++# Get some extra files from gnulib, overriding existing files. ++for file in $gnulib_extra_files; do ++ case $file in ++ */INSTALL) dst=INSTALL;; ++ build-aux/*) dst=$build_aux/${file#build-aux/};; ++ *) dst=$file;; ++ esac ++ symlink_to_dir "$GNULIB_SRCDIR" $file $dst \ ++ || die "failed to symlink $file" ++done ++ ++if test $with_gettext = yes; then ++ # Create gettext configuration. ++ echo "$0: Creating po/Makevars from po/Makevars.template ..." ++ rm -f po/Makevars ++ sed ' ++ /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/ ++ /^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/ ++ /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'| ++ /^XGETTEXT_OPTIONS *=/{ ++ s/$/ \\/ ++ a\ ++ '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+} ++ } ++ ' po/Makevars.template >po/Makevars \ ++ || die 'cannot generate po/Makevars' ++ ++ # If the 'gettext' module is in use, grab the latest Makefile.in.in. ++ # If only the 'gettext-h' module is in use, assume autopoint already ++ # put the correct version of this file into place. ++ case $gnulib_modules in ++ *gettext-h*) ;; ++ *gettext*) ++ cp $GNULIB_SRCDIR/build-aux/po/Makefile.in.in po/Makefile.in.in \ ++ || die "cannot create po/Makefile.in.in" ++ ;; ++ esac ++ ++ if test -d runtime-po; then ++ # Similarly for runtime-po/Makevars, but not quite the same. ++ rm -f runtime-po/Makevars ++ sed ' ++ /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/ ++ /^subdir *=.*/s/=.*/= runtime-po/ ++ /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/ ++ /^XGETTEXT_OPTIONS *=/{ ++ s/$/ \\/ ++ a\ ++ '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+} ++ } ++ ' po/Makevars.template >runtime-po/Makevars \ ++ || die 'cannot generate runtime-po/Makevars' ++ ++ # Copy identical files from po to runtime-po. ++ (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po) ++ fi ++fi ++ ++bootstrap_epilogue ++ ++echo "$0: done. Now you can run './configure'." ++ ++# Local variables: ++# eval: (add-hook 'write-file-hooks 'time-stamp) ++# time-stamp-start: "scriptversion=" ++# time-stamp-format: "%:y-%02m-%02d.%02H" ++# time-stamp-time-zone: "UTC" ++# time-stamp-end: "; # UTC" ++# End: +diff -Nuar groff-1.22.3.old/bootstrap.conf groff-1.22.3/bootstrap.conf +--- groff-1.22.3.old/bootstrap.conf 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/bootstrap.conf 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,100 @@ ++# Bootstrap configuration. ++ ++# Copyright (C) 2006-2007, 2009-2012 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++ ++# gnulib m4 macro ++m4_base=gnulib_m4 ++ ++# gnulib C source files ++source_base=lib ++ ++# additional standard files, particularly added by ++# automake --add-missing ++build_aux=build-aux ++ ++gnulib_name=libgnu ++ ++# This file is not distributed and used to check if the bootstrap ++# script is not launched on a tarball ++checkout_only_file=README.git ++ ++# gnulib modules used by this package. ++# havelib provides config.rpath ++# can be get through gettext though ++gnulib_modules=" ++ havelib ++ non-recursive-gnulib-prefix-hack ++ wcwidth ++" ++ ++# Name of the Makefile.am ++gnulib_tool_option_extras="--makefile-name=gnulib.mk" ++ ++# Additional xgettext options to use. Use "\\\newline" to break lines. ++XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\ ++ --from-code=UTF-8\\\ ++ --flag=asprintf:2:c-format --flag=vasprintf:2:c-format\\\ ++ --flag=asnprintf:3:c-format --flag=vasnprintf:3:c-format\\\ ++ --flag=wrapf:1:c-format\\\ ++' ++ ++# If "AM_GNU_GETTEXT(external" or "AM_GNU_GETTEXT([external]" ++# appears in configure.ac, exclude some unnecessary files. ++# Without grep's -E option (not portable enough, pre-configure), ++# the following test is ugly. Also, this depends on the existence ++# of configure.ac, not the obsolescent-named configure.in. But if ++# you're using this infrastructure, you should care about such things. ++ ++gettext_external=0 ++grep '^[ ]*AM_GNU_GETTEXT(external\>' configure.ac > /dev/null && ++ gettext_external=1 ++grep '^[ ]*AM_GNU_GETTEXT(\[external\]' configure.ac > /dev/null && ++ gettext_external=1 ++ ++if test $gettext_external = 1; then ++ # Gettext supplies these files, but we don't need them since ++ # we don't have an intl subdirectory. ++ excluded_files=' ++ m4/glibc2.m4 ++ m4/intdiv0.m4 ++ m4/lcmessage.m4 ++ m4/lock.m4 ++ m4/printf-posix.m4 ++ m4/size_max.m4 ++ m4/uintmax_t.m4 ++ m4/ulonglong.m4 ++ m4/visibility.m4 ++ m4/xsize.m4 ++ ' ++fi ++ ++# Build prerequisites ++buildreq="\ ++autoconf 2.65 ++automake 1.12.2 ++git 1.5.5 ++libtool 2.2.2 ++tar - ++" ++ ++bootstrap_post_import_hook () ++{ ++ # Automake requires that ChangeLog exist. ++ touch ChangeLog || return 1 ++ # Massage lib/gnulib.mk before using it later in the bootstrapping process. ++ build-aux/prefix-gnulib-mk --lib-name=$gnulib_name lib/$gnulib_mk ++} +diff -Nuar groff-1.22.3.old/ChangeLog groff-1.22.3/ChangeLog +--- groff-1.22.3.old/ChangeLog 2014-11-04 10:38:35.138525085 +0200 ++++ groff-1.22.3/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,243 @@ ++2015-04-22 Deri James ++ ++ Fix Savannah bug #44891. ++ ++ * src/devices/gropdf/gropdf.pl: If module Compress::Zlib is not ++ available fallback to producing uncompressed PDF and output a ++ warning. ++ ++2015-04-22 Bjarni Ingi Gislason ++ ++ Fix Savannah bug #44894. ++ ++ * tmac/strip.sed: Add a `generated file' warning. ++ ++2015-04-21 Deri James ++ ++ Fix Savannah bug #44890. ++ Patch by Peter Bray. ++ ++ * font/devpdf/devpdf.am: Don't use 'find -maxdepth'. ++ ++2015-03-07 Ingo Schwarze ++ ++ [mdoc] Fix Savannah bug #44733. ++ ++ Prevent mdoc(7) Bl with trailing -width or -offset from picking up ++ old args. ++ ++ * tmac/doc.tmac-u (doc-do-Bl-args): When checking whether there is ++ another argument to a Bl macro, do not inspect the argument list ++ because it is never cleaned and may contain arguments from previous ++ macro invocations. Instead, inspect the argument count which is ++ always up to date. ++ ++2015-04-10 Daiki Ueno ++ ++ Fix link error on NetBSD 6. ++ ++ Reported by carsten.kunze@arcor.de in: ++ . ++ The problem can also be reproduced if gl_cv_func_wcwidth_works=no ++ is passed to configure. ++ ++ * src/preproc/grn/grn.am (grn_LDADD): Change the link order of ++ libgroff.a and lib/libgnu.a according to dependency. ++ * src/roff/troff/troff.am (troff_LDADD): Likewise. ++ ++2015-04-08 Werner LEMBERG ++ ++ Fix Savannah bug #44767. ++ Patch by Peter Bray. ++ ++ * src/roff/grog/grog.am (grog): Correctly substitute `grog_dir'. ++ ++2015-04-03 Werner LEMBERG ++ ++ Fix Savannah bug #44708 (2/2). ++ ++ Make man pages work in compatibility mode. ++ Also fix some minor typos. ++ ++ * contrib/pic2graph/pic2graph.man, man/ditroff.man, man/groff.man, ++ man/groff_diff.man, man/groff_out.man, man/groff_tmac.man, ++ man/roff.man, src/devices/grodvi/grodvi.man, ++ src/devices/grohtml/grohtml.man, src/devices/grolbp/grolbp.man, ++ src/devices/grolj4/grolj4.man, src/devices/grolj4/lj4_font.man, ++ src/devices/gropdf/gropdf.man, src/devices/gropdf/pdfmom.man, ++ src/devices/grops/grops.man, src/devices/grotty/grotty.man, ++ src/devices/xditview/xditview.man, src/preproc/eqn/eqn.man, ++ src/preproc/eqn/neqn.man, src/preproc/grn/grn.man, ++ src/preproc/pic/pic.man, src/preproc/preconv/preconv.man, ++ src/preproc/refer/refer.man, src/preproc/soelim/soelim.man, ++ src/preproc/tbl/tbl.man, src/roff/groff/groff.man, ++ src/roff/grog/grog.man, src/roff/nroff/nroff.man, ++ src/roff/troff/troff.man, src/utils/addftinto/addftinfo.man, ++ src/utils/afmtodit/afmtodit.man, src/utils/hpftodit/hpftodit.man, ++ src/utils/indxbib/indxbib.man, src/utils/lkbib/lkbib.man, ++ src/utils/lookbib/lookbib.man, src/utils/pfbtops/pfbtops.man, ++ src/utils/tfmtodit/tfmtodit.man, src/utils/xtotroff/xtotroff.man, ++ tmac/groff_man.man, tmac/groff_trace.man: Do it. ++ ++2015-04-03 Werner LEMBERG ++ ++ Fix Savannah bug #44708 (1/2). ++ ++ * tmac/andoc.tmac (reload_doc, reload_man): Don't use `de1', ++ otherwise we can't manipulate the compatibility flag within the ++ macro. ++ ++ * tmac/doc-common-u (Dt): Remove invalid leading whitespace. ++ ++2015-03-11 Deri James ++ ++ * src/devices/gropdf/gropdf.pl: Was not handling the final glyph ++ correctly in the "standard" fonts which are not embedded. They ++ actually have 257 glyphs (0-256) not 256 as I'd assumed, so the ++ remappiing code needs to be applied for them as well as the ++ embedded downloadable fonts. ++ ++2015-03-11 Deri James ++ ++ * src/devices/gropdf/gropdf.pl: Fix problem remappiing ++ ellipsis (affects all glyphs > 255). ++ ++2015-03-07 Werner LEMBERG ++ ++ * tmac/tmac.am (TMACSPECIALFILES): Removed. No longer used. ++ ++2015-03-07 Ingo Schwarze ++ ++ * tmac/doc-common-u (Dd): Avoid warning `unbalanced .el request'. ++ ++2015-02-12 Werner LEMBERG ++ ++ Minor fixes due to renaming `groff.texinfo' to `groff.texi'. ++ ++ * doc/doc.am (SUFFIXES): Update. ++ * m4/groff.m4 (GROFF_MAKEINFO): Update. ++ ++2015-01-30 Bertrand Garrigues ++ ++ Automake migration and Gnulib integration. ++ ++ Gnulib: ++ - Added gnulib as a git submodule. ++ - Integrated bootstrap scripts from gnulib. ++ - Gnulib m4 directory is now in `gnulib_m4', while Gnulib's .c ++ files are located in `lib'. `gnulib_m4' and `lib' are generated ++ and distributed. ++ ++ Automake: ++ - Removed Makefiles from the old build system. ++ - Converted Makefile.in into Makefile.am. ++ - Converted Makefile.sub files in all directories to a .am file. ++ - Removed configure, src/include/config.hin (now generated). ++ - Removed various helper scripts (config.guess, config.rpath...), ++ now installed by bootstrap in `build-aux'. ++ - Moved aclocal.m4 to acinclude.m4 (aclocal.m4 is now generated). ++ - Makefile in non-recursive style. ++ - Updated INSTALL.REPO (INSTALL is now a symlink to ++ gnulib/doc/INSTALL, original INSTALL file moved to INSTALL.extra) ++ - Added (empty) THANKS, AUTHORS files. ++ - Added a document on the usage of automake in groff in ++ doc/automake.pdf. ++ ++ Additional features: ++ - Out-of-source build is supported. ++ - Parallel build is possible (make -j). ++ - Automatic targets from Automake: `make dist', `make distcheck'. ++ - 'make check' is available for automatic testing, gdiffmk's test ++ was plugged to this target. ++ - Auto-detect if make has builtin variable `RM'. ++ ++2015-01-14 Ingo Schwarze ++ ++ Fix Savannah bug #43905. ++ ++ * src/libs/libgroff/glyphuni.cpp (glyph_to_unicode_list), ++ * src/libs/libgroff/uniglyph.cpp (unicode_to_glyph_list): Remove ++ double entries for `rk', `lk', `lt', `rt', `rb', and `lb'. ++ ++2014-12-16 Werner LEMBERG ++ ++ Update Unicode-to-Unicode mapping to version 7.0.0. ++ ++ * src/libs/libgroff/make-uniuni: Update emitted copyright. ++ ++ * src/libs/libgroff/uniuni.cpp: Regenerated. ++ ++2014-11-29 Werner LEMBERG ++ ++ Fix previous commit. ++ ++ We forgot to test whether the patch works if compiling from ++ scratch... ++ ++ Problem reported by Bertrand Garrigues ++ . ++ ++ * src/include/lib.h (interpret_lf_args, normalize_for_lf): Move ++ declarations to... ++ * src/include/lf.h: This new file. ++ ++ * src/libs/libgroff/lf.cpp, src/preproc/pic/pic.h, ++ src/preproc/preconv/preconv.cpp, src/preproc/refer/refer.h, ++ src/preproc/soelim/soelim.cpp, src/preproc/tbl/table.h: Include ++ `lf.h'. ++ Make `lib.h' the first included header file. ++ ++ * src/preproc/eqn/eqn.h: Don't include `stringclass.h'. ++ * src/preproc/eqn/main.cpp: Include `stringclass.h' and `lf.h'. ++ ++ * src/roff/groff/groff.cpp: Make `lib.h' the first included header ++ file. ++ ++2014-11-10 Eli Zaretskii ++ ++ Improve native Windows port. ++ ++ This patch fixes two issues. ++ ++ . Handle backslashes in `.lf' arguments for MSDOS and Windows. ++ . Fix file name quoting for the groff pipeline. ++ ++ * src/preproc/soelim/soelim.cpp (do_file): ++ * src/preproc/refer/refer.cpp (do_file): ++ * src/preproc/preconv/preconv.cpp (do_file): ++ * src/preproc/pic/main.cpp (do_file): ++ * src/preproc/eqn/main.cpp (do_file): Call `normalize_for_lf' to ++ convert backslashes in the file name being processed to forward ++ slashes. ++ ++ * src/include/lib.h (normalize_for_lf): Add prototype. ++ ++ * src/preproc/eqn/eqn.h: ++ * src/preproc/pic/pic.h: ++ * src/preproc/refer/refer.h: ++ * src/preproc/tbl/table.h: Include stringclass.h before lib.h. ++ ++ * src/libs/libgroff/lf.cpp (normalize_for_lf): New function. ++ ++ * src/roff/groff/groff.cpp: Include stringclass.h before lib.h. ++ (append_arg_to_string) [_WIN32 && !__CYGWIN__]: Use only "..." for ++ quoting in native Windows builds. ++ ++2014-11-18 Deri James ++ ++ My commit '3fe78135c9fe666dadffde2a822b0535d8db6feb' introduced ++ problem in subroutine `TextWid'. Octal char `\nnn' returns width of ++ 4 char string rather than width of single character. ++ ++ * src/devices/gropdf/gropdf.pl: Change `TextWid' to recognise octal ++ escaped characters (\nnn). ++ ++2014-11-07 Deri James ++ ++ See bug #43555. ++ ++ * src/devices/gropdf/gropdf.pl: Correct Date Format. ++ + 2014-11-04 Werner LEMBERG + + * src/libs/gnulib/*: Regenerate autotool files. +diff -Nuar groff-1.22.3.old/config.guess groff-1.22.3/config.guess +--- groff-1.22.3.old/config.guess 2014-11-04 10:38:35.140525060 +0200 ++++ groff-1.22.3/config.guess 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1420 +0,0 @@ +-#! /bin/sh +-# Attempt to guess a canonical system name. +-# Copyright 1992-2014 Free Software Foundation, Inc. +- +-timestamp='2014-03-23' +- +-# This file is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 3 of the License, or +-# (at your option) any later version. +-# +-# This program is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program; if not, see . +-# +-# As a special exception to the GNU General Public License, if you +-# distribute this file as part of a program that contains a +-# configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that +-# program. This Exception is an additional permission under section 7 +-# of the GNU General Public License, version 3 ("GPLv3"). +-# +-# Originally written by Per Bothner. +-# +-# You can get the latest version of this script from: +-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +-# +-# Please send patches with a ChangeLog entry to config-patches@gnu.org. +- +- +-me=`echo "$0" | sed -e 's,.*/,,'` +- +-usage="\ +-Usage: $0 [OPTION] +- +-Output the configuration name of the system \`$me' is run on. +- +-Operation modes: +- -h, --help print this help, then exit +- -t, --time-stamp print date of last modification, then exit +- -v, --version print version number, then exit +- +-Report bugs and patches to ." +- +-version="\ +-GNU config.guess ($timestamp) +- +-Originally written by Per Bothner. +-Copyright 1992-2014 Free Software Foundation, Inc. +- +-This is free software; see the source for copying conditions. There is NO +-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +- +-help=" +-Try \`$me --help' for more information." +- +-# Parse command line +-while test $# -gt 0 ; do +- case $1 in +- --time-stamp | --time* | -t ) +- echo "$timestamp" ; exit ;; +- --version | -v ) +- echo "$version" ; exit ;; +- --help | --h* | -h ) +- echo "$usage"; exit ;; +- -- ) # Stop option processing +- shift; break ;; +- - ) # Use stdin as input. +- break ;; +- -* ) +- echo "$me: invalid option $1$help" >&2 +- exit 1 ;; +- * ) +- break ;; +- esac +-done +- +-if test $# != 0; then +- echo "$me: too many arguments$help" >&2 +- exit 1 +-fi +- +-trap 'exit 1' 1 2 15 +- +-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +-# compiler to aid in system detection is discouraged as it requires +-# temporary files to be created and, as you can see below, it is a +-# headache to deal with in a portable fashion. +- +-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +-# use `HOST_CC' if defined, but it is deprecated. +- +-# Portable tmp directory creation inspired by the Autoconf team. +- +-set_cc_for_build=' +-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +-: ${TMPDIR=/tmp} ; +- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || +- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || +- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || +- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +-dummy=$tmp/dummy ; +-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +-case $CC_FOR_BUILD,$HOST_CC,$CC in +- ,,) echo "int x;" > $dummy.c ; +- for c in cc gcc c89 c99 ; do +- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then +- CC_FOR_BUILD="$c"; break ; +- fi ; +- done ; +- if test x"$CC_FOR_BUILD" = x ; then +- CC_FOR_BUILD=no_compiler_found ; +- fi +- ;; +- ,,*) CC_FOR_BUILD=$CC ;; +- ,*,*) CC_FOR_BUILD=$HOST_CC ;; +-esac ; set_cc_for_build= ;' +- +-# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +-# (ghazi@noc.rutgers.edu 1994-08-24) +-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +- PATH=$PATH:/.attbin ; export PATH +-fi +- +-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +- +-case "${UNAME_SYSTEM}" in +-Linux|GNU|GNU/*) +- # If the system lacks a compiler, then just pick glibc. +- # We could probably try harder. +- LIBC=gnu +- +- eval $set_cc_for_build +- cat <<-EOF > $dummy.c +- #include +- #if defined(__UCLIBC__) +- LIBC=uclibc +- #elif defined(__dietlibc__) +- LIBC=dietlibc +- #else +- LIBC=gnu +- #endif +- EOF +- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` +- ;; +-esac +- +-# Note: order is significant - the case branches are not exclusive. +- +-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +- *:NetBSD:*:*) +- # NetBSD (nbsd) targets should (where applicable) match one or +- # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, +- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently +- # switched to ELF, *-*-netbsd* would select the old +- # object file format. This provides both forward +- # compatibility and a consistent mechanism for selecting the +- # object file format. +- # +- # Note: NetBSD doesn't particularly care about the vendor +- # portion of the name. We always set it to "unknown". +- sysctl="sysctl -n hw.machine_arch" +- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ +- /usr/sbin/$sysctl 2>/dev/null || echo unknown)` +- case "${UNAME_MACHINE_ARCH}" in +- armeb) machine=armeb-unknown ;; +- arm*) machine=arm-unknown ;; +- sh3el) machine=shl-unknown ;; +- sh3eb) machine=sh-unknown ;; +- sh5el) machine=sh5le-unknown ;; +- *) machine=${UNAME_MACHINE_ARCH}-unknown ;; +- esac +- # The Operating System including object format, if it has switched +- # to ELF recently, or will in the future. +- case "${UNAME_MACHINE_ARCH}" in +- arm*|i386|m68k|ns32k|sh3*|sparc|vax) +- eval $set_cc_for_build +- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ +- | grep -q __ELF__ +- then +- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). +- # Return netbsd for either. FIX? +- os=netbsd +- else +- os=netbsdelf +- fi +- ;; +- *) +- os=netbsd +- ;; +- esac +- # The OS release +- # Debian GNU/NetBSD machines have a different userland, and +- # thus, need a distinct triplet. However, they do not need +- # kernel version information, so it can be replaced with a +- # suitable tag, in the style of linux-gnu. +- case "${UNAME_VERSION}" in +- Debian*) +- release='-gnu' +- ;; +- *) +- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` +- ;; +- esac +- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: +- # contains redundant information, the shorter form: +- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. +- echo "${machine}-${os}${release}" +- exit ;; +- *:Bitrig:*:*) +- UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` +- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} +- exit ;; +- *:OpenBSD:*:*) +- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` +- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} +- exit ;; +- *:ekkoBSD:*:*) +- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} +- exit ;; +- *:SolidBSD:*:*) +- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} +- exit ;; +- macppc:MirBSD:*:*) +- echo powerpc-unknown-mirbsd${UNAME_RELEASE} +- exit ;; +- *:MirBSD:*:*) +- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} +- exit ;; +- alpha:OSF1:*:*) +- case $UNAME_RELEASE in +- *4.0) +- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` +- ;; +- *5.*) +- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` +- ;; +- esac +- # According to Compaq, /usr/sbin/psrinfo has been available on +- # OSF/1 and Tru64 systems produced since 1995. I hope that +- # covers most systems running today. This code pipes the CPU +- # types through head -n 1, so we only detect the type of CPU 0. +- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` +- case "$ALPHA_CPU_TYPE" in +- "EV4 (21064)") +- UNAME_MACHINE="alpha" ;; +- "EV4.5 (21064)") +- UNAME_MACHINE="alpha" ;; +- "LCA4 (21066/21068)") +- UNAME_MACHINE="alpha" ;; +- "EV5 (21164)") +- UNAME_MACHINE="alphaev5" ;; +- "EV5.6 (21164A)") +- UNAME_MACHINE="alphaev56" ;; +- "EV5.6 (21164PC)") +- UNAME_MACHINE="alphapca56" ;; +- "EV5.7 (21164PC)") +- UNAME_MACHINE="alphapca57" ;; +- "EV6 (21264)") +- UNAME_MACHINE="alphaev6" ;; +- "EV6.7 (21264A)") +- UNAME_MACHINE="alphaev67" ;; +- "EV6.8CB (21264C)") +- UNAME_MACHINE="alphaev68" ;; +- "EV6.8AL (21264B)") +- UNAME_MACHINE="alphaev68" ;; +- "EV6.8CX (21264D)") +- UNAME_MACHINE="alphaev68" ;; +- "EV6.9A (21264/EV69A)") +- UNAME_MACHINE="alphaev69" ;; +- "EV7 (21364)") +- UNAME_MACHINE="alphaev7" ;; +- "EV7.9 (21364A)") +- UNAME_MACHINE="alphaev79" ;; +- esac +- # A Pn.n version is a patched version. +- # A Vn.n version is a released version. +- # A Tn.n version is a released field test version. +- # A Xn.n version is an unreleased experimental baselevel. +- # 1.2 uses "1.2" for uname -r. +- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` +- # Reset EXIT trap before exiting to avoid spurious non-zero exit code. +- exitcode=$? +- trap '' 0 +- exit $exitcode ;; +- Alpha\ *:Windows_NT*:*) +- # How do we know it's Interix rather than the generic POSIX subsystem? +- # Should we change UNAME_MACHINE based on the output of uname instead +- # of the specific Alpha model? +- echo alpha-pc-interix +- exit ;; +- 21064:Windows_NT:50:3) +- echo alpha-dec-winnt3.5 +- exit ;; +- Amiga*:UNIX_System_V:4.0:*) +- echo m68k-unknown-sysv4 +- exit ;; +- *:[Aa]miga[Oo][Ss]:*:*) +- echo ${UNAME_MACHINE}-unknown-amigaos +- exit ;; +- *:[Mm]orph[Oo][Ss]:*:*) +- echo ${UNAME_MACHINE}-unknown-morphos +- exit ;; +- *:OS/390:*:*) +- echo i370-ibm-openedition +- exit ;; +- *:z/VM:*:*) +- echo s390-ibm-zvmoe +- exit ;; +- *:OS400:*:*) +- echo powerpc-ibm-os400 +- exit ;; +- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) +- echo arm-acorn-riscix${UNAME_RELEASE} +- exit ;; +- arm*:riscos:*:*|arm*:RISCOS:*:*) +- echo arm-unknown-riscos +- exit ;; +- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) +- echo hppa1.1-hitachi-hiuxmpp +- exit ;; +- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) +- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. +- if test "`(/bin/universe) 2>/dev/null`" = att ; then +- echo pyramid-pyramid-sysv3 +- else +- echo pyramid-pyramid-bsd +- fi +- exit ;; +- NILE*:*:*:dcosx) +- echo pyramid-pyramid-svr4 +- exit ;; +- DRS?6000:unix:4.0:6*) +- echo sparc-icl-nx6 +- exit ;; +- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) +- case `/usr/bin/uname -p` in +- sparc) echo sparc-icl-nx7; exit ;; +- esac ;; +- s390x:SunOS:*:*) +- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- sun4H:SunOS:5.*:*) +- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) +- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) +- echo i386-pc-auroraux${UNAME_RELEASE} +- exit ;; +- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) +- eval $set_cc_for_build +- SUN_ARCH="i386" +- # If there is a compiler, see if it is configured for 64-bit objects. +- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. +- # This test works for both compilers. +- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then +- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ +- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ +- grep IS_64BIT_ARCH >/dev/null +- then +- SUN_ARCH="x86_64" +- fi +- fi +- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- sun4*:SunOS:6*:*) +- # According to config.sub, this is the proper way to canonicalize +- # SunOS6. Hard to guess exactly what SunOS6 will be like, but +- # it's likely to be more like Solaris than SunOS4. +- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- sun4*:SunOS:*:*) +- case "`/usr/bin/arch -k`" in +- Series*|S4*) +- UNAME_RELEASE=`uname -v` +- ;; +- esac +- # Japanese Language versions have a version number like `4.1.3-JL'. +- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` +- exit ;; +- sun3*:SunOS:*:*) +- echo m68k-sun-sunos${UNAME_RELEASE} +- exit ;; +- sun*:*:4.2BSD:*) +- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` +- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 +- case "`/bin/arch`" in +- sun3) +- echo m68k-sun-sunos${UNAME_RELEASE} +- ;; +- sun4) +- echo sparc-sun-sunos${UNAME_RELEASE} +- ;; +- esac +- exit ;; +- aushp:SunOS:*:*) +- echo sparc-auspex-sunos${UNAME_RELEASE} +- exit ;; +- # The situation for MiNT is a little confusing. The machine name +- # can be virtually everything (everything which is not +- # "atarist" or "atariste" at least should have a processor +- # > m68000). The system name ranges from "MiNT" over "FreeMiNT" +- # to the lowercase version "mint" (or "freemint"). Finally +- # the system name "TOS" denotes a system which is actually not +- # MiNT. But MiNT is downward compatible to TOS, so this should +- # be no problem. +- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) +- echo m68k-atari-mint${UNAME_RELEASE} +- exit ;; +- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) +- echo m68k-atari-mint${UNAME_RELEASE} +- exit ;; +- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) +- echo m68k-atari-mint${UNAME_RELEASE} +- exit ;; +- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) +- echo m68k-milan-mint${UNAME_RELEASE} +- exit ;; +- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) +- echo m68k-hades-mint${UNAME_RELEASE} +- exit ;; +- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) +- echo m68k-unknown-mint${UNAME_RELEASE} +- exit ;; +- m68k:machten:*:*) +- echo m68k-apple-machten${UNAME_RELEASE} +- exit ;; +- powerpc:machten:*:*) +- echo powerpc-apple-machten${UNAME_RELEASE} +- exit ;; +- RISC*:Mach:*:*) +- echo mips-dec-mach_bsd4.3 +- exit ;; +- RISC*:ULTRIX:*:*) +- echo mips-dec-ultrix${UNAME_RELEASE} +- exit ;; +- VAX*:ULTRIX*:*:*) +- echo vax-dec-ultrix${UNAME_RELEASE} +- exit ;; +- 2020:CLIX:*:* | 2430:CLIX:*:*) +- echo clipper-intergraph-clix${UNAME_RELEASE} +- exit ;; +- mips:*:*:UMIPS | mips:*:*:RISCos) +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +-#ifdef __cplusplus +-#include /* for printf() prototype */ +- int main (int argc, char *argv[]) { +-#else +- int main (argc, argv) int argc; char *argv[]; { +-#endif +- #if defined (host_mips) && defined (MIPSEB) +- #if defined (SYSTYPE_SYSV) +- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); +- #endif +- #if defined (SYSTYPE_SVR4) +- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); +- #endif +- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) +- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); +- #endif +- #endif +- exit (-1); +- } +-EOF +- $CC_FOR_BUILD -o $dummy $dummy.c && +- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && +- SYSTEM_NAME=`$dummy $dummyarg` && +- { echo "$SYSTEM_NAME"; exit; } +- echo mips-mips-riscos${UNAME_RELEASE} +- exit ;; +- Motorola:PowerMAX_OS:*:*) +- echo powerpc-motorola-powermax +- exit ;; +- Motorola:*:4.3:PL8-*) +- echo powerpc-harris-powermax +- exit ;; +- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) +- echo powerpc-harris-powermax +- exit ;; +- Night_Hawk:Power_UNIX:*:*) +- echo powerpc-harris-powerunix +- exit ;; +- m88k:CX/UX:7*:*) +- echo m88k-harris-cxux7 +- exit ;; +- m88k:*:4*:R4*) +- echo m88k-motorola-sysv4 +- exit ;; +- m88k:*:3*:R3*) +- echo m88k-motorola-sysv3 +- exit ;; +- AViiON:dgux:*:*) +- # DG/UX returns AViiON for all architectures +- UNAME_PROCESSOR=`/usr/bin/uname -p` +- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] +- then +- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ +- [ ${TARGET_BINARY_INTERFACE}x = x ] +- then +- echo m88k-dg-dgux${UNAME_RELEASE} +- else +- echo m88k-dg-dguxbcs${UNAME_RELEASE} +- fi +- else +- echo i586-dg-dgux${UNAME_RELEASE} +- fi +- exit ;; +- M88*:DolphinOS:*:*) # DolphinOS (SVR3) +- echo m88k-dolphin-sysv3 +- exit ;; +- M88*:*:R3*:*) +- # Delta 88k system running SVR3 +- echo m88k-motorola-sysv3 +- exit ;; +- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) +- echo m88k-tektronix-sysv3 +- exit ;; +- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) +- echo m68k-tektronix-bsd +- exit ;; +- *:IRIX*:*:*) +- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` +- exit ;; +- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. +- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id +- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' +- i*86:AIX:*:*) +- echo i386-ibm-aix +- exit ;; +- ia64:AIX:*:*) +- if [ -x /usr/bin/oslevel ] ; then +- IBM_REV=`/usr/bin/oslevel` +- else +- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} +- fi +- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} +- exit ;; +- *:AIX:2:3) +- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- #include +- +- main() +- { +- if (!__power_pc()) +- exit(1); +- puts("powerpc-ibm-aix3.2.5"); +- exit(0); +- } +-EOF +- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` +- then +- echo "$SYSTEM_NAME" +- else +- echo rs6000-ibm-aix3.2.5 +- fi +- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then +- echo rs6000-ibm-aix3.2.4 +- else +- echo rs6000-ibm-aix3.2 +- fi +- exit ;; +- *:AIX:*:[4567]) +- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` +- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then +- IBM_ARCH=rs6000 +- else +- IBM_ARCH=powerpc +- fi +- if [ -x /usr/bin/oslevel ] ; then +- IBM_REV=`/usr/bin/oslevel` +- else +- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} +- fi +- echo ${IBM_ARCH}-ibm-aix${IBM_REV} +- exit ;; +- *:AIX:*:*) +- echo rs6000-ibm-aix +- exit ;; +- ibmrt:4.4BSD:*|romp-ibm:BSD:*) +- echo romp-ibm-bsd4.4 +- exit ;; +- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and +- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to +- exit ;; # report: romp-ibm BSD 4.3 +- *:BOSX:*:*) +- echo rs6000-bull-bosx +- exit ;; +- DPX/2?00:B.O.S.:*:*) +- echo m68k-bull-sysv3 +- exit ;; +- 9000/[34]??:4.3bsd:1.*:*) +- echo m68k-hp-bsd +- exit ;; +- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) +- echo m68k-hp-bsd4.4 +- exit ;; +- 9000/[34678]??:HP-UX:*:*) +- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` +- case "${UNAME_MACHINE}" in +- 9000/31? ) HP_ARCH=m68000 ;; +- 9000/[34]?? ) HP_ARCH=m68k ;; +- 9000/[678][0-9][0-9]) +- if [ -x /usr/bin/getconf ]; then +- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` +- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` +- case "${sc_cpu_version}" in +- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 +- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 +- 532) # CPU_PA_RISC2_0 +- case "${sc_kernel_bits}" in +- 32) HP_ARCH="hppa2.0n" ;; +- 64) HP_ARCH="hppa2.0w" ;; +- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 +- esac ;; +- esac +- fi +- if [ "${HP_ARCH}" = "" ]; then +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- +- #define _HPUX_SOURCE +- #include +- #include +- +- int main () +- { +- #if defined(_SC_KERNEL_BITS) +- long bits = sysconf(_SC_KERNEL_BITS); +- #endif +- long cpu = sysconf (_SC_CPU_VERSION); +- +- switch (cpu) +- { +- case CPU_PA_RISC1_0: puts ("hppa1.0"); break; +- case CPU_PA_RISC1_1: puts ("hppa1.1"); break; +- case CPU_PA_RISC2_0: +- #if defined(_SC_KERNEL_BITS) +- switch (bits) +- { +- case 64: puts ("hppa2.0w"); break; +- case 32: puts ("hppa2.0n"); break; +- default: puts ("hppa2.0"); break; +- } break; +- #else /* !defined(_SC_KERNEL_BITS) */ +- puts ("hppa2.0"); break; +- #endif +- default: puts ("hppa1.0"); break; +- } +- exit (0); +- } +-EOF +- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` +- test -z "$HP_ARCH" && HP_ARCH=hppa +- fi ;; +- esac +- if [ ${HP_ARCH} = "hppa2.0w" ] +- then +- eval $set_cc_for_build +- +- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating +- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler +- # generating 64-bit code. GNU and HP use different nomenclature: +- # +- # $ CC_FOR_BUILD=cc ./config.guess +- # => hppa2.0w-hp-hpux11.23 +- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess +- # => hppa64-hp-hpux11.23 +- +- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | +- grep -q __LP64__ +- then +- HP_ARCH="hppa2.0w" +- else +- HP_ARCH="hppa64" +- fi +- fi +- echo ${HP_ARCH}-hp-hpux${HPUX_REV} +- exit ;; +- ia64:HP-UX:*:*) +- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` +- echo ia64-hp-hpux${HPUX_REV} +- exit ;; +- 3050*:HI-UX:*:*) +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- #include +- int +- main () +- { +- long cpu = sysconf (_SC_CPU_VERSION); +- /* The order matters, because CPU_IS_HP_MC68K erroneously returns +- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct +- results, however. */ +- if (CPU_IS_PA_RISC (cpu)) +- { +- switch (cpu) +- { +- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; +- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; +- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; +- default: puts ("hppa-hitachi-hiuxwe2"); break; +- } +- } +- else if (CPU_IS_HP_MC68K (cpu)) +- puts ("m68k-hitachi-hiuxwe2"); +- else puts ("unknown-hitachi-hiuxwe2"); +- exit (0); +- } +-EOF +- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && +- { echo "$SYSTEM_NAME"; exit; } +- echo unknown-hitachi-hiuxwe2 +- exit ;; +- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) +- echo hppa1.1-hp-bsd +- exit ;; +- 9000/8??:4.3bsd:*:*) +- echo hppa1.0-hp-bsd +- exit ;; +- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) +- echo hppa1.0-hp-mpeix +- exit ;; +- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) +- echo hppa1.1-hp-osf +- exit ;; +- hp8??:OSF1:*:*) +- echo hppa1.0-hp-osf +- exit ;; +- i*86:OSF1:*:*) +- if [ -x /usr/sbin/sysversion ] ; then +- echo ${UNAME_MACHINE}-unknown-osf1mk +- else +- echo ${UNAME_MACHINE}-unknown-osf1 +- fi +- exit ;; +- parisc*:Lites*:*:*) +- echo hppa1.1-hp-lites +- exit ;; +- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) +- echo c1-convex-bsd +- exit ;; +- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) +- if getsysinfo -f scalar_acc +- then echo c32-convex-bsd +- else echo c2-convex-bsd +- fi +- exit ;; +- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) +- echo c34-convex-bsd +- exit ;; +- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) +- echo c38-convex-bsd +- exit ;; +- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) +- echo c4-convex-bsd +- exit ;; +- CRAY*Y-MP:*:*:*) +- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- CRAY*[A-Z]90:*:*:*) +- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ +- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ +- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ +- -e 's/\.[^.]*$/.X/' +- exit ;; +- CRAY*TS:*:*:*) +- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- CRAY*T3E:*:*:*) +- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- CRAY*SV1:*:*:*) +- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- *:UNICOS/mp:*:*) +- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) +- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` +- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` +- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` +- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" +- exit ;; +- 5000:UNIX_System_V:4.*:*) +- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` +- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` +- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" +- exit ;; +- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) +- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} +- exit ;; +- sparc*:BSD/OS:*:*) +- echo sparc-unknown-bsdi${UNAME_RELEASE} +- exit ;; +- *:BSD/OS:*:*) +- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} +- exit ;; +- *:FreeBSD:*:*) +- UNAME_PROCESSOR=`/usr/bin/uname -p` +- case ${UNAME_PROCESSOR} in +- amd64) +- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; +- *) +- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; +- esac +- exit ;; +- i*:CYGWIN*:*) +- echo ${UNAME_MACHINE}-pc-cygwin +- exit ;; +- *:MINGW64*:*) +- echo ${UNAME_MACHINE}-pc-mingw64 +- exit ;; +- *:MINGW*:*) +- echo ${UNAME_MACHINE}-pc-mingw32 +- exit ;; +- *:MSYS*:*) +- echo ${UNAME_MACHINE}-pc-msys +- exit ;; +- i*:windows32*:*) +- # uname -m includes "-pc" on this system. +- echo ${UNAME_MACHINE}-mingw32 +- exit ;; +- i*:PW*:*) +- echo ${UNAME_MACHINE}-pc-pw32 +- exit ;; +- *:Interix*:*) +- case ${UNAME_MACHINE} in +- x86) +- echo i586-pc-interix${UNAME_RELEASE} +- exit ;; +- authenticamd | genuineintel | EM64T) +- echo x86_64-unknown-interix${UNAME_RELEASE} +- exit ;; +- IA64) +- echo ia64-unknown-interix${UNAME_RELEASE} +- exit ;; +- esac ;; +- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) +- echo i${UNAME_MACHINE}-pc-mks +- exit ;; +- 8664:Windows_NT:*) +- echo x86_64-pc-mks +- exit ;; +- i*:Windows_NT*:* | Pentium*:Windows_NT*:*) +- # How do we know it's Interix rather than the generic POSIX subsystem? +- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we +- # UNAME_MACHINE based on the output of uname instead of i386? +- echo i586-pc-interix +- exit ;; +- i*:UWIN*:*) +- echo ${UNAME_MACHINE}-pc-uwin +- exit ;; +- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) +- echo x86_64-unknown-cygwin +- exit ;; +- p*:CYGWIN*:*) +- echo powerpcle-unknown-cygwin +- exit ;; +- prep*:SunOS:5.*:*) +- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- *:GNU:*:*) +- # the GNU system +- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` +- exit ;; +- *:GNU/*:*:*) +- # other systems with GNU libc and userland +- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} +- exit ;; +- i*86:Minix:*:*) +- echo ${UNAME_MACHINE}-pc-minix +- exit ;; +- aarch64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- aarch64_be:Linux:*:*) +- UNAME_MACHINE=aarch64_be +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- alpha:Linux:*:*) +- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in +- EV5) UNAME_MACHINE=alphaev5 ;; +- EV56) UNAME_MACHINE=alphaev56 ;; +- PCA56) UNAME_MACHINE=alphapca56 ;; +- PCA57) UNAME_MACHINE=alphapca56 ;; +- EV6) UNAME_MACHINE=alphaev6 ;; +- EV67) UNAME_MACHINE=alphaev67 ;; +- EV68*) UNAME_MACHINE=alphaev68 ;; +- esac +- objdump --private-headers /bin/sh | grep -q ld.so.1 +- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- arc:Linux:*:* | arceb:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- arm*:Linux:*:*) +- eval $set_cc_for_build +- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ +- | grep -q __ARM_EABI__ +- then +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- else +- if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ +- | grep -q __ARM_PCS_VFP +- then +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi +- else +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf +- fi +- fi +- exit ;; +- avr32*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- cris:Linux:*:*) +- echo ${UNAME_MACHINE}-axis-linux-${LIBC} +- exit ;; +- crisv32:Linux:*:*) +- echo ${UNAME_MACHINE}-axis-linux-${LIBC} +- exit ;; +- frv:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- hexagon:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- i*86:Linux:*:*) +- echo ${UNAME_MACHINE}-pc-linux-${LIBC} +- exit ;; +- ia64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- m32r*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- m68*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- mips:Linux:*:* | mips64:Linux:*:*) +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- #undef CPU +- #undef ${UNAME_MACHINE} +- #undef ${UNAME_MACHINE}el +- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) +- CPU=${UNAME_MACHINE}el +- #else +- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) +- CPU=${UNAME_MACHINE} +- #else +- CPU= +- #endif +- #endif +-EOF +- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` +- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } +- ;; +- openrisc*:Linux:*:*) +- echo or1k-unknown-linux-${LIBC} +- exit ;; +- or32:Linux:*:* | or1k*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- padre:Linux:*:*) +- echo sparc-unknown-linux-${LIBC} +- exit ;; +- parisc64:Linux:*:* | hppa64:Linux:*:*) +- echo hppa64-unknown-linux-${LIBC} +- exit ;; +- parisc:Linux:*:* | hppa:Linux:*:*) +- # Look for CPU level +- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in +- PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; +- PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; +- *) echo hppa-unknown-linux-${LIBC} ;; +- esac +- exit ;; +- ppc64:Linux:*:*) +- echo powerpc64-unknown-linux-${LIBC} +- exit ;; +- ppc:Linux:*:*) +- echo powerpc-unknown-linux-${LIBC} +- exit ;; +- ppc64le:Linux:*:*) +- echo powerpc64le-unknown-linux-${LIBC} +- exit ;; +- ppcle:Linux:*:*) +- echo powerpcle-unknown-linux-${LIBC} +- exit ;; +- s390:Linux:*:* | s390x:Linux:*:*) +- echo ${UNAME_MACHINE}-ibm-linux-${LIBC} +- exit ;; +- sh64*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- sh*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- sparc:Linux:*:* | sparc64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- tile*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- vax:Linux:*:*) +- echo ${UNAME_MACHINE}-dec-linux-${LIBC} +- exit ;; +- x86_64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- xtensa*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- i*86:DYNIX/ptx:4*:*) +- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. +- # earlier versions are messed up and put the nodename in both +- # sysname and nodename. +- echo i386-sequent-sysv4 +- exit ;; +- i*86:UNIX_SV:4.2MP:2.*) +- # Unixware is an offshoot of SVR4, but it has its own version +- # number series starting with 2... +- # I am not positive that other SVR4 systems won't match this, +- # I just have to hope. -- rms. +- # Use sysv4.2uw... so that sysv4* matches it. +- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} +- exit ;; +- i*86:OS/2:*:*) +- # If we were able to find `uname', then EMX Unix compatibility +- # is probably installed. +- echo ${UNAME_MACHINE}-pc-os2-emx +- exit ;; +- i*86:XTS-300:*:STOP) +- echo ${UNAME_MACHINE}-unknown-stop +- exit ;; +- i*86:atheos:*:*) +- echo ${UNAME_MACHINE}-unknown-atheos +- exit ;; +- i*86:syllable:*:*) +- echo ${UNAME_MACHINE}-pc-syllable +- exit ;; +- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) +- echo i386-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- i*86:*DOS:*:*) +- echo ${UNAME_MACHINE}-pc-msdosdjgpp +- exit ;; +- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) +- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` +- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then +- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} +- else +- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} +- fi +- exit ;; +- i*86:*:5:[678]*) +- # UnixWare 7.x, OpenUNIX and OpenServer 6. +- case `/bin/uname -X | grep "^Machine"` in +- *486*) UNAME_MACHINE=i486 ;; +- *Pentium) UNAME_MACHINE=i586 ;; +- *Pent*|*Celeron) UNAME_MACHINE=i686 ;; +- esac +- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} +- exit ;; +- i*86:*:3.2:*) +- if test -f /usr/options/cb.name; then +- UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then +- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` +- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 +- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ +- && UNAME_MACHINE=i586 +- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ +- && UNAME_MACHINE=i686 +- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ +- && UNAME_MACHINE=i686 +- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL +- else +- echo ${UNAME_MACHINE}-pc-sysv32 +- fi +- exit ;; +- pc:*:*:*) +- # Left here for compatibility: +- # uname -m prints for DJGPP always 'pc', but it prints nothing about +- # the processor, so we play safe by assuming i586. +- # Note: whatever this is, it MUST be the same as what config.sub +- # prints for the "djgpp" host, or else GDB configury will decide that +- # this is a cross-build. +- echo i586-pc-msdosdjgpp +- exit ;; +- Intel:Mach:3*:*) +- echo i386-pc-mach3 +- exit ;; +- paragon:*:*:*) +- echo i860-intel-osf1 +- exit ;; +- i860:*:4.*:*) # i860-SVR4 +- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then +- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 +- else # Add other i860-SVR4 vendors below as they are discovered. +- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 +- fi +- exit ;; +- mini*:CTIX:SYS*5:*) +- # "miniframe" +- echo m68010-convergent-sysv +- exit ;; +- mc68k:UNIX:SYSTEM5:3.51m) +- echo m68k-convergent-sysv +- exit ;; +- M680?0:D-NIX:5.3:*) +- echo m68k-diab-dnix +- exit ;; +- M68*:*:R3V[5678]*:*) +- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; +- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) +- OS_REL='' +- test -r /etc/.relid \ +- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` +- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ +- && { echo i486-ncr-sysv4.3${OS_REL}; exit; } +- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ +- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; +- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) +- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ +- && { echo i486-ncr-sysv4; exit; } ;; +- NCR*:*:4.2:* | MPRAS*:*:4.2:*) +- OS_REL='.3' +- test -r /etc/.relid \ +- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` +- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ +- && { echo i486-ncr-sysv4.3${OS_REL}; exit; } +- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ +- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } +- /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ +- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; +- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) +- echo m68k-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- mc68030:UNIX_System_V:4.*:*) +- echo m68k-atari-sysv4 +- exit ;; +- TSUNAMI:LynxOS:2.*:*) +- echo sparc-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- rs6000:LynxOS:2.*:*) +- echo rs6000-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) +- echo powerpc-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- SM[BE]S:UNIX_SV:*:*) +- echo mips-dde-sysv${UNAME_RELEASE} +- exit ;; +- RM*:ReliantUNIX-*:*:*) +- echo mips-sni-sysv4 +- exit ;; +- RM*:SINIX-*:*:*) +- echo mips-sni-sysv4 +- exit ;; +- *:SINIX-*:*:*) +- if uname -p 2>/dev/null >/dev/null ; then +- UNAME_MACHINE=`(uname -p) 2>/dev/null` +- echo ${UNAME_MACHINE}-sni-sysv4 +- else +- echo ns32k-sni-sysv +- fi +- exit ;; +- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort +- # says +- echo i586-unisys-sysv4 +- exit ;; +- *:UNIX_System_V:4*:FTX*) +- # From Gerald Hewes . +- # How about differentiating between stratus architectures? -djm +- echo hppa1.1-stratus-sysv4 +- exit ;; +- *:*:*:FTX*) +- # From seanf@swdc.stratus.com. +- echo i860-stratus-sysv4 +- exit ;; +- i*86:VOS:*:*) +- # From Paul.Green@stratus.com. +- echo ${UNAME_MACHINE}-stratus-vos +- exit ;; +- *:VOS:*:*) +- # From Paul.Green@stratus.com. +- echo hppa1.1-stratus-vos +- exit ;; +- mc68*:A/UX:*:*) +- echo m68k-apple-aux${UNAME_RELEASE} +- exit ;; +- news*:NEWS-OS:6*:*) +- echo mips-sony-newsos6 +- exit ;; +- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) +- if [ -d /usr/nec ]; then +- echo mips-nec-sysv${UNAME_RELEASE} +- else +- echo mips-unknown-sysv${UNAME_RELEASE} +- fi +- exit ;; +- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. +- echo powerpc-be-beos +- exit ;; +- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. +- echo powerpc-apple-beos +- exit ;; +- BePC:BeOS:*:*) # BeOS running on Intel PC compatible. +- echo i586-pc-beos +- exit ;; +- BePC:Haiku:*:*) # Haiku running on Intel PC compatible. +- echo i586-pc-haiku +- exit ;; +- x86_64:Haiku:*:*) +- echo x86_64-unknown-haiku +- exit ;; +- SX-4:SUPER-UX:*:*) +- echo sx4-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-5:SUPER-UX:*:*) +- echo sx5-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-6:SUPER-UX:*:*) +- echo sx6-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-7:SUPER-UX:*:*) +- echo sx7-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-8:SUPER-UX:*:*) +- echo sx8-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-8R:SUPER-UX:*:*) +- echo sx8r-nec-superux${UNAME_RELEASE} +- exit ;; +- Power*:Rhapsody:*:*) +- echo powerpc-apple-rhapsody${UNAME_RELEASE} +- exit ;; +- *:Rhapsody:*:*) +- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} +- exit ;; +- *:Darwin:*:*) +- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown +- eval $set_cc_for_build +- if test "$UNAME_PROCESSOR" = unknown ; then +- UNAME_PROCESSOR=powerpc +- fi +- if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then +- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then +- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ +- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ +- grep IS_64BIT_ARCH >/dev/null +- then +- case $UNAME_PROCESSOR in +- i386) UNAME_PROCESSOR=x86_64 ;; +- powerpc) UNAME_PROCESSOR=powerpc64 ;; +- esac +- fi +- fi +- elif test "$UNAME_PROCESSOR" = i386 ; then +- # Avoid executing cc on OS X 10.9, as it ships with a stub +- # that puts up a graphical alert prompting to install +- # developer tools. Any system running Mac OS X 10.7 or +- # later (Darwin 11 and later) is required to have a 64-bit +- # processor. This is not true of the ARM version of Darwin +- # that Apple uses in portable devices. +- UNAME_PROCESSOR=x86_64 +- fi +- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} +- exit ;; +- *:procnto*:*:* | *:QNX:[0123456789]*:*) +- UNAME_PROCESSOR=`uname -p` +- if test "$UNAME_PROCESSOR" = "x86"; then +- UNAME_PROCESSOR=i386 +- UNAME_MACHINE=pc +- fi +- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} +- exit ;; +- *:QNX:*:4*) +- echo i386-pc-qnx +- exit ;; +- NEO-?:NONSTOP_KERNEL:*:*) +- echo neo-tandem-nsk${UNAME_RELEASE} +- exit ;; +- NSE-*:NONSTOP_KERNEL:*:*) +- echo nse-tandem-nsk${UNAME_RELEASE} +- exit ;; +- NSR-?:NONSTOP_KERNEL:*:*) +- echo nsr-tandem-nsk${UNAME_RELEASE} +- exit ;; +- *:NonStop-UX:*:*) +- echo mips-compaq-nonstopux +- exit ;; +- BS2000:POSIX*:*:*) +- echo bs2000-siemens-sysv +- exit ;; +- DS/*:UNIX_System_V:*:*) +- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} +- exit ;; +- *:Plan9:*:*) +- # "uname -m" is not consistent, so use $cputype instead. 386 +- # is converted to i386 for consistency with other x86 +- # operating systems. +- if test "$cputype" = "386"; then +- UNAME_MACHINE=i386 +- else +- UNAME_MACHINE="$cputype" +- fi +- echo ${UNAME_MACHINE}-unknown-plan9 +- exit ;; +- *:TOPS-10:*:*) +- echo pdp10-unknown-tops10 +- exit ;; +- *:TENEX:*:*) +- echo pdp10-unknown-tenex +- exit ;; +- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) +- echo pdp10-dec-tops20 +- exit ;; +- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) +- echo pdp10-xkl-tops20 +- exit ;; +- *:TOPS-20:*:*) +- echo pdp10-unknown-tops20 +- exit ;; +- *:ITS:*:*) +- echo pdp10-unknown-its +- exit ;; +- SEI:*:*:SEIUX) +- echo mips-sei-seiux${UNAME_RELEASE} +- exit ;; +- *:DragonFly:*:*) +- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` +- exit ;; +- *:*VMS:*:*) +- UNAME_MACHINE=`(uname -p) 2>/dev/null` +- case "${UNAME_MACHINE}" in +- A*) echo alpha-dec-vms ; exit ;; +- I*) echo ia64-dec-vms ; exit ;; +- V*) echo vax-dec-vms ; exit ;; +- esac ;; +- *:XENIX:*:SysV) +- echo i386-pc-xenix +- exit ;; +- i*86:skyos:*:*) +- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' +- exit ;; +- i*86:rdos:*:*) +- echo ${UNAME_MACHINE}-pc-rdos +- exit ;; +- i*86:AROS:*:*) +- echo ${UNAME_MACHINE}-pc-aros +- exit ;; +- x86_64:VMkernel:*:*) +- echo ${UNAME_MACHINE}-unknown-esx +- exit ;; +-esac +- +-cat >&2 < in order to provide the needed +-information to handle your system. +- +-config.guess timestamp = $timestamp +- +-uname -m = `(uname -m) 2>/dev/null || echo unknown` +-uname -r = `(uname -r) 2>/dev/null || echo unknown` +-uname -s = `(uname -s) 2>/dev/null || echo unknown` +-uname -v = `(uname -v) 2>/dev/null || echo unknown` +- +-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +-/bin/uname -X = `(/bin/uname -X) 2>/dev/null` +- +-hostinfo = `(hostinfo) 2>/dev/null` +-/bin/universe = `(/bin/universe) 2>/dev/null` +-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +-/bin/arch = `(/bin/arch) 2>/dev/null` +-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` +- +-UNAME_MACHINE = ${UNAME_MACHINE} +-UNAME_RELEASE = ${UNAME_RELEASE} +-UNAME_SYSTEM = ${UNAME_SYSTEM} +-UNAME_VERSION = ${UNAME_VERSION} +-EOF +- +-exit 1 +- +-# Local variables: +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "timestamp='" +-# time-stamp-format: "%:y-%02m-%02d" +-# time-stamp-end: "'" +-# End: +diff -Nuar groff-1.22.3.old/config.rpath groff-1.22.3/config.rpath +--- groff-1.22.3.old/config.rpath 2014-11-04 10:38:35.140525060 +0200 ++++ groff-1.22.3/config.rpath 1970-01-01 02:00:00.000000000 +0200 +@@ -1,684 +0,0 @@ +-#! /bin/sh +-# Output a system dependent set of variables, describing how to set the +-# run time search path of shared libraries in an executable. +-# +-# Copyright 1996-2014 Free Software Foundation, Inc. +-# Taken from GNU libtool, 2001 +-# Originally by Gordon Matzigkeit , 1996 +-# +-# This file is free software; the Free Software Foundation gives +-# unlimited permission to copy and/or distribute it, with or without +-# modifications, as long as this notice is preserved. +-# +-# The first argument passed to this file is the canonical host specification, +-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +-# or +-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +-# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +-# should be set by the caller. +-# +-# The set of defined variables is at the end of this script. +- +-# Known limitations: +-# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +-# than 256 bytes, otherwise the compiler driver will dump core. The only +-# known workaround is to choose shorter directory names for the build +-# directory and/or the installation directory. +- +-# All known linkers require a '.a' archive for static linking (except MSVC, +-# which needs '.lib'). +-libext=a +-shrext=.so +- +-host="$1" +-host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +-host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +-host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +- +-# Code taken from libtool.m4's _LT_CC_BASENAME. +- +-for cc_temp in $CC""; do +- case $cc_temp in +- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; +- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; +- \-*) ;; +- *) break;; +- esac +-done +-cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` +- +-# Code taken from libtool.m4's _LT_COMPILER_PIC. +- +-wl= +-if test "$GCC" = yes; then +- wl='-Wl,' +-else +- case "$host_os" in +- aix*) +- wl='-Wl,' +- ;; +- mingw* | cygwin* | pw32* | os2* | cegcc*) +- ;; +- hpux9* | hpux10* | hpux11*) +- wl='-Wl,' +- ;; +- irix5* | irix6* | nonstopux*) +- wl='-Wl,' +- ;; +- linux* | k*bsd*-gnu | kopensolaris*-gnu) +- case $cc_basename in +- ecc*) +- wl='-Wl,' +- ;; +- icc* | ifort*) +- wl='-Wl,' +- ;; +- lf95*) +- wl='-Wl,' +- ;; +- nagfor*) +- wl='-Wl,-Wl,,' +- ;; +- pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) +- wl='-Wl,' +- ;; +- ccc*) +- wl='-Wl,' +- ;; +- xl* | bgxl* | bgf* | mpixl*) +- wl='-Wl,' +- ;; +- como) +- wl='-lopt=' +- ;; +- *) +- case `$CC -V 2>&1 | sed 5q` in +- *Sun\ F* | *Sun*Fortran*) +- wl= +- ;; +- *Sun\ C*) +- wl='-Wl,' +- ;; +- esac +- ;; +- esac +- ;; +- newsos6) +- ;; +- *nto* | *qnx*) +- ;; +- osf3* | osf4* | osf5*) +- wl='-Wl,' +- ;; +- rdos*) +- ;; +- solaris*) +- case $cc_basename in +- f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) +- wl='-Qoption ld ' +- ;; +- *) +- wl='-Wl,' +- ;; +- esac +- ;; +- sunos4*) +- wl='-Qoption ld ' +- ;; +- sysv4 | sysv4.2uw2* | sysv4.3*) +- wl='-Wl,' +- ;; +- sysv4*MP*) +- ;; +- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) +- wl='-Wl,' +- ;; +- unicos*) +- wl='-Wl,' +- ;; +- uts4*) +- ;; +- esac +-fi +- +-# Code taken from libtool.m4's _LT_LINKER_SHLIBS. +- +-hardcode_libdir_flag_spec= +-hardcode_libdir_separator= +-hardcode_direct=no +-hardcode_minus_L=no +- +-case "$host_os" in +- cygwin* | mingw* | pw32* | cegcc*) +- # FIXME: the MSVC++ port hasn't been tested in a loooong time +- # When not using gcc, we currently assume that we are using +- # Microsoft Visual C++. +- if test "$GCC" != yes; then +- with_gnu_ld=no +- fi +- ;; +- interix*) +- # we just hope/assume this is gcc and not c89 (= MSVC++) +- with_gnu_ld=yes +- ;; +- openbsd*) +- with_gnu_ld=no +- ;; +-esac +- +-ld_shlibs=yes +-if test "$with_gnu_ld" = yes; then +- # Set some defaults for GNU ld with shared library support. These +- # are reset later if shared libraries are not supported. Putting them +- # here allows them to be overridden if necessary. +- # Unlike libtool, we use -rpath here, not --rpath, since the documented +- # option of GNU ld is called -rpath, not --rpath. +- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +- case "$host_os" in +- aix[3-9]*) +- # On AIX/PPC, the GNU linker is very broken +- if test "$host_cpu" != ia64; then +- ld_shlibs=no +- fi +- ;; +- amigaos*) +- case "$host_cpu" in +- powerpc) +- ;; +- m68k) +- hardcode_libdir_flag_spec='-L$libdir' +- hardcode_minus_L=yes +- ;; +- esac +- ;; +- beos*) +- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then +- : +- else +- ld_shlibs=no +- fi +- ;; +- cygwin* | mingw* | pw32* | cegcc*) +- # hardcode_libdir_flag_spec is actually meaningless, as there is +- # no search path for DLLs. +- hardcode_libdir_flag_spec='-L$libdir' +- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then +- : +- else +- ld_shlibs=no +- fi +- ;; +- haiku*) +- ;; +- interix[3-9]*) +- hardcode_direct=no +- hardcode_libdir_flag_spec='${wl}-rpath,$libdir' +- ;; +- gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) +- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then +- : +- else +- ld_shlibs=no +- fi +- ;; +- netbsd*) +- ;; +- solaris*) +- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then +- ld_shlibs=no +- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then +- : +- else +- ld_shlibs=no +- fi +- ;; +- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) +- case `$LD -v 2>&1` in +- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) +- ld_shlibs=no +- ;; +- *) +- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then +- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' +- else +- ld_shlibs=no +- fi +- ;; +- esac +- ;; +- sunos4*) +- hardcode_direct=yes +- ;; +- *) +- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then +- : +- else +- ld_shlibs=no +- fi +- ;; +- esac +- if test "$ld_shlibs" = no; then +- hardcode_libdir_flag_spec= +- fi +-else +- case "$host_os" in +- aix3*) +- # Note: this linker hardcodes the directories in LIBPATH if there +- # are no directories specified by -L. +- hardcode_minus_L=yes +- if test "$GCC" = yes; then +- # Neither direct hardcoding nor static linking is supported with a +- # broken collect2. +- hardcode_direct=unsupported +- fi +- ;; +- aix[4-9]*) +- if test "$host_cpu" = ia64; then +- # On IA64, the linker does run time linking by default, so we don't +- # have to do anything special. +- aix_use_runtimelinking=no +- else +- aix_use_runtimelinking=no +- # Test if we are trying to use run time linking or normal +- # AIX style linking. If -brtl is somewhere in LDFLAGS, we +- # need to do runtime linking. +- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) +- for ld_flag in $LDFLAGS; do +- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then +- aix_use_runtimelinking=yes +- break +- fi +- done +- ;; +- esac +- fi +- hardcode_direct=yes +- hardcode_libdir_separator=':' +- if test "$GCC" = yes; then +- case $host_os in aix4.[012]|aix4.[012].*) +- collect2name=`${CC} -print-prog-name=collect2` +- if test -f "$collect2name" && \ +- strings "$collect2name" | grep resolve_lib_name >/dev/null +- then +- # We have reworked collect2 +- : +- else +- # We have old collect2 +- hardcode_direct=unsupported +- hardcode_minus_L=yes +- hardcode_libdir_flag_spec='-L$libdir' +- hardcode_libdir_separator= +- fi +- ;; +- esac +- fi +- # Begin _LT_AC_SYS_LIBPATH_AIX. +- echo 'int main () { return 0; }' > conftest.c +- ${CC} ${LDFLAGS} conftest.c -o conftest +- aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +-}'` +- if test -z "$aix_libpath"; then +- aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +-}'` +- fi +- if test -z "$aix_libpath"; then +- aix_libpath="/usr/lib:/lib" +- fi +- rm -f conftest.c conftest +- # End _LT_AC_SYS_LIBPATH_AIX. +- if test "$aix_use_runtimelinking" = yes; then +- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" +- else +- if test "$host_cpu" = ia64; then +- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' +- else +- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" +- fi +- fi +- ;; +- amigaos*) +- case "$host_cpu" in +- powerpc) +- ;; +- m68k) +- hardcode_libdir_flag_spec='-L$libdir' +- hardcode_minus_L=yes +- ;; +- esac +- ;; +- bsdi[45]*) +- ;; +- cygwin* | mingw* | pw32* | cegcc*) +- # When not using gcc, we currently assume that we are using +- # Microsoft Visual C++. +- # hardcode_libdir_flag_spec is actually meaningless, as there is +- # no search path for DLLs. +- hardcode_libdir_flag_spec=' ' +- libext=lib +- ;; +- darwin* | rhapsody*) +- hardcode_direct=no +- if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then +- : +- else +- ld_shlibs=no +- fi +- ;; +- dgux*) +- hardcode_libdir_flag_spec='-L$libdir' +- ;; +- freebsd2.[01]*) +- hardcode_direct=yes +- hardcode_minus_L=yes +- ;; +- freebsd* | dragonfly*) +- hardcode_libdir_flag_spec='-R$libdir' +- hardcode_direct=yes +- ;; +- hpux9*) +- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' +- hardcode_libdir_separator=: +- hardcode_direct=yes +- # hardcode_minus_L: Not really in the search PATH, +- # but as the default location of the library. +- hardcode_minus_L=yes +- ;; +- hpux10*) +- if test "$with_gnu_ld" = no; then +- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' +- hardcode_libdir_separator=: +- hardcode_direct=yes +- # hardcode_minus_L: Not really in the search PATH, +- # but as the default location of the library. +- hardcode_minus_L=yes +- fi +- ;; +- hpux11*) +- if test "$with_gnu_ld" = no; then +- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' +- hardcode_libdir_separator=: +- case $host_cpu in +- hppa*64*|ia64*) +- hardcode_direct=no +- ;; +- *) +- hardcode_direct=yes +- # hardcode_minus_L: Not really in the search PATH, +- # but as the default location of the library. +- hardcode_minus_L=yes +- ;; +- esac +- fi +- ;; +- irix5* | irix6* | nonstopux*) +- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +- hardcode_libdir_separator=: +- ;; +- netbsd*) +- hardcode_libdir_flag_spec='-R$libdir' +- hardcode_direct=yes +- ;; +- newsos6) +- hardcode_direct=yes +- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +- hardcode_libdir_separator=: +- ;; +- *nto* | *qnx*) +- ;; +- openbsd*) +- if test -f /usr/libexec/ld.so; then +- hardcode_direct=yes +- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then +- hardcode_libdir_flag_spec='${wl}-rpath,$libdir' +- else +- case "$host_os" in +- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) +- hardcode_libdir_flag_spec='-R$libdir' +- ;; +- *) +- hardcode_libdir_flag_spec='${wl}-rpath,$libdir' +- ;; +- esac +- fi +- else +- ld_shlibs=no +- fi +- ;; +- os2*) +- hardcode_libdir_flag_spec='-L$libdir' +- hardcode_minus_L=yes +- ;; +- osf3*) +- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +- hardcode_libdir_separator=: +- ;; +- osf4* | osf5*) +- if test "$GCC" = yes; then +- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +- else +- # Both cc and cxx compiler support -rpath directly +- hardcode_libdir_flag_spec='-rpath $libdir' +- fi +- hardcode_libdir_separator=: +- ;; +- solaris*) +- hardcode_libdir_flag_spec='-R$libdir' +- ;; +- sunos4*) +- hardcode_libdir_flag_spec='-L$libdir' +- hardcode_direct=yes +- hardcode_minus_L=yes +- ;; +- sysv4) +- case $host_vendor in +- sni) +- hardcode_direct=yes # is this really true??? +- ;; +- siemens) +- hardcode_direct=no +- ;; +- motorola) +- hardcode_direct=no #Motorola manual says yes, but my tests say they lie +- ;; +- esac +- ;; +- sysv4.3*) +- ;; +- sysv4*MP*) +- if test -d /usr/nec; then +- ld_shlibs=yes +- fi +- ;; +- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) +- ;; +- sysv5* | sco3.2v5* | sco5v6*) +- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' +- hardcode_libdir_separator=':' +- ;; +- uts4*) +- hardcode_libdir_flag_spec='-L$libdir' +- ;; +- *) +- ld_shlibs=no +- ;; +- esac +-fi +- +-# Check dynamic linker characteristics +-# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +-# Unlike libtool.m4, here we don't care about _all_ names of the library, but +-# only about the one the linker finds when passed -lNAME. This is the last +-# element of library_names_spec in libtool.m4, or possibly two of them if the +-# linker has special search rules. +-library_names_spec= # the last element of library_names_spec in libtool.m4 +-libname_spec='lib$name' +-case "$host_os" in +- aix3*) +- library_names_spec='$libname.a' +- ;; +- aix[4-9]*) +- library_names_spec='$libname$shrext' +- ;; +- amigaos*) +- case "$host_cpu" in +- powerpc*) +- library_names_spec='$libname$shrext' ;; +- m68k) +- library_names_spec='$libname.a' ;; +- esac +- ;; +- beos*) +- library_names_spec='$libname$shrext' +- ;; +- bsdi[45]*) +- library_names_spec='$libname$shrext' +- ;; +- cygwin* | mingw* | pw32* | cegcc*) +- shrext=.dll +- library_names_spec='$libname.dll.a $libname.lib' +- ;; +- darwin* | rhapsody*) +- shrext=.dylib +- library_names_spec='$libname$shrext' +- ;; +- dgux*) +- library_names_spec='$libname$shrext' +- ;; +- freebsd[23].*) +- library_names_spec='$libname$shrext$versuffix' +- ;; +- freebsd* | dragonfly*) +- library_names_spec='$libname$shrext' +- ;; +- gnu*) +- library_names_spec='$libname$shrext' +- ;; +- haiku*) +- library_names_spec='$libname$shrext' +- ;; +- hpux9* | hpux10* | hpux11*) +- case $host_cpu in +- ia64*) +- shrext=.so +- ;; +- hppa*64*) +- shrext=.sl +- ;; +- *) +- shrext=.sl +- ;; +- esac +- library_names_spec='$libname$shrext' +- ;; +- interix[3-9]*) +- library_names_spec='$libname$shrext' +- ;; +- irix5* | irix6* | nonstopux*) +- library_names_spec='$libname$shrext' +- case "$host_os" in +- irix5* | nonstopux*) +- libsuff= shlibsuff= +- ;; +- *) +- case $LD in +- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; +- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; +- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; +- *) libsuff= shlibsuff= ;; +- esac +- ;; +- esac +- ;; +- linux*oldld* | linux*aout* | linux*coff*) +- ;; +- linux* | k*bsd*-gnu | kopensolaris*-gnu) +- library_names_spec='$libname$shrext' +- ;; +- knetbsd*-gnu) +- library_names_spec='$libname$shrext' +- ;; +- netbsd*) +- library_names_spec='$libname$shrext' +- ;; +- newsos6) +- library_names_spec='$libname$shrext' +- ;; +- *nto* | *qnx*) +- library_names_spec='$libname$shrext' +- ;; +- openbsd*) +- library_names_spec='$libname$shrext$versuffix' +- ;; +- os2*) +- libname_spec='$name' +- shrext=.dll +- library_names_spec='$libname.a' +- ;; +- osf3* | osf4* | osf5*) +- library_names_spec='$libname$shrext' +- ;; +- rdos*) +- ;; +- solaris*) +- library_names_spec='$libname$shrext' +- ;; +- sunos4*) +- library_names_spec='$libname$shrext$versuffix' +- ;; +- sysv4 | sysv4.3*) +- library_names_spec='$libname$shrext' +- ;; +- sysv4*MP*) +- library_names_spec='$libname$shrext' +- ;; +- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) +- library_names_spec='$libname$shrext' +- ;; +- tpf*) +- library_names_spec='$libname$shrext' +- ;; +- uts4*) +- library_names_spec='$libname$shrext' +- ;; +-esac +- +-sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +-escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +-shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +-escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +-escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +-escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +- +-LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. +-# +-# As a special exception to the GNU General Public License, if you +-# distribute this file as part of a program that contains a +-# configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that +-# program. This Exception is an additional permission under section 7 +-# of the GNU General Public License, version 3 ("GPLv3"). +- +- +-# Please send patches with a ChangeLog entry to config-patches@gnu.org. +-# +-# Configuration subroutine to validate and canonicalize a configuration type. +-# Supply the specified configuration type as an argument. +-# If it is invalid, we print an error message on stderr and exit with code 1. +-# Otherwise, we print the canonical config type on stdout and succeed. +- +-# You can get the latest version of this script from: +-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +- +-# This file is supposed to be the same for all GNU packages +-# and recognize all the CPU types, system types and aliases +-# that are meaningful with *any* GNU software. +-# Each package is responsible for reporting which valid configurations +-# it does not support. The user should be able to distinguish +-# a failure to support a valid configuration from a meaningless +-# configuration. +- +-# The goal of this file is to map all the various variations of a given +-# machine specification into a single specification in the form: +-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +-# or in some cases, the newer four-part form: +-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +-# It is wrong to echo any other type of specification. +- +-me=`echo "$0" | sed -e 's,.*/,,'` +- +-usage="\ +-Usage: $0 [OPTION] CPU-MFR-OPSYS +- $0 [OPTION] ALIAS +- +-Canonicalize a configuration name. +- +-Operation modes: +- -h, --help print this help, then exit +- -t, --time-stamp print date of last modification, then exit +- -v, --version print version number, then exit +- +-Report bugs and patches to ." +- +-version="\ +-GNU config.sub ($timestamp) +- +-Copyright 1992-2014 Free Software Foundation, Inc. +- +-This is free software; see the source for copying conditions. There is NO +-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +- +-help=" +-Try \`$me --help' for more information." +- +-# Parse command line +-while test $# -gt 0 ; do +- case $1 in +- --time-stamp | --time* | -t ) +- echo "$timestamp" ; exit ;; +- --version | -v ) +- echo "$version" ; exit ;; +- --help | --h* | -h ) +- echo "$usage"; exit ;; +- -- ) # Stop option processing +- shift; break ;; +- - ) # Use stdin as input. +- break ;; +- -* ) +- echo "$me: invalid option $1$help" +- exit 1 ;; +- +- *local*) +- # First pass through any local machine types. +- echo $1 +- exit ;; +- +- * ) +- break ;; +- esac +-done +- +-case $# in +- 0) echo "$me: missing argument$help" >&2 +- exit 1;; +- 1) ;; +- *) echo "$me: too many arguments$help" >&2 +- exit 1;; +-esac +- +-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +-# Here we must recognize all the valid KERNEL-OS combinations. +-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +-case $maybe_os in +- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ +- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ +- knetbsd*-gnu* | netbsd*-gnu* | \ +- kopensolaris*-gnu* | \ +- storm-chaos* | os2-emx* | rtmk-nova*) +- os=-$maybe_os +- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` +- ;; +- android-linux) +- os=-linux-android +- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown +- ;; +- *) +- basic_machine=`echo $1 | sed 's/-[^-]*$//'` +- if [ $basic_machine != $1 ] +- then os=`echo $1 | sed 's/.*-/-/'` +- else os=; fi +- ;; +-esac +- +-### Let's recognize common machines as not being operating systems so +-### that things like config.sub decstation-3100 work. We also +-### recognize some manufacturers as not being operating systems, so we +-### can provide default operating systems below. +-case $os in +- -sun*os*) +- # Prevent following clause from handling this invalid input. +- ;; +- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ +- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ +- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ +- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ +- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ +- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ +- -apple | -axis | -knuth | -cray | -microblaze*) +- os= +- basic_machine=$1 +- ;; +- -bluegene*) +- os=-cnk +- ;; +- -sim | -cisco | -oki | -wec | -winbond) +- os= +- basic_machine=$1 +- ;; +- -scout) +- ;; +- -wrs) +- os=-vxworks +- basic_machine=$1 +- ;; +- -chorusos*) +- os=-chorusos +- basic_machine=$1 +- ;; +- -chorusrdb) +- os=-chorusrdb +- basic_machine=$1 +- ;; +- -hiux*) +- os=-hiuxwe2 +- ;; +- -sco6) +- os=-sco5v6 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco5) +- os=-sco3.2v5 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco4) +- os=-sco3.2v4 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco3.2.[4-9]*) +- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco3.2v[4-9]*) +- # Don't forget version if it is 3.2v4 or newer. +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco5v6*) +- # Don't forget version if it is 3.2v4 or newer. +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco*) +- os=-sco3.2v2 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -udk*) +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -isc) +- os=-isc2.2 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -clix*) +- basic_machine=clipper-intergraph +- ;; +- -isc*) +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -lynx*178) +- os=-lynxos178 +- ;; +- -lynx*5) +- os=-lynxos5 +- ;; +- -lynx*) +- os=-lynxos +- ;; +- -ptx*) +- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` +- ;; +- -windowsnt*) +- os=`echo $os | sed -e 's/windowsnt/winnt/'` +- ;; +- -psos*) +- os=-psos +- ;; +- -mint | -mint[0-9]*) +- basic_machine=m68k-atari +- os=-mint +- ;; +-esac +- +-# Decode aliases for certain CPU-COMPANY combinations. +-case $basic_machine in +- # Recognize the basic CPU types without company name. +- # Some are omitted here because they have special meanings below. +- 1750a | 580 \ +- | a29k \ +- | aarch64 | aarch64_be \ +- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ +- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ +- | am33_2.0 \ +- | arc | arceb \ +- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ +- | avr | avr32 \ +- | be32 | be64 \ +- | bfin \ +- | c4x | c8051 | clipper \ +- | d10v | d30v | dlx | dsp16xx \ +- | epiphany \ +- | fido | fr30 | frv \ +- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ +- | hexagon \ +- | i370 | i860 | i960 | ia64 \ +- | ip2k | iq2000 \ +- | k1om \ +- | le32 | le64 \ +- | lm32 \ +- | m32c | m32r | m32rle | m68000 | m68k | m88k \ +- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ +- | mips | mipsbe | mipseb | mipsel | mipsle \ +- | mips16 \ +- | mips64 | mips64el \ +- | mips64octeon | mips64octeonel \ +- | mips64orion | mips64orionel \ +- | mips64r5900 | mips64r5900el \ +- | mips64vr | mips64vrel \ +- | mips64vr4100 | mips64vr4100el \ +- | mips64vr4300 | mips64vr4300el \ +- | mips64vr5000 | mips64vr5000el \ +- | mips64vr5900 | mips64vr5900el \ +- | mipsisa32 | mipsisa32el \ +- | mipsisa32r2 | mipsisa32r2el \ +- | mipsisa32r6 | mipsisa32r6el \ +- | mipsisa64 | mipsisa64el \ +- | mipsisa64r2 | mipsisa64r2el \ +- | mipsisa64r6 | mipsisa64r6el \ +- | mipsisa64sb1 | mipsisa64sb1el \ +- | mipsisa64sr71k | mipsisa64sr71kel \ +- | mipsr5900 | mipsr5900el \ +- | mipstx39 | mipstx39el \ +- | mn10200 | mn10300 \ +- | moxie \ +- | mt \ +- | msp430 \ +- | nds32 | nds32le | nds32be \ +- | nios | nios2 | nios2eb | nios2el \ +- | ns16k | ns32k \ +- | open8 | or1k | or1knd | or32 \ +- | pdp10 | pdp11 | pj | pjl \ +- | powerpc | powerpc64 | powerpc64le | powerpcle \ +- | pyramid \ +- | riscv32 | riscv64 \ +- | rl78 | rx \ +- | score \ +- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ +- | sh64 | sh64le \ +- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ +- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ +- | spu \ +- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ +- | ubicom32 \ +- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ +- | we32k \ +- | x86 | xc16x | xstormy16 | xtensa \ +- | z8k | z80) +- basic_machine=$basic_machine-unknown +- ;; +- c54x) +- basic_machine=tic54x-unknown +- ;; +- c55x) +- basic_machine=tic55x-unknown +- ;; +- c6x) +- basic_machine=tic6x-unknown +- ;; +- leon|leon[3-9]) +- basic_machine=sparc-$basic_machine +- ;; +- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) +- basic_machine=$basic_machine-unknown +- os=-none +- ;; +- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) +- ;; +- ms1) +- basic_machine=mt-unknown +- ;; +- +- strongarm | thumb | xscale) +- basic_machine=arm-unknown +- ;; +- xgate) +- basic_machine=$basic_machine-unknown +- os=-none +- ;; +- xscaleeb) +- basic_machine=armeb-unknown +- ;; +- +- xscaleel) +- basic_machine=armel-unknown +- ;; +- +- # We use `pc' rather than `unknown' +- # because (1) that's what they normally are, and +- # (2) the word "unknown" tends to confuse beginning users. +- i*86 | x86_64) +- basic_machine=$basic_machine-pc +- ;; +- # Object if more than one company name word. +- *-*-*) +- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 +- exit 1 +- ;; +- # Recognize the basic CPU types with company name. +- 580-* \ +- | a29k-* \ +- | aarch64-* | aarch64_be-* \ +- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ +- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ +- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ +- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ +- | avr-* | avr32-* \ +- | be32-* | be64-* \ +- | bfin-* | bs2000-* \ +- | c[123]* | c30-* | [cjt]90-* | c4x-* \ +- | c8051-* | clipper-* | craynv-* | cydra-* \ +- | d10v-* | d30v-* | dlx-* \ +- | elxsi-* \ +- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ +- | h8300-* | h8500-* \ +- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ +- | hexagon-* \ +- | i*86-* | i860-* | i960-* | ia64-* \ +- | ip2k-* | iq2000-* \ +- | k1om-* \ +- | le32-* | le64-* \ +- | lm32-* \ +- | m32c-* | m32r-* | m32rle-* \ +- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ +- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ +- | microblaze-* | microblazeel-* \ +- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ +- | mips16-* \ +- | mips64-* | mips64el-* \ +- | mips64octeon-* | mips64octeonel-* \ +- | mips64orion-* | mips64orionel-* \ +- | mips64r5900-* | mips64r5900el-* \ +- | mips64vr-* | mips64vrel-* \ +- | mips64vr4100-* | mips64vr4100el-* \ +- | mips64vr4300-* | mips64vr4300el-* \ +- | mips64vr5000-* | mips64vr5000el-* \ +- | mips64vr5900-* | mips64vr5900el-* \ +- | mipsisa32-* | mipsisa32el-* \ +- | mipsisa32r2-* | mipsisa32r2el-* \ +- | mipsisa32r6-* | mipsisa32r6el-* \ +- | mipsisa64-* | mipsisa64el-* \ +- | mipsisa64r2-* | mipsisa64r2el-* \ +- | mipsisa64r6-* | mipsisa64r6el-* \ +- | mipsisa64sb1-* | mipsisa64sb1el-* \ +- | mipsisa64sr71k-* | mipsisa64sr71kel-* \ +- | mipsr5900-* | mipsr5900el-* \ +- | mipstx39-* | mipstx39el-* \ +- | mmix-* \ +- | mt-* \ +- | msp430-* \ +- | nds32-* | nds32le-* | nds32be-* \ +- | nios-* | nios2-* | nios2eb-* | nios2el-* \ +- | none-* | np1-* | ns16k-* | ns32k-* \ +- | open8-* \ +- | or1k*-* \ +- | orion-* \ +- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ +- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ +- | pyramid-* \ +- | rl78-* | romp-* | rs6000-* | rx-* \ +- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ +- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ +- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ +- | sparclite-* \ +- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ +- | tahoe-* \ +- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ +- | tile*-* \ +- | tron-* \ +- | ubicom32-* \ +- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ +- | vax-* \ +- | we32k-* \ +- | x86-* | x86_64-* | xc16x-* | xps100-* \ +- | xstormy16-* | xtensa*-* \ +- | ymp-* \ +- | z8k-* | z80-*) +- ;; +- # Recognize the basic CPU types without company name, with glob match. +- xtensa*) +- basic_machine=$basic_machine-unknown +- ;; +- # Recognize the various machine names and aliases which stand +- # for a CPU type and a company and sometimes even an OS. +- 386bsd) +- basic_machine=i386-unknown +- os=-bsd +- ;; +- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) +- basic_machine=m68000-att +- ;; +- 3b*) +- basic_machine=we32k-att +- ;; +- a29khif) +- basic_machine=a29k-amd +- os=-udi +- ;; +- abacus) +- basic_machine=abacus-unknown +- ;; +- adobe68k) +- basic_machine=m68010-adobe +- os=-scout +- ;; +- alliant | fx80) +- basic_machine=fx80-alliant +- ;; +- altos | altos3068) +- basic_machine=m68k-altos +- ;; +- am29k) +- basic_machine=a29k-none +- os=-bsd +- ;; +- amd64) +- basic_machine=x86_64-pc +- ;; +- amd64-*) +- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- amdahl) +- basic_machine=580-amdahl +- os=-sysv +- ;; +- amiga | amiga-*) +- basic_machine=m68k-unknown +- ;; +- amigaos | amigados) +- basic_machine=m68k-unknown +- os=-amigaos +- ;; +- amigaunix | amix) +- basic_machine=m68k-unknown +- os=-sysv4 +- ;; +- apollo68) +- basic_machine=m68k-apollo +- os=-sysv +- ;; +- apollo68bsd) +- basic_machine=m68k-apollo +- os=-bsd +- ;; +- aros) +- basic_machine=i386-pc +- os=-aros +- ;; +- aux) +- basic_machine=m68k-apple +- os=-aux +- ;; +- balance) +- basic_machine=ns32k-sequent +- os=-dynix +- ;; +- blackfin) +- basic_machine=bfin-unknown +- os=-linux +- ;; +- blackfin-*) +- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` +- os=-linux +- ;; +- bluegene*) +- basic_machine=powerpc-ibm +- os=-cnk +- ;; +- c54x-*) +- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- c55x-*) +- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- c6x-*) +- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- c90) +- basic_machine=c90-cray +- os=-unicos +- ;; +- cegcc) +- basic_machine=arm-unknown +- os=-cegcc +- ;; +- convex-c1) +- basic_machine=c1-convex +- os=-bsd +- ;; +- convex-c2) +- basic_machine=c2-convex +- os=-bsd +- ;; +- convex-c32) +- basic_machine=c32-convex +- os=-bsd +- ;; +- convex-c34) +- basic_machine=c34-convex +- os=-bsd +- ;; +- convex-c38) +- basic_machine=c38-convex +- os=-bsd +- ;; +- cray | j90) +- basic_machine=j90-cray +- os=-unicos +- ;; +- craynv) +- basic_machine=craynv-cray +- os=-unicosmp +- ;; +- cr16 | cr16-*) +- basic_machine=cr16-unknown +- os=-elf +- ;; +- crds | unos) +- basic_machine=m68k-crds +- ;; +- crisv32 | crisv32-* | etraxfs*) +- basic_machine=crisv32-axis +- ;; +- cris | cris-* | etrax*) +- basic_machine=cris-axis +- ;; +- crx) +- basic_machine=crx-unknown +- os=-elf +- ;; +- da30 | da30-*) +- basic_machine=m68k-da30 +- ;; +- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) +- basic_machine=mips-dec +- ;; +- decsystem10* | dec10*) +- basic_machine=pdp10-dec +- os=-tops10 +- ;; +- decsystem20* | dec20*) +- basic_machine=pdp10-dec +- os=-tops20 +- ;; +- delta | 3300 | motorola-3300 | motorola-delta \ +- | 3300-motorola | delta-motorola) +- basic_machine=m68k-motorola +- ;; +- delta88) +- basic_machine=m88k-motorola +- os=-sysv3 +- ;; +- dicos) +- basic_machine=i686-pc +- os=-dicos +- ;; +- djgpp) +- basic_machine=i586-pc +- os=-msdosdjgpp +- ;; +- dpx20 | dpx20-*) +- basic_machine=rs6000-bull +- os=-bosx +- ;; +- dpx2* | dpx2*-bull) +- basic_machine=m68k-bull +- os=-sysv3 +- ;; +- ebmon29k) +- basic_machine=a29k-amd +- os=-ebmon +- ;; +- elxsi) +- basic_machine=elxsi-elxsi +- os=-bsd +- ;; +- encore | umax | mmax) +- basic_machine=ns32k-encore +- ;; +- es1800 | OSE68k | ose68k | ose | OSE) +- basic_machine=m68k-ericsson +- os=-ose +- ;; +- fx2800) +- basic_machine=i860-alliant +- ;; +- genix) +- basic_machine=ns32k-ns +- ;; +- gmicro) +- basic_machine=tron-gmicro +- os=-sysv +- ;; +- go32) +- basic_machine=i386-pc +- os=-go32 +- ;; +- h3050r* | hiux*) +- basic_machine=hppa1.1-hitachi +- os=-hiuxwe2 +- ;; +- h8300hms) +- basic_machine=h8300-hitachi +- os=-hms +- ;; +- h8300xray) +- basic_machine=h8300-hitachi +- os=-xray +- ;; +- h8500hms) +- basic_machine=h8500-hitachi +- os=-hms +- ;; +- harris) +- basic_machine=m88k-harris +- os=-sysv3 +- ;; +- hp300-*) +- basic_machine=m68k-hp +- ;; +- hp300bsd) +- basic_machine=m68k-hp +- os=-bsd +- ;; +- hp300hpux) +- basic_machine=m68k-hp +- os=-hpux +- ;; +- hp3k9[0-9][0-9] | hp9[0-9][0-9]) +- basic_machine=hppa1.0-hp +- ;; +- hp9k2[0-9][0-9] | hp9k31[0-9]) +- basic_machine=m68000-hp +- ;; +- hp9k3[2-9][0-9]) +- basic_machine=m68k-hp +- ;; +- hp9k6[0-9][0-9] | hp6[0-9][0-9]) +- basic_machine=hppa1.0-hp +- ;; +- hp9k7[0-79][0-9] | hp7[0-79][0-9]) +- basic_machine=hppa1.1-hp +- ;; +- hp9k78[0-9] | hp78[0-9]) +- # FIXME: really hppa2.0-hp +- basic_machine=hppa1.1-hp +- ;; +- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) +- # FIXME: really hppa2.0-hp +- basic_machine=hppa1.1-hp +- ;; +- hp9k8[0-9][13679] | hp8[0-9][13679]) +- basic_machine=hppa1.1-hp +- ;; +- hp9k8[0-9][0-9] | hp8[0-9][0-9]) +- basic_machine=hppa1.0-hp +- ;; +- hppa-next) +- os=-nextstep3 +- ;; +- hppaosf) +- basic_machine=hppa1.1-hp +- os=-osf +- ;; +- hppro) +- basic_machine=hppa1.1-hp +- os=-proelf +- ;; +- i370-ibm* | ibm*) +- basic_machine=i370-ibm +- ;; +- i*86v32) +- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` +- os=-sysv32 +- ;; +- i*86v4*) +- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` +- os=-sysv4 +- ;; +- i*86v) +- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` +- os=-sysv +- ;; +- i*86sol2) +- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` +- os=-solaris2 +- ;; +- i386mach) +- basic_machine=i386-mach +- os=-mach +- ;; +- i386-vsta | vsta) +- basic_machine=i386-unknown +- os=-vsta +- ;; +- iris | iris4d) +- basic_machine=mips-sgi +- case $os in +- -irix*) +- ;; +- *) +- os=-irix4 +- ;; +- esac +- ;; +- isi68 | isi) +- basic_machine=m68k-isi +- os=-sysv +- ;; +- leon-*|leon[3-9]-*) +- basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` +- ;; +- m68knommu) +- basic_machine=m68k-unknown +- os=-linux +- ;; +- m68knommu-*) +- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` +- os=-linux +- ;; +- m88k-omron*) +- basic_machine=m88k-omron +- ;; +- magnum | m3230) +- basic_machine=mips-mips +- os=-sysv +- ;; +- merlin) +- basic_machine=ns32k-utek +- os=-sysv +- ;; +- microblaze*) +- basic_machine=microblaze-xilinx +- ;; +- mingw64) +- basic_machine=x86_64-pc +- os=-mingw64 +- ;; +- mingw32) +- basic_machine=i686-pc +- os=-mingw32 +- ;; +- mingw32ce) +- basic_machine=arm-unknown +- os=-mingw32ce +- ;; +- miniframe) +- basic_machine=m68000-convergent +- ;; +- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) +- basic_machine=m68k-atari +- os=-mint +- ;; +- mips3*-*) +- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` +- ;; +- mips3*) +- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown +- ;; +- monitor) +- basic_machine=m68k-rom68k +- os=-coff +- ;; +- morphos) +- basic_machine=powerpc-unknown +- os=-morphos +- ;; +- moxiebox) +- basic_machine=moxie-unknown +- os=-moxiebox +- ;; +- msdos) +- basic_machine=i386-pc +- os=-msdos +- ;; +- ms1-*) +- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` +- ;; +- msys) +- basic_machine=i686-pc +- os=-msys +- ;; +- mvs) +- basic_machine=i370-ibm +- os=-mvs +- ;; +- nacl) +- basic_machine=le32-unknown +- os=-nacl +- ;; +- ncr3000) +- basic_machine=i486-ncr +- os=-sysv4 +- ;; +- netbsd386) +- basic_machine=i386-unknown +- os=-netbsd +- ;; +- netwinder) +- basic_machine=armv4l-rebel +- os=-linux +- ;; +- news | news700 | news800 | news900) +- basic_machine=m68k-sony +- os=-newsos +- ;; +- news1000) +- basic_machine=m68030-sony +- os=-newsos +- ;; +- news-3600 | risc-news) +- basic_machine=mips-sony +- os=-newsos +- ;; +- necv70) +- basic_machine=v70-nec +- os=-sysv +- ;; +- next | m*-next ) +- basic_machine=m68k-next +- case $os in +- -nextstep* ) +- ;; +- -ns2*) +- os=-nextstep2 +- ;; +- *) +- os=-nextstep3 +- ;; +- esac +- ;; +- nh3000) +- basic_machine=m68k-harris +- os=-cxux +- ;; +- nh[45]000) +- basic_machine=m88k-harris +- os=-cxux +- ;; +- nindy960) +- basic_machine=i960-intel +- os=-nindy +- ;; +- mon960) +- basic_machine=i960-intel +- os=-mon960 +- ;; +- nonstopux) +- basic_machine=mips-compaq +- os=-nonstopux +- ;; +- np1) +- basic_machine=np1-gould +- ;; +- neo-tandem) +- basic_machine=neo-tandem +- ;; +- nse-tandem) +- basic_machine=nse-tandem +- ;; +- nsr-tandem) +- basic_machine=nsr-tandem +- ;; +- op50n-* | op60c-*) +- basic_machine=hppa1.1-oki +- os=-proelf +- ;; +- openrisc | openrisc-*) +- basic_machine=or32-unknown +- ;; +- os400) +- basic_machine=powerpc-ibm +- os=-os400 +- ;; +- OSE68000 | ose68000) +- basic_machine=m68000-ericsson +- os=-ose +- ;; +- os68k) +- basic_machine=m68k-none +- os=-os68k +- ;; +- pa-hitachi) +- basic_machine=hppa1.1-hitachi +- os=-hiuxwe2 +- ;; +- paragon) +- basic_machine=i860-intel +- os=-osf +- ;; +- parisc) +- basic_machine=hppa-unknown +- os=-linux +- ;; +- parisc-*) +- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` +- os=-linux +- ;; +- pbd) +- basic_machine=sparc-tti +- ;; +- pbb) +- basic_machine=m68k-tti +- ;; +- pc532 | pc532-*) +- basic_machine=ns32k-pc532 +- ;; +- pc98) +- basic_machine=i386-pc +- ;; +- pc98-*) +- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pentium | p5 | k5 | k6 | nexgen | viac3) +- basic_machine=i586-pc +- ;; +- pentiumpro | p6 | 6x86 | athlon | athlon_*) +- basic_machine=i686-pc +- ;; +- pentiumii | pentium2 | pentiumiii | pentium3) +- basic_machine=i686-pc +- ;; +- pentium4) +- basic_machine=i786-pc +- ;; +- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) +- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pentiumpro-* | p6-* | 6x86-* | athlon-*) +- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) +- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pentium4-*) +- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pn) +- basic_machine=pn-gould +- ;; +- power) basic_machine=power-ibm +- ;; +- ppc | ppcbe) basic_machine=powerpc-unknown +- ;; +- ppc-* | ppcbe-*) +- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- ppcle | powerpclittle | ppc-le | powerpc-little) +- basic_machine=powerpcle-unknown +- ;; +- ppcle-* | powerpclittle-*) +- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- ppc64) basic_machine=powerpc64-unknown +- ;; +- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- ppc64le | powerpc64little | ppc64-le | powerpc64-little) +- basic_machine=powerpc64le-unknown +- ;; +- ppc64le-* | powerpc64little-*) +- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- ps2) +- basic_machine=i386-ibm +- ;; +- pw32) +- basic_machine=i586-unknown +- os=-pw32 +- ;; +- rdos | rdos64) +- basic_machine=x86_64-pc +- os=-rdos +- ;; +- rdos32) +- basic_machine=i386-pc +- os=-rdos +- ;; +- rom68k) +- basic_machine=m68k-rom68k +- os=-coff +- ;; +- rm[46]00) +- basic_machine=mips-siemens +- ;; +- rtpc | rtpc-*) +- basic_machine=romp-ibm +- ;; +- s390 | s390-*) +- basic_machine=s390-ibm +- ;; +- s390x | s390x-*) +- basic_machine=s390x-ibm +- ;; +- sa29200) +- basic_machine=a29k-amd +- os=-udi +- ;; +- sb1) +- basic_machine=mipsisa64sb1-unknown +- ;; +- sb1el) +- basic_machine=mipsisa64sb1el-unknown +- ;; +- sde) +- basic_machine=mipsisa32-sde +- os=-elf +- ;; +- sei) +- basic_machine=mips-sei +- os=-seiux +- ;; +- sequent) +- basic_machine=i386-sequent +- ;; +- sh) +- basic_machine=sh-hitachi +- os=-hms +- ;; +- sh5el) +- basic_machine=sh5le-unknown +- ;; +- sh64) +- basic_machine=sh64-unknown +- ;; +- sparclite-wrs | simso-wrs) +- basic_machine=sparclite-wrs +- os=-vxworks +- ;; +- sps7) +- basic_machine=m68k-bull +- os=-sysv2 +- ;; +- spur) +- basic_machine=spur-unknown +- ;; +- st2000) +- basic_machine=m68k-tandem +- ;; +- stratus) +- basic_machine=i860-stratus +- os=-sysv4 +- ;; +- strongarm-* | thumb-*) +- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- sun2) +- basic_machine=m68000-sun +- ;; +- sun2os3) +- basic_machine=m68000-sun +- os=-sunos3 +- ;; +- sun2os4) +- basic_machine=m68000-sun +- os=-sunos4 +- ;; +- sun3os3) +- basic_machine=m68k-sun +- os=-sunos3 +- ;; +- sun3os4) +- basic_machine=m68k-sun +- os=-sunos4 +- ;; +- sun4os3) +- basic_machine=sparc-sun +- os=-sunos3 +- ;; +- sun4os4) +- basic_machine=sparc-sun +- os=-sunos4 +- ;; +- sun4sol2) +- basic_machine=sparc-sun +- os=-solaris2 +- ;; +- sun3 | sun3-*) +- basic_machine=m68k-sun +- ;; +- sun4) +- basic_machine=sparc-sun +- ;; +- sun386 | sun386i | roadrunner) +- basic_machine=i386-sun +- ;; +- sv1) +- basic_machine=sv1-cray +- os=-unicos +- ;; +- symmetry) +- basic_machine=i386-sequent +- os=-dynix +- ;; +- t3e) +- basic_machine=alphaev5-cray +- os=-unicos +- ;; +- t90) +- basic_machine=t90-cray +- os=-unicos +- ;; +- tile*) +- basic_machine=$basic_machine-unknown +- os=-linux-gnu +- ;; +- tx39) +- basic_machine=mipstx39-unknown +- ;; +- tx39el) +- basic_machine=mipstx39el-unknown +- ;; +- toad1) +- basic_machine=pdp10-xkl +- os=-tops20 +- ;; +- tower | tower-32) +- basic_machine=m68k-ncr +- ;; +- tpf) +- basic_machine=s390x-ibm +- os=-tpf +- ;; +- udi29k) +- basic_machine=a29k-amd +- os=-udi +- ;; +- ultra3) +- basic_machine=a29k-nyu +- os=-sym1 +- ;; +- v810 | necv810) +- basic_machine=v810-nec +- os=-none +- ;; +- vaxv) +- basic_machine=vax-dec +- os=-sysv +- ;; +- vms) +- basic_machine=vax-dec +- os=-vms +- ;; +- vpp*|vx|vx-*) +- basic_machine=f301-fujitsu +- ;; +- vxworks960) +- basic_machine=i960-wrs +- os=-vxworks +- ;; +- vxworks68) +- basic_machine=m68k-wrs +- os=-vxworks +- ;; +- vxworks29k) +- basic_machine=a29k-wrs +- os=-vxworks +- ;; +- w65*) +- basic_machine=w65-wdc +- os=-none +- ;; +- w89k-*) +- basic_machine=hppa1.1-winbond +- os=-proelf +- ;; +- xbox) +- basic_machine=i686-pc +- os=-mingw32 +- ;; +- xps | xps100) +- basic_machine=xps100-honeywell +- ;; +- xscale-* | xscalee[bl]-*) +- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` +- ;; +- ymp) +- basic_machine=ymp-cray +- os=-unicos +- ;; +- z8k-*-coff) +- basic_machine=z8k-unknown +- os=-sim +- ;; +- z80-*-coff) +- basic_machine=z80-unknown +- os=-sim +- ;; +- none) +- basic_machine=none-none +- os=-none +- ;; +- +-# Here we handle the default manufacturer of certain CPU types. It is in +-# some cases the only manufacturer, in others, it is the most popular. +- w89k) +- basic_machine=hppa1.1-winbond +- ;; +- op50n) +- basic_machine=hppa1.1-oki +- ;; +- op60c) +- basic_machine=hppa1.1-oki +- ;; +- romp) +- basic_machine=romp-ibm +- ;; +- mmix) +- basic_machine=mmix-knuth +- ;; +- rs6000) +- basic_machine=rs6000-ibm +- ;; +- vax) +- basic_machine=vax-dec +- ;; +- pdp10) +- # there are many clones, so DEC is not a safe bet +- basic_machine=pdp10-unknown +- ;; +- pdp11) +- basic_machine=pdp11-dec +- ;; +- we32k) +- basic_machine=we32k-att +- ;; +- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) +- basic_machine=sh-unknown +- ;; +- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) +- basic_machine=sparc-sun +- ;; +- cydra) +- basic_machine=cydra-cydrome +- ;; +- orion) +- basic_machine=orion-highlevel +- ;; +- orion105) +- basic_machine=clipper-highlevel +- ;; +- mac | mpw | mac-mpw) +- basic_machine=m68k-apple +- ;; +- pmac | pmac-mpw) +- basic_machine=powerpc-apple +- ;; +- *-unknown) +- # Make sure to match an already-canonicalized machine name. +- ;; +- *) +- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 +- exit 1 +- ;; +-esac +- +-# Here we canonicalize certain aliases for manufacturers. +-case $basic_machine in +- *-digital*) +- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +- ;; +- *-commodore*) +- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` +- ;; +- *) +- ;; +-esac +- +-# Decode manufacturer-specific aliases for certain operating systems. +- +-if [ x"$os" != x"" ] +-then +-case $os in +- # First match some system type aliases +- # that might get confused with valid system types. +- # -solaris* is a basic system type, with this one exception. +- -auroraux) +- os=-auroraux +- ;; +- -solaris1 | -solaris1.*) +- os=`echo $os | sed -e 's|solaris1|sunos4|'` +- ;; +- -solaris) +- os=-solaris2 +- ;; +- -svr4*) +- os=-sysv4 +- ;; +- -unixware*) +- os=-sysv4.2uw +- ;; +- -gnu/linux*) +- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` +- ;; +- # First accept the basic system types. +- # The portable systems comes first. +- # Each alternative MUST END IN A *, to match a version number. +- # -sysv* is not here because it comes later, after sysvr4. +- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ +- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ +- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ +- | -sym* | -kopensolaris* | -plan9* \ +- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ +- | -aos* | -aros* \ +- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ +- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ +- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ +- | -bitrig* | -openbsd* | -solidbsd* \ +- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ +- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ +- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ +- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ +- | -chorusos* | -chorusrdb* | -cegcc* \ +- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ +- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ +- | -linux-newlib* | -linux-musl* | -linux-uclibc* \ +- | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ +- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ +- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ +- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ +- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ +- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ +- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ +- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) +- # Remember, each alternative MUST END IN *, to match a version number. +- ;; +- -qnx*) +- case $basic_machine in +- x86-* | i*86-*) +- ;; +- *) +- os=-nto$os +- ;; +- esac +- ;; +- -nto-qnx*) +- ;; +- -nto*) +- os=`echo $os | sed -e 's|nto|nto-qnx|'` +- ;; +- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ +- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ +- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) +- ;; +- -mac*) +- os=`echo $os | sed -e 's|mac|macos|'` +- ;; +- -linux-dietlibc) +- os=-linux-dietlibc +- ;; +- -linux*) +- os=`echo $os | sed -e 's|linux|linux-gnu|'` +- ;; +- -sunos5*) +- os=`echo $os | sed -e 's|sunos5|solaris2|'` +- ;; +- -sunos6*) +- os=`echo $os | sed -e 's|sunos6|solaris3|'` +- ;; +- -opened*) +- os=-openedition +- ;; +- -os400*) +- os=-os400 +- ;; +- -wince*) +- os=-wince +- ;; +- -osfrose*) +- os=-osfrose +- ;; +- -osf*) +- os=-osf +- ;; +- -utek*) +- os=-bsd +- ;; +- -dynix*) +- os=-bsd +- ;; +- -acis*) +- os=-aos +- ;; +- -atheos*) +- os=-atheos +- ;; +- -syllable*) +- os=-syllable +- ;; +- -386bsd) +- os=-bsd +- ;; +- -ctix* | -uts*) +- os=-sysv +- ;; +- -nova*) +- os=-rtmk-nova +- ;; +- -ns2 ) +- os=-nextstep2 +- ;; +- -nsk*) +- os=-nsk +- ;; +- # Preserve the version number of sinix5. +- -sinix5.*) +- os=`echo $os | sed -e 's|sinix|sysv|'` +- ;; +- -sinix*) +- os=-sysv4 +- ;; +- -tpf*) +- os=-tpf +- ;; +- -triton*) +- os=-sysv3 +- ;; +- -oss*) +- os=-sysv3 +- ;; +- -svr4) +- os=-sysv4 +- ;; +- -svr3) +- os=-sysv3 +- ;; +- -sysvr4) +- os=-sysv4 +- ;; +- # This must come after -sysvr4. +- -sysv*) +- ;; +- -ose*) +- os=-ose +- ;; +- -es1800*) +- os=-ose +- ;; +- -xenix) +- os=-xenix +- ;; +- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) +- os=-mint +- ;; +- -aros*) +- os=-aros +- ;; +- -zvmoe) +- os=-zvmoe +- ;; +- -dicos*) +- os=-dicos +- ;; +- -nacl*) +- ;; +- -none) +- ;; +- *) +- # Get rid of the `-' at the beginning of $os. +- os=`echo $os | sed 's/[^-]*-//'` +- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 +- exit 1 +- ;; +-esac +-else +- +-# Here we handle the default operating systems that come with various machines. +-# The value should be what the vendor currently ships out the door with their +-# machine or put another way, the most popular os provided with the machine. +- +-# Note that if you're going to try to match "-MANUFACTURER" here (say, +-# "-sun"), then you have to tell the case statement up towards the top +-# that MANUFACTURER isn't an operating system. Otherwise, code above +-# will signal an error saying that MANUFACTURER isn't an operating +-# system, and we'll never get to this point. +- +-case $basic_machine in +- score-*) +- os=-elf +- ;; +- spu-*) +- os=-elf +- ;; +- *-acorn) +- os=-riscix1.2 +- ;; +- arm*-rebel) +- os=-linux +- ;; +- arm*-semi) +- os=-aout +- ;; +- c4x-* | tic4x-*) +- os=-coff +- ;; +- c8051-*) +- os=-elf +- ;; +- hexagon-*) +- os=-elf +- ;; +- tic54x-*) +- os=-coff +- ;; +- tic55x-*) +- os=-coff +- ;; +- tic6x-*) +- os=-coff +- ;; +- # This must come before the *-dec entry. +- pdp10-*) +- os=-tops20 +- ;; +- pdp11-*) +- os=-none +- ;; +- *-dec | vax-*) +- os=-ultrix4.2 +- ;; +- m68*-apollo) +- os=-domain +- ;; +- i386-sun) +- os=-sunos4.0.2 +- ;; +- m68000-sun) +- os=-sunos3 +- ;; +- m68*-cisco) +- os=-aout +- ;; +- mep-*) +- os=-elf +- ;; +- mips*-cisco) +- os=-elf +- ;; +- mips*-*) +- os=-elf +- ;; +- or32-*) +- os=-coff +- ;; +- *-tti) # must be before sparc entry or we get the wrong os. +- os=-sysv3 +- ;; +- sparc-* | *-sun) +- os=-sunos4.1.1 +- ;; +- *-be) +- os=-beos +- ;; +- *-haiku) +- os=-haiku +- ;; +- *-ibm) +- os=-aix +- ;; +- *-knuth) +- os=-mmixware +- ;; +- *-wec) +- os=-proelf +- ;; +- *-winbond) +- os=-proelf +- ;; +- *-oki) +- os=-proelf +- ;; +- *-hp) +- os=-hpux +- ;; +- *-hitachi) +- os=-hiux +- ;; +- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) +- os=-sysv +- ;; +- *-cbm) +- os=-amigaos +- ;; +- *-dg) +- os=-dgux +- ;; +- *-dolphin) +- os=-sysv3 +- ;; +- m68k-ccur) +- os=-rtu +- ;; +- m88k-omron*) +- os=-luna +- ;; +- *-next ) +- os=-nextstep +- ;; +- *-sequent) +- os=-ptx +- ;; +- *-crds) +- os=-unos +- ;; +- *-ns) +- os=-genix +- ;; +- i370-*) +- os=-mvs +- ;; +- *-next) +- os=-nextstep3 +- ;; +- *-gould) +- os=-sysv +- ;; +- *-highlevel) +- os=-bsd +- ;; +- *-encore) +- os=-bsd +- ;; +- *-sgi) +- os=-irix +- ;; +- *-siemens) +- os=-sysv4 +- ;; +- *-masscomp) +- os=-rtu +- ;; +- f30[01]-fujitsu | f700-fujitsu) +- os=-uxpv +- ;; +- *-rom68k) +- os=-coff +- ;; +- *-*bug) +- os=-coff +- ;; +- *-apple) +- os=-macos +- ;; +- *-atari*) +- os=-mint +- ;; +- *) +- os=-none +- ;; +-esac +-fi +- +-# Here we handle the case where we know the os, and the CPU type, but not the +-# manufacturer. We pick the logical manufacturer. +-vendor=unknown +-case $basic_machine in +- *-unknown) +- case $os in +- -riscix*) +- vendor=acorn +- ;; +- -sunos*) +- vendor=sun +- ;; +- -cnk*|-aix*) +- vendor=ibm +- ;; +- -beos*) +- vendor=be +- ;; +- -hpux*) +- vendor=hp +- ;; +- -mpeix*) +- vendor=hp +- ;; +- -hiux*) +- vendor=hitachi +- ;; +- -unos*) +- vendor=crds +- ;; +- -dgux*) +- vendor=dg +- ;; +- -luna*) +- vendor=omron +- ;; +- -genix*) +- vendor=ns +- ;; +- -mvs* | -opened*) +- vendor=ibm +- ;; +- -os400*) +- vendor=ibm +- ;; +- -ptx*) +- vendor=sequent +- ;; +- -tpf*) +- vendor=ibm +- ;; +- -vxsim* | -vxworks* | -windiss*) +- vendor=wrs +- ;; +- -aux*) +- vendor=apple +- ;; +- -hms*) +- vendor=hitachi +- ;; +- -mpw* | -macos*) +- vendor=apple +- ;; +- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) +- vendor=atari +- ;; +- -vos*) +- vendor=stratus +- ;; +- esac +- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` +- ;; +-esac +- +-echo $basic_machine$os +-exit +- +-# Local variables: +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "timestamp='" +-# time-stamp-format: "%:y-%02m-%02d" +-# time-stamp-end: "'" +-# End: +diff -Nuar groff-1.22.3.old/configure groff-1.22.3/configure +--- groff-1.22.3.old/configure 2014-11-04 10:39:11.525070190 +0200 ++++ groff-1.22.3/configure 1970-01-01 02:00:00.000000000 +0200 +@@ -1,12366 +0,0 @@ +-#! /bin/sh +-# Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.69 for groff 1.22.3. +-# +-# Report bugs to . +-# +-# +-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +-# +-# +-# This configure script is free software; the Free Software Foundation +-# gives unlimited permission to copy, distribute and modify it. +-## -------------------- ## +-## M4sh Initialization. ## +-## -------------------- ## +- +-# Be more Bourne compatible +-DUALCASE=1; export DUALCASE # for MKS sh +-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +- emulate sh +- NULLCMD=: +- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which +- # is contrary to our usage. Disable this feature. +- alias -g '${1+"$@"}'='"$@"' +- setopt NO_GLOB_SUBST +-else +- case `(set -o) 2>/dev/null` in #( +- *posix*) : +- set -o posix ;; #( +- *) : +- ;; +-esac +-fi +- +- +-as_nl=' +-' +-export as_nl +-# Printing a long string crashes Solaris 7 /usr/bin/printf. +-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +-# Prefer a ksh shell builtin over an external printf program on Solaris, +-# but without wasting forks for bash or zsh. +-if test -z "$BASH_VERSION$ZSH_VERSION" \ +- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then +- as_echo='print -r --' +- as_echo_n='print -rn --' +-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then +- as_echo='printf %s\n' +- as_echo_n='printf %s' +-else +- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then +- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' +- as_echo_n='/usr/ucb/echo -n' +- else +- as_echo_body='eval expr "X$1" : "X\\(.*\\)"' +- as_echo_n_body='eval +- arg=$1; +- case $arg in #( +- *"$as_nl"*) +- expr "X$arg" : "X\\(.*\\)$as_nl"; +- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; +- esac; +- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" +- ' +- export as_echo_n_body +- as_echo_n='sh -c $as_echo_n_body as_echo' +- fi +- export as_echo_body +- as_echo='sh -c $as_echo_body as_echo' +-fi +- +-# The user is always right. +-if test "${PATH_SEPARATOR+set}" != set; then +- PATH_SEPARATOR=: +- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { +- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || +- PATH_SEPARATOR=';' +- } +-fi +- +- +-# IFS +-# We need space, tab and new line, in precisely that order. Quoting is +-# there to prevent editors from complaining about space-tab. +-# (If _AS_PATH_WALK were called with IFS unset, it would disable word +-# splitting by setting IFS to empty value.) +-IFS=" "" $as_nl" +- +-# Find who we are. Look in the path if we contain no directory separator. +-as_myself= +-case $0 in #(( +- *[\\/]* ) as_myself=$0 ;; +- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +- done +-IFS=$as_save_IFS +- +- ;; +-esac +-# We did not find ourselves, most probably we were run as `sh COMMAND' +-# in which case we are not to be found in the path. +-if test "x$as_myself" = x; then +- as_myself=$0 +-fi +-if test ! -f "$as_myself"; then +- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 +- exit 1 +-fi +- +-# Unset variables that we do not need and which cause bugs (e.g. in +-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +-# suppresses any "Segmentation fault" message there. '((' could +-# trigger a bug in pdksh 5.2.14. +-for as_var in BASH_ENV ENV MAIL MAILPATH +-do eval test x\${$as_var+set} = xset \ +- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +-done +-PS1='$ ' +-PS2='> ' +-PS4='+ ' +- +-# NLS nuisances. +-LC_ALL=C +-export LC_ALL +-LANGUAGE=C +-export LANGUAGE +- +-# CDPATH. +-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +- +-# Use a proper internal environment variable to ensure we don't fall +- # into an infinite loop, continuously re-executing ourselves. +- if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then +- _as_can_reexec=no; export _as_can_reexec; +- # We cannot yet assume a decent shell, so we have to provide a +-# neutralization value for shells without unset; and this also +-# works around shells that cannot unset nonexistent variables. +-# Preserve -v and -x to the replacement shell. +-BASH_ENV=/dev/null +-ENV=/dev/null +-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +-case $- in # (((( +- *v*x* | *x*v* ) as_opts=-vx ;; +- *v* ) as_opts=-v ;; +- *x* ) as_opts=-x ;; +- * ) as_opts= ;; +-esac +-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +-# Admittedly, this is quite paranoid, since all the known shells bail +-# out after a failed `exec'. +-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +-as_fn_exit 255 +- fi +- # We don't want this to propagate to other subprocesses. +- { _as_can_reexec=; unset _as_can_reexec;} +-if test "x$CONFIG_SHELL" = x; then +- as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : +- emulate sh +- NULLCMD=: +- # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which +- # is contrary to our usage. Disable this feature. +- alias -g '\${1+\"\$@\"}'='\"\$@\"' +- setopt NO_GLOB_SUBST +-else +- case \`(set -o) 2>/dev/null\` in #( +- *posix*) : +- set -o posix ;; #( +- *) : +- ;; +-esac +-fi +-" +- as_required="as_fn_return () { (exit \$1); } +-as_fn_success () { as_fn_return 0; } +-as_fn_failure () { as_fn_return 1; } +-as_fn_ret_success () { return 0; } +-as_fn_ret_failure () { return 1; } +- +-exitcode=0 +-as_fn_success || { exitcode=1; echo as_fn_success failed.; } +-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : +- +-else +- exitcode=1; echo positional parameters were not saved. +-fi +-test x\$exitcode = x0 || exit 1 +-test -x / || exit 1" +- as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO +- as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO +- eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && +- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +-test \$(( 1 + 1 )) = 2 || exit 1" +- if (eval "$as_required") 2>/dev/null; then : +- as_have_required=yes +-else +- as_have_required=no +-fi +- if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : +- +-else +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-as_found=false +-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- as_found=: +- case $as_dir in #( +- /*) +- for as_base in sh bash ksh sh5; do +- # Try only shells that exist, to save several forks. +- as_shell=$as_dir/$as_base +- if { test -f "$as_shell" || test -f "$as_shell.exe"; } && +- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : +- CONFIG_SHELL=$as_shell as_have_required=yes +- if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : +- break 2 +-fi +-fi +- done;; +- esac +- as_found=false +-done +-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && +- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : +- CONFIG_SHELL=$SHELL as_have_required=yes +-fi; } +-IFS=$as_save_IFS +- +- +- if test "x$CONFIG_SHELL" != x; then : +- export CONFIG_SHELL +- # We cannot yet assume a decent shell, so we have to provide a +-# neutralization value for shells without unset; and this also +-# works around shells that cannot unset nonexistent variables. +-# Preserve -v and -x to the replacement shell. +-BASH_ENV=/dev/null +-ENV=/dev/null +-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +-case $- in # (((( +- *v*x* | *x*v* ) as_opts=-vx ;; +- *v* ) as_opts=-v ;; +- *x* ) as_opts=-x ;; +- * ) as_opts= ;; +-esac +-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +-# Admittedly, this is quite paranoid, since all the known shells bail +-# out after a failed `exec'. +-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +-exit 255 +-fi +- +- if test x$as_have_required = xno; then : +- $as_echo "$0: This script requires a shell more modern than all" +- $as_echo "$0: the shells that I found on your system." +- if test x${ZSH_VERSION+set} = xset ; then +- $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" +- $as_echo "$0: be upgraded to zsh 4.3.4 or later." +- else +- $as_echo "$0: Please tell bug-autoconf@gnu.org and bug-groff@gnu.org +-$0: about your system, including any error possibly output +-$0: before this message. Then install a modern shell, or +-$0: manually run the script under such a shell if you do +-$0: have one." +- fi +- exit 1 +-fi +-fi +-fi +-SHELL=${CONFIG_SHELL-/bin/sh} +-export SHELL +-# Unset more variables known to interfere with behavior of common tools. +-CLICOLOR_FORCE= GREP_OPTIONS= +-unset CLICOLOR_FORCE GREP_OPTIONS +- +-## --------------------- ## +-## M4sh Shell Functions. ## +-## --------------------- ## +-# as_fn_unset VAR +-# --------------- +-# Portably unset VAR. +-as_fn_unset () +-{ +- { eval $1=; unset $1;} +-} +-as_unset=as_fn_unset +- +-# as_fn_set_status STATUS +-# ----------------------- +-# Set $? to STATUS, without forking. +-as_fn_set_status () +-{ +- return $1 +-} # as_fn_set_status +- +-# as_fn_exit STATUS +-# ----------------- +-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +-as_fn_exit () +-{ +- set +e +- as_fn_set_status $1 +- exit $1 +-} # as_fn_exit +- +-# as_fn_mkdir_p +-# ------------- +-# Create "$as_dir" as a directory, including parents if necessary. +-as_fn_mkdir_p () +-{ +- +- case $as_dir in #( +- -*) as_dir=./$as_dir;; +- esac +- test -d "$as_dir" || eval $as_mkdir_p || { +- as_dirs= +- while :; do +- case $as_dir in #( +- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( +- *) as_qdir=$as_dir;; +- esac +- as_dirs="'$as_qdir' $as_dirs" +- as_dir=`$as_dirname -- "$as_dir" || +-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$as_dir" : 'X\(//\)[^/]' \| \ +- X"$as_dir" : 'X\(//\)$' \| \ +- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$as_dir" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- test -d "$as_dir" && break +- done +- test -z "$as_dirs" || eval "mkdir $as_dirs" +- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" +- +- +-} # as_fn_mkdir_p +- +-# as_fn_executable_p FILE +-# ----------------------- +-# Test if FILE is an executable regular file. +-as_fn_executable_p () +-{ +- test -f "$1" && test -x "$1" +-} # as_fn_executable_p +-# as_fn_append VAR VALUE +-# ---------------------- +-# Append the text in VALUE to the end of the definition contained in VAR. Take +-# advantage of any shell optimizations that allow amortized linear growth over +-# repeated appends, instead of the typical quadratic growth present in naive +-# implementations. +-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +- eval 'as_fn_append () +- { +- eval $1+=\$2 +- }' +-else +- as_fn_append () +- { +- eval $1=\$$1\$2 +- } +-fi # as_fn_append +- +-# as_fn_arith ARG... +-# ------------------ +-# Perform arithmetic evaluation on the ARGs, and store the result in the +-# global $as_val. Take advantage of shells that can avoid forks. The arguments +-# must be portable across $(()) and expr. +-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +- eval 'as_fn_arith () +- { +- as_val=$(( $* )) +- }' +-else +- as_fn_arith () +- { +- as_val=`expr "$@" || test $? -eq 1` +- } +-fi # as_fn_arith +- +- +-# as_fn_error STATUS ERROR [LINENO LOG_FD] +-# ---------------------------------------- +-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +-# script with STATUS, using 1 if that was 0. +-as_fn_error () +-{ +- as_status=$1; test $as_status -eq 0 && as_status=1 +- if test "$4"; then +- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 +- fi +- $as_echo "$as_me: error: $2" >&2 +- as_fn_exit $as_status +-} # as_fn_error +- +-if expr a : '\(a\)' >/dev/null 2>&1 && +- test "X`expr 00001 : '.*\(...\)'`" = X001; then +- as_expr=expr +-else +- as_expr=false +-fi +- +-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then +- as_basename=basename +-else +- as_basename=false +-fi +- +-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then +- as_dirname=dirname +-else +- as_dirname=false +-fi +- +-as_me=`$as_basename -- "$0" || +-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ +- X"$0" : 'X\(//\)$' \| \ +- X"$0" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X/"$0" | +- sed '/^.*\/\([^/][^/]*\)\/*$/{ +- s//\1/ +- q +- } +- /^X\/\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\/\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- +-# Avoid depending upon Character Ranges. +-as_cr_letters='abcdefghijklmnopqrstuvwxyz' +-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +-as_cr_Letters=$as_cr_letters$as_cr_LETTERS +-as_cr_digits='0123456789' +-as_cr_alnum=$as_cr_Letters$as_cr_digits +- +- +- as_lineno_1=$LINENO as_lineno_1a=$LINENO +- as_lineno_2=$LINENO as_lineno_2a=$LINENO +- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && +- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { +- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) +- sed -n ' +- p +- /[$]LINENO/= +- ' <$as_myself | +- sed ' +- s/[$]LINENO.*/&-/ +- t lineno +- b +- :lineno +- N +- :loop +- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ +- t loop +- s/-\n.*// +- ' >$as_me.lineno && +- chmod +x "$as_me.lineno" || +- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } +- +- # If we had to re-execute with $CONFIG_SHELL, we're ensured to have +- # already done that, so ensure we don't try to do so again and fall +- # in an infinite loop. This has already happened in practice. +- _as_can_reexec=no; export _as_can_reexec +- # Don't try to exec as it changes $[0], causing all sort of problems +- # (the dirname of $[0] is not the place where we might find the +- # original and so on. Autoconf is especially sensitive to this). +- . "./$as_me.lineno" +- # Exit status is that of the last command. +- exit +-} +- +-ECHO_C= ECHO_N= ECHO_T= +-case `echo -n x` in #((((( +--n*) +- case `echo 'xy\c'` in +- *c*) ECHO_T=' ';; # ECHO_T is single tab character. +- xy) ECHO_C='\c';; +- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null +- ECHO_T=' ';; +- esac;; +-*) +- ECHO_N='-n';; +-esac +- +-rm -f conf$$ conf$$.exe conf$$.file +-if test -d conf$$.dir; then +- rm -f conf$$.dir/conf$$.file +-else +- rm -f conf$$.dir +- mkdir conf$$.dir 2>/dev/null +-fi +-if (echo >conf$$.file) 2>/dev/null; then +- if ln -s conf$$.file conf$$ 2>/dev/null; then +- as_ln_s='ln -s' +- # ... but there are two gotchas: +- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. +- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. +- # In both cases, we have to default to `cp -pR'. +- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || +- as_ln_s='cp -pR' +- elif ln conf$$.file conf$$ 2>/dev/null; then +- as_ln_s=ln +- else +- as_ln_s='cp -pR' +- fi +-else +- as_ln_s='cp -pR' +-fi +-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +-rmdir conf$$.dir 2>/dev/null +- +-if mkdir -p . 2>/dev/null; then +- as_mkdir_p='mkdir -p "$as_dir"' +-else +- test -d ./-p && rmdir ./-p +- as_mkdir_p=false +-fi +- +-as_test_x='test -x' +-as_executable_p=as_fn_executable_p +- +-# Sed expression to map a string onto a valid CPP name. +-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +- +-# Sed expression to map a string onto a valid variable name. +-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +- +- +-test -n "$DJDIR" || exec 7<&0 &1 +- +-# Name of the host. +-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +-# so uname gets run too. +-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` +- +-# +-# Initializations. +-# +-ac_default_prefix=/usr/local +-ac_clean_files= +-ac_config_libobj_dir=. +-LIBOBJS= +-cross_compiling=no +-subdirs= +-MFLAGS= +-MAKEFLAGS= +- +-# Identity of this package. +-PACKAGE_NAME='groff' +-PACKAGE_TARNAME='groff-1.22.3' +-PACKAGE_VERSION='1.22.3' +-PACKAGE_STRING='groff 1.22.3' +-PACKAGE_BUGREPORT='bug-groff@gnu.org' +-PACKAGE_URL='' +- +-ac_unique_file="src/roff/groff/groff.cpp" +-# Factoring default headers for most tests. +-ac_includes_default="\ +-#include +-#ifdef HAVE_SYS_TYPES_H +-# include +-#endif +-#ifdef HAVE_SYS_STAT_H +-# include +-#endif +-#ifdef STDC_HEADERS +-# include +-# include +-#else +-# ifdef HAVE_STDLIB_H +-# include +-# endif +-#endif +-#ifdef HAVE_STRING_H +-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +-# include +-# endif +-# include +-#endif +-#ifdef HAVE_STRINGS_H +-# include +-#endif +-#ifdef HAVE_INTTYPES_H +-# include +-#endif +-#ifdef HAVE_STDINT_H +-# include +-#endif +-#ifdef HAVE_UNISTD_H +-# include +-#endif" +- +-ac_header_list= +-ac_func_list= +-ac_subst_vars='LTLIBOBJS +-GLIBC21 +-pnmtops_nosetpage +-make_uninstall_pdfexamples +-make_install_pdfexamples +-make_pdfexamples +-make_uninstall_pdfdoc +-make_install_pdfdoc +-make_pdfdoc +-ac_ct_AWK +-ALT_AWK_PROGS +-make_uninstall_htmlexamples +-make_install_htmlexamples +-make_htmlexamples +-make_uninstall_htmldoc +-make_install_htmldoc +-make_htmldoc +-pnmtops +-psselect +-pnmtopng +-pnmcrop +-pnmcut +-ac_ct_GHOSTSCRIPT +-GHOSTSCRIPT +-ALT_GHOSTSCRIPT_PROGS +-GROFF_PATH_SEPARATOR +-tmac_wrap +-sys_tmac_prefix +-g +-PAGE +-BROKEN_SPOOLER_FLAGS +-LIBOBJS +-LIBEXT +-LTLIBICONV +-LIBICONV +-CXXCPP +-host_os +-host_vendor +-host_cpu +-host +-build_os +-build_vendor +-build_cpu +-build +-LIBM +-LIBC +-SH_SCRIPT_SED_CMD +-LN_S +-INSTALL_DATA +-INSTALL_SCRIPT +-INSTALL_PROGRAM +-INSTALL_INFO +-RANLIB +-make_uninstall_infodoc +-make_install_infodoc +-make_infodoc +-MAKEINFO +-make_uninstall_examples +-make_install_examples +-make_examples +-make_uninstall_otherdoc +-make_install_otherdoc +-make_otherdoc +-make_uninstall_shipped_htmldoc +-make_install_shipped_htmldoc +-doc_dist_target_ok +-YACC +-DVIPRINT +-PSPRINT +-LPQ +-LP +-LPR +-AWK +-PERL_VERSION +-SED +-PERL +-groffer_dir +-appresdir +-XLIBDIRS +-XPROGDIRS +-XDEVDIRS +-X_EXTRA_LIBS +-X_LIBS +-X_PRE_LIBS +-X_CFLAGS +-XMKMF +-make_uninstall_winscripts +-make_install_winscripts +-make_winscripts +-OTHERDEVDIRS +-TTYDEVDIRS +-ac_ct_CXX +-CXXFLAGS +-CXX +-EGREP +-GREP +-CPP +-OBJEXT +-EXEEXT +-ac_ct_CC +-CPPFLAGS +-LDFLAGS +-CFLAGS +-CC +-target_alias +-host_alias +-build_alias +-LIBS +-ECHO_T +-ECHO_N +-ECHO_C +-DEFS +-mandir +-localedir +-libdir +-psdir +-pdfdir +-dvidir +-htmldir +-infodir +-docdir +-oldincludedir +-includedir +-localstatedir +-sharedstatedir +-sysconfdir +-datadir +-datarootdir +-libexecdir +-sbindir +-bindir +-program_transform_name +-prefix +-exec_prefix +-PACKAGE_URL +-PACKAGE_BUGREPORT +-PACKAGE_STRING +-PACKAGE_VERSION +-PACKAGE_TARNAME +-PACKAGE_NAME +-PATH_SEPARATOR +-SHELL +-referdir +-grog_dir +-gpinyin_dir +-glilypond_dir +-libprogramdir' +-ac_subst_files='' +-ac_user_opts=' +-enable_option_checking +-with_x +-with_appresdir +-with_grofferdir +-with_doc +-with_gnu_ld +-enable_rpath +-with_libiconv_prefix +-with_alt_gs +-with_gs +-with_alt_awk +-with_awk +-' +- ac_precious_vars='build_alias +-host_alias +-target_alias +-CC +-CFLAGS +-LDFLAGS +-LIBS +-CPPFLAGS +-CPP +-CXX +-CXXFLAGS +-CCC +-XMKMF +-CXXCPP' +- +- +-# Initialize some variables set by options. +-ac_init_help= +-ac_init_version=false +-ac_unrecognized_opts= +-ac_unrecognized_sep= +-# The variables have the same names as the options, with +-# dashes changed to underlines. +-cache_file=/dev/null +-exec_prefix=NONE +-no_create= +-no_recursion= +-prefix=NONE +-program_prefix=NONE +-program_suffix=NONE +-program_transform_name=s,x,x, +-silent= +-site= +-srcdir= +-verbose= +-x_includes=NONE +-x_libraries=NONE +- +-# Installation directory options. +-# These are left unexpanded so users can "make install exec_prefix=/foo" +-# and all the variables that are supposed to be based on exec_prefix +-# by default will actually change. +-# Use braces instead of parens because sh, perl, etc. also accept them. +-# (The list follows the same order as the GNU Coding Standards.) +-bindir='${exec_prefix}/bin' +-sbindir='${exec_prefix}/sbin' +-libexecdir='${exec_prefix}/libexec' +-datarootdir='${prefix}/share' +-datadir='${datarootdir}' +-sysconfdir='${prefix}/etc' +-sharedstatedir='${prefix}/com' +-localstatedir='${prefix}/var' +-includedir='${prefix}/include' +-oldincludedir='/usr/include' +-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +-infodir='${datarootdir}/info' +-htmldir='${docdir}' +-dvidir='${docdir}' +-pdfdir='${docdir}' +-psdir='${docdir}' +-libdir='${exec_prefix}/lib' +-localedir='${datarootdir}/locale' +-mandir='${datarootdir}/man' +- +-ac_prev= +-ac_dashdash= +-for ac_option +-do +- # If the previous option needs an argument, assign it. +- if test -n "$ac_prev"; then +- eval $ac_prev=\$ac_option +- ac_prev= +- continue +- fi +- +- case $ac_option in +- *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; +- *=) ac_optarg= ;; +- *) ac_optarg=yes ;; +- esac +- +- # Accept the important Cygnus configure options, so we can diagnose typos. +- +- case $ac_dashdash$ac_option in +- --) +- ac_dashdash=yes ;; +- +- -bindir | --bindir | --bindi | --bind | --bin | --bi) +- ac_prev=bindir ;; +- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) +- bindir=$ac_optarg ;; +- +- -build | --build | --buil | --bui | --bu) +- ac_prev=build_alias ;; +- -build=* | --build=* | --buil=* | --bui=* | --bu=*) +- build_alias=$ac_optarg ;; +- +- -cache-file | --cache-file | --cache-fil | --cache-fi \ +- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) +- ac_prev=cache_file ;; +- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ +- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) +- cache_file=$ac_optarg ;; +- +- --config-cache | -C) +- cache_file=config.cache ;; +- +- -datadir | --datadir | --datadi | --datad) +- ac_prev=datadir ;; +- -datadir=* | --datadir=* | --datadi=* | --datad=*) +- datadir=$ac_optarg ;; +- +- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ +- | --dataroo | --dataro | --datar) +- ac_prev=datarootdir ;; +- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ +- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) +- datarootdir=$ac_optarg ;; +- +- -disable-* | --disable-*) +- ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` +- # Reject names that are not valid shell variable names. +- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && +- as_fn_error $? "invalid feature name: $ac_useropt" +- ac_useropt_orig=$ac_useropt +- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` +- case $ac_user_opts in +- *" +-"enable_$ac_useropt" +-"*) ;; +- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" +- ac_unrecognized_sep=', ';; +- esac +- eval enable_$ac_useropt=no ;; +- +- -docdir | --docdir | --docdi | --doc | --do) +- ac_prev=docdir ;; +- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) +- docdir=$ac_optarg ;; +- +- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) +- ac_prev=dvidir ;; +- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) +- dvidir=$ac_optarg ;; +- +- -enable-* | --enable-*) +- ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` +- # Reject names that are not valid shell variable names. +- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && +- as_fn_error $? "invalid feature name: $ac_useropt" +- ac_useropt_orig=$ac_useropt +- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` +- case $ac_user_opts in +- *" +-"enable_$ac_useropt" +-"*) ;; +- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" +- ac_unrecognized_sep=', ';; +- esac +- eval enable_$ac_useropt=\$ac_optarg ;; +- +- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ +- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ +- | --exec | --exe | --ex) +- ac_prev=exec_prefix ;; +- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ +- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ +- | --exec=* | --exe=* | --ex=*) +- exec_prefix=$ac_optarg ;; +- +- -gas | --gas | --ga | --g) +- # Obsolete; use --with-gas. +- with_gas=yes ;; +- +- -help | --help | --hel | --he | -h) +- ac_init_help=long ;; +- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) +- ac_init_help=recursive ;; +- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) +- ac_init_help=short ;; +- +- -host | --host | --hos | --ho) +- ac_prev=host_alias ;; +- -host=* | --host=* | --hos=* | --ho=*) +- host_alias=$ac_optarg ;; +- +- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) +- ac_prev=htmldir ;; +- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ +- | --ht=*) +- htmldir=$ac_optarg ;; +- +- -includedir | --includedir | --includedi | --included | --include \ +- | --includ | --inclu | --incl | --inc) +- ac_prev=includedir ;; +- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ +- | --includ=* | --inclu=* | --incl=* | --inc=*) +- includedir=$ac_optarg ;; +- +- -infodir | --infodir | --infodi | --infod | --info | --inf) +- ac_prev=infodir ;; +- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) +- infodir=$ac_optarg ;; +- +- -libdir | --libdir | --libdi | --libd) +- ac_prev=libdir ;; +- -libdir=* | --libdir=* | --libdi=* | --libd=*) +- libdir=$ac_optarg ;; +- +- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ +- | --libexe | --libex | --libe) +- ac_prev=libexecdir ;; +- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ +- | --libexe=* | --libex=* | --libe=*) +- libexecdir=$ac_optarg ;; +- +- -localedir | --localedir | --localedi | --localed | --locale) +- ac_prev=localedir ;; +- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) +- localedir=$ac_optarg ;; +- +- -localstatedir | --localstatedir | --localstatedi | --localstated \ +- | --localstate | --localstat | --localsta | --localst | --locals) +- ac_prev=localstatedir ;; +- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ +- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) +- localstatedir=$ac_optarg ;; +- +- -mandir | --mandir | --mandi | --mand | --man | --ma | --m) +- ac_prev=mandir ;; +- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) +- mandir=$ac_optarg ;; +- +- -nfp | --nfp | --nf) +- # Obsolete; use --without-fp. +- with_fp=no ;; +- +- -no-create | --no-create | --no-creat | --no-crea | --no-cre \ +- | --no-cr | --no-c | -n) +- no_create=yes ;; +- +- -no-recursion | --no-recursion | --no-recursio | --no-recursi \ +- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) +- no_recursion=yes ;; +- +- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ +- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ +- | --oldin | --oldi | --old | --ol | --o) +- ac_prev=oldincludedir ;; +- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ +- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ +- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) +- oldincludedir=$ac_optarg ;; +- +- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) +- ac_prev=prefix ;; +- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) +- prefix=$ac_optarg ;; +- +- -program-prefix | --program-prefix | --program-prefi | --program-pref \ +- | --program-pre | --program-pr | --program-p) +- ac_prev=program_prefix ;; +- -program-prefix=* | --program-prefix=* | --program-prefi=* \ +- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) +- program_prefix=$ac_optarg ;; +- +- -program-suffix | --program-suffix | --program-suffi | --program-suff \ +- | --program-suf | --program-su | --program-s) +- ac_prev=program_suffix ;; +- -program-suffix=* | --program-suffix=* | --program-suffi=* \ +- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) +- program_suffix=$ac_optarg ;; +- +- -program-transform-name | --program-transform-name \ +- | --program-transform-nam | --program-transform-na \ +- | --program-transform-n | --program-transform- \ +- | --program-transform | --program-transfor \ +- | --program-transfo | --program-transf \ +- | --program-trans | --program-tran \ +- | --progr-tra | --program-tr | --program-t) +- ac_prev=program_transform_name ;; +- -program-transform-name=* | --program-transform-name=* \ +- | --program-transform-nam=* | --program-transform-na=* \ +- | --program-transform-n=* | --program-transform-=* \ +- | --program-transform=* | --program-transfor=* \ +- | --program-transfo=* | --program-transf=* \ +- | --program-trans=* | --program-tran=* \ +- | --progr-tra=* | --program-tr=* | --program-t=*) +- program_transform_name=$ac_optarg ;; +- +- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) +- ac_prev=pdfdir ;; +- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) +- pdfdir=$ac_optarg ;; +- +- -psdir | --psdir | --psdi | --psd | --ps) +- ac_prev=psdir ;; +- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) +- psdir=$ac_optarg ;; +- +- -q | -quiet | --quiet | --quie | --qui | --qu | --q \ +- | -silent | --silent | --silen | --sile | --sil) +- silent=yes ;; +- +- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) +- ac_prev=sbindir ;; +- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ +- | --sbi=* | --sb=*) +- sbindir=$ac_optarg ;; +- +- -sharedstatedir | --sharedstatedir | --sharedstatedi \ +- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ +- | --sharedst | --shareds | --shared | --share | --shar \ +- | --sha | --sh) +- ac_prev=sharedstatedir ;; +- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ +- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ +- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ +- | --sha=* | --sh=*) +- sharedstatedir=$ac_optarg ;; +- +- -site | --site | --sit) +- ac_prev=site ;; +- -site=* | --site=* | --sit=*) +- site=$ac_optarg ;; +- +- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) +- ac_prev=srcdir ;; +- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) +- srcdir=$ac_optarg ;; +- +- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ +- | --syscon | --sysco | --sysc | --sys | --sy) +- ac_prev=sysconfdir ;; +- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ +- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) +- sysconfdir=$ac_optarg ;; +- +- -target | --target | --targe | --targ | --tar | --ta | --t) +- ac_prev=target_alias ;; +- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) +- target_alias=$ac_optarg ;; +- +- -v | -verbose | --verbose | --verbos | --verbo | --verb) +- verbose=yes ;; +- +- -version | --version | --versio | --versi | --vers | -V) +- ac_init_version=: ;; +- +- -with-* | --with-*) +- ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` +- # Reject names that are not valid shell variable names. +- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && +- as_fn_error $? "invalid package name: $ac_useropt" +- ac_useropt_orig=$ac_useropt +- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` +- case $ac_user_opts in +- *" +-"with_$ac_useropt" +-"*) ;; +- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" +- ac_unrecognized_sep=', ';; +- esac +- eval with_$ac_useropt=\$ac_optarg ;; +- +- -without-* | --without-*) +- ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` +- # Reject names that are not valid shell variable names. +- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && +- as_fn_error $? "invalid package name: $ac_useropt" +- ac_useropt_orig=$ac_useropt +- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` +- case $ac_user_opts in +- *" +-"with_$ac_useropt" +-"*) ;; +- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" +- ac_unrecognized_sep=', ';; +- esac +- eval with_$ac_useropt=no ;; +- +- --x) +- # Obsolete; use --with-x. +- with_x=yes ;; +- +- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ +- | --x-incl | --x-inc | --x-in | --x-i) +- ac_prev=x_includes ;; +- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ +- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) +- x_includes=$ac_optarg ;; +- +- -x-libraries | --x-libraries | --x-librarie | --x-librari \ +- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) +- ac_prev=x_libraries ;; +- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ +- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) +- x_libraries=$ac_optarg ;; +- +- -*) as_fn_error $? "unrecognized option: \`$ac_option' +-Try \`$0 --help' for more information" +- ;; +- +- *=*) +- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` +- # Reject names that are not valid shell variable names. +- case $ac_envvar in #( +- '' | [0-9]* | *[!_$as_cr_alnum]* ) +- as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; +- esac +- eval $ac_envvar=\$ac_optarg +- export $ac_envvar ;; +- +- *) +- # FIXME: should be removed in autoconf 3.0. +- $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 +- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && +- $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 +- : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" +- ;; +- +- esac +-done +- +-if test -n "$ac_prev"; then +- ac_option=--`echo $ac_prev | sed 's/_/-/g'` +- as_fn_error $? "missing argument to $ac_option" +-fi +- +-if test -n "$ac_unrecognized_opts"; then +- case $enable_option_checking in +- no) ;; +- fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; +- *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; +- esac +-fi +- +-# Check all directory arguments for consistency. +-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ +- datadir sysconfdir sharedstatedir localstatedir includedir \ +- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ +- libdir localedir mandir +-do +- eval ac_val=\$$ac_var +- # Remove trailing slashes. +- case $ac_val in +- */ ) +- ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` +- eval $ac_var=\$ac_val;; +- esac +- # Be sure to have absolute directory names. +- case $ac_val in +- [\\/$]* | ?:[\\/]* ) continue;; +- NONE | '' ) case $ac_var in *prefix ) continue;; esac;; +- esac +- as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +-done +- +-# There might be people who depend on the old broken behavior: `$host' +-# used to hold the argument of --host etc. +-# FIXME: To remove some day. +-build=$build_alias +-host=$host_alias +-target=$target_alias +- +-# FIXME: To remove some day. +-if test "x$host_alias" != x; then +- if test "x$build_alias" = x; then +- cross_compiling=maybe +- elif test "x$build_alias" != "x$host_alias"; then +- cross_compiling=yes +- fi +-fi +- +-ac_tool_prefix= +-test -n "$host_alias" && ac_tool_prefix=$host_alias- +- +-test "$silent" = yes && exec 6>/dev/null +- +- +-ac_pwd=`pwd` && test -n "$ac_pwd" && +-ac_ls_di=`ls -di .` && +-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || +- as_fn_error $? "working directory cannot be determined" +-test "X$ac_ls_di" = "X$ac_pwd_ls_di" || +- as_fn_error $? "pwd does not report name of working directory" +- +- +-# Find the source files, if location was not specified. +-if test -z "$srcdir"; then +- ac_srcdir_defaulted=yes +- # Try the directory containing this script, then the parent directory. +- ac_confdir=`$as_dirname -- "$as_myself" || +-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$as_myself" : 'X\(//\)[^/]' \| \ +- X"$as_myself" : 'X\(//\)$' \| \ +- X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$as_myself" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- srcdir=$ac_confdir +- if test ! -r "$srcdir/$ac_unique_file"; then +- srcdir=.. +- fi +-else +- ac_srcdir_defaulted=no +-fi +-if test ! -r "$srcdir/$ac_unique_file"; then +- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." +- as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +-fi +-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +-ac_abs_confdir=`( +- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" +- pwd)` +-# When building in place, set srcdir=. +-if test "$ac_abs_confdir" = "$ac_pwd"; then +- srcdir=. +-fi +-# Remove unnecessary trailing slashes from srcdir. +-# Double slashes in file names in object file debugging info +-# mess up M-x gdb in Emacs. +-case $srcdir in +-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +-esac +-for ac_var in $ac_precious_vars; do +- eval ac_env_${ac_var}_set=\${${ac_var}+set} +- eval ac_env_${ac_var}_value=\$${ac_var} +- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} +- eval ac_cv_env_${ac_var}_value=\$${ac_var} +-done +- +-# +-# Report the --help message. +-# +-if test "$ac_init_help" = "long"; then +- # Omit some internal or obsolete options to make the list less imposing. +- # This message is too long to be a string in the A/UX 3.1 sh. +- cat <<_ACEOF +-\`configure' configures groff 1.22.3 to adapt to many kinds of systems. +- +-Usage: $0 [OPTION]... [VAR=VALUE]... +- +-To assign environment variables (e.g., CC, CFLAGS...), specify them as +-VAR=VALUE. See below for descriptions of some of the useful variables. +- +-Defaults for the options are specified in brackets. +- +-Configuration: +- -h, --help display this help and exit +- --help=short display options specific to this package +- --help=recursive display the short help of all the included packages +- -V, --version display version information and exit +- -q, --quiet, --silent do not print \`checking ...' messages +- --cache-file=FILE cache test results in FILE [disabled] +- -C, --config-cache alias for \`--cache-file=config.cache' +- -n, --no-create do not create output files +- --srcdir=DIR find the sources in DIR [configure dir or \`..'] +- +-Installation directories: +- --prefix=PREFIX install architecture-independent files in PREFIX +- [$ac_default_prefix] +- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX +- [PREFIX] +- +-By default, \`make install' will install all the files in +-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +-an installation prefix other than \`$ac_default_prefix' using \`--prefix', +-for instance \`--prefix=\$HOME'. +- +-For better control, use the options below. +- +-Fine tuning of the installation directories: +- --bindir=DIR user executables [EPREFIX/bin] +- --sbindir=DIR system admin executables [EPREFIX/sbin] +- --libexecdir=DIR program executables [EPREFIX/libexec] +- --sysconfdir=DIR read-only single-machine data [PREFIX/etc] +- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] +- --localstatedir=DIR modifiable single-machine data [PREFIX/var] +- --libdir=DIR object code libraries [EPREFIX/lib] +- --includedir=DIR C header files [PREFIX/include] +- --oldincludedir=DIR C header files for non-gcc [/usr/include] +- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] +- --datadir=DIR read-only architecture-independent data [DATAROOTDIR] +- --infodir=DIR info documentation [DATAROOTDIR/info] +- --localedir=DIR locale-dependent data [DATAROOTDIR/locale] +- --mandir=DIR man documentation [DATAROOTDIR/man] +- --docdir=DIR documentation root [DATAROOTDIR/doc/groff-1.22.3] +- --htmldir=DIR html documentation [DOCDIR] +- --dvidir=DIR dvi documentation [DOCDIR] +- --pdfdir=DIR pdf documentation [DOCDIR] +- --psdir=DIR ps documentation [DOCDIR] +-_ACEOF +- +- cat <<\_ACEOF +- +-X features: +- --x-includes=DIR X include files are in DIR +- --x-libraries=DIR X library files are in DIR +- +-System types: +- --build=BUILD configure for building on BUILD [guessed] +- --host=HOST cross-compile to build programs to run on HOST [BUILD] +-_ACEOF +-fi +- +-if test -n "$ac_init_help"; then +- case $ac_init_help in +- short | recursive ) echo "Configuration of groff 1.22.3:";; +- esac +- cat <<\_ACEOF +- +-Optional Features: +- --disable-option-checking ignore unrecognized --enable/--with options +- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) +- --enable-FEATURE[=ARG] include FEATURE [ARG=yes] +- --disable-rpath do not hardcode runtime library paths +- +-Optional Packages: +- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) +- --with-x use the X Window System +- --with-appresdir=DIR X11 application resource files +- --with-grofferdir=DIR groffer files location +- --with-doc[=TYPE] choose which manuals (beside man pages) are +- desirable. TYPE can be `yes' or `no', or a +- comma-separated list of one or multiple of `html', +- `info', `other', `pdf', and `examples', to restrict +- what is produced +- --with-gnu-ld assume the C compiler uses GNU ld [default=no] +- --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib +- --without-libiconv-prefix don't search for libiconv in includedir and libdir +- --with-alt-gs=LIST alternative names for ghostscript executable +- --with-gs=PROG actual [/path/]name of ghostscript executable +- --with-alt-awk=LIST alternative names for awk executable +- --with-awk=PROG actual [/path/]name of awk executable +- +-Some influential environment variables: +- CC C compiler command +- CFLAGS C compiler flags +- LDFLAGS linker flags, e.g. -L if you have libraries in a +- nonstandard directory +- LIBS libraries to pass to the linker, e.g. -l +- CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if +- you have headers in a nonstandard directory +- CPP C preprocessor +- CXX C++ compiler command +- CXXFLAGS C++ compiler flags +- XMKMF Path to xmkmf, Makefile generator for X Window System +- CXXCPP C++ preprocessor +- +-Use these variables to override the choices made by `configure' or to help +-it to find libraries and programs with nonstandard names/locations. +- +-Report bugs to . +-_ACEOF +-ac_status=$? +-fi +- +-if test "$ac_init_help" = "recursive"; then +- # If there are subdirs, report their specific --help. +- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue +- test -d "$ac_dir" || +- { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || +- continue +- ac_builddir=. +- +-case "$ac_dir" in +-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +-*) +- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` +- # A ".." for each directory in $ac_dir_suffix. +- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` +- case $ac_top_builddir_sub in +- "") ac_top_builddir_sub=. ac_top_build_prefix= ;; +- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; +- esac ;; +-esac +-ac_abs_top_builddir=$ac_pwd +-ac_abs_builddir=$ac_pwd$ac_dir_suffix +-# for backward compatibility: +-ac_top_builddir=$ac_top_build_prefix +- +-case $srcdir in +- .) # We are building in place. +- ac_srcdir=. +- ac_top_srcdir=$ac_top_builddir_sub +- ac_abs_top_srcdir=$ac_pwd ;; +- [\\/]* | ?:[\\/]* ) # Absolute name. +- ac_srcdir=$srcdir$ac_dir_suffix; +- ac_top_srcdir=$srcdir +- ac_abs_top_srcdir=$srcdir ;; +- *) # Relative name. +- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix +- ac_top_srcdir=$ac_top_build_prefix$srcdir +- ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +-esac +-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix +- +- cd "$ac_dir" || { ac_status=$?; continue; } +- # Check for guested configure. +- if test -f "$ac_srcdir/configure.gnu"; then +- echo && +- $SHELL "$ac_srcdir/configure.gnu" --help=recursive +- elif test -f "$ac_srcdir/configure"; then +- echo && +- $SHELL "$ac_srcdir/configure" --help=recursive +- else +- $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 +- fi || ac_status=$? +- cd "$ac_pwd" || { ac_status=$?; break; } +- done +-fi +- +-test -n "$ac_init_help" && exit $ac_status +-if $ac_init_version; then +- cat <<\_ACEOF +-groff configure 1.22.3 +-generated by GNU Autoconf 2.69 +- +-Copyright (C) 2012 Free Software Foundation, Inc. +-This configure script is free software; the Free Software Foundation +-gives unlimited permission to copy, distribute and modify it. +-_ACEOF +- exit +-fi +- +-## ------------------------ ## +-## Autoconf initialization. ## +-## ------------------------ ## +- +-# ac_fn_c_try_compile LINENO +-# -------------------------- +-# Try to compile conftest.$ac_ext, and return whether this succeeded. +-ac_fn_c_try_compile () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- rm -f conftest.$ac_objext +- if { { ac_try="$ac_compile" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_compile") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- grep -v '^ *+' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- mv -f conftest.er1 conftest.err +- fi +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && { +- test -z "$ac_c_werror_flag" || +- test ! -s conftest.err +- } && test -s conftest.$ac_objext; then : +- ac_retval=0 +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=1 +-fi +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_c_try_compile +- +-# ac_fn_c_try_cpp LINENO +-# ---------------------- +-# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +-ac_fn_c_try_cpp () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- if { { ac_try="$ac_cpp conftest.$ac_ext" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- grep -v '^ *+' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- mv -f conftest.er1 conftest.err +- fi +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } > conftest.i && { +- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || +- test ! -s conftest.err +- }; then : +- ac_retval=0 +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=1 +-fi +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_c_try_cpp +- +-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +-# ------------------------------------------------------- +-# Tests whether HEADER exists, giving a warning if it cannot be compiled using +-# the include files in INCLUDES and setting the cache variable VAR +-# accordingly. +-ac_fn_c_check_header_mongrel () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- if eval \${$3+:} false; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +-$as_echo_n "checking for $2... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +-else +- # Is the header compilable? +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +-$as_echo_n "checking $2 usability... " >&6; } +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-#include <$2> +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_header_compiler=yes +-else +- ac_header_compiler=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +-$as_echo "$ac_header_compiler" >&6; } +- +-# Is the header present? +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +-$as_echo_n "checking $2 presence... " >&6; } +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include <$2> +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- ac_header_preproc=yes +-else +- ac_header_preproc=no +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +-$as_echo "$ac_header_preproc" >&6; } +- +-# So? What about this header? +-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( +- yes:no: ) +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +- ;; +- no:yes:* ) +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +-$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +-$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +-( $as_echo "## -------------------------------- ## +-## Report this to bug-groff@gnu.org ## +-## -------------------------------- ##" +- ) | sed "s/^/$as_me: WARNING: /" >&2 +- ;; +-esac +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +-$as_echo_n "checking for $2... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- eval "$3=\$ac_header_compiler" +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +-fi +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_header_mongrel +- +-# ac_fn_c_try_run LINENO +-# ---------------------- +-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +-# that executables *can* be run. +-ac_fn_c_try_run () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- if { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' +- { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; }; then : +- ac_retval=0 +-else +- $as_echo "$as_me: program exited with status $ac_status" >&5 +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=$ac_status +-fi +- rm -rf conftest.dSYM conftest_ipa8_conftest.oo +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_c_try_run +- +-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +-# ------------------------------------------------------- +-# Tests whether HEADER exists and can be compiled using the include files in +-# INCLUDES, setting the cache variable VAR accordingly. +-ac_fn_c_check_header_compile () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +-$as_echo_n "checking for $2... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-#include <$2> +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval "$3=yes" +-else +- eval "$3=no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_header_compile +- +-# ac_fn_cxx_try_compile LINENO +-# ---------------------------- +-# Try to compile conftest.$ac_ext, and return whether this succeeded. +-ac_fn_cxx_try_compile () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- rm -f conftest.$ac_objext +- if { { ac_try="$ac_compile" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_compile") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- grep -v '^ *+' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- mv -f conftest.er1 conftest.err +- fi +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && { +- test -z "$ac_cxx_werror_flag" || +- test ! -s conftest.err +- } && test -s conftest.$ac_objext; then : +- ac_retval=0 +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=1 +-fi +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_cxx_try_compile +- +-# ac_fn_cxx_try_run LINENO +-# ------------------------ +-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +-# that executables *can* be run. +-ac_fn_cxx_try_run () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- if { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' +- { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; }; then : +- ac_retval=0 +-else +- $as_echo "$as_me: program exited with status $ac_status" >&5 +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=$ac_status +-fi +- rm -rf conftest.dSYM conftest_ipa8_conftest.oo +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_cxx_try_run +- +-# ac_fn_cxx_try_link LINENO +-# ------------------------- +-# Try to link conftest.$ac_ext, and return whether this succeeded. +-ac_fn_cxx_try_link () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- rm -f conftest.$ac_objext conftest$ac_exeext +- if { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- grep -v '^ *+' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- mv -f conftest.er1 conftest.err +- fi +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && { +- test -z "$ac_cxx_werror_flag" || +- test ! -s conftest.err +- } && test -s conftest$ac_exeext && { +- test "$cross_compiling" = yes || +- test -x conftest$ac_exeext +- }; then : +- ac_retval=0 +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=1 +-fi +- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information +- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would +- # interfere with the next link command; also delete a directory that is +- # left behind by Apple's compiler. We do this before executing the actions. +- rm -rf conftest.dSYM conftest_ipa8_conftest.oo +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_cxx_try_link +- +-# ac_fn_c_try_link LINENO +-# ----------------------- +-# Try to link conftest.$ac_ext, and return whether this succeeded. +-ac_fn_c_try_link () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- rm -f conftest.$ac_objext conftest$ac_exeext +- if { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- grep -v '^ *+' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- mv -f conftest.er1 conftest.err +- fi +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && { +- test -z "$ac_c_werror_flag" || +- test ! -s conftest.err +- } && test -s conftest$ac_exeext && { +- test "$cross_compiling" = yes || +- test -x conftest$ac_exeext +- }; then : +- ac_retval=0 +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=1 +-fi +- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information +- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would +- # interfere with the next link command; also delete a directory that is +- # left behind by Apple's compiler. We do this before executing the actions. +- rm -rf conftest.dSYM conftest_ipa8_conftest.oo +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_c_try_link +- +-# ac_fn_c_check_func LINENO FUNC VAR +-# ---------------------------------- +-# Tests whether FUNC exists, setting the cache variable VAR accordingly +-ac_fn_c_check_func () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +-$as_echo_n "checking for $2... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-/* Define $2 to an innocuous variant, in case declares $2. +- For example, HP-UX 11i declares gettimeofday. */ +-#define $2 innocuous_$2 +- +-/* System header to define __stub macros and hopefully few prototypes, +- which can conflict with char $2 (); below. +- Prefer to if __STDC__ is defined, since +- exists even on freestanding compilers. */ +- +-#ifdef __STDC__ +-# include +-#else +-# include +-#endif +- +-#undef $2 +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char $2 (); +-/* The GNU C library defines this for functions which it implements +- to always fail with ENOSYS. Some functions are actually named +- something starting with __ and the normal name is an alias. */ +-#if defined __stub_$2 || defined __stub___$2 +-choke me +-#endif +- +-int +-main () +-{ +-return $2 (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- eval "$3=yes" +-else +- eval "$3=no" +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_func +- +-# ac_fn_cxx_try_cpp LINENO +-# ------------------------ +-# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +-ac_fn_cxx_try_cpp () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- if { { ac_try="$ac_cpp conftest.$ac_ext" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- grep -v '^ *+' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- mv -f conftest.er1 conftest.err +- fi +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } > conftest.i && { +- test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || +- test ! -s conftest.err +- }; then : +- ac_retval=0 +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=1 +-fi +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_cxx_try_cpp +- +-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +-# --------------------------------------------- +-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +-# accordingly. +-ac_fn_c_check_decl () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- as_decl_name=`echo $2|sed 's/ *(.*//'` +- as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +-$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-#ifndef $as_decl_name +-#ifdef __cplusplus +- (void) $as_decl_use; +-#else +- (void) $as_decl_name; +-#endif +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval "$3=yes" +-else +- eval "$3=no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_decl +-cat >config.log <<_ACEOF +-This file contains any messages produced by compilers while +-running configure, to aid debugging if configure makes a mistake. +- +-It was created by groff $as_me 1.22.3, which was +-generated by GNU Autoconf 2.69. Invocation command line was +- +- $ $0 $@ +- +-_ACEOF +-exec 5>>config.log +-{ +-cat <<_ASUNAME +-## --------- ## +-## Platform. ## +-## --------- ## +- +-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +-uname -m = `(uname -m) 2>/dev/null || echo unknown` +-uname -r = `(uname -r) 2>/dev/null || echo unknown` +-uname -s = `(uname -s) 2>/dev/null || echo unknown` +-uname -v = `(uname -v) 2>/dev/null || echo unknown` +- +-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` +- +-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` +- +-_ASUNAME +- +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- $as_echo "PATH: $as_dir" +- done +-IFS=$as_save_IFS +- +-} >&5 +- +-cat >&5 <<_ACEOF +- +- +-## ----------- ## +-## Core tests. ## +-## ----------- ## +- +-_ACEOF +- +- +-# Keep a trace of the command line. +-# Strip out --no-create and --no-recursion so they do not pile up. +-# Strip out --silent because we don't want to record it for future runs. +-# Also quote any args containing shell meta-characters. +-# Make two passes to allow for proper duplicate-argument suppression. +-ac_configure_args= +-ac_configure_args0= +-ac_configure_args1= +-ac_must_keep_next=false +-for ac_pass in 1 2 +-do +- for ac_arg +- do +- case $ac_arg in +- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; +- -q | -quiet | --quiet | --quie | --qui | --qu | --q \ +- | -silent | --silent | --silen | --sile | --sil) +- continue ;; +- *\'*) +- ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; +- esac +- case $ac_pass in +- 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; +- 2) +- as_fn_append ac_configure_args1 " '$ac_arg'" +- if test $ac_must_keep_next = true; then +- ac_must_keep_next=false # Got value, back to normal. +- else +- case $ac_arg in +- *=* | --config-cache | -C | -disable-* | --disable-* \ +- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ +- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ +- | -with-* | --with-* | -without-* | --without-* | --x) +- case "$ac_configure_args0 " in +- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; +- esac +- ;; +- -* ) ac_must_keep_next=true ;; +- esac +- fi +- as_fn_append ac_configure_args " '$ac_arg'" +- ;; +- esac +- done +-done +-{ ac_configure_args0=; unset ac_configure_args0;} +-{ ac_configure_args1=; unset ac_configure_args1;} +- +-# When interrupted or exit'd, cleanup temporary files, and complete +-# config.log. We remove comments because anyway the quotes in there +-# would cause problems or look ugly. +-# WARNING: Use '\'' to represent an apostrophe within the trap. +-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +-trap 'exit_status=$? +- # Save into config.log some information that might help in debugging. +- { +- echo +- +- $as_echo "## ---------------- ## +-## Cache variables. ## +-## ---------------- ##" +- echo +- # The following way of writing the cache mishandles newlines in values, +-( +- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do +- eval ac_val=\$$ac_var +- case $ac_val in #( +- *${as_nl}*) +- case $ac_var in #( +- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; +- esac +- case $ac_var in #( +- _ | IFS | as_nl) ;; #( +- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( +- *) { eval $ac_var=; unset $ac_var;} ;; +- esac ;; +- esac +- done +- (set) 2>&1 | +- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( +- *${as_nl}ac_space=\ *) +- sed -n \ +- "s/'\''/'\''\\\\'\'''\''/g; +- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" +- ;; #( +- *) +- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" +- ;; +- esac | +- sort +-) +- echo +- +- $as_echo "## ----------------- ## +-## Output variables. ## +-## ----------------- ##" +- echo +- for ac_var in $ac_subst_vars +- do +- eval ac_val=\$$ac_var +- case $ac_val in +- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; +- esac +- $as_echo "$ac_var='\''$ac_val'\''" +- done | sort +- echo +- +- if test -n "$ac_subst_files"; then +- $as_echo "## ------------------- ## +-## File substitutions. ## +-## ------------------- ##" +- echo +- for ac_var in $ac_subst_files +- do +- eval ac_val=\$$ac_var +- case $ac_val in +- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; +- esac +- $as_echo "$ac_var='\''$ac_val'\''" +- done | sort +- echo +- fi +- +- if test -s confdefs.h; then +- $as_echo "## ----------- ## +-## confdefs.h. ## +-## ----------- ##" +- echo +- cat confdefs.h +- echo +- fi +- test "$ac_signal" != 0 && +- $as_echo "$as_me: caught signal $ac_signal" +- $as_echo "$as_me: exit $exit_status" +- } >&5 +- rm -f core *.core core.conftest.* && +- rm -f -r conftest* confdefs* conf$$* $ac_clean_files && +- exit $exit_status +-' 0 +-for ac_signal in 1 2 13 15; do +- trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +-done +-ac_signal=0 +- +-# confdefs.h avoids OS command line length limits that DEFS can exceed. +-rm -f -r conftest* confdefs.h +- +-$as_echo "/* confdefs.h */" > confdefs.h +- +-# Predefined preprocessor variables. +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_NAME "$PACKAGE_NAME" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_VERSION "$PACKAGE_VERSION" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_STRING "$PACKAGE_STRING" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_URL "$PACKAGE_URL" +-_ACEOF +- +- +-# Let the site file select an alternate cache file if it wants to. +-# Prefer an explicitly selected file to automatically selected ones. +-ac_site_file1=NONE +-ac_site_file2=NONE +-if test -n "$CONFIG_SITE"; then +- # We do not want a PATH search for config.site. +- case $CONFIG_SITE in #(( +- -*) ac_site_file1=./$CONFIG_SITE;; +- */*) ac_site_file1=$CONFIG_SITE;; +- *) ac_site_file1=./$CONFIG_SITE;; +- esac +-elif test "x$prefix" != xNONE; then +- ac_site_file1=$prefix/share/config.site +- ac_site_file2=$prefix/etc/config.site +-else +- ac_site_file1=$ac_default_prefix/share/config.site +- ac_site_file2=$ac_default_prefix/etc/config.site +-fi +-for ac_site_file in "$ac_site_file1" "$ac_site_file2" +-do +- test "x$ac_site_file" = xNONE && continue +- if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +-$as_echo "$as_me: loading site script $ac_site_file" >&6;} +- sed 's/^/| /' "$ac_site_file" >&5 +- . "$ac_site_file" \ +- || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "failed to load site script $ac_site_file +-See \`config.log' for more details" "$LINENO" 5; } +- fi +-done +- +-if test -r "$cache_file"; then +- # Some versions of bash will fail to source /dev/null (special files +- # actually), so we avoid doing that. DJGPP emulates it as a regular file. +- if test /dev/null != "$cache_file" && test -f "$cache_file"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +-$as_echo "$as_me: loading cache $cache_file" >&6;} +- case $cache_file in +- [\\/]* | ?:[\\/]* ) . "$cache_file";; +- *) . "./$cache_file";; +- esac +- fi +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +-$as_echo "$as_me: creating cache $cache_file" >&6;} +- >$cache_file +-fi +- +-as_fn_append ac_header_list " stdlib.h" +-as_fn_append ac_header_list " unistd.h" +-as_fn_append ac_header_list " sys/param.h" +-as_fn_append ac_func_list " symlink" +-# Check that the precious variables saved in the cache have kept the same +-# value. +-ac_cache_corrupted=false +-for ac_var in $ac_precious_vars; do +- eval ac_old_set=\$ac_cv_env_${ac_var}_set +- eval ac_new_set=\$ac_env_${ac_var}_set +- eval ac_old_val=\$ac_cv_env_${ac_var}_value +- eval ac_new_val=\$ac_env_${ac_var}_value +- case $ac_old_set,$ac_new_set in +- set,) +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} +- ac_cache_corrupted=: ;; +- ,set) +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} +- ac_cache_corrupted=: ;; +- ,);; +- *) +- if test "x$ac_old_val" != "x$ac_new_val"; then +- # differences in whitespace do not lead to failure. +- ac_old_val_w=`echo x $ac_old_val` +- ac_new_val_w=`echo x $ac_new_val` +- if test "$ac_old_val_w" != "$ac_new_val_w"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} +- ac_cache_corrupted=: +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} +- eval $ac_var=\$ac_old_val +- fi +- { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +-$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +-$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} +- fi;; +- esac +- # Pass precious variables to config.status. +- if test "$ac_new_set" = set; then +- case $ac_new_val in +- *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; +- *) ac_arg=$ac_var=$ac_new_val ;; +- esac +- case " $ac_configure_args " in +- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. +- *) as_fn_append ac_configure_args " '$ac_arg'" ;; +- esac +- fi +-done +-if $ac_cache_corrupted; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} +- as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +-fi +-## -------------------- ## +-## Main body of script. ## +-## -------------------- ## +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +- +- +-ac_config_headers="$ac_config_headers src/include/config.h:src/include/config.hin" +- +- +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +-if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +-set dummy ${ac_tool_prefix}gcc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CC="${ac_tool_prefix}gcc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$ac_cv_prog_CC"; then +- ac_ct_CC=$CC +- # Extract the first word of "gcc", so it can be a program name with args. +-set dummy gcc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_CC"; then +- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_CC="gcc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_CC=$ac_cv_prog_ac_ct_CC +-if test -n "$ac_ct_CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +-$as_echo "$ac_ct_CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- if test "x$ac_ct_CC" = x; then +- CC="" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- CC=$ac_ct_CC +- fi +-else +- CC="$ac_cv_prog_CC" +-fi +- +-if test -z "$CC"; then +- if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +-set dummy ${ac_tool_prefix}cc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CC="${ac_tool_prefix}cc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- fi +-fi +-if test -z "$CC"; then +- # Extract the first word of "cc", so it can be a program name with args. +-set dummy cc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +- ac_prog_rejected=no +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then +- ac_prog_rejected=yes +- continue +- fi +- ac_cv_prog_CC="cc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-if test $ac_prog_rejected = yes; then +- # We found a bogon in the path, so make sure we never use it. +- set dummy $ac_cv_prog_CC +- shift +- if test $# != 0; then +- # We chose a different compiler from the bogus one. +- # However, it has the same basename, so the bogon will be chosen +- # first if we set CC to just the basename; use the full file name. +- shift +- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" +- fi +-fi +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$CC"; then +- if test -n "$ac_tool_prefix"; then +- for ac_prog in cl.exe +- do +- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +-set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CC="$ac_tool_prefix$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$CC" && break +- done +-fi +-if test -z "$CC"; then +- ac_ct_CC=$CC +- for ac_prog in cl.exe +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_CC"; then +- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_CC="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_CC=$ac_cv_prog_ac_ct_CC +-if test -n "$ac_ct_CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +-$as_echo "$ac_ct_CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$ac_ct_CC" && break +-done +- +- if test "x$ac_ct_CC" = x; then +- CC="" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- CC=$ac_ct_CC +- fi +-fi +- +-fi +- +- +-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "no acceptable C compiler found in \$PATH +-See \`config.log' for more details" "$LINENO" 5; } +- +-# Provide some information about the compiler. +-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +-set X $ac_compile +-ac_compiler=$2 +-for ac_option in --version -v -V -qversion; do +- { { ac_try="$ac_compiler $ac_option >&5" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_compiler $ac_option >&5") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- sed '10a\ +-... rest of stderr output deleted ... +- 10q' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- fi +- rm -f conftest.er1 conftest.err +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } +-done +- +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-ac_clean_files_save=$ac_clean_files +-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +-# Try to create an executable without -o first, disregard a.out. +-# It will help us diagnose broken compilers, and finding out an intuition +-# of exeext. +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +-$as_echo_n "checking whether the C compiler works... " >&6; } +-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +- +-# The possible output files: +-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" +- +-ac_rmfiles= +-for ac_file in $ac_files +-do +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; +- * ) ac_rmfiles="$ac_rmfiles $ac_file";; +- esac +-done +-rm -f $ac_rmfiles +- +-if { { ac_try="$ac_link_default" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link_default") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then : +- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +-# in a Makefile. We should not override ac_cv_exeext if it was cached, +-# so that the user can short-circuit this test for compilers unknown to +-# Autoconf. +-for ac_file in $ac_files '' +-do +- test -f "$ac_file" || continue +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) +- ;; +- [ab].out ) +- # We found the default executable, but exeext='' is most +- # certainly right. +- break;; +- *.* ) +- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; +- then :; else +- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` +- fi +- # We set ac_cv_exeext here because the later test for it is not +- # safe: cross compilers may not add the suffix if given an `-o' +- # argument, so we may need to know it at that point already. +- # Even if this section looks crufty: it has the advantage of +- # actually working. +- break;; +- * ) +- break;; +- esac +-done +-test "$ac_cv_exeext" = no && ac_cv_exeext= +- +-else +- ac_file='' +-fi +-if test -z "$ac_file"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-$as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error 77 "C compiler cannot create executables +-See \`config.log' for more details" "$LINENO" 5; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +-$as_echo_n "checking for C compiler default output file name... " >&6; } +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +-$as_echo "$ac_file" >&6; } +-ac_exeext=$ac_cv_exeext +- +-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +-ac_clean_files=$ac_clean_files_save +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +-$as_echo_n "checking for suffix of executables... " >&6; } +-if { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then : +- # If both `conftest.exe' and `conftest' are `present' (well, observable) +-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +-# work properly (i.e., refer to `conftest.exe'), while it won't with +-# `rm'. +-for ac_file in conftest.exe conftest conftest.*; do +- test -f "$ac_file" || continue +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; +- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` +- break;; +- * ) break;; +- esac +-done +-else +- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "cannot compute suffix of executables: cannot compile and link +-See \`config.log' for more details" "$LINENO" 5; } +-fi +-rm -f conftest conftest$ac_cv_exeext +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +-$as_echo "$ac_cv_exeext" >&6; } +- +-rm -f conftest.$ac_ext +-EXEEXT=$ac_cv_exeext +-ac_exeext=$EXEEXT +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-int +-main () +-{ +-FILE *f = fopen ("conftest.out", "w"); +- return ferror (f) || fclose (f) != 0; +- +- ; +- return 0; +-} +-_ACEOF +-ac_clean_files="$ac_clean_files conftest.out" +-# Check that the compiler produces executables we can run. If not, either +-# the compiler is broken, or we cross compile. +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +-$as_echo_n "checking whether we are cross compiling... " >&6; } +-if test "$cross_compiling" != yes; then +- { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } +- if { ac_try='./conftest$ac_cv_exeext' +- { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; }; then +- cross_compiling=no +- else +- if test "$cross_compiling" = maybe; then +- cross_compiling=yes +- else +- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "cannot run C compiled programs. +-If you meant to cross compile, use \`--host'. +-See \`config.log' for more details" "$LINENO" 5; } +- fi +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +-$as_echo "$cross_compiling" >&6; } +- +-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +-ac_clean_files=$ac_clean_files_save +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +-$as_echo_n "checking for suffix of object files... " >&6; } +-if ${ac_cv_objext+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.o conftest.obj +-if { { ac_try="$ac_compile" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_compile") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then : +- for ac_file in conftest.o conftest.obj conftest.*; do +- test -f "$ac_file" || continue; +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; +- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` +- break;; +- esac +-done +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "cannot compute suffix of object files: cannot compile +-See \`config.log' for more details" "$LINENO" 5; } +-fi +-rm -f conftest.$ac_cv_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +-$as_echo "$ac_cv_objext" >&6; } +-OBJEXT=$ac_cv_objext +-ac_objext=$OBJEXT +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +-if ${ac_cv_c_compiler_gnu+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +-#ifndef __GNUC__ +- choke me +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_compiler_gnu=yes +-else +- ac_compiler_gnu=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-ac_cv_c_compiler_gnu=$ac_compiler_gnu +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +-$as_echo "$ac_cv_c_compiler_gnu" >&6; } +-if test $ac_compiler_gnu = yes; then +- GCC=yes +-else +- GCC= +-fi +-ac_test_CFLAGS=${CFLAGS+set} +-ac_save_CFLAGS=$CFLAGS +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +-$as_echo_n "checking whether $CC accepts -g... " >&6; } +-if ${ac_cv_prog_cc_g+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_save_c_werror_flag=$ac_c_werror_flag +- ac_c_werror_flag=yes +- ac_cv_prog_cc_g=no +- CFLAGS="-g" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_prog_cc_g=yes +-else +- CFLAGS="" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- +-else +- ac_c_werror_flag=$ac_save_c_werror_flag +- CFLAGS="-g" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_prog_cc_g=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_c_werror_flag=$ac_save_c_werror_flag +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +-$as_echo "$ac_cv_prog_cc_g" >&6; } +-if test "$ac_test_CFLAGS" = set; then +- CFLAGS=$ac_save_CFLAGS +-elif test $ac_cv_prog_cc_g = yes; then +- if test "$GCC" = yes; then +- CFLAGS="-g -O2" +- else +- CFLAGS="-g" +- fi +-else +- if test "$GCC" = yes; then +- CFLAGS="-O2" +- else +- CFLAGS= +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +-if ${ac_cv_prog_cc_c89+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_cv_prog_cc_c89=no +-ac_save_CC=$CC +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-#include +-struct stat; +-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +-struct buf { int x; }; +-FILE * (*rcsopen) (struct buf *, struct stat *, int); +-static char *e (p, i) +- char **p; +- int i; +-{ +- return p[i]; +-} +-static char *f (char * (*g) (char **, int), char **p, ...) +-{ +- char *s; +- va_list v; +- va_start (v,p); +- s = g (p, va_arg (v,int)); +- va_end (v); +- return s; +-} +- +-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has +- function prototypes and stuff, but not '\xHH' hex character constants. +- These don't provoke an error unfortunately, instead are silently treated +- as 'x'. The following induces an error, until -std is added to get +- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an +- array size at least. It's necessary to write '\x00'==0 to get something +- that's true only with -std. */ +-int osf4_cc_array ['\x00' == 0 ? 1 : -1]; +- +-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters +- inside strings and character constants. */ +-#define FOO(x) 'x' +-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; +- +-int test (int i, double x); +-struct s1 {int (*f) (int a);}; +-struct s2 {int (*f) (double a);}; +-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +-int argc; +-char **argv; +-int +-main () +-{ +-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; +- ; +- return 0; +-} +-_ACEOF +-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ +- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +-do +- CC="$ac_save_CC $ac_arg" +- if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_prog_cc_c89=$ac_arg +-fi +-rm -f core conftest.err conftest.$ac_objext +- test "x$ac_cv_prog_cc_c89" != "xno" && break +-done +-rm -f conftest.$ac_ext +-CC=$ac_save_CC +- +-fi +-# AC_CACHE_VAL +-case "x$ac_cv_prog_cc_c89" in +- x) +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +-$as_echo "none needed" >&6; } ;; +- xno) +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +-$as_echo "unsupported" >&6; } ;; +- *) +- CC="$CC $ac_cv_prog_cc_c89" +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +-esac +-if test "x$ac_cv_prog_cc_c89" != xno; then : +- +-fi +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +-$as_echo_n "checking how to run the C preprocessor... " >&6; } +-# On Suns, sometimes $CPP names a directory. +-if test -n "$CPP" && test -d "$CPP"; then +- CPP= +-fi +-if test -z "$CPP"; then +- if ${ac_cv_prog_CPP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- # Double quotes because CPP needs to be expanded +- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" +- do +- ac_preproc_ok=false +-for ac_c_preproc_warn_flag in '' yes +-do +- # Use a header file that comes with gcc, so configuring glibc +- # with a fresh cross-compiler works. +- # Prefer to if __STDC__ is defined, since +- # exists even on freestanding compilers. +- # On the NeXT, cc -E runs the code through the compiler's parser, +- # not just through cpp. "Syntax error" is here to catch this case. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#ifdef __STDC__ +-# include +-#else +-# include +-#endif +- Syntax error +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- +-else +- # Broken: fails on valid input. +-continue +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +- # OK, works on sane cases. Now check whether nonexistent headers +- # can be detected and how. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- # Broken: success on invalid input. +-continue +-else +- # Passes both tests. +-ac_preproc_ok=: +-break +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +-done +-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +-rm -f conftest.i conftest.err conftest.$ac_ext +-if $ac_preproc_ok; then : +- break +-fi +- +- done +- ac_cv_prog_CPP=$CPP +- +-fi +- CPP=$ac_cv_prog_CPP +-else +- ac_cv_prog_CPP=$CPP +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +-$as_echo "$CPP" >&6; } +-ac_preproc_ok=false +-for ac_c_preproc_warn_flag in '' yes +-do +- # Use a header file that comes with gcc, so configuring glibc +- # with a fresh cross-compiler works. +- # Prefer to if __STDC__ is defined, since +- # exists even on freestanding compilers. +- # On the NeXT, cc -E runs the code through the compiler's parser, +- # not just through cpp. "Syntax error" is here to catch this case. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#ifdef __STDC__ +-# include +-#else +-# include +-#endif +- Syntax error +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- +-else +- # Broken: fails on valid input. +-continue +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +- # OK, works on sane cases. Now check whether nonexistent headers +- # can be detected and how. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- # Broken: success on invalid input. +-continue +-else +- # Passes both tests. +-ac_preproc_ok=: +-break +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +-done +-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +-rm -f conftest.i conftest.err conftest.$ac_ext +-if $ac_preproc_ok; then : +- +-else +- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +-See \`config.log' for more details" "$LINENO" 5; } +-fi +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +-$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +-if ${ac_cv_path_GREP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -z "$GREP"; then +- ac_path_GREP_found=false +- # Loop through the user's path and test for each of PROGNAME-LIST +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_prog in grep ggrep; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" +- as_fn_executable_p "$ac_path_GREP" || continue +-# Check for GNU ac_path_GREP and select it if it is found. +- # Check for GNU $ac_path_GREP +-case `"$ac_path_GREP" --version 2>&1` in +-*GNU*) +- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +-*) +- ac_count=0 +- $as_echo_n 0123456789 >"conftest.in" +- while : +- do +- cat "conftest.in" "conftest.in" >"conftest.tmp" +- mv "conftest.tmp" "conftest.in" +- cp "conftest.in" "conftest.nl" +- $as_echo 'GREP' >> "conftest.nl" +- "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break +- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break +- as_fn_arith $ac_count + 1 && ac_count=$as_val +- if test $ac_count -gt ${ac_path_GREP_max-0}; then +- # Best one so far, save it but keep looking for a better one +- ac_cv_path_GREP="$ac_path_GREP" +- ac_path_GREP_max=$ac_count +- fi +- # 10*(2^10) chars as input seems more than enough +- test $ac_count -gt 10 && break +- done +- rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +-esac +- +- $ac_path_GREP_found && break 3 +- done +- done +- done +-IFS=$as_save_IFS +- if test -z "$ac_cv_path_GREP"; then +- as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 +- fi +-else +- ac_cv_path_GREP=$GREP +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +-$as_echo "$ac_cv_path_GREP" >&6; } +- GREP="$ac_cv_path_GREP" +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +-$as_echo_n "checking for egrep... " >&6; } +-if ${ac_cv_path_EGREP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 +- then ac_cv_path_EGREP="$GREP -E" +- else +- if test -z "$EGREP"; then +- ac_path_EGREP_found=false +- # Loop through the user's path and test for each of PROGNAME-LIST +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_prog in egrep; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" +- as_fn_executable_p "$ac_path_EGREP" || continue +-# Check for GNU ac_path_EGREP and select it if it is found. +- # Check for GNU $ac_path_EGREP +-case `"$ac_path_EGREP" --version 2>&1` in +-*GNU*) +- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +-*) +- ac_count=0 +- $as_echo_n 0123456789 >"conftest.in" +- while : +- do +- cat "conftest.in" "conftest.in" >"conftest.tmp" +- mv "conftest.tmp" "conftest.in" +- cp "conftest.in" "conftest.nl" +- $as_echo 'EGREP' >> "conftest.nl" +- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break +- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break +- as_fn_arith $ac_count + 1 && ac_count=$as_val +- if test $ac_count -gt ${ac_path_EGREP_max-0}; then +- # Best one so far, save it but keep looking for a better one +- ac_cv_path_EGREP="$ac_path_EGREP" +- ac_path_EGREP_max=$ac_count +- fi +- # 10*(2^10) chars as input seems more than enough +- test $ac_count -gt 10 && break +- done +- rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +-esac +- +- $ac_path_EGREP_found && break 3 +- done +- done +- done +-IFS=$as_save_IFS +- if test -z "$ac_cv_path_EGREP"; then +- as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 +- fi +-else +- ac_cv_path_EGREP=$EGREP +-fi +- +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +-$as_echo "$ac_cv_path_EGREP" >&6; } +- EGREP="$ac_cv_path_EGREP" +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +-$as_echo_n "checking for ANSI C header files... " >&6; } +-if ${ac_cv_header_stdc+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-#include +-#include +-#include +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_header_stdc=yes +-else +- ac_cv_header_stdc=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-if test $ac_cv_header_stdc = yes; then +- # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-_ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "memchr" >/dev/null 2>&1; then : +- +-else +- ac_cv_header_stdc=no +-fi +-rm -f conftest* +- +-fi +- +-if test $ac_cv_header_stdc = yes; then +- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-_ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "free" >/dev/null 2>&1; then : +- +-else +- ac_cv_header_stdc=no +-fi +-rm -f conftest* +- +-fi +- +-if test $ac_cv_header_stdc = yes; then +- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +- if test "$cross_compiling" = yes; then : +- : +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-#include +-#if ((' ' & 0x0FF) == 0x020) +-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +-#else +-# define ISLOWER(c) \ +- (('a' <= (c) && (c) <= 'i') \ +- || ('j' <= (c) && (c) <= 'r') \ +- || ('s' <= (c) && (c) <= 'z')) +-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +-#endif +- +-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +-int +-main () +-{ +- int i; +- for (i = 0; i < 256; i++) +- if (XOR (islower (i), ISLOWER (i)) +- || toupper (i) != TOUPPER (i)) +- return 2; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- +-else +- ac_cv_header_stdc=no +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +-fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +-$as_echo "$ac_cv_header_stdc" >&6; } +-if test $ac_cv_header_stdc = yes; then +- +-$as_echo "#define STDC_HEADERS 1" >>confdefs.h +- +-fi +- +-# On IRIX 5.3, sys/types and inttypes.h are conflicting. +-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ +- inttypes.h stdint.h unistd.h +-do : +- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +-" +-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +-_ACEOF +- +-fi +- +-done +- +- +- +- ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +-if test "x$ac_cv_header_minix_config_h" = xyes; then : +- MINIX=yes +-else +- MINIX= +-fi +- +- +- if test "$MINIX" = yes; then +- +-$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h +- +- +-$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h +- +- +-$as_echo "#define _MINIX 1" >>confdefs.h +- +- fi +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +-$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +-if ${ac_cv_safe_to_define___extensions__+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-# define __EXTENSIONS__ 1 +- $ac_includes_default +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_safe_to_define___extensions__=yes +-else +- ac_cv_safe_to_define___extensions__=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +-$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } +- test $ac_cv_safe_to_define___extensions__ = yes && +- $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h +- +- $as_echo "#define _ALL_SOURCE 1" >>confdefs.h +- +- $as_echo "#define _GNU_SOURCE 1" >>confdefs.h +- +- $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h +- +- $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h +- +- +- +-# checks for programs +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +-if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +-set dummy ${ac_tool_prefix}gcc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CC="${ac_tool_prefix}gcc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$ac_cv_prog_CC"; then +- ac_ct_CC=$CC +- # Extract the first word of "gcc", so it can be a program name with args. +-set dummy gcc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_CC"; then +- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_CC="gcc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_CC=$ac_cv_prog_ac_ct_CC +-if test -n "$ac_ct_CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +-$as_echo "$ac_ct_CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- if test "x$ac_ct_CC" = x; then +- CC="" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- CC=$ac_ct_CC +- fi +-else +- CC="$ac_cv_prog_CC" +-fi +- +-if test -z "$CC"; then +- if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +-set dummy ${ac_tool_prefix}cc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CC="${ac_tool_prefix}cc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- fi +-fi +-if test -z "$CC"; then +- # Extract the first word of "cc", so it can be a program name with args. +-set dummy cc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +- ac_prog_rejected=no +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then +- ac_prog_rejected=yes +- continue +- fi +- ac_cv_prog_CC="cc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-if test $ac_prog_rejected = yes; then +- # We found a bogon in the path, so make sure we never use it. +- set dummy $ac_cv_prog_CC +- shift +- if test $# != 0; then +- # We chose a different compiler from the bogus one. +- # However, it has the same basename, so the bogon will be chosen +- # first if we set CC to just the basename; use the full file name. +- shift +- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" +- fi +-fi +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$CC"; then +- if test -n "$ac_tool_prefix"; then +- for ac_prog in cl.exe +- do +- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +-set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CC="$ac_tool_prefix$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$CC" && break +- done +-fi +-if test -z "$CC"; then +- ac_ct_CC=$CC +- for ac_prog in cl.exe +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_CC"; then +- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_CC="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_CC=$ac_cv_prog_ac_ct_CC +-if test -n "$ac_ct_CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +-$as_echo "$ac_ct_CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$ac_ct_CC" && break +-done +- +- if test "x$ac_ct_CC" = x; then +- CC="" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- CC=$ac_ct_CC +- fi +-fi +- +-fi +- +- +-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "no acceptable C compiler found in \$PATH +-See \`config.log' for more details" "$LINENO" 5; } +- +-# Provide some information about the compiler. +-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +-set X $ac_compile +-ac_compiler=$2 +-for ac_option in --version -v -V -qversion; do +- { { ac_try="$ac_compiler $ac_option >&5" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_compiler $ac_option >&5") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- sed '10a\ +-... rest of stderr output deleted ... +- 10q' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- fi +- rm -f conftest.er1 conftest.err +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } +-done +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +-if ${ac_cv_c_compiler_gnu+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +-#ifndef __GNUC__ +- choke me +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_compiler_gnu=yes +-else +- ac_compiler_gnu=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-ac_cv_c_compiler_gnu=$ac_compiler_gnu +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +-$as_echo "$ac_cv_c_compiler_gnu" >&6; } +-if test $ac_compiler_gnu = yes; then +- GCC=yes +-else +- GCC= +-fi +-ac_test_CFLAGS=${CFLAGS+set} +-ac_save_CFLAGS=$CFLAGS +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +-$as_echo_n "checking whether $CC accepts -g... " >&6; } +-if ${ac_cv_prog_cc_g+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_save_c_werror_flag=$ac_c_werror_flag +- ac_c_werror_flag=yes +- ac_cv_prog_cc_g=no +- CFLAGS="-g" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_prog_cc_g=yes +-else +- CFLAGS="" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- +-else +- ac_c_werror_flag=$ac_save_c_werror_flag +- CFLAGS="-g" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_prog_cc_g=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_c_werror_flag=$ac_save_c_werror_flag +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +-$as_echo "$ac_cv_prog_cc_g" >&6; } +-if test "$ac_test_CFLAGS" = set; then +- CFLAGS=$ac_save_CFLAGS +-elif test $ac_cv_prog_cc_g = yes; then +- if test "$GCC" = yes; then +- CFLAGS="-g -O2" +- else +- CFLAGS="-g" +- fi +-else +- if test "$GCC" = yes; then +- CFLAGS="-O2" +- else +- CFLAGS= +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +-if ${ac_cv_prog_cc_c89+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_cv_prog_cc_c89=no +-ac_save_CC=$CC +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-#include +-struct stat; +-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +-struct buf { int x; }; +-FILE * (*rcsopen) (struct buf *, struct stat *, int); +-static char *e (p, i) +- char **p; +- int i; +-{ +- return p[i]; +-} +-static char *f (char * (*g) (char **, int), char **p, ...) +-{ +- char *s; +- va_list v; +- va_start (v,p); +- s = g (p, va_arg (v,int)); +- va_end (v); +- return s; +-} +- +-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has +- function prototypes and stuff, but not '\xHH' hex character constants. +- These don't provoke an error unfortunately, instead are silently treated +- as 'x'. The following induces an error, until -std is added to get +- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an +- array size at least. It's necessary to write '\x00'==0 to get something +- that's true only with -std. */ +-int osf4_cc_array ['\x00' == 0 ? 1 : -1]; +- +-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters +- inside strings and character constants. */ +-#define FOO(x) 'x' +-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; +- +-int test (int i, double x); +-struct s1 {int (*f) (int a);}; +-struct s2 {int (*f) (double a);}; +-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +-int argc; +-char **argv; +-int +-main () +-{ +-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; +- ; +- return 0; +-} +-_ACEOF +-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ +- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +-do +- CC="$ac_save_CC $ac_arg" +- if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_prog_cc_c89=$ac_arg +-fi +-rm -f core conftest.err conftest.$ac_objext +- test "x$ac_cv_prog_cc_c89" != "xno" && break +-done +-rm -f conftest.$ac_ext +-CC=$ac_save_CC +- +-fi +-# AC_CACHE_VAL +-case "x$ac_cv_prog_cc_c89" in +- x) +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +-$as_echo "none needed" >&6; } ;; +- xno) +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +-$as_echo "unsupported" >&6; } ;; +- *) +- CC="$CC $ac_cv_prog_cc_c89" +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +-esac +-if test "x$ac_cv_prog_cc_c89" != xno; then : +- +-fi +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +-if test -z "$CXX"; then +- if test -n "$CCC"; then +- CXX=$CCC +- else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +- do +- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +-set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CXX+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CXX"; then +- ac_cv_prog_CXX="$CXX" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CXX=$ac_cv_prog_CXX +-if test -n "$CXX"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +-$as_echo "$CXX" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$CXX" && break +- done +-fi +-if test -z "$CXX"; then +- ac_ct_CXX=$CXX +- for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_CXX+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_CXX"; then +- ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_CXX="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +-if test -n "$ac_ct_CXX"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +-$as_echo "$ac_ct_CXX" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$ac_ct_CXX" && break +-done +- +- if test "x$ac_ct_CXX" = x; then +- CXX="g++" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- CXX=$ac_ct_CXX +- fi +-fi +- +- fi +-fi +-# Provide some information about the compiler. +-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +-set X $ac_compile +-ac_compiler=$2 +-for ac_option in --version -v -V -qversion; do +- { { ac_try="$ac_compiler $ac_option >&5" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_compiler $ac_option >&5") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- sed '10a\ +-... rest of stderr output deleted ... +- 10q' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- fi +- rm -f conftest.er1 conftest.err +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } +-done +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +-$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +-if ${ac_cv_cxx_compiler_gnu+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +-#ifndef __GNUC__ +- choke me +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- ac_compiler_gnu=yes +-else +- ac_compiler_gnu=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-ac_cv_cxx_compiler_gnu=$ac_compiler_gnu +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +-$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +-if test $ac_compiler_gnu = yes; then +- GXX=yes +-else +- GXX= +-fi +-ac_test_CXXFLAGS=${CXXFLAGS+set} +-ac_save_CXXFLAGS=$CXXFLAGS +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +-$as_echo_n "checking whether $CXX accepts -g... " >&6; } +-if ${ac_cv_prog_cxx_g+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_save_cxx_werror_flag=$ac_cxx_werror_flag +- ac_cxx_werror_flag=yes +- ac_cv_prog_cxx_g=no +- CXXFLAGS="-g" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- ac_cv_prog_cxx_g=yes +-else +- CXXFLAGS="" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- +-else +- ac_cxx_werror_flag=$ac_save_cxx_werror_flag +- CXXFLAGS="-g" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- ac_cv_prog_cxx_g=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_cxx_werror_flag=$ac_save_cxx_werror_flag +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +-$as_echo "$ac_cv_prog_cxx_g" >&6; } +-if test "$ac_test_CXXFLAGS" = set; then +- CXXFLAGS=$ac_save_CXXFLAGS +-elif test $ac_cv_prog_cxx_g = yes; then +- if test "$GXX" = yes; then +- CXXFLAGS="-g -O2" +- else +- CXXFLAGS="-g" +- fi +-else +- if test "$GXX" = yes; then +- CXXFLAGS="-O2" +- else +- CXXFLAGS= +- fi +-fi +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +- +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if test "$cross_compiling" = no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking that C++ compiler can compile simple program" >&5 +-$as_echo_n "checking that C++ compiler can compile simple program... " >&6; } +- fi +- if test "$cross_compiling" = yes; then : +- : +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-int main() { +- return 0; +-} +- +- +- +-_ACEOF +-if ac_fn_cxx_try_run "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- as_fn_error $? "a working C++ compiler is required" "$LINENO" 5 +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- +- if test "$cross_compiling" = no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking that C++ static constructors and destructors are called" >&5 +-$as_echo_n "checking that C++ static constructors and destructors are called... " >&6; } +- fi +- if test "$cross_compiling" = yes; then : +- : +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-extern "C" { +- void _exit(int); +-} +- +-int i; +-struct A { +- char dummy; +- A() { i = 1; } +- ~A() { if (i == 1) _exit(0); } +-}; +- +-A a; +- +-int main() +-{ +- return 1; +-} +- +- +- +-_ACEOF +-if ac_fn_cxx_try_run "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- as_fn_error $? "a working C++ compiler is required" "$LINENO" 5 +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking that header files support C++" >&5 +-$as_echo_n "checking that header files support C++... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +- +- +-int +-main () +-{ +- +- +-fopen(0, 0); +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_link "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- as_fn_error $? "header files do not support C++ +- (if you are using a version of gcc/g++ earlier than 2.5, +- you should install libg++)" "$LINENO" 5 +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether character set is EBCDIC" >&5 +-$as_echo_n "checking whether character set is EBCDIC... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-/* Treat any failure as ASCII for compatibility with existing art. +- Use compile-time rather than run-time tests for cross-compiler +- tolerance. */ +-#if '0' != 240 +-make an error "Character set is not EBCDIC" +-#endif +- +- +-int +-main () +-{ +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- groff_cv_ebcdic="yes" +- TTYDEVDIRS="font/devcp1047" +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define IS_EBCDIC_HOST 1" >>confdefs.h +- +-else +- groff_cv_ebcdic="no" +- TTYDEVDIRS="font/devascii font/devlatin1" +- OTHERDEVDIRS="font/devlj4 font/devlbp" +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +- +-if test "$groff_cv_ebcdic" = "yes"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OS/390 Unix" >&5 +-$as_echo_n "checking for OS/390 Unix... " >&6; } +- case `uname` in +- OS/390) +- CFLAGS="$CFLAGS -D_ALL_SOURCE" +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } ;; +- *) +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } ;; +- esac +- fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install .cmd wrapper scripts for Windows" >&5 +-$as_echo_n "checking whether to install .cmd wrapper scripts for Windows... " >&6; } +- case "$host_os" in +- *mingw*) +- make_winscripts=winscripts +- make_install_winscripts=install_winscripts +- make_uninstall_winscripts=uninstall_winscripts +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } ;; +- *) +- make_winscripts= +- make_install_winscripts= +- make_uninstall_winscripts= +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } ;; +- esac +- +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 +-$as_echo_n "checking for X... " >&6; } +- +- +-# Check whether --with-x was given. +-if test "${with_x+set}" = set; then : +- withval=$with_x; +-fi +- +-# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +-if test "x$with_x" = xno; then +- # The user explicitly disabled X. +- have_x=disabled +-else +- case $x_includes,$x_libraries in #( +- *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( +- *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- # One or both of the vars are not set, and there is no cached value. +-ac_x_includes=no ac_x_libraries=no +-rm -f -r conftest.dir +-if mkdir conftest.dir; then +- cd conftest.dir +- cat >Imakefile <<'_ACEOF' +-incroot: +- @echo incroot='${INCROOT}' +-usrlibdir: +- @echo usrlibdir='${USRLIBDIR}' +-libdir: +- @echo libdir='${LIBDIR}' +-_ACEOF +- if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then +- # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +- for ac_var in incroot usrlibdir libdir; do +- eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" +- done +- # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. +- for ac_extension in a so sl dylib la dll; do +- if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && +- test -f "$ac_im_libdir/libX11.$ac_extension"; then +- ac_im_usrlibdir=$ac_im_libdir; break +- fi +- done +- # Screen out bogus values from the imake configuration. They are +- # bogus both because they are the default anyway, and because +- # using them would break gcc on systems where it needs fixed includes. +- case $ac_im_incroot in +- /usr/include) ac_x_includes= ;; +- *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; +- esac +- case $ac_im_usrlibdir in +- /usr/lib | /usr/lib64 | /lib | /lib64) ;; +- *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; +- esac +- fi +- cd .. +- rm -f -r conftest.dir +-fi +- +-# Standard set of common directories for X headers. +-# Check X11 before X11Rn because it is often a symlink to the current release. +-ac_x_header_dirs=' +-/usr/X11/include +-/usr/X11R7/include +-/usr/X11R6/include +-/usr/X11R5/include +-/usr/X11R4/include +- +-/usr/include/X11 +-/usr/include/X11R7 +-/usr/include/X11R6 +-/usr/include/X11R5 +-/usr/include/X11R4 +- +-/usr/local/X11/include +-/usr/local/X11R7/include +-/usr/local/X11R6/include +-/usr/local/X11R5/include +-/usr/local/X11R4/include +- +-/usr/local/include/X11 +-/usr/local/include/X11R7 +-/usr/local/include/X11R6 +-/usr/local/include/X11R5 +-/usr/local/include/X11R4 +- +-/usr/X386/include +-/usr/x386/include +-/usr/XFree86/include/X11 +- +-/usr/include +-/usr/local/include +-/usr/unsupported/include +-/usr/athena/include +-/usr/local/x11r5/include +-/usr/lpp/Xamples/include +- +-/usr/openwin/include +-/usr/openwin/share/include' +- +-if test "$ac_x_includes" = no; then +- # Guess where to find include files, by looking for Xlib.h. +- # First, try using that file with no special directory specified. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- # We can compile using X headers with no special include directory. +-ac_x_includes= +-else +- for ac_dir in $ac_x_header_dirs; do +- if test -r "$ac_dir/X11/Xlib.h"; then +- ac_x_includes=$ac_dir +- break +- fi +-done +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +-fi # $ac_x_includes = no +- +-if test "$ac_x_libraries" = no; then +- # Check for the libraries. +- # See if we find them without any special options. +- # Don't add to $LIBS permanently. +- ac_save_LIBS=$LIBS +- LIBS="-lX11 $LIBS" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-int +-main () +-{ +-XrmInitialize () +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- LIBS=$ac_save_LIBS +-# We can link X programs with no special library path. +-ac_x_libraries= +-else +- LIBS=$ac_save_LIBS +-for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` +-do +- # Don't even attempt the hair of trying to link an X program! +- for ac_extension in a so sl dylib la dll; do +- if test -r "$ac_dir/libX11.$ac_extension"; then +- ac_x_libraries=$ac_dir +- break 2 +- fi +- done +-done +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-fi # $ac_x_libraries = no +- +-case $ac_x_includes,$ac_x_libraries in #( +- no,* | *,no | *\'*) +- # Didn't find X, or a directory has "'" in its name. +- ac_cv_have_x="have_x=no";; #( +- *) +- # Record where we found X for the cache. +- ac_cv_have_x="have_x=yes\ +- ac_x_includes='$ac_x_includes'\ +- ac_x_libraries='$ac_x_libraries'" +-esac +-fi +-;; #( +- *) have_x=yes;; +- esac +- eval "$ac_cv_have_x" +-fi # $with_x != no +- +-if test "$have_x" != yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 +-$as_echo "$have_x" >&6; } +- no_x=yes +-else +- # If each of the values was on the command line, it overrides each guess. +- test "x$x_includes" = xNONE && x_includes=$ac_x_includes +- test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries +- # Update the cache value to reflect the command line values. +- ac_cv_have_x="have_x=yes\ +- ac_x_includes='$x_includes'\ +- ac_x_libraries='$x_libraries'" +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 +-$as_echo "libraries $x_libraries, headers $x_includes" >&6; } +-fi +- +-if test "$no_x" = yes; then +- # Not all programs may use this symbol, but it does not hurt to define it. +- +-$as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h +- +- X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +-else +- if test -n "$x_includes"; then +- X_CFLAGS="$X_CFLAGS -I$x_includes" +- fi +- +- # It would also be nice to do this for all -L options, not just this one. +- if test -n "$x_libraries"; then +- X_LIBS="$X_LIBS -L$x_libraries" +- # For Solaris; some versions of Sun CC require a space after -R and +- # others require no space. Words are not sufficient . . . . +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 +-$as_echo_n "checking whether -R must be followed by a space... " >&6; } +- ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" +- ac_xsave_c_werror_flag=$ac_c_werror_flag +- ac_c_werror_flag=yes +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- X_LIBS="$X_LIBS -R$x_libraries" +-else +- LIBS="$ac_xsave_LIBS -R $x_libraries" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- X_LIBS="$X_LIBS -R $x_libraries" +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 +-$as_echo "neither works" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- ac_c_werror_flag=$ac_xsave_c_werror_flag +- LIBS=$ac_xsave_LIBS +- fi +- +- # Check for system-dependent libraries X programs must link with. +- # Do this before checking for the system-independent R6 libraries +- # (-lICE), since we may need -lsocket or whatever for X linking. +- +- if test "$ISC" = yes; then +- X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" +- else +- # Martyn Johnson says this is needed for Ultrix, if the X +- # libraries were built with DECnet support. And Karl Berry says +- # the Alpha needs dnet_stub (dnet does not exist). +- ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char XOpenDisplay (); +-int +-main () +-{ +-return XOpenDisplay (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 +-$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } +-if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-ldnet $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char dnet_ntoa (); +-int +-main () +-{ +-return dnet_ntoa (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_dnet_dnet_ntoa=yes +-else +- ac_cv_lib_dnet_dnet_ntoa=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 +-$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } +-if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : +- X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +-fi +- +- if test $ac_cv_lib_dnet_dnet_ntoa = no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 +-$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } +-if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-ldnet_stub $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char dnet_ntoa (); +-int +-main () +-{ +-return dnet_ntoa (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_dnet_stub_dnet_ntoa=yes +-else +- ac_cv_lib_dnet_stub_dnet_ntoa=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 +-$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } +-if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : +- X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +-fi +- +- fi +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- LIBS="$ac_xsave_LIBS" +- +- # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, +- # to get the SysV transport functions. +- # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) +- # needs -lnsl. +- # The nsl library prevents programs from opening the X display +- # on Irix 5.2, according to T.E. Dickey. +- # The functions gethostbyname, getservbyname, and inet_addr are +- # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. +- ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +-if test "x$ac_cv_func_gethostbyname" = xyes; then : +- +-fi +- +- if test $ac_cv_func_gethostbyname = no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +-$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +-if ${ac_cv_lib_nsl_gethostbyname+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-lnsl $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char gethostbyname (); +-int +-main () +-{ +-return gethostbyname (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_nsl_gethostbyname=yes +-else +- ac_cv_lib_nsl_gethostbyname=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +-$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +-if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : +- X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +-fi +- +- if test $ac_cv_lib_nsl_gethostbyname = no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 +-$as_echo_n "checking for gethostbyname in -lbsd... " >&6; } +-if ${ac_cv_lib_bsd_gethostbyname+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-lbsd $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char gethostbyname (); +-int +-main () +-{ +-return gethostbyname (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_bsd_gethostbyname=yes +-else +- ac_cv_lib_bsd_gethostbyname=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 +-$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } +-if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : +- X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" +-fi +- +- fi +- fi +- +- # lieder@skyler.mavd.honeywell.com says without -lsocket, +- # socket/setsockopt and other routines are undefined under SCO ODT +- # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary +- # on later versions), says Simon Leinen: it contains gethostby* +- # variants that don't use the name server (or something). -lsocket +- # must be given before -lnsl if both are needed. We assume that +- # if connect needs -lnsl, so does gethostbyname. +- ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" +-if test "x$ac_cv_func_connect" = xyes; then : +- +-fi +- +- if test $ac_cv_func_connect = no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 +-$as_echo_n "checking for connect in -lsocket... " >&6; } +-if ${ac_cv_lib_socket_connect+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-lsocket $X_EXTRA_LIBS $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char connect (); +-int +-main () +-{ +-return connect (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_socket_connect=yes +-else +- ac_cv_lib_socket_connect=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 +-$as_echo "$ac_cv_lib_socket_connect" >&6; } +-if test "x$ac_cv_lib_socket_connect" = xyes; then : +- X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +-fi +- +- fi +- +- # Guillermo Gomez says -lposix is necessary on A/UX. +- ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" +-if test "x$ac_cv_func_remove" = xyes; then : +- +-fi +- +- if test $ac_cv_func_remove = no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 +-$as_echo_n "checking for remove in -lposix... " >&6; } +-if ${ac_cv_lib_posix_remove+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-lposix $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char remove (); +-int +-main () +-{ +-return remove (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_posix_remove=yes +-else +- ac_cv_lib_posix_remove=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 +-$as_echo "$ac_cv_lib_posix_remove" >&6; } +-if test "x$ac_cv_lib_posix_remove" = xyes; then : +- X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +-fi +- +- fi +- +- # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. +- ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" +-if test "x$ac_cv_func_shmat" = xyes; then : +- +-fi +- +- if test $ac_cv_func_shmat = no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 +-$as_echo_n "checking for shmat in -lipc... " >&6; } +-if ${ac_cv_lib_ipc_shmat+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-lipc $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char shmat (); +-int +-main () +-{ +-return shmat (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_ipc_shmat=yes +-else +- ac_cv_lib_ipc_shmat=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 +-$as_echo "$ac_cv_lib_ipc_shmat" >&6; } +-if test "x$ac_cv_lib_ipc_shmat" = xyes; then : +- X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" +-fi +- +- fi +- fi +- +- # Check for libraries that X11R6 Xt/Xaw programs need. +- ac_save_LDFLAGS=$LDFLAGS +- test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" +- # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to +- # check for ICE first), but we must link in the order -lSM -lICE or +- # we get undefined symbols. So assume we have SM if we have ICE. +- # These have to be linked with before -lX11, unlike the other +- # libraries we check for below, so use a different variable. +- # John Interrante, Karl Berry +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 +-$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } +-if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-lICE $X_EXTRA_LIBS $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char IceConnectionNumber (); +-int +-main () +-{ +-return IceConnectionNumber (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_ICE_IceConnectionNumber=yes +-else +- ac_cv_lib_ICE_IceConnectionNumber=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 +-$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } +-if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : +- X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +-fi +- +- LDFLAGS=$ac_save_LDFLAGS +- +-fi +- +- +- groff_no_x=$no_x +- if test -z "$groff_no_x"; then +- OLDCFLAGS=$CFLAGS +- OLDLDFLAGS=$LDFLAGS +- OLDLIBS=$LIBS +- CFLAGS="$CFLAGS $X_CFLAGS" +- LDFLAGS="$LDFLAGS $X_LIBS" +- LIBS="$LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" +- +- LIBS="$LIBS -lXaw" +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Xaw library and header files" >&5 +-$as_echo_n "checking for Xaw library and header files... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#include +- +- +-int +-main () +-{ +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- groff_no_x="yes" +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- LIBS="$LIBS -lXmu" +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Xmu library and header files" >&5 +-$as_echo_n "checking for Xmu library and header files... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#include +- +- +-int +-main () +-{ +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- groff_no_x="yes" +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +- CFLAGS=$OLDCFLAGS +- LDFLAGS=$OLDLDFLAGS +- LIBS=$OLDLIBS +- fi +- +- if test "x$groff_no_x" = "xyes"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: gxditview and xtotroff won't be built" >&5 +-$as_echo "$as_me: gxditview and xtotroff won't be built" >&6;} +- else +- XDEVDIRS="font/devX75 font/devX75-12 font/devX100 font/devX100-12" +- XPROGDIRS="src/devices/xditview src/utils/xtotroff" +- XLIBDIRS="src/libs/libxutil" +- fi +- +- +- +- +- +-# Check whether --with-appresdir was given. +-if test "${with_appresdir+set}" = set; then : +- withval=$with_appresdir; +-fi +- +-if test -z "$groff_no_x"; then +- if test "x$with_appresdir" = "x"; then +- if test "x$prefix" = "xNONE"; then +- appresdir=$ac_default_prefix/lib/X11/app-defaults +- else +- appresdir=$prefix/lib/X11/app-defaults +- fi +- else +- appresdir=$with_appresdir +- fi +- fi +- +-libprogramdir=$libdir/groff +- +- +-# Check whether --with-grofferdir was given. +-if test "${with_grofferdir+set}" = set; then : +- withval=$with_grofferdir; +-fi +- +-if test "x$with_grofferdir" = "x"; then +- groffer_dir=$libprogramdir/groffer +- else +- groffer_dir=$with_grofferdir +- fi +- +-glilypond_dir=$libprogramdir/glilypond +- +-gpinyin_dir=$libprogramdir/gpinyin +- +-grog_dir=$libprogramdir/grog +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +-$as_echo_n "checking for a sed that does not truncate output... " >&6; } +-if ${ac_cv_path_SED+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ +- for ac_i in 1 2 3 4 5 6 7; do +- ac_script="$ac_script$as_nl$ac_script" +- done +- echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed +- { ac_script=; unset ac_script;} +- if test -z "$SED"; then +- ac_path_SED_found=false +- # Loop through the user's path and test for each of PROGNAME-LIST +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_prog in sed gsed; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" +- as_fn_executable_p "$ac_path_SED" || continue +-# Check for GNU ac_path_SED and select it if it is found. +- # Check for GNU $ac_path_SED +-case `"$ac_path_SED" --version 2>&1` in +-*GNU*) +- ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +-*) +- ac_count=0 +- $as_echo_n 0123456789 >"conftest.in" +- while : +- do +- cat "conftest.in" "conftest.in" >"conftest.tmp" +- mv "conftest.tmp" "conftest.in" +- cp "conftest.in" "conftest.nl" +- $as_echo '' >> "conftest.nl" +- "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break +- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break +- as_fn_arith $ac_count + 1 && ac_count=$as_val +- if test $ac_count -gt ${ac_path_SED_max-0}; then +- # Best one so far, save it but keep looking for a better one +- ac_cv_path_SED="$ac_path_SED" +- ac_path_SED_max=$ac_count +- fi +- # 10*(2^10) chars as input seems more than enough +- test $ac_count -gt 10 && break +- done +- rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +-esac +- +- $ac_path_SED_found && break 3 +- done +- done +- done +-IFS=$as_save_IFS +- if test -z "$ac_cv_path_SED"; then +- as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 +- fi +-else +- ac_cv_path_SED=$SED +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +-$as_echo "$ac_cv_path_SED" >&6; } +- SED="$ac_cv_path_SED" +- rm -f conftest.sed +- +-for ac_prog in gawk mawk nawk awk +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_AWK+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$AWK"; then +- ac_cv_prog_AWK="$AWK" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_AWK="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-AWK=$ac_cv_prog_AWK +-if test -n "$AWK"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +-$as_echo "$AWK" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$AWK" && break +-done +- +-PERLVERSION=v5.6.1 +- # Extract the first word of "perl", so it can be a program name with args. +-set dummy perl; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_path_PERL+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- case $PERL in +- [\\/]* | ?:[\\/]*) +- ac_cv_path_PERL="$PERL" # Let the user override the test with a path. +- ;; +- *) +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="no" +- ;; +-esac +-fi +-PERL=$ac_cv_path_PERL +-if test -n "$PERL"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 +-$as_echo "$PERL" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- if test "x$PERL" = "xno"; then +- as_fn_error 1 "perl binary not found" "$LINENO" 5 +- fi +- +- +- +- +- if test -n "$PERL"; then : +- +- ax_perl_version="$PERLVERSION" +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for perl version" >&5 +-$as_echo_n "checking for perl version... " >&6; } +- +- perl_version=`$PERL --version 2>&1 \ +- | $SED -n -e '/This is perl/b inspect +-b +-: inspect +-s/.* (\{0,1\}v\([0-9]*\.[0-9]*\.[0-9]*\))\{0,1\} .*/\1/;p'` +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $perl_version" >&5 +-$as_echo "$perl_version" >&6; } +- +- PERL_VERSION=$perl_version +- +- +- +- +- +- # Used to indicate true or false condition +- ax_compare_version=false +- +- # Convert the two version strings to be compared into a format that +- # allows a simple string comparison. The end result is that a version +- # string of the form 1.12.5-r617 will be converted to the form +- # 0001001200050617. In other words, each number is zero padded to four +- # digits, and non digits are removed. +- +- ax_compare_version_A=`echo "$ax_perl_version" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ +- -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ +- -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ +- -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ +- -e 's/[^0-9]//g'` +- +- +- ax_compare_version_B=`echo "$perl_version" | sed -e 's/\([0-9]*\)/Z\1Z/g' \ +- -e 's/Z\([0-9]\)Z/Z0\1Z/g' \ +- -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \ +- -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \ +- -e 's/[^0-9]//g'` +- +- +- ax_compare_version=`echo "x$ax_compare_version_A +-x$ax_compare_version_B" | sed 's/^ *//' | sort | sed "s/x${ax_compare_version_A}/true/;s/x${ax_compare_version_B}/false/;1q"` +- +- +- +- if test "$ax_compare_version" = "true" ; then +- +- : +- true +- +- else +- : +- \ +- as_fn_error 1 "perl version is too old" "$LINENO" 5 +- +- fi +- +- +-else +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find the perl interpreter" >&5 +-$as_echo "$as_me: WARNING: could not find the perl interpreter" >&2;} +- \ +- as_fn_error 1 "perl version is too old" "$LINENO" 5 +- +-fi +- +-if test -z "$PSPRINT"; then +- for ac_prog in lpr +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_LPR+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$LPR"; then +- ac_cv_prog_LPR="$LPR" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_LPR="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-LPR=$ac_cv_prog_LPR +-if test -n "$LPR"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LPR" >&5 +-$as_echo "$LPR" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$LPR" && break +-done +- +- for ac_prog in lp +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_LP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$LP"; then +- ac_cv_prog_LP="$LP" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_LP="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-LP=$ac_cv_prog_LP +-if test -n "$LP"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LP" >&5 +-$as_echo "$LP" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$LP" && break +-done +- +- if test -n "$LPR" && test -n "$LP"; then +- # HP-UX provides an lpr command that emulates lpr using lp, +- # but it doesn't have lpq; in this case we want to use lp +- # rather than lpr. +- for ac_prog in lpq +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_LPQ+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$LPQ"; then +- ac_cv_prog_LPQ="$LPQ" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_LPQ="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-LPQ=$ac_cv_prog_LPQ +-if test -n "$LPQ"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LPQ" >&5 +-$as_echo "$LPQ" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$LPQ" && break +-done +- +- test -n "$LPQ" || LPR= +- fi +- if test -n "$LPR"; then +- PSPRINT="$LPR" +- elif test -n "$LP"; then +- PSPRINT="$LP" +- fi +- fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for command to use for printing PostScript files" >&5 +-$as_echo_n "checking for command to use for printing PostScript files... " >&6; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PSPRINT" >&5 +-$as_echo "$PSPRINT" >&6; } +- +- # Figure out DVIPRINT from PSPRINT. +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for command to use for printing dvi files" >&5 +-$as_echo_n "checking for command to use for printing dvi files... " >&6; } +- if test -n "$PSPRINT" && test -z "$DVIPRINT"; then +- if test "x$PSPRINT" = "xlpr"; then +- DVIPRINT="lpr -d" +- else +- DVIPRINT="$PSPRINT" +- fi +- fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DVIPRINT" >&5 +-$as_echo "$DVIPRINT" >&6; } +-# GROFF_REFER +-referdir=$libprogramdir/refer +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +-$as_echo_n "checking for egrep... " >&6; } +-if ${ac_cv_path_EGREP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 +- then ac_cv_path_EGREP="$GREP -E" +- else +- if test -z "$EGREP"; then +- ac_path_EGREP_found=false +- # Loop through the user's path and test for each of PROGNAME-LIST +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_prog in egrep; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" +- as_fn_executable_p "$ac_path_EGREP" || continue +-# Check for GNU ac_path_EGREP and select it if it is found. +- # Check for GNU $ac_path_EGREP +-case `"$ac_path_EGREP" --version 2>&1` in +-*GNU*) +- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +-*) +- ac_count=0 +- $as_echo_n 0123456789 >"conftest.in" +- while : +- do +- cat "conftest.in" "conftest.in" >"conftest.tmp" +- mv "conftest.tmp" "conftest.in" +- cp "conftest.in" "conftest.nl" +- $as_echo 'EGREP' >> "conftest.nl" +- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break +- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break +- as_fn_arith $ac_count + 1 && ac_count=$as_val +- if test $ac_count -gt ${ac_path_EGREP_max-0}; then +- # Best one so far, save it but keep looking for a better one +- ac_cv_path_EGREP="$ac_path_EGREP" +- ac_path_EGREP_max=$ac_count +- fi +- # 10*(2^10) chars as input seems more than enough +- test $ac_count -gt 10 && break +- done +- rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +-esac +- +- $ac_path_EGREP_found && break 3 +- done +- done +- done +-IFS=$as_save_IFS +- if test -z "$ac_cv_path_EGREP"; then +- as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 +- fi +-else +- ac_cv_path_EGREP=$EGREP +-fi +- +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +-$as_echo "$ac_cv_path_EGREP" >&6; } +- EGREP="$ac_cv_path_EGREP" +- +- +-for ac_prog in byacc 'bison -y' +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_YACC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$YACC"; then +- ac_cv_prog_YACC="$YACC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_YACC="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-YACC=$ac_cv_prog_YACC +-if test -n "$YACC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5 +-$as_echo "$YACC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$YACC" && break +-done +-test -n "$YACC" || YACC="yacc" +- +- +-# Check whether --with-doc was given. +-if test "${with_doc+set}" = set; then : +- withval=$with_doc; doc="$withval" +-else +- doc=yes +-fi +- +- test "x$doc" = xno && doc='' +- if test "x$doc" = xyes; then +- doc_dist_target_ok=yes +- docadd_html=yes +- docadd_info=yes +- docadd_other=yes +- docadd_pdf=yes +- docadd_examples=yes +- else +- # Don't use case/esac, verify input. +- doc_dist_target_ok=no +- docadd_html=no +- docadd_info=no +- docadd_other=no +- docadd_pdf=no +- docadd_examples=no +- OFS=$IFS +- IFS=',' +- set -- $doc +- IFS=$OFS +- for i +- do +- test "x$i" = xhtml && { docadd_html=yes; continue; } +- test "x$i" = xinfo && { docadd_info=yes; continue; } +- test "x$i" = xother && { docadd_other=yes; continue; } +- test "x$i" = xpdf && { docadd_pdf=yes; continue; } +- test "x$i" = xexamples && { docadd_examples=yes; continue; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Invalid \`--with-doc' argument: $i" >&5 +-$as_echo "$as_me: WARNING: Invalid \`--with-doc' argument: $i" >&2;} +- done +- fi +- if test $docadd_html = yes; then +- make_install_shipped_htmldoc=install_shipped_htmldoc +- make_uninstall_shipped_htmldoc=uninstall_shipped_htmldoc +- else +- make_install_shipped_htmldoc= +- make_uninstall_shipped_htmldoc= +- fi +- if test $docadd_other = yes; then +- make_otherdoc=otherdoc +- make_install_otherdoc=install_otherdoc +- make_uninstall_otherdoc=uninstall_otherdoc +- else +- make_otherdoc= +- make_install_otherdoc= +- make_uninstall_otherdoc= +- fi +- if test $docadd_examples = yes; then +- make_examples=examples +- make_install_examples=install_examples +- make_uninstall_examples=uninstall_examples +- else +- make_examples= +- make_install_examples= +- make_uninstall_examples= +- fi +- +- +- +- +- +- +- +- +- +-if test $docadd_info = yes; then +- missing= +- # Extract the first word of "makeinfo", so it can be a program name with args. +-set dummy makeinfo; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_MAKEINFO+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$MAKEINFO"; then +- ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_MAKEINFO="makeinfo" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-MAKEINFO=$ac_cv_prog_MAKEINFO +-if test -n "$MAKEINFO"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKEINFO" >&5 +-$as_echo "$MAKEINFO" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- if test -z "$MAKEINFO"; then +- missing="\`makeinfo' is missing." +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for makeinfo version" >&5 +-$as_echo_n "checking for makeinfo version... " >&6; } +- # We need an additional level of quoting to make sed's regexps work. +- makeinfo_version=`$MAKEINFO --version 2>&1 \ +- | sed -e 's/^.* \([^ ][^ ]*\)$/\1/' -e '1q'` +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $makeinfo_version" >&5 +-$as_echo "$makeinfo_version" >&6; } +- # Consider only the first two numbers in version number string. +- makeinfo_version_major=`IFS=.; set x $makeinfo_version; echo 0${2}` +- makeinfo_version_minor=`IFS=.; set x $makeinfo_version; echo 0${3}` +- makeinfo_version_numeric=` +- expr ${makeinfo_version_major}000 \+ ${makeinfo_version_minor}` +- if test $makeinfo_version_numeric -lt 4008; then +- missing="\`makeinfo' is too old." +- fi +- fi +- +- if test -n "$missing"; then +- infofile=doc/groff.info +- test -f ${infofile} || infofile=${srcdir}/${infofile} +- if test ! -f ${infofile} \ +- || test ${srcdir}/doc/groff.texinfo -nt ${infofile}; then +- as_fn_error $? "$missing +-Get the \`texinfo' package version 4.8 or newer." "$LINENO" 5 +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $missing +-Get the \`texinfo' package version 4.8 or newer if you want to convert +-\`groff.texinfo' into a PDF or HTML document." >&5 +-$as_echo "$as_me: WARNING: $missing +-Get the \`texinfo' package version 4.8 or newer if you want to convert +-\`groff.texinfo' into a PDF or HTML document." >&2;} +- fi +- fi +- +- make_infodoc=infodoc +- make_install_infodoc=install_infodoc +- make_uninstall_infodoc=uninstall_infodoc +- else +- make_infodoc= +- make_install_infodoc= +- make_uninstall_infodoc= +- MAKEINFO= +- fi +- +- +- +- +-if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +-set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_RANLIB+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$RANLIB"; then +- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-RANLIB=$ac_cv_prog_RANLIB +-if test -n "$RANLIB"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +-$as_echo "$RANLIB" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$ac_cv_prog_RANLIB"; then +- ac_ct_RANLIB=$RANLIB +- # Extract the first word of "ranlib", so it can be a program name with args. +-set dummy ranlib; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_RANLIB"; then +- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_RANLIB="ranlib" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +-if test -n "$ac_ct_RANLIB"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +-$as_echo "$ac_ct_RANLIB" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- if test "x$ac_ct_RANLIB" = x; then +- RANLIB=":" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- RANLIB=$ac_ct_RANLIB +- fi +-else +- RANLIB="$ac_cv_prog_RANLIB" +-fi +- +-ac_aux_dir= +-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do +- if test -f "$ac_dir/install-sh"; then +- ac_aux_dir=$ac_dir +- ac_install_sh="$ac_aux_dir/install-sh -c" +- break +- elif test -f "$ac_dir/install.sh"; then +- ac_aux_dir=$ac_dir +- ac_install_sh="$ac_aux_dir/install.sh -c" +- break +- elif test -f "$ac_dir/shtool"; then +- ac_aux_dir=$ac_dir +- ac_install_sh="$ac_aux_dir/shtool install -c" +- break +- fi +-done +-if test -z "$ac_aux_dir"; then +- as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +-fi +- +-# These three variables are undocumented and unsupported, +-# and are intended to be withdrawn in a future Autoconf release. +-# They can cause serious problems if a builder's source tree is in a directory +-# whose full name contains unusual characters. +-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. +- +- +- +- ac_dir=`cd $ac_aux_dir; pwd` +- ac_install_sh="$ac_dir/install-sh -c" +-if test $docadd_info = yes; then +- for ac_prog in install-info +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_INSTALL_INFO+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$INSTALL_INFO"; then +- ac_cv_prog_INSTALL_INFO="$INSTALL_INFO" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_INSTALL_INFO="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-INSTALL_INFO=$ac_cv_prog_INSTALL_INFO +-if test -n "$INSTALL_INFO"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL_INFO" >&5 +-$as_echo "$INSTALL_INFO" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$INSTALL_INFO" && break +-done +-test -n "$INSTALL_INFO" || INSTALL_INFO=":" +- +- fi +-# Find a good install program. We prefer a C program (faster), +-# so one script is as good as another. But avoid the broken or +-# incompatible versions: +-# SysV /etc/install, /usr/sbin/install +-# SunOS /usr/etc/install +-# IRIX /sbin/install +-# AIX /bin/install +-# AmigaOS /C/install, which installs bootblocks on floppy discs +-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +-# AFS /usr/afsws/bin/install, which mishandles nonexistent args +-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +-# OS/2's system install, which has a completely different semantic +-# ./install, which can be erroneously created by make from ./install.sh. +-# Reject install programs that cannot install multiple files. +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +-$as_echo_n "checking for a BSD-compatible install... " >&6; } +-if test -z "$INSTALL"; then +-if ${ac_cv_path_install+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- # Account for people who put trailing slashes in PATH elements. +-case $as_dir/ in #(( +- ./ | .// | /[cC]/* | \ +- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ +- ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ +- /usr/ucb/* ) ;; +- *) +- # OSF1 and SCO ODT 3.0 have their own names for install. +- # Don't use installbsd from OSF since it installs stuff as root +- # by default. +- for ac_prog in ginstall scoinst install; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then +- if test $ac_prog = install && +- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then +- # AIX install. It has an incompatible calling convention. +- : +- elif test $ac_prog = install && +- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then +- # program-specific install script used by HP pwplus--don't use. +- : +- else +- rm -rf conftest.one conftest.two conftest.dir +- echo one > conftest.one +- echo two > conftest.two +- mkdir conftest.dir +- if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && +- test -s conftest.one && test -s conftest.two && +- test -s conftest.dir/conftest.one && +- test -s conftest.dir/conftest.two +- then +- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" +- break 3 +- fi +- fi +- fi +- done +- done +- ;; +-esac +- +- done +-IFS=$as_save_IFS +- +-rm -rf conftest.one conftest.two conftest.dir +- +-fi +- if test "${ac_cv_path_install+set}" = set; then +- INSTALL=$ac_cv_path_install +- else +- # As a last resort, use the slow shell script. Don't cache a +- # value for INSTALL within a source directory, because that will +- # break other packages using the cache if that directory is +- # removed, or if the value is a relative name. +- INSTALL=$ac_install_sh +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +-$as_echo "$INSTALL" >&6; } +- +-# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +-# It thinks the first close brace ends the variable substitution. +-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' +- +-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' +- +-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +-$as_echo_n "checking whether ln -s works... " >&6; } +-LN_S=$as_ln_s +-if test "$LN_S" = "ln -s"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +-$as_echo "no, using $LN_S" >&6; } +-fi +- +- +-# use a dummy substitution if no csh hack is necessary to avoid errors +-# with non-GNU sed programs +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for csh hash hack" >&5 +-$as_echo_n "checking for csh hash hack... " >&6; } +- +-cat <conftest.sh +-#! /bin/sh +-true || exit 0 +-export PATH || exit 0 +-exit 1 +-EOF +- +- chmod +x conftest.sh +- if echo ./conftest.sh | (csh >/dev/null 2>&1) >/dev/null 2>&1; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- SH_SCRIPT_SED_CMD='1s/.*/:/' +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- SH_SCRIPT_SED_CMD='1s/a/a/' +- fi +- rm -f conftest.sh +- +- +-# checks for headers +-for ac_header in stddef.h stdlib.h unistd.h dirent.h limits.h sys/dir.h \ +- string.h strings.h math.h sys/time.h direct.h process.h +-do : +- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +-_ACEOF +- +-fi +- +-done +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ISC 3.x or 4.x" >&5 +-$as_echo_n "checking for ISC 3.x or 4.x... " >&6; } +- if grep '[34]\.' /usr/options/cb.name >/dev/null 2>&1 +- then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define _SYSV3 1" >>confdefs.h +- +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -D_POSIX_SOURCE is necessary" >&5 +-$as_echo_n "checking whether -D_POSIX_SOURCE is necessary... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-extern "C" { void fileno(int); } +- +- +-int +-main () +-{ +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +-# checks for header stuff +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for return type of srand" >&5 +-$as_echo_n "checking for return type of srand... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-extern "C" { void srand(unsigned int); } +- +- +-int +-main () +-{ +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: void" >&5 +-$as_echo "void" >&6; } +- +-$as_echo "#define RET_TYPE_SRAND_IS_VOID 1" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5 +-$as_echo "int" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gettimeofday must be declared" >&5 +-$as_echo_n "checking whether gettimeofday must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_gettimeofday+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef gettimeofday +- char *p = (char *) gettimeofday; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_gettimeofday=no +-else +- groff_cv_decl_needed_gettimeofday=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_gettimeofday" >&5 +-$as_echo "$groff_cv_decl_needed_gettimeofday" >&6; } +- if test $groff_cv_decl_needed_gettimeofday = yes; then +- +-$as_echo "#define NEED_DECLARATION_GETTIMEOFDAY 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether hypot must be declared" >&5 +-$as_echo_n "checking whether hypot must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_hypot+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef hypot +- char *p = (char *) hypot; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_hypot=no +-else +- groff_cv_decl_needed_hypot=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_hypot" >&5 +-$as_echo "$groff_cv_decl_needed_hypot" >&6; } +- if test $groff_cv_decl_needed_hypot = yes; then +- +-$as_echo "#define NEED_DECLARATION_HYPOT 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether popen must be declared" >&5 +-$as_echo_n "checking whether popen must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_popen+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef popen +- char *p = (char *) popen; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_popen=no +-else +- groff_cv_decl_needed_popen=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_popen" >&5 +-$as_echo "$groff_cv_decl_needed_popen" >&6; } +- if test $groff_cv_decl_needed_popen = yes; then +- +-$as_echo "#define NEED_DECLARATION_POPEN 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pclose must be declared" >&5 +-$as_echo_n "checking whether pclose must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_pclose+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef pclose +- char *p = (char *) pclose; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_pclose=no +-else +- groff_cv_decl_needed_pclose=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_pclose" >&5 +-$as_echo "$groff_cv_decl_needed_pclose" >&6; } +- if test $groff_cv_decl_needed_pclose = yes; then +- +-$as_echo "#define NEED_DECLARATION_PCLOSE 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether putenv must be declared" >&5 +-$as_echo_n "checking whether putenv must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_putenv+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef putenv +- char *p = (char *) putenv; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_putenv=no +-else +- groff_cv_decl_needed_putenv=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_putenv" >&5 +-$as_echo "$groff_cv_decl_needed_putenv" >&6; } +- if test $groff_cv_decl_needed_putenv = yes; then +- +-$as_echo "#define NEED_DECLARATION_PUTENV 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether rand must be declared" >&5 +-$as_echo_n "checking whether rand must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_rand+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef rand +- char *p = (char *) rand; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_rand=no +-else +- groff_cv_decl_needed_rand=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_rand" >&5 +-$as_echo "$groff_cv_decl_needed_rand" >&6; } +- if test $groff_cv_decl_needed_rand = yes; then +- +-$as_echo "#define NEED_DECLARATION_RAND 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether snprintf must be declared" >&5 +-$as_echo_n "checking whether snprintf must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_snprintf+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef snprintf +- char *p = (char *) snprintf; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_snprintf=no +-else +- groff_cv_decl_needed_snprintf=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_snprintf" >&5 +-$as_echo "$groff_cv_decl_needed_snprintf" >&6; } +- if test $groff_cv_decl_needed_snprintf = yes; then +- +-$as_echo "#define NEED_DECLARATION_SNPRINTF 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether srand must be declared" >&5 +-$as_echo_n "checking whether srand must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_srand+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef srand +- char *p = (char *) srand; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_srand=no +-else +- groff_cv_decl_needed_srand=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_srand" >&5 +-$as_echo "$groff_cv_decl_needed_srand" >&6; } +- if test $groff_cv_decl_needed_srand = yes; then +- +-$as_echo "#define NEED_DECLARATION_SRAND 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strcasecmp must be declared" >&5 +-$as_echo_n "checking whether strcasecmp must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_strcasecmp+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef strcasecmp +- char *p = (char *) strcasecmp; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_strcasecmp=no +-else +- groff_cv_decl_needed_strcasecmp=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_strcasecmp" >&5 +-$as_echo "$groff_cv_decl_needed_strcasecmp" >&6; } +- if test $groff_cv_decl_needed_strcasecmp = yes; then +- +-$as_echo "#define NEED_DECLARATION_STRCASECMP 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strncasecmp must be declared" >&5 +-$as_echo_n "checking whether strncasecmp must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_strncasecmp+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef strncasecmp +- char *p = (char *) strncasecmp; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_strncasecmp=no +-else +- groff_cv_decl_needed_strncasecmp=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_strncasecmp" >&5 +-$as_echo "$groff_cv_decl_needed_strncasecmp" >&6; } +- if test $groff_cv_decl_needed_strncasecmp = yes; then +- +-$as_echo "#define NEED_DECLARATION_STRNCASECMP 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vfprintf must be declared" >&5 +-$as_echo_n "checking whether vfprintf must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_vfprintf+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef vfprintf +- char *p = (char *) vfprintf; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_vfprintf=no +-else +- groff_cv_decl_needed_vfprintf=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_vfprintf" >&5 +-$as_echo "$groff_cv_decl_needed_vfprintf" >&6; } +- if test $groff_cv_decl_needed_vfprintf = yes; then +- +-$as_echo "#define NEED_DECLARATION_VFPRINTF 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vsnprintf must be declared" >&5 +-$as_echo_n "checking whether vsnprintf must be declared... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- if ${groff_cv_decl_needed_vsnprintf+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#ifdef HAVE_STRING_H +-#include +-#endif +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#ifdef HAVE_STDLIB_H +-#include +-#endif +-#ifdef HAVE_SYS_TIME_H +-#include +-#endif +-#ifdef HAVE_UNISTD_H +-#include +-#endif +-#ifdef HAVE_MATH_H +-#include +-#endif +- +- +-int +-main () +-{ +- +- +-#ifndef vsnprintf +- char *p = (char *) vsnprintf; +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_decl_needed_vsnprintf=no +-else +- groff_cv_decl_needed_vsnprintf=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_decl_needed_vsnprintf" >&5 +-$as_echo "$groff_cv_decl_needed_vsnprintf" >&6; } +- if test $groff_cv_decl_needed_vsnprintf = yes; then +- +-$as_echo "#define NEED_DECLARATION_VSNPRINTF 1" >>confdefs.h +- +- fi +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys_nerr in , , or " >&5 +-$as_echo_n "checking for sys_nerr in , , or ... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#include +-#include +- +- +-int +-main () +-{ +- +- +-int k; +-k = sys_nerr; +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define HAVE_SYS_NERR 1" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys_errlist in , , or " >&5 +-$as_echo_n "checking for sys_errlist in , , or ... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#include +-#include +- +- +-int +-main () +-{ +- +- +-int k; +-k = (int)sys_errlist[0]; +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define HAVE_SYS_ERRLIST 1" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking C++ " >&5 +-$as_echo_n "checking C++ ... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +- +- +-int +-main () +-{ +- +- +-read(0, 0, 0); +-open(0, 0); +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define HAVE_CC_OSFCN_H 1" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking C++ " >&5 +-$as_echo_n "checking C++ ... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +- +- +-int +-main () +-{ +- +- +-int x = INT_MIN; +-int y = INT_MAX; +-int z = UCHAR_MAX; +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define HAVE_CC_LIMITS_H 1" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking C++ " >&5 +-$as_echo_n "checking C++ ... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#include +- +- +-int +-main () +-{ +- +- +-uintmax_t i = (uintmax_t)-1; +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- groff_cv_header_inttypes_h=yes +- +-$as_echo "#define HAVE_CC_INTTYPES_H 1" >>confdefs.h +- +-else +- groff_cv_header_inttypes_h=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_header_inttypes_h" >&5 +-$as_echo "$groff_cv_header_inttypes_h" >&6; } +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +-# checks for typedefs +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long" >&5 +-$as_echo_n "checking for unsigned long long... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-unsigned long long ull = 1; +-int i = 63; +-unsigned long long ullmax = (unsigned long long)-1; +- +- +-int +-main () +-{ +- +- +-return ull << i | ull >> i | ullmax / ull | ullmax % ull; +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_link "$LINENO"; then : +- groff_cv_type_unsigned_long_long=yes +-else +- groff_cv_type_unsigned_long_long=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $groff_cv_type_unsigned_long_long" >&5 +-$as_echo "$groff_cv_type_unsigned_long_long" >&6; } +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +- if test $groff_cv_header_inttypes_h = no; then +- +- test $groff_cv_type_unsigned_long_long = yes \ +- && ac_type='unsigned long long' \ +- || ac_type='unsigned long' +- +-cat >>confdefs.h <<_ACEOF +-#define uintmax_t $ac_type +-_ACEOF +- +- fi +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for declaration of time_t" >&5 +-$as_echo_n "checking for declaration of time_t... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +- +- +-int +-main () +-{ +- +- +-time_t t = time(0); +-struct tm *p = localtime(&t); +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- +-$as_echo "#define LONG_FOR_TIME_T 1" >>confdefs.h +- +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for return type of signal handlers" >&5 +-$as_echo_n "checking for return type of signal handlers... " >&6; } +- for groff_declaration in \ +- 'extern "C" void (*signal (int, void (*)(int)))(int);' \ +- 'extern "C" void (*signal (int, void (*)(int)) throw ())(int);' \ +- 'void (*signal ()) ();' +- do +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#include +-#ifdef signal +-# undef signal +-#endif +-$groff_declaration +- +- +-int +-main () +-{ +- +- +-int i; +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- break +-else +- continue +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- done +- +- if test -n "$groff_declaration"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: void" >&5 +-$as_echo "void" >&6; } +- +-$as_echo "#define RETSIGTYPE void" >>confdefs.h +- +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5 +-$as_echo "int" >&6; } +- +-$as_echo "#define RETSIGTYPE int" >>confdefs.h +- +- fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking struct exception" >&5 +-$as_echo_n "checking struct exception... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +- +- +-int +-main () +-{ +- +- +-struct exception e; +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define HAVE_STRUCT_EXCEPTION 1" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-# check endianness +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +-$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +-if ${ac_cv_c_bigendian+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_cv_c_bigendian=unknown +- # See if we're dealing with a universal compiler. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#ifndef __APPLE_CC__ +- not a universal capable compiler +- #endif +- typedef int dummy; +- +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- +- # Check for potential -arch flags. It is not universal unless +- # there are at least two -arch flags with different values. +- ac_arch= +- ac_prev= +- for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do +- if test -n "$ac_prev"; then +- case $ac_word in +- i?86 | x86_64 | ppc | ppc64) +- if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then +- ac_arch=$ac_word +- else +- ac_cv_c_bigendian=universal +- break +- fi +- ;; +- esac +- ac_prev= +- elif test "x$ac_word" = "x-arch"; then +- ac_prev=arch +- fi +- done +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- if test $ac_cv_c_bigendian = unknown; then +- # See if sys/param.h defines the BYTE_ORDER macro. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- #include +- +-int +-main () +-{ +-#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ +- && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ +- && LITTLE_ENDIAN) +- bogus endian macros +- #endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- # It does; now see whether it defined to BIG_ENDIAN or not. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- #include +- +-int +-main () +-{ +-#if BYTE_ORDER != BIG_ENDIAN +- not big endian +- #endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_c_bigendian=yes +-else +- ac_cv_c_bigendian=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- fi +- if test $ac_cv_c_bigendian = unknown; then +- # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-int +-main () +-{ +-#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) +- bogus endian macros +- #endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- # It does; now see whether it defined to _BIG_ENDIAN or not. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-int +-main () +-{ +-#ifndef _BIG_ENDIAN +- not big endian +- #endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_c_bigendian=yes +-else +- ac_cv_c_bigendian=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- fi +- if test $ac_cv_c_bigendian = unknown; then +- # Compile a test program. +- if test "$cross_compiling" = yes; then : +- # Try to guess by grepping values from an object file. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-short int ascii_mm[] = +- { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +- short int ascii_ii[] = +- { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +- int use_ascii (int i) { +- return ascii_mm[i] + ascii_ii[i]; +- } +- short int ebcdic_ii[] = +- { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +- short int ebcdic_mm[] = +- { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +- int use_ebcdic (int i) { +- return ebcdic_mm[i] + ebcdic_ii[i]; +- } +- extern int foo; +- +-int +-main () +-{ +-return use_ascii (foo) == use_ebcdic (foo); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then +- ac_cv_c_bigendian=yes +- fi +- if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then +- if test "$ac_cv_c_bigendian" = unknown; then +- ac_cv_c_bigendian=no +- else +- # finding both strings is unlikely to happen, but who knows? +- ac_cv_c_bigendian=unknown +- fi +- fi +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$ac_includes_default +-int +-main () +-{ +- +- /* Are we little or big endian? From Harbison&Steele. */ +- union +- { +- long int l; +- char c[sizeof (long int)]; +- } u; +- u.l = 1; +- return u.c[sizeof (long int) - 1] == 1; +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- ac_cv_c_bigendian=no +-else +- ac_cv_c_bigendian=yes +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +-$as_echo "$ac_cv_c_bigendian" >&6; } +- case $ac_cv_c_bigendian in #( +- yes) +- $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +-;; #( +- no) +- ;; #( +- universal) +- +-$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h +- +- ;; #( +- *) +- as_fn_error $? "unknown endianness +- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; +- esac +- +- +-# checks for libraries +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lc" >&5 +-$as_echo_n "checking for main in -lc... " >&6; } +-if ${ac_cv_lib_c_main+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-lc $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +-int +-main () +-{ +-return main (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_c_main=yes +-else +- ac_cv_lib_c_main=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_main" >&5 +-$as_echo "$ac_cv_lib_c_main" >&6; } +-if test "x$ac_cv_lib_c_main" = xyes; then : +- LIBC=-lc +-fi +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5 +-$as_echo_n "checking for sin in -lm... " >&6; } +-if ${ac_cv_lib_m_sin+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_check_lib_save_LIBS=$LIBS +-LIBS="-lm $LIBS" +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char sin (); +-int +-main () +-{ +-return sin (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- ac_cv_lib_m_sin=yes +-else +- ac_cv_lib_m_sin=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-LIBS=$ac_check_lib_save_LIBS +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sin" >&5 +-$as_echo "$ac_cv_lib_m_sin" >&6; } +-if test "x$ac_cv_lib_m_sin" = xyes; then : +- LIBM=-lm +-fi +- +- +- +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +-# Make sure we can run config.sub. +-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || +- as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +-$as_echo_n "checking build system type... " >&6; } +-if ${ac_cv_build+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_build_alias=$build_alias +-test "x$ac_build_alias" = x && +- ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +-test "x$ac_build_alias" = x && +- as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || +- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +-$as_echo "$ac_cv_build" >&6; } +-case $ac_cv_build in +-*-*-*) ;; +-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +-esac +-build=$ac_cv_build +-ac_save_IFS=$IFS; IFS='-' +-set x $ac_cv_build +-shift +-build_cpu=$1 +-build_vendor=$2 +-shift; shift +-# Remember, the first character of IFS is used to create $*, +-# except with old shells: +-build_os=$* +-IFS=$ac_save_IFS +-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +-$as_echo_n "checking host system type... " >&6; } +-if ${ac_cv_host+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test "x$host_alias" = x; then +- ac_cv_host=$ac_cv_build +-else +- ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || +- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +-$as_echo "$ac_cv_host" >&6; } +-case $ac_cv_host in +-*-*-*) ;; +-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +-esac +-host=$ac_cv_host +-ac_save_IFS=$IFS; IFS='-' +-set x $ac_cv_host +-shift +-host_cpu=$1 +-host_vendor=$2 +-shift; shift +-# Remember, the first character of IFS is used to create $*, +-# except with old shells: +-host_os=$* +-IFS=$ac_save_IFS +-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac +- +- +- +- if test "X$prefix" = "XNONE"; then +- acl_final_prefix="$ac_default_prefix" +- else +- acl_final_prefix="$prefix" +- fi +- if test "X$exec_prefix" = "XNONE"; then +- acl_final_exec_prefix='${prefix}' +- else +- acl_final_exec_prefix="$exec_prefix" +- fi +- acl_save_prefix="$prefix" +- prefix="$acl_final_prefix" +- eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" +- prefix="$acl_save_prefix" +- +- +- +-# Check whether --with-gnu-ld was given. +-if test "${with_gnu_ld+set}" = set; then : +- withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +-else +- with_gnu_ld=no +-fi +- +-# Prepare PATH_SEPARATOR. +-# The user is always right. +-if test "${PATH_SEPARATOR+set}" != set; then +- # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which +- # contains only /bin. Note that ksh looks also at the FPATH variable, +- # so we have to set that as well for the test. +- PATH_SEPARATOR=: +- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ +- && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ +- || PATH_SEPARATOR=';' +- } +-fi +- +-ac_prog=ld +-if test "$GCC" = yes; then +- # Check if gcc -print-prog-name=ld gives a path. +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +-$as_echo_n "checking for ld used by $CC... " >&6; } +- case $host in +- *-*-mingw*) +- # gcc leaves a trailing carriage return which upsets mingw +- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; +- *) +- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; +- esac +- case $ac_prog in +- # Accept absolute paths. +- [\\/]* | ?:[\\/]*) +- re_direlt='/[^/][^/]*/\.\./' +- # Canonicalize the pathname of ld +- ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` +- while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do +- ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` +- done +- test -z "$LD" && LD="$ac_prog" +- ;; +- "") +- # If it fails, then pretend we aren't using GCC. +- ac_prog=ld +- ;; +- *) +- # If it is relative, then search for the first ld in PATH. +- with_gnu_ld=unknown +- ;; +- esac +-elif test "$with_gnu_ld" = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +-$as_echo_n "checking for GNU ld... " >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +-$as_echo_n "checking for non-GNU ld... " >&6; } +-fi +-if ${acl_cv_path_LD+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -z "$LD"; then +- acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +- for ac_dir in $PATH; do +- IFS="$acl_save_ifs" +- test -z "$ac_dir" && ac_dir=. +- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then +- acl_cv_path_LD="$ac_dir/$ac_prog" +- # Check to see if the program is GNU ld. I'd rather use --version, +- # but apparently some variants of GNU ld only accept -v. +- # Break only if it was the GNU/non-GNU ld that we prefer. +- case `"$acl_cv_path_LD" -v 2>&1 &5 +-$as_echo "$LD" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +-if ${acl_cv_prog_gnu_ld+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- # I'd rather use --version here, but apparently some GNU lds only accept -v. +-case `$LD -v 2>&1 &5 +-$as_echo "$acl_cv_prog_gnu_ld" >&6; } +-with_gnu_ld=$acl_cv_prog_gnu_ld +- +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +-$as_echo_n "checking for shared library run path origin... " >&6; } +-if ${acl_cv_rpath+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ +- ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh +- . ./conftest.sh +- rm -f ./conftest.sh +- acl_cv_rpath=done +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +-$as_echo "$acl_cv_rpath" >&6; } +- wl="$acl_cv_wl" +- acl_libext="$acl_cv_libext" +- acl_shlibext="$acl_cv_shlibext" +- acl_libname_spec="$acl_cv_libname_spec" +- acl_library_names_spec="$acl_cv_library_names_spec" +- acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" +- acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" +- acl_hardcode_direct="$acl_cv_hardcode_direct" +- acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" +- # Check whether --enable-rpath was given. +-if test "${enable_rpath+set}" = set; then : +- enableval=$enable_rpath; : +-else +- enable_rpath=yes +-fi +- +- +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +-$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +-if test -z "$CXXCPP"; then +- if ${ac_cv_prog_CXXCPP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- # Double quotes because CXXCPP needs to be expanded +- for CXXCPP in "$CXX -E" "/lib/cpp" +- do +- ac_preproc_ok=false +-for ac_cxx_preproc_warn_flag in '' yes +-do +- # Use a header file that comes with gcc, so configuring glibc +- # with a fresh cross-compiler works. +- # Prefer to if __STDC__ is defined, since +- # exists even on freestanding compilers. +- # On the NeXT, cc -E runs the code through the compiler's parser, +- # not just through cpp. "Syntax error" is here to catch this case. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#ifdef __STDC__ +-# include +-#else +-# include +-#endif +- Syntax error +-_ACEOF +-if ac_fn_cxx_try_cpp "$LINENO"; then : +- +-else +- # Broken: fails on valid input. +-continue +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +- # OK, works on sane cases. Now check whether nonexistent headers +- # can be detected and how. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-_ACEOF +-if ac_fn_cxx_try_cpp "$LINENO"; then : +- # Broken: success on invalid input. +-continue +-else +- # Passes both tests. +-ac_preproc_ok=: +-break +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +-done +-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +-rm -f conftest.i conftest.err conftest.$ac_ext +-if $ac_preproc_ok; then : +- break +-fi +- +- done +- ac_cv_prog_CXXCPP=$CXXCPP +- +-fi +- CXXCPP=$ac_cv_prog_CXXCPP +-else +- ac_cv_prog_CXXCPP=$CXXCPP +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +-$as_echo "$CXXCPP" >&6; } +-ac_preproc_ok=false +-for ac_cxx_preproc_warn_flag in '' yes +-do +- # Use a header file that comes with gcc, so configuring glibc +- # with a fresh cross-compiler works. +- # Prefer to if __STDC__ is defined, since +- # exists even on freestanding compilers. +- # On the NeXT, cc -E runs the code through the compiler's parser, +- # not just through cpp. "Syntax error" is here to catch this case. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#ifdef __STDC__ +-# include +-#else +-# include +-#endif +- Syntax error +-_ACEOF +-if ac_fn_cxx_try_cpp "$LINENO"; then : +- +-else +- # Broken: fails on valid input. +-continue +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +- # OK, works on sane cases. Now check whether nonexistent headers +- # can be detected and how. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-_ACEOF +-if ac_fn_cxx_try_cpp "$LINENO"; then : +- # Broken: success on invalid input. +-continue +-else +- # Passes both tests. +-ac_preproc_ok=: +-break +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +-done +-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +-rm -f conftest.i conftest.err conftest.$ac_ext +-if $ac_preproc_ok; then : +- +-else +- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +-See \`config.log' for more details" "$LINENO" 5; } +-fi +- +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- +- +- +- acl_libdirstem=lib +- acl_libdirstem2= +- case "$host_os" in +- solaris*) +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 +-$as_echo_n "checking for 64-bit host... " >&6; } +-if ${gl_cv_solaris_64bit+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef _LP64 +-sixtyfour bits +-#endif +- +-_ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "sixtyfour bits" >/dev/null 2>&1; then : +- gl_cv_solaris_64bit=yes +-else +- gl_cv_solaris_64bit=no +-fi +-rm -f conftest* +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5 +-$as_echo "$gl_cv_solaris_64bit" >&6; } +- if test $gl_cv_solaris_64bit = yes; then +- acl_libdirstem=lib/64 +- case "$host_cpu" in +- sparc*) acl_libdirstem2=lib/sparcv9 ;; +- i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; +- esac +- fi +- ;; +- *) +- searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` +- if test -n "$searchpath"; then +- acl_save_IFS="${IFS= }"; IFS=":" +- for searchdir in $searchpath; do +- if test -d "$searchdir"; then +- case "$searchdir" in +- */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; +- */../ | */.. ) +- # Better ignore directories of this form. They are misleading. +- ;; +- *) searchdir=`cd "$searchdir" && pwd` +- case "$searchdir" in +- */lib64 ) acl_libdirstem=lib64 ;; +- esac ;; +- esac +- fi +- done +- IFS="$acl_save_IFS" +- fi +- ;; +- esac +- test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" +- +- +- +- +- +- +- +- +- +- +- +- +- use_additional=yes +- +- acl_save_prefix="$prefix" +- prefix="$acl_final_prefix" +- acl_save_exec_prefix="$exec_prefix" +- exec_prefix="$acl_final_exec_prefix" +- +- eval additional_includedir=\"$includedir\" +- eval additional_libdir=\"$libdir\" +- +- exec_prefix="$acl_save_exec_prefix" +- prefix="$acl_save_prefix" +- +- +-# Check whether --with-libiconv-prefix was given. +-if test "${with_libiconv_prefix+set}" = set; then : +- withval=$with_libiconv_prefix; +- if test "X$withval" = "Xno"; then +- use_additional=no +- else +- if test "X$withval" = "X"; then +- +- acl_save_prefix="$prefix" +- prefix="$acl_final_prefix" +- acl_save_exec_prefix="$exec_prefix" +- exec_prefix="$acl_final_exec_prefix" +- +- eval additional_includedir=\"$includedir\" +- eval additional_libdir=\"$libdir\" +- +- exec_prefix="$acl_save_exec_prefix" +- prefix="$acl_save_prefix" +- +- else +- additional_includedir="$withval/include" +- additional_libdir="$withval/$acl_libdirstem" +- if test "$acl_libdirstem2" != "$acl_libdirstem" \ +- && ! test -d "$withval/$acl_libdirstem"; then +- additional_libdir="$withval/$acl_libdirstem2" +- fi +- fi +- fi +- +-fi +- +- LIBICONV= +- LTLIBICONV= +- INCICONV= +- LIBICONV_PREFIX= +- HAVE_LIBICONV= +- rpathdirs= +- ltrpathdirs= +- names_already_handled= +- names_next_round='iconv ' +- while test -n "$names_next_round"; do +- names_this_round="$names_next_round" +- names_next_round= +- for name in $names_this_round; do +- already_handled= +- for n in $names_already_handled; do +- if test "$n" = "$name"; then +- already_handled=yes +- break +- fi +- done +- if test -z "$already_handled"; then +- names_already_handled="$names_already_handled $name" +- uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` +- eval value=\"\$HAVE_LIB$uppername\" +- if test -n "$value"; then +- if test "$value" = yes; then +- eval value=\"\$LIB$uppername\" +- test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" +- eval value=\"\$LTLIB$uppername\" +- test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" +- else +- : +- fi +- else +- found_dir= +- found_la= +- found_so= +- found_a= +- eval libname=\"$acl_libname_spec\" # typically: libname=lib$name +- if test -n "$acl_shlibext"; then +- shrext=".$acl_shlibext" # typically: shrext=.so +- else +- shrext= +- fi +- if test $use_additional = yes; then +- dir="$additional_libdir" +- if test -n "$acl_shlibext"; then +- if test -f "$dir/$libname$shrext"; then +- found_dir="$dir" +- found_so="$dir/$libname$shrext" +- else +- if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then +- ver=`(cd "$dir" && \ +- for f in "$libname$shrext".*; do echo "$f"; done \ +- | sed -e "s,^$libname$shrext\\\\.,," \ +- | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ +- | sed 1q ) 2>/dev/null` +- if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then +- found_dir="$dir" +- found_so="$dir/$libname$shrext.$ver" +- fi +- else +- eval library_names=\"$acl_library_names_spec\" +- for f in $library_names; do +- if test -f "$dir/$f"; then +- found_dir="$dir" +- found_so="$dir/$f" +- break +- fi +- done +- fi +- fi +- fi +- if test "X$found_dir" = "X"; then +- if test -f "$dir/$libname.$acl_libext"; then +- found_dir="$dir" +- found_a="$dir/$libname.$acl_libext" +- fi +- fi +- if test "X$found_dir" != "X"; then +- if test -f "$dir/$libname.la"; then +- found_la="$dir/$libname.la" +- fi +- fi +- fi +- if test "X$found_dir" = "X"; then +- for x in $LDFLAGS $LTLIBICONV; do +- +- acl_save_prefix="$prefix" +- prefix="$acl_final_prefix" +- acl_save_exec_prefix="$exec_prefix" +- exec_prefix="$acl_final_exec_prefix" +- eval x=\"$x\" +- exec_prefix="$acl_save_exec_prefix" +- prefix="$acl_save_prefix" +- +- case "$x" in +- -L*) +- dir=`echo "X$x" | sed -e 's/^X-L//'` +- if test -n "$acl_shlibext"; then +- if test -f "$dir/$libname$shrext"; then +- found_dir="$dir" +- found_so="$dir/$libname$shrext" +- else +- if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then +- ver=`(cd "$dir" && \ +- for f in "$libname$shrext".*; do echo "$f"; done \ +- | sed -e "s,^$libname$shrext\\\\.,," \ +- | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ +- | sed 1q ) 2>/dev/null` +- if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then +- found_dir="$dir" +- found_so="$dir/$libname$shrext.$ver" +- fi +- else +- eval library_names=\"$acl_library_names_spec\" +- for f in $library_names; do +- if test -f "$dir/$f"; then +- found_dir="$dir" +- found_so="$dir/$f" +- break +- fi +- done +- fi +- fi +- fi +- if test "X$found_dir" = "X"; then +- if test -f "$dir/$libname.$acl_libext"; then +- found_dir="$dir" +- found_a="$dir/$libname.$acl_libext" +- fi +- fi +- if test "X$found_dir" != "X"; then +- if test -f "$dir/$libname.la"; then +- found_la="$dir/$libname.la" +- fi +- fi +- ;; +- esac +- if test "X$found_dir" != "X"; then +- break +- fi +- done +- fi +- if test "X$found_dir" != "X"; then +- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" +- if test "X$found_so" != "X"; then +- if test "$enable_rpath" = no \ +- || test "X$found_dir" = "X/usr/$acl_libdirstem" \ +- || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then +- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" +- else +- haveit= +- for x in $ltrpathdirs; do +- if test "X$x" = "X$found_dir"; then +- haveit=yes +- break +- fi +- done +- if test -z "$haveit"; then +- ltrpathdirs="$ltrpathdirs $found_dir" +- fi +- if test "$acl_hardcode_direct" = yes; then +- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" +- else +- if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then +- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" +- haveit= +- for x in $rpathdirs; do +- if test "X$x" = "X$found_dir"; then +- haveit=yes +- break +- fi +- done +- if test -z "$haveit"; then +- rpathdirs="$rpathdirs $found_dir" +- fi +- else +- haveit= +- for x in $LDFLAGS $LIBICONV; do +- +- acl_save_prefix="$prefix" +- prefix="$acl_final_prefix" +- acl_save_exec_prefix="$exec_prefix" +- exec_prefix="$acl_final_exec_prefix" +- eval x=\"$x\" +- exec_prefix="$acl_save_exec_prefix" +- prefix="$acl_save_prefix" +- +- if test "X$x" = "X-L$found_dir"; then +- haveit=yes +- break +- fi +- done +- if test -z "$haveit"; then +- LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" +- fi +- if test "$acl_hardcode_minus_L" != no; then +- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" +- else +- LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" +- fi +- fi +- fi +- fi +- else +- if test "X$found_a" != "X"; then +- LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" +- else +- LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" +- fi +- fi +- additional_includedir= +- case "$found_dir" in +- */$acl_libdirstem | */$acl_libdirstem/) +- basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` +- if test "$name" = 'iconv'; then +- LIBICONV_PREFIX="$basedir" +- fi +- additional_includedir="$basedir/include" +- ;; +- */$acl_libdirstem2 | */$acl_libdirstem2/) +- basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` +- if test "$name" = 'iconv'; then +- LIBICONV_PREFIX="$basedir" +- fi +- additional_includedir="$basedir/include" +- ;; +- esac +- if test "X$additional_includedir" != "X"; then +- if test "X$additional_includedir" != "X/usr/include"; then +- haveit= +- if test "X$additional_includedir" = "X/usr/local/include"; then +- if test -n "$GCC"; then +- case $host_os in +- linux* | gnu* | k*bsd*-gnu) haveit=yes;; +- esac +- fi +- fi +- if test -z "$haveit"; then +- for x in $CPPFLAGS $INCICONV; do +- +- acl_save_prefix="$prefix" +- prefix="$acl_final_prefix" +- acl_save_exec_prefix="$exec_prefix" +- exec_prefix="$acl_final_exec_prefix" +- eval x=\"$x\" +- exec_prefix="$acl_save_exec_prefix" +- prefix="$acl_save_prefix" +- +- if test "X$x" = "X-I$additional_includedir"; then +- haveit=yes +- break +- fi +- done +- if test -z "$haveit"; then +- if test -d "$additional_includedir"; then +- INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" +- fi +- fi +- fi +- fi +- fi +- if test -n "$found_la"; then +- save_libdir="$libdir" +- case "$found_la" in +- */* | *\\*) . "$found_la" ;; +- *) . "./$found_la" ;; +- esac +- libdir="$save_libdir" +- for dep in $dependency_libs; do +- case "$dep" in +- -L*) +- additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` +- if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ +- && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then +- haveit= +- if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ +- || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then +- if test -n "$GCC"; then +- case $host_os in +- linux* | gnu* | k*bsd*-gnu) haveit=yes;; +- esac +- fi +- fi +- if test -z "$haveit"; then +- haveit= +- for x in $LDFLAGS $LIBICONV; do +- +- acl_save_prefix="$prefix" +- prefix="$acl_final_prefix" +- acl_save_exec_prefix="$exec_prefix" +- exec_prefix="$acl_final_exec_prefix" +- eval x=\"$x\" +- exec_prefix="$acl_save_exec_prefix" +- prefix="$acl_save_prefix" +- +- if test "X$x" = "X-L$additional_libdir"; then +- haveit=yes +- break +- fi +- done +- if test -z "$haveit"; then +- if test -d "$additional_libdir"; then +- LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" +- fi +- fi +- haveit= +- for x in $LDFLAGS $LTLIBICONV; do +- +- acl_save_prefix="$prefix" +- prefix="$acl_final_prefix" +- acl_save_exec_prefix="$exec_prefix" +- exec_prefix="$acl_final_exec_prefix" +- eval x=\"$x\" +- exec_prefix="$acl_save_exec_prefix" +- prefix="$acl_save_prefix" +- +- if test "X$x" = "X-L$additional_libdir"; then +- haveit=yes +- break +- fi +- done +- if test -z "$haveit"; then +- if test -d "$additional_libdir"; then +- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" +- fi +- fi +- fi +- fi +- ;; +- -R*) +- dir=`echo "X$dep" | sed -e 's/^X-R//'` +- if test "$enable_rpath" != no; then +- haveit= +- for x in $rpathdirs; do +- if test "X$x" = "X$dir"; then +- haveit=yes +- break +- fi +- done +- if test -z "$haveit"; then +- rpathdirs="$rpathdirs $dir" +- fi +- haveit= +- for x in $ltrpathdirs; do +- if test "X$x" = "X$dir"; then +- haveit=yes +- break +- fi +- done +- if test -z "$haveit"; then +- ltrpathdirs="$ltrpathdirs $dir" +- fi +- fi +- ;; +- -l*) +- names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` +- ;; +- *.la) +- names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` +- ;; +- *) +- LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" +- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" +- ;; +- esac +- done +- fi +- else +- LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" +- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" +- fi +- fi +- fi +- done +- done +- if test "X$rpathdirs" != "X"; then +- if test -n "$acl_hardcode_libdir_separator"; then +- alldirs= +- for found_dir in $rpathdirs; do +- alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" +- done +- acl_save_libdir="$libdir" +- libdir="$alldirs" +- eval flag=\"$acl_hardcode_libdir_flag_spec\" +- libdir="$acl_save_libdir" +- LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" +- else +- for found_dir in $rpathdirs; do +- acl_save_libdir="$libdir" +- libdir="$found_dir" +- eval flag=\"$acl_hardcode_libdir_flag_spec\" +- libdir="$acl_save_libdir" +- LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" +- done +- fi +- fi +- if test "X$ltrpathdirs" != "X"; then +- for found_dir in $ltrpathdirs; do +- LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" +- done +- fi +- +- +- +- +- +- +- +- +- +- +- +- +- am_save_CPPFLAGS="$CPPFLAGS" +- +- for element in $INCICONV; do +- haveit= +- for x in $CPPFLAGS; do +- +- acl_save_prefix="$prefix" +- prefix="$acl_final_prefix" +- acl_save_exec_prefix="$exec_prefix" +- exec_prefix="$acl_final_exec_prefix" +- eval x=\"$x\" +- exec_prefix="$acl_save_exec_prefix" +- prefix="$acl_save_prefix" +- +- if test "X$x" = "X$element"; then +- haveit=yes +- break +- fi +- done +- if test -z "$haveit"; then +- CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" +- fi +- done +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +-$as_echo_n "checking for iconv... " >&6; } +-if ${am_cv_func_iconv+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- am_cv_func_iconv="no, consider installing GNU libiconv" +- am_cv_lib_iconv=no +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#include +- +-int +-main () +-{ +-iconv_t cd = iconv_open("",""); +- iconv(cd,NULL,NULL,NULL,NULL); +- iconv_close(cd); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_cxx_try_link "$LINENO"; then : +- am_cv_func_iconv=yes +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- if test "$am_cv_func_iconv" != yes; then +- am_save_LIBS="$LIBS" +- LIBS="$LIBS $LIBICONV" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#include +- +-int +-main () +-{ +-iconv_t cd = iconv_open("",""); +- iconv(cd,NULL,NULL,NULL,NULL); +- iconv_close(cd); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_cxx_try_link "$LINENO"; then : +- am_cv_lib_iconv=yes +- am_cv_func_iconv=yes +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- LIBS="$am_save_LIBS" +- fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 +-$as_echo "$am_cv_func_iconv" >&6; } +- if test "$am_cv_func_iconv" = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 +-$as_echo_n "checking for working iconv... " >&6; } +-if ${am_cv_func_iconv_works+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- am_save_LIBS="$LIBS" +- if test $am_cv_lib_iconv = yes; then +- LIBS="$LIBS $LIBICONV" +- fi +- am_cv_func_iconv_works=no +- for ac_iconv_const in '' 'const'; do +- if test "$cross_compiling" = yes; then : +- case "$host_os" in +- aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; +- *) am_cv_func_iconv_works="guessing yes" ;; +- esac +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#include +- +-#ifndef ICONV_CONST +-# define ICONV_CONST $ac_iconv_const +-#endif +- +-int +-main () +-{ +-int result = 0; +- /* Test against AIX 5.1 bug: Failures are not distinguishable from successful +- returns. */ +- { +- iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); +- if (cd_utf8_to_88591 != (iconv_t)(-1)) +- { +- static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ +- char buf[10]; +- ICONV_CONST char *inptr = input; +- size_t inbytesleft = strlen (input); +- char *outptr = buf; +- size_t outbytesleft = sizeof (buf); +- size_t res = iconv (cd_utf8_to_88591, +- &inptr, &inbytesleft, +- &outptr, &outbytesleft); +- if (res == 0) +- result |= 1; +- iconv_close (cd_utf8_to_88591); +- } +- } +- /* Test against Solaris 10 bug: Failures are not distinguishable from +- successful returns. */ +- { +- iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); +- if (cd_ascii_to_88591 != (iconv_t)(-1)) +- { +- static ICONV_CONST char input[] = "\263"; +- char buf[10]; +- ICONV_CONST char *inptr = input; +- size_t inbytesleft = strlen (input); +- char *outptr = buf; +- size_t outbytesleft = sizeof (buf); +- size_t res = iconv (cd_ascii_to_88591, +- &inptr, &inbytesleft, +- &outptr, &outbytesleft); +- if (res == 0) +- result |= 2; +- iconv_close (cd_ascii_to_88591); +- } +- } +- /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ +- { +- iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); +- if (cd_88591_to_utf8 != (iconv_t)(-1)) +- { +- static ICONV_CONST char input[] = "\304"; +- static char buf[2] = { (char)0xDE, (char)0xAD }; +- ICONV_CONST char *inptr = input; +- size_t inbytesleft = 1; +- char *outptr = buf; +- size_t outbytesleft = 1; +- size_t res = iconv (cd_88591_to_utf8, +- &inptr, &inbytesleft, +- &outptr, &outbytesleft); +- if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) +- result |= 4; +- iconv_close (cd_88591_to_utf8); +- } +- } +-#if 0 /* This bug could be worked around by the caller. */ +- /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ +- { +- iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); +- if (cd_88591_to_utf8 != (iconv_t)(-1)) +- { +- static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; +- char buf[50]; +- ICONV_CONST char *inptr = input; +- size_t inbytesleft = strlen (input); +- char *outptr = buf; +- size_t outbytesleft = sizeof (buf); +- size_t res = iconv (cd_88591_to_utf8, +- &inptr, &inbytesleft, +- &outptr, &outbytesleft); +- if ((int)res > 0) +- result |= 8; +- iconv_close (cd_88591_to_utf8); +- } +- } +-#endif +- /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is +- provided. */ +- if (/* Try standardized names. */ +- iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) +- /* Try IRIX, OSF/1 names. */ +- && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) +- /* Try AIX names. */ +- && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) +- /* Try HP-UX names. */ +- && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) +- result |= 16; +- return result; +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_cxx_try_run "$LINENO"; then : +- am_cv_func_iconv_works=yes +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- test "$am_cv_func_iconv_works" = no || break +- done +- LIBS="$am_save_LIBS" +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 +-$as_echo "$am_cv_func_iconv_works" >&6; } +- case "$am_cv_func_iconv_works" in +- *no) am_func_iconv=no am_cv_lib_iconv=no ;; +- *) am_func_iconv=yes ;; +- esac +- else +- am_func_iconv=no am_cv_lib_iconv=no +- fi +- if test "$am_func_iconv" = yes; then +- +-$as_echo "#define HAVE_ICONV 1" >>confdefs.h +- +- fi +- if test "$am_cv_lib_iconv" = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 +-$as_echo_n "checking how to link with libiconv... " >&6; } +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 +-$as_echo "$LIBICONV" >&6; } +- else +- CPPFLAGS="$am_save_CPPFLAGS" +- LIBICONV= +- LTLIBICONV= +- fi +- +- +- +- if test "$am_cv_func_iconv" = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 +-$as_echo_n "checking for iconv declaration... " >&6; } +- if ${am_cv_proto_iconv+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#include +-extern +-#ifdef __cplusplus +-"C" +-#endif +-#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) +-size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +-#else +-size_t iconv(); +-#endif +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- am_cv_proto_iconv_arg1="" +-else +- am_cv_proto_iconv_arg1="const" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" +-fi +- +- am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: +- $am_cv_proto_iconv" >&5 +-$as_echo " +- $am_cv_proto_iconv" >&6; } +- +-cat >>confdefs.h <<_ACEOF +-#define ICONV_CONST $am_cv_proto_iconv_arg1 +-_ACEOF +- +- +- fi +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +-# we need LIBEXT +-LIBEXT=$acl_libext +- +- +-# checks for functions +- +- +- +- for ac_header in $ac_header_list +-do : +- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +-" +-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +-_ACEOF +- +-fi +- +-done +- +- +- +- +- +- +- +- +-for ac_func in getpagesize +-do : +- ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" +-if test "x$ac_cv_func_getpagesize" = xyes; then : +- cat >>confdefs.h <<_ACEOF +-#define HAVE_GETPAGESIZE 1 +-_ACEOF +- +-fi +-done +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5 +-$as_echo_n "checking for working mmap... " >&6; } +-if ${ac_cv_func_mmap_fixed_mapped+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test "$cross_compiling" = yes; then : +- ac_cv_func_mmap_fixed_mapped=no +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$ac_includes_default +-/* malloc might have been renamed as rpl_malloc. */ +-#undef malloc +- +-/* Thanks to Mike Haertel and Jim Avera for this test. +- Here is a matrix of mmap possibilities: +- mmap private not fixed +- mmap private fixed at somewhere currently unmapped +- mmap private fixed at somewhere already mapped +- mmap shared not fixed +- mmap shared fixed at somewhere currently unmapped +- mmap shared fixed at somewhere already mapped +- For private mappings, we should verify that changes cannot be read() +- back from the file, nor mmap's back from the file at a different +- address. (There have been systems where private was not correctly +- implemented like the infamous i386 svr4.0, and systems where the +- VM page cache was not coherent with the file system buffer cache +- like early versions of FreeBSD and possibly contemporary NetBSD.) +- For shared mappings, we should conversely verify that changes get +- propagated back to all the places they're supposed to be. +- +- Grep wants private fixed already mapped. +- The main things grep needs to know about mmap are: +- * does it exist and is it safe to write into the mmap'd area +- * how to use it (BSD variants) */ +- +-#include +-#include +- +-#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H +-char *malloc (); +-#endif +- +-/* This mess was copied from the GNU getpagesize.h. */ +-#ifndef HAVE_GETPAGESIZE +-# ifdef _SC_PAGESIZE +-# define getpagesize() sysconf(_SC_PAGESIZE) +-# else /* no _SC_PAGESIZE */ +-# ifdef HAVE_SYS_PARAM_H +-# include +-# ifdef EXEC_PAGESIZE +-# define getpagesize() EXEC_PAGESIZE +-# else /* no EXEC_PAGESIZE */ +-# ifdef NBPG +-# define getpagesize() NBPG * CLSIZE +-# ifndef CLSIZE +-# define CLSIZE 1 +-# endif /* no CLSIZE */ +-# else /* no NBPG */ +-# ifdef NBPC +-# define getpagesize() NBPC +-# else /* no NBPC */ +-# ifdef PAGESIZE +-# define getpagesize() PAGESIZE +-# endif /* PAGESIZE */ +-# endif /* no NBPC */ +-# endif /* no NBPG */ +-# endif /* no EXEC_PAGESIZE */ +-# else /* no HAVE_SYS_PARAM_H */ +-# define getpagesize() 8192 /* punt totally */ +-# endif /* no HAVE_SYS_PARAM_H */ +-# endif /* no _SC_PAGESIZE */ +- +-#endif /* no HAVE_GETPAGESIZE */ +- +-int +-main () +-{ +- char *data, *data2, *data3; +- const char *cdata2; +- int i, pagesize; +- int fd, fd2; +- +- pagesize = getpagesize (); +- +- /* First, make a file with some known garbage in it. */ +- data = (char *) malloc (pagesize); +- if (!data) +- return 1; +- for (i = 0; i < pagesize; ++i) +- *(data + i) = rand (); +- umask (0); +- fd = creat ("conftest.mmap", 0600); +- if (fd < 0) +- return 2; +- if (write (fd, data, pagesize) != pagesize) +- return 3; +- close (fd); +- +- /* Next, check that the tail of a page is zero-filled. File must have +- non-zero length, otherwise we risk SIGBUS for entire page. */ +- fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600); +- if (fd2 < 0) +- return 4; +- cdata2 = ""; +- if (write (fd2, cdata2, 1) != 1) +- return 5; +- data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L); +- if (data2 == MAP_FAILED) +- return 6; +- for (i = 0; i < pagesize; ++i) +- if (*(data2 + i)) +- return 7; +- close (fd2); +- if (munmap (data2, pagesize)) +- return 8; +- +- /* Next, try to mmap the file at a fixed address which already has +- something else allocated at it. If we can, also make sure that +- we see the same garbage. */ +- fd = open ("conftest.mmap", O_RDWR); +- if (fd < 0) +- return 9; +- if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, +- MAP_PRIVATE | MAP_FIXED, fd, 0L)) +- return 10; +- for (i = 0; i < pagesize; ++i) +- if (*(data + i) != *(data2 + i)) +- return 11; +- +- /* Finally, make sure that changes to the mapped area do not +- percolate back to the file as seen by read(). (This is a bug on +- some variants of i386 svr4.0.) */ +- for (i = 0; i < pagesize; ++i) +- *(data2 + i) = *(data2 + i) + 1; +- data3 = (char *) malloc (pagesize); +- if (!data3) +- return 12; +- if (read (fd, data3, pagesize) != pagesize) +- return 13; +- for (i = 0; i < pagesize; ++i) +- if (*(data + i) != *(data3 + i)) +- return 14; +- close (fd); +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- ac_cv_func_mmap_fixed_mapped=yes +-else +- ac_cv_func_mmap_fixed_mapped=no +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5 +-$as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; } +-if test $ac_cv_func_mmap_fixed_mapped = yes; then +- +-$as_echo "#define HAVE_MMAP 1" >>confdefs.h +- +-fi +-rm -f conftest.mmap conftest.txt +- +-saved_libs="$LIBS" +-LIBS="$LIBS $LIBC $LIBM" +-ac_fn_c_check_func "$LINENO" "fmod" "ac_cv_func_fmod" +-if test "x$ac_cv_func_fmod" = xyes; then : +- $as_echo "#define HAVE_FMOD 1" >>confdefs.h +- +-else +- case " $LIBOBJS " in +- *" fmod.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS fmod.$ac_objext" +- ;; +-esac +- +-fi +- +-ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd" +-if test "x$ac_cv_func_getcwd" = xyes; then : +- $as_echo "#define HAVE_GETCWD 1" >>confdefs.h +- +-else +- case " $LIBOBJS " in +- *" getcwd.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS getcwd.$ac_objext" +- ;; +-esac +- +-fi +- +-ac_fn_c_check_func "$LINENO" "putenv" "ac_cv_func_putenv" +-if test "x$ac_cv_func_putenv" = xyes; then : +- $as_echo "#define HAVE_PUTENV 1" >>confdefs.h +- +-else +- case " $LIBOBJS " in +- *" putenv.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS putenv.$ac_objext" +- ;; +-esac +- +-fi +- +-ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" +-if test "x$ac_cv_func_snprintf" = xyes; then : +- $as_echo "#define HAVE_SNPRINTF 1" >>confdefs.h +- +-else +- case " $LIBOBJS " in +- *" snprintf.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" +- ;; +-esac +- +-fi +- +-ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" +-if test "x$ac_cv_func_strcasecmp" = xyes; then : +- $as_echo "#define HAVE_STRCASECMP 1" >>confdefs.h +- +-else +- case " $LIBOBJS " in +- *" strcasecmp.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS strcasecmp.$ac_objext" +- ;; +-esac +- +-fi +- +-ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" +-if test "x$ac_cv_func_strerror" = xyes; then : +- $as_echo "#define HAVE_STRERROR 1" >>confdefs.h +- +-else +- case " $LIBOBJS " in +- *" strerror.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS strerror.$ac_objext" +- ;; +-esac +- +-fi +- +-ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" +-if test "x$ac_cv_func_strncasecmp" = xyes; then : +- $as_echo "#define HAVE_STRNCASECMP 1" >>confdefs.h +- +-else +- case " $LIBOBJS " in +- *" strncasecmp.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS strncasecmp.$ac_objext" +- ;; +-esac +- +-fi +- +-ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol" +-if test "x$ac_cv_func_strtol" = xyes; then : +- $as_echo "#define HAVE_STRTOL 1" >>confdefs.h +- +-else +- case " $LIBOBJS " in +- *" strtol.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS strtol.$ac_objext" +- ;; +-esac +- +-fi +- +- +-# vsnprintf is in the same source file as snprintf +-for ac_func in vsnprintf +-do : +- ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" +-if test "x$ac_cv_func_vsnprintf" = xyes; then : +- cat >>confdefs.h <<_ACEOF +-#define HAVE_VSNPRINTF 1 +-_ACEOF +- +-else +- case " $LIBOBJS " in +- *" snprintf.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" +- ;; +-esac +- +-fi +-done +- +-LIBS="$saved_libs" +-for ac_func in gettimeofday isatty kill rename setlocale strsep +-do : +- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +-if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +-_ACEOF +- +-fi +-done +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mkstemp" >&5 +-$as_echo_n "checking for mkstemp... " >&6; } +- ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#include +-int (*f) (char *); +- +- +-int +-main () +-{ +- +- +-f = mkstemp; +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_link "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define HAVE_MKSTEMP 1" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- case " $LIBOBJS " in +- *" mkstemp.$ac_objext "* ) ;; +- *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" +- ;; +-esac +- +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "$ac_includes_default" +-if test "x$ac_cv_have_decl_sys_siglist" = xyes; then : +- ac_have_decl=1 +-else +- ac_have_decl=0 +-fi +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_DECL_SYS_SIGLIST $ac_have_decl +-_ACEOF +-ac_fn_c_check_decl "$LINENO" "getc_unlocked" "ac_cv_have_decl_getc_unlocked" "$ac_includes_default" +-if test "x$ac_cv_have_decl_getc_unlocked" = xyes; then : +- ac_have_decl=1 +-else +- ac_have_decl=0 +-fi +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_DECL_GETC_UNLOCKED $ac_have_decl +-_ACEOF +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5 +-$as_echo_n "checking for nl_langinfo and CODESET... " >&6; } +-if ${am_cv_langinfo_codeset+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-int +-main () +-{ +-char* cs = nl_langinfo(CODESET); return !cs; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- am_cv_langinfo_codeset=yes +-else +- am_cv_langinfo_codeset=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_langinfo_codeset" >&5 +-$as_echo "$am_cv_langinfo_codeset" >&6; } +- if test $am_cv_langinfo_codeset = yes; then +- +-$as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h +- +- fi +- +- +-# checks for compiler characteristics +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ANSI array delete syntax is supported" >&5 +-$as_echo_n "checking whether ANSI array delete syntax is supported... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +-int +-main () +-{ +- +- +-char *p = new char[5]; +-delete [] p; +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- +-$as_echo "#define ARRAY_DELETE_NEEDS_SIZE 1" >>confdefs.h +- +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-ac_ext=cpp +-ac_cpp='$CXXCPP $CPPFLAGS' +-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking traditional preprocessor" >&5 +-$as_echo_n "checking traditional preprocessor... " >&6; } +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#define name2(a, b) a/**/b +- +- +-int +-main () +-{ +- +- +-int name2(foo, bar); +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define TRADITIONAL_CPP 1" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +-# checks for operating system services +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking w_coredump" >&5 +-$as_echo_n "checking w_coredump... " >&6; } +- if test "$cross_compiling" = yes; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#include +- +- +-int +-main () +-{ +- +- +-main() +-{ +-#ifdef WCOREFLAG +- exit(1); +-#else +- int i = 0; +- ((union wait *)&i)->w_coredump = 1; +- exit(i != 0200); +-#endif +-} +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- +-$as_echo "#define WCOREFLAG 0200" >>confdefs.h +- +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- +-# other random stuff +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking default value for grops -b option" >&5 +-$as_echo_n "checking default value for grops -b option... " >&6; } +- test -n "${BROKEN_SPOOLER_FLAGS}" || BROKEN_SPOOLER_FLAGS=0 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BROKEN_SPOOLER_FLAGS" >&5 +-$as_echo "$BROKEN_SPOOLER_FLAGS" >&6; } +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking default paper size" >&5 +-$as_echo_n "checking default paper size... " >&6; } +- groff_prefix=$prefix +- test "x$prefix" = "xNONE" && groff_prefix=$ac_default_prefix +- if test -z "$PAGE"; then +- descfile= +- if test -r $groff_prefix/share/groff/font/devps/DESC; then +- descfile=$groff_prefix/share/groff/font/devps/DESC +- elif test -r $groff_prefix/lib/groff/font/devps/DESC; then +- descfile=$groff_prefix/lib/groff/font/devps/DESC +- else +- for f in $groff_prefix/share/groff/*/font/devps/DESC; do +- if test -r $f; then +- descfile=$f +- break +- fi +- done +- fi +- +- if test -n "$descfile"; then +- if grep '^paperlength[ ]\+841890' $descfile >/dev/null 2>&1; then +- PAGE=A4 +- elif grep '^papersize[ ]\+[aA]4' $descfile >/dev/null 2>&1; then +- PAGE=A4 +- fi +- fi +- fi +- +- if test -z "$PAGE"; then +- dom=`awk '($1 == "dom" || $1 == "search") { print $2; exit}' \ +- /etc/resolv.conf 2>/dev/null` +- if test -z "$dom"; then +- dom=`(domainname) 2>/dev/null | tr -d '+'` +- if test -z "$dom" \ +- || test "$dom" = '(none)'; then +- dom=`(hostname) 2>/dev/null | grep '\.'` +- fi +- fi +- # If the top-level domain is two letters and it's not `us' or `ca' +- # then they probably use A4 paper. +- case "$dom" in +- *.[Uu][Ss]|*.[Cc][Aa]) +- ;; +- *.[A-Za-z][A-Za-z]) +- PAGE=A4 ;; +- esac +- fi +- +- test -n "$PAGE" || PAGE=letter +- if test "x$PAGE" = "xA4"; then +- +-$as_echo "#define PAGEA4 1" >>confdefs.h +- +- fi +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PAGE" >&5 +-$as_echo "$PAGE" >&6; } +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for existing troff installation" >&5 +-$as_echo_n "checking for existing troff installation... " >&6; } +- if test "x`(echo .tm '|n(.g' | tr '|' '\\\\' | troff -z -i 2>&1) 2>/dev/null`" = x0; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- g=g +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- g= +- fi +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for prefix of system macro packages" >&5 +-$as_echo_n "checking for prefix of system macro packages... " >&6; } +- sys_tmac_prefix= +- sys_tmac_file_prefix= +- for d in /usr/share/lib/tmac /usr/lib/tmac; do +- for t in "" tmac.; do +- for m in an s m; do +- f=$d/$t$m +- if test -z "$sys_tmac_prefix" \ +- && test -f $f \ +- && grep '^\.if' $f >/dev/null 2>&1; then +- sys_tmac_prefix=$d/$t +- sys_tmac_file_prefix=$t +- fi +- done +- done +- done +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sys_tmac_prefix" >&5 +-$as_echo "$sys_tmac_prefix" >&6; } +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking which system macro packages should be made available" >&5 +-$as_echo_n "checking which system macro packages should be made available... " >&6; } +- tmac_wrap= +- if test "x$sys_tmac_file_prefix" = "xtmac."; then +- for f in $sys_tmac_prefix*; do +- suff=`echo $f | sed -e "s;$sys_tmac_prefix;;"` +- case "$suff" in +- e) +- ;; +- *) +- grep "Copyright.*Free Software Foundation" $f >/dev/null \ +- || tmac_wrap="$tmac_wrap $suff" ;; +- esac +- done +- elif test -n "$sys_tmac_prefix"; then +- files=`echo $sys_tmac_prefix*` +- grep "\\.so" $files >conftest.sol +- for f in $files; do +- case "$f" in +- ${sys_tmac_prefix}e) +- ;; +- *.me) +- ;; +- */ms.*) +- ;; +- *) +- b=`basename $f` +- if grep "\\.so.*/$b\$" conftest.sol >/dev/null \ +- || grep -l "Copyright.*Free Software Foundation" $f >/dev/null; then +- : +- else +- suff=`echo $f | sed -e "s;$sys_tmac_prefix;;"` +- case "$suff" in +- tmac.*) +- ;; +- *) +- tmac_wrap="$tmac_wrap $suff" ;; +- esac +- fi +- esac +- done +- rm -f conftest.sol +- fi +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tmac_wrap" >&5 +-$as_echo "$tmac_wrap" >&6; } +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking separator character to use in groff search paths" >&5 +-$as_echo_n "checking separator character to use in groff search paths... " >&6; } +- cp ${srcdir}/src/include/nonposix.h conftest.h +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +- +-#include +-#include "conftest.h" +- +- +-int +-main () +-{ +- +- +-#if PATH_SEP_CHAR == ';' +-make an error "Path separator is ';'" +-#endif +- +- +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- GROFF_PATH_SEPARATOR=":" +-else +- GROFF_PATH_SEPARATOR=";" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GROFF_PATH_SEPARATOR" >&5 +-$as_echo "$GROFF_PATH_SEPARATOR" >&6; } +- +- +-# Check whether --with-alt-gs was given. +-if test "${with_alt_gs+set}" = set; then : +- withval=$with_alt_gs; ALT_GHOSTSCRIPT_PROGS="$withval" +-else +- ALT_GHOSTSCRIPT_PROGS="gs gswin32c gsos2" +-fi +- +- +- +- +-# Check whether --with-gs was given. +-if test "${with_gs+set}" = set; then : +- withval=$with_gs; GHOSTSCRIPT=$withval +-else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in $ALT_GHOSTSCRIPT_PROGS +- do +- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +-set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_GHOSTSCRIPT+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$GHOSTSCRIPT"; then +- ac_cv_prog_GHOSTSCRIPT="$GHOSTSCRIPT" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_GHOSTSCRIPT="$ac_tool_prefix$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-GHOSTSCRIPT=$ac_cv_prog_GHOSTSCRIPT +-if test -n "$GHOSTSCRIPT"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GHOSTSCRIPT" >&5 +-$as_echo "$GHOSTSCRIPT" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$GHOSTSCRIPT" && break +- done +-fi +-if test -z "$GHOSTSCRIPT"; then +- ac_ct_GHOSTSCRIPT=$GHOSTSCRIPT +- for ac_prog in $ALT_GHOSTSCRIPT_PROGS +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_GHOSTSCRIPT+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_GHOSTSCRIPT"; then +- ac_cv_prog_ac_ct_GHOSTSCRIPT="$ac_ct_GHOSTSCRIPT" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_GHOSTSCRIPT="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_GHOSTSCRIPT=$ac_cv_prog_ac_ct_GHOSTSCRIPT +-if test -n "$ac_ct_GHOSTSCRIPT"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GHOSTSCRIPT" >&5 +-$as_echo "$ac_ct_GHOSTSCRIPT" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$ac_ct_GHOSTSCRIPT" && break +-done +- +- if test "x$ac_ct_GHOSTSCRIPT" = x; then +- GHOSTSCRIPT="missing" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- GHOSTSCRIPT=$ac_ct_GHOSTSCRIPT +- fi +-fi +- +-fi +- +- test "$GHOSTSCRIPT" = "no" && GHOSTSCRIPT=missing +-make_htmldoc= +- make_install_htmldoc= +- make_uninstall_htmldoc= +- make_htmlexamples= +- make_install_htmlexamples= +- make_uninstall_htmlexamples= +- +- +- missing= +- # Extract the first word of "pnmcut", so it can be a program name with args. +-set dummy pnmcut; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_pnmcut+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$pnmcut"; then +- ac_cv_prog_pnmcut="$pnmcut" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_pnmcut="found" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- test -z "$ac_cv_prog_pnmcut" && ac_cv_prog_pnmcut="missing" +-fi +-fi +-pnmcut=$ac_cv_prog_pnmcut +-if test -n "$pnmcut"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pnmcut" >&5 +-$as_echo "$pnmcut" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- if test $pnmcut = missing; then +- missing="$missing \`pnmcut'" +- fi;# Extract the first word of "pnmcrop", so it can be a program name with args. +-set dummy pnmcrop; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_pnmcrop+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$pnmcrop"; then +- ac_cv_prog_pnmcrop="$pnmcrop" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_pnmcrop="found" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- test -z "$ac_cv_prog_pnmcrop" && ac_cv_prog_pnmcrop="missing" +-fi +-fi +-pnmcrop=$ac_cv_prog_pnmcrop +-if test -n "$pnmcrop"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pnmcrop" >&5 +-$as_echo "$pnmcrop" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- if test $pnmcrop = missing; then +- missing="$missing \`pnmcrop'" +- fi;# Extract the first word of "pnmtopng", so it can be a program name with args. +-set dummy pnmtopng; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_pnmtopng+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$pnmtopng"; then +- ac_cv_prog_pnmtopng="$pnmtopng" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_pnmtopng="found" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- test -z "$ac_cv_prog_pnmtopng" && ac_cv_prog_pnmtopng="missing" +-fi +-fi +-pnmtopng=$ac_cv_prog_pnmtopng +-if test -n "$pnmtopng"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pnmtopng" >&5 +-$as_echo "$pnmtopng" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- if test $pnmtopng = missing; then +- missing="$missing \`pnmtopng'" +- fi;# Extract the first word of "psselect", so it can be a program name with args. +-set dummy psselect; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_psselect+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$psselect"; then +- ac_cv_prog_psselect="$psselect" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_psselect="found" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- test -z "$ac_cv_prog_psselect" && ac_cv_prog_psselect="missing" +-fi +-fi +-psselect=$ac_cv_prog_psselect +-if test -n "$psselect"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $psselect" >&5 +-$as_echo "$psselect" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- if test $psselect = missing; then +- missing="$missing \`psselect'" +- fi;# Extract the first word of "pnmtops", so it can be a program name with args. +-set dummy pnmtops; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_pnmtops+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$pnmtops"; then +- ac_cv_prog_pnmtops="$pnmtops" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_pnmtops="found" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +- test -z "$ac_cv_prog_pnmtops" && ac_cv_prog_pnmtops="missing" +-fi +-fi +-pnmtops=$ac_cv_prog_pnmtops +-if test -n "$pnmtops"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pnmtops" >&5 +-$as_echo "$pnmtops" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- if test $pnmtops = missing; then +- missing="$missing \`pnmtops'" +- fi; +- +- test "$GHOSTSCRIPT" = "missing" && missing="$missing \`gs'" +- +- if test -z "$missing"; then +- if test $docadd_html = yes; then +- make_htmldoc=htmldoc +- make_install_htmldoc=install_htmldoc +- make_uninstall_htmldoc=uninstall_htmldoc +- if test $docadd_examples = yes; then +- make_htmlexamples=html_examples +- make_install_htmlexamples=install_htmlexamples +- make_uninstall_htmlexamples=uninstall_htmlexamples +- fi +- fi +- else +- plural=`set $missing; test $# -gt 1 && echo s` +- missing=`set $missing +- missing="" +- while test $# -gt 0 +- do +- case $# in +- 1) missing="$missing$1" ;; +- 2) missing="$missing$1 and " ;; +- *) missing="$missing$1, " ;; +- esac +- shift +- done +- echo $missing` +- +- docnote=. +- test $docadd_html = yes && docnote='; +- therefore, it will neither be possible to prepare, nor to install, +- documentation in HTML format.' +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing program$plural: +- +- The program$plural +- $missing +- cannot be found in the PATH. +- Consequently, groff's HTML backend (grohtml) will not work properly$docnote +- " >&5 +-$as_echo "$as_me: WARNING: missing program$plural: +- +- The program$plural +- $missing +- cannot be found in the PATH. +- Consequently, groff's HTML backend (grohtml) will not work properly$docnote +- " >&2;} +- doc_dist_target_ok=no +- fi +- +- +- +- +- +- +- +-# Check whether --with-alt-awk was given. +-if test "${with_alt_awk+set}" = set; then : +- withval=$with_alt_awk; ALT_AWK_PROGS="$withval" +-else +- ALT_AWK_PROGS="gawk mawk nawk awk" +-fi +- +- +- +- +-# Check whether --with-awk was given. +-if test "${with_awk+set}" = set; then : +- withval=$with_awk; AWK=$withval +-else +- if test -n "$ac_tool_prefix"; then +- for ac_prog in $ALT_AWK_PROGS +- do +- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +-set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_AWK+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$AWK"; then +- ac_cv_prog_AWK="$AWK" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_AWK="$ac_tool_prefix$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-AWK=$ac_cv_prog_AWK +-if test -n "$AWK"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +-$as_echo "$AWK" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$AWK" && break +- done +-fi +-if test -z "$AWK"; then +- ac_ct_AWK=$AWK +- for ac_prog in $ALT_AWK_PROGS +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_AWK+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_AWK"; then +- ac_cv_prog_ac_ct_AWK="$ac_ct_AWK" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_AWK="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_AWK=$ac_cv_prog_ac_ct_AWK +-if test -n "$ac_ct_AWK"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AWK" >&5 +-$as_echo "$ac_ct_AWK" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$ac_ct_AWK" && break +-done +- +- if test "x$ac_ct_AWK" = x; then +- AWK="missing" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- AWK=$ac_ct_AWK +- fi +-fi +- +-fi +- +- test "$AWK" = "no" && AWK=missing +-make_pdfdoc= +- make_install_pdfdoc= +- make_uninstall_pdfdoc= +- make_pdfexamples= +- make_install_pdfexamples= +- make_uninstall_pdfexamples= +- +- +- +- missing="" +- test "$AWK" = missing && missing="\`awk'" +- test "$GHOSTSCRIPT" = missing && missing="$missing \`gs'" +- if test -z "$missing"; then +- if test $docadd_pdf = yes; then +- make_pdfdoc=pdfdoc +- make_install_pdfdoc=install_pdfdoc +- make_uninstall_pdfdoc=uninstall_pdfdoc +- if test $docadd_examples = yes; then +- make_pdfexamples=pdfexamples +- make_install_pdfexamples=install_pdfexamples +- make_uninstall_pdfexamples=uninstall_pdfexamples +- fi +- fi +- else +- plural=`set $missing; test $# -eq 2 && echo s` +- test x$plural = xs \ +- && missing=`set $missing; echo "$1 and $2"` \ +- || missing=`echo $missing` +- +- docnote=. +- test $docadd_pdf = yes && docnote='; +- therefore, it will neither be possible to prepare, nor to install, +- documentation and most of the examples in PDF format.' +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: missing program$plural: +- +- The program$plural $missing cannot be found in the PATH. +- Consequently, groff's PDF formatter (pdfroff) will not work properly$docnote +- " >&5 +-$as_echo "$as_me: WARNING: missing program$plural: +- +- The program$plural $missing cannot be found in the PATH. +- Consequently, groff's PDF formatter (pdfroff) will not work properly$docnote +- " >&2;} +- doc_dist_target_ok=no +- fi +- +- +- +- +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pnmtops can handle the -nosetpage option" >&5 +-$as_echo_n "checking whether pnmtops can handle the -nosetpage option... " >&6; } +- if echo P2 2 2 255 0 1 2 0 | pnmtops -nosetpage > /dev/null 2>&1 ; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- pnmtops_nosetpage="pnmtops -nosetpage" +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- pnmtops_nosetpage="pnmtops" +- fi +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C Library >= 2.1 or uClibc" >&5 +-$as_echo_n "checking whether we are using the GNU C Library >= 2.1 or uClibc... " >&6; } +-if ${ac_cv_gnu_library_2_1+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#ifdef __GNU_LIBRARY__ +- #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) +- Lucky GNU user +- #endif +-#endif +-#ifdef __UCLIBC__ +- Lucky user +-#endif +- +-_ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "Lucky" >/dev/null 2>&1; then : +- ac_cv_gnu_library_2_1=yes +-else +- ac_cv_gnu_library_2_1=no +-fi +-rm -f conftest* +- +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gnu_library_2_1" >&5 +-$as_echo "$ac_cv_gnu_library_2_1" >&6; } +- +- GLIBC21="$ac_cv_gnu_library_2_1" +- +- +- +- +- +- for ac_func in $ac_func_list +-do : +- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +-if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +-_ACEOF +- +-fi +-done +- +- +- +- +- +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fcntl.h" >&5 +-$as_echo_n "checking for working fcntl.h... " >&6; } +-if ${gl_cv_header_working_fcntl_h+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test "$cross_compiling" = yes; then : +- gl_cv_header_working_fcntl_h=cross-compiling +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- #include +- #if HAVE_UNISTD_H +- # include +- #else /* on Windows with MSVC */ +- # include +- # include +- # defined sleep(n) _sleep ((n) * 1000) +- #endif +- #include +- #ifndef O_NOATIME +- #define O_NOATIME 0 +- #endif +- #ifndef O_NOFOLLOW +- #define O_NOFOLLOW 0 +- #endif +- static int const constants[] = +- { +- O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, +- O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY +- }; +- +-int +-main () +-{ +- +- int result = !constants; +- #if HAVE_SYMLINK +- { +- static char const sym[] = "conftest.sym"; +- if (symlink ("/dev/null", sym) != 0) +- result |= 2; +- else +- { +- int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0); +- if (fd >= 0) +- { +- close (fd); +- result |= 4; +- } +- } +- if (unlink (sym) != 0 || symlink (".", sym) != 0) +- result |= 2; +- else +- { +- int fd = open (sym, O_RDONLY | O_NOFOLLOW); +- if (fd >= 0) +- { +- close (fd); +- result |= 4; +- } +- } +- unlink (sym); +- } +- #endif +- { +- static char const file[] = "confdefs.h"; +- int fd = open (file, O_RDONLY | O_NOATIME); +- if (fd < 0) +- result |= 8; +- else +- { +- struct stat st0; +- if (fstat (fd, &st0) != 0) +- result |= 16; +- else +- { +- char c; +- sleep (1); +- if (read (fd, &c, 1) != 1) +- result |= 24; +- else +- { +- if (close (fd) != 0) +- result |= 32; +- else +- { +- struct stat st1; +- if (stat (file, &st1) != 0) +- result |= 40; +- else +- if (st0.st_atime != st1.st_atime) +- result |= 64; +- } +- } +- } +- } +- } +- return result; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- gl_cv_header_working_fcntl_h=yes +-else +- case $? in #( +- 4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( +- 64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #( +- 68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( +- *) gl_cv_header_working_fcntl_h='no';; +- esac +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_fcntl_h" >&5 +-$as_echo "$gl_cv_header_working_fcntl_h" >&6; } +- +- case $gl_cv_header_working_fcntl_h in #( +- *O_NOATIME* | no | cross-compiling) ac_val=0;; #( +- *) ac_val=1;; +- esac +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_WORKING_O_NOATIME $ac_val +-_ACEOF +- +- +- case $gl_cv_header_working_fcntl_h in #( +- *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #( +- *) ac_val=1;; +- esac +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_WORKING_O_NOFOLLOW $ac_val +-_ACEOF +- +- +-ac_fn_c_check_decl "$LINENO" "getc_unlocked" "ac_cv_have_decl_getc_unlocked" "$ac_includes_default" +-if test "x$ac_cv_have_decl_getc_unlocked" = xyes; then : +- ac_have_decl=1 +-else +- ac_have_decl=0 +-fi +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_DECL_GETC_UNLOCKED $ac_have_decl +-_ACEOF +- +- +- +- +- +- +- +- +- +- +-ac_config_files="$ac_config_files stamp-h" +- +-ac_config_files="$ac_config_files Makefile doc/Makefile src/utils/xtotroff/Makefile" +- +-ac_config_files="$ac_config_files contrib/gdiffmk/tests/runtests" +- +-ac_config_files="$ac_config_files test-groff" +- +-cat >confcache <<\_ACEOF +-# This file is a shell script that caches the results of configure +-# tests run on this system so they can be shared between configure +-# scripts and configure runs, see configure's option --config-cache. +-# It is not useful on other systems. If it contains results you don't +-# want to keep, you may remove or edit it. +-# +-# config.status only pays attention to the cache file if you give it +-# the --recheck option to rerun configure. +-# +-# `ac_cv_env_foo' variables (set or unset) will be overridden when +-# loading this file, other *unset* `ac_cv_foo' will be assigned the +-# following values. +- +-_ACEOF +- +-# The following way of writing the cache mishandles newlines in values, +-# but we know of no workaround that is simple, portable, and efficient. +-# So, we kill variables containing newlines. +-# Ultrix sh set writes to stderr and can't be redirected directly, +-# and sets the high bit in the cache file unless we assign to the vars. +-( +- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do +- eval ac_val=\$$ac_var +- case $ac_val in #( +- *${as_nl}*) +- case $ac_var in #( +- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; +- esac +- case $ac_var in #( +- _ | IFS | as_nl) ;; #( +- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( +- *) { eval $ac_var=; unset $ac_var;} ;; +- esac ;; +- esac +- done +- +- (set) 2>&1 | +- case $as_nl`(ac_space=' '; set) 2>&1` in #( +- *${as_nl}ac_space=\ *) +- # `set' does not quote correctly, so add quotes: double-quote +- # substitution turns \\\\ into \\, and sed turns \\ into \. +- sed -n \ +- "s/'/'\\\\''/g; +- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" +- ;; #( +- *) +- # `set' quotes correctly as required by POSIX, so do not add quotes. +- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" +- ;; +- esac | +- sort +-) | +- sed ' +- /^ac_cv_env_/b end +- t clear +- :clear +- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ +- t end +- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ +- :end' >>confcache +-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else +- if test -w "$cache_file"; then +- if test "x$cache_file" != "x/dev/null"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +-$as_echo "$as_me: updating cache $cache_file" >&6;} +- if test ! -f "$cache_file" || test -h "$cache_file"; then +- cat confcache >"$cache_file" +- else +- case $cache_file in #( +- */* | ?:*) +- mv -f confcache "$cache_file"$$ && +- mv -f "$cache_file"$$ "$cache_file" ;; #( +- *) +- mv -f confcache "$cache_file" ;; +- esac +- fi +- fi +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} +- fi +-fi +-rm -f confcache +- +-test "x$prefix" = xNONE && prefix=$ac_default_prefix +-# Let make expand exec_prefix. +-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' +- +-DEFS=-DHAVE_CONFIG_H +- +-ac_libobjs= +-ac_ltlibobjs= +-U= +-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue +- # 1. Remove the extension, and $U if already installed. +- ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' +- ac_i=`$as_echo "$ac_i" | sed "$ac_script"` +- # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR +- # will be set to the directory where LIBOBJS objects are built. +- as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" +- as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +-done +-LIBOBJS=$ac_libobjs +- +-LTLIBOBJS=$ac_ltlibobjs +- +- +- +- +-: "${CONFIG_STATUS=./config.status}" +-ac_write_fail=0 +-ac_clean_files_save=$ac_clean_files +-ac_clean_files="$ac_clean_files $CONFIG_STATUS" +-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +-as_write_fail=0 +-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +-#! $SHELL +-# Generated by $as_me. +-# Run this file to recreate the current configuration. +-# Compiler output produced by configure, useful for debugging +-# configure, is in config.log if it exists. +- +-debug=false +-ac_cs_recheck=false +-ac_cs_silent=false +- +-SHELL=\${CONFIG_SHELL-$SHELL} +-export SHELL +-_ASEOF +-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +-## -------------------- ## +-## M4sh Initialization. ## +-## -------------------- ## +- +-# Be more Bourne compatible +-DUALCASE=1; export DUALCASE # for MKS sh +-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +- emulate sh +- NULLCMD=: +- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which +- # is contrary to our usage. Disable this feature. +- alias -g '${1+"$@"}'='"$@"' +- setopt NO_GLOB_SUBST +-else +- case `(set -o) 2>/dev/null` in #( +- *posix*) : +- set -o posix ;; #( +- *) : +- ;; +-esac +-fi +- +- +-as_nl=' +-' +-export as_nl +-# Printing a long string crashes Solaris 7 /usr/bin/printf. +-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +-# Prefer a ksh shell builtin over an external printf program on Solaris, +-# but without wasting forks for bash or zsh. +-if test -z "$BASH_VERSION$ZSH_VERSION" \ +- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then +- as_echo='print -r --' +- as_echo_n='print -rn --' +-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then +- as_echo='printf %s\n' +- as_echo_n='printf %s' +-else +- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then +- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' +- as_echo_n='/usr/ucb/echo -n' +- else +- as_echo_body='eval expr "X$1" : "X\\(.*\\)"' +- as_echo_n_body='eval +- arg=$1; +- case $arg in #( +- *"$as_nl"*) +- expr "X$arg" : "X\\(.*\\)$as_nl"; +- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; +- esac; +- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" +- ' +- export as_echo_n_body +- as_echo_n='sh -c $as_echo_n_body as_echo' +- fi +- export as_echo_body +- as_echo='sh -c $as_echo_body as_echo' +-fi +- +-# The user is always right. +-if test "${PATH_SEPARATOR+set}" != set; then +- PATH_SEPARATOR=: +- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { +- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || +- PATH_SEPARATOR=';' +- } +-fi +- +- +-# IFS +-# We need space, tab and new line, in precisely that order. Quoting is +-# there to prevent editors from complaining about space-tab. +-# (If _AS_PATH_WALK were called with IFS unset, it would disable word +-# splitting by setting IFS to empty value.) +-IFS=" "" $as_nl" +- +-# Find who we are. Look in the path if we contain no directory separator. +-as_myself= +-case $0 in #(( +- *[\\/]* ) as_myself=$0 ;; +- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +- done +-IFS=$as_save_IFS +- +- ;; +-esac +-# We did not find ourselves, most probably we were run as `sh COMMAND' +-# in which case we are not to be found in the path. +-if test "x$as_myself" = x; then +- as_myself=$0 +-fi +-if test ! -f "$as_myself"; then +- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 +- exit 1 +-fi +- +-# Unset variables that we do not need and which cause bugs (e.g. in +-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +-# suppresses any "Segmentation fault" message there. '((' could +-# trigger a bug in pdksh 5.2.14. +-for as_var in BASH_ENV ENV MAIL MAILPATH +-do eval test x\${$as_var+set} = xset \ +- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +-done +-PS1='$ ' +-PS2='> ' +-PS4='+ ' +- +-# NLS nuisances. +-LC_ALL=C +-export LC_ALL +-LANGUAGE=C +-export LANGUAGE +- +-# CDPATH. +-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +- +- +-# as_fn_error STATUS ERROR [LINENO LOG_FD] +-# ---------------------------------------- +-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +-# script with STATUS, using 1 if that was 0. +-as_fn_error () +-{ +- as_status=$1; test $as_status -eq 0 && as_status=1 +- if test "$4"; then +- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 +- fi +- $as_echo "$as_me: error: $2" >&2 +- as_fn_exit $as_status +-} # as_fn_error +- +- +-# as_fn_set_status STATUS +-# ----------------------- +-# Set $? to STATUS, without forking. +-as_fn_set_status () +-{ +- return $1 +-} # as_fn_set_status +- +-# as_fn_exit STATUS +-# ----------------- +-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +-as_fn_exit () +-{ +- set +e +- as_fn_set_status $1 +- exit $1 +-} # as_fn_exit +- +-# as_fn_unset VAR +-# --------------- +-# Portably unset VAR. +-as_fn_unset () +-{ +- { eval $1=; unset $1;} +-} +-as_unset=as_fn_unset +-# as_fn_append VAR VALUE +-# ---------------------- +-# Append the text in VALUE to the end of the definition contained in VAR. Take +-# advantage of any shell optimizations that allow amortized linear growth over +-# repeated appends, instead of the typical quadratic growth present in naive +-# implementations. +-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +- eval 'as_fn_append () +- { +- eval $1+=\$2 +- }' +-else +- as_fn_append () +- { +- eval $1=\$$1\$2 +- } +-fi # as_fn_append +- +-# as_fn_arith ARG... +-# ------------------ +-# Perform arithmetic evaluation on the ARGs, and store the result in the +-# global $as_val. Take advantage of shells that can avoid forks. The arguments +-# must be portable across $(()) and expr. +-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +- eval 'as_fn_arith () +- { +- as_val=$(( $* )) +- }' +-else +- as_fn_arith () +- { +- as_val=`expr "$@" || test $? -eq 1` +- } +-fi # as_fn_arith +- +- +-if expr a : '\(a\)' >/dev/null 2>&1 && +- test "X`expr 00001 : '.*\(...\)'`" = X001; then +- as_expr=expr +-else +- as_expr=false +-fi +- +-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then +- as_basename=basename +-else +- as_basename=false +-fi +- +-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then +- as_dirname=dirname +-else +- as_dirname=false +-fi +- +-as_me=`$as_basename -- "$0" || +-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ +- X"$0" : 'X\(//\)$' \| \ +- X"$0" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X/"$0" | +- sed '/^.*\/\([^/][^/]*\)\/*$/{ +- s//\1/ +- q +- } +- /^X\/\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\/\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- +-# Avoid depending upon Character Ranges. +-as_cr_letters='abcdefghijklmnopqrstuvwxyz' +-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +-as_cr_Letters=$as_cr_letters$as_cr_LETTERS +-as_cr_digits='0123456789' +-as_cr_alnum=$as_cr_Letters$as_cr_digits +- +-ECHO_C= ECHO_N= ECHO_T= +-case `echo -n x` in #((((( +--n*) +- case `echo 'xy\c'` in +- *c*) ECHO_T=' ';; # ECHO_T is single tab character. +- xy) ECHO_C='\c';; +- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null +- ECHO_T=' ';; +- esac;; +-*) +- ECHO_N='-n';; +-esac +- +-rm -f conf$$ conf$$.exe conf$$.file +-if test -d conf$$.dir; then +- rm -f conf$$.dir/conf$$.file +-else +- rm -f conf$$.dir +- mkdir conf$$.dir 2>/dev/null +-fi +-if (echo >conf$$.file) 2>/dev/null; then +- if ln -s conf$$.file conf$$ 2>/dev/null; then +- as_ln_s='ln -s' +- # ... but there are two gotchas: +- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. +- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. +- # In both cases, we have to default to `cp -pR'. +- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || +- as_ln_s='cp -pR' +- elif ln conf$$.file conf$$ 2>/dev/null; then +- as_ln_s=ln +- else +- as_ln_s='cp -pR' +- fi +-else +- as_ln_s='cp -pR' +-fi +-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +-rmdir conf$$.dir 2>/dev/null +- +- +-# as_fn_mkdir_p +-# ------------- +-# Create "$as_dir" as a directory, including parents if necessary. +-as_fn_mkdir_p () +-{ +- +- case $as_dir in #( +- -*) as_dir=./$as_dir;; +- esac +- test -d "$as_dir" || eval $as_mkdir_p || { +- as_dirs= +- while :; do +- case $as_dir in #( +- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( +- *) as_qdir=$as_dir;; +- esac +- as_dirs="'$as_qdir' $as_dirs" +- as_dir=`$as_dirname -- "$as_dir" || +-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$as_dir" : 'X\(//\)[^/]' \| \ +- X"$as_dir" : 'X\(//\)$' \| \ +- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$as_dir" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- test -d "$as_dir" && break +- done +- test -z "$as_dirs" || eval "mkdir $as_dirs" +- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" +- +- +-} # as_fn_mkdir_p +-if mkdir -p . 2>/dev/null; then +- as_mkdir_p='mkdir -p "$as_dir"' +-else +- test -d ./-p && rmdir ./-p +- as_mkdir_p=false +-fi +- +- +-# as_fn_executable_p FILE +-# ----------------------- +-# Test if FILE is an executable regular file. +-as_fn_executable_p () +-{ +- test -f "$1" && test -x "$1" +-} # as_fn_executable_p +-as_test_x='test -x' +-as_executable_p=as_fn_executable_p +- +-# Sed expression to map a string onto a valid CPP name. +-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +- +-# Sed expression to map a string onto a valid variable name. +-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +- +- +-exec 6>&1 +-## ----------------------------------- ## +-## Main body of $CONFIG_STATUS script. ## +-## ----------------------------------- ## +-_ASEOF +-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-# Save the log message, to keep $0 and so on meaningful, and to +-# report actual input values of CONFIG_FILES etc. instead of their +-# values after options handling. +-ac_log=" +-This file was extended by groff $as_me 1.22.3, which was +-generated by GNU Autoconf 2.69. Invocation command line was +- +- CONFIG_FILES = $CONFIG_FILES +- CONFIG_HEADERS = $CONFIG_HEADERS +- CONFIG_LINKS = $CONFIG_LINKS +- CONFIG_COMMANDS = $CONFIG_COMMANDS +- $ $0 $@ +- +-on `(hostname || uname -n) 2>/dev/null | sed 1q` +-" +- +-_ACEOF +- +-case $ac_config_files in *" +-"*) set x $ac_config_files; shift; ac_config_files=$*;; +-esac +- +-case $ac_config_headers in *" +-"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +-esac +- +- +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-# Files that config.status was made for. +-config_files="$ac_config_files" +-config_headers="$ac_config_headers" +- +-_ACEOF +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-ac_cs_usage="\ +-\`$as_me' instantiates files and other configuration actions +-from templates according to the current configuration. Unless the files +-and actions are specified as TAGs, all are instantiated by default. +- +-Usage: $0 [OPTION]... [TAG]... +- +- -h, --help print this help, then exit +- -V, --version print version number and configuration settings, then exit +- --config print configuration, then exit +- -q, --quiet, --silent +- do not print progress messages +- -d, --debug don't remove temporary files +- --recheck update $as_me by reconfiguring in the same conditions +- --file=FILE[:TEMPLATE] +- instantiate the configuration file FILE +- --header=FILE[:TEMPLATE] +- instantiate the configuration header FILE +- +-Configuration files: +-$config_files +- +-Configuration headers: +-$config_headers +- +-Report bugs to ." +- +-_ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +-ac_cs_version="\\ +-groff config.status 1.22.3 +-configured by $0, generated by GNU Autoconf 2.69, +- with options \\"\$ac_cs_config\\" +- +-Copyright (C) 2012 Free Software Foundation, Inc. +-This config.status script is free software; the Free Software Foundation +-gives unlimited permission to copy, distribute and modify it." +- +-ac_pwd='$ac_pwd' +-srcdir='$srcdir' +-INSTALL='$INSTALL' +-AWK='$AWK' +-test -n "\$AWK" || AWK=awk +-_ACEOF +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-# The default lists apply if the user does not specify any file. +-ac_need_defaults=: +-while test $# != 0 +-do +- case $1 in +- --*=?*) +- ac_option=`expr "X$1" : 'X\([^=]*\)='` +- ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` +- ac_shift=: +- ;; +- --*=) +- ac_option=`expr "X$1" : 'X\([^=]*\)='` +- ac_optarg= +- ac_shift=: +- ;; +- *) +- ac_option=$1 +- ac_optarg=$2 +- ac_shift=shift +- ;; +- esac +- +- case $ac_option in +- # Handling of the options. +- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) +- ac_cs_recheck=: ;; +- --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) +- $as_echo "$ac_cs_version"; exit ;; +- --config | --confi | --conf | --con | --co | --c ) +- $as_echo "$ac_cs_config"; exit ;; +- --debug | --debu | --deb | --de | --d | -d ) +- debug=: ;; +- --file | --fil | --fi | --f ) +- $ac_shift +- case $ac_optarg in +- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; +- '') as_fn_error $? "missing file argument" ;; +- esac +- as_fn_append CONFIG_FILES " '$ac_optarg'" +- ac_need_defaults=false;; +- --header | --heade | --head | --hea ) +- $ac_shift +- case $ac_optarg in +- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; +- esac +- as_fn_append CONFIG_HEADERS " '$ac_optarg'" +- ac_need_defaults=false;; +- --he | --h) +- # Conflict between --help and --header +- as_fn_error $? "ambiguous option: \`$1' +-Try \`$0 --help' for more information.";; +- --help | --hel | -h ) +- $as_echo "$ac_cs_usage"; exit ;; +- -q | -quiet | --quiet | --quie | --qui | --qu | --q \ +- | -silent | --silent | --silen | --sile | --sil | --si | --s) +- ac_cs_silent=: ;; +- +- # This is an error. +- -*) as_fn_error $? "unrecognized option: \`$1' +-Try \`$0 --help' for more information." ;; +- +- *) as_fn_append ac_config_targets " $1" +- ac_need_defaults=false ;; +- +- esac +- shift +-done +- +-ac_configure_extra_args= +- +-if $ac_cs_silent; then +- exec 6>/dev/null +- ac_configure_extra_args="$ac_configure_extra_args --silent" +-fi +- +-_ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-if \$ac_cs_recheck; then +- set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +- shift +- \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 +- CONFIG_SHELL='$SHELL' +- export CONFIG_SHELL +- exec "\$@" +-fi +- +-_ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-exec 5>>config.log +-{ +- echo +- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +-## Running $as_me. ## +-_ASBOX +- $as_echo "$ac_log" +-} >&5 +- +-_ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-_ACEOF +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +- +-# Handling of arguments. +-for ac_config_target in $ac_config_targets +-do +- case $ac_config_target in +- "src/include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/include/config.h:src/include/config.hin" ;; +- "stamp-h") CONFIG_FILES="$CONFIG_FILES stamp-h" ;; +- "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; +- "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; +- "src/utils/xtotroff/Makefile") CONFIG_FILES="$CONFIG_FILES src/utils/xtotroff/Makefile" ;; +- "contrib/gdiffmk/tests/runtests") CONFIG_FILES="$CONFIG_FILES contrib/gdiffmk/tests/runtests" ;; +- "test-groff") CONFIG_FILES="$CONFIG_FILES test-groff" ;; +- +- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; +- esac +-done +- +- +-# If the user did not use the arguments to specify the items to instantiate, +-# then the envvar interface is used. Set only those that are not. +-# We use the long form for the default assignment because of an extremely +-# bizarre bug on SunOS 4.1.3. +-if $ac_need_defaults; then +- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +- test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +-fi +- +-# Have a temporary directory for convenience. Make it in the build tree +-# simply because there is no reason against having it here, and in addition, +-# creating and moving files from /tmp can sometimes cause problems. +-# Hook for its removal unless debugging. +-# Note that there is a small window in which the directory will not be cleaned: +-# after its creation but before its name has been assigned to `$tmp'. +-$debug || +-{ +- tmp= ac_tmp= +- trap 'exit_status=$? +- : "${ac_tmp:=$tmp}" +- { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +-' 0 +- trap 'as_fn_exit 1' 1 2 13 15 +-} +-# Create a (secure) tmp directory for tmp files. +- +-{ +- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && +- test -d "$tmp" +-} || +-{ +- tmp=./conf$$-$RANDOM +- (umask 077 && mkdir "$tmp") +-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +-ac_tmp=$tmp +- +-# Set up the scripts for CONFIG_FILES section. +-# No need to generate them if there are no CONFIG_FILES. +-# This happens for instance with `./config.status config.h'. +-if test -n "$CONFIG_FILES"; then +- +- +-ac_cr=`echo X | tr X '\015'` +-# On cygwin, bash can eat \r inside `` if the user requested igncr. +-# But we know of no other shell where ac_cr would be empty at this +-# point, so we can use a bashism as a fallback. +-if test "x$ac_cr" = x; then +- eval ac_cr=\$\'\\r\' +-fi +-ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +-if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then +- ac_cs_awk_cr='\\r' +-else +- ac_cs_awk_cr=$ac_cr +-fi +- +-echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +-_ACEOF +- +- +-{ +- echo "cat >conf$$subs.awk <<_ACEOF" && +- echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && +- echo "_ACEOF" +-} >conf$$subs.sh || +- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +-ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +-ac_delim='%!_!# ' +-for ac_last_try in false false false false false :; do +- . ./conf$$subs.sh || +- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +- +- ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` +- if test $ac_delim_n = $ac_delim_num; then +- break +- elif $ac_last_try; then +- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +- else +- ac_delim="$ac_delim!$ac_delim _$ac_delim!! " +- fi +-done +-rm -f conf$$subs.sh +- +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +-_ACEOF +-sed -n ' +-h +-s/^/S["/; s/!.*/"]=/ +-p +-g +-s/^[^!]*!// +-:repl +-t repl +-s/'"$ac_delim"'$// +-t delim +-:nl +-h +-s/\(.\{148\}\)..*/\1/ +-t more1 +-s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +-p +-n +-b repl +-:more1 +-s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +-p +-g +-s/.\{148\}// +-t nl +-:delim +-h +-s/\(.\{148\}\)..*/\1/ +-t more2 +-s/["\\]/\\&/g; s/^/"/; s/$/"/ +-p +-b +-:more2 +-s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +-p +-g +-s/.\{148\}// +-t delim +-' >$CONFIG_STATUS || ac_write_fail=1 +-rm -f conf$$subs.awk +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-_ACAWK +-cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && +- for (key in S) S_is_set[key] = 1 +- FS = "" +- +-} +-{ +- line = $ 0 +- nfields = split(line, field, "@") +- substed = 0 +- len = length(field[1]) +- for (i = 2; i < nfields; i++) { +- key = field[i] +- keylen = length(key) +- if (S_is_set[key]) { +- value = S[key] +- line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) +- len += length(value) + length(field[++i]) +- substed = 1 +- } else +- len += 1 + keylen +- } +- +- print line +-} +- +-_ACAWK +-_ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then +- sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +-else +- cat +-fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ +- || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +-_ACEOF +- +-# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +-# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +-# trailing colons and then remove the whole line if VPATH becomes empty +-# (actually we leave an empty line to preserve line numbers). +-if test "x$srcdir" = x.; then +- ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +-h +-s/// +-s/^/:/ +-s/[ ]*$/:/ +-s/:\$(srcdir):/:/g +-s/:\${srcdir}:/:/g +-s/:@srcdir@:/:/g +-s/^:*// +-s/:*$// +-x +-s/\(=[ ]*\).*/\1/ +-G +-s/\n// +-s/^[^=]*=[ ]*$// +-}' +-fi +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-fi # test -n "$CONFIG_FILES" +- +-# Set up the scripts for CONFIG_HEADERS section. +-# No need to generate them if there are no CONFIG_HEADERS. +-# This happens for instance with `./config.status Makefile'. +-if test -n "$CONFIG_HEADERS"; then +-cat >"$ac_tmp/defines.awk" <<\_ACAWK || +-BEGIN { +-_ACEOF +- +-# Transform confdefs.h into an awk script `defines.awk', embedded as +-# here-document in config.status, that substitutes the proper values into +-# config.h.in to produce config.h. +- +-# Create a delimiter string that does not exist in confdefs.h, to ease +-# handling of long lines. +-ac_delim='%!_!# ' +-for ac_last_try in false false :; do +- ac_tt=`sed -n "/$ac_delim/p" confdefs.h` +- if test -z "$ac_tt"; then +- break +- elif $ac_last_try; then +- as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 +- else +- ac_delim="$ac_delim!$ac_delim _$ac_delim!! " +- fi +-done +- +-# For the awk script, D is an array of macro values keyed by name, +-# likewise P contains macro parameters if any. Preserve backslash +-# newline sequences. +- +-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +-sed -n ' +-s/.\{148\}/&'"$ac_delim"'/g +-t rset +-:rset +-s/^[ ]*#[ ]*define[ ][ ]*/ / +-t def +-d +-:def +-s/\\$// +-t bsnl +-s/["\\]/\\&/g +-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +-D["\1"]=" \3"/p +-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +-d +-:bsnl +-s/["\\]/\\&/g +-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +-D["\1"]=" \3\\\\\\n"\\/p +-t cont +-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +-t cont +-d +-:cont +-n +-s/.\{148\}/&'"$ac_delim"'/g +-t clear +-:clear +-s/\\$// +-t bsnlc +-s/["\\]/\\&/g; s/^/"/; s/$/"/p +-d +-:bsnlc +-s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +-b cont +-' >$CONFIG_STATUS || ac_write_fail=1 +- +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +- for (key in D) D_is_set[key] = 1 +- FS = "" +-} +-/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { +- line = \$ 0 +- split(line, arg, " ") +- if (arg[1] == "#") { +- defundef = arg[2] +- mac1 = arg[3] +- } else { +- defundef = substr(arg[1], 2) +- mac1 = arg[2] +- } +- split(mac1, mac2, "(") #) +- macro = mac2[1] +- prefix = substr(line, 1, index(line, defundef) - 1) +- if (D_is_set[macro]) { +- # Preserve the white space surrounding the "#". +- print prefix "define", macro P[macro] D[macro] +- next +- } else { +- # Replace #undef with comments. This is necessary, for example, +- # in the case of _POSIX_SOURCE, which is predefined and required +- # on some systems where configure will not decide to define it. +- if (defundef == "undef") { +- print "/*", prefix defundef, macro, "*/" +- next +- } +- } +-} +-{ print } +-_ACAWK +-_ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +- as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +-fi # test -n "$CONFIG_HEADERS" +- +- +-eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +-shift +-for ac_tag +-do +- case $ac_tag in +- :[FHLC]) ac_mode=$ac_tag; continue;; +- esac +- case $ac_mode$ac_tag in +- :[FHL]*:*);; +- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; +- :[FH]-) ac_tag=-:-;; +- :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; +- esac +- ac_save_IFS=$IFS +- IFS=: +- set x $ac_tag +- IFS=$ac_save_IFS +- shift +- ac_file=$1 +- shift +- +- case $ac_mode in +- :L) ac_source=$1;; +- :[FH]) +- ac_file_inputs= +- for ac_f +- do +- case $ac_f in +- -) ac_f="$ac_tmp/stdin";; +- *) # Look for the file first in the build tree, then in the source tree +- # (if the path is not absolute). The absolute path cannot be DOS-style, +- # because $ac_f cannot contain `:'. +- test -f "$ac_f" || +- case $ac_f in +- [\\/$]*) false;; +- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; +- esac || +- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; +- esac +- case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac +- as_fn_append ac_file_inputs " '$ac_f'" +- done +- +- # Let's still pretend it is `configure' which instantiates (i.e., don't +- # use $as_me), people would be surprised to read: +- # /* config.h. Generated by config.status. */ +- configure_input='Generated from '` +- $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' +- `' by configure.' +- if test x"$ac_file" != x-; then +- configure_input="$ac_file. $configure_input" +- { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +-$as_echo "$as_me: creating $ac_file" >&6;} +- fi +- # Neutralize special characters interpreted by sed in replacement strings. +- case $configure_input in #( +- *\&* | *\|* | *\\* ) +- ac_sed_conf_input=`$as_echo "$configure_input" | +- sed 's/[\\\\&|]/\\\\&/g'`;; #( +- *) ac_sed_conf_input=$configure_input;; +- esac +- +- case $ac_tag in +- *:-:* | *:-) cat >"$ac_tmp/stdin" \ +- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; +- esac +- ;; +- esac +- +- ac_dir=`$as_dirname -- "$ac_file" || +-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$ac_file" : 'X\(//\)[^/]' \| \ +- X"$ac_file" : 'X\(//\)$' \| \ +- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$ac_file" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- as_dir="$ac_dir"; as_fn_mkdir_p +- ac_builddir=. +- +-case "$ac_dir" in +-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +-*) +- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` +- # A ".." for each directory in $ac_dir_suffix. +- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` +- case $ac_top_builddir_sub in +- "") ac_top_builddir_sub=. ac_top_build_prefix= ;; +- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; +- esac ;; +-esac +-ac_abs_top_builddir=$ac_pwd +-ac_abs_builddir=$ac_pwd$ac_dir_suffix +-# for backward compatibility: +-ac_top_builddir=$ac_top_build_prefix +- +-case $srcdir in +- .) # We are building in place. +- ac_srcdir=. +- ac_top_srcdir=$ac_top_builddir_sub +- ac_abs_top_srcdir=$ac_pwd ;; +- [\\/]* | ?:[\\/]* ) # Absolute name. +- ac_srcdir=$srcdir$ac_dir_suffix; +- ac_top_srcdir=$srcdir +- ac_abs_top_srcdir=$srcdir ;; +- *) # Relative name. +- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix +- ac_top_srcdir=$ac_top_build_prefix$srcdir +- ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +-esac +-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix +- +- +- case $ac_mode in +- :F) +- # +- # CONFIG_FILE +- # +- +- case $INSTALL in +- [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; +- *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; +- esac +-_ACEOF +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-# If the template does not know about datarootdir, expand it. +-# FIXME: This hack should be removed a few years after 2.60. +-ac_datarootdir_hack=; ac_datarootdir_seen= +-ac_sed_dataroot=' +-/datarootdir/ { +- p +- q +-} +-/@datadir@/p +-/@docdir@/p +-/@infodir@/p +-/@localedir@/p +-/@mandir@/p' +-case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +-*datarootdir*) ac_datarootdir_seen=yes;; +-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +-_ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +- ac_datarootdir_hack=' +- s&@datadir@&$datadir&g +- s&@docdir@&$docdir&g +- s&@infodir@&$infodir&g +- s&@localedir@&$localedir&g +- s&@mandir@&$mandir&g +- s&\\\${datarootdir}&$datarootdir&g' ;; +-esac +-_ACEOF +- +-# Neutralize VPATH when `$srcdir' = `.'. +-# Shell code in configure.ac might set extrasub. +-# FIXME: do we really want to maintain this feature? +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-ac_sed_extra="$ac_vpsub +-$extrasub +-_ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-:t +-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +-s|@configure_input@|$ac_sed_conf_input|;t t +-s&@top_builddir@&$ac_top_builddir_sub&;t t +-s&@top_build_prefix@&$ac_top_build_prefix&;t t +-s&@srcdir@&$ac_srcdir&;t t +-s&@abs_srcdir@&$ac_abs_srcdir&;t t +-s&@top_srcdir@&$ac_top_srcdir&;t t +-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +-s&@builddir@&$ac_builddir&;t t +-s&@abs_builddir@&$ac_abs_builddir&;t t +-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +-s&@INSTALL@&$ac_INSTALL&;t t +-$ac_datarootdir_hack +-" +-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ +- >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +- +-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && +- { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && +- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ +- "$ac_tmp/out"`; test -z "$ac_out"; } && +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +-which seems to be undefined. Please make sure it is defined" >&5 +-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +-which seems to be undefined. Please make sure it is defined" >&2;} +- +- rm -f "$ac_tmp/stdin" +- case $ac_file in +- -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; +- *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; +- esac \ +- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +- ;; +- :H) +- # +- # CONFIG_HEADER +- # +- if test x"$ac_file" != x-; then +- { +- $as_echo "/* $configure_input */" \ +- && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" +- } >"$ac_tmp/config.h" \ +- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +- if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +-$as_echo "$as_me: $ac_file is unchanged" >&6;} +- else +- rm -f "$ac_file" +- mv "$ac_tmp/config.h" "$ac_file" \ +- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +- fi +- else +- $as_echo "/* $configure_input */" \ +- && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ +- || as_fn_error $? "could not create -" "$LINENO" 5 +- fi +- ;; +- +- +- esac +- +- +- case $ac_file$ac_mode in +- "stamp-h":F) echo timestamp > stamp-h ;; +- "contrib/gdiffmk/tests/runtests":F) chmod +x contrib/gdiffmk/tests/runtests ;; +- "test-groff":F) chmod +x test-groff ;; +- +- esac +-done # for ac_tag +- +- +-as_fn_exit 0 +-_ACEOF +-ac_clean_files=$ac_clean_files_save +- +-test $ac_write_fail = 0 || +- as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 +- +- +-# configure is writing to config.log, and then calls config.status. +-# config.status does its own redirection, appending to config.log. +-# Unfortunately, on DOS this fails, as config.log is still kept open +-# by configure, so config.status won't be able to write to it; its +-# output is simply discarded. So we exec the FD to /dev/null, +-# effectively closing config.log, so it can be properly (re)opened and +-# appended to by config.status. When coming back to configure, we +-# need to make the FD available again. +-if test "$no_create" != yes; then +- ac_cs_success=: +- ac_config_status_args= +- test "$silent" = yes && +- ac_config_status_args="$ac_config_status_args --quiet" +- exec 5>/dev/null +- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false +- exec 5>>config.log +- # Use ||, not &&, to avoid exiting from the if with $? = 1, which +- # would make configure fail if this is the last instruction. +- $ac_cs_success || as_fn_exit 1 +-fi +-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +-fi +- +- +-echo " +-${PACKAGE_NAME} version ${PACKAGE_VERSION} +----------------------------------------------------------------------- +- Prefix : ${prefix} +- Compiler : ${CC} ${CFLAGS} ${CPPFLAGS}" +-if test "x$groff_no_x" = "xyes"; then +-echo "\ +- X11 support : no" +-else +-echo "\ +- X11 support : yes +- X11 resources dir : $appresdir" +-fi +-if test "x$doc" = x; then +-echo "\ +- Doc build : no" +-else +-echo "\ +- Doc build : ${doc} " +-fi +-echo "\ +-----------------------------------------------------------------------" +- +-if test -z "$groff_no_x"; then +- if test "x$with_appresdir" = "x"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: +- The application resource files for gxditview (GXditview and +- GXditview-color) will be installed in: +- +- $appresdir +- +- (existing files will be saved by appending \`.old' to the file +- name). +- +- To install them into a different directory, say, +- \`/etc/X11/app-defaults', add +- \`--with-appresdir=/etc/X11/app-defaults' to the configure script +- command line options and rerun it (\`prefix' value has no effect on +- a --with-appresdir option). +- +- If the gxditview resources are installed in a directory that is not +- one of the default X11 resources directories (common default +- directories are /usr/lib/X11/app-defaults, +- /usr/share/X11/app-defaults and /etc/X11/app-defaults), you will +- have to set the environment variable XFILESEARCHPATH to this +- path. More details can be found in the X(7) manual page, or in \"X +- Toolkit Intrinsics - C Language Interface manual\" +- " >&5 +-$as_echo "$as_me: +- The application resource files for gxditview (GXditview and +- GXditview-color) will be installed in: +- +- $appresdir +- +- (existing files will be saved by appending \`.old' to the file +- name). +- +- To install them into a different directory, say, +- \`/etc/X11/app-defaults', add +- \`--with-appresdir=/etc/X11/app-defaults' to the configure script +- command line options and rerun it (\`prefix' value has no effect on +- a --with-appresdir option). +- +- If the gxditview resources are installed in a directory that is not +- one of the default X11 resources directories (common default +- directories are /usr/lib/X11/app-defaults, +- /usr/share/X11/app-defaults and /etc/X11/app-defaults), you will +- have to set the environment variable XFILESEARCHPATH to this +- path. More details can be found in the X(7) manual page, or in \"X +- Toolkit Intrinsics - C Language Interface manual\" +- " >&6;} +- fi +- fi +diff -Nuar groff-1.22.3.old/configure.ac groff-1.22.3/configure.ac +--- groff-1.22.3.old/configure.ac 2014-11-04 10:38:35.143525022 +0200 ++++ groff-1.22.3/configure.ac 2015-04-23 20:57:03.000000000 +0300 +@@ -37,20 +37,28 @@ + GROFF_VERSION[.]GROFF_REVISION, + GROFF_VERSION)) + +-AC_INIT([groff], ++AC_INIT([GNU Troff], + GROFF_VERSION_STRING, + [bug-groff@gnu.org], +- [groff-]GROFF_VERSION_STRING) ++ [groff]) + AC_PREREQ([2.62]) + ++# Directories where the helper scripts should be found. This must be consistent ++# with the variable build_aux in bootstrap.conf ++AC_CONFIG_AUX_DIR([build-aux]) ++ + AC_CONFIG_HEADERS([src/include/config.h:src/include/config.hin]) + AC_CONFIG_SRCDIR([src/roff/groff/groff.cpp]) + + AC_USE_SYSTEM_EXTENSIONS + ++AM_INIT_AUTOMAKE([subdir-objects]) ++ + # checks for programs + AC_PROG_CC + AC_PROG_CXX ++gl_EARLY ++gl_INIT + GROFF_CXX_CHECK + GROFF_EBCDIC + GROFF_OS390 +@@ -77,6 +85,8 @@ + GROFF_INSTALL_INFO + AC_PROG_INSTALL + AC_PROG_LN_S ++AC_PROG_MKDIR_P ++GROFF_PROG_XPMTOPPM + + # use a dummy substitution if no csh hack is necessary to avoid errors + # with non-GNU sed programs +@@ -160,13 +170,38 @@ + GROFF_HTML_PROGRAMS + GROFF_PDFDOC_PROGRAMS + GROFF_PNMTOPS_NOSETPAGE ++GROFF_MAKE_RM + gl_GLIBC21 + gl_LOCALCHARSET + +-AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) +-AC_CONFIG_FILES([Makefile doc/Makefile src/utils/xtotroff/Makefile]) +-AC_CONFIG_FILES([contrib/gdiffmk/tests/runtests], +- [chmod +x contrib/gdiffmk/tests/runtests]) ++AM_CONDITIONAL([BUILD_WINSCRIPTS], [test -n "$make_winscripts"]) ++ ++# If X11 is not available, don't build: ++# font/devX75 ++# font/devX75-12 ++# font/devX100 ++# font/devX100-12 ++# src/devices/xditview ++# src/utils/xtotroff ++# src/libs/libxutil ++AM_CONDITIONAL([WITHOUT_X11], [test "x$groff_no_x" = "xyes"]) ++ ++# make builtin variable RM ++AM_CONDITIONAL([MAKE_DONT_HAVE_RM], [test "x$groff_is_rm_defined" = "xno"]) ++ ++# Some programs have a "g" prefix if an existing groff installation is detected ++AM_CONDITIONAL([USEPROGRAMPREFIX], [test x$g = xg]) ++ ++AM_CONDITIONAL([BUILD_INFODOC], [test -n "$make_infodoc"]) ++AM_CONDITIONAL([BUILD_HTML], [test -n "$make_htmldoc"]) ++AM_CONDITIONAL([BUILD_HTMLEXAMPLES], [test -n "$make_htmlexamples"]) ++AM_CONDITIONAL([BUILD_PDFDOC], [test -n "$make_pdfdoc"]) ++AM_CONDITIONAL([BUILD_PDFEXAMPLES], [test -n "$make_pdfexamples"]) ++AM_CONDITIONAL([BUILD_OTHERDOC], [test -n "$make_otherdoc"]) ++AM_CONDITIONAL([BUILD_EXAMPLES], [test -n "$make_examples"]) ++AM_CONDITIONAL([INSTALL_SHIPPED_HTML], [test -n "$make_install_shipped_htmldoc"]) ++ ++AC_CONFIG_FILES([Makefile]) + AC_CONFIG_FILES([test-groff], [chmod +x test-groff]) + AC_OUTPUT + +diff -Nuar groff-1.22.3.old/contrib/chem/ChangeLog groff-1.22.3/contrib/chem/ChangeLog +--- groff-1.22.3.old/contrib/chem/ChangeLog 2014-11-04 10:38:35.438521334 +0200 ++++ groff-1.22.3/contrib/chem/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,8 @@ ++2015-04-03 Werner LEMBERG ++ ++ * chem.man: Make it work in compatibility mode. ++ (EL): Fix typo. ++ + 2014-09-25 Bernd Warken + + * chem.pl: New chem version 1.0.5. +diff -Nuar groff-1.22.3.old/contrib/chem/chem.am groff-1.22.3/contrib/chem/chem.am +--- groff-1.22.3.old/contrib/chem/chem.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/chem/chem.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,121 @@ ++# Automake rules for `chem' ++ ++# File position: /contrib/chem/chem.am ++ ++# Copyright (C) 2006-14 ++# Free Software Foundation, Inc. ++# Written by Bernd Warken . ++# Moved to automake by Bertrand Garrigues ++ ++# This file is part of `chem' which is part of `groff'. ++ ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License (GPL) version 2 as ++# published by the Free Software Foundation. ++ ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++ ++# The GPL2 license text is available in the internet at ++# . ++ ++######################################################################## ++ ++chem_srcdir = $(top_srcdir)/contrib/chem ++prefixexecbin_SCRIPTS += chem ++ ++# Files installed in $(datasubdir)/pic ++chempicdir = $(datasubdir)/pic ++dist_chempic_DATA = contrib/chem/chem.pic ++ ++ ++CHEM_GENEXAMPLES = contrib/chem/examples/README ++CHEM_EXAMPLES = \ ++ contrib/chem/examples/atp.chem \ ++ contrib/chem/examples/cholesterin.chem \ ++ contrib/chem/examples/ethamivan.chem \ ++ contrib/chem/examples/lsd.chem \ ++ contrib/chem/examples/morphine.chem \ ++ contrib/chem/examples/penicillin.chem \ ++ contrib/chem/examples/reserpine.chem ++ ++if BUILD_EXAMPLES ++# Files installed in $(exampledir)/chem ++chemexampledir = $(exampledir)/chem ++nodist_chemexample_DATA = $(CHEM_GENEXAMPLES) ++dist_chemexample_DATA = $(CHEM_EXAMPLES) ++ ++# Files installed in $(exampledir)/chem/122. All the .chem files in 122 are ++# lazily installed by the local install target ++chemexample122dir = $(chemexampledir)/122 ++nodist_chemexample122_DATA = contrib/chem/examples/122/README ++endif ++EXTRA_DIST += \ ++ contrib/chem/ChangeLog \ ++ contrib/chem/chem.man \ ++ contrib/chem/chem.pic \ ++ contrib/chem/chem.pl \ ++ contrib/chem/README.txt \ ++ contrib/chem/examples/README.txt \ ++ contrib/chem/examples/122/README.txt ++ ++man1_MANS += contrib/chem/chem.n ++MOSTLYCLEANFILES += $(CHEM_GENEXAMPLES) $(nodist_chemexample122_DATA) \ ++ contrib/chem/README ++ ++# This is strangly built but not installed ++all: contrib/chem/README ++ ++contrib/chem/README: $(chem_srcdir)/README.txt ++ @$(MKDIR_P) contrib/chem/ ++ sed -e "s|[@]g[@]|$(g)|g" $? >$@ ++ ++contrib/chem/examples/README: $(chem_srcdir)/examples/README.txt ++ @$(MKDIR_P) contrib/chem/examples ++ sed -e "s|[@]g[@]|$(g)|g" $? >$@ ++ ++contrib/chem/examples/122/README: $(chem_srcdir)/examples/122/README.txt ++ @$(MKDIR_P) contrib/chem/examples/122 ++ sed -e "s|[@]g[@]|$(g)|g" $? >$@ ++ ++chem: $(chem_srcdir)/chem.pl $(SH_DEPS_SED_SCRIPT) ++ $(RM) $@ ++ sed -f "$(SH_DEPS_SED_SCRIPT)" \ ++ -e "s|[@]g[@]|$(g)|g" \ ++ -e "s|[@]BINDIR[@]|$(DESTDIR)$(bindir)|g" \ ++ -e "s|[@]MACRODIR[@]|$(DESTDIR)$(tmacdir)|g" \ ++ -e "s|[@]PICDIR[@]|$(DESTDIR)$(datasubdir)/pic|g" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|g" \ ++ -e "$(SH_SCRIPT_SED_CMD)" \ ++ $(chem_srcdir)/chem.pl >$@ ++ chmod +x $@ ++ ++install-data-local: install_chem_extra ++install_chem_extra: ++if BUILD_EXAMPLES ++ -test -d $(DESTDIR)$(chemexample122dir) \ ++ || $(mkinstalldirs) $(DESTDIR)$(chemexample122dir); ++ for i in $(chem_srcdir)/examples/122/*.chem; do \ ++ n=`echo $$i | sed 's|$(chem_srcdir)/examples/122/||g'`; \ ++ $(INSTALL_DATA) $$i $(DESTDIR)$(chemexample122dir)/$$n; \ ++ done ++endif ++ ++uninstall-local: uninstall_chem_extra ++uninstall_chem_extra: ++if BUILD_EXAMPLES ++ $(RM) $(DESTDIR)$(exampledir)/chem/122/* ++ -rmdir $(DESTDIR)$(exampledir)/chem/122 ++ $(RM) $(DESTDIR)$(exampledir)/chem/* ++ -rmdir $(DESTDIR)$(exampledir)/chem ++endif ++ -rmdir $(DESTDIR)$(datasubdir)/pic ++ ++dist-hook: dist_chem ++dist_chem: ++ chmod u+w $(distdir)/contrib/chem/examples/122 ++ for i in $(chem_srcdir)/examples/122/*.chem; do \ ++ cp -f $$i $(distdir)/contrib/chem/examples/122; \ ++ done +diff -Nuar groff-1.22.3.old/contrib/chem/chem.man groff-1.22.3/contrib/chem/chem.man +--- groff-1.22.3.old/contrib/chem/chem.man 2014-11-04 10:38:35.438521334 +0200 ++++ groff-1.22.3/contrib/chem/chem.man 2015-04-23 20:57:03.000000000 +0300 +@@ -12,7 +12,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 2006-2014 Free Software Foundation, Inc. ++Copyright \(co 2006-2014 Free Software Foundation, Inc. + + This file is part of chem, which is part of groff, a free software + project. +@@ -39,13 +39,16 @@ + .\" Setup + .\" -------------------------------------------------------------------- + . ++.do nr groff_C \n[.C] ++.cp 0 ++. + .\" -------------------------------------------------------------------- + .\" Characters + .\" -------------------------------------------------------------------- + . + .\" Ellipsis ... +-.ie t .ds EL \fS\N'188'\fP +-.el .ds EL \&.\|.\|.\&\ ++.ie t .ds EL \fS\N'188'\fP\" ++.el .ds EL \&.\|.\|.\&\" + .\" called with \*(EL + . + .\" Bullet +@@ -999,6 +1002,9 @@ + .au + . + . ++.cp \n[groff_C] ++. ++. + .\" -------------------------------------------------------------------- + .\" Emacs settings + .\" -------------------------------------------------------------------- +diff -Nuar groff-1.22.3.old/contrib/chem/examples/.gitignore groff-1.22.3/contrib/chem/examples/.gitignore +--- groff-1.22.3.old/contrib/chem/examples/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/chem/examples/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++README +diff -Nuar groff-1.22.3.old/contrib/chem/.gitignore groff-1.22.3/contrib/chem/.gitignore +--- groff-1.22.3.old/contrib/chem/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/chem/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++chem ++chem.n ++README +diff -Nuar groff-1.22.3.old/contrib/chem/Makefile.sub groff-1.22.3/contrib/chem/Makefile.sub +--- groff-1.22.3.old/contrib/chem/Makefile.sub 2014-11-04 10:38:35.438521334 +0200 ++++ groff-1.22.3/contrib/chem/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,124 +0,0 @@ +-# Makefile.sub for `chem' +- +-# File position: /contrib/chem/Makefile.sub +- +-# Copyright (C) 2006-2014 Free Software Foundation, Inc. +-# Written by Bernd Warken . +- +-# This file is part of `chem' which is part of `groff'. +- +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License (GPL) version 2 as +-# published by the Free Software Foundation. +- +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +- +-# The GPL2 license text is available in the internet at +-# . +- +-######################################################################## +- +-MAN1=chem.n +-MOSTLYCLEANADD=\ +- chem \ +- chem.n \ +- README \ +- examples/README \ +- examples/122/README +- +-RM=rm -f +- +-all: README chem $(MAN1) $(make_examples) +- +-README: $(srcdir)/README.txt +- sed -e "s|@g@|$(g)|g" $? >$@ +- +-.PHONY: examples +-examples: examples/README examples/122/README +- +-examples/README: $(srcdir)/examples/README.txt +- test -d examples || $(mkinstalldirs) examples; +- sed -e "s|@g@|$(g)|g" $? >$@ +- +-examples/122/README: $(srcdir)/examples/122/README.txt +- test -d examples || $(mkinstalldirs) examples; +- test -d examples/122 || $(mkinstalldirs) examples/122; +- sed -e "s|@g@|$(g)|g" $? >$@; +- +-chem: $(srcdir)/chem.pl $(SH_DEPS_SED_SCRIPT) +- $(RM) $@; +- sed -f "$(SH_DEPS_SED_SCRIPT)" \ +- -e "s|@g@|$(g)|g" \ +- -e "s|@BINDIR@|$(DESTDIR)$(bindir)|g" \ +- -e "s|@MACRODIR@|$(DESTDIR)$(tmacdir)|g" \ +- -e "s|@PICDIR@|$(DESTDIR)$(datasubdir)/pic|g" \ +- -e "s|@VERSION@|$(version)$(revision)|g" \ +- -e "$(SH_SCRIPT_SED_CMD)" \ +- $(srcdir)/chem.pl >$@; +- chmod +x $@; +- +-.PHONY: install_always +-install_always: chem README $(srcdir)/chem.pic +- test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir); +- $(RM) $(DESTDIR)$(bindir)/$(g)chem; +- $(INSTALL_SCRIPT) chem $(DESTDIR)$(bindir)/$(g)chem; +- test -d $(DESTDIR)$(datasubdir)/pic \ +- || $(mkinstalldirs) $(DESTDIR)$(datasubdir)/pic; +- $(RM) $(DESTDIR)$(datasubdir)/pic/chem.pic; +- $(INSTALL_DATA) $(srcdir)/chem.pic \ +- $(DESTDIR)$(datasubdir)/pic/chem.pic; +- +-.PHONY: install_examples +-install_examples: +- test -d $(DESTDIR)$(exampledir)/chem \ +- || $(mkinstalldirs) $(DESTDIR)$(exampledir)/chem; +- test -d $(DESTDIR)$(exampledir)/chem/122 \ +- || $(mkinstalldirs) $(DESTDIR)$(exampledir)/chem/122; +- find $(DESTDIR)$(exampledir)/chem -type f -exec rm -f '{}' ';' +- $(INSTALL_DATA) examples/README $(DESTDIR)$(exampledir)/chem/README; +- for i in $(srcdir)/examples/*.chem; do \ +- n=`echo $$i | sed 's|$(srcdir)/examples/||g'`; \ +- $(INSTALL_DATA) $$i $(DESTDIR)$(exampledir)/chem/$$n; \ +- done; +- $(INSTALL_DATA) examples/122/README \ +- $(DESTDIR)$(exampledir)/chem/122/README; +- for i in $(srcdir)/examples/122/*.chem; do \ +- n=`echo $$i | sed 's|$(srcdir)/examples/122/||g'`; \ +- $(INSTALL_DATA) $$i $(DESTDIR)$(exampledir)/chem/122/$$n; \ +- done +- +-.PHONY: install_data +- +-install_data: install_always $(make_install_examples) +- +-# uninstall_sub: uninstall_always $(make_uninstall_examples) +- +-.PHONY: uninstall_always +-uninstall_always: +- $(RM) $(DESTDIR)$(bindir)/chem; +- $(RM) $(DESTDIR)$(datasubdir)/pic/chem.pic; +- -test -d $(DESTDIR)$(datasubdir)/pic && \ +- rmdir $(DESTDIR)$(datasubdir)/pic; +- +-.PHONY: uninstall_examples +-uninstall_examples: +- $(RM) $(DESTDIR)$(exampledir)/chem/122/*; +- -test -d $(DESTDIR)$(exampledir)/chem/122 && \ +- rmdir $(DESTDIR)$(exampledir)/chem/122; +- $(RM) $(DESTDIR)$(exampledir)/chem/*; +- -test -d $(DESTDIR)$(exampledir)/chem && \ +- rmdir $(DESTDIR)$(exampledir)/chem; +- +-.PHONY: uninstall_sub +-uninstall_sub: uninstall_always uninstall_examples +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/eqn2graph/eqn2graph.am groff-1.22.3/contrib/eqn2graph/eqn2graph.am +--- groff-1.22.3.old/contrib/eqn2graph/eqn2graph.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/eqn2graph/eqn2graph.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,33 @@ ++# Copyright (C) 2002-2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++# eqn2graph.am ++# ++ ++eqn2graph_srcdir = $(top_srcdir)/contrib/eqn2graph ++bin_SCRIPTS += eqn2graph ++man1_MANS += contrib/eqn2graph/eqn2graph.n ++EXTRA_DIST += \ ++ contrib/eqn2graph/eqn2graph.man \ ++ contrib/eqn2graph/eqn2graph.sh ++ ++eqn2graph: $(top_srcdir)/contrib/eqn2graph/eqn2graph.sh ++ sed -e "s|[@]g[@]|$(g)|g" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|" \ ++ -e $(SH_SCRIPT_SED_CMD) $(eqn2graph_srcdir)/eqn2graph.sh >$@ ++ chmod +x $@ +diff -Nuar groff-1.22.3.old/contrib/eqn2graph/.gitignore groff-1.22.3/contrib/eqn2graph/.gitignore +--- groff-1.22.3.old/contrib/eqn2graph/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/eqn2graph/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,2 @@ ++eqn2graph ++eqn2graph.n +diff -Nuar groff-1.22.3.old/contrib/eqn2graph/Makefile.sub groff-1.22.3/contrib/eqn2graph/Makefile.sub +--- groff-1.22.3.old/contrib/eqn2graph/Makefile.sub 2014-11-04 10:38:35.442521284 +0200 ++++ groff-1.22.3/contrib/eqn2graph/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,47 +0,0 @@ +-# Copyright (C) 2002-2014 +-# Free Software Foundation, Inc. +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.sub +-# +-MAN1=eqn2graph.n +-MOSTLYCLEANADD=eqn2graph +-RM=rm -f +- +-all: eqn2graph +- +-eqn2graph: eqn2graph.sh +- sed -e "s|@g@|$(g)|g" \ +- -e "s|@VERSION@|$(version)$(revision)|" \ +- -e $(SH_SCRIPT_SED_CMD) $(srcdir)/eqn2graph.sh >$@ +- chmod +x $@ +- +-install_data: eqn2graph +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/eqn2graph +- $(INSTALL_SCRIPT) eqn2graph $(DESTDIR)$(bindir)/eqn2graph +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/eqn2graph +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/ChangeLog groff-1.22.3/contrib/gdiffmk/ChangeLog +--- groff-1.22.3.old/contrib/gdiffmk/ChangeLog 2014-11-04 10:38:35.446521234 +0200 ++++ groff-1.22.3/contrib/gdiffmk/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,49 @@ ++2015-04-13 Mike Bianchi ++ More fixes to Savannah bug #44768. ++ ++ * gdiffmk.sh: ++ replace ++ for OPTION with while [ $# -gt 0 ] ++ ++ test -e ... with test -f ++ ++ use ${DIFFCMD} for the last diff ++ add ++ -s SEDCMD option ++ OPTION="$1" ++ ++ many other cosmetic changes documented in the bug Discussion. ++ especially: ++ capitalize variables e.g. CMD=`basename $0` ++ ++ fix make check tests within gdiffmk ++ * tests/gdiffmk_tests.sh ++ add set -e ++ fails if ${abs_top_builddir} not set or incorrect ++ ++ * tests/runtests.sh ++ add test 6a ++ # Different values for addmark, changemark, deletemark ++ # Alternate format of -a -c and -d flag arguments ++ ++ add test 9a ++ # Test -D and -M options ++ # Alternate format of -M argument. ++ ++ add printout of failure count ++ add exit with failure exit_code if any test fails ++ ++2015-04-10 Werner LEMBERG ++ ++ Fix Savannah bug #44768. ++ ++ * gdiffmk.sh: Remove bash's $(...) with classic `...`. ++ Patch by Peter Bray. ++ ++2015-04-03 Werner LEMBERG + + * all `gdiffmk' source files: Add and improve the copying +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/gdiffmk.am groff-1.22.3/contrib/gdiffmk/gdiffmk.am +--- groff-1.22.3.old/contrib/gdiffmk/gdiffmk.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/gdiffmk/gdiffmk.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,58 @@ ++# Automake rules for `gdiffmk' (integration into the groff source tree) ++# ++# File position: /contrib/gdiffmk/gdiffmk.am ++# ++# Copyright (C) 2004, 2006, 2009, 2014 Free Software Foundation, Inc. ++# Written by Mike Bianchi > ++# Automake migration by Bertrand Garrigues ++# ++# This file is part of the gdiffmk utility, which is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# groff is distributed in the hope that it will be useful, but WITHOUT ++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ++# License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++######################################################################## ++gdiffmk_srcdir = $(top_srcdir)/contrib/gdiffmk ++bin_SCRIPTS += gdiffmk ++TESTS += contrib/gdiffmk/tests/gdiffmk_tests.sh ++man1_MANS += contrib/gdiffmk/gdiffmk.n ++EXTRA_DIST += \ ++ contrib/gdiffmk/gdiffmk.man \ ++ contrib/gdiffmk/ChangeLog \ ++ contrib/gdiffmk/README \ ++ contrib/gdiffmk/gdiffmk.sh \ ++ contrib/gdiffmk/tests/gdiffmk_tests.sh \ ++ contrib/gdiffmk/tests/runtests.sh \ ++ contrib/gdiffmk/tests/baseline \ ++ contrib/gdiffmk/tests/baseline.6 \ ++ contrib/gdiffmk/tests/baseline.6a \ ++ contrib/gdiffmk/tests/baseline.7 \ ++ contrib/gdiffmk/tests/baseline.8 \ ++ contrib/gdiffmk/tests/baseline.9 \ ++ contrib/gdiffmk/tests/baseline.9a \ ++ contrib/gdiffmk/tests/baseline.10 \ ++ contrib/gdiffmk/tests/file1 \ ++ contrib/gdiffmk/tests/file2 ++ ++gdiffmk: $(gdiffmk_srcdir)/gdiffmk.sh ++ sed -e "s|[@]BINDIR[@]|$(bindir)|g" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|g" \ ++ -e $(SH_SCRIPT_SED_CMD) $(gdiffmk_srcdir)/gdiffmk.sh >$@ ++ chmod +x $@ ++ ++clean-local: clean_gdiffmk_check ++clean_gdiffmk_check: ++ if test -d $(top_builddir)/contrib/gdiffmk/tests; then \ ++ cd $(top_builddir)/contrib/gdiffmk/tests && \ ++ $(abs_top_srcdir)/contrib/gdiffmk/tests/runtests.sh clean; \ ++ fi +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/gdiffmk.man groff-1.22.3/contrib/gdiffmk/gdiffmk.man +--- groff-1.22.3.old/contrib/gdiffmk/gdiffmk.man 2014-11-04 10:38:35.446521234 +0200 ++++ groff-1.22.3/contrib/gdiffmk/gdiffmk.man 2015-04-23 20:57:03.000000000 +0300 +@@ -10,7 +10,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 2004-2014 Free Software Foundation, Inc. ++Copyright \(co 2004-2014 Free Software Foundation, Inc. + + This file is part of the gdiffmk utility, which is part of groff, a + free software project. +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/gdiffmk.sh groff-1.22.3/contrib/gdiffmk/gdiffmk.sh +--- groff-1.22.3.old/contrib/gdiffmk/gdiffmk.sh 2014-11-04 10:38:35.446521234 +0200 ++++ groff-1.22.3/contrib/gdiffmk/gdiffmk.sh 2015-04-23 20:57:03.000000000 +0300 +@@ -1,6 +1,7 @@ + #! /bin/sh + # Copyright (C) 2004-2014 Free Software Foundation, Inc. + # Written by Mike Bianchi > ++# Thanks to Peter Bray for debugging. + + # This file is part of the gdiffmk utility, which is part of groff. + +@@ -19,16 +20,16 @@ + # This file is part of GNU gdiffmk. + + +-cmd=$( basename $0 ) ++CMD=`basename $0` + + Usage () { +- if test "$#" -gt 0 ++ if test $# -gt 0 + then +- echo >&2 "${cmd}: $@" ++ echo >&2 "${CMD}: $@" + fi + echo >&2 "\ + +-Usage: ${cmd} [ OPTIONS ] FILE1 FILE2 [ OUTPUT ] ++Usage: ${CMD} [ OPTIONS ] FILE1 FILE2 [ OUTPUT ] + Place difference marks into the new version of a groff/nroff/troff document. + FILE1 and FILE2 are compared, using \`diff', and FILE2 is output with + groff \`.mc' requests added to indicate how it is different from FILE1. +@@ -53,6 +54,8 @@ + + -x DIFFCMD Use a different diff(1) command; + one that accepts the \`-Dname' option, such as GNU diff. ++ -s SEDCMD Use a different sed(1) command; ++ one that accepts ????????????????????, such as GNU sed. + --version Print version information on the standard output and exit. + --help Print this message on the standard error. + " +@@ -65,7 +68,7 @@ + shift + for arg + do +- echo >&2 "${cmd}: $1" ++ echo >&2 "${CMD}: $1" + shift + done + exit ${exitcode} +@@ -82,7 +85,7 @@ + ;; + esac + +- if test ! -e "$2" ++ if test ! -f "$2" + then + Exit $1 "File \`$2' not found." + fi +@@ -104,12 +107,13 @@ + ;; + esac + +- if ! touch "$2" 2>/dev/null ++ touch "$2" 2>/dev/null ++ if test $? -ne 0 + then +- if test ! -e "$2" ++ if test ! -f "$2" + then + Exit $1 "File \`$2' not created; " \ +- "Cannot write directory \`$( dirname "$2" )'." ++ "Cannot write directory \``dirname "$2"`'." + fi + Exit $1 "File \`$2' not writeable." + fi +@@ -146,7 +150,7 @@ + ;; + esac + +- if test "$#" -lt 2 ++ if test $# -lt 2 + then + Exit 255 "Option \`$1' requires a value." + fi +@@ -155,47 +159,53 @@ + return 0 + } + +-badoption= ++BADOPTION= + DIFFCMD=diff ++SEDCMD=sed + D_option= + br=.br +-for OPTION ++while [ $# -gt 0 ] + do ++ OPTION="$1" + case "${OPTION}" in + -a*) +- ADDMARK=$( RequiresArgument "${OPTION}" $2 ) && ++ ADDMARK=`RequiresArgument "${OPTION}" "$2"` && + shift + ;; + -c*) +- CHANGEMARK=$( RequiresArgument "${OPTION}" $2 ) && ++ CHANGEMARK=`RequiresArgument "${OPTION}" "$2"` && + shift + ;; + -d*) +- DELETEMARK=$( RequiresArgument "${OPTION}" $2 ) && ++ DELETEMARK=`RequiresArgument "${OPTION}" "$2"` && + shift + ;; + -D ) + D_option=D_option + ;; + -M* ) +- MARK1=$( RequiresArgument "${OPTION}" $2 ) && ++ MARK1=`RequiresArgument "${OPTION}" "$2"` && + shift + if [ $# -lt 2 ] + then + Usage "Option \`-M' is missing the MARK2 value." + fi +- MARK2=$2 ++ MARK2="$2" + shift + ;; + -B ) + br=. + ;; ++ -s* ) ++ SEDCMD=`RequiresArgument "${OPTION}" "$2"` && ++ shift ++ ;; + -x* ) +- DIFFCMD=$( RequiresArgument "${OPTION}" $2 ) && ++ DIFFCMD=`RequiresArgument "${OPTION}" "$2"` && + shift + ;; + --version) +- echo "GNU ${cmd} (groff) version @VERSION@" ++ echo "GNU ${CMD} (groff) version @VERSION@" + exit 0 + ;; + --help) +@@ -210,7 +220,7 @@ + break + ;; + -*) +- badoption="${cmd}: invalid option \`$1'" ++ BADOPTION="${CMD}: invalid option \`$1'" + ;; + *) + break +@@ -224,28 +234,28 @@ + "the required \`-Dname' option. + Use GNU diff instead. See the \`-x DIFFCMD' option." + +-if test -n "${badoption}" ++if test -n "${BADOPTION}" + then +- Usage "${badoption}" ++ Usage "${BADOPTION}" + fi + +-if test "$#" -lt 2 -o "$#" -gt 3 ++if test $# -lt 2 -o $# -gt 3 + then + Usage "Incorrect number of arguments." + fi + +-if test "1$1" = 1- -a "2$2" = 2- ++if test "1$1" = "1-" -a "2$2" = "2-" + then + Usage "Both FILE1 and FILE2 are \`-'." + fi + +-FILE1=$1 +-FILE2=$2 ++FILE1="$1" ++FILE2="$2" + + FileRead 1 "${FILE1}" + FileRead 2 "${FILE2}" + +-if test "$#" = 3 ++if test $# = 3 + then + case "$3" in + -) +@@ -262,24 +272,24 @@ + esac + fi + +-# To make a very unlikely label even more unlikely ... +-label=__diffmk_$$__ ++# To make a very unlikely LABEL even more unlikely ... ++LABEL=__diffmk_$$__ + +-sed_script=' +- /^#ifdef '"${label}"'/,/^#endif \/\* '"${label}"'/ { +- /^#ifdef '"${label}"'/ s/.*/.mc '"${ADDMARK}"'/ +- /^#endif \/\* '"${label}"'/ s/.*/.mc/ ++SED_SCRIPT=' ++ /^#ifdef '"${LABEL}"'/,/^#endif \/\* '"${LABEL}"'/ { ++ /^#ifdef '"${LABEL}"'/ s/.*/.mc '"${ADDMARK}"'/ ++ /^#endif \/\* '"${LABEL}"'/ s/.*/.mc/ + p + d + } +- /^#ifndef '"${label}"'/,/^#endif \/\* [!not ]*'"${label}"'/ { +- /^#else \/\* '"${label}"'/,/^#endif \/\* '"${label}"'/ { +- /^#else \/\* '"${label}"'/ s/.*/.mc '"${CHANGEMARK}"'/ +- /^#endif \/\* '"${label}"'/ s/.*/.mc/ ++ /^#ifndef '"${LABEL}"'/,/^#endif \/\* [!not ]*'"${LABEL}"'/ { ++ /^#else \/\* '"${LABEL}"'/,/^#endif \/\* '"${LABEL}"'/ { ++ /^#else \/\* '"${LABEL}"'/ s/.*/.mc '"${CHANGEMARK}"'/ ++ /^#endif \/\* '"${LABEL}"'/ s/.*/.mc/ + p + d + } +- /^#endif \/\* \(not\|!\) '"${label}"'/ { ++ /^#endif \/\* \(not\|!\) '"${LABEL}"'/ { + s/.*/.mc '"${DELETEMARK}"'/p + a\ + .mc +@@ -291,27 +301,27 @@ + + if [ ${D_option} ] + then +- sed_script=' +- /^#ifdef '"${label}"'/,/^#endif \/\* '"${label}"'/ { +- /^#ifdef '"${label}"'/ s/.*/.mc '"${ADDMARK}"'/ +- /^#endif \/\* '"${label}"'/ s/.*/.mc/ ++ SED_SCRIPT=' ++ /^#ifdef '"${LABEL}"'/,/^#endif \/\* '"${LABEL}"'/ { ++ /^#ifdef '"${LABEL}"'/ s/.*/.mc '"${ADDMARK}"'/ ++ /^#endif \/\* '"${LABEL}"'/ s/.*/.mc/ + p + d + } +- /^#ifndef '"${label}"'/,/^#endif \/\* [!not ]*'"${label}"'/ { +- /^#ifndef '"${label}"'/ { ++ /^#ifndef '"${LABEL}"'/,/^#endif \/\* [!not ]*'"${LABEL}"'/ { ++ /^#ifndef '"${LABEL}"'/ { + i\ + '"${MARK1}"' + d + } +- /^#else \/\* '"${label}"'/ ! { +- /^#endif \/\* [!not ]*'"${label}"'/ ! { ++ /^#else \/\* '"${LABEL}"'/ ! { ++ /^#endif \/\* [!not ]*'"${LABEL}"'/ ! { + p + d + } + } +- /^#else \/\* '"${label}"'/,/^#endif \/\* '"${label}"'/ { +- /^#else \/\* '"${label}"'/ { ++ /^#else \/\* '"${LABEL}"'/,/^#endif \/\* '"${LABEL}"'/ { ++ /^#else \/\* '"${LABEL}"'/ { + i\ + '"${MARK2}"'\ + '"${br}"' +@@ -320,11 +330,11 @@ + .mc '"${CHANGEMARK}"' + d + } +- /^#endif \/\* '"${label}"'/ s/.*/.mc/ ++ /^#endif \/\* '"${LABEL}"'/ s/.*/.mc/ + p + d + } +- /^#endif \/\* \(not\|!\) '"${label}"'/ { ++ /^#endif \/\* \(not\|!\) '"${LABEL}"'/ { + i\ + '"${MARK2}"'\ + '"${br}"' +@@ -338,15 +348,7 @@ + ' + fi + +-diff -D"${label}" -- ${FILE1} ${FILE2} | +- sed -n "${sed_script}" ++${DIFFCMD} -D"${LABEL}" -- "${FILE1}" "${FILE2}" | ++ ${SEDCMD} -n "${SED_SCRIPT}" + + # EOF +- +- +-######################################################################## +-# Emacs settings +-# +-# Local Variables: +-# mode: text +-# End: +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/.gitignore groff-1.22.3/contrib/gdiffmk/.gitignore +--- groff-1.22.3.old/contrib/gdiffmk/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/gdiffmk/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,5 @@ ++gdiffmk ++gdiffmk.n ++tests/gdiffmk_tests.sh.log ++tests/gdiffmk_tests.sh.trs ++tests/result.* +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/Makefile.sub groff-1.22.3/contrib/gdiffmk/Makefile.sub +--- groff-1.22.3.old/contrib/gdiffmk/Makefile.sub 2014-11-04 10:38:35.446521234 +0200 ++++ groff-1.22.3/contrib/gdiffmk/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,51 +0,0 @@ +-# Makefile.sub for `gdiffmk' (integration into the groff source tree) +- +-# File position: /contrib/gdiffmk/Makefile.sub +- +-# Copyright (C) 2004-2014 Free Software Foundation, Inc. +-# Written by Mike Bianchi > +- +-# This file is part of the gdiffmk utility, which is part of groff. +- +-# groff is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +- +-# groff is distributed in the hope that it will be useful, but WITHOUT +-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +-# License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-######################################################################## +- +-MAN1=gdiffmk.n +-MOSTLYCLEANADD=gdiffmk tests/runtests +-RM=rm -f +- +-all: gdiffmk +- +-gdiffmk: gdiffmk.sh +- sed -e "s|@BINDIR@|$(bindir)|g" \ +- -e "s|@VERSION@|$(version)$(revision)|g" \ +- -e $(SH_SCRIPT_SED_CMD) $(srcdir)/gdiffmk.sh >$@ +- chmod +x $@ +- +-install_data: gdiffmk +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/gdiffmk +- $(INSTALL_SCRIPT) gdiffmk $(DESTDIR)$(bindir)/gdiffmk +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/gdiffmk +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/tests/baseline groff-1.22.3/contrib/gdiffmk/tests/baseline +--- groff-1.22.3.old/contrib/gdiffmk/tests/baseline 2014-11-04 10:38:35.620519059 +0200 ++++ groff-1.22.3/contrib/gdiffmk/tests/baseline 2015-04-23 20:57:03.000000000 +0300 +@@ -1,24 +1,3 @@ +-.ig \"-*- nroff -*- +-Copyright (C) 2004-2014 Free Software Foundation, Inc. +- +-This file is part of the gdiffmk utility, which is part of groff. +-Written by Mike Bianchi > +- +-Permission is granted to make and distribute verbatim copies of +-this manual provided the copyright notice and this permission notice +-are preserved on all copies. +- +-Permission is granted to copy and distribute modified versions of this +-manual under the conditions for verbatim copying, provided that the +-entire resulting derived work is distributed under the terms of a +-permission notice identical to this one. +- +-Permission is granted to copy and distribute translations of this +-manual into another language, under the above conditions for modified +-versions, except that this permission notice may be included in +-translations approved by the Free Software Foundation instead of in +-the original English. +-.. + .ll 25 + .pl 20 + .nf +@@ -36,8 +15,3 @@ + .mc + file1 and file2 #4 + file1 and file2 #5 +-. +-.\" Emacs setup +-.\" Local Variables: +-.\" mode: nroff +-.\" End: +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/tests/baseline.10 groff-1.22.3/contrib/gdiffmk/tests/baseline.10 +--- groff-1.22.3.old/contrib/gdiffmk/tests/baseline.10 2014-11-04 10:38:35.620519059 +0200 ++++ groff-1.22.3/contrib/gdiffmk/tests/baseline.10 2015-04-23 20:57:03.000000000 +0300 +@@ -1,24 +1,3 @@ +-.ig \"-*- nroff -*- +-Copyright (C) 2004-2014 Free Software Foundation, Inc. +- +-This file is part of the gdiffmk utility, which is part of groff. +-Written by Mike Bianchi > +- +-Permission is granted to make and distribute verbatim copies of +-this manual provided the copyright notice and this permission notice +-are preserved on all copies. +- +-Permission is granted to copy and distribute modified versions of this +-manual under the conditions for verbatim copying, provided that the +-entire resulting derived work is distributed under the terms of a +-permission notice identical to this one. +- +-Permission is granted to copy and distribute translations of this +-manual into another language, under the above conditions for modified +-versions, except that this permission notice may be included in +-translations approved by the Free Software Foundation instead of in +-the original English. +-.. + .ll 25 + .pl 20 + .nf +@@ -45,8 +24,3 @@ + .mc + file1 and file2 #4 + file1 and file2 #5 +-. +-.\" Emacs setup +-.\" Local Variables: +-.\" mode: nroff +-.\" End: +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/tests/baseline.6 groff-1.22.3/contrib/gdiffmk/tests/baseline.6 +--- groff-1.22.3.old/contrib/gdiffmk/tests/baseline.6 2014-11-04 10:38:35.620519059 +0200 ++++ groff-1.22.3/contrib/gdiffmk/tests/baseline.6 2015-04-23 20:57:03.000000000 +0300 +@@ -1,24 +1,3 @@ +-.ig \"-*- nroff -*- +-Copyright (C) 2004-2014 Free Software Foundation, Inc. +- +-This file is part of the gdiffmk utility, which is part of groff. +-Written by Mike Bianchi > +- +-Permission is granted to make and distribute verbatim copies of +-this manual provided the copyright notice and this permission notice +-are preserved on all copies. +- +-Permission is granted to copy and distribute modified versions of this +-manual under the conditions for verbatim copying, provided that the +-entire resulting derived work is distributed under the terms of a +-permission notice identical to this one. +- +-Permission is granted to copy and distribute translations of this +-manual into another language, under the above conditions for modified +-versions, except that this permission notice may be included in +-translations approved by the Free Software Foundation instead of in +-the original English. +-.. + .ll 25 + .pl 20 + .nf +@@ -36,8 +15,3 @@ + .mc + file1 and file2 #4 + file1 and file2 #5 +-. +-.\" Emacs setup +-.\" Local Variables: +-.\" mode: nroff +-.\" End: +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/tests/baseline.8 groff-1.22.3/contrib/gdiffmk/tests/baseline.8 +--- groff-1.22.3.old/contrib/gdiffmk/tests/baseline.8 2014-11-04 10:38:35.621519046 +0200 ++++ groff-1.22.3/contrib/gdiffmk/tests/baseline.8 2015-04-23 20:57:03.000000000 +0300 +@@ -1,24 +1,3 @@ +-.ig \"-*- nroff -*- +-Copyright (C) 2004-2014 Free Software Foundation, Inc. +- +-This file is part of the gdiffmk utility, which is part of groff. +-Written by Mike Bianchi > +- +-Permission is granted to make and distribute verbatim copies of +-this manual provided the copyright notice and this permission notice +-are preserved on all copies. +- +-Permission is granted to copy and distribute modified versions of this +-manual under the conditions for verbatim copying, provided that the +-entire resulting derived work is distributed under the terms of a +-permission notice identical to this one. +- +-Permission is granted to copy and distribute translations of this +-manual into another language, under the above conditions for modified +-versions, except that this permission notice may be included in +-translations approved by the Free Software Foundation instead of in +-the original English. +-.. + .ll 25 + .pl 20 + .nf +@@ -45,8 +24,3 @@ + .mc + file1 and file2 #4 + file1 and file2 #5 +-. +-.\" Emacs setup +-.\" Local Variables: +-.\" mode: nroff +-.\" End: +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/tests/baseline.9 groff-1.22.3/contrib/gdiffmk/tests/baseline.9 +--- groff-1.22.3.old/contrib/gdiffmk/tests/baseline.9 2014-11-04 10:38:35.621519046 +0200 ++++ groff-1.22.3/contrib/gdiffmk/tests/baseline.9 2015-04-23 20:57:03.000000000 +0300 +@@ -1,24 +1,3 @@ +-.ig \"-*- nroff -*- +-Copyright (C) 2004-2014 Free Software Foundation, Inc. +- +-This file is part of the gdiffmk utility, which is part of groff. +-Written by Mike Bianchi > +- +-Permission is granted to make and distribute verbatim copies of +-this manual provided the copyright notice and this permission notice +-are preserved on all copies. +- +-Permission is granted to copy and distribute modified versions of this +-manual under the conditions for verbatim copying, provided that the +-entire resulting derived work is distributed under the terms of a +-permission notice identical to this one. +- +-Permission is granted to copy and distribute translations of this +-manual into another language, under the above conditions for modified +-versions, except that this permission notice may be included in +-translations approved by the Free Software Foundation instead of in +-the original English. +-.. + .ll 25 + .pl 20 + .nf +@@ -45,8 +24,3 @@ + .mc + file1 and file2 #4 + file1 and file2 #5 +-. +-.\" Emacs setup +-.\" Local Variables: +-.\" mode: nroff +-.\" End: +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/tests/gdiffmk_tests.sh groff-1.22.3/contrib/gdiffmk/tests/gdiffmk_tests.sh +--- groff-1.22.3.old/contrib/gdiffmk/tests/gdiffmk_tests.sh 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/gdiffmk/tests/gdiffmk_tests.sh 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,9 @@ ++#!/bin/sh ++ ++# Execute runtests.sh in the builddir ++ ++set -e ++ ++mkdir -p ${abs_top_builddir}/contrib/gdiffmk/tests ++cd ${abs_top_builddir}/contrib/gdiffmk/tests ++${abs_top_srcdir}/contrib/gdiffmk/tests/runtests.sh run +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/tests/.gitignore groff-1.22.3/contrib/gdiffmk/tests/.gitignore +--- groff-1.22.3.old/contrib/gdiffmk/tests/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/gdiffmk/tests/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++test_result* ++tmp_file* ++runtests +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/tests/runtests.in groff-1.22.3/contrib/gdiffmk/tests/runtests.in +--- groff-1.22.3.old/contrib/gdiffmk/tests/runtests.in 2014-11-04 10:38:35.621519046 +0200 ++++ groff-1.22.3/contrib/gdiffmk/tests/runtests.in 1970-01-01 02:00:00.000000000 +0200 +@@ -1,118 +0,0 @@ +-#! /bin/sh +-# +-# A very simple function test for gdiffmk.sh. +-# +-# Copyright (C) 2004, 2005, 2009 Free Software Foundation, Inc. +-# Written by Mike Bianchi > +- +-# This file is part of the gdiffmk utility, which is part of groff. +- +-# groff is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +- +-# groff is distributed in the hope that it will be useful, but WITHOUT +-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +-# License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# This file is part of GNU gdiffmk. +- +-srcdir=@srcdir@ +- +-command=../gdiffmk +- +-# Test the number of arguments and the first argument. +-case $#-$1 in +-1-clean ) +- rm -fv result* tmp_file* +- exit 0 +- ;; +-1-run ) +- ;; +-* ) +- echo >&2 "$0 [ clean | run ] +-Run a few simple tests on \`${command}'."' +- +-clean Remove the result? and tmp_file? files. +-run Run the tests. +-' +- exit 255 +- ;; +-esac +- +-function TestResult { +- if cmp -s $1 $2 +- then +- echo $2 PASSED +- else +- echo '' +- echo $2 TEST FAILED +- diff $1 $2 +- echo '' +- fi +-} +- +-tmpfile=/tmp/$$ +-trap 'rm -f ${tmpfile}' 0 1 2 3 15 +- +-# Run tests. +- +-# 3 file arguments +-ResultFile=result.1 +-${command} ${srcdir}/file1 ${srcdir}/file2 ${ResultFile} 2>${tmpfile} +-cat ${tmpfile} >>${ResultFile} +-TestResult ${srcdir}/baseline ${ResultFile} +- +-# OUTPUT to stdout by default +-ResultFile=result.2 +-${command} ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 +-TestResult ${srcdir}/baseline ${ResultFile} +- +-# OUTPUT to stdout via - argument +-ResultFile=result.3 +-${command} ${srcdir}/file1 ${srcdir}/file2 - >${ResultFile} 2>&1 +-TestResult ${srcdir}/baseline ${ResultFile} +- +-# FILE1 from standard input via - argument +-ResultFile=result.4 +-${command} - ${srcdir}/file2 <${srcdir}/file1 >${ResultFile} 2>&1 +-TestResult ${srcdir}/baseline ${ResultFile} +- +-# FILE2 from standard input via - argument +-ResultFile=result.5 +-${command} ${srcdir}/file1 - <${srcdir}/file2 >${ResultFile} 2>&1 +-TestResult ${srcdir}/baseline ${ResultFile} +- +-# Different values for addmark, changemark, deletemark +-ResultFile=result.6 +-${command} -aA -cC -dD ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 +-TestResult ${srcdir}/baseline.6 ${ResultFile} +- +-# Test for accidental file overwrite. +-ResultFile=result.7 +-cp ${srcdir}/file2 tmp_file.7 +-${command} -aA -dD -cC ${srcdir}/file1 tmp_file.7 tmp_file.7 \ +- >${ResultFile} 2>&1 +-TestResult ${srcdir}/baseline.7 ${ResultFile} +- +-# Test -D option +-ResultFile=result.8 +-${command} -D ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 +-TestResult ${srcdir}/baseline.8 ${ResultFile} +- +-# Test -D and -M options +-ResultFile=result.9 +-${command} -D -M '<<<<' '>>>>' \ +- ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 +-TestResult ${srcdir}/baseline.9 ${ResultFile} +- +-# Test -D and -B options +-ResultFile=result.10 +-${command} -D -B ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 +-TestResult ${srcdir}/baseline.10 ${ResultFile} +- +-# EOF +diff -Nuar groff-1.22.3.old/contrib/gdiffmk/tests/runtests.sh groff-1.22.3/contrib/gdiffmk/tests/runtests.sh +--- groff-1.22.3.old/contrib/gdiffmk/tests/runtests.sh 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/gdiffmk/tests/runtests.sh 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,154 @@ ++#! /bin/sh ++# ++# A very simple function test for gdiffmk.sh. ++# ++# Copyright (C) 2004, 2005, 2009 Free Software Foundation, Inc. ++# Written by Mike Bianchi > ++ ++# This file is part of the gdiffmk utility, which is part of groff. ++ ++# groff is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# groff is distributed in the hope that it will be useful, but WITHOUT ++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ++# License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# This file is part of GNU gdiffmk. ++ ++# abs_top_srcdir and abs_top_builddir are set by AM_TESTS_ENVIRONMENT ++# (defined in Makefile.am) when running make check ++ ++srcdir=${abs_top_srcdir}/contrib/gdiffmk/tests ++ ++command=${abs_top_builddir}/gdiffmk ++ ++# Test the number of arguments and the first argument. ++case "$#-$1" in ++1-clean ) ++ rm -fv result* tmp_file* ++ exit 0 ++ ;; ++1-run ) ++ ;; ++* ) ++ echo >&2 "$0 [ clean | run ] ++Run a few simple tests on \`${command}'."' ++ ++clean Remove the result? and tmp_file? files. ++run Run the tests. ++' ++ exit 255 ++ ;; ++esac ++ ++exit_code=0 # Success ++failure_count=0 ++TestResult () { ++ if cmp -s $1 $2 ++ then ++ echo $2 PASSED ++ else ++ echo '' ++ echo $2 TEST FAILED ++ diff $1 $2 ++ echo '' ++ exit_code=1 # Failure ++ failure_count=`expr ${failure_count} + 1` ++ fi ++} ++ ++tmpfile=/tmp/$$ ++trap 'rm -f ${tmpfile}' 0 1 2 3 15 ++ ++# Run tests. ++ ++# 3 file arguments ++ResultFile=result.1 ++${command} ${srcdir}/file1 ${srcdir}/file2 ${ResultFile} 2>${tmpfile} ++cat ${tmpfile} >>${ResultFile} ++TestResult ${srcdir}/baseline ${ResultFile} ++ ++ ++# OUTPUT to stdout by default ++ResultFile=result.2 ++${command} ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline ${ResultFile} ++ ++ ++# OUTPUT to stdout via - argument ++ResultFile=result.3 ++${command} ${srcdir}/file1 ${srcdir}/file2 - >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline ${ResultFile} ++ ++ ++# FILE1 from standard input via - argument ++ResultFile=result.4 ++${command} - ${srcdir}/file2 <${srcdir}/file1 >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline ${ResultFile} ++ ++ ++# FILE2 from standard input via - argument ++ResultFile=result.5 ++${command} ${srcdir}/file1 - <${srcdir}/file2 >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline ${ResultFile} ++ ++ ++# Different values for addmark, changemark, deletemark ++ResultFile=result.6 ++${command} -aA -cC -dD ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline.6 ${ResultFile} ++ ++ ++# Different values for addmark, changemark, deletemark ++# Alternate format of -a -c and -d flag arguments ++ResultFile=result.6a ++${command} -a A -c C -d D ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline.6a ${ResultFile} ++ ++ ++# Test for accidental file overwrite. ++ResultFile=result.7 ++cp ${srcdir}/file2 tmp_file.7 ++${command} -aA -dD -cC ${srcdir}/file1 tmp_file.7 tmp_file.7 \ ++ >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline.7 ${ResultFile} ++ ++ ++# Test -D option ++ResultFile=result.8 ++${command} -D ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline.8 ${ResultFile} ++ ++ ++# Test -D and -M options ++ResultFile=result.9 ++${command} -D -M '<<<<' '>>>>' \ ++ ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline.9 ${ResultFile} ++ ++ ++# Test -D and -M options ++# Alternate format of -M argument. ++ResultFile=result.9a ++${command} -D -M'<<<<' '>>>>' \ ++ ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline.9a ${ResultFile} ++ ++ ++# Test -D and -B options ++ResultFile=result.10 ++${command} -D -B ${srcdir}/file1 ${srcdir}/file2 >${ResultFile} 2>&1 ++TestResult ${srcdir}/baseline.10 ${ResultFile} ++ ++ ++echo failure_count ${failure_count} ++ ++exit ${exit_code} ++ ++# EOF +diff -Nuar groff-1.22.3.old/contrib/glilypond/ChangeLog groff-1.22.3/contrib/glilypond/ChangeLog +--- groff-1.22.3.old/contrib/glilypond/ChangeLog 2014-11-04 10:38:35.452521159 +0200 ++++ groff-1.22.3/contrib/glilypond/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,18 @@ ++2015-04-03 Werner LEMBERG ++ ++ * glilypond.man: Make it work in compatibility mode. ++ (EL): Fix typo. ++ ++2015-03-20 Ralph Corderoy ++ ++ * glilypond.pl: Minor syntax fixes. ++ ++2015-03-20 Werner LEMBERG ++ ++ * glilypond.pl : Fix typo. ++ ++ Problem reported by Grégoire Babey . ++ + 2014-09-03 Bernd Warken + + * glilypond.pl: New version 1.3.1 +diff -Nuar groff-1.22.3.old/contrib/glilypond/examples/example.groff groff-1.22.3/contrib/glilypond/examples/example.groff +--- groff-1.22.3.old/contrib/glilypond/examples/example.groff 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/glilypond/examples/example.groff 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,48 @@ ++.\" -------------------------------------------------------------------- ++.\" Legalese ++.\" -------------------------------------------------------------------- ++. ++.ig ++glilypond - integrate `lilypond' parts into `groff' files ++ ++Source file position: /contrib/glilypond.man ++Installed position: /share/man/man1/glilypond.1 ++ ++This file was written by Bernd Warken . ++. ++Copyright (C) 2013-2014 Free Software Foundation, Inc. ++ ++This file is part of glilypond, which is part of GNU groff, a free ++software project. ++ ++You can redistribute it and/or modify it under the terms of the GNU ++General Public License version 2 as published by the Free Software ++Foundation. ++ ++The license text is available in the internet at ++.UR http://\%www.gnu.org/\%licenses/\%gpl-2.0.html ++.UE . ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" Groff Part ++.\" -------------------------------------------------------------------- ++. ++before ++.lilypond start ++\version "2.14.2" ++\relative c'' { ++ \key c \minor ++ g( ++ ) ++ -. ++ -. ++} ++\paper { ++ oddHeaderMarkup = #f ++ evenHeaderMarkup = #f ++ oddFooterMarkup = #f ++ evenFooterMarkup = #f ++} ++.lilypond end ++after +diff -Nuar groff-1.22.3.old/contrib/glilypond/glilypond.am groff-1.22.3/contrib/glilypond/glilypond.am +--- groff-1.22.3.old/contrib/glilypond/glilypond.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/glilypond/glilypond.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,63 @@ ++# Automake rules for `glilypond' ++ ++# File position: /contrib/lilypond/glilypond.am ++ ++# Copyright (C) 2013-2014 ++# Free Software Foundation, Inc. ++# Written by Werner Lemberg and ++# Bernd Warken . ++# Automake migration by Bertrand Garrigues ++ ++# This file is part of `glilypond' which is part of `groff'. ++ ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++######################################################################## ++glilypond_srcdir = $(top_srcdir)/contrib/glilypond ++bin_SCRIPTS += glilypond ++man1_MANS += contrib/glilypond/glilypond.n ++ ++# files going to lib directory `$(glilypond_dir)' ++# TODO glilypond_dir is subsitued by configure.ac, check if this could be removed ++glilyponddir = $(glilypond_dir) ++dist_glilypond_DATA = \ ++ contrib/glilypond/subs.pl \ ++ contrib/glilypond/oop_fh.pl \ ++ contrib/glilypond/args.pl ++ ++EXTRA_DIST += \ ++ contrib/glilypond/ChangeLog \ ++ contrib/glilypond/ChangeLog.0x \ ++ contrib/glilypond/glilypond.man \ ++ contrib/glilypond/glilypond.pl \ ++ contrib/glilypond/README.txt \ ++ contrib/glilypond/examples/example.groff ++ ++ ++# create perl executable `glilypond', being stored into `bindir' ++glilypond: $(glilypond_srcdir)/glilypond.pl shdeps.sed ++ $(RM) $@ ++ sed -f "$(SH_DEPS_SED_SCRIPT)" \ ++ -e "s|[@]g[@]|$(g)|g" \ ++ -e "s|[@]BINDIR[@]|$(DESTDIR)$(bindir)|g" \ ++ -e "s|[@]glilypond_dir[@]|$(DESTDIR)$(glilypond_dir)|g" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|g" \ ++ $(glilypond_srcdir)/glilypond.pl >$@ ++ chmod +x $@ ++ ++uninstall_groffdirs: uninstall-glilypond-hook ++uninstall-glilypond-hook: ++ if test -d $(DESTDIR)$(glilyponddir); then \ ++ rmdir $(DESTDIR)$(glilyponddir); \ ++ fi +diff -Nuar groff-1.22.3.old/contrib/glilypond/glilypond.man groff-1.22.3/contrib/glilypond/glilypond.man +--- groff-1.22.3.old/contrib/glilypond/glilypond.man 2014-11-04 10:38:35.452521159 +0200 ++++ groff-1.22.3/contrib/glilypond/glilypond.man 2015-04-23 20:57:03.000000000 +0300 +@@ -14,7 +14,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 2013-2014 Free Software Foundation, Inc. ++Copyright \(co 2013-2014 Free Software Foundation, Inc. + + This file is part of glilypond, which is part of GNU groff, a free + software project. +@@ -40,8 +40,8 @@ + .\" -------------------------------------------------------------------- + . + .\" Ellipsis ... +-.ie t .ds EL \fS\N'188'\fP +-.el .ds EL \&.\|.\|.\&\ ++.ie t .ds EL \fS\N'188'\fP\" ++.el .ds EL \&.\|.\|.\&\" + .\" called with \*(EL + . + .ad l +diff -Nuar groff-1.22.3.old/contrib/glilypond/glilypond.pl groff-1.22.3/contrib/glilypond/glilypond.pl +--- groff-1.22.3.old/contrib/glilypond/glilypond.pl 2014-11-04 10:38:35.452521159 +0200 ++++ groff-1.22.3/contrib/glilypond/glilypond.pl 2015-04-23 20:57:03.000000000 +0300 +@@ -13,7 +13,7 @@ + # use diagnostics; + + use Carp; +-$SIG[__DIE__] = sub { &Carp::croak; }; ++$SIG{__DIE__} = sub { &Carp::croak; }; + + use Data::Dumper; + +@@ -406,7 +406,7 @@ + $Temp->{'eps_dir'} = $dir; + $make_dir = TRUE; + } else { # could not remove +- stderr->print( "Could not use EPS dir `" . $dir . ++ $stderr->print( "Could not use EPS dir `" . $dir . + "', use temp dir." ); + } # end of unlink + } # end test of -d $dir +@@ -546,7 +546,7 @@ + $ly = new FH_FILE($path_ly); + + my $include = new FH_READ_FILE($file); +- my $res = $include->read-all(); # is a refernce to an array ++ my $res = $include->read_all(); # is a reference to an array + foreach ( @$res ) { + chomp; + $ly->print($_); +diff -Nuar groff-1.22.3.old/contrib/glilypond/Makefile.sub groff-1.22.3/contrib/glilypond/Makefile.sub +--- groff-1.22.3.old/contrib/glilypond/Makefile.sub 2014-11-04 10:38:35.452521159 +0200 ++++ groff-1.22.3/contrib/glilypond/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,81 +0,0 @@ +-# Makefile.sub for `glilypond' +- +-# File position: /contrib/lilypond/Makefile.sub +- +-# Copyright (C) 2013-2014 Free Software Foundation, Inc. +-# Written by Werner Lemberg and +-# Bernd Warken . +- +-# This file is part of `glilypond' which is part of `groff'. +- +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +- +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-######################################################################## +- +-MAN1=glilypond.n +- +-MOSTLYCLEANADD=glilypond $(MAN1) +- +-all: glilypond +- +-# files going to lib directory `$(glilypond_dir)' +- +-GLILYPOND_LIB=\ +- $(srcdir)/subs.pl \ +- $(srcdir)/oop_fh.pl \ +- $(srcdir)/args.pl +- +-GLILYPOND_LIB_=`echo $(GLILYPOND_LIB) | sed 's|$(srcdir)/||g'` +- +-RM=rm -f +- +-# create perl executable `glilypond', being stored into `bindir' +- +-glilypond: $(srcdir)/glilypond.pl +- $(RM) $@ +- sed -f "$(SH_DEPS_SED_SCRIPT)" \ +- -e "s|@g@|$(g)|g" \ +- -e "s|@BINDIR@|$(DESTDIR)$(bindir)|g" \ +- -e "s|@glilypond_dir@|$(DESTDIR)$(glilypond_dir)|g" \ +- -e "s|@VERSION@|$(version)$(revision)|g" \ +- $(srcdir)/glilypond.pl >$@ +- chmod +x $@ +- +-install_data: glilypond $(GLILYPOND_LIB) +- -test -d $(DESTDIR)$(bindir) \ +- || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/glilypond +- $(INSTALL_SCRIPT) glilypond $(DESTDIR)$(bindir)/glilypond +- -test -d $(DESTDIR)$(glilypond_dir) \ +- || $(mkinstalldirs) $(DESTDIR)$(glilypond_dir) +- for f in $(GLILYPOND_LIB_); do \ +- $(RM) $(DESTDIR)$(glilypond_dir)/$$f; \ +- $(INSTALL_SCRIPT) $(srcdir)/$$f $(DESTDIR)$(glilypond_dir)/$$f; \ +- done +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/glilypond +- -for f in $(GLILYPOND_LIB_); do \ +- $(RM) $(DESTDIR)$(glilypond_dir)/$$f; \ +- done +- -test -d $(DESTDIR)$(glilypond_dir) && \ +- rmdir $(DESTDIR)$(glilypond_dir) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/gperl/ChangeLog groff-1.22.3/contrib/gperl/ChangeLog +--- groff-1.22.3.old/contrib/gperl/ChangeLog 2014-11-04 10:38:35.457521097 +0200 ++++ groff-1.22.3/contrib/gperl/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,8 @@ ++2015-04-03 Werner LEMBERG ++ ++ * gperl.man: Make it work in compatibility mode. ++ (EL): Fix typo. ++ + 2014-10-11 Bernd Warken + + * gperl.pl: Version 1.2.6 +diff -Nuar groff-1.22.3.old/contrib/gperl/gperl.am groff-1.22.3/contrib/gperl/gperl.am +--- groff-1.22.3.old/contrib/gperl/gperl.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/gperl/gperl.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,42 @@ ++# Automake rules for `gperl' (preprocessor for added Perl parts) ++ ++# File position: /contrib/gperl/gperl.am ++ ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# Written by Bernd Warken . ++# Automake migration by Bertrand Garrigues ++ ++# This file is part of `gperl' which is part of `groff'. ++ ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++ ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see ++# . ++ ++######################################################################## ++ ++bin_SCRIPTS += gperl ++man1_MANS += contrib/gperl/gperl.n ++EXTRA_DIST += \ ++ contrib/gperl/ChangeLog \ ++ contrib/gperl/gperl.man \ ++ contrib/gperl/gperl.pl ++gperl: $(top_srcdir)/contrib/gperl/gperl.pl shdeps.sed ++ $(RM) $@ ++ sed -f "$(SH_DEPS_SED_SCRIPT)" \ ++ -e "s|[@]g[@]|$(g)|g" \ ++ -e "s|[@]BINDIR[@]|$(DESTDIR)$(bindir)|g" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|g" \ ++ -e "$(SH_SCRIPT_SED_CMD)" \ ++ $(top_srcdir)/contrib/gperl/gperl.pl >$@; \ ++ chmod +x $@ ++ +diff -Nuar groff-1.22.3.old/contrib/gperl/gperl.man groff-1.22.3/contrib/gperl/gperl.man +--- groff-1.22.3.old/contrib/gperl/gperl.man 2014-11-04 10:38:35.457521097 +0200 ++++ groff-1.22.3/contrib/gperl/gperl.man 2015-04-23 20:57:03.000000000 +0300 +@@ -16,7 +16,7 @@ + .. + . + .de co +-Copyright \[co] 2014 Free Software Foundation, Inc. ++Copyright \(co 2014 Free Software Foundation, Inc. + . + .P + This file is part of +@@ -46,12 +46,12 @@ + .\" -------------------------------------------------------------------- + . + .\" Ellipsis ... +-.ie t .ds EL \fS\N'188'\fP +-.el .ds EL \&.\|.\|.\&\ ++.ie t .ds EL \fS\N'188'\fP\" ++.el .ds EL \&.\|.\|.\&\" + .\" called with \*(EL + . + .\" Bullet +-.ie t .ds BU \[bu] ++.ie t .ds BU \(bu + .el .ds BU * + .\" used in `.IP \*(BU 2m' (former .Topic) + . +@@ -200,7 +200,7 @@ + .I other_than_start + can additionally be used as a + .I groff +-string variable name for storage \[em] see next section. ++string variable name for storage \(em see next section. + . + . + .\" -------------------------------------------------------------------- +@@ -228,7 +228,7 @@ + . + This pseudo-printing output can have several lines, due to printed + line breaks with +-.BR \[rs]n . ++.BR \(rsn . + . + By that, the output of a Perl run should be stored into a Perl array, + with a single line for each array member. +@@ -432,7 +432,7 @@ + . + .P + This stores the result +-.B \[rq]some data\[rq] ++.B \(rqsome data\(rq + into the + .I roff string + called +@@ -457,9 +457,9 @@ + .RS + .EX + \&.Perl start +-print \[rq]first\[rs]n\[rq]; +-print \[rq]second line\[rs]n\[rq]; +-print \[rq]3\[rs]n\[rq]; ++print \(rqfirst\(rsn\(rq; ++print \(rqsecond line\(rsn\(rq; ++print \(rq3\(rsn\(rq; + \&.Perl var1 var2 .nr var3 + .EE + .RE +diff -Nuar groff-1.22.3.old/contrib/gperl/Makefile.sub groff-1.22.3/contrib/gperl/Makefile.sub +--- groff-1.22.3.old/contrib/gperl/Makefile.sub 2014-11-04 10:38:35.457521097 +0200 ++++ groff-1.22.3/contrib/gperl/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,61 +0,0 @@ +-# Makefile.sub for `gperl' (preprocessor for added Perl parts) +- +-# File position: /contrib/gperl/Makefile.sub +- +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# Written by Bernd Warken . +- +-# This file is part of `gperl' which is part of `groff'. +- +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +- +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +- +-######################################################################## +- +-MAN1=gperl.n +- +-MOSTLYCLEANADD=gperl $(MAN1) +- +-# not all make programs have $(RM) predefined. +-RM=rm -f +- +-all: gperl +- +-gperl: gperl.pl +- sed -f "$(SH_DEPS_SED_SCRIPT)" \ +- -e "s|@g@|$(g)|g" \ +- -e "s|@BINDIR@|$(DESTDIR)$(bindir)|g" \ +- -e "s|@VERSION@|$(version)$(revision)|g" \ +- -e "$(SH_SCRIPT_SED_CMD)" \ +- $(srcdir)/gperl.pl >$@; \ +- chmod +x $@ +- +-.PHONY: install_data +-install_data: gperl +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/gperl +- $(INSTALL_SCRIPT) gperl $(DESTDIR)$(bindir)/gperl +- +-.PHONY: uninstall_sub +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/gperl +- +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/gpinyin/ChangeLog groff-1.22.3/contrib/gpinyin/ChangeLog +--- groff-1.22.3.old/contrib/gpinyin/ChangeLog 2014-11-04 10:38:35.462521034 +0200 ++++ groff-1.22.3/contrib/gpinyin/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,8 @@ ++2015-04-03 Werner LEMBERG ++ ++ * gpinyin.man: Make it work in compatibility mode. ++ (EL): Fix typo. ++ + 2014-10-11 Werner LEMBERG + + * Makefile.sub (gpinyin): Handle `gpinyin_dir'. +diff -Nuar groff-1.22.3.old/contrib/gpinyin/gpinyin.am groff-1.22.3/contrib/gpinyin/gpinyin.am +--- groff-1.22.3.old/contrib/gpinyin/gpinyin.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/gpinyin/gpinyin.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,52 @@ ++# Automake rules for `gpinyin' (preprocessor for added Perl parts) ++ ++# File position: /contrib/gpinyin/gpinyin.am ++ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# Written by Bernd Warken . ++# Moved to automake by Bertrand Garrigues ++ ++# This file is part of `gpinyin' which is part of `groff'. ++ ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++ ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see ++# . ++ ++######################################################################## ++ ++gpinyin_srcdir = $(top_srcdir)/contrib/gpinyin ++bin_SCRIPTS += gpinyin ++gpinyindir = $(gpinyin_dir) ++dist_gpinyin_DATA = contrib/gpinyin/subs.pl ++man1_MANS += contrib/gpinyin/gpinyin.n ++EXTRA_DIST += \ ++ contrib/gpinyin/ChangeLog \ ++ contrib/gpinyin/gpinyin.man \ ++ contrib/gpinyin/gpinyin.pl ++ ++gpinyin: contrib/gpinyin/gpinyin.pl ++ sed -f "$(SH_DEPS_SED_SCRIPT)" \ ++ -e "s|[@]g[@]|$(g)|g" \ ++ -e "s|[@]BINDIR[@]|$(DESTDIR)$(bindir)|g" \ ++ -e "s|[@]gpinyin_dir[@]|$(DESTIR)$(gpinyin_dir)|" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|g" \ ++ -e "$(SH_SCRIPT_SED_CMD)" \ ++ $(gpinyin_srcdir)/gpinyin.pl >$@; \ ++ chmod +x $@ ++ ++uninstall_groffdirs: uninstall-gpinyin-hook ++uninstall-gpinyin-hook: ++ if test -d $(DESTDIR)$(gpinyindir); then \ ++ rmdir $(DESTDIR)$(gpinyindir); \ ++ fi +diff -Nuar groff-1.22.3.old/contrib/gpinyin/gpinyin.man groff-1.22.3/contrib/gpinyin/gpinyin.man +--- groff-1.22.3.old/contrib/gpinyin/gpinyin.man 2014-11-04 10:38:35.462521034 +0200 ++++ groff-1.22.3/contrib/gpinyin/gpinyin.man 2015-04-23 20:57:03.000000000 +0300 +@@ -10,7 +10,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 2014 Free Software Foundation, Inc. ++Copyright \(co 2014 Free Software Foundation, Inc. + + This file is part of gpinyin, which is part of groff, a free software + project. +@@ -32,8 +32,8 @@ + .\" Characters + .\" -------------------------------------------------------------------- + . +-.ie t .ds EL \f[S]\N'188'\f[P] +-.el .ds EL \&.\|.\|.\&\ ++.ie t .ds EL \f[S]\N'188'\f[P]\" ++.el .ds EL \&.\|.\|.\&\" + .\" ie t .char \[Ellipsis] \f[S]\N'188'\f[P] + .\" el .char \[Ellipsis] \&.\|.\|.\&\ + .\" called with \[Ellipsis] +diff -Nuar groff-1.22.3.old/contrib/gpinyin/Makefile.sub groff-1.22.3/contrib/gpinyin/Makefile.sub +--- groff-1.22.3.old/contrib/gpinyin/Makefile.sub 2014-11-04 10:38:35.462521034 +0200 ++++ groff-1.22.3/contrib/gpinyin/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,71 +0,0 @@ +-# Makefile.sub for `gpinyin' (preprocessor for added Perl parts) +- +-# File position: /contrib/gpinyin/Makefile.sub +- +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# Written by Bernd Warken . +- +-# This file is part of `gpinyin' which is part of `groff'. +- +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +- +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +- +-######################################################################## +- +-MAN1=gpinyin.n +- +-MOSTLYCLEANADD=gpinyin $(MAN1) +- +-# not all make programs have $(RM) predefined. +-RM=rm -f +- +-all: gpinyin +- +-gpinyin: gpinyin.pl +- sed -f "$(SH_DEPS_SED_SCRIPT)" \ +- -e "s|@g@|$(g)|g" \ +- -e "s|@BINDIR@|$(DESTDIR)$(bindir)|g" \ +- -e "s|@gpinyin_dir@|$(DESTIR)$(gpinyin_dir)|" \ +- -e "s|@VERSION@|$(version)$(revision)|g" \ +- -e "$(SH_SCRIPT_SED_CMD)" \ +- $(srcdir)/gpinyin.pl >$@; \ +- chmod +x $@ +- +-.PHONY: install_data +-install_data: gpinyin subs.pl +- test -d $(DESTDIR)$(bindir) || \ +- $(mkinstalldirs) $(DESTDIR)$(bindir); \ +- $(RM) $(DESTDIR)$(bindir)/gpinyin; \ +- $(INSTALL_SCRIPT) gpinyin $(DESTDIR)$(bindir)/gpinyin; \ +- test -d $(DESTDIR)$(gpinyin_dir) || \ +- $(mkinstalldirs) $(DESTDIR)$(gpinyin_dir); \ +- $(RM) $(DESTDIR)$(gpinyin_dir)/subs.pl; \ +- $(INSTALL_SCRIPT) $(srcdir)/subs.pl \ +- $(DESTDIR)$(gpinyin_dir)/subs.pl +- +-.PHONY: uninstall_sub +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/gpinyin; \ +- $(RM) $(DESTDIR)$(gpinyin_dir)/subs.pl; +- -test -d $(DESTDIR)$(gpinyin_dir) && \ +- rmdir $(DESTDIR)$(gpinyin_dir) +- +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/grap2graph/.gitignore groff-1.22.3/contrib/grap2graph/.gitignore +--- groff-1.22.3.old/contrib/grap2graph/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/grap2graph/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,2 @@ ++grap2graph ++grap2graph.n +diff -Nuar groff-1.22.3.old/contrib/grap2graph/grap2graph.am groff-1.22.3/contrib/grap2graph/grap2graph.am +--- groff-1.22.3.old/contrib/grap2graph/grap2graph.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/grap2graph/grap2graph.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,31 @@ ++# Copyright (C) 2003-2014 Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++# grap2graph.am ++# ++ ++grap2graph_srcdir = $(top_srcdir)/contrib/grap2graph ++bin_SCRIPTS += grap2graph ++man1_MANS += contrib/grap2graph/grap2graph.n ++EXTRA_DIST += \ ++ $(grap2graph_srcdir)/grap2graph.sh \ ++ $(grap2graph_srcdir)/grap2graph.man ++grap2graph: $(grap2graph_srcdir)/grap2graph.sh ++ sed -e "s|[@]g[@]|$(g)|g" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|" \ ++ -e $(SH_SCRIPT_SED_CMD) $(grap2graph_srcdir)/grap2graph.sh >$@ ++ chmod +x $@ +diff -Nuar groff-1.22.3.old/contrib/grap2graph/Makefile.sub groff-1.22.3/contrib/grap2graph/Makefile.sub +--- groff-1.22.3.old/contrib/grap2graph/Makefile.sub 2014-11-04 10:38:35.466520984 +0200 ++++ groff-1.22.3/contrib/grap2graph/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,46 +0,0 @@ +-# Copyright (C) 2003-2014 Free Software Foundation, Inc. +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.sub +-# +-MAN1=grap2graph.n +-MOSTLYCLEANADD=grap2graph +-RM=rm -f +- +-all: grap2graph +- +-grap2graph: grap2graph.sh +- sed -e "s|@g@|$(g)|g" \ +- -e "s|@VERSION@|$(version)$(revision)|" \ +- -e $(SH_SCRIPT_SED_CMD) $(srcdir)/grap2graph.sh >$@ +- chmod +x $@ +- +-install_data: grap2graph +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/grap2graph +- $(INSTALL_SCRIPT) grap2graph $(DESTDIR)$(bindir)/grap2graph +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/grap2graph +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/groffer/ChangeLog groff-1.22.3/contrib/groffer/ChangeLog +--- groff-1.22.3.old/contrib/groffer/ChangeLog 2014-11-04 10:38:35.477520847 +0200 ++++ groff-1.22.3/contrib/groffer/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,20 @@ ++2015-04-04 Werner LEMBERG ++ ++ * roff2.man (EL): Fix typo. ++ ++2015-04-04 Werner LEMBERG ++ ++ * roff2.man: Make it work in compatibility mode. ++ ++2015-04-04 Werner LEMBERG ++ ++ * groffer.man: Make it work in compatibility mode. ++ (EL): Fix typo. ++ ++2015-03-20 Werner LEMBERG ++ ++ * subs.pl (where_is_prog): Fix typo. ++ + 2014-11-04 Werner LEMBERG + + * version.sh (_GROFF_VERSION_PRESET): Set to 1.22.3. +diff -Nuar groff-1.22.3.old/contrib/groffer/.gitignore groff-1.22.3/contrib/groffer/.gitignore +--- groff-1.22.3.old/contrib/groffer/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/groffer/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,24 @@ ++PERL ++SHELL ++groffer ++groffer.man ++groffer.n ++roff2x.n ++roff2x.man ++roff2x ++roff2text.n ++roff2text.man ++roff2text ++roff2ps.n ++roff2ps.man ++roff2ps ++roff2pdf.n ++roff2pdf.man ++roff2pdf ++roff2html.n ++roff2html.man ++roff2html ++roff2dvi.n ++roff2dvi.man ++roff2dvi ++HAVE_PERL +diff -Nuar groff-1.22.3.old/contrib/groffer/groffer.am groff-1.22.3/contrib/groffer/groffer.am +--- groff-1.22.3.old/contrib/groffer/groffer.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/groffer/groffer.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,106 @@ ++# Automake rules for `groffer' ++ ++# File position: /contrib/groffer/groffer.am ++ ++# Copyright (C) 2001-2014 ++# Free Software Foundation, Inc. ++# Written by Werner Lemberg and ++# Bernd Warken . ++# Automake migration by Bertrand Garrigues ++ ++# This file is part of `groffer' which is part of `groff'. ++ ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++ ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see ++# . ++ ++######################################################################## ++ ++groffer_srcdir = $(top_srcdir)/contrib/groffer ++# generated programs ++ROFF2PROGS = \ ++ roff2dvi \ ++ roff2html \ ++ roff2pdf \ ++ roff2ps \ ++ roff2text \ ++ roff2x ++ ++# Generated man templates ++ROFF2MAN = \ ++ contrib/groffer/roff2dvi.man \ ++ contrib/groffer/roff2html.man \ ++ contrib/groffer/roff2pdf.man \ ++ contrib/groffer/roff2ps.man \ ++ contrib/groffer/roff2text.man \ ++ contrib/groffer/roff2x.man ++ ++GROFFER_PERL = \ ++ contrib/groffer/main_subs.pl \ ++ contrib/groffer/man.pl \ ++ contrib/groffer/split_env.sh \ ++ contrib/groffer/subs.pl ++ ++GROFFER_REST = \ ++ contrib/groffer/roff2.man \ ++ contrib/groffer/version.sh \ ++ contrib/groffer/groffer.man \ ++ contrib/groffer/groffer.pl \ ++ contrib/groffer/roff2.pl ++ ++EXTRA_DIST += $(GROFFER_PERL) $(GROFFER_REST) \ ++ contrib/groffer/ChangeLog \ ++ contrib/groffer/README \ ++ contrib/groffer/README_PERL ++ ++# groffer_dir is set by a m4 macro ++grofferdir = $(groffer_dir) ++bin_SCRIPTS += groffer $(ROFF2PROGS) ++groffer_DATA = $(GROFFER_PERL) contrib/groffer/version.sh ++man1_MANS += \ ++ contrib/groffer/groffer.n \ ++ contrib/groffer/roff2dvi.n \ ++ contrib/groffer/roff2html.n \ ++ contrib/groffer/roff2pdf.n \ ++ contrib/groffer/roff2ps.n \ ++ contrib/groffer/roff2text.n \ ++ contrib/groffer/roff2x.n ++MOSTLYCLEANFILES += $(ROFF2MAN) ++ ++$(ROFF2PROGS): $(groffer_srcdir)/roff2.pl ++ cp $(groffer_srcdir)/roff2.pl $@; ++ ++# we take roff2.man and replace the @ROFF2MODE@ by the type of file ++# (dvi, pdf, html etc ...) ++$(ROFF2MAN): $(groffer_srcdir)/roff2.man ++ @$(MKDIR_P) contrib/groffer ++ FILEMODE=`echo $@ | sed 's|contrib/groffer/roff2\([a-z][a-z]*\)\.man|\1|g'` \ ++ && sed -e 's/[@]ROFF2MODE[@]/'"$$FILEMODE"'/g' $(groffer_srcdir)/roff2.man > $@; ++ ++groffer: $(GROFFER_PERL) $(GROFFER_REST) $(SH_DEPS_SED_SCRIPT) ++ echo "Using perl version of groffer."; \ ++ sed -f "$(SH_DEPS_SED_SCRIPT)" \ ++ -e "s|[@]g[@]|$(g)|g" \ ++ -e "s|[@]BINDIR[@]|$(DESTDIR)$(bindir)|g" \ ++ -e "s|[@]libdir[@]|$(DESTDIR)$(libdir)|g" \ ++ -e "s|[@]groffer_dir[@]|$(DESTDIR)$(groffer_dir)|g" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|g" \ ++ -e "$(SH_SCRIPT_SED_CMD)" \ ++ $(groffer_srcdir)/groffer.pl >$@; \ ++ chmod +x $@; ++ ++uninstall_groffdirs: uninstall-groffer-hook ++uninstall-groffer-hook: ++ if test -d $(DESTDIR)$(grofferdir); then \ ++ rmdir $(DESTDIR)$(grofferdir); \ ++ fi +diff -Nuar groff-1.22.3.old/contrib/groffer/groffer.man groff-1.22.3/contrib/groffer/groffer.man +--- groff-1.22.3.old/contrib/groffer/groffer.man 2014-11-04 10:38:35.477520847 +0200 ++++ groff-1.22.3/contrib/groffer/groffer.man 2015-04-23 20:57:03.000000000 +0300 +@@ -4,12 +4,22 @@ + . + .\" The .SH was moved to this place in order to appease `apropos'. + . ++. ++.\"********************************************************************* ++.\" ++.\" This man page doesn't use extended groff syntax! ++.\" Formatting it with and without groff's option `-C' should always ++.\" give the same result. ++.\" ++.\"********************************************************************* ++. ++. + .\" -------------------------------------------------------------------- + .\" Legalese + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 2001-2014 Free Software Foundation, Inc. ++Copyright \(co 2001-2014 Free Software Foundation, Inc. + + This file is part of groffer, which is part of groff, a free software + project. +@@ -35,12 +45,12 @@ + .\" -------------------------------------------------------------------- + . + .\" Ellipsis ... +-.ie t .ds EL \fS\N'188'\fP +-.el .ds EL \&.\|.\|.\&\ ++.ie t .ds EL \fS\N'188'\fP\" ++.el .ds EL \&.\|.\|.\&\" + .\" called with \*(EL + . + .\" Bullet +-.ie t .ds BU \[bu] ++.ie t .ds BU \(bu + .el .ds BU * + .\" used in `.IP \*(BU 2m' (former .Topic) + . +@@ -102,7 +112,7 @@ + The + .B \%groffer + program also includes many of the features for finding and displaying +-the \%\f[CR]Unix\f[] manual pages ++the \%\f(CRUnix\fP manual pages + .nh + .RI ( man\~pages ), + .hy +@@ -139,7 +149,7 @@ + . + This includes the + .I \%groff +-native \%\f[CR]X\~Window\f[] viewer ++native \%\f(CRX\~Window\fP viewer + .BR \%gxditview (@MAN1EXT@), + each + .IR \%Postcript , +@@ -175,7 +185,7 @@ + . + . + .P +-Option handling is done in \f[CR]GNU\f[] style. ++Option handling is done in \f(CRGNU\fP style. + . + Options and file names can be mixed freely. + . +@@ -294,7 +304,7 @@ + .OP \-\-troff\-device device + .YS + .P +-Further long options of \f[CR]GNU\f[] ++Further long options of \f(CRGNU\fP + .B man + are accepted as well. + .RE +@@ -365,7 +375,7 @@ + The name of a + .I man section + is a single character from +-.BR \%[1\[en]9on] , ++.BR \%[1\(en9on] , + the + .I extension + is some word. +@@ -524,7 +534,7 @@ + .IR "mode x" , + and + .I "mode dvi" +-in \%\f[CR]X\~Window\f[] with different viewers and ++in \%\f(CRX\~Window\fP with different viewers and + .I mode tty + with device + .I utf8 +@@ -535,14 +545,14 @@ + . + . + .P +-In \%\f[CR]X\~Window\f[], many programs create their own window when ++In \%\f(CRX\~Window\fP, many programs create their own window when + called. + . + .B \%groffer + can run these viewers as an independent program in the background. + . + As this does not work in text mode on a terminal (tty) there must be a +-way to know which viewers are \%\f[CR]X\~Window\f[] graphical ++way to know which viewers are \%\f(CRX\~Window\fP graphical + programs. + . + The +@@ -550,7 +560,7 @@ + script has a small set of information on some viewer names. + . + If a viewer argument of the command\-line chooses an element that is +-kept as \%\f[CR]X\~Window\f[] program in this list it is treated as a ++kept as \%\f(CRX\~Window\fP program in this list it is treated as a + viewer that can run in the background. + . + All other, unknown viewer calls are not run in the background. +@@ -620,7 +630,7 @@ + .SM + .BR $PATH . + . +-Known \%\f[CR]X\~Window\f[] ++Known \%\f(CRX\~Window\fP + .I \%dvi + viewers include + .BR \%xdvi (1) +@@ -781,7 +791,7 @@ + Format in a + .I \%groff\~text\~mode + and write the result to standard output using a text pager program, +-even when in \%\f[CR]X\~Window\f[]. ++even when in \%\f(CRX\~Window\fP. + . + . + .TP +@@ -800,7 +810,7 @@ + .BR \%gxditview (@MAN1EXT@) + program being distributed together with + .BR \%groff . +-But the standard \%\f[CR]X\~Window\f[] tool ++But the standard \%\f(CRX\~Window\fP tool + .BR \%xditview (1) + can also be chosen with the option + .BR \-\-viewer . +@@ -1281,7 +1291,7 @@ + .I \%filespec + argument search all + .I \%man\~pages +-and display their description \[em] or say that it is not a ++and display their description \(em or say that it is not a + .IR \%man\~page . + This is written from anew, so it differs from + .IR man 's +@@ -1355,10 +1365,10 @@ + . + The long options of + .B \%groffer +-were synchronized with the long options of \f[CR]GNU\f[] ++were synchronized with the long options of \f(CRGNU\fP + .BR man . + . +-All long options of \f[CR]GNU\f[] ++All long options of \f(CRGNU\fP + .B man + are recognized, but not all of these options are important to + .BR \%groffer , +@@ -1382,9 +1392,9 @@ + . + . + .P +-If your system has \f[CR]GNU\f[] ++If your system has \f(CRGNU\fP + .B man +-installed the full set of long and short options of the \f[CR]GNU\f[] ++installed the full set of long and short options of the \f(CRGNU\fP + .B man + program can be passed via the environment variable + .SM +@@ -1514,11 +1524,11 @@ + .\" -------------------------------------------------------------------- + . + The following long options were adapted from the corresponding +-\%\f[CR]X\~Window\~Toolkit\f[] options. ++\%\f(CRX\~Window\~Toolkit\fP options. + . + .B \%groffer + will pass them to the actual viewer program if it is an +-\%\f[CR]X\~Window\f[] program. ++\%\f(CRX\~Window\fP program. + . + Otherwise these options are ignored. + . +@@ -1534,14 +1544,14 @@ + .B \%groffer + uses the option + .B \-\-font +-for the \%\f[CR]X\~Window\f[] option ++for the \%\f(CRX\~Window\fP option + .BR \-font . + . + . + .P + See + .BR X (7) +-and the documentation on the \%\f[CR]X\~Window\~Toolkit\f[] options ++and the documentation on the \%\f(CRX\~Window\~Toolkit\fP options + for more details on these options and their arguments. + . + . +@@ -1581,8 +1591,8 @@ + . + .TP + .BI \-\-display \ X-display +-Set the \%\f[CR]X\~Window\f[] display on which the viewer program +-shall be started, see the \%\f[CR]X\~Window\f[] documentation for the ++Set the \%\f(CRX\~Window\fP display on which the viewer program ++shall be started, see the \%\f(CRX\~Window\fP documentation for the + syntax of the argument. + . + . +@@ -1607,7 +1617,7 @@ + .BI \-\-font \ font_name + Set the font used by the viewer window. + . +-The argument is an \%\f[CR]X\~Window\f[] font name. ++The argument is an \%\f(CRX\~Window\fP font name. + . + . + .TP +@@ -1628,7 +1638,7 @@ + . + .TP + .BI \-\-resolution \ value +-Set \%\f[CR]X\~Window\f[] resolution in dpi (dots per inch) in some ++Set \%\f(CRX\~Window\fP resolution in dpi (dots per inch) in some + viewer programs. + . + The only supported dpi values are +@@ -1656,7 +1666,7 @@ + . + .TP + .BI \-\-xrm \ 'resource' +-Set \f[CR]\%X\~Window\f[] resource. ++Set \f(CR\%X\~Window\fP resource. + . + . + .\" -------------------------------------------------------------------- +@@ -1790,12 +1800,12 @@ + . + . + .P +-The strange \%\f[CR]POSIX\f[] behavior to regard all arguments behind ++The strange \%\f(CRPOSIX\fP behavior to regard all arguments behind + the first non-option argument as + .I \%filespec + arguments is ignored. + . +-The \f[CR]GNU\f[] behavior to recognize options even when mixed with ++The \f(CRGNU\fP behavior to recognize options even when mixed with + .I \%filespec + arguments is used throughout. + . +@@ -1803,7 +1813,7 @@ + .B \-\- + ends the option handling and interprets all following arguments as + .I \%filespec +-arguments; so the \%\f[CR]POSIX\f[] behavior can be easily adopted. ++arguments; so the \%\f(CRPOSIX\fP behavior can be easily adopted. + . + . + .P +@@ -2026,7 +2036,7 @@ + . + .P + Several different modes are offered, graphical modes for +-\f[CR]\%X\~Window\f[], ++\f(CR\%X\~Window\fP, + .IR \%text\~modes , + and some direct + .I \%groff\~modes +@@ -2060,7 +2070,7 @@ + .SS "Graphical Display Modes" + .\" -------------------------------------------------------------------- + . +-The graphical display modes work mostly in the \%\f[CR]X\~Window\f[] ++The graphical display modes work mostly in the \%\f(CRX\~Window\fP + environment (or similar implementations within other windowing + environments). + . +@@ -2069,11 +2079,11 @@ + .B \%$DISPLAY + and the option + .B \-\-display +-are used for specifying the \%\f[CR]X\~Window\f[] display to be used. ++are used for specifying the \%\f(CRX\~Window\fP display to be used. + . + If this environment variable is empty + .B \%groffer +-assumes that no \%\f[CR]X\~Window\f[] is running and changes to a ++assumes that no \%\f(CRX\~Window\fP is running and changes to a + .IR \%text\~mode . + . + You can change this automatic behavior by the option +@@ -2082,7 +2092,7 @@ + . + .P + Known viewers for the graphical display modes and their standard +-\%\f[CR]X\~Window\f[] viewer programs are ++\%\f(CRX\~Window\fP viewer programs are + . + .IP \*(BU 2m + in a PDF viewer +@@ -2106,7 +2116,7 @@ + .hy + . + .IP \*(BU 2m +-\%\f[CR]X\~Window\f[] ++\%\f(CRX\~Window\fP + .I roff + viewers such as + .BR \%gxditview (@MAN1EXT@) +@@ -2125,7 +2135,7 @@ + .P + The + .I \%pdf\~mode +-has a major advantage \[em] it is the only graphical display mode that ++has a major advantage \(em it is the only graphical display mode that + allows to search for text within the viewer; this can be a really + important feature. + . +@@ -2135,12 +2145,12 @@ + . + .P + These graphical viewers can be customized by options of the +-\%\f[CR]X\~Window\~Toolkit\f[]. ++\%\f(CRX\~Window\~Toolkit\fP. + . + But the + .B \%groffer + options use a leading double minus instead of the single minus used by +-the \%\f[CR]X\~Window\~Toolkit\f[]. ++the \%\f(CRX\~Window\~Toolkit\fP. + . + . + .\" -------------------------------------------------------------------- +@@ -2315,7 +2325,7 @@ + .IR \%man\~pages . + . + All long options, all environment variables, and most of the +-functionality of the \f[CR]GNU\fP ++functionality of the \f(CRGNU\fP + .BR \%man (1) + program were implemented. + . +@@ -2509,7 +2519,7 @@ + The + .I default language + can be specified by specifying one of the pseudo-language parameters +-\f[CR]C\fP or \f[CR]\%POSIX\fP. ++\f(CRC\fP or \f(CR\%POSIX\fP. + . + This is like deleting a formerly given + .I language +@@ -2527,13 +2537,13 @@ + .I language + name is determined by + .BR man . +-In \f[CR]GNU\fP ++In \f(CRGNU\fP + .BR man , +-it is specified in the \%\f[CR]POSIX\~1003.1\fP based format: ++it is specified in the \%\f(CRPOSIX\~1003.1\fP based format: + .P + .nh +-\f[I]\/\f[][\f[CB]_\f[]\,\f[I]\/\f[][\f[CB].\fP\ +-\f[I]\/\f[][\f[CB],\fP\,\f[I]\/\fP]]], ++\fI\/\fP[\f(CB_\fP\,\fI\/\fP[\f(CB.\fP\ ++\fI\/\fP[\f(CB,\fP\,\fI\/\fP]]], + .hy + .P + but the two-letter code in +@@ -2613,8 +2623,8 @@ + file in a + .I section + directory has the form +-.IR \%\f[CB]man\fP
\f[CB]/\fP\f[CB].\fP
\ +-[][\f[CB].\fP] , ++.IR \%\f(CBman\fP
\f(CB/\fP\f(CB.\fP
\ ++[][\f(CB.\fP] , + where + .I \% + and +@@ -2753,7 +2763,7 @@ + .B /usr/share/man/man1/groff.1 + This is an uncompressed file for the + .I \%man\~page +-\f[CR]groff\fP in ++\f(CRgroff\fP in + .IR section\~1 . + . + It can be called by +@@ -2841,8 +2851,8 @@ + \fIsh#\fR\~groffer\~1e\~ctags + \fIsh#\fR\~groffer\~\-\-extension=e\~\-\-sections=1\~ctags + .EE +-where \f[CR]e\fP works as an abbreviation for the extension +-\f[CR]emacs21\fP. ++where \f(CRe\fP works as an abbreviation for the extension ++\f(CRemacs21\fP. + . + . + .TP +@@ -2912,7 +2922,7 @@ + .BR \%bzip2 (1) + it is decompressed on-the-fly. + . +-This includes the \f[CR]GNU\fP ++This includes the \f(CRGNU\fP + .BR \%.gz , + .BR \%.bz2 , + and the traditional +@@ -2934,7 +2944,7 @@ + . + All environment variables of + .BR \%groff (@MAN1EXT@) +-and \f[CR]GNU\fP ++and \f(CRGNU\fP + .BR \%man (1) + and some standard system variables are honored. + . +@@ -2972,7 +2982,7 @@ + .TP + .SM + .B \%$DISPLAY +-If this variable is set this indicates that the \%\f[CR]X\~Window\fP ++If this variable is set this indicates that the \%\f(CRX\~Window\fP + system is running. + . + Testing this variable decides on whether graphical or text output is +@@ -2981,7 +2991,7 @@ + This variable should not be changed by the user carelessly, but it can + be used to start the graphical + .B \%groffer +-on a remote \%\f[CR]X\~Window\fP terminal. ++on a remote \%\f(CRX\~Window\fP terminal. + . + For example, depending on your system, + .B \%groffer +@@ -3026,7 +3036,7 @@ + see + .BR \%setlocale (3). + . +-The locale values \f[CR]C\fP and \%\f[CR]POSIX\fP ++The locale values \f(CRC\fP and \%\f(CRPOSIX\fP + stand for the default, i.e.\& the + .I \%man\~page + directories without a language prefix. +@@ -3407,9 +3417,9 @@ + .BR /usr/local/share/doc/groff , + using the standard viewer + .B \%gxditview +-as graphical viewer when in \%\f[CR]X\~Window\fP, or the ++as graphical viewer when in \%\f(CRX\~Window\fP, or the + .BR \%less (1) +-pager program when not in \%\f[CR]X\~Window\fP. ++pager program when not in \%\f(CRX\~Window\fP. + . + .sp + .EX +@@ -3476,7 +3486,7 @@ + . + .sp + .EX +-\fIsh#\fR\~groffer\~groff\~\[cq]troff(1)\[cq]\~man:roff ++\fIsh#\fR\~groffer\~groff\~\(cqtroff(1)\(cq\~man:roff + .EE + .sp + The arguments that are not existing files are looked-up as the +@@ -3492,13 +3502,13 @@ + . + The quotes around + .nh +-.I \[cq]troff(1)\[cq] ++.I \(cqtroff(1)\(cq + .hy + are necessary because the parentheses are special shell characters; + escaping them with a backslash character +-.I \[rs]( ++.I \(rs( + and +-.I \[rs]) ++.I \(rs) + would be possible, too. + . + The formatted files are concatenated and displayed in one piece. +@@ -3581,12 +3591,12 @@ + . + .sp + .EX +-\fIsh#\fR\~echo\~'\[rs]f[CB]WOW!'\~| ++\fIsh#\fR\~echo\~'\(rsf(CBWOW!'\~| + > groffer \-\-x \-\-bg red \-\-fg yellow \-\-geometry 200x100 \- + .EE + .sp + . +-Display the word \f[CB]WOW!\fP in a small window in constant-width ++Display the word \f(CBWOW!\fP in a small window in constant-width + bold font, using color yellow on red background. + . + . +@@ -3602,9 +3612,9 @@ + .P + .B \%groffer + provides its own parser for command line arguments that is compatible +-to both \%\f[CR]POSIX\fP ++to both \%\f(CRPOSIX\fP + .BR \%getopts (1) +-and \%\f[CR]GNU\fP ++and \%\f(CRGNU\fP + .BR \%getopt (1). + It can handle option arguments and file names containing white space + and a large set of special characters. +@@ -3673,7 +3683,7 @@ + .I \%filespec + parameters follows the GNU principle. + . +-That does not fulfill the strange option behavior of \%\f[CR]POSIX\fP ++That does not fulfill the strange option behavior of \%\f(CRPOSIX\fP + that ends option processing as soon as the first non-option argument + has been reached. + . +diff -Nuar groff-1.22.3.old/contrib/groffer/Makefile.sub groff-1.22.3/contrib/groffer/Makefile.sub +--- groff-1.22.3.old/contrib/groffer/Makefile.sub 2014-11-04 10:38:35.478520834 +0200 ++++ groff-1.22.3/contrib/groffer/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,109 +0,0 @@ +-# Makefile.sub for `groffer' (integration into the `groff' source tree) +- +-# File position: /contrib/groffer/Makefile.sub +- +-# Copyright (C) 2001-2014 Free Software Foundation, Inc. +-# Written by Werner Lemberg and +-# Bernd Warken . +- +-# This file is part of `groffer' which is part of `groff'. +- +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +- +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +- +-######################################################################## +- +-ROFF2MODES=dvi html pdf ps text x +-ROFF2PROGS=`echo $(ROFF2MODES) | sed 's/[a-z][a-z]*/roff2&/g'` +-ROFF2MAN=`echo $(ROFF2MODES) | sed 's/[a-z][a-z]*/roff2&.man/g'` +-ROFF2N=`echo $(ROFF2MODES) | sed 's/[a-z][a-z]*/roff2&.n/g'` +- +-MAN1=groffer.n \ +- roff2dvi.n \ +- roff2html.n \ +- roff2pdf.n \ +- roff2ps.n \ +- roff2text.n \ +- roff2x.n +- +-MOSTLYCLEANADD=groffer $(MAN1) $(ROFF2MAN) $(ROFF2N) $(ROFF2PROGS) +- +-RM=rm -f +- +-all: groffer +- +-GROFFER_PERL=subs.pl \ +- main_subs.pl \ +- man.pl \ +- split_env.sh +-GROFFER_REST=roff2.man \ +- version.sh \ +- groffer.man \ +- groffer.pl \ +- roff2.pl +- +-groffer: $(GROFFER_PERL) $(GROFFER_REST) $(SH_DEPS_SED_SCRIPT) +- sed -f "$(SH_DEPS_SED_SCRIPT)" \ +- -e "s|@g@|$(g)|g" \ +- -e "s|@BINDIR@|$(DESTDIR)$(bindir)|g" \ +- -e "s|@libdir@|$(DESTDIR)$(libdir)|g" \ +- -e "s|@groffer_dir@|$(DESTDIR)$(groffer_dir)|g" \ +- -e "s|@VERSION@|$(version)$(revision)|g" \ +- -e "$(SH_SCRIPT_SED_CMD)" \ +- $(srcdir)/groffer.pl >$@; \ +- for f in $(ROFF2PROGS); do \ +- cp $(srcdir)/roff2.pl $$f; \ +- done; \ +- chmod +x $@ +- for m in $(ROFF2MODES); do \ +- cat $(srcdir)/roff2.man \ +- | sed 's/@ROFF2MODE@/'"$$m"'/g' > roff2$${m}.man; \ +- done +- +-install_data: groffer +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/groffer +- $(INSTALL_SCRIPT) groffer $(DESTDIR)$(bindir)/groffer +- for f in $(ROFF2PROGS); do \ +- $(RM) $(DESTDIR)$(bindir)/$$f; \ +- $(INSTALL_SCRIPT) $$f $(DESTDIR)$(bindir)/$$f; \ +- done +- -test -d $(DESTDIR)$(groffer_dir) \ +- || $(mkinstalldirs) $(DESTDIR)$(groffer_dir) +- $(RM) $(DESTDIR)$(groffer_dir)/version.sh +- $(INSTALL_DATA) $(srcdir)/version.sh $(DESTDIR)$(groffer_dir)/version.sh +- for f in $(GROFFER_PERL); do \ +- $(RM) $(DESTDIR)$(groffer_dir)/$$f; \ +- done +- for f in $(GROFFER_PERL); do \ +- $(INSTALL_SCRIPT) $(srcdir)/$$f $(DESTDIR)$(groffer_dir)/$$f; \ +- done; +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/groffer +- -for f in $(ROFF2PROGS); do $(RM) $(DESTDIR)$(bindir)/$$f; done +- -for f in $(GROFFER_PERL) version.sh; do \ +- $(RM) $(DESTDIR)$(groffer_dir)/$$f;\ +- done +- -test -d $(DESTDIR)$(libdir)/groff/groffer && \ +- rmdir $(DESTDIR)$(libdir)/groff/groffer +- +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/groffer/roff2.man groff-1.22.3/contrib/groffer/roff2.man +--- groff-1.22.3.old/contrib/groffer/roff2.man 2014-11-04 10:38:35.478520834 +0200 ++++ groff-1.22.3/contrib/groffer/roff2.man 2015-04-23 20:57:03.000000000 +0300 +@@ -13,7 +13,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 2006-2014 Free Software Foundation, Inc. ++Copyright \(co 2006-2014 Free Software Foundation, Inc. + + This file is part of groffer, which is part of GNU groff, a free + software project. +@@ -39,8 +39,8 @@ + .\" -------------------------------------------------------------------- + . + .\" Ellipsis ... +-.ie t .ds EL \fS\N'188'\fP +-.el .ds EL \&.\|.\|.\&\ ++.ie t .ds EL \fS\N'188'\fP\" ++.el .ds EL \&.\|.\|.\&\" + .\" called with \*(EL + . + . +diff -Nuar groff-1.22.3.old/contrib/groffer/subs.pl groff-1.22.3/contrib/groffer/subs.pl +--- groff-1.22.3.old/contrib/groffer/subs.pl 2014-11-04 10:38:35.478520834 +0200 ++++ groff-1.22.3/contrib/groffer/subs.pl 2015-04-23 20:57:03.000000000 +0300 +@@ -749,7 +749,7 @@ + my @baseargs = ($n); + while (@base) { + my $base = join(' ', @base); +- foreach my $d (@maon::Path) { ++ foreach my $d (@main::Path) { + my $file = File::Spec->catfile($d, $base); + if (-f $file && -x $file) { + my $baseargs = join(' ', @baseargs); +diff -Nuar groff-1.22.3.old/contrib/groff_filenames/ChangeLog groff-1.22.3/contrib/groff_filenames/ChangeLog +--- groff-1.22.3.old/contrib/groff_filenames/ChangeLog 2014-11-04 10:38:35.471520922 +0200 ++++ groff-1.22.3/contrib/groff_filenames/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,7 @@ ++2015-04-03 Werner LEMBERG ++ ++ * groff_filenames.man: Make it work in compatibility mode. ++ + 2014-09-03 Bernd Warken + + * groff_filenames.man, Makefile.sub: Repair copying and Emacs +diff -Nuar groff-1.22.3.old/contrib/groff_filenames/groff_filenames.am groff-1.22.3/contrib/groff_filenames/groff_filenames.am +--- groff-1.22.3.old/contrib/groff_filenames/groff_filenames.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/groff_filenames/groff_filenames.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,30 @@ ++# Automake rules for `groff_filenames' ++ ++# File position: /contrib/groff_filenames/groff_filenames.am ++ ++# Copyright (C) 2013-2014 Free Software Foundation, Inc. ++# ++# Written by Bernd Warken . ++# Automake migration by Bertrand Garrigues ++ ++# This file is part of `groff'. ++ ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++ ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++######################################################################## ++ ++man7_MANS += contrib/groff_filenames/groff_filenames.n ++EXTRA_DIST += \ ++ contrib/groff_filenames/ChangeLog \ ++ contrib/groff_filenames/groff_filenames.man +diff -Nuar groff-1.22.3.old/contrib/groff_filenames/groff_filenames.man groff-1.22.3/contrib/groff_filenames/groff_filenames.man +--- groff-1.22.3.old/contrib/groff_filenames/groff_filenames.man 2014-11-04 10:38:35.471520922 +0200 ++++ groff-1.22.3/contrib/groff_filenames/groff_filenames.man 2015-04-23 20:57:03.000000000 +0300 +@@ -10,7 +10,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 2013-2014 Free Software Foundation, Inc. ++Copyright \(co 2013-2014 Free Software Foundation, Inc. + + This file is part of groff, a free software project. You can + redistribute it and/or modify it under the terms of the GNU General +@@ -74,7 +74,7 @@ + .IR "compressor name" . + . + So the whole filename has the structure +-.IR \f[CB].\fP [ \f[CB].\fP ] . ++.IR \f(CB.\fP [ \f(CB.\fP ] . + . + . + .P +@@ -635,13 +635,13 @@ + . + .P + .UR https://\:github.com/\:n-t-roff/\:heirloom-doctools +-.I Gunnar Ritter\[aq]s Heirloom roff project ++.I Gunnar Ritter\(aqs Heirloom roff project + .UE . + . + You can get this package with the shell command: + .RS + .EX +-\[Do] git clone https://github.com/n-t-roff/heirloom-doctools ++\(Do git clone https://github.com/n-t-roff/heirloom-doctools + .EE + .RE + . +diff -Nuar groff-1.22.3.old/contrib/groff_filenames/Makefile.sub groff-1.22.3/contrib/groff_filenames/Makefile.sub +--- groff-1.22.3.old/contrib/groff_filenames/Makefile.sub 2014-11-04 10:38:35.471520922 +0200 ++++ groff-1.22.3/contrib/groff_filenames/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,35 +0,0 @@ +-# Makefile.sub for `groff_filenames' (integration into the `groff' source tree) +- +-# File position: /contrib/groff_filenames/Makefile.sub +- +-# Copyright (C) 2013-2014 Free Software Foundation, Inc. +-# +-# Written by Bernd Warken . +- +-# This file is part of `groff'. +- +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +- +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-######################################################################## +- +-MAN7=\ +- groff_filenames.n +- +-MOSTLYCLEANADD=$(MAN7) +- +-######################################################################## +-##### Emacs settings +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/hdtbl/ChangeLog groff-1.22.3/contrib/hdtbl/ChangeLog +--- groff-1.22.3.old/contrib/hdtbl/ChangeLog 2014-11-04 10:38:35.482520784 +0200 ++++ groff-1.22.3/contrib/hdtbl/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,15 @@ ++2015-04-03 Werner LEMBERG ++ ++ Fix Savannah bug #44798. ++ ++ * examples/fonts_n.in, examples/fonts_x.in: Use @EGREP@. ++ ++ * hdtbl.am (.in.roff): Handle @EGREP@. ++ ++2015-04-03 Werner LEMBERG ++ ++ * groff_hdtbl.man: Make it work in compatibility mode. ++ + 2013-09-03 Bernd Warken + + * all files in groff_hdtbl: Copying and Emacs setup. +diff -Nuar groff-1.22.3.old/contrib/hdtbl/examples/fonts_n.in groff-1.22.3/contrib/hdtbl/examples/fonts_n.in +--- groff-1.22.3.old/contrib/hdtbl/examples/fonts_n.in 2014-11-04 10:38:35.593519396 +0200 ++++ groff-1.22.3/contrib/hdtbl/examples/fonts_n.in 2015-04-23 20:57:03.000000000 +0300 +@@ -102,7 +102,7 @@ + . TBL border=.1n bc=red cpd=0 csp=.1n bgc= + . CPTN groff font \\*[*$1] \ + .br \ +- val=b ".pso grep -e internalname \\*[fontpath]/dev\*[.T]/\\*[*$1]" ++ val=b ".pso @EGREP@ internalname \\*[fontpath]/dev\*[.T]/\\*[*$1]" + . TR + . TD + . TBL cols=12 border=.1n bc=red csp=.1n cpd=.2n fgc=red4 bgc=beige \ +diff -Nuar groff-1.22.3.old/contrib/hdtbl/examples/fonts_x.in groff-1.22.3/contrib/hdtbl/examples/fonts_x.in +--- groff-1.22.3.old/contrib/hdtbl/examples/fonts_x.in 2014-11-04 10:38:35.593519396 +0200 ++++ groff-1.22.3/contrib/hdtbl/examples/fonts_x.in 2015-04-23 20:57:03.000000000 +0300 +@@ -102,7 +102,7 @@ + . TBL border=.1n bc=red cpd=0 csp=.1n bgc= + . CPTN groff font \\*[*$1] \ + .br \ +- val=b ".pso grep -e internalname \\*[fontpath]/dev\*[.T]/\\*[*$1]" ++ val=b ".pso @EGREP@ internalname \\*[fontpath]/dev\*[.T]/\\*[*$1]" + . TR + . TD + . TBL cols=18 border=.1n bc=red csp=.1n cpd=.2n fgc=red4 bgc=beige \ +diff -Nuar groff-1.22.3.old/contrib/hdtbl/examples/.gitignore groff-1.22.3/contrib/hdtbl/examples/.gitignore +--- groff-1.22.3.old/contrib/hdtbl/examples/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/hdtbl/examples/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,14 @@ ++stamp ++short_reference.ps ++rainbow.ps ++mixed_pickles.ps ++fonts_x.roff ++fonts_x.ps ++fonts_n.roff ++fonts_n.ps ++color_transitions.ps ++color_table_cells.ps ++color_nested_tables.ps ++color_boxes.ps ++col_rowspan_colors.ps ++chess_board.ps +diff -Nuar groff-1.22.3.old/contrib/hdtbl/.gitignore groff-1.22.3/contrib/hdtbl/.gitignore +--- groff-1.22.3.old/contrib/hdtbl/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/hdtbl/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,5 @@ ++stamp-strip ++hdtbl.tmac-s ++hdmisc.tmac-s ++groff_hdtbl.n ++gnu.eps +diff -Nuar groff-1.22.3.old/contrib/hdtbl/groff_hdtbl.man groff-1.22.3/contrib/hdtbl/groff_hdtbl.man +--- groff-1.22.3.old/contrib/hdtbl/groff_hdtbl.man 2014-11-04 10:38:35.483520772 +0200 ++++ groff-1.22.3/contrib/hdtbl/groff_hdtbl.man 2015-04-23 20:57:03.000000000 +0300 +@@ -3,6 +3,10 @@ + groff_hdtbl \- groff `hdtbl' macros for generation of tables + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" Legalese + .\" -------------------------------------------------------------------- +@@ -1261,7 +1265,7 @@ + .au + . + . +-.\" EOF ++.cp \n[groff_C] + . + . + .\" -------------------------------------------------------------------- +diff -Nuar groff-1.22.3.old/contrib/hdtbl/hdmisc.tmac groff-1.22.3/contrib/hdtbl/hdmisc.tmac +--- groff-1.22.3.old/contrib/hdtbl/hdmisc.tmac 2014-11-04 10:38:35.483520772 +0200 ++++ groff-1.22.3/contrib/hdtbl/hdmisc.tmac 1970-01-01 02:00:00.000000000 +0200 +@@ -1,325 +0,0 @@ +-.\" -*- mode: nroff -*- +-.ig +- +-hdmisc.tmac +- +-This file is part of groff, the GNU roff type-setting system. +- +-Copyright (C) 2005-2014 Free Software Foundation, Inc. +-written by Joachim Walsdorff . +- +-groff is free software; you can redistribute it and/or modify it under +-the terms of the GNU General Public License as published by the Free +-Software Foundation, either version 3 of the License, or +-(at your option) any later version. +- +-groff is distributed in the hope that it will be useful, but WITHOUT +-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-for more details. +- +-You should have received a copy of the GNU General Public License +-along with this program. If not, see . +- +-.. +-. +-. +-.\" %beginstrip% +-. +-.if d t*getarg \ +-. nx +-. +-. +-.\" ****************************************************************** +-.\" ** Some macros and default settings needed by hdtbl ** +-.\" ****************************************************************** +-. +-. +-.\" Utility macro: .getarg ... +-.\" +-.\" Get macro argument. This macro searches in the +-.\" remaining arguments and assigns its value to a string +-.\" register named . The following syntax forms are +-.\" recognized. +-.\" +-.\" = Assign to string . +-.\" must not contain spaces. +-.\" ='' Assign to string . +-.\" can contain spaces. +-.\" = Assign `=' to string . +-.\" Assign `key' to string . +-.\" +-.\" After return, the string `args' contains the remaining +-.\" arguments. +-.\" +-.\" Example: With the definition of string `foo' as +-.\" +-.\" .ds foo aaa=xxx bbb ccc='yyy zzz' ddd= eee +-.\" +-.\" a call to `getarg' with +-.\" +-.\" .getarg ccc \*[foo] +-.\" +-.\" sets string `ccc' to value `yyy zzz'. The string `args' +-.\" now contains `aaa=xxx bbb ddd= eee'. An additional call +-.\" like +-.\" +-.\" .getarg ddd \*[args] +-.\" +-.\" sets string `ddd' to value `=', and `args' contains +-.\" `aaa=xxx bbb eee'. +-.de t*getarg +-. ds \\$1 +-. ds args +-. +-. if (\\n[.$] < 2) \ +-. return +-. +-. ds $1 \\$1\" +-. shift +-. +-. length * \\*[$1] +-. while \\n[.$] \{\ +-. ds * "\\$1\" +-. ds ** "\\$1\" +-. length ** \\*[**] +-. shift +-. if (\\n[*] > \\n[**]) \{\ +-. as args " "\\*[**]"\" value too short, repeat +-. continue +-. \} +-. substring * 0 (\\n[*] - 1) +-. \" The surrounding \? escapes emulate string comparison. +-. ie !"\?\\*[$1]\?"\?\\*[*]\?" \{\ +-. as args " "\\*[**]"\" key not found, repeat +-. continue +-. \} +-. el \{\ +-. ie "\?\\*[**]\?"\?\\*[$1]\?" \ +-. ds \\*[$1] \\*[$1]\" return key as string +-. el \{\ +-. ie "\?\\*[**]\?"\?\\*[$1]=\?" \ +-. ds \\*[$1] =\" return `=' +-. el \{\ +-. substring ** (\\n[*] + 1) -1 +-. ds * \\*[**]\" +-. substring * 0 0 +-. +-. \" check whether value starts with quote +-. if "\?\\*[*]\?"\?'\?" \{\ +-. substring ** 1 -1 +-. ds * \\*[**]\" +-. substring * -1 -1 +-. +-. \" search final quote +-. ie "\?\\*[*]\?"\?'\?" \ +-. substring ** 0 -2 +-. el \{\ +-. as \\*[$1] \\*[**] \" not found, append argument +-. +-. while 1 \{\ +-. ds ** \\$1\" get next argument +-. ds * \\$1\" +-. shift +-. substring * -1 -1 +-. +-. if "\?\\*[*]\?"\?'\?" \{\ +-. substring ** 0 -2 +-. break \" break if no final quote +-. \} +-. +-. as \\*[$1] \\*[**] \" otherwise append and repeat +-. \} +-. \}\} +-. +-. as \\*[$1] \\*[**]\" +-. \} +-. +-. as args " \\$@\" +-. \}\} +-. +-. return +-. \} +-.. +-. +-. +-.\" Utility macro: .index +-.\" +-.\" Check whether is a substring of and +-.\" return its position in number register `t*index', starting +-.\" with 1. If not found, return 0. If is empty, +-.\" set `t*index' to -999. +-.de t*index +-. if "\\$2"" \{\ +-. nr t*index -999 +-. return +-. \} +-. +-. length ** \\$1 +-. length $2 \\$2 +-. nr * 0-1 1 +-. +-. while (\\n+[*] < \\n[**]) \{\ +-. ds * \\$1\" +-. substring * \\n[*] (\\n[*] + \\n[$2] - 1) +-. \" The surrounding \? escapes emulate string comparison. +-. if "\?\\*[*]\?"\?\\$2\?" \ +-. break +-. \} +-. +-. ie (\\n[*] == \\n[**]) \ +-. nr t*index 0 +-. el \ +-. nr t*index (\\n[*] + 1) +-.. +-. +-. +-.\" ****************************************************************** +-.\" ******** non-accumulating space .t*SP [v] ********** +-.\" ** ** +-.\" ** nl vor erster Seite -1, oben auf Seite 0 resp. tH ** +-.\" ** .k nach .sp oder .br 0, ** +-.\" ** sonst Laenge der angefangenen Zeile ** +-.\" ** Der Merker M# fuer vorangegangenes .t*SP wird in .HM am ** +-.\" ** Seitenanfang zurueckgesetzt. ** +-.\" ** ganz richtig ist .sp + .br = .br + .sp = .sp ** +-.\" ****************************************************************** +-.de t*SP +-. if (\\n[nl] < 0) \ +-. br \" start very first page +-. nr * \\n[.p] \" save current page length +-. +-. ie "\\$1"" \ +-. pl +1 \" without arg increase page length by 1v +-. el \ +-. pl +\\$1 \" otherwise use \\$1 +-. +-. nr ** (\\n[.p] - \\n[*]) \" ** now holds arg for .t*SP in base units +-. pl \\n[*]u \" restore page length +-. +-. \" we do nothing at start of new page or column +-. if ((\\n[nl] - \\n[tH]) & (\\n[nl] - \\n[<<]) : \\n[.k]) \{\ +-. ie ((\\n[.d] - \\n[M#]) : \\n[.k]) \{\ +-. sp \\n[**]u \" execute .sp +-. nr S# \\n[**] \" store ** in S# +-. \} +-. el \{\ +-. if (\\n[**] - \\n[S#]) \{\ +-. sp (\\n[**]u - \\n[S#]u)\" emit difference to previous .t*SP +-. nr S# \\n[**] \" store ** in S# +-. \}\} +-. +-. nr M# \\n[.d] \" store vertical position .d in M# +-. \} +-.. +-. +-. +-.\" ****************************************************************** +-.\" ** Perform all arguments once ** +-.\" ** P1 is nestable ** +-.\" ****************************************************************** +-.de t*P1 +-. \" `while' command is about five times faster than recursion! +-. while \\n[.$] \{\ +-. nop \\$1 +-. shift +-. \} +-.. +-. +-. +-.\" ****************************************************************** +-.\" ** Hilfsmakro zum Einstellen von Schriftgroesse und ** +-.\" ** Zeilenabstand, bezogen auf Anfangswerte \n[t*s] ** +-.\" ** und \n[t*v] sowie fuer Hyphenation: ** +-.\" ** .pv s v hy# hart; macht .br ** +-.\" ** Bei 4. Argument setzen der Register s und v und hy. ** +-.\" ** Fuer angefangene Zeile die vorgefundenen Einstellungen ** +-.\" ** ** +-.\" ** Auxiliary macro to set internal registers for font size ** +-.\" ** and line spacing, relative to initial values \n[t*s] and ** +-.\" ** \n[t*v]. Optionally sets hyphenation. A fourth argument ** +-.\" ** initializes internal registers to global default values. ** +-.\" ****************************************************************** +-.de t*pv +-. br +-. +-. if \\n[.$] \ +-. ps (\\n[t*s]u * \\$1z / 1z) +-. +-. ie (\\n[.$] - 1) \ +-. vs (\\n[t*v]u * \\$2p / 1p) +-. el \{\ +-. vs (\\n[t*v]u * \\$1p / 1p) +-. return +-. \} +-. +-. if !""\\$3" \ +-. hy \\$3 +-. +-. if !""\\$4" \{\ +-. nr t*v \\n[.v] +-. nr t*s \\n[.ps] +-. nr t*hy \\n[.hy] +-. \} +-.. +-. +-. +-.\" ****************************************************************** +-.\" ** Hilfsmakros pop/pops/popr (pop stackelement): ** +-.\" ** pop or popr: pop register ** +-.\" ** pops: pop string ** +-.\" ** .pop[s|r] reg|string stackname ** +-.\" ** reg|string: name of reg/string to get the ** +-.\" ** popped element ** +-.\" ** stack: name of stack ** +-.\" ****************************************************************** +-.de *pop +-. ie "\\$1"pops" \ +-. ds \\$2 \\$4\" pop first stackelement +-. el \ +-. nr \\$2 \\$4 +-. +-. ds $3 \\$3\" remember stackname +-. shift 4 \" shift four args +-. +-. ds \\*[$3] "\\$@\" fill stack with remaining elements +-.. +-. +-.de pop +-. *pop \\$0 \\$1 \\$2 \\*[\\$2] +-.. +-. +-.als popr pop +-.als pops pop +-. +-. +-.\" ****************************************************************** +-.\" ** process diversion ** +-.\" ****************************************************************** +-.de t*DI +-. nr * \\n[.u] +-. nf \" diversion is already formatted - output it unchanged +-. \\$1 \" output the diversion ... +-. rm \\$1 \" ... and remove it +-. if \\n[*] \ +-. fi \" reactivate formatting +-.. +-. +-.\" ****************************************************************** +-.\" ** error checking at end ** +-.\" ****************************************************************** +-.de t*EM +-. +-. if !"\\*[t*kept]"" \{\ +-. tm1 "hdtbl: Not all tables have been printed. +-. tm1 " Add `.bp' at the end of your document. +-. \} +-. if !"\\*[t*held]"" \{\ +-. tm1 "hdtbl: There are held tables which haven't been printed. +-. tm1 " Add `.t*free' at the end of your document. +-. \} +-. if \\n[t*#] \ +-. tm hdtbl: Missing `.ETB' macro; last .TBL in \\*[t*FN] at line \\*[t*LN]. +-.. +-. +-.\" EOF +diff -Nuar groff-1.22.3.old/contrib/hdtbl/hdmisc.tmac-u groff-1.22.3/contrib/hdtbl/hdmisc.tmac-u +--- groff-1.22.3.old/contrib/hdtbl/hdmisc.tmac-u 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/hdtbl/hdmisc.tmac-u 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,325 @@ ++.\" -*- mode: nroff -*- ++.ig ++ ++hdmisc.tmac ++ ++This file is part of groff, the GNU roff type-setting system. ++ ++Copyright (C) 2005-2014 Free Software Foundation, Inc. ++written by Joachim Walsdorff . ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation, either version 3 of the License, or ++(at your option) any later version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program. If not, see . ++ ++.. ++. ++. ++.\" %beginstrip% ++. ++.if d t*getarg \ ++. nx ++. ++. ++.\" ****************************************************************** ++.\" ** Some macros and default settings needed by hdtbl ** ++.\" ****************************************************************** ++. ++. ++.\" Utility macro: .getarg ... ++.\" ++.\" Get macro argument. This macro searches in the ++.\" remaining arguments and assigns its value to a string ++.\" register named . The following syntax forms are ++.\" recognized. ++.\" ++.\" = Assign to string . ++.\" must not contain spaces. ++.\" ='' Assign to string . ++.\" can contain spaces. ++.\" = Assign `=' to string . ++.\" Assign `key' to string . ++.\" ++.\" After return, the string `args' contains the remaining ++.\" arguments. ++.\" ++.\" Example: With the definition of string `foo' as ++.\" ++.\" .ds foo aaa=xxx bbb ccc='yyy zzz' ddd= eee ++.\" ++.\" a call to `getarg' with ++.\" ++.\" .getarg ccc \*[foo] ++.\" ++.\" sets string `ccc' to value `yyy zzz'. The string `args' ++.\" now contains `aaa=xxx bbb ddd= eee'. An additional call ++.\" like ++.\" ++.\" .getarg ddd \*[args] ++.\" ++.\" sets string `ddd' to value `=', and `args' contains ++.\" `aaa=xxx bbb eee'. ++.de t*getarg ++. ds \\$1 ++. ds args ++. ++. if (\\n[.$] < 2) \ ++. return ++. ++. ds $1 \\$1\" ++. shift ++. ++. length * \\*[$1] ++. while \\n[.$] \{\ ++. ds * "\\$1\" ++. ds ** "\\$1\" ++. length ** \\*[**] ++. shift ++. if (\\n[*] > \\n[**]) \{\ ++. as args " "\\*[**]"\" value too short, repeat ++. continue ++. \} ++. substring * 0 (\\n[*] - 1) ++. \" The surrounding \? escapes emulate string comparison. ++. ie !"\?\\*[$1]\?"\?\\*[*]\?" \{\ ++. as args " "\\*[**]"\" key not found, repeat ++. continue ++. \} ++. el \{\ ++. ie "\?\\*[**]\?"\?\\*[$1]\?" \ ++. ds \\*[$1] \\*[$1]\" return key as string ++. el \{\ ++. ie "\?\\*[**]\?"\?\\*[$1]=\?" \ ++. ds \\*[$1] =\" return `=' ++. el \{\ ++. substring ** (\\n[*] + 1) -1 ++. ds * \\*[**]\" ++. substring * 0 0 ++. ++. \" check whether value starts with quote ++. if "\?\\*[*]\?"\?'\?" \{\ ++. substring ** 1 -1 ++. ds * \\*[**]\" ++. substring * -1 -1 ++. ++. \" search final quote ++. ie "\?\\*[*]\?"\?'\?" \ ++. substring ** 0 -2 ++. el \{\ ++. as \\*[$1] \\*[**] \" not found, append argument ++. ++. while 1 \{\ ++. ds ** \\$1\" get next argument ++. ds * \\$1\" ++. shift ++. substring * -1 -1 ++. ++. if "\?\\*[*]\?"\?'\?" \{\ ++. substring ** 0 -2 ++. break \" break if no final quote ++. \} ++. ++. as \\*[$1] \\*[**] \" otherwise append and repeat ++. \} ++. \}\} ++. ++. as \\*[$1] \\*[**]\" ++. \} ++. ++. as args " \\$@\" ++. \}\} ++. ++. return ++. \} ++.. ++. ++. ++.\" Utility macro: .index ++.\" ++.\" Check whether is a substring of and ++.\" return its position in number register `t*index', starting ++.\" with 1. If not found, return 0. If is empty, ++.\" set `t*index' to -999. ++.de t*index ++. if "\\$2"" \{\ ++. nr t*index -999 ++. return ++. \} ++. ++. length ** \\$1 ++. length $2 \\$2 ++. nr * 0-1 1 ++. ++. while (\\n+[*] < \\n[**]) \{\ ++. ds * \\$1\" ++. substring * \\n[*] (\\n[*] + \\n[$2] - 1) ++. \" The surrounding \? escapes emulate string comparison. ++. if "\?\\*[*]\?"\?\\$2\?" \ ++. break ++. \} ++. ++. ie (\\n[*] == \\n[**]) \ ++. nr t*index 0 ++. el \ ++. nr t*index (\\n[*] + 1) ++.. ++. ++. ++.\" ****************************************************************** ++.\" ******** non-accumulating space .t*SP [v] ********** ++.\" ** ** ++.\" ** nl vor erster Seite -1, oben auf Seite 0 resp. tH ** ++.\" ** .k nach .sp oder .br 0, ** ++.\" ** sonst Laenge der angefangenen Zeile ** ++.\" ** Der Merker M# fuer vorangegangenes .t*SP wird in .HM am ** ++.\" ** Seitenanfang zurueckgesetzt. ** ++.\" ** ganz richtig ist .sp + .br = .br + .sp = .sp ** ++.\" ****************************************************************** ++.de t*SP ++. if (\\n[nl] < 0) \ ++. br \" start very first page ++. nr * \\n[.p] \" save current page length ++. ++. ie "\\$1"" \ ++. pl +1 \" without arg increase page length by 1v ++. el \ ++. pl +\\$1 \" otherwise use \\$1 ++. ++. nr ** (\\n[.p] - \\n[*]) \" ** now holds arg for .t*SP in base units ++. pl \\n[*]u \" restore page length ++. ++. \" we do nothing at start of new page or column ++. if ((\\n[nl] - \\n[tH]) & (\\n[nl] - \\n[<<]) : \\n[.k]) \{\ ++. ie ((\\n[.d] - \\n[M#]) : \\n[.k]) \{\ ++. sp \\n[**]u \" execute .sp ++. nr S# \\n[**] \" store ** in S# ++. \} ++. el \{\ ++. if (\\n[**] - \\n[S#]) \{\ ++. sp (\\n[**]u - \\n[S#]u)\" emit difference to previous .t*SP ++. nr S# \\n[**] \" store ** in S# ++. \}\} ++. ++. nr M# \\n[.d] \" store vertical position .d in M# ++. \} ++.. ++. ++. ++.\" ****************************************************************** ++.\" ** Perform all arguments once ** ++.\" ** P1 is nestable ** ++.\" ****************************************************************** ++.de t*P1 ++. \" `while' command is about five times faster than recursion! ++. while \\n[.$] \{\ ++. nop \\$1 ++. shift ++. \} ++.. ++. ++. ++.\" ****************************************************************** ++.\" ** Hilfsmakro zum Einstellen von Schriftgroesse und ** ++.\" ** Zeilenabstand, bezogen auf Anfangswerte \n[t*s] ** ++.\" ** und \n[t*v] sowie fuer Hyphenation: ** ++.\" ** .pv s v hy# hart; macht .br ** ++.\" ** Bei 4. Argument setzen der Register s und v und hy. ** ++.\" ** Fuer angefangene Zeile die vorgefundenen Einstellungen ** ++.\" ** ** ++.\" ** Auxiliary macro to set internal registers for font size ** ++.\" ** and line spacing, relative to initial values \n[t*s] and ** ++.\" ** \n[t*v]. Optionally sets hyphenation. A fourth argument ** ++.\" ** initializes internal registers to global default values. ** ++.\" ****************************************************************** ++.de t*pv ++. br ++. ++. if \\n[.$] \ ++. ps (\\n[t*s]u * \\$1z / 1z) ++. ++. ie (\\n[.$] - 1) \ ++. vs (\\n[t*v]u * \\$2p / 1p) ++. el \{\ ++. vs (\\n[t*v]u * \\$1p / 1p) ++. return ++. \} ++. ++. if !""\\$3" \ ++. hy \\$3 ++. ++. if !""\\$4" \{\ ++. nr t*v \\n[.v] ++. nr t*s \\n[.ps] ++. nr t*hy \\n[.hy] ++. \} ++.. ++. ++. ++.\" ****************************************************************** ++.\" ** Hilfsmakros pop/pops/popr (pop stackelement): ** ++.\" ** pop or popr: pop register ** ++.\" ** pops: pop string ** ++.\" ** .pop[s|r] reg|string stackname ** ++.\" ** reg|string: name of reg/string to get the ** ++.\" ** popped element ** ++.\" ** stack: name of stack ** ++.\" ****************************************************************** ++.de *pop ++. ie "\\$1"pops" \ ++. ds \\$2 \\$4\" pop first stackelement ++. el \ ++. nr \\$2 \\$4 ++. ++. ds $3 \\$3\" remember stackname ++. shift 4 \" shift four args ++. ++. ds \\*[$3] "\\$@\" fill stack with remaining elements ++.. ++. ++.de pop ++. *pop \\$0 \\$1 \\$2 \\*[\\$2] ++.. ++. ++.als popr pop ++.als pops pop ++. ++. ++.\" ****************************************************************** ++.\" ** process diversion ** ++.\" ****************************************************************** ++.de t*DI ++. nr * \\n[.u] ++. nf \" diversion is already formatted - output it unchanged ++. \\$1 \" output the diversion ... ++. rm \\$1 \" ... and remove it ++. if \\n[*] \ ++. fi \" reactivate formatting ++.. ++. ++.\" ****************************************************************** ++.\" ** error checking at end ** ++.\" ****************************************************************** ++.de t*EM ++. ++. if !"\\*[t*kept]"" \{\ ++. tm1 "hdtbl: Not all tables have been printed. ++. tm1 " Add `.bp' at the end of your document. ++. \} ++. if !"\\*[t*held]"" \{\ ++. tm1 "hdtbl: There are held tables which haven't been printed. ++. tm1 " Add `.t*free' at the end of your document. ++. \} ++. if \\n[t*#] \ ++. tm hdtbl: Missing `.ETB' macro; last .TBL in \\*[t*FN] at line \\*[t*LN]. ++.. ++. ++.\" EOF +diff -Nuar groff-1.22.3.old/contrib/hdtbl/hdtbl.am groff-1.22.3/contrib/hdtbl/hdtbl.am +--- groff-1.22.3.old/contrib/hdtbl/hdtbl.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/hdtbl/hdtbl.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,126 @@ ++# Copyright (C) 2006-2014 Free Software Foundation, Inc. ++# Written by Werner Lemberg (wl@gnu.org) ++# Automake migration by Bertrand Garrigues ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++hdtbl_srcdir = $(top_srcdir)/contrib/hdtbl ++hdtbl_builddir = $(top_builddir)/contrib/hdtbl ++ ++man7_MANS += contrib/hdtbl/groff_hdtbl.n ++ ++# Groff command used to generate .ps files ++HDTBL_TFLAG = -M$(hdtbl_srcdir) -M$(hdtbl_builddir) ++HDTLB_PFLAG=-t -p -e -U ++HDTBLGROFF = \ ++ GROFF_COMMAND_PREFIX= \ ++ GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ ++ $(GROFFBIN) $(FFLAG) $(TFLAG) $(HDTBL_TFLAG) $(HDTLB_PFLAG) ++ ++# Files installed in $(tmacdir). ++# These files are generated with `strip.sed' from their unstripped source file ++# equivalent (e.g. hdtbl.tmac is generated from hdtbl.tmac-u) ++HDTBLSTRIPFILES = \ ++ contrib/hdtbl/hdtbl.tmac \ ++ contrib/hdtbl/hdmisc.tmac ++hdtbltmacdir = $(tmacdir) ++hdtbltmac_DATA = $(HDTBLSTRIPFILES) ++ ++# Files installed in $(exampledir)/hdtbl. HDTBLEXAMPLEFILES are ++# located in the source tree, while HDTBLPROCESSEDEXAMPLEFILES are ++# generated in the build tree. ++ ++# These files are handled by the `.in.roff' rule. ++HDTBLGENFILES = \ ++ contrib/hdtbl/examples/fonts_n.roff \ ++ contrib/hdtbl/examples/fonts_x.roff ++EXTRA_DIST += \ ++ contrib/hdtbl/examples/fonts_n.in \ ++ contrib/hdtbl/examples/fonts_x.in ++ ++HDTBLEXAMPLEFILES = \ ++ contrib/hdtbl/examples/common.roff \ ++ contrib/hdtbl/examples/chess_board.roff \ ++ contrib/hdtbl/examples/color_boxes.roff \ ++ contrib/hdtbl/examples/color_nested_tables.roff \ ++ contrib/hdtbl/examples/color_table_cells.roff \ ++ contrib/hdtbl/examples/color_transitions.roff \ ++ contrib/hdtbl/examples/col_rowspan_colors.roff \ ++ contrib/hdtbl/examples/mixed_pickles.roff \ ++ contrib/hdtbl/examples/rainbow.roff \ ++ contrib/hdtbl/examples/short_reference.roff ++ ++HDTBLPROCESSEDEXAMPLEFILES = \ ++ contrib/hdtbl/examples/chess_board.ps \ ++ contrib/hdtbl/examples/color_boxes.ps \ ++ contrib/hdtbl/examples/color_nested_tables.ps \ ++ contrib/hdtbl/examples/color_table_cells.ps \ ++ contrib/hdtbl/examples/color_transitions.ps \ ++ contrib/hdtbl/examples/col_rowspan_colors.ps \ ++ contrib/hdtbl/examples/fonts_n.ps \ ++ contrib/hdtbl/examples/fonts_x.ps \ ++ contrib/hdtbl/examples/mixed_pickles.ps \ ++ contrib/hdtbl/examples/rainbow.ps \ ++ contrib/hdtbl/examples/short_reference.ps ++ ++hdtblexampledir = $(exampledir)/hdtbl ++ ++if BUILD_EXAMPLES ++dist_hdtblexample_DATA = $(HDTBLEXAMPLEFILES) ++nodist_hdtblexample_DATA = \ ++ $(HDTBLGENFILES) \ ++ $(HDTBLPROCESSEDEXAMPLEFILES) \ ++ gnu.eps ++else ++EXTRA_DIST += $(HDTBLEXAMPLEFILES) ++endif ++$(hdtblexample_DATA): $(HDTBLSTRIPFILES) ++ ++MOSTLYCLEANFILES += $(HDTBLGENFILES) $(HDTBLPROCESSEDEXAMPLEFILES) \ ++ hdmisc.tmac-s hdtbl.tmac-s $(HDTBLSTRIPFILES) ++ ++EXTRA_DIST += \ ++ contrib/hdtbl/ChangeLog \ ++ contrib/hdtbl/TODO \ ++ contrib/hdtbl/groff_hdtbl.man \ ++ contrib/hdtbl/hdtbl.tmac-u \ ++ contrib/hdtbl/hdmisc.tmac-u ++ ++# Rule to generate ps and roff files ++SUFFIXES += .roff .in .ps ++ ++.roff.ps: ++ @$(MKDIR_P) `dirname $@` ++ $(HDTBLGROFF) -Tps -dfontpath=$(top_srcdir)/font -dsopath=$(hdtbl_srcdir)/ \ ++ -mhdtbl $< >$@ ++.in.roff: ++ @$(MKDIR_P) `dirname $@` ++ sed -e "s|[@]fontdir[@]|$(fontdir)|" \ ++ -e "s|[@]EGREP[@]|$(EGREP)|" $< >$@ ++ ++ ++$(HDTBLPROCESSEDEXAMPLEFILES): gnu.eps groff troff pic tbl \ ++ contrib/hdtbl/examples/common.roff ++ ++$(HDTBLSTRIPFILES): $(top_srcdir)/tmac/strip.sed ++ @$(MKDIR_P) `dirname $@` ++ sed -f $(top_srcdir)/tmac/strip.sed $(hdtbl_srcdir)/`basename $@`-u > $@; ++ ++uninstall_groffdirs: uninstall-hdtbl-hook ++uninstall-hdtbl-hook: ++ if test -d $(DESTDIR)$(hdtblexampledir); then \ ++ rmdir $(DESTDIR)$(hdtblexampledir); \ ++ fi +diff -Nuar groff-1.22.3.old/contrib/hdtbl/hdtbl.tmac groff-1.22.3/contrib/hdtbl/hdtbl.tmac +--- groff-1.22.3.old/contrib/hdtbl/hdtbl.tmac 2014-11-04 10:38:35.483520772 +0200 ++++ groff-1.22.3/contrib/hdtbl/hdtbl.tmac 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1003 +0,0 @@ +-.\" -*- nroff -*- +-.ig +- +-hdtbl.tmac +- +-This file is part of groff, the GNU roff type-setting system. +- +-Copyright (C) 2005-2014 Free Software Foundation, Inc. +-written by Joachim Walsdorff . +- +-groff is free software; you can redistribute it and/or modify it under +-the terms of the GNU General Public License as published by the Free +-Software Foundation, either version 3 of the License, or +-(at your option) any later version. +- +-groff is distributed in the hope that it will be useful, but WITHOUT +-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-for more details. +- +-You should have received a copy of the GNU General Public License +-along with this program. If not, see . +- +-.. +-. +-. +-.\" ***************************************************************** +-.\" * hdtbl - Heidelberger table macros * +-.\" * Vers. 0.91 December 2005 * +-.\" ***************************************************************** +-. +-.if d TBL \ +-. nx +-. +-.mso hdmisc.tmac +-.mso 62bit.tmac +-. +-. +-.\" ***************************************************************** +-.\" * default values for some arguments * +-.\" ***************************************************************** +-. +-.ds t*hl s\" +-.ds t*vl s\" +-.ds t*tal l\" +-.ds t*hal b\" +-.ds t*val t\" +-.ds t*ff \\n[.fam]\" +-.ds t*fst \\n[.f]\" +-.ds t*fsz 1 1\" +-.ds t*fgc red4\" +-.ds t*bgc bisque\" +-.ds t*bc red4\" +-.nr t*cpd .5n +-.nr t*csp .5n +-.nr t*b .1n +-.nr t*cols 1 +-.nr t*v \n[.v] +-.nr t*s \n[.ps] +-.nr t*hy \n[.hy] +-.nr t*l \n[.ll] +-. +-. +-.\" defaults for table captions +-.nr t*cptn 0 1 +-.ds t*cptn "".sp .4" \ +- ".t*pv 1.0 1.0" \ +- ".ad l" \ +- "\m[\\*[t*fgc]]Table \\n+[t*cptn]:\0\c\k*"\" +-. +-. +-.\" %beginstrip% +-. +-.\" for better error messages +-.ds nth-1 st\" +-.ds nth-2 nd\" +-.ds nth-3 rd\" +-. +-.\" initialization of various registers +-.nr t*# 0 \" table nesting level +-.nr t*numb 0 1 \" held table diversion # +-. +-.ds *#trc* +-. +-. +-.\" ***************************************************************** +-.\" * The four base macros and the two optional macros * +-.\" ***************************************************************** +-. +-.ie n \ +-. ds g tty:\" +-.el \ +-. ds g ps: exec\" +-. +-.\" TBL: table start +-.\" predecessor: text, TD or ETB +-.\" successor: CPTN or TR +-.de TBL +-. ds t*m\\n[t*#] \\n[.m]\" +-. ie \\n[t*#] \ +-. br +-. el \{\ +-. ds * \\n[.ev]\" +-. ev t*tbl +-. evc \\*[*] +-. di t*tbl0 +-. sp .4 \" XXX: hard-coded value +-. nr t*i \\n[.i] +-. ll -\\n[.i]u +-. in 0 +-. \} +-. nr t*# +1 +-. +-. \" Save current location for error checking at end +-. ds t*FN \\[.F] +-. ds t*LN \\[.c] +-. +-. t*getarg cols \\$@\" from here string `args' contains the rest of \\$@ +-. ie "\\*[cols]"" \ +-. nr t*cols\\n[t*#] \\n[t*cols] +-. el \{\ +-. ie \B\\*[cols] \ +-. nr t*cols\\n[t*#] \\*[cols] +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid number of columns value `\\*[cols]'. +-. \} +-. +-. t*getarg cpd \\*[args] \" cell padding +-. ie "\\*[cpd]"" \ +-. nr t*cpd\\n[t*#] \\n[t*cpd] +-. el \{\ +-. ie \B\\*[cpd] \ +-. nr t*cpd\\n[t*#] \\*[cpd] +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid cell padding value `\\*[cpd]'. +-. \} +-. +-. t*getarg csp \\*[args] \" cell spacing +-. ie "\\*[csp]"" \ +-. nr t*csp\\n[t*#] \\n[t*csp] +-. el \{\ +-. ie \B\\*[csp] \ +-. nr t*csp\\n[t*#] \\*[csp] +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid cell spacing value `\\*[csp]'. +-. \} +-. +-. t*getarg border \\*[args] \" border thickness +-. ie "\\*[border]"=" \ +-. nr t*b\\n[t*#] 0-1 +-. el \{\ +-. ie "\\*[border]"" \ +-. nr t*b\\n[t*#] \\n[t*b] +-. el \{\ +-. ie \B\\*[border] \ +-. nr t*b\\n[t*#] \\*[border] +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid border thickness value `\\*[border]'. +-. \}\} +-. +-. t*getarg bc \\*[args] \" border color +-. ds t*bc\\n[t*#] \\*[t*bc]\" +-. if !"\\*[bc]"" \{\ +-. ie m\\*[bc] \ +-. ds t*bc\\n[t*#] \\*[bc]\" +-. el \{\ +-. ie "\\*[bc]"=" \ +-. ds t*bc\\n[t*#] =\" +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid border color `\\*[bc]'. +-. \}\} +-. ie "\\*[bc]"=" \ +-. ds t*bc\\n[t*#] +-. el \{\ +-. ie "\\*[bc]"" \ +-. ds t*bc\\n[t*#] \\*[t*bc]\" +-. el \ +-. ds t*bc\\n[t*#] \\*[bc]\" +-. \} +-. +-. t*getarg width \\*[args] \" table/col widths +-. if "\\*[width]"=" \ +-. ds width +-. +-. nr b/2\\n[t*#] (\\n[t*b\\n[t*#]] / 2)\" shortcut +-. nr cscp\\n[t*#] (\\n[t*csp\\n[t*#]] + \\n[t*cpd\\n[t*#]])\" aux. register +-. +-. t*getarg height \\*[args] \" table outline height +-. ie "\\*[height]"" \ +-. nr t*height\\n[t*#] 0 +-. el \{\ +-. ie \B\\*[height] \ +-. nr t*height\\n[t*#] (\\*[height] \ +- - ((2 * \\n[cscp\\n[t*#]]) \ +- + (3 * \\n[b/2\\n[t*#]]))) +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid height value `\\*[height]'. +-. \} +-. +-. t*cl \\*[width] \" get cell widths and offsets +-. t*args \\n[t*#] \" look for common arguments +-. +-. t*getarg tal \\*[args] \" table horizontal alignment +-. if "\\*[tal]"" \ +-. ds tal \\*[t*tal]\" +-. ie "\\*[tal]"l" \ +-. nr in\\n[t*#] \\n[.i] +-. el \{\ +-. ie "\\*[tal]"c" \ +-. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]]/2 + \\n[.i]) +-. el \{\ +-. ie "\\*[tal]"r" \ +-. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]] + \\n[.i]) +-. el \{\ +-. tmc \\n[.F]:\\n[.c]: Invalid horizontal table alignment `\\*[tal]': +-. tm1 " must be `l', `c' or `r'. +-. \}\}\} +-. +-. nr t*r#\\n[t*#] 0 \" initialize row index +-. mk toptbl\\n[t*#] +-. +-. t*P1 \\*[args] +-.. +-. +-. +-.\" CPTN: optional table caption +-.\" predecessor: TBL +-.\" successor: TR +-.de CPTN +-. ft 1 +-. +-. if "\\$0"CPTN" \ +-. if \\n[t*r#\\n[t*#]] \{\ +-. tmc \\n[.F]:\\n[.c]: Invalid placement of `.CPTN'; +-. tm1 " must be called immediately after `.TBL'. +-. return +-. \} +-. +-. t*getarg val \\$@ +-. ds args\\n[t*#] "\\*[args]\" +-. +-. t*index "\\*[args]" .TR +-. ie \\n[t*index] \{\ +-. ds *a\\n[t*#] "\\*[args]\" +-. substring args\\n[t*#] 0 \\n[t*index] +-. substring *a\\n[t*#] \\n[t*index]-2 -1 +-. \} +-. el \ +-. ds *a\\n[t*#] +-. +-. ie "\\*[val]"b" \{\ +-. de t*cptn\\n[t*#] +-. *CPTN \\*[args\\n[t*#]] +-. rm t*cptn\\n[t*#] +-\\.. +-. \} +-. el \{\ +-. ll (\\n[ll\\n[t*#]]u + \\n[in\\n[t*#]]u) +-. in \\n[in\\n[t*#]]u +-. t*P1 \\*[t*cptn] +-' in +\\n[*]u +-. t*P1 \\*[args\\n[t*#]] +-. t*pv 1 1 +-. in +-. mk toptbl\\n[t*#] +-. \} +-. +-. t*P1 \\*[*a\\n[t*#]] +-.. +-. +-.als *CPTN CPTN +-. +-. +-.\" TR: table row +-.\" predecessor: TBL, CPTN, text, TD or ETB +-.\" successor: TD +-.de TR +-. ft 1 +-. if !\\n[t*#] \{\ +-. tm \\n[.F]:\\n[.c]: Table row (.TR) without preceding table start (.TBL). +-. return +-. \} +-. +-. \" finish previous data cell, if any +-. if \\n[t*r#\\n[t*#]] \ +-. t*dntr 1 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*] +-. +-. nr t*r#\\n[t*#] +1 \" row number in this table +-. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" table row identifier +-. \" (*) +-. nr c#\\*[#t#r] 0 1 \" clear cell counter +-. nr dntr\\*[#t#r] 0 1 \" clear accumulated row height +-. +-. t*getarg height \\$@ +-. ie "\\*[height]"" \ +-. nr t*height\\*[#t#r] 0 +-. el \{\ +-. ie \B\\*[height] \ +-. nr t*height\\*[#t#r] \\*[height] +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid table row height `\\*[height]'. +-. \} +-. +-. \" If there is a TR with height `height', the total height of the table +-. \" is too high by 3/2 b, independent of the number of TR with `height'. +-. t*args \\*[#t#r] \\n[t*#] \" look for common arguments +-. +-. t*P1 \\*[args] +-.. +-. +-. +-.\" TH: optional table header cell +-.\" predecessor: text, TD or TR +-.\" successor: text, TD, TR, TBL or ETB +-.\" +-.\" cell content bolded and horizontally and vertically centered, +-.\" else like .TD +-.de TH +-. ft 1 +-. t*getarg hal \\$@ +-. if "\\*[hal]"" \ +-. ds hal c\" +-. +-. t*getarg val \\*[args] +-. if "\\*[val]"" \ +-. ds val m\" +-. +-. t*getarg fst \\*[args] +-. if "\\*[fst]"" \ +-. ds fst B\" +-. +-. TD hal=\\*[hal] val=\\*[val] fst=\\*[fst] \\*[args] +-.. +-. +-. +-.\" TD: table data cell +-.\" predecessor: text, TD or TR +-.\" successor: text, TD, TR, TBL or ETB +-.de TD +-. ft 1 +-. \" finish previous data cell -- note the use of \E +-. t*dntr 0 \\n[c#\\*[#t#r]]-1 \En[c#\\*[#t#r]] \\*[*#trc*] +-. +-. ds *#trc* \\*[#t#r]*\\n[c#\\*[#t#r]]\" table cell identifier +-. \" (**) +-. +-. t*getarg rowspan \\$@ +-. nr rowspan 1 +-. if !"\\*[rowspan]"" \{\ +-. ie \B\\*[rowspan] \{\ +-. nr rowspan (\\*[rowspan] >? 1) +-. nr *rsp*\\*[*#trc*] (\\n[rowspan] - 1) +-. \} +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid value of `rowspan' keyword. +-. \} +-. +-. t*getarg colspan \\*[args] +-. nr colspan 1 +-. if !"\\*[colspan]"" \{\ +-. ie \B\\*[colspan] \ +-. nr colspan (\\*[colspan] >? 1) +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid value of `colspan' keyword. +-. \} +-. +-. t*args \\*[#trc] \\*[#t#r] \" look for common arguments +-. +-. nr in\\*[#trc] \\n[in\\n[t*#]*\\n[c#\\*[#t#r]]] +-. nr *cl \\n[cll\\n[t*#]*\\n[c#\\*[#t#r]]] +-. nr * 0 1 +-. nr *r \\n[t*r#\\n[t*#]] +-. +-. if (\\n[rowspan] - 1) \ +-. while (\\n+[*] <= \\n[rowspan]) \{\ +-. nr rspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan] +-. if (\\n[*] > 1) \ +-. nr cspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan] +-. nr *r +1 +-. \} +-. +-. nr * 1 1 +-. nr *c \\n[c#\\*[#t#r]] +-. +-. if (\\n[colspan] - 1) \{\ +-. nr vline\\*[*#trc*] 0-1 \" set `no vl' flag +-. +-. while (\\n+[*] <= \\n[colspan]) \{\ +-. nr *c +1 +-. nr *cl +(2 * \\n[cscp\\n[t*#]] \ +- + \\n[b/2\\n[t*#]] \ +- + \\n[cll\\n[t*#]*\\n[*c]]) +-. nr c#\\*[#t#r] +1 +-. \} +-. \} +-. +-. if (\\n[c#\\n[t*#]*\\n[t*r#\\n[t*#]]] > \\n[t*cols\\n[t*#]]) \{\ +-. ds * are\" +-. ds ** columns\" +-. if (\\n[c#\\*[#t#r]] == 1) \{\ +-. ds * is\" +-. ds ** column\" +-. \} +-. tmc \\n[.F]:\\n[.c]: There \\*[*] \\n[c#\\*[#t#r]] table \\*[**] (.TD) +-. +-. ds * are\" +-. if (\\n[t*cols\\n[t*#]] == 1) \ +-. ds * is\" +-. tm1 " but only \\n[t*cols\\n[t*#]] \\*[*] expected. +-. +-. ds * +-. length * \\n[.F]:\\n[.c]: +-. +-. while \\n-[*] \ +-. ds * " \\*[*]\" +-. +-. tm1 "\\*[*] Remaining .TDs and its contents are ignored. +-. +-. di *t*dummy* \" bypass superfluous input +-. return +-. \} +-. +-. di t*\\*[#trc] \" open cell diversion and set locals +-. in 0 +-. nr cll\\*[#trc] \\n[*cl] +-. ll \\n[*cl]u +-. nr *cl\\n[t*#] \\n[.l] +-. gcolor \\*[t*fgc\\*[#trc]] +-. ad \\*[t*hal\\*[#trc]] +-. fam \\*[t*ff\\*[#trc]] +-. ft \\*[t*fst\\*[#trc]] +-. t*pv \\*[t*fsz\\*[#trc]] +-. +-. t*P1 \\*[args] +-.. +-. +-. +-.\" ETB: end of table +-.\" predecessor: text, TD or ETB +-.\" successor: text, TD, TR or TBL +-.de ETB +-. ie \\n[t*#] \ +-. if !\\n[t*r#\\n[t*#]] \{\ +-. tmc \\n[.F]:\\n[.c]: Each table (.TBL) +-. tm1 " should contain at least one table row (.TR)! +-. \} +-. el \{\ +-. tmc \\n[.F]:\\n[.c]: Table end (.ETB) +-. tm1 " without corresponding table start (.TBL)! +-. \} +-. +-. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier +-. t*dntr 2 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*] +-. +-. t*divs \" print this table +-. +-. sp \\n[b/2\\n[t*#]]u +-. t*cptn\\n[t*#] +-. nr t*# -1 +-. +-. ll \\n[*cl\\n[t*#]]u \" restore ll outside this table +-. in 0 \" reset indent +-. gcolor \\*[t*m\\n[t*#]] \" reset previous fgc +-. +-. t*getarg hold \\$@ +-. if !\\n[t*#] \{\ +-. sp .5 +-. di +-. in \\n[t*i]u +-. ie "\\*[hold]"" \{\ +-. ie (\\n[.t] - \\n[dn]) \ +-. t*DI t*tbl0 +-. el \{\ +-. rn t*tbl0 t*tbl\\n+[t*numb] +-. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[dn]\" +-. \} +-. \} +-. el \{\ +-. rn t*tbl0 t*hold\\n+[t*numb] +-. tm \\n[.F]:\\n[.c]: Table t*hold\\n[t*numb] held. +-. ds t*held \\*[t*held] t*hold\\n[t*numb] \\n[dn]\" +-. \} +-. +-. ev \" restore previous environment +-. \} +-. +-. t*P1 \\*[args] +-.. +-. +-. +-.\" ***************************************************************** +-.\" * Following the definition of five utility macros * +-.\" * special to hdtbl. * +-.\" * Other utility macros common to hdtbl and hdgroff * +-.\" * are defined in the file hdmisc.tmac. * +-.\" ***************************************************************** +-. +-. +-.\" .t*free [n] +-.\" print the next [n] held table[s]. +-.\" Don't call it within a table! +-.\" If the table is higher than the remaining space +-.\" on the page, the table is printed on the next page. +-.de t*free +-. if "\\$0"CPTN" \ +-. if \\n[t*r#\\n[t*#]] \{\ +-. tmc \\n[.F]:\\n[.c]: Invalid placement of `.t*free' within a table; +-. tm1 " it must be called outside of any table. +-. return +-. \} +-. +-. if "\\*[t*held]"" \{\ +-. tm \\n[.F]:\\n[.c]: No held tables. +-. return +-. \} +-. +-. nr ** (\\$1 >? 1) 1 +-. while !""\\*[t*held]" \{\ +-. pops * t*held +-. popr * t*held +-. +-. ie (\\n[.t] - \\n[*]) \{\ +-. ev t*tbl +-. t*DI \\*[*] +-. ev +-. \} +-. el \{\ +-. rn \\*[*] t*tbl\\n+[t*numb] +-. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[*]\" +-. \} +-. +-. if !(\\n-[**] - 1) \ +-. return +-. \} +-.. +-. +-. +-.\" The main utility macro for tables: +-.\" If a table is closed by ETB, this macro is called. It +-.\" processes one complete table, i.e., all the table cell +-.\" diversions, paints the cell backgrounds, draws +-.\" horizontal and vertical table lines and the table border. +-.\" +-.\" Nested tables are processed from inside to outside. +-. +-.de t*divs +-. ll (\\n[t*l]u + 1c) \" avoid warning `can't break line' +-. nf +-. +-. nr b/2 \\n[b/2\\n[t*#]] \" some abbreviations +-. nr cscp \\n[cscp\\n[t*#]] +-. nr cscpb (\\n[b/2] + \\n[cscp]) +-. +-. nr topdiv (\\n[.d] + \\n[b/2] - \\n[cscp])\" top of cell diversion +-. nr cscpb2 (\\n[b/2] / 2 + \\n[cscp]) +-. +-. nr #r 0 1 +-. \" outer loop for rows +-. while (\\n+[#r] <= \\n[t*r#\\n[t*#]]) \{\ +-. \" TODO: insert code here for multipage tables +-. nr * (\\n[#r] - 1) +-. nr topdiv +(\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb]) +-. +-. \" if table still smaller than specified table height, increase it +-. if ((\\n[#r] == \\n[t*r#\\n[t*#]]) & \\n[t*height\\n[t*#]]) \ +-. nr dntr\\n[t*#]*\\n[#r] (\\n[cscpb] \ +- + \\n[toptbl\\n[t*#]] \ +- + \\n[t*height\\n[t*#]] \ +- - (\\n[topdiv] >? \\n[dntr\\n[t*#]*\\n[#r]])) +-. +-. nr #c 0 1 +-. \" inner loop for cells +-. while (\\n+[#c] <= \\n[t*cols\\n[t*#]]) \{\ +-. ds #trc \\n[t*#]*\\n[#r]*\\n[#c]\" +-. \" continue if the diversion is empty +-. if !d t*\\*[#trc] \ +-. continue +-. +-. sp |\\n[topdiv]u +-. in (\\n[in\\n[t*#]]u + \\n[in\\*[#trc]]u)\" cell offset +-. nr $1 \\n[dntr\\n[t*#]*\\n[#r]] \" cell height +-. +-. \" if we have spanned rows, calculate resulting row height +-. \" and position of lower horizontal line +-. if \\n[*rsp*\\*[#trc]] \{\ +-. nr * \\n[#r] 1 +-. nr rspan\\*[#trc] 0-1 \" set `no hl' flag +-. nr corr (\\n[dn\\*[#trc]] - \\n[dntr\\n[t*#]*\\n[#r]]) +-. +-. \" clear row span flags in following rows and update row height +-. while \\n[*rsp*\\*[#trc]] \{\ +-. nr *rsp*\\*[#trc] -1 +-. nr rspan\\n[t*#]*\\n+[*]*\\n[#c] 0 +-. nr ** (\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb]) +-. nr corr -\\n[**] +-. nr $1 +\\n[**] +-. \} +-. +-. if (\\n-[*] == \\n[t*r#\\n[t*#]]) \ +-. nr $1 ((\\n[t*height\\n[t*#]] \ +- - \\n[.d] \ +- + \\n[toptbl\\n[t*#]] \ +- + \\n[cscpb]) \ +- >? \\n[$1]) +-. nr dntr\\n[t*#]*\\n[*] +(\\n[corr] >? 0) +-. \} +-. +-. \" paint cell background +-. nr * (2 * \\n[t*cpd\\n[t*#]] + \\n[cll\\*[#trc]])\" background width +-. nr $1 (\\n[$1] >? \\n[dn\\*[#trc]])\" cell height +-. +-. if !"\\*[t*bgc\\*[#trc]]"=" \{\ +-. nop \h'\\n[t*csp\\n[t*#]]u'\ +-\M[\\*[t*bgc\\*[#trc]]]\ +-\v'(-.67v - \\n[t*cpd\\n[t*#]]u)'\ +-\D'P \\n[*]u 0 \ +- 0 (2u * \\n[t*cpd\\n[t*#]]u + \\n[$1]u) \ +- -\\n[*]u 0'\ +-\M[] +-. sp -1 +-. \} +-. +-. \" *** horizontal and vertical single or double lines *** +-. \" double and single lines have the same thickness; +-. \" the double lines' distance is the line thickness. +-. \" +-. \" `border=x': horizontal/vertical lines x/2 thick, minimum .1n +-. \" `border=0': no border; horizontal/vertical lines .1n thick +-. \" `border=': neither border nor horizontal/vertical lines +-. +-. nr *t (.1n >? \\n[b/2]) \" thickness of hl/vl; min. .1n +-. in +\\n[cscp]u +-. +-. \" check for vertical and horizontal lines +-. if (1 + \\n[t*b\\n[t*#]]) \{\ +-. if !"\\*[t*bc\\n[t*#]]"=" \{\ +-. \" draw horizontal line between this cell and the one below +-. if (\\n[t*r#\\n[t*#]] - \\n[#r] + \\n[rspan\\*[#trc]]) \{\ +-. if !"\\*[t*hl\\*[#trc]]"=" \{\ +-. sp \\n[$1]u +-. nr * (\\n[cscp] + \\n[cscpb] + \\n[cll\\*[#trc]]) +-. nop \X'\*[g] 1 setlinecap'\ +-\h'(-\\n[cscpb2]u - \\n[*t]u)'\ +-\v'(\\n[cscpb2]u - .67v)'\ +-\m[\\*[t*bc\\n[t*#]]]\ +-\D't \\n[*t]u'\c +-. +-. ie "\\*[t*hl\\*[#trc]]"d" \ +-. nop \v'-\\n[*t]u'\ +-\D'l \\n[*]u 0'\ +-\v'(2u * \\n[*t]u)'\ +-\D'l -\\n[*]u 0'\ +-\D't 0' +-. el \ +-. nop \D'l \\n[*]u 0'\ +-\D't 0' +-. +-. sp (-\\n[$1]u - 1v) +-. \}\} +-. +-. nr rspan\\*[#trc] 0 +-. +-. \" draw vertical line between this cell and the one to the right +-. if (\\n[t*cols\\n[t*#]] - \\n[#c] + \\n[vline\\*[#trc]]) \{\ +-. if !"\\*[t*vl\\*[#trc]]"=" \{\ +-. nop \X'\*[g] 1 setlinecap'\ +-\v'(-\\n[cscpb2]u - .67v)'\ +-\m[\\*[t*bc\\n[t*#]]]\ +-\h'(\\n[cscpb2]u - \\n[*t]u + \\n[cll\\*[#trc]]u)'\c +-. +-. ie "\\*[t*vl\\*[#trc]]"d" \ +-. nop \h'-\\n[*t]u'\ +-\D't \\n[*t]u'\ +-\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\ +-\h'(2u * \\n[*t]u)'\ +-\D'l 0 -(2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\ +-\D't 0' +-. el \ +-. nop \D't \\n[*t]u'\ +-\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\ +-\D't 0' +-. sp -1 +-. \}\}\}\} +-. +-. nr vline\\*[#trc] 0 +-. +-. \" vert. cell content alignment +-. nr ** 0 +-. +-. ie "\\*[t*val\\*[#trc]]"m" \ +-. nr ** ((\\n[$1] - \\n[dn\\*[#trc]]) / 2)\" val=m +-. el \ +-. if "\\*[t*val\\*[#trc]]"b" \ +-. nr ** (\\n[$1] - \\n[dn\\*[#trc]])\" val=b +-. +-. sp \\n[**]u \" vertical content position +-. +-. \" finally output the diversion +-. t*\\*[#trc] +-. rm t*\\*[#trc] +-. \} +-. \} +-. +-. \" draw the box border +-. in \\n[in\\n[t*#]]u +-. nr ** (\\n[topdiv] + \\n[dntr\\n[t*#]*\\n-[#r]]) +-. +-. if \\n[t*b\\n[t*#]] \{\ +-. sp |(\\n[toptbl\\n[t*#]]u + \\n[b/2]u) +-. nr $1 (\\n[toptbl\\n[t*#]] - \\n[**] - \\n[cscp]) +-. nr * (\\n[ll\\n[t*#]] - \\n[t*b\\n[t*#]]) +-. +-. if !"\\*[t*bc\\n[t*#]]"=" \ +-. nop \X'\*[g] 0 setlinejoin 2 setlinecap'\ +-\v'-.67v'\ +-\h'-\\n[b/2]u'\ +-\m[\\*[t*bc\\n[t*#]]]\ +-\D't \\n[t*b\\n[t*#]]u'\ +-\D'l \\n[*]u 0'\ +-\D'l 0 -\\n[$1]u'\ +-\D'l -\\n[*]u 0'\ +-\D'l 0 \\n[$1]u'\ +-\D't 0' +-. \} +-. +-. sp |(\\n[**]u + \\n[cscpb]u) +-. fi +-.. +-. +-. +-.\" Utility macro: .t*cl [width1 [width2 [...]]] +-.\" +-.\" Calculate cell widths, table width, and cell offsets. +-.de t*cl +-. nr t*cols\\n[t*#] (\\n[.$] >? \\n[t*cols\\n[t*#]]) +-. nr ll\\n[t*#] 0 \" accumulated cell widths +-. nr ** (\\n[.l] / \\n[t*cols\\n[t*#]])\" width for remaining cells +-. nr * 0 1 \" counter +-. +-. \" while-loop: Parse user arguments to get each cell's width. +-. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\ +-. nr $\\n[*] \\n[**] +-. if !"\\$[\\n[*]]"" \{\ +-. \" check for `%' pseudo scaling indicator +-. ds * \\$\\n[*]\" +-. substring * -1 -1 +-. ie "\\*[*]"%" \{\ +-. ds ** \\$[\\n[*]]\" +-. substring ** 0 -2 +-. ie \B\\*[**] \ +-. nr $\\n[*] (\\*[**] * \\n[.l] / 100) +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid relative cell width `\\*[**]%'. +-. \} +-. el \{\ +-. ie \B\\$[\\n[*]] \ +-. nr $\\n[*] \\$[\\n[*]] +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid cell width `\\$[\\n[*]]'. +-. \}\} +-. +-. nr ll\\n[t*#] +\\n[$\\n[*]] +-. nr ** \\n[$\\n[*]] +-. \} +-. +-. if (\\n[ll\\n[t*#]] > \\n[.l]) \ +-. tm \\n[.F]:\\n[.c]: Table width larger than column width. +-. +-. nr ** (0 >? \\n[t*b\\n[t*#]]) +-. nr * 0 1 +-. +-. \" second while loop: Compute final cell widths. +-. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\ +-. \" Remove border width, if any. +-. if \\n[t*b\\n[t*#]] \{\ +-. \" cell_width := cell_width * (length - 1.5*border) / length +-. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2)) +-. nr *** (\\n[ll\\n[t*#]] / 2) +-. \" avoid multiplication overflow +-. mult31by31 $\\n[*] #* **** +-. add31to62 *** **** **** +-. div62by31 **** ll\\n[t*#] $\\n[*] +-. \} +-. +-. \" Get cell widths without padding, spacing, and separator line. +-. nr cll\\n[t*#]*\\n[*] (\\n[$\\n[*]] \ +- - (2 * \\n[cscp\\n[t*#]]) \ +- - \\n[b/2\\n[t*#]]) +-. +-. \" Check whether value is non-positive. +-. if !\\n[cll\\n[t*#]*\\n[*]] \{\ +-. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2)) +-. nr *** (\\n[#*] / 2) +-. nr *h (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]]) +-. mult31by31 *h ll\\n[t*#] **** +-. add31to62 *** **** **** +-. div62by31 **** #* *h +-. ds * \\n[*]th\" +-. nr *** (\\n[*] % 10) +-. if d nth-\\n[***] \ +-. ds * \\n[*]\\*[nth-\\n[***]]\" +-. tmc \\n[.F]:\\n[.c]: The \\*[*] width value (\\$\\n[*]) is too small. +-. tm1 " It should be greater than \\n[*h]. +-. \} +-. +-. nr in\\n[t*#]*\\n[*] \\n[**] \" cell offset +-. nr ** +\\n[$\\n[*]] +-. \} +-.. +-. +-. +-.\" Utility macro: .t*dntr ? +-.\" +-.\" Close TD diversion, make some calculations, and set +-.\" some help strings and registers. is 0, 1, +-.\" or 2 if the call of .t*dntr occurs in .TD, .TR, or +-.\" .ETB, respectively. +-.de t*dntr +-. nr dn 0 \" reset diversion height +-. br \" finish cell data +-. +-. if "\\n[.z]"*t*dummy*" \ +-. return +-. +-. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier +-. +-. if \\n[c#\\*[#t#r]] \{\ +-. di \" close diversion +-. nr dn\\$4 \\n[dn] \" save height of this cell +-. if !\\n[rspan\\*[#trc]] \{\ +-. \" update row height if not in a row span +-. nr dntr\\*[#t#r] (\\n[dntr\\*[#t#r]] >? \\n[dn]) +-. if \\$2 \ +-. nr dntr\\*[#t#r] ((\\n[t*height\\*[#t#r]] \ +- - (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])) \ +- >? \\n[dntr\\*[#t#r]]) +-. \}\} +-. +-. nr c#\\*[#t#r] +1 +-. nr * \\$2 +-. +-. \" update column span registers +-. while (\\n+[*] <= \\$3) \{\ +-. if r cspan\\*[#t#r]*\\n[*] \ +-. nr c#\\*[#t#r] +\\n[cspan\\*[#t#r]*\\n[*]] +-. nr cspan\\*[#t#r]*\\n[*] 0 +-. \} +-. +-. ds #trc \\*[#t#r]*\\n[c#\\*[#t#r]]\" +-. +-. \" only check for cell underflow if called by .TR or .ETB +-. if (\\$1 & (\\n[c#\\*[#t#r]] <= \\n[t*cols\\n[t*#]])) \{\ +-. ds * are\" +-. ds ** columns\" +-. if (\\n-[c#\\*[#t#r]] == 1) \{\ +-. ds * is\" +-. ds ** column\" +-. \} +-. tmc \\n[.F]:\\n[.c]: There \\*[*] only \\n[c#\\*[#t#r]] \\*[**] +-. +-. nr * \\n[t*r#\\n[t*#]] +-. ds * \\n[*]th\" +-. nr *** (\\n[*] % 10) +-. if d nth-\\n[***] \ +-. ds * \\n[*]\\*[nth-\\n[***]]\" +-. tmc " in the \\*[*] row +-. +-. ds * are\" +-. if (\\n[t*cols\\n[t*#]] == 1) \ +-. ds * is\" +-. tm1 " but \\n[t*cols\\n[t*#]] \\*[*] expected. +-. \} +-.. +-. +-. +-.\" Utility-macro: .t*args level_1 [level_2] +-.\" +-.\" Get the arguments common to TBL, TR, and TD for the level +-.\" in argument 1, using default values from the level in +-.\" argument 2. If argument 2 is missing, use the global +-.\" default values. +-.\" +-.de t*args +-. ds t*bgc\\$1 \\*[t*bgc\\$2]\" +-. ds t*fgc\\$1 \\*[t*fgc\\$2]\" +-. ds t*hl\\$1 \\*[t*hl\\$2]\" +-. ds t*vl\\$1 \\*[t*vl\\$2]\" +-. ds t*hal\\$1 \\*[t*hal\\$2]\" +-. ds t*val\\$1 \\*[t*val\\$2]\" +-. ds t*ff\\$1 \\*[t*ff\\$2]\" +-. ds t*fst\\$1 \\*[t*fst\\$2]\" +-. ds t*fsz\\$1 \\*[t*fsz\\$2]\" +-. +-. if "\\*[args]"" \ +-. return +-. +-. t*getarg bgc \\*[args] \" background color +-. if !"\\*[bgc]"" \{\ +-. ie m\\*[bgc] \ +-. ds t*bgc\\$1 \\*[bgc]\" +-. el \{\ +-. ie "\\*[bgc]"=" \ +-. ds t*bgc\\$1 =\" +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid background color `\\*[bgc]'. +-. \}\} +-. if "\\*[args]"" \ +-. return +-. +-. t*getarg fgc \\*[args] \" foreground color +-. if !"\\*[fgc]"" \{\ +-. ie m\\*[fgc] \ +-. ds t*fgc\\$1 \\*[fgc]\" +-. el \{\ +-. ie "\\*[fgc]"=" \ +-. ds t*fgc\\$1 =\" +-. el \ +-. tm \\n[.F]:\\n[.c]: Invalid foreground color `\\*[fgc]'. +-. \}\} +-. if "\\*[args]"" \ +-. return +-. +-. t*getarg hl \\*[args] \" horizontal line between cells +-. if !"\\*[hl]"" \ +-. ds t*hl\\$1 \\*[hl]\" +-. if "\\*[args]"" \ +-. return +-. +-. t*getarg vl \\*[args] \" vertical line between cells +-. if !"\\*[vl]"" \ +-. ds t*vl\\$1 \\*[vl]\" +-. if "\\*[args]"" \ +-. return +-. +-. t*getarg hal \\*[args] \" horizontal table cell alignment +-. if !"\\*[hal]"" \{\ +-. t*index bcrl \\*[hal] +-. ie \\n[t*index] \ +-. ds t*hal\\$1 \\*[hal]\" +-. el \{\ +-. tmc \\n[.F]:\\n[.c]: Invalid horizontal alignment `\\*[hal]': +-. tm1 " must be `b', `c', `l' or `r'. +-. \}\} +-. if "\\*[args]"" \ +-. return +-. +-. t*getarg val \\*[args] \" vertical table cell alignment +-. if !"\\*[val]"" \{\ +-. t*index tmb \\*[val] +-. ie \\n[t*index] \ +-. ds t*val\\$1 \\*[val]\" +-. el \{\ +-. tmc \\n[.F]:\\n[.c]: Invalid vertical alignment `\\*[val]': +-. tm1 " must be `t', `m' or `b'. +-. \}\} +-. if "\\*[args]"" \ +-. return +-. +-. t*getarg ff \\*[args] \" font family +-. if !"\\*[ff]"" \ +-. ds t*ff\\$1 \\*[ff]\" +-. if "\\*[args]"" \ +-. return +-. +-. t*getarg fst \\*[args] \" font style +-. if !"\\*[fst]"" \ +-. ds t*fst\\$1 \\*[fst]\" +-. if "\\*[args]"" \ +-. return +-. +-. t*getarg fsz \\*[args] \" font size and spacing factor +-. if !"\\*[fsz]"" \ +-. ds t*fsz\\$1 \\*[fsz]\" +-.. +-. +-. +-.\" Append to your page header macro ('pg@top' for MS) +-.\" to enable tables to span pages. +-.de t*hm +-. ev t*tbl +-. nr ** \\n[.t] +-. while !""\\*[t*kept]" \{\ +-. pops * t*kept +-. popr * t*kept +-. if (\\n[*] - \\n[**]) \{\ +-. tm \\n[.F]:\\n[.c]: Table \\*[*] higher than page -- ignored! +-. break +-. \} +-. +-. if (\\n[*] - \\n[.t]) \{\ +-. ds t*kept \\n[*] \\*[t*kept]\" +-. ds t*kept \\*[*] \\*[t*kept]\" +-. tmc \\n[.F]:\\n[.c]: Remaining table(s), +-. tm1 " because not all fit onto this page. +-. break +-. \} +-. +-. t*DI \\*[*] +-. \} +-. ev +-.. +-. +-.\" EOF +diff -Nuar groff-1.22.3.old/contrib/hdtbl/hdtbl.tmac-u groff-1.22.3/contrib/hdtbl/hdtbl.tmac-u +--- groff-1.22.3.old/contrib/hdtbl/hdtbl.tmac-u 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/hdtbl/hdtbl.tmac-u 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,1003 @@ ++.\" -*- nroff -*- ++.ig ++ ++hdtbl.tmac ++ ++This file is part of groff, the GNU roff type-setting system. ++ ++Copyright (C) 2005-2014 Free Software Foundation, Inc. ++written by Joachim Walsdorff . ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation, either version 3 of the License, or ++(at your option) any later version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program. If not, see . ++ ++.. ++. ++. ++.\" ***************************************************************** ++.\" * hdtbl - Heidelberger table macros * ++.\" * Vers. 0.91 December 2005 * ++.\" ***************************************************************** ++. ++.if d TBL \ ++. nx ++. ++.mso hdmisc.tmac ++.mso 62bit.tmac ++. ++. ++.\" ***************************************************************** ++.\" * default values for some arguments * ++.\" ***************************************************************** ++. ++.ds t*hl s\" ++.ds t*vl s\" ++.ds t*tal l\" ++.ds t*hal b\" ++.ds t*val t\" ++.ds t*ff \\n[.fam]\" ++.ds t*fst \\n[.f]\" ++.ds t*fsz 1 1\" ++.ds t*fgc red4\" ++.ds t*bgc bisque\" ++.ds t*bc red4\" ++.nr t*cpd .5n ++.nr t*csp .5n ++.nr t*b .1n ++.nr t*cols 1 ++.nr t*v \n[.v] ++.nr t*s \n[.ps] ++.nr t*hy \n[.hy] ++.nr t*l \n[.ll] ++. ++. ++.\" defaults for table captions ++.nr t*cptn 0 1 ++.ds t*cptn "".sp .4" \ ++ ".t*pv 1.0 1.0" \ ++ ".ad l" \ ++ "\m[\\*[t*fgc]]Table \\n+[t*cptn]:\0\c\k*"\" ++. ++. ++.\" %beginstrip% ++. ++.\" for better error messages ++.ds nth-1 st\" ++.ds nth-2 nd\" ++.ds nth-3 rd\" ++. ++.\" initialization of various registers ++.nr t*# 0 \" table nesting level ++.nr t*numb 0 1 \" held table diversion # ++. ++.ds *#trc* ++. ++. ++.\" ***************************************************************** ++.\" * The four base macros and the two optional macros * ++.\" ***************************************************************** ++. ++.ie n \ ++. ds g tty:\" ++.el \ ++. ds g ps: exec\" ++. ++.\" TBL: table start ++.\" predecessor: text, TD or ETB ++.\" successor: CPTN or TR ++.de TBL ++. ds t*m\\n[t*#] \\n[.m]\" ++. ie \\n[t*#] \ ++. br ++. el \{\ ++. ds * \\n[.ev]\" ++. ev t*tbl ++. evc \\*[*] ++. di t*tbl0 ++. sp .4 \" XXX: hard-coded value ++. nr t*i \\n[.i] ++. ll -\\n[.i]u ++. in 0 ++. \} ++. nr t*# +1 ++. ++. \" Save current location for error checking at end ++. ds t*FN \\[.F] ++. ds t*LN \\[.c] ++. ++. t*getarg cols \\$@\" from here string `args' contains the rest of \\$@ ++. ie "\\*[cols]"" \ ++. nr t*cols\\n[t*#] \\n[t*cols] ++. el \{\ ++. ie \B\\*[cols] \ ++. nr t*cols\\n[t*#] \\*[cols] ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid number of columns value `\\*[cols]'. ++. \} ++. ++. t*getarg cpd \\*[args] \" cell padding ++. ie "\\*[cpd]"" \ ++. nr t*cpd\\n[t*#] \\n[t*cpd] ++. el \{\ ++. ie \B\\*[cpd] \ ++. nr t*cpd\\n[t*#] \\*[cpd] ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid cell padding value `\\*[cpd]'. ++. \} ++. ++. t*getarg csp \\*[args] \" cell spacing ++. ie "\\*[csp]"" \ ++. nr t*csp\\n[t*#] \\n[t*csp] ++. el \{\ ++. ie \B\\*[csp] \ ++. nr t*csp\\n[t*#] \\*[csp] ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid cell spacing value `\\*[csp]'. ++. \} ++. ++. t*getarg border \\*[args] \" border thickness ++. ie "\\*[border]"=" \ ++. nr t*b\\n[t*#] 0-1 ++. el \{\ ++. ie "\\*[border]"" \ ++. nr t*b\\n[t*#] \\n[t*b] ++. el \{\ ++. ie \B\\*[border] \ ++. nr t*b\\n[t*#] \\*[border] ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid border thickness value `\\*[border]'. ++. \}\} ++. ++. t*getarg bc \\*[args] \" border color ++. ds t*bc\\n[t*#] \\*[t*bc]\" ++. if !"\\*[bc]"" \{\ ++. ie m\\*[bc] \ ++. ds t*bc\\n[t*#] \\*[bc]\" ++. el \{\ ++. ie "\\*[bc]"=" \ ++. ds t*bc\\n[t*#] =\" ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid border color `\\*[bc]'. ++. \}\} ++. ie "\\*[bc]"=" \ ++. ds t*bc\\n[t*#] ++. el \{\ ++. ie "\\*[bc]"" \ ++. ds t*bc\\n[t*#] \\*[t*bc]\" ++. el \ ++. ds t*bc\\n[t*#] \\*[bc]\" ++. \} ++. ++. t*getarg width \\*[args] \" table/col widths ++. if "\\*[width]"=" \ ++. ds width ++. ++. nr b/2\\n[t*#] (\\n[t*b\\n[t*#]] / 2)\" shortcut ++. nr cscp\\n[t*#] (\\n[t*csp\\n[t*#]] + \\n[t*cpd\\n[t*#]])\" aux. register ++. ++. t*getarg height \\*[args] \" table outline height ++. ie "\\*[height]"" \ ++. nr t*height\\n[t*#] 0 ++. el \{\ ++. ie \B\\*[height] \ ++. nr t*height\\n[t*#] (\\*[height] \ ++ - ((2 * \\n[cscp\\n[t*#]]) \ ++ + (3 * \\n[b/2\\n[t*#]]))) ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid height value `\\*[height]'. ++. \} ++. ++. t*cl \\*[width] \" get cell widths and offsets ++. t*args \\n[t*#] \" look for common arguments ++. ++. t*getarg tal \\*[args] \" table horizontal alignment ++. if "\\*[tal]"" \ ++. ds tal \\*[t*tal]\" ++. ie "\\*[tal]"l" \ ++. nr in\\n[t*#] \\n[.i] ++. el \{\ ++. ie "\\*[tal]"c" \ ++. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]]/2 + \\n[.i]) ++. el \{\ ++. ie "\\*[tal]"r" \ ++. nr in\\n[t*#] (\\n[.l] - \\n[ll\\n[t*#]] + \\n[.i]) ++. el \{\ ++. tmc \\n[.F]:\\n[.c]: Invalid horizontal table alignment `\\*[tal]': ++. tm1 " must be `l', `c' or `r'. ++. \}\}\} ++. ++. nr t*r#\\n[t*#] 0 \" initialize row index ++. mk toptbl\\n[t*#] ++. ++. t*P1 \\*[args] ++.. ++. ++. ++.\" CPTN: optional table caption ++.\" predecessor: TBL ++.\" successor: TR ++.de CPTN ++. ft 1 ++. ++. if "\\$0"CPTN" \ ++. if \\n[t*r#\\n[t*#]] \{\ ++. tmc \\n[.F]:\\n[.c]: Invalid placement of `.CPTN'; ++. tm1 " must be called immediately after `.TBL'. ++. return ++. \} ++. ++. t*getarg val \\$@ ++. ds args\\n[t*#] "\\*[args]\" ++. ++. t*index "\\*[args]" .TR ++. ie \\n[t*index] \{\ ++. ds *a\\n[t*#] "\\*[args]\" ++. substring args\\n[t*#] 0 \\n[t*index] ++. substring *a\\n[t*#] \\n[t*index]-2 -1 ++. \} ++. el \ ++. ds *a\\n[t*#] ++. ++. ie "\\*[val]"b" \{\ ++. de t*cptn\\n[t*#] ++. *CPTN \\*[args\\n[t*#]] ++. rm t*cptn\\n[t*#] ++\\.. ++. \} ++. el \{\ ++. ll (\\n[ll\\n[t*#]]u + \\n[in\\n[t*#]]u) ++. in \\n[in\\n[t*#]]u ++. t*P1 \\*[t*cptn] ++' in +\\n[*]u ++. t*P1 \\*[args\\n[t*#]] ++. t*pv 1 1 ++. in ++. mk toptbl\\n[t*#] ++. \} ++. ++. t*P1 \\*[*a\\n[t*#]] ++.. ++. ++.als *CPTN CPTN ++. ++. ++.\" TR: table row ++.\" predecessor: TBL, CPTN, text, TD or ETB ++.\" successor: TD ++.de TR ++. ft 1 ++. if !\\n[t*#] \{\ ++. tm \\n[.F]:\\n[.c]: Table row (.TR) without preceding table start (.TBL). ++. return ++. \} ++. ++. \" finish previous data cell, if any ++. if \\n[t*r#\\n[t*#]] \ ++. t*dntr 1 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*] ++. ++. nr t*r#\\n[t*#] +1 \" row number in this table ++. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" table row identifier ++. \" (*) ++. nr c#\\*[#t#r] 0 1 \" clear cell counter ++. nr dntr\\*[#t#r] 0 1 \" clear accumulated row height ++. ++. t*getarg height \\$@ ++. ie "\\*[height]"" \ ++. nr t*height\\*[#t#r] 0 ++. el \{\ ++. ie \B\\*[height] \ ++. nr t*height\\*[#t#r] \\*[height] ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid table row height `\\*[height]'. ++. \} ++. ++. \" If there is a TR with height `height', the total height of the table ++. \" is too high by 3/2 b, independent of the number of TR with `height'. ++. t*args \\*[#t#r] \\n[t*#] \" look for common arguments ++. ++. t*P1 \\*[args] ++.. ++. ++. ++.\" TH: optional table header cell ++.\" predecessor: text, TD or TR ++.\" successor: text, TD, TR, TBL or ETB ++.\" ++.\" cell content bolded and horizontally and vertically centered, ++.\" else like .TD ++.de TH ++. ft 1 ++. t*getarg hal \\$@ ++. if "\\*[hal]"" \ ++. ds hal c\" ++. ++. t*getarg val \\*[args] ++. if "\\*[val]"" \ ++. ds val m\" ++. ++. t*getarg fst \\*[args] ++. if "\\*[fst]"" \ ++. ds fst B\" ++. ++. TD hal=\\*[hal] val=\\*[val] fst=\\*[fst] \\*[args] ++.. ++. ++. ++.\" TD: table data cell ++.\" predecessor: text, TD or TR ++.\" successor: text, TD, TR, TBL or ETB ++.de TD ++. ft 1 ++. \" finish previous data cell -- note the use of \E ++. t*dntr 0 \\n[c#\\*[#t#r]]-1 \En[c#\\*[#t#r]] \\*[*#trc*] ++. ++. ds *#trc* \\*[#t#r]*\\n[c#\\*[#t#r]]\" table cell identifier ++. \" (**) ++. ++. t*getarg rowspan \\$@ ++. nr rowspan 1 ++. if !"\\*[rowspan]"" \{\ ++. ie \B\\*[rowspan] \{\ ++. nr rowspan (\\*[rowspan] >? 1) ++. nr *rsp*\\*[*#trc*] (\\n[rowspan] - 1) ++. \} ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid value of `rowspan' keyword. ++. \} ++. ++. t*getarg colspan \\*[args] ++. nr colspan 1 ++. if !"\\*[colspan]"" \{\ ++. ie \B\\*[colspan] \ ++. nr colspan (\\*[colspan] >? 1) ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid value of `colspan' keyword. ++. \} ++. ++. t*args \\*[#trc] \\*[#t#r] \" look for common arguments ++. ++. nr in\\*[#trc] \\n[in\\n[t*#]*\\n[c#\\*[#t#r]]] ++. nr *cl \\n[cll\\n[t*#]*\\n[c#\\*[#t#r]]] ++. nr * 0 1 ++. nr *r \\n[t*r#\\n[t*#]] ++. ++. if (\\n[rowspan] - 1) \ ++. while (\\n+[*] <= \\n[rowspan]) \{\ ++. nr rspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan] ++. if (\\n[*] > 1) \ ++. nr cspan\\n[t*#]*\\n[*r]*\\n[c#\\*[#t#r]] \\n[colspan] ++. nr *r +1 ++. \} ++. ++. nr * 1 1 ++. nr *c \\n[c#\\*[#t#r]] ++. ++. if (\\n[colspan] - 1) \{\ ++. nr vline\\*[*#trc*] 0-1 \" set `no vl' flag ++. ++. while (\\n+[*] <= \\n[colspan]) \{\ ++. nr *c +1 ++. nr *cl +(2 * \\n[cscp\\n[t*#]] \ ++ + \\n[b/2\\n[t*#]] \ ++ + \\n[cll\\n[t*#]*\\n[*c]]) ++. nr c#\\*[#t#r] +1 ++. \} ++. \} ++. ++. if (\\n[c#\\n[t*#]*\\n[t*r#\\n[t*#]]] > \\n[t*cols\\n[t*#]]) \{\ ++. ds * are\" ++. ds ** columns\" ++. if (\\n[c#\\*[#t#r]] == 1) \{\ ++. ds * is\" ++. ds ** column\" ++. \} ++. tmc \\n[.F]:\\n[.c]: There \\*[*] \\n[c#\\*[#t#r]] table \\*[**] (.TD) ++. ++. ds * are\" ++. if (\\n[t*cols\\n[t*#]] == 1) \ ++. ds * is\" ++. tm1 " but only \\n[t*cols\\n[t*#]] \\*[*] expected. ++. ++. ds * ++. length * \\n[.F]:\\n[.c]: ++. ++. while \\n-[*] \ ++. ds * " \\*[*]\" ++. ++. tm1 "\\*[*] Remaining .TDs and its contents are ignored. ++. ++. di *t*dummy* \" bypass superfluous input ++. return ++. \} ++. ++. di t*\\*[#trc] \" open cell diversion and set locals ++. in 0 ++. nr cll\\*[#trc] \\n[*cl] ++. ll \\n[*cl]u ++. nr *cl\\n[t*#] \\n[.l] ++. gcolor \\*[t*fgc\\*[#trc]] ++. ad \\*[t*hal\\*[#trc]] ++. fam \\*[t*ff\\*[#trc]] ++. ft \\*[t*fst\\*[#trc]] ++. t*pv \\*[t*fsz\\*[#trc]] ++. ++. t*P1 \\*[args] ++.. ++. ++. ++.\" ETB: end of table ++.\" predecessor: text, TD or ETB ++.\" successor: text, TD, TR or TBL ++.de ETB ++. ie \\n[t*#] \ ++. if !\\n[t*r#\\n[t*#]] \{\ ++. tmc \\n[.F]:\\n[.c]: Each table (.TBL) ++. tm1 " should contain at least one table row (.TR)! ++. \} ++. el \{\ ++. tmc \\n[.F]:\\n[.c]: Table end (.ETB) ++. tm1 " without corresponding table start (.TBL)! ++. \} ++. ++. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier ++. t*dntr 2 \\n[c#\\*[#t#r]] \\n[t*cols\\n[t*#]] \\*[*#trc*] ++. ++. t*divs \" print this table ++. ++. sp \\n[b/2\\n[t*#]]u ++. t*cptn\\n[t*#] ++. nr t*# -1 ++. ++. ll \\n[*cl\\n[t*#]]u \" restore ll outside this table ++. in 0 \" reset indent ++. gcolor \\*[t*m\\n[t*#]] \" reset previous fgc ++. ++. t*getarg hold \\$@ ++. if !\\n[t*#] \{\ ++. sp .5 ++. di ++. in \\n[t*i]u ++. ie "\\*[hold]"" \{\ ++. ie (\\n[.t] - \\n[dn]) \ ++. t*DI t*tbl0 ++. el \{\ ++. rn t*tbl0 t*tbl\\n+[t*numb] ++. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[dn]\" ++. \} ++. \} ++. el \{\ ++. rn t*tbl0 t*hold\\n+[t*numb] ++. tm \\n[.F]:\\n[.c]: Table t*hold\\n[t*numb] held. ++. ds t*held \\*[t*held] t*hold\\n[t*numb] \\n[dn]\" ++. \} ++. ++. ev \" restore previous environment ++. \} ++. ++. t*P1 \\*[args] ++.. ++. ++. ++.\" ***************************************************************** ++.\" * Following the definition of five utility macros * ++.\" * special to hdtbl. * ++.\" * Other utility macros common to hdtbl and hdgroff * ++.\" * are defined in the file hdmisc.tmac. * ++.\" ***************************************************************** ++. ++. ++.\" .t*free [n] ++.\" print the next [n] held table[s]. ++.\" Don't call it within a table! ++.\" If the table is higher than the remaining space ++.\" on the page, the table is printed on the next page. ++.de t*free ++. if "\\$0"CPTN" \ ++. if \\n[t*r#\\n[t*#]] \{\ ++. tmc \\n[.F]:\\n[.c]: Invalid placement of `.t*free' within a table; ++. tm1 " it must be called outside of any table. ++. return ++. \} ++. ++. if "\\*[t*held]"" \{\ ++. tm \\n[.F]:\\n[.c]: No held tables. ++. return ++. \} ++. ++. nr ** (\\$1 >? 1) 1 ++. while !""\\*[t*held]" \{\ ++. pops * t*held ++. popr * t*held ++. ++. ie (\\n[.t] - \\n[*]) \{\ ++. ev t*tbl ++. t*DI \\*[*] ++. ev ++. \} ++. el \{\ ++. rn \\*[*] t*tbl\\n+[t*numb] ++. ds t*kept \\*[t*kept] t*tbl\\n[t*numb] \\n[*]\" ++. \} ++. ++. if !(\\n-[**] - 1) \ ++. return ++. \} ++.. ++. ++. ++.\" The main utility macro for tables: ++.\" If a table is closed by ETB, this macro is called. It ++.\" processes one complete table, i.e., all the table cell ++.\" diversions, paints the cell backgrounds, draws ++.\" horizontal and vertical table lines and the table border. ++.\" ++.\" Nested tables are processed from inside to outside. ++. ++.de t*divs ++. ll (\\n[t*l]u + 1c) \" avoid warning `can't break line' ++. nf ++. ++. nr b/2 \\n[b/2\\n[t*#]] \" some abbreviations ++. nr cscp \\n[cscp\\n[t*#]] ++. nr cscpb (\\n[b/2] + \\n[cscp]) ++. ++. nr topdiv (\\n[.d] + \\n[b/2] - \\n[cscp])\" top of cell diversion ++. nr cscpb2 (\\n[b/2] / 2 + \\n[cscp]) ++. ++. nr #r 0 1 ++. \" outer loop for rows ++. while (\\n+[#r] <= \\n[t*r#\\n[t*#]]) \{\ ++. \" TODO: insert code here for multipage tables ++. nr * (\\n[#r] - 1) ++. nr topdiv +(\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb]) ++. ++. \" if table still smaller than specified table height, increase it ++. if ((\\n[#r] == \\n[t*r#\\n[t*#]]) & \\n[t*height\\n[t*#]]) \ ++. nr dntr\\n[t*#]*\\n[#r] (\\n[cscpb] \ ++ + \\n[toptbl\\n[t*#]] \ ++ + \\n[t*height\\n[t*#]] \ ++ - (\\n[topdiv] >? \\n[dntr\\n[t*#]*\\n[#r]])) ++. ++. nr #c 0 1 ++. \" inner loop for cells ++. while (\\n+[#c] <= \\n[t*cols\\n[t*#]]) \{\ ++. ds #trc \\n[t*#]*\\n[#r]*\\n[#c]\" ++. \" continue if the diversion is empty ++. if !d t*\\*[#trc] \ ++. continue ++. ++. sp |\\n[topdiv]u ++. in (\\n[in\\n[t*#]]u + \\n[in\\*[#trc]]u)\" cell offset ++. nr $1 \\n[dntr\\n[t*#]*\\n[#r]] \" cell height ++. ++. \" if we have spanned rows, calculate resulting row height ++. \" and position of lower horizontal line ++. if \\n[*rsp*\\*[#trc]] \{\ ++. nr * \\n[#r] 1 ++. nr rspan\\*[#trc] 0-1 \" set `no hl' flag ++. nr corr (\\n[dn\\*[#trc]] - \\n[dntr\\n[t*#]*\\n[#r]]) ++. ++. \" clear row span flags in following rows and update row height ++. while \\n[*rsp*\\*[#trc]] \{\ ++. nr *rsp*\\*[#trc] -1 ++. nr rspan\\n[t*#]*\\n+[*]*\\n[#c] 0 ++. nr ** (\\n[dntr\\n[t*#]*\\n[*]] + \\n[cscp] + \\n[cscpb]) ++. nr corr -\\n[**] ++. nr $1 +\\n[**] ++. \} ++. ++. if (\\n-[*] == \\n[t*r#\\n[t*#]]) \ ++. nr $1 ((\\n[t*height\\n[t*#]] \ ++ - \\n[.d] \ ++ + \\n[toptbl\\n[t*#]] \ ++ + \\n[cscpb]) \ ++ >? \\n[$1]) ++. nr dntr\\n[t*#]*\\n[*] +(\\n[corr] >? 0) ++. \} ++. ++. \" paint cell background ++. nr * (2 * \\n[t*cpd\\n[t*#]] + \\n[cll\\*[#trc]])\" background width ++. nr $1 (\\n[$1] >? \\n[dn\\*[#trc]])\" cell height ++. ++. if !"\\*[t*bgc\\*[#trc]]"=" \{\ ++. nop \h'\\n[t*csp\\n[t*#]]u'\ ++\M[\\*[t*bgc\\*[#trc]]]\ ++\v'(-.67v - \\n[t*cpd\\n[t*#]]u)'\ ++\D'P \\n[*]u 0 \ ++ 0 (2u * \\n[t*cpd\\n[t*#]]u + \\n[$1]u) \ ++ -\\n[*]u 0'\ ++\M[] ++. sp -1 ++. \} ++. ++. \" *** horizontal and vertical single or double lines *** ++. \" double and single lines have the same thickness; ++. \" the double lines' distance is the line thickness. ++. \" ++. \" `border=x': horizontal/vertical lines x/2 thick, minimum .1n ++. \" `border=0': no border; horizontal/vertical lines .1n thick ++. \" `border=': neither border nor horizontal/vertical lines ++. ++. nr *t (.1n >? \\n[b/2]) \" thickness of hl/vl; min. .1n ++. in +\\n[cscp]u ++. ++. \" check for vertical and horizontal lines ++. if (1 + \\n[t*b\\n[t*#]]) \{\ ++. if !"\\*[t*bc\\n[t*#]]"=" \{\ ++. \" draw horizontal line between this cell and the one below ++. if (\\n[t*r#\\n[t*#]] - \\n[#r] + \\n[rspan\\*[#trc]]) \{\ ++. if !"\\*[t*hl\\*[#trc]]"=" \{\ ++. sp \\n[$1]u ++. nr * (\\n[cscp] + \\n[cscpb] + \\n[cll\\*[#trc]]) ++. nop \X'\*[g] 1 setlinecap'\ ++\h'(-\\n[cscpb2]u - \\n[*t]u)'\ ++\v'(\\n[cscpb2]u - .67v)'\ ++\m[\\*[t*bc\\n[t*#]]]\ ++\D't \\n[*t]u'\c ++. ++. ie "\\*[t*hl\\*[#trc]]"d" \ ++. nop \v'-\\n[*t]u'\ ++\D'l \\n[*]u 0'\ ++\v'(2u * \\n[*t]u)'\ ++\D'l -\\n[*]u 0'\ ++\D't 0' ++. el \ ++. nop \D'l \\n[*]u 0'\ ++\D't 0' ++. ++. sp (-\\n[$1]u - 1v) ++. \}\} ++. ++. nr rspan\\*[#trc] 0 ++. ++. \" draw vertical line between this cell and the one to the right ++. if (\\n[t*cols\\n[t*#]] - \\n[#c] + \\n[vline\\*[#trc]]) \{\ ++. if !"\\*[t*vl\\*[#trc]]"=" \{\ ++. nop \X'\*[g] 1 setlinecap'\ ++\v'(-\\n[cscpb2]u - .67v)'\ ++\m[\\*[t*bc\\n[t*#]]]\ ++\h'(\\n[cscpb2]u - \\n[*t]u + \\n[cll\\*[#trc]]u)'\c ++. ++. ie "\\*[t*vl\\*[#trc]]"d" \ ++. nop \h'-\\n[*t]u'\ ++\D't \\n[*t]u'\ ++\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\ ++\h'(2u * \\n[*t]u)'\ ++\D'l 0 -(2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\ ++\D't 0' ++. el \ ++. nop \D't \\n[*t]u'\ ++\D'l 0 (2u * \\n[cscp]u + \\n[$1]u + (\\n[*t]u / 2u))'\ ++\D't 0' ++. sp -1 ++. \}\}\}\} ++. ++. nr vline\\*[#trc] 0 ++. ++. \" vert. cell content alignment ++. nr ** 0 ++. ++. ie "\\*[t*val\\*[#trc]]"m" \ ++. nr ** ((\\n[$1] - \\n[dn\\*[#trc]]) / 2)\" val=m ++. el \ ++. if "\\*[t*val\\*[#trc]]"b" \ ++. nr ** (\\n[$1] - \\n[dn\\*[#trc]])\" val=b ++. ++. sp \\n[**]u \" vertical content position ++. ++. \" finally output the diversion ++. t*\\*[#trc] ++. rm t*\\*[#trc] ++. \} ++. \} ++. ++. \" draw the box border ++. in \\n[in\\n[t*#]]u ++. nr ** (\\n[topdiv] + \\n[dntr\\n[t*#]*\\n-[#r]]) ++. ++. if \\n[t*b\\n[t*#]] \{\ ++. sp |(\\n[toptbl\\n[t*#]]u + \\n[b/2]u) ++. nr $1 (\\n[toptbl\\n[t*#]] - \\n[**] - \\n[cscp]) ++. nr * (\\n[ll\\n[t*#]] - \\n[t*b\\n[t*#]]) ++. ++. if !"\\*[t*bc\\n[t*#]]"=" \ ++. nop \X'\*[g] 0 setlinejoin 2 setlinecap'\ ++\v'-.67v'\ ++\h'-\\n[b/2]u'\ ++\m[\\*[t*bc\\n[t*#]]]\ ++\D't \\n[t*b\\n[t*#]]u'\ ++\D'l \\n[*]u 0'\ ++\D'l 0 -\\n[$1]u'\ ++\D'l -\\n[*]u 0'\ ++\D'l 0 \\n[$1]u'\ ++\D't 0' ++. \} ++. ++. sp |(\\n[**]u + \\n[cscpb]u) ++. fi ++.. ++. ++. ++.\" Utility macro: .t*cl [width1 [width2 [...]]] ++.\" ++.\" Calculate cell widths, table width, and cell offsets. ++.de t*cl ++. nr t*cols\\n[t*#] (\\n[.$] >? \\n[t*cols\\n[t*#]]) ++. nr ll\\n[t*#] 0 \" accumulated cell widths ++. nr ** (\\n[.l] / \\n[t*cols\\n[t*#]])\" width for remaining cells ++. nr * 0 1 \" counter ++. ++. \" while-loop: Parse user arguments to get each cell's width. ++. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\ ++. nr $\\n[*] \\n[**] ++. if !"\\$[\\n[*]]"" \{\ ++. \" check for `%' pseudo scaling indicator ++. ds * \\$\\n[*]\" ++. substring * -1 -1 ++. ie "\\*[*]"%" \{\ ++. ds ** \\$[\\n[*]]\" ++. substring ** 0 -2 ++. ie \B\\*[**] \ ++. nr $\\n[*] (\\*[**] * \\n[.l] / 100) ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid relative cell width `\\*[**]%'. ++. \} ++. el \{\ ++. ie \B\\$[\\n[*]] \ ++. nr $\\n[*] \\$[\\n[*]] ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid cell width `\\$[\\n[*]]'. ++. \}\} ++. ++. nr ll\\n[t*#] +\\n[$\\n[*]] ++. nr ** \\n[$\\n[*]] ++. \} ++. ++. if (\\n[ll\\n[t*#]] > \\n[.l]) \ ++. tm \\n[.F]:\\n[.c]: Table width larger than column width. ++. ++. nr ** (0 >? \\n[t*b\\n[t*#]]) ++. nr * 0 1 ++. ++. \" second while loop: Compute final cell widths. ++. while (\\n[t*cols\\n[t*#]] >= \\n+[*]) \{\ ++. \" Remove border width, if any. ++. if \\n[t*b\\n[t*#]] \{\ ++. \" cell_width := cell_width * (length - 1.5*border) / length ++. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2)) ++. nr *** (\\n[ll\\n[t*#]] / 2) ++. \" avoid multiplication overflow ++. mult31by31 $\\n[*] #* **** ++. add31to62 *** **** **** ++. div62by31 **** ll\\n[t*#] $\\n[*] ++. \} ++. ++. \" Get cell widths without padding, spacing, and separator line. ++. nr cll\\n[t*#]*\\n[*] (\\n[$\\n[*]] \ ++ - (2 * \\n[cscp\\n[t*#]]) \ ++ - \\n[b/2\\n[t*#]]) ++. ++. \" Check whether value is non-positive. ++. if !\\n[cll\\n[t*#]*\\n[*]] \{\ ++. nr #* (\\n[ll\\n[t*#]] - (3 * \\n[t*b\\n[t*#]] / 2)) ++. nr *** (\\n[#*] / 2) ++. nr *h (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]]) ++. mult31by31 *h ll\\n[t*#] **** ++. add31to62 *** **** **** ++. div62by31 **** #* *h ++. ds * \\n[*]th\" ++. nr *** (\\n[*] % 10) ++. if d nth-\\n[***] \ ++. ds * \\n[*]\\*[nth-\\n[***]]\" ++. tmc \\n[.F]:\\n[.c]: The \\*[*] width value (\\$\\n[*]) is too small. ++. tm1 " It should be greater than \\n[*h]. ++. \} ++. ++. nr in\\n[t*#]*\\n[*] \\n[**] \" cell offset ++. nr ** +\\n[$\\n[*]] ++. \} ++.. ++. ++. ++.\" Utility macro: .t*dntr ? ++.\" ++.\" Close TD diversion, make some calculations, and set ++.\" some help strings and registers. is 0, 1, ++.\" or 2 if the call of .t*dntr occurs in .TD, .TR, or ++.\" .ETB, respectively. ++.de t*dntr ++. nr dn 0 \" reset diversion height ++. br \" finish cell data ++. ++. if "\\n[.z]"*t*dummy*" \ ++. return ++. ++. ds #t#r \\n[t*#]*\\n[t*r#\\n[t*#]]\" refresh table row identifier ++. ++. if \\n[c#\\*[#t#r]] \{\ ++. di \" close diversion ++. nr dn\\$4 \\n[dn] \" save height of this cell ++. if !\\n[rspan\\*[#trc]] \{\ ++. \" update row height if not in a row span ++. nr dntr\\*[#t#r] (\\n[dntr\\*[#t#r]] >? \\n[dn]) ++. if \\$2 \ ++. nr dntr\\*[#t#r] ((\\n[t*height\\*[#t#r]] \ ++ - (2 * \\n[cscp\\n[t*#]] + \\n[b/2\\n[t*#]])) \ ++ >? \\n[dntr\\*[#t#r]]) ++. \}\} ++. ++. nr c#\\*[#t#r] +1 ++. nr * \\$2 ++. ++. \" update column span registers ++. while (\\n+[*] <= \\$3) \{\ ++. if r cspan\\*[#t#r]*\\n[*] \ ++. nr c#\\*[#t#r] +\\n[cspan\\*[#t#r]*\\n[*]] ++. nr cspan\\*[#t#r]*\\n[*] 0 ++. \} ++. ++. ds #trc \\*[#t#r]*\\n[c#\\*[#t#r]]\" ++. ++. \" only check for cell underflow if called by .TR or .ETB ++. if (\\$1 & (\\n[c#\\*[#t#r]] <= \\n[t*cols\\n[t*#]])) \{\ ++. ds * are\" ++. ds ** columns\" ++. if (\\n-[c#\\*[#t#r]] == 1) \{\ ++. ds * is\" ++. ds ** column\" ++. \} ++. tmc \\n[.F]:\\n[.c]: There \\*[*] only \\n[c#\\*[#t#r]] \\*[**] ++. ++. nr * \\n[t*r#\\n[t*#]] ++. ds * \\n[*]th\" ++. nr *** (\\n[*] % 10) ++. if d nth-\\n[***] \ ++. ds * \\n[*]\\*[nth-\\n[***]]\" ++. tmc " in the \\*[*] row ++. ++. ds * are\" ++. if (\\n[t*cols\\n[t*#]] == 1) \ ++. ds * is\" ++. tm1 " but \\n[t*cols\\n[t*#]] \\*[*] expected. ++. \} ++.. ++. ++. ++.\" Utility-macro: .t*args level_1 [level_2] ++.\" ++.\" Get the arguments common to TBL, TR, and TD for the level ++.\" in argument 1, using default values from the level in ++.\" argument 2. If argument 2 is missing, use the global ++.\" default values. ++.\" ++.de t*args ++. ds t*bgc\\$1 \\*[t*bgc\\$2]\" ++. ds t*fgc\\$1 \\*[t*fgc\\$2]\" ++. ds t*hl\\$1 \\*[t*hl\\$2]\" ++. ds t*vl\\$1 \\*[t*vl\\$2]\" ++. ds t*hal\\$1 \\*[t*hal\\$2]\" ++. ds t*val\\$1 \\*[t*val\\$2]\" ++. ds t*ff\\$1 \\*[t*ff\\$2]\" ++. ds t*fst\\$1 \\*[t*fst\\$2]\" ++. ds t*fsz\\$1 \\*[t*fsz\\$2]\" ++. ++. if "\\*[args]"" \ ++. return ++. ++. t*getarg bgc \\*[args] \" background color ++. if !"\\*[bgc]"" \{\ ++. ie m\\*[bgc] \ ++. ds t*bgc\\$1 \\*[bgc]\" ++. el \{\ ++. ie "\\*[bgc]"=" \ ++. ds t*bgc\\$1 =\" ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid background color `\\*[bgc]'. ++. \}\} ++. if "\\*[args]"" \ ++. return ++. ++. t*getarg fgc \\*[args] \" foreground color ++. if !"\\*[fgc]"" \{\ ++. ie m\\*[fgc] \ ++. ds t*fgc\\$1 \\*[fgc]\" ++. el \{\ ++. ie "\\*[fgc]"=" \ ++. ds t*fgc\\$1 =\" ++. el \ ++. tm \\n[.F]:\\n[.c]: Invalid foreground color `\\*[fgc]'. ++. \}\} ++. if "\\*[args]"" \ ++. return ++. ++. t*getarg hl \\*[args] \" horizontal line between cells ++. if !"\\*[hl]"" \ ++. ds t*hl\\$1 \\*[hl]\" ++. if "\\*[args]"" \ ++. return ++. ++. t*getarg vl \\*[args] \" vertical line between cells ++. if !"\\*[vl]"" \ ++. ds t*vl\\$1 \\*[vl]\" ++. if "\\*[args]"" \ ++. return ++. ++. t*getarg hal \\*[args] \" horizontal table cell alignment ++. if !"\\*[hal]"" \{\ ++. t*index bcrl \\*[hal] ++. ie \\n[t*index] \ ++. ds t*hal\\$1 \\*[hal]\" ++. el \{\ ++. tmc \\n[.F]:\\n[.c]: Invalid horizontal alignment `\\*[hal]': ++. tm1 " must be `b', `c', `l' or `r'. ++. \}\} ++. if "\\*[args]"" \ ++. return ++. ++. t*getarg val \\*[args] \" vertical table cell alignment ++. if !"\\*[val]"" \{\ ++. t*index tmb \\*[val] ++. ie \\n[t*index] \ ++. ds t*val\\$1 \\*[val]\" ++. el \{\ ++. tmc \\n[.F]:\\n[.c]: Invalid vertical alignment `\\*[val]': ++. tm1 " must be `t', `m' or `b'. ++. \}\} ++. if "\\*[args]"" \ ++. return ++. ++. t*getarg ff \\*[args] \" font family ++. if !"\\*[ff]"" \ ++. ds t*ff\\$1 \\*[ff]\" ++. if "\\*[args]"" \ ++. return ++. ++. t*getarg fst \\*[args] \" font style ++. if !"\\*[fst]"" \ ++. ds t*fst\\$1 \\*[fst]\" ++. if "\\*[args]"" \ ++. return ++. ++. t*getarg fsz \\*[args] \" font size and spacing factor ++. if !"\\*[fsz]"" \ ++. ds t*fsz\\$1 \\*[fsz]\" ++.. ++. ++. ++.\" Append to your page header macro ('pg@top' for MS) ++.\" to enable tables to span pages. ++.de t*hm ++. ev t*tbl ++. nr ** \\n[.t] ++. while !""\\*[t*kept]" \{\ ++. pops * t*kept ++. popr * t*kept ++. if (\\n[*] - \\n[**]) \{\ ++. tm \\n[.F]:\\n[.c]: Table \\*[*] higher than page -- ignored! ++. break ++. \} ++. ++. if (\\n[*] - \\n[.t]) \{\ ++. ds t*kept \\n[*] \\*[t*kept]\" ++. ds t*kept \\*[*] \\*[t*kept]\" ++. tmc \\n[.F]:\\n[.c]: Remaining table(s), ++. tm1 " because not all fit onto this page. ++. break ++. \} ++. ++. t*DI \\*[*] ++. \} ++. ev ++.. ++. ++.\" EOF +diff -Nuar groff-1.22.3.old/contrib/hdtbl/Makefile.sub groff-1.22.3/contrib/hdtbl/Makefile.sub +--- groff-1.22.3.old/contrib/hdtbl/Makefile.sub 2014-11-04 10:38:35.483520772 +0200 ++++ groff-1.22.3/contrib/hdtbl/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,174 +0,0 @@ +-# Copyright (C) 2006-2014 Free Software Foundation, Inc. +-# Written by Werner Lemberg (wl@gnu.org) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-# These may be overridden if cross-compiling. +-GROFFBIN=$(top_builddir)/src/roff/groff/groff +-GROFF_BIN_PATH=`echo $(groff_bin_dirs) | sed -e 's| *|$(SH_SEP)|g'` +- +-groff_bin_dirs=\ +- $(top_builddir)/src/roff/groff \ +- $(top_builddir)/src/roff/troff \ +- $(top_builddir)/src/preproc/eqn \ +- $(top_builddir)/src/preproc/pic \ +- $(top_builddir)/src/preproc/tbl \ +- $(top_builddir)/src/devices/grops +- +-FFLAG=-F$(top_builddir)/font -F$(top_srcdir)/font +-TFLAG=-M$(top_builddir)/tmac -M$(top_srcdir)/tmac -M$(srcdir) +-PFLAG=-t -p -e -U +- +-GROFF=\ +- GROFF_COMMAND_PREFIX= \ +- GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ +- $(GROFFBIN) $(FFLAG) $(TFLAG) $(PFLAG) +- +-MAN7=\ +- groff_hdtbl.n +- +-# These files are processed with `strip.sed'. +-STRIPFILES=\ +- hdtbl.tmac \ +- hdmisc.tmac +- +-# These files are handled by the `.in.roff' rule. +-GENFILES=\ +- examples/fonts_n.roff \ +- examples/fonts_x.roff +- +-EXAMPLEFILES=\ +- examples/common.roff \ +- examples/chess_board.roff \ +- examples/color_boxes.roff \ +- examples/color_nested_tables.roff \ +- examples/color_table_cells.roff \ +- examples/color_transitions.roff \ +- examples/col_rowspan_colors.roff \ +- examples/mixed_pickles.roff \ +- examples/rainbow.roff \ +- examples/short_reference.roff +- +-PROCESSEDEXAMPLEFILES=\ +- examples/chess_board.ps \ +- examples/color_boxes.ps \ +- examples/color_nested_tables.ps \ +- examples/color_table_cells.ps \ +- examples/color_transitions.ps \ +- examples/col_rowspan_colors.ps \ +- examples/fonts_n.ps \ +- examples/fonts_x.ps \ +- examples/mixed_pickles.ps \ +- examples/rainbow.ps \ +- examples/short_reference.ps +- +-EXAMPLEFILES_=`echo $(EXAMPLEFILES) | sed 's|examples/||g'` +-GENFILES_=`echo $(GENFILES) | sed 's|examples/||g'` +-PROCESSEDEXAMPLEFILES_=`echo $(PROCESSEDEXAMPLEFILES) | sed 's|examples/||g'` +- +-MOSTLYCLEANADD=\ +- gnu.eps \ +- $(PROCESSEDEXAMPLEFILES) \ +- $(GENFILES) \ +- examples/stamp \ +- stamp-strip \ +- hdmisc.tmac-s hdtbl.tmac-s +- +-RM=rm -f +- +-.SUFFIXES: .roff .in .ps +- +-.roff.ps: +- $(GROFF) -Tps -dfontpath=$(top_srcdir)/font -dsopath=$(srcdir)/ \ +- -mhdtbl $< >$@ +- +-.in.roff: +- sed -e "s|@fontdir@|$(fontdir)|" $< >$@ +- +-all: $(make_examples) stamp-strip +- +-.PHONY: examples +-examples: $(PROCESSEDEXAMPLEFILES) +- +-$(PROCESSEDEXAMPLEFILES): gnu.eps examples/stamp examples/common.roff +- +-gnu.eps: +- if test -f $(top_srcdir)/doc/gnu.eps; then \ +- cp $(top_srcdir)/doc/gnu.eps . ; \ +- elif test -f $(top_builddir)/doc/gnu.eps; then \ +- cp $(top_builddir)/doc/gnu.eps . ; \ +- else \ +- xpmtoppm $(top_srcdir)/doc/gnu.xpm | pnmdepth 15 \ +- | $(pnmtops_nosetpage) -noturn -rle >$@ ; \ +- fi +- +-examples/stamp: +- -test -d examples || $(mkinstalldirs) examples +- touch $@ +- +-stamp-strip: $(STRIPFILES) +- for f in $(STRIPFILES); do \ +- $(RM) $$f-s; \ +- sed -f $(top_srcdir)/tmac/strip.sed $(srcdir)/$$f >$$f-s; \ +- done +- touch $@ +- +-$(GENFILES): examples/stamp +- +-install_data: install_always $(make_install_examples) +- +-install_always: $(STRIPFILES) $(GENFILES) +- -test -d $(DESTDIR)$(tmacdir) || $(mkinstalldirs) $(DESTDIR)$(tmacdir) +- for f in $(STRIPFILES); do \ +- $(RM) $(DESTDIR)$(tmacdir)/$$f; \ +- $(INSTALL_DATA) $$f-s $(DESTDIR)$(tmacdir)/$$f; \ +- done +- +-install_examples: install_always $(EXAMPLEFILES) $(PROCESSEDEXAMPLEFILES) \ +- gnu.eps stamp-strip +- -test -d $(DESTDIR)$(exampledir)/hdtbl \ +- || $(mkinstalldirs) $(DESTDIR)$(exampledir)/hdtbl +- for f in $(EXAMPLEFILES_); do \ +- $(RM) $(DESTDIR)$(exampledir)/hdtbl/$$f; \ +- $(INSTALL_DATA) $(srcdir)/examples/$$f \ +- $(DESTDIR)$(exampledir)/hdtbl/$$f; \ +- done +- for f in $(PROCESSEDEXAMPLEFILES_) $(GENFILES_); do \ +- $(RM) $(DESTDIR)$(exampledir)/hdtbl/$$f; \ +- $(INSTALL_DATA) examples/$$f $(DESTDIR)$(exampledir)/hdtbl/$$f; \ +- done +- $(INSTALL_DATA) gnu.eps $(DESTDIR)$(exampledir)/hdtbl/gnu.eps +- +-uninstall_sub: uninstall_always $(make_uninstall_examples) +- +-uninstall_always: +- -for f in $(STRIPFILES); do $(RM) $(DESTDIR)$(tmacdir)/$$f; done +- +-uninstall_examples: uninstall_always +- -for f in $(EXAMPLEFILES_) $(PROCESSEDEXAMPLEFILES_) $(GENFILES_); do \ +- $(RM) $(DESTDIR)$(exampledir)/hdtbl/$$f; \ +- done +- $(RM) $(DESTDIR)$(exampledir)/hdtbl/gnu.eps +- -test -d $(DESTDIR)$(exampledir)/hdtbl && \ +- rmdir $(DESTDIR)$(exampledir)/hdtbl +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/mm/ChangeLog groff-1.22.3/contrib/mm/ChangeLog +--- groff-1.22.3.old/contrib/mm/ChangeLog 2014-11-04 10:38:35.487520722 +0200 ++++ groff-1.22.3/contrib/mm/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,9 @@ ++Fri Apr 3 16:33:22 2015 Werner LEMBERG ++ ++ Make man pages work in compatibility mode. ++ ++ * groff_mm.man, groff_mmse.man, mmroff.man: Do it. ++ + Wed Sep 3 21:29:00 2014 Bernd Warken + + * all files in contrib/mm: Copying and Emacs setting. +diff -Nuar groff-1.22.3.old/contrib/mm/.gitignore groff-1.22.3/contrib/mm/.gitignore +--- groff-1.22.3.old/contrib/mm/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/mm/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,4 @@ ++groff_mm.n ++groff_mmse.n ++mmroff ++mmroff.n +diff -Nuar groff-1.22.3.old/contrib/mm/groff_mm.man groff-1.22.3/contrib/mm/groff_mm.man +--- groff-1.22.3.old/contrib/mm/groff_mm.man 2014-11-04 10:38:35.487520722 +0200 ++++ groff-1.22.3/contrib/mm/groff_mm.man 2015-04-23 20:57:03.000000000 +0300 +@@ -4,6 +4,10 @@ + groff_mm \- groff mm macros + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .de co + Copyright \[co] 1989-2014 Free Software Foundation, Inc. + +@@ -3977,6 +3981,9 @@ + .au + . + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" mode: nroff + .\" coding: latin-1 +diff -Nuar groff-1.22.3.old/contrib/mm/groff_mmse.man groff-1.22.3/contrib/mm/groff_mmse.man +--- groff-1.22.3.old/contrib/mm/groff_mmse.man 2014-11-04 10:38:35.487520722 +0200 ++++ groff-1.22.3/contrib/mm/groff_mmse.man 2015-04-23 20:57:03.000000000 +0300 +@@ -4,6 +4,10 @@ + groff_mmse \- svenska mm makro fr groff + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .ig + Copyright \[co] 1989-2014 Free Software Foundation, Inc. + +@@ -157,6 +161,9 @@ + .br + .BR groff_mm (@MAN7EXT@) + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" coding: latin-1 + .\" mode: nroff +diff -Nuar groff-1.22.3.old/contrib/mm/Makefile.sub groff-1.22.3/contrib/mm/Makefile.sub +--- groff-1.22.3.old/contrib/mm/Makefile.sub 2014-11-04 10:38:35.488520709 +0200 ++++ groff-1.22.3/contrib/mm/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,95 +0,0 @@ +-# Copyright 1991-2014 Free Software Foundation, Inc. +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.sub +-# +-# +-PROG=mmroff +-MAN1=\ +- mmroff.n +-MAN7=\ +- groff_mm.n \ +- groff_mmse.n +-FILES=0.MT 5.MT 4.MT ms.cov se_ms.cov +-# Local configuration files with default values. +-LOCALE=locale se_locale +-MOSTLYCLEANADD=temp +-RM=rm -f +- +-all: mmroff +- +-install_bin: install_mmroff +- +-install_data: install_m +- -test -d $(DESTDIR)$(tmacdir)/mm \ +- || $(mkinstalldirs) $(DESTDIR)$(tmacdir)/mm +- for f in $(FILES); do \ +- $(RM) $(DESTDIR)$(tmacdir)/mm/$$f; \ +- $(INSTALL_DATA) $(srcdir)/mm/$$f $(DESTDIR)$(tmacdir)/mm/$$f; \ +- done +- for f in $(LOCALE); do \ +- test -f $(DESTDIR)$(tmacdir)/mm/$$f \ +- || touch $(DESTDIR)$(tmacdir)/mm/$$f; \ +- done +- $(INSTALL_DATA) $(srcdir)/refer-mm.tmac \ +- $(DESTDIR)$(tmacdir)/refer-mm.tmac +- +-install_m: +- -test -d $(DESTDIR)$(tmacdir) || $(mkinstalldirs) $(DESTDIR)$(tmacdir) +- $(RM) $(DESTDIR)$(tmacdir)/tmac.$(tmac_m_prefix)m +- $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)m.tmac +- $(INSTALL_DATA) $(srcdir)/m.tmac \ +- $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)m.tmac +- @sed -e "s;^.mso m.tmac;.mso $(tmac_m_prefix)m.tmac;g" \ +- $(srcdir)/mse.tmac > $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mse.tmac +- @sed -e "s;^.mso mse.tmac;.mso $(tmac_m_prefix)mse.tmac;g" \ +- $(srcdir)/mmse.tmac > $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mmse.tmac +- @sed -e "s;^.mso m.tmac;.mso $(tmac_m_prefix)m.tmac;g" \ +- $(srcdir)/mm.tmac > $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mm.tmac +- +-install_mmroff: mmroff +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/mmroff +- $(INSTALL_SCRIPT) mmroff $(DESTDIR)$(bindir)/mmroff +- +-mmroff: mmroff.pl +- sed -e 's;/usr/bin/perl;$(PERL);' $(srcdir)/mmroff.pl >$@ +- chmod +x $@ +- +-uninstall_sub: +- -for f in $(FILES); do $(RM) $(DESTDIR)$(tmacdir)/mm/$$f; done +- -for f in $(LOCALE); do \ +- test -s $(DESTDIR)$(tmacdir)/mm/$$f \ +- || $(RM) $(DESTDIR)$(tmacdir)/mm/$$f; \ +- done +- $(RM) $(DESTDIR)$(tmacdir)/tmac.$(tmac_m_prefix)m +- $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)m.tmac +- $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mm.tmac +- $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mse.tmac +- $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mmse.tmac +- $(RM) $(DESTDIR)$(tmacdir)/refer-mm.tmac +- -test -d $(DESTDIR)$(tmacdir)/mm && \ +- rmdir $(DESTDIR)$(tmacdir)/mm +- $(RM) $(DESTDIR)$(bindir)/mmroff +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/contrib/mm/mm.am groff-1.22.3/contrib/mm/mm.am +--- groff-1.22.3.old/contrib/mm/mm.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/mm/mm.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,106 @@ ++# Copyright 1991-2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++# mm.am ++# ++ ++mm_srcdir = $(top_srcdir)/contrib/mm ++mm_builddir = $(top_builddir)/contrib/mm ++ ++bin_SCRIPTS += mmroff ++ ++man1_MANS += contrib/mm/mmroff.n ++man7_MANS += \ ++ contrib/mm/groff_mm.n \ ++ contrib/mm/groff_mmse.n ++ ++# Files installed in $(tmacdir)/mm ++MMFILES = \ ++ contrib/mm/mm/0.MT \ ++ contrib/mm/mm/5.MT \ ++ contrib/mm/mm/4.MT \ ++ contrib/mm/mm/ms.cov \ ++ contrib/mm/mm/se_ms.cov ++mmdir = $(tmacdir)/mm ++dist_mm_DATA = $(MMFILES) ++ ++# Files installed in $(tmacdir) ++tmacmmdir = $(tmacdir) ++dist_tmacmm_DATA = contrib/mm/refer-mm.tmac ++ ++# Local configuration files with default values. ++MMLOCALE = \ ++ locale \ ++ se_locale ++ ++EXTRA_DIST += \ ++ contrib/mm/ChangeLog \ ++ contrib/mm/examples \ ++ contrib/mm/Makefile.sim \ ++ contrib/mm/mm \ ++ contrib/mm/NOTES \ ++ contrib/mm/README \ ++ contrib/mm/groff_mm.man \ ++ contrib/mm/groff_mmse.man \ ++ contrib/mm/mmroff.man \ ++ contrib/mm/mmroff.pl ++ ++mmroff: $(mm_srcdir)/mmroff.pl ++ sed -e 's;/usr/bin/perl;$(PERL);' $(mm_srcdir)/mmroff.pl >$@ ++ chmod +x $@ ++ ++# Special installation rules for m.tmac, mse.tmac, mmse.tmac, mm.tmac ++# and MMLOCALE ++install-data-local: install_mm ++install_mm: ++ -test -d $(DESTDIR)$(tmacdir) || $(mkinstalldirs) $(DESTDIR)$(tmacdir) ++ -test -d $(DESTDIR)$(mmdir) || $(mkinstalldirs) $(DESTDIR)$(mmdir) ++ $(RM) $(DESTDIR)$(tmacdir)/tmac.$(tmac_m_prefix)m ++ $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)m.tmac ++ $(INSTALL_DATA) $(mm_srcdir)/m.tmac \ ++ $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)m.tmac ++ sed -e "s;^.mso m.tmac;.mso $(tmac_m_prefix)m.tmac;g" \ ++ $(mm_srcdir)/mse.tmac > $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mse.tmac ++ @sed -e "s;^.mso mse.tmac;.mso $(tmac_m_prefix)mse.tmac;g" \ ++ $(mm_srcdir)/mmse.tmac > $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mmse.tmac ++ @sed -e "s;^.mso m.tmac;.mso $(tmac_m_prefix)m.tmac;g" \ ++ $(mm_srcdir)/mm.tmac > $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mm.tmac ++ @for f in $(MMLOCALE); do \ ++ test -f $(DESTDIR)$(tmacdir)/mm/$$f \ ++ || touch $(DESTDIR)$(tmacdir)/mm/$$f; \ ++ done ++uninstall-local: uninstall_mm ++uninstall_mm: ++ -for f in $(MMLOCALE); do \ ++ test -s $(DESTDIR)$(tmacdir)/mm/$$f \ ++ || $(RM) $(DESTDIR)$(tmacdir)/mm/$$f; \ ++ done ++ $(RM) $(DESTDIR)$(tmacdir)/tmac.$(tmac_m_prefix)m ++ $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)m.tmac ++ $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mm.tmac ++ $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mse.tmac ++ $(RM) $(DESTDIR)$(tmacdir)/$(tmac_m_prefix)mmse.tmac ++ -rmdir $(DESTDIR)$(tmacdir)/mm ++ ++# Special distribution rule: we copy all .tmac files from contrib/mm ++dist-hook: dist_mm ++dist_mm: ++ chmod u+w $(distdir)/contrib/mm/ ++ for i in $(mm_srcdir)/*.tmac; do \ ++ cp -f $$i $(distdir)/contrib/mm/; \ ++ done +diff -Nuar groff-1.22.3.old/contrib/mm/mmroff.man groff-1.22.3/contrib/mm/mmroff.man +--- groff-1.22.3.old/contrib/mm/mmroff.man 2014-11-04 10:38:35.488520709 +0200 ++++ groff-1.22.3/contrib/mm/mmroff.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -69,7 +69,7 @@ + .B \-x + Just create the cross reference file. + . +-This can be used to refresh the cross reference file, it isn\[aq]t ++This can be used to refresh the cross reference file, it isn\(aqt + always needed to have accurate cross references and by using this + option + .B groff +diff -Nuar groff-1.22.3.old/contrib/mom/BUGS groff-1.22.3/contrib/mom/BUGS +--- groff-1.22.3.old/contrib/mom/BUGS 2014-11-04 10:38:35.502520534 +0200 ++++ groff-1.22.3/contrib/mom/BUGS 2015-04-23 20:57:03.000000000 +0300 +@@ -1,5 +1,5 @@ + -*- text -*- +- Copyright 2004-2014 Free Software Foundation, Inc. ++ Copyright 2004-2015 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright +@@ -22,6 +22,40 @@ + + ==================================================================== + ++Version 2.1 ++=========== ++PDF_IMAGE and FLOAT environments conflicting. ++---Fixed--- ++ ++DROPCAP picking up color from last call to .gcolor. ++---Fixed--- ++ ++PAD not working properly with mom's indent macros. ++---Fixed--- ++ ++Margin notes not respecting differing recto-verso margins. ++---Fixed--- ++ ++Graphical object macros not clearing fill/no-fill registers and ++modes. ++---Fixed--- ++ ++LIST ALPHA emitting a number register to output. ++---Fixed--- ++ ++HEADER_PLAIN and FOOTER_PLAIN broken. ++---Fixed--- ++ ++Version 2.0-c_1 ++=============== ++ ++.TS with no H causing FN_OVERFLOW warning when there are footnotes ++on same page. ++---Fixed--- ++ ++PDF_TARGET "descriptive text" not printing. ++---Fixed--- ++ + Version 2.0-c + ============= + +diff -Nuar groff-1.22.3.old/contrib/mom/ChangeLog groff-1.22.3/contrib/mom/ChangeLog +--- groff-1.22.3.old/contrib/mom/ChangeLog 2014-11-04 10:38:35.502520534 +0200 ++++ groff-1.22.3/contrib/mom/ChangeLog 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,54 @@ ++* Fri Apr 4 2015 ++ ++ o groff_mom.man: Make it work in compatibility mode. ++ ++* Sat Feb 28 2015 ++ ++ o Added an ADJUST argument to QUOTE and BLOCKQUOTE to facilitate ++ optical centering tweaks ++ ++* Sat Feb 21 2015 ++ ++ o Expanded scope of _STYLE macros to headers/footers and ++ page numbers ++ ++* Thu Feb 5 2015 ++ ++ o Version 2.1 release (see NEWS) ++ ++ o overhaul of control macro handling ++ ++ o overhaul of cover and docheader management ++ ++ o general code cleanup to remove redundancies and reduce size of ++ om.tmac ++ ++ o changes to example files to demonstrate new features ++ ++ o copyrights updated in all files ++ ++* Tue Jan 14 2015 ++ ++ o Added a new example in French, mon_premier_doc.mom ++ ++ o Added README-fr.txt, a translation in French of the README.txt file ++ ++ o Makefile.sub: generation of mon_premier_doc.mom, installation of ++ README-fr.txt ++ ++* Sun Nov 30 2014 ++ ++ o Added auto underscoring, caps, and color to TOC header ++ (first-page titles) ++ ++ o Added vertical page positioning control macros for TOC and ++ ENDNOTES headers (first-page titles) ++ ++* Tue Nov 25 2014 ++ ++ o Tweak so collated, non-chapter docs with the same author ++ don't require .AUTHOR "" to skip printing author in docheader ++ + * Wed Oct 29 2014 + + o Makefile.sub: KFLAG to run pdfmom with -k +diff -Nuar groff-1.22.3.old/contrib/mom/copyright groff-1.22.3/contrib/mom/copyright +--- groff-1.22.3.old/contrib/mom/copyright 2014-11-04 10:38:35.502520534 +0200 ++++ groff-1.22.3/contrib/mom/copyright 2015-04-23 20:57:03.000000000 +0300 +@@ -9,7 +9,7 @@ + ======================================================================== + + The groff macro file om.tmac and the html documentation pertaining to +-it are Copyright (C) 2004-2014 Peter Schaffter. ++it are Copyright (C) 2004-2015 Peter Schaffter. + + om.tmac is issued under the GNU General Public License, a full copy of + which can be had at +diff -Nuar groff-1.22.3.old/contrib/mom/examples/.gitignore groff-1.22.3/contrib/mom/examples/.gitignore +--- groff-1.22.3.old/contrib/mom/examples/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/mom/examples/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,2 @@ ++*.ps ++stamp +\ Dosya sonunda yenisatır yok. +diff -Nuar groff-1.22.3.old/contrib/mom/examples/letter.mom groff-1.22.3/contrib/mom/examples/letter.mom +--- groff-1.22.3.old/contrib/mom/examples/letter.mom 2014-11-04 10:38:35.606519234 +0200 ++++ groff-1.22.3/contrib/mom/examples/letter.mom 2015-04-23 20:57:03.000000000 +0300 +@@ -1,6 +1,6 @@ + .\" -*- mode: troff; coding: utf-8; -*- + . +-\# Copyright (C) 2004-2014 Free Software Foundation, Inc. ++\# Copyright (C) 2004-2015 Free Software Foundation, Inc. + \# + \# Copying and distribution of this file, with or without modification, + \# are permitted in any medium without royalty provided the copyright +diff -Nuar groff-1.22.3.old/contrib/mom/examples/mom-pdf.mom groff-1.22.3/contrib/mom/examples/mom-pdf.mom +--- groff-1.22.3.old/contrib/mom/examples/mom-pdf.mom 2014-11-04 10:38:35.606519234 +0200 ++++ groff-1.22.3/contrib/mom/examples/mom-pdf.mom 2015-04-23 20:57:03.000000000 +0300 +@@ -1,5 +1,5 @@ + .\" -*- nroff -*- +-.\" Copyright (C) 2012-2014 Free Software Foundation, Inc. ++.\" Copyright (C) 2012-2015 Free Software Foundation, Inc. + .\" + .\" This file is part of mom, which is part of groff, a free software + .\" project. +@@ -8,68 +8,92 @@ + .\" GNU General Public License as published by the "Free Software + \" Foundation", version\~2. + .\" +-.\" The license text is available in the internet at ++.\" The license text is available on the internet at + .\" + .\" +-.PAPER A4 ++.PAPER A4 + .\" Reference macros (metadata) + .TITLE "Producing PDFs" "with groff and mom" + .PDF_TITLE "\*[$TITLE] +-.AUTHOR "\v'-.5v'\*[UP 4p]Deri James" \ +- "\v'-.5v'\*[UP 8p]and" \ +- "\v'-.5v'\*[UP 11p]Peter Schaffter" +-.MISC "This file is part of groff." \ +- ".sp .25v" \ +- "groff is free software; you can redistribute it" \ +- "and\*[FU3]/or modify it under the terms of the GNU" \ +- "General Public License as published by the" \ +- "Free Software Foundation, either version 3" \ +- "of the License, or (at your option) any later" \ +- "version." \ +- ".sp .25v" \ +- "You should have received a copy of the GNU" \ +- "General Public License along with this program." \ +- "If not, see:" \ +- ".sp .25v" \ +- ".IL 2P" \ +- ".PDF_WWW_LINK http://www.gnu.org/licenses/" \ +- ".IQ CLEAR" +-.COPYRIGHT "20\*[BU3]1\*[BU2]2 Free Software Foundation ++.COPYRIGHT "20\*[BU3]1\*[BU2]5 Free Software Foundation ++.AUTHOR "Deri James" "\*[UP .5p]and" "Peter Schaffter" ++.\" Cover author style ++.COVER_AUTHOR_STYLE \ ++ LEAD 15 \ ++ SPACE -.5v ++.\" Docheader author style ++.AUTHOR_STYLE \ ++ LEAD 14 \ ++ SPACE -.75 + .ATTRIBUTE_STRING "" \" Don't print 'by' ++.\" + .PDF_BOOKMARKS_OPEN 2 +-.\" Cover and page header +-.COVER TITLE AUTHOR COPYRIGHT MISC +-.HEADER_LEFT "James, Schaffter" +-.\" Page, style, formatting ++.\" Formatting style, margins + .PRINTSTYLE TYPESET + .L_MARGIN 2.5c + .R_MARGIN 2.5c + .B_MARGIN 2.5c +-.\" ++.\" General defaults + .FAM H + .FT R + .PT_SIZE 10.5 + .AUTOLEAD 3 +-.PARA_INDENT 0 \" Because we're spacing paragraphs. ++.PARA_INDENT 0 \" No indent because we're spacing paragraphs. ++.\" Copyright notice ++.COVERTEXT ++.SP .5v ++.QUAD CENTER ++.HY off ++.IB 8P ++This file is part of groff. ++.SP .5v ++Groff is free software. You can redistribute it ++and\*[FU3]/or modify it under the terms of the GNU ++General Public License as published by the ++Free Software Foundation, either version 3 ++of the License, or (at your option) any later ++version. ++.SP .5v ++You should have received a copy of the GNU ++General Public License along with this program. ++If not, see: ++.SP .25v ++.PDF_WWW_LINK http://www.gnu.org/licenses/ ++.IQ CLEAR ++.HY ++.COVERTEXT end ++.\" Cover and page header ++.COVER TITLE AUTHOR COPYRIGHT COVERTEXT ++.HEADER_LEFT "James, Schaffter" + .\" + .COVER_LEAD +3.5 + .DOCHEADER_LEAD +3.5 + .\" Color for code snippets + .NEWCOLOUR dark-grey RGB #343434 + .\" Make QUOTE look like CODE +-.QUOTE_FAMILY C +-.QUOTE_FONT B +-.QUOTE_SIZE +1.5 +-.QUOTE_COLOR dark-grey +-.QUOTE_INDENT 9p +-.\" +-.CODE_FONT B +-.CODE_SIZE 115 +-.CODE_COLOR dark-grey +-.CONDENSE 87 +-.\" +-.HEADING_STYLE 1 NUMBER FONT B SIZE +1 BASELINE_ADJUST \n[.v]/5 +-.HEADING_STYLE 2 NUMBER FONT I SIZE +.25 BASELINE_ADJUST \n[.v]/5 ++.QUOTE_STYLE \ ++ FAMILY C \ ++ FONT B \ ++ SIZE +1.5 \ ++ COLOR dark-grey \ ++ INDENT 9p ++.\" ++.CODE_STYLE \ ++ FONT B \ ++ SIZE 115 \ ++ COLOR dark-grey ++.CONDENSE 87 \" Condense percentage used in COD ++.\" ++.HEADING_STYLE 1 \ ++ NUMBER \ ++ FONT B \ ++ SIZE +1 \ ++ BASELINE_ADJUST \n[.v]/5 ++.HEADING_STYLE 2 \ ++ NUMBER \ ++ FONT I \ ++ SIZE +.25 \ ++ BASELINE_ADJUST \n[.v]/5 + .\" + .FOOTNOTE_SIZE -1 + .\" Character definitions for program names, opts, etc. +@@ -119,10 +143,11 @@ + .TOC_ENTRY_STYLE 2 FONT I + .TOC_LEAD 14 + .\" +-.DOCHEADER_ADVANCE 5c \" Begin this distance down from top of page ++.DOCHEADER_ADVANCE 5c \" Begin docheader this distance down from top of page + .\" + .START + .\" ++.SP .5c + .HEADING 1 NAMED intro "Introduction" + .PP + .RW .12 +@@ -198,6 +223,7 @@ + heading for use later on when linking to it (see + .PDF_LINK internal SUFFIX ). + + If headings are being numbered, the heading number is prepended. ++.NO_SHIM off + .HEADING 2 NAMED target "Creating destination points at arbitrary locations" + .PP + Any part of a document can be a link destination, not just headings. +@@ -209,6 +235,7 @@ + \*[cod]HEADING\*[codx], \*[cod]\*[codx] is any unique name. + \*[cod]\*[codx] is optional. \*[cod]\*[codx] can now be linked + to from anywhere in the document. ++.sp 2.5p + .HEADING 2 NAMED internal "Creating internal links" + .PP + Internal links are clickable text areas that allow you to jump to +@@ -529,7 +556,7 @@ + .PP + Several features described in this manual are not available when + using \[pdfmom] with the \[-Tps] option, or when using \[pdfroff], or +-\[groff]\~\[-Tps]\~\[-mpdfmark]. ++\[groff]\~\[-Tps]\~\[-mpdfmark]: + .SP .25v + .QUAD LEFT + .HYPHENATION off +diff -Nuar groff-1.22.3.old/contrib/mom/examples/mon_premier_doc.mom groff-1.22.3/contrib/mom/examples/mon_premier_doc.mom +--- groff-1.22.3.old/contrib/mom/examples/mon_premier_doc.mom 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/mom/examples/mon_premier_doc.mom 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,133 @@ ++.\" -*- mode: troff; coding: utf-8; -*- ++\# Copyright (C) 2015 Free Software Foundation, Inc. ++\# ++\# Copying and distribution of this file, with or without modification, ++\# are permitted in any medium without royalty provided the copyright ++\# notice and this notice are preserved. ++\# ++\# A very simple document with basic elements: headings, paragraphs, ++\# lists, table of contents and clickable links. ++\# ++.TITLE "Mon Premier Document" ++.AUTHOR "Cicéron" ++.DOCTYPE DEFAULT ++.PRINTSTYLE TYPESET ++.PAPER A4 ++.DOC_COVERTITLE "Mon Premier Document" ++.DOC_COVER DOC_COVERTITLE ++.COVER TITLE AUTHOR ++.ATTRIBUTE_STRING "par" ++.TOC_HEADER_STRING "Table des matières" ++.AUTO_RELOCATE_TOC ++.HEADING_STYLE 1 NUMBER ++.HEADING_STYLE 2 NUMBER ++.INDENT_FIRST_PARAS ++.START ++\# ++.HEADING 1 "Les différentes versions" ++Voir également le chapitre sur ++.PDF_LINK evolution "les évolutions" ++possibles. ++.HEADING 2 "La version originale" ++.PP ++Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non ++risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ++ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula ++massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci ++nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl ++sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, ++consequat in, pretium a, enim. Pellentesque congue. Ut in risus ++volutpat libero pharetra tempor. Cras vestibulum bibendum augue. ++Praesent egestas leo in pede. Praesent blandit odio eu enim. ++Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum ++primis in faucibus orci luctus et ultrices posuere cubilia Curae; ++Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. ++Maecenas adipiscing ante non diam sodales hendrerit. ++.PP ++Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non ++risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ++ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula ++massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci ++nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl ++sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, ++consequat in, pretium a, enim. Pellentesque congue. Ut in risus ++volutpat libero pharetra tempor. Cras vestibulum bibendum augue. ++Praesent egestas leo in pede. Praesent blandit odio eu enim. ++Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum ++primis in faucibus orci luctus et ultrices posuere cubilia Curae; ++Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. ++Maecenas adipiscing ante non diam sodales hendrerit. ++.PP ++Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non ++risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ++ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula ++massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci ++nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl ++sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, ++consequat in, pretium a, enim. Pellentesque congue. Ut in risus ++volutpat libero pharetra tempor. Cras vestibulum bibendum augue. ++Praesent egestas leo in pede. Praesent blandit odio eu enim. ++Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum ++primis in faucibus orci luctus et ultrices posuere cubilia Curae; ++Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. ++Maecenas adipiscing ante non diam sodales hendrerit. ++\# ++.HEADING 2 "La version moderne" ++.PP ++Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non ++risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ++ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula ++massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci ++nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl ++sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, ++consequat in, pretium a, enim. Pellentesque congue. Ut in risus ++volutpat libero pharetra tempor. Cras vestibulum bibendum augue. ++Praesent egestas leo in pede. Praesent blandit odio eu enim. ++Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum ++primis in faucibus orci luctus et ultrices posuere cubilia Curae; ++Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. ++Maecenas adipiscing ante non diam sodales hendrerit. ++.PP ++Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non ++risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ++ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula ++massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci ++nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl ++sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, ++consequat in, pretium a, enim. Pellentesque congue. Ut in risus ++volutpat libero pharetra tempor. Cras vestibulum bibendum augue. ++Praesent egestas leo in pede. Praesent blandit odio eu enim. ++Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum ++primis in faucibus orci luctus et ultrices posuere cubilia Curae; ++Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. ++Maecenas adipiscing ante non diam sodales hendrerit. ++\# ++.HEADING 1 NAMED evolution "Les évolutions du Lorem" ++.PP ++Trois axes de progressions sont envisageables: ++.LIST ++.SHIFT_LIST 3m ++.ITEM ++Lorem ipsum dolor sit amet. ++.ITEM ++Consectetur adipiscing elit. ++.ITEM ++.PDF_TARGET sed_non_risus ++Sed non risus. ++.LIST OFF ++Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non ++risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ++ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula ++massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci ++nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl ++sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, ++consequat in, pretium a, enim. Pellentesque congue. Ut in risus ++volutpat libero pharetra tempor. Cras vestibulum bibendum augue. ++Praesent egestas leo in pede. Praesent blandit odio eu enim. ++Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum ++primis in faucibus orci luctus et ultrices posuere cubilia Curae; ++Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. ++Maecenas adipiscing ante non diam sodales hendrerit. ++\# ++.TOC_RV_SWITCH ++.TOC +diff -Nuar groff-1.22.3.old/contrib/mom/examples/README-fr.txt groff-1.22.3/contrib/mom/examples/README-fr.txt +--- groff-1.22.3.old/contrib/mom/examples/README-fr.txt 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/mom/examples/README-fr.txt 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,111 @@ ++ -*- mode: text; coding: utf-8; -*- ++ Copyright (C) 2014-2015 Free Software Foundation, Inc. ++ ++ Copying and distribution of this file, with or without modification, ++ are permitted in any medium without royalty provided the copyright ++ notice and this notice are preserved. ++ ++======================================================================== ++ ++Les fichiers dans ce répertoire vous permettent de voir mom en pleine ++action. ++ ++Si vous avez téléchargé et décompressé une version de mom depuis sa ++page d'accueil, vous verrez qu'aucun exemple n'est accompagné du ++fichier PDF (.pdf) correspondant, comme c'est le cas sur les versions ++pré-compilées de groff, ou groff compilé à partir des sources. ++ ++Je n'ai pas inclu les PDF parce que je voulais conserver l'archive mom ++aussi petite que possible. Pour générer les PDF, traitez les fichiers ++avec pdfmom(1). ++ ++ pdfmom -k letter.mom > letter.pdf ++ pdfmom mom-pdf.mom > mom-pdf.pdf ++ pdfmom -k mon_premier_doc.mom > mon_premier_doc.pdf ++ pdfmom sample_docs.mom > sample_docs.pdf ++ pdfmom typesetting.mom > typesetting.pdf ++ ++Les fichiers ++------------ ++ ++Tous les fichiers sont configurés pour le format lettre US, exceptés ++mom-pdf.mom et mon_premier_doc.mom, qui utilisent le format A4. ++ ++***typesetting.mom** ++ ++Le fichier typesetting.mom montre l'utilisation d'éléments de ++composition typographique: tabulations, tabulations intégrées dans des ++chaînes de caractères, remplissage de lignes, texte sur plusieurs ++colonnes et différents styles d'indentation; ainsi que certaines ++subtilités et réglages précis disponibles via des macros et des ++échappements en ligne ("inline escape", des commandes insérées ++directement dans le texte, par opposition aux macros). ++ ++Comme ce fichier montre également l'utilisation d'une petite image au ++milieu d'un texte et que cette image est la mascotte favorite de tout ++le monde -- Tux, le fichier PDF de cette image, penguin.pdf, a été ++ajouté dans ce répertoire. ++ ++***sample_docs.mom*** ++ ++Le fichier sample_docs.mom montre en exemple les trois styles de ++documents apportés par les macros de formattage de document de mom, ++ansi que l'utilisation de COLLATE. Il montre également certaines ++fonctionnalités PDF de mom dont l'écriture d'une ébauche de nouvelle ++ou des liens cliquables dans une table des matières. ++ ++Le dernier exemple démontre, par un texte séparé en deux colonnes, la ++souplesse de mom pour la conception de document. ++ ++Le PRINTSTYLE de ce fichier est TYPESET et vous donne une idée du ++comportement par défaut de mom pour la composition typographique de ++document. ++ ++Si vous souhaitez voir comment mom traite le même fichier quand ++PRINTSTYLE est TYPEWRITE (c'est-à-dire dactylographié, avec espace ++double) remplacez .PRINTSTYLE TYPESET par .PRINTSTYLE TYPEWRITE au ++début du fichier. ++ ++***letter.mom*** ++ ++Ceci est simplement l'exemple du tutorial de momdocs, prêt à être vu. ++ ++***mon_premier_doc.mom*** ++ ++Le fichier mon_premier_doc.mom est un exemple simple en français ++montrant l'utilisation d'éléments de formattage courants: titres de ++section, paragraphes, listes, table des matières et liens PDF ++cliquables. Il doit être généré avec l'option -k du fait de la ++présence de caractères accentués. ++ ++Un certain nombre de réglages ont également été changés pour ce ++document en français: ATTRIBUTE_STRING est utilisé pour remplacer ++"by" par "par" en tête de document (là où le titre et l'auteur sont ++affichés). TOC_HEADER_STRING sert à modifier le titre de la table des ++matières en "Table des matières" plutôt que "Table of Content". Enfin, ++le paramètre de configuration INDENT_FIRST_PARAS est activé afin ++d'indenter le premier paragraphe de chaque section -- ceci est l'usage ++en typographie française. ++ ++***mom-pdf.mom*** ++ ++Le manuel "Producing PDFs with mom and groff". ++ ++***mom.vim*** ++ ++Les règles de coloration syntaxique vim sont baséés sur celles ++fournies par Christian V. J. Brüssow (cvjb@cvjb.de). Copiez le fichier ++mom.vim dans votre répertoire ~/.vim/syntax directory; ensuite, ++autorisez la coloration syntaxique si ce n'est pas encore le cas: ++ ++ :syntax enable ++ou ++ :syntax on ++ ++***elvis_syntax.new*** ++ ++Ceux qui utilisent elvis, le clone de vi, peuvent directement ++copier-coller le contenu de ce fichier dans leur elvis.syn. Tous les ++fichiers ayant l'extension .mom auront la coloration syntaxique. Les ++règles dans elvis_syntax ne sont pas exhaustive, mais aideront ++beaucoup à rendre les fichiers mom plus lisibles. +diff -Nuar groff-1.22.3.old/contrib/mom/examples/README.txt groff-1.22.3/contrib/mom/examples/README.txt +--- groff-1.22.3.old/contrib/mom/examples/README.txt 2014-11-04 10:38:35.606519234 +0200 ++++ groff-1.22.3/contrib/mom/examples/README.txt 2015-04-23 20:57:03.000000000 +0300 +@@ -1,5 +1,5 @@ + -*- text -*- +- Copyright (C) 2004-2014 Free Software Foundation, Inc. ++ Copyright (C) 2004-2015 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, + are permitted in any medium without royalty provided the copyright +@@ -18,16 +18,17 @@ + archive as lean as possible. To view the PDF output, process the + files with pdfmom(1). + +- pdfmom letter.mom > letter.pdf ++ pdfmom -k letter.mom > letter.pdf + pdfmom mom-pdf.mom > mom-pdf.pdf ++ pdfmom -k mon_premier_doc.mom > mon_premier_doc.pdf + pdfmom sample_docs.mom > sample_docs.pdf + pdfmom typesetting.mom > typesetting.pdf + + The files themselves + -------------------- + +-All are set up for US letter papersize except mom-pdf.mom, which +-uses A4. ++All are set up for US letter papersize except mom-pdf.mom and ++mon_premier_doc.mom, which uses A4. + + ***typesetting.mom** + +@@ -64,6 +65,21 @@ + This is just the tutorial example from the momdocs, ready for + previewing. + ++***mon_premier_doc.mom*** ++ ++The file, mon_premier_doc.mom, is a simple example in French showing ++the use of common elements: section headings, paragraphs, lists, table ++of contents and clickable links. It should be generated with option -k ++as there are some accented letters. ++ ++A few settings were also changed for this French document: ++ATTRIBUTE_STRING is used to replace "by" by "par" in the document ++header (where the title and the author are displayed). ++TOC_HEADER_STRING is used to modity the Table of Content title to ++"Table des matires". And finally, INDENT_FIRST_PARAS is used to ++indent the first paragraph of a section -- this is the usual ++convention in French typesetting. ++ + ***mom-pdf.mom*** + + The manual, Producing PDFs with mom and groff. +diff -Nuar groff-1.22.3.old/contrib/mom/examples/sample_docs.mom groff-1.22.3/contrib/mom/examples/sample_docs.mom +--- groff-1.22.3.old/contrib/mom/examples/sample_docs.mom 2014-11-04 10:38:35.607519221 +0200 ++++ groff-1.22.3/contrib/mom/examples/sample_docs.mom 2015-04-23 20:57:03.000000000 +0300 +@@ -1,4 +1,4 @@ +-\# Copyright (C) 2004-2014 Free Software Foundation, Inc. ++\# Copyright (C) 2004-2015 Free Software Foundation, Inc. + \# + \# Copying and distribution of this file, with or without modification, + \# are permitted in any medium without royalty provided the copyright +@@ -31,43 +31,102 @@ + \# subheads and paraheads. I've turned the feature on merely to + \# demonstrate it. + \# +-\# Reference macros (metadata) ++\# Information for the cover pages ++\# ++\# Title, subtitle and copyright for the document cover. ++\# ++.TITLE DOC_COVER \ ++ "Sample mom Documents" ++.SUBTITLE DOC_COVER \ ++ "Three types of mom documents" \ ++ "assembled and collated" \ ++ "by mom's author" ++.COPYRIGHT DOC_COVER \ ++ "2015 Peter Schaffter" ++\# ++\# What appears in the pdf viewer's window title ++\# ++.PDF_TITLE "Sample mom documents" ++\# ++\# Reference macros (metadata) for the first section of the collated ++\# document. + \# + .TITLE "Lake Attica's Shores" + .SUBTITLE "A Romance Novel" + .AUTHOR "Rosemary Winspeare" +-.COPYRIGHT "2004 Alma Podborski" +-.PDF_TITLE "Sample mom documents" ++.COPYRIGHT "2015 Alma Podborski" ++\# ++\# What to put on the cover for the whole document (in mom-speak, ++\# the "doc cover"). The title, subtitle, and author are what were ++\# given to TITLE DOC_COVER, SUBTITLE DOC_COVER, and COPYRIGHT ++\# DOC_COVER. + \# +-\# Additional information, for the cover ++.DOC_COVER TITLE SUBTITLE COPYRIGHT + \# +-.DOC_COVERTITLE "Sample mom Documents" +-.MISC "Three types of mom documents" "assembled and collated by mom's author" ++\# What to put on the first document's title page (in mom-speak, the ++\# "cover"). In this case, we're using the metadata from TITLE, ++\# SUBTITLE, AUTHOR and COPYRIGHT, which will also be used to ++\# generate the docheader (minus the copyright). ++\# ++.COVER TITLE AUTHOR DOCTYPE COPYRIGHT + \# + \# Docstyle macros (templates) + \# + .DOCTYPE NAMED "Outline" +-.PRINTSTYLE TYPESET \" Or TYPEWRITE to preview "typewritten, double-spaced" ++.PRINTSTYLE TYPESET + .PAPER LETTER + \# +-\# What to put on the cover and first title page ++\# Here we style the covers a bit. ++\# ++.DOC_COVER_TITLE_STYLE \ ++ SIZE +8 \ ++ SMALLCAPS \ ++ UNDERLINE 1 3p ++.DOC_COVER_SUBTITLE_STYLE \ ++ FONT I \ ++ SIZE +3 \ ++ LEAD 18 \ ++ SPACE .5v ++.DOC_COVER_COPYRIGHT_SIZE +.5 ++\# ++.COVER_TITLE_SIZE +5 ++.COVER_ATTRIBUTE_STYLE \ ++ SIZE +2 \ ++ SPACE .25v ++.COVER_AUTHOR_STYLE \ ++ SIZE +2 \ ++ LEAD 18 ++.COVER_DOCTYPE_STYLE \ ++ SIZE +4 \ ++ UNDERLINE DOUBLE 1 ++.COVER_COPYRIGHT_SIZE +.5 + \# +-.DOC_COVER DOC_COVERTITLE MISC +-.COVER TITLE AUTHOR DOCTYPE COPYRIGHT ++\# Here we style the docheader a bit. + \# +-\# Style for nested heading levels ++.SUBTITLE_SPACE .25v ++.DOCTYPE_UNDERLINE 1 2p ++\# ++\# Styles for nested heading levels + \# + \# The first two instances of level-1 headings will be paragraph heads + \# so we set the paragraph head style here, then change it when + \# level-1 headings become main heads. + \# +-.HEADING_STYLE 1 FONT BI SIZE +.25 +-.HEADING_STYLE 2 FONT B SIZE +.5 BASELINE_ADJUST \n[.v]/8 \" ie 1/8 the leading ++.HEADING_STYLE 1 \ ++ FONT BI \ ++ SIZE +.75 ++.HEADING_STYLE 2 \ ++ FONT B \ ++ SIZE +.5 \ ++ BASELINE_ADJUST \n[.v]/8 \" ie 1/8 the leading ++\# ++.AUTO_RELOCATE_TOC \" Move table of contents to the top of the doc ++.SPACE_TOC_ITEMS \" Prettify TOC spacing + \# +-.AUTO_RELOCATE_TOC +-.SPACE_TOC_ITEMS ++\# Begin the document + \# + .START ++\# + .PP + .HEADING 1 PARAHEAD "A note on the setting" + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +@@ -99,8 +158,15 @@ + \# + \# Change level-1 style and add numbering to levels 1 and 2 + \# +-.HEADING_STYLE 1 FONT B SIZE +1.5 CAPS UNDERSCORE .5 2p QUAD C \ +- NO_SPACE_AFTER BASELINE_ADJUST +0 NUMBER ++.HEADING_STYLE 1 \ ++ FONT B \ ++ SIZE +1.5 \ ++ CAPS \ ++ UNDERSCORE .5 2p \ ++ QUAD C \ ++ NO_SPACE_AFTER \ ++ BASELINE_ADJUST +0 \ ++ NUMBER + .HEADING_STYLE 2 NUMBER + \# + .HEADING 1 "Part One" +@@ -168,32 +234,30 @@ + .PP + At vero eos et accusam et justo duo do\%lo\%res et ea rebum. Stet clita + kasd gubergren. Sea takimata sanctus est lorem ipsum dolor +-sit amet. Accusam et justo duo do\%lo\%res et ea rebum +-.SPREAD ++sit amet. Accusam et justo duo do\%lo\%res et ea rebum. Diam ++nonumy eirmod tempor invidunt ut labore et do\%lo\%re magna. + .RIGHT + \*[BD]\&...end of sample outline\c + .EL + .COLLATE + \# +-\# The .EL after the line "...end of sample outline" ensures that +-\# mom doesn't spring the page trap, which would deposit a header at +-\# the top of the next page. COLLATE doesn't print a page header +-\# on the first page of a collated document, but if the page trap +-\# has already deposited one there, COLLATE can't undo it. +-\# +-\# Normally, this isn't necessary; here we require it because the +-\# line falls right at the bottom of the page. +-\# +-\# Please notice, too, the use of "\&" before "..." Whenever an +-\# input line begins with either a period, an apostrophe or a space, +-\# you must precede it with \&, otherwise the line will disappear, +-\# even when, as here, there's an inline escape that starts the +-\# line. ++\# The '\c /.EL' keeps mom from depositing a line break which, ++\# because "...end of sample outline" falls exactly on the last ++\# baseline of the page, would spring the page trap that sets a ++\# header at the top of the next page. Since the next page is a ++\# title page, we don't want that. Normally, this isn't required, ++\# although using it routinely before COLLATE is a good habit. ++\# ++\# Notice, too, the use of "\&" before "..." Whenever an input line ++\# begins with either a period, an apostrophe or a space, you must ++\# precede it with \&, otherwise the line will disappear, even when, ++\# as here, there's an inline escape beforehand. + \# + \# ===================================================================== + \# +-\# Next, two pages of a chapter, set in DRAFT style, showing the use +-\# of the EPIGRAPH BLOCK macro and the QUOTE macro. ++\# Next, a document composed of two pages of a chapter, set in DRAFT ++\# style, showing the use of the EPIGRAPH BLOCK macro and the QUOTE ++\# macro. + \# + \# You'll notice that the starting page number of this "draft" is 1 (in + \# roman numerals). COPYSTYLE DRAFT always numbers the first page of a +@@ -214,10 +278,20 @@ + .EPIGRAPH_FONT I \" Epigraphs are normally set in roman + .DRAFT_WITH_PAGENUMBER \" Draft/revision info usually goes in the header + \# +-.COVER_MISC_FAMILY H +-.COVER_MISC_QUAD RIGHT ++\# Style the title page ++\# ++.COVER_CHAPTER_SIZE +3 ++.COVER_CHAPTER_TITLE_STYLE \ ++ SIZE +5 \ ++ SPACE .25v ++.COVER_MISC_SIZE +.5 ++\# ++\# What goes on the title page ++\# + .COVER CHAPTER+TITLE MISC + \# ++\# Begin the document ++\# + .START + .EPIGRAPH BLOCK + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam +@@ -225,7 +299,8 @@ + sed diam voluptua. + .RIGHT + \# +-\# If running PRINTSTYLE TYPEWRITE, add space before citation ++\# If running PRINTSTYLE TYPEWRITE, this adds space before ++\# attribution ("Joseph E. Blough") + \# + .if \n[#PRINT_STYLE]=1 .sp + \# +@@ -317,24 +392,45 @@ + \# create a stylesheet, along with some of the control macros that + \# can be used. + \# +-.TITLE "CONTROL EQUALS CHAOS" ++\# Style the title page ++\# ++.COVER_TITLE_CAPS ++.COVER_ATTRIBUTE_SPACE .5v ++.COVER_AUTHOR_STYLE \ ++ SIZE +1.5 \ ++ LEAD 14 \ ++ SPACE .25v ++.COVER_MISC_STYLE \ ++ QUAD L \ ++ SIZE +0 ++.COVER_COPYRIGHT_SIZE +0 ++\# ++\# What goes on the title page ++\# ++.COVER TITLE AUTHOR COPYRIGHT MISC ++\# ++.DOCTYPE DEFAULT ++.COPYSTYLE FINAL ++\# ++.TITLE "Control Equals Chaos" + .SUBTITLE "\*[ALD1]The Psychological and Auditory \ + Impact of Serial vs. Aleatoric Music\*[RLD1]" + .AUTHOR "Joe Chang" "and" "Brad Hegel Connors" +-.COPYRIGHT "2004 J. Chang, B.H. Connors +-.MISC "Submitted June 3, 2004" "\*[IT]Piano Quarterly\*[PREV]" ++.COPYRIGHT "2015 J. Chang, B.H. Connors ++.MISC "Submitted June 3, 2015" "\*[IT]Piano Quarterly\*[PREV]" + \# +-.DOCTYPE DEFAULT +-.COPYSTYLE FINAL ++\# Style the docheader ++\# ++.TITLE_CAPS ++.ATTRIBUTE_SPACE .33 ++.AUTHOR_SIZE +1 ++.SUBTITLE_SIZE +2 + \# + .L_MARGIN 6P + .R_MARGIN 4P+6p + .PT_SIZE 10 + .AUTOLEAD 1.5 + \# +-.AUTHOR_SIZE +.5 +-.SUBTITLE_SIZE +1 +-\# + .RECTO_VERSO + .PAGENUM 1 + \# +@@ -350,27 +446,30 @@ + .if \n[#PRINT_STYLE]=2 \{\ + . PARA_INDENT 1P + . QUOTE_INDENT 2 ++. BLOCKQUOTE_INDENT 2 + .\} + \# +-.HEADING_STYLE 1 QUAD L SIZE +0 NO_NUMBER NO_CAPS NO_UNDERSCORE \ +- NO_SPACE_AFTER BASELINE_ADJUST \n[.v]/8 \" ie 1/8 of the leading ++\# Style heading 1 + \# +-.BLOCKQUOTE_FAMILY H +-.BLOCKQUOTE_SIZE -2 +-.BLOCKQUOTE_AUTOLEAD 2 +-\# +-.COVERTITLE "\*[UP 3p]\E*[$TITLE]" \" Use $TITLE, but raise 3 points +-\# +-.COVER_LEAD +2 +-.COVER_AUTHOR_SIZE +1.5 +-.COVER_MISC_FAMILY T +-.COVER_MISC_QUAD L +-.COVER_MISC_SIZE +0 +-.COVER_COPYRIGHT_SIZE +0 ++.HEADING_STYLE 1 \ ++ QUAD L \ ++ SIZE +0 \ ++ NO_NUMBER \ ++ NO_CAPS \ ++ NO_UNDERSCORE \ ++ NO_SPACE_AFTER \ ++ BASELINE_ADJUST \n[.v]/8 \" ie 1/8 of the leading ++\# ++\# Style the blockquotes ++\# ++.BLOCKQUOTE_STYLE \ ++ FAMILY H \ ++ SIZE -2 \ ++ AUTOLEAD 2 + \# +-.COVER COVERTITLE AUTHOR COPYRIGHT MISC ++.COLUMNS 2 1P+6p \" Set in two columns + \# +-.COLUMNS 2 1P+6p ++\# Being the document + \# + .START + .PP +@@ -384,6 +483,7 @@ + invidunt ut labore et do\%lo\%re magna ali\%quyam erat. Sed diam voluptua + at vero eos et accusam et justo. + \# ++.if \n[#PRINT_STYLE]=2 .sp 1p \" A little tweak + .BLOCKQUOTE + Stet clita kasd gubergren, no sea takimata sanctus est lorem. + Ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy +diff -Nuar groff-1.22.3.old/contrib/mom/examples/typesetting.mom groff-1.22.3/contrib/mom/examples/typesetting.mom +--- groff-1.22.3.old/contrib/mom/examples/typesetting.mom 2014-11-04 10:38:35.607519221 +0200 ++++ groff-1.22.3/contrib/mom/examples/typesetting.mom 2015-04-23 20:57:03.000000000 +0300 +@@ -310,7 +310,7 @@ + simple enumerated lists. Nested lists are possible, as the example + shows; however, the more complex the nesting, the wiser it becomes + to use (string) tabs, as seen in Example 4. +-.RLD .25v \" Move upwards 1/2 linespace ++.RLD .5v \" Move upwards 1/2 linespace + .DBX .5 0 \n[.l]u 2P+9p \" Draw box; \n[.l]u means "the current line length" + .IB 6p \" Indent from both left and right margins + .ALD 14p +diff -Nuar groff-1.22.3.old/contrib/mom/.gitignore groff-1.22.3/contrib/mom/.gitignore +--- groff-1.22.3.old/contrib/mom/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/mom/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,4 @@ ++groff_mom.n ++penguin.ps ++stamp-strip ++om.tmac-s +diff -Nuar groff-1.22.3.old/contrib/mom/groff_mom.man groff-1.22.3/contrib/mom/groff_mom.man +--- groff-1.22.3.old/contrib/mom/groff_mom.man 2014-11-04 10:38:35.502520534 +0200 ++++ groff-1.22.3/contrib/mom/groff_mom.man 2015-04-23 20:57:03.000000000 +0300 +@@ -4,6 +4,11 @@ + . + .\" The .SH was moved to this place in order to appease `apropos'. + . ++. ++.do nr groff_mom_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" Legalese + .\" -------------------------------------------------------------------- +@@ -80,9 +85,6 @@ + .. + . + . +-.do nr groff_mom_C \n[.C] +-.cp 0 +-. + .de TQ + .br + .ns +diff -Nuar groff-1.22.3.old/contrib/mom/Makefile.sub groff-1.22.3/contrib/mom/Makefile.sub +--- groff-1.22.3.old/contrib/mom/Makefile.sub 2014-11-04 10:38:35.502520534 +0200 ++++ groff-1.22.3/contrib/mom/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,230 +0,0 @@ +-# -*- makefile -*- +-# Copyright (C) 2002-2014 Free Software Foundation, Inc. +-# Written by Werner Lemberg (wl@gnu.org) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-# These may be overridden if cross-compiling. +-GROFFBIN=$(top_builddir)/src/roff/groff/groff +-GROFF_BIN_PATH=`echo $(groff_bin_dirs) | sed -e 's| *|$(SH_SEP)|g'` +-PDFMOMBIN=$(top_builddir)/src/devices/gropdf/pdfmom +- +-groff_bin_dirs=\ +- $(top_builddir)/src/roff/groff \ +- $(top_builddir)/src/roff/troff \ +- $(top_builddir)/src/devices/grops \ +- $(top_builddir)/src/devices/gropdf +- +-FFLAG=-F$(top_builddir)/font -F$(top_srcdir)/font +-TFLAG=-M$(top_builddir)/tmac -M$(top_srcdir)/tmac -M$(srcdir) +-KFLAG=-k +- +-GROFF=\ +- GROFF_COMMAND_PREFIX= \ +- GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ +- $(GROFFBIN) $(FFLAG) $(TFLAG) +- +-PDFMOM=\ +- GROFF_COMMAND_PREFIX= \ +- GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ +- PDFMOM_BIN_PATH="$(top_builddir)/src/devices/gropdf" \ +- $(PDFMOMBIN) $(FFLAG) $(TFLAG) $(KFLAG) +- +-MAN7=\ +- groff_mom.n +- +-NORMALFILES=\ +- mom.tmac +- +-# These files are processed with `strip.sed'. +-STRIPFILES=\ +- om.tmac +- +-HTMLDOCFILES=\ +- momdoc/stylesheet.css \ +- momdoc/appendices.html \ +- momdoc/color.html \ +- momdoc/cover.html \ +- momdoc/definitions.html \ +- momdoc/docelement.html \ +- momdoc/docprocessing.html \ +- momdoc/goodies.html \ +- momdoc/graphical.html \ +- momdoc/headfootpage.html \ +- momdoc/images.html \ +- momdoc/inlines.html \ +- momdoc/intro.html \ +- momdoc/letters.html \ +- momdoc/macrolist.html \ +- momdoc/rectoverso.html \ +- momdoc/refer.html \ +- momdoc/reserved.html \ +- momdoc/tables-of-contents.html \ +- momdoc/toc.html \ +- momdoc/typesetting.html \ +- momdoc/using.html \ +- momdoc/version-2.html +- +-EXAMPLEFILES=\ +- examples/letter.mom \ +- examples/mom-pdf.mom \ +- examples/sample_docs.mom \ +- examples/typesetting.mom \ +- examples/README.txt \ +- examples/elvis_syntax \ +- examples/elvis_syntax.new \ +- examples/penguin.ps \ +- examples/penguin.pdf \ +- examples/mom.vim +- +-PROCESSEDEXAMPLEFILES=\ +- examples/letter.pdf \ +- examples/mom-pdf.pdf \ +- examples/sample_docs.pdf \ +- examples/typesetting.pdf +- +-HTMLDOCFILES_=`echo $(HTMLDOCFILES) | sed 's|momdoc/||g'` +-EXAMPLEFILES_=`echo $(EXAMPLEFILES) | sed 's|examples/||g'` +-PROCESSEDEXAMPLEFILES_=`echo $(PROCESSEDEXAMPLEFILES) | sed 's|examples/||g'` +-PDFDOCFILE=mom-pdf.pdf +- +-MOSTLYCLEANADD=\ +- stamp-strip \ +- penguin.ps \ +- penguin.pdf \ +- $(PROCESSEDEXAMPLEFILES) \ +- examples/stamp \ +- om.tmac-s +- +-RM=rm -f +- +-#.SUFFIXES: .mom .ps +-#.mom.ps: +-# $(GROFF) -Tps -mom $< >$@ +- +-.SUFFIXES: .mom .pdf +-.mom.pdf: +- LC_ALL=C $(PDFMOM) $< >$@ +- +-all: stamp-strip $(make_pdfexamples) +- +-$(PROCESSEDEXAMPLEFILES): penguin.ps penguin.pdf examples/stamp +- +-pdfexamples: $(PROCESSEDEXAMPLEFILES) +- +-penguin.ps: +- cp $(srcdir)/examples/penguin.ps . +-penguin.pdf: +- cp $(srcdir)/examples/penguin.pdf . +- +-examples/stamp: +- -test -d examples || $(mkinstalldirs) examples +- touch $@ +- +-install_data: install_always \ +- $(make_install_pdfdoc) $(make_install_shipped_htmldoc) \ +- $(make_install_examples) +- +-install_always: stamp-strip $(NORMALFILES) +- -test -d $(DESTDIR)$(tmacdir) || $(mkinstalldirs) $(DESTDIR)$(tmacdir) +- for f in $(NORMALFILES); do \ +- $(RM) $(DESTDIR)$(tmacdir)/$$f; \ +- $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(tmacdir)/$$f; \ +- done +- for f in $(STRIPFILES); do \ +- $(RM) $(DESTDIR)$(tmacdir)/$$f; \ +- $(INSTALL_DATA) $$f-s $(DESTDIR)$(tmacdir)/$$f; \ +- done +- +-install_pdfdoc: +-# Since this uses examples/, it's in install_pdfexamples +- +-install_shipped_htmldoc: install_always $(HTMLDOCFILES) +- -test -d $(DESTDIR)$(htmldocdir)/mom \ +- || $(mkinstalldirs) $(DESTDIR)$(htmldocdir)/mom +- for f in $(HTMLDOCFILES_); do \ +- $(RM) $(DESTDIR)$(htmldocdir)/mom/$$f; \ +- $(INSTALL_DATA) $(srcdir)/momdoc/$$f \ +- $(DESTDIR)$(htmldocdir)/mom/$$f; \ +- done +- +- +-install_examples: install_examples_always $(make_install_pdfexamples) +- +-install_examples_always: $(EXAMPLEFILES) +- -test -d $(DESTDIR)$(exampledir)/mom \ +- || $(mkinstalldirs) $(DESTDIR)$(exampledir)/mom +- for f in $(EXAMPLEFILES_); do \ +- $(RM) $(DESTDIR)$(exampledir)/mom/$$f; \ +- $(INSTALL_DATA) $(srcdir)/examples/$$f \ +- $(DESTDIR)$(exampledir)/mom/$$f; \ +- done +- +-install_pdfexamples: install_examples_always $(PROCESSEDEXAMPLEFILES) +- for f in $(PROCESSEDEXAMPLEFILES_); do \ +- $(RM) $(DESTDIR)$(exampledir)/mom/$$f; \ +- $(INSTALL_DATA) examples/$$f $(DESTDIR)$(exampledir)/mom/$$f; \ +- done +- -test -d $(DESTDIR)$(pdfdocdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(pdfdocdir) +- for f in $(PDFDOCFILE); do \ +- $(RM) $(DESTDIR)$(pdfdocdir)/$$f; \ +- ln -s $(exampledir)/mom/$$f $(DESTDIR)$(pdfdocdir)/$$f; \ +- done +- +-stamp-strip: $(STRIPFILES) +- for f in $(STRIPFILES); do \ +- $(RM) $$f-s; \ +- LANG=C LC_ALL=C \ +- sed -f $(top_srcdir)/tmac/strip.sed $(srcdir)/$$f >$$f-s; \ +- done +- touch $@ +- +-uninstall_sub: uninstall_always \ +- $(make_uninstall_pdfdoc) $(make_uninstall_shipped_htmldoc) \ +- $(make_uninstall_examples) +- +-uninstall_always: +- -for f in $(NORMALFILES) $(STRIPFILES); do \ +- $(RM) $(DESTDIR)$(tmacdir)/$$f; \ +- done +- +-uninstall_pdfdoc: uninstall_always +-# Since that used examples/, it's in uninstall_pdfexamples +- +-uninstall_shipped_htmldoc: uninstall_always +- -for f in $(HTMLDOCFILES_); do \ +- $(RM) $(DESTDIR)$(htmldocdir)/mom/$$f; \ +- done +- -test -d $(DESTDIR)$(htmldocdir)/mom && \ +- rmdir $(DESTDIR)$(htmldocdir)/mom +- +-uninstall_examples: uninstall_examples_always $(make_uninstall_pdfexamples) +- -test -d $(DESTDIR)$(exampledir)/mom && \ +- rmdir $(DESTDIR)$(exampledir)/mom +- +-uninstall_examples_always: +- -for f in $(EXAMPLEFILES_); do \ +- $(RM) $(DESTDIR)$(exampledir)/mom/$$f; \ +- done +- +-uninstall_pdfexamples: uninstall_examples_always +- -for f in $(PDFDOCFILE); do \ +- $(RM) $(DESTDIR)$(pdfdocdir)/$$f; \ +- done +- -for f in $(PROCESSEDEXAMPLEFILES_); do \ +- $(RM) $(DESTDIR)$(exampledir)/mom/$$f; \ +- done +diff -Nuar groff-1.22.3.old/contrib/mom/mom.am groff-1.22.3/contrib/mom/mom.am +--- groff-1.22.3.old/contrib/mom/mom.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/contrib/mom/mom.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,168 @@ ++# Copyright (C) 2002-2014 ++# Free Software Foundation, Inc. ++# Written by Werner Lemberg (wl@gnu.org) ++# Automake migration by Bertrand Garrigues ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++mom_srcdir = $(top_srcdir)/contrib/mom ++mom_builddir = $(top_builddir)/contrib/mom ++ ++# pdfmom command used to generated .pdf ++MOM_TFLAG = -M$(mom_srcdir) -M$(mom_builddir) ++MOM_KFLAG = -k ++MOMPDFMOM = \ ++ GROFF_COMMAND_PREFIX= \ ++ GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ ++ PDFMOM_BIN_PATH="$(top_builddir)" \ ++ $(PDFMOMBIN) $(FFLAG) $(TFLAG) $(MOM_TFLAG) $(MOM_KFLAG) ++ ++man7_MANS += contrib/mom/groff_mom.n ++ ++# Files installed in $(tmacdir). ++# MOMNORMALFILES are located in the source tree. ++# om.tmac is generated in the build tree from the unstripped file om.tmac-u with ++# strip.sed ++MOMNORMALFILES = \ ++ contrib/mom/mom.tmac ++MOMSTRIPFILES = \ ++ contrib/mom/om.tmac ++momtmacdir = $(tmacdir) ++nodist_momtmac_DATA = $(MOMSTRIPFILES) ++dist_momtmac_DATA = $(MOMNORMALFILES) ++ ++# Files installed in htmldocdir/mom ++if INSTALL_SHIPPED_HTML ++MOMHTMLDOCFILES=\ ++ contrib/mom/momdoc/stylesheet.css \ ++ contrib/mom/momdoc/appendices.html \ ++ contrib/mom/momdoc/color.html \ ++ contrib/mom/momdoc/cover.html \ ++ contrib/mom/momdoc/definitions.html \ ++ contrib/mom/momdoc/docelement.html \ ++ contrib/mom/momdoc/docprocessing.html \ ++ contrib/mom/momdoc/goodies.html \ ++ contrib/mom/momdoc/graphical.html \ ++ contrib/mom/momdoc/headfootpage.html \ ++ contrib/mom/momdoc/images.html \ ++ contrib/mom/momdoc/inlines.html \ ++ contrib/mom/momdoc/intro.html \ ++ contrib/mom/momdoc/letters.html \ ++ contrib/mom/momdoc/macrolist.html \ ++ contrib/mom/momdoc/rectoverso.html \ ++ contrib/mom/momdoc/refer.html \ ++ contrib/mom/momdoc/reserved.html \ ++ contrib/mom/momdoc/tables-of-contents.html \ ++ contrib/mom/momdoc/toc.html \ ++ contrib/mom/momdoc/typesetting.html \ ++ contrib/mom/momdoc/using.html \ ++ contrib/mom/momdoc/version-2.html ++momhtmldir = $(htmldocdir)/mom ++momhtml_DATA = $(MOMHTMLDOCFILES) ++endif ++ ++# Files installed in $(examplesdir)/mom. MOMEXAMPLEFILES are located ++# in the source tree, while MOMPROCESSEDEXAMPLEFILES are generated in ++# the build tree. ++MOMEXAMPLEFILES=\ ++ contrib/mom/examples/letter.mom \ ++ contrib/mom/examples/mom-pdf.mom \ ++ contrib/mom/examples/mon_premier_doc.mom \ ++ contrib/mom/examples/sample_docs.mom \ ++ contrib/mom/examples/typesetting.mom \ ++ contrib/mom/examples/README.txt \ ++ contrib/mom/examples/README-fr.txt \ ++ contrib/mom/examples/elvis_syntax \ ++ contrib/mom/examples/elvis_syntax.new \ ++ contrib/mom/examples/penguin.ps \ ++ contrib/mom/examples/penguin.pdf \ ++ contrib/mom/examples/mom.vim ++if BUILD_EXAMPLES ++momexampledir = $(exampledir)/mom ++dist_momexample_DATA = $(MOMEXAMPLEFILES) ++else ++EXTRA_DIST += $(MOMEXAMPLEFILES) ++endif ++ ++if BUILD_PDFEXAMPLES ++MOMPROCESSEDEXAMPLEFILES = \ ++ contrib/mom/examples/letter.pdf \ ++ contrib/mom/examples/mom-pdf.pdf \ ++ contrib/mom/examples/mon_premier_doc.pdf \ ++ contrib/mom/examples/sample_docs.pdf \ ++ contrib/mom/examples/typesetting.pdf ++momprocessedexampledir = $(exampledir)/mom ++nodist_momprocessedexample_DATA = $(MOMPROCESSEDEXAMPLEFILES) ++endif ++ ++# For this list of files we add a symlink from $(exampledir)/mom to $(pdfdocdir) ++PDFDOCFILE = mom-pdf.pdf ++ ++EXTRA_DIST += $(MOMHTMLDOCFILES) $(MOMEXAMPLEFILES) \ ++ contrib/mom/BUGS \ ++ contrib/mom/ChangeLog \ ++ contrib/mom/NEWS \ ++ contrib/mom/TODO \ ++ contrib/mom/copyright \ ++ contrib/mom/groff_mom.man \ ++ contrib/mom/om.tmac-u ++ ++MOSTLYCLEANFILES += \ ++ $(MOMPROCESSEDEXAMPLEFILES) \ ++ contrib/mom/om.tmac \ ++ penguin.ps \ ++ penguin.pdf ++ ++# Rule to generated .pdf files from .mom files ++SUFFIXES += .mom .pdf ++.mom.pdf: ++ @$(MKDIR_P) `dirname $@` ++ LC_ALL=C $(MOMPDFMOM) $< >$@ ++ ++$(MOMPROCESSEDEXAMPLEFILES): $(MOMSTRIPFILES) $(MOMNORMALFILES) \ ++ groff troff gropdf pdfmom penguin.ps penguin.pdf \ ++ gnu.eps font/devpdf/build_font_files ++ ++penguin.ps: ++ cp $(mom_srcdir)/examples/penguin.ps $@ ++penguin.pdf: ++ cp $(mom_srcdir)/examples/penguin.pdf $@ ++ ++$(MOMSTRIPFILES): $(top_srcdir)/tmac/strip.sed ++ @$(MKDIR_P) `dirname $@` ++ LANG=C LC_ALL=C \ ++ sed -f $(top_srcdir)/tmac/strip.sed $(mom_srcdir)/`basename $@`-u > $@; ++ ++install-data-hook: install_mom ++install_mom: ++if BUILD_PDFEXAMPLES ++ for f in $(PDFDOCFILE); do \ ++ $(RM) $(DESTDIR)$(pdfdocdir)/$$f; \ ++ ln -s $(exampledir)/mom/$$f $(DESTDIR)$(pdfdocdir)/$$f; \ ++ done ++endif ++ ++uninstall_groffdirs: uninstall_mom ++uninstall_mom: ++ for f in $(PDFDOCFILE); do \ ++ $(RM) $(DESTDIR)$(pdfdocdir)/$$f; \ ++ done ++ if test -d $(DESTDIR)$(exampledir)/mom; then \ ++ rmdir $(DESTDIR)$(exampledir)/mom; \ ++ fi ++ if test -d $(DESTDIR)$(htmldocdir)/mom; then \ ++ rmdir $(DESTDIR)$(htmldocdir)/mom; \ ++ fi +diff -Nuar groff-1.22.3.old/contrib/mom/momdoc/appendices.html groff-1.22.3/contrib/mom/momdoc/appendices.html +--- groff-1.22.3.old/contrib/mom/momdoc/appendices.html 2014-11-04 10:38:35.612519159 +0200 ++++ groff-1.22.3/contrib/mom/momdoc/appendices.html 2015-04-23 20:57:03.000000000 +0300 +@@ -2,7 +2,7 @@ + + +
+-

COVER and DOC_COVER

++

DOC_COVER and COVER

+
+ +-
+-Macro: COVER (see required and optional arguments, below) ++
++Macro: DOC_COVER (see argument list, below) +
+ +-
+-Macro: DOC_COVER (see required and optional arguments, below) ++
++Macro: COVER (see argument list, below) +
+ +-
+-Required argument: TITLE | DOCTITLE | COVERTITLE | CHAPTER | CHAPTER_TITLE | CHAPTER+TITLE +-
+- +-
+-Optional arguments: [ SUBTITLE AUTHOR DOCTYPE COPYRIGHT MISC BLANKPAGE PDF_OUTLINE_LABEL <label> ] +-
+- +-
+-

+-Note: +-These macros should be placed in the style sheet section of your +-document setup (see +-Tutorial – Setting up a mom document), +-ie after PRINTSTYLE (and/or DOCTYPE and/or COPYSTYLE), but before +-START. +-

+-
+- +-

+-COVER and DOC_COVER behave identically. The reason mom provides ++

++DOC_COVER and COVER behave identically. The reason mom provides + two macros for cover page generation is so that you can have two + different kinds of covers with different information on each. +

+@@ -267,50 +279,166 @@ + author’s) name, and perhaps the copyright date. Subsequently, + you could use COVER, after each .COLLATE but before each + .START, +-to generate a cover page (or cover ”sheet”, if you +-prefer) containing just the name of the section. ++to generate a cover page (title page, cover sheet) containing ++just the name of the section, for example, “Part 1”. +

+ +-

The required argument

+- +

+-Both COVER and DOC_COVER, whenever invoked, require a first +-argument, as listed above. This first argument will become the +-first bit of information mom prints on the cover or doc cover (ie +-the title). ++The arguments to DOC_COVER and COVER tell mom ++what you’d like on cover pages. You may give as many or as ++few arguments as you need, in any order. A very common setup would ++be: ++
++ ++ .COVER TITLE AUTHOR COPYRIGHT ++ +

+ +-

+-In order for the information to appear, you must, of course, have +-given mom the appropriate +-reference macro. +-A list of first arguments with their equivalent reference macros follows. +-

+- +-
+-
TITLE
+-
+- – means the argument you gave to TITLE +-
+-
DOCTITLE
+-
+- – means the argument you gave to DOCTITLE +-
+-
COVERTITLE
+-
+- – means the argument you gave to COVERTITLE +- or +- DOC_COVERTITLE +-
+-
CHAPTER, CHAPTER_TITLE, CHAPTER+TITLE
+-
+- – see below, How the CHAPTER argument and friends work +-
+-
++

The argument list

+ +-
How the CHAPTER argument and friends work
++

++The arguments to COVER and DOC_COVER tell mom ++what you want on the cover page: ++
++ ++ TITLE | DOCTITLE | DOC_COVERTITLE | COVERTITLE ++ CHAPTER | CHAPTER_TITLE | CHAPTER+TITLE ++ SUBTITLE ++ AUTHOR ++ DOCTYPE ++ DOC_COVERTEXT | COVERTEXT ++ DOC_COVER_IMAGE | COVER_IMAGE ++ COPYRIGHT ++ MISC ++ PDF_OUTLINE_LABEL "<label>" ++ BLANKPAGE ++ ++

++ ++

What the arguments mean

++ ++
++
TITLE
++
– the string(s) you gave to ++ TITLE ++
++
DOCTITLE
++
– the string(s) you gave to ++ DOCTITLE ++
++
DOC_COVERTITLE / COVERTITLE
++
– the string(s) you gave to ++ DOC_COVERTITLE ++ or ++ COVERTITLE ++
++
CHAPTER, CHAPTER_TITLE, CHAPTER+TITLE
++
– see below, ++ How the CHAPTER argument and friends work ++
++
SUBTITLE
++
– the string(s) you gave to ++ SUBTITLE ++
++
AUTHOR
++
– the string(s) you gave to ++ AUTHOR ++
++
DOCTYPE
++
– the string you gave to ++ DOCTYPE NAMED ++
++
DOC_COVERTEXT / COVERTEXT
++
– the block of type you entered for ++ DOC_COVERTEXT ++ or ++ COVERTEXT ++
++
DOC_COVER_IMAGE / COVER_IMAGE
++
– the image file you gave to ++ DOC_COVER_IMAGE ++ or ++ COVER_IMAGE ++
++
COPYRIGHT
++
– the string you gave to ++ COPYRIGHT ++
++
MISC
++
– the string(s) you gave to ++ MISC ++
++
PDF_OUTLINE_LABEL <label>
++
++ ++ By default, mom identifies doc-covers in the outline panel of PDF ++ viewers with the prepended label, “Cover:”, and covers ++ with the label “Title Page:”. If you would like ++ to change the label, give the PDF_OUTLINE_LABEL ++ argument to DOC_COVER or COVER along with the new label, in ++ quotation marks, as in this example: ++
++   .COVER TITLE AUTHOR COPYRIGHT PDF_LABEL "Cover Sheet: " ++
++
++
BLANKPAGE
++
++ ++ If the final argument to DOC_COVER or COVER is BLANKPAGE, ++ mom will insert a blank page after the doc-cover or cover. This is ++ particularly useful if you intend to print your document two-sided, ++ since, in two-sided printing, there may be instances where you do ++ not want text on the reverse side of cover or title pages ++ ++ ++ If you enable ++ DOC_COVERS_COUNT_PAGES ++ and/or ++ COVERS_COUNT_PAGES, ++ the blank page will be taken into account in the pagination ++ scheme, though no page number appears on it. Otherwise, blank ++ pages are invisible to mom's pagination. ++ ++
++
++ ++

++Please note that in all cases, if you have passed ++a reference macro one of the optional arguments, ++DOC_COVER or COVER (e.g. ++.TITLE DOC_COVER "Title"), mom will print the ++appropriate string on the appropriate cover page. Thus, ++
++ ++ .TITLE DOC_COVER "Collected Essays" ++ .TITLE COVER "1985-2015" ++ .TITLE "Neo-liberalism: Who Did They Think They Were Fooling?" ++ .DOC_COVER TITLE ++ .COVER TITLE ++ ++will print “Collected Essays” on the doc-cover page, ++“1985-2015” on the cover page, and, assuming the ++docheader hasn’t been disabled, “Neo-liberalism: Who ++Did They Think They Were Fooling?” as the title in the ++docheader. ++

+ +

++Note that ++
++ ++ .DOC_COVERTITLE "Collected Essays" ++ .COVERTITLE "1985-2015" ++ .TITLE "Neo-liberalism: Who Did They Think They Were Fooling?" ++ .DOC_COVER DOC_COVERTITLE ++ .COVER COVERTITLE ++ ++could be used to accomplish the same thing. ++

++ ++
How the CHAPTER argument and friends work
++ ++

+ • CHAPTER +
+ The CHAPTER argument will print the +@@ -322,7 +450,7 @@ + + .CHAPTER 1 + .CHAPTER_TITLE "The Bonny Blue Yonder" +- .COVER CHAPTER \"(or .DOC_COVER CHAPTER) ++ .COVER CHAPTER \" (or .DOC_COVER CHAPTER) + + will print (and only print) +
+@@ -371,72 +499,196 @@ + +

+ +-

The optional arguments

++
++

DOC_COVERTEXT and COVERTEXT

++
++ ++
++Macro: DOC_COVERTEXT <toggle> ++
++
++Macro: COVERTEXT <toggle> ++
++ ++

++• Must come after ++PRINTSTYLE ++

++ ++

++DOC_COVERTEXT and COVERTEXT allow you to add ++text to doc-covers and covers in addition to, or instead of, what is ++generated by mom from the arguments you give to ++DOC_COVER ++and ++COVER. ++

++ ++

++Invoke .DOC_COVERTEXT or .COVERTEXT on a line ++by itself, follow it with the text and formatting you desire, and ++terminate the text block with .DOC_COVERTEXT OFF or ++COVERTEXT OFF (or QUIT, END, DONE, etc.). ++

++ ++

++By default, cover text is set over the full line length of the ++document, using the style parameters of ++running text. ++Therefore, as noted, these macros must come after PRINTSTYLE ++and any global style changes (margins, family, size, leading, ++etc.). Formatting within a cover text block must be done ++“manually” with mom’s typesetting macros; ++PP ++is the only allowed document element tag. ++

++ ++

Placement

+ +

+-The remainder of the arguments to COVER and +-DOC_COVER are optional. They refer specifically to +-the information you gave the +-reference macros +-bearing the same name as the arguments. You may enter as many or as +-few as you like, in any order. ++If you do not instruct mom to put anything on doc-cover or cover ++pages except DOC_COVERTEXT or COVERTEXT, the ++cover text will begin at the document’s top margin. You must ++use ++SP ++or ++ALD ++to move it further down the page. Equally, if only ++COPYRIGHT and/or MISC are to go on the pages, ++cover text begins at the top margin. In all other cases, cover text ++begins below the last element on the page, separated by a blank ++line. +

+ +-
What the DOCTYPE argument means
++

++DOC_COVERTEXT and COVERTEXT are particularly ++useful for putting abstracts on cover pages, as technical reports ++often require. ++

+ +

+-When you pass COVER or DOC_COVER +-the argument, DOCTYPE, it refers to the argument you gave +-to +-DOCTYPE NAMED. +-For example, if, in your +-docstyle macros +-you gave a ++Here's a simple recipe for setting an abstract: +
+ +- .DOCTYPE NAMED "Abstract" ++ .COVERTEXT ++ .FT BI ++ .PT_SIZE 14 ++ .LS 14 ++ .CENTER ++ Abstract ++ .SP .5v ++ .FT R ++ .PT_SIZE 12 ++ .IB 6P ++ .JUSTIFY ++ Text of Abstract... ++ .COVERTEXT OFF + +-the argument, DOCTYPE, given to the COVER or DOC_COVER +-macros, would mean that you wanted the word, Abstract, to appear on +-the cover or doc cover underneath the title and/or author(s), just +-as it would in the +-docheader. ++Assuming you have told mom to put the title and author on the ++cover page, the abstract will appear beneath the author with a ++14-point bold-italic title, centered, with the text of the abstract ++medium-roman and justified, indented 6 picas from both margins. +

+ +-
What the BLANKPAGE argument means
++
++

DOC_COVER_IMAGE and COVER_IMAGE

++
++ ++
++Macro: DOC_COVER_IMAGE <image> <width> <height> [ -L | -C | -R | -I <indent> <Y-pos> [ <X-pos> ] ] ++
++ ++
++Macro: COVER_IMAGE <image> <width> <height> [ -L | -C | -R | -I <indent> <Y-pos> [ <X-pos> ] ] ++
+ +

+-If the final argument to DOC_COVER or COVER is BLANKPAGE, +-mom will insert a blank page after the doc cover or cover. This is +-particularly useful if you intend to print your document two-sided, +-since, in two-sided printing, there may be instances where you do +-not want text on the reverse side of cover or title pages. ++There are times you need a full page image on a cover, for example ++the jacket of a book. Equally, there are times when you need a small ++image on the cover, perhaps a company logo. +

+ +

+-If you enable DOC_COVERS_COUNT_PAGES and/or COVERS_COUNT_PAGES, the +-blank page will be taken into account in the pagination scheme, +-though no page number appears on it. Otherwise, blank pages are +-invisible to mom's pagination. ++DOC_COVER_IMAGE and COVER_IMAGE take the same arguments ++as PDF_IMAGE, and in the same order. Consult ++PDF_IMAGE ++for a desciption. +

+ +-
What the PDF_OUTLINE_LABEL argument means
++

++Two additional arguments allow you to place images using x-y ++coordinates. Please note that if you use x-y coordinates for ++positioning, Y-pos comes before X-pos in the order of ++arguments. ++

+ +

+-By default, mom identifies doccovers in the outline panel of PDF +-viewers with the prepended string, “Cover:”, and covers +-with the string “Title Page:”. If you would like +-to change the strings, pass the PDF_OUTLINE_LABEL +-argument to COVER or DOCCOVER, along with the new string. ++Like PDF_IMAGE, the image file must be in PDF format. Mom ++apologizes, but PostScript images are not supported for inclusion on ++covers. See ++Image conversion and file processing ++for instructions on converting various image types to PDF, and ++here ++for instructions on obtaining image dimensions. +

+ +- ++

Positioning of doc-cover and cover images

+ +-
++

++With no arguments other than <file name>, ++<width>, and <height>, ++DOC_COVER_IMAGE and COVER_IMAGE place images flush with the top ++left corner of the printer sheet. This allows placing full-page ++background images on covers. For example, assuming a US-letter page ++size, ++
++ ++ .DOC_COVER_IMAGE image.pdf 612p 792p ++ .DOC_COVER TITLE AUTHOR DOC_COVER_IMAGE ++ ++will fill the doc-cover page with “image.pdf” and set ++the title and author in their usual locations. ++

++ ++

++For smaller images, the horizontal position is established ++with one of the -L, -C, -R, or ++-I <indent> arguments, just like ++PDF_IMAGE. ++You may instead use the X-pos argument, provided that it ++is preceded by a Y-pos argument. The values given to ++-I, Y-pos and X-pos must have a ++unit of measure ++appended to them. ++

++ ++

++Vertical positioning of smaller images requires the Y-pos ++argument (which is why it precedes X-pos in the order of ++arguments) otherwise the image will be flush with the top edge of ++the printer sheet ++

++ ++

++The positioning of images does not effect the placement of type on ++doc-cover and cover pages. ++

++ ++
++

++Tip: ++The combination of ++COVERTEXT ++and COVER_IMAGE make it possible to design covers entirely to your ++own specifications. ++

++
++ ++
+

Enabling/disabling automatic generation of cover pages

+
+ +-
++
+ Macro: COVERS <toggle> +
+ +@@ -449,7 +701,7 @@ + COVER + or + DOC_COVER +-directive, she will print the cover or doc cover. In a document ++directive, she will print the cover or doc-cover. In a document + that contains sections, articles or chapters formerly treated as + ”one-off’s” but now being + collated, +@@ -458,12 +710,11 @@ + +

+ Mom lets you selectively enable or disable the generation of covers +-and/or doc covers with the toggle macros, COVERS and DOC_COVERS. ++and/or doc-covers with the toggle macros, COVERS and DOC_COVERS. + Because they’re toggle macros, simply invoking them by +-themselves enables automatic cover or doc cover generation, while ++themselves enables automatic cover or doc-cover generation, while + invoking them with any argument at all (OFF, QUIT, X, +-etc) disables cover or doc cover generation. +-

++etc) disables cover or doc-cover generation.

+ +
+

+@@ -482,10 +733,10 @@ + +


+ +-

Control macros for covers and doc covers

++

Control macros for doc-covers and covers

+ +

+-The default typographic appearance of the items on a cover or doc ++The default typographic appearance of the items on a doc-cover or + cover is identical to that of the items in a + docheader. + (See +@@ -501,111 +752,80 @@ + characteristics: +

+
    +-
  • the COPYRIGHT line is set in the bottom right hand corner +- of the page, 2 ++
  • the COPYRIGHT line is set flush with the document’s right ++ and bottom margins, 2 + point sizes + smaller than the size of + running text +
  • +-
  • MISC lines are set in the bottom left hand +- corner of the page, in the same family, font and point size +- as the copyright line. ++
  • MISC lines are set flush with the document’s left and bottom ++ margins, in the same family, font and point size as the ++ copyright line. +
  • +
+ +

+-The defaults for the entirety of covers and doc covers, and all the ++The defaults for the entirety of doc-covers and covers, and all the + elements thereon, can be changed with control macros whose defaults +-and arguments are identical to the corresponding control macros +-governing docheaders. The only difference is the name by which you +-invoke them. ++and arguments are identical to the corresponding ++Control macros for docheaders ++(q.v.) The only difference is the name by which you invoke them. Wherever ++DOCHEADER is used for overall changes, replace it ++with DOC_COVER or COVER. For part-by-part ++changes, prepend DOC_COVER_ or COVER_ to the ++part/parameter. +

+ +

+-A complete list of cover and doc cover control macros follows. +-Please refer to +-docheader control +-in order to get the defaults and any special instructions for usage. +-

+- +-

Cover / doc cover control macros and defaults

+- +-
+- +- +-COVER_ADVANCE DOC_COVER_ADVANCE -+ +-COVER_FAMILY DOC_COVER_FAMILY | like +-COVER_LEAD DOC_COVER_LEAD | DOCHEADER_<spec> +-COVER_QUAD DOC_COVER_QUAD -+ +- +-COVER_TITLE_FAMILY DOC_COVER_TITLE_FAMILY -+ +-COVER_TITLE_FONT DOC_COVER_TITLE_FONT | like +-COVER_TITLE_COLOR DOC_COVER_TITLE_COLOR | TITLE_<spec> +-COVER_TITLE_SIZE DOC_COVER_TITLE_SIZE -+ +- +-COVER_CHAPTER_TITLE_FAMILY DOC_COVER_CHAPTER_TITLE_FAMILY -+ +-COVER_CHAPTER_TITLE_FONT DOC_COVER_CHAPTER_TITLE_FONT | like +-COVER_CHAPTER_TITLE_COLOR DOC_COVER_CHAPTER_TITLE_COLOR | CHAPTER_TITLE_<spec> +-COVER_CHAPTER_TITLE_SIZE DOC_COVER_CHAPTER_TITLE_SIZE -+ +- +-COVER_SUBTITLE_FAMILY DOC_COVER_SUBTITLE_FAMILY -+ +-COVER_SUBTITLE_FONT DOC_COVER_SUBTITLE_FONT | like +-COVER_SUBTITLE_COLOR DOC_COVER_SUBTITLE_COLOR | SUBTITLE_<spec> +-COVER_SUBTITLE_SIZE DOC_COVER_AUTHOR_SIZE -+ +- +-COVER_ATTRIBUTE_COLOR DOC_COVER_ATTRIBUTE_COLOR - like ATTRIBUTE_COLOR +- - the macro, ATTRIBUTE_STRING, controls the attribution string +- for both docheaders and cover pages; cover pages have no +- separate ATTRIBUTE_STRING macro +- +-COVER_AUTHOR_FAMILY DOC_COVER_AUTHOR_FAMILY -+ +-COVER_AUTHOR_FONT DOC_COVER_AUTHOR_FONT | like +-COVER_AUTHOR_COLOR DOC_COVER_AUTHOR_COLOR | AUTHOR_<spec> +-COVER_AUTHOR_SIZE DOC_COVER_AUTHOR_SIZE -+ +- +-COVER_DOCTYPE_FAMILY DOC_COVER_DOCTYPE_FAMILY -+ +-COVER_DOCTYPE_FONT DOC_COVER_DOCTYPE_FONT | like +-COVER_DOCTYPE_COLOR DOC_COVER_DOCTYPE_COLOR | DOCTYPE_<spec> +-COVER_DOCTYPE_SIZE DOC_COVER_DOCTYPE_SIZE -+ +- +-COVER_COPYRIGHT_FAMILY DOC_COVER_COPYRIGHT_FAMILY -+ +-COVER_COPYRIGHT_FONT DOC_COVER_COPYRIGHT_FONT | +-COVER_COPYRIGHT_COLOR DOC_COVER_COPYRIGHT_COLOR | like any of the above +-COVER_COPYRIGHT_SIZE DOC_COVER_COPYRIGHT_SIZE | +-COVER_COPYRIGHT_QUAD DOC_COVER_COPYRIGHT_QUAD -+ +- - copyright quad sets both the position on the page and the quad +- direction and can be either L (left) or R (right); default is right +- +-COVER_MISC_FAMILY DOC_COVER_MISC_FAMILY -+ +-COVER_MISC_FONT DOC_COVER_MISC_FONT | +-COVER_MISC_COLOR DOC_COVER_MISC_COLOR | like any of the above +-COVER_MISC_SIZE DOC_COVER_MISC_SIZE | +-COVER_MISC_QUAD DOC_COVER_MISC_QUAD -+ +- - misc quad sets both the position on the page and the quad +- direction and can be either L (left) or R (right); default is left +- +-COVER_UNDERLINE DOC_COVER_UNDERLINE - like DOCTYPE_UNDERLINE +- - cover underline controls underlining of the argument given to +- DOCTYPE NAMED "<name>" only +- +-COVER_COUNTS_PAGES DOC_COVER_COUNTS_PAGES +- - whether to consider cover pages in the pagination scheme; the +- default is to ignore them +- - see Note ++Thus, to change the overall family, color, leading, quad and ++starting position of a doc-cover, you’d do ++
++ ++ .DOC_COVER_FAMILY H ++ .DOC_COVER_COLOR blue ++ .DOC_COVER_LEADING +2 ++ .DOC_COVER_QUAD L ++ .DOC_COVER_ADVANCE 3i \" or .DOC_COVER_START_POS 3i + +-
+- +-

+-Note: ++To change the style parameters for selected parts of a cover, you ++might do something like this: +
+-COVER_COUNTS_PAGES and DOC_COVER_COUNTS_PAGES are toggle macros, +-hence invoking them by themselves means that mom will consider +-covers and doc covers in the pagination scheme; invoking them with +-any argument (OFF, NO, X, etc.) means they are ignored. +-The default is to ignore them. ++ ++ .COVER_TITLE_FONT B ++ .COVER_TITLE_SIZE +4 ++ .COVER_SUBTITLE_FONT I ++ .COVER_AUTHOR_FONT R ++ .COVER_AUTHOR_SPACE_BEFORE 6p ++ .COVER_DOCTYPE_COLOR red ++ .COVER_MISC_SIZE -1 ++ .COVER_MISC_LEAD 12 ++ .COVER_COPYRIGHT_SIZE -2 ++ .COVER_COPYRIGHT_QUAD L ++ .COVER_MISC_QUAD R ++ ++Note in the above example that _COPYRIGHT_QUAD and _MISC_QUAD set ++both the horizontal position on the page and the quad direction, ++either L (or LEFT) or R (or RIGHT), and have no corresponding ++docheader control macro. +

+ +-

++
++

++Tip: ++As with the docheader control macros, DOC_COVER_ and ++COVER_ part/parameter style changes may be ++grouped, ++for example ++
++ ++ .DOC_COVER_TITLE_STYLE \ ++ FAMILY A \ ++ FONT B \ ++ SIZE +4 \ ++ CAPS ++ ++

++
+ + + +diff -Nuar groff-1.22.3.old/contrib/mom/momdoc/definitions.html groff-1.22.3/contrib/mom/momdoc/definitions.html +--- groff-1.22.3.old/contrib/mom/momdoc/definitions.html 2014-11-04 10:38:35.612519159 +0200 ++++ groff-1.22.3/contrib/mom/momdoc/definitions.html 2015-04-23 20:57:03.000000000 +0300 +@@ -2,7 +2,7 @@ + +@@ -469,11 +540,24 @@ + +
+

+-Tip: ++Tips on vertical spacing around epigraphs: ++If you wish to change the vertical position of an epigraph with ++SPACE/ ++ALD/ ++RLD, ++do so before invoking .EPIGRAPH, like this: ++
++ ++ .SP -6p ++ .EPIGRAPH ++ A notable quote. ++ .EPIGRAPH OFF ++ + If you’re setting a document in + columns +-and you’d like to add or subtract space after the epigraph, +-the place to do it is inside the epigraph, like this: ++and you’d like to add or subtract space after the ++epigraph, which is centered over the top of both columns, the place ++to do it is inside the epigraph, like this: +
+ + .EPIGRAPH +@@ -493,6 +577,10 @@ +

+ See + Arguments to the control macros. ++
++The following EPIGRAPH control macros may also be ++grouped ++using EPIGRAPH_STYLE. +

+ + +@@ -501,10 +589,7 @@ + .EPIGRAPH_SIZE default = -1.5 (points) + .EPIGRAPH_COLOR default = black + .EPIGRAPH_AUTOLEAD default = 2 points +- + (The next two apply to “block” style epigraphs only) +- +-.EPIGRAPH_QUAD default = same as paragraphs + .EPIGRAPH_INDENT* (see Note on EPIGRAPH_INDENT, below) + + *Indent here refers to the indent from both the left and right margins +@@ -666,8 +751,11 @@ + The PP macro being so important, and representing, as it were, the + basis of everything that goes on in a document, its control is + managed in a manner somewhat different from other document element +-tags. ++tags. As a result, the control macros for PP may not be ++grouped ++within a _STYLE macro. +

++ +
    +
  1. Family control
  2. +
  3. Font control
  4. +@@ -1270,6 +1358,7 @@ + UNDERSCORE <weight> <gap> | NO_UNDERSCORE \ + UNDERSCORE2 <weight> <gap1> <gap2> | NO_UNDERSCORE2 \ + CAPS | NO_CAPS \ ++ SMALLCAPS | NO_SMALLCAPS \ + BASELINE_ADJUST <amount to raise heading from the baseline> \ + SPACE_AFTER | NO_SPACE_AFTER \ + NUMBER | NO_NUMBER +@@ -1927,9 +2016,9 @@ +

    + +
    +-

    Further notes on quote spacing

    ++

    Notes on quote spacing

    + +-

    ++

    + If your quote (or blockquote) leading differs from the document + leading, mom attempts to observe the same rules for vertical + whitespace outlined above; however, she will also insert a small, +@@ -1945,12 +2034,12 @@ + which, by and large, processes text on a line-per-line basis.) +

    + +-

    Disable shimming of quotes and blockquotes

    ++

    Disable shimming of quotes and blockquotes

    + +

    + If you don’t want the behaviour described above (ie you +-don’t want mom shimming +-quotes and blockquotes), issue the macro ++don’t want mom shimming quotes and blockquotes), issue the ++macro +
    + + .NO_SHIM +@@ -1961,6 +2050,17 @@ +

    + +

    ++If you set the leading of ++quotes ++or ++blockquotes ++to a value other than the one used in paragraphs, mom will apply ++shimming after the quote, whether or not .NO_SHIM ++is enabled. This is the only way mom can guarantee that the ++difference in leading will not result in uneven bottom margins. ++

    ++ ++

    + If you’ve disabled shimming of quotes and blockquotes with + .NO_SHIM and you want mom to return to her default + behaviour in this matter, invoke .NO_SHIM OFF (or +@@ -2015,14 +2115,18 @@ +

    + +
    +-Macro: QUOTE toggle ++Macro: QUOTE [ ADJUST +|-<space> ] | <anything> +
    ++

    ++• The argument to ADJUST requires a ++unit of measure ++

    + +

    +-QUOTE is a toggle macro. To begin a section +-of quoted text, invoke it with no argument, then type in your +-quote. When you’re finished, invoke .QUOTE with any +-argument (eg OFF, END, X, Q...) to turn it off. Example: ++QUOTE is a toggle macro. To begin a section of quoted text, invoke ++it with no argument, then type in your quote. When you’re ++finished, invoke .QUOTE with any argument (eg OFF, ++END, X, Q...) to turn it off. Example: +
    + + .QUOTE +@@ -2033,9 +2137,28 @@ + And bits of her tits in Brazil. + .QUOTE END + ++Mom does her best to equalize whitespace around quotes and make ++sure the line following it falls on a valid baseline. On occasion, ++you may need to tweak the quote placement slightly, which is done ++by passing ADJUST to QUOTE with a plus or minus value. ++The quote will be lowered (+) or raised (-) ++within the space allotted for it by the given amount. For ++example, to lower a quote slightly within the space allotted for it, ++you’d do ++
    ++ ++ .QUOTE ADJUST +3p ++ There was a soprano named Golda ++ Whose lovers grew colda and colda ++ For during love-making ++ She'd sing the earth-shaking ++ Love theme from Tristan und Isolde. ++ .QUOTE off ++ +

    + +
    ++ +

    QUOTE control macros and defaults

    + +
      +@@ -2051,14 +2174,27 @@ +

      + See + Arguments to the control macros. ++
      ++The following QUOTE control macros may also be ++grouped ++using QUOTE_STYLE. If you do so, QUOTE_LEFT, QUOTE_CENTER, ++and QUOTE_RIGHT must be entered as: ++
      ++   QUAD LEFT
      ++   QUAD CENTER
      ++   QUAD RIGHT +

      ++ + + .QUOTE_FAMILY default = prevailing document family; default is Times Roman + .QUOTE_FONT default = italic; underlined in TYPEWRITE + .QUOTE_SIZE default = +0 (ie same size as paragraph text) +-.QUOTE_AUTOLEAD default = none; leading of quotes is the same as paragraphs ++.QUOTE_AUTOLEAD default = none; leading of quotes is the same as paragraphs + .QUOTE_COLOR default = black + .QUOTE_INDENT (see below, "Quote indent") ++.QUOTE_LEFT -+ Quad direction of quote. ++.QUOTE_CENTER | LEFT observes QUOTE_INDENT; ++.QUOTE_RIGHT -+ CENTER and RIGHT do not + +
    + +@@ -2086,19 +2222,13 @@ +

    + +
    +-

    ++

    + Note: + If your PARA_INDENT is 0 (ie no indenting of the first line of + paragraphs), you must set a QUOTE_INDENT yourself, with a + unit of measure appended to the argument. Mom has no default for + QUOTE_INDENT if paragraph first lines are not being indented. +

    +- +-

    +-Additional note: +-QUOTE_INDENT also sets the indent for +-blockquotes. +-

    +
    + +

    2. Spacing above and below quotes (typeset only)

    +@@ -2112,7 +2242,7 @@ + + with no argument. If you wish to restore mom’s + default behaviour regarding the spacing of quotes (see +-above), ++Quote spacing), + invoke the macro with any argument (OFF, QUIT, END, X...) +

    + +@@ -2179,7 +2309,7 @@ + Besides indenting blockquotes, mom further sets them off from + running text with a small amount of vertical whitespace top and + bottom. (See +-above ++Quote spacing + for a complete explanation of how this is managed, and how + to control it.) +

    +@@ -2191,13 +2321,18 @@ +
+ +
+-Macro: BLOCKQUOTE toggle ++Macro: BLOCKQUOTE [ ADJUST +|-<space> ] | <anything> +
+ +

+ Aliases: CITE, CITATION +

+ ++

++• The argument to ADJUST requires a ++unit of measure ++

++ +

+ BLOCKQUOTE is a toggle macro. To begin a cited passage, invoke + the tag with no argument, then type in your blockquote. When +@@ -2219,6 +2354,27 @@ + .PP. +

+ ++

++Mom does her best to equalize whitespace around blockquotes and make ++sure the line following it falls on a valid baseline. On occasion, ++you may need to tweak the blockquote placement slightly, which is ++done by passing ADJUST to BLOCKQUOTE with a plus or minus ++value. The blockquote will be lowered (+) or raised ++(-) within the space allotted for it by the given ++amount. For example, to raise a blockquote slightly within the ++space allotted for it, you’d do ++
++ ++ .BLOCKQUOTE ADJUST -3p ++ True! - nervous - very, very dreadfully nervous I had been and ++ am; but why will you say that I am mad? The disease had sharpened ++ my senses - not destroyed - not dulled them. ++ .RIGHT ++ \[em]Edgar Allen Poe, The Tell-Tale Heart ++ .QUOTE off ++ ++

++ +
+

+ Note: +@@ -2243,12 +2399,16 @@ +

+ See + Arguments to the control macros. ++
++The following BLOCKQUOTE control macros may also be ++grouped ++using BLOCKQUOTE_STYLE. +

+ + .BLOCKQUOTE_FAMILY default = prevailing document family; default is Times Roman + .BLOCKQUOTE_FONT default = roman + .BLOCKQUOTE_SIZE default = -1 (point) +-.BLOCKQUOTE_AUTOLEAD default = none; leading of blockquotes is the same as paragraphs ++.BLOCKQUOTE_AUTOLEAD default = none; leading of blockquotes is the same as paragraphs + .BLOCKQUOTE_COLOR default = black + .BLOCKQUOTE_QUAD default = left + .BLOCKQUOTE_INDENT (see below) +@@ -2280,19 +2440,13 @@ +

+ +
+-

++

+ Note: + If your PARA_INDENT is 0 (ie no indenting of the first line of + paragraphs), you must set a BLOCKQUOTE_INDENT yourself, with + a unit of measure appended to the argument. Mom has no default for + BLOCKQUOTE_INDENT if paragraph first lines are not being indented. +

+- +-

+-Additional note: +-BLOCKQUOTE_INDENT also sets the indent for +-quotes. +-

+
+ + +@@ -2308,7 +2462,7 @@ +
+ with no argument. If you wish to restore mom’s default + behaviour regarding the spacing of blockquotes (see +-above), ++Quote spacing), + invoke the macro with any argument (OFF, QUIT, END, + X...). +

+@@ -2506,6 +2660,10 @@ +

+ See + Arguments to the control macros. ++
++The following CODE control macros may also be ++grouped ++using CODE_STYLE. +

+ + .CODE_FAMILY default = Courier +@@ -2883,9 +3041,6 @@ + Lorem ipsum dolor sit amet, consetetur sadipscing elitr, + sed diam nonumy eirmod tempor invidunt ut labore. + +-

+- +-

+ Alternatively, you may use the single-purpose macro, + .QUIT_LISTS, to get yourself out of a list structure. In + the example above, the two .LIST OFF lines could be +@@ -2935,7 +3090,12 @@ +

+

LIST control macros and defaults

+ +-
    ++

    ++LIST control macros may not be ++grouped. ++

    ++ ++
      +
    1. Indenting lists (SHIFT_LIST)
    2. +
    3. Resetting an initialized list’s enumerator (RESET_LIST)
    4. +
    5. Padding digit enumerators (PAD_LIST_DIGITS)
    6. +@@ -3377,8 +3537,9 @@ + +
        +
      1. Family/font/size/colour
      2. ++
      3. Reset line numbering after COLLATE
      4. +
      5. Line numbering control for quotes and blockquotes +-
+ +-

2. Line numbering control macros for QUOTE and BLOCKQUOTE

++

2. Reset line numbering after COLLATE

++ ++

++After ++COLLATE, ++line numbering continues from where it left off. If you would like ++each chapter or major document section to begin its line numbering ++at “1”, invoke ++ ++ .NUMBER_LINES_PER_SECTION ++ ++after ++.NUMBER_LINES. ++

++ ++

3. Line numbering control macros for QUOTE and BLOCKQUOTE

+ +
• Including QUOTEs and BLOCKQUOTEs in the line numbering scheme
+ +@@ -3993,6 +4173,10 @@ +

+ See + Arguments to the control macros. ++
++The following FOOTNOTE control macros may also be ++grouped ++using FOOTNOTE_STYLE. +

+ + .FOOTNOTE_FAMILY default = prevailing document family; default is Times Roman +@@ -4711,19 +4895,18 @@ +
  • Header/footer centre string when doctype is CHAPTER
  • +
  • Allow headers on endnotes pages
  • + +-
  • Endnotes' first-page title control ++
  • Endnotes header (first-page title) control +
  • +
  • Endnotes document-identification string control +
  • +
  • Endnotes referencing style +
      +@@ -4747,6 +4930,10 @@ +

      + See + Arguments to the control macros. ++
      ++The following ENDNOTE control macros may also be ++grouped ++using ENDNOTE_STYLE. +

      + + .ENDNOTE_FAMILY default = prevailing document family; default is Times Roman +@@ -5200,59 +5387,82 @@ +

      +
  • + +-

    4. Endnotes' first-page title control

    ++

    4. Endnotes header (first-page title) control

    + +- ++ + +-
    • Title string
    ++
    • Header (first-page title) string
    + +
    +-Macro: ENDNOTE_STRING "<head to print at the top of endnotes>" ++Macro: ENDNOTES_HEADER_STRING "<title to print at the top of endnotes>" +
    + ++

    ++Alias: ENDNOTE_STRING (for compatibility with older documents) ++

    ++ +

    + By default, mom prints the word “ENDNOTES” as a head + at the top of the first page of endnotes. If you want her to +-print something else, invoke .ENDNOTE_STRING with the +-endnotes-page head you want, surrounded by double-quotes. If you +-don’t want a head at the top of the first endnotes-page, +-invoke .ENDNOTE_STRING with a blank argument (either two +-double-quotes side by side—""—or no +-argument at all). ++print something else, invoke .ENDNOTES_HEADER_STRING ++with the endnotes-page head you want, surrounded by double-quotes. ++If you don’t want a head at the top of the first ++endnotes-page, invoke .ENDNOTES_HEADER_STRING ++with a blank argument (either two double-quotes side by ++side—""—or no argument at all). +

    + +- ++ + +-
    • Title control macros and defaults
    ++
    • Header (first-page title) control macros and defaults
    + +
    +

    + See + Arguments to the control macros. ++
    ++The following ENDNOTES_HEADER control macros may also be ++grouped ++using ENDNOTES_HEADER_STYLE. +

    ++ ++

    ++Please note that “_HEADER_”, here, refers to the title ++that appears at the top of the first endnotes page, not to the page ++headers of subsequent endnotes pages. + +-.ENDNOTE_STRING_FAMILY default = prevailing document family +-.ENDNOTE_STRING_FONT default = bold +-.ENDNOTE_STRING_SIZE* default = +1 +-.ENDNOTE_STRING_QUAD default = centred +-.ENDNOTE_STRING_COLOR default = black ++.ENDNOTES_HEADER_FAMILY default = prevailing document family ++.ENDNOTES_HEADER_FONT default = bold ++.ENDNOTES_HEADER_SIZE* default = +1 ++.ENDNOTES_HEADER_QUAD default = centred ++.ENDNOTES_HEADER_COLOR default = black + + *Relative to the size of the endnotes text (set with ENDNOTE_PT_SIZE) + ++

    +
    + +- ++

    ++Note: For compatibility with older documents, these macros are aliased ++as .ENDNOTE_STRING_<SPEC>, e.g. .ENDNOTE_STRING_FAMILY. ++

    ++ ++ + +-
    • Title string placement
    ++
    • Header (first-page title) placement
    + +
    +-Macro: ENDNOTE_STRING_ADVANCE <distance from top of page> ++Macro: ENDNOTES_HEADER_V_POS <distance from top of page> +
    + +

    + • Argument requires a unit of measusure +

    + ++

    ++Alias: ENDNOTE_STRING_ADVANCE (for compatibility with older documents) ++

    ++ +

    + By default, mom places the title (the docheader, as it were) of + endnotes pages (typically "ENDNOTES") on the same +@@ -5261,7 +5471,7 @@ + running text. + If you’d prefer another location, higher or lower on the page + (thereby also raising or lowering the starting position of the +-endnotes themselves), invoke .ENDNOTE_STRING_ADVANCE with ++endnotes themselves), invoke .ENDNOTES_HEADER_V_POS with + an argument stating the distance from the top edge of the page at + which you’d like the title placed. +

    +@@ -5272,20 +5482,23 @@ + mom about it like this: +
    + +- .ENDNOTE_STRING_ADVANCE 1.5i ++ .ENDNOTES_HEADER_V_POS 1.5i + +

    + +- ++ + +-
    • Title string underscoring
    ++
    • Header (first-page title) underscoring
    + +
    +-Macro: ENDNOTE_STRING_UNDERSCORE [DOUBLE] [<underscore weight> [<underscore gap> [<distance between double rules]]] | <none> | <anything> ++Macro: ENDNOTES_HEADER_UNDERSCORE [DOUBLE] [<underscore weight> [<underscore gap> [<distance between double rules]]] | <none> | <anything> +
    + +

    +-Alias: ENDNOTE_STRING_UNDERLINE ++Alias: ENDNOTES_HEADER_UNDERLINE. ++(For compatibility with older documents, also ++aliased as ENDNOTE_STRING_UNDERSCORE and ++ENDNOTE_STRING_UNDERLINE.) +

    + +

    +@@ -5298,16 +5511,16 @@ +

    + +

    +-Invoked without an argument, .ENDNOTE_STRING_UNDERSCORE ++Invoked without an argument, .ENDNOTES_HEADER_UNDERSCORE + will place a single rule underneath the endnotes page title. Invoked +-with the argument, DOUBLE, ENDNOTE_STRING_UNDERSCORE will ++with the argument, DOUBLE, ENDNOTES_HEADER_UNDERSCORE will + double-underscore the title. Invoked with any other non-numeric + argument, (eg OFF, NO, X, etc.) the macro disables + underscoring of the title. +

    + +

    +-In addition, you can use ENDNOTE_STRING_UNDERSCORE to control the ++In addition, you can use ENDNOTES_HEADER_UNDERSCORE to control the + weight of the underscore rule(s), the gap between the title and the + underscore, and, in the case of double-underscores, the distance + between the two rules. +@@ -5317,27 +5530,27 @@ + Some examples: +
    + +- .ENDNOTE_STRING_UNDERSCORE 1 ++ .ENDNOTES_HEADER_UNDERSCORE 1 + - turn underscoring on; set the rule weight to 1 point + +- .ENDNOTE_STRING_UNDERSCORE 1 3p ++ .ENDNOTES_HEADER_UNDERSCORE 1 3p + - turn underscoring on; set the rule weight to 1 point; set + the gap between the title and the underscore to 3 points + +- .ENDNOTE_STRING_UNDERSCORE DOUBLE .75 3p ++ .ENDNOTES_HEADER_UNDERSCORE DOUBLE .75 3p + - turn double-underscoring on; set the rule weight to 3/4 of + a point; set the gap between the title and the upper + underscore to 3 points; leave the gap between the upper +- and the lower underunderscore at the default ++ and the lower underscore at the default + +- .ENDNOTE_STRING_UNDERSCORE DOUBLE 1.5 1.5p 1.5p ++ .ENDNOTES_HEADER_UNDERSCORE DOUBLE 1.5 1.5p 1.5p + - turn double-underscoring on; set the rule weight to 1-1/2 + points; set the gap between the title and the upper + underscore to 1-1/2 points; set the gap between the upper + and the lower underscore to 1-1/2 points + + Note, from the above, that in all instances, underscoring (single +-or double) is enabled whenever ENDNOTE_STRING_UNDERSCORE is used in ++or double) is enabled whenever ENDNOTES_HEADER_UNDERSCORE is used in + this way. +

    + +@@ -5347,16 +5560,20 @@ + title. +

    + +- ++ + +-
    • Title string capitalization
    ++
    • Header (first-page title) capitalization
    + +
    +-Macro: ENDNOTE_STRING_CAPS toggle ++Macro: ENDNOTES_HEADER_CAPS toggle +
    + ++

    ++Alias: ENDNOTE_STRING_CAPS (for compatibility with older documents) ++

    ++ +

    +-Invoked by itself, .ENDNOTE_STRING_CAPS will ++Invoked by itself, .ENDNOTES_HEADER_CAPS will + automatically capitalize the endnotes-page title. Invoked with any + other argument, the macro disables automatic capitalization of the + title. +@@ -5366,8 +5583,8 @@ + If you’re generating a table of contents, you may want the + endnotes pages title to be in caps, but the toc entry in caps/lower + case. If the argument to +-ENDNOTE_STRING +-is in caps/lower case and ENDNOTE_STRING_CAPS is on, this is exactly ++ENDNOTES_HEADER_STRING ++is in caps/lower case and ENDNOTES_HEADER_CAPS is on, this is exactly + what will happen. +

    + +@@ -5412,87 +5629,25 @@ +

    + See + Arguments to the control macros. ++
    ++The following ENDNOTE_TITLE_STYLE control macros may also be ++grouped ++using ENDNOTE_TITLE_STYLE_STYLE. +

    + +-.ENDNOTE_TITLE_FAMILY default = prevailing document family; default is Times Roman +-.ENDNOTE_TITLE_FONT default = bold +-.ENDNOTE_TITLE_SIZE* default = 0 +-.ENDNOTE_TITLE_QUAD default = left ++.ENDNOTE_TITLE_FAMILY default = prevailing document family; default is Times Roman ++.ENDNOTE_TITLE_FONT default = bold ++.ENDNOTE_TITLE_SIZE* default = 0 ++.ENDNOTE_TITLE_COLOR default = black ++.ENDNOTE_TITLE_QUAD default = left ++.ENDNOTE_TITLE_CAPS ++.ENDNOTE_TITLE_SMALLCAPS ++.ENDNOTE_TITLE_UNDERSCORE default = single underscore + + *Relative to the size of the endnotes text (set with ENDNOTE_PT_SIZE) + + + +- +- +-
    • Endnotes document-identification underscoring
    +- +-
    +-Macro: ENDNOTE_TITLE_UNDERSCORE [DOUBLE] [<underline weight> [<underline gap> [<distance between double rules]]] | <none> | <anything> +-
    +- +-

    +-Alias: ENDNOTE_TITLE_UNDERLINE +-

    +- +-

    +-• The argument +-<underscore weight> +-must not have the +-unit of measure, +-p, +-appended to it; all other arguments require a unit of measure +-

    +- +-

    +-Invoked without an argument, .ENDNOTE_TITLE_UNDERSCORE +-will place a single rule underneath the document identification +-string. Invoked with the argument DOUBLE, +-ENDNOTE_TITLE_UNDERSCORE will double-underscore the string. Invoked +-with any other non-numeric argument, (eg OFF, NO, X, +-etc.) the macro disables underscoring of the string. +-

    +- +-

    +-In addition, you can use ENDNOTE_TITLE_UNDERSCORE to control the +-weight of the underscore rule(s), the gap between the title and the +-underscore, and, in the case of double-underscores, the distance +-between the two rules. +-

    +- +-

    +-Some examples: +-
    +- +- .ENDNOTE_TITLE_UNDERSCORE 1 +- - turn underscoring on; set the rule weight to 1 point +- +- .ENDNOTE_TITLE_UNDERSCORE 1 3p +- - turn underscoring on; set the rule weight to 1 point; set +- the gap between the string and the underscore to 3 points +- +- .ENDNOTE_TITLE_UNDERSCORE DOUBLE .75 3p +- - turn double-underscoring on; set the rule weight to 3 points +- +- .ENDNOTE_TITLE_UNDERSCORE DOUBLE 1.5 1.5p 1.5p +- - turn double-underscoring on; set the rule weight to 1-1/2 +- points; set the gap between the string and the upper +- underscore to 1-1/2 points; set the gap between the upper +- and the lower underscore to 1-1/2 points +- +-

    +- +-

    +-Note, from the above, that in all instances, underscoring (single or +-double) is enabled whenever ENDNOTE_TITLE_UNDERSCORE is used in this +-way. +-

    +- +-

    +-Mom’s default is to single-underscore the string with a +-1/2-point rule placed 2 points below its baseline. +-

    +- + + +

    6. Endnotes referencing style

    +@@ -6167,11 +6322,12 @@ + + + +@@ -6243,7 +6399,15 @@ + +

    Finis contol macros

    + +-

    Changing the FINIS string

    ++

    ++Since FINIS is only used once in a document, it has few control ++macros. It is expected that you will make changes to style ++parameters such as family, font, and size with ++inline escapes ++in the FINIS string itself (see below). ++

    ++ ++

    Changing the FINIS string

    + +

    + By default, FINIS prints the word, END, between +@@ -6312,6 +6476,19 @@ + (usually black). +

    + ++ ++ ++

    Removing the dashes around FINIS

    ++ ++

    ++If you don’t want the dashes around the FINIS string, you can ++remove them with ++
    ++ ++ .FINIS_NO_DASHES ++ ++

    ++ +

    + + +diff -Nuar groff-1.22.3.old/contrib/mom/momdoc/docprocessing.html groff-1.22.3/contrib/mom/momdoc/docprocessing.html +--- groff-1.22.3.old/contrib/mom/momdoc/docprocessing.html 2014-11-04 10:38:35.613519146 +0200 ++++ groff-1.22.3/contrib/mom/momdoc/docprocessing.html 2015-04-23 20:57:03.000000000 +0300 +@@ -2,7 +2,7 @@ + + +@@ -832,7 +833,7 @@ + +

    + Moreover, DOCTITLE does not appear in the +-PDF outline , ++PDF outline, + as its presence in window title would make it redundant. +

    + +@@ -1255,7 +1256,7 @@ +

    + You may, if you wish, invoke .REVISION without an + argument, in which case, no revision number will be printed beside +-"Rev." in headers or footers. ++“Rev.” in headers or footers. +

    + + +@@ -1487,7 +1488,7 @@ + +

    + Except for +-DOCTITLE, ++DOCTITLE, + mom does not, by default, provide PDF viewers with a document title. + You may set one, if you like, with PDF_TITLE. +

    +@@ -1509,9 +1510,6 @@ +

    Docstyle macros

    +
      +
    • DOCTYPE +-
    • +
    • PRINTSTYLE – non-optional macro required for document processing +
        +
      • Defaults for PRINTSTYLE TYPESET
      • +@@ -1603,100 +1601,21 @@ + for how mom outputs each part of the page header.) +

        + +-

        +-Additionally, if you wish the name of this particular kind of +-document to be coloured, you can pass DOCTYPE NAMED a +-third (optional) argument: the name of a colour pre-defined (or +-“initialized”) with +-NEWCOLOR +-or +-XCOLOR. +-For example, if you have a doctype named “Warning”, +-and you’d like “Warning” to be in red, assuming you’ve +-pre-defined (or “initialized”) the color, red, this is +-what the DOCTYPE entry would look like: +-
        +- +- .DOCTYPE NAMED "Warning" red +- +-

        +- +-
        +-

        How to control DOCTYPE NAMED underlining

        +- +-

        +-By default, the string passed to DOCTYPE NAMED is +-underlined in the docheader, and on document-cover pages and cover +-(“title”) pages. (See the +-Introduction to covers +-for the difference between “doc cover” and +-“cover” pages.) +-

        +- +-

        +-You can use the macro DOCTYPE_UNDERLINE to set the weight of +-the underline and its distance from where the doctype-name appears +-in the docheader (doc covers and covers handle underlining of the +-doctype-name differently; see +-COVER_UNDERLINE), +-or simply toggle doctype underlining on or off. Mom’s default +-is to underline the doctype-name. +-

        +- +-

        +-The order of arguments is weight, optionally followed by +-gap, where “gap” is the distance from the +-baseline +-of the doctype-name to the underline. +-

        +- +-

        +-The weight argument is given in points, or fractions +-thereof, and must not have the +-unit of measure, +-p, appended. Like +-RULE_WEIGHT, +-weights must be greater than 0 and less than 100. Mom’s +-default for DOCTYPE NAMED underlining is 1/2 point. +-

        +- +-

        +-The gap argument can be given using any unit of measure, +-and must have the unit of measure appended to the argument. +-The distance of the gap is measured from the baseline of the +-DOCTYPE NAMED name to the upper edge of the underline. +-Mom’s default gap for named-doctype underlining is 2 points. +-

        +- +-

        +-As an example, suppose you want the doctype-name underlined in the +-docheader with a 2-point rule separated from the doctype-name by 3 +-points. The way to accomplish it is: +-
        +- +- .DOCTYPE_UNDERLINE 2 3p +- +-If you wanted the same thing, but were content with mom’s +-default gap of 2 points, ++

        ++

        ++Note: version 2.1 change +
        +- +- .DOCTYPE_UNDERLINE 2 +- +-would do the trick. +-

        +- +-

        +-If you merely want to toggle the underlining of +-the doctype-name in docheaders on or off, invoke +-.DOCTYPE_UNDERLINE by itself to turn the underlining on, +-or .DOCTYPE_UNDERLINE OFF (or NO, X, etc.) +-

        +- +-

        +-Please note that if you supply a weight to DOCTYPE_UNDERLINE, and +-optionally a gap, you also turn the underlining of the doctype-name +-in docheaders on; if this is not what you want, you must turn the +-underlining off manually afterwards. ++DOCTYPE NAMED "string" no longer accepts a color argument ++after "string". Setting the color of the string is now ++done with DOCTYPE_COLOR <color>. Default ++underscoring of "string" in the docheader and on covers ++has been removed. Use DOCTYPE_UNDERLINE, ++DOC_COVER_DOCTYPE_UNDERLINE and/or ++COVER_DOCTYPE_UNDERLINE to re-enable it. All three ++take the same arguments listed in the ++Underline style, rule weight ++section of ++Arguments to the control macros. +

        +
        + +@@ -2556,22 +2475,16 @@ + of the first line of type. +

        + +-
        +-

        +-Tip: +-Since no document processing happens until you invoke +-.START—including +-anything to do with docheaders—you can +-typeset your own docheader prior to START (if +-you don’t like the way mom does things) and use +-.DOCHEADER OFF with its optional distance +-argument to ensure that the body of your document starts where +-you want. You can even insert a PDF or PostScript image file (see +-PSPIC). +-and +-PDF_IMAGE). ++

        ++With DOCHEADER OFF, it is possible to create your own ++custom docheaders (after ++START) ++using mom’s typesetting macros. It is recommended that if you ++do create a custom docheader, you make ++.SHIM ++the last macro before the first item of your document (for ++example, .PP or .HEADING 1. PP...) +

        +-
        + + + +@@ -2599,8 +2512,7 @@ + by medium italic, same size as running text + Author(s) medium italic, same size as running text + +-(Document type) bold italic, underscored, 3 points larger than running text +- ++(Document type) bold italic, 3 points larger than running text + +
        + +@@ -2613,7 +2525,6 @@ + + Chapter <n> bold, 4 points larger than running text + Chapter Title bold italic, 4 points larger than running text +- + + + +@@ -2624,7 +2535,6 @@ + author and document type are what you supply with the + reference macros. + Any you leave out will not appear; mom will compensate: +- +

        + +
        +@@ -2633,44 +2543,48 @@ + If your DOCTYPE is CHAPTER and you have both “Chapter + <n>” and a “Chapter Title” (as above), mom + inserts a small amount of whitespace between them, equal to +-one-quarter of the leading in +-effect. If this doesn’t suit you, you can alter the space by +-including the +-inline escapes, +-\*[UP] +-or +-\*[DOWN], +-in the argument you pass to +-CHAPTER_TITLE, +-like this: +-
        +- +- .CHAPTER_TITLE "\*[DOWN 2p]Why Not Patent Calculus?" +- +-or +- +- .CHAPTER_TITLE "\*[UP 2p]Why Not Patent Calculus?" +- ++one-quarter of the ++leading ++in effect. If this doesn’t suit you, you can remove or alter ++the space with ++CHAPTER_TITLE_SPACE_BEFORE. +

        +
        + + + +-

        1. Change the starting position of the docheader

        ++

        1. Changes to the whole docheader

        ++ ++
        Change the starting position of the docheader
        + +

        + By default, a docheader starts on the same +@@ -2707,7 +2621,7 @@ +

        + + +-

        2. Change the quad direction of the docheader

        ++
        Change the quad direction of the docheader
        + +

        + By default, mom centers the docheader. If you’d prefer to +@@ -2718,7 +2632,7 @@ + C). +

        + +-

        3. Change the family of the entire docheader

        ++
        Change the family of the entire docheader
        + +

        + By default, mom sets the docheader in the same +@@ -2743,186 +2657,199 @@ + +

        + Please note that if you use DOCHEADER_FAMILY, you can still alter +-the family of individual parts of the docheader with the macros +-listed +-here. ++the family of individual parts of the docheader. +

        + +-

        4. Change the family of individual docheader elements

        ++
        Change the color of the entire docheader
        + +

        +-The following macros let you change the +-family +-of each docheader element separately: +-

        +-
          +-
        • Macro: TITLE_FAMILY <family>
        • +-
        • Macro: CHAPTER_TITLE_FAMILY <family>
        • +-
        • Macro: SUBTITLE_FAMILY <family>
        • +-
        • Macro: AUTHOR_FAMILY <family>
        • +-
        • Macro: DOCTYPE_FAMILY <family> +- (if DOCTYPE is NAMED) +-
        • +-
        +- +-

        +-Simply pass the appropriate macro the family you want, just as you +-would with +-FAMILY. +-

        +- +-

        5. Change the font of individual docheader elements

        +- +-

        +-The following macros let you change the +-font +-of each docheader element separately: +-

        +-
          +-
        • Macro: TITLE_FONT R | B | I | BI
        • +-
        • Macro: CHAPTER_TITLE_FONT R | B | I | BI
        • +-
        • Macro: SUBTITLE_FONT R | B | I | BI
        • +-
        • Macro: AUTHOR_FONT R | B | I | BI
        • +-
        • Macro: DOCTYPE_FONT R | B | I | BI +- (if DOCTYPE is NAMED) +-
        • +-
        +- +-

        +-Simply pass the appropriate macro the font you want. R, B, +-I and BI have the same meaning as they do for +-FT. You may also use any of the +-style extensions +-provided by mom. +-

        +- +-

        6. Adjust the size of individual docheader elements

        +- +-

        +-The following macros let you adjust the point size of each docheader +-element separately. +-

        +- +-

        +-Mom calculates the point size of docheader elements from the point +-size of paragraphs in running text, so you must prepend a + or - +-sign to the argument. Points is assumed as the +-unit of measure, +-so there’s no need to append a unit to the argument. +-Fractional point sizes are allowed. ++The default color for docheaders is black, as you’d expect. ++If you wish to change it, use ++.DOCHEADER_COLOR <color>, where ++ <color> is a color pre-initialized with ++XCOLOR ++or ++NEWCOLOR. +

        + +-
          +-
        • Macro: TITLE_SIZE <+/-points> +-
          +-    default = +3.5 (+4 if docheader title is "Chapter <n>") +-
        • +-
        • Macro: CHAPTER_TITLE_SIZE <+/-points> +-
          +-    default = +4 +-
        • +-
        • Macro: SUBTITLE_SIZE <+/-points> +-
          +-    default = +0 +-
        • +-
        • Macro: AUTHOR_SIZE <+/-points> +-
          +-    default = +0 +-
        • +-
        • Macro: DOCTYPE_SIZE <+/-points> +- (if DOCTYPE is NAMED) +-
          +-    default = +3 +-
        • +-
        ++
        Change the leading of the entire docheader
        + +

        +-Simply pass the appropriate macro the size adjustment you want. ++By default, mom uses the leading in effect for ++running text ++for docheaders. If you want to increase or ++decrease the overall docheader leading, use ++.DOCHEADER_LEAD +|-<amount>, where ++<amount> is the number of ++points ++by which to make the adjustment. +

        + +-

        7. Adjust the docheader leading

        ++

        2. Part by part changes

        + +

        +-The +-leading +-of docheaders is the same as running text. If you’d like your +-docheaders to have a different leading, say, 2 points more than the +-lead of running text, use: ++Whenever you want to change the style parameters for any part of ++the docheader, simply join the name of the part to the parameter ++you wish to change using an underscore, then supply any necessary ++arguments. The subitle double-underlined? No problem. +
        + +- .DOCHEADER_LEAD +2 ++ .SUBTITLE_UNDERLINE DOUBLE + +-Since the leading of docheaders is calculated from the lead of running +-text, a + or - sign is required before the argument (how much to add +-or subtract from the lead of running text). No +-unit of measure +-is required; points is assumed. +-

        +- +-

        8. Change the colour of the entire docheader

        +- +-

        +-If you want to colourize the entire docheader: ++Author in red? +
        + +- .DOCHEADER_COLOR <color name> ++ .AUTHOR_COLOR red ++ ++Title in smallcaps? ++ ++ .TITLE_SMALLCAPS + +-You must pre-define (or “initialize”) the colour with +-NEWCOLOR +-or +-XCOLOR. +-

        +- +- +-

        9. Change the colour of the docheader elements individually

        +- +-

        +-The following macros let you change the colour of each +-docheader element separately. You must pre-define (or +-“initialize”) the colour with +-NEWCOLOR +-or +-XCOLOR. +

        +-
          +-
        • Macro: TITLE_COLOR <colorname>
        • +-
        • Macro: CHAPTER_TITLE_COLOR <colorname> +-
            +-
          • Note: CHAPTER_TITLE_COLOR is needed only if you supply both a +- CHAPTER +- reference macro and a +- CHAPTER_TITLE +- macro. Otherwise, TITLE_COLOR takes care of colorizing the +- chapter header. +-
          • +-
        • +-
        • Macro: SUBTITLE_COLOR <colorname>
        • +-
        • Macro: ATTRIBUTE_COLOR <colorname> +- (the “by” string preceding author[s] name[s]) +-
        • +-
        • Macro: AUTHOR_COLOR <colorname>
        • +-
        • Macro: DOCTYPE_COLOR <colorname> +- (if DOCTYPE is NAMED) +-
        • +-
        + +-

        +-It is not recommended that you embed colour (with the +-inline escape, +-\*[<colorname>]) +-in the strings passed to TITLE, CHAPTER_TITLE, SUBTITLE, AUTHOR or +-the name you give DOCTYPE NAMED. The strings passed to +-these macros are used to generate page +-headers +-and +-footers, +-with the result that an embedded colour will cause the string to be +-colourized in headers and/or footers as well. (If you want headers +-or footers colourized, or parts thereof, use the header/footer +-control macros.) ++

        ++

        ++Note: ++Use ATTRIBUTE as the part name for the attribution string ++(“by”) that precedes the author, and DOCTYPE ++as the name for the string passed to DOCTYPE NAMED "string". ++

        ++
        ++ ++
        List of parameters with arguments
        ++ ++
        ++
        _FAMILY
        ++
        ++ Takes the same argument as FAMILY. ++
        ++
        _FONT
        ++
        ++ Takes the same argument as FT. ++
        ++
        _SIZE
        ++
        ++ Takes a + or - value relative to the size of ++ running text. ++
        ++
        _COLOR
        ++
        ++ Takes the same argument as COLOR. ++ Colors should be pre-initialized with ++ XCOLOR ++ or ++ NEWCOLOR. ++
        ++
        _LEAD
        ++
        ++ Takes an absolute leading value, i.e. not relative to the ++ overall leading of the docheader. The leading applies to ++ multiple lines of type within the same docheader part, e.g. ++ several authors or a long title that must be split over two ++ lines. No ++ unit of measure ++ is required; ++ points ++ is assumed. ++
        ++
        _SPACE_BEFORE
        ++
        ++ Takes a numeric value with a ++ unit of measure ++ appended to it. The value may be negative. This allows you ++ to adjust the whitespace before a docheader part, for example ++ if you want more whitespace between the title and the author. ++ ++ Note that TITLE does not have a _SPACE_BEFORE ++ parameter; use ++ DOCHEADER_ADVANCE ++ to move the title further down on the page. ++ ++
        ++
        _CAPS
        ++
        ++ Capitalizes the entire docheader part. No argument is ++ required. ++
        ++
        _NO_CAPS
        ++
        ++ Only used if you need to reverse the sense of _CAPS, as ++ can sometimes happen when ++ collating ++ documents that have differing docheader style requirements. ++
        ++
        _SMALLCAPS
        ++
        ++ Set the entire docheader part in smallcaps. No argument is ++ required. ++
        ++
        _NO_SMALLCAPS
        ++
        ++ Only used if you need to reverse the sense of ++ _SMALLCAPS, as can sometimes happen when ++ collating ++ documents that have differing docheader style requirements. ++
        ++
        _UNDERSCORE
        ++
        ++ With no argument, underscores the docheader part. With a ++ single, possibly decimal numeric argument, sets the weight of ++ the underscore. A second numeric argument to which a ++ unit of measure ++ is appended (most likely p) sets the distance ++ between the baseline and the underscore. ++ ++ If the argument DOUBLE is given, double underscores ++ the docheader part. With a single, possibly decimal numeric ++ argument afterwards, sets the weight of the underscore rules. ++ A third numeric argument to which a ++ unit of measure ++ is appended (most likely p) sets the distance ++ between the baseline and the first underscore rule. A fourth ++ numeric argument to which a unit of measure is appended sets ++ the distance between the two underscore rules. ++ ++ ++ You may give _UNDERLINE as the parameter instead of ++ _UNDERSCORE if you prefer. ++ ++
        ++
        NO_UNDERSCORE
        ++
        ++ Only used if you need to reverse the sense of ++ _UNDERSCORE, as can sometimes happen when ++ collating ++ documents that have differing docheader style requirements. ++
        ++
        ++ ++
        Grouping part/parameter changes
        ++ ++

        ++If you want to change several parameters for a particular docheader ++part, you may group the changes together in a single macro by ++joining the name of the part to STYLE with an underscore, ++for example TITLE_STYLE or AUTHOR_STYLE. ++The following demonstrates: ++ ++ .CHAPTER_TITLE_STYLE \ ++ FAMILY T \ ++ SIZE +4 \ ++ UNDERSCORE 2 \ ++ SMALLCAPS ++ ++Notice the use of the backslash character, which is required after ++the macro name and all parameters except the last. Grouping reduces ++clutter and the finger fatigue caused by entering ++ ++ .CHAPTER_TITLE_FAMILY T ++ .CHAPTER_TITLE_SIZE +4 ++ .CHAPTER_TITLE_UNDERSCORE 2 ++ .CHAPTER_TITLE_SMALLCAPS ++ +

        + +-

        10. Change the attribution string (“by”)

        ++

        3. Changing or removing the attribution string (“by”)

        + +

        + If you’re not writing in English, you can change what mom +@@ -2933,7 +2860,7 @@ + + changes “by” to “par”. ATTRIBUTE_STRING + can also be used, for example, to make the attribution read +-"Edited by". ++“Edited by”. +

        + +

        +@@ -2978,24 +2905,6 @@ + arguments, is sufficient. +

        + +-
        +-

        +-Note: +-The type specs for the attribution line in docheaders are the +-same as for the author line. Although it’s highly unlikely +-you’ll want the attribution line in a different family, font, +-or point size, you can make such changes using +-inline escapes +-in the argument to ATTRIBUTE_STRING. For example, +-
        +- +- .ATTRIBUTE_STRING "\f[HBI]\*[SIZE -2p] by \*[SIZE +2p]\*[PREV]" +- +-would set “by” in Helvetica bold italic, 2 points +-smaller than normal. +-

        +-
        +- +

        + + +@@ -3151,7 +3060,7 @@ + it left (assuming the type is justified or quad left), and moves over + to the top of the next column. If the column happens to be the last + (rightmost) one on the page, mom starts a new page +-at the "column 1" position. This is the macro to use when ++at the “column 1” position. This is the macro to use when + you want to start a new column after the end of a paragraph. +

        + +@@ -3313,12 +3222,12 @@ + element tag is entered, the font reverts + to the current default for the new tag. + +- N.B. — \•[SLANT] and \•[BOLDER] affect ++ N.B. — \*[SLANT] and \*[BOLDER] affect + paragraph text, and remain in effect for all + paragraphs until turned off. If you want to + use them in a macro that takes a string + argument, include the escape in the string. +- \•[COND] and \•[EXT] behave similarly. ++ \*[COND] and \*[EXT] behave similarly. + + PT_SIZE •Changes point size for the duration of the + current tag only. As soon as another document +@@ -3340,9 +3249,7 @@ + track when you’re ready to return to the + document’s default leading. + +- +- +- AUTOLEAD •Invoked before START, sets the overall document ++ AUTOLEAD •Invoked before START, sets the overall document + leading as a function of the overall document + point size (ie the point size used in paragraphs); + subsequently disabled after START, except for calls +@@ -3822,9 +3729,6 @@ +

        + + +- +-

        +- + +
    + +diff -Nuar groff-1.22.3.old/contrib/mom/momdoc/goodies.html groff-1.22.3/contrib/mom/momdoc/goodies.html +--- groff-1.22.3.old/contrib/mom/momdoc/goodies.html 2014-11-04 10:38:35.613519146 +0200 ++++ groff-1.22.3/contrib/mom/momdoc/goodies.html 2015-04-23 20:57:03.000000000 +0300 +@@ -2,7 +2,7 @@ + + +
    +@@ -1433,7 +1448,7 @@ + you can change it by invoking SUPERSCRIPT_RAISE_AMOUNT with the + amount you want them raised. A + unit of measure +-must be appended directly to the amount. Thus, you want ++must be appended directly to the amount. Thus, if you want + superscripts raised by 3 + points + instead of 1/3 em, you’d do +diff -Nuar groff-1.22.3.old/contrib/mom/momdoc/graphical.html groff-1.22.3/contrib/mom/momdoc/graphical.html +--- groff-1.22.3.old/contrib/mom/momdoc/graphical.html 2014-11-04 10:38:35.613519146 +0200 ++++ groff-1.22.3/contrib/mom/momdoc/graphical.html 2015-04-23 20:57:03.000000000 +0300 +@@ -2,7 +2,7 @@ + + +

    3. Header/footer vertical placement and spacing

    +@@ -2071,16 +2133,25 @@ +

    + See + Arguments to the control macros. ++
    ++The following control macros may also be ++grouped ++using PAGENUMBER_STYLE.* +

    + +-.PAGENUM_FAMILY default = prevailing document family; default is Times Roman ++.PAGENUM_FAMILY default = prevailing document family + .PAGENUM_FONT default = roman +-.PAGENUM_SIZE default = 0 (ie same size as paragraph text) ++.PAGENUM_SIZE default = +0 (ie same size as paragraph text) + .PAGENUM_COLOR default = black + +
    + +-

    2. Page number position

    ++

    ++*Note: Do not confuse PAGENUMBER_STYLE with ++PAGENUM_STYLE. ++

    ++ ++

    2. Page number position

    + +
    + Macro: PAGENUM_POS TOP | BOTTOM  LEFT | CENTER | RIGHT +diff -Nuar groff-1.22.3.old/contrib/mom/momdoc/images.html groff-1.22.3/contrib/mom/momdoc/images.html +--- groff-1.22.3.old/contrib/mom/momdoc/images.html 2014-11-04 10:38:35.614519134 +0200 ++++ groff-1.22.3/contrib/mom/momdoc/images.html 2015-04-23 20:57:03.000000000 +0300 +@@ -2,7 +2,7 @@ + ++ ++
    ++

    Smallcaps

    ++
    ++ ++
    ++Macro: SMALLCAPS <toggle> ++
    ++ ++

    ++To begin setting type in pseudo-smallcaps, simply invoke ++.SMALLCAPS. When you no longer want them, invoke ++SMALLCAPS OFF (or END, STOP, ++DONE, etc). If you are currently in a ++no-fill mode, ++(i.e. .LEFT, .CENTER, or .RIGHT) ++and you want the smallcaps to continue on the same line, ++append a \c to the line, like this ++
    ++ ++ A line of type\c ++ .SMALLCAPS ++ with a few words in smallcaps. ++ .SMALLCAPS OFF ++ ++The line preceding .SMALLCAPS OFF should also have a ++\c appended to it if you wish it to continue unbroken. ++

    ++ ++
    ++

    ++Note: ++SMALLCAPS does not have an inline equivalent to ++\*[UC] / \*[LC]. ++Furthermore, if you’re using the ++document processing macros ++with ++PRINTSTYLE TYPEWRITE, ++mom ignores SMALLCAPS. ++

    ++ ++

    ++Additionally, be aware that no automatic ++kerning ++takes place while pseudo-smallcaps are in effect. ++

    ++
    ++ ++
    ++

    Set size, weight, and width of smallcaps

    ++
    ++ ++
    ++Macro: SMALLCAPS_STYLE SIZE <percentage> WEIGHT_ADJ <percentage> EXTEND <percentage> ++
    ++ ++

    ++True smallcaps are not a font effect, but, like designer cuts of ++bold, condensed, and extended, actual fonts provided with some ++families. It is highly recommended that you acquire real smallcaps ++fonts rather than relying on mom's pseudo version. ++

    ++ ++

    ++To achieve a reasonable facsimile of designer-cut small fonts, mom ++needs to know the percentage of regular caps at a given point size ++by which to reduce the small caps. To make adjustments for the ++difference in weight and width of the smaller caps, she also needs ++to know by how much to embolden (“fatten”) the ++smallcaps, and by how much to increase their width. ++

    ++ ++

    ++All three arguments to SMALLCAPS_STYLE reflect a ++percentage of the point size in effect when ++SMALLCAPS ++is invoked. Mom’s defaults for pseudo-smallcaps are: ++
    ++ ++ SIZE = 74% ++ WEIGHT_ADJ = .3% ++ EXTEND = 5% ++ ++To change any or all of the defaults, you might enter ++
    ++ ++ .SMALLCAPS_STYLE SIZE 80 WEIGHT_ADJ .25 EXTEND 3 ++ ++or, more readably, ++
    ++ ++ .SMALLCAPS_STYLE ++ SIZE 80 \ ++ WEIGHT_ADJ .25 \ ++ EXTEND 3 ++ ++Note that you do not have to give SMALLCAPS_STYLE all three ++arguments, and that the arguments may be entered in any order. Any ++arguments you omit will remain at their former value. ++

    ++ +

    + + +diff -Nuar groff-1.22.3.old/contrib/mom/momdoc/using.html groff-1.22.3/contrib/mom/momdoc/using.html +--- groff-1.22.3.old/contrib/mom/momdoc/using.html 2014-11-04 10:38:35.616519109 +0200 ++++ groff-1.22.3/contrib/mom/momdoc/using.html 2015-04-23 20:57:03.000000000 +0300 +@@ -2,7 +2,7 @@ + | in |<-- +- |<-----------ll------------>| +- +----+----+----------------------+----+ +- | : : : | +- +----+----+----------------------+----+ +- -->| po |<-- +- |<--------paper width---------------->| +- +-These dimensions are: +- +-'po' +- "Page offset" - this is the leftmost position of text on the final +- output, defining the "left margin". +- +-'in' +- "Indentation" - this is the distance from the left margin where +- text is printed. +- +-'ll' +- "Line length" - this is the distance from the left margin to right +- margin. +- +- A simple demonstration: +- +- .ll 3i +- This is text without indentation. +- The line length has been set to 3\~inch. +- .in +.5i +- .ll -.5i +- Now the left and right margins are both increased. +- .in +- .ll +- Calling .in and .ll without parameters restore +- the previous values. +- +- Result: +- +- This is text without indenta- +- tion. The line length has +- been set to 3 inch. +- Now the left and +- right margins are +- both increased. +- Calling .in and .ll without +- parameters restore the previ- +- ous values. +- +- -- Request: .po [offset] +- -- Request: .po +offset +- -- Request: .po -offset +- -- Register: \n[.o] +- Set horizontal page offset to OFFSET (or increment or decrement the +- current value by OFFSET). Note that this request does not cause a +- break, so changing the page offset in the middle of text being +- filled may not yield the expected result. The initial value is 1i. +- For TTY output devices, it is set to 0 in the startup file +- 'troffrc'; the default scaling indicator is 'm' (and not 'v' as +- incorrectly documented in the original UNIX troff manual). +- +- The current page offset can be found in the read-only number +- register '.o'. +- +- If 'po' is called without an argument, the page offset is reset to +- the previous value before the last call to 'po'. +- +- .po 3i +- \n[.o] +- => 720 +- .po -1i +- \n[.o] +- => 480 +- .po +- \n[.o] +- => 720 +- +- -- Request: .in [indent] +- -- Request: .in +indent +- -- Request: .in -indent +- -- Register: \n[.i] +- Set indentation to INDENT (or increment or decrement the current +- value by INDENT). This request causes a break. Initially, there +- is no indentation. +- +- If 'in' is called without an argument, the indentation is reset to +- the previous value before the last call to 'in'. The default +- scaling indicator is 'm'. +- +- The indentation is associated with the current environment (*note +- Environments::). +- +- If a negative indentation value is specified (which is not +- allowed), 'gtroff' emits a warning of type 'range' and sets the +- indentation to zero. +- +- The effect of 'in' is delayed until a partially collected line (if +- it exists) is output. A temporary indentation value is reset to +- zero also. +- +- The current indentation (as set by 'in') can be found in the +- read-only number register '.i'. +- +- -- Request: .ti offset +- -- Request: .ti +offset +- -- Request: .ti -offset +- -- Register: \n[.in] +- Temporarily indent the next output line by OFFSET. If an increment +- or decrement value is specified, adjust the temporary indentation +- relative to the value set by the 'in' request. +- +- This request causes a break; its value is associated with the +- current environment (*note Environments::). The default scaling +- indicator is 'm'. A call of 'ti' without an argument is ignored. +- +- If the total indentation value is negative (which is not allowed), +- 'gtroff' emits a warning of type 'range' and sets the temporary +- indentation to zero. 'Total indentation' is either OFFSET if +- specified as an absolute value, or the temporary plus normal +- indentation, if OFFSET is given as a relative value. +- +- The effect of 'ti' is delayed until a partially collected line (if +- it exists) is output. +- +- The read-only number register '.in' is the indentation that applies +- to the current output line. +- +- The difference between '.i' and '.in' is that the latter takes into +- account whether a partially collected line still uses the old +- indentation value or a temporary indentation value is active. +- +- -- Request: .ll [length] +- -- Request: .ll +length +- -- Request: .ll -length +- -- Register: \n[.l] +- -- Register: \n[.ll] +- Set the line length to LENGTH (or increment or decrement the +- current value by LENGTH). Initially, the line length is set to +- 6.5i. The effect of 'll' is delayed until a partially collected +- line (if it exists) is output. The default scaling indicator is +- 'm'. +- +- If 'll' is called without an argument, the line length is reset to +- the previous value before the last call to 'll'. If a negative +- line length is specified (which is not allowed), 'gtroff' emits a +- warning of type 'range' and sets the line length to zero. +- +- The line length is associated with the current environment (*note +- Environments::). +- +- The current line length (as set by 'll') can be found in the +- read-only number register '.l'. The read-only number register +- '.ll' is the line length that applies to the current output line. +- +- Similar to '.i' and '.in', the difference between '.l' and '.ll' is +- that the latter takes into account whether a partially collected +- line still uses the old line length value. +- +- +-File: groff.info, Node: Line Control, Next: Page Layout, Prev: Line Layout, Up: gtroff Reference +- +-5.14 Line Control +-================= +- +-It is important to understand how 'gtroff' handles input and output +-lines. +- +- Many escapes use positioning relative to the input line. For +-example, this +- +- This is a \h'|1.2i'test. +- +- This is a +- \h'|1.2i'test. +- +-produces +- +- This is a test. +- +- This is a test. +- +- The main usage of this feature is to define macros that act exactly +-at the place where called. +- +- .\" A simple macro to underline a word +- .de underline +- . nop \\$1\l'|0\[ul]' +- .. +- +-In the above example, '|0' specifies a negative distance from the +-current position (at the end of the just emitted argument '\$1') back to +-the beginning of the input line. Thus, the '\l' escape draws a line +-from right to left. +- +- 'gtroff' makes a difference between input and output line +-continuation; the latter is also called "interrupting" a line. +- +- -- Escape: \ +- -- Escape: \c +- -- Register: \n[.int] +- Continue a line. '\' (this is a backslash at the end of a +- line immediately followed by a newline) works on the input level, +- suppressing the effects of the following newline in the input. +- +- This is a \ +- .test +- => This is a .test +- +- The '|' operator is also affected. +- +- '\c' works on the output level. Anything after this escape on the +- same line is ignored except '\R', which works as usual. Anything +- before '\c' on the same line is appended to the current partial +- output line. The next non-command line after an interrupted line +- counts as a new input line. +- +- The visual results depend on whether no-fill mode is active. +- +- * If no-fill mode is active (using the 'nf' request), the next +- input text line after '\c' is handled as a continuation of the +- same input text line. +- +- .nf +- This is a \c +- test. +- => This is a test. +- +- * If fill mode is active (using the 'fi' request), a word +- interrupted with '\c' is continued with the text on the next +- input text line, without an intervening space. +- +- This is a te\c +- st. +- => This is a test. +- +- Note that an intervening control line that causes a break is +- stronger than '\c', flushing out the current partial line in the +- usual way. +- +- The '.int' register contains a positive value if the last output +- line was interrupted with '\c'; this is associated with the current +- environment (*note Environments::). +- +- +-File: groff.info, Node: Page Layout, Next: Page Control, Prev: Line Control, Up: gtroff Reference +- +-5.15 Page Layout +-================ +- +-'gtroff' provides some very primitive operations for controlling page +-layout. +- +- -- Request: .pl [length] +- -- Request: .pl +length +- -- Request: .pl -length +- -- Register: \n[.p] +- Set the "page length" to LENGTH (or increment or decrement the +- current value by LENGTH). This is the length of the physical +- output page. The default scaling indicator is 'v'. +- +- The current setting can be found in the read-only number register +- '.p'. +- +- Note that this only specifies the size of the page, not the top and +- bottom margins. Those are not set by 'gtroff' directly. *Note +- Traps::, for further information on how to do this. +- +- Negative 'pl' values are possible also, but not very useful: No +- trap is sprung, and each line is output on a single page (thus +- suppressing all vertical spacing). +- +- If no argument or an invalid argument is given, 'pl' sets the page +- length to 11i. +- +- 'gtroff' provides several operations that help in setting up top and +-bottom titles (or headers and footers). +- +- -- Request: .tl 'left'center'right' +- Print a "title line". It consists of three parts: a left justified +- portion, a centered portion, and a right justified portion. The +- argument separator ''' can be replaced with any character not +- occurring in the title line. The '%' character is replaced with +- the current page number. This character can be changed with the +- 'pc' request (see below). +- +- Without argument, 'tl' is ignored. +- +- Some notes: +- +- * The line length set by the 'll' request is not honoured by +- 'tl'; use the 'lt' request (described below) instead, to +- control line length for text set by 'tl'. +- +- * A title line is not restricted to the top or bottom of a page. +- +- * 'tl' prints the title line immediately, ignoring a partially +- filled line (which stays untouched). +- +- * It is not an error to omit closing delimiters. For example, +- '.tl /foo' is equivalent to '.tl /foo///': It prints a title +- line with the left justified word 'foo'; the centered and +- right justfied parts are empty. +- +- * 'tl' accepts the same parameter delimiting characters as the +- '\A' escape; see *note Escapes::. +- +- -- Request: .lt [length] +- -- Request: .lt +length +- -- Request: .lt -length +- -- Register: \n[.lt] +- The title line is printed using its own line length, which is +- specified (or incremented or decremented) with the 'lt' request. +- Initially, the title line length is set to 6.5i. If a negative +- line length is specified (which is not allowed), 'gtroff' emits a +- warning of type 'range' and sets the title line length to zero. +- The default scaling indicator is 'm'. If 'lt' is called without an +- argument, the title length is reset to the previous value before +- the last call to 'lt'. +- +- The current setting of this is available in the '.lt' read-only +- number register; it is associated with the current environment +- (*note Environments::). +- +- -- Request: .pn page +- -- Request: .pn +page +- -- Request: .pn -page +- -- Register: \n[.pn] +- Change (increase or decrease) the page number of the _next_ page. +- The only argument is the page number; the request is ignored +- without a parameter. +- +- The read-only number register '.pn' contains the number of the next +- page: either the value set by a 'pn' request, or the number of the +- current page plus 1. +- +- -- Request: .pc [char] +- Change the page number character (used by the 'tl' request) to a +- different character. With no argument, this mechanism is disabled. +- Note that this doesn't affect the number register '%'. +- +- *Note Traps::. +- +- +-File: groff.info, Node: Page Control, Next: Fonts and Symbols, Prev: Page Layout, Up: gtroff Reference +- +-5.16 Page Control +-================= +- +- -- Request: .bp [page] +- -- Request: .bp +page +- -- Request: .bp -page +- -- Register: \n[%] +- Stop processing the current page and move to the next page. This +- request causes a break. It can also take an argument to set +- (increase, decrease) the page number of the next page (which +- actually becomes the current page after 'bp' has finished). The +- difference between 'bp' and 'pn' is that 'pn' does not cause a +- break or actually eject a page. *Note Page Layout::. +- +- .de newpage \" define macro +- 'bp \" begin page +- 'sp .5i \" vertical space +- .tl 'left top'center top'right top' \" title +- 'sp .3i \" vertical space +- .. \" end macro +- +- 'bp' has no effect if not called within the top-level diversion +- (*note Diversions::). +- +- The read-write register '%' holds the current page number. +- +- The number register '.pe' is set to 1 while 'bp' is active. *Note +- Page Location Traps::. +- +- -- Request: .ne [space] +- It is often necessary to force a certain amount of space before a +- new page occurs. This is most useful to make sure that there is +- not a single "orphan" line left at the bottom of a page. The 'ne' +- request ensures that there is a certain distance, specified by the +- first argument, before the next page is triggered (see *note +- Traps::, for further information). The default scaling indicator +- for 'ne' is 'v'; the default value of SPACE is 1v if no argument is +- given. +- +- For example, to make sure that no fewer than 2 lines get orphaned, +- do the following before each paragraph: +- +- .ne 2 +- text text text +- +- 'ne' then automatically causes a page break if there is space for +- one line only. +- +- -- Request: .sv [space] +- -- Request: .os +- 'sv' is similar to the 'ne' request; it reserves the specified +- amount of vertical space. If the desired amount of space exists +- before the next trap (or the bottom page boundary if no trap is +- set), the space is output immediately (ignoring a partially filled +- line, which stays untouched). If there is not enough space, it is +- stored for later output via the 'os' request. The default value +- is 1v if no argument is given; the default scaling indicator is +- 'v'. +- +- Both 'sv' and 'os' ignore no-space mode. While the 'sv' request +- allows negative values for SPACE, 'os' ignores them. +- +- -- Register: \n[nl] +- This register contains the current vertical position. If the +- vertical position is zero and the top of page transition hasn't +- happened yet, 'nl' is set to negative value. 'gtroff' itself does +- this at the very beginning of a document before anything has been +- printed, but the main usage is to plant a header trap on a page if +- this page has already started. +- +- Consider the following: +- +- .de xxx +- . sp +- . tl ''Header'' +- . sp +- .. +- . +- First page. +- .bp +- .wh 0 xxx +- .nr nl (-1) +- Second page. +- +- Result: +- +- First page. +- +- ... +- +- Header +- +- Second page. +- +- ... +- +- Without resetting 'nl' to a negative value, the just planted trap +- would be active beginning with the _next_ page, not the current +- one. +- +- *Note Diversions::, for a comparison with the '.h' and '.d' +- registers. +- +- +-File: groff.info, Node: Fonts and Symbols, Next: Sizes, Prev: Page Control, Up: gtroff Reference +- +-5.17 Fonts and Symbols +-====================== +- +-'gtroff' can switch fonts at any point in the text. +- +- The basic set of fonts is 'R', 'I', 'B', and 'BI'. These are Times +-Roman, Italic, Bold, and Bold Italic. For non-TTY devices, there is +-also at least one symbol font that contains various special symbols +-(Greek, mathematics). +- +-* Menu: +- +-* Changing Fonts:: +-* Font Families:: +-* Font Positions:: +-* Using Symbols:: +-* Character Classes:: +-* Special Fonts:: +-* Artificial Fonts:: +-* Ligatures and Kerning:: +- +- +-File: groff.info, Node: Changing Fonts, Next: Font Families, Prev: Fonts and Symbols, Up: Fonts and Symbols +- +-5.17.1 Changing Fonts +---------------------- +- +- -- Request: .ft [font] +- -- Escape: \ff +- -- Escape: \f(fn +- -- Escape: \f[font] +- -- Register: \n[.sty] +- The 'ft' request and the '\f' escape change the current font to +- FONT (one-character name F, two-character name FN). +- +- If FONT is a style name (as set with the 'sty' request or with the +- 'styles' command in the 'DESC' file), use it within the current +- font family (as set with the 'fam' request, '\F' escape, or with +- the 'family' command in the 'DESC' file). +- +- It is not possible to switch to a font with the name 'DESC' +- (whereas this name could be used as a style name; however, this is +- not recommended). +- +- With no argument or using 'P' as an argument, '.ft' switches to the +- previous font. Use '\f[]' to do this with the escape. The old +- syntax forms '\fP' or '\f[P]' are also supported. +- +- Fonts are generally specified as upper-case strings, which are +- usually 1 to 4 characters representing an abbreviation or acronym +- of the font name. This is no limitation, just a convention. +- +- The example below produces two identical lines. +- +- eggs, bacon, +- .ft B +- spam +- .ft +- and sausage. +- +- eggs, bacon, \fBspam\fP and sausage. +- +- Note that '\f' doesn't produce an input token in 'gtroff'. As a +- consequence, it can be used in requests like 'mc' (which expects a +- single character as an argument) to change the font on the fly: +- +- .mc \f[I]x\f[] +- +- The current style name is available in the read-only number +- register '.sty' (this is a string-valued register); if the current +- font isn't a style, the empty string is returned. It is associated +- with the current environment. +- +- *Note Font Positions::, for an alternative syntax. +- +- -- Request: .ftr f [g] +- Translate font F to font G. Whenever a font named F is referred to +- in a '\f' escape sequence, in the 'F' and 'S' conditional +- operators, or in the 'ft', 'ul', 'bd', 'cs', 'tkf', 'special', +- 'fspecial', 'fp', or 'sty' requests, font G is used. If G is +- missing or equal to F the translation is undone. +- +- Note that it is not possible to chain font translations. Example: +- +- .ftr XXX TR +- .ftr XXX YYY +- .ft XXX +- => warning: can't find font `XXX' +- +- -- Request: .fzoom f [zoom] +- -- Register: \n[.zoom] +- Set magnification of font F to factor ZOOM, which must be a +- non-negative integer multiple of 1/1000th. This request is useful +- to adjust the optical size of a font in relation to the others. In +- the example below, font 'CR' is magnified by 10% (the zoom factor +- is thus 1.1). +- +- .fam P +- .fzoom CR 1100 +- .ps 12 +- Palatino and \f[CR]Courier\f[] +- +- A missing or zero value of ZOOM is the same as a value of 1000, +- which means no magnification. F must be a real font name, not a +- style. +- +- Note that the magnification of a font is completely transparent to +- troff; a change of the zoom factor doesn't cause any effect except +- that the dimensions of glyphs, (word) spaces, kerns, etc., of the +- affected font are adjusted accordingly. +- +- The zoom factor of the current font is available in the read-only +- number register '.zoom', in multiples of 1/1000th. It returns zero +- if there is no magnification. +- +- +-File: groff.info, Node: Font Families, Next: Font Positions, Prev: Changing Fonts, Up: Fonts and Symbols +- +-5.17.2 Font Families +--------------------- +- +-Due to the variety of fonts available, 'gtroff' has added the concept of +-"font families" and "font styles". The fonts are specified as the +-concatenation of the font family and style. Specifying a font without +-the family part causes 'gtroff' to use that style of the current family. +- +- Currently, fonts for the devices '-Tps', '-Tpdf', '-Tdvi', '-Tlj4', +-'-Tlbp', and the X11 fonts are set up to this mechanism. By default, +-'gtroff' uses the Times family with the four styles 'R', 'I', 'B', and +-'BI'. +- +- This way, it is possible to use the basic four fonts and to select a +-different font family on the command line (*note Groff Options::). +- +- -- Request: .fam [family] +- -- Register: \n[.fam] +- -- Escape: \Ff +- -- Escape: \F(fm +- -- Escape: \F[family] +- -- Register: \n[.fn] +- Switch font family to FAMILY (one-character name F, two-character +- name FM). If no argument is given, switch back to the previous +- font family. Use '\F[]' to do this with the escape. Note that +- '\FP' doesn't work; it selects font family 'P' instead. +- +- The value at start-up is 'T'. The current font family is available +- in the read-only number register '.fam' (this is a string-valued +- register); it is associated with the current environment. +- +- spam, +- .fam H \" helvetica family +- spam, \" used font is family H + style R = HR +- .ft B \" family H + style B = font HB +- spam, +- .fam T \" times family +- spam, \" used font is family T + style B = TB +- .ft AR \" font AR (not a style) +- baked beans, +- .ft R \" family T + style R = font TR +- and spam. +- +- Note that '\F' doesn't produce an input token in 'gtroff'. As a +- consequence, it can be used in requests like 'mc' (which expects a +- single character as an argument) to change the font family on the +- fly: +- +- .mc \F[P]x\F[] +- +- The '.fn' register contains the current "real font name" of the +- current font. This is a string-valued register. If the current +- font is a style, the value of '\n[.fn]' is the proper concatenation +- of family and style name. +- +- -- Request: .sty n style +- Associate STYLE with font position N. A font position can be +- associated either with a font or with a style. The current font is +- the index of a font position and so is also either a font or a +- style. If it is a style, the font that is actually used is the +- font which name is the concatenation of the name of the current +- family and the name of the current style. For example, if the +- current font is 1 and font position 1 is associated with style 'R' +- and the current font family is 'T', then font 'TR' is used. If the +- current font is not a style, then the current family is ignored. +- If the requests 'cs', 'bd', 'tkf', 'uf', or 'fspecial' are applied +- to a style, they are instead applied to the member of the current +- family corresponding to that style. +- +- N must be a non-negative integer value. +- +- The default family can be set with the '-f' option (*note Groff +- Options::). The 'styles' command in the 'DESC' file controls which +- font positions (if any) are initially associated with styles rather +- than fonts. For example, the default setting for POSTSCRIPT fonts +- +- styles R I B BI +- +- is equivalent to +- +- .sty 1 R +- .sty 2 I +- .sty 3 B +- .sty 4 BI +- +- 'fam' and '\F' always check whether the current font position is +- valid; this can give surprising results if the current font +- position is associated with a style. +- +- In the following example, we want to access the POSTSCRIPT font +- 'FooBar' from the font family 'Foo': +- +- .sty \n[.fp] Bar +- .fam Foo +- => warning: can't find font `FooR' +- +- The default font position at start-up is 1; for the POSTSCRIPT +- device, this is associated with style 'R', so 'gtroff' tries to +- open 'FooR'. +- +- A solution to this problem is to use a dummy font like the +- following: +- +- .fp 0 dummy TR \" set up dummy font at position 0 +- .sty \n[.fp] Bar \" register style `Bar' +- .ft 0 \" switch to font at position 0 +- .fam Foo \" activate family `Foo' +- .ft Bar \" switch to font `FooBar' +- +- *Note Font Positions::. +- +- +-File: groff.info, Node: Font Positions, Next: Using Symbols, Prev: Font Families, Up: Fonts and Symbols +- +-5.17.3 Font Positions +---------------------- +- +-For the sake of old phototypesetters and compatibility with old versions +-of 'troff', 'gtroff' has the concept of font "positions", on which +-various fonts are mounted. +- +- -- Request: .fp pos font [external-name] +- -- Register: \n[.f] +- -- Register: \n[.fp] +- Mount font FONT at position POS (which must be a non-negative +- integer). This numeric position can then be referred to with font +- changing commands. When 'gtroff' starts it is using font +- position 1 (which must exist; position 0 is unused usually at +- start-up). +- +- The current font in use, as a font position, is available in the +- read-only number register '.f'. This can be useful to remember the +- current font for later recall. It is associated with the current +- environment (*note Environments::). +- +- .nr save-font \n[.f] +- .ft B +- ... text text text ... +- .ft \n[save-font] +- +- The number of the next free font position is available in the +- read-only number register '.fp'. This is useful when mounting a +- new font, like so: +- +- .fp \n[.fp] NEATOFONT +- +- Fonts not listed in the 'DESC' file are automatically mounted on +- the next available font position when they are referenced. If a +- font is to be mounted explicitly with the 'fp' request on an unused +- font position, it should be mounted on the first unused font +- position, which can be found in the '.fp' register. Although +- 'gtroff' does not enforce this strictly, it is not allowed to mount +- a font at a position whose number is much greater (approx. 1000 +- positions) than that of any currently used position. +- +- The 'fp' request has an optional third argument. This argument +- gives the external name of the font, which is used for finding the +- font description file. The second argument gives the internal name +- of the font, which is used to refer to the font in 'gtroff' after +- it has been mounted. If there is no third argument then the +- internal name is used as the external name. This feature makes it +- possible to use fonts with long names in compatibility mode. +- +- Both the 'ft' request and the '\f' escape have alternative syntax +-forms to access font positions. +- +- -- Request: .ft nnn +- -- Escape: \fn +- -- Escape: \f(nn +- -- Escape: \f[nnn] +- Change the current font position to NNN (one-digit position N, +- two-digit position NN), which must be a non-negative integer. +- +- If NNN is associated with a style (as set with the 'sty' request or +- with the 'styles' command in the 'DESC' file), use it within the +- current font family (as set with the 'fam' request, the '\F' +- escape, or with the 'family' command in the 'DESC' file). +- +- this is font 1 +- .ft 2 +- this is font 2 +- .ft \" switch back to font 1 +- .ft 3 +- this is font 3 +- .ft +- this is font 1 again +- +- *Note Changing Fonts::, for the standard syntax form. +- +- +-File: groff.info, Node: Using Symbols, Next: Character Classes, Prev: Font Positions, Up: Fonts and Symbols +- +-5.17.4 Using Symbols +--------------------- +- +-A "glyph" is a graphical representation of a "character". While a +-character is an abstract entity containing semantic information, a glyph +-is something that can be actually seen on screen or paper. It is +-possible that a character has multiple glyph representation forms (for +-example, the character 'A' can be either written in a roman or an italic +-font, yielding two different glyphs); sometimes more than one character +-maps to a single glyph (this is a "ligature" - the most common is 'fi'). +- +- A "symbol" is simply a named glyph. Within 'gtroff', all glyph names +-of a particular font are defined in its font file. If the user requests +-a glyph not available in this font, 'gtroff' looks up an ordered list of +-"special fonts". By default, the POSTSCRIPT output device supports the +-two special fonts 'SS' (slanted symbols) and 'S' (symbols) (the former +-is looked up before the latter). Other output devices use different +-names for special fonts. Fonts mounted with the 'fonts' keyword in the +-'DESC' file are globally available. To install additional special fonts +-locally (i.e. for a particular font), use the 'fspecial' request. +- +- Here the exact rules how 'gtroff' searches a given symbol: +- +- * If the symbol has been defined with the 'char' request, use it. +- This hides a symbol with the same name in the current font. +- +- * Check the current font. +- +- * If the symbol has been defined with the 'fchar' request, use it. +- +- * Check whether the current font has a font-specific list of special +- fonts; test all fonts in the order of appearance in the last +- 'fspecial' call if appropriate. +- +- * If the symbol has been defined with the 'fschar' request for the +- current font, use it. +- +- * Check all fonts in the order of appearance in the last 'special' +- call. +- +- * If the symbol has been defined with the 'schar' request, use it. +- +- * As a last resort, consult all fonts loaded up to now for special +- fonts and check them, starting with the lowest font number. Note +- that this can sometimes lead to surprising results since the +- 'fonts' line in the 'DESC' file often contains empty positions, +- which are filled later on. For example, consider the following: +- +- fonts 3 0 0 FOO +- +- This mounts font 'foo' at font position 3. We assume that 'FOO' is +- a special font, containing glyph 'foo', and that no font has been +- loaded yet. The line +- +- .fspecial BAR BAZ +- +- makes font 'BAZ' special only if font 'BAR' is active. We further +- assume that 'BAZ' is really a special font, i.e., the font +- description file contains the 'special' keyword, and that it also +- contains glyph 'foo' with a special shape fitting to font 'BAR'. +- After executing 'fspecial', font 'BAR' is loaded at font +- position 1, and 'BAZ' at position 2. +- +- We now switch to a new font 'XXX', trying to access glyph 'foo' +- that is assumed to be missing. There are neither font-specific +- special fonts for 'XXX' nor any other fonts made special with the +- 'special' request, so 'gtroff' starts the search for special fonts +- in the list of already mounted fonts, with increasing font +- positions. Consequently, it finds 'BAZ' before 'FOO' even for +- 'XXX', which is not the intended behaviour. +- +- *Note Font Files::, and *note Special Fonts::, for more details. +- +- The list of available symbols is device dependent; see the +-'groff_char(7)' man page for a complete list of all glyphs. For +-example, say +- +- man -Tdvi groff_char > groff_char.dvi +- +-for a list using the default DVI fonts (not all versions of the 'man' +-program support the '-T' option). If you want to use an additional +-macro package to change the used fonts, 'groff' must be called directly: +- +- groff -Tdvi -mec -man groff_char.7 > groff_char.dvi +- +- Glyph names not listed in groff_char(7) are derived algorithmically, +-using a simplified version of the Adobe Glyph List (AGL) algorithm, +-which is described in +-. +-The (frozen) set of glyph names that can't be derived algorithmically is +-called "groff glyph list (GGL)". +- +- * A glyph for Unicode character U+XXXX[X[X]], which is not a +- composite character is named 'uXXXX[X[X]]'. X must be an uppercase +- hexadecimal digit. Examples: 'u1234', 'u008E', 'u12DB8'. The +- largest Unicode value is 0x10FFFF. There must be at least four 'X' +- digits; if necessary, add leading zeroes (after the 'u'). No zero +- padding is allowed for character codes greater than 0xFFFF. +- Surrogates (i.e., Unicode values greater than 0xFFFF represented +- with character codes from the surrogate area U+D800-U+DFFF) are not +- allowed too. +- +- * A glyph representing more than a single input character is named +- +- 'u' COMPONENT1 '_' COMPONENT2 '_' COMPONENT3 ... +- +- Example: 'u0045_0302_0301'. +- +- For simplicity, all Unicode characters that are composites must be +- decomposed maximally (this is normalization form D in the Unicode +- standard); for example, 'u00CA_0301' is not a valid glyph name +- since U+00CA (LATIN CAPITAL LETTER E WITH CIRCUMFLEX) can be +- further decomposed into U+0045 (LATIN CAPITAL LETTER E) and U+0302 +- (COMBINING CIRCUMFLEX ACCENT). 'u0045_0302_0301' is thus the glyph +- name for U+1EBE, LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE. +- +- * groff maintains a table to decompose all algorithmically derived +- glyph names that are composites itself. For example, 'u0100' +- (LATIN LETTER A WITH MACRON) is automatically decomposed into +- 'u0041_0304'. Additionally, a glyph name of the GGL is preferred +- to an algorithmically derived glyph name; groff also automatically +- does the mapping. Example: The glyph 'u0045_0302' is mapped to +- '^E'. +- +- * glyph names of the GGL can't be used in composite glyph names; for +- example, '^E_u0301' is invalid. +- +- -- Escape: \(nm +- -- Escape: \[name] +- -- Escape: \[component1 component2 ...] +- Insert a symbol NAME (two-character name NM) or a composite glyph +- with component glyphs COMPONENT1, COMPONENT2, ... There is no +- special syntax for one-character names - the natural form '\N' +- would collide with escapes.(1) (*note Using Symbols-Footnote-1::) +- +- If NAME is undefined, a warning of type 'char' is generated, and +- the escape is ignored. *Note Debugging::, for information about +- warnings. +- +- groff resolves '\[...]' with more than a single component as +- follows: +- +- * Any component that is found in the GGL is converted to the +- 'uXXXX' form. +- +- * Any component 'uXXXX' that is found in the list of +- decomposable glyphs is decomposed. +- +- * The resulting elements are then concatenated with '_' in +- between, dropping the leading 'u' in all elements but the +- first. +- +- No check for the existence of any component (similar to 'tr' +- request) is done. +- +- Examples: +- +- '\[A ho]' +- 'A' maps to 'u0041', 'ho' maps to 'u02DB', thus the final +- glyph name would be 'u0041_02DB'. Note this is not the +- expected result: The ogonek glyph 'ho' is a spacing ogonek, +- but for a proper composite a non-spacing ogonek (U+0328) is +- necessary. Looking into the file 'composite.tmac' one can +- find '.composite ho u0328', which changes the mapping of 'ho' +- while a composite glyph name is constructed, causing the final +- glyph name to be 'u0041_0328'. +- +- '\[^E u0301]' +- '\[^E aa]' +- '\[E a^ aa]' +- '\[E ^ ']' +- '^E' maps to 'u0045_0302', thus the final glyph name is +- 'u0045_0302_0301' in all forms (assuming proper calls of the +- 'composite' request). +- +- It is not possible to define glyphs with names like 'A ho' within a +- groff font file. This is not really a limitation; instead, you +- have to define 'u0041_0328'. +- +- -- Escape: \C'xxx' +- Typeset the glyph named XXX.(2) (*note Using Symbols-Footnote-2::) +- Normally it is more convenient to use '\[XXX]', but '\C' has the +- advantage that it is compatible with newer versions of AT&T 'troff' +- and is available in compatibility mode. +- +- -- Request: .composite from to +- Map glyph name FROM to glyph name TO if it is used in '\[...]' with +- more than one component. See above for examples. +- +- This mapping is based on glyph names only; no check for the +- existence of either glyph is done. +- +- A set of default mappings for many accents can be found in the file +- 'composite.tmac', which is loaded at start-up. +- +- -- Escape: \N'n' +- Typeset the glyph with code N in the current font ('n' is *not* the +- input character code). The number N can be any non-negative +- decimal integer. Most devices only have glyphs with codes between +- 0 and 255; the Unicode output device uses codes in the range +- 0-65535. If the current font does not contain a glyph with that +- code, special fonts are _not_ searched. The '\N' escape sequence +- can be conveniently used in conjunction with the 'char' request: +- +- .char \[phone] \f[ZD]\N'37' +- +- The code of each glyph is given in the fourth column in the font +- description file after the 'charset' command. It is possible to +- include unnamed glyphs in the font description file by using a name +- of '---'; the '\N' escape sequence is the only way to use these. +- +- No kerning is applied to glyphs accessed with '\N'. +- +- Some escape sequences directly map onto special glyphs. +- +- -- Escape: \' +- This is a backslash followed by the apostrophe character, ASCII +- character '0x27' (EBCDIC character '0x7D'). The same as '\[aa]', +- the acute accent. +- +- -- Escape: \` +- This is a backslash followed by ASCII character '0x60' (EBCDIC +- character '0x79' usually). The same as '\[ga]', the grave accent. +- +- -- Escape: \- +- This is the same as '\[-]', the minus sign in the current font. +- +- -- Escape: \_ +- This is the same as '\[ul]', the underline character. +- +- -- Request: .cflags n c1 c2 ... +- Input characters and symbols have certain properties associated +- with it.(3) (*note Using Symbols-Footnote-3::) These properties +- can be modified with the 'cflags' request. The first argument is +- the sum of the desired flags and the remaining arguments are the +- characters or symbols to have those properties. It is possible to +- omit the spaces between the characters or symbols. Instead of +- single characters or symbols you can also use character classes +- (see *note Character Classes:: for more details). +- +- '1' +- The character ends sentences (initially characters '.?!' have +- this property). +- +- '2' +- Lines can be broken before the character (initially no +- characters have this property). This only works if both the +- characters before and after have non-zero hyphenation codes +- (as set with the 'hcode' request). Use value 64 to override +- this behaviour. +- +- '4' +- Lines can be broken after the character (initially the +- character '-' and the symbols '\[hy]' and '\[em]' have this +- property). This only works if both the characters before and +- after have non-zero hyphenation codes (as set with the 'hcode' +- request). Use value 64 to override this behaviour. +- +- '8' +- The character overlaps horizontally if used as a horizontal +- line building element. Initially the symbols '\[ul]', +- '\[rn]', '\[ru]', '\[radicalex]', and '\[sqrtex]' have this +- property. +- +- '16' +- The character overlaps vertically if used as vertical line +- building element. Initially symbol '\[br]' has this property. +- +- '32' +- An end-of-sentence character followed by any number of +- characters with this property is treated as the end of a +- sentence if followed by a newline or two spaces; in other +- words the character is "transparent" for the purposes of +- end-of-sentence recognition - this is the same as having a +- zero space factor in TeX (initially characters '"')]*' and the +- symbols '\[dg]', '\[rq]', and '\[cq]' have this property). +- +- '64' +- Ignore hyphenation code values of the surrounding characters. +- Use this in combination with values 2 and 4 (initially no +- characters have this property). For example, if you need an +- automatic break point after the hyphen in number ranges like +- '3000-5000', insert +- +- .cflags 68 - +- +- into your document. Note, however, that this can lead to bad +- layout if done without thinking; in most situations, a better +- solution instead of changing the 'cflags' value is to insert +- '\:' right after the hyphen at the places that really need a +- break point. +- +- '128' +- Prohibit a line break before the character, but allow a line +- break after the character. This works only in combination +- with flags 256 and 512 (see below) and has no effect +- otherwise. +- +- '256' +- Prohibit a line break after the character, but allow a line +- break before the character. This works only in combination +- with flags 128 and 512 (see below) and has no effect +- otherwise. +- +- '512' +- Allow line break before or after the character. This works +- only in combination with flags 128 and 256 and has no effect +- otherwise. +- +- Contrary to flag values 2 and 4, the flags 128, 256, and 512 +- work pairwise. If, for example, the left character has value +- 512, and the right character 128, no line break gets inserted. +- If we use value 6 instead for the left character, a line break +- after the character can't be suppressed since the right +- neighbour character doesn't get examined. +- +- -- Request: .char g [string] +- -- Request: .fchar g [string] +- -- Request: .fschar f g [string] +- -- Request: .schar g [string] +- Define a new glyph G to be STRING (which can be empty).(4) (*note +- Using Symbols-Footnote-4::) Every time glyph G needs to be printed, +- STRING is processed in a temporary environment and the result is +- wrapped up into a single object. Compatibility mode is turned off +- and the escape character is set to '\' while STRING is being +- processed. Any emboldening, constant spacing or track kerning is +- applied to this object rather than to individual characters in +- STRING. +- +- A glyph defined by these requests can be used just like a normal +- glyph provided by the output device. In particular, other +- characters can be translated to it with the 'tr' or 'trin' +- requests; it can be made the leader character by the 'lc' request; +- repeated patterns can be drawn with the glyph using the '\l' and +- '\L' escape sequences; words containing the glyph can be hyphenated +- correctly if the 'hcode' request is used to give the glyph's symbol +- a hyphenation code. +- +- There is a special anti-recursion feature: Use of 'g' within the +- glyph's definition is handled like normal characters and symbols +- not defined with 'char'. +- +- Note that the 'tr' and 'trin' requests take precedence if 'char' +- accesses the same symbol. +- +- .tr XY +- X +- => Y +- .char X Z +- X +- => Y +- .tr XX +- X +- => Z +- +- The 'fchar' request defines a fallback glyph: 'gtroff' only checks +- for glyphs defined with 'fchar' if it cannot find the glyph in the +- current font. 'gtroff' carries out this test before checking +- special fonts. +- +- 'fschar' defines a fallback glyph for font F: 'gtroff' checks for +- glyphs defined with 'fschar' after the list of fonts declared as +- font-specific special fonts with the 'fspecial' request, but before +- the list of fonts declared as global special fonts with the +- 'special' request. +- +- Finally, the 'schar' request defines a global fallback glyph: +- 'gtroff' checks for glyphs defined with 'schar' after the list of +- fonts declared as global special fonts with the 'special' request, +- but before the already mounted special fonts. +- +- *Note Using Symbols::, for a detailed description of the glyph +- searching mechanism in 'gtroff'. +- +- -- Request: .rchar c1 c2 ... +- -- Request: .rfschar f c1 c2 ... +- Remove the definitions of glyphs C1, C2, ... This undoes the +- effect of a 'char', 'fchar', or 'schar' request. +- +- It is possible to omit the whitespace between arguments. +- +- The request 'rfschar' removes glyph definitions defined with +- 'fschar' for glyph f. +- +- *Note Special Characters::. +- +- +-File: groff.info, Node: Using Symbols-Footnotes, Up: Using Symbols +- +- (1) Note that a one-character symbol is not the same as an input +-character, i.e., the character 'a' is not the same as '\[a]'. By +-default, 'groff' defines only a single one-character symbol, '\[-]'; it +-is usually accessed as '\-'. On the other hand, 'gtroff' has the +-special feature that '\[charXXX]' is the same as the input character +-with character code XXX. For example, '\[char97]' is identical to the +-letter 'a' if ASCII encoding is active. +- +- (2) '\C' is actually a misnomer since it accesses an output glyph. +- +- (3) Note that the output glyphs themselves don't have such +-properties. For 'gtroff', a glyph is a numbered box with a given width, +-depth, and height, nothing else. All manipulations with the 'cflags' +-request work on the input level. +- +- (4) 'char' is a misnomer since an output glyph is defined. +- +- +-File: groff.info, Node: Character Classes, Next: Special Fonts, Prev: Using Symbols, Up: Fonts and Symbols +- +-5.17.5 Character Classes +------------------------- +- +-Classes are particularly useful for East Asian languages such as +-Chinese, Japanese, and Korean, where the number of needed characters is +-much larger than in European languages, and where large sets of +-characters share the same properties. +- +- -- Request: .class n c1 c2 ... +- In 'groff', a "character class" (or simply "class") is a set of +- characters, grouped by some user aspect. The 'class' request +- defines such classes so that other requests can refer to all +- characters belonging to this set with a single class name. +- Currently, only the 'cflags' request can handle character classes. +- +- A 'class' request takes a class name followed by a list of +- entities. In its simplest form, the entities are characters or +- symbols: +- +- .class [prepunct] , : ; > } +- +- Since class and glyph names share the same namespace, it is +- recommended to start and end the class name with '[' and ']', +- respectively, to avoid collisions with normal 'groff' symbols (and +- symbols defined by the user). In particular, the presence of ']' +- in the symbol name intentionally prevents the usage of '\[...]', +- thus you must use the '\C' escape to access a class with such a +- name. +- +- You can also use a special character range notation, consisting of +- a start character or symbol, followed by '-', and an end character +- or symbol. Internally, 'gtroff' converts these two symbol names to +- Unicode values (according to the groff glyph gist), which then give +- the start and end value of the range. If that fails, the class +- definition is skipped. +- +- Finally, classes can be nested, too. +- +- Here is a more complex example: +- +- .class [prepunctx] \C'[prepunct]' \[u2013]-\[u2016] +- +- The class 'prepunctx' now contains the contents of the class +- 'prepunct' as defined above (the set ', : ; > }'), and characters +- in the range between 'U+2013' and 'U+2016'. +- +- If you want to add '-' to a class, it must be the first character +- value in the argument list, otherwise it gets misinterpreted as a +- range. +- +- Note that it is not possible to use class names within range +- definitions. +- +- Typical use of the 'class' request is to control line-breaking and +- hyphenation rules as defined by the 'cflags' request. For example, +- to inhibit line breaks before the characters belonging to the +- 'prepunctx' class, you can write: +- +- .cflags 2 \C'[prepunctx]' +- +- See the 'cflags' request in *note Using Symbols::, for more +- details. +- +- +-File: groff.info, Node: Special Fonts, Next: Artificial Fonts, Prev: Character Classes, Up: Fonts and Symbols +- +-5.17.6 Special Fonts +--------------------- +- +-Special fonts are those that 'gtroff' searches when it cannot find the +-requested glyph in the current font. The Symbol font is usually a +-special font. +- +- 'gtroff' provides the following two requests to add more special +-fonts. *Note Using Symbols::, for a detailed description of the glyph +-searching mechanism in 'gtroff'. +- +- Usually, only non-TTY devices have special fonts. +- +- -- Request: .special [s1 s2 ...] +- -- Request: .fspecial f [s1 s2 ...] +- Use the 'special' request to define special fonts. Initially, this +- list is empty. +- +- Use the 'fspecial' request to designate special fonts only when +- font F is active. Initially, this list is empty. +- +- Previous calls to 'special' or 'fspecial' are overwritten; without +- arguments, the particular list of special fonts is set to empty. +- Special fonts are searched in the order they appear as arguments. +- +- All fonts that appear in a call to 'special' or 'fspecial' are +- loaded. +- +- *Note Using Symbols::, for the exact search order of glyphs. +- +- +-File: groff.info, Node: Artificial Fonts, Next: Ligatures and Kerning, Prev: Special Fonts, Up: Fonts and Symbols +- +-5.17.7 Artificial Fonts +------------------------ +- +-There are a number of requests and escapes for artificially creating +-fonts. These are largely vestiges of the days when output devices did +-not have a wide variety of fonts, and when 'nroff' and 'troff' were +-separate programs. Most of them are no longer necessary in GNU 'troff'. +-Nevertheless, they are supported. +- +- -- Escape: \H'height' +- -- Escape: \H'+height' +- -- Escape: \H'-height' +- -- Register: \n[.height] +- Change (increment, decrement) the height of the current font, but +- not the width. If HEIGHT is zero, restore the original height. +- Default scaling indicator is 'z'. +- +- The read-only number register '.height' contains the font height as +- set by '\H'. +- +- Currently, only the '-Tps' and '-Tpdf' devices support this +- feature. +- +- Note that '\H' doesn't produce an input token in 'gtroff'. As a +- consequence, it can be used in requests like 'mc' (which expects a +- single character as an argument) to change the font on the fly: +- +- .mc \H'+5z'x\H'0' +- +- In compatibility mode, 'gtroff' behaves differently: If an +- increment or decrement is used, it is always taken relative to the +- current point size and not relative to the previously selected font +- height. Thus, +- +- .cp 1 +- \H'+5'test \H'+5'test +- +- prints the word 'test' twice with the same font height (five points +- larger than the current font size). +- +- -- Escape: \S'slant' +- -- Register: \n[.slant] +- Slant the current font by SLANT degrees. Positive values slant to +- the right. Only integer values are possible. +- +- The read-only number register '.slant' contains the font slant as +- set by '\S'. +- +- Currently, only the '-Tps' and '-Tpdf' devices support this +- feature. +- +- Note that '\S' doesn't produce an input token in 'gtroff'. As a +- consequence, it can be used in requests like 'mc' (which expects a +- single character as an argument) to change the font on the fly: +- +- .mc \S'20'x\S'0' +- +- This request is incorrectly documented in the original UNIX troff +- manual; the slant is always set to an absolute value. +- +- -- Request: .ul [lines] +- The 'ul' request normally underlines subsequent lines if a TTY +- output device is used. Otherwise, the lines are printed in italics +- (only the term 'underlined' is used in the following). The single +- argument is the number of input lines to be underlined; with no +- argument, the next line is underlined. If LINES is zero or +- negative, stop the effects of 'ul' (if it was active). Requests +- and empty lines do not count for computing the number of underlined +- input lines, even if they produce some output like 'tl'. Lines +- inserted by macros (e.g. invoked by a trap) do count. +- +- At the beginning of 'ul', the current font is stored and the +- underline font is activated. Within the span of a 'ul' request, it +- is possible to change fonts, but after the last line affected by +- 'ul' the saved font is restored. +- +- This number of lines still to be underlined is associated with the +- current environment (*note Environments::). The underline font can +- be changed with the 'uf' request. +- +- The 'ul' request does not underline spaces. +- +- -- Request: .cu [lines] +- The 'cu' request is similar to 'ul' but underlines spaces as well +- (if a TTY output device is used). +- +- -- Request: .uf font +- Set the underline font (globally) used by 'ul' and 'cu'. By +- default, this is the font at position 2. FONT can be either a +- non-negative font position or the name of a font. +- +- -- Request: .bd font [offset] +- -- Request: .bd font1 font2 [offset] +- -- Register: \n[.b] +- Artificially create a bold font by printing each glyph twice, +- slightly offset. +- +- Two syntax forms are available. +- +- * Imitate a bold font unconditionally. The first argument +- specifies the font to embolden, and the second is the number +- of basic units, minus one, by which the two glyphs are offset. +- If the second argument is missing, emboldening is turned off. +- +- FONT can be either a non-negative font position or the name of +- a font. +- +- OFFSET is available in the '.b' read-only register if a +- special font is active; in the 'bd' request, its default unit +- is 'u'. +- +- * Imitate a bold form conditionally. Embolden FONT1 by OFFSET +- only if font FONT2 is the current font. This command can be +- issued repeatedly to set up different emboldening values for +- different current fonts. If the second argument is missing, +- emboldening is turned off for this particular current font. +- +- This affects special fonts only (either set up with the +- 'special' command in font files or with the 'fspecial' +- request). +- +- -- Request: .cs font [width [em-size]] +- Switch to and from "constant glyph space mode". If activated, the +- width of every glyph is WIDTH/36 ems. The em size is given +- absolutely by EM-SIZE; if this argument is missing, the em value is +- taken from the current font size (as set with the 'ps' request) +- when the font is effectively in use. Without second and third +- argument, constant glyph space mode is deactivated. +- +- Default scaling indicator for EM-SIZE is 'z'; WIDTH is an integer. +- +- +-File: groff.info, Node: Ligatures and Kerning, Prev: Artificial Fonts, Up: Fonts and Symbols +- +-5.17.8 Ligatures and Kerning +----------------------------- +- +-Ligatures are groups of characters that are run together, i.e, producing +-a single glyph. For example, the letters 'f' and 'i' can form a +-ligature 'fi' as in the word 'file'. This produces a cleaner look +-(albeit subtle) to the printed output. Usually, ligatures are not +-available in fonts for TTY output devices. +- +- Most POSTSCRIPT fonts support the fi and fl ligatures. The C/A/T +-typesetter that was the target of AT&T 'troff' also supported 'ff', +-'ffi', and 'ffl' ligatures. Advanced typesetters or 'expert' fonts may +-include ligatures for 'ft' and 'ct', although GNU 'troff' does not +-support these (yet). +- +- Only the current font is checked for ligatures and kerns; neither +-special fonts nor entities defined with the 'char' request (and its +-siblings) are taken into account. +- +- -- Request: .lg [flag] +- -- Register: \n[.lg] +- Switch the ligature mechanism on or off; if the parameter is +- non-zero or missing, ligatures are enabled, otherwise disabled. +- Default is on. The current ligature mode can be found in the +- read-only number register '.lg' (set to 1 or 2 if ligatures are +- enabled, 0 otherwise). +- +- Setting the ligature mode to 2 enables the two-character ligatures +- (fi, fl, and ff) and disables the three-character ligatures (ffi +- and ffl). +- +- "Pairwise kerning" is another subtle typesetting mechanism that +-modifies the distance between a glyph pair to improve readability. In +-most cases (but not always) the distance is decreased. Typewriter-like +-fonts and fonts for terminals where all glyphs have the same width don't +-use kerning. +- +- -- Request: .kern [flag] +- -- Register: \n[.kern] +- Switch kerning on or off. If the parameter is non-zero or missing, +- enable pairwise kerning, otherwise disable it. The read-only +- number register '.kern' is set to 1 if pairwise kerning is enabled, +- 0 otherwise. +- +- If the font description file contains pairwise kerning information, +- glyphs from that font are kerned. Kerning between two glyphs can +- be inhibited by placing '\&' between them: 'V\&A'. +- +- *Note Font File Format::. +- +- "Track kerning" expands or reduces the space between glyphs. This +-can be handy, for example, if you need to squeeze a long word onto a +-single line or spread some text to fill a narrow column. It must be +-used with great care since it is usually considered bad typography if +-the reader notices the effect. +- +- -- Request: .tkf f s1 n1 s2 n2 +- Enable track kerning for font F. If the current font is F the +- width of every glyph is increased by an amount between N1 and N2 +- (N1, N2 can be negative); if the current point size is less than or +- equal to S1 the width is increased by N1; if it is greater than or +- equal to S2 the width is increased by N2; if the point size is +- greater than or equal to S1 and less than or equal to S2 the +- increase in width is a linear function of the point size. +- +- The default scaling indicator is 'z' for S1 and S2, 'p' for N1 and +- N2. +- +- Note that the track kerning amount is added even to the rightmost +- glyph in a line; for large values it is thus recommended to +- increase the line length by the same amount to compensate it. +- +- Sometimes, when typesetting letters of different fonts, more or less +-space at such boundaries are needed. There are two escapes to help with +-this. +- +- -- Escape: \/ +- Increase the width of the preceding glyph so that the spacing +- between that glyph and the following glyph is correct if the +- following glyph is a roman glyph. For example, if an italic 'f' is +- immediately followed by a roman right parenthesis, then in many +- fonts the top right portion of the 'f' overlaps the top left of the +- right parenthesis. Use this escape sequence whenever an italic +- glyph is immediately followed by a roman glyph without any +- intervening space. This small amount of space is also called +- "italic correction". +- +- -- Escape: \, +- Modify the spacing of the following glyph so that the spacing +- between that glyph and the preceding glyph is correct if the +- preceding glyph is a roman glyph. Use this escape sequence +- whenever a roman glyph is immediately followed by an italic glyph +- without any intervening space. In analogy to above, this space +- could be called "left italic correction", but this term isn't used +- widely. +- +- -- Escape: \& +- Insert a zero-width character, which is invisible. Its intended +- use is to stop interaction of a character with its surrounding. +- +- * It prevents the insertion of extra space after an +- end-of-sentence character. +- +- Test. +- Test. +- => Test. Test. +- Test.\& +- Test. +- => Test. Test. +- +- * It prevents interpretation of a control character at the +- beginning of an input line. +- +- .Test +- => warning: `Test' not defined +- \&.Test +- => .Test +- +- * It prevents kerning between two glyphs. +- +- * It is needed to map an arbitrary character to nothing in the +- 'tr' request (*note Character Translations::). +- +- -- Escape: \) +- This escape is similar to '\&' except that it behaves like a +- character declared with the 'cflags' request to be transparent for +- the purposes of an end-of-sentence character. +- +- Its main usage is in macro definitions to protect against arguments +- starting with a control character. +- +- .de xxx +- \)\\$1 +- .. +- .de yyy +- \&\\$1 +- .. +- This is a test.\c +- .xxx ' +- This is a test. +- =>This is a test.' This is a test. +- This is a test.\c +- .yyy ' +- This is a test. +- =>This is a test.' This is a test. +- +- +-File: groff.info, Node: Sizes, Next: Strings, Prev: Fonts and Symbols, Up: gtroff Reference +- +-5.18 Sizes +-========== +- +-'gtroff' uses two dimensions with each line of text, type size and +-vertical spacing. The "type size" is approximately the height of the +-tallest glyph.(1) (*note Sizes-Footnote-1::) "Vertical spacing" is the +-amount of space 'gtroff' allows for a line of text; normally, this is +-about 20% larger than the current type size. Ratios smaller than this +-can result in hard-to-read text; larger than this, it spreads the text +-out more vertically (useful for term papers). By default, 'gtroff' uses +-10 point type on 12 point spacing. +- +- The difference between type size and vertical spacing is known, by +-typesetters, as "leading" (this is pronounced 'ledding'). +- +-* Menu: +- +-* Changing Type Sizes:: +-* Fractional Type Sizes:: +- +- +-File: groff.info, Node: Sizes-Footnotes, Up: Sizes +- +- (1) This is usually the parenthesis. Note that in most cases the +-real dimensions of the glyphs in a font are _not_ related to its type +-size! For example, the standard POSTSCRIPT font families 'Times Roman', +-'Helvetica', and 'Courier' can't be used together at 10pt; to get +-acceptable output, the size of 'Helvetica' has to be reduced by one +-point, and the size of 'Courier' must be increased by one point. +- +- +-File: groff.info, Node: Changing Type Sizes, Next: Fractional Type Sizes, Prev: Sizes, Up: Sizes +- +-5.18.1 Changing Type Sizes +--------------------------- +- +- -- Request: .ps [size] +- -- Request: .ps +size +- -- Request: .ps -size +- -- Escape: \ssize +- -- Register: \n[.s] +- Use the 'ps' request or the '\s' escape to change (increase, +- decrease) the type size (in points). Specify SIZE as either an +- absolute point size, or as a relative change from the current size. +- The size 0 (for both '.ps' and '\s'), or no argument (for '.ps' +- only), goes back to the previous size. +- +- Default scaling indicator of 'size' is 'z'. If 'size' is negative, +- it is set to 1u. +- +- The read-only number register '.s' returns the point size in points +- as a decimal fraction. This is a string. To get the point size in +- scaled points, use the '.ps' register instead. +- +- '.s' is associated with the current environment (*note +- Environments::). +- +- snap, snap, +- .ps +2 +- grin, grin, +- .ps +2 +- wink, wink, \s+2nudge, nudge,\s+8 say no more! +- .ps 10 +- +- The '\s' escape may be called in a variety of ways. Much like +- other escapes there must be a way to determine where the argument +- ends and the text begins. Any of the following forms are valid: +- +- '\sN' +- Set the point size to N points. N must be either 0 or in the +- range 4 to 39. +- +- '\s+N' +- '\s-N' +- Increase or decrease the point size by N points. N must be +- exactly one digit. +- +- '\s(NN' +- Set the point size to NN points. NN must be exactly two +- digits. +- +- '\s+(NN' +- '\s-(NN' +- '\s(+NN' +- '\s(-NN' +- Increase or decrease the point size by NN points. NN must be +- exactly two digits. +- +- Note that '\s' doesn't produce an input token in 'gtroff'. As a +- consequence, it can be used in requests like 'mc' (which expects a +- single character as an argument) to change the font on the fly: +- +- .mc \s[20]x\s[0] +- +- *Note Fractional Type Sizes::, for yet another syntactical form of +- using the '\s' escape. +- +- -- Request: .sizes s1 s2 ... sn [0] +- Some devices may only have certain permissible sizes, in which case +- 'gtroff' rounds to the nearest permissible size. The 'DESC' file +- specifies which sizes are permissible for the device. +- +- Use the 'sizes' request to change the permissible sizes for the +- current output device. Arguments are in scaled points; the +- 'sizescale' line in the 'DESC' file for the output device provides +- the scaling factor. For example, if the scaling factor is 1000, +- then the value 12000 is 12 points. +- +- Each argument can be a single point size (such as '12000'), or a +- range of sizes (such as '4000-72000'). You can optionally end the +- list with a zero. +- +- -- Request: .vs [space] +- -- Request: .vs +space +- -- Request: .vs -space +- -- Register: \n[.v] +- Change (increase, decrease) the vertical spacing by SPACE. The +- default scaling indicator is 'p'. +- +- If 'vs' is called without an argument, the vertical spacing is +- reset to the previous value before the last call to 'vs'. +- +- 'gtroff' creates a warning of type 'range' if SPACE is negative; +- the vertical spacing is then set to smallest positive value, the +- vertical resolution (as given in the '.V' register). +- +- Note that '.vs 0' isn't saved in a diversion since it doesn't +- result in a vertical motion. You explicitly have to repeat this +- command before inserting the diversion. +- +- The read-only number register '.v' contains the current vertical +- spacing; it is associated with the current environment (*note +- Environments::). +- +- The effective vertical line spacing consists of four components. +-Breaking a line causes the following actions (in the given order). +- +- * Move the current point vertically by the "extra pre-vertical line +- space". This is the minimum value of all '\x' escapes with a +- negative argument in the current output line. +- +- * Move the current point vertically by the vertical line spacing as +- set with the 'vs' request. +- +- * Output the current line. +- +- * Move the current point vertically by the "extra post-vertical line +- space". This is the maximum value of all '\x' escapes with a +- positive argument in the line that has just been output. +- +- * Move the current point vertically by the "post-vertical line +- spacing" as set with the 'pvs' request. +- +- It is usually better to use 'vs' or 'pvs' instead of 'ls' to produce +-double-spaced documents: 'vs' and 'pvs' have a finer granularity for the +-inserted vertical space compared to 'ls'; furthermore, certain +-preprocessors assume single-spacing. +- +- *Note Manipulating Spacing::, for more details on the '\x' escape and +-the 'ls' request. +- +- -- Request: .pvs [space] +- -- Request: .pvs +space +- -- Request: .pvs -space +- -- Register: \n[.pvs] +- Change (increase, decrease) the post-vertical spacing by SPACE. +- The default scaling indicator is 'p'. +- +- If 'pvs' is called without an argument, the post-vertical spacing +- is reset to the previous value before the last call to 'pvs'. +- +- 'gtroff' creates a warning of type 'range' if SPACE is zero or +- negative; the vertical spacing is then set to zero. +- +- The read-only number register '.pvs' contains the current +- post-vertical spacing; it is associated with the current +- environment (*note Environments::). +- +- +-File: groff.info, Node: Fractional Type Sizes, Prev: Changing Type Sizes, Up: Sizes +- +-5.18.2 Fractional Type Sizes +----------------------------- +- +-A "scaled point" is equal to 1/SIZESCALE points, where SIZESCALE is +-specified in the 'DESC' file (1 by default). There is a new scale +-indicator 'z', which has the effect of multiplying by SIZESCALE. +-Requests and escape sequences in 'gtroff' interpret arguments that +-represent a point size as being in units of scaled points, but they +-evaluate each such argument using a default scale indicator of 'z'. +-Arguments treated in this way are the argument to the 'ps' request, the +-third argument to the 'cs' request, the second and fourth arguments to +-the 'tkf' request, the argument to the '\H' escape sequence, and those +-variants of the '\s' escape sequence that take a numeric expression as +-their argument (see below). +- +- For example, suppose SIZESCALE is 1000; then a scaled point is +-equivalent to a millipoint; the request '.ps 10.25' is equivalent to +-'.ps 10.25z' and thus sets the point size to 10250 scaled points, which +-is equal to 10.25 points. +- +- 'gtroff' disallows the use of the 'z' scale indicator in instances +-where it would make no sense, such as a numeric expression whose default +-scale indicator was neither 'u' nor 'z'. Similarly it would make no +-sense to use a scaling indicator other than 'z' or 'u' in a numeric +-expression whose default scale indicator was 'z', and so 'gtroff' +-disallows this as well. +- +- There is also new scale indicator 's', which multiplies by the number +-of units in a scaled point. So, for example, '\n[.ps]s' is equal to +-'1m'. Be sure not to confuse the 's' and 'z' scale indicators. +- +- -- Register: \n[.ps] +- A read-only number register returning the point size in scaled +- points. +- +- '.ps' is associated with the current environment (*note +- Environments::). +- +- -- Register: \n[.psr] +- -- Register: \n[.sr] +- The last-requested point size in scaled points is contained in the +- '.psr' read-only number register. The last requested point size in +- points as a decimal fraction can be found in '.sr'. This is a +- string-valued read-only number register. +- +- Note that the requested point sizes are device-independent, whereas +- the values returned by the '.ps' and '.s' registers are not. For +- example, if a point size of 11pt is requested, and a 'sizes' +- request (or a 'sizescale' line in a 'DESC' file) specifies 10.95pt +- instead, this value is actually used. +- +- Both registers are associated with the current environment (*note +- Environments::). +- +- The '\s' escape has the following syntax for working with fractional +-type sizes: +- +-'\s[N]' +-'\s'N'' +- Set the point size to N scaled points; N is a numeric expression +- with a default scale indicator of 'z'. +- +-'\s[+N]' +-'\s[-N]' +-'\s+[N]' +-'\s-[N]' +-'\s'+N'' +-'\s'-N'' +-'\s+'N'' +-'\s-'N'' +- Increase or or decrease the point size by N scaled points; N is a +- numeric expression (which may start with a minus sign) with a +- default scale indicator of 'z'. +- +- *Note Font Files::. +- +- +-File: groff.info, Node: Strings, Next: Conditionals and Loops, Prev: Sizes, Up: gtroff Reference +- +-5.19 Strings +-============ +- +-'gtroff' has string variables, which are entirely for user convenience +-(i.e. there are no built-in strings exept '.T', but even this is a +-read-write string variable). +- +- Although the following requests can be used to create strings, simply +-using an undefined string will cause it to be defined as empty. *Note +-Identifiers::. +- +- -- Request: .ds name [string] +- -- Request: .ds1 name [string] +- -- Escape: \*n +- -- Escape: \*(nm +- -- Escape: \*[name arg1 arg2 ...] +- Define and access a string variable NAME (one-character name N, +- two-character name NM). If NAME already exists, 'ds' overwrites +- the previous definition. Only the syntax form using brackets can +- take arguments that are handled identically to macro arguments; the +- single exception is that a closing bracket as an argument must be +- enclosed in double quotes. *Note Request and Macro Arguments::, +- and *note Parameters::. +- +- Example: +- +- .ds foo a \\$1 test +- . +- This is \*[foo nice]. +- => This is a nice test. +- +- The '\*' escape "interpolates" (expands in-place) a +- previously-defined string variable. To be more precise, the stored +- string is pushed onto the input stack, which is then parsed by +- 'gtroff'. Similar to number registers, it is possible to nest +- strings, i.e., string variables can be called within string +- variables. +- +- If the string named by the '\*' escape does not exist, it is +- defined as empty, and a warning of type 'mac' is emitted (see *note +- Debugging::, for more details). +- +- *Caution:* Unlike other requests, the second argument to the 'ds' +- request takes up the entire line including trailing spaces. This +- means that comments on a line with such a request can introduce +- unwanted space into a string. +- +- .ds UX \s-1UNIX\s0\u\s-3tm\s0\d \" UNIX trademark +- +- Instead the comment should be put on another line or have the +- comment escape adjacent with the end of the string. +- +- .ds UX \s-1UNIX\s0\u\s-3tm\s0\d\" UNIX trademark +- +- To produce leading space the string can be started with a double +- quote. No trailing quote is needed; in fact, any trailing quote is +- included in your string. +- +- .ds sign " Yours in a white wine sauce, +- +- Strings are not limited to a single line of text. A string can +- span several lines by escaping the newlines with a backslash. The +- resulting string is stored _without_ the newlines. +- +- .ds foo lots and lots \ +- of text are on these \ +- next several lines +- +- It is not possible to have real newlines in a string. To put a +- single double quote character into a string, use two consecutive +- double quote characters. +- +- The 'ds1' request turns off compatibility mode while interpreting a +- string. To be more precise, a "compatibility save" input token is +- inserted at the beginning of the string, and a "compatibility +- restore" input token at the end. +- +- .nr xxx 12345 +- .ds aa The value of xxx is \\n[xxx]. +- .ds1 bb The value of xxx ix \\n[xxx]. +- . +- .cp 1 +- . +- \*(aa +- => warning: number register `[' not defined +- => The value of xxx is 0xxx]. +- \*(bb +- => The value of xxx ix 12345. +- +- Strings, macros, and diversions (and boxes) share the same name +- space. Internally, even the same mechanism is used to store them. +- This has some interesting consequences. For example, it is +- possible to call a macro with string syntax and vice versa. +- +- .de xxx +- a funny test. +- .. +- This is \*[xxx] +- => This is a funny test. +- +- .ds yyy a funny test +- This is +- .yyy +- => This is a funny test. +- +- In particular, interpolating a string does not hide existing macro +- arguments. Thus in a macro, a more efficient way of doing +- +- .xx \\$@ +- +- is +- +- \\*[xx]\\ +- +- Note that the latter calling syntax doesn't change the value of +- '\$0', which is then inherited from the calling macro. +- +- Diversions and boxes can be also called with string syntax. +- +- Another consequence is that you can copy one-line diversions or +- boxes to a string. +- +- .di xxx +- a \fItest\fR +- .br +- .di +- .ds yyy This is \*[xxx]\c +- \*[yyy]. +- => This is a test. +- +- As the previous example shows, it is possible to store formatted +- output in strings. The '\c' escape prevents the insertion of an +- additional blank line in the output. +- +- Copying diversions longer than a single output line produces +- unexpected results. +- +- .di xxx +- a funny +- .br +- test +- .br +- .di +- .ds yyy This is \*[xxx]\c +- \*[yyy]. +- => test This is a funny. +- +- Usually, it is not predictable whether a diversion contains one or +- more output lines, so this mechanism should be avoided. With UNIX +- 'troff', this was the only solution to strip off a final newline +- from a diversion. Another disadvantage is that the spaces in the +- copied string are already formatted, making them unstretchable. +- This can cause ugly results. +- +- A clean solution to this problem is available in GNU 'troff', using +- the requests 'chop' to remove the final newline of a diversion, and +- 'unformat' to make the horizontal spaces stretchable again. +- +- .box xxx +- a funny +- .br +- test +- .br +- .box +- .chop xxx +- .unformat xxx +- This is \*[xxx]. +- => This is a funny test. +- +- *Note Gtroff Internals::, for more information. +- +- -- Request: .as name [string] +- -- Request: .as1 name [string] +- The 'as' request is similar to 'ds' but appends STRING to the +- string stored as NAME instead of redefining it. If NAME doesn't +- exist yet, it is created. +- +- .as sign " with shallots, onions and garlic, +- +- The 'as1' request is similar to 'as', but compatibility mode is +- switched off while the appended string is interpreted. To be more +- precise, a "compatibility save" input token is inserted at the +- beginning of the appended string, and a "compatibility restore" +- input token at the end. +- +- Rudimentary string manipulation routines are given with the next two +-requests. +- +- -- Request: .substring str n1 [n2] +- Replace the string named STR with the substring defined by the +- indices N1 and N2. The first character in the string has index 0. +- If N2 is omitted, it is implicitly set to the largest valid value +- (the string length minus one). If the index value N1 or N2 is +- negative, it is counted from the end of the string, going +- backwards: The last character has index -1, the character before +- the last character has index -2, etc. +- +- .ds xxx abcdefgh +- .substring xxx 1 -4 +- \*[xxx] +- => bcde +- .substring xxx 2 +- \*[xxx] +- => de +- +- -- Request: .length reg str +- Compute the number of characters of STR and return it in the number +- register REG. If REG doesn't exist, it is created. 'str' is read +- in copy mode. +- +- .ds xxx abcd\h'3i'efgh +- .length yyy \*[xxx] +- \n[yyy] +- => 14 +- +- -- Request: .rn xx yy +- Rename the request, macro, diversion, or string XX to YY. +- +- -- Request: .rm xx +- Remove the request, macro, diversion, or string XX. 'gtroff' +- treats subsequent invocations as if the object had never been +- defined. +- +- -- Request: .als new old +- Create an alias named NEW for the request, string, macro, or +- diversion object named OLD. The new name and the old name are +- exactly equivalent (it is similar to a hard rather than a soft +- link). If OLD is undefined, 'gtroff' generates a warning of type +- 'mac' and ignores the request. +- +- To understand how the 'als' request works it is probably best to +- think of two different pools: one pool for objects (macros, +- strings, etc.), and another one for names. As soon as an object is +- defined, 'gtroff' adds it to the object pool, adds its name to the +- name pool, and creates a link between them. When 'als' creates an +- alias, it adds a new name to the name pool that gets linked to the +- same object as the old name. +- +- Now consider this example. +- +- .de foo +- .. +- . +- .als bar foo +- . +- .de bar +- . foo +- .. +- . +- .bar +- => input stack limit exceeded +- +- The definition of macro 'bar' replaces the old object this name is +- linked to. However, the alias to 'foo' is still active! In other +- words, 'foo' is still linked to the same object as 'bar', and the +- result of calling 'bar' is an infinite, recursive loop that finally +- leads to an error. +- +- To undo an alias, simply call 'rm' on the aliased name. The object +- itself is not destroyed until there are no more aliases. +- +- -- Request: .chop xx +- Remove (chop) the last character from the macro, string, or +- diversion named XX. This is useful for removing the newline from +- the end of diversions that are to be interpolated as strings. This +- command can be used repeatedly; see *note Gtroff Internals::, for +- details on nodes inserted additionally by 'gtroff'. +- +- *Note Identifiers::, and *note Comments::. +- +- +-File: groff.info, Node: Conditionals and Loops, Next: Writing Macros, Prev: Strings, Up: gtroff Reference +- +-5.20 Conditionals and Loops +-=========================== +- +-* Menu: +- +-* Operators in Conditionals:: +-* if-else:: +-* while:: +- +- +-File: groff.info, Node: Operators in Conditionals, Next: if-else, Prev: Conditionals and Loops, Up: Conditionals and Loops +- +-5.20.1 Operators in Conditionals +--------------------------------- +- +-In 'if', 'ie', and 'while' requests, in addition to ordinary *note +-Expressions::, there are several more operators available: +- +-'e' +-'o' +- True if the current page is even or odd numbered (respectively). +- +-'n' +- True if the document is being processed in nroff mode (i.e., the +- '.nroff' command has been issued). *Note Troff and Nroff Mode::. +- +-'t' +- True if the document is being processed in troff mode (i.e., the +- '.troff' command has been issued). *Note Troff and Nroff Mode::. +- +-'v' +- Always false. This condition is for compatibility with other +- 'troff' versions only (identifying a '-Tversatec' device). +- +-''XXX'YYY'' +- True if the output produced by XXX is equal to the output produced +- by YYY. Other characters can be used in place of the single +- quotes; the same set of delimiters as for the '\D' escape is used +- (*note Escapes::). 'gtroff' formats XXX and YYY in separate +- environments; after the comparison the resulting data is discarded. +- +- .ie "|"\fR|\fP" \ +- true +- .el \ +- false +- => true +- +- The resulting motions, glyph sizes, and fonts have to match,(1) +- (*note Operators in Conditionals-Footnote-1::) and not the +- individual motion, size, and font requests. In the previous +- example, '|' and '\fR|\fP' both result in a roman '|' glyph with +- the same point size and at the same location on the page, so the +- strings are equal. If '.ft I' had been added before the '.ie', the +- result would be "false" because (the first) '|' produces an italic +- '|' rather than a roman one. +- +- To compare strings without processing, surround the data with '\?'. +- +- .ie "\?|\?"\?\fR|\fP\?" \ +- true +- .el \ +- false +- => false +- +- Since data protected with '\?' is read in copy-in mode it is even +- possible to use incomplete input without causing an error. +- +- .ds a \[ +- .ds b \[ +- .ie '\?\*a\?'\?\*b\?' \ +- true +- .el \ +- false +- => true +- +-'r XXX' +- True if there is a number register named XXX. +- +-'d XXX' +- True if there is a string, macro, diversion, or request named XXX. +- +-'m XXX' +- True if there is a color named XXX. +- +-'c G' +- True if there is a glyph G available(2) (*note Operators in +- Conditionals-Footnote-2::); G is either an ASCII character or a +- special character ('\N'XXX'', '\(GG' or '\[GGG]'); the condition is +- also true if G has been defined by the 'char' request. +- +-'F FONT' +- True if a font named FONT exists. FONT is handled as if it was +- opened with the 'ft' request (this is, font translation and styles +- are applied), without actually mounting it. +- +- This test doesn't load the complete font but only its header to +- verify its validity. +- +-'S STYLE' +- True if style STYLE has been registered. Font translation is +- applied. +- +- Note that these operators can't be combined with other operators like +-':' or '&'; only a leading '!' (without whitespace between the +-exclamation mark and the operator) can be used to negate the result. +- +- .nr xxx 1 +- .ie !r xxx \ +- true +- .el \ +- false +- => false +- +- A whitespace after '!' always evaluates to zero (this bizarre +-behaviour is due to compatibility with UNIX 'troff'). +- +- .nr xxx 1 +- .ie ! r xxx \ +- true +- .el \ +- false +- => r xxx true +- +- It is possible to omit the whitespace before the argument to the 'r', +-'d', and 'c' operators. +- +- *Note Expressions::. +- +- +-File: groff.info, Node: Operators in Conditionals-Footnotes, Up: Operators in Conditionals +- +- (1) The created output nodes must be identical. *Note Gtroff +-Internals::. +- +- (2) The name of this conditional operator is a misnomer since it +-tests names of output glyphs. +- +- +-File: groff.info, Node: if-else, Next: while, Prev: Operators in Conditionals, Up: Conditionals and Loops +- +-5.20.2 if-else +--------------- +- +-'gtroff' has if-then-else constructs like other languages, although the +-formatting can be painful. +- +- -- Request: .if expr anything +- +- Evaluate the expression EXPR, and executes ANYTHING (the remainder +- of the line) if EXPR evaluates to a value greater than zero (true). +- ANYTHING is interpreted as though it was on a line by itself +- (except that leading spaces are swallowed). *Note Operators in +- Conditionals::, for more info. +- +- .nr xxx 1 +- .nr yyy 2 +- .if ((\n[xxx] == 1) & (\n[yyy] == 2)) true +- => true +- +- -- Request: .nop anything +- Executes ANYTHING. This is similar to '.if 1'. +- +- -- Request: .ie expr anything +- -- Request: .el anything +- Use the 'ie' and 'el' requests to write an if-then-else. The first +- request is the 'if' part and the latter is the 'else' part. +- +- .ie n .ls 2 \" double-spacing in nroff +- .el .ls 1 \" single-spacing in troff +- +- -- Escape: \{ +- -- Escape: \} +- In many cases, an if (or if-else) construct needs to execute more +- than one request. This can be done using the escapes '\{' (which +- must start the first line) and '\}' (which must end the last line). +- +- .ie t \{\ +- . ds lq `` +- . ds rq '' +- .\} +- .el \{\ +- . ds lq "" +- . ds rq "" +- .\} +- +- *Note Expressions::. +- +- +-File: groff.info, Node: while, Prev: if-else, Up: Conditionals and Loops +- +-5.20.3 while +------------- +- +-'gtroff' provides a looping construct using the 'while' request, which +-is used much like the 'if' (and related) requests. +- +- -- Request: .while expr anything +- Evaluate the expression EXPR, and repeatedly execute ANYTHING (the +- remainder of the line) until EXPR evaluates to 0. +- +- .nr a 0 1 +- .while (\na < 9) \{\ +- \n+a, +- .\} +- \n+a +- => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +- +- Some remarks. +- +- * The body of a 'while' request is treated like the body of a +- 'de' request: 'gtroff' temporarily stores it in a macro that +- is deleted after the loop has been exited. It can +- considerably slow down a macro if the body of the 'while' +- request (within the macro) is large. Each time the macro is +- executed, the 'while' body is parsed and stored again as a +- temporary macro. +- +- .de xxx +- . nr num 10 +- . while (\\n[num] > 0) \{\ +- . \" many lines of code +- . nr num -1 +- . \} +- .. +- +- The traditional and ofter better solution (UNIX 'troff' +- doesn't have the 'while' request) is to use a recursive macro +- instead that is parsed only once during its definition. +- +- .de yyy +- . if (\\n[num] > 0) \{\ +- . \" many lines of code +- . nr num -1 +- . yyy +- . \} +- .. +- . +- .de xxx +- . nr num 10 +- . yyy +- .. +- +- Note that the number of available recursion levels is set +- to 1000 (this is a compile-time constant value of 'gtroff'). +- +- * The closing brace of a 'while' body must end a line. +- +- .if 1 \{\ +- . nr a 0 1 +- . while (\n[a] < 10) \{\ +- . nop \n+[a] +- .\}\} +- => unbalanced \{ \} +- +- -- Request: .break +- Break out of a 'while' loop. Be sure not to confuse this with the +- 'br' request (causing a line break). +- +- -- Request: .continue +- Finish the current iteration of a 'while' loop, immediately +- restarting the next iteration. +- +- *Note Expressions::. +- +- +-File: groff.info, Node: Writing Macros, Next: Page Motions, Prev: Conditionals and Loops, Up: gtroff Reference +- +-5.21 Writing Macros +-=================== +- +-A "macro" is a collection of text and embedded commands that can be +-invoked multiple times. Use macros to define common operations. *Note +-Strings::, for a (limited) alternative syntax to call macros. +- +- Although the following requests can be used to create macros, simply +-using an undefined macro will cause it to be defined as empty. *Note +-Identifiers::. +- +- -- Request: .de name [end] +- -- Request: .de1 name [end] +- -- Request: .dei name [end] +- -- Request: .dei1 name [end] +- Define a new macro named NAME. 'gtroff' copies subsequent lines +- (starting with the next one) into an internal buffer until it +- encounters the line '..' (two dots). If the optional second +- argument to 'de' is present it is used as the macro closure request +- instead of '..'. +- +- There can be whitespace after the first dot in the line containing +- the ending token (either '.' or macro 'END'). Don't insert a tab +- character immediately after the '..', otherwise it isn't recognized +- as the end-of-macro symbol.(1) (*note Writing Macros-Footnote-1::) +- +- Here a small example macro called 'P' that causes a break and +- inserts some vertical space. It could be used to separate +- paragraphs. +- +- .de P +- . br +- . sp .8v +- .. +- +- The following example defines a macro within another. Remember +- that expansion must be protected twice; once for reading the macro +- and once for executing. +- +- \# a dummy macro to avoid a warning +- .de end +- .. +- . +- .de foo +- . de bar end +- . nop \f[B]Hallo \\\\$1!\f[] +- . end +- .. +- . +- .foo +- .bar Joe +- => Hallo Joe! +- +- Since '\f' has no expansion, it isn't necessary to protect its +- backslash. Had we defined another macro within 'bar' that takes a +- parameter, eight backslashes would be necessary before '$1'. +- +- The 'de1' request turns off compatibility mode while executing the +- macro. On entry, the current compatibility mode is saved and +- restored at exit. +- +- .nr xxx 12345 +- . +- .de aa +- The value of xxx is \\n[xxx]. +- .. +- .de1 bb +- The value of xxx ix \\n[xxx]. +- .. +- . +- .cp 1 +- . +- .aa +- => warning: number register `[' not defined +- => The value of xxx is 0xxx]. +- .bb +- => The value of xxx ix 12345. +- +- The 'dei' request defines a macro indirectly. That is, it expands +- strings whose names are NAME or END before performing the append. +- +- This: +- +- .ds xx aa +- .ds yy bb +- .dei xx yy +- +- is equivalent to: +- +- .de aa bb +- +- The 'dei1' request is similar to 'dei' but with compatibility mode +- switched off during execution of the defined macro. +- +- If compatibility mode is on, 'de' (and 'dei') behave similar to +- 'de1' (and 'dei1'): A 'compatibility save' token is inserted at the +- beginning, and a 'compatibility restore' token at the end, with +- compatibility mode switched on during execution. *Note Gtroff +- Internals::, for more information on switching compatibility mode +- on and off in a single document. +- +- Using 'trace.tmac', you can trace calls to 'de' and 'de1'. +- +- Note that macro identifiers are shared with identifiers for strings +- and diversions. +- +- *Note the description of the 'als' request: als, for possible +- pitfalls if redefining a macro that has been aliased. +- +- -- Request: .am name [end] +- -- Request: .am1 name [end] +- -- Request: .ami name [end] +- -- Request: .ami1 name [end] +- Works similarly to 'de' except it appends onto the macro named +- NAME. So, to make the previously defined 'P' macro actually do +- indented instead of block paragraphs, add the necessary code to the +- existing macro like this: +- +- .am P +- .ti +5n +- .. +- +- The 'am1' request turns off compatibility mode while executing the +- appended macro piece. To be more precise, a "compatibility save" +- input token is inserted at the beginning of the appended code, and +- a "compatibility restore" input token at the end. +- +- The 'ami' request appends indirectly, meaning that 'gtroff' expands +- strings whose names are NAME or END before performing the append. +- +- The 'ami1' request is similar to 'ami' but compatibility mode is +- switched off during execution of the defined macro. +- +- Using 'trace.tmac', you can trace calls to 'am' and 'am1'. +- +- *Note Strings::, for the 'als' and 'rn' request to create an alias +-and rename a macro, respectively. +- +- The 'de', 'am', 'di', 'da', 'ds', and 'as' requests (together with +-its variants) only create a new object if the name of the macro, +-diversion or string diversion is currently undefined or if it is defined +-to be a request; normally they modify the value of an existing object. +- +- -- Request: .return [anything] +- Exit a macro, immediately returning to the caller. +- +- If called with an argument, exit twice, namely the current macro +- and the macro one level higher. This is used to define a wrapper +- macro for 'return' in 'trace.tmac'. +- +-* Menu: +- +-* Copy-in Mode:: +-* Parameters:: +- +- +-File: groff.info, Node: Writing Macros-Footnotes, Up: Writing Macros +- +- (1) While it is possible to define and call a macro '.' with +- +- .de . +- . tm foo +- .. +- . +- .. \" This calls macro `.'! +- +-you can't use this as the end-of-macro macro: during a macro definition, +-'..' is never handled as a call to '.', even if you say '.de foo .' +-explicitly. +- +diff -Nuar groff-1.22.3.old/doc/groff.info-2 groff-1.22.3/doc/groff.info-2 +--- groff-1.22.3.old/doc/groff.info-2 2014-11-04 10:39:07.761117246 +0200 ++++ groff-1.22.3/doc/groff.info-2 1970-01-01 02:00:00.000000000 +0200 +@@ -1,8155 +0,0 @@ +-This is groff.info, produced by makeinfo version 5.2dev from +-groff.texinfo. +- +-This manual documents GNU 'troff' version 1.22.3. +- +- Copyright 1994-2014 Free Software Foundation, Inc. +- +- Permission is granted to copy, distribute and/or modify this +- document under the terms of the GNU Free Documentation License, +- Version 1.3 or any later version published by the Free Software +- Foundation; with no Invariant Sections, with the Front-Cover texts +- being "A GNU Manual," and with the Back-Cover Texts as in (a) +- below. A copy of the license is included in the section entitled +- "GNU Free Documentation License." +- +- (a) The FSF's Back-Cover Text is: "You have the freedom to copy and +- modify this GNU manual. Buying copies from the FSF supports it in +- developing GNU and promoting software freedom." +-INFO-DIR-SECTION Typesetting +-START-INFO-DIR-ENTRY +-* Groff: (groff). The GNU troff document formatting system. +-END-INFO-DIR-ENTRY +- +- +-File: groff.info, Node: Copy-in Mode, Next: Parameters, Prev: Writing Macros, Up: Writing Macros +- +-5.21.1 Copy-in Mode +-------------------- +- +-When 'gtroff' reads in the text for a macro, string, or diversion, it +-copies the text (including request lines, but excluding escapes) into an +-internal buffer. Escapes are converted into an internal form, except +-for '\n', '\$', '\*', '\\' and '\', which are evaluated and +-inserted into the text where the escape was located. This is known as +-"copy-in" mode or "copy" mode. +- +- What this means is that you can specify when these escapes are to be +-evaluated (either at copy-in time or at the time of use) by insulating +-the escapes with an extra backslash. Compare this to the '\def' and +-'\edef' commands in TeX. +- +- The following example prints the numbers 20 and 10: +- +- .nr x 20 +- .de y +- .nr x 10 +- \&\nx +- \&\\nx +- .. +- .y +- +- +-File: groff.info, Node: Parameters, Prev: Copy-in Mode, Up: Writing Macros +- +-5.21.2 Parameters +------------------ +- +-The arguments to a macro or string can be examined using a variety of +-escapes. +- +- -- Register: \n[.$] +- The number of arguments passed to a macro or string. This is a +- read-only number register. +- +- Note that the 'shift' request can change its value. +- +- Any individual argument can be retrieved with one of the following +-escapes: +- +- -- Escape: \$n +- -- Escape: \$(nn +- -- Escape: \$[nnn] +- Retrieve the Nth, NNth or NNNth argument. As usual, the first form +- only accepts a single number (larger than zero), the second a +- two-digit number (larger or equal to 10), and the third any +- positive integer value (larger than zero). Macros and strings can +- have an unlimited number of arguments. Note that due to copy-in +- mode, use two backslashes on these in actual use to prevent +- interpolation until the macro is actually invoked. +- +- -- Request: .shift [n] +- Shift the arguments 1 position, or as many positions as specified +- by its argument. After executing this request, argument I becomes +- argument I-N; arguments 1 to N are no longer available. Shifting +- by negative amounts is currently undefined. +- +- The register '.$' is adjusted accordingly. +- +- -- Escape: \$* +- -- Escape: \$@ +- In some cases it is convenient to use all of the arguments at once +- (for example, to pass the arguments along to another macro). The +- '\$*' escape concatenates all the arguments separated by spaces. A +- similar escape is '\$@', which concatenates all the arguments with +- each surrounded by double quotes, and separated by spaces. If not +- in compatibility mode, the input level of double quotes is +- preserved (see *note Request and Macro Arguments::). +- +- -- Escape: \$^ +- Handle the parameters of a macro as if they were an argument to the +- 'ds' or similar requests. +- +- .de foo +- . tm $1=`\\$1' +- . tm $2=`\\$2' +- . tm $*=`\\$*' +- . tm $@=`\\$@' +- . tm $^=`\\$^' +- .. +- .foo " This is a "test" +- => $1=` This is a ' +- => $2=`test"' +- => $*=` This is a test"' +- => $@=`" This is a " "test""' +- => $^=`" This is a "test"' +- +- This escape is useful mainly for macro packages like 'trace.tmac', +- which redefines some requests and macros for debugging purposes. +- +- -- Escape: \$0 +- The name used to invoke the current macro. The 'als' request can +- make a macro have more than one name. +- +- If a macro is called as a string (within another macro), the value +- of '\$0' isn't changed. +- +- .de foo +- . tm \\$0 +- .. +- .als foo bar +- . +- .de aaa +- . foo +- .. +- .de bbb +- . bar +- .. +- .de ccc +- \\*[foo]\\ +- .. +- .de ddd +- \\*[bar]\\ +- .. +- . +- .aaa +- => foo +- .bbb +- => bar +- .ccc +- => ccc +- .ddd +- => ddd +- +- *Note Request and Macro Arguments::. +- +- +-File: groff.info, Node: Page Motions, Next: Drawing Requests, Prev: Writing Macros, Up: gtroff Reference +- +-5.22 Page Motions +-================= +- +-*Note Manipulating Spacing::, for a discussion of the main request for +-vertical motion, 'sp'. +- +- -- Request: .mk [reg] +- -- Request: .rt [dist] +- The request 'mk' can be used to mark a location on a page, for +- movement to later. This request takes a register name as an +- argument in which to store the current page location. With no +- argument it stores the location in an internal register. The +- results of this can be used later by the 'rt' or the 'sp' request +- (or the '\v' escape). +- +- The 'rt' request returns _upwards_ to the location marked with the +- last 'mk' request. If used with an argument, return to a position +- which distance from the top of the page is DIST (no previous call +- to 'mk' is necessary in this case). Default scaling indicator is +- 'v'. +- +- Here a primitive solution for a two-column macro. +- +- .nr column-length 1.5i +- .nr column-gap 4m +- .nr bottom-margin 1m +- . +- .de 2c +- . br +- . mk +- . ll \\n[column-length]u +- . wh -\\n[bottom-margin]u 2c-trap +- . nr right-side 0 +- .. +- . +- .de 2c-trap +- . ie \\n[right-side] \{\ +- . nr right-side 0 +- . po -(\\n[column-length]u + \\n[column-gap]u) +- . \" remove trap +- . wh -\\n[bottom-margin]u +- . \} +- . el \{\ +- . \" switch to right side +- . nr right-side 1 +- . po +(\\n[column-length]u + \\n[column-gap]u) +- . rt +- . \} +- .. +- . +- .pl 1.5i +- .ll 4i +- This is a small test that shows how the +- rt request works in combination with mk. +- +- .2c +- Starting here, text is typeset in two columns. +- Note that this implementation isn't robust +- and thus not suited for a real two-column +- macro. +- +- Result: +- +- This is a small test that shows how the +- rt request works in combination with mk. +- +- Starting here, isn't robust +- text is typeset and thus not +- in two columns. suited for a +- Note that this real two-column +- implementation macro. +- +- The following escapes give fine control of movements about the page. +- +- -- Escape: \v'e' +- Move vertically, usually from the current location on the page (if +- no absolute position operator '|' is used). The argument E +- specifies the distance to move; positive is downwards and negative +- upwards. The default scaling indicator for this escape is 'v'. +- Beware, however, that 'gtroff' continues text processing at the +- point where the motion ends, so you should always balance motions +- to avoid interference with text processing. +- +- '\v' doesn't trigger a trap. This can be quite useful; for +- example, consider a page bottom trap macro that prints a marker in +- the margin to indicate continuation of a footnote or something +- similar. +- +- There are some special-case escapes for vertical motion. +- +- -- Escape: \r +- Move upwards 1v. +- +- -- Escape: \u +- Move upwards .5v. +- +- -- Escape: \d +- Move down .5v. +- +- -- Escape: \h'e' +- Move horizontally, usually from the current location (if no +- absolute position operator '|' is used). The expression E +- indicates how far to move: positive is rightwards and negative +- leftwards. The default scaling indicator for this escape is 'm'. +- +- This horizontal space is not discarded at the end of a line. To +- insert discardable space of a certain length use the 'ss' request. +- +- There are a number of special-case escapes for horizontal motion. +- +- -- Escape: \ +- An unbreakable and unpaddable (i.e. not expanded during filling) +- space. (Note: This is a backslash followed by a space.) +- +- -- Escape: \~ +- An unbreakable space that stretches like a normal inter-word space +- when a line is adjusted. +- +- -- Escape: \| +- A 1/6th em space. Ignored for TTY output devices (rounded to +- zero). +- +- However, if there is a glyph defined in the current font file with +- name '\|' (note the leading backslash), the width of this glyph is +- used instead (even for TTYs). +- +- -- Escape: \^ +- A 1/12th em space. Ignored for TTY output devices (rounded to +- zero). +- +- However, if there is a glyph defined in the current font file with +- name '\^' (note the leading backslash), the width of this glyph is +- used instead (even for TTYs). +- +- -- Escape: \0 +- A space the size of a digit. +- +- The following string sets the TeX logo: +- +- .ds TeX T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X +- +- -- Escape: \w'text' +- -- Register: \n[st] +- -- Register: \n[sb] +- -- Register: \n[rst] +- -- Register: \n[rsb] +- -- Register: \n[ct] +- -- Register: \n[ssc] +- -- Register: \n[skw] +- Return the width of the specified TEXT in basic units. This allows +- horizontal movement based on the width of some arbitrary text (e.g. +- given as an argument to a macro). +- +- The length of the string `abc' is \w'abc'u. +- => The length of the string `abc' is 72u. +- +- Font changes may occur in TEXT, which don't affect current +- settings. +- +- After use, '\w' sets several registers: +- +- 'st' +- 'sb' +- The highest and lowest point of the baseline, respectively, in +- TEXT. +- +- 'rst' +- 'rsb' +- Like the 'st' and 'sb' registers, but takes account of the +- heights and depths of glyphs. In other words, this gives the +- highest and lowest point of TEXT. Values below the baseline +- are negative. +- +- 'ct' +- Defines the kinds of glyphs occurring in TEXT: +- +- 0 +- only short glyphs, no descenders or tall glyphs. +- +- 1 +- at least one descender. +- +- 2 +- at least one tall glyph. +- +- 3 +- at least one each of a descender and a tall glyph. +- +- 'ssc' +- The amount of horizontal space (possibly negative) that should +- be added to the last glyph before a subscript. +- +- 'skw' +- How far to right of the center of the last glyph in the '\w' +- argument, the center of an accent from a roman font should be +- placed over that glyph. +- +- -- Escape: \kp +- -- Escape: \k(ps +- -- Escape: \k[position] +- Store the current horizontal position in the _input_ line in number +- register with name POSITION (one-character name P, two-character +- name PS). Use this, for example, to return to the beginning of a +- string for highlighting or other decoration. +- +- -- Register: \n[hp] +- The current horizontal position at the input line. +- +- -- Register: \n[.k] +- A read-only number register containing the current horizontal +- output position (relative to the current indentation). +- +- -- Escape: \o'abc' +- Overstrike glyphs A, B, C, ...; the glyphs are centered, and the +- resulting spacing is the largest width of the affected glyphs. +- +- -- Escape: \zg +- Print glyph G with zero width, i.e., without spacing. Use this to +- overstrike glyphs left-aligned. +- +- -- Escape: \Z'anything' +- Print ANYTHING, then restore the horizontal and vertical position. +- The argument may not contain tabs or leaders. +- +- The following is an example of a strike-through macro: +- +- .de ST +- .nr ww \w'\\$1' +- \Z@\v'-.25m'\l'\\n[ww]u'@\\$1 +- .. +- . +- This is +- .ST "a test" +- an actual emergency! +- +- +-File: groff.info, Node: Drawing Requests, Next: Traps, Prev: Page Motions, Up: gtroff Reference +- +-5.23 Drawing Requests +-===================== +- +-'gtroff' provides a number of ways to draw lines and other figures on +-the page. Used in combination with the page motion commands (see *note +-Page Motions::, for more info), a wide variety of figures can be drawn. +-However, for complex drawings these operations can be quite cumbersome, +-and it may be wise to use graphic preprocessors like 'gpic' or 'ggrn'. +-*Note gpic::, and *note ggrn::, for more information. +- +- All drawing is done via escapes. +- +- -- Escape: \l'l' +- -- Escape: \l'lg' +- Draw a line horizontally. L is the length of the line to be drawn. +- If it is positive, start the line at the current location and draw +- to the right; its end point is the new current location. Negative +- values are handled differently: The line starts at the current +- location and draws to the left, but the current location doesn't +- move. +- +- L can also be specified absolutely (i.e. with a leading '|'), which +- draws back to the beginning of the input line. Default scaling +- indicator is 'm'. +- +- The optional second parameter G is a glyph to draw the line with. +- If this second argument is not specified, 'gtroff' uses the +- underscore glyph, '\[ru]'. +- +- To separate the two arguments (to prevent 'gtroff' from +- interpreting a drawing glyph as a scaling indicator if the glyph is +- represented by a single character) use '\&'. +- +- Here a small useful example: +- +- .de box +- \[br]\\$*\[br]\l'|0\[rn]'\l'|0\[ul]' +- .. +- +- Note that this works by outputting a box rule (a vertical line), +- then the text given as an argument and then another box rule. +- Finally, the line drawing escapes both draw from the current +- location to the beginning of the _input_ line - this works because +- the line length is negative, not moving the current point. +- +- -- Escape: \L'l' +- -- Escape: \L'lg' +- Draw vertical lines. Its parameters are similar to the '\l' +- escape, except that the default scaling indicator is 'v'. The +- movement is downwards for positive values, and upwards for negative +- values. The default glyph is the box rule glyph, '\[br]'. As with +- the vertical motion escapes, text processing blindly continues +- where the line ends. +- +- This is a \L'3v'test. +- +- Here the result, produced with 'grotty'. +- +- This is a +- | +- | +- |test. +- +- -- Escape: \D'command arg ...' +- The '\D' escape provides a variety of drawing functions. Note that +- on character devices, only vertical and horizontal lines are +- supported within 'grotty'; other devices may only support a subset +- of the available drawing functions. +- +- The default scaling indicator for all subcommands of '\D' is 'm' +- for horizontal distances and 'v' for vertical ones. Exceptions are +- '\D'f ...'' and '\D't ...'', which use 'u' as the default, and +- '\D'FX ...'', which arguments are treated similar to the 'defcolor' +- request. +- +- '\D'l DX DY'' +- Draw a line from the current location to the relative point +- specified by (DX,DY), where positive values mean down and +- right, respectively. The end point of the line is the new +- current location. +- +- The following example is a macro for creating a box around a +- text string; for simplicity, the box margin is taken as a +- fixed value, 0.2m. +- +- .de BOX +- . nr @wd \w'\\$1' +- \h'.2m'\ +- \h'-.2m'\v'(.2m - \\n[rsb]u)'\ +- \D'l 0 -(\\n[rst]u - \\n[rsb]u + .4m)'\ +- \D'l (\\n[@wd]u + .4m) 0'\ +- \D'l 0 (\\n[rst]u - \\n[rsb]u + .4m)'\ +- \D'l -(\\n[@wd]u + .4m) 0'\ +- \h'.2m'\v'-(.2m - \\n[rsb]u)'\ +- \\$1\ +- \h'.2m' +- .. +- +- First, the width of the string is stored in register '@wd'. +- Then, four lines are drawn to form a box, properly offset by +- the box margin. The registers 'rst' and 'rsb' are set by the +- '\w' escape, containing the largest height and depth of the +- whole string. +- +- '\D'c D'' +- Draw a circle with a diameter of D with the leftmost point at +- the current position. After drawing, the current location is +- positioned at the rightmost point of the circle. +- +- '\D'C D'' +- Draw a solid circle with the same parameters and behaviour as +- an outlined circle. No outline is drawn. +- +- '\D'e X Y'' +- Draw an ellipse with a horizontal diameter of X and a vertical +- diameter of Y with the leftmost point at the current position. +- After drawing, the current location is positioned at the +- rightmost point of the ellipse. +- +- '\D'E X Y'' +- Draw a solid ellipse with the same parameters and behaviour as +- an outlined ellipse. No outline is drawn. +- +- '\D'a DX1 DY1 DX2 DY2'' +- Draw an arc clockwise from the current location through the +- two specified relative locations (DX1,DY1) and (DX2,DY2). The +- coordinates of the first point are relative to the current +- position, and the coordinates of the second point are relative +- to the first point. After drawing, the current position is +- moved to the final point of the arc. +- +- '\D'~ DX1 DY1 DX2 DY2 ...'' +- Draw a spline from the current location to the relative point +- (DX1,DY1) and then to (DX2,DY2), and so on. The current +- position is moved to the terminal point of the drawn curve. +- +- '\D'f N'' +- Set the shade of gray to be used for filling solid objects +- to N; N must be an integer between 0 and 1000, where 0 +- corresponds solid white and 1000 to solid black, and values in +- between correspond to intermediate shades of gray. This +- applies only to solid circles, solid ellipses, and solid +- polygons. By default, a level of 1000 is used. +- +- Despite of being silly, the current point is moved +- horizontally to the right by N. +- +- Don't use this command! It has the serious drawback that it +- is always rounded to the next integer multiple of the +- horizontal resolution (the value of the 'hor' keyword in the +- 'DESC' file). Use '\M' (*note Colors::) or '\D'Fg ...'' +- instead. +- +- '\D'p DX1 DY1 DX2 DY2 ...'' +- Draw a polygon from the current location to the relative +- position (DX1,DY1) and then to (DX2,DY2) and so on. When the +- specified data points are exhausted, a line is drawn back to +- the starting point. The current position is changed by adding +- the sum of all arguments with odd index to the actual +- horizontal position and the even ones to the vertical +- position. +- +- '\D'P DX1 DY1 DX2 DY2 ...'' +- Draw a solid polygon with the same parameters and behaviour as +- an outlined polygon. No outline is drawn. +- +- Here a better variant of the box macro to fill the box with +- some color. Note that the box must be drawn before the text +- since colors in 'gtroff' are not transparent; the filled +- polygon would hide the text completely. +- +- .de BOX +- . nr @wd \w'\\$1' +- \h'.2m'\ +- \h'-.2m'\v'(.2m - \\n[rsb]u)'\ +- \M[lightcyan]\ +- \D'P 0 -(\\n[rst]u - \\n[rsb]u + .4m) \ +- (\\n[@wd]u + .4m) 0 \ +- 0 (\\n[rst]u - \\n[rsb]u + .4m) \ +- -(\\n[@wd]u + .4m) 0'\ +- \h'.2m'\v'-(.2m - \\n[rsb]u)'\ +- \M[]\ +- \\$1\ +- \h'.2m' +- .. +- +- If you want a filled polygon that has exactly the same size as +- an unfilled one, you must draw both an unfilled and a filled +- polygon. A filled polygon is always smaller than an unfilled +- one because the latter uses straight lines with a given line +- thickness to connect the polygon's corners, while the former +- simply fills the area defined by the coordinates. +- +- \h'1i'\v'1i'\ +- \# increase line thickness +- \Z'\D't 5p''\ +- \# draw unfilled polygon +- \Z'\D'p 3 3 -6 0''\ +- \# draw filled polygon +- \Z'\D'P 3 3 -6 0'' +- +- '\D't N'' +- Set the current line thickness to N machine units. A value of +- zero selects the smallest available line thickness. A +- negative value makes the line thickness proportional to the +- current point size (this is the default behaviour of AT&T +- 'troff'). +- +- Despite of being silly, the current point is moved +- horizontally to the right by N. +- +- '\D'FSCHEME COLOR_COMPONENTS'' +- Change current fill color. SCHEME is a single letter denoting +- the color scheme: 'r' (rgb), 'c' (cmy), 'k' (cmyk), 'g' +- (gray), or 'd' (default color). The color components use +- exactly the same syntax as in the 'defcolor' request (*note +- Colors::); the command '\D'Fd'' doesn't take an argument. +- +- _No_ position changing! +- +- Examples: +- +- \D'Fg .3' \" same gray as \D'f 700' +- \D'Fr #0000ff' \" blue +- +- *Note Graphics Commands::. +- +- -- Escape: \b'string' +- "Pile" a sequence of glyphs vertically, and center it vertically on +- the current line. Use it to build large brackets and braces. +- +- Here an example how to create a large opening brace: +- +- \b'\[lt]\[bv]\[lk]\[bv]\[lb]' +- +- The first glyph is on the top, the last glyph in STRING is at the +- bottom. Note that 'gtroff' separates the glyphs vertically by 1m, +- and the whole object is centered 0.5m above the current baseline; +- the largest glyph width is used as the width for the whole object. +- This rather unflexible positioning algorithm doesn't work with +- '-Tdvi' since the bracket pieces vary in height for this device. +- Instead, use the 'eqn' preprocessor. +- +- *Note Manipulating Spacing::, how to adjust the vertical spacing +- with the '\x' escape. +- +- +-File: groff.info, Node: Traps, Next: Diversions, Prev: Drawing Requests, Up: gtroff Reference +- +-5.24 Traps +-========== +- +-"Traps" are locations that, when reached, call a specified macro. These +-traps can occur at a given location on the page, at a given location in +-the current diversion, at a blank line, after a certain number of input +-lines, or at the end of input. +- +- Setting a trap is also called "planting". It is also said that a +-trap is "sprung" if the associated macro is executed. +- +-* Menu: +- +-* Page Location Traps:: +-* Diversion Traps:: +-* Input Line Traps:: +-* Blank Line Traps:: +-* Leading Spaces Traps:: +-* End-of-input Traps:: +- +- +-File: groff.info, Node: Page Location Traps, Next: Diversion Traps, Prev: Traps, Up: Traps +- +-5.24.1 Page Location Traps +--------------------------- +- +-"Page location traps" perform an action when 'gtroff' reaches or passes +-a certain vertical location on the page. Page location traps have a +-variety of purposes, including: +- +- * setting headers and footers +- +- * setting body text in multiple columns +- +- * setting footnotes +- +- -- Request: .vpt flag +- -- Register: \n[.vpt] +- Enable vertical position traps if FLAG is non-zero, or disables +- them otherwise. Vertical position traps are traps set by the 'wh' +- or 'dt' requests. Traps set by the 'it' request are not vertical +- position traps. The parameter that controls whether vertical +- position traps are enabled is global. Initially vertical position +- traps are enabled. The current setting of this is available in the +- '.vpt' read-only number register. +- +- Note that a page can't be ejected if 'vpt' is set to zero. +- +- -- Request: .wh dist [macro] +- Set a page location trap. Non-negative values for DIST set the +- trap relative to the top of the page; negative values set the trap +- relative to the bottom of the page. Default scaling indicator is +- 'v'; values of DIST are always rounded to be multiples of the +- vertical resolution (as given in register '.V'). +- +- MACRO is the name of the macro to execute when the trap is sprung. +- If MACRO is missing, remove the first trap (if any) at DIST. +- +- The following is a simple example of how many macro packages set +- headers and footers. +- +- .de hd \" Page header +- ' sp .5i +- . tl 'Title''date' +- ' sp .3i +- .. +- . +- .de fo \" Page footer +- ' sp 1v +- . tl ''%'' +- ' bp +- .. +- . +- .wh 0 hd \" trap at top of the page +- .wh -1i fo \" trap one inch from bottom +- +- A trap at or below the bottom of the page is ignored; it can be +- made active by either moving it up or increasing the page length so +- that the trap is on the page. +- +- Negative trap values always use the _current_ page length; they are +- not converted to an absolute vertical position: +- +- .pl 5i +- .wh -1i xx +- .ptr +- => xx -240 +- .pl 100i +- .ptr +- => xx -240 +- +- It is possible to have more than one trap at the same location; to +- do so, the traps must be defined at different locations, then moved +- together with the 'ch' request; otherwise the second trap would +- replace the first one. Earlier defined traps hide later defined +- traps if moved to the same position (the many empty lines caused by +- the 'bp' request are omitted in the following example): +- +- .de a +- . nop a +- .. +- .de b +- . nop b +- .. +- .de c +- . nop c +- .. +- . +- .wh 1i a +- .wh 2i b +- .wh 3i c +- .bp +- => a b c +- .ch b 1i +- .ch c 1i +- .bp +- => a +- .ch a 0.5i +- .bp +- => a b +- +- -- Register: \n[.t] +- A read-only number register holding the distance to the next trap. +- +- If there are no traps between the current position and the bottom +- of the page, it contains the distance to the page bottom. In a +- diversion, the distance to the page bottom is infinite (the +- returned value is the biggest integer that can be represented in +- 'groff') if there are no diversion traps. +- +- -- Request: .ch macro [dist] +- Change the location of a trap. The first argument is the name of +- the macro to be invoked at the trap, and the second argument is the +- new location for the trap (note that the parameters are specified +- in opposite order as in the 'wh' request). This is useful for +- building up footnotes in a diversion to allow more space at the +- bottom of the page for them. +- +- Default scaling indicator for DIST is 'v'. If DIST is missing, the +- trap is removed. +- +- -- Register: \n[.ne] +- The read-only number register '.ne' contains the amount of space +- that was needed in the last 'ne' request that caused a trap to be +- sprung. Useful in conjunction with the '.trunc' register. *Note +- Page Control::, for more information. +- +- Since the '.ne' register is only set by traps it doesn't make much +- sense to use it outside of trap macros. +- +- -- Register: \n[.trunc] +- A read-only register containing the amount of vertical space +- truncated by the most recently sprung vertical position trap, or, +- if the trap was sprung by an 'ne' request, minus the amount of +- vertical motion produced by the 'ne' request. In other words, at +- the point a trap is sprung, it represents the difference of what +- the vertical position would have been but for the trap, and what +- the vertical position actually is. +- +- Since the '.trunc' register is only set by traps it doesn't make +- much sense to use it outside of trap macros. +- +- -- Register: \n[.pe] +- A read-only register that is set to 1 while a page is ejected with +- the 'bp' request (or by the end of input). +- +- Outside of traps this register is always zero. In the following +- example, only the second call to 'x' is caused by 'bp'. +- +- .de x +- \&.pe=\\n[.pe] +- .br +- .. +- .wh 1v x +- .wh 4v x +- A line. +- .br +- Another line. +- .br +- => A line. +- .pe=0 +- Another line. +- +- .pe=1 +- +- An important fact to consider while designing macros is that +-diversions and traps do not interact normally. For example, if a trap +-invokes a header macro (while outputting a diversion) that tries to +-change the font on the current page, the effect is not visible before +-the diversion has completely been printed (except for input protected +-with '\!' or '\?') since the data in the diversion is already formatted. +-In most cases, this is not the expected behaviour. +- +- +-File: groff.info, Node: Diversion Traps, Next: Input Line Traps, Prev: Page Location Traps, Up: Traps +- +-5.24.2 Diversion Traps +----------------------- +- +- -- Request: .dt [dist macro] +- Set a trap _within_ a diversion. DIST is the location of the trap +- (identical to the 'wh' request; default scaling indicator is 'v') +- and MACRO is the name of the macro to be invoked. If called +- without arguments, the diversion trap is removed. +- +- Note that there exists only a single diversion trap. +- +- The number register '.t' still works within diversions. *Note +- Diversions::, for more information. +- +- +-File: groff.info, Node: Input Line Traps, Next: Blank Line Traps, Prev: Diversion Traps, Up: Traps +- +-5.24.3 Input Line Traps +------------------------ +- +- -- Request: .it n macro +- -- Request: .itc n macro +- Set an input line trap. N is the number of lines of input that may +- be read before springing the trap, MACRO is the macro to be +- invoked. Request lines are not counted as input lines. +- +- For example, one possible use is to have a macro that prints the +- next N lines in a bold font. +- +- .de B +- . it \\$1 B-end +- . ft B +- .. +- . +- .de B-end +- . ft R +- .. +- +- The 'itc' request is identical except that an interrupted text line +- (ending with '\c') is not counted as a separate line. +- +- Both requests are associated with the current environment (*note +- Environments::); switching to another environment disables the +- current input trap, and going back reactivates it, restoring the +- number of already processed lines. +- +- +-File: groff.info, Node: Blank Line Traps, Next: Leading Spaces Traps, Prev: Input Line Traps, Up: Traps +- +-5.24.4 Blank Line Traps +------------------------ +- +- -- Request: .blm macro +- Set a blank line trap. 'gtroff' executes MACRO when it encounters +- a blank line in the input file. +- +- +-File: groff.info, Node: Leading Spaces Traps, Next: End-of-input Traps, Prev: Blank Line Traps, Up: Traps +- +-5.24.5 Leading Spaces Traps +---------------------------- +- +- -- Request: .lsm macro +- -- Register: \n[lsn] +- -- Register: \n[lss] +- Set a leading spaces trap. 'gtroff' executes MACRO when it +- encounters leading spaces in an input line; the implicit line break +- that normally happens in this case is suppressed. A line +- consisting of spaces only, however, is treated as an empty line, +- possibly subject to an empty line macro set with the 'blm' request. +- +- Leading spaces are removed from the input line before calling the +- leading spaces macro. The number of removed spaces is stored in +- register 'lsn'; the horizontal space that would be emitted if there +- was no leading space macro is stored in register 'lss'. Note that +- 'lsn' and 'lss' are available even if no leading space macro has +- been set. +- +- The first thing a leading space macro sees is a token. However, +- some escapes like '\f' or '\m' are handled on the fly (see *note +- Gtroff Internals::, for a complete list) without creating a token +- at all. Consider that a line starts with two spaces followed by +- '\fIfoo'. While skipping the spaces '\fI' is handled too so that +- groff's current font is properly set to 'I', but the leading space +- macro only sees 'foo', without the preceding '\fI'. If the macro +- should see the font escape you have to 'protect' it with something +- that creates a token, for example with '\&\fIfoo'. +- +- +-File: groff.info, Node: End-of-input Traps, Prev: Leading Spaces Traps, Up: Traps +- +-5.24.6 End-of-input Traps +-------------------------- +- +- -- Request: .em macro +- Set a trap at the end of input. MACRO is executed after the last +- line of the input file has been processed. +- +- For example, if the document had to have a section at the bottom of +- the last page for someone to approve it, the 'em' request could be +- used. +- +- .de approval +- \c +- . ne 3v +- . sp (\\n[.t]u - 3v) +- . in +4i +- . lc _ +- . br +- Approved:\t\a +- . sp +- Date:\t\t\a +- .. +- . +- .em approval +- +- The '\c' in the above example needs explanation. For historical +- reasons (and for compatibility with AT&T 'troff'), the end macro +- exits as soon as it causes a page break and no remaining data is in +- the partially collected line. +- +- Let us assume that there is no '\c' in the above 'approval' macro, +- and that the page is full and has been ended with, say, a 'br' +- request. The 'ne' request now causes the start of a new page, +- which in turn makes 'troff' exit immediately for the reasons just +- described. In most situations this is not intended. +- +- To always force processing the whole end macro independently of +- this behaviour it is thus advisable to insert something that starts +- an empty partially filled line ('\c') whenever there is a chance +- that a page break can happen. In the above example, the call of +- the 'ne' request assures that the remaining code stays on the same +- page, so we have to insert '\c' only once. +- +- The next example shows how to append three lines, then starting a +- new page unconditionally. Since '.ne 1' doesn't give the desired +- effect - there is always one line available or we are already at +- the beginning of the next page - we temporarily increase the page +- length by one line so that we can use '.ne 2'. +- +- .de EM +- .pl +1v +- \c +- .ne 2 +- line one +- .br +- \c +- .ne 2 +- line two +- .br +- \c +- .ne 2 +- line three +- .br +- .pl -1v +- \c +- 'bp +- .. +- .em EM +- +- Note that this specific feature affects only the first potential +- page break caused by the end macro; further page breaks emitted by +- the end macro are handled normally. +- +- Another possible use of the 'em' request is to make 'gtroff' emit a +- single large page instead of multiple pages. For example, one may +- want to produce a long plain-text file for reading on-screen. The +- idea is to set the page length at the beginning of the document to +- a very large value to hold all the text, and automatically adjust +- it to the exact height of the document after the text has been +- output. +- +- .de adjust-page-length +- . br +- . pl \\n[nl]u \" \n[nl] holds the current page length +- .. +- . +- .de single-page-mode +- . pl 99999 +- . em adjust-page-length +- .. +- . +- .\" activate the above code +- .single-page-mode +- +- Since only one end-of-input trap does exist and other macro +- packages may already use it, care must be taken not to break the +- mechanism. A simple solution would be to append the above macro to +- the macro package's end-of-input macro using the '.am' request. +- +- +-File: groff.info, Node: Diversions, Next: Environments, Prev: Traps, Up: gtroff Reference +- +-5.25 Diversions +-=============== +- +-In 'gtroff' it is possible to "divert" text into a named storage area. +-Due to the similarity to defining macros it is sometimes said to be +-stored in a macro. This is used for saving text for output at a later +-time, which is useful for keeping blocks of text on the same page, +-footnotes, tables of contents, and indices. +- +- For orthogonality it is said that 'gtroff' is in the "top-level +-diversion" if no diversion is active (i.e., the data is diverted to the +-output device). +- +- Although the following requests can be used to create diversions, +-simply using an undefined diversion will cause it to be defined as +-empty. *Note Identifiers::. +- +- -- Request: .di macro +- -- Request: .da macro +- Begin a diversion. Like the 'de' request, it takes an argument of +- a macro name to divert subsequent text into. The 'da' macro +- appends to an existing diversion. +- +- 'di' or 'da' without an argument ends the diversion. +- +- The current partially-filled line is included into the diversion. +- See the 'box' request below for an example. Note that switching to +- another (empty) environment (with the 'ev' request) avoids the +- inclusion of the current partially-filled line. +- +- -- Request: .box macro +- -- Request: .boxa macro +- Begin (or append to) a diversion like the 'di' and 'da' requests. +- The difference is that 'box' and 'boxa' do not include a +- partially-filled line in the diversion. +- +- Compare this: +- +- Before the box. +- .box xxx +- In the box. +- .br +- .box +- After the box. +- .br +- => Before the box. After the box. +- .xxx +- => In the box. +- +- with this: +- +- Before the diversion. +- .di yyy +- In the diversion. +- .br +- .di +- After the diversion. +- .br +- => After the diversion. +- .yyy +- => Before the diversion. In the diversion. +- +- 'box' or 'boxa' without an argument ends the diversion. +- +- -- Register: \n[.z] +- -- Register: \n[.d] +- Diversions may be nested. The read-only number register '.z' +- contains the name of the current diversion (this is a string-valued +- register). The read-only number register '.d' contains the current +- vertical place in the diversion. If not in a diversion it is the +- same as register 'nl'. +- +- -- Register: \n[.h] +- The "high-water mark" on the current page. It corresponds to the +- text baseline of the lowest line on the page. This is a read-only +- register. +- +- .tm .h==\n[.h], nl==\n[nl] +- => .h==0, nl==-1 +- This is a test. +- .br +- .sp 2 +- .tm .h==\n[.h], nl==\n[nl] +- => .h==40, nl==120 +- +- As can be seen in the previous example, empty lines are not +- considered in the return value of the '.h' register. +- +- -- Register: \n[dn] +- -- Register: \n[dl] +- After completing a diversion, the read-write number registers 'dn' +- and 'dl' contain the vertical and horizontal size of the diversion. +- Note that only the just processed lines are counted: For the +- computation of 'dn' and 'dl', the requests 'da' and 'boxa' are +- handled as if 'di' and 'box' had been used - lines that have been +- already stored in a macro are not taken into account. +- +- .\" Center text both horizontally & vertically +- . +- .\" Enclose macro definitions in .eo and .ec +- .\" to avoid the doubling of the backslash +- .eo +- .\" macro .(c starts centering mode +- .de (c +- . br +- . ev (c +- . evc 0 +- . in 0 +- . nf +- . di @c +- .. +- .\" macro .)c terminates centering mode +- .de )c +- . br +- . ev +- . di +- . nr @s (((\n[.t]u - \n[dn]u) / 2u) - 1v) +- . sp \n[@s]u +- . ce 1000 +- . @c +- . ce 0 +- . sp \n[@s]u +- . br +- . fi +- . rr @s +- . rm @s +- . rm @c +- .. +- .\" End of macro definitions, restore escape mechanism +- .ec +- +- -- Escape: \! +- -- Escape: \?anything\? +- Prevent requests, macros, and escapes from being interpreted when +- read into a diversion. Both escapes take the given text and +- "transparently" embed it into the diversion. This is useful for +- macros that shouldn't be invoked until the diverted text is +- actually output. +- +- The '\!' escape transparently embeds text up to and including the +- end of the line. The '\?' escape transparently embeds text until +- the next occurrence of the '\?' escape. Example: +- +- \?ANYTHING\? +- +- ANYTHING may not contain newlines; use '\!' to embed newlines in a +- diversion. The escape sequence '\?' is also recognized in copy +- mode and turned into a single internal code; it is this code that +- terminates ANYTHING. Thus the following example prints 4. +- +- .nr x 1 +- .nf +- .di d +- \?\\?\\\\?\\\\\\\\nx\\\\?\\?\? +- .di +- .nr x 2 +- .di e +- .d +- .di +- .nr x 3 +- .di f +- .e +- .di +- .nr x 4 +- .f +- +- Both escapes read the data in copy mode. +- +- If '\!' is used in the top-level diversion, its argument is +- directly embedded into the 'gtroff' intermediate output. This can +- be used for example to control a postprocessor that processes the +- data before it is sent to the device driver. +- +- The '\?' escape used in the top-level diversion produces no output +- at all; its argument is simply ignored. +- +- -- Request: .output string +- Emit STRING directly to the 'gtroff' intermediate output (subject +- to copy mode interpretation); this is similar to '\!' used at the +- top level. An initial double quote in STRING is stripped off to +- allow initial blanks. +- +- This request can't be used before the first page has started - if +- you get an error, simply insert '.br' before the 'output' request. +- +- Without argument, 'output' is ignored. +- +- Use with caution! It is normally only needed for mark-up used by a +- postprocessor that does something with the output before sending it +- to the output device, filtering out STRING again. +- +- -- Request: .asciify div +- "Unformat" the diversion specified by DIV in such a way that ASCII +- characters, characters translated with the 'trin' request, space +- characters, and some escape sequences that were formatted and +- diverted are treated like ordinary input characters when the +- diversion is reread. It can be also used for gross hacks; for +- example, the following sets register 'n' to 1. +- +- .tr @. +- .di x +- @nr n 1 +- .br +- .di +- .tr @@ +- .asciify x +- .x +- +- Note that 'asciify' cannot return all items in a diversion back to +- their source equivalent, nodes such as '\N[...]' will still remain +- as nodes, so the result cannot be guaranteed to be a pure string. +- +- *Note Copy-in Mode::. +- +- -- Request: .unformat div +- Like 'asciify', unformat the specified diversion. However, +- 'unformat' only unformats spaces and tabs between words. +- Unformatted tabs are treated as input tokens, and spaces are +- stretchable again. +- +- The vertical size of lines is not preserved; glyph information +- (font, font size, space width, etc.) is retained. +- +- +-File: groff.info, Node: Environments, Next: Suppressing output, Prev: Diversions, Up: gtroff Reference +- +-5.26 Environments +-================= +- +-It happens frequently that some text should be printed in a certain +-format regardless of what may be in effect at the time, for example, in +-a trap invoked macro to print headers and footers. To solve this +-'gtroff' processes text in "environments". An environment contains most +-of the parameters that control text processing. It is possible to +-switch amongst these environments; by default 'gtroff' processes text in +-environment 0. The following is the information kept in an environment. +- +- * font parameters (size, family, style, glyph height and slant, space +- and sentence space size) +- +- * page parameters (line length, title length, vertical spacing, line +- spacing, indentation, line numbering, centering, right-justifying, +- underlining, hyphenation data) +- +- * fill and adjust mode +- +- * tab stops, tab and leader characters, escape character, no-break +- and hyphen indicators, margin character data +- +- * partially collected lines +- +- * input traps +- +- * drawing and fill colours +- +- These environments may be given arbitrary names (see *note +-Identifiers::, for more info). Old versions of 'troff' only had +-environments named '0', '1', and '2'. +- +- -- Request: .ev [env] +- -- Register: \n[.ev] +- Switch to another environment. The argument ENV is the name of the +- environment to switch to. With no argument, 'gtroff' switches back +- to the previous environment. There is no limit on the number of +- named environments; they are created the first time that they are +- referenced. The '.ev' read-only register contains the name or +- number of the current environment. This is a string-valued +- register. +- +- Note that a call to 'ev' (with argument) pushes the previously +- active environment onto a stack. If, say, environments 'foo', +- 'bar', and 'zap' are called (in that order), the first 'ev' request +- without parameter switches back to environment 'bar' (which is +- popped off the stack), and a second call switches back to +- environment 'foo'. +- +- Here is an example: +- +- .ev footnote-env +- .fam N +- .ps 6 +- .vs 8 +- .ll -.5i +- .ev +- +- ... +- +- .ev footnote-env +- \(dg Note the large, friendly letters. +- .ev +- +- -- Request: .evc env +- Copy the environment ENV into the current environment. +- +- The following environment data is not copied: +- +- * Partially filled lines. +- +- * The status whether the previous line was interrupted. +- +- * The number of lines still to center, or to right-justify, or +- to underline (with or without underlined spaces); they are set +- to zero. +- +- * The status whether a temporary indentation is active. +- +- * Input traps and its associated data. +- +- * Line numbering mode is disabled; it can be reactivated with +- '.nm +0'. +- +- * The number of consecutive hyphenated lines (set to zero). +- +- -- Register: \n[.w] +- -- Register: \n[.cht] +- -- Register: \n[.cdp] +- -- Register: \n[.csk] +- The '\n[.w]' register contains the width of the last glyph added to +- the current environment. +- +- The '\n[.cht]' register contains the height of the last glyph added +- to the current environment. +- +- The '\n[.cdp]' register contains the depth of the last glyph added +- to the current environment. It is positive for glyphs extending +- below the baseline. +- +- The '\n[.csk]' register contains the "skew" (how far to the right +- of the glyph's center that 'gtroff' should place an accent) of the +- last glyph added to the current environment. +- +- -- Register: \n[.n] +- The '\n[.n]' register contains the length of the previous output +- line in the current environment. +- +- +-File: groff.info, Node: Suppressing output, Next: Colors, Prev: Environments, Up: gtroff Reference +- +-5.27 Suppressing output +-======================= +- +- -- Escape: \Onum +- Disable or enable output depending on the value of NUM: +- +- '\O0' +- Disable any glyphs from being emitted to the device driver, +- provided that the escape occurs at the outer level (see +- '\O[3]' and '\O[4]'). Motion is not suppressed so effectively +- '\O[0]' means _pen up_. +- +- '\O1' +- Enable output of glyphs, provided that the escape occurs at +- the outer level. +- +- '\O0' and '\O1' also reset the four registers 'opminx', 'opminy', +- 'opmaxx', and 'opmaxy' to -1. *Note Register Index::. These four +- registers mark the top left and bottom right hand corners of a box +- that encompasses all written glyphs. +- +- For example the input text: +- +- Hello \O[0]world \O[1]this is a test. +- +- produces the following output: +- +- Hello this is a test. +- +- '\O2' +- Provided that the escape occurs at the outer level, enable +- output of glyphs and also write out to 'stderr' the page +- number and four registers encompassing the glyphs previously +- written since the last call to '\O'. +- +- '\O3' +- Begin a nesting level. At start-up, 'gtroff' is at outer +- level. The current level is contained within the read-only +- register '.O'. *Note Built-in Registers::. +- +- '\O4' +- End a nesting level. The current level is contained within +- the read-only register '.O'. *Note Built-in Registers::. +- +- '\O[5PFILENAME]' +- This escape is 'grohtml' specific. Provided that this escape +- occurs at the outer nesting level write the 'filename' to +- 'stderr'. The position of the image, P, must be specified and +- must be one of 'l', 'r', 'c', or 'i' (left, right, centered, +- inline). FILENAME is associated with the production of the +- next inline image. +- +- +-File: groff.info, Node: Colors, Next: I/O, Prev: Suppressing output, Up: gtroff Reference +- +-5.28 Colors +-=========== +- +- -- Request: .color [n] +- -- Register: \n[.color] +- If N is missing or non-zero, activate colors (this is the default); +- otherwise, turn it off. +- +- The read-only number register '.color' is 1 if colors are active, +- 0 otherwise. +- +- Internally, 'color' sets a global flag; it does not produce a +- token. Similar to the 'cp' request, you should use it at the +- beginning of your document to control color output. +- +- Colors can be also turned off with the '-c' command line option. +- +- -- Request: .defcolor ident scheme color_components +- Define color with name IDENT. SCHEME can be one of the following +- values: 'rgb' (three components), 'cmy' (three components), 'cmyk' +- (four components), and 'gray' or 'grey' (one component). +- +- Color components can be given either as a hexadecimal string or as +- positive decimal integers in the range 0-65535. A hexadecimal +- string contains all color components concatenated. It must start +- with either '#' or '##'; the former specifies hex values in the +- range 0-255 (which are internally multiplied by 257), the latter in +- the range 0-65535. Examples: '#FFC0CB' (pink), '##ffff0000ffff' +- (magenta). The default color name value is device-specific +- (usually black). It is possible that the default color for '\m' +- and '\M' is not identical. +- +- A new scaling indicator 'f' has been introduced, which multiplies +- its value by 65536; this makes it convenient to specify color +- components as fractions in the range 0 to 1 (1f equals 65536u). +- Example: +- +- .defcolor darkgreen rgb 0.1f 0.5f 0.2f +- +- Note that 'f' is the default scaling indicator for the 'defcolor' +- request, thus the above statement is equivalent to +- +- .defcolor darkgreen rgb 0.1 0.5 0.2 +- +- -- Request: .gcolor [color] +- -- Escape: \mc +- -- Escape: \m(co +- -- Escape: \m[color] +- -- Register: \n[.m] +- Set (glyph) drawing color. The following examples show how to turn +- the next four words red. +- +- .gcolor red +- these are in red +- .gcolor +- and these words are in black. +- +- \m[red]these are in red\m[] and these words are in black. +- +- The escape '\m[]' returns to the previous color, as does a call to +- 'gcolor' without an argument. +- +- The name of the current drawing color is available in the +- read-only, string-valued number register '.m'. +- +- The drawing color is associated with the current environment (*note +- Environments::). +- +- Note that '\m' doesn't produce an input token in 'gtroff'. As a +- consequence, it can be used in requests like 'mc' (which expects a +- single character as an argument) to change the color on the fly: +- +- .mc \m[red]x\m[] +- +- -- Request: .fcolor [color] +- -- Escape: \Mc +- -- Escape: \M(co +- -- Escape: \M[color] +- -- Register: \n[.M] +- Set fill (background) color for filled objects drawn with the +- '\D'...'' commands. +- +- A red ellipse can be created with the following code: +- +- \M[red]\h'0.5i'\D'E 2i 1i'\M[] +- +- The escape '\M[]' returns to the previous fill color, as does a +- call to 'fcolor' without an argument. +- +- The name of the current fill (background) color is available in the +- read-only, string-valued number register '.M'. +- +- The fill color is associated with the current environment (*note +- Environments::). +- +- Note that '\M' doesn't produce an input token in 'gtroff'. +- +- +-File: groff.info, Node: I/O, Next: Postprocessor Access, Prev: Colors, Up: gtroff Reference +- +-5.29 I/O +-======== +- +-'gtroff' has several requests for including files: +- +- -- Request: .so file +- Read in the specified FILE and includes it in place of the 'so' +- request. This is quite useful for large documents, e.g. keeping +- each chapter in a separate file. *Note gsoelim::, for more +- information. +- +- Since 'gtroff' replaces the 'so' request with the contents of +- 'file', it makes a difference whether the data is terminated with a +- newline or not: Assuming that file 'xxx' contains the word 'foo' +- without a final newline, this +- +- This is +- .so xxx +- bar +- +- yields 'This is foobar'. +- +- The search path for FILE can be controlled with the '-I' command +- line option. +- +- -- Request: .pso command +- Read the standard output from the specified COMMAND and includes it +- in place of the 'pso' request. +- +- This request causes an error if used in safer mode (which is the +- default). Use 'groff''s or 'troff''s '-U' option to activate +- unsafe mode. +- +- The comment regarding a final newline for the 'so' request is valid +- for 'pso' also. +- +- -- Request: .mso file +- Identical to the 'so' request except that 'gtroff' searches for the +- specified FILE in the same directories as macro files for the the +- '-m' command line option. If the file name to be included has the +- form 'NAME.tmac' and it isn't found, 'mso' tries to include +- 'tmac.NAME' and vice versa. If the file does not exist, a warning +- of type 'file' is emitted. *Note Debugging::, for information +- about warnings. +- +- -- Request: .trf file +- -- Request: .cf file +- Transparently output the contents of FILE. Each line is output as +- if it were preceded by '\!'; however, the lines are _not_ subject +- to copy mode interpretation. If the file does not end with a +- newline, then a newline is added ('trf' only). For example, to +- define a macro 'x' containing the contents of file 'f', use +- +- .ev 1 +- .di x +- .trf f +- .di +- .ev +- +- The calls to 'ev' prevent that the current partial input line +- becomes part of the diversion. +- +- Both 'trf' and 'cf', when used in a diversion, embeds an object in +- the diversion which, when reread, causes the contents of FILE to be +- transparently copied through to the output. In UNIX 'troff', the +- contents of FILE is immediately copied through to the output +- regardless of whether there is a current diversion; this behaviour +- is so anomalous that it must be considered a bug. +- +- While 'cf' copies the contents of FILE completely unprocessed, +- 'trf' disallows characters such as NUL that are not valid 'gtroff' +- input characters (*note Identifiers::). +- +- For 'cf', within a diversion, 'completely unprocessed' means that +- each line of a file to be inserted is handled as if it were +- preceded by '\!\\!'. +- +- Both requests cause a line break. +- +- -- Request: .nx [file] +- Force 'gtroff' to continue processing of the file specified as an +- argument. If no argument is given, immediately jump to the end of +- file. +- +- -- Request: .rd [prompt [arg1 arg2 ...]] +- Read from standard input, and include what is read as though it +- were part of the input file. Text is read until a blank line is +- encountered. +- +- If standard input is a TTY input device (keyboard), write PROMPT to +- standard error, followed by a colon (or send BEL for a beep if no +- argument is given). +- +- Arguments after PROMPT are available for the input. For example, +- the line +- +- .rd data foo bar +- +- with the input 'This is \$2.' prints +- +- This is bar. +- +- Using the 'nx' and 'rd' requests, it is easy to set up form letters. +-The form letter template is constructed like this, putting the following +-lines into a file called 'repeat.let': +- +- .ce +- \*(td +- .sp 2 +- .nf +- .rd +- .sp +- .rd +- .fi +- Body of letter. +- .bp +- .nx repeat.let +- +-When this is run, a file containing the following lines should be +-redirected in. Note that requests included in this file are executed as +-though they were part of the form letter. The last block of input is +-the 'ex' request, which tells 'groff' to stop processing. If this was +-not there, 'groff' would not know when to stop. +- +- Trent A. Fisher +- 708 NW 19th Av., #202 +- Portland, OR 97209 +- +- Dear Trent, +- +- Len Adollar +- 4315 Sierra Vista +- San Diego, CA 92103 +- +- Dear Mr. Adollar, +- +- .ex +- +- -- Request: .pi pipe +- Pipe the output of 'gtroff' to the shell command(s) specified by +- PIPE. This request must occur before 'gtroff' has a chance to +- print anything. +- +- 'pi' causes an error if used in safer mode (which is the default). +- Use 'groff''s or 'troff''s '-U' option to activate unsafe mode. +- +- Multiple calls to 'pi' are allowed, acting as a chain. For +- example, +- +- .pi foo +- .pi bar +- ... +- +- is the same as '.pi foo | bar'. +- +- Note that the intermediate output format of 'gtroff' is piped to +- the specified commands. Consequently, calling 'groff' without the +- '-Z' option normally causes a fatal error. +- +- -- Request: .sy cmds +- -- Register: \n[systat] +- Execute the shell command(s) specified by CMDS. The output is not +- saved anyplace, so it is up to the user to do so. +- +- This request causes an error if used in safer mode (which is the +- default). Use 'groff''s or 'troff''s '-U' option to activate +- unsafe mode. +- +- For example, the following code fragment introduces the current +- time into a document: +- +- .sy perl -e 'printf ".nr H %d\\n.nr M %d\\n.nr S %d\\n",\ +- (localtime(time))[2,1,0]' > /tmp/x\n[$$] +- .so /tmp/x\n[$$] +- .sy rm /tmp/x\n[$$] +- \nH:\nM:\nS +- +- Note that this works by having the 'perl' script (run by 'sy') +- print out the 'nr' requests that set the number registers 'H', 'M', +- and 'S', and then reads those commands in with the 'so' request. +- +- For most practical purposes, the number registers 'seconds', +- 'minutes', and 'hours', which are initialized at start-up of +- 'gtroff', should be sufficient. Use the 'af' request to get a +- formatted output: +- +- .af hours 00 +- .af minutes 00 +- .af seconds 00 +- \n[hours]:\n[minutes]:\n[seconds] +- +- The 'systat' read-write number register contains the return value +- of the 'system()' function executed by the last 'sy' request. +- +- -- Request: .open stream file +- -- Request: .opena stream file +- Open the specified FILE for writing and associates the specified +- STREAM with it. +- +- The 'opena' request is like 'open', but if the file exists, append +- to it instead of truncating it. +- +- Both 'open' and 'opena' cause an error if used in safer mode (which +- is the default). Use 'groff''s or 'troff''s '-U' option to +- activate unsafe mode. +- +- -- Request: .write stream data +- -- Request: .writec stream data +- Write to the file associated with the specified STREAM. The stream +- must previously have been the subject of an open request. The +- remainder of the line is interpreted as the 'ds' request reads its +- second argument: A leading '"' is stripped, and it is read in +- copy-in mode. +- +- The 'writec' request is like 'write', but only 'write' appends a +- newline to the data. +- +- -- Request: .writem stream xx +- Write the contents of the macro or string XX to the file associated +- with the specified STREAM. +- +- XX is read in copy mode, i.e., already formatted elements are +- ignored. Consequently, diversions must be unformatted with the +- 'asciify' request before calling 'writem'. Usually, this means a +- loss of information. +- +- -- Request: .close stream +- Close the specified STREAM; the stream is no longer an acceptable +- argument to the 'write' request. +- +- Here a simple macro to write an index entry. +- +- .open idx test.idx +- . +- .de IX +- . write idx \\n[%] \\$* +- .. +- . +- .IX test entry +- . +- .close idx +- +- -- Escape: \Ve +- -- Escape: \V(ev +- -- Escape: \V[env] +- Interpolate the contents of the specified environment variable ENV +- (one-character name E, two-character name EV) as returned by the +- function 'getenv'. '\V' is interpreted in copy-in mode. +- +- +-File: groff.info, Node: Postprocessor Access, Next: Miscellaneous, Prev: I/O, Up: gtroff Reference +- +-5.30 Postprocessor Access +-========================= +- +-There are two escapes that give information directly to the +-postprocessor. This is particularly useful for embedding POSTSCRIPT +-into the final document. +- +- -- Request: .device xxx +- -- Escape: \X'xxx' +- Embeds its argument into the 'gtroff' output preceded with 'x X'. +- +- The escapes '\&', '\)', '\%', and '\:' are ignored within '\X', +- '\ ' and '\~' are converted to single space characters. All other +- escapes (except '\\', which produces a backslash) cause an error. +- +- Contrary to '\X', the 'device' request simply processes its +- argument in copy mode (*note Copy-in Mode::). +- +- If the 'use_charnames_in_special' keyword is set in the 'DESC' +- file, special characters no longer cause an error; they are simply +- output verbatim. Additionally, the backslash is represented as +- '\\'. +- +- 'use_charnames_in_special' is currently used by 'grohtml' only. +- +- -- Request: .devicem xx +- -- Escape: \Yn +- -- Escape: \Y(nm +- -- Escape: \Y[name] +- This is approximately equivalent to '\X'\*[NAME]'' (one-character +- name N, two-character name NM). However, the contents of the +- string or macro NAME are not interpreted; also it is permitted for +- NAME to have been defined as a macro and thus contain newlines (it +- is not permitted for the argument to '\X' to contain newlines). +- The inclusion of newlines requires an extension to the UNIX 'troff' +- output format, and confuses drivers that do not know about this +- extension (*note Device Control Commands::). +- +- *Note Output Devices::. +- +- +-File: groff.info, Node: Miscellaneous, Next: Gtroff Internals, Prev: Postprocessor Access, Up: gtroff Reference +- +-5.31 Miscellaneous +-================== +- +-This section documents parts of 'gtroff' that cannot (yet) be +-categorized elsewhere in this manual. +- +- -- Request: .nm [start [inc [space [indent]]]] +- Print line numbers. START is the line number of the _next_ output +- line. INC indicates which line numbers are printed. For example, +- the value 5 means to emit only line numbers that are multiples +- of 5; this defaults to 1. SPACE is the space to be left between +- the number and the text; this defaults to one digit space. The +- fourth argument is the indentation of the line numbers, defaulting +- to zero. Both SPACE and INDENT are given as multiples of digit +- spaces; they can be negative also. Without any arguments, line +- numbers are turned off. +- +- 'gtroff' reserves three digit spaces for the line number (which is +- printed right-justified) plus the amount given by INDENT; the +- output lines are concatenated to the line numbers, separated by +- SPACE, and _without_ reducing the line length. Depending on the +- value of the horizontal page offset (as set with the 'po' request), +- line numbers that are longer than the reserved space stick out to +- the left, or the whole line is moved to the right. +- +- Parameters corresponding to missing arguments are not changed; any +- non-digit argument (to be more precise, any argument starting with +- a character valid as a delimiter for identifiers) is also treated +- as missing. +- +- If line numbering has been disabled with a call to 'nm' without an +- argument, it can be reactivated with '.nm +0', using the previously +- active line numbering parameters. +- +- The parameters of 'nm' are associated with the current environment +- (*note Environments::). The current output line number is +- available in the number register 'ln'. +- +- .po 1m +- .ll 2i +- This test shows how line numbering works with groff. +- .nm 999 +- This test shows how line numbering works with groff. +- .br +- .nm xxx 3 2 +- .ll -\w'0'u +- This test shows how line numbering works with groff. +- .nn 2 +- This test shows how line numbering works with groff. +- +- And here the result: +- +- This test shows how +- line numbering works +- 999 with groff. This +- 1000 test shows how line +- 1001 numbering works with +- 1002 groff. +- This test shows how +- line numbering +- works with groff. +- This test shows how +- 1005 line numbering +- works with groff. +- +- -- Request: .nn [skip] +- Temporarily turn off line numbering. The argument is the number of +- lines not to be numbered; this defaults to 1. +- +- -- Request: .mc glyph [dist] +- Print a "margin character" to the right of the text.(1) (*note +- Miscellaneous-Footnote-1::) The first argument is the glyph to be +- printed. The second argument is the distance away from the right +- margin. If missing, the previously set value is used; default is +- 10pt). For text lines that are too long (that is, longer than the +- text length plus DIST), the margin character is directly appended +- to the lines. +- +- With no arguments the margin character is turned off. If this +- occurs before a break, no margin character is printed. +- +- For compatibility with AT&T 'troff', a call to 'mc' to set the +- margin character can't be undone immediately; at least one line +- gets a margin character. Thus +- +- .ll 1i +- .mc \[br] +- .mc +- xxx +- .br +- xxx +- +- produces +- +- xxx | +- xxx +- +- For empty lines and lines produced by the 'tl' request no margin +- character is emitted. +- +- The margin character is associated with the current environment +- (*note Environments::). +- +- This is quite useful for indicating text that has changed, and, in +- fact, there are programs available for doing this (they are called +- 'nrchbar' and 'changebar' and can be found in any +- 'comp.sources.unix' archive). +- +- .ll 3i +- .mc | +- This paragraph is highlighted with a margin +- character. +- .sp +- Note that vertical space isn't marked. +- .br +- \& +- .br +- But we can fake it with `\&'. +- +- Result: +- +- This paragraph is highlighted | +- with a margin character. | +- +- Note that vertical space isn't | +- marked. | +- | +- But we can fake it with `\&'. | +- +- -- Request: .psbb filename +- -- Register: \n[llx] +- -- Register: \n[lly] +- -- Register: \n[urx] +- -- Register: \n[ury] +- Retrieve the bounding box of the POSTSCRIPT image found in +- FILENAME. The file must conform to Adobe's "Document Structuring +- Conventions" (DSC); the command searches for a '%%BoundingBox' +- comment and extracts the bounding box values into the number +- registers 'llx', 'lly', 'urx', and 'ury'. If an error occurs (for +- example, 'psbb' cannot find the '%%BoundingBox' comment), it sets +- the four number registers to zero. +- +- The search path for FILENAME can be controlled with the '-I' +- command line option. +- +- +-File: groff.info, Node: Miscellaneous-Footnotes, Up: Miscellaneous +- +- (1) "Margin character" is a misnomer since it is an output glyph. +- +- +-File: groff.info, Node: Gtroff Internals, Next: Debugging, Prev: Miscellaneous, Up: gtroff Reference +- +-5.32 'gtroff' Internals +-======================= +- +-'gtroff' processes input in three steps. One or more input characters +-are converted to an "input token".(1) (*note Gtroff +-Internals-Footnote-1::) Then, one or more input tokens are converted to +-an "output node". Finally, output nodes are converted to the +-intermediate output language understood by all output devices. +- +- Actually, before step one happens, 'gtroff' converts certain escape +-sequences into reserved input characters (not accessible by the user); +-such reserved characters are used for other internal processing also - +-this is the very reason why not all characters are valid input. *Note +-Identifiers::, for more on this topic. +- +- For example, the input string 'fi\[:u]' is converted into a character +-token 'f', a character token 'i', and a special token ':u' (representing +-u umlaut). Later on, the character tokens 'f' and 'i' are merged to a +-single output node representing the ligature glyph 'fi' (provided the +-current font has a glyph for this ligature); the same happens with ':u'. +-All output glyph nodes are 'processed', which means that they are +-invariably associated with a given font, font size, advance width, etc. +-During the formatting process, 'gtroff' itself adds various nodes to +-control the data flow. +- +- Macros, diversions, and strings collect elements in two chained +-lists: a list of input tokens that have been passed unprocessed, and a +-list of output nodes. Consider the following the diversion. +- +- .di xxx +- a +- \!b +- c +- .br +- .di +- +-It contains these elements. +- +-node list token list element number +- +-line start node -- 1 +-glyph node 'a' -- 2 +-word space node -- 3 +--- 'b' 4 +--- '\n' 5 +-glyph node 'c' -- 6 +-vertical size node -- 7 +-vertical size node -- 8 +--- '\n' 9 +- +-Elements 1, 7, and 8 are inserted by 'gtroff'; the latter two (which are +-always present) specify the vertical extent of the last line, possibly +-modified by '\x'. The 'br' request finishes the current partial line, +-inserting a newline input token, which is subsequently converted to a +-space when the diversion is reread. Note that the word space node has a +-fixed width that isn't stretchable anymore. To convert horizontal space +-nodes back to input tokens, use the 'unformat' request. +- +- Macros only contain elements in the token list (and the node list is +-empty); diversions and strings can contain elements in both lists. +- +- Note that the 'chop' request simply reduces the number of elements in +-a macro, string, or diversion by one. Exceptions are "compatibility +-save" and "compatibility ignore" input tokens, which are ignored. The +-'substring' request also ignores those input tokens. +- +- Some requests like 'tr' or 'cflags' work on glyph identifiers only; +-this means that the associated glyph can be changed without destroying +-this association. This can be very helpful for substituting glyphs. In +-the following example, we assume that glyph 'foo' isn't available by +-default, so we provide a substitution using the 'fchar' request and map +-it to input character 'x'. +- +- .fchar \[foo] foo +- .tr x \[foo] +- +-Now let us assume that we install an additional special font 'bar' that +-has glyph 'foo'. +- +- .special bar +- .rchar \[foo] +- +-Since glyphs defined with 'fchar' are searched before glyphs in special +-fonts, we must call 'rchar' to remove the definition of the fallback +-glyph. Anyway, the translation is still active; 'x' now maps to the +-real glyph 'foo'. +- +- Macro and request arguments preserve the compatibility mode: +- +- .cp 1 \" switch to compatibility mode +- .de xx +- \\$1 +- .. +- .cp 0 \" switch compatibility mode off +- .xx caf\['e] +- => caf +- +-Since compatibility mode is on while 'de' is called, the macro 'xx' +-activates compatibility mode while executing. Argument '$1' can still +-be handled properly because it inherits the compatibility mode status +-which was active at the point where 'xx' is called. +- +- After expansion of the parameters, the compatibility save and restore +-tokens are removed. +- +- +-File: groff.info, Node: Gtroff Internals-Footnotes, Up: Gtroff Internals +- +- (1) Except the escapes '\f', '\F', '\H', '\m', '\M', '\R', '\s', and +-'\S', which are processed immediately if not in copy-in mode. +- +- +-File: groff.info, Node: Debugging, Next: Implementation Differences, Prev: Gtroff Internals, Up: gtroff Reference +- +-5.33 Debugging +-============== +- +-'gtroff' is not easy to debug, but there are some useful features and +-strategies for debugging. +- +- -- Request: .lf line [filename] +- Change the line number and optionally the file name 'gtroff' shall +- use for error and warning messages. LINE is the input line number +- of the _next_ line. +- +- Without argument, the request is ignored. +- +- This is a debugging aid for documents that are split into many +- files, then put together with 'soelim' and other preprocessors. +- Usually, it isn't invoked manually. +- +- Note that other 'troff' implementations (including the original +- AT&T version) handle 'lf' differently. For them, LINE changes the +- line number of the _current_ line. +- +- -- Request: .tm string +- -- Request: .tm1 string +- -- Request: .tmc string +- Send STRING to the standard error output; this is very useful for +- printing debugging messages among other things. +- +- STRING is read in copy mode. +- +- The 'tm' request ignores leading spaces of STRING; 'tm1' handles +- its argument similar to the 'ds' request: a leading double quote in +- STRING is stripped to allow initial blanks. +- +- The 'tmc' request is similar to 'tm1' but does not append a newline +- (as is done in 'tm' and 'tm1'). +- +- -- Request: .ab [string] +- Similar to the 'tm' request, except that it causes 'gtroff' to stop +- processing. With no argument it prints 'User Abort.' to standard +- error. +- +- -- Request: .ex +- The 'ex' request also causes 'gtroff' to stop processing; see also +- *note I/O::. +- +- When doing something involved it is useful to leave the debugging +-statements in the code and have them turned on by a command line flag. +- +- .if \n(DB .tm debugging output +- +-To activate these statements say +- +- groff -rDB=1 file +- +- If it is known in advance that there are many errors and no useful +-output, 'gtroff' can be forced to suppress formatted output with the +-'-z' flag. +- +- -- Request: .pev +- Print the contents of the current environment and all the currently +- defined environments (both named and numbered) on 'stderr'. +- +- -- Request: .pm +- Print the entire symbol table on 'stderr'. Names of all defined +- macros, strings, and diversions are print together with their size +- in bytes. Since 'gtroff' sometimes adds nodes by itself, the +- returned size can be larger than expected. +- +- This request differs from UNIX 'troff': 'gtroff' reports the sizes +- of diversions, ignores an additional argument to print only the +- total of the sizes, and the size isn't returned in blocks of 128 +- characters. +- +- -- Request: .pnr +- Print the names and contents of all currently defined number +- registers on 'stderr'. +- +- -- Request: .ptr +- Print the names and positions of all traps (not including input +- line traps and diversion traps) on 'stderr'. Empty slots in the +- page trap list are printed as well, because they can affect the +- priority of subsequently planted traps. +- +- -- Request: .fl +- Instruct 'gtroff' to flush its output immediately. The intent is +- for interactive use, but this behaviour is currently not +- implemented in 'gtroff'. Contrary to UNIX 'troff', TTY output is +- sent to a device driver also ('grotty'), making it non-trivial to +- communicate interactively. +- +- This request causes a line break. +- +- -- Request: .backtrace +- Print a backtrace of the input stack to the standard error stream. +- +- Consider the following in file 'test': +- +- .de xxx +- . backtrace +- .. +- .de yyy +- . xxx +- .. +- . +- .yyy +- +- On execution, 'gtroff' prints the following: +- +- test:2: backtrace: macro `xxx' +- test:5: backtrace: macro `yyy' +- test:8: backtrace: file `test' +- +- The option '-b' of 'gtroff' internally calls a variant of this +- request on each error and warning. +- +- -- Register: \n[slimit] +- Use the 'slimit' number register to set the maximum number of +- objects on the input stack. If 'slimit' is less than or equal +- to 0, there is no limit set. With no limit, a buggy recursive +- macro can exhaust virtual memory. +- +- The default value is 1000; this is a compile-time constant. +- +- -- Request: .warnscale si +- Set the scaling indicator used in warnings to SI. Valid values for +- SI are 'u', 'i', 'c', 'p', and 'P'. At startup, it is set to 'i'. +- +- -- Request: .spreadwarn [limit] +- Make 'gtroff' emit a warning if the additional space inserted for +- each space between words in an output line is larger or equal to +- LIMIT. A negative value is changed to zero; no argument toggles +- the warning on and off without changing LIMIT. The default scaling +- indicator is 'm'. At startup, 'spreadwarn' is deactivated, and +- LIMIT is set to 3m. +- +- For example, +- +- .spreadwarn 0.2m +- +- causes a warning if 'gtroff' must add 0.2m or more for each +- interword space in a line. +- +- This request is active only if text is justified to both margins +- (using '.ad b'). +- +- 'gtroff' has command line options for printing out more warnings +-('-w') and for printing backtraces ('-b') when a warning or an error +-occurs. The most verbose level of warnings is '-ww'. +- +- -- Request: .warn [flags] +- -- Register: \n[.warn] +- Control the level of warnings checked for. The FLAGS are the sum +- of the numbers associated with each warning that is to be enabled; +- all other warnings are disabled. The number associated with each +- warning is listed below. For example, '.warn 0' disables all +- warnings, and '.warn 1' disables all warnings except that about +- missing glyphs. If no argument is given, all warnings are enabled. +- +- The read-only number register '.warn' contains the current warning +- level. +- +-* Menu: +- +-* Warnings:: +- +- +-File: groff.info, Node: Warnings, Prev: Debugging, Up: Debugging +- +-5.33.1 Warnings +---------------- +- +-The warnings that can be given to 'gtroff' are divided into the +-following categories. The name associated with each warning is used by +-the '-w' and '-W' options; the number is used by the 'warn' request and +-by the '.warn' register. +- +-'char' +-'1' +- Non-existent glyphs.(1) (*note Warnings-Footnote-1::) This is +- enabled by default. +- +-'number' +-'2' +- Invalid numeric expressions. This is enabled by default. *Note +- Expressions::. +- +-'break' +-'4' +- In fill mode, lines that could not be broken so that their length +- was less than the line length. This is enabled by default. +- +-'delim' +-'8' +- Missing or mismatched closing delimiters. +- +-'el' +-'16' +- Use of the 'el' request with no matching 'ie' request. *Note +- if-else::. +- +-'scale' +-'32' +- Meaningless scaling indicators. +- +-'range' +-'64' +- Out of range arguments. +- +-'syntax' +-'128' +- Dubious syntax in numeric expressions. +- +-'di' +-'256' +- Use of 'di' or 'da' without an argument when there is no current +- diversion. +- +-'mac' +-'512' +- Use of undefined strings, macros and diversions. When an undefined +- string, macro, or diversion is used, that string is automatically +- defined as empty. So, in most cases, at most one warning is given +- for each name. +- +-'reg' +-'1024' +- Use of undefined number registers. When an undefined number +- register is used, that register is automatically defined to have a +- value of 0. So, in most cases, at most one warning is given for +- use of a particular name. +- +-'tab' +-'2048' +- Use of a tab character where a number was expected. +- +-'right-brace' +-'4096' +- Use of '\}' where a number was expected. +- +-'missing' +-'8192' +- Requests that are missing non-optional arguments. +- +-'input' +-'16384' +- Invalid input characters. +- +-'escape' +-'32768' +- Unrecognized escape sequences. When an unrecognized escape +- sequence '\X' is encountered, the escape character is ignored, and +- X is printed. +- +-'space' +-'65536' +- Missing space between a request or macro and its argument. This +- warning is given when an undefined name longer than two characters +- is encountered, and the first two characters of the name make a +- defined name. The request or macro is not invoked. When this +- warning is given, no macro is automatically defined. This is +- enabled by default. This warning never occurs in compatibility +- mode. +- +-'font' +-'131072' +- Non-existent fonts. This is enabled by default. +- +-'ig' +-'262144' +- Invalid escapes in text ignored with the 'ig' request. These are +- conditions that are errors when they do not occur in ignored text. +- +-'color' +-'524288' +- Color related warnings. +- +-'file' +-'1048576' +- Missing files. The 'mso' request gives this warning when the +- requested macro file does not exist. This is enabled by default. +- +-'all' +- All warnings except 'di', 'mac' and 'reg'. It is intended that +- this covers all warnings that are useful with traditional macro +- packages. +- +-'w' +- All warnings. +- +- +-File: groff.info, Node: Warnings-Footnotes, Up: Warnings +- +- (1) 'char' is a misnomer since it reports missing glyphs - there +-aren't missing input characters, only invalid ones. +- +- +-File: groff.info, Node: Implementation Differences, Prev: Debugging, Up: gtroff Reference +- +-5.34 Implementation Differences +-=============================== +- +-GNU 'troff' has a number of features that cause incompatibilities with +-documents written with old versions of 'troff'. +- +- Long names cause some incompatibilities. UNIX 'troff' interprets +- +- .dsabcd +- +-as defining a string 'ab' with contents 'cd'. Normally, GNU 'troff' +-interprets this as a call of a macro named 'dsabcd'. Also UNIX 'troff' +-interprets '\*[' or '\n[' as references to a string or number register +-called '['. In GNU 'troff', however, this is normally interpreted as +-the start of a long name. In compatibility mode GNU 'troff' interprets +-long names in the traditional way (which means that they are not +-recognized as names). +- +- -- Request: .cp [n] +- -- Request: .do cmd +- -- Register: \n[.C] +- If N is missing or non-zero, turn on compatibility mode; otherwise, +- turn it off. +- +- The read-only number register '.C' is 1 if compatibility mode is +- on, 0 otherwise. +- +- Compatibility mode can be also turned on with the '-C' command line +- option. +- +- The 'do' request turns off compatibility mode while executing its +- arguments as a 'gtroff' command. However, it does not turn off +- compatibility mode while processing the macro itself. To do that, +- use the 'de1' request (or manipulate the '.C' register manually). +- *Note Writing Macros::. +- +- .do fam T +- +- executes the 'fam' request when compatibility mode is enabled. +- +- 'gtroff' restores the previous compatibility setting before +- interpreting any files sourced by the CMD. +- +- Two other features are controlled by '-C'. If not in compatibility +-mode, GNU 'troff' preserves the input level in delimited arguments: +- +- .ds xx ' +- \w'abc\*(xxdef' +- +-In compatibility mode, the string '72def'' is returned; without '-C' the +-resulting string is '168' (assuming a TTY output device). +- +- Finally, the escapes '\f', '\H', '\m', '\M', '\R', '\s', and '\S' are +-transparent for recognizing the beginning of a line only in +-compatibility mode (this is a rather obscure feature). For example, the +-code +- +- .de xx +- Hallo! +- .. +- \fB.xx\fP +- +-prints 'Hallo!' in bold face if in compatibility mode, and '.xx' in bold +-face otherwise. +- +- GNU 'troff' does not allow the use of the escape sequences '\|', +-'\^', '\&', '\{', '\}', '\', '\'', '\`', '\-', '\_', '\!', '\%', and +-'\c' in names of strings, macros, diversions, number registers, fonts or +-environments; UNIX 'troff' does. The '\A' escape sequence (*note +-Identifiers::) may be helpful in avoiding use of these escape sequences +-in names. +- +- Fractional point sizes cause one noteworthy incompatibility. In UNIX +-'troff' the 'ps' request ignores scale indicators and thus +- +- .ps 10u +- +-sets the point size to 10 points, whereas in GNU 'troff' it sets the +-point size to 10 scaled points. *Note Fractional Type Sizes::, for more +-information. +- +- In GNU 'troff' there is a fundamental difference between +-(unformatted) input characters and (formatted) output glyphs. +-Everything that affects how a glyph is output is stored with the glyph +-node; once a glyph node has been constructed it is unaffected by any +-subsequent requests that are executed, including 'bd', 'cs', 'tkf', +-'tr', or 'fp' requests. Normally glyphs are constructed from input +-characters at the moment immediately before the glyph is added to the +-current output line. Macros, diversions and strings are all, in fact, +-the same type of object; they contain lists of input characters and +-glyph nodes in any combination. A glyph node does not behave like an +-input character for the purposes of macro processing; it does not +-inherit any of the special properties that the input character from +-which it was constructed might have had. For example, +- +- .di x +- \\\\ +- .br +- .di +- .x +- +-prints '\\' in GNU 'troff'; each pair of input backslashes is turned +-into one output backslash and the resulting output backslashes are not +-interpreted as escape characters when they are reread. UNIX 'troff' +-would interpret them as escape characters when they were reread and +-would end up printing one '\'. The correct way to obtain a printable +-backslash is to use the '\e' escape sequence: This always prints a +-single instance of the current escape character, regardless of whether +-or not it is used in a diversion; it also works in both GNU 'troff' and +-UNIX 'troff'.(1) (*note Implementation Differences-Footnote-1::) To +-store, for some reason, an escape sequence in a diversion that is +-interpreted when the diversion is reread, either use the traditional +-'\!' transparent output facility, or, if this is unsuitable, the new +-'\?' escape sequence. +- +- *Note Diversions::, and *note Gtroff Internals::, for more +-information. +- +- +-File: groff.info, Node: Implementation Differences-Footnotes, Up: Implementation Differences +- +- (1) To be completely independent of the current escape character, use +-'\(rs', which represents a reverse solidus (backslash) glyph. +- +- +-File: groff.info, Node: Preprocessors, Next: Output Devices, Prev: gtroff Reference, Up: Top +- +-6 Preprocessors +-*************** +- +-This chapter describes all preprocessors that come with 'groff' or which +-are freely available. +- +-* Menu: +- +-* geqn:: +-* gtbl:: +-* gpic:: +-* ggrn:: +-* grap:: +-* gchem:: +-* grefer:: +-* gsoelim:: +-* preconv:: +- +- +-File: groff.info, Node: geqn, Next: gtbl, Prev: Preprocessors, Up: Preprocessors +- +-6.1 'geqn' +-========== +- +-* Menu: +- +-* Invoking geqn:: +- +- +-File: groff.info, Node: Invoking geqn, Prev: geqn, Up: geqn +- +-6.1.1 Invoking 'geqn' +---------------------- +- +- +-File: groff.info, Node: gtbl, Next: gpic, Prev: geqn, Up: Preprocessors +- +-6.2 'gtbl' +-========== +- +-* Menu: +- +-* Invoking gtbl:: +- +- +-File: groff.info, Node: Invoking gtbl, Prev: gtbl, Up: gtbl +- +-6.2.1 Invoking 'gtbl' +---------------------- +- +- +-File: groff.info, Node: gpic, Next: ggrn, Prev: gtbl, Up: Preprocessors +- +-6.3 'gpic' +-========== +- +-* Menu: +- +-* Invoking gpic:: +- +- +-File: groff.info, Node: Invoking gpic, Prev: gpic, Up: gpic +- +-6.3.1 Invoking 'gpic' +---------------------- +- +- +-File: groff.info, Node: ggrn, Next: grap, Prev: gpic, Up: Preprocessors +- +-6.4 'ggrn' +-========== +- +-* Menu: +- +-* Invoking ggrn:: +- +- +-File: groff.info, Node: Invoking ggrn, Prev: ggrn, Up: ggrn +- +-6.4.1 Invoking 'ggrn' +---------------------- +- +- +-File: groff.info, Node: grap, Next: gchem, Prev: ggrn, Up: Preprocessors +- +-6.5 'grap' +-========== +- +-A free implementation of 'grap', written by Ted Faber, is available as +-an extra package from the following address: +- +- +- +- +-File: groff.info, Node: gchem, Next: grefer, Prev: grap, Up: Preprocessors +- +-6.6 'gchem' +-=========== +- +-* Menu: +- +-* Invoking gchem:: +- +- +-File: groff.info, Node: Invoking gchem, Prev: gchem, Up: gchem +- +-6.6.1 Invoking 'gchem' +----------------------- +- +- +-File: groff.info, Node: grefer, Next: gsoelim, Prev: gchem, Up: Preprocessors +- +-6.7 'grefer' +-============ +- +-* Menu: +- +-* Invoking grefer:: +- +- +-File: groff.info, Node: Invoking grefer, Prev: grefer, Up: grefer +- +-6.7.1 Invoking 'grefer' +------------------------ +- +- +-File: groff.info, Node: gsoelim, Next: preconv, Prev: grefer, Up: Preprocessors +- +-6.8 'gsoelim' +-============= +- +-* Menu: +- +-* Invoking gsoelim:: +- +- +-File: groff.info, Node: Invoking gsoelim, Prev: gsoelim, Up: gsoelim +- +-6.8.1 Invoking 'gsoelim' +------------------------- +- +- +-File: groff.info, Node: preconv, Prev: gsoelim, Up: Preprocessors +- +-6.9 'preconv' +-============= +- +-* Menu: +- +-* Invoking preconv:: +- +- +-File: groff.info, Node: Invoking preconv, Prev: preconv, Up: preconv +- +-6.9.1 Invoking 'preconv' +------------------------- +- +- +-File: groff.info, Node: Output Devices, Next: File formats, Prev: Preprocessors, Up: Top +- +-7 Output Devices +-**************** +- +-* Menu: +- +-* Special Characters:: +-* grotty:: +-* grops:: +-* gropdf:: +-* grodvi:: +-* grolj4:: +-* grolbp:: +-* grohtml:: +-* gxditview:: +- +- +-File: groff.info, Node: Special Characters, Next: grotty, Prev: Output Devices, Up: Output Devices +- +-7.1 Special Characters +-====================== +- +-*Note Font Files::. +- +- +-File: groff.info, Node: grotty, Next: grops, Prev: Special Characters, Up: Output Devices +- +-7.2 'grotty' +-============ +- +-The postprocessor 'grotty' translates the output from GNU 'troff' into a +-form suitable for typewriter-like devices. It is fully documented on +-its manual page, 'grotty(1)'. +- +-* Menu: +- +-* Invoking grotty:: +- +- +-File: groff.info, Node: Invoking grotty, Prev: grotty, Up: grotty +- +-7.2.1 Invoking 'grotty' +------------------------ +- +-The postprocessor 'grotty' accepts the following command-line options: +- +-'-b' +- Do not overstrike bold glyphs. Ignored if '-c' isn't used. +- +-'-B' +- Do not underline bold-italic glyphs. Ignored if '-c' isn't used. +- +-'-c' +- Use overprint and disable colours for printing on legacy Teletype +- printers (see below). +- +-'-d' +- Do not render lines (this is, ignore all '\D' escapes). +- +-'-f' +- Use form feed control characters in the output. +- +-'-FDIR' +- Put the directory 'DIR/devNAME' in front of the search path for the +- font and device description files, given the target device NAME. +- +-'-h' +- Use horizontal tabs for sequences of 8 space characters. +- +-'-i' +- Request italic glyphs from the terminal. Ignored if '-c' is +- active. +- +-'-o' +- Do not overstrike. +- +-'-r' +- Highlight italic glyphs. Ignored if '-c' is active. +- +-'-u' +- Do not underline italic glyphs. Ignored if '-c' isn't used. +- +-'-U' +- Do not overstrike bold-italic glyphs. Ignored if '-c' isn't used. +- +-'-v' +- Print the version number. +- +- The '-c' mode for TTY output devices means that underlining is done +-by emitting sequences of '_' and '^H' (the backspace character) before +-the actual character. Literally, this is printing an underline +-character, then moving the caret back one character position, and +-printing the actual character at the same position as the underline +-character (similar to a typewriter). Usually, a modern terminal can't +-interpret this (and the original Teletype machines for which this +-sequence was appropriate are no longer in use). You need a pager +-program like 'less' that translates this into ISO 6429 SGR sequences to +-control terminals. +- +- +-File: groff.info, Node: grops, Next: gropdf, Prev: grotty, Up: Output Devices +- +-7.3 'grops' +-=========== +- +-The postprocessor 'grops' translates the output from GNU 'troff' into a +-form suitable for Adobe POSTSCRIPT devices. It is fully documented on +-its manual page, 'grops(1)'. +- +-* Menu: +- +-* Invoking grops:: +-* Embedding PostScript:: +- +- +-File: groff.info, Node: Invoking grops, Next: Embedding PostScript, Prev: grops, Up: grops +- +-7.3.1 Invoking 'grops' +----------------------- +- +-The postprocessor 'grops' accepts the following command-line options: +- +-'-bFLAGS' +- Use backward compatibility settings given by FLAGS as documented in +- the 'grops(1)' manual page. Overrides the command 'broken' in the +- 'DESC' file. +- +-'-cN' +- Print N copies of each page. +- +-'-FDIR' +- Put the directory 'DIR/devNAME' in front of the search path for the +- font, prologue and device description files, given the target +- device NAME, usually *ps*. +- +-'-g' +- Tell the printer to guess the page length. Useful for printing +- vertically centered pages when the paper dimensions are determined +- at print time. +- +-'-IPATH ...' +- Consider the directory 'PATH' for searching included files +- specified with relative paths. The current directory is searched +- as fallback. +- +-'-l' +- Use landscape orientation. +- +-'-m' +- Use manual feed. +- +-'-pPAPERSIZE' +- Set the page dimensions. Overrides the commands 'papersize', +- 'paperlength', and 'paperwidth' in the 'DESC' file. See the +- 'groff_font(5)' manual page for details. +- +-'-PPROLOGUE' +- Use the PROLOGUE in the font path as the prologue instead of the +- default 'prologue'. Overrides the environment variable +- 'GROPS_PROLOGUE'. +- +-'-wN' +- Set the line thickness to N/1000em. Overrides the default value N +- = 40. +- +-'-v' +- Print the version number. +- +- +-File: groff.info, Node: Embedding PostScript, Prev: Invoking grops, Up: grops +- +-7.3.2 Embedding POSTSCRIPT +--------------------------- +- +-The escape sequence +- +- '\X'ps: import FILE LLX LLY URX URY WIDTH [HEIGHT]'' +- +-places a rectangle of the specified WIDTH containing the POSTSCRIPT +-drawing from file FILE bound by the box from LLX LLY to URX URY (in +-POSTSCRIPT coordinates) at the insertion point. If HEIGHT is not +-specified, the embedded drawing is scaled proportionally. +- +- *Note Miscellaneous::, for the 'psbb' request, which automatically +-generates the bounding box. +- +- This escape sequence is used internally by the macro 'PSPIC' (see the +-'groff_tmac(5)' manual page). +- +- +-File: groff.info, Node: gropdf, Next: grodvi, Prev: grops, Up: Output Devices +- +-7.4 'gropdf' +-============ +- +-The postprocessor 'gropdf' translates the output from GNU 'troff' into a +-form suitable for Adobe PDF devices. It is fully documented on its +-manual page, 'gropdf(1)'. +- +-* Menu: +- +-* Invoking gropdf:: +-* Embedding PDF:: +- +- +-File: groff.info, Node: Invoking gropdf, Next: Embedding PDF, Prev: gropdf, Up: gropdf +- +-7.4.1 Invoking 'gropdf' +------------------------ +- +-The postprocessor 'gropdf' accepts the following command-line options: +- +-'-d' +- Produce uncompressed PDFs that include debugging comments. +- +-'-e' +- This forces 'gropdf' to embed all used fonts in the PDF, even if +- they are one of the 14 base Adobe fonts. +- +-'-FDIR' +- Put the directory 'DIR/devNAME' in front of the search path for the +- font, prologue and device description files, given the target +- device NAME, usually *pdf*. +- +-'-yFOUNDRY' +- This forces the use of a different font foundry. +- +-'-l' +- Use landscape orientation. +- +-'-pPAPERSIZE' +- Set the page dimensions. Overrides the commands 'papersize', +- 'paperlength', and 'paperwidth' in the 'DESC' file. See the +- 'groff_font(5)' manual page for details. +- +-'-v' +- Print the version number. +- +-'-s' +- Append a comment line to end of PDF showing statistics, i.e. +- number of pages in document. Ghostscript's 'ps2pdf(1)' complains +- about this line if it is included, but works anyway. +- +-'-uFILENAME' +- 'gropdf' normally includes a ToUnicode CMap with any font created +- using 'text.enc' as the encoding file, this makes it easier to +- search for words that contain ligatures. You can include your own +- CMap by specifying a FILENAME or have no CMap at all by omitting +- the FILENAME. +- +- +-File: groff.info, Node: Embedding PDF, Prev: Invoking gropdf, Up: gropdf +- +-7.4.2 Embedding PDF +-------------------- +- +-The escape sequence +- +- '\X'pdf: pdfpic FILE ALIGNMENT WIDTH [HEIGHT] [LINELENGTH]'' +- +-places a rectangle of the specified WIDTH containing the PDF drawing +-from file FILE of desired WIDTH and HEIGHT (if HEIGHT is missing or zero +-then it is scaled proportionally). If ALIGNMENT is '-L' the drawing is +-left aligned. If it is '-C' or '-R' a LINELENGTH greater than the width +-of the drawing is required as well. If WIDTH is specified as zero then +-the width is scaled in proportion to the height. +- +- +-File: groff.info, Node: grodvi, Next: grolj4, Prev: gropdf, Up: Output Devices +- +-7.5 'grodvi' +-============ +- +-The postprocessor 'grodvi' translates the output from GNU 'troff' into +-the *DVI* output format compatible with the *TeX* document preparation +-system. It is fully documented on its manual page, 'grodvi(1)'. +- +-* Menu: +- +-* Invoking grodvi:: +- +- +-File: groff.info, Node: Invoking grodvi, Prev: grodvi, Up: grodvi +- +-7.5.1 Invoking 'grodvi' +------------------------ +- +-The postprocessor 'grodvi' accepts the following command-line options: +- +-'-d' +- Do not use *tpic* specials to implement drawing commands. +- +-'-FDIR' +- Put the directory 'DIR/devNAME' in front of the search path for the +- font and device description files, given the target device NAME, +- usually *dvi*. +- +-'-l' +- Use landscape orientation. +- +-'-pPAPERSIZE' +- Set the page dimensions. Overrides the commands 'papersize', +- 'paperlength', and 'paperwidth' in the 'DESC' file. See +- 'groff_font(5)' manual page for details. +- +-'-v' +- Print the version number. +- +-'-wN' +- Set the line thickness to N/1000em. Overrides the default value N +- = 40. +- +- +-File: groff.info, Node: grolj4, Next: grolbp, Prev: grodvi, Up: Output Devices +- +-7.6 'grolj4' +-============ +- +-The postprocessor 'grolj4' translates the output from GNU 'troff' into +-the *PCL5* output format suitable for printing on a *HP LaserJet 4* +-printer. It is fully documented on its manual page, 'grolj4(1)'. +- +-* Menu: +- +-* Invoking grolj4:: +- +- +-File: groff.info, Node: Invoking grolj4, Prev: grolj4, Up: grolj4 +- +-7.6.1 Invoking 'grolj4' +------------------------ +- +-The postprocessor 'grolj4' accepts the following command-line options: +- +-'-cN' +- Print N copies of each page. +- +-'-FDIR' +- Put the directory 'DIR/devNAME' in front of the search path for the +- font and device description files, given the target device NAME, +- usually *lj4*. +- +-'-l' +- Use landscape orientation. +- +-'-pSIZE' +- Set the page dimensions. Valid values for SIZE are: 'letter', +- 'legal', 'executive', 'a4', 'com10', 'monarch', 'c5', 'b5', 'd1'. +- +-'-v' +- Print the version number. +- +-'-wN' +- Set the line thickness to N/1000em. Overrides the default value N +- = 40. +- +- The special drawing command '\D'R DH DV'' draws a horizontal +-rectangle from the current position to the position at offset (DH,DV). +- +- +-File: groff.info, Node: grolbp, Next: grohtml, Prev: grolj4, Up: Output Devices +- +-7.7 'grolbp' +-============ +- +-The postprocessor 'grolbp' translates the output from GNU 'troff' into +-the *LBP* output format suitable for printing on *Canon CAPSL* printers. +-It is fully documented on its manual page, 'grolbp(1)'. +- +-* Menu: +- +-* Invoking grolbp:: +- +- +-File: groff.info, Node: Invoking grolbp, Prev: grolbp, Up: grolbp +- +-7.7.1 Invoking 'grolbp' +------------------------ +- +-The postprocessor 'grolbp' accepts the following command-line options: +- +-'-cN' +- Print N copies of each page. +- +-'-FDIR' +- Put the directory 'DIR/devNAME' in front of the search path for the +- font, prologue and device description files, given the target +- device NAME, usually *lbp*. +- +-'-l' +- Use landscape orientation. +- +-'-oORIENTATION' +- Use the ORIENTATION specified: 'portrait' or 'landscape'. +- +-'-pPAPERSIZE' +- Set the page dimensions. See 'groff_font(5)' manual page for +- details. +- +-'-wN' +- Set the line thickness to N/1000em. Overrides the default value N +- = 40. +- +-'-v' +- Print the version number. +- +-'-h' +- Print command-line help. +- +- +-File: groff.info, Node: grohtml, Next: gxditview, Prev: grolbp, Up: Output Devices +- +-7.8 'grohtml' +-============= +- +-The 'grohtml' front end (which consists of a preprocessor, +-'pre-grohtml', and a device driver, 'post-grohtml') translates the +-output of GNU 'troff' to HTML. Users should always invoke 'grohtml' via +-the 'groff' command with a '\-Thtml' option. If no files are given, +-'grohtml' will read the standard input. A filename of '-' will also +-cause 'grohtml' to read the standard input. HTML output is written to +-the standard output. When 'grohtml' is run by 'groff', options can be +-passed to 'grohtml' using 'groff''s '-P' option. +- +- 'grohtml' invokes 'groff' twice. In the first pass, pictures, +-equations, and tables are rendered using the 'ps' device, and in the +-second pass HTML output is generated by the 'html' device. +- +- 'grohtml' always writes output in 'UTF-8' encoding and has built-in +-entities for all non-composite unicode characters. In spite of this, +-'groff' may issue warnings about unknown special characters if they +-can't be found during the first pass. Such warnings can be safely +-ignored unless the special characters appear inside a table or equation, +-in which case glyphs for these characters must be defined for the 'ps' +-device as well. +- +- This output device is fully documented on its manual page, +-'grohtml(1)'. +- +-* Menu: +- +-* Invoking grohtml:: +-* grohtml specific registers and strings:: +- +- +-File: groff.info, Node: Invoking grohtml, Next: grohtml specific registers and strings, Prev: grohtml, Up: grohtml +- +-7.8.1 Invoking 'grohtml' +------------------------- +- +-The postprocessor 'grohtml' accepts the following command-line options: +- +-'-aBITS' +- Use this number of BITS (= 1, 2 or 4) for text antialiasing. +- Default: BITS = 4. +- +-'-a0' +- Do not use text antialiasing. +- +-'-b' +- Use white background. +- +-'-DDIR' +- Store rendered images in the directory 'DIR'. +- +-'-FDIR' +- Put the directory 'DIR/devNAME' in front of the search path for the +- font, prologue and device description files, given the target +- device NAME, usually *html*. +- +-'-gBITS' +- Use this number of BITS (= 1, 2 or 4) for antialiasing of drawings. +- Default: BITS = 4. +- +-'-g0' +- Do not use antialiasing for drawings. +- +-'-h' +- Use the 'B' element for section headings. +- +-'-iRESOLUTION' +- Use the RESOLUTION for rendered images. Default: RESOLUTION = +- 100dpi. +- +-'-ISTEM' +- Set the images' STEM NAME. Default: STEM = 'grohtml-XXX' (XXX is +- the process ID). +- +-'-jSTEM' +- Place each section in a separate file called 'STEM-N.html' (where N +- is a generated section number). +- +-'-l' +- Do not generate the table of contents. +- +-'-n' +- Generate simple fragment identifiers. +- +-'-oOFFSET' +- Use vertical paddding OFFSET for images. +- +-'-p' +- Display the page rendering progress to 'stderr'. +- +-'-r' +- Do not use horizontal rules to separate headers and footers. +- +-'-sSIZE' +- Set the base font size, to be modified using the elements 'BIG' and +- 'SMALL'. +- +-'-SLEVEL' +- Generate separate files for sections at level LEVEL. +- +-'-v' +- Print the version number. +- +-'-V' +- Generate a validator button at the bottom. +- +-'-y' +- Generate a signature of groff after the validator button, if any. +- +- +-File: groff.info, Node: grohtml specific registers and strings, Prev: Invoking grohtml, Up: grohtml +- +-7.8.2 'grohtml' specific registers and strings +----------------------------------------------- +- +- -- Register: \n[ps4html] +- -- String: \*[www-image-template] +- The registers 'ps4html' and 'www-image-template' are defined by the +- 'pre-grohtml' preprocessor. 'pre-grohtml' reads in the 'troff' +- input, marks up the inline equations and passes the result firstly +- to +- +- troff -Tps -rps4html=1 -dwww-image-template=TEMPLATE +- +- and secondly to +- +- troff -Thtml +- +- or +- +- troff -Txhtml +- +- The POSTSCRIPT device is used to create all the image files (for +- '-Thtml'; if '-Txhtml' is used, all equations are passed to 'geqn' +- to produce MathML, and the register 'ps4html' enables the macro +- sets to ignore floating keeps, footers, and headings. +- +- The register 'www-image-template' is set to the user specified +- template name or the default name. +- +- +-File: groff.info, Node: gxditview, Prev: grohtml, Up: Output Devices +- +-7.9 'gxditview' +-=============== +- +-* Menu: +- +-* Invoking gxditview:: +- +- +-File: groff.info, Node: Invoking gxditview, Prev: gxditview, Up: gxditview +- +-7.9.1 Invoking 'gxditview' +--------------------------- +- +- +-File: groff.info, Node: File formats, Next: Installation, Prev: Output Devices, Up: Top +- +-8 File formats +-************** +- +-All files read and written by 'gtroff' are text files. The following +-two sections describe their format. +- +-* Menu: +- +-* gtroff Output:: +-* Font Files:: +- +- +-File: groff.info, Node: gtroff Output, Next: Font Files, Prev: File formats, Up: File formats +- +-8.1 'gtroff' Output +-=================== +- +-This section describes the intermediate output format of GNU 'troff'. +-This output is produced by a run of 'gtroff' before it is fed into a +-device postprocessor program. +- +- As 'groff' is a wrapper program around 'gtroff' that automatically +-calls a postprocessor, this output does not show up normally. This is +-why it is called "intermediate". 'groff' provides the option '-Z' to +-inhibit postprocessing, such that the produced intermediate output is +-sent to standard output just like calling 'gtroff' manually. +- +- Here, the term "troff output" describes what is output by 'gtroff', +-while "intermediate output" refers to the language that is accepted by +-the parser that prepares this output for the postprocessors. This +-parser is smarter on whitespace and implements obsolete elements for +-compatibility, otherwise both formats are the same.(1) (*note gtroff +-Output-Footnote-1::) +- +- The main purpose of the intermediate output concept is to facilitate +-the development of postprocessors by providing a common programming +-interface for all devices. It has a language of its own that is +-completely different from the 'gtroff' language. While the 'gtroff' +-language is a high-level programming language for text processing, the +-intermediate output language is a kind of low-level assembler language +-by specifying all positions on the page for writing and drawing. +- +- The intermediate output produced by 'gtroff' is fairly readable, +-while output from AT&T 'troff' is rather hard to understand because of +-strange habits that are still supported, but not used any longer by +-'gtroff'. +- +-* Menu: +- +-* Language Concepts:: +-* Command Reference:: +-* Intermediate Output Examples:: +-* Output Language Compatibility:: +- +- +-File: groff.info, Node: gtroff Output-Footnotes, Up: gtroff Output +- +- (1) The parser and postprocessor for intermediate output can be found +-in the file +-'GROFF-SOURCE-DIR/src/libs/libdriver/input.cpp'. +- +- +-File: groff.info, Node: Language Concepts, Next: Command Reference, Prev: gtroff Output, Up: gtroff Output +- +-8.1.1 Language Concepts +------------------------ +- +-During the run of 'gtroff', the input data is cracked down to the +-information on what has to be printed at what position on the intended +-device. So the language of the intermediate output format can be quite +-small. Its only elements are commands with and without arguments. In +-this section, the term "command" always refers to the intermediate +-output language, and never to the 'gtroff' language used for document +-formatting. There are commands for positioning and text writing, for +-drawing, and for device controlling. +- +-* Menu: +- +-* Separation:: +-* Argument Units:: +-* Document Parts:: +- +- +-File: groff.info, Node: Separation, Next: Argument Units, Prev: Language Concepts, Up: Language Concepts +- +-8.1.1.1 Separation +-.................. +- +-AT&T 'troff' output has strange requirements on whitespace. The +-'gtroff' output parser, however, is smart about whitespace by making it +-maximally optional. The whitespace characters, i.e., the tab, space, +-and newline characters, always have a syntactical meaning. They are +-never printable because spacing within the output is always done by +-positioning commands. +- +- Any sequence of space or tab characters is treated as a single +-"syntactical space". It separates commands and arguments, but is only +-required when there would occur a clashing between the command code and +-the arguments without the space. Most often, this happens when +-variable-length command names, arguments, argument lists, or command +-clusters meet. Commands and arguments with a known, fixed length need +-not be separated by syntactical space. +- +- A line break is a syntactical element, too. Every command argument +-can be followed by whitespace, a comment, or a newline character. Thus +-a "syntactical line break" is defined to consist of optional syntactical +-space that is optionally followed by a comment, and a newline character. +- +- The normal commands, those for positioning and text, consist of a +-single letter taking a fixed number of arguments. For historical +-reasons, the parser allows to stack such commands on the same line, but +-fortunately, in 'gtroff''s intermediate output, every command with at +-least one argument is followed by a line break, thus providing excellent +-readability. +- +- The other commands - those for drawing and device controlling - have +-a more complicated structure; some recognize long command names, and +-some take a variable number of arguments. So all 'D' and 'x' commands +-were designed to request a syntactical line break after their last +-argument. Only one command, 'x X', has an argument that can stretch +-over several lines; all other commands must have all of their arguments +-on the same line as the command, i.e., the arguments may not be split by +-a line break. +- +- Empty lines (these are lines containing only space and/or a comment), +-can occur everywhere. They are just ignored. +- +- +-File: groff.info, Node: Argument Units, Next: Document Parts, Prev: Separation, Up: Language Concepts +- +-8.1.1.2 Argument Units +-...................... +- +-Some commands take integer arguments that are assumed to represent +-values in a measurement unit, but the letter for the corresponding scale +-indicator is not written with the output command arguments. Most +-commands assume the scale indicator 'u', the basic unit of the device, +-some use 'z', the scaled point unit of the device, while others, such as +-the color commands, expect plain integers. +- +- Note that single characters can have the eighth bit set, as can the +-names of fonts and special characters. The names of characters and +-fonts can be of arbitrary length. A character that is to be printed is +-always in the current font. +- +- A string argument is always terminated by the next whitespace +-character (space, tab, or newline); an embedded '#' character is +-regarded as part of the argument, not as the beginning of a comment +-command. An integer argument is already terminated by the next +-non-digit character, which then is regarded as the first character of +-the next argument or command. +- +- +-File: groff.info, Node: Document Parts, Prev: Argument Units, Up: Language Concepts +- +-8.1.1.3 Document Parts +-...................... +- +-A correct intermediate output document consists of two parts, the +-"prologue" and the "body". +- +- The task of the prologue is to set the general device parameters +-using three exactly specified commands. 'gtroff''s prologue is +-guaranteed to consist of the following three lines (in that order): +- +- x T DEVICE +- x res N H V +- x init +- +-with the arguments set as outlined in *note Device Control Commands::. +-Note that the parser for the intermediate output format is able to +-swallow additional whitespace and comments as well even in the prologue. +- +- The body is the main section for processing the document data. +-Syntactically, it is a sequence of any commands different from the ones +-used in the prologue. Processing is terminated as soon as the first +-'x stop' command is encountered; the last line of any 'gtroff' +-intermediate output always contains such a command. +- +- Semantically, the body is page oriented. A new page is started by a +-'p' command. Positioning, writing, and drawing commands are always done +-within the current page, so they cannot occur before the first 'p' +-command. Absolute positioning (by the 'H' and 'V' commands) is done +-relative to the current page; all other positioning is done relative to +-the current location within this page. +- +- +-File: groff.info, Node: Command Reference, Next: Intermediate Output Examples, Prev: Language Concepts, Up: gtroff Output +- +-8.1.2 Command Reference +------------------------ +- +-This section describes all intermediate output commands, both from AT&T +-'troff' as well as the 'gtroff' extensions. +- +-* Menu: +- +-* Comment Command:: +-* Simple Commands:: +-* Graphics Commands:: +-* Device Control Commands:: +-* Obsolete Command:: +- +- +-File: groff.info, Node: Comment Command, Next: Simple Commands, Prev: Command Reference, Up: Command Reference +- +-8.1.2.1 Comment Command +-....................... +- +-'#ANYTHING' +- A comment. Ignore any characters from the '#' character up to the +- next newline character. +- +- This command is the only possibility for commenting in the +- intermediate output. Each comment can be preceded by arbitrary +- syntactical space; every command can be terminated by a comment. +- +- +-File: groff.info, Node: Simple Commands, Next: Graphics Commands, Prev: Comment Command, Up: Command Reference +- +-8.1.2.2 Simple Commands +-....................... +- +-The commands in this subsection have a command code consisting of a +-single character, taking a fixed number of arguments. Most of them are +-commands for positioning and text writing. These commands are smart +-about whitespace. Optionally, syntactical space can be inserted before, +-after, and between the command letter and its arguments. All of these +-commands are stackable, i.e., they can be preceded by other simple +-commands or followed by arbitrary other commands on the same line. A +-separating syntactical space is only necessary when two integer +-arguments would clash or if the preceding argument ends with a string +-argument. +- +-'C XXX' +- Print a special character named XXX. The trailing syntactical +- space or line break is necessary to allow glyph names of arbitrary +- length. The glyph is printed at the current print position; the +- glyph's size is read from the font file. The print position is not +- changed. +- +-'c G' +- Print glyph G at the current print position;(1) (*note Simple +- Commands-Footnote-1::) the glyph's size is read from the font file. +- The print position is not changed. +- +-'f N' +- Set font to font number N (a non-negative integer). +- +-'H N' +- Move right to the absolute vertical position N (a non-negative +- integer in basic units 'u' relative to left edge of current page. +- +-'h N' +- Move N (a non-negative integer) basic units 'u' horizontally to the +- right. The original UNIX troff manual allows negative values for N +- also, but 'gtroff' doesn't use this. +- +-'m COLOR-SCHEME [COMPONENT ...]' +- Set the color for text (glyphs), line drawing, and the outline of +- graphic objects using different color schemes; the analoguous +- command for the filling color of graphic objects is 'DF'. The +- color components are specified as integer arguments between 0 and +- 65536. The number of color components and their meaning vary for +- the different color schemes. These commands are generated by +- 'gtroff''s escape sequence '\m'. No position changing. These +- commands are a 'gtroff' extension. +- +- 'mc CYAN MAGENTA YELLOW' +- Set color using the CMY color scheme, having the 3 color +- components CYAN, MAGENTA, and YELLOW. +- +- 'md' +- Set color to the default color value (black in most cases). +- No component arguments. +- +- 'mg GRAY' +- Set color to the shade of gray given by the argument, an +- integer between 0 (black) and 65536 (white). +- +- 'mk CYAN MAGENTA YELLOW BLACK' +- Set color using the CMYK color scheme, having the 4 color +- components CYAN, MAGENTA, YELLOW, and BLACK. +- +- 'mr RED GREEN BLUE' +- Set color using the RGB color scheme, having the 3 color +- components RED, GREEN, and BLUE. +- +-'N N' +- Print glyph with index N (a non-negative integer) of the current +- font. This command is a 'gtroff' extension. +- +-'n B A' +- Inform the device about a line break, but no positioning is done by +- this command. In AT&T 'troff', the integer arguments B and A +- informed about the space before and after the current line to make +- the intermediate output more human readable without performing any +- action. In 'groff', they are just ignored, but they must be +- provided for compatibility reasons. +- +-'p N' +- Begin a new page in the outprint. The page number is set to N. +- This page is completely independent of pages formerly processed +- even if those have the same page number. The vertical position on +- the outprint is automatically set to 0. All positioning, writing, +- and drawing is always done relative to a page, so a 'p' command +- must be issued before any of these commands. +- +-'s N' +- Set point size to N scaled points (this is unit 'z'). AT&T 'troff' +- used the unit points ('p') instead. *Note Output Language +- Compatibility::. +- +-'t XXX' +-'t XXX DUMMY-ARG' +- Print a word, i.e., a sequence of characters XXX representing +- output glyphs which names are single characters, terminated by a +- space character or a line break; an optional second integer +- argument is ignored (this allows the formatter to generate an even +- number of arguments). The first glyph should be printed at the +- current position, the current horizontal position should then be +- increased by the width of the first glyph, and so on for each +- glyph. The widths of the glyphs are read from the font file, +- scaled for the current point size, and rounded to a multiple of the +- horizontal resolution. Special characters cannot be printed using +- this command (use the 'C' command for special characters). This +- command is a 'gtroff' extension; it is only used for devices whose +- 'DESC' file contains the 'tcommand' keyword (*note DESC File +- Format::). +- +-'u N XXX' +- Print word with track kerning. This is the same as the 't' command +- except that after printing each glyph, the current horizontal +- position is increased by the sum of the width of that glyph and N +- (an integer in basic units 'u'). This command is a 'gtroff' +- extension; it is only used for devices whose 'DESC' file contains +- the 'tcommand' keyword (*note DESC File Format::). +- +-'V N' +- Move down to the absolute vertical position N (a non-negative +- integer in basic units 'u') relative to upper edge of current page. +- +-'v N' +- Move N basic units 'u' down (N is a non-negative integer). The +- original UNIX troff manual allows negative values for N also, but +- 'gtroff' doesn't use this. +- +-'w' +- Informs about a paddable white space to increase readability. The +- spacing itself must be performed explicitly by a move command. +- +- +-File: groff.info, Node: Simple Commands-Footnotes, Up: Simple Commands +- +- (1) 'c' is actually a misnomer since it outputs a glyph. +- +- +-File: groff.info, Node: Graphics Commands, Next: Device Control Commands, Prev: Simple Commands, Up: Command Reference +- +-8.1.2.3 Graphics Commands +-......................... +- +-Each graphics or drawing command in the intermediate output starts with +-the letter 'D', followed by one or two characters that specify a +-subcommand; this is followed by a fixed or variable number of integer +-arguments that are separated by a single space character. A 'D' command +-may not be followed by another command on the same line (apart from a +-comment), so each 'D' command is terminated by a syntactical line break. +- +- 'gtroff' output follows the classical spacing rules (no space between +-command and subcommand, all arguments are preceded by a single space +-character), but the parser allows optional space between the command +-letters and makes the space before the first argument optional. As +-usual, each space can be any sequence of tab and space characters. +- +- Some graphics commands can take a variable number of arguments. In +-this case, they are integers representing a size measured in basic units +-'u'. The arguments called H1, H2, ..., HN stand for horizontal +-distances where positive means right, negative left. The arguments +-called V1, V2, ..., VN stand for vertical distances where positive means +-down, negative up. All these distances are offsets relative to the +-current location. +- +- Each graphics command directly corresponds to a similar 'gtroff' '\D' +-escape sequence. *Note Drawing Requests::. +- +- Unknown 'D' commands are assumed to be device-specific. Its +-arguments are parsed as strings; the whole information is then sent to +-the postprocessor. +- +- In the following command reference, the syntax element +-means a syntactical line break as defined above. +- +-'D~ H1 V1 H2 V2 ... HN VN' +- Draw B-spline from current position to offset (H1,V1), then to +- offset (H2,V2), if given, etc. up to (HN,VN). This command takes a +- variable number of argument pairs; the current position is moved to +- the terminal point of the drawn curve. +- +-'Da H1 V1 H2 V2' +- Draw arc from current position to (H1,V1)+(H2,V2) with center at +- (H1,V1); then move the current position to the final point of the +- arc. +- +-'DC D' +-'DC D DUMMY-ARG' +- Draw a solid circle using the current fill color with diameter D +- (integer in basic units 'u') with leftmost point at the current +- position; then move the current position to the rightmost point of +- the circle. An optional second integer argument is ignored (this +- allows the formatter to generate an even number of arguments). +- This command is a 'gtroff' extension. +- +-'Dc D' +- Draw circle line with diameter D (integer in basic units 'u') with +- leftmost point at the current position; then move the current +- position to the rightmost point of the circle. +- +-'DE H V' +- Draw a solid ellipse in the current fill color with a horizontal +- diameter of H and a vertical diameter of V (both integers in basic +- units 'u') with the leftmost point at the current position; then +- move to the rightmost point of the ellipse. This command is a +- 'gtroff' extension. +- +-'De H V' +- Draw an outlined ellipse with a horizontal diameter of H and a +- vertical diameter of V (both integers in basic units 'u') with the +- leftmost point at current position; then move to the rightmost +- point of the ellipse. +- +-'DF COLOR-SCHEME [COMPONENT ...]' +- Set fill color for solid drawing objects using different color +- schemes; the analoguous command for setting the color of text, line +- graphics, and the outline of graphic objects is 'm'. The color +- components are specified as integer arguments between 0 and 65536. +- The number of color components and their meaning vary for the +- different color schemes. These commands are generated by +- 'gtroff''s escape sequences '\D'F ...'' and '\M' (with no other +- corresponding graphics commands). No position changing. This +- command is a 'gtroff' extension. +- +- 'DFc CYAN MAGENTA YELLOW' +- Set fill color for solid drawing objects using the CMY color +- scheme, having the 3 color components CYAN, MAGENTA, and +- YELLOW. +- +- 'DFd' +- Set fill color for solid drawing objects to the default fill +- color value (black in most cases). No component arguments. +- +- 'DFg GRAY' +- Set fill color for solid drawing objects to the shade of gray +- given by the argument, an integer between 0 (black) and 65536 +- (white). +- +- 'DFk CYAN MAGENTA YELLOW BLACK' +- Set fill color for solid drawing objects using the CMYK color +- scheme, having the 4 color components CYAN, MAGENTA, YELLOW, +- and BLACK. +- +- 'DFr RED GREEN BLUE' +- Set fill color for solid drawing objects using the RGB color +- scheme, having the 3 color components RED, GREEN, and BLUE. +- +-'Df N' +- The argument N must be an integer in the range -32767 to 32767. +- +- 0 <= N <= 1000 +- Set the color for filling solid drawing objects to a shade of +- gray, where 0 corresponds to solid white, 1000 (the default) +- to solid black, and values in between to intermediate shades +- of gray; this is obsoleted by command 'DFg'. +- +- N < 0 or N > 1000 +- Set the filling color to the color that is currently being +- used for the text and the outline, see command 'm'. For +- example, the command sequence +- +- mg 0 0 65536 +- Df -1 +- +- sets all colors to blue. +- +- No position changing. This command is a 'gtroff' extension. +- +-'Dl H V' +- Draw line from current position to offset (H,V) (integers in basic +- units 'u'); then set current position to the end of the drawn line. +- +-'Dp H1 V1 H2 V2 ... HN VN' +- Draw a polygon line from current position to offset (H1,V1), from +- there to offset (H2,V2), etc. up to offset (HN,VN), and from there +- back to the starting position. For historical reasons, the +- position is changed by adding the sum of all arguments with odd +- index to the actual horizontal position and the even ones to the +- vertical position. Although this doesn't make sense it is kept for +- compatibility. This command is a 'gtroff' extension. +- +-'Dp H1 V1 H2 V2 ... HN VN' +- Draw a solid polygon in the current fill color rather than an +- outlined polygon, using the same arguments and positioning as the +- corresponding 'Dp' command. This command is a 'gtroff' extension. +- +-'Dt N' +- Set the current line thickness to N (an integer in basic units 'u') +- if N>0; if N=0 select the smallest available line thickness; if N<0 +- set the line thickness proportional to the point size (this is the +- default before the first 'Dt' command was specified). For +- historical reasons, the horizontal position is changed by adding +- the argument to the actual horizontal position, while the vertical +- position is not changed. Although this doesn't make sense it is +- kept for compatibility. This command is a 'gtroff' extension. +- +- +-File: groff.info, Node: Device Control Commands, Next: Obsolete Command, Prev: Graphics Commands, Up: Command Reference +- +-8.1.2.4 Device Control Commands +-............................... +- +-Each device control command starts with the letter 'x', followed by a +-space character (optional or arbitrary space or tab in 'gtroff') and a +-subcommand letter or word; each argument (if any) must be preceded by a +-syntactical space. All 'x' commands are terminated by a syntactical +-line break; no device control command can be followed by another command +-on the same line (except a comment). +- +- The subcommand is basically a single letter, but to increase +-readability, it can be written as a word, i.e., an arbitrary sequence of +-characters terminated by the next tab, space, or newline character. All +-characters of the subcommand word but the first are simply ignored. For +-example, 'gtroff' outputs the initialization command 'x i' as 'x init' +-and the resolution command 'x r' as 'x res'. +- +- In the following, the syntax element means a syntactical +-line break (*note Separation::). +- +-'xF NAME' +- The 'F' stands for FILENAME. +- +- Use NAME as the intended name for the current file in error +- reports. This is useful for remembering the original file name +- when 'gtroff' uses an internal piping mechanism. The input file is +- not changed by this command. This command is a 'gtroff' extension. +- +-'xf N S' +- The 'f' stands for FONT. +- +- Mount font position N (a non-negative integer) with font named S (a +- text word). *Note Font Positions::. +- +-'xH N' +- The 'H' stands for HEIGHT. +- +- Set glyph height to N (a positive integer in scaled points 'z'). +- AT&T 'troff' uses the unit points ('p') instead. *Note Output +- Language Compatibility::. +- +-'xi' +- The 'i' stands for INIT. +- +- Initialize device. This is the third command of the prologue. +- +-'xp' +- The 'p' stands for PAUSE. +- +- Parsed but ignored. The original UNIX troff manual writes +- +- pause device, can be restarted +- +-'xr N H V' +- The 'r' stands for RESOLUTION. +- +- Resolution is N, while H is the minimal horizontal motion, and V +- the minimal vertical motion possible with this device; all +- arguments are positive integers in basic units 'u' per inch. This +- is the second command of the prologue. +- +-'xS N' +- The 'S' stands for SLANT. +- +- Set slant to N (an integer in basic units 'u'). +- +-'xs' +- The 's' stands for STOP. +- +- Terminates the processing of the current file; issued as the last +- command of any intermediate troff output. +- +-'xt' +- The 't' stands for TRAILER. +- +- Generate trailer information, if any. In GTROFF, this is actually +- just ignored. +- +-'xT XXX' +- The 'T' stands for TYPESETTER. +- +- Set name of device to word XXX, a sequence of characters ended by +- the next white space character. The possible device names coincide +- with those from the 'groff' '-T' option. This is the first command +- of the prologue. +- +-'xu N' +- The 'u' stands for UNDERLINE. +- +- Configure underlining of spaces. If N is 1, start underlining of +- spaces; if N is 0, stop underlining of spaces. This is needed for +- the 'cu' request in nroff mode and is ignored otherwise. This +- command is a 'gtroff' extension. +- +-'xX ANYTHING' +- The 'x' stands for X-ESCAPE. +- +- Send string ANYTHING uninterpreted to the device. If the line +- following this command starts with a '+' character this line is +- interpreted as a continuation line in the following sense. The '+' +- is ignored, but a newline character is sent instead to the device, +- the rest of the line is sent uninterpreted. The same applies to +- all following lines until the first character of a line is not a +- '+' character. This command is generated by the 'gtroff' escape +- sequence '\X'. The line-continuing feature is a 'gtroff' +- extension. +- +- +-File: groff.info, Node: Obsolete Command, Prev: Device Control Commands, Up: Command Reference +- +-8.1.2.5 Obsolete Command +-........................ +- +-In AT&T 'troff' output, the writing of a single glyph is mostly done by +-a very strange command that combines a horizontal move and a single +-character giving the glyph name. It doesn't have a command code, but is +-represented by a 3-character argument consisting of exactly 2 digits and +-a character. +- +-DDG +- Move right DD (exactly two decimal digits) basic units 'u', then +- print glyph G (represented as a single character). +- +- In 'gtroff', arbitrary syntactical space around and within this +- command is allowed to be added. Only when a preceding command on +- the same line ends with an argument of variable length a separating +- space is obligatory. In AT&T 'troff', large clusters of these and +- other commands are used, mostly without spaces; this made such +- output almost unreadable. +- +- For modern high-resolution devices, this command does not make sense +-because the width of the glyphs can become much larger than two decimal +-digits. In 'gtroff', this is only used for the devices 'X75', 'X75-12', +-'X100', and 'X100-12'. For other devices, the commands 't' and 'u' +-provide a better functionality. +- +- +-File: groff.info, Node: Intermediate Output Examples, Next: Output Language Compatibility, Prev: Command Reference, Up: gtroff Output +- +-8.1.3 Intermediate Output Examples +----------------------------------- +- +-This section presents the intermediate output generated from the same +-input for three different devices. The input is the sentence 'hell +-world' fed into 'gtroff' on the command line. +- +-High-resolution device 'ps' +- +- This is the standard output of 'gtroff' if no '-T' option is given. +- +- shell> echo "hell world" | groff -Z -T ps +- +- x T ps +- x res 72000 1 1 +- x init +- p1 +- x font 5 TR +- f5 +- s10000 +- V12000 +- H72000 +- thell +- wh2500 +- tw +- H96620 +- torld +- n12000 0 +- x trailer +- V792000 +- x stop +- +- This output can be fed into 'grops' to get its representation as a +- POSTSCRIPT file. +- +-Low-resolution device 'latin1' +- +- This is similar to the high-resolution device except that the +- positioning is done at a minor scale. Some comments (lines +- starting with '#') were added for clarification; they were not +- generated by the formatter. +- +- shell> echo "hell world" | groff -Z -T latin1 +- +- # prologue +- x T latin1 +- x res 240 24 40 +- x init +- # begin a new page +- p1 +- # font setup +- x font 1 R +- f1 +- s10 +- # initial positioning on the page +- V40 +- H0 +- # write text `hell' +- thell +- # inform about space, and issue a horizontal jump +- wh24 +- # write text `world' +- tworld +- # announce line break, but do nothing because ... +- n40 0 +- # ... the end of the document has been reached +- x trailer +- V2640 +- x stop +- +- This output can be fed into 'grotty' to get a formatted text +- document. +- +-AT&T 'troff' output +- Since a computer monitor has a very low resolution compared to +- modern printers the intermediate output for the X Window devices +- can use the jump-and-write command with its 2-digit displacements. +- +- shell> echo "hell world" | groff -Z -T X100 +- +- x T X100 +- x res 100 1 1 +- x init +- p1 +- x font 5 TR +- f5 +- s10 +- V16 +- H100 +- # write text with jump-and-write commands +- ch07e07l03lw06w11o07r05l03dh7 +- n16 0 +- x trailer +- V1100 +- x stop +- +- This output can be fed into 'xditview' or 'gxditview' for +- displaying in X. +- +- Due to the obsolete jump-and-write command, the text clusters in +- the AT&T 'troff' output are almost unreadable. +- +- +-File: groff.info, Node: Output Language Compatibility, Prev: Intermediate Output Examples, Up: gtroff Output +- +-8.1.4 Output Language Compatibility +------------------------------------ +- +-The intermediate output language of AT&T 'troff' was first documented in +-the UNIX troff manual, with later additions documented in 'A +-Typesetter-indenpendent TROFF', written by Brian Kernighan. +- +- The 'gtroff' intermediate output format is compatible with this +-specification except for the following features. +- +- * The classical quasi device independence is not yet implemented. +- +- * The old hardware was very different from what we use today. So the +- 'groff' devices are also fundamentally different from the ones in +- AT&T 'troff'. For example, the AT&T POSTSCRIPT device is called +- 'post' and has a resolution of only 720 units per inch, suitable +- for printers 20 years ago, while 'groff''s 'ps' device has a +- resolution of 72000 units per inch. Maybe, by implementing some +- rescaling mechanism similar to the classical quasi device +- independence, 'groff' could emulate AT&T's 'post' device. +- +- * The B-spline command 'D~' is correctly handled by the intermediate +- output parser, but the drawing routines aren't implemented in some +- of the postprocessor programs. +- +- * The argument of the commands 's' and 'x H' has the implicit unit +- scaled point 'z' in 'gtroff', while AT&T 'troff' has point ('p'). +- This isn't an incompatibility but a compatible extension, for both +- units coincide for all devices without a 'sizescale' parameter in +- the 'DESC' file, including all postprocessors from AT&T and +- 'groff''s text devices. The few 'groff' devices with a 'sizescale' +- parameter either do not exist for AT&T 'troff', have a different +- name, or seem to have a different resolution. So conflicts are +- very unlikely. +- +- * The position changing after the commands 'Dp', 'DP', and 'Dt' is +- illogical, but as old versions of 'gtroff' used this feature it is +- kept for compatibility reasons. +- +- +-File: groff.info, Node: Font Files, Prev: gtroff Output, Up: File formats +- +-8.2 Font Files +-============== +- +-The 'gtroff' font format is roughly a superset of the 'ditroff' font +-format (as used in later versions of AT&T 'troff' and its descendants). +-Unlike the 'ditroff' font format, there is no associated binary format; +-all files are text files.(1) (*note Font Files-Footnote-1::) The font +-files for device NAME are stored in a directory 'devNAME'. There are +-two types of file: a device description file called 'DESC' and for each +-font F a font file called 'F'. +- +-* Menu: +- +-* DESC File Format:: +-* Font File Format:: +- +- +-File: groff.info, Node: Font Files-Footnotes, Up: Font Files +- +- (1) Plan 9 'troff' has also abandoned the binary format. +- +- +-File: groff.info, Node: DESC File Format, Next: Font File Format, Prev: Font Files, Up: Font Files +- +-8.2.1 'DESC' File Format +------------------------- +- +-The 'DESC' file can contain the following types of line. Except for the +-'charset' keyword, which must comes last (if at all), the order of the +-lines is not important. Later entries in the file, however, override +-previous values. +- +-'charset' +- This line and everything following in the file are ignored. It is +- allowed for the sake of backwards compatibility. +- +-'family FAM' +- The default font family is FAM. +- +-'fonts N F1 F2 F3 ... FN' +- Fonts F1 ... FN are mounted in the font positions M+1, ..., M+N +- where M is the number of styles. This command may extend over more +- than one line. A font name of 0 means no font is mounted on the +- corresponding font position. +- +-'hor N' +- The horizontal resolution is N machine units. All horizontal +- quantities are rounded to be multiples of this value. +- +-'image_generator STRING' +- Needed for 'grohtml' only. It specifies the program to generate +- PNG images from POSTSCRIPT input. Under GNU/Linux this is usually +- 'gs' but under other systems (notably cygwin) it might be set to +- another name. +- +-'paperlength N' +- The physical vertical dimension of the output medium in machine +- units. This isn't used by 'troff' itself but by output devices. +- Deprecated. Use 'papersize' instead. +- +-'papersize STRING ...' +- Select a paper size. Valid values for STRING are the ISO paper +- types 'A0'-'A7', 'B0'-'B7', 'C0'-'C7', 'D0'-'D7', 'DL', and the US +- paper types 'letter', 'legal', 'tabloid', 'ledger', 'statement', +- 'executive', 'com10', and 'monarch'. Case is not significant for +- STRING if it holds predefined paper types. Alternatively, STRING +- can be a file name (e.g. '/etc/papersize'); if the file can be +- opened, 'groff' reads the first line and tests for the above paper +- sizes. Finally, STRING can be a custom paper size in the format +- 'LENGTH,WIDTH' (no spaces before and after the comma). Both LENGTH +- and WIDTH must have a unit appended; valid values are 'i' for +- inches, 'C' for centimeters, 'p' for points, and 'P' for picas. +- Example: '12c,235p'. An argument that starts with a digit is +- always treated as a custom paper format. 'papersize' sets both the +- vertical and horizontal dimension of the output medium. +- +- More than one argument can be specified; 'groff' scans from left to +- right and uses the first valid paper specification. +- +-'paperwidth N' +- The physical horizontal dimension of the output medium in machine +- units. This isn't used by 'troff' itself but by output devices. +- Deprecated. Use 'papersize' instead. +- +-'pass_filenames' +- Tell 'gtroff' to emit the name of the source file currently being +- processed. This is achieved by the intermediate output command +- 'F'. Currently, this is only used by the 'grohtml' output device. +- +-'postpro PROGRAM' +- Call PROGRAM as a postprocessor. For example, the line +- +- postpro grodvi +- +- in the file 'devdvi/DESC' makes 'groff' call 'grodvi' if option +- '-Tdvi' is given (and '-Z' isn't used). +- +-'prepro PROGRAM' +- Call PROGRAM as a preprocessor. Currently, this keyword is used by +- 'groff' with option '-Thtml' or '-Txhtml' only. +- +-'print PROGRAM' +- Use PROGRAM as a spooler program for printing. If omitted, the +- '-l' and '-L' options of 'groff' are ignored. +- +-'res N' +- There are N machine units per inch. +- +-'sizes S1 S2 ... SN 0' +- This means that the device has fonts at S1, S2, ... SN scaled +- points. The list of sizes must be terminated by 0 (this is digit +- zero). Each SI can also be a range of sizes M-N. The list can +- extend over more than one line. +- +-'sizescale N' +- The scale factor for point sizes. By default this has a value +- of 1. One scaled point is equal to one point/N. The arguments to +- the 'unitwidth' and 'sizes' commands are given in scaled points. +- *Note Fractional Type Sizes::, for more information. +- +-'styles S1 S2 ... SM' +- The first M font positions are associated with styles S1 ... SM. +- +-'tcommand' +- This means that the postprocessor can handle the 't' and 'u' +- intermediate output commands. +- +-'unicode' +- Indicate that the output device supports the complete Unicode +- repertoire. Useful only for devices that produce _character +- entities_ instead of glyphs. +- +- If 'unicode' is present, no 'charset' section is required in the +- font description files since the Unicode handling built into +- 'groff' is used. However, if there are entries in a 'charset' +- section, they either override the default mappings for those +- particular characters or add new mappings (normally for composite +- characters). +- +- This is used for '-Tutf8', '-Thtml', and '-Txhtml'. +- +-'unitwidth N' +- Quantities in the font files are given in machine units for fonts +- whose point size is N scaled points. +- +-'unscaled_charwidths' +- Make the font handling module always return unscaled character +- widths. Needed for the 'grohtml' device. +- +-'use_charnames_in_special' +- This command indicates that 'gtroff' should encode special +- characters inside special commands. Currently, this is only used +- by the 'grohtml' output device. *Note Postprocessor Access::. +- +-'vert N' +- The vertical resolution is N machine units. All vertical +- quantities are rounded to be multiples of this value. +- +- The 'res', 'unitwidth', 'fonts', and 'sizes' lines are mandatory. +-Other commands are ignored by 'gtroff' but may be used by postprocessors +-to store arbitrary information about the device in the 'DESC' file. +- +- Here a list of obsolete keywords that are recognized by 'groff' but +-completely ignored: 'spare1', 'spare2', 'biggestfont'. +- +- +-File: groff.info, Node: Font File Format, Prev: DESC File Format, Up: Font Files +- +-8.2.2 Font File Format +----------------------- +- +-A "font file", also (and probably better) called a "font description +-file", has two sections. The first section is a sequence of lines each +-containing a sequence of blank delimited words; the first word in the +-line is a key, and subsequent words give a value for that key. +- +-'name F' +- The name of the font is F. +- +-'spacewidth N' +- The normal width of a space is N. +- +-'slant N' +- The glyphs of the font have a slant of N degrees. (Positive means +- forward.) +- +-'ligatures LIG1 LIG2 ... LIGN [0]' +- Glyphs LIG1, LIG2, ..., LIGN are ligatures; possible ligatures are +- 'ff', 'fi', 'fl', 'ffi' and 'ffl'. For backwards compatibility, +- the list of ligatures may be terminated with a 0. The list of +- ligatures may not extend over more than one line. +- +-'special' +- The font is "special"; this means that when a glyph is requested +- that is not present in the current font, it is searched for in any +- special fonts that are mounted. +- +- Other commands are ignored by 'gtroff' but may be used by +-postprocessors to store arbitrary information about the font in the font +-file. +- +- The first section can contain comments, which start with the '#' +-character and extend to the end of a line. +- +- The second section contains one or two subsections. It must contain +-a 'charset' subsection and it may also contain a 'kernpairs' subsection. +-These subsections can appear in any order. Each subsection starts with +-a word on a line by itself. +- +- The word 'charset' starts the character set subsection.(1) (*note +-Font File Format-Footnote-1::) The 'charset' line is followed by a +-sequence of lines. Each line gives information for one glyph. A line +-comprises a number of fields separated by blanks or tabs. The format is +- +- NAME METRICS TYPE CODE [ENTITY-NAME] ['--' COMMENT] +- +-NAME identifies the glyph name(2) (*note Font File Format-Footnote-2::): +-If NAME is a single character C then it corresponds to the 'gtroff' +-input character C; if it is of the form '\C' where C is a single +-character, then it corresponds to the special character '\[C]'; +-otherwise it corresponds to the special character '\[NAME]'. If it is +-exactly two characters XX it can be entered as '\(XX'. Note that +-single-letter special characters can't be accessed as '\C'; the only +-exception is '\-', which is identical to '\[-]'. +- +- 'gtroff' supports 8-bit input characters; however some utilities have +-difficulties with eight-bit characters. For this reason, there is a +-convention that the entity name 'charN' is equivalent to the single +-input character whose code is N. For example, 'char163' would be +-equivalent to the character with code 163, which is the pounds sterling +-sign in the ISO Latin-1 character set. You shouldn't use 'charN' +-entities in font description files since they are related to input, not +-output. Otherwise, you get hard-coded connections between input and +-output encoding, which prevents use of different (input) character sets. +- +- The name '---' is special and indicates that the glyph is unnamed; +-such glyphs can only be used by means of the '\N' escape sequence in +-'gtroff'. +- +- The TYPE field gives the glyph type: +- +-'1' +- the glyph has a descender, for example, 'p'; +- +-'2' +- the glyph has an ascender, for example, 'b'; +- +-'3' +- the glyph has both an ascender and a descender, for example, '('. +- +- The CODE field gives the code that the postprocessor uses to print +-the glyph. The glyph can also be input to 'gtroff' using this code by +-means of the '\N' escape sequence. CODE can be any integer. If it +-starts with '0' it is interpreted as octal; if it starts with '0x' or +-'0X' it is interpreted as hexadecimal. Note, however, that the '\N' +-escape sequence only accepts a decimal integer. +- +- The ENTITY-NAME field gives an ASCII string identifying the glyph +-that the postprocessor uses to print the 'gtroff' glyph NAME. This +-field is optional and has been introduced so that the 'grohtml' device +-driver can encode its character set. For example, the glyph '\[Po]' is +-represented as '£' in HTML 4.0. +- +- Anything on the line after the ENTITY-NAME field resp. after '--' is +-ignored. +- +- The METRICS field has the form: +- +- WIDTH[','HEIGHT[','DEPTH[','ITALIC-CORRECTION +- [','LEFT-ITALIC-CORRECTION[','SUBSCRIPT-CORRECTION]]]]] +- +-There must not be any spaces between these subfields (it has been split +-here into two lines for better legibility only). Missing subfields are +-assumed to be 0. The subfields are all decimal integers. Since there +-is no associated binary format, these values are not required to fit +-into a variable of type 'char' as they are in 'ditroff'. The WIDTH +-subfield gives the width of the glyph. The HEIGHT subfield gives the +-height of the glyph (upwards is positive); if a glyph does not extend +-above the baseline, it should be given a zero height, rather than a +-negative height. The DEPTH subfield gives the depth of the glyph, that +-is, the distance from the baseline to the lowest point below the +-baseline to which the glyph extends (downwards is positive); if a glyph +-does not extend below the baseline, it should be given a zero depth, +-rather than a negative depth. The ITALIC-CORRECTION subfield gives the +-amount of space that should be added after the glyph when it is +-immediately to be followed by a glyph from a roman font. The +-LEFT-ITALIC-CORRECTION subfield gives the amount of space that should be +-added before the glyph when it is immediately to be preceded by a glyph +-from a roman font. The SUBSCRIPT-CORRECTION gives the amount of space +-that should be added after a glyph before adding a subscript. This +-should be less than the italic correction. +- +- A line in the 'charset' section can also have the format +- +- NAME " +- +-This indicates that NAME is just another name for the glyph mentioned in +-the preceding line. +- +- The word 'kernpairs' starts the kernpairs section. This contains a +-sequence of lines of the form: +- +- C1 C2 N +- +-This means that when glyph C1 appears next to glyph C2 the space between +-them should be increased by N. Most entries in the kernpairs section +-have a negative value for N. +- +- +-File: groff.info, Node: Font File Format-Footnotes, Up: Font File Format +- +- (1) This keyword is misnamed since it starts a list of ordered +-glyphs, not characters. +- +- (2) The distinction between input, characters, and output, glyphs, is +-not clearly separated in the terminology of 'groff'; for example, the +-'char' request should be called 'glyph' since it defines an output +-entity. +- +- +-File: groff.info, Node: Installation, Next: Copying This Manual, Prev: File formats, Up: Top +- +-9 Installation +-************** +- +- +-File: groff.info, Node: Copying This Manual, Next: Request Index, Prev: Installation, Up: Top +- +-Appendix A Copying This Manual +-****************************** +- +- Version 1.3, 3 November 2008 +- +- Copyright 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +- +- +- Everyone is permitted to copy and distribute verbatim copies +- of this license document, but changing it is not allowed. +- +- 0. PREAMBLE +- +- The purpose of this License is to make a manual, textbook, or other +- functional and useful document "free" in the sense of freedom: to +- assure everyone the effective freedom to copy and redistribute it, +- with or without modifying it, either commercially or +- noncommercially. Secondarily, this License preserves for the +- author and publisher a way to get credit for their work, while not +- being considered responsible for modifications made by others. +- +- This License is a kind of "copyleft", which means that derivative +- works of the document must themselves be free in the same sense. +- It complements the GNU General Public License, which is a copyleft +- license designed for free software. +- +- We have designed this License in order to use it for manuals for +- free software, because free software needs free documentation: a +- free program should come with manuals providing the same freedoms +- that the software does. But this License is not limited to +- software manuals; it can be used for any textual work, regardless +- of subject matter or whether it is published as a printed book. We +- recommend this License principally for works whose purpose is +- instruction or reference. +- +- 1. APPLICABILITY AND DEFINITIONS +- +- This License applies to any manual or other work, in any medium, +- that contains a notice placed by the copyright holder saying it can +- be distributed under the terms of this License. Such a notice +- grants a world-wide, royalty-free license, unlimited in duration, +- to use that work under the conditions stated herein. The +- "Document", below, refers to any such manual or work. Any member +- of the public is a licensee, and is addressed as "you". You accept +- the license if you copy, modify or distribute the work in a way +- requiring permission under copyright law. +- +- A "Modified Version" of the Document means any work containing the +- Document or a portion of it, either copied verbatim, or with +- modifications and/or translated into another language. +- +- A "Secondary Section" is a named appendix or a front-matter section +- of the Document that deals exclusively with the relationship of the +- publishers or authors of the Document to the Document's overall +- subject (or to related matters) and contains nothing that could +- fall directly within that overall subject. (Thus, if the Document +- is in part a textbook of mathematics, a Secondary Section may not +- explain any mathematics.) The relationship could be a matter of +- historical connection with the subject or with related matters, or +- of legal, commercial, philosophical, ethical or political position +- regarding them. +- +- The "Invariant Sections" are certain Secondary Sections whose +- titles are designated, as being those of Invariant Sections, in the +- notice that says that the Document is released under this License. +- If a section does not fit the above definition of Secondary then it +- is not allowed to be designated as Invariant. The Document may +- contain zero Invariant Sections. If the Document does not identify +- any Invariant Sections then there are none. +- +- The "Cover Texts" are certain short passages of text that are +- listed, as Front-Cover Texts or Back-Cover Texts, in the notice +- that says that the Document is released under this License. A +- Front-Cover Text may be at most 5 words, and a Back-Cover Text may +- be at most 25 words. +- +- A "Transparent" copy of the Document means a machine-readable copy, +- represented in a format whose specification is available to the +- general public, that is suitable for revising the document +- straightforwardly with generic text editors or (for images composed +- of pixels) generic paint programs or (for drawings) some widely +- available drawing editor, and that is suitable for input to text +- formatters or for automatic translation to a variety of formats +- suitable for input to text formatters. A copy made in an otherwise +- Transparent file format whose markup, or absence of markup, has +- been arranged to thwart or discourage subsequent modification by +- readers is not Transparent. An image format is not Transparent if +- used for any substantial amount of text. A copy that is not +- "Transparent" is called "Opaque". +- +- Examples of suitable formats for Transparent copies include plain +- ASCII without markup, Texinfo input format, LaTeX input format, +- SGML or XML using a publicly available DTD, and standard-conforming +- simple HTML, PostScript or PDF designed for human modification. +- Examples of transparent image formats include PNG, XCF and JPG. +- Opaque formats include proprietary formats that can be read and +- edited only by proprietary word processors, SGML or XML for which +- the DTD and/or processing tools are not generally available, and +- the machine-generated HTML, PostScript or PDF produced by some word +- processors for output purposes only. +- +- The "Title Page" means, for a printed book, the title page itself, +- plus such following pages as are needed to hold, legibly, the +- material this License requires to appear in the title page. For +- works in formats which do not have any title page as such, "Title +- Page" means the text near the most prominent appearance of the +- work's title, preceding the beginning of the body of the text. +- +- The "publisher" means any person or entity that distributes copies +- of the Document to the public. +- +- A section "Entitled XYZ" means a named subunit of the Document +- whose title either is precisely XYZ or contains XYZ in parentheses +- following text that translates XYZ in another language. (Here XYZ +- stands for a specific section name mentioned below, such as +- "Acknowledgements", "Dedications", "Endorsements", or "History".) +- To "Preserve the Title" of such a section when you modify the +- Document means that it remains a section "Entitled XYZ" according +- to this definition. +- +- The Document may include Warranty Disclaimers next to the notice +- which states that this License applies to the Document. These +- Warranty Disclaimers are considered to be included by reference in +- this License, but only as regards disclaiming warranties: any other +- implication that these Warranty Disclaimers may have is void and +- has no effect on the meaning of this License. +- +- 2. VERBATIM COPYING +- +- You may copy and distribute the Document in any medium, either +- commercially or noncommercially, provided that this License, the +- copyright notices, and the license notice saying this License +- applies to the Document are reproduced in all copies, and that you +- add no other conditions whatsoever to those of this License. You +- may not use technical measures to obstruct or control the reading +- or further copying of the copies you make or distribute. However, +- you may accept compensation in exchange for copies. If you +- distribute a large enough number of copies you must also follow the +- conditions in section 3. +- +- You may also lend copies, under the same conditions stated above, +- and you may publicly display copies. +- +- 3. COPYING IN QUANTITY +- +- If you publish printed copies (or copies in media that commonly +- have printed covers) of the Document, numbering more than 100, and +- the Document's license notice requires Cover Texts, you must +- enclose the copies in covers that carry, clearly and legibly, all +- these Cover Texts: Front-Cover Texts on the front cover, and +- Back-Cover Texts on the back cover. Both covers must also clearly +- and legibly identify you as the publisher of these copies. The +- front cover must present the full title with all words of the title +- equally prominent and visible. You may add other material on the +- covers in addition. Copying with changes limited to the covers, as +- long as they preserve the title of the Document and satisfy these +- conditions, can be treated as verbatim copying in other respects. +- +- If the required texts for either cover are too voluminous to fit +- legibly, you should put the first ones listed (as many as fit +- reasonably) on the actual cover, and continue the rest onto +- adjacent pages. +- +- If you publish or distribute Opaque copies of the Document +- numbering more than 100, you must either include a machine-readable +- Transparent copy along with each Opaque copy, or state in or with +- each Opaque copy a computer-network location from which the general +- network-using public has access to download using public-standard +- network protocols a complete Transparent copy of the Document, free +- of added material. If you use the latter option, you must take +- reasonably prudent steps, when you begin distribution of Opaque +- copies in quantity, to ensure that this Transparent copy will +- remain thus accessible at the stated location until at least one +- year after the last time you distribute an Opaque copy (directly or +- through your agents or retailers) of that edition to the public. +- +- It is requested, but not required, that you contact the authors of +- the Document well before redistributing any large number of copies, +- to give them a chance to provide you with an updated version of the +- Document. +- +- 4. MODIFICATIONS +- +- You may copy and distribute a Modified Version of the Document +- under the conditions of sections 2 and 3 above, provided that you +- release the Modified Version under precisely this License, with the +- Modified Version filling the role of the Document, thus licensing +- distribution and modification of the Modified Version to whoever +- possesses a copy of it. In addition, you must do these things in +- the Modified Version: +- +- A. Use in the Title Page (and on the covers, if any) a title +- distinct from that of the Document, and from those of previous +- versions (which should, if there were any, be listed in the +- History section of the Document). You may use the same title +- as a previous version if the original publisher of that +- version gives permission. +- +- B. List on the Title Page, as authors, one or more persons or +- entities responsible for authorship of the modifications in +- the Modified Version, together with at least five of the +- principal authors of the Document (all of its principal +- authors, if it has fewer than five), unless they release you +- from this requirement. +- +- C. State on the Title page the name of the publisher of the +- Modified Version, as the publisher. +- +- D. Preserve all the copyright notices of the Document. +- +- E. Add an appropriate copyright notice for your modifications +- adjacent to the other copyright notices. +- +- F. Include, immediately after the copyright notices, a license +- notice giving the public permission to use the Modified +- Version under the terms of this License, in the form shown in +- the Addendum below. +- +- G. Preserve in that license notice the full lists of Invariant +- Sections and required Cover Texts given in the Document's +- license notice. +- +- H. Include an unaltered copy of this License. +- +- I. Preserve the section Entitled "History", Preserve its Title, +- and add to it an item stating at least the title, year, new +- authors, and publisher of the Modified Version as given on the +- Title Page. If there is no section Entitled "History" in the +- Document, create one stating the title, year, authors, and +- publisher of the Document as given on its Title Page, then add +- an item describing the Modified Version as stated in the +- previous sentence. +- +- J. Preserve the network location, if any, given in the Document +- for public access to a Transparent copy of the Document, and +- likewise the network locations given in the Document for +- previous versions it was based on. These may be placed in the +- "History" section. You may omit a network location for a work +- that was published at least four years before the Document +- itself, or if the original publisher of the version it refers +- to gives permission. +- +- K. For any section Entitled "Acknowledgements" or "Dedications", +- Preserve the Title of the section, and preserve in the section +- all the substance and tone of each of the contributor +- acknowledgements and/or dedications given therein. +- +- L. Preserve all the Invariant Sections of the Document, unaltered +- in their text and in their titles. Section numbers or the +- equivalent are not considered part of the section titles. +- +- M. Delete any section Entitled "Endorsements". Such a section +- may not be included in the Modified Version. +- +- N. Do not retitle any existing section to be Entitled +- "Endorsements" or to conflict in title with any Invariant +- Section. +- +- O. Preserve any Warranty Disclaimers. +- +- If the Modified Version includes new front-matter sections or +- appendices that qualify as Secondary Sections and contain no +- material copied from the Document, you may at your option designate +- some or all of these sections as invariant. To do this, add their +- titles to the list of Invariant Sections in the Modified Version's +- license notice. These titles must be distinct from any other +- section titles. +- +- You may add a section Entitled "Endorsements", provided it contains +- nothing but endorsements of your Modified Version by various +- parties--for example, statements of peer review or that the text +- has been approved by an organization as the authoritative +- definition of a standard. +- +- You may add a passage of up to five words as a Front-Cover Text, +- and a passage of up to 25 words as a Back-Cover Text, to the end of +- the list of Cover Texts in the Modified Version. Only one passage +- of Front-Cover Text and one of Back-Cover Text may be added by (or +- through arrangements made by) any one entity. If the Document +- already includes a cover text for the same cover, previously added +- by you or by arrangement made by the same entity you are acting on +- behalf of, you may not add another; but you may replace the old +- one, on explicit permission from the previous publisher that added +- the old one. +- +- The author(s) and publisher(s) of the Document do not by this +- License give permission to use their names for publicity for or to +- assert or imply endorsement of any Modified Version. +- +- 5. COMBINING DOCUMENTS +- +- You may combine the Document with other documents released under +- this License, under the terms defined in section 4 above for +- modified versions, provided that you include in the combination all +- of the Invariant Sections of all of the original documents, +- unmodified, and list them all as Invariant Sections of your +- combined work in its license notice, and that you preserve all +- their Warranty Disclaimers. +- +- The combined work need only contain one copy of this License, and +- multiple identical Invariant Sections may be replaced with a single +- copy. If there are multiple Invariant Sections with the same name +- but different contents, make the title of each such section unique +- by adding at the end of it, in parentheses, the name of the +- original author or publisher of that section if known, or else a +- unique number. Make the same adjustment to the section titles in +- the list of Invariant Sections in the license notice of the +- combined work. +- +- In the combination, you must combine any sections Entitled +- "History" in the various original documents, forming one section +- Entitled "History"; likewise combine any sections Entitled +- "Acknowledgements", and any sections Entitled "Dedications". You +- must delete all sections Entitled "Endorsements." +- +- 6. COLLECTIONS OF DOCUMENTS +- +- You may make a collection consisting of the Document and other +- documents released under this License, and replace the individual +- copies of this License in the various documents with a single copy +- that is included in the collection, provided that you follow the +- rules of this License for verbatim copying of each of the documents +- in all other respects. +- +- You may extract a single document from such a collection, and +- distribute it individually under this License, provided you insert +- a copy of this License into the extracted document, and follow this +- License in all other respects regarding verbatim copying of that +- document. +- +- 7. AGGREGATION WITH INDEPENDENT WORKS +- +- A compilation of the Document or its derivatives with other +- separate and independent documents or works, in or on a volume of a +- storage or distribution medium, is called an "aggregate" if the +- copyright resulting from the compilation is not used to limit the +- legal rights of the compilation's users beyond what the individual +- works permit. When the Document is included in an aggregate, this +- License does not apply to the other works in the aggregate which +- are not themselves derivative works of the Document. +- +- If the Cover Text requirement of section 3 is applicable to these +- copies of the Document, then if the Document is less than one half +- of the entire aggregate, the Document's Cover Texts may be placed +- on covers that bracket the Document within the aggregate, or the +- electronic equivalent of covers if the Document is in electronic +- form. Otherwise they must appear on printed covers that bracket +- the whole aggregate. +- +- 8. TRANSLATION +- +- Translation is considered a kind of modification, so you may +- distribute translations of the Document under the terms of section +- 4. Replacing Invariant Sections with translations requires special +- permission from their copyright holders, but you may include +- translations of some or all Invariant Sections in addition to the +- original versions of these Invariant Sections. You may include a +- translation of this License, and all the license notices in the +- Document, and any Warranty Disclaimers, provided that you also +- include the original English version of this License and the +- original versions of those notices and disclaimers. In case of a +- disagreement between the translation and the original version of +- this License or a notice or disclaimer, the original version will +- prevail. +- +- If a section in the Document is Entitled "Acknowledgements", +- "Dedications", or "History", the requirement (section 4) to +- Preserve its Title (section 1) will typically require changing the +- actual title. +- +- 9. TERMINATION +- +- You may not copy, modify, sublicense, or distribute the Document +- except as expressly provided under this License. Any attempt +- otherwise to copy, modify, sublicense, or distribute it is void, +- and will automatically terminate your rights under this License. +- +- However, if you cease all violation of this License, then your +- license from a particular copyright holder is reinstated (a) +- provisionally, unless and until the copyright holder explicitly and +- finally terminates your license, and (b) permanently, if the +- copyright holder fails to notify you of the violation by some +- reasonable means prior to 60 days after the cessation. +- +- Moreover, your license from a particular copyright holder is +- reinstated permanently if the copyright holder notifies you of the +- violation by some reasonable means, this is the first time you have +- received notice of violation of this License (for any work) from +- that copyright holder, and you cure the violation prior to 30 days +- after your receipt of the notice. +- +- Termination of your rights under this section does not terminate +- the licenses of parties who have received copies or rights from you +- under this License. If your rights have been terminated and not +- permanently reinstated, receipt of a copy of some or all of the +- same material does not give you any rights to use it. +- +- 10. FUTURE REVISIONS OF THIS LICENSE +- +- The Free Software Foundation may publish new, revised versions of +- the GNU Free Documentation License from time to time. Such new +- versions will be similar in spirit to the present version, but may +- differ in detail to address new problems or concerns. See +- . +- +- Each version of the License is given a distinguishing version +- number. If the Document specifies that a particular numbered +- version of this License "or any later version" applies to it, you +- have the option of following the terms and conditions either of +- that specified version or of any later version that has been +- published (not as a draft) by the Free Software Foundation. If the +- Document does not specify a version number of this License, you may +- choose any version ever published (not as a draft) by the Free +- Software Foundation. If the Document specifies that a proxy can +- decide which future versions of this License can be used, that +- proxy's public statement of acceptance of a version permanently +- authorizes you to choose that version for the Document. +- +- 11. RELICENSING +- +- "Massive Multiauthor Collaboration Site" (or "MMC Site") means any +- World Wide Web server that publishes copyrightable works and also +- provides prominent facilities for anybody to edit those works. A +- public wiki that anybody can edit is an example of such a server. +- A "Massive Multiauthor Collaboration" (or "MMC") contained in the +- site means any set of copyrightable works thus published on the MMC +- site. +- +- "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 +- license published by Creative Commons Corporation, a not-for-profit +- corporation with a principal place of business in San Francisco, +- California, as well as future copyleft versions of that license +- published by that same organization. +- +- "Incorporate" means to publish or republish a Document, in whole or +- in part, as part of another Document. +- +- An MMC is "eligible for relicensing" if it is licensed under this +- License, and if all works that were first published under this +- License somewhere other than this MMC, and subsequently +- incorporated in whole or in part into the MMC, (1) had no cover +- texts or invariant sections, and (2) were thus incorporated prior +- to November 1, 2008. +- +- The operator of an MMC Site may republish an MMC contained in the +- site under CC-BY-SA on the same site at any time before August 1, +- 2009, provided the MMC is eligible for relicensing. +- +-ADDENDUM: How to use this License for your documents +-==================================================== +- +-To use this License in a document you have written, include a copy of +-the License in the document and put the following copyright and license +-notices just after the title page: +- +- Copyright (C) YEAR YOUR NAME. +- Permission is granted to copy, distribute and/or modify this document +- under the terms of the GNU Free Documentation License, Version 1.3 +- or any later version published by the Free Software Foundation; +- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover +- Texts. A copy of the license is included in the section entitled ``GNU +- Free Documentation License''. +- +- If you have Invariant Sections, Front-Cover Texts and Back-Cover +-Texts, replace the "with...Texts." line with this: +- +- with the Invariant Sections being LIST THEIR TITLES, with +- the Front-Cover Texts being LIST, and with the Back-Cover Texts +- being LIST. +- +- If you have Invariant Sections without Cover Texts, or some other +-combination of the three, merge those two alternatives to suit the +-situation. +- +- If your document contains nontrivial examples of program code, we +-recommend releasing these examples in parallel under your choice of free +-software license, such as the GNU General Public License, to permit +-their use in free software. +- +- +-File: groff.info, Node: Request Index, Next: Escape Index, Prev: Copying This Manual, Up: Top +- +-Appendix B Request Index +-************************ +- +-Requests appear without the leading control character (normally either +-'.' or '''). +- +-[index] +-* Menu: +- +-* ab: Debugging. (line 40) +-* ad: Manipulating Filling and Adjusting. +- (line 50) +-* af: Assigning Formats. (line 12) +-* aln: Setting Registers. (line 112) +-* als: Strings. (line 229) +-* am: Writing Macros. (line 113) +-* am1: Writing Macros. (line 114) +-* ami: Writing Macros. (line 115) +-* ami1: Writing Macros. (line 116) +-* as: Strings. (line 175) +-* as1: Strings. (line 176) +-* asciify: Diversions. (line 195) +-* backtrace: Debugging. (line 96) +-* bd: Artificial Fonts. (line 96) +-* blm: Blank Line Traps. (line 7) +-* box: Diversions. (line 34) +-* boxa: Diversions. (line 35) +-* bp: Page Control. (line 7) +-* br: Manipulating Filling and Adjusting. +- (line 12) +-* break: while. (line 68) +-* brp: Manipulating Filling and Adjusting. +- (line 130) +-* c2: Character Translations. +- (line 16) +-* cc: Character Translations. +- (line 10) +-* ce: Manipulating Filling and Adjusting. +- (line 203) +-* cf: I/O. (line 50) +-* cflags: Using Symbols. (line 237) +-* ch: Page Location Traps. (line 111) +-* char: Using Symbols. (line 323) +-* chop: Strings. (line 267) +-* class: Character Classes. (line 12) +-* close: I/O. (line 231) +-* color: Colors. (line 7) +-* composite: Using Symbols. (line 191) +-* continue: while. (line 72) +-* cp: Implementation Differences. +- (line 22) +-* cs: Artificial Fonts. (line 126) +-* cu: Artificial Fonts. (line 86) +-* da: Diversions. (line 22) +-* de: Writing Macros. (line 15) +-* de1: Writing Macros. (line 16) +-* defcolor: Colors. (line 22) +-* dei: Writing Macros. (line 17) +-* dei1: Writing Macros. (line 18) +-* device: Postprocessor Access. +- (line 11) +-* devicem: Postprocessor Access. +- (line 30) +-* di: Diversions. (line 21) +-* do: Implementation Differences. +- (line 23) +-* ds: Strings. (line 15) +-* ds1: Strings. (line 16) +-* dt: Diversion Traps. (line 7) +-* ec: Character Translations. +- (line 47) +-* ecr: Character Translations. +- (line 59) +-* ecs: Character Translations. +- (line 58) +-* el: if-else. (line 27) +-* em: End-of-input Traps. (line 7) +-* eo: Character Translations. +- (line 24) +-* ev: Environments. (line 38) +-* evc: Environments. (line 70) +-* ex: Debugging. (line 45) +-* fam: Font Families. (line 20) +-* fc: Fields. (line 18) +-* fchar: Using Symbols. (line 324) +-* fcolor: Colors. (line 80) +-* fi: Manipulating Filling and Adjusting. +- (line 28) +-* fl: Debugging. (line 87) +-* fp: Font Positions. (line 11) +-* fschar: Using Symbols. (line 325) +-* fspecial: Special Fonts. (line 18) +-* ft: Changing Fonts. (line 7) +-* ft <1>: Font Positions. (line 57) +-* ftr: Changing Fonts. (line 55) +-* fzoom: Changing Fonts. (line 70) +-* gcolor: Colors. (line 50) +-* hc: Manipulating Hyphenation. +- (line 105) +-* hcode: Manipulating Hyphenation. +- (line 175) +-* hla: Manipulating Hyphenation. +- (line 255) +-* hlm: Manipulating Hyphenation. +- (line 45) +-* hpf: Manipulating Hyphenation. +- (line 114) +-* hpfa: Manipulating Hyphenation. +- (line 115) +-* hpfcode: Manipulating Hyphenation. +- (line 116) +-* hw: Manipulating Hyphenation. +- (line 62) +-* hy: Manipulating Hyphenation. +- (line 9) +-* hym: Manipulating Hyphenation. +- (line 210) +-* hys: Manipulating Hyphenation. +- (line 226) +-* ie: if-else. (line 26) +-* if: if-else. (line 10) +-* ig: Comments. (line 63) +-* in: Line Layout. (line 86) +-* it: Input Line Traps. (line 7) +-* itc: Input Line Traps. (line 8) +-* kern: Ligatures and Kerning. +- (line 41) +-* lc: Leaders. (line 23) +-* length: Strings. (line 211) +-* lf: Debugging. (line 10) +-* lg: Ligatures and Kerning. +- (line 23) +-* linetabs: Tabs and Fields. (line 137) +-* ll: Line Layout. (line 140) +-* ls: Manipulating Spacing. +- (line 63) +-* lsm: Leading Spaces Traps. +- (line 7) +-* lt: Page Layout. (line 64) +-* mc: Miscellaneous. (line 75) +-* mk: Page Motions. (line 10) +-* mso: I/O. (line 40) +-* na: Manipulating Filling and Adjusting. +- (line 122) +-* ne: Page Control. (line 33) +-* nf: Manipulating Filling and Adjusting. +- (line 39) +-* nh: Manipulating Hyphenation. +- (line 37) +-* nm: Miscellaneous. (line 10) +-* nn: Miscellaneous. (line 71) +-* nop: if-else. (line 23) +-* nr: Setting Registers. (line 13) +-* nr <1>: Setting Registers. (line 68) +-* nr <2>: Auto-increment. (line 11) +-* nroff: Troff and Nroff Mode. +- (line 32) +-* ns: Manipulating Spacing. +- (line 121) +-* nx: I/O. (line 84) +-* open: I/O. (line 199) +-* opena: I/O. (line 200) +-* os: Page Control. (line 53) +-* output: Diversions. (line 180) +-* pc: Page Layout. (line 94) +-* pev: Debugging. (line 62) +-* pi: I/O. (line 143) +-* pl: Page Layout. (line 10) +-* pm: Debugging. (line 66) +-* pn: Page Layout. (line 81) +-* pnr: Debugging. (line 77) +-* po: Line Layout. (line 58) +-* ps: Changing Type Sizes. (line 7) +-* psbb: Miscellaneous. (line 135) +-* pso: I/O. (line 29) +-* ptr: Debugging. (line 81) +-* pvs: Changing Type Sizes. (line 134) +-* rchar: Using Symbols. (line 381) +-* rd: I/O. (line 89) +-* return: Writing Macros. (line 147) +-* rfschar: Using Symbols. (line 382) +-* rj: Manipulating Filling and Adjusting. +- (line 249) +-* rm: Strings. (line 224) +-* rn: Strings. (line 221) +-* rnn: Setting Registers. (line 108) +-* rr: Setting Registers. (line 104) +-* rs: Manipulating Spacing. +- (line 122) +-* rt: Page Motions. (line 11) +-* schar: Using Symbols. (line 326) +-* shc: Manipulating Hyphenation. +- (line 243) +-* shift: Parameters. (line 31) +-* sizes: Changing Type Sizes. (line 69) +-* so: I/O. (line 9) +-* sp: Manipulating Spacing. +- (line 7) +-* special: Special Fonts. (line 17) +-* spreadwarn: Debugging. (line 131) +-* ss: Manipulating Filling and Adjusting. +- (line 149) +-* sty: Font Families. (line 59) +-* substring: Strings. (line 192) +-* sv: Page Control. (line 52) +-* sy: I/O. (line 164) +-* ta: Tabs and Fields. (line 14) +-* tc: Tabs and Fields. (line 129) +-* ti: Line Layout. (line 112) +-* tkf: Ligatures and Kerning. +- (line 60) +-* tl: Page Layout. (line 35) +-* tm: Debugging. (line 25) +-* tm1: Debugging. (line 26) +-* tmc: Debugging. (line 27) +-* tr: Character Translations. +- (line 148) +-* trf: I/O. (line 49) +-* trin: Character Translations. +- (line 149) +-* trnt: Character Translations. +- (line 237) +-* troff: Troff and Nroff Mode. +- (line 24) +-* uf: Artificial Fonts. (line 90) +-* ul: Artificial Fonts. (line 64) +-* unformat: Diversions. (line 218) +-* vpt: Page Location Traps. (line 17) +-* vs: Changing Type Sizes. (line 85) +-* warn: Debugging. (line 154) +-* warnscale: Debugging. (line 127) +-* wh: Page Location Traps. (line 29) +-* while: while. (line 10) +-* write: I/O. (line 211) +-* writec: I/O. (line 212) +-* writem: I/O. (line 222) +- +- +-File: groff.info, Node: Escape Index, Next: Operator Index, Prev: Request Index, Up: Top +- +-Appendix C Escape Index +-*********************** +- +-Any escape sequence '\X' with X not in the list below emits a warning, +-printing glyph X. +- +-[index] +-* Menu: +- +-* \: Using Symbols. (line 132) +-* \!: Diversions. (line 135) +-* \": Comments. (line 10) +-* \#: Comments. (line 48) +-* \$: Parameters. (line 19) +-* \$*: Parameters. (line 40) +-* \$0: Parameters. (line 71) +-* \$@: Parameters. (line 41) +-* \$^: Parameters. (line 50) +-* \%: Manipulating Hyphenation. +- (line 84) +-* \&: Ligatures and Kerning. +- (line 100) +-* \': Using Symbols. (line 222) +-* \): Ligatures and Kerning. +- (line 127) +-* \*: Strings. (line 17) +-* \,: Ligatures and Kerning. +- (line 91) +-* \-: Using Symbols. (line 231) +-* \.: Character Translations. +- (line 122) +-* \/: Ligatures and Kerning. +- (line 80) +-* \0: Page Motions. (line 138) +-* \: Manipulating Hyphenation. +- (line 85) +-* \?: Diversions. (line 136) +-* \A: Identifiers. (line 53) +-* \a: Leaders. (line 18) +-* \B: Expressions. (line 83) +-* \b: Drawing Requests. (line 232) +-* \c: Line Control. (line 41) +-* \C: Using Symbols. (line 185) +-* \d: Page Motions. (line 100) +-* \D: Drawing Requests. (line 67) +-* \e: Character Translations. +- (line 69) +-* \E: Character Translations. +- (line 70) +-* \f: Changing Fonts. (line 8) +-* \F: Font Families. (line 22) +-* \f <1>: Font Positions. (line 58) +-* \g: Assigning Formats. (line 73) +-* \H: Artificial Fonts. (line 13) +-* \h: Page Motions. (line 103) +-* \k: Page Motions. (line 201) +-* \l: Drawing Requests. (line 16) +-* \L: Drawing Requests. (line 49) +-* \m: Colors. (line 51) +-* \M: Colors. (line 81) +-* \n: Interpolating Registers. +- (line 9) +-* \n <1>: Auto-increment. (line 19) +-* \N: Using Symbols. (line 201) +-* \o: Page Motions. (line 216) +-* \O: Suppressing output. (line 7) +-* \p: Manipulating Filling and Adjusting. +- (line 131) +-* \R: Setting Registers. (line 14) +-* \R <1>: Setting Registers. (line 70) +-* \r: Page Motions. (line 94) +-* \: Line Control. (line 40) +-* \S: Artificial Fonts. (line 44) +-* \s: Changing Type Sizes. (line 10) +-* \: Page Motions. (line 114) +-* \t: Tabs and Fields. (line 10) +-* \u: Page Motions. (line 97) +-* \v: Page Motions. (line 78) +-* \V: I/O. (line 247) +-* \w: Page Motions. (line 145) +-* \x: Manipulating Spacing. +- (line 82) +-* \X: Postprocessor Access. +- (line 12) +-* \Y: Postprocessor Access. +- (line 31) +-* \z: Page Motions. (line 220) +-* \Z: Page Motions. (line 224) +-* \\: Character Translations. +- (line 68) +-* \^: Page Motions. (line 130) +-* \_: Using Symbols. (line 234) +-* \`: Using Symbols. (line 227) +-* \{: if-else. (line 35) +-* \|: Page Motions. (line 122) +-* \}: if-else. (line 35) +-* \~: Page Motions. (line 118) +- +- +-File: groff.info, Node: Operator Index, Next: Register Index, Prev: Escape Index, Up: Top +- +-Appendix D Operator Index +-************************* +- +-[index] +-* Menu: +- +-* !: Expressions. (line 21) +-* %: Expressions. (line 8) +-* &: Expressions. (line 19) +-* (: Expressions. (line 59) +-* ): Expressions. (line 59) +-* *: Expressions. (line 8) +-* +: Expressions. (line 8) +-* + <1>: Expressions. (line 21) +-* -: Expressions. (line 8) +-* - <1>: Expressions. (line 21) +-* /: Expressions. (line 8) +-* <: Expressions. (line 15) +-* <=: Expressions. (line 15) +-* : Expressions. (line 19) +-* =: Expressions. (line 15) +-* ==: Expressions. (line 15) +-* >: Expressions. (line 15) +-* >=: Expressions. (line 15) +-* >?: Expressions. (line 44) +- +- +-File: groff.info, Node: Register Index, Next: Macro Index, Prev: Operator Index, Up: Top +- +-Appendix E Register Index +-************************* +- +-The macro package or program a specific register belongs to is appended +-in brackets. +- +- A register name 'x' consisting of exactly one character can be +-accessed as '\nx'. A register name 'xx' consisting of exactly two +-characters can be accessed as '\n(xx'. Register names 'xxx' of any +-length can be accessed as '\n[xxx]'. +- +-[index] +-* Menu: +- +-* $$: Built-in Registers. (line 99) +-* %: Page Layout. (line 94) +-* % <1>: Page Control. (line 10) +-* .$: Parameters. (line 10) +-* .A: Built-in Registers. (line 106) +-* .a: Manipulating Spacing. +- (line 83) +-* .b: Artificial Fonts. (line 98) +-* .br: Requests. (line 56) +-* .c: Built-in Registers. (line 76) +-* .C: Implementation Differences. +- (line 24) +-* .cdp: Environments. (line 94) +-* .ce: Manipulating Filling and Adjusting. +- (line 204) +-* .cht: Environments. (line 93) +-* .color: Colors. (line 8) +-* .csk: Environments. (line 95) +-* .d: Diversions. (line 69) +-* .ev: Environments. (line 39) +-* .F: Built-in Registers. (line 12) +-* .f: Font Positions. (line 12) +-* .fam: Font Families. (line 21) +-* .fn: Font Families. (line 25) +-* .fp: Font Positions. (line 13) +-* .g: Built-in Registers. (line 102) +-* .H: Built-in Registers. (line 15) +-* .h: Diversions. (line 76) +-* .height: Artificial Fonts. (line 16) +-* .hla: Manipulating Hyphenation. +- (line 256) +-* .hlc: Manipulating Hyphenation. +- (line 47) +-* .hlm: Manipulating Hyphenation. +- (line 46) +-* .hy: Manipulating Hyphenation. +- (line 10) +-* .hym: Manipulating Hyphenation. +- (line 211) +-* .hys: Manipulating Hyphenation. +- (line 227) +-* .i: Line Layout. (line 89) +-* .in: Line Layout. (line 115) +-* .int: Line Control. (line 42) +-* .j: Manipulating Filling and Adjusting. +- (line 51) +-* .k: Page Motions. (line 212) +-* .kern: Ligatures and Kerning. +- (line 42) +-* .L: Manipulating Spacing. +- (line 64) +-* .l: Line Layout. (line 143) +-* .lg: Ligatures and Kerning. +- (line 24) +-* .linetabs: Tabs and Fields. (line 138) +-* .ll: Line Layout. (line 144) +-* .lt: Page Layout. (line 67) +-* .m: Colors. (line 54) +-* .M: Colors. (line 84) +-* .n: Environments. (line 110) +-* .ne: Page Location Traps. (line 122) +-* .ns: Manipulating Spacing. +- (line 123) +-* .O: Built-in Registers. (line 112) +-* .o: Line Layout. (line 61) +-* .P: Built-in Registers. (line 116) +-* .p: Page Layout. (line 13) +-* .pe: Page Location Traps. (line 143) +-* .pn: Page Layout. (line 84) +-* .ps: Fractional Type Sizes. +- (line 37) +-* .psr: Fractional Type Sizes. +- (line 44) +-* .pvs: Changing Type Sizes. (line 137) +-* .R: Built-in Registers. (line 18) +-* .rj: Manipulating Filling and Adjusting. +- (line 250) +-* .s: Changing Type Sizes. (line 11) +-* .slant: Artificial Fonts. (line 45) +-* .sr: Fractional Type Sizes. +- (line 45) +-* .ss: Manipulating Filling and Adjusting. +- (line 150) +-* .sss: Manipulating Filling and Adjusting. +- (line 151) +-* .sty: Changing Fonts. (line 11) +-* .T: Built-in Registers. (line 122) +-* .t: Page Location Traps. (line 102) +-* .tabs: Tabs and Fields. (line 15) +-* .trunc: Page Location Traps. (line 131) +-* .U: Built-in Registers. (line 23) +-* .u: Manipulating Filling and Adjusting. +- (line 29) +-* .V: Built-in Registers. (line 28) +-* .v: Changing Type Sizes. (line 88) +-* .vpt: Page Location Traps. (line 18) +-* .w: Environments. (line 92) +-* .warn: Debugging. (line 155) +-* .x: Built-in Registers. (line 88) +-* .y: Built-in Registers. (line 92) +-* .Y: Built-in Registers. (line 96) +-* .z: Diversions. (line 68) +-* .zoom: Changing Fonts. (line 71) +-* c.: Built-in Registers. (line 77) +-* ct: Page Motions. (line 150) +-* DD [ms]: ms Document Control Registers. +- (line 239) +-* dl: Diversions. (line 93) +-* dn: Diversions. (line 92) +-* dw: Built-in Registers. (line 45) +-* dy: Built-in Registers. (line 48) +-* FAM [ms]: ms Document Control Registers. +- (line 111) +-* FF [ms]: ms Document Control Registers. +- (line 185) +-* FI [ms]: ms Document Control Registers. +- (line 178) +-* FL [ms]: ms Document Control Registers. +- (line 171) +-* FM [ms]: ms Document Control Registers. +- (line 47) +-* FPD [ms]: ms Document Control Registers. +- (line 221) +-* FPS [ms]: ms Document Control Registers. +- (line 205) +-* FVS [ms]: ms Document Control Registers. +- (line 213) +-* GROWPS [ms]: ms Document Control Registers. +- (line 89) +-* GS [ms]: Differences from AT&T ms. +- (line 45) +-* HM [ms]: ms Document Control Registers. +- (line 40) +-* HORPHANS [ms]: ms Document Control Registers. +- (line 155) +-* hours: Built-in Registers. (line 41) +-* hp: Page Motions. (line 209) +-* HY [ms]: ms Document Control Registers. +- (line 102) +-* LL [ms]: ms Document Control Registers. +- (line 25) +-* llx: Miscellaneous. (line 136) +-* lly: Miscellaneous. (line 137) +-* ln: Built-in Registers. (line 82) +-* lsn: Leading Spaces Traps. +- (line 8) +-* lss: Leading Spaces Traps. +- (line 9) +-* LT [ms]: ms Document Control Registers. +- (line 32) +-* MINGW [ms]: ms Document Control Registers. +- (line 231) +-* MINGW [ms] <1>: Additional ms Macros. +- (line 28) +-* minutes: Built-in Registers. (line 37) +-* mo: Built-in Registers. (line 51) +-* nl: Page Control. (line 67) +-* opmaxx: Suppressing output. (line 19) +-* opmaxy: Suppressing output. (line 19) +-* opminx: Suppressing output. (line 19) +-* opminy: Suppressing output. (line 19) +-* PD [ms]: ms Document Control Registers. +- (line 128) +-* PI [ms]: ms Document Control Registers. +- (line 121) +-* PO [ms]: ms Document Control Registers. +- (line 16) +-* PORPHANS [ms]: ms Document Control Registers. +- (line 143) +-* PS [ms]: ms Document Control Registers. +- (line 57) +-* ps4html [grohtml]: grohtml specific registers and strings. +- (line 7) +-* PSINCR [ms]: ms Document Control Registers. +- (line 77) +-* QI [ms]: ms Document Control Registers. +- (line 135) +-* rsb: Page Motions. (line 149) +-* rst: Page Motions. (line 148) +-* sb: Page Motions. (line 147) +-* seconds: Built-in Registers. (line 31) +-* skw: Page Motions. (line 152) +-* slimit: Debugging. (line 119) +-* ssc: Page Motions. (line 151) +-* st: Page Motions. (line 146) +-* systat: I/O. (line 165) +-* urx: Miscellaneous. (line 138) +-* ury: Miscellaneous. (line 139) +-* VS [ms]: ms Document Control Registers. +- (line 67) +-* year: Built-in Registers. (line 54) +-* yr: Built-in Registers. (line 57) +- +- +-File: groff.info, Node: Macro Index, Next: String Index, Prev: Register Index, Up: Top +- +-Appendix F Macro Index +-********************** +- +-The macro package a specific macro belongs to is appended in brackets. +-They appear without the leading control character (normally '.'). +- +-[index] +-* Menu: +- +-* 1C [ms]: ms Multiple Columns. (line 13) +-* 2C [ms]: ms Multiple Columns. (line 16) +-* [ [ms]: ms Insertions. (line 33) +-* ] [ms]: ms Insertions. (line 34) +-* AB [ms]: ms Cover Page Macros. +- (line 59) +-* AE [ms]: ms Cover Page Macros. +- (line 64) +-* AI [ms]: ms Cover Page Macros. +- (line 55) +-* AM [ms]: ms Strings and Special Characters. +- (line 51) +-* AM [ms] <1>: Additional ms Macros. +- (line 10) +-* AT [man]: Miscellaneous man macros. +- (line 27) +-* AU [ms]: ms Cover Page Macros. +- (line 39) +-* B [man]: Man font macros. (line 47) +-* B [ms]: Highlighting in ms. (line 10) +-* B1 [ms]: ms Displays and Keeps. +- (line 94) +-* B2 [ms]: ms Displays and Keeps. +- (line 95) +-* BD [ms]: ms Displays and Keeps. +- (line 31) +-* BI [man]: Man font macros. (line 18) +-* BI [ms]: Highlighting in ms. (line 38) +-* BR [man]: Man font macros. (line 39) +-* BT [man]: Optional man extensions. +- (line 21) +-* BT [ms]: ms Headers and Footers. +- (line 39) +-* BX [ms]: Highlighting in ms. (line 42) +-* CD [ms]: ms Displays and Keeps. +- (line 41) +-* CT [man]: Optional man extensions. +- (line 36) +-* CW [man]: Optional man extensions. +- (line 39) +-* CW [ms]: Highlighting in ms. (line 34) +-* CW [ms] <1>: Additional ms Macros. +- (line 19) +-* DA [ms]: ms Cover Page Macros. +- (line 24) +-* De [man]: Optional man extensions. +- (line 45) +-* DE [ms]: ms Displays and Keeps. +- (line 16) +-* DE [ms] <1>: ms Displays and Keeps. +- (line 24) +-* DE [ms] <2>: ms Displays and Keeps. +- (line 32) +-* DE [ms] <3>: ms Displays and Keeps. +- (line 42) +-* DE [ms] <4>: ms Displays and Keeps. +- (line 50) +-* De [ms]: ms Displays and Keeps. +- (line 57) +-* Ds [man]: Optional man extensions. +- (line 42) +-* DS [ms]: ms Displays and Keeps. +- (line 14) +-* DS [ms] <1>: ms Displays and Keeps. +- (line 22) +-* DS [ms] <2>: ms Displays and Keeps. +- (line 30) +-* DS [ms] <3>: ms Displays and Keeps. +- (line 40) +-* DS [ms] <4>: ms Displays and Keeps. +- (line 48) +-* Ds [ms]: ms Displays and Keeps. +- (line 56) +-* DS [ms] <5>: Additional ms Macros. +- (line 14) +-* DT [man]: Miscellaneous man macros. +- (line 10) +-* EE [man]: Optional man extensions. +- (line 52) +-* EF [ms]: ms Headers and Footers. +- (line 26) +-* EH [ms]: ms Headers and Footers. +- (line 24) +-* EN [ms]: ms Insertions. (line 28) +-* EQ [ms]: ms Insertions. (line 27) +-* EX [man]: Optional man extensions. +- (line 48) +-* FE [ms]: ms Footnotes. (line 15) +-* FS [ms]: ms Footnotes. (line 14) +-* G [man]: Optional man extensions. +- (line 55) +-* GL [man]: Optional man extensions. +- (line 60) +-* HB [man]: Optional man extensions. +- (line 65) +-* HD [ms]: ms Headers and Footers. +- (line 38) +-* HP [man]: Man usage. (line 98) +-* I [man]: Man font macros. (line 52) +-* I [ms]: Highlighting in ms. (line 30) +-* IB [man]: Man font macros. (line 27) +-* ID [ms]: ms Displays and Keeps. +- (line 23) +-* IP [man]: Man usage. (line 80) +-* IP [ms]: Lists in ms. (line 9) +-* IR [man]: Man font macros. (line 35) +-* IX [ms]: Additional ms Macros. +- (line 22) +-* KE [ms]: ms Displays and Keeps. +- (line 73) +-* KE [ms] <1>: ms Displays and Keeps. +- (line 78) +-* KF [ms]: ms Displays and Keeps. +- (line 77) +-* KS [ms]: ms Displays and Keeps. +- (line 72) +-* LD [ms]: ms Displays and Keeps. +- (line 15) +-* LG [ms]: Highlighting in ms. (line 51) +-* LP [man]: Man usage. (line 70) +-* LP [ms]: Paragraphs in ms. (line 12) +-* MC [ms]: ms Multiple Columns. (line 19) +-* MS [man]: Optional man extensions. +- (line 73) +-* ND [ms]: ms Cover Page Macros. +- (line 29) +-* NE [man]: Optional man extensions. +- (line 85) +-* NH [ms]: Headings in ms. (line 13) +-* NL [ms]: Highlighting in ms. (line 63) +-* NT [man]: Optional man extensions. +- (line 78) +-* OF [ms]: ms Headers and Footers. +- (line 25) +-* OH [ms]: ms Headers and Footers. +- (line 23) +-* P [man]: Man usage. (line 72) +-* P1 [ms]: ms Cover Page Macros. +- (line 20) +-* PD [man]: Miscellaneous man macros. +- (line 15) +-* PE [ms]: ms Insertions. (line 21) +-* PN [man]: Optional man extensions. +- (line 88) +-* Pn [man]: Optional man extensions. +- (line 92) +-* PP [man]: Man usage. (line 71) +-* PP [ms]: Paragraphs in ms. (line 9) +-* PS [ms]: ms Insertions. (line 20) +-* PT [man]: Optional man extensions. +- (line 16) +-* PT [ms]: ms Headers and Footers. +- (line 37) +-* PX [ms]: ms TOC. (line 62) +-* QP [ms]: Paragraphs in ms. (line 15) +-* R [man]: Optional man extensions. +- (line 98) +-* R [ms]: Highlighting in ms. (line 26) +-* RB [man]: Man font macros. (line 43) +-* RD [ms]: ms Displays and Keeps. +- (line 49) +-* RE [man]: Man usage. (line 115) +-* RE [ms]: Indentation values in ms. +- (line 12) +-* RI [man]: Man font macros. (line 31) +-* RN [man]: Optional man extensions. +- (line 101) +-* RP [ms]: ms Cover Page Macros. +- (line 10) +-* RS [man]: Man usage. (line 106) +-* RS [ms]: Indentation values in ms. +- (line 11) +-* SB [man]: Man font macros. (line 14) +-* SH [man]: Man usage. (line 34) +-* SH [ms]: Headings in ms. (line 54) +-* SM [man]: Man font macros. (line 10) +-* SM [ms]: Highlighting in ms. (line 57) +-* SS [man]: Man usage. (line 43) +-* TA [ms]: Tabstops in ms. (line 10) +-* TB [man]: Optional man extensions. +- (line 70) +-* TC [ms]: ms TOC. (line 52) +-* TE [ms]: ms Insertions. (line 12) +-* TH [man]: Man usage. (line 11) +-* TL [ms]: ms Cover Page Macros. +- (line 34) +-* TP [man]: Man usage. (line 51) +-* TS [ms]: ms Insertions. (line 11) +-* UC [man]: Miscellaneous man macros. +- (line 44) +-* UL [ms]: Highlighting in ms. (line 46) +-* VE [man]: Optional man extensions. +- (line 108) +-* VS [man]: Optional man extensions. +- (line 104) +-* XA [ms]: ms TOC. (line 13) +-* XE [ms]: ms TOC. (line 14) +-* XP [ms]: Paragraphs in ms. (line 20) +-* XS [ms]: ms TOC. (line 12) +- +- +-File: groff.info, Node: String Index, Next: Glyph Name Index, Prev: Macro Index, Up: Top +- +-Appendix G String Index +-*********************** +- +-The macro package or program a specific string belongs to is appended in +-brackets. +- +- A string name 'x' consisting of exactly one character can be accessed +-as '\*x'. A string name 'xx' consisting of exactly two characters can +-be accessed as '\*(xx'. String names 'xxx' of any length can be +-accessed as '\*[xxx]'. +- +-[index] +-* Menu: +- +-* ! [ms]: ms Strings and Special Characters. +- (line 101) +-* ' [ms]: ms Strings and Special Characters. +- (line 65) +-* * [ms]: ms Footnotes. (line 11) +-* , [ms]: ms Strings and Special Characters. +- (line 74) +-* - [ms]: ms Strings and Special Characters. +- (line 41) +-* . [ms]: ms Strings and Special Characters. +- (line 89) +-* .T: Built-in Registers. (line 127) +-* 3 [ms]: ms Strings and Special Characters. +- (line 107) +-* 8 [ms]: ms Strings and Special Characters. +- (line 104) +-* ? [ms]: ms Strings and Special Characters. +- (line 98) +-* \*[] [ms]: ms Strings and Special Characters. +- (line 80) +-* ^ [ms]: ms Strings and Special Characters. +- (line 71) +-* _ [ms]: ms Strings and Special Characters. +- (line 86) +-* ` [ms]: ms Strings and Special Characters. +- (line 68) +-* { [ms]: Highlighting in ms. (line 67) +-* } [ms]: Highlighting in ms. (line 68) +-* ~ [ms]: ms Strings and Special Characters. +- (line 77) +-* ABSTRACT [ms]: ms Strings and Special Characters. +- (line 15) +-* ae [ms]: ms Strings and Special Characters. +- (line 125) +-* Ae [ms]: ms Strings and Special Characters. +- (line 128) +-* CF [ms]: ms Headers and Footers. +- (line 16) +-* CH [ms]: ms Headers and Footers. +- (line 11) +-* D- [ms]: ms Strings and Special Characters. +- (line 116) +-* d- [ms]: ms Strings and Special Characters. +- (line 119) +-* HF [man]: Predefined man strings. +- (line 12) +-* LF [ms]: ms Headers and Footers. +- (line 15) +-* LH [ms]: ms Headers and Footers. +- (line 10) +-* lq [man]: Predefined man strings. +- (line 21) +-* MONTH1 [ms]: ms Strings and Special Characters. +- (line 23) +-* MONTH10 [ms]: ms Strings and Special Characters. +- (line 32) +-* MONTH11 [ms]: ms Strings and Special Characters. +- (line 33) +-* MONTH12 [ms]: ms Strings and Special Characters. +- (line 34) +-* MONTH2 [ms]: ms Strings and Special Characters. +- (line 24) +-* MONTH3 [ms]: ms Strings and Special Characters. +- (line 25) +-* MONTH4 [ms]: ms Strings and Special Characters. +- (line 26) +-* MONTH5 [ms]: ms Strings and Special Characters. +- (line 27) +-* MONTH6 [ms]: ms Strings and Special Characters. +- (line 28) +-* MONTH7 [ms]: ms Strings and Special Characters. +- (line 29) +-* MONTH8 [ms]: ms Strings and Special Characters. +- (line 30) +-* MONTH9 [ms]: ms Strings and Special Characters. +- (line 31) +-* o [ms]: ms Strings and Special Characters. +- (line 92) +-* Q [ms]: ms Strings and Special Characters. +- (line 44) +-* q [ms]: ms Strings and Special Characters. +- (line 122) +-* R [man]: Predefined man strings. +- (line 15) +-* REFERENCES [ms]: ms Strings and Special Characters. +- (line 11) +-* RF [ms]: ms Headers and Footers. +- (line 17) +-* RH [ms]: ms Headers and Footers. +- (line 12) +-* rq [man]: Predefined man strings. +- (line 22) +-* S [man]: Predefined man strings. +- (line 9) +-* SN [ms]: Headings in ms. (line 22) +-* SN-DOT [ms]: Headings in ms. (line 23) +-* SN-NO-DOT [ms]: Headings in ms. (line 24) +-* SN-STYLE [ms]: Headings in ms. (line 36) +-* Th [ms]: ms Strings and Special Characters. +- (line 110) +-* th [ms]: ms Strings and Special Characters. +- (line 113) +-* Tm [man]: Predefined man strings. +- (line 18) +-* TOC [ms]: ms Strings and Special Characters. +- (line 19) +-* U [ms]: ms Strings and Special Characters. +- (line 45) +-* v [ms]: ms Strings and Special Characters. +- (line 83) +-* www-image-template [grohtml]: grohtml specific registers and strings. +- (line 8) +- +- +-File: groff.info, Node: Glyph Name Index, Next: Font File Keyword Index, Prev: String Index, Up: Top +- +-Appendix H Glyph Name Index +-*************************** +- +-A glyph name 'xx' consisting of exactly two characters can be accessed +-as '\(xx'. Glyph names 'xxx' of any length can be accessed as '\[xxx]'. +- +- +-File: groff.info, Node: Font File Keyword Index, Next: Program and File Index, Prev: Glyph Name Index, Up: Top +- +-Appendix I Font File Keyword Index +-********************************** +- +-[index] +-* Menu: +- +-* #: Font File Format. (line 36) +-* ---: Font File Format. (line 51) +-* biggestfont: DESC File Format. (line 142) +-* charset: DESC File Format. (line 12) +-* charset <1>: Font File Format. (line 44) +-* family: Changing Fonts. (line 11) +-* family <1>: Font Positions. (line 60) +-* family <2>: DESC File Format. (line 16) +-* fonts: Using Symbols. (line 14) +-* fonts <1>: Special Fonts. (line 18) +-* fonts <2>: DESC File Format. (line 19) +-* hor: DESC File Format. (line 25) +-* image_generator: DESC File Format. (line 29) +-* kernpairs: Font File Format. (line 139) +-* ligatures: Font File Format. (line 22) +-* name: Font File Format. (line 12) +-* paperlength: DESC File Format. (line 35) +-* papersize: DESC File Format. (line 40) +-* paperwidth: DESC File Format. (line 59) +-* pass_filenames: DESC File Format. (line 64) +-* postpro: DESC File Format. (line 69) +-* prepro: DESC File Format. (line 77) +-* print: DESC File Format. (line 81) +-* res: DESC File Format. (line 85) +-* sizes: DESC File Format. (line 88) +-* sizescale: DESC File Format. (line 95) +-* slant: Font File Format. (line 18) +-* spacewidth: Font File Format. (line 15) +-* spare1: DESC File Format. (line 142) +-* spare2: DESC File Format. (line 142) +-* special: Artificial Fonts. (line 115) +-* special <1>: Font File Format. (line 28) +-* styles: Changing Fonts. (line 11) +-* styles <1>: Font Families. (line 75) +-* styles <2>: Font Positions. (line 60) +-* styles <3>: DESC File Format. (line 101) +-* tcommand: DESC File Format. (line 104) +-* unicode: DESC File Format. (line 108) +-* unitwidth: DESC File Format. (line 122) +-* unscaled_charwidths: DESC File Format. (line 126) +-* use_charnames_in_special: Postprocessor Access. +- (line 22) +-* use_charnames_in_special <1>: DESC File Format. (line 130) +-* vert: DESC File Format. (line 135) +- +- +-File: groff.info, Node: Program and File Index, Next: Concept Index, Prev: Font File Keyword Index, Up: Top +- +-Appendix J Program and File Index +-********************************* +- +-[index] +-* Menu: +- +-* an.tmac: man. (line 6) +-* changebar: Miscellaneous. (line 108) +-* composite.tmac: Using Symbols. (line 191) +-* cp1047.tmac: Input Encodings. (line 9) +-* DESC: Changing Fonts. (line 11) +-* DESC <1>: Font Families. (line 75) +-* DESC <2>: Font Positions. (line 60) +-* DESC <3>: Using Symbols. (line 14) +-* DESC <4>: Using Symbols. (line 212) +-* DESC <5>: Special Fonts. (line 18) +-* DESC file format: DESC File Format. (line 6) +-* DESC, and font mounting: Font Positions. (line 36) +-* DESC, and 'use_charnames_in_special': Postprocessor Access. +- (line 22) +-* ditroff: History. (line 59) +-* ec.tmac: Input Encodings. (line 46) +-* eqn: ms Insertions. (line 7) +-* freeeuro.pfa: Input Encodings. (line 46) +-* gchem: Groff Options. (line 6) +-* geqn: Groff Options. (line 6) +-* geqn, invocation in manual pages: Preprocessors in man pages. +- (line 11) +-* ggrn: Groff Options. (line 6) +-* gpic: Groff Options. (line 6) +-* grap: Groff Options. (line 6) +-* grefer: Groff Options. (line 6) +-* grefer, invocation in manual pages: Preprocessors in man pages. +- (line 11) +-* groff: Groff Options. (line 6) +-* grog: grog. (line 6) +-* grohtml: Miscellaneous man macros. +- (line 6) +-* gsoelim: Groff Options. (line 6) +-* gtbl: Groff Options. (line 6) +-* gtbl, invocation in manual pages: Preprocessors in man pages. +- (line 11) +-* gtroff: Groff Options. (line 6) +-* hyphen.us: Manipulating Hyphenation. +- (line 162) +-* hyphenex.us: Manipulating Hyphenation. +- (line 162) +-* latin1.tmac: Input Encodings. (line 14) +-* latin2.tmac: Input Encodings. (line 18) +-* latin2.tmac <1>: Input Encodings. (line 23) +-* latin9.tmac: Input Encodings. (line 28) +-* less: Invoking grotty. (line 50) +-* makeindex: Indices. (line 10) +-* man, invocation of preprocessors: Preprocessors in man pages. +- (line 11) +-* man-old.tmac: man. (line 6) +-* man.local: Man usage. (line 6) +-* man.local <1>: Optional man extensions. +- (line 6) +-* man.tmac: man. (line 6) +-* man.ultrix: Optional man extensions. +- (line 30) +-* nrchbar: Miscellaneous. (line 108) +-* papersize.tmac: Paper Size. (line 16) +-* perl: I/O. (line 175) +-* pic: ms Insertions. (line 7) +-* post-grohtml: Groff Options. (line 275) +-* pre-grohtml: Groff Options. (line 275) +-* preconv: Groff Options. (line 6) +-* refer: ms Insertions. (line 7) +-* soelim: Debugging. (line 10) +-* tbl: ms Insertions. (line 7) +-* trace.tmac: Writing Macros. (line 104) +-* trace.tmac <1>: Writing Macros. (line 136) +-* troffrc: Groff Options. (line 206) +-* troffrc <1>: Paper Size. (line 16) +-* troffrc <2>: Manipulating Hyphenation. +- (line 162) +-* troffrc <3>: Manipulating Hyphenation. +- (line 256) +-* troffrc <4>: Troff and Nroff Mode. +- (line 24) +-* troffrc <5>: Line Layout. (line 61) +-* troffrc-end: Groff Options. (line 206) +-* troffrc-end <1>: Manipulating Hyphenation. +- (line 162) +-* troffrc-end <2>: Manipulating Hyphenation. +- (line 256) +-* troffrc-end <3>: Troff and Nroff Mode. +- (line 24) +-* tty.tmac: Troff and Nroff Mode. +- (line 32) +- +- +-File: groff.info, Node: Concept Index, Prev: Program and File Index, Up: Top +- +-Appendix K Concept Index +-************************ +- +-[index] +-* Menu: +- +-* '"', at end of sentence: Sentences. (line 18) +-* '"', at end of sentence <1>: Using Symbols. (line 275) +-* '"', in a macro argument: Request and Macro Arguments. +- (line 25) +-* '%', as delimiter: Escapes. (line 67) +-* '&', as delimiter: Escapes. (line 67) +-* ''', as a comment: Comments. (line 42) +-* ''', at end of sentence: Sentences. (line 18) +-* ''', at end of sentence <1>: Using Symbols. (line 275) +-* ''', delimiting arguments: Escapes. (line 29) +-* '(', as delimiter: Escapes. (line 67) +-* '(', starting a two-character identifier: Identifiers. (line 73) +-* '(', starting a two-character identifier <1>: Escapes. (line 16) +-* ')', as delimiter: Escapes. (line 67) +-* ')', at end of sentence: Sentences. (line 18) +-* ')', at end of sentence <1>: Using Symbols. (line 275) +-* '*', as delimiter: Escapes. (line 67) +-* '*', at end of sentence: Sentences. (line 18) +-* '*', at end of sentence <1>: Using Symbols. (line 275) +-* '+', and page motion: Expressions. (line 65) +-* '+', as delimiter: Escapes. (line 67) +-* '-', and page motion: Expressions. (line 65) +-* '-', as delimiter: Escapes. (line 67) +-* '.', as delimiter: Escapes. (line 67) +-* '.h' register, difference to 'nl': Diversions. (line 88) +-* '.ps' register, in comparison with '.psr': Fractional Type Sizes. +- (line 45) +-* '.s' register, in comparison with '.sr': Fractional Type Sizes. +- (line 45) +-* '.S' register, Plan 9 alias for '.tabs': Tabs and Fields. (line 125) +-* '.t' register, and diversions: Diversion Traps. (line 7) +-* '.tabs' register, Plan 9 alias ('.S'): Tabs and Fields. (line 125) +-* '.V' register, and 'vs': Changing Type Sizes. (line 94) +-* '/', as delimiter: Escapes. (line 67) +-* 8-bit input: Font File Format. (line 51) +-* '<', as delimiter: Escapes. (line 67) +-* , as delimiter: Escapes. (line 67) +-* '=', as delimiter: Escapes. (line 67) +-* '>', as delimiter: Escapes. (line 67) +-* '[', macro names starting with, and 'refer': Identifiers. (line 46) +-* '[', starting an identifier: Identifiers. (line 75) +-* '[', starting an identifier <1>: Escapes. (line 20) +-* '\!', and copy-in mode: Diversions. (line 148) +-* '\!', and 'output' request: Diversions. (line 179) +-* '\!', and 'trnt': Character Translations. +- (line 237) +-* '\!', in top-level diversion: Diversions. (line 171) +-* '\!', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\!', incompatibilities with AT&T 'troff' <1>: Implementation Differences. +- (line 106) +-* '\!', used as delimiter: Escapes. (line 52) +-* '\!', used as delimiter <1>: Escapes. (line 71) +-* '\$', when reading text for a macro: Copy-in Mode. (line 6) +-* '\%', and translations: Character Translations. +- (line 166) +-* '\%', following '\X' or '\Y': Manipulating Hyphenation. +- (line 98) +-* '\%', in '\X': Postprocessor Access. +- (line 14) +-* '\%', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\%', used as delimiter: Escapes. (line 52) +-* '\%', used as delimiter <1>: Escapes. (line 71) +-* '\&', and glyph definitions: Using Symbols. (line 326) +-* '\&', and translations: Character Translations. +- (line 176) +-* '\&', at end of sentence: Sentences. (line 24) +-* '\&', escaping control characters: Requests. (line 47) +-* '\&', in '\X': Postprocessor Access. +- (line 14) +-* '\&', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\&', used as delimiter: Escapes. (line 52) +-* '\'', and translations: Character Translations. +- (line 160) +-* '\'', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\'', used as delimiter: Escapes. (line 52) +-* '\'', used as delimiter <1>: Escapes. (line 71) +-* '\(', and translations: Character Translations. +- (line 160) +-* '\)', in '\X': Postprocessor Access. +- (line 14) +-* '\)', used as delimiter: Escapes. (line 52) +-* '\*', and warnings: Warnings. (line 54) +-* '\*', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 13) +-* '\*', when reading text for a macro: Copy-in Mode. (line 6) +-* '\', disabling ('eo'): Character Translations. +- (line 24) +-* '\,', used as delimiter: Escapes. (line 52) +-* '\-', and translations: Character Translations. +- (line 160) +-* '\-', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\-', used as delimiter: Escapes. (line 52) +-* '\-', used as delimiter <1>: Escapes. (line 71) +-* '\/', used as delimiter: Escapes. (line 52) +-* '\/', used as delimiter <1>: Escapes. (line 71) +-* '\0', used as delimiter: Escapes. (line 52) +-* '\', in '\X': Postprocessor Access. +- (line 14) +-* '\', used as delimiter: Escapes. (line 52) +-* '\', used as delimiter <1>: Escapes. (line 71) +-* '\?', and copy-in mode: Operators in Conditionals. +- (line 55) +-* '\?', and copy-in mode <1>: Diversions. (line 148) +-* '\?', in top-level diversion: Diversions. (line 176) +-* '\?', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 106) +-* '\?', used as delimiter: Escapes. (line 52) +-* '\A', allowed delimiters: Escapes. (line 59) +-* '\a', and copy-in mode: Leaders. (line 18) +-* '\a', and translations: Character Translations. +- (line 169) +-* '\A', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\a', used as delimiter: Escapes. (line 52) +-* '\B', allowed delimiters: Escapes. (line 59) +-* '\b', limitations: Drawing Requests. (line 239) +-* '\b', possible quote characters: Escapes. (line 37) +-* '\C', allowed delimiters: Escapes. (line 59) +-* '\c', and fill mode: Line Control. (line 69) +-* '\c', and no-fill mode: Line Control. (line 60) +-* '\C', and translations: Character Translations. +- (line 160) +-* '\c', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\c', used as delimiter: Escapes. (line 52) +-* '\c', used as delimiter <1>: Escapes. (line 71) +-* '\D'f ...'' and horizontal resolution: Drawing Requests. (line 151) +-* '\D', allowed delimiters: Escapes. (line 62) +-* '\d', used as delimiter: Escapes. (line 52) +-* '\E', and copy-in mode: Character Translations. +- (line 81) +-* '\e', and glyph definitions: Using Symbols. (line 326) +-* '\e', and translations: Character Translations. +- (line 164) +-* '\e', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 106) +-* '\e', used as delimiter: Escapes. (line 52) +-* '\E', used as delimiter: Escapes. (line 52) +-* '\e', used as delimiter <1>: Escapes. (line 71) +-* '\F', and changing fonts: Changing Fonts. (line 11) +-* '\F', and font positions: Font Positions. (line 60) +-* '\f', and font translations: Changing Fonts. (line 55) +-* '\f', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 56) +-* '\h', allowed delimiters: Escapes. (line 62) +-* '\H', allowed delimiters: Escapes. (line 62) +-* '\H', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 56) +-* '\H', using '+' and '-': Expressions. (line 75) +-* '\H', with fractional type sizes: Fractional Type Sizes. +- (line 6) +-* '\l', allowed delimiters: Escapes. (line 62) +-* '\L', allowed delimiters: Escapes. (line 62) +-* '\l', and glyph definitions: Using Symbols. (line 326) +-* '\L', and glyph definitions: Using Symbols. (line 326) +-* '\N', allowed delimiters: Escapes. (line 62) +-* '\N', and translations: Character Translations. +- (line 160) +-* '\n', and warnings: Warnings. (line 61) +-* '\n', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 13) +-* '\n', when reading text for a macro: Copy-in Mode. (line 6) +-* '\o', possible quote characters: Escapes. (line 37) +-* '\p', used as delimiter: Escapes. (line 52) +-* '\p', used as delimiter <1>: Escapes. (line 71) +-* '\R', after '\c': Line Control. (line 52) +-* '\R', allowed delimiters: Escapes. (line 62) +-* '\R', and warnings: Warnings. (line 61) +-* '\R', difference to 'nr': Auto-increment. (line 11) +-* '\r', used as delimiter: Escapes. (line 52) +-* '\R', using '+' and '-': Expressions. (line 75) +-* \, when reading text for a macro: Copy-in Mode. (line 6) +-* '\s', allowed delimiters: Escapes. (line 62) +-* '\S', allowed delimiters: Escapes. (line 62) +-* '\s', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 56) +-* '\S', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 56) +-* '\s', using '+' and '-': Expressions. (line 75) +-* '\s', with fractional type sizes: Fractional Type Sizes. +- (line 6) +-* '\', difference to '\~': Request and Macro Arguments. +- (line 20) +-* '\', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\', used as delimiter: Escapes. (line 52) +-* '\t', and copy-in mode: Tabs and Fields. (line 10) +-* '\t', and translations: Character Translations. +- (line 169) +-* '\t', and warnings: Warnings. (line 69) +-* '\t', used as delimiter: Escapes. (line 52) +-* '\u', used as delimiter: Escapes. (line 52) +-* '\v', allowed delimiters: Escapes. (line 62) +-* '\V', and copy-in mode: I/O. (line 249) +-* '\v', internal representation: Gtroff Internals. (line 54) +-* '\w', allowed delimiters: Escapes. (line 59) +-* '\x', allowed delimiters: Escapes. (line 62) +-* '\X', and special characters: Postprocessor Access. +- (line 22) +-* '\X', followed by '\%': Manipulating Hyphenation. +- (line 98) +-* '\X', possible quote characters: Escapes. (line 37) +-* '\Y', followed by '\%': Manipulating Hyphenation. +- (line 98) +-* '\Z', allowed delimiters: Escapes. (line 59) +-* '\[', and translations: Character Translations. +- (line 160) +-* '\\', when reading text for a macro: Copy-in Mode. (line 6) +-* '\^', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\^', used as delimiter: Escapes. (line 52) +-* '\_', and translations: Character Translations. +- (line 160) +-* '\_', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\_', used as delimiter: Escapes. (line 52) +-* '\_', used as delimiter <1>: Escapes. (line 71) +-* '\`', and translations: Character Translations. +- (line 160) +-* '\`', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\`', used as delimiter: Escapes. (line 52) +-* '\`', used as delimiter <1>: Escapes. (line 71) +-* '\{', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\{', used as delimiter: Escapes. (line 52) +-* '\{', used as delimiter <1>: Escapes. (line 71) +-* '\|', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\|', used as delimiter: Escapes. (line 52) +-* '\}', and warnings: Warnings. (line 73) +-* '\}', incompatibilities with AT&T 'troff': Implementation Differences. +- (line 69) +-* '\}', used as delimiter: Escapes. (line 52) +-* '\}', used as delimiter <1>: Escapes. (line 71) +-* '\~', and translations: Character Translations. +- (line 166) +-* '\~', difference to '\': Request and Macro Arguments. +- (line 20) +-* '\~', used as delimiter: Escapes. (line 52) +-* ']', as part of an identifier: Identifiers. (line 41) +-* ']', at end of sentence: Sentences. (line 18) +-* ']', at end of sentence <1>: Using Symbols. (line 275) +-* ']', ending an identifier: Identifiers. (line 75) +-* ']', ending an identifier <1>: Escapes. (line 20) +-* ']', macro names starting with, and 'refer': Identifiers. (line 46) +-* '|', and page motion: Expressions. (line 70) +-* aborting ('ab'): Debugging. (line 40) +-* absolute position operator ('|'): Expressions. (line 70) +-* accent marks ['ms']: ms Strings and Special Characters. +- (line 6) +-* access of postprocessor: Postprocessor Access. +- (line 6) +-* accessing unnamed glyphs with '\N': Font File Format. (line 51) +-* activating kerning ('kern'): Ligatures and Kerning. +- (line 42) +-* activating ligatures ('lg'): Ligatures and Kerning. +- (line 24) +-* activating track kerning ('tkf'): Ligatures and Kerning. +- (line 60) +-* 'ad' request, and hyphenation margin: Manipulating Hyphenation. +- (line 211) +-* 'ad' request, and hyphenation space: Manipulating Hyphenation. +- (line 227) +-* adjusting: Filling and Adjusting. +- (line 6) +-* adjusting and filling, manipulating: Manipulating Filling and Adjusting. +- (line 6) +-* adjustment mode register ('.j'): Manipulating Filling and Adjusting. +- (line 114) +-* adobe glyph list (AGL): Using Symbols. (line 88) +-* AGL (adobe glyph list): Using Symbols. (line 88) +-* alias, diversion, creating ('als'): Strings. (line 229) +-* alias, diversion, removing ('rm'): Strings. (line 263) +-* alias, macro, creating ('als'): Strings. (line 229) +-* alias, macro, removing ('rm'): Strings. (line 263) +-* alias, number register, creating ('aln'): Setting Registers. +- (line 112) +-* alias, string, creating ('als'): Strings. (line 229) +-* alias, string, removing ('rm'): Strings. (line 263) +-* 'als' request, and '\$0': Parameters. (line 71) +-* 'am', 'am1', 'ami' requests, and warnings: Warnings. (line 54) +-* annotations: Footnotes and Annotations. +- (line 6) +-* appending to a diversion ('da'): Diversions. (line 22) +-* appending to a file ('opena'): I/O. (line 200) +-* appending to a macro ('am'): Writing Macros. (line 116) +-* appending to a string ('as'): Strings. (line 176) +-* arc, drawing ('\D'a ...''): Drawing Requests. (line 128) +-* argument delimiting characters: Escapes. (line 29) +-* arguments to macros, and tabs: Request and Macro Arguments. +- (line 6) +-* arguments to requests and macros: Request and Macro Arguments. +- (line 6) +-* arguments, and compatibility mode: Gtroff Internals. (line 91) +-* arguments, macro ('\$'): Parameters. (line 21) +-* arguments, of strings: Strings. (line 19) +-* arithmetic operators: Expressions. (line 8) +-* artificial fonts: Artificial Fonts. (line 6) +-* 'as', 'as1' requests, and comments: Comments. (line 16) +-* 'as', 'as1' requests, and warnings: Warnings. (line 54) +-* ASCII approximation output register ('.A'): Groff Options. (line 51) +-* ASCII approximation output register ('.A') <1>: Built-in Registers. +- (line 106) +-* ASCII, output encoding: Groff Options. (line 250) +-* 'asciify' request, and 'writem': I/O. (line 222) +-* assigning formats ('af'): Assigning Formats. (line 6) +-* assignments, indirect: Interpolating Registers. +- (line 11) +-* assignments, nested: Interpolating Registers. +- (line 11) +-* AT&T 'troff', 'ms' macro package differences: Differences from AT&T ms. +- (line 6) +-* auto-increment: Auto-increment. (line 6) +-* auto-increment, and 'ig' request: Comments. (line 85) +-* available glyphs, list ('groff_char(7)' man page): Using Symbols. +- (line 76) +-* background color name register ('.M'): Colors. (line 94) +-* backslash, printing ('\\', '\e', '\E', '\[rs]'): Escapes. (line 74) +-* backslash, printing ('\\', '\e', '\E', '\[rs]') <1>: Implementation Differences. +- (line 106) +-* backspace character: Identifiers. (line 12) +-* backspace character, and translations: Character Translations. +- (line 169) +-* backtrace of input stack ('backtrace'): Debugging. (line 96) +-* baseline: Sizes. (line 6) +-* basic unit ('u'): Measurements. (line 6) +-* basics of macros: Basics. (line 6) +-* 'bd' request, and font styles: Font Families. (line 59) +-* 'bd' request, and font translations: Changing Fonts. (line 55) +-* 'bd' request, incompatibilities with AT&T 'troff': Implementation Differences. +- (line 86) +-* begin of conditional block ('\{'): if-else. (line 35) +-* beginning diversion ('di'): Diversions. (line 22) +-* blank line: Implicit Line Breaks. +- (line 10) +-* blank line <1>: Requests. (line 27) +-* blank line ('sp'): Basics. (line 93) +-* blank line macro ('blm'): Implicit Line Breaks. +- (line 10) +-* blank line macro ('blm') <1>: Requests. (line 27) +-* blank line macro ('blm') <2>: Blank Line Traps. (line 7) +-* blank line traps: Blank Line Traps. (line 6) +-* blank lines, disabling: Manipulating Spacing. +- (line 123) +-* block, conditional, begin ('\{'): if-else. (line 35) +-* block, condititional, end ('\}'): if-else. (line 35) +-* bold face ['man']: Man font macros. (line 14) +-* bold face, imitating ('bd'): Artificial Fonts. (line 98) +-* bottom margin: Page Layout. (line 20) +-* bounding box: Miscellaneous. (line 139) +-* box rule glyph ('\[br]'): Drawing Requests. (line 50) +-* 'box', 'boxa' requests, and warnings: Warnings. (line 54) +-* 'boxa' request, and 'dn' ('dl'): Diversions. (line 93) +-* 'bp' request, and top-level diversion: Page Control. (line 24) +-* 'bp' request, and traps ('.pe'): Page Location Traps. (line 143) +-* 'bp' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* 'bp' request, using '+' and '-': Expressions. (line 75) +-* 'br' glyph, and 'cflags': Using Symbols. (line 271) +-* break: Basics. (line 48) +-* break <1>: Manipulating Filling and Adjusting. +- (line 6) +-* break ('br'): Basics. (line 118) +-* 'break' request, in a 'while' loop: while. (line 68) +-* break, implicit: Implicit Line Breaks. +- (line 6) +-* built-in registers: Built-in Registers. (line 6) +-* bulleted list, example markup ['ms']: Lists in ms. (line 21) +-* 'c' unit: Measurements. (line 27) +-* calling convention of preprocessors: Preprocessors in man pages. +- (line 6) +-* capabilities of 'groff': groff Capabilities. (line 6) +-* 'ce' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* 'ce' request, difference to '.ad c': Manipulating Filling and Adjusting. +- (line 66) +-* centered text: Manipulating Filling and Adjusting. +- (line 66) +-* centering lines ('ce'): Basics. (line 105) +-* centering lines ('ce') <1>: Manipulating Filling and Adjusting. +- (line 204) +-* centimeter unit ('c'): Measurements. (line 27) +-* 'cf' request, and copy-in mode: I/O. (line 50) +-* 'cf' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* changing font family ('fam', '\F'): Font Families. (line 25) +-* changing font position ('\f'): Font Positions. (line 60) +-* changing font style ('sty'): Font Families. (line 59) +-* changing fonts ('ft', '\f'): Changing Fonts. (line 11) +-* changing format, and read-only registers: Assigning Formats. +- (line 68) +-* changing the font height ('\H'): Artificial Fonts. (line 16) +-* changing the font slant ('\S'): Artificial Fonts. (line 45) +-* changing the page number character ('pc'): Page Layout. (line 94) +-* changing trap location ('ch'): Page Location Traps. (line 111) +-* changing type sizes ('ps', '\s'): Changing Type Sizes. (line 11) +-* changing vertical line spacing ('vs'): Changing Type Sizes. (line 88) +-* 'char' request, and soft hyphen character: Manipulating Hyphenation. +- (line 243) +-* 'char' request, and translations: Character Translations. +- (line 160) +-* 'char' request, used with '\N': Using Symbols. (line 201) +-* character: Using Symbols. (line 6) +-* character class ('class'): Character Classes. (line 12) +-* character classes: Character Classes. (line 6) +-* character properties ('cflags'): Using Symbols. (line 237) +-* character translations: Character Translations. +- (line 6) +-* character, backspace: Identifiers. (line 12) +-* character, backspace, and translations: Character Translations. +- (line 169) +-* character, control ('.'): Requests. (line 6) +-* character, control, changing ('cc'): Character Translations. +- (line 6) +-* character, defining ('char'): Using Symbols. (line 326) +-* character, defining fallback ('fchar', 'fschar', 'schar'): Using Symbols. +- (line 326) +-* character, escape, changing ('ec'): Character Translations. +- (line 47) +-* character, escape, while defining glyph: Using Symbols. (line 326) +-* character, field delimiting ('fc'): Fields. (line 6) +-* character, field padding ('fc'): Fields. (line 6) +-* character, hyphenation ('\%'): Manipulating Hyphenation. +- (line 85) +-* character, leader repetition ('lc'): Leaders. (line 23) +-* character, leader, and translations: Character Translations. +- (line 169) +-* character, leader, non-interpreted ('\a'): Leaders. (line 18) +-* character, named ('\C'): Using Symbols. (line 185) +-* character, newline: Escapes. (line 69) +-* character, newline, and translations: Character Translations. +- (line 169) +-* character, no-break control ('''): Requests. (line 6) +-* character, no-break control, changing ('c2'): Character Translations. +- (line 6) +-* character, soft hyphen, setting ('shc'): Manipulating Hyphenation. +- (line 243) +-* character, space: Escapes. (line 69) +-* character, special: Character Translations. +- (line 160) +-* character, tab: Escapes. (line 69) +-* character, tab repetition ('tc'): Tabs and Fields. (line 129) +-* character, tab, and translations: Character Translations. +- (line 169) +-* character, tab, non-interpreted ('\t'): Tabs and Fields. (line 10) +-* character, tabulator: Tab Stops. (line 6) +-* character, transparent: Sentences. (line 18) +-* character, transparent <1>: Using Symbols. (line 275) +-* character, whitespace: Identifiers. (line 10) +-* character, zero width space ('\&'): Requests. (line 47) +-* character, zero width space ('\&') <1>: Ligatures and Kerning. +- (line 47) +-* character, zero width space ('\&') <2>: Drawing Requests. (line 32) +-* characters, argument delimiting: Escapes. (line 29) +-* characters, end-of-sentence: Using Symbols. (line 247) +-* characters, hyphenation: Using Symbols. (line 251) +-* characters, input, and output glyphs, compatibility with AT&T 'troff': Implementation Differences. +- (line 86) +-* characters, invalid for 'trf' request: I/O. (line 73) +-* characters, invalid input: Identifiers. (line 15) +-* characters, overlapping: Using Symbols. (line 265) +-* characters, special: Special Characters. (line 6) +-* characters, unnamed, accessing with '\N': Font File Format. (line 51) +-* 'chem', the program: gchem. (line 6) +-* circle, drawing ('\D'c ...''): Drawing Requests. (line 109) +-* circle, solid, drawing ('\D'C ...''): Drawing Requests. (line 114) +-* class of characters ('class'): Character Classes. (line 12) +-* classes, character: Character Classes. (line 6) +-* closing file ('close'): I/O. (line 231) +-* code, hyphenation ('hcode'): Manipulating Hyphenation. +- (line 175) +-* color name, background, register ('.M'): Colors. (line 94) +-* color name, drawing, register ('.m'): Colors. (line 67) +-* color name, fill, register ('.M'): Colors. (line 94) +-* color, default: Colors. (line 26) +-* colors: Colors. (line 6) +-* colors, fill, unnamed ('\D'F...''): Drawing Requests. (line 216) +-* command prefix: Environment. (line 14) +-* command-line options: Groff Options. (line 50) +-* commands, embedded: Embedded Commands. (line 6) +-* comments: Comments. (line 6) +-* comments in font files: Font File Format. (line 36) +-* comments, lining up with tabs: Comments. (line 21) +-* comments, with 'ds': Strings. (line 45) +-* common features: Common Features. (line 6) +-* common name space of macros, diversions, and strings: Strings. +- (line 92) +-* comparison of strings: Operators in Conditionals. +- (line 47) +-* comparison operators: Expressions. (line 15) +-* compatibility mode: Warnings. (line 91) +-* compatibility mode <1>: Implementation Differences. +- (line 6) +-* compatibility mode, and parameters: Gtroff Internals. (line 91) +-* composite glyph names: Using Symbols. (line 88) +-* conditional block, begin ('\{'): if-else. (line 35) +-* conditional block, end ('\}'): if-else. (line 35) +-* conditional output for terminal (TTY): Operators in Conditionals. +- (line 14) +-* conditional page break ('ne'): Page Control. (line 33) +-* conditionals and loops: Conditionals and Loops. +- (line 6) +-* consecutive hyphenated lines ('hlm'): Manipulating Hyphenation. +- (line 47) +-* constant glyph space mode ('cs'): Artificial Fonts. (line 126) +-* contents, table of: Table of Contents. (line 6) +-* contents, table of <1>: Leaders. (line 29) +-* continuation, input line ('\'): Line Control. (line 36) +-* continuation, output line ('\c'): Line Control. (line 36) +-* 'continue' request, in a 'while' loop: while. (line 68) +-* continuous underlining ('cu'): Artificial Fonts. (line 86) +-* control character ('.'): Requests. (line 6) +-* control character, changing ('cc'): Character Translations. +- (line 6) +-* control character, no-break ('''): Requests. (line 6) +-* control character, no-break, changing ('c2'): Character Translations. +- (line 6) +-* control sequences, for terminals: Invoking grotty. (line 50) +-* control, line: Line Control. (line 6) +-* control, page: Page Control. (line 6) +-* conventions for input: Input Conventions. (line 6) +-* copy mode: Copy-in Mode. (line 6) +-* copy-in mode: Copy-in Mode. (line 6) +-* copy-in mode, and 'cf' request: I/O. (line 50) +-* copy-in mode, and 'device' request: Postprocessor Access. +- (line 19) +-* copy-in mode, and 'ig' request: Comments. (line 85) +-* copy-in mode, and 'length' request: Strings. (line 211) +-* copy-in mode, and macro arguments: Parameters. (line 21) +-* copy-in mode, and 'output' request: Diversions. (line 179) +-* copy-in mode, and 'tm' request: Debugging. (line 30) +-* copy-in mode, and 'tm1' request: Debugging. (line 30) +-* copy-in mode, and 'tmc' request: Debugging. (line 30) +-* copy-in mode, and 'trf' request: I/O. (line 50) +-* copy-in mode, and 'write' request: I/O. (line 212) +-* copy-in mode, and 'writec' request: I/O. (line 212) +-* copy-in mode, and 'writem' request: I/O. (line 225) +-* copy-in mode, and '\!': Diversions. (line 148) +-* copy-in mode, and '\?': Operators in Conditionals. +- (line 55) +-* copy-in mode, and '\?' <1>: Diversions. (line 148) +-* copy-in mode, and '\a': Leaders. (line 18) +-* copy-in mode, and '\E': Character Translations. +- (line 81) +-* copy-in mode, and '\t': Tabs and Fields. (line 10) +-* copy-in mode, and '\V': I/O. (line 249) +-* copying environment ('evc'): Environments. (line 70) +-* correction between italic and roman glyph ('\/', '\,'): Ligatures and Kerning. +- (line 80) +-* correction, italic ('\/'): Ligatures and Kerning. +- (line 80) +-* correction, left italic ('\,'): Ligatures and Kerning. +- (line 91) +-* cover page macros, ['ms']: ms Cover Page Macros. +- (line 6) +-* 'cp' request, and glyph definitions: Using Symbols. (line 326) +-* cp1047, input encoding: Input Encodings. (line 9) +-* cp1047, output encoding: Groff Options. (line 264) +-* 'cq' glyph, at end of sentence: Sentences. (line 18) +-* 'cq' glyph, at end of sentence <1>: Using Symbols. (line 275) +-* creating alias, for diversion ('als'): Strings. (line 229) +-* creating alias, for macro ('als'): Strings. (line 229) +-* creating alias, for number register ('aln'): Setting Registers. +- (line 112) +-* creating alias, for string ('als'): Strings. (line 229) +-* creating new characters ('char'): Using Symbols. (line 326) +-* credits: Credits. (line 6) +-* 'cs' request, and font styles: Font Families. (line 59) +-* 'cs' request, and font translations: Changing Fonts. (line 55) +-* 'cs' request, incompatibilities with AT&T 'troff': Implementation Differences. +- (line 86) +-* 'cs' request, with fractional type sizes: Fractional Type Sizes. +- (line 6) +-* current directory: Macro Directories. (line 21) +-* current input file name register ('.F'): Built-in Registers. +- (line 12) +-* current page number ('%'): Page Control. (line 27) +-* current time: I/O. (line 175) +-* current time, hours ('hours'): Built-in Registers. (line 41) +-* current time, minutes ('minutes'): Built-in Registers. (line 37) +-* current time, seconds ('seconds'): Built-in Registers. (line 31) +-* current vertical position ('nl'): Page Control. (line 67) +-* 'da' request, and 'dn' ('dl'): Diversions. (line 93) +-* 'da' request, and warnings: Warnings. (line 49) +-* 'da' request, and warnings <1>: Warnings. (line 54) +-* date, day of the month register ('dy'): Built-in Registers. (line 48) +-* date, day of the week register ('dw'): Built-in Registers. (line 45) +-* date, month of the year register ('mo'): Built-in Registers. +- (line 51) +-* date, year register ('year', 'yr'): Built-in Registers. (line 54) +-* day of the month register ('dy'): Built-in Registers. (line 48) +-* day of the week register ('dw'): Built-in Registers. (line 45) +-* 'de' request, and 'while': while. (line 22) +-* 'de', 'de1', 'dei' requests, and warnings: Warnings. (line 54) +-* debugging: Debugging. (line 6) +-* default color: Colors. (line 26) +-* default indentation ['man']: Miscellaneous man macros. +- (line 6) +-* default indentation, resetting ['man']: Man usage. (line 127) +-* default units: Default Units. (line 6) +-* defining character ('char'): Using Symbols. (line 326) +-* defining character class ('class'): Character Classes. (line 12) +-* defining fallback character ('fchar', 'fschar', 'schar'): Using Symbols. +- (line 326) +-* defining glyph ('char'): Using Symbols. (line 326) +-* defining symbol ('char'): Using Symbols. (line 326) +-* delayed text: Footnotes and Annotations. +- (line 10) +-* delimited arguments, incompatibilities with AT&T 'troff': Implementation Differences. +- (line 47) +-* delimiting character, for fields ('fc'): Fields. (line 6) +-* delimiting characters for arguments: Escapes. (line 29) +-* depth, of last glyph ('.cdp'): Environments. (line 95) +-* 'DESC' file, format: DESC File Format. (line 6) +-* 'device' request, and copy-in mode: Postprocessor Access. +- (line 19) +-* device resolution: DESC File Format. (line 85) +-* devices for output: Output device intro. (line 6) +-* devices for output <1>: Output Devices. (line 6) +-* 'dg' glyph, at end of sentence: Sentences. (line 18) +-* 'dg' glyph, at end of sentence <1>: Using Symbols. (line 275) +-* 'di' request, and warnings: Warnings. (line 49) +-* 'di' request, and warnings <1>: Warnings. (line 54) +-* differences in implementation: Implementation Differences. +- (line 6) +-* digit width space ('\0'): Page Motions. (line 138) +-* digits, and delimiters: Escapes. (line 65) +-* dimensions, line: Line Layout. (line 6) +-* directories for fonts: Font Directories. (line 6) +-* directories for macros: Macro Directories. (line 6) +-* directory, current: Macro Directories. (line 21) +-* directory, for tmac files: Macro Directories. (line 11) +-* directory, home: Macro Directories. (line 24) +-* directory, platform-specific: Macro Directories. (line 26) +-* directory, site-specific: Macro Directories. (line 26) +-* directory, site-specific <1>: Font Directories. (line 29) +-* disabling hyphenation ('\%'): Manipulating Hyphenation. +- (line 85) +-* disabling '\' ('eo'): Character Translations. +- (line 24) +-* discardable horizontal space: Manipulating Filling and Adjusting. +- (line 183) +-* discarded space in traps: Manipulating Spacing. +- (line 53) +-* displays: Displays. (line 6) +-* displays ['ms']: ms Displays and Keeps. +- (line 6) +-* displays, and footnotes ['ms']: ms Footnotes. (line 24) +-* distance to next trap register ('.t'): Page Location Traps. (line 102) +-* 'ditroff', the program: History. (line 59) +-* diversion name register ('.z'): Diversions. (line 69) +-* diversion trap, setting ('dt'): Diversion Traps. (line 7) +-* diversion traps: Diversion Traps. (line 6) +-* diversion, appending ('da'): Diversions. (line 22) +-* diversion, beginning ('di'): Diversions. (line 22) +-* diversion, creating alias ('als'): Strings. (line 229) +-* diversion, ending ('di'): Diversions. (line 22) +-* diversion, nested: Diversions. (line 69) +-* diversion, removing ('rm'): Strings. (line 224) +-* diversion, removing alias ('rm'): Strings. (line 263) +-* diversion, renaming ('rn'): Strings. (line 221) +-* diversion, stripping final newline: Strings. (line 157) +-* diversion, top-level: Diversions. (line 12) +-* diversion, top-level, and 'bp': Page Control. (line 24) +-* diversion, top-level, and '\!': Diversions. (line 171) +-* diversion, top-level, and '\?': Diversions. (line 176) +-* diversion, unformatting ('asciify'): Diversions. (line 195) +-* diversion, vertical position in, register ('.d'): Diversions. +- (line 69) +-* diversions: Diversions. (line 6) +-* diversions, and traps: Page Location Traps. (line 166) +-* diversions, shared name space with macros and strings: Strings. +- (line 92) +-* 'dl' register, and 'da' ('boxa'): Diversions. (line 93) +-* 'dn' register, and 'da' ('boxa'): Diversions. (line 93) +-* documents, multi-file: Debugging. (line 10) +-* documents, structuring the source code: Requests. (line 14) +-* double quote, in a macro argument: Request and Macro Arguments. +- (line 25) +-* double-spacing ('ls'): Basics. (line 82) +-* double-spacing ('ls') <1>: Manipulating Spacing. +- (line 64) +-* double-spacing ('vs', 'pvs'): Changing Type Sizes. (line 125) +-* drawing a circle ('\D'c ...''): Drawing Requests. (line 109) +-* drawing a line ('\D'l ...''): Drawing Requests. (line 80) +-* drawing a polygon ('\D'p ...''): Drawing Requests. (line 158) +-* drawing a solid circle ('\D'C ...''): Drawing Requests. (line 114) +-* drawing a solid ellipse ('\D'E ...''): Drawing Requests. (line 124) +-* drawing a solid polygon ('\D'P ...''): Drawing Requests. (line 167) +-* drawing a spline ('\D'~ ...''): Drawing Requests. (line 136) +-* drawing an arc ('\D'a ...''): Drawing Requests. (line 128) +-* drawing an ellipse ('\D'e ...''): Drawing Requests. (line 118) +-* drawing color name register ('.m'): Colors. (line 67) +-* drawing horizontal lines ('\l'): Drawing Requests. (line 17) +-* drawing requests: Drawing Requests. (line 6) +-* drawing vertical lines ('\L'): Drawing Requests. (line 50) +-* 'ds' request, and comments: Strings. (line 45) +-* 'ds' request, and double quotes: Request and Macro Arguments. +- (line 69) +-* 'ds' request, and leading spaces: Strings. (line 57) +-* 'ds', 'ds1' requests, and comments: Comments. (line 16) +-* 'ds', 'ds1' requests, and warnings: Warnings. (line 54) +-* dumping environments ('pev'): Debugging. (line 62) +-* dumping number registers ('pnr'): Debugging. (line 77) +-* dumping symbol table ('pm'): Debugging. (line 66) +-* dumping traps ('ptr'): Debugging. (line 81) +-* EBCDIC encoding: Tab Stops. (line 6) +-* EBCDIC encoding of a tab: Tabs and Fields. (line 6) +-* EBCDIC encoding of backspace: Identifiers. (line 12) +-* EBCDIC, input encoding: Input Encodings. (line 9) +-* EBCDIC, output encoding: Groff Options. (line 264) +-* 'el' request, and warnings: Warnings. (line 32) +-* ellipse, drawing ('\D'e ...''): Drawing Requests. (line 118) +-* ellipse, solid, drawing ('\D'E ...''): Drawing Requests. (line 124) +-* 'em' glyph, and 'cflags': Using Symbols. (line 258) +-* em unit ('m'): Measurements. (line 50) +-* embedded commands: Embedded Commands. (line 6) +-* embedding PDF: Embedding PDF. (line 6) +-* embedding PostScript: Embedding PostScript. +- (line 6) +-* embolding of special fonts: Artificial Fonts. (line 115) +-* empty line: Implicit Line Breaks. +- (line 10) +-* empty line ('sp'): Basics. (line 93) +-* empty space before a paragraph ['man']: Miscellaneous man macros. +- (line 15) +-* en unit ('n'): Measurements. (line 55) +-* enabling vertical position traps ('vpt'): Page Location Traps. +- (line 18) +-* encoding, EBCDIC: Tab Stops. (line 6) +-* encoding, input, cp1047: Input Encodings. (line 9) +-* encoding, input, EBCDIC: Input Encodings. (line 9) +-* encoding, input, latin-1 (ISO 8859-1): Input Encodings. (line 14) +-* encoding, input, latin-2 (ISO 8859-2): Input Encodings. (line 18) +-* encoding, input, latin-5 (ISO 8859-9): Input Encodings. (line 23) +-* encoding, input, latin-9 (latin-0, ISO 8859-15): Input Encodings. +- (line 28) +-* encoding, output, ASCII: Groff Options. (line 250) +-* encoding, output, cp1047: Groff Options. (line 264) +-* encoding, output, EBCDIC: Groff Options. (line 264) +-* encoding, output, latin-1 (ISO 8859-1): Groff Options. (line 254) +-* encoding, output, utf-8: Groff Options. (line 259) +-* end of conditional block ('\}'): if-else. (line 35) +-* end-of-input macro ('em'): End-of-input Traps. (line 7) +-* end-of-input trap, setting ('em'): End-of-input Traps. (line 7) +-* end-of-input traps: End-of-input Traps. (line 6) +-* end-of-sentence characters: Using Symbols. (line 247) +-* ending diversion ('di'): Diversions. (line 22) +-* environment number/name register ('.ev'): Environments. (line 39) +-* environment variables: Environment. (line 6) +-* environment, copying ('evc'): Environments. (line 70) +-* environment, dimensions of last glyph ('.w', '.cht', '.cdp', '.csk'): Environments. +- (line 95) +-* environment, previous line length ('.n'): Environments. (line 110) +-* environment, switching ('ev'): Environments. (line 39) +-* environments: Environments. (line 6) +-* environments, dumping ('pev'): Debugging. (line 62) +-* 'eqn', the program: geqn. (line 6) +-* equations ['ms']: ms Insertions. (line 6) +-* escape character, changing ('ec'): Character Translations. +- (line 47) +-* escape character, while defining glyph: Using Symbols. (line 326) +-* escapes: Escapes. (line 6) +-* escaping newline characters, in strings: Strings. (line 63) +-* 'ex' request, use in debugging: Debugging. (line 45) +-* 'ex' request, used with 'nx' and 'rd': I/O. (line 122) +-* example markup, bulleted list ['ms']: Lists in ms. (line 21) +-* example markup, glossary-style list ['ms']: Lists in ms. (line 65) +-* example markup, multi-page table ['ms']: Example multi-page table. +- (line 6) +-* example markup, numbered list ['ms']: Lists in ms. (line 41) +-* example markup, title page: ms Cover Page Macros. +- (line 66) +-* examples of invocation: Invocation Examples. (line 6) +-* exiting ('ex'): Debugging. (line 45) +-* expansion of strings ('\*'): Strings. (line 19) +-* explicit hyphen ('\%'): Manipulating Hyphenation. +- (line 47) +-* expression, limitation of logical not in: Expressions. (line 27) +-* expression, order of evaluation: Expressions. (line 59) +-* expressions: Expressions. (line 6) +-* expressions, and space characters: Expressions. (line 86) +-* extra post-vertical line space ('\x'): Changing Type Sizes. (line 118) +-* extra post-vertical line space register ('.a'): Manipulating Spacing. +- (line 94) +-* extra pre-vertical line space ('\x'): Changing Type Sizes. (line 109) +-* extra spaces: Filling and Adjusting. +- (line 10) +-* extremum operators ('>?', ': Manipulating Filling and Adjusting. +- (line 156) +-* fill mode <2>: Warnings. (line 23) +-* fill mode ('fi'): Manipulating Filling and Adjusting. +- (line 29) +-* fill mode, and '\c': Line Control. (line 69) +-* filling: Filling and Adjusting. +- (line 6) +-* filling and adjusting, manipulating: Manipulating Filling and Adjusting. +- (line 6) +-* final newline, stripping in diversions: Strings. (line 157) +-* 'fl' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* floating keep: Displays. (line 23) +-* flush output ('fl'): Debugging. (line 87) +-* font description file, format: DESC File Format. (line 6) +-* font description file, format <1>: Font File Format. (line 6) +-* font directories: Font Directories. (line 6) +-* font families: Font Families. (line 6) +-* font family, changing ('fam', '\F'): Font Families. (line 25) +-* font file, format: Font File Format. (line 6) +-* font files: Font Files. (line 6) +-* font files, comments: Font File Format. (line 36) +-* font for underlining ('uf'): Artificial Fonts. (line 90) +-* font height, changing ('\H'): Artificial Fonts. (line 16) +-* font path: Font Directories. (line 14) +-* font position register ('.f'): Font Positions. (line 20) +-* font position, changing ('\f'): Font Positions. (line 60) +-* font positions: Font Positions. (line 6) +-* font selection ['man']: Man font macros. (line 6) +-* font slant, changing ('\S'): Artificial Fonts. (line 45) +-* font style, changing ('sty'): Font Families. (line 59) +-* font styles: Font Families. (line 6) +-* font translation ('ftr'): Changing Fonts. (line 55) +-* font, magnification ('fzoom'): Changing Fonts. (line 71) +-* font, mounting ('fp'): Font Positions. (line 13) +-* font, optical size: Changing Fonts. (line 71) +-* font, previous ('ft', '\f[]', '\fP'): Changing Fonts. (line 23) +-* font, zoom factor ('fzoom'): Changing Fonts. (line 71) +-* fonts: Fonts and Symbols. (line 6) +-* fonts <1>: Changing Fonts. (line 6) +-* fonts, artificial: Artificial Fonts. (line 6) +-* fonts, changing ('ft', '\f'): Changing Fonts. (line 11) +-* fonts, PostScript: Font Families. (line 11) +-* fonts, searching: Font Directories. (line 6) +-* fonts, special: Special Fonts. (line 6) +-* footers: Page Layout. (line 31) +-* footers <1>: Page Location Traps. (line 38) +-* footers ['ms']: ms Headers and Footers. +- (line 6) +-* footnotes: Footnotes and Annotations. +- (line 6) +-* footnotes ['ms']: ms Footnotes. (line 6) +-* footnotes, and displays ['ms']: ms Footnotes. (line 24) +-* footnotes, and keeps ['ms']: ms Footnotes. (line 24) +-* form letters: I/O. (line 106) +-* format of font description file: DESC File Format. (line 6) +-* format of font description files: Font File Format. (line 6) +-* format of font files: Font File Format. (line 6) +-* format of register ('\g'): Assigning Formats. (line 75) +-* formats, assigning ('af'): Assigning Formats. (line 6) +-* formats, file: File formats. (line 6) +-* 'fp' request, and font translations: Changing Fonts. (line 55) +-* 'fp' request, incompatibilities with AT&T 'troff': Implementation Differences. +- (line 86) +-* fractional point sizes: Fractional Type Sizes. +- (line 6) +-* fractional point sizes <1>: Implementation Differences. +- (line 76) +-* fractional type sizes: Fractional Type Sizes. +- (line 6) +-* fractional type sizes <1>: Implementation Differences. +- (line 76) +-* french-spacing: Sentences. (line 12) +-* 'fspecial' request, and font styles: Font Families. (line 59) +-* 'fspecial' request, and font translations: Changing Fonts. (line 55) +-* 'fspecial' request, and glyph search order: Using Symbols. (line 14) +-* 'fspecial' request, and imitating bold: Artificial Fonts. (line 115) +-* 'ft' request, and font translations: Changing Fonts. (line 55) +-* 'gchem', invoking: Invoking gchem. (line 5) +-* 'gchem', the program: gchem. (line 6) +-* 'geqn', invoking: Invoking geqn. (line 5) +-* 'geqn', the program: geqn. (line 6) +-* GGL (groff glyph list): Using Symbols. (line 88) +-* GGL (groff glyph list) <1>: Character Classes. (line 32) +-* 'ggrn', invoking: Invoking ggrn. (line 5) +-* 'ggrn', the program: ggrn. (line 6) +-* glossary-style list, example markup ['ms']: Lists in ms. (line 65) +-* glyph: Using Symbols. (line 6) +-* glyph for line drawing: Drawing Requests. (line 50) +-* glyph names, composite: Using Symbols. (line 88) +-* glyph pile ('\b'): Drawing Requests. (line 232) +-* glyph properties ('cflags'): Using Symbols. (line 237) +-* glyph, box rule ('\[br]'): Drawing Requests. (line 50) +-* glyph, constant space: Artificial Fonts. (line 126) +-* glyph, defining ('char'): Using Symbols. (line 326) +-* glyph, for line drawing: Drawing Requests. (line 28) +-* glyph, for margins ('mc'): Miscellaneous. (line 75) +-* glyph, italic correction ('\/'): Ligatures and Kerning. +- (line 80) +-* glyph, last, dimensions ('.w', '.cht', '.cdp', '.csk'): Environments. +- (line 95) +-* glyph, leader repetition ('lc'): Leaders. (line 23) +-* glyph, left italic correction ('\,'): Ligatures and Kerning. +- (line 91) +-* glyph, numbered ('\N'): Character Translations. +- (line 160) +-* glyph, numbered ('\N') <1>: Using Symbols. (line 201) +-* glyph, removing definition ('rchar', 'rfschar'): Using Symbols. +- (line 382) +-* glyph, soft hyphen ('hy'): Manipulating Hyphenation. +- (line 243) +-* glyph, tab repetition ('tc'): Tabs and Fields. (line 129) +-* glyph, underscore ('\[ru]'): Drawing Requests. (line 28) +-* glyphs, available, list ('groff_char(7)' man page): Using Symbols. +- (line 76) +-* glyphs, output, and input characters, compatibility with AT&T 'troff': Implementation Differences. +- (line 86) +-* glyphs, overstriking ('\o'): Page Motions. (line 216) +-* glyphs, unnamed: Using Symbols. (line 212) +-* glyphs, unnamed, accessing with '\N': Font File Format. (line 51) +-* GNU-specific register ('.g'): Built-in Registers. (line 102) +-* 'gpic', invoking: Invoking gpic. (line 5) +-* 'gpic', the program: gpic. (line 6) +-* 'grap', the program: grap. (line 6) +-* gray shading ('\D'f ...''): Drawing Requests. (line 141) +-* 'grefer', invoking: Invoking grefer. (line 5) +-* 'grefer', the program: grefer. (line 6) +-* 'grn', the program: ggrn. (line 6) +-* 'grodvi', invoking: Invoking grodvi. (line 6) +-* 'grodvi', the program: grodvi. (line 6) +-* 'groff' - what is it?: What Is groff?. (line 6) +-* 'groff' capabilities: groff Capabilities. (line 6) +-* groff glyph list (GGL): Using Symbols. (line 88) +-* groff glyph list (GGL) <1>: Character Classes. (line 32) +-* 'groff' invocation: Invoking groff. (line 6) +-* 'groff', and 'pi' request: I/O. (line 159) +-* GROFF_BIN_PATH, environment variable: Environment. (line 10) +-* GROFF_COMMAND_PREFIX, environment variable: Environment. (line 14) +-* GROFF_ENCODING, environment variable: Environment. (line 25) +-* GROFF_FONT_PATH, environment variable: Environment. (line 34) +-* GROFF_FONT_PATH, environment variable <1>: Font Directories. +- (line 26) +-* GROFF_TMAC_PATH, environment variable: Environment. (line 39) +-* GROFF_TMAC_PATH, environment variable <1>: Macro Directories. +- (line 18) +-* GROFF_TMPDIR, environment variable: Environment. (line 44) +-* GROFF_TYPESETTER, environment variable: Environment. (line 52) +-* 'grohtml', invoking: Invoking grohtml. (line 6) +-* 'grohtml', registers and strings: grohtml specific registers and strings. +- (line 6) +-* 'grohtml', the program: Groff Options. (line 275) +-* 'grohtml', the program <1>: grohtml. (line 6) +-* 'grolbp', invoking: Invoking grolbp. (line 6) +-* 'grolbp', the program: grolbp. (line 6) +-* 'grolj4', invoking: Invoking grolj4. (line 6) +-* 'grolj4', the program: grolj4. (line 6) +-* 'gropdf', invoking: Invoking gropdf. (line 6) +-* 'gropdf', the program: gropdf. (line 6) +-* 'grops', invoking: Invoking grops. (line 6) +-* 'grops', the program: grops. (line 6) +-* 'grotty', invoking: Invoking grotty. (line 6) +-* 'grotty', the program: grotty. (line 6) +-* 'gsoelim', invoking: Invoking gsoelim. (line 5) +-* 'gsoelim', the program: gsoelim. (line 6) +-* 'gtbl', invoking: Invoking gtbl. (line 5) +-* 'gtbl', the program: gtbl. (line 6) +-* 'gtroff', identification register ('.g'): Built-in Registers. +- (line 102) +-* 'gtroff', interactive use: Debugging. (line 87) +-* 'gtroff', output: gtroff Output. (line 6) +-* 'gtroff', process ID register ('$$'): Built-in Registers. (line 99) +-* 'gtroff', reference: gtroff Reference. (line 6) +-* 'gxditview', invoking: Invoking gxditview. (line 5) +-* 'gxditview', the program: gxditview. (line 6) +-* hanging indentation ['man']: Man usage. (line 98) +-* 'hcode' request, and glyph definitions: Using Symbols. (line 326) +-* headers: Page Layout. (line 31) +-* headers <1>: Page Location Traps. (line 38) +-* headers ['ms']: ms Headers and Footers. +- (line 6) +-* height, font, changing ('\H'): Artificial Fonts. (line 16) +-* height, of last glyph ('.cht'): Environments. (line 95) +-* high-water mark register ('.h'): Diversions. (line 76) +-* history: History. (line 6) +-* home directory: Macro Directories. (line 24) +-* horizontal discardable space: Manipulating Filling and Adjusting. +- (line 183) +-* horizontal input line position register ('hp'): Page Motions. +- (line 209) +-* horizontal input line position, saving ('\k'): Page Motions. +- (line 203) +-* horizontal line, drawing ('\l'): Drawing Requests. (line 17) +-* horizontal motion ('\h'): Page Motions. (line 103) +-* horizontal output line position register ('.k'): Page Motions. +- (line 212) +-* horizontal resolution: DESC File Format. (line 25) +-* horizontal resolution register ('.H'): Built-in Registers. (line 15) +-* horizontal space ('\h'): Page Motions. (line 103) +-* horizontal space, unformatting: Strings. (line 157) +-* hours, current time ('hours'): Built-in Registers. (line 41) +-* 'hpf' request, and hyphenation language: Manipulating Hyphenation. +- (line 256) +-* 'hw' request, and hyphenation language: Manipulating Hyphenation. +- (line 256) +-* 'hy' glyph, and 'cflags': Using Symbols. (line 258) +-* hyphen, explicit ('\%'): Manipulating Hyphenation. +- (line 47) +-* hyphenated lines, consecutive ('hlm'): Manipulating Hyphenation. +- (line 47) +-* hyphenating characters: Using Symbols. (line 251) +-* hyphenation: Hyphenation. (line 6) +-* hyphenation character ('\%'): Manipulating Hyphenation. +- (line 85) +-* hyphenation code ('hcode'): Manipulating Hyphenation. +- (line 175) +-* hyphenation language register ('.hla'): Manipulating Hyphenation. +- (line 263) +-* hyphenation margin ('hym'): Manipulating Hyphenation. +- (line 211) +-* hyphenation margin register ('.hym'): Manipulating Hyphenation. +- (line 222) +-* hyphenation patterns ('hpf'): Manipulating Hyphenation. +- (line 116) +-* hyphenation restrictions register ('.hy'): Manipulating Hyphenation. +- (line 30) +-* hyphenation space ('hys'): Manipulating Hyphenation. +- (line 227) +-* hyphenation space register ('.hys'): Manipulating Hyphenation. +- (line 239) +-* hyphenation, disabling ('\%'): Manipulating Hyphenation. +- (line 85) +-* hyphenation, manipulating: Manipulating Hyphenation. +- (line 6) +-* 'i' unit: Measurements. (line 22) +-* i/o: I/O. (line 6) +-* IBM cp1047 input encoding: Input Encodings. (line 9) +-* IBM cp1047 output encoding: Groff Options. (line 264) +-* identifiers: Identifiers. (line 6) +-* identifiers, undefined: Identifiers. (line 79) +-* 'ie' request, and font translations: Changing Fonts. (line 55) +-* 'ie' request, and warnings: Warnings. (line 32) +-* 'ie' request, operators to use with: Operators in Conditionals. +- (line 6) +-* 'if' request, and font translations: Changing Fonts. (line 55) +-* 'if' request, and the '!' operator: Expressions. (line 21) +-* 'if' request, operators to use with: Operators in Conditionals. +- (line 6) +-* if-else: if-else. (line 6) +-* 'ig' request, and auto-increment: Comments. (line 85) +-* 'ig' request, and copy-in mode: Comments. (line 85) +-* imitating bold face ('bd'): Artificial Fonts. (line 98) +-* implementation differences: Implementation Differences. +- (line 6) +-* implicit breaks of lines: Implicit Line Breaks. +- (line 6) +-* implicit line breaks: Implicit Line Breaks. +- (line 6) +-* 'in' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* 'in' request, using '+' and '-': Expressions. (line 75) +-* inch unit ('i'): Measurements. (line 22) +-* including a file ('so'): I/O. (line 9) +-* incompatibilities with AT&T 'troff': Implementation Differences. +- (line 6) +-* increment value without changing the register: Auto-increment. +- (line 52) +-* increment, automatic: Auto-increment. (line 6) +-* indentaion, resetting to default ['man']: Man usage. (line 127) +-* indentation ('in'): Line Layout. (line 25) +-* index, in macro package: Indices. (line 6) +-* indicator, scaling: Measurements. (line 6) +-* indirect assignments: Interpolating Registers. +- (line 11) +-* input and output requests: I/O. (line 6) +-* input characters and output glyphs, compatibility with AT&T 'troff': Implementation Differences. +- (line 86) +-* input characters, invalid: Identifiers. (line 15) +-* input conventions: Input Conventions. (line 6) +-* input encoding, cp1047: Input Encodings. (line 9) +-* input encoding, EBCDIC: Input Encodings. (line 9) +-* input encoding, latin-1 (ISO 8859-1): Input Encodings. (line 14) +-* input encoding, latin-2 (ISO 8859-2): Input Encodings. (line 18) +-* input encoding, latin-2 (ISO 8859-9): Input Encodings. (line 23) +-* input encoding, latin-9 (latin-9, ISO 8859-15): Input Encodings. +- (line 28) +-* input file name, current, register ('.F'): Built-in Registers. +- (line 12) +-* input level in delimited arguments: Implementation Differences. +- (line 47) +-* input line continuation ('\'): Line Control. (line 36) +-* input line number register ('.c', 'c.'): Built-in Registers. +- (line 77) +-* input line number, setting ('lf'): Debugging. (line 10) +-* input line position, horizontal, saving ('\k'): Page Motions. +- (line 203) +-* input line trap, setting ('it'): Input Line Traps. (line 8) +-* input line traps: Input Line Traps. (line 6) +-* input line traps and interrupted lines ('itc'): Input Line Traps. +- (line 24) +-* input line, horizontal position, register ('hp'): Page Motions. +- (line 209) +-* input stack, backtrace ('backtrace'): Debugging. (line 96) +-* input stack, setting limit: Debugging. (line 119) +-* input token: Gtroff Internals. (line 6) +-* input, 8-bit: Font File Format. (line 51) +-* input, standard, reading from ('rd'): I/O. (line 89) +-* inserting horizontal space ('\h'): Page Motions. (line 103) +-* installation: Installation. (line 5) +-* interactive use of 'gtroff': Debugging. (line 87) +-* intermediate output: gtroff Output. (line 16) +-* interpolating registers ('\n'): Interpolating Registers. +- (line 6) +-* interpolation of strings ('\*'): Strings. (line 19) +-* interrupted line: Line Control. (line 36) +-* interrupted line register ('.int'): Line Control. (line 81) +-* interrupted lines and input line traps ('itc'): Input Line Traps. +- (line 24) +-* introduction: Introduction. (line 6) +-* invalid characters for 'trf' request: I/O. (line 73) +-* invalid input characters: Identifiers. (line 15) +-* invocation examples: Invocation Examples. (line 6) +-* invoking 'gchem': Invoking gchem. (line 6) +-* invoking 'geqn': Invoking geqn. (line 6) +-* invoking 'ggrn': Invoking ggrn. (line 6) +-* invoking 'gpic': Invoking gpic. (line 6) +-* invoking 'grefer': Invoking grefer. (line 6) +-* invoking 'grodvi': Invoking grodvi. (line 6) +-* invoking 'groff': Invoking groff. (line 6) +-* invoking 'grohtml': Invoking grohtml. (line 6) +-* invoking 'grolbp': Invoking grolbp. (line 6) +-* invoking 'grolj4': Invoking grolj4. (line 6) +-* invoking 'gropdf': Invoking gropdf. (line 6) +-* invoking 'grops': Invoking grops. (line 6) +-* invoking 'grotty': Invoking grotty. (line 6) +-* invoking 'gsoelim': Invoking gsoelim. (line 6) +-* invoking 'gtbl': Invoking gtbl. (line 6) +-* invoking 'gxditview': Invoking gxditview. (line 6) +-* invoking 'preconv': Invoking preconv. (line 6) +-* ISO 6249 SGR: Invoking grotty. (line 50) +-* ISO 8859-1 (latin-1), input encoding: Input Encodings. (line 14) +-* ISO 8859-1 (latin-1), output encoding: Groff Options. (line 254) +-* ISO 8859-15 (latin-9, latin-0), input encoding: Input Encodings. +- (line 28) +-* ISO 8859-2 (latin-2), input encoding: Input Encodings. (line 18) +-* ISO 8859-9 (latin-2), input encoding: Input Encodings. (line 23) +-* italic correction ('\/'): Ligatures and Kerning. +- (line 80) +-* italic fonts ['man']: Man font macros. (line 52) +-* italic glyph, correction after roman glyph ('\,'): Ligatures and Kerning. +- (line 91) +-* italic glyph, correction before roman glyph ('\/'): Ligatures and Kerning. +- (line 80) +-* justifying text: Manipulating Filling and Adjusting. +- (line 6) +-* justifying text ('rj'): Manipulating Filling and Adjusting. +- (line 250) +-* keep: Displays. (line 18) +-* keep, floating: Displays. (line 23) +-* keeps ['ms']: ms Displays and Keeps. +- (line 6) +-* keeps, and footnotes ['ms']: ms Footnotes. (line 24) +-* kerning and ligatures: Ligatures and Kerning. +- (line 6) +-* kerning enabled register ('.kern'): Ligatures and Kerning. +- (line 42) +-* kerning, activating ('kern'): Ligatures and Kerning. +- (line 42) +-* kerning, track: Ligatures and Kerning. +- (line 53) +-* landscape page orientation: Paper Size. (line 6) +-* last glyph, dimensions ('.w', '.cht', '.cdp', '.csk'): Environments. +- (line 95) +-* last-requested point size registers ('.psr', '.sr'): Fractional Type Sizes. +- (line 45) +-* latin-1 (ISO 8859-1), input encoding: Input Encodings. (line 14) +-* latin-1 (ISO 8859-1), output encoding: Groff Options. (line 254) +-* latin-2 (ISO 8859-2), input encoding: Input Encodings. (line 18) +-* latin-2 (ISO 8859-9), input encoding: Input Encodings. (line 23) +-* latin-9 (latin-0, ISO 8859-15), input encoding: Input Encodings. +- (line 28) +-* layout, line: Line Layout. (line 6) +-* layout, page: Page Layout. (line 6) +-* 'lc' request, and glyph definitions: Using Symbols. (line 326) +-* leader character: Leaders. (line 12) +-* leader character, and translations: Character Translations. +- (line 169) +-* leader character, non-interpreted ('\a'): Leaders. (line 18) +-* leader repetition character ('lc'): Leaders. (line 23) +-* leaders: Leaders. (line 6) +-* leading: Sizes. (line 17) +-* leading spaces: Filling and Adjusting. +- (line 10) +-* leading spaces macro ('lsm'): Implicit Line Breaks. +- (line 15) +-* leading spaces macro ('lsm') <1>: Leading Spaces Traps. +- (line 9) +-* leading spaces traps: Leading Spaces Traps. +- (line 6) +-* leading spaces with 'ds': Strings. (line 57) +-* left italic correction ('\,'): Ligatures and Kerning. +- (line 91) +-* left margin ('po'): Line Layout. (line 21) +-* left margin, how to move ['man']: Man usage. (line 106) +-* length of a string ('length'): Strings. (line 211) +-* length of line ('ll'): Line Layout. (line 29) +-* length of page ('pl'): Page Layout. (line 13) +-* length of previous line ('.n'): Environments. (line 110) +-* length of title line ('lt'): Page Layout. (line 67) +-* 'length' request, and copy-in mode: Strings. (line 211) +-* letters, form: I/O. (line 106) +-* level of warnings ('warn'): Debugging. (line 155) +-* ligature: Using Symbols. (line 6) +-* ligatures and kerning: Ligatures and Kerning. +- (line 6) +-* ligatures enabled register ('.lg'): Ligatures and Kerning. +- (line 24) +-* ligatures, activating ('lg'): Ligatures and Kerning. +- (line 24) +-* limitations of '\b' escape: Drawing Requests. (line 239) +-* line break: Basics. (line 48) +-* line break <1>: Implicit Line Breaks. +- (line 6) +-* line break <2>: Manipulating Filling and Adjusting. +- (line 6) +-* line break ('br'): Basics. (line 118) +-* line breaks, with vertical space ['man']: Man usage. (line 120) +-* line breaks, without vertical space ['man']: Man usage. (line 124) +-* line control: Line Control. (line 6) +-* line dimensions: Line Layout. (line 6) +-* line drawing glyph: Drawing Requests. (line 28) +-* line drawing glyph <1>: Drawing Requests. (line 50) +-* line indentation ('in'): Line Layout. (line 25) +-* line layout: Line Layout. (line 6) +-* line length ('ll'): Line Layout. (line 29) +-* line length register ('.l'): Line Layout. (line 158) +-* line length, previous ('.n'): Environments. (line 110) +-* line number, input, register ('.c', 'c.'): Built-in Registers. +- (line 77) +-* line number, output, register ('ln'): Built-in Registers. (line 82) +-* line numbers, printing ('nm'): Miscellaneous. (line 10) +-* line space, extra post-vertical ('\x'): Changing Type Sizes. +- (line 118) +-* line space, extra pre-vertical ('\x'): Changing Type Sizes. (line 109) +-* line spacing register ('.L'): Manipulating Spacing. +- (line 75) +-* line spacing, post-vertical ('pvs'): Changing Type Sizes. (line 122) +-* line thickness ('\D't ...''): Drawing Requests. (line 206) +-* line, blank: Implicit Line Breaks. +- (line 10) +-* line, drawing ('\D'l ...''): Drawing Requests. (line 80) +-* line, empty ('sp'): Basics. (line 93) +-* line, horizontal, drawing ('\l'): Drawing Requests. (line 17) +-* line, implicit breaks: Implicit Line Breaks. +- (line 6) +-* line, input, continuation ('\'): Line Control. (line 36) +-* line, input, horizontal position, register ('hp'): Page Motions. +- (line 209) +-* line, input, horizontal position, saving ('\k'): Page Motions. +- (line 203) +-* line, interrupted: Line Control. (line 36) +-* line, output, continuation ('\c'): Line Control. (line 36) +-* line, output, horizontal position, register ('.k'): Page Motions. +- (line 212) +-* line, vertical, drawing ('\L'): Drawing Requests. (line 50) +-* line-tabs mode: Tabs and Fields. (line 138) +-* lines, blank, disabling: Manipulating Spacing. +- (line 123) +-* lines, centering ('ce'): Basics. (line 105) +-* lines, centering ('ce') <1>: Manipulating Filling and Adjusting. +- (line 204) +-* lines, consecutive hyphenated ('hlm'): Manipulating Hyphenation. +- (line 47) +-* lines, interrupted, and input line traps ('itc'): Input Line Traps. +- (line 24) +-* list: Displays. (line 13) +-* list of available glyphs ('groff_char(7)' man page): Using Symbols. +- (line 76) +-* 'll' request, using '+' and '-': Expressions. (line 75) +-* location, vertical, page, marking ('mk'): Page Motions. (line 11) +-* location, vertical, page, returning to marked ('rt'): Page Motions. +- (line 11) +-* logical not, limitation in expression: Expressions. (line 27) +-* logical operators: Expressions. (line 19) +-* long names: Implementation Differences. +- (line 9) +-* loops and conditionals: Conditionals and Loops. +- (line 6) +-* 'lq' glyph, and 'lq' string ['man']: Predefined man strings. +- (line 22) +-* 'ls' request, alternative to ('pvs'): Changing Type Sizes. (line 137) +-* 'lt' request, using '+' and '-': Expressions. (line 75) +-* 'm' unit: Measurements. (line 50) +-* 'M' unit: Measurements. (line 62) +-* machine unit ('u'): Measurements. (line 6) +-* macro arguments: Request and Macro Arguments. +- (line 6) +-* macro arguments, and compatibility mode: Gtroff Internals. (line 91) +-* macro arguments, and tabs: Request and Macro Arguments. +- (line 6) +-* macro basics: Basics. (line 6) +-* macro directories: Macro Directories. (line 6) +-* macro files, searching: Macro Directories. (line 11) +-* macro name register ('\$0'): Parameters. (line 71) +-* macro names, starting with '[' or ']', and 'refer': Identifiers. +- (line 46) +-* macro packages: Macro Package Intro. (line 6) +-* macro packages <1>: Macro Packages. (line 6) +-* macro packages, structuring the source code: Requests. (line 14) +-* macro, appending ('am'): Writing Macros. (line 116) +-* macro, arguments ('\$'): Parameters. (line 21) +-* macro, creating alias ('als'): Strings. (line 229) +-* macro, end-of-input ('em'): End-of-input Traps. (line 7) +-* macro, removing ('rm'): Strings. (line 224) +-* macro, removing alias ('rm'): Strings. (line 263) +-* macro, renaming ('rn'): Strings. (line 221) +-* macros: Macros. (line 6) +-* macros for manual pages ['man']: Man usage. (line 6) +-* macros, recursive: while. (line 38) +-* macros, searching: Macro Directories. (line 6) +-* macros, shared name space with strings and diversions: Strings. +- (line 92) +-* macros, tutorial for users: Tutorial for Macro Users. +- (line 6) +-* macros, writing: Writing Macros. (line 6) +-* magnification of a font ('fzoom'): Changing Fonts. (line 71) +-* major quotes: Displays. (line 10) +-* major version number register ('.x'): Built-in Registers. (line 88) +-* 'man' macros: Man usage. (line 6) +-* 'man' macros, bold face: Man font macros. (line 14) +-* 'man' macros, custom headers and footers: Optional man extensions. +- (line 12) +-* 'man' macros, default indentation: Miscellaneous man macros. +- (line 6) +-* 'man' macros, empty space before a paragraph: Miscellaneous man macros. +- (line 15) +-* 'man' macros, hanging indentation: Man usage. (line 98) +-* 'man' macros, how to set fonts: Man font macros. (line 6) +-* 'man' macros, italic fonts: Man font macros. (line 52) +-* 'man' macros, line breaks with vertical space: Man usage. (line 120) +-* 'man' macros, line breaks without vertical space: Man usage. +- (line 124) +-* 'man' macros, moving left margin: Man usage. (line 106) +-* 'man' macros, resetting default indentation: Man usage. (line 127) +-* 'man' macros, tab stops: Miscellaneous man macros. +- (line 10) +-* 'man' macros, Ultrix-specific: Optional man extensions. +- (line 30) +-* man pages: man. (line 6) +-* manipulating filling and adjusting: Manipulating Filling and Adjusting. +- (line 6) +-* manipulating hyphenation: Manipulating Hyphenation. +- (line 6) +-* manipulating spacing: Manipulating Spacing. +- (line 6) +-* 'man'macros, BSD compatibility: Miscellaneous man macros. +- (line 27) +-* 'man'macros, BSD compatibility <1>: Miscellaneous man macros. +- (line 44) +-* manual pages: man. (line 6) +-* margin for hyphenation ('hym'): Manipulating Hyphenation. +- (line 211) +-* margin glyph ('mc'): Miscellaneous. (line 75) +-* margin, bottom: Page Layout. (line 20) +-* margin, left ('po'): Line Layout. (line 21) +-* margin, top: Page Layout. (line 20) +-* mark, high-water, register ('.h'): Diversions. (line 76) +-* marking vertical page location ('mk'): Page Motions. (line 11) +-* MathML: grohtml specific registers and strings. +- (line 23) +-* maximum values of Roman numerals: Assigning Formats. (line 59) +-* 'mdoc' macros: mdoc. (line 6) +-* 'me' macro package: me. (line 6) +-* measurement unit: Measurements. (line 6) +-* measurements: Measurements. (line 6) +-* measurements, specifying safely: Default Units. (line 25) +-* minimum values of Roman numerals: Assigning Formats. (line 59) +-* minor version number register ('.y'): Built-in Registers. (line 92) +-* minutes, current time ('minutes'): Built-in Registers. (line 37) +-* 'mm' macro package: mm. (line 6) +-* mode for constant glyph space ('cs'): Artificial Fonts. (line 126) +-* mode, compatibility: Implementation Differences. +- (line 6) +-* mode, compatibility, and parameters: Gtroff Internals. (line 91) +-* mode, copy: Copy-in Mode. (line 6) +-* mode, copy-in: Copy-in Mode. (line 6) +-* mode, copy-in, and 'cf' request: I/O. (line 50) +-* mode, copy-in, and 'device' request: Postprocessor Access. +- (line 19) +-* mode, copy-in, and 'ig' request: Comments. (line 85) +-* mode, copy-in, and 'length' request: Strings. (line 211) +-* mode, copy-in, and macro arguments: Parameters. (line 21) +-* mode, copy-in, and 'output' request: Diversions. (line 179) +-* mode, copy-in, and 'tm' request: Debugging. (line 30) +-* mode, copy-in, and 'tm1' request: Debugging. (line 30) +-* mode, copy-in, and 'tmc' request: Debugging. (line 30) +-* mode, copy-in, and 'trf' request: I/O. (line 50) +-* mode, copy-in, and 'write' request: I/O. (line 212) +-* mode, copy-in, and 'writec' request: I/O. (line 212) +-* mode, copy-in, and 'writem' request: I/O. (line 225) +-* mode, copy-in, and '\!': Diversions. (line 148) +-* mode, copy-in, and '\?': Operators in Conditionals. +- (line 55) +-* mode, copy-in, and '\?' <1>: Diversions. (line 148) +-* mode, copy-in, and '\a': Leaders. (line 18) +-* mode, copy-in, and '\E': Character Translations. +- (line 81) +-* mode, copy-in, and '\t': Tabs and Fields. (line 10) +-* mode, copy-in, and '\V': I/O. (line 249) +-* mode, fill: Implicit Line Breaks. +- (line 15) +-* mode, fill <1>: Manipulating Filling and Adjusting. +- (line 156) +-* mode, fill <2>: Warnings. (line 23) +-* mode, fill ('fi'): Manipulating Filling and Adjusting. +- (line 29) +-* mode, fill, and '\c': Line Control. (line 69) +-* mode, line-tabs: Tabs and Fields. (line 138) +-* mode, no-fill ('nf'): Manipulating Filling and Adjusting. +- (line 39) +-* mode, no-fill, and '\c': Line Control. (line 60) +-* mode, no-space ('ns'): Manipulating Spacing. +- (line 123) +-* mode, nroff: Troff and Nroff Mode. +- (line 6) +-* mode, safer: Groff Options. (line 214) +-* mode, safer <1>: Macro Directories. (line 21) +-* mode, safer <2>: Built-in Registers. (line 23) +-* mode, safer <3>: I/O. (line 32) +-* mode, safer <4>: I/O. (line 147) +-* mode, safer <5>: I/O. (line 168) +-* mode, safer <6>: I/O. (line 206) +-* mode, troff: Troff and Nroff Mode. +- (line 6) +-* mode, unsafe: Groff Options. (line 292) +-* mode, unsafe <1>: Macro Directories. (line 21) +-* mode, unsafe <2>: Built-in Registers. (line 23) +-* mode, unsafe <3>: I/O. (line 32) +-* mode, unsafe <4>: I/O. (line 147) +-* mode, unsafe <5>: I/O. (line 168) +-* mode, unsafe <6>: I/O. (line 206) +-* modifying requests: Requests. (line 61) +-* 'mom' macro package: mom. (line 6) +-* month of the year register ('mo'): Built-in Registers. (line 51) +-* motion operators: Expressions. (line 65) +-* motion, horizontal ('\h'): Page Motions. (line 103) +-* motion, vertical ('\v'): Page Motions. (line 78) +-* motions, page: Page Motions. (line 6) +-* mounting font ('fp'): Font Positions. (line 13) +-* 'ms' macros: ms. (line 6) +-* 'ms' macros, accent marks: ms Strings and Special Characters. +- (line 6) +-* 'ms' macros, body text: ms Body Text. (line 6) +-* 'ms' macros, cover page: ms Cover Page Macros. +- (line 6) +-* 'ms' macros, creating table of contents: ms TOC. (line 6) +-* 'ms' macros, differences from AT&T: Differences from AT&T ms. +- (line 6) +-* 'ms' macros, displays: ms Displays and Keeps. +- (line 6) +-* 'ms' macros, document control registers: ms Document Control Registers. +- (line 6) +-* 'ms' macros, equations: ms Insertions. (line 6) +-* 'ms' macros, figures: ms Insertions. (line 6) +-* 'ms' macros, footers: ms Headers and Footers. +- (line 6) +-* 'ms' macros, footnotes: ms Footnotes. (line 6) +-* 'ms' macros, general structure: General ms Structure. +- (line 6) +-* 'ms' macros, headers: ms Headers and Footers. +- (line 6) +-* 'ms' macros, headings: Headings in ms. (line 6) +-* 'ms' macros, highlighting: Highlighting in ms. (line 6) +-* 'ms' macros, keeps: ms Displays and Keeps. +- (line 6) +-* 'ms' macros, lists: Lists in ms. (line 6) +-* 'ms' macros, margins: ms Margins. (line 6) +-* 'ms' macros, multiple columns: ms Multiple Columns. (line 6) +-* 'ms' macros, naming conventions: Naming Conventions. (line 6) +-* 'ms' macros, nested lists: Lists in ms. (line 122) +-* 'ms' macros, page layout: ms Page Layout. (line 6) +-* 'ms' macros, paragraph handling: Paragraphs in ms. (line 6) +-* 'ms' macros, references: ms Insertions. (line 6) +-* 'ms' macros, special characters: ms Strings and Special Characters. +- (line 6) +-* 'ms' macros, strings: ms Strings and Special Characters. +- (line 6) +-* 'ms' macros, tables: ms Insertions. (line 6) +-* multi-file documents: Debugging. (line 10) +-* multi-line strings: Strings. (line 63) +-* multi-page table, example markup ['ms']: Example multi-page table. +- (line 6) +-* multiple columns ['ms']: ms Multiple Columns. (line 6) +-* 'n' unit: Measurements. (line 55) +-* name space, common, of macros, diversions, and strings: Strings. +- (line 92) +-* name, background color, register ('.M'): Colors. (line 94) +-* name, drawing color, register ('.m'): Colors. (line 67) +-* name, fill color, register ('.M'): Colors. (line 94) +-* named character ('\C'): Using Symbols. (line 185) +-* names, long: Implementation Differences. +- (line 9) +-* naming conventions, 'ms' macros: Naming Conventions. (line 6) +-* 'ne' request, and the '.trunc' register: Page Location Traps. +- (line 131) +-* 'ne' request, comparison with 'sv': Page Control. (line 53) +-* negating register values: Setting Registers. (line 78) +-* nested assignments: Interpolating Registers. +- (line 11) +-* nested diversions: Diversions. (line 69) +-* nested lists ['ms']: Lists in ms. (line 122) +-* new page ('bp'): Basics. (line 91) +-* new page ('bp') <1>: Page Control. (line 10) +-* newline character: Identifiers. (line 10) +-* newline character <1>: Escapes. (line 69) +-* newline character, and translations: Character Translations. +- (line 169) +-* newline character, in strings, escaping: Strings. (line 63) +-* newline, final, stripping in diversions: Strings. (line 157) +-* next file, processing ('nx'): I/O. (line 84) +-* next free font position register ('.fp'): Font Positions. (line 30) +-* 'nf' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* 'nl' register, and '.d': Diversions. (line 69) +-* 'nl' register, difference to '.h': Diversions. (line 88) +-* 'nm' request, using '+' and '-': Expressions. (line 75) +-* no-break control character ('''): Requests. (line 6) +-* no-break control character, changing ('c2'): Character Translations. +- (line 6) +-* no-fill mode ('nf'): Manipulating Filling and Adjusting. +- (line 39) +-* no-fill mode, and '\c': Line Control. (line 60) +-* no-space mode ('ns'): Manipulating Spacing. +- (line 123) +-* node, output: Gtroff Internals. (line 6) +-* 'nr' request, and warnings: Warnings. (line 61) +-* 'nr' request, using '+' and '-': Expressions. (line 75) +-* nroff mode: Troff and Nroff Mode. +- (line 6) +-* 'nroff', the program: History. (line 22) +-* number of arguments register ('.$'): Parameters. (line 10) +-* number of registers register ('.R'): Built-in Registers. (line 18) +-* number register, creating alias ('aln'): Setting Registers. (line 112) +-* number register, removing ('rr'): Setting Registers. (line 104) +-* number register, renaming ('rnn'): Setting Registers. (line 108) +-* number registers, dumping ('pnr'): Debugging. (line 77) +-* number, input line, setting ('lf'): Debugging. (line 10) +-* number, page ('pn'): Page Layout. (line 84) +-* numbered glyph ('\N'): Character Translations. +- (line 160) +-* numbered glyph ('\N') <1>: Using Symbols. (line 201) +-* numbered list, example markup ['ms']: Lists in ms. (line 41) +-* numbers, and delimiters: Escapes. (line 65) +-* numbers, line, printing ('nm'): Miscellaneous. (line 10) +-* numerals, Roman: Assigning Formats. (line 32) +-* numeric expression, valid: Expressions. (line 83) +-* offset, page ('po'): Line Layout. (line 21) +-* 'open' request, and safer mode: Groff Options. (line 214) +-* 'opena' request, and safer mode: Groff Options. (line 214) +-* opening file ('open'): I/O. (line 200) +-* operator, scaling: Expressions. (line 54) +-* operators, arithmetic: Expressions. (line 8) +-* operators, as delimiters: Escapes. (line 67) +-* operators, comparison: Expressions. (line 15) +-* operators, extremum ('>?', ': Built-in Registers. +- (line 127) +-* output device usage number register ('.T'): Groff Options. (line 281) +-* output devices: Output device intro. (line 6) +-* output devices <1>: Output Devices. (line 6) +-* output encoding, ASCII: Groff Options. (line 250) +-* output encoding, cp1047: Groff Options. (line 264) +-* output encoding, EBCDIC: Groff Options. (line 264) +-* output encoding, latin-1 (ISO 8859-1): Groff Options. (line 254) +-* output encoding, utf-8: Groff Options. (line 259) +-* output glyphs, and input characters,compatibility with AT&T 'troff': Implementation Differences. +- (line 86) +-* output line number register ('ln'): Built-in Registers. (line 82) +-* output line, continuation ('\c'): Line Control. (line 36) +-* output line, horizontal position, register ('.k'): Page Motions. +- (line 212) +-* output node: Gtroff Internals. (line 6) +-* 'output' request, and copy-in mode: Diversions. (line 179) +-* 'output' request, and '\!': Diversions. (line 179) +-* output, flush ('fl'): Debugging. (line 87) +-* output, 'gtroff': gtroff Output. (line 6) +-* output, intermediate: gtroff Output. (line 16) +-* output, suppressing ('\O'): Suppressing output. (line 7) +-* output, transparent ('cf', 'trf'): I/O. (line 50) +-* output, transparent ('\!', '\?'): Diversions. (line 136) +-* output, transparent, incompatibilities with AT&T 'troff': Implementation Differences. +- (line 106) +-* output, troff: gtroff Output. (line 16) +-* overlapping characters: Using Symbols. (line 265) +-* overstriking glyphs ('\o'): Page Motions. (line 216) +-* 'p' unit: Measurements. (line 30) +-* 'P' unit: Measurements. (line 34) +-* packages, macros: Macro Packages. (line 6) +-* padding character, for fields ('fc'): Fields. (line 6) +-* page break, conditional ('ne'): Page Control. (line 33) +-* page control: Page Control. (line 6) +-* page ejecting register ('.pe'): Page Location Traps. (line 143) +-* page footers: Page Location Traps. (line 38) +-* page headers: Page Location Traps. (line 38) +-* page layout: Page Layout. (line 6) +-* page layout ['ms']: ms Page Layout. (line 6) +-* page length ('pl'): Page Layout. (line 13) +-* page length register ('.p'): Page Layout. (line 17) +-* page location traps: Page Location Traps. (line 6) +-* page location, vertical, marking ('mk'): Page Motions. (line 11) +-* page location, vertical, returning to marked ('rt'): Page Motions. +- (line 11) +-* page motions: Page Motions. (line 6) +-* page number ('pn'): Page Layout. (line 84) +-* page number character ('%'): Page Layout. (line 35) +-* page number character, changing ('pc'): Page Layout. (line 94) +-* page number register ('%'): Page Control. (line 27) +-* page offset ('po'): Line Layout. (line 21) +-* page orientation, landscape: Paper Size. (line 6) +-* page, new ('bp'): Page Control. (line 10) +-* paper formats: Paper Formats. (line 6) +-* paper size: Paper Size. (line 6) +-* paragraphs: Paragraphs. (line 6) +-* parameters: Parameters. (line 6) +-* parameters, and compatibility mode: Gtroff Internals. (line 91) +-* parentheses: Expressions. (line 59) +-* path, for font files: Font Directories. (line 14) +-* path, for tmac files: Macro Directories. (line 11) +-* patterns for hyphenation ('hpf'): Manipulating Hyphenation. +- (line 116) +-* PDF, embedding: Embedding PDF. (line 6) +-* 'pi' request, and 'groff': I/O. (line 159) +-* 'pi' request, and safer mode: Groff Options. (line 214) +-* 'pic', the program: gpic. (line 6) +-* pica unit ('P'): Measurements. (line 34) +-* pile, glyph ('\b'): Drawing Requests. (line 232) +-* 'pl' request, using '+' and '-': Expressions. (line 75) +-* planting a trap: Traps. (line 11) +-* platform-specific directory: Macro Directories. (line 26) +-* 'pn' request, using '+' and '-': Expressions. (line 75) +-* PNG image generation from PostScript: DESC File Format. (line 29) +-* 'po' request, using '+' and '-': Expressions. (line 75) +-* point size registers ('.s', '.ps'): Changing Type Sizes. (line 20) +-* point size registers, last-requested ('.psr', '.sr'): Fractional Type Sizes. +- (line 45) +-* point sizes, changing ('ps', '\s'): Changing Type Sizes. (line 11) +-* point sizes, fractional: Fractional Type Sizes. +- (line 6) +-* point sizes, fractional <1>: Implementation Differences. +- (line 76) +-* point unit ('p'): Measurements. (line 30) +-* polygon, drawing ('\D'p ...''): Drawing Requests. (line 158) +-* polygon, solid, drawing ('\D'P ...''): Drawing Requests. (line 167) +-* position of lowest text line ('.h'): Diversions. (line 76) +-* position, absolute, operator ('|'): Expressions. (line 70) +-* position, horizontal input line, saving ('\k'): Page Motions. +- (line 203) +-* position, horizontal, in input line, register ('hp'): Page Motions. +- (line 209) +-* position, horizontal, in output line, register ('.k'): Page Motions. +- (line 212) +-* position, vertical, current ('nl'): Page Control. (line 67) +-* position, vertical, in diversion, register ('.d'): Diversions. +- (line 69) +-* positions, font: Font Positions. (line 6) +-* post-vertical line spacing: Changing Type Sizes. (line 122) +-* post-vertical line spacing register ('.pvs'): Changing Type Sizes. +- (line 137) +-* post-vertical line spacing, changing ('pvs'): Changing Type Sizes. +- (line 137) +-* postprocessor access: Postprocessor Access. +- (line 6) +-* postprocessors: Output device intro. (line 6) +-* PostScript fonts: Font Families. (line 11) +-* PostScript, bounding box: Miscellaneous. (line 139) +-* PostScript, embedding: Embedding PostScript. +- (line 6) +-* PostScript, PNG image generation: DESC File Format. (line 29) +-* 'preconv', invoking: Invoking preconv. (line 5) +-* 'preconv', the program: preconv. (line 6) +-* prefix, for commands: Environment. (line 14) +-* preprocessor, calling convention: Preprocessors in man pages. +- (line 6) +-* preprocessors: Preprocessor Intro. (line 6) +-* preprocessors <1>: Preprocessors. (line 6) +-* previous font ('ft', '\f[]', '\fP'): Changing Fonts. (line 23) +-* previous line length ('.n'): Environments. (line 110) +-* print current page register ('.P'): Groff Options. (line 171) +-* printing backslash ('\\', '\e', '\E', '\[rs]'): Escapes. (line 74) +-* printing backslash ('\\', '\e', '\E', '\[rs]') <1>: Implementation Differences. +- (line 106) +-* printing line numbers ('nm'): Miscellaneous. (line 10) +-* printing to stderr ('tm', 'tm1', 'tmc'): Debugging. (line 27) +-* printing, zero-width ('\z', '\Z'): Page Motions. (line 220) +-* printing, zero-width ('\z', '\Z') <1>: Page Motions. (line 224) +-* process ID of 'gtroff' register ('$$'): Built-in Registers. (line 99) +-* processing next file ('nx'): I/O. (line 84) +-* properties of characters ('cflags'): Using Symbols. (line 237) +-* properties of glyphs ('cflags'): Using Symbols. (line 237) +-* 'ps' request, and constant glyph space mode: Artificial Fonts. +- (line 126) +-* 'ps' request, incompatibilities with AT&T 'troff': Implementation Differences. +- (line 76) +-* 'ps' request, using '+' and '-': Expressions. (line 75) +-* 'ps' request, with fractional type sizes: Fractional Type Sizes. +- (line 6) +-* 'pso' request, and safer mode: Groff Options. (line 214) +-* 'pvs' request, using '+' and '-': Expressions. (line 75) +-* quotes, major: Displays. (line 10) +-* quotes, trailing: Strings. (line 57) +-* 'radicalex' glyph, and 'cflags': Using Symbols. (line 265) +-* ragged-left: Manipulating Filling and Adjusting. +- (line 63) +-* ragged-right: Manipulating Filling and Adjusting. +- (line 59) +-* 'rc' request, and glyph definitions: Using Symbols. (line 326) +-* read-only register, changing format: Assigning Formats. (line 68) +-* reading from standard input ('rd'): I/O. (line 89) +-* recursive macros: while. (line 38) +-* 'refer', and macro names starting with '[' or ']': Identifiers. +- (line 46) +-* 'refer', the program: grefer. (line 6) +-* reference, 'gtroff': gtroff Reference. (line 6) +-* references ['ms']: ms Insertions. (line 6) +-* register, creating alias ('aln'): Setting Registers. (line 112) +-* register, format ('\g'): Assigning Formats. (line 75) +-* register, removing ('rr'): Setting Registers. (line 104) +-* register, renaming ('rnn'): Setting Registers. (line 108) +-* registers: Registers. (line 6) +-* registers specific to 'grohtml': grohtml specific registers and strings. +- (line 6) +-* registers, built-in: Built-in Registers. (line 6) +-* registers, interpolating ('\n'): Interpolating Registers. +- (line 6) +-* registers, number of, register ('.R'): Built-in Registers. (line 18) +-* registers, setting ('nr', '\R'): Setting Registers. (line 6) +-* removing alias, for diversion ('rm'): Strings. (line 263) +-* removing alias, for macro ('rm'): Strings. (line 263) +-* removing alias, for string ('rm'): Strings. (line 263) +-* removing diversion ('rm'): Strings. (line 224) +-* removing glyph definition ('rchar', 'rfschar'): Using Symbols. +- (line 382) +-* removing macro ('rm'): Strings. (line 224) +-* removing number register ('rr'): Setting Registers. (line 104) +-* removing request ('rm'): Strings. (line 224) +-* removing string ('rm'): Strings. (line 224) +-* renaming diversion ('rn'): Strings. (line 221) +-* renaming macro ('rn'): Strings. (line 221) +-* renaming number register ('rnn'): Setting Registers. (line 108) +-* renaming request ('rn'): Strings. (line 221) +-* renaming string ('rn'): Strings. (line 221) +-* request arguments: Request and Macro Arguments. +- (line 6) +-* request arguments, and compatibility mode: Gtroff Internals. +- (line 91) +-* request, removing ('rm'): Strings. (line 224) +-* request, renaming ('rn'): Strings. (line 221) +-* request, undefined: Comments. (line 25) +-* requests: Requests. (line 6) +-* requests for drawing: Drawing Requests. (line 6) +-* requests for input and output: I/O. (line 6) +-* requests, modifying: Requests. (line 61) +-* resolution, device: DESC File Format. (line 85) +-* resolution, horizontal: DESC File Format. (line 25) +-* resolution, horizontal, register ('.H'): Built-in Registers. +- (line 15) +-* resolution, vertical: DESC File Format. (line 135) +-* resolution, vertical, register ('.V'): Built-in Registers. (line 28) +-* returning to marked vertical page location ('rt'): Page Motions. +- (line 11) +-* revision number register ('.Y'): Built-in Registers. (line 96) +-* 'rf', the program: History. (line 6) +-* right-justifying ('rj'): Manipulating Filling and Adjusting. +- (line 250) +-* 'rj' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* 'rn' glyph, and 'cflags': Using Symbols. (line 265) +-* 'roff', the program: History. (line 17) +-* roman glyph, correction after italic glyph ('\/'): Ligatures and Kerning. +- (line 80) +-* roman glyph, correction before italic glyph ('\,'): Ligatures and Kerning. +- (line 91) +-* Roman numerals: Assigning Formats. (line 32) +-* Roman numerals, maximum and minimum: Assigning Formats. (line 59) +-* 'rq' glyph, and 'rq' string ['man']: Predefined man strings. +- (line 22) +-* 'rq' glyph, at end of sentence: Sentences. (line 18) +-* 'rq' glyph, at end of sentence <1>: Using Symbols. (line 275) +-* 'rt' request, using '+' and '-': Expressions. (line 75) +-* 'ru' glyph, and 'cflags': Using Symbols. (line 265) +-* 'RUNOFF', the program: History. (line 6) +-* 's' unit: Measurements. (line 40) +-* 's' unit <1>: Fractional Type Sizes. +- (line 6) +-* safer mode: Groff Options. (line 214) +-* safer mode <1>: Macro Directories. (line 21) +-* safer mode <2>: Built-in Registers. (line 23) +-* safer mode <3>: I/O. (line 32) +-* safer mode <4>: I/O. (line 147) +-* safer mode <5>: I/O. (line 168) +-* safer mode <6>: I/O. (line 206) +-* saving horizontal input line position ('\k'): Page Motions. (line 203) +-* scaling indicator: Measurements. (line 6) +-* scaling operator: Expressions. (line 54) +-* searching fonts: Font Directories. (line 6) +-* searching macro files: Macro Directories. (line 11) +-* searching macros: Macro Directories. (line 6) +-* seconds, current time ('seconds'): Built-in Registers. (line 31) +-* sentence space: Sentences. (line 12) +-* sentence space size register ('.sss'): Manipulating Filling and Adjusting. +- (line 151) +-* sentences: Sentences. (line 6) +-* setting diversion trap ('dt'): Diversion Traps. (line 7) +-* setting end-of-input trap ('em'): End-of-input Traps. (line 7) +-* setting input line number ('lf'): Debugging. (line 10) +-* setting input line trap ('it'): Input Line Traps. (line 8) +-* setting registers ('nr', '\R'): Setting Registers. (line 6) +-* shading filled objects ('\D'f ...''): Drawing Requests. (line 141) +-* 'shc' request, and translations: Character Translations. +- (line 173) +-* site-specific directory: Macro Directories. (line 26) +-* site-specific directory <1>: Font Directories. (line 29) +-* size of sentence space register ('.sss'): Manipulating Filling and Adjusting. +- (line 151) +-* size of type: Sizes. (line 6) +-* size of word space register ('.ss'): Manipulating Filling and Adjusting. +- (line 151) +-* size, optical, of a font: Changing Fonts. (line 71) +-* size, paper: Paper Size. (line 6) +-* sizes: Sizes. (line 6) +-* sizes, fractional: Fractional Type Sizes. +- (line 6) +-* sizes, fractional <1>: Implementation Differences. +- (line 76) +-* skew, of last glyph ('.csk'): Environments. (line 95) +-* slant, font, changing ('\S'): Artificial Fonts. (line 45) +-* 'soelim', the program: gsoelim. (line 6) +-* soft hyphen character, setting ('shc'): Manipulating Hyphenation. +- (line 243) +-* soft hyphen glyph ('hy'): Manipulating Hyphenation. +- (line 243) +-* solid circle, drawing ('\D'C ...''): Drawing Requests. (line 114) +-* solid ellipse, drawing ('\D'E ...''): Drawing Requests. (line 124) +-* solid polygon, drawing ('\D'P ...''): Drawing Requests. (line 167) +-* 'sp' request, and no-space mode: Manipulating Spacing. +- (line 123) +-* 'sp' request, and traps: Manipulating Spacing. +- (line 53) +-* 'sp' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* space between sentences: Sentences. (line 12) +-* space between sentences register ('.sss'): Manipulating Filling and Adjusting. +- (line 151) +-* space between words register ('.ss'): Manipulating Filling and Adjusting. +- (line 151) +-* space character: Escapes. (line 69) +-* space character, zero width ('\&'): Requests. (line 47) +-* space character, zero width ('\&') <1>: Ligatures and Kerning. +- (line 47) +-* space character, zero width ('\&') <2>: Drawing Requests. (line 32) +-* space characters, in expressions: Expressions. (line 86) +-* space, discardable, horizontal: Manipulating Filling and Adjusting. +- (line 183) +-* space, discarded, in traps: Manipulating Spacing. +- (line 53) +-* space, horizontal ('\h'): Page Motions. (line 103) +-* space, horizontal, unformatting: Strings. (line 157) +-* space, unbreakable: Page Motions. (line 114) +-* space, vertical, unit ('v'): Measurements. (line 58) +-* space, width of a digit ('\0'): Page Motions. (line 138) +-* spaces with 'ds': Strings. (line 57) +-* spaces, in a macro argument: Request and Macro Arguments. +- (line 10) +-* spaces, leading and trailing: Filling and Adjusting. +- (line 10) +-* spacing: Basics. (line 82) +-* spacing, manipulating: Manipulating Spacing. +- (line 6) +-* spacing, vertical: Sizes. (line 6) +-* special characters: Character Translations. +- (line 160) +-* special characters <1>: Special Characters. (line 6) +-* special characters ['ms']: ms Strings and Special Characters. +- (line 6) +-* special fonts: Using Symbols. (line 14) +-* special fonts <1>: Special Fonts. (line 6) +-* special fonts <2>: Font File Format. (line 28) +-* special fonts, emboldening: Artificial Fonts. (line 115) +-* 'special' request, and font translations: Changing Fonts. (line 55) +-* 'special' request, and glyph search order: Using Symbols. (line 14) +-* spline, drawing ('\D'~ ...''): Drawing Requests. (line 136) +-* springing a trap: Traps. (line 11) +-* 'sqrtex' glyph, and 'cflags': Using Symbols. (line 265) +-* stacking glyphs ('\b'): Drawing Requests. (line 232) +-* standard input, reading from ('rd'): I/O. (line 89) +-* stderr, printing to ('tm', 'tm1', 'tmc'): Debugging. (line 27) +-* stops, tabulator: Tab Stops. (line 6) +-* string arguments: Strings. (line 19) +-* string comparison: Operators in Conditionals. +- (line 47) +-* string expansion ('\*'): Strings. (line 19) +-* string interpolation ('\*'): Strings. (line 19) +-* string, appending ('as'): Strings. (line 176) +-* string, creating alias ('als'): Strings. (line 229) +-* string, length of ('length'): Strings. (line 211) +-* string, removing ('rm'): Strings. (line 224) +-* string, removing alias ('rm'): Strings. (line 263) +-* string, renaming ('rn'): Strings. (line 221) +-* strings: Strings. (line 6) +-* strings specific to 'grohtml': grohtml specific registers and strings. +- (line 6) +-* strings ['ms']: ms Strings and Special Characters. +- (line 6) +-* strings, multi-line: Strings. (line 63) +-* strings, shared name space with macros and diversions: Strings. +- (line 92) +-* stripping final newline in diversions: Strings. (line 157) +-* structuring source code of documents or macro packages: Requests. +- (line 14) +-* 'sty' request, and changing fonts: Changing Fonts. (line 11) +-* 'sty' request, and font positions: Font Positions. (line 60) +-* 'sty' request, and font translations: Changing Fonts. (line 55) +-* styles, font: Font Families. (line 6) +-* substring ('substring'): Strings. (line 192) +-* suppressing output ('\O'): Suppressing output. (line 7) +-* 'sv' request, and no-space mode: Page Control. (line 63) +-* switching environments ('ev'): Environments. (line 39) +-* 'sy' request, and safer mode: Groff Options. (line 214) +-* symbol: Using Symbols. (line 14) +-* symbol table, dumping ('pm'): Debugging. (line 66) +-* symbol, defining ('char'): Using Symbols. (line 326) +-* symbols, using: Using Symbols. (line 6) +-* 'system()' return value register ('systat'): I/O. (line 195) +-* tab character: Tab Stops. (line 6) +-* tab character <1>: Escapes. (line 69) +-* tab character, and translations: Character Translations. +- (line 169) +-* tab character, non-interpreted ('\t'): Tabs and Fields. (line 10) +-* tab repetition character ('tc'): Tabs and Fields. (line 129) +-* tab settings register ('.tabs'): Tabs and Fields. (line 117) +-* tab stops: Tab Stops. (line 6) +-* tab stops ['man']: Miscellaneous man macros. +- (line 10) +-* tab stops, for TTY output devices: Tabs and Fields. (line 115) +-* tab, line-tabs mode: Tabs and Fields. (line 138) +-* table of contents: Table of Contents. (line 6) +-* table of contents <1>: Leaders. (line 29) +-* table of contents, creating ['ms']: ms TOC. (line 6) +-* tables ['ms']: ms Insertions. (line 6) +-* tabs, and fields: Tabs and Fields. (line 6) +-* tabs, and macro arguments: Request and Macro Arguments. +- (line 6) +-* tabs, before comments: Comments. (line 21) +-* 'tbl', the program: gtbl. (line 6) +-* Teletype: Invoking grotty. (line 50) +-* terminal control sequences: Invoking grotty. (line 50) +-* terminal, conditional output for: Operators in Conditionals. +- (line 14) +-* text line, position of lowest ('.h'): Diversions. (line 76) +-* text, 'gtroff' processing: Text. (line 6) +-* text, justifying: Manipulating Filling and Adjusting. +- (line 6) +-* text, justifying ('rj'): Manipulating Filling and Adjusting. +- (line 250) +-* thickness of lines ('\D't ...''): Drawing Requests. (line 206) +-* three-part title ('tl'): Page Layout. (line 35) +-* 'ti' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* 'ti' request, using '+' and '-': Expressions. (line 75) +-* time, current: I/O. (line 175) +-* time, current, hours ('hours'): Built-in Registers. (line 41) +-* time, current, minutes ('minutes'): Built-in Registers. (line 37) +-* time, current, seconds ('seconds'): Built-in Registers. (line 31) +-* title line ('tl'): Page Layout. (line 35) +-* title line length register ('.lt'): Page Layout. (line 67) +-* title line, length ('lt'): Page Layout. (line 67) +-* title page, example markup: ms Cover Page Macros. +- (line 66) +-* titles: Page Layout. (line 31) +-* 'tkf' request, and font styles: Font Families. (line 59) +-* 'tkf' request, and font translations: Changing Fonts. (line 55) +-* 'tkf' request, with fractional type sizes: Fractional Type Sizes. +- (line 6) +-* 'tl' request, and 'mc': Miscellaneous. (line 102) +-* 'tm' request, and copy-in mode: Debugging. (line 30) +-* 'tm1' request, and copy-in mode: Debugging. (line 30) +-* tmac, directory: Macro Directories. (line 11) +-* tmac, path: Macro Directories. (line 11) +-* 'tmc' request, and copy-in mode: Debugging. (line 30) +-* TMPDIR, environment variable: Environment. (line 44) +-* token, input: Gtroff Internals. (line 6) +-* top margin: Page Layout. (line 20) +-* top-level diversion: Diversions. (line 12) +-* top-level diversion, and 'bp': Page Control. (line 24) +-* top-level diversion, and '\!': Diversions. (line 171) +-* top-level diversion, and '\?': Diversions. (line 176) +-* 'tr' request, and glyph definitions: Using Symbols. (line 326) +-* 'tr' request, and soft hyphen character: Manipulating Hyphenation. +- (line 243) +-* 'tr' request, incompatibilities with AT&T 'troff': Implementation Differences. +- (line 86) +-* track kerning: Ligatures and Kerning. +- (line 53) +-* track kerning, activating ('tkf'): Ligatures and Kerning. +- (line 60) +-* trailing quotes: Strings. (line 57) +-* trailing spaces: Filling and Adjusting. +- (line 10) +-* translations of characters: Character Translations. +- (line 6) +-* transparent characters: Sentences. (line 18) +-* transparent characters <1>: Using Symbols. (line 275) +-* transparent output ('cf', 'trf'): I/O. (line 50) +-* transparent output ('\!', '\?'): Diversions. (line 136) +-* transparent output, incompatibilities with AT&T 'troff': Implementation Differences. +- (line 106) +-* trap, changing location ('ch'): Page Location Traps. (line 111) +-* trap, distance, register ('.t'): Page Location Traps. (line 102) +-* trap, diversion, setting ('dt'): Diversion Traps. (line 7) +-* trap, end-of-input, setting ('em'): End-of-input Traps. (line 7) +-* trap, input line, setting ('it'): Input Line Traps. (line 8) +-* trap, planting: Traps. (line 11) +-* trap, springing: Traps. (line 11) +-* traps: Traps. (line 6) +-* traps, and discarded space: Manipulating Spacing. +- (line 53) +-* traps, and diversions: Page Location Traps. (line 166) +-* traps, blank line: Blank Line Traps. (line 6) +-* traps, diversion: Diversion Traps. (line 6) +-* traps, dumping ('ptr'): Debugging. (line 81) +-* traps, end-of-input: End-of-input Traps. (line 6) +-* traps, input line: Input Line Traps. (line 6) +-* traps, input line, and interrupted lines ('itc'): Input Line Traps. +- (line 24) +-* traps, leading spaces: Leading Spaces Traps. +- (line 6) +-* traps, page location: Page Location Traps. (line 6) +-* traps, sprung by 'bp' request ('.pe'): Page Location Traps. (line 143) +-* 'trf' request, and copy-in mode: I/O. (line 50) +-* 'trf' request, and invalid characters: I/O. (line 73) +-* 'trf' request, causing implicit linebreak: Manipulating Filling and Adjusting. +- (line 6) +-* 'trin' request, and 'asciify': Diversions. (line 195) +-* troff mode: Troff and Nroff Mode. +- (line 6) +-* troff output: gtroff Output. (line 16) +-* truncated vertical space register ('.trunc'): Page Location Traps. +- (line 131) +-* TTY, conditional output for: Operators in Conditionals. +- (line 14) +-* tutorial for macro users: Tutorial for Macro Users. +- (line 6) +-* type size: Sizes. (line 6) +-* type size registers ('.s', '.ps'): Changing Type Sizes. (line 20) +-* type sizes, changing ('ps', '\s'): Changing Type Sizes. (line 11) +-* type sizes, fractional: Fractional Type Sizes. +- (line 6) +-* type sizes, fractional <1>: Implementation Differences. +- (line 76) +-* 'u' unit: Measurements. (line 6) +-* 'uf' request, and font styles: Font Families. (line 59) +-* 'ul' glyph, and 'cflags': Using Symbols. (line 265) +-* 'ul' request, and font translations: Changing Fonts. (line 55) +-* Ultrix-specific 'man' macros: Optional man extensions. +- (line 30) +-* unary operators: Expressions. (line 21) +-* unbreakable space: Page Motions. (line 114) +-* undefined identifiers: Identifiers. (line 79) +-* undefined request: Comments. (line 25) +-* underline font ('uf'): Artificial Fonts. (line 90) +-* underlining ('ul'): Artificial Fonts. (line 64) +-* underlining, continuous ('cu'): Artificial Fonts. (line 86) +-* underscore glyph ('\[ru]'): Drawing Requests. (line 28) +-* unformatting diversions ('asciify'): Diversions. (line 195) +-* unformatting horizontal space: Strings. (line 157) +-* Unicode: Identifiers. (line 15) +-* Unicode <1>: Using Symbols. (line 201) +-* unit, 'c': Measurements. (line 27) +-* unit, 'f': Measurements. (line 43) +-* unit, 'f', and colors: Colors. (line 36) +-* unit, 'i': Measurements. (line 22) +-* unit, 'm': Measurements. (line 50) +-* unit, 'M': Measurements. (line 62) +-* unit, 'n': Measurements. (line 55) +-* unit, 'p': Measurements. (line 30) +-* unit, 'P': Measurements. (line 34) +-* unit, 's': Measurements. (line 40) +-* unit, 's' <1>: Fractional Type Sizes. +- (line 6) +-* unit, 'u': Measurements. (line 6) +-* unit, 'v': Measurements. (line 58) +-* unit, 'z': Measurements. (line 40) +-* unit, 'z' <1>: Fractional Type Sizes. +- (line 6) +-* units of measurement: Measurements. (line 6) +-* units, default: Default Units. (line 6) +-* unnamed fill colors ('\D'F...''): Drawing Requests. (line 216) +-* unnamed glyphs: Using Symbols. (line 212) +-* unnamed glyphs, accessing with '\N': Font File Format. (line 51) +-* unsafe mode: Groff Options. (line 292) +-* unsafe mode <1>: Macro Directories. (line 21) +-* unsafe mode <2>: Built-in Registers. (line 23) +-* unsafe mode <3>: I/O. (line 32) +-* unsafe mode <4>: I/O. (line 147) +-* unsafe mode <5>: I/O. (line 168) +-* unsafe mode <6>: I/O. (line 206) +-* user's macro tutorial: Tutorial for Macro Users. +- (line 6) +-* user's tutorial for macros: Tutorial for Macro Users. +- (line 6) +-* using symbols: Using Symbols. (line 6) +-* utf-8, output encoding: Groff Options. (line 259) +-* 'v' unit: Measurements. (line 58) +-* valid numeric expression: Expressions. (line 83) +-* value, incrementing without changing the register: Auto-increment. +- (line 52) +-* variables in environment: Environment. (line 6) +-* version number, major, register ('.x'): Built-in Registers. (line 88) +-* version number, minor, register ('.y'): Built-in Registers. (line 92) +-* vertical line drawing ('\L'): Drawing Requests. (line 50) +-* vertical line spacing register ('.v'): Changing Type Sizes. (line 88) +-* vertical line spacing, changing ('vs'): Changing Type Sizes. +- (line 88) +-* vertical line spacing, effective value: Changing Type Sizes. +- (line 106) +-* vertical motion ('\v'): Page Motions. (line 78) +-* vertical page location, marking ('mk'): Page Motions. (line 11) +-* vertical page location, returning to marked ('rt'): Page Motions. +- (line 11) +-* vertical position in diversion register ('.d'): Diversions. (line 69) +-* vertical position trap enable register ('.vpt'): Page Location Traps. +- (line 18) +-* vertical position traps, enabling ('vpt'): Page Location Traps. +- (line 18) +-* vertical position, current ('nl'): Page Control. (line 67) +-* vertical resolution: DESC File Format. (line 135) +-* vertical resolution register ('.V'): Built-in Registers. (line 28) +-* vertical space unit ('v'): Measurements. (line 58) +-* vertical spacing: Sizes. (line 6) +-* warnings: Debugging. (line 149) +-* warnings <1>: Warnings. (line 6) +-* warnings, level ('warn'): Debugging. (line 155) +-* what is 'groff'?: What Is groff?. (line 6) +-* while: while. (line 6) +-* 'while' request, and font translations: Changing Fonts. (line 55) +-* 'while' request, and the '!' operator: Expressions. (line 21) +-* 'while' request, confusing with 'br': while. (line 68) +-* 'while' request, operators to use with: Operators in Conditionals. +- (line 6) +-* whitespace characters: Identifiers. (line 10) +-* width escape ('\w'): Page Motions. (line 152) +-* width, of last glyph ('.w'): Environments. (line 95) +-* word space size register ('.ss'): Manipulating Filling and Adjusting. +- (line 151) +-* 'write' request, and copy-in mode: I/O. (line 212) +-* 'writec' request, and copy-in mode: I/O. (line 212) +-* 'writem' request, and copy-in mode: I/O. (line 225) +-* writing macros: Writing Macros. (line 6) +-* writing to file ('write', 'writec'): I/O. (line 212) +-* year, current, register ('year', 'yr'): Built-in Registers. (line 54) +-* 'z' unit: Measurements. (line 40) +-* 'z' unit <1>: Fractional Type Sizes. +- (line 6) +-* zero width space character ('\&'): Requests. (line 47) +-* zero width space character ('\&') <1>: Ligatures and Kerning. +- (line 47) +-* zero width space character ('\&') <2>: Drawing Requests. (line 32) +-* zero-width printing ('\z', '\Z'): Page Motions. (line 220) +-* zero-width printing ('\z', '\Z') <1>: Page Motions. (line 224) +-* zoom factor of a font ('fzoom'): Changing Fonts. (line 71) +- +diff -Nuar groff-1.22.3.old/doc/groff.texi groff-1.22.3/doc/groff.texi +--- groff-1.22.3.old/doc/groff.texi 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/doc/groff.texi 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,17157 @@ ++\input texinfo ++ ++@c ++@c Please convert this manual with `texi2dvi -e groff.texi' due to ++@c problems in texinfo regarding expansion of user-defined macros. ++@c ++@c You need texinfo 4.8 or newer to format this document! ++@c ++ ++@c %**start of header (This is for running Texinfo on a region.) ++@setfilename groff.info ++@settitle The GNU Troff Manual ++@setchapternewpage odd ++@footnotestyle separate ++@c %**end of header (This is for running Texinfo on a region.) ++ ++@documentlanguage en ++@documentencoding ISO-8859-1 ++ ++ ++@smallbook ++ ++@finalout ++ ++ ++@copying ++This manual documents GNU @code{troff} version 1.22.3. ++ ++Copyright @copyright{} 1994-2014 Free Software Foundation, Inc. ++ ++@quotation ++Permission is granted to copy, distribute and/or modify this document ++under the terms of the GNU Free Documentation License, Version 1.3 or ++any later version published by the Free Software Foundation; with no ++Invariant Sections, with the Front-Cover texts being ``A GNU Manual,'' ++and with the Back-Cover Texts as in (a) below. A copy of the license is ++included in the section entitled ``GNU Free Documentation License.'' ++ ++(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and ++modify this GNU manual. Buying copies from the FSF supports it in ++developing GNU and promoting software freedom.'' ++@end quotation ++@end copying ++ ++ ++@c We use the following indices: ++@c ++@c cindex: concepts ++@c rqindex: requests ++@c esindex: escapes ++@c vindex: registers ++@c kindex: commands in font files ++@c pindex: programs and files ++@c tindex: environment variables ++@c maindex: macros ++@c stindex: strings ++@c opindex: operators ++@c ++@c tindex and cindex are merged. ++ ++@defcodeindex rq ++@defcodeindex es ++@defcodeindex ma ++@defcodeindex st ++@defcodeindex op ++@syncodeindex tp cp ++ ++ ++@c To avoid uppercasing in @deffn while converting to info, we define ++@c our special @Var{}. ++ ++@macro Var{arg} ++@r{@slanted{\arg\}} ++@end macro ++ ++ ++@c To assure correct HTML translation, some ugly hacks are necessary. ++@c While processing a @def... request, the HTML translator looks at the ++@c next line to decide whether to start indentation, and if the line ++@c starts with @def... (e.g. @deffnx), indentation is started. We must ++@c therefore ensure that a @def... is seen, during macro expansion. ++@c ++@c The following macros have to be used: ++@c ++@c One item: ++@c ++@c @Def... ++@c ++@c Two items: ++@c ++@c @Def...List ++@c @Def...ListEnd ++@c ++@c More than two: ++@c ++@c @Def...List ++@c @Def...Item ++@c @Def...Item ++@c ... ++@c @Def...ListEnd ++@c ++@c The definition block must end with ++@c ++@c @endDef... ++@c ++@c The above is valid for texinfo 4.0f and above. ++@c ++@c By default, only the first item generates an index entry. To ++@c override this, use a variant with a trailing `x' (like ++@c `@DefmacItemx'). ++ ++ ++@c a dummy macro to assure the `@def...' ++ ++@macro defdummy ++@c ++@end macro ++ ++ ++@c definition of requests ++ ++@macro Defreq{name, arg} ++@deffn Request @t{.\name\} \arg\ ++@rqindex \name\ ++@c ++@end macro ++ ++@macro DefreqList{name, arg} ++@deffn Request @t{.\name\} \arg\ ++@defdummy ++@rqindex \name\ ++@c ++@end macro ++ ++@macro DefreqItem{name, arg} ++@deffnx Request @t{.\name\} \arg\ ++@defdummy ++@c ++@end macro ++ ++@macro DefreqItemx{name, arg} ++@deffnx Request @t{.\name\} \arg\ ++@defdummy ++@rqindex \name\ ++@c ++@end macro ++ ++@macro DefreqListEnd{name, arg} ++@deffnx Request @t{.\name\} \arg\ ++@c ++@end macro ++ ++@macro DefreqListEndx{name, arg} ++@deffnx Request @t{.\name\} \arg\ ++@rqindex \name\ ++@c ++@end macro ++ ++@macro endDefreq ++@end deffn ++@end macro ++ ++ ++@c definition of escapes ++ ++@macro Defesc{name, delimI, arg, delimII} ++@deffn Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} ++@esindex \name\ ++@c ++@end macro ++ ++@macro DefescList{name, delimI, arg, delimII} ++@deffn Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} ++@defdummy ++@esindex \name\ ++@c ++@end macro ++ ++@macro DefescItem{name, delimI, arg, delimII} ++@deffnx Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} ++@defdummy ++@c ++@end macro ++ ++@macro DefescItemx{name, delimI, arg, delimII} ++@deffnx Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} ++@defdummy ++@esindex \name\ ++@c ++@end macro ++ ++@macro DefescListEnd{name, delimI, arg, delimII} ++@deffnx Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} ++@c ++@end macro ++ ++@macro DefescListEndx{name, delimI, arg, delimII} ++@deffnx Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} ++@esindex \name\ ++@c ++@end macro ++ ++@macro endDefesc ++@end deffn ++@end macro ++ ++ ++@c definition of registers ++ ++@macro Defreg{name} ++@deffn Register @t{\\n[\name\]} ++@vindex \name\ ++@c ++@end macro ++ ++@macro DefregList{name} ++@deffn Register @t{\\n[\name\]} ++@defdummy ++@vindex \name\ ++@c ++@end macro ++ ++@macro DefregItem{name} ++@deffnx Register @t{\\n[\name\]} ++@defdummy ++@c ++@end macro ++ ++@macro DefregItemx{name} ++@deffnx Register @t{\\n[\name\]} ++@defdummy ++@vindex \name\ ++@c ++@end macro ++ ++@macro DefregListEnd{name} ++@deffnx Register @t{\\n[\name\]} ++@c ++@end macro ++ ++@macro DefregListEndx{name} ++@deffnx Register @t{\\n[\name\]} ++@vindex \name\ ++@c ++@end macro ++ ++@macro endDefreg ++@end deffn ++@end macro ++ ++ ++@c definition of registers specific to macro packages, preprocessors, etc. ++ ++@macro Defmpreg{name, package} ++@deffn Register @t{\\n[\name\]} ++@vindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro DefmpregList{name, package} ++@deffn Register @t{\\n[\name\]} ++@defdummy ++@vindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro DefmpregItem{name, package} ++@deffnx Register @t{\\n[\name\]} ++@defdummy ++@c ++@end macro ++ ++@macro DefmpregItemx{name, package} ++@deffnx Register @t{\\n[\name\]} ++@defdummy ++@vindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro DefmpregListEnd{name, package} ++@deffnx Register @t{\\n[\name\]} ++@c ++@end macro ++ ++@macro DefmpregListEndx{name, package} ++@deffnx Register @t{\\n[\name\]} ++@vindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro endDefmpreg ++@end deffn ++@end macro ++ ++ ++@c definition of macros ++ ++@macro Defmac{name, arg, package} ++@defmac @t{.\name\} \arg\ ++@maindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro DefmacList{name, arg, package} ++@defmac @t{.\name\} \arg\ ++@defdummy ++@maindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro DefmacItem{name, arg, package} ++@defmacx @t{.\name\} \arg\ ++@defdummy ++@c ++@end macro ++ ++@macro DefmacItemx{name, arg, package} ++@defmacx @t{.\name\} \arg\ ++@defdummy ++@maindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro DefmacListEnd{name, arg, package} ++@defmacx @t{.\name\} \arg\ ++@c ++@end macro ++ ++@macro DefmacListEndx{name, arg, package} ++@defmacx @t{.\name\} \arg\ ++@maindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro endDefmac ++@end defmac ++@end macro ++ ++ ++@c definition of strings ++ ++@macro Defstr{name, package} ++@deffn String @t{\\*[\name\]} ++@stindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro DefstrList{name, package} ++@deffn String @t{\\*[\name\]} ++@defdummy ++@stindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro DefstrItem{name, package} ++@deffnx String @t{\\*[\name\]} ++@defdummy ++@c ++@end macro ++ ++@macro DefstrItemx{name, package} ++@deffnx String @t{\\*[\name\]} ++@defdummy ++@stindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro DefstrListEnd{name, package} ++@deffnx String @t{\\*[\name\]} ++@c ++@end macro ++ ++@macro DefstrListEndx{name, package} ++@deffnx String @t{\\*[\name\]} ++@stindex \name\ @r{[}\package\@r{]} ++@c ++@end macro ++ ++@macro endDefstr ++@end deffn ++@end macro ++ ++ ++@c our example macros ++ ++@macro Example ++@example ++@group ++@end macro ++ ++@macro endExample ++@end group ++@end example ++@end macro ++ ++@macro CartoucheExample ++@cartouche ++@example ++@end macro ++ ++@macro endCartoucheExample ++@end example ++@end cartouche ++@end macro ++ ++ ++@c ++ ++@tex ++\gdef\Langlemacro{\angleleft} ++\gdef\Ranglemacro{\angleright} ++@end tex ++ ++@iftex ++@set Langlemacro @Langlemacro ++@set Ranglemacro @Ranglemacro ++@end iftex ++ ++@ifnottex ++@set Langlemacro < ++@set Ranglemacro > ++@end ifnottex ++ ++@macro angles{text} ++@value{Langlemacro}@r{\text\}@value{Ranglemacro} ++@end macro ++ ++ ++@c a <= sign ++@c ++@c Since expansion of macros has changed between texinfo 4.x and 5.x, ++@c we can't define a macro but have to use @value directly. ++ ++@tex ++\gdef\LE{\le} ++@end tex ++ ++@iftex ++@set LE @LE ++@end iftex ++ ++@ifnottex ++@set LE <= ++@end ifnottex ++ ++ ++@c Special care is required with parentheses, brackets, and braces: ++@c ++@c . Real parentheses in @deffn produce an error while compiling with ++@c TeX. ++@c . Real brackets use the wrong font in @deffn, overriding @t{}. ++@c ++@c . @{ and @} fail with info if used in a macro. ++@c ++@c Since macros aren't expanded in @deffn during -E, the following ++@c definitions are for non-TeX only. ++@c ++@c This is true for texinfo 4.0 and above. ++ ++@iftex ++@set Lparenmacro @lparen ++@set Rparenmacro @rparen ++@set Lbrackmacro @lbrack ++@set Rbrackmacro @rbrack ++@set Lbracemacro @{ ++@set Rbracemacro @} ++@end iftex ++ ++@ifnottex ++@set Lparenmacro ( ++@set Rparenmacro ) ++@set Lbrackmacro [ ++@set Rbrackmacro ] ++@set Lbracemacro @{ ++@set Rbracemacro @} ++@end ifnottex ++ ++@macro Lparen{} ++@value{Lparenmacro} ++@end macro ++@macro Rparen{} ++@value{Rparenmacro} ++@end macro ++@macro Lbrack{} ++@value{Lbrackmacro} ++@end macro ++@macro Rbrack{} ++@value{Rbrackmacro} ++@end macro ++@macro Lbrace{} ++@value{Lbracemacro} ++@end macro ++@macro Rbrace{} ++@value{Rbracemacro} ++@end macro ++ ++ ++@c This suppresses the word `Appendix' in the appendix headers. ++ ++@tex ++\gdef\gobblefirst#1#2{#2} ++\gdef\putwordAppendix{\gobblefirst} ++@end tex ++ ++ ++@c We map some latin-1 characters to corresponding texinfo macros. ++@c Newer versions of texinfo.tex have similar code included already. ++ ++@tex ++\global\catcode`^^e4\active % ++\gdef^^e4{\"a} ++\global\catcode`^^c4\active % ++\gdef^^c4{\"A} ++\global\catcode`^^e9\active % ++\gdef^^e9{\'e} ++\global\catcode`^^c9\active % ++\gdef^^c9{\'E} ++\global\catcode`^^f6\active % ++\gdef^^f6{\"o} ++\global\catcode`^^d6\active % ++\gdef^^d6{\"O} ++\global\catcode`^^fc\active % ++\gdef^^fc{\"u} ++\global\catcode`^^dc\active % ++\gdef^^dc{\"U} ++\global\catcode`^^e6\active % ++\gdef^^e6{\ae} ++\global\catcode`^^c6\active % ++\gdef^^c6{\AE} ++\global\catcode`^^df\active % ++\gdef^^df{\ss} ++@end tex ++ ++ ++@c Note: We say `Roman numerals' but `roman font'. ++ ++ ++@dircategory Typesetting ++@direntry ++* Groff: (groff). The GNU troff document formatting system. ++@end direntry ++ ++ ++@titlepage ++@title groff ++@subtitle The GNU implementation of @code{troff} ++@subtitle Edition 1.22.3 ++@subtitle Autumn 2014 ++@author by Trent A.@tie{}Fisher ++@author and Werner Lemberg (@email{bug-groff@@gnu.org}) ++ ++@page ++@vskip 0pt plus 1filll ++@insertcopying ++@end titlepage ++ ++@contents ++ ++@ifnottex ++@node Top, Introduction, (dir), (dir) ++@top GNU troff ++@end ifnottex ++ ++@menu ++* Introduction:: ++* Invoking groff:: ++* Tutorial for Macro Users:: ++* Macro Packages:: ++* gtroff Reference:: ++* Preprocessors:: ++* Output Devices:: ++* File formats:: ++* Installation:: ++* Copying This Manual:: ++* Request Index:: ++* Escape Index:: ++* Operator Index:: ++* Register Index:: ++* Macro Index:: ++* String Index:: ++* Glyph Name Index:: ++* Font File Keyword Index:: ++* Program and File Index:: ++* Concept Index:: ++@end menu ++ ++@ifnottex ++@insertcopying ++@end ifnottex ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Introduction, Invoking groff, Top, Top ++@chapter Introduction ++@cindex introduction ++ ++GNU @code{troff} (or @code{groff}) is a system for typesetting ++documents. @code{troff} is very flexible and has been used extensively ++for some thirty years. It is well entrenched in the @acronym{UNIX} ++community. ++ ++@menu ++* What Is groff?:: ++* History:: ++* groff Capabilities:: ++* Macro Package Intro:: ++* Preprocessor Intro:: ++* Output device intro:: ++* Credits:: ++@end menu ++ ++ ++@c ===================================================================== ++ ++@node What Is groff?, History, Introduction, Introduction ++@section What Is @code{groff}? ++@cindex what is @code{groff}? ++@cindex @code{groff} -- what is it? ++ ++@code{groff} belongs to an older generation of document preparation ++systems, which operate more like compilers than the more recent ++interactive @acronym{WYSIWYG}@footnote{What You See Is What You Get} ++systems. @code{groff} and its contemporary counterpart, @TeX{}, both ++work using a @dfn{batch} paradigm: The input (or @dfn{source}) files are ++normal text files with embedded formatting commands. These files can ++then be processed by @code{groff} to produce a typeset document on a ++variety of devices. ++ ++@code{groff} should not be confused with a @dfn{word processor}, an ++integrated system of editor and text formatter. Also, many word ++processors follow the @acronym{WYSIWYG} paradigm discussed earlier. ++ ++Although @acronym{WYSIWYG} systems may be easier to use, they have a ++number of disadvantages compared to @code{troff}: ++ ++@itemize @bullet ++@item ++They must be used on a graphics display to work on a document. ++ ++@item ++Most of the @acronym{WYSIWYG} systems are either non-free or are not ++very portable. ++ ++@item ++@code{troff} is firmly entrenched in all @acronym{UNIX} systems. ++ ++@item ++It is difficult to have a wide range of capabilities within the confines ++of a GUI/window system. ++ ++@item ++It is more difficult to make global changes to a document. ++@end itemize ++ ++@quotation ++``GUIs normally make it simple to accomplish simple actions and ++impossible to accomplish complex actions.'' --Doug Gwyn (22/Jun/91 in ++@code{comp.unix.wizards}) ++@end quotation ++ ++ ++@c ===================================================================== ++ ++@node History, groff Capabilities, What Is groff?, Introduction ++@section History ++@cindex history ++ ++@cindex @code{RUNOFF}, the program ++@cindex @code{rf}, the program ++@code{troff} can trace its origins back to a formatting program called ++@code{RUNOFF}, written by Jerry Saltzer, which ran on the @acronym{CTSS} ++(@emph{Compatible Time Sharing System}, a project of MIT, the ++Massachusetts Institute of Technology) in the ++mid-sixties.@footnote{Jerome H.@: Saltzer, a grad student then, later a ++Professor of Electrical Engineering, now retired. Saltzer's PhD thesis ++was the first application for @code{RUNOFF} and is available from the ++MIT Libraries.} The name came from the use of the phrase ``run off a ++document'', meaning to print it out. ++@c ++@c Tom Van Vleck writes about the following: ++@c ++@c I am not sure about this.. I think the BCPL runoff was the port to ++@c the 635 architecture, and that the order of events is ++@c 1. CTSS runoff ++@c 2. BCPL runoff on Multics ++@c 3. BCPL runoff on 635 ++@c 4. rf on PDP-7 ++@c ++Bob Morris ported it to the 635 architecture and called the program ++@code{roff} (an abbreviation of @code{runoff}). It was rewritten as ++@code{rf} for the @w{PDP-7} (before having @acronym{UNIX}), and at the ++same time (1969), Doug McIllroy rewrote an extended and simplified ++version of @code{roff} in the @acronym{BCPL} programming language. ++ ++@cindex @code{roff}, the program ++In 1971, the UNIX developers wanted to get a @w{PDP-11}, and to justify ++the cost, proposed the development of a document formatting system for ++the @acronym{AT&T} patents division. This first formatting program was ++a reimplementation of McIllroy's @code{roff}, written by J.@tie{}F.@: ++Ossanna. ++ ++@cindex @code{nroff}, the program ++When they needed a more flexible language, a new version of @code{roff} ++called @code{nroff} (``Newer @code{roff}'') was written. It had a much ++more complicated syntax, but provided the basis for all future versions. ++When they got a Graphic Systems CAT Phototypesetter, Ossanna wrote a ++version of @code{nroff} that would drive it. It was dubbed ++@code{troff}, for ``typesetter @code{roff}'', although many people have ++speculated that it actually means ``Times @code{roff}'' because of the ++use of the Times font family in @code{troff} by default. As such, the ++name @code{troff} is pronounced `@w{t-roff}' rather than `trough'. ++ ++With @code{troff} came @code{nroff} (they were actually the same program ++except for some @samp{#ifdef}s), which was for producing output for line ++printers and character terminals. It understood everything @code{troff} ++did, and ignored the commands that were not applicable (e.g.@: font ++changes). ++ ++Since there are several things that cannot be done easily in ++@code{troff}, work on several preprocessors began. These programs would ++transform certain parts of a document into @code{troff}, which made a ++very natural use of pipes in @acronym{UNIX}. ++ ++The @code{eqn} preprocessor allowed mathematical formul to be specified ++in a much simpler and more intuitive manner. @code{tbl} is a ++preprocessor for formatting tables. The @code{refer} preprocessor (and ++the similar program, @code{bib}) processes citations in a document ++according to a bibliographic database. ++ ++Unfortunately, Ossanna's @code{troff} was written in @w{PDP-11} assembly ++language and produced output specifically for the CAT phototypesetter. ++He rewrote it in C, although it was now 7000@tie{}lines of uncommented ++code and still dependent on the CAT@. As the CAT became less common, and ++was no longer supported by the manufacturer, the need to make it support ++other devices became a priority. However, before this could be done, ++Ossanna died by a severe heart attack in a hospital while recovering ++from a previous one. ++ ++@pindex ditroff ++@cindex @code{ditroff}, the program ++So, Brian Kernighan took on the task of rewriting @code{troff}. The ++newly rewritten version produced device independent code that was very ++easy for postprocessors to read and translate to the appropriate printer ++codes. Also, this new version of @code{troff} (called @code{ditroff} ++for ``device independent @code{troff}'') had several extensions, which ++included drawing functions. ++ ++Due to the additional abilities of the new version of @code{troff}, ++several new preprocessors appeared. The @code{pic} preprocessor ++provides a wide range of drawing functions. Likewise the @code{ideal} ++preprocessor did the same, although via a much different paradigm. The ++@code{grap} preprocessor took specifications for graphs, but, unlike ++other preprocessors, produced @code{pic} code. ++ ++James Clark began work on a GNU implementation of @code{ditroff} in ++early@tie{}1989. The first version, @code{groff}@tie{}0.3.1, was ++released June@tie{}1990. @code{groff} included: ++ ++@itemize @bullet ++@item ++A replacement for @code{ditroff} with many extensions. ++ ++@item ++The @code{soelim}, @code{pic}, @code{tbl}, and @code{eqn} preprocessors. ++ ++@item ++Postprocessors for character devices, @sc{PostScript}, @TeX{} DVI, and ++X@tie{}Windows. GNU @code{troff} also eliminated the need for a ++separate @code{nroff} program with a postprocessor that would produce ++@acronym{ASCII} output. ++ ++@item ++A version of the @file{me} macros and an implementation of the ++@file{man} macros. ++@end itemize ++ ++Also, a front-end was included that could construct the, sometimes ++painfully long, pipelines required for all the post- and preprocessors. ++ ++Development of GNU @code{troff} progressed rapidly, and saw the ++additions of a replacement for @code{refer}, an implementation of the ++@file{ms} and @file{mm} macros, and a program to deduce how to format a ++document (@code{grog}). ++ ++It was declared a stable (i.e.@: non-beta) package with the release of ++version@tie{}1.04 around November@tie{}1991. ++ ++Beginning in@tie{}1999, @code{groff} has new maintainers (the package ++was an orphan for a few years). As a result, new features and programs ++like @code{grn}, a preprocessor for gremlin images, and an output device ++to produce @acronym{HTML} and @acronym{XHTML} have been added. ++ ++ ++@c ===================================================================== ++ ++@node groff Capabilities, Macro Package Intro, History, Introduction ++@section @code{groff} Capabilities ++@cindex @code{groff} capabilities ++@cindex capabilities of @code{groff} ++ ++So what exactly is @code{groff} capable of doing? @code{groff} provides ++a wide range of low-level text formatting operations. Using these, it ++is possible to perform a wide range of formatting tasks, such as ++footnotes, table of contents, multiple columns, etc. Here's a list of ++the most important operations supported by @code{groff}: ++ ++@itemize @bullet ++@item ++text filling, adjusting, and centering ++ ++@item ++hyphenation ++ ++@item ++page control ++ ++@item ++font and glyph size control ++ ++@item ++vertical spacing (e.g.@: double-spacing) ++ ++@item ++line length and indenting ++ ++@item ++macros, strings, diversions, and traps ++ ++@item ++number registers ++ ++@item ++tabs, leaders, and fields ++ ++@item ++input and output conventions and character translation ++ ++@item ++overstrike, bracket, line drawing, and zero-width functions ++ ++@item ++local horizontal and vertical motions and the width function ++ ++@item ++three-part titles ++ ++@item ++output line numbering ++ ++@item ++conditional acceptance of input ++ ++@item ++environment switching ++ ++@item ++insertions from the standard input ++ ++@item ++input/output file switching ++ ++@item ++output and error messages ++@end itemize ++ ++ ++@c ===================================================================== ++ ++@node Macro Package Intro, Preprocessor Intro, groff Capabilities, Introduction ++@section Macro Packages ++@cindex macro packages ++ ++Since @code{groff} provides such low-level facilities, it can be quite ++difficult to use by itself. However, @code{groff} provides a ++@dfn{macro} facility to specify how certain routine operations ++(e.g.@tie{}starting paragraphs, printing headers and footers, etc.)@: ++should be done. These macros can be collected together into a ++@dfn{macro package}. There are a number of macro packages available; ++the most common (and the ones described in this manual) are @file{man}, ++@file{mdoc}, @file{me}, @file{ms}, and @file{mm}. ++ ++ ++@c ===================================================================== ++ ++@node Preprocessor Intro, Output device intro, Macro Package Intro, Introduction ++@section Preprocessors ++@cindex preprocessors ++ ++Although @code{groff} provides most functions needed to format a ++document, some operations would be unwieldy (e.g.@: to draw pictures). ++Therefore, programs called @dfn{preprocessors} were written that ++understand their own language and produce the necessary @code{groff} ++operations. These preprocessors are able to differentiate their own ++input from the rest of the document via markers. ++ ++To use a preprocessor, @acronym{UNIX} pipes are used to feed the output ++from the preprocessor into @code{groff}. Any number of preprocessors ++may be used on a given document; in this case, the preprocessors are ++linked together into one pipeline. However, with @code{groff}, the user ++does not need to construct the pipe, but only tell @code{groff} what ++preprocessors to use. ++ ++@code{groff} currently has preprocessors for producing tables ++(@code{tbl}), typesetting equations (@code{eqn}), drawing pictures ++(@code{pic} and @code{grn}), processing bibliographies ++(@code{refer}), and drawing chemical structures (@code{chem}). An ++associated program that is useful when dealing with preprocessors is ++@code{soelim}. ++ ++A free implementation of @code{grap}, a preprocessor for drawing graphs, ++can be obtained as an extra package; @code{groff} can use @code{grap} ++also. ++ ++Unique to @code{groff} is the @code{preconv} preprocessor that enables ++@code{groff} to handle documents in various input encodings. ++ ++There are other preprocessors in existence, but, unfortunately, no free ++implementations are available. Among them is a preprocessor for drawing ++mathematical pictures (@code{ideal}). ++ ++ ++@c ===================================================================== ++ ++@node Output device intro, Credits, Preprocessor Intro, Introduction ++@section Output Devices ++@cindex postprocessors ++@cindex output devices ++@cindex devices for output ++ ++@code{groff} actually produces device independent code that may be fed ++into a postprocessor to produce output for a particular device. ++Currently, @code{groff} has postprocessors for @sc{PostScript} devices, ++character terminals, X@tie{}Windows (for previewing), @TeX{} DVI format, ++HP LaserJet@tie{}4 and Canon LBP printers (which use @acronym{CAPSL}), ++@acronym{HTML}, @acronym{XHTML}, and PDF. ++ ++ ++@c ===================================================================== ++ ++@node Credits, , Output device intro, Introduction ++@section Credits ++@cindex credits ++ ++Large portions of this manual were taken from existing documents, most ++notably, the manual pages for the @code{groff} package by James Clark, ++and Eric Allman's papers on the @file{me} macro package. ++ ++The section on the @file{man} macro package is partly based on ++Susan@tie{}G.@: Kleinmann's @file{groff_man} manual page written for the ++Debian GNU/Linux system. ++ ++Larry Kollar contributed the section in the @file{ms} macro package. ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Invoking groff, Tutorial for Macro Users, Introduction, Top ++@chapter Invoking @code{groff} ++@cindex invoking @code{groff} ++@cindex @code{groff} invocation ++ ++This section focuses on how to invoke the @code{groff} front end. This ++front end takes care of the details of constructing the pipeline among ++the preprocessors, @code{gtroff} and the postprocessor. ++ ++It has become a tradition that GNU programs get the prefix @samp{g} to ++distinguish it from its original counterparts provided by the host (see ++@ref{Environment}, for more details). Thus, for example, @code{geqn} is ++GNU @code{eqn}. On operating systems like GNU/Linux or the Hurd, which ++don't contain proprietary versions of @code{troff}, and on ++MS-DOS/MS-Windows, where @code{troff} and associated programs are not ++available at all, this prefix is omitted since GNU @code{troff} is the ++only used incarnation of @code{troff}. Exception: @samp{groff} is never ++replaced by @samp{roff}. ++ ++In this document, we consequently say @samp{gtroff} when talking about ++the GNU @code{troff} program. All other implementations of @code{troff} ++are called @acronym{AT&T} @code{troff}, which is the common origin of all ++@code{troff} derivates (with more or less compatible changes). ++Similarly, we say @samp{gpic}, @samp{geqn}, etc. ++ ++@menu ++* Groff Options:: ++* Environment:: ++* Macro Directories:: ++* Font Directories:: ++* Paper Size:: ++* Invocation Examples:: ++@end menu ++ ++ ++@c ===================================================================== ++ ++@node Groff Options, Environment, Invoking groff, Invoking groff ++@section Options ++@cindex options ++ ++@pindex groff ++@pindex gtroff ++@pindex gpic ++@pindex geqn ++@pindex ggrn ++@pindex grap ++@pindex gtbl ++@pindex gchem ++@pindex grefer ++@pindex gsoelim ++@pindex preconv ++@code{groff} normally runs the @code{gtroff} program and a ++postprocessor appropriate for the selected device. The default device ++is @samp{ps} (but it can be changed when @code{groff} is configured and ++built). It can optionally preprocess with any of @code{gpic}, ++@code{geqn}, @code{gtbl}, @code{ggrn}, @code{grap}, @code{gchem}, ++@code{grefer}, @code{gsoelim}, or @code{preconv}. ++ ++This section only documents options to the @code{groff} front end. Many ++of the arguments to @code{groff} are passed on to @code{gtroff}, ++therefore those are also included. Arguments to pre- or postprocessors ++can be found in @ref{Invoking gpic}, @ref{Invoking geqn}, @ref{Invoking ++gtbl}, @ref{Invoking ggrn}, @ref{Invoking grefer}, @ref{Invoking gchem}, ++@ref{Invoking gsoelim}, @ref{Invoking preconv}, @ref{Invoking grotty}, ++@ref{Invoking grops}, @ref{Invoking gropdf}, @ref{Invoking grohtml}, ++@ref{Invoking grodvi}, @ref{Invoking grolj4}, @ref{Invoking grolbp}, and ++@ref{Invoking gxditview}. ++ ++The command line format for @code{groff} is: ++ ++@Example ++groff [ -abceghijklpstvzCEGNRSUVXZ ] [ -d@var{cs} ] [ -D@var{arg} ] ++ [ -f@var{fam} ] [ -F@var{dir} ] [ -I@var{dir} ] [ -K@var{arg} ] ++ [ -L@var{arg} ] [ -m@var{name} ] [ -M@var{dir} ] [ -n@var{num} ] ++ [ -o@var{list} ] [ -P@var{arg} ] [ -r@var{cn} ] [ -T@var{dev} ] ++ [ -w@var{name} ] [ -W@var{name} ] [ @var{files}@dots{} ] ++@endExample ++ ++The command line format for @code{gtroff} is as follows. ++ ++@Example ++gtroff [ -abcivzCERU ] [ -d@var{cs} ] [ -f@var{fam} ] [ -F@var{dir} ] ++ [ -m@var{name} ] [ -M@var{dir} ] [ -n@var{num} ] [ -o@var{list} ] ++ [ -r@var{cn} ] [ -T@var{name} ] [ -w@var{name} ] [ -W@var{name} ] ++ [ @var{files}@dots{} ] ++@endExample ++ ++@noindent ++Obviously, many of the options to @code{groff} are actually passed on to ++@code{gtroff}. ++ ++Options without an argument can be grouped behind a ++single@tie{}@option{-}. A filename of@tie{}@file{-} denotes the ++standard input. It is possible to have whitespace between an option and ++its parameter. ++ ++The @code{grog} command can be used to guess the correct @code{groff} ++command to format a file. ++ ++Here's the description of the command-line options: ++ ++@cindex command-line options ++@table @samp ++@item -a ++@cindex @acronym{ASCII} approximation output register (@code{.A}) ++Generate an @acronym{ASCII} approximation of the typeset output. The ++read-only register @code{.A} is then set to@tie{}1. @xref{Built-in ++Registers}. A typical example is ++ ++@Example ++groff -a -man -Tdvi troff.man | less ++@endExample ++ ++@noindent ++which shows how lines are broken for the DVI device. Note that this ++option is rather useless today since graphic output devices are ++available virtually everywhere. ++ ++@item -b ++Print a backtrace with each warning or error message. This backtrace ++should help track down the cause of the error. The line numbers given ++in the backtrace may not always be correct: @code{gtroff} can get ++confused by @code{as} or @code{am} requests while counting line numbers. ++ ++@item -c ++Suppress color output. ++ ++@item -C ++Enable compatibility mode. @xref{Implementation Differences}, for the ++list of incompatibilities between @code{groff} and @acronym{AT&T} ++@code{troff}. ++ ++@item -d@var{c}@var{s} ++@itemx -d@var{name}=@var{s} ++Define @var{c} or @var{name} to be a string@tie{}@var{s}. ++@var{c}@tie{}must be a one-letter name; @var{name} can be of arbitrary ++length. All string assignments happen before loading any macro file ++(including the start-up file). ++ ++@item -D@var{arg} ++Set default input encoding used by @code{preconv} to @var{arg}. Implies ++@option{-k}. ++ ++@item -e ++Preprocess with @code{geqn}. ++ ++@item -E ++Inhibit all error messages. ++ ++@item -f@var{fam} ++Use @var{fam} as the default font family. @xref{Font Families}. ++ ++@item -F@var{dir} ++Search @file{@var{dir}} for subdirectories @file{dev@var{name}} ++(@var{name} is the name of the device), for the @file{DESC} file, and ++for font files before looking in the standard directories (@pxref{Font ++Directories}). This option is passed to all pre- and postprocessors ++using the @env{GROFF_FONT_PATH} environment variable. ++ ++@item -g ++Preprocess with @code{ggrn}. ++ ++@item -G ++Preprocess with @code{grap}. Implies @option{-p}. ++ ++@item -h ++Print a help message. ++ ++@item -i ++Read the standard input after all the named input files have been ++processed. ++ ++@item -I@var{dir} ++This option may be used to specify a directory to search for files. ++It is passed to the following programs: ++ ++@itemize ++@item ++@code{gsoelim} (see @ref{gsoelim} for more details); ++it also implies @code{groff}'s @option{-s} option. ++ ++@item ++@code{gtroff}; it is used to search files named in the @code{psbb} and ++@code{so} requests. ++ ++@item ++@code{grops}; it is used to search files named in the ++@w{@code{\X'ps: import}} and @w{@code{\X'ps: file}} escapes. ++@end itemize ++ ++The current directory is always searched first. This option may be ++specified more than once; the directories are searched in the order ++specified. No directory search is performed for files specified using ++an absolute path. ++ ++@item -j ++Preprocess with @code{gchem}. Implies @option{-p}. ++ ++@item -k ++Preprocess with @code{preconv}. This is run before any other ++preprocessor. Please refer to @code{preconv}'s manual page for its ++behaviour if no @option{-K} (or @option{-D}) option is specified. ++ ++@item -K@var{arg} ++Set input encoding used by preconv to @var{arg}. Implies @option{-k}. ++ ++@item -l ++Send the output to a spooler for printing. The command used for this is ++specified by the @code{print} command in the device description file ++(see @ref{Font Files}, for more info). If not present, @option{-l} is ++ignored. ++ ++@item -L@var{arg} ++Pass @var{arg} to the spooler. Each argument should be passed with a ++separate @option{-L} option. Note that @code{groff} does not prepend a ++@samp{-} to @var{arg} before passing it to the postprocessor. If the ++@code{print} keyword in the device description file is missing, ++@option{-L} is ignored. ++ ++@item -m@var{name} ++Read in the file @file{@var{name}.tmac}. Normally @code{groff} searches ++for this in its macro directories. If it isn't found, it tries ++@file{tmac.@var{name}} (searching in the same directories). ++ ++@item -M@var{dir} ++Search directory @file{@var{dir}} for macro files before the standard ++directories (@pxref{Macro Directories}). ++ ++@item -n@var{num} ++Number the first page @var{num}. ++ ++@item -N ++Don't allow newlines with @code{eqn} delimiters. This is the same as ++the @option{-N} option in @code{geqn}. ++ ++@item -o@var{list} ++@cindex print current page register (@code{.P}) ++Output only pages in @var{list}, which is a comma-separated list of page ++ranges; @samp{@var{n}} means print page@tie{}@var{n}, ++@samp{@var{m}-@var{n}} means print every page between @var{m} ++and@tie{}@var{n}, @samp{-@var{n}} means print every page up ++to@tie{}@var{n}, @samp{@var{n}-} means print every page beginning ++with@tie{}@var{n}. @code{gtroff} exits after printing the last page in ++the list. All the ranges are inclusive on both ends. ++ ++Within @code{gtroff}, this information can be extracted with the ++@samp{.P} register. @xref{Built-in Registers}. ++ ++If your document restarts page numbering at the beginning of each ++chapter, then @code{gtroff} prints the specified page range for each ++chapter. ++ ++@item -p ++Preprocess with @code{gpic}. ++ ++@item -P@var{arg} ++Pass @var{arg} to the postprocessor. Each argument should be passed ++with a separate @option{-P} option. Note that @code{groff} does not ++prepend @samp{-} to @var{arg} before passing it to the postprocessor. ++ ++@item -r@var{c}@var{n} ++@itemx -r@var{name}=@var{n} ++Set number register@tie{}@var{c} or @var{name} to the ++value@tie{}@var{n}. @var{c}@tie{}must be a one-letter name; @var{name} ++can be of arbitrary length. @var{n}@tie{}can be any @code{gtroff} ++numeric expression. All register assignments happen before loading any ++macro file (including the start-up file). ++ ++@item -R ++Preprocess with @code{grefer}. No mechanism is provided for passing ++arguments to @code{grefer} because most @code{grefer} options have ++equivalent commands that can be included in the file. @xref{grefer}, ++for more details. ++ ++@pindex troffrc ++@pindex troffrc-end ++Note that @code{gtroff} also accepts a @option{-R} option, which is not ++accessible via @code{groff}. This option prevents the loading of the ++@file{troffrc} and @file{troffrc-end} files. ++ ++@item -s ++Preprocess with @code{gsoelim}. ++ ++@item -S ++@cindex @code{open} request, and safer mode ++@cindex @code{opena} request, and safer mode ++@cindex @code{pso} request, and safer mode ++@cindex @code{sy} request, and safer mode ++@cindex @code{pi} request, and safer mode ++@cindex safer mode ++@cindex mode, safer ++Safer mode. Pass the @option{-S} option to @code{gpic} and disable the ++@code{open}, @code{opena}, @code{pso}, @code{sy}, and @code{pi} ++requests. For security reasons, this is enabled by default. ++ ++@item -t ++Preprocess with @code{gtbl}. ++ ++@item -T@var{dev} ++Prepare output for device @var{dev}. The default device is @samp{ps}, ++unless changed when @code{groff} was configured and built. The ++following are the output devices currently available: ++ ++@table @code ++@item ps ++For @sc{PostScript} printers and previewers. ++ ++@item pdf ++For PDF viewers or printers. ++ ++@item dvi ++For @TeX{} DVI format. ++ ++@item X75 ++For a 75@dmn{dpi} X11 previewer. ++ ++@item X75-12 ++For a 75@dmn{dpi} X11 previewer with a 12@dmn{pt} base font in the ++document. ++ ++@item X100 ++For a 100@dmn{dpi} X11 previewer. ++ ++@item X100-12 ++For a 100@dmn{dpi} X11 previewer with a 12@dmn{pt} base font in the ++document. ++ ++@item ascii ++@cindex encoding, output, @acronym{ASCII} ++@cindex @acronym{ASCII}, output encoding ++@cindex output encoding, @acronym{ASCII} ++For typewriter-like devices using the (7-bit) @acronym{ASCII} ++character set. ++ ++@item latin1 ++@cindex encoding, output, @w{latin-1} (ISO @w{8859-1}) ++@cindex @w{latin-1} (ISO @w{8859-1}), output encoding ++@cindex ISO @w{8859-1} (@w{latin-1}), output encoding ++@cindex output encoding, @w{latin-1} (ISO @w{8859-1}) ++For typewriter-like devices that support the @w{Latin-1} ++(ISO@tie{}@w{8859-1}) character set. ++ ++@item utf8 ++@cindex encoding, output, @w{utf-8} ++@cindex @w{utf-8}, output encoding ++@cindex output encoding, @w{utf-8} ++For typewriter-like devices that use the Unicode (ISO@tie{}10646) ++character set with @w{UTF-8} encoding. ++ ++@item cp1047 ++@cindex encoding, output, @acronym{EBCDIC} ++@cindex @acronym{EBCDIC}, output encoding ++@cindex output encoding, @acronym{EBCDIC} ++@cindex encoding, output, cp1047 ++@cindex cp1047, output encoding ++@cindex output encoding, cp1047 ++@cindex IBM cp1047 output encoding ++For typewriter-like devices that use the @acronym{EBCDIC} encoding IBM ++cp1047. ++ ++@item lj4 ++For HP LaserJet4-compatible (or other PCL5-compatible) printers. ++ ++@item lbp ++For Canon @acronym{CAPSL} printers (@w{LBP-4} and @w{LBP-8} series laser ++printers). ++ ++@pindex pre-grohtml ++@pindex post-grohtml ++@cindex @code{grohtml}, the program ++@item html ++@itemx xhtml ++To produce @acronym{HTML} and @acronym{XHTML} output, respectively. ++Note that this driver consists of two parts, a preprocessor ++(@code{pre-grohtml}) and a postprocessor (@code{post-grohtml}). ++@end table ++ ++@cindex output device name string register (@code{.T}) ++@cindex output device usage number register (@code{.T}) ++The predefined @code{gtroff} string register @code{.T} contains the ++current output device; the read-only number register @code{.T} is set ++to@tie{}1 if this option is used (which is always true if @code{groff} ++is used to call @code{gtroff}). @xref{Built-in Registers}. ++ ++The postprocessor to be used for a device is specified by the ++@code{postpro} command in the device description file. (@xref{Font ++Files}, for more info.) This can be overridden with the @option{-X} ++option. ++ ++@item -U ++@cindex mode, unsafe ++@cindex unsafe mode ++Unsafe mode. This enables the @code{open}, @code{opena}, @code{pso}, ++@code{sy}, and @code{pi} requests. ++ ++@item -w@var{name} ++Enable warning @var{name}. Available warnings are described in ++@ref{Debugging}. Multiple @option{-w} options are allowed. ++ ++@item -W@var{name} ++Inhibit warning @var{name}. Multiple @option{-W} options are allowed. ++ ++@item -v ++Make programs run by @code{groff} print out their version number. ++ ++@item -V ++Print the pipeline on @code{stdout} instead of executing it. If ++specified more than once, print the pipeline on @code{stderr} and ++execute it. ++ ++@item -X ++Preview with @code{gxditview} instead of using the usual postprocessor. ++This is unlikely to produce good results except with @option{-Tps}. ++ ++Note that this is not the same as using @option{-TX75} or ++@option{-TX100} to view a document with @code{gxditview}: The former ++uses the metrics of the specified device, whereas the latter uses ++X-specific fonts and metrics. ++ ++@item -z ++Suppress output from @code{gtroff}. Only error messages are printed. ++ ++@item -Z ++Do not postprocess the output of @code{gtroff}. Normally @code{groff} ++automatically runs the appropriate postprocessor. ++@end table ++ ++ ++@c ===================================================================== ++ ++@node Environment, Macro Directories, Groff Options, Invoking groff ++@section Environment ++@cindex environment variables ++@cindex variables in environment ++ ++There are also several environment variables (of the operating system, ++not within @code{gtroff}) that can modify the behavior of @code{groff}. ++ ++@table @code ++@item GROFF_BIN_PATH ++@tindex GROFF_BIN_PATH@r{, environment variable} ++This search path, followed by @code{PATH}, is used for commands executed ++by @code{groff}. ++ ++@item GROFF_COMMAND_PREFIX ++@tindex GROFF_COMMAND_PREFIX@r{, environment variable} ++@cindex command prefix ++@cindex prefix, for commands ++If this is set to@tie{}@var{X}, then @code{groff} runs ++@code{@var{X}troff} instead of @code{gtroff}. This also applies to ++@code{tbl}, @code{pic}, @code{eqn}, @code{grn}, @code{chem}, ++@code{refer}, and @code{soelim}. It does not apply to @code{grops}, ++@code{grodvi}, @code{grotty}, @code{pre-grohtml}, @code{post-grohtml}, ++@code{preconv}, @code{grolj4}, @code{gropdf}, and @code{gxditview}. ++ ++The default command prefix is determined during the installation ++process. If a non-GNU troff system is found, prefix @samp{g} is used, ++none otherwise. ++ ++@item GROFF_ENCODING ++@tindex GROFF_ENCODING@r{, environment variable} ++The value of this environment value is passed to the @code{preconv} ++preprocessor to select the encoding of input files. Setting this option ++implies @code{groff}'s command line option @option{-k} (this is, ++@code{groff} actually always calls @code{preconv}). If set without a ++value, @code{groff} calls @code{preconv} without arguments. An explicit ++@option{-K} command line option overrides the value of ++@env{GROFF_ENCODING}. See the manual page of @code{preconv} for details. ++ ++@item GROFF_FONT_PATH ++@tindex GROFF_FONT_PATH@r{, environment variable} ++A colon-separated list of directories in which to search for the ++@code{dev}@var{name} directory (before the default directories are ++tried). @xref{Font Directories}. ++ ++@item GROFF_TMAC_PATH ++@tindex GROFF_TMAC_PATH@r{, environment variable} ++A colon-separated list of directories in which to search for macro files ++(before the default directories are tried). @xref{Macro Directories}. ++ ++@item GROFF_TMPDIR ++@tindex GROFF_TMPDIR@r{, environment variable} ++@tindex TMPDIR@r{, environment variable} ++The directory in which @code{groff} creates temporary files. If this is ++not set and @env{TMPDIR} is set, temporary files are created in that ++directory. Otherwise temporary files are created in a system-dependent ++default directory (on Unix and GNU/Linux systems, this is usually ++@file{/tmp}). @code{grops}, @code{grefer}, @code{pre-grohtml}, and ++@code{post-grohtml} can create temporary files in this directory. ++ ++@item GROFF_TYPESETTER ++@tindex GROFF_TYPESETTER@r{, environment variable} ++The default output device. ++@end table ++ ++Note that MS-DOS and MS-Windows ports of @code{groff} use semi-colons, ++rather than colons, to separate the directories in the lists described ++above. ++ ++ ++@c ===================================================================== ++ ++@node Macro Directories, Font Directories, Environment, Invoking groff ++@section Macro Directories ++@cindex macro directories ++@cindex directories for macros ++@cindex searching macros ++@cindex macros, searching ++ ++All macro file names must be named @code{@var{name}.tmac} or ++@code{tmac.@var{name}} to make the @option{-m@var{name}} command line ++option work. The @code{mso} request doesn't have this restriction; any ++file name can be used, and @code{gtroff} won't try to append or prepend ++the @samp{tmac} string. ++ ++@cindex tmac, directory ++@cindex directory, for tmac files ++@cindex tmac, path ++@cindex path, for tmac files ++@cindex searching macro files ++@cindex macro files, searching ++@cindex files, macro, searching ++Macro files are kept in the @dfn{tmac directories}, all of which ++constitute the @dfn{tmac path}. The elements of the search path for ++macro files are (in that order): ++ ++@itemize @bullet ++@item ++The directories specified with @code{gtroff}'s or @code{groff}'s ++@option{-M} command line option. ++ ++@item ++@tindex GROFF_TMAC_PATH@r{, environment variable} ++The directories given in the @env{GROFF_TMAC_PATH} environment variable. ++ ++@item ++@cindex safer mode ++@cindex mode, safer ++@cindex unsafe mode ++@cindex mode, unsafe ++@cindex current directory ++@cindex directory, current ++The current directory (only if in unsafe mode using the @option{-U} ++command line switch). ++ ++@item ++@cindex home directory ++@cindex directory, home ++The home directory. ++ ++@item ++@cindex site-specific directory ++@cindex directory, site-specific ++@cindex platform-specific directory ++@cindex directory, platform-specific ++A platform-dependent directory, a site-specific (platform-independent) ++directory, and the main tmac directory; the default locations are ++ ++@Example ++/usr/local/lib/groff/site-tmac ++/usr/local/share/groff/site-tmac ++/usr/local/share/groff/1.22.3/tmac ++@endExample ++ ++@noindent ++assuming that the version of @code{groff} is 1.22.3, and the ++installation prefix was @file{/usr/local}. It is possible to fine-tune ++those directories during the installation process. ++@end itemize ++ ++ ++@c ===================================================================== ++ ++@node Font Directories, Paper Size, Macro Directories, Invoking groff ++@section Font Directories ++@cindex font directories ++@cindex directories for fonts ++@cindex searching fonts ++@cindex fonts, searching ++ ++Basically, there is no restriction how font files for @code{groff} are ++named and how long font names are; however, to make the font family ++mechanism work (@pxref{Font Families}), fonts within a family should ++start with the family name, followed by the shape. For example, the ++Times family uses @samp{T} for the family name and @samp{R}, @samp{B}, ++@samp{I}, and @samp{BI} to indicate the shapes `roman', `bold', ++`italic', and `bold italic', respectively. Thus the final font names ++are @samp{TR}, @samp{TB}, @samp{TI}, and @samp{TBI}. ++ ++@cindex font path ++@cindex path, for font files ++All font files are kept in the @dfn{font directories}, which constitute ++the @dfn{font path}. The file search functions always append the ++directory @code{dev}@var{name}, where @var{name} is the name of the ++output device. Assuming, say, DVI output, and @file{/foo/bar} as a font ++directory, the font files for @code{grodvi} must be in ++@file{/foo/bar/devdvi}. ++ ++The elements of the search path for font files are (in that order): ++ ++@itemize @bullet ++@item ++The directories specified with @code{gtroff}'s or @code{groff}'s ++@option{-F} command line option. All device drivers and some ++preprocessors also have this option. ++ ++@item ++@tindex GROFF_FONT_PATH@r{, environment variable} ++The directories given in the @env{GROFF_FONT_PATH} environment variable. ++ ++@item ++@cindex site-specific directory ++@cindex directory, site-specific ++A site-specific directory and the main font directory; the default ++locations are ++ ++@Example ++/usr/local/share/groff/site-font ++/usr/local/share/groff/1.22.3/font ++@endExample ++ ++@noindent ++assuming that the version of @code{groff} is 1.22.3, and the ++installation prefix was @file{/usr/local}. It is possible to fine-tune ++those directories during the installation process. ++@end itemize ++ ++ ++@c ===================================================================== ++ ++@node Paper Size, Invocation Examples, Font Directories, Invoking groff ++@section Paper Size ++@cindex paper size ++@cindex size, paper ++@cindex landscape page orientation ++@cindex orientation, landscape ++@cindex page orientation, landscape ++ ++In groff, the page size for @code{gtroff} and for output devices are ++handled separately. @xref{Page Layout}, for vertical manipulation of ++the page size. @xref{Line Layout}, for horizontal changes. ++ ++A default paper size can be set in the device's @file{DESC} file. Most ++output devices also have a command line option @option{-p} to override ++the default paper size and option @option{-l} to use landscape ++orientation. @xref{DESC File Format}, for a description of the ++@code{papersize} keyword, which takes the same argument as @option{-p}. ++ ++@pindex papersize.tmac ++@pindex troffrc ++A convenient shorthand to set a particular paper size for @code{gtroff} ++is command line option @option{-dpaper=@var{size}}. This defines string ++@code{paper}, which is processed in file @file{papersize.tmac} (loaded in ++the start-up file @file{troffrc} by default). Possible values for ++@var{size} are the same as the predefined values for the ++@code{papersize} keyword (but only in lowercase) except ++@code{a7}-@code{d7}. An appended @samp{l} (ell) character denotes ++landscape orientation. ++ ++For example, use the following for PS output on A4 paper in landscape ++orientation: ++ ++@Example ++groff -Tps -dpaper=a4l -P-pa4 -P-l -ms foo.ms > foo.ps ++@endExample ++ ++Note that it is up to the particular macro package to respect default ++page dimensions set in this way (most do). ++ ++ ++@c ===================================================================== ++ ++@node Invocation Examples, , Paper Size, Invoking groff ++@section Invocation Examples ++@cindex invocation examples ++@cindex examples of invocation ++ ++This section lists several common uses of @code{groff} and the ++corresponding command lines. ++ ++@Example ++groff file ++@endExample ++ ++@noindent ++This command processes @file{file} without a macro package or a ++preprocessor. The output device is the default, @samp{ps}, and the ++output is sent to @code{stdout}. ++ ++@Example ++groff -t -mandoc -Tascii file | less ++@endExample ++ ++@noindent ++This is basically what a call to the @code{man} program does. ++@code{gtroff} processes the manual page @file{file} with the ++@file{mandoc} macro file (which in turn either calls the @file{man} or ++the @file{mdoc} macro package), using the @code{tbl} preprocessor and ++the @acronym{ASCII} output device. Finally, the @code{less} pager ++displays the result. ++ ++@Example ++groff -X -m me file ++@endExample ++ ++@noindent ++Preview @file{file} with @code{gxditview}, using the @file{me} macro ++package. Since no @option{-T} option is specified, use the default ++device (@samp{ps}). Note that you can either say @w{@samp{-m me}} or ++@w{@samp{-me}}; the latter is an anachronism from the early days of ++@acronym{UNIX}.@footnote{The same is true for the other main macro ++packages that come with @code{groff}: @file{man}, @file{mdoc}, ++@file{ms}, @file{mm}, and @file{mandoc}. This won't work in general; ++for example, to load @file{trace.tmac}, either @samp{-mtrace} or ++@w{@samp{-m trace}} must be used.} ++ ++@Example ++groff -man -rD1 -z file ++@endExample ++ ++@noindent ++Check @file{file} with the @file{man} macro package, forcing ++double-sided printing -- don't produce any output. ++ ++@menu ++* grog:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node grog, , Invocation Examples, Invocation Examples ++@subsection @code{grog} ++ ++@pindex grog ++@code{grog} reads files, guesses which of the @code{groff} preprocessors ++and/or macro packages are required for formatting them, and prints the ++@code{groff} command including those options on the standard output. It ++generates one or more of the options @option{-e}, @option{-man}, ++@option{-me}, @option{-mm}, @option{-mom}, @option{-ms}, @option{-mdoc}, ++@option{-mdoc-old}, @option{-p}, @option{-R}, @option{-g}, @option{-G}, ++@option{-s}, and @option{-t}. ++ ++A special file name@tie{}@file{-} refers to the standard input. ++Specifying no files also means to read the standard input. Any ++specified options are included in the printed command. No space is ++allowed between options and their arguments. The only options ++recognized are @option{-C} (which is also passed on) to enable ++compatibility mode, and @option{-v} to print the version number and ++exit. ++ ++For example, ++ ++@Example ++grog -Tdvi paper.ms ++@endExample ++ ++@noindent ++guesses the appropriate command to print @file{paper.ms} and then prints ++it to the command line after adding the @option{-Tdvi} option. For ++direct execution, enclose the call to @code{grog} in backquotes at the ++@acronym{UNIX} shell prompt: ++ ++@Example ++`grog -Tdvi paper.ms` > paper.dvi ++@endExample ++ ++@noindent ++As seen in the example, it is still necessary to redirect the output to ++something meaningful (i.e.@: either a file or a pager program like ++@code{less}). ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Tutorial for Macro Users, Macro Packages, Invoking groff, Top ++@chapter Tutorial for Macro Users ++@cindex tutorial for macro users ++@cindex macros, tutorial for users ++@cindex user's tutorial for macros ++@cindex user's macro tutorial ++ ++Most users tend to use a macro package to format their papers. This ++means that the whole breadth of @code{groff} is not necessary for most ++people. This chapter covers the material needed to efficiently use a ++macro package. ++ ++@menu ++* Basics:: ++* Common Features:: ++@end menu ++ ++ ++@c ===================================================================== ++ ++@node Basics, Common Features, Tutorial for Macro Users, Tutorial for Macro Users ++@section Basics ++@cindex basics of macros ++@cindex macro basics ++ ++This section covers some of the basic concepts necessary to understand ++how to use a macro package.@footnote{This section is derived from ++@cite{Writing Papers with nroff using -me} by Eric P.@tie{}Allman.} ++References are made throughout to more detailed information, if desired. ++ ++@code{gtroff} reads an input file prepared by the user and outputs a ++formatted document suitable for publication or framing. The input ++consists of text, or words to be printed, and embedded commands ++(@dfn{requests} and @dfn{escapes}), which tell @code{gtroff} how to ++format the output. For more detail on this, see @ref{Embedded ++Commands}. ++ ++The word @dfn{argument} is used in this chapter to mean a word or number ++that appears on the same line as a request, and which modifies the ++meaning of that request. For example, the request ++ ++@Example ++.sp ++@endExample ++ ++@noindent ++spaces one line, but ++ ++@Example ++.sp 4 ++@endExample ++ ++@noindent ++spaces four lines. The number@tie{}4 is an argument to the @code{sp} ++request, which says to space four lines instead of one. Arguments are ++separated from the request and from each other by spaces (@emph{no} ++tabs). More details on this can be found in @ref{Request and Macro ++Arguments}. ++ ++The primary function of @code{gtroff} is to collect words from input ++lines, fill output lines with those words, justify the right-hand margin ++by inserting extra spaces in the line, and output the result. For ++example, the input: ++ ++@Example ++Now is the time ++for all good men ++to come to the aid ++of their party. ++Four score and seven ++years ago, etc. ++@endExample ++ ++@noindent ++is read, packed onto output lines, and justified to produce: ++ ++@quotation ++Now is the time for all good men to come to the aid of their party. ++Four score and seven years ago, etc. ++@end quotation ++ ++@cindex break ++@cindex line break ++Sometimes a new output line should be started even though the current ++line is not yet full; for example, at the end of a paragraph. To do ++this it is possible to cause a @dfn{break}, which starts a new output ++line. Some requests cause a break automatically, as normally do blank ++input lines and input lines beginning with a space. ++ ++Not all input lines are text to be formatted. Some input lines are ++requests that describe how to format the text. Requests always have a ++period (@samp{.}) or an apostrophe (@samp{'}) as the first character of ++the input line. ++ ++The text formatter also does more complex things, such as automatically ++numbering pages, skipping over page boundaries, putting footnotes in the ++correct place, and so forth. ++ ++Here are a few hints for preparing text for input to @code{gtroff}. ++ ++@itemize @bullet ++@item ++First, keep the input lines short. Short input lines are easier to ++edit, and @code{gtroff} packs words onto longer lines anyhow. ++ ++@item ++In keeping with this, it is helpful to begin a new line after every ++comma or phrase, since common corrections are to add or delete sentences ++or phrases. ++ ++@item ++End each sentence with two spaces -- or better, start each sentence on a ++new line. @code{gtroff} recognizes characters that usually end a ++sentence, and inserts sentence space accordingly. ++ ++@item ++Do not hyphenate words at the end of lines -- @code{gtroff} is smart ++enough to hyphenate words as needed, but is not smart enough to take ++hyphens out and join a word back together. Also, words such as ++``mother-in-law'' should not be broken over a line, since then a space ++can occur where not wanted, such as ``@w{mother- in}-law''. ++@end itemize ++ ++@cindex double-spacing (@code{ls}) ++@cindex spacing ++@code{gtroff} double-spaces output text automatically if you use the ++request @w{@samp{.ls 2}}. Reactivate single-spaced mode by typing ++@w{@samp{.ls 1}}.@footnote{If you need finer granularity of the vertical ++space, use the @code{pvs} request (@pxref{Changing Type Sizes}).} ++ ++A number of requests allow to change the way the output looks, sometimes ++called the @dfn{layout} of the output page. Most of these requests ++adjust the placing of @dfn{whitespace} (blank lines or spaces). ++ ++@cindex new page (@code{bp}) ++The @code{bp} request starts a new page, causing a line break. ++ ++@cindex blank line (@code{sp}) ++@cindex empty line (@code{sp}) ++@cindex line, empty (@code{sp}) ++The request @w{@samp{.sp @var{N}}} leaves @var{N}@tie{}lines of blank ++space. @var{N}@tie{}can be omitted (meaning skip a single line) or can ++be of the form @var{N}i (for @var{N}@tie{}inches) or @var{N}c (for ++@var{N}@tie{}centimeters). For example, the input: ++ ++@Example ++.sp 1.5i ++My thoughts on the subject ++.sp ++@endExample ++ ++@noindent ++leaves one and a half inches of space, followed by the line ``My ++thoughts on the subject'', followed by a single blank line (more ++measurement units are available, see @ref{Measurements}). ++ ++@cindex centering lines (@code{ce}) ++@cindex lines, centering (@code{ce}) ++Text lines can be centered by using the @code{ce} request. The line ++after @code{ce} is centered (horizontally) on the page. To center more ++than one line, use @w{@samp{.ce @var{N}}} (where @var{N} is the number ++of lines to center), followed by the @var{N}@tie{}lines. To center many ++lines without counting them, type: ++ ++@Example ++.ce 1000 ++lines to center ++.ce 0 ++@endExample ++ ++@noindent ++The @w{@samp{.ce 0}} request tells @code{groff} to center zero more ++lines, in other words, stop centering. ++ ++@cindex line break (@code{br}) ++@cindex break (@code{br}) ++All of these requests cause a break; that is, they always start a new ++line. To start a new line without performing any other action, use ++@code{br}. ++ ++ ++@c ===================================================================== ++ ++@node Common Features, , Basics, Tutorial for Macro Users ++@section Common Features ++@cindex common features ++@cindex features, common ++ ++@code{gtroff} provides very low-level operations for formatting a ++document. There are many common routine operations that are done in ++all documents. These common operations are written into @dfn{macros} ++and collected into a @dfn{macro package}. ++ ++All macro packages provide certain common capabilities that fall into ++the following categories. ++ ++@menu ++* Paragraphs:: ++* Sections and Chapters:: ++* Headers and Footers:: ++* Page Layout Adjustment:: ++* Displays:: ++* Footnotes and Annotations:: ++* Table of Contents:: ++* Indices:: ++* Paper Formats:: ++* Multiple Columns:: ++* Font and Size Changes:: ++* Predefined Strings:: ++* Preprocessor Support:: ++* Configuration and Customization:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Paragraphs, Sections and Chapters, Common Features, Common Features ++@subsection Paragraphs ++@cindex paragraphs ++ ++One of the most common and most used capability is starting a paragraph. ++There are a number of different types of paragraphs, any of which can be ++initiated with macros supplied by the macro package. Normally, ++paragraphs start with a blank line and the first line indented, like the ++text in this manual. There are also block style paragraphs, which omit ++the indentation: ++ ++@Example ++Some men look at constitutions with sanctimonious ++reverence, and deem them like the ark of the covenant, too ++sacred to be touched. ++@endExample ++ ++@noindent ++And there are also indented paragraphs, which begin with a tag or label ++at the margin and the remaining text indented. ++ ++@Example ++one This is the first paragraph. Notice how the first ++ line of the resulting paragraph lines up with the ++ other lines in the paragraph. ++@endExample ++ ++@Example ++longlabel ++ This paragraph had a long label. The first ++ character of text on the first line does not line up ++ with the text on second and subsequent lines, ++ although they line up with each other. ++@endExample ++ ++A variation of this is a bulleted list. ++ ++@Example ++. Bulleted lists start with a bullet. It is possible ++ to use other glyphs instead of the bullet. In nroff ++ mode using the ASCII character set for output, a dot ++ is used instead of a real bullet. ++@endExample ++ ++@c --------------------------------------------------------------------- ++ ++@node Sections and Chapters, Headers and Footers, Paragraphs, Common Features ++@subsection Sections and Chapters ++ ++Most macro packages supply some form of section headers. The simplest ++kind is simply the heading on a line by itself in bold type. Others ++supply automatically numbered section heading or different heading ++styles at different levels. Some, more sophisticated, macro packages ++supply macros for starting chapters and appendices. ++ ++@c --------------------------------------------------------------------- ++ ++@node Headers and Footers, Page Layout Adjustment, Sections and Chapters, Common Features ++@subsection Headers and Footers ++ ++Every macro package gives some way to manipulate the @dfn{headers} and ++@dfn{footers} (also called @dfn{titles}) on each page. This is text put ++at the top and bottom of each page, respectively, which contain data ++like the current page number, the current chapter title, and so on. Its ++appearance is not affected by the running text. Some packages allow for ++different ones on the even and odd pages (for material printed in a book ++form). ++ ++The titles are called @dfn{three-part titles}, that is, there is a ++left-justified part, a centered part, and a right-justified part. An ++automatically generated page number may be put in any of these fields ++with the @samp{%} character (see @ref{Page Layout}, for more details). ++ ++@c --------------------------------------------------------------------- ++ ++@node Page Layout Adjustment, Displays, Headers and Footers, Common Features ++@subsection Page Layout ++ ++Most macro packages let the user specify top and bottom margins and ++other details about the appearance of the printed pages. ++ ++@c --------------------------------------------------------------------- ++ ++@node Displays, Footnotes and Annotations, Page Layout Adjustment, Common Features ++@subsection Displays ++@cindex displays ++ ++@dfn{Displays} are sections of text to be set off from the body of the ++paper. Major quotes, tables, and figures are types of displays, as are ++all the examples used in this document. ++ ++@cindex quotes, major ++@cindex major quotes ++@dfn{Major quotes} are quotes that are several lines long, and hence ++are set in from the rest of the text without quote marks around them. ++ ++@cindex list ++A @dfn{list} is an indented, single-spaced, unfilled display. Lists ++should be used when the material to be printed should not be filled and ++justified like normal text, such as columns of figures or the examples ++used in this paper. ++ ++@cindex keep ++A @dfn{keep} is a display of lines that are kept on a single page if ++possible. An example for a keep might be a diagram. Keeps differ from ++lists in that lists may be broken over a page boundary whereas keeps are ++not. ++ ++@cindex keep, floating ++@cindex floating keep ++@dfn{Floating keeps} move relative to the text. Hence, they are good ++for things that are referred to by name, such as ``See figure@tie{}3''. ++A floating keep appears at the bottom of the current page if it fits; ++otherwise, it appears at the top of the next page. Meanwhile, the ++surrounding text `flows' around the keep, thus leaving no blank areas. ++ ++@c --------------------------------------------------------------------- ++ ++@node Footnotes and Annotations, Table of Contents, Displays, Common Features ++@subsection Footnotes and Annotations ++@cindex footnotes ++@cindex annotations ++ ++There are a number of requests to save text for later printing. ++ ++@dfn{Footnotes} are printed at the bottom of the current page. ++ ++@cindex delayed text ++@dfn{Delayed text} is very similar to a footnote except that it is ++printed when called for explicitly. This allows a list of references to ++appear (for example) at the end of each chapter, as is the convention in ++some disciplines. ++ ++Most macro packages that supply this functionality also supply a means ++of automatically numbering either type of annotation. ++ ++@c --------------------------------------------------------------------- ++ ++@node Table of Contents, Indices, Footnotes and Annotations, Common Features ++@subsection Table of Contents ++@cindex table of contents ++@cindex contents, table of ++ ++@dfn{Tables of contents} are a type of delayed text having a tag ++(usually the page number) attached to each entry after a row of dots. ++The table accumulates throughout the paper until printed, usually after ++the paper has ended. Many macro packages provide the ability to have ++several tables of contents (e.g.@: a standard table of contents, a list ++of tables, etc). ++ ++@c --------------------------------------------------------------------- ++ ++@node Indices, Paper Formats, Table of Contents, Common Features ++@subsection Indices ++@cindex index, in macro package ++ ++While some macro packages use the term @dfn{index}, none actually ++provide that functionality. The facilities they call indices are ++actually more appropriate for tables of contents. ++ ++@pindex makeindex ++To produce a real index in a document, external tools like the ++@code{makeindex} program are necessary. ++ ++@c --------------------------------------------------------------------- ++ ++@node Paper Formats, Multiple Columns, Indices, Common Features ++@subsection Paper Formats ++@cindex paper formats ++ ++Some macro packages provide stock formats for various kinds of ++documents. Many of them provide a common format for the title and ++opening pages of a technical paper. The @file{mm} macros in particular ++provide formats for letters and memoranda. ++ ++@c --------------------------------------------------------------------- ++ ++@node Multiple Columns, Font and Size Changes, Paper Formats, Common Features ++@subsection Multiple Columns ++ ++Some macro packages (but not @file{man}) provide the ability to have two ++or more columns on a page. ++ ++@c --------------------------------------------------------------------- ++ ++@node Font and Size Changes, Predefined Strings, Multiple Columns, Common Features ++@subsection Font and Size Changes ++ ++The built-in font and size functions are not always intuitive, so all ++macro packages provide macros to make these operations simpler. ++ ++@c --------------------------------------------------------------------- ++ ++@node Predefined Strings, Preprocessor Support, Font and Size Changes, Common Features ++@subsection Predefined Strings ++ ++Most macro packages provide various predefined strings for a variety of ++uses; examples are sub- and superscripts, printable dates, quotes and ++various special characters. ++ ++@c --------------------------------------------------------------------- ++ ++@node Preprocessor Support, Configuration and Customization, Predefined Strings, Common Features ++@subsection Preprocessor Support ++ ++All macro packages provide support for various preprocessors and may ++extend their functionality. ++ ++For example, all macro packages mark tables (which are processed with ++@code{gtbl}) by placing them between @code{TS} and @code{TE} macros. ++The @file{ms} macro package has an option, @samp{.TS@tie{}H}, that ++prints a caption at the top of a new page (when the table is too long to ++fit on a single page). ++ ++@c --------------------------------------------------------------------- ++ ++@node Configuration and Customization, , Preprocessor Support, Common Features ++@subsection Configuration and Customization ++ ++Some macro packages provide means of customizing many of the details of ++how the package behaves. This ranges from setting the default type size ++to changing the appearance of section headers. ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Macro Packages, gtroff Reference, Tutorial for Macro Users, Top ++@chapter Macro Packages ++@cindex macro packages ++@cindex packages, macros ++ ++This chapter documents the main macro packages that come with ++@code{groff}. ++ ++Different main macro packages can't be used at the same time; for ++example ++ ++@Example ++groff -m man foo.man -m ms bar.doc ++@endExample ++ ++@noindent ++doesn't work. Note that option arguments are processed before ++non-option arguments; the above (failing) sample is thus reordered to ++ ++@Example ++groff -m man -m ms foo.man bar.doc ++@endExample ++ ++@menu ++* man:: ++* mdoc:: ++* ms:: ++* me:: ++* mm:: ++* mom:: ++@end menu ++ ++ ++@c ===================================================================== ++ ++@node man, mdoc, Macro Packages, Macro Packages ++@section @file{man} ++@cindex manual pages ++@cindex man pages ++@pindex an.tmac ++@pindex man.tmac ++@pindex man-old.tmac ++ ++This is the most popular and probably the most important macro package ++of @code{groff}. It is easy to use, and a vast majority of manual pages ++are based on it. ++ ++@menu ++* Man options:: ++* Man usage:: ++* Man font macros:: ++* Miscellaneous man macros:: ++* Predefined man strings:: ++* Preprocessors in man pages:: ++* Optional man extensions:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Man options, Man usage, man, man ++@subsection Options ++ ++The command line format for using the @file{man} macros with ++@code{groff} is: ++ ++@Example ++groff -m man [ -rLL=@var{length} ] [ -rLT=@var{length} ] [ -rFT=@var{dist} ] ++ [ -rcR=1 ] [ -rC1 ] [ -rD1 ] [-rHY=@var{flags} ] ++ [ -rP@var{nnn} ] [ -rS@var{xx} ] [ -rX@var{nnn} ] ++ [ -rIN=@var{length} ] [ -rSN=@var{length} ] [ @var{files}@dots{} ] ++@endExample ++ ++@noindent ++It is possible to use @samp{-man} instead of @w{@samp{-m man}}. ++ ++@table @code ++@item -rcR=1 ++This option (the default if a TTY output device is used) creates a ++single, very long page instead of multiple pages. Use @code{-rcR=0} to ++disable it. ++ ++@item -rC1 ++If more than one manual page is given on the command line, number the ++pages continuously, rather than starting each at@tie{}1. ++ ++@item -rD1 ++Double-sided printing. Footers for even and odd pages are formatted ++differently. ++ ++@item -rFT=@var{dist} ++Set the position of the footer text to @var{dist}. If positive, the ++distance is measured relative to the top of the page, otherwise it is ++relative to the bottom. The default is @minus{}0.5@dmn{i}. ++ ++@item -rHY=@var{flags} ++Set hyphenation flags. Possible values are 1@tie{}to hyphenate without ++restrictions, 2@tie{}to not hyphenate the last word on a page, 4@tie{}to ++not hyphenate the last two characters of a word, and 8@tie{}to not ++hyphenate the first two characters of a word. These values are ++additive; the default is@tie{}14. ++ ++@item -rIN=@var{length} ++Set the body text indentation to @var{length}. If not specified, the ++indentation defaults to 7@dmn{n} (7@tie{}characters) in nroff mode and ++7.2@dmn{n} otherwise. For nroff, this value should always be an integer ++multiple of unit @samp{n} to get consistent indentation. ++ ++@item -rLL=@var{length} ++Set line length to @var{length}. If not specified, the line length is ++set to respect any value set by a prior @samp{ll} request (which ++@emph{must} be in effect when the @samp{TH} macro is invoked), if this ++differs from the built-in default for the formatter; otherwise it ++defaults to 78@dmn{n} in nroff mode (this is 78 characters per line) and ++6.5@dmn{i} in troff mode.@footnote{Note that the use of a @samp{.ll ++@var{length}} request to initialize the line length, prior to use of the ++@samp{TH} macro, is supported for backward compatibility with some ++versions of the @code{man} program. @emph{Always} use the ++@option{-rLL=@var{length}} option, or an equivalent @samp{.nr LL ++@var{length}} request, in preference to such a @samp{.ll @var{length}} ++request. In particular, note that in nroff mode, the request @samp{.ll ++65n}, (with any @var{length} expression that evaluates equal to ++65@dmn{n}, i.e., the formatter's default line length in nroff mode), ++does @emph{not} set the line length to 65@dmn{n} (it is adjusted to the ++@code{man} macro package's default setting of 78@dmn{n}), whereas the ++use of the @option{-rLL=65n} option, or the @samp{.nr LL 65n} request ++@emph{does} establish a line length of 65@dmn{n}.} ++ ++@item -rLT=@var{length} ++Set title length to @var{length}. If not specified, the title length ++defaults to the line length. ++ ++@item -rP@var{nnn} ++Page numbering starts with @var{nnn} rather than with@tie{}1. ++ ++@item -rS@var{xx} ++Use @var{xx} (which can be 10, 11, or@tie{}12@dmn{pt}) as the base ++document font size instead of the default value of@tie{}10@dmn{pt}. ++ ++@item -rSN=@var{length} ++Set the indentation for sub-subheadings to @var{length}. If not ++specified, the indentation defaults to 3@dmn{n}. ++ ++@item -rX@var{nnn} ++After page @var{nnn}, number pages as @var{nnn}a, @var{nnn}b, ++@var{nnn}c, etc. For example, the option @option{-rX2} produces the ++following page numbers: 1, 2, 2a, 2b, 2c, etc. ++@end table ++ ++@c --------------------------------------------------------------------- ++ ++@node Man usage, Man font macros, Man options, man ++@subsection Usage ++@cindex @code{man} macros ++@cindex macros for manual pages [@code{man}] ++ ++@pindex man.local ++This section describes the available macros for manual pages. For ++further customization, put additional macros and requests into the file ++@file{man.local}, which is loaded immediately after the @file{man} ++package. ++ ++@Defmac {TH, title section [@Var{extra1} [@Var{extra2} [@Var{extra3}]]], man} ++Set the title of the man page to @var{title} and the section to ++@var{section}, which must have a value between 1 and@tie{}8. The value ++of @var{section} may also have a string appended, e.g.@: @samp{.pm}, to ++indicate a specific subsection of the man pages. ++ ++Both @var{title} and @var{section} are positioned at the left and right ++in the header line (with @var{section} in parentheses immediately ++appended to @var{title}. @var{extra1} is positioned in the middle of ++the footer line. @var{extra2} is positioned at the left in the footer ++line (or at the left on even pages and at the right on odd pages if ++double-sided printing is active). @var{extra3} is centered in the ++header line. ++ ++For @acronym{HTML} and @acronym{XHTML} output, headers and footers are ++completely suppressed. ++ ++Additionally, this macro starts a new page; the new line number ++is@tie{}1 again (except if the @option{-rC1} option is given on the ++command line) -- this feature is intended only for formatting multiple ++man pages; a single man page should contain exactly one @code{TH} macro ++at the beginning of the file. ++@endDefmac ++ ++@Defmac {SH, [@Var{heading}], man} ++Set up an unnumbered section heading sticking out to the left. Prints ++out all the text following @code{SH} up to the end of the line (or the ++text in the next line if there is no argument to @code{SH}) in bold face ++(or the font specified by the string @code{HF}), one size larger than ++the base document size. Additionally, the left margin and the ++indentation for the following text is reset to its default value. ++@endDefmac ++ ++@Defmac {SS, [@Var{heading}], man} ++Set up an unnumbered (sub)section heading. Prints out all the text ++following @code{SS} up to the end of the line (or the text in the next ++line if there is no argument to @code{SS}) in bold face (or the font ++specified by the string @code{HF}), at the same size as the base ++document size. Additionally, the left margin and the indentation for ++the following text is reset to its default value. ++@endDefmac ++ ++@Defmac {TP, [@Var{nnn}], man} ++Set up an indented paragraph with label. The indentation is set to ++@var{nnn} if that argument is supplied (the default unit is @samp{n} if ++omitted), otherwise it is set to the previous indentation value ++specified with @code{TP}, @code{IP}, or @code{HP} (or to the default ++value if none of them have been used yet). ++ ++The first line of text following this macro is interpreted as a string ++to be printed flush-left, as it is appropriate for a label. It is not ++interpreted as part of a paragraph, so there is no attempt to fill the ++first line with text from the following input lines. Nevertheless, if ++the label is not as wide as the indentation the paragraph starts at the ++same line (but indented), continuing on the following lines. If the ++label is wider than the indentation the descriptive part of the ++paragraph begins on the line following the label, entirely indented. ++Note that neither font shape nor font size of the label is set to a ++default value; on the other hand, the rest of the text has default font ++settings. ++@endDefmac ++ ++@DefmacList {LP, , man} ++@DefmacItemx {PP, , man} ++@DefmacListEndx {P, , man} ++These macros are mutual aliases. Any of them causes a line break at the ++current position, followed by a vertical space downwards by the amount ++specified by the @code{PD} macro. The font size and shape are reset to ++the default value (10@dmn{pt} roman if no @option{-rS} option is given ++on the command line). Finally, the current left margin and the ++indentation is restored. ++@endDefmac ++ ++@Defmac {IP, [@Var{designator} [@Var{nnn}]], man} ++Set up an indented paragraph, using @var{designator} as a tag to mark ++its beginning. The indentation is set to @var{nnn} if that argument is ++supplied (default unit is @samp{n}), otherwise it is set to the previous ++indentation value specified with @code{TP}, @code{IP}, or @code{HP} (or ++the default value if none of them have been used yet). Font size and ++face of the paragraph (but not the designator) are reset to their ++default values. ++ ++To start an indented paragraph with a particular indentation but without ++a designator, use @samp{""} (two double quotes) as the first argument of ++@code{IP}. ++ ++For example, to start a paragraph with bullets as the designator and ++4@tie{}en indentation, write ++ ++@Example ++.IP \(bu 4 ++@endExample ++@endDefmac ++ ++@Defmac {HP, [@Var{nnn}], man} ++@cindex hanging indentation [@code{man}] ++@cindex @code{man} macros, hanging indentation ++Set up a paragraph with hanging left indentation. The indentation is ++set to @var{nnn} if that argument is supplied (default unit is ++@samp{n}), otherwise it is set to the previous indentation value ++specified with @code{TP}, @code{IP}, or @code{HP} (or the default value ++if non of them have been used yet). Font size and face are reset to ++their default values. ++@endDefmac ++ ++@Defmac {RS, [@Var{nnn}], man} ++@cindex left margin, how to move [@code{man}] ++@cindex @code{man} macros, moving left margin ++Move the left margin to the right by the value @var{nnn} if specified ++(default unit is @samp{n}); otherwise it is set to the previous ++indentation value specified with @code{TP}, @code{IP}, or @code{HP} (or ++to the default value if none of them have been used yet). The ++indentation value is then set to the default. ++ ++Calls to the @code{RS} macro can be nested. ++@endDefmac ++ ++@Defmac {RE, [@Var{nnn}], man} ++Move the left margin back to level @var{nnn}, restoring the previous ++left margin. If no argument is given, it moves one level back. The ++first level (i.e., no call to @code{RS} yet) has number@tie{}1, and each ++call to @code{RS} increases the level by@tie{}1. ++@endDefmac ++ ++@cindex line breaks, with vertical space [@code{man}] ++@cindex @code{man} macros, line breaks with vertical space ++To summarize, the following macros cause a line break with the insertion ++of vertical space (which amount can be changed with the @code{PD} ++macro): @code{SH}, @code{SS}, @code{TP}, @code{LP} (@code{PP}, ++@code{P}), @code{IP}, and @code{HP}. ++ ++@cindex line breaks, without vertical space [@code{man}] ++@cindex @code{man} macros, line breaks without vertical space ++The macros @code{RS} and @code{RE} also cause a break but do not insert ++vertical space. ++ ++@cindex default indentation, resetting [@code{man}] ++@cindex indentaion, resetting to default [@code{man}] ++@cindex @code{man} macros, resetting default indentation ++Finally, the macros @code{SH}, @code{SS}, @code{LP} (@code{PP}, ++@code{P}), and @code{RS} reset the indentation to its default value. ++ ++@c --------------------------------------------------------------------- ++ ++@node Man font macros, Miscellaneous man macros, Man usage, man ++@subsection Macros to set fonts ++@cindex font selection [@code{man}] ++@cindex @code{man} macros, how to set fonts ++ ++The standard font is roman; the default text size is 10@tie{}point. If ++command line option @option{-rS=@var{n}} is given, use @var{n}@dmn{pt} ++as the default text size. ++ ++@Defmac {SM, [@Var{text}], man} ++Set the text on the same line or the text on the next line in a font ++that is one point size smaller than the default font. ++@endDefmac ++ ++@Defmac {SB, [@Var{text}], man} ++@cindex bold face [@code{man}] ++@cindex @code{man} macros, bold face ++Set the text on the same line or the text on the next line in bold face ++font, one point size smaller than the default font. ++@endDefmac ++ ++@Defmac {BI, text, man} ++Set its arguments alternately in bold face and italic, without a space ++between the arguments. Thus, ++ ++@Example ++.BI this "word and" that ++@endExample ++ ++@noindent ++produces ``thisword andthat'' with ``this'' and ``that'' in bold face, ++and ``word and'' in italics. ++@endDefmac ++ ++@Defmac {IB, text, man} ++Set its arguments alternately in italic and bold face, without a space ++between the arguments. ++@endDefmac ++ ++@Defmac {RI, text, man} ++Set its arguments alternately in roman and italic, without a space ++between the arguments. ++@endDefmac ++ ++@Defmac {IR, text, man} ++Set its arguments alternately in italic and roman, without a space ++between the arguments. ++@endDefmac ++ ++@Defmac {BR, text, man} ++Set its arguments alternately in bold face and roman, without a space ++between the arguments. ++@endDefmac ++ ++@Defmac {RB, text, man} ++Set its arguments alternately in roman and bold face, without a space ++between the arguments. ++@endDefmac ++ ++@Defmac {B, [@Var{text}], man} ++Set @var{text} in bold face. If no text is present on the line where ++the macro is called, then the text of the next line appears in bold ++face. ++@endDefmac ++ ++@Defmac {I, [@Var{text}], man} ++@cindex italic fonts [@code{man}] ++@cindex @code{man} macros, italic fonts ++Set @var{text} in italic. If no text is present on the line where the ++macro is called, then the text of the next line appears in italic. ++@endDefmac ++ ++@c --------------------------------------------------------------------- ++ ++@node Miscellaneous man macros, Predefined man strings, Man font macros, man ++@subsection Miscellaneous macros ++ ++@pindex grohtml ++@cindex @code{man} macros, default indentation ++@cindex default indentation [@code{man}] ++The default indentation is 7.2@dmn{n} in troff mode and 7@dmn{n} in ++nroff mode except for @code{grohtml}, which ignores indentation. ++ ++@Defmac {DT, , man} ++@cindex tab stops [@code{man}] ++@cindex @code{man} macros, tab stops ++Set tabs every 0.5@tie{}inches. Since this macro is always executed ++during a call to the @code{TH} macro, it makes sense to call it only if ++the tab positions have been changed. ++@endDefmac ++ ++@Defmac {PD, [@Var{nnn}], man} ++@cindex empty space before a paragraph [@code{man}] ++@cindex @code{man} macros, empty space before a paragraph ++Adjust the empty space before a new paragraph (or section). The ++optional argument gives the amount of space (default unit is @samp{v}); ++without parameter, the value is reset to its default value (1@tie{}line ++in nroff mode, 0.4@dmn{v}@tie{}otherwise). ++ ++This affects the macros @code{SH}, @code{SS}, @code{TP}, @code{LP} (as ++well as @code{PP} and @code{P}), @code{IP}, and @code{HP}. ++@endDefmac ++ ++The following two macros are included for BSD compatibility. ++ ++@Defmac {AT, [@Var{system} [@Var{release}]], man} ++@cindex @code{man}macros, BSD compatibility ++Alter the footer for use with @acronym{AT&T} manpages. This command ++exists only for compatibility; don't use it. The first argument ++@var{system} can be: ++ ++@table @code ++@item 3 ++7th Edition (the default) ++ ++@item 4 ++System III ++ ++@item 5 ++System V ++@end table ++ ++An optional second argument @var{release} to @code{AT} specifies the ++release number (such as ``System V Release 3''). ++@endDefmac ++ ++@Defmac {UC, [@Var{version}], man} ++@cindex @code{man}macros, BSD compatibility ++Alters the footer for use with BSD manpages. This command exists only ++for compatibility; don't use it. The argument can be: ++ ++@table @code ++@item 3 ++3rd Berkeley Distribution (the default) ++ ++@item 4 ++4th Berkeley Distribution ++ ++@item 5 ++4.2 Berkeley Distribution ++ ++@item 6 ++4.3 Berkeley Distribution ++ ++@item 7 ++4.4 Berkeley Distribution ++@end table ++@endDefmac ++ ++@c --------------------------------------------------------------------- ++ ++@node Predefined man strings, Preprocessors in man pages, Miscellaneous man macros, man ++@subsection Predefined strings ++ ++The following strings are defined: ++ ++@Defstr {S, man} ++Switch back to the default font size. ++@endDefstr ++ ++@Defstr {HF, man} ++The typeface used for headings. ++The default is @samp{B}. ++@endDefstr ++ ++@Defstr {R, man} ++The `registered' sign. ++@endDefstr ++ ++@Defstr {Tm, man} ++The `trademark' sign. ++@endDefstr ++ ++@DefstrList {lq, man} ++@DefstrListEndx {rq, man} ++@cindex @code{lq} glyph, and @code{lq} string [@code{man}] ++@cindex @code{rq} glyph, and @code{rq} string [@code{man}] ++Left and right quote. This is equal to @code{\(lq} and @code{\(rq}, ++respectively. ++@endDefstr ++ ++@c --------------------------------------------------------------------- ++ ++@node Preprocessors in man pages, Optional man extensions, Predefined man strings, man ++@subsection Preprocessors in @file{man} pages ++ ++@cindex preprocessor, calling convention ++@cindex calling convention of preprocessors ++If a preprocessor like @code{gtbl} or @code{geqn} is needed, it has ++become common usage to make the first line of the man page look like ++this: ++ ++@Example ++'\" @var{word} ++@endExample ++ ++@pindex geqn@r{, invocation in manual pages} ++@pindex grefer@r{, invocation in manual pages} ++@pindex gtbl@r{, invocation in manual pages} ++@pindex man@r{, invocation of preprocessors} ++@noindent ++Note the single space character after the double quote. @var{word} ++consists of letters for the needed preprocessors: @samp{e} for ++@code{geqn}, @samp{r} for @code{grefer}, @samp{t} for @code{gtbl}. ++Modern implementations of the @code{man} program read this first line ++and automatically call the right preprocessor(s). ++ ++@c --------------------------------------------------------------------- ++ ++@node Optional man extensions, , Preprocessors in man pages, man ++@subsection Optional @file{man} extensions ++ ++@pindex man.local ++Use the file @file{man.local} for local extensions to the @code{man} ++macros or for style changes. ++ ++@unnumberedsubsubsec Custom headers and footers ++@cindex @code{man} macros, custom headers and footers ++ ++In groff versions 1.18.2 and later, you can specify custom headers and ++footers by redefining the following macros in @file{man.local}. ++ ++@Defmac {PT, , man} ++Control the content of the headers. Normally, the header prints the ++command name and section number on either side, and the optional fifth ++argument to @code{TH} in the center. ++@endDefmac ++ ++@Defmac {BT, , man} ++Control the content of the footers. Normally, the footer prints the ++page number and the third and fourth arguments to @code{TH}. ++ ++Use the @code{FT} number register to specify the footer position. The ++default is @minus{}0.5@dmn{i}. ++@endDefmac ++ ++@unnumberedsubsubsec Ultrix-specific man macros ++@cindex Ultrix-specific @code{man} macros ++@cindex @code{man} macros, Ultrix-specific ++ ++@pindex man.ultrix ++The @code{groff} source distribution includes a file named ++@file{man.ultrix}, containing macros compatible with the Ultrix variant ++of @code{man}. Copy this file into @file{man.local} (or use the ++@code{mso} request to load it) to enable the following macros. ++ ++@Defmac {CT, @Var{key}, man} ++Print @samp{}. ++@endDefmac ++ ++@Defmac {CW, , man} ++Print subsequent text using the constant width (Courier) typeface. ++@endDefmac ++ ++@Defmac {Ds, , man} ++Begin a non-filled display. ++@endDefmac ++ ++@Defmac {De, , man} ++End a non-filled display started with @code{Ds}. ++@endDefmac ++ ++@Defmac {EX, [@Var{indent}], man} ++Begin a non-filled display using the constant width (Courier) typeface. ++Use the optional @var{indent} argument to indent the display. ++@endDefmac ++ ++@Defmac {EE, , man} ++End a non-filled display started with @code{EX}. ++@endDefmac ++ ++@Defmac {G, [@Var{text}], man} ++Set @var{text} in Helvetica. If no text is present on the line where ++the macro is called, then the text of the next line appears in ++Helvetica. ++@endDefmac ++ ++@Defmac {GL, [@Var{text}], man} ++Set @var{text} in Helvetica Oblique. If no text is present on the line ++where the macro is called, then the text of the next line appears in ++Helvetica Oblique. ++@endDefmac ++ ++@Defmac {HB, [@Var{text}], man} ++Set @var{text} in Helvetica Bold. If no text is present on the line ++where the macro is called, then all text up to the next @code{HB} ++appears in Helvetica Bold. ++@endDefmac ++ ++@Defmac {TB, [@Var{text}], man} ++Identical to @code{HB}. ++@endDefmac ++ ++@Defmac {MS, @Var{title} @Var{sect} [@Var{punct}], man} ++Set a manpage reference in Ultrix format. The @var{title} is in Courier ++instead of italic. Optional punctuation follows the section number ++without an intervening space. ++@endDefmac ++ ++@Defmac {NT, [@code{C}] [@Var{title}], man} ++Begin a note. Print the optional @Var{title}, or the word ``Note'', ++centered on the page. Text following the macro makes up the body of the ++note, and is indented on both sides. If the first argument is @code{C}, ++the body of the note is printed centered (the second argument replaces ++the word ``Note'' if specified). ++@endDefmac ++ ++@Defmac {NE, , man} ++End a note begun with @code{NT}. ++@endDefmac ++ ++@Defmac {PN, @Var{path} [@Var{punct}], man} ++Set the path name in constant width (Courier), followed by optional ++punctuation. ++@endDefmac ++ ++@Defmac {Pn, [@Var{punct}] @Var{path} [@Var{punct}], man} ++If called with two arguments, identical to @code{PN}. If called with ++three arguments, set the second argument in constant width (Courier), ++bracketed by the first and third arguments in the current font. ++@endDefmac ++ ++@Defmac {R, , man} ++Switch to roman font and turn off any underlining in effect. ++@endDefmac ++ ++@Defmac {RN, , man} ++Print the string @samp{}. ++@endDefmac ++ ++@Defmac {VS, [@code{4}], man} ++Start printing a change bar in the margin if the number@tie{}@code{4} is ++specified. Otherwise, this macro does nothing. ++@endDefmac ++ ++@Defmac {VE, , man} ++End printing the change bar begun by @code{VS}. ++@endDefmac ++ ++@unnumberedsubsubsec Simple example ++ ++The following example @file{man.local} file alters the @code{SH} macro ++to add some extra vertical space before printing the heading. Headings ++are printed in Helvetica Bold. ++ ++@Example ++.\" Make the heading fonts Helvetica ++.ds HF HB ++. ++.\" Put more whitespace in front of headings. ++.rn SH SH-orig ++.de SH ++. if t .sp (u;\\n[PD]*2) ++. SH-orig \\$* ++.. ++@endExample ++ ++ ++@c ===================================================================== ++ ++@node mdoc, ms, man, Macro Packages ++@section @file{mdoc} ++@cindex @code{mdoc} macros ++ ++@c XXX documentation ++@c XXX this is a placeholder until we get stuff knocked into shape ++See the @cite{groff_mdoc(7)} man page (type @command{man groff_mdoc} ++at the command line). ++ ++ ++@c ===================================================================== ++ ++@node ms, me, mdoc, Macro Packages ++@section @file{ms} ++@cindex @code{ms} macros ++ ++The @file{-ms} macros are suitable for reports, letters, books, user ++manuals, and so forth. The package provides macros for cover pages, ++section headings, paragraphs, lists, footnotes, pagination, and a table ++of contents. ++ ++@menu ++* ms Intro:: ++* General ms Structure:: ++* ms Document Control Registers:: ++* ms Cover Page Macros:: ++* ms Body Text:: ++* ms Page Layout:: ++* Differences from AT&T ms:: ++* Naming Conventions:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Intro, General ms Structure, ms, ms ++@subsection Introduction to @file{ms} ++ ++The original @file{-ms} macros were included with @acronym{AT&T} ++@code{troff} as well as the @file{man} macros. While the @file{man} ++package is intended for brief documents that can be read on-line as well ++as printed, the @file{ms} macros are suitable for longer documents that ++are meant to be printed rather than read on-line. ++ ++The @file{ms} macro package included with @code{groff} is a complete, ++bottom-up re-implementation. Several macros (specific to @acronym{AT&T} ++or Berkeley) are not included, while several new commands are. ++@xref{Differences from AT&T ms}, for more information. ++ ++@c --------------------------------------------------------------------- ++ ++@node General ms Structure, ms Document Control Registers, ms Intro, ms ++@subsection General structure of an @file{ms} document ++@cindex @code{ms} macros, general structure ++ ++The @file{ms} macro package expects a certain amount of structure, but ++not as much as packages such as @file{man} or @file{mdoc}. ++ ++The simplest documents can begin with a paragraph macro (such as ++@code{LP} or @code{PP}), and consist of text separated by paragraph ++macros or even blank lines. Longer documents have a structure as ++follows: ++ ++@table @strong ++@item Document type ++If you invoke the @code{RP} (report) macro on the first line of the ++document, @code{groff} prints the cover page information on its own ++page; otherwise it prints the information on the first page with your ++document text immediately following. Other document formats found in ++@acronym{AT&T} @code{troff} are specific to @acronym{AT&T} or Berkeley, ++and are not supported in @code{groff}. ++ ++@item Format and layout ++By setting number registers, you can change your document's type (font ++and size), margins, spacing, headers and footers, and footnotes. ++@xref{ms Document Control Registers}, for more details. ++ ++@item Cover page ++A cover page consists of a title, the author's name and institution, an ++abstract, and the date.@footnote{Actually, only the title is required.} ++@xref{ms Cover Page Macros}, for more details. ++ ++@item Body ++Following the cover page is your document. You can use the @file{ms} ++macros to write reports, letters, books, and so forth. The package is ++designed for structured documents, consisting of paragraphs interspersed ++with headings and augmented by lists, footnotes, tables, and other ++common constructs. @xref{ms Body Text}, for more details. ++ ++@item Table of contents ++Longer documents usually include a table of contents, which you can ++invoke by placing the @code{TC} macro at the end of your document. The ++@file{ms} macros have minimal indexing facilities, consisting of the ++@code{IX} macro, which prints an entry on standard error. Printing the ++table of contents at the end is necessary since @code{groff} is a ++single-pass text formatter, thus it cannot determine the page number of ++each section until that section has actually been set and printed. ++Since @file{ms} output is intended for hardcopy, you can manually ++relocate the pages containing the table of contents between the cover ++page and the body text after printing. ++@end table ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Document Control Registers, ms Cover Page Macros, General ms Structure, ms ++@subsection Document control registers ++@cindex @code{ms} macros, document control registers ++ ++The following is a list of document control number registers. For the ++sake of consistency, set registers related to margins at the beginning ++of your document, or just after the @code{RP} macro. You can set other ++registers later in your document, but you should keep them together at ++the beginning to make them easy to find and edit as necessary. ++ ++@unnumberedsubsubsec Margin Settings ++ ++@Defmpreg {PO, ms} ++Defines the page offset (i.e., the left margin). There is no explicit ++right margin setting; the combination of the @code{PO} and @code{LL} ++registers implicitly define the right margin width. ++ ++Effective: next page. ++ ++Default value: 1@dmn{i}. ++@endDefmpreg ++ ++@Defmpreg {LL, ms} ++Defines the line length (i.e., the width of the body text). ++ ++Effective: next paragraph. ++ ++Default: 6@dmn{i}. ++@endDefmpreg ++ ++@Defmpreg {LT, ms} ++Defines the title length (i.e., the header and footer width). This ++is usually the same as @code{LL}, but not necessarily. ++ ++Effective: next paragraph. ++ ++Default: 6@dmn{i}. ++@endDefmpreg ++ ++@Defmpreg {HM, ms} ++Defines the header margin height at the top of the page. ++ ++Effective: next page. ++ ++Default: 1@dmn{i}. ++@endDefmpreg ++ ++@Defmpreg {FM, ms} ++Defines the footer margin height at the bottom of the page. ++ ++Effective: next page. ++ ++Default: 1@dmn{i}. ++@endDefmpreg ++ ++@unnumberedsubsubsec Text Settings ++ ++@Defmpreg {PS, ms} ++Defines the point size of the body text. If the value is larger than or ++equal to 1000, divide it by 1000 to get a fractional point size. For ++example, @samp{.nr PS 10250} sets the document's point size to ++10.25@dmn{p}. ++ ++Effective: next paragraph. ++ ++Default: 10@dmn{p}. ++@endDefmpreg ++ ++@Defmpreg {VS, ms} ++Defines the space between lines (line height plus leading). If the ++value is larger than or equal to 1000, divide it by 1000 to get a ++fractional point size. Due to backwards compatibility, @code{VS} must ++be smaller than 40000 (this is 40.0@dmn{p}). ++ ++Effective: next paragraph. ++ ++Default: 12@dmn{p}. ++@endDefmpreg ++ ++@Defmpreg {PSINCR, ms} ++Defines an increment in point size, which is applied to section headings ++at nesting levels below the value specified in @code{GROWPS}. The value ++of @code{PSINCR} should be specified in points, with the @dmn{p} scaling ++factor, and may include a fractional component; for example, ++@w{@samp{.nr PSINCR 1.5p}} sets a point size increment of 1.5@dmn{p}. ++ ++Effective: next section heading. ++ ++Default: 1@dmn{p}. ++@endDefmpreg ++ ++@Defmpreg {GROWPS, ms} ++Defines the heading level below which the point size increment set by ++@code{PSINCR} becomes effective. Section headings at and above the ++level specified by @code{GROWPS} are printed at the point size set by ++@code{PS}; for each level below the value of @code{GROWPS}, the point ++size is increased in steps equal to the value of @code{PSINCR}. Setting ++@code{GROWPS} to any value less than@tie{}2 disables the incremental ++heading size feature. ++ ++Effective: next section heading. ++ ++Default: 0. ++@endDefmpreg ++ ++@Defmpreg {HY, ms} ++Defines the hyphenation level. @code{HY} sets safely the value of the ++low-level @code{hy} register. Setting the value of @code{HY} to@tie{}0 ++is equivalent to using the @code{nh} request. ++ ++Effective: next paragraph. ++ ++Default: 14. ++@endDefmpreg ++ ++@Defmpreg {FAM, ms} ++Defines the font family used to typeset the document. ++ ++Effective: next paragraph. ++ ++Default: as defined in the output device. ++@endDefmpreg ++ ++@unnumberedsubsubsec Paragraph Settings ++ ++@Defmpreg {PI, ms} ++Defines the initial indentation of a (@code{PP} macro) paragraph. ++ ++Effective: next paragraph. ++ ++Default: 5@dmn{n}. ++@endDefmpreg ++ ++@Defmpreg {PD, ms} ++Defines the space between paragraphs. ++ ++Effective: next paragraph. ++ ++Default: 0.3@dmn{v}. ++@endDefmpreg ++ ++@Defmpreg {QI, ms} ++Defines the indentation on both sides of a quoted (@code{QP} macro) ++paragraph. ++ ++Effective: next paragraph. ++ ++Default: 5@dmn{n}. ++@endDefmpreg ++ ++@Defmpreg {PORPHANS, ms} ++Defines the minimum number of initial lines of any paragraph that ++should be kept together, to avoid orphan lines at the bottom of a page. ++If a new paragraph is started close to the bottom of a page, and there ++is insufficient space to accommodate @code{PORPHANS} lines before an ++automatic page break, then the page break is forced, before the start of ++the paragraph. ++ ++Effective: next paragraph. ++ ++Default: 1. ++@endDefmpreg ++ ++@Defmpreg {HORPHANS, ms} ++Defines the minimum number of lines of the following paragraph that ++should be kept together with any section heading introduced by the ++@code{NH} or @code{SH} macros. If a section heading is placed close to ++the bottom of a page, and there is insufficient space to accommodate ++both the heading and at least @code{HORPHANS} lines of the following ++paragraph, before an automatic page break, then the page break is forced ++before the heading. ++ ++Effective: next paragraph. ++ ++Default: 1. ++@endDefmpreg ++ ++@unnumberedsubsubsec Footnote Settings ++ ++@Defmpreg {FL, ms} ++Defines the length of a footnote. ++ ++Effective: next footnote. ++ ++Default: @math{@code{@\n[LL]} * 5 / 6}. ++@endDefmpreg ++ ++@Defmpreg {FI, ms} ++Defines the footnote indentation. ++ ++Effective: next footnote. ++ ++Default: 2@dmn{n}. ++@endDefmpreg ++ ++@Defmpreg {FF, ms} ++The footnote format: ++@table @code ++@item 0 ++Print the footnote number as a superscript; indent the footnote ++(default). ++ ++@item 1 ++Print the number followed by a period (like 1.@:) and indent the ++footnote. ++ ++@item 2 ++Like 1, without an indentation. ++ ++@item 3 ++Like 1, but print the footnote number as a hanging paragraph. ++@end table ++ ++Effective: next footnote. ++ ++Default: 0. ++@endDefmpreg ++ ++@Defmpreg {FPS, ms} ++Defines the footnote point size. If the value is larger than or equal ++to 1000, divide it by 1000 to get a fractional point size. ++ ++Effective: next footnote. ++ ++Default: @math{@code{@\n[PS]} - 2}. ++@endDefmpreg ++ ++@Defmpreg {FVS, ms} ++Defines the footnote vertical spacing. If the value is larger than or ++equal to 1000, divide it by 1000 to get a fractional point size. ++ ++Effective: next footnote. ++ ++Default: @math{@code{@\n[FPS]} + 2}. ++@endDefmpreg ++ ++@Defmpreg {FPD, ms} ++Defines the footnote paragraph spacing. ++ ++Effective: next footnote. ++ ++Default: @math{@code{@\n[PD]} / 2}. ++@endDefmpreg ++ ++@unnumberedsubsubsec Miscellaneous Number Registers ++ ++@Defmpreg {MINGW, ms} ++Defines the minimum width between columns in a multi-column document. ++ ++Effective: next page. ++ ++Default: 2@dmn{n}. ++@endDefmpreg ++ ++@Defmpreg {DD, ms} ++Sets the vertical spacing before and after a display, a @code{tbl} table, an ++@code{eqn} equation, or a @code{pic} image. ++ ++Effective: next paragraph. ++ ++Default: 0.5@dmn{v}. ++@endDefmpreg ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Cover Page Macros, ms Body Text, ms Document Control Registers, ms ++@subsection Cover page macros ++@cindex @code{ms} macros, cover page ++@cindex cover page macros, [@code{ms}] ++ ++Use the following macros to create a cover page for your document in the ++order shown. ++ ++@Defmac {RP, [@code{no}], ms} ++Specifies the report format for your document. The report format ++creates a separate cover page. The default action (no @code{RP} macro) ++is to print a subset of the cover page on page@tie{}1 of your document. ++ ++If you use the word @code{no} as an optional argument, @code{groff} ++prints a title page but does not repeat any of the title page ++information (title, author, abstract, etc.@:) on page@tie{}1 of the ++document. ++@endDefmac ++ ++@Defmac {P1, , ms} ++(P-one) Prints the header on page@tie{}1. The default is to suppress ++the header. ++@endDefmac ++ ++@Defmac {DA, [@dots{}], ms} ++(optional) Prints the current date, or the arguments to the macro if ++any, on the title page (if specified) and in the footers. This is the ++default for @code{nroff}. ++@endDefmac ++ ++@Defmac {ND, [@dots{}], ms} ++(optional) Prints the current date, or the arguments to the macro if ++any, on the title page (if specified) but not in the footers. This is ++the default for @code{troff}. ++@endDefmac ++ ++@Defmac {TL, , ms} ++Specifies the document title. @code{groff} collects text following the ++@code{TL} macro into the title, until reaching the author name or ++abstract. ++@endDefmac ++ ++@Defmac {AU, , ms} ++Specifies the author's name, which appears on the line (or lines) ++immediately following. You can specify multiple authors as follows: ++ ++@Example ++.AU ++John Doe ++.AI ++University of West Bumblefuzz ++.AU ++Martha Buck ++.AI ++Monolithic Corporation ++ ++... ++@endExample ++@endDefmac ++ ++@Defmac {AI, , ms} ++Specifies the author's institution. You can specify multiple ++institutions in the same way that you specify multiple authors. ++@endDefmac ++ ++@Defmac {AB, [@code{no}], ms} ++Begins the abstract. The default is to print the word ++@acronym{ABSTRACT}, centered and in italics, above the text of the ++abstract. The word @code{no} as an optional argument suppresses this ++heading. ++@endDefmac ++ ++@Defmac {AE, , ms} ++Ends the abstract. ++@endDefmac ++ ++The following is example mark-up for a title page. ++@cindex title page, example markup ++@cindex example markup, title page ++ ++@CartoucheExample ++.RP ++.TL ++The Inevitability of Code Bloat ++in Commercial and Free Software ++.AU ++J. Random Luser ++.AI ++University of West Bumblefuzz ++.AB ++This report examines the long-term growth ++of the code bases in two large, popular software ++packages; the free Emacs and the commercial ++Microsoft Word. ++While differences appear in the type or order ++of features added, due to the different ++methodologies used, the results are the same ++in the end. ++.PP ++The free software approach is shown to be ++superior in that while free software can ++become as bloated as commercial offerings, ++free software tends to have fewer serious ++bugs and the added features are in line with ++user demand. ++.AE ++ ++... the rest of the paper follows ... ++@endCartoucheExample ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Body Text, ms Page Layout, ms Cover Page Macros, ms ++@subsection Body text ++@cindex @code{ms} macros, body text ++ ++This section describes macros used to mark up the body of your document. ++Examples include paragraphs, sections, and other groups. ++ ++@menu ++* Paragraphs in ms:: ++* Headings in ms:: ++* Highlighting in ms:: ++* Lists in ms:: ++* Indentation values in ms:: ++* Tabstops in ms:: ++* ms Displays and Keeps:: ++* ms Insertions:: ++* Example multi-page table:: ++* ms Footnotes:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Paragraphs in ms, Headings in ms, ms Body Text, ms Body Text ++@subsubsection Paragraphs ++@cindex @code{ms} macros, paragraph handling ++ ++The following paragraph types are available. ++ ++@Defmac {PP, , ms} ++Sets a paragraph with an initial indentation. ++@endDefmac ++ ++@Defmac {LP, , ms} ++Sets a paragraph without an initial indentation. ++@endDefmac ++ ++@Defmac {QP, , ms} ++Sets a paragraph that is indented at both left and right margins. The ++effect is identical to the @acronym{HTML} @code{
    } element. ++The next paragraph or heading returns margins to normal. ++@endDefmac ++ ++@Defmac {XP, , ms} ++Sets a paragraph whose lines are indented, except for the first line. ++This is a Berkeley extension. ++@endDefmac ++ ++The following markup uses all four paragraph macros. ++ ++@CartoucheExample ++.NH 2 ++Cases used in the study ++.LP ++The following software and versions were ++considered for this report. ++.PP ++For commercial software, we chose ++.B "Microsoft Word for Windows" , ++starting with version 1.0 through the ++current version (Word 2000). ++.PP ++For free software, we chose ++.B Emacs , ++from its first appearance as a standalone ++editor through the current version (v20). ++See [Bloggs 2002] for details. ++.QP ++Franklin's Law applied to software: ++software expands to outgrow both ++RAM and disk space over time. ++.LP ++Bibliography: ++.XP ++Bloggs, Joseph R., ++.I "Everyone's a Critic" , ++Underground Press, March 2002. ++A definitive work that answers all questions ++and criticisms about the quality and usability of ++free software. ++@endCartoucheExample ++ ++The @code{PORPHANS} register (@pxref{ms Document Control Registers}) ++operates in conjunction with each of these macros, to inhibit the ++printing of orphan lines at the bottom of any page. ++ ++@c --------------------------------------------------------------------- ++ ++@node Headings in ms, Highlighting in ms, Paragraphs in ms, ms Body Text ++@subsubsection Headings ++@cindex @code{ms} macros, headings ++ ++Use headings to create a hierarchical structure for your document. The ++@file{ms} macros print headings in @strong{bold}, using the same font ++family and point size as the body text. ++ ++The following describes the heading macros: ++ ++@DefmacList {NH, @Var{curr-level}, ms} ++@DefmacListEnd {NH, @t{S} @Var{level0} @dots{}, ms} ++Numbered heading. The argument is either a numeric argument to indicate ++the level of the heading, or the letter@tie{}@code{S} followed by ++numeric arguments to set the heading level explicitly. ++ ++If you specify heading levels out of sequence, such as invoking ++@samp{.NH 3} after @samp{.NH 1}, @code{groff} prints a warning on ++standard error. ++@endDefmac ++ ++@DefstrList {SN, ms} ++@DefstrItemx {SN-DOT, ms} ++@DefstrListEndx {SN-NO-DOT, ms} ++After invocation of @code{NH}, the assigned section number is made ++available in the strings @code{SN-DOT} (as it appears in a printed ++section heading with default formatting, followed by a terminating ++period), and @code{SN-NO-DOT} (with the terminating period omitted). ++The string @code{SN} is also defined, as an alias for @code{SN-DOT}; if ++preferred, you may redefine it as an alias for @code{SN-NO-DOT}, by ++including the initialization ++@Example ++.als SN SN-NO-DOT ++@endExample ++ ++@noindent ++at any time @strong{before} you would like the change to take effect. ++@endDefstr ++ ++@Defstr {SN-STYLE, ms} ++You may control the style used to print section numbers, within numbered ++section headings, by defining an appropriate alias for the string ++@code{SN-STYLE}. The default style, in which the printed section number ++is followed by a terminating period, is obtained by defining the alias ++ ++@Example ++.als SN-STYLE SN-DOT ++@endExample ++ ++@noindent ++If you prefer to omit the terminating period, from section numbers ++appearing in numbered section headings, you may define the alias ++ ++@Example ++.als SN-STYLE SN-NO-DOT ++@endExample ++ ++@noindent ++Any such change in section numbering style becomes effective from the ++next use of @code{.NH}, following redefinition of the alias for ++@code{SN-STYLE}. ++@endDefstr ++ ++@Defmac {SH, [@Var{match-level}], ms} ++Unnumbered subheading. ++ ++The optional @var{match-level} argument is a GNU extension. It is a ++number indicating the level of the heading, in a manner analogous to the ++@var{curr-level} argument to @code{.NH}. Its purpose is to match the ++point size, at which the heading is printed, to the size of a numbered ++heading at the same level, when the @code{GROWPS} and @code{PSINCR} ++heading size adjustment mechanism is in effect. @xref{ms Document ++Control Registers}. ++@endDefmac ++ ++The @code{HORPHANS} register (@pxref{ms Document Control Registers}) ++operates in conjunction with the @code{NH} and @code{SH} macros, to ++inhibit the printing of orphaned section headings at the bottom of any ++page. ++ ++@c --------------------------------------------------------------------- ++ ++@node Highlighting in ms, Lists in ms, Headings in ms, ms Body Text ++@subsubsection Highlighting ++@cindex @code{ms} macros, highlighting ++ ++The @file{ms} macros provide a variety of methods to highlight or ++emphasize text: ++ ++@Defmac {B, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} ++Sets its first argument in @strong{bold type}. If you specify a second ++argument, @code{groff} prints it in the previous font after the bold ++text, with no intervening space (this allows you to set punctuation ++after the highlighted text without highlighting the punctuation). ++Similarly, it prints the third argument (if any) in the previous font ++@strong{before} the first argument. For example, ++ ++@Example ++.B foo ) ( ++@endExample ++ ++prints (@strong{foo}). ++ ++If you give this macro no arguments, @code{groff} prints all text ++following in bold until the next highlighting, paragraph, or heading ++macro. ++@endDefmac ++ ++@Defmac {R, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} ++Sets its first argument in roman (or regular) type. It operates ++similarly to the @code{B}@tie{}macro otherwise. ++@endDefmac ++ ++@Defmac {I, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} ++Sets its first argument in @emph{italic type}. It operates similarly ++to the @code{B}@tie{}macro otherwise. ++@endDefmac ++ ++@Defmac {CW, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} ++Sets its first argument in a @code{constant width face}. It operates ++similarly to the @code{B}@tie{}macro otherwise. ++@endDefmac ++ ++@Defmac {BI, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} ++Sets its first argument in bold italic type. It operates similarly to ++the @code{B}@tie{}macro otherwise. ++@endDefmac ++ ++@Defmac {BX, [@Var{txt}], ms} ++Prints its argument and draws a box around it. If you want to box a ++string that contains spaces, use a digit-width space (@code{\0}). ++@endDefmac ++ ++@Defmac {UL, [@Var{txt} [@Var{post}]], ms} ++Prints its first argument with an underline. If you specify a second ++argument, @code{groff} prints it in the previous font after the ++underlined text, with no intervening space. ++@endDefmac ++ ++@Defmac {LG, , ms} ++Prints all text following in larger type (two points larger than the ++current point size) until the next font size, highlighting, paragraph, ++or heading macro. You can specify this macro multiple times to ++enlarge the point size as needed. ++@endDefmac ++ ++@Defmac {SM, , ms} ++Prints all text following in smaller type (two points smaller than the ++current point size) until the next type size, highlighting, paragraph, ++or heading macro. You can specify this macro multiple times to reduce ++the point size as needed. ++@endDefmac ++ ++@Defmac {NL, , ms} ++Prints all text following in the normal point size (that is, the value ++of the @code{PS} register). ++@endDefmac ++ ++@DefstrList {@Lbrace{}, ms} ++@DefstrListEndx {@Rbrace{}, ms} ++Text enclosed with @code{\*@{} and @code{\*@}} is printed as a ++superscript. ++@endDefstr ++ ++@c --------------------------------------------------------------------- ++ ++@node Lists in ms, Indentation values in ms, Highlighting in ms, ms Body Text ++@subsubsection Lists ++@cindex @code{ms} macros, lists ++ ++The @code{IP} macro handles duties for all lists. ++ ++@Defmac {IP, [@Var{marker} [@Var{width}]], ms} ++The @var{marker} is usually a bullet glyph (@code{\[bu]}) for unordered ++lists, a number (or auto-incrementing number register) for numbered ++lists, or a word or phrase for indented (glossary-style) lists. ++ ++The @var{width} specifies the indentation for the body of each list ++item; its default unit is @samp{n}. Once specified, the indentation ++remains the same for all list items in the document until specified ++again. ++ ++The @code{PORPHANS} register (@pxref{ms Document Control Registers}) ++operates in conjunction with the @code{IP} macro, to inhibit the ++printing of orphaned list markers at the bottom of any page. ++@endDefmac ++ ++The following is an example of a bulleted list. ++@cindex example markup, bulleted list [@code{ms}] ++@cindex bulleted list, example markup [@code{ms}] ++ ++@Example ++A bulleted list: ++.IP \[bu] 2 ++lawyers ++.IP \[bu] ++guns ++.IP \[bu] ++money ++@endExample ++ ++Produces: ++ ++@Example ++A bulleted list: ++ ++o lawyers ++ ++o guns ++ ++o money ++@endExample ++ ++The following is an example of a numbered list. ++@cindex example markup, numbered list [@code{ms}] ++@cindex numbered list, example markup [@code{ms}] ++ ++@Example ++.nr step 1 1 ++A numbered list: ++.IP \n[step] 3 ++lawyers ++.IP \n+[step] ++guns ++.IP \n+[step] ++money ++@endExample ++ ++Produces: ++ ++@Example ++A numbered list: ++ ++1. lawyers ++ ++2. guns ++ ++3. money ++@endExample ++ ++Note the use of the auto-incrementing number register in this example. ++ ++The following is an example of a glossary-style list. ++@cindex example markup, glossary-style list [@code{ms}] ++@cindex glossary-style list, example markup [@code{ms}] ++ ++@Example ++A glossary-style list: ++.IP lawyers 0.4i ++Two or more attorneys. ++.IP guns ++Firearms, preferably ++large-caliber. ++.IP money ++Gotta pay for those ++lawyers and guns! ++@endExample ++ ++Produces: ++ ++@Example ++A glossary-style list: ++ ++lawyers ++ Two or more attorneys. ++ ++guns Firearms, preferably large-caliber. ++ ++money ++ Gotta pay for those lawyers and guns! ++@endExample ++ ++In the last example, the @code{IP} macro places the definition on the ++same line as the term if it has enough space; otherwise, it breaks to ++the next line and starts the definition below the term. This may or may ++not be the effect you want, especially if some of the definitions break ++and some do not. The following examples show two possible ways to force ++a break. ++ ++The first workaround uses the @code{br} request to force a break after ++printing the term or label. ++ ++@CartoucheExample ++A glossary-style list: ++.IP lawyers 0.4i ++Two or more attorneys. ++.IP guns ++.br ++Firearms, preferably large-caliber. ++.IP money ++Gotta pay for those lawyers and guns! ++@endCartoucheExample ++ ++The second workaround uses the @code{\p} escape to force the break. ++Note the space following the escape; this is important. If you omit the ++space, @code{groff} prints the first word on the same line as the term ++or label (if it fits) @strong{then} breaks the line. ++ ++@CartoucheExample ++A glossary-style list: ++.IP lawyers 0.4i ++Two or more attorneys. ++.IP guns ++\p Firearms, preferably large-caliber. ++.IP money ++Gotta pay for those lawyers and guns! ++@endCartoucheExample ++ ++To set nested lists, use the @code{RS} and @code{RE} macros. ++@xref{Indentation values in ms}, for more information. ++@cindex @code{ms} macros, nested lists ++@cindex nested lists [@code{ms}] ++ ++For example: ++ ++@CartoucheExample ++.IP \[bu] 2 ++Lawyers: ++.RS ++.IP \[bu] ++Dewey, ++.IP \[bu] ++Cheatham, ++.IP \[bu] ++and Howe. ++.RE ++.IP \[bu] ++Guns ++@endCartoucheExample ++ ++Produces: ++ ++@Example ++o Lawyers: ++ ++ o Dewey, ++ ++ o Cheatham, ++ ++ o and Howe. ++ ++o Guns ++@endExample ++ ++@c --------------------------------------------------------------------- ++ ++@node Indentation values in ms, Tabstops in ms, Lists in ms, ms Body Text ++@subsubsection Indentation values ++ ++In many situations, you may need to indentation a section of text while ++still wrapping and filling. @xref{Lists in ms}, for an example of ++nested lists. ++ ++@DefmacList {RS, , ms} ++@DefmacListEndx {RE, , ms} ++These macros begin and end an indented section. The @code{PI} register ++controls the amount of indentation, allowing the indented text to line ++up under hanging and indented paragraphs. ++@endDefmac ++ ++@xref{ms Displays and Keeps}, for macros to indentation and turn off ++filling. ++ ++@c --------------------------------------------------------------------- ++ ++@node Tabstops in ms, ms Displays and Keeps, Indentation values in ms, ms Body Text ++@subsubsection Tab Stops ++ ++Use the @code{ta} request to define tab stops as needed. @xref{Tabs and ++Fields}. ++ ++@Defmac {TA, , ms} ++Use this macro to reset the tab stops to the default for @file{ms} ++(every 5n). You can redefine the @code{TA} macro to create a different ++set of default tab stops. ++@endDefmac ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Displays and Keeps, ms Insertions, Tabstops in ms, ms Body Text ++@subsubsection Displays and keeps ++@cindex @code{ms} macros, displays ++@cindex @code{ms} macros, keeps ++@cindex keeps [@code{ms}] ++@cindex displays [@code{ms}] ++ ++Use displays to show text-based examples or figures (such as code ++listings). ++ ++Displays turn off filling, so lines of code are displayed as-is without ++inserting @code{br} requests in between each line. Displays can be ++@dfn{kept} on a single page, or allowed to break across pages. ++ ++@DefmacList {DS, @t{L}, ms} ++@DefmacItemx {LD, , ms} ++@DefmacListEndx {DE, , ms} ++Left-justified display. The @samp{.DS L} call generates a page break, ++if necessary, to keep the entire display on one page. The @code{LD} ++macro allows the display to break across pages. The @code{DE} macro ++ends the display. ++@endDefmac ++ ++@DefmacList {DS, @t{I}, ms} ++@DefmacItemx {ID, , ms} ++@DefmacListEndx {DE, , ms} ++Indents the display as defined by the @code{DI} register. The @samp{.DS ++I} call generates a page break, if necessary, to keep the entire display ++on one page. The @code{ID} macro allows the display to break across ++pages. The @code{DE} macro ends the display. ++@endDefmac ++ ++@DefmacList {DS, @t{B}, ms} ++@DefmacItemx {BD, , ms} ++@DefmacListEndx {DE, , ms} ++Sets a block-centered display: the entire display is left-justified, but ++indented so that the longest line in the display is centered on the ++page. The @samp{.DS B} call generates a page break, if necessary, to ++keep the entire display on one page. The @code{BD} macro allows the ++display to break across pages. The @code{DE} macro ends the display. ++@endDefmac ++ ++@DefmacList {DS, @t{C}, ms} ++@DefmacItemx {CD, , ms} ++@DefmacListEndx {DE, , ms} ++Sets a centered display: each line in the display is centered. The ++@samp{.DS C} call generates a page break, if necessary, to keep the ++entire display on one page. The @code{CD} macro allows the display to ++break across pages. The @code{DE} macro ends the display. ++@endDefmac ++ ++@DefmacList {DS, @t{R}, ms} ++@DefmacItemx {RD, , ms} ++@DefmacListEndx {DE, , ms} ++Right-justifies each line in the display. The @samp{.DS R} call ++generates a page break, if necessary, to keep the entire display on one ++page. The @code{RD} macro allows the display to break across pages. ++The @code{DE} macro ends the display. ++@endDefmac ++ ++@DefmacList {Ds, , ms} ++@DefmacListEndx {De, , ms} ++These two macros were formerly provided as aliases for @code{DS} and ++@code{DE}, respectively. They have been removed, and should no longer ++be used. The original implementations of @code{DS} and @code{DE} are ++retained, and should be used instead. X11 documents that actually use ++@code{Ds} and @code{De} always load a specific macro file from the X11 ++distribution (@file{macros.t}) that provides proper definitions for the ++two macros. ++@endDefmac ++ ++On occasion, you may want to @dfn{keep} other text together on a page. ++For example, you may want to keep two paragraphs together, or a ++paragraph that refers to a table (or list, or other item) immediately ++following. The @file{ms} macros provide the @code{KS} and @code{KE} ++macros for this purpose. ++ ++@DefmacList {KS, , ms} ++@DefmacListEndx {KE, , ms} ++The @code{KS} macro begins a block of text to be kept on a single page, ++and the @code{KE} macro ends the block. ++@endDefmac ++ ++@DefmacList {KF, , ms} ++@DefmacListEndx {KE, , ms} ++Specifies a @dfn{floating keep}; if the keep cannot fit on the current ++page, @code{groff} holds the contents of the keep and allows text ++following the keep (in the source file) to fill in the remainder of the ++current page. When the page breaks, whether by an explicit @code{bp} ++request or by reaching the end of the page, @code{groff} prints the ++floating keep at the top of the new page. This is useful for printing ++large graphics or tables that do not need to appear exactly where ++specified. ++@endDefmac ++ ++You can also use the @code{ne} request to force a page break if there is ++not enough vertical space remaining on the page. ++ ++Use the following macros to draw a box around a section of text (such as ++a display). ++ ++@DefmacList {B1, , ms} ++@DefmacListEndx {B2, , ms} ++Marks the beginning and ending of text that is to have a box drawn ++around it. The @code{B1} macro begins the box; the @code{B2} macro ends ++it. Text in the box is automatically placed in a diversion (keep). ++@endDefmac ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Insertions, Example multi-page table, ms Displays and Keeps, ms Body Text ++@subsubsection Tables, figures, equations, and references ++@cindex @code{ms} macros, tables ++@cindex @code{ms} macros, figures ++@cindex @code{ms} macros, equations ++@cindex @code{ms} macros, references ++@cindex tables [@code{ms}] ++@cindex figures [@code{ms}] ++@cindex equations [@code{ms}] ++@cindex references [@code{ms}] ++ ++The @file{ms} macros support the standard @code{groff} preprocessors: ++@code{tbl}, @code{pic}, @code{eqn}, and @code{refer}. ++@pindex tbl ++@pindex pic ++@pindex eqn ++@pindex refer ++You mark text meant for preprocessors by enclosing it in pairs of tags ++as follows. ++ ++@DefmacList {TS, [@code{H}], ms} ++@DefmacListEndx {TE, , ms} ++Denotes a table, to be processed by the @code{tbl} preprocessor. The ++optional argument@tie{}@code{H} to @code{TS} instructs @code{groff} to ++create a running header with the information up to the @code{TH} macro. ++@code{groff} prints the header at the beginning of the table; if the ++table runs onto another page, @code{groff} prints the header on the next ++page as well. ++@endDefmac ++ ++@DefmacList {PS, , ms} ++@DefmacListEndx {PE, , ms} ++Denotes a graphic, to be processed by the @code{pic} preprocessor. You ++can create a @code{pic} file by hand, using the @acronym{AT&T} ++@code{pic} manual available on the Web as a reference, or by using a ++graphics program such as @code{xfig}. ++@endDefmac ++ ++@DefmacList {EQ, [@Var{align}], ms} ++@DefmacListEndx {EN, , ms} ++Denotes an equation, to be processed by the @code{eqn} preprocessor. ++The optional @var{align} argument can be @code{C}, @code{L}, ++or@tie{}@code{I} to center (the default), left-justify, or indent the ++equation. ++@endDefmac ++ ++@DefmacList {[, , ms} ++@DefmacListEndx {], , ms} ++Denotes a reference, to be processed by the @code{refer} preprocessor. ++The GNU @cite{refer(1)} man page provides a comprehensive reference to ++the preprocessor and the format of the bibliographic database. ++@endDefmac ++ ++@menu ++* Example multi-page table:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Example multi-page table, ms Footnotes, ms Insertions, ms Body Text ++@subsubsection An example multi-page table ++@cindex example markup, multi-page table [@code{ms}] ++@cindex multi-page table, example markup [@code{ms}] ++ ++The following is an example of how to set up a table that may print ++across two or more pages. ++ ++@CartoucheExample ++.TS H ++allbox expand; ++cb | cb . ++Text ...of heading... ++_ ++.TH ++.T& ++l | l . ++... the rest of the table follows... ++.CW ++.TE ++@endCartoucheExample ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Footnotes, , Example multi-page table, ms Body Text ++@subsubsection Footnotes ++@cindex @code{ms} macros, footnotes ++@cindex footnotes [@code{ms}] ++ ++The @file{ms} macro package has a flexible footnote system. You can ++specify either numbered footnotes or symbolic footnotes (that is, using ++a marker such as a dagger symbol). ++ ++@Defstr {*, ms} ++Specifies the location of a numbered footnote marker in the text. ++@endDefesc ++ ++@DefmacList {FS, , ms} ++@DefmacListEndx {FE, , ms} ++Specifies the text of the footnote. The default action is to create a ++numbered footnote; you can create a symbolic footnote by specifying a ++@dfn{mark} glyph (such as @code{\[dg]} for the dagger glyph) in the body ++text and as an argument to the @code{FS} macro, followed by the text of ++the footnote and the @code{FE} macro. ++@endDefmac ++ ++You can control how @code{groff} prints footnote numbers by changing the ++value of the @code{FF} register. @xref{ms Document Control Registers}. ++ ++@cindex footnotes, and keeps [@code{ms}] ++@cindex keeps, and footnotes [@code{ms}] ++@cindex footnotes, and displays [@code{ms}] ++@cindex displays, and footnotes [@code{ms}] ++Footnotes can be safely used within keeps and displays, but you should ++avoid using numbered footnotes within floating keeps. You can set a ++second @code{\**} marker between a @code{\**} and its corresponding ++@code{.FS} entry; as long as each @code{FS} macro occurs @emph{after} ++the corresponding @code{\**} and the occurrences of @code{.FS} are in ++the same order as the corresponding occurrences of @code{\**}. ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Page Layout, Differences from AT&T ms, ms Body Text, ms ++@subsection Page layout ++@cindex @code{ms} macros, page layout ++@cindex page layout [@code{ms}] ++ ++The default output from the @file{ms} macros provides a minimalist page ++layout: it prints a single column, with the page number centered at the ++top of each page. It prints no footers. ++ ++You can change the layout by setting the proper number registers and ++strings. ++ ++@menu ++* ms Headers and Footers:: ++* ms Margins:: ++* ms Multiple Columns:: ++* ms TOC:: ++* ms Strings and Special Characters:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Headers and Footers, ms Margins, ms Page Layout, ms Page Layout ++@subsubsection Headers and footers ++@cindex @code{ms} macros, headers ++@cindex @code{ms} macros, footers ++@cindex headers [@code{ms}] ++@cindex footers [@code{ms}] ++ ++For documents that do not distinguish between odd and even pages, set ++the following strings: ++ ++@DefstrList {LH, ms} ++@DefstrItemx {CH, ms} ++@DefstrListEndx {RH, ms} ++Sets the left, center, and right headers. ++@endDefstr ++ ++@DefstrList {LF, ms} ++@DefstrItemx {CF, ms} ++@DefstrListEndx {RF, ms} ++Sets the left, center, and right footers. ++@endDefstr ++ ++For documents that need different information printed in the even and ++odd pages, use the following macros: ++ ++@DefmacList {OH, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}, ms} ++@DefmacItemx {EH, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}, ms} ++@DefmacItemx {OF, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}, ms} ++@DefmacListEndx {EF, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}, ms} ++The @code{OH} and @code{EH} macros define headers for the odd and even ++pages; the @code{OF} and @code{EF} macros define footers for the odd and ++even pages. This is more flexible than defining the individual strings. ++ ++You can replace the quote (@code{'}) marks with any character not ++appearing in the header or footer text. ++@endDefmac ++ ++To specify custom header and footer processing, redefine the following ++macros: ++ ++@DefmacList {PT,, ms} ++@DefmacItemx {HD,, ms} ++@DefmacListEndx {BT,, ms} ++The @code{PT} macro defines a custom header; the @code{BT} macro defines ++a custom footer. These macros must handle odd/even/first page ++differences if necessary. ++ ++The @code{HD} macro defines additional header processing to take place ++after executing the @code{PT} macro. ++@endDefmac ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Margins, ms Multiple Columns, ms Headers and Footers, ms Page Layout ++@subsubsection Margins ++@cindex @code{ms} macros, margins ++ ++You control margins using a set of number registers. @xref{ms Document ++Control Registers}, for details. ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Multiple Columns, ms TOC, ms Margins, ms Page Layout ++@subsubsection Multiple columns ++@cindex @code{ms} macros, multiple columns ++@cindex multiple columns [@code{ms}] ++ ++The @file{ms} macros can set text in as many columns as do reasonably ++fit on the page. The following macros are available; all of them force ++a page break if a multi-column mode is already set. However, if the ++current mode is single-column, starting a multi-column mode does ++@emph{not} force a page break. ++ ++@Defmac {1C, , ms} ++Single-column mode. ++@endDefmac ++ ++@Defmac {2C, , ms} ++Two-column mode. ++@endDefmac ++ ++@Defmac {MC, [@Var{width} [@Var{gutter}]], ms} ++Multi-column mode. If you specify no arguments, it is equivalent to the ++@code{2C} macro. Otherwise, @var{width} is the width of each column and ++@var{gutter} is the space between columns. The @code{MINGW} number ++register controls the default gutter width. ++@endDefmac ++ ++@c --------------------------------------------------------------------- ++ ++@node ms TOC, ms Strings and Special Characters, ms Multiple Columns, ms Page Layout ++@subsubsection Creating a table of contents ++@cindex @code{ms} macros, creating table of contents ++@cindex table of contents, creating [@code{ms}] ++ ++The facilities in the @file{ms} macro package for creating a table of ++contents are semi-automated at best. Assuming that you want the table ++of contents to consist of the document's headings, you need to repeat ++those headings wrapped in @code{XS} and @code{XE} macros. ++ ++@DefmacList {XS, [@Var{page}], ms} ++@DefmacItemx {XA, [@Var{page}], ms} ++@DefmacListEndx {XE, , ms} ++These macros define a table of contents or an individual entry in the ++table of contents, depending on their use. The macros are very simple; ++they cannot indent a heading based on its level. The easiest way to ++work around this is to add tabs to the table of contents string. The ++following is an example: ++ ++@CartoucheExample ++.NH 1 ++Introduction ++.XS ++Introduction ++.XE ++.LP ++... ++.CW ++.NH 2 ++Methodology ++.XS ++Methodology ++.XE ++.LP ++... ++@endCartoucheExample ++ ++You can manually create a table of contents by beginning with the ++@code{XS} macro for the first entry, specifying the page number for that ++entry as the argument to @code{XS}. Add subsequent entries using the ++@code{XA} macro, specifying the page number for that entry as the ++argument to @code{XA}. The following is an example: ++ ++@CartoucheExample ++.XS 1 ++Introduction ++.XA 2 ++A Brief History of the Universe ++.XA 729 ++Details of Galactic Formation ++... ++.XE ++@endCartoucheExample ++@endDefmac ++ ++@Defmac {TC, [@code{no}], ms} ++Prints the table of contents on a new page, setting the page number ++to@tie{}@strong{i} (Roman lowercase numeral one). You should usually ++place this macro at the end of the file, since @code{groff} is a ++single-pass formatter and can only print what has been collected up to ++the point that the @code{TC} macro appears. ++ ++The optional argument @code{no} suppresses printing the title specified ++by the string register @code{TOC}. ++@endDefmac ++ ++@Defmac {PX, [@code{no}], ms} ++Prints the table of contents on a new page, using the current page ++numbering sequence. Use this macro to print a manually-generated table ++of contents at the beginning of your document. ++ ++The optional argument @code{no} suppresses printing the title specified ++by the string register @code{TOC}. ++@endDefmac ++ ++The @cite{Groff and Friends HOWTO} includes a @code{sed} script that ++automatically inserts @code{XS} and @code{XE} macro entries after each ++heading in a document. ++ ++Altering the @code{NH} macro to automatically build the table of ++contents is perhaps initially more difficult, but would save a great ++deal of time in the long run if you use @file{ms} regularly. ++ ++@c --------------------------------------------------------------------- ++ ++@node ms Strings and Special Characters, , ms TOC, ms Page Layout ++@subsubsection Strings and Special Characters ++@cindex @code{ms} macros, strings ++@cindex @code{ms} macros, special characters ++@cindex @code{ms} macros, accent marks ++@cindex accent marks [@code{ms}] ++@cindex special characters [@code{ms}] ++@cindex strings [@code{ms}] ++ ++The @file{ms} macros provide the following predefined strings. You can ++change the string definitions to help in creating documents in languages ++other than English. ++ ++@Defstr {REFERENCES, ms} ++Contains the string printed at the beginning of the references ++(bibliography) page. The default is @samp{References}. ++@endDefstr ++ ++@Defstr {ABSTRACT, ms} ++Contains the string printed at the beginning of the abstract. The ++default is @samp{ABSTRACT}. ++@endDefstr ++ ++@Defstr {TOC, ms} ++Contains the string printed at the beginning of the table of contents. ++@endDefstr ++ ++@DefstrList {MONTH1, ms} ++@DefstrItemx {MONTH2, ms} ++@DefstrItemx {MONTH3, ms} ++@DefstrItemx {MONTH4, ms} ++@DefstrItemx {MONTH5, ms} ++@DefstrItemx {MONTH6, ms} ++@DefstrItemx {MONTH7, ms} ++@DefstrItemx {MONTH8, ms} ++@DefstrItemx {MONTH9, ms} ++@DefstrItemx {MONTH10, ms} ++@DefstrItemx {MONTH11, ms} ++@DefstrListEndx {MONTH12, ms} ++Prints the full name of the month in dates. The default is ++@samp{January}, @samp{February}, etc. ++@endDefstr ++ ++The following special characters are available@footnote{For an ++explanation what special characters are see @ref{Special Characters}.}: ++ ++@Defstr {-, ms} ++Prints an em dash. ++@endDefstr ++ ++@DefstrList {Q, ms} ++@DefstrListEndx {U, ms} ++Prints typographer's quotes in troff, and plain quotes in nroff. ++@code{\*Q} is the left quote and @code{\*U} is the right quote. ++@endDefstr ++ ++Improved accent marks are available in the @file{ms} macros. ++ ++@Defmac {AM, , ms} ++Specify this macro at the beginning of your document to enable extended ++accent marks and special characters. This is a Berkeley extension. ++ ++To use the accent marks, place them @strong{after} the character being ++accented. ++ ++Note that groff's native support for accents is superior to the ++following definitions. ++@endDefmac ++ ++The following accent marks are available after invoking the @code{AM} ++macro: ++ ++@Defstr {', ms} ++Acute accent. ++@endDefstr ++ ++@Defstr {`, ms} ++Grave accent. ++@endDefstr ++ ++@Defstr {^, ms} ++Circumflex. ++@endDefstr ++ ++@Defstr {\,, ms} ++Cedilla. ++@endDefstr ++ ++@Defstr {~, ms} ++Tilde. ++@endDefstr ++ ++@deffn String @t{\*[:]} ++@ifnotinfo ++@stindex : @r{[}ms@r{]} ++@end ifnotinfo ++@ifinfo ++@stindex \*[@r{}] @r{[}ms@r{]} ++@end ifinfo ++Umlaut. ++@end deffn ++ ++@Defstr {v, ms} ++Hacek. ++@endDefstr ++ ++@Defstr {_, ms} ++Macron (overbar). ++@endDefstr ++ ++@Defstr {., ms} ++Underdot. ++@endDefstr ++ ++@Defstr {o, ms} ++Ring above. ++@endDefstr ++ ++The following are standalone characters available after invoking the ++@code{AM} macro: ++ ++@Defstr {?, ms} ++Upside-down question mark. ++@endDefstr ++ ++@Defstr {!, ms} ++Upside-down exclamation point. ++@endDefstr ++ ++@Defstr {8, ms} ++German ligature. ++@endDefstr ++ ++@Defstr {3, ms} ++Yogh. ++@endDefstr ++ ++@Defstr {Th, ms} ++Uppercase thorn. ++@endDefstr ++ ++@Defstr {th, ms} ++Lowercase thorn. ++@endDefstr ++ ++@Defstr {D-, ms} ++Uppercase eth. ++@endDefstr ++ ++@Defstr {d-, ms} ++Lowercase eth. ++@endDefstr ++ ++@Defstr {q, ms} ++Hooked o. ++@endDefstr ++ ++@Defstr {ae, ms} ++Lowercase ligature. ++@endDefstr ++ ++@Defstr {Ae, ms} ++Uppercase ligature. ++@endDefstr ++ ++@c --------------------------------------------------------------------- ++ ++@node Differences from AT&T ms, Naming Conventions, ms Page Layout, ms ++@subsection Differences from @acronym{AT&T} @file{ms} ++@cindex @code{ms} macros, differences from @acronym{AT&T} ++@cindex @acronym{AT&T} @code{troff}, @code{ms} macro package differences ++ ++This section lists the (minor) differences between the @code{groff -ms} ++macros and @acronym{AT&T} @code{troff -ms} macros. ++ ++@itemize @bullet ++@item ++The internals of @code{groff -ms} differ from the internals of ++@acronym{AT&T} @code{troff -ms}. Documents that depend upon ++implementation details of @acronym{AT&T} @code{troff -ms} may not format ++properly with @code{groff -ms}. ++ ++@item ++The general error-handling policy of @code{groff -ms} is to detect and ++report errors, rather than silently to ignore them. ++ ++@item ++@code{groff -ms} does not work in compatibility mode (this is, with the ++@option{-C} option). ++ ++@item ++There is no special support for typewriter-like devices. ++ ++@item ++@code{groff -ms} does not provide cut marks. ++ ++@item ++Multiple line spacing is not supported. Use a larger vertical spacing ++instead. ++ ++@item ++Some @acronym{UNIX} @code{ms} documentation says that the @code{CW} and ++@code{GW} number registers can be used to control the column width and ++gutter width, respectively. These number registers are not used in ++@code{groff -ms}. ++ ++@item ++Macros that cause a reset (paragraphs, headings, etc.@:) may change the ++indentation. Macros that change the indentation do not increment or ++decrement the indentation, but rather set it absolutely. This can cause ++problems for documents that define additional macros of their own. The ++solution is to use not the @code{in} request but instead the @code{RS} ++and @code{RE} macros. ++ ++@item ++To make @code{groff -ms} use the default page offset (which also ++specifies the left margin), the @code{PO} register must stay undefined ++until the first @file{-ms} macro is evaluated. This implies that ++@code{PO} should not be used early in the document, unless it is changed ++also: Remember that accessing an undefined register automatically ++defines it. ++@end itemize ++ ++@Defmpreg {GS, ms} ++This number register is set to@tie{}1 by the @code{groff -ms} macros, ++but it is not used by the @code{AT&T} @code{troff -ms} macros. ++Documents that need to determine whether they are being formatted with ++@code{AT&T} @code{troff -ms} or @code{groff -ms} should use this number ++register. ++@endDefmpreg ++ ++Emulations of a few ancient Bell Labs macros can be re-enabled by ++calling the otherwise undocumented @code{SC} section-header macro. ++Calling @code{SC} enables @code{UC} for marking up a product or ++application name, and the pair @code{P1}/@code{P2} for surrounding code ++example displays. ++ ++These are not enabled by default because (a)@tie{}they were not ++documented, in the original @code{ms} manual, and (b)@tie{}the @code{P1} ++and @code{UC} macros collide with different macros with the same names ++in the Berkeley version of @code{ms}. ++ ++These @code{groff} emulations are sufficient to give back the 1976 ++Kernighan@tie{}& Cherry paper @cite{Typsetting Mathematics -- User's ++Guide} its section headings, and restore some text that had gone missing ++as arguments of undefined macros. No warranty express or implied is ++given as to how well the typographic details these produce match the ++original Bell Labs macros. ++ ++@menu ++* Missing ms Macros:: ++* Additional ms Macros:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Missing ms Macros, Additional ms Macros, Differences from AT&T ms, Differences from AT&T ms ++@subsubsection @code{troff} macros not appearing in @code{groff} ++ ++Macros missing from @code{groff -ms} are cover page macros specific to ++Bell Labs and Berkeley. The macros known to be missing are: ++ ++@table @code ++@item .TM ++Technical memorandum; a cover sheet style ++ ++@item .IM ++Internal memorandum; a cover sheet style ++ ++@item .MR ++Memo for record; a cover sheet style ++ ++@item .MF ++Memo for file; a cover sheet style ++ ++@item .EG ++Engineer's notes; a cover sheet style ++ ++@item .TR ++Computing Science Tech Report; a cover sheet style ++ ++@item .OK ++Other keywords ++ ++@item .CS ++Cover sheet information ++ ++@item .MH ++A cover sheet macro ++@end table ++ ++@c --------------------------------------------------------------------- ++ ++@node Additional ms Macros, , Missing ms Macros, Differences from AT&T ms ++@subsubsection @code{groff} macros not appearing in @acronym{AT&T} @code{troff} ++ ++The @code{groff -ms} macros have a few minor extensions compared to the ++@acronym{AT&T} @code{troff -ms} macros. ++ ++@Defmac {AM, , ms} ++Improved accent marks. @xref{ms Strings and Special Characters}, for ++details. ++@endDefmac ++ ++@Defmac {DS, @t{I}, ms} ++Indented display. The default behavior of @acronym{AT&T} @code{troff ++-ms} was to indent; the @code{groff} default prints displays flush left ++with the body text. ++@endDefmac ++ ++@Defmac {CW, , ms} ++Print text in @code{constant width} (Courier) font. ++@endDefmac ++ ++@Defmac {IX, , ms} ++Indexing term (printed on standard error). You can write a script to ++capture and process an index generated in this manner. ++@endDefmac ++ ++The following additional number registers ++appear in @code{groff -ms}: ++ ++@Defmpreg {MINGW, ms} ++Specifies a minimum space between columns (for multi-column output); ++this takes the place of the @code{GW} register that was documented but ++apparently not implemented in @acronym{AT&T} @code{troff}. ++@endDefmpreg ++ ++Several new string registers are available as well. You can change ++these to handle (for example) the local language. @xref{ms Strings and ++Special Characters}, for details. ++ ++@c --------------------------------------------------------------------- ++ ++@node Naming Conventions, , Differences from AT&T ms, ms ++@subsection Naming Conventions ++@cindex @code{ms} macros, naming conventions ++@cindex naming conventions, @code{ms} macros ++ ++The following conventions are used for names of macros, strings and ++number registers. External names available to documents that use the ++@code{groff -ms} macros contain only uppercase letters and digits. ++ ++Internally the macros are divided into modules; naming conventions are ++as follows: ++ ++@itemize @bullet ++@item ++Names used only within one module are of the form ++@var{module}@code{*}@var{name}. ++ ++@item ++Names used outside the module in which they are defined are of the form ++@var{module}@code{@@}@var{name}. ++ ++@item ++Names associated with a particular environment are of the form ++@var{environment}@code{:}@var{name}; these are used only within the ++@code{par} module. ++ ++@item ++@var{name} does not have a module prefix. ++ ++@item ++Constructed names used to implement arrays are of the form ++@var{array}@code{!}@var{index}. ++@end itemize ++ ++Thus the groff ms macros reserve the following names: ++ ++@itemize @bullet ++@item ++Names containing the characters @code{*}, @code{@@}, and@tie{}@code{:}. ++ ++@item ++Names containing only uppercase letters and digits. ++@end itemize ++ ++ ++@c ===================================================================== ++ ++@node me, mm, ms, Macro Packages ++@section @file{me} ++@cindex @code{me} macro package ++ ++@c XXX documentation ++@c XXX this is a placeholder until we get stuff knocked into shape ++See the @file{meintro.me} and @file{meref.me} documents in groff's ++@file{doc} directory. ++ ++ ++@c ===================================================================== ++ ++@node mm, mom, me, Macro Packages ++@section @file{mm} ++@cindex @code{mm} macro package ++ ++@c XXX documentation ++@c XXX this is a placeholder until we get stuff knocked into shape ++See the @cite{groff_mm(7)} man page (type @command{man groff_mm} at the ++command line). ++ ++ ++@c ===================================================================== ++ ++@node mom, , mm, Macro Packages ++@section @file{mom} ++@cindex @code{mom} macro package ++ ++@c XXX documentation ++@c XXX this is a placeholder until we get stuff knocked into shape ++See the @cite{groff_mom(7)} man page (type @command{man groff_mom} at ++the command line), which gives a short overview and a link to its ++extensive documentation in HTML format. ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node gtroff Reference, Preprocessors, Macro Packages, Top ++@chapter @code{gtroff} Reference ++@cindex reference, @code{gtroff} ++@cindex @code{gtroff}, reference ++ ++This chapter covers @strong{all} of the facilities of @code{gtroff}. ++Users of macro packages may skip it if not interested in details. ++ ++ ++@menu ++* Text:: ++* Measurements:: ++* Expressions:: ++* Identifiers:: ++* Embedded Commands:: ++* Registers:: ++* Manipulating Filling and Adjusting:: ++* Manipulating Hyphenation:: ++* Manipulating Spacing:: ++* Tabs and Fields:: ++* Character Translations:: ++* Troff and Nroff Mode:: ++* Line Layout:: ++* Line Control:: ++* Page Layout:: ++* Page Control:: ++* Fonts and Symbols:: ++* Sizes:: ++* Strings:: ++* Conditionals and Loops:: ++* Writing Macros:: ++* Page Motions:: ++* Drawing Requests:: ++* Traps:: ++* Diversions:: ++* Environments:: ++* Suppressing output:: ++* Colors:: ++* I/O:: ++* Postprocessor Access:: ++* Miscellaneous:: ++* Gtroff Internals:: ++* Debugging:: ++* Implementation Differences:: ++@end menu ++ ++ ++@c ===================================================================== ++ ++@node Text, Measurements, gtroff Reference, gtroff Reference ++@section Text ++@cindex text, @code{gtroff} processing ++ ++@code{gtroff} input files contain text with control commands ++interspersed throughout. But, even without control codes, @code{gtroff} ++still does several things with the input text: ++ ++@itemize @bullet ++@item ++filling and adjusting ++ ++@item ++adding additional space after sentences ++ ++@item ++hyphenating ++ ++@item ++inserting implicit line breaks ++@end itemize ++ ++@menu ++* Filling and Adjusting:: ++* Hyphenation:: ++* Sentences:: ++* Tab Stops:: ++* Implicit Line Breaks:: ++* Input Conventions:: ++* Input Encodings:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Filling and Adjusting, Hyphenation, Text, Text ++@subsection Filling and Adjusting ++@cindex filling ++@cindex adjusting ++ ++When @code{gtroff} reads text, it collects words from the input and fits ++as many of them together on one output line as it can. This is known as ++@dfn{filling}. ++ ++@cindex leading spaces ++@cindex spaces, leading and trailing ++@cindex extra spaces ++@cindex trailing spaces ++Once @code{gtroff} has a @dfn{filled} line, it tries to @dfn{adjust} it. ++This means it widens the spacing between words until the text reaches ++the right margin (in the default adjustment mode). Extra spaces between ++words are preserved, but spaces at the end of lines are ignored. Spaces ++at the front of a line cause a @dfn{break} (breaks are explained in ++@ref{Implicit Line Breaks}). ++ ++@xref{Manipulating Filling and Adjusting}. ++ ++@c --------------------------------------------------------------------- ++ ++@node Hyphenation, Sentences, Filling and Adjusting, Text ++@subsection Hyphenation ++@cindex hyphenation ++ ++Since the odds are not great for finding a set of words, for every ++output line, which fit nicely on a line without inserting excessive ++amounts of space between words, @code{gtroff} hyphenates words so that ++it can justify lines without inserting too much space between words. It ++uses an internal hyphenation algorithm (a simplified version of the ++algorithm used within @TeX{}) to indicate which words can be hyphenated ++and how to do so. When a word is hyphenated, the first part of the word ++is added to the current filled line being output (with an attached ++hyphen), and the other portion is added to the next line to be filled. ++ ++@xref{Manipulating Hyphenation}. ++ ++@c --------------------------------------------------------------------- ++ ++@node Sentences, Tab Stops, Hyphenation, Text ++@subsection Sentences ++@cindex sentences ++ ++Although it is often debated, some typesetting rules say there should be ++different amounts of space after various punctuation marks. For ++example, the @cite{Chicago typsetting manual} says that a period at the ++end of a sentence should have twice as much space following it as would ++a comma or a period as part of an abbreviation. ++ ++@c XXX exact citation of Chicago manual ++ ++@cindex sentence space ++@cindex space between sentences ++@cindex french-spacing ++@code{gtroff} does this by flagging certain characters (normally ++@samp{!}, @samp{?}, and @samp{.}) as @dfn{end-of-sentence} characters. ++When @code{gtroff} encounters one of these characters at the end of a ++line, it appends a normal space followed by a @dfn{sentence space} in ++the formatted output. (This justifies one of the conventions mentioned ++in @ref{Input Conventions}.) ++ ++@cindex transparent characters ++@cindex character, transparent ++@cindex @code{dg} glyph, at end of sentence ++@cindex @code{rq} glyph, at end of sentence ++@cindex @code{cq} glyph, at end of sentence ++@cindex @code{"}, at end of sentence ++@cindex @code{'}, at end of sentence ++@cindex @code{)}, at end of sentence ++@cindex @code{]}, at end of sentence ++@cindex @code{*}, at end of sentence ++In addition, the following characters and symbols are treated ++transparently while handling end-of-sentence characters: @samp{"}, ++@samp{'}, @samp{)}, @samp{]}, @samp{*}, @code{\[dg]}, @code{\[rq]}, and ++@code{\[cq]}. ++ ++See the @code{cflags} request in @ref{Using Symbols}, for more details. ++ ++@cindex @code{\&}, at end of sentence ++To prevent the insertion of extra space after an end-of-sentence ++character (at the end of a line), append @code{\&}. ++ ++@c --------------------------------------------------------------------- ++ ++@node Tab Stops, Implicit Line Breaks, Sentences, Text ++@subsection Tab Stops ++@cindex tab stops ++@cindex stops, tabulator ++@cindex tab character ++@cindex character, tabulator ++ ++@cindex @acronym{EBCDIC} encoding ++@cindex encoding, @acronym{EBCDIC} ++@code{gtroff} translates @dfn{tabulator characters}, also called ++@dfn{tabs} (normally code point @acronym{ASCII} @code{0x09} or ++@acronym{EBCDIC} @code{0x05}), in the input into movements to the next ++tabulator stop. These tab stops are initially located every half inch ++across the page. Using this, simple tables can be made easily. ++However, it can often be deceptive as the appearance (and width) of the ++text on a terminal and the results from @code{gtroff} can vary greatly. ++ ++Also, a possible sticking point is that lines beginning with tab ++characters are still filled, again producing unexpected results. For ++example, the following input ++ ++@multitable {12345678} {12345678} {12345678} {12345678} ++@item ++@tab 1 @tab 2 @tab 3 ++@item ++@tab @tab 4 @tab 5 ++@end multitable ++ ++@noindent ++produces ++ ++@multitable {12345678} {12345678} {12345678} {12345678} {12345678} {12345678} {12345678} ++@item ++@tab 1 @tab 2 @tab 3 @tab @tab 4 @tab 5 ++@end multitable ++ ++@xref{Tabs and Fields}. ++ ++@c --------------------------------------------------------------------- ++ ++@node Implicit Line Breaks, Input Conventions, Tab Stops, Text ++@subsection Implicit Line Breaks ++@cindex implicit line breaks ++@cindex implicit breaks of lines ++@cindex line, implicit breaks ++@cindex break, implicit ++@cindex line break ++ ++An important concept in @code{gtroff} is the @dfn{break}. When a break ++occurs, @code{gtroff} outputs the partially filled line (unjustified), ++and resumes collecting and filling text on the next output line. ++ ++@cindex blank line ++@cindex empty line ++@cindex line, blank ++@cindex blank line macro (@code{blm}) ++There are several ways to cause a break in @code{gtroff}. A blank line ++not only causes a break, but it also outputs a one-line vertical space ++(effectively a blank line). Note that this behaviour can be modified ++with the blank line macro request @code{blm}. @xref{Blank Line Traps}. ++ ++@cindex fill mode ++@cindex mode, fill ++@cindex leading spaces macro (@code{lsm}) ++A line that begins with a space causes a break and the space is output ++at the beginning of the next line. Note that this space isn't adjusted, ++even in fill mode; however, the behaviour can be modified with the ++leading spaces macro request @code{lsm}. @xref{Leading Spaces Traps}. ++ ++The end of file also causes a break -- otherwise the last line of the ++document may vanish! ++ ++Certain requests also cause breaks, implicitly or explicitly. This is ++discussed in @ref{Manipulating Filling and Adjusting}. ++ ++@c --------------------------------------------------------------------- ++ ++@node Input Conventions, Input Encodings, Implicit Line Breaks, Text ++@subsection Input Conventions ++@cindex input conventions ++@cindex conventions for input ++ ++Since @code{gtroff} does filling automatically, it is traditional in ++@code{groff} not to try and type things in as nicely formatted ++paragraphs. These are some conventions commonly used when typing ++@code{gtroff} text: ++ ++@itemize @bullet ++@item ++Break lines after punctuation, particularly at the end of a sentence and ++in other logical places. Keep separate phrases on lines by themselves, ++as entire phrases are often added or deleted when editing. ++ ++@item ++Try to keep lines less than 40-60@tie{}characters, to allow space for ++inserting more text. ++ ++@item ++Do not try to do any formatting in a @acronym{WYSIWYG} manner (i.e., ++don't try using spaces to get proper indentation). ++@end itemize ++ ++@c --------------------------------------------------------------------- ++ ++@node Input Encodings, , Input Conventions, Text ++@subsection Input Encodings ++ ++Currently, the following input encodings are available. ++ ++@table @asis ++@item cp1047 ++@cindex encoding, input, @acronym{EBCDIC} ++@cindex @acronym{EBCDIC}, input encoding ++@cindex input encoding, @acronym{EBCDIC} ++@cindex encoding, input, cp1047 ++@cindex cp1047, input encoding ++@cindex input encoding, cp1047 ++@cindex IBM cp1047 input encoding ++@pindex cp1047.tmac ++This input encoding works only on @acronym{EBCDIC} platforms (and vice ++versa, the other input encodings don't work with @acronym{EBCDIC}); the ++file @file{cp1047.tmac} is by default loaded at start-up. ++ ++@item latin-1 ++@cindex encoding, input, @w{latin-1} (ISO @w{8859-1}) ++@cindex @w{latin-1} (ISO @w{8859-1}), input encoding ++@cindex ISO @w{8859-1} (@w{latin-1}), input encoding ++@cindex input encoding, @w{latin-1} (ISO @w{8859-1}) ++@pindex latin1.tmac ++This is the default input encoding on non-@acronym{EBCDIC} platforms; ++the file @file{latin1.tmac} is loaded at start-up. ++ ++@item latin-2 ++@cindex encoding, input, @w{latin-2} (ISO @w{8859-2}) ++@cindex @w{latin-2} (ISO @w{8859-2}), input encoding ++@cindex ISO @w{8859-2} (@w{latin-2}), input encoding ++@cindex input encoding, @w{latin-2} (ISO @w{8859-2}) ++@pindex latin2.tmac ++To use this encoding, either say @w{@samp{.mso latin2.tmac}} at the very ++beginning of your document or use @samp{-mlatin2} as a command line ++argument for @code{groff}. ++ ++@item latin-5 ++@cindex encoding, input, @w{latin-5} (ISO @w{8859-9}) ++@cindex @w{latin-2} (ISO @w{8859-9}), input encoding ++@cindex ISO @w{8859-9} (@w{latin-2}), input encoding ++@cindex input encoding, @w{latin-2} (ISO @w{8859-9}) ++@pindex latin2.tmac ++For Turkish. Either say @w{@samp{.mso latin9.tmac}} at the very ++beginning of your document or use @samp{-mlatin9} as a command line ++argument for @code{groff}. ++ ++@item latin-9 (latin-0) ++@cindex encoding, input, @w{latin-9} (@w{latin-0}, ISO @w{8859-15}) ++@cindex @w{latin-9} (@w{latin-0}, ISO @w{8859-15}), input encoding ++@cindex ISO @w{8859-15} (@w{latin-9}, @w{latin-0}), input encoding ++@cindex input encoding, @w{latin-9} (@w{latin-9}, ISO @w{8859-15}) ++@pindex latin9.tmac ++This encoding is intended (at least in Europe) to replace @w{latin-1} ++encoding. The main difference to @w{latin-1} is that @w{latin-9} ++contains the Euro character. To use this encoding, either say ++@w{@samp{.mso latin9.tmac}} at the very beginning of your document or ++use @samp{-mlatin9} as a command line argument for @code{groff}. ++@end table ++ ++Note that it can happen that some input encoding characters are not ++available for a particular output device. For example, saying ++ ++@Example ++groff -Tlatin1 -mlatin9 ... ++@endExample ++ ++@noindent ++fails if you use the Euro character in the input. Usually, this ++limitation is present only for devices that have a limited set of ++output glyphs (e.g.@: @option{-Tascii} and @option{-Tlatin1}); for other ++devices it is usually sufficient to install proper fonts that contain ++the necessary glyphs. ++ ++@pindex freeeuro.pfa ++@pindex ec.tmac ++Due to the importance of the Euro glyph in Europe, the groff package now ++comes with a @sc{PostScript} font called @file{freeeuro.pfa}, which ++provides various glyph shapes for the Euro. In other words, ++@w{latin-9} encoding is supported for the @option{-Tps} device out of ++the box (@w{latin-2} isn't). ++ ++By its very nature, @option{-Tutf8} supports all input encodings; ++@option{-Tdvi} has support for both @w{latin-2} and @w{latin-9} if the ++command line @option{-mec} is used also to load the file @file{ec.tmac} ++(which flips to the EC fonts). ++ ++ ++@c ===================================================================== ++ ++@node Measurements, Expressions, Text, gtroff Reference ++@section Measurements ++@cindex measurements ++@cindex scaling indicator ++@cindex indicator, scaling ++ ++@cindex units of measurement ++@cindex basic unit (@code{u}) ++@cindex machine unit (@code{u}) ++@cindex measurement unit ++@cindex @code{u} unit ++@cindex unit, @code{u} ++@code{gtroff} (like many other programs) requires numeric parameters to ++specify various measurements. Most numeric parameters@footnote{those ++that specify vertical or horizontal motion or a type size} may have a ++@dfn{measurement unit} attached. These units are specified as a single ++character that immediately follows the number or expression. Each of ++these units are understood, by @code{gtroff}, to be a multiple of its ++@dfn{basic unit}. So, whenever a different measurement unit is ++specified @code{gtroff} converts this into its @dfn{basic units}. This ++basic unit, represented by a @samp{u}, is a device dependent measurement, ++which is quite small, ranging from 1/75@dmn{th} to 1/72000@dmn{th} of an ++inch. The values may be given as fractional numbers; however, ++fractional basic units are always rounded to integers. ++ ++Some of the measurement units are completely independent of any of the ++current settings (e.g.@: type size) of @code{gtroff}. ++ ++@table @code ++@item i ++@cindex inch unit (@code{i}) ++@cindex @code{i} unit ++@cindex unit, @code{i} ++Inches. An antiquated measurement unit still in use in certain ++backwards countries with incredibly low-cost computer equipment. One ++inch is equal to@tie{}2.54@dmn{cm}. ++ ++@item c ++@cindex centimeter unit (@code{c}) ++@cindex @code{c} unit ++@cindex unit, @code{c} ++Centimeters. One centimeter is equal to@tie{}0.3937@dmn{in}. ++ ++@item p ++@cindex point unit (@code{p}) ++@cindex @code{p} unit ++@cindex unit, @code{p} ++Points. This is a typesetter's measurement used for measure type size. ++It is 72@tie{}points to an inch. ++ ++@item P ++@cindex pica unit (@code{P}) ++@cindex @code{P} unit ++@cindex unit, @code{P} ++Pica. Another typesetting measurement. 6@tie{}Picas to an inch (and ++12@tie{}points to a pica). ++ ++@item s ++@itemx z ++@cindex @code{s} unit ++@cindex unit, @code{s} ++@cindex @code{z} unit ++@cindex unit, @code{z} ++@xref{Fractional Type Sizes}, for a discussion of these units. ++ ++@item f ++@cindex @code{f} unit ++@cindex unit, @code{f} ++Fractions. Value is 65536. ++@xref{Colors}, for usage. ++@end table ++ ++The other measurements understood by @code{gtroff} depend on settings ++currently in effect in @code{gtroff}. These are very useful for ++specifying measurements that should look proper with any size of text. ++ ++@table @code ++@item m ++@cindex em unit (@code{m}) ++@cindex @code{m} unit ++@cindex unit, @code{m} ++Ems. This unit is equal to the current font size in points. So called ++because it is @emph{approximately} the width of the letter@tie{}@samp{m} ++in the current font. ++ ++@item n ++@cindex en unit (@code{n}) ++@cindex @code{n} unit ++@cindex unit, @code{n} ++Ens. In @code{groff}, this is half of an em. ++ ++@item v ++@cindex vertical space unit (@code{v}) ++@cindex space, vertical, unit (@code{v}) ++@cindex @code{v} unit ++@cindex unit, @code{v} ++Vertical space. This is equivalent to the current line spacing. ++@xref{Sizes}, for more information about this. ++ ++@item M ++@cindex @code{M} unit ++@cindex unit, @code{M} ++100ths of an em. ++@end table ++ ++@menu ++* Default Units:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Default Units, , Measurements, Measurements ++@subsection Default Units ++@cindex default units ++@cindex units, default ++ ++Many requests take a default unit. While this can be helpful at times, ++it can cause strange errors in some expressions. For example, the line ++length request expects em units. Here are several attempts to get a ++line length of 3.5@tie{}inches and their results: ++ ++@Example ++3.5i @result{} 3.5i ++7/2 @result{} 0i ++7/2i @result{} 0i ++(7 / 2)u @result{} 0i ++7i/2 @result{} 0.1i ++7i/2u @result{} 3.5i ++@endExample ++ ++@noindent ++Everything is converted to basic units first. In the above example it ++is assumed that 1@dmn{i} equals@tie{}240@dmn{u}, and 1@dmn{m} ++equals@tie{}10@dmn{p} (thus 1@dmn{m} equals@tie{}33@dmn{u}). The value ++7@dmn{i}/2 is first handled as 7@dmn{i}/2@dmn{m}, then converted to ++1680@dmn{u}/66@dmn{u}, which is 25@dmn{u}, and this is approximately ++0.1@dmn{i}. As can be seen, a scaling indicator after a closing ++parenthesis is simply ignored. ++ ++@cindex measurements, specifying safely ++Thus, the safest way to specify measurements is to always attach a ++scaling indicator. If you want to multiply or divide by a certain ++scalar value, use @samp{u} as the unit for that value. ++ ++ ++@c ===================================================================== ++ ++@node Expressions, Identifiers, Measurements, gtroff Reference ++@section Expressions ++@cindex expressions ++ ++@code{gtroff} has most arithmetic operators common to other languages: ++ ++@itemize @bullet ++@item ++@cindex arithmetic operators ++@cindex operators, arithmetic ++@opindex + ++@opindex - ++@opindex / ++@opindex * ++@opindex % ++Arithmetic: @samp{+} (addition), @samp{-} (subtraction), @samp{/} ++(division), @samp{*} (multiplication), @samp{%} (modulo). ++ ++@code{gtroff} only provides integer arithmetic. The internal type used ++for computing results is @samp{int}, which is usually a 32@dmn{bit} ++signed integer. ++ ++@item ++@cindex comparison operators ++@cindex operators, comparison ++@opindex < ++@opindex > ++@opindex >= ++@opindex <= ++@opindex = ++@opindex == ++Comparison: @samp{<} (less than), @samp{>} (greater than), @samp{<=} ++(less than or equal), @samp{>=} (greater than or equal), @samp{=} ++(equal), @samp{==} (the same as @samp{=}). ++ ++@item ++@cindex logical operators ++@cindex operators, logical ++@opindex & ++@ifnotinfo ++@opindex : ++@end ifnotinfo ++@ifinfo ++@opindex @r{} ++@end ifinfo ++Logical: @samp{&} (logical and), @samp{:} (logical or). ++ ++@item ++@cindex unary operators ++@cindex operators, unary ++@opindex - ++@opindex + ++@opindex ! ++@cindex @code{if} request, and the @samp{!} operator ++@cindex @code{while} request, and the @samp{!} operator ++Unary operators: @samp{-} (negating, i.e.@: changing the sign), @samp{+} ++(just for completeness; does nothing in expressions), @samp{!} (logical ++not; this works only within @code{if} and @code{while} ++requests).@footnote{Note that, for example, @samp{!(-1)} evaluates to ++`true' because @code{gtroff} treats both negative numbers and zero as ++`false'.} See below for the use of unary operators in motion requests. ++ ++@cindex logical not, limitation in expression ++@cindex expression, limitation of logical not in ++The logical not operator, ++as described above, ++works only within @code{if} and @code{while} requests. ++Furthermore, it may appear ++only at the beginning of an expression, ++and negates the entire expression. ++Attempting to insert the @samp{!} operator ++within the expression results in a ++@samp{numeric expression expected} warning. This ++maintains compatibility ++with old versions of @code{troff}. ++ ++Example: ++ ++@Example ++.nr X 1 ++.nr Y 0 ++.\" This does not work as expected ++.if (\n[X])&(!\n[Y]) .nop X only ++. ++.\" Use this construct instead ++.if (\n[X]=1)&(\n[Y]=0) .nop X only ++@endExample ++ ++@item ++@cindex extremum operators (@code{>?}, @code{?}, @code{? ++@opindex ?} (maximum), @samp{? \n[y]) ++@endExample ++ ++@noindent ++The register@tie{}@code{z} now contains@tie{}5. ++ ++@item ++@cindex scaling operator ++@cindex operator, scaling ++Scaling: @code{(@var{c};@var{e})}. Evaluate@tie{}@var{e} ++using@tie{}@var{c} as the default scaling indicator. If @var{c} is ++missing, ignore scaling indicators in the evaluation of@tie{}@var{e}. ++@end itemize ++ ++@cindex parentheses ++@cindex order of evaluation in expressions ++@cindex expression, order of evaluation ++@opindex ( ++@opindex ) ++Parentheses may be used as in any other language. However, in ++@code{gtroff} they are necessary to ensure order of evaluation. ++@code{gtroff} has no operator precedence; expressions are evaluated left ++to right. This means that @code{gtroff} evaluates @samp{3+5*4} as if it ++were parenthesized like @samp{(3+5)*4}, not as @samp{3+(5*4)}, as might ++be expected. ++ ++@cindex @code{+}, and page motion ++@cindex @code{-}, and page motion ++@cindex motion operators ++@cindex operators, motion ++For many requests that cause a motion on the page, the unary operators ++@samp{+} and @samp{-} work differently if leading an expression. They ++then indicate a motion relative to the current position (down or up, ++respectively). ++ ++@cindex @code{|}, and page motion ++@cindex absolute position operator (@code{|}) ++@cindex position, absolute, operator (@code{|}) ++Similarly, a leading @samp{|} operator indicates an absolute position. ++For vertical movements, it specifies the distance from the top of the ++page; for horizontal movements, it gives the distance from the beginning ++of the @emph{input} line. ++ ++@cindex @code{bp} request, using @code{+} and@tie{}@code{-} ++@cindex @code{in} request, using @code{+} and@tie{}@code{-} ++@cindex @code{ll} request, using @code{+} and@tie{}@code{-} ++@cindex @code{lt} request, using @code{+} and@tie{}@code{-} ++@cindex @code{nm} request, using @code{+} and@tie{}@code{-} ++@cindex @code{nr} request, using @code{+} and@tie{}@code{-} ++@cindex @code{pl} request, using @code{+} and@tie{}@code{-} ++@cindex @code{pn} request, using @code{+} and@tie{}@code{-} ++@cindex @code{po} request, using @code{+} and@tie{}@code{-} ++@cindex @code{ps} request, using @code{+} and@tie{}@code{-} ++@cindex @code{pvs} request, using @code{+} and@tie{}@code{-} ++@cindex @code{rt} request, using @code{+} and@tie{}@code{-} ++@cindex @code{ti} request, using @code{+} and@tie{}@code{-} ++@cindex @code{\H}, using @code{+} and@tie{}@code{-} ++@cindex @code{\R}, using @code{+} and@tie{}@code{-} ++@cindex @code{\s}, using @code{+} and@tie{}@code{-} ++@samp{+} and @samp{-} are also treated differently by the following ++requests and escapes: @code{bp}, @code{in}, @code{ll}, @code{lt}, ++@code{nm}, @code{nr}, @code{pl}, @code{pn}, @code{po}, @code{ps}, ++@code{pvs}, @code{rt}, @code{ti}, @code{\H}, @code{\R}, and @code{\s}. ++Here, leading plus and minus signs indicate increments and decrements. ++ ++@xref{Setting Registers}, for some examples. ++ ++@Defesc {\\B, ', anything, '} ++@cindex numeric expression, valid ++@cindex valid numeric expression ++Return@tie{}1 if @var{anything} is a valid numeric expression; or@tie{}0 ++if @var{anything} is empty or not a valid numeric expression. ++@endDefesc ++ ++@cindex space characters, in expressions ++@cindex expressions, and space characters ++Due to the way arguments are parsed, spaces are not allowed in ++expressions, unless the entire expression is surrounded by parentheses. ++ ++@xref{Request and Macro Arguments}, and @ref{Conditionals and Loops}. ++ ++ ++@c ===================================================================== ++ ++@node Identifiers, Embedded Commands, Expressions, gtroff Reference ++@section Identifiers ++@cindex identifiers ++ ++Like any other language, @code{gtroff} has rules for properly formed ++@dfn{identifiers}. In @code{gtroff}, an identifier can be made up of ++almost any printable character, with the exception of the following ++characters: ++ ++@itemize @bullet ++@item ++@cindex whitespace characters ++@cindex newline character ++@cindex character, whitespace ++Whitespace characters (spaces, tabs, and newlines). ++ ++@item ++@cindex character, backspace ++@cindex backspace character ++@cindex @acronym{EBCDIC} encoding of backspace ++Backspace (@acronym{ASCII}@tie{}@code{0x08} or ++@acronym{EBCDIC}@tie{}@code{0x16}) and character code @code{0x01}. ++ ++@item ++@cindex invalid input characters ++@cindex input characters, invalid ++@cindex characters, invalid input ++@cindex Unicode ++The following input characters are invalid and are ignored if ++@code{groff} runs on a machine based on @acronym{ASCII}, causing a ++warning message of type @samp{input} (see @ref{Debugging}, for more ++details): @code{0x00}, @code{0x0B}, @code{0x0D}-@code{0x1F}, ++@code{0x80}-@code{0x9F}. ++ ++And here are the invalid input characters if @code{groff} runs on an ++@acronym{EBCDIC} host: @code{0x00}, @code{0x08}, @code{0x09}, ++@code{0x0B}, @code{0x0D}-@code{0x14}, @code{0x17}-@code{0x1F}, ++@code{0x30}-@code{0x3F}. ++ ++Currently, some of these reserved codepoints are used internally, thus ++making it non-trivial to extend @code{gtroff} to cover Unicode or other ++character sets and encodings that use characters of these ranges. ++ ++Note that invalid characters are removed before parsing; an identifier ++@code{foo}, followed by an invalid character, followed by @code{bar} is ++treated as @code{foobar}. ++@end itemize ++ ++For example, any of the following is valid. ++ ++@Example ++br ++PP ++(l ++end-list ++@@_ ++@endExample ++ ++@cindex @code{]}, as part of an identifier ++@noindent ++Note that identifiers longer than two characters with a closing bracket ++(@samp{]}) in its name can't be accessed with escape sequences that ++expect an identifier as a parameter. For example, @samp{\[foo]]} ++accesses the glyph @samp{foo}, followed by @samp{]}, whereas ++@samp{\C'foo]'} really asks for glyph @samp{foo]}. ++ ++@cindex @code{refer}, and macro names starting with @code{[} or @code{]} ++@cindex @code{[}, macro names starting with, and @code{refer} ++@cindex @code{]}, macro names starting with, and @code{refer} ++@cindex macro names, starting with @code{[} or @code{]}, and @code{refer} ++To avoid problems with the @code{refer} preprocessor, macro names should ++not start with @samp{[} or @samp{]}. Due to backwards compatibility, ++everything after @samp{.[} and @samp{.]} is handled as a special ++argument to @code{refer}. For example, @samp{.[foo} makes @code{refer} ++to start a reference, using @samp{foo} as a parameter. ++ ++@Defesc {\\A, ', ident, '} ++Test whether an identifier @var{ident} is valid in @code{gtroff}. It ++expands to the character@tie{}1 or@tie{}0 according to whether its ++argument (usually delimited by quotes) is or is not acceptable as the ++name of a string, macro, diversion, number register, environment, or ++font. It returns@tie{}0 if no argument is given. This is useful for ++looking up user input in some sort of associative table. ++ ++@Example ++\A'end-list' ++ @result{} 1 ++@endExample ++@endDefesc ++ ++@xref{Escapes}, for details on parameter delimiting characters. ++ ++Identifiers in @code{gtroff} can be any length, but, in some contexts, ++@code{gtroff} needs to be told where identifiers end and text begins ++(and in different ways depending on their length): ++ ++@itemize @bullet ++@item ++Single character. ++ ++@cindex @code{(}, starting a two-character identifier ++@item ++Two characters. Must be prefixed with @samp{(} in some situations. ++ ++@cindex @code{[}, starting an identifier ++@cindex @code{]}, ending an identifier ++@item ++Arbitrary length (@code{gtroff} only). Must be bracketed with @samp{[} ++and@tie{}@samp{]} in some situations. Any length identifier can be put ++in brackets. ++@end itemize ++ ++@cindex undefined identifiers ++@cindex identifiers, undefined ++Unlike many other programming languages, undefined identifiers are ++silently ignored or expanded to nothing. When @code{gtroff} finds an ++undefined identifier, it emits a warning, doing the following: ++ ++@itemize @bullet ++@item ++If the identifier is a string, macro, or diversion, @code{gtroff} ++defines it as empty. ++ ++@item ++If the identifier is a number register, @code{gtroff} defines it with a ++value of@tie{}0. ++@end itemize ++ ++@xref{Warnings}., @ref{Interpolating Registers}, and @ref{Strings}. ++ ++Note that macros, strings, and diversions share the same name space. ++ ++@Example ++.de xxx ++. nop foo ++.. ++. ++.di xxx ++bar ++.br ++.di ++. ++.xxx ++ @result{} bar ++@endExample ++ ++@noindent ++As can be seen in the previous example, @code{gtroff} reuses the ++identifier @samp{xxx}, changing it from a macro to a diversion. No ++warning is emitted! The contents of the first macro definition is lost. ++ ++@xref{Interpolating Registers}, and @ref{Strings}. ++ ++ ++@c ===================================================================== ++ ++@node Embedded Commands, Registers, Identifiers, gtroff Reference ++@section Embedded Commands ++@cindex embedded commands ++@cindex commands, embedded ++ ++Most documents need more functionality beyond filling, adjusting and ++implicit line breaking. In order to gain further functionality, ++@code{gtroff} allows commands to be embedded into the text, in two ways. ++ ++The first is a @dfn{request} that takes up an entire line, and does ++some large-scale operation (e.g.@: break lines, start new pages). ++ ++The other is an @dfn{escape} that can be usually embedded anywhere in ++the text; most requests can accept it even as an argument. Escapes ++generally do more minor operations like sub- and superscripts, print a ++symbol, etc. ++ ++@menu ++* Requests:: ++* Macros:: ++* Escapes:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Requests, Macros, Embedded Commands, Embedded Commands ++@subsection Requests ++@cindex requests ++ ++@cindex control character (@code{.}) ++@cindex character, control (@code{.}) ++@cindex no-break control character (@code{'}) ++@cindex character, no-break control (@code{'}) ++@cindex control character, no-break (@code{'}) ++A request line begins with a control character, which is either a single ++quote (@samp{'}, the @dfn{no-break control character}) or a period ++(@samp{.}, the normal @dfn{control character}). These can be changed; ++see @ref{Character Translations}, for details. After this there may be ++optional tabs or spaces followed by an identifier, which is the name of ++the request. This may be followed by any number of space-separated ++arguments (@emph{no} tabs here). ++ ++@cindex structuring source code of documents or macro packages ++@cindex documents, structuring the source code ++@cindex macro packages, structuring the source code ++Since a control character followed by whitespace only is ignored, it is ++common practice to use this feature for structuring the source code of ++documents or macro packages. ++ ++@Example ++.de foo ++. tm This is foo. ++.. ++. ++. ++.de bar ++. tm This is bar. ++.. ++@endExample ++ ++@cindex blank line ++@cindex blank line macro (@code{blm}) ++Another possibility is to use the blank line macro request @code{blm} by ++assigning an empty macro to it. ++ ++@Example ++.de do-nothing ++.. ++.blm do-nothing \" activate blank line macro ++ ++.de foo ++. tm This is foo. ++.. ++ ++ ++.de bar ++. tm This is bar. ++.. ++ ++.blm \" deactivate blank line macro ++@endExample ++ ++@xref{Blank Line Traps}. ++ ++@cindex zero width space character (@code{\&}) ++@cindex character, zero width space (@code{\&}) ++@cindex space character, zero width (@code{\&}) ++@cindex @code{\&}, escaping control characters ++To begin a line with a control character without it being interpreted, ++precede it with @code{\&}. This represents a zero width space, which ++means it does not affect the output. ++ ++In most cases the period is used as a control character. Several ++requests cause a break implicitly; using the single quote control ++character prevents this. ++ ++@Defreg {.br} ++A read-only number register, which is set to@tie{}1 if a macro is called ++with the normal control character (as defined with the @code{cc} ++request), and set to@tie{}0 otherwise. ++ ++@cindex modifying requests ++@cindex requests, modifying ++This allows to reliably modify requests. ++ ++@Example ++.als bp*orig bp ++.de bp ++. tm before bp ++. ie \\n[.br] .bp*orig ++. el 'bp*orig ++. tm after bp ++.. ++@endExample ++ ++Using this register outside of a macro makes no sense (it always returns ++zero in such cases). ++ ++If a macro is called as a string (this is, using @code{\*}), the value ++of the @code{.br} register is inherited from the calling macro. ++@endDefreg ++ ++@menu ++* Request and Macro Arguments:: ++@end menu ++ ++@node Request and Macro Arguments, , Requests, Requests ++@subsubsection Request and Macro Arguments ++@cindex request arguments ++@cindex macro arguments ++@cindex arguments to requests and macros ++ ++@cindex tabs, and macro arguments ++@cindex macro arguments, and tabs ++@cindex arguments to macros, and tabs ++Arguments to requests and macros are processed much like the shell: ++The line is split into arguments according to ++spaces.@footnote{Plan@tie{}9's @code{troff} implementation also allows ++tabs for argument separation -- @code{gtroff} intentionally doesn't ++support this.} ++ ++@cindex spaces, in a macro argument ++An argument to a macro that is intended to contain spaces can either be ++enclosed in double quotes, or have the spaces @dfn{escaped} with ++backslashes. This is @emph{not} true for requests. ++ ++Here are a few examples for a hypothetical macro @code{uh}: ++ ++@Example ++.uh The Mouse Problem ++.uh "The Mouse Problem" ++.uh The\ Mouse\ Problem ++@endExample ++ ++@cindex @code{\~}, difference to @code{\@key{SP}} ++@cindex @code{\@key{SP}}, difference to @code{\~} ++@noindent ++The first line is the @code{uh} macro being called with 3 arguments, ++@samp{The}, @samp{Mouse}, and @samp{Problem}. The latter two have the ++same effect of calling the @code{uh} macro with one argument, @samp{The ++Mouse Problem}.@footnote{The last solution, i.e., using escaped spaces, ++is ``classical'' in the sense that it can be found in most @code{troff} ++documents. Nevertheless, it is not optimal in all situations, since ++@w{@samp{\ }} inserts a fixed-width, non-breaking space character that ++can't stretch. @code{gtroff} provides a different command @code{\~} to ++insert a stretchable, non-breaking space.} ++ ++@cindex @code{"}, in a macro argument ++@cindex double quote, in a macro argument ++A double quote that isn't preceded by a space doesn't start a macro ++argument. If not closing a string, it is printed literally. ++ ++For example, ++ ++@Example ++.xxx a" "b c" "de"fg" ++@endExample ++ ++@noindent ++has the arguments @samp{a"}, @w{@samp{b c}}, @samp{de}, and @samp{fg"}. ++Don't rely on this obscure behaviour! ++ ++There are two possibilities to get a double quote reliably. ++ ++@itemize @bullet ++@item ++Enclose the whole argument with double quotes and use two consecutive ++double quotes to represent a single one. This traditional solution has ++the disadvantage that double quotes don't survive argument expansion ++again if called in compatibility mode (using the @option{-C} option of ++@code{groff}): ++ ++@Example ++.de xx ++. tm xx: `\\$1' `\\$2' `\\$3' ++. ++. yy "\\$1" "\\$2" "\\$3" ++.. ++.de yy ++. tm yy: `\\$1' `\\$2' `\\$3' ++.. ++.xx A "test with ""quotes""" . ++ @result{} xx: `A' `test with "quotes"' `.' ++ @result{} yy: `A' `test with ' `quotes""' ++@endExample ++ ++@noindent ++If not in compatibility mode, you get the expected result ++ ++@Example ++xx: `A' `test with "quotes"' `.' ++yy: `A' `test with "quotes"' `.' ++@endExample ++ ++@noindent ++since @code{gtroff} preserves the input level. ++ ++@item ++Use the double quote glyph @code{\(dq}. This works with and without ++compatibility mode enabled since @code{gtroff} doesn't convert ++@code{\(dq} back to a double quote input character. ++ ++Note that this method won't work with @acronym{UNIX} @code{troff} in ++general since the glyph `dq' isn't defined normally. ++@end itemize ++ ++@cindex @code{ds} request, and double quotes ++Double quotes in the @code{ds} request are handled differently. ++@xref{Strings}, for more details. ++ ++@c --------------------------------------------------------------------- ++ ++@node Macros, Escapes, Requests, Embedded Commands ++@subsection Macros ++@cindex macros ++ ++@code{gtroff} has a @dfn{macro} facility for defining a series of lines ++that can be invoked by name. They are called in the same manner as ++requests -- arguments also may be passed basically in the same manner. ++ ++@xref{Writing Macros}, and @ref{Request and Macro Arguments}. ++ ++@c --------------------------------------------------------------------- ++ ++@node Escapes, , Macros, Embedded Commands ++@subsection Escapes ++@cindex escapes ++ ++Escapes may occur anywhere in the input to @code{gtroff}. They usually ++begin with a backslash and are followed by a single character, which ++indicates the function to be performed. The escape character can be ++changed; see @ref{Character Translations}. ++ ++Escape sequences that require an identifier as a parameter accept three ++possible syntax forms. ++ ++@itemize @bullet ++@item ++The next single character is the identifier. ++ ++@cindex @code{(}, starting a two-character identifier ++@item ++If this single character is an opening parenthesis, take the following ++two characters as the identifier. Note that there is no closing ++parenthesis after the identifier. ++ ++@cindex @code{[}, starting an identifier ++@cindex @code{]}, ending an identifier ++@item ++If this single character is an opening bracket, take all characters ++until a closing bracket as the identifier. ++@end itemize ++ ++@noindent ++Examples: ++ ++@Example ++\fB ++\n(XX ++\*[TeX] ++@endExample ++ ++@cindex @code{'}, delimiting arguments ++@cindex argument delimiting characters ++@cindex characters, argument delimiting ++@cindex delimiting characters for arguments ++Other escapes may require several arguments and/or some special format. ++In such cases the argument is traditionally enclosed in single quotes ++(and quotes are always used in this manual for the definitions of escape ++sequences). The enclosed text is then processed according to what that ++escape expects. Example: ++ ++@Example ++\l'1.5i\(bu' ++@endExample ++ ++@cindex @code{\o}, possible quote characters ++@cindex @code{\b}, possible quote characters ++@cindex @code{\X}, possible quote characters ++Note that the quote character can be replaced with any other character ++that does not occur in the argument (even a newline or a space ++character) in the following escapes: @code{\o}, @code{\b}, and ++@code{\X}. This makes e.g. ++ ++@Example ++A caf ++\o ++e\' ++ ++ ++in Paris ++ @result{} A caf in Paris ++@endExample ++ ++@noindent ++possible, but it is better not to use this feature to avoid confusion. ++ ++@cindex @code{\%}, used as delimiter ++@cindex @code{\@key{SP}}, used as delimiter ++@cindex @code{\|}, used as delimiter ++@cindex @code{\^}, used as delimiter ++@cindex @code{\@{}, used as delimiter ++@cindex @code{\@}}, used as delimiter ++@cindex @code{\'}, used as delimiter ++@cindex @code{\`}, used as delimiter ++@cindex @code{\-}, used as delimiter ++@cindex @code{\_}, used as delimiter ++@cindex @code{\!}, used as delimiter ++@cindex @code{\?}, used as delimiter ++@cindex @code{\)}, used as delimiter ++@cindex @code{\/}, used as delimiter ++@cindex @code{\,}, used as delimiter ++@cindex @code{\&}, used as delimiter ++@ifnotinfo ++@cindex @code{\:}, used as delimiter ++@end ifnotinfo ++@ifinfo ++@cindex @code{\@r{}}, used as delimiter ++@end ifinfo ++@cindex @code{\~}, used as delimiter ++@cindex @code{\0}, used as delimiter ++@cindex @code{\a}, used as delimiter ++@cindex @code{\c}, used as delimiter ++@cindex @code{\d}, used as delimiter ++@cindex @code{\e}, used as delimiter ++@cindex @code{\E}, used as delimiter ++@cindex @code{\p}, used as delimiter ++@cindex @code{\r}, used as delimiter ++@cindex @code{\t}, used as delimiter ++@cindex @code{\u}, used as delimiter ++The following escapes sequences (which are handled similarly to ++characters since they don't take a parameter) are also allowed as ++delimiters: @code{\%}, @w{@samp{\ }}, @code{\|}, @code{\^}, @code{\@{}, ++@code{\@}}, @code{\'}, @code{\`}, @code{\-}, @code{\_}, @code{\!}, ++@code{\?}, @code{\)}, @code{\/}, @code{\,}, @code{\&}, @code{\:}, ++@code{\~}, @code{\0}, @code{\a}, @code{\c}, @code{\d}, @code{\e}, ++@code{\E}, @code{\p}, @code{\r}, @code{\t}, and @code{\u}. Again, don't ++use these if possible. ++ ++@cindex @code{\A}, allowed delimiters ++@cindex @code{\B}, allowed delimiters ++@cindex @code{\Z}, allowed delimiters ++@cindex @code{\C}, allowed delimiters ++@cindex @code{\w}, allowed delimiters ++No newline characters as delimiters are allowed in the following ++escapes: @code{\A}, @code{\B}, @code{\Z}, @code{\C}, and @code{\w}. ++ ++@cindex @code{\D}, allowed delimiters ++@cindex @code{\h}, allowed delimiters ++@cindex @code{\H}, allowed delimiters ++@cindex @code{\l}, allowed delimiters ++@cindex @code{\L}, allowed delimiters ++@cindex @code{\N}, allowed delimiters ++@cindex @code{\R}, allowed delimiters ++@cindex @code{\s}, allowed delimiters ++@cindex @code{\S}, allowed delimiters ++@cindex @code{\v}, allowed delimiters ++@cindex @code{\x}, allowed delimiters ++Finally, the escapes @code{\D}, @code{\h}, @code{\H}, @code{\l}, ++@code{\L}, @code{\N}, @code{\R}, @code{\s}, @code{\S}, @code{\v}, and ++@code{\x} can't use the following characters as delimiters: ++ ++@itemize @bullet ++@item ++@cindex numbers, and delimiters ++@cindex digits, and delimiters ++The digits @code{0}-@code{9}. ++ ++@item ++@cindex operators, as delimiters ++@cindex @code{+}, as delimiter ++@cindex @code{-}, as delimiter ++@cindex @code{/}, as delimiter ++@cindex @code{*}, as delimiter ++@cindex @code{%}, as delimiter ++@cindex @code{<}, as delimiter ++@cindex @code{>}, as delimiter ++@cindex @code{=}, as delimiter ++@cindex @code{&}, as delimiter ++@ifnotinfo ++@cindex @code{:}, as delimiter ++@end ifnotinfo ++@ifinfo ++@cindex , as delimiter ++@end ifinfo ++@cindex @code{(}, as delimiter ++@cindex @code{)}, as delimiter ++@cindex @code{.}, as delimiter ++The (single-character) operators @samp{+-/*%<>=&:().}. ++ ++@item ++@cindex space character ++@cindex character, space ++@cindex tab character ++@cindex character, tab ++@cindex newline character ++@cindex character, newline ++The space, tab, and newline characters. ++ ++@item ++@cindex @code{\%}, used as delimiter ++@ifnotinfo ++@cindex @code{\:}, used as delimiter ++@end ifnotinfo ++@ifinfo ++@cindex @code{\@r{}}, used as delimiter ++@end ifinfo ++@cindex @code{\@{}, used as delimiter ++@cindex @code{\@}}, used as delimiter ++@cindex @code{\'}, used as delimiter ++@cindex @code{\`}, used as delimiter ++@cindex @code{\-}, used as delimiter ++@cindex @code{\_}, used as delimiter ++@cindex @code{\!}, used as delimiter ++@cindex @code{\/}, used as delimiter ++@cindex @code{\c}, used as delimiter ++@cindex @code{\e}, used as delimiter ++@cindex @code{\p}, used as delimiter ++All escape sequences except @code{\%}, @code{\:}, @code{\@{}, ++@code{\@}}, @code{\'}, @code{\`}, @code{\-}, @code{\_}, @code{\!}, ++@code{\/}, @code{\c}, @code{\e}, and @code{\p}. ++@end itemize ++ ++@cindex printing backslash (@code{\\}, @code{\e}, @code{\E}, @code{\[rs]}) ++@cindex backslash, printing (@code{\\}, @code{\e}, @code{\E}, @code{\[rs]}) ++To have a backslash (actually, the current escape character) appear in ++the output several escapes are defined: @code{\\}, @code{\e} or ++@code{\E}. These are very similar, and only differ with respect to ++being used in macros or diversions. @xref{Character Translations}, for ++an exact description of those escapes. ++ ++@xref{Implementation Differences}, @ref{Copy-in Mode}, and ++@ref{Diversions}, @ref{Identifiers}, for more information. ++ ++@menu ++* Comments:: ++@end menu ++ ++@node Comments, , Escapes, Escapes ++@subsubsection Comments ++@cindex comments ++ ++Probably one of the most@footnote{Unfortunately, this is a lie. But ++hopefully future @code{gtroff} hackers will believe it @code{:-)}} ++common forms of escapes is the comment. ++ ++@Defesc {\\", , , } ++Start a comment. Everything to the end of the input line is ignored. ++ ++This may sound simple, but it can be tricky to keep the comments from ++interfering with the appearance of the final output. ++ ++@cindex @code{ds}, @code{ds1} requests, and comments ++@cindex @code{as}, @code{as1} requests, and comments ++If the escape is to the right of some text or a request, that portion of ++the line is ignored, but the space leading up to it is noticed by ++@code{gtroff}. This only affects the @code{ds} and @code{as} request ++and its variants. ++ ++@cindex tabs, before comments ++@cindex comments, lining up with tabs ++One possibly irritating idiosyncracy is that tabs must not be used to ++line up comments. Tabs are not treated as whitespace between the ++request and macro arguments. ++ ++@cindex undefined request ++@cindex request, undefined ++A comment on a line by itself is treated as a blank line, because after ++eliminating the comment, that is all that remains: ++ ++@Example ++Test ++\" comment ++Test ++@endExample ++ ++@noindent ++produces ++ ++@Example ++Test ++ ++Test ++@endExample ++ ++To avoid this, it is common to start the line with @code{.\"}, which ++causes the line to be treated as an undefined request and thus ignored ++completely. ++ ++@cindex @code{'}, as a comment ++Another commenting scheme seen sometimes is three consecutive single ++quotes (@code{'''}) at the beginning of a line. This works, but ++@code{gtroff} gives a warning about an undefined macro (namely ++@code{''}), which is harmless, but irritating. ++@endDefesc ++ ++@Defesc {\\#, , , } ++To avoid all this, @code{gtroff} has a new comment mechanism using the ++@code{\#} escape. This escape works the same as @code{\"} except that ++the newline is also ignored: ++ ++@Example ++Test ++\# comment ++Test ++@endExample ++ ++@noindent ++produces ++ ++@Example ++Test Test ++@endExample ++ ++@noindent ++as expected. ++@endDefesc ++ ++@Defreq {ig, [@Var{end}]} ++Ignore all input until @code{gtroff} encounters the macro named ++@code{.}@var{end} on a line by itself (or @code{..} if @var{end} is not ++specified). This is useful for commenting out large blocks of text: ++ ++@Example ++text text text... ++.ig ++This is part of a large block ++of text that has been ++temporarily(?) commented out. ++ ++We can restore it simply by removing ++the .ig request and the ".." at the ++end of the block. ++.. ++More text text text... ++@endExample ++ ++@noindent ++produces ++ ++@Example ++text text text@dots{} More text text text@dots{} ++@endExample ++ ++@noindent ++Note that the commented-out block of text does not cause a break. ++ ++@cindex @code{ig} request, and copy-in mode ++@cindex copy-in mode, and @code{ig} request ++@cindex mode, copy-in, and @code{ig} request ++@cindex @code{ig} request, and auto-increment ++@cindex auto-increment, and @code{ig} request ++The input is read in copy-mode; auto-incremented registers @emph{are} ++affected (@pxref{Auto-increment}). ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Registers, Manipulating Filling and Adjusting, Embedded Commands, gtroff Reference ++@section Registers ++@cindex registers ++ ++Numeric variables in @code{gtroff} are called @dfn{registers}. There ++are a number of built-in registers, supplying anything from the date to ++details of formatting parameters. ++ ++@xref{Identifiers}, for details on register identifiers. ++ ++@menu ++* Setting Registers:: ++* Interpolating Registers:: ++* Auto-increment:: ++* Assigning Formats:: ++* Built-in Registers:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Setting Registers, Interpolating Registers, Registers, Registers ++@subsection Setting Registers ++@cindex setting registers (@code{nr}, @code{\R}) ++@cindex registers, setting (@code{nr}, @code{\R}) ++ ++Define or set registers using the @code{nr} request or the @code{\R} ++escape. ++ ++Although the following requests and escapes can be used to create ++registers, simply using an undefined register will cause it to be ++set to zero. ++ ++@DefreqList {nr, ident value} ++@DefescListEndx {\\R, ', ident value, '} ++Set number register @var{ident} to @var{value}. If @var{ident} doesn't ++exist, @code{gtroff} creates it. ++ ++The argument to @code{\R} usually has to be enclosed in quotes. ++@xref{Escapes}, for details on parameter delimiting characters. ++ ++The @code{\R} escape doesn't produce an input token in @code{gtroff}; ++in other words, it vanishes completely after @code{gtroff} has ++processed it. ++ ++For example, the following two lines are equivalent: ++ ++@Example ++.nr a (((17 + (3 * 4))) % 4) ++\R'a (((17 + (3 * 4))) % 4)' ++ @result{} 1 ++@endExample ++ ++Note that the complete transparency of @code{\R} can cause surprising ++effects if you use number registers like @code{.k}, which get evaluated ++at the time they are accessed. ++ ++@Example ++.ll 1.6i ++. ++aaa bbb ccc ddd eee fff ggg hhh\R':k \n[.k]' ++.tm :k == \n[:k] ++ @result{} :k == 126950 ++. ++.br ++. ++aaa bbb ccc ddd eee fff ggg hhh\h'0'\R':k \n[.k]' ++.tm :k == \n[:k] ++ @result{} :k == 15000 ++@endExample ++ ++If you process this with the @sc{PostScript} device (@code{-Tps}), ++there will be a line break eventually after @code{ggg} in both input ++lines. However, after processing the space after @code{ggg}, the ++partially collected line is not overfull yet, so @code{troff} ++continues to collect input until it sees the space (or in this case, ++the newline) after @code{hhh}. At this point, the line is longer ++than the line length, and the line gets broken. ++ ++In the first input line, since the @code{\R} escape leaves no traces, ++the check for the overfull line hasn't been done yet at the point where ++@code{\R} gets handled, and you get a value for the @code{.k} number ++register that is even greater than the current line length. ++ ++In the second input line, the insertion of @code{\h'0'} to emit an ++invisible zero-width space forces @code{troff} to check the line length, ++which in turn causes the start of a new output line. Now @code{.k} ++returns the expected value. ++@endDefreq ++ ++Both @code{nr} and @code{\R} have two additional special forms to ++increment or decrement a register. ++ ++@DefreqList {nr, ident @t{+}@Var{value}} ++@DefreqItem {nr, ident @t{-}@Var{value}} ++@DefescItemx {\\R, ', ident @t{+}value, '} ++@DefescListEnd {\\R, ', ident @t{-}value, '} ++Increment (decrement) register @var{ident} by @var{value}. ++ ++@Example ++.nr a 1 ++.nr a +1 ++\na ++ @result{} 2 ++@endExample ++ ++@cindex negating register values ++To assign the negated value of a register to another register, some care ++must be taken to get the desired result: ++ ++@Example ++.nr a 7 ++.nr b 3 ++.nr a -\nb ++\na ++ @result{} 4 ++.nr a (-\nb) ++\na ++ @result{} -3 ++@endExample ++ ++@noindent ++The surrounding parentheses prevent the interpretation of the minus sign ++as a decrementing operator. An alternative is to start the assignment ++with a @samp{0}: ++ ++@Example ++.nr a 7 ++.nr b -3 ++.nr a \nb ++\na ++ @result{} 4 ++.nr a 0\nb ++\na ++ @result{} -3 ++@endExample ++@endDefreq ++ ++@Defreq {rr, ident} ++@cindex removing number register (@code{rr}) ++@cindex number register, removing (@code{rr}) ++@cindex register, removing (@code{rr}) ++Remove number register @var{ident}. If @var{ident} doesn't exist, the ++request is ignored. ++@endDefreq ++ ++@Defreq {rnn, ident1 ident2} ++@cindex renaming number register (@code{rnn}) ++@cindex number register, renaming (@code{rnn}) ++@cindex register, renaming (@code{rnn}) ++Rename number register @var{ident1} to @var{ident2}. If either ++@var{ident1} or @var{ident2} doesn't exist, the request is ignored. ++@endDefreq ++ ++@Defreq {aln, ident1 ident2} ++@cindex alias, number register, creating (@code{aln}) ++@cindex creating alias, for number register (@code{aln}) ++@cindex number register, creating alias (@code{aln}) ++@cindex register, creating alias (@code{aln}) ++Create an alias @var{ident1} for a number register @var{ident2}. The ++new name and the old name are exactly equivalent. If @var{ident1} is ++undefined, a warning of type @samp{reg} is generated, and the request is ++ignored. @xref{Debugging}, for information about warnings. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Interpolating Registers, Auto-increment, Setting Registers, Registers ++@subsection Interpolating Registers ++@cindex interpolating registers (@code{\n}) ++@cindex registers, interpolating (@code{\n}) ++ ++Numeric registers can be accessed via the @code{\n} escape. ++ ++@DefescList {\\n, , i, } ++@DefescItem {\\n, @Lparen{}, id, } ++@DefescListEnd {\\n, @Lbrack{}, ident, @Rbrack{}} ++@cindex nested assignments ++@cindex assignments, nested ++@cindex indirect assignments ++@cindex assignments, indirect ++Interpolate number register with name @var{ident} (one-character ++name@tie{}@var{i}, two-character name @var{id}). This means that the ++value of the register is expanded in-place while @code{gtroff} is ++parsing the input line. Nested assignments (also called indirect ++assignments) are possible. ++ ++@Example ++.nr a 5 ++.nr as \na+\na ++\n(as ++ @result{} 10 ++@endExample ++ ++@Example ++.nr a1 5 ++.nr ab 6 ++.ds str b ++.ds num 1 ++\n[a\n[num]] ++ @result{} 5 ++\n[a\*[str]] ++ @result{} 6 ++@endExample ++@endDefesc ++ ++@c --------------------------------------------------------------------- ++ ++@node Auto-increment, Assigning Formats, Interpolating Registers, Registers ++@subsection Auto-increment ++@cindex auto-increment ++@cindex increment, automatic ++ ++Number registers can also be auto-incremented and auto-decremented. The ++increment or decrement value can be specified with a third argument to ++the @code{nr} request or @code{\R} escape. ++ ++@Defreq {nr, ident value incr} ++@cindex @code{\R}, difference to @code{nr} ++Set number register @var{ident} to @var{value}; the increment for ++auto-incrementing is set to @var{incr}. Note that the @code{\R} escape ++doesn't support this notation. ++@endDefreq ++ ++To activate auto-incrementing, the escape @code{\n} has a special syntax ++form. ++ ++@DefescList {\\n, +, i, } ++@DefescItem {\\n, -, i, } ++@DefescItem {\\n, @Lparen{}+, id, } ++@DefescItem {\\n, @Lparen{}-, id, } ++@DefescItem {\\n, +@Lparen{}, id, } ++@DefescItem {\\n, -@Lparen{}, id, } ++@DefescItem {\\n, @Lbrack{}+, ident, @Rbrack{}} ++@DefescItem {\\n, @Lbrack{}-, ident, @Rbrack{}} ++@DefescItem {\\n, +@Lbrack{}, ident, @Rbrack{}} ++@DefescListEnd {\\n, -@Lbrack{}, ident, @Rbrack{}} ++Before interpolating, increment or decrement @var{ident} (one-character ++name@tie{}@var{i}, two-character name @var{id}) by the auto-increment ++value as specified with the @code{nr} request (or the @code{\R} escape). ++If no auto-increment value has been specified, these syntax forms are ++identical to @code{\n}. ++@endDefesc ++ ++For example, ++ ++@Example ++.nr a 0 1 ++.nr xx 0 5 ++.nr foo 0 -2 ++\n+a, \n+a, \n+a, \n+a, \n+a ++.br ++\n-(xx, \n-(xx, \n-(xx, \n-(xx, \n-(xx ++.br ++\n+[foo], \n+[foo], \n+[foo], \n+[foo], \n+[foo] ++@endExample ++ ++@noindent ++produces ++ ++@Example ++1, 2, 3, 4, 5 ++-5, -10, -15, -20, -25 ++-2, -4, -6, -8, -10 ++@endExample ++ ++@cindex increment value without changing the register ++@cindex value, incrementing without changing the register ++To change the increment value without changing the value of a register ++(@var{a} in the example), the following can be used: ++ ++@Example ++.nr a \na 10 ++@endExample ++ ++@c --------------------------------------------------------------------- ++ ++@node Assigning Formats, Built-in Registers, Auto-increment, Registers ++@subsection Assigning Formats ++@cindex assigning formats (@code{af}) ++@cindex formats, assigning (@code{af}) ++ ++When a register is used, it is always textually replaced (or ++interpolated) with a representation of that number. This output format ++can be changed to a variety of formats (numbers, Roman numerals, etc.). ++This is done using the @code{af} request. ++ ++@Defreq {af, ident format} ++Change the output format of a number register. The first argument ++@var{ident} is the name of the number register to be changed, and the ++second argument @var{format} is the output format. The following output ++formats are available: ++ ++@table @code ++@item 1 ++Decimal arabic numbers. This is the default format: 0, 1, 2, ++3,@tie{}@enddots{} ++ ++@item 0@dots{}0 ++Decimal numbers with as many digits as specified. So, @samp{00} would ++result in printing numbers as 01, 02, 03,@tie{}@enddots{} ++ ++In fact, any digit instead of zero does work; @code{gtroff} only counts ++how many digits are specified. As a consequence, @code{af}'s default ++format @samp{1} could be specified as @samp{0} also (and exactly this is ++returned by the @code{\g} escape, see below). ++ ++@item I ++@cindex Roman numerals ++@cindex numerals, Roman ++Upper-case Roman numerals: 0, I, II, III, IV,@tie{}@enddots{} ++ ++@item i ++Lower-case Roman numerals: 0, i, ii, iii, iv,@tie{}@enddots{} ++ ++@item A ++Upper-case letters: 0, A, B, C, @dots{},@tie{}Z, AA, AB,@tie{}@enddots{} ++ ++@item a ++Lower-case letters: 0, a, b, c, @dots{},@tie{}z, aa, ab,@tie{}@enddots{} ++@end table ++ ++Omitting the number register format causes a warning of type ++@samp{missing}. @xref{Debugging}, for more details. Specifying a ++nonexistent format causes an error. ++ ++The following example produces @samp{10, X, j, 010}: ++ ++@Example ++.nr a 10 ++.af a 1 \" the default format ++\na, ++.af a I ++\na, ++.af a a ++\na, ++.af a 001 ++\na ++@endExample ++ ++@cindex Roman numerals, maximum and minimum ++@cindex maximum values of Roman numerals ++@cindex minimum values of Roman numerals ++The largest number representable for the @samp{i} and @samp{I} formats ++is 39999 (or @minus{}39999); @acronym{UNIX} @code{troff} uses @samp{z} ++and @samp{w} to represent 10000 and 5000 in Roman numerals, and so does ++@code{gtroff}. Currently, the correct glyphs of Roman numeral five ++thousand and Roman numeral ten thousand (Unicode code points ++@code{U+2182} and @code{U+2181}, respectively) are not available. ++ ++If @var{ident} doesn't exist, it is created. ++ ++@cindex read-only register, changing format ++@cindex changing format, and read-only registers ++Changing the output format of a read-only register causes an error. It ++is necessary to first copy the register's value to a writeable register, ++then apply the @code{af} request to this other register. ++@endDefreq ++ ++@DefescList {\\g, , i, } ++@DefescItem {\\g, @Lparen{}, id, } ++@DefescListEnd {\\g, @Lbrack{}, ident, @Rbrack{}} ++@cindex format of register (@code{\g}) ++@cindex register, format (@code{\g}) ++Return the current format of the specified register @var{ident} ++(one-character name@tie{}@var{i}, two-character name @var{id}). For ++example, @samp{\ga} after the previous example would produce the string ++@samp{000}. If the register hasn't been defined yet, nothing is ++returned. ++@endDefesc ++ ++@c --------------------------------------------------------------------- ++ ++@node Built-in Registers, , Assigning Formats, Registers ++@subsection Built-in Registers ++@cindex built-in registers ++@cindex registers, built-in ++ ++The following lists some built-in registers that are not described ++elsewhere in this manual. Any register that begins with a @samp{.} is ++read-only. A complete listing of all built-in registers can be found in ++@ref{Register Index}. ++ ++@table @code ++@item \n[.F] ++@cindex current input file name register (@code{.F}) ++@cindex input file name, current, register (@code{.F}) ++@vindex .F ++This string-valued register returns the current input file name. ++ ++@item \n[.H] ++@cindex horizontal resolution register (@code{.H}) ++@cindex resolution, horizontal, register (@code{.H}) ++@vindex .H ++Horizontal resolution in basic units. ++ ++@item \n[.R] ++@cindex number of registers register (@code{.R}) ++@cindex registers, number of, register (@code{.R}) ++@vindex .R ++The number of number registers available. This is always 10000 in ++GNU@tie{}@code{troff}; it exists for backward compatibility. ++ ++@item \n[.U] ++@cindex safer mode ++@cindex mode, safer ++@cindex unsafe mode ++@cindex mode, unsafe ++@vindex .U ++If @code{gtroff} is called with the @option{-U} command line option to ++activate unsafe mode, the number register @code{.U} is set to@tie{}1, ++and to zero otherwise. @xref{Groff Options}. ++ ++@item \n[.V] ++@cindex vertical resolution register (@code{.V}) ++@cindex resolution, vertical, register (@code{.V}) ++@vindex .V ++Vertical resolution in basic units. ++ ++@item \n[seconds] ++@cindex seconds, current time (@code{seconds}) ++@cindex time, current, seconds (@code{seconds}) ++@cindex current time, seconds (@code{seconds}) ++@vindex seconds ++The number of seconds after the minute, normally in the range@tie{}0 ++to@tie{}59, but can be up to@tie{}61 to allow for leap seconds. ++Initialized at start-up of @code{gtroff}. ++ ++@item \n[minutes] ++@cindex minutes, current time (@code{minutes}) ++@cindex time, current, minutes (@code{minutes}) ++@cindex current time, minutes (@code{minutes}) ++@vindex minutes ++The number of minutes after the hour, in the range@tie{}0 to@tie{}59. ++Initialized at start-up of @code{gtroff}. ++ ++@item \n[hours] ++@cindex hours, current time (@code{hours}) ++@cindex time, current, hours (@code{hours}) ++@cindex current time, hours (@code{hours}) ++@vindex hours ++The number of hours past midnight, in the range@tie{}0 to@tie{}23. ++Initialized at start-up of @code{gtroff}. ++ ++@item \n[dw] ++@cindex day of the week register (@code{dw}) ++@cindex date, day of the week register (@code{dw}) ++@vindex dw ++Day of the week (1-7). ++ ++@item \n[dy] ++@cindex day of the month register (@code{dy}) ++@cindex date, day of the month register (@code{dy}) ++@vindex dy ++Day of the month (1-31). ++ ++@item \n[mo] ++@cindex month of the year register (@code{mo}) ++@cindex date, month of the year register (@code{mo}) ++@vindex mo ++Current month (1-12). ++ ++@item \n[year] ++@cindex date, year register (@code{year}, @code{yr}) ++@cindex year, current, register (@code{year}, @code{yr}) ++@vindex year ++The current year. ++ ++@item \n[yr] ++@vindex yr ++The current year minus@tie{}1900. Unfortunately, the documentation of ++@acronym{UNIX} Version@tie{}7's @code{troff} had a year@tie{}2000 bug: ++It incorrectly claimed that @code{yr} contains the last two digits of ++the year. That claim has never been true of either @acronym{AT&T} ++@code{troff} or GNU @code{troff}. Old @code{troff} input that looks ++like this: ++ ++@Example ++'\" The following line stopped working after 1999 ++This document was formatted in 19\n(yr. ++@endExample ++ ++@noindent ++can be corrected as follows: ++ ++@Example ++This document was formatted in \n[year]. ++@endExample ++ ++@noindent ++or, to be portable to older @code{troff} versions, as follows: ++ ++@Example ++.nr y4 1900+\n(yr ++This document was formatted in \n(y4. ++@endExample ++ ++@item \n[.c] ++@vindex .c ++@itemx \n[c.] ++@vindex c. ++@cindex input line number register (@code{.c}, @code{c.}) ++@cindex line number, input, register (@code{.c}, @code{c.}) ++The current @emph{input} line number. Register @samp{.c} is read-only, ++whereas @samp{c.} (a @code{gtroff} extension) is writable also, ++affecting both @samp{.c} and @samp{c.}. ++ ++@item \n[ln] ++@vindex ln ++@cindex output line number register (@code{ln}) ++@cindex line number, output, register (@code{ln}) ++The current @emph{output} line number after a call to the @code{nm} ++request to activate line numbering. ++ ++@xref{Miscellaneous}, for more information about line numbering. ++ ++@item \n[.x] ++@vindex .x ++@cindex major version number register (@code{.x}) ++@cindex version number, major, register (@code{.x}) ++The major version number. For example, if the version number is 1.03 ++then @code{.x} contains@tie{}@samp{1}. ++ ++@item \n[.y] ++@vindex .y ++@cindex minor version number register (@code{.y}) ++@cindex version number, minor, register (@code{.y}) ++The minor version number. For example, if the version number is 1.03 ++then @code{.y} contains@tie{}@samp{03}. ++ ++@item \n[.Y] ++@vindex .Y ++@cindex revision number register (@code{.Y}) ++The revision number of @code{groff}. ++ ++@item \n[$$] ++@vindex $$ ++@cindex process ID of @code{gtroff} register (@code{$$}) ++@cindex @code{gtroff}, process ID register (@code{$$}) ++The process ID of @code{gtroff}. ++ ++@item \n[.g] ++@vindex .g ++@cindex @code{gtroff}, identification register (@code{.g}) ++@cindex GNU-specific register (@code{.g}) ++Always@tie{}1. Macros should use this to determine whether they are ++running under GNU @code{troff}. ++ ++@item \n[.A] ++@vindex .A ++@cindex @acronym{ASCII} approximation output register (@code{.A}) ++If the command line option @option{-a} is used to produce an ++@acronym{ASCII} approximation of the output, this is set to@tie{}1, zero ++otherwise. @xref{Groff Options}. ++ ++@item \n[.O] ++@vindex .O ++This read-only register is set to the suppression nesting level (see ++escapes @code{\O}). @xref{Suppressing output}. ++ ++@item \n[.P] ++@vindex .P ++This register is set to@tie{}1 (and to@tie{}0 otherwise) if the current ++page is actually being printed, i.e., if the @option{-o} option is being ++used to only print selected pages. @xref{Groff Options}, for more ++information. ++ ++@item \n[.T] ++@vindex .T ++If @code{gtroff} is called with the @option{-T} command line option, the ++number register @code{.T} is set to@tie{}1, and zero otherwise. ++@xref{Groff Options}. ++ ++@item \*[.T] ++@stindex .T ++@cindex output device name string register (@code{.T}) ++A single read-write string register that contains the current output ++device (for example, @samp{latin1} or @samp{ps}). This is the only ++string register defined by @code{gtroff}. ++@end table ++ ++ ++@c ===================================================================== ++ ++@node Manipulating Filling and Adjusting, Manipulating Hyphenation, Registers, gtroff Reference ++@section Manipulating Filling and Adjusting ++@cindex manipulating filling and adjusting ++@cindex filling and adjusting, manipulating ++@cindex adjusting and filling, manipulating ++@cindex justifying text ++@cindex text, justifying ++ ++@cindex break ++@cindex line break ++@cindex @code{bp} request, causing implicit linebreak ++@cindex @code{ce} request, causing implicit linebreak ++@cindex @code{cf} request, causing implicit linebreak ++@cindex @code{fi} request, causing implicit linebreak ++@cindex @code{fl} request, causing implicit linebreak ++@cindex @code{in} request, causing implicit linebreak ++@cindex @code{nf} request, causing implicit linebreak ++@cindex @code{rj} request, causing implicit linebreak ++@cindex @code{sp} request, causing implicit linebreak ++@cindex @code{ti} request, causing implicit linebreak ++@cindex @code{trf} request, causing implicit linebreak ++Various ways of causing @dfn{breaks} were given in @ref{Implicit Line ++Breaks}. The @code{br} request likewise causes a break. Several other ++requests also cause breaks, but implicitly. These are @code{bp}, ++@code{ce}, @code{cf}, @code{fi}, @code{fl}, @code{in}, @code{nf}, ++@code{rj}, @code{sp}, @code{ti}, and @code{trf}. ++ ++@Defreq {br, } ++Break the current line, i.e., the input collected so far is emitted ++without adjustment. ++ ++If the no-break control character is used, @code{gtroff} suppresses the ++break: ++ ++@Example ++a ++'br ++b ++ @result{} a b ++@endExample ++@endDefreq ++ ++Initially, @code{gtroff} fills and adjusts text to both margins. ++Filling can be disabled via the @code{nf} request and re-enabled with ++the @code{fi} request. ++ ++@DefreqList {fi, } ++@DefregListEndx {.u} ++@cindex fill mode (@code{fi}) ++@cindex mode, fill (@code{fi}) ++Activate fill mode (which is the default). This request implicitly ++enables adjusting; it also inserts a break in the text currently being ++filled. The read-only number register @code{.u} is set to@tie{}1. ++ ++The fill mode status is associated with the current environment ++(@pxref{Environments}). ++ ++See @ref{Line Control}, for interaction with the @code{\c} escape. ++@endDefreq ++ ++@Defreq {nf, } ++@cindex no-fill mode (@code{nf}) ++@cindex mode, no-fill (@code{nf}) ++Activate no-fill mode. Input lines are output as-is, retaining line ++breaks and ignoring the current line length. This command implicitly ++disables adjusting; it also causes a break. The number register ++@code{.u} is set to@tie{}0. ++ ++The fill mode status is associated with the current environment ++(@pxref{Environments}). ++ ++See @ref{Line Control}, for interaction with the @code{\c} escape. ++@endDefreq ++ ++@DefreqList {ad, [@Var{mode}]} ++@DefregListEndx {.j} ++Set adjusting mode. ++ ++Activation and deactivation of adjusting is done implicitly with calls ++to the @code{fi} or @code{nf} requests. ++ ++@var{mode} can have one of the following values: ++ ++@table @code ++@item l ++@cindex ragged-right ++Adjust text to the left margin. This produces what is traditionally ++called ragged-right text. ++ ++@item r ++@cindex ragged-left ++Adjust text to the right margin, producing ragged-left text. ++ ++@item c ++@cindex centered text ++@cindex @code{ce} request, difference to @samp{.ad@tie{}c} ++Center filled text. This is different to the @code{ce} request, which ++only centers text without filling. ++ ++@item b ++@itemx n ++Justify to both margins. This is the default used by @code{gtroff}. ++@end table ++ ++Finally, @var{mode} can be the numeric argument returned by the ++@code{.j} register. ++ ++Using @code{ad} without argument is the same as saying ++@w{@code{.ad \[.j]}}. In particular, @code{gtroff} adjusts lines ++in the same way it did before adjusting was deactivated (with a call ++to @code{na}, say). For example, this input code ++ ++@Example ++.de AD ++. br ++. ad \\$1 ++.. ++. ++.de NA ++. br ++. na ++.. ++. ++textA ++.AD r ++.nr ad \n[.j] ++textB ++.AD c ++textC ++.NA ++textD ++.AD \" back to centering ++textE ++.AD \n[ad] \" back to right justifying ++textF ++@endExample ++ ++@noindent ++produces the following output: ++ ++@Example ++textA ++ textB ++ textC ++textD ++ textE ++ textF ++@endExample ++ ++@cindex adjustment mode register (@code{.j}) ++As just demonstrated, the current adjustment mode is available in the ++read-only number register @code{.j}; it can be stored and ++subsequently used to set adjustment. ++ ++The adjustment mode status is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@Defreq {na, } ++Disable adjusting. This request won't change the current adjustment ++mode: A subsequent call to @code{ad} uses the previous adjustment ++setting. ++ ++The adjustment mode status is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@DefreqList {brp, } ++@DefescListEndx {\\p, , , } ++Adjust the current line and cause a break. ++ ++In most cases this produces very ugly results since @code{gtroff} ++doesn't have a sophisticated paragraph building algorithm (as @TeX{} ++have, for example); instead, @code{gtroff} fills and adjusts a paragraph ++line by line: ++ ++@Example ++This is an uninteresting sentence. ++This is an uninteresting sentence.\p ++This is an uninteresting sentence. ++@endExample ++ ++@noindent ++is formatted as ++ ++@Example ++This is an uninteresting sentence. This is an ++uninteresting sentence. ++This is an uninteresting sentence. ++@endExample ++@endDefreq ++ ++@DefreqList {ss, word_space_size [@Var{sentence_space_size}]} ++@DefregItemx {.ss} ++@DefregListEndx {.sss} ++@cindex word space size register (@code{.ss}) ++@cindex size of word space register (@code{.ss}) ++@cindex space between words register (@code{.ss}) ++@cindex sentence space size register (@code{.sss}) ++@cindex size of sentence space register (@code{.sss}) ++@cindex space between sentences register (@code{.sss}) ++Change the size of a space between words. It takes its units as one ++twelfth of the space width parameter for the current font. Initially ++both the @var{word_space_size} and @var{sentence_space_size} ++are@tie{}12. In fill mode, the values specify the minimum distance. ++ ++@cindex fill mode ++@cindex mode, fill ++If two arguments are given to the @code{ss} request, the second argument ++sets the sentence space size. If the second argument is not given, ++sentence space size is set to @var{word_space_size}. The sentence space ++size is used in two circumstances: If the end of a sentence occurs at ++the end of a line in fill mode, then both an inter-word space and a ++sentence space are added; if two spaces follow the end of a sentence in ++the middle of a line, then the second space is a sentence space. If a ++second argument is never given to the @code{ss} request, the behaviour ++of @acronym{UNIX} @code{troff} is the same as that exhibited by GNU ++@code{troff}. In GNU @code{troff}, as in @acronym{UNIX} @code{troff}, a ++sentence should always be followed by either a newline or two spaces. ++ ++The read-only number registers @code{.ss} and @code{.sss} hold the ++values of the parameters set by the first and second arguments of the ++@code{ss} request. ++ ++The word space and sentence space values are associated with the current ++environment (@pxref{Environments}). ++ ++Contrary to @acronym{AT&T} @code{troff}, this request is @emph{not} ++ignored if a TTY output device is used; the given values are then ++rounded down to a multiple of@tie{}12 (@pxref{Implementation ++Differences}). ++ ++The request is ignored if there is no parameter. ++ ++@cindex discardable horizontal space ++@cindex space, discardable, horizontal ++@cindex horizontal discardable space ++Another useful application of the @code{ss} request is to insert ++discardable horizontal space, i.e., space that is discarded at a line ++break. For example, paragraph-style footnotes could be separated this ++way: ++ ++@Example ++.ll 4.5i ++1.\ This is the first footnote.\c ++.ss 48 ++.nop ++.ss 12 ++2.\ This is the second footnote. ++@endExample ++ ++@noindent ++The result: ++ ++@Example ++1. This is the first footnote. 2. This ++is the second footnote. ++@endExample ++ ++@noindent ++Note that the @code{\h} escape produces unbreakable space. ++@endDefreq ++ ++@DefreqList {ce, [@Var{nnn}]} ++@DefregListEndx {.ce} ++@cindex centering lines (@code{ce}) ++@cindex lines, centering (@code{ce}) ++Center text. While the @w{@samp{.ad c}} request also centers text, it ++fills the text as well. @code{ce} does not fill the text it affects. ++This request causes a break. The number of lines still to be centered ++is associated with the current environment (@pxref{Environments}). ++ ++The following example demonstrates the differences. Here is the input: ++ ++@Example ++.ll 4i ++.ce 1000 ++This is a small text fragment that shows the differences ++between the `.ce' and the `.ad c' request. ++.ce 0 ++ ++.ad c ++This is a small text fragment that shows the differences ++between the `.ce' and the `.ad c' request. ++@endExample ++ ++@noindent ++And here the result: ++ ++@Example ++ This is a small text fragment that ++ shows the differences ++between the `.ce' and the `.ad c' request. ++ ++ This is a small text fragment that ++shows the differences between the `.ce' ++ and the `.ad c' request. ++@endExample ++ ++With no arguments, @code{ce} centers the next line of text. @var{nnn} ++specifies the number of lines to be centered. If the argument is zero ++or negative, centering is disabled. ++ ++The basic length for centering text is the line length (as set with the ++@code{ll} request) minus the indentation (as set with the @code{in} ++request). Temporary indentation is ignored. ++ ++As can be seen in the previous example, it is a common idiom to turn on ++centering for a large number of lines, and to turn off centering after ++text to be centered. This is useful for any request that takes a ++number of lines as an argument. ++ ++The @code{.ce} read-only number register contains the number of lines ++remaining to be centered, as set by the @code{ce} request. ++@endDefreq ++ ++@DefreqList {rj, [@Var{nnn}]} ++@DefregListEndx {.rj} ++@cindex justifying text (@code{rj}) ++@cindex text, justifying (@code{rj}) ++@cindex right-justifying (@code{rj}) ++Justify unfilled text to the right margin. Arguments are identical to ++the @code{ce} request. The @code{.rj} read-only number register is the ++number of lines to be right-justified as set by the @code{rj} request. ++This request causes a break. The number of lines still to be ++right-justified is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Manipulating Hyphenation, Manipulating Spacing, Manipulating Filling and Adjusting, gtroff Reference ++@section Manipulating Hyphenation ++@cindex manipulating hyphenation ++@cindex hyphenation, manipulating ++ ++Here a description of requests that influence hyphenation. ++ ++@DefreqList {hy, [@Var{mode}]} ++@DefregListEndx {.hy} ++Enable hyphenation. The request has an optional numeric argument, ++@var{mode}, to restrict hyphenation if necessary: ++ ++@table @code ++@item 1 ++The default argument if @var{mode} is omitted. Hyphenate without ++restrictions. This is also the start-up value of @code{gtroff}. ++ ++@item 2 ++Do not hyphenate the last word on a page or column. ++ ++@item 4 ++Do not hyphenate the last two characters of a word. ++ ++@item 8 ++Do not hyphenate the first two characters of a word. ++@end table ++ ++Values in the previous table are additive. For example, the ++value@tie{}12 causes @code{gtroff} to neither hyphenate the last two nor ++the first two characters of a word. ++ ++@cindex hyphenation restrictions register (@code{.hy}) ++The current hyphenation restrictions can be found in the read-only ++number register @samp{.hy}. ++ ++The hyphenation mode is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@Defreq {nh, } ++Disable hyphenation (i.e., set the hyphenation mode to zero). Note that ++the hyphenation mode of the last call to @code{hy} is not remembered. ++ ++The hyphenation mode is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@DefreqList {hlm, [@Var{nnn}]} ++@DefregItemx {.hlm} ++@DefregListEndx {.hlc} ++@cindex explicit hyphen (@code{\%}) ++@cindex hyphen, explicit (@code{\%}) ++@cindex consecutive hyphenated lines (@code{hlm}) ++@cindex lines, consecutive hyphenated (@code{hlm}) ++@cindex hyphenated lines, consecutive (@code{hlm}) ++Set the maximum number of consecutive hyphenated lines to @var{nnn}. If ++this number is negative, there is no maximum. The default value ++is@tie{}@minus{}1 if @var{nnn} is omitted. This value is associated ++with the current environment (@pxref{Environments}). Only lines output ++from a given environment count towards the maximum associated with that ++environment. Hyphens resulting from @code{\%} are counted; explicit ++hyphens are not. ++ ++The current setting of @code{hlm} is available in the @code{.hlm} ++read-only number register. Also the number of immediately preceding ++consecutive hyphenated lines are available in the read-only number ++register @samp{.hlc}. ++@endDefreq ++ ++@Defreq {hw, word1 word2 @dots{}} ++Define how @var{word1}, @var{word2}, etc.@: are to be hyphenated. The ++words must be given with hyphens at the hyphenation points. For ++example: ++ ++@Example ++.hw in-sa-lub-rious ++@endExample ++ ++@noindent ++Besides the space character, any character whose hyphenation code value ++is zero can be used to separate the arguments of @code{hw} (see the ++documentation for the @code{hcode} request below for more information). ++In addition, this request can be used more than once. ++ ++Hyphenation exceptions specified with the @code{hw} request are ++associated with the current hyphenation language; it causes an error if ++there is no current hyphenation language. ++ ++This request is ignored if there is no parameter. ++ ++In old versions of @code{troff} there was a limited amount of space to ++store such information; fortunately, with @code{gtroff}, this is no ++longer a restriction. ++@endDefreq ++ ++@DefescList {\\%, , , } ++@deffnx Escape @t{\:} ++@ifnotinfo ++@esindex \: ++@end ifnotinfo ++@ifinfo ++@esindex \@r{} ++@end ifinfo ++@cindex hyphenation character (@code{\%}) ++@cindex character, hyphenation (@code{\%}) ++@cindex disabling hyphenation (@code{\%}) ++@cindex hyphenation, disabling (@code{\%}) ++To tell @code{gtroff} how to hyphenate words on the fly, use the ++@code{\%} escape, also known as the @dfn{hyphenation character}. ++Preceding a word with this character prevents it from being ++hyphenated; putting it inside a word indicates to @code{gtroff} that ++the word may be hyphenated at that point. Note that this mechanism ++only affects that one occurrence of the word; to change the ++hyphenation of a word for the entire document, use the @code{hw} ++request. ++ ++The @code{\:} escape inserts a zero-width break point (that is, the word ++breaks but without adding a hyphen). ++ ++@Example ++... check the /var/log/\:httpd/\:access_log file ... ++@endExample ++ ++@cindex @code{\X}, followed by @code{\%} ++@cindex @code{\Y}, followed by @code{\%} ++@cindex @code{\%}, following @code{\X} or @code{\Y} ++Note that @code{\X} and @code{\Y} start a word, that is, the @code{\%} ++escape in (say) @w{@samp{\X'...'\%foobar}} and ++@w{@samp{\Y'...'\%foobar}} no longer prevents hyphenation but inserts a ++hyphenation point at the beginning of @samp{foobar}; most likely this ++isn't what you want to do. ++@endDefesc ++ ++@Defreq {hc, [@Var{char}]} ++Change the hyphenation character to @var{char}. This character then ++works the same as the @code{\%} escape, and thus, no longer appears in ++the output. Without an argument, @code{hc} resets the hyphenation ++character to be @code{\%} (the default) only. ++ ++The hyphenation character is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@DefreqList {hpf, pattern_file} ++@DefreqItemx {hpfa, pattern_file} ++@DefreqListEndx {hpfcode, a b [c d @dots{}]} ++@cindex hyphenation patterns (@code{hpf}) ++@cindex patterns for hyphenation (@code{hpf}) ++Read in a file of hyphenation patterns. This file is searched for in ++the same way as @file{@var{name}.tmac} (or @file{tmac.@var{name}}) is ++searched for if the @option{-m@var{name}} option is specified. ++ ++It should have the same format as (simple) @TeX{} patterns files. More ++specifically, the following scanning rules are implemented. ++ ++@itemize @bullet ++@item ++A percent sign starts a comment (up to the end of the line) even if ++preceded by a backslash. ++ ++@item ++No support for `digraphs' like @code{\$}. ++ ++@item ++@code{^^@var{xx}} (@var{x} is 0-9 or a-f) and @code{^^@var{x}} ++(character code of @var{x} in the range 0-127) are recognized; other use ++of @code{^} causes an error. ++ ++@item ++No macro expansion. ++ ++@item ++@code{hpf} checks for the expression @code{\patterns@{@dots{}@}} ++(possibly with whitespace before and after the braces). Everything ++between the braces is taken as hyphenation patterns. Consequently, ++@code{@{} and @code{@}} are not allowed in patterns. ++ ++@item ++Similarly, @code{\hyphenation@{@dots{}@}} gives a list of hyphenation ++exceptions. ++ ++@item ++@code{\endinput} is recognized also. ++ ++@item ++For backwards compatibility, if @code{\patterns} is missing, the whole ++file is treated as a list of hyphenation patterns (only recognizing the ++@code{%} character as the start of a comment). ++@end itemize ++ ++If no @code{hpf} request is specified (either in the document or in a ++macro package), @code{gtroff} won't hyphenate at all. ++ ++The @code{hpfa} request appends a file of patterns to the current list. ++ ++The @code{hpfcode} request defines mapping values for character codes in ++hyphenation patterns. @code{hpf} or @code{hpfa} then apply the mapping ++(after reading the patterns) before replacing or appending them to the ++current list of patterns. Its arguments are pairs of character codes -- ++integers from 0 to@tie{}255. The request maps character ++code@tie{}@var{a} to code@tie{}@var{b}, code@tie{}@var{c} to ++code@tie{}@var{d}, and so on. You can use character codes that would ++be invalid otherwise. By default, everything maps to itself except ++letters `A' to `Z', which map to `a' to `z'. ++ ++ ++@pindex troffrc ++@pindex troffrc-end ++@pindex hyphen.us ++@pindex hyphenex.us ++The set of hyphenation patterns is associated with the current language ++set by the @code{hla} request. The @code{hpf} request is usually ++invoked by the @file{troffrc} or @file{troffrc-end} file; by default, ++@file{troffrc} loads hyphenation patterns and exceptions for American ++English (in files @file{hyphen.us} and @file{hyphenex.us}). ++ ++A second call to @code{hpf} (for the same language) replaces the ++hyphenation patterns with the new ones. ++ ++Invoking @code{hpf} causes an error if there is no current hyphenation ++language. ++@endDefreq ++ ++@Defreq {hcode, c1 code1 [c2 code2 @dots{}]} ++@cindex hyphenation code (@code{hcode}) ++@cindex code, hyphenation (@code{hcode}) ++Set the hyphenation code of character @var{c1} to @var{code1}, that of ++@var{c2} to @var{code2}, etc. A hyphenation code must be a single input ++character (not a special character) other than a digit or a space. ++ ++To make hyphenation work, hyphenation codes must be set up. At ++start-up, groff only assigns hyphenation codes to the letters ++@samp{a}-@samp{z} (mapped to themselves) and to the letters ++@samp{A}-@samp{Z} (mapped to @samp{a}-@samp{z}); all other hyphenation ++codes are set to zero. Normally, hyphenation patterns contain only ++lowercase letters, which should be applied regardless of case. In ++other words, the words `FOO' and `Foo' should be hyphenated exactly the ++same way as the word `foo' is hyphenated, and this is what @code{hcode} ++is good for. Words that contain other letters won't be hyphenated ++properly if the corresponding hyphenation patterns actually do contain ++them. For example, the following @code{hcode} requests are necessary to ++assign hyphenation codes to the letters @samp{} (this is needed ++for German): ++ ++@Example ++.hcode ++.hcode ++.hcode ++.hcode ++@endExample ++ ++Without those assignments, groff treats German words like ++@w{`Kindergrten'} (the plural form of `kindergarten') as two substrings ++@w{`kinderg'} and @w{`rten'} because the hyphenation code of the ++umlaut@tie{}a is zero by default. There is a German hyphenation pattern ++that covers @w{`kinder'}, so groff finds the hyphenation `kin-der'. ++The other two hyphenation points (`kin-der-gr-ten') are missed. ++ ++This request is ignored if it has no parameter. ++@endDefreq ++ ++@DefreqList {hym, [@Var{length}]} ++@DefregListEndx {.hym} ++@cindex hyphenation margin (@code{hym}) ++@cindex margin for hyphenation (@code{hym}) ++@cindex @code{ad} request, and hyphenation margin ++Set the (right) hyphenation margin to @var{length}. If the current ++adjustment mode is not @samp{b} or @samp{n}, the line is not hyphenated ++if it is shorter than @var{length}. Without an argument, the ++hyphenation margin is reset to its default value, which is@tie{}0. The ++default scaling indicator for this request is @samp{m}. The hyphenation ++margin is associated with the current environment ++(@pxref{Environments}). ++ ++A negative argument resets the hyphenation margin to zero, emitting a ++warning of type @samp{range}. ++ ++@cindex hyphenation margin register (@code{.hym}) ++The current hyphenation margin is available in the @code{.hym} read-only ++number register. ++@endDefreq ++ ++@DefreqList {hys, [@Var{hyphenation_space}]} ++@DefregListEndx {.hys} ++@cindex hyphenation space (@code{hys}) ++@cindex @code{ad} request, and hyphenation space ++Set the hyphenation space to @var{hyphenation_space}. If the current ++adjustment mode is @samp{b} or @samp{n}, don't hyphenate the line if it ++can be justified by adding no more than @var{hyphenation_space} extra ++space to each word space. Without argument, the hyphenation space is ++set to its default value, which is@tie{}0. The default scaling ++indicator for this request is @samp{m}. The hyphenation space is ++associated with the current environment (@pxref{Environments}). ++ ++A negative argument resets the hyphenation space to zero, emitting a ++warning of type @samp{range}. ++ ++@cindex hyphenation space register (@code{.hys}) ++The current hyphenation space is available in the @code{.hys} read-only ++number register. ++@endDefreq ++ ++@Defreq {shc, [@Var{glyph}]} ++@cindex soft hyphen character, setting (@code{shc}) ++@cindex character, soft hyphen, setting (@code{shc}) ++@cindex glyph, soft hyphen (@code{hy}) ++@cindex soft hyphen glyph (@code{hy}) ++@cindex @code{char} request, and soft hyphen character ++@cindex @code{tr} request, and soft hyphen character ++Set the @dfn{soft hyphen character} to @var{glyph}.@footnote{@dfn{Soft ++hyphen character} is a misnomer since it is an output glyph.} If the ++argument is omitted, the soft hyphen character is set to the default ++glyph @code{\(hy} (this is the start-up value of @code{gtroff} also). ++The soft hyphen character is the glyph that is inserted when a word is ++hyphenated at a line break. If the soft hyphen character does not exist ++in the font of the character immediately preceding a potential break ++point, then the line is not broken at that point. Neither definitions ++(specified with the @code{char} request) nor translations (specified ++with the @code{tr} request) are considered when finding the soft hyphen ++character. ++@endDefreq ++ ++@DefreqList {hla, language} ++@DefregListEndx {.hla} ++@cindex @code{hpf} request, and hyphenation language ++@cindex @code{hw} request, and hyphenation language ++@pindex troffrc ++@pindex troffrc-end ++Set the current hyphenation language to the string @var{language}. ++Hyphenation exceptions specified with the @code{hw} request and ++hyphenation patterns specified with the @code{hpf} and @code{hpfa} ++requests are both associated with the current hyphenation language. The ++@code{hla} request is usually invoked by the @file{troffrc} or the ++@file{troffrc-end} files; @file{troffrc} sets the default language to ++@samp{us}. ++ ++@cindex hyphenation language register (@code{.hla}) ++The current hyphenation language is available as a string in the ++read-only number register @samp{.hla}. ++ ++@Example ++.ds curr_language \n[.hla] ++\*[curr_language] ++ @result{} us ++@endExample ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Manipulating Spacing, Tabs and Fields, Manipulating Hyphenation, gtroff Reference ++@section Manipulating Spacing ++@cindex manipulating spacing ++@cindex spacing, manipulating ++ ++@Defreq {sp, [@Var{distance}]} ++Space downwards @var{distance}. With no argument it advances ++1@tie{}line. A negative argument causes @code{gtroff} to move up the ++page the specified distance. If the argument is preceded by a @samp{|} ++then @code{gtroff} moves that distance from the top of the page. This ++request causes a line break, and that adds the current line spacing to ++the space you have just specified. The default scaling indicator is ++@samp{v}. ++ ++For convenience you may wish to use the following macros to set the ++height of the next line at a given distance from the top or the bottom ++of the page: ++ ++@Example ++.de y-from-top-down ++. sp |\\$1-\\n[.v]u ++.. ++. ++.de y-from-bot-up ++. sp |\\n[.p]u-\\$1-\\n[.v]u ++.. ++@endExample ++ ++@noindent ++A call to @samp{.y-from-bot-up 10c} means that the bottom of the next ++line will be at 10@dmn{cm} from the paper edge at the bottom. ++ ++If a vertical trap is sprung during execution of @code{sp}, the amount ++of vertical space after the trap is discarded. For example, this ++ ++@Example ++.de xxx ++.. ++. ++.wh 0 xxx ++. ++.pl 5v ++foo ++.sp 2 ++bar ++.sp 50 ++baz ++@endExample ++ ++@noindent ++results in ++ ++@Example ++foo ++ ++ ++bar ++ ++baz ++@endExample ++ ++@cindex @code{sp} request, and traps ++@cindex discarded space in traps ++@cindex space, discarded, in traps ++@cindex traps, and discarded space ++The amount of discarded space is available in the number register ++@code{.trunc}. ++ ++To protect @code{sp} against vertical traps, use the @code{vpt} request: ++ ++@Example ++.vpt 0 ++.sp -3 ++.vpt 1 ++@endExample ++@endDefreq ++ ++@DefreqList {ls, [@Var{nnn}]} ++@DefregListEndx {.L} ++@cindex double-spacing (@code{ls}) ++Output @w{@var{nnn}@minus{}1} blank lines after each line of text. With ++no argument, @code{gtroff} uses the previous value before the last ++@code{ls} call. ++ ++@Example ++.ls 2 \" This causes double-spaced output ++.ls 3 \" This causes triple-spaced output ++.ls \" Again double-spaced ++@endExample ++ ++The line spacing is associated with the current environment ++(@pxref{Environments}). ++ ++@cindex line spacing register (@code{.L}) ++The read-only number register @code{.L} contains the current line ++spacing setting. ++@endDefreq ++ ++@xref{Changing Type Sizes}, for the requests @code{vs} and @code{pvs} as ++alternatives to @code{ls}. ++ ++@DefescList {\\x, ', spacing, '} ++@DefregListEndx {.a} ++Sometimes, extra vertical spacing is only needed occasionally, e.g.@: to ++allow space for a tall construct (like an equation). The @code{\x} ++escape does this. The escape is given a numerical argument, usually ++enclosed in quotes (like @samp{\x'3p'}); the default scaling indicator ++is @samp{v}. If this number is positive extra vertical space is ++inserted below the current line. A negative number adds space above. ++If this escape is used multiple times on the same line, the maximum of ++the values is used. ++ ++@xref{Escapes}, for details on parameter delimiting characters. ++ ++@cindex extra post-vertical line space register (@code{.a}) ++The @code{.a} read-only number register contains the most recent ++(nonnegative) extra vertical line space. ++ ++Using @code{\x} can be necessary in combination with the @code{\b} ++escape, as the following example shows. ++ ++@Example ++This is a test with the \[rs]b escape. ++.br ++This is a test with the \[rs]b escape. ++.br ++This is a test with \b'xyz'\x'-1m'\x'1m'. ++.br ++This is a test with the \[rs]b escape. ++.br ++This is a test with the \[rs]b escape. ++@endExample ++ ++@noindent ++produces ++ ++@Example ++This is a test with the \b escape. ++This is a test with the \b escape. ++ x ++This is a test with y. ++ z ++This is a test with the \b escape. ++This is a test with the \b escape. ++@endExample ++@endDefesc ++ ++@DefreqList {ns, } ++@DefreqItemx {rs, } ++@DefregListEndx {.ns} ++@cindex @code{sp} request, and no-space mode ++@cindex no-space mode (@code{ns}) ++@cindex mode, no-space (@code{ns}) ++@cindex blank lines, disabling ++@cindex lines, blank, disabling ++Enable @dfn{no-space mode}. In this mode, spacing (either via @code{sp} ++or via blank lines) is disabled. The @code{bp} request to advance to ++the next page is also disabled, except if it is accompanied by a page ++number (see @ref{Page Control}, for more information). This mode ends ++when actual text is output or the @code{rs} request is encountered, which ++ends no-space mode. The read-only number register @code{.ns} is set ++to@tie{}1 as long as no-space mode is active. ++ ++This request is useful for macros that conditionally insert vertical ++space before the text starts (for example, a paragraph macro could ++insert some space except when it is the first paragraph after a section ++header). ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Tabs and Fields, Character Translations, Manipulating Spacing, gtroff Reference ++@section Tabs and Fields ++@cindex tabs, and fields ++@cindex fields, and tabs ++ ++@cindex @acronym{EBCDIC} encoding of a tab ++A tab character (@acronym{ASCII} char@tie{}9, @acronym{EBCDIC} ++char@tie{}5) causes a horizontal movement to the next tab stop (much ++like it did on a typewriter). ++ ++@Defesc {\\t, , , } ++@cindex tab character, non-interpreted (@code{\t}) ++@cindex character, tab, non-interpreted (@code{\t}) ++@cindex @code{\t}, and copy-in mode ++@cindex copy-in mode, and @code{\t} ++@cindex mode, copy-in, and @code{\t} ++This escape is a non-interpreted tab character. In copy mode ++(@pxref{Copy-in Mode}), @code{\t} is the same as a real tab character. ++@endDefesc ++ ++@DefreqList {ta, [@Var{n1} @Var{n2} @dots{} @Var{nn} @t{T} @Var{r1} @Var{r2} @dots{} @Var{rn}]} ++@DefregListEndx {.tabs} ++Change tab stop positions. This request takes a series of tab ++specifiers as arguments (optionally divided into two groups with the ++letter @samp{T}) that indicate where each tab stop is to be (overriding ++any previous settings). ++ ++Tab stops can be specified absolutely, i.e., as the distance from the ++left margin. For example, the following sets 6@tie{}tab stops every one ++inch. ++ ++@Example ++.ta 1i 2i 3i 4i 5i 6i ++@endExample ++ ++Tab stops can also be specified using a leading @samp{+}, which means ++that the specified tab stop is set relative to the previous tab stop. ++For example, the following is equivalent to the previous example. ++ ++@Example ++.ta 1i +1i +1i +1i +1i +1i ++@endExample ++ ++@code{gtroff} supports an extended syntax to specify repeat values after ++the @samp{T} mark (these values are always taken as relative) -- this is ++the usual way to specify tabs set at equal intervals. The following is, ++yet again, the same as the previous examples. It does even more since ++it defines an infinite number of tab stops separated by one inch. ++ ++@Example ++.ta T 1i ++@endExample ++ ++Now we are ready to interpret the full syntax given at the beginning: ++Set tabs at positions @var{n1}, @var{n2}, @dots{}, @var{nn} and then set ++tabs at @var{nn}+@var{r1}, @var{nn}+@var{r2}, @dots{}, @var{nn}+@var{rn} ++and then at @var{nn}+@var{rn}+@var{r1}, @var{nn}+@var{rn}+@var{r2}, ++@dots{}, @var{nn}+@var{rn}+@var{rn}, and so on. ++ ++Example: @samp{4c +6c T 3c 5c 2c} is equivalent to @samp{4c 10c 13c 18c ++20c 23c 28c 30c @dots{}}. ++ ++The material in each tab column (i.e., the column between two tab stops) ++may be justified to the right or left or centered in the column. This ++is specified by appending @samp{R}, @samp{L}, or @samp{C} to the tab ++specifier. The default justification is @samp{L}. Example: ++ ++@Example ++.ta 1i 2iC 3iR ++@endExample ++ ++Some notes: ++ ++@itemize @bullet ++@item ++The default unit of the @code{ta} request is @samp{m}. ++ ++@item ++A tab stop is converted into a non-breakable horizontal movement that ++can be neither stretched nor squeezed. For example, ++ ++@Example ++.ds foo a\tb\tc ++.ta T 5i ++\*[foo] ++@endExample ++ ++@noindent ++creates a single line, which is a bit longer than 10@tie{}inches (a ++string is used to show exactly where the tab characters are). Now ++consider the following: ++ ++@Example ++.ds bar a\tb b\tc ++.ta T 5i ++\*[bar] ++@endExample ++ ++@noindent ++@code{gtroff} first converts the tab stops of the line into unbreakable ++horizontal movements, then splits the line after the second @samp{b} ++(assuming a sufficiently short line length). Usually, this isn't what ++the user wants. ++ ++@item ++Superfluous tabs (i.e., tab characters that do not correspond to a tab ++stop) are ignored except the first one, which delimits the characters ++belonging to the last tab stop for right-justifying or centering. ++Consider the following example ++ ++@Example ++.ds Z foo\tbar\tfoo ++.ds ZZ foo\tbar\tfoobar ++.ds ZZZ foo\tbar\tfoo\tbar ++.ta 2i 4iR ++\*[Z] ++.br ++\*[ZZ] ++.br ++\*[ZZZ] ++.br ++@endExample ++ ++@noindent ++which produces the following output: ++ ++@Example ++foo bar foo ++foo bar foobar ++foo bar foobar ++@endExample ++ ++@noindent ++The first line right-justifies the second `foo' relative to the tab ++stop. The second line right-justifies `foobar'. The third line finally ++right-justifies only `foo' because of the additional tab character, which ++marks the end of the string belonging to the last defined tab stop. ++ ++@item ++Tab stops are associated with the current environment ++(@pxref{Environments}). ++ ++@item ++Calling @code{ta} without an argument removes all tab stops. ++ ++@item ++@cindex tab stops, for TTY output devices ++The start-up value of @code{gtroff} is @w{@samp{T 0.8i}}. ++@end itemize ++ ++@cindex tab settings register (@code{.tabs}) ++The read-only number register @code{.tabs} contains a string ++representation of the current tab settings suitable for use as an ++argument to the @code{ta} request. ++ ++@Example ++.ds tab-string \n[.tabs] ++\*[tab-string] ++ @result{} T120u ++@endExample ++ ++@cindex @code{.S} register, Plan@tie{}9 alias for @code{.tabs} ++@cindex @code{.tabs} register, Plan@tie{}9 alias (@code{.S}) ++The @code{troff} version of the Plan@tie{}9 operating system uses ++register @code{.S} for the same purpose. ++@endDefreq ++ ++@Defreq {tc, [@Var{fill-glyph}]} ++@cindex tab repetition character (@code{tc}) ++@cindex character, tab repetition (@code{tc}) ++@cindex glyph, tab repetition (@code{tc}) ++Normally @code{gtroff} fills the space to the next tab stop with ++whitespace. This can be changed with the @code{tc} request. With no ++argument @code{gtroff} reverts to using whitespace, which is the ++default. The value of this @dfn{tab repetition character} is associated ++with the current environment (@pxref{Environments}).@footnote{@dfn{Tab ++repetition character} is a misnomer since it is an output glyph.} ++@endDefreq ++ ++@DefreqList {linetabs, n} ++@DefregListEndx {.linetabs} ++@cindex tab, line-tabs mode ++@cindex line-tabs mode ++@cindex mode, line-tabs ++If @var{n} is missing or not zero, enable @dfn{line-tabs} mode, or ++disable it otherwise (the default). In line-tabs mode, @code{gtroff} ++computes tab distances relative to the (current) output line instead of ++the input line. ++ ++For example, the following code: ++ ++@Example ++.ds x a\t\c ++.ds y b\t\c ++.ds z c ++.ta 1i 3i ++\*x ++\*y ++\*z ++@endExample ++ ++@noindent ++in normal mode, results in the output ++ ++@Example ++a b c ++@endExample ++ ++@noindent ++in line-tabs mode, the same code outputs ++ ++@Example ++a b c ++@endExample ++ ++Line-tabs mode is associated with the current environment. The ++read-only register @code{.linetabs} is set to@tie{}1 if in line-tabs ++mode, and 0 in normal mode. ++@endDefreq ++ ++@menu ++* Leaders:: ++* Fields:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Leaders, Fields, Tabs and Fields, Tabs and Fields ++@subsection Leaders ++@cindex leaders ++ ++Sometimes it may may be desirable to use the @code{tc} request to fill a ++particular tab stop with a given glyph (for example dots in a table of ++contents), but also normal tab stops on the rest of the line. For this ++@code{gtroff} provides an alternate tab mechanism, called @dfn{leaders}, ++which does just that. ++ ++@cindex leader character ++A leader character (character code@tie{}1) behaves similarly to a tab ++character: It moves to the next tab stop. The only difference is that ++for this movement, the fill glyph defaults to a period character and not ++to space. ++ ++@Defesc {\\a, , , } ++@cindex leader character, non-interpreted (@code{\a}) ++@cindex character, leader, non-interpreted (@code{\a}) ++@cindex @code{\a}, and copy-in mode ++@cindex copy-in mode, and @code{\a} ++@cindex mode, copy-in, and @code{\a} ++This escape is a non-interpreted leader character. In copy mode ++(@pxref{Copy-in Mode}), @code{\a} is the same as a real leader ++character. ++@endDefesc ++ ++@Defreq {lc, [@Var{fill-glyph}]} ++@cindex leader repetition character (@code{lc}) ++@cindex character, leader repetition (@code{lc}) ++@cindex glyph, leader repetition (@code{lc}) ++Declare the @dfn{leader repetition character}.@footnote{@dfn{Leader ++repetition character} is a misnomer since it is an output glyph.} ++Without an argument, leaders act the same as tabs (i.e., using ++whitespace for filling). @code{gtroff}'s start-up value is a dot ++(@samp{.}). The value of the leader repetition character is associated ++with the current environment (@pxref{Environments}). ++@endDefreq ++ ++@cindex table of contents ++@cindex contents, table of ++For a table of contents, to name an example, tab stops may be defined so ++that the section number is one tab stop, the title is the second with ++the remaining space being filled with a line of dots, and then the page ++number slightly separated from the dots. ++ ++@Example ++.ds entry 1.1\tFoo\a\t12 ++.lc . ++.ta 1i 5i +.25i ++\*[entry] ++@endExample ++ ++@noindent ++This produces ++ ++@Example ++1.1 Foo.......................................... 12 ++@endExample ++ ++@c --------------------------------------------------------------------- ++ ++@node Fields, , Leaders, Tabs and Fields ++@subsection Fields ++@cindex fields ++ ++@cindex field delimiting character (@code{fc}) ++@cindex delimiting character, for fields (@code{fc}) ++@cindex character, field delimiting (@code{fc}) ++@cindex field padding character (@code{fc}) ++@cindex padding character, for fields (@code{fc}) ++@cindex character, field padding (@code{fc}) ++@dfn{Fields} are a more general way of laying out tabular data. A field ++is defined as the data between a pair of @dfn{delimiting characters}. ++It contains substrings that are separated by @dfn{padding characters}. ++The width of a field is the distance on the @emph{input} line from the ++position where the field starts to the next tab stop. A padding ++character inserts stretchable space similar to @TeX{}'s @code{\hss} ++command (thus it can even be negative) to make the sum of all substring ++lengths plus the stretchable space equal to the field width. If more ++than one padding character is inserted, the available space is evenly ++distributed among them. ++ ++@Defreq {fc, [@Var{delim-char} [@Var{padding-char}]]} ++Define a delimiting and a padding character for fields. If the latter ++is missing, the padding character defaults to a space character. If ++there is no argument at all, the field mechanism is disabled (which is ++the default). Note that contrary to e.g.@: the tab repetition ++character, delimiting and padding characters are @emph{not} associated ++to the current environment (@pxref{Environments}). ++ ++Example: ++ ++@Example ++.fc # ^ ++.ta T 3i ++#foo^bar^smurf# ++.br ++#foo^^bar^smurf# ++@endExample ++ ++@noindent ++and here the result: ++ ++@Example ++foo bar smurf ++foo bar smurf ++@endExample ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Character Translations, Troff and Nroff Mode, Tabs and Fields, gtroff Reference ++@section Character Translations ++@cindex character translations ++@cindex translations of characters ++ ++@cindex control character, changing (@code{cc}) ++@cindex character, control, changing (@code{cc}) ++@cindex no-break control character, changing (@code{c2}) ++@cindex character, no-break control, changing (@code{c2}) ++@cindex control character, no-break, changing (@code{c2}) ++The control character (@samp{.}) and the no-break control character ++(@samp{'}) can be changed with the @code{cc} and @code{c2} requests, ++respectively. ++ ++@Defreq {cc, [@Var{c}]} ++Set the control character to@tie{}@var{c}. With no argument the default ++control character @samp{.} is restored. The value of the control ++character is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@Defreq {c2, [@Var{c}]} ++Set the no-break control character to@tie{}@var{c}. With no argument ++the default control character @samp{'} is restored. The value of the ++no-break control character is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@xref{Requests}. ++ ++@Defreq {eo, } ++@cindex disabling @code{\} (@code{eo}) ++@cindex @code{\}, disabling (@code{eo}) ++Disable the escape mechanism completely. After executing this request, ++the backslash character @samp{\} no longer starts an escape sequence. ++ ++This request can be very helpful in writing macros since it is not ++necessary then to double the escape character. Here an example: ++ ++@Example ++.\" This is a simplified version of the ++.\" .BR request from the man macro package ++.eo ++.de BR ++. ds result \& ++. while (\n[.$] >= 2) \@{\ ++. as result \fB\$1\fR\$2 ++. shift 2 ++. \@} ++. if \n[.$] .as result \fB\$1 ++\*[result] ++. ft R ++.. ++.ec ++@endExample ++@endDefreq ++ ++@Defreq {ec, [@Var{c}]} ++@cindex escape character, changing (@code{ec}) ++@cindex character, escape, changing (@code{ec}) ++Set the escape character to@tie{}@var{c}. With no argument the default ++escape character @samp{\} is restored. It can be also used to re-enable ++the escape mechanism after an @code{eo} request. ++ ++Note that changing the escape character globally likely breaks macro ++packages since @code{gtroff} has no mechanism to `intern' macros, i.e., ++to convert a macro definition into an internal form that is independent ++of its representation (@TeX{} has this mechanism). If a macro is ++called, it is executed literally. ++@endDefreq ++ ++@DefreqList {ecs, } ++@DefreqListEndx {ecr, } ++The @code{ecs} request saves the current escape character in an internal ++register. Use this request in combination with the @code{ec} request to ++temporarily change the escape character. ++ ++The @code{ecr} request restores the escape character saved with ++@code{ecs}. Without a previous call to @code{ecs}, this request sets ++the escape character to @code{\}. ++@endDefreq ++ ++@DefescList {\\\\, , , } ++@DefescItemx {\\e, , , } ++@DefescListEndx {\\E, , , } ++Print the current escape character (which is the backslash character ++@samp{\} by default). ++ ++@code{\\} is a `delayed' backslash; more precisely, it is the default ++escape character followed by a backslash, which no longer has special ++meaning due to the leading escape character. It is @emph{not} an escape ++sequence in the usual sense! In any unknown escape sequence ++@code{\@var{X}} the escape character is ignored and @var{X} is printed. ++But if @var{X} is equal to the current escape character, no warning is ++emitted. ++ ++@cindex @code{\E}, and copy-in mode ++@cindex copy-in mode, and @code{\E} ++@cindex mode, copy-in, and @code{\E} ++As a consequence, only at top-level or in a diversion a backslash glyph ++is printed; in copy-in mode, it expands to a single backslash, which then ++combines with the following character to an escape sequence. ++ ++The @code{\E} escape differs from @code{\e} by printing an escape ++character that is not interpreted in copy mode. Use this to define ++strings with escapes that work when used in copy mode (for example, as a ++macro argument). The following example defines strings to begin and end ++a superscript: ++ ++@Example ++.ds @{ \v'-.3m'\s'\En[.s]*60/100' ++.ds @} \s0\v'.3m' ++@endExample ++ ++Another example to demonstrate the differences between the various ++escape sequences, using a strange escape character, @samp{-}. ++ ++@Example ++.ec - ++.de xxx ++--A'123' ++.. ++.xxx ++ @result{} -A'foo' ++@endExample ++ ++@noindent ++The result is surprising for most users, expecting @samp{1} since ++@samp{foo} is a valid identifier. What has happened? As mentioned ++above, the leading escape character makes the following character ++ordinary. Written with the default escape character the sequence ++@samp{--} becomes @samp{\-} -- this is the minus sign. ++ ++If the escape character followed by itself is a valid escape sequence, ++only @code{\E} yields the expected result: ++ ++@Example ++.ec - ++.de xxx ++-EA'123' ++.. ++.xxx ++ @result{} 1 ++@endExample ++@endDefesc ++ ++@Defesc {\\., , , } ++Similar to @code{\\}, the sequence @code{\.} isn't a real escape ++sequence. As before, a warning message is suppressed if the escape ++character is followed by a dot, and the dot itself is printed. ++ ++@Example ++.de foo ++. nop foo ++. ++. de bar ++. nop bar ++\\.. ++. ++.. ++.foo ++.bar ++ @result{} foo bar ++@endExample ++ ++@noindent ++The first backslash is consumed while the macro is read, and the second ++is swallowed while executing macro @code{foo}. ++@endDefesc ++ ++A @dfn{translation} is a mapping of an input character to an output ++glyph. The mapping occurs at output time, i.e., the input character ++gets assigned the metric information of the mapped output character ++right before input tokens are converted to nodes (@pxref{Gtroff ++Internals}, for more on this process). ++ ++@DefreqList {tr, @Var{a}@Var{b}@Var{c}@Var{d}@dots{}} ++@DefreqListEndx {trin, @Var{a}@Var{b}@Var{c}@Var{d}@dots{}} ++Translate character @var{a} to glyph@tie{}@var{b}, character @var{c} to ++glyph@tie{}@var{d}, etc. If there is an odd number of arguments, the ++last one is translated to an unstretchable space (@w{@samp{\ }}). ++ ++The @code{trin} request is identical to @code{tr}, but when you unformat ++a diversion with @code{asciify} it ignores the translation. ++@xref{Diversions}, for details about the @code{asciify} request. ++ ++Some notes: ++ ++@itemize @bullet ++@item ++@cindex @code{\(}, and translations ++@cindex @code{\[}, and translations ++@cindex @code{\'}, and translations ++@cindex @code{\`}, and translations ++@cindex @code{\-}, and translations ++@cindex @code{\_}, and translations ++@cindex @code{\C}, and translations ++@cindex @code{\N}, and translations ++@cindex @code{char} request, and translations ++@cindex special characters ++@cindex character, special ++@cindex numbered glyph (@code{\N}) ++@cindex glyph, numbered (@code{\N}) ++Special characters (@code{\(@var{xx}}, @code{\[@var{xxx}]}, ++@code{\C'@var{xxx}'}, @code{\'}, @code{\`}, @code{\-}, @code{\_}), ++glyphs defined with the @code{char} request, and numbered glyphs ++(@code{\N'@var{xxx}'}) can be translated also. ++ ++@item ++@cindex @code{\e}, and translations ++The @code{\e} escape can be translated also. ++ ++@item ++@cindex @code{\%}, and translations ++@cindex @code{\~}, and translations ++Characters can be mapped onto the @code{\%} and @code{\~} escapes (but ++@code{\%} and @code{\~} can't be mapped onto another glyph). ++ ++@item ++@cindex backspace character, and translations ++@cindex character, backspace, and translations ++@cindex leader character, and translations ++@cindex character, leader, and translations ++@cindex newline character, and translations ++@cindex character, newline, and translations ++@cindex tab character, and translations ++@cindex character, tab, and translations ++@cindex @code{\a}, and translations ++@cindex @code{\t}, and translations ++The following characters can't be translated: space (with one exception, ++see below), backspace, newline, leader (and @code{\a}), tab (and ++@code{\t}). ++ ++@item ++@cindex @code{shc} request, and translations ++Translations are not considered for finding the soft hyphen character ++set with the @code{shc} request. ++ ++@item ++@cindex @code{\&}, and translations ++The pair @samp{@var{c}\&} (this is an arbitrary character@tie{}@var{c} ++followed by the zero width space character) maps this character to ++nothing. ++ ++@Example ++.tr a\& ++foo bar ++ @result{} foo br ++@endExample ++ ++@noindent ++It is even possible to map the space character to nothing: ++ ++@Example ++.tr aa \& ++foo bar ++ @result{} foobar ++@endExample ++ ++@noindent ++As shown in the example, the space character can't be the first ++character/glyph pair as an argument of @code{tr}. Additionally, it is ++not possible to map the space character to any other glyph; requests ++like @w{@samp{.tr aa x}} undo @w{@samp{.tr aa \&}} instead. ++ ++If justification is active, lines are justified in spite of the `empty' ++space character (but there is no minimal distance, i.e.@: the space ++character, between words). ++ ++@item ++After an output glyph has been constructed (this happens at the moment ++immediately before the glyph is appended to an output glyph list, either ++by direct output, in a macro, diversion, or string), it is no longer ++affected by @code{tr}. ++ ++@item ++Translating character to glyphs where one of them or both are undefined ++is possible also; @code{tr} does not check whether the entities in its ++argument do exist. ++ ++@xref{Gtroff Internals}. ++ ++@item ++@code{troff} no longer has a hard-coded dependency on @w{Latin-1}; all ++@code{char@var{XXX}} entities have been removed from the font ++description files. This has a notable consequence that shows up in ++warnings like @code{can't find character with input code @var{XXX}} if ++the @code{tr} request isn't handled properly. ++ ++Consider the following translation: ++ ++@Example ++.tr ++@endExample ++ ++@noindent ++This maps input character @code{} onto glyph @code{}, which is ++identical to glyph @code{char201}. But this glyph intentionally doesn't ++exist! Instead, @code{\[char201]} is treated as an input character ++entity and is by default mapped onto @code{\['E]}, and @code{gtroff} ++doesn't handle translations of translations. ++ ++The right way to write the above translation is ++ ++@Example ++.tr \['E] ++@endExample ++ ++@noindent ++In other words, the first argument of @code{tr} should be an input ++character or entity, and the second one a glyph entity. ++ ++@item ++Without an argument, the @code{tr} request is ignored. ++@end itemize ++@endDefreq ++ ++@Defreq {trnt, @Var{a}@Var{b}@Var{c}@Var{d}@dots{}} ++@cindex @code{\!}, and @code{trnt} ++@code{trnt} is the same as the @code{tr} request except that the ++translations do not apply to text that is transparently throughput into ++a diversion with @code{\!}. @xref{Diversions}, for more information. ++ ++For example, ++ ++@Example ++.tr ab ++.di x ++\!.tm a ++.di ++.x ++@endExample ++ ++@noindent ++prints @samp{b} to the standard error stream; if @code{trnt} is used ++instead of @code{tr} it prints @samp{a}. ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Troff and Nroff Mode, Line Layout, Character Translations, gtroff Reference ++@section Troff and Nroff Mode ++@cindex troff mode ++@cindex mode, troff ++@cindex nroff mode ++@cindex mode, nroff ++ ++Originally, @code{nroff} and @code{troff} were two separate programs, ++the former for TTY output, the latter for everything else. With GNU ++@code{troff}, both programs are merged into one executable, sending its ++output to a device driver (@code{grotty} for TTY devices, @code{grops} ++for @sc{PostScript}, etc.)@: which interprets the intermediate output of ++@code{gtroff}. For @acronym{UNIX} @code{troff} it makes sense to talk ++about @dfn{Nroff mode} and @dfn{Troff mode} since the differences are ++hardcoded. For GNU @code{troff}, this distinction is not appropriate ++because @code{gtroff} simply takes the information given in the font ++files for a particular device without handling requests specially if a ++TTY output device is used. ++ ++Usually, a macro package can be used with all output devices. ++Nevertheless, it is sometimes necessary to make a distinction between ++TTY and non-TTY devices: @code{gtroff} provides two built-in conditions ++@samp{n} and @samp{t} for the @code{if}, @code{ie}, and @code{while} ++requests to decide whether @code{gtroff} shall behave like @code{nroff} ++or like @code{troff}. ++ ++@Defreq {troff, } ++@pindex troffrc ++@pindex troffrc-end ++Make the @samp{t} built-in condition true (and the @samp{n} built-in ++condition false) for @code{if}, @code{ie}, and @code{while} conditional ++requests. This is the default if @code{gtroff} (@emph{not} ++@code{groff}) is started with the @option{-R} switch to avoid loading of ++the start-up files @file{troffrc} and @file{troffrc-end}. Without ++@option{-R}, @code{gtroff} stays in troff mode if the output device is ++not a TTY (e.g.@: `ps'). ++@endDefreq ++ ++@Defreq {nroff, } ++@pindex tty.tmac ++Make the @samp{n} built-in condition true (and the @samp{t} built-in ++condition false) for @code{if}, @code{ie}, and @code{while} conditional ++requests. This is the default if @code{gtroff} uses a TTY output ++device; the code for switching to nroff mode is in the file ++@file{tty.tmac}, which is loaded by the start-up file @code{troffrc}. ++@endDefreq ++ ++@xref{Conditionals and Loops}, for more details on built-in conditions. ++ ++ ++@c ===================================================================== ++ ++@node Line Layout, Line Control, Troff and Nroff Mode, gtroff Reference ++@section Line Layout ++@cindex line layout ++@cindex layout, line ++ ++@cindex dimensions, line ++@cindex line dimensions ++The following drawing shows the dimensions that @code{gtroff} uses for ++placing a line of output onto the page. They are labeled with the ++request that manipulates each dimension. ++ ++@Example ++ -->| in |<-- ++ |<-----------ll------------>| ++ +----+----+----------------------+----+ ++ | : : : | ++ +----+----+----------------------+----+ ++-->| po |<-- ++ |<--------paper width---------------->| ++@endExample ++ ++@noindent ++These dimensions are: ++ ++@ftable @code ++@item po ++@cindex left margin (@code{po}) ++@cindex margin, left (@code{po}) ++@cindex page offset (@code{po}) ++@cindex offset, page (@code{po}) ++@dfn{Page offset} -- this is the leftmost position of text on the final ++output, defining the @dfn{left margin}. ++ ++@item in ++@cindex indentation (@code{in}) ++@cindex line indentation (@code{in}) ++@dfn{Indentation} -- this is the distance from the left margin where ++text is printed. ++ ++@item ll ++@cindex line length (@code{ll}) ++@cindex length of line (@code{ll}) ++@dfn{Line length} -- this is the distance from the left margin to right ++margin. ++@end ftable ++ ++A simple demonstration: ++ ++@Example ++.ll 3i ++This is text without indentation. ++The line length has been set to 3\~inch. ++.in +.5i ++.ll -.5i ++Now the left and right margins are both increased. ++.in ++.ll ++Calling .in and .ll without parameters restore ++the previous values. ++@endExample ++ ++Result: ++ ++@Example ++This is text without indenta- ++tion. The line length has ++been set to 3 inch. ++ Now the left and ++ right margins are ++ both increased. ++Calling .in and .ll without ++parameters restore the previ- ++ous values. ++@endExample ++ ++@DefreqList {po, [@Var{offset}]} ++@DefreqItem {po, @t{+}@Var{offset}} ++@DefreqItem {po, @t{-}@Var{offset}} ++@DefregListEndx {.o} ++@pindex troffrc ++Set horizontal page offset to @var{offset} (or increment or decrement ++the current value by @var{offset}). Note that this request does not ++cause a break, so changing the page offset in the middle of text being ++filled may not yield the expected result. The initial value is ++1@dmn{i}. For TTY output devices, it is set to 0 in the startup file ++@file{troffrc}; the default scaling indicator is @samp{m} (and not ++@samp{v} as incorrectly documented in the original @acronym{UNIX} troff ++manual). ++ ++The current page offset can be found in the read-only number register ++@samp{.o}. ++ ++If @code{po} is called without an argument, the page offset is reset to ++the previous value before the last call to @code{po}. ++ ++@Example ++.po 3i ++\n[.o] ++ @result{} 720 ++.po -1i ++\n[.o] ++ @result{} 480 ++.po ++\n[.o] ++ @result{} 720 ++@endExample ++@endDefreq ++ ++@DefreqList {in, [@Var{indent}]} ++@DefreqItem {in, @t{+}@Var{indent}} ++@DefreqItem {in, @t{-}@Var{indent}} ++@DefregListEndx {.i} ++Set indentation to @var{indent} (or increment or decrement the current ++value by @var{indent}). This request causes a break. Initially, there ++is no indentation. ++ ++If @code{in} is called without an argument, the indentation is reset to ++the previous value before the last call to @code{in}. The default ++scaling indicator is @samp{m}. ++ ++The indentation is associated with the current environment ++(@pxref{Environments}). ++ ++If a negative indentation value is specified (which is not allowed), ++@code{gtroff} emits a warning of type @samp{range} and sets the ++indentation to zero. ++ ++The effect of @code{in} is delayed until a partially collected line (if ++it exists) is output. A temporary indentation value is reset to zero ++also. ++ ++The current indentation (as set by @code{in}) can be found in the ++read-only number register @samp{.i}. ++@endDefreq ++ ++@DefreqList {ti, offset} ++@DefreqItem {ti, @t{+}@Var{offset}} ++@DefreqItem {ti, @t{-}@Var{offset}} ++@DefregListEndx {.in} ++Temporarily indent the next output line by @var{offset}. If an ++increment or decrement value is specified, adjust the temporary ++indentation relative to the value set by the @code{in} request. ++ ++This request causes a break; its value is associated with the current ++environment (@pxref{Environments}). The default scaling indicator is ++@samp{m}. A call of @code{ti} without an argument is ignored. ++ ++If the total indentation value is negative (which is not allowed), ++@code{gtroff} emits a warning of type @samp{range} and sets the ++temporary indentation to zero. `Total indentation' is either ++@var{offset} if specified as an absolute value, or the temporary plus ++normal indentation, if @var{offset} is given as a relative value. ++ ++The effect of @code{ti} is delayed until a partially collected line (if ++it exists) is output. ++ ++The read-only number register @code{.in} is the indentation that applies ++to the current output line. ++ ++The difference between @code{.i} and @code{.in} is that the latter takes ++into account whether a partially collected line still uses the old ++indentation value or a temporary indentation value is active. ++@endDefreq ++ ++@DefreqList {ll, [@Var{length}]} ++@DefreqItem {ll, @t{+}@Var{length}} ++@DefreqItem {ll, @t{-}@Var{length}} ++@DefregItemx {.l} ++@DefregListEndx {.ll} ++Set the line length to @var{length} (or increment or decrement the ++current value by @var{length}). Initially, the line length is set to ++6.5@dmn{i}. The effect of @code{ll} is delayed until a partially ++collected line (if it exists) is output. The default scaling indicator ++is @samp{m}. ++ ++If @code{ll} is called without an argument, the line length is reset to ++the previous value before the last call to @code{ll}. If a negative ++line length is specified (which is not allowed), @code{gtroff} emits a ++warning of type @samp{range} and sets the line length to zero. ++ ++The line length is associated with the current environment ++(@pxref{Environments}). ++ ++@cindex line length register (@code{.l}) ++The current line length (as set by @code{ll}) can be found in the ++read-only number register @samp{.l}. The read-only number register ++@code{.ll} is the line length that applies to the current output line. ++ ++Similar to @code{.i} and @code{.in}, the difference between @code{.l} ++and @code{.ll} is that the latter takes into account whether a partially ++collected line still uses the old line length value. ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Line Control, Page Layout, Line Layout, gtroff Reference ++@section Line Control ++@cindex line control ++@cindex control, line ++ ++It is important to understand how @code{gtroff} handles input and output ++lines. ++ ++Many escapes use positioning relative to the input line. For example, ++this ++ ++@Example ++This is a \h'|1.2i'test. ++ ++This is a ++\h'|1.2i'test. ++@endExample ++ ++@noindent ++produces ++ ++@Example ++This is a test. ++ ++This is a test. ++@endExample ++ ++The main usage of this feature is to define macros that act exactly at ++the place where called. ++ ++@Example ++.\" A simple macro to underline a word ++.de underline ++. nop \\$1\l'|0\[ul]' ++.. ++@endExample ++ ++@noindent ++In the above example, @samp{|0} specifies a negative distance from the ++current position (at the end of the just emitted argument @code{\$1}) ++back to the beginning of the input line. Thus, the @samp{\l} escape ++draws a line from right to left. ++ ++@cindex input line continuation (@code{\}) ++@cindex line, input, continuation (@code{\}) ++@cindex continuation, input line (@code{\}) ++@cindex output line, continuation (@code{\c}) ++@cindex line, output, continuation (@code{\c}) ++@cindex continuation, output line (@code{\c}) ++@cindex interrupted line ++@cindex line, interrupted ++@code{gtroff} makes a difference between input and output line ++continuation; the latter is also called @dfn{interrupting} a line. ++ ++@DefescList {\\@key{RET}, , ,} ++@DefescItemx {\\c, , ,} ++@DefregListEndx {.int} ++Continue a line. @code{\@key{RET}} (this is a backslash at the end of a ++line immediately followed by a newline) works on the input level, ++suppressing the effects of the following newline in the input. ++ ++@Example ++This is a \ ++.test ++ @result{} This is a .test ++@endExample ++ ++The @samp{|} operator is also affected. ++ ++@cindex @code{\R}, after @code{\c} ++@code{\c} works on the output level. Anything after this escape on the ++same line is ignored except @code{\R}, which works as usual. Anything ++before @code{\c} on the same line is appended to the current partial ++output line. The next non-command line after an interrupted line counts ++as a new input line. ++ ++The visual results depend on whether no-fill mode is active. ++ ++@itemize @bullet ++@item ++@cindex @code{\c}, and no-fill mode ++@cindex no-fill mode, and @code{\c} ++@cindex mode, no-fill, and @code{\c} ++If no-fill mode is active (using the @code{nf} request), the next input ++text line after @code{\c} is handled as a continuation of the same input ++text line. ++ ++@Example ++.nf ++This is a \c ++test. ++ @result{} This is a test. ++@endExample ++ ++@item ++@cindex @code{\c}, and fill mode ++@cindex fill mode, and @code{\c} ++@cindex mode, fill, and @code{\c} ++If fill mode is active (using the @code{fi} request), a word interrupted ++with @code{\c} is continued with the text on the next input text line, ++without an intervening space. ++ ++@Example ++This is a te\c ++st. ++ @result{} This is a test. ++@endExample ++@end itemize ++ ++Note that an intervening control line that causes a break is stronger ++than @code{\c}, flushing out the current partial line in the usual way. ++ ++@cindex interrupted line register (@code{.int}) ++The @code{.int} register contains a positive value if the last output ++line was interrupted with @code{\c}; this is associated with the current ++environment (@pxref{Environments}). ++@endDefesc ++ ++ ++@c ===================================================================== ++ ++@node Page Layout, Page Control, Line Control, gtroff Reference ++@section Page Layout ++@cindex page layout ++@cindex layout, page ++ ++@code{gtroff} provides some very primitive operations for controlling ++page layout. ++ ++@DefreqList {pl, [@Var{length}]} ++@DefreqItem {pl, @t{+}@Var{length}} ++@DefreqItem {pl, @t{-}@Var{length}} ++@DefregListEndx {.p} ++@cindex page length (@code{pl}) ++@cindex length of page (@code{pl}) ++Set the @dfn{page length} to @var{length} (or increment or decrement the ++current value by @var{length}). This is the length of the physical ++output page. The default scaling indicator is @samp{v}. ++ ++@cindex page length register (@code{.p}) ++The current setting can be found in the read-only number register ++@samp{.p}. ++ ++@cindex top margin ++@cindex margin, top ++@cindex bottom margin ++@cindex margin, bottom ++Note that this only specifies the size of the page, not the top and ++bottom margins. Those are not set by @code{gtroff} directly. ++@xref{Traps}, for further information on how to do this. ++ ++Negative @code{pl} values are possible also, but not very useful: No ++trap is sprung, and each line is output on a single page (thus ++suppressing all vertical spacing). ++ ++If no argument or an invalid argument is given, @code{pl} sets the page ++length to 11@dmn{i}. ++@endDefreq ++ ++@cindex headers ++@cindex footers ++@cindex titles ++@code{gtroff} provides several operations that help in setting up top ++and bottom titles (or headers and footers). ++ ++@Defreq {tl, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}} ++@cindex title line (@code{tl}) ++@cindex three-part title (@code{tl}) ++@cindex page number character (@code{%}) ++Print a @dfn{title line}. It consists of three parts: a left justified ++portion, a centered portion, and a right justified portion. The ++argument separator @samp{'} can be replaced with any character not ++occurring in the title line. The @samp{%} character is replaced with ++the current page number. This character can be changed with the ++@code{pc} request (see below). ++ ++Without argument, @code{tl} is ignored. ++ ++Some notes: ++ ++@itemize @bullet ++@item ++The line length set by the @code{ll} request is not honoured by ++@code{tl}; use the @code{lt} request (described below) instead, to ++control line length for text set by @code{tl}. ++ ++@item ++A title line is not restricted to the top or bottom of a page. ++ ++@item ++@code{tl} prints the title line immediately, ignoring a partially filled ++line (which stays untouched). ++ ++@item ++It is not an error to omit closing delimiters. For example, ++@w{@samp{.tl /foo}} is equivalent to @w{@samp{.tl /foo///}}: It prints a ++title line with the left justified word @samp{foo}; the centered and ++right justfied parts are empty. ++ ++@item ++@code{tl} accepts the same parameter delimiting characters as the ++@code{\A} escape; see @ref{Escapes}. ++@end itemize ++@endDefreq ++ ++@DefreqList {lt, [@Var{length}]} ++@DefreqItem {lt, @t{+}@Var{length}} ++@DefreqItem {lt, @t{-}@Var{length}} ++@DefregListEndx {.lt} ++@cindex length of title line (@code{lt}) ++@cindex title line, length (@code{lt}) ++@cindex title line length register (@code{.lt}) ++The title line is printed using its own line length, which is specified ++(or incremented or decremented) with the @code{lt} request. Initially, ++the title line length is set to 6.5@dmn{i}. If a negative line length ++is specified (which is not allowed), @code{gtroff} emits a warning of ++type @samp{range} and sets the title line length to zero. The default ++scaling indicator is @samp{m}. If @code{lt} is called without an ++argument, the title length is reset to the previous value before the ++last call to @code{lt}. ++ ++The current setting of this is available in the @code{.lt} read-only ++number register; it is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@DefreqList {pn, page} ++@DefreqItem {pn, @t{+}@Var{page}} ++@DefreqItem {pn, @t{-}@Var{page}} ++@DefregListEndx {.pn} ++@cindex page number (@code{pn}) ++@cindex number, page (@code{pn}) ++Change (increase or decrease) the page number of the @emph{next} page. ++The only argument is the page number; the request is ignored without a ++parameter. ++ ++The read-only number register @code{.pn} contains the number of the next ++page: either the value set by a @code{pn} request, or the number of the ++current page plus@tie{}1. ++@endDefreq ++ ++@Defreq {pc, [@Var{char}]} ++@cindex changing the page number character (@code{pc}) ++@cindex page number character, changing (@code{pc}) ++@vindex % ++Change the page number character (used by the @code{tl} request) to a ++different character. With no argument, this mechanism is disabled. ++Note that this doesn't affect the number register@tie{}@code{%}. ++@endDefreq ++ ++@xref{Traps}. ++ ++ ++@c ===================================================================== ++ ++@node Page Control, Fonts and Symbols, Page Layout, gtroff Reference ++@section Page Control ++@cindex page control ++@cindex control, page ++ ++@DefreqList {bp, [@Var{page}]} ++@DefreqItem {bp, @t{+}@Var{page}} ++@DefreqItem {bp, @t{-}@Var{page}} ++@DefregListEndx {%} ++@cindex new page (@code{bp}) ++@cindex page, new (@code{bp}) ++Stop processing the current page and move to the next page. This ++request causes a break. It can also take an argument to set (increase, ++decrease) the page number of the next page (which actually becomes the ++current page after @code{bp} has finished). The difference between ++@code{bp} and @code{pn} is that @code{pn} does not cause a break or ++actually eject a page. @xref{Page Layout}. ++ ++@Example ++.de newpage \" define macro ++'bp \" begin page ++'sp .5i \" vertical space ++.tl 'left top'center top'right top' \" title ++'sp .3i \" vertical space ++.. \" end macro ++@endExample ++ ++@cindex @code{bp} request, and top-level diversion ++@cindex top-level diversion, and @code{bp} ++@cindex diversion, top-level, and @code{bp} ++@code{bp} has no effect if not called within the top-level diversion ++(@pxref{Diversions}). ++ ++@cindex page number register (@code{%}) ++@cindex current page number (@code{%}) ++The read-write register@tie{}@code{%} holds the current page number. ++ ++The number register @code{.pe} is set to@tie{}1 while @code{bp} is ++active. @xref{Page Location Traps}. ++@endDefreq ++ ++@Defreq {ne, [@Var{space}]} ++@cindex orphan lines, preventing with @code{ne} ++@cindex conditional page break (@code{ne}) ++@cindex page break, conditional (@code{ne}) ++It is often necessary to force a certain amount of space before a new ++page occurs. This is most useful to make sure that there is not a ++single @dfn{orphan} line left at the bottom of a page. The @code{ne} ++request ensures that there is a certain distance, specified by the first ++argument, before the next page is triggered (see @ref{Traps}, for ++further information). The default scaling indicator for @code{ne} is ++@samp{v}; the default value of @var{space} is@tie{}1@dmn{v} if no ++argument is given. ++ ++For example, to make sure that no fewer than 2@tie{}lines get orphaned, ++do the following before each paragraph: ++ ++@Example ++.ne 2 ++text text text ++@endExample ++ ++@code{ne} then automatically causes a page break if there is space for ++one line only. ++@endDefreq ++ ++@DefreqList {sv, [@Var{space}]} ++@DefreqListEndx {os, } ++@cindex @code{ne} request, comparison with @code{sv} ++@code{sv} is similar to the @code{ne} request; it reserves the specified ++amount of vertical space. If the desired amount of space exists before ++the next trap (or the bottom page boundary if no trap is set), the space ++is output immediately (ignoring a partially filled line, which stays ++untouched). If there is not enough space, it is stored for later output ++via the @code{os} request. The default value is@tie{}1@dmn{v} if no ++argument is given; the default scaling indicator is @samp{v}. ++ ++@cindex @code{sv} request, and no-space mode ++@cindex @code{os} request, and no-space mode ++Both @code{sv} and @code{os} ignore no-space mode. While the @code{sv} ++request allows negative values for @var{space}, @code{os} ignores them. ++@endDefreq ++ ++@Defreg {nl} ++@cindex current vertical position (@code{nl}) ++@cindex vertical position, current (@code{nl}) ++@cindex position, vertical, current (@code{nl}) ++This register contains the current vertical position. If the vertical ++position is zero and the top of page transition hasn't happened yet, ++@code{nl} is set to negative value. @code{gtroff} itself does this at ++the very beginning of a document before anything has been printed, but ++the main usage is to plant a header trap on a page if this page has ++already started. ++ ++Consider the following: ++ ++@Example ++.de xxx ++. sp ++. tl ''Header'' ++. sp ++.. ++. ++First page. ++.bp ++.wh 0 xxx ++.nr nl (-1) ++Second page. ++@endExample ++ ++@noindent ++Result: ++ ++@Example ++First page. ++ ++... ++ ++ Header ++ ++Second page. ++ ++... ++@endExample ++ ++@noindent ++Without resetting @code{nl} to a negative value, the just planted trap ++would be active beginning with the @emph{next} page, not the current ++one. ++ ++@xref{Diversions}, for a comparison with the @code{.h} and @code{.d} ++registers. ++@endDefreg ++ ++ ++@c ===================================================================== ++ ++@node Fonts and Symbols, Sizes, Page Control, gtroff Reference ++@section Fonts and Symbols ++@cindex fonts ++ ++@code{gtroff} can switch fonts at any point in the text. ++ ++The basic set of fonts is @samp{R}, @samp{I}, @samp{B}, and @samp{BI}. ++These are Times Roman, Italic, Bold, and Bold Italic. For non-TTY ++devices, there is also at least one symbol font that contains various ++special symbols (Greek, mathematics). ++ ++@menu ++* Changing Fonts:: ++* Font Families:: ++* Font Positions:: ++* Using Symbols:: ++* Character Classes:: ++* Special Fonts:: ++* Artificial Fonts:: ++* Ligatures and Kerning:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Changing Fonts, Font Families, Fonts and Symbols, Fonts and Symbols ++@subsection Changing Fonts ++@cindex fonts ++ ++@DefreqList {ft, [@Var{font}]} ++@DefescItemx {\\f, , f, } ++@DefescItem {\\f, @Lparen{}, fn, } ++@DefescItem {\\f, @Lbrack{}, font, @Rbrack{}} ++@DefregListEndx {.sty} ++@cindex changing fonts (@code{ft}, @code{\f}) ++@cindex fonts, changing (@code{ft}, @code{\f}) ++@cindex @code{sty} request, and changing fonts ++@cindex @code{fam} request, and changing fonts ++@cindex @code{\F}, and changing fonts ++@kindex styles ++@kindex family ++@pindex DESC ++The @code{ft} request and the @code{\f} escape change the current font ++to @var{font} (one-character name@tie{}@var{f}, two-character name ++@var{fn}). ++ ++If @var{font} is a style name (as set with the @code{sty} request or ++with the @code{styles} command in the @file{DESC} file), use it within ++the current font family (as set with the @code{fam} request, @code{\F} ++escape, or with the @code{family} command in the @file{DESC} file). ++ ++It is not possible to switch to a font with the name @samp{DESC} ++(whereas this name could be used as a style name; however, this is not ++recommended). ++ ++@cindex previous font (@code{ft}, @code{\f[]}, @code{\fP}) ++@cindex font, previous (@code{ft}, @code{\f[]}, @code{\fP}) ++With no argument or using @samp{P} as an argument, @code{.ft} switches ++to the previous font. Use @code{\f[]} to do this with the escape. The ++old syntax forms @code{\fP} or @code{\f[P]} are also supported. ++ ++Fonts are generally specified as upper-case strings, which are usually ++1@tie{}to 4 characters representing an abbreviation or acronym of the ++font name. This is no limitation, just a convention. ++ ++The example below produces two identical lines. ++ ++@Example ++eggs, bacon, ++.ft B ++spam ++.ft ++and sausage. ++ ++eggs, bacon, \fBspam\fP and sausage. ++@endExample ++ ++Note that @code{\f} doesn't produce an input token in @code{gtroff}. As ++a consequence, it can be used in requests like @code{mc} (which expects ++a single character as an argument) to change the font on the fly: ++ ++@Example ++.mc \f[I]x\f[] ++@endExample ++ ++The current style name is available in the read-only number register ++@samp{.sty} (this is a string-valued register); if the current font ++isn't a style, the empty string is returned. It is associated with the ++current environment. ++ ++@xref{Font Positions}, for an alternative syntax. ++@endDefreq ++ ++@Defreq {ftr, f [@Var{g}]} ++@cindex font translation (@code{ftr}) ++@cindex @code{ft} request, and font translations ++@cindex @code{ul} request, and font translations ++@cindex @code{bd} request, and font translations ++@cindex @code{\f}, and font translations ++@cindex @code{cs} request, and font translations ++@cindex @code{tkf} request, and font translations ++@cindex @code{special} request, and font translations ++@cindex @code{fspecial} request, and font translations ++@cindex @code{fp} request, and font translations ++@cindex @code{sty} request, and font translations ++@cindex @code{if} request, and font translations ++@cindex @code{ie} request, and font translations ++@cindex @code{while} request, and font translations ++Translate font@tie{}@var{f} to font@tie{}@var{g}. Whenever a font ++named@tie{}@var{f} is referred to in a @code{\f} escape sequence, in the ++@code{F} and @code{S} conditional operators, or in the @code{ft}, ++@code{ul}, @code{bd}, @code{cs}, @code{tkf}, @code{special}, ++@code{fspecial}, @code{fp}, or @code{sty} requests, font@tie{}@var{g} is ++used. If @var{g} is missing or equal to@tie{}@var{f} the translation is ++undone. ++ ++Note that it is not possible to chain font translations. Example: ++ ++@Example ++.ftr XXX TR ++.ftr XXX YYY ++.ft XXX ++ @result{} warning: can't find font `XXX' ++@endExample ++@endDefreq ++ ++@DefreqList {fzoom, f [@Var{zoom}]} ++@DefregListEndx {.zoom} ++@cindex magnification of a font (@code{fzoom}) ++@cindex font, magnification (@code{fzoom}) ++@cindex zoom factor of a font (@code{fzoom}) ++@cindex factor, zoom, of a font (@code{fzoom}) ++@cindex font, zoom factor (@code{fzoom}) ++@cindex optical size of a font ++@cindex font, optical size ++@cindex size, optical, of a font ++Set magnification of font@tie{}@var{f} to factor @var{zoom}, which must ++be a non-negative integer multiple of 1/1000th. This request is useful ++to adjust the optical size of a font in relation to the others. In the ++example below, font @code{CR} is magnified by 10% (the zoom factor is ++thus 1.1). ++ ++@Example ++.fam P ++.fzoom CR 1100 ++.ps 12 ++Palatino and \f[CR]Courier\f[] ++@endExample ++ ++A missing or zero value of @var{zoom} is the same as a value of 1000, ++which means no magnification. @var{f}@tie{}must be a real font name, ++not a style. ++ ++Note that the magnification of a font is completely transparent to ++troff; a change of the zoom factor doesn't cause any effect except that ++the dimensions of glyphs, (word) spaces, kerns, etc., of the affected ++font are adjusted accordingly. ++ ++The zoom factor of the current font is available in the read-only number ++register @samp{.zoom}, in multiples of 1/1000th. It returns zero if ++there is no magnification. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Font Families, Font Positions, Changing Fonts, Fonts and Symbols ++@subsection Font Families ++@cindex font families ++@cindex families, font ++@cindex font styles ++@cindex styles, font ++ ++Due to the variety of fonts available, @code{gtroff} has added the ++concept of @dfn{font families} and @dfn{font styles}. The fonts are ++specified as the concatenation of the font family and style. Specifying ++a font without the family part causes @code{gtroff} to use that style of ++the current family. ++ ++@cindex PostScript fonts ++@cindex fonts, PostScript ++Currently, fonts for the devices @option{-Tps}, @option{-Tpdf}, ++@option{-Tdvi}, @option{-Tlj4}, @option{-Tlbp}, and the X11 fonts are ++set up to this mechanism. By default, @code{gtroff} uses the Times ++family with the four styles @samp{R}, @samp{I}, @samp{B}, and @samp{BI}. ++ ++This way, it is possible to use the basic four fonts and to select a ++different font family on the command line (@pxref{Groff Options}). ++ ++@DefreqList {fam, [@Var{family}]} ++@DefregItemx {.fam} ++@DefescItemx {\\F, , f, } ++@DefescItem {\\F, @Lparen{}, fm, } ++@DefescItem {\\F, @Lbrack{}, family, @Rbrack{}} ++@DefregListEndx {.fn} ++@cindex changing font family (@code{fam}, @code{\F}) ++@cindex font family, changing (@code{fam}, @code{\F}) ++Switch font family to @var{family} (one-character name@tie{}@var{f}, ++two-character name @var{fm}). If no argument is given, switch back to ++the previous font family. Use @code{\F[]} to do this with the escape. ++Note that @code{\FP} doesn't work; it selects font family @samp{P} ++instead. ++ ++The value at start-up is @samp{T}. The current font family is available ++in the read-only number register @samp{.fam} (this is a string-valued ++register); it is associated with the current environment. ++ ++@Example ++spam, ++.fam H \" helvetica family ++spam, \" used font is family H + style R = HR ++.ft B \" family H + style B = font HB ++spam, ++.fam T \" times family ++spam, \" used font is family T + style B = TB ++.ft AR \" font AR (not a style) ++baked beans, ++.ft R \" family T + style R = font TR ++and spam. ++@endExample ++ ++Note that @code{\F} doesn't produce an input token in @code{gtroff}. As ++a consequence, it can be used in requests like @code{mc} (which expects ++a single character as an argument) to change the font family on the fly: ++ ++@Example ++.mc \F[P]x\F[] ++@endExample ++ ++The @samp{.fn} register contains the current @dfn{real font name} of the ++current font. This is a string-valued register. If the current font is ++a style, the value of @code{\n[.fn]} is the proper concatenation of ++family and style name. ++@endDefreq ++ ++@Defreq {sty, n style} ++@cindex changing font style (@code{sty}) ++@cindex font style, changing (@code{sty}) ++@cindex @code{cs} request, and font styles ++@cindex @code{bd} request, and font styles ++@cindex @code{tkf} request, and font styles ++@cindex @code{uf} request, and font styles ++@cindex @code{fspecial} request, and font styles ++Associate @var{style} with font position@tie{}@var{n}. A font position ++can be associated either with a font or with a style. The current font ++is the index of a font position and so is also either a font or a style. ++If it is a style, the font that is actually used is the font which name ++is the concatenation of the name of the current family and the name of ++the current style. For example, if the current font is@tie{}1 and font ++position@tie{}1 is associated with style @samp{R} and the current font ++family is @samp{T}, then font @samp{TR} is used. If the current font is ++not a style, then the current family is ignored. If the requests ++@code{cs}, @code{bd}, @code{tkf}, @code{uf}, or @code{fspecial} are ++applied to a style, they are instead applied to the member of the ++current family corresponding to that style. ++ ++@var{n}@tie{}must be a non-negative integer value. ++ ++@pindex DESC ++@kindex styles ++The default family can be set with the @option{-f} option (@pxref{Groff ++Options}). The @code{styles} command in the @file{DESC} file controls ++which font positions (if any) are initially associated with styles ++rather than fonts. For example, the default setting for @sc{PostScript} ++fonts ++ ++@Example ++styles R I B BI ++@endExample ++ ++@noindent ++is equivalent to ++ ++@Example ++.sty 1 R ++.sty 2 I ++.sty 3 B ++.sty 4 BI ++@endExample ++ ++@code{fam} and @code{\F} always check whether the current font position ++is valid; this can give surprising results if the current font position ++is associated with a style. ++ ++In the following example, we want to access the @sc{PostScript} font ++@code{FooBar} from the font family @code{Foo}: ++ ++@Example ++.sty \n[.fp] Bar ++.fam Foo ++ @result{} warning: can't find font `FooR' ++@endExample ++ ++@noindent ++The default font position at start-up is@tie{}1; for the @sc{PostScript} ++device, this is associated with style @samp{R}, so @code{gtroff} tries ++to open @code{FooR}. ++ ++A solution to this problem is to use a dummy font like the following: ++ ++@Example ++.fp 0 dummy TR \" set up dummy font at position 0 ++.sty \n[.fp] Bar \" register style `Bar' ++.ft 0 \" switch to font at position 0 ++.fam Foo \" activate family `Foo' ++.ft Bar \" switch to font `FooBar' ++@endExample ++ ++@xref{Font Positions}. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Font Positions, Using Symbols, Font Families, Fonts and Symbols ++@subsection Font Positions ++@cindex font positions ++@cindex positions, font ++ ++For the sake of old phototypesetters and compatibility with old versions ++of @code{troff}, @code{gtroff} has the concept of font @dfn{positions}, ++on which various fonts are mounted. ++ ++@DefreqList {fp, pos font [@Var{external-name}]} ++@DefregItemx {.f} ++@DefregListEndx {.fp} ++@cindex mounting font (@code{fp}) ++@cindex font, mounting (@code{fp}) ++Mount font @var{font} at position @var{pos} (which must be a ++non-negative integer). This numeric position can then be referred to ++with font changing commands. When @code{gtroff} starts it is using font ++position@tie{}1 (which must exist; position@tie{}0 is unused usually at ++start-up). ++ ++@cindex font position register (@code{.f}) ++The current font in use, as a font position, is available in the ++read-only number register @samp{.f}. This can be useful to remember the ++current font for later recall. It is associated with the current ++environment (@pxref{Environments}). ++ ++@Example ++.nr save-font \n[.f] ++.ft B ++... text text text ... ++.ft \n[save-font] ++@endExample ++ ++@cindex next free font position register (@code{.fp}) ++The number of the next free font position is available in the read-only ++number register @samp{.fp}. This is useful when mounting a new font, ++like so: ++ ++@Example ++.fp \n[.fp] NEATOFONT ++@endExample ++ ++@pindex DESC@r{, and font mounting} ++Fonts not listed in the @file{DESC} file are automatically mounted on ++the next available font position when they are referenced. If a font is ++to be mounted explicitly with the @code{fp} request on an unused font ++position, it should be mounted on the first unused font position, which ++can be found in the @code{.fp} register. Although @code{gtroff} does ++not enforce this strictly, it is not allowed to mount a font at a ++position whose number is much greater (approx.@: 1000 positions) than ++that of any currently used position. ++ ++The @code{fp} request has an optional third argument. This argument ++gives the external name of the font, which is used for finding the font ++description file. The second argument gives the internal name of the ++font, which is used to refer to the font in @code{gtroff} after it has ++been mounted. If there is no third argument then the internal name is ++used as the external name. This feature makes it possible to use fonts ++with long names in compatibility mode. ++@endDefreq ++ ++Both the @code{ft} request and the @code{\f} escape have alternative ++syntax forms to access font positions. ++ ++@DefreqList {ft, nnn} ++@DefescItemx {\\f, , n, } ++@DefescItem {\\f, @Lparen{}, nn, } ++@DefescListEnd {\\f, @Lbrack{}, nnn, @Rbrack{}} ++@cindex changing font position (@code{\f}) ++@cindex font position, changing (@code{\f}) ++@cindex @code{sty} request, and font positions ++@cindex @code{fam} request, and font positions ++@cindex @code{\F}, and font positions ++@kindex styles ++@kindex family ++@pindex DESC ++Change the current font position to @var{nnn} (one-digit ++position@tie{}@var{n}, two-digit position @var{nn}), which must be a ++non-negative integer. ++ ++If @var{nnn} is associated with a style (as set with the @code{sty} ++request or with the @code{styles} command in the @file{DESC} file), use ++it within the current font family (as set with the @code{fam} request, ++the @code{\F} escape, or with the @code{family} command in the ++@file{DESC} file). ++ ++@Example ++this is font 1 ++.ft 2 ++this is font 2 ++.ft \" switch back to font 1 ++.ft 3 ++this is font 3 ++.ft ++this is font 1 again ++@endExample ++ ++@xref{Changing Fonts}, for the standard syntax form. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Using Symbols, Character Classes, Font Positions, Fonts and Symbols ++@subsection Using Symbols ++@cindex using symbols ++@cindex symbols, using ++ ++@cindex glyph ++@cindex character ++@cindex ligature ++A @dfn{glyph} is a graphical representation of a @dfn{character}. While ++a character is an abstract entity containing semantic information, a ++glyph is something that can be actually seen on screen or paper. It is ++possible that a character has multiple glyph representation forms (for ++example, the character `A' can be either written in a roman or an italic ++font, yielding two different glyphs); sometimes more than one character ++maps to a single glyph (this is a @dfn{ligature} -- the most common is ++`fi'). ++ ++@cindex symbol ++@cindex special fonts ++@kindex fonts ++@pindex DESC ++@cindex @code{special} request, and glyph search order ++@cindex @code{fspecial} request, and glyph search order ++A @dfn{symbol} is simply a named glyph. Within @code{gtroff}, all glyph ++names of a particular font are defined in its font file. If the user ++requests a glyph not available in this font, @code{gtroff} looks up an ++ordered list of @dfn{special fonts}. By default, the @sc{PostScript} ++output device supports the two special fonts @samp{SS} (slanted symbols) ++and @samp{S} (symbols) (the former is looked up before the latter). ++Other output devices use different names for special fonts. Fonts ++mounted with the @code{fonts} keyword in the @file{DESC} file are ++globally available. To install additional special fonts locally (i.e.@: ++for a particular font), use the @code{fspecial} request. ++ ++Here are the exact rules how @code{gtroff} searches a given symbol: ++ ++@itemize @bullet ++@item ++If the symbol has been defined with the @code{char} request, use it. ++This hides a symbol with the same name in the current font. ++ ++@item ++Check the current font. ++ ++@item ++If the symbol has been defined with the @code{fchar} request, use it. ++ ++@item ++Check whether the current font has a font-specific list of special ++fonts; test all fonts in the order of appearance in the last ++@code{fspecial} call if appropriate. ++ ++@item ++If the symbol has been defined with the @code{fschar} request for the ++current font, use it. ++ ++@item ++Check all fonts in the order of appearance in the last @code{special} ++call. ++ ++@item ++If the symbol has been defined with the @code{schar} request, use it. ++ ++@item ++As a last resort, consult all fonts loaded up to now for special fonts ++and check them, starting with the lowest font number. Note that this ++can sometimes lead to surprising results since the @code{fonts} line in ++the @file{DESC} file often contains empty positions, which are filled ++later on. For example, consider the following: ++ ++@Example ++fonts 3 0 0 FOO ++@endExample ++ ++@noindent ++This mounts font @code{foo} at font position@tie{}3. We assume that ++@code{FOO} is a special font, containing glyph @code{foo}, and that no ++font has been loaded yet. The line ++ ++@Example ++.fspecial BAR BAZ ++@endExample ++ ++@noindent ++makes font @code{BAZ} special only if font @code{BAR} is active. We ++further assume that @code{BAZ} is really a special font, i.e., the font ++description file contains the @code{special} keyword, and that it also ++contains glyph @code{foo} with a special shape fitting to font ++@code{BAR}. After executing @code{fspecial}, font @code{BAR} is loaded ++at font position@tie{}1, and @code{BAZ} at position@tie{}2. ++ ++We now switch to a new font @code{XXX}, trying to access glyph ++@code{foo} that is assumed to be missing. There are neither ++font-specific special fonts for @code{XXX} nor any other fonts made ++special with the @code{special} request, so @code{gtroff} starts the ++search for special fonts in the list of already mounted fonts, with ++increasing font positions. Consequently, it finds @code{BAZ} before ++@code{FOO} even for @code{XXX}, which is not the intended behaviour. ++@end itemize ++ ++@xref{Font Files}, and @ref{Special Fonts}, for more details. ++ ++@cindex list of available glyphs (@cite{groff_char(7)} man page) ++@cindex available glyphs, list (@cite{groff_char(7)} man page) ++@cindex glyphs, available, list (@cite{groff_char(7)} man page) ++The list of available symbols is device dependent; see the ++@cite{groff_char(7)} man page for a complete list of all glyphs. For ++example, say ++ ++@Example ++man -Tdvi groff_char > groff_char.dvi ++@endExample ++ ++@noindent ++for a list using the default DVI fonts (not all versions of the ++@code{man} program support the @option{-T} option). If you want to use ++an additional macro package to change the used fonts, @code{groff} must ++be called directly: ++ ++@Example ++groff -Tdvi -mec -man groff_char.7 > groff_char.dvi ++@endExample ++ ++@cindex composite glyph names ++@cindex glyph names, composite ++@cindex groff glyph list (GGL) ++@cindex GGL (groff glyph list) ++@cindex adobe glyph list (AGL) ++@cindex AGL (adobe glyph list) ++Glyph names not listed in groff_char(7) are derived algorithmically, ++using a simplified version of the Adobe Glyph List (AGL) algorithm, which ++is described in ++@uref{http://partners.adobe.com@//public@//developer@//opentype@//index_glyph.html}. ++The (frozen) set of glyph names that can't be derived algorithmically ++is called @dfn{groff glyph list (GGL)}. ++ ++@itemize @bullet ++@item ++A glyph for Unicode character U+@var{XXXX}[@var{X}[@var{X}]], which is ++not a composite character is named ++@code{u@var{XXXX}@r{[}@var{X}@r{[}@var{X}@r{]]}}. @var{X} must be an ++uppercase hexadecimal digit. Examples: @code{u1234}, @code{u008E}, ++@code{u12DB8}. The largest Unicode value is 0x10FFFF. There must be at ++least four @code{X} digits; if necessary, add leading zeroes (after the ++@samp{u}). No zero padding is allowed for character codes greater than ++0xFFFF. Surrogates (i.e., Unicode values greater than 0xFFFF ++represented with character codes from the surrogate area U+D800-U+DFFF) ++are not allowed too. ++ ++@item ++A glyph representing more than a single input character is named ++ ++@display ++@samp{u} @var{component1} @samp{_} @var{component2} @samp{_} @var{component3} @dots{} ++@end display ++ ++@noindent ++Example: @code{u0045_0302_0301}. ++ ++For simplicity, all Unicode characters that are composites must be ++decomposed maximally (this is normalization form@tie{}D in the Unicode ++standard); for example, @code{u00CA_0301} is not a valid glyph name ++since U+00CA (@sc{latin capital letter e with circumflex}) can be ++further decomposed into U+0045 (@sc{latin capital letter e}) and U+0302 ++(@sc{combining circumflex accent}). @code{u0045_0302_0301} is thus the ++glyph name for U+1EBE, @sc{latin capital letter e with circumflex and ++acute}. ++ ++@item ++groff maintains a table to decompose all algorithmically derived glyph ++names that are composites itself. For example, @code{u0100} (@sc{latin ++letter a with macron}) is automatically decomposed into ++@code{u0041_0304}. Additionally, a glyph name of the GGL is preferred ++to an algorithmically derived glyph name; groff also automatically does ++the mapping. Example: The glyph @code{u0045_0302} is mapped to ++@code{^E}. ++ ++@item ++glyph names of the GGL can't be used in composite glyph names; for ++example, @code{^E_u0301} is invalid. ++@end itemize ++ ++@DefescList {\\, @Lparen{}, nm, } ++@DefescItem {\\, @Lbrack{}, name, @Rbrack{}} ++@DefescListEnd {\\, @Lbrack{}, component1 component2 @dots{}, @Rbrack{}} ++Insert a symbol @var{name} (two-character name @var{nm}) or a composite ++glyph with component glyphs @var{component1}, @var{component2}, ++@enddots{} There is no special syntax for one-character names -- the ++natural form @samp{\@var{n}} would collide with escapes.@footnote{Note ++that a one-character symbol is not the same as an input character, i.e., ++the character @code{a} is not the same as @code{\[a]}. By default, ++@code{groff} defines only a single one-character symbol, @code{\[-]}; it ++is usually accessed as @code{\-}. On the other hand, @code{gtroff} has ++the special feature that @code{\[char@var{XXX}]} is the same as the ++input character with character code @var{XXX}. For example, ++@code{\[char97]} is identical to the letter @code{a} if @acronym{ASCII} ++encoding is active.} ++ ++If @var{name} is undefined, a warning of type @samp{char} is generated, ++and the escape is ignored. @xref{Debugging}, for information about ++warnings. ++ ++groff resolves @code{\[...]} with more than a single component as ++follows: ++ ++@itemize @bullet ++@item ++Any component that is found in the GGL is converted to the ++@code{u@var{XXXX}} form. ++ ++@item ++Any component @code{u@var{XXXX}} that is found in the list of ++decomposable glyphs is decomposed. ++ ++@item ++The resulting elements are then concatenated with @samp{_} in between, ++dropping the leading @samp{u} in all elements but the first. ++@end itemize ++ ++No check for the existence of any component (similar to @code{tr} ++request) is done. ++ ++Examples: ++ ++@table @code ++@item \[A ho] ++@samp{A} maps to @code{u0041}, @samp{ho} maps to @code{u02DB}, thus the ++final glyph name would be @code{u0041_02DB}. Note this is not the ++expected result: The ogonek glyph @samp{ho} is a spacing ogonek, but for ++a proper composite a non-spacing ogonek (U+0328) is necessary. Looking ++into the file @file{composite.tmac} one can find @w{@samp{.composite ho ++u0328}}, which changes the mapping of @samp{ho} while a composite glyph ++name is constructed, causing the final glyph name to be ++@code{u0041_0328}. ++ ++@item \[^E u0301] ++@itemx \[^E aa] ++@itemx \[E a^ aa] ++@itemx \[E ^ '] ++@samp{^E} maps to @code{u0045_0302}, thus the final glyph name is ++@code{u0045_0302_0301} in all forms (assuming proper calls of the ++@code{composite} request). ++@end table ++ ++It is not possible to define glyphs with names like @w{@samp{A ho}} ++within a groff font file. This is not really a limitation; instead, you ++have to define @code{u0041_0328}. ++@endDefesc ++ ++@Defesc {\\C, ', xxx, '} ++@cindex named character (@code{\C}) ++@cindex character, named (@code{\C}) ++Typeset the glyph named @var{xxx}.@footnote{@code{\C} is actually a ++misnomer since it accesses an output glyph.} Normally it is more ++convenient to use @code{\[@var{xxx}]}, but @code{\C} has the advantage ++that it is compatible with newer versions of @acronym{AT&T} @code{troff} ++and is available in compatibility mode. ++@endDefesc ++ ++@Defreq {composite, from to} ++@pindex composite.tmac ++Map glyph name @var{from} to glyph name @var{to} if it is used in ++@code{\[...]} with more than one component. See above for examples. ++ ++This mapping is based on glyph names only; no check for the existence of ++either glyph is done. ++ ++A set of default mappings for many accents can be found in the file ++@file{composite.tmac}, which is loaded at start-up. ++@endDefreq ++ ++@Defesc {\\N, ', n, '} ++@cindex numbered glyph (@code{\N}) ++@cindex glyph, numbered (@code{\N}) ++@cindex @code{char} request, used with @code{\N} ++@cindex Unicode ++Typeset the glyph with code@tie{}@var{n} in the current font ++(@code{n}@tie{}is @strong{not} the input character code). The number ++@var{n}@tie{}can be any non-negative decimal integer. Most devices only ++have glyphs with codes between 0 and@tie{}255; the Unicode output device ++uses codes in the range 0--65535. If the current font does not contain ++a glyph with that code, special fonts are @emph{not} searched. The ++@code{\N} escape sequence can be conveniently used in conjunction with ++the @code{char} request: ++ ++@Example ++.char \[phone] \f[ZD]\N'37' ++@endExample ++ ++@noindent ++@pindex DESC ++@cindex unnamed glyphs ++@cindex glyphs, unnamed ++The code of each glyph is given in the fourth column in the font ++description file after the @code{charset} command. It is possible to ++include unnamed glyphs in the font description file by using a name of ++@samp{---}; the @code{\N} escape sequence is the only way to use these. ++ ++No kerning is applied to glyphs accessed with @code{\N}. ++@endDefesc ++ ++Some escape sequences directly map onto special glyphs. ++ ++@Defesc {\\', , , } ++This is a backslash followed by the apostrophe character, ++@acronym{ASCII} character @code{0x27} (@acronym{EBCDIC} character ++@code{0x7D}). The same as @code{\[aa]}, the acute accent. ++@endDefesc ++ ++@Defesc {\\`, , , } ++This is a backslash followed by @acronym{ASCII} character @code{0x60} ++(@acronym{EBCDIC} character @code{0x79} usually). The same as ++@code{\[ga]}, the grave accent. ++@endDefesc ++ ++@Defesc {\\-, , , } ++This is the same as @code{\[-]}, the minus sign in the current font. ++@endDefesc ++ ++@Defesc {\\_, , , } ++This is the same as @code{\[ul]}, the underline character. ++@endDefesc ++ ++@Defreq {cflags, n c1 c2 @dots{}} ++@cindex glyph properties (@code{cflags}) ++@cindex character properties (@code{cflags}) ++@cindex properties of glyphs (@code{cflags}) ++@cindex properties of characters (@code{cflags}) ++Input characters and symbols have certain properties associated with ++it.@footnote{Note that the output glyphs themselves don't have such ++properties. For @code{gtroff}, a glyph is a numbered box with a given ++width, depth, and height, nothing else. All manipulations with the ++@code{cflags} request work on the input level.} These properties can be ++modified with the @code{cflags} request. The first argument is the sum ++of the desired flags and the remaining arguments are the characters or ++symbols to have those properties. It is possible to omit the spaces ++between the characters or symbols. Instead of single characters or ++symbols you can also use character classes (see @ref{Character Classes} ++for more details). ++ ++@table @code ++@item 1 ++@cindex end-of-sentence characters ++@cindex characters, end-of-sentence ++The character ends sentences (initially characters @samp{.?!} have this ++property). ++ ++@item 2 ++@cindex hyphenating characters ++@cindex characters, hyphenation ++Lines can be broken before the character (initially no characters have ++this property). This only works if both the characters before and after ++have non-zero hyphenation codes (as set with the @code{hcode} request). ++Use value@tie{}64 to override this behaviour. ++ ++@item 4 ++@cindex @code{hy} glyph, and @code{cflags} ++@cindex @code{em} glyph, and @code{cflags} ++Lines can be broken after the character (initially the character ++@samp{-} and the symbols @samp{\[hy]} and @samp{\[em]} have this ++property). This only works if both the characters before and after have ++non-zero hyphenation codes (as set with the @code{hcode} request). Use ++value@tie{}64 to override this behaviour. ++ ++@item 8 ++@cindex overlapping characters ++@cindex characters, overlapping ++@cindex @code{ul} glyph, and @code{cflags} ++@cindex @code{rn} glyph, and @code{cflags} ++@cindex @code{ru} glyph, and @code{cflags} ++@cindex @code{radicalex} glyph, and @code{cflags} ++@cindex @code{sqrtex} glyph, and @code{cflags} ++The character overlaps horizontally if used as a horizontal line ++building element. Initially the symbols @samp{\[ul]}, @samp{\[rn]}, ++@samp{\[ru]}, @samp{\[radicalex]}, and @samp{\[sqrtex]} have this ++property. ++ ++@item 16 ++@cindex @code{br} glyph, and @code{cflags} ++The character overlaps vertically if used as vertical line building ++element. Initially symbol @samp{\[br]} has this property. ++ ++@item 32 ++@cindex transparent characters ++@cindex character, transparent ++@cindex @code{"}, at end of sentence ++@cindex @code{'}, at end of sentence ++@cindex @code{)}, at end of sentence ++@cindex @code{]}, at end of sentence ++@cindex @code{*}, at end of sentence ++@cindex @code{dg} glyph, at end of sentence ++@cindex @code{rq} glyph, at end of sentence ++@cindex @code{cq} glyph, at end of sentence ++An end-of-sentence character followed by any number of characters with ++this property is treated as the end of a sentence if followed by a ++newline or two spaces; in other words the character is @dfn{transparent} ++for the purposes of end-of-sentence recognition -- this is the same as ++having a zero space factor in @TeX{} (initially characters @samp{"')]*} ++and the symbols @samp{\[dg]}, @samp{\[rq]}, and @samp{\[cq]} have this ++property). ++ ++@item 64 ++Ignore hyphenation code values of the surrounding characters. Use this ++in combination with values 2 and@tie{}4 (initially no characters have ++this property). For example, if you need an automatic break point after ++the hyphen in number ranges like `3000-5000', insert ++ ++@Example ++.cflags 68 - ++@endExample ++ ++@noindent ++into your document. Note, however, that this can lead to bad layout if ++done without thinking; in most situations, a better solution instead of ++changing the @code{cflags} value is to insert @code{\:} right after the ++hyphen at the places that really need a break point. ++ ++@item 128 ++Prohibit a line break before the character, but allow a line break after ++the character. This works only in combination with flags 256 and 512 ++(see below) and has no effect otherwise. ++ ++@item 256 ++Prohibit a line break after the character, but allow a line break before ++the character. This works only in combination with flags 128 and 512 ++(see below) and has no effect otherwise. ++ ++@item 512 ++Allow line break before or after the character. This works only in ++combination with flags 128 and 256 and has no effect otherwise. ++ ++Contrary to flag values 2 and@tie{}4, the flags 128, 256, and 512 work ++pairwise. If, for example, the left character has value 512, and the ++right character 128, no line break gets inserted. If we use ++value@tie{}6 instead for the left character, a line break after the ++character can't be suppressed since the right neighbour character ++doesn't get examined. ++@end table ++@endDefreq ++ ++@DefreqList {char, g [@Var{string}]} ++@DefreqItemx {fchar, g [@Var{string}]} ++@DefreqItemx {fschar, f g [@Var{string}]} ++@DefreqListEndx {schar, g [@Var{string}]} ++@cindex defining character (@code{char}) ++@cindex defining fallback character (@code{fchar}, @code{fschar}, @code{schar}) ++@cindex character, defining (@code{char}) ++@cindex character, defining fallback (@code{fchar}, @code{fschar}, @code{schar}) ++@cindex fallback character, defining (@code{fchar}, @code{fschar}, @code{schar}) ++@cindex creating new characters (@code{char}) ++@cindex defining symbol (@code{char}) ++@cindex symbol, defining (@code{char}) ++@cindex defining glyph (@code{char}) ++@cindex glyph, defining (@code{char}) ++@cindex escape character, while defining glyph ++@cindex character, escape, while defining glyph ++@cindex @code{tr} request, and glyph definitions ++@cindex @code{cp} request, and glyph definitions ++@cindex @code{rc} request, and glyph definitions ++@cindex @code{lc} request, and glyph definitions ++@cindex @code{\l}, and glyph definitions ++@cindex @code{\L}, and glyph definitions ++@cindex @code{\&}, and glyph definitions ++@cindex @code{\e}, and glyph definitions ++@cindex @code{hcode} request, and glyph definitions ++Define a new glyph@tie{}@var{g} to be @var{string} (which can be ++empty).@footnote{@code{char} is a misnomer since an output glyph is ++defined.} Every time glyph@tie{}@var{g} needs to be printed, ++@var{string} is processed in a temporary environment and the result is ++wrapped up into a single object. Compatibility mode is turned off and ++the escape character is set to @samp{\} while @var{string} is being ++processed. Any emboldening, constant spacing or track kerning is ++applied to this object rather than to individual characters in ++@var{string}. ++ ++A glyph defined by these requests can be used just like a normal glyph ++provided by the output device. In particular, other characters can be ++translated to it with the @code{tr} or @code{trin} requests; it can be ++made the leader character by the @code{lc} request; repeated patterns ++can be drawn with the glyph using the @code{\l} and @code{\L} escape ++sequences; words containing the glyph can be hyphenated correctly if the ++@code{hcode} request is used to give the glyph's symbol a hyphenation ++code. ++ ++There is a special anti-recursion feature: Use of @code{g} within the ++glyph's definition is handled like normal characters and symbols not ++defined with @code{char}. ++ ++Note that the @code{tr} and @code{trin} requests take precedence if ++@code{char} accesses the same symbol. ++ ++@Example ++.tr XY ++X ++ @result{} Y ++.char X Z ++X ++ @result{} Y ++.tr XX ++X ++ @result{} Z ++@endExample ++ ++The @code{fchar} request defines a fallback glyph: @code{gtroff} only ++checks for glyphs defined with @code{fchar} if it cannot find the glyph ++in the current font. @code{gtroff} carries out this test before ++checking special fonts. ++ ++@code{fschar} defines a fallback glyph for font@tie{}@var{f}: ++@code{gtroff} checks for glyphs defined with @code{fschar} after the ++list of fonts declared as font-specific special fonts with the ++@code{fspecial} request, but before the list of fonts declared as global ++special fonts with the @code{special} request. ++ ++Finally, the @code{schar} request defines a global fallback glyph: ++@code{gtroff} checks for glyphs defined with @code{schar} after the list ++of fonts declared as global special fonts with the @code{special} ++request, but before the already mounted special fonts. ++ ++@xref{Using Symbols}, for a detailed description of the glyph searching ++mechanism in @code{gtroff}. ++@endDefreq ++ ++@DefreqList {rchar, c1 c2 @dots{}} ++@DefreqListEndx {rfschar, f c1 c2 @dots{}} ++@cindex removing glyph definition (@code{rchar}, @code{rfschar}) ++@cindex glyph, removing definition (@code{rchar}, @code{rfschar}) ++@cindex fallback glyph, removing definition (@code{rchar}, @code{rfschar}) ++Remove the definitions of glyphs @var{c1}, @var{c2},@tie{}@enddots{} ++This undoes the effect of a @code{char}, @code{fchar}, or @code{schar} ++request. ++ ++It is possible to omit the whitespace between arguments. ++ ++The request @code{rfschar} removes glyph definitions defined with ++@code{fschar} for glyph@tie{}f. ++@endDefreq ++ ++@xref{Special Characters}. ++ ++@c --------------------------------------------------------------------- ++ ++@node Character Classes, Special Fonts, Using Symbols, Fonts and Symbols ++@subsection Character Classes ++@cindex character classes ++@cindex classes, character ++ ++Classes are particularly useful for East Asian languages such as ++Chinese, Japanese, and Korean, where the number of needed characters is ++much larger than in European languages, and where large sets of ++characters share the same properties. ++ ++@Defreq {class, n c1 c2 @dots{}} ++@cindex character class (@code{class}) ++@cindex defining character class (@code{class}) ++@cindex class of characters (@code{class}) ++In @code{groff}, a @dfn{character class} (or simply ``class'') is a set ++of characters, grouped by some user aspect. The @code{class} request ++defines such classes so that other requests can refer to all characters ++belonging to this set with a single class name. Currently, only the ++@code{cflags} request can handle character classes. ++ ++A @code{class} request takes a class name followed by a list of ++entities. In its simplest form, the entities are characters or symbols: ++ ++@Example ++.class [prepunct] , : ; > @} ++@endExample ++ ++Since class and glyph names share the same namespace, it is recommended ++to start and end the class name with @code{[} and @code{]}, ++respectively, to avoid collisions with normal @code{groff} symbols (and ++symbols defined by the user). In particular, the presence of @code{]} ++in the symbol name intentionally prevents the usage of @code{\[...]}, ++thus you must use the @code{\C} escape to access a class with such a ++name. ++ ++@cindex GGL (groff glyph list) ++@cindex groff glyph list (GGL) ++You can also use a special character range notation, consisting of a ++start character or symbol, followed by @samp{-}, and an end character or ++symbol. Internally, @code{gtroff} converts these two symbol names to ++Unicode values (according to the groff glyph gist), which then give the ++start and end value of the range. If that fails, the class definition ++is skipped. ++ ++Finally, classes can be nested, too. ++ ++Here is a more complex example: ++ ++@Example ++.class [prepunctx] \C'[prepunct]' \[u2013]-\[u2016] ++@endExample ++ ++The class @samp{prepunctx} now contains the contents of the class ++@code{prepunct} as defined above (the set @samp{, : ; > @}}), and ++characters in the range between @code{U+2013} and @code{U+2016}. ++ ++If you want to add @samp{-} to a class, it must be the first character ++value in the argument list, otherwise it gets misinterpreted as a range. ++ ++Note that it is not possible to use class names within range ++definitions. ++ ++Typical use of the @code{class} request is to control line-breaking and ++hyphenation rules as defined by the @code{cflags} request. For example, ++to inhibit line breaks before the characters belonging to the ++@code{prepunctx} class, you can write: ++ ++@Example ++.cflags 2 \C'[prepunctx]' ++@endExample ++ ++See the @code{cflags} request in @ref{Using Symbols}, for more details. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Special Fonts, Artificial Fonts, Character Classes, Fonts and Symbols ++@subsection Special Fonts ++@cindex special fonts ++@cindex fonts, special ++ ++Special fonts are those that @code{gtroff} searches when it cannot find ++the requested glyph in the current font. The Symbol font is usually a ++special font. ++ ++@code{gtroff} provides the following two requests to add more special ++fonts. @xref{Using Symbols}, for a detailed description of the glyph ++searching mechanism in @code{gtroff}. ++ ++Usually, only non-TTY devices have special fonts. ++ ++@DefreqList {special, [@Var{s1} @Var{s2} @dots{}]} ++@DefreqListEndx {fspecial, f [@Var{s1} @Var{s2} @dots{}]} ++@kindex fonts ++@pindex DESC ++Use the @code{special} request to define special fonts. Initially, this ++list is empty. ++ ++Use the @code{fspecial} request to designate special fonts only when ++font@tie{}@var{f} is active. Initially, this list is empty. ++ ++Previous calls to @code{special} or @code{fspecial} are overwritten; ++without arguments, the particular list of special fonts is set to empty. ++Special fonts are searched in the order they appear as arguments. ++ ++All fonts that appear in a call to @code{special} or @code{fspecial} ++are loaded. ++ ++@xref{Using Symbols}, for the exact search order of glyphs. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Artificial Fonts, Ligatures and Kerning, Special Fonts, Fonts and Symbols ++@subsection Artificial Fonts ++@cindex artificial fonts ++@cindex fonts, artificial ++ ++There are a number of requests and escapes for artificially creating ++fonts. These are largely vestiges of the days when output devices did ++not have a wide variety of fonts, and when @code{nroff} and @code{troff} ++were separate programs. Most of them are no longer necessary in GNU ++@code{troff}. Nevertheless, they are supported. ++ ++@DefescList {\\H, ', height, '} ++@DefescItem {\\H, ', @t{+}height, '} ++@DefescItem {\\H, ', @t{-}height, '} ++@DefregListEndx {.height} ++@cindex changing the font height (@code{\H}) ++@cindex font height, changing (@code{\H}) ++@cindex height, font, changing (@code{\H}) ++Change (increment, decrement) the height of the current font, but not ++the width. If @var{height} is zero, restore the original height. ++Default scaling indicator is @samp{z}. ++ ++The read-only number register @code{.height} contains the font height as ++set by @code{\H}. ++ ++Currently, only the @option{-Tps} and @option{-Tpdf} devices support ++this feature. ++ ++Note that @code{\H} doesn't produce an input token in @code{gtroff}. As ++a consequence, it can be used in requests like @code{mc} (which expects ++a single character as an argument) to change the font on the fly: ++ ++@Example ++.mc \H'+5z'x\H'0' ++@endExample ++ ++In compatibility mode, @code{gtroff} behaves differently: If an ++increment or decrement is used, it is always taken relative to the ++current point size and not relative to the previously selected font ++height. Thus, ++ ++@Example ++.cp 1 ++\H'+5'test \H'+5'test ++@endExample ++ ++@noindent ++prints the word @samp{test} twice with the same font height (five points ++larger than the current font size). ++@endDefesc ++ ++@DefescList {\\S, ', slant, '} ++@DefregListEndx {.slant} ++@cindex changing the font slant (@code{\S}) ++@cindex font slant, changing (@code{\S}) ++@cindex slant, font, changing (@code{\S}) ++Slant the current font by @var{slant} degrees. Positive values slant to ++the right. Only integer values are possible. ++ ++The read-only number register @code{.slant} contains the font slant as ++set by @code{\S}. ++ ++Currently, only the @option{-Tps} and @option{-Tpdf} devices support ++this feature. ++ ++Note that @code{\S} doesn't produce an input token in @code{gtroff}. As ++a consequence, it can be used in requests like @code{mc} (which expects ++a single character as an argument) to change the font on the fly: ++ ++@Example ++.mc \S'20'x\S'0' ++@endExample ++ ++This request is incorrectly documented in the original @acronym{UNIX} ++troff manual; the slant is always set to an absolute value. ++@endDefesc ++ ++@Defreq {ul, [@Var{lines}]} ++@cindex underlining (@code{ul}) ++The @code{ul} request normally underlines subsequent lines if a TTY ++output device is used. Otherwise, the lines are printed in italics ++(only the term `underlined' is used in the following). The single ++argument is the number of input lines to be underlined; with no ++argument, the next line is underlined. If @var{lines} is zero or ++negative, stop the effects of @code{ul} (if it was active). Requests ++and empty lines do not count for computing the number of underlined ++input lines, even if they produce some output like @code{tl}. Lines ++inserted by macros (e.g.@: invoked by a trap) do count. ++ ++At the beginning of @code{ul}, the current font is stored and the ++underline font is activated. Within the span of a @code{ul} request, it ++is possible to change fonts, but after the last line affected by ++@code{ul} the saved font is restored. ++ ++This number of lines still to be underlined is associated with the ++current environment (@pxref{Environments}). The underline font can be ++changed with the @code{uf} request. ++ ++@c XXX @xref should be changed to grotty ++ ++@c @xref{Troff and Nroff Mode}, for a discussion how underlining is ++@c implemented in for TTY output devices, and which problems can arise. ++ ++The @code{ul} request does not underline spaces. ++@endDefreq ++ ++@Defreq {cu, [@Var{lines}]} ++@cindex continuous underlining (@code{cu}) ++@cindex underlining, continuous (@code{cu}) ++The @code{cu} request is similar to @code{ul} but underlines spaces as ++well (if a TTY output device is used). ++@endDefreq ++ ++@Defreq {uf, font} ++@cindex underline font (@code{uf}) ++@cindex font for underlining (@code{uf}) ++Set the underline font (globally) used by @code{ul} and @code{cu}. By ++default, this is the font at position@tie{}2. @var{font} can be either ++a non-negative font position or the name of a font. ++@endDefreq ++ ++@DefreqList {bd, font [@Var{offset}]} ++@DefreqItem {bd, font1 font2 [@Var{offset}]} ++@DefregListEndx {.b} ++@cindex imitating bold face (@code{bd}) ++@cindex bold face, imitating (@code{bd}) ++Artificially create a bold font by printing each glyph twice, slightly ++offset. ++ ++Two syntax forms are available. ++ ++@itemize @bullet ++@item ++Imitate a bold font unconditionally. The first argument specifies the ++font to embolden, and the second is the number of basic units, minus ++one, by which the two glyphs are offset. If the second argument is ++missing, emboldening is turned off. ++ ++@var{font} can be either a non-negative font position or the name of a ++font. ++ ++@var{offset} is available in the @code{.b} read-only register if a ++special font is active; in the @code{bd} request, its default unit is ++@samp{u}. ++ ++@cindex @code{fspecial} request, and imitating bold ++@kindex special ++@cindex embolding of special fonts ++@cindex special fonts, emboldening ++@item ++Imitate a bold form conditionally. Embolden @var{font1} by @var{offset} ++only if font @var{font2} is the current font. This command can be ++issued repeatedly to set up different emboldening values for different ++current fonts. If the second argument is missing, emboldening is turned ++off for this particular current font. ++ ++This affects special fonts only (either set up with the @code{special} ++command in font files or with the @code{fspecial} request). ++@end itemize ++@endDefreq ++ ++@Defreq {cs, font [@Var{width} [@Var{em-size}]]} ++@cindex constant glyph space mode (@code{cs}) ++@cindex mode for constant glyph space (@code{cs}) ++@cindex glyph, constant space ++@cindex @code{ps} request, and constant glyph space mode ++Switch to and from @dfn{constant glyph space mode}. If activated, the ++width of every glyph is @math{@var{width}/36} ems. The em size is given ++absolutely by @var{em-size}; if this argument is missing, the em value ++is taken from the current font size (as set with the @code{ps} request) ++when the font is effectively in use. Without second and third argument, ++constant glyph space mode is deactivated. ++ ++Default scaling indicator for @var{em-size} is @samp{z}; @var{width} is ++an integer. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Ligatures and Kerning, , Artificial Fonts, Fonts and Symbols ++@subsection Ligatures and Kerning ++@cindex ligatures and kerning ++@cindex kerning and ligatures ++ ++Ligatures are groups of characters that are run together, i.e, producing ++a single glyph. For example, the letters `f' and `i' can form a ++ligature `fi' as in the word `file'. This produces a cleaner look ++(albeit subtle) to the printed output. Usually, ligatures are not ++available in fonts for TTY output devices. ++ ++Most @sc{PostScript} fonts support the fi and fl ligatures. The C/A/T ++typesetter that was the target of @acronym{AT&T} @code{troff} also ++supported `ff', `ffi', and `ffl' ligatures. Advanced typesetters or ++`expert' fonts may include ligatures for `ft' and `ct', although GNU ++@code{troff} does not support these (yet). ++ ++Only the current font is checked for ligatures and kerns; neither ++special fonts nor entities defined with the @code{char} request (and its ++siblings) are taken into account. ++ ++@DefreqList {lg, [@Var{flag}]} ++@DefregListEndx {.lg} ++@cindex activating ligatures (@code{lg}) ++@cindex ligatures, activating (@code{lg}) ++@cindex ligatures enabled register (@code{.lg}) ++Switch the ligature mechanism on or off; if the parameter is non-zero or ++missing, ligatures are enabled, otherwise disabled. Default is on. The ++current ligature mode can be found in the read-only number register ++@code{.lg} (set to 1 or@tie{}2 if ligatures are enabled, ++0@tie{}otherwise). ++ ++Setting the ligature mode to@tie{}2 enables the two-character ligatures ++(fi, fl, and ff) and disables the three-character ligatures (ffi and ++ffl). ++@endDefreq ++ ++@dfn{Pairwise kerning} is another subtle typesetting mechanism that ++modifies the distance between a glyph pair to improve readability. In ++most cases (but not always) the distance is decreased. ++@iftex ++For example, compare the combination of the letters `V' and `A'. With ++kerning, `VA' is printed. Without kerning it appears as `V@w{}A'. ++@end iftex ++Typewriter-like fonts and fonts for terminals where all glyphs have the ++same width don't use kerning. ++ ++@DefreqList {kern, [@Var{flag}]} ++@DefregListEndx {.kern} ++@cindex activating kerning (@code{kern}) ++@cindex kerning, activating (@code{kern}) ++@cindex kerning enabled register (@code{.kern}) ++Switch kerning on or off. If the parameter is non-zero or missing, ++enable pairwise kerning, otherwise disable it. The read-only number ++register @code{.kern} is set to@tie{}1 if pairwise kerning is enabled, ++0@tie{}otherwise. ++ ++@cindex zero width space character (@code{\&}) ++@cindex character, zero width space (@code{\&}) ++@cindex space character, zero width (@code{\&}) ++If the font description file contains pairwise kerning information, ++glyphs from that font are kerned. Kerning between two glyphs can be ++inhibited by placing @code{\&} between them: @samp{V\&A}. ++ ++@xref{Font File Format}. ++@endDefreq ++ ++@cindex track kerning ++@cindex kerning, track ++@dfn{Track kerning} expands or reduces the space between glyphs. This ++can be handy, for example, if you need to squeeze a long word onto a ++single line or spread some text to fill a narrow column. It must be ++used with great care since it is usually considered bad typography if ++the reader notices the effect. ++ ++@Defreq {tkf, f s1 n1 s2 n2} ++@cindex activating track kerning (@code{tkf}) ++@cindex track kerning, activating (@code{tkf}) ++Enable track kerning for font@tie{}@var{f}. If the current font ++is@tie{}@var{f} the width of every glyph is increased by an amount ++between @var{n1} and @var{n2} (@var{n1}, @var{n2} can be negative); if ++the current point size is less than or equal to @var{s1} the width is ++increased by @var{n1}; if it is greater than or equal to @var{s2} the ++width is increased by @var{n2}; if the point size is greater than or ++equal to @var{s1} and less than or equal to @var{s2} the increase in ++width is a linear function of the point size. ++ ++The default scaling indicator is @samp{z} for @var{s1} and @var{s2}, ++@samp{p} for @var{n1} and @var{n2}. ++ ++Note that the track kerning amount is added even to the rightmost glyph ++in a line; for large values it is thus recommended to increase the line ++length by the same amount to compensate it. ++@endDefreq ++ ++Sometimes, when typesetting letters of different fonts, more or less ++space at such boundaries are needed. There are two escapes to help with ++this. ++ ++@Defesc {\\/, , , } ++@cindex italic correction (@code{\/}) ++@cindex correction, italic (@code{\/}) ++@cindex correction between italic and roman glyph (@code{\/}, @code{\,}) ++@cindex roman glyph, correction after italic glyph (@code{\/}) ++@cindex italic glyph, correction before roman glyph (@code{\/}) ++@cindex glyph, italic correction (@code{\/}) ++Increase the width of the preceding glyph so that the spacing between ++that glyph and the following glyph is correct if the following glyph is ++a roman glyph. For example, if an italic@tie{}@code{f} is immediately ++followed by a roman right parenthesis, then in many fonts the top right ++portion of the@tie{}@code{f} overlaps the top left of the right ++parenthesis. Use this escape sequence whenever an italic glyph is ++immediately followed by a roman glyph without any intervening space. ++This small amount of space is also called @dfn{italic correction}. ++ ++@iftex ++@c can't use @Example...@endExample here ++@example ++@group ++\f[I]f\f[R]) ++ @result{} {@it f}@r{)} ++\f[I]f\/\f[R]) ++ @result{} @i{f}@r{)} ++@end group ++@end example ++@end iftex ++@endDefesc ++ ++@Defesc {\\\,, , , } ++@cindex left italic correction (@code{\,}) ++@cindex correction, left italic (@code{\,}) ++@cindex glyph, left italic correction (@code{\,}) ++@cindex roman glyph, correction before italic glyph (@code{\,}) ++@cindex italic glyph, correction after roman glyph (@code{\,}) ++Modify the spacing of the following glyph so that the spacing between ++that glyph and the preceding glyph is correct if the preceding glyph is ++a roman glyph. Use this escape sequence whenever a roman glyph is ++immediately followed by an italic glyph without any intervening space. ++In analogy to above, this space could be called @dfn{left italic ++correction}, but this term isn't used widely. ++ ++@iftex ++@c can't use @Example...@endExample here ++@example ++@group ++q\f[I]f ++ @result{} @r{q}@i{f} ++q\,\f[I]f ++ @result{} @r{q}@math{@ptexcomma}@i{f} ++@end group ++@end example ++@end iftex ++@endDefesc ++ ++@Defesc {\\&, , , } ++Insert a zero-width character, which is invisible. Its intended use is ++to stop interaction of a character with its surrounding. ++ ++@itemize @bullet ++@item ++It prevents the insertion of extra space after an end-of-sentence ++character. ++ ++@Example ++Test. ++Test. ++ @result{} Test. Test. ++Test.\& ++Test. ++ @result{} Test. Test. ++@endExample ++ ++@item ++It prevents interpretation of a control character at the beginning of an ++input line. ++ ++@Example ++.Test ++ @result{} warning: `Test' not defined ++\&.Test ++ @result{} .Test ++@endExample ++ ++@item ++It prevents kerning between two glyphs. ++ ++@iftex ++@c can't use @Example...@endExample here ++@example ++@group ++VA ++ @result{} @r{VA} ++V\&A ++ @result{} @r{V@w{}A} ++@end group ++@end example ++@end iftex ++ ++@item ++It is needed to map an arbitrary character to nothing in the @code{tr} ++request (@pxref{Character Translations}). ++@end itemize ++@endDefesc ++ ++@Defesc {\\), , , } ++This escape is similar to @code{\&} except that it behaves like a ++character declared with the @code{cflags} request to be transparent for ++the purposes of an end-of-sentence character. ++ ++Its main usage is in macro definitions to protect against arguments ++starting with a control character. ++ ++@Example ++.de xxx ++\)\\$1 ++.. ++.de yyy ++\&\\$1 ++.. ++This is a test.\c ++.xxx ' ++This is a test. ++ @result{}This is a test.' This is a test. ++This is a test.\c ++.yyy ' ++This is a test. ++ @result{}This is a test.' This is a test. ++@endExample ++@endDefesc ++ ++ ++@c ===================================================================== ++ ++@node Sizes, Strings, Fonts and Symbols, gtroff Reference ++@section Sizes ++@cindex sizes ++ ++@cindex baseline ++@cindex type size ++@cindex size of type ++@cindex vertical spacing ++@cindex spacing, vertical ++@code{gtroff} uses two dimensions with each line of text, type size and ++vertical spacing. The @dfn{type size} is approximately the height of ++the tallest glyph.@footnote{This is usually the parenthesis. Note that ++in most cases the real dimensions of the glyphs in a font are @emph{not} ++related to its type size! For example, the standard @sc{PostScript} ++font families `Times Roman', `Helvetica', and `Courier' can't be used ++together at 10@dmn{pt}; to get acceptable output, the size of ++`Helvetica' has to be reduced by one point, and the size of `Courier' ++must be increased by one point.} @dfn{Vertical spacing} is the amount ++of space @code{gtroff} allows for a line of text; normally, this is ++about 20%@tie{}larger than the current type size. Ratios smaller than ++this can result in hard-to-read text; larger than this, it spreads the ++text out more vertically (useful for term papers). By default, ++@code{gtroff} uses 10@tie{}point type on 12@tie{}point spacing. ++ ++@cindex leading ++The difference between type size and vertical spacing is known, by ++typesetters, as @dfn{leading} (this is pronounced `ledding'). ++ ++@menu ++* Changing Type Sizes:: ++* Fractional Type Sizes:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Changing Type Sizes, Fractional Type Sizes, Sizes, Sizes ++@subsection Changing Type Sizes ++ ++@DefreqList {ps, [@Var{size}]} ++@DefreqItem {ps, @t{+}@Var{size}} ++@DefreqItem {ps, @t{-}@Var{size}} ++@DefescItemx {\\s, , size, } ++@DefregListEndx {.s} ++@cindex changing type sizes (@code{ps}, @code{\s}) ++@cindex type sizes, changing (@code{ps}, @code{\s}) ++@cindex point sizes, changing (@code{ps}, @code{\s}) ++Use the @code{ps} request or the @code{\s} escape to change (increase, ++decrease) the type size (in points). Specify @var{size} as either an ++absolute point size, or as a relative change from the current size. The ++size@tie{}0 (for both @code{.ps} and @code{\s}), or no argument (for ++@code{.ps} only), goes back to the previous size. ++ ++Default scaling indicator of @code{size} is @samp{z}. If @code{size} is ++negative, it is set to 1@dmn{u}. ++ ++@cindex type size registers (@code{.s}, @code{.ps}) ++@cindex point size registers (@code{.s}, @code{.ps}) ++The read-only number register @code{.s} returns the point size in points ++as a decimal fraction. This is a string. To get the point size in ++scaled points, use the @code{.ps} register instead. ++ ++@code{.s} is associated with the current environment ++(@pxref{Environments}). ++ ++@Example ++snap, snap, ++.ps +2 ++grin, grin, ++.ps +2 ++wink, wink, \s+2nudge, nudge,\s+8 say no more! ++.ps 10 ++@endExample ++ ++The @code{\s} escape may be called in a variety of ways. Much like ++other escapes there must be a way to determine where the argument ends ++and the text begins. Any of the following forms are valid: ++ ++@table @code ++@item \s@var{n} ++Set the point size to @var{n}@tie{}points. @var{n}@tie{}must be either ++0 or in the range 4 to@tie{}39. ++ ++@item \s+@var{n} ++@itemx \s-@var{n} ++Increase or decrease the point size by @var{n}@tie{}points. ++@var{n}@tie{}must be exactly one digit. ++ ++@item \s(@var{nn} ++Set the point size to @var{nn}@tie{}points. @var{nn} must be exactly ++two digits. ++ ++@item \s+(@var{nn} ++@itemx \s-(@var{nn} ++@itemx \s(+@var{nn} ++@itemx \s(-@var{nn} ++Increase or decrease the point size by @var{nn}@tie{}points. @var{nn} ++must be exactly two digits. ++@end table ++ ++Note that @code{\s} doesn't produce an input token in @code{gtroff}. As ++a consequence, it can be used in requests like @code{mc} (which expects ++a single character as an argument) to change the font on the fly: ++ ++@Example ++.mc \s[20]x\s[0] ++@endExample ++ ++@xref{Fractional Type Sizes}, for yet another syntactical form of using ++the @code{\s} escape. ++@endDefreq ++ ++@Defreq {sizes, s1 s2 @dots{} sn [0]} ++Some devices may only have certain permissible sizes, in which case ++@code{gtroff} rounds to the nearest permissible size. The @file{DESC} ++file specifies which sizes are permissible for the device. ++ ++Use the @code{sizes} request to change the permissible sizes for the ++current output device. Arguments are in scaled points; the ++@code{sizescale} line in the @file{DESC} file for the output device ++provides the scaling factor. For example, if the scaling factor is ++1000, then the value 12000 is 12@tie{}points. ++ ++Each argument can be a single point size (such as @samp{12000}), or a ++range of sizes (such as @samp{4000-72000}). You can optionally end the ++list with a zero. ++@endDefreq ++ ++@DefreqList {vs, [@Var{space}]} ++@DefreqItem {vs, @t{+}@Var{space}} ++@DefreqItem {vs, @t{-}@Var{space}} ++@DefregListEndx {.v} ++@cindex changing vertical line spacing (@code{vs}) ++@cindex vertical line spacing, changing (@code{vs}) ++@cindex vertical line spacing register (@code{.v}) ++Change (increase, decrease) the vertical spacing by @var{space}. The ++default scaling indicator is @samp{p}. ++ ++If @code{vs} is called without an argument, the vertical spacing is ++reset to the previous value before the last call to @code{vs}. ++ ++@cindex @code{.V} register, and @code{vs} ++@code{gtroff} creates a warning of type @samp{range} if @var{space} is ++negative; the vertical spacing is then set to smallest positive value, ++the vertical resolution (as given in the @code{.V} register). ++ ++Note that @w{@samp{.vs 0}} isn't saved in a diversion since it doesn't ++result in a vertical motion. You explicitly have to repeat this command ++before inserting the diversion. ++ ++The read-only number register @code{.v} contains the current vertical ++spacing; it is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@cindex vertical line spacing, effective value ++The effective vertical line spacing consists of four components. ++Breaking a line causes the following actions (in the given order). ++ ++@itemize @bullet ++@item ++@cindex extra pre-vertical line space (@code{\x}) ++@cindex line space, extra pre-vertical (@code{\x}) ++Move the current point vertically by the @dfn{extra pre-vertical line ++space}. This is the minimum value of all @code{\x} escapes with a ++negative argument in the current output line. ++ ++@item ++Move the current point vertically by the vertical line spacing as set ++with the @code{vs} request. ++ ++@item ++Output the current line. ++ ++@item ++@cindex extra post-vertical line space (@code{\x}) ++@cindex line space, extra post-vertical (@code{\x}) ++Move the current point vertically by the @dfn{extra post-vertical line ++space}. This is the maximum value of all @code{\x} escapes with a ++positive argument in the line that has just been output. ++ ++@item ++@cindex post-vertical line spacing ++@cindex line spacing, post-vertical (@code{pvs}) ++Move the current point vertically by the @dfn{post-vertical line ++spacing} as set with the @code{pvs} request. ++@end itemize ++ ++@cindex double-spacing (@code{vs}, @code{pvs}) ++It is usually better to use @code{vs} or @code{pvs} instead of @code{ls} ++to produce double-spaced documents: @code{vs} and @code{pvs} have a ++finer granularity for the inserted vertical space compared to @code{ls}; ++furthermore, certain preprocessors assume single-spacing. ++ ++@xref{Manipulating Spacing}, for more details on the @code{\x} escape ++and the @code{ls} request. ++ ++@DefreqList {pvs, [@Var{space}]} ++@DefreqItem {pvs, @t{+}@Var{space}} ++@DefreqItem {pvs, @t{-}@Var{space}} ++@DefregListEndx {.pvs} ++@cindex @code{ls} request, alternative to (@code{pvs}) ++@cindex post-vertical line spacing, changing (@code{pvs}) ++@cindex post-vertical line spacing register (@code{.pvs}) ++Change (increase, decrease) the post-vertical spacing by @var{space}. ++The default scaling indicator is @samp{p}. ++ ++If @code{pvs} is called without an argument, the post-vertical spacing ++is reset to the previous value before the last call to @code{pvs}. ++ ++@code{gtroff} creates a warning of type @samp{range} if @var{space} is ++zero or negative; the vertical spacing is then set to zero. ++ ++The read-only number register @code{.pvs} contains the current ++post-vertical spacing; it is associated with the current environment ++(@pxref{Environments}). ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Fractional Type Sizes, , Changing Type Sizes, Sizes ++@subsection Fractional Type Sizes ++@cindex fractional type sizes ++@cindex fractional point sizes ++@cindex type sizes, fractional ++@cindex point sizes, fractional ++@cindex sizes, fractional ++ ++@cindex @code{s} unit ++@cindex unit, @code{s} ++@cindex @code{z} unit ++@cindex unit, @code{z} ++@cindex @code{ps} request, with fractional type sizes ++@cindex @code{cs} request, with fractional type sizes ++@cindex @code{tkf} request, with fractional type sizes ++@cindex @code{\H}, with fractional type sizes ++@cindex @code{\s}, with fractional type sizes ++A @dfn{scaled point} is equal to @math{1/@var{sizescale}} points, where ++@var{sizescale} is specified in the @file{DESC} file (1@tie{}by ++default). There is a new scale indicator @samp{z}, which has the effect ++of multiplying by @var{sizescale}. Requests and escape sequences in ++@code{gtroff} interpret arguments that represent a point size as being ++in units of scaled points, but they evaluate each such argument using a ++default scale indicator of @samp{z}. Arguments treated in this way are ++the argument to the @code{ps} request, the third argument to the ++@code{cs} request, the second and fourth arguments to the @code{tkf} ++request, the argument to the @code{\H} escape sequence, and those ++variants of the @code{\s} escape sequence that take a numeric expression ++as their argument (see below). ++ ++For example, suppose @var{sizescale} is@tie{}1000; then a scaled point ++is equivalent to a millipoint; the request @w{@samp{.ps 10.25}} is ++equivalent to @w{@samp{.ps 10.25z}} and thus sets the point size to ++10250@tie{}scaled points, which is equal to 10.25@tie{}points. ++ ++@code{gtroff} disallows the use of the @samp{z} scale indicator in ++instances where it would make no sense, such as a numeric expression ++whose default scale indicator was neither @samp{u} nor @samp{z}. ++Similarly it would make no sense to use a scaling indicator other than ++@samp{z} or @samp{u} in a numeric expression whose default scale ++indicator was @samp{z}, and so @code{gtroff} disallows this as well. ++ ++There is also new scale indicator @samp{s}, which multiplies by the ++number of units in a scaled point. So, for example, @samp{\n[.ps]s} is ++equal to @samp{1m}. Be sure not to confuse the @samp{s} and @samp{z} ++scale indicators. ++ ++@Defreg {.ps} ++A read-only number register returning the point size in scaled points. ++ ++@code{.ps} is associated with the current environment ++(@pxref{Environments}). ++@endDefreg ++ ++@DefregList {.psr} ++@DefregListEndx {.sr} ++@cindex last-requested point size registers (@code{.psr}, @code{.sr}) ++@cindex point size registers, last-requested (@code{.psr}, @code{.sr}) ++@cindex @code{.ps} register, in comparison with @code{.psr} ++@cindex @code{.s} register, in comparison with @code{.sr} ++The last-requested point size in scaled points is contained in the ++@code{.psr} read-only number register. The last requested point size in ++points as a decimal fraction can be found in @code{.sr}. This is a ++string-valued read-only number register. ++ ++Note that the requested point sizes are device-independent, whereas the ++values returned by the @code{.ps} and @code{.s} registers are not. For ++example, if a point size of 11@dmn{pt} is requested, and a @code{sizes} ++request (or a @code{sizescale} line in a @file{DESC} file) specifies ++10.95@dmn{pt} instead, this value is actually used. ++ ++Both registers are associated with the current environment ++(@pxref{Environments}). ++@endDefreg ++ ++The @code{\s} escape has the following syntax for working with ++fractional type sizes: ++ ++@table @code ++@item \s[@var{n}] ++@itemx \s'@var{n}' ++Set the point size to @var{n}@tie{}scaled points; @var{n}@tie{}is a ++numeric expression with a default scale indicator of @samp{z}. ++ ++@item \s[+@var{n}] ++@itemx \s[-@var{n}] ++@itemx \s+[@var{n}] ++@itemx \s-[@var{n}] ++@itemx \s'+@var{n}' ++@itemx \s'-@var{n}' ++@itemx \s+'@var{n}' ++@itemx \s-'@var{n}' ++Increase or or decrease the point size by @var{n}@tie{}scaled points; ++@var{n}@tie{}is a numeric expression (which may start with a minus sign) ++with a default scale indicator of @samp{z}. ++@end table ++ ++@xref{Font Files}. ++ ++ ++@c ===================================================================== ++ ++@node Strings, Conditionals and Loops, Sizes, gtroff Reference ++@section Strings ++@cindex strings ++ ++@code{gtroff} has string variables, which are entirely for user ++convenience (i.e.@: there are no built-in strings exept @code{.T}, but ++even this is a read-write string variable). ++ ++Although the following requests can be used to create strings, ++simply using an undefined string will cause it to be defined as empty. ++@xref{Identifiers}. ++ ++@DefreqList {ds, name [@Var{string}]} ++@DefreqItemx {ds1, name [@Var{string}]} ++@DefescItemx {\\*, , n, } ++@DefescItem {\\*, @Lparen{}, nm, } ++@DefescListEnd {\\*, @Lbrack{}, name arg1 arg2 @dots{}, @Rbrack{}} ++@cindex string interpolation (@code{\*}) ++@cindex string expansion (@code{\*}) ++@cindex interpolation of strings (@code{\*}) ++@cindex expansion of strings (@code{\*}) ++@cindex string arguments ++@cindex arguments, of strings ++Define and access a string variable @var{name} (one-character ++name@tie{}@var{n}, two-character name @var{nm}). If @var{name} already ++exists, @code{ds} overwrites the previous definition. Only the syntax ++form using brackets can take arguments that are handled identically to ++macro arguments; the single exception is that a closing bracket as an ++argument must be enclosed in double quotes. @xref{Request and Macro ++Arguments}, and @ref{Parameters}. ++ ++Example: ++ ++@Example ++.ds foo a \\$1 test ++. ++This is \*[foo nice]. ++ @result{} This is a nice test. ++@endExample ++ ++The @code{\*} escape @dfn{interpolates} (expands in-place) a ++previously-defined string variable. To be more precise, the stored ++string is pushed onto the input stack, which is then parsed by ++@code{gtroff}. Similar to number registers, it is possible to nest ++strings, i.e., string variables can be called within string variables. ++ ++If the string named by the @code{\*} escape does not exist, it is ++defined as empty, and a warning of type @samp{mac} is emitted (see ++@ref{Debugging}, for more details). ++ ++@cindex comments, with @code{ds} ++@cindex @code{ds} request, and comments ++@strong{Caution:} Unlike other requests, the second argument to the ++@code{ds} request takes up the entire line including trailing spaces. ++This means that comments on a line with such a request can introduce ++unwanted space into a string. ++ ++@Example ++.ds UX \s-1UNIX\s0\u\s-3tm\s0\d \" UNIX trademark ++@endExample ++ ++@noindent ++Instead the comment should be put on another line or have the comment ++escape adjacent with the end of the string. ++ ++@Example ++.ds UX \s-1UNIX\s0\u\s-3tm\s0\d\" UNIX trademark ++@endExample ++ ++@cindex trailing quotes ++@cindex quotes, trailing ++@cindex leading spaces with @code{ds} ++@cindex spaces with @code{ds} ++@cindex @code{ds} request, and leading spaces ++To produce leading space the string can be started with a double quote. ++No trailing quote is needed; in fact, any trailing quote is included in ++your string. ++ ++@Example ++.ds sign " Yours in a white wine sauce, ++@endExample ++ ++@cindex multi-line strings ++@cindex strings, multi-line ++@cindex newline character, in strings, escaping ++@cindex escaping newline characters, in strings ++Strings are not limited to a single line of text. A string can span ++several lines by escaping the newlines with a backslash. The resulting ++string is stored @emph{without} the newlines. ++ ++@Example ++.ds foo lots and lots \ ++of text are on these \ ++next several lines ++@endExample ++ ++It is not possible to have real newlines in a string. To put a single ++double quote character into a string, use two consecutive double quote ++characters. ++ ++The @code{ds1} request turns off compatibility mode while interpreting a ++string. To be more precise, a @dfn{compatibility save} input token is ++inserted at the beginning of the string, and a @dfn{compatibility ++restore} input token at the end. ++ ++@Example ++.nr xxx 12345 ++.ds aa The value of xxx is \\n[xxx]. ++.ds1 bb The value of xxx ix \\n[xxx]. ++. ++.cp 1 ++. ++\*(aa ++ @result{} warning: number register `[' not defined ++ @result{} The value of xxx is 0xxx]. ++\*(bb ++ @result{} The value of xxx ix 12345. ++@endExample ++ ++@cindex name space, common, of macros, diversions, and strings ++@cindex common name space of macros, diversions, and strings ++@cindex macros, shared name space with strings and diversions ++@cindex strings, shared name space with macros and diversions ++@cindex diversions, shared name space with macros and strings ++Strings, macros, and diversions (and boxes) share the same name space. ++Internally, even the same mechanism is used to store them. This has ++some interesting consequences. For example, it is possible to call a ++macro with string syntax and vice versa. ++ ++@Example ++.de xxx ++a funny test. ++.. ++This is \*[xxx] ++ @result{} This is a funny test. ++ ++.ds yyy a funny test ++This is ++.yyy ++ @result{} This is a funny test. ++@endExample ++ ++In particular, interpolating a string does not hide existing macro ++arguments. Thus in a macro, a more efficient way of doing ++ ++@Example ++.xx \\$@@ ++@endExample ++ ++@noindent ++is ++ ++@Example ++\\*[xx]\\ ++@endExample ++ ++@noindent ++Note that the latter calling syntax doesn't change the value of ++@code{\$0}, which is then inherited from the calling macro. ++ ++Diversions and boxes can be also called with string syntax. ++ ++Another consequence is that you can copy one-line diversions or boxes to ++a string. ++ ++@Example ++.di xxx ++a \fItest\fR ++.br ++.di ++.ds yyy This is \*[xxx]\c ++\*[yyy]. ++ @result{} @r{This is a }@i{test}. ++@endExample ++ ++@noindent ++As the previous example shows, it is possible to store formatted output ++in strings. The @code{\c} escape prevents the insertion of an ++additional blank line in the output. ++ ++Copying diversions longer than a single output line produces unexpected ++results. ++ ++@Example ++.di xxx ++a funny ++.br ++test ++.br ++.di ++.ds yyy This is \*[xxx]\c ++\*[yyy]. ++ @result{} test This is a funny. ++@endExample ++ ++Usually, it is not predictable whether a diversion contains one or more ++output lines, so this mechanism should be avoided. With @acronym{UNIX} ++@code{troff}, this was the only solution to strip off a final newline ++from a diversion. Another disadvantage is that the spaces in the copied ++string are already formatted, making them unstretchable. This can cause ++ugly results. ++ ++@cindex stripping final newline in diversions ++@cindex diversion, stripping final newline ++@cindex final newline, stripping in diversions ++@cindex newline, final, stripping in diversions ++@cindex horizontal space, unformatting ++@cindex space, horizontal, unformatting ++@cindex unformatting horizontal space ++A clean solution to this problem is available in GNU @code{troff}, using ++the requests @code{chop} to remove the final newline of a diversion, and ++@code{unformat} to make the horizontal spaces stretchable again. ++ ++@Example ++.box xxx ++a funny ++.br ++test ++.br ++.box ++.chop xxx ++.unformat xxx ++This is \*[xxx]. ++ @result{} This is a funny test. ++@endExample ++ ++@xref{Gtroff Internals}, for more information. ++@endDefreq ++ ++@DefreqList {as, name [@Var{string}]} ++@DefreqListEndx {as1, name [@Var{string}]} ++@cindex appending to a string (@code{as}) ++@cindex string, appending (@code{as}) ++The @code{as} request is similar to @code{ds} but appends @var{string} ++to the string stored as @var{name} instead of redefining it. If ++@var{name} doesn't exist yet, it is created. ++ ++@Example ++.as sign " with shallots, onions and garlic, ++@endExample ++ ++The @code{as1} request is similar to @code{as}, but compatibility mode ++is switched off while the appended string is interpreted. To be more ++precise, a @dfn{compatibility save} input token is inserted at the ++beginning of the appended string, and a @dfn{compatibility restore} ++input token at the end. ++@endDefreq ++ ++Rudimentary string manipulation routines are given with the next two ++requests. ++ ++@Defreq {substring, str n1 [@Var{n2}]} ++@cindex substring (@code{substring}) ++Replace the string named @var{str} with the substring defined by the ++indices @var{n1} and @var{n2}. The first character in the string has ++index@tie{}0. If @var{n2} is omitted, it is implicitly set to the ++largest valid value (the string length minus one). If the index value ++@var{n1} or @var{n2} is negative, it is counted from the end of the ++string, going backwards: The last character has index@tie{}@minus{}1, ++the character before the last character has index@tie{}@minus{}2, etc. ++ ++@Example ++.ds xxx abcdefgh ++.substring xxx 1 -4 ++\*[xxx] ++ @result{} bcde ++.substring xxx 2 ++\*[xxx] ++ @result{} de ++@endExample ++@endDefreq ++ ++@Defreq {length, reg str} ++@cindex length of a string (@code{length}) ++@cindex string, length of (@code{length}) ++@cindex @code{length} request, and copy-in mode ++@cindex copy-in mode, and @code{length} request ++@cindex mode, copy-in, and @code{length} request ++Compute the number of characters of @var{str} and return it in the ++number register @var{reg}. If @var{reg} doesn't exist, it is created. ++@code{str} is read in copy mode. ++ ++@Example ++.ds xxx abcd\h'3i'efgh ++.length yyy \*[xxx] ++\n[yyy] ++ @result{} 14 ++@endExample ++@endDefreq ++ ++@Defreq {rn, xx yy} ++@cindex renaming request (@code{rn}) ++@cindex request, renaming (@code{rn}) ++@cindex renaming macro (@code{rn}) ++@cindex macro, renaming (@code{rn}) ++@cindex renaming string (@code{rn}) ++@cindex string, renaming (@code{rn}) ++@cindex renaming diversion (@code{rn}) ++@cindex diversion, renaming (@code{rn}) ++Rename the request, macro, diversion, or string @var{xx} to @var{yy}. ++@endDefreq ++ ++@Defreq {rm, xx} ++@cindex removing request (@code{rm}) ++@cindex request, removing (@code{rm}) ++@cindex removing macro (@code{rm}) ++@cindex macro, removing (@code{rm}) ++@cindex removing string (@code{rm}) ++@cindex string, removing (@code{rm}) ++@cindex removing diversion (@code{rm}) ++@cindex diversion, removing (@code{rm}) ++Remove the request, macro, diversion, or string @var{xx}. @code{gtroff} ++treats subsequent invocations as if the object had never been defined. ++@endDefreq ++ ++@anchor{als} ++@Defreq {als, new old} ++@cindex alias, string, creating (@code{als}) ++@cindex alias, macro, creating (@code{als}) ++@cindex alias, diversion, creating (@code{als}) ++@cindex creating alias, for string (@code{als}) ++@cindex creating alias, for macro (@code{als}) ++@cindex creating alias, for diversion (@code{als}) ++@cindex string, creating alias (@code{als}) ++@cindex macro, creating alias (@code{als}) ++@cindex diversion, creating alias (@code{als}) ++Create an alias named @var{new} for the request, string, macro, or ++diversion object named @var{old}. The new name and the old name are ++exactly equivalent (it is similar to a hard rather than a soft link). If ++@var{old} is undefined, @code{gtroff} generates a warning of type ++@samp{mac} and ignores the request. ++ ++To understand how the @code{als} request works it is probably best to ++think of two different pools: one pool for objects (macros, strings, ++etc.), and another one for names. As soon as an object is defined, ++@code{gtroff} adds it to the object pool, adds its name to the name ++pool, and creates a link between them. When @code{als} creates an ++alias, it adds a new name to the name pool that gets linked to the same ++object as the old name. ++ ++Now consider this example. ++ ++@Example ++.de foo ++.. ++. ++.als bar foo ++. ++.de bar ++. foo ++.. ++. ++.bar ++ @result{} input stack limit exceeded ++@endExample ++ ++@noindent ++The definition of macro @code{bar} replaces the old object this name is ++linked to. However, the alias to @code{foo} is still active! In ++other words, @code{foo} is still linked to the same object as ++@code{bar}, and the result of calling @code{bar} is an infinite, ++recursive loop that finally leads to an error. ++ ++@cindex alias, string, removing (@code{rm}) ++@cindex alias, macro, removing (@code{rm}) ++@cindex alias, diversion, removing (@code{rm}) ++@cindex removing alias, for string (@code{rm}) ++@cindex removing alias, for macro (@code{rm}) ++@cindex removing alias, for diversion (@code{rm}) ++@cindex string, removing alias (@code{rm}) ++@cindex macro, removing alias (@code{rm}) ++@cindex diversion, removing alias (@code{rm}) ++To undo an alias, simply call @code{rm} on the aliased name. The object ++itself is not destroyed until there are no more aliases. ++@endDefreq ++ ++@Defreq {chop, xx} ++Remove (chop) the last character from the macro, string, or diversion ++named @var{xx}. This is useful for removing the newline from the end of ++diversions that are to be interpolated as strings. This command can be ++used repeatedly; see @ref{Gtroff Internals}, for details on nodes ++inserted additionally by @code{gtroff}. ++@endDefreq ++ ++@xref{Identifiers}, and @ref{Comments}. ++ ++ ++@c ===================================================================== ++ ++@node Conditionals and Loops, Writing Macros, Strings, gtroff Reference ++@section Conditionals and Loops ++@cindex conditionals and loops ++@cindex loops and conditionals ++ ++@menu ++* Operators in Conditionals:: ++* if-else:: ++* while:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Operators in Conditionals, if-else, Conditionals and Loops, Conditionals and Loops ++@subsection Operators in Conditionals ++ ++@cindex @code{if} request, operators to use with ++@cindex @code{ie} request, operators to use with ++@cindex @code{while} request, operators to use with ++In @code{if}, @code{ie}, and @code{while} requests, in addition to ordinary ++@ref{Expressions}, there are several more operators available: ++ ++@table @code ++@item e ++@itemx o ++True if the current page is even or odd numbered (respectively). ++ ++@item n ++@cindex conditional output for terminal (TTY) ++@cindex TTY, conditional output for ++@cindex terminal, conditional output for ++True if the document is being processed in nroff mode (i.e., the ++@code{.nroff} command has been issued). @xref{Troff and Nroff Mode}. ++ ++@item t ++True if the document is being processed in troff mode (i.e., the ++@code{.troff} command has been issued). @xref{Troff and Nroff Mode}. ++ ++@item v ++Always false. This condition is for compatibility with other ++@code{troff} versions only (identifying a @code{-Tversatec} device). ++ ++@item '@var{xxx}'@var{yyy}' ++True if the output produced by @var{xxx} is equal to the output produced ++by @var{yyy}. Other characters can be used in place of the single ++quotes; the same set of delimiters as for the @code{\D} escape is used ++(@pxref{Escapes}). @code{gtroff} formats @var{xxx} and @var{yyy} in ++separate environments; after the comparison the resulting data is ++discarded. ++ ++@Example ++.ie "|"\fR|\fP" \ ++true ++.el \ ++false ++ @result{} true ++@endExample ++ ++@noindent ++The resulting motions, glyph sizes, and fonts have to ++match,@footnote{The created output nodes must be identical. ++@xref{Gtroff Internals}.} and not the individual motion, size, and font ++requests. In the previous example, @samp{|} and @samp{\fR|\fP} both ++result in a roman @samp{|} glyph with the same point size and at the ++same location on the page, so the strings are equal. If ++@samp{.ft@tie{}I} had been added before the @samp{.ie}, the result would ++be ``false'' because (the first) @samp{|} produces an italic @samp{|} ++rather than a roman one. ++ ++@cindex string comparison ++@cindex comparison of strings ++To compare strings without processing, surround the data with @code{\?}. ++ ++@Example ++.ie "\?|\?"\?\fR|\fP\?" \ ++true ++.el \ ++false ++ @result{} false ++@endExample ++ ++@cindex @code{\?}, and copy-in mode ++@cindex copy-in mode, and @code{\?} ++@cindex mode, copy-in, and @code{\?} ++@noindent ++Since data protected with @code{\?} is read in copy-in mode it is even ++possible to use incomplete input without causing an error. ++ ++@Example ++.ds a \[ ++.ds b \[ ++.ie '\?\*a\?'\?\*b\?' \ ++true ++.el \ ++false ++ @result{} true ++@endExample ++ ++@item r @var{xxx} ++True if there is a number register named @var{xxx}. ++ ++@item d @var{xxx} ++True if there is a string, macro, diversion, or request named @var{xxx}. ++ ++@item m @var{xxx} ++True if there is a color named @var{xxx}. ++ ++@item c @var{g} ++True if there is a glyph @var{g} available@footnote{The name of this ++conditional operator is a misnomer since it tests names of output ++glyphs.}; @var{g} is either an @acronym{ASCII} character or a special ++character (@code{\N'@var{xxx}'}, @code{\(@var{gg}} or ++@code{\[@var{ggg}]}); the condition is also true if @var{g} has been ++defined by the @code{char} request. ++ ++@item F @var{font} ++True if a font named @var{font} exists. @var{font} is handled as if it ++was opened with the @code{ft} request (this is, font translation and ++styles are applied), without actually mounting it. ++ ++This test doesn't load the complete font but only its header to verify ++its validity. ++ ++@item S @var{style} ++True if style @var{style} has been registered. Font translation is ++applied. ++@end table ++ ++Note that these operators can't be combined with other operators like ++@samp{:} or @samp{&}; only a leading @samp{!} (without whitespace ++between the exclamation mark and the operator) can be used to negate the ++result. ++ ++@Example ++.nr xxx 1 ++.ie !r xxx \ ++true ++.el \ ++false ++ @result{} false ++@endExample ++ ++A whitespace after @samp{!} always evaluates to zero (this bizarre ++behaviour is due to compatibility with @acronym{UNIX} @code{troff}). ++ ++@Example ++.nr xxx 1 ++.ie ! r xxx \ ++true ++.el \ ++false ++ @result{} r xxx true ++@endExample ++ ++It is possible to omit the whitespace before the argument to the ++@samp{r}, @samp{d}, and @samp{c} operators. ++ ++@xref{Expressions}. ++ ++@c --------------------------------------------------------------------- ++ ++@node if-else, while, Operators in Conditionals, Conditionals and Loops ++@subsection if-else ++@cindex if-else ++ ++@code{gtroff} has if-then-else constructs like other languages, although ++the formatting can be painful. ++ ++@Defreq {if, expr anything} ++ ++Evaluate the expression @var{expr}, and executes @var{anything} (the ++remainder of the line) if @var{expr} evaluates to a value greater than ++zero (true). @var{anything} is interpreted as though it was on a line ++by itself (except that leading spaces are swallowed). ++@xref{Operators in Conditionals}, for more info. ++ ++@Example ++.nr xxx 1 ++.nr yyy 2 ++.if ((\n[xxx] == 1) & (\n[yyy] == 2)) true ++ @result{} true ++@endExample ++@endDefreq ++ ++@Defreq {nop, anything} ++Executes @var{anything}. This is similar to @code{.if@tie{}1}. ++@endDefreq ++ ++@DefreqList {ie, expr anything} ++@DefreqListEndx {el, anything} ++Use the @code{ie} and @code{el} requests to write an if-then-else. The ++first request is the `if' part and the latter is the `else' part. ++ ++@Example ++.ie n .ls 2 \" double-spacing in nroff ++.el .ls 1 \" single-spacing in troff ++@endExample ++@endDefreq ++ ++@c there is a bug in makeinfo <= 4.1a: you can't have `@{' as an argument ++@c to @deffn ++@c ++@c and in 4.2 you still can't use @{ in macros. ++ ++@c @DefescList {\@{, , , } ++@c @DefescListEnd {\@}, , , } ++@deffn Escape @t{\@{} ++@deffnx Escape @t{\@}} ++@esindex \@{ ++@esindex \@} ++@cindex begin of conditional block (@code{\@{}) ++@cindex end of conditional block (@code{\@}}) ++@cindex conditional block, begin (@code{\@{}) ++@cindex conditional block, end (@code{\@}}) ++@cindex block, conditional, begin (@code{\@{}) ++@cindex block, condititional, end (@code{\@}}) ++In many cases, an if (or if-else) construct needs to execute more than ++one request. This can be done using the escapes @code{\@{} (which must ++start the first line) and @code{\@}} (which must end the last line). ++ ++@Example ++.ie t \@{\ ++. ds lq `` ++. ds rq '' ++.\@} ++.el \@{\ ++. ds lq "" ++. ds rq "" ++.\@} ++@endExample ++@c @endDefesc ++@end deffn ++ ++@xref{Expressions}. ++ ++@c --------------------------------------------------------------------- ++ ++@node while, , if-else, Conditionals and Loops ++@subsection while ++@cindex while ++ ++@code{gtroff} provides a looping construct using the @code{while} ++request, which is used much like the @code{if} (and related) requests. ++ ++@Defreq {while, expr anything} ++Evaluate the expression @var{expr}, and repeatedly execute ++@var{anything} (the remainder of the line) until @var{expr} evaluates ++to@tie{}0. ++ ++@Example ++.nr a 0 1 ++.while (\na < 9) \@{\ ++\n+a, ++.\@} ++\n+a ++ @result{} 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ++@endExample ++ ++Some remarks. ++ ++@cindex @code{de} request, and @code{while} ++@itemize @bullet ++@item ++The body of a @code{while} request is treated like the body of a ++@code{de} request: @code{gtroff} temporarily stores it in a macro that ++is deleted after the loop has been exited. It can considerably slow ++down a macro if the body of the @code{while} request (within the macro) ++is large. Each time the macro is executed, the @code{while} body is ++parsed and stored again as a temporary macro. ++ ++@Example ++.de xxx ++. nr num 10 ++. while (\\n[num] > 0) \@{\ ++. \" many lines of code ++. nr num -1 ++. \@} ++.. ++@endExample ++ ++@cindex recursive macros ++@cindex macros, recursive ++@noindent ++The traditional and ofter better solution (@acronym{UNIX} @code{troff} ++doesn't have the @code{while} request) is to use a recursive macro ++instead that is parsed only once during its definition. ++ ++@Example ++.de yyy ++. if (\\n[num] > 0) \@{\ ++. \" many lines of code ++. nr num -1 ++. yyy ++. \@} ++.. ++. ++.de xxx ++. nr num 10 ++. yyy ++.. ++@endExample ++ ++@noindent ++Note that the number of available recursion levels is set to@tie{}1000 ++(this is a compile-time constant value of @code{gtroff}). ++ ++@item ++The closing brace of a @code{while} body must end a line. ++ ++@Example ++.if 1 \@{\ ++. nr a 0 1 ++. while (\n[a] < 10) \@{\ ++. nop \n+[a] ++.\@}\@} ++ @result{} unbalanced \@{ \@} ++@endExample ++@end itemize ++@endDefreq ++ ++@Defreq {break, } ++@cindex @code{while} request, confusing with @code{br} ++@cindex @code{break} request, in a @code{while} loop ++@cindex @code{continue} request, in a @code{while} loop ++Break out of a @code{while} loop. Be sure not to confuse this with the ++@code{br} request (causing a line break). ++@endDefreq ++ ++@Defreq {continue, } ++Finish the current iteration of a @code{while} loop, immediately ++restarting the next iteration. ++@endDefreq ++ ++@xref{Expressions}. ++ ++ ++@c ===================================================================== ++ ++@node Writing Macros, Page Motions, Conditionals and Loops, gtroff Reference ++@section Writing Macros ++@cindex writing macros ++@cindex macros, writing ++ ++A @dfn{macro} is a collection of text and embedded commands that can be ++invoked multiple times. Use macros to define common operations. ++@xref{Strings}, for a (limited) alternative syntax to call macros. ++ ++Although the following requests can be used to create macros, ++simply using an undefined macro will cause it to be defined as empty. ++@xref{Identifiers}. ++ ++@DefreqList {de, name [@Var{end}]} ++@DefreqItemx {de1, name [@Var{end}]} ++@DefreqItemx {dei, name [@Var{end}]} ++@DefreqListEndx {dei1, name [@Var{end}]} ++Define a new macro named @var{name}. @code{gtroff} copies subsequent ++lines (starting with the next one) into an internal buffer until it ++encounters the line @samp{..} (two dots). If the optional second ++argument to @code{de} is present it is used as the macro closure ++request instead of @samp{..}. ++ ++There can be whitespace after the first dot in the line containing the ++ending token (either @samp{.} or macro @samp{@var{end}}). Don't insert ++a tab character immediately after the @samp{..}, otherwise it isn't ++recognized as the end-of-macro symbol.@footnote{While it is possible to ++define and call a macro @samp{.} with ++ ++@Example ++.de . ++. tm foo ++.. ++. ++.. \" This calls macro `.'! ++@endExample ++ ++@noindent ++you can't use this as the end-of-macro macro: during a macro definition, ++@samp{..} is never handled as a call to @samp{.}, even if you say ++@samp{.de foo .} explicitly.} ++ ++Here a small example macro called @samp{P} that causes a break and ++inserts some vertical space. It could be used to separate paragraphs. ++ ++@Example ++.de P ++. br ++. sp .8v ++.. ++@endExample ++ ++The following example defines a macro within another. Remember that ++expansion must be protected twice; once for reading the macro and once ++for executing. ++ ++@Example ++\# a dummy macro to avoid a warning ++.de end ++.. ++. ++.de foo ++. de bar end ++. nop \f[B]Hallo \\\\$1!\f[] ++. end ++.. ++. ++.foo ++.bar Joe ++ @result{} @b{Hallo Joe!} ++@endExample ++ ++@noindent ++Since @code{\f} has no expansion, it isn't necessary to protect its ++backslash. Had we defined another macro within @code{bar} that takes a ++parameter, eight backslashes would be necessary before @samp{$1}. ++ ++The @code{de1} request turns off compatibility mode while executing the ++macro. On entry, the current compatibility mode is saved and restored ++at exit. ++ ++@Example ++.nr xxx 12345 ++. ++.de aa ++The value of xxx is \\n[xxx]. ++.. ++.de1 bb ++The value of xxx ix \\n[xxx]. ++.. ++. ++.cp 1 ++. ++.aa ++ @result{} warning: number register `[' not defined ++ @result{} The value of xxx is 0xxx]. ++.bb ++ @result{} The value of xxx ix 12345. ++@endExample ++ ++The @code{dei} request defines a macro indirectly. That is, it expands ++strings whose names are @var{name} or @var{end} before performing the ++append. ++ ++This: ++ ++@Example ++.ds xx aa ++.ds yy bb ++.dei xx yy ++@endExample ++ ++@noindent ++is equivalent to: ++ ++@Example ++.de aa bb ++@endExample ++ ++The @code{dei1} request is similar to @code{dei} but with compatibility ++mode switched off during execution of the defined macro. ++ ++If compatibility mode is on, @code{de} (and @code{dei}) behave similar ++to @code{de1} (and @code{dei1}): A `compatibility save' token is ++inserted at the beginning, and a `compatibility restore' token at the ++end, with compatibility mode switched on during execution. @xref{Gtroff ++Internals}, for more information on switching compatibility mode on and ++off in a single document. ++ ++@pindex trace.tmac ++Using @file{trace.tmac}, you can trace calls to @code{de} and ++@code{de1}. ++ ++Note that macro identifiers are shared with identifiers for strings and ++diversions. ++ ++@xref{als,,the description of the @code{als} request}, for possible ++pitfalls if redefining a macro that has been aliased. ++@endDefreq ++ ++@DefreqList {am, name [@Var{end}]} ++@DefreqItemx {am1, name [@Var{end}]} ++@DefreqItemx {ami, name [@Var{end}]} ++@DefreqListEndx {ami1, name [@Var{end}]} ++@cindex appending to a macro (@code{am}) ++@cindex macro, appending (@code{am}) ++Works similarly to @code{de} except it appends onto the macro named ++@var{name}. So, to make the previously defined @samp{P} macro actually ++do indented instead of block paragraphs, add the necessary code to the ++existing macro like this: ++ ++@Example ++.am P ++.ti +5n ++.. ++@endExample ++ ++The @code{am1} request turns off compatibility mode while executing the ++appended macro piece. To be more precise, a @dfn{compatibility save} ++input token is inserted at the beginning of the appended code, and a ++@dfn{compatibility restore} input token at the end. ++ ++The @code{ami} request appends indirectly, meaning that @code{gtroff} ++expands strings whose names are @var{name} or @var{end} before ++performing the append. ++ ++The @code{ami1} request is similar to @code{ami} but compatibility mode ++is switched off during execution of the defined macro. ++ ++@pindex trace.tmac ++Using @file{trace.tmac}, you can trace calls to @code{am} and ++@code{am1}. ++@endDefreq ++ ++@xref{Strings}, for the @code{als} and @code{rn} request to create an ++alias and rename a macro, respectively. ++ ++The @code{de}, @code{am}, @code{di}, @code{da}, @code{ds}, and @code{as} ++requests (together with its variants) only create a new object if the ++name of the macro, diversion or string diversion is currently undefined ++or if it is defined to be a request; normally they modify the value of ++an existing object. ++ ++@Defreq {return, [@Var{anything}]} ++Exit a macro, immediately returning to the caller. ++ ++If called with an argument, exit twice, namely the current macro and the ++macro one level higher. This is used to define a wrapper macro for ++@code{return} in @file{trace.tmac}. ++@endDefreq ++ ++@menu ++* Copy-in Mode:: ++* Parameters:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Copy-in Mode, Parameters, Writing Macros, Writing Macros ++@subsection Copy-in Mode ++@cindex copy mode ++@cindex copy-in mode ++@cindex mode, copy ++@cindex mode, copy-in ++ ++@cindex @code{\n}, when reading text for a macro ++@cindex @code{\$}, when reading text for a macro ++@cindex @code{\*}, when reading text for a macro ++@cindex @code{\\}, when reading text for a macro ++@cindex \@key{RET}, when reading text for a macro ++When @code{gtroff} reads in the text for a macro, string, or diversion, ++it copies the text (including request lines, but excluding escapes) into ++an internal buffer. Escapes are converted into an internal form, except ++for @code{\n}, @code{\$}, @code{\*}, @code{\\} and @code{\@key{RET}}, ++which are evaluated and inserted into the text where the escape was ++located. This is known as @dfn{copy-in} mode or @dfn{copy} mode. ++ ++What this means is that you can specify when these escapes are to be ++evaluated (either at copy-in time or at the time of use) by insulating ++the escapes with an extra backslash. Compare this to the @code{\def} ++and @code{\edef} commands in @TeX{}. ++ ++The following example prints the numbers 20 and@tie{}10: ++ ++@Example ++.nr x 20 ++.de y ++.nr x 10 ++\&\nx ++\&\\nx ++.. ++.y ++@endExample ++ ++@c --------------------------------------------------------------------- ++ ++@node Parameters, , Copy-in Mode, Writing Macros ++@subsection Parameters ++@cindex parameters ++ ++The arguments to a macro or string can be examined using a variety of ++escapes. ++ ++@Defreg {.$} ++@cindex number of arguments register (@code{.$}) ++The number of arguments passed to a macro or string. This is a ++read-only number register. ++ ++Note that the @code{shift} request can change its value. ++@endDefreg ++ ++Any individual argument can be retrieved with one of the following ++escapes: ++ ++@DefescList {\\$, , n, } ++@DefescItem {\\$, @Lparen{}, nn, } ++@DefescListEnd {\\$, @Lbrack{}, nnn, @Rbrack{}} ++@cindex copy-in mode, and macro arguments ++@cindex mode, copy-in, and macro arguments ++@cindex macro, arguments (@code{\$}) ++@cindex arguments, macro (@code{\$}) ++Retrieve the @var{n}@dmn{th}, @var{nn}@dmn{th} or @var{nnn}@dmn{th} ++argument. As usual, the first form only accepts a single number (larger ++than zero), the second a two-digit number (larger or equal to@tie{}10), ++and the third any positive integer value (larger than zero). Macros and ++strings can have an unlimited number of arguments. Note that due to ++copy-in mode, use two backslashes on these in actual use to prevent ++interpolation until the macro is actually invoked. ++@endDefesc ++ ++@Defreq {shift, [@Var{n}]} ++Shift the arguments 1@tie{}position, or as many positions as specified ++by its argument. After executing this request, argument@tie{}@var{i} ++becomes argument @math{@var{i}-@var{n}}; arguments 1 to@tie{}@var{n} are ++no longer available. Shifting by negative amounts is currently ++undefined. ++ ++The register @code{.$} is adjusted accordingly. ++@endDefreq ++ ++@DefescList {\\$*, , , } ++@DefescListEndx {\\$@@, , , } ++In some cases it is convenient to use all of the arguments at once (for ++example, to pass the arguments along to another macro). The @code{\$*} ++escape concatenates all the arguments separated by spaces. A similar ++escape is @code{\$@@}, which concatenates all the arguments with each ++surrounded by double quotes, and separated by spaces. If not in ++compatibility mode, the input level of double quotes is preserved (see ++@ref{Request and Macro Arguments}). ++@endDefesc ++ ++@Defesc {\\$^, , , } ++Handle the parameters of a macro as if they were an argument to the ++@code{ds} or similar requests. ++ ++@Example ++.de foo ++. tm $1=`\\$1' ++. tm $2=`\\$2' ++. tm $*=`\\$*' ++. tm $@@=`\\$@@' ++. tm $^=`\\$^' ++.. ++.foo " This is a "test" ++ @result{} $1=` This is a ' ++ @result{} $2=`test"' ++ @result{} $*=` This is a test"' ++ @result{} $@@=`" This is a " "test""' ++ @result{} $^=`" This is a "test"' ++@endExample ++ ++This escape is useful mainly for macro packages like @file{trace.tmac}, ++which redefines some requests and macros for debugging purposes. ++@endDefesc ++ ++@Defesc {\\$0, , , } ++@cindex macro name register (@code{\$0}) ++@cindex @code{als} request, and @code{\$0} ++The name used to invoke the current macro. The @code{als} request can ++make a macro have more than one name. ++ ++If a macro is called as a string (within another macro), the value of ++@code{\$0} isn't changed. ++ ++@Example ++.de foo ++. tm \\$0 ++.. ++.als foo bar ++. ++@endExample ++@Example ++.de aaa ++. foo ++.. ++.de bbb ++. bar ++.. ++.de ccc ++\\*[foo]\\ ++.. ++.de ddd ++\\*[bar]\\ ++.. ++. ++@endExample ++@Example ++.aaa ++ @result{} foo ++.bbb ++ @result{} bar ++.ccc ++ @result{} ccc ++.ddd ++ @result{} ddd ++@endExample ++@endDefesc ++ ++@xref{Request and Macro Arguments}. ++ ++ ++@c ===================================================================== ++ ++@node Page Motions, Drawing Requests, Writing Macros, gtroff Reference ++@section Page Motions ++@cindex page motions ++@cindex motions, page ++ ++@xref{Manipulating Spacing}, for a discussion of the main request for ++vertical motion, @code{sp}. ++ ++@DefreqList {mk, [@Var{reg}]} ++@DefreqListEndx {rt, [@Var{dist}]} ++@cindex marking vertical page location (@code{mk}) ++@cindex page location, vertical, marking (@code{mk}) ++@cindex location, vertical, page, marking (@code{mk}) ++@cindex vertical page location, marking (@code{mk}) ++@cindex returning to marked vertical page location (@code{rt}) ++@cindex page location, vertical, returning to marked (@code{rt}) ++@cindex location, vertical, page, returning to marked (@code{rt}) ++@cindex vertical page location, returning to marked (@code{rt}) ++The request @code{mk} can be used to mark a location on a page, for ++movement to later. This request takes a register name as an argument in ++which to store the current page location. With no argument it stores ++the location in an internal register. The results of this can be used ++later by the @code{rt} or the @code{sp} request (or the @code{\v} ++escape). ++ ++The @code{rt} request returns @emph{upwards} to the location marked with ++the last @code{mk} request. If used with an argument, return to a ++position which distance from the top of the page is @var{dist} (no ++previous call to @code{mk} is necessary in this case). Default scaling ++indicator is @samp{v}. ++ ++Here a primitive solution for a two-column macro. ++ ++@Example ++.nr column-length 1.5i ++.nr column-gap 4m ++.nr bottom-margin 1m ++. ++@endExample ++@Example ++.de 2c ++. br ++. mk ++. ll \\n[column-length]u ++. wh -\\n[bottom-margin]u 2c-trap ++. nr right-side 0 ++.. ++. ++@endExample ++@Example ++.de 2c-trap ++. ie \\n[right-side] \@{\ ++. nr right-side 0 ++. po -(\\n[column-length]u + \\n[column-gap]u) ++. \" remove trap ++. wh -\\n[bottom-margin]u ++. \@} ++. el \@{\ ++. \" switch to right side ++. nr right-side 1 ++. po +(\\n[column-length]u + \\n[column-gap]u) ++. rt ++. \@} ++.. ++. ++@endExample ++@Example ++.pl 1.5i ++.ll 4i ++This is a small test that shows how the ++rt request works in combination with mk. ++ ++.2c ++Starting here, text is typeset in two columns. ++Note that this implementation isn't robust ++and thus not suited for a real two-column ++macro. ++@endExample ++ ++Result: ++ ++@Example ++This is a small test that shows how the ++rt request works in combination with mk. ++ ++Starting here, isn't robust ++text is typeset and thus not ++in two columns. suited for a ++Note that this real two-column ++implementation macro. ++@endExample ++@endDefreq ++ ++The following escapes give fine control of movements about the page. ++ ++@Defesc {\\v, ', e, '} ++@cindex vertical motion (@code{\v}) ++@cindex motion, vertical (@code{\v}) ++Move vertically, usually from the current location on the page (if no ++absolute position operator @samp{|} is used). The argument@tie{}@var{e} ++specifies the distance to move; positive is downwards and negative ++upwards. The default scaling indicator for this escape is @samp{v}. ++Beware, however, that @code{gtroff} continues text processing at the ++point where the motion ends, so you should always balance motions to ++avoid interference with text processing. ++ ++@code{\v} doesn't trigger a trap. This can be quite useful; for ++example, consider a page bottom trap macro that prints a marker in the ++margin to indicate continuation of a footnote or something similar. ++@endDefesc ++ ++There are some special-case escapes for vertical motion. ++ ++@Defesc {\\r, , , } ++Move upwards@tie{}1@dmn{v}. ++@endDefesc ++ ++@Defesc {\\u, , , } ++Move upwards@tie{}.5@dmn{v}. ++@endDefesc ++ ++@Defesc {\\d, , , } ++Move down@tie{}.5@dmn{v}. ++@endDefesc ++ ++@Defesc {\\h, ', e, '} ++@cindex inserting horizontal space (@code{\h}) ++@cindex horizontal space (@code{\h}) ++@cindex space, horizontal (@code{\h}) ++@cindex horizontal motion (@code{\h}) ++@cindex motion, horizontal (@code{\h}) ++Move horizontally, usually from the current location (if no absolute ++position operator @samp{|} is used). The expression@tie{}@var{e} ++indicates how far to move: positive is rightwards and negative ++leftwards. The default scaling indicator for this escape is @samp{m}. ++ ++This horizontal space is not discarded at the end of a line. To insert ++discardable space of a certain length use the @code{ss} request. ++@endDefesc ++ ++There are a number of special-case escapes for horizontal motion. ++ ++@Defesc {\\@key{SP}, , , } ++@cindex space, unbreakable ++@cindex unbreakable space ++An unbreakable and unpaddable (i.e.@: not expanded during filling) ++space. (Note: This is a backslash followed by a space.) ++@endDefesc ++ ++@Defesc {\\~, , , } ++An unbreakable space that stretches like a normal inter-word space when ++a line is adjusted. ++@endDefesc ++ ++@Defesc {\\|, , , } ++A 1/6@dmn{th} em space. Ignored for TTY output devices (rounded to ++zero). ++ ++However, if there is a glyph defined in the current font file with name ++@code{\|} (note the leading backslash), the width of this glyph is used ++instead (even for TTYs). ++@endDefesc ++ ++@Defesc {\\^, , , } ++A 1/12@dmn{th} em space. Ignored for TTY output devices (rounded to ++zero). ++ ++However, if there is a glyph defined in the current font file with name ++@code{\^} (note the leading backslash), the width of this glyph is used ++instead (even for TTYs). ++@endDefesc ++ ++@Defesc {\\0, , , } ++@cindex space, width of a digit (@code{\0}) ++@cindex digit width space (@code{\0}) ++A space the size of a digit. ++@endDefesc ++ ++The following string sets the @TeX{} logo: ++ ++@Example ++.ds TeX T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X ++@endExample ++ ++@DefescList {\\w, ', text, '} ++@DefregItemx {st} ++@DefregItemx {sb} ++@DefregItemx {rst} ++@DefregItemx {rsb} ++@DefregItemx {ct} ++@DefregItemx {ssc} ++@DefregListEndx {skw} ++@cindex width escape (@code{\w}) ++Return the width of the specified @var{text} in basic units. This ++allows horizontal movement based on the width of some arbitrary text ++(e.g.@: given as an argument to a macro). ++ ++@Example ++The length of the string `abc' is \w'abc'u. ++ @result{} The length of the string `abc' is 72u. ++@endExample ++ ++Font changes may occur in @var{text}, which don't affect current ++settings. ++ ++After use, @code{\w} sets several registers: ++ ++@table @code ++@item st ++@itemx sb ++The highest and lowest point of the baseline, respectively, in ++@var{text}. ++ ++@item rst ++@itemx rsb ++Like the @code{st} and @code{sb} registers, but takes account of the ++heights and depths of glyphs. In other words, this gives the highest ++and lowest point of @var{text}. Values below the baseline are negative. ++ ++@item ct ++Defines the kinds of glyphs occurring in @var{text}: ++ ++@table @asis ++@item 0 ++only short glyphs, no descenders or tall glyphs. ++ ++@item 1 ++at least one descender. ++ ++@item 2 ++at least one tall glyph. ++ ++@item 3 ++at least one each of a descender and a tall glyph. ++@end table ++ ++@item ssc ++The amount of horizontal space (possibly negative) that should be added ++to the last glyph before a subscript. ++ ++@item skw ++How far to right of the center of the last glyph in the @code{\w} ++argument, the center of an accent from a roman font should be placed ++over that glyph. ++@end table ++@endDefesc ++ ++@DefescList {\\k, , p, } ++@DefescItem {\\k, @Lparen{}, ps, } ++@DefescListEnd {\\k, @Lbrack{}, position, @Rbrack{}} ++@cindex saving horizontal input line position (@code{\k}) ++@cindex horizontal input line position, saving (@code{\k}) ++@cindex input line position, horizontal, saving (@code{\k}) ++@cindex position, horizontal input line, saving (@code{\k}) ++@cindex line, input, horizontal position, saving (@code{\k}) ++Store the current horizontal position in the @emph{input} line in number ++register with name @var{position} (one-character name@tie{}@var{p}, ++two-character name @var{ps}). Use this, for example, to return to the ++beginning of a string for highlighting or other decoration. ++@endDefesc ++ ++@Defreg {hp} ++@cindex horizontal input line position register (@code{hp}) ++@cindex input line, horizontal position, register (@code{hp}) ++@cindex position, horizontal, in input line, register (@code{hp}) ++@cindex line, input, horizontal position, register (@code{hp}) ++The current horizontal position at the input line. ++@endDefreg ++ ++@Defreg {.k} ++@cindex horizontal output line position register (@code{.k}) ++@cindex output line, horizontal position, register (@code{.k}) ++@cindex position, horizontal, in output line, register (@code{.k}) ++@cindex line, output, horizontal position, register (@code{.k}) ++A read-only number register containing the current horizontal output ++position (relative to the current indentation). ++@endDefreg ++ ++@Defesc {\\o, ', abc, '} ++@cindex overstriking glyphs (@code{\o}) ++@cindex glyphs, overstriking (@code{\o}) ++Overstrike glyphs @var{a}, @var{b}, @var{c}, @dots{}; the glyphs are ++centered, and the resulting spacing is the largest width of the affected ++glyphs. ++@endDefesc ++ ++@Defesc {\\z, , g, } ++@cindex zero-width printing (@code{\z}, @code{\Z}) ++@cindex printing, zero-width (@code{\z}, @code{\Z}) ++Print glyph @var{g} with zero width, i.e., without spacing. Use this to ++overstrike glyphs left-aligned. ++@endDefesc ++ ++@Defesc {\\Z, ', anything, '} ++@cindex zero-width printing (@code{\z}, @code{\Z}) ++@cindex printing, zero-width (@code{\z}, @code{\Z}) ++Print @var{anything}, then restore the horizontal and vertical position. ++The argument may not contain tabs or leaders. ++ ++The following is an example of a strike-through macro: ++ ++@Example ++.de ST ++.nr ww \w'\\$1' ++\Z@@\v'-.25m'\l'\\n[ww]u'@@\\$1 ++.. ++. ++This is ++.ST "a test" ++an actual emergency! ++@endExample ++@endDefesc ++ ++ ++@c ===================================================================== ++ ++@node Drawing Requests, Traps, Page Motions, gtroff Reference ++@section Drawing Requests ++@cindex drawing requests ++@cindex requests for drawing ++ ++@code{gtroff} provides a number of ways to draw lines and other figures ++on the page. Used in combination with the page motion commands (see ++@ref{Page Motions}, for more info), a wide variety of figures can be ++drawn. However, for complex drawings these operations can be quite ++cumbersome, and it may be wise to use graphic preprocessors like ++@code{gpic} or @code{ggrn}. @xref{gpic}, and @ref{ggrn}, for more ++information. ++ ++All drawing is done via escapes. ++ ++@DefescList {\\l, ', l, '} ++@DefescListEnd {\\l, ', lg, '} ++@cindex drawing horizontal lines (@code{\l}) ++@cindex horizontal line, drawing (@code{\l}) ++@cindex line, horizontal, drawing (@code{\l}) ++Draw a line horizontally. @var{l} is the length of the line to be ++drawn. If it is positive, start the line at the current location and ++draw to the right; its end point is the new current location. Negative ++values are handled differently: The line starts at the current location ++and draws to the left, but the current location doesn't move. ++ ++@var{l} can also be specified absolutely (i.e.@: with a leading ++@samp{|}), which draws back to the beginning of the input line. Default ++scaling indicator is @samp{m}. ++ ++@cindex underscore glyph (@code{\[ru]}) ++@cindex glyph, underscore (@code{\[ru]}) ++@cindex line drawing glyph ++@cindex glyph, for line drawing ++The optional second parameter@tie{}@var{g} is a glyph to draw the line ++with. If this second argument is not specified, @code{gtroff} uses the ++underscore glyph, @code{\[ru]}. ++ ++@cindex zero width space character (@code{\&}) ++@cindex character, zero width space (@code{\&}) ++@cindex space character, zero width (@code{\&}) ++To separate the two arguments (to prevent @code{gtroff} from ++interpreting a drawing glyph as a scaling indicator if the glyph is ++represented by a single character) use @code{\&}. ++ ++Here a small useful example: ++ ++@Example ++.de box ++\[br]\\$*\[br]\l'|0\[rn]'\l'|0\[ul]' ++.. ++@endExample ++ ++@noindent ++Note that this works by outputting a box rule (a vertical line), then ++the text given as an argument and then another box rule. Finally, the ++line drawing escapes both draw from the current location to the ++beginning of the @emph{input} line -- this works because the line length ++is negative, not moving the current point. ++@endDefesc ++ ++@DefescList {\\L, ', l, '} ++@DefescListEnd {\\L, ', lg, '} ++@cindex drawing vertical lines (@code{\L}) ++@cindex vertical line drawing (@code{\L}) ++@cindex line, vertical, drawing (@code{\L}) ++@cindex line drawing glyph ++@cindex glyph for line drawing ++@cindex box rule glyph (@code{\[br]}) ++@cindex glyph, box rule (@code{\[br]}) ++Draw vertical lines. Its parameters are similar to the @code{\l} ++escape, except that the default scaling indicator is @samp{v}. The ++movement is downwards for positive values, and upwards for negative ++values. The default glyph is the box rule glyph, @code{\[br]}. As with ++the vertical motion escapes, text processing blindly continues where the ++line ends. ++ ++@Example ++This is a \L'3v'test. ++@endExample ++ ++@noindent ++Here is the result, produced with @code{grotty}. ++ ++@Example ++This is a ++ | ++ | ++ |test. ++@endExample ++@endDefesc ++ ++@Defesc {\\D, ', command arg @dots{}, '} ++The @code{\D} escape provides a variety of drawing functions. Note that ++on character devices, only vertical and horizontal lines are supported ++within @code{grotty}; other devices may only support a subset of the ++available drawing functions. ++ ++The default scaling indicator for all subcommands of @code{\D} is ++@samp{m} for horizontal distances and @samp{v} for vertical ones. ++Exceptions are @w{@code{\D'f @dots{}'}} and @w{@code{\D't @dots{}'}}, ++which use @code{u} as the default, and @w{@code{\D'F@var{x} @dots{}'}}, ++which arguments are treated similar to the @code{defcolor} request. ++ ++@table @code ++@item \D'l @var{dx} @var{dy}' ++@cindex line, drawing (@w{@code{\D'l @dots{}'}}) ++@cindex drawing a line (@w{@code{\D'l @dots{}'}}) ++Draw a line from the current location to the relative point specified by ++(@var{dx},@var{dy}), where positive values mean down and right, ++respectively. The end point of the line is the new current location. ++ ++The following example is a macro for creating a box around a text ++string; for simplicity, the box margin is taken as a fixed value, ++0.2@dmn{m}. ++ ++@Example ++.de BOX ++. nr @@wd \w'\\$1' ++\h'.2m'\ ++\h'-.2m'\v'(.2m - \\n[rsb]u)'\ ++\D'l 0 -(\\n[rst]u - \\n[rsb]u + .4m)'\ ++\D'l (\\n[@@wd]u + .4m) 0'\ ++\D'l 0 (\\n[rst]u - \\n[rsb]u + .4m)'\ ++\D'l -(\\n[@@wd]u + .4m) 0'\ ++\h'.2m'\v'-(.2m - \\n[rsb]u)'\ ++\\$1\ ++\h'.2m' ++.. ++@endExample ++ ++@noindent ++First, the width of the string is stored in register @code{@@wd}. Then, ++four lines are drawn to form a box, properly offset by the box margin. ++The registers @code{rst} and @code{rsb} are set by the @code{\w} escape, ++containing the largest height and depth of the whole string. ++ ++@item \D'c @var{d}' ++@cindex circle, drawing (@w{@code{\D'c @dots{}'}}) ++@cindex drawing a circle (@w{@code{\D'c @dots{}'}}) ++Draw a circle with a diameter of@tie{}@var{d} with the leftmost point at ++the current position. After drawing, the current location is positioned ++at the rightmost point of the circle. ++ ++@item \D'C @var{d}' ++@cindex circle, solid, drawing (@w{@code{\D'C @dots{}'}}) ++@cindex drawing a solid circle (@w{@code{\D'C @dots{}'}}) ++@cindex solid circle, drawing (@w{@code{\D'C @dots{}'}}) ++Draw a solid circle with the same parameters and behaviour as an ++outlined circle. No outline is drawn. ++ ++@item \D'e @var{x} @var{y}' ++@cindex drawing an ellipse (@w{@code{\D'e @dots{}'}}) ++@cindex ellipse, drawing (@w{@code{\D'e @dots{}'}}) ++Draw an ellipse with a horizontal diameter of @var{x} and a vertical ++diameter of @var{y} with the leftmost point at the current position. ++After drawing, the current location is positioned at the rightmost point ++of the ellipse. ++ ++@item \D'E @var{x} @var{y}' ++@cindex ellipse, solid, drawing (@w{@code{\D'E @dots{}'}}) ++@cindex drawing a solid ellipse (@w{@code{\D'E @dots{}'}}) ++@cindex solid ellipse, drawing (@w{@code{\D'E @dots{}'}}) ++Draw a solid ellipse with the same parameters and behaviour as an ++outlined ellipse. No outline is drawn. ++ ++@item \D'a @var{dx1} @var{dy1} @var{dx2} @var{dy2}' ++@cindex arc, drawing (@w{@code{\D'a @dots{}'}}) ++@cindex drawing an arc (@w{@code{\D'a @dots{}'}}) ++Draw an arc clockwise from the current location through the two ++specified relative locations (@var{dx1},@var{dy1}) and ++(@var{dx2},@var{dy2}). The coordinates of the first point are relative ++to the current position, and the coordinates of the second point are ++relative to the first point. After drawing, the current position is ++moved to the final point of the arc. ++ ++@item \D'~ @var{dx1} @var{dy1} @var{dx2} @var{dy2} @dots{}' ++@cindex drawing a spline (@w{@code{\D'~ @dots{}'}}) ++@cindex spline, drawing (@w{@code{\D'~ @dots{}'}}) ++Draw a spline from the current location to the relative point ++(@var{dx1},@var{dy1}) and then to (@var{dx2},@var{dy2}), and so on. The ++current position is moved to the terminal point of the drawn curve. ++ ++@item \D'f @var{n}' ++@cindex gray shading (@w{@code{\D'f @dots{}'}}) ++@cindex shading filled objects (@w{@code{\D'f @dots{}'}}) ++Set the shade of gray to be used for filling solid objects ++to@tie{}@var{n}; @var{n}@tie{}must be an integer between 0 ++and@tie{}1000, where 0 corresponds solid white and 1000 to solid black, ++and values in between correspond to intermediate shades of gray. This ++applies only to solid circles, solid ellipses, and solid polygons. By ++default, a level of 1000 is used. ++ ++Despite of being silly, the current point is moved horizontally to the ++right by@tie{}@var{n}. ++ ++@cindex @w{@code{\D'f @dots{}'}} and horizontal resolution ++Don't use this command! It has the serious drawback that it is always ++rounded to the next integer multiple of the horizontal resolution (the ++value of the @code{hor} keyword in the @file{DESC} file). Use @code{\M} ++(@pxref{Colors}) or @w{@code{\D'Fg @dots{}'}} instead. ++ ++@item \D'p @var{dx1} @var{dy1} @var{dx2} @var{dy2} @dots{}' ++@cindex drawing a polygon (@w{@code{\D'p @dots{}'}}) ++@cindex polygon, drawing (@w{@code{\D'p @dots{}'}}) ++Draw a polygon from the current location to the relative position ++(@var{dx1},@var{dy1}) and then to (@var{dx2},@var{dy2}) and so on. When ++the specified data points are exhausted, a line is drawn back to the ++starting point. The current position is changed by adding the sum of ++all arguments with odd index to the actual horizontal position and the ++even ones to the vertical position. ++ ++@item \D'P @var{dx1} @var{dy1} @var{dx2} @var{dy2} @dots{}' ++@cindex polygon, solid, drawing (@w{@code{\D'P @dots{}'}}) ++@cindex drawing a solid polygon (@w{@code{\D'P @dots{}'}}) ++@cindex solid polygon, drawing (@w{@code{\D'P @dots{}'}}) ++Draw a solid polygon with the same parameters and behaviour as an ++outlined polygon. No outline is drawn. ++ ++Here a better variant of the box macro to fill the box with some color. ++Note that the box must be drawn before the text since colors in ++@code{gtroff} are not transparent; the filled polygon would hide the ++text completely. ++ ++@Example ++.de BOX ++. nr @@wd \w'\\$1' ++\h'.2m'\ ++\h'-.2m'\v'(.2m - \\n[rsb]u)'\ ++\M[lightcyan]\ ++\D'P 0 -(\\n[rst]u - \\n[rsb]u + .4m) \ ++ (\\n[@@wd]u + .4m) 0 \ ++ 0 (\\n[rst]u - \\n[rsb]u + .4m) \ ++ -(\\n[@@wd]u + .4m) 0'\ ++\h'.2m'\v'-(.2m - \\n[rsb]u)'\ ++\M[]\ ++\\$1\ ++\h'.2m' ++.. ++@endExample ++ ++If you want a filled polygon that has exactly the same size as an ++unfilled one, you must draw both an unfilled and a filled polygon. A ++filled polygon is always smaller than an unfilled one because the latter ++uses straight lines with a given line thickness to connect the polygon's ++corners, while the former simply fills the area defined by the ++coordinates. ++ ++@Example ++\h'1i'\v'1i'\ ++\# increase line thickness ++\Z'\D't 5p''\ ++\# draw unfilled polygon ++\Z'\D'p 3 3 -6 0''\ ++\# draw filled polygon ++\Z'\D'P 3 3 -6 0'' ++@endExample ++ ++@item \D't @var{n}' ++@cindex line thickness (@w{@code{\D't @dots{}'}}) ++@cindex thickness of lines (@w{@code{\D't @dots{}'}}) ++Set the current line thickness to @var{n}@tie{}machine units. A value ++of zero selects the smallest available line thickness. A negative value ++makes the line thickness proportional to the current point size (this is ++the default behaviour of @acronym{AT&T} @code{troff}). ++ ++Despite of being silly, the current point is moved horizontally to the ++right by@tie{}@var{n}. ++ ++@item \D'F@var{scheme} @var{color_components}' ++@cindex unnamed fill colors (@code{\D'F@dots{}'}) ++@cindex fill colors, unnamed (@code{\D'F@dots{}'}) ++@cindex colors, fill, unnamed (@code{\D'F@dots{}'}) ++Change current fill color. @var{scheme} is a single letter denoting the ++color scheme: @samp{r} (rgb), @samp{c} (cmy), @samp{k} (cmyk), @samp{g} ++(gray), or @samp{d} (default color). The color components use exactly ++the same syntax as in the @code{defcolor} request (@pxref{Colors}); the ++command @code{\D'Fd'} doesn't take an argument. ++ ++@emph{No} position changing! ++ ++Examples: ++ ++@Example ++\D'Fg .3' \" same gray as \D'f 700' ++\D'Fr #0000ff' \" blue ++@endExample ++@end table ++@endDefesc ++ ++@xref{Graphics Commands}. ++ ++@Defesc {\\b, ', string, '} ++@cindex pile, glyph (@code{\b}) ++@cindex glyph pile (@code{\b}) ++@cindex stacking glyphs (@code{\b}) ++@dfn{Pile} a sequence of glyphs vertically, and center it vertically on ++the current line. Use it to build large brackets and braces. ++ ++Here an example how to create a large opening brace: ++ ++@Example ++\b'\[lt]\[bv]\[lk]\[bv]\[lb]' ++@endExample ++ ++@cindex @code{\b}, limitations ++@cindex limitations of @code{\b} escape ++The first glyph is on the top, the last glyph in @var{string} is at the ++bottom. Note that @code{gtroff} separates the glyphs vertically by ++1@dmn{m}, and the whole object is centered 0.5@dmn{m} above the current ++baseline; the largest glyph width is used as the width for the whole ++object. This rather unflexible positioning algorithm doesn't work with ++@option{-Tdvi} since the bracket pieces vary in height for this device. ++Instead, use the @code{eqn} preprocessor. ++ ++@xref{Manipulating Spacing}, how to adjust the vertical spacing with the ++@code{\x} escape. ++@endDefesc ++ ++ ++@c ===================================================================== ++ ++@node Traps, Diversions, Drawing Requests, gtroff Reference ++@section Traps ++@cindex traps ++ ++@dfn{Traps} are locations that, when reached, call a specified macro. ++These traps can occur at a given location on the page, at a given ++location in the current diversion, at a blank line, after a certain ++number of input lines, or at the end of input. ++ ++@cindex planting a trap ++@cindex trap, planting ++Setting a trap is also called @dfn{planting}. ++@cindex trap, springing ++@cindex springing a trap ++It is also said that a trap is @dfn{sprung} if the associated macro is ++executed. ++ ++@menu ++* Page Location Traps:: ++* Diversion Traps:: ++* Input Line Traps:: ++* Blank Line Traps:: ++* Leading Spaces Traps:: ++* End-of-input Traps:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Page Location Traps, Diversion Traps, Traps, Traps ++@subsection Page Location Traps ++@cindex page location traps ++@cindex traps, page location ++ ++@dfn{Page location traps} perform an action when @code{gtroff} reaches ++or passes a certain vertical location on the page. Page location traps ++have a variety of purposes, including: ++ ++@itemize ++@item ++setting headers and footers ++ ++@item ++setting body text in multiple columns ++ ++@item ++setting footnotes ++@end itemize ++ ++@DefreqList {vpt, flag} ++@DefregListEndx {.vpt} ++@cindex enabling vertical position traps (@code{vpt}) ++@cindex vertical position traps, enabling (@code{vpt}) ++@cindex vertical position trap enable register (@code{.vpt}) ++Enable vertical position traps if @var{flag} is non-zero, or disables ++them otherwise. Vertical position traps are traps set by the @code{wh} ++or @code{dt} requests. Traps set by the @code{it} request are not ++vertical position traps. The parameter that controls whether vertical ++position traps are enabled is global. Initially vertical position traps ++are enabled. The current setting of this is available in the ++@code{.vpt} read-only number register. ++ ++Note that a page can't be ejected if @code{vpt} is set to zero. ++@endDefreq ++ ++@Defreq {wh, dist [@Var{macro}]} ++Set a page location trap. Non-negative values for @var{dist} set the ++trap relative to the top of the page; negative values set the trap ++relative to the bottom of the page. Default scaling indicator is ++@samp{v}; values of @var{dist} are always rounded to be multiples of the ++vertical resolution (as given in register @code{.V}). ++ ++@var{macro} is the name of the macro to execute when the trap is sprung. ++If @var{macro} is missing, remove the first trap (if any) at @var{dist}. ++ ++@cindex page headers ++@cindex page footers ++@cindex headers ++@cindex footers ++The following is a simple example of how many macro packages set headers ++and footers. ++ ++@Example ++.de hd \" Page header ++' sp .5i ++. tl 'Title''date' ++' sp .3i ++.. ++. ++.de fo \" Page footer ++' sp 1v ++. tl ''%'' ++' bp ++.. ++. ++.wh 0 hd \" trap at top of the page ++.wh -1i fo \" trap one inch from bottom ++@endExample ++ ++A trap at or below the bottom of the page is ignored; it can be made ++active by either moving it up or increasing the page length so that the ++trap is on the page. ++ ++Negative trap values always use the @emph{current} page length; they are ++not converted to an absolute vertical position: ++ ++@Example ++.pl 5i ++.wh -1i xx ++.ptr ++ @result{} xx -240 ++.pl 100i ++.ptr ++ @result{} xx -240 ++@endExample ++ ++It is possible to have more than one trap at the same location; to do ++so, the traps must be defined at different locations, then moved ++together with the @code{ch} request; otherwise the second trap would ++replace the first one. Earlier defined traps hide later defined traps ++if moved to the same position (the many empty lines caused by the ++@code{bp} request are omitted in the following example): ++ ++@Example ++.de a ++. nop a ++.. ++.de b ++. nop b ++.. ++.de c ++. nop c ++.. ++. ++.wh 1i a ++.wh 2i b ++.wh 3i c ++.bp ++ @result{} a b c ++@endExample ++@Example ++.ch b 1i ++.ch c 1i ++.bp ++ @result{} a ++@endExample ++@Example ++.ch a 0.5i ++.bp ++ @result{} a b ++@endExample ++@endDefreq ++ ++@Defreg {.t} ++@cindex distance to next trap register (@code{.t}) ++@cindex trap, distance, register (@code{.t}) ++A read-only number register holding the distance to the next trap. ++ ++If there are no traps between the current position and the bottom of the ++page, it contains the distance to the page bottom. In a diversion, the ++distance to the page bottom is infinite (the returned value is the ++biggest integer that can be represented in @code{groff}) if there are ++no diversion traps. ++@endDefreg ++ ++@Defreq {ch, macro [@Var{dist}]} ++@cindex changing trap location (@code{ch}) ++@cindex trap, changing location (@code{ch}) ++Change the location of a trap. The first argument is the name of the ++macro to be invoked at the trap, and the second argument is the new ++location for the trap (note that the parameters are specified in ++opposite order as in the @code{wh} request). This is useful for ++building up footnotes in a diversion to allow more space at the bottom ++of the page for them. ++ ++Default scaling indicator for @var{dist} is @samp{v}. If @var{dist} is ++missing, the trap is removed. ++ ++@c XXX ++ ++@ignore ++@Example ++... (simplified) footnote example ... ++@endExample ++@end ignore ++@endDefreq ++ ++@Defreg {.ne} ++The read-only number register @code{.ne} contains the amount of space ++that was needed in the last @code{ne} request that caused a trap to be ++sprung. Useful in conjunction with the @code{.trunc} register. ++@xref{Page Control}, for more information. ++ ++Since the @code{.ne} register is only set by traps it doesn't make much ++sense to use it outside of trap macros. ++@endDefreg ++ ++@Defreg {.trunc} ++@cindex @code{ne} request, and the @code{.trunc} register ++@cindex truncated vertical space register (@code{.trunc}) ++A read-only register containing the amount of vertical space truncated ++by the most recently sprung vertical position trap, or, if the trap was ++sprung by an @code{ne} request, minus the amount of vertical motion ++produced by the @code{ne} request. In other words, at the point a trap ++is sprung, it represents the difference of what the vertical position ++would have been but for the trap, and what the vertical position ++actually is. ++ ++Since the @code{.trunc} register is only set by traps it doesn't make ++much sense to use it outside of trap macros. ++@endDefreg ++ ++@Defreg {.pe} ++@cindex @code{bp} request, and traps (@code{.pe}) ++@cindex traps, sprung by @code{bp} request (@code{.pe}) ++@cindex page ejecting register (@code{.pe}) ++A read-only register that is set to@tie{}1 while a page is ejected with ++the @code{bp} request (or by the end of input). ++ ++Outside of traps this register is always zero. In the following ++example, only the second call to@tie{}@code{x} is caused by @code{bp}. ++ ++@Example ++.de x ++\&.pe=\\n[.pe] ++.br ++.. ++.wh 1v x ++.wh 4v x ++A line. ++.br ++Another line. ++.br ++ @result{} A line. ++ .pe=0 ++ Another line. ++ ++ .pe=1 ++@endExample ++@endDefreg ++ ++@cindex diversions, and traps ++@cindex traps, and diversions ++An important fact to consider while designing macros is that diversions ++and traps do not interact normally. For example, if a trap invokes a ++header macro (while outputting a diversion) that tries to change the ++font on the current page, the effect is not visible before the diversion ++has completely been printed (except for input protected with @code{\!} ++or @code{\?}) since the data in the diversion is already formatted. In ++most cases, this is not the expected behaviour. ++ ++@c --------------------------------------------------------------------- ++ ++@node Diversion Traps, Input Line Traps, Page Location Traps, Traps ++@subsection Diversion Traps ++@cindex diversion traps ++@cindex traps, diversion ++ ++@Defreq {dt, [@Var{dist} @Var{macro}]} ++@cindex @code{.t} register, and diversions ++@cindex setting diversion trap (@code{dt}) ++@cindex diversion trap, setting (@code{dt}) ++@cindex trap, diversion, setting (@code{dt}) ++Set a trap @emph{within} a diversion. @var{dist} is the location of the ++trap (identical to the @code{wh} request; default scaling indicator is ++@samp{v}) and @var{macro} is the name of the macro to be invoked. If ++called without arguments, the diversion trap is removed. ++ ++Note that there exists only a single diversion trap. ++ ++The number register @code{.t} still works within diversions. ++@xref{Diversions}, for more information. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Input Line Traps, Blank Line Traps, Diversion Traps, Traps ++@subsection Input Line Traps ++@cindex input line traps ++@cindex traps, input line ++ ++@DefreqList {it, n macro} ++@DefreqListEndx {itc, n macro} ++@cindex setting input line trap (@code{it}) ++@cindex input line trap, setting (@code{it}) ++@cindex trap, input line, setting (@code{it}) ++Set an input line trap. @var{n}@tie{}is the number of lines of input ++that may be read before springing the trap, @var{macro} is the macro to ++be invoked. Request lines are not counted as input lines. ++ ++For example, one possible use is to have a macro that prints the next ++@var{n}@tie{}lines in a bold font. ++ ++@Example ++.de B ++. it \\$1 B-end ++. ft B ++.. ++. ++.de B-end ++. ft R ++.. ++@endExample ++ ++@cindex input line traps and interrupted lines (@code{itc}) ++@cindex interrupted lines and input line traps (@code{itc}) ++@cindex traps, input line, and interrupted lines (@code{itc}) ++@cindex lines, interrupted, and input line traps (@code{itc}) ++The @code{itc} request is identical except that an interrupted text line ++(ending with @code{\c}) is not counted as a separate line. ++ ++Both requests are associated with the current environment ++(@pxref{Environments}); switching to another environment disables the ++current input trap, and going back reactivates it, restoring the number ++of already processed lines. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Blank Line Traps, Leading Spaces Traps, Input Line Traps, Traps ++@subsection Blank Line Traps ++@cindex blank line traps ++@cindex traps, blank line ++ ++@Defreq {blm, macro} ++@cindex blank line macro (@code{blm}) ++Set a blank line trap. @code{gtroff} executes @var{macro} when it ++encounters a blank line in the input file. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node Leading Spaces Traps, End-of-input Traps, Blank Line Traps, Traps ++@subsection Leading Spaces Traps ++@cindex leading spaces traps ++@cindex traps, leading spaces ++ ++@DefreqList {lsm, macro} ++@DefregItemx {lsn} ++@DefregListEndx {lss} ++@cindex leading spaces macro (@code{lsm}) ++Set a leading spaces trap. @code{gtroff} executes @var{macro} when it ++encounters leading spaces in an input line; the implicit line break ++that normally happens in this case is suppressed. A line consisting ++of spaces only, however, is treated as an empty line, possibly subject ++to an empty line macro set with the @code{blm} request. ++ ++Leading spaces are removed from the input line before calling the ++leading spaces macro. The number of removed spaces is stored in ++register @code{lsn}; the horizontal space that would be emitted if ++there was no leading space macro is stored in register @code{lss}. ++Note that @code{lsn} and @code{lss} are available even if no leading ++space macro has been set. ++ ++The first thing a leading space macro sees is a token. However, some ++escapes like @code{\f} or @code{\m} are handled on the fly (see ++@ref{Gtroff Internals}, for a complete list) without creating a token ++at all. Consider that a line starts with two spaces followed by ++@code{\fIfoo}. While skipping the spaces @code{\fI} is handled too so ++that groff's current font is properly set to @samp{I}, but the leading ++space macro only sees @code{foo}, without the preceding @code{\fI}. ++If the macro should see the font escape you have to `protect' it with ++something that creates a token, for example with @code{\&\fIfoo}. ++@endDefreq ++ ++@c --------------------------------------------------------------------- ++ ++@node End-of-input Traps, , Leading Spaces Traps, Traps ++@subsection End-of-input Traps ++@cindex end-of-input traps ++@cindex traps, end-of-input ++ ++@Defreq {em, macro} ++@cindex setting end-of-input trap (@code{em}) ++@cindex end-of-input trap, setting (@code{em}) ++@cindex trap, end-of-input, setting (@code{em}) ++@cindex end-of-input macro (@code{em}) ++@cindex macro, end-of-input (@code{em}) ++Set a trap at the end of input. @var{macro} is executed after the last ++line of the input file has been processed. ++ ++For example, if the document had to have a section at the bottom of the ++last page for someone to approve it, the @code{em} request could be ++used. ++ ++@Example ++.de approval ++\c ++. ne 3v ++. sp (\\n[.t]u - 3v) ++. in +4i ++. lc _ ++. br ++Approved:\t\a ++. sp ++Date:\t\t\a ++.. ++. ++.em approval ++@endExample ++ ++The @code{\c} in the above example needs explanation. For historical ++reasons (and for compatibility with @acronym{AT&T} @code{troff}), the ++end macro exits as soon as it causes a page break and no remaining ++data is in the partially collected line. ++ ++Let us assume that there is no @code{\c} in the above @code{approval} ++macro, and that the page is full and has been ended with, say, a ++@code{br} request. The @code{ne} request now causes the start of a new ++page, which in turn makes @code{troff} exit immediately for the reasons ++just described. In most situations this is not intended. ++ ++To always force processing the whole end macro independently of this ++behaviour it is thus advisable to insert something that starts an ++empty partially filled line (@code{\c}) whenever there is a chance that ++a page break can happen. In the above example, the call of the ++@code{ne} request assures that the remaining code stays on the same ++page, so we have to insert @code{\c} only once. ++ ++The next example shows how to append three lines, then starting a new ++page unconditionally. Since @w{@samp{.ne 1}} doesn't give the desired ++effect -- there is always one line available or we are already at the ++beginning of the next page -- we temporarily increase the page length ++by one line so that we can use @w{@samp{.ne 2}}. ++ ++@Example ++.de EM ++.pl +1v ++\c ++.ne 2 ++line one ++.br ++\c ++.ne 2 ++line two ++.br ++\c ++.ne 2 ++line three ++.br ++.pl -1v ++\c ++'bp ++.. ++.em EM ++@endExample ++ ++Note that this specific feature affects only the first potential page ++break caused by the end macro; further page breaks emitted by the end ++macro are handled normally. ++ ++Another possible use of the @code{em} request is to make @code{gtroff} ++emit a single large page instead of multiple pages. For example, one ++may want to produce a long plain-text file for reading on-screen. The ++idea is to set the page length at the beginning of the document to a ++very large value to hold all the text, and automatically adjust it to ++the exact height of the document after the text has been output. ++ ++@Example ++.de adjust-page-length ++. br ++. pl \\n[nl]u \" \n[nl] holds the current page length ++.. ++. ++.de single-page-mode ++. pl 99999 ++. em adjust-page-length ++.. ++. ++.\" activate the above code ++.single-page-mode ++@endExample ++ ++Since only one end-of-input trap does exist and other macro packages ++may already use it, care must be taken not to break the mechanism. A ++simple solution would be to append the above macro to the macro ++package's end-of-input macro using the @code{.am} request. ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Diversions, Environments, Traps, gtroff Reference ++@section Diversions ++@cindex diversions ++ ++In @code{gtroff} it is possible to @dfn{divert} text into a named ++storage area. Due to the similarity to defining macros it is sometimes ++said to be stored in a macro. This is used for saving text for output ++at a later time, which is useful for keeping blocks of text on the same ++page, footnotes, tables of contents, and indices. ++ ++@cindex top-level diversion ++@cindex diversion, top-level ++For orthogonality it is said that @code{gtroff} is in the @dfn{top-level ++diversion} if no diversion is active (i.e., the data is diverted to the ++output device). ++ ++Although the following requests can be used to create diversions, ++simply using an undefined diversion will cause it to be defined as empty. ++@xref{Identifiers}. ++ ++@DefreqList {di, macro} ++@DefreqListEndx {da, macro} ++@cindex beginning diversion (@code{di}) ++@cindex diversion, beginning (@code{di}) ++@cindex ending diversion (@code{di}) ++@cindex diversion, ending (@code{di}) ++@cindex appending to a diversion (@code{da}) ++@cindex diversion, appending (@code{da}) ++Begin a diversion. Like the @code{de} request, it takes an argument of ++a macro name to divert subsequent text into. The @code{da} macro ++appends to an existing diversion. ++ ++@code{di} or @code{da} without an argument ends the diversion. ++ ++The current partially-filled line is included into the diversion. See ++the @code{box} request below for an example. Note that switching to ++another (empty) environment (with the @code{ev} request) avoids the ++inclusion of the current partially-filled line. ++@endDefreq ++ ++@DefreqList {box, macro} ++@DefreqListEndx {boxa, macro} ++Begin (or append to) a diversion like the @code{di} and @code{da} ++requests. The difference is that @code{box} and @code{boxa} do not ++include a partially-filled line in the diversion. ++ ++Compare this: ++ ++@Example ++Before the box. ++.box xxx ++In the box. ++.br ++.box ++After the box. ++.br ++ @result{} Before the box. After the box. ++.xxx ++ @result{} In the box. ++@endExample ++ ++@noindent ++with this: ++ ++@Example ++Before the diversion. ++.di yyy ++In the diversion. ++.br ++.di ++After the diversion. ++.br ++ @result{} After the diversion. ++.yyy ++ @result{} Before the diversion. In the diversion. ++@endExample ++ ++@code{box} or @code{boxa} without an argument ends the diversion. ++@endDefreq ++ ++@DefregList {.z} ++@DefregListEndx {.d} ++@cindex @code{nl} register, and @code{.d} ++@cindex nested diversions ++@cindex diversion, nested ++@cindex diversion name register (@code{.z}) ++@cindex vertical position in diversion register (@code{.d}) ++@cindex position, vertical, in diversion, register (@code{.d}) ++@cindex diversion, vertical position in, register (@code{.d}) ++Diversions may be nested. The read-only number register @code{.z} ++contains the name of the current diversion (this is a string-valued ++register). The read-only number register @code{.d} contains the current ++vertical place in the diversion. If not in a diversion it is the same ++as register @code{nl}. ++@endDefreg ++ ++@Defreg {.h} ++@cindex high-water mark register (@code{.h}) ++@cindex mark, high-water, register (@code{.h}) ++@cindex position of lowest text line (@code{.h}) ++@cindex text line, position of lowest (@code{.h}) ++The @dfn{high-water mark} on the current page. It corresponds to the ++text baseline of the lowest line on the page. This is a read-only ++register. ++ ++@Example ++.tm .h==\n[.h], nl==\n[nl] ++ @result{} .h==0, nl==-1 ++This is a test. ++.br ++.sp 2 ++.tm .h==\n[.h], nl==\n[nl] ++ @result{} .h==40, nl==120 ++@endExample ++ ++@cindex @code{.h} register, difference to @code{nl} ++@cindex @code{nl} register, difference to @code{.h} ++@noindent ++As can be seen in the previous example, empty lines are not considered ++in the return value of the @code{.h} register. ++@endDefreg ++ ++@DefregList {dn} ++@DefregListEndx {dl} ++@cindex @code{dn} register, and @code{da} (@code{boxa}) ++@cindex @code{dl} register, and @code{da} (@code{boxa}) ++@cindex @code{da} request, and @code{dn} (@code{dl}) ++@cindex @code{boxa} request, and @code{dn} (@code{dl}) ++After completing a diversion, the read-write number registers @code{dn} ++and @code{dl} contain the vertical and horizontal size of the diversion. ++Note that only the just processed lines are counted: For the computation ++of @code{dn} and @code{dl}, the requests @code{da} and @code{boxa} are ++handled as if @code{di} and @code{box} had been used -- lines that have ++been already stored in a macro are not taken into account. ++ ++@Example ++.\" Center text both horizontally & vertically ++. ++.\" Enclose macro definitions in .eo and .ec ++.\" to avoid the doubling of the backslash ++.eo ++.\" macro .(c starts centering mode ++.de (c ++. br ++. ev (c ++. evc 0 ++. in 0 ++. nf ++. di @@c ++.. ++@endExample ++@Example ++.\" macro .)c terminates centering mode ++.de )c ++. br ++. ev ++. di ++. nr @@s (((\n[.t]u - \n[dn]u) / 2u) - 1v) ++. sp \n[@@s]u ++. ce 1000 ++. @@c ++. ce 0 ++. sp \n[@@s]u ++. br ++. fi ++. rr @@s ++. rm @@s ++. rm @@c ++.. ++.\" End of macro definitions, restore escape mechanism ++.ec ++@endExample ++@endDefreg ++ ++@DefescList {\\!, , , } ++@DefescListEndx {\\?, , anything, \\?} ++@cindex transparent output (@code{\!}, @code{\?}) ++@cindex output, transparent (@code{\!}, @code{\?}) ++Prevent requests, macros, and escapes from being interpreted when read ++into a diversion. Both escapes take the given text and ++@dfn{transparently} embed it into the diversion. This is useful for ++macros that shouldn't be invoked until the diverted text is actually ++output. ++ ++The @code{\!} escape transparently embeds text up to and including the ++end of the line. The @code{\?} escape transparently embeds text until ++the next occurrence of the @code{\?} escape. Example: ++ ++@Example ++\?@var{anything}\? ++@endExample ++ ++@cindex @code{\?}, and copy-in mode ++@cindex copy-in mode, and @code{\?} ++@cindex mode, copy-in, and @code{\?} ++@cindex @code{\!}, and copy-in mode ++@cindex copy-in mode, and @code{\!} ++@cindex mode, copy-in, and @code{\!} ++@noindent ++@var{anything} may not contain newlines; use @code{\!} to embed ++newlines in a diversion. The escape sequence @code{\?} is also ++recognized in copy mode and turned into a single internal code; it is ++this code that terminates @var{anything}. Thus the following example ++prints@tie{}4. ++ ++@Example ++.nr x 1 ++.nf ++.di d ++\?\\?\\\\?\\\\\\\\nx\\\\?\\?\? ++.di ++.nr x 2 ++.di e ++.d ++.di ++.nr x 3 ++.di f ++.e ++.di ++.nr x 4 ++.f ++@endExample ++ ++Both escapes read the data in copy mode. ++ ++@cindex @code{\!}, in top-level diversion ++@cindex top-level diversion, and @code{\!} ++@cindex diversion, top-level, and @code{\!} ++If @code{\!} is used in the top-level diversion, its argument is ++directly embedded into the @code{gtroff} intermediate output. This can ++be used for example to control a postprocessor that processes the data ++before it is sent to the device driver. ++ ++@cindex @code{\?}, in top-level diversion ++@cindex top-level diversion, and @code{\?} ++@cindex diversion, top-level, and @code{\?} ++The @code{\?} escape used in the top-level diversion produces no output ++at all; its argument is simply ignored. ++@endDefesc ++ ++@cindex @code{\!}, and @code{output} request ++@cindex @code{output} request, and @code{\!} ++@cindex @code{output} request, and copy-in mode ++@cindex copy-in mode, and @code{output} request ++@cindex mode, copy-in, and @code{output} request ++@Defreq {output, string} ++Emit @var{string} directly to the @code{gtroff} intermediate output ++(subject to copy mode interpretation); this is similar to @code{\!} used ++at the top level. An initial double quote in @var{string} is stripped ++off to allow initial blanks. ++ ++This request can't be used before the first page has started -- if you ++get an error, simply insert @code{.br} before the @code{output} request. ++ ++Without argument, @code{output} is ignored. ++ ++Use with caution! It is normally only needed for mark-up used by a ++postprocessor that does something with the output before sending it to ++the output device, filtering out @var{string} again. ++@endDefreq ++ ++@Defreq {asciify, div} ++@cindex unformatting diversions (@code{asciify}) ++@cindex diversion, unformatting (@code{asciify}) ++@cindex @code{trin} request, and @code{asciify} ++@dfn{Unformat} the diversion specified by @var{div} in such a way that ++@acronym{ASCII} characters, characters translated with the @code{trin} ++request, space characters, and some escape sequences that were formatted ++and diverted are treated like ordinary input characters when the ++diversion is reread. It can be also used for gross hacks; for example, ++the following sets register@tie{}@code{n} to@tie{}1. ++ ++@Example ++.tr @@. ++.di x ++@@nr n 1 ++.br ++.di ++.tr @@@@ ++.asciify x ++.x ++@endExample ++ ++Note that @code{asciify} cannot return all items in a diversion back ++to their source equivalent, nodes such as @code{\N[...]} will still ++remain as nodes, so the result cannot be guaranteed to be a pure string. ++ ++@xref{Copy-in Mode}. ++@endDefreq ++ ++@Defreq {unformat, div} ++Like @code{asciify}, unformat the specified diversion. However, ++@code{unformat} only unformats spaces and tabs between words. ++Unformatted tabs are treated as input tokens, and spaces are stretchable ++again. ++ ++The vertical size of lines is not preserved; glyph information (font, ++font size, space width, etc.)@: is retained. ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Environments, Suppressing output, Diversions, gtroff Reference ++@section Environments ++@cindex environments ++ ++It happens frequently that some text should be printed in a certain ++format regardless of what may be in effect at the time, for example, in ++a trap invoked macro to print headers and footers. To solve this ++@code{gtroff} processes text in @dfn{environments}. An environment ++contains most of the parameters that control text processing. It is ++possible to switch amongst these environments; by default @code{gtroff} ++processes text in environment@tie{}0. The following is the information ++kept in an environment. ++ ++@itemize @bullet ++@item ++font parameters (size, family, style, glyph height and slant, space and ++sentence space size) ++ ++@item ++page parameters (line length, title length, vertical spacing, line ++spacing, indentation, line numbering, centering, right-justifying, ++underlining, hyphenation data) ++ ++@item ++fill and adjust mode ++ ++@item ++tab stops, tab and leader characters, escape character, no-break and ++hyphen indicators, margin character data ++ ++@item ++partially collected lines ++ ++@item ++input traps ++ ++@item ++drawing and fill colours ++@end itemize ++ ++These environments may be given arbitrary names (see @ref{Identifiers}, ++for more info). Old versions of @code{troff} only had environments ++named @samp{0}, @samp{1}, and @samp{2}. ++ ++@DefreqList {ev, [@Var{env}]} ++@DefregListEndx {.ev} ++@cindex switching environments (@code{ev}) ++@cindex environment, switching (@code{ev}) ++@cindex environment number/name register (@code{.ev}) ++Switch to another environment. The argument @var{env} is the name of ++the environment to switch to. With no argument, @code{gtroff} switches ++back to the previous environment. There is no limit on the number of ++named environments; they are created the first time that they are ++referenced. The @code{.ev} read-only register contains the name or ++number of the current environment. This is a string-valued register. ++ ++Note that a call to @code{ev} (with argument) pushes the previously ++active environment onto a stack. If, say, environments @samp{foo}, ++@samp{bar}, and @samp{zap} are called (in that order), the first ++@code{ev} request without parameter switches back to environment ++@samp{bar} (which is popped off the stack), and a second call switches ++back to environment @samp{foo}. ++ ++Here is an example: ++ ++@Example ++.ev footnote-env ++.fam N ++.ps 6 ++.vs 8 ++.ll -.5i ++.ev ++ ++... ++ ++.ev footnote-env ++\(dg Note the large, friendly letters. ++.ev ++@endExample ++@endDefreq ++ ++@Defreq {evc, env} ++@cindex copying environment (@code{evc}) ++@cindex environment, copying (@code{evc}) ++Copy the environment @var{env} into the current environment. ++ ++The following environment data is not copied: ++ ++@itemize @bullet ++@item ++Partially filled lines. ++ ++@item ++The status whether the previous line was interrupted. ++ ++@item ++The number of lines still to center, or to right-justify, or to ++underline (with or without underlined spaces); they are set to zero. ++ ++@item ++The status whether a temporary indentation is active. ++ ++@item ++Input traps and its associated data. ++ ++@item ++Line numbering mode is disabled; it can be reactivated with @w{@samp{.nm +++0}}. ++ ++@item ++The number of consecutive hyphenated lines (set to zero). ++@end itemize ++@endDefreq ++ ++@DefregList {.w} ++@DefregItemx {.cht} ++@DefregItemx {.cdp} ++@DefregListEndx {.csk} ++@cindex environment, dimensions of last glyph (@code{.w}, @code{.cht}, @code{.cdp}, @code{.csk}) ++@cindex width, of last glyph (@code{.w}) ++@cindex height, of last glyph (@code{.cht}) ++@cindex depth, of last glyph (@code{.cdp}) ++@cindex skew, of last glyph (@code{.csk}) ++@cindex last glyph, dimensions (@code{.w}, @code{.cht}, @code{.cdp}, @code{.csk}) ++@cindex glyph, last, dimensions (@code{.w}, @code{.cht}, @code{.cdp}, @code{.csk}) ++The @code{\n[.w]} register contains the width of the last glyph added to ++the current environment. ++ ++The @code{\n[.cht]} register contains the height of the last glyph added ++to the current environment. ++ ++The @code{\n[.cdp]} register contains the depth of the last glyph added ++to the current environment. It is positive for glyphs extending below ++the baseline. ++ ++The @code{\n[.csk]} register contains the @dfn{skew} (how far to the ++right of the glyph's center that @code{gtroff} should place an accent) ++of the last glyph added to the current environment. ++@endDefreg ++ ++@Defreg {.n} ++@cindex environment, previous line length (@code{.n}) ++@cindex line length, previous (@code{.n}) ++@cindex length of previous line (@code{.n}) ++@cindex previous line length (@code{.n}) ++The @code{\n[.n]} register contains the length of the previous output ++line in the current environment. ++@endDefreg ++ ++ ++@c ===================================================================== ++ ++@node Suppressing output, Colors, Environments, gtroff Reference ++@section Suppressing output ++ ++@Defesc {\\O, , num, } ++@cindex suppressing output (@code{\O}) ++@cindex output, suppressing (@code{\O}) ++Disable or enable output depending on the value of @var{num}: ++ ++@table @samp ++@item \O0 ++Disable any glyphs from being emitted to the device driver, provided ++that the escape occurs at the outer level (see @code{\O[3]} and ++@code{\O[4]}). Motion is not suppressed so effectively @code{\O[0]} ++means @emph{pen up}. ++ ++@item \O1 ++Enable output of glyphs, provided that the escape occurs at the outer ++level. ++@end table ++ ++@vindex opminx ++@vindex opminy ++@vindex opmaxx ++@vindex opmaxy ++@code{\O0} and @code{\O1} also reset the four registers @samp{opminx}, ++@samp{opminy}, @samp{opmaxx}, and @samp{opmaxy} to @minus{}1. ++@xref{Register Index}. These four registers mark the top left and ++bottom right hand corners of a box that encompasses all written glyphs. ++ ++For example the input text: ++ ++@Example ++Hello \O[0]world \O[1]this is a test. ++@endExample ++ ++@noindent ++produces the following output: ++ ++@Example ++Hello this is a test. ++@endExample ++ ++@table @samp ++@item \O2 ++Provided that the escape occurs at the outer level, enable output of ++glyphs and also write out to @code{stderr} the page number and four ++registers encompassing the glyphs previously written since the last call ++to @code{\O}. ++ ++@item \O3 ++Begin a nesting level. At start-up, @code{gtroff} is at outer level. ++The current level is contained within the read-only register @code{.O}. ++@xref{Built-in Registers}. ++ ++@item \O4 ++End a nesting level. The current level is contained within the ++read-only register @code{.O}. @xref{Built-in Registers}. ++ ++@item \O[5@var{P}@var{filename}] ++This escape is @code{grohtml} specific. Provided that this escape ++occurs at the outer nesting level write the @code{filename} to ++@code{stderr}. The position of the image, @var{P}, must be specified ++and must be one of @code{l}, @code{r}, @code{c}, or@tie{}@code{i} (left, ++right, centered, inline). @var{filename} is associated with the ++production of the next inline image. ++@end table ++@endDefesc ++ ++ ++@c ===================================================================== ++ ++@node Colors, I/O, Suppressing output, gtroff Reference ++@section Colors ++@cindex colors ++ ++@DefreqList {color, [@Var{n}]} ++@DefregListEndx {.color} ++If @var{n} is missing or non-zero, activate colors (this is the ++default); otherwise, turn it off. ++ ++The read-only number register @code{.color} is@tie{}1 if colors are ++active, 0@tie{}otherwise. ++ ++Internally, @code{color} sets a global flag; it does not produce a ++token. Similar to the @code{cp} request, you should use it at the ++beginning of your document to control color output. ++ ++Colors can be also turned off with the @option{-c} command line option. ++@endDefreq ++ ++@Defreq {defcolor, ident scheme color_components} ++Define color with name @var{ident}. @var{scheme} can be one of the ++following values: @code{rgb} (three components), @code{cmy} (three ++components), @code{cmyk} (four components), and @code{gray} or ++@code{grey} (one component). ++ ++@cindex default color ++@cindex color, default ++Color components can be given either as a hexadecimal string or as ++positive decimal integers in the range 0--65535. A hexadecimal string ++contains all color components concatenated. It must start with either ++@code{#} or @code{##}; the former specifies hex values in the range ++0--255 (which are internally multiplied by@tie{}257), the latter in the ++range 0--65535. Examples: @code{#FFC0CB} (pink), @code{##ffff0000ffff} ++(magenta). The default color name @c{default} can't be redefined; its ++value is device-specific (usually black). It is possible that the ++default color for @code{\m} and @code{\M} is not identical. ++ ++@cindex @code{f} unit, and colors ++@cindex unit, @code{f}, and colors ++A new scaling indicator@tie{}@code{f} has been introduced, which ++multiplies its value by 65536; this makes it convenient to specify color ++components as fractions in the range 0 to@tie{}1 (1f equals 65536u). ++Example: ++ ++@Example ++.defcolor darkgreen rgb 0.1f 0.5f 0.2f ++@endExample ++ ++Note that @code{f} is the default scaling indicator for the ++@code{defcolor} request, thus the above statement is equivalent to ++ ++@Example ++.defcolor darkgreen rgb 0.1 0.5 0.2 ++@endExample ++@endDefreq ++ ++@DefreqList {gcolor, [@Var{color}]} ++@DefescItemx {\\m, , c, } ++@DefescItem {\\m, @Lparen{}, co, } ++@DefescItem {\\m, @Lbrack{}, color, @Rbrack{}} ++@DefregListEndx {.m} ++Set (glyph) drawing color. The following examples show how to turn the ++next four words red. ++ ++@Example ++.gcolor red ++these are in red ++.gcolor ++and these words are in black. ++@endExample ++ ++@Example ++\m[red]these are in red\m[] and these words are in black. ++@endExample ++ ++The escape @code{\m[]} returns to the previous color, as does a call to ++@code{gcolor} without an argument. ++ ++@cindex drawing color name register (@code{.m}) ++@cindex name, drawing color, register (@code{.m}) ++@cindex color name, drawing, register (@code{.m}) ++The name of the current drawing color is available in the read-only, ++string-valued number register @samp{.m}. ++ ++The drawing color is associated with the current environment ++(@pxref{Environments}). ++ ++Note that @code{\m} doesn't produce an input token in @code{gtroff}. As ++a consequence, it can be used in requests like @code{mc} (which expects ++a single character as an argument) to change the color on the fly: ++ ++@Example ++.mc \m[red]x\m[] ++@endExample ++@endDefesc ++ ++@DefreqList {fcolor, [@Var{color}]} ++@DefescItemx {\\M, , c, } ++@DefescItem {\\M, @Lparen{}, co, } ++@DefescItem {\\M, @Lbrack{}, color, @Rbrack{}} ++@DefregListEndx {.M} ++Set fill (background) color for filled objects drawn with the ++@code{\D'@dots{}'} commands. ++ ++A red ellipse can be created with the following code: ++ ++@Example ++\M[red]\h'0.5i'\D'E 2i 1i'\M[] ++@endExample ++ ++The escape @code{\M[]} returns to the previous fill color, as does a ++call to @code{fcolor} without an argument. ++ ++@cindex background color name register (@code{.M}) ++@cindex name, background color, register (@code{.M}) ++@cindex color name, background, register (@code{.M}) ++@cindex fill color name register (@code{.M}) ++@cindex name, fill color, register (@code{.M}) ++@cindex color name, fill, register (@code{.M}) ++The name of the current fill (background) color is available in the ++read-only, string-valued number register @samp{.M}. ++ ++The fill color is associated with the current environment ++(@pxref{Environments}). ++ ++Note that @code{\M} doesn't produce an input token in @code{gtroff}. ++@endDefesc ++ ++ ++@c ===================================================================== ++ ++@node I/O, Postprocessor Access, Colors, gtroff Reference ++@section I/O ++@cindex i/o ++@cindex input and output requests ++@cindex requests for input and output ++@cindex output and input requests ++ ++@code{gtroff} has several requests for including files: ++ ++@Defreq {so, file} ++@cindex including a file (@code{so}) ++@cindex file, inclusion (@code{so}) ++Read in the specified @var{file} and includes it in place of the ++@code{so} request. This is quite useful for large documents, e.g.@: ++keeping each chapter in a separate file. @xref{gsoelim}, for more ++information. ++ ++Since @code{gtroff} replaces the @code{so} request with the contents of ++@code{file}, it makes a difference whether the data is terminated with a ++newline or not: Assuming that file @file{xxx} contains the word ++@samp{foo} without a final newline, this ++ ++@Example ++This is ++.so xxx ++bar ++@endExample ++ ++@noindent ++yields @samp{This is foobar}. ++ ++The search path for @var{file} can be controlled with the @option{-I} ++command line option. ++@endDefreq ++ ++@Defreq {pso, command} ++Read the standard output from the specified @var{command} and includes ++it in place of the @code{pso} request. ++ ++@cindex safer mode ++@cindex mode, safer ++@cindex unsafe mode ++@cindex mode, unsafe ++This request causes an error if used in safer mode (which is the ++default). Use @code{groff}'s or @code{troff}'s @option{-U} option to ++activate unsafe mode. ++ ++The comment regarding a final newline for the @code{so} request is valid ++for @code{pso} also. ++@endDefreq ++ ++@Defreq {mso, file} ++Identical to the @code{so} request except that @code{gtroff} searches ++for the specified @var{file} in the same directories as macro files for ++the the @option{-m} command line option. If the file name to be ++included has the form @file{@var{name}.tmac} and it isn't found, ++@code{mso} tries to include @file{tmac.@var{name}} and vice versa. ++If the file does not exist, a warning of type @samp{file} is emitted. ++@xref{Debugging}, for information about warnings. ++@endDefreq ++ ++@DefreqList {trf, file} ++@DefreqListEndx {cf, file} ++@cindex transparent output (@code{cf}, @code{trf}) ++@cindex output, transparent (@code{cf}, @code{trf}) ++@cindex @code{cf} request, and copy-in mode ++@cindex copy-in mode, and @code{cf} request ++@cindex mode, copy-in, and @code{cf} request ++@cindex @code{trf} request, and copy-in mode ++@cindex copy-in mode, and @code{trf} request ++@cindex mode, copy-in, and @code{trf} request ++Transparently output the contents of @var{file}. Each line is output as ++if it were preceded by @code{\!}; however, the lines are @emph{not} ++subject to copy mode interpretation. If the file does not end with a ++newline, then a newline is added (@code{trf} only). For example, to ++define a macro@tie{}@code{x} containing the contents of ++file@tie{}@file{f}, use ++ ++@Example ++.ev 1 ++.di x ++.trf f ++.di ++.ev ++@endExample ++ ++@noindent ++The calls to @code{ev} prevent that the current partial input line ++becomes part of the diversion. ++ ++Both @code{trf} and @code{cf}, when used in a diversion, embeds an ++object in the diversion which, when reread, causes the contents of ++@var{file} to be transparently copied through to the output. In ++@acronym{UNIX} @code{troff}, the contents of @var{file} is immediately ++copied through to the output regardless of whether there is a current ++diversion; this behaviour is so anomalous that it must be considered a ++bug. ++ ++@cindex @code{trf} request, and invalid characters ++@cindex characters, invalid for @code{trf} request ++@cindex invalid characters for @code{trf} request ++ ++While @code{cf} copies the contents of @var{file} completely ++unprocessed, @code{trf} disallows characters such as NUL that are not ++valid @code{gtroff} input characters (@pxref{Identifiers}). ++ ++For @code{cf}, within a diversion, `completely unprocessed' means that ++each line of a file to be inserted is handled as if it were preceded by ++@code{\!\\!}. ++ ++Both requests cause a line break. ++@endDefreq ++ ++@Defreq {nx, [@Var{file}]} ++@cindex processing next file (@code{nx}) ++@cindex file, processing next (@code{nx}) ++@cindex next file, processing (@code{nx}) ++Force @code{gtroff} to continue processing of the file specified as an ++argument. If no argument is given, immediately jump to the end of file. ++@endDefreq ++ ++@Defreq {rd, [@Var{prompt} [@Var{arg1} @Var{arg2} @dots{}]]} ++@cindex reading from standard input (@code{rd}) ++@cindex standard input, reading from (@code{rd}) ++@cindex input, standard, reading from (@code{rd}) ++Read from standard input, and include what is read as though it were ++part of the input file. Text is read until a blank line is encountered. ++ ++If standard input is a TTY input device (keyboard), write @var{prompt} ++to standard error, followed by a colon (or send BEL for a beep if no ++argument is given). ++ ++Arguments after @var{prompt} are available for the input. For example, ++the line ++ ++@Example ++.rd data foo bar ++@endExample ++ ++with the input @w{@samp{This is \$2.}} prints ++ ++@Example ++This is bar. ++@endExample ++@endDefreq ++ ++@cindex form letters ++@cindex letters, form ++Using the @code{nx} and @code{rd} requests, it is easy to set up form ++letters. The form letter template is constructed like this, putting the ++following lines into a file called @file{repeat.let}: ++ ++@Example ++.ce ++\*(td ++.sp 2 ++.nf ++.rd ++.sp ++.rd ++.fi ++Body of letter. ++.bp ++.nx repeat.let ++@endExample ++ ++@cindex @code{ex} request, used with @code{nx} and @code{rd} ++@noindent ++When this is run, a file containing the following lines should be ++redirected in. Note that requests included in this file are executed as ++though they were part of the form letter. The last block of input is ++the @code{ex} request, which tells @code{groff} to stop processing. If ++this was not there, @code{groff} would not know when to stop. ++ ++@Example ++Trent A. Fisher ++708 NW 19th Av., #202 ++Portland, OR 97209 ++ ++Dear Trent, ++ ++Len Adollar ++4315 Sierra Vista ++San Diego, CA 92103 ++ ++Dear Mr. Adollar, ++ ++.ex ++@endExample ++ ++@Defreq {pi, pipe} ++Pipe the output of @code{gtroff} to the shell command(s) specified by ++@var{pipe}. This request must occur before @code{gtroff} has a chance ++to print anything. ++ ++@cindex safer mode ++@cindex mode, safer ++@cindex unsafe mode ++@cindex mode, unsafe ++@code{pi} causes an error if used in safer mode (which is the default). ++Use @code{groff}'s or @code{troff}'s @option{-U} option to activate ++unsafe mode. ++ ++Multiple calls to @code{pi} are allowed, acting as a chain. For ++example, ++ ++@Example ++.pi foo ++.pi bar ++... ++@endExample ++ ++is the same as @w{@samp{.pi foo | bar}}. ++ ++@cindex @code{groff}, and @code{pi} request ++@cindex @code{pi} request, and @code{groff} ++Note that the intermediate output format of @code{gtroff} is piped to ++the specified commands. Consequently, calling @code{groff} without the ++@option{-Z} option normally causes a fatal error. ++@endDefreq ++ ++@DefreqList {sy, cmds} ++@DefregListEndx {systat} ++Execute the shell command(s) specified by @var{cmds}. The output is not ++saved anyplace, so it is up to the user to do so. ++ ++@cindex safer mode ++@cindex mode, safer ++@cindex unsafe mode ++@cindex mode, unsafe ++This request causes an error if used in safer mode (which is the ++default). Use @code{groff}'s or @code{troff}'s @option{-U} option to ++activate unsafe mode. ++ ++For example, the following code fragment introduces the current time ++into a document: ++ ++@cindex time, current ++@cindex current time ++@pindex perl ++@Example ++.sy perl -e 'printf ".nr H %d\\n.nr M %d\\n.nr S %d\\n",\ ++ (localtime(time))[2,1,0]' > /tmp/x\n[$$] ++.so /tmp/x\n[$$] ++.sy rm /tmp/x\n[$$] ++\nH:\nM:\nS ++@endExample ++ ++@noindent ++Note that this works by having the @code{perl} script (run by @code{sy}) ++print out the @code{nr} requests that set the number registers ++@code{H}, @code{M}, and @code{S}, and then reads those commands in with ++the @code{so} request. ++ ++For most practical purposes, the number registers @code{seconds}, ++@code{minutes}, and @code{hours}, which are initialized at start-up of ++@code{gtroff}, should be sufficient. Use the @code{af} request to get a ++formatted output: ++ ++@Example ++.af hours 00 ++.af minutes 00 ++.af seconds 00 ++\n[hours]:\n[minutes]:\n[seconds] ++@endExample ++ ++@cindex @code{system()} return value register (@code{systat}) ++The @code{systat} read-write number register contains the return value ++of the @code{system()} function executed by the last @code{sy} request. ++@endDefreq ++ ++@DefreqList {open, stream file} ++@DefreqListEndx {opena, stream file} ++@cindex opening file (@code{open}) ++@cindex file, opening (@code{open}) ++@cindex appending to a file (@code{opena}) ++@cindex file, appending to (@code{opena}) ++Open the specified @var{file} for writing and associates the specified ++@var{stream} with it. ++ ++The @code{opena} request is like @code{open}, but if the file exists, ++append to it instead of truncating it. ++ ++@cindex safer mode ++@cindex mode, safer ++@cindex unsafe mode ++@cindex mode, unsafe ++Both @code{open} and @code{opena} cause an error if used in safer mode ++(which is the default). Use @code{groff}'s or @code{troff}'s ++@option{-U} option to activate unsafe mode. ++@endDefreq ++ ++@DefreqList {write, stream data} ++@DefreqListEndx {writec, stream data} ++@cindex copy-in mode, and @code{write} request ++@cindex @code{write} request, and copy-in mode ++@cindex mode, copy-in, and @code{write} request ++@cindex copy-in mode, and @code{writec} request ++@cindex @code{writec} request, and copy-in mode ++@cindex mode, copy-in, and @code{writec} request ++@cindex writing to file (@code{write}, @code{writec}) ++@cindex file, writing to (@code{write}, @code{writec}) ++Write to the file associated with the specified @var{stream}. The ++stream must previously have been the subject of an open request. The ++remainder of the line is interpreted as the @code{ds} request reads its ++second argument: A leading @samp{"} is stripped, and it is read in ++copy-in mode. ++ ++The @code{writec} request is like @code{write}, but only @code{write} ++appends a newline to the data. ++@endDefreq ++ ++@Defreq {writem, stream xx} ++@cindex @code{asciify} request, and @code{writem} ++Write the contents of the macro or string @var{xx} to the file ++associated with the specified @var{stream}. ++ ++@cindex @code{writem} request, and copy-in mode ++@cindex copy-in mode, and @code{writem} request ++@cindex mode, copy-in, and @code{writem} request ++@var{xx} is read in copy mode, i.e., already formatted elements are ++ignored. Consequently, diversions must be unformatted with the ++@code{asciify} request before calling @code{writem}. Usually, this ++means a loss of information. ++@endDefreq ++ ++@Defreq {close, stream} ++@cindex closing file (@code{close}) ++@cindex file, closing (@code{close}) ++Close the specified @var{stream}; the stream is no longer an acceptable ++argument to the @code{write} request. ++ ++Here a simple macro to write an index entry. ++ ++@Example ++.open idx test.idx ++. ++.de IX ++. write idx \\n[%] \\$* ++.. ++. ++.IX test entry ++. ++.close idx ++@endExample ++@endDefreq ++ ++@DefescList {\\V, , e, } ++@DefescItem {\\V, @Lparen{}, ev, } ++@DefescListEnd {\\V, @Lbrack{}, env, @Rbrack{}} ++@cindex @code{\V}, and copy-in mode ++@cindex copy-in mode, and @code{\V} ++@cindex mode, copy-in, and @code{\V} ++Interpolate the contents of the specified environment variable @var{env} ++(one-character name@tie{}@var{e}, two-character name @var{ev}) as ++returned by the function @code{getenv}. @code{\V} is interpreted in ++copy-in mode. ++@endDefesc ++ ++ ++@c ===================================================================== ++ ++@node Postprocessor Access, Miscellaneous, I/O, gtroff Reference ++@section Postprocessor Access ++@cindex postprocessor access ++@cindex access of postprocessor ++ ++There are two escapes that give information directly to the ++postprocessor. This is particularly useful for embedding ++@sc{PostScript} into the final document. ++ ++@DefreqList {device, xxx} ++@DefescListEndx {\\X, ', xxx, '} ++Embeds its argument into the @code{gtroff} output preceded with ++@w{@samp{x X}}. ++ ++@cindex @code{\&}, in @code{\X} ++@cindex @code{\)}, in @code{\X} ++@cindex @code{\%}, in @code{\X} ++@ifnotinfo ++@cindex @code{\:}, in @code{\X} ++@end ifnotinfo ++@ifinfo ++@cindex @code{\@r{}}, in @code{\X} ++@end ifinfo ++The escapes @code{\&}, @code{\)}, @code{\%}, and @code{\:} are ignored ++within @code{\X}, @w{@samp{\ }} and @code{\~} are converted to single ++space characters. All other escapes (except @code{\\}, which produces a ++backslash) cause an error. ++ ++@cindex @code{device} request, and copy-in mode ++@cindex copy-in mode, and @code{device} request ++@cindex mode, copy-in, and @code{device} request ++Contrary to @code{\X}, the @code{device} request simply processes its ++argument in copy mode (@pxref{Copy-in Mode}). ++ ++@kindex use_charnames_in_special ++@pindex DESC@r{, and @code{use_charnames_in_special}} ++@cindex @code{\X}, and special characters ++If the @samp{use_charnames_in_special} keyword is set in the @file{DESC} ++file, special characters no longer cause an error; they are simply ++output verbatim. Additionally, the backslash is represented as ++@code{\\}. ++ ++@samp{use_charnames_in_special} is currently used by @code{grohtml} ++only. ++@endDefesc ++ ++@DefreqList {devicem, xx} ++@DefescItemx {\\Y, , n, } ++@DefescItem {\\Y, @Lparen{}, nm, } ++@DefescListEnd {\\Y, @Lbrack{}, name, @Rbrack{}} ++This is approximately equivalent to @samp{\X'\*[@var{name}]'} ++(one-character name@tie{}@var{n}, two-character name @var{nm}). ++However, the contents of the string or macro @var{name} are not ++interpreted; also it is permitted for @var{name} to have been defined as ++a macro and thus contain newlines (it is not permitted for the argument ++to @code{\X} to contain newlines). The inclusion of newlines requires ++an extension to the @acronym{UNIX} @code{troff} output format, and ++confuses drivers that do not know about this extension (@pxref{Device ++Control Commands}). ++@endDefesc ++ ++@xref{Output Devices}. ++ ++ ++@c ===================================================================== ++ ++@node Miscellaneous, Gtroff Internals, Postprocessor Access, gtroff Reference ++@section Miscellaneous ++ ++This section documents parts of @code{gtroff} that cannot (yet) be ++categorized elsewhere in this manual. ++ ++@Defreq {nm, [@Var{start} [@Var{inc} [@Var{space} [@Var{indent}]]]]} ++@cindex printing line numbers (@code{nm}) ++@cindex line numbers, printing (@code{nm}) ++@cindex numbers, line, printing (@code{nm}) ++Print line numbers. @var{start} is the line number of the @emph{next} ++output line. @var{inc} indicates which line numbers are printed. For ++example, the value@tie{}5 means to emit only line numbers that are ++multiples of@tie{}5; this defaults to@tie{}1. @var{space} is the space ++to be left between the number and the text; this defaults to one digit ++space. The fourth argument is the indentation of the line numbers, ++defaulting to zero. Both @var{space} and @var{indent} are given as ++multiples of digit spaces; they can be negative also. Without any ++arguments, line numbers are turned off. ++ ++@code{gtroff} reserves three digit spaces for the line number (which is ++printed right-justified) plus the amount given by @var{indent}; the ++output lines are concatenated to the line numbers, separated by ++@var{space}, and @emph{without} reducing the line length. Depending on ++the value of the horizontal page offset (as set with the @code{po} ++request), line numbers that are longer than the reserved space stick ++out to the left, or the whole line is moved to the right. ++ ++Parameters corresponding to missing arguments are not changed; any ++non-digit argument (to be more precise, any argument starting with a ++character valid as a delimiter for identifiers) is also treated as ++missing. ++ ++If line numbering has been disabled with a call to @code{nm} without an ++argument, it can be reactivated with @samp{.nm +0}, using the previously ++active line numbering parameters. ++ ++The parameters of @code{nm} are associated with the current environment ++(@pxref{Environments}). The current output line number is available in ++the number register @code{ln}. ++ ++@Example ++.po 1m ++.ll 2i ++This test shows how line numbering works with groff. ++.nm 999 ++This test shows how line numbering works with groff. ++.br ++.nm xxx 3 2 ++.ll -\w'0'u ++This test shows how line numbering works with groff. ++.nn 2 ++This test shows how line numbering works with groff. ++@endExample ++ ++@noindent ++And here the result: ++ ++@Example ++ This test shows how ++ line numbering works ++ 999 with groff. This ++1000 test shows how line ++1001 numbering works with ++1002 groff. ++ This test shows how ++ line numbering ++ works with groff. ++ This test shows how ++1005 line numbering ++ works with groff. ++@endExample ++@endDefreq ++ ++@Defreq {nn, [@Var{skip}]} ++Temporarily turn off line numbering. The argument is the number of ++lines not to be numbered; this defaults to@tie{}1. ++@endDefreq ++ ++@Defreq {mc, glyph [@Var{dist}]} ++@cindex margin glyph (@code{mc}) ++@cindex glyph, for margins (@code{mc}) ++Print a @dfn{margin character} to the right of the ++text.@footnote{@dfn{Margin character} is a misnomer since it is an ++output glyph.} The first argument is the glyph to be printed. The ++second argument is the distance away from the right margin. If missing, ++the previously set value is used; default is 10@dmn{pt}). For text ++lines that are too long (that is, longer than the text length plus ++@var{dist}), the margin character is directly appended to the lines. ++ ++With no arguments the margin character is turned off. If this occurs ++before a break, no margin character is printed. ++ ++For compatibility with @acronym{AT&T} @code{troff}, a call to @code{mc} ++to set the margin character can't be undone immediately; at least one ++line gets a margin character. Thus ++ ++@Example ++.ll 1i ++.mc \[br] ++.mc ++xxx ++.br ++xxx ++@endExample ++ ++@noindent ++produces ++ ++@Example ++xxx | ++xxx ++@endExample ++ ++@cindex @code{tl} request, and @code{mc} ++For empty lines and lines produced by the @code{tl} request no margin ++character is emitted. ++ ++The margin character is associated with the current environment ++(@pxref{Environments}). ++ ++@pindex nrchbar ++@pindex changebar ++This is quite useful for indicating text that has changed, and, in fact, ++there are programs available for doing this (they are called ++@code{nrchbar} and @code{changebar} and can be found in any ++@samp{comp.sources.unix} archive). ++ ++@Example ++.ll 3i ++.mc | ++This paragraph is highlighted with a margin ++character. ++.sp ++Note that vertical space isn't marked. ++.br ++\& ++.br ++But we can fake it with `\&'. ++@endExample ++ ++Result: ++ ++@Example ++This paragraph is highlighted | ++with a margin character. | ++ ++Note that vertical space isn't | ++marked. | ++ | ++But we can fake it with `\&'. | ++@endExample ++@endDefreq ++ ++@DefreqList {psbb, filename} ++@DefregItemx {llx} ++@DefregItemx {lly} ++@DefregItemx {urx} ++@DefregListEndx {ury} ++@cindex PostScript, bounding box ++@cindex bounding box ++Retrieve the bounding box of the @sc{PostScript} image found in ++@var{filename}. The file must conform to Adobe's @dfn{Document ++Structuring Conventions} (DSC); the command searches for a ++@code{%%BoundingBox} comment and extracts the bounding box values into ++the number registers @code{llx}, @code{lly}, @code{urx}, and @code{ury}. ++If an error occurs (for example, @code{psbb} cannot find the ++@code{%%BoundingBox} comment), it sets the four number registers to ++zero. ++ ++The search path for @var{filename} can be controlled with the ++@option{-I} command line option. ++@endDefreq ++ ++ ++@c ===================================================================== ++ ++@node Gtroff Internals, Debugging, Miscellaneous, gtroff Reference ++@section @code{gtroff} Internals ++ ++@cindex input token ++@cindex token, input ++@cindex output node ++@cindex node, output ++@code{gtroff} processes input in three steps. One or more input ++characters are converted to an @dfn{input token}.@footnote{Except the ++escapes @code{\f}, @code{\F}, @code{\H}, @code{\m}, @code{\M}, ++@code{\R}, @code{\s}, and @code{\S}, which are processed immediately if ++not in copy-in mode.} Then, one or more input tokens are converted to ++an @dfn{output node}. Finally, output nodes are converted to the ++intermediate output language understood by all output devices. ++ ++Actually, before step one happens, @code{gtroff} converts certain escape ++sequences into reserved input characters (not accessible by the user); ++such reserved characters are used for other internal processing also -- ++this is the very reason why not all characters are valid input. ++@xref{Identifiers}, for more on this topic. ++ ++For example, the input string @samp{fi\[:u]} is converted into a ++character token @samp{f}, a character token @samp{i}, and a special ++token @samp{:u} (representing u@tie{}umlaut). Later on, the character ++tokens @samp{f} and @samp{i} are merged to a single output node ++representing the ligature glyph @samp{fi} (provided the current font has ++a glyph for this ligature); the same happens with @samp{:u}. All output ++glyph nodes are `processed', which means that they are invariably ++associated with a given font, font size, advance width, etc. During the ++formatting process, @code{gtroff} itself adds various nodes to control ++the data flow. ++ ++Macros, diversions, and strings collect elements in two chained lists: a ++list of input tokens that have been passed unprocessed, and a list of ++output nodes. Consider the following the diversion. ++ ++@Example ++.di xxx ++a ++\!b ++c ++.br ++.di ++@endExample ++ ++@noindent ++It contains these elements. ++ ++@multitable {@i{vertical size node}} {token list} {element number} ++@item node list @tab token list @tab element number ++ ++@item @i{line start node} @tab --- @tab 1 ++@item @i{glyph node @code{a}} @tab --- @tab 2 ++@item @i{word space node} @tab --- @tab 3 ++@item --- @tab @code{b} @tab 4 ++@item --- @tab @code{\n} @tab 5 ++@item @i{glyph node @code{c}} @tab --- @tab 6 ++@item @i{vertical size node} @tab --- @tab 7 ++@item @i{vertical size node} @tab --- @tab 8 ++@item --- @tab @code{\n} @tab 9 ++@end multitable ++ ++@cindex @code{\v}, internal representation ++@noindent ++Elements 1, 7, and@tie{}8 are inserted by @code{gtroff}; the latter two ++(which are always present) specify the vertical extent of the last line, ++possibly modified by @code{\x}. The @code{br} request finishes the ++current partial line, inserting a newline input token, which is ++subsequently converted to a space when the diversion is reread. Note ++that the word space node has a fixed width that isn't stretchable ++anymore. To convert horizontal space nodes back to input tokens, use ++the @code{unformat} request. ++ ++Macros only contain elements in the token list (and the node list is ++empty); diversions and strings can contain elements in both lists. ++ ++Note that the @code{chop} request simply reduces the number of elements ++in a macro, string, or diversion by one. Exceptions are ++@dfn{compatibility save} and @dfn{compatibility ignore} input tokens, ++which are ignored. The @code{substring} request also ignores those ++input tokens. ++ ++Some requests like @code{tr} or @code{cflags} work on glyph identifiers ++only; this means that the associated glyph can be changed without ++destroying this association. This can be very helpful for substituting ++glyphs. In the following example, we assume that glyph @samp{foo} isn't ++available by default, so we provide a substitution using the ++@code{fchar} request and map it to input character @samp{x}. ++ ++@Example ++.fchar \[foo] foo ++.tr x \[foo] ++@endExample ++ ++@noindent ++Now let us assume that we install an additional special font @samp{bar} ++that has glyph @samp{foo}. ++ ++@Example ++.special bar ++.rchar \[foo] ++@endExample ++ ++@noindent ++Since glyphs defined with @code{fchar} are searched before glyphs in ++special fonts, we must call @code{rchar} to remove the definition of the ++fallback glyph. Anyway, the translation is still active; @samp{x} now ++maps to the real glyph @samp{foo}. ++ ++@cindex compatibility mode, and parameters ++@cindex mode, compatibility, and parameters ++@cindex arguments, and compatibility mode ++@cindex parameters, and compatibility mode ++@cindex macro arguments, and compatibility mode ++@cindex request arguments, and compatibility mode ++Macro and request arguments preserve the compatibility mode: ++ ++@Example ++.cp 1 \" switch to compatibility mode ++.de xx ++\\$1 ++.. ++.cp 0 \" switch compatibility mode off ++.xx caf\['e] ++ @result{} caf ++@endExample ++ ++@noindent ++Since compatibility mode is on while @code{de} is called, the macro ++@code{xx} activates compatibility mode while executing. Argument ++@code{$1} can still be handled properly because it inherits the ++compatibility mode status which was active at the point where @code{xx} ++is called. ++ ++After expansion of the parameters, the compatibility save and restore ++tokens are removed. ++ ++ ++@c ===================================================================== ++ ++@node Debugging, Implementation Differences, Gtroff Internals, gtroff Reference ++@section Debugging ++@cindex debugging ++ ++@code{gtroff} is not easy to debug, but there are some useful features ++and strategies for debugging. ++ ++@Defreq {lf, line [@Var{filename}]} ++@pindex soelim ++@cindex multi-file documents ++@cindex documents, multi-file ++@cindex setting input line number (@code{lf}) ++@cindex input line number, setting (@code{lf}) ++@cindex number, input line, setting (@code{lf}) ++Change the line number and optionally the file name @code{gtroff} shall ++use for error and warning messages. @var{line} is the input line number ++of the @emph{next} line. ++ ++Without argument, the request is ignored. ++ ++This is a debugging aid for documents that are split into many files, ++then put together with @code{soelim} and other preprocessors. Usually, ++it isn't invoked manually. ++ ++Note that other @code{troff} implementations (including the original ++@acronym{AT&T} version) handle @code{lf} differently. For them, ++@var{line} changes the line number of the @emph{current} line. ++@endDefreq ++ ++@DefreqList {tm, string} ++@DefreqItemx {tm1, string} ++@DefreqListEndx {tmc, string} ++@cindex printing to stderr (@code{tm}, @code{tm1}, @code{tmc}) ++@cindex stderr, printing to (@code{tm}, @code{tm1}, @code{tmc}) ++Send @var{string} to the standard error output; this is very useful for ++printing debugging messages among other things. ++ ++@cindex @code{tm} request, and copy-in mode ++@cindex copy-in mode, and @code{tm} request ++@cindex mode, copy-in, and @code{tm} request ++@cindex @code{tm1} request, and copy-in mode ++@cindex copy-in mode, and @code{tm1} request ++@cindex mode, copy-in, and @code{tm1} request ++@cindex @code{tmc} request, and copy-in mode ++@cindex copy-in mode, and @code{tmc} request ++@cindex mode, copy-in, and @code{tmc} request ++@var{string} is read in copy mode. ++ ++The @code{tm} request ignores leading spaces of @var{string}; @code{tm1} ++handles its argument similar to the @code{ds} request: a leading double ++quote in @var{string} is stripped to allow initial blanks. ++ ++The @code{tmc} request is similar to @code{tm1} but does not append a ++newline (as is done in @code{tm} and @code{tm1}). ++@endDefreq ++ ++@Defreq {ab, [@Var{string}]} ++@cindex aborting (@code{ab}) ++Similar to the @code{tm} request, except that it causes @code{gtroff} to ++stop processing. With no argument it prints @samp{User Abort.} to ++standard error. ++@endDefreq ++ ++@Defreq {ex, } ++@cindex @code{ex} request, use in debugging ++@cindex exiting (@code{ex}) ++The @code{ex} request also causes @code{gtroff} to stop processing; see ++also @ref{I/O}. ++@endDefreq ++ ++When doing something involved it is useful to leave the debugging ++statements in the code and have them turned on by a command line flag. ++ ++@Example ++.if \n(DB .tm debugging output ++@endExample ++ ++@noindent ++To activate these statements say ++ ++@Example ++groff -rDB=1 file ++@endExample ++ ++If it is known in advance that there are many errors and no useful ++output, @code{gtroff} can be forced to suppress formatted output with ++the @option{-z} flag. ++ ++@Defreq {pev, } ++@cindex dumping environments (@code{pev}) ++@cindex environments, dumping (@code{pev}) ++Print the contents of the current environment and all the currently ++defined environments (both named and numbered) on @code{stderr}. ++@endDefreq ++ ++@Defreq {pm, } ++@cindex dumping symbol table (@code{pm}) ++@cindex symbol table, dumping (@code{pm}) ++Print the entire symbol table on @code{stderr}. Names of all defined ++macros, strings, and diversions are print together with their size in ++bytes. Since @code{gtroff} sometimes adds nodes by itself, the returned ++size can be larger than expected. ++ ++This request differs from @acronym{UNIX} @code{troff}: @code{gtroff} ++reports the sizes of diversions, ignores an additional argument to print ++only the total of the sizes, and the size isn't returned in blocks of ++128 characters. ++@endDefreq ++ ++@Defreq {pnr, } ++@cindex dumping number registers (@code{pnr}) ++@cindex number registers, dumping (@code{pnr}) ++Print the names and contents of all currently defined number registers ++on @code{stderr}. ++@endDefreq ++ ++@Defreq {ptr, } ++@cindex dumping traps (@code{ptr}) ++@cindex traps, dumping (@code{ptr}) ++Print the names and positions of all traps (not including input line ++traps and diversion traps) on @code{stderr}. Empty slots in the page ++trap list are printed as well, because they can affect the priority of ++subsequently planted traps. ++@endDefreq ++ ++@Defreq {fl, } ++@cindex flush output (@code{fl}) ++@cindex output, flush (@code{fl}) ++@cindex interactive use of @code{gtroff} ++@cindex @code{gtroff}, interactive use ++Instruct @code{gtroff} to flush its output immediately. The intent is ++for interactive use, but this behaviour is currently not implemented in ++@code{gtroff}. Contrary to @acronym{UNIX} @code{troff}, TTY output is ++sent to a device driver also (@code{grotty}), making it non-trivial to ++communicate interactively. ++ ++This request causes a line break. ++@endDefreq ++ ++@Defreq {backtrace, } ++@cindex backtrace of input stack (@code{backtrace}) ++@cindex input stack, backtrace (@code{backtrace}) ++Print a backtrace of the input stack to the standard error stream. ++ ++Consider the following in file @file{test}: ++ ++@Example ++.de xxx ++. backtrace ++.. ++.de yyy ++. xxx ++.. ++. ++.yyy ++@endExample ++ ++@noindent ++On execution, @code{gtroff} prints the following: ++ ++@Example ++test:2: backtrace: macro `xxx' ++test:5: backtrace: macro `yyy' ++test:8: backtrace: file `test' ++@endExample ++ ++The option @option{-b} of @code{gtroff} internally calls a variant of ++this request on each error and warning. ++@endDefreq ++ ++@Defreg {slimit} ++@cindex input stack, setting limit ++Use the @code{slimit} number register to set the maximum number of ++objects on the input stack. If @code{slimit} is less than or equal ++to@tie{}0, there is no limit set. With no limit, a buggy recursive ++macro can exhaust virtual memory. ++ ++The default value is 1000; this is a compile-time constant. ++@endDefreg ++ ++@Defreq {warnscale, si} ++Set the scaling indicator used in warnings to @var{si}. Valid values ++for @var{si} are @samp{u}, @samp{i}, @samp{c}, @samp{p}, and @samp{P}. ++At startup, it is set to @samp{i}. ++@endDefreq ++ ++@Defreq {spreadwarn, [@Var{limit}]} ++Make @code{gtroff} emit a warning if the additional space inserted for ++each space between words in an output line is larger or equal to ++@var{limit}. A negative value is changed to zero; no argument toggles ++the warning on and off without changing @var{limit}. The default ++scaling indicator is @samp{m}. At startup, @code{spreadwarn} is ++deactivated, and @var{limit} is set to 3@dmn{m}. ++ ++For example, ++ ++@Example ++.spreadwarn 0.2m ++@endExample ++ ++@noindent ++causes a warning if @code{gtroff} must add 0.2@dmn{m} or more for each ++interword space in a line. ++ ++This request is active only if text is justified to both margins (using ++@w{@samp{.ad b}}). ++@endDefreq ++ ++@cindex warnings ++@code{gtroff} has command line options for printing out more warnings ++(@option{-w}) and for printing backtraces (@option{-b}) when a warning ++or an error occurs. The most verbose level of warnings is @option{-ww}. ++ ++@DefreqList {warn, [@Var{flags}]} ++@DefregListEndx {.warn} ++@cindex level of warnings (@code{warn}) ++@cindex warnings, level (@code{warn}) ++Control the level of warnings checked for. The @var{flags} are the sum ++of the numbers associated with each warning that is to be enabled; all ++other warnings are disabled. The number associated with each warning is ++listed below. For example, @w{@code{.warn 0}} disables all warnings, ++and @w{@code{.warn 1}} disables all warnings except that about missing ++glyphs. If no argument is given, all warnings are enabled. ++ ++The read-only number register @code{.warn} contains the current warning ++level. ++@endDefreq ++ ++@menu ++* Warnings:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Warnings, , Debugging, Debugging ++@subsection Warnings ++@cindex warnings ++ ++The warnings that can be given to @code{gtroff} are divided into the ++following categories. The name associated with each warning is used by ++the @option{-w} and @option{-W} options; the number is used by the ++@code{warn} request and by the @code{.warn} register. ++ ++@table @samp ++@item char ++@itemx 1 ++Non-existent glyphs.@footnote{@code{char} is a misnomer since it reports ++missing glyphs -- there aren't missing input characters, only invalid ++ones.} This is enabled by default. ++ ++@item number ++@itemx 2 ++Invalid numeric expressions. This is enabled by default. ++@xref{Expressions}. ++ ++@item break ++@itemx 4 ++@cindex fill mode ++@cindex mode, fill ++In fill mode, lines that could not be broken so that their length was ++less than the line length. This is enabled by default. ++ ++@item delim ++@itemx 8 ++Missing or mismatched closing delimiters. ++ ++@item el ++@itemx 16 ++@cindex @code{ie} request, and warnings ++@cindex @code{el} request, and warnings ++Use of the @code{el} request with no matching @code{ie} request. ++@xref{if-else}. ++ ++@item scale ++@itemx 32 ++Meaningless scaling indicators. ++ ++@item range ++@itemx 64 ++Out of range arguments. ++ ++@item syntax ++@itemx 128 ++Dubious syntax in numeric expressions. ++ ++@item di ++@itemx 256 ++@cindex @code{di} request, and warnings ++@cindex @code{da} request, and warnings ++Use of @code{di} or @code{da} without an argument when there is no ++current diversion. ++ ++@item mac ++@itemx 512 ++@cindex @code{de}, @code{de1}, @code{dei} requests, and warnings ++@cindex @code{am}, @code{am1}, @code{ami} requests, and warnings ++@cindex @code{ds}, @code{ds1} requests, and warnings ++@cindex @code{as}, @code{as1} requests, and warnings ++@cindex @code{di} request, and warnings ++@cindex @code{da} request, and warnings ++@cindex @code{box}, @code{boxa} requests, and warnings ++@cindex @code{\*}, and warnings ++Use of undefined strings, macros and diversions. When an undefined ++string, macro, or diversion is used, that string is automatically ++defined as empty. So, in most cases, at most one warning is given for ++each name. ++ ++@item reg ++@itemx 1024 ++@cindex @code{nr} request, and warnings ++@cindex @code{\R}, and warnings ++@cindex @code{\n}, and warnings ++Use of undefined number registers. When an undefined number register is ++used, that register is automatically defined to have a value of@tie{}0. ++So, in most cases, at most one warning is given for use of a particular ++name. ++ ++@item tab ++@itemx 2048 ++@cindex @code{\t}, and warnings ++Use of a tab character where a number was expected. ++ ++@item right-brace ++@itemx 4096 ++@cindex @code{\@}}, and warnings ++Use of @code{\@}} where a number was expected. ++ ++@item missing ++@itemx 8192 ++Requests that are missing non-optional arguments. ++ ++@item input ++@itemx 16384 ++Invalid input characters. ++ ++@item escape ++@itemx 32768 ++Unrecognized escape sequences. When an unrecognized escape sequence ++@code{\@var{X}} is encountered, the escape character is ignored, and ++@var{X} is printed. ++ ++@item space ++@itemx 65536 ++@cindex compatibility mode ++Missing space between a request or macro and its argument. This warning ++is given when an undefined name longer than two characters is ++encountered, and the first two characters of the name make a defined ++name. The request or macro is not invoked. When this warning is given, ++no macro is automatically defined. This is enabled by default. This ++warning never occurs in compatibility mode. ++ ++@item font ++@itemx 131072 ++Non-existent fonts. This is enabled by default. ++ ++@item ig ++@itemx 262144 ++Invalid escapes in text ignored with the @code{ig} request. These are ++conditions that are errors when they do not occur in ignored text. ++ ++@item color ++@itemx 524288 ++Color related warnings. ++ ++@item file ++@itemx 1048576 ++Missing files. The @code{mso} request gives this warning when the ++requested macro file does not exist. This is enabled by default. ++ ++@item all ++All warnings except @samp{di}, @samp{mac} and @samp{reg}. It is ++intended that this covers all warnings that are useful with traditional ++macro packages. ++ ++@item w ++All warnings. ++@end table ++ ++ ++@c ===================================================================== ++ ++@node Implementation Differences, , Debugging, gtroff Reference ++@section Implementation Differences ++@cindex implementation differences ++@cindex differences in implementation ++@cindex incompatibilities with @acronym{AT&T} @code{troff} ++@cindex compatibility mode ++@cindex mode, compatibility ++ ++GNU @code{troff} has a number of features that cause incompatibilities ++with documents written with old versions of @code{troff}. ++ ++@cindex long names ++@cindex names, long ++Long names cause some incompatibilities. @acronym{UNIX} @code{troff} ++interprets ++ ++@Example ++.dsabcd ++@endExample ++ ++@cindex @code{\*}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\n}, incompatibilities with @acronym{AT&T} @code{troff} ++@noindent ++as defining a string @samp{ab} with contents @samp{cd}. Normally, GNU ++@code{troff} interprets this as a call of a macro named @code{dsabcd}. ++Also @acronym{UNIX} @code{troff} interprets @code{\*[} or @code{\n[} as ++references to a string or number register called @samp{[}. In GNU ++@code{troff}, however, this is normally interpreted as the start of a ++long name. In compatibility mode GNU @code{troff} interprets long names ++in the traditional way (which means that they are not recognized as ++names). ++ ++@DefreqList {cp, [@Var{n}]} ++@DefreqItemx {do, cmd} ++@DefregListEndx {.C} ++If @var{n} is missing or non-zero, turn on compatibility mode; ++otherwise, turn it off. ++ ++The read-only number register @code{.C} is@tie{}1 if compatibility mode ++is on, 0@tie{}otherwise. ++ ++Compatibility mode can be also turned on with the @option{-C} command ++line option. ++ ++The @code{do} request turns off compatibility mode while executing its ++arguments as a @code{gtroff} command. However, it does not turn off ++compatibility mode while processing the macro itself. To do that, use ++the @code{de1} request (or manipulate the @code{.C} register manually). ++@xref{Writing Macros}. ++ ++@Example ++.do fam T ++@endExample ++ ++@noindent ++executes the @code{fam} request when compatibility mode is enabled. ++ ++@code{gtroff} restores the previous compatibility setting before ++interpreting any files sourced by the @var{cmd}. ++@endDefreq ++ ++@cindex input level in delimited arguments ++@cindex delimited arguments, incompatibilities with @acronym{AT&T} @code{troff} ++Two other features are controlled by @option{-C}. If not in ++compatibility mode, GNU @code{troff} preserves the input level in ++delimited arguments: ++ ++@Example ++.ds xx ' ++\w'abc\*(xxdef' ++@endExample ++ ++@noindent ++In compatibility mode, the string @samp{72def'} is returned; without ++@option{-C} the resulting string is @samp{168} (assuming a TTY output ++device). ++ ++@cindex @code{\f}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\H}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\s}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\S}, incompatibilities with @acronym{AT&T} @code{troff} ++Finally, the escapes @code{\f}, @code{\H}, @code{\m}, @code{\M}, ++@code{\R}, @code{\s}, and @code{\S} are transparent for recognizing the ++beginning of a line only in compatibility mode (this is a rather obscure ++feature). For example, the code ++ ++@Example ++.de xx ++Hallo! ++.. ++\fB.xx\fP ++@endExample ++ ++@noindent ++prints @samp{Hallo!} in bold face if in compatibility mode, and ++@samp{.xx} in bold face otherwise. ++ ++@cindex @code{\A}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\|}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\^}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\&}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\@{}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\@}}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\@key{SP}}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\'}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\`}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\-}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\_}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\!}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\%}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\c}, incompatibilities with @acronym{AT&T} @code{troff} ++GNU @code{troff} does not allow the use of the escape sequences ++@code{\|}, @code{\^}, @code{\&}, @code{\@{}, @code{\@}}, ++@code{\@key{SP}}, @code{\'}, @code{\`}, @code{\-}, @code{\_}, @code{\!}, ++@code{\%}, and @code{\c} in names of strings, macros, diversions, number ++registers, fonts or environments; @acronym{UNIX} @code{troff} does. The ++@code{\A} escape sequence (@pxref{Identifiers}) may be helpful in ++avoiding use of these escape sequences in names. ++ ++@cindex fractional point sizes ++@cindex fractional type sizes ++@cindex point sizes, fractional ++@cindex type sizes, fractional ++@cindex sizes, fractional ++@cindex @code{ps} request, incompatibilities with @acronym{AT&T} @code{troff} ++Fractional point sizes cause one noteworthy incompatibility. In ++@acronym{UNIX} @code{troff} the @code{ps} request ignores scale ++indicators and thus ++ ++@Example ++.ps 10u ++@endExample ++ ++@noindent ++sets the point size to 10@tie{}points, whereas in GNU @code{troff} it ++sets the point size to 10@tie{}scaled points. @xref{Fractional Type ++Sizes}, for more information. ++ ++@cindex @code{bd} request, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{cs} request, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{tr} request, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{fp} request, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex input characters and output glyphs, compatibility with @acronym{AT&T} @code{troff} ++@cindex output glyphs, and input characters,compatibility with @acronym{AT&T} @code{troff} ++@cindex characters, input, and output glyphs, compatibility with @acronym{AT&T} @code{troff} ++@cindex glyphs, output, and input characters, compatibility with @acronym{AT&T} @code{troff} ++In GNU @code{troff} there is a fundamental difference between ++(unformatted) input characters and (formatted) output glyphs. ++Everything that affects how a glyph is output is stored with the glyph ++node; once a glyph node has been constructed it is unaffected by any ++subsequent requests that are executed, including @code{bd}, @code{cs}, ++@code{tkf}, @code{tr}, or @code{fp} requests. Normally glyphs are ++constructed from input characters at the moment immediately before the ++glyph is added to the current output line. Macros, diversions and ++strings are all, in fact, the same type of object; they contain lists of ++input characters and glyph nodes in any combination. A glyph node does ++not behave like an input character for the purposes of macro processing; ++it does not inherit any of the special properties that the input ++character from which it was constructed might have had. For example, ++ ++@Example ++.di x ++\\\\ ++.br ++.di ++.x ++@endExample ++ ++@cindex printing backslash (@code{\\}, @code{\e}, @code{\E}, @code{\[rs]}) ++@cindex backslash, printing (@code{\\}, @code{\e}, @code{\E}, @code{\[rs]}) ++@cindex @code{\e}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\!}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex @code{\?}, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex transparent output, incompatibilities with @acronym{AT&T} @code{troff} ++@cindex output, transparent, incompatibilities with @acronym{AT&T} @code{troff} ++@noindent ++prints @samp{\\} in GNU @code{troff}; each pair of input backslashes is ++turned into one output backslash and the resulting output backslashes ++are not interpreted as escape characters when they are reread. ++@acronym{UNIX} @code{troff} would interpret them as escape characters ++when they were reread and would end up printing one @samp{\}. The ++correct way to obtain a printable backslash is to use the @code{\e} ++escape sequence: This always prints a single instance of the current ++escape character, regardless of whether or not it is used in a ++diversion; it also works in both GNU @code{troff} and @acronym{UNIX} ++@code{troff}.@footnote{To be completely independent of the current ++escape character, use @code{\(rs}, which represents a reverse solidus ++(backslash) glyph.} To store, for some reason, an escape sequence in a ++diversion that is interpreted when the diversion is reread, either use ++the traditional @code{\!} transparent output facility, or, if this is ++unsuitable, the new @code{\?} escape sequence. ++ ++@xref{Diversions}, and @ref{Gtroff Internals}, for more information. ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Preprocessors, Output Devices, gtroff Reference, Top ++@chapter Preprocessors ++@cindex preprocessors ++ ++This chapter describes all preprocessors that come with @code{groff} or ++which are freely available. ++ ++@menu ++* geqn:: ++* gtbl:: ++* gpic:: ++* ggrn:: ++* grap:: ++* gchem:: ++* grefer:: ++* gsoelim:: ++* preconv:: ++@end menu ++ ++ ++@c ===================================================================== ++ ++@node geqn, gtbl, Preprocessors, Preprocessors ++@section @code{geqn} ++@cindex @code{eqn}, the program ++@cindex @code{geqn}, the program ++ ++@c XXX ++ ++@menu ++* Invoking geqn:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking geqn, , geqn, geqn ++@subsection Invoking @code{geqn} ++@cindex invoking @code{geqn} ++@cindex @code{geqn}, invoking ++ ++@c XXX ++ ++ ++@c ===================================================================== ++ ++@node gtbl, gpic, geqn, Preprocessors ++@section @code{gtbl} ++@cindex @code{tbl}, the program ++@cindex @code{gtbl}, the program ++ ++@c XXX ++ ++@menu ++* Invoking gtbl:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking gtbl, , gtbl, gtbl ++@subsection Invoking @code{gtbl} ++@cindex invoking @code{gtbl} ++@cindex @code{gtbl}, invoking ++ ++@c XXX ++ ++ ++@c ===================================================================== ++ ++@node gpic, ggrn, gtbl, Preprocessors ++@section @code{gpic} ++@cindex @code{pic}, the program ++@cindex @code{gpic}, the program ++ ++@c XXX ++ ++@menu ++* Invoking gpic:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking gpic, , gpic, gpic ++@subsection Invoking @code{gpic} ++@cindex invoking @code{gpic} ++@cindex @code{gpic}, invoking ++ ++@c XXX ++ ++ ++@c ===================================================================== ++ ++@node ggrn, grap, gpic, Preprocessors ++@section @code{ggrn} ++@cindex @code{grn}, the program ++@cindex @code{ggrn}, the program ++ ++@c XXX ++ ++@menu ++* Invoking ggrn:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking ggrn, , ggrn, ggrn ++@subsection Invoking @code{ggrn} ++@cindex invoking @code{ggrn} ++@cindex @code{ggrn}, invoking ++ ++@c XXX ++ ++ ++@c ===================================================================== ++ ++@node grap, gchem, ggrn, Preprocessors ++@section @code{grap} ++@cindex @code{grap}, the program ++ ++A free implementation of @code{grap}, written by Ted Faber, ++is available as an extra package from the following address: ++ ++@display ++@uref{http://www.lunabase.org/~faber/Vault/software/grap/} ++@end display ++ ++ ++@c ===================================================================== ++ ++@node gchem, grefer, grap, Preprocessors ++@section @code{gchem} ++@cindex @code{chem}, the program ++@cindex @code{gchem}, the program ++ ++@c XXX ++ ++@menu ++* Invoking gchem:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking gchem, , gchem, gchem ++@subsection Invoking @code{gchem} ++@cindex invoking @code{gchem} ++@cindex @code{gchem}, invoking ++ ++@c XXX ++ ++ ++@c ===================================================================== ++ ++@node grefer, gsoelim, gchem, Preprocessors ++@section @code{grefer} ++@cindex @code{refer}, the program ++@cindex @code{grefer}, the program ++ ++@c XXX ++ ++@menu ++* Invoking grefer:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking grefer, , grefer, grefer ++@subsection Invoking @code{grefer} ++@cindex invoking @code{grefer} ++@cindex @code{grefer}, invoking ++ ++@c XXX ++ ++ ++@c ===================================================================== ++ ++@node gsoelim, preconv, grefer, Preprocessors ++@section @code{gsoelim} ++@cindex @code{soelim}, the program ++@cindex @code{gsoelim}, the program ++ ++@c XXX ++ ++@menu ++* Invoking gsoelim:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking gsoelim, , gsoelim, gsoelim ++@subsection Invoking @code{gsoelim} ++@cindex invoking @code{gsoelim} ++@cindex @code{gsoelim}, invoking ++ ++@c XXX ++ ++ ++@c ===================================================================== ++ ++@node preconv, , gsoelim, Preprocessors ++@section @code{preconv} ++@cindex @code{preconv}, the program ++ ++@c XXX ++ ++@menu ++* Invoking preconv:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking preconv, , preconv, preconv ++@subsection Invoking @code{preconv} ++@cindex invoking @code{preconv} ++@cindex @code{preconv}, invoking ++ ++@c XXX ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Output Devices, File formats, Preprocessors, Top ++@chapter Output Devices ++@cindex output devices ++@cindex devices for output ++ ++@c XXX ++ ++@menu ++* Special Characters:: ++* grotty:: ++* grops:: ++* gropdf:: ++* grodvi:: ++* grolj4:: ++* grolbp:: ++* grohtml:: ++* gxditview:: ++@end menu ++ ++ ++@c ===================================================================== ++ ++@node Special Characters, grotty, Output Devices, Output Devices ++@section Special Characters ++@cindex special characters ++@cindex characters, special ++ ++@c XXX ++ ++@xref{Font Files}. ++ ++ ++@c ===================================================================== ++ ++@node grotty, grops, Special Characters, Output Devices ++@section @code{grotty} ++@cindex @code{grotty}, the program ++ ++The postprocessor @code{grotty} translates the output from GNU ++@code{troff} into a form suitable for typewriter-like devices. It is ++fully documented on its manual page, @cite{grotty(1)}. ++ ++@menu ++* Invoking grotty:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking grotty, , grotty, grotty ++@subsection Invoking @code{grotty} ++@cindex invoking @code{grotty} ++@cindex @code{grotty}, invoking ++ ++The postprocessor @command{grotty} accepts the following command-line ++options: ++ ++@table @option ++@item -b ++Do not overstrike bold glyphs. Ignored if @option{-c} isn't used. ++ ++@item -B ++Do not underline bold-italic glyphs. Ignored if @option{-c} isn't ++used. ++ ++@item -c ++Use overprint and disable colours for printing on legacy Teletype ++printers (see below). ++ ++@item -d ++Do not render lines (this is, ignore all @code{\D} escapes). ++ ++@item -f ++Use form feed control characters in the output. ++ ++@item -F@var{dir} ++Put the directory @file{@var{dir}/dev@var{name}} in front of the ++search path for the font and device description files, given the ++target device @var{name}. ++ ++@item -h ++Use horizontal tabs for sequences of 8 space characters. ++ ++@item -i ++Request italic glyphs from the terminal. Ignored if @option{-c} is ++active. ++ ++@item -o ++Do not overstrike. ++ ++@item -r ++Highlight italic glyphs. Ignored if @option{-c} is active. ++ ++@item -u ++Do not underline italic glyphs. Ignored if @option{-c} isn't used. ++ ++@item -U ++Do not overstrike bold-italic glyphs. Ignored if @option{-c} isn't ++used. ++ ++@item -v ++Print the version number. ++@end table ++ ++@pindex less ++@cindex Teletype ++@cindex ISO 6249 SGR ++@cindex terminal control sequences ++@cindex control sequences, for terminals ++The @option{-c} mode for TTY output devices means that underlining is ++done by emitting sequences of @samp{_} and @samp{^H} (the backspace ++character) before the actual character. Literally, this is printing ++an underline character, then moving the caret back one character ++position, and printing the actual character at the same position as ++the underline character (similar to a typewriter). Usually, a modern ++terminal can't interpret this (and the original Teletype machines for ++which this sequence was appropriate are no longer in use). You need ++a pager program like @code{less} that translates this into ++ISO@tie{}6429 SGR sequences to control terminals. ++ ++ ++@c ===================================================================== ++ ++@node grops, gropdf, grotty, Output Devices ++@section @code{grops} ++@cindex @code{grops}, the program ++ ++The postprocessor @command{grops} translates the output from GNU ++@command{troff} into a form suitable for Adobe @sc{PostScript} ++devices. It is fully documented on its manual page, @cite{grops(1)}. ++ ++ ++@menu ++* Invoking grops:: ++* Embedding PostScript:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking grops, Embedding PostScript, grops, grops ++@subsection Invoking @code{grops} ++@cindex invoking @code{grops} ++@cindex @code{grops}, invoking ++ ++The postprocessor @code{grops} accepts the following command-line ++options: ++ ++@table @option ++@item -b@var{flags} ++Use backward compatibility settings given by @var{flags} as ++documented in the @cite{grops(1)} manual page. Overrides the command ++@option{broken} in the @file{DESC} file. ++ ++@item -c@var{n} ++Print @var{n} copies of each page. ++ ++@item -F@var{dir} ++Put the directory @file{@var{dir}/dev@var{name}} in front of the ++search path for the font, prologue and device description files, ++given the target device @var{name}, usually @strong{ps}. ++ ++@item -g ++Tell the printer to guess the page length. Useful for printing ++vertically centered pages when the paper dimensions are determined at ++print time. ++ ++@item -I@var{path} @dots{} ++Consider the directory @file{@var{path}} for searching included files ++specified with relative paths. The current directory is searched as ++fallback. ++ ++@item -l ++Use landscape orientation. ++ ++@item -m ++Use manual feed. ++ ++@item -p@var{papersize} ++Set the page dimensions. Overrides the commands @option{papersize}, ++@option{paperlength}, and @option{paperwidth} in the @file{DESC} ++file. See the @cite{groff_font(5)} manual page for details. ++ ++@item -P@var{prologue} ++Use the @var{prologue} in the font path as the prologue instead of ++the default @file{prologue}. Overrides the environment variable ++@env{GROPS_PROLOGUE}. ++ ++@item -w@var{n} ++Set the line thickness to @var{n}/1000@dmn{em}. Overrides the ++default value @var{n} = 40. ++ ++@item -v ++Print the version number. ++@end table ++ ++@c --------------------------------------------------------------------- ++ ++@node Embedding PostScript, , Invoking grops, grops ++@subsection Embedding @sc{PostScript} ++@cindex embedding PostScript ++@cindex PostScript, embedding ++ ++The escape sequence ++ ++@code{\X'ps: import @var{file} @var{llx} @var{lly} @var{urx} @var{ury} ++ @var{width} [@var{height}]'} ++ ++@noindent ++places a rectangle of the specified @var{width} containing the ++@sc{PostScript} drawing from file @var{file} bound by the box from ++@var{llx} @var{lly} to @var{urx} @var{ury} (in @sc{PostScript} ++coordinates) at the insertion point. If @var{height} is not ++specified, the embedded drawing is scaled proportionally. ++ ++@xref{Miscellaneous}, for the @code{psbb} request, which automatically ++generates the bounding box. ++ ++This escape sequence is used internally by the macro @code{PSPIC} ++(see the @cite{groff_tmac(5)} manual page). ++ ++ ++@c ===================================================================== ++ ++@node gropdf, grodvi, grops, Output Devices ++@section @code{gropdf} ++@cindex @code{gropdf}, the program ++ ++The postprocessor @command{gropdf} translates the output from GNU ++@command{troff} into a form suitable for Adobe PDF devices. It is fully ++documented on its manual page, @cite{gropdf(1)}. ++ ++@menu ++* Invoking gropdf:: ++* Embedding PDF:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking gropdf, Embedding PDF, gropdf, gropdf ++@subsection Invoking @code{gropdf} ++@cindex invoking @code{gropdf} ++@cindex @code{gropdf}, invoking ++ ++The postprocessor @code{gropdf} accepts the following command-line ++options: ++ ++@table @option ++@item -d ++Produce uncompressed PDFs that include debugging comments. ++ ++@item -e ++This forces @code{gropdf} to embed all used fonts in the PDF, ++even if they are one of the 14 base Adobe fonts. ++ ++@item -F@var{dir} ++Put the directory @file{@var{dir}/dev@var{name}} in front of the ++search path for the font, prologue and device description files, ++given the target device @var{name}, usually @strong{pdf}. ++ ++@item -y@var{foundry} ++This forces the use of a different font foundry. ++ ++@item -l ++Use landscape orientation. ++ ++@item -p@var{papersize} ++Set the page dimensions. Overrides the commands @option{papersize}, ++@option{paperlength}, and @option{paperwidth} in the @file{DESC} ++file. See the @cite{groff_font(5)} manual page for details. ++ ++@item -v ++Print the version number. ++ ++@item -s ++Append a comment line to end of PDF showing statistics, i.e. number of ++pages in document. Ghostscript's @cite{ps2pdf(1)} complains about this ++line if it is included, but works anyway. ++ ++@item -u@var{filename} ++@code{gropdf} normally includes a ToUnicode CMap with any font created ++using @file{text.enc} as the encoding file, this makes it easier to ++search for words that contain ligatures. You can include your own CMap ++by specifying a @var{filename} or have no CMap at all by omitting the ++@var{filename}. ++@end table ++ ++@c --------------------------------------------------------------------- ++ ++@node Embedding PDF, , Invoking gropdf, gropdf ++@subsection Embedding PDF ++@cindex embedding PDF ++@cindex PDF, embedding ++ ++The escape sequence ++ ++@code{\X'pdf: pdfpic @var{file} @var{alignment} @var{width} [@var{height}] ++ [@var{linelength}]'} ++ ++@noindent ++places a rectangle of the specified @var{width} containing the PDF ++drawing from file @var{file} of desired @var{width} and @var{height} (if ++@var{height} is missing or zero then it is scaled proportionally). If ++@var{alignment} is @code{-L} the drawing is left aligned. If it is ++@code{-C} or @code{-R} a @var{linelength} greater than the width of the ++drawing is required as well. If @var{width} is specified as zero then ++the width is scaled in proportion to the height. ++ ++ ++@c ===================================================================== ++ ++@node grodvi, grolj4, gropdf, Output Devices ++@section @code{grodvi} ++@cindex @code{grodvi}, the program ++ ++The postprocessor @command{grodvi} translates the output from GNU ++@command{troff} into the @strong{DVI} output format compatible with ++the @strong{@TeX{}} document preparation system. It is fully ++documented on its manual page, @cite{grodvi(1)}. ++ ++@menu ++* Invoking grodvi:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking grodvi, , grodvi, grodvi ++@subsection Invoking @code{grodvi} ++@cindex invoking @code{grodvi} ++@cindex @code{grodvi}, invoking ++ ++The postprocessor @code{grodvi} accepts the following command-line ++options: ++ ++@table @option ++@item -d ++Do not use @strong{tpic} specials to implement drawing commands. ++ ++@item -F@var{dir} ++Put the directory @file{@var{dir}/dev@var{name}} in front of the ++search path for the font and device description files, given the ++target device @var{name}, usually @strong{dvi}. ++ ++@item -l ++Use landscape orientation. ++ ++@item -p@var{papersize} ++Set the page dimensions. Overrides the commands @option{papersize}, ++@option{paperlength}, and @option{paperwidth} in the @file{DESC} ++file. See @cite{groff_font(5)} manual page for details. ++ ++@item -v ++Print the version number. ++ ++@item -w@var{n} ++Set the line thickness to @var{n}/1000@dmn{em}. Overrides the ++default value @var{n} = 40. ++@end table ++ ++ ++@c ===================================================================== ++ ++@node grolj4, grolbp, grodvi, Output Devices ++@section @code{grolj4} ++@cindex @code{grolj4}, the program ++ ++The postprocessor @command{grolj4} translates the output from GNU ++@command{troff} into the @strong{PCL5} output format suitable for ++printing on a @strong{HP LaserJet@tie{}4} printer. It is fully ++documented on its manual page, @cite{grolj4(1)}. ++ ++@menu ++* Invoking grolj4:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking grolj4, , grolj4, grolj4 ++@subsection Invoking @code{grolj4} ++@cindex invoking @code{grolj4} ++@cindex @code{grolj4}, invoking ++ ++The postprocessor @code{grolj4} accepts the following command-line ++options: ++ ++@table @option ++@item -c@var{n} ++Print @var{n} copies of each page. ++ ++@item -F@var{dir} ++Put the directory @file{@var{dir}/dev@var{name}} in front of the ++search path for the font and device description files, given the ++target device @var{name}, usually @strong{lj4}. ++ ++@item -l ++Use landscape orientation. ++ ++@item -p@var{size} ++Set the page dimensions. Valid values for @var{size} are: ++@code{letter}, @code{legal}, @code{executive}, @code{a4}, ++@code{com10}, @code{monarch}, @code{c5}, @code{b5}, @code{d1}. ++ ++@item -v ++Print the version number. ++ ++@item -w@var{n} ++Set the line thickness to @var{n}/1000@dmn{em}. Overrides the ++default value @var{n} = 40. ++@end table ++ ++The special drawing command @code{\D'R @var{dh} @var{dv}'} draws a ++horizontal rectangle from the current position to the position at ++offset (@var{dh},@var{dv}). ++ ++ ++@c ===================================================================== ++ ++@node grolbp, grohtml, grolj4, Output Devices ++@section @code{grolbp} ++@cindex @code{grolbp}, the program ++ ++The postprocessor @command{grolbp} translates the output from GNU ++@command{troff} into the @strong{LBP} output format suitable for ++printing on @strong{Canon CAPSL} printers. It is fully documented on ++its manual page, @cite{grolbp(1)}. ++ ++@menu ++* Invoking grolbp:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking grolbp, , grolbp, grolbp ++@subsection Invoking @code{grolbp} ++@cindex invoking @code{grolbp} ++@cindex @code{grolbp}, invoking ++ ++The postprocessor @code{grolbp} accepts the following command-line ++options: ++ ++@table @option ++@item -c@var{n} ++Print @var{n} copies of each page. ++ ++@item -F@var{dir} ++Put the directory @file{@var{dir}/dev@var{name}} in front of the ++search path for the font, prologue and device description files, ++given the target device @var{name}, usually @strong{lbp}. ++ ++@item -l ++Use landscape orientation. ++ ++@item -o@var{orientation} ++Use the @var{orientation} specified: @code{portrait} or ++@code{landscape}. ++ ++@item -p@var{papersize} ++Set the page dimensions. See @cite{groff_font(5)} manual page for ++details. ++ ++@item -w@var{n} ++Set the line thickness to @var{n}/1000@dmn{em}. Overrides the ++default value @var{n} = 40. ++ ++@item -v ++Print the version number. ++ ++@item -h ++Print command-line help. ++@end table ++ ++ ++@c ===================================================================== ++ ++@node grohtml, gxditview, grolbp, Output Devices ++@section @code{grohtml} ++@cindex @code{grohtml}, the program ++ ++The @code{grohtml} front end (which consists of a preprocessor, ++@code{pre-grohtml}, and a device driver, @code{post-grohtml}) translates ++the output of GNU @code{troff} to @acronym{HTML}. Users should always ++invoke @code{grohtml} via the @code{groff} command with a @code{\-Thtml} ++option. If no files are given, @code{grohtml} will read the standard ++input. A filename of @code{-} will also cause @code{grohtml} to read ++the standard input. @acronym{HTML} output is written to the standard ++output. When @code{grohtml} is run by @code{groff}, options can be ++passed to @code{grohtml} using @code{groff}'s @option{-P} option. ++ ++@code{grohtml} invokes @code{groff} twice. In the first pass, pictures, ++equations, and tables are rendered using the @code{ps} device, and in ++the second pass @acronym{HTML} output is generated by the @code{html} ++device. ++ ++@code{grohtml} always writes output in @code{UTF-8} encoding and has ++built-in entities for all non-composite unicode characters. In spite of ++this, @code{groff} may issue warnings about unknown special characters ++if they can't be found during the first pass. Such warnings can be ++safely ignored unless the special characters appear inside a table or ++equation, in which case glyphs for these characters must be defined for ++the @code{ps} device as well. ++ ++This output device is fully documented on its manual page, ++@cite{grohtml(1)}. ++ ++@menu ++* Invoking grohtml:: ++* grohtml specific registers and strings:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking grohtml, grohtml specific registers and strings, grohtml, grohtml ++@subsection Invoking @code{grohtml} ++@cindex invoking @code{grohtml} ++@cindex @code{grohtml}, invoking ++ ++The postprocessor @code{grohtml} accepts the following command-line ++options: ++ ++@table @option ++@item -a@var{bits} ++Use this number of @var{bits} (= 1, 2 or 4) for text antialiasing. ++Default: @var{bits} = 4. ++ ++@item -a0 ++Do not use text antialiasing. ++ ++@item -b ++Use white background. ++ ++@item -D@var{dir} ++Store rendered images in the directory @file{@var{dir}}. ++ ++@item -F@var{dir} ++Put the directory @file{@var{dir}/dev@var{name}} in front of the ++search path for the font, prologue and device description files, ++given the target device @var{name}, usually @strong{html}. ++ ++@item -g@var{bits} ++Use this number of @var{bits} (= 1, 2 or 4) for antialiasing of ++drawings. Default: @var{bits} = 4. ++ ++@item -g0 ++Do not use antialiasing for drawings. ++ ++@item -h ++Use the @code{B} element for section headings. ++ ++@item -i@var{resolution} ++Use the @var{resolution} for rendered images. Default: ++@var{resolution} = 100@dmn{dpi}. ++ ++@item -I@var{stem} ++Set the images' @var{stem name}. Default: @var{stem} = ++@file{grohtml-@var{XXX}} (@var{XXX} is the process ID). ++ ++@item -j@var{stem} ++Place each section in a separate file called ++@file{@var{stem}-@var{n}.html} (where @var{n} is a generated section ++number). ++ ++@item -l ++Do not generate the table of contents. ++ ++@item -n ++Generate simple fragment identifiers. ++ ++@item -o@var{offset} ++Use vertical paddding @var{offset} for images. ++ ++@item -p ++Display the page rendering progress to @code{stderr}. ++ ++@item -r ++Do not use horizontal rules to separate headers and footers. ++ ++@item -s@var{size} ++Set the base font size, to be modified using the elements @code{BIG} ++and @code{SMALL}. ++ ++@item -S@var{level} ++Generate separate files for sections at level @var{level}. ++ ++@item -v ++Print the version number. ++ ++@item -V ++Generate a validator button at the bottom. ++ ++@item -y ++Generate a signature of groff after the validator button, if any. ++@end table ++ ++ ++@c --------------------------------------------------------------------- ++ ++@node grohtml specific registers and strings, , Invoking grohtml, grohtml ++@subsection @code{grohtml} specific registers and strings ++@cindex registers specific to @code{grohtml} ++@cindex strings specific to @code{grohtml} ++@cindex @code{grohtml}, registers and strings ++ ++@DefmpregList {ps4html, grohtml} ++@DefstrListEndx {www-image-template, grohtml} ++The registers @code{ps4html} and @code{www-image-template} are defined ++by the @code{pre-grohtml} preprocessor. @code{pre-grohtml} reads in the ++@code{troff} input, marks up the inline equations and passes the result ++firstly to ++ ++@Example ++troff -Tps -rps4html=1 -dwww-image-template=@var{template} ++@endExample ++ ++@noindent ++and secondly to ++ ++@Example ++troff -Thtml ++@endExample ++ ++@noindent ++or ++ ++@Example ++troff -Txhtml ++@endExample ++ ++@cindex MathML ++The @sc{PostScript} device is used to create all the image files (for ++@option{-Thtml}; if @option{-Txhtml} is used, all equations are passed ++to @code{geqn} to produce @acronym{MathML}, and the register ++@code{ps4html} enables the macro sets to ignore floating keeps, footers, ++and headings. ++ ++The register @code{www-image-template} is set to the user specified ++template name or the default name. ++@endDefmpreg ++ ++ ++@c ===================================================================== ++ ++@node gxditview, , grohtml, Output Devices ++@section @code{gxditview} ++@cindex @code{gxditview}, the program ++ ++@c XXX ++ ++@menu ++* Invoking gxditview:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Invoking gxditview, , gxditview, gxditview ++@subsection Invoking @code{gxditview} ++@cindex invoking @code{gxditview} ++@cindex @code{gxditview}, invoking ++ ++@c XXX ++@c X11's xditview ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node File formats, Installation, Output Devices, Top ++@chapter File formats ++@cindex file formats ++@cindex formats, file ++ ++All files read and written by @code{gtroff} are text files. The ++following two sections describe their format. ++ ++@menu ++* gtroff Output:: ++* Font Files:: ++@end menu ++ ++ ++@c ===================================================================== ++ ++@node gtroff Output, Font Files, File formats, File formats ++@section @code{gtroff} Output ++@cindex @code{gtroff}, output ++@cindex output, @code{gtroff} ++ ++This section describes the intermediate output format of GNU ++@code{troff}. This output is produced by a run of @code{gtroff} before ++it is fed into a device postprocessor program. ++ ++As @code{groff} is a wrapper program around @code{gtroff} that ++automatically calls a postprocessor, this output does not show up ++normally. This is why it is called @dfn{intermediate}. @code{groff} ++provides the option @option{-Z} to inhibit postprocessing, such that the ++produced intermediate output is sent to standard output just like ++calling @code{gtroff} manually. ++ ++@cindex troff output ++@cindex output, troff ++@cindex intermediate output ++@cindex output, intermediate ++Here, the term @dfn{troff output} describes what is output by ++@code{gtroff}, while @dfn{intermediate output} refers to the language ++that is accepted by the parser that prepares this output for the ++postprocessors. This parser is smarter on whitespace and implements ++obsolete elements for compatibility, otherwise both formats are the ++same.@footnote{The parser and postprocessor for intermediate output can ++be found in the file@* ++@file{@var{groff-source-dir}/src/libs/libdriver/input.cpp}.} ++ ++The main purpose of the intermediate output concept is to facilitate the ++development of postprocessors by providing a common programming ++interface for all devices. It has a language of its own that is ++completely different from the @code{gtroff} language. While the ++@code{gtroff} language is a high-level programming language for text ++processing, the intermediate output language is a kind of low-level ++assembler language by specifying all positions on the page for writing ++and drawing. ++ ++The intermediate output produced by @code{gtroff} is fairly readable, ++while output from @acronym{AT&T} @code{troff} is rather hard to ++understand because of strange habits that are still supported, but not ++used any longer by @code{gtroff}. ++ ++@menu ++* Language Concepts:: ++* Command Reference:: ++* Intermediate Output Examples:: ++* Output Language Compatibility:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node Language Concepts, Command Reference, gtroff Output, gtroff Output ++@subsection Language Concepts ++ ++During the run of @code{gtroff}, the input data is cracked down to the ++information on what has to be printed at what position on the intended ++device. So the language of the intermediate output format can be quite ++small. Its only elements are commands with and without arguments. In ++this section, the term @dfn{command} always refers to the intermediate ++output language, and never to the @code{gtroff} language used for ++document formatting. There are commands for positioning and text ++writing, for drawing, and for device controlling. ++ ++@menu ++* Separation:: ++* Argument Units:: ++* Document Parts:: ++@end menu ++ ++@node Separation, Argument Units, Language Concepts, Language Concepts ++@subsubsection Separation ++ ++@acronym{AT&T} @code{troff} output has strange requirements on ++whitespace. The @code{gtroff} output parser, however, is smart about ++whitespace by making it maximally optional. The whitespace characters, ++i.e., the tab, space, and newline characters, always have a syntactical ++meaning. They are never printable because spacing within the output is ++always done by positioning commands. ++ ++Any sequence of space or tab characters is treated as a single ++@dfn{syntactical space}. It separates commands and arguments, but is ++only required when there would occur a clashing between the command code ++and the arguments without the space. Most often, this happens when ++variable-length command names, arguments, argument lists, or command ++clusters meet. Commands and arguments with a known, fixed length need ++not be separated by syntactical space. ++ ++A line break is a syntactical element, too. Every command argument can ++be followed by whitespace, a comment, or a newline character. Thus a ++@dfn{syntactical line break} is defined to consist of optional ++syntactical space that is optionally followed by a comment, and a ++newline character. ++ ++The normal commands, those for positioning and text, consist of a single ++letter taking a fixed number of arguments. For historical reasons, the ++parser allows to stack such commands on the same line, but fortunately, ++in @code{gtroff}'s intermediate output, every command with at least one ++argument is followed by a line break, thus providing excellent ++readability. ++ ++The other commands -- those for drawing and device controlling -- have a ++more complicated structure; some recognize long command names, and some ++take a variable number of arguments. So all @samp{D} and @samp{x} ++commands were designed to request a syntactical line break after their ++last argument. Only one command, @w{@samp{x X}}, has an argument that ++can stretch over several lines; all other commands must have all of ++their arguments on the same line as the command, i.e., the arguments may ++not be split by a line break. ++ ++Empty lines (these are lines containing only space and/or a comment), ++can occur everywhere. They are just ignored. ++ ++@node Argument Units, Document Parts, Separation, Language Concepts ++@subsubsection Argument Units ++ ++Some commands take integer arguments that are assumed to represent ++values in a measurement unit, but the letter for the corresponding scale ++indicator is not written with the output command arguments. Most ++commands assume the scale indicator @samp{u}, the basic unit of the ++device, some use @samp{z}, the scaled point unit of the device, while ++others, such as the color commands, expect plain integers. ++ ++Note that single characters can have the eighth bit set, as can the ++names of fonts and special characters. The names of characters and ++fonts can be of arbitrary length. A character that is to be printed is ++always in the current font. ++ ++A string argument is always terminated by the next whitespace character ++(space, tab, or newline); an embedded @samp{#} character is regarded as ++part of the argument, not as the beginning of a comment command. An ++integer argument is already terminated by the next non-digit character, ++which then is regarded as the first character of the next argument or ++command. ++ ++@node Document Parts, , Argument Units, Language Concepts ++@subsubsection Document Parts ++ ++A correct intermediate output document consists of two parts, the ++@dfn{prologue} and the @dfn{body}. ++ ++The task of the prologue is to set the general device parameters using ++three exactly specified commands. @code{gtroff}'s prologue is ++guaranteed to consist of the following three lines (in that order): ++ ++@Example ++x T @var{device} ++x res @var{n} @var{h} @var{v} ++x init ++@endExample ++ ++@noindent ++with the arguments set as outlined in @ref{Device Control Commands}. ++Note that the parser for the intermediate output format is able to ++swallow additional whitespace and comments as well even in the prologue. ++ ++The body is the main section for processing the document data. ++Syntactically, it is a sequence of any commands different from the ones ++used in the prologue. Processing is terminated as soon as the first ++@w{@samp{x stop}} command is encountered; the last line of any ++@code{gtroff} intermediate output always contains such a command. ++ ++Semantically, the body is page oriented. A new page is started by a ++@samp{p} command. Positioning, writing, and drawing commands are always ++done within the current page, so they cannot occur before the first ++@samp{p} command. Absolute positioning (by the @samp{H} and @samp{V} ++commands) is done relative to the current page; all other positioning is ++done relative to the current location within this page. ++ ++@c --------------------------------------------------------------------- ++ ++@node Command Reference, Intermediate Output Examples, Language Concepts, gtroff Output ++@subsection Command Reference ++ ++This section describes all intermediate output commands, both from ++@acronym{AT&T} @code{troff} as well as the @code{gtroff} extensions. ++ ++@menu ++* Comment Command:: ++* Simple Commands:: ++* Graphics Commands:: ++* Device Control Commands:: ++* Obsolete Command:: ++@end menu ++ ++@node Comment Command, Simple Commands, Command Reference, Command Reference ++@subsubsection Comment Command ++ ++@table @code ++@item #@var{anything}@angles{end of line} ++A comment. Ignore any characters from the @samp{#} character up to the ++next newline character. ++ ++This command is the only possibility for commenting in the intermediate ++output. Each comment can be preceded by arbitrary syntactical space; ++every command can be terminated by a comment. ++@end table ++ ++@node Simple Commands, Graphics Commands, Comment Command, Command Reference ++@subsubsection Simple Commands ++ ++The commands in this subsection have a command code consisting of a ++single character, taking a fixed number of arguments. Most of them are ++commands for positioning and text writing. These commands are smart ++about whitespace. Optionally, syntactical space can be inserted before, ++after, and between the command letter and its arguments. All of these ++commands are stackable, i.e., they can be preceded by other simple ++commands or followed by arbitrary other commands on the same line. A ++separating syntactical space is only necessary when two integer ++arguments would clash or if the preceding argument ends with a string ++argument. ++ ++@table @code ++@ignore ++.if (\n[@USE_ENV_STACK] == 1) \{\ ++.command { ++Open a new environment by copying the actual device configuration data ++to the environment stack. ++. ++The current environment is setup by the device specification and ++manipulated by the setting commands. ++. ++. ++.command } ++Close the actual environment (opened by a preceding ++.BR { \~command) ++and restore the previous environment from the environment ++stack as the actual device configuration data. ++. ++\} \" endif @USE_ENV_STACK ++@end ignore ++ ++@item C @var{xxx}@angles{whitespace} ++Print a special character named @var{xxx}. The trailing syntactical ++space or line break is necessary to allow glyph names of arbitrary ++length. The glyph is printed at the current print position; the glyph's ++size is read from the font file. The print position is not changed. ++ ++@item c @var{g} ++Print glyph@tie{}@var{g} at the current print ++position;@footnote{@samp{c} is actually a misnomer since it outputs a ++glyph.} the glyph's size is read from the font file. The print position ++is not changed. ++ ++@item f @var{n} ++Set font to font number@tie{}@var{n} (a non-negative integer). ++ ++@item H @var{n} ++Move right to the absolute vertical position@tie{}@var{n} (a ++non-negative integer in basic units @samp{u} relative to left edge of ++current page. ++ ++@item h @var{n} ++Move @var{n} (a non-negative integer) basic units @samp{u} horizontally ++to the right. The original @acronym{UNIX} troff manual allows negative ++values for @var{n} also, but @code{gtroff} doesn't use this. ++ ++@item m @var{color-scheme} @r{[}@var{component} @dots{}@r{]} ++Set the color for text (glyphs), line drawing, and the outline of ++graphic objects using different color schemes; the analoguous command ++for the filling color of graphic objects is @samp{DF}. The color ++components are specified as integer arguments between 0 and 65536. The ++number of color components and their meaning vary for the different ++color schemes. These commands are generated by @code{gtroff}'s escape ++sequence @code{\m}. No position changing. These commands are a ++@code{gtroff} extension. ++ ++@table @code ++@item mc @var{cyan} @var{magenta} @var{yellow} ++Set color using the CMY color scheme, having the 3@tie{}color components ++@var{cyan}, @var{magenta}, and @var{yellow}. ++ ++@item md ++Set color to the default color value (black in most cases). No ++component arguments. ++ ++@item mg @var{gray} ++Set color to the shade of gray given by the argument, an integer between ++0 (black) and 65536 (white). ++ ++@item mk @var{cyan} @var{magenta} @var{yellow} @var{black} ++Set color using the CMYK color scheme, having the 4@tie{}color ++components @var{cyan}, @var{magenta}, @var{yellow}, and @var{black}. ++ ++@item mr @var{red} @var{green} @var{blue} ++Set color using the RGB color scheme, having the 3@tie{}color components ++@var{red}, @var{green}, and @var{blue}. ++@end table ++ ++@item N @var{n} ++Print glyph with index@tie{}@var{n} (a non-negative integer) of the ++current font. This command is a @code{gtroff} extension. ++ ++@item n @var{b} @var{a} ++Inform the device about a line break, but no positioning is done by this ++command. In @acronym{AT&T} @code{troff}, the integer arguments @var{b} ++and@tie{}@var{a} informed about the space before and after the current ++line to make the intermediate output more human readable without ++performing any action. In @code{groff}, they are just ignored, but they ++must be provided for compatibility reasons. ++ ++@item p @var{n} ++Begin a new page in the outprint. The page number is set ++to@tie{}@var{n}. This page is completely independent of pages formerly ++processed even if those have the same page number. The vertical ++position on the outprint is automatically set to@tie{}0. All ++positioning, writing, and drawing is always done relative to a page, so ++a @samp{p} command must be issued before any of these commands. ++ ++@item s @var{n} ++Set point size to @var{n}@tie{}scaled points (this is unit @samp{z}). ++@acronym{AT&T} @code{troff} used the unit points (@samp{p}) instead. ++@xref{Output Language Compatibility}. ++ ++@item t @var{xxx}@angles{whitespace} ++@itemx t @var{xxx} @var{dummy-arg}@angles{whitespace} ++Print a word, i.e., a sequence of characters @var{xxx} representing ++output glyphs which names are single characters, terminated by a space ++character or a line break; an optional second integer argument is ++ignored (this allows the formatter to generate an even number of ++arguments). The first glyph should be printed at the current position, ++the current horizontal position should then be increased by the width of ++the first glyph, and so on for each glyph. The widths of the glyphs are ++read from the font file, scaled for the current point size, and rounded ++to a multiple of the horizontal resolution. Special characters cannot ++be printed using this command (use the @samp{C} command for special ++characters). This command is a @code{gtroff} extension; it is only used ++for devices whose @file{DESC} file contains the @code{tcommand} keyword ++(@pxref{DESC File Format}). ++ ++@item u @var{n} @var{xxx}@angles{whitespace} ++Print word with track kerning. This is the same as the @samp{t} command ++except that after printing each glyph, the current horizontal position ++is increased by the sum of the width of that glyph and@tie{}@var{n} (an ++integer in basic units @samp{u}). This command is a @code{gtroff} ++extension; it is only used for devices whose @file{DESC} file contains ++the @code{tcommand} keyword (@pxref{DESC File Format}). ++ ++@item V @var{n} ++Move down to the absolute vertical position@tie{}@var{n} (a non-negative ++integer in basic units @samp{u}) relative to upper edge of current page. ++ ++@item v @var{n} ++Move @var{n}@tie{}basic units @samp{u} down (@var{n} is a non-negative ++integer). The original @acronym{UNIX} troff manual allows negative ++values for @var{n} also, but @code{gtroff} doesn't use this. ++ ++@item w ++Informs about a paddable white space to increase readability. The ++spacing itself must be performed explicitly by a move command. ++@end table ++ ++@node Graphics Commands, Device Control Commands, Simple Commands, Command Reference ++@subsubsection Graphics Commands ++ ++Each graphics or drawing command in the intermediate output starts with ++the letter @samp{D}, followed by one or two characters that specify a ++subcommand; this is followed by a fixed or variable number of integer ++arguments that are separated by a single space character. A @samp{D} ++command may not be followed by another command on the same line (apart ++from a comment), so each @samp{D} command is terminated by a syntactical ++line break. ++ ++@code{gtroff} output follows the classical spacing rules (no space ++between command and subcommand, all arguments are preceded by a single ++space character), but the parser allows optional space between the ++command letters and makes the space before the first argument optional. ++As usual, each space can be any sequence of tab and space characters. ++ ++Some graphics commands can take a variable number of arguments. In this ++case, they are integers representing a size measured in basic units ++@samp{u}. The arguments called @var{h1}, @var{h2}, @dots{}, @var{hn} ++stand for horizontal distances where positive means right, negative ++left. The arguments called @var{v1}, @var{v2}, @dots{}, @var{vn} stand ++for vertical distances where positive means down, negative up. All ++these distances are offsets relative to the current location. ++ ++Each graphics command directly corresponds to a similar @code{gtroff} ++@code{\D} escape sequence. @xref{Drawing Requests}. ++ ++Unknown @samp{D} commands are assumed to be device-specific. Its ++arguments are parsed as strings; the whole information is then sent to ++the postprocessor. ++ ++In the following command reference, the syntax element @angles{line ++break} means a syntactical line break as defined above. ++ ++@table @code ++@item D~ @var{h1} @var{v1} @var{h2} @var{v2} @dots{} @var{hn} @var{vn}@angles{line break} ++Draw B-spline from current position to offset (@var{h1},@var{v1}), then ++to offset (@var{h2},@var{v2}), if given, etc.@: up to ++(@var{hn},@var{vn}). This command takes a variable number of argument ++pairs; the current position is moved to the terminal point of the drawn ++curve. ++ ++@item Da @var{h1} @var{v1} @var{h2} @var{v2}@angles{line break} ++Draw arc from current position to ++(@var{h1},@var{v1})@math{+}(@var{h2},@var{v2}) with center at ++(@var{h1},@var{v1}); then move the current position to the final point ++of the arc. ++ ++@item DC @var{d}@angles{line break} ++@itemx DC @var{d} @var{dummy-arg}@angles{line break} ++Draw a solid circle using the current fill color with ++diameter@tie{}@var{d} (integer in basic units @samp{u}) with leftmost ++point at the current position; then move the current position to the ++rightmost point of the circle. An optional second integer argument is ++ignored (this allows the formatter to generate an even number of ++arguments). This command is a @code{gtroff} extension. ++ ++@item Dc @var{d}@angles{line break} ++Draw circle line with diameter@tie{}@var{d} (integer in basic units ++@samp{u}) with leftmost point at the current position; then move the ++current position to the rightmost point of the circle. ++ ++@item DE @var{h} @var{v}@angles{line break} ++Draw a solid ellipse in the current fill color with a horizontal ++diameter of@tie{}@var{h} and a vertical diameter of@tie{}@var{v} (both ++integers in basic units @samp{u}) with the leftmost point at the current ++position; then move to the rightmost point of the ellipse. This command ++is a @code{gtroff} extension. ++ ++@item De @var{h} @var{v}@angles{line break} ++Draw an outlined ellipse with a horizontal diameter of@tie{}@var{h} and ++a vertical diameter of@tie{}@var{v} (both integers in basic units ++@samp{u}) with the leftmost point at current position; then move to the ++rightmost point of the ellipse. ++ ++@item DF @var{color-scheme} @r{[}@var{component} @dots{}@r{]}@angles{line break} ++Set fill color for solid drawing objects using different color schemes; ++the analoguous command for setting the color of text, line graphics, and ++the outline of graphic objects is @samp{m}. The color components are ++specified as integer arguments between 0 and 65536. The number of color ++components and their meaning vary for the different color schemes. ++These commands are generated by @code{gtroff}'s escape sequences ++@w{@code{\D'F @dots{}'}} and @code{\M} (with no other corresponding ++graphics commands). No position changing. This command is a ++@code{gtroff} extension. ++ ++@table @code ++@item DFc @var{cyan} @var{magenta} @var{yellow}@angles{line break} ++Set fill color for solid drawing objects using the CMY color scheme, ++having the 3@tie{}color components @var{cyan}, @var{magenta}, and ++@var{yellow}. ++ ++@item DFd@angles{line break} ++Set fill color for solid drawing objects to the default fill color value ++(black in most cases). No component arguments. ++ ++@item DFg @var{gray}@angles{line break} ++Set fill color for solid drawing objects to the shade of gray given by ++the argument, an integer between 0 (black) and 65536 (white). ++ ++@item DFk @var{cyan} @var{magenta} @var{yellow} @var{black}@angles{line break} ++Set fill color for solid drawing objects using the CMYK color scheme, ++having the 4@tie{}color components @var{cyan}, @var{magenta}, ++@var{yellow}, and @var{black}. ++ ++@item DFr @var{red} @var{green} @var{blue}@angles{line break} ++Set fill color for solid drawing objects using the RGB color scheme, ++having the 3@tie{}color components @var{red}, @var{green}, and ++@var{blue}. ++@end table ++ ++@item Df @var{n}@angles{line break} ++The argument@tie{}@var{n} must be an integer in the range @math{-32767} ++to 32767. ++ ++@table @asis ++@item @math{0 @value{LE} @var{n} @value{LE} 1000} ++Set the color for filling solid drawing objects to a shade of gray, ++where 0 corresponds to solid white, 1000 (the default) to solid black, ++and values in between to intermediate shades of gray; this is obsoleted ++by command @samp{DFg}. ++ ++@item @math{@var{n} < 0} or @math{@var{n} > 1000} ++Set the filling color to the color that is currently being used for the ++text and the outline, see command @samp{m}. For example, the command ++sequence ++ ++@Example ++mg 0 0 65536 ++Df -1 ++@endExample ++ ++@noindent ++sets all colors to blue. ++@end table ++ ++@noindent ++No position changing. This command is a @code{gtroff} extension. ++ ++@item Dl @var{h} @var{v}@angles{line break} ++Draw line from current position to offset (@var{h},@var{v}) (integers in ++basic units @samp{u}); then set current position to the end of the drawn ++line. ++ ++@item Dp @var{h1} @var{v1} @var{h2} @var{v2} @dots{} @var{hn} @var{vn}@angles{line break} ++Draw a polygon line from current position to offset (@var{h1},@var{v1}), ++from there to offset (@var{h2},@var{v2}), etc.@: up to offset ++(@var{hn},@var{vn}), and from there back to the starting position. For ++historical reasons, the position is changed by adding the sum of all ++arguments with odd index to the actual horizontal position and the even ++ones to the vertical position. Although this doesn't make sense it is ++kept for compatibility. ++@ignore ++As the polygon is closed, the end of drawing is the starting point, so ++the position doesn't change. ++@end ignore ++This command is a @code{gtroff} extension. ++ ++@item Dp @var{h1} @var{v1} @var{h2} @var{v2} @dots{} @var{hn} @var{vn}@angles{line break} ++Draw a solid polygon in the current fill color rather than an outlined ++polygon, using the same arguments and positioning as the corresponding ++@samp{Dp} command. ++@ignore ++No position changing. ++@end ignore ++This command is a @code{gtroff} extension. ++ ++@item Dt @var{n}@angles{line break} ++Set the current line thickness to@tie{}@var{n} (an integer in basic ++units @samp{u}) if @math{@var{n}>0}; if @math{@var{n}=0} select the ++smallest available line thickness; if @math{@var{n}<0} set the line ++thickness proportional to the point size (this is the default before the ++first @samp{Dt} command was specified). For historical reasons, the ++horizontal position is changed by adding the argument to the actual ++horizontal position, while the vertical position is not changed. ++Although this doesn't make sense it is kept for compatibility. ++@ignore ++No position changing. ++@end ignore ++This command is a @code{gtroff} extension. ++@end table ++ ++@node Device Control Commands, Obsolete Command, Graphics Commands, Command Reference ++@subsubsection Device Control Commands ++ ++Each device control command starts with the letter @samp{x}, followed by ++a space character (optional or arbitrary space or tab in @code{gtroff}) ++and a subcommand letter or word; each argument (if any) must be preceded ++by a syntactical space. All @samp{x} commands are terminated by a ++syntactical line break; no device control command can be followed by ++another command on the same line (except a comment). ++ ++The subcommand is basically a single letter, but to increase ++readability, it can be written as a word, i.e., an arbitrary sequence of ++characters terminated by the next tab, space, or newline character. All ++characters of the subcommand word but the first are simply ignored. For ++example, @code{gtroff} outputs the initialization command @w{@samp{x i}} ++as @w{@samp{x init}} and the resolution command @w{@samp{x r}} as ++@w{@samp{x res}}. ++ ++In the following, the syntax element @angles{line break} means a ++syntactical line break (@pxref{Separation}). ++ ++@table @code ++@item xF @var{name}@angles{line break} ++The @samp{F} stands for @var{Filename}. ++ ++Use @var{name} as the intended name for the current file in error ++reports. This is useful for remembering the original file name when ++@code{gtroff} uses an internal piping mechanism. The input file is not ++changed by this command. This command is a @code{gtroff} extension. ++ ++@item xf @var{n} @var{s}@angles{line break} ++The @samp{f} stands for @var{font}. ++ ++Mount font position@tie{}@var{n} (a non-negative integer) with font ++named@tie{}@var{s} (a text word). @xref{Font Positions}. ++ ++@item xH @var{n}@angles{line break} ++The @samp{H} stands for @var{Height}. ++ ++Set glyph height to@tie{}@var{n} (a positive integer in scaled points ++@samp{z}). @acronym{AT&T} @code{troff} uses the unit points (@samp{p}) ++instead. @xref{Output Language Compatibility}. ++ ++@item xi@angles{line break} ++The @samp{i} stands for @var{init}. ++ ++Initialize device. This is the third command of the prologue. ++ ++@item xp@angles{line break} ++The @samp{p} stands for @var{pause}. ++ ++Parsed but ignored. The original @acronym{UNIX} troff manual writes ++ ++@display ++pause device, can be restarted ++@end display ++ ++@item xr @var{n} @var{h} @var{v}@angles{line break} ++The @samp{r} stands for @var{resolution}. ++ ++Resolution is@tie{}@var{n}, while @var{h} is the minimal horizontal ++motion, and @var{v} the minimal vertical motion possible with this ++device; all arguments are positive integers in basic units @samp{u} per ++inch. This is the second command of the prologue. ++ ++@item xS @var{n}@angles{line break} ++The @samp{S} stands for @var{Slant}. ++ ++Set slant to@tie{}@var{n} (an integer in basic units @samp{u}). ++ ++@item xs@angles{line break} ++The @samp{s} stands for @var{stop}. ++ ++Terminates the processing of the current file; issued as the last ++command of any intermediate troff output. ++ ++@item xt@angles{line break} ++The @samp{t} stands for @var{trailer}. ++ ++Generate trailer information, if any. In @var{gtroff}, this is actually ++just ignored. ++ ++@item xT @var{xxx}@angles{line break} ++The @samp{T} stands for @var{Typesetter}. ++ ++Set name of device to word @var{xxx}, a sequence of characters ended by ++the next white space character. The possible device names coincide with ++those from the @code{groff} @option{-T} option. This is the first ++command of the prologue. ++ ++@item xu @var{n}@angles{line break} ++The @samp{u} stands for @var{underline}. ++ ++Configure underlining of spaces. If @var{n} is@tie{}1, start ++underlining of spaces; if @var{n} is@tie{}0, stop underlining of spaces. ++This is needed for the @code{cu} request in nroff mode and is ignored ++otherwise. This command is a @code{gtroff} extension. ++ ++@item xX @var{anything}@angles{line break} ++The @samp{x} stands for @var{X-escape}. ++ ++Send string @var{anything} uninterpreted to the device. If the line ++following this command starts with a @samp{+} character this line is ++interpreted as a continuation line in the following sense. The @samp{+} ++is ignored, but a newline character is sent instead to the device, the ++rest of the line is sent uninterpreted. The same applies to all ++following lines until the first character of a line is not a @samp{+} ++character. This command is generated by the @code{gtroff} escape ++sequence @code{\X}. The line-continuing feature is a @code{gtroff} ++extension. ++@end table ++ ++@node Obsolete Command, , Device Control Commands, Command Reference ++@subsubsection Obsolete Command ++In @acronym{AT&T} @code{troff} output, the writing of a single glyph is ++mostly done by a very strange command that combines a horizontal move ++and a single character giving the glyph name. It doesn't have a command ++code, but is represented by a 3-character argument consisting of exactly ++2@tie{}digits and a character. ++ ++@table @asis ++@item @var{dd}@var{g} ++Move right @var{dd} (exactly two decimal digits) basic units @samp{u}, ++then print glyph@tie{}@var{g} (represented as a single character). ++ ++In @code{gtroff}, arbitrary syntactical space around and within this ++command is allowed to be added. Only when a preceding command on the ++same line ends with an argument of variable length a separating space is ++obligatory. In @acronym{AT&T} @code{troff}, large clusters of these and ++other commands are used, mostly without spaces; this made such output ++almost unreadable. ++@end table ++ ++For modern high-resolution devices, this command does not make sense ++because the width of the glyphs can become much larger than two decimal ++digits. In @code{gtroff}, this is only used for the devices @code{X75}, ++@code{X75-12}, @code{X100}, and @code{X100-12}. For other devices, the ++commands @samp{t} and @samp{u} provide a better functionality. ++ ++@c --------------------------------------------------------------------- ++ ++@node Intermediate Output Examples, Output Language Compatibility, Command Reference, gtroff Output ++@subsection Intermediate Output Examples ++ ++This section presents the intermediate output generated from the same ++input for three different devices. The input is the sentence @samp{hell ++world} fed into @code{gtroff} on the command line. ++ ++@table @asis ++@item High-resolution device @code{ps} ++ ++This is the standard output of @code{gtroff} if no @option{-T} option is ++given. ++ ++@example ++@group ++shell> echo "hell world" | groff -Z -T ps ++ ++x T ps ++x res 72000 1 1 ++x init ++@end group ++p1 ++x font 5 TR ++f5 ++s10000 ++V12000 ++H72000 ++thell ++wh2500 ++tw ++H96620 ++torld ++n12000 0 ++@group ++x trailer ++V792000 ++x stop ++@end group ++@end example ++ ++@noindent ++This output can be fed into @code{grops} to get its representation as a ++@sc{PostScript} file. ++ ++@item Low-resolution device @code{latin1} ++ ++This is similar to the high-resolution device except that the ++positioning is done at a minor scale. Some comments (lines starting ++with @samp{#}) were added for clarification; they were not generated by ++the formatter. ++ ++@example ++@group ++shell> echo "hell world" | groff -Z -T latin1 ++ ++# prologue ++x T latin1 ++x res 240 24 40 ++x init ++@end group ++# begin a new page ++p1 ++# font setup ++x font 1 R ++f1 ++s10 ++# initial positioning on the page ++V40 ++H0 ++# write text `hell' ++thell ++# inform about space, and issue a horizontal jump ++wh24 ++# write text `world' ++tworld ++# announce line break, but do nothing because ... ++n40 0 ++@group ++# ... the end of the document has been reached ++x trailer ++V2640 ++x stop ++@end group ++@end example ++ ++@noindent ++This output can be fed into @code{grotty} to get a formatted text ++document. ++ ++@item @acronym{AT&T} @code{troff} output ++Since a computer monitor has a very low resolution compared to modern ++printers the intermediate output for the X@tie{}Window devices can use ++the jump-and-write command with its 2-digit displacements. ++ ++@example ++@group ++shell> echo "hell world" | groff -Z -T X100 ++ ++x T X100 ++x res 100 1 1 ++x init ++@end group ++p1 ++x font 5 TR ++f5 ++s10 ++V16 ++H100 ++# write text with jump-and-write commands ++ch07e07l03lw06w11o07r05l03dh7 ++n16 0 ++@group ++x trailer ++V1100 ++x stop ++@end group ++@end example ++ ++@noindent ++This output can be fed into @code{xditview} or @code{gxditview} for ++displaying in@tie{}X. ++ ++Due to the obsolete jump-and-write command, the text clusters in the ++@acronym{AT&T} @code{troff} output are almost unreadable. ++@end table ++ ++@c --------------------------------------------------------------------- ++ ++@node Output Language Compatibility, , Intermediate Output Examples, gtroff Output ++@subsection Output Language Compatibility ++ ++The intermediate output language of @acronym{AT&T} @code{troff} was ++first documented in the @acronym{UNIX} troff manual, with later ++additions documented in @cite{A Typesetter-indenpendent TROFF}, written ++by Brian Kernighan. ++ ++The @code{gtroff} intermediate output format is compatible with this ++specification except for the following features. ++ ++@itemize @bullet ++@item ++The classical quasi device independence is not yet implemented. ++ ++@item ++The old hardware was very different from what we use today. So the ++@code{groff} devices are also fundamentally different from the ones ++in @acronym{AT&T} @code{troff}. For example, the @acronym{AT&T} ++@sc{PostScript} device is called @code{post} and has a resolution of ++only 720 units per inch, suitable for printers 20 years ago, while ++@code{groff}'s @code{ps} device has a resolution of 72000 units per ++inch. Maybe, by implementing some rescaling mechanism similar to the ++classical quasi device independence, @code{groff} could emulate ++@acronym{AT&T}'s @code{post} device. ++ ++@item ++The B-spline command @samp{D~} is correctly handled by the intermediate ++output parser, but the drawing routines aren't implemented in some of ++the postprocessor programs. ++ ++@item ++The argument of the commands @samp{s} and @w{@samp{x H}} has the ++implicit unit scaled point @samp{z} in @code{gtroff}, while ++@acronym{AT&T} @code{troff} has point (@samp{p}). This isn't an ++incompatibility but a compatible extension, for both units coincide for ++all devices without a @code{sizescale} parameter in the @file{DESC} ++file, including all postprocessors from @acronym{AT&T} and ++@code{groff}'s text devices. The few @code{groff} devices with a ++@code{sizescale} parameter either do not exist for @acronym{AT&T} ++@code{troff}, have a different name, or seem to have a different ++resolution. So conflicts are very unlikely. ++ ++@item ++The position changing after the commands @samp{Dp}, @samp{DP}, and ++@samp{Dt} is illogical, but as old versions of @code{gtroff} used this ++feature it is kept for compatibility reasons. ++ ++@ignore ++Temporarily, there existed some confusion on the positioning after the ++@samp{D} commands that are groff extensions. This has been clarified by ++establishing the classical rule for all @code{groff} drawing commands: ++ ++@itemize ++@item ++The position after a graphic object has been drawn is at its end; for ++circles and ellipses, the `end' is at the right side. ++ ++@item ++From this, the positionings specified for the drawing commands above ++follow quite naturally. ++@end itemize ++@end ignore ++ ++@end itemize ++ ++ ++@c ===================================================================== ++ ++@node Font Files, , gtroff Output, File formats ++@section Font Files ++@cindex font files ++@cindex files, font ++ ++The @code{gtroff} font format is roughly a superset of the ++@code{ditroff} font format (as used in later versions of @acronym{AT&T} ++@code{troff} and its descendants). Unlike the @code{ditroff} font ++format, there is no associated binary format; all files are text ++files.@footnote{Plan@tie{}9 @code{troff} has also abandoned the binary ++format.} The font files for device @var{name} are stored in a directory ++@file{dev@var{name}}. There are two types of file: a device description ++file called @file{DESC} and for each font@tie{}@var{f} a font file ++called@tie{}@file{@var{f}}. ++ ++@menu ++* DESC File Format:: ++* Font File Format:: ++@end menu ++ ++@c --------------------------------------------------------------------- ++ ++@node DESC File Format, Font File Format, Font Files, Font Files ++@subsection @file{DESC} File Format ++@cindex @file{DESC} file, format ++@cindex font description file, format ++@cindex format of font description file ++@pindex DESC@r{ file format} ++ ++The @file{DESC} file can contain the following types of line. Except ++for the @code{charset} keyword, which must comes last (if at all), the ++order of the lines is not important. Later entries in the file, ++however, override previous values. ++ ++@table @code ++@item charset ++@kindex charset ++This line and everything following in the file are ignored. It is ++allowed for the sake of backwards compatibility. ++ ++@item family @var{fam} ++@kindex family ++The default font family is @var{fam}. ++ ++@item fonts @var{n} @var{F1} @var{F2} @var{F3} @dots{} @var{Fn} ++@kindex fonts ++Fonts @var{F1} @dots{} @var{Fn} are mounted in the font positions ++@var{m}+1, @dots{}, @var{m}+@var{n} where @var{m} is the number of ++styles. This command may extend over more than one line. A font name ++of@tie{}0 means no font is mounted on the corresponding font position. ++ ++@item hor @var{n} ++@kindex hor ++@cindex horizontal resolution ++@cindex resolution, horizontal ++The horizontal resolution is @var{n}@tie{}machine units. All horizontal ++quantities are rounded to be multiples of this value. ++ ++@item image_generator @var{string} ++@kindex image_generator ++@cindex PostScript, PNG image generation ++@cindex PNG image generation from PostScript ++Needed for @code{grohtml} only. It specifies the program to generate ++PNG images from @sc{PostScript} input. Under GNU/Linux this is ++usually @code{gs} but under other systems (notably cygwin) it might ++be set to another name. ++ ++@item paperlength @var{n} ++@kindex paperlength ++The physical vertical dimension of the output medium in machine units. ++This isn't used by @code{troff} itself but by output devices. ++Deprecated. Use @code{papersize} instead. ++ ++@item papersize @var{string} @dots{} ++@kindex papersize ++Select a paper size. Valid values for @var{string} are the ISO paper ++types @code{A0}-@code{A7}, @code{B0}-@code{B7}, @code{C0}-@code{C7}, ++@code{D0}-@code{D7}, @code{DL}, and the US paper types @code{letter}, ++@code{legal}, @code{tabloid}, @code{ledger}, @code{statement}, ++@code{executive}, @code{com10}, and @code{monarch}. Case is not ++significant for @var{string} if it holds predefined paper types. ++Alternatively, @var{string} can be a file name (e.g.@: ++@file{/etc/papersize}); if the file can be opened, @code{groff} reads ++the first line and tests for the above paper sizes. Finally, ++@var{string} can be a custom paper size in the format ++@code{@var{length},@var{width}} (no spaces before and after the comma). ++Both @var{length} and @var{width} must have a unit appended; valid ++values are @samp{i} for inches, @samp{C} for centimeters, @samp{p} for ++points, and @samp{P} for picas. Example: @code{12c,235p}. An argument ++that starts with a digit is always treated as a custom paper format. ++@code{papersize} sets both the vertical and horizontal dimension of the ++output medium. ++ ++More than one argument can be specified; @code{groff} scans from left to ++right and uses the first valid paper specification. ++ ++@item paperwidth @var{n} ++@kindex paperwidth ++The physical horizontal dimension of the output medium in machine units. ++This isn't used by @code{troff} itself but by output devices. ++Deprecated. Use @code{papersize} instead. ++ ++@item pass_filenames ++@kindex pass_filenames ++Tell @code{gtroff} to emit the name of the source file currently being ++processed. This is achieved by the intermediate output command ++@samp{F}. Currently, this is only used by the @code{grohtml} output ++device. ++ ++@item postpro @var{program} ++@kindex postpro ++Call @var{program} as a postprocessor. For example, the line ++ ++@Example ++postpro grodvi ++@endExample ++ ++@noindent ++in the file @file{devdvi/DESC} makes @code{groff} call @code{grodvi} if ++option @option{-Tdvi} is given (and @option{-Z} isn't used). ++ ++@item prepro @var{program} ++@kindex prepro ++Call @var{program} as a preprocessor. Currently, this keyword is used ++by @code{groff} with option @option{-Thtml} or @option{-Txhtml} only. ++ ++@item print @var{program} ++@kindex print ++Use @var{program} as a spooler program for printing. If omitted, the ++@option{-l} and @option{-L} options of @code{groff} are ignored. ++ ++@item res @var{n} ++@kindex res ++@cindex device resolution ++@cindex resolution, device ++There are @var{n}@tie{}machine units per inch. ++ ++@item sizes @var{s1} @var{s2} @dots{} @var{sn} 0 ++@kindex sizes ++This means that the device has fonts at @var{s1}, @var{s2}, @dots{} ++@var{sn} scaled points. The list of sizes must be terminated by@tie{}0 ++(this is digit zero). Each @var{si} can also be a range of sizes ++@var{m}-@var{n}. The list can extend over more than one line. ++ ++@item sizescale @var{n} ++@kindex sizescale ++The scale factor for point sizes. By default this has a value ++of@tie{}1. One scaled point is equal to one point/@var{n}. The ++arguments to the @code{unitwidth} and @code{sizes} commands are given in ++scaled points. @xref{Fractional Type Sizes}, for more information. ++ ++@item styles @var{S1} @var{S2} @dots{} @var{Sm} ++@kindex styles ++The first @var{m}@tie{}font positions are associated with styles ++@var{S1} @dots{} @var{Sm}. ++ ++@item tcommand ++@kindex tcommand ++This means that the postprocessor can handle the @samp{t} and @samp{u} ++intermediate output commands. ++ ++@item unicode ++@kindex unicode ++Indicate that the output device supports the complete Unicode ++repertoire. Useful only for devices that produce @emph{character ++entities} instead of glyphs. ++ ++If @code{unicode} is present, no @code{charset} section is required in ++the font description files since the Unicode handling built into ++@code{groff} is used. However, if there are entries in a @code{charset} ++section, they either override the default mappings for those particular ++characters or add new mappings (normally for composite characters). ++ ++This is used for @option{-Tutf8}, @option{-Thtml}, and @option{-Txhtml}. ++ ++@item unitwidth @var{n} ++@kindex unitwidth ++Quantities in the font files are given in machine units for fonts whose ++point size is @var{n}@tie{}scaled points. ++ ++@item unscaled_charwidths ++@kindex unscaled_charwidths ++Make the font handling module always return unscaled character widths. ++Needed for the @code{grohtml} device. ++ ++@item use_charnames_in_special ++@kindex use_charnames_in_special ++This command indicates that @code{gtroff} should encode special ++characters inside special commands. Currently, this is only used by the ++@code{grohtml} output device. @xref{Postprocessor Access}. ++ ++@item vert @var{n} ++@kindex vert ++@cindex vertical resolution ++@cindex resolution, vertical ++The vertical resolution is @var{n}@tie{}machine units. All vertical ++quantities are rounded to be multiples of this value. ++@end table ++ ++The @code{res}, @code{unitwidth}, @code{fonts}, and @code{sizes} lines ++are mandatory. Other commands are ignored by @code{gtroff} but may be ++used by postprocessors to store arbitrary information about the device ++in the @file{DESC} file. ++ ++@kindex spare1 ++@kindex spare2 ++@kindex biggestfont ++Here a list of obsolete keywords that are recognized by @code{groff} ++but completely ignored: @code{spare1}, @code{spare2}, ++@code{biggestfont}. ++ ++@c --------------------------------------------------------------------- ++ ++@node Font File Format, , DESC File Format, Font Files ++@subsection Font File Format ++@cindex font file, format ++@cindex font description file, format ++@cindex format of font files ++@cindex format of font description files ++ ++A @dfn{font file}, also (and probably better) called a @dfn{font ++description file}, has two sections. The first section is a sequence of ++lines each containing a sequence of blank delimited words; the first ++word in the line is a key, and subsequent words give a value for that ++key. ++ ++@table @code ++@item name @var{f} ++@kindex name ++The name of the font is@tie{}@var{f}. ++ ++@item spacewidth @var{n} ++@kindex spacewidth ++The normal width of a space is@tie{}@var{n}. ++ ++@item slant @var{n} ++@kindex slant ++The glyphs of the font have a slant of @var{n}@tie{}degrees. (Positive ++means forward.) ++ ++@item ligatures @var{lig1} @var{lig2} @dots{} @var{lign} [0] ++@kindex ligatures ++Glyphs @var{lig1}, @var{lig2}, @dots{}, @var{lign} are ligatures; ++possible ligatures are @samp{ff}, @samp{fi}, @samp{fl}, @samp{ffi} and ++@samp{ffl}. For backwards compatibility, the list of ligatures may be ++terminated with a@tie{}0. The list of ligatures may not extend over ++more than one line. ++ ++@item special ++@cindex special fonts ++@kindex special ++The font is @dfn{special}; this means that when a glyph is requested ++that is not present in the current font, it is searched for in any ++special fonts that are mounted. ++@end table ++ ++Other commands are ignored by @code{gtroff} but may be used by ++postprocessors to store arbitrary information about the font in the font ++file. ++ ++@cindex comments in font files ++@cindex font files, comments ++@kindex # ++The first section can contain comments, which start with the @samp{#} ++character and extend to the end of a line. ++ ++The second section contains one or two subsections. It must contain a ++@code{charset} subsection and it may also contain a @code{kernpairs} ++subsection. These subsections can appear in any order. Each subsection ++starts with a word on a line by itself. ++ ++@kindex charset ++The word @code{charset} starts the character set ++subsection.@footnote{This keyword is misnamed since it starts a list of ++ordered glyphs, not characters.} The @code{charset} line is followed by ++a sequence of lines. Each line gives information for one glyph. A line ++comprises a number of fields separated by blanks or tabs. The format is ++ ++@quotation ++@var{name} @var{metrics} @var{type} @var{code} [@var{entity-name}] ++[@code{--} @var{comment}] ++@end quotation ++ ++@cindex 8-bit input ++@cindex input, 8-bit ++@cindex accessing unnamed glyphs with @code{\N} ++@cindex unnamed glyphs, accessing with @code{\N} ++@cindex characters, unnamed, accessing with @code{\N} ++@cindex glyphs, unnamed, accessing with @code{\N} ++@kindex --- ++@noindent ++@var{name} identifies the glyph name@footnote{The distinction between ++input, characters, and output, glyphs, is not clearly separated in the ++terminology of @code{groff}; for example, the @code{char} request should ++be called @code{glyph} since it defines an output entity.}: If ++@var{name} is a single character@tie{}@var{c} then it corresponds to the ++@code{gtroff} input character@tie{}@var{c}; if it is of the form ++@samp{\@var{c}} where @var{c} is a single character, then it corresponds ++to the special character @code{\[@var{c}]}; otherwise it corresponds to ++the special character @samp{\[@var{name}]}. If it is exactly two ++characters @var{xx} it can be entered as @samp{\(@var{xx}}. Note that ++single-letter special characters can't be accessed as @samp{\@var{c}}; ++the only exception is @samp{\-}, which is identical to @code{\[-]}. ++ ++@code{gtroff} supports 8-bit input characters; however some utilities ++have difficulties with eight-bit characters. For this reason, there is ++a convention that the entity name @samp{char@var{n}} is equivalent to ++the single input character whose code is@tie{}@var{n}. For example, ++@samp{char163} would be equivalent to the character with code@tie{}163, ++which is the pounds sterling sign in the ISO@tie{}@w{Latin-1} character ++set. You shouldn't use @samp{char@var{n}} entities in font description ++files since they are related to input, not output. Otherwise, you get ++hard-coded connections between input and output encoding, which prevents ++use of different (input) character sets. ++ ++The name @samp{---} is special and indicates that the glyph is unnamed; ++such glyphs can only be used by means of the @code{\N} escape sequence ++in @code{gtroff}. ++ ++The @var{type} field gives the glyph type: ++ ++@table @code ++@item 1 ++the glyph has a descender, for example, @samp{p}; ++ ++@item 2 ++the glyph has an ascender, for example, @samp{b}; ++ ++@item 3 ++the glyph has both an ascender and a descender, for example, @samp{(}. ++@end table ++ ++The @var{code} field gives the code that the postprocessor uses to ++print the glyph. The glyph can also be input to @code{gtroff} using ++this code by means of the @code{\N} escape sequence. @var{code} can be ++any integer. If it starts with @samp{0} it is interpreted as octal; if ++it starts with @samp{0x} or @samp{0X} it is interpreted as hexadecimal. ++Note, however, that the @code{\N} escape sequence only accepts a decimal ++integer. ++ ++The @var{entity-name} field gives an @acronym{ASCII} string identifying ++the glyph that the postprocessor uses to print the @code{gtroff} glyph ++@var{name}. This field is optional and has been introduced so that the ++@code{grohtml} device driver can encode its character set. For example, ++the glyph @samp{\[Po]} is represented as @samp{£} in ++@acronym{HTML} 4.0. ++ ++Anything on the line after the @var{entity-name} field resp.@: after ++@samp{--} is ignored. ++ ++The @var{metrics} field has the form: ++ ++@display ++@group ++@var{width}[@code{,}@var{height}[@code{,}@var{depth}[@code{,}@var{italic-correction} ++ [@code{,}@var{left-italic-correction}[@code{,}@var{subscript-correction}]]]]] ++@end group ++@end display ++ ++@noindent ++There must not be any spaces between these subfields (it has been split ++here into two lines for better legibility only). Missing subfields are ++assumed to be@tie{}0. The subfields are all decimal integers. Since ++there is no associated binary format, these values are not required to ++fit into a variable of type @samp{char} as they are in @code{ditroff}. ++The @var{width} subfield gives the width of the glyph. The @var{height} ++subfield gives the height of the glyph (upwards is positive); if a glyph ++does not extend above the baseline, it should be given a zero height, ++rather than a negative height. The @var{depth} subfield gives the depth ++of the glyph, that is, the distance from the baseline to the lowest ++point below the baseline to which the glyph extends (downwards is ++positive); if a glyph does not extend below the baseline, it should be ++given a zero depth, rather than a negative depth. The ++@var{italic-correction} subfield gives the amount of space that should ++be added after the glyph when it is immediately to be followed by a ++glyph from a roman font. The @var{left-italic-correction} subfield ++gives the amount of space that should be added before the glyph when it ++is immediately to be preceded by a glyph from a roman font. The ++@var{subscript-correction} gives the amount of space that should be ++added after a glyph before adding a subscript. This should be less than ++the italic correction. ++ ++A line in the @code{charset} section can also have the format ++ ++@Example ++@var{name} " ++@endExample ++ ++@noindent ++This indicates that @var{name} is just another name for the glyph ++mentioned in the preceding line. ++ ++@kindex kernpairs ++The word @code{kernpairs} starts the kernpairs section. This contains a ++sequence of lines of the form: ++ ++@Example ++@var{c1} @var{c2} @var{n} ++@endExample ++ ++@noindent ++This means that when glyph @var{c1} appears next to glyph @var{c2} the ++space between them should be increased by@tie{}@var{n}. Most entries in ++the kernpairs section have a negative value for@tie{}@var{n}. ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Installation, Copying This Manual, File formats, Top ++@chapter Installation ++@cindex installation ++ ++@c XXX ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Copying This Manual, Request Index, Installation, Top ++@appendix Copying This Manual ++ ++@include fdl.texi ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Request Index, Escape Index, Copying This Manual, Top ++@appendix Request Index ++ ++Requests appear without the leading control character (normally either ++@samp{.} or @samp{'}). ++ ++@printindex rq ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Escape Index, Operator Index, Request Index, Top ++@appendix Escape Index ++ ++Any escape sequence @code{\@var{X}} with @var{X} not in the list below ++emits a warning, printing glyph @var{X}. ++ ++@printindex es ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Operator Index, Register Index, Escape Index, Top ++@appendix Operator Index ++ ++@printindex op ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Register Index, Macro Index, Operator Index, Top ++@appendix Register Index ++ ++The macro package or program a specific register belongs to is appended in ++brackets. ++ ++A register name@tie{}@code{x} consisting of exactly one character can be ++accessed as @samp{\nx}. A register name @code{xx} consisting of exactly ++two characters can be accessed as @samp{\n(xx}. Register names ++@code{xxx} of any length can be accessed as @samp{\n[xxx]}. ++ ++@printindex vr ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Macro Index, String Index, Register Index, Top ++@appendix Macro Index ++ ++The macro package a specific macro belongs to is appended in brackets. ++They appear without the leading control character (normally @samp{.}). ++ ++@printindex ma ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node String Index, Glyph Name Index, Macro Index, Top ++@appendix String Index ++ ++The macro package or program a specific string belongs to is appended in ++brackets. ++ ++A string name@tie{}@code{x} consisting of exactly one character can be ++accessed as @samp{\*x}. A string name @code{xx} consisting of exactly ++two characters can be accessed as @samp{\*(xx}. String names @code{xxx} ++of any length can be accessed as @samp{\*[xxx]}. ++ ++ ++@printindex st ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Glyph Name Index, Font File Keyword Index, String Index, Top ++@appendix Glyph Name Index ++ ++A glyph name @code{xx} consisting of exactly two characters can be ++accessed as @samp{\(xx}. Glyph names @code{xxx} of any length can be ++accessed as @samp{\[xxx]}. ++ ++@c XXX ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Font File Keyword Index, Program and File Index, Glyph Name Index, Top ++@appendix Font File Keyword Index ++ ++@printindex ky ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Program and File Index, Concept Index, Font File Keyword Index, Top ++@appendix Program and File Index ++ ++@printindex pg ++ ++ ++ ++@c ===================================================================== ++@c ===================================================================== ++ ++@node Concept Index, , Program and File Index, Top ++@appendix Concept Index ++ ++@printindex cp ++ ++ ++@bye ++ ++@c Local Variables: ++@c mode: texinfo ++@c coding: latin-1 ++@c End: +diff -Nuar groff-1.22.3.old/doc/groff.texinfo groff-1.22.3/doc/groff.texinfo +--- groff-1.22.3.old/doc/groff.texinfo 2014-11-04 10:38:35.560519809 +0200 ++++ groff-1.22.3/doc/groff.texinfo 1970-01-01 02:00:00.000000000 +0200 +@@ -1,17157 +0,0 @@ +-\input texinfo +- +-@c +-@c Please convert this manual with `texi2dvi -e groff.texinfo' due to +-@c problems in texinfo regarding expansion of user-defined macros. +-@c +-@c You need texinfo 4.8 or newer to format this document! +-@c +- +-@c %**start of header (This is for running Texinfo on a region.) +-@setfilename groff.info +-@settitle The GNU Troff Manual +-@setchapternewpage odd +-@footnotestyle separate +-@c %**end of header (This is for running Texinfo on a region.) +- +-@documentlanguage en +-@documentencoding ISO-8859-1 +- +- +-@smallbook +- +-@finalout +- +- +-@copying +-This manual documents GNU @code{troff} version 1.22.3. +- +-Copyright @copyright{} 1994-2014 Free Software Foundation, Inc. +- +-@quotation +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the GNU Free Documentation License, Version 1.3 or +-any later version published by the Free Software Foundation; with no +-Invariant Sections, with the Front-Cover texts being ``A GNU Manual,'' +-and with the Back-Cover Texts as in (a) below. A copy of the license is +-included in the section entitled ``GNU Free Documentation License.'' +- +-(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and +-modify this GNU manual. Buying copies from the FSF supports it in +-developing GNU and promoting software freedom.'' +-@end quotation +-@end copying +- +- +-@c We use the following indices: +-@c +-@c cindex: concepts +-@c rqindex: requests +-@c esindex: escapes +-@c vindex: registers +-@c kindex: commands in font files +-@c pindex: programs and files +-@c tindex: environment variables +-@c maindex: macros +-@c stindex: strings +-@c opindex: operators +-@c +-@c tindex and cindex are merged. +- +-@defcodeindex rq +-@defcodeindex es +-@defcodeindex ma +-@defcodeindex st +-@defcodeindex op +-@syncodeindex tp cp +- +- +-@c To avoid uppercasing in @deffn while converting to info, we define +-@c our special @Var{}. +- +-@macro Var{arg} +-@r{@slanted{\arg\}} +-@end macro +- +- +-@c To assure correct HTML translation, some ugly hacks are necessary. +-@c While processing a @def... request, the HTML translator looks at the +-@c next line to decide whether to start indentation, and if the line +-@c starts with @def... (e.g. @deffnx), indentation is started. We must +-@c therefore ensure that a @def... is seen, during macro expansion. +-@c +-@c The following macros have to be used: +-@c +-@c One item: +-@c +-@c @Def... +-@c +-@c Two items: +-@c +-@c @Def...List +-@c @Def...ListEnd +-@c +-@c More than two: +-@c +-@c @Def...List +-@c @Def...Item +-@c @Def...Item +-@c ... +-@c @Def...ListEnd +-@c +-@c The definition block must end with +-@c +-@c @endDef... +-@c +-@c The above is valid for texinfo 4.0f and above. +-@c +-@c By default, only the first item generates an index entry. To +-@c override this, use a variant with a trailing `x' (like +-@c `@DefmacItemx'). +- +- +-@c a dummy macro to assure the `@def...' +- +-@macro defdummy +-@c +-@end macro +- +- +-@c definition of requests +- +-@macro Defreq{name, arg} +-@deffn Request @t{.\name\} \arg\ +-@rqindex \name\ +-@c +-@end macro +- +-@macro DefreqList{name, arg} +-@deffn Request @t{.\name\} \arg\ +-@defdummy +-@rqindex \name\ +-@c +-@end macro +- +-@macro DefreqItem{name, arg} +-@deffnx Request @t{.\name\} \arg\ +-@defdummy +-@c +-@end macro +- +-@macro DefreqItemx{name, arg} +-@deffnx Request @t{.\name\} \arg\ +-@defdummy +-@rqindex \name\ +-@c +-@end macro +- +-@macro DefreqListEnd{name, arg} +-@deffnx Request @t{.\name\} \arg\ +-@c +-@end macro +- +-@macro DefreqListEndx{name, arg} +-@deffnx Request @t{.\name\} \arg\ +-@rqindex \name\ +-@c +-@end macro +- +-@macro endDefreq +-@end deffn +-@end macro +- +- +-@c definition of escapes +- +-@macro Defesc{name, delimI, arg, delimII} +-@deffn Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +-@esindex \name\ +-@c +-@end macro +- +-@macro DefescList{name, delimI, arg, delimII} +-@deffn Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +-@defdummy +-@esindex \name\ +-@c +-@end macro +- +-@macro DefescItem{name, delimI, arg, delimII} +-@deffnx Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +-@defdummy +-@c +-@end macro +- +-@macro DefescItemx{name, delimI, arg, delimII} +-@deffnx Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +-@defdummy +-@esindex \name\ +-@c +-@end macro +- +-@macro DefescListEnd{name, delimI, arg, delimII} +-@deffnx Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +-@c +-@end macro +- +-@macro DefescListEndx{name, delimI, arg, delimII} +-@deffnx Escape @t{\name\\delimI\}@Var{\arg\}@t{\delimII\} +-@esindex \name\ +-@c +-@end macro +- +-@macro endDefesc +-@end deffn +-@end macro +- +- +-@c definition of registers +- +-@macro Defreg{name} +-@deffn Register @t{\\n[\name\]} +-@vindex \name\ +-@c +-@end macro +- +-@macro DefregList{name} +-@deffn Register @t{\\n[\name\]} +-@defdummy +-@vindex \name\ +-@c +-@end macro +- +-@macro DefregItem{name} +-@deffnx Register @t{\\n[\name\]} +-@defdummy +-@c +-@end macro +- +-@macro DefregItemx{name} +-@deffnx Register @t{\\n[\name\]} +-@defdummy +-@vindex \name\ +-@c +-@end macro +- +-@macro DefregListEnd{name} +-@deffnx Register @t{\\n[\name\]} +-@c +-@end macro +- +-@macro DefregListEndx{name} +-@deffnx Register @t{\\n[\name\]} +-@vindex \name\ +-@c +-@end macro +- +-@macro endDefreg +-@end deffn +-@end macro +- +- +-@c definition of registers specific to macro packages, preprocessors, etc. +- +-@macro Defmpreg{name, package} +-@deffn Register @t{\\n[\name\]} +-@vindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro DefmpregList{name, package} +-@deffn Register @t{\\n[\name\]} +-@defdummy +-@vindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro DefmpregItem{name, package} +-@deffnx Register @t{\\n[\name\]} +-@defdummy +-@c +-@end macro +- +-@macro DefmpregItemx{name, package} +-@deffnx Register @t{\\n[\name\]} +-@defdummy +-@vindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro DefmpregListEnd{name, package} +-@deffnx Register @t{\\n[\name\]} +-@c +-@end macro +- +-@macro DefmpregListEndx{name, package} +-@deffnx Register @t{\\n[\name\]} +-@vindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro endDefmpreg +-@end deffn +-@end macro +- +- +-@c definition of macros +- +-@macro Defmac{name, arg, package} +-@defmac @t{.\name\} \arg\ +-@maindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro DefmacList{name, arg, package} +-@defmac @t{.\name\} \arg\ +-@defdummy +-@maindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro DefmacItem{name, arg, package} +-@defmacx @t{.\name\} \arg\ +-@defdummy +-@c +-@end macro +- +-@macro DefmacItemx{name, arg, package} +-@defmacx @t{.\name\} \arg\ +-@defdummy +-@maindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro DefmacListEnd{name, arg, package} +-@defmacx @t{.\name\} \arg\ +-@c +-@end macro +- +-@macro DefmacListEndx{name, arg, package} +-@defmacx @t{.\name\} \arg\ +-@maindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro endDefmac +-@end defmac +-@end macro +- +- +-@c definition of strings +- +-@macro Defstr{name, package} +-@deffn String @t{\\*[\name\]} +-@stindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro DefstrList{name, package} +-@deffn String @t{\\*[\name\]} +-@defdummy +-@stindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro DefstrItem{name, package} +-@deffnx String @t{\\*[\name\]} +-@defdummy +-@c +-@end macro +- +-@macro DefstrItemx{name, package} +-@deffnx String @t{\\*[\name\]} +-@defdummy +-@stindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro DefstrListEnd{name, package} +-@deffnx String @t{\\*[\name\]} +-@c +-@end macro +- +-@macro DefstrListEndx{name, package} +-@deffnx String @t{\\*[\name\]} +-@stindex \name\ @r{[}\package\@r{]} +-@c +-@end macro +- +-@macro endDefstr +-@end deffn +-@end macro +- +- +-@c our example macros +- +-@macro Example +-@example +-@group +-@end macro +- +-@macro endExample +-@end group +-@end example +-@end macro +- +-@macro CartoucheExample +-@cartouche +-@example +-@end macro +- +-@macro endCartoucheExample +-@end example +-@end cartouche +-@end macro +- +- +-@c +- +-@tex +-\gdef\Langlemacro{\angleleft} +-\gdef\Ranglemacro{\angleright} +-@end tex +- +-@iftex +-@set Langlemacro @Langlemacro +-@set Ranglemacro @Ranglemacro +-@end iftex +- +-@ifnottex +-@set Langlemacro < +-@set Ranglemacro > +-@end ifnottex +- +-@macro angles{text} +-@value{Langlemacro}@r{\text\}@value{Ranglemacro} +-@end macro +- +- +-@c a <= sign +-@c +-@c Since expansion of macros has changed between texinfo 4.x and 5.x, +-@c we can't define a macro but have to use @value directly. +- +-@tex +-\gdef\LE{\le} +-@end tex +- +-@iftex +-@set LE @LE +-@end iftex +- +-@ifnottex +-@set LE <= +-@end ifnottex +- +- +-@c Special care is required with parentheses, brackets, and braces: +-@c +-@c . Real parentheses in @deffn produce an error while compiling with +-@c TeX. +-@c . Real brackets use the wrong font in @deffn, overriding @t{}. +-@c +-@c . @{ and @} fail with info if used in a macro. +-@c +-@c Since macros aren't expanded in @deffn during -E, the following +-@c definitions are for non-TeX only. +-@c +-@c This is true for texinfo 4.0 and above. +- +-@iftex +-@set Lparenmacro @lparen +-@set Rparenmacro @rparen +-@set Lbrackmacro @lbrack +-@set Rbrackmacro @rbrack +-@set Lbracemacro @{ +-@set Rbracemacro @} +-@end iftex +- +-@ifnottex +-@set Lparenmacro ( +-@set Rparenmacro ) +-@set Lbrackmacro [ +-@set Rbrackmacro ] +-@set Lbracemacro @{ +-@set Rbracemacro @} +-@end ifnottex +- +-@macro Lparen{} +-@value{Lparenmacro} +-@end macro +-@macro Rparen{} +-@value{Rparenmacro} +-@end macro +-@macro Lbrack{} +-@value{Lbrackmacro} +-@end macro +-@macro Rbrack{} +-@value{Rbrackmacro} +-@end macro +-@macro Lbrace{} +-@value{Lbracemacro} +-@end macro +-@macro Rbrace{} +-@value{Rbracemacro} +-@end macro +- +- +-@c This suppresses the word `Appendix' in the appendix headers. +- +-@tex +-\gdef\gobblefirst#1#2{#2} +-\gdef\putwordAppendix{\gobblefirst} +-@end tex +- +- +-@c We map some latin-1 characters to corresponding texinfo macros. +-@c Newer versions of texinfo.tex have similar code included already. +- +-@tex +-\global\catcode`^^e4\active % +-\gdef^^e4{\"a} +-\global\catcode`^^c4\active % +-\gdef^^c4{\"A} +-\global\catcode`^^e9\active % +-\gdef^^e9{\'e} +-\global\catcode`^^c9\active % +-\gdef^^c9{\'E} +-\global\catcode`^^f6\active % +-\gdef^^f6{\"o} +-\global\catcode`^^d6\active % +-\gdef^^d6{\"O} +-\global\catcode`^^fc\active % +-\gdef^^fc{\"u} +-\global\catcode`^^dc\active % +-\gdef^^dc{\"U} +-\global\catcode`^^e6\active % +-\gdef^^e6{\ae} +-\global\catcode`^^c6\active % +-\gdef^^c6{\AE} +-\global\catcode`^^df\active % +-\gdef^^df{\ss} +-@end tex +- +- +-@c Note: We say `Roman numerals' but `roman font'. +- +- +-@dircategory Typesetting +-@direntry +-* Groff: (groff). The GNU troff document formatting system. +-@end direntry +- +- +-@titlepage +-@title groff +-@subtitle The GNU implementation of @code{troff} +-@subtitle Edition 1.22.3 +-@subtitle Autumn 2014 +-@author by Trent A.@tie{}Fisher +-@author and Werner Lemberg (@email{bug-groff@@gnu.org}) +- +-@page +-@vskip 0pt plus 1filll +-@insertcopying +-@end titlepage +- +-@contents +- +-@ifnottex +-@node Top, Introduction, (dir), (dir) +-@top GNU troff +-@end ifnottex +- +-@menu +-* Introduction:: +-* Invoking groff:: +-* Tutorial for Macro Users:: +-* Macro Packages:: +-* gtroff Reference:: +-* Preprocessors:: +-* Output Devices:: +-* File formats:: +-* Installation:: +-* Copying This Manual:: +-* Request Index:: +-* Escape Index:: +-* Operator Index:: +-* Register Index:: +-* Macro Index:: +-* String Index:: +-* Glyph Name Index:: +-* Font File Keyword Index:: +-* Program and File Index:: +-* Concept Index:: +-@end menu +- +-@ifnottex +-@insertcopying +-@end ifnottex +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Introduction, Invoking groff, Top, Top +-@chapter Introduction +-@cindex introduction +- +-GNU @code{troff} (or @code{groff}) is a system for typesetting +-documents. @code{troff} is very flexible and has been used extensively +-for some thirty years. It is well entrenched in the @acronym{UNIX} +-community. +- +-@menu +-* What Is groff?:: +-* History:: +-* groff Capabilities:: +-* Macro Package Intro:: +-* Preprocessor Intro:: +-* Output device intro:: +-* Credits:: +-@end menu +- +- +-@c ===================================================================== +- +-@node What Is groff?, History, Introduction, Introduction +-@section What Is @code{groff}? +-@cindex what is @code{groff}? +-@cindex @code{groff} -- what is it? +- +-@code{groff} belongs to an older generation of document preparation +-systems, which operate more like compilers than the more recent +-interactive @acronym{WYSIWYG}@footnote{What You See Is What You Get} +-systems. @code{groff} and its contemporary counterpart, @TeX{}, both +-work using a @dfn{batch} paradigm: The input (or @dfn{source}) files are +-normal text files with embedded formatting commands. These files can +-then be processed by @code{groff} to produce a typeset document on a +-variety of devices. +- +-@code{groff} should not be confused with a @dfn{word processor}, an +-integrated system of editor and text formatter. Also, many word +-processors follow the @acronym{WYSIWYG} paradigm discussed earlier. +- +-Although @acronym{WYSIWYG} systems may be easier to use, they have a +-number of disadvantages compared to @code{troff}: +- +-@itemize @bullet +-@item +-They must be used on a graphics display to work on a document. +- +-@item +-Most of the @acronym{WYSIWYG} systems are either non-free or are not +-very portable. +- +-@item +-@code{troff} is firmly entrenched in all @acronym{UNIX} systems. +- +-@item +-It is difficult to have a wide range of capabilities within the confines +-of a GUI/window system. +- +-@item +-It is more difficult to make global changes to a document. +-@end itemize +- +-@quotation +-``GUIs normally make it simple to accomplish simple actions and +-impossible to accomplish complex actions.'' --Doug Gwyn (22/Jun/91 in +-@code{comp.unix.wizards}) +-@end quotation +- +- +-@c ===================================================================== +- +-@node History, groff Capabilities, What Is groff?, Introduction +-@section History +-@cindex history +- +-@cindex @code{RUNOFF}, the program +-@cindex @code{rf}, the program +-@code{troff} can trace its origins back to a formatting program called +-@code{RUNOFF}, written by Jerry Saltzer, which ran on the @acronym{CTSS} +-(@emph{Compatible Time Sharing System}, a project of MIT, the +-Massachusetts Institute of Technology) in the +-mid-sixties.@footnote{Jerome H.@: Saltzer, a grad student then, later a +-Professor of Electrical Engineering, now retired. Saltzer's PhD thesis +-was the first application for @code{RUNOFF} and is available from the +-MIT Libraries.} The name came from the use of the phrase ``run off a +-document'', meaning to print it out. +-@c +-@c Tom Van Vleck writes about the following: +-@c +-@c I am not sure about this.. I think the BCPL runoff was the port to +-@c the 635 architecture, and that the order of events is +-@c 1. CTSS runoff +-@c 2. BCPL runoff on Multics +-@c 3. BCPL runoff on 635 +-@c 4. rf on PDP-7 +-@c +-Bob Morris ported it to the 635 architecture and called the program +-@code{roff} (an abbreviation of @code{runoff}). It was rewritten as +-@code{rf} for the @w{PDP-7} (before having @acronym{UNIX}), and at the +-same time (1969), Doug McIllroy rewrote an extended and simplified +-version of @code{roff} in the @acronym{BCPL} programming language. +- +-@cindex @code{roff}, the program +-In 1971, the UNIX developers wanted to get a @w{PDP-11}, and to justify +-the cost, proposed the development of a document formatting system for +-the @acronym{AT&T} patents division. This first formatting program was +-a reimplementation of McIllroy's @code{roff}, written by J.@tie{}F.@: +-Ossanna. +- +-@cindex @code{nroff}, the program +-When they needed a more flexible language, a new version of @code{roff} +-called @code{nroff} (``Newer @code{roff}'') was written. It had a much +-more complicated syntax, but provided the basis for all future versions. +-When they got a Graphic Systems CAT Phototypesetter, Ossanna wrote a +-version of @code{nroff} that would drive it. It was dubbed +-@code{troff}, for ``typesetter @code{roff}'', although many people have +-speculated that it actually means ``Times @code{roff}'' because of the +-use of the Times font family in @code{troff} by default. As such, the +-name @code{troff} is pronounced `@w{t-roff}' rather than `trough'. +- +-With @code{troff} came @code{nroff} (they were actually the same program +-except for some @samp{#ifdef}s), which was for producing output for line +-printers and character terminals. It understood everything @code{troff} +-did, and ignored the commands that were not applicable (e.g.@: font +-changes). +- +-Since there are several things that cannot be done easily in +-@code{troff}, work on several preprocessors began. These programs would +-transform certain parts of a document into @code{troff}, which made a +-very natural use of pipes in @acronym{UNIX}. +- +-The @code{eqn} preprocessor allowed mathematical formul to be specified +-in a much simpler and more intuitive manner. @code{tbl} is a +-preprocessor for formatting tables. The @code{refer} preprocessor (and +-the similar program, @code{bib}) processes citations in a document +-according to a bibliographic database. +- +-Unfortunately, Ossanna's @code{troff} was written in @w{PDP-11} assembly +-language and produced output specifically for the CAT phototypesetter. +-He rewrote it in C, although it was now 7000@tie{}lines of uncommented +-code and still dependent on the CAT@. As the CAT became less common, and +-was no longer supported by the manufacturer, the need to make it support +-other devices became a priority. However, before this could be done, +-Ossanna died by a severe heart attack in a hospital while recovering +-from a previous one. +- +-@pindex ditroff +-@cindex @code{ditroff}, the program +-So, Brian Kernighan took on the task of rewriting @code{troff}. The +-newly rewritten version produced device independent code that was very +-easy for postprocessors to read and translate to the appropriate printer +-codes. Also, this new version of @code{troff} (called @code{ditroff} +-for ``device independent @code{troff}'') had several extensions, which +-included drawing functions. +- +-Due to the additional abilities of the new version of @code{troff}, +-several new preprocessors appeared. The @code{pic} preprocessor +-provides a wide range of drawing functions. Likewise the @code{ideal} +-preprocessor did the same, although via a much different paradigm. The +-@code{grap} preprocessor took specifications for graphs, but, unlike +-other preprocessors, produced @code{pic} code. +- +-James Clark began work on a GNU implementation of @code{ditroff} in +-early@tie{}1989. The first version, @code{groff}@tie{}0.3.1, was +-released June@tie{}1990. @code{groff} included: +- +-@itemize @bullet +-@item +-A replacement for @code{ditroff} with many extensions. +- +-@item +-The @code{soelim}, @code{pic}, @code{tbl}, and @code{eqn} preprocessors. +- +-@item +-Postprocessors for character devices, @sc{PostScript}, @TeX{} DVI, and +-X@tie{}Windows. GNU @code{troff} also eliminated the need for a +-separate @code{nroff} program with a postprocessor that would produce +-@acronym{ASCII} output. +- +-@item +-A version of the @file{me} macros and an implementation of the +-@file{man} macros. +-@end itemize +- +-Also, a front-end was included that could construct the, sometimes +-painfully long, pipelines required for all the post- and preprocessors. +- +-Development of GNU @code{troff} progressed rapidly, and saw the +-additions of a replacement for @code{refer}, an implementation of the +-@file{ms} and @file{mm} macros, and a program to deduce how to format a +-document (@code{grog}). +- +-It was declared a stable (i.e.@: non-beta) package with the release of +-version@tie{}1.04 around November@tie{}1991. +- +-Beginning in@tie{}1999, @code{groff} has new maintainers (the package +-was an orphan for a few years). As a result, new features and programs +-like @code{grn}, a preprocessor for gremlin images, and an output device +-to produce @acronym{HTML} and @acronym{XHTML} have been added. +- +- +-@c ===================================================================== +- +-@node groff Capabilities, Macro Package Intro, History, Introduction +-@section @code{groff} Capabilities +-@cindex @code{groff} capabilities +-@cindex capabilities of @code{groff} +- +-So what exactly is @code{groff} capable of doing? @code{groff} provides +-a wide range of low-level text formatting operations. Using these, it +-is possible to perform a wide range of formatting tasks, such as +-footnotes, table of contents, multiple columns, etc. Here's a list of +-the most important operations supported by @code{groff}: +- +-@itemize @bullet +-@item +-text filling, adjusting, and centering +- +-@item +-hyphenation +- +-@item +-page control +- +-@item +-font and glyph size control +- +-@item +-vertical spacing (e.g.@: double-spacing) +- +-@item +-line length and indenting +- +-@item +-macros, strings, diversions, and traps +- +-@item +-number registers +- +-@item +-tabs, leaders, and fields +- +-@item +-input and output conventions and character translation +- +-@item +-overstrike, bracket, line drawing, and zero-width functions +- +-@item +-local horizontal and vertical motions and the width function +- +-@item +-three-part titles +- +-@item +-output line numbering +- +-@item +-conditional acceptance of input +- +-@item +-environment switching +- +-@item +-insertions from the standard input +- +-@item +-input/output file switching +- +-@item +-output and error messages +-@end itemize +- +- +-@c ===================================================================== +- +-@node Macro Package Intro, Preprocessor Intro, groff Capabilities, Introduction +-@section Macro Packages +-@cindex macro packages +- +-Since @code{groff} provides such low-level facilities, it can be quite +-difficult to use by itself. However, @code{groff} provides a +-@dfn{macro} facility to specify how certain routine operations +-(e.g.@tie{}starting paragraphs, printing headers and footers, etc.)@: +-should be done. These macros can be collected together into a +-@dfn{macro package}. There are a number of macro packages available; +-the most common (and the ones described in this manual) are @file{man}, +-@file{mdoc}, @file{me}, @file{ms}, and @file{mm}. +- +- +-@c ===================================================================== +- +-@node Preprocessor Intro, Output device intro, Macro Package Intro, Introduction +-@section Preprocessors +-@cindex preprocessors +- +-Although @code{groff} provides most functions needed to format a +-document, some operations would be unwieldy (e.g.@: to draw pictures). +-Therefore, programs called @dfn{preprocessors} were written that +-understand their own language and produce the necessary @code{groff} +-operations. These preprocessors are able to differentiate their own +-input from the rest of the document via markers. +- +-To use a preprocessor, @acronym{UNIX} pipes are used to feed the output +-from the preprocessor into @code{groff}. Any number of preprocessors +-may be used on a given document; in this case, the preprocessors are +-linked together into one pipeline. However, with @code{groff}, the user +-does not need to construct the pipe, but only tell @code{groff} what +-preprocessors to use. +- +-@code{groff} currently has preprocessors for producing tables +-(@code{tbl}), typesetting equations (@code{eqn}), drawing pictures +-(@code{pic} and @code{grn}), processing bibliographies +-(@code{refer}), and drawing chemical structures (@code{chem}). An +-associated program that is useful when dealing with preprocessors is +-@code{soelim}. +- +-A free implementation of @code{grap}, a preprocessor for drawing graphs, +-can be obtained as an extra package; @code{groff} can use @code{grap} +-also. +- +-Unique to @code{groff} is the @code{preconv} preprocessor that enables +-@code{groff} to handle documents in various input encodings. +- +-There are other preprocessors in existence, but, unfortunately, no free +-implementations are available. Among them is a preprocessor for drawing +-mathematical pictures (@code{ideal}). +- +- +-@c ===================================================================== +- +-@node Output device intro, Credits, Preprocessor Intro, Introduction +-@section Output Devices +-@cindex postprocessors +-@cindex output devices +-@cindex devices for output +- +-@code{groff} actually produces device independent code that may be fed +-into a postprocessor to produce output for a particular device. +-Currently, @code{groff} has postprocessors for @sc{PostScript} devices, +-character terminals, X@tie{}Windows (for previewing), @TeX{} DVI format, +-HP LaserJet@tie{}4 and Canon LBP printers (which use @acronym{CAPSL}), +-@acronym{HTML}, @acronym{XHTML}, and PDF. +- +- +-@c ===================================================================== +- +-@node Credits, , Output device intro, Introduction +-@section Credits +-@cindex credits +- +-Large portions of this manual were taken from existing documents, most +-notably, the manual pages for the @code{groff} package by James Clark, +-and Eric Allman's papers on the @file{me} macro package. +- +-The section on the @file{man} macro package is partly based on +-Susan@tie{}G.@: Kleinmann's @file{groff_man} manual page written for the +-Debian GNU/Linux system. +- +-Larry Kollar contributed the section in the @file{ms} macro package. +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Invoking groff, Tutorial for Macro Users, Introduction, Top +-@chapter Invoking @code{groff} +-@cindex invoking @code{groff} +-@cindex @code{groff} invocation +- +-This section focuses on how to invoke the @code{groff} front end. This +-front end takes care of the details of constructing the pipeline among +-the preprocessors, @code{gtroff} and the postprocessor. +- +-It has become a tradition that GNU programs get the prefix @samp{g} to +-distinguish it from its original counterparts provided by the host (see +-@ref{Environment}, for more details). Thus, for example, @code{geqn} is +-GNU @code{eqn}. On operating systems like GNU/Linux or the Hurd, which +-don't contain proprietary versions of @code{troff}, and on +-MS-DOS/MS-Windows, where @code{troff} and associated programs are not +-available at all, this prefix is omitted since GNU @code{troff} is the +-only used incarnation of @code{troff}. Exception: @samp{groff} is never +-replaced by @samp{roff}. +- +-In this document, we consequently say @samp{gtroff} when talking about +-the GNU @code{troff} program. All other implementations of @code{troff} +-are called @acronym{AT&T} @code{troff}, which is the common origin of all +-@code{troff} derivates (with more or less compatible changes). +-Similarly, we say @samp{gpic}, @samp{geqn}, etc. +- +-@menu +-* Groff Options:: +-* Environment:: +-* Macro Directories:: +-* Font Directories:: +-* Paper Size:: +-* Invocation Examples:: +-@end menu +- +- +-@c ===================================================================== +- +-@node Groff Options, Environment, Invoking groff, Invoking groff +-@section Options +-@cindex options +- +-@pindex groff +-@pindex gtroff +-@pindex gpic +-@pindex geqn +-@pindex ggrn +-@pindex grap +-@pindex gtbl +-@pindex gchem +-@pindex grefer +-@pindex gsoelim +-@pindex preconv +-@code{groff} normally runs the @code{gtroff} program and a +-postprocessor appropriate for the selected device. The default device +-is @samp{ps} (but it can be changed when @code{groff} is configured and +-built). It can optionally preprocess with any of @code{gpic}, +-@code{geqn}, @code{gtbl}, @code{ggrn}, @code{grap}, @code{gchem}, +-@code{grefer}, @code{gsoelim}, or @code{preconv}. +- +-This section only documents options to the @code{groff} front end. Many +-of the arguments to @code{groff} are passed on to @code{gtroff}, +-therefore those are also included. Arguments to pre- or postprocessors +-can be found in @ref{Invoking gpic}, @ref{Invoking geqn}, @ref{Invoking +-gtbl}, @ref{Invoking ggrn}, @ref{Invoking grefer}, @ref{Invoking gchem}, +-@ref{Invoking gsoelim}, @ref{Invoking preconv}, @ref{Invoking grotty}, +-@ref{Invoking grops}, @ref{Invoking gropdf}, @ref{Invoking grohtml}, +-@ref{Invoking grodvi}, @ref{Invoking grolj4}, @ref{Invoking grolbp}, and +-@ref{Invoking gxditview}. +- +-The command line format for @code{groff} is: +- +-@Example +-groff [ -abceghijklpstvzCEGNRSUVXZ ] [ -d@var{cs} ] [ -D@var{arg} ] +- [ -f@var{fam} ] [ -F@var{dir} ] [ -I@var{dir} ] [ -K@var{arg} ] +- [ -L@var{arg} ] [ -m@var{name} ] [ -M@var{dir} ] [ -n@var{num} ] +- [ -o@var{list} ] [ -P@var{arg} ] [ -r@var{cn} ] [ -T@var{dev} ] +- [ -w@var{name} ] [ -W@var{name} ] [ @var{files}@dots{} ] +-@endExample +- +-The command line format for @code{gtroff} is as follows. +- +-@Example +-gtroff [ -abcivzCERU ] [ -d@var{cs} ] [ -f@var{fam} ] [ -F@var{dir} ] +- [ -m@var{name} ] [ -M@var{dir} ] [ -n@var{num} ] [ -o@var{list} ] +- [ -r@var{cn} ] [ -T@var{name} ] [ -w@var{name} ] [ -W@var{name} ] +- [ @var{files}@dots{} ] +-@endExample +- +-@noindent +-Obviously, many of the options to @code{groff} are actually passed on to +-@code{gtroff}. +- +-Options without an argument can be grouped behind a +-single@tie{}@option{-}. A filename of@tie{}@file{-} denotes the +-standard input. It is possible to have whitespace between an option and +-its parameter. +- +-The @code{grog} command can be used to guess the correct @code{groff} +-command to format a file. +- +-Here's the description of the command-line options: +- +-@cindex command-line options +-@table @samp +-@item -a +-@cindex @acronym{ASCII} approximation output register (@code{.A}) +-Generate an @acronym{ASCII} approximation of the typeset output. The +-read-only register @code{.A} is then set to@tie{}1. @xref{Built-in +-Registers}. A typical example is +- +-@Example +-groff -a -man -Tdvi troff.man | less +-@endExample +- +-@noindent +-which shows how lines are broken for the DVI device. Note that this +-option is rather useless today since graphic output devices are +-available virtually everywhere. +- +-@item -b +-Print a backtrace with each warning or error message. This backtrace +-should help track down the cause of the error. The line numbers given +-in the backtrace may not always be correct: @code{gtroff} can get +-confused by @code{as} or @code{am} requests while counting line numbers. +- +-@item -c +-Suppress color output. +- +-@item -C +-Enable compatibility mode. @xref{Implementation Differences}, for the +-list of incompatibilities between @code{groff} and @acronym{AT&T} +-@code{troff}. +- +-@item -d@var{c}@var{s} +-@itemx -d@var{name}=@var{s} +-Define @var{c} or @var{name} to be a string@tie{}@var{s}. +-@var{c}@tie{}must be a one-letter name; @var{name} can be of arbitrary +-length. All string assignments happen before loading any macro file +-(including the start-up file). +- +-@item -D@var{arg} +-Set default input encoding used by @code{preconv} to @var{arg}. Implies +-@option{-k}. +- +-@item -e +-Preprocess with @code{geqn}. +- +-@item -E +-Inhibit all error messages. +- +-@item -f@var{fam} +-Use @var{fam} as the default font family. @xref{Font Families}. +- +-@item -F@var{dir} +-Search @file{@var{dir}} for subdirectories @file{dev@var{name}} +-(@var{name} is the name of the device), for the @file{DESC} file, and +-for font files before looking in the standard directories (@pxref{Font +-Directories}). This option is passed to all pre- and postprocessors +-using the @env{GROFF_FONT_PATH} environment variable. +- +-@item -g +-Preprocess with @code{ggrn}. +- +-@item -G +-Preprocess with @code{grap}. Implies @option{-p}. +- +-@item -h +-Print a help message. +- +-@item -i +-Read the standard input after all the named input files have been +-processed. +- +-@item -I@var{dir} +-This option may be used to specify a directory to search for files. +-It is passed to the following programs: +- +-@itemize +-@item +-@code{gsoelim} (see @ref{gsoelim} for more details); +-it also implies @code{groff}'s @option{-s} option. +- +-@item +-@code{gtroff}; it is used to search files named in the @code{psbb} and +-@code{so} requests. +- +-@item +-@code{grops}; it is used to search files named in the +-@w{@code{\X'ps: import}} and @w{@code{\X'ps: file}} escapes. +-@end itemize +- +-The current directory is always searched first. This option may be +-specified more than once; the directories are searched in the order +-specified. No directory search is performed for files specified using +-an absolute path. +- +-@item -j +-Preprocess with @code{gchem}. Implies @option{-p}. +- +-@item -k +-Preprocess with @code{preconv}. This is run before any other +-preprocessor. Please refer to @code{preconv}'s manual page for its +-behaviour if no @option{-K} (or @option{-D}) option is specified. +- +-@item -K@var{arg} +-Set input encoding used by preconv to @var{arg}. Implies @option{-k}. +- +-@item -l +-Send the output to a spooler for printing. The command used for this is +-specified by the @code{print} command in the device description file +-(see @ref{Font Files}, for more info). If not present, @option{-l} is +-ignored. +- +-@item -L@var{arg} +-Pass @var{arg} to the spooler. Each argument should be passed with a +-separate @option{-L} option. Note that @code{groff} does not prepend a +-@samp{-} to @var{arg} before passing it to the postprocessor. If the +-@code{print} keyword in the device description file is missing, +-@option{-L} is ignored. +- +-@item -m@var{name} +-Read in the file @file{@var{name}.tmac}. Normally @code{groff} searches +-for this in its macro directories. If it isn't found, it tries +-@file{tmac.@var{name}} (searching in the same directories). +- +-@item -M@var{dir} +-Search directory @file{@var{dir}} for macro files before the standard +-directories (@pxref{Macro Directories}). +- +-@item -n@var{num} +-Number the first page @var{num}. +- +-@item -N +-Don't allow newlines with @code{eqn} delimiters. This is the same as +-the @option{-N} option in @code{geqn}. +- +-@item -o@var{list} +-@cindex print current page register (@code{.P}) +-Output only pages in @var{list}, which is a comma-separated list of page +-ranges; @samp{@var{n}} means print page@tie{}@var{n}, +-@samp{@var{m}-@var{n}} means print every page between @var{m} +-and@tie{}@var{n}, @samp{-@var{n}} means print every page up +-to@tie{}@var{n}, @samp{@var{n}-} means print every page beginning +-with@tie{}@var{n}. @code{gtroff} exits after printing the last page in +-the list. All the ranges are inclusive on both ends. +- +-Within @code{gtroff}, this information can be extracted with the +-@samp{.P} register. @xref{Built-in Registers}. +- +-If your document restarts page numbering at the beginning of each +-chapter, then @code{gtroff} prints the specified page range for each +-chapter. +- +-@item -p +-Preprocess with @code{gpic}. +- +-@item -P@var{arg} +-Pass @var{arg} to the postprocessor. Each argument should be passed +-with a separate @option{-P} option. Note that @code{groff} does not +-prepend @samp{-} to @var{arg} before passing it to the postprocessor. +- +-@item -r@var{c}@var{n} +-@itemx -r@var{name}=@var{n} +-Set number register@tie{}@var{c} or @var{name} to the +-value@tie{}@var{n}. @var{c}@tie{}must be a one-letter name; @var{name} +-can be of arbitrary length. @var{n}@tie{}can be any @code{gtroff} +-numeric expression. All register assignments happen before loading any +-macro file (including the start-up file). +- +-@item -R +-Preprocess with @code{grefer}. No mechanism is provided for passing +-arguments to @code{grefer} because most @code{grefer} options have +-equivalent commands that can be included in the file. @xref{grefer}, +-for more details. +- +-@pindex troffrc +-@pindex troffrc-end +-Note that @code{gtroff} also accepts a @option{-R} option, which is not +-accessible via @code{groff}. This option prevents the loading of the +-@file{troffrc} and @file{troffrc-end} files. +- +-@item -s +-Preprocess with @code{gsoelim}. +- +-@item -S +-@cindex @code{open} request, and safer mode +-@cindex @code{opena} request, and safer mode +-@cindex @code{pso} request, and safer mode +-@cindex @code{sy} request, and safer mode +-@cindex @code{pi} request, and safer mode +-@cindex safer mode +-@cindex mode, safer +-Safer mode. Pass the @option{-S} option to @code{gpic} and disable the +-@code{open}, @code{opena}, @code{pso}, @code{sy}, and @code{pi} +-requests. For security reasons, this is enabled by default. +- +-@item -t +-Preprocess with @code{gtbl}. +- +-@item -T@var{dev} +-Prepare output for device @var{dev}. The default device is @samp{ps}, +-unless changed when @code{groff} was configured and built. The +-following are the output devices currently available: +- +-@table @code +-@item ps +-For @sc{PostScript} printers and previewers. +- +-@item pdf +-For PDF viewers or printers. +- +-@item dvi +-For @TeX{} DVI format. +- +-@item X75 +-For a 75@dmn{dpi} X11 previewer. +- +-@item X75-12 +-For a 75@dmn{dpi} X11 previewer with a 12@dmn{pt} base font in the +-document. +- +-@item X100 +-For a 100@dmn{dpi} X11 previewer. +- +-@item X100-12 +-For a 100@dmn{dpi} X11 previewer with a 12@dmn{pt} base font in the +-document. +- +-@item ascii +-@cindex encoding, output, @acronym{ASCII} +-@cindex @acronym{ASCII}, output encoding +-@cindex output encoding, @acronym{ASCII} +-For typewriter-like devices using the (7-bit) @acronym{ASCII} +-character set. +- +-@item latin1 +-@cindex encoding, output, @w{latin-1} (ISO @w{8859-1}) +-@cindex @w{latin-1} (ISO @w{8859-1}), output encoding +-@cindex ISO @w{8859-1} (@w{latin-1}), output encoding +-@cindex output encoding, @w{latin-1} (ISO @w{8859-1}) +-For typewriter-like devices that support the @w{Latin-1} +-(ISO@tie{}@w{8859-1}) character set. +- +-@item utf8 +-@cindex encoding, output, @w{utf-8} +-@cindex @w{utf-8}, output encoding +-@cindex output encoding, @w{utf-8} +-For typewriter-like devices that use the Unicode (ISO@tie{}10646) +-character set with @w{UTF-8} encoding. +- +-@item cp1047 +-@cindex encoding, output, @acronym{EBCDIC} +-@cindex @acronym{EBCDIC}, output encoding +-@cindex output encoding, @acronym{EBCDIC} +-@cindex encoding, output, cp1047 +-@cindex cp1047, output encoding +-@cindex output encoding, cp1047 +-@cindex IBM cp1047 output encoding +-For typewriter-like devices that use the @acronym{EBCDIC} encoding IBM +-cp1047. +- +-@item lj4 +-For HP LaserJet4-compatible (or other PCL5-compatible) printers. +- +-@item lbp +-For Canon @acronym{CAPSL} printers (@w{LBP-4} and @w{LBP-8} series laser +-printers). +- +-@pindex pre-grohtml +-@pindex post-grohtml +-@cindex @code{grohtml}, the program +-@item html +-@itemx xhtml +-To produce @acronym{HTML} and @acronym{XHTML} output, respectively. +-Note that this driver consists of two parts, a preprocessor +-(@code{pre-grohtml}) and a postprocessor (@code{post-grohtml}). +-@end table +- +-@cindex output device name string register (@code{.T}) +-@cindex output device usage number register (@code{.T}) +-The predefined @code{gtroff} string register @code{.T} contains the +-current output device; the read-only number register @code{.T} is set +-to@tie{}1 if this option is used (which is always true if @code{groff} +-is used to call @code{gtroff}). @xref{Built-in Registers}. +- +-The postprocessor to be used for a device is specified by the +-@code{postpro} command in the device description file. (@xref{Font +-Files}, for more info.) This can be overridden with the @option{-X} +-option. +- +-@item -U +-@cindex mode, unsafe +-@cindex unsafe mode +-Unsafe mode. This enables the @code{open}, @code{opena}, @code{pso}, +-@code{sy}, and @code{pi} requests. +- +-@item -w@var{name} +-Enable warning @var{name}. Available warnings are described in +-@ref{Debugging}. Multiple @option{-w} options are allowed. +- +-@item -W@var{name} +-Inhibit warning @var{name}. Multiple @option{-W} options are allowed. +- +-@item -v +-Make programs run by @code{groff} print out their version number. +- +-@item -V +-Print the pipeline on @code{stdout} instead of executing it. If +-specified more than once, print the pipeline on @code{stderr} and +-execute it. +- +-@item -X +-Preview with @code{gxditview} instead of using the usual postprocessor. +-This is unlikely to produce good results except with @option{-Tps}. +- +-Note that this is not the same as using @option{-TX75} or +-@option{-TX100} to view a document with @code{gxditview}: The former +-uses the metrics of the specified device, whereas the latter uses +-X-specific fonts and metrics. +- +-@item -z +-Suppress output from @code{gtroff}. Only error messages are printed. +- +-@item -Z +-Do not postprocess the output of @code{gtroff}. Normally @code{groff} +-automatically runs the appropriate postprocessor. +-@end table +- +- +-@c ===================================================================== +- +-@node Environment, Macro Directories, Groff Options, Invoking groff +-@section Environment +-@cindex environment variables +-@cindex variables in environment +- +-There are also several environment variables (of the operating system, +-not within @code{gtroff}) that can modify the behavior of @code{groff}. +- +-@table @code +-@item GROFF_BIN_PATH +-@tindex GROFF_BIN_PATH@r{, environment variable} +-This search path, followed by @code{PATH}, is used for commands executed +-by @code{groff}. +- +-@item GROFF_COMMAND_PREFIX +-@tindex GROFF_COMMAND_PREFIX@r{, environment variable} +-@cindex command prefix +-@cindex prefix, for commands +-If this is set to@tie{}@var{X}, then @code{groff} runs +-@code{@var{X}troff} instead of @code{gtroff}. This also applies to +-@code{tbl}, @code{pic}, @code{eqn}, @code{grn}, @code{chem}, +-@code{refer}, and @code{soelim}. It does not apply to @code{grops}, +-@code{grodvi}, @code{grotty}, @code{pre-grohtml}, @code{post-grohtml}, +-@code{preconv}, @code{grolj4}, @code{gropdf}, and @code{gxditview}. +- +-The default command prefix is determined during the installation +-process. If a non-GNU troff system is found, prefix @samp{g} is used, +-none otherwise. +- +-@item GROFF_ENCODING +-@tindex GROFF_ENCODING@r{, environment variable} +-The value of this environment value is passed to the @code{preconv} +-preprocessor to select the encoding of input files. Setting this option +-implies @code{groff}'s command line option @option{-k} (this is, +-@code{groff} actually always calls @code{preconv}). If set without a +-value, @code{groff} calls @code{preconv} without arguments. An explicit +-@option{-K} command line option overrides the value of +-@env{GROFF_ENCODING}. See the manual page of @code{preconv} for details. +- +-@item GROFF_FONT_PATH +-@tindex GROFF_FONT_PATH@r{, environment variable} +-A colon-separated list of directories in which to search for the +-@code{dev}@var{name} directory (before the default directories are +-tried). @xref{Font Directories}. +- +-@item GROFF_TMAC_PATH +-@tindex GROFF_TMAC_PATH@r{, environment variable} +-A colon-separated list of directories in which to search for macro files +-(before the default directories are tried). @xref{Macro Directories}. +- +-@item GROFF_TMPDIR +-@tindex GROFF_TMPDIR@r{, environment variable} +-@tindex TMPDIR@r{, environment variable} +-The directory in which @code{groff} creates temporary files. If this is +-not set and @env{TMPDIR} is set, temporary files are created in that +-directory. Otherwise temporary files are created in a system-dependent +-default directory (on Unix and GNU/Linux systems, this is usually +-@file{/tmp}). @code{grops}, @code{grefer}, @code{pre-grohtml}, and +-@code{post-grohtml} can create temporary files in this directory. +- +-@item GROFF_TYPESETTER +-@tindex GROFF_TYPESETTER@r{, environment variable} +-The default output device. +-@end table +- +-Note that MS-DOS and MS-Windows ports of @code{groff} use semi-colons, +-rather than colons, to separate the directories in the lists described +-above. +- +- +-@c ===================================================================== +- +-@node Macro Directories, Font Directories, Environment, Invoking groff +-@section Macro Directories +-@cindex macro directories +-@cindex directories for macros +-@cindex searching macros +-@cindex macros, searching +- +-All macro file names must be named @code{@var{name}.tmac} or +-@code{tmac.@var{name}} to make the @option{-m@var{name}} command line +-option work. The @code{mso} request doesn't have this restriction; any +-file name can be used, and @code{gtroff} won't try to append or prepend +-the @samp{tmac} string. +- +-@cindex tmac, directory +-@cindex directory, for tmac files +-@cindex tmac, path +-@cindex path, for tmac files +-@cindex searching macro files +-@cindex macro files, searching +-@cindex files, macro, searching +-Macro files are kept in the @dfn{tmac directories}, all of which +-constitute the @dfn{tmac path}. The elements of the search path for +-macro files are (in that order): +- +-@itemize @bullet +-@item +-The directories specified with @code{gtroff}'s or @code{groff}'s +-@option{-M} command line option. +- +-@item +-@tindex GROFF_TMAC_PATH@r{, environment variable} +-The directories given in the @env{GROFF_TMAC_PATH} environment variable. +- +-@item +-@cindex safer mode +-@cindex mode, safer +-@cindex unsafe mode +-@cindex mode, unsafe +-@cindex current directory +-@cindex directory, current +-The current directory (only if in unsafe mode using the @option{-U} +-command line switch). +- +-@item +-@cindex home directory +-@cindex directory, home +-The home directory. +- +-@item +-@cindex site-specific directory +-@cindex directory, site-specific +-@cindex platform-specific directory +-@cindex directory, platform-specific +-A platform-dependent directory, a site-specific (platform-independent) +-directory, and the main tmac directory; the default locations are +- +-@Example +-/usr/local/lib/groff/site-tmac +-/usr/local/share/groff/site-tmac +-/usr/local/share/groff/1.22.3/tmac +-@endExample +- +-@noindent +-assuming that the version of @code{groff} is 1.22.3, and the +-installation prefix was @file{/usr/local}. It is possible to fine-tune +-those directories during the installation process. +-@end itemize +- +- +-@c ===================================================================== +- +-@node Font Directories, Paper Size, Macro Directories, Invoking groff +-@section Font Directories +-@cindex font directories +-@cindex directories for fonts +-@cindex searching fonts +-@cindex fonts, searching +- +-Basically, there is no restriction how font files for @code{groff} are +-named and how long font names are; however, to make the font family +-mechanism work (@pxref{Font Families}), fonts within a family should +-start with the family name, followed by the shape. For example, the +-Times family uses @samp{T} for the family name and @samp{R}, @samp{B}, +-@samp{I}, and @samp{BI} to indicate the shapes `roman', `bold', +-`italic', and `bold italic', respectively. Thus the final font names +-are @samp{TR}, @samp{TB}, @samp{TI}, and @samp{TBI}. +- +-@cindex font path +-@cindex path, for font files +-All font files are kept in the @dfn{font directories}, which constitute +-the @dfn{font path}. The file search functions always append the +-directory @code{dev}@var{name}, where @var{name} is the name of the +-output device. Assuming, say, DVI output, and @file{/foo/bar} as a font +-directory, the font files for @code{grodvi} must be in +-@file{/foo/bar/devdvi}. +- +-The elements of the search path for font files are (in that order): +- +-@itemize @bullet +-@item +-The directories specified with @code{gtroff}'s or @code{groff}'s +-@option{-F} command line option. All device drivers and some +-preprocessors also have this option. +- +-@item +-@tindex GROFF_FONT_PATH@r{, environment variable} +-The directories given in the @env{GROFF_FONT_PATH} environment variable. +- +-@item +-@cindex site-specific directory +-@cindex directory, site-specific +-A site-specific directory and the main font directory; the default +-locations are +- +-@Example +-/usr/local/share/groff/site-font +-/usr/local/share/groff/1.22.3/font +-@endExample +- +-@noindent +-assuming that the version of @code{groff} is 1.22.3, and the +-installation prefix was @file{/usr/local}. It is possible to fine-tune +-those directories during the installation process. +-@end itemize +- +- +-@c ===================================================================== +- +-@node Paper Size, Invocation Examples, Font Directories, Invoking groff +-@section Paper Size +-@cindex paper size +-@cindex size, paper +-@cindex landscape page orientation +-@cindex orientation, landscape +-@cindex page orientation, landscape +- +-In groff, the page size for @code{gtroff} and for output devices are +-handled separately. @xref{Page Layout}, for vertical manipulation of +-the page size. @xref{Line Layout}, for horizontal changes. +- +-A default paper size can be set in the device's @file{DESC} file. Most +-output devices also have a command line option @option{-p} to override +-the default paper size and option @option{-l} to use landscape +-orientation. @xref{DESC File Format}, for a description of the +-@code{papersize} keyword, which takes the same argument as @option{-p}. +- +-@pindex papersize.tmac +-@pindex troffrc +-A convenient shorthand to set a particular paper size for @code{gtroff} +-is command line option @option{-dpaper=@var{size}}. This defines string +-@code{paper}, which is processed in file @file{papersize.tmac} (loaded in +-the start-up file @file{troffrc} by default). Possible values for +-@var{size} are the same as the predefined values for the +-@code{papersize} keyword (but only in lowercase) except +-@code{a7}-@code{d7}. An appended @samp{l} (ell) character denotes +-landscape orientation. +- +-For example, use the following for PS output on A4 paper in landscape +-orientation: +- +-@Example +-groff -Tps -dpaper=a4l -P-pa4 -P-l -ms foo.ms > foo.ps +-@endExample +- +-Note that it is up to the particular macro package to respect default +-page dimensions set in this way (most do). +- +- +-@c ===================================================================== +- +-@node Invocation Examples, , Paper Size, Invoking groff +-@section Invocation Examples +-@cindex invocation examples +-@cindex examples of invocation +- +-This section lists several common uses of @code{groff} and the +-corresponding command lines. +- +-@Example +-groff file +-@endExample +- +-@noindent +-This command processes @file{file} without a macro package or a +-preprocessor. The output device is the default, @samp{ps}, and the +-output is sent to @code{stdout}. +- +-@Example +-groff -t -mandoc -Tascii file | less +-@endExample +- +-@noindent +-This is basically what a call to the @code{man} program does. +-@code{gtroff} processes the manual page @file{file} with the +-@file{mandoc} macro file (which in turn either calls the @file{man} or +-the @file{mdoc} macro package), using the @code{tbl} preprocessor and +-the @acronym{ASCII} output device. Finally, the @code{less} pager +-displays the result. +- +-@Example +-groff -X -m me file +-@endExample +- +-@noindent +-Preview @file{file} with @code{gxditview}, using the @file{me} macro +-package. Since no @option{-T} option is specified, use the default +-device (@samp{ps}). Note that you can either say @w{@samp{-m me}} or +-@w{@samp{-me}}; the latter is an anachronism from the early days of +-@acronym{UNIX}.@footnote{The same is true for the other main macro +-packages that come with @code{groff}: @file{man}, @file{mdoc}, +-@file{ms}, @file{mm}, and @file{mandoc}. This won't work in general; +-for example, to load @file{trace.tmac}, either @samp{-mtrace} or +-@w{@samp{-m trace}} must be used.} +- +-@Example +-groff -man -rD1 -z file +-@endExample +- +-@noindent +-Check @file{file} with the @file{man} macro package, forcing +-double-sided printing -- don't produce any output. +- +-@menu +-* grog:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node grog, , Invocation Examples, Invocation Examples +-@subsection @code{grog} +- +-@pindex grog +-@code{grog} reads files, guesses which of the @code{groff} preprocessors +-and/or macro packages are required for formatting them, and prints the +-@code{groff} command including those options on the standard output. It +-generates one or more of the options @option{-e}, @option{-man}, +-@option{-me}, @option{-mm}, @option{-mom}, @option{-ms}, @option{-mdoc}, +-@option{-mdoc-old}, @option{-p}, @option{-R}, @option{-g}, @option{-G}, +-@option{-s}, and @option{-t}. +- +-A special file name@tie{}@file{-} refers to the standard input. +-Specifying no files also means to read the standard input. Any +-specified options are included in the printed command. No space is +-allowed between options and their arguments. The only options +-recognized are @option{-C} (which is also passed on) to enable +-compatibility mode, and @option{-v} to print the version number and +-exit. +- +-For example, +- +-@Example +-grog -Tdvi paper.ms +-@endExample +- +-@noindent +-guesses the appropriate command to print @file{paper.ms} and then prints +-it to the command line after adding the @option{-Tdvi} option. For +-direct execution, enclose the call to @code{grog} in backquotes at the +-@acronym{UNIX} shell prompt: +- +-@Example +-`grog -Tdvi paper.ms` > paper.dvi +-@endExample +- +-@noindent +-As seen in the example, it is still necessary to redirect the output to +-something meaningful (i.e.@: either a file or a pager program like +-@code{less}). +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Tutorial for Macro Users, Macro Packages, Invoking groff, Top +-@chapter Tutorial for Macro Users +-@cindex tutorial for macro users +-@cindex macros, tutorial for users +-@cindex user's tutorial for macros +-@cindex user's macro tutorial +- +-Most users tend to use a macro package to format their papers. This +-means that the whole breadth of @code{groff} is not necessary for most +-people. This chapter covers the material needed to efficiently use a +-macro package. +- +-@menu +-* Basics:: +-* Common Features:: +-@end menu +- +- +-@c ===================================================================== +- +-@node Basics, Common Features, Tutorial for Macro Users, Tutorial for Macro Users +-@section Basics +-@cindex basics of macros +-@cindex macro basics +- +-This section covers some of the basic concepts necessary to understand +-how to use a macro package.@footnote{This section is derived from +-@cite{Writing Papers with nroff using -me} by Eric P.@tie{}Allman.} +-References are made throughout to more detailed information, if desired. +- +-@code{gtroff} reads an input file prepared by the user and outputs a +-formatted document suitable for publication or framing. The input +-consists of text, or words to be printed, and embedded commands +-(@dfn{requests} and @dfn{escapes}), which tell @code{gtroff} how to +-format the output. For more detail on this, see @ref{Embedded +-Commands}. +- +-The word @dfn{argument} is used in this chapter to mean a word or number +-that appears on the same line as a request, and which modifies the +-meaning of that request. For example, the request +- +-@Example +-.sp +-@endExample +- +-@noindent +-spaces one line, but +- +-@Example +-.sp 4 +-@endExample +- +-@noindent +-spaces four lines. The number@tie{}4 is an argument to the @code{sp} +-request, which says to space four lines instead of one. Arguments are +-separated from the request and from each other by spaces (@emph{no} +-tabs). More details on this can be found in @ref{Request and Macro +-Arguments}. +- +-The primary function of @code{gtroff} is to collect words from input +-lines, fill output lines with those words, justify the right-hand margin +-by inserting extra spaces in the line, and output the result. For +-example, the input: +- +-@Example +-Now is the time +-for all good men +-to come to the aid +-of their party. +-Four score and seven +-years ago, etc. +-@endExample +- +-@noindent +-is read, packed onto output lines, and justified to produce: +- +-@quotation +-Now is the time for all good men to come to the aid of their party. +-Four score and seven years ago, etc. +-@end quotation +- +-@cindex break +-@cindex line break +-Sometimes a new output line should be started even though the current +-line is not yet full; for example, at the end of a paragraph. To do +-this it is possible to cause a @dfn{break}, which starts a new output +-line. Some requests cause a break automatically, as normally do blank +-input lines and input lines beginning with a space. +- +-Not all input lines are text to be formatted. Some input lines are +-requests that describe how to format the text. Requests always have a +-period (@samp{.}) or an apostrophe (@samp{'}) as the first character of +-the input line. +- +-The text formatter also does more complex things, such as automatically +-numbering pages, skipping over page boundaries, putting footnotes in the +-correct place, and so forth. +- +-Here are a few hints for preparing text for input to @code{gtroff}. +- +-@itemize @bullet +-@item +-First, keep the input lines short. Short input lines are easier to +-edit, and @code{gtroff} packs words onto longer lines anyhow. +- +-@item +-In keeping with this, it is helpful to begin a new line after every +-comma or phrase, since common corrections are to add or delete sentences +-or phrases. +- +-@item +-End each sentence with two spaces -- or better, start each sentence on a +-new line. @code{gtroff} recognizes characters that usually end a +-sentence, and inserts sentence space accordingly. +- +-@item +-Do not hyphenate words at the end of lines -- @code{gtroff} is smart +-enough to hyphenate words as needed, but is not smart enough to take +-hyphens out and join a word back together. Also, words such as +-``mother-in-law'' should not be broken over a line, since then a space +-can occur where not wanted, such as ``@w{mother- in}-law''. +-@end itemize +- +-@cindex double-spacing (@code{ls}) +-@cindex spacing +-@code{gtroff} double-spaces output text automatically if you use the +-request @w{@samp{.ls 2}}. Reactivate single-spaced mode by typing +-@w{@samp{.ls 1}}.@footnote{If you need finer granularity of the vertical +-space, use the @code{pvs} request (@pxref{Changing Type Sizes}).} +- +-A number of requests allow to change the way the output looks, sometimes +-called the @dfn{layout} of the output page. Most of these requests +-adjust the placing of @dfn{whitespace} (blank lines or spaces). +- +-@cindex new page (@code{bp}) +-The @code{bp} request starts a new page, causing a line break. +- +-@cindex blank line (@code{sp}) +-@cindex empty line (@code{sp}) +-@cindex line, empty (@code{sp}) +-The request @w{@samp{.sp @var{N}}} leaves @var{N}@tie{}lines of blank +-space. @var{N}@tie{}can be omitted (meaning skip a single line) or can +-be of the form @var{N}i (for @var{N}@tie{}inches) or @var{N}c (for +-@var{N}@tie{}centimeters). For example, the input: +- +-@Example +-.sp 1.5i +-My thoughts on the subject +-.sp +-@endExample +- +-@noindent +-leaves one and a half inches of space, followed by the line ``My +-thoughts on the subject'', followed by a single blank line (more +-measurement units are available, see @ref{Measurements}). +- +-@cindex centering lines (@code{ce}) +-@cindex lines, centering (@code{ce}) +-Text lines can be centered by using the @code{ce} request. The line +-after @code{ce} is centered (horizontally) on the page. To center more +-than one line, use @w{@samp{.ce @var{N}}} (where @var{N} is the number +-of lines to center), followed by the @var{N}@tie{}lines. To center many +-lines without counting them, type: +- +-@Example +-.ce 1000 +-lines to center +-.ce 0 +-@endExample +- +-@noindent +-The @w{@samp{.ce 0}} request tells @code{groff} to center zero more +-lines, in other words, stop centering. +- +-@cindex line break (@code{br}) +-@cindex break (@code{br}) +-All of these requests cause a break; that is, they always start a new +-line. To start a new line without performing any other action, use +-@code{br}. +- +- +-@c ===================================================================== +- +-@node Common Features, , Basics, Tutorial for Macro Users +-@section Common Features +-@cindex common features +-@cindex features, common +- +-@code{gtroff} provides very low-level operations for formatting a +-document. There are many common routine operations that are done in +-all documents. These common operations are written into @dfn{macros} +-and collected into a @dfn{macro package}. +- +-All macro packages provide certain common capabilities that fall into +-the following categories. +- +-@menu +-* Paragraphs:: +-* Sections and Chapters:: +-* Headers and Footers:: +-* Page Layout Adjustment:: +-* Displays:: +-* Footnotes and Annotations:: +-* Table of Contents:: +-* Indices:: +-* Paper Formats:: +-* Multiple Columns:: +-* Font and Size Changes:: +-* Predefined Strings:: +-* Preprocessor Support:: +-* Configuration and Customization:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Paragraphs, Sections and Chapters, Common Features, Common Features +-@subsection Paragraphs +-@cindex paragraphs +- +-One of the most common and most used capability is starting a paragraph. +-There are a number of different types of paragraphs, any of which can be +-initiated with macros supplied by the macro package. Normally, +-paragraphs start with a blank line and the first line indented, like the +-text in this manual. There are also block style paragraphs, which omit +-the indentation: +- +-@Example +-Some men look at constitutions with sanctimonious +-reverence, and deem them like the ark of the covenant, too +-sacred to be touched. +-@endExample +- +-@noindent +-And there are also indented paragraphs, which begin with a tag or label +-at the margin and the remaining text indented. +- +-@Example +-one This is the first paragraph. Notice how the first +- line of the resulting paragraph lines up with the +- other lines in the paragraph. +-@endExample +- +-@Example +-longlabel +- This paragraph had a long label. The first +- character of text on the first line does not line up +- with the text on second and subsequent lines, +- although they line up with each other. +-@endExample +- +-A variation of this is a bulleted list. +- +-@Example +-. Bulleted lists start with a bullet. It is possible +- to use other glyphs instead of the bullet. In nroff +- mode using the ASCII character set for output, a dot +- is used instead of a real bullet. +-@endExample +- +-@c --------------------------------------------------------------------- +- +-@node Sections and Chapters, Headers and Footers, Paragraphs, Common Features +-@subsection Sections and Chapters +- +-Most macro packages supply some form of section headers. The simplest +-kind is simply the heading on a line by itself in bold type. Others +-supply automatically numbered section heading or different heading +-styles at different levels. Some, more sophisticated, macro packages +-supply macros for starting chapters and appendices. +- +-@c --------------------------------------------------------------------- +- +-@node Headers and Footers, Page Layout Adjustment, Sections and Chapters, Common Features +-@subsection Headers and Footers +- +-Every macro package gives some way to manipulate the @dfn{headers} and +-@dfn{footers} (also called @dfn{titles}) on each page. This is text put +-at the top and bottom of each page, respectively, which contain data +-like the current page number, the current chapter title, and so on. Its +-appearance is not affected by the running text. Some packages allow for +-different ones on the even and odd pages (for material printed in a book +-form). +- +-The titles are called @dfn{three-part titles}, that is, there is a +-left-justified part, a centered part, and a right-justified part. An +-automatically generated page number may be put in any of these fields +-with the @samp{%} character (see @ref{Page Layout}, for more details). +- +-@c --------------------------------------------------------------------- +- +-@node Page Layout Adjustment, Displays, Headers and Footers, Common Features +-@subsection Page Layout +- +-Most macro packages let the user specify top and bottom margins and +-other details about the appearance of the printed pages. +- +-@c --------------------------------------------------------------------- +- +-@node Displays, Footnotes and Annotations, Page Layout Adjustment, Common Features +-@subsection Displays +-@cindex displays +- +-@dfn{Displays} are sections of text to be set off from the body of the +-paper. Major quotes, tables, and figures are types of displays, as are +-all the examples used in this document. +- +-@cindex quotes, major +-@cindex major quotes +-@dfn{Major quotes} are quotes that are several lines long, and hence +-are set in from the rest of the text without quote marks around them. +- +-@cindex list +-A @dfn{list} is an indented, single-spaced, unfilled display. Lists +-should be used when the material to be printed should not be filled and +-justified like normal text, such as columns of figures or the examples +-used in this paper. +- +-@cindex keep +-A @dfn{keep} is a display of lines that are kept on a single page if +-possible. An example for a keep might be a diagram. Keeps differ from +-lists in that lists may be broken over a page boundary whereas keeps are +-not. +- +-@cindex keep, floating +-@cindex floating keep +-@dfn{Floating keeps} move relative to the text. Hence, they are good +-for things that are referred to by name, such as ``See figure@tie{}3''. +-A floating keep appears at the bottom of the current page if it fits; +-otherwise, it appears at the top of the next page. Meanwhile, the +-surrounding text `flows' around the keep, thus leaving no blank areas. +- +-@c --------------------------------------------------------------------- +- +-@node Footnotes and Annotations, Table of Contents, Displays, Common Features +-@subsection Footnotes and Annotations +-@cindex footnotes +-@cindex annotations +- +-There are a number of requests to save text for later printing. +- +-@dfn{Footnotes} are printed at the bottom of the current page. +- +-@cindex delayed text +-@dfn{Delayed text} is very similar to a footnote except that it is +-printed when called for explicitly. This allows a list of references to +-appear (for example) at the end of each chapter, as is the convention in +-some disciplines. +- +-Most macro packages that supply this functionality also supply a means +-of automatically numbering either type of annotation. +- +-@c --------------------------------------------------------------------- +- +-@node Table of Contents, Indices, Footnotes and Annotations, Common Features +-@subsection Table of Contents +-@cindex table of contents +-@cindex contents, table of +- +-@dfn{Tables of contents} are a type of delayed text having a tag +-(usually the page number) attached to each entry after a row of dots. +-The table accumulates throughout the paper until printed, usually after +-the paper has ended. Many macro packages provide the ability to have +-several tables of contents (e.g.@: a standard table of contents, a list +-of tables, etc). +- +-@c --------------------------------------------------------------------- +- +-@node Indices, Paper Formats, Table of Contents, Common Features +-@subsection Indices +-@cindex index, in macro package +- +-While some macro packages use the term @dfn{index}, none actually +-provide that functionality. The facilities they call indices are +-actually more appropriate for tables of contents. +- +-@pindex makeindex +-To produce a real index in a document, external tools like the +-@code{makeindex} program are necessary. +- +-@c --------------------------------------------------------------------- +- +-@node Paper Formats, Multiple Columns, Indices, Common Features +-@subsection Paper Formats +-@cindex paper formats +- +-Some macro packages provide stock formats for various kinds of +-documents. Many of them provide a common format for the title and +-opening pages of a technical paper. The @file{mm} macros in particular +-provide formats for letters and memoranda. +- +-@c --------------------------------------------------------------------- +- +-@node Multiple Columns, Font and Size Changes, Paper Formats, Common Features +-@subsection Multiple Columns +- +-Some macro packages (but not @file{man}) provide the ability to have two +-or more columns on a page. +- +-@c --------------------------------------------------------------------- +- +-@node Font and Size Changes, Predefined Strings, Multiple Columns, Common Features +-@subsection Font and Size Changes +- +-The built-in font and size functions are not always intuitive, so all +-macro packages provide macros to make these operations simpler. +- +-@c --------------------------------------------------------------------- +- +-@node Predefined Strings, Preprocessor Support, Font and Size Changes, Common Features +-@subsection Predefined Strings +- +-Most macro packages provide various predefined strings for a variety of +-uses; examples are sub- and superscripts, printable dates, quotes and +-various special characters. +- +-@c --------------------------------------------------------------------- +- +-@node Preprocessor Support, Configuration and Customization, Predefined Strings, Common Features +-@subsection Preprocessor Support +- +-All macro packages provide support for various preprocessors and may +-extend their functionality. +- +-For example, all macro packages mark tables (which are processed with +-@code{gtbl}) by placing them between @code{TS} and @code{TE} macros. +-The @file{ms} macro package has an option, @samp{.TS@tie{}H}, that +-prints a caption at the top of a new page (when the table is too long to +-fit on a single page). +- +-@c --------------------------------------------------------------------- +- +-@node Configuration and Customization, , Preprocessor Support, Common Features +-@subsection Configuration and Customization +- +-Some macro packages provide means of customizing many of the details of +-how the package behaves. This ranges from setting the default type size +-to changing the appearance of section headers. +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Macro Packages, gtroff Reference, Tutorial for Macro Users, Top +-@chapter Macro Packages +-@cindex macro packages +-@cindex packages, macros +- +-This chapter documents the main macro packages that come with +-@code{groff}. +- +-Different main macro packages can't be used at the same time; for +-example +- +-@Example +-groff -m man foo.man -m ms bar.doc +-@endExample +- +-@noindent +-doesn't work. Note that option arguments are processed before +-non-option arguments; the above (failing) sample is thus reordered to +- +-@Example +-groff -m man -m ms foo.man bar.doc +-@endExample +- +-@menu +-* man:: +-* mdoc:: +-* ms:: +-* me:: +-* mm:: +-* mom:: +-@end menu +- +- +-@c ===================================================================== +- +-@node man, mdoc, Macro Packages, Macro Packages +-@section @file{man} +-@cindex manual pages +-@cindex man pages +-@pindex an.tmac +-@pindex man.tmac +-@pindex man-old.tmac +- +-This is the most popular and probably the most important macro package +-of @code{groff}. It is easy to use, and a vast majority of manual pages +-are based on it. +- +-@menu +-* Man options:: +-* Man usage:: +-* Man font macros:: +-* Miscellaneous man macros:: +-* Predefined man strings:: +-* Preprocessors in man pages:: +-* Optional man extensions:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Man options, Man usage, man, man +-@subsection Options +- +-The command line format for using the @file{man} macros with +-@code{groff} is: +- +-@Example +-groff -m man [ -rLL=@var{length} ] [ -rLT=@var{length} ] [ -rFT=@var{dist} ] +- [ -rcR=1 ] [ -rC1 ] [ -rD1 ] [-rHY=@var{flags} ] +- [ -rP@var{nnn} ] [ -rS@var{xx} ] [ -rX@var{nnn} ] +- [ -rIN=@var{length} ] [ -rSN=@var{length} ] [ @var{files}@dots{} ] +-@endExample +- +-@noindent +-It is possible to use @samp{-man} instead of @w{@samp{-m man}}. +- +-@table @code +-@item -rcR=1 +-This option (the default if a TTY output device is used) creates a +-single, very long page instead of multiple pages. Use @code{-rcR=0} to +-disable it. +- +-@item -rC1 +-If more than one manual page is given on the command line, number the +-pages continuously, rather than starting each at@tie{}1. +- +-@item -rD1 +-Double-sided printing. Footers for even and odd pages are formatted +-differently. +- +-@item -rFT=@var{dist} +-Set the position of the footer text to @var{dist}. If positive, the +-distance is measured relative to the top of the page, otherwise it is +-relative to the bottom. The default is @minus{}0.5@dmn{i}. +- +-@item -rHY=@var{flags} +-Set hyphenation flags. Possible values are 1@tie{}to hyphenate without +-restrictions, 2@tie{}to not hyphenate the last word on a page, 4@tie{}to +-not hyphenate the last two characters of a word, and 8@tie{}to not +-hyphenate the first two characters of a word. These values are +-additive; the default is@tie{}14. +- +-@item -rIN=@var{length} +-Set the body text indentation to @var{length}. If not specified, the +-indentation defaults to 7@dmn{n} (7@tie{}characters) in nroff mode and +-7.2@dmn{n} otherwise. For nroff, this value should always be an integer +-multiple of unit @samp{n} to get consistent indentation. +- +-@item -rLL=@var{length} +-Set line length to @var{length}. If not specified, the line length is +-set to respect any value set by a prior @samp{ll} request (which +-@emph{must} be in effect when the @samp{TH} macro is invoked), if this +-differs from the built-in default for the formatter; otherwise it +-defaults to 78@dmn{n} in nroff mode (this is 78 characters per line) and +-6.5@dmn{i} in troff mode.@footnote{Note that the use of a @samp{.ll +-@var{length}} request to initialize the line length, prior to use of the +-@samp{TH} macro, is supported for backward compatibility with some +-versions of the @code{man} program. @emph{Always} use the +-@option{-rLL=@var{length}} option, or an equivalent @samp{.nr LL +-@var{length}} request, in preference to such a @samp{.ll @var{length}} +-request. In particular, note that in nroff mode, the request @samp{.ll +-65n}, (with any @var{length} expression that evaluates equal to +-65@dmn{n}, i.e., the formatter's default line length in nroff mode), +-does @emph{not} set the line length to 65@dmn{n} (it is adjusted to the +-@code{man} macro package's default setting of 78@dmn{n}), whereas the +-use of the @option{-rLL=65n} option, or the @samp{.nr LL 65n} request +-@emph{does} establish a line length of 65@dmn{n}.} +- +-@item -rLT=@var{length} +-Set title length to @var{length}. If not specified, the title length +-defaults to the line length. +- +-@item -rP@var{nnn} +-Page numbering starts with @var{nnn} rather than with@tie{}1. +- +-@item -rS@var{xx} +-Use @var{xx} (which can be 10, 11, or@tie{}12@dmn{pt}) as the base +-document font size instead of the default value of@tie{}10@dmn{pt}. +- +-@item -rSN=@var{length} +-Set the indentation for sub-subheadings to @var{length}. If not +-specified, the indentation defaults to 3@dmn{n}. +- +-@item -rX@var{nnn} +-After page @var{nnn}, number pages as @var{nnn}a, @var{nnn}b, +-@var{nnn}c, etc. For example, the option @option{-rX2} produces the +-following page numbers: 1, 2, 2a, 2b, 2c, etc. +-@end table +- +-@c --------------------------------------------------------------------- +- +-@node Man usage, Man font macros, Man options, man +-@subsection Usage +-@cindex @code{man} macros +-@cindex macros for manual pages [@code{man}] +- +-@pindex man.local +-This section describes the available macros for manual pages. For +-further customization, put additional macros and requests into the file +-@file{man.local}, which is loaded immediately after the @file{man} +-package. +- +-@Defmac {TH, title section [@Var{extra1} [@Var{extra2} [@Var{extra3}]]], man} +-Set the title of the man page to @var{title} and the section to +-@var{section}, which must have a value between 1 and@tie{}8. The value +-of @var{section} may also have a string appended, e.g.@: @samp{.pm}, to +-indicate a specific subsection of the man pages. +- +-Both @var{title} and @var{section} are positioned at the left and right +-in the header line (with @var{section} in parentheses immediately +-appended to @var{title}. @var{extra1} is positioned in the middle of +-the footer line. @var{extra2} is positioned at the left in the footer +-line (or at the left on even pages and at the right on odd pages if +-double-sided printing is active). @var{extra3} is centered in the +-header line. +- +-For @acronym{HTML} and @acronym{XHTML} output, headers and footers are +-completely suppressed. +- +-Additionally, this macro starts a new page; the new line number +-is@tie{}1 again (except if the @option{-rC1} option is given on the +-command line) -- this feature is intended only for formatting multiple +-man pages; a single man page should contain exactly one @code{TH} macro +-at the beginning of the file. +-@endDefmac +- +-@Defmac {SH, [@Var{heading}], man} +-Set up an unnumbered section heading sticking out to the left. Prints +-out all the text following @code{SH} up to the end of the line (or the +-text in the next line if there is no argument to @code{SH}) in bold face +-(or the font specified by the string @code{HF}), one size larger than +-the base document size. Additionally, the left margin and the +-indentation for the following text is reset to its default value. +-@endDefmac +- +-@Defmac {SS, [@Var{heading}], man} +-Set up an unnumbered (sub)section heading. Prints out all the text +-following @code{SS} up to the end of the line (or the text in the next +-line if there is no argument to @code{SS}) in bold face (or the font +-specified by the string @code{HF}), at the same size as the base +-document size. Additionally, the left margin and the indentation for +-the following text is reset to its default value. +-@endDefmac +- +-@Defmac {TP, [@Var{nnn}], man} +-Set up an indented paragraph with label. The indentation is set to +-@var{nnn} if that argument is supplied (the default unit is @samp{n} if +-omitted), otherwise it is set to the previous indentation value +-specified with @code{TP}, @code{IP}, or @code{HP} (or to the default +-value if none of them have been used yet). +- +-The first line of text following this macro is interpreted as a string +-to be printed flush-left, as it is appropriate for a label. It is not +-interpreted as part of a paragraph, so there is no attempt to fill the +-first line with text from the following input lines. Nevertheless, if +-the label is not as wide as the indentation the paragraph starts at the +-same line (but indented), continuing on the following lines. If the +-label is wider than the indentation the descriptive part of the +-paragraph begins on the line following the label, entirely indented. +-Note that neither font shape nor font size of the label is set to a +-default value; on the other hand, the rest of the text has default font +-settings. +-@endDefmac +- +-@DefmacList {LP, , man} +-@DefmacItemx {PP, , man} +-@DefmacListEndx {P, , man} +-These macros are mutual aliases. Any of them causes a line break at the +-current position, followed by a vertical space downwards by the amount +-specified by the @code{PD} macro. The font size and shape are reset to +-the default value (10@dmn{pt} roman if no @option{-rS} option is given +-on the command line). Finally, the current left margin and the +-indentation is restored. +-@endDefmac +- +-@Defmac {IP, [@Var{designator} [@Var{nnn}]], man} +-Set up an indented paragraph, using @var{designator} as a tag to mark +-its beginning. The indentation is set to @var{nnn} if that argument is +-supplied (default unit is @samp{n}), otherwise it is set to the previous +-indentation value specified with @code{TP}, @code{IP}, or @code{HP} (or +-the default value if none of them have been used yet). Font size and +-face of the paragraph (but not the designator) are reset to their +-default values. +- +-To start an indented paragraph with a particular indentation but without +-a designator, use @samp{""} (two double quotes) as the first argument of +-@code{IP}. +- +-For example, to start a paragraph with bullets as the designator and +-4@tie{}en indentation, write +- +-@Example +-.IP \(bu 4 +-@endExample +-@endDefmac +- +-@Defmac {HP, [@Var{nnn}], man} +-@cindex hanging indentation [@code{man}] +-@cindex @code{man} macros, hanging indentation +-Set up a paragraph with hanging left indentation. The indentation is +-set to @var{nnn} if that argument is supplied (default unit is +-@samp{n}), otherwise it is set to the previous indentation value +-specified with @code{TP}, @code{IP}, or @code{HP} (or the default value +-if non of them have been used yet). Font size and face are reset to +-their default values. +-@endDefmac +- +-@Defmac {RS, [@Var{nnn}], man} +-@cindex left margin, how to move [@code{man}] +-@cindex @code{man} macros, moving left margin +-Move the left margin to the right by the value @var{nnn} if specified +-(default unit is @samp{n}); otherwise it is set to the previous +-indentation value specified with @code{TP}, @code{IP}, or @code{HP} (or +-to the default value if none of them have been used yet). The +-indentation value is then set to the default. +- +-Calls to the @code{RS} macro can be nested. +-@endDefmac +- +-@Defmac {RE, [@Var{nnn}], man} +-Move the left margin back to level @var{nnn}, restoring the previous +-left margin. If no argument is given, it moves one level back. The +-first level (i.e., no call to @code{RS} yet) has number@tie{}1, and each +-call to @code{RS} increases the level by@tie{}1. +-@endDefmac +- +-@cindex line breaks, with vertical space [@code{man}] +-@cindex @code{man} macros, line breaks with vertical space +-To summarize, the following macros cause a line break with the insertion +-of vertical space (which amount can be changed with the @code{PD} +-macro): @code{SH}, @code{SS}, @code{TP}, @code{LP} (@code{PP}, +-@code{P}), @code{IP}, and @code{HP}. +- +-@cindex line breaks, without vertical space [@code{man}] +-@cindex @code{man} macros, line breaks without vertical space +-The macros @code{RS} and @code{RE} also cause a break but do not insert +-vertical space. +- +-@cindex default indentation, resetting [@code{man}] +-@cindex indentaion, resetting to default [@code{man}] +-@cindex @code{man} macros, resetting default indentation +-Finally, the macros @code{SH}, @code{SS}, @code{LP} (@code{PP}, +-@code{P}), and @code{RS} reset the indentation to its default value. +- +-@c --------------------------------------------------------------------- +- +-@node Man font macros, Miscellaneous man macros, Man usage, man +-@subsection Macros to set fonts +-@cindex font selection [@code{man}] +-@cindex @code{man} macros, how to set fonts +- +-The standard font is roman; the default text size is 10@tie{}point. If +-command line option @option{-rS=@var{n}} is given, use @var{n}@dmn{pt} +-as the default text size. +- +-@Defmac {SM, [@Var{text}], man} +-Set the text on the same line or the text on the next line in a font +-that is one point size smaller than the default font. +-@endDefmac +- +-@Defmac {SB, [@Var{text}], man} +-@cindex bold face [@code{man}] +-@cindex @code{man} macros, bold face +-Set the text on the same line or the text on the next line in bold face +-font, one point size smaller than the default font. +-@endDefmac +- +-@Defmac {BI, text, man} +-Set its arguments alternately in bold face and italic, without a space +-between the arguments. Thus, +- +-@Example +-.BI this "word and" that +-@endExample +- +-@noindent +-produces ``thisword andthat'' with ``this'' and ``that'' in bold face, +-and ``word and'' in italics. +-@endDefmac +- +-@Defmac {IB, text, man} +-Set its arguments alternately in italic and bold face, without a space +-between the arguments. +-@endDefmac +- +-@Defmac {RI, text, man} +-Set its arguments alternately in roman and italic, without a space +-between the arguments. +-@endDefmac +- +-@Defmac {IR, text, man} +-Set its arguments alternately in italic and roman, without a space +-between the arguments. +-@endDefmac +- +-@Defmac {BR, text, man} +-Set its arguments alternately in bold face and roman, without a space +-between the arguments. +-@endDefmac +- +-@Defmac {RB, text, man} +-Set its arguments alternately in roman and bold face, without a space +-between the arguments. +-@endDefmac +- +-@Defmac {B, [@Var{text}], man} +-Set @var{text} in bold face. If no text is present on the line where +-the macro is called, then the text of the next line appears in bold +-face. +-@endDefmac +- +-@Defmac {I, [@Var{text}], man} +-@cindex italic fonts [@code{man}] +-@cindex @code{man} macros, italic fonts +-Set @var{text} in italic. If no text is present on the line where the +-macro is called, then the text of the next line appears in italic. +-@endDefmac +- +-@c --------------------------------------------------------------------- +- +-@node Miscellaneous man macros, Predefined man strings, Man font macros, man +-@subsection Miscellaneous macros +- +-@pindex grohtml +-@cindex @code{man} macros, default indentation +-@cindex default indentation [@code{man}] +-The default indentation is 7.2@dmn{n} in troff mode and 7@dmn{n} in +-nroff mode except for @code{grohtml}, which ignores indentation. +- +-@Defmac {DT, , man} +-@cindex tab stops [@code{man}] +-@cindex @code{man} macros, tab stops +-Set tabs every 0.5@tie{}inches. Since this macro is always executed +-during a call to the @code{TH} macro, it makes sense to call it only if +-the tab positions have been changed. +-@endDefmac +- +-@Defmac {PD, [@Var{nnn}], man} +-@cindex empty space before a paragraph [@code{man}] +-@cindex @code{man} macros, empty space before a paragraph +-Adjust the empty space before a new paragraph (or section). The +-optional argument gives the amount of space (default unit is @samp{v}); +-without parameter, the value is reset to its default value (1@tie{}line +-in nroff mode, 0.4@dmn{v}@tie{}otherwise). +- +-This affects the macros @code{SH}, @code{SS}, @code{TP}, @code{LP} (as +-well as @code{PP} and @code{P}), @code{IP}, and @code{HP}. +-@endDefmac +- +-The following two macros are included for BSD compatibility. +- +-@Defmac {AT, [@Var{system} [@Var{release}]], man} +-@cindex @code{man}macros, BSD compatibility +-Alter the footer for use with @acronym{AT&T} manpages. This command +-exists only for compatibility; don't use it. The first argument +-@var{system} can be: +- +-@table @code +-@item 3 +-7th Edition (the default) +- +-@item 4 +-System III +- +-@item 5 +-System V +-@end table +- +-An optional second argument @var{release} to @code{AT} specifies the +-release number (such as ``System V Release 3''). +-@endDefmac +- +-@Defmac {UC, [@Var{version}], man} +-@cindex @code{man}macros, BSD compatibility +-Alters the footer for use with BSD manpages. This command exists only +-for compatibility; don't use it. The argument can be: +- +-@table @code +-@item 3 +-3rd Berkeley Distribution (the default) +- +-@item 4 +-4th Berkeley Distribution +- +-@item 5 +-4.2 Berkeley Distribution +- +-@item 6 +-4.3 Berkeley Distribution +- +-@item 7 +-4.4 Berkeley Distribution +-@end table +-@endDefmac +- +-@c --------------------------------------------------------------------- +- +-@node Predefined man strings, Preprocessors in man pages, Miscellaneous man macros, man +-@subsection Predefined strings +- +-The following strings are defined: +- +-@Defstr {S, man} +-Switch back to the default font size. +-@endDefstr +- +-@Defstr {HF, man} +-The typeface used for headings. +-The default is @samp{B}. +-@endDefstr +- +-@Defstr {R, man} +-The `registered' sign. +-@endDefstr +- +-@Defstr {Tm, man} +-The `trademark' sign. +-@endDefstr +- +-@DefstrList {lq, man} +-@DefstrListEndx {rq, man} +-@cindex @code{lq} glyph, and @code{lq} string [@code{man}] +-@cindex @code{rq} glyph, and @code{rq} string [@code{man}] +-Left and right quote. This is equal to @code{\(lq} and @code{\(rq}, +-respectively. +-@endDefstr +- +-@c --------------------------------------------------------------------- +- +-@node Preprocessors in man pages, Optional man extensions, Predefined man strings, man +-@subsection Preprocessors in @file{man} pages +- +-@cindex preprocessor, calling convention +-@cindex calling convention of preprocessors +-If a preprocessor like @code{gtbl} or @code{geqn} is needed, it has +-become common usage to make the first line of the man page look like +-this: +- +-@Example +-'\" @var{word} +-@endExample +- +-@pindex geqn@r{, invocation in manual pages} +-@pindex grefer@r{, invocation in manual pages} +-@pindex gtbl@r{, invocation in manual pages} +-@pindex man@r{, invocation of preprocessors} +-@noindent +-Note the single space character after the double quote. @var{word} +-consists of letters for the needed preprocessors: @samp{e} for +-@code{geqn}, @samp{r} for @code{grefer}, @samp{t} for @code{gtbl}. +-Modern implementations of the @code{man} program read this first line +-and automatically call the right preprocessor(s). +- +-@c --------------------------------------------------------------------- +- +-@node Optional man extensions, , Preprocessors in man pages, man +-@subsection Optional @file{man} extensions +- +-@pindex man.local +-Use the file @file{man.local} for local extensions to the @code{man} +-macros or for style changes. +- +-@unnumberedsubsubsec Custom headers and footers +-@cindex @code{man} macros, custom headers and footers +- +-In groff versions 1.18.2 and later, you can specify custom headers and +-footers by redefining the following macros in @file{man.local}. +- +-@Defmac {PT, , man} +-Control the content of the headers. Normally, the header prints the +-command name and section number on either side, and the optional fifth +-argument to @code{TH} in the center. +-@endDefmac +- +-@Defmac {BT, , man} +-Control the content of the footers. Normally, the footer prints the +-page number and the third and fourth arguments to @code{TH}. +- +-Use the @code{FT} number register to specify the footer position. The +-default is @minus{}0.5@dmn{i}. +-@endDefmac +- +-@unnumberedsubsubsec Ultrix-specific man macros +-@cindex Ultrix-specific @code{man} macros +-@cindex @code{man} macros, Ultrix-specific +- +-@pindex man.ultrix +-The @code{groff} source distribution includes a file named +-@file{man.ultrix}, containing macros compatible with the Ultrix variant +-of @code{man}. Copy this file into @file{man.local} (or use the +-@code{mso} request to load it) to enable the following macros. +- +-@Defmac {CT, @Var{key}, man} +-Print @samp{}. +-@endDefmac +- +-@Defmac {CW, , man} +-Print subsequent text using the constant width (Courier) typeface. +-@endDefmac +- +-@Defmac {Ds, , man} +-Begin a non-filled display. +-@endDefmac +- +-@Defmac {De, , man} +-End a non-filled display started with @code{Ds}. +-@endDefmac +- +-@Defmac {EX, [@Var{indent}], man} +-Begin a non-filled display using the constant width (Courier) typeface. +-Use the optional @var{indent} argument to indent the display. +-@endDefmac +- +-@Defmac {EE, , man} +-End a non-filled display started with @code{EX}. +-@endDefmac +- +-@Defmac {G, [@Var{text}], man} +-Set @var{text} in Helvetica. If no text is present on the line where +-the macro is called, then the text of the next line appears in +-Helvetica. +-@endDefmac +- +-@Defmac {GL, [@Var{text}], man} +-Set @var{text} in Helvetica Oblique. If no text is present on the line +-where the macro is called, then the text of the next line appears in +-Helvetica Oblique. +-@endDefmac +- +-@Defmac {HB, [@Var{text}], man} +-Set @var{text} in Helvetica Bold. If no text is present on the line +-where the macro is called, then all text up to the next @code{HB} +-appears in Helvetica Bold. +-@endDefmac +- +-@Defmac {TB, [@Var{text}], man} +-Identical to @code{HB}. +-@endDefmac +- +-@Defmac {MS, @Var{title} @Var{sect} [@Var{punct}], man} +-Set a manpage reference in Ultrix format. The @var{title} is in Courier +-instead of italic. Optional punctuation follows the section number +-without an intervening space. +-@endDefmac +- +-@Defmac {NT, [@code{C}] [@Var{title}], man} +-Begin a note. Print the optional @Var{title}, or the word ``Note'', +-centered on the page. Text following the macro makes up the body of the +-note, and is indented on both sides. If the first argument is @code{C}, +-the body of the note is printed centered (the second argument replaces +-the word ``Note'' if specified). +-@endDefmac +- +-@Defmac {NE, , man} +-End a note begun with @code{NT}. +-@endDefmac +- +-@Defmac {PN, @Var{path} [@Var{punct}], man} +-Set the path name in constant width (Courier), followed by optional +-punctuation. +-@endDefmac +- +-@Defmac {Pn, [@Var{punct}] @Var{path} [@Var{punct}], man} +-If called with two arguments, identical to @code{PN}. If called with +-three arguments, set the second argument in constant width (Courier), +-bracketed by the first and third arguments in the current font. +-@endDefmac +- +-@Defmac {R, , man} +-Switch to roman font and turn off any underlining in effect. +-@endDefmac +- +-@Defmac {RN, , man} +-Print the string @samp{}. +-@endDefmac +- +-@Defmac {VS, [@code{4}], man} +-Start printing a change bar in the margin if the number@tie{}@code{4} is +-specified. Otherwise, this macro does nothing. +-@endDefmac +- +-@Defmac {VE, , man} +-End printing the change bar begun by @code{VS}. +-@endDefmac +- +-@unnumberedsubsubsec Simple example +- +-The following example @file{man.local} file alters the @code{SH} macro +-to add some extra vertical space before printing the heading. Headings +-are printed in Helvetica Bold. +- +-@Example +-.\" Make the heading fonts Helvetica +-.ds HF HB +-. +-.\" Put more whitespace in front of headings. +-.rn SH SH-orig +-.de SH +-. if t .sp (u;\\n[PD]*2) +-. SH-orig \\$* +-.. +-@endExample +- +- +-@c ===================================================================== +- +-@node mdoc, ms, man, Macro Packages +-@section @file{mdoc} +-@cindex @code{mdoc} macros +- +-@c XXX documentation +-@c XXX this is a placeholder until we get stuff knocked into shape +-See the @cite{groff_mdoc(7)} man page (type @command{man groff_mdoc} +-at the command line). +- +- +-@c ===================================================================== +- +-@node ms, me, mdoc, Macro Packages +-@section @file{ms} +-@cindex @code{ms} macros +- +-The @file{-ms} macros are suitable for reports, letters, books, user +-manuals, and so forth. The package provides macros for cover pages, +-section headings, paragraphs, lists, footnotes, pagination, and a table +-of contents. +- +-@menu +-* ms Intro:: +-* General ms Structure:: +-* ms Document Control Registers:: +-* ms Cover Page Macros:: +-* ms Body Text:: +-* ms Page Layout:: +-* Differences from AT&T ms:: +-* Naming Conventions:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node ms Intro, General ms Structure, ms, ms +-@subsection Introduction to @file{ms} +- +-The original @file{-ms} macros were included with @acronym{AT&T} +-@code{troff} as well as the @file{man} macros. While the @file{man} +-package is intended for brief documents that can be read on-line as well +-as printed, the @file{ms} macros are suitable for longer documents that +-are meant to be printed rather than read on-line. +- +-The @file{ms} macro package included with @code{groff} is a complete, +-bottom-up re-implementation. Several macros (specific to @acronym{AT&T} +-or Berkeley) are not included, while several new commands are. +-@xref{Differences from AT&T ms}, for more information. +- +-@c --------------------------------------------------------------------- +- +-@node General ms Structure, ms Document Control Registers, ms Intro, ms +-@subsection General structure of an @file{ms} document +-@cindex @code{ms} macros, general structure +- +-The @file{ms} macro package expects a certain amount of structure, but +-not as much as packages such as @file{man} or @file{mdoc}. +- +-The simplest documents can begin with a paragraph macro (such as +-@code{LP} or @code{PP}), and consist of text separated by paragraph +-macros or even blank lines. Longer documents have a structure as +-follows: +- +-@table @strong +-@item Document type +-If you invoke the @code{RP} (report) macro on the first line of the +-document, @code{groff} prints the cover page information on its own +-page; otherwise it prints the information on the first page with your +-document text immediately following. Other document formats found in +-@acronym{AT&T} @code{troff} are specific to @acronym{AT&T} or Berkeley, +-and are not supported in @code{groff}. +- +-@item Format and layout +-By setting number registers, you can change your document's type (font +-and size), margins, spacing, headers and footers, and footnotes. +-@xref{ms Document Control Registers}, for more details. +- +-@item Cover page +-A cover page consists of a title, the author's name and institution, an +-abstract, and the date.@footnote{Actually, only the title is required.} +-@xref{ms Cover Page Macros}, for more details. +- +-@item Body +-Following the cover page is your document. You can use the @file{ms} +-macros to write reports, letters, books, and so forth. The package is +-designed for structured documents, consisting of paragraphs interspersed +-with headings and augmented by lists, footnotes, tables, and other +-common constructs. @xref{ms Body Text}, for more details. +- +-@item Table of contents +-Longer documents usually include a table of contents, which you can +-invoke by placing the @code{TC} macro at the end of your document. The +-@file{ms} macros have minimal indexing facilities, consisting of the +-@code{IX} macro, which prints an entry on standard error. Printing the +-table of contents at the end is necessary since @code{groff} is a +-single-pass text formatter, thus it cannot determine the page number of +-each section until that section has actually been set and printed. +-Since @file{ms} output is intended for hardcopy, you can manually +-relocate the pages containing the table of contents between the cover +-page and the body text after printing. +-@end table +- +-@c --------------------------------------------------------------------- +- +-@node ms Document Control Registers, ms Cover Page Macros, General ms Structure, ms +-@subsection Document control registers +-@cindex @code{ms} macros, document control registers +- +-The following is a list of document control number registers. For the +-sake of consistency, set registers related to margins at the beginning +-of your document, or just after the @code{RP} macro. You can set other +-registers later in your document, but you should keep them together at +-the beginning to make them easy to find and edit as necessary. +- +-@unnumberedsubsubsec Margin Settings +- +-@Defmpreg {PO, ms} +-Defines the page offset (i.e., the left margin). There is no explicit +-right margin setting; the combination of the @code{PO} and @code{LL} +-registers implicitly define the right margin width. +- +-Effective: next page. +- +-Default value: 1@dmn{i}. +-@endDefmpreg +- +-@Defmpreg {LL, ms} +-Defines the line length (i.e., the width of the body text). +- +-Effective: next paragraph. +- +-Default: 6@dmn{i}. +-@endDefmpreg +- +-@Defmpreg {LT, ms} +-Defines the title length (i.e., the header and footer width). This +-is usually the same as @code{LL}, but not necessarily. +- +-Effective: next paragraph. +- +-Default: 6@dmn{i}. +-@endDefmpreg +- +-@Defmpreg {HM, ms} +-Defines the header margin height at the top of the page. +- +-Effective: next page. +- +-Default: 1@dmn{i}. +-@endDefmpreg +- +-@Defmpreg {FM, ms} +-Defines the footer margin height at the bottom of the page. +- +-Effective: next page. +- +-Default: 1@dmn{i}. +-@endDefmpreg +- +-@unnumberedsubsubsec Text Settings +- +-@Defmpreg {PS, ms} +-Defines the point size of the body text. If the value is larger than or +-equal to 1000, divide it by 1000 to get a fractional point size. For +-example, @samp{.nr PS 10250} sets the document's point size to +-10.25@dmn{p}. +- +-Effective: next paragraph. +- +-Default: 10@dmn{p}. +-@endDefmpreg +- +-@Defmpreg {VS, ms} +-Defines the space between lines (line height plus leading). If the +-value is larger than or equal to 1000, divide it by 1000 to get a +-fractional point size. Due to backwards compatibility, @code{VS} must +-be smaller than 40000 (this is 40.0@dmn{p}). +- +-Effective: next paragraph. +- +-Default: 12@dmn{p}. +-@endDefmpreg +- +-@Defmpreg {PSINCR, ms} +-Defines an increment in point size, which is applied to section headings +-at nesting levels below the value specified in @code{GROWPS}. The value +-of @code{PSINCR} should be specified in points, with the @dmn{p} scaling +-factor, and may include a fractional component; for example, +-@w{@samp{.nr PSINCR 1.5p}} sets a point size increment of 1.5@dmn{p}. +- +-Effective: next section heading. +- +-Default: 1@dmn{p}. +-@endDefmpreg +- +-@Defmpreg {GROWPS, ms} +-Defines the heading level below which the point size increment set by +-@code{PSINCR} becomes effective. Section headings at and above the +-level specified by @code{GROWPS} are printed at the point size set by +-@code{PS}; for each level below the value of @code{GROWPS}, the point +-size is increased in steps equal to the value of @code{PSINCR}. Setting +-@code{GROWPS} to any value less than@tie{}2 disables the incremental +-heading size feature. +- +-Effective: next section heading. +- +-Default: 0. +-@endDefmpreg +- +-@Defmpreg {HY, ms} +-Defines the hyphenation level. @code{HY} sets safely the value of the +-low-level @code{hy} register. Setting the value of @code{HY} to@tie{}0 +-is equivalent to using the @code{nh} request. +- +-Effective: next paragraph. +- +-Default: 14. +-@endDefmpreg +- +-@Defmpreg {FAM, ms} +-Defines the font family used to typeset the document. +- +-Effective: next paragraph. +- +-Default: as defined in the output device. +-@endDefmpreg +- +-@unnumberedsubsubsec Paragraph Settings +- +-@Defmpreg {PI, ms} +-Defines the initial indentation of a (@code{PP} macro) paragraph. +- +-Effective: next paragraph. +- +-Default: 5@dmn{n}. +-@endDefmpreg +- +-@Defmpreg {PD, ms} +-Defines the space between paragraphs. +- +-Effective: next paragraph. +- +-Default: 0.3@dmn{v}. +-@endDefmpreg +- +-@Defmpreg {QI, ms} +-Defines the indentation on both sides of a quoted (@code{QP} macro) +-paragraph. +- +-Effective: next paragraph. +- +-Default: 5@dmn{n}. +-@endDefmpreg +- +-@Defmpreg {PORPHANS, ms} +-Defines the minimum number of initial lines of any paragraph that +-should be kept together, to avoid orphan lines at the bottom of a page. +-If a new paragraph is started close to the bottom of a page, and there +-is insufficient space to accommodate @code{PORPHANS} lines before an +-automatic page break, then the page break is forced, before the start of +-the paragraph. +- +-Effective: next paragraph. +- +-Default: 1. +-@endDefmpreg +- +-@Defmpreg {HORPHANS, ms} +-Defines the minimum number of lines of the following paragraph that +-should be kept together with any section heading introduced by the +-@code{NH} or @code{SH} macros. If a section heading is placed close to +-the bottom of a page, and there is insufficient space to accommodate +-both the heading and at least @code{HORPHANS} lines of the following +-paragraph, before an automatic page break, then the page break is forced +-before the heading. +- +-Effective: next paragraph. +- +-Default: 1. +-@endDefmpreg +- +-@unnumberedsubsubsec Footnote Settings +- +-@Defmpreg {FL, ms} +-Defines the length of a footnote. +- +-Effective: next footnote. +- +-Default: @math{@code{@\n[LL]} * 5 / 6}. +-@endDefmpreg +- +-@Defmpreg {FI, ms} +-Defines the footnote indentation. +- +-Effective: next footnote. +- +-Default: 2@dmn{n}. +-@endDefmpreg +- +-@Defmpreg {FF, ms} +-The footnote format: +-@table @code +-@item 0 +-Print the footnote number as a superscript; indent the footnote +-(default). +- +-@item 1 +-Print the number followed by a period (like 1.@:) and indent the +-footnote. +- +-@item 2 +-Like 1, without an indentation. +- +-@item 3 +-Like 1, but print the footnote number as a hanging paragraph. +-@end table +- +-Effective: next footnote. +- +-Default: 0. +-@endDefmpreg +- +-@Defmpreg {FPS, ms} +-Defines the footnote point size. If the value is larger than or equal +-to 1000, divide it by 1000 to get a fractional point size. +- +-Effective: next footnote. +- +-Default: @math{@code{@\n[PS]} - 2}. +-@endDefmpreg +- +-@Defmpreg {FVS, ms} +-Defines the footnote vertical spacing. If the value is larger than or +-equal to 1000, divide it by 1000 to get a fractional point size. +- +-Effective: next footnote. +- +-Default: @math{@code{@\n[FPS]} + 2}. +-@endDefmpreg +- +-@Defmpreg {FPD, ms} +-Defines the footnote paragraph spacing. +- +-Effective: next footnote. +- +-Default: @math{@code{@\n[PD]} / 2}. +-@endDefmpreg +- +-@unnumberedsubsubsec Miscellaneous Number Registers +- +-@Defmpreg {MINGW, ms} +-Defines the minimum width between columns in a multi-column document. +- +-Effective: next page. +- +-Default: 2@dmn{n}. +-@endDefmpreg +- +-@Defmpreg {DD, ms} +-Sets the vertical spacing before and after a display, a @code{tbl} table, an +-@code{eqn} equation, or a @code{pic} image. +- +-Effective: next paragraph. +- +-Default: 0.5@dmn{v}. +-@endDefmpreg +- +-@c --------------------------------------------------------------------- +- +-@node ms Cover Page Macros, ms Body Text, ms Document Control Registers, ms +-@subsection Cover page macros +-@cindex @code{ms} macros, cover page +-@cindex cover page macros, [@code{ms}] +- +-Use the following macros to create a cover page for your document in the +-order shown. +- +-@Defmac {RP, [@code{no}], ms} +-Specifies the report format for your document. The report format +-creates a separate cover page. The default action (no @code{RP} macro) +-is to print a subset of the cover page on page@tie{}1 of your document. +- +-If you use the word @code{no} as an optional argument, @code{groff} +-prints a title page but does not repeat any of the title page +-information (title, author, abstract, etc.@:) on page@tie{}1 of the +-document. +-@endDefmac +- +-@Defmac {P1, , ms} +-(P-one) Prints the header on page@tie{}1. The default is to suppress +-the header. +-@endDefmac +- +-@Defmac {DA, [@dots{}], ms} +-(optional) Prints the current date, or the arguments to the macro if +-any, on the title page (if specified) and in the footers. This is the +-default for @code{nroff}. +-@endDefmac +- +-@Defmac {ND, [@dots{}], ms} +-(optional) Prints the current date, or the arguments to the macro if +-any, on the title page (if specified) but not in the footers. This is +-the default for @code{troff}. +-@endDefmac +- +-@Defmac {TL, , ms} +-Specifies the document title. @code{groff} collects text following the +-@code{TL} macro into the title, until reaching the author name or +-abstract. +-@endDefmac +- +-@Defmac {AU, , ms} +-Specifies the author's name, which appears on the line (or lines) +-immediately following. You can specify multiple authors as follows: +- +-@Example +-.AU +-John Doe +-.AI +-University of West Bumblefuzz +-.AU +-Martha Buck +-.AI +-Monolithic Corporation +- +-... +-@endExample +-@endDefmac +- +-@Defmac {AI, , ms} +-Specifies the author's institution. You can specify multiple +-institutions in the same way that you specify multiple authors. +-@endDefmac +- +-@Defmac {AB, [@code{no}], ms} +-Begins the abstract. The default is to print the word +-@acronym{ABSTRACT}, centered and in italics, above the text of the +-abstract. The word @code{no} as an optional argument suppresses this +-heading. +-@endDefmac +- +-@Defmac {AE, , ms} +-Ends the abstract. +-@endDefmac +- +-The following is example mark-up for a title page. +-@cindex title page, example markup +-@cindex example markup, title page +- +-@CartoucheExample +-.RP +-.TL +-The Inevitability of Code Bloat +-in Commercial and Free Software +-.AU +-J. Random Luser +-.AI +-University of West Bumblefuzz +-.AB +-This report examines the long-term growth +-of the code bases in two large, popular software +-packages; the free Emacs and the commercial +-Microsoft Word. +-While differences appear in the type or order +-of features added, due to the different +-methodologies used, the results are the same +-in the end. +-.PP +-The free software approach is shown to be +-superior in that while free software can +-become as bloated as commercial offerings, +-free software tends to have fewer serious +-bugs and the added features are in line with +-user demand. +-.AE +- +-... the rest of the paper follows ... +-@endCartoucheExample +- +-@c --------------------------------------------------------------------- +- +-@node ms Body Text, ms Page Layout, ms Cover Page Macros, ms +-@subsection Body text +-@cindex @code{ms} macros, body text +- +-This section describes macros used to mark up the body of your document. +-Examples include paragraphs, sections, and other groups. +- +-@menu +-* Paragraphs in ms:: +-* Headings in ms:: +-* Highlighting in ms:: +-* Lists in ms:: +-* Indentation values in ms:: +-* Tabstops in ms:: +-* ms Displays and Keeps:: +-* ms Insertions:: +-* Example multi-page table:: +-* ms Footnotes:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Paragraphs in ms, Headings in ms, ms Body Text, ms Body Text +-@subsubsection Paragraphs +-@cindex @code{ms} macros, paragraph handling +- +-The following paragraph types are available. +- +-@Defmac {PP, , ms} +-Sets a paragraph with an initial indentation. +-@endDefmac +- +-@Defmac {LP, , ms} +-Sets a paragraph without an initial indentation. +-@endDefmac +- +-@Defmac {QP, , ms} +-Sets a paragraph that is indented at both left and right margins. The +-effect is identical to the @acronym{HTML} @code{
    } element. +-The next paragraph or heading returns margins to normal. +-@endDefmac +- +-@Defmac {XP, , ms} +-Sets a paragraph whose lines are indented, except for the first line. +-This is a Berkeley extension. +-@endDefmac +- +-The following markup uses all four paragraph macros. +- +-@CartoucheExample +-.NH 2 +-Cases used in the study +-.LP +-The following software and versions were +-considered for this report. +-.PP +-For commercial software, we chose +-.B "Microsoft Word for Windows" , +-starting with version 1.0 through the +-current version (Word 2000). +-.PP +-For free software, we chose +-.B Emacs , +-from its first appearance as a standalone +-editor through the current version (v20). +-See [Bloggs 2002] for details. +-.QP +-Franklin's Law applied to software: +-software expands to outgrow both +-RAM and disk space over time. +-.LP +-Bibliography: +-.XP +-Bloggs, Joseph R., +-.I "Everyone's a Critic" , +-Underground Press, March 2002. +-A definitive work that answers all questions +-and criticisms about the quality and usability of +-free software. +-@endCartoucheExample +- +-The @code{PORPHANS} register (@pxref{ms Document Control Registers}) +-operates in conjunction with each of these macros, to inhibit the +-printing of orphan lines at the bottom of any page. +- +-@c --------------------------------------------------------------------- +- +-@node Headings in ms, Highlighting in ms, Paragraphs in ms, ms Body Text +-@subsubsection Headings +-@cindex @code{ms} macros, headings +- +-Use headings to create a hierarchical structure for your document. The +-@file{ms} macros print headings in @strong{bold}, using the same font +-family and point size as the body text. +- +-The following describes the heading macros: +- +-@DefmacList {NH, @Var{curr-level}, ms} +-@DefmacListEnd {NH, @t{S} @Var{level0} @dots{}, ms} +-Numbered heading. The argument is either a numeric argument to indicate +-the level of the heading, or the letter@tie{}@code{S} followed by +-numeric arguments to set the heading level explicitly. +- +-If you specify heading levels out of sequence, such as invoking +-@samp{.NH 3} after @samp{.NH 1}, @code{groff} prints a warning on +-standard error. +-@endDefmac +- +-@DefstrList {SN, ms} +-@DefstrItemx {SN-DOT, ms} +-@DefstrListEndx {SN-NO-DOT, ms} +-After invocation of @code{NH}, the assigned section number is made +-available in the strings @code{SN-DOT} (as it appears in a printed +-section heading with default formatting, followed by a terminating +-period), and @code{SN-NO-DOT} (with the terminating period omitted). +-The string @code{SN} is also defined, as an alias for @code{SN-DOT}; if +-preferred, you may redefine it as an alias for @code{SN-NO-DOT}, by +-including the initialization +-@Example +-.als SN SN-NO-DOT +-@endExample +- +-@noindent +-at any time @strong{before} you would like the change to take effect. +-@endDefstr +- +-@Defstr {SN-STYLE, ms} +-You may control the style used to print section numbers, within numbered +-section headings, by defining an appropriate alias for the string +-@code{SN-STYLE}. The default style, in which the printed section number +-is followed by a terminating period, is obtained by defining the alias +- +-@Example +-.als SN-STYLE SN-DOT +-@endExample +- +-@noindent +-If you prefer to omit the terminating period, from section numbers +-appearing in numbered section headings, you may define the alias +- +-@Example +-.als SN-STYLE SN-NO-DOT +-@endExample +- +-@noindent +-Any such change in section numbering style becomes effective from the +-next use of @code{.NH}, following redefinition of the alias for +-@code{SN-STYLE}. +-@endDefstr +- +-@Defmac {SH, [@Var{match-level}], ms} +-Unnumbered subheading. +- +-The optional @var{match-level} argument is a GNU extension. It is a +-number indicating the level of the heading, in a manner analogous to the +-@var{curr-level} argument to @code{.NH}. Its purpose is to match the +-point size, at which the heading is printed, to the size of a numbered +-heading at the same level, when the @code{GROWPS} and @code{PSINCR} +-heading size adjustment mechanism is in effect. @xref{ms Document +-Control Registers}. +-@endDefmac +- +-The @code{HORPHANS} register (@pxref{ms Document Control Registers}) +-operates in conjunction with the @code{NH} and @code{SH} macros, to +-inhibit the printing of orphaned section headings at the bottom of any +-page. +- +-@c --------------------------------------------------------------------- +- +-@node Highlighting in ms, Lists in ms, Headings in ms, ms Body Text +-@subsubsection Highlighting +-@cindex @code{ms} macros, highlighting +- +-The @file{ms} macros provide a variety of methods to highlight or +-emphasize text: +- +-@Defmac {B, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} +-Sets its first argument in @strong{bold type}. If you specify a second +-argument, @code{groff} prints it in the previous font after the bold +-text, with no intervening space (this allows you to set punctuation +-after the highlighted text without highlighting the punctuation). +-Similarly, it prints the third argument (if any) in the previous font +-@strong{before} the first argument. For example, +- +-@Example +-.B foo ) ( +-@endExample +- +-prints (@strong{foo}). +- +-If you give this macro no arguments, @code{groff} prints all text +-following in bold until the next highlighting, paragraph, or heading +-macro. +-@endDefmac +- +-@Defmac {R, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} +-Sets its first argument in roman (or regular) type. It operates +-similarly to the @code{B}@tie{}macro otherwise. +-@endDefmac +- +-@Defmac {I, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} +-Sets its first argument in @emph{italic type}. It operates similarly +-to the @code{B}@tie{}macro otherwise. +-@endDefmac +- +-@Defmac {CW, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} +-Sets its first argument in a @code{constant width face}. It operates +-similarly to the @code{B}@tie{}macro otherwise. +-@endDefmac +- +-@Defmac {BI, [@Var{txt} [@Var{post} [@Var{pre}]]], ms} +-Sets its first argument in bold italic type. It operates similarly to +-the @code{B}@tie{}macro otherwise. +-@endDefmac +- +-@Defmac {BX, [@Var{txt}], ms} +-Prints its argument and draws a box around it. If you want to box a +-string that contains spaces, use a digit-width space (@code{\0}). +-@endDefmac +- +-@Defmac {UL, [@Var{txt} [@Var{post}]], ms} +-Prints its first argument with an underline. If you specify a second +-argument, @code{groff} prints it in the previous font after the +-underlined text, with no intervening space. +-@endDefmac +- +-@Defmac {LG, , ms} +-Prints all text following in larger type (two points larger than the +-current point size) until the next font size, highlighting, paragraph, +-or heading macro. You can specify this macro multiple times to +-enlarge the point size as needed. +-@endDefmac +- +-@Defmac {SM, , ms} +-Prints all text following in smaller type (two points smaller than the +-current point size) until the next type size, highlighting, paragraph, +-or heading macro. You can specify this macro multiple times to reduce +-the point size as needed. +-@endDefmac +- +-@Defmac {NL, , ms} +-Prints all text following in the normal point size (that is, the value +-of the @code{PS} register). +-@endDefmac +- +-@DefstrList {@Lbrace{}, ms} +-@DefstrListEndx {@Rbrace{}, ms} +-Text enclosed with @code{\*@{} and @code{\*@}} is printed as a +-superscript. +-@endDefstr +- +-@c --------------------------------------------------------------------- +- +-@node Lists in ms, Indentation values in ms, Highlighting in ms, ms Body Text +-@subsubsection Lists +-@cindex @code{ms} macros, lists +- +-The @code{IP} macro handles duties for all lists. +- +-@Defmac {IP, [@Var{marker} [@Var{width}]], ms} +-The @var{marker} is usually a bullet glyph (@code{\[bu]}) for unordered +-lists, a number (or auto-incrementing number register) for numbered +-lists, or a word or phrase for indented (glossary-style) lists. +- +-The @var{width} specifies the indentation for the body of each list +-item; its default unit is @samp{n}. Once specified, the indentation +-remains the same for all list items in the document until specified +-again. +- +-The @code{PORPHANS} register (@pxref{ms Document Control Registers}) +-operates in conjunction with the @code{IP} macro, to inhibit the +-printing of orphaned list markers at the bottom of any page. +-@endDefmac +- +-The following is an example of a bulleted list. +-@cindex example markup, bulleted list [@code{ms}] +-@cindex bulleted list, example markup [@code{ms}] +- +-@Example +-A bulleted list: +-.IP \[bu] 2 +-lawyers +-.IP \[bu] +-guns +-.IP \[bu] +-money +-@endExample +- +-Produces: +- +-@Example +-A bulleted list: +- +-o lawyers +- +-o guns +- +-o money +-@endExample +- +-The following is an example of a numbered list. +-@cindex example markup, numbered list [@code{ms}] +-@cindex numbered list, example markup [@code{ms}] +- +-@Example +-.nr step 1 1 +-A numbered list: +-.IP \n[step] 3 +-lawyers +-.IP \n+[step] +-guns +-.IP \n+[step] +-money +-@endExample +- +-Produces: +- +-@Example +-A numbered list: +- +-1. lawyers +- +-2. guns +- +-3. money +-@endExample +- +-Note the use of the auto-incrementing number register in this example. +- +-The following is an example of a glossary-style list. +-@cindex example markup, glossary-style list [@code{ms}] +-@cindex glossary-style list, example markup [@code{ms}] +- +-@Example +-A glossary-style list: +-.IP lawyers 0.4i +-Two or more attorneys. +-.IP guns +-Firearms, preferably +-large-caliber. +-.IP money +-Gotta pay for those +-lawyers and guns! +-@endExample +- +-Produces: +- +-@Example +-A glossary-style list: +- +-lawyers +- Two or more attorneys. +- +-guns Firearms, preferably large-caliber. +- +-money +- Gotta pay for those lawyers and guns! +-@endExample +- +-In the last example, the @code{IP} macro places the definition on the +-same line as the term if it has enough space; otherwise, it breaks to +-the next line and starts the definition below the term. This may or may +-not be the effect you want, especially if some of the definitions break +-and some do not. The following examples show two possible ways to force +-a break. +- +-The first workaround uses the @code{br} request to force a break after +-printing the term or label. +- +-@CartoucheExample +-A glossary-style list: +-.IP lawyers 0.4i +-Two or more attorneys. +-.IP guns +-.br +-Firearms, preferably large-caliber. +-.IP money +-Gotta pay for those lawyers and guns! +-@endCartoucheExample +- +-The second workaround uses the @code{\p} escape to force the break. +-Note the space following the escape; this is important. If you omit the +-space, @code{groff} prints the first word on the same line as the term +-or label (if it fits) @strong{then} breaks the line. +- +-@CartoucheExample +-A glossary-style list: +-.IP lawyers 0.4i +-Two or more attorneys. +-.IP guns +-\p Firearms, preferably large-caliber. +-.IP money +-Gotta pay for those lawyers and guns! +-@endCartoucheExample +- +-To set nested lists, use the @code{RS} and @code{RE} macros. +-@xref{Indentation values in ms}, for more information. +-@cindex @code{ms} macros, nested lists +-@cindex nested lists [@code{ms}] +- +-For example: +- +-@CartoucheExample +-.IP \[bu] 2 +-Lawyers: +-.RS +-.IP \[bu] +-Dewey, +-.IP \[bu] +-Cheatham, +-.IP \[bu] +-and Howe. +-.RE +-.IP \[bu] +-Guns +-@endCartoucheExample +- +-Produces: +- +-@Example +-o Lawyers: +- +- o Dewey, +- +- o Cheatham, +- +- o and Howe. +- +-o Guns +-@endExample +- +-@c --------------------------------------------------------------------- +- +-@node Indentation values in ms, Tabstops in ms, Lists in ms, ms Body Text +-@subsubsection Indentation values +- +-In many situations, you may need to indentation a section of text while +-still wrapping and filling. @xref{Lists in ms}, for an example of +-nested lists. +- +-@DefmacList {RS, , ms} +-@DefmacListEndx {RE, , ms} +-These macros begin and end an indented section. The @code{PI} register +-controls the amount of indentation, allowing the indented text to line +-up under hanging and indented paragraphs. +-@endDefmac +- +-@xref{ms Displays and Keeps}, for macros to indentation and turn off +-filling. +- +-@c --------------------------------------------------------------------- +- +-@node Tabstops in ms, ms Displays and Keeps, Indentation values in ms, ms Body Text +-@subsubsection Tab Stops +- +-Use the @code{ta} request to define tab stops as needed. @xref{Tabs and +-Fields}. +- +-@Defmac {TA, , ms} +-Use this macro to reset the tab stops to the default for @file{ms} +-(every 5n). You can redefine the @code{TA} macro to create a different +-set of default tab stops. +-@endDefmac +- +-@c --------------------------------------------------------------------- +- +-@node ms Displays and Keeps, ms Insertions, Tabstops in ms, ms Body Text +-@subsubsection Displays and keeps +-@cindex @code{ms} macros, displays +-@cindex @code{ms} macros, keeps +-@cindex keeps [@code{ms}] +-@cindex displays [@code{ms}] +- +-Use displays to show text-based examples or figures (such as code +-listings). +- +-Displays turn off filling, so lines of code are displayed as-is without +-inserting @code{br} requests in between each line. Displays can be +-@dfn{kept} on a single page, or allowed to break across pages. +- +-@DefmacList {DS, @t{L}, ms} +-@DefmacItemx {LD, , ms} +-@DefmacListEndx {DE, , ms} +-Left-justified display. The @samp{.DS L} call generates a page break, +-if necessary, to keep the entire display on one page. The @code{LD} +-macro allows the display to break across pages. The @code{DE} macro +-ends the display. +-@endDefmac +- +-@DefmacList {DS, @t{I}, ms} +-@DefmacItemx {ID, , ms} +-@DefmacListEndx {DE, , ms} +-Indents the display as defined by the @code{DI} register. The @samp{.DS +-I} call generates a page break, if necessary, to keep the entire display +-on one page. The @code{ID} macro allows the display to break across +-pages. The @code{DE} macro ends the display. +-@endDefmac +- +-@DefmacList {DS, @t{B}, ms} +-@DefmacItemx {BD, , ms} +-@DefmacListEndx {DE, , ms} +-Sets a block-centered display: the entire display is left-justified, but +-indented so that the longest line in the display is centered on the +-page. The @samp{.DS B} call generates a page break, if necessary, to +-keep the entire display on one page. The @code{BD} macro allows the +-display to break across pages. The @code{DE} macro ends the display. +-@endDefmac +- +-@DefmacList {DS, @t{C}, ms} +-@DefmacItemx {CD, , ms} +-@DefmacListEndx {DE, , ms} +-Sets a centered display: each line in the display is centered. The +-@samp{.DS C} call generates a page break, if necessary, to keep the +-entire display on one page. The @code{CD} macro allows the display to +-break across pages. The @code{DE} macro ends the display. +-@endDefmac +- +-@DefmacList {DS, @t{R}, ms} +-@DefmacItemx {RD, , ms} +-@DefmacListEndx {DE, , ms} +-Right-justifies each line in the display. The @samp{.DS R} call +-generates a page break, if necessary, to keep the entire display on one +-page. The @code{RD} macro allows the display to break across pages. +-The @code{DE} macro ends the display. +-@endDefmac +- +-@DefmacList {Ds, , ms} +-@DefmacListEndx {De, , ms} +-These two macros were formerly provided as aliases for @code{DS} and +-@code{DE}, respectively. They have been removed, and should no longer +-be used. The original implementations of @code{DS} and @code{DE} are +-retained, and should be used instead. X11 documents that actually use +-@code{Ds} and @code{De} always load a specific macro file from the X11 +-distribution (@file{macros.t}) that provides proper definitions for the +-two macros. +-@endDefmac +- +-On occasion, you may want to @dfn{keep} other text together on a page. +-For example, you may want to keep two paragraphs together, or a +-paragraph that refers to a table (or list, or other item) immediately +-following. The @file{ms} macros provide the @code{KS} and @code{KE} +-macros for this purpose. +- +-@DefmacList {KS, , ms} +-@DefmacListEndx {KE, , ms} +-The @code{KS} macro begins a block of text to be kept on a single page, +-and the @code{KE} macro ends the block. +-@endDefmac +- +-@DefmacList {KF, , ms} +-@DefmacListEndx {KE, , ms} +-Specifies a @dfn{floating keep}; if the keep cannot fit on the current +-page, @code{groff} holds the contents of the keep and allows text +-following the keep (in the source file) to fill in the remainder of the +-current page. When the page breaks, whether by an explicit @code{bp} +-request or by reaching the end of the page, @code{groff} prints the +-floating keep at the top of the new page. This is useful for printing +-large graphics or tables that do not need to appear exactly where +-specified. +-@endDefmac +- +-You can also use the @code{ne} request to force a page break if there is +-not enough vertical space remaining on the page. +- +-Use the following macros to draw a box around a section of text (such as +-a display). +- +-@DefmacList {B1, , ms} +-@DefmacListEndx {B2, , ms} +-Marks the beginning and ending of text that is to have a box drawn +-around it. The @code{B1} macro begins the box; the @code{B2} macro ends +-it. Text in the box is automatically placed in a diversion (keep). +-@endDefmac +- +-@c --------------------------------------------------------------------- +- +-@node ms Insertions, Example multi-page table, ms Displays and Keeps, ms Body Text +-@subsubsection Tables, figures, equations, and references +-@cindex @code{ms} macros, tables +-@cindex @code{ms} macros, figures +-@cindex @code{ms} macros, equations +-@cindex @code{ms} macros, references +-@cindex tables [@code{ms}] +-@cindex figures [@code{ms}] +-@cindex equations [@code{ms}] +-@cindex references [@code{ms}] +- +-The @file{ms} macros support the standard @code{groff} preprocessors: +-@code{tbl}, @code{pic}, @code{eqn}, and @code{refer}. +-@pindex tbl +-@pindex pic +-@pindex eqn +-@pindex refer +-You mark text meant for preprocessors by enclosing it in pairs of tags +-as follows. +- +-@DefmacList {TS, [@code{H}], ms} +-@DefmacListEndx {TE, , ms} +-Denotes a table, to be processed by the @code{tbl} preprocessor. The +-optional argument@tie{}@code{H} to @code{TS} instructs @code{groff} to +-create a running header with the information up to the @code{TH} macro. +-@code{groff} prints the header at the beginning of the table; if the +-table runs onto another page, @code{groff} prints the header on the next +-page as well. +-@endDefmac +- +-@DefmacList {PS, , ms} +-@DefmacListEndx {PE, , ms} +-Denotes a graphic, to be processed by the @code{pic} preprocessor. You +-can create a @code{pic} file by hand, using the @acronym{AT&T} +-@code{pic} manual available on the Web as a reference, or by using a +-graphics program such as @code{xfig}. +-@endDefmac +- +-@DefmacList {EQ, [@Var{align}], ms} +-@DefmacListEndx {EN, , ms} +-Denotes an equation, to be processed by the @code{eqn} preprocessor. +-The optional @var{align} argument can be @code{C}, @code{L}, +-or@tie{}@code{I} to center (the default), left-justify, or indent the +-equation. +-@endDefmac +- +-@DefmacList {[, , ms} +-@DefmacListEndx {], , ms} +-Denotes a reference, to be processed by the @code{refer} preprocessor. +-The GNU @cite{refer(1)} man page provides a comprehensive reference to +-the preprocessor and the format of the bibliographic database. +-@endDefmac +- +-@menu +-* Example multi-page table:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Example multi-page table, ms Footnotes, ms Insertions, ms Body Text +-@subsubsection An example multi-page table +-@cindex example markup, multi-page table [@code{ms}] +-@cindex multi-page table, example markup [@code{ms}] +- +-The following is an example of how to set up a table that may print +-across two or more pages. +- +-@CartoucheExample +-.TS H +-allbox expand; +-cb | cb . +-Text ...of heading... +-_ +-.TH +-.T& +-l | l . +-... the rest of the table follows... +-.CW +-.TE +-@endCartoucheExample +- +-@c --------------------------------------------------------------------- +- +-@node ms Footnotes, , Example multi-page table, ms Body Text +-@subsubsection Footnotes +-@cindex @code{ms} macros, footnotes +-@cindex footnotes [@code{ms}] +- +-The @file{ms} macro package has a flexible footnote system. You can +-specify either numbered footnotes or symbolic footnotes (that is, using +-a marker such as a dagger symbol). +- +-@Defstr {*, ms} +-Specifies the location of a numbered footnote marker in the text. +-@endDefesc +- +-@DefmacList {FS, , ms} +-@DefmacListEndx {FE, , ms} +-Specifies the text of the footnote. The default action is to create a +-numbered footnote; you can create a symbolic footnote by specifying a +-@dfn{mark} glyph (such as @code{\[dg]} for the dagger glyph) in the body +-text and as an argument to the @code{FS} macro, followed by the text of +-the footnote and the @code{FE} macro. +-@endDefmac +- +-You can control how @code{groff} prints footnote numbers by changing the +-value of the @code{FF} register. @xref{ms Document Control Registers}. +- +-@cindex footnotes, and keeps [@code{ms}] +-@cindex keeps, and footnotes [@code{ms}] +-@cindex footnotes, and displays [@code{ms}] +-@cindex displays, and footnotes [@code{ms}] +-Footnotes can be safely used within keeps and displays, but you should +-avoid using numbered footnotes within floating keeps. You can set a +-second @code{\**} marker between a @code{\**} and its corresponding +-@code{.FS} entry; as long as each @code{FS} macro occurs @emph{after} +-the corresponding @code{\**} and the occurrences of @code{.FS} are in +-the same order as the corresponding occurrences of @code{\**}. +- +-@c --------------------------------------------------------------------- +- +-@node ms Page Layout, Differences from AT&T ms, ms Body Text, ms +-@subsection Page layout +-@cindex @code{ms} macros, page layout +-@cindex page layout [@code{ms}] +- +-The default output from the @file{ms} macros provides a minimalist page +-layout: it prints a single column, with the page number centered at the +-top of each page. It prints no footers. +- +-You can change the layout by setting the proper number registers and +-strings. +- +-@menu +-* ms Headers and Footers:: +-* ms Margins:: +-* ms Multiple Columns:: +-* ms TOC:: +-* ms Strings and Special Characters:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node ms Headers and Footers, ms Margins, ms Page Layout, ms Page Layout +-@subsubsection Headers and footers +-@cindex @code{ms} macros, headers +-@cindex @code{ms} macros, footers +-@cindex headers [@code{ms}] +-@cindex footers [@code{ms}] +- +-For documents that do not distinguish between odd and even pages, set +-the following strings: +- +-@DefstrList {LH, ms} +-@DefstrItemx {CH, ms} +-@DefstrListEndx {RH, ms} +-Sets the left, center, and right headers. +-@endDefstr +- +-@DefstrList {LF, ms} +-@DefstrItemx {CF, ms} +-@DefstrListEndx {RF, ms} +-Sets the left, center, and right footers. +-@endDefstr +- +-For documents that need different information printed in the even and +-odd pages, use the following macros: +- +-@DefmacList {OH, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}, ms} +-@DefmacItemx {EH, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}, ms} +-@DefmacItemx {OF, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}, ms} +-@DefmacListEndx {EF, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}, ms} +-The @code{OH} and @code{EH} macros define headers for the odd and even +-pages; the @code{OF} and @code{EF} macros define footers for the odd and +-even pages. This is more flexible than defining the individual strings. +- +-You can replace the quote (@code{'}) marks with any character not +-appearing in the header or footer text. +-@endDefmac +- +-To specify custom header and footer processing, redefine the following +-macros: +- +-@DefmacList {PT,, ms} +-@DefmacItemx {HD,, ms} +-@DefmacListEndx {BT,, ms} +-The @code{PT} macro defines a custom header; the @code{BT} macro defines +-a custom footer. These macros must handle odd/even/first page +-differences if necessary. +- +-The @code{HD} macro defines additional header processing to take place +-after executing the @code{PT} macro. +-@endDefmac +- +-@c --------------------------------------------------------------------- +- +-@node ms Margins, ms Multiple Columns, ms Headers and Footers, ms Page Layout +-@subsubsection Margins +-@cindex @code{ms} macros, margins +- +-You control margins using a set of number registers. @xref{ms Document +-Control Registers}, for details. +- +-@c --------------------------------------------------------------------- +- +-@node ms Multiple Columns, ms TOC, ms Margins, ms Page Layout +-@subsubsection Multiple columns +-@cindex @code{ms} macros, multiple columns +-@cindex multiple columns [@code{ms}] +- +-The @file{ms} macros can set text in as many columns as do reasonably +-fit on the page. The following macros are available; all of them force +-a page break if a multi-column mode is already set. However, if the +-current mode is single-column, starting a multi-column mode does +-@emph{not} force a page break. +- +-@Defmac {1C, , ms} +-Single-column mode. +-@endDefmac +- +-@Defmac {2C, , ms} +-Two-column mode. +-@endDefmac +- +-@Defmac {MC, [@Var{width} [@Var{gutter}]], ms} +-Multi-column mode. If you specify no arguments, it is equivalent to the +-@code{2C} macro. Otherwise, @var{width} is the width of each column and +-@var{gutter} is the space between columns. The @code{MINGW} number +-register controls the default gutter width. +-@endDefmac +- +-@c --------------------------------------------------------------------- +- +-@node ms TOC, ms Strings and Special Characters, ms Multiple Columns, ms Page Layout +-@subsubsection Creating a table of contents +-@cindex @code{ms} macros, creating table of contents +-@cindex table of contents, creating [@code{ms}] +- +-The facilities in the @file{ms} macro package for creating a table of +-contents are semi-automated at best. Assuming that you want the table +-of contents to consist of the document's headings, you need to repeat +-those headings wrapped in @code{XS} and @code{XE} macros. +- +-@DefmacList {XS, [@Var{page}], ms} +-@DefmacItemx {XA, [@Var{page}], ms} +-@DefmacListEndx {XE, , ms} +-These macros define a table of contents or an individual entry in the +-table of contents, depending on their use. The macros are very simple; +-they cannot indent a heading based on its level. The easiest way to +-work around this is to add tabs to the table of contents string. The +-following is an example: +- +-@CartoucheExample +-.NH 1 +-Introduction +-.XS +-Introduction +-.XE +-.LP +-... +-.CW +-.NH 2 +-Methodology +-.XS +-Methodology +-.XE +-.LP +-... +-@endCartoucheExample +- +-You can manually create a table of contents by beginning with the +-@code{XS} macro for the first entry, specifying the page number for that +-entry as the argument to @code{XS}. Add subsequent entries using the +-@code{XA} macro, specifying the page number for that entry as the +-argument to @code{XA}. The following is an example: +- +-@CartoucheExample +-.XS 1 +-Introduction +-.XA 2 +-A Brief History of the Universe +-.XA 729 +-Details of Galactic Formation +-... +-.XE +-@endCartoucheExample +-@endDefmac +- +-@Defmac {TC, [@code{no}], ms} +-Prints the table of contents on a new page, setting the page number +-to@tie{}@strong{i} (Roman lowercase numeral one). You should usually +-place this macro at the end of the file, since @code{groff} is a +-single-pass formatter and can only print what has been collected up to +-the point that the @code{TC} macro appears. +- +-The optional argument @code{no} suppresses printing the title specified +-by the string register @code{TOC}. +-@endDefmac +- +-@Defmac {PX, [@code{no}], ms} +-Prints the table of contents on a new page, using the current page +-numbering sequence. Use this macro to print a manually-generated table +-of contents at the beginning of your document. +- +-The optional argument @code{no} suppresses printing the title specified +-by the string register @code{TOC}. +-@endDefmac +- +-The @cite{Groff and Friends HOWTO} includes a @code{sed} script that +-automatically inserts @code{XS} and @code{XE} macro entries after each +-heading in a document. +- +-Altering the @code{NH} macro to automatically build the table of +-contents is perhaps initially more difficult, but would save a great +-deal of time in the long run if you use @file{ms} regularly. +- +-@c --------------------------------------------------------------------- +- +-@node ms Strings and Special Characters, , ms TOC, ms Page Layout +-@subsubsection Strings and Special Characters +-@cindex @code{ms} macros, strings +-@cindex @code{ms} macros, special characters +-@cindex @code{ms} macros, accent marks +-@cindex accent marks [@code{ms}] +-@cindex special characters [@code{ms}] +-@cindex strings [@code{ms}] +- +-The @file{ms} macros provide the following predefined strings. You can +-change the string definitions to help in creating documents in languages +-other than English. +- +-@Defstr {REFERENCES, ms} +-Contains the string printed at the beginning of the references +-(bibliography) page. The default is @samp{References}. +-@endDefstr +- +-@Defstr {ABSTRACT, ms} +-Contains the string printed at the beginning of the abstract. The +-default is @samp{ABSTRACT}. +-@endDefstr +- +-@Defstr {TOC, ms} +-Contains the string printed at the beginning of the table of contents. +-@endDefstr +- +-@DefstrList {MONTH1, ms} +-@DefstrItemx {MONTH2, ms} +-@DefstrItemx {MONTH3, ms} +-@DefstrItemx {MONTH4, ms} +-@DefstrItemx {MONTH5, ms} +-@DefstrItemx {MONTH6, ms} +-@DefstrItemx {MONTH7, ms} +-@DefstrItemx {MONTH8, ms} +-@DefstrItemx {MONTH9, ms} +-@DefstrItemx {MONTH10, ms} +-@DefstrItemx {MONTH11, ms} +-@DefstrListEndx {MONTH12, ms} +-Prints the full name of the month in dates. The default is +-@samp{January}, @samp{February}, etc. +-@endDefstr +- +-The following special characters are available@footnote{For an +-explanation what special characters are see @ref{Special Characters}.}: +- +-@Defstr {-, ms} +-Prints an em dash. +-@endDefstr +- +-@DefstrList {Q, ms} +-@DefstrListEndx {U, ms} +-Prints typographer's quotes in troff, and plain quotes in nroff. +-@code{\*Q} is the left quote and @code{\*U} is the right quote. +-@endDefstr +- +-Improved accent marks are available in the @file{ms} macros. +- +-@Defmac {AM, , ms} +-Specify this macro at the beginning of your document to enable extended +-accent marks and special characters. This is a Berkeley extension. +- +-To use the accent marks, place them @strong{after} the character being +-accented. +- +-Note that groff's native support for accents is superior to the +-following definitions. +-@endDefmac +- +-The following accent marks are available after invoking the @code{AM} +-macro: +- +-@Defstr {', ms} +-Acute accent. +-@endDefstr +- +-@Defstr {`, ms} +-Grave accent. +-@endDefstr +- +-@Defstr {^, ms} +-Circumflex. +-@endDefstr +- +-@Defstr {\,, ms} +-Cedilla. +-@endDefstr +- +-@Defstr {~, ms} +-Tilde. +-@endDefstr +- +-@deffn String @t{\*[:]} +-@ifnotinfo +-@stindex : @r{[}ms@r{]} +-@end ifnotinfo +-@ifinfo +-@stindex \*[@r{}] @r{[}ms@r{]} +-@end ifinfo +-Umlaut. +-@end deffn +- +-@Defstr {v, ms} +-Hacek. +-@endDefstr +- +-@Defstr {_, ms} +-Macron (overbar). +-@endDefstr +- +-@Defstr {., ms} +-Underdot. +-@endDefstr +- +-@Defstr {o, ms} +-Ring above. +-@endDefstr +- +-The following are standalone characters available after invoking the +-@code{AM} macro: +- +-@Defstr {?, ms} +-Upside-down question mark. +-@endDefstr +- +-@Defstr {!, ms} +-Upside-down exclamation point. +-@endDefstr +- +-@Defstr {8, ms} +-German ligature. +-@endDefstr +- +-@Defstr {3, ms} +-Yogh. +-@endDefstr +- +-@Defstr {Th, ms} +-Uppercase thorn. +-@endDefstr +- +-@Defstr {th, ms} +-Lowercase thorn. +-@endDefstr +- +-@Defstr {D-, ms} +-Uppercase eth. +-@endDefstr +- +-@Defstr {d-, ms} +-Lowercase eth. +-@endDefstr +- +-@Defstr {q, ms} +-Hooked o. +-@endDefstr +- +-@Defstr {ae, ms} +-Lowercase ligature. +-@endDefstr +- +-@Defstr {Ae, ms} +-Uppercase ligature. +-@endDefstr +- +-@c --------------------------------------------------------------------- +- +-@node Differences from AT&T ms, Naming Conventions, ms Page Layout, ms +-@subsection Differences from @acronym{AT&T} @file{ms} +-@cindex @code{ms} macros, differences from @acronym{AT&T} +-@cindex @acronym{AT&T} @code{troff}, @code{ms} macro package differences +- +-This section lists the (minor) differences between the @code{groff -ms} +-macros and @acronym{AT&T} @code{troff -ms} macros. +- +-@itemize @bullet +-@item +-The internals of @code{groff -ms} differ from the internals of +-@acronym{AT&T} @code{troff -ms}. Documents that depend upon +-implementation details of @acronym{AT&T} @code{troff -ms} may not format +-properly with @code{groff -ms}. +- +-@item +-The general error-handling policy of @code{groff -ms} is to detect and +-report errors, rather than silently to ignore them. +- +-@item +-@code{groff -ms} does not work in compatibility mode (this is, with the +-@option{-C} option). +- +-@item +-There is no special support for typewriter-like devices. +- +-@item +-@code{groff -ms} does not provide cut marks. +- +-@item +-Multiple line spacing is not supported. Use a larger vertical spacing +-instead. +- +-@item +-Some @acronym{UNIX} @code{ms} documentation says that the @code{CW} and +-@code{GW} number registers can be used to control the column width and +-gutter width, respectively. These number registers are not used in +-@code{groff -ms}. +- +-@item +-Macros that cause a reset (paragraphs, headings, etc.@:) may change the +-indentation. Macros that change the indentation do not increment or +-decrement the indentation, but rather set it absolutely. This can cause +-problems for documents that define additional macros of their own. The +-solution is to use not the @code{in} request but instead the @code{RS} +-and @code{RE} macros. +- +-@item +-To make @code{groff -ms} use the default page offset (which also +-specifies the left margin), the @code{PO} register must stay undefined +-until the first @file{-ms} macro is evaluated. This implies that +-@code{PO} should not be used early in the document, unless it is changed +-also: Remember that accessing an undefined register automatically +-defines it. +-@end itemize +- +-@Defmpreg {GS, ms} +-This number register is set to@tie{}1 by the @code{groff -ms} macros, +-but it is not used by the @code{AT&T} @code{troff -ms} macros. +-Documents that need to determine whether they are being formatted with +-@code{AT&T} @code{troff -ms} or @code{groff -ms} should use this number +-register. +-@endDefmpreg +- +-Emulations of a few ancient Bell Labs macros can be re-enabled by +-calling the otherwise undocumented @code{SC} section-header macro. +-Calling @code{SC} enables @code{UC} for marking up a product or +-application name, and the pair @code{P1}/@code{P2} for surrounding code +-example displays. +- +-These are not enabled by default because (a)@tie{}they were not +-documented, in the original @code{ms} manual, and (b)@tie{}the @code{P1} +-and @code{UC} macros collide with different macros with the same names +-in the Berkeley version of @code{ms}. +- +-These @code{groff} emulations are sufficient to give back the 1976 +-Kernighan@tie{}& Cherry paper @cite{Typsetting Mathematics -- User's +-Guide} its section headings, and restore some text that had gone missing +-as arguments of undefined macros. No warranty express or implied is +-given as to how well the typographic details these produce match the +-original Bell Labs macros. +- +-@menu +-* Missing ms Macros:: +-* Additional ms Macros:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Missing ms Macros, Additional ms Macros, Differences from AT&T ms, Differences from AT&T ms +-@subsubsection @code{troff} macros not appearing in @code{groff} +- +-Macros missing from @code{groff -ms} are cover page macros specific to +-Bell Labs and Berkeley. The macros known to be missing are: +- +-@table @code +-@item .TM +-Technical memorandum; a cover sheet style +- +-@item .IM +-Internal memorandum; a cover sheet style +- +-@item .MR +-Memo for record; a cover sheet style +- +-@item .MF +-Memo for file; a cover sheet style +- +-@item .EG +-Engineer's notes; a cover sheet style +- +-@item .TR +-Computing Science Tech Report; a cover sheet style +- +-@item .OK +-Other keywords +- +-@item .CS +-Cover sheet information +- +-@item .MH +-A cover sheet macro +-@end table +- +-@c --------------------------------------------------------------------- +- +-@node Additional ms Macros, , Missing ms Macros, Differences from AT&T ms +-@subsubsection @code{groff} macros not appearing in @acronym{AT&T} @code{troff} +- +-The @code{groff -ms} macros have a few minor extensions compared to the +-@acronym{AT&T} @code{troff -ms} macros. +- +-@Defmac {AM, , ms} +-Improved accent marks. @xref{ms Strings and Special Characters}, for +-details. +-@endDefmac +- +-@Defmac {DS, @t{I}, ms} +-Indented display. The default behavior of @acronym{AT&T} @code{troff +--ms} was to indent; the @code{groff} default prints displays flush left +-with the body text. +-@endDefmac +- +-@Defmac {CW, , ms} +-Print text in @code{constant width} (Courier) font. +-@endDefmac +- +-@Defmac {IX, , ms} +-Indexing term (printed on standard error). You can write a script to +-capture and process an index generated in this manner. +-@endDefmac +- +-The following additional number registers +-appear in @code{groff -ms}: +- +-@Defmpreg {MINGW, ms} +-Specifies a minimum space between columns (for multi-column output); +-this takes the place of the @code{GW} register that was documented but +-apparently not implemented in @acronym{AT&T} @code{troff}. +-@endDefmpreg +- +-Several new string registers are available as well. You can change +-these to handle (for example) the local language. @xref{ms Strings and +-Special Characters}, for details. +- +-@c --------------------------------------------------------------------- +- +-@node Naming Conventions, , Differences from AT&T ms, ms +-@subsection Naming Conventions +-@cindex @code{ms} macros, naming conventions +-@cindex naming conventions, @code{ms} macros +- +-The following conventions are used for names of macros, strings and +-number registers. External names available to documents that use the +-@code{groff -ms} macros contain only uppercase letters and digits. +- +-Internally the macros are divided into modules; naming conventions are +-as follows: +- +-@itemize @bullet +-@item +-Names used only within one module are of the form +-@var{module}@code{*}@var{name}. +- +-@item +-Names used outside the module in which they are defined are of the form +-@var{module}@code{@@}@var{name}. +- +-@item +-Names associated with a particular environment are of the form +-@var{environment}@code{:}@var{name}; these are used only within the +-@code{par} module. +- +-@item +-@var{name} does not have a module prefix. +- +-@item +-Constructed names used to implement arrays are of the form +-@var{array}@code{!}@var{index}. +-@end itemize +- +-Thus the groff ms macros reserve the following names: +- +-@itemize @bullet +-@item +-Names containing the characters @code{*}, @code{@@}, and@tie{}@code{:}. +- +-@item +-Names containing only uppercase letters and digits. +-@end itemize +- +- +-@c ===================================================================== +- +-@node me, mm, ms, Macro Packages +-@section @file{me} +-@cindex @code{me} macro package +- +-@c XXX documentation +-@c XXX this is a placeholder until we get stuff knocked into shape +-See the @file{meintro.me} and @file{meref.me} documents in groff's +-@file{doc} directory. +- +- +-@c ===================================================================== +- +-@node mm, mom, me, Macro Packages +-@section @file{mm} +-@cindex @code{mm} macro package +- +-@c XXX documentation +-@c XXX this is a placeholder until we get stuff knocked into shape +-See the @cite{groff_mm(7)} man page (type @command{man groff_mm} at the +-command line). +- +- +-@c ===================================================================== +- +-@node mom, , mm, Macro Packages +-@section @file{mom} +-@cindex @code{mom} macro package +- +-@c XXX documentation +-@c XXX this is a placeholder until we get stuff knocked into shape +-See the @cite{groff_mom(7)} man page (type @command{man groff_mom} at +-the command line), which gives a short overview and a link to its +-extensive documentation in HTML format. +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node gtroff Reference, Preprocessors, Macro Packages, Top +-@chapter @code{gtroff} Reference +-@cindex reference, @code{gtroff} +-@cindex @code{gtroff}, reference +- +-This chapter covers @strong{all} of the facilities of @code{gtroff}. +-Users of macro packages may skip it if not interested in details. +- +- +-@menu +-* Text:: +-* Measurements:: +-* Expressions:: +-* Identifiers:: +-* Embedded Commands:: +-* Registers:: +-* Manipulating Filling and Adjusting:: +-* Manipulating Hyphenation:: +-* Manipulating Spacing:: +-* Tabs and Fields:: +-* Character Translations:: +-* Troff and Nroff Mode:: +-* Line Layout:: +-* Line Control:: +-* Page Layout:: +-* Page Control:: +-* Fonts and Symbols:: +-* Sizes:: +-* Strings:: +-* Conditionals and Loops:: +-* Writing Macros:: +-* Page Motions:: +-* Drawing Requests:: +-* Traps:: +-* Diversions:: +-* Environments:: +-* Suppressing output:: +-* Colors:: +-* I/O:: +-* Postprocessor Access:: +-* Miscellaneous:: +-* Gtroff Internals:: +-* Debugging:: +-* Implementation Differences:: +-@end menu +- +- +-@c ===================================================================== +- +-@node Text, Measurements, gtroff Reference, gtroff Reference +-@section Text +-@cindex text, @code{gtroff} processing +- +-@code{gtroff} input files contain text with control commands +-interspersed throughout. But, even without control codes, @code{gtroff} +-still does several things with the input text: +- +-@itemize @bullet +-@item +-filling and adjusting +- +-@item +-adding additional space after sentences +- +-@item +-hyphenating +- +-@item +-inserting implicit line breaks +-@end itemize +- +-@menu +-* Filling and Adjusting:: +-* Hyphenation:: +-* Sentences:: +-* Tab Stops:: +-* Implicit Line Breaks:: +-* Input Conventions:: +-* Input Encodings:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Filling and Adjusting, Hyphenation, Text, Text +-@subsection Filling and Adjusting +-@cindex filling +-@cindex adjusting +- +-When @code{gtroff} reads text, it collects words from the input and fits +-as many of them together on one output line as it can. This is known as +-@dfn{filling}. +- +-@cindex leading spaces +-@cindex spaces, leading and trailing +-@cindex extra spaces +-@cindex trailing spaces +-Once @code{gtroff} has a @dfn{filled} line, it tries to @dfn{adjust} it. +-This means it widens the spacing between words until the text reaches +-the right margin (in the default adjustment mode). Extra spaces between +-words are preserved, but spaces at the end of lines are ignored. Spaces +-at the front of a line cause a @dfn{break} (breaks are explained in +-@ref{Implicit Line Breaks}). +- +-@xref{Manipulating Filling and Adjusting}. +- +-@c --------------------------------------------------------------------- +- +-@node Hyphenation, Sentences, Filling and Adjusting, Text +-@subsection Hyphenation +-@cindex hyphenation +- +-Since the odds are not great for finding a set of words, for every +-output line, which fit nicely on a line without inserting excessive +-amounts of space between words, @code{gtroff} hyphenates words so that +-it can justify lines without inserting too much space between words. It +-uses an internal hyphenation algorithm (a simplified version of the +-algorithm used within @TeX{}) to indicate which words can be hyphenated +-and how to do so. When a word is hyphenated, the first part of the word +-is added to the current filled line being output (with an attached +-hyphen), and the other portion is added to the next line to be filled. +- +-@xref{Manipulating Hyphenation}. +- +-@c --------------------------------------------------------------------- +- +-@node Sentences, Tab Stops, Hyphenation, Text +-@subsection Sentences +-@cindex sentences +- +-Although it is often debated, some typesetting rules say there should be +-different amounts of space after various punctuation marks. For +-example, the @cite{Chicago typsetting manual} says that a period at the +-end of a sentence should have twice as much space following it as would +-a comma or a period as part of an abbreviation. +- +-@c XXX exact citation of Chicago manual +- +-@cindex sentence space +-@cindex space between sentences +-@cindex french-spacing +-@code{gtroff} does this by flagging certain characters (normally +-@samp{!}, @samp{?}, and @samp{.}) as @dfn{end-of-sentence} characters. +-When @code{gtroff} encounters one of these characters at the end of a +-line, it appends a normal space followed by a @dfn{sentence space} in +-the formatted output. (This justifies one of the conventions mentioned +-in @ref{Input Conventions}.) +- +-@cindex transparent characters +-@cindex character, transparent +-@cindex @code{dg} glyph, at end of sentence +-@cindex @code{rq} glyph, at end of sentence +-@cindex @code{cq} glyph, at end of sentence +-@cindex @code{"}, at end of sentence +-@cindex @code{'}, at end of sentence +-@cindex @code{)}, at end of sentence +-@cindex @code{]}, at end of sentence +-@cindex @code{*}, at end of sentence +-In addition, the following characters and symbols are treated +-transparently while handling end-of-sentence characters: @samp{"}, +-@samp{'}, @samp{)}, @samp{]}, @samp{*}, @code{\[dg]}, @code{\[rq]}, and +-@code{\[cq]}. +- +-See the @code{cflags} request in @ref{Using Symbols}, for more details. +- +-@cindex @code{\&}, at end of sentence +-To prevent the insertion of extra space after an end-of-sentence +-character (at the end of a line), append @code{\&}. +- +-@c --------------------------------------------------------------------- +- +-@node Tab Stops, Implicit Line Breaks, Sentences, Text +-@subsection Tab Stops +-@cindex tab stops +-@cindex stops, tabulator +-@cindex tab character +-@cindex character, tabulator +- +-@cindex @acronym{EBCDIC} encoding +-@cindex encoding, @acronym{EBCDIC} +-@code{gtroff} translates @dfn{tabulator characters}, also called +-@dfn{tabs} (normally code point @acronym{ASCII} @code{0x09} or +-@acronym{EBCDIC} @code{0x05}), in the input into movements to the next +-tabulator stop. These tab stops are initially located every half inch +-across the page. Using this, simple tables can be made easily. +-However, it can often be deceptive as the appearance (and width) of the +-text on a terminal and the results from @code{gtroff} can vary greatly. +- +-Also, a possible sticking point is that lines beginning with tab +-characters are still filled, again producing unexpected results. For +-example, the following input +- +-@multitable {12345678} {12345678} {12345678} {12345678} +-@item +-@tab 1 @tab 2 @tab 3 +-@item +-@tab @tab 4 @tab 5 +-@end multitable +- +-@noindent +-produces +- +-@multitable {12345678} {12345678} {12345678} {12345678} {12345678} {12345678} {12345678} +-@item +-@tab 1 @tab 2 @tab 3 @tab @tab 4 @tab 5 +-@end multitable +- +-@xref{Tabs and Fields}. +- +-@c --------------------------------------------------------------------- +- +-@node Implicit Line Breaks, Input Conventions, Tab Stops, Text +-@subsection Implicit Line Breaks +-@cindex implicit line breaks +-@cindex implicit breaks of lines +-@cindex line, implicit breaks +-@cindex break, implicit +-@cindex line break +- +-An important concept in @code{gtroff} is the @dfn{break}. When a break +-occurs, @code{gtroff} outputs the partially filled line (unjustified), +-and resumes collecting and filling text on the next output line. +- +-@cindex blank line +-@cindex empty line +-@cindex line, blank +-@cindex blank line macro (@code{blm}) +-There are several ways to cause a break in @code{gtroff}. A blank line +-not only causes a break, but it also outputs a one-line vertical space +-(effectively a blank line). Note that this behaviour can be modified +-with the blank line macro request @code{blm}. @xref{Blank Line Traps}. +- +-@cindex fill mode +-@cindex mode, fill +-@cindex leading spaces macro (@code{lsm}) +-A line that begins with a space causes a break and the space is output +-at the beginning of the next line. Note that this space isn't adjusted, +-even in fill mode; however, the behaviour can be modified with the +-leading spaces macro request @code{lsm}. @xref{Leading Spaces Traps}. +- +-The end of file also causes a break -- otherwise the last line of the +-document may vanish! +- +-Certain requests also cause breaks, implicitly or explicitly. This is +-discussed in @ref{Manipulating Filling and Adjusting}. +- +-@c --------------------------------------------------------------------- +- +-@node Input Conventions, Input Encodings, Implicit Line Breaks, Text +-@subsection Input Conventions +-@cindex input conventions +-@cindex conventions for input +- +-Since @code{gtroff} does filling automatically, it is traditional in +-@code{groff} not to try and type things in as nicely formatted +-paragraphs. These are some conventions commonly used when typing +-@code{gtroff} text: +- +-@itemize @bullet +-@item +-Break lines after punctuation, particularly at the end of a sentence and +-in other logical places. Keep separate phrases on lines by themselves, +-as entire phrases are often added or deleted when editing. +- +-@item +-Try to keep lines less than 40-60@tie{}characters, to allow space for +-inserting more text. +- +-@item +-Do not try to do any formatting in a @acronym{WYSIWYG} manner (i.e., +-don't try using spaces to get proper indentation). +-@end itemize +- +-@c --------------------------------------------------------------------- +- +-@node Input Encodings, , Input Conventions, Text +-@subsection Input Encodings +- +-Currently, the following input encodings are available. +- +-@table @asis +-@item cp1047 +-@cindex encoding, input, @acronym{EBCDIC} +-@cindex @acronym{EBCDIC}, input encoding +-@cindex input encoding, @acronym{EBCDIC} +-@cindex encoding, input, cp1047 +-@cindex cp1047, input encoding +-@cindex input encoding, cp1047 +-@cindex IBM cp1047 input encoding +-@pindex cp1047.tmac +-This input encoding works only on @acronym{EBCDIC} platforms (and vice +-versa, the other input encodings don't work with @acronym{EBCDIC}); the +-file @file{cp1047.tmac} is by default loaded at start-up. +- +-@item latin-1 +-@cindex encoding, input, @w{latin-1} (ISO @w{8859-1}) +-@cindex @w{latin-1} (ISO @w{8859-1}), input encoding +-@cindex ISO @w{8859-1} (@w{latin-1}), input encoding +-@cindex input encoding, @w{latin-1} (ISO @w{8859-1}) +-@pindex latin1.tmac +-This is the default input encoding on non-@acronym{EBCDIC} platforms; +-the file @file{latin1.tmac} is loaded at start-up. +- +-@item latin-2 +-@cindex encoding, input, @w{latin-2} (ISO @w{8859-2}) +-@cindex @w{latin-2} (ISO @w{8859-2}), input encoding +-@cindex ISO @w{8859-2} (@w{latin-2}), input encoding +-@cindex input encoding, @w{latin-2} (ISO @w{8859-2}) +-@pindex latin2.tmac +-To use this encoding, either say @w{@samp{.mso latin2.tmac}} at the very +-beginning of your document or use @samp{-mlatin2} as a command line +-argument for @code{groff}. +- +-@item latin-5 +-@cindex encoding, input, @w{latin-5} (ISO @w{8859-9}) +-@cindex @w{latin-2} (ISO @w{8859-9}), input encoding +-@cindex ISO @w{8859-9} (@w{latin-2}), input encoding +-@cindex input encoding, @w{latin-2} (ISO @w{8859-9}) +-@pindex latin2.tmac +-For Turkish. Either say @w{@samp{.mso latin9.tmac}} at the very +-beginning of your document or use @samp{-mlatin9} as a command line +-argument for @code{groff}. +- +-@item latin-9 (latin-0) +-@cindex encoding, input, @w{latin-9} (@w{latin-0}, ISO @w{8859-15}) +-@cindex @w{latin-9} (@w{latin-0}, ISO @w{8859-15}), input encoding +-@cindex ISO @w{8859-15} (@w{latin-9}, @w{latin-0}), input encoding +-@cindex input encoding, @w{latin-9} (@w{latin-9}, ISO @w{8859-15}) +-@pindex latin9.tmac +-This encoding is intended (at least in Europe) to replace @w{latin-1} +-encoding. The main difference to @w{latin-1} is that @w{latin-9} +-contains the Euro character. To use this encoding, either say +-@w{@samp{.mso latin9.tmac}} at the very beginning of your document or +-use @samp{-mlatin9} as a command line argument for @code{groff}. +-@end table +- +-Note that it can happen that some input encoding characters are not +-available for a particular output device. For example, saying +- +-@Example +-groff -Tlatin1 -mlatin9 ... +-@endExample +- +-@noindent +-fails if you use the Euro character in the input. Usually, this +-limitation is present only for devices that have a limited set of +-output glyphs (e.g.@: @option{-Tascii} and @option{-Tlatin1}); for other +-devices it is usually sufficient to install proper fonts that contain +-the necessary glyphs. +- +-@pindex freeeuro.pfa +-@pindex ec.tmac +-Due to the importance of the Euro glyph in Europe, the groff package now +-comes with a @sc{PostScript} font called @file{freeeuro.pfa}, which +-provides various glyph shapes for the Euro. In other words, +-@w{latin-9} encoding is supported for the @option{-Tps} device out of +-the box (@w{latin-2} isn't). +- +-By its very nature, @option{-Tutf8} supports all input encodings; +-@option{-Tdvi} has support for both @w{latin-2} and @w{latin-9} if the +-command line @option{-mec} is used also to load the file @file{ec.tmac} +-(which flips to the EC fonts). +- +- +-@c ===================================================================== +- +-@node Measurements, Expressions, Text, gtroff Reference +-@section Measurements +-@cindex measurements +-@cindex scaling indicator +-@cindex indicator, scaling +- +-@cindex units of measurement +-@cindex basic unit (@code{u}) +-@cindex machine unit (@code{u}) +-@cindex measurement unit +-@cindex @code{u} unit +-@cindex unit, @code{u} +-@code{gtroff} (like many other programs) requires numeric parameters to +-specify various measurements. Most numeric parameters@footnote{those +-that specify vertical or horizontal motion or a type size} may have a +-@dfn{measurement unit} attached. These units are specified as a single +-character that immediately follows the number or expression. Each of +-these units are understood, by @code{gtroff}, to be a multiple of its +-@dfn{basic unit}. So, whenever a different measurement unit is +-specified @code{gtroff} converts this into its @dfn{basic units}. This +-basic unit, represented by a @samp{u}, is a device dependent measurement, +-which is quite small, ranging from 1/75@dmn{th} to 1/72000@dmn{th} of an +-inch. The values may be given as fractional numbers; however, +-fractional basic units are always rounded to integers. +- +-Some of the measurement units are completely independent of any of the +-current settings (e.g.@: type size) of @code{gtroff}. +- +-@table @code +-@item i +-@cindex inch unit (@code{i}) +-@cindex @code{i} unit +-@cindex unit, @code{i} +-Inches. An antiquated measurement unit still in use in certain +-backwards countries with incredibly low-cost computer equipment. One +-inch is equal to@tie{}2.54@dmn{cm}. +- +-@item c +-@cindex centimeter unit (@code{c}) +-@cindex @code{c} unit +-@cindex unit, @code{c} +-Centimeters. One centimeter is equal to@tie{}0.3937@dmn{in}. +- +-@item p +-@cindex point unit (@code{p}) +-@cindex @code{p} unit +-@cindex unit, @code{p} +-Points. This is a typesetter's measurement used for measure type size. +-It is 72@tie{}points to an inch. +- +-@item P +-@cindex pica unit (@code{P}) +-@cindex @code{P} unit +-@cindex unit, @code{P} +-Pica. Another typesetting measurement. 6@tie{}Picas to an inch (and +-12@tie{}points to a pica). +- +-@item s +-@itemx z +-@cindex @code{s} unit +-@cindex unit, @code{s} +-@cindex @code{z} unit +-@cindex unit, @code{z} +-@xref{Fractional Type Sizes}, for a discussion of these units. +- +-@item f +-@cindex @code{f} unit +-@cindex unit, @code{f} +-Fractions. Value is 65536. +-@xref{Colors}, for usage. +-@end table +- +-The other measurements understood by @code{gtroff} depend on settings +-currently in effect in @code{gtroff}. These are very useful for +-specifying measurements that should look proper with any size of text. +- +-@table @code +-@item m +-@cindex em unit (@code{m}) +-@cindex @code{m} unit +-@cindex unit, @code{m} +-Ems. This unit is equal to the current font size in points. So called +-because it is @emph{approximately} the width of the letter@tie{}@samp{m} +-in the current font. +- +-@item n +-@cindex en unit (@code{n}) +-@cindex @code{n} unit +-@cindex unit, @code{n} +-Ens. In @code{groff}, this is half of an em. +- +-@item v +-@cindex vertical space unit (@code{v}) +-@cindex space, vertical, unit (@code{v}) +-@cindex @code{v} unit +-@cindex unit, @code{v} +-Vertical space. This is equivalent to the current line spacing. +-@xref{Sizes}, for more information about this. +- +-@item M +-@cindex @code{M} unit +-@cindex unit, @code{M} +-100ths of an em. +-@end table +- +-@menu +-* Default Units:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Default Units, , Measurements, Measurements +-@subsection Default Units +-@cindex default units +-@cindex units, default +- +-Many requests take a default unit. While this can be helpful at times, +-it can cause strange errors in some expressions. For example, the line +-length request expects em units. Here are several attempts to get a +-line length of 3.5@tie{}inches and their results: +- +-@Example +-3.5i @result{} 3.5i +-7/2 @result{} 0i +-7/2i @result{} 0i +-(7 / 2)u @result{} 0i +-7i/2 @result{} 0.1i +-7i/2u @result{} 3.5i +-@endExample +- +-@noindent +-Everything is converted to basic units first. In the above example it +-is assumed that 1@dmn{i} equals@tie{}240@dmn{u}, and 1@dmn{m} +-equals@tie{}10@dmn{p} (thus 1@dmn{m} equals@tie{}33@dmn{u}). The value +-7@dmn{i}/2 is first handled as 7@dmn{i}/2@dmn{m}, then converted to +-1680@dmn{u}/66@dmn{u}, which is 25@dmn{u}, and this is approximately +-0.1@dmn{i}. As can be seen, a scaling indicator after a closing +-parenthesis is simply ignored. +- +-@cindex measurements, specifying safely +-Thus, the safest way to specify measurements is to always attach a +-scaling indicator. If you want to multiply or divide by a certain +-scalar value, use @samp{u} as the unit for that value. +- +- +-@c ===================================================================== +- +-@node Expressions, Identifiers, Measurements, gtroff Reference +-@section Expressions +-@cindex expressions +- +-@code{gtroff} has most arithmetic operators common to other languages: +- +-@itemize @bullet +-@item +-@cindex arithmetic operators +-@cindex operators, arithmetic +-@opindex + +-@opindex - +-@opindex / +-@opindex * +-@opindex % +-Arithmetic: @samp{+} (addition), @samp{-} (subtraction), @samp{/} +-(division), @samp{*} (multiplication), @samp{%} (modulo). +- +-@code{gtroff} only provides integer arithmetic. The internal type used +-for computing results is @samp{int}, which is usually a 32@dmn{bit} +-signed integer. +- +-@item +-@cindex comparison operators +-@cindex operators, comparison +-@opindex < +-@opindex > +-@opindex >= +-@opindex <= +-@opindex = +-@opindex == +-Comparison: @samp{<} (less than), @samp{>} (greater than), @samp{<=} +-(less than or equal), @samp{>=} (greater than or equal), @samp{=} +-(equal), @samp{==} (the same as @samp{=}). +- +-@item +-@cindex logical operators +-@cindex operators, logical +-@opindex & +-@ifnotinfo +-@opindex : +-@end ifnotinfo +-@ifinfo +-@opindex @r{} +-@end ifinfo +-Logical: @samp{&} (logical and), @samp{:} (logical or). +- +-@item +-@cindex unary operators +-@cindex operators, unary +-@opindex - +-@opindex + +-@opindex ! +-@cindex @code{if} request, and the @samp{!} operator +-@cindex @code{while} request, and the @samp{!} operator +-Unary operators: @samp{-} (negating, i.e.@: changing the sign), @samp{+} +-(just for completeness; does nothing in expressions), @samp{!} (logical +-not; this works only within @code{if} and @code{while} +-requests).@footnote{Note that, for example, @samp{!(-1)} evaluates to +-`true' because @code{gtroff} treats both negative numbers and zero as +-`false'.} See below for the use of unary operators in motion requests. +- +-@cindex logical not, limitation in expression +-@cindex expression, limitation of logical not in +-The logical not operator, +-as described above, +-works only within @code{if} and @code{while} requests. +-Furthermore, it may appear +-only at the beginning of an expression, +-and negates the entire expression. +-Attempting to insert the @samp{!} operator +-within the expression results in a +-@samp{numeric expression expected} warning. This +-maintains compatibility +-with old versions of @code{troff}. +- +-Example: +- +-@Example +-.nr X 1 +-.nr Y 0 +-.\" This does not work as expected +-.if (\n[X])&(!\n[Y]) .nop X only +-. +-.\" Use this construct instead +-.if (\n[X]=1)&(\n[Y]=0) .nop X only +-@endExample +- +-@item +-@cindex extremum operators (@code{>?}, @code{?}, @code{? +-@opindex ?} (maximum), @samp{? \n[y]) +-@endExample +- +-@noindent +-The register@tie{}@code{z} now contains@tie{}5. +- +-@item +-@cindex scaling operator +-@cindex operator, scaling +-Scaling: @code{(@var{c};@var{e})}. Evaluate@tie{}@var{e} +-using@tie{}@var{c} as the default scaling indicator. If @var{c} is +-missing, ignore scaling indicators in the evaluation of@tie{}@var{e}. +-@end itemize +- +-@cindex parentheses +-@cindex order of evaluation in expressions +-@cindex expression, order of evaluation +-@opindex ( +-@opindex ) +-Parentheses may be used as in any other language. However, in +-@code{gtroff} they are necessary to ensure order of evaluation. +-@code{gtroff} has no operator precedence; expressions are evaluated left +-to right. This means that @code{gtroff} evaluates @samp{3+5*4} as if it +-were parenthesized like @samp{(3+5)*4}, not as @samp{3+(5*4)}, as might +-be expected. +- +-@cindex @code{+}, and page motion +-@cindex @code{-}, and page motion +-@cindex motion operators +-@cindex operators, motion +-For many requests that cause a motion on the page, the unary operators +-@samp{+} and @samp{-} work differently if leading an expression. They +-then indicate a motion relative to the current position (down or up, +-respectively). +- +-@cindex @code{|}, and page motion +-@cindex absolute position operator (@code{|}) +-@cindex position, absolute, operator (@code{|}) +-Similarly, a leading @samp{|} operator indicates an absolute position. +-For vertical movements, it specifies the distance from the top of the +-page; for horizontal movements, it gives the distance from the beginning +-of the @emph{input} line. +- +-@cindex @code{bp} request, using @code{+} and@tie{}@code{-} +-@cindex @code{in} request, using @code{+} and@tie{}@code{-} +-@cindex @code{ll} request, using @code{+} and@tie{}@code{-} +-@cindex @code{lt} request, using @code{+} and@tie{}@code{-} +-@cindex @code{nm} request, using @code{+} and@tie{}@code{-} +-@cindex @code{nr} request, using @code{+} and@tie{}@code{-} +-@cindex @code{pl} request, using @code{+} and@tie{}@code{-} +-@cindex @code{pn} request, using @code{+} and@tie{}@code{-} +-@cindex @code{po} request, using @code{+} and@tie{}@code{-} +-@cindex @code{ps} request, using @code{+} and@tie{}@code{-} +-@cindex @code{pvs} request, using @code{+} and@tie{}@code{-} +-@cindex @code{rt} request, using @code{+} and@tie{}@code{-} +-@cindex @code{ti} request, using @code{+} and@tie{}@code{-} +-@cindex @code{\H}, using @code{+} and@tie{}@code{-} +-@cindex @code{\R}, using @code{+} and@tie{}@code{-} +-@cindex @code{\s}, using @code{+} and@tie{}@code{-} +-@samp{+} and @samp{-} are also treated differently by the following +-requests and escapes: @code{bp}, @code{in}, @code{ll}, @code{lt}, +-@code{nm}, @code{nr}, @code{pl}, @code{pn}, @code{po}, @code{ps}, +-@code{pvs}, @code{rt}, @code{ti}, @code{\H}, @code{\R}, and @code{\s}. +-Here, leading plus and minus signs indicate increments and decrements. +- +-@xref{Setting Registers}, for some examples. +- +-@Defesc {\\B, ', anything, '} +-@cindex numeric expression, valid +-@cindex valid numeric expression +-Return@tie{}1 if @var{anything} is a valid numeric expression; or@tie{}0 +-if @var{anything} is empty or not a valid numeric expression. +-@endDefesc +- +-@cindex space characters, in expressions +-@cindex expressions, and space characters +-Due to the way arguments are parsed, spaces are not allowed in +-expressions, unless the entire expression is surrounded by parentheses. +- +-@xref{Request and Macro Arguments}, and @ref{Conditionals and Loops}. +- +- +-@c ===================================================================== +- +-@node Identifiers, Embedded Commands, Expressions, gtroff Reference +-@section Identifiers +-@cindex identifiers +- +-Like any other language, @code{gtroff} has rules for properly formed +-@dfn{identifiers}. In @code{gtroff}, an identifier can be made up of +-almost any printable character, with the exception of the following +-characters: +- +-@itemize @bullet +-@item +-@cindex whitespace characters +-@cindex newline character +-@cindex character, whitespace +-Whitespace characters (spaces, tabs, and newlines). +- +-@item +-@cindex character, backspace +-@cindex backspace character +-@cindex @acronym{EBCDIC} encoding of backspace +-Backspace (@acronym{ASCII}@tie{}@code{0x08} or +-@acronym{EBCDIC}@tie{}@code{0x16}) and character code @code{0x01}. +- +-@item +-@cindex invalid input characters +-@cindex input characters, invalid +-@cindex characters, invalid input +-@cindex Unicode +-The following input characters are invalid and are ignored if +-@code{groff} runs on a machine based on @acronym{ASCII}, causing a +-warning message of type @samp{input} (see @ref{Debugging}, for more +-details): @code{0x00}, @code{0x0B}, @code{0x0D}-@code{0x1F}, +-@code{0x80}-@code{0x9F}. +- +-And here are the invalid input characters if @code{groff} runs on an +-@acronym{EBCDIC} host: @code{0x00}, @code{0x08}, @code{0x09}, +-@code{0x0B}, @code{0x0D}-@code{0x14}, @code{0x17}-@code{0x1F}, +-@code{0x30}-@code{0x3F}. +- +-Currently, some of these reserved codepoints are used internally, thus +-making it non-trivial to extend @code{gtroff} to cover Unicode or other +-character sets and encodings that use characters of these ranges. +- +-Note that invalid characters are removed before parsing; an identifier +-@code{foo}, followed by an invalid character, followed by @code{bar} is +-treated as @code{foobar}. +-@end itemize +- +-For example, any of the following is valid. +- +-@Example +-br +-PP +-(l +-end-list +-@@_ +-@endExample +- +-@cindex @code{]}, as part of an identifier +-@noindent +-Note that identifiers longer than two characters with a closing bracket +-(@samp{]}) in its name can't be accessed with escape sequences that +-expect an identifier as a parameter. For example, @samp{\[foo]]} +-accesses the glyph @samp{foo}, followed by @samp{]}, whereas +-@samp{\C'foo]'} really asks for glyph @samp{foo]}. +- +-@cindex @code{refer}, and macro names starting with @code{[} or @code{]} +-@cindex @code{[}, macro names starting with, and @code{refer} +-@cindex @code{]}, macro names starting with, and @code{refer} +-@cindex macro names, starting with @code{[} or @code{]}, and @code{refer} +-To avoid problems with the @code{refer} preprocessor, macro names should +-not start with @samp{[} or @samp{]}. Due to backwards compatibility, +-everything after @samp{.[} and @samp{.]} is handled as a special +-argument to @code{refer}. For example, @samp{.[foo} makes @code{refer} +-to start a reference, using @samp{foo} as a parameter. +- +-@Defesc {\\A, ', ident, '} +-Test whether an identifier @var{ident} is valid in @code{gtroff}. It +-expands to the character@tie{}1 or@tie{}0 according to whether its +-argument (usually delimited by quotes) is or is not acceptable as the +-name of a string, macro, diversion, number register, environment, or +-font. It returns@tie{}0 if no argument is given. This is useful for +-looking up user input in some sort of associative table. +- +-@Example +-\A'end-list' +- @result{} 1 +-@endExample +-@endDefesc +- +-@xref{Escapes}, for details on parameter delimiting characters. +- +-Identifiers in @code{gtroff} can be any length, but, in some contexts, +-@code{gtroff} needs to be told where identifiers end and text begins +-(and in different ways depending on their length): +- +-@itemize @bullet +-@item +-Single character. +- +-@cindex @code{(}, starting a two-character identifier +-@item +-Two characters. Must be prefixed with @samp{(} in some situations. +- +-@cindex @code{[}, starting an identifier +-@cindex @code{]}, ending an identifier +-@item +-Arbitrary length (@code{gtroff} only). Must be bracketed with @samp{[} +-and@tie{}@samp{]} in some situations. Any length identifier can be put +-in brackets. +-@end itemize +- +-@cindex undefined identifiers +-@cindex identifiers, undefined +-Unlike many other programming languages, undefined identifiers are +-silently ignored or expanded to nothing. When @code{gtroff} finds an +-undefined identifier, it emits a warning, doing the following: +- +-@itemize @bullet +-@item +-If the identifier is a string, macro, or diversion, @code{gtroff} +-defines it as empty. +- +-@item +-If the identifier is a number register, @code{gtroff} defines it with a +-value of@tie{}0. +-@end itemize +- +-@xref{Warnings}., @ref{Interpolating Registers}, and @ref{Strings}. +- +-Note that macros, strings, and diversions share the same name space. +- +-@Example +-.de xxx +-. nop foo +-.. +-. +-.di xxx +-bar +-.br +-.di +-. +-.xxx +- @result{} bar +-@endExample +- +-@noindent +-As can be seen in the previous example, @code{gtroff} reuses the +-identifier @samp{xxx}, changing it from a macro to a diversion. No +-warning is emitted! The contents of the first macro definition is lost. +- +-@xref{Interpolating Registers}, and @ref{Strings}. +- +- +-@c ===================================================================== +- +-@node Embedded Commands, Registers, Identifiers, gtroff Reference +-@section Embedded Commands +-@cindex embedded commands +-@cindex commands, embedded +- +-Most documents need more functionality beyond filling, adjusting and +-implicit line breaking. In order to gain further functionality, +-@code{gtroff} allows commands to be embedded into the text, in two ways. +- +-The first is a @dfn{request} that takes up an entire line, and does +-some large-scale operation (e.g.@: break lines, start new pages). +- +-The other is an @dfn{escape} that can be usually embedded anywhere in +-the text; most requests can accept it even as an argument. Escapes +-generally do more minor operations like sub- and superscripts, print a +-symbol, etc. +- +-@menu +-* Requests:: +-* Macros:: +-* Escapes:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Requests, Macros, Embedded Commands, Embedded Commands +-@subsection Requests +-@cindex requests +- +-@cindex control character (@code{.}) +-@cindex character, control (@code{.}) +-@cindex no-break control character (@code{'}) +-@cindex character, no-break control (@code{'}) +-@cindex control character, no-break (@code{'}) +-A request line begins with a control character, which is either a single +-quote (@samp{'}, the @dfn{no-break control character}) or a period +-(@samp{.}, the normal @dfn{control character}). These can be changed; +-see @ref{Character Translations}, for details. After this there may be +-optional tabs or spaces followed by an identifier, which is the name of +-the request. This may be followed by any number of space-separated +-arguments (@emph{no} tabs here). +- +-@cindex structuring source code of documents or macro packages +-@cindex documents, structuring the source code +-@cindex macro packages, structuring the source code +-Since a control character followed by whitespace only is ignored, it is +-common practice to use this feature for structuring the source code of +-documents or macro packages. +- +-@Example +-.de foo +-. tm This is foo. +-.. +-. +-. +-.de bar +-. tm This is bar. +-.. +-@endExample +- +-@cindex blank line +-@cindex blank line macro (@code{blm}) +-Another possibility is to use the blank line macro request @code{blm} by +-assigning an empty macro to it. +- +-@Example +-.de do-nothing +-.. +-.blm do-nothing \" activate blank line macro +- +-.de foo +-. tm This is foo. +-.. +- +- +-.de bar +-. tm This is bar. +-.. +- +-.blm \" deactivate blank line macro +-@endExample +- +-@xref{Blank Line Traps}. +- +-@cindex zero width space character (@code{\&}) +-@cindex character, zero width space (@code{\&}) +-@cindex space character, zero width (@code{\&}) +-@cindex @code{\&}, escaping control characters +-To begin a line with a control character without it being interpreted, +-precede it with @code{\&}. This represents a zero width space, which +-means it does not affect the output. +- +-In most cases the period is used as a control character. Several +-requests cause a break implicitly; using the single quote control +-character prevents this. +- +-@Defreg {.br} +-A read-only number register, which is set to@tie{}1 if a macro is called +-with the normal control character (as defined with the @code{cc} +-request), and set to@tie{}0 otherwise. +- +-@cindex modifying requests +-@cindex requests, modifying +-This allows to reliably modify requests. +- +-@Example +-.als bp*orig bp +-.de bp +-. tm before bp +-. ie \\n[.br] .bp*orig +-. el 'bp*orig +-. tm after bp +-.. +-@endExample +- +-Using this register outside of a macro makes no sense (it always returns +-zero in such cases). +- +-If a macro is called as a string (this is, using @code{\*}), the value +-of the @code{.br} register is inherited from the calling macro. +-@endDefreg +- +-@menu +-* Request and Macro Arguments:: +-@end menu +- +-@node Request and Macro Arguments, , Requests, Requests +-@subsubsection Request and Macro Arguments +-@cindex request arguments +-@cindex macro arguments +-@cindex arguments to requests and macros +- +-@cindex tabs, and macro arguments +-@cindex macro arguments, and tabs +-@cindex arguments to macros, and tabs +-Arguments to requests and macros are processed much like the shell: +-The line is split into arguments according to +-spaces.@footnote{Plan@tie{}9's @code{troff} implementation also allows +-tabs for argument separation -- @code{gtroff} intentionally doesn't +-support this.} +- +-@cindex spaces, in a macro argument +-An argument to a macro that is intended to contain spaces can either be +-enclosed in double quotes, or have the spaces @dfn{escaped} with +-backslashes. This is @emph{not} true for requests. +- +-Here are a few examples for a hypothetical macro @code{uh}: +- +-@Example +-.uh The Mouse Problem +-.uh "The Mouse Problem" +-.uh The\ Mouse\ Problem +-@endExample +- +-@cindex @code{\~}, difference to @code{\@key{SP}} +-@cindex @code{\@key{SP}}, difference to @code{\~} +-@noindent +-The first line is the @code{uh} macro being called with 3 arguments, +-@samp{The}, @samp{Mouse}, and @samp{Problem}. The latter two have the +-same effect of calling the @code{uh} macro with one argument, @samp{The +-Mouse Problem}.@footnote{The last solution, i.e., using escaped spaces, +-is ``classical'' in the sense that it can be found in most @code{troff} +-documents. Nevertheless, it is not optimal in all situations, since +-@w{@samp{\ }} inserts a fixed-width, non-breaking space character that +-can't stretch. @code{gtroff} provides a different command @code{\~} to +-insert a stretchable, non-breaking space.} +- +-@cindex @code{"}, in a macro argument +-@cindex double quote, in a macro argument +-A double quote that isn't preceded by a space doesn't start a macro +-argument. If not closing a string, it is printed literally. +- +-For example, +- +-@Example +-.xxx a" "b c" "de"fg" +-@endExample +- +-@noindent +-has the arguments @samp{a"}, @w{@samp{b c}}, @samp{de}, and @samp{fg"}. +-Don't rely on this obscure behaviour! +- +-There are two possibilities to get a double quote reliably. +- +-@itemize @bullet +-@item +-Enclose the whole argument with double quotes and use two consecutive +-double quotes to represent a single one. This traditional solution has +-the disadvantage that double quotes don't survive argument expansion +-again if called in compatibility mode (using the @option{-C} option of +-@code{groff}): +- +-@Example +-.de xx +-. tm xx: `\\$1' `\\$2' `\\$3' +-. +-. yy "\\$1" "\\$2" "\\$3" +-.. +-.de yy +-. tm yy: `\\$1' `\\$2' `\\$3' +-.. +-.xx A "test with ""quotes""" . +- @result{} xx: `A' `test with "quotes"' `.' +- @result{} yy: `A' `test with ' `quotes""' +-@endExample +- +-@noindent +-If not in compatibility mode, you get the expected result +- +-@Example +-xx: `A' `test with "quotes"' `.' +-yy: `A' `test with "quotes"' `.' +-@endExample +- +-@noindent +-since @code{gtroff} preserves the input level. +- +-@item +-Use the double quote glyph @code{\(dq}. This works with and without +-compatibility mode enabled since @code{gtroff} doesn't convert +-@code{\(dq} back to a double quote input character. +- +-Note that this method won't work with @acronym{UNIX} @code{troff} in +-general since the glyph `dq' isn't defined normally. +-@end itemize +- +-@cindex @code{ds} request, and double quotes +-Double quotes in the @code{ds} request are handled differently. +-@xref{Strings}, for more details. +- +-@c --------------------------------------------------------------------- +- +-@node Macros, Escapes, Requests, Embedded Commands +-@subsection Macros +-@cindex macros +- +-@code{gtroff} has a @dfn{macro} facility for defining a series of lines +-that can be invoked by name. They are called in the same manner as +-requests -- arguments also may be passed basically in the same manner. +- +-@xref{Writing Macros}, and @ref{Request and Macro Arguments}. +- +-@c --------------------------------------------------------------------- +- +-@node Escapes, , Macros, Embedded Commands +-@subsection Escapes +-@cindex escapes +- +-Escapes may occur anywhere in the input to @code{gtroff}. They usually +-begin with a backslash and are followed by a single character, which +-indicates the function to be performed. The escape character can be +-changed; see @ref{Character Translations}. +- +-Escape sequences that require an identifier as a parameter accept three +-possible syntax forms. +- +-@itemize @bullet +-@item +-The next single character is the identifier. +- +-@cindex @code{(}, starting a two-character identifier +-@item +-If this single character is an opening parenthesis, take the following +-two characters as the identifier. Note that there is no closing +-parenthesis after the identifier. +- +-@cindex @code{[}, starting an identifier +-@cindex @code{]}, ending an identifier +-@item +-If this single character is an opening bracket, take all characters +-until a closing bracket as the identifier. +-@end itemize +- +-@noindent +-Examples: +- +-@Example +-\fB +-\n(XX +-\*[TeX] +-@endExample +- +-@cindex @code{'}, delimiting arguments +-@cindex argument delimiting characters +-@cindex characters, argument delimiting +-@cindex delimiting characters for arguments +-Other escapes may require several arguments and/or some special format. +-In such cases the argument is traditionally enclosed in single quotes +-(and quotes are always used in this manual for the definitions of escape +-sequences). The enclosed text is then processed according to what that +-escape expects. Example: +- +-@Example +-\l'1.5i\(bu' +-@endExample +- +-@cindex @code{\o}, possible quote characters +-@cindex @code{\b}, possible quote characters +-@cindex @code{\X}, possible quote characters +-Note that the quote character can be replaced with any other character +-that does not occur in the argument (even a newline or a space +-character) in the following escapes: @code{\o}, @code{\b}, and +-@code{\X}. This makes e.g. +- +-@Example +-A caf +-\o +-e\' +- +- +-in Paris +- @result{} A caf in Paris +-@endExample +- +-@noindent +-possible, but it is better not to use this feature to avoid confusion. +- +-@cindex @code{\%}, used as delimiter +-@cindex @code{\@key{SP}}, used as delimiter +-@cindex @code{\|}, used as delimiter +-@cindex @code{\^}, used as delimiter +-@cindex @code{\@{}, used as delimiter +-@cindex @code{\@}}, used as delimiter +-@cindex @code{\'}, used as delimiter +-@cindex @code{\`}, used as delimiter +-@cindex @code{\-}, used as delimiter +-@cindex @code{\_}, used as delimiter +-@cindex @code{\!}, used as delimiter +-@cindex @code{\?}, used as delimiter +-@cindex @code{\)}, used as delimiter +-@cindex @code{\/}, used as delimiter +-@cindex @code{\,}, used as delimiter +-@cindex @code{\&}, used as delimiter +-@ifnotinfo +-@cindex @code{\:}, used as delimiter +-@end ifnotinfo +-@ifinfo +-@cindex @code{\@r{}}, used as delimiter +-@end ifinfo +-@cindex @code{\~}, used as delimiter +-@cindex @code{\0}, used as delimiter +-@cindex @code{\a}, used as delimiter +-@cindex @code{\c}, used as delimiter +-@cindex @code{\d}, used as delimiter +-@cindex @code{\e}, used as delimiter +-@cindex @code{\E}, used as delimiter +-@cindex @code{\p}, used as delimiter +-@cindex @code{\r}, used as delimiter +-@cindex @code{\t}, used as delimiter +-@cindex @code{\u}, used as delimiter +-The following escapes sequences (which are handled similarly to +-characters since they don't take a parameter) are also allowed as +-delimiters: @code{\%}, @w{@samp{\ }}, @code{\|}, @code{\^}, @code{\@{}, +-@code{\@}}, @code{\'}, @code{\`}, @code{\-}, @code{\_}, @code{\!}, +-@code{\?}, @code{\)}, @code{\/}, @code{\,}, @code{\&}, @code{\:}, +-@code{\~}, @code{\0}, @code{\a}, @code{\c}, @code{\d}, @code{\e}, +-@code{\E}, @code{\p}, @code{\r}, @code{\t}, and @code{\u}. Again, don't +-use these if possible. +- +-@cindex @code{\A}, allowed delimiters +-@cindex @code{\B}, allowed delimiters +-@cindex @code{\Z}, allowed delimiters +-@cindex @code{\C}, allowed delimiters +-@cindex @code{\w}, allowed delimiters +-No newline characters as delimiters are allowed in the following +-escapes: @code{\A}, @code{\B}, @code{\Z}, @code{\C}, and @code{\w}. +- +-@cindex @code{\D}, allowed delimiters +-@cindex @code{\h}, allowed delimiters +-@cindex @code{\H}, allowed delimiters +-@cindex @code{\l}, allowed delimiters +-@cindex @code{\L}, allowed delimiters +-@cindex @code{\N}, allowed delimiters +-@cindex @code{\R}, allowed delimiters +-@cindex @code{\s}, allowed delimiters +-@cindex @code{\S}, allowed delimiters +-@cindex @code{\v}, allowed delimiters +-@cindex @code{\x}, allowed delimiters +-Finally, the escapes @code{\D}, @code{\h}, @code{\H}, @code{\l}, +-@code{\L}, @code{\N}, @code{\R}, @code{\s}, @code{\S}, @code{\v}, and +-@code{\x} can't use the following characters as delimiters: +- +-@itemize @bullet +-@item +-@cindex numbers, and delimiters +-@cindex digits, and delimiters +-The digits @code{0}-@code{9}. +- +-@item +-@cindex operators, as delimiters +-@cindex @code{+}, as delimiter +-@cindex @code{-}, as delimiter +-@cindex @code{/}, as delimiter +-@cindex @code{*}, as delimiter +-@cindex @code{%}, as delimiter +-@cindex @code{<}, as delimiter +-@cindex @code{>}, as delimiter +-@cindex @code{=}, as delimiter +-@cindex @code{&}, as delimiter +-@ifnotinfo +-@cindex @code{:}, as delimiter +-@end ifnotinfo +-@ifinfo +-@cindex , as delimiter +-@end ifinfo +-@cindex @code{(}, as delimiter +-@cindex @code{)}, as delimiter +-@cindex @code{.}, as delimiter +-The (single-character) operators @samp{+-/*%<>=&:().}. +- +-@item +-@cindex space character +-@cindex character, space +-@cindex tab character +-@cindex character, tab +-@cindex newline character +-@cindex character, newline +-The space, tab, and newline characters. +- +-@item +-@cindex @code{\%}, used as delimiter +-@ifnotinfo +-@cindex @code{\:}, used as delimiter +-@end ifnotinfo +-@ifinfo +-@cindex @code{\@r{}}, used as delimiter +-@end ifinfo +-@cindex @code{\@{}, used as delimiter +-@cindex @code{\@}}, used as delimiter +-@cindex @code{\'}, used as delimiter +-@cindex @code{\`}, used as delimiter +-@cindex @code{\-}, used as delimiter +-@cindex @code{\_}, used as delimiter +-@cindex @code{\!}, used as delimiter +-@cindex @code{\/}, used as delimiter +-@cindex @code{\c}, used as delimiter +-@cindex @code{\e}, used as delimiter +-@cindex @code{\p}, used as delimiter +-All escape sequences except @code{\%}, @code{\:}, @code{\@{}, +-@code{\@}}, @code{\'}, @code{\`}, @code{\-}, @code{\_}, @code{\!}, +-@code{\/}, @code{\c}, @code{\e}, and @code{\p}. +-@end itemize +- +-@cindex printing backslash (@code{\\}, @code{\e}, @code{\E}, @code{\[rs]}) +-@cindex backslash, printing (@code{\\}, @code{\e}, @code{\E}, @code{\[rs]}) +-To have a backslash (actually, the current escape character) appear in +-the output several escapes are defined: @code{\\}, @code{\e} or +-@code{\E}. These are very similar, and only differ with respect to +-being used in macros or diversions. @xref{Character Translations}, for +-an exact description of those escapes. +- +-@xref{Implementation Differences}, @ref{Copy-in Mode}, and +-@ref{Diversions}, @ref{Identifiers}, for more information. +- +-@menu +-* Comments:: +-@end menu +- +-@node Comments, , Escapes, Escapes +-@subsubsection Comments +-@cindex comments +- +-Probably one of the most@footnote{Unfortunately, this is a lie. But +-hopefully future @code{gtroff} hackers will believe it @code{:-)}} +-common forms of escapes is the comment. +- +-@Defesc {\\", , , } +-Start a comment. Everything to the end of the input line is ignored. +- +-This may sound simple, but it can be tricky to keep the comments from +-interfering with the appearance of the final output. +- +-@cindex @code{ds}, @code{ds1} requests, and comments +-@cindex @code{as}, @code{as1} requests, and comments +-If the escape is to the right of some text or a request, that portion of +-the line is ignored, but the space leading up to it is noticed by +-@code{gtroff}. This only affects the @code{ds} and @code{as} request +-and its variants. +- +-@cindex tabs, before comments +-@cindex comments, lining up with tabs +-One possibly irritating idiosyncracy is that tabs must not be used to +-line up comments. Tabs are not treated as whitespace between the +-request and macro arguments. +- +-@cindex undefined request +-@cindex request, undefined +-A comment on a line by itself is treated as a blank line, because after +-eliminating the comment, that is all that remains: +- +-@Example +-Test +-\" comment +-Test +-@endExample +- +-@noindent +-produces +- +-@Example +-Test +- +-Test +-@endExample +- +-To avoid this, it is common to start the line with @code{.\"}, which +-causes the line to be treated as an undefined request and thus ignored +-completely. +- +-@cindex @code{'}, as a comment +-Another commenting scheme seen sometimes is three consecutive single +-quotes (@code{'''}) at the beginning of a line. This works, but +-@code{gtroff} gives a warning about an undefined macro (namely +-@code{''}), which is harmless, but irritating. +-@endDefesc +- +-@Defesc {\\#, , , } +-To avoid all this, @code{gtroff} has a new comment mechanism using the +-@code{\#} escape. This escape works the same as @code{\"} except that +-the newline is also ignored: +- +-@Example +-Test +-\# comment +-Test +-@endExample +- +-@noindent +-produces +- +-@Example +-Test Test +-@endExample +- +-@noindent +-as expected. +-@endDefesc +- +-@Defreq {ig, [@Var{end}]} +-Ignore all input until @code{gtroff} encounters the macro named +-@code{.}@var{end} on a line by itself (or @code{..} if @var{end} is not +-specified). This is useful for commenting out large blocks of text: +- +-@Example +-text text text... +-.ig +-This is part of a large block +-of text that has been +-temporarily(?) commented out. +- +-We can restore it simply by removing +-the .ig request and the ".." at the +-end of the block. +-.. +-More text text text... +-@endExample +- +-@noindent +-produces +- +-@Example +-text text text@dots{} More text text text@dots{} +-@endExample +- +-@noindent +-Note that the commented-out block of text does not cause a break. +- +-@cindex @code{ig} request, and copy-in mode +-@cindex copy-in mode, and @code{ig} request +-@cindex mode, copy-in, and @code{ig} request +-@cindex @code{ig} request, and auto-increment +-@cindex auto-increment, and @code{ig} request +-The input is read in copy-mode; auto-incremented registers @emph{are} +-affected (@pxref{Auto-increment}). +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Registers, Manipulating Filling and Adjusting, Embedded Commands, gtroff Reference +-@section Registers +-@cindex registers +- +-Numeric variables in @code{gtroff} are called @dfn{registers}. There +-are a number of built-in registers, supplying anything from the date to +-details of formatting parameters. +- +-@xref{Identifiers}, for details on register identifiers. +- +-@menu +-* Setting Registers:: +-* Interpolating Registers:: +-* Auto-increment:: +-* Assigning Formats:: +-* Built-in Registers:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Setting Registers, Interpolating Registers, Registers, Registers +-@subsection Setting Registers +-@cindex setting registers (@code{nr}, @code{\R}) +-@cindex registers, setting (@code{nr}, @code{\R}) +- +-Define or set registers using the @code{nr} request or the @code{\R} +-escape. +- +-Although the following requests and escapes can be used to create +-registers, simply using an undefined register will cause it to be +-set to zero. +- +-@DefreqList {nr, ident value} +-@DefescListEndx {\\R, ', ident value, '} +-Set number register @var{ident} to @var{value}. If @var{ident} doesn't +-exist, @code{gtroff} creates it. +- +-The argument to @code{\R} usually has to be enclosed in quotes. +-@xref{Escapes}, for details on parameter delimiting characters. +- +-The @code{\R} escape doesn't produce an input token in @code{gtroff}; +-in other words, it vanishes completely after @code{gtroff} has +-processed it. +- +-For example, the following two lines are equivalent: +- +-@Example +-.nr a (((17 + (3 * 4))) % 4) +-\R'a (((17 + (3 * 4))) % 4)' +- @result{} 1 +-@endExample +- +-Note that the complete transparency of @code{\R} can cause surprising +-effects if you use number registers like @code{.k}, which get evaluated +-at the time they are accessed. +- +-@Example +-.ll 1.6i +-. +-aaa bbb ccc ddd eee fff ggg hhh\R':k \n[.k]' +-.tm :k == \n[:k] +- @result{} :k == 126950 +-. +-.br +-. +-aaa bbb ccc ddd eee fff ggg hhh\h'0'\R':k \n[.k]' +-.tm :k == \n[:k] +- @result{} :k == 15000 +-@endExample +- +-If you process this with the @sc{PostScript} device (@code{-Tps}), +-there will be a line break eventually after @code{ggg} in both input +-lines. However, after processing the space after @code{ggg}, the +-partially collected line is not overfull yet, so @code{troff} +-continues to collect input until it sees the space (or in this case, +-the newline) after @code{hhh}. At this point, the line is longer +-than the line length, and the line gets broken. +- +-In the first input line, since the @code{\R} escape leaves no traces, +-the check for the overfull line hasn't been done yet at the point where +-@code{\R} gets handled, and you get a value for the @code{.k} number +-register that is even greater than the current line length. +- +-In the second input line, the insertion of @code{\h'0'} to emit an +-invisible zero-width space forces @code{troff} to check the line length, +-which in turn causes the start of a new output line. Now @code{.k} +-returns the expected value. +-@endDefreq +- +-Both @code{nr} and @code{\R} have two additional special forms to +-increment or decrement a register. +- +-@DefreqList {nr, ident @t{+}@Var{value}} +-@DefreqItem {nr, ident @t{-}@Var{value}} +-@DefescItemx {\\R, ', ident @t{+}value, '} +-@DefescListEnd {\\R, ', ident @t{-}value, '} +-Increment (decrement) register @var{ident} by @var{value}. +- +-@Example +-.nr a 1 +-.nr a +1 +-\na +- @result{} 2 +-@endExample +- +-@cindex negating register values +-To assign the negated value of a register to another register, some care +-must be taken to get the desired result: +- +-@Example +-.nr a 7 +-.nr b 3 +-.nr a -\nb +-\na +- @result{} 4 +-.nr a (-\nb) +-\na +- @result{} -3 +-@endExample +- +-@noindent +-The surrounding parentheses prevent the interpretation of the minus sign +-as a decrementing operator. An alternative is to start the assignment +-with a @samp{0}: +- +-@Example +-.nr a 7 +-.nr b -3 +-.nr a \nb +-\na +- @result{} 4 +-.nr a 0\nb +-\na +- @result{} -3 +-@endExample +-@endDefreq +- +-@Defreq {rr, ident} +-@cindex removing number register (@code{rr}) +-@cindex number register, removing (@code{rr}) +-@cindex register, removing (@code{rr}) +-Remove number register @var{ident}. If @var{ident} doesn't exist, the +-request is ignored. +-@endDefreq +- +-@Defreq {rnn, ident1 ident2} +-@cindex renaming number register (@code{rnn}) +-@cindex number register, renaming (@code{rnn}) +-@cindex register, renaming (@code{rnn}) +-Rename number register @var{ident1} to @var{ident2}. If either +-@var{ident1} or @var{ident2} doesn't exist, the request is ignored. +-@endDefreq +- +-@Defreq {aln, ident1 ident2} +-@cindex alias, number register, creating (@code{aln}) +-@cindex creating alias, for number register (@code{aln}) +-@cindex number register, creating alias (@code{aln}) +-@cindex register, creating alias (@code{aln}) +-Create an alias @var{ident1} for a number register @var{ident2}. The +-new name and the old name are exactly equivalent. If @var{ident1} is +-undefined, a warning of type @samp{reg} is generated, and the request is +-ignored. @xref{Debugging}, for information about warnings. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Interpolating Registers, Auto-increment, Setting Registers, Registers +-@subsection Interpolating Registers +-@cindex interpolating registers (@code{\n}) +-@cindex registers, interpolating (@code{\n}) +- +-Numeric registers can be accessed via the @code{\n} escape. +- +-@DefescList {\\n, , i, } +-@DefescItem {\\n, @Lparen{}, id, } +-@DefescListEnd {\\n, @Lbrack{}, ident, @Rbrack{}} +-@cindex nested assignments +-@cindex assignments, nested +-@cindex indirect assignments +-@cindex assignments, indirect +-Interpolate number register with name @var{ident} (one-character +-name@tie{}@var{i}, two-character name @var{id}). This means that the +-value of the register is expanded in-place while @code{gtroff} is +-parsing the input line. Nested assignments (also called indirect +-assignments) are possible. +- +-@Example +-.nr a 5 +-.nr as \na+\na +-\n(as +- @result{} 10 +-@endExample +- +-@Example +-.nr a1 5 +-.nr ab 6 +-.ds str b +-.ds num 1 +-\n[a\n[num]] +- @result{} 5 +-\n[a\*[str]] +- @result{} 6 +-@endExample +-@endDefesc +- +-@c --------------------------------------------------------------------- +- +-@node Auto-increment, Assigning Formats, Interpolating Registers, Registers +-@subsection Auto-increment +-@cindex auto-increment +-@cindex increment, automatic +- +-Number registers can also be auto-incremented and auto-decremented. The +-increment or decrement value can be specified with a third argument to +-the @code{nr} request or @code{\R} escape. +- +-@Defreq {nr, ident value incr} +-@cindex @code{\R}, difference to @code{nr} +-Set number register @var{ident} to @var{value}; the increment for +-auto-incrementing is set to @var{incr}. Note that the @code{\R} escape +-doesn't support this notation. +-@endDefreq +- +-To activate auto-incrementing, the escape @code{\n} has a special syntax +-form. +- +-@DefescList {\\n, +, i, } +-@DefescItem {\\n, -, i, } +-@DefescItem {\\n, @Lparen{}+, id, } +-@DefescItem {\\n, @Lparen{}-, id, } +-@DefescItem {\\n, +@Lparen{}, id, } +-@DefescItem {\\n, -@Lparen{}, id, } +-@DefescItem {\\n, @Lbrack{}+, ident, @Rbrack{}} +-@DefescItem {\\n, @Lbrack{}-, ident, @Rbrack{}} +-@DefescItem {\\n, +@Lbrack{}, ident, @Rbrack{}} +-@DefescListEnd {\\n, -@Lbrack{}, ident, @Rbrack{}} +-Before interpolating, increment or decrement @var{ident} (one-character +-name@tie{}@var{i}, two-character name @var{id}) by the auto-increment +-value as specified with the @code{nr} request (or the @code{\R} escape). +-If no auto-increment value has been specified, these syntax forms are +-identical to @code{\n}. +-@endDefesc +- +-For example, +- +-@Example +-.nr a 0 1 +-.nr xx 0 5 +-.nr foo 0 -2 +-\n+a, \n+a, \n+a, \n+a, \n+a +-.br +-\n-(xx, \n-(xx, \n-(xx, \n-(xx, \n-(xx +-.br +-\n+[foo], \n+[foo], \n+[foo], \n+[foo], \n+[foo] +-@endExample +- +-@noindent +-produces +- +-@Example +-1, 2, 3, 4, 5 +--5, -10, -15, -20, -25 +--2, -4, -6, -8, -10 +-@endExample +- +-@cindex increment value without changing the register +-@cindex value, incrementing without changing the register +-To change the increment value without changing the value of a register +-(@var{a} in the example), the following can be used: +- +-@Example +-.nr a \na 10 +-@endExample +- +-@c --------------------------------------------------------------------- +- +-@node Assigning Formats, Built-in Registers, Auto-increment, Registers +-@subsection Assigning Formats +-@cindex assigning formats (@code{af}) +-@cindex formats, assigning (@code{af}) +- +-When a register is used, it is always textually replaced (or +-interpolated) with a representation of that number. This output format +-can be changed to a variety of formats (numbers, Roman numerals, etc.). +-This is done using the @code{af} request. +- +-@Defreq {af, ident format} +-Change the output format of a number register. The first argument +-@var{ident} is the name of the number register to be changed, and the +-second argument @var{format} is the output format. The following output +-formats are available: +- +-@table @code +-@item 1 +-Decimal arabic numbers. This is the default format: 0, 1, 2, +-3,@tie{}@enddots{} +- +-@item 0@dots{}0 +-Decimal numbers with as many digits as specified. So, @samp{00} would +-result in printing numbers as 01, 02, 03,@tie{}@enddots{} +- +-In fact, any digit instead of zero does work; @code{gtroff} only counts +-how many digits are specified. As a consequence, @code{af}'s default +-format @samp{1} could be specified as @samp{0} also (and exactly this is +-returned by the @code{\g} escape, see below). +- +-@item I +-@cindex Roman numerals +-@cindex numerals, Roman +-Upper-case Roman numerals: 0, I, II, III, IV,@tie{}@enddots{} +- +-@item i +-Lower-case Roman numerals: 0, i, ii, iii, iv,@tie{}@enddots{} +- +-@item A +-Upper-case letters: 0, A, B, C, @dots{},@tie{}Z, AA, AB,@tie{}@enddots{} +- +-@item a +-Lower-case letters: 0, a, b, c, @dots{},@tie{}z, aa, ab,@tie{}@enddots{} +-@end table +- +-Omitting the number register format causes a warning of type +-@samp{missing}. @xref{Debugging}, for more details. Specifying a +-nonexistent format causes an error. +- +-The following example produces @samp{10, X, j, 010}: +- +-@Example +-.nr a 10 +-.af a 1 \" the default format +-\na, +-.af a I +-\na, +-.af a a +-\na, +-.af a 001 +-\na +-@endExample +- +-@cindex Roman numerals, maximum and minimum +-@cindex maximum values of Roman numerals +-@cindex minimum values of Roman numerals +-The largest number representable for the @samp{i} and @samp{I} formats +-is 39999 (or @minus{}39999); @acronym{UNIX} @code{troff} uses @samp{z} +-and @samp{w} to represent 10000 and 5000 in Roman numerals, and so does +-@code{gtroff}. Currently, the correct glyphs of Roman numeral five +-thousand and Roman numeral ten thousand (Unicode code points +-@code{U+2182} and @code{U+2181}, respectively) are not available. +- +-If @var{ident} doesn't exist, it is created. +- +-@cindex read-only register, changing format +-@cindex changing format, and read-only registers +-Changing the output format of a read-only register causes an error. It +-is necessary to first copy the register's value to a writeable register, +-then apply the @code{af} request to this other register. +-@endDefreq +- +-@DefescList {\\g, , i, } +-@DefescItem {\\g, @Lparen{}, id, } +-@DefescListEnd {\\g, @Lbrack{}, ident, @Rbrack{}} +-@cindex format of register (@code{\g}) +-@cindex register, format (@code{\g}) +-Return the current format of the specified register @var{ident} +-(one-character name@tie{}@var{i}, two-character name @var{id}). For +-example, @samp{\ga} after the previous example would produce the string +-@samp{000}. If the register hasn't been defined yet, nothing is +-returned. +-@endDefesc +- +-@c --------------------------------------------------------------------- +- +-@node Built-in Registers, , Assigning Formats, Registers +-@subsection Built-in Registers +-@cindex built-in registers +-@cindex registers, built-in +- +-The following lists some built-in registers that are not described +-elsewhere in this manual. Any register that begins with a @samp{.} is +-read-only. A complete listing of all built-in registers can be found in +-@ref{Register Index}. +- +-@table @code +-@item \n[.F] +-@cindex current input file name register (@code{.F}) +-@cindex input file name, current, register (@code{.F}) +-@vindex .F +-This string-valued register returns the current input file name. +- +-@item \n[.H] +-@cindex horizontal resolution register (@code{.H}) +-@cindex resolution, horizontal, register (@code{.H}) +-@vindex .H +-Horizontal resolution in basic units. +- +-@item \n[.R] +-@cindex number of registers register (@code{.R}) +-@cindex registers, number of, register (@code{.R}) +-@vindex .R +-The number of number registers available. This is always 10000 in +-GNU@tie{}@code{troff}; it exists for backward compatibility. +- +-@item \n[.U] +-@cindex safer mode +-@cindex mode, safer +-@cindex unsafe mode +-@cindex mode, unsafe +-@vindex .U +-If @code{gtroff} is called with the @option{-U} command line option to +-activate unsafe mode, the number register @code{.U} is set to@tie{}1, +-and to zero otherwise. @xref{Groff Options}. +- +-@item \n[.V] +-@cindex vertical resolution register (@code{.V}) +-@cindex resolution, vertical, register (@code{.V}) +-@vindex .V +-Vertical resolution in basic units. +- +-@item \n[seconds] +-@cindex seconds, current time (@code{seconds}) +-@cindex time, current, seconds (@code{seconds}) +-@cindex current time, seconds (@code{seconds}) +-@vindex seconds +-The number of seconds after the minute, normally in the range@tie{}0 +-to@tie{}59, but can be up to@tie{}61 to allow for leap seconds. +-Initialized at start-up of @code{gtroff}. +- +-@item \n[minutes] +-@cindex minutes, current time (@code{minutes}) +-@cindex time, current, minutes (@code{minutes}) +-@cindex current time, minutes (@code{minutes}) +-@vindex minutes +-The number of minutes after the hour, in the range@tie{}0 to@tie{}59. +-Initialized at start-up of @code{gtroff}. +- +-@item \n[hours] +-@cindex hours, current time (@code{hours}) +-@cindex time, current, hours (@code{hours}) +-@cindex current time, hours (@code{hours}) +-@vindex hours +-The number of hours past midnight, in the range@tie{}0 to@tie{}23. +-Initialized at start-up of @code{gtroff}. +- +-@item \n[dw] +-@cindex day of the week register (@code{dw}) +-@cindex date, day of the week register (@code{dw}) +-@vindex dw +-Day of the week (1-7). +- +-@item \n[dy] +-@cindex day of the month register (@code{dy}) +-@cindex date, day of the month register (@code{dy}) +-@vindex dy +-Day of the month (1-31). +- +-@item \n[mo] +-@cindex month of the year register (@code{mo}) +-@cindex date, month of the year register (@code{mo}) +-@vindex mo +-Current month (1-12). +- +-@item \n[year] +-@cindex date, year register (@code{year}, @code{yr}) +-@cindex year, current, register (@code{year}, @code{yr}) +-@vindex year +-The current year. +- +-@item \n[yr] +-@vindex yr +-The current year minus@tie{}1900. Unfortunately, the documentation of +-@acronym{UNIX} Version@tie{}7's @code{troff} had a year@tie{}2000 bug: +-It incorrectly claimed that @code{yr} contains the last two digits of +-the year. That claim has never been true of either @acronym{AT&T} +-@code{troff} or GNU @code{troff}. Old @code{troff} input that looks +-like this: +- +-@Example +-'\" The following line stopped working after 1999 +-This document was formatted in 19\n(yr. +-@endExample +- +-@noindent +-can be corrected as follows: +- +-@Example +-This document was formatted in \n[year]. +-@endExample +- +-@noindent +-or, to be portable to older @code{troff} versions, as follows: +- +-@Example +-.nr y4 1900+\n(yr +-This document was formatted in \n(y4. +-@endExample +- +-@item \n[.c] +-@vindex .c +-@itemx \n[c.] +-@vindex c. +-@cindex input line number register (@code{.c}, @code{c.}) +-@cindex line number, input, register (@code{.c}, @code{c.}) +-The current @emph{input} line number. Register @samp{.c} is read-only, +-whereas @samp{c.} (a @code{gtroff} extension) is writable also, +-affecting both @samp{.c} and @samp{c.}. +- +-@item \n[ln] +-@vindex ln +-@cindex output line number register (@code{ln}) +-@cindex line number, output, register (@code{ln}) +-The current @emph{output} line number after a call to the @code{nm} +-request to activate line numbering. +- +-@xref{Miscellaneous}, for more information about line numbering. +- +-@item \n[.x] +-@vindex .x +-@cindex major version number register (@code{.x}) +-@cindex version number, major, register (@code{.x}) +-The major version number. For example, if the version number is 1.03 +-then @code{.x} contains@tie{}@samp{1}. +- +-@item \n[.y] +-@vindex .y +-@cindex minor version number register (@code{.y}) +-@cindex version number, minor, register (@code{.y}) +-The minor version number. For example, if the version number is 1.03 +-then @code{.y} contains@tie{}@samp{03}. +- +-@item \n[.Y] +-@vindex .Y +-@cindex revision number register (@code{.Y}) +-The revision number of @code{groff}. +- +-@item \n[$$] +-@vindex $$ +-@cindex process ID of @code{gtroff} register (@code{$$}) +-@cindex @code{gtroff}, process ID register (@code{$$}) +-The process ID of @code{gtroff}. +- +-@item \n[.g] +-@vindex .g +-@cindex @code{gtroff}, identification register (@code{.g}) +-@cindex GNU-specific register (@code{.g}) +-Always@tie{}1. Macros should use this to determine whether they are +-running under GNU @code{troff}. +- +-@item \n[.A] +-@vindex .A +-@cindex @acronym{ASCII} approximation output register (@code{.A}) +-If the command line option @option{-a} is used to produce an +-@acronym{ASCII} approximation of the output, this is set to@tie{}1, zero +-otherwise. @xref{Groff Options}. +- +-@item \n[.O] +-@vindex .O +-This read-only register is set to the suppression nesting level (see +-escapes @code{\O}). @xref{Suppressing output}. +- +-@item \n[.P] +-@vindex .P +-This register is set to@tie{}1 (and to@tie{}0 otherwise) if the current +-page is actually being printed, i.e., if the @option{-o} option is being +-used to only print selected pages. @xref{Groff Options}, for more +-information. +- +-@item \n[.T] +-@vindex .T +-If @code{gtroff} is called with the @option{-T} command line option, the +-number register @code{.T} is set to@tie{}1, and zero otherwise. +-@xref{Groff Options}. +- +-@item \*[.T] +-@stindex .T +-@cindex output device name string register (@code{.T}) +-A single read-write string register that contains the current output +-device (for example, @samp{latin1} or @samp{ps}). This is the only +-string register defined by @code{gtroff}. +-@end table +- +- +-@c ===================================================================== +- +-@node Manipulating Filling and Adjusting, Manipulating Hyphenation, Registers, gtroff Reference +-@section Manipulating Filling and Adjusting +-@cindex manipulating filling and adjusting +-@cindex filling and adjusting, manipulating +-@cindex adjusting and filling, manipulating +-@cindex justifying text +-@cindex text, justifying +- +-@cindex break +-@cindex line break +-@cindex @code{bp} request, causing implicit linebreak +-@cindex @code{ce} request, causing implicit linebreak +-@cindex @code{cf} request, causing implicit linebreak +-@cindex @code{fi} request, causing implicit linebreak +-@cindex @code{fl} request, causing implicit linebreak +-@cindex @code{in} request, causing implicit linebreak +-@cindex @code{nf} request, causing implicit linebreak +-@cindex @code{rj} request, causing implicit linebreak +-@cindex @code{sp} request, causing implicit linebreak +-@cindex @code{ti} request, causing implicit linebreak +-@cindex @code{trf} request, causing implicit linebreak +-Various ways of causing @dfn{breaks} were given in @ref{Implicit Line +-Breaks}. The @code{br} request likewise causes a break. Several other +-requests also cause breaks, but implicitly. These are @code{bp}, +-@code{ce}, @code{cf}, @code{fi}, @code{fl}, @code{in}, @code{nf}, +-@code{rj}, @code{sp}, @code{ti}, and @code{trf}. +- +-@Defreq {br, } +-Break the current line, i.e., the input collected so far is emitted +-without adjustment. +- +-If the no-break control character is used, @code{gtroff} suppresses the +-break: +- +-@Example +-a +-'br +-b +- @result{} a b +-@endExample +-@endDefreq +- +-Initially, @code{gtroff} fills and adjusts text to both margins. +-Filling can be disabled via the @code{nf} request and re-enabled with +-the @code{fi} request. +- +-@DefreqList {fi, } +-@DefregListEndx {.u} +-@cindex fill mode (@code{fi}) +-@cindex mode, fill (@code{fi}) +-Activate fill mode (which is the default). This request implicitly +-enables adjusting; it also inserts a break in the text currently being +-filled. The read-only number register @code{.u} is set to@tie{}1. +- +-The fill mode status is associated with the current environment +-(@pxref{Environments}). +- +-See @ref{Line Control}, for interaction with the @code{\c} escape. +-@endDefreq +- +-@Defreq {nf, } +-@cindex no-fill mode (@code{nf}) +-@cindex mode, no-fill (@code{nf}) +-Activate no-fill mode. Input lines are output as-is, retaining line +-breaks and ignoring the current line length. This command implicitly +-disables adjusting; it also causes a break. The number register +-@code{.u} is set to@tie{}0. +- +-The fill mode status is associated with the current environment +-(@pxref{Environments}). +- +-See @ref{Line Control}, for interaction with the @code{\c} escape. +-@endDefreq +- +-@DefreqList {ad, [@Var{mode}]} +-@DefregListEndx {.j} +-Set adjusting mode. +- +-Activation and deactivation of adjusting is done implicitly with calls +-to the @code{fi} or @code{nf} requests. +- +-@var{mode} can have one of the following values: +- +-@table @code +-@item l +-@cindex ragged-right +-Adjust text to the left margin. This produces what is traditionally +-called ragged-right text. +- +-@item r +-@cindex ragged-left +-Adjust text to the right margin, producing ragged-left text. +- +-@item c +-@cindex centered text +-@cindex @code{ce} request, difference to @samp{.ad@tie{}c} +-Center filled text. This is different to the @code{ce} request, which +-only centers text without filling. +- +-@item b +-@itemx n +-Justify to both margins. This is the default used by @code{gtroff}. +-@end table +- +-Finally, @var{mode} can be the numeric argument returned by the +-@code{.j} register. +- +-Using @code{ad} without argument is the same as saying +-@w{@code{.ad \[.j]}}. In particular, @code{gtroff} adjusts lines +-in the same way it did before adjusting was deactivated (with a call +-to @code{na}, say). For example, this input code +- +-@Example +-.de AD +-. br +-. ad \\$1 +-.. +-. +-.de NA +-. br +-. na +-.. +-. +-textA +-.AD r +-.nr ad \n[.j] +-textB +-.AD c +-textC +-.NA +-textD +-.AD \" back to centering +-textE +-.AD \n[ad] \" back to right justifying +-textF +-@endExample +- +-@noindent +-produces the following output: +- +-@Example +-textA +- textB +- textC +-textD +- textE +- textF +-@endExample +- +-@cindex adjustment mode register (@code{.j}) +-As just demonstrated, the current adjustment mode is available in the +-read-only number register @code{.j}; it can be stored and +-subsequently used to set adjustment. +- +-The adjustment mode status is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@Defreq {na, } +-Disable adjusting. This request won't change the current adjustment +-mode: A subsequent call to @code{ad} uses the previous adjustment +-setting. +- +-The adjustment mode status is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@DefreqList {brp, } +-@DefescListEndx {\\p, , , } +-Adjust the current line and cause a break. +- +-In most cases this produces very ugly results since @code{gtroff} +-doesn't have a sophisticated paragraph building algorithm (as @TeX{} +-have, for example); instead, @code{gtroff} fills and adjusts a paragraph +-line by line: +- +-@Example +-This is an uninteresting sentence. +-This is an uninteresting sentence.\p +-This is an uninteresting sentence. +-@endExample +- +-@noindent +-is formatted as +- +-@Example +-This is an uninteresting sentence. This is an +-uninteresting sentence. +-This is an uninteresting sentence. +-@endExample +-@endDefreq +- +-@DefreqList {ss, word_space_size [@Var{sentence_space_size}]} +-@DefregItemx {.ss} +-@DefregListEndx {.sss} +-@cindex word space size register (@code{.ss}) +-@cindex size of word space register (@code{.ss}) +-@cindex space between words register (@code{.ss}) +-@cindex sentence space size register (@code{.sss}) +-@cindex size of sentence space register (@code{.sss}) +-@cindex space between sentences register (@code{.sss}) +-Change the size of a space between words. It takes its units as one +-twelfth of the space width parameter for the current font. Initially +-both the @var{word_space_size} and @var{sentence_space_size} +-are@tie{}12. In fill mode, the values specify the minimum distance. +- +-@cindex fill mode +-@cindex mode, fill +-If two arguments are given to the @code{ss} request, the second argument +-sets the sentence space size. If the second argument is not given, +-sentence space size is set to @var{word_space_size}. The sentence space +-size is used in two circumstances: If the end of a sentence occurs at +-the end of a line in fill mode, then both an inter-word space and a +-sentence space are added; if two spaces follow the end of a sentence in +-the middle of a line, then the second space is a sentence space. If a +-second argument is never given to the @code{ss} request, the behaviour +-of @acronym{UNIX} @code{troff} is the same as that exhibited by GNU +-@code{troff}. In GNU @code{troff}, as in @acronym{UNIX} @code{troff}, a +-sentence should always be followed by either a newline or two spaces. +- +-The read-only number registers @code{.ss} and @code{.sss} hold the +-values of the parameters set by the first and second arguments of the +-@code{ss} request. +- +-The word space and sentence space values are associated with the current +-environment (@pxref{Environments}). +- +-Contrary to @acronym{AT&T} @code{troff}, this request is @emph{not} +-ignored if a TTY output device is used; the given values are then +-rounded down to a multiple of@tie{}12 (@pxref{Implementation +-Differences}). +- +-The request is ignored if there is no parameter. +- +-@cindex discardable horizontal space +-@cindex space, discardable, horizontal +-@cindex horizontal discardable space +-Another useful application of the @code{ss} request is to insert +-discardable horizontal space, i.e., space that is discarded at a line +-break. For example, paragraph-style footnotes could be separated this +-way: +- +-@Example +-.ll 4.5i +-1.\ This is the first footnote.\c +-.ss 48 +-.nop +-.ss 12 +-2.\ This is the second footnote. +-@endExample +- +-@noindent +-The result: +- +-@Example +-1. This is the first footnote. 2. This +-is the second footnote. +-@endExample +- +-@noindent +-Note that the @code{\h} escape produces unbreakable space. +-@endDefreq +- +-@DefreqList {ce, [@Var{nnn}]} +-@DefregListEndx {.ce} +-@cindex centering lines (@code{ce}) +-@cindex lines, centering (@code{ce}) +-Center text. While the @w{@samp{.ad c}} request also centers text, it +-fills the text as well. @code{ce} does not fill the text it affects. +-This request causes a break. The number of lines still to be centered +-is associated with the current environment (@pxref{Environments}). +- +-The following example demonstrates the differences. Here the input: +- +-@Example +-.ll 4i +-.ce 1000 +-This is a small text fragment that shows the differences +-between the `.ce' and the `.ad c' request. +-.ce 0 +- +-.ad c +-This is a small text fragment that shows the differences +-between the `.ce' and the `.ad c' request. +-@endExample +- +-@noindent +-And here the result: +- +-@Example +- This is a small text fragment that +- shows the differences +-between the `.ce' and the `.ad c' request. +- +- This is a small text fragment that +-shows the differences between the `.ce' +- and the `.ad c' request. +-@endExample +- +-With no arguments, @code{ce} centers the next line of text. @var{nnn} +-specifies the number of lines to be centered. If the argument is zero +-or negative, centering is disabled. +- +-The basic length for centering text is the line length (as set with the +-@code{ll} request) minus the indentation (as set with the @code{in} +-request). Temporary indentation is ignored. +- +-As can be seen in the previous example, it is a common idiom to turn on +-centering for a large number of lines, and to turn off centering after +-text to be centered. This is useful for any request that takes a +-number of lines as an argument. +- +-The @code{.ce} read-only number register contains the number of lines +-remaining to be centered, as set by the @code{ce} request. +-@endDefreq +- +-@DefreqList {rj, [@Var{nnn}]} +-@DefregListEndx {.rj} +-@cindex justifying text (@code{rj}) +-@cindex text, justifying (@code{rj}) +-@cindex right-justifying (@code{rj}) +-Justify unfilled text to the right margin. Arguments are identical to +-the @code{ce} request. The @code{.rj} read-only number register is the +-number of lines to be right-justified as set by the @code{rj} request. +-This request causes a break. The number of lines still to be +-right-justified is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Manipulating Hyphenation, Manipulating Spacing, Manipulating Filling and Adjusting, gtroff Reference +-@section Manipulating Hyphenation +-@cindex manipulating hyphenation +-@cindex hyphenation, manipulating +- +-Here a description of requests that influence hyphenation. +- +-@DefreqList {hy, [@Var{mode}]} +-@DefregListEndx {.hy} +-Enable hyphenation. The request has an optional numeric argument, +-@var{mode}, to restrict hyphenation if necessary: +- +-@table @code +-@item 1 +-The default argument if @var{mode} is omitted. Hyphenate without +-restrictions. This is also the start-up value of @code{gtroff}. +- +-@item 2 +-Do not hyphenate the last word on a page or column. +- +-@item 4 +-Do not hyphenate the last two characters of a word. +- +-@item 8 +-Do not hyphenate the first two characters of a word. +-@end table +- +-Values in the previous table are additive. For example, the +-value@tie{}12 causes @code{gtroff} to neither hyphenate the last two nor +-the first two characters of a word. +- +-@cindex hyphenation restrictions register (@code{.hy}) +-The current hyphenation restrictions can be found in the read-only +-number register @samp{.hy}. +- +-The hyphenation mode is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@Defreq {nh, } +-Disable hyphenation (i.e., set the hyphenation mode to zero). Note that +-the hyphenation mode of the last call to @code{hy} is not remembered. +- +-The hyphenation mode is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@DefreqList {hlm, [@Var{nnn}]} +-@DefregItemx {.hlm} +-@DefregListEndx {.hlc} +-@cindex explicit hyphen (@code{\%}) +-@cindex hyphen, explicit (@code{\%}) +-@cindex consecutive hyphenated lines (@code{hlm}) +-@cindex lines, consecutive hyphenated (@code{hlm}) +-@cindex hyphenated lines, consecutive (@code{hlm}) +-Set the maximum number of consecutive hyphenated lines to @var{nnn}. If +-this number is negative, there is no maximum. The default value +-is@tie{}@minus{}1 if @var{nnn} is omitted. This value is associated +-with the current environment (@pxref{Environments}). Only lines output +-from a given environment count towards the maximum associated with that +-environment. Hyphens resulting from @code{\%} are counted; explicit +-hyphens are not. +- +-The current setting of @code{hlm} is available in the @code{.hlm} +-read-only number register. Also the number of immediately preceding +-consecutive hyphenated lines are available in the read-only number +-register @samp{.hlc}. +-@endDefreq +- +-@Defreq {hw, word1 word2 @dots{}} +-Define how @var{word1}, @var{word2}, etc.@: are to be hyphenated. The +-words must be given with hyphens at the hyphenation points. For +-example: +- +-@Example +-.hw in-sa-lub-rious +-@endExample +- +-@noindent +-Besides the space character, any character whose hyphenation code value +-is zero can be used to separate the arguments of @code{hw} (see the +-documentation for the @code{hcode} request below for more information). +-In addition, this request can be used more than once. +- +-Hyphenation exceptions specified with the @code{hw} request are +-associated with the current hyphenation language; it causes an error if +-there is no current hyphenation language. +- +-This request is ignored if there is no parameter. +- +-In old versions of @code{troff} there was a limited amount of space to +-store such information; fortunately, with @code{gtroff}, this is no +-longer a restriction. +-@endDefreq +- +-@DefescList {\\%, , , } +-@deffnx Escape @t{\:} +-@ifnotinfo +-@esindex \: +-@end ifnotinfo +-@ifinfo +-@esindex \@r{} +-@end ifinfo +-@cindex hyphenation character (@code{\%}) +-@cindex character, hyphenation (@code{\%}) +-@cindex disabling hyphenation (@code{\%}) +-@cindex hyphenation, disabling (@code{\%}) +-To tell @code{gtroff} how to hyphenate words on the fly, use the +-@code{\%} escape, also known as the @dfn{hyphenation character}. +-Preceding a word with this character prevents it from being +-hyphenated; putting it inside a word indicates to @code{gtroff} that +-the word may be hyphenated at that point. Note that this mechanism +-only affects that one occurrence of the word; to change the +-hyphenation of a word for the entire document, use the @code{hw} +-request. +- +-The @code{\:} escape inserts a zero-width break point (that is, the word +-breaks but without adding a hyphen). +- +-@Example +-... check the /var/log/\:httpd/\:access_log file ... +-@endExample +- +-@cindex @code{\X}, followed by @code{\%} +-@cindex @code{\Y}, followed by @code{\%} +-@cindex @code{\%}, following @code{\X} or @code{\Y} +-Note that @code{\X} and @code{\Y} start a word, that is, the @code{\%} +-escape in (say) @w{@samp{\X'...'\%foobar}} and +-@w{@samp{\Y'...'\%foobar}} no longer prevents hyphenation but inserts a +-hyphenation point at the beginning of @samp{foobar}; most likely this +-isn't what you want to do. +-@endDefesc +- +-@Defreq {hc, [@Var{char}]} +-Change the hyphenation character to @var{char}. This character then +-works the same as the @code{\%} escape, and thus, no longer appears in +-the output. Without an argument, @code{hc} resets the hyphenation +-character to be @code{\%} (the default) only. +- +-The hyphenation character is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@DefreqList {hpf, pattern_file} +-@DefreqItemx {hpfa, pattern_file} +-@DefreqListEndx {hpfcode, a b [c d @dots{}]} +-@cindex hyphenation patterns (@code{hpf}) +-@cindex patterns for hyphenation (@code{hpf}) +-Read in a file of hyphenation patterns. This file is searched for in +-the same way as @file{@var{name}.tmac} (or @file{tmac.@var{name}}) is +-searched for if the @option{-m@var{name}} option is specified. +- +-It should have the same format as (simple) @TeX{} patterns files. More +-specifically, the following scanning rules are implemented. +- +-@itemize @bullet +-@item +-A percent sign starts a comment (up to the end of the line) even if +-preceded by a backslash. +- +-@item +-No support for `digraphs' like @code{\$}. +- +-@item +-@code{^^@var{xx}} (@var{x} is 0-9 or a-f) and @code{^^@var{x}} +-(character code of @var{x} in the range 0-127) are recognized; other use +-of @code{^} causes an error. +- +-@item +-No macro expansion. +- +-@item +-@code{hpf} checks for the expression @code{\patterns@{@dots{}@}} +-(possibly with whitespace before and after the braces). Everything +-between the braces is taken as hyphenation patterns. Consequently, +-@code{@{} and @code{@}} are not allowed in patterns. +- +-@item +-Similarly, @code{\hyphenation@{@dots{}@}} gives a list of hyphenation +-exceptions. +- +-@item +-@code{\endinput} is recognized also. +- +-@item +-For backwards compatibility, if @code{\patterns} is missing, the whole +-file is treated as a list of hyphenation patterns (only recognizing the +-@code{%} character as the start of a comment). +-@end itemize +- +-If no @code{hpf} request is specified (either in the document or in a +-macro package), @code{gtroff} won't hyphenate at all. +- +-The @code{hpfa} request appends a file of patterns to the current list. +- +-The @code{hpfcode} request defines mapping values for character codes in +-hyphenation patterns. @code{hpf} or @code{hpfa} then apply the mapping +-(after reading the patterns) before replacing or appending them to the +-current list of patterns. Its arguments are pairs of character codes -- +-integers from 0 to@tie{}255. The request maps character +-code@tie{}@var{a} to code@tie{}@var{b}, code@tie{}@var{c} to +-code@tie{}@var{d}, and so on. You can use character codes that would +-be invalid otherwise. By default, everything maps to itself except +-letters `A' to `Z', which map to `a' to `z'. +- +- +-@pindex troffrc +-@pindex troffrc-end +-@pindex hyphen.us +-@pindex hyphenex.us +-The set of hyphenation patterns is associated with the current language +-set by the @code{hla} request. The @code{hpf} request is usually +-invoked by the @file{troffrc} or @file{troffrc-end} file; by default, +-@file{troffrc} loads hyphenation patterns and exceptions for American +-English (in files @file{hyphen.us} and @file{hyphenex.us}). +- +-A second call to @code{hpf} (for the same language) replaces the +-hyphenation patterns with the new ones. +- +-Invoking @code{hpf} causes an error if there is no current hyphenation +-language. +-@endDefreq +- +-@Defreq {hcode, c1 code1 [c2 code2 @dots{}]} +-@cindex hyphenation code (@code{hcode}) +-@cindex code, hyphenation (@code{hcode}) +-Set the hyphenation code of character @var{c1} to @var{code1}, that of +-@var{c2} to @var{code2}, etc. A hyphenation code must be a single input +-character (not a special character) other than a digit or a space. +- +-To make hyphenation work, hyphenation codes must be set up. At +-start-up, groff only assigns hyphenation codes to the letters +-@samp{a}-@samp{z} (mapped to themselves) and to the letters +-@samp{A}-@samp{Z} (mapped to @samp{a}-@samp{z}); all other hyphenation +-codes are set to zero. Normally, hyphenation patterns contain only +-lowercase letters, which should be applied regardless of case. In +-other words, the words `FOO' and `Foo' should be hyphenated exactly the +-same way as the word `foo' is hyphenated, and this is what @code{hcode} +-is good for. Words that contain other letters won't be hyphenated +-properly if the corresponding hyphenation patterns actually do contain +-them. For example, the following @code{hcode} requests are necessary to +-assign hyphenation codes to the letters @samp{} (this is needed +-for German): +- +-@Example +-.hcode +-.hcode +-.hcode +-.hcode +-@endExample +- +-Without those assignments, groff treats German words like +-@w{`Kindergrten'} (the plural form of `kindergarten') as two substrings +-@w{`kinderg'} and @w{`rten'} because the hyphenation code of the +-umlaut@tie{}a is zero by default. There is a German hyphenation pattern +-that covers @w{`kinder'}, so groff finds the hyphenation `kin-der'. +-The other two hyphenation points (`kin-der-gr-ten') are missed. +- +-This request is ignored if it has no parameter. +-@endDefreq +- +-@DefreqList {hym, [@Var{length}]} +-@DefregListEndx {.hym} +-@cindex hyphenation margin (@code{hym}) +-@cindex margin for hyphenation (@code{hym}) +-@cindex @code{ad} request, and hyphenation margin +-Set the (right) hyphenation margin to @var{length}. If the current +-adjustment mode is not @samp{b} or @samp{n}, the line is not hyphenated +-if it is shorter than @var{length}. Without an argument, the +-hyphenation margin is reset to its default value, which is@tie{}0. The +-default scaling indicator for this request is @samp{m}. The hyphenation +-margin is associated with the current environment +-(@pxref{Environments}). +- +-A negative argument resets the hyphenation margin to zero, emitting a +-warning of type @samp{range}. +- +-@cindex hyphenation margin register (@code{.hym}) +-The current hyphenation margin is available in the @code{.hym} read-only +-number register. +-@endDefreq +- +-@DefreqList {hys, [@Var{hyphenation_space}]} +-@DefregListEndx {.hys} +-@cindex hyphenation space (@code{hys}) +-@cindex @code{ad} request, and hyphenation space +-Set the hyphenation space to @var{hyphenation_space}. If the current +-adjustment mode is @samp{b} or @samp{n}, don't hyphenate the line if it +-can be justified by adding no more than @var{hyphenation_space} extra +-space to each word space. Without argument, the hyphenation space is +-set to its default value, which is@tie{}0. The default scaling +-indicator for this request is @samp{m}. The hyphenation space is +-associated with the current environment (@pxref{Environments}). +- +-A negative argument resets the hyphenation space to zero, emitting a +-warning of type @samp{range}. +- +-@cindex hyphenation space register (@code{.hys}) +-The current hyphenation space is available in the @code{.hys} read-only +-number register. +-@endDefreq +- +-@Defreq {shc, [@Var{glyph}]} +-@cindex soft hyphen character, setting (@code{shc}) +-@cindex character, soft hyphen, setting (@code{shc}) +-@cindex glyph, soft hyphen (@code{hy}) +-@cindex soft hyphen glyph (@code{hy}) +-@cindex @code{char} request, and soft hyphen character +-@cindex @code{tr} request, and soft hyphen character +-Set the @dfn{soft hyphen character} to @var{glyph}.@footnote{@dfn{Soft +-hyphen character} is a misnomer since it is an output glyph.} If the +-argument is omitted, the soft hyphen character is set to the default +-glyph @code{\(hy} (this is the start-up value of @code{gtroff} also). +-The soft hyphen character is the glyph that is inserted when a word is +-hyphenated at a line break. If the soft hyphen character does not exist +-in the font of the character immediately preceding a potential break +-point, then the line is not broken at that point. Neither definitions +-(specified with the @code{char} request) nor translations (specified +-with the @code{tr} request) are considered when finding the soft hyphen +-character. +-@endDefreq +- +-@DefreqList {hla, language} +-@DefregListEndx {.hla} +-@cindex @code{hpf} request, and hyphenation language +-@cindex @code{hw} request, and hyphenation language +-@pindex troffrc +-@pindex troffrc-end +-Set the current hyphenation language to the string @var{language}. +-Hyphenation exceptions specified with the @code{hw} request and +-hyphenation patterns specified with the @code{hpf} and @code{hpfa} +-requests are both associated with the current hyphenation language. The +-@code{hla} request is usually invoked by the @file{troffrc} or the +-@file{troffrc-end} files; @file{troffrc} sets the default language to +-@samp{us}. +- +-@cindex hyphenation language register (@code{.hla}) +-The current hyphenation language is available as a string in the +-read-only number register @samp{.hla}. +- +-@Example +-.ds curr_language \n[.hla] +-\*[curr_language] +- @result{} us +-@endExample +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Manipulating Spacing, Tabs and Fields, Manipulating Hyphenation, gtroff Reference +-@section Manipulating Spacing +-@cindex manipulating spacing +-@cindex spacing, manipulating +- +-@Defreq {sp, [@Var{distance}]} +-Space downwards @var{distance}. With no argument it advances +-1@tie{}line. A negative argument causes @code{gtroff} to move up the +-page the specified distance. If the argument is preceded by a @samp{|} +-then @code{gtroff} moves that distance from the top of the page. This +-request causes a line break, and that adds the current line spacing to +-the space you have just specified. The default scaling indicator is +-@samp{v}. +- +-For convenience you may wish to use the following macros to set the +-height of the next line at a given distance from the top or the bottom +-of the page: +- +-@Example +-.de y-from-top-down +-. sp |\\$1-\\n[.v]u +-.. +-. +-.de y-from-bot-up +-. sp |\\n[.p]u-\\$1-\\n[.v]u +-.. +-@endExample +- +-@noindent +-A call to @samp{.y-from-bot-up 10c} means that the bottom of the next +-line will be at 10@dmn{cm} from the paper edge at the bottom. +- +-If a vertical trap is sprung during execution of @code{sp}, the amount +-of vertical space after the trap is discarded. For example, this +- +-@Example +-.de xxx +-.. +-. +-.wh 0 xxx +-. +-.pl 5v +-foo +-.sp 2 +-bar +-.sp 50 +-baz +-@endExample +- +-@noindent +-results in +- +-@Example +-foo +- +- +-bar +- +-baz +-@endExample +- +-@cindex @code{sp} request, and traps +-@cindex discarded space in traps +-@cindex space, discarded, in traps +-@cindex traps, and discarded space +-The amount of discarded space is available in the number register +-@code{.trunc}. +- +-To protect @code{sp} against vertical traps, use the @code{vpt} request: +- +-@Example +-.vpt 0 +-.sp -3 +-.vpt 1 +-@endExample +-@endDefreq +- +-@DefreqList {ls, [@Var{nnn}]} +-@DefregListEndx {.L} +-@cindex double-spacing (@code{ls}) +-Output @w{@var{nnn}@minus{}1} blank lines after each line of text. With +-no argument, @code{gtroff} uses the previous value before the last +-@code{ls} call. +- +-@Example +-.ls 2 \" This causes double-spaced output +-.ls 3 \" This causes triple-spaced output +-.ls \" Again double-spaced +-@endExample +- +-The line spacing is associated with the current environment +-(@pxref{Environments}). +- +-@cindex line spacing register (@code{.L}) +-The read-only number register @code{.L} contains the current line +-spacing setting. +-@endDefreq +- +-@xref{Changing Type Sizes}, for the requests @code{vs} and @code{pvs} as +-alternatives to @code{ls}. +- +-@DefescList {\\x, ', spacing, '} +-@DefregListEndx {.a} +-Sometimes, extra vertical spacing is only needed occasionally, e.g.@: to +-allow space for a tall construct (like an equation). The @code{\x} +-escape does this. The escape is given a numerical argument, usually +-enclosed in quotes (like @samp{\x'3p'}); the default scaling indicator +-is @samp{v}. If this number is positive extra vertical space is +-inserted below the current line. A negative number adds space above. +-If this escape is used multiple times on the same line, the maximum of +-the values is used. +- +-@xref{Escapes}, for details on parameter delimiting characters. +- +-@cindex extra post-vertical line space register (@code{.a}) +-The @code{.a} read-only number register contains the most recent +-(nonnegative) extra vertical line space. +- +-Using @code{\x} can be necessary in combination with the @code{\b} +-escape, as the following example shows. +- +-@Example +-This is a test with the \[rs]b escape. +-.br +-This is a test with the \[rs]b escape. +-.br +-This is a test with \b'xyz'\x'-1m'\x'1m'. +-.br +-This is a test with the \[rs]b escape. +-.br +-This is a test with the \[rs]b escape. +-@endExample +- +-@noindent +-produces +- +-@Example +-This is a test with the \b escape. +-This is a test with the \b escape. +- x +-This is a test with y. +- z +-This is a test with the \b escape. +-This is a test with the \b escape. +-@endExample +-@endDefesc +- +-@DefreqList {ns, } +-@DefreqItemx {rs, } +-@DefregListEndx {.ns} +-@cindex @code{sp} request, and no-space mode +-@cindex no-space mode (@code{ns}) +-@cindex mode, no-space (@code{ns}) +-@cindex blank lines, disabling +-@cindex lines, blank, disabling +-Enable @dfn{no-space mode}. In this mode, spacing (either via @code{sp} +-or via blank lines) is disabled. The @code{bp} request to advance to +-the next page is also disabled, except if it is accompanied by a page +-number (see @ref{Page Control}, for more information). This mode ends +-when actual text is output or the @code{rs} request is encountered, which +-ends no-space mode. The read-only number register @code{.ns} is set +-to@tie{}1 as long as no-space mode is active. +- +-This request is useful for macros that conditionally insert vertical +-space before the text starts (for example, a paragraph macro could +-insert some space except when it is the first paragraph after a section +-header). +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Tabs and Fields, Character Translations, Manipulating Spacing, gtroff Reference +-@section Tabs and Fields +-@cindex tabs, and fields +-@cindex fields, and tabs +- +-@cindex @acronym{EBCDIC} encoding of a tab +-A tab character (@acronym{ASCII} char@tie{}9, @acronym{EBCDIC} +-char@tie{}5) causes a horizontal movement to the next tab stop (much +-like it did on a typewriter). +- +-@Defesc {\\t, , , } +-@cindex tab character, non-interpreted (@code{\t}) +-@cindex character, tab, non-interpreted (@code{\t}) +-@cindex @code{\t}, and copy-in mode +-@cindex copy-in mode, and @code{\t} +-@cindex mode, copy-in, and @code{\t} +-This escape is a non-interpreted tab character. In copy mode +-(@pxref{Copy-in Mode}), @code{\t} is the same as a real tab character. +-@endDefesc +- +-@DefreqList {ta, [@Var{n1} @Var{n2} @dots{} @Var{nn} @t{T} @Var{r1} @Var{r2} @dots{} @Var{rn}]} +-@DefregListEndx {.tabs} +-Change tab stop positions. This request takes a series of tab +-specifiers as arguments (optionally divided into two groups with the +-letter @samp{T}) that indicate where each tab stop is to be (overriding +-any previous settings). +- +-Tab stops can be specified absolutely, i.e., as the distance from the +-left margin. For example, the following sets 6@tie{}tab stops every one +-inch. +- +-@Example +-.ta 1i 2i 3i 4i 5i 6i +-@endExample +- +-Tab stops can also be specified using a leading @samp{+}, which means +-that the specified tab stop is set relative to the previous tab stop. +-For example, the following is equivalent to the previous example. +- +-@Example +-.ta 1i +1i +1i +1i +1i +1i +-@endExample +- +-@code{gtroff} supports an extended syntax to specify repeat values after +-the @samp{T} mark (these values are always taken as relative) -- this is +-the usual way to specify tabs set at equal intervals. The following is, +-yet again, the same as the previous examples. It does even more since +-it defines an infinite number of tab stops separated by one inch. +- +-@Example +-.ta T 1i +-@endExample +- +-Now we are ready to interpret the full syntax given at the beginning: +-Set tabs at positions @var{n1}, @var{n2}, @dots{}, @var{nn} and then set +-tabs at @var{nn}+@var{r1}, @var{nn}+@var{r2}, @dots{}, @var{nn}+@var{rn} +-and then at @var{nn}+@var{rn}+@var{r1}, @var{nn}+@var{rn}+@var{r2}, +-@dots{}, @var{nn}+@var{rn}+@var{rn}, and so on. +- +-Example: @samp{4c +6c T 3c 5c 2c} is equivalent to @samp{4c 10c 13c 18c +-20c 23c 28c 30c @dots{}}. +- +-The material in each tab column (i.e., the column between two tab stops) +-may be justified to the right or left or centered in the column. This +-is specified by appending @samp{R}, @samp{L}, or @samp{C} to the tab +-specifier. The default justification is @samp{L}. Example: +- +-@Example +-.ta 1i 2iC 3iR +-@endExample +- +-Some notes: +- +-@itemize @bullet +-@item +-The default unit of the @code{ta} request is @samp{m}. +- +-@item +-A tab stop is converted into a non-breakable horizontal movement that +-can be neither stretched nor squeezed. For example, +- +-@Example +-.ds foo a\tb\tc +-.ta T 5i +-\*[foo] +-@endExample +- +-@noindent +-creates a single line, which is a bit longer than 10@tie{}inches (a +-string is used to show exactly where the tab characters are). Now +-consider the following: +- +-@Example +-.ds bar a\tb b\tc +-.ta T 5i +-\*[bar] +-@endExample +- +-@noindent +-@code{gtroff} first converts the tab stops of the line into unbreakable +-horizontal movements, then splits the line after the second @samp{b} +-(assuming a sufficiently short line length). Usually, this isn't what +-the user wants. +- +-@item +-Superfluous tabs (i.e., tab characters that do not correspond to a tab +-stop) are ignored except the first one, which delimits the characters +-belonging to the last tab stop for right-justifying or centering. +-Consider the following example +- +-@Example +-.ds Z foo\tbar\tfoo +-.ds ZZ foo\tbar\tfoobar +-.ds ZZZ foo\tbar\tfoo\tbar +-.ta 2i 4iR +-\*[Z] +-.br +-\*[ZZ] +-.br +-\*[ZZZ] +-.br +-@endExample +- +-@noindent +-which produces the following output: +- +-@Example +-foo bar foo +-foo bar foobar +-foo bar foobar +-@endExample +- +-@noindent +-The first line right-justifies the second `foo' relative to the tab +-stop. The second line right-justifies `foobar'. The third line finally +-right-justifies only `foo' because of the additional tab character, which +-marks the end of the string belonging to the last defined tab stop. +- +-@item +-Tab stops are associated with the current environment +-(@pxref{Environments}). +- +-@item +-Calling @code{ta} without an argument removes all tab stops. +- +-@item +-@cindex tab stops, for TTY output devices +-The start-up value of @code{gtroff} is @w{@samp{T 0.8i}}. +-@end itemize +- +-@cindex tab settings register (@code{.tabs}) +-The read-only number register @code{.tabs} contains a string +-representation of the current tab settings suitable for use as an +-argument to the @code{ta} request. +- +-@Example +-.ds tab-string \n[.tabs] +-\*[tab-string] +- @result{} T120u +-@endExample +- +-@cindex @code{.S} register, Plan@tie{}9 alias for @code{.tabs} +-@cindex @code{.tabs} register, Plan@tie{}9 alias (@code{.S}) +-The @code{troff} version of the Plan@tie{}9 operating system uses +-register @code{.S} for the same purpose. +-@endDefreq +- +-@Defreq {tc, [@Var{fill-glyph}]} +-@cindex tab repetition character (@code{tc}) +-@cindex character, tab repetition (@code{tc}) +-@cindex glyph, tab repetition (@code{tc}) +-Normally @code{gtroff} fills the space to the next tab stop with +-whitespace. This can be changed with the @code{tc} request. With no +-argument @code{gtroff} reverts to using whitespace, which is the +-default. The value of this @dfn{tab repetition character} is associated +-with the current environment (@pxref{Environments}).@footnote{@dfn{Tab +-repetition character} is a misnomer since it is an output glyph.} +-@endDefreq +- +-@DefreqList {linetabs, n} +-@DefregListEndx {.linetabs} +-@cindex tab, line-tabs mode +-@cindex line-tabs mode +-@cindex mode, line-tabs +-If @var{n} is missing or not zero, enable @dfn{line-tabs} mode, or +-disable it otherwise (the default). In line-tabs mode, @code{gtroff} +-computes tab distances relative to the (current) output line instead of +-the input line. +- +-For example, the following code: +- +-@Example +-.ds x a\t\c +-.ds y b\t\c +-.ds z c +-.ta 1i 3i +-\*x +-\*y +-\*z +-@endExample +- +-@noindent +-in normal mode, results in the output +- +-@Example +-a b c +-@endExample +- +-@noindent +-in line-tabs mode, the same code outputs +- +-@Example +-a b c +-@endExample +- +-Line-tabs mode is associated with the current environment. The +-read-only register @code{.linetabs} is set to@tie{}1 if in line-tabs +-mode, and 0 in normal mode. +-@endDefreq +- +-@menu +-* Leaders:: +-* Fields:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Leaders, Fields, Tabs and Fields, Tabs and Fields +-@subsection Leaders +-@cindex leaders +- +-Sometimes it may may be desirable to use the @code{tc} request to fill a +-particular tab stop with a given glyph (for example dots in a table of +-contents), but also normal tab stops on the rest of the line. For this +-@code{gtroff} provides an alternate tab mechanism, called @dfn{leaders}, +-which does just that. +- +-@cindex leader character +-A leader character (character code@tie{}1) behaves similarly to a tab +-character: It moves to the next tab stop. The only difference is that +-for this movement, the fill glyph defaults to a period character and not +-to space. +- +-@Defesc {\\a, , , } +-@cindex leader character, non-interpreted (@code{\a}) +-@cindex character, leader, non-interpreted (@code{\a}) +-@cindex @code{\a}, and copy-in mode +-@cindex copy-in mode, and @code{\a} +-@cindex mode, copy-in, and @code{\a} +-This escape is a non-interpreted leader character. In copy mode +-(@pxref{Copy-in Mode}), @code{\a} is the same as a real leader +-character. +-@endDefesc +- +-@Defreq {lc, [@Var{fill-glyph}]} +-@cindex leader repetition character (@code{lc}) +-@cindex character, leader repetition (@code{lc}) +-@cindex glyph, leader repetition (@code{lc}) +-Declare the @dfn{leader repetition character}.@footnote{@dfn{Leader +-repetition character} is a misnomer since it is an output glyph.} +-Without an argument, leaders act the same as tabs (i.e., using +-whitespace for filling). @code{gtroff}'s start-up value is a dot +-(@samp{.}). The value of the leader repetition character is associated +-with the current environment (@pxref{Environments}). +-@endDefreq +- +-@cindex table of contents +-@cindex contents, table of +-For a table of contents, to name an example, tab stops may be defined so +-that the section number is one tab stop, the title is the second with +-the remaining space being filled with a line of dots, and then the page +-number slightly separated from the dots. +- +-@Example +-.ds entry 1.1\tFoo\a\t12 +-.lc . +-.ta 1i 5i +.25i +-\*[entry] +-@endExample +- +-@noindent +-This produces +- +-@Example +-1.1 Foo.......................................... 12 +-@endExample +- +-@c --------------------------------------------------------------------- +- +-@node Fields, , Leaders, Tabs and Fields +-@subsection Fields +-@cindex fields +- +-@cindex field delimiting character (@code{fc}) +-@cindex delimiting character, for fields (@code{fc}) +-@cindex character, field delimiting (@code{fc}) +-@cindex field padding character (@code{fc}) +-@cindex padding character, for fields (@code{fc}) +-@cindex character, field padding (@code{fc}) +-@dfn{Fields} are a more general way of laying out tabular data. A field +-is defined as the data between a pair of @dfn{delimiting characters}. +-It contains substrings that are separated by @dfn{padding characters}. +-The width of a field is the distance on the @emph{input} line from the +-position where the field starts to the next tab stop. A padding +-character inserts stretchable space similar to @TeX{}'s @code{\hss} +-command (thus it can even be negative) to make the sum of all substring +-lengths plus the stretchable space equal to the field width. If more +-than one padding character is inserted, the available space is evenly +-distributed among them. +- +-@Defreq {fc, [@Var{delim-char} [@Var{padding-char}]]} +-Define a delimiting and a padding character for fields. If the latter +-is missing, the padding character defaults to a space character. If +-there is no argument at all, the field mechanism is disabled (which is +-the default). Note that contrary to e.g.@: the tab repetition +-character, delimiting and padding characters are @emph{not} associated +-to the current environment (@pxref{Environments}). +- +-Example: +- +-@Example +-.fc # ^ +-.ta T 3i +-#foo^bar^smurf# +-.br +-#foo^^bar^smurf# +-@endExample +- +-@noindent +-and here the result: +- +-@Example +-foo bar smurf +-foo bar smurf +-@endExample +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Character Translations, Troff and Nroff Mode, Tabs and Fields, gtroff Reference +-@section Character Translations +-@cindex character translations +-@cindex translations of characters +- +-@cindex control character, changing (@code{cc}) +-@cindex character, control, changing (@code{cc}) +-@cindex no-break control character, changing (@code{c2}) +-@cindex character, no-break control, changing (@code{c2}) +-@cindex control character, no-break, changing (@code{c2}) +-The control character (@samp{.}) and the no-break control character +-(@samp{'}) can be changed with the @code{cc} and @code{c2} requests, +-respectively. +- +-@Defreq {cc, [@Var{c}]} +-Set the control character to@tie{}@var{c}. With no argument the default +-control character @samp{.} is restored. The value of the control +-character is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@Defreq {c2, [@Var{c}]} +-Set the no-break control character to@tie{}@var{c}. With no argument +-the default control character @samp{'} is restored. The value of the +-no-break control character is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@xref{Requests}. +- +-@Defreq {eo, } +-@cindex disabling @code{\} (@code{eo}) +-@cindex @code{\}, disabling (@code{eo}) +-Disable the escape mechanism completely. After executing this request, +-the backslash character @samp{\} no longer starts an escape sequence. +- +-This request can be very helpful in writing macros since it is not +-necessary then to double the escape character. Here an example: +- +-@Example +-.\" This is a simplified version of the +-.\" .BR request from the man macro package +-.eo +-.de BR +-. ds result \& +-. while (\n[.$] >= 2) \@{\ +-. as result \fB\$1\fR\$2 +-. shift 2 +-. \@} +-. if \n[.$] .as result \fB\$1 +-\*[result] +-. ft R +-.. +-.ec +-@endExample +-@endDefreq +- +-@Defreq {ec, [@Var{c}]} +-@cindex escape character, changing (@code{ec}) +-@cindex character, escape, changing (@code{ec}) +-Set the escape character to@tie{}@var{c}. With no argument the default +-escape character @samp{\} is restored. It can be also used to re-enable +-the escape mechanism after an @code{eo} request. +- +-Note that changing the escape character globally likely breaks macro +-packages since @code{gtroff} has no mechanism to `intern' macros, i.e., +-to convert a macro definition into an internal form that is independent +-of its representation (@TeX{} has this mechanism). If a macro is +-called, it is executed literally. +-@endDefreq +- +-@DefreqList {ecs, } +-@DefreqListEndx {ecr, } +-The @code{ecs} request saves the current escape character in an internal +-register. Use this request in combination with the @code{ec} request to +-temporarily change the escape character. +- +-The @code{ecr} request restores the escape character saved with +-@code{ecs}. Without a previous call to @code{ecs}, this request sets +-the escape character to @code{\}. +-@endDefreq +- +-@DefescList {\\\\, , , } +-@DefescItemx {\\e, , , } +-@DefescListEndx {\\E, , , } +-Print the current escape character (which is the backslash character +-@samp{\} by default). +- +-@code{\\} is a `delayed' backslash; more precisely, it is the default +-escape character followed by a backslash, which no longer has special +-meaning due to the leading escape character. It is @emph{not} an escape +-sequence in the usual sense! In any unknown escape sequence +-@code{\@var{X}} the escape character is ignored and @var{X} is printed. +-But if @var{X} is equal to the current escape character, no warning is +-emitted. +- +-@cindex @code{\E}, and copy-in mode +-@cindex copy-in mode, and @code{\E} +-@cindex mode, copy-in, and @code{\E} +-As a consequence, only at top-level or in a diversion a backslash glyph +-is printed; in copy-in mode, it expands to a single backslash, which then +-combines with the following character to an escape sequence. +- +-The @code{\E} escape differs from @code{\e} by printing an escape +-character that is not interpreted in copy mode. Use this to define +-strings with escapes that work when used in copy mode (for example, as a +-macro argument). The following example defines strings to begin and end +-a superscript: +- +-@Example +-.ds @{ \v'-.3m'\s'\En[.s]*60/100' +-.ds @} \s0\v'.3m' +-@endExample +- +-Another example to demonstrate the differences between the various +-escape sequences, using a strange escape character, @samp{-}. +- +-@Example +-.ec - +-.de xxx +---A'123' +-.. +-.xxx +- @result{} -A'foo' +-@endExample +- +-@noindent +-The result is surprising for most users, expecting @samp{1} since +-@samp{foo} is a valid identifier. What has happened? As mentioned +-above, the leading escape character makes the following character +-ordinary. Written with the default escape character the sequence +-@samp{--} becomes @samp{\-} -- this is the minus sign. +- +-If the escape character followed by itself is a valid escape sequence, +-only @code{\E} yields the expected result: +- +-@Example +-.ec - +-.de xxx +--EA'123' +-.. +-.xxx +- @result{} 1 +-@endExample +-@endDefesc +- +-@Defesc {\\., , , } +-Similar to @code{\\}, the sequence @code{\.} isn't a real escape +-sequence. As before, a warning message is suppressed if the escape +-character is followed by a dot, and the dot itself is printed. +- +-@Example +-.de foo +-. nop foo +-. +-. de bar +-. nop bar +-\\.. +-. +-.. +-.foo +-.bar +- @result{} foo bar +-@endExample +- +-@noindent +-The first backslash is consumed while the macro is read, and the second +-is swallowed while executing macro @code{foo}. +-@endDefesc +- +-A @dfn{translation} is a mapping of an input character to an output +-glyph. The mapping occurs at output time, i.e., the input character +-gets assigned the metric information of the mapped output character +-right before input tokens are converted to nodes (@pxref{Gtroff +-Internals}, for more on this process). +- +-@DefreqList {tr, @Var{a}@Var{b}@Var{c}@Var{d}@dots{}} +-@DefreqListEndx {trin, @Var{a}@Var{b}@Var{c}@Var{d}@dots{}} +-Translate character @var{a} to glyph@tie{}@var{b}, character @var{c} to +-glyph@tie{}@var{d}, etc. If there is an odd number of arguments, the +-last one is translated to an unstretchable space (@w{@samp{\ }}). +- +-The @code{trin} request is identical to @code{tr}, but when you unformat +-a diversion with @code{asciify} it ignores the translation. +-@xref{Diversions}, for details about the @code{asciify} request. +- +-Some notes: +- +-@itemize @bullet +-@item +-@cindex @code{\(}, and translations +-@cindex @code{\[}, and translations +-@cindex @code{\'}, and translations +-@cindex @code{\`}, and translations +-@cindex @code{\-}, and translations +-@cindex @code{\_}, and translations +-@cindex @code{\C}, and translations +-@cindex @code{\N}, and translations +-@cindex @code{char} request, and translations +-@cindex special characters +-@cindex character, special +-@cindex numbered glyph (@code{\N}) +-@cindex glyph, numbered (@code{\N}) +-Special characters (@code{\(@var{xx}}, @code{\[@var{xxx}]}, +-@code{\C'@var{xxx}'}, @code{\'}, @code{\`}, @code{\-}, @code{\_}), +-glyphs defined with the @code{char} request, and numbered glyphs +-(@code{\N'@var{xxx}'}) can be translated also. +- +-@item +-@cindex @code{\e}, and translations +-The @code{\e} escape can be translated also. +- +-@item +-@cindex @code{\%}, and translations +-@cindex @code{\~}, and translations +-Characters can be mapped onto the @code{\%} and @code{\~} escapes (but +-@code{\%} and @code{\~} can't be mapped onto another glyph). +- +-@item +-@cindex backspace character, and translations +-@cindex character, backspace, and translations +-@cindex leader character, and translations +-@cindex character, leader, and translations +-@cindex newline character, and translations +-@cindex character, newline, and translations +-@cindex tab character, and translations +-@cindex character, tab, and translations +-@cindex @code{\a}, and translations +-@cindex @code{\t}, and translations +-The following characters can't be translated: space (with one exception, +-see below), backspace, newline, leader (and @code{\a}), tab (and +-@code{\t}). +- +-@item +-@cindex @code{shc} request, and translations +-Translations are not considered for finding the soft hyphen character +-set with the @code{shc} request. +- +-@item +-@cindex @code{\&}, and translations +-The pair @samp{@var{c}\&} (this is an arbitrary character@tie{}@var{c} +-followed by the zero width space character) maps this character to +-nothing. +- +-@Example +-.tr a\& +-foo bar +- @result{} foo br +-@endExample +- +-@noindent +-It is even possible to map the space character to nothing: +- +-@Example +-.tr aa \& +-foo bar +- @result{} foobar +-@endExample +- +-@noindent +-As shown in the example, the space character can't be the first +-character/glyph pair as an argument of @code{tr}. Additionally, it is +-not possible to map the space character to any other glyph; requests +-like @w{@samp{.tr aa x}} undo @w{@samp{.tr aa \&}} instead. +- +-If justification is active, lines are justified in spite of the `empty' +-space character (but there is no minimal distance, i.e.@: the space +-character, between words). +- +-@item +-After an output glyph has been constructed (this happens at the moment +-immediately before the glyph is appended to an output glyph list, either +-by direct output, in a macro, diversion, or string), it is no longer +-affected by @code{tr}. +- +-@item +-Translating character to glyphs where one of them or both are undefined +-is possible also; @code{tr} does not check whether the entities in its +-argument do exist. +- +-@xref{Gtroff Internals}. +- +-@item +-@code{troff} no longer has a hard-coded dependency on @w{Latin-1}; all +-@code{char@var{XXX}} entities have been removed from the font +-description files. This has a notable consequence that shows up in +-warnings like @code{can't find character with input code @var{XXX}} if +-the @code{tr} request isn't handled properly. +- +-Consider the following translation: +- +-@Example +-.tr +-@endExample +- +-@noindent +-This maps input character @code{} onto glyph @code{}, which is +-identical to glyph @code{char201}. But this glyph intentionally doesn't +-exist! Instead, @code{\[char201]} is treated as an input character +-entity and is by default mapped onto @code{\['E]}, and @code{gtroff} +-doesn't handle translations of translations. +- +-The right way to write the above translation is +- +-@Example +-.tr \['E] +-@endExample +- +-@noindent +-In other words, the first argument of @code{tr} should be an input +-character or entity, and the second one a glyph entity. +- +-@item +-Without an argument, the @code{tr} request is ignored. +-@end itemize +-@endDefreq +- +-@Defreq {trnt, @Var{a}@Var{b}@Var{c}@Var{d}@dots{}} +-@cindex @code{\!}, and @code{trnt} +-@code{trnt} is the same as the @code{tr} request except that the +-translations do not apply to text that is transparently throughput into +-a diversion with @code{\!}. @xref{Diversions}, for more information. +- +-For example, +- +-@Example +-.tr ab +-.di x +-\!.tm a +-.di +-.x +-@endExample +- +-@noindent +-prints @samp{b} to the standard error stream; if @code{trnt} is used +-instead of @code{tr} it prints @samp{a}. +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Troff and Nroff Mode, Line Layout, Character Translations, gtroff Reference +-@section Troff and Nroff Mode +-@cindex troff mode +-@cindex mode, troff +-@cindex nroff mode +-@cindex mode, nroff +- +-Originally, @code{nroff} and @code{troff} were two separate programs, +-the former for TTY output, the latter for everything else. With GNU +-@code{troff}, both programs are merged into one executable, sending its +-output to a device driver (@code{grotty} for TTY devices, @code{grops} +-for @sc{PostScript}, etc.)@: which interprets the intermediate output of +-@code{gtroff}. For @acronym{UNIX} @code{troff} it makes sense to talk +-about @dfn{Nroff mode} and @dfn{Troff mode} since the differences are +-hardcoded. For GNU @code{troff}, this distinction is not appropriate +-because @code{gtroff} simply takes the information given in the font +-files for a particular device without handling requests specially if a +-TTY output device is used. +- +-Usually, a macro package can be used with all output devices. +-Nevertheless, it is sometimes necessary to make a distinction between +-TTY and non-TTY devices: @code{gtroff} provides two built-in conditions +-@samp{n} and @samp{t} for the @code{if}, @code{ie}, and @code{while} +-requests to decide whether @code{gtroff} shall behave like @code{nroff} +-or like @code{troff}. +- +-@Defreq {troff, } +-@pindex troffrc +-@pindex troffrc-end +-Make the @samp{t} built-in condition true (and the @samp{n} built-in +-condition false) for @code{if}, @code{ie}, and @code{while} conditional +-requests. This is the default if @code{gtroff} (@emph{not} +-@code{groff}) is started with the @option{-R} switch to avoid loading of +-the start-up files @file{troffrc} and @file{troffrc-end}. Without +-@option{-R}, @code{gtroff} stays in troff mode if the output device is +-not a TTY (e.g.@: `ps'). +-@endDefreq +- +-@Defreq {nroff, } +-@pindex tty.tmac +-Make the @samp{n} built-in condition true (and the @samp{t} built-in +-condition false) for @code{if}, @code{ie}, and @code{while} conditional +-requests. This is the default if @code{gtroff} uses a TTY output +-device; the code for switching to nroff mode is in the file +-@file{tty.tmac}, which is loaded by the start-up file @code{troffrc}. +-@endDefreq +- +-@xref{Conditionals and Loops}, for more details on built-in conditions. +- +- +-@c ===================================================================== +- +-@node Line Layout, Line Control, Troff and Nroff Mode, gtroff Reference +-@section Line Layout +-@cindex line layout +-@cindex layout, line +- +-@cindex dimensions, line +-@cindex line dimensions +-The following drawing shows the dimensions that @code{gtroff} uses for +-placing a line of output onto the page. They are labeled with the +-request that manipulates each dimension. +- +-@Example +- -->| in |<-- +- |<-----------ll------------>| +- +----+----+----------------------+----+ +- | : : : | +- +----+----+----------------------+----+ +--->| po |<-- +- |<--------paper width---------------->| +-@endExample +- +-@noindent +-These dimensions are: +- +-@ftable @code +-@item po +-@cindex left margin (@code{po}) +-@cindex margin, left (@code{po}) +-@cindex page offset (@code{po}) +-@cindex offset, page (@code{po}) +-@dfn{Page offset} -- this is the leftmost position of text on the final +-output, defining the @dfn{left margin}. +- +-@item in +-@cindex indentation (@code{in}) +-@cindex line indentation (@code{in}) +-@dfn{Indentation} -- this is the distance from the left margin where +-text is printed. +- +-@item ll +-@cindex line length (@code{ll}) +-@cindex length of line (@code{ll}) +-@dfn{Line length} -- this is the distance from the left margin to right +-margin. +-@end ftable +- +-A simple demonstration: +- +-@Example +-.ll 3i +-This is text without indentation. +-The line length has been set to 3\~inch. +-.in +.5i +-.ll -.5i +-Now the left and right margins are both increased. +-.in +-.ll +-Calling .in and .ll without parameters restore +-the previous values. +-@endExample +- +-Result: +- +-@Example +-This is text without indenta- +-tion. The line length has +-been set to 3 inch. +- Now the left and +- right margins are +- both increased. +-Calling .in and .ll without +-parameters restore the previ- +-ous values. +-@endExample +- +-@DefreqList {po, [@Var{offset}]} +-@DefreqItem {po, @t{+}@Var{offset}} +-@DefreqItem {po, @t{-}@Var{offset}} +-@DefregListEndx {.o} +-@pindex troffrc +-Set horizontal page offset to @var{offset} (or increment or decrement +-the current value by @var{offset}). Note that this request does not +-cause a break, so changing the page offset in the middle of text being +-filled may not yield the expected result. The initial value is +-1@dmn{i}. For TTY output devices, it is set to 0 in the startup file +-@file{troffrc}; the default scaling indicator is @samp{m} (and not +-@samp{v} as incorrectly documented in the original @acronym{UNIX} troff +-manual). +- +-The current page offset can be found in the read-only number register +-@samp{.o}. +- +-If @code{po} is called without an argument, the page offset is reset to +-the previous value before the last call to @code{po}. +- +-@Example +-.po 3i +-\n[.o] +- @result{} 720 +-.po -1i +-\n[.o] +- @result{} 480 +-.po +-\n[.o] +- @result{} 720 +-@endExample +-@endDefreq +- +-@DefreqList {in, [@Var{indent}]} +-@DefreqItem {in, @t{+}@Var{indent}} +-@DefreqItem {in, @t{-}@Var{indent}} +-@DefregListEndx {.i} +-Set indentation to @var{indent} (or increment or decrement the current +-value by @var{indent}). This request causes a break. Initially, there +-is no indentation. +- +-If @code{in} is called without an argument, the indentation is reset to +-the previous value before the last call to @code{in}. The default +-scaling indicator is @samp{m}. +- +-The indentation is associated with the current environment +-(@pxref{Environments}). +- +-If a negative indentation value is specified (which is not allowed), +-@code{gtroff} emits a warning of type @samp{range} and sets the +-indentation to zero. +- +-The effect of @code{in} is delayed until a partially collected line (if +-it exists) is output. A temporary indentation value is reset to zero +-also. +- +-The current indentation (as set by @code{in}) can be found in the +-read-only number register @samp{.i}. +-@endDefreq +- +-@DefreqList {ti, offset} +-@DefreqItem {ti, @t{+}@Var{offset}} +-@DefreqItem {ti, @t{-}@Var{offset}} +-@DefregListEndx {.in} +-Temporarily indent the next output line by @var{offset}. If an +-increment or decrement value is specified, adjust the temporary +-indentation relative to the value set by the @code{in} request. +- +-This request causes a break; its value is associated with the current +-environment (@pxref{Environments}). The default scaling indicator is +-@samp{m}. A call of @code{ti} without an argument is ignored. +- +-If the total indentation value is negative (which is not allowed), +-@code{gtroff} emits a warning of type @samp{range} and sets the +-temporary indentation to zero. `Total indentation' is either +-@var{offset} if specified as an absolute value, or the temporary plus +-normal indentation, if @var{offset} is given as a relative value. +- +-The effect of @code{ti} is delayed until a partially collected line (if +-it exists) is output. +- +-The read-only number register @code{.in} is the indentation that applies +-to the current output line. +- +-The difference between @code{.i} and @code{.in} is that the latter takes +-into account whether a partially collected line still uses the old +-indentation value or a temporary indentation value is active. +-@endDefreq +- +-@DefreqList {ll, [@Var{length}]} +-@DefreqItem {ll, @t{+}@Var{length}} +-@DefreqItem {ll, @t{-}@Var{length}} +-@DefregItemx {.l} +-@DefregListEndx {.ll} +-Set the line length to @var{length} (or increment or decrement the +-current value by @var{length}). Initially, the line length is set to +-6.5@dmn{i}. The effect of @code{ll} is delayed until a partially +-collected line (if it exists) is output. The default scaling indicator +-is @samp{m}. +- +-If @code{ll} is called without an argument, the line length is reset to +-the previous value before the last call to @code{ll}. If a negative +-line length is specified (which is not allowed), @code{gtroff} emits a +-warning of type @samp{range} and sets the line length to zero. +- +-The line length is associated with the current environment +-(@pxref{Environments}). +- +-@cindex line length register (@code{.l}) +-The current line length (as set by @code{ll}) can be found in the +-read-only number register @samp{.l}. The read-only number register +-@code{.ll} is the line length that applies to the current output line. +- +-Similar to @code{.i} and @code{.in}, the difference between @code{.l} +-and @code{.ll} is that the latter takes into account whether a partially +-collected line still uses the old line length value. +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Line Control, Page Layout, Line Layout, gtroff Reference +-@section Line Control +-@cindex line control +-@cindex control, line +- +-It is important to understand how @code{gtroff} handles input and output +-lines. +- +-Many escapes use positioning relative to the input line. For example, +-this +- +-@Example +-This is a \h'|1.2i'test. +- +-This is a +-\h'|1.2i'test. +-@endExample +- +-@noindent +-produces +- +-@Example +-This is a test. +- +-This is a test. +-@endExample +- +-The main usage of this feature is to define macros that act exactly at +-the place where called. +- +-@Example +-.\" A simple macro to underline a word +-.de underline +-. nop \\$1\l'|0\[ul]' +-.. +-@endExample +- +-@noindent +-In the above example, @samp{|0} specifies a negative distance from the +-current position (at the end of the just emitted argument @code{\$1}) +-back to the beginning of the input line. Thus, the @samp{\l} escape +-draws a line from right to left. +- +-@cindex input line continuation (@code{\}) +-@cindex line, input, continuation (@code{\}) +-@cindex continuation, input line (@code{\}) +-@cindex output line, continuation (@code{\c}) +-@cindex line, output, continuation (@code{\c}) +-@cindex continuation, output line (@code{\c}) +-@cindex interrupted line +-@cindex line, interrupted +-@code{gtroff} makes a difference between input and output line +-continuation; the latter is also called @dfn{interrupting} a line. +- +-@DefescList {\\@key{RET}, , ,} +-@DefescItemx {\\c, , ,} +-@DefregListEndx {.int} +-Continue a line. @code{\@key{RET}} (this is a backslash at the end of a +-line immediately followed by a newline) works on the input level, +-suppressing the effects of the following newline in the input. +- +-@Example +-This is a \ +-.test +- @result{} This is a .test +-@endExample +- +-The @samp{|} operator is also affected. +- +-@cindex @code{\R}, after @code{\c} +-@code{\c} works on the output level. Anything after this escape on the +-same line is ignored except @code{\R}, which works as usual. Anything +-before @code{\c} on the same line is appended to the current partial +-output line. The next non-command line after an interrupted line counts +-as a new input line. +- +-The visual results depend on whether no-fill mode is active. +- +-@itemize @bullet +-@item +-@cindex @code{\c}, and no-fill mode +-@cindex no-fill mode, and @code{\c} +-@cindex mode, no-fill, and @code{\c} +-If no-fill mode is active (using the @code{nf} request), the next input +-text line after @code{\c} is handled as a continuation of the same input +-text line. +- +-@Example +-.nf +-This is a \c +-test. +- @result{} This is a test. +-@endExample +- +-@item +-@cindex @code{\c}, and fill mode +-@cindex fill mode, and @code{\c} +-@cindex mode, fill, and @code{\c} +-If fill mode is active (using the @code{fi} request), a word interrupted +-with @code{\c} is continued with the text on the next input text line, +-without an intervening space. +- +-@Example +-This is a te\c +-st. +- @result{} This is a test. +-@endExample +-@end itemize +- +-Note that an intervening control line that causes a break is stronger +-than @code{\c}, flushing out the current partial line in the usual way. +- +-@cindex interrupted line register (@code{.int}) +-The @code{.int} register contains a positive value if the last output +-line was interrupted with @code{\c}; this is associated with the current +-environment (@pxref{Environments}). +-@endDefesc +- +- +-@c ===================================================================== +- +-@node Page Layout, Page Control, Line Control, gtroff Reference +-@section Page Layout +-@cindex page layout +-@cindex layout, page +- +-@code{gtroff} provides some very primitive operations for controlling +-page layout. +- +-@DefreqList {pl, [@Var{length}]} +-@DefreqItem {pl, @t{+}@Var{length}} +-@DefreqItem {pl, @t{-}@Var{length}} +-@DefregListEndx {.p} +-@cindex page length (@code{pl}) +-@cindex length of page (@code{pl}) +-Set the @dfn{page length} to @var{length} (or increment or decrement the +-current value by @var{length}). This is the length of the physical +-output page. The default scaling indicator is @samp{v}. +- +-@cindex page length register (@code{.p}) +-The current setting can be found in the read-only number register +-@samp{.p}. +- +-@cindex top margin +-@cindex margin, top +-@cindex bottom margin +-@cindex margin, bottom +-Note that this only specifies the size of the page, not the top and +-bottom margins. Those are not set by @code{gtroff} directly. +-@xref{Traps}, for further information on how to do this. +- +-Negative @code{pl} values are possible also, but not very useful: No +-trap is sprung, and each line is output on a single page (thus +-suppressing all vertical spacing). +- +-If no argument or an invalid argument is given, @code{pl} sets the page +-length to 11@dmn{i}. +-@endDefreq +- +-@cindex headers +-@cindex footers +-@cindex titles +-@code{gtroff} provides several operations that help in setting up top +-and bottom titles (or headers and footers). +- +-@Defreq {tl, @t{'}@Var{left}@t{'}@Var{center}@t{'}@Var{right}@t{'}} +-@cindex title line (@code{tl}) +-@cindex three-part title (@code{tl}) +-@cindex page number character (@code{%}) +-Print a @dfn{title line}. It consists of three parts: a left justified +-portion, a centered portion, and a right justified portion. The +-argument separator @samp{'} can be replaced with any character not +-occurring in the title line. The @samp{%} character is replaced with +-the current page number. This character can be changed with the +-@code{pc} request (see below). +- +-Without argument, @code{tl} is ignored. +- +-Some notes: +- +-@itemize @bullet +-@item +-The line length set by the @code{ll} request is not honoured by +-@code{tl}; use the @code{lt} request (described below) instead, to +-control line length for text set by @code{tl}. +- +-@item +-A title line is not restricted to the top or bottom of a page. +- +-@item +-@code{tl} prints the title line immediately, ignoring a partially filled +-line (which stays untouched). +- +-@item +-It is not an error to omit closing delimiters. For example, +-@w{@samp{.tl /foo}} is equivalent to @w{@samp{.tl /foo///}}: It prints a +-title line with the left justified word @samp{foo}; the centered and +-right justfied parts are empty. +- +-@item +-@code{tl} accepts the same parameter delimiting characters as the +-@code{\A} escape; see @ref{Escapes}. +-@end itemize +-@endDefreq +- +-@DefreqList {lt, [@Var{length}]} +-@DefreqItem {lt, @t{+}@Var{length}} +-@DefreqItem {lt, @t{-}@Var{length}} +-@DefregListEndx {.lt} +-@cindex length of title line (@code{lt}) +-@cindex title line, length (@code{lt}) +-@cindex title line length register (@code{.lt}) +-The title line is printed using its own line length, which is specified +-(or incremented or decremented) with the @code{lt} request. Initially, +-the title line length is set to 6.5@dmn{i}. If a negative line length +-is specified (which is not allowed), @code{gtroff} emits a warning of +-type @samp{range} and sets the title line length to zero. The default +-scaling indicator is @samp{m}. If @code{lt} is called without an +-argument, the title length is reset to the previous value before the +-last call to @code{lt}. +- +-The current setting of this is available in the @code{.lt} read-only +-number register; it is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@DefreqList {pn, page} +-@DefreqItem {pn, @t{+}@Var{page}} +-@DefreqItem {pn, @t{-}@Var{page}} +-@DefregListEndx {.pn} +-@cindex page number (@code{pn}) +-@cindex number, page (@code{pn}) +-Change (increase or decrease) the page number of the @emph{next} page. +-The only argument is the page number; the request is ignored without a +-parameter. +- +-The read-only number register @code{.pn} contains the number of the next +-page: either the value set by a @code{pn} request, or the number of the +-current page plus@tie{}1. +-@endDefreq +- +-@Defreq {pc, [@Var{char}]} +-@cindex changing the page number character (@code{pc}) +-@cindex page number character, changing (@code{pc}) +-@vindex % +-Change the page number character (used by the @code{tl} request) to a +-different character. With no argument, this mechanism is disabled. +-Note that this doesn't affect the number register@tie{}@code{%}. +-@endDefreq +- +-@xref{Traps}. +- +- +-@c ===================================================================== +- +-@node Page Control, Fonts and Symbols, Page Layout, gtroff Reference +-@section Page Control +-@cindex page control +-@cindex control, page +- +-@DefreqList {bp, [@Var{page}]} +-@DefreqItem {bp, @t{+}@Var{page}} +-@DefreqItem {bp, @t{-}@Var{page}} +-@DefregListEndx {%} +-@cindex new page (@code{bp}) +-@cindex page, new (@code{bp}) +-Stop processing the current page and move to the next page. This +-request causes a break. It can also take an argument to set (increase, +-decrease) the page number of the next page (which actually becomes the +-current page after @code{bp} has finished). The difference between +-@code{bp} and @code{pn} is that @code{pn} does not cause a break or +-actually eject a page. @xref{Page Layout}. +- +-@Example +-.de newpage \" define macro +-'bp \" begin page +-'sp .5i \" vertical space +-.tl 'left top'center top'right top' \" title +-'sp .3i \" vertical space +-.. \" end macro +-@endExample +- +-@cindex @code{bp} request, and top-level diversion +-@cindex top-level diversion, and @code{bp} +-@cindex diversion, top-level, and @code{bp} +-@code{bp} has no effect if not called within the top-level diversion +-(@pxref{Diversions}). +- +-@cindex page number register (@code{%}) +-@cindex current page number (@code{%}) +-The read-write register@tie{}@code{%} holds the current page number. +- +-The number register @code{.pe} is set to@tie{}1 while @code{bp} is +-active. @xref{Page Location Traps}. +-@endDefreq +- +-@Defreq {ne, [@Var{space}]} +-@cindex orphan lines, preventing with @code{ne} +-@cindex conditional page break (@code{ne}) +-@cindex page break, conditional (@code{ne}) +-It is often necessary to force a certain amount of space before a new +-page occurs. This is most useful to make sure that there is not a +-single @dfn{orphan} line left at the bottom of a page. The @code{ne} +-request ensures that there is a certain distance, specified by the first +-argument, before the next page is triggered (see @ref{Traps}, for +-further information). The default scaling indicator for @code{ne} is +-@samp{v}; the default value of @var{space} is@tie{}1@dmn{v} if no +-argument is given. +- +-For example, to make sure that no fewer than 2@tie{}lines get orphaned, +-do the following before each paragraph: +- +-@Example +-.ne 2 +-text text text +-@endExample +- +-@code{ne} then automatically causes a page break if there is space for +-one line only. +-@endDefreq +- +-@DefreqList {sv, [@Var{space}]} +-@DefreqListEndx {os, } +-@cindex @code{ne} request, comparison with @code{sv} +-@code{sv} is similar to the @code{ne} request; it reserves the specified +-amount of vertical space. If the desired amount of space exists before +-the next trap (or the bottom page boundary if no trap is set), the space +-is output immediately (ignoring a partially filled line, which stays +-untouched). If there is not enough space, it is stored for later output +-via the @code{os} request. The default value is@tie{}1@dmn{v} if no +-argument is given; the default scaling indicator is @samp{v}. +- +-@cindex @code{sv} request, and no-space mode +-@cindex @code{os} request, and no-space mode +-Both @code{sv} and @code{os} ignore no-space mode. While the @code{sv} +-request allows negative values for @var{space}, @code{os} ignores them. +-@endDefreq +- +-@Defreg {nl} +-@cindex current vertical position (@code{nl}) +-@cindex vertical position, current (@code{nl}) +-@cindex position, vertical, current (@code{nl}) +-This register contains the current vertical position. If the vertical +-position is zero and the top of page transition hasn't happened yet, +-@code{nl} is set to negative value. @code{gtroff} itself does this at +-the very beginning of a document before anything has been printed, but +-the main usage is to plant a header trap on a page if this page has +-already started. +- +-Consider the following: +- +-@Example +-.de xxx +-. sp +-. tl ''Header'' +-. sp +-.. +-. +-First page. +-.bp +-.wh 0 xxx +-.nr nl (-1) +-Second page. +-@endExample +- +-@noindent +-Result: +- +-@Example +-First page. +- +-... +- +- Header +- +-Second page. +- +-... +-@endExample +- +-@noindent +-Without resetting @code{nl} to a negative value, the just planted trap +-would be active beginning with the @emph{next} page, not the current +-one. +- +-@xref{Diversions}, for a comparison with the @code{.h} and @code{.d} +-registers. +-@endDefreg +- +- +-@c ===================================================================== +- +-@node Fonts and Symbols, Sizes, Page Control, gtroff Reference +-@section Fonts and Symbols +-@cindex fonts +- +-@code{gtroff} can switch fonts at any point in the text. +- +-The basic set of fonts is @samp{R}, @samp{I}, @samp{B}, and @samp{BI}. +-These are Times Roman, Italic, Bold, and Bold Italic. For non-TTY +-devices, there is also at least one symbol font that contains various +-special symbols (Greek, mathematics). +- +-@menu +-* Changing Fonts:: +-* Font Families:: +-* Font Positions:: +-* Using Symbols:: +-* Character Classes:: +-* Special Fonts:: +-* Artificial Fonts:: +-* Ligatures and Kerning:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Changing Fonts, Font Families, Fonts and Symbols, Fonts and Symbols +-@subsection Changing Fonts +-@cindex fonts +- +-@DefreqList {ft, [@Var{font}]} +-@DefescItemx {\\f, , f, } +-@DefescItem {\\f, @Lparen{}, fn, } +-@DefescItem {\\f, @Lbrack{}, font, @Rbrack{}} +-@DefregListEndx {.sty} +-@cindex changing fonts (@code{ft}, @code{\f}) +-@cindex fonts, changing (@code{ft}, @code{\f}) +-@cindex @code{sty} request, and changing fonts +-@cindex @code{fam} request, and changing fonts +-@cindex @code{\F}, and changing fonts +-@kindex styles +-@kindex family +-@pindex DESC +-The @code{ft} request and the @code{\f} escape change the current font +-to @var{font} (one-character name@tie{}@var{f}, two-character name +-@var{fn}). +- +-If @var{font} is a style name (as set with the @code{sty} request or +-with the @code{styles} command in the @file{DESC} file), use it within +-the current font family (as set with the @code{fam} request, @code{\F} +-escape, or with the @code{family} command in the @file{DESC} file). +- +-It is not possible to switch to a font with the name @samp{DESC} +-(whereas this name could be used as a style name; however, this is not +-recommended). +- +-@cindex previous font (@code{ft}, @code{\f[]}, @code{\fP}) +-@cindex font, previous (@code{ft}, @code{\f[]}, @code{\fP}) +-With no argument or using @samp{P} as an argument, @code{.ft} switches +-to the previous font. Use @code{\f[]} to do this with the escape. The +-old syntax forms @code{\fP} or @code{\f[P]} are also supported. +- +-Fonts are generally specified as upper-case strings, which are usually +-1@tie{}to 4 characters representing an abbreviation or acronym of the +-font name. This is no limitation, just a convention. +- +-The example below produces two identical lines. +- +-@Example +-eggs, bacon, +-.ft B +-spam +-.ft +-and sausage. +- +-eggs, bacon, \fBspam\fP and sausage. +-@endExample +- +-Note that @code{\f} doesn't produce an input token in @code{gtroff}. As +-a consequence, it can be used in requests like @code{mc} (which expects +-a single character as an argument) to change the font on the fly: +- +-@Example +-.mc \f[I]x\f[] +-@endExample +- +-The current style name is available in the read-only number register +-@samp{.sty} (this is a string-valued register); if the current font +-isn't a style, the empty string is returned. It is associated with the +-current environment. +- +-@xref{Font Positions}, for an alternative syntax. +-@endDefreq +- +-@Defreq {ftr, f [@Var{g}]} +-@cindex font translation (@code{ftr}) +-@cindex @code{ft} request, and font translations +-@cindex @code{ul} request, and font translations +-@cindex @code{bd} request, and font translations +-@cindex @code{\f}, and font translations +-@cindex @code{cs} request, and font translations +-@cindex @code{tkf} request, and font translations +-@cindex @code{special} request, and font translations +-@cindex @code{fspecial} request, and font translations +-@cindex @code{fp} request, and font translations +-@cindex @code{sty} request, and font translations +-@cindex @code{if} request, and font translations +-@cindex @code{ie} request, and font translations +-@cindex @code{while} request, and font translations +-Translate font@tie{}@var{f} to font@tie{}@var{g}. Whenever a font +-named@tie{}@var{f} is referred to in a @code{\f} escape sequence, in the +-@code{F} and @code{S} conditional operators, or in the @code{ft}, +-@code{ul}, @code{bd}, @code{cs}, @code{tkf}, @code{special}, +-@code{fspecial}, @code{fp}, or @code{sty} requests, font@tie{}@var{g} is +-used. If @var{g} is missing or equal to@tie{}@var{f} the translation is +-undone. +- +-Note that it is not possible to chain font translations. Example: +- +-@Example +-.ftr XXX TR +-.ftr XXX YYY +-.ft XXX +- @result{} warning: can't find font `XXX' +-@endExample +-@endDefreq +- +-@DefreqList {fzoom, f [@Var{zoom}]} +-@DefregListEndx {.zoom} +-@cindex magnification of a font (@code{fzoom}) +-@cindex font, magnification (@code{fzoom}) +-@cindex zoom factor of a font (@code{fzoom}) +-@cindex factor, zoom, of a font (@code{fzoom}) +-@cindex font, zoom factor (@code{fzoom}) +-@cindex optical size of a font +-@cindex font, optical size +-@cindex size, optical, of a font +-Set magnification of font@tie{}@var{f} to factor @var{zoom}, which must +-be a non-negative integer multiple of 1/1000th. This request is useful +-to adjust the optical size of a font in relation to the others. In the +-example below, font @code{CR} is magnified by 10% (the zoom factor is +-thus 1.1). +- +-@Example +-.fam P +-.fzoom CR 1100 +-.ps 12 +-Palatino and \f[CR]Courier\f[] +-@endExample +- +-A missing or zero value of @var{zoom} is the same as a value of 1000, +-which means no magnification. @var{f}@tie{}must be a real font name, +-not a style. +- +-Note that the magnification of a font is completely transparent to +-troff; a change of the zoom factor doesn't cause any effect except that +-the dimensions of glyphs, (word) spaces, kerns, etc., of the affected +-font are adjusted accordingly. +- +-The zoom factor of the current font is available in the read-only number +-register @samp{.zoom}, in multiples of 1/1000th. It returns zero if +-there is no magnification. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Font Families, Font Positions, Changing Fonts, Fonts and Symbols +-@subsection Font Families +-@cindex font families +-@cindex families, font +-@cindex font styles +-@cindex styles, font +- +-Due to the variety of fonts available, @code{gtroff} has added the +-concept of @dfn{font families} and @dfn{font styles}. The fonts are +-specified as the concatenation of the font family and style. Specifying +-a font without the family part causes @code{gtroff} to use that style of +-the current family. +- +-@cindex PostScript fonts +-@cindex fonts, PostScript +-Currently, fonts for the devices @option{-Tps}, @option{-Tpdf}, +-@option{-Tdvi}, @option{-Tlj4}, @option{-Tlbp}, and the X11 fonts are +-set up to this mechanism. By default, @code{gtroff} uses the Times +-family with the four styles @samp{R}, @samp{I}, @samp{B}, and @samp{BI}. +- +-This way, it is possible to use the basic four fonts and to select a +-different font family on the command line (@pxref{Groff Options}). +- +-@DefreqList {fam, [@Var{family}]} +-@DefregItemx {.fam} +-@DefescItemx {\\F, , f, } +-@DefescItem {\\F, @Lparen{}, fm, } +-@DefescItem {\\F, @Lbrack{}, family, @Rbrack{}} +-@DefregListEndx {.fn} +-@cindex changing font family (@code{fam}, @code{\F}) +-@cindex font family, changing (@code{fam}, @code{\F}) +-Switch font family to @var{family} (one-character name@tie{}@var{f}, +-two-character name @var{fm}). If no argument is given, switch back to +-the previous font family. Use @code{\F[]} to do this with the escape. +-Note that @code{\FP} doesn't work; it selects font family @samp{P} +-instead. +- +-The value at start-up is @samp{T}. The current font family is available +-in the read-only number register @samp{.fam} (this is a string-valued +-register); it is associated with the current environment. +- +-@Example +-spam, +-.fam H \" helvetica family +-spam, \" used font is family H + style R = HR +-.ft B \" family H + style B = font HB +-spam, +-.fam T \" times family +-spam, \" used font is family T + style B = TB +-.ft AR \" font AR (not a style) +-baked beans, +-.ft R \" family T + style R = font TR +-and spam. +-@endExample +- +-Note that @code{\F} doesn't produce an input token in @code{gtroff}. As +-a consequence, it can be used in requests like @code{mc} (which expects +-a single character as an argument) to change the font family on the fly: +- +-@Example +-.mc \F[P]x\F[] +-@endExample +- +-The @samp{.fn} register contains the current @dfn{real font name} of the +-current font. This is a string-valued register. If the current font is +-a style, the value of @code{\n[.fn]} is the proper concatenation of +-family and style name. +-@endDefreq +- +-@Defreq {sty, n style} +-@cindex changing font style (@code{sty}) +-@cindex font style, changing (@code{sty}) +-@cindex @code{cs} request, and font styles +-@cindex @code{bd} request, and font styles +-@cindex @code{tkf} request, and font styles +-@cindex @code{uf} request, and font styles +-@cindex @code{fspecial} request, and font styles +-Associate @var{style} with font position@tie{}@var{n}. A font position +-can be associated either with a font or with a style. The current font +-is the index of a font position and so is also either a font or a style. +-If it is a style, the font that is actually used is the font which name +-is the concatenation of the name of the current family and the name of +-the current style. For example, if the current font is@tie{}1 and font +-position@tie{}1 is associated with style @samp{R} and the current font +-family is @samp{T}, then font @samp{TR} is used. If the current font is +-not a style, then the current family is ignored. If the requests +-@code{cs}, @code{bd}, @code{tkf}, @code{uf}, or @code{fspecial} are +-applied to a style, they are instead applied to the member of the +-current family corresponding to that style. +- +-@var{n}@tie{}must be a non-negative integer value. +- +-@pindex DESC +-@kindex styles +-The default family can be set with the @option{-f} option (@pxref{Groff +-Options}). The @code{styles} command in the @file{DESC} file controls +-which font positions (if any) are initially associated with styles +-rather than fonts. For example, the default setting for @sc{PostScript} +-fonts +- +-@Example +-styles R I B BI +-@endExample +- +-@noindent +-is equivalent to +- +-@Example +-.sty 1 R +-.sty 2 I +-.sty 3 B +-.sty 4 BI +-@endExample +- +-@code{fam} and @code{\F} always check whether the current font position +-is valid; this can give surprising results if the current font position +-is associated with a style. +- +-In the following example, we want to access the @sc{PostScript} font +-@code{FooBar} from the font family @code{Foo}: +- +-@Example +-.sty \n[.fp] Bar +-.fam Foo +- @result{} warning: can't find font `FooR' +-@endExample +- +-@noindent +-The default font position at start-up is@tie{}1; for the @sc{PostScript} +-device, this is associated with style @samp{R}, so @code{gtroff} tries +-to open @code{FooR}. +- +-A solution to this problem is to use a dummy font like the following: +- +-@Example +-.fp 0 dummy TR \" set up dummy font at position 0 +-.sty \n[.fp] Bar \" register style `Bar' +-.ft 0 \" switch to font at position 0 +-.fam Foo \" activate family `Foo' +-.ft Bar \" switch to font `FooBar' +-@endExample +- +-@xref{Font Positions}. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Font Positions, Using Symbols, Font Families, Fonts and Symbols +-@subsection Font Positions +-@cindex font positions +-@cindex positions, font +- +-For the sake of old phototypesetters and compatibility with old versions +-of @code{troff}, @code{gtroff} has the concept of font @dfn{positions}, +-on which various fonts are mounted. +- +-@DefreqList {fp, pos font [@Var{external-name}]} +-@DefregItemx {.f} +-@DefregListEndx {.fp} +-@cindex mounting font (@code{fp}) +-@cindex font, mounting (@code{fp}) +-Mount font @var{font} at position @var{pos} (which must be a +-non-negative integer). This numeric position can then be referred to +-with font changing commands. When @code{gtroff} starts it is using font +-position@tie{}1 (which must exist; position@tie{}0 is unused usually at +-start-up). +- +-@cindex font position register (@code{.f}) +-The current font in use, as a font position, is available in the +-read-only number register @samp{.f}. This can be useful to remember the +-current font for later recall. It is associated with the current +-environment (@pxref{Environments}). +- +-@Example +-.nr save-font \n[.f] +-.ft B +-... text text text ... +-.ft \n[save-font] +-@endExample +- +-@cindex next free font position register (@code{.fp}) +-The number of the next free font position is available in the read-only +-number register @samp{.fp}. This is useful when mounting a new font, +-like so: +- +-@Example +-.fp \n[.fp] NEATOFONT +-@endExample +- +-@pindex DESC@r{, and font mounting} +-Fonts not listed in the @file{DESC} file are automatically mounted on +-the next available font position when they are referenced. If a font is +-to be mounted explicitly with the @code{fp} request on an unused font +-position, it should be mounted on the first unused font position, which +-can be found in the @code{.fp} register. Although @code{gtroff} does +-not enforce this strictly, it is not allowed to mount a font at a +-position whose number is much greater (approx.@: 1000 positions) than +-that of any currently used position. +- +-The @code{fp} request has an optional third argument. This argument +-gives the external name of the font, which is used for finding the font +-description file. The second argument gives the internal name of the +-font, which is used to refer to the font in @code{gtroff} after it has +-been mounted. If there is no third argument then the internal name is +-used as the external name. This feature makes it possible to use fonts +-with long names in compatibility mode. +-@endDefreq +- +-Both the @code{ft} request and the @code{\f} escape have alternative +-syntax forms to access font positions. +- +-@DefreqList {ft, nnn} +-@DefescItemx {\\f, , n, } +-@DefescItem {\\f, @Lparen{}, nn, } +-@DefescListEnd {\\f, @Lbrack{}, nnn, @Rbrack{}} +-@cindex changing font position (@code{\f}) +-@cindex font position, changing (@code{\f}) +-@cindex @code{sty} request, and font positions +-@cindex @code{fam} request, and font positions +-@cindex @code{\F}, and font positions +-@kindex styles +-@kindex family +-@pindex DESC +-Change the current font position to @var{nnn} (one-digit +-position@tie{}@var{n}, two-digit position @var{nn}), which must be a +-non-negative integer. +- +-If @var{nnn} is associated with a style (as set with the @code{sty} +-request or with the @code{styles} command in the @file{DESC} file), use +-it within the current font family (as set with the @code{fam} request, +-the @code{\F} escape, or with the @code{family} command in the +-@file{DESC} file). +- +-@Example +-this is font 1 +-.ft 2 +-this is font 2 +-.ft \" switch back to font 1 +-.ft 3 +-this is font 3 +-.ft +-this is font 1 again +-@endExample +- +-@xref{Changing Fonts}, for the standard syntax form. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Using Symbols, Character Classes, Font Positions, Fonts and Symbols +-@subsection Using Symbols +-@cindex using symbols +-@cindex symbols, using +- +-@cindex glyph +-@cindex character +-@cindex ligature +-A @dfn{glyph} is a graphical representation of a @dfn{character}. While +-a character is an abstract entity containing semantic information, a +-glyph is something that can be actually seen on screen or paper. It is +-possible that a character has multiple glyph representation forms (for +-example, the character `A' can be either written in a roman or an italic +-font, yielding two different glyphs); sometimes more than one character +-maps to a single glyph (this is a @dfn{ligature} -- the most common is +-`fi'). +- +-@cindex symbol +-@cindex special fonts +-@kindex fonts +-@pindex DESC +-@cindex @code{special} request, and glyph search order +-@cindex @code{fspecial} request, and glyph search order +-A @dfn{symbol} is simply a named glyph. Within @code{gtroff}, all glyph +-names of a particular font are defined in its font file. If the user +-requests a glyph not available in this font, @code{gtroff} looks up an +-ordered list of @dfn{special fonts}. By default, the @sc{PostScript} +-output device supports the two special fonts @samp{SS} (slanted symbols) +-and @samp{S} (symbols) (the former is looked up before the latter). +-Other output devices use different names for special fonts. Fonts +-mounted with the @code{fonts} keyword in the @file{DESC} file are +-globally available. To install additional special fonts locally (i.e.@: +-for a particular font), use the @code{fspecial} request. +- +-Here the exact rules how @code{gtroff} searches a given symbol: +- +-@itemize @bullet +-@item +-If the symbol has been defined with the @code{char} request, use it. +-This hides a symbol with the same name in the current font. +- +-@item +-Check the current font. +- +-@item +-If the symbol has been defined with the @code{fchar} request, use it. +- +-@item +-Check whether the current font has a font-specific list of special +-fonts; test all fonts in the order of appearance in the last +-@code{fspecial} call if appropriate. +- +-@item +-If the symbol has been defined with the @code{fschar} request for the +-current font, use it. +- +-@item +-Check all fonts in the order of appearance in the last @code{special} +-call. +- +-@item +-If the symbol has been defined with the @code{schar} request, use it. +- +-@item +-As a last resort, consult all fonts loaded up to now for special fonts +-and check them, starting with the lowest font number. Note that this +-can sometimes lead to surprising results since the @code{fonts} line in +-the @file{DESC} file often contains empty positions, which are filled +-later on. For example, consider the following: +- +-@Example +-fonts 3 0 0 FOO +-@endExample +- +-@noindent +-This mounts font @code{foo} at font position@tie{}3. We assume that +-@code{FOO} is a special font, containing glyph @code{foo}, and that no +-font has been loaded yet. The line +- +-@Example +-.fspecial BAR BAZ +-@endExample +- +-@noindent +-makes font @code{BAZ} special only if font @code{BAR} is active. We +-further assume that @code{BAZ} is really a special font, i.e., the font +-description file contains the @code{special} keyword, and that it also +-contains glyph @code{foo} with a special shape fitting to font +-@code{BAR}. After executing @code{fspecial}, font @code{BAR} is loaded +-at font position@tie{}1, and @code{BAZ} at position@tie{}2. +- +-We now switch to a new font @code{XXX}, trying to access glyph +-@code{foo} that is assumed to be missing. There are neither +-font-specific special fonts for @code{XXX} nor any other fonts made +-special with the @code{special} request, so @code{gtroff} starts the +-search for special fonts in the list of already mounted fonts, with +-increasing font positions. Consequently, it finds @code{BAZ} before +-@code{FOO} even for @code{XXX}, which is not the intended behaviour. +-@end itemize +- +-@xref{Font Files}, and @ref{Special Fonts}, for more details. +- +-@cindex list of available glyphs (@cite{groff_char(7)} man page) +-@cindex available glyphs, list (@cite{groff_char(7)} man page) +-@cindex glyphs, available, list (@cite{groff_char(7)} man page) +-The list of available symbols is device dependent; see the +-@cite{groff_char(7)} man page for a complete list of all glyphs. For +-example, say +- +-@Example +-man -Tdvi groff_char > groff_char.dvi +-@endExample +- +-@noindent +-for a list using the default DVI fonts (not all versions of the +-@code{man} program support the @option{-T} option). If you want to use +-an additional macro package to change the used fonts, @code{groff} must +-be called directly: +- +-@Example +-groff -Tdvi -mec -man groff_char.7 > groff_char.dvi +-@endExample +- +-@cindex composite glyph names +-@cindex glyph names, composite +-@cindex groff glyph list (GGL) +-@cindex GGL (groff glyph list) +-@cindex adobe glyph list (AGL) +-@cindex AGL (adobe glyph list) +-Glyph names not listed in groff_char(7) are derived algorithmically, +-using a simplified version of the Adobe Glyph List (AGL) algorithm, which +-is described in +-@uref{http://partners.adobe.com@//public@//developer@//opentype@//index_glyph.html}. +-The (frozen) set of glyph names that can't be derived algorithmically +-is called @dfn{groff glyph list (GGL)}. +- +-@itemize @bullet +-@item +-A glyph for Unicode character U+@var{XXXX}[@var{X}[@var{X}]], which is +-not a composite character is named +-@code{u@var{XXXX}@r{[}@var{X}@r{[}@var{X}@r{]]}}. @var{X} must be an +-uppercase hexadecimal digit. Examples: @code{u1234}, @code{u008E}, +-@code{u12DB8}. The largest Unicode value is 0x10FFFF. There must be at +-least four @code{X} digits; if necessary, add leading zeroes (after the +-@samp{u}). No zero padding is allowed for character codes greater than +-0xFFFF. Surrogates (i.e., Unicode values greater than 0xFFFF +-represented with character codes from the surrogate area U+D800-U+DFFF) +-are not allowed too. +- +-@item +-A glyph representing more than a single input character is named +- +-@display +-@samp{u} @var{component1} @samp{_} @var{component2} @samp{_} @var{component3} @dots{} +-@end display +- +-@noindent +-Example: @code{u0045_0302_0301}. +- +-For simplicity, all Unicode characters that are composites must be +-decomposed maximally (this is normalization form@tie{}D in the Unicode +-standard); for example, @code{u00CA_0301} is not a valid glyph name +-since U+00CA (@sc{latin capital letter e with circumflex}) can be +-further decomposed into U+0045 (@sc{latin capital letter e}) and U+0302 +-(@sc{combining circumflex accent}). @code{u0045_0302_0301} is thus the +-glyph name for U+1EBE, @sc{latin capital letter e with circumflex and +-acute}. +- +-@item +-groff maintains a table to decompose all algorithmically derived glyph +-names that are composites itself. For example, @code{u0100} (@sc{latin +-letter a with macron}) is automatically decomposed into +-@code{u0041_0304}. Additionally, a glyph name of the GGL is preferred +-to an algorithmically derived glyph name; groff also automatically does +-the mapping. Example: The glyph @code{u0045_0302} is mapped to +-@code{^E}. +- +-@item +-glyph names of the GGL can't be used in composite glyph names; for +-example, @code{^E_u0301} is invalid. +-@end itemize +- +-@DefescList {\\, @Lparen{}, nm, } +-@DefescItem {\\, @Lbrack{}, name, @Rbrack{}} +-@DefescListEnd {\\, @Lbrack{}, component1 component2 @dots{}, @Rbrack{}} +-Insert a symbol @var{name} (two-character name @var{nm}) or a composite +-glyph with component glyphs @var{component1}, @var{component2}, +-@enddots{} There is no special syntax for one-character names -- the +-natural form @samp{\@var{n}} would collide with escapes.@footnote{Note +-that a one-character symbol is not the same as an input character, i.e., +-the character @code{a} is not the same as @code{\[a]}. By default, +-@code{groff} defines only a single one-character symbol, @code{\[-]}; it +-is usually accessed as @code{\-}. On the other hand, @code{gtroff} has +-the special feature that @code{\[char@var{XXX}]} is the same as the +-input character with character code @var{XXX}. For example, +-@code{\[char97]} is identical to the letter @code{a} if @acronym{ASCII} +-encoding is active.} +- +-If @var{name} is undefined, a warning of type @samp{char} is generated, +-and the escape is ignored. @xref{Debugging}, for information about +-warnings. +- +-groff resolves @code{\[...]} with more than a single component as +-follows: +- +-@itemize @bullet +-@item +-Any component that is found in the GGL is converted to the +-@code{u@var{XXXX}} form. +- +-@item +-Any component @code{u@var{XXXX}} that is found in the list of +-decomposable glyphs is decomposed. +- +-@item +-The resulting elements are then concatenated with @samp{_} in between, +-dropping the leading @samp{u} in all elements but the first. +-@end itemize +- +-No check for the existence of any component (similar to @code{tr} +-request) is done. +- +-Examples: +- +-@table @code +-@item \[A ho] +-@samp{A} maps to @code{u0041}, @samp{ho} maps to @code{u02DB}, thus the +-final glyph name would be @code{u0041_02DB}. Note this is not the +-expected result: The ogonek glyph @samp{ho} is a spacing ogonek, but for +-a proper composite a non-spacing ogonek (U+0328) is necessary. Looking +-into the file @file{composite.tmac} one can find @w{@samp{.composite ho +-u0328}}, which changes the mapping of @samp{ho} while a composite glyph +-name is constructed, causing the final glyph name to be +-@code{u0041_0328}. +- +-@item \[^E u0301] +-@itemx \[^E aa] +-@itemx \[E a^ aa] +-@itemx \[E ^ '] +-@samp{^E} maps to @code{u0045_0302}, thus the final glyph name is +-@code{u0045_0302_0301} in all forms (assuming proper calls of the +-@code{composite} request). +-@end table +- +-It is not possible to define glyphs with names like @w{@samp{A ho}} +-within a groff font file. This is not really a limitation; instead, you +-have to define @code{u0041_0328}. +-@endDefesc +- +-@Defesc {\\C, ', xxx, '} +-@cindex named character (@code{\C}) +-@cindex character, named (@code{\C}) +-Typeset the glyph named @var{xxx}.@footnote{@code{\C} is actually a +-misnomer since it accesses an output glyph.} Normally it is more +-convenient to use @code{\[@var{xxx}]}, but @code{\C} has the advantage +-that it is compatible with newer versions of @acronym{AT&T} @code{troff} +-and is available in compatibility mode. +-@endDefesc +- +-@Defreq {composite, from to} +-@pindex composite.tmac +-Map glyph name @var{from} to glyph name @var{to} if it is used in +-@code{\[...]} with more than one component. See above for examples. +- +-This mapping is based on glyph names only; no check for the existence of +-either glyph is done. +- +-A set of default mappings for many accents can be found in the file +-@file{composite.tmac}, which is loaded at start-up. +-@endDefreq +- +-@Defesc {\\N, ', n, '} +-@cindex numbered glyph (@code{\N}) +-@cindex glyph, numbered (@code{\N}) +-@cindex @code{char} request, used with @code{\N} +-@cindex Unicode +-Typeset the glyph with code@tie{}@var{n} in the current font +-(@code{n}@tie{}is @strong{not} the input character code). The number +-@var{n}@tie{}can be any non-negative decimal integer. Most devices only +-have glyphs with codes between 0 and@tie{}255; the Unicode output device +-uses codes in the range 0--65535. If the current font does not contain +-a glyph with that code, special fonts are @emph{not} searched. The +-@code{\N} escape sequence can be conveniently used in conjunction with +-the @code{char} request: +- +-@Example +-.char \[phone] \f[ZD]\N'37' +-@endExample +- +-@noindent +-@pindex DESC +-@cindex unnamed glyphs +-@cindex glyphs, unnamed +-The code of each glyph is given in the fourth column in the font +-description file after the @code{charset} command. It is possible to +-include unnamed glyphs in the font description file by using a name of +-@samp{---}; the @code{\N} escape sequence is the only way to use these. +- +-No kerning is applied to glyphs accessed with @code{\N}. +-@endDefesc +- +-Some escape sequences directly map onto special glyphs. +- +-@Defesc {\\', , , } +-This is a backslash followed by the apostrophe character, +-@acronym{ASCII} character @code{0x27} (@acronym{EBCDIC} character +-@code{0x7D}). The same as @code{\[aa]}, the acute accent. +-@endDefesc +- +-@Defesc {\\`, , , } +-This is a backslash followed by @acronym{ASCII} character @code{0x60} +-(@acronym{EBCDIC} character @code{0x79} usually). The same as +-@code{\[ga]}, the grave accent. +-@endDefesc +- +-@Defesc {\\-, , , } +-This is the same as @code{\[-]}, the minus sign in the current font. +-@endDefesc +- +-@Defesc {\\_, , , } +-This is the same as @code{\[ul]}, the underline character. +-@endDefesc +- +-@Defreq {cflags, n c1 c2 @dots{}} +-@cindex glyph properties (@code{cflags}) +-@cindex character properties (@code{cflags}) +-@cindex properties of glyphs (@code{cflags}) +-@cindex properties of characters (@code{cflags}) +-Input characters and symbols have certain properties associated with +-it.@footnote{Note that the output glyphs themselves don't have such +-properties. For @code{gtroff}, a glyph is a numbered box with a given +-width, depth, and height, nothing else. All manipulations with the +-@code{cflags} request work on the input level.} These properties can be +-modified with the @code{cflags} request. The first argument is the sum +-of the desired flags and the remaining arguments are the characters or +-symbols to have those properties. It is possible to omit the spaces +-between the characters or symbols. Instead of single characters or +-symbols you can also use character classes (see @ref{Character Classes} +-for more details). +- +-@table @code +-@item 1 +-@cindex end-of-sentence characters +-@cindex characters, end-of-sentence +-The character ends sentences (initially characters @samp{.?!} have this +-property). +- +-@item 2 +-@cindex hyphenating characters +-@cindex characters, hyphenation +-Lines can be broken before the character (initially no characters have +-this property). This only works if both the characters before and after +-have non-zero hyphenation codes (as set with the @code{hcode} request). +-Use value@tie{}64 to override this behaviour. +- +-@item 4 +-@cindex @code{hy} glyph, and @code{cflags} +-@cindex @code{em} glyph, and @code{cflags} +-Lines can be broken after the character (initially the character +-@samp{-} and the symbols @samp{\[hy]} and @samp{\[em]} have this +-property). This only works if both the characters before and after have +-non-zero hyphenation codes (as set with the @code{hcode} request). Use +-value@tie{}64 to override this behaviour. +- +-@item 8 +-@cindex overlapping characters +-@cindex characters, overlapping +-@cindex @code{ul} glyph, and @code{cflags} +-@cindex @code{rn} glyph, and @code{cflags} +-@cindex @code{ru} glyph, and @code{cflags} +-@cindex @code{radicalex} glyph, and @code{cflags} +-@cindex @code{sqrtex} glyph, and @code{cflags} +-The character overlaps horizontally if used as a horizontal line +-building element. Initially the symbols @samp{\[ul]}, @samp{\[rn]}, +-@samp{\[ru]}, @samp{\[radicalex]}, and @samp{\[sqrtex]} have this +-property. +- +-@item 16 +-@cindex @code{br} glyph, and @code{cflags} +-The character overlaps vertically if used as vertical line building +-element. Initially symbol @samp{\[br]} has this property. +- +-@item 32 +-@cindex transparent characters +-@cindex character, transparent +-@cindex @code{"}, at end of sentence +-@cindex @code{'}, at end of sentence +-@cindex @code{)}, at end of sentence +-@cindex @code{]}, at end of sentence +-@cindex @code{*}, at end of sentence +-@cindex @code{dg} glyph, at end of sentence +-@cindex @code{rq} glyph, at end of sentence +-@cindex @code{cq} glyph, at end of sentence +-An end-of-sentence character followed by any number of characters with +-this property is treated as the end of a sentence if followed by a +-newline or two spaces; in other words the character is @dfn{transparent} +-for the purposes of end-of-sentence recognition -- this is the same as +-having a zero space factor in @TeX{} (initially characters @samp{"')]*} +-and the symbols @samp{\[dg]}, @samp{\[rq]}, and @samp{\[cq]} have this +-property). +- +-@item 64 +-Ignore hyphenation code values of the surrounding characters. Use this +-in combination with values 2 and@tie{}4 (initially no characters have +-this property). For example, if you need an automatic break point after +-the hyphen in number ranges like `3000-5000', insert +- +-@Example +-.cflags 68 - +-@endExample +- +-@noindent +-into your document. Note, however, that this can lead to bad layout if +-done without thinking; in most situations, a better solution instead of +-changing the @code{cflags} value is to insert @code{\:} right after the +-hyphen at the places that really need a break point. +- +-@item 128 +-Prohibit a line break before the character, but allow a line break after +-the character. This works only in combination with flags 256 and 512 +-(see below) and has no effect otherwise. +- +-@item 256 +-Prohibit a line break after the character, but allow a line break before +-the character. This works only in combination with flags 128 and 512 +-(see below) and has no effect otherwise. +- +-@item 512 +-Allow line break before or after the character. This works only in +-combination with flags 128 and 256 and has no effect otherwise. +- +-Contrary to flag values 2 and@tie{}4, the flags 128, 256, and 512 work +-pairwise. If, for example, the left character has value 512, and the +-right character 128, no line break gets inserted. If we use +-value@tie{}6 instead for the left character, a line break after the +-character can't be suppressed since the right neighbour character +-doesn't get examined. +-@end table +-@endDefreq +- +-@DefreqList {char, g [@Var{string}]} +-@DefreqItemx {fchar, g [@Var{string}]} +-@DefreqItemx {fschar, f g [@Var{string}]} +-@DefreqListEndx {schar, g [@Var{string}]} +-@cindex defining character (@code{char}) +-@cindex defining fallback character (@code{fchar}, @code{fschar}, @code{schar}) +-@cindex character, defining (@code{char}) +-@cindex character, defining fallback (@code{fchar}, @code{fschar}, @code{schar}) +-@cindex fallback character, defining (@code{fchar}, @code{fschar}, @code{schar}) +-@cindex creating new characters (@code{char}) +-@cindex defining symbol (@code{char}) +-@cindex symbol, defining (@code{char}) +-@cindex defining glyph (@code{char}) +-@cindex glyph, defining (@code{char}) +-@cindex escape character, while defining glyph +-@cindex character, escape, while defining glyph +-@cindex @code{tr} request, and glyph definitions +-@cindex @code{cp} request, and glyph definitions +-@cindex @code{rc} request, and glyph definitions +-@cindex @code{lc} request, and glyph definitions +-@cindex @code{\l}, and glyph definitions +-@cindex @code{\L}, and glyph definitions +-@cindex @code{\&}, and glyph definitions +-@cindex @code{\e}, and glyph definitions +-@cindex @code{hcode} request, and glyph definitions +-Define a new glyph@tie{}@var{g} to be @var{string} (which can be +-empty).@footnote{@code{char} is a misnomer since an output glyph is +-defined.} Every time glyph@tie{}@var{g} needs to be printed, +-@var{string} is processed in a temporary environment and the result is +-wrapped up into a single object. Compatibility mode is turned off and +-the escape character is set to @samp{\} while @var{string} is being +-processed. Any emboldening, constant spacing or track kerning is +-applied to this object rather than to individual characters in +-@var{string}. +- +-A glyph defined by these requests can be used just like a normal glyph +-provided by the output device. In particular, other characters can be +-translated to it with the @code{tr} or @code{trin} requests; it can be +-made the leader character by the @code{lc} request; repeated patterns +-can be drawn with the glyph using the @code{\l} and @code{\L} escape +-sequences; words containing the glyph can be hyphenated correctly if the +-@code{hcode} request is used to give the glyph's symbol a hyphenation +-code. +- +-There is a special anti-recursion feature: Use of @code{g} within the +-glyph's definition is handled like normal characters and symbols not +-defined with @code{char}. +- +-Note that the @code{tr} and @code{trin} requests take precedence if +-@code{char} accesses the same symbol. +- +-@Example +-.tr XY +-X +- @result{} Y +-.char X Z +-X +- @result{} Y +-.tr XX +-X +- @result{} Z +-@endExample +- +-The @code{fchar} request defines a fallback glyph: @code{gtroff} only +-checks for glyphs defined with @code{fchar} if it cannot find the glyph +-in the current font. @code{gtroff} carries out this test before +-checking special fonts. +- +-@code{fschar} defines a fallback glyph for font@tie{}@var{f}: +-@code{gtroff} checks for glyphs defined with @code{fschar} after the +-list of fonts declared as font-specific special fonts with the +-@code{fspecial} request, but before the list of fonts declared as global +-special fonts with the @code{special} request. +- +-Finally, the @code{schar} request defines a global fallback glyph: +-@code{gtroff} checks for glyphs defined with @code{schar} after the list +-of fonts declared as global special fonts with the @code{special} +-request, but before the already mounted special fonts. +- +-@xref{Using Symbols}, for a detailed description of the glyph searching +-mechanism in @code{gtroff}. +-@endDefreq +- +-@DefreqList {rchar, c1 c2 @dots{}} +-@DefreqListEndx {rfschar, f c1 c2 @dots{}} +-@cindex removing glyph definition (@code{rchar}, @code{rfschar}) +-@cindex glyph, removing definition (@code{rchar}, @code{rfschar}) +-@cindex fallback glyph, removing definition (@code{rchar}, @code{rfschar}) +-Remove the definitions of glyphs @var{c1}, @var{c2},@tie{}@enddots{} +-This undoes the effect of a @code{char}, @code{fchar}, or @code{schar} +-request. +- +-It is possible to omit the whitespace between arguments. +- +-The request @code{rfschar} removes glyph definitions defined with +-@code{fschar} for glyph@tie{}f. +-@endDefreq +- +-@xref{Special Characters}. +- +-@c --------------------------------------------------------------------- +- +-@node Character Classes, Special Fonts, Using Symbols, Fonts and Symbols +-@subsection Character Classes +-@cindex character classes +-@cindex classes, character +- +-Classes are particularly useful for East Asian languages such as +-Chinese, Japanese, and Korean, where the number of needed characters is +-much larger than in European languages, and where large sets of +-characters share the same properties. +- +-@Defreq {class, n c1 c2 @dots{}} +-@cindex character class (@code{class}) +-@cindex defining character class (@code{class}) +-@cindex class of characters (@code{class}) +-In @code{groff}, a @dfn{character class} (or simply ``class'') is a set +-of characters, grouped by some user aspect. The @code{class} request +-defines such classes so that other requests can refer to all characters +-belonging to this set with a single class name. Currently, only the +-@code{cflags} request can handle character classes. +- +-A @code{class} request takes a class name followed by a list of +-entities. In its simplest form, the entities are characters or symbols: +- +-@Example +-.class [prepunct] , : ; > @} +-@endExample +- +-Since class and glyph names share the same namespace, it is recommended +-to start and end the class name with @code{[} and @code{]}, +-respectively, to avoid collisions with normal @code{groff} symbols (and +-symbols defined by the user). In particular, the presence of @code{]} +-in the symbol name intentionally prevents the usage of @code{\[...]}, +-thus you must use the @code{\C} escape to access a class with such a +-name. +- +-@cindex GGL (groff glyph list) +-@cindex groff glyph list (GGL) +-You can also use a special character range notation, consisting of a +-start character or symbol, followed by @samp{-}, and an end character or +-symbol. Internally, @code{gtroff} converts these two symbol names to +-Unicode values (according to the groff glyph gist), which then give the +-start and end value of the range. If that fails, the class definition +-is skipped. +- +-Finally, classes can be nested, too. +- +-Here is a more complex example: +- +-@Example +-.class [prepunctx] \C'[prepunct]' \[u2013]-\[u2016] +-@endExample +- +-The class @samp{prepunctx} now contains the contents of the class +-@code{prepunct} as defined above (the set @samp{, : ; > @}}), and +-characters in the range between @code{U+2013} and @code{U+2016}. +- +-If you want to add @samp{-} to a class, it must be the first character +-value in the argument list, otherwise it gets misinterpreted as a range. +- +-Note that it is not possible to use class names within range +-definitions. +- +-Typical use of the @code{class} request is to control line-breaking and +-hyphenation rules as defined by the @code{cflags} request. For example, +-to inhibit line breaks before the characters belonging to the +-@code{prepunctx} class, you can write: +- +-@Example +-.cflags 2 \C'[prepunctx]' +-@endExample +- +-See the @code{cflags} request in @ref{Using Symbols}, for more details. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Special Fonts, Artificial Fonts, Character Classes, Fonts and Symbols +-@subsection Special Fonts +-@cindex special fonts +-@cindex fonts, special +- +-Special fonts are those that @code{gtroff} searches when it cannot find +-the requested glyph in the current font. The Symbol font is usually a +-special font. +- +-@code{gtroff} provides the following two requests to add more special +-fonts. @xref{Using Symbols}, for a detailed description of the glyph +-searching mechanism in @code{gtroff}. +- +-Usually, only non-TTY devices have special fonts. +- +-@DefreqList {special, [@Var{s1} @Var{s2} @dots{}]} +-@DefreqListEndx {fspecial, f [@Var{s1} @Var{s2} @dots{}]} +-@kindex fonts +-@pindex DESC +-Use the @code{special} request to define special fonts. Initially, this +-list is empty. +- +-Use the @code{fspecial} request to designate special fonts only when +-font@tie{}@var{f} is active. Initially, this list is empty. +- +-Previous calls to @code{special} or @code{fspecial} are overwritten; +-without arguments, the particular list of special fonts is set to empty. +-Special fonts are searched in the order they appear as arguments. +- +-All fonts that appear in a call to @code{special} or @code{fspecial} +-are loaded. +- +-@xref{Using Symbols}, for the exact search order of glyphs. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Artificial Fonts, Ligatures and Kerning, Special Fonts, Fonts and Symbols +-@subsection Artificial Fonts +-@cindex artificial fonts +-@cindex fonts, artificial +- +-There are a number of requests and escapes for artificially creating +-fonts. These are largely vestiges of the days when output devices did +-not have a wide variety of fonts, and when @code{nroff} and @code{troff} +-were separate programs. Most of them are no longer necessary in GNU +-@code{troff}. Nevertheless, they are supported. +- +-@DefescList {\\H, ', height, '} +-@DefescItem {\\H, ', @t{+}height, '} +-@DefescItem {\\H, ', @t{-}height, '} +-@DefregListEndx {.height} +-@cindex changing the font height (@code{\H}) +-@cindex font height, changing (@code{\H}) +-@cindex height, font, changing (@code{\H}) +-Change (increment, decrement) the height of the current font, but not +-the width. If @var{height} is zero, restore the original height. +-Default scaling indicator is @samp{z}. +- +-The read-only number register @code{.height} contains the font height as +-set by @code{\H}. +- +-Currently, only the @option{-Tps} and @option{-Tpdf} devices support +-this feature. +- +-Note that @code{\H} doesn't produce an input token in @code{gtroff}. As +-a consequence, it can be used in requests like @code{mc} (which expects +-a single character as an argument) to change the font on the fly: +- +-@Example +-.mc \H'+5z'x\H'0' +-@endExample +- +-In compatibility mode, @code{gtroff} behaves differently: If an +-increment or decrement is used, it is always taken relative to the +-current point size and not relative to the previously selected font +-height. Thus, +- +-@Example +-.cp 1 +-\H'+5'test \H'+5'test +-@endExample +- +-@noindent +-prints the word @samp{test} twice with the same font height (five points +-larger than the current font size). +-@endDefesc +- +-@DefescList {\\S, ', slant, '} +-@DefregListEndx {.slant} +-@cindex changing the font slant (@code{\S}) +-@cindex font slant, changing (@code{\S}) +-@cindex slant, font, changing (@code{\S}) +-Slant the current font by @var{slant} degrees. Positive values slant to +-the right. Only integer values are possible. +- +-The read-only number register @code{.slant} contains the font slant as +-set by @code{\S}. +- +-Currently, only the @option{-Tps} and @option{-Tpdf} devices support +-this feature. +- +-Note that @code{\S} doesn't produce an input token in @code{gtroff}. As +-a consequence, it can be used in requests like @code{mc} (which expects +-a single character as an argument) to change the font on the fly: +- +-@Example +-.mc \S'20'x\S'0' +-@endExample +- +-This request is incorrectly documented in the original @acronym{UNIX} +-troff manual; the slant is always set to an absolute value. +-@endDefesc +- +-@Defreq {ul, [@Var{lines}]} +-@cindex underlining (@code{ul}) +-The @code{ul} request normally underlines subsequent lines if a TTY +-output device is used. Otherwise, the lines are printed in italics +-(only the term `underlined' is used in the following). The single +-argument is the number of input lines to be underlined; with no +-argument, the next line is underlined. If @var{lines} is zero or +-negative, stop the effects of @code{ul} (if it was active). Requests +-and empty lines do not count for computing the number of underlined +-input lines, even if they produce some output like @code{tl}. Lines +-inserted by macros (e.g.@: invoked by a trap) do count. +- +-At the beginning of @code{ul}, the current font is stored and the +-underline font is activated. Within the span of a @code{ul} request, it +-is possible to change fonts, but after the last line affected by +-@code{ul} the saved font is restored. +- +-This number of lines still to be underlined is associated with the +-current environment (@pxref{Environments}). The underline font can be +-changed with the @code{uf} request. +- +-@c XXX @xref should be changed to grotty +- +-@c @xref{Troff and Nroff Mode}, for a discussion how underlining is +-@c implemented in for TTY output devices, and which problems can arise. +- +-The @code{ul} request does not underline spaces. +-@endDefreq +- +-@Defreq {cu, [@Var{lines}]} +-@cindex continuous underlining (@code{cu}) +-@cindex underlining, continuous (@code{cu}) +-The @code{cu} request is similar to @code{ul} but underlines spaces as +-well (if a TTY output device is used). +-@endDefreq +- +-@Defreq {uf, font} +-@cindex underline font (@code{uf}) +-@cindex font for underlining (@code{uf}) +-Set the underline font (globally) used by @code{ul} and @code{cu}. By +-default, this is the font at position@tie{}2. @var{font} can be either +-a non-negative font position or the name of a font. +-@endDefreq +- +-@DefreqList {bd, font [@Var{offset}]} +-@DefreqItem {bd, font1 font2 [@Var{offset}]} +-@DefregListEndx {.b} +-@cindex imitating bold face (@code{bd}) +-@cindex bold face, imitating (@code{bd}) +-Artificially create a bold font by printing each glyph twice, slightly +-offset. +- +-Two syntax forms are available. +- +-@itemize @bullet +-@item +-Imitate a bold font unconditionally. The first argument specifies the +-font to embolden, and the second is the number of basic units, minus +-one, by which the two glyphs are offset. If the second argument is +-missing, emboldening is turned off. +- +-@var{font} can be either a non-negative font position or the name of a +-font. +- +-@var{offset} is available in the @code{.b} read-only register if a +-special font is active; in the @code{bd} request, its default unit is +-@samp{u}. +- +-@cindex @code{fspecial} request, and imitating bold +-@kindex special +-@cindex embolding of special fonts +-@cindex special fonts, emboldening +-@item +-Imitate a bold form conditionally. Embolden @var{font1} by @var{offset} +-only if font @var{font2} is the current font. This command can be +-issued repeatedly to set up different emboldening values for different +-current fonts. If the second argument is missing, emboldening is turned +-off for this particular current font. +- +-This affects special fonts only (either set up with the @code{special} +-command in font files or with the @code{fspecial} request). +-@end itemize +-@endDefreq +- +-@Defreq {cs, font [@Var{width} [@Var{em-size}]]} +-@cindex constant glyph space mode (@code{cs}) +-@cindex mode for constant glyph space (@code{cs}) +-@cindex glyph, constant space +-@cindex @code{ps} request, and constant glyph space mode +-Switch to and from @dfn{constant glyph space mode}. If activated, the +-width of every glyph is @math{@var{width}/36} ems. The em size is given +-absolutely by @var{em-size}; if this argument is missing, the em value +-is taken from the current font size (as set with the @code{ps} request) +-when the font is effectively in use. Without second and third argument, +-constant glyph space mode is deactivated. +- +-Default scaling indicator for @var{em-size} is @samp{z}; @var{width} is +-an integer. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Ligatures and Kerning, , Artificial Fonts, Fonts and Symbols +-@subsection Ligatures and Kerning +-@cindex ligatures and kerning +-@cindex kerning and ligatures +- +-Ligatures are groups of characters that are run together, i.e, producing +-a single glyph. For example, the letters `f' and `i' can form a +-ligature `fi' as in the word `file'. This produces a cleaner look +-(albeit subtle) to the printed output. Usually, ligatures are not +-available in fonts for TTY output devices. +- +-Most @sc{PostScript} fonts support the fi and fl ligatures. The C/A/T +-typesetter that was the target of @acronym{AT&T} @code{troff} also +-supported `ff', `ffi', and `ffl' ligatures. Advanced typesetters or +-`expert' fonts may include ligatures for `ft' and `ct', although GNU +-@code{troff} does not support these (yet). +- +-Only the current font is checked for ligatures and kerns; neither +-special fonts nor entities defined with the @code{char} request (and its +-siblings) are taken into account. +- +-@DefreqList {lg, [@Var{flag}]} +-@DefregListEndx {.lg} +-@cindex activating ligatures (@code{lg}) +-@cindex ligatures, activating (@code{lg}) +-@cindex ligatures enabled register (@code{.lg}) +-Switch the ligature mechanism on or off; if the parameter is non-zero or +-missing, ligatures are enabled, otherwise disabled. Default is on. The +-current ligature mode can be found in the read-only number register +-@code{.lg} (set to 1 or@tie{}2 if ligatures are enabled, +-0@tie{}otherwise). +- +-Setting the ligature mode to@tie{}2 enables the two-character ligatures +-(fi, fl, and ff) and disables the three-character ligatures (ffi and +-ffl). +-@endDefreq +- +-@dfn{Pairwise kerning} is another subtle typesetting mechanism that +-modifies the distance between a glyph pair to improve readability. In +-most cases (but not always) the distance is decreased. +-@iftex +-For example, compare the combination of the letters `V' and `A'. With +-kerning, `VA' is printed. Without kerning it appears as `V@w{}A'. +-@end iftex +-Typewriter-like fonts and fonts for terminals where all glyphs have the +-same width don't use kerning. +- +-@DefreqList {kern, [@Var{flag}]} +-@DefregListEndx {.kern} +-@cindex activating kerning (@code{kern}) +-@cindex kerning, activating (@code{kern}) +-@cindex kerning enabled register (@code{.kern}) +-Switch kerning on or off. If the parameter is non-zero or missing, +-enable pairwise kerning, otherwise disable it. The read-only number +-register @code{.kern} is set to@tie{}1 if pairwise kerning is enabled, +-0@tie{}otherwise. +- +-@cindex zero width space character (@code{\&}) +-@cindex character, zero width space (@code{\&}) +-@cindex space character, zero width (@code{\&}) +-If the font description file contains pairwise kerning information, +-glyphs from that font are kerned. Kerning between two glyphs can be +-inhibited by placing @code{\&} between them: @samp{V\&A}. +- +-@xref{Font File Format}. +-@endDefreq +- +-@cindex track kerning +-@cindex kerning, track +-@dfn{Track kerning} expands or reduces the space between glyphs. This +-can be handy, for example, if you need to squeeze a long word onto a +-single line or spread some text to fill a narrow column. It must be +-used with great care since it is usually considered bad typography if +-the reader notices the effect. +- +-@Defreq {tkf, f s1 n1 s2 n2} +-@cindex activating track kerning (@code{tkf}) +-@cindex track kerning, activating (@code{tkf}) +-Enable track kerning for font@tie{}@var{f}. If the current font +-is@tie{}@var{f} the width of every glyph is increased by an amount +-between @var{n1} and @var{n2} (@var{n1}, @var{n2} can be negative); if +-the current point size is less than or equal to @var{s1} the width is +-increased by @var{n1}; if it is greater than or equal to @var{s2} the +-width is increased by @var{n2}; if the point size is greater than or +-equal to @var{s1} and less than or equal to @var{s2} the increase in +-width is a linear function of the point size. +- +-The default scaling indicator is @samp{z} for @var{s1} and @var{s2}, +-@samp{p} for @var{n1} and @var{n2}. +- +-Note that the track kerning amount is added even to the rightmost glyph +-in a line; for large values it is thus recommended to increase the line +-length by the same amount to compensate it. +-@endDefreq +- +-Sometimes, when typesetting letters of different fonts, more or less +-space at such boundaries are needed. There are two escapes to help with +-this. +- +-@Defesc {\\/, , , } +-@cindex italic correction (@code{\/}) +-@cindex correction, italic (@code{\/}) +-@cindex correction between italic and roman glyph (@code{\/}, @code{\,}) +-@cindex roman glyph, correction after italic glyph (@code{\/}) +-@cindex italic glyph, correction before roman glyph (@code{\/}) +-@cindex glyph, italic correction (@code{\/}) +-Increase the width of the preceding glyph so that the spacing between +-that glyph and the following glyph is correct if the following glyph is +-a roman glyph. For example, if an italic@tie{}@code{f} is immediately +-followed by a roman right parenthesis, then in many fonts the top right +-portion of the@tie{}@code{f} overlaps the top left of the right +-parenthesis. Use this escape sequence whenever an italic glyph is +-immediately followed by a roman glyph without any intervening space. +-This small amount of space is also called @dfn{italic correction}. +- +-@iftex +-@c can't use @Example...@endExample here +-@example +-@group +-\f[I]f\f[R]) +- @result{} {@it f}@r{)} +-\f[I]f\/\f[R]) +- @result{} @i{f}@r{)} +-@end group +-@end example +-@end iftex +-@endDefesc +- +-@Defesc {\\\,, , , } +-@cindex left italic correction (@code{\,}) +-@cindex correction, left italic (@code{\,}) +-@cindex glyph, left italic correction (@code{\,}) +-@cindex roman glyph, correction before italic glyph (@code{\,}) +-@cindex italic glyph, correction after roman glyph (@code{\,}) +-Modify the spacing of the following glyph so that the spacing between +-that glyph and the preceding glyph is correct if the preceding glyph is +-a roman glyph. Use this escape sequence whenever a roman glyph is +-immediately followed by an italic glyph without any intervening space. +-In analogy to above, this space could be called @dfn{left italic +-correction}, but this term isn't used widely. +- +-@iftex +-@c can't use @Example...@endExample here +-@example +-@group +-q\f[I]f +- @result{} @r{q}@i{f} +-q\,\f[I]f +- @result{} @r{q}@math{@ptexcomma}@i{f} +-@end group +-@end example +-@end iftex +-@endDefesc +- +-@Defesc {\\&, , , } +-Insert a zero-width character, which is invisible. Its intended use is +-to stop interaction of a character with its surrounding. +- +-@itemize @bullet +-@item +-It prevents the insertion of extra space after an end-of-sentence +-character. +- +-@Example +-Test. +-Test. +- @result{} Test. Test. +-Test.\& +-Test. +- @result{} Test. Test. +-@endExample +- +-@item +-It prevents interpretation of a control character at the beginning of an +-input line. +- +-@Example +-.Test +- @result{} warning: `Test' not defined +-\&.Test +- @result{} .Test +-@endExample +- +-@item +-It prevents kerning between two glyphs. +- +-@iftex +-@c can't use @Example...@endExample here +-@example +-@group +-VA +- @result{} @r{VA} +-V\&A +- @result{} @r{V@w{}A} +-@end group +-@end example +-@end iftex +- +-@item +-It is needed to map an arbitrary character to nothing in the @code{tr} +-request (@pxref{Character Translations}). +-@end itemize +-@endDefesc +- +-@Defesc {\\), , , } +-This escape is similar to @code{\&} except that it behaves like a +-character declared with the @code{cflags} request to be transparent for +-the purposes of an end-of-sentence character. +- +-Its main usage is in macro definitions to protect against arguments +-starting with a control character. +- +-@Example +-.de xxx +-\)\\$1 +-.. +-.de yyy +-\&\\$1 +-.. +-This is a test.\c +-.xxx ' +-This is a test. +- @result{}This is a test.' This is a test. +-This is a test.\c +-.yyy ' +-This is a test. +- @result{}This is a test.' This is a test. +-@endExample +-@endDefesc +- +- +-@c ===================================================================== +- +-@node Sizes, Strings, Fonts and Symbols, gtroff Reference +-@section Sizes +-@cindex sizes +- +-@cindex baseline +-@cindex type size +-@cindex size of type +-@cindex vertical spacing +-@cindex spacing, vertical +-@code{gtroff} uses two dimensions with each line of text, type size and +-vertical spacing. The @dfn{type size} is approximately the height of +-the tallest glyph.@footnote{This is usually the parenthesis. Note that +-in most cases the real dimensions of the glyphs in a font are @emph{not} +-related to its type size! For example, the standard @sc{PostScript} +-font families `Times Roman', `Helvetica', and `Courier' can't be used +-together at 10@dmn{pt}; to get acceptable output, the size of +-`Helvetica' has to be reduced by one point, and the size of `Courier' +-must be increased by one point.} @dfn{Vertical spacing} is the amount +-of space @code{gtroff} allows for a line of text; normally, this is +-about 20%@tie{}larger than the current type size. Ratios smaller than +-this can result in hard-to-read text; larger than this, it spreads the +-text out more vertically (useful for term papers). By default, +-@code{gtroff} uses 10@tie{}point type on 12@tie{}point spacing. +- +-@cindex leading +-The difference between type size and vertical spacing is known, by +-typesetters, as @dfn{leading} (this is pronounced `ledding'). +- +-@menu +-* Changing Type Sizes:: +-* Fractional Type Sizes:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Changing Type Sizes, Fractional Type Sizes, Sizes, Sizes +-@subsection Changing Type Sizes +- +-@DefreqList {ps, [@Var{size}]} +-@DefreqItem {ps, @t{+}@Var{size}} +-@DefreqItem {ps, @t{-}@Var{size}} +-@DefescItemx {\\s, , size, } +-@DefregListEndx {.s} +-@cindex changing type sizes (@code{ps}, @code{\s}) +-@cindex type sizes, changing (@code{ps}, @code{\s}) +-@cindex point sizes, changing (@code{ps}, @code{\s}) +-Use the @code{ps} request or the @code{\s} escape to change (increase, +-decrease) the type size (in points). Specify @var{size} as either an +-absolute point size, or as a relative change from the current size. The +-size@tie{}0 (for both @code{.ps} and @code{\s}), or no argument (for +-@code{.ps} only), goes back to the previous size. +- +-Default scaling indicator of @code{size} is @samp{z}. If @code{size} is +-negative, it is set to 1@dmn{u}. +- +-@cindex type size registers (@code{.s}, @code{.ps}) +-@cindex point size registers (@code{.s}, @code{.ps}) +-The read-only number register @code{.s} returns the point size in points +-as a decimal fraction. This is a string. To get the point size in +-scaled points, use the @code{.ps} register instead. +- +-@code{.s} is associated with the current environment +-(@pxref{Environments}). +- +-@Example +-snap, snap, +-.ps +2 +-grin, grin, +-.ps +2 +-wink, wink, \s+2nudge, nudge,\s+8 say no more! +-.ps 10 +-@endExample +- +-The @code{\s} escape may be called in a variety of ways. Much like +-other escapes there must be a way to determine where the argument ends +-and the text begins. Any of the following forms are valid: +- +-@table @code +-@item \s@var{n} +-Set the point size to @var{n}@tie{}points. @var{n}@tie{}must be either +-0 or in the range 4 to@tie{}39. +- +-@item \s+@var{n} +-@itemx \s-@var{n} +-Increase or decrease the point size by @var{n}@tie{}points. +-@var{n}@tie{}must be exactly one digit. +- +-@item \s(@var{nn} +-Set the point size to @var{nn}@tie{}points. @var{nn} must be exactly +-two digits. +- +-@item \s+(@var{nn} +-@itemx \s-(@var{nn} +-@itemx \s(+@var{nn} +-@itemx \s(-@var{nn} +-Increase or decrease the point size by @var{nn}@tie{}points. @var{nn} +-must be exactly two digits. +-@end table +- +-Note that @code{\s} doesn't produce an input token in @code{gtroff}. As +-a consequence, it can be used in requests like @code{mc} (which expects +-a single character as an argument) to change the font on the fly: +- +-@Example +-.mc \s[20]x\s[0] +-@endExample +- +-@xref{Fractional Type Sizes}, for yet another syntactical form of using +-the @code{\s} escape. +-@endDefreq +- +-@Defreq {sizes, s1 s2 @dots{} sn [0]} +-Some devices may only have certain permissible sizes, in which case +-@code{gtroff} rounds to the nearest permissible size. The @file{DESC} +-file specifies which sizes are permissible for the device. +- +-Use the @code{sizes} request to change the permissible sizes for the +-current output device. Arguments are in scaled points; the +-@code{sizescale} line in the @file{DESC} file for the output device +-provides the scaling factor. For example, if the scaling factor is +-1000, then the value 12000 is 12@tie{}points. +- +-Each argument can be a single point size (such as @samp{12000}), or a +-range of sizes (such as @samp{4000-72000}). You can optionally end the +-list with a zero. +-@endDefreq +- +-@DefreqList {vs, [@Var{space}]} +-@DefreqItem {vs, @t{+}@Var{space}} +-@DefreqItem {vs, @t{-}@Var{space}} +-@DefregListEndx {.v} +-@cindex changing vertical line spacing (@code{vs}) +-@cindex vertical line spacing, changing (@code{vs}) +-@cindex vertical line spacing register (@code{.v}) +-Change (increase, decrease) the vertical spacing by @var{space}. The +-default scaling indicator is @samp{p}. +- +-If @code{vs} is called without an argument, the vertical spacing is +-reset to the previous value before the last call to @code{vs}. +- +-@cindex @code{.V} register, and @code{vs} +-@code{gtroff} creates a warning of type @samp{range} if @var{space} is +-negative; the vertical spacing is then set to smallest positive value, +-the vertical resolution (as given in the @code{.V} register). +- +-Note that @w{@samp{.vs 0}} isn't saved in a diversion since it doesn't +-result in a vertical motion. You explicitly have to repeat this command +-before inserting the diversion. +- +-The read-only number register @code{.v} contains the current vertical +-spacing; it is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@cindex vertical line spacing, effective value +-The effective vertical line spacing consists of four components. +-Breaking a line causes the following actions (in the given order). +- +-@itemize @bullet +-@item +-@cindex extra pre-vertical line space (@code{\x}) +-@cindex line space, extra pre-vertical (@code{\x}) +-Move the current point vertically by the @dfn{extra pre-vertical line +-space}. This is the minimum value of all @code{\x} escapes with a +-negative argument in the current output line. +- +-@item +-Move the current point vertically by the vertical line spacing as set +-with the @code{vs} request. +- +-@item +-Output the current line. +- +-@item +-@cindex extra post-vertical line space (@code{\x}) +-@cindex line space, extra post-vertical (@code{\x}) +-Move the current point vertically by the @dfn{extra post-vertical line +-space}. This is the maximum value of all @code{\x} escapes with a +-positive argument in the line that has just been output. +- +-@item +-@cindex post-vertical line spacing +-@cindex line spacing, post-vertical (@code{pvs}) +-Move the current point vertically by the @dfn{post-vertical line +-spacing} as set with the @code{pvs} request. +-@end itemize +- +-@cindex double-spacing (@code{vs}, @code{pvs}) +-It is usually better to use @code{vs} or @code{pvs} instead of @code{ls} +-to produce double-spaced documents: @code{vs} and @code{pvs} have a +-finer granularity for the inserted vertical space compared to @code{ls}; +-furthermore, certain preprocessors assume single-spacing. +- +-@xref{Manipulating Spacing}, for more details on the @code{\x} escape +-and the @code{ls} request. +- +-@DefreqList {pvs, [@Var{space}]} +-@DefreqItem {pvs, @t{+}@Var{space}} +-@DefreqItem {pvs, @t{-}@Var{space}} +-@DefregListEndx {.pvs} +-@cindex @code{ls} request, alternative to (@code{pvs}) +-@cindex post-vertical line spacing, changing (@code{pvs}) +-@cindex post-vertical line spacing register (@code{.pvs}) +-Change (increase, decrease) the post-vertical spacing by @var{space}. +-The default scaling indicator is @samp{p}. +- +-If @code{pvs} is called without an argument, the post-vertical spacing +-is reset to the previous value before the last call to @code{pvs}. +- +-@code{gtroff} creates a warning of type @samp{range} if @var{space} is +-zero or negative; the vertical spacing is then set to zero. +- +-The read-only number register @code{.pvs} contains the current +-post-vertical spacing; it is associated with the current environment +-(@pxref{Environments}). +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Fractional Type Sizes, , Changing Type Sizes, Sizes +-@subsection Fractional Type Sizes +-@cindex fractional type sizes +-@cindex fractional point sizes +-@cindex type sizes, fractional +-@cindex point sizes, fractional +-@cindex sizes, fractional +- +-@cindex @code{s} unit +-@cindex unit, @code{s} +-@cindex @code{z} unit +-@cindex unit, @code{z} +-@cindex @code{ps} request, with fractional type sizes +-@cindex @code{cs} request, with fractional type sizes +-@cindex @code{tkf} request, with fractional type sizes +-@cindex @code{\H}, with fractional type sizes +-@cindex @code{\s}, with fractional type sizes +-A @dfn{scaled point} is equal to @math{1/@var{sizescale}} points, where +-@var{sizescale} is specified in the @file{DESC} file (1@tie{}by +-default). There is a new scale indicator @samp{z}, which has the effect +-of multiplying by @var{sizescale}. Requests and escape sequences in +-@code{gtroff} interpret arguments that represent a point size as being +-in units of scaled points, but they evaluate each such argument using a +-default scale indicator of @samp{z}. Arguments treated in this way are +-the argument to the @code{ps} request, the third argument to the +-@code{cs} request, the second and fourth arguments to the @code{tkf} +-request, the argument to the @code{\H} escape sequence, and those +-variants of the @code{\s} escape sequence that take a numeric expression +-as their argument (see below). +- +-For example, suppose @var{sizescale} is@tie{}1000; then a scaled point +-is equivalent to a millipoint; the request @w{@samp{.ps 10.25}} is +-equivalent to @w{@samp{.ps 10.25z}} and thus sets the point size to +-10250@tie{}scaled points, which is equal to 10.25@tie{}points. +- +-@code{gtroff} disallows the use of the @samp{z} scale indicator in +-instances where it would make no sense, such as a numeric expression +-whose default scale indicator was neither @samp{u} nor @samp{z}. +-Similarly it would make no sense to use a scaling indicator other than +-@samp{z} or @samp{u} in a numeric expression whose default scale +-indicator was @samp{z}, and so @code{gtroff} disallows this as well. +- +-There is also new scale indicator @samp{s}, which multiplies by the +-number of units in a scaled point. So, for example, @samp{\n[.ps]s} is +-equal to @samp{1m}. Be sure not to confuse the @samp{s} and @samp{z} +-scale indicators. +- +-@Defreg {.ps} +-A read-only number register returning the point size in scaled points. +- +-@code{.ps} is associated with the current environment +-(@pxref{Environments}). +-@endDefreg +- +-@DefregList {.psr} +-@DefregListEndx {.sr} +-@cindex last-requested point size registers (@code{.psr}, @code{.sr}) +-@cindex point size registers, last-requested (@code{.psr}, @code{.sr}) +-@cindex @code{.ps} register, in comparison with @code{.psr} +-@cindex @code{.s} register, in comparison with @code{.sr} +-The last-requested point size in scaled points is contained in the +-@code{.psr} read-only number register. The last requested point size in +-points as a decimal fraction can be found in @code{.sr}. This is a +-string-valued read-only number register. +- +-Note that the requested point sizes are device-independent, whereas the +-values returned by the @code{.ps} and @code{.s} registers are not. For +-example, if a point size of 11@dmn{pt} is requested, and a @code{sizes} +-request (or a @code{sizescale} line in a @file{DESC} file) specifies +-10.95@dmn{pt} instead, this value is actually used. +- +-Both registers are associated with the current environment +-(@pxref{Environments}). +-@endDefreg +- +-The @code{\s} escape has the following syntax for working with +-fractional type sizes: +- +-@table @code +-@item \s[@var{n}] +-@itemx \s'@var{n}' +-Set the point size to @var{n}@tie{}scaled points; @var{n}@tie{}is a +-numeric expression with a default scale indicator of @samp{z}. +- +-@item \s[+@var{n}] +-@itemx \s[-@var{n}] +-@itemx \s+[@var{n}] +-@itemx \s-[@var{n}] +-@itemx \s'+@var{n}' +-@itemx \s'-@var{n}' +-@itemx \s+'@var{n}' +-@itemx \s-'@var{n}' +-Increase or or decrease the point size by @var{n}@tie{}scaled points; +-@var{n}@tie{}is a numeric expression (which may start with a minus sign) +-with a default scale indicator of @samp{z}. +-@end table +- +-@xref{Font Files}. +- +- +-@c ===================================================================== +- +-@node Strings, Conditionals and Loops, Sizes, gtroff Reference +-@section Strings +-@cindex strings +- +-@code{gtroff} has string variables, which are entirely for user +-convenience (i.e.@: there are no built-in strings exept @code{.T}, but +-even this is a read-write string variable). +- +-Although the following requests can be used to create strings, +-simply using an undefined string will cause it to be defined as empty. +-@xref{Identifiers}. +- +-@DefreqList {ds, name [@Var{string}]} +-@DefreqItemx {ds1, name [@Var{string}]} +-@DefescItemx {\\*, , n, } +-@DefescItem {\\*, @Lparen{}, nm, } +-@DefescListEnd {\\*, @Lbrack{}, name arg1 arg2 @dots{}, @Rbrack{}} +-@cindex string interpolation (@code{\*}) +-@cindex string expansion (@code{\*}) +-@cindex interpolation of strings (@code{\*}) +-@cindex expansion of strings (@code{\*}) +-@cindex string arguments +-@cindex arguments, of strings +-Define and access a string variable @var{name} (one-character +-name@tie{}@var{n}, two-character name @var{nm}). If @var{name} already +-exists, @code{ds} overwrites the previous definition. Only the syntax +-form using brackets can take arguments that are handled identically to +-macro arguments; the single exception is that a closing bracket as an +-argument must be enclosed in double quotes. @xref{Request and Macro +-Arguments}, and @ref{Parameters}. +- +-Example: +- +-@Example +-.ds foo a \\$1 test +-. +-This is \*[foo nice]. +- @result{} This is a nice test. +-@endExample +- +-The @code{\*} escape @dfn{interpolates} (expands in-place) a +-previously-defined string variable. To be more precise, the stored +-string is pushed onto the input stack, which is then parsed by +-@code{gtroff}. Similar to number registers, it is possible to nest +-strings, i.e., string variables can be called within string variables. +- +-If the string named by the @code{\*} escape does not exist, it is +-defined as empty, and a warning of type @samp{mac} is emitted (see +-@ref{Debugging}, for more details). +- +-@cindex comments, with @code{ds} +-@cindex @code{ds} request, and comments +-@strong{Caution:} Unlike other requests, the second argument to the +-@code{ds} request takes up the entire line including trailing spaces. +-This means that comments on a line with such a request can introduce +-unwanted space into a string. +- +-@Example +-.ds UX \s-1UNIX\s0\u\s-3tm\s0\d \" UNIX trademark +-@endExample +- +-@noindent +-Instead the comment should be put on another line or have the comment +-escape adjacent with the end of the string. +- +-@Example +-.ds UX \s-1UNIX\s0\u\s-3tm\s0\d\" UNIX trademark +-@endExample +- +-@cindex trailing quotes +-@cindex quotes, trailing +-@cindex leading spaces with @code{ds} +-@cindex spaces with @code{ds} +-@cindex @code{ds} request, and leading spaces +-To produce leading space the string can be started with a double quote. +-No trailing quote is needed; in fact, any trailing quote is included in +-your string. +- +-@Example +-.ds sign " Yours in a white wine sauce, +-@endExample +- +-@cindex multi-line strings +-@cindex strings, multi-line +-@cindex newline character, in strings, escaping +-@cindex escaping newline characters, in strings +-Strings are not limited to a single line of text. A string can span +-several lines by escaping the newlines with a backslash. The resulting +-string is stored @emph{without} the newlines. +- +-@Example +-.ds foo lots and lots \ +-of text are on these \ +-next several lines +-@endExample +- +-It is not possible to have real newlines in a string. To put a single +-double quote character into a string, use two consecutive double quote +-characters. +- +-The @code{ds1} request turns off compatibility mode while interpreting a +-string. To be more precise, a @dfn{compatibility save} input token is +-inserted at the beginning of the string, and a @dfn{compatibility +-restore} input token at the end. +- +-@Example +-.nr xxx 12345 +-.ds aa The value of xxx is \\n[xxx]. +-.ds1 bb The value of xxx ix \\n[xxx]. +-. +-.cp 1 +-. +-\*(aa +- @result{} warning: number register `[' not defined +- @result{} The value of xxx is 0xxx]. +-\*(bb +- @result{} The value of xxx ix 12345. +-@endExample +- +-@cindex name space, common, of macros, diversions, and strings +-@cindex common name space of macros, diversions, and strings +-@cindex macros, shared name space with strings and diversions +-@cindex strings, shared name space with macros and diversions +-@cindex diversions, shared name space with macros and strings +-Strings, macros, and diversions (and boxes) share the same name space. +-Internally, even the same mechanism is used to store them. This has +-some interesting consequences. For example, it is possible to call a +-macro with string syntax and vice versa. +- +-@Example +-.de xxx +-a funny test. +-.. +-This is \*[xxx] +- @result{} This is a funny test. +- +-.ds yyy a funny test +-This is +-.yyy +- @result{} This is a funny test. +-@endExample +- +-In particular, interpolating a string does not hide existing macro +-arguments. Thus in a macro, a more efficient way of doing +- +-@Example +-.xx \\$@@ +-@endExample +- +-@noindent +-is +- +-@Example +-\\*[xx]\\ +-@endExample +- +-@noindent +-Note that the latter calling syntax doesn't change the value of +-@code{\$0}, which is then inherited from the calling macro. +- +-Diversions and boxes can be also called with string syntax. +- +-Another consequence is that you can copy one-line diversions or boxes to +-a string. +- +-@Example +-.di xxx +-a \fItest\fR +-.br +-.di +-.ds yyy This is \*[xxx]\c +-\*[yyy]. +- @result{} @r{This is a }@i{test}. +-@endExample +- +-@noindent +-As the previous example shows, it is possible to store formatted output +-in strings. The @code{\c} escape prevents the insertion of an +-additional blank line in the output. +- +-Copying diversions longer than a single output line produces unexpected +-results. +- +-@Example +-.di xxx +-a funny +-.br +-test +-.br +-.di +-.ds yyy This is \*[xxx]\c +-\*[yyy]. +- @result{} test This is a funny. +-@endExample +- +-Usually, it is not predictable whether a diversion contains one or more +-output lines, so this mechanism should be avoided. With @acronym{UNIX} +-@code{troff}, this was the only solution to strip off a final newline +-from a diversion. Another disadvantage is that the spaces in the copied +-string are already formatted, making them unstretchable. This can cause +-ugly results. +- +-@cindex stripping final newline in diversions +-@cindex diversion, stripping final newline +-@cindex final newline, stripping in diversions +-@cindex newline, final, stripping in diversions +-@cindex horizontal space, unformatting +-@cindex space, horizontal, unformatting +-@cindex unformatting horizontal space +-A clean solution to this problem is available in GNU @code{troff}, using +-the requests @code{chop} to remove the final newline of a diversion, and +-@code{unformat} to make the horizontal spaces stretchable again. +- +-@Example +-.box xxx +-a funny +-.br +-test +-.br +-.box +-.chop xxx +-.unformat xxx +-This is \*[xxx]. +- @result{} This is a funny test. +-@endExample +- +-@xref{Gtroff Internals}, for more information. +-@endDefreq +- +-@DefreqList {as, name [@Var{string}]} +-@DefreqListEndx {as1, name [@Var{string}]} +-@cindex appending to a string (@code{as}) +-@cindex string, appending (@code{as}) +-The @code{as} request is similar to @code{ds} but appends @var{string} +-to the string stored as @var{name} instead of redefining it. If +-@var{name} doesn't exist yet, it is created. +- +-@Example +-.as sign " with shallots, onions and garlic, +-@endExample +- +-The @code{as1} request is similar to @code{as}, but compatibility mode +-is switched off while the appended string is interpreted. To be more +-precise, a @dfn{compatibility save} input token is inserted at the +-beginning of the appended string, and a @dfn{compatibility restore} +-input token at the end. +-@endDefreq +- +-Rudimentary string manipulation routines are given with the next two +-requests. +- +-@Defreq {substring, str n1 [@Var{n2}]} +-@cindex substring (@code{substring}) +-Replace the string named @var{str} with the substring defined by the +-indices @var{n1} and @var{n2}. The first character in the string has +-index@tie{}0. If @var{n2} is omitted, it is implicitly set to the +-largest valid value (the string length minus one). If the index value +-@var{n1} or @var{n2} is negative, it is counted from the end of the +-string, going backwards: The last character has index@tie{}@minus{}1, +-the character before the last character has index@tie{}@minus{}2, etc. +- +-@Example +-.ds xxx abcdefgh +-.substring xxx 1 -4 +-\*[xxx] +- @result{} bcde +-.substring xxx 2 +-\*[xxx] +- @result{} de +-@endExample +-@endDefreq +- +-@Defreq {length, reg str} +-@cindex length of a string (@code{length}) +-@cindex string, length of (@code{length}) +-@cindex @code{length} request, and copy-in mode +-@cindex copy-in mode, and @code{length} request +-@cindex mode, copy-in, and @code{length} request +-Compute the number of characters of @var{str} and return it in the +-number register @var{reg}. If @var{reg} doesn't exist, it is created. +-@code{str} is read in copy mode. +- +-@Example +-.ds xxx abcd\h'3i'efgh +-.length yyy \*[xxx] +-\n[yyy] +- @result{} 14 +-@endExample +-@endDefreq +- +-@Defreq {rn, xx yy} +-@cindex renaming request (@code{rn}) +-@cindex request, renaming (@code{rn}) +-@cindex renaming macro (@code{rn}) +-@cindex macro, renaming (@code{rn}) +-@cindex renaming string (@code{rn}) +-@cindex string, renaming (@code{rn}) +-@cindex renaming diversion (@code{rn}) +-@cindex diversion, renaming (@code{rn}) +-Rename the request, macro, diversion, or string @var{xx} to @var{yy}. +-@endDefreq +- +-@Defreq {rm, xx} +-@cindex removing request (@code{rm}) +-@cindex request, removing (@code{rm}) +-@cindex removing macro (@code{rm}) +-@cindex macro, removing (@code{rm}) +-@cindex removing string (@code{rm}) +-@cindex string, removing (@code{rm}) +-@cindex removing diversion (@code{rm}) +-@cindex diversion, removing (@code{rm}) +-Remove the request, macro, diversion, or string @var{xx}. @code{gtroff} +-treats subsequent invocations as if the object had never been defined. +-@endDefreq +- +-@anchor{als} +-@Defreq {als, new old} +-@cindex alias, string, creating (@code{als}) +-@cindex alias, macro, creating (@code{als}) +-@cindex alias, diversion, creating (@code{als}) +-@cindex creating alias, for string (@code{als}) +-@cindex creating alias, for macro (@code{als}) +-@cindex creating alias, for diversion (@code{als}) +-@cindex string, creating alias (@code{als}) +-@cindex macro, creating alias (@code{als}) +-@cindex diversion, creating alias (@code{als}) +-Create an alias named @var{new} for the request, string, macro, or +-diversion object named @var{old}. The new name and the old name are +-exactly equivalent (it is similar to a hard rather than a soft link). If +-@var{old} is undefined, @code{gtroff} generates a warning of type +-@samp{mac} and ignores the request. +- +-To understand how the @code{als} request works it is probably best to +-think of two different pools: one pool for objects (macros, strings, +-etc.), and another one for names. As soon as an object is defined, +-@code{gtroff} adds it to the object pool, adds its name to the name +-pool, and creates a link between them. When @code{als} creates an +-alias, it adds a new name to the name pool that gets linked to the same +-object as the old name. +- +-Now consider this example. +- +-@Example +-.de foo +-.. +-. +-.als bar foo +-. +-.de bar +-. foo +-.. +-. +-.bar +- @result{} input stack limit exceeded +-@endExample +- +-@noindent +-The definition of macro @code{bar} replaces the old object this name is +-linked to. However, the alias to @code{foo} is still active! In +-other words, @code{foo} is still linked to the same object as +-@code{bar}, and the result of calling @code{bar} is an infinite, +-recursive loop that finally leads to an error. +- +-@cindex alias, string, removing (@code{rm}) +-@cindex alias, macro, removing (@code{rm}) +-@cindex alias, diversion, removing (@code{rm}) +-@cindex removing alias, for string (@code{rm}) +-@cindex removing alias, for macro (@code{rm}) +-@cindex removing alias, for diversion (@code{rm}) +-@cindex string, removing alias (@code{rm}) +-@cindex macro, removing alias (@code{rm}) +-@cindex diversion, removing alias (@code{rm}) +-To undo an alias, simply call @code{rm} on the aliased name. The object +-itself is not destroyed until there are no more aliases. +-@endDefreq +- +-@Defreq {chop, xx} +-Remove (chop) the last character from the macro, string, or diversion +-named @var{xx}. This is useful for removing the newline from the end of +-diversions that are to be interpolated as strings. This command can be +-used repeatedly; see @ref{Gtroff Internals}, for details on nodes +-inserted additionally by @code{gtroff}. +-@endDefreq +- +-@xref{Identifiers}, and @ref{Comments}. +- +- +-@c ===================================================================== +- +-@node Conditionals and Loops, Writing Macros, Strings, gtroff Reference +-@section Conditionals and Loops +-@cindex conditionals and loops +-@cindex loops and conditionals +- +-@menu +-* Operators in Conditionals:: +-* if-else:: +-* while:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Operators in Conditionals, if-else, Conditionals and Loops, Conditionals and Loops +-@subsection Operators in Conditionals +- +-@cindex @code{if} request, operators to use with +-@cindex @code{ie} request, operators to use with +-@cindex @code{while} request, operators to use with +-In @code{if}, @code{ie}, and @code{while} requests, in addition to ordinary +-@ref{Expressions}, there are several more operators available: +- +-@table @code +-@item e +-@itemx o +-True if the current page is even or odd numbered (respectively). +- +-@item n +-@cindex conditional output for terminal (TTY) +-@cindex TTY, conditional output for +-@cindex terminal, conditional output for +-True if the document is being processed in nroff mode (i.e., the +-@code{.nroff} command has been issued). @xref{Troff and Nroff Mode}. +- +-@item t +-True if the document is being processed in troff mode (i.e., the +-@code{.troff} command has been issued). @xref{Troff and Nroff Mode}. +- +-@item v +-Always false. This condition is for compatibility with other +-@code{troff} versions only (identifying a @code{-Tversatec} device). +- +-@item '@var{xxx}'@var{yyy}' +-True if the output produced by @var{xxx} is equal to the output produced +-by @var{yyy}. Other characters can be used in place of the single +-quotes; the same set of delimiters as for the @code{\D} escape is used +-(@pxref{Escapes}). @code{gtroff} formats @var{xxx} and @var{yyy} in +-separate environments; after the comparison the resulting data is +-discarded. +- +-@Example +-.ie "|"\fR|\fP" \ +-true +-.el \ +-false +- @result{} true +-@endExample +- +-@noindent +-The resulting motions, glyph sizes, and fonts have to +-match,@footnote{The created output nodes must be identical. +-@xref{Gtroff Internals}.} and not the individual motion, size, and font +-requests. In the previous example, @samp{|} and @samp{\fR|\fP} both +-result in a roman @samp{|} glyph with the same point size and at the +-same location on the page, so the strings are equal. If +-@samp{.ft@tie{}I} had been added before the @samp{.ie}, the result would +-be ``false'' because (the first) @samp{|} produces an italic @samp{|} +-rather than a roman one. +- +-@cindex string comparison +-@cindex comparison of strings +-To compare strings without processing, surround the data with @code{\?}. +- +-@Example +-.ie "\?|\?"\?\fR|\fP\?" \ +-true +-.el \ +-false +- @result{} false +-@endExample +- +-@cindex @code{\?}, and copy-in mode +-@cindex copy-in mode, and @code{\?} +-@cindex mode, copy-in, and @code{\?} +-@noindent +-Since data protected with @code{\?} is read in copy-in mode it is even +-possible to use incomplete input without causing an error. +- +-@Example +-.ds a \[ +-.ds b \[ +-.ie '\?\*a\?'\?\*b\?' \ +-true +-.el \ +-false +- @result{} true +-@endExample +- +-@item r @var{xxx} +-True if there is a number register named @var{xxx}. +- +-@item d @var{xxx} +-True if there is a string, macro, diversion, or request named @var{xxx}. +- +-@item m @var{xxx} +-True if there is a color named @var{xxx}. +- +-@item c @var{g} +-True if there is a glyph @var{g} available@footnote{The name of this +-conditional operator is a misnomer since it tests names of output +-glyphs.}; @var{g} is either an @acronym{ASCII} character or a special +-character (@code{\N'@var{xxx}'}, @code{\(@var{gg}} or +-@code{\[@var{ggg}]}); the condition is also true if @var{g} has been +-defined by the @code{char} request. +- +-@item F @var{font} +-True if a font named @var{font} exists. @var{font} is handled as if it +-was opened with the @code{ft} request (this is, font translation and +-styles are applied), without actually mounting it. +- +-This test doesn't load the complete font but only its header to verify +-its validity. +- +-@item S @var{style} +-True if style @var{style} has been registered. Font translation is +-applied. +-@end table +- +-Note that these operators can't be combined with other operators like +-@samp{:} or @samp{&}; only a leading @samp{!} (without whitespace +-between the exclamation mark and the operator) can be used to negate the +-result. +- +-@Example +-.nr xxx 1 +-.ie !r xxx \ +-true +-.el \ +-false +- @result{} false +-@endExample +- +-A whitespace after @samp{!} always evaluates to zero (this bizarre +-behaviour is due to compatibility with @acronym{UNIX} @code{troff}). +- +-@Example +-.nr xxx 1 +-.ie ! r xxx \ +-true +-.el \ +-false +- @result{} r xxx true +-@endExample +- +-It is possible to omit the whitespace before the argument to the +-@samp{r}, @samp{d}, and @samp{c} operators. +- +-@xref{Expressions}. +- +-@c --------------------------------------------------------------------- +- +-@node if-else, while, Operators in Conditionals, Conditionals and Loops +-@subsection if-else +-@cindex if-else +- +-@code{gtroff} has if-then-else constructs like other languages, although +-the formatting can be painful. +- +-@Defreq {if, expr anything} +- +-Evaluate the expression @var{expr}, and executes @var{anything} (the +-remainder of the line) if @var{expr} evaluates to a value greater than +-zero (true). @var{anything} is interpreted as though it was on a line +-by itself (except that leading spaces are swallowed). +-@xref{Operators in Conditionals}, for more info. +- +-@Example +-.nr xxx 1 +-.nr yyy 2 +-.if ((\n[xxx] == 1) & (\n[yyy] == 2)) true +- @result{} true +-@endExample +-@endDefreq +- +-@Defreq {nop, anything} +-Executes @var{anything}. This is similar to @code{.if@tie{}1}. +-@endDefreq +- +-@DefreqList {ie, expr anything} +-@DefreqListEndx {el, anything} +-Use the @code{ie} and @code{el} requests to write an if-then-else. The +-first request is the `if' part and the latter is the `else' part. +- +-@Example +-.ie n .ls 2 \" double-spacing in nroff +-.el .ls 1 \" single-spacing in troff +-@endExample +-@endDefreq +- +-@c there is a bug in makeinfo <= 4.1a: you can't have `@{' as an argument +-@c to @deffn +-@c +-@c and in 4.2 you still can't use @{ in macros. +- +-@c @DefescList {\@{, , , } +-@c @DefescListEnd {\@}, , , } +-@deffn Escape @t{\@{} +-@deffnx Escape @t{\@}} +-@esindex \@{ +-@esindex \@} +-@cindex begin of conditional block (@code{\@{}) +-@cindex end of conditional block (@code{\@}}) +-@cindex conditional block, begin (@code{\@{}) +-@cindex conditional block, end (@code{\@}}) +-@cindex block, conditional, begin (@code{\@{}) +-@cindex block, condititional, end (@code{\@}}) +-In many cases, an if (or if-else) construct needs to execute more than +-one request. This can be done using the escapes @code{\@{} (which must +-start the first line) and @code{\@}} (which must end the last line). +- +-@Example +-.ie t \@{\ +-. ds lq `` +-. ds rq '' +-.\@} +-.el \@{\ +-. ds lq "" +-. ds rq "" +-.\@} +-@endExample +-@c @endDefesc +-@end deffn +- +-@xref{Expressions}. +- +-@c --------------------------------------------------------------------- +- +-@node while, , if-else, Conditionals and Loops +-@subsection while +-@cindex while +- +-@code{gtroff} provides a looping construct using the @code{while} +-request, which is used much like the @code{if} (and related) requests. +- +-@Defreq {while, expr anything} +-Evaluate the expression @var{expr}, and repeatedly execute +-@var{anything} (the remainder of the line) until @var{expr} evaluates +-to@tie{}0. +- +-@Example +-.nr a 0 1 +-.while (\na < 9) \@{\ +-\n+a, +-.\@} +-\n+a +- @result{} 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 +-@endExample +- +-Some remarks. +- +-@cindex @code{de} request, and @code{while} +-@itemize @bullet +-@item +-The body of a @code{while} request is treated like the body of a +-@code{de} request: @code{gtroff} temporarily stores it in a macro that +-is deleted after the loop has been exited. It can considerably slow +-down a macro if the body of the @code{while} request (within the macro) +-is large. Each time the macro is executed, the @code{while} body is +-parsed and stored again as a temporary macro. +- +-@Example +-.de xxx +-. nr num 10 +-. while (\\n[num] > 0) \@{\ +-. \" many lines of code +-. nr num -1 +-. \@} +-.. +-@endExample +- +-@cindex recursive macros +-@cindex macros, recursive +-@noindent +-The traditional and ofter better solution (@acronym{UNIX} @code{troff} +-doesn't have the @code{while} request) is to use a recursive macro +-instead that is parsed only once during its definition. +- +-@Example +-.de yyy +-. if (\\n[num] > 0) \@{\ +-. \" many lines of code +-. nr num -1 +-. yyy +-. \@} +-.. +-. +-.de xxx +-. nr num 10 +-. yyy +-.. +-@endExample +- +-@noindent +-Note that the number of available recursion levels is set to@tie{}1000 +-(this is a compile-time constant value of @code{gtroff}). +- +-@item +-The closing brace of a @code{while} body must end a line. +- +-@Example +-.if 1 \@{\ +-. nr a 0 1 +-. while (\n[a] < 10) \@{\ +-. nop \n+[a] +-.\@}\@} +- @result{} unbalanced \@{ \@} +-@endExample +-@end itemize +-@endDefreq +- +-@Defreq {break, } +-@cindex @code{while} request, confusing with @code{br} +-@cindex @code{break} request, in a @code{while} loop +-@cindex @code{continue} request, in a @code{while} loop +-Break out of a @code{while} loop. Be sure not to confuse this with the +-@code{br} request (causing a line break). +-@endDefreq +- +-@Defreq {continue, } +-Finish the current iteration of a @code{while} loop, immediately +-restarting the next iteration. +-@endDefreq +- +-@xref{Expressions}. +- +- +-@c ===================================================================== +- +-@node Writing Macros, Page Motions, Conditionals and Loops, gtroff Reference +-@section Writing Macros +-@cindex writing macros +-@cindex macros, writing +- +-A @dfn{macro} is a collection of text and embedded commands that can be +-invoked multiple times. Use macros to define common operations. +-@xref{Strings}, for a (limited) alternative syntax to call macros. +- +-Although the following requests can be used to create macros, +-simply using an undefined macro will cause it to be defined as empty. +-@xref{Identifiers}. +- +-@DefreqList {de, name [@Var{end}]} +-@DefreqItemx {de1, name [@Var{end}]} +-@DefreqItemx {dei, name [@Var{end}]} +-@DefreqListEndx {dei1, name [@Var{end}]} +-Define a new macro named @var{name}. @code{gtroff} copies subsequent +-lines (starting with the next one) into an internal buffer until it +-encounters the line @samp{..} (two dots). If the optional second +-argument to @code{de} is present it is used as the macro closure +-request instead of @samp{..}. +- +-There can be whitespace after the first dot in the line containing the +-ending token (either @samp{.} or macro @samp{@var{end}}). Don't insert +-a tab character immediately after the @samp{..}, otherwise it isn't +-recognized as the end-of-macro symbol.@footnote{While it is possible to +-define and call a macro @samp{.} with +- +-@Example +-.de . +-. tm foo +-.. +-. +-.. \" This calls macro `.'! +-@endExample +- +-@noindent +-you can't use this as the end-of-macro macro: during a macro definition, +-@samp{..} is never handled as a call to @samp{.}, even if you say +-@samp{.de foo .} explicitly.} +- +-Here a small example macro called @samp{P} that causes a break and +-inserts some vertical space. It could be used to separate paragraphs. +- +-@Example +-.de P +-. br +-. sp .8v +-.. +-@endExample +- +-The following example defines a macro within another. Remember that +-expansion must be protected twice; once for reading the macro and once +-for executing. +- +-@Example +-\# a dummy macro to avoid a warning +-.de end +-.. +-. +-.de foo +-. de bar end +-. nop \f[B]Hallo \\\\$1!\f[] +-. end +-.. +-. +-.foo +-.bar Joe +- @result{} @b{Hallo Joe!} +-@endExample +- +-@noindent +-Since @code{\f} has no expansion, it isn't necessary to protect its +-backslash. Had we defined another macro within @code{bar} that takes a +-parameter, eight backslashes would be necessary before @samp{$1}. +- +-The @code{de1} request turns off compatibility mode while executing the +-macro. On entry, the current compatibility mode is saved and restored +-at exit. +- +-@Example +-.nr xxx 12345 +-. +-.de aa +-The value of xxx is \\n[xxx]. +-.. +-.de1 bb +-The value of xxx ix \\n[xxx]. +-.. +-. +-.cp 1 +-. +-.aa +- @result{} warning: number register `[' not defined +- @result{} The value of xxx is 0xxx]. +-.bb +- @result{} The value of xxx ix 12345. +-@endExample +- +-The @code{dei} request defines a macro indirectly. That is, it expands +-strings whose names are @var{name} or @var{end} before performing the +-append. +- +-This: +- +-@Example +-.ds xx aa +-.ds yy bb +-.dei xx yy +-@endExample +- +-@noindent +-is equivalent to: +- +-@Example +-.de aa bb +-@endExample +- +-The @code{dei1} request is similar to @code{dei} but with compatibility +-mode switched off during execution of the defined macro. +- +-If compatibility mode is on, @code{de} (and @code{dei}) behave similar +-to @code{de1} (and @code{dei1}): A `compatibility save' token is +-inserted at the beginning, and a `compatibility restore' token at the +-end, with compatibility mode switched on during execution. @xref{Gtroff +-Internals}, for more information on switching compatibility mode on and +-off in a single document. +- +-@pindex trace.tmac +-Using @file{trace.tmac}, you can trace calls to @code{de} and +-@code{de1}. +- +-Note that macro identifiers are shared with identifiers for strings and +-diversions. +- +-@xref{als,,the description of the @code{als} request}, for possible +-pitfalls if redefining a macro that has been aliased. +-@endDefreq +- +-@DefreqList {am, name [@Var{end}]} +-@DefreqItemx {am1, name [@Var{end}]} +-@DefreqItemx {ami, name [@Var{end}]} +-@DefreqListEndx {ami1, name [@Var{end}]} +-@cindex appending to a macro (@code{am}) +-@cindex macro, appending (@code{am}) +-Works similarly to @code{de} except it appends onto the macro named +-@var{name}. So, to make the previously defined @samp{P} macro actually +-do indented instead of block paragraphs, add the necessary code to the +-existing macro like this: +- +-@Example +-.am P +-.ti +5n +-.. +-@endExample +- +-The @code{am1} request turns off compatibility mode while executing the +-appended macro piece. To be more precise, a @dfn{compatibility save} +-input token is inserted at the beginning of the appended code, and a +-@dfn{compatibility restore} input token at the end. +- +-The @code{ami} request appends indirectly, meaning that @code{gtroff} +-expands strings whose names are @var{name} or @var{end} before +-performing the append. +- +-The @code{ami1} request is similar to @code{ami} but compatibility mode +-is switched off during execution of the defined macro. +- +-@pindex trace.tmac +-Using @file{trace.tmac}, you can trace calls to @code{am} and +-@code{am1}. +-@endDefreq +- +-@xref{Strings}, for the @code{als} and @code{rn} request to create an +-alias and rename a macro, respectively. +- +-The @code{de}, @code{am}, @code{di}, @code{da}, @code{ds}, and @code{as} +-requests (together with its variants) only create a new object if the +-name of the macro, diversion or string diversion is currently undefined +-or if it is defined to be a request; normally they modify the value of +-an existing object. +- +-@Defreq {return, [@Var{anything}]} +-Exit a macro, immediately returning to the caller. +- +-If called with an argument, exit twice, namely the current macro and the +-macro one level higher. This is used to define a wrapper macro for +-@code{return} in @file{trace.tmac}. +-@endDefreq +- +-@menu +-* Copy-in Mode:: +-* Parameters:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Copy-in Mode, Parameters, Writing Macros, Writing Macros +-@subsection Copy-in Mode +-@cindex copy mode +-@cindex copy-in mode +-@cindex mode, copy +-@cindex mode, copy-in +- +-@cindex @code{\n}, when reading text for a macro +-@cindex @code{\$}, when reading text for a macro +-@cindex @code{\*}, when reading text for a macro +-@cindex @code{\\}, when reading text for a macro +-@cindex \@key{RET}, when reading text for a macro +-When @code{gtroff} reads in the text for a macro, string, or diversion, +-it copies the text (including request lines, but excluding escapes) into +-an internal buffer. Escapes are converted into an internal form, except +-for @code{\n}, @code{\$}, @code{\*}, @code{\\} and @code{\@key{RET}}, +-which are evaluated and inserted into the text where the escape was +-located. This is known as @dfn{copy-in} mode or @dfn{copy} mode. +- +-What this means is that you can specify when these escapes are to be +-evaluated (either at copy-in time or at the time of use) by insulating +-the escapes with an extra backslash. Compare this to the @code{\def} +-and @code{\edef} commands in @TeX{}. +- +-The following example prints the numbers 20 and@tie{}10: +- +-@Example +-.nr x 20 +-.de y +-.nr x 10 +-\&\nx +-\&\\nx +-.. +-.y +-@endExample +- +-@c --------------------------------------------------------------------- +- +-@node Parameters, , Copy-in Mode, Writing Macros +-@subsection Parameters +-@cindex parameters +- +-The arguments to a macro or string can be examined using a variety of +-escapes. +- +-@Defreg {.$} +-@cindex number of arguments register (@code{.$}) +-The number of arguments passed to a macro or string. This is a +-read-only number register. +- +-Note that the @code{shift} request can change its value. +-@endDefreg +- +-Any individual argument can be retrieved with one of the following +-escapes: +- +-@DefescList {\\$, , n, } +-@DefescItem {\\$, @Lparen{}, nn, } +-@DefescListEnd {\\$, @Lbrack{}, nnn, @Rbrack{}} +-@cindex copy-in mode, and macro arguments +-@cindex mode, copy-in, and macro arguments +-@cindex macro, arguments (@code{\$}) +-@cindex arguments, macro (@code{\$}) +-Retrieve the @var{n}@dmn{th}, @var{nn}@dmn{th} or @var{nnn}@dmn{th} +-argument. As usual, the first form only accepts a single number (larger +-than zero), the second a two-digit number (larger or equal to@tie{}10), +-and the third any positive integer value (larger than zero). Macros and +-strings can have an unlimited number of arguments. Note that due to +-copy-in mode, use two backslashes on these in actual use to prevent +-interpolation until the macro is actually invoked. +-@endDefesc +- +-@Defreq {shift, [@Var{n}]} +-Shift the arguments 1@tie{}position, or as many positions as specified +-by its argument. After executing this request, argument@tie{}@var{i} +-becomes argument @math{@var{i}-@var{n}}; arguments 1 to@tie{}@var{n} are +-no longer available. Shifting by negative amounts is currently +-undefined. +- +-The register @code{.$} is adjusted accordingly. +-@endDefreq +- +-@DefescList {\\$*, , , } +-@DefescListEndx {\\$@@, , , } +-In some cases it is convenient to use all of the arguments at once (for +-example, to pass the arguments along to another macro). The @code{\$*} +-escape concatenates all the arguments separated by spaces. A similar +-escape is @code{\$@@}, which concatenates all the arguments with each +-surrounded by double quotes, and separated by spaces. If not in +-compatibility mode, the input level of double quotes is preserved (see +-@ref{Request and Macro Arguments}). +-@endDefesc +- +-@Defesc {\\$^, , , } +-Handle the parameters of a macro as if they were an argument to the +-@code{ds} or similar requests. +- +-@Example +-.de foo +-. tm $1=`\\$1' +-. tm $2=`\\$2' +-. tm $*=`\\$*' +-. tm $@@=`\\$@@' +-. tm $^=`\\$^' +-.. +-.foo " This is a "test" +- @result{} $1=` This is a ' +- @result{} $2=`test"' +- @result{} $*=` This is a test"' +- @result{} $@@=`" This is a " "test""' +- @result{} $^=`" This is a "test"' +-@endExample +- +-This escape is useful mainly for macro packages like @file{trace.tmac}, +-which redefines some requests and macros for debugging purposes. +-@endDefesc +- +-@Defesc {\\$0, , , } +-@cindex macro name register (@code{\$0}) +-@cindex @code{als} request, and @code{\$0} +-The name used to invoke the current macro. The @code{als} request can +-make a macro have more than one name. +- +-If a macro is called as a string (within another macro), the value of +-@code{\$0} isn't changed. +- +-@Example +-.de foo +-. tm \\$0 +-.. +-.als foo bar +-. +-@endExample +-@Example +-.de aaa +-. foo +-.. +-.de bbb +-. bar +-.. +-.de ccc +-\\*[foo]\\ +-.. +-.de ddd +-\\*[bar]\\ +-.. +-. +-@endExample +-@Example +-.aaa +- @result{} foo +-.bbb +- @result{} bar +-.ccc +- @result{} ccc +-.ddd +- @result{} ddd +-@endExample +-@endDefesc +- +-@xref{Request and Macro Arguments}. +- +- +-@c ===================================================================== +- +-@node Page Motions, Drawing Requests, Writing Macros, gtroff Reference +-@section Page Motions +-@cindex page motions +-@cindex motions, page +- +-@xref{Manipulating Spacing}, for a discussion of the main request for +-vertical motion, @code{sp}. +- +-@DefreqList {mk, [@Var{reg}]} +-@DefreqListEndx {rt, [@Var{dist}]} +-@cindex marking vertical page location (@code{mk}) +-@cindex page location, vertical, marking (@code{mk}) +-@cindex location, vertical, page, marking (@code{mk}) +-@cindex vertical page location, marking (@code{mk}) +-@cindex returning to marked vertical page location (@code{rt}) +-@cindex page location, vertical, returning to marked (@code{rt}) +-@cindex location, vertical, page, returning to marked (@code{rt}) +-@cindex vertical page location, returning to marked (@code{rt}) +-The request @code{mk} can be used to mark a location on a page, for +-movement to later. This request takes a register name as an argument in +-which to store the current page location. With no argument it stores +-the location in an internal register. The results of this can be used +-later by the @code{rt} or the @code{sp} request (or the @code{\v} +-escape). +- +-The @code{rt} request returns @emph{upwards} to the location marked with +-the last @code{mk} request. If used with an argument, return to a +-position which distance from the top of the page is @var{dist} (no +-previous call to @code{mk} is necessary in this case). Default scaling +-indicator is @samp{v}. +- +-Here a primitive solution for a two-column macro. +- +-@Example +-.nr column-length 1.5i +-.nr column-gap 4m +-.nr bottom-margin 1m +-. +-@endExample +-@Example +-.de 2c +-. br +-. mk +-. ll \\n[column-length]u +-. wh -\\n[bottom-margin]u 2c-trap +-. nr right-side 0 +-.. +-. +-@endExample +-@Example +-.de 2c-trap +-. ie \\n[right-side] \@{\ +-. nr right-side 0 +-. po -(\\n[column-length]u + \\n[column-gap]u) +-. \" remove trap +-. wh -\\n[bottom-margin]u +-. \@} +-. el \@{\ +-. \" switch to right side +-. nr right-side 1 +-. po +(\\n[column-length]u + \\n[column-gap]u) +-. rt +-. \@} +-.. +-. +-@endExample +-@Example +-.pl 1.5i +-.ll 4i +-This is a small test that shows how the +-rt request works in combination with mk. +- +-.2c +-Starting here, text is typeset in two columns. +-Note that this implementation isn't robust +-and thus not suited for a real two-column +-macro. +-@endExample +- +-Result: +- +-@Example +-This is a small test that shows how the +-rt request works in combination with mk. +- +-Starting here, isn't robust +-text is typeset and thus not +-in two columns. suited for a +-Note that this real two-column +-implementation macro. +-@endExample +-@endDefreq +- +-The following escapes give fine control of movements about the page. +- +-@Defesc {\\v, ', e, '} +-@cindex vertical motion (@code{\v}) +-@cindex motion, vertical (@code{\v}) +-Move vertically, usually from the current location on the page (if no +-absolute position operator @samp{|} is used). The argument@tie{}@var{e} +-specifies the distance to move; positive is downwards and negative +-upwards. The default scaling indicator for this escape is @samp{v}. +-Beware, however, that @code{gtroff} continues text processing at the +-point where the motion ends, so you should always balance motions to +-avoid interference with text processing. +- +-@code{\v} doesn't trigger a trap. This can be quite useful; for +-example, consider a page bottom trap macro that prints a marker in the +-margin to indicate continuation of a footnote or something similar. +-@endDefesc +- +-There are some special-case escapes for vertical motion. +- +-@Defesc {\\r, , , } +-Move upwards@tie{}1@dmn{v}. +-@endDefesc +- +-@Defesc {\\u, , , } +-Move upwards@tie{}.5@dmn{v}. +-@endDefesc +- +-@Defesc {\\d, , , } +-Move down@tie{}.5@dmn{v}. +-@endDefesc +- +-@Defesc {\\h, ', e, '} +-@cindex inserting horizontal space (@code{\h}) +-@cindex horizontal space (@code{\h}) +-@cindex space, horizontal (@code{\h}) +-@cindex horizontal motion (@code{\h}) +-@cindex motion, horizontal (@code{\h}) +-Move horizontally, usually from the current location (if no absolute +-position operator @samp{|} is used). The expression@tie{}@var{e} +-indicates how far to move: positive is rightwards and negative +-leftwards. The default scaling indicator for this escape is @samp{m}. +- +-This horizontal space is not discarded at the end of a line. To insert +-discardable space of a certain length use the @code{ss} request. +-@endDefesc +- +-There are a number of special-case escapes for horizontal motion. +- +-@Defesc {\\@key{SP}, , , } +-@cindex space, unbreakable +-@cindex unbreakable space +-An unbreakable and unpaddable (i.e.@: not expanded during filling) +-space. (Note: This is a backslash followed by a space.) +-@endDefesc +- +-@Defesc {\\~, , , } +-An unbreakable space that stretches like a normal inter-word space when +-a line is adjusted. +-@endDefesc +- +-@Defesc {\\|, , , } +-A 1/6@dmn{th} em space. Ignored for TTY output devices (rounded to +-zero). +- +-However, if there is a glyph defined in the current font file with name +-@code{\|} (note the leading backslash), the width of this glyph is used +-instead (even for TTYs). +-@endDefesc +- +-@Defesc {\\^, , , } +-A 1/12@dmn{th} em space. Ignored for TTY output devices (rounded to +-zero). +- +-However, if there is a glyph defined in the current font file with name +-@code{\^} (note the leading backslash), the width of this glyph is used +-instead (even for TTYs). +-@endDefesc +- +-@Defesc {\\0, , , } +-@cindex space, width of a digit (@code{\0}) +-@cindex digit width space (@code{\0}) +-A space the size of a digit. +-@endDefesc +- +-The following string sets the @TeX{} logo: +- +-@Example +-.ds TeX T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X +-@endExample +- +-@DefescList {\\w, ', text, '} +-@DefregItemx {st} +-@DefregItemx {sb} +-@DefregItemx {rst} +-@DefregItemx {rsb} +-@DefregItemx {ct} +-@DefregItemx {ssc} +-@DefregListEndx {skw} +-@cindex width escape (@code{\w}) +-Return the width of the specified @var{text} in basic units. This +-allows horizontal movement based on the width of some arbitrary text +-(e.g.@: given as an argument to a macro). +- +-@Example +-The length of the string `abc' is \w'abc'u. +- @result{} The length of the string `abc' is 72u. +-@endExample +- +-Font changes may occur in @var{text}, which don't affect current +-settings. +- +-After use, @code{\w} sets several registers: +- +-@table @code +-@item st +-@itemx sb +-The highest and lowest point of the baseline, respectively, in +-@var{text}. +- +-@item rst +-@itemx rsb +-Like the @code{st} and @code{sb} registers, but takes account of the +-heights and depths of glyphs. In other words, this gives the highest +-and lowest point of @var{text}. Values below the baseline are negative. +- +-@item ct +-Defines the kinds of glyphs occurring in @var{text}: +- +-@table @asis +-@item 0 +-only short glyphs, no descenders or tall glyphs. +- +-@item 1 +-at least one descender. +- +-@item 2 +-at least one tall glyph. +- +-@item 3 +-at least one each of a descender and a tall glyph. +-@end table +- +-@item ssc +-The amount of horizontal space (possibly negative) that should be added +-to the last glyph before a subscript. +- +-@item skw +-How far to right of the center of the last glyph in the @code{\w} +-argument, the center of an accent from a roman font should be placed +-over that glyph. +-@end table +-@endDefesc +- +-@DefescList {\\k, , p, } +-@DefescItem {\\k, @Lparen{}, ps, } +-@DefescListEnd {\\k, @Lbrack{}, position, @Rbrack{}} +-@cindex saving horizontal input line position (@code{\k}) +-@cindex horizontal input line position, saving (@code{\k}) +-@cindex input line position, horizontal, saving (@code{\k}) +-@cindex position, horizontal input line, saving (@code{\k}) +-@cindex line, input, horizontal position, saving (@code{\k}) +-Store the current horizontal position in the @emph{input} line in number +-register with name @var{position} (one-character name@tie{}@var{p}, +-two-character name @var{ps}). Use this, for example, to return to the +-beginning of a string for highlighting or other decoration. +-@endDefesc +- +-@Defreg {hp} +-@cindex horizontal input line position register (@code{hp}) +-@cindex input line, horizontal position, register (@code{hp}) +-@cindex position, horizontal, in input line, register (@code{hp}) +-@cindex line, input, horizontal position, register (@code{hp}) +-The current horizontal position at the input line. +-@endDefreg +- +-@Defreg {.k} +-@cindex horizontal output line position register (@code{.k}) +-@cindex output line, horizontal position, register (@code{.k}) +-@cindex position, horizontal, in output line, register (@code{.k}) +-@cindex line, output, horizontal position, register (@code{.k}) +-A read-only number register containing the current horizontal output +-position (relative to the current indentation). +-@endDefreg +- +-@Defesc {\\o, ', abc, '} +-@cindex overstriking glyphs (@code{\o}) +-@cindex glyphs, overstriking (@code{\o}) +-Overstrike glyphs @var{a}, @var{b}, @var{c}, @dots{}; the glyphs are +-centered, and the resulting spacing is the largest width of the affected +-glyphs. +-@endDefesc +- +-@Defesc {\\z, , g, } +-@cindex zero-width printing (@code{\z}, @code{\Z}) +-@cindex printing, zero-width (@code{\z}, @code{\Z}) +-Print glyph @var{g} with zero width, i.e., without spacing. Use this to +-overstrike glyphs left-aligned. +-@endDefesc +- +-@Defesc {\\Z, ', anything, '} +-@cindex zero-width printing (@code{\z}, @code{\Z}) +-@cindex printing, zero-width (@code{\z}, @code{\Z}) +-Print @var{anything}, then restore the horizontal and vertical position. +-The argument may not contain tabs or leaders. +- +-The following is an example of a strike-through macro: +- +-@Example +-.de ST +-.nr ww \w'\\$1' +-\Z@@\v'-.25m'\l'\\n[ww]u'@@\\$1 +-.. +-. +-This is +-.ST "a test" +-an actual emergency! +-@endExample +-@endDefesc +- +- +-@c ===================================================================== +- +-@node Drawing Requests, Traps, Page Motions, gtroff Reference +-@section Drawing Requests +-@cindex drawing requests +-@cindex requests for drawing +- +-@code{gtroff} provides a number of ways to draw lines and other figures +-on the page. Used in combination with the page motion commands (see +-@ref{Page Motions}, for more info), a wide variety of figures can be +-drawn. However, for complex drawings these operations can be quite +-cumbersome, and it may be wise to use graphic preprocessors like +-@code{gpic} or @code{ggrn}. @xref{gpic}, and @ref{ggrn}, for more +-information. +- +-All drawing is done via escapes. +- +-@DefescList {\\l, ', l, '} +-@DefescListEnd {\\l, ', lg, '} +-@cindex drawing horizontal lines (@code{\l}) +-@cindex horizontal line, drawing (@code{\l}) +-@cindex line, horizontal, drawing (@code{\l}) +-Draw a line horizontally. @var{l} is the length of the line to be +-drawn. If it is positive, start the line at the current location and +-draw to the right; its end point is the new current location. Negative +-values are handled differently: The line starts at the current location +-and draws to the left, but the current location doesn't move. +- +-@var{l} can also be specified absolutely (i.e.@: with a leading +-@samp{|}), which draws back to the beginning of the input line. Default +-scaling indicator is @samp{m}. +- +-@cindex underscore glyph (@code{\[ru]}) +-@cindex glyph, underscore (@code{\[ru]}) +-@cindex line drawing glyph +-@cindex glyph, for line drawing +-The optional second parameter@tie{}@var{g} is a glyph to draw the line +-with. If this second argument is not specified, @code{gtroff} uses the +-underscore glyph, @code{\[ru]}. +- +-@cindex zero width space character (@code{\&}) +-@cindex character, zero width space (@code{\&}) +-@cindex space character, zero width (@code{\&}) +-To separate the two arguments (to prevent @code{gtroff} from +-interpreting a drawing glyph as a scaling indicator if the glyph is +-represented by a single character) use @code{\&}. +- +-Here a small useful example: +- +-@Example +-.de box +-\[br]\\$*\[br]\l'|0\[rn]'\l'|0\[ul]' +-.. +-@endExample +- +-@noindent +-Note that this works by outputting a box rule (a vertical line), then +-the text given as an argument and then another box rule. Finally, the +-line drawing escapes both draw from the current location to the +-beginning of the @emph{input} line -- this works because the line length +-is negative, not moving the current point. +-@endDefesc +- +-@DefescList {\\L, ', l, '} +-@DefescListEnd {\\L, ', lg, '} +-@cindex drawing vertical lines (@code{\L}) +-@cindex vertical line drawing (@code{\L}) +-@cindex line, vertical, drawing (@code{\L}) +-@cindex line drawing glyph +-@cindex glyph for line drawing +-@cindex box rule glyph (@code{\[br]}) +-@cindex glyph, box rule (@code{\[br]}) +-Draw vertical lines. Its parameters are similar to the @code{\l} +-escape, except that the default scaling indicator is @samp{v}. The +-movement is downwards for positive values, and upwards for negative +-values. The default glyph is the box rule glyph, @code{\[br]}. As with +-the vertical motion escapes, text processing blindly continues where the +-line ends. +- +-@Example +-This is a \L'3v'test. +-@endExample +- +-@noindent +-Here the result, produced with @code{grotty}. +- +-@Example +-This is a +- | +- | +- |test. +-@endExample +-@endDefesc +- +-@Defesc {\\D, ', command arg @dots{}, '} +-The @code{\D} escape provides a variety of drawing functions. Note that +-on character devices, only vertical and horizontal lines are supported +-within @code{grotty}; other devices may only support a subset of the +-available drawing functions. +- +-The default scaling indicator for all subcommands of @code{\D} is +-@samp{m} for horizontal distances and @samp{v} for vertical ones. +-Exceptions are @w{@code{\D'f @dots{}'}} and @w{@code{\D't @dots{}'}}, +-which use @code{u} as the default, and @w{@code{\D'F@var{x} @dots{}'}}, +-which arguments are treated similar to the @code{defcolor} request. +- +-@table @code +-@item \D'l @var{dx} @var{dy}' +-@cindex line, drawing (@w{@code{\D'l @dots{}'}}) +-@cindex drawing a line (@w{@code{\D'l @dots{}'}}) +-Draw a line from the current location to the relative point specified by +-(@var{dx},@var{dy}), where positive values mean down and right, +-respectively. The end point of the line is the new current location. +- +-The following example is a macro for creating a box around a text +-string; for simplicity, the box margin is taken as a fixed value, +-0.2@dmn{m}. +- +-@Example +-.de BOX +-. nr @@wd \w'\\$1' +-\h'.2m'\ +-\h'-.2m'\v'(.2m - \\n[rsb]u)'\ +-\D'l 0 -(\\n[rst]u - \\n[rsb]u + .4m)'\ +-\D'l (\\n[@@wd]u + .4m) 0'\ +-\D'l 0 (\\n[rst]u - \\n[rsb]u + .4m)'\ +-\D'l -(\\n[@@wd]u + .4m) 0'\ +-\h'.2m'\v'-(.2m - \\n[rsb]u)'\ +-\\$1\ +-\h'.2m' +-.. +-@endExample +- +-@noindent +-First, the width of the string is stored in register @code{@@wd}. Then, +-four lines are drawn to form a box, properly offset by the box margin. +-The registers @code{rst} and @code{rsb} are set by the @code{\w} escape, +-containing the largest height and depth of the whole string. +- +-@item \D'c @var{d}' +-@cindex circle, drawing (@w{@code{\D'c @dots{}'}}) +-@cindex drawing a circle (@w{@code{\D'c @dots{}'}}) +-Draw a circle with a diameter of@tie{}@var{d} with the leftmost point at +-the current position. After drawing, the current location is positioned +-at the rightmost point of the circle. +- +-@item \D'C @var{d}' +-@cindex circle, solid, drawing (@w{@code{\D'C @dots{}'}}) +-@cindex drawing a solid circle (@w{@code{\D'C @dots{}'}}) +-@cindex solid circle, drawing (@w{@code{\D'C @dots{}'}}) +-Draw a solid circle with the same parameters and behaviour as an +-outlined circle. No outline is drawn. +- +-@item \D'e @var{x} @var{y}' +-@cindex drawing an ellipse (@w{@code{\D'e @dots{}'}}) +-@cindex ellipse, drawing (@w{@code{\D'e @dots{}'}}) +-Draw an ellipse with a horizontal diameter of @var{x} and a vertical +-diameter of @var{y} with the leftmost point at the current position. +-After drawing, the current location is positioned at the rightmost point +-of the ellipse. +- +-@item \D'E @var{x} @var{y}' +-@cindex ellipse, solid, drawing (@w{@code{\D'E @dots{}'}}) +-@cindex drawing a solid ellipse (@w{@code{\D'E @dots{}'}}) +-@cindex solid ellipse, drawing (@w{@code{\D'E @dots{}'}}) +-Draw a solid ellipse with the same parameters and behaviour as an +-outlined ellipse. No outline is drawn. +- +-@item \D'a @var{dx1} @var{dy1} @var{dx2} @var{dy2}' +-@cindex arc, drawing (@w{@code{\D'a @dots{}'}}) +-@cindex drawing an arc (@w{@code{\D'a @dots{}'}}) +-Draw an arc clockwise from the current location through the two +-specified relative locations (@var{dx1},@var{dy1}) and +-(@var{dx2},@var{dy2}). The coordinates of the first point are relative +-to the current position, and the coordinates of the second point are +-relative to the first point. After drawing, the current position is +-moved to the final point of the arc. +- +-@item \D'~ @var{dx1} @var{dy1} @var{dx2} @var{dy2} @dots{}' +-@cindex drawing a spline (@w{@code{\D'~ @dots{}'}}) +-@cindex spline, drawing (@w{@code{\D'~ @dots{}'}}) +-Draw a spline from the current location to the relative point +-(@var{dx1},@var{dy1}) and then to (@var{dx2},@var{dy2}), and so on. The +-current position is moved to the terminal point of the drawn curve. +- +-@item \D'f @var{n}' +-@cindex gray shading (@w{@code{\D'f @dots{}'}}) +-@cindex shading filled objects (@w{@code{\D'f @dots{}'}}) +-Set the shade of gray to be used for filling solid objects +-to@tie{}@var{n}; @var{n}@tie{}must be an integer between 0 +-and@tie{}1000, where 0 corresponds solid white and 1000 to solid black, +-and values in between correspond to intermediate shades of gray. This +-applies only to solid circles, solid ellipses, and solid polygons. By +-default, a level of 1000 is used. +- +-Despite of being silly, the current point is moved horizontally to the +-right by@tie{}@var{n}. +- +-@cindex @w{@code{\D'f @dots{}'}} and horizontal resolution +-Don't use this command! It has the serious drawback that it is always +-rounded to the next integer multiple of the horizontal resolution (the +-value of the @code{hor} keyword in the @file{DESC} file). Use @code{\M} +-(@pxref{Colors}) or @w{@code{\D'Fg @dots{}'}} instead. +- +-@item \D'p @var{dx1} @var{dy1} @var{dx2} @var{dy2} @dots{}' +-@cindex drawing a polygon (@w{@code{\D'p @dots{}'}}) +-@cindex polygon, drawing (@w{@code{\D'p @dots{}'}}) +-Draw a polygon from the current location to the relative position +-(@var{dx1},@var{dy1}) and then to (@var{dx2},@var{dy2}) and so on. When +-the specified data points are exhausted, a line is drawn back to the +-starting point. The current position is changed by adding the sum of +-all arguments with odd index to the actual horizontal position and the +-even ones to the vertical position. +- +-@item \D'P @var{dx1} @var{dy1} @var{dx2} @var{dy2} @dots{}' +-@cindex polygon, solid, drawing (@w{@code{\D'P @dots{}'}}) +-@cindex drawing a solid polygon (@w{@code{\D'P @dots{}'}}) +-@cindex solid polygon, drawing (@w{@code{\D'P @dots{}'}}) +-Draw a solid polygon with the same parameters and behaviour as an +-outlined polygon. No outline is drawn. +- +-Here a better variant of the box macro to fill the box with some color. +-Note that the box must be drawn before the text since colors in +-@code{gtroff} are not transparent; the filled polygon would hide the +-text completely. +- +-@Example +-.de BOX +-. nr @@wd \w'\\$1' +-\h'.2m'\ +-\h'-.2m'\v'(.2m - \\n[rsb]u)'\ +-\M[lightcyan]\ +-\D'P 0 -(\\n[rst]u - \\n[rsb]u + .4m) \ +- (\\n[@@wd]u + .4m) 0 \ +- 0 (\\n[rst]u - \\n[rsb]u + .4m) \ +- -(\\n[@@wd]u + .4m) 0'\ +-\h'.2m'\v'-(.2m - \\n[rsb]u)'\ +-\M[]\ +-\\$1\ +-\h'.2m' +-.. +-@endExample +- +-If you want a filled polygon that has exactly the same size as an +-unfilled one, you must draw both an unfilled and a filled polygon. A +-filled polygon is always smaller than an unfilled one because the latter +-uses straight lines with a given line thickness to connect the polygon's +-corners, while the former simply fills the area defined by the +-coordinates. +- +-@Example +-\h'1i'\v'1i'\ +-\# increase line thickness +-\Z'\D't 5p''\ +-\# draw unfilled polygon +-\Z'\D'p 3 3 -6 0''\ +-\# draw filled polygon +-\Z'\D'P 3 3 -6 0'' +-@endExample +- +-@item \D't @var{n}' +-@cindex line thickness (@w{@code{\D't @dots{}'}}) +-@cindex thickness of lines (@w{@code{\D't @dots{}'}}) +-Set the current line thickness to @var{n}@tie{}machine units. A value +-of zero selects the smallest available line thickness. A negative value +-makes the line thickness proportional to the current point size (this is +-the default behaviour of @acronym{AT&T} @code{troff}). +- +-Despite of being silly, the current point is moved horizontally to the +-right by@tie{}@var{n}. +- +-@item \D'F@var{scheme} @var{color_components}' +-@cindex unnamed fill colors (@code{\D'F@dots{}'}) +-@cindex fill colors, unnamed (@code{\D'F@dots{}'}) +-@cindex colors, fill, unnamed (@code{\D'F@dots{}'}) +-Change current fill color. @var{scheme} is a single letter denoting the +-color scheme: @samp{r} (rgb), @samp{c} (cmy), @samp{k} (cmyk), @samp{g} +-(gray), or @samp{d} (default color). The color components use exactly +-the same syntax as in the @code{defcolor} request (@pxref{Colors}); the +-command @code{\D'Fd'} doesn't take an argument. +- +-@emph{No} position changing! +- +-Examples: +- +-@Example +-\D'Fg .3' \" same gray as \D'f 700' +-\D'Fr #0000ff' \" blue +-@endExample +-@end table +-@endDefesc +- +-@xref{Graphics Commands}. +- +-@Defesc {\\b, ', string, '} +-@cindex pile, glyph (@code{\b}) +-@cindex glyph pile (@code{\b}) +-@cindex stacking glyphs (@code{\b}) +-@dfn{Pile} a sequence of glyphs vertically, and center it vertically on +-the current line. Use it to build large brackets and braces. +- +-Here an example how to create a large opening brace: +- +-@Example +-\b'\[lt]\[bv]\[lk]\[bv]\[lb]' +-@endExample +- +-@cindex @code{\b}, limitations +-@cindex limitations of @code{\b} escape +-The first glyph is on the top, the last glyph in @var{string} is at the +-bottom. Note that @code{gtroff} separates the glyphs vertically by +-1@dmn{m}, and the whole object is centered 0.5@dmn{m} above the current +-baseline; the largest glyph width is used as the width for the whole +-object. This rather unflexible positioning algorithm doesn't work with +-@option{-Tdvi} since the bracket pieces vary in height for this device. +-Instead, use the @code{eqn} preprocessor. +- +-@xref{Manipulating Spacing}, how to adjust the vertical spacing with the +-@code{\x} escape. +-@endDefesc +- +- +-@c ===================================================================== +- +-@node Traps, Diversions, Drawing Requests, gtroff Reference +-@section Traps +-@cindex traps +- +-@dfn{Traps} are locations that, when reached, call a specified macro. +-These traps can occur at a given location on the page, at a given +-location in the current diversion, at a blank line, after a certain +-number of input lines, or at the end of input. +- +-@cindex planting a trap +-@cindex trap, planting +-Setting a trap is also called @dfn{planting}. +-@cindex trap, springing +-@cindex springing a trap +-It is also said that a trap is @dfn{sprung} if the associated macro is +-executed. +- +-@menu +-* Page Location Traps:: +-* Diversion Traps:: +-* Input Line Traps:: +-* Blank Line Traps:: +-* Leading Spaces Traps:: +-* End-of-input Traps:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Page Location Traps, Diversion Traps, Traps, Traps +-@subsection Page Location Traps +-@cindex page location traps +-@cindex traps, page location +- +-@dfn{Page location traps} perform an action when @code{gtroff} reaches +-or passes a certain vertical location on the page. Page location traps +-have a variety of purposes, including: +- +-@itemize +-@item +-setting headers and footers +- +-@item +-setting body text in multiple columns +- +-@item +-setting footnotes +-@end itemize +- +-@DefreqList {vpt, flag} +-@DefregListEndx {.vpt} +-@cindex enabling vertical position traps (@code{vpt}) +-@cindex vertical position traps, enabling (@code{vpt}) +-@cindex vertical position trap enable register (@code{.vpt}) +-Enable vertical position traps if @var{flag} is non-zero, or disables +-them otherwise. Vertical position traps are traps set by the @code{wh} +-or @code{dt} requests. Traps set by the @code{it} request are not +-vertical position traps. The parameter that controls whether vertical +-position traps are enabled is global. Initially vertical position traps +-are enabled. The current setting of this is available in the +-@code{.vpt} read-only number register. +- +-Note that a page can't be ejected if @code{vpt} is set to zero. +-@endDefreq +- +-@Defreq {wh, dist [@Var{macro}]} +-Set a page location trap. Non-negative values for @var{dist} set the +-trap relative to the top of the page; negative values set the trap +-relative to the bottom of the page. Default scaling indicator is +-@samp{v}; values of @var{dist} are always rounded to be multiples of the +-vertical resolution (as given in register @code{.V}). +- +-@var{macro} is the name of the macro to execute when the trap is sprung. +-If @var{macro} is missing, remove the first trap (if any) at @var{dist}. +- +-@cindex page headers +-@cindex page footers +-@cindex headers +-@cindex footers +-The following is a simple example of how many macro packages set headers +-and footers. +- +-@Example +-.de hd \" Page header +-' sp .5i +-. tl 'Title''date' +-' sp .3i +-.. +-. +-.de fo \" Page footer +-' sp 1v +-. tl ''%'' +-' bp +-.. +-. +-.wh 0 hd \" trap at top of the page +-.wh -1i fo \" trap one inch from bottom +-@endExample +- +-A trap at or below the bottom of the page is ignored; it can be made +-active by either moving it up or increasing the page length so that the +-trap is on the page. +- +-Negative trap values always use the @emph{current} page length; they are +-not converted to an absolute vertical position: +- +-@Example +-.pl 5i +-.wh -1i xx +-.ptr +- @result{} xx -240 +-.pl 100i +-.ptr +- @result{} xx -240 +-@endExample +- +-It is possible to have more than one trap at the same location; to do +-so, the traps must be defined at different locations, then moved +-together with the @code{ch} request; otherwise the second trap would +-replace the first one. Earlier defined traps hide later defined traps +-if moved to the same position (the many empty lines caused by the +-@code{bp} request are omitted in the following example): +- +-@Example +-.de a +-. nop a +-.. +-.de b +-. nop b +-.. +-.de c +-. nop c +-.. +-. +-.wh 1i a +-.wh 2i b +-.wh 3i c +-.bp +- @result{} a b c +-@endExample +-@Example +-.ch b 1i +-.ch c 1i +-.bp +- @result{} a +-@endExample +-@Example +-.ch a 0.5i +-.bp +- @result{} a b +-@endExample +-@endDefreq +- +-@Defreg {.t} +-@cindex distance to next trap register (@code{.t}) +-@cindex trap, distance, register (@code{.t}) +-A read-only number register holding the distance to the next trap. +- +-If there are no traps between the current position and the bottom of the +-page, it contains the distance to the page bottom. In a diversion, the +-distance to the page bottom is infinite (the returned value is the +-biggest integer that can be represented in @code{groff}) if there are +-no diversion traps. +-@endDefreg +- +-@Defreq {ch, macro [@Var{dist}]} +-@cindex changing trap location (@code{ch}) +-@cindex trap, changing location (@code{ch}) +-Change the location of a trap. The first argument is the name of the +-macro to be invoked at the trap, and the second argument is the new +-location for the trap (note that the parameters are specified in +-opposite order as in the @code{wh} request). This is useful for +-building up footnotes in a diversion to allow more space at the bottom +-of the page for them. +- +-Default scaling indicator for @var{dist} is @samp{v}. If @var{dist} is +-missing, the trap is removed. +- +-@c XXX +- +-@ignore +-@Example +-... (simplified) footnote example ... +-@endExample +-@end ignore +-@endDefreq +- +-@Defreg {.ne} +-The read-only number register @code{.ne} contains the amount of space +-that was needed in the last @code{ne} request that caused a trap to be +-sprung. Useful in conjunction with the @code{.trunc} register. +-@xref{Page Control}, for more information. +- +-Since the @code{.ne} register is only set by traps it doesn't make much +-sense to use it outside of trap macros. +-@endDefreg +- +-@Defreg {.trunc} +-@cindex @code{ne} request, and the @code{.trunc} register +-@cindex truncated vertical space register (@code{.trunc}) +-A read-only register containing the amount of vertical space truncated +-by the most recently sprung vertical position trap, or, if the trap was +-sprung by an @code{ne} request, minus the amount of vertical motion +-produced by the @code{ne} request. In other words, at the point a trap +-is sprung, it represents the difference of what the vertical position +-would have been but for the trap, and what the vertical position +-actually is. +- +-Since the @code{.trunc} register is only set by traps it doesn't make +-much sense to use it outside of trap macros. +-@endDefreg +- +-@Defreg {.pe} +-@cindex @code{bp} request, and traps (@code{.pe}) +-@cindex traps, sprung by @code{bp} request (@code{.pe}) +-@cindex page ejecting register (@code{.pe}) +-A read-only register that is set to@tie{}1 while a page is ejected with +-the @code{bp} request (or by the end of input). +- +-Outside of traps this register is always zero. In the following +-example, only the second call to@tie{}@code{x} is caused by @code{bp}. +- +-@Example +-.de x +-\&.pe=\\n[.pe] +-.br +-.. +-.wh 1v x +-.wh 4v x +-A line. +-.br +-Another line. +-.br +- @result{} A line. +- .pe=0 +- Another line. +- +- .pe=1 +-@endExample +-@endDefreg +- +-@cindex diversions, and traps +-@cindex traps, and diversions +-An important fact to consider while designing macros is that diversions +-and traps do not interact normally. For example, if a trap invokes a +-header macro (while outputting a diversion) that tries to change the +-font on the current page, the effect is not visible before the diversion +-has completely been printed (except for input protected with @code{\!} +-or @code{\?}) since the data in the diversion is already formatted. In +-most cases, this is not the expected behaviour. +- +-@c --------------------------------------------------------------------- +- +-@node Diversion Traps, Input Line Traps, Page Location Traps, Traps +-@subsection Diversion Traps +-@cindex diversion traps +-@cindex traps, diversion +- +-@Defreq {dt, [@Var{dist} @Var{macro}]} +-@cindex @code{.t} register, and diversions +-@cindex setting diversion trap (@code{dt}) +-@cindex diversion trap, setting (@code{dt}) +-@cindex trap, diversion, setting (@code{dt}) +-Set a trap @emph{within} a diversion. @var{dist} is the location of the +-trap (identical to the @code{wh} request; default scaling indicator is +-@samp{v}) and @var{macro} is the name of the macro to be invoked. If +-called without arguments, the diversion trap is removed. +- +-Note that there exists only a single diversion trap. +- +-The number register @code{.t} still works within diversions. +-@xref{Diversions}, for more information. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Input Line Traps, Blank Line Traps, Diversion Traps, Traps +-@subsection Input Line Traps +-@cindex input line traps +-@cindex traps, input line +- +-@DefreqList {it, n macro} +-@DefreqListEndx {itc, n macro} +-@cindex setting input line trap (@code{it}) +-@cindex input line trap, setting (@code{it}) +-@cindex trap, input line, setting (@code{it}) +-Set an input line trap. @var{n}@tie{}is the number of lines of input +-that may be read before springing the trap, @var{macro} is the macro to +-be invoked. Request lines are not counted as input lines. +- +-For example, one possible use is to have a macro that prints the next +-@var{n}@tie{}lines in a bold font. +- +-@Example +-.de B +-. it \\$1 B-end +-. ft B +-.. +-. +-.de B-end +-. ft R +-.. +-@endExample +- +-@cindex input line traps and interrupted lines (@code{itc}) +-@cindex interrupted lines and input line traps (@code{itc}) +-@cindex traps, input line, and interrupted lines (@code{itc}) +-@cindex lines, interrupted, and input line traps (@code{itc}) +-The @code{itc} request is identical except that an interrupted text line +-(ending with @code{\c}) is not counted as a separate line. +- +-Both requests are associated with the current environment +-(@pxref{Environments}); switching to another environment disables the +-current input trap, and going back reactivates it, restoring the number +-of already processed lines. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Blank Line Traps, Leading Spaces Traps, Input Line Traps, Traps +-@subsection Blank Line Traps +-@cindex blank line traps +-@cindex traps, blank line +- +-@Defreq {blm, macro} +-@cindex blank line macro (@code{blm}) +-Set a blank line trap. @code{gtroff} executes @var{macro} when it +-encounters a blank line in the input file. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node Leading Spaces Traps, End-of-input Traps, Blank Line Traps, Traps +-@subsection Leading Spaces Traps +-@cindex leading spaces traps +-@cindex traps, leading spaces +- +-@DefreqList {lsm, macro} +-@DefregItemx {lsn} +-@DefregListEndx {lss} +-@cindex leading spaces macro (@code{lsm}) +-Set a leading spaces trap. @code{gtroff} executes @var{macro} when it +-encounters leading spaces in an input line; the implicit line break +-that normally happens in this case is suppressed. A line consisting +-of spaces only, however, is treated as an empty line, possibly subject +-to an empty line macro set with the @code{blm} request. +- +-Leading spaces are removed from the input line before calling the +-leading spaces macro. The number of removed spaces is stored in +-register @code{lsn}; the horizontal space that would be emitted if +-there was no leading space macro is stored in register @code{lss}. +-Note that @code{lsn} and @code{lss} are available even if no leading +-space macro has been set. +- +-The first thing a leading space macro sees is a token. However, some +-escapes like @code{\f} or @code{\m} are handled on the fly (see +-@ref{Gtroff Internals}, for a complete list) without creating a token +-at all. Consider that a line starts with two spaces followed by +-@code{\fIfoo}. While skipping the spaces @code{\fI} is handled too so +-that groff's current font is properly set to @samp{I}, but the leading +-space macro only sees @code{foo}, without the preceding @code{\fI}. +-If the macro should see the font escape you have to `protect' it with +-something that creates a token, for example with @code{\&\fIfoo}. +-@endDefreq +- +-@c --------------------------------------------------------------------- +- +-@node End-of-input Traps, , Leading Spaces Traps, Traps +-@subsection End-of-input Traps +-@cindex end-of-input traps +-@cindex traps, end-of-input +- +-@Defreq {em, macro} +-@cindex setting end-of-input trap (@code{em}) +-@cindex end-of-input trap, setting (@code{em}) +-@cindex trap, end-of-input, setting (@code{em}) +-@cindex end-of-input macro (@code{em}) +-@cindex macro, end-of-input (@code{em}) +-Set a trap at the end of input. @var{macro} is executed after the last +-line of the input file has been processed. +- +-For example, if the document had to have a section at the bottom of the +-last page for someone to approve it, the @code{em} request could be +-used. +- +-@Example +-.de approval +-\c +-. ne 3v +-. sp (\\n[.t]u - 3v) +-. in +4i +-. lc _ +-. br +-Approved:\t\a +-. sp +-Date:\t\t\a +-.. +-. +-.em approval +-@endExample +- +-The @code{\c} in the above example needs explanation. For historical +-reasons (and for compatibility with @acronym{AT&T} @code{troff}), the +-end macro exits as soon as it causes a page break and no remaining +-data is in the partially collected line. +- +-Let us assume that there is no @code{\c} in the above @code{approval} +-macro, and that the page is full and has been ended with, say, a +-@code{br} request. The @code{ne} request now causes the start of a new +-page, which in turn makes @code{troff} exit immediately for the reasons +-just described. In most situations this is not intended. +- +-To always force processing the whole end macro independently of this +-behaviour it is thus advisable to insert something that starts an +-empty partially filled line (@code{\c}) whenever there is a chance that +-a page break can happen. In the above example, the call of the +-@code{ne} request assures that the remaining code stays on the same +-page, so we have to insert @code{\c} only once. +- +-The next example shows how to append three lines, then starting a new +-page unconditionally. Since @w{@samp{.ne 1}} doesn't give the desired +-effect -- there is always one line available or we are already at the +-beginning of the next page -- we temporarily increase the page length +-by one line so that we can use @w{@samp{.ne 2}}. +- +-@Example +-.de EM +-.pl +1v +-\c +-.ne 2 +-line one +-.br +-\c +-.ne 2 +-line two +-.br +-\c +-.ne 2 +-line three +-.br +-.pl -1v +-\c +-'bp +-.. +-.em EM +-@endExample +- +-Note that this specific feature affects only the first potential page +-break caused by the end macro; further page breaks emitted by the end +-macro are handled normally. +- +-Another possible use of the @code{em} request is to make @code{gtroff} +-emit a single large page instead of multiple pages. For example, one +-may want to produce a long plain-text file for reading on-screen. The +-idea is to set the page length at the beginning of the document to a +-very large value to hold all the text, and automatically adjust it to +-the exact height of the document after the text has been output. +- +-@Example +-.de adjust-page-length +-. br +-. pl \\n[nl]u \" \n[nl] holds the current page length +-.. +-. +-.de single-page-mode +-. pl 99999 +-. em adjust-page-length +-.. +-. +-.\" activate the above code +-.single-page-mode +-@endExample +- +-Since only one end-of-input trap does exist and other macro packages +-may already use it, care must be taken not to break the mechanism. A +-simple solution would be to append the above macro to the macro +-package's end-of-input macro using the @code{.am} request. +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Diversions, Environments, Traps, gtroff Reference +-@section Diversions +-@cindex diversions +- +-In @code{gtroff} it is possible to @dfn{divert} text into a named +-storage area. Due to the similarity to defining macros it is sometimes +-said to be stored in a macro. This is used for saving text for output +-at a later time, which is useful for keeping blocks of text on the same +-page, footnotes, tables of contents, and indices. +- +-@cindex top-level diversion +-@cindex diversion, top-level +-For orthogonality it is said that @code{gtroff} is in the @dfn{top-level +-diversion} if no diversion is active (i.e., the data is diverted to the +-output device). +- +-Although the following requests can be used to create diversions, +-simply using an undefined diversion will cause it to be defined as empty. +-@xref{Identifiers}. +- +-@DefreqList {di, macro} +-@DefreqListEndx {da, macro} +-@cindex beginning diversion (@code{di}) +-@cindex diversion, beginning (@code{di}) +-@cindex ending diversion (@code{di}) +-@cindex diversion, ending (@code{di}) +-@cindex appending to a diversion (@code{da}) +-@cindex diversion, appending (@code{da}) +-Begin a diversion. Like the @code{de} request, it takes an argument of +-a macro name to divert subsequent text into. The @code{da} macro +-appends to an existing diversion. +- +-@code{di} or @code{da} without an argument ends the diversion. +- +-The current partially-filled line is included into the diversion. See +-the @code{box} request below for an example. Note that switching to +-another (empty) environment (with the @code{ev} request) avoids the +-inclusion of the current partially-filled line. +-@endDefreq +- +-@DefreqList {box, macro} +-@DefreqListEndx {boxa, macro} +-Begin (or append to) a diversion like the @code{di} and @code{da} +-requests. The difference is that @code{box} and @code{boxa} do not +-include a partially-filled line in the diversion. +- +-Compare this: +- +-@Example +-Before the box. +-.box xxx +-In the box. +-.br +-.box +-After the box. +-.br +- @result{} Before the box. After the box. +-.xxx +- @result{} In the box. +-@endExample +- +-@noindent +-with this: +- +-@Example +-Before the diversion. +-.di yyy +-In the diversion. +-.br +-.di +-After the diversion. +-.br +- @result{} After the diversion. +-.yyy +- @result{} Before the diversion. In the diversion. +-@endExample +- +-@code{box} or @code{boxa} without an argument ends the diversion. +-@endDefreq +- +-@DefregList {.z} +-@DefregListEndx {.d} +-@cindex @code{nl} register, and @code{.d} +-@cindex nested diversions +-@cindex diversion, nested +-@cindex diversion name register (@code{.z}) +-@cindex vertical position in diversion register (@code{.d}) +-@cindex position, vertical, in diversion, register (@code{.d}) +-@cindex diversion, vertical position in, register (@code{.d}) +-Diversions may be nested. The read-only number register @code{.z} +-contains the name of the current diversion (this is a string-valued +-register). The read-only number register @code{.d} contains the current +-vertical place in the diversion. If not in a diversion it is the same +-as register @code{nl}. +-@endDefreg +- +-@Defreg {.h} +-@cindex high-water mark register (@code{.h}) +-@cindex mark, high-water, register (@code{.h}) +-@cindex position of lowest text line (@code{.h}) +-@cindex text line, position of lowest (@code{.h}) +-The @dfn{high-water mark} on the current page. It corresponds to the +-text baseline of the lowest line on the page. This is a read-only +-register. +- +-@Example +-.tm .h==\n[.h], nl==\n[nl] +- @result{} .h==0, nl==-1 +-This is a test. +-.br +-.sp 2 +-.tm .h==\n[.h], nl==\n[nl] +- @result{} .h==40, nl==120 +-@endExample +- +-@cindex @code{.h} register, difference to @code{nl} +-@cindex @code{nl} register, difference to @code{.h} +-@noindent +-As can be seen in the previous example, empty lines are not considered +-in the return value of the @code{.h} register. +-@endDefreg +- +-@DefregList {dn} +-@DefregListEndx {dl} +-@cindex @code{dn} register, and @code{da} (@code{boxa}) +-@cindex @code{dl} register, and @code{da} (@code{boxa}) +-@cindex @code{da} request, and @code{dn} (@code{dl}) +-@cindex @code{boxa} request, and @code{dn} (@code{dl}) +-After completing a diversion, the read-write number registers @code{dn} +-and @code{dl} contain the vertical and horizontal size of the diversion. +-Note that only the just processed lines are counted: For the computation +-of @code{dn} and @code{dl}, the requests @code{da} and @code{boxa} are +-handled as if @code{di} and @code{box} had been used -- lines that have +-been already stored in a macro are not taken into account. +- +-@Example +-.\" Center text both horizontally & vertically +-. +-.\" Enclose macro definitions in .eo and .ec +-.\" to avoid the doubling of the backslash +-.eo +-.\" macro .(c starts centering mode +-.de (c +-. br +-. ev (c +-. evc 0 +-. in 0 +-. nf +-. di @@c +-.. +-@endExample +-@Example +-.\" macro .)c terminates centering mode +-.de )c +-. br +-. ev +-. di +-. nr @@s (((\n[.t]u - \n[dn]u) / 2u) - 1v) +-. sp \n[@@s]u +-. ce 1000 +-. @@c +-. ce 0 +-. sp \n[@@s]u +-. br +-. fi +-. rr @@s +-. rm @@s +-. rm @@c +-.. +-.\" End of macro definitions, restore escape mechanism +-.ec +-@endExample +-@endDefreg +- +-@DefescList {\\!, , , } +-@DefescListEndx {\\?, , anything, \\?} +-@cindex transparent output (@code{\!}, @code{\?}) +-@cindex output, transparent (@code{\!}, @code{\?}) +-Prevent requests, macros, and escapes from being interpreted when read +-into a diversion. Both escapes take the given text and +-@dfn{transparently} embed it into the diversion. This is useful for +-macros that shouldn't be invoked until the diverted text is actually +-output. +- +-The @code{\!} escape transparently embeds text up to and including the +-end of the line. The @code{\?} escape transparently embeds text until +-the next occurrence of the @code{\?} escape. Example: +- +-@Example +-\?@var{anything}\? +-@endExample +- +-@cindex @code{\?}, and copy-in mode +-@cindex copy-in mode, and @code{\?} +-@cindex mode, copy-in, and @code{\?} +-@cindex @code{\!}, and copy-in mode +-@cindex copy-in mode, and @code{\!} +-@cindex mode, copy-in, and @code{\!} +-@noindent +-@var{anything} may not contain newlines; use @code{\!} to embed +-newlines in a diversion. The escape sequence @code{\?} is also +-recognized in copy mode and turned into a single internal code; it is +-this code that terminates @var{anything}. Thus the following example +-prints@tie{}4. +- +-@Example +-.nr x 1 +-.nf +-.di d +-\?\\?\\\\?\\\\\\\\nx\\\\?\\?\? +-.di +-.nr x 2 +-.di e +-.d +-.di +-.nr x 3 +-.di f +-.e +-.di +-.nr x 4 +-.f +-@endExample +- +-Both escapes read the data in copy mode. +- +-@cindex @code{\!}, in top-level diversion +-@cindex top-level diversion, and @code{\!} +-@cindex diversion, top-level, and @code{\!} +-If @code{\!} is used in the top-level diversion, its argument is +-directly embedded into the @code{gtroff} intermediate output. This can +-be used for example to control a postprocessor that processes the data +-before it is sent to the device driver. +- +-@cindex @code{\?}, in top-level diversion +-@cindex top-level diversion, and @code{\?} +-@cindex diversion, top-level, and @code{\?} +-The @code{\?} escape used in the top-level diversion produces no output +-at all; its argument is simply ignored. +-@endDefesc +- +-@cindex @code{\!}, and @code{output} request +-@cindex @code{output} request, and @code{\!} +-@cindex @code{output} request, and copy-in mode +-@cindex copy-in mode, and @code{output} request +-@cindex mode, copy-in, and @code{output} request +-@Defreq {output, string} +-Emit @var{string} directly to the @code{gtroff} intermediate output +-(subject to copy mode interpretation); this is similar to @code{\!} used +-at the top level. An initial double quote in @var{string} is stripped +-off to allow initial blanks. +- +-This request can't be used before the first page has started -- if you +-get an error, simply insert @code{.br} before the @code{output} request. +- +-Without argument, @code{output} is ignored. +- +-Use with caution! It is normally only needed for mark-up used by a +-postprocessor that does something with the output before sending it to +-the output device, filtering out @var{string} again. +-@endDefreq +- +-@Defreq {asciify, div} +-@cindex unformatting diversions (@code{asciify}) +-@cindex diversion, unformatting (@code{asciify}) +-@cindex @code{trin} request, and @code{asciify} +-@dfn{Unformat} the diversion specified by @var{div} in such a way that +-@acronym{ASCII} characters, characters translated with the @code{trin} +-request, space characters, and some escape sequences that were formatted +-and diverted are treated like ordinary input characters when the +-diversion is reread. It can be also used for gross hacks; for example, +-the following sets register@tie{}@code{n} to@tie{}1. +- +-@Example +-.tr @@. +-.di x +-@@nr n 1 +-.br +-.di +-.tr @@@@ +-.asciify x +-.x +-@endExample +- +-Note that @code{asciify} cannot return all items in a diversion back +-to their source equivalent, nodes such as @code{\N[...]} will still +-remain as nodes, so the result cannot be guaranteed to be a pure string. +- +-@xref{Copy-in Mode}. +-@endDefreq +- +-@Defreq {unformat, div} +-Like @code{asciify}, unformat the specified diversion. However, +-@code{unformat} only unformats spaces and tabs between words. +-Unformatted tabs are treated as input tokens, and spaces are stretchable +-again. +- +-The vertical size of lines is not preserved; glyph information (font, +-font size, space width, etc.)@: is retained. +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Environments, Suppressing output, Diversions, gtroff Reference +-@section Environments +-@cindex environments +- +-It happens frequently that some text should be printed in a certain +-format regardless of what may be in effect at the time, for example, in +-a trap invoked macro to print headers and footers. To solve this +-@code{gtroff} processes text in @dfn{environments}. An environment +-contains most of the parameters that control text processing. It is +-possible to switch amongst these environments; by default @code{gtroff} +-processes text in environment@tie{}0. The following is the information +-kept in an environment. +- +-@itemize @bullet +-@item +-font parameters (size, family, style, glyph height and slant, space and +-sentence space size) +- +-@item +-page parameters (line length, title length, vertical spacing, line +-spacing, indentation, line numbering, centering, right-justifying, +-underlining, hyphenation data) +- +-@item +-fill and adjust mode +- +-@item +-tab stops, tab and leader characters, escape character, no-break and +-hyphen indicators, margin character data +- +-@item +-partially collected lines +- +-@item +-input traps +- +-@item +-drawing and fill colours +-@end itemize +- +-These environments may be given arbitrary names (see @ref{Identifiers}, +-for more info). Old versions of @code{troff} only had environments +-named @samp{0}, @samp{1}, and @samp{2}. +- +-@DefreqList {ev, [@Var{env}]} +-@DefregListEndx {.ev} +-@cindex switching environments (@code{ev}) +-@cindex environment, switching (@code{ev}) +-@cindex environment number/name register (@code{.ev}) +-Switch to another environment. The argument @var{env} is the name of +-the environment to switch to. With no argument, @code{gtroff} switches +-back to the previous environment. There is no limit on the number of +-named environments; they are created the first time that they are +-referenced. The @code{.ev} read-only register contains the name or +-number of the current environment. This is a string-valued register. +- +-Note that a call to @code{ev} (with argument) pushes the previously +-active environment onto a stack. If, say, environments @samp{foo}, +-@samp{bar}, and @samp{zap} are called (in that order), the first +-@code{ev} request without parameter switches back to environment +-@samp{bar} (which is popped off the stack), and a second call switches +-back to environment @samp{foo}. +- +-Here is an example: +- +-@Example +-.ev footnote-env +-.fam N +-.ps 6 +-.vs 8 +-.ll -.5i +-.ev +- +-... +- +-.ev footnote-env +-\(dg Note the large, friendly letters. +-.ev +-@endExample +-@endDefreq +- +-@Defreq {evc, env} +-@cindex copying environment (@code{evc}) +-@cindex environment, copying (@code{evc}) +-Copy the environment @var{env} into the current environment. +- +-The following environment data is not copied: +- +-@itemize @bullet +-@item +-Partially filled lines. +- +-@item +-The status whether the previous line was interrupted. +- +-@item +-The number of lines still to center, or to right-justify, or to +-underline (with or without underlined spaces); they are set to zero. +- +-@item +-The status whether a temporary indentation is active. +- +-@item +-Input traps and its associated data. +- +-@item +-Line numbering mode is disabled; it can be reactivated with @w{@samp{.nm +-+0}}. +- +-@item +-The number of consecutive hyphenated lines (set to zero). +-@end itemize +-@endDefreq +- +-@DefregList {.w} +-@DefregItemx {.cht} +-@DefregItemx {.cdp} +-@DefregListEndx {.csk} +-@cindex environment, dimensions of last glyph (@code{.w}, @code{.cht}, @code{.cdp}, @code{.csk}) +-@cindex width, of last glyph (@code{.w}) +-@cindex height, of last glyph (@code{.cht}) +-@cindex depth, of last glyph (@code{.cdp}) +-@cindex skew, of last glyph (@code{.csk}) +-@cindex last glyph, dimensions (@code{.w}, @code{.cht}, @code{.cdp}, @code{.csk}) +-@cindex glyph, last, dimensions (@code{.w}, @code{.cht}, @code{.cdp}, @code{.csk}) +-The @code{\n[.w]} register contains the width of the last glyph added to +-the current environment. +- +-The @code{\n[.cht]} register contains the height of the last glyph added +-to the current environment. +- +-The @code{\n[.cdp]} register contains the depth of the last glyph added +-to the current environment. It is positive for glyphs extending below +-the baseline. +- +-The @code{\n[.csk]} register contains the @dfn{skew} (how far to the +-right of the glyph's center that @code{gtroff} should place an accent) +-of the last glyph added to the current environment. +-@endDefreg +- +-@Defreg {.n} +-@cindex environment, previous line length (@code{.n}) +-@cindex line length, previous (@code{.n}) +-@cindex length of previous line (@code{.n}) +-@cindex previous line length (@code{.n}) +-The @code{\n[.n]} register contains the length of the previous output +-line in the current environment. +-@endDefreg +- +- +-@c ===================================================================== +- +-@node Suppressing output, Colors, Environments, gtroff Reference +-@section Suppressing output +- +-@Defesc {\\O, , num, } +-@cindex suppressing output (@code{\O}) +-@cindex output, suppressing (@code{\O}) +-Disable or enable output depending on the value of @var{num}: +- +-@table @samp +-@item \O0 +-Disable any glyphs from being emitted to the device driver, provided +-that the escape occurs at the outer level (see @code{\O[3]} and +-@code{\O[4]}). Motion is not suppressed so effectively @code{\O[0]} +-means @emph{pen up}. +- +-@item \O1 +-Enable output of glyphs, provided that the escape occurs at the outer +-level. +-@end table +- +-@vindex opminx +-@vindex opminy +-@vindex opmaxx +-@vindex opmaxy +-@code{\O0} and @code{\O1} also reset the four registers @samp{opminx}, +-@samp{opminy}, @samp{opmaxx}, and @samp{opmaxy} to @minus{}1. +-@xref{Register Index}. These four registers mark the top left and +-bottom right hand corners of a box that encompasses all written glyphs. +- +-For example the input text: +- +-@Example +-Hello \O[0]world \O[1]this is a test. +-@endExample +- +-@noindent +-produces the following output: +- +-@Example +-Hello this is a test. +-@endExample +- +-@table @samp +-@item \O2 +-Provided that the escape occurs at the outer level, enable output of +-glyphs and also write out to @code{stderr} the page number and four +-registers encompassing the glyphs previously written since the last call +-to @code{\O}. +- +-@item \O3 +-Begin a nesting level. At start-up, @code{gtroff} is at outer level. +-The current level is contained within the read-only register @code{.O}. +-@xref{Built-in Registers}. +- +-@item \O4 +-End a nesting level. The current level is contained within the +-read-only register @code{.O}. @xref{Built-in Registers}. +- +-@item \O[5@var{P}@var{filename}] +-This escape is @code{grohtml} specific. Provided that this escape +-occurs at the outer nesting level write the @code{filename} to +-@code{stderr}. The position of the image, @var{P}, must be specified +-and must be one of @code{l}, @code{r}, @code{c}, or@tie{}@code{i} (left, +-right, centered, inline). @var{filename} is associated with the +-production of the next inline image. +-@end table +-@endDefesc +- +- +-@c ===================================================================== +- +-@node Colors, I/O, Suppressing output, gtroff Reference +-@section Colors +-@cindex colors +- +-@DefreqList {color, [@Var{n}]} +-@DefregListEndx {.color} +-If @var{n} is missing or non-zero, activate colors (this is the +-default); otherwise, turn it off. +- +-The read-only number register @code{.color} is@tie{}1 if colors are +-active, 0@tie{}otherwise. +- +-Internally, @code{color} sets a global flag; it does not produce a +-token. Similar to the @code{cp} request, you should use it at the +-beginning of your document to control color output. +- +-Colors can be also turned off with the @option{-c} command line option. +-@endDefreq +- +-@Defreq {defcolor, ident scheme color_components} +-Define color with name @var{ident}. @var{scheme} can be one of the +-following values: @code{rgb} (three components), @code{cmy} (three +-components), @code{cmyk} (four components), and @code{gray} or +-@code{grey} (one component). +- +-@cindex default color +-@cindex color, default +-Color components can be given either as a hexadecimal string or as +-positive decimal integers in the range 0--65535. A hexadecimal string +-contains all color components concatenated. It must start with either +-@code{#} or @code{##}; the former specifies hex values in the range +-0--255 (which are internally multiplied by@tie{}257), the latter in the +-range 0--65535. Examples: @code{#FFC0CB} (pink), @code{##ffff0000ffff} +-(magenta). The default color name @c{default} can't be redefined; its +-value is device-specific (usually black). It is possible that the +-default color for @code{\m} and @code{\M} is not identical. +- +-@cindex @code{f} unit, and colors +-@cindex unit, @code{f}, and colors +-A new scaling indicator@tie{}@code{f} has been introduced, which +-multiplies its value by 65536; this makes it convenient to specify color +-components as fractions in the range 0 to@tie{}1 (1f equals 65536u). +-Example: +- +-@Example +-.defcolor darkgreen rgb 0.1f 0.5f 0.2f +-@endExample +- +-Note that @code{f} is the default scaling indicator for the +-@code{defcolor} request, thus the above statement is equivalent to +- +-@Example +-.defcolor darkgreen rgb 0.1 0.5 0.2 +-@endExample +-@endDefreq +- +-@DefreqList {gcolor, [@Var{color}]} +-@DefescItemx {\\m, , c, } +-@DefescItem {\\m, @Lparen{}, co, } +-@DefescItem {\\m, @Lbrack{}, color, @Rbrack{}} +-@DefregListEndx {.m} +-Set (glyph) drawing color. The following examples show how to turn the +-next four words red. +- +-@Example +-.gcolor red +-these are in red +-.gcolor +-and these words are in black. +-@endExample +- +-@Example +-\m[red]these are in red\m[] and these words are in black. +-@endExample +- +-The escape @code{\m[]} returns to the previous color, as does a call to +-@code{gcolor} without an argument. +- +-@cindex drawing color name register (@code{.m}) +-@cindex name, drawing color, register (@code{.m}) +-@cindex color name, drawing, register (@code{.m}) +-The name of the current drawing color is available in the read-only, +-string-valued number register @samp{.m}. +- +-The drawing color is associated with the current environment +-(@pxref{Environments}). +- +-Note that @code{\m} doesn't produce an input token in @code{gtroff}. As +-a consequence, it can be used in requests like @code{mc} (which expects +-a single character as an argument) to change the color on the fly: +- +-@Example +-.mc \m[red]x\m[] +-@endExample +-@endDefesc +- +-@DefreqList {fcolor, [@Var{color}]} +-@DefescItemx {\\M, , c, } +-@DefescItem {\\M, @Lparen{}, co, } +-@DefescItem {\\M, @Lbrack{}, color, @Rbrack{}} +-@DefregListEndx {.M} +-Set fill (background) color for filled objects drawn with the +-@code{\D'@dots{}'} commands. +- +-A red ellipse can be created with the following code: +- +-@Example +-\M[red]\h'0.5i'\D'E 2i 1i'\M[] +-@endExample +- +-The escape @code{\M[]} returns to the previous fill color, as does a +-call to @code{fcolor} without an argument. +- +-@cindex background color name register (@code{.M}) +-@cindex name, background color, register (@code{.M}) +-@cindex color name, background, register (@code{.M}) +-@cindex fill color name register (@code{.M}) +-@cindex name, fill color, register (@code{.M}) +-@cindex color name, fill, register (@code{.M}) +-The name of the current fill (background) color is available in the +-read-only, string-valued number register @samp{.M}. +- +-The fill color is associated with the current environment +-(@pxref{Environments}). +- +-Note that @code{\M} doesn't produce an input token in @code{gtroff}. +-@endDefesc +- +- +-@c ===================================================================== +- +-@node I/O, Postprocessor Access, Colors, gtroff Reference +-@section I/O +-@cindex i/o +-@cindex input and output requests +-@cindex requests for input and output +-@cindex output and input requests +- +-@code{gtroff} has several requests for including files: +- +-@Defreq {so, file} +-@cindex including a file (@code{so}) +-@cindex file, inclusion (@code{so}) +-Read in the specified @var{file} and includes it in place of the +-@code{so} request. This is quite useful for large documents, e.g.@: +-keeping each chapter in a separate file. @xref{gsoelim}, for more +-information. +- +-Since @code{gtroff} replaces the @code{so} request with the contents of +-@code{file}, it makes a difference whether the data is terminated with a +-newline or not: Assuming that file @file{xxx} contains the word +-@samp{foo} without a final newline, this +- +-@Example +-This is +-.so xxx +-bar +-@endExample +- +-@noindent +-yields @samp{This is foobar}. +- +-The search path for @var{file} can be controlled with the @option{-I} +-command line option. +-@endDefreq +- +-@Defreq {pso, command} +-Read the standard output from the specified @var{command} and includes +-it in place of the @code{pso} request. +- +-@cindex safer mode +-@cindex mode, safer +-@cindex unsafe mode +-@cindex mode, unsafe +-This request causes an error if used in safer mode (which is the +-default). Use @code{groff}'s or @code{troff}'s @option{-U} option to +-activate unsafe mode. +- +-The comment regarding a final newline for the @code{so} request is valid +-for @code{pso} also. +-@endDefreq +- +-@Defreq {mso, file} +-Identical to the @code{so} request except that @code{gtroff} searches +-for the specified @var{file} in the same directories as macro files for +-the the @option{-m} command line option. If the file name to be +-included has the form @file{@var{name}.tmac} and it isn't found, +-@code{mso} tries to include @file{tmac.@var{name}} and vice versa. +-If the file does not exist, a warning of type @samp{file} is emitted. +-@xref{Debugging}, for information about warnings. +-@endDefreq +- +-@DefreqList {trf, file} +-@DefreqListEndx {cf, file} +-@cindex transparent output (@code{cf}, @code{trf}) +-@cindex output, transparent (@code{cf}, @code{trf}) +-@cindex @code{cf} request, and copy-in mode +-@cindex copy-in mode, and @code{cf} request +-@cindex mode, copy-in, and @code{cf} request +-@cindex @code{trf} request, and copy-in mode +-@cindex copy-in mode, and @code{trf} request +-@cindex mode, copy-in, and @code{trf} request +-Transparently output the contents of @var{file}. Each line is output as +-if it were preceded by @code{\!}; however, the lines are @emph{not} +-subject to copy mode interpretation. If the file does not end with a +-newline, then a newline is added (@code{trf} only). For example, to +-define a macro@tie{}@code{x} containing the contents of +-file@tie{}@file{f}, use +- +-@Example +-.ev 1 +-.di x +-.trf f +-.di +-.ev +-@endExample +- +-@noindent +-The calls to @code{ev} prevent that the current partial input line +-becomes part of the diversion. +- +-Both @code{trf} and @code{cf}, when used in a diversion, embeds an +-object in the diversion which, when reread, causes the contents of +-@var{file} to be transparently copied through to the output. In +-@acronym{UNIX} @code{troff}, the contents of @var{file} is immediately +-copied through to the output regardless of whether there is a current +-diversion; this behaviour is so anomalous that it must be considered a +-bug. +- +-@cindex @code{trf} request, and invalid characters +-@cindex characters, invalid for @code{trf} request +-@cindex invalid characters for @code{trf} request +- +-While @code{cf} copies the contents of @var{file} completely +-unprocessed, @code{trf} disallows characters such as NUL that are not +-valid @code{gtroff} input characters (@pxref{Identifiers}). +- +-For @code{cf}, within a diversion, `completely unprocessed' means that +-each line of a file to be inserted is handled as if it were preceded by +-@code{\!\\!}. +- +-Both requests cause a line break. +-@endDefreq +- +-@Defreq {nx, [@Var{file}]} +-@cindex processing next file (@code{nx}) +-@cindex file, processing next (@code{nx}) +-@cindex next file, processing (@code{nx}) +-Force @code{gtroff} to continue processing of the file specified as an +-argument. If no argument is given, immediately jump to the end of file. +-@endDefreq +- +-@Defreq {rd, [@Var{prompt} [@Var{arg1} @Var{arg2} @dots{}]]} +-@cindex reading from standard input (@code{rd}) +-@cindex standard input, reading from (@code{rd}) +-@cindex input, standard, reading from (@code{rd}) +-Read from standard input, and include what is read as though it were +-part of the input file. Text is read until a blank line is encountered. +- +-If standard input is a TTY input device (keyboard), write @var{prompt} +-to standard error, followed by a colon (or send BEL for a beep if no +-argument is given). +- +-Arguments after @var{prompt} are available for the input. For example, +-the line +- +-@Example +-.rd data foo bar +-@endExample +- +-with the input @w{@samp{This is \$2.}} prints +- +-@Example +-This is bar. +-@endExample +-@endDefreq +- +-@cindex form letters +-@cindex letters, form +-Using the @code{nx} and @code{rd} requests, it is easy to set up form +-letters. The form letter template is constructed like this, putting the +-following lines into a file called @file{repeat.let}: +- +-@Example +-.ce +-\*(td +-.sp 2 +-.nf +-.rd +-.sp +-.rd +-.fi +-Body of letter. +-.bp +-.nx repeat.let +-@endExample +- +-@cindex @code{ex} request, used with @code{nx} and @code{rd} +-@noindent +-When this is run, a file containing the following lines should be +-redirected in. Note that requests included in this file are executed as +-though they were part of the form letter. The last block of input is +-the @code{ex} request, which tells @code{groff} to stop processing. If +-this was not there, @code{groff} would not know when to stop. +- +-@Example +-Trent A. Fisher +-708 NW 19th Av., #202 +-Portland, OR 97209 +- +-Dear Trent, +- +-Len Adollar +-4315 Sierra Vista +-San Diego, CA 92103 +- +-Dear Mr. Adollar, +- +-.ex +-@endExample +- +-@Defreq {pi, pipe} +-Pipe the output of @code{gtroff} to the shell command(s) specified by +-@var{pipe}. This request must occur before @code{gtroff} has a chance +-to print anything. +- +-@cindex safer mode +-@cindex mode, safer +-@cindex unsafe mode +-@cindex mode, unsafe +-@code{pi} causes an error if used in safer mode (which is the default). +-Use @code{groff}'s or @code{troff}'s @option{-U} option to activate +-unsafe mode. +- +-Multiple calls to @code{pi} are allowed, acting as a chain. For +-example, +- +-@Example +-.pi foo +-.pi bar +-... +-@endExample +- +-is the same as @w{@samp{.pi foo | bar}}. +- +-@cindex @code{groff}, and @code{pi} request +-@cindex @code{pi} request, and @code{groff} +-Note that the intermediate output format of @code{gtroff} is piped to +-the specified commands. Consequently, calling @code{groff} without the +-@option{-Z} option normally causes a fatal error. +-@endDefreq +- +-@DefreqList {sy, cmds} +-@DefregListEndx {systat} +-Execute the shell command(s) specified by @var{cmds}. The output is not +-saved anyplace, so it is up to the user to do so. +- +-@cindex safer mode +-@cindex mode, safer +-@cindex unsafe mode +-@cindex mode, unsafe +-This request causes an error if used in safer mode (which is the +-default). Use @code{groff}'s or @code{troff}'s @option{-U} option to +-activate unsafe mode. +- +-For example, the following code fragment introduces the current time +-into a document: +- +-@cindex time, current +-@cindex current time +-@pindex perl +-@Example +-.sy perl -e 'printf ".nr H %d\\n.nr M %d\\n.nr S %d\\n",\ +- (localtime(time))[2,1,0]' > /tmp/x\n[$$] +-.so /tmp/x\n[$$] +-.sy rm /tmp/x\n[$$] +-\nH:\nM:\nS +-@endExample +- +-@noindent +-Note that this works by having the @code{perl} script (run by @code{sy}) +-print out the @code{nr} requests that set the number registers +-@code{H}, @code{M}, and @code{S}, and then reads those commands in with +-the @code{so} request. +- +-For most practical purposes, the number registers @code{seconds}, +-@code{minutes}, and @code{hours}, which are initialized at start-up of +-@code{gtroff}, should be sufficient. Use the @code{af} request to get a +-formatted output: +- +-@Example +-.af hours 00 +-.af minutes 00 +-.af seconds 00 +-\n[hours]:\n[minutes]:\n[seconds] +-@endExample +- +-@cindex @code{system()} return value register (@code{systat}) +-The @code{systat} read-write number register contains the return value +-of the @code{system()} function executed by the last @code{sy} request. +-@endDefreq +- +-@DefreqList {open, stream file} +-@DefreqListEndx {opena, stream file} +-@cindex opening file (@code{open}) +-@cindex file, opening (@code{open}) +-@cindex appending to a file (@code{opena}) +-@cindex file, appending to (@code{opena}) +-Open the specified @var{file} for writing and associates the specified +-@var{stream} with it. +- +-The @code{opena} request is like @code{open}, but if the file exists, +-append to it instead of truncating it. +- +-@cindex safer mode +-@cindex mode, safer +-@cindex unsafe mode +-@cindex mode, unsafe +-Both @code{open} and @code{opena} cause an error if used in safer mode +-(which is the default). Use @code{groff}'s or @code{troff}'s +-@option{-U} option to activate unsafe mode. +-@endDefreq +- +-@DefreqList {write, stream data} +-@DefreqListEndx {writec, stream data} +-@cindex copy-in mode, and @code{write} request +-@cindex @code{write} request, and copy-in mode +-@cindex mode, copy-in, and @code{write} request +-@cindex copy-in mode, and @code{writec} request +-@cindex @code{writec} request, and copy-in mode +-@cindex mode, copy-in, and @code{writec} request +-@cindex writing to file (@code{write}, @code{writec}) +-@cindex file, writing to (@code{write}, @code{writec}) +-Write to the file associated with the specified @var{stream}. The +-stream must previously have been the subject of an open request. The +-remainder of the line is interpreted as the @code{ds} request reads its +-second argument: A leading @samp{"} is stripped, and it is read in +-copy-in mode. +- +-The @code{writec} request is like @code{write}, but only @code{write} +-appends a newline to the data. +-@endDefreq +- +-@Defreq {writem, stream xx} +-@cindex @code{asciify} request, and @code{writem} +-Write the contents of the macro or string @var{xx} to the file +-associated with the specified @var{stream}. +- +-@cindex @code{writem} request, and copy-in mode +-@cindex copy-in mode, and @code{writem} request +-@cindex mode, copy-in, and @code{writem} request +-@var{xx} is read in copy mode, i.e., already formatted elements are +-ignored. Consequently, diversions must be unformatted with the +-@code{asciify} request before calling @code{writem}. Usually, this +-means a loss of information. +-@endDefreq +- +-@Defreq {close, stream} +-@cindex closing file (@code{close}) +-@cindex file, closing (@code{close}) +-Close the specified @var{stream}; the stream is no longer an acceptable +-argument to the @code{write} request. +- +-Here a simple macro to write an index entry. +- +-@Example +-.open idx test.idx +-. +-.de IX +-. write idx \\n[%] \\$* +-.. +-. +-.IX test entry +-. +-.close idx +-@endExample +-@endDefreq +- +-@DefescList {\\V, , e, } +-@DefescItem {\\V, @Lparen{}, ev, } +-@DefescListEnd {\\V, @Lbrack{}, env, @Rbrack{}} +-@cindex @code{\V}, and copy-in mode +-@cindex copy-in mode, and @code{\V} +-@cindex mode, copy-in, and @code{\V} +-Interpolate the contents of the specified environment variable @var{env} +-(one-character name@tie{}@var{e}, two-character name @var{ev}) as +-returned by the function @code{getenv}. @code{\V} is interpreted in +-copy-in mode. +-@endDefesc +- +- +-@c ===================================================================== +- +-@node Postprocessor Access, Miscellaneous, I/O, gtroff Reference +-@section Postprocessor Access +-@cindex postprocessor access +-@cindex access of postprocessor +- +-There are two escapes that give information directly to the +-postprocessor. This is particularly useful for embedding +-@sc{PostScript} into the final document. +- +-@DefreqList {device, xxx} +-@DefescListEndx {\\X, ', xxx, '} +-Embeds its argument into the @code{gtroff} output preceded with +-@w{@samp{x X}}. +- +-@cindex @code{\&}, in @code{\X} +-@cindex @code{\)}, in @code{\X} +-@cindex @code{\%}, in @code{\X} +-@ifnotinfo +-@cindex @code{\:}, in @code{\X} +-@end ifnotinfo +-@ifinfo +-@cindex @code{\@r{}}, in @code{\X} +-@end ifinfo +-The escapes @code{\&}, @code{\)}, @code{\%}, and @code{\:} are ignored +-within @code{\X}, @w{@samp{\ }} and @code{\~} are converted to single +-space characters. All other escapes (except @code{\\}, which produces a +-backslash) cause an error. +- +-@cindex @code{device} request, and copy-in mode +-@cindex copy-in mode, and @code{device} request +-@cindex mode, copy-in, and @code{device} request +-Contrary to @code{\X}, the @code{device} request simply processes its +-argument in copy mode (@pxref{Copy-in Mode}). +- +-@kindex use_charnames_in_special +-@pindex DESC@r{, and @code{use_charnames_in_special}} +-@cindex @code{\X}, and special characters +-If the @samp{use_charnames_in_special} keyword is set in the @file{DESC} +-file, special characters no longer cause an error; they are simply +-output verbatim. Additionally, the backslash is represented as +-@code{\\}. +- +-@samp{use_charnames_in_special} is currently used by @code{grohtml} +-only. +-@endDefesc +- +-@DefreqList {devicem, xx} +-@DefescItemx {\\Y, , n, } +-@DefescItem {\\Y, @Lparen{}, nm, } +-@DefescListEnd {\\Y, @Lbrack{}, name, @Rbrack{}} +-This is approximately equivalent to @samp{\X'\*[@var{name}]'} +-(one-character name@tie{}@var{n}, two-character name @var{nm}). +-However, the contents of the string or macro @var{name} are not +-interpreted; also it is permitted for @var{name} to have been defined as +-a macro and thus contain newlines (it is not permitted for the argument +-to @code{\X} to contain newlines). The inclusion of newlines requires +-an extension to the @acronym{UNIX} @code{troff} output format, and +-confuses drivers that do not know about this extension (@pxref{Device +-Control Commands}). +-@endDefesc +- +-@xref{Output Devices}. +- +- +-@c ===================================================================== +- +-@node Miscellaneous, Gtroff Internals, Postprocessor Access, gtroff Reference +-@section Miscellaneous +- +-This section documents parts of @code{gtroff} that cannot (yet) be +-categorized elsewhere in this manual. +- +-@Defreq {nm, [@Var{start} [@Var{inc} [@Var{space} [@Var{indent}]]]]} +-@cindex printing line numbers (@code{nm}) +-@cindex line numbers, printing (@code{nm}) +-@cindex numbers, line, printing (@code{nm}) +-Print line numbers. @var{start} is the line number of the @emph{next} +-output line. @var{inc} indicates which line numbers are printed. For +-example, the value@tie{}5 means to emit only line numbers that are +-multiples of@tie{}5; this defaults to@tie{}1. @var{space} is the space +-to be left between the number and the text; this defaults to one digit +-space. The fourth argument is the indentation of the line numbers, +-defaulting to zero. Both @var{space} and @var{indent} are given as +-multiples of digit spaces; they can be negative also. Without any +-arguments, line numbers are turned off. +- +-@code{gtroff} reserves three digit spaces for the line number (which is +-printed right-justified) plus the amount given by @var{indent}; the +-output lines are concatenated to the line numbers, separated by +-@var{space}, and @emph{without} reducing the line length. Depending on +-the value of the horizontal page offset (as set with the @code{po} +-request), line numbers that are longer than the reserved space stick +-out to the left, or the whole line is moved to the right. +- +-Parameters corresponding to missing arguments are not changed; any +-non-digit argument (to be more precise, any argument starting with a +-character valid as a delimiter for identifiers) is also treated as +-missing. +- +-If line numbering has been disabled with a call to @code{nm} without an +-argument, it can be reactivated with @samp{.nm +0}, using the previously +-active line numbering parameters. +- +-The parameters of @code{nm} are associated with the current environment +-(@pxref{Environments}). The current output line number is available in +-the number register @code{ln}. +- +-@Example +-.po 1m +-.ll 2i +-This test shows how line numbering works with groff. +-.nm 999 +-This test shows how line numbering works with groff. +-.br +-.nm xxx 3 2 +-.ll -\w'0'u +-This test shows how line numbering works with groff. +-.nn 2 +-This test shows how line numbering works with groff. +-@endExample +- +-@noindent +-And here the result: +- +-@Example +- This test shows how +- line numbering works +- 999 with groff. This +-1000 test shows how line +-1001 numbering works with +-1002 groff. +- This test shows how +- line numbering +- works with groff. +- This test shows how +-1005 line numbering +- works with groff. +-@endExample +-@endDefreq +- +-@Defreq {nn, [@Var{skip}]} +-Temporarily turn off line numbering. The argument is the number of +-lines not to be numbered; this defaults to@tie{}1. +-@endDefreq +- +-@Defreq {mc, glyph [@Var{dist}]} +-@cindex margin glyph (@code{mc}) +-@cindex glyph, for margins (@code{mc}) +-Print a @dfn{margin character} to the right of the +-text.@footnote{@dfn{Margin character} is a misnomer since it is an +-output glyph.} The first argument is the glyph to be printed. The +-second argument is the distance away from the right margin. If missing, +-the previously set value is used; default is 10@dmn{pt}). For text +-lines that are too long (that is, longer than the text length plus +-@var{dist}), the margin character is directly appended to the lines. +- +-With no arguments the margin character is turned off. If this occurs +-before a break, no margin character is printed. +- +-For compatibility with @acronym{AT&T} @code{troff}, a call to @code{mc} +-to set the margin character can't be undone immediately; at least one +-line gets a margin character. Thus +- +-@Example +-.ll 1i +-.mc \[br] +-.mc +-xxx +-.br +-xxx +-@endExample +- +-@noindent +-produces +- +-@Example +-xxx | +-xxx +-@endExample +- +-@cindex @code{tl} request, and @code{mc} +-For empty lines and lines produced by the @code{tl} request no margin +-character is emitted. +- +-The margin character is associated with the current environment +-(@pxref{Environments}). +- +-@pindex nrchbar +-@pindex changebar +-This is quite useful for indicating text that has changed, and, in fact, +-there are programs available for doing this (they are called +-@code{nrchbar} and @code{changebar} and can be found in any +-@samp{comp.sources.unix} archive). +- +-@Example +-.ll 3i +-.mc | +-This paragraph is highlighted with a margin +-character. +-.sp +-Note that vertical space isn't marked. +-.br +-\& +-.br +-But we can fake it with `\&'. +-@endExample +- +-Result: +- +-@Example +-This paragraph is highlighted | +-with a margin character. | +- +-Note that vertical space isn't | +-marked. | +- | +-But we can fake it with `\&'. | +-@endExample +-@endDefreq +- +-@DefreqList {psbb, filename} +-@DefregItemx {llx} +-@DefregItemx {lly} +-@DefregItemx {urx} +-@DefregListEndx {ury} +-@cindex PostScript, bounding box +-@cindex bounding box +-Retrieve the bounding box of the @sc{PostScript} image found in +-@var{filename}. The file must conform to Adobe's @dfn{Document +-Structuring Conventions} (DSC); the command searches for a +-@code{%%BoundingBox} comment and extracts the bounding box values into +-the number registers @code{llx}, @code{lly}, @code{urx}, and @code{ury}. +-If an error occurs (for example, @code{psbb} cannot find the +-@code{%%BoundingBox} comment), it sets the four number registers to +-zero. +- +-The search path for @var{filename} can be controlled with the +-@option{-I} command line option. +-@endDefreq +- +- +-@c ===================================================================== +- +-@node Gtroff Internals, Debugging, Miscellaneous, gtroff Reference +-@section @code{gtroff} Internals +- +-@cindex input token +-@cindex token, input +-@cindex output node +-@cindex node, output +-@code{gtroff} processes input in three steps. One or more input +-characters are converted to an @dfn{input token}.@footnote{Except the +-escapes @code{\f}, @code{\F}, @code{\H}, @code{\m}, @code{\M}, +-@code{\R}, @code{\s}, and @code{\S}, which are processed immediately if +-not in copy-in mode.} Then, one or more input tokens are converted to +-an @dfn{output node}. Finally, output nodes are converted to the +-intermediate output language understood by all output devices. +- +-Actually, before step one happens, @code{gtroff} converts certain escape +-sequences into reserved input characters (not accessible by the user); +-such reserved characters are used for other internal processing also -- +-this is the very reason why not all characters are valid input. +-@xref{Identifiers}, for more on this topic. +- +-For example, the input string @samp{fi\[:u]} is converted into a +-character token @samp{f}, a character token @samp{i}, and a special +-token @samp{:u} (representing u@tie{}umlaut). Later on, the character +-tokens @samp{f} and @samp{i} are merged to a single output node +-representing the ligature glyph @samp{fi} (provided the current font has +-a glyph for this ligature); the same happens with @samp{:u}. All output +-glyph nodes are `processed', which means that they are invariably +-associated with a given font, font size, advance width, etc. During the +-formatting process, @code{gtroff} itself adds various nodes to control +-the data flow. +- +-Macros, diversions, and strings collect elements in two chained lists: a +-list of input tokens that have been passed unprocessed, and a list of +-output nodes. Consider the following the diversion. +- +-@Example +-.di xxx +-a +-\!b +-c +-.br +-.di +-@endExample +- +-@noindent +-It contains these elements. +- +-@multitable {@i{vertical size node}} {token list} {element number} +-@item node list @tab token list @tab element number +- +-@item @i{line start node} @tab --- @tab 1 +-@item @i{glyph node @code{a}} @tab --- @tab 2 +-@item @i{word space node} @tab --- @tab 3 +-@item --- @tab @code{b} @tab 4 +-@item --- @tab @code{\n} @tab 5 +-@item @i{glyph node @code{c}} @tab --- @tab 6 +-@item @i{vertical size node} @tab --- @tab 7 +-@item @i{vertical size node} @tab --- @tab 8 +-@item --- @tab @code{\n} @tab 9 +-@end multitable +- +-@cindex @code{\v}, internal representation +-@noindent +-Elements 1, 7, and@tie{}8 are inserted by @code{gtroff}; the latter two +-(which are always present) specify the vertical extent of the last line, +-possibly modified by @code{\x}. The @code{br} request finishes the +-current partial line, inserting a newline input token, which is +-subsequently converted to a space when the diversion is reread. Note +-that the word space node has a fixed width that isn't stretchable +-anymore. To convert horizontal space nodes back to input tokens, use +-the @code{unformat} request. +- +-Macros only contain elements in the token list (and the node list is +-empty); diversions and strings can contain elements in both lists. +- +-Note that the @code{chop} request simply reduces the number of elements +-in a macro, string, or diversion by one. Exceptions are +-@dfn{compatibility save} and @dfn{compatibility ignore} input tokens, +-which are ignored. The @code{substring} request also ignores those +-input tokens. +- +-Some requests like @code{tr} or @code{cflags} work on glyph identifiers +-only; this means that the associated glyph can be changed without +-destroying this association. This can be very helpful for substituting +-glyphs. In the following example, we assume that glyph @samp{foo} isn't +-available by default, so we provide a substitution using the +-@code{fchar} request and map it to input character @samp{x}. +- +-@Example +-.fchar \[foo] foo +-.tr x \[foo] +-@endExample +- +-@noindent +-Now let us assume that we install an additional special font @samp{bar} +-that has glyph @samp{foo}. +- +-@Example +-.special bar +-.rchar \[foo] +-@endExample +- +-@noindent +-Since glyphs defined with @code{fchar} are searched before glyphs in +-special fonts, we must call @code{rchar} to remove the definition of the +-fallback glyph. Anyway, the translation is still active; @samp{x} now +-maps to the real glyph @samp{foo}. +- +-@cindex compatibility mode, and parameters +-@cindex mode, compatibility, and parameters +-@cindex arguments, and compatibility mode +-@cindex parameters, and compatibility mode +-@cindex macro arguments, and compatibility mode +-@cindex request arguments, and compatibility mode +-Macro and request arguments preserve the compatibility mode: +- +-@Example +-.cp 1 \" switch to compatibility mode +-.de xx +-\\$1 +-.. +-.cp 0 \" switch compatibility mode off +-.xx caf\['e] +- @result{} caf +-@endExample +- +-@noindent +-Since compatibility mode is on while @code{de} is called, the macro +-@code{xx} activates compatibility mode while executing. Argument +-@code{$1} can still be handled properly because it inherits the +-compatibility mode status which was active at the point where @code{xx} +-is called. +- +-After expansion of the parameters, the compatibility save and restore +-tokens are removed. +- +- +-@c ===================================================================== +- +-@node Debugging, Implementation Differences, Gtroff Internals, gtroff Reference +-@section Debugging +-@cindex debugging +- +-@code{gtroff} is not easy to debug, but there are some useful features +-and strategies for debugging. +- +-@Defreq {lf, line [@Var{filename}]} +-@pindex soelim +-@cindex multi-file documents +-@cindex documents, multi-file +-@cindex setting input line number (@code{lf}) +-@cindex input line number, setting (@code{lf}) +-@cindex number, input line, setting (@code{lf}) +-Change the line number and optionally the file name @code{gtroff} shall +-use for error and warning messages. @var{line} is the input line number +-of the @emph{next} line. +- +-Without argument, the request is ignored. +- +-This is a debugging aid for documents that are split into many files, +-then put together with @code{soelim} and other preprocessors. Usually, +-it isn't invoked manually. +- +-Note that other @code{troff} implementations (including the original +-@acronym{AT&T} version) handle @code{lf} differently. For them, +-@var{line} changes the line number of the @emph{current} line. +-@endDefreq +- +-@DefreqList {tm, string} +-@DefreqItemx {tm1, string} +-@DefreqListEndx {tmc, string} +-@cindex printing to stderr (@code{tm}, @code{tm1}, @code{tmc}) +-@cindex stderr, printing to (@code{tm}, @code{tm1}, @code{tmc}) +-Send @var{string} to the standard error output; this is very useful for +-printing debugging messages among other things. +- +-@cindex @code{tm} request, and copy-in mode +-@cindex copy-in mode, and @code{tm} request +-@cindex mode, copy-in, and @code{tm} request +-@cindex @code{tm1} request, and copy-in mode +-@cindex copy-in mode, and @code{tm1} request +-@cindex mode, copy-in, and @code{tm1} request +-@cindex @code{tmc} request, and copy-in mode +-@cindex copy-in mode, and @code{tmc} request +-@cindex mode, copy-in, and @code{tmc} request +-@var{string} is read in copy mode. +- +-The @code{tm} request ignores leading spaces of @var{string}; @code{tm1} +-handles its argument similar to the @code{ds} request: a leading double +-quote in @var{string} is stripped to allow initial blanks. +- +-The @code{tmc} request is similar to @code{tm1} but does not append a +-newline (as is done in @code{tm} and @code{tm1}). +-@endDefreq +- +-@Defreq {ab, [@Var{string}]} +-@cindex aborting (@code{ab}) +-Similar to the @code{tm} request, except that it causes @code{gtroff} to +-stop processing. With no argument it prints @samp{User Abort.} to +-standard error. +-@endDefreq +- +-@Defreq {ex, } +-@cindex @code{ex} request, use in debugging +-@cindex exiting (@code{ex}) +-The @code{ex} request also causes @code{gtroff} to stop processing; see +-also @ref{I/O}. +-@endDefreq +- +-When doing something involved it is useful to leave the debugging +-statements in the code and have them turned on by a command line flag. +- +-@Example +-.if \n(DB .tm debugging output +-@endExample +- +-@noindent +-To activate these statements say +- +-@Example +-groff -rDB=1 file +-@endExample +- +-If it is known in advance that there are many errors and no useful +-output, @code{gtroff} can be forced to suppress formatted output with +-the @option{-z} flag. +- +-@Defreq {pev, } +-@cindex dumping environments (@code{pev}) +-@cindex environments, dumping (@code{pev}) +-Print the contents of the current environment and all the currently +-defined environments (both named and numbered) on @code{stderr}. +-@endDefreq +- +-@Defreq {pm, } +-@cindex dumping symbol table (@code{pm}) +-@cindex symbol table, dumping (@code{pm}) +-Print the entire symbol table on @code{stderr}. Names of all defined +-macros, strings, and diversions are print together with their size in +-bytes. Since @code{gtroff} sometimes adds nodes by itself, the returned +-size can be larger than expected. +- +-This request differs from @acronym{UNIX} @code{troff}: @code{gtroff} +-reports the sizes of diversions, ignores an additional argument to print +-only the total of the sizes, and the size isn't returned in blocks of +-128 characters. +-@endDefreq +- +-@Defreq {pnr, } +-@cindex dumping number registers (@code{pnr}) +-@cindex number registers, dumping (@code{pnr}) +-Print the names and contents of all currently defined number registers +-on @code{stderr}. +-@endDefreq +- +-@Defreq {ptr, } +-@cindex dumping traps (@code{ptr}) +-@cindex traps, dumping (@code{ptr}) +-Print the names and positions of all traps (not including input line +-traps and diversion traps) on @code{stderr}. Empty slots in the page +-trap list are printed as well, because they can affect the priority of +-subsequently planted traps. +-@endDefreq +- +-@Defreq {fl, } +-@cindex flush output (@code{fl}) +-@cindex output, flush (@code{fl}) +-@cindex interactive use of @code{gtroff} +-@cindex @code{gtroff}, interactive use +-Instruct @code{gtroff} to flush its output immediately. The intent is +-for interactive use, but this behaviour is currently not implemented in +-@code{gtroff}. Contrary to @acronym{UNIX} @code{troff}, TTY output is +-sent to a device driver also (@code{grotty}), making it non-trivial to +-communicate interactively. +- +-This request causes a line break. +-@endDefreq +- +-@Defreq {backtrace, } +-@cindex backtrace of input stack (@code{backtrace}) +-@cindex input stack, backtrace (@code{backtrace}) +-Print a backtrace of the input stack to the standard error stream. +- +-Consider the following in file @file{test}: +- +-@Example +-.de xxx +-. backtrace +-.. +-.de yyy +-. xxx +-.. +-. +-.yyy +-@endExample +- +-@noindent +-On execution, @code{gtroff} prints the following: +- +-@Example +-test:2: backtrace: macro `xxx' +-test:5: backtrace: macro `yyy' +-test:8: backtrace: file `test' +-@endExample +- +-The option @option{-b} of @code{gtroff} internally calls a variant of +-this request on each error and warning. +-@endDefreq +- +-@Defreg {slimit} +-@cindex input stack, setting limit +-Use the @code{slimit} number register to set the maximum number of +-objects on the input stack. If @code{slimit} is less than or equal +-to@tie{}0, there is no limit set. With no limit, a buggy recursive +-macro can exhaust virtual memory. +- +-The default value is 1000; this is a compile-time constant. +-@endDefreg +- +-@Defreq {warnscale, si} +-Set the scaling indicator used in warnings to @var{si}. Valid values +-for @var{si} are @samp{u}, @samp{i}, @samp{c}, @samp{p}, and @samp{P}. +-At startup, it is set to @samp{i}. +-@endDefreq +- +-@Defreq {spreadwarn, [@Var{limit}]} +-Make @code{gtroff} emit a warning if the additional space inserted for +-each space between words in an output line is larger or equal to +-@var{limit}. A negative value is changed to zero; no argument toggles +-the warning on and off without changing @var{limit}. The default +-scaling indicator is @samp{m}. At startup, @code{spreadwarn} is +-deactivated, and @var{limit} is set to 3@dmn{m}. +- +-For example, +- +-@Example +-.spreadwarn 0.2m +-@endExample +- +-@noindent +-causes a warning if @code{gtroff} must add 0.2@dmn{m} or more for each +-interword space in a line. +- +-This request is active only if text is justified to both margins (using +-@w{@samp{.ad b}}). +-@endDefreq +- +-@cindex warnings +-@code{gtroff} has command line options for printing out more warnings +-(@option{-w}) and for printing backtraces (@option{-b}) when a warning +-or an error occurs. The most verbose level of warnings is @option{-ww}. +- +-@DefreqList {warn, [@Var{flags}]} +-@DefregListEndx {.warn} +-@cindex level of warnings (@code{warn}) +-@cindex warnings, level (@code{warn}) +-Control the level of warnings checked for. The @var{flags} are the sum +-of the numbers associated with each warning that is to be enabled; all +-other warnings are disabled. The number associated with each warning is +-listed below. For example, @w{@code{.warn 0}} disables all warnings, +-and @w{@code{.warn 1}} disables all warnings except that about missing +-glyphs. If no argument is given, all warnings are enabled. +- +-The read-only number register @code{.warn} contains the current warning +-level. +-@endDefreq +- +-@menu +-* Warnings:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Warnings, , Debugging, Debugging +-@subsection Warnings +-@cindex warnings +- +-The warnings that can be given to @code{gtroff} are divided into the +-following categories. The name associated with each warning is used by +-the @option{-w} and @option{-W} options; the number is used by the +-@code{warn} request and by the @code{.warn} register. +- +-@table @samp +-@item char +-@itemx 1 +-Non-existent glyphs.@footnote{@code{char} is a misnomer since it reports +-missing glyphs -- there aren't missing input characters, only invalid +-ones.} This is enabled by default. +- +-@item number +-@itemx 2 +-Invalid numeric expressions. This is enabled by default. +-@xref{Expressions}. +- +-@item break +-@itemx 4 +-@cindex fill mode +-@cindex mode, fill +-In fill mode, lines that could not be broken so that their length was +-less than the line length. This is enabled by default. +- +-@item delim +-@itemx 8 +-Missing or mismatched closing delimiters. +- +-@item el +-@itemx 16 +-@cindex @code{ie} request, and warnings +-@cindex @code{el} request, and warnings +-Use of the @code{el} request with no matching @code{ie} request. +-@xref{if-else}. +- +-@item scale +-@itemx 32 +-Meaningless scaling indicators. +- +-@item range +-@itemx 64 +-Out of range arguments. +- +-@item syntax +-@itemx 128 +-Dubious syntax in numeric expressions. +- +-@item di +-@itemx 256 +-@cindex @code{di} request, and warnings +-@cindex @code{da} request, and warnings +-Use of @code{di} or @code{da} without an argument when there is no +-current diversion. +- +-@item mac +-@itemx 512 +-@cindex @code{de}, @code{de1}, @code{dei} requests, and warnings +-@cindex @code{am}, @code{am1}, @code{ami} requests, and warnings +-@cindex @code{ds}, @code{ds1} requests, and warnings +-@cindex @code{as}, @code{as1} requests, and warnings +-@cindex @code{di} request, and warnings +-@cindex @code{da} request, and warnings +-@cindex @code{box}, @code{boxa} requests, and warnings +-@cindex @code{\*}, and warnings +-Use of undefined strings, macros and diversions. When an undefined +-string, macro, or diversion is used, that string is automatically +-defined as empty. So, in most cases, at most one warning is given for +-each name. +- +-@item reg +-@itemx 1024 +-@cindex @code{nr} request, and warnings +-@cindex @code{\R}, and warnings +-@cindex @code{\n}, and warnings +-Use of undefined number registers. When an undefined number register is +-used, that register is automatically defined to have a value of@tie{}0. +-So, in most cases, at most one warning is given for use of a particular +-name. +- +-@item tab +-@itemx 2048 +-@cindex @code{\t}, and warnings +-Use of a tab character where a number was expected. +- +-@item right-brace +-@itemx 4096 +-@cindex @code{\@}}, and warnings +-Use of @code{\@}} where a number was expected. +- +-@item missing +-@itemx 8192 +-Requests that are missing non-optional arguments. +- +-@item input +-@itemx 16384 +-Invalid input characters. +- +-@item escape +-@itemx 32768 +-Unrecognized escape sequences. When an unrecognized escape sequence +-@code{\@var{X}} is encountered, the escape character is ignored, and +-@var{X} is printed. +- +-@item space +-@itemx 65536 +-@cindex compatibility mode +-Missing space between a request or macro and its argument. This warning +-is given when an undefined name longer than two characters is +-encountered, and the first two characters of the name make a defined +-name. The request or macro is not invoked. When this warning is given, +-no macro is automatically defined. This is enabled by default. This +-warning never occurs in compatibility mode. +- +-@item font +-@itemx 131072 +-Non-existent fonts. This is enabled by default. +- +-@item ig +-@itemx 262144 +-Invalid escapes in text ignored with the @code{ig} request. These are +-conditions that are errors when they do not occur in ignored text. +- +-@item color +-@itemx 524288 +-Color related warnings. +- +-@item file +-@itemx 1048576 +-Missing files. The @code{mso} request gives this warning when the +-requested macro file does not exist. This is enabled by default. +- +-@item all +-All warnings except @samp{di}, @samp{mac} and @samp{reg}. It is +-intended that this covers all warnings that are useful with traditional +-macro packages. +- +-@item w +-All warnings. +-@end table +- +- +-@c ===================================================================== +- +-@node Implementation Differences, , Debugging, gtroff Reference +-@section Implementation Differences +-@cindex implementation differences +-@cindex differences in implementation +-@cindex incompatibilities with @acronym{AT&T} @code{troff} +-@cindex compatibility mode +-@cindex mode, compatibility +- +-GNU @code{troff} has a number of features that cause incompatibilities +-with documents written with old versions of @code{troff}. +- +-@cindex long names +-@cindex names, long +-Long names cause some incompatibilities. @acronym{UNIX} @code{troff} +-interprets +- +-@Example +-.dsabcd +-@endExample +- +-@cindex @code{\*}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\n}, incompatibilities with @acronym{AT&T} @code{troff} +-@noindent +-as defining a string @samp{ab} with contents @samp{cd}. Normally, GNU +-@code{troff} interprets this as a call of a macro named @code{dsabcd}. +-Also @acronym{UNIX} @code{troff} interprets @code{\*[} or @code{\n[} as +-references to a string or number register called @samp{[}. In GNU +-@code{troff}, however, this is normally interpreted as the start of a +-long name. In compatibility mode GNU @code{troff} interprets long names +-in the traditional way (which means that they are not recognized as +-names). +- +-@DefreqList {cp, [@Var{n}]} +-@DefreqItemx {do, cmd} +-@DefregListEndx {.C} +-If @var{n} is missing or non-zero, turn on compatibility mode; +-otherwise, turn it off. +- +-The read-only number register @code{.C} is@tie{}1 if compatibility mode +-is on, 0@tie{}otherwise. +- +-Compatibility mode can be also turned on with the @option{-C} command +-line option. +- +-The @code{do} request turns off compatibility mode while executing its +-arguments as a @code{gtroff} command. However, it does not turn off +-compatibility mode while processing the macro itself. To do that, use +-the @code{de1} request (or manipulate the @code{.C} register manually). +-@xref{Writing Macros}. +- +-@Example +-.do fam T +-@endExample +- +-@noindent +-executes the @code{fam} request when compatibility mode is enabled. +- +-@code{gtroff} restores the previous compatibility setting before +-interpreting any files sourced by the @var{cmd}. +-@endDefreq +- +-@cindex input level in delimited arguments +-@cindex delimited arguments, incompatibilities with @acronym{AT&T} @code{troff} +-Two other features are controlled by @option{-C}. If not in +-compatibility mode, GNU @code{troff} preserves the input level in +-delimited arguments: +- +-@Example +-.ds xx ' +-\w'abc\*(xxdef' +-@endExample +- +-@noindent +-In compatibility mode, the string @samp{72def'} is returned; without +-@option{-C} the resulting string is @samp{168} (assuming a TTY output +-device). +- +-@cindex @code{\f}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\H}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\s}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\S}, incompatibilities with @acronym{AT&T} @code{troff} +-Finally, the escapes @code{\f}, @code{\H}, @code{\m}, @code{\M}, +-@code{\R}, @code{\s}, and @code{\S} are transparent for recognizing the +-beginning of a line only in compatibility mode (this is a rather obscure +-feature). For example, the code +- +-@Example +-.de xx +-Hallo! +-.. +-\fB.xx\fP +-@endExample +- +-@noindent +-prints @samp{Hallo!} in bold face if in compatibility mode, and +-@samp{.xx} in bold face otherwise. +- +-@cindex @code{\A}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\|}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\^}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\&}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\@{}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\@}}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\@key{SP}}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\'}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\`}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\-}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\_}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\!}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\%}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\c}, incompatibilities with @acronym{AT&T} @code{troff} +-GNU @code{troff} does not allow the use of the escape sequences +-@code{\|}, @code{\^}, @code{\&}, @code{\@{}, @code{\@}}, +-@code{\@key{SP}}, @code{\'}, @code{\`}, @code{\-}, @code{\_}, @code{\!}, +-@code{\%}, and @code{\c} in names of strings, macros, diversions, number +-registers, fonts or environments; @acronym{UNIX} @code{troff} does. The +-@code{\A} escape sequence (@pxref{Identifiers}) may be helpful in +-avoiding use of these escape sequences in names. +- +-@cindex fractional point sizes +-@cindex fractional type sizes +-@cindex point sizes, fractional +-@cindex type sizes, fractional +-@cindex sizes, fractional +-@cindex @code{ps} request, incompatibilities with @acronym{AT&T} @code{troff} +-Fractional point sizes cause one noteworthy incompatibility. In +-@acronym{UNIX} @code{troff} the @code{ps} request ignores scale +-indicators and thus +- +-@Example +-.ps 10u +-@endExample +- +-@noindent +-sets the point size to 10@tie{}points, whereas in GNU @code{troff} it +-sets the point size to 10@tie{}scaled points. @xref{Fractional Type +-Sizes}, for more information. +- +-@cindex @code{bd} request, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{cs} request, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{tr} request, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{fp} request, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex input characters and output glyphs, compatibility with @acronym{AT&T} @code{troff} +-@cindex output glyphs, and input characters,compatibility with @acronym{AT&T} @code{troff} +-@cindex characters, input, and output glyphs, compatibility with @acronym{AT&T} @code{troff} +-@cindex glyphs, output, and input characters, compatibility with @acronym{AT&T} @code{troff} +-In GNU @code{troff} there is a fundamental difference between +-(unformatted) input characters and (formatted) output glyphs. +-Everything that affects how a glyph is output is stored with the glyph +-node; once a glyph node has been constructed it is unaffected by any +-subsequent requests that are executed, including @code{bd}, @code{cs}, +-@code{tkf}, @code{tr}, or @code{fp} requests. Normally glyphs are +-constructed from input characters at the moment immediately before the +-glyph is added to the current output line. Macros, diversions and +-strings are all, in fact, the same type of object; they contain lists of +-input characters and glyph nodes in any combination. A glyph node does +-not behave like an input character for the purposes of macro processing; +-it does not inherit any of the special properties that the input +-character from which it was constructed might have had. For example, +- +-@Example +-.di x +-\\\\ +-.br +-.di +-.x +-@endExample +- +-@cindex printing backslash (@code{\\}, @code{\e}, @code{\E}, @code{\[rs]}) +-@cindex backslash, printing (@code{\\}, @code{\e}, @code{\E}, @code{\[rs]}) +-@cindex @code{\e}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\!}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex @code{\?}, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex transparent output, incompatibilities with @acronym{AT&T} @code{troff} +-@cindex output, transparent, incompatibilities with @acronym{AT&T} @code{troff} +-@noindent +-prints @samp{\\} in GNU @code{troff}; each pair of input backslashes is +-turned into one output backslash and the resulting output backslashes +-are not interpreted as escape characters when they are reread. +-@acronym{UNIX} @code{troff} would interpret them as escape characters +-when they were reread and would end up printing one @samp{\}. The +-correct way to obtain a printable backslash is to use the @code{\e} +-escape sequence: This always prints a single instance of the current +-escape character, regardless of whether or not it is used in a +-diversion; it also works in both GNU @code{troff} and @acronym{UNIX} +-@code{troff}.@footnote{To be completely independent of the current +-escape character, use @code{\(rs}, which represents a reverse solidus +-(backslash) glyph.} To store, for some reason, an escape sequence in a +-diversion that is interpreted when the diversion is reread, either use +-the traditional @code{\!} transparent output facility, or, if this is +-unsuitable, the new @code{\?} escape sequence. +- +-@xref{Diversions}, and @ref{Gtroff Internals}, for more information. +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Preprocessors, Output Devices, gtroff Reference, Top +-@chapter Preprocessors +-@cindex preprocessors +- +-This chapter describes all preprocessors that come with @code{groff} or +-which are freely available. +- +-@menu +-* geqn:: +-* gtbl:: +-* gpic:: +-* ggrn:: +-* grap:: +-* gchem:: +-* grefer:: +-* gsoelim:: +-* preconv:: +-@end menu +- +- +-@c ===================================================================== +- +-@node geqn, gtbl, Preprocessors, Preprocessors +-@section @code{geqn} +-@cindex @code{eqn}, the program +-@cindex @code{geqn}, the program +- +-@c XXX +- +-@menu +-* Invoking geqn:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking geqn, , geqn, geqn +-@subsection Invoking @code{geqn} +-@cindex invoking @code{geqn} +-@cindex @code{geqn}, invoking +- +-@c XXX +- +- +-@c ===================================================================== +- +-@node gtbl, gpic, geqn, Preprocessors +-@section @code{gtbl} +-@cindex @code{tbl}, the program +-@cindex @code{gtbl}, the program +- +-@c XXX +- +-@menu +-* Invoking gtbl:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking gtbl, , gtbl, gtbl +-@subsection Invoking @code{gtbl} +-@cindex invoking @code{gtbl} +-@cindex @code{gtbl}, invoking +- +-@c XXX +- +- +-@c ===================================================================== +- +-@node gpic, ggrn, gtbl, Preprocessors +-@section @code{gpic} +-@cindex @code{pic}, the program +-@cindex @code{gpic}, the program +- +-@c XXX +- +-@menu +-* Invoking gpic:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking gpic, , gpic, gpic +-@subsection Invoking @code{gpic} +-@cindex invoking @code{gpic} +-@cindex @code{gpic}, invoking +- +-@c XXX +- +- +-@c ===================================================================== +- +-@node ggrn, grap, gpic, Preprocessors +-@section @code{ggrn} +-@cindex @code{grn}, the program +-@cindex @code{ggrn}, the program +- +-@c XXX +- +-@menu +-* Invoking ggrn:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking ggrn, , ggrn, ggrn +-@subsection Invoking @code{ggrn} +-@cindex invoking @code{ggrn} +-@cindex @code{ggrn}, invoking +- +-@c XXX +- +- +-@c ===================================================================== +- +-@node grap, gchem, ggrn, Preprocessors +-@section @code{grap} +-@cindex @code{grap}, the program +- +-A free implementation of @code{grap}, written by Ted Faber, +-is available as an extra package from the following address: +- +-@display +-@uref{http://www.lunabase.org/~faber/Vault/software/grap/} +-@end display +- +- +-@c ===================================================================== +- +-@node gchem, grefer, grap, Preprocessors +-@section @code{gchem} +-@cindex @code{chem}, the program +-@cindex @code{gchem}, the program +- +-@c XXX +- +-@menu +-* Invoking gchem:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking gchem, , gchem, gchem +-@subsection Invoking @code{gchem} +-@cindex invoking @code{gchem} +-@cindex @code{gchem}, invoking +- +-@c XXX +- +- +-@c ===================================================================== +- +-@node grefer, gsoelim, gchem, Preprocessors +-@section @code{grefer} +-@cindex @code{refer}, the program +-@cindex @code{grefer}, the program +- +-@c XXX +- +-@menu +-* Invoking grefer:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking grefer, , grefer, grefer +-@subsection Invoking @code{grefer} +-@cindex invoking @code{grefer} +-@cindex @code{grefer}, invoking +- +-@c XXX +- +- +-@c ===================================================================== +- +-@node gsoelim, preconv, grefer, Preprocessors +-@section @code{gsoelim} +-@cindex @code{soelim}, the program +-@cindex @code{gsoelim}, the program +- +-@c XXX +- +-@menu +-* Invoking gsoelim:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking gsoelim, , gsoelim, gsoelim +-@subsection Invoking @code{gsoelim} +-@cindex invoking @code{gsoelim} +-@cindex @code{gsoelim}, invoking +- +-@c XXX +- +- +-@c ===================================================================== +- +-@node preconv, , gsoelim, Preprocessors +-@section @code{preconv} +-@cindex @code{preconv}, the program +- +-@c XXX +- +-@menu +-* Invoking preconv:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking preconv, , preconv, preconv +-@subsection Invoking @code{preconv} +-@cindex invoking @code{preconv} +-@cindex @code{preconv}, invoking +- +-@c XXX +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Output Devices, File formats, Preprocessors, Top +-@chapter Output Devices +-@cindex output devices +-@cindex devices for output +- +-@c XXX +- +-@menu +-* Special Characters:: +-* grotty:: +-* grops:: +-* gropdf:: +-* grodvi:: +-* grolj4:: +-* grolbp:: +-* grohtml:: +-* gxditview:: +-@end menu +- +- +-@c ===================================================================== +- +-@node Special Characters, grotty, Output Devices, Output Devices +-@section Special Characters +-@cindex special characters +-@cindex characters, special +- +-@c XXX +- +-@xref{Font Files}. +- +- +-@c ===================================================================== +- +-@node grotty, grops, Special Characters, Output Devices +-@section @code{grotty} +-@cindex @code{grotty}, the program +- +-The postprocessor @code{grotty} translates the output from GNU +-@code{troff} into a form suitable for typewriter-like devices. It is +-fully documented on its manual page, @cite{grotty(1)}. +- +-@menu +-* Invoking grotty:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking grotty, , grotty, grotty +-@subsection Invoking @code{grotty} +-@cindex invoking @code{grotty} +-@cindex @code{grotty}, invoking +- +-The postprocessor @command{grotty} accepts the following command-line +-options: +- +-@table @option +-@item -b +-Do not overstrike bold glyphs. Ignored if @option{-c} isn't used. +- +-@item -B +-Do not underline bold-italic glyphs. Ignored if @option{-c} isn't +-used. +- +-@item -c +-Use overprint and disable colours for printing on legacy Teletype +-printers (see below). +- +-@item -d +-Do not render lines (this is, ignore all @code{\D} escapes). +- +-@item -f +-Use form feed control characters in the output. +- +-@item -F@var{dir} +-Put the directory @file{@var{dir}/dev@var{name}} in front of the +-search path for the font and device description files, given the +-target device @var{name}. +- +-@item -h +-Use horizontal tabs for sequences of 8 space characters. +- +-@item -i +-Request italic glyphs from the terminal. Ignored if @option{-c} is +-active. +- +-@item -o +-Do not overstrike. +- +-@item -r +-Highlight italic glyphs. Ignored if @option{-c} is active. +- +-@item -u +-Do not underline italic glyphs. Ignored if @option{-c} isn't used. +- +-@item -U +-Do not overstrike bold-italic glyphs. Ignored if @option{-c} isn't +-used. +- +-@item -v +-Print the version number. +-@end table +- +-@pindex less +-@cindex Teletype +-@cindex ISO 6249 SGR +-@cindex terminal control sequences +-@cindex control sequences, for terminals +-The @option{-c} mode for TTY output devices means that underlining is +-done by emitting sequences of @samp{_} and @samp{^H} (the backspace +-character) before the actual character. Literally, this is printing +-an underline character, then moving the caret back one character +-position, and printing the actual character at the same position as +-the underline character (similar to a typewriter). Usually, a modern +-terminal can't interpret this (and the original Teletype machines for +-which this sequence was appropriate are no longer in use). You need +-a pager program like @code{less} that translates this into +-ISO@tie{}6429 SGR sequences to control terminals. +- +- +-@c ===================================================================== +- +-@node grops, gropdf, grotty, Output Devices +-@section @code{grops} +-@cindex @code{grops}, the program +- +-The postprocessor @command{grops} translates the output from GNU +-@command{troff} into a form suitable for Adobe @sc{PostScript} +-devices. It is fully documented on its manual page, @cite{grops(1)}. +- +- +-@menu +-* Invoking grops:: +-* Embedding PostScript:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking grops, Embedding PostScript, grops, grops +-@subsection Invoking @code{grops} +-@cindex invoking @code{grops} +-@cindex @code{grops}, invoking +- +-The postprocessor @code{grops} accepts the following command-line +-options: +- +-@table @option +-@item -b@var{flags} +-Use backward compatibility settings given by @var{flags} as +-documented in the @cite{grops(1)} manual page. Overrides the command +-@option{broken} in the @file{DESC} file. +- +-@item -c@var{n} +-Print @var{n} copies of each page. +- +-@item -F@var{dir} +-Put the directory @file{@var{dir}/dev@var{name}} in front of the +-search path for the font, prologue and device description files, +-given the target device @var{name}, usually @strong{ps}. +- +-@item -g +-Tell the printer to guess the page length. Useful for printing +-vertically centered pages when the paper dimensions are determined at +-print time. +- +-@item -I@var{path} @dots{} +-Consider the directory @file{@var{path}} for searching included files +-specified with relative paths. The current directory is searched as +-fallback. +- +-@item -l +-Use landscape orientation. +- +-@item -m +-Use manual feed. +- +-@item -p@var{papersize} +-Set the page dimensions. Overrides the commands @option{papersize}, +-@option{paperlength}, and @option{paperwidth} in the @file{DESC} +-file. See the @cite{groff_font(5)} manual page for details. +- +-@item -P@var{prologue} +-Use the @var{prologue} in the font path as the prologue instead of +-the default @file{prologue}. Overrides the environment variable +-@env{GROPS_PROLOGUE}. +- +-@item -w@var{n} +-Set the line thickness to @var{n}/1000@dmn{em}. Overrides the +-default value @var{n} = 40. +- +-@item -v +-Print the version number. +-@end table +- +-@c --------------------------------------------------------------------- +- +-@node Embedding PostScript, , Invoking grops, grops +-@subsection Embedding @sc{PostScript} +-@cindex embedding PostScript +-@cindex PostScript, embedding +- +-The escape sequence +- +-@code{\X'ps: import @var{file} @var{llx} @var{lly} @var{urx} @var{ury} +- @var{width} [@var{height}]'} +- +-@noindent +-places a rectangle of the specified @var{width} containing the +-@sc{PostScript} drawing from file @var{file} bound by the box from +-@var{llx} @var{lly} to @var{urx} @var{ury} (in @sc{PostScript} +-coordinates) at the insertion point. If @var{height} is not +-specified, the embedded drawing is scaled proportionally. +- +-@xref{Miscellaneous}, for the @code{psbb} request, which automatically +-generates the bounding box. +- +-This escape sequence is used internally by the macro @code{PSPIC} +-(see the @cite{groff_tmac(5)} manual page). +- +- +-@c ===================================================================== +- +-@node gropdf, grodvi, grops, Output Devices +-@section @code{gropdf} +-@cindex @code{gropdf}, the program +- +-The postprocessor @command{gropdf} translates the output from GNU +-@command{troff} into a form suitable for Adobe PDF devices. It is fully +-documented on its manual page, @cite{gropdf(1)}. +- +-@menu +-* Invoking gropdf:: +-* Embedding PDF:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking gropdf, Embedding PDF, gropdf, gropdf +-@subsection Invoking @code{gropdf} +-@cindex invoking @code{gropdf} +-@cindex @code{gropdf}, invoking +- +-The postprocessor @code{gropdf} accepts the following command-line +-options: +- +-@table @option +-@item -d +-Produce uncompressed PDFs that include debugging comments. +- +-@item -e +-This forces @code{gropdf} to embed all used fonts in the PDF, +-even if they are one of the 14 base Adobe fonts. +- +-@item -F@var{dir} +-Put the directory @file{@var{dir}/dev@var{name}} in front of the +-search path for the font, prologue and device description files, +-given the target device @var{name}, usually @strong{pdf}. +- +-@item -y@var{foundry} +-This forces the use of a different font foundry. +- +-@item -l +-Use landscape orientation. +- +-@item -p@var{papersize} +-Set the page dimensions. Overrides the commands @option{papersize}, +-@option{paperlength}, and @option{paperwidth} in the @file{DESC} +-file. See the @cite{groff_font(5)} manual page for details. +- +-@item -v +-Print the version number. +- +-@item -s +-Append a comment line to end of PDF showing statistics, i.e. number of +-pages in document. Ghostscript's @cite{ps2pdf(1)} complains about this +-line if it is included, but works anyway. +- +-@item -u@var{filename} +-@code{gropdf} normally includes a ToUnicode CMap with any font created +-using @file{text.enc} as the encoding file, this makes it easier to +-search for words that contain ligatures. You can include your own CMap +-by specifying a @var{filename} or have no CMap at all by omitting the +-@var{filename}. +-@end table +- +-@c --------------------------------------------------------------------- +- +-@node Embedding PDF, , Invoking gropdf, gropdf +-@subsection Embedding PDF +-@cindex embedding PDF +-@cindex PDF, embedding +- +-The escape sequence +- +-@code{\X'pdf: pdfpic @var{file} @var{alignment} @var{width} [@var{height}] +- [@var{linelength}]'} +- +-@noindent +-places a rectangle of the specified @var{width} containing the PDF +-drawing from file @var{file} of desired @var{width} and @var{height} (if +-@var{height} is missing or zero then it is scaled proportionally). If +-@var{alignment} is @code{-L} the drawing is left aligned. If it is +-@code{-C} or @code{-R} a @var{linelength} greater than the width of the +-drawing is required as well. If @var{width} is specified as zero then +-the width is scaled in proportion to the height. +- +- +-@c ===================================================================== +- +-@node grodvi, grolj4, gropdf, Output Devices +-@section @code{grodvi} +-@cindex @code{grodvi}, the program +- +-The postprocessor @command{grodvi} translates the output from GNU +-@command{troff} into the @strong{DVI} output format compatible with +-the @strong{@TeX{}} document preparation system. It is fully +-documented on its manual page, @cite{grodvi(1)}. +- +-@menu +-* Invoking grodvi:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking grodvi, , grodvi, grodvi +-@subsection Invoking @code{grodvi} +-@cindex invoking @code{grodvi} +-@cindex @code{grodvi}, invoking +- +-The postprocessor @code{grodvi} accepts the following command-line +-options: +- +-@table @option +-@item -d +-Do not use @strong{tpic} specials to implement drawing commands. +- +-@item -F@var{dir} +-Put the directory @file{@var{dir}/dev@var{name}} in front of the +-search path for the font and device description files, given the +-target device @var{name}, usually @strong{dvi}. +- +-@item -l +-Use landscape orientation. +- +-@item -p@var{papersize} +-Set the page dimensions. Overrides the commands @option{papersize}, +-@option{paperlength}, and @option{paperwidth} in the @file{DESC} +-file. See @cite{groff_font(5)} manual page for details. +- +-@item -v +-Print the version number. +- +-@item -w@var{n} +-Set the line thickness to @var{n}/1000@dmn{em}. Overrides the +-default value @var{n} = 40. +-@end table +- +- +-@c ===================================================================== +- +-@node grolj4, grolbp, grodvi, Output Devices +-@section @code{grolj4} +-@cindex @code{grolj4}, the program +- +-The postprocessor @command{grolj4} translates the output from GNU +-@command{troff} into the @strong{PCL5} output format suitable for +-printing on a @strong{HP LaserJet@tie{}4} printer. It is fully +-documented on its manual page, @cite{grolj4(1)}. +- +-@menu +-* Invoking grolj4:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking grolj4, , grolj4, grolj4 +-@subsection Invoking @code{grolj4} +-@cindex invoking @code{grolj4} +-@cindex @code{grolj4}, invoking +- +-The postprocessor @code{grolj4} accepts the following command-line +-options: +- +-@table @option +-@item -c@var{n} +-Print @var{n} copies of each page. +- +-@item -F@var{dir} +-Put the directory @file{@var{dir}/dev@var{name}} in front of the +-search path for the font and device description files, given the +-target device @var{name}, usually @strong{lj4}. +- +-@item -l +-Use landscape orientation. +- +-@item -p@var{size} +-Set the page dimensions. Valid values for @var{size} are: +-@code{letter}, @code{legal}, @code{executive}, @code{a4}, +-@code{com10}, @code{monarch}, @code{c5}, @code{b5}, @code{d1}. +- +-@item -v +-Print the version number. +- +-@item -w@var{n} +-Set the line thickness to @var{n}/1000@dmn{em}. Overrides the +-default value @var{n} = 40. +-@end table +- +-The special drawing command @code{\D'R @var{dh} @var{dv}'} draws a +-horizontal rectangle from the current position to the position at +-offset (@var{dh},@var{dv}). +- +- +-@c ===================================================================== +- +-@node grolbp, grohtml, grolj4, Output Devices +-@section @code{grolbp} +-@cindex @code{grolbp}, the program +- +-The postprocessor @command{grolbp} translates the output from GNU +-@command{troff} into the @strong{LBP} output format suitable for +-printing on @strong{Canon CAPSL} printers. It is fully documented on +-its manual page, @cite{grolbp(1)}. +- +-@menu +-* Invoking grolbp:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking grolbp, , grolbp, grolbp +-@subsection Invoking @code{grolbp} +-@cindex invoking @code{grolbp} +-@cindex @code{grolbp}, invoking +- +-The postprocessor @code{grolbp} accepts the following command-line +-options: +- +-@table @option +-@item -c@var{n} +-Print @var{n} copies of each page. +- +-@item -F@var{dir} +-Put the directory @file{@var{dir}/dev@var{name}} in front of the +-search path for the font, prologue and device description files, +-given the target device @var{name}, usually @strong{lbp}. +- +-@item -l +-Use landscape orientation. +- +-@item -o@var{orientation} +-Use the @var{orientation} specified: @code{portrait} or +-@code{landscape}. +- +-@item -p@var{papersize} +-Set the page dimensions. See @cite{groff_font(5)} manual page for +-details. +- +-@item -w@var{n} +-Set the line thickness to @var{n}/1000@dmn{em}. Overrides the +-default value @var{n} = 40. +- +-@item -v +-Print the version number. +- +-@item -h +-Print command-line help. +-@end table +- +- +-@c ===================================================================== +- +-@node grohtml, gxditview, grolbp, Output Devices +-@section @code{grohtml} +-@cindex @code{grohtml}, the program +- +-The @code{grohtml} front end (which consists of a preprocessor, +-@code{pre-grohtml}, and a device driver, @code{post-grohtml}) translates +-the output of GNU @code{troff} to @acronym{HTML}. Users should always +-invoke @code{grohtml} via the @code{groff} command with a @code{\-Thtml} +-option. If no files are given, @code{grohtml} will read the standard +-input. A filename of @code{-} will also cause @code{grohtml} to read +-the standard input. @acronym{HTML} output is written to the standard +-output. When @code{grohtml} is run by @code{groff}, options can be +-passed to @code{grohtml} using @code{groff}'s @option{-P} option. +- +-@code{grohtml} invokes @code{groff} twice. In the first pass, pictures, +-equations, and tables are rendered using the @code{ps} device, and in +-the second pass @acronym{HTML} output is generated by the @code{html} +-device. +- +-@code{grohtml} always writes output in @code{UTF-8} encoding and has +-built-in entities for all non-composite unicode characters. In spite of +-this, @code{groff} may issue warnings about unknown special characters +-if they can't be found during the first pass. Such warnings can be +-safely ignored unless the special characters appear inside a table or +-equation, in which case glyphs for these characters must be defined for +-the @code{ps} device as well. +- +-This output device is fully documented on its manual page, +-@cite{grohtml(1)}. +- +-@menu +-* Invoking grohtml:: +-* grohtml specific registers and strings:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking grohtml, grohtml specific registers and strings, grohtml, grohtml +-@subsection Invoking @code{grohtml} +-@cindex invoking @code{grohtml} +-@cindex @code{grohtml}, invoking +- +-The postprocessor @code{grohtml} accepts the following command-line +-options: +- +-@table @option +-@item -a@var{bits} +-Use this number of @var{bits} (= 1, 2 or 4) for text antialiasing. +-Default: @var{bits} = 4. +- +-@item -a0 +-Do not use text antialiasing. +- +-@item -b +-Use white background. +- +-@item -D@var{dir} +-Store rendered images in the directory @file{@var{dir}}. +- +-@item -F@var{dir} +-Put the directory @file{@var{dir}/dev@var{name}} in front of the +-search path for the font, prologue and device description files, +-given the target device @var{name}, usually @strong{html}. +- +-@item -g@var{bits} +-Use this number of @var{bits} (= 1, 2 or 4) for antialiasing of +-drawings. Default: @var{bits} = 4. +- +-@item -g0 +-Do not use antialiasing for drawings. +- +-@item -h +-Use the @code{B} element for section headings. +- +-@item -i@var{resolution} +-Use the @var{resolution} for rendered images. Default: +-@var{resolution} = 100@dmn{dpi}. +- +-@item -I@var{stem} +-Set the images' @var{stem name}. Default: @var{stem} = +-@file{grohtml-@var{XXX}} (@var{XXX} is the process ID). +- +-@item -j@var{stem} +-Place each section in a separate file called +-@file{@var{stem}-@var{n}.html} (where @var{n} is a generated section +-number). +- +-@item -l +-Do not generate the table of contents. +- +-@item -n +-Generate simple fragment identifiers. +- +-@item -o@var{offset} +-Use vertical paddding @var{offset} for images. +- +-@item -p +-Display the page rendering progress to @code{stderr}. +- +-@item -r +-Do not use horizontal rules to separate headers and footers. +- +-@item -s@var{size} +-Set the base font size, to be modified using the elements @code{BIG} +-and @code{SMALL}. +- +-@item -S@var{level} +-Generate separate files for sections at level @var{level}. +- +-@item -v +-Print the version number. +- +-@item -V +-Generate a validator button at the bottom. +- +-@item -y +-Generate a signature of groff after the validator button, if any. +-@end table +- +- +-@c --------------------------------------------------------------------- +- +-@node grohtml specific registers and strings, , Invoking grohtml, grohtml +-@subsection @code{grohtml} specific registers and strings +-@cindex registers specific to @code{grohtml} +-@cindex strings specific to @code{grohtml} +-@cindex @code{grohtml}, registers and strings +- +-@DefmpregList {ps4html, grohtml} +-@DefstrListEndx {www-image-template, grohtml} +-The registers @code{ps4html} and @code{www-image-template} are defined +-by the @code{pre-grohtml} preprocessor. @code{pre-grohtml} reads in the +-@code{troff} input, marks up the inline equations and passes the result +-firstly to +- +-@Example +-troff -Tps -rps4html=1 -dwww-image-template=@var{template} +-@endExample +- +-@noindent +-and secondly to +- +-@Example +-troff -Thtml +-@endExample +- +-@noindent +-or +- +-@Example +-troff -Txhtml +-@endExample +- +-@cindex MathML +-The @sc{PostScript} device is used to create all the image files (for +-@option{-Thtml}; if @option{-Txhtml} is used, all equations are passed +-to @code{geqn} to produce @acronym{MathML}, and the register +-@code{ps4html} enables the macro sets to ignore floating keeps, footers, +-and headings. +- +-The register @code{www-image-template} is set to the user specified +-template name or the default name. +-@endDefmpreg +- +- +-@c ===================================================================== +- +-@node gxditview, , grohtml, Output Devices +-@section @code{gxditview} +-@cindex @code{gxditview}, the program +- +-@c XXX +- +-@menu +-* Invoking gxditview:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Invoking gxditview, , gxditview, gxditview +-@subsection Invoking @code{gxditview} +-@cindex invoking @code{gxditview} +-@cindex @code{gxditview}, invoking +- +-@c XXX +-@c X11's xditview +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node File formats, Installation, Output Devices, Top +-@chapter File formats +-@cindex file formats +-@cindex formats, file +- +-All files read and written by @code{gtroff} are text files. The +-following two sections describe their format. +- +-@menu +-* gtroff Output:: +-* Font Files:: +-@end menu +- +- +-@c ===================================================================== +- +-@node gtroff Output, Font Files, File formats, File formats +-@section @code{gtroff} Output +-@cindex @code{gtroff}, output +-@cindex output, @code{gtroff} +- +-This section describes the intermediate output format of GNU +-@code{troff}. This output is produced by a run of @code{gtroff} before +-it is fed into a device postprocessor program. +- +-As @code{groff} is a wrapper program around @code{gtroff} that +-automatically calls a postprocessor, this output does not show up +-normally. This is why it is called @dfn{intermediate}. @code{groff} +-provides the option @option{-Z} to inhibit postprocessing, such that the +-produced intermediate output is sent to standard output just like +-calling @code{gtroff} manually. +- +-@cindex troff output +-@cindex output, troff +-@cindex intermediate output +-@cindex output, intermediate +-Here, the term @dfn{troff output} describes what is output by +-@code{gtroff}, while @dfn{intermediate output} refers to the language +-that is accepted by the parser that prepares this output for the +-postprocessors. This parser is smarter on whitespace and implements +-obsolete elements for compatibility, otherwise both formats are the +-same.@footnote{The parser and postprocessor for intermediate output can +-be found in the file@* +-@file{@var{groff-source-dir}/src/libs/libdriver/input.cpp}.} +- +-The main purpose of the intermediate output concept is to facilitate the +-development of postprocessors by providing a common programming +-interface for all devices. It has a language of its own that is +-completely different from the @code{gtroff} language. While the +-@code{gtroff} language is a high-level programming language for text +-processing, the intermediate output language is a kind of low-level +-assembler language by specifying all positions on the page for writing +-and drawing. +- +-The intermediate output produced by @code{gtroff} is fairly readable, +-while output from @acronym{AT&T} @code{troff} is rather hard to +-understand because of strange habits that are still supported, but not +-used any longer by @code{gtroff}. +- +-@menu +-* Language Concepts:: +-* Command Reference:: +-* Intermediate Output Examples:: +-* Output Language Compatibility:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node Language Concepts, Command Reference, gtroff Output, gtroff Output +-@subsection Language Concepts +- +-During the run of @code{gtroff}, the input data is cracked down to the +-information on what has to be printed at what position on the intended +-device. So the language of the intermediate output format can be quite +-small. Its only elements are commands with and without arguments. In +-this section, the term @dfn{command} always refers to the intermediate +-output language, and never to the @code{gtroff} language used for +-document formatting. There are commands for positioning and text +-writing, for drawing, and for device controlling. +- +-@menu +-* Separation:: +-* Argument Units:: +-* Document Parts:: +-@end menu +- +-@node Separation, Argument Units, Language Concepts, Language Concepts +-@subsubsection Separation +- +-@acronym{AT&T} @code{troff} output has strange requirements on +-whitespace. The @code{gtroff} output parser, however, is smart about +-whitespace by making it maximally optional. The whitespace characters, +-i.e., the tab, space, and newline characters, always have a syntactical +-meaning. They are never printable because spacing within the output is +-always done by positioning commands. +- +-Any sequence of space or tab characters is treated as a single +-@dfn{syntactical space}. It separates commands and arguments, but is +-only required when there would occur a clashing between the command code +-and the arguments without the space. Most often, this happens when +-variable-length command names, arguments, argument lists, or command +-clusters meet. Commands and arguments with a known, fixed length need +-not be separated by syntactical space. +- +-A line break is a syntactical element, too. Every command argument can +-be followed by whitespace, a comment, or a newline character. Thus a +-@dfn{syntactical line break} is defined to consist of optional +-syntactical space that is optionally followed by a comment, and a +-newline character. +- +-The normal commands, those for positioning and text, consist of a single +-letter taking a fixed number of arguments. For historical reasons, the +-parser allows to stack such commands on the same line, but fortunately, +-in @code{gtroff}'s intermediate output, every command with at least one +-argument is followed by a line break, thus providing excellent +-readability. +- +-The other commands -- those for drawing and device controlling -- have a +-more complicated structure; some recognize long command names, and some +-take a variable number of arguments. So all @samp{D} and @samp{x} +-commands were designed to request a syntactical line break after their +-last argument. Only one command, @w{@samp{x X}}, has an argument that +-can stretch over several lines; all other commands must have all of +-their arguments on the same line as the command, i.e., the arguments may +-not be split by a line break. +- +-Empty lines (these are lines containing only space and/or a comment), +-can occur everywhere. They are just ignored. +- +-@node Argument Units, Document Parts, Separation, Language Concepts +-@subsubsection Argument Units +- +-Some commands take integer arguments that are assumed to represent +-values in a measurement unit, but the letter for the corresponding scale +-indicator is not written with the output command arguments. Most +-commands assume the scale indicator @samp{u}, the basic unit of the +-device, some use @samp{z}, the scaled point unit of the device, while +-others, such as the color commands, expect plain integers. +- +-Note that single characters can have the eighth bit set, as can the +-names of fonts and special characters. The names of characters and +-fonts can be of arbitrary length. A character that is to be printed is +-always in the current font. +- +-A string argument is always terminated by the next whitespace character +-(space, tab, or newline); an embedded @samp{#} character is regarded as +-part of the argument, not as the beginning of a comment command. An +-integer argument is already terminated by the next non-digit character, +-which then is regarded as the first character of the next argument or +-command. +- +-@node Document Parts, , Argument Units, Language Concepts +-@subsubsection Document Parts +- +-A correct intermediate output document consists of two parts, the +-@dfn{prologue} and the @dfn{body}. +- +-The task of the prologue is to set the general device parameters using +-three exactly specified commands. @code{gtroff}'s prologue is +-guaranteed to consist of the following three lines (in that order): +- +-@Example +-x T @var{device} +-x res @var{n} @var{h} @var{v} +-x init +-@endExample +- +-@noindent +-with the arguments set as outlined in @ref{Device Control Commands}. +-Note that the parser for the intermediate output format is able to +-swallow additional whitespace and comments as well even in the prologue. +- +-The body is the main section for processing the document data. +-Syntactically, it is a sequence of any commands different from the ones +-used in the prologue. Processing is terminated as soon as the first +-@w{@samp{x stop}} command is encountered; the last line of any +-@code{gtroff} intermediate output always contains such a command. +- +-Semantically, the body is page oriented. A new page is started by a +-@samp{p} command. Positioning, writing, and drawing commands are always +-done within the current page, so they cannot occur before the first +-@samp{p} command. Absolute positioning (by the @samp{H} and @samp{V} +-commands) is done relative to the current page; all other positioning is +-done relative to the current location within this page. +- +-@c --------------------------------------------------------------------- +- +-@node Command Reference, Intermediate Output Examples, Language Concepts, gtroff Output +-@subsection Command Reference +- +-This section describes all intermediate output commands, both from +-@acronym{AT&T} @code{troff} as well as the @code{gtroff} extensions. +- +-@menu +-* Comment Command:: +-* Simple Commands:: +-* Graphics Commands:: +-* Device Control Commands:: +-* Obsolete Command:: +-@end menu +- +-@node Comment Command, Simple Commands, Command Reference, Command Reference +-@subsubsection Comment Command +- +-@table @code +-@item #@var{anything}@angles{end of line} +-A comment. Ignore any characters from the @samp{#} character up to the +-next newline character. +- +-This command is the only possibility for commenting in the intermediate +-output. Each comment can be preceded by arbitrary syntactical space; +-every command can be terminated by a comment. +-@end table +- +-@node Simple Commands, Graphics Commands, Comment Command, Command Reference +-@subsubsection Simple Commands +- +-The commands in this subsection have a command code consisting of a +-single character, taking a fixed number of arguments. Most of them are +-commands for positioning and text writing. These commands are smart +-about whitespace. Optionally, syntactical space can be inserted before, +-after, and between the command letter and its arguments. All of these +-commands are stackable, i.e., they can be preceded by other simple +-commands or followed by arbitrary other commands on the same line. A +-separating syntactical space is only necessary when two integer +-arguments would clash or if the preceding argument ends with a string +-argument. +- +-@table @code +-@ignore +-.if (\n[@USE_ENV_STACK] == 1) \{\ +-.command { +-Open a new environment by copying the actual device configuration data +-to the environment stack. +-. +-The current environment is setup by the device specification and +-manipulated by the setting commands. +-. +-. +-.command } +-Close the actual environment (opened by a preceding +-.BR { \~command) +-and restore the previous environment from the environment +-stack as the actual device configuration data. +-. +-\} \" endif @USE_ENV_STACK +-@end ignore +- +-@item C @var{xxx}@angles{whitespace} +-Print a special character named @var{xxx}. The trailing syntactical +-space or line break is necessary to allow glyph names of arbitrary +-length. The glyph is printed at the current print position; the glyph's +-size is read from the font file. The print position is not changed. +- +-@item c @var{g} +-Print glyph@tie{}@var{g} at the current print +-position;@footnote{@samp{c} is actually a misnomer since it outputs a +-glyph.} the glyph's size is read from the font file. The print position +-is not changed. +- +-@item f @var{n} +-Set font to font number@tie{}@var{n} (a non-negative integer). +- +-@item H @var{n} +-Move right to the absolute vertical position@tie{}@var{n} (a +-non-negative integer in basic units @samp{u} relative to left edge of +-current page. +- +-@item h @var{n} +-Move @var{n} (a non-negative integer) basic units @samp{u} horizontally +-to the right. The original @acronym{UNIX} troff manual allows negative +-values for @var{n} also, but @code{gtroff} doesn't use this. +- +-@item m @var{color-scheme} @r{[}@var{component} @dots{}@r{]} +-Set the color for text (glyphs), line drawing, and the outline of +-graphic objects using different color schemes; the analoguous command +-for the filling color of graphic objects is @samp{DF}. The color +-components are specified as integer arguments between 0 and 65536. The +-number of color components and their meaning vary for the different +-color schemes. These commands are generated by @code{gtroff}'s escape +-sequence @code{\m}. No position changing. These commands are a +-@code{gtroff} extension. +- +-@table @code +-@item mc @var{cyan} @var{magenta} @var{yellow} +-Set color using the CMY color scheme, having the 3@tie{}color components +-@var{cyan}, @var{magenta}, and @var{yellow}. +- +-@item md +-Set color to the default color value (black in most cases). No +-component arguments. +- +-@item mg @var{gray} +-Set color to the shade of gray given by the argument, an integer between +-0 (black) and 65536 (white). +- +-@item mk @var{cyan} @var{magenta} @var{yellow} @var{black} +-Set color using the CMYK color scheme, having the 4@tie{}color +-components @var{cyan}, @var{magenta}, @var{yellow}, and @var{black}. +- +-@item mr @var{red} @var{green} @var{blue} +-Set color using the RGB color scheme, having the 3@tie{}color components +-@var{red}, @var{green}, and @var{blue}. +-@end table +- +-@item N @var{n} +-Print glyph with index@tie{}@var{n} (a non-negative integer) of the +-current font. This command is a @code{gtroff} extension. +- +-@item n @var{b} @var{a} +-Inform the device about a line break, but no positioning is done by this +-command. In @acronym{AT&T} @code{troff}, the integer arguments @var{b} +-and@tie{}@var{a} informed about the space before and after the current +-line to make the intermediate output more human readable without +-performing any action. In @code{groff}, they are just ignored, but they +-must be provided for compatibility reasons. +- +-@item p @var{n} +-Begin a new page in the outprint. The page number is set +-to@tie{}@var{n}. This page is completely independent of pages formerly +-processed even if those have the same page number. The vertical +-position on the outprint is automatically set to@tie{}0. All +-positioning, writing, and drawing is always done relative to a page, so +-a @samp{p} command must be issued before any of these commands. +- +-@item s @var{n} +-Set point size to @var{n}@tie{}scaled points (this is unit @samp{z}). +-@acronym{AT&T} @code{troff} used the unit points (@samp{p}) instead. +-@xref{Output Language Compatibility}. +- +-@item t @var{xxx}@angles{whitespace} +-@itemx t @var{xxx} @var{dummy-arg}@angles{whitespace} +-Print a word, i.e., a sequence of characters @var{xxx} representing +-output glyphs which names are single characters, terminated by a space +-character or a line break; an optional second integer argument is +-ignored (this allows the formatter to generate an even number of +-arguments). The first glyph should be printed at the current position, +-the current horizontal position should then be increased by the width of +-the first glyph, and so on for each glyph. The widths of the glyphs are +-read from the font file, scaled for the current point size, and rounded +-to a multiple of the horizontal resolution. Special characters cannot +-be printed using this command (use the @samp{C} command for special +-characters). This command is a @code{gtroff} extension; it is only used +-for devices whose @file{DESC} file contains the @code{tcommand} keyword +-(@pxref{DESC File Format}). +- +-@item u @var{n} @var{xxx}@angles{whitespace} +-Print word with track kerning. This is the same as the @samp{t} command +-except that after printing each glyph, the current horizontal position +-is increased by the sum of the width of that glyph and@tie{}@var{n} (an +-integer in basic units @samp{u}). This command is a @code{gtroff} +-extension; it is only used for devices whose @file{DESC} file contains +-the @code{tcommand} keyword (@pxref{DESC File Format}). +- +-@item V @var{n} +-Move down to the absolute vertical position@tie{}@var{n} (a non-negative +-integer in basic units @samp{u}) relative to upper edge of current page. +- +-@item v @var{n} +-Move @var{n}@tie{}basic units @samp{u} down (@var{n} is a non-negative +-integer). The original @acronym{UNIX} troff manual allows negative +-values for @var{n} also, but @code{gtroff} doesn't use this. +- +-@item w +-Informs about a paddable white space to increase readability. The +-spacing itself must be performed explicitly by a move command. +-@end table +- +-@node Graphics Commands, Device Control Commands, Simple Commands, Command Reference +-@subsubsection Graphics Commands +- +-Each graphics or drawing command in the intermediate output starts with +-the letter @samp{D}, followed by one or two characters that specify a +-subcommand; this is followed by a fixed or variable number of integer +-arguments that are separated by a single space character. A @samp{D} +-command may not be followed by another command on the same line (apart +-from a comment), so each @samp{D} command is terminated by a syntactical +-line break. +- +-@code{gtroff} output follows the classical spacing rules (no space +-between command and subcommand, all arguments are preceded by a single +-space character), but the parser allows optional space between the +-command letters and makes the space before the first argument optional. +-As usual, each space can be any sequence of tab and space characters. +- +-Some graphics commands can take a variable number of arguments. In this +-case, they are integers representing a size measured in basic units +-@samp{u}. The arguments called @var{h1}, @var{h2}, @dots{}, @var{hn} +-stand for horizontal distances where positive means right, negative +-left. The arguments called @var{v1}, @var{v2}, @dots{}, @var{vn} stand +-for vertical distances where positive means down, negative up. All +-these distances are offsets relative to the current location. +- +-Each graphics command directly corresponds to a similar @code{gtroff} +-@code{\D} escape sequence. @xref{Drawing Requests}. +- +-Unknown @samp{D} commands are assumed to be device-specific. Its +-arguments are parsed as strings; the whole information is then sent to +-the postprocessor. +- +-In the following command reference, the syntax element @angles{line +-break} means a syntactical line break as defined above. +- +-@table @code +-@item D~ @var{h1} @var{v1} @var{h2} @var{v2} @dots{} @var{hn} @var{vn}@angles{line break} +-Draw B-spline from current position to offset (@var{h1},@var{v1}), then +-to offset (@var{h2},@var{v2}), if given, etc.@: up to +-(@var{hn},@var{vn}). This command takes a variable number of argument +-pairs; the current position is moved to the terminal point of the drawn +-curve. +- +-@item Da @var{h1} @var{v1} @var{h2} @var{v2}@angles{line break} +-Draw arc from current position to +-(@var{h1},@var{v1})@math{+}(@var{h2},@var{v2}) with center at +-(@var{h1},@var{v1}); then move the current position to the final point +-of the arc. +- +-@item DC @var{d}@angles{line break} +-@itemx DC @var{d} @var{dummy-arg}@angles{line break} +-Draw a solid circle using the current fill color with +-diameter@tie{}@var{d} (integer in basic units @samp{u}) with leftmost +-point at the current position; then move the current position to the +-rightmost point of the circle. An optional second integer argument is +-ignored (this allows the formatter to generate an even number of +-arguments). This command is a @code{gtroff} extension. +- +-@item Dc @var{d}@angles{line break} +-Draw circle line with diameter@tie{}@var{d} (integer in basic units +-@samp{u}) with leftmost point at the current position; then move the +-current position to the rightmost point of the circle. +- +-@item DE @var{h} @var{v}@angles{line break} +-Draw a solid ellipse in the current fill color with a horizontal +-diameter of@tie{}@var{h} and a vertical diameter of@tie{}@var{v} (both +-integers in basic units @samp{u}) with the leftmost point at the current +-position; then move to the rightmost point of the ellipse. This command +-is a @code{gtroff} extension. +- +-@item De @var{h} @var{v}@angles{line break} +-Draw an outlined ellipse with a horizontal diameter of@tie{}@var{h} and +-a vertical diameter of@tie{}@var{v} (both integers in basic units +-@samp{u}) with the leftmost point at current position; then move to the +-rightmost point of the ellipse. +- +-@item DF @var{color-scheme} @r{[}@var{component} @dots{}@r{]}@angles{line break} +-Set fill color for solid drawing objects using different color schemes; +-the analoguous command for setting the color of text, line graphics, and +-the outline of graphic objects is @samp{m}. The color components are +-specified as integer arguments between 0 and 65536. The number of color +-components and their meaning vary for the different color schemes. +-These commands are generated by @code{gtroff}'s escape sequences +-@w{@code{\D'F @dots{}'}} and @code{\M} (with no other corresponding +-graphics commands). No position changing. This command is a +-@code{gtroff} extension. +- +-@table @code +-@item DFc @var{cyan} @var{magenta} @var{yellow}@angles{line break} +-Set fill color for solid drawing objects using the CMY color scheme, +-having the 3@tie{}color components @var{cyan}, @var{magenta}, and +-@var{yellow}. +- +-@item DFd@angles{line break} +-Set fill color for solid drawing objects to the default fill color value +-(black in most cases). No component arguments. +- +-@item DFg @var{gray}@angles{line break} +-Set fill color for solid drawing objects to the shade of gray given by +-the argument, an integer between 0 (black) and 65536 (white). +- +-@item DFk @var{cyan} @var{magenta} @var{yellow} @var{black}@angles{line break} +-Set fill color for solid drawing objects using the CMYK color scheme, +-having the 4@tie{}color components @var{cyan}, @var{magenta}, +-@var{yellow}, and @var{black}. +- +-@item DFr @var{red} @var{green} @var{blue}@angles{line break} +-Set fill color for solid drawing objects using the RGB color scheme, +-having the 3@tie{}color components @var{red}, @var{green}, and +-@var{blue}. +-@end table +- +-@item Df @var{n}@angles{line break} +-The argument@tie{}@var{n} must be an integer in the range @math{-32767} +-to 32767. +- +-@table @asis +-@item @math{0 @value{LE} @var{n} @value{LE} 1000} +-Set the color for filling solid drawing objects to a shade of gray, +-where 0 corresponds to solid white, 1000 (the default) to solid black, +-and values in between to intermediate shades of gray; this is obsoleted +-by command @samp{DFg}. +- +-@item @math{@var{n} < 0} or @math{@var{n} > 1000} +-Set the filling color to the color that is currently being used for the +-text and the outline, see command @samp{m}. For example, the command +-sequence +- +-@Example +-mg 0 0 65536 +-Df -1 +-@endExample +- +-@noindent +-sets all colors to blue. +-@end table +- +-@noindent +-No position changing. This command is a @code{gtroff} extension. +- +-@item Dl @var{h} @var{v}@angles{line break} +-Draw line from current position to offset (@var{h},@var{v}) (integers in +-basic units @samp{u}); then set current position to the end of the drawn +-line. +- +-@item Dp @var{h1} @var{v1} @var{h2} @var{v2} @dots{} @var{hn} @var{vn}@angles{line break} +-Draw a polygon line from current position to offset (@var{h1},@var{v1}), +-from there to offset (@var{h2},@var{v2}), etc.@: up to offset +-(@var{hn},@var{vn}), and from there back to the starting position. For +-historical reasons, the position is changed by adding the sum of all +-arguments with odd index to the actual horizontal position and the even +-ones to the vertical position. Although this doesn't make sense it is +-kept for compatibility. +-@ignore +-As the polygon is closed, the end of drawing is the starting point, so +-the position doesn't change. +-@end ignore +-This command is a @code{gtroff} extension. +- +-@item Dp @var{h1} @var{v1} @var{h2} @var{v2} @dots{} @var{hn} @var{vn}@angles{line break} +-Draw a solid polygon in the current fill color rather than an outlined +-polygon, using the same arguments and positioning as the corresponding +-@samp{Dp} command. +-@ignore +-No position changing. +-@end ignore +-This command is a @code{gtroff} extension. +- +-@item Dt @var{n}@angles{line break} +-Set the current line thickness to@tie{}@var{n} (an integer in basic +-units @samp{u}) if @math{@var{n}>0}; if @math{@var{n}=0} select the +-smallest available line thickness; if @math{@var{n}<0} set the line +-thickness proportional to the point size (this is the default before the +-first @samp{Dt} command was specified). For historical reasons, the +-horizontal position is changed by adding the argument to the actual +-horizontal position, while the vertical position is not changed. +-Although this doesn't make sense it is kept for compatibility. +-@ignore +-No position changing. +-@end ignore +-This command is a @code{gtroff} extension. +-@end table +- +-@node Device Control Commands, Obsolete Command, Graphics Commands, Command Reference +-@subsubsection Device Control Commands +- +-Each device control command starts with the letter @samp{x}, followed by +-a space character (optional or arbitrary space or tab in @code{gtroff}) +-and a subcommand letter or word; each argument (if any) must be preceded +-by a syntactical space. All @samp{x} commands are terminated by a +-syntactical line break; no device control command can be followed by +-another command on the same line (except a comment). +- +-The subcommand is basically a single letter, but to increase +-readability, it can be written as a word, i.e., an arbitrary sequence of +-characters terminated by the next tab, space, or newline character. All +-characters of the subcommand word but the first are simply ignored. For +-example, @code{gtroff} outputs the initialization command @w{@samp{x i}} +-as @w{@samp{x init}} and the resolution command @w{@samp{x r}} as +-@w{@samp{x res}}. +- +-In the following, the syntax element @angles{line break} means a +-syntactical line break (@pxref{Separation}). +- +-@table @code +-@item xF @var{name}@angles{line break} +-The @samp{F} stands for @var{Filename}. +- +-Use @var{name} as the intended name for the current file in error +-reports. This is useful for remembering the original file name when +-@code{gtroff} uses an internal piping mechanism. The input file is not +-changed by this command. This command is a @code{gtroff} extension. +- +-@item xf @var{n} @var{s}@angles{line break} +-The @samp{f} stands for @var{font}. +- +-Mount font position@tie{}@var{n} (a non-negative integer) with font +-named@tie{}@var{s} (a text word). @xref{Font Positions}. +- +-@item xH @var{n}@angles{line break} +-The @samp{H} stands for @var{Height}. +- +-Set glyph height to@tie{}@var{n} (a positive integer in scaled points +-@samp{z}). @acronym{AT&T} @code{troff} uses the unit points (@samp{p}) +-instead. @xref{Output Language Compatibility}. +- +-@item xi@angles{line break} +-The @samp{i} stands for @var{init}. +- +-Initialize device. This is the third command of the prologue. +- +-@item xp@angles{line break} +-The @samp{p} stands for @var{pause}. +- +-Parsed but ignored. The original @acronym{UNIX} troff manual writes +- +-@display +-pause device, can be restarted +-@end display +- +-@item xr @var{n} @var{h} @var{v}@angles{line break} +-The @samp{r} stands for @var{resolution}. +- +-Resolution is@tie{}@var{n}, while @var{h} is the minimal horizontal +-motion, and @var{v} the minimal vertical motion possible with this +-device; all arguments are positive integers in basic units @samp{u} per +-inch. This is the second command of the prologue. +- +-@item xS @var{n}@angles{line break} +-The @samp{S} stands for @var{Slant}. +- +-Set slant to@tie{}@var{n} (an integer in basic units @samp{u}). +- +-@item xs@angles{line break} +-The @samp{s} stands for @var{stop}. +- +-Terminates the processing of the current file; issued as the last +-command of any intermediate troff output. +- +-@item xt@angles{line break} +-The @samp{t} stands for @var{trailer}. +- +-Generate trailer information, if any. In @var{gtroff}, this is actually +-just ignored. +- +-@item xT @var{xxx}@angles{line break} +-The @samp{T} stands for @var{Typesetter}. +- +-Set name of device to word @var{xxx}, a sequence of characters ended by +-the next white space character. The possible device names coincide with +-those from the @code{groff} @option{-T} option. This is the first +-command of the prologue. +- +-@item xu @var{n}@angles{line break} +-The @samp{u} stands for @var{underline}. +- +-Configure underlining of spaces. If @var{n} is@tie{}1, start +-underlining of spaces; if @var{n} is@tie{}0, stop underlining of spaces. +-This is needed for the @code{cu} request in nroff mode and is ignored +-otherwise. This command is a @code{gtroff} extension. +- +-@item xX @var{anything}@angles{line break} +-The @samp{x} stands for @var{X-escape}. +- +-Send string @var{anything} uninterpreted to the device. If the line +-following this command starts with a @samp{+} character this line is +-interpreted as a continuation line in the following sense. The @samp{+} +-is ignored, but a newline character is sent instead to the device, the +-rest of the line is sent uninterpreted. The same applies to all +-following lines until the first character of a line is not a @samp{+} +-character. This command is generated by the @code{gtroff} escape +-sequence @code{\X}. The line-continuing feature is a @code{gtroff} +-extension. +-@end table +- +-@node Obsolete Command, , Device Control Commands, Command Reference +-@subsubsection Obsolete Command +-In @acronym{AT&T} @code{troff} output, the writing of a single glyph is +-mostly done by a very strange command that combines a horizontal move +-and a single character giving the glyph name. It doesn't have a command +-code, but is represented by a 3-character argument consisting of exactly +-2@tie{}digits and a character. +- +-@table @asis +-@item @var{dd}@var{g} +-Move right @var{dd} (exactly two decimal digits) basic units @samp{u}, +-then print glyph@tie{}@var{g} (represented as a single character). +- +-In @code{gtroff}, arbitrary syntactical space around and within this +-command is allowed to be added. Only when a preceding command on the +-same line ends with an argument of variable length a separating space is +-obligatory. In @acronym{AT&T} @code{troff}, large clusters of these and +-other commands are used, mostly without spaces; this made such output +-almost unreadable. +-@end table +- +-For modern high-resolution devices, this command does not make sense +-because the width of the glyphs can become much larger than two decimal +-digits. In @code{gtroff}, this is only used for the devices @code{X75}, +-@code{X75-12}, @code{X100}, and @code{X100-12}. For other devices, the +-commands @samp{t} and @samp{u} provide a better functionality. +- +-@c --------------------------------------------------------------------- +- +-@node Intermediate Output Examples, Output Language Compatibility, Command Reference, gtroff Output +-@subsection Intermediate Output Examples +- +-This section presents the intermediate output generated from the same +-input for three different devices. The input is the sentence @samp{hell +-world} fed into @code{gtroff} on the command line. +- +-@table @asis +-@item High-resolution device @code{ps} +- +-This is the standard output of @code{gtroff} if no @option{-T} option is +-given. +- +-@example +-@group +-shell> echo "hell world" | groff -Z -T ps +- +-x T ps +-x res 72000 1 1 +-x init +-@end group +-p1 +-x font 5 TR +-f5 +-s10000 +-V12000 +-H72000 +-thell +-wh2500 +-tw +-H96620 +-torld +-n12000 0 +-@group +-x trailer +-V792000 +-x stop +-@end group +-@end example +- +-@noindent +-This output can be fed into @code{grops} to get its representation as a +-@sc{PostScript} file. +- +-@item Low-resolution device @code{latin1} +- +-This is similar to the high-resolution device except that the +-positioning is done at a minor scale. Some comments (lines starting +-with @samp{#}) were added for clarification; they were not generated by +-the formatter. +- +-@example +-@group +-shell> echo "hell world" | groff -Z -T latin1 +- +-# prologue +-x T latin1 +-x res 240 24 40 +-x init +-@end group +-# begin a new page +-p1 +-# font setup +-x font 1 R +-f1 +-s10 +-# initial positioning on the page +-V40 +-H0 +-# write text `hell' +-thell +-# inform about space, and issue a horizontal jump +-wh24 +-# write text `world' +-tworld +-# announce line break, but do nothing because ... +-n40 0 +-@group +-# ... the end of the document has been reached +-x trailer +-V2640 +-x stop +-@end group +-@end example +- +-@noindent +-This output can be fed into @code{grotty} to get a formatted text +-document. +- +-@item @acronym{AT&T} @code{troff} output +-Since a computer monitor has a very low resolution compared to modern +-printers the intermediate output for the X@tie{}Window devices can use +-the jump-and-write command with its 2-digit displacements. +- +-@example +-@group +-shell> echo "hell world" | groff -Z -T X100 +- +-x T X100 +-x res 100 1 1 +-x init +-@end group +-p1 +-x font 5 TR +-f5 +-s10 +-V16 +-H100 +-# write text with jump-and-write commands +-ch07e07l03lw06w11o07r05l03dh7 +-n16 0 +-@group +-x trailer +-V1100 +-x stop +-@end group +-@end example +- +-@noindent +-This output can be fed into @code{xditview} or @code{gxditview} for +-displaying in@tie{}X. +- +-Due to the obsolete jump-and-write command, the text clusters in the +-@acronym{AT&T} @code{troff} output are almost unreadable. +-@end table +- +-@c --------------------------------------------------------------------- +- +-@node Output Language Compatibility, , Intermediate Output Examples, gtroff Output +-@subsection Output Language Compatibility +- +-The intermediate output language of @acronym{AT&T} @code{troff} was +-first documented in the @acronym{UNIX} troff manual, with later +-additions documented in @cite{A Typesetter-indenpendent TROFF}, written +-by Brian Kernighan. +- +-The @code{gtroff} intermediate output format is compatible with this +-specification except for the following features. +- +-@itemize @bullet +-@item +-The classical quasi device independence is not yet implemented. +- +-@item +-The old hardware was very different from what we use today. So the +-@code{groff} devices are also fundamentally different from the ones +-in @acronym{AT&T} @code{troff}. For example, the @acronym{AT&T} +-@sc{PostScript} device is called @code{post} and has a resolution of +-only 720 units per inch, suitable for printers 20 years ago, while +-@code{groff}'s @code{ps} device has a resolution of 72000 units per +-inch. Maybe, by implementing some rescaling mechanism similar to the +-classical quasi device independence, @code{groff} could emulate +-@acronym{AT&T}'s @code{post} device. +- +-@item +-The B-spline command @samp{D~} is correctly handled by the intermediate +-output parser, but the drawing routines aren't implemented in some of +-the postprocessor programs. +- +-@item +-The argument of the commands @samp{s} and @w{@samp{x H}} has the +-implicit unit scaled point @samp{z} in @code{gtroff}, while +-@acronym{AT&T} @code{troff} has point (@samp{p}). This isn't an +-incompatibility but a compatible extension, for both units coincide for +-all devices without a @code{sizescale} parameter in the @file{DESC} +-file, including all postprocessors from @acronym{AT&T} and +-@code{groff}'s text devices. The few @code{groff} devices with a +-@code{sizescale} parameter either do not exist for @acronym{AT&T} +-@code{troff}, have a different name, or seem to have a different +-resolution. So conflicts are very unlikely. +- +-@item +-The position changing after the commands @samp{Dp}, @samp{DP}, and +-@samp{Dt} is illogical, but as old versions of @code{gtroff} used this +-feature it is kept for compatibility reasons. +- +-@ignore +-Temporarily, there existed some confusion on the positioning after the +-@samp{D} commands that are groff extensions. This has been clarified by +-establishing the classical rule for all @code{groff} drawing commands: +- +-@itemize +-@item +-The position after a graphic object has been drawn is at its end; for +-circles and ellipses, the `end' is at the right side. +- +-@item +-From this, the positionings specified for the drawing commands above +-follow quite naturally. +-@end itemize +-@end ignore +- +-@end itemize +- +- +-@c ===================================================================== +- +-@node Font Files, , gtroff Output, File formats +-@section Font Files +-@cindex font files +-@cindex files, font +- +-The @code{gtroff} font format is roughly a superset of the +-@code{ditroff} font format (as used in later versions of @acronym{AT&T} +-@code{troff} and its descendants). Unlike the @code{ditroff} font +-format, there is no associated binary format; all files are text +-files.@footnote{Plan@tie{}9 @code{troff} has also abandoned the binary +-format.} The font files for device @var{name} are stored in a directory +-@file{dev@var{name}}. There are two types of file: a device description +-file called @file{DESC} and for each font@tie{}@var{f} a font file +-called@tie{}@file{@var{f}}. +- +-@menu +-* DESC File Format:: +-* Font File Format:: +-@end menu +- +-@c --------------------------------------------------------------------- +- +-@node DESC File Format, Font File Format, Font Files, Font Files +-@subsection @file{DESC} File Format +-@cindex @file{DESC} file, format +-@cindex font description file, format +-@cindex format of font description file +-@pindex DESC@r{ file format} +- +-The @file{DESC} file can contain the following types of line. Except +-for the @code{charset} keyword, which must comes last (if at all), the +-order of the lines is not important. Later entries in the file, +-however, override previous values. +- +-@table @code +-@item charset +-@kindex charset +-This line and everything following in the file are ignored. It is +-allowed for the sake of backwards compatibility. +- +-@item family @var{fam} +-@kindex family +-The default font family is @var{fam}. +- +-@item fonts @var{n} @var{F1} @var{F2} @var{F3} @dots{} @var{Fn} +-@kindex fonts +-Fonts @var{F1} @dots{} @var{Fn} are mounted in the font positions +-@var{m}+1, @dots{}, @var{m}+@var{n} where @var{m} is the number of +-styles. This command may extend over more than one line. A font name +-of@tie{}0 means no font is mounted on the corresponding font position. +- +-@item hor @var{n} +-@kindex hor +-@cindex horizontal resolution +-@cindex resolution, horizontal +-The horizontal resolution is @var{n}@tie{}machine units. All horizontal +-quantities are rounded to be multiples of this value. +- +-@item image_generator @var{string} +-@kindex image_generator +-@cindex PostScript, PNG image generation +-@cindex PNG image generation from PostScript +-Needed for @code{grohtml} only. It specifies the program to generate +-PNG images from @sc{PostScript} input. Under GNU/Linux this is +-usually @code{gs} but under other systems (notably cygwin) it might +-be set to another name. +- +-@item paperlength @var{n} +-@kindex paperlength +-The physical vertical dimension of the output medium in machine units. +-This isn't used by @code{troff} itself but by output devices. +-Deprecated. Use @code{papersize} instead. +- +-@item papersize @var{string} @dots{} +-@kindex papersize +-Select a paper size. Valid values for @var{string} are the ISO paper +-types @code{A0}-@code{A7}, @code{B0}-@code{B7}, @code{C0}-@code{C7}, +-@code{D0}-@code{D7}, @code{DL}, and the US paper types @code{letter}, +-@code{legal}, @code{tabloid}, @code{ledger}, @code{statement}, +-@code{executive}, @code{com10}, and @code{monarch}. Case is not +-significant for @var{string} if it holds predefined paper types. +-Alternatively, @var{string} can be a file name (e.g.@: +-@file{/etc/papersize}); if the file can be opened, @code{groff} reads +-the first line and tests for the above paper sizes. Finally, +-@var{string} can be a custom paper size in the format +-@code{@var{length},@var{width}} (no spaces before and after the comma). +-Both @var{length} and @var{width} must have a unit appended; valid +-values are @samp{i} for inches, @samp{C} for centimeters, @samp{p} for +-points, and @samp{P} for picas. Example: @code{12c,235p}. An argument +-that starts with a digit is always treated as a custom paper format. +-@code{papersize} sets both the vertical and horizontal dimension of the +-output medium. +- +-More than one argument can be specified; @code{groff} scans from left to +-right and uses the first valid paper specification. +- +-@item paperwidth @var{n} +-@kindex paperwidth +-The physical horizontal dimension of the output medium in machine units. +-This isn't used by @code{troff} itself but by output devices. +-Deprecated. Use @code{papersize} instead. +- +-@item pass_filenames +-@kindex pass_filenames +-Tell @code{gtroff} to emit the name of the source file currently being +-processed. This is achieved by the intermediate output command +-@samp{F}. Currently, this is only used by the @code{grohtml} output +-device. +- +-@item postpro @var{program} +-@kindex postpro +-Call @var{program} as a postprocessor. For example, the line +- +-@Example +-postpro grodvi +-@endExample +- +-@noindent +-in the file @file{devdvi/DESC} makes @code{groff} call @code{grodvi} if +-option @option{-Tdvi} is given (and @option{-Z} isn't used). +- +-@item prepro @var{program} +-@kindex prepro +-Call @var{program} as a preprocessor. Currently, this keyword is used +-by @code{groff} with option @option{-Thtml} or @option{-Txhtml} only. +- +-@item print @var{program} +-@kindex print +-Use @var{program} as a spooler program for printing. If omitted, the +-@option{-l} and @option{-L} options of @code{groff} are ignored. +- +-@item res @var{n} +-@kindex res +-@cindex device resolution +-@cindex resolution, device +-There are @var{n}@tie{}machine units per inch. +- +-@item sizes @var{s1} @var{s2} @dots{} @var{sn} 0 +-@kindex sizes +-This means that the device has fonts at @var{s1}, @var{s2}, @dots{} +-@var{sn} scaled points. The list of sizes must be terminated by@tie{}0 +-(this is digit zero). Each @var{si} can also be a range of sizes +-@var{m}-@var{n}. The list can extend over more than one line. +- +-@item sizescale @var{n} +-@kindex sizescale +-The scale factor for point sizes. By default this has a value +-of@tie{}1. One scaled point is equal to one point/@var{n}. The +-arguments to the @code{unitwidth} and @code{sizes} commands are given in +-scaled points. @xref{Fractional Type Sizes}, for more information. +- +-@item styles @var{S1} @var{S2} @dots{} @var{Sm} +-@kindex styles +-The first @var{m}@tie{}font positions are associated with styles +-@var{S1} @dots{} @var{Sm}. +- +-@item tcommand +-@kindex tcommand +-This means that the postprocessor can handle the @samp{t} and @samp{u} +-intermediate output commands. +- +-@item unicode +-@kindex unicode +-Indicate that the output device supports the complete Unicode +-repertoire. Useful only for devices that produce @emph{character +-entities} instead of glyphs. +- +-If @code{unicode} is present, no @code{charset} section is required in +-the font description files since the Unicode handling built into +-@code{groff} is used. However, if there are entries in a @code{charset} +-section, they either override the default mappings for those particular +-characters or add new mappings (normally for composite characters). +- +-This is used for @option{-Tutf8}, @option{-Thtml}, and @option{-Txhtml}. +- +-@item unitwidth @var{n} +-@kindex unitwidth +-Quantities in the font files are given in machine units for fonts whose +-point size is @var{n}@tie{}scaled points. +- +-@item unscaled_charwidths +-@kindex unscaled_charwidths +-Make the font handling module always return unscaled character widths. +-Needed for the @code{grohtml} device. +- +-@item use_charnames_in_special +-@kindex use_charnames_in_special +-This command indicates that @code{gtroff} should encode special +-characters inside special commands. Currently, this is only used by the +-@code{grohtml} output device. @xref{Postprocessor Access}. +- +-@item vert @var{n} +-@kindex vert +-@cindex vertical resolution +-@cindex resolution, vertical +-The vertical resolution is @var{n}@tie{}machine units. All vertical +-quantities are rounded to be multiples of this value. +-@end table +- +-The @code{res}, @code{unitwidth}, @code{fonts}, and @code{sizes} lines +-are mandatory. Other commands are ignored by @code{gtroff} but may be +-used by postprocessors to store arbitrary information about the device +-in the @file{DESC} file. +- +-@kindex spare1 +-@kindex spare2 +-@kindex biggestfont +-Here a list of obsolete keywords that are recognized by @code{groff} +-but completely ignored: @code{spare1}, @code{spare2}, +-@code{biggestfont}. +- +-@c --------------------------------------------------------------------- +- +-@node Font File Format, , DESC File Format, Font Files +-@subsection Font File Format +-@cindex font file, format +-@cindex font description file, format +-@cindex format of font files +-@cindex format of font description files +- +-A @dfn{font file}, also (and probably better) called a @dfn{font +-description file}, has two sections. The first section is a sequence of +-lines each containing a sequence of blank delimited words; the first +-word in the line is a key, and subsequent words give a value for that +-key. +- +-@table @code +-@item name @var{f} +-@kindex name +-The name of the font is@tie{}@var{f}. +- +-@item spacewidth @var{n} +-@kindex spacewidth +-The normal width of a space is@tie{}@var{n}. +- +-@item slant @var{n} +-@kindex slant +-The glyphs of the font have a slant of @var{n}@tie{}degrees. (Positive +-means forward.) +- +-@item ligatures @var{lig1} @var{lig2} @dots{} @var{lign} [0] +-@kindex ligatures +-Glyphs @var{lig1}, @var{lig2}, @dots{}, @var{lign} are ligatures; +-possible ligatures are @samp{ff}, @samp{fi}, @samp{fl}, @samp{ffi} and +-@samp{ffl}. For backwards compatibility, the list of ligatures may be +-terminated with a@tie{}0. The list of ligatures may not extend over +-more than one line. +- +-@item special +-@cindex special fonts +-@kindex special +-The font is @dfn{special}; this means that when a glyph is requested +-that is not present in the current font, it is searched for in any +-special fonts that are mounted. +-@end table +- +-Other commands are ignored by @code{gtroff} but may be used by +-postprocessors to store arbitrary information about the font in the font +-file. +- +-@cindex comments in font files +-@cindex font files, comments +-@kindex # +-The first section can contain comments, which start with the @samp{#} +-character and extend to the end of a line. +- +-The second section contains one or two subsections. It must contain a +-@code{charset} subsection and it may also contain a @code{kernpairs} +-subsection. These subsections can appear in any order. Each subsection +-starts with a word on a line by itself. +- +-@kindex charset +-The word @code{charset} starts the character set +-subsection.@footnote{This keyword is misnamed since it starts a list of +-ordered glyphs, not characters.} The @code{charset} line is followed by +-a sequence of lines. Each line gives information for one glyph. A line +-comprises a number of fields separated by blanks or tabs. The format is +- +-@quotation +-@var{name} @var{metrics} @var{type} @var{code} [@var{entity-name}] +-[@code{--} @var{comment}] +-@end quotation +- +-@cindex 8-bit input +-@cindex input, 8-bit +-@cindex accessing unnamed glyphs with @code{\N} +-@cindex unnamed glyphs, accessing with @code{\N} +-@cindex characters, unnamed, accessing with @code{\N} +-@cindex glyphs, unnamed, accessing with @code{\N} +-@kindex --- +-@noindent +-@var{name} identifies the glyph name@footnote{The distinction between +-input, characters, and output, glyphs, is not clearly separated in the +-terminology of @code{groff}; for example, the @code{char} request should +-be called @code{glyph} since it defines an output entity.}: If +-@var{name} is a single character@tie{}@var{c} then it corresponds to the +-@code{gtroff} input character@tie{}@var{c}; if it is of the form +-@samp{\@var{c}} where @var{c} is a single character, then it corresponds +-to the special character @code{\[@var{c}]}; otherwise it corresponds to +-the special character @samp{\[@var{name}]}. If it is exactly two +-characters @var{xx} it can be entered as @samp{\(@var{xx}}. Note that +-single-letter special characters can't be accessed as @samp{\@var{c}}; +-the only exception is @samp{\-}, which is identical to @code{\[-]}. +- +-@code{gtroff} supports 8-bit input characters; however some utilities +-have difficulties with eight-bit characters. For this reason, there is +-a convention that the entity name @samp{char@var{n}} is equivalent to +-the single input character whose code is@tie{}@var{n}. For example, +-@samp{char163} would be equivalent to the character with code@tie{}163, +-which is the pounds sterling sign in the ISO@tie{}@w{Latin-1} character +-set. You shouldn't use @samp{char@var{n}} entities in font description +-files since they are related to input, not output. Otherwise, you get +-hard-coded connections between input and output encoding, which prevents +-use of different (input) character sets. +- +-The name @samp{---} is special and indicates that the glyph is unnamed; +-such glyphs can only be used by means of the @code{\N} escape sequence +-in @code{gtroff}. +- +-The @var{type} field gives the glyph type: +- +-@table @code +-@item 1 +-the glyph has a descender, for example, @samp{p}; +- +-@item 2 +-the glyph has an ascender, for example, @samp{b}; +- +-@item 3 +-the glyph has both an ascender and a descender, for example, @samp{(}. +-@end table +- +-The @var{code} field gives the code that the postprocessor uses to +-print the glyph. The glyph can also be input to @code{gtroff} using +-this code by means of the @code{\N} escape sequence. @var{code} can be +-any integer. If it starts with @samp{0} it is interpreted as octal; if +-it starts with @samp{0x} or @samp{0X} it is interpreted as hexadecimal. +-Note, however, that the @code{\N} escape sequence only accepts a decimal +-integer. +- +-The @var{entity-name} field gives an @acronym{ASCII} string identifying +-the glyph that the postprocessor uses to print the @code{gtroff} glyph +-@var{name}. This field is optional and has been introduced so that the +-@code{grohtml} device driver can encode its character set. For example, +-the glyph @samp{\[Po]} is represented as @samp{£} in +-@acronym{HTML} 4.0. +- +-Anything on the line after the @var{entity-name} field resp.@: after +-@samp{--} is ignored. +- +-The @var{metrics} field has the form: +- +-@display +-@group +-@var{width}[@code{,}@var{height}[@code{,}@var{depth}[@code{,}@var{italic-correction} +- [@code{,}@var{left-italic-correction}[@code{,}@var{subscript-correction}]]]]] +-@end group +-@end display +- +-@noindent +-There must not be any spaces between these subfields (it has been split +-here into two lines for better legibility only). Missing subfields are +-assumed to be@tie{}0. The subfields are all decimal integers. Since +-there is no associated binary format, these values are not required to +-fit into a variable of type @samp{char} as they are in @code{ditroff}. +-The @var{width} subfield gives the width of the glyph. The @var{height} +-subfield gives the height of the glyph (upwards is positive); if a glyph +-does not extend above the baseline, it should be given a zero height, +-rather than a negative height. The @var{depth} subfield gives the depth +-of the glyph, that is, the distance from the baseline to the lowest +-point below the baseline to which the glyph extends (downwards is +-positive); if a glyph does not extend below the baseline, it should be +-given a zero depth, rather than a negative depth. The +-@var{italic-correction} subfield gives the amount of space that should +-be added after the glyph when it is immediately to be followed by a +-glyph from a roman font. The @var{left-italic-correction} subfield +-gives the amount of space that should be added before the glyph when it +-is immediately to be preceded by a glyph from a roman font. The +-@var{subscript-correction} gives the amount of space that should be +-added after a glyph before adding a subscript. This should be less than +-the italic correction. +- +-A line in the @code{charset} section can also have the format +- +-@Example +-@var{name} " +-@endExample +- +-@noindent +-This indicates that @var{name} is just another name for the glyph +-mentioned in the preceding line. +- +-@kindex kernpairs +-The word @code{kernpairs} starts the kernpairs section. This contains a +-sequence of lines of the form: +- +-@Example +-@var{c1} @var{c2} @var{n} +-@endExample +- +-@noindent +-This means that when glyph @var{c1} appears next to glyph @var{c2} the +-space between them should be increased by@tie{}@var{n}. Most entries in +-the kernpairs section have a negative value for@tie{}@var{n}. +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Installation, Copying This Manual, File formats, Top +-@chapter Installation +-@cindex installation +- +-@c XXX +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Copying This Manual, Request Index, Installation, Top +-@appendix Copying This Manual +- +-@include fdl.texi +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Request Index, Escape Index, Copying This Manual, Top +-@appendix Request Index +- +-Requests appear without the leading control character (normally either +-@samp{.} or @samp{'}). +- +-@printindex rq +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Escape Index, Operator Index, Request Index, Top +-@appendix Escape Index +- +-Any escape sequence @code{\@var{X}} with @var{X} not in the list below +-emits a warning, printing glyph @var{X}. +- +-@printindex es +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Operator Index, Register Index, Escape Index, Top +-@appendix Operator Index +- +-@printindex op +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Register Index, Macro Index, Operator Index, Top +-@appendix Register Index +- +-The macro package or program a specific register belongs to is appended in +-brackets. +- +-A register name@tie{}@code{x} consisting of exactly one character can be +-accessed as @samp{\nx}. A register name @code{xx} consisting of exactly +-two characters can be accessed as @samp{\n(xx}. Register names +-@code{xxx} of any length can be accessed as @samp{\n[xxx]}. +- +-@printindex vr +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Macro Index, String Index, Register Index, Top +-@appendix Macro Index +- +-The macro package a specific macro belongs to is appended in brackets. +-They appear without the leading control character (normally @samp{.}). +- +-@printindex ma +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node String Index, Glyph Name Index, Macro Index, Top +-@appendix String Index +- +-The macro package or program a specific string belongs to is appended in +-brackets. +- +-A string name@tie{}@code{x} consisting of exactly one character can be +-accessed as @samp{\*x}. A string name @code{xx} consisting of exactly +-two characters can be accessed as @samp{\*(xx}. String names @code{xxx} +-of any length can be accessed as @samp{\*[xxx]}. +- +- +-@printindex st +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Glyph Name Index, Font File Keyword Index, String Index, Top +-@appendix Glyph Name Index +- +-A glyph name @code{xx} consisting of exactly two characters can be +-accessed as @samp{\(xx}. Glyph names @code{xxx} of any length can be +-accessed as @samp{\[xxx]}. +- +-@c XXX +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Font File Keyword Index, Program and File Index, Glyph Name Index, Top +-@appendix Font File Keyword Index +- +-@printindex ky +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Program and File Index, Concept Index, Font File Keyword Index, Top +-@appendix Program and File Index +- +-@printindex pg +- +- +- +-@c ===================================================================== +-@c ===================================================================== +- +-@node Concept Index, , Program and File Index, Top +-@appendix Concept Index +- +-@printindex cp +- +- +-@bye +- +-@c Local Variables: +-@c mode: texinfo +-@c coding: latin-1 +-@c End: +diff -Nuar groff-1.22.3.old/doc/Makefile.in groff-1.22.3/doc/Makefile.in +--- groff-1.22.3.old/doc/Makefile.in 2014-11-04 10:38:35.561519796 +0200 ++++ groff-1.22.3/doc/Makefile.in 1970-01-01 02:00:00.000000000 +0200 +@@ -1,177 +0,0 @@ +-# Copyright (C) 2002-2014 Free Software Foundation, Inc. +-# Written by Werner Lemberg +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +- +-# Use this file to produce documentation in various formats; e.g. you can +-# say +-# +-# make groff.pdf +-# +-# to get the groff texinfo manual as a PDF file. +-# +-# Note that you have to compile the groff package first. +- +- +-srcdir=@srcdir@ +-top_srcdir=@abs_top_srcdir@ +-VPATH=@srcdir@ +-top_builddir=@abs_top_builddir@ +-pnmtops=@pnmtops_nosetpage@ +- +-# These may be overridden if cross-compiling. +-TROFFBIN=$(top_builddir)/src/roff/troff/troff +-GROFFBIN=$(top_builddir)/src/roff/groff/groff +-GROFF_BIN_PATH=`echo $(groff_bin_dirs) \ +- | LANG=C LC_ALL=C sed -e 's| *|:|g'` +- +-# info files are distributed with the groff package, so makeinfo is +-# usually not needed (however, to build from the repo you NEED it!) +-MAKEINFO=@MAKEINFO@ +- +-# Users who want to print out the groff manual are expected to have a +-# working TeX installation. Note that texi2dvi properly honours the +-# `MAKEINFO' environment variable. +-TEXI2DVI=texi2dvi +- +-groff_bin_dirs=\ +- $(top_builddir)/src/roff/groff \ +- $(top_builddir)/src/roff/troff \ +- $(top_builddir)/src/preproc/preconv \ +- $(top_builddir)/src/preproc/pic \ +- $(top_builddir)/src/preproc/eqn \ +- $(top_builddir)/src/preproc/tbl \ +- $(top_builddir)/src/preproc/grn \ +- $(top_builddir)/src/preproc/refer \ +- $(top_builddir)/src/preproc/soelim \ +- $(top_builddir)/src/preproc/html \ +- $(top_builddir)/src/devices/grops \ +- $(top_builddir)/src/devices/gropdf \ +- $(top_builddir)/src/devices/grodvi \ +- $(top_builddir)/src/devices/grotty \ +- $(top_builddir)/src/devices/grolj4 \ +- $(top_builddir)/src/devices/grolbp \ +- $(top_builddir)/src/devices/grohtml +- +-version=`cat $(top_srcdir)/VERSION` +-# No additional number if revision is zero. +-revision=`sed -e 's/^0$$//' -e 's/^[1-9].*$$/.&/' $(top_srcdir)/REVISION` +- +-FFLAG=-F$(top_builddir)/font -F$(top_srcdir)/font +-TFLAG=-M$(top_builddir)/tmac -M$(top_srcdir)/tmac +- +-TROFF=$(TROFFBIN) $(TFLAG) $(FFLAG) -ww +-GROFF=\ +- LANG=C \ +- LC_ALL=C \ +- sed -e "s;@VERSION@;$(version)$(revision);" $< \ +- | GROFF_COMMAND_PREFIX= \ +- GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ +- $(GROFFBIN) $(TFLAG) $(FFLAG) -Upet -ww +- +-imagedir=img +- +-.SUFFIXES: .me .ms .ps .html .txt .texinfo .dvi .pdf .xhtml +-.PHONY: all prepare_examples clean distclean realclean extraclean +- +-# For simplicity, we always call preconv, grn, and eqn. +-.me.txt: +- $(GROFF) -k -Tutf8 -ge -me >$@ +-.me.ps: +- $(GROFF) -k -Tps -ge -me >$@ +- +-.ms.html: +- $(GROFF) -P-p -P-b -P-I`basename $< | sed -e 's|.ms$$||'` \ +- -P-D$(imagedir) -P-V -Thtml -ms >$@ +-.ms.txt: +- $(GROFF) -Tascii -ms -mwww >$@ +-.ms.ps: +- $(GROFF) -Tps -ms -mwww >$@ +- +-.texinfo.txt: +- LANG=C \ +- LC_ALL=C \ +- $(MAKEINFO) --enable-encoding -I$(srcdir) --plaintext -o $@ $< +-.texinfo.dvi: +- LANG=C \ +- LC_ALL=C \ +- MAKEINFO=$(MAKEINFO) $(TEXI2DVI) -e $< +-.texinfo.pdf: +- LANG=C \ +- LC_ALL=C \ +- MAKEINFO=$(MAKEINFO) $(TEXI2DVI) -e --pdf $< +-.texinfo.html: +- LANG=C \ +- LC_ALL=C \ +- $(MAKEINFO) --enable-encoding -I$(srcdir) --html --no-split $< \ +- && $(SHELL) $(srcdir)/fixinfo.sh $@ +- +-all: prepare_examples +- +-prepare_examples: grnexmpl.g groff.css +- test -f grnexmpl.g || cp $(srcdir)/grnexmpl.g . +- test -f groff.css || cp $(srcdir)/groff.css . +- +-groff.info: groff.texinfo +- $(MAKEINFO) --enable-encoding -I$(srcdir) $(srcdir)/groff.texinfo +- +-gnu.eps: gnu.xpm +- xpmtoppm $(srcdir)/gnu.xpm | pnmdepth 15 | $(pnmtops) -noturn >$@ +- +-pic.html: pic.ms +- $(GROFF) -P-p -P-I`basename $< | sed -e 's|.ms$$||'` \ +- -P-D$(imagedir) -P-j`basename $< | sed -e 's|.ms$$||'` \ +- -Thtml -P-V -ms >$@ +- +-webpage.html: webpage.ms gnu.eps groff.css +- $(GROFF) -P-j`basename $< | sed -e 's|.ms$$||'` \ +- -P-nrpb -P-I`basename $< | sed -e 's|.ms$$||'` \ +- -P-D$(imagedir) -Thtml -ms >$@ +- +-webpage.ps: gnu.eps +- +-grnexmpl.ps: grnexmpl.me grnexmpl.g +- +-split-html: +- LANG=C \ +- LC_ALL=C \ +- $(MAKEINFO) --enable-encoding -I$(srcdir) --html groff.texinfo \ +- && for f in groff/*; do $(SHELL) $(srcdir)/fixinfo.sh $$f; done +- +-clean: +- rm -f *.ps *.html *.txt core +- rm -f *.aux *.dvi *.pdf *.log *.toc texput.log +- rm -f *.cp *.cps *.cv *.cn *.es *.ess *.fn *.fns *.ky *.kys \ +- *.ma *.mas *.op *.ops *.pg *.pgs *.rq *.rqs *.st *.sts \ +- *.tp *.tps *.tr *.vr *.vrs *.xhtml +- -rm -rf img +- +-distclean: clean +- +-realclean: distclean +- rm -f *.png *.eps +- +-extraclean: distclean +- rm -f core *~ \#* junk temp grot +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/doc/Makefile.sub groff-1.22.3/doc/Makefile.sub +--- groff-1.22.3.old/doc/Makefile.sub 2014-11-04 10:38:35.561519796 +0200 ++++ groff-1.22.3/doc/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,296 +0,0 @@ +-# Copyright (C) 2002-2014 Free Software Foundation, Inc. +-# Written by Werner Lemberg +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-# These may be overridden if cross-compiling. +-GROFFBIN=$(top_builddir)/src/roff/groff/groff +-GROFF_BIN_PATH=`echo $(groff_bin_dirs) | sed -e 's| *|$(SH_SEP)|g'` +- +-groff_bin_dirs=\ +- $(top_builddir)/src/roff/groff \ +- $(top_builddir)/src/roff/troff \ +- $(top_builddir)/src/preproc/preconv \ +- $(top_builddir)/src/preproc/pic \ +- $(top_builddir)/src/preproc/eqn \ +- $(top_builddir)/src/preproc/tbl \ +- $(top_builddir)/src/preproc/grn \ +- $(top_builddir)/src/preproc/refer \ +- $(top_builddir)/src/preproc/soelim \ +- $(top_builddir)/src/preproc/html \ +- $(top_builddir)/src/devices/grops \ +- $(top_builddir)/src/devices/gropdf \ +- $(top_builddir)/src/devices/grohtml +- +-FFLAG=-F$(top_builddir)/font -F$(top_srcdir)/font +-TFLAG=-M$(top_builddir)/tmac -M$(top_srcdir)/tmac +- +-GROFF=\ +- sed -e "s;@VERSION@;$(version)$(revision);" $< \ +- | GROFF_COMMAND_PREFIX= \ +- GROFF_BIN_PATH="$(GROFF_BIN_PATH)" \ +- $(GROFFBIN) $(TFLAG) $(FFLAG) -Upet -ww +- +-DOCFILES=\ +- meref.me \ +- meintro.me \ +- meintro_fr.me \ +- pic.ms +- +-PROCESSEDDOCFILES=\ +- meref.ps \ +- meintro.ps \ +- meintro_fr.ps \ +- pic.ps +- +-HTMLDOCFILES=\ +- pic.html +- +-HTMLDOCFILESALL=\ +- pic*.html +- +-HTMLDOCIMAGEFILES=\ +- pic* +- +-EXAMPLEFILES=\ +- webpage.ms \ +- groff.css \ +- grnexmpl.g \ +- grnexmpl.me +- +-PROCESSEDEXAMPLEFILES=\ +- webpage.ps \ +- grnexmpl.ps +- +-HTMLEXAMPLEFILES=\ +- webpage.html +- +-HTMLEXAMPLEFILESALL=\ +- webpage*.html +- +-HTMLEXAMPLEIMAGEFILES=\ +- webpage* +- +-imagedir=img +-htmldocimagedir=$(htmldocdir)/$(imagedir) +-exampleimagedir=$(exampledir)/$(imagedir) +- +-MOSTLYCLEANADD=\ +- $(PROCESSEDDOCFILES) \ +- $(PROCESSEDEXAMPLEFILES) \ +- $(HTMLEXAMPLEFILESALL) \ +- $(HTMLDOCFILESALL) \ +- groff.aux groff.cp* groff.dvi groff.es* groff.fn* groff.html groff.ky* \ +- groff.log groff.ma* groff.op* groff.pdf groff.pg* groff.ps groff.rq* \ +- groff.st* groff.toc groff.tp groff.vr* \ +- examples.stamp +- +-MOSTLYCLEANDIRADD=\ +- $(imagedir) +- +-MOSTLYCLEANNOTSRCDIRADD=\ +- groff.css \ +- grnexmpl.g \ +- groff.info \ +- groff-*.info \ +- gnu.eps +- +-RM=rm -f +- +-.SUFFIXES: .me .ms .ps .html +- +-# For simplicity, we always call preconv, grn, and eqn. +-.me.ps: +- $(GROFF) -k -Tps -ge -me >$@ +- +-.ms.html: +- $(GROFF) -P-p -P-b -P-I`basename $< | sed -e 's|.ms$$||'` \ +- -P-D$(imagedir) -P-V -Thtml -ms >$@ +-.ms.ps: +- $(GROFF) -Tps -ms -mwww >$@ +- +-all: $(make_otherdoc) \ +- $(make_infodoc) \ +- $(make_htmldoc) \ +- $(make_examples) \ +- $(make_htmlexamples) +- +-otherdoc: $(PROCESSEDDOCFILES) +-infodoc: groff.info +-htmldoc: $(HTMLDOCFILES) +- +-examples: examples.stamp $(PROCESSEDEXAMPLEFILES) +- +-html_examples: $(HTMLEXAMPLEFILES) +- +-examples.stamp: grnexmpl.g groff.css gnu.eps +- test -f grnexmpl.g || cp $(srcdir)/grnexmpl.g . +- test -f groff.css || cp $(srcdir)/groff.css . +- if test ! -f gnu.eps; then \ +- if test -f $(srcdir)/gnu.eps; then \ +- cp $(srcdir)/gnu.eps .; \ +- elif test -f $(top_builddir)/contrib/pdfmark/gnu.eps; then \ +- cp $(top_builddir)/contrib/pdfmark/gnu.eps .; \ +- fi; \ +- fi +- echo timestamp > $@ +- +-groff.info: groff.texinfo +- $(MAKEINFO) --enable-encoding -I$(srcdir) $(srcdir)/groff.texinfo +- +-gnu.eps: gnu.xpm +- xpmtoppm $(srcdir)/gnu.xpm | pnmdepth 15 \ +- | $(pnmtops_nosetpage) -noturn -rle >$@ +- +-pic.html: pic.ms +- $(GROFF) -P-p -P-I`basename $< | sed -e 's|.ms$$||'` \ +- -P-D$(imagedir) -P-j`basename $< | sed -e 's|.ms$$||'` \ +- -Thtml -P-V -ms >$@ +- +-webpage.html: webpage.ms gnu.eps groff.css +- $(GROFF) -P-j`basename $< | sed -e 's|.ms$$||'` \ +- -P-nrpb -P-I`basename $< | sed -e 's|.ms$$||'` \ +- -P-D$(imagedir) -Thtml -ms >$@ +- +-webpage.ps: gnu.eps +- +-grnexmpl.ps: grnexmpl.me grnexmpl.g +- +-distfiles: groff.info gnu.eps +- +-install_data: install_always $(make_install_otherdoc) \ +- $(make_install_infodoc) $(make_install_htmldoc) \ +- $(make_install_examples) +- +-install_always: +- -test -d $(DESTDIR)$(docdir) || $(mkinstalldirs) $(DESTDIR)$(docdir) +- +-install_otherdoc: install_always $(DOCFILES) $(PROCESSEDDOCFILES) +- for f in $(DOCFILES); do \ +- $(RM) $(DESTDIR)$(docdir)/$$f; \ +- $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(docdir)/$$f; \ +- done +- for f in $(PROCESSEDDOCFILES); do \ +- $(RM) $(DESTDIR)$(docdir)/$$f; \ +- $(INSTALL_DATA) $$f $(DESTDIR)$(docdir)/$$f; \ +- done +- +-install_infodoc: install_always groff.info +-# Prefer info files in builddir over srcdir; we test for +-# the existence of `groff.info'. +- -test -d $(DESTDIR)$(infodir) || $(mkinstalldirs) $(DESTDIR)$(infodir) +- d=.; test -f "groff.info" || d=$(srcdir); \ +- for p in $$d/groff.info `ls $$d/groff.info*`; do \ +- f=`basename $$p`; \ +- $(RM) $(DESTDIR)$(infodir)/$$f; \ +- $(INSTALL_DATA) $$p $(DESTDIR)$(infodir)/$$f; \ +- done +- $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) \ +- $(DESTDIR)$(infodir)/groff.info +- +-install_htmldoc: install_always $(HTMLDOCFILES) +- -test -d $(DESTDIR)$(htmldocdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(htmldocdir) +- for f in `ls $(HTMLDOCFILESALL)`; do \ +- $(RM) $(DESTDIR)$(htmldocdir)/$$f; \ +- $(INSTALL_DATA) $$f $(DESTDIR)$(htmldocdir)/$$f; \ +- done +- -test -d $(DESTDIR)$(htmldocimagedir) \ +- || $(mkinstalldirs) $(DESTDIR)$(htmldocimagedir) +- $(RM) $(DESTDIR)$(htmldocimagedir)/$(HTMLDOCIMAGEFILES) +- $(INSTALL_DATA) $(imagedir)/$(HTMLDOCIMAGEFILES) \ +- $(DESTDIR)$(htmldocimagedir) +- +-install_examples: install_always install_examples_always \ +- $(make_install_htmlexamples) +- +-install_examples_always: gnu.eps $(EXAMPLEFILES) $(PROCESSEDEXAMPLEFILES) +-# Prefer gnu.eps in builddir over srcdir. +- -test -d $(DESTDIR)$(exampledir) \ +- || $(mkinstalldirs) $(DESTDIR)$(exampledir) +- d=.; test -f "gnu.eps" || d=$(srcdir); \ +- $(RM) $(DESTDIR)$(exampledir)/gnu.eps; \ +- $(INSTALL_DATA) $$d/gnu.eps $(DESTDIR)$(exampledir)/gnu.eps +- for f in $(EXAMPLEFILES); do \ +- $(RM) $(DESTDIR)$(exampledir)/$$f; \ +- $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(exampledir)/$$f; \ +- done +- for f in $(PROCESSEDEXAMPLEFILES); do \ +- $(RM) $(DESTDIR)$(exampledir)/$$f; \ +- $(INSTALL_DATA) $$f $(DESTDIR)$(exampledir)/$$f; \ +- done +- +-install_htmlexamples: install_examples_always $(HTMLEXAMPLEFILES) +- for f in `ls $(HTMLEXAMPLEFILESALL)`; do \ +- $(RM) $(DESTDIR)$(exampledir)/$$f; \ +- $(INSTALL_DATA) $$f $(DESTDIR)$(exampledir)/$$f; \ +- done +- -test -d $(DESTDIR)$(exampleimagedir) \ +- || $(mkinstalldirs) $(DESTDIR)$(exampleimagedir) +- $(RM) $(DESTDIR)$(exampleimagedir)/$(HTMLEXAMPLEIMAGEFILES) +- $(INSTALL_DATA) $(imagedir)/$(HTMLEXAMPLEIMAGEFILES) \ +- $(DESTDIR)$(exampleimagedir) +- +-uninstall_sub: uninstall_always \ +- $(make_uninstall_infodoc) $(make_uninstall_htmldoc) \ +- $(make_uninstall_examples) +- +-uninstall_always: +- -for f in $(DOCFILES) $(PROCESSEDDOCFILES); do \ +- $(RM) $(DESTDIR)$(docdir)/$$f; \ +- done +- +-uninstall_infodoc: uninstall_always +- -$(INSTALL_INFO) --remove --info-dir=$(DESTDIR)$(infodir) \ +- $(DESTDIR)$(infodir)/groff.info +- -for f in groff `ls groff.info*`; do \ +- $(RM) $(DESTDIR)$(infodir)/$$f; \ +- done +- +-uninstall_htmldoc: uninstall_always +- -for f in `ls $(HTMLDOCFILESALL)`; do \ +- $(RM) $(DESTDIR)$(htmldocdir)/$$f; \ +- done +- $(RM) $(DESTDIR)$(htmldocimagedir)/$(HTMLDOCIMAGEFILES) +- -test -d $(DESTDIR)$(htmldocimagedir) && \ +- rmdir $(DESTDIR)$(htmldocimagedir) +- +-uninstall_examples: uninstall_always uninstall_examples_always \ +- $(make_uninstall_htmlexamples) +- -test -d $(DESTDIR)$(exampledir) && \ +- rmdir $(DESTDIR)$(exampledir) +- +-uninstall_examples_always: +- -for f in $(EXAMPLEFILES) $(PROCESSEDEXAMPLEFILES); do \ +- $(RM) $(DESTDIR)$(exampledir)/$$f; \ +- done +- $(RM) $(DESTDIR)$(exampledir)/gnu.eps +- +-uninstall_htmlexamples: uninstall_examples_always +- -for f in `ls $(HTMLEXAMPLEFILESALL)`; do \ +- $(RM) $(DESTDIR)$(exampledir)/$$f; \ +- done +- $(RM) $(DESTDIR)$(exampleimagedir)/$(HTMLEXAMPLEIMAGEFILES) +- -test -d $(DESTDIR)$(exampleimagedir) && \ +- rmdir $(DESTDIR)$(exampleimagedir) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/doc/texinfo.tex groff-1.22.3/doc/texinfo.tex +--- groff-1.22.3.old/doc/texinfo.tex 2014-11-04 10:38:35.563519771 +0200 ++++ groff-1.22.3/doc/texinfo.tex 1970-01-01 02:00:00.000000000 +0200 +@@ -1,10183 +0,0 @@ +-% texinfo.tex -- TeX macros to handle Texinfo files. +-% +-% Load plain if necessary, i.e., if running under initex. +-\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +-% +-\def\texinfoversion{2014-10-29.10} +-% +-% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, +-% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +-% 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc. +-% +-% This texinfo.tex file is free software: you can redistribute it and/or +-% modify it under the terms of the GNU General Public License as +-% published by the Free Software Foundation, either version 3 of the +-% License, or (at your option) any later version. +-% +-% This texinfo.tex file is distributed in the hope that it will be +-% useful, but WITHOUT ANY WARRANTY; without even the implied warranty +-% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-% General Public License for more details. +-% +-% You should have received a copy of the GNU General Public License +-% along with this program. If not, see . +-% +-% As a special exception, when this file is read by TeX when processing +-% a Texinfo source document, you may use the result without +-% restriction. This Exception is an additional permission under section 7 +-% of the GNU General Public License, version 3 ("GPLv3"). +-% +-% Please try the latest version of texinfo.tex before submitting bug +-% reports; you can get the latest version from: +-% http://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or +-% http://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or +-% http://www.gnu.org/software/texinfo/ (the Texinfo home page) +-% The texinfo.tex in any given distribution could well be out +-% of date, so if that's what you're using, please check. +-% +-% Send bug reports to bug-texinfo@gnu.org. Please include including a +-% complete document in each bug report with which we can reproduce the +-% problem. Patches are, of course, greatly appreciated. +-% +-% To process a Texinfo manual with TeX, it's most reliable to use the +-% texi2dvi shell script that comes with the distribution. For a simple +-% manual foo.texi, however, you can get away with this: +-% tex foo.texi +-% texindex foo.?? +-% tex foo.texi +-% tex foo.texi +-% dvips foo.dvi -o # or whatever; this makes foo.ps. +-% The extra TeX runs get the cross-reference information correct. +-% Sometimes one run after texindex suffices, and sometimes you need more +-% than two; texi2dvi does it as many times as necessary. +-% +-% It is possible to adapt texinfo.tex for other languages, to some +-% extent. You can get the existing language-specific files from the +-% full Texinfo distribution. +-% +-% The GNU Texinfo home page is http://www.gnu.org/software/texinfo. +- +- +-\message{Loading texinfo [version \texinfoversion]:} +- +-% If in a .fmt file, print the version number +-% and turn on active characters that we couldn't do earlier because +-% they might have appeared in the input file name. +-\everyjob{\message{[Texinfo version \texinfoversion]}% +- \catcode`+=\active \catcode`\_=\active} +- +-\chardef\other=12 +- +-% We never want plain's \outer definition of \+ in Texinfo. +-% For @tex, we can use \tabalign. +-\let\+ = \relax +- +-% Save some plain tex macros whose names we will redefine. +-\let\ptexb=\b +-\let\ptexbullet=\bullet +-\let\ptexc=\c +-\let\ptexcomma=\, +-\let\ptexdot=\. +-\let\ptexdots=\dots +-\let\ptexend=\end +-\let\ptexequiv=\equiv +-\let\ptexexclam=\! +-\let\ptexfootnote=\footnote +-\let\ptexgtr=> +-\let\ptexhat=^ +-\let\ptexi=\i +-\let\ptexindent=\indent +-\let\ptexinsert=\insert +-\let\ptexlbrace=\{ +-\let\ptexless=< +-\let\ptexnewwrite\newwrite +-\let\ptexnoindent=\noindent +-\let\ptexplus=+ +-\let\ptexraggedright=\raggedright +-\let\ptexrbrace=\} +-\let\ptexslash=\/ +-\let\ptexstar=\* +-\let\ptext=\t +-\let\ptextop=\top +-{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode +- +-% If this character appears in an error message or help string, it +-% starts a new line in the output. +-\newlinechar = `^^J +- +-% Use TeX 3.0's \inputlineno to get the line number, for better error +-% messages, but if we're using an old version of TeX, don't do anything. +-% +-\ifx\inputlineno\thisisundefined +- \let\linenumber = \empty % Pre-3.0. +-\else +- \def\linenumber{l.\the\inputlineno:\space} +-\fi +- +-% Set up fixed words for English if not already set. +-\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +-\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +-\ifx\putworderror\undefined \gdef\putworderror{error}\fi +-\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +-\ifx\putwordin\undefined \gdef\putwordin{in}\fi +-\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +-\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +-\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +-\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +-\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +-\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +-\ifx\putwordof\undefined \gdef\putwordof{of}\fi +-\ifx\putwordon\undefined \gdef\putwordon{on}\fi +-\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +-\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +-\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +-\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +-\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +-\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +-\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +-% +-\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +-\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +-\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +-\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +-\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +-\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +-\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +-\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +-\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +-\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +-\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +-\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +-% +-\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +-\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +-\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +-\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +-\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi +- +-% Since the category of space is not known, we have to be careful. +-\chardef\spacecat = 10 +-\def\spaceisspace{\catcode`\ =\spacecat} +- +-% sometimes characters are active, so we need control sequences. +-\chardef\ampChar = `\& +-\chardef\colonChar = `\: +-\chardef\commaChar = `\, +-\chardef\dashChar = `\- +-\chardef\dotChar = `\. +-\chardef\exclamChar= `\! +-\chardef\hashChar = `\# +-\chardef\lquoteChar= `\` +-\chardef\questChar = `\? +-\chardef\rquoteChar= `\' +-\chardef\semiChar = `\; +-\chardef\slashChar = `\/ +-\chardef\underChar = `\_ +- +-% Ignore a token. +-% +-\def\gobble#1{} +- +-% The following is used inside several \edef's. +-\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} +- +-% Hyphenation fixes. +-\hyphenation{ +- Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script +- ap-pen-dix bit-map bit-maps +- data-base data-bases eshell fall-ing half-way long-est man-u-script +- man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm +- par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces +- spell-ing spell-ings +- stand-alone strong-est time-stamp time-stamps which-ever white-space +- wide-spread wrap-around +-} +- +-% Margin to add to right of even pages, to left of odd pages. +-\newdimen\bindingoffset +-\newdimen\normaloffset +-\newdimen\pagewidth \newdimen\pageheight +- +-% For a final copy, take out the rectangles +-% that mark overfull boxes (in case you have decided +-% that the text looks ok even though it passes the margin). +-% +-\def\finalout{\overfullrule=0pt } +- +-% Sometimes it is convenient to have everything in the transcript file +-% and nothing on the terminal. We don't just call \tracingall here, +-% since that produces some useless output on the terminal. We also make +-% some effort to order the tracing commands to reduce output in the log +-% file; cf. trace.sty in LaTeX. +-% +-\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +-\def\loggingall{% +- \tracingstats2 +- \tracingpages1 +- \tracinglostchars2 % 2 gives us more in etex +- \tracingparagraphs1 +- \tracingoutput1 +- \tracingmacros2 +- \tracingrestores1 +- \showboxbreadth\maxdimen \showboxdepth\maxdimen +- \ifx\eTeXversion\thisisundefined\else % etex gives us more logging +- \tracingscantokens1 +- \tracingifs1 +- \tracinggroups1 +- \tracingnesting2 +- \tracingassigns1 +- \fi +- \tracingcommands3 % 3 gives us more in etex +- \errorcontextlines16 +-}% +- +-% @errormsg{MSG}. Do the index-like expansions on MSG, but if things +-% aren't perfect, it's not the end of the world, being an error message, +-% after all. +-% +-\def\errormsg{\begingroup \indexnofonts \doerrormsg} +-\def\doerrormsg#1{\errmessage{#1}} +- +-% add check for \lastpenalty to plain's definitions. If the last thing +-% we did was a \nobreak, we don't want to insert more space. +-% +-\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount +- \removelastskip\penalty-50\smallskip\fi\fi} +-\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount +- \removelastskip\penalty-100\medskip\fi\fi} +-\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount +- \removelastskip\penalty-200\bigskip\fi\fi} +- +-% Do @cropmarks to get crop marks. +-% +-\newif\ifcropmarks +-\let\cropmarks = \cropmarkstrue +-% +-% Dimensions to add cropmarks at corners. +-% Added by P. A. MacKay, 12 Nov. 1986 +-% +-\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +-\newdimen\cornerlong \cornerlong=1pc +-\newdimen\cornerthick \cornerthick=.3pt +-\newdimen\topandbottommargin \topandbottommargin=.75in +- +-% Output a mark which sets \thischapter, \thissection and \thiscolor. +-% We dump everything together because we only have one kind of mark. +-% This works because we only use \botmark / \topmark, not \firstmark. +-% +-% A mark contains a subexpression of the \ifcase ... \fi construct. +-% \get*marks macros below extract the needed part using \ifcase. +-% +-% Another complication is to let the user choose whether \thischapter +-% (\thissection) refers to the chapter (section) in effect at the top +-% of a page, or that at the bottom of a page. The solution is +-% described on page 260 of The TeXbook. It involves outputting two +-% marks for the sectioning macros, one before the section break, and +-% one after. I won't pretend I can describe this better than DEK... +-\def\domark{% +- \toks0=\expandafter{\lastchapterdefs}% +- \toks2=\expandafter{\lastsectiondefs}% +- \toks4=\expandafter{\prevchapterdefs}% +- \toks6=\expandafter{\prevsectiondefs}% +- \toks8=\expandafter{\lastcolordefs}% +- \mark{% +- \the\toks0 \the\toks2 % 0: top marks (\last...) +- \noexpand\or \the\toks4 \the\toks6 % 1: bottom marks (default, \prev...) +- \noexpand\else \the\toks8 % 2: color marks +- }% +-} +-% \topmark doesn't work for the very first chapter (after the title +-% page or the contents), so we use \firstmark there -- this gets us +-% the mark with the chapter defs, unless the user sneaks in, e.g., +-% @setcolor (or @url, or @link, etc.) between @contents and the very +-% first @chapter. +-\def\gettopheadingmarks{% +- \ifcase0\topmark\fi +- \ifx\thischapter\empty \ifcase0\firstmark\fi \fi +-} +-\def\getbottomheadingmarks{\ifcase1\botmark\fi} +-\def\getcolormarks{\ifcase2\topmark\fi} +- +-% Avoid "undefined control sequence" errors. +-\def\lastchapterdefs{} +-\def\lastsectiondefs{} +-\def\prevchapterdefs{} +-\def\prevsectiondefs{} +-\def\lastcolordefs{} +- +-% Main output routine. +-\chardef\PAGE = 255 +-\output = {\onepageout{\pagecontents\PAGE}} +- +-\newbox\headlinebox +-\newbox\footlinebox +- +-% \onepageout takes a vbox as an argument. Note that \pagecontents +-% does insertions, but you have to call it yourself. +-\def\onepageout#1{% +- \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi +- % +- \ifodd\pageno \advance\hoffset by \bindingoffset +- \else \advance\hoffset by -\bindingoffset\fi +- % +- % Do this outside of the \shipout so @code etc. will be expanded in +- % the headline as they should be, not taken literally (outputting ''code). +- \def\commmonheadfootline{\let\hsize=\pagewidth \texinfochars} +- % +- \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi +- \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}% +- % +- \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi +- \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}% +- % +- {% +- % Have to do this stuff outside the \shipout because we want it to +- % take effect in \write's, yet the group defined by the \vbox ends +- % before the \shipout runs. +- % +- \indexdummies % don't expand commands in the output. +- \normalturnoffactive % \ in index entries must not stay \, e.g., if +- % the page break happens to be in the middle of an example. +- % We don't want .vr (or whatever) entries like this: +- % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}} +- % "\acronym" won't work when it's read back in; +- % it needs to be +- % {\code {{\tt \backslashcurfont }acronym} +- \shipout\vbox{% +- % Do this early so pdf references go to the beginning of the page. +- \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi +- % +- \ifcropmarks \vbox to \outervsize\bgroup +- \hsize = \outerhsize +- \vskip-\topandbottommargin +- \vtop to0pt{% +- \line{\ewtop\hfil\ewtop}% +- \nointerlineskip +- \line{% +- \vbox{\moveleft\cornerthick\nstop}% +- \hfill +- \vbox{\moveright\cornerthick\nstop}% +- }% +- \vss}% +- \vskip\topandbottommargin +- \line\bgroup +- \hfil % center the page within the outer (page) hsize. +- \ifodd\pageno\hskip\bindingoffset\fi +- \vbox\bgroup +- \fi +- % +- \unvbox\headlinebox +- \pagebody{#1}% +- \ifdim\ht\footlinebox > 0pt +- % Only leave this space if the footline is nonempty. +- % (We lessened \vsize for it in \oddfootingyyy.) +- % The \baselineskip=24pt in plain's \makefootline has no effect. +- \vskip 24pt +- \unvbox\footlinebox +- \fi +- % +- \ifcropmarks +- \egroup % end of \vbox\bgroup +- \hfil\egroup % end of (centering) \line\bgroup +- \vskip\topandbottommargin plus1fill minus1fill +- \boxmaxdepth = \cornerthick +- \vbox to0pt{\vss +- \line{% +- \vbox{\moveleft\cornerthick\nsbot}% +- \hfill +- \vbox{\moveright\cornerthick\nsbot}% +- }% +- \nointerlineskip +- \line{\ewbot\hfil\ewbot}% +- }% +- \egroup % \vbox from first cropmarks clause +- \fi +- }% end of \shipout\vbox +- }% end of group with \indexdummies +- \advancepageno +- \ifnum\outputpenalty>-20000 \else\dosupereject\fi +-} +- +-\newinsert\margin \dimen\margin=\maxdimen +- +-\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}} +-{\catcode`\@ =11 +-\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +-% marginal hacks, juha@viisa.uucp (Juha Takala) +-\ifvoid\margin\else % marginal info is present +- \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +-\dimen@=\dp#1\relax \unvbox#1\relax +-\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi +-\ifr@ggedbottom \kern-\dimen@ \vfil \fi} +-} +- +-% Here are the rules for the cropmarks. Note that they are +-% offset so that the space between them is truly \outerhsize or \outervsize +-% (P. A. MacKay, 12 November, 1986) +-% +-\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong} +-\def\nstop{\vbox +- {\hrule height\cornerthick depth\cornerlong width\cornerthick}} +-\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong} +-\def\nsbot{\vbox +- {\hrule height\cornerlong depth\cornerthick width\cornerthick}} +- +-% Parse an argument, then pass it to #1. The argument is the rest of +-% the input line (except we remove a trailing comment). #1 should be a +-% macro which expects an ordinary undelimited TeX argument. +-% +-\def\parsearg{\parseargusing{}} +-\def\parseargusing#1#2{% +- \def\argtorun{#2}% +- \begingroup +- \obeylines +- \spaceisspace +- #1% +- \parseargline\empty% Insert the \empty token, see \finishparsearg below. +-} +- +-{\obeylines % +- \gdef\parseargline#1^^M{% +- \endgroup % End of the group started in \parsearg. +- \argremovecomment #1\comment\ArgTerm% +- }% +-} +- +-% First remove any @comment, then any @c comment. +-\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} +-\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} +- +-% Each occurrence of `\^^M' or `\^^M' is replaced by a single space. +-% +-% \argremovec might leave us with trailing space, e.g., +-% @end itemize @c foo +-% This space token undergoes the same procedure and is eventually removed +-% by \finishparsearg. +-% +-\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} +-\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} +-\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% +- \def\temp{#3}% +- \ifx\temp\empty +- % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: +- \let\temp\finishparsearg +- \else +- \let\temp\argcheckspaces +- \fi +- % Put the space token in: +- \temp#1 #3\ArgTerm +-} +- +-% If a _delimited_ argument is enclosed in braces, they get stripped; so +-% to get _exactly_ the rest of the line, we had to prevent such situation. +-% We prepended an \empty token at the very beginning and we expand it now, +-% just before passing the control to \argtorun. +-% (Similarly, we have to think about #3 of \argcheckspacesY above: it is +-% either the null string, or it ends with \^^M---thus there is no danger +-% that a pair of braces would be stripped. +-% +-% But first, we have to remove the trailing space token. +-% +-\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} +- +-% \parseargdef\foo{...} +-% is roughly equivalent to +-% \def\foo{\parsearg\Xfoo} +-% \def\Xfoo#1{...} +-% +-% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my +-% favourite TeX trick. --kasal, 16nov03 +- +-\def\parseargdef#1{% +- \expandafter \doparseargdef \csname\string#1\endcsname #1% +-} +-\def\doparseargdef#1#2{% +- \def#2{\parsearg#1}% +- \def#1##1% +-} +- +-% Several utility definitions with active space: +-{ +- \obeyspaces +- \gdef\obeyedspace{ } +- +- % Make each space character in the input produce a normal interword +- % space in the output. Don't allow a line break at this space, as this +- % is used only in environments like @example, where each line of input +- % should produce a line of output anyway. +- % +- \gdef\sepspaces{\obeyspaces\let =\tie} +- +- % If an index command is used in an @example environment, any spaces +- % therein should become regular spaces in the raw index file, not the +- % expansion of \tie (\leavevmode \penalty \@M \ ). +- \gdef\unsepspaces{\let =\space} +-} +- +- +-\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} +- +-% Define the framework for environments in texinfo.tex. It's used like this: +-% +-% \envdef\foo{...} +-% \def\Efoo{...} +-% +-% It's the responsibility of \envdef to insert \begingroup before the +-% actual body; @end closes the group after calling \Efoo. \envdef also +-% defines \thisenv, so the current environment is known; @end checks +-% whether the environment name matches. The \checkenv macro can also be +-% used to check whether the current environment is the one expected. +-% +-% Non-false conditionals (@iftex, @ifset) don't fit into this, so they +-% are not treated as environments; they don't open a group. (The +-% implementation of @end takes care not to call \endgroup in this +-% special case.) +- +- +-% At run-time, environments start with this: +-\def\startenvironment#1{\begingroup\def\thisenv{#1}} +-% initialize +-\let\thisenv\empty +- +-% ... but they get defined via ``\envdef\foo{...}'': +-\long\def\envdef#1#2{\def#1{\startenvironment#1#2}} +-\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} +- +-% Check whether we're in the right environment: +-\def\checkenv#1{% +- \def\temp{#1}% +- \ifx\thisenv\temp +- \else +- \badenverr +- \fi +-} +- +-% Environment mismatch, #1 expected: +-\def\badenverr{% +- \errhelp = \EMsimple +- \errmessage{This command can appear only \inenvironment\temp, +- not \inenvironment\thisenv}% +-} +-\def\inenvironment#1{% +- \ifx#1\empty +- outside of any environment% +- \else +- in environment \expandafter\string#1% +- \fi +-} +- +-% @end foo executes the definition of \Efoo. +-% But first, it executes a specialized version of \checkenv +-% +-\parseargdef\end{% +- \if 1\csname iscond.#1\endcsname +- \else +- % The general wording of \badenverr may not be ideal. +- \expandafter\checkenv\csname#1\endcsname +- \csname E#1\endcsname +- \endgroup +- \fi +-} +- +-\newhelp\EMsimple{Press RETURN to continue.} +- +- +-% Be sure we're in horizontal mode when doing a tie, since we make space +-% equivalent to this in @example-like environments. Otherwise, a space +-% at the beginning of a line will start with \penalty -- and +-% since \penalty is valid in vertical mode, we'd end up putting the +-% penalty on the vertical list instead of in the new paragraph. +-{\catcode`@ = 11 +- % Avoid using \@M directly, because that causes trouble +- % if the definition is written into an index file. +- \global\let\tiepenalty = \@M +- \gdef\tie{\leavevmode\penalty\tiepenalty\ } +-} +- +-% @: forces normal size whitespace following. +-\def\:{\spacefactor=1000 } +- +-% @* forces a line break. +-\def\*{\unskip\hfil\break\hbox{}\ignorespaces} +- +-% @/ allows a line break. +-\let\/=\allowbreak +- +-% @. is an end-of-sentence period. +-\def\.{.\spacefactor=\endofsentencespacefactor\space} +- +-% @! is an end-of-sentence bang. +-\def\!{!\spacefactor=\endofsentencespacefactor\space} +- +-% @? is an end-of-sentence query. +-\def\?{?\spacefactor=\endofsentencespacefactor\space} +- +-% @frenchspacing on|off says whether to put extra space after punctuation. +-% +-\def\onword{on} +-\def\offword{off} +-% +-\parseargdef\frenchspacing{% +- \def\temp{#1}% +- \ifx\temp\onword \plainfrenchspacing +- \else\ifx\temp\offword \plainnonfrenchspacing +- \else +- \errhelp = \EMsimple +- \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% +- \fi\fi +-} +- +-% @w prevents a word break. Without the \leavevmode, @w at the +-% beginning of a paragraph, when TeX is still in vertical mode, would +-% produce a whole line of output instead of starting the paragraph. +-\def\w#1{\leavevmode\hbox{#1}} +- +-% @group ... @end group forces ... to be all on one page, by enclosing +-% it in a TeX vbox. We use \vtop instead of \vbox to construct the box +-% to keep its height that of a normal line. According to the rules for +-% \topskip (p.114 of the TeXbook), the glue inserted is +-% max (\topskip - \ht (first item), 0). If that height is large, +-% therefore, no glue is inserted, and the space between the headline and +-% the text is small, which looks bad. +-% +-% Another complication is that the group might be very large. This can +-% cause the glue on the previous page to be unduly stretched, because it +-% does not have much material. In this case, it's better to add an +-% explicit \vfill so that the extra space is at the bottom. The +-% threshold for doing this is if the group is more than \vfilllimit +-% percent of a page (\vfilllimit can be changed inside of @tex). +-% +-\newbox\groupbox +-\def\vfilllimit{0.7} +-% +-\envdef\group{% +- \ifnum\catcode`\^^M=\active \else +- \errhelp = \groupinvalidhelp +- \errmessage{@group invalid in context where filling is enabled}% +- \fi +- \startsavinginserts +- % +- \setbox\groupbox = \vtop\bgroup +- % Do @comment since we are called inside an environment such as +- % @example, where each end-of-line in the input causes an +- % end-of-line in the output. We don't want the end-of-line after +- % the `@group' to put extra space in the output. Since @group +- % should appear on a line by itself (according to the Texinfo +- % manual), we don't worry about eating any user text. +- \comment +-} +-% +-% The \vtop produces a box with normal height and large depth; thus, TeX puts +-% \baselineskip glue before it, and (when the next line of text is done) +-% \lineskip glue after it. Thus, space below is not quite equal to space +-% above. But it's pretty close. +-\def\Egroup{% +- % To get correct interline space between the last line of the group +- % and the first line afterwards, we have to propagate \prevdepth. +- \endgraf % Not \par, as it may have been set to \lisppar. +- \global\dimen1 = \prevdepth +- \egroup % End the \vtop. +- % \dimen0 is the vertical size of the group's box. +- \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox +- % \dimen2 is how much space is left on the page (more or less). +- \dimen2 = \pageheight \advance\dimen2 by -\pagetotal +- % if the group doesn't fit on the current page, and it's a big big +- % group, force a page break. +- \ifdim \dimen0 > \dimen2 +- \ifdim \pagetotal < \vfilllimit\pageheight +- \page +- \fi +- \fi +- \box\groupbox +- \prevdepth = \dimen1 +- \checkinserts +-} +-% +-% TeX puts in an \escapechar (i.e., `@') at the beginning of the help +-% message, so this ends up printing `@group can only ...'. +-% +-\newhelp\groupinvalidhelp{% +-group can only be used in environments such as @example,^^J% +-where each line of input produces a line of output.} +- +-% @need space-in-mils +-% forces a page break if there is not space-in-mils remaining. +- +-\newdimen\mil \mil=0.001in +- +-\parseargdef\need{% +- % Ensure vertical mode, so we don't make a big box in the middle of a +- % paragraph. +- \par +- % +- % If the @need value is less than one line space, it's useless. +- \dimen0 = #1\mil +- \dimen2 = \ht\strutbox +- \advance\dimen2 by \dp\strutbox +- \ifdim\dimen0 > \dimen2 +- % +- % Do a \strut just to make the height of this box be normal, so the +- % normal leading is inserted relative to the preceding line. +- % And a page break here is fine. +- \vtop to #1\mil{\strut\vfil}% +- % +- % TeX does not even consider page breaks if a penalty added to the +- % main vertical list is 10000 or more. But in order to see if the +- % empty box we just added fits on the page, we must make it consider +- % page breaks. On the other hand, we don't want to actually break the +- % page after the empty box. So we use a penalty of 9999. +- % +- % There is an extremely small chance that TeX will actually break the +- % page at this \penalty, if there are no other feasible breakpoints in +- % sight. (If the user is using lots of big @group commands, which +- % almost-but-not-quite fill up a page, TeX will have a hard time doing +- % good page breaking, for example.) However, I could not construct an +- % example where a page broke at this \penalty; if it happens in a real +- % document, then we can reconsider our strategy. +- \penalty9999 +- % +- % Back up by the size of the box, whether we did a page break or not. +- \kern -#1\mil +- % +- % Do not allow a page break right after this kern. +- \nobreak +- \fi +-} +- +-% @br forces paragraph break (and is undocumented). +- +-\let\br = \par +- +-% @page forces the start of a new page. +-% +-\def\page{\par\vfill\supereject} +- +-% @exdent text.... +-% outputs text on separate line in roman font, starting at standard page margin +- +-% This records the amount of indent in the innermost environment. +-% That's how much \exdent should take out. +-\newskip\exdentamount +- +-% This defn is used inside fill environments such as @defun. +-\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} +- +-% This defn is used inside nofill environments such as @example. +-\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount +- \leftline{\hskip\leftskip{\rm#1}}}} +- +-% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current +-% paragraph. For more general purposes, use the \margin insertion +-% class. WHICH is `l' or `r'. Not documented, written for gawk manual. +-% +-\newskip\inmarginspacing \inmarginspacing=1cm +-\def\strutdepth{\dp\strutbox} +-% +-\def\doinmargin#1#2{\strut\vadjust{% +- \nobreak +- \kern-\strutdepth +- \vtop to \strutdepth{% +- \baselineskip=\strutdepth +- \vss +- % if you have multiple lines of stuff to put here, you'll need to +- % make the vbox yourself of the appropriate size. +- \ifx#1l% +- \llap{\ignorespaces #2\hskip\inmarginspacing}% +- \else +- \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% +- \fi +- \null +- }% +-}} +-\def\inleftmargin{\doinmargin l} +-\def\inrightmargin{\doinmargin r} +-% +-% @inmargin{TEXT [, RIGHT-TEXT]} +-% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; +-% else use TEXT for both). +-% +-\def\inmargin#1{\parseinmargin #1,,\finish} +-\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. +- \setbox0 = \hbox{\ignorespaces #2}% +- \ifdim\wd0 > 0pt +- \def\lefttext{#1}% have both texts +- \def\righttext{#2}% +- \else +- \def\lefttext{#1}% have only one text +- \def\righttext{#1}% +- \fi +- % +- \ifodd\pageno +- \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin +- \else +- \def\temp{\inleftmargin\lefttext}% +- \fi +- \temp +-} +- +-% @| inserts a changebar to the left of the current line. It should +-% surround any changed text. This approach does *not* work if the +-% change spans more than two lines of output. To handle that, we would +-% have adopt a much more difficult approach (putting marks into the main +-% vertical list for the beginning and end of each change). This command +-% is not documented, not supported, and doesn't work. +-% +-\def\|{% +- % \vadjust can only be used in horizontal mode. +- \leavevmode +- % +- % Append this vertical mode material after the current line in the output. +- \vadjust{% +- % We want to insert a rule with the height and depth of the current +- % leading; that is exactly what \strutbox is supposed to record. +- \vskip-\baselineskip +- % +- % \vadjust-items are inserted at the left edge of the type. So +- % the \llap here moves out into the left-hand margin. +- \llap{% +- % +- % For a thicker or thinner bar, change the `1pt'. +- \vrule height\baselineskip width1pt +- % +- % This is the space between the bar and the text. +- \hskip 12pt +- }% +- }% +-} +- +-% @include FILE -- \input text of FILE. +-% +-\def\include{\parseargusing\filenamecatcodes\includezzz} +-\def\includezzz#1{% +- \pushthisfilestack +- \def\thisfile{#1}% +- {% +- \makevalueexpandable % we want to expand any @value in FILE. +- \turnoffactive % and allow special characters in the expansion +- \indexnofonts % Allow `@@' and other weird things in file names. +- \wlog{texinfo.tex: doing @include of #1^^J}% +- \edef\temp{\noexpand\input #1 }% +- % +- % This trickery is to read FILE outside of a group, in case it makes +- % definitions, etc. +- \expandafter +- }\temp +- \popthisfilestack +-} +-\def\filenamecatcodes{% +- \catcode`\\=\other +- \catcode`~=\other +- \catcode`^=\other +- \catcode`_=\other +- \catcode`|=\other +- \catcode`<=\other +- \catcode`>=\other +- \catcode`+=\other +- \catcode`-=\other +- \catcode`\`=\other +- \catcode`\'=\other +-} +- +-\def\pushthisfilestack{% +- \expandafter\pushthisfilestackX\popthisfilestack\StackTerm +-} +-\def\pushthisfilestackX{% +- \expandafter\pushthisfilestackY\thisfile\StackTerm +-} +-\def\pushthisfilestackY #1\StackTerm #2\StackTerm {% +- \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% +-} +- +-\def\popthisfilestack{\errthisfilestackempty} +-\def\errthisfilestackempty{\errmessage{Internal error: +- the stack of filenames is empty.}} +-% +-\def\thisfile{} +- +-% @center line +-% outputs that line, centered. +-% +-\parseargdef\center{% +- \ifhmode +- \let\centersub\centerH +- \else +- \let\centersub\centerV +- \fi +- \centersub{\hfil \ignorespaces#1\unskip \hfil}% +- \let\centersub\relax % don't let the definition persist, just in case +-} +-\def\centerH#1{{% +- \hfil\break +- \advance\hsize by -\leftskip +- \advance\hsize by -\rightskip +- \line{#1}% +- \break +-}} +-% +-\newcount\centerpenalty +-\def\centerV#1{% +- % The idea here is the same as in \startdefun, \cartouche, etc.: if +- % @center is the first thing after a section heading, we need to wipe +- % out the negative parskip inserted by \sectionheading, but still +- % prevent a page break here. +- \centerpenalty = \lastpenalty +- \ifnum\centerpenalty>10000 \vskip\parskip \fi +- \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi +- \line{\kern\leftskip #1\kern\rightskip}% +-} +- +-% @sp n outputs n lines of vertical space +-% +-\parseargdef\sp{\vskip #1\baselineskip} +- +-% @comment ...line which is ignored... +-% @c is the same as @comment +-% @ignore ... @end ignore is another way to write a comment +-% +-\def\comment{\begingroup \catcode`\^^M=\other% +-\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +-\commentxxx} +-{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}} +-% +-\let\c=\comment +- +-% @paragraphindent NCHARS +-% We'll use ems for NCHARS, close enough. +-% NCHARS can also be the word `asis' or `none'. +-% We cannot feasibly implement @paragraphindent asis, though. +-% +-\def\asisword{asis} % no translation, these are keywords +-\def\noneword{none} +-% +-\parseargdef\paragraphindent{% +- \def\temp{#1}% +- \ifx\temp\asisword +- \else +- \ifx\temp\noneword +- \defaultparindent = 0pt +- \else +- \defaultparindent = #1em +- \fi +- \fi +- \parindent = \defaultparindent +-} +- +-% @exampleindent NCHARS +-% We'll use ems for NCHARS like @paragraphindent. +-% It seems @exampleindent asis isn't necessary, but +-% I preserve it to make it similar to @paragraphindent. +-\parseargdef\exampleindent{% +- \def\temp{#1}% +- \ifx\temp\asisword +- \else +- \ifx\temp\noneword +- \lispnarrowing = 0pt +- \else +- \lispnarrowing = #1em +- \fi +- \fi +-} +- +-% @firstparagraphindent WORD +-% If WORD is `none', then suppress indentation of the first paragraph +-% after a section heading. If WORD is `insert', then do indent at such +-% paragraphs. +-% +-% The paragraph indentation is suppressed or not by calling +-% \suppressfirstparagraphindent, which the sectioning commands do. +-% We switch the definition of this back and forth according to WORD. +-% By default, we suppress indentation. +-% +-\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} +-\def\insertword{insert} +-% +-\parseargdef\firstparagraphindent{% +- \def\temp{#1}% +- \ifx\temp\noneword +- \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent +- \else\ifx\temp\insertword +- \let\suppressfirstparagraphindent = \relax +- \else +- \errhelp = \EMsimple +- \errmessage{Unknown @firstparagraphindent option `\temp'}% +- \fi\fi +-} +- +-% Here is how we actually suppress indentation. Redefine \everypar to +-% \kern backwards by \parindent, and then reset itself to empty. +-% +-% We also make \indent itself not actually do anything until the next +-% paragraph. +-% +-\gdef\dosuppressfirstparagraphindent{% +- \gdef\indent{% +- \restorefirstparagraphindent +- \indent +- }% +- \gdef\noindent{% +- \restorefirstparagraphindent +- \noindent +- }% +- \global\everypar = {% +- \kern -\parindent +- \restorefirstparagraphindent +- }% +-} +- +-\gdef\restorefirstparagraphindent{% +- \global \let \indent = \ptexindent +- \global \let \noindent = \ptexnoindent +- \global \everypar = {}% +-} +- +- +-% @refill is a no-op. +-\let\refill=\relax +- +-% If working on a large document in chapters, it is convenient to +-% be able to disable indexing, cross-referencing, and contents, for test runs. +-% This is done with @novalidate (before @setfilename). +-% +-\newif\iflinks \linkstrue % by default we want the aux files. +-\let\novalidate = \linksfalse +- +-% @setfilename is done at the beginning of every texinfo file. +-% So open here the files we need to have open while reading the input. +-% This makes it possible to make a .fmt file for texinfo. +-\def\setfilename{% +- \fixbackslash % Turn off hack to swallow `\input texinfo'. +- \iflinks +- \tryauxfile +- % Open the new aux file. TeX will close it automatically at exit. +- \immediate\openout\auxfile=\jobname.aux +- \fi % \openindices needs to do some work in any case. +- \openindices +- \let\setfilename=\comment % Ignore extra @setfilename cmds. +- % +- % If texinfo.cnf is present on the system, read it. +- % Useful for site-wide @afourpaper, etc. +- \openin 1 texinfo.cnf +- \ifeof 1 \else \input texinfo.cnf \fi +- \closein 1 +- % +- \comment % Ignore the actual filename. +-} +- +-% Called from \setfilename. +-% +-\def\openindices{% +- \newindex{cp}% +- \newcodeindex{fn}% +- \newcodeindex{vr}% +- \newcodeindex{tp}% +- \newcodeindex{ky}% +- \newcodeindex{pg}% +-} +- +-% @bye. +-\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} +- +- +-\message{pdf,} +-% adobe `portable' document format +-\newcount\tempnum +-\newcount\lnkcount +-\newtoks\filename +-\newcount\filenamelength +-\newcount\pgn +-\newtoks\toksA +-\newtoks\toksB +-\newtoks\toksC +-\newtoks\toksD +-\newbox\boxA +-\newcount\countA +-\newif\ifpdf +-\newif\ifpdfmakepagedest +- +-% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 +-% can be set). So we test for \relax and 0 as well as being undefined. +-\ifx\pdfoutput\thisisundefined +-\else +- \ifx\pdfoutput\relax +- \else +- \ifcase\pdfoutput +- \else +- \pdftrue +- \fi +- \fi +-\fi +- +-% PDF uses PostScript string constants for the names of xref targets, +-% for display in the outlines, and in other places. Thus, we have to +-% double any backslashes. Otherwise, a name like "\node" will be +-% interpreted as a newline (\n), followed by o, d, e. Not good. +-% +-% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and +-% related messages. The final outcome is that it is up to the TeX user +-% to double the backslashes and otherwise make the string valid, so +-% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to +-% do this reliably, so we use it. +- +-% #1 is a control sequence in which to do the replacements, +-% which we \xdef. +-\def\txiescapepdf#1{% +- \ifx\pdfescapestring\thisisundefined +- % No primitive available; should we give a warning or log? +- % Many times it won't matter. +- \else +- % The expandable \pdfescapestring primitive escapes parentheses, +- % backslashes, and other special chars. +- \xdef#1{\pdfescapestring{#1}}% +- \fi +-} +- +-\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images +-with PDF output, and none of those formats could be found. (.eps cannot +-be supported due to the design of the PDF format; use regular TeX (DVI +-output) for that.)} +- +-\ifpdf +- % +- % Color manipulation macros using ideas from pdfcolor.tex, +- % except using rgb instead of cmyk; the latter is said to render as a +- % very dark gray on-screen and a very dark halftone in print, instead +- % of actual black. The dark red here is dark enough to print on paper as +- % nearly black, but still distinguishable for online viewing. We use +- % black by default, though. +- \def\rgbDarkRed{0.50 0.09 0.12} +- \def\rgbBlack{0 0 0} +- % +- % k sets the color for filling (usual text, etc.); +- % K sets the color for stroking (thin rules, e.g., normal _'s). +- \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} +- % +- % Set color, and create a mark which defines \thiscolor accordingly, +- % so that \makeheadline knows which color to restore. +- \def\setcolor#1{% +- \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% +- \domark +- \pdfsetcolor{#1}% +- } +- % +- \def\maincolor{\rgbBlack} +- \pdfsetcolor{\maincolor} +- \edef\thiscolor{\maincolor} +- \def\lastcolordefs{} +- % +- \def\makefootline{% +- \baselineskip24pt +- \line{\pdfsetcolor{\maincolor}\the\footline}% +- } +- % +- \def\makeheadline{% +- \vbox to 0pt{% +- \vskip-22.5pt +- \line{% +- \vbox to8.5pt{}% +- % Extract \thiscolor definition from the marks. +- \getcolormarks +- % Typeset the headline with \maincolor, then restore the color. +- \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% +- }% +- \vss +- }% +- \nointerlineskip +- } +- % +- % +- \pdfcatalog{/PageMode /UseOutlines} +- % +- % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). +- \def\dopdfimage#1#2#3{% +- \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% +- \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% +- % +- % pdftex (and the PDF format) support .pdf, .png, .jpg (among +- % others). Let's try in that order, PDF first since if +- % someone has a scalable image, presumably better to use that than a +- % bitmap. +- \let\pdfimgext=\empty +- \begingroup +- \openin 1 #1.pdf \ifeof 1 +- \openin 1 #1.PDF \ifeof 1 +- \openin 1 #1.png \ifeof 1 +- \openin 1 #1.jpg \ifeof 1 +- \openin 1 #1.jpeg \ifeof 1 +- \openin 1 #1.JPG \ifeof 1 +- \errhelp = \nopdfimagehelp +- \errmessage{Could not find image file #1 for pdf}% +- \else \gdef\pdfimgext{JPG}% +- \fi +- \else \gdef\pdfimgext{jpeg}% +- \fi +- \else \gdef\pdfimgext{jpg}% +- \fi +- \else \gdef\pdfimgext{png}% +- \fi +- \else \gdef\pdfimgext{PDF}% +- \fi +- \else \gdef\pdfimgext{pdf}% +- \fi +- \closein 1 +- \endgroup +- % +- % without \immediate, ancient pdftex seg faults when the same image is +- % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) +- \ifnum\pdftexversion < 14 +- \immediate\pdfimage +- \else +- \immediate\pdfximage +- \fi +- \ifdim \wd0 >0pt width \pdfimagewidth \fi +- \ifdim \wd2 >0pt height \pdfimageheight \fi +- \ifnum\pdftexversion<13 +- #1.\pdfimgext +- \else +- {#1.\pdfimgext}% +- \fi +- \ifnum\pdftexversion < 14 \else +- \pdfrefximage \pdflastximage +- \fi} +- % +- \def\pdfmkdest#1{{% +- % We have to set dummies so commands such as @code, and characters +- % such as \, aren't expanded when present in a section title. +- \indexnofonts +- \turnoffactive +- \makevalueexpandable +- \def\pdfdestname{#1}% +- \txiescapepdf\pdfdestname +- \safewhatsit{\pdfdest name{\pdfdestname} xyz}% +- }} +- % +- % used to mark target names; must be expandable. +- \def\pdfmkpgn#1{#1} +- % +- % by default, use black for everything. +- \def\urlcolor{\rgbBlack} +- \def\linkcolor{\rgbBlack} +- \def\endlink{\setcolor{\maincolor}\pdfendlink} +- % +- % Adding outlines to PDF; macros for calculating structure of outlines +- % come from Petr Olsak +- \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% +- \else \csname#1\endcsname \fi} +- \def\advancenumber#1{\tempnum=\expnumber{#1}\relax +- \advance\tempnum by 1 +- \expandafter\xdef\csname#1\endcsname{\the\tempnum}} +- % +- % #1 is the section text, which is what will be displayed in the +- % outline by the pdf viewer. #2 is the pdf expression for the number +- % of subentries (or empty, for subsubsections). #3 is the node text, +- % which might be empty if this toc entry had no corresponding node. +- % #4 is the page number +- % +- \def\dopdfoutline#1#2#3#4{% +- % Generate a link to the node text if that exists; else, use the +- % page number. We could generate a destination for the section +- % text in the case where a section has no node, but it doesn't +- % seem worth the trouble, since most documents are normally structured. +- \edef\pdfoutlinedest{#3}% +- \ifx\pdfoutlinedest\empty +- \def\pdfoutlinedest{#4}% +- \else +- \txiescapepdf\pdfoutlinedest +- \fi +- % +- % Also escape PDF chars in the display string. +- \edef\pdfoutlinetext{#1}% +- \txiescapepdf\pdfoutlinetext +- % +- \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}% +- } +- % +- \def\pdfmakeoutlines{% +- \begingroup +- % Read toc silently, to get counts of subentries for \pdfoutline. +- \def\partentry##1##2##3##4{}% ignore parts in the outlines +- \def\numchapentry##1##2##3##4{% +- \def\thischapnum{##2}% +- \def\thissecnum{0}% +- \def\thissubsecnum{0}% +- }% +- \def\numsecentry##1##2##3##4{% +- \advancenumber{chap\thischapnum}% +- \def\thissecnum{##2}% +- \def\thissubsecnum{0}% +- }% +- \def\numsubsecentry##1##2##3##4{% +- \advancenumber{sec\thissecnum}% +- \def\thissubsecnum{##2}% +- }% +- \def\numsubsubsecentry##1##2##3##4{% +- \advancenumber{subsec\thissubsecnum}% +- }% +- \def\thischapnum{0}% +- \def\thissecnum{0}% +- \def\thissubsecnum{0}% +- % +- % use \def rather than \let here because we redefine \chapentry et +- % al. a second time, below. +- \def\appentry{\numchapentry}% +- \def\appsecentry{\numsecentry}% +- \def\appsubsecentry{\numsubsecentry}% +- \def\appsubsubsecentry{\numsubsubsecentry}% +- \def\unnchapentry{\numchapentry}% +- \def\unnsecentry{\numsecentry}% +- \def\unnsubsecentry{\numsubsecentry}% +- \def\unnsubsubsecentry{\numsubsubsecentry}% +- \readdatafile{toc}% +- % +- % Read toc second time, this time actually producing the outlines. +- % The `-' means take the \expnumber as the absolute number of +- % subentries, which we calculated on our first read of the .toc above. +- % +- % We use the node names as the destinations. +- \def\numchapentry##1##2##3##4{% +- \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% +- \def\numsecentry##1##2##3##4{% +- \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% +- \def\numsubsecentry##1##2##3##4{% +- \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% +- \def\numsubsubsecentry##1##2##3##4{% count is always zero +- \dopdfoutline{##1}{}{##3}{##4}}% +- % +- % PDF outlines are displayed using system fonts, instead of +- % document fonts. Therefore we cannot use special characters, +- % since the encoding is unknown. For example, the eogonek from +- % Latin 2 (0xea) gets translated to a | character. Info from +- % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. +- % +- % TODO this right, we have to translate 8-bit characters to +- % their "best" equivalent, based on the @documentencoding. Too +- % much work for too little return. Just use the ASCII equivalents +- % we use for the index sort strings. +- % +- \indexnofonts +- \setupdatafile +- % We can have normal brace characters in the PDF outlines, unlike +- % Texinfo index files. So set that up. +- \def\{{\lbracecharliteral}% +- \def\}{\rbracecharliteral}% +- \catcode`\\=\active \otherbackslash +- \input \tocreadfilename +- \endgroup +- } +- {\catcode`[=1 \catcode`]=2 +- \catcode`{=\other \catcode`}=\other +- \gdef\lbracecharliteral[{]% +- \gdef\rbracecharliteral[}]% +- ] +- % +- \def\skipspaces#1{\def\PP{#1}\def\D{|}% +- \ifx\PP\D\let\nextsp\relax +- \else\let\nextsp\skipspaces +- \addtokens{\filename}{\PP}% +- \advance\filenamelength by 1 +- \fi +- \nextsp} +- \def\getfilename#1{% +- \filenamelength=0 +- % If we don't expand the argument now, \skipspaces will get +- % snagged on things like "@value{foo}". +- \edef\temp{#1}% +- \expandafter\skipspaces\temp|\relax +- } +- \ifnum\pdftexversion < 14 +- \let \startlink \pdfannotlink +- \else +- \let \startlink \pdfstartlink +- \fi +- % make a live url in pdf output. +- \def\pdfurl#1{% +- \begingroup +- % it seems we really need yet another set of dummies; have not +- % tried to figure out what each command should do in the context +- % of @url. for now, just make @/ a no-op, that's the only one +- % people have actually reported a problem with. +- % +- \normalturnoffactive +- \def\@{@}% +- \let\/=\empty +- \makevalueexpandable +- % do we want to go so far as to use \indexnofonts instead of just +- % special-casing \var here? +- \def\var##1{##1}% +- % +- \leavevmode\setcolor{\urlcolor}% +- \startlink attr{/Border [0 0 0]}% +- user{/Subtype /Link /A << /S /URI /URI (#1) >>}% +- \endgroup} +- \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} +- \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} +- \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} +- \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} +- \def\maketoks{% +- \expandafter\poptoks\the\toksA|ENDTOKS|\relax +- \ifx\first0\adn0 +- \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 +- \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 +- \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 +- \else +- \ifnum0=\countA\else\makelink\fi +- \ifx\first.\let\next=\done\else +- \let\next=\maketoks +- \addtokens{\toksB}{\the\toksD} +- \ifx\first,\addtokens{\toksB}{\space}\fi +- \fi +- \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi +- \next} +- \def\makelink{\addtokens{\toksB}% +- {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} +- \def\pdflink#1{% +- \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} +- \setcolor{\linkcolor}#1\endlink} +- \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +-\else +- % non-pdf mode +- \let\pdfmkdest = \gobble +- \let\pdfurl = \gobble +- \let\endlink = \relax +- \let\setcolor = \gobble +- \let\pdfsetcolor = \gobble +- \let\pdfmakeoutlines = \relax +-\fi % \ifx\pdfoutput +- +- +-\message{fonts,} +- +-% Change the current font style to #1, remembering it in \curfontstyle. +-% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in +-% italics, not bold italics. +-% +-\def\setfontstyle#1{% +- \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. +- \csname ten#1\endcsname % change the current font +-} +- +-% Select #1 fonts with the current style. +-% +-\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname} +- +-\def\rm{\fam=0 \setfontstyle{rm}} +-\def\it{\fam=\itfam \setfontstyle{it}} +-\def\sl{\fam=\slfam \setfontstyle{sl}} +-\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} +-\def\tt{\fam=\ttfam \setfontstyle{tt}} +- +-% Unfortunately, we have to override this for titles and the like, since +-% in those cases "rm" is bold. Sigh. +-\def\rmisbold{\rm\def\curfontstyle{bf}} +- +-% Texinfo sort of supports the sans serif font style, which plain TeX does not. +-% So we set up a \sf. +-\newfam\sffam +-\def\sf{\fam=\sffam \setfontstyle{sf}} +-\let\li = \sf % Sometimes we call it \li, not \sf. +- +-% We don't need math for this font style. +-\def\ttsl{\setfontstyle{ttsl}} +- +- +-% Set the baselineskip to #1, and the lineskip and strut size +-% correspondingly. There is no deep meaning behind these magic numbers +-% used as factors; they just match (closely enough) what Knuth defined. +-% +-\def\lineskipfactor{.08333} +-\def\strutheightpercent{.70833} +-\def\strutdepthpercent {.29167} +-% +-% can get a sort of poor man's double spacing by redefining this. +-\def\baselinefactor{1} +-% +-\newdimen\textleading +-\def\setleading#1{% +- \dimen0 = #1\relax +- \normalbaselineskip = \baselinefactor\dimen0 +- \normallineskip = \lineskipfactor\normalbaselineskip +- \normalbaselines +- \setbox\strutbox =\hbox{% +- \vrule width0pt height\strutheightpercent\baselineskip +- depth \strutdepthpercent \baselineskip +- }% +-} +- +-% PDF CMaps. See also LaTeX's t1.cmap. +-% +-% do nothing with this by default. +-\expandafter\let\csname cmapOT1\endcsname\gobble +-\expandafter\let\csname cmapOT1IT\endcsname\gobble +-\expandafter\let\csname cmapOT1TT\endcsname\gobble +- +-% if we are producing pdf, and we have \pdffontattr, then define cmaps. +-% (\pdffontattr was introduced many years ago, but people still run +-% older pdftex's; it's easy to conditionalize, so we do.) +-\ifpdf \ifx\pdffontattr\thisisundefined \else +- \begingroup +- \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. +- \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +-%%DocumentNeededResources: ProcSet (CIDInit) +-%%IncludeResource: ProcSet (CIDInit) +-%%BeginResource: CMap (TeX-OT1-0) +-%%Title: (TeX-OT1-0 TeX OT1 0) +-%%Version: 1.000 +-%%EndComments +-/CIDInit /ProcSet findresource begin +-12 dict begin +-begincmap +-/CIDSystemInfo +-<< /Registry (TeX) +-/Ordering (OT1) +-/Supplement 0 +->> def +-/CMapName /TeX-OT1-0 def +-/CMapType 2 def +-1 begincodespacerange +-<00> <7F> +-endcodespacerange +-8 beginbfrange +-<00> <01> <0393> +-<09> <0A> <03A8> +-<23> <26> <0023> +-<28> <3B> <0028> +-<3F> <5B> <003F> +-<5D> <5E> <005D> +-<61> <7A> <0061> +-<7B> <7C> <2013> +-endbfrange +-40 beginbfchar +-<02> <0398> +-<03> <039B> +-<04> <039E> +-<05> <03A0> +-<06> <03A3> +-<07> <03D2> +-<08> <03A6> +-<0B> <00660066> +-<0C> <00660069> +-<0D> <0066006C> +-<0E> <006600660069> +-<0F> <00660066006C> +-<10> <0131> +-<11> <0237> +-<12> <0060> +-<13> <00B4> +-<14> <02C7> +-<15> <02D8> +-<16> <00AF> +-<17> <02DA> +-<18> <00B8> +-<19> <00DF> +-<1A> <00E6> +-<1B> <0153> +-<1C> <00F8> +-<1D> <00C6> +-<1E> <0152> +-<1F> <00D8> +-<21> <0021> +-<22> <201D> +-<27> <2019> +-<3C> <00A1> +-<3D> <003D> +-<3E> <00BF> +-<5C> <201C> +-<5F> <02D9> +-<60> <2018> +-<7D> <02DD> +-<7E> <007E> +-<7F> <00A8> +-endbfchar +-endcmap +-CMapName currentdict /CMap defineresource pop +-end +-end +-%%EndResource +-%%EOF +- }\endgroup +- \expandafter\edef\csname cmapOT1\endcsname#1{% +- \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% +- }% +-% +-% \cmapOT1IT +- \begingroup +- \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. +- \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +-%%DocumentNeededResources: ProcSet (CIDInit) +-%%IncludeResource: ProcSet (CIDInit) +-%%BeginResource: CMap (TeX-OT1IT-0) +-%%Title: (TeX-OT1IT-0 TeX OT1IT 0) +-%%Version: 1.000 +-%%EndComments +-/CIDInit /ProcSet findresource begin +-12 dict begin +-begincmap +-/CIDSystemInfo +-<< /Registry (TeX) +-/Ordering (OT1IT) +-/Supplement 0 +->> def +-/CMapName /TeX-OT1IT-0 def +-/CMapType 2 def +-1 begincodespacerange +-<00> <7F> +-endcodespacerange +-8 beginbfrange +-<00> <01> <0393> +-<09> <0A> <03A8> +-<25> <26> <0025> +-<28> <3B> <0028> +-<3F> <5B> <003F> +-<5D> <5E> <005D> +-<61> <7A> <0061> +-<7B> <7C> <2013> +-endbfrange +-42 beginbfchar +-<02> <0398> +-<03> <039B> +-<04> <039E> +-<05> <03A0> +-<06> <03A3> +-<07> <03D2> +-<08> <03A6> +-<0B> <00660066> +-<0C> <00660069> +-<0D> <0066006C> +-<0E> <006600660069> +-<0F> <00660066006C> +-<10> <0131> +-<11> <0237> +-<12> <0060> +-<13> <00B4> +-<14> <02C7> +-<15> <02D8> +-<16> <00AF> +-<17> <02DA> +-<18> <00B8> +-<19> <00DF> +-<1A> <00E6> +-<1B> <0153> +-<1C> <00F8> +-<1D> <00C6> +-<1E> <0152> +-<1F> <00D8> +-<21> <0021> +-<22> <201D> +-<23> <0023> +-<24> <00A3> +-<27> <2019> +-<3C> <00A1> +-<3D> <003D> +-<3E> <00BF> +-<5C> <201C> +-<5F> <02D9> +-<60> <2018> +-<7D> <02DD> +-<7E> <007E> +-<7F> <00A8> +-endbfchar +-endcmap +-CMapName currentdict /CMap defineresource pop +-end +-end +-%%EndResource +-%%EOF +- }\endgroup +- \expandafter\edef\csname cmapOT1IT\endcsname#1{% +- \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% +- }% +-% +-% \cmapOT1TT +- \begingroup +- \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. +- \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +-%%DocumentNeededResources: ProcSet (CIDInit) +-%%IncludeResource: ProcSet (CIDInit) +-%%BeginResource: CMap (TeX-OT1TT-0) +-%%Title: (TeX-OT1TT-0 TeX OT1TT 0) +-%%Version: 1.000 +-%%EndComments +-/CIDInit /ProcSet findresource begin +-12 dict begin +-begincmap +-/CIDSystemInfo +-<< /Registry (TeX) +-/Ordering (OT1TT) +-/Supplement 0 +->> def +-/CMapName /TeX-OT1TT-0 def +-/CMapType 2 def +-1 begincodespacerange +-<00> <7F> +-endcodespacerange +-5 beginbfrange +-<00> <01> <0393> +-<09> <0A> <03A8> +-<21> <26> <0021> +-<28> <5F> <0028> +-<61> <7E> <0061> +-endbfrange +-32 beginbfchar +-<02> <0398> +-<03> <039B> +-<04> <039E> +-<05> <03A0> +-<06> <03A3> +-<07> <03D2> +-<08> <03A6> +-<0B> <2191> +-<0C> <2193> +-<0D> <0027> +-<0E> <00A1> +-<0F> <00BF> +-<10> <0131> +-<11> <0237> +-<12> <0060> +-<13> <00B4> +-<14> <02C7> +-<15> <02D8> +-<16> <00AF> +-<17> <02DA> +-<18> <00B8> +-<19> <00DF> +-<1A> <00E6> +-<1B> <0153> +-<1C> <00F8> +-<1D> <00C6> +-<1E> <0152> +-<1F> <00D8> +-<20> <2423> +-<27> <2019> +-<60> <2018> +-<7F> <00A8> +-endbfchar +-endcmap +-CMapName currentdict /CMap defineresource pop +-end +-end +-%%EndResource +-%%EOF +- }\endgroup +- \expandafter\edef\csname cmapOT1TT\endcsname#1{% +- \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% +- }% +-\fi\fi +- +- +-% Set the font macro #1 to the font named \fontprefix#2. +-% #3 is the font's design size, #4 is a scale factor, #5 is the CMap +-% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). +-% Example: +-% #1 = \textrm +-% #2 = \rmshape +-% #3 = 10 +-% #4 = \mainmagstep +-% #5 = OT1 +-% +-\def\setfont#1#2#3#4#5{% +- \font#1=\fontprefix#2#3 scaled #4 +- \csname cmap#5\endcsname#1% +-} +-% This is what gets called when #5 of \setfont is empty. +-\let\cmap\gobble +-% +-% (end of cmaps) +- +-% Use cm as the default font prefix. +-% To specify the font prefix, you must define \fontprefix +-% before you read in texinfo.tex. +-\ifx\fontprefix\thisisundefined +-\def\fontprefix{cm} +-\fi +-% Support font families that don't use the same naming scheme as CM. +-\def\rmshape{r} +-\def\rmbshape{bx} % where the normal face is bold +-\def\bfshape{b} +-\def\bxshape{bx} +-\def\ttshape{tt} +-\def\ttbshape{tt} +-\def\ttslshape{sltt} +-\def\itshape{ti} +-\def\itbshape{bxti} +-\def\slshape{sl} +-\def\slbshape{bxsl} +-\def\sfshape{ss} +-\def\sfbshape{ss} +-\def\scshape{csc} +-\def\scbshape{csc} +- +-% Definitions for a main text size of 11pt. (The default in Texinfo.) +-% +-\def\definetextfontsizexi{% +-% Text fonts (11.2pt, magstep1). +-\def\textnominalsize{11pt} +-\edef\mainmagstep{\magstephalf} +-\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +-\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +-\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +-\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +-\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +-\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +-\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +-\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +-\font\texti=cmmi10 scaled \mainmagstep +-\font\textsy=cmsy10 scaled \mainmagstep +-\def\textecsize{1095} +- +-% A few fonts for @defun names and args. +-\setfont\defbf\bfshape{10}{\magstep1}{OT1} +-\setfont\deftt\ttshape{10}{\magstep1}{OT1TT} +-\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} +-\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} +- +-% Fonts for indices, footnotes, small examples (9pt). +-\def\smallnominalsize{9pt} +-\setfont\smallrm\rmshape{9}{1000}{OT1} +-\setfont\smalltt\ttshape{9}{1000}{OT1TT} +-\setfont\smallbf\bfshape{10}{900}{OT1} +-\setfont\smallit\itshape{9}{1000}{OT1IT} +-\setfont\smallsl\slshape{9}{1000}{OT1} +-\setfont\smallsf\sfshape{9}{1000}{OT1} +-\setfont\smallsc\scshape{10}{900}{OT1} +-\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +-\font\smalli=cmmi9 +-\font\smallsy=cmsy9 +-\def\smallecsize{0900} +- +-% Fonts for small examples (8pt). +-\def\smallernominalsize{8pt} +-\setfont\smallerrm\rmshape{8}{1000}{OT1} +-\setfont\smallertt\ttshape{8}{1000}{OT1TT} +-\setfont\smallerbf\bfshape{10}{800}{OT1} +-\setfont\smallerit\itshape{8}{1000}{OT1IT} +-\setfont\smallersl\slshape{8}{1000}{OT1} +-\setfont\smallersf\sfshape{8}{1000}{OT1} +-\setfont\smallersc\scshape{10}{800}{OT1} +-\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +-\font\smalleri=cmmi8 +-\font\smallersy=cmsy8 +-\def\smallerecsize{0800} +- +-% Fonts for title page (20.4pt): +-\def\titlenominalsize{20pt} +-\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +-\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +-\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +-\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +-\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +-\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +-\let\titlebf=\titlerm +-\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +-\font\titlei=cmmi12 scaled \magstep3 +-\font\titlesy=cmsy10 scaled \magstep4 +-\def\titleecsize{2074} +- +-% Chapter (and unnumbered) fonts (17.28pt). +-\def\chapnominalsize{17pt} +-\setfont\chaprm\rmbshape{12}{\magstep2}{OT1} +-\setfont\chapit\itbshape{10}{\magstep3}{OT1IT} +-\setfont\chapsl\slbshape{10}{\magstep3}{OT1} +-\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} +-\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} +-\setfont\chapsf\sfbshape{17}{1000}{OT1} +-\let\chapbf=\chaprm +-\setfont\chapsc\scbshape{10}{\magstep3}{OT1} +-\font\chapi=cmmi12 scaled \magstep2 +-\font\chapsy=cmsy10 scaled \magstep3 +-\def\chapecsize{1728} +- +-% Section fonts (14.4pt). +-\def\secnominalsize{14pt} +-\setfont\secrm\rmbshape{12}{\magstep1}{OT1} +-\setfont\secit\itbshape{10}{\magstep2}{OT1IT} +-\setfont\secsl\slbshape{10}{\magstep2}{OT1} +-\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} +-\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} +-\setfont\secsf\sfbshape{12}{\magstep1}{OT1} +-\let\secbf\secrm +-\setfont\secsc\scbshape{10}{\magstep2}{OT1} +-\font\seci=cmmi12 scaled \magstep1 +-\font\secsy=cmsy10 scaled \magstep2 +-\def\sececsize{1440} +- +-% Subsection fonts (13.15pt). +-\def\ssecnominalsize{13pt} +-\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} +-\setfont\ssecit\itbshape{10}{1315}{OT1IT} +-\setfont\ssecsl\slbshape{10}{1315}{OT1} +-\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} +-\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} +-\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} +-\let\ssecbf\ssecrm +-\setfont\ssecsc\scbshape{10}{1315}{OT1} +-\font\sseci=cmmi12 scaled \magstephalf +-\font\ssecsy=cmsy10 scaled 1315 +-\def\ssececsize{1200} +- +-% Reduced fonts for @acro in text (10pt). +-\def\reducednominalsize{10pt} +-\setfont\reducedrm\rmshape{10}{1000}{OT1} +-\setfont\reducedtt\ttshape{10}{1000}{OT1TT} +-\setfont\reducedbf\bfshape{10}{1000}{OT1} +-\setfont\reducedit\itshape{10}{1000}{OT1IT} +-\setfont\reducedsl\slshape{10}{1000}{OT1} +-\setfont\reducedsf\sfshape{10}{1000}{OT1} +-\setfont\reducedsc\scshape{10}{1000}{OT1} +-\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} +-\font\reducedi=cmmi10 +-\font\reducedsy=cmsy10 +-\def\reducedecsize{1000} +- +-\textleading = 13.2pt % line spacing for 11pt CM +-\textfonts % reset the current fonts +-\rm +-} % end of 11pt text font size definitions, \definetextfontsizexi +- +- +-% Definitions to make the main text be 10pt Computer Modern, with +-% section, chapter, etc., sizes following suit. This is for the GNU +-% Press printing of the Emacs 22 manual. Maybe other manuals in the +-% future. Used with @smallbook, which sets the leading to 12pt. +-% +-\def\definetextfontsizex{% +-% Text fonts (10pt). +-\def\textnominalsize{10pt} +-\edef\mainmagstep{1000} +-\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +-\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +-\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +-\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +-\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +-\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +-\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +-\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +-\font\texti=cmmi10 scaled \mainmagstep +-\font\textsy=cmsy10 scaled \mainmagstep +-\def\textecsize{1000} +- +-% A few fonts for @defun names and args. +-\setfont\defbf\bfshape{10}{\magstephalf}{OT1} +-\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} +-\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} +-\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf} +- +-% Fonts for indices, footnotes, small examples (9pt). +-\def\smallnominalsize{9pt} +-\setfont\smallrm\rmshape{9}{1000}{OT1} +-\setfont\smalltt\ttshape{9}{1000}{OT1TT} +-\setfont\smallbf\bfshape{10}{900}{OT1} +-\setfont\smallit\itshape{9}{1000}{OT1IT} +-\setfont\smallsl\slshape{9}{1000}{OT1} +-\setfont\smallsf\sfshape{9}{1000}{OT1} +-\setfont\smallsc\scshape{10}{900}{OT1} +-\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +-\font\smalli=cmmi9 +-\font\smallsy=cmsy9 +-\def\smallecsize{0900} +- +-% Fonts for small examples (8pt). +-\def\smallernominalsize{8pt} +-\setfont\smallerrm\rmshape{8}{1000}{OT1} +-\setfont\smallertt\ttshape{8}{1000}{OT1TT} +-\setfont\smallerbf\bfshape{10}{800}{OT1} +-\setfont\smallerit\itshape{8}{1000}{OT1IT} +-\setfont\smallersl\slshape{8}{1000}{OT1} +-\setfont\smallersf\sfshape{8}{1000}{OT1} +-\setfont\smallersc\scshape{10}{800}{OT1} +-\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +-\font\smalleri=cmmi8 +-\font\smallersy=cmsy8 +-\def\smallerecsize{0800} +- +-% Fonts for title page (20.4pt): +-\def\titlenominalsize{20pt} +-\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +-\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +-\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +-\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +-\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +-\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +-\let\titlebf=\titlerm +-\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +-\font\titlei=cmmi12 scaled \magstep3 +-\font\titlesy=cmsy10 scaled \magstep4 +-\def\titleecsize{2074} +- +-% Chapter fonts (14.4pt). +-\def\chapnominalsize{14pt} +-\setfont\chaprm\rmbshape{12}{\magstep1}{OT1} +-\setfont\chapit\itbshape{10}{\magstep2}{OT1IT} +-\setfont\chapsl\slbshape{10}{\magstep2}{OT1} +-\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} +-\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} +-\setfont\chapsf\sfbshape{12}{\magstep1}{OT1} +-\let\chapbf\chaprm +-\setfont\chapsc\scbshape{10}{\magstep2}{OT1} +-\font\chapi=cmmi12 scaled \magstep1 +-\font\chapsy=cmsy10 scaled \magstep2 +-\def\chapecsize{1440} +- +-% Section fonts (12pt). +-\def\secnominalsize{12pt} +-\setfont\secrm\rmbshape{12}{1000}{OT1} +-\setfont\secit\itbshape{10}{\magstep1}{OT1IT} +-\setfont\secsl\slbshape{10}{\magstep1}{OT1} +-\setfont\sectt\ttbshape{12}{1000}{OT1TT} +-\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} +-\setfont\secsf\sfbshape{12}{1000}{OT1} +-\let\secbf\secrm +-\setfont\secsc\scbshape{10}{\magstep1}{OT1} +-\font\seci=cmmi12 +-\font\secsy=cmsy10 scaled \magstep1 +-\def\sececsize{1200} +- +-% Subsection fonts (10pt). +-\def\ssecnominalsize{10pt} +-\setfont\ssecrm\rmbshape{10}{1000}{OT1} +-\setfont\ssecit\itbshape{10}{1000}{OT1IT} +-\setfont\ssecsl\slbshape{10}{1000}{OT1} +-\setfont\ssectt\ttbshape{10}{1000}{OT1TT} +-\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} +-\setfont\ssecsf\sfbshape{10}{1000}{OT1} +-\let\ssecbf\ssecrm +-\setfont\ssecsc\scbshape{10}{1000}{OT1} +-\font\sseci=cmmi10 +-\font\ssecsy=cmsy10 +-\def\ssececsize{1000} +- +-% Reduced fonts for @acro in text (9pt). +-\def\reducednominalsize{9pt} +-\setfont\reducedrm\rmshape{9}{1000}{OT1} +-\setfont\reducedtt\ttshape{9}{1000}{OT1TT} +-\setfont\reducedbf\bfshape{10}{900}{OT1} +-\setfont\reducedit\itshape{9}{1000}{OT1IT} +-\setfont\reducedsl\slshape{9}{1000}{OT1} +-\setfont\reducedsf\sfshape{9}{1000}{OT1} +-\setfont\reducedsc\scshape{10}{900}{OT1} +-\setfont\reducedttsl\ttslshape{10}{900}{OT1TT} +-\font\reducedi=cmmi9 +-\font\reducedsy=cmsy9 +-\def\reducedecsize{0900} +- +-\divide\parskip by 2 % reduce space between paragraphs +-\textleading = 12pt % line spacing for 10pt CM +-\textfonts % reset the current fonts +-\rm +-} % end of 10pt text font size definitions, \definetextfontsizex +- +- +-% We provide the user-level command +-% @fonttextsize 10 +-% (or 11) to redefine the text font size. pt is assumed. +-% +-\def\xiword{11} +-\def\xword{10} +-\def\xwordpt{10pt} +-% +-\parseargdef\fonttextsize{% +- \def\textsizearg{#1}% +- %\wlog{doing @fonttextsize \textsizearg}% +- % +- % Set \globaldefs so that documents can use this inside @tex, since +- % makeinfo 4.8 does not support it, but we need it nonetheless. +- % +- \begingroup \globaldefs=1 +- \ifx\textsizearg\xword \definetextfontsizex +- \else \ifx\textsizearg\xiword \definetextfontsizexi +- \else +- \errhelp=\EMsimple +- \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} +- \fi\fi +- \endgroup +-} +- +- +-% In order for the font changes to affect most math symbols and letters, +-% we have to define the \textfont of the standard families. Since +-% texinfo doesn't allow for producing subscripts and superscripts except +-% in the main text, we don't bother to reset \scriptfont and +-% \scriptscriptfont (which would also require loading a lot more fonts). +-% +-\def\resetmathfonts{% +- \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy +- \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf +- \textfont\ttfam=\tentt \textfont\sffam=\tensf +-} +- +-% The font-changing commands redefine the meanings of \tenSTYLE, instead +-% of just \STYLE. We do this because \STYLE needs to also set the +-% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire +-% \tenSTYLE to set the current font. +-% +-% Each font-changing command also sets the names \lsize (one size lower) +-% and \lllsize (three sizes lower). These relative commands are used in +-% the LaTeX logo and acronyms. +-% +-% This all needs generalizing, badly. +-% +-\def\textfonts{% +- \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl +- \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc +- \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy +- \let\tenttsl=\textttsl +- \def\curfontsize{text}% +- \def\lsize{reduced}\def\lllsize{smaller}% +- \resetmathfonts \setleading{\textleading}} +-\def\titlefonts{% +- \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl +- \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc +- \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy +- \let\tenttsl=\titlettsl +- \def\curfontsize{title}% +- \def\lsize{chap}\def\lllsize{subsec}% +- \resetmathfonts \setleading{27pt}} +-\def\titlefont#1{{\titlefonts\rmisbold #1}} +-\def\chapfonts{% +- \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl +- \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc +- \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy +- \let\tenttsl=\chapttsl +- \def\curfontsize{chap}% +- \def\lsize{sec}\def\lllsize{text}% +- \resetmathfonts \setleading{19pt}} +-\def\secfonts{% +- \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl +- \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc +- \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy +- \let\tenttsl=\secttsl +- \def\curfontsize{sec}% +- \def\lsize{subsec}\def\lllsize{reduced}% +- \resetmathfonts \setleading{17pt}} +-\def\subsecfonts{% +- \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl +- \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc +- \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy +- \let\tenttsl=\ssecttsl +- \def\curfontsize{ssec}% +- \def\lsize{text}\def\lllsize{small}% +- \resetmathfonts \setleading{15pt}} +-\let\subsubsecfonts = \subsecfonts +-\def\reducedfonts{% +- \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl +- \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc +- \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy +- \let\tenttsl=\reducedttsl +- \def\curfontsize{reduced}% +- \def\lsize{small}\def\lllsize{smaller}% +- \resetmathfonts \setleading{10.5pt}} +-\def\smallfonts{% +- \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl +- \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc +- \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy +- \let\tenttsl=\smallttsl +- \def\curfontsize{small}% +- \def\lsize{smaller}\def\lllsize{smaller}% +- \resetmathfonts \setleading{10.5pt}} +-\def\smallerfonts{% +- \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl +- \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc +- \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy +- \let\tenttsl=\smallerttsl +- \def\curfontsize{smaller}% +- \def\lsize{smaller}\def\lllsize{smaller}% +- \resetmathfonts \setleading{9.5pt}} +- +-% Fonts for short table of contents. +-\setfont\shortcontrm\rmshape{12}{1000}{OT1} +-\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +-\setfont\shortcontsl\slshape{12}{1000}{OT1} +-\setfont\shortconttt\ttshape{12}{1000}{OT1TT} +- +-% Define these just so they can be easily changed for other fonts. +-\def\angleleft{$\langle$} +-\def\angleright{$\rangle$} +- +-% Set the fonts to use with the @small... environments. +-\let\smallexamplefonts = \smallfonts +- +-% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample +-% can fit this many characters: +-% 8.5x11=86 smallbook=72 a4=90 a5=69 +-% If we use \scriptfonts (8pt), then we can fit this many characters: +-% 8.5x11=90+ smallbook=80 a4=90+ a5=77 +-% For me, subjectively, the few extra characters that fit aren't worth +-% the additional smallness of 8pt. So I'm making the default 9pt. +-% +-% By the way, for comparison, here's what fits with @example (10pt): +-% 8.5x11=71 smallbook=60 a4=75 a5=58 +-% --karl, 24jan03. +- +-% Set up the default fonts, so we can use them for creating boxes. +-% +-\definetextfontsizexi +- +- +-\message{markup,} +- +-% Check if we are currently using a typewriter font. Since all the +-% Computer Modern typewriter fonts have zero interword stretch (and +-% shrink), and it is reasonable to expect all typewriter fonts to have +-% this property, we can check that font parameter. +-% +-\def\ifmonospace{\ifdim\fontdimen3\font=0pt } +- +-% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will +-% define and register \INITMACRO to be called on markup style changes. +-% \INITMACRO can check \currentmarkupstyle for the innermost +-% style and the set of \ifmarkupSTYLE switches for all styles +-% currently in effect. +-\newif\ifmarkupvar +-\newif\ifmarkupsamp +-\newif\ifmarkupkey +-%\newif\ifmarkupfile % @file == @samp. +-%\newif\ifmarkupoption % @option == @samp. +-\newif\ifmarkupcode +-\newif\ifmarkupkbd +-%\newif\ifmarkupenv % @env == @code. +-%\newif\ifmarkupcommand % @command == @code. +-\newif\ifmarkuptex % @tex (and part of @math, for now). +-\newif\ifmarkupexample +-\newif\ifmarkupverb +-\newif\ifmarkupverbatim +- +-\let\currentmarkupstyle\empty +- +-\def\setupmarkupstyle#1{% +- \csname markup#1true\endcsname +- \def\currentmarkupstyle{#1}% +- \markupstylesetup +-} +- +-\let\markupstylesetup\empty +- +-\def\defmarkupstylesetup#1{% +- \expandafter\def\expandafter\markupstylesetup +- \expandafter{\markupstylesetup #1}% +- \def#1% +-} +- +-% Markup style setup for left and right quotes. +-\defmarkupstylesetup\markupsetuplq{% +- \expandafter\let\expandafter \temp +- \csname markupsetuplq\currentmarkupstyle\endcsname +- \ifx\temp\relax \markupsetuplqdefault \else \temp \fi +-} +- +-\defmarkupstylesetup\markupsetuprq{% +- \expandafter\let\expandafter \temp +- \csname markupsetuprq\currentmarkupstyle\endcsname +- \ifx\temp\relax \markupsetuprqdefault \else \temp \fi +-} +- +-{ +-\catcode`\'=\active +-\catcode`\`=\active +- +-\gdef\markupsetuplqdefault{\let`\lq} +-\gdef\markupsetuprqdefault{\let'\rq} +- +-\gdef\markupsetcodequoteleft{\let`\codequoteleft} +-\gdef\markupsetcodequoteright{\let'\codequoteright} +-} +- +-\let\markupsetuplqcode \markupsetcodequoteleft +-\let\markupsetuprqcode \markupsetcodequoteright +-% +-\let\markupsetuplqexample \markupsetcodequoteleft +-\let\markupsetuprqexample \markupsetcodequoteright +-% +-\let\markupsetuplqkbd \markupsetcodequoteleft +-\let\markupsetuprqkbd \markupsetcodequoteright +-% +-\let\markupsetuplqsamp \markupsetcodequoteleft +-\let\markupsetuprqsamp \markupsetcodequoteright +-% +-\let\markupsetuplqverb \markupsetcodequoteleft +-\let\markupsetuprqverb \markupsetcodequoteright +-% +-\let\markupsetuplqverbatim \markupsetcodequoteleft +-\let\markupsetuprqverbatim \markupsetcodequoteright +- +-% Allow an option to not use regular directed right quote/apostrophe +-% (char 0x27), but instead the undirected quote from cmtt (char 0x0d). +-% The undirected quote is ugly, so don't make it the default, but it +-% works for pasting with more pdf viewers (at least evince), the +-% lilypond developers report. xpdf does work with the regular 0x27. +-% +-\def\codequoteright{% +- \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax +- \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax +- '% +- \else \char'15 \fi +- \else \char'15 \fi +-} +-% +-% and a similar option for the left quote char vs. a grave accent. +-% Modern fonts display ASCII 0x60 as a grave accent, so some people like +-% the code environments to do likewise. +-% +-\def\codequoteleft{% +- \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax +- \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax +- % [Knuth] pp. 380,381,391 +- % \relax disables Spanish ligatures ?` and !` of \tt font. +- \relax`% +- \else \char'22 \fi +- \else \char'22 \fi +-} +- +-% Commands to set the quote options. +-% +-\parseargdef\codequoteundirected{% +- \def\temp{#1}% +- \ifx\temp\onword +- \expandafter\let\csname SETtxicodequoteundirected\endcsname +- = t% +- \else\ifx\temp\offword +- \expandafter\let\csname SETtxicodequoteundirected\endcsname +- = \relax +- \else +- \errhelp = \EMsimple +- \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% +- \fi\fi +-} +-% +-\parseargdef\codequotebacktick{% +- \def\temp{#1}% +- \ifx\temp\onword +- \expandafter\let\csname SETtxicodequotebacktick\endcsname +- = t% +- \else\ifx\temp\offword +- \expandafter\let\csname SETtxicodequotebacktick\endcsname +- = \relax +- \else +- \errhelp = \EMsimple +- \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% +- \fi\fi +-} +- +-% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. +-\def\noligaturesquoteleft{\relax\lq} +- +-% Count depth in font-changes, for error checks +-\newcount\fontdepth \fontdepth=0 +- +-% Font commands. +- +-% #1 is the font command (\sl or \it), #2 is the text to slant. +-% If we are in a monospaced environment, however, 1) always use \ttsl, +-% and 2) do not add an italic correction. +-\def\dosmartslant#1#2{% +- \ifusingtt +- {{\ttsl #2}\let\next=\relax}% +- {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% +- \next +-} +-\def\smartslanted{\dosmartslant\sl} +-\def\smartitalic{\dosmartslant\it} +- +-% Output an italic correction unless \next (presumed to be the following +-% character) is such as not to need one. +-\def\smartitaliccorrection{% +- \ifx\next,% +- \else\ifx\next-% +- \else\ifx\next.% +- \else\ifx\next\.% +- \else\ifx\next\comma% +- \else\ptexslash +- \fi\fi\fi\fi\fi +- \aftersmartic +-} +- +-% Unconditional use \ttsl, and no ic. @var is set to this for defuns. +-\def\ttslanted#1{{\ttsl #1}} +- +-% @cite is like \smartslanted except unconditionally use \sl. We never want +-% ttsl for book titles, do we? +-\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} +- +-\def\aftersmartic{} +-\def\var#1{% +- \let\saveaftersmartic = \aftersmartic +- \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% +- \smartslanted{#1}% +-} +- +-\let\i=\smartitalic +-\let\slanted=\smartslanted +-\let\dfn=\smartslanted +-\let\emph=\smartitalic +- +-% Explicit font changes: @r, @sc, undocumented @ii. +-\def\r#1{{\rm #1}} % roman font +-\def\sc#1{{\smallcaps#1}} % smallcaps font +-\def\ii#1{{\it #1}} % italic font +- +-% @b, explicit bold. Also @strong. +-\def\b#1{{\bf #1}} +-\let\strong=\b +- +-% @sansserif, explicit sans. +-\def\sansserif#1{{\sf #1}} +- +-% We can't just use \exhyphenpenalty, because that only has effect at +-% the end of a paragraph. Restore normal hyphenation at the end of the +-% group within which \nohyphenation is presumably called. +-% +-\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation} +-\def\restorehyphenation{\hyphenchar\font = `- } +- +-% Set sfcode to normal for the chars that usually have another value. +-% Can't use plain's \frenchspacing because it uses the `\x notation, and +-% sometimes \x has an active definition that messes things up. +-% +-\catcode`@=11 +- \def\plainfrenchspacing{% +- \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m +- \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m +- \def\endofsentencespacefactor{1000}% for @. and friends +- } +- \def\plainnonfrenchspacing{% +- \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 +- \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 +- \def\endofsentencespacefactor{3000}% for @. and friends +- } +-\catcode`@=\other +-\def\endofsentencespacefactor{3000}% default +- +-% @t, explicit typewriter. +-\def\t#1{% +- {\tt \rawbackslash \plainfrenchspacing #1}% +- \null +-} +- +-% @samp. +-\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} +- +-% @indicateurl is \samp, that is, with quotes. +-\let\indicateurl=\samp +- +-% @code (and similar) prints in typewriter, but with spaces the same +-% size as normal in the surrounding text, without hyphenation, etc. +-% This is a subroutine for that. +-\def\tclose#1{% +- {% +- % Change normal interword space to be same as for the current font. +- \spaceskip = \fontdimen2\font +- % +- % Switch to typewriter. +- \tt +- % +- % But `\ ' produces the large typewriter interword space. +- \def\ {{\spaceskip = 0pt{} }}% +- % +- % Turn off hyphenation. +- \nohyphenation +- % +- \rawbackslash +- \plainfrenchspacing +- #1% +- }% +- \null % reset spacefactor to 1000 +-} +- +-% We *must* turn on hyphenation at `-' and `_' in @code. +-% (But see \codedashfinish below.) +-% Otherwise, it is too hard to avoid overfull hboxes +-% in the Emacs manual, the Library manual, etc. +-% +-% Unfortunately, TeX uses one parameter (\hyphenchar) to control +-% both hyphenation at - and hyphenation within words. +-% We must therefore turn them both off (\tclose does that) +-% and arrange explicitly to hyphenate at a dash. -- rms. +-{ +- \catcode`\-=\active \catcode`\_=\active +- \catcode`\'=\active \catcode`\`=\active +- \global\let'=\rq \global\let`=\lq % default definitions +- % +- \global\def\code{\begingroup +- \setupmarkupstyle{code}% +- % The following should really be moved into \setupmarkupstyle handlers. +- \catcode\dashChar=\active \catcode\underChar=\active +- \ifallowcodebreaks +- \let-\codedash +- \let_\codeunder +- \else +- \let-\normaldash +- \let_\realunder +- \fi +- % Given -foo (with a single dash), we do not want to allow a break +- % after the hyphen. +- \global\let\codedashprev=\codedash +- % +- \codex +- } +- % +- \gdef\codedash{\futurelet\next\codedashfinish} +- \gdef\codedashfinish{% +- \normaldash % always output the dash character itself. +- % +- % Now, output a discretionary to allow a line break, unless +- % (a) the next character is a -, or +- % (b) the preceding character is a -. +- % E.g., given --posix, we do not want to allow a break after either -. +- % Given --foo-bar, we do want to allow a break between the - and the b. +- \ifx\next\codedash \else +- \ifx\codedashprev\codedash +- \else \discretionary{}{}{}\fi +- \fi +- % we need the space after the = for the case when \next itself is a +- % space token; it would get swallowed otherwise. As in @code{- a}. +- \global\let\codedashprev= \next +- } +-} +-\def\normaldash{-} +-% +-\def\codex #1{\tclose{#1}\endgroup} +- +-\def\codeunder{% +- % this is all so @math{@code{var_name}+1} can work. In math mode, _ +- % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) +- % will therefore expand the active definition of _, which is us +- % (inside @code that is), therefore an endless loop. +- \ifusingtt{\ifmmode +- \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. +- \else\normalunderscore \fi +- \discretionary{}{}{}}% +- {\_}% +-} +- +-% An additional complication: the above will allow breaks after, e.g., +-% each of the four underscores in __typeof__. This is bad. +-% @allowcodebreaks provides a document-level way to turn breaking at - +-% and _ on and off. +-% +-\newif\ifallowcodebreaks \allowcodebreakstrue +- +-\def\keywordtrue{true} +-\def\keywordfalse{false} +- +-\parseargdef\allowcodebreaks{% +- \def\txiarg{#1}% +- \ifx\txiarg\keywordtrue +- \allowcodebreakstrue +- \else\ifx\txiarg\keywordfalse +- \allowcodebreaksfalse +- \else +- \errhelp = \EMsimple +- \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% +- \fi\fi +-} +- +-% For @command, @env, @file, @option quotes seem unnecessary, +-% so use \code rather than \samp. +-\let\command=\code +-\let\env=\code +-\let\file=\code +-\let\option=\code +- +-% @uref (abbreviation for `urlref') aka @url takes an optional +-% (comma-separated) second argument specifying the text to display and +-% an optional third arg as text to display instead of (rather than in +-% addition to) the url itself. First (mandatory) arg is the url. +- +-% TeX-only option to allow changing PDF output to show only the second +-% arg (if given), and not the url (which is then just the link target). +-\newif\ifurefurlonlylink +- +-% The main macro is \urefbreak, which allows breaking at expected +-% places within the url. (There used to be another version, which +-% didn't support automatic breaking.) +-\def\urefbreak{\begingroup \urefcatcodes \dourefbreak} +-\let\uref=\urefbreak +-% +-\def\dourefbreak#1{\urefbreakfinish #1,,,\finish} +-\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example +- \unsepspaces +- \pdfurl{#1}% +- \setbox0 = \hbox{\ignorespaces #3}% +- \ifdim\wd0 > 0pt +- \unhbox0 % third arg given, show only that +- \else +- \setbox0 = \hbox{\ignorespaces #2}% look for second arg +- \ifdim\wd0 > 0pt +- \ifpdf +- \ifurefurlonlylink +- % PDF plus option to not display url, show just arg +- \unhbox0 +- \else +- % PDF, normally display both arg and url for consistency, +- % visibility, if the pdf is eventually used to print, etc. +- \unhbox0\ (\urefcode{#1})% +- \fi +- \else +- \unhbox0\ (\urefcode{#1})% DVI, always show arg and url +- \fi +- \else +- \urefcode{#1}% only url given, so show it +- \fi +- \fi +- \endlink +-\endgroup} +- +-% Allow line breaks around only a few characters (only). +-\def\urefcatcodes{% +- \catcode\ampChar=\active \catcode\dotChar=\active +- \catcode\hashChar=\active \catcode\questChar=\active +- \catcode\slashChar=\active +-} +-{ +- \urefcatcodes +- % +- \global\def\urefcode{\begingroup +- \setupmarkupstyle{code}% +- \urefcatcodes +- \let&\urefcodeamp +- \let.\urefcodedot +- \let#\urefcodehash +- \let?\urefcodequest +- \let/\urefcodeslash +- \codex +- } +- % +- % By default, they are just regular characters. +- \global\def&{\normalamp} +- \global\def.{\normaldot} +- \global\def#{\normalhash} +- \global\def?{\normalquest} +- \global\def/{\normalslash} +-} +- +-% we put a little stretch before and after the breakable chars, to help +-% line breaking of long url's. The unequal skips make look better in +-% cmtt at least, especially for dots. +-\def\urefprestretchamount{.13em} +-\def\urefpoststretchamount{.1em} +-\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax} +-\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax} +-% +-\def\urefcodeamp{\urefprestretch \&\urefpoststretch} +-\def\urefcodedot{\urefprestretch .\urefpoststretch} +-\def\urefcodehash{\urefprestretch \#\urefpoststretch} +-\def\urefcodequest{\urefprestretch ?\urefpoststretch} +-\def\urefcodeslash{\futurelet\next\urefcodeslashfinish} +-{ +- \catcode`\/=\active +- \global\def\urefcodeslashfinish{% +- \urefprestretch \slashChar +- % Allow line break only after the final / in a sequence of +- % slashes, to avoid line break between the slashes in http://. +- \ifx\next/\else \urefpoststretch \fi +- } +-} +- +-% One more complication: by default we'll break after the special +-% characters, but some people like to break before the special chars, so +-% allow that. Also allow no breaking at all, for manual control. +-% +-\parseargdef\urefbreakstyle{% +- \def\txiarg{#1}% +- \ifx\txiarg\wordnone +- \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} +- \else\ifx\txiarg\wordbefore +- \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} +- \else\ifx\txiarg\wordafter +- \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} +- \else +- \errhelp = \EMsimple +- \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% +- \fi\fi\fi +-} +-\def\wordafter{after} +-\def\wordbefore{before} +-\def\wordnone{none} +- +-\urefbreakstyle after +- +-% @url synonym for @uref, since that's how everyone uses it. +-% +-\let\url=\uref +- +-% rms does not like angle brackets --karl, 17may97. +-% So now @email is just like @uref, unless we are pdf. +-% +-%\def\email#1{\angleleft{\tt #1}\angleright} +-\ifpdf +- \def\email#1{\doemail#1,,\finish} +- \def\doemail#1,#2,#3\finish{\begingroup +- \unsepspaces +- \pdfurl{mailto:#1}% +- \setbox0 = \hbox{\ignorespaces #2}% +- \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi +- \endlink +- \endgroup} +-\else +- \let\email=\uref +-\fi +- +-% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +-% `example' (@kbd uses ttsl only inside of @example and friends), +-% or `code' (@kbd uses normal tty font always). +-\parseargdef\kbdinputstyle{% +- \def\txiarg{#1}% +- \ifx\txiarg\worddistinct +- \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% +- \else\ifx\txiarg\wordexample +- \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% +- \else\ifx\txiarg\wordcode +- \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% +- \else +- \errhelp = \EMsimple +- \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% +- \fi\fi\fi +-} +-\def\worddistinct{distinct} +-\def\wordexample{example} +-\def\wordcode{code} +- +-% Default is `distinct'. +-\kbdinputstyle distinct +- +-% @kbd is like @code, except that if the argument is just one @key command, +-% then @kbd has no effect. +-\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} +- +-\def\xkey{\key} +-\def\kbdsub#1#2#3\par{% +- \def\one{#1}\def\three{#3}\def\threex{??}% +- \ifx\one\xkey\ifx\threex\three \key{#2}% +- \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +- \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +-} +- +-% definition of @key that produces a lozenge. Doesn't adjust to text size. +-%\setfont\keyrm\rmshape{8}{1000}{OT1} +-%\font\keysy=cmsy9 +-%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +-% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +-% \vbox{\hrule\kern-0.4pt +-% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +-% \kern-0.4pt\hrule}% +-% \kern-.06em\raise0.4pt\hbox{\angleright}}}} +- +-% definition of @key with no lozenge. If the current font is already +-% monospace, don't change it; that way, we respect @kbdinputstyle. But +-% if it isn't monospace, then use \tt. +-% +-\def\key#1{{\setupmarkupstyle{key}% +- \nohyphenation +- \ifmonospace\else\tt\fi +- #1}\null} +- +-% @clicksequence{File @click{} Open ...} +-\def\clicksequence#1{\begingroup #1\endgroup} +- +-% @clickstyle @arrow (by default) +-\parseargdef\clickstyle{\def\click{#1}} +-\def\click{\arrow} +- +-% Typeset a dimension, e.g., `in' or `pt'. The only reason for the +-% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt. +-% +-\def\dmn#1{\thinspace #1} +- +-% @l was never documented to mean ``switch to the Lisp font'', +-% and it is not used as such in any manual I can find. We need it for +-% Polish suppressed-l. --karl, 22sep96. +-%\def\l#1{{\li #1}\null} +- +-% @acronym for "FBI", "NATO", and the like. +-% We print this one point size smaller, since it's intended for +-% all-uppercase. +-% +-\def\acronym#1{\doacronym #1,,\finish} +-\def\doacronym#1,#2,#3\finish{% +- {\selectfonts\lsize #1}% +- \def\temp{#2}% +- \ifx\temp\empty \else +- \space ({\unsepspaces \ignorespaces \temp \unskip})% +- \fi +- \null % reset \spacefactor=1000 +-} +- +-% @abbr for "Comput. J." and the like. +-% No font change, but don't do end-of-sentence spacing. +-% +-\def\abbr#1{\doabbr #1,,\finish} +-\def\doabbr#1,#2,#3\finish{% +- {\plainfrenchspacing #1}% +- \def\temp{#2}% +- \ifx\temp\empty \else +- \space ({\unsepspaces \ignorespaces \temp \unskip})% +- \fi +- \null % reset \spacefactor=1000 +-} +- +-% @asis just yields its argument. Used with @table, for example. +-% +-\def\asis#1{#1} +- +-% @math outputs its argument in math mode. +-% +-% One complication: _ usually means subscripts, but it could also mean +-% an actual _ character, as in @math{@var{some_variable} + 1}. So make +-% _ active, and distinguish by seeing if the current family is \slfam, +-% which is what @var uses. +-{ +- \catcode`\_ = \active +- \gdef\mathunderscore{% +- \catcode`\_=\active +- \def_{\ifnum\fam=\slfam \_\else\sb\fi}% +- } +-} +-% Another complication: we want \\ (and @\) to output a math (or tt) \. +-% FYI, plain.tex uses \\ as a temporary control sequence (for no +-% particular reason), but this is not advertised and we don't care. +-% +-% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +-\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +-% +-\def\math{% +- \tex +- \mathunderscore +- \let\\ = \mathbackslash +- \mathactive +- % make the texinfo accent commands work in math mode +- \let\"=\ddot +- \let\'=\acute +- \let\==\bar +- \let\^=\hat +- \let\`=\grave +- \let\u=\breve +- \let\v=\check +- \let\~=\tilde +- \let\dotaccent=\dot +- $\finishmath +-} +-\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. +- +-% Some active characters (such as <) are spaced differently in math. +-% We have to reset their definitions in case the @math was an argument +-% to a command which sets the catcodes (such as @item or @section). +-% +-{ +- \catcode`^ = \active +- \catcode`< = \active +- \catcode`> = \active +- \catcode`+ = \active +- \catcode`' = \active +- \gdef\mathactive{% +- \let^ = \ptexhat +- \let< = \ptexless +- \let> = \ptexgtr +- \let+ = \ptexplus +- \let' = \ptexquoteright +- } +-} +- +-% ctrl is no longer a Texinfo command, but leave this definition for fun. +-\def\ctrl #1{{\tt \rawbackslash \hat}#1} +- +-% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. +-% Ignore unless FMTNAME == tex; then it is like @iftex and @tex, +-% except specified as a normal braced arg, so no newlines to worry about. +-% +-\def\outfmtnametex{tex} +-% +-\long\def\inlinefmt#1{\doinlinefmt #1,\finish} +-\long\def\doinlinefmt#1,#2,\finish{% +- \def\inlinefmtname{#1}% +- \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi +-} +-% +-% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if +-% FMTNAME is tex, else ELSE-TEXT. +-\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish} +-\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{% +- \def\inlinefmtname{#1}% +- \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi +-} +-% +-% For raw, must switch into @tex before parsing the argument, to avoid +-% setting catcodes prematurely. Doing it this way means that, for +-% example, @inlineraw{html, foo{bar} gets a parse error instead of being +-% ignored. But this isn't important because if people want a literal +-% *right* brace they would have to use a command anyway, so they may as +-% well use a command to get a left brace too. We could re-use the +-% delimiter character idea from \verb, but it seems like overkill. +-% +-\long\def\inlineraw{\tex \doinlineraw} +-\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} +-\def\doinlinerawtwo#1,#2,\finish{% +- \def\inlinerawname{#1}% +- \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi +- \endgroup % close group opened by \tex. +-} +- +-% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set. +-% +-\long\def\inlineifset#1{\doinlineifset #1,\finish} +-\long\def\doinlineifset#1,#2,\finish{% +- \def\inlinevarname{#1}% +- \expandafter\ifx\csname SET\inlinevarname\endcsname\relax +- \else\ignorespaces#2\fi +-} +- +-% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set. +-% +-\long\def\inlineifclear#1{\doinlineifclear #1,\finish} +-\long\def\doinlineifclear#1,#2,\finish{% +- \def\inlinevarname{#1}% +- \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi +-} +- +- +-\message{glyphs,} +-% and logos. +- +-% @@ prints an @, as does @atchar{}. +-\def\@{\char64 } +-\let\atchar=\@ +- +-% @{ @} @lbracechar{} @rbracechar{} all generate brace characters. +-% Unless we're in typewriter, use \ecfont because the CM text fonts do +-% not have braces, and we don't want to switch into math. +-\def\mylbrace{{\ifmonospace\else\ecfont\fi \char123}} +-\def\myrbrace{{\ifmonospace\else\ecfont\fi \char125}} +-\let\{=\mylbrace \let\lbracechar=\{ +-\let\}=\myrbrace \let\rbracechar=\} +-\begingroup +- % Definitions to produce \{ and \} commands for indices, +- % and @{ and @} for the aux/toc files. +- \catcode`\{ = \other \catcode`\} = \other +- \catcode`\[ = 1 \catcode`\] = 2 +- \catcode`\! = 0 \catcode`\\ = \other +- !gdef!lbracecmd[\{]% +- !gdef!rbracecmd[\}]% +- !gdef!lbraceatcmd[@{]% +- !gdef!rbraceatcmd[@}]% +-!endgroup +- +-% @comma{} to avoid , parsing problems. +-\let\comma = , +- +-% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +-% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +-\let\, = \ptexc +-\let\dotaccent = \ptexdot +-\def\ringaccent#1{{\accent23 #1}} +-\let\tieaccent = \ptext +-\let\ubaraccent = \ptexb +-\let\udotaccent = \d +- +-% Other special characters: @questiondown @exclamdown @ordf @ordm +-% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +-\def\questiondown{?`} +-\def\exclamdown{!`} +-\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}} +-\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}} +- +-% Dotless i and dotless j, used for accents. +-\def\imacro{i} +-\def\jmacro{j} +-\def\dotless#1{% +- \def\temp{#1}% +- \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi +- \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi +- \else \errmessage{@dotless can be used only with i or j}% +- \fi\fi +-} +- +-% The \TeX{} logo, as in plain, but resetting the spacing so that a +-% period following counts as ending a sentence. (Idea found in latex.) +-% +-\edef\TeX{\TeX \spacefactor=1000 } +- +-% @LaTeX{} logo. Not quite the same results as the definition in +-% latex.ltx, since we use a different font for the raised A; it's most +-% convenient for us to use an explicitly smaller font, rather than using +-% the \scriptstyle font (since we don't reset \scriptstyle and +-% \scriptscriptstyle). +-% +-\def\LaTeX{% +- L\kern-.36em +- {\setbox0=\hbox{T}% +- \vbox to \ht0{\hbox{% +- \ifx\textnominalsize\xwordpt +- % for 10pt running text, \lllsize (8pt) is too small for the A in LaTeX. +- % Revert to plain's \scriptsize, which is 7pt. +- \count255=\the\fam $\fam\count255 \scriptstyle A$% +- \else +- % For 11pt, we can use our lllsize. +- \selectfonts\lllsize A% +- \fi +- }% +- \vss +- }}% +- \kern-.15em +- \TeX +-} +- +-% Some math mode symbols. +-\def\bullet{$\ptexbullet$} +-\def\geq{\ifmmode \ge\else $\ge$\fi} +-\def\leq{\ifmmode \le\else $\le$\fi} +-\def\minus{\ifmmode -\else $-$\fi} +- +-% @dots{} outputs an ellipsis using the current font. +-% We do .5em per period so that it has the same spacing in the cm +-% typewriter fonts as three actual period characters; on the other hand, +-% in other typewriter fonts three periods are wider than 1.5em. So do +-% whichever is larger. +-% +-\def\dots{% +- \leavevmode +- \setbox0=\hbox{...}% get width of three periods +- \ifdim\wd0 > 1.5em +- \dimen0 = \wd0 +- \else +- \dimen0 = 1.5em +- \fi +- \hbox to \dimen0{% +- \hskip 0pt plus.25fil +- .\hskip 0pt plus1fil +- .\hskip 0pt plus1fil +- .\hskip 0pt plus.5fil +- }% +-} +- +-% @enddots{} is an end-of-sentence ellipsis. +-% +-\def\enddots{% +- \dots +- \spacefactor=\endofsentencespacefactor +-} +- +-% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +-% +-% Since these characters are used in examples, they should be an even number of +-% \tt widths. Each \tt character is 1en, so two makes it 1em. +-% +-\def\point{$\star$} +-\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}} +-\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +-\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}} +-\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +-\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}} +- +-% The @error{} command. +-% Adapted from the TeXbook's \boxit. +-% +-\newbox\errorbox +-% +-{\tentt \global\dimen0 = 3em}% Width of the box. +-\dimen2 = .55pt % Thickness of rules +-% The text. (`r' is open on the right, `e' somewhat less so on the left.) +-\setbox0 = \hbox{\kern-.75pt \reducedsf \putworderror\kern-1.5pt} +-% +-\setbox\errorbox=\hbox to \dimen0{\hfil +- \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right. +- \advance\hsize by -2\dimen2 % Rules. +- \vbox{% +- \hrule height\dimen2 +- \hbox{\vrule width\dimen2 \kern3pt % Space to left of text. +- \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below. +- \kern3pt\vrule width\dimen2}% Space to right. +- \hrule height\dimen2} +- \hfil} +-% +-\def\error{\leavevmode\lower.7ex\copy\errorbox} +- +-% @pounds{} is a sterling sign, which Knuth put in the CM italic font. +-% +-\def\pounds{{\it\$}} +- +-% @euro{} comes from a separate font, depending on the current style. +-% We use the free feym* fonts from the eurosym package by Henrik +-% Theiling, which support regular, slanted, bold and bold slanted (and +-% "outlined" (blackboard board, sort of) versions, which we don't need). +-% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. +-% +-% Although only regular is the truly official Euro symbol, we ignore +-% that. The Euro is designed to be slightly taller than the regular +-% font height. +-% +-% feymr - regular +-% feymo - slanted +-% feybr - bold +-% feybo - bold slanted +-% +-% There is no good (free) typewriter version, to my knowledge. +-% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. +-% Hmm. +-% +-% Also doesn't work in math. Do we need to do math with euro symbols? +-% Hope not. +-% +-% +-\def\euro{{\eurofont e}} +-\def\eurofont{% +- % We set the font at each command, rather than predefining it in +- % \textfonts and the other font-switching commands, so that +- % installations which never need the symbol don't have to have the +- % font installed. +- % +- % There is only one designed size (nominal 10pt), so we always scale +- % that to the current nominal size. +- % +- % By the way, simply using "at 1em" works for cmr10 and the like, but +- % does not work for cmbx10 and other extended/shrunken fonts. +- % +- \def\eurosize{\csname\curfontsize nominalsize\endcsname}% +- % +- \ifx\curfontstyle\bfstylename +- % bold: +- \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize +- \else +- % regular: +- \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize +- \fi +- \thiseurofont +-} +- +-% Glyphs from the EC fonts. We don't use \let for the aliases, because +-% sometimes we redefine the original macro, and the alias should reflect +-% the redefinition. +-% +-% Use LaTeX names for the Icelandic letters. +-\def\DH{{\ecfont \char"D0}} % Eth +-\def\dh{{\ecfont \char"F0}} % eth +-\def\TH{{\ecfont \char"DE}} % Thorn +-\def\th{{\ecfont \char"FE}} % thorn +-% +-\def\guillemetleft{{\ecfont \char"13}} +-\def\guillemotleft{\guillemetleft} +-\def\guillemetright{{\ecfont \char"14}} +-\def\guillemotright{\guillemetright} +-\def\guilsinglleft{{\ecfont \char"0E}} +-\def\guilsinglright{{\ecfont \char"0F}} +-\def\quotedblbase{{\ecfont \char"12}} +-\def\quotesinglbase{{\ecfont \char"0D}} +-% +-% This positioning is not perfect (see the ogonek LaTeX package), but +-% we have the precomposed glyphs for the most common cases. We put the +-% tests to use those glyphs in the single \ogonek macro so we have fewer +-% dummy definitions to worry about for index entries, etc. +-% +-% ogonek is also used with other letters in Lithuanian (IOU), but using +-% the precomposed glyphs for those is not so easy since they aren't in +-% the same EC font. +-\def\ogonek#1{{% +- \def\temp{#1}% +- \ifx\temp\macrocharA\Aogonek +- \else\ifx\temp\macrochara\aogonek +- \else\ifx\temp\macrocharE\Eogonek +- \else\ifx\temp\macrochare\eogonek +- \else +- \ecfont \setbox0=\hbox{#1}% +- \ifdim\ht0=1ex\accent"0C #1% +- \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}% +- \fi +- \fi\fi\fi\fi +- }% +-} +-\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A} +-\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a} +-\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} +-\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} +-% +-% Use the ec* fonts (cm-super in outline format) for non-CM glyphs. +-\def\ecfont{% +- % We can't distinguish serif/sans and italic/slanted, but this +- % is used for crude hacks anyway (like adding French and German +- % quotes to documents typeset with CM, where we lose kerning), so +- % hopefully nobody will notice/care. +- \edef\ecsize{\csname\curfontsize ecsize\endcsname}% +- \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% +- \ifmonospace +- % typewriter: +- \font\thisecfont = ectt\ecsize \space at \nominalsize +- \else +- \ifx\curfontstyle\bfstylename +- % bold: +- \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize +- \else +- % regular: +- \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize +- \fi +- \fi +- \thisecfont +-} +- +-% @registeredsymbol - R in a circle. The font for the R should really +-% be smaller yet, but lllsize is the best we can do for now. +-% Adapted from the plain.tex definition of \copyright. +-% +-\def\registeredsymbol{% +- $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}% +- \hfil\crcr\Orb}}% +- }$% +-} +- +-% @textdegree - the normal degrees sign. +-% +-\def\textdegree{$^\circ$} +- +-% Laurent Siebenmann reports \Orb undefined with: +-% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 +-% so we'll define it if necessary. +-% +-\ifx\Orb\thisisundefined +-\def\Orb{\mathhexbox20D} +-\fi +- +-% Quotes. +-\chardef\quotedblleft="5C +-\chardef\quotedblright=`\" +-\chardef\quoteleft=`\` +-\chardef\quoteright=`\' +- +- +-\message{page headings,} +- +-\newskip\titlepagetopglue \titlepagetopglue = 1.5in +-\newskip\titlepagebottomglue \titlepagebottomglue = 2pc +- +-% First the title page. Must do @settitle before @titlepage. +-\newif\ifseenauthor +-\newif\iffinishedtitlepage +- +-% Do an implicit @contents or @shortcontents after @end titlepage if the +-% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage. +-% +-\newif\ifsetcontentsaftertitlepage +- \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue +-\newif\ifsetshortcontentsaftertitlepage +- \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue +- +-\parseargdef\shorttitlepage{% +- \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% +- \endgroup\page\hbox{}\page} +- +-\envdef\titlepage{% +- % Open one extra group, as we want to close it in the middle of \Etitlepage. +- \begingroup +- \parindent=0pt \textfonts +- % Leave some space at the very top of the page. +- \vglue\titlepagetopglue +- % No rule at page bottom unless we print one at the top with @title. +- \finishedtitlepagetrue +- % +- % Most title ``pages'' are actually two pages long, with space +- % at the top of the second. We don't want the ragged left on the second. +- \let\oldpage = \page +- \def\page{% +- \iffinishedtitlepage\else +- \finishtitlepage +- \fi +- \let\page = \oldpage +- \page +- \null +- }% +-} +- +-\def\Etitlepage{% +- \iffinishedtitlepage\else +- \finishtitlepage +- \fi +- % It is important to do the page break before ending the group, +- % because the headline and footline are only empty inside the group. +- % If we use the new definition of \page, we always get a blank page +- % after the title page, which we certainly don't want. +- \oldpage +- \endgroup +- % +- % Need this before the \...aftertitlepage checks so that if they are +- % in effect the toc pages will come out with page numbers. +- \HEADINGSon +- % +- % If they want short, they certainly want long too. +- \ifsetshortcontentsaftertitlepage +- \shortcontents +- \contents +- \global\let\shortcontents = \relax +- \global\let\contents = \relax +- \fi +- % +- \ifsetcontentsaftertitlepage +- \contents +- \global\let\contents = \relax +- \global\let\shortcontents = \relax +- \fi +-} +- +-\def\finishtitlepage{% +- \vskip4pt \hrule height 2pt width \hsize +- \vskip\titlepagebottomglue +- \finishedtitlepagetrue +-} +- +-% Settings used for typesetting titles: no hyphenation, no indentation, +-% don't worry much about spacing, ragged right. This should be used +-% inside a \vbox, and fonts need to be set appropriately first. Because +-% it is always used for titles, nothing else, we call \rmisbold. \par +-% should be specified before the end of the \vbox, since a vbox is a group. +-% +-\def\raggedtitlesettings{% +- \rmisbold +- \hyphenpenalty=10000 +- \parindent=0pt +- \tolerance=5000 +- \ptexraggedright +-} +- +-% Macros to be used within @titlepage: +- +-\let\subtitlerm=\tenrm +-\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} +- +-\parseargdef\title{% +- \checkenv\titlepage +- \vbox{\titlefonts \raggedtitlesettings #1\par}% +- % print a rule at the page bottom also. +- \finishedtitlepagefalse +- \vskip4pt \hrule height 4pt width \hsize \vskip4pt +-} +- +-\parseargdef\subtitle{% +- \checkenv\titlepage +- {\subtitlefont \rightline{#1}}% +-} +- +-% @author should come last, but may come many times. +-% It can also be used inside @quotation. +-% +-\parseargdef\author{% +- \def\temp{\quotation}% +- \ifx\thisenv\temp +- \def\quotationauthor{#1}% printed in \Equotation. +- \else +- \checkenv\titlepage +- \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi +- {\secfonts\rmisbold \leftline{#1}}% +- \fi +-} +- +- +-% Set up page headings and footings. +- +-\let\thispage=\folio +- +-\newtoks\evenheadline % headline on even pages +-\newtoks\oddheadline % headline on odd pages +-\newtoks\evenfootline % footline on even pages +-\newtoks\oddfootline % footline on odd pages +- +-% Now make TeX use those variables +-\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline +- \else \the\evenheadline \fi}} +-\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline +- \else \the\evenfootline \fi}\HEADINGShook} +-\let\HEADINGShook=\relax +- +-% Commands to set those variables. +-% For example, this is what @headings on does +-% @evenheading @thistitle|@thispage|@thischapter +-% @oddheading @thischapter|@thispage|@thistitle +-% @evenfooting @thisfile|| +-% @oddfooting ||@thisfile +- +- +-\def\evenheading{\parsearg\evenheadingxxx} +-\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} +-\def\evenheadingyyy #1\|#2\|#3\|#4\finish{% +-\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} +- +-\def\oddheading{\parsearg\oddheadingxxx} +-\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} +-\def\oddheadingyyy #1\|#2\|#3\|#4\finish{% +-\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} +- +-\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% +- +-\def\evenfooting{\parsearg\evenfootingxxx} +-\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} +-\def\evenfootingyyy #1\|#2\|#3\|#4\finish{% +-\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} +- +-\def\oddfooting{\parsearg\oddfootingxxx} +-\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} +-\def\oddfootingyyy #1\|#2\|#3\|#4\finish{% +- \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% +- % +- % Leave some space for the footline. Hopefully ok to assume +- % @evenfooting will not be used by itself. +- \global\advance\pageheight by -12pt +- \global\advance\vsize by -12pt +-} +- +-\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} +- +-% @evenheadingmarks top \thischapter <- chapter at the top of a page +-% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page +-% +-% The same set of arguments for: +-% +-% @oddheadingmarks +-% @evenfootingmarks +-% @oddfootingmarks +-% @everyheadingmarks +-% @everyfootingmarks +- +-\def\evenheadingmarks{\headingmarks{even}{heading}} +-\def\oddheadingmarks{\headingmarks{odd}{heading}} +-\def\evenfootingmarks{\headingmarks{even}{footing}} +-\def\oddfootingmarks{\headingmarks{odd}{footing}} +-\def\everyheadingmarks#1 {\headingmarks{even}{heading}{#1} +- \headingmarks{odd}{heading}{#1} } +-\def\everyfootingmarks#1 {\headingmarks{even}{footing}{#1} +- \headingmarks{odd}{footing}{#1} } +-% #1 = even/odd, #2 = heading/footing, #3 = top/bottom. +-\def\headingmarks#1#2#3 {% +- \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname +- \global\expandafter\let\csname get#1#2marks\endcsname \temp +-} +- +-\everyheadingmarks bottom +-\everyfootingmarks bottom +- +-% @headings double turns headings on for double-sided printing. +-% @headings single turns headings on for single-sided printing. +-% @headings off turns them off. +-% @headings on same as @headings double, retained for compatibility. +-% @headings after turns on double-sided headings after this page. +-% @headings doubleafter turns on double-sided headings after this page. +-% @headings singleafter turns on single-sided headings after this page. +-% By default, they are off at the start of a document, +-% and turned `on' after @end titlepage. +- +-\def\headings #1 {\csname HEADINGS#1\endcsname} +- +-\def\headingsoff{% non-global headings elimination +- \evenheadline={\hfil}\evenfootline={\hfil}% +- \oddheadline={\hfil}\oddfootline={\hfil}% +-} +- +-\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting +-\HEADINGSoff % it's the default +- +-% When we turn headings on, set the page number to 1. +-% For double-sided printing, put current file name in lower left corner, +-% chapter name on inside top of right hand pages, document +-% title on inside top of left hand pages, and page numbers on outside top +-% edge of all pages. +-\def\HEADINGSdouble{% +-\global\pageno=1 +-\global\evenfootline={\hfil} +-\global\oddfootline={\hfil} +-\global\evenheadline={\line{\folio\hfil\thistitle}} +-\global\oddheadline={\line{\thischapter\hfil\folio}} +-\global\let\contentsalignmacro = \chapoddpage +-} +-\let\contentsalignmacro = \chappager +- +-% For single-sided printing, chapter title goes across top left of page, +-% page number on top right. +-\def\HEADINGSsingle{% +-\global\pageno=1 +-\global\evenfootline={\hfil} +-\global\oddfootline={\hfil} +-\global\evenheadline={\line{\thischapter\hfil\folio}} +-\global\oddheadline={\line{\thischapter\hfil\folio}} +-\global\let\contentsalignmacro = \chappager +-} +-\def\HEADINGSon{\HEADINGSdouble} +- +-\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex} +-\let\HEADINGSdoubleafter=\HEADINGSafter +-\def\HEADINGSdoublex{% +-\global\evenfootline={\hfil} +-\global\oddfootline={\hfil} +-\global\evenheadline={\line{\folio\hfil\thistitle}} +-\global\oddheadline={\line{\thischapter\hfil\folio}} +-\global\let\contentsalignmacro = \chapoddpage +-} +- +-\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +-\def\HEADINGSsinglex{% +-\global\evenfootline={\hfil} +-\global\oddfootline={\hfil} +-\global\evenheadline={\line{\thischapter\hfil\folio}} +-\global\oddheadline={\line{\thischapter\hfil\folio}} +-\global\let\contentsalignmacro = \chappager +-} +- +-% Subroutines used in generating headings +-% This produces Day Month Year style of output. +-% Only define if not already defined, in case a txi-??.tex file has set +-% up a different format (e.g., txi-cs.tex does this). +-\ifx\today\thisisundefined +-\def\today{% +- \number\day\space +- \ifcase\month +- \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr +- \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug +- \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec +- \fi +- \space\number\year} +-\fi +- +-% @settitle line... specifies the title of the document, for headings. +-% It generates no output of its own. +-\def\thistitle{\putwordNoTitle} +-\def\settitle{\parsearg{\gdef\thistitle}} +- +- +-\message{tables,} +-% Tables -- @table, @ftable, @vtable, @item(x). +- +-% default indentation of table text +-\newdimen\tableindent \tableindent=.8in +-% default indentation of @itemize and @enumerate text +-\newdimen\itemindent \itemindent=.3in +-% margin between end of table item and start of table text. +-\newdimen\itemmargin \itemmargin=.1in +- +-% used internally for \itemindent minus \itemmargin +-\newdimen\itemmax +- +-% Note @table, @ftable, and @vtable define @item, @itemx, etc., with +-% these defs. +-% They also define \itemindex +-% to index the item name in whatever manner is desired (perhaps none). +- +-\newif\ifitemxneedsnegativevskip +- +-\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi} +- +-\def\internalBitem{\smallbreak \parsearg\itemzzz} +-\def\internalBitemx{\itemxpar \parsearg\itemzzz} +- +-\def\itemzzz #1{\begingroup % +- \advance\hsize by -\rightskip +- \advance\hsize by -\tableindent +- \setbox0=\hbox{\itemindicate{#1}}% +- \itemindex{#1}% +- \nobreak % This prevents a break before @itemx. +- % +- % If the item text does not fit in the space we have, put it on a line +- % by itself, and do not allow a page break either before or after that +- % line. We do not start a paragraph here because then if the next +- % command is, e.g., @kindex, the whatsit would get put into the +- % horizontal list on a line by itself, resulting in extra blank space. +- \ifdim \wd0>\itemmax +- % +- % Make this a paragraph so we get the \parskip glue and wrapping, +- % but leave it ragged-right. +- \begingroup +- \advance\leftskip by-\tableindent +- \advance\hsize by\tableindent +- \advance\rightskip by0pt plus1fil\relax +- \leavevmode\unhbox0\par +- \endgroup +- % +- % We're going to be starting a paragraph, but we don't want the +- % \parskip glue -- logically it's part of the @item we just started. +- \nobreak \vskip-\parskip +- % +- % Stop a page break at the \parskip glue coming up. However, if +- % what follows is an environment such as @example, there will be no +- % \parskip glue; then the negative vskip we just inserted would +- % cause the example and the item to crash together. So we use this +- % bizarre value of 10001 as a signal to \aboveenvbreak to insert +- % \parskip glue after all. Section titles are handled this way also. +- % +- \penalty 10001 +- \endgroup +- \itemxneedsnegativevskipfalse +- \else +- % The item text fits into the space. Start a paragraph, so that the +- % following text (if any) will end up on the same line. +- \noindent +- % Do this with kerns and \unhbox so that if there is a footnote in +- % the item text, it can migrate to the main vertical list and +- % eventually be printed. +- \nobreak\kern-\tableindent +- \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 +- \unhbox0 +- \nobreak\kern\dimen0 +- \endgroup +- \itemxneedsnegativevskiptrue +- \fi +-} +- +-\def\item{\errmessage{@item while not in a list environment}} +-\def\itemx{\errmessage{@itemx while not in a list environment}} +- +-% @table, @ftable, @vtable. +-\envdef\table{% +- \let\itemindex\gobble +- \tablecheck{table}% +-} +-\envdef\ftable{% +- \def\itemindex ##1{\doind {fn}{\code{##1}}}% +- \tablecheck{ftable}% +-} +-\envdef\vtable{% +- \def\itemindex ##1{\doind {vr}{\code{##1}}}% +- \tablecheck{vtable}% +-} +-\def\tablecheck#1{% +- \ifnum \the\catcode`\^^M=\active +- \endgroup +- \errmessage{This command won't work in this context; perhaps the problem is +- that we are \inenvironment\thisenv}% +- \def\next{\doignore{#1}}% +- \else +- \let\next\tablex +- \fi +- \next +-} +-\def\tablex#1{% +- \def\itemindicate{#1}% +- \parsearg\tabley +-} +-\def\tabley#1{% +- {% +- \makevalueexpandable +- \edef\temp{\noexpand\tablez #1\space\space\space}% +- \expandafter +- }\temp \endtablez +-} +-\def\tablez #1 #2 #3 #4\endtablez{% +- \aboveenvbreak +- \ifnum 0#1>0 \advance \leftskip by #1\mil \fi +- \ifnum 0#2>0 \tableindent=#2\mil \fi +- \ifnum 0#3>0 \advance \rightskip by #3\mil \fi +- \itemmax=\tableindent +- \advance \itemmax by -\itemmargin +- \advance \leftskip by \tableindent +- \exdentamount=\tableindent +- \parindent = 0pt +- \parskip = \smallskipamount +- \ifdim \parskip=0pt \parskip=2pt \fi +- \let\item = \internalBitem +- \let\itemx = \internalBitemx +-} +-\def\Etable{\endgraf\afterenvbreak} +-\let\Eftable\Etable +-\let\Evtable\Etable +-\let\Eitemize\Etable +-\let\Eenumerate\Etable +- +-% This is the counter used by @enumerate, which is really @itemize +- +-\newcount \itemno +- +-\envdef\itemize{\parsearg\doitemize} +- +-\def\doitemize#1{% +- \aboveenvbreak +- \itemmax=\itemindent +- \advance\itemmax by -\itemmargin +- \advance\leftskip by \itemindent +- \exdentamount=\itemindent +- \parindent=0pt +- \parskip=\smallskipamount +- \ifdim\parskip=0pt \parskip=2pt \fi +- % +- % Try typesetting the item mark so that if the document erroneously says +- % something like @itemize @samp (intending @table), there's an error +- % right away at the @itemize. It's not the best error message in the +- % world, but it's better than leaving it to the @item. This means if +- % the user wants an empty mark, they have to say @w{} not just @w. +- \def\itemcontents{#1}% +- \setbox0 = \hbox{\itemcontents}% +- % +- % @itemize with no arg is equivalent to @itemize @bullet. +- \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi +- % +- \let\item=\itemizeitem +-} +- +-% Definition of @item while inside @itemize and @enumerate. +-% +-\def\itemizeitem{% +- \advance\itemno by 1 % for enumerations +- {\let\par=\endgraf \smallbreak}% reasonable place to break +- {% +- % If the document has an @itemize directly after a section title, a +- % \nobreak will be last on the list, and \sectionheading will have +- % done a \vskip-\parskip. In that case, we don't want to zero +- % parskip, or the item text will crash with the heading. On the +- % other hand, when there is normal text preceding the item (as there +- % usually is), we do want to zero parskip, or there would be too much +- % space. In that case, we won't have a \nobreak before. At least +- % that's the theory. +- \ifnum\lastpenalty<10000 \parskip=0in \fi +- \noindent +- \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% +- % +- \vadjust{\penalty 1200}}% not good to break after first line of item. +- \flushcr +-} +- +-% \splitoff TOKENS\endmark defines \first to be the first token in +-% TOKENS, and \rest to be the remainder. +-% +-\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}% +- +-% Allow an optional argument of an uppercase letter, lowercase letter, +-% or number, to specify the first label in the enumerated list. No +-% argument is the same as `1'. +-% +-\envparseargdef\enumerate{\enumeratey #1 \endenumeratey} +-\def\enumeratey #1 #2\endenumeratey{% +- % If we were given no argument, pretend we were given `1'. +- \def\thearg{#1}% +- \ifx\thearg\empty \def\thearg{1}\fi +- % +- % Detect if the argument is a single token. If so, it might be a +- % letter. Otherwise, the only valid thing it can be is a number. +- % (We will always have one token, because of the test we just made. +- % This is a good thing, since \splitoff doesn't work given nothing at +- % all -- the first parameter is undelimited.) +- \expandafter\splitoff\thearg\endmark +- \ifx\rest\empty +- % Only one token in the argument. It could still be anything. +- % A ``lowercase letter'' is one whose \lccode is nonzero. +- % An ``uppercase letter'' is one whose \lccode is both nonzero, and +- % not equal to itself. +- % Otherwise, we assume it's a number. +- % +- % We need the \relax at the end of the \ifnum lines to stop TeX from +- % continuing to look for a . +- % +- \ifnum\lccode\expandafter`\thearg=0\relax +- \numericenumerate % a number (we hope) +- \else +- % It's a letter. +- \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax +- \lowercaseenumerate % lowercase letter +- \else +- \uppercaseenumerate % uppercase letter +- \fi +- \fi +- \else +- % Multiple tokens in the argument. We hope it's a number. +- \numericenumerate +- \fi +-} +- +-% An @enumerate whose labels are integers. The starting integer is +-% given in \thearg. +-% +-\def\numericenumerate{% +- \itemno = \thearg +- \startenumeration{\the\itemno}% +-} +- +-% The starting (lowercase) letter is in \thearg. +-\def\lowercaseenumerate{% +- \itemno = \expandafter`\thearg +- \startenumeration{% +- % Be sure we're not beyond the end of the alphabet. +- \ifnum\itemno=0 +- \errmessage{No more lowercase letters in @enumerate; get a bigger +- alphabet}% +- \fi +- \char\lccode\itemno +- }% +-} +- +-% The starting (uppercase) letter is in \thearg. +-\def\uppercaseenumerate{% +- \itemno = \expandafter`\thearg +- \startenumeration{% +- % Be sure we're not beyond the end of the alphabet. +- \ifnum\itemno=0 +- \errmessage{No more uppercase letters in @enumerate; get a bigger +- alphabet} +- \fi +- \char\uccode\itemno +- }% +-} +- +-% Call \doitemize, adding a period to the first argument and supplying the +-% common last two arguments. Also subtract one from the initial value in +-% \itemno, since @item increments \itemno. +-% +-\def\startenumeration#1{% +- \advance\itemno by -1 +- \doitemize{#1.}\flushcr +-} +- +-% @alphaenumerate and @capsenumerate are abbreviations for giving an arg +-% to @enumerate. +-% +-\def\alphaenumerate{\enumerate{a}} +-\def\capsenumerate{\enumerate{A}} +-\def\Ealphaenumerate{\Eenumerate} +-\def\Ecapsenumerate{\Eenumerate} +- +- +-% @multitable macros +-% Amy Hendrickson, 8/18/94, 3/6/96 +-% +-% @multitable ... @end multitable will make as many columns as desired. +-% Contents of each column will wrap at width given in preamble. Width +-% can be specified either with sample text given in a template line, +-% or in percent of \hsize, the current width of text on page. +- +-% Table can continue over pages but will only break between lines. +- +-% To make preamble: +-% +-% Either define widths of columns in terms of percent of \hsize: +-% @multitable @columnfractions .25 .3 .45 +-% @item ... +-% +-% Numbers following @columnfractions are the percent of the total +-% current hsize to be used for each column. You may use as many +-% columns as desired. +- +- +-% Or use a template: +-% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +-% @item ... +-% using the widest term desired in each column. +- +-% Each new table line starts with @item, each subsequent new column +-% starts with @tab. Empty columns may be produced by supplying @tab's +-% with nothing between them for as many times as empty columns are needed, +-% ie, @tab@tab@tab will produce two empty columns. +- +-% @item, @tab do not need to be on their own lines, but it will not hurt +-% if they are. +- +-% Sample multitable: +- +-% @multitable {Column 1 template} {Column 2 template} {Column 3 template} +-% @item first col stuff @tab second col stuff @tab third col +-% @item +-% first col stuff +-% @tab +-% second col stuff +-% @tab +-% third col +-% @item first col stuff @tab second col stuff +-% @tab Many paragraphs of text may be used in any column. +-% +-% They will wrap at the width determined by the template. +-% @item@tab@tab This will be in third column. +-% @end multitable +- +-% Default dimensions may be reset by user. +-% @multitableparskip is vertical space between paragraphs in table. +-% @multitableparindent is paragraph indent in table. +-% @multitablecolmargin is horizontal space to be left between columns. +-% @multitablelinespace is space to leave between table items, baseline +-% to baseline. +-% 0pt means it depends on current normal line spacing. +-% +-\newskip\multitableparskip +-\newskip\multitableparindent +-\newdimen\multitablecolspace +-\newskip\multitablelinespace +-\multitableparskip=0pt +-\multitableparindent=6pt +-\multitablecolspace=12pt +-\multitablelinespace=0pt +- +-% Macros used to set up halign preamble: +-% +-\let\endsetuptable\relax +-\def\xendsetuptable{\endsetuptable} +-\let\columnfractions\relax +-\def\xcolumnfractions{\columnfractions} +-\newif\ifsetpercent +- +-% #1 is the @columnfraction, usually a decimal number like .5, but might +-% be just 1. We just use it, whatever it is. +-% +-\def\pickupwholefraction#1 {% +- \global\advance\colcount by 1 +- \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% +- \setuptable +-} +- +-\newcount\colcount +-\def\setuptable#1{% +- \def\firstarg{#1}% +- \ifx\firstarg\xendsetuptable +- \let\go = \relax +- \else +- \ifx\firstarg\xcolumnfractions +- \global\setpercenttrue +- \else +- \ifsetpercent +- \let\go\pickupwholefraction +- \else +- \global\advance\colcount by 1 +- \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a +- % separator; typically that is always in the input, anyway. +- \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% +- \fi +- \fi +- \ifx\go\pickupwholefraction +- % Put the argument back for the \pickupwholefraction call, so +- % we'll always have a period there to be parsed. +- \def\go{\pickupwholefraction#1}% +- \else +- \let\go = \setuptable +- \fi% +- \fi +- \go +-} +- +-% multitable-only commands. +-% +-% @headitem starts a heading row, which we typeset in bold. Assignments +-% have to be global since we are inside the implicit group of an +-% alignment entry. \everycr below resets \everytab so we don't have to +-% undo it ourselves. +-\def\headitemfont{\b}% for people to use in the template row; not changeable +-\def\headitem{% +- \checkenv\multitable +- \crcr +- \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings +- \global\everytab={\bf}% can't use \headitemfont since the parsing differs +- \the\everytab % for the first item +-}% +-% +-% default for tables with no headings. +-\let\headitemcrhook=\relax +-% +-% A \tab used to include \hskip1sp. But then the space in a template +-% line is not enough. That is bad. So let's go back to just `&' until +-% we again encounter the problem the 1sp was intended to solve. +-% --karl, nathan@acm.org, 20apr99. +-\def\tab{\checkenv\multitable &\the\everytab}% +- +-% @multitable ... @end multitable definitions: +-% +-\newtoks\everytab % insert after every tab. +-% +-\envdef\multitable{% +- \vskip\parskip +- \startsavinginserts +- % +- % @item within a multitable starts a normal row. +- % We use \def instead of \let so that if one of the multitable entries +- % contains an @itemize, we don't choke on the \item (seen as \crcr aka +- % \endtemplate) expanding \doitemize. +- \def\item{\crcr}% +- % +- \tolerance=9500 +- \hbadness=9500 +- \setmultitablespacing +- \parskip=\multitableparskip +- \parindent=\multitableparindent +- \overfullrule=0pt +- \global\colcount=0 +- % +- \everycr = {% +- \noalign{% +- \global\everytab={}% Reset from possible headitem. +- \global\colcount=0 % Reset the column counter. +- % +- % Check for saved footnotes, etc.: +- \checkinserts +- % +- % Perhaps a \nobreak, then reset: +- \headitemcrhook +- \global\let\headitemcrhook=\relax +- }% +- }% +- % +- \parsearg\domultitable +-} +-\def\domultitable#1{% +- % To parse everything between @multitable and @item: +- \setuptable#1 \endsetuptable +- % +- % This preamble sets up a generic column definition, which will +- % be used as many times as user calls for columns. +- % \vtop will set a single line and will also let text wrap and +- % continue for many paragraphs if desired. +- \halign\bgroup &% +- \global\advance\colcount by 1 +- \multistrut +- \vtop{% +- % Use the current \colcount to find the correct column width: +- \hsize=\expandafter\csname col\the\colcount\endcsname +- % +- % In order to keep entries from bumping into each other +- % we will add a \leftskip of \multitablecolspace to all columns after +- % the first one. +- % +- % If a template has been used, we will add \multitablecolspace +- % to the width of each template entry. +- % +- % If the user has set preamble in terms of percent of \hsize we will +- % use that dimension as the width of the column, and the \leftskip +- % will keep entries from bumping into each other. Table will start at +- % left margin and final column will justify at right margin. +- % +- % Make sure we don't inherit \rightskip from the outer environment. +- \rightskip=0pt +- \ifnum\colcount=1 +- % The first column will be indented with the surrounding text. +- \advance\hsize by\leftskip +- \else +- \ifsetpercent \else +- % If user has not set preamble in terms of percent of \hsize +- % we will advance \hsize by \multitablecolspace. +- \advance\hsize by \multitablecolspace +- \fi +- % In either case we will make \leftskip=\multitablecolspace: +- \leftskip=\multitablecolspace +- \fi +- % Ignoring space at the beginning and end avoids an occasional spurious +- % blank line, when TeX decides to break the line at the space before the +- % box from the multistrut, so the strut ends up on a line by itself. +- % For example: +- % @multitable @columnfractions .11 .89 +- % @item @code{#} +- % @tab Legal holiday which is valid in major parts of the whole country. +- % Is automatically provided with highlighting sequences respectively +- % marking characters. +- \noindent\ignorespaces##\unskip\multistrut +- }\cr +-} +-\def\Emultitable{% +- \crcr +- \egroup % end the \halign +- \global\setpercentfalse +-} +- +-\def\setmultitablespacing{% +- \def\multistrut{\strut}% just use the standard line spacing +- % +- % Compute \multitablelinespace (if not defined by user) for use in +- % \multitableparskip calculation. We used define \multistrut based on +- % this, but (ironically) that caused the spacing to be off. +- % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. +-\ifdim\multitablelinespace=0pt +-\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +-\global\advance\multitablelinespace by-\ht0 +-\fi +-% Test to see if parskip is larger than space between lines of +-% table. If not, do nothing. +-% If so, set to same dimension as multitablelinespace. +-\ifdim\multitableparskip>\multitablelinespace +-\global\multitableparskip=\multitablelinespace +-\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller +- % than skip between lines in the table. +-\fi% +-\ifdim\multitableparskip=0pt +-\global\multitableparskip=\multitablelinespace +-\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller +- % than skip between lines in the table. +-\fi} +- +- +-\message{conditionals,} +- +-% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, +-% @ifnotxml always succeed. They currently do nothing; we don't +-% attempt to check whether the conditionals are properly nested. But we +-% have to remember that they are conditionals, so that @end doesn't +-% attempt to close an environment group. +-% +-\def\makecond#1{% +- \expandafter\let\csname #1\endcsname = \relax +- \expandafter\let\csname iscond.#1\endcsname = 1 +-} +-\makecond{iftex} +-\makecond{ifnotdocbook} +-\makecond{ifnothtml} +-\makecond{ifnotinfo} +-\makecond{ifnotplaintext} +-\makecond{ifnotxml} +- +-% Ignore @ignore, @ifhtml, @ifinfo, and the like. +-% +-\def\direntry{\doignore{direntry}} +-\def\documentdescription{\doignore{documentdescription}} +-\def\docbook{\doignore{docbook}} +-\def\html{\doignore{html}} +-\def\ifdocbook{\doignore{ifdocbook}} +-\def\ifhtml{\doignore{ifhtml}} +-\def\ifinfo{\doignore{ifinfo}} +-\def\ifnottex{\doignore{ifnottex}} +-\def\ifplaintext{\doignore{ifplaintext}} +-\def\ifxml{\doignore{ifxml}} +-\def\ignore{\doignore{ignore}} +-\def\menu{\doignore{menu}} +-\def\xml{\doignore{xml}} +- +-% Ignore text until a line `@end #1', keeping track of nested conditionals. +-% +-% A count to remember the depth of nesting. +-\newcount\doignorecount +- +-\def\doignore#1{\begingroup +- % Scan in ``verbatim'' mode: +- \obeylines +- \catcode`\@ = \other +- \catcode`\{ = \other +- \catcode`\} = \other +- % +- % Make sure that spaces turn into tokens that match what \doignoretext wants. +- \spaceisspace +- % +- % Count number of #1's that we've seen. +- \doignorecount = 0 +- % +- % Swallow text until we reach the matching `@end #1'. +- \dodoignore{#1}% +-} +- +-{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. +- \obeylines % +- % +- \gdef\dodoignore#1{% +- % #1 contains the command name as a string, e.g., `ifinfo'. +- % +- % Define a command to find the next `@end #1'. +- \long\def\doignoretext##1^^M@end #1{% +- \doignoretextyyy##1^^M@#1\_STOP_}% +- % +- % And this command to find another #1 command, at the beginning of a +- % line. (Otherwise, we would consider a line `@c @ifset', for +- % example, to count as an @ifset for nesting.) +- \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% +- % +- % And now expand that command. +- \doignoretext ^^M% +- }% +-} +- +-\def\doignoreyyy#1{% +- \def\temp{#1}% +- \ifx\temp\empty % Nothing found. +- \let\next\doignoretextzzz +- \else % Found a nested condition, ... +- \advance\doignorecount by 1 +- \let\next\doignoretextyyy % ..., look for another. +- % If we're here, #1 ends with ^^M\ifinfo (for example). +- \fi +- \next #1% the token \_STOP_ is present just after this macro. +-} +- +-% We have to swallow the remaining "\_STOP_". +-% +-\def\doignoretextzzz#1{% +- \ifnum\doignorecount = 0 % We have just found the outermost @end. +- \let\next\enddoignore +- \else % Still inside a nested condition. +- \advance\doignorecount by -1 +- \let\next\doignoretext % Look for the next @end. +- \fi +- \next +-} +- +-% Finish off ignored text. +-{ \obeylines% +- % Ignore anything after the last `@end #1'; this matters in verbatim +- % environments, where otherwise the newline after an ignored conditional +- % would result in a blank line in the output. +- \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% +-} +- +- +-% @set VAR sets the variable VAR to an empty value. +-% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE. +-% +-% Since we want to separate VAR from REST-OF-LINE (which might be +-% empty), we can't just use \parsearg; we have to insert a space of our +-% own to delimit the rest of the line, and then take it out again if we +-% didn't need it. +-% We rely on the fact that \parsearg sets \catcode`\ =10. +-% +-\parseargdef\set{\setyyy#1 \endsetyyy} +-\def\setyyy#1 #2\endsetyyy{% +- {% +- \makevalueexpandable +- \def\temp{#2}% +- \edef\next{\gdef\makecsname{SET#1}}% +- \ifx\temp\empty +- \next{}% +- \else +- \setzzz#2\endsetzzz +- \fi +- }% +-} +-% Remove the trailing space \setxxx inserted. +-\def\setzzz#1 \endsetzzz{\next{#1}} +- +-% @clear VAR clears (i.e., unsets) the variable VAR. +-% +-\parseargdef\clear{% +- {% +- \makevalueexpandable +- \global\expandafter\let\csname SET#1\endcsname=\relax +- }% +-} +- +-% @value{foo} gets the text saved in variable foo. +-\def\value{\begingroup\makevalueexpandable\valuexxx} +-\def\valuexxx#1{\expandablevalue{#1}\endgroup} +-{ +- \catcode`\-=\active \catcode`\_=\active +- % +- \gdef\makevalueexpandable{% +- \let\value = \expandablevalue +- % We don't want these characters active, ... +- \catcode`\-=\other \catcode`\_=\other +- % ..., but we might end up with active ones in the argument if +- % we're called from @code, as @code{@value{foo-bar_}}, though. +- % So \let them to their normal equivalents. +- \let-\normaldash \let_\normalunderscore +- } +-} +- +-% We have this subroutine so that we can handle at least some @value's +-% properly in indexes (we call \makevalueexpandable in \indexdummies). +-% The command has to be fully expandable (if the variable is set), since +-% the result winds up in the index file. This means that if the +-% variable's value contains other Texinfo commands, it's almost certain +-% it will fail (although perhaps we could fix that with sufficient work +-% to do a one-level expansion on the result, instead of complete). +-% +-% Unfortunately, this has the consequence that when _ is in the *value* +-% of an @set, it does not print properly in the roman fonts (get the cmr +-% dot accent at position 126 instead). No fix comes to mind, and it's +-% been this way since 2003 or earlier, so just ignore it. +-% +-\def\expandablevalue#1{% +- \expandafter\ifx\csname SET#1\endcsname\relax +- {[No value for ``#1'']}% +- \message{Variable `#1', used in @value, is not set.}% +- \else +- \csname SET#1\endcsname +- \fi +-} +- +-% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +-% with @set. +-% +-% To get the special treatment we need for `@end ifset,' we call +-% \makecond and then redefine. +-% +-\makecond{ifset} +-\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} +-\def\doifset#1#2{% +- {% +- \makevalueexpandable +- \let\next=\empty +- \expandafter\ifx\csname SET#2\endcsname\relax +- #1% If not set, redefine \next. +- \fi +- \expandafter +- }\next +-} +-\def\ifsetfail{\doignore{ifset}} +- +-% @ifclear VAR ... @end executes the `...' iff VAR has never been +-% defined with @set, or has been undefined with @clear. +-% +-% The `\else' inside the `\doifset' parameter is a trick to reuse the +-% above code: if the variable is not set, do nothing, if it is set, +-% then redefine \next to \ifclearfail. +-% +-\makecond{ifclear} +-\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} +-\def\ifclearfail{\doignore{ifclear}} +- +-% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written +-% without the @) is in fact defined. We can only feasibly check at the +-% TeX level, so something like `mathcode' is going to considered +-% defined even though it is not a Texinfo command. +-% +-\makecond{ifcommanddefined} +-\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} +-% +-\def\doifcmddefined#1#2{{% +- \makevalueexpandable +- \let\next=\empty +- \expandafter\ifx\csname #2\endcsname\relax +- #1% If not defined, \let\next as above. +- \fi +- \expandafter +- }\next +-} +-\def\ifcmddefinedfail{\doignore{ifcommanddefined}} +- +-% @ifcommandnotdefined CMD ... handled similar to @ifclear above. +-\makecond{ifcommandnotdefined} +-\def\ifcommandnotdefined{% +- \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} +-\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} +- +-% Set the `txicommandconditionals' variable, so documents have a way to +-% test if the @ifcommand...defined conditionals are available. +-\set txicommandconditionals +- +-% @dircategory CATEGORY -- specify a category of the dir file +-% which this file should belong to. Ignore this in TeX. +-\let\dircategory=\comment +- +-% @defininfoenclose. +-\let\definfoenclose=\comment +- +- +-\message{indexing,} +-% Index generation facilities +- +-% Define \newwrite to be identical to plain tex's \newwrite +-% except not \outer, so it can be used within macros and \if's. +-\edef\newwrite{\makecsname{ptexnewwrite}} +- +-% \newindex {foo} defines an index named foo. +-% It automatically defines \fooindex such that +-% \fooindex ...rest of line... puts an entry in the index foo. +-% It also defines \fooindfile to be the number of the output channel for +-% the file that accumulates this index. The file's extension is foo. +-% The name of an index should be no more than 2 characters long +-% for the sake of vms. +-% +-\def\newindex#1{% +- \iflinks +- \expandafter\newwrite \csname#1indfile\endcsname +- \openout \csname#1indfile\endcsname \jobname.#1 % Open the file +- \fi +- \expandafter\xdef\csname#1index\endcsname{% % Define @#1index +- \noexpand\doindex{#1}} +-} +- +-% @defindex foo == \newindex{foo} +-% +-\def\defindex{\parsearg\newindex} +- +-% Define @defcodeindex, like @defindex except put all entries in @code. +-% +-\def\defcodeindex{\parsearg\newcodeindex} +-% +-\def\newcodeindex#1{% +- \iflinks +- \expandafter\newwrite \csname#1indfile\endcsname +- \openout \csname#1indfile\endcsname \jobname.#1 +- \fi +- \expandafter\xdef\csname#1index\endcsname{% +- \noexpand\docodeindex{#1}}% +-} +- +- +-% @synindex foo bar makes index foo feed into index bar. +-% Do this instead of @defindex foo if you don't want it as a separate index. +-% +-% @syncodeindex foo bar similar, but put all entries made for index foo +-% inside @code. +-% +-\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} +-\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} +- +-% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), +-% #3 the target index (bar). +-\def\dosynindex#1#2#3{% +- % Only do \closeout if we haven't already done it, else we'll end up +- % closing the target index. +- \expandafter \ifx\csname donesynindex#2\endcsname \relax +- % The \closeout helps reduce unnecessary open files; the limit on the +- % Acorn RISC OS is a mere 16 files. +- \expandafter\closeout\csname#2indfile\endcsname +- \expandafter\let\csname donesynindex#2\endcsname = 1 +- \fi +- % redefine \fooindfile: +- \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname +- \expandafter\let\csname#2indfile\endcsname=\temp +- % redefine \fooindex: +- \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% +-} +- +-% Define \doindex, the driver for all \fooindex macros. +-% Argument #1 is generated by the calling \fooindex macro, +-% and it is "foo", the name of the index. +- +-% \doindex just uses \parsearg; it calls \doind for the actual work. +-% This is because \doind is more useful to call from other macros. +- +-% There is also \dosubind {index}{topic}{subtopic} +-% which makes an entry in a two-level index such as the operation index. +- +-\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer} +-\def\singleindexer #1{\doind{\indexname}{#1}} +- +-% like the previous two, but they put @code around the argument. +-\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer} +-\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}} +- +-% Take care of Texinfo commands that can appear in an index entry. +-% Since there are some commands we want to expand, and others we don't, +-% we have to laboriously prevent expansion for those that we don't. +-% +-\def\indexdummies{% +- \escapechar = `\\ % use backslash in output files. +- \def\@{@}% change to @@ when we switch to @ as escape char in index files. +- \def\ {\realbackslash\space }% +- % +- % Need these unexpandable (because we define \tt as a dummy) +- % definitions when @{ or @} appear in index entry text. Also, more +- % complicated, when \tex is in effect and \{ is a \delimiter again. +- % We can't use \lbracecmd and \rbracecmd because texindex assumes +- % braces and backslashes are used only as delimiters. Perhaps we +- % should use @lbracechar and @rbracechar? +- \def\{{{\tt\char123}}% +- \def\}{{\tt\char125}}% +- % +- % I don't entirely understand this, but when an index entry is +- % generated from a macro call, the \endinput which \scanmacro inserts +- % causes processing to be prematurely terminated. This is, +- % apparently, because \indexsorttmp is fully expanded, and \endinput +- % is an expandable command. The redefinition below makes \endinput +- % disappear altogether for that purpose -- although logging shows that +- % processing continues to some further point. On the other hand, it +- % seems \endinput does not hurt in the printed index arg, since that +- % is still getting written without apparent harm. +- % +- % Sample source (mac-idx3.tex, reported by Graham Percival to +- % help-texinfo, 22may06): +- % @macro funindex {WORD} +- % @findex xyz +- % @end macro +- % ... +- % @funindex commtest +- % This is not enough to reproduce the bug, but it gives the flavor. +- % +- % Sample whatsit resulting: +- % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}} +- % +- % So: +- \let\endinput = \empty +- % +- % Do the redefinitions. +- \commondummies +-} +- +-% For the aux and toc files, @ is the escape character. So we want to +-% redefine everything using @ as the escape character (instead of +-% \realbackslash, still used for index files). When everything uses @, +-% this will be simpler. +-% +-\def\atdummies{% +- \def\@{@@}% +- \def\ {@ }% +- \let\{ = \lbraceatcmd +- \let\} = \rbraceatcmd +- % +- % Do the redefinitions. +- \commondummies +- \otherbackslash +-} +- +-% Called from \indexdummies and \atdummies. +-% +-\def\commondummies{% +- % +- % \definedummyword defines \#1 as \string\#1\space, thus effectively +- % preventing its expansion. This is used only for control words, +- % not control letters, because the \space would be incorrect for +- % control characters, but is needed to separate the control word +- % from whatever follows. +- % +- % For control letters, we have \definedummyletter, which omits the +- % space. +- % +- % These can be used both for control words that take an argument and +- % those that do not. If it is followed by {arg} in the input, then +- % that will dutifully get written to the index (or wherever). +- % +- \def\definedummyword ##1{\def##1{\string##1\space}}% +- \def\definedummyletter##1{\def##1{\string##1}}% +- \let\definedummyaccent\definedummyletter +- % +- \commondummiesnofonts +- % +- \definedummyletter\_% +- \definedummyletter\-% +- % +- % Non-English letters. +- \definedummyword\AA +- \definedummyword\AE +- \definedummyword\DH +- \definedummyword\L +- \definedummyword\O +- \definedummyword\OE +- \definedummyword\TH +- \definedummyword\aa +- \definedummyword\ae +- \definedummyword\dh +- \definedummyword\exclamdown +- \definedummyword\l +- \definedummyword\o +- \definedummyword\oe +- \definedummyword\ordf +- \definedummyword\ordm +- \definedummyword\questiondown +- \definedummyword\ss +- \definedummyword\th +- % +- % Although these internal commands shouldn't show up, sometimes they do. +- \definedummyword\bf +- \definedummyword\gtr +- \definedummyword\hat +- \definedummyword\less +- \definedummyword\sf +- \definedummyword\sl +- \definedummyword\tclose +- \definedummyword\tt +- % +- \definedummyword\LaTeX +- \definedummyword\TeX +- % +- % Assorted special characters. +- \definedummyword\arrow +- \definedummyword\bullet +- \definedummyword\comma +- \definedummyword\copyright +- \definedummyword\registeredsymbol +- \definedummyword\dots +- \definedummyword\enddots +- \definedummyword\entrybreak +- \definedummyword\equiv +- \definedummyword\error +- \definedummyword\euro +- \definedummyword\expansion +- \definedummyword\geq +- \definedummyword\guillemetleft +- \definedummyword\guillemetright +- \definedummyword\guilsinglleft +- \definedummyword\guilsinglright +- \definedummyword\lbracechar +- \definedummyword\leq +- \definedummyword\minus +- \definedummyword\ogonek +- \definedummyword\pounds +- \definedummyword\point +- \definedummyword\print +- \definedummyword\quotedblbase +- \definedummyword\quotedblleft +- \definedummyword\quotedblright +- \definedummyword\quoteleft +- \definedummyword\quoteright +- \definedummyword\quotesinglbase +- \definedummyword\rbracechar +- \definedummyword\result +- \definedummyword\textdegree +- % +- % We want to disable all macros so that they are not expanded by \write. +- \macrolist +- % +- \normalturnoffactive +- % +- % Handle some cases of @value -- where it does not contain any +- % (non-fully-expandable) commands. +- \makevalueexpandable +-} +- +-% \commondummiesnofonts: common to \commondummies and \indexnofonts. +-% +-\def\commondummiesnofonts{% +- % Control letters and accents. +- \definedummyletter\!% +- \definedummyaccent\"% +- \definedummyaccent\'% +- \definedummyletter\*% +- \definedummyaccent\,% +- \definedummyletter\.% +- \definedummyletter\/% +- \definedummyletter\:% +- \definedummyaccent\=% +- \definedummyletter\?% +- \definedummyaccent\^% +- \definedummyaccent\`% +- \definedummyaccent\~% +- \definedummyword\u +- \definedummyword\v +- \definedummyword\H +- \definedummyword\dotaccent +- \definedummyword\ogonek +- \definedummyword\ringaccent +- \definedummyword\tieaccent +- \definedummyword\ubaraccent +- \definedummyword\udotaccent +- \definedummyword\dotless +- % +- % Texinfo font commands. +- \definedummyword\b +- \definedummyword\i +- \definedummyword\r +- \definedummyword\sansserif +- \definedummyword\sc +- \definedummyword\slanted +- \definedummyword\t +- % +- % Commands that take arguments. +- \definedummyword\abbr +- \definedummyword\acronym +- \definedummyword\anchor +- \definedummyword\cite +- \definedummyword\code +- \definedummyword\command +- \definedummyword\dfn +- \definedummyword\dmn +- \definedummyword\email +- \definedummyword\emph +- \definedummyword\env +- \definedummyword\file +- \definedummyword\image +- \definedummyword\indicateurl +- \definedummyword\inforef +- \definedummyword\kbd +- \definedummyword\key +- \definedummyword\math +- \definedummyword\option +- \definedummyword\pxref +- \definedummyword\ref +- \definedummyword\samp +- \definedummyword\strong +- \definedummyword\tie +- \definedummyword\uref +- \definedummyword\url +- \definedummyword\var +- \definedummyword\verb +- \definedummyword\w +- \definedummyword\xref +- % +- % Consider: +- % @macro mkind{arg1,arg2} +- % @cindex \arg2\ +- % @end macro +- % @mkind{foo, bar} +- % The space after the comma will end up in the temporary definition +- % that we make for arg2 (see \parsemargdef ff.). We want all this to be +- % expanded for the sake of the index, so we end up just seeing "bar". +- \let\xeatspaces = \eatspaces +-} +- +-% For testing: output @{ and @} in index sort strings as \{ and \}. +-\newif\ifusebracesinindexes +- +-% \indexnofonts is used when outputting the strings to sort the index +-% by, and when constructing control sequence names. It eliminates all +-% control sequences and just writes whatever the best ASCII sort string +-% would be for a given command (usually its argument). +-% +-\def\indexnofonts{% +- % Accent commands should become @asis. +- \def\definedummyaccent##1{\let##1\asis}% +- % We can just ignore other control letters. +- \def\definedummyletter##1{\let##1\empty}% +- % All control words become @asis by default; overrides below. +- \let\definedummyword\definedummyaccent +- % +- \commondummiesnofonts +- % +- % Don't no-op \tt, since it isn't a user-level command +- % and is used in the definitions of the active chars like <, >, |, etc. +- % Likewise with the other plain tex font commands. +- %\let\tt=\asis +- % +- \def\ { }% +- \def\@{@}% +- \def\_{\normalunderscore}% +- \def\-{}% @- shouldn't affect sorting +- % +- % Unfortunately, texindex is not prepared to handle braces in the +- % content at all. So for index sorting, we map @{ and @} to strings +- % starting with |, since that ASCII character is between ASCII { and }. +- \ifusebracesinindexes +- \def\lbracechar{\lbracecmd}% +- \def\rbracechar{\rbracecmd}% +- \else +- \def\lbracechar{|a}% +- \def\rbracechar{|b}% +- \fi +- \let\{=\lbracechar +- \let\}=\rbracechar +- % +- % +- % Non-English letters. +- \def\AA{AA}% +- \def\AE{AE}% +- \def\DH{DZZ}% +- \def\L{L}% +- \def\OE{OE}% +- \def\O{O}% +- \def\TH{ZZZ}% +- \def\aa{aa}% +- \def\ae{ae}% +- \def\dh{dzz}% +- \def\exclamdown{!}% +- \def\l{l}% +- \def\oe{oe}% +- \def\ordf{a}% +- \def\ordm{o}% +- \def\o{o}% +- \def\questiondown{?}% +- \def\ss{ss}% +- \def\th{zzz}% +- % +- \def\LaTeX{LaTeX}% +- \def\TeX{TeX}% +- % +- % Assorted special characters. +- % (The following {} will end up in the sort string, but that's ok.) +- \def\arrow{->}% +- \def\bullet{bullet}% +- \def\comma{,}% +- \def\copyright{copyright}% +- \def\dots{...}% +- \def\enddots{...}% +- \def\equiv{==}% +- \def\error{error}% +- \def\euro{euro}% +- \def\expansion{==>}% +- \def\geq{>=}% +- \def\guillemetleft{<<}% +- \def\guillemetright{>>}% +- \def\guilsinglleft{<}% +- \def\guilsinglright{>}% +- \def\leq{<=}% +- \def\minus{-}% +- \def\point{.}% +- \def\pounds{pounds}% +- \def\print{-|}% +- \def\quotedblbase{"}% +- \def\quotedblleft{"}% +- \def\quotedblright{"}% +- \def\quoteleft{`}% +- \def\quoteright{'}% +- \def\quotesinglbase{,}% +- \def\registeredsymbol{R}% +- \def\result{=>}% +- \def\textdegree{o}% +- % +- \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax +- \else \indexlquoteignore \fi +- % +- % We need to get rid of all macros, leaving only the arguments (if present). +- % Of course this is not nearly correct, but it is the best we can do for now. +- % makeinfo does not expand macros in the argument to @deffn, which ends up +- % writing an index entry, and texindex isn't prepared for an index sort entry +- % that starts with \. +- % +- % Since macro invocations are followed by braces, we can just redefine them +- % to take a single TeX argument. The case of a macro invocation that +- % goes to end-of-line is not handled. +- % +- \macrolist +-} +- +-% Undocumented (for FSFS 2nd ed.): @set txiindexlquoteignore makes us +-% ignore left quotes in the sort term. +-{\catcode`\`=\active +- \gdef\indexlquoteignore{\let`=\empty}} +- +-\let\indexbackslash=0 %overridden during \printindex. +-\let\SETmarginindex=\relax % put index entries in margin (undocumented)? +- +-% Most index entries go through here, but \dosubind is the general case. +-% #1 is the index name, #2 is the entry text. +-\def\doind#1#2{\dosubind{#1}{#2}{}} +- +-% Workhorse for all \fooindexes. +-% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +-% empty if called from \doind, as we usually are (the main exception +-% is with most defuns, which call us directly). +-% +-\def\dosubind#1#2#3{% +- \iflinks +- {% +- % Store the main index entry text (including the third arg). +- \toks0 = {#2}% +- % If third arg is present, precede it with a space. +- \def\thirdarg{#3}% +- \ifx\thirdarg\empty \else +- \toks0 = \expandafter{\the\toks0 \space #3}% +- \fi +- % +- \edef\writeto{\csname#1indfile\endcsname}% +- % +- \safewhatsit\dosubindwrite +- }% +- \fi +-} +- +-% Write the entry in \toks0 to the index file: +-% +-\def\dosubindwrite{% +- % Put the index entry in the margin if desired. +- \ifx\SETmarginindex\relax\else +- \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% +- \fi +- % +- % Remember, we are within a group. +- \indexdummies % Must do this here, since \bf, etc expand at this stage +- \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now +- % so it will be output as is; and it will print as backslash. +- % +- % Process the index entry with all font commands turned off, to +- % get the string to sort by. +- {\indexnofonts +- \edef\temp{\the\toks0}% need full expansion +- \xdef\indexsorttmp{\temp}% +- }% +- % +- % Set up the complete index entry, with both the sort key and +- % the original text, including any font commands. We write +- % three arguments to \entry to the .?? file (four in the +- % subentry case), texindex reduces to two when writing the .??s +- % sorted result. +- \edef\temp{% +- \write\writeto{% +- \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}% +- }% +- \temp +-} +- +-% Take care of unwanted page breaks/skips around a whatsit: +-% +-% If a skip is the last thing on the list now, preserve it +-% by backing up by \lastskip, doing the \write, then inserting +-% the skip again. Otherwise, the whatsit generated by the +-% \write or \pdfdest will make \lastskip zero. The result is that +-% sequences like this: +-% @end defun +-% @tindex whatever +-% @defun ... +-% will have extra space inserted, because the \medbreak in the +-% start of the @defun won't see the skip inserted by the @end of +-% the previous defun. +-% +-% But don't do any of this if we're not in vertical mode. We +-% don't want to do a \vskip and prematurely end a paragraph. +-% +-% Avoid page breaks due to these extra skips, too. +-% +-% But wait, there is a catch there: +-% We'll have to check whether \lastskip is zero skip. \ifdim is not +-% sufficient for this purpose, as it ignores stretch and shrink parts +-% of the skip. The only way seems to be to check the textual +-% representation of the skip. +-% +-% The following is almost like \def\zeroskipmacro{0.0pt} except that +-% the ``p'' and ``t'' characters have catcode \other, not 11 (letter). +-% +-\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} +-% +-\newskip\whatsitskip +-\newcount\whatsitpenalty +-% +-% ..., ready, GO: +-% +-\def\safewhatsit#1{\ifhmode +- #1% +- \else +- % \lastskip and \lastpenalty cannot both be nonzero simultaneously. +- \whatsitskip = \lastskip +- \edef\lastskipmacro{\the\lastskip}% +- \whatsitpenalty = \lastpenalty +- % +- % If \lastskip is nonzero, that means the last item was a +- % skip. And since a skip is discardable, that means this +- % -\whatsitskip glue we're inserting is preceded by a +- % non-discardable item, therefore it is not a potential +- % breakpoint, therefore no \nobreak needed. +- \ifx\lastskipmacro\zeroskipmacro +- \else +- \vskip-\whatsitskip +- \fi +- % +- #1% +- % +- \ifx\lastskipmacro\zeroskipmacro +- % If \lastskip was zero, perhaps the last item was a penalty, and +- % perhaps it was >=10000, e.g., a \nobreak. In that case, we want +- % to re-insert the same penalty (values >10000 are used for various +- % signals); since we just inserted a non-discardable item, any +- % following glue (such as a \parskip) would be a breakpoint. For example: +- % @deffn deffn-whatever +- % @vindex index-whatever +- % Description. +- % would allow a break between the index-whatever whatsit +- % and the "Description." paragraph. +- \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi +- \else +- % On the other hand, if we had a nonzero \lastskip, +- % this make-up glue would be preceded by a non-discardable item +- % (the whatsit from the \write), so we must insert a \nobreak. +- \nobreak\vskip\whatsitskip +- \fi +-\fi} +- +-% The index entry written in the file actually looks like +-% \entry {sortstring}{page}{topic} +-% or +-% \entry {sortstring}{page}{topic}{subtopic} +-% The texindex program reads in these files and writes files +-% containing these kinds of lines: +-% \initial {c} +-% before the first topic whose initial is c +-% \entry {topic}{pagelist} +-% for a topic that is used without subtopics +-% \primary {topic} +-% for the beginning of a topic that is used with subtopics +-% \secondary {subtopic}{pagelist} +-% for each subtopic. +- +-% Define the user-accessible indexing commands +-% @findex, @vindex, @kindex, @cindex. +- +-\def\findex {\fnindex} +-\def\kindex {\kyindex} +-\def\cindex {\cpindex} +-\def\vindex {\vrindex} +-\def\tindex {\tpindex} +-\def\pindex {\pgindex} +- +-\def\cindexsub {\begingroup\obeylines\cindexsub} +-{\obeylines % +-\gdef\cindexsub "#1" #2^^M{\endgroup % +-\dosubind{cp}{#2}{#1}}} +- +-% Define the macros used in formatting output of the sorted index material. +- +-% @printindex causes a particular index (the ??s file) to get printed. +-% It does not print any chapter heading (usually an @unnumbered). +-% +-\parseargdef\printindex{\begingroup +- \dobreak \chapheadingskip{10000}% +- % +- \smallfonts \rm +- \tolerance = 9500 +- \plainfrenchspacing +- \everypar = {}% don't want the \kern\-parindent from indentation suppression. +- % +- % See if the index file exists and is nonempty. +- % Change catcode of @ here so that if the index file contains +- % \initial {@} +- % as its first line, TeX doesn't complain about mismatched braces +- % (because it thinks @} is a control sequence). +- \catcode`\@ = 11 +- \openin 1 \jobname.#1s +- \ifeof 1 +- % \enddoublecolumns gets confused if there is no text in the index, +- % and it loses the chapter title and the aux file entries for the +- % index. The easiest way to prevent this problem is to make sure +- % there is some text. +- \putwordIndexNonexistent +- \else +- % +- % If the index file exists but is empty, then \openin leaves \ifeof +- % false. We have to make TeX try to read something from the file, so +- % it can discover if there is anything in it. +- \read 1 to \temp +- \ifeof 1 +- \putwordIndexIsEmpty +- \else +- % Index files are almost Texinfo source, but we use \ as the escape +- % character. It would be better to use @, but that's too big a change +- % to make right now. +- \def\indexbackslash{\backslashcurfont}% +- \catcode`\\ = 0 +- \escapechar = `\\ +- \begindoublecolumns +- \input \jobname.#1s +- \enddoublecolumns +- \fi +- \fi +- \closein 1 +-\endgroup} +- +-% These macros are used by the sorted index file itself. +-% Change them to control the appearance of the index. +- +-\def\initial#1{{% +- % Some minor font changes for the special characters. +- \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt +- % +- % Remove any glue we may have, we'll be inserting our own. +- \removelastskip +- % +- % We like breaks before the index initials, so insert a bonus. +- \nobreak +- \vskip 0pt plus 3\baselineskip +- \penalty 0 +- \vskip 0pt plus -3\baselineskip +- % +- % Typeset the initial. Making this add up to a whole number of +- % baselineskips increases the chance of the dots lining up from column +- % to column. It still won't often be perfect, because of the stretch +- % we need before each entry, but it's better. +- % +- % No shrink because it confuses \balancecolumns. +- \vskip 1.67\baselineskip plus .5\baselineskip +- \leftline{\secbf #1}% +- % Do our best not to break after the initial. +- \nobreak +- \vskip .33\baselineskip plus .1\baselineskip +-}} +- +-% \entry typesets a paragraph consisting of the text (#1), dot leaders, and +-% then page number (#2) flushed to the right margin. It is used for index +-% and table of contents entries. The paragraph is indented by \leftskip. +-% +-% A straightforward implementation would start like this: +-% \def\entry#1#2{... +-% But this freezes the catcodes in the argument, and can cause problems to +-% @code, which sets - active. This problem was fixed by a kludge--- +-% ``-'' was active throughout whole index, but this isn't really right. +-% The right solution is to prevent \entry from swallowing the whole text. +-% --kasal, 21nov03 +-\def\entry{% +- \begingroup +- % +- % Start a new paragraph if necessary, so our assignments below can't +- % affect previous text. +- \par +- % +- % Do not fill out the last line with white space. +- \parfillskip = 0in +- % +- % No extra space above this paragraph. +- \parskip = 0in +- % +- % Do not prefer a separate line ending with a hyphen to fewer lines. +- \finalhyphendemerits = 0 +- % +- % \hangindent is only relevant when the entry text and page number +- % don't both fit on one line. In that case, bob suggests starting the +- % dots pretty far over on the line. Unfortunately, a large +- % indentation looks wrong when the entry text itself is broken across +- % lines. So we use a small indentation and put up with long leaders. +- % +- % \hangafter is reset to 1 (which is the value we want) at the start +- % of each paragraph, so we need not do anything with that. +- \hangindent = 2em +- % +- % When the entry text needs to be broken, just fill out the first line +- % with blank space. +- \rightskip = 0pt plus1fil +- % +- % A bit of stretch before each entry for the benefit of balancing +- % columns. +- \vskip 0pt plus1pt +- % +- % When reading the text of entry, convert explicit line breaks +- % from @* into spaces. The user might give these in long section +- % titles, for instance. +- \def\*{\unskip\space\ignorespaces}% +- \def\entrybreak{\hfil\break}% +- % +- % Swallow the left brace of the text (first parameter): +- \afterassignment\doentry +- \let\temp = +-} +-\def\entrybreak{\unskip\space\ignorespaces}% +-\def\doentry{% +- \bgroup % Instead of the swallowed brace. +- \noindent +- \aftergroup\finishentry +- % And now comes the text of the entry. +-} +-\def\finishentry#1{% +- % #1 is the page number. +- % +- % The following is kludged to not output a line of dots in the index if +- % there are no page numbers. The next person who breaks this will be +- % cursed by a Unix daemon. +- \setbox\boxA = \hbox{#1}% +- \ifdim\wd\boxA = 0pt +- \ % +- \else +- % +- % If we must, put the page number on a line of its own, and fill out +- % this line with blank space. (The \hfil is overwhelmed with the +- % fill leaders glue in \indexdotfill if the page number does fit.) +- \hfil\penalty50 +- \null\nobreak\indexdotfill % Have leaders before the page number. +- % +- % The `\ ' here is removed by the implicit \unskip that TeX does as +- % part of (the primitive) \par. Without it, a spurious underfull +- % \hbox ensues. +- \ifpdf +- \pdfgettoks#1.% +- \ \the\toksA +- \else +- \ #1% +- \fi +- \fi +- \par +- \endgroup +-} +- +-% Like plain.tex's \dotfill, except uses up at least 1 em. +-\def\indexdotfill{\cleaders +- \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill} +- +-\def\primary #1{\line{#1\hfil}} +- +-\newskip\secondaryindent \secondaryindent=0.5cm +-\def\secondary#1#2{{% +- \parfillskip=0in +- \parskip=0in +- \hangindent=1in +- \hangafter=1 +- \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill +- \ifpdf +- \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. +- \else +- #2 +- \fi +- \par +-}} +- +-% Define two-column mode, which we use to typeset indexes. +-% Adapted from the TeXbook, page 416, which is to say, +-% the manmac.tex format used to print the TeXbook itself. +-\catcode`\@=11 +- +-\newbox\partialpage +-\newdimen\doublecolumnhsize +- +-\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns +- % Grab any single-column material above us. +- \output = {% +- % +- % Here is a possibility not foreseen in manmac: if we accumulate a +- % whole lot of material, we might end up calling this \output +- % routine twice in a row (see the doublecol-lose test, which is +- % essentially a couple of indexes with @setchapternewpage off). In +- % that case we just ship out what is in \partialpage with the normal +- % output routine. Generally, \partialpage will be empty when this +- % runs and this will be a no-op. See the indexspread.tex test case. +- \ifvoid\partialpage \else +- \onepageout{\pagecontents\partialpage}% +- \fi +- % +- \global\setbox\partialpage = \vbox{% +- % Unvbox the main output page. +- \unvbox\PAGE +- \kern-\topskip \kern\baselineskip +- }% +- }% +- \eject % run that output routine to set \partialpage +- % +- % Use the double-column output routine for subsequent pages. +- \output = {\doublecolumnout}% +- % +- % Change the page size parameters. We could do this once outside this +- % routine, in each of @smallbook, @afourpaper, and the default 8.5x11 +- % format, but then we repeat the same computation. Repeating a couple +- % of assignments once per index is clearly meaningless for the +- % execution time, so we may as well do it in one place. +- % +- % First we halve the line length, less a little for the gutter between +- % the columns. We compute the gutter based on the line length, so it +- % changes automatically with the paper format. The magic constant +- % below is chosen so that the gutter has the same value (well, +-<1pt) +- % as it did when we hard-coded it. +- % +- % We put the result in a separate register, \doublecolumhsize, so we +- % can restore it in \pagesofar, after \hsize itself has (potentially) +- % been clobbered. +- % +- \doublecolumnhsize = \hsize +- \advance\doublecolumnhsize by -.04154\hsize +- \divide\doublecolumnhsize by 2 +- \hsize = \doublecolumnhsize +- % +- % Double the \vsize as well. (We don't need a separate register here, +- % since nobody clobbers \vsize.) +- \vsize = 2\vsize +-} +- +-% The double-column output routine for all double-column pages except +-% the last. +-% +-\def\doublecolumnout{% +- \splittopskip=\topskip \splitmaxdepth=\maxdepth +- % Get the available space for the double columns -- the normal +- % (undoubled) page height minus any material left over from the +- % previous page. +- \dimen@ = \vsize +- \divide\dimen@ by 2 +- \advance\dimen@ by -\ht\partialpage +- % +- % box0 will be the left-hand column, box2 the right. +- \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ +- \onepageout\pagesofar +- \unvbox255 +- \penalty\outputpenalty +-} +-% +-% Re-output the contents of the output page -- any previous material, +-% followed by the two boxes we just split, in box0 and box2. +-\def\pagesofar{% +- \unvbox\partialpage +- % +- \hsize = \doublecolumnhsize +- \wd0=\hsize \wd2=\hsize +- \hbox to\pagewidth{\box0\hfil\box2}% +-} +-% +-% All done with double columns. +-\def\enddoublecolumns{% +- % The following penalty ensures that the page builder is exercised +- % _before_ we change the output routine. This is necessary in the +- % following situation: +- % +- % The last section of the index consists only of a single entry. +- % Before this section, \pagetotal is less than \pagegoal, so no +- % break occurs before the last section starts. However, the last +- % section, consisting of \initial and the single \entry, does not +- % fit on the page and has to be broken off. Without the following +- % penalty the page builder will not be exercised until \eject +- % below, and by that time we'll already have changed the output +- % routine to the \balancecolumns version, so the next-to-last +- % double-column page will be processed with \balancecolumns, which +- % is wrong: The two columns will go to the main vertical list, with +- % the broken-off section in the recent contributions. As soon as +- % the output routine finishes, TeX starts reconsidering the page +- % break. The two columns and the broken-off section both fit on the +- % page, because the two columns now take up only half of the page +- % goal. When TeX sees \eject from below which follows the final +- % section, it invokes the new output routine that we've set after +- % \balancecolumns below; \onepageout will try to fit the two columns +- % and the final section into the vbox of \pageheight (see +- % \pagebody), causing an overfull box. +- % +- % Note that glue won't work here, because glue does not exercise the +- % page builder, unlike penalties (see The TeXbook, pp. 280-281). +- \penalty0 +- % +- \output = {% +- % Split the last of the double-column material. Leave it on the +- % current page, no automatic page break. +- \balancecolumns +- % +- % If we end up splitting too much material for the current page, +- % though, there will be another page break right after this \output +- % invocation ends. Having called \balancecolumns once, we do not +- % want to call it again. Therefore, reset \output to its normal +- % definition right away. (We hope \balancecolumns will never be +- % called on to balance too much material, but if it is, this makes +- % the output somewhat more palatable.) +- \global\output = {\onepageout{\pagecontents\PAGE}}% +- }% +- \eject +- \endgroup % started in \begindoublecolumns +- % +- % \pagegoal was set to the doubled \vsize above, since we restarted +- % the current page. We're now back to normal single-column +- % typesetting, so reset \pagegoal to the normal \vsize (after the +- % \endgroup where \vsize got restored). +- \pagegoal = \vsize +-} +-% +-% Called at the end of the double column material. +-\def\balancecolumns{% +- \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. +- \dimen@ = \ht0 +- \advance\dimen@ by \topskip +- \advance\dimen@ by-\baselineskip +- \divide\dimen@ by 2 % target to split to +- %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}% +- \splittopskip = \topskip +- % Loop until we get a decent breakpoint. +- {% +- \vbadness = 10000 +- \loop +- \global\setbox3 = \copy0 +- \global\setbox1 = \vsplit3 to \dimen@ +- \ifdim\ht3>\dimen@ +- \global\advance\dimen@ by 1pt +- \repeat +- }% +- %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}% +- \setbox0=\vbox to\dimen@{\unvbox1}% +- \setbox2=\vbox to\dimen@{\unvbox3}% +- % +- \pagesofar +-} +-\catcode`\@ = \other +- +- +-\message{sectioning,} +-% Chapters, sections, etc. +- +-% Let's start with @part. +-\outer\parseargdef\part{\partzzz{#1}} +-\def\partzzz#1{% +- \chapoddpage +- \null +- \vskip.3\vsize % move it down on the page a bit +- \begingroup +- \noindent \titlefonts\rmisbold #1\par % the text +- \let\lastnode=\empty % no node to associate with +- \writetocentry{part}{#1}{}% but put it in the toc +- \headingsoff % no headline or footline on the part page +- \chapoddpage +- \endgroup +-} +- +-% \unnumberedno is an oxymoron. But we count the unnumbered +-% sections so that we can refer to them unambiguously in the pdf +-% outlines by their "section number". We avoid collisions with chapter +-% numbers by starting them at 10000. (If a document ever has 10000 +-% chapters, we're in trouble anyway, I'm sure.) +-\newcount\unnumberedno \unnumberedno = 10000 +-\newcount\chapno +-\newcount\secno \secno=0 +-\newcount\subsecno \subsecno=0 +-\newcount\subsubsecno \subsubsecno=0 +- +-% This counter is funny since it counts through charcodes of letters A, B, ... +-\newcount\appendixno \appendixno = `\@ +-% +-% \def\appendixletter{\char\the\appendixno} +-% We do the following ugly conditional instead of the above simple +-% construct for the sake of pdftex, which needs the actual +-% letter in the expansion, not just typeset. +-% +-\def\appendixletter{% +- \ifnum\appendixno=`A A% +- \else\ifnum\appendixno=`B B% +- \else\ifnum\appendixno=`C C% +- \else\ifnum\appendixno=`D D% +- \else\ifnum\appendixno=`E E% +- \else\ifnum\appendixno=`F F% +- \else\ifnum\appendixno=`G G% +- \else\ifnum\appendixno=`H H% +- \else\ifnum\appendixno=`I I% +- \else\ifnum\appendixno=`J J% +- \else\ifnum\appendixno=`K K% +- \else\ifnum\appendixno=`L L% +- \else\ifnum\appendixno=`M M% +- \else\ifnum\appendixno=`N N% +- \else\ifnum\appendixno=`O O% +- \else\ifnum\appendixno=`P P% +- \else\ifnum\appendixno=`Q Q% +- \else\ifnum\appendixno=`R R% +- \else\ifnum\appendixno=`S S% +- \else\ifnum\appendixno=`T T% +- \else\ifnum\appendixno=`U U% +- \else\ifnum\appendixno=`V V% +- \else\ifnum\appendixno=`W W% +- \else\ifnum\appendixno=`X X% +- \else\ifnum\appendixno=`Y Y% +- \else\ifnum\appendixno=`Z Z% +- % The \the is necessary, despite appearances, because \appendixletter is +- % expanded while writing the .toc file. \char\appendixno is not +- % expandable, thus it is written literally, thus all appendixes come out +- % with the same letter (or @) in the toc without it. +- \else\char\the\appendixno +- \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi +- \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} +- +-% Each @chapter defines these (using marks) as the number+name, number +-% and name of the chapter. Page headings and footings can use +-% these. @section does likewise. +-\def\thischapter{} +-\def\thischapternum{} +-\def\thischaptername{} +-\def\thissection{} +-\def\thissectionnum{} +-\def\thissectionname{} +- +-\newcount\absseclevel % used to calculate proper heading level +-\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count +- +-% @raisesections: treat @section as chapter, @subsection as section, etc. +-\def\raisesections{\global\advance\secbase by -1} +-\let\up=\raisesections % original BFox name +- +-% @lowersections: treat @chapter as section, @section as subsection, etc. +-\def\lowersections{\global\advance\secbase by 1} +-\let\down=\lowersections % original BFox name +- +-% we only have subsub. +-\chardef\maxseclevel = 3 +-% +-% A numbered section within an unnumbered changes to unnumbered too. +-% To achieve this, remember the "biggest" unnum. sec. we are currently in: +-\chardef\unnlevel = \maxseclevel +-% +-% Trace whether the current chapter is an appendix or not: +-% \chapheadtype is "N" or "A", unnumbered chapters are ignored. +-\def\chapheadtype{N} +- +-% Choose a heading macro +-% #1 is heading type +-% #2 is heading level +-% #3 is text for heading +-\def\genhead#1#2#3{% +- % Compute the abs. sec. level: +- \absseclevel=#2 +- \advance\absseclevel by \secbase +- % Make sure \absseclevel doesn't fall outside the range: +- \ifnum \absseclevel < 0 +- \absseclevel = 0 +- \else +- \ifnum \absseclevel > 3 +- \absseclevel = 3 +- \fi +- \fi +- % The heading type: +- \def\headtype{#1}% +- \if \headtype U% +- \ifnum \absseclevel < \unnlevel +- \chardef\unnlevel = \absseclevel +- \fi +- \else +- % Check for appendix sections: +- \ifnum \absseclevel = 0 +- \edef\chapheadtype{\headtype}% +- \else +- \if \headtype A\if \chapheadtype N% +- \errmessage{@appendix... within a non-appendix chapter}% +- \fi\fi +- \fi +- % Check for numbered within unnumbered: +- \ifnum \absseclevel > \unnlevel +- \def\headtype{U}% +- \else +- \chardef\unnlevel = 3 +- \fi +- \fi +- % Now print the heading: +- \if \headtype U% +- \ifcase\absseclevel +- \unnumberedzzz{#3}% +- \or \unnumberedseczzz{#3}% +- \or \unnumberedsubseczzz{#3}% +- \or \unnumberedsubsubseczzz{#3}% +- \fi +- \else +- \if \headtype A% +- \ifcase\absseclevel +- \appendixzzz{#3}% +- \or \appendixsectionzzz{#3}% +- \or \appendixsubseczzz{#3}% +- \or \appendixsubsubseczzz{#3}% +- \fi +- \else +- \ifcase\absseclevel +- \chapterzzz{#3}% +- \or \seczzz{#3}% +- \or \numberedsubseczzz{#3}% +- \or \numberedsubsubseczzz{#3}% +- \fi +- \fi +- \fi +- \suppressfirstparagraphindent +-} +- +-% an interface: +-\def\numhead{\genhead N} +-\def\apphead{\genhead A} +-\def\unnmhead{\genhead U} +- +-% @chapter, @appendix, @unnumbered. Increment top-level counter, reset +-% all lower-level sectioning counters to zero. +-% +-% Also set \chaplevelprefix, which we prepend to @float sequence numbers +-% (e.g., figures), q.v. By default (before any chapter), that is empty. +-\let\chaplevelprefix = \empty +-% +-\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz +-\def\chapterzzz#1{% +- % section resetting is \global in case the chapter is in a group, such +- % as an @include file. +- \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 +- \global\advance\chapno by 1 +- % +- % Used for \float. +- \gdef\chaplevelprefix{\the\chapno.}% +- \resetallfloatnos +- % +- % \putwordChapter can contain complex things in translations. +- \toks0=\expandafter{\putwordChapter}% +- \message{\the\toks0 \space \the\chapno}% +- % +- % Write the actual heading. +- \chapmacro{#1}{Ynumbered}{\the\chapno}% +- % +- % So @section and the like are numbered underneath this chapter. +- \global\let\section = \numberedsec +- \global\let\subsection = \numberedsubsec +- \global\let\subsubsection = \numberedsubsubsec +-} +- +-\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz +-% +-\def\appendixzzz#1{% +- \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 +- \global\advance\appendixno by 1 +- \gdef\chaplevelprefix{\appendixletter.}% +- \resetallfloatnos +- % +- % \putwordAppendix can contain complex things in translations. +- \toks0=\expandafter{\putwordAppendix}% +- \message{\the\toks0 \space \appendixletter}% +- % +- \chapmacro{#1}{Yappendix}{\appendixletter}% +- % +- \global\let\section = \appendixsec +- \global\let\subsection = \appendixsubsec +- \global\let\subsubsection = \appendixsubsubsec +-} +- +-% normally unnmhead0 calls unnumberedzzz: +-\outer\parseargdef\unnumbered{\unnmhead0{#1}} +-\def\unnumberedzzz#1{% +- \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 +- \global\advance\unnumberedno by 1 +- % +- % Since an unnumbered has no number, no prefix for figures. +- \global\let\chaplevelprefix = \empty +- \resetallfloatnos +- % +- % This used to be simply \message{#1}, but TeX fully expands the +- % argument to \message. Therefore, if #1 contained @-commands, TeX +- % expanded them. For example, in `@unnumbered The @cite{Book}', TeX +- % expanded @cite (which turns out to cause errors because \cite is meant +- % to be executed, not expanded). +- % +- % Anyway, we don't want the fully-expanded definition of @cite to appear +- % as a result of the \message, we just want `@cite' itself. We use +- % \the to achieve this: TeX expands \the only once, +- % simply yielding the contents of . (We also do this for +- % the toc entries.) +- \toks0 = {#1}% +- \message{(\the\toks0)}% +- % +- \chapmacro{#1}{Ynothing}{\the\unnumberedno}% +- % +- \global\let\section = \unnumberedsec +- \global\let\subsection = \unnumberedsubsec +- \global\let\subsubsection = \unnumberedsubsubsec +-} +- +-% @centerchap is like @unnumbered, but the heading is centered. +-\outer\parseargdef\centerchap{% +- % Well, we could do the following in a group, but that would break +- % an assumption that \chapmacro is called at the outermost level. +- % Thus we are safer this way: --kasal, 24feb04 +- \let\centerparametersmaybe = \centerparameters +- \unnmhead0{#1}% +- \let\centerparametersmaybe = \relax +-} +- +-% @top is like @unnumbered. +-\let\top\unnumbered +- +-% Sections. +-% +-\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz +-\def\seczzz#1{% +- \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 +- \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% +-} +- +-% normally calls appendixsectionzzz: +-\outer\parseargdef\appendixsection{\apphead1{#1}} +-\def\appendixsectionzzz#1{% +- \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 +- \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% +-} +-\let\appendixsec\appendixsection +- +-% normally calls unnumberedseczzz: +-\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} +-\def\unnumberedseczzz#1{% +- \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 +- \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% +-} +- +-% Subsections. +-% +-% normally calls numberedsubseczzz: +-\outer\parseargdef\numberedsubsec{\numhead2{#1}} +-\def\numberedsubseczzz#1{% +- \global\subsubsecno=0 \global\advance\subsecno by 1 +- \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% +-} +- +-% normally calls appendixsubseczzz: +-\outer\parseargdef\appendixsubsec{\apphead2{#1}} +-\def\appendixsubseczzz#1{% +- \global\subsubsecno=0 \global\advance\subsecno by 1 +- \sectionheading{#1}{subsec}{Yappendix}% +- {\appendixletter.\the\secno.\the\subsecno}% +-} +- +-% normally calls unnumberedsubseczzz: +-\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} +-\def\unnumberedsubseczzz#1{% +- \global\subsubsecno=0 \global\advance\subsecno by 1 +- \sectionheading{#1}{subsec}{Ynothing}% +- {\the\unnumberedno.\the\secno.\the\subsecno}% +-} +- +-% Subsubsections. +-% +-% normally numberedsubsubseczzz: +-\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} +-\def\numberedsubsubseczzz#1{% +- \global\advance\subsubsecno by 1 +- \sectionheading{#1}{subsubsec}{Ynumbered}% +- {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% +-} +- +-% normally appendixsubsubseczzz: +-\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} +-\def\appendixsubsubseczzz#1{% +- \global\advance\subsubsecno by 1 +- \sectionheading{#1}{subsubsec}{Yappendix}% +- {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% +-} +- +-% normally unnumberedsubsubseczzz: +-\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} +-\def\unnumberedsubsubseczzz#1{% +- \global\advance\subsubsecno by 1 +- \sectionheading{#1}{subsubsec}{Ynothing}% +- {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% +-} +- +-% These macros control what the section commands do, according +-% to what kind of chapter we are in (ordinary, appendix, or unnumbered). +-% Define them by default for a numbered chapter. +-\let\section = \numberedsec +-\let\subsection = \numberedsubsec +-\let\subsubsection = \numberedsubsubsec +- +-% Define @majorheading, @heading and @subheading +- +-\def\majorheading{% +- {\advance\chapheadingskip by 10pt \chapbreak }% +- \parsearg\chapheadingzzz +-} +- +-\def\chapheading{\chapbreak \parsearg\chapheadingzzz} +-\def\chapheadingzzz#1{% +- \vbox{\chapfonts \raggedtitlesettings #1\par}% +- \nobreak\bigskip \nobreak +- \suppressfirstparagraphindent +-} +- +-% @heading, @subheading, @subsubheading. +-\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} +- \suppressfirstparagraphindent} +-\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} +- \suppressfirstparagraphindent} +-\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} +- \suppressfirstparagraphindent} +- +-% These macros generate a chapter, section, etc. heading only +-% (including whitespace, linebreaking, etc. around it), +-% given all the information in convenient, parsed form. +- +-% Args are the skip and penalty (usually negative) +-\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi} +- +-% Parameter controlling skip before chapter headings (if needed) +-\newskip\chapheadingskip +- +-% Define plain chapter starts, and page on/off switching for it. +-\def\chapbreak{\dobreak \chapheadingskip {-4000}} +-\def\chappager{\par\vfill\supereject} +-% Because \domark is called before \chapoddpage, the filler page will +-% get the headings for the next chapter, which is wrong. But we don't +-% care -- we just disable all headings on the filler page. +-\def\chapoddpage{% +- \chappager +- \ifodd\pageno \else +- \begingroup +- \headingsoff +- \null +- \chappager +- \endgroup +- \fi +-} +- +-\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname} +- +-\def\CHAPPAGoff{% +-\global\let\contentsalignmacro = \chappager +-\global\let\pchapsepmacro=\chapbreak +-\global\let\pagealignmacro=\chappager} +- +-\def\CHAPPAGon{% +-\global\let\contentsalignmacro = \chappager +-\global\let\pchapsepmacro=\chappager +-\global\let\pagealignmacro=\chappager +-\global\def\HEADINGSon{\HEADINGSsingle}} +- +-\def\CHAPPAGodd{% +-\global\let\contentsalignmacro = \chapoddpage +-\global\let\pchapsepmacro=\chapoddpage +-\global\let\pagealignmacro=\chapoddpage +-\global\def\HEADINGSon{\HEADINGSdouble}} +- +-\CHAPPAGon +- +-% Chapter opening. +-% +-% #1 is the text, #2 is the section type (Ynumbered, Ynothing, +-% Yappendix, Yomitfromtoc), #3 the chapter number. +-% Not used for @heading series. +-% +-% To test against our argument. +-\def\Ynothingkeyword{Ynothing} +-\def\Yappendixkeyword{Yappendix} +-\def\Yomitfromtockeyword{Yomitfromtoc} +-% +-\def\chapmacro#1#2#3{% +- \checkenv{}% chapters, etc., should not start inside an environment. +- % +- % Insert the first mark before the heading break (see notes for \domark). +- \let\prevchapterdefs=\lastchapterdefs +- \let\prevsectiondefs=\lastsectiondefs +- \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% +- \gdef\thissection{}}% +- % +- \def\temptype{#2}% +- \ifx\temptype\Ynothingkeyword +- \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% +- \gdef\thischapter{\thischaptername}}% +- \else\ifx\temptype\Yomitfromtockeyword +- \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% +- \gdef\thischapter{}}% +- \else\ifx\temptype\Yappendixkeyword +- \toks0={#1}% +- \xdef\lastchapterdefs{% +- \gdef\noexpand\thischaptername{\the\toks0}% +- \gdef\noexpand\thischapternum{\appendixletter}% +- % \noexpand\putwordAppendix avoids expanding indigestible +- % commands in some of the translations. +- \gdef\noexpand\thischapter{\noexpand\putwordAppendix{} +- \noexpand\thischapternum: +- \noexpand\thischaptername}% +- }% +- \else +- \toks0={#1}% +- \xdef\lastchapterdefs{% +- \gdef\noexpand\thischaptername{\the\toks0}% +- \gdef\noexpand\thischapternum{\the\chapno}% +- % \noexpand\putwordChapter avoids expanding indigestible +- % commands in some of the translations. +- \gdef\noexpand\thischapter{\noexpand\putwordChapter{} +- \noexpand\thischapternum: +- \noexpand\thischaptername}% +- }% +- \fi\fi\fi +- % +- % Output the mark. Pass it through \safewhatsit, to take care of +- % the preceding space. +- \safewhatsit\domark +- % +- % Insert the chapter heading break. +- \pchapsepmacro +- % +- % Now the second mark, after the heading break. No break points +- % between here and the heading. +- \let\prevchapterdefs=\lastchapterdefs +- \let\prevsectiondefs=\lastsectiondefs +- \domark +- % +- {% +- \chapfonts \rmisbold +- % +- % Have to define \lastsection before calling \donoderef, because the +- % xref code eventually uses it. On the other hand, it has to be called +- % after \pchapsepmacro, or the headline will change too soon. +- \gdef\lastsection{#1}% +- % +- % Only insert the separating space if we have a chapter/appendix +- % number, and don't print the unnumbered ``number''. +- \ifx\temptype\Ynothingkeyword +- \setbox0 = \hbox{}% +- \def\toctype{unnchap}% +- \else\ifx\temptype\Yomitfromtockeyword +- \setbox0 = \hbox{}% contents like unnumbered, but no toc entry +- \def\toctype{omit}% +- \else\ifx\temptype\Yappendixkeyword +- \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% +- \def\toctype{app}% +- \else +- \setbox0 = \hbox{#3\enspace}% +- \def\toctype{numchap}% +- \fi\fi\fi +- % +- % Write the toc entry for this chapter. Must come before the +- % \donoderef, because we include the current node name in the toc +- % entry, and \donoderef resets it to empty. +- \writetocentry{\toctype}{#1}{#3}% +- % +- % For pdftex, we have to write out the node definition (aka, make +- % the pdfdest) after any page break, but before the actual text has +- % been typeset. If the destination for the pdf outline is after the +- % text, then jumping from the outline may wind up with the text not +- % being visible, for instance under high magnification. +- \donoderef{#2}% +- % +- % Typeset the actual heading. +- \nobreak % Avoid page breaks at the interline glue. +- \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe +- \unhbox0 #1\par}% +- }% +- \nobreak\bigskip % no page break after a chapter title +- \nobreak +-} +- +-% @centerchap -- centered and unnumbered. +-\let\centerparametersmaybe = \relax +-\def\centerparameters{% +- \advance\rightskip by 3\rightskip +- \leftskip = \rightskip +- \parfillskip = 0pt +-} +- +- +-% I don't think this chapter style is supported any more, so I'm not +-% updating it with the new noderef stuff. We'll see. --karl, 11aug03. +-% +-\def\setchapterstyle #1 {\csname CHAPF#1\endcsname} +-% +-\def\unnchfopen #1{% +- \chapoddpage +- \vbox{\chapfonts \raggedtitlesettings #1\par}% +- \nobreak\bigskip\nobreak +-} +-\def\chfopen #1#2{\chapoddpage {\chapfonts +-\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% +-\par\penalty 5000 % +-} +-\def\centerchfopen #1{% +- \chapoddpage +- \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% +- \nobreak\bigskip \nobreak +-} +-\def\CHAPFopen{% +- \global\let\chapmacro=\chfopen +- \global\let\centerchapmacro=\centerchfopen} +- +- +-% Section titles. These macros combine the section number parts and +-% call the generic \sectionheading to do the printing. +-% +-\newskip\secheadingskip +-\def\secheadingbreak{\dobreak \secheadingskip{-1000}} +- +-% Subsection titles. +-\newskip\subsecheadingskip +-\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} +- +-% Subsubsection titles. +-\def\subsubsecheadingskip{\subsecheadingskip} +-\def\subsubsecheadingbreak{\subsecheadingbreak} +- +- +-% Print any size, any type, section title. +-% +-% #1 is the text of the title, +-% #2 is the section level (sec/subsec/subsubsec), +-% #3 is the section type (Ynumbered, Ynothing, Yappendix, Yomitfromtoc), +-% #4 is the section number. +-% +-\def\seckeyword{sec} +-% +-\def\sectionheading#1#2#3#4{% +- {% +- \def\sectionlevel{#2}% +- \def\temptype{#3}% +- % +- % It is ok for the @heading series commands to appear inside an +- % environment (it's been historically allowed, though the logic is +- % dubious), but not the others. +- \ifx\temptype\Yomitfromtockeyword\else +- \checkenv{}% non-@*heading should not be in an environment. +- \fi +- % +- % Switch to the right set of fonts. +- \csname #2fonts\endcsname \rmisbold +- % +- % Insert first mark before the heading break (see notes for \domark). +- \let\prevsectiondefs=\lastsectiondefs +- \ifx\temptype\Ynothingkeyword +- \ifx\sectionlevel\seckeyword +- \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% +- \gdef\thissection{\thissectionname}}% +- \fi +- \else\ifx\temptype\Yomitfromtockeyword +- % Don't redefine \thissection. +- \else\ifx\temptype\Yappendixkeyword +- \ifx\sectionlevel\seckeyword +- \toks0={#1}% +- \xdef\lastsectiondefs{% +- \gdef\noexpand\thissectionname{\the\toks0}% +- \gdef\noexpand\thissectionnum{#4}% +- % \noexpand\putwordSection avoids expanding indigestible +- % commands in some of the translations. +- \gdef\noexpand\thissection{\noexpand\putwordSection{} +- \noexpand\thissectionnum: +- \noexpand\thissectionname}% +- }% +- \fi +- \else +- \ifx\sectionlevel\seckeyword +- \toks0={#1}% +- \xdef\lastsectiondefs{% +- \gdef\noexpand\thissectionname{\the\toks0}% +- \gdef\noexpand\thissectionnum{#4}% +- % \noexpand\putwordSection avoids expanding indigestible +- % commands in some of the translations. +- \gdef\noexpand\thissection{\noexpand\putwordSection{} +- \noexpand\thissectionnum: +- \noexpand\thissectionname}% +- }% +- \fi +- \fi\fi\fi +- % +- % Go into vertical mode. Usually we'll already be there, but we +- % don't want the following whatsit to end up in a preceding paragraph +- % if the document didn't happen to have a blank line. +- \par +- % +- % Output the mark. Pass it through \safewhatsit, to take care of +- % the preceding space. +- \safewhatsit\domark +- % +- % Insert space above the heading. +- \csname #2headingbreak\endcsname +- % +- % Now the second mark, after the heading break. No break points +- % between here and the heading. +- \global\let\prevsectiondefs=\lastsectiondefs +- \domark +- % +- % Only insert the space after the number if we have a section number. +- \ifx\temptype\Ynothingkeyword +- \setbox0 = \hbox{}% +- \def\toctype{unn}% +- \gdef\lastsection{#1}% +- \else\ifx\temptype\Yomitfromtockeyword +- % for @headings -- no section number, don't include in toc, +- % and don't redefine \lastsection. +- \setbox0 = \hbox{}% +- \def\toctype{omit}% +- \let\sectionlevel=\empty +- \else\ifx\temptype\Yappendixkeyword +- \setbox0 = \hbox{#4\enspace}% +- \def\toctype{app}% +- \gdef\lastsection{#1}% +- \else +- \setbox0 = \hbox{#4\enspace}% +- \def\toctype{num}% +- \gdef\lastsection{#1}% +- \fi\fi\fi +- % +- % Write the toc entry (before \donoderef). See comments in \chapmacro. +- \writetocentry{\toctype\sectionlevel}{#1}{#4}% +- % +- % Write the node reference (= pdf destination for pdftex). +- % Again, see comments in \chapmacro. +- \donoderef{#3}% +- % +- % Interline glue will be inserted when the vbox is completed. +- % That glue will be a valid breakpoint for the page, since it'll be +- % preceded by a whatsit (usually from the \donoderef, or from the +- % \writetocentry if there was no node). We don't want to allow that +- % break, since then the whatsits could end up on page n while the +- % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. +- \nobreak +- % +- % Output the actual section heading. +- \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright +- \hangindent=\wd0 % zero if no section number +- \unhbox0 #1}% +- }% +- % Add extra space after the heading -- half of whatever came above it. +- % Don't allow stretch, though. +- \kern .5 \csname #2headingskip\endcsname +- % +- % Do not let the kern be a potential breakpoint, as it would be if it +- % was followed by glue. +- \nobreak +- % +- % We'll almost certainly start a paragraph next, so don't let that +- % glue accumulate. (Not a breakpoint because it's preceded by a +- % discardable item.) However, when a paragraph is not started next +- % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out +- % or the negative glue will cause weirdly wrong output, typically +- % obscuring the section heading with something else. +- \vskip-\parskip +- % +- % This is so the last item on the main vertical list is a known +- % \penalty > 10000, so \startdefun, etc., can recognize the situation +- % and do the needful. +- \penalty 10001 +-} +- +- +-\message{toc,} +-% Table of contents. +-\newwrite\tocfile +- +-% Write an entry to the toc file, opening it if necessary. +-% Called from @chapter, etc. +-% +-% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} +-% We append the current node name (if any) and page number as additional +-% arguments for the \{chap,sec,...}entry macros which will eventually +-% read this. The node name is used in the pdf outlines as the +-% destination to jump to. +-% +-% We open the .toc file for writing here instead of at @setfilename (or +-% any other fixed time) so that @contents can be anywhere in the document. +-% But if #1 is `omit', then we don't do anything. This is used for the +-% table of contents chapter openings themselves. +-% +-\newif\iftocfileopened +-\def\omitkeyword{omit}% +-% +-\def\writetocentry#1#2#3{% +- \edef\writetoctype{#1}% +- \ifx\writetoctype\omitkeyword \else +- \iftocfileopened\else +- \immediate\openout\tocfile = \jobname.toc +- \global\tocfileopenedtrue +- \fi +- % +- \iflinks +- {\atdummies +- \edef\temp{% +- \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% +- \temp +- }% +- \fi +- \fi +- % +- % Tell \shipout to create a pdf destination on each page, if we're +- % writing pdf. These are used in the table of contents. We can't +- % just write one on every page because the title pages are numbered +- % 1 and 2 (the page numbers aren't printed), and so are the first +- % two pages of the document. Thus, we'd have two destinations named +- % `1', and two named `2'. +- \ifpdf \global\pdfmakepagedesttrue \fi +-} +- +- +-% These characters do not print properly in the Computer Modern roman +-% fonts, so we must take special care. This is more or less redundant +-% with the Texinfo input format setup at the end of this file. +-% +-\def\activecatcodes{% +- \catcode`\"=\active +- \catcode`\$=\active +- \catcode`\<=\active +- \catcode`\>=\active +- \catcode`\\=\active +- \catcode`\^=\active +- \catcode`\_=\active +- \catcode`\|=\active +- \catcode`\~=\active +-} +- +- +-% Read the toc file, which is essentially Texinfo input. +-\def\readtocfile{% +- \setupdatafile +- \activecatcodes +- \input \tocreadfilename +-} +- +-\newskip\contentsrightmargin \contentsrightmargin=1in +-\newcount\savepageno +-\newcount\lastnegativepageno \lastnegativepageno = -1 +- +-% Prepare to read what we've written to \tocfile. +-% +-\def\startcontents#1{% +- % If @setchapternewpage on, and @headings double, the contents should +- % start on an odd page, unlike chapters. Thus, we maintain +- % \contentsalignmacro in parallel with \pagealignmacro. +- % From: Torbjorn Granlund +- \contentsalignmacro +- \immediate\closeout\tocfile +- % +- % Don't need to put `Contents' or `Short Contents' in the headline. +- % It is abundantly clear what they are. +- \chapmacro{#1}{Yomitfromtoc}{}% +- % +- \savepageno = \pageno +- \begingroup % Set up to handle contents files properly. +- \raggedbottom % Worry more about breakpoints than the bottom. +- \advance\hsize by -\contentsrightmargin % Don't use the full line length. +- % +- % Roman numerals for page numbers. +- \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi +-} +- +-% redefined for the two-volume lispref. We always output on +-% \jobname.toc even if this is redefined. +-% +-\def\tocreadfilename{\jobname.toc} +- +-% Normal (long) toc. +-% +-\def\contents{% +- \startcontents{\putwordTOC}% +- \openin 1 \tocreadfilename\space +- \ifeof 1 \else +- \readtocfile +- \fi +- \vfill \eject +- \contentsalignmacro % in case @setchapternewpage odd is in effect +- \ifeof 1 \else +- \pdfmakeoutlines +- \fi +- \closein 1 +- \endgroup +- \lastnegativepageno = \pageno +- \global\pageno = \savepageno +-} +- +-% And just the chapters. +-\def\summarycontents{% +- \startcontents{\putwordShortTOC}% +- % +- \let\partentry = \shortpartentry +- \let\numchapentry = \shortchapentry +- \let\appentry = \shortchapentry +- \let\unnchapentry = \shortunnchapentry +- % We want a true roman here for the page numbers. +- \secfonts +- \let\rm=\shortcontrm \let\bf=\shortcontbf +- \let\sl=\shortcontsl \let\tt=\shortconttt +- \rm +- \hyphenpenalty = 10000 +- \advance\baselineskip by 1pt % Open it up a little. +- \def\numsecentry##1##2##3##4{} +- \let\appsecentry = \numsecentry +- \let\unnsecentry = \numsecentry +- \let\numsubsecentry = \numsecentry +- \let\appsubsecentry = \numsecentry +- \let\unnsubsecentry = \numsecentry +- \let\numsubsubsecentry = \numsecentry +- \let\appsubsubsecentry = \numsecentry +- \let\unnsubsubsecentry = \numsecentry +- \openin 1 \tocreadfilename\space +- \ifeof 1 \else +- \readtocfile +- \fi +- \closein 1 +- \vfill \eject +- \contentsalignmacro % in case @setchapternewpage odd is in effect +- \endgroup +- \lastnegativepageno = \pageno +- \global\pageno = \savepageno +-} +-\let\shortcontents = \summarycontents +- +-% Typeset the label for a chapter or appendix for the short contents. +-% The arg is, e.g., `A' for an appendix, or `3' for a chapter. +-% +-\def\shortchaplabel#1{% +- % This space should be enough, since a single number is .5em, and the +- % widest letter (M) is 1em, at least in the Computer Modern fonts. +- % But use \hss just in case. +- % (This space doesn't include the extra space that gets added after +- % the label; that gets put in by \shortchapentry above.) +- % +- % We'd like to right-justify chapter numbers, but that looks strange +- % with appendix letters. And right-justifying numbers and +- % left-justifying letters looks strange when there is less than 10 +- % chapters. Have to read the whole toc once to know how many chapters +- % there are before deciding ... +- \hbox to 1em{#1\hss}% +-} +- +-% These macros generate individual entries in the table of contents. +-% The first argument is the chapter or section name. +-% The last argument is the page number. +-% The arguments in between are the chapter number, section number, ... +- +-% Parts, in the main contents. Replace the part number, which doesn't +-% exist, with an empty box. Let's hope all the numbers have the same width. +-% Also ignore the page number, which is conventionally not printed. +-\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} +-\def\partentry#1#2#3#4{\dochapentry{\numeralbox\labelspace#1}{}} +-% +-% Parts, in the short toc. +-\def\shortpartentry#1#2#3#4{% +- \penalty-300 +- \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip +- \shortchapentry{{\bf #1}}{\numeralbox}{}{}% +-} +- +-% Chapters, in the main contents. +-\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} +-% +-% Chapters, in the short toc. +-% See comments in \dochapentry re vbox and related settings. +-\def\shortchapentry#1#2#3#4{% +- \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% +-} +- +-% Appendices, in the main contents. +-% Need the word Appendix, and a fixed-size box. +-% +-\def\appendixbox#1{% +- % We use M since it's probably the widest letter. +- \setbox0 = \hbox{\putwordAppendix{} M}% +- \hbox to \wd0{\putwordAppendix{} #1\hss}} +-% +-\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}} +- +-% Unnumbered chapters. +-\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} +-\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} +- +-% Sections. +-\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} +-\let\appsecentry=\numsecentry +-\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} +- +-% Subsections. +-\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} +-\let\appsubsecentry=\numsubsecentry +-\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} +- +-% And subsubsections. +-\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} +-\let\appsubsubsecentry=\numsubsubsecentry +-\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} +- +-% This parameter controls the indentation of the various levels. +-% Same as \defaultparindent. +-\newdimen\tocindent \tocindent = 15pt +- +-% Now for the actual typesetting. In all these, #1 is the text and #2 is the +-% page number. +-% +-% If the toc has to be broken over pages, we want it to be at chapters +-% if at all possible; hence the \penalty. +-\def\dochapentry#1#2{% +- \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip +- \begingroup +- \chapentryfonts +- \tocentry{#1}{\dopageno\bgroup#2\egroup}% +- \endgroup +- \nobreak\vskip .25\baselineskip plus.1\baselineskip +-} +- +-\def\dosecentry#1#2{\begingroup +- \secentryfonts \leftskip=\tocindent +- \tocentry{#1}{\dopageno\bgroup#2\egroup}% +-\endgroup} +- +-\def\dosubsecentry#1#2{\begingroup +- \subsecentryfonts \leftskip=2\tocindent +- \tocentry{#1}{\dopageno\bgroup#2\egroup}% +-\endgroup} +- +-\def\dosubsubsecentry#1#2{\begingroup +- \subsubsecentryfonts \leftskip=3\tocindent +- \tocentry{#1}{\dopageno\bgroup#2\egroup}% +-\endgroup} +- +-% We use the same \entry macro as for the index entries. +-\let\tocentry = \entry +- +-% Space between chapter (or whatever) number and the title. +-\def\labelspace{\hskip1em \relax} +- +-\def\dopageno#1{{\rm #1}} +-\def\doshortpageno#1{{\rm #1}} +- +-\def\chapentryfonts{\secfonts \rm} +-\def\secentryfonts{\textfonts} +-\def\subsecentryfonts{\textfonts} +-\def\subsubsecentryfonts{\textfonts} +- +- +-\message{environments,} +-% @foo ... @end foo. +- +-% @tex ... @end tex escapes into raw TeX temporarily. +-% One exception: @ is still an escape character, so that @end tex works. +-% But \@ or @@ will get a plain @ character. +- +-\envdef\tex{% +- \setupmarkupstyle{tex}% +- \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 +- \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 +- \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie +- \catcode `\%=14 +- \catcode `\+=\other +- \catcode `\"=\other +- \catcode `\|=\other +- \catcode `\<=\other +- \catcode `\>=\other +- \catcode `\`=\other +- \catcode `\'=\other +- \escapechar=`\\ +- % +- % ' is active in math mode (mathcode"8000). So reset it, and all our +- % other math active characters (just in case), to plain's definitions. +- \mathactive +- % +- \let\b=\ptexb +- \let\bullet=\ptexbullet +- \let\c=\ptexc +- \let\,=\ptexcomma +- \let\.=\ptexdot +- \let\dots=\ptexdots +- \let\equiv=\ptexequiv +- \let\!=\ptexexclam +- \let\i=\ptexi +- \let\indent=\ptexindent +- \let\noindent=\ptexnoindent +- \let\{=\ptexlbrace +- \let\+=\tabalign +- \let\}=\ptexrbrace +- \let\/=\ptexslash +- \let\*=\ptexstar +- \let\t=\ptext +- \expandafter \let\csname top\endcsname=\ptextop % we've made it outer +- \let\frenchspacing=\plainfrenchspacing +- % +- \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% +- \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% +- \def\@{@}% +-} +-% There is no need to define \Etex. +- +-% Define @lisp ... @end lisp. +-% @lisp environment forms a group so it can rebind things, +-% including the definition of @end lisp (which normally is erroneous). +- +-% Amount to narrow the margins by for @lisp. +-\newskip\lispnarrowing \lispnarrowing=0.4in +- +-% This is the definition that ^^M gets inside @lisp, @example, and other +-% such environments. \null is better than a space, since it doesn't +-% have any width. +-\def\lisppar{\null\endgraf} +- +-% This space is always present above and below environments. +-\newskip\envskipamount \envskipamount = 0pt +- +-% Make spacing and below environment symmetrical. We use \parskip here +-% to help in doing that, since in @example-like environments \parskip +-% is reset to zero; thus the \afterenvbreak inserts no space -- but the +-% start of the next paragraph will insert \parskip. +-% +-\def\aboveenvbreak{{% +- % =10000 instead of <10000 because of a special case in \itemzzz and +- % \sectionheading, q.v. +- \ifnum \lastpenalty=10000 \else +- \advance\envskipamount by \parskip +- \endgraf +- \ifdim\lastskip<\envskipamount +- \removelastskip +- % it's not a good place to break if the last penalty was \nobreak +- % or better ... +- \ifnum\lastpenalty<10000 \penalty-50 \fi +- \vskip\envskipamount +- \fi +- \fi +-}} +- +-\let\afterenvbreak = \aboveenvbreak +- +-% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will +-% also clear it, so that its embedded environments do the narrowing again. +-\let\nonarrowing=\relax +- +-% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +-% environment contents. +-\font\circle=lcircle10 +-\newdimen\circthick +-\newdimen\cartouter\newdimen\cartinner +-\newskip\normbskip\newskip\normpskip\newskip\normlskip +-\circthick=\fontdimen8\circle +-% +-\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth +-\def\ctr{{\hskip 6pt\circle\char'010}} +-\def\cbl{{\circle\char'012\hskip -6pt}} +-\def\cbr{{\hskip 6pt\circle\char'011}} +-\def\carttop{\hbox to \cartouter{\hskip\lskip +- \ctl\leaders\hrule height\circthick\hfil\ctr +- \hskip\rskip}} +-\def\cartbot{\hbox to \cartouter{\hskip\lskip +- \cbl\leaders\hrule height\circthick\hfil\cbr +- \hskip\rskip}} +-% +-\newskip\lskip\newskip\rskip +- +-\envdef\cartouche{% +- \ifhmode\par\fi % can't be in the midst of a paragraph. +- \startsavinginserts +- \lskip=\leftskip \rskip=\rightskip +- \leftskip=0pt\rightskip=0pt % we want these *outside*. +- \cartinner=\hsize \advance\cartinner by-\lskip +- \advance\cartinner by-\rskip +- \cartouter=\hsize +- \advance\cartouter by 18.4pt % allow for 3pt kerns on either +- % side, and for 6pt waste from +- % each corner char, and rule thickness +- \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip +- % +- % If this cartouche directly follows a sectioning command, we need the +- % \parskip glue (backspaced over by default) or the cartouche can +- % collide with the section heading. +- \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi +- % +- \vbox\bgroup +- \baselineskip=0pt\parskip=0pt\lineskip=0pt +- \carttop +- \hbox\bgroup +- \hskip\lskip +- \vrule\kern3pt +- \vbox\bgroup +- \kern3pt +- \hsize=\cartinner +- \baselineskip=\normbskip +- \lineskip=\normlskip +- \parskip=\normpskip +- \vskip -\parskip +- \comment % For explanation, see the end of def\group. +-} +-\def\Ecartouche{% +- \ifhmode\par\fi +- \kern3pt +- \egroup +- \kern3pt\vrule +- \hskip\rskip +- \egroup +- \cartbot +- \egroup +- \checkinserts +-} +- +- +-% This macro is called at the beginning of all the @example variants, +-% inside a group. +-\newdimen\nonfillparindent +-\def\nonfillstart{% +- \aboveenvbreak +- \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy +- \sepspaces % Make spaces be word-separators rather than space tokens. +- \let\par = \lisppar % don't ignore blank lines +- \obeylines % each line of input is a line of output +- \parskip = 0pt +- % Turn off paragraph indentation but redefine \indent to emulate +- % the normal \indent. +- \nonfillparindent=\parindent +- \parindent = 0pt +- \let\indent\nonfillindent +- % +- \emergencystretch = 0pt % don't try to avoid overfull boxes +- \ifx\nonarrowing\relax +- \advance \leftskip by \lispnarrowing +- \exdentamount=\lispnarrowing +- \else +- \let\nonarrowing = \relax +- \fi +- \let\exdent=\nofillexdent +-} +- +-\begingroup +-\obeyspaces +-% We want to swallow spaces (but not other tokens) after the fake +-% @indent in our nonfill-environments, where spaces are normally +-% active and set to @tie, resulting in them not being ignored after +-% @indent. +-\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}% +-\gdef\nonfillindentcheck{% +-\ifx\temp % +-\expandafter\nonfillindentgobble% +-\else% +-\leavevmode\nonfillindentbox% +-\fi% +-}% +-\endgroup +-\def\nonfillindentgobble#1{\nonfillindent} +-\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}} +- +-% If you want all examples etc. small: @set dispenvsize small. +-% If you want even small examples the full size: @set dispenvsize nosmall. +-% This affects the following displayed environments: +-% @example, @display, @format, @lisp +-% +-\def\smallword{small} +-\def\nosmallword{nosmall} +-\let\SETdispenvsize\relax +-\def\setnormaldispenv{% +- \ifx\SETdispenvsize\smallword +- % end paragraph for sake of leading, in case document has no blank +- % line. This is redundant with what happens in \aboveenvbreak, but +- % we need to do it before changing the fonts, and it's inconvenient +- % to change the fonts afterward. +- \ifnum \lastpenalty=10000 \else \endgraf \fi +- \smallexamplefonts \rm +- \fi +-} +-\def\setsmalldispenv{% +- \ifx\SETdispenvsize\nosmallword +- \else +- \ifnum \lastpenalty=10000 \else \endgraf \fi +- \smallexamplefonts \rm +- \fi +-} +- +-% We often define two environments, @foo and @smallfoo. +-% Let's do it in one command. #1 is the env name, #2 the definition. +-\def\makedispenvdef#1#2{% +- \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% +- \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% +- \expandafter\let\csname E#1\endcsname \afterenvbreak +- \expandafter\let\csname Esmall#1\endcsname \afterenvbreak +-} +- +-% Define two environment synonyms (#1 and #2) for an environment. +-\def\maketwodispenvdef#1#2#3{% +- \makedispenvdef{#1}{#3}% +- \makedispenvdef{#2}{#3}% +-} +-% +-% @lisp: indented, narrowed, typewriter font; +-% @example: same as @lisp. +-% +-% @smallexample and @smalllisp: use smaller fonts. +-% Originally contributed by Pavel@xerox. +-% +-\maketwodispenvdef{lisp}{example}{% +- \nonfillstart +- \tt\setupmarkupstyle{example}% +- \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. +- \gobble % eat return +-} +-% @display/@smalldisplay: same as @lisp except keep current font. +-% +-\makedispenvdef{display}{% +- \nonfillstart +- \gobble +-} +- +-% @format/@smallformat: same as @display except don't narrow margins. +-% +-\makedispenvdef{format}{% +- \let\nonarrowing = t% +- \nonfillstart +- \gobble +-} +- +-% @flushleft: same as @format, but doesn't obey \SETdispenvsize. +-\envdef\flushleft{% +- \let\nonarrowing = t% +- \nonfillstart +- \gobble +-} +-\let\Eflushleft = \afterenvbreak +- +-% @flushright. +-% +-\envdef\flushright{% +- \let\nonarrowing = t% +- \nonfillstart +- \advance\leftskip by 0pt plus 1fill\relax +- \gobble +-} +-\let\Eflushright = \afterenvbreak +- +- +-% @raggedright does more-or-less normal line breaking but no right +-% justification. From plain.tex. Don't stretch around special +-% characters in urls in this environment, since the stretch at the right +-% should be enough. +-\envdef\raggedright{% +- \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax +- \def\urefprestretchamount{0pt}% +- \def\urefpoststretchamount{0pt}% +-} +-\let\Eraggedright\par +- +-\envdef\raggedleft{% +- \parindent=0pt \leftskip0pt plus2em +- \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt +- \hbadness=10000 % Last line will usually be underfull, so turn off +- % badness reporting. +-} +-\let\Eraggedleft\par +- +-\envdef\raggedcenter{% +- \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em +- \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt +- \hbadness=10000 % Last line will usually be underfull, so turn off +- % badness reporting. +-} +-\let\Eraggedcenter\par +- +- +-% @quotation does normal linebreaking (hence we can't use \nonfillstart) +-% and narrows the margins. We keep \parskip nonzero in general, since +-% we're doing normal filling. So, when using \aboveenvbreak and +-% \afterenvbreak, temporarily make \parskip 0. +-% +-\makedispenvdef{quotation}{\quotationstart} +-% +-\def\quotationstart{% +- \indentedblockstart % same as \indentedblock, but increase right margin too. +- \ifx\nonarrowing\relax +- \advance\rightskip by \lispnarrowing +- \fi +- \parsearg\quotationlabel +-} +- +-% We have retained a nonzero parskip for the environment, since we're +-% doing normal filling. +-% +-\def\Equotation{% +- \par +- \ifx\quotationauthor\thisisundefined\else +- % indent a bit. +- \leftline{\kern 2\leftskip \sl ---\quotationauthor}% +- \fi +- {\parskip=0pt \afterenvbreak}% +-} +-\def\Esmallquotation{\Equotation} +- +-% If we're given an argument, typeset it in bold with a colon after. +-\def\quotationlabel#1{% +- \def\temp{#1}% +- \ifx\temp\empty \else +- {\bf #1: }% +- \fi +-} +- +-% @indentedblock is like @quotation, but indents only on the left and +-% has no optional argument. +-% +-\makedispenvdef{indentedblock}{\indentedblockstart} +-% +-\def\indentedblockstart{% +- {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip +- \parindent=0pt +- % +- % @cartouche defines \nonarrowing to inhibit narrowing at next level down. +- \ifx\nonarrowing\relax +- \advance\leftskip by \lispnarrowing +- \exdentamount = \lispnarrowing +- \else +- \let\nonarrowing = \relax +- \fi +-} +- +-% Keep a nonzero parskip for the environment, since we're doing normal filling. +-% +-\def\Eindentedblock{% +- \par +- {\parskip=0pt \afterenvbreak}% +-} +-\def\Esmallindentedblock{\Eindentedblock} +- +- +-% LaTeX-like @verbatim...@end verbatim and @verb{...} +-% If we want to allow any as delimiter, +-% we need the curly braces so that makeinfo sees the @verb command, eg: +-% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org +-% +-% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. +-% +-% [Knuth] p.344; only we need to do the other characters Texinfo sets +-% active too. Otherwise, they get lost as the first character on a +-% verbatim line. +-\def\dospecials{% +- \do\ \do\\\do\{\do\}\do\$\do\&% +- \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% +- \do\<\do\>\do\|\do\@\do+\do\"% +- % Don't do the quotes -- if we do, @set txicodequoteundirected and +- % @set txicodequotebacktick will not have effect on @verb and +- % @verbatim, and ?` and !` ligatures won't get disabled. +- %\do\`\do\'% +-} +-% +-% [Knuth] p. 380 +-\def\uncatcodespecials{% +- \def\do##1{\catcode`##1=\other}\dospecials} +-% +-% Setup for the @verb command. +-% +-% Eight spaces for a tab +-\begingroup +- \catcode`\^^I=\active +- \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} +-\endgroup +-% +-\def\setupverb{% +- \tt % easiest (and conventionally used) font for verbatim +- \def\par{\leavevmode\endgraf}% +- \setupmarkupstyle{verb}% +- \tabeightspaces +- % Respect line breaks, +- % print special symbols as themselves, and +- % make each space count +- % must do in this order: +- \obeylines \uncatcodespecials \sepspaces +-} +- +-% Setup for the @verbatim environment +-% +-% Real tab expansion. +-\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount +-% +-% We typeset each line of the verbatim in an \hbox, so we can handle +-% tabs. The \global is in case the verbatim line starts with an accent, +-% or some other command that starts with a begin-group. Otherwise, the +-% entire \verbbox would disappear at the corresponding end-group, before +-% it is typeset. Meanwhile, we can't have nested verbatim commands +-% (can we?), so the \global won't be overwriting itself. +-\newbox\verbbox +-\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} +-% +-\begingroup +- \catcode`\^^I=\active +- \gdef\tabexpand{% +- \catcode`\^^I=\active +- \def^^I{\leavevmode\egroup +- \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab +- \divide\dimen\verbbox by\tabw +- \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw +- \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw +- \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox +- }% +- } +-\endgroup +- +-% start the verbatim environment. +-\def\setupverbatim{% +- \let\nonarrowing = t% +- \nonfillstart +- \tt % easiest (and conventionally used) font for verbatim +- % The \leavevmode here is for blank lines. Otherwise, we would +- % never \starttabox and the \egroup would end verbatim mode. +- \def\par{\leavevmode\egroup\box\verbbox\endgraf}% +- \tabexpand +- \setupmarkupstyle{verbatim}% +- % Respect line breaks, +- % print special symbols as themselves, and +- % make each space count. +- % Must do in this order: +- \obeylines \uncatcodespecials \sepspaces +- \everypar{\starttabbox}% +-} +- +-% Do the @verb magic: verbatim text is quoted by unique +-% delimiter characters. Before first delimiter expect a +-% right brace, after last delimiter expect closing brace: +-% +-% \def\doverb'{'#1'}'{#1} +-% +-% [Knuth] p. 382; only eat outer {} +-\begingroup +- \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other +- \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] +-\endgroup +-% +-\def\verb{\begingroup\setupverb\doverb} +-% +-% +-% Do the @verbatim magic: define the macro \doverbatim so that +-% the (first) argument ends when '@end verbatim' is reached, ie: +-% +-% \def\doverbatim#1@end verbatim{#1} +-% +-% For Texinfo it's a lot easier than for LaTeX, +-% because texinfo's \verbatim doesn't stop at '\end{verbatim}': +-% we need not redefine '\', '{' and '}'. +-% +-% Inspired by LaTeX's verbatim command set [latex.ltx] +-% +-\begingroup +- \catcode`\ =\active +- \obeylines % +- % ignore everything up to the first ^^M, that's the newline at the end +- % of the @verbatim input line itself. Otherwise we get an extra blank +- % line in the output. +- \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% +- % We really want {...\end verbatim} in the body of the macro, but +- % without the active space; thus we have to use \xdef and \gobble. +-\endgroup +-% +-\envdef\verbatim{% +- \setupverbatim\doverbatim +-} +-\let\Everbatim = \afterenvbreak +- +- +-% @verbatiminclude FILE - insert text of file in verbatim environment. +-% +-\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} +-% +-\def\doverbatiminclude#1{% +- {% +- \makevalueexpandable +- \setupverbatim +- \indexnofonts % Allow `@@' and other weird things in file names. +- \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% +- \input #1 +- \afterenvbreak +- }% +-} +- +-% @copying ... @end copying. +-% Save the text away for @insertcopying later. +-% +-% We save the uninterpreted tokens, rather than creating a box. +-% Saving the text in a box would be much easier, but then all the +-% typesetting commands (@smallbook, font changes, etc.) have to be done +-% beforehand -- and a) we want @copying to be done first in the source +-% file; b) letting users define the frontmatter in as flexible order as +-% possible is very desirable. +-% +-\def\copying{\checkenv{}\begingroup\scanargctxt\docopying} +-\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} +-% +-\def\insertcopying{% +- \begingroup +- \parindent = 0pt % paragraph indentation looks wrong on title page +- \scanexp\copyingtext +- \endgroup +-} +- +- +-\message{defuns,} +-% @defun etc. +- +-\newskip\defbodyindent \defbodyindent=.4in +-\newskip\defargsindent \defargsindent=50pt +-\newskip\deflastargmargin \deflastargmargin=18pt +-\newcount\defunpenalty +- +-% Start the processing of @deffn: +-\def\startdefun{% +- \ifnum\lastpenalty<10000 +- \medbreak +- \defunpenalty=10003 % Will keep this @deffn together with the +- % following @def command, see below. +- \else +- % If there are two @def commands in a row, we'll have a \nobreak, +- % which is there to keep the function description together with its +- % header. But if there's nothing but headers, we need to allow a +- % break somewhere. Check specifically for penalty 10002, inserted +- % by \printdefunline, instead of 10000, since the sectioning +- % commands also insert a nobreak penalty, and we don't want to allow +- % a break between a section heading and a defun. +- % +- % As a further refinement, we avoid "club" headers by signalling +- % with penalty of 10003 after the very first @deffn in the +- % sequence (see above), and penalty of 10002 after any following +- % @def command. +- \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi +- % +- % Similarly, after a section heading, do not allow a break. +- % But do insert the glue. +- \medskip % preceded by discardable penalty, so not a breakpoint +- \fi +- % +- \parindent=0in +- \advance\leftskip by \defbodyindent +- \exdentamount=\defbodyindent +-} +- +-\def\dodefunx#1{% +- % First, check whether we are in the right environment: +- \checkenv#1% +- % +- % As above, allow line break if we have multiple x headers in a row. +- % It's not a great place, though. +- \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi +- % +- % And now, it's time to reuse the body of the original defun: +- \expandafter\gobbledefun#1% +-} +-\def\gobbledefun#1\startdefun{} +- +-% \printdefunline \deffnheader{text} +-% +-\def\printdefunline#1#2{% +- \begingroup +- % call \deffnheader: +- #1#2 \endheader +- % common ending: +- \interlinepenalty = 10000 +- \advance\rightskip by 0pt plus 1fil\relax +- \endgraf +- \nobreak\vskip -\parskip +- \penalty\defunpenalty % signal to \startdefun and \dodefunx +- % Some of the @defun-type tags do not enable magic parentheses, +- % rendering the following check redundant. But we don't optimize. +- \checkparencounts +- \endgroup +-} +- +-\def\Edefun{\endgraf\medbreak} +- +-% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; +-% the only thing remaining is to define \deffnheader. +-% +-\def\makedefun#1{% +- \expandafter\let\csname E#1\endcsname = \Edefun +- \edef\temp{\noexpand\domakedefun +- \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% +- \temp +-} +- +-% \domakedefun \deffn \deffnx \deffnheader +-% +-% Define \deffn and \deffnx, without parameters. +-% \deffnheader has to be defined explicitly. +-% +-\def\domakedefun#1#2#3{% +- \envdef#1{% +- \startdefun +- \doingtypefnfalse % distinguish typed functions from all else +- \parseargusing\activeparens{\printdefunline#3}% +- }% +- \def#2{\dodefunx#1}% +- \def#3% +-} +- +-\newif\ifdoingtypefn % doing typed function? +-\newif\ifrettypeownline % typeset return type on its own line? +- +-% @deftypefnnewline on|off says whether the return type of typed functions +-% are printed on their own line. This affects @deftypefn, @deftypefun, +-% @deftypeop, and @deftypemethod. +-% +-\parseargdef\deftypefnnewline{% +- \def\temp{#1}% +- \ifx\temp\onword +- \expandafter\let\csname SETtxideftypefnnl\endcsname +- = \empty +- \else\ifx\temp\offword +- \expandafter\let\csname SETtxideftypefnnl\endcsname +- = \relax +- \else +- \errhelp = \EMsimple +- \errmessage{Unknown @txideftypefnnl value `\temp', +- must be on|off}% +- \fi\fi +-} +- +-% Untyped functions: +- +-% @deffn category name args +-\makedefun{deffn}{\deffngeneral{}} +- +-% @deffn category class name args +-\makedefun{defop}#1 {\defopon{#1\ \putwordon}} +- +-% \defopon {category on}class name args +-\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } +- +-% \deffngeneral {subind}category name args +-% +-\def\deffngeneral#1#2 #3 #4\endheader{% +- % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. +- \dosubind{fn}{\code{#3}}{#1}% +- \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% +-} +- +-% Typed functions: +- +-% @deftypefn category type name args +-\makedefun{deftypefn}{\deftypefngeneral{}} +- +-% @deftypeop category class type name args +-\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} +- +-% \deftypeopon {category on}class type name args +-\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } +- +-% \deftypefngeneral {subind}category type name args +-% +-\def\deftypefngeneral#1#2 #3 #4 #5\endheader{% +- \dosubind{fn}{\code{#4}}{#1}% +- \doingtypefntrue +- \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +-} +- +-% Typed variables: +- +-% @deftypevr category type var args +-\makedefun{deftypevr}{\deftypecvgeneral{}} +- +-% @deftypecv category class type var args +-\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} +- +-% \deftypecvof {category of}class type var args +-\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } +- +-% \deftypecvgeneral {subind}category type var args +-% +-\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% +- \dosubind{vr}{\code{#4}}{#1}% +- \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +-} +- +-% Untyped variables: +- +-% @defvr category var args +-\makedefun{defvr}#1 {\deftypevrheader{#1} {} } +- +-% @defcv category class var args +-\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} +- +-% \defcvof {category of}class var args +-\def\defcvof#1#2 {\deftypecvof{#1}#2 {} } +- +-% Types: +- +-% @deftp category name args +-\makedefun{deftp}#1 #2 #3\endheader{% +- \doind{tp}{\code{#2}}% +- \defname{#1}{}{#2}\defunargs{#3\unskip}% +-} +- +-% Remaining @defun-like shortcuts: +-\makedefun{defun}{\deffnheader{\putwordDeffunc} } +-\makedefun{defmac}{\deffnheader{\putwordDefmac} } +-\makedefun{defspec}{\deffnheader{\putwordDefspec} } +-\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } +-\makedefun{defvar}{\defvrheader{\putwordDefvar} } +-\makedefun{defopt}{\defvrheader{\putwordDefopt} } +-\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } +-\makedefun{defmethod}{\defopon\putwordMethodon} +-\makedefun{deftypemethod}{\deftypeopon\putwordMethodon} +-\makedefun{defivar}{\defcvof\putwordInstanceVariableof} +-\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} +- +-% \defname, which formats the name of the @def (not the args). +-% #1 is the category, such as "Function". +-% #2 is the return type, if any. +-% #3 is the function name. +-% +-% We are followed by (but not passed) the arguments, if any. +-% +-\def\defname#1#2#3{% +- \par +- % Get the values of \leftskip and \rightskip as they were outside the @def... +- \advance\leftskip by -\defbodyindent +- % +- % Determine if we are typesetting the return type of a typed function +- % on a line by itself. +- \rettypeownlinefalse +- \ifdoingtypefn % doing a typed function specifically? +- % then check user option for putting return type on its own line: +- \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else +- \rettypeownlinetrue +- \fi +- \fi +- % +- % How we'll format the category name. Putting it in brackets helps +- % distinguish it from the body text that may end up on the next line +- % just below it. +- \def\temp{#1}% +- \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} +- % +- % Figure out line sizes for the paragraph shape. We'll always have at +- % least two. +- \tempnum = 2 +- % +- % The first line needs space for \box0; but if \rightskip is nonzero, +- % we need only space for the part of \box0 which exceeds it: +- \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip +- % +- % If doing a return type on its own line, we'll have another line. +- \ifrettypeownline +- \advance\tempnum by 1 +- \def\maybeshapeline{0in \hsize}% +- \else +- \def\maybeshapeline{}% +- \fi +- % +- % The continuations: +- \dimen2=\hsize \advance\dimen2 by -\defargsindent +- % +- % The final paragraph shape: +- \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 +- % +- % Put the category name at the right margin. +- \noindent +- \hbox to 0pt{% +- \hfil\box0 \kern-\hsize +- % \hsize has to be shortened this way: +- \kern\leftskip +- % Intentionally do not respect \rightskip, since we need the space. +- }% +- % +- % Allow all lines to be underfull without complaint: +- \tolerance=10000 \hbadness=10000 +- \exdentamount=\defbodyindent +- {% +- % defun fonts. We use typewriter by default (used to be bold) because: +- % . we're printing identifiers, they should be in tt in principle. +- % . in languages with many accents, such as Czech or French, it's +- % common to leave accents off identifiers. The result looks ok in +- % tt, but exceedingly strange in rm. +- % . we don't want -- and --- to be treated as ligatures. +- % . this still does not fix the ?` and !` ligatures, but so far no +- % one has made identifiers using them :). +- \df \tt +- \def\temp{#2}% text of the return type +- \ifx\temp\empty\else +- \tclose{\temp}% typeset the return type +- \ifrettypeownline +- % put return type on its own line; prohibit line break following: +- \hfil\vadjust{\nobreak}\break +- \else +- \space % type on same line, so just followed by a space +- \fi +- \fi % no return type +- #3% output function name +- }% +- {\rm\enskip}% hskip 0.5 em of \tenrm +- % +- \boldbrax +- % arguments will be output next, if any. +-} +- +-% Print arguments in slanted roman (not ttsl), inconsistently with using +-% tt for the name. This is because literal text is sometimes needed in +-% the argument list (groff manual), and ttsl and tt are not very +-% distinguishable. Prevent hyphenation at `-' chars. +-% +-\def\defunargs#1{% +- % use sl by default (not ttsl), +- % tt for the names. +- \df \sl \hyphenchar\font=0 +- % +- % On the other hand, if an argument has two dashes (for instance), we +- % want a way to get ttsl. We used to recommend @var for that, so +- % leave the code in, but it's strange for @var to lead to typewriter. +- % Nowadays we recommend @code, since the difference between a ttsl hyphen +- % and a tt hyphen is pretty tiny. @code also disables ?` !`. +- \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% +- #1% +- \sl\hyphenchar\font=45 +-} +- +-% We want ()&[] to print specially on the defun line. +-% +-\def\activeparens{% +- \catcode`\(=\active \catcode`\)=\active +- \catcode`\[=\active \catcode`\]=\active +- \catcode`\&=\active +-} +- +-% Make control sequences which act like normal parenthesis chars. +-\let\lparen = ( \let\rparen = ) +- +-% Be sure that we always have a definition for `(', etc. For example, +-% if the fn name has parens in it, \boldbrax will not be in effect yet, +-% so TeX would otherwise complain about undefined control sequence. +-{ +- \activeparens +- \global\let(=\lparen \global\let)=\rparen +- \global\let[=\lbrack \global\let]=\rbrack +- \global\let& = \& +- +- \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} +- \gdef\magicamp{\let&=\amprm} +-} +- +-\newcount\parencount +- +-% If we encounter &foo, then turn on ()-hacking afterwards +-\newif\ifampseen +-\def\amprm#1 {\ampseentrue{\bf\ }} +- +-\def\parenfont{% +- \ifampseen +- % At the first level, print parens in roman, +- % otherwise use the default font. +- \ifnum \parencount=1 \rm \fi +- \else +- % The \sf parens (in \boldbrax) actually are a little bolder than +- % the contained text. This is especially needed for [ and ] . +- \sf +- \fi +-} +-\def\infirstlevel#1{% +- \ifampseen +- \ifnum\parencount=1 +- #1% +- \fi +- \fi +-} +-\def\bfafterword#1 {#1 \bf} +- +-\def\opnr{% +- \global\advance\parencount by 1 +- {\parenfont(}% +- \infirstlevel \bfafterword +-} +-\def\clnr{% +- {\parenfont)}% +- \infirstlevel \sl +- \global\advance\parencount by -1 +-} +- +-\newcount\brackcount +-\def\lbrb{% +- \global\advance\brackcount by 1 +- {\bf[}% +-} +-\def\rbrb{% +- {\bf]}% +- \global\advance\brackcount by -1 +-} +- +-\def\checkparencounts{% +- \ifnum\parencount=0 \else \badparencount \fi +- \ifnum\brackcount=0 \else \badbrackcount \fi +-} +-% these should not use \errmessage; the glibc manual, at least, actually +-% has such constructs (when documenting function pointers). +-\def\badparencount{% +- \message{Warning: unbalanced parentheses in @def...}% +- \global\parencount=0 +-} +-\def\badbrackcount{% +- \message{Warning: unbalanced square brackets in @def...}% +- \global\brackcount=0 +-} +- +- +-\message{macros,} +-% @macro. +- +-% To do this right we need a feature of e-TeX, \scantokens, +-% which we arrange to emulate with a temporary file in ordinary TeX. +-\ifx\eTeXversion\thisisundefined +- \newwrite\macscribble +- \def\scantokens#1{% +- \toks0={#1}% +- \immediate\openout\macscribble=\jobname.tmp +- \immediate\write\macscribble{\the\toks0}% +- \immediate\closeout\macscribble +- \input \jobname.tmp +- } +-\fi +- +-\def\scanmacro#1{\begingroup +- \newlinechar`\^^M +- \let\xeatspaces\eatspaces +- % +- % Undo catcode changes of \startcontents and \doprintindex +- % When called from @insertcopying or (short)caption, we need active +- % backslash to get it printed correctly. Previously, we had +- % \catcode`\\=\other instead. We'll see whether a problem appears +- % with macro expansion. --kasal, 19aug04 +- \catcode`\@=0 \catcode`\\=\active \escapechar=`\@ +- % +- % ... and for \example: +- \spaceisspace +- % +- % The \empty here causes a following catcode 5 newline to be eaten as +- % part of reading whitespace after a control sequence. It does not +- % eat a catcode 13 newline. There's no good way to handle the two +- % cases (untried: maybe e-TeX's \everyeof could help, though plain TeX +- % would then have different behavior). See the Macro Details node in +- % the manual for the workaround we recommend for macros and +- % line-oriented commands. +- % +- \scantokens{#1\empty}% +-\endgroup} +- +-\def\scanexp#1{% +- \edef\temp{\noexpand\scanmacro{#1}}% +- \temp +-} +- +-\newcount\paramno % Count of parameters +-\newtoks\macname % Macro name +-\newif\ifrecursive % Is it recursive? +- +-% List of all defined macros in the form +-% \definedummyword\macro1\definedummyword\macro2... +-% Currently is also contains all @aliases; the list can be split +-% if there is a need. +-\def\macrolist{} +- +-% Add the macro to \macrolist +-\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} +-\def\addtomacrolistxxx#1{% +- \toks0 = \expandafter{\macrolist\definedummyword#1}% +- \xdef\macrolist{\the\toks0}% +-} +- +-% Utility routines. +-% This does \let #1 = #2, with \csnames; that is, +-% \let \csname#1\endcsname = \csname#2\endcsname +-% (except of course we have to play expansion games). +-% +-\def\cslet#1#2{% +- \expandafter\let +- \csname#1\expandafter\endcsname +- \csname#2\endcsname +-} +- +-% Trim leading and trailing spaces off a string. +-% Concepts from aro-bend problem 15 (see CTAN). +-{\catcode`\@=11 +-\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +-\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +-\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +-\def\unbrace#1{#1} +-\unbrace{\gdef\trim@@@ #1 } #2@{#1} +-} +- +-% Trim a single trailing ^^M off a string. +-{\catcode`\^^M=\other \catcode`\Q=3% +-\gdef\eatcr #1{\eatcra #1Q^^MQ}% +-\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +-\gdef\eatcrb#1Q#2Q{#1}% +-} +- +-% Macro bodies are absorbed as an argument in a context where +-% all characters are catcode 10, 11 or 12, except \ which is active +-% (as in normal texinfo). It is necessary to change the definition of \ +-% to recognize macro arguments; this is the job of \mbodybackslash. +-% +-% Non-ASCII encodings make 8-bit characters active, so un-activate +-% them to avoid their expansion. Must do this non-globally, to +-% confine the change to the current group. +-% +-% It's necessary to have hard CRs when the macro is executed. This is +-% done by making ^^M (\endlinechar) catcode 12 when reading the macro +-% body, and then making it the \newlinechar in \scanmacro. +-% +-\def\scanctxt{% used as subroutine +- \catcode`\"=\other +- \catcode`\+=\other +- \catcode`\<=\other +- \catcode`\>=\other +- \catcode`\@=\other +- \catcode`\^=\other +- \catcode`\_=\other +- \catcode`\|=\other +- \catcode`\~=\other +- \ifx\declaredencoding\ascii \else \setnonasciicharscatcodenonglobal\other \fi +-} +- +-\def\scanargctxt{% used for copying and captions, not macros. +- \scanctxt +- \catcode`\\=\other +- \catcode`\^^M=\other +-} +- +-\def\macrobodyctxt{% used for @macro definitions +- \scanctxt +- \catcode`\{=\other +- \catcode`\}=\other +- \catcode`\^^M=\other +- \usembodybackslash +-} +- +-\def\macroargctxt{% used when scanning invocations +- \scanctxt +- \catcode`\\=0 +-} +-% why catcode 0 for \ in the above? To recognize \\ \{ \} as "escapes" +-% for the single characters \ { }. Thus, we end up with the "commands" +-% that would be written @\ @{ @} in a Texinfo document. +-% +-% We already have @{ and @}. For @\, we define it here, and only for +-% this purpose, to produce a typewriter backslash (so, the @\ that we +-% define for @math can't be used with @macro calls): +-% +-\def\\{\normalbackslash}% +-% +-% We would like to do this for \, too, since that is what makeinfo does. +-% But it is not possible, because Texinfo already has a command @, for a +-% cedilla accent. Documents must use @comma{} instead. +-% +-% \anythingelse will almost certainly be an error of some kind. +- +- +-% \mbodybackslash is the definition of \ in @macro bodies. +-% It maps \foo\ => \csname macarg.foo\endcsname => #N +-% where N is the macro parameter number. +-% We define \csname macarg.\endcsname to be \realbackslash, so +-% \\ in macro replacement text gets you a backslash. +-% +-{\catcode`@=0 @catcode`@\=@active +- @gdef@usembodybackslash{@let\=@mbodybackslash} +- @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +-} +-\expandafter\def\csname macarg.\endcsname{\realbackslash} +- +-\def\margbackslash#1{\char`\#1 } +- +-\def\macro{\recursivefalse\parsearg\macroxxx} +-\def\rmacro{\recursivetrue\parsearg\macroxxx} +- +-\def\macroxxx#1{% +- \getargs{#1}% now \macname is the macname and \argl the arglist +- \ifx\argl\empty % no arguments +- \paramno=0\relax +- \else +- \expandafter\parsemargdef \argl;% +- \if\paramno>256\relax +- \ifx\eTeXversion\thisisundefined +- \errhelp = \EMsimple +- \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} +- \fi +- \fi +- \fi +- \if1\csname ismacro.\the\macname\endcsname +- \message{Warning: redefining \the\macname}% +- \else +- \expandafter\ifx\csname \the\macname\endcsname \relax +- \else \errmessage{Macro name \the\macname\space already defined}\fi +- \global\cslet{macsave.\the\macname}{\the\macname}% +- \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% +- \addtomacrolist{\the\macname}% +- \fi +- \begingroup \macrobodyctxt +- \ifrecursive \expandafter\parsermacbody +- \else \expandafter\parsemacbody +- \fi} +- +-\parseargdef\unmacro{% +- \if1\csname ismacro.#1\endcsname +- \global\cslet{#1}{macsave.#1}% +- \global\expandafter\let \csname ismacro.#1\endcsname=0% +- % Remove the macro name from \macrolist: +- \begingroup +- \expandafter\let\csname#1\endcsname \relax +- \let\definedummyword\unmacrodo +- \xdef\macrolist{\macrolist}% +- \endgroup +- \else +- \errmessage{Macro #1 not defined}% +- \fi +-} +- +-% Called by \do from \dounmacro on each macro. The idea is to omit any +-% macro definitions that have been changed to \relax. +-% +-\def\unmacrodo#1{% +- \ifx #1\relax +- % remove this +- \else +- \noexpand\definedummyword \noexpand#1% +- \fi +-} +- +-% This makes use of the obscure feature that if the last token of a +-% is #, then the preceding argument is delimited by +-% an opening brace, and that opening brace is not consumed. +-\def\getargs#1{\getargsxxx#1{}} +-\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +-\def\getmacname#1 #2\relax{\macname={#1}} +-\def\getmacargs#1{\def\argl{#1}} +- +-% For macro processing make @ a letter so that we can make Texinfo private macro names. +-\edef\texiatcatcode{\the\catcode`\@} +-\catcode `@=11\relax +- +-% Parse the optional {params} list. Set up \paramno and \paramlist +-% so \defmacro knows what to do. Define \macarg.BLAH for each BLAH +-% in the params list to some hook where the argument is to be expanded. If +-% there are less than 10 arguments that hook is to be replaced by ##N where N +-% is the position in that list, that is to say the macro arguments are to be +-% defined `a la TeX in the macro body. +-% +-% That gets used by \mbodybackslash (above). +-% +-% We need to get `macro parameter char #' into several definitions. +-% The technique used is stolen from LaTeX: let \hash be something +-% unexpandable, insert that wherever you need a #, and then redefine +-% it to # just before using the token list produced. +-% +-% The same technique is used to protect \eatspaces till just before +-% the macro is used. +-% +-% If there are 10 or more arguments, a different technique is used, where the +-% hook remains in the body, and when macro is to be expanded the body is +-% processed again to replace the arguments. +-% +-% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the +-% argument N value and then \edef the body (nothing else will expand because of +-% the catcode regime underwhich the body was input). +-% +-% If you compile with TeX (not eTeX), and you have macros with 10 or more +-% arguments, you need that no macro has more than 256 arguments, otherwise an +-% error is produced. +-\def\parsemargdef#1;{% +- \paramno=0\def\paramlist{}% +- \let\hash\relax +- \let\xeatspaces\relax +- \parsemargdefxxx#1,;,% +- % In case that there are 10 or more arguments we parse again the arguments +- % list to set new definitions for the \macarg.BLAH macros corresponding to +- % each BLAH argument. It was anyhow needed to parse already once this list +- % in order to count the arguments, and as macros with at most 9 arguments +- % are by far more frequent than macro with 10 or more arguments, defining +- % twice the \macarg.BLAH macros does not cost too much processing power. +- \ifnum\paramno<10\relax\else +- \paramno0\relax +- \parsemmanyargdef@@#1,;,% 10 or more arguments +- \fi +-} +-\def\parsemargdefxxx#1,{% +- \if#1;\let\next=\relax +- \else \let\next=\parsemargdefxxx +- \advance\paramno by 1 +- \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname +- {\xeatspaces{\hash\the\paramno}}% +- \edef\paramlist{\paramlist\hash\the\paramno,}% +- \fi\next} +- +-\def\parsemmanyargdef@@#1,{% +- \if#1;\let\next=\relax +- \else +- \let\next=\parsemmanyargdef@@ +- \edef\tempb{\eatspaces{#1}}% +- \expandafter\def\expandafter\tempa +- \expandafter{\csname macarg.\tempb\endcsname}% +- % Note that we need some extra \noexpand\noexpand, this is because we +- % don't want \the to be expanded in the \parsermacbody as it uses an +- % \xdef . +- \expandafter\edef\tempa +- {\noexpand\noexpand\noexpand\the\toks\the\paramno}% +- \advance\paramno by 1\relax +- \fi\next} +- +-% These two commands read recursive and nonrecursive macro bodies. +-% (They're different since rec and nonrec macros end differently.) +-% +- +-\catcode `\@\texiatcatcode +-\long\def\parsemacbody#1@end macro% +-{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +-\long\def\parsermacbody#1@end rmacro% +-{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}% +-\catcode `\@=11\relax +- +-\let\endargs@\relax +-\let\nil@\relax +-\def\nilm@{\nil@}% +-\long\def\nillm@{\nil@}% +- +-% This macro is expanded during the Texinfo macro expansion, not during its +-% definition. It gets all the arguments values and assigns them to macros +-% macarg.ARGNAME +-% +-% #1 is the macro name +-% #2 is the list of argument names +-% #3 is the list of argument values +-\def\getargvals@#1#2#3{% +- \def\macargdeflist@{}% +- \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. +- \def\paramlist{#2,\nil@}% +- \def\macroname{#1}% +- \begingroup +- \macroargctxt +- \def\argvaluelist{#3,\nil@}% +- \def\@tempa{#3}% +- \ifx\@tempa\empty +- \setemptyargvalues@ +- \else +- \getargvals@@ +- \fi +-} +- +-% +-\def\getargvals@@{% +- \ifx\paramlist\nilm@ +- % Some sanity check needed here that \argvaluelist is also empty. +- \ifx\argvaluelist\nillm@ +- \else +- \errhelp = \EMsimple +- \errmessage{Too many arguments in macro `\macroname'!}% +- \fi +- \let\next\macargexpandinbody@ +- \else +- \ifx\argvaluelist\nillm@ +- % No more arguments values passed to macro. Set remaining named-arg +- % macros to empty. +- \let\next\setemptyargvalues@ +- \else +- % pop current arg name into \@tempb +- \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% +- \expandafter\@tempa\expandafter{\paramlist}% +- % pop current argument value into \@tempc +- \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% +- \expandafter\@tempa\expandafter{\argvaluelist}% +- % Here \@tempb is the current arg name and \@tempc is the current arg value. +- % First place the new argument macro definition into \@tempd +- \expandafter\macname\expandafter{\@tempc}% +- \expandafter\let\csname macarg.\@tempb\endcsname\relax +- \expandafter\def\expandafter\@tempe\expandafter{% +- \csname macarg.\@tempb\endcsname}% +- \edef\@tempd{\long\def\@tempe{\the\macname}}% +- \push@\@tempd\macargdeflist@ +- \let\next\getargvals@@ +- \fi +- \fi +- \next +-} +- +-\def\push@#1#2{% +- \expandafter\expandafter\expandafter\def +- \expandafter\expandafter\expandafter#2% +- \expandafter\expandafter\expandafter{% +- \expandafter#1#2}% +-} +- +-% Replace arguments by their values in the macro body, and place the result +-% in macro \@tempa +-\def\macvalstoargs@{% +- % To do this we use the property that token registers that are \the'ed +- % within an \edef expand only once. So we are going to place all argument +- % values into respective token registers. +- % +- % First we save the token context, and initialize argument numbering. +- \begingroup +- \paramno0\relax +- % Then, for each argument number #N, we place the corresponding argument +- % value into a new token list register \toks#N +- \expandafter\putargsintokens@\saveparamlist@,;,% +- % Then, we expand the body so that argument are replaced by their +- % values. The trick for values not to be expanded themselves is that they +- % are within tokens and that tokens expand only once in an \edef . +- \edef\@tempc{\csname mac.\macroname .body\endcsname}% +- % Now we restore the token stack pointer to free the token list registers +- % which we have used, but we make sure that expanded body is saved after +- % group. +- \expandafter +- \endgroup +- \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% +- } +- +-\def\macargexpandinbody@{% +- %% Define the named-macro outside of this group and then close this group. +- \expandafter +- \endgroup +- \macargdeflist@ +- % First the replace in body the macro arguments by their values, the result +- % is in \@tempa . +- \macvalstoargs@ +- % Then we point at the \norecurse or \gobble (for recursive) macro value +- % with \@tempb . +- \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname +- % Depending on whether it is recursive or not, we need some tailing +- % \egroup . +- \ifx\@tempb\gobble +- \let\@tempc\relax +- \else +- \let\@tempc\egroup +- \fi +- % And now we do the real job: +- \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% +- \@tempd +-} +- +-\def\putargsintokens@#1,{% +- \if#1;\let\next\relax +- \else +- \let\next\putargsintokens@ +- % First we allocate the new token list register, and give it a temporary +- % alias \@tempb . +- \toksdef\@tempb\the\paramno +- % Then we place the argument value into that token list register. +- \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname +- \expandafter\@tempb\expandafter{\@tempa}% +- \advance\paramno by 1\relax +- \fi +- \next +-} +- +-% Save the token stack pointer into macro #1 +-\def\texisavetoksstackpoint#1{\edef#1{\the\@cclvi}} +-% Restore the token stack pointer from number in macro #1 +-\def\texirestoretoksstackpoint#1{\expandafter\mathchardef\expandafter\@cclvi#1\relax} +-% newtoks that can be used non \outer . +-\def\texinonouternewtoks{\alloc@ 5\toks \toksdef \@cclvi} +- +-% Tailing missing arguments are set to empty +-\def\setemptyargvalues@{% +- \ifx\paramlist\nilm@ +- \let\next\macargexpandinbody@ +- \else +- \expandafter\setemptyargvaluesparser@\paramlist\endargs@ +- \let\next\setemptyargvalues@ +- \fi +- \next +-} +- +-\def\setemptyargvaluesparser@#1,#2\endargs@{% +- \expandafter\def\expandafter\@tempa\expandafter{% +- \expandafter\def\csname macarg.#1\endcsname{}}% +- \push@\@tempa\macargdeflist@ +- \def\paramlist{#2}% +-} +- +-% #1 is the element target macro +-% #2 is the list macro +-% #3,#4\endargs@ is the list value +-\def\pop@#1#2#3,#4\endargs@{% +- \def#1{#3}% +- \def#2{#4}% +-} +-\long\def\longpop@#1#2#3,#4\endargs@{% +- \long\def#1{#3}% +- \long\def#2{#4}% +-} +- +-% This defines a Texinfo @macro. There are eight cases: recursive and +-% nonrecursive macros of zero, one, up to nine, and many arguments. +-% Much magic with \expandafter here. +-% \xdef is used so that macro definitions will survive the file +-% they're defined in; @include reads the file inside a group. +-% +-\def\defmacro{% +- \let\hash=##% convert placeholders to macro parameter chars +- \ifrecursive +- \ifcase\paramno +- % 0 +- \expandafter\xdef\csname\the\macname\endcsname{% +- \noexpand\scanmacro{\temp}}% +- \or % 1 +- \expandafter\xdef\csname\the\macname\endcsname{% +- \bgroup\noexpand\macroargctxt +- \noexpand\braceorline +- \expandafter\noexpand\csname\the\macname xxx\endcsname}% +- \expandafter\xdef\csname\the\macname xxx\endcsname##1{% +- \egroup\noexpand\scanmacro{\temp}}% +- \else +- \ifnum\paramno<10\relax % at most 9 +- \expandafter\xdef\csname\the\macname\endcsname{% +- \bgroup\noexpand\macroargctxt +- \noexpand\csname\the\macname xx\endcsname}% +- \expandafter\xdef\csname\the\macname xx\endcsname##1{% +- \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% +- \expandafter\expandafter +- \expandafter\xdef +- \expandafter\expandafter +- \csname\the\macname xxx\endcsname +- \paramlist{\egroup\noexpand\scanmacro{\temp}}% +- \else % 10 or more +- \expandafter\xdef\csname\the\macname\endcsname{% +- \noexpand\getargvals@{\the\macname}{\argl}% +- }% +- \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp +- \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble +- \fi +- \fi +- \else +- \ifcase\paramno +- % 0 +- \expandafter\xdef\csname\the\macname\endcsname{% +- \noexpand\norecurse{\the\macname}% +- \noexpand\scanmacro{\temp}\egroup}% +- \or % 1 +- \expandafter\xdef\csname\the\macname\endcsname{% +- \bgroup\noexpand\macroargctxt +- \noexpand\braceorline +- \expandafter\noexpand\csname\the\macname xxx\endcsname}% +- \expandafter\xdef\csname\the\macname xxx\endcsname##1{% +- \egroup +- \noexpand\norecurse{\the\macname}% +- \noexpand\scanmacro{\temp}\egroup}% +- \else % at most 9 +- \ifnum\paramno<10\relax +- \expandafter\xdef\csname\the\macname\endcsname{% +- \bgroup\noexpand\macroargctxt +- \expandafter\noexpand\csname\the\macname xx\endcsname}% +- \expandafter\xdef\csname\the\macname xx\endcsname##1{% +- \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}% +- \expandafter\expandafter +- \expandafter\xdef +- \expandafter\expandafter +- \csname\the\macname xxx\endcsname +- \paramlist{% +- \egroup +- \noexpand\norecurse{\the\macname}% +- \noexpand\scanmacro{\temp}\egroup}% +- \else % 10 or more: +- \expandafter\xdef\csname\the\macname\endcsname{% +- \noexpand\getargvals@{\the\macname}{\argl}% +- }% +- \global\expandafter\let\csname mac.\the\macname .body\endcsname\temp +- \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\norecurse +- \fi +- \fi +- \fi} +- +-\catcode `\@\texiatcatcode\relax +- +-\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} +- +-% \braceorline decides whether the next nonwhitespace character is a +-% {. If so it reads up to the closing }, if not, it reads the whole +-% line. Whatever was read is then fed to the next control sequence +-% as an argument (by \parsebrace or \parsearg). +-% +-\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} +-\def\braceorlinexxx{% +- \ifx\nchar\bgroup\else +- \expandafter\parsearg +- \fi \macnamexxx} +- +- +-% @alias. +-% We need some trickery to remove the optional spaces around the equal +-% sign. Make them active and then expand them all to nothing. +-% +-\def\alias{\parseargusing\obeyspaces\aliasxxx} +-\def\aliasxxx #1{\aliasyyy#1\relax} +-\def\aliasyyy #1=#2\relax{% +- {% +- \expandafter\let\obeyedspace=\empty +- \addtomacrolist{#1}% +- \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% +- }% +- \next +-} +- +- +-\message{cross references,} +- +-\newwrite\auxfile +-\newif\ifhavexrefs % True if xref values are known. +-\newif\ifwarnedxrefs % True if we warned once that they aren't known. +- +-% @inforef is relatively simple. +-\def\inforef #1{\inforefzzz #1,,,,**} +-\def\inforefzzz #1,#2,#3,#4**{% +- \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, +- node \samp{\ignorespaces#1{}}} +- +-% @node's only job in TeX is to define \lastnode, which is used in +-% cross-references. The @node line might or might not have commas, and +-% might or might not have spaces before the first comma, like: +-% @node foo , bar , ... +-% We don't want such trailing spaces in the node name. +-% +-\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} +-% +-% also remove a trailing comma, in case of something like this: +-% @node Help-Cross, , , Cross-refs +-\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} +-\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} +- +-\let\nwnode=\node +-\let\lastnode=\empty +- +-% Write a cross-reference definition for the current node. #1 is the +-% type (Ynumbered, Yappendix, Ynothing). +-% +-\def\donoderef#1{% +- \ifx\lastnode\empty\else +- \setref{\lastnode}{#1}% +- \global\let\lastnode=\empty +- \fi +-} +- +-% @anchor{NAME} -- define xref target at arbitrary point. +-% +-\newcount\savesfregister +-% +-\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +-\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +-\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} +- +-% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an +-% anchor), which consists of three parts: +-% 1) NAME-title - the current sectioning name taken from \lastsection, +-% or the anchor name. +-% 2) NAME-snt - section number and type, passed as the SNT arg, or +-% empty for anchors. +-% 3) NAME-pg - the page number. +-% +-% This is called from \donoderef, \anchor, and \dofloat. In the case of +-% floats, there is an additional part, which is not written here: +-% 4) NAME-lof - the text as it should appear in a @listoffloats. +-% +-\def\setref#1#2{% +- \pdfmkdest{#1}% +- \iflinks +- {% +- \atdummies % preserve commands, but don't expand them +- \edef\writexrdef##1##2{% +- \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef +- ##1}{##2}}% these are parameters of \writexrdef +- }% +- \toks0 = \expandafter{\lastsection}% +- \immediate \writexrdef{title}{\the\toks0 }% +- \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. +- \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout +- }% +- \fi +-} +- +-% @xrefautosectiontitle on|off says whether @section(ing) names are used +-% automatically in xrefs, if the third arg is not explicitly specified. +-% This was provided as a "secret" @set xref-automatic-section-title +-% variable, now it's official. +-% +-\parseargdef\xrefautomaticsectiontitle{% +- \def\temp{#1}% +- \ifx\temp\onword +- \expandafter\let\csname SETxref-automatic-section-title\endcsname +- = \empty +- \else\ifx\temp\offword +- \expandafter\let\csname SETxref-automatic-section-title\endcsname +- = \relax +- \else +- \errhelp = \EMsimple +- \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', +- must be on|off}% +- \fi\fi +-} +- +-% +-% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is +-% the node name, #2 the name of the Info cross-reference, #3 the printed +-% node name, #4 the name of the Info file, #5 the name of the printed +-% manual. All but the node name can be omitted. +-% +-\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]} +-\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]} +-\def\ref#1{\xrefX[#1,,,,,,,]} +-% +-\newbox\toprefbox +-\newbox\printedrefnamebox +-\newbox\infofilenamebox +-\newbox\printedmanualbox +-% +-\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup +- \unsepspaces +- % +- % Get args without leading/trailing spaces. +- \def\printedrefname{\ignorespaces #3}% +- \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% +- % +- \def\infofilename{\ignorespaces #4}% +- \setbox\infofilenamebox = \hbox{\infofilename\unskip}% +- % +- \def\printedmanual{\ignorespaces #5}% +- \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% +- % +- % If the printed reference name (arg #3) was not explicitly given in +- % the @xref, figure out what we want to use. +- \ifdim \wd\printedrefnamebox = 0pt +- % No printed node name was explicitly given. +- \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax +- % Not auto section-title: use node name inside the square brackets. +- \def\printedrefname{\ignorespaces #1}% +- \else +- % Auto section-title: use chapter/section title inside +- % the square brackets if we have it. +- \ifdim \wd\printedmanualbox > 0pt +- % It is in another manual, so we don't have it; use node name. +- \def\printedrefname{\ignorespaces #1}% +- \else +- \ifhavexrefs +- % We (should) know the real title if we have the xref values. +- \def\printedrefname{\refx{#1-title}{}}% +- \else +- % Otherwise just copy the Info node name. +- \def\printedrefname{\ignorespaces #1}% +- \fi% +- \fi +- \fi +- \fi +- % +- % Make link in pdf output. +- \ifpdf +- {\indexnofonts +- \turnoffactive +- \makevalueexpandable +- % This expands tokens, so do it after making catcode changes, so _ +- % etc. don't get their TeX definitions. This ignores all spaces in +- % #4, including (wrongly) those in the middle of the filename. +- \getfilename{#4}% +- % +- % This (wrongly) does not take account of leading or trailing +- % spaces in #1, which should be ignored. +- \edef\pdfxrefdest{#1}% +- \ifx\pdfxrefdest\empty +- \def\pdfxrefdest{Top}% no empty targets +- \else +- \txiescapepdf\pdfxrefdest % escape PDF special chars +- \fi +- % +- \leavevmode +- \startlink attr{/Border [0 0 0]}% +- \ifnum\filenamelength>0 +- goto file{\the\filename.pdf} name{\pdfxrefdest}% +- \else +- goto name{\pdfmkpgn{\pdfxrefdest}}% +- \fi +- }% +- \setcolor{\linkcolor}% +- \fi +- % +- % Float references are printed completely differently: "Figure 1.2" +- % instead of "[somenode], p.3". We distinguish them by the +- % LABEL-title being set to a magic string. +- {% +- % Have to otherify everything special to allow the \csname to +- % include an _ in the xref name, etc. +- \indexnofonts +- \turnoffactive +- \expandafter\global\expandafter\let\expandafter\Xthisreftitle +- \csname XR#1-title\endcsname +- }% +- \iffloat\Xthisreftitle +- % If the user specified the print name (third arg) to the ref, +- % print it instead of our usual "Figure 1.2". +- \ifdim\wd\printedrefnamebox = 0pt +- \refx{#1-snt}{}% +- \else +- \printedrefname +- \fi +- % +- % If the user also gave the printed manual name (fifth arg), append +- % "in MANUALNAME". +- \ifdim \wd\printedmanualbox > 0pt +- \space \putwordin{} \cite{\printedmanual}% +- \fi +- \else +- % node/anchor (non-float) references. +- % +- % If we use \unhbox to print the node names, TeX does not insert +- % empty discretionaries after hyphens, which means that it will not +- % find a line break at a hyphen in a node names. Since some manuals +- % are best written with fairly long node names, containing hyphens, +- % this is a loss. Therefore, we give the text of the node name +- % again, so it is as if TeX is seeing it for the first time. +- % +- \ifdim \wd\printedmanualbox > 0pt +- % Cross-manual reference with a printed manual name. +- % +- \crossmanualxref{\cite{\printedmanual\unskip}}% +- % +- \else\ifdim \wd\infofilenamebox > 0pt +- % Cross-manual reference with only an info filename (arg 4), no +- % printed manual name (arg 5). This is essentially the same as +- % the case above; we output the filename, since we have nothing else. +- % +- \crossmanualxref{\code{\infofilename\unskip}}% +- % +- \else +- % Reference within this manual. +- % +- % _ (for example) has to be the character _ for the purposes of the +- % control sequence corresponding to the node, but it has to expand +- % into the usual \leavevmode...\vrule stuff for purposes of +- % printing. So we \turnoffactive for the \refx-snt, back on for the +- % printing, back off for the \refx-pg. +- {\turnoffactive +- % Only output a following space if the -snt ref is nonempty; for +- % @unnumbered and @anchor, it won't be. +- \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% +- \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi +- }% +- % output the `[mynode]' via the macro below so it can be overridden. +- \xrefprintnodename\printedrefname +- % +- % But we always want a comma and a space: +- ,\space +- % +- % output the `page 3'. +- \turnoffactive \putwordpage\tie\refx{#1-pg}{}% +- \fi\fi +- \fi +- \endlink +-\endgroup} +- +-% Output a cross-manual xref to #1. Used just above (twice). +-% +-% Only include the text "Section ``foo'' in" if the foo is neither +-% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply +-% "see The Foo Manual", the idea being to refer to the whole manual. +-% +-% But, this being TeX, we can't easily compare our node name against the +-% string "Top" while ignoring the possible spaces before and after in +-% the input. By adding the arbitrary 7sp below, we make it much less +-% likely that a real node name would have the same width as "Top" (e.g., +-% in a monospaced font). Hopefully it will never happen in practice. +-% +-% For the same basic reason, we retypeset the "Top" at every +-% reference, since the current font is indeterminate. +-% +-\def\crossmanualxref#1{% +- \setbox\toprefbox = \hbox{Top\kern7sp}% +- \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% +- \ifdim \wd2 > 7sp % nonempty? +- \ifdim \wd2 = \wd\toprefbox \else % same as Top? +- \putwordSection{} ``\printedrefname'' \putwordin{}\space +- \fi +- \fi +- #1% +-} +- +-% This macro is called from \xrefX for the `[nodename]' part of xref +-% output. It's a separate macro only so it can be changed more easily, +-% since square brackets don't work well in some documents. Particularly +-% one that Bob is working on :). +-% +-\def\xrefprintnodename#1{[#1]} +- +-% Things referred to by \setref. +-% +-\def\Ynothing{} +-\def\Yomitfromtoc{} +-\def\Ynumbered{% +- \ifnum\secno=0 +- \putwordChapter@tie \the\chapno +- \else \ifnum\subsecno=0 +- \putwordSection@tie \the\chapno.\the\secno +- \else \ifnum\subsubsecno=0 +- \putwordSection@tie \the\chapno.\the\secno.\the\subsecno +- \else +- \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno +- \fi\fi\fi +-} +-\def\Yappendix{% +- \ifnum\secno=0 +- \putwordAppendix@tie @char\the\appendixno{}% +- \else \ifnum\subsecno=0 +- \putwordSection@tie @char\the\appendixno.\the\secno +- \else \ifnum\subsubsecno=0 +- \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno +- \else +- \putwordSection@tie +- @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno +- \fi\fi\fi +-} +- +-% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME. +-% If its value is nonempty, SUFFIX is output afterward. +-% +-\def\refx#1#2{% +- {% +- \indexnofonts +- \otherbackslash +- \expandafter\global\expandafter\let\expandafter\thisrefX +- \csname XR#1\endcsname +- }% +- \ifx\thisrefX\relax +- % If not defined, say something at least. +- \angleleft un\-de\-fined\angleright +- \iflinks +- \ifhavexrefs +- {\toks0 = {#1}% avoid expansion of possibly-complex value +- \message{\linenumber Undefined cross reference `\the\toks0'.}}% +- \else +- \ifwarnedxrefs\else +- \global\warnedxrefstrue +- \message{Cross reference values unknown; you must run TeX again.}% +- \fi +- \fi +- \fi +- \else +- % It's defined, so just use it. +- \thisrefX +- \fi +- #2% Output the suffix in any case. +-} +- +-% This is the macro invoked by entries in the aux file. Usually it's +-% just a \def (we prepend XR to the control sequence name to avoid +-% collisions). But if this is a float type, we have more work to do. +-% +-\def\xrdef#1#2{% +- {% The node name might contain 8-bit characters, which in our current +- % implementation are changed to commands like @'e. Don't let these +- % mess up the control sequence name. +- \indexnofonts +- \turnoffactive +- \xdef\safexrefname{#1}% +- }% +- % +- \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% remember this xref +- % +- % Was that xref control sequence that we just defined for a float? +- \expandafter\iffloat\csname XR\safexrefname\endcsname +- % it was a float, and we have the (safe) float type in \iffloattype. +- \expandafter\let\expandafter\floatlist +- \csname floatlist\iffloattype\endcsname +- % +- % Is this the first time we've seen this float type? +- \expandafter\ifx\floatlist\relax +- \toks0 = {\do}% yes, so just \do +- \else +- % had it before, so preserve previous elements in list. +- \toks0 = \expandafter{\floatlist\do}% +- \fi +- % +- % Remember this xref in the control sequence \floatlistFLOATTYPE, +- % for later use in \listoffloats. +- \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 +- {\safexrefname}}% +- \fi +-} +- +-% Read the last existing aux file, if any. No error if none exists. +-% +-\def\tryauxfile{% +- \openin 1 \jobname.aux +- \ifeof 1 \else +- \readdatafile{aux}% +- \global\havexrefstrue +- \fi +- \closein 1 +-} +- +-\def\setupdatafile{% +- \catcode`\^^@=\other +- \catcode`\^^A=\other +- \catcode`\^^B=\other +- \catcode`\^^C=\other +- \catcode`\^^D=\other +- \catcode`\^^E=\other +- \catcode`\^^F=\other +- \catcode`\^^G=\other +- \catcode`\^^H=\other +- \catcode`\^^K=\other +- \catcode`\^^L=\other +- \catcode`\^^N=\other +- \catcode`\^^P=\other +- \catcode`\^^Q=\other +- \catcode`\^^R=\other +- \catcode`\^^S=\other +- \catcode`\^^T=\other +- \catcode`\^^U=\other +- \catcode`\^^V=\other +- \catcode`\^^W=\other +- \catcode`\^^X=\other +- \catcode`\^^Z=\other +- \catcode`\^^[=\other +- \catcode`\^^\=\other +- \catcode`\^^]=\other +- \catcode`\^^^=\other +- \catcode`\^^_=\other +- % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. +- % in xref tags, i.e., node names. But since ^^e4 notation isn't +- % supported in the main text, it doesn't seem desirable. Furthermore, +- % that is not enough: for node names that actually contain a ^ +- % character, we would end up writing a line like this: 'xrdef {'hat +- % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first +- % argument, and \hat is not an expandable control sequence. It could +- % all be worked out, but why? Either we support ^^ or we don't. +- % +- % The other change necessary for this was to define \auxhat: +- % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter +- % and then to call \auxhat in \setq. +- % +- \catcode`\^=\other +- % +- % Special characters. Should be turned off anyway, but... +- \catcode`\~=\other +- \catcode`\[=\other +- \catcode`\]=\other +- \catcode`\"=\other +- \catcode`\_=\other +- \catcode`\|=\other +- \catcode`\<=\other +- \catcode`\>=\other +- \catcode`\$=\other +- \catcode`\#=\other +- \catcode`\&=\other +- \catcode`\%=\other +- \catcode`+=\other % avoid \+ for paranoia even though we've turned it off +- % +- % This is to support \ in node names and titles, since the \ +- % characters end up in a \csname. It's easier than +- % leaving it active and making its active definition an actual \ +- % character. What I don't understand is why it works in the *value* +- % of the xrdef. Seems like it should be a catcode12 \, and that +- % should not typeset properly. But it works, so I'm moving on for +- % now. --karl, 15jan04. +- \catcode`\\=\other +- % +- % Make the characters 128-255 be printing characters. +- {% +- \count1=128 +- \def\loop{% +- \catcode\count1=\other +- \advance\count1 by 1 +- \ifnum \count1<256 \loop \fi +- }% +- }% +- % +- % @ is our escape character in .aux files, and we need braces. +- \catcode`\{=1 +- \catcode`\}=2 +- \catcode`\@=0 +-} +- +-\def\readdatafile#1{% +-\begingroup +- \setupdatafile +- \input\jobname.#1 +-\endgroup} +- +- +-\message{insertions,} +-% including footnotes. +- +-\newcount \footnoteno +- +-% The trailing space in the following definition for supereject is +-% vital for proper filling; pages come out unaligned when you do a +-% pagealignmacro call if that space before the closing brace is +-% removed. (Generally, numeric constants should always be followed by a +-% space to prevent strange expansion errors.) +-\def\supereject{\par\penalty -20000\footnoteno =0 } +- +-% @footnotestyle is meaningful for Info output only. +-\let\footnotestyle=\comment +- +-{\catcode `\@=11 +-% +-% Auto-number footnotes. Otherwise like plain. +-\gdef\footnote{% +- \let\indent=\ptexindent +- \let\noindent=\ptexnoindent +- % +- \global\advance\footnoteno by \@ne +- \edef\thisfootno{$^{\the\footnoteno}$}% +- % +- % In case the footnote comes at the end of a sentence, preserve the +- % extra spacing after we do the footnote number. +- \let\@sf\empty +- \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi +- % +- % Remove inadvertent blank space before typesetting the footnote number. +- \unskip +- \thisfootno\@sf +- \dofootnote +-}% +- +-% Don't bother with the trickery in plain.tex to not require the +-% footnote text as a parameter. Our footnotes don't need to be so general. +-% +-% Oh yes, they do; otherwise, @ifset (and anything else that uses +-% \parseargline) fails inside footnotes because the tokens are fixed when +-% the footnote is read. --karl, 16nov96. +-% +-\gdef\dofootnote{% +- \insert\footins\bgroup +- % +- % Nested footnotes are not supported in TeX, that would take a lot +- % more work. (\startsavinginserts does not suffice.) +- \let\footnote=\errfootnote +- % +- % We want to typeset this text as a normal paragraph, even if the +- % footnote reference occurs in (for example) a display environment. +- % So reset some parameters. +- \hsize=\pagewidth +- \interlinepenalty\interfootnotelinepenalty +- \splittopskip\ht\strutbox % top baseline for broken footnotes +- \splitmaxdepth\dp\strutbox +- \floatingpenalty\@MM +- \leftskip\z@skip +- \rightskip\z@skip +- \spaceskip\z@skip +- \xspaceskip\z@skip +- \parindent\defaultparindent +- % +- \smallfonts \rm +- % +- % Because we use hanging indentation in footnotes, a @noindent appears +- % to exdent this text, so make it be a no-op. makeinfo does not use +- % hanging indentation so @noindent can still be needed within footnote +- % text after an @example or the like (not that this is good style). +- \let\noindent = \relax +- % +- % Hang the footnote text off the number. Use \everypar in case the +- % footnote extends for more than one paragraph. +- \everypar = {\hang}% +- \textindent{\thisfootno}% +- % +- % Don't crash into the line above the footnote text. Since this +- % expands into a box, it must come within the paragraph, lest it +- % provide a place where TeX can split the footnote. +- \footstrut +- % +- % Invoke rest of plain TeX footnote routine. +- \futurelet\next\fo@t +-} +-}%end \catcode `\@=11 +- +-\def\errfootnote{% +- \errhelp=\EMsimple +- \errmessage{Nested footnotes not supported in texinfo.tex, +- even though they work in makeinfo; sorry} +-} +- +-% In case a @footnote appears in a vbox, save the footnote text and create +-% the real \insert just after the vbox finished. Otherwise, the insertion +-% would be lost. +-% Similarly, if a @footnote appears inside an alignment, save the footnote +-% text to a box and make the \insert when a row of the table is finished. +-% And the same can be done for other insert classes. --kasal, 16nov03. +-% +-% Replace the \insert primitive by a cheating macro. +-% Deeper inside, just make sure that the saved insertions are not spilled +-% out prematurely. +-% +-\def\startsavinginserts{% +- \ifx \insert\ptexinsert +- \let\insert\saveinsert +- \else +- \let\checkinserts\relax +- \fi +-} +- +-% This \insert replacement works for both \insert\footins{foo} and +-% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. +-% +-\def\saveinsert#1{% +- \edef\next{\noexpand\savetobox \makeSAVEname#1}% +- \afterassignment\next +- % swallow the left brace +- \let\temp = +-} +-\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} +-\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} +- +-\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} +- +-\def\placesaveins#1{% +- \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname +- {\box#1}% +-} +- +-% eat @SAVE -- beware, all of them have catcode \other: +-{ +- \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) +- \gdef\gobblesave @SAVE{} +-} +- +-% initialization: +-\def\newsaveins #1{% +- \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% +- \next +-} +-\def\newsaveinsX #1{% +- \csname newbox\endcsname #1% +- \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts +- \checksaveins #1}% +-} +- +-% initialize: +-\let\checkinserts\empty +-\newsaveins\footins +-\newsaveins\margin +- +- +-% @image. We use the macros from epsf.tex to support this. +-% If epsf.tex is not installed and @image is used, we complain. +-% +-% Check for and read epsf.tex up front. If we read it only at @image +-% time, we might be inside a group, and then its definitions would get +-% undone and the next image would fail. +-\openin 1 = epsf.tex +-\ifeof 1 \else +- % Do not bother showing banner with epsf.tex v2.7k (available in +- % doc/epsf.tex and on ctan). +- \def\epsfannounce{\toks0 = }% +- \input epsf.tex +-\fi +-\closein 1 +-% +-% We will only complain once about lack of epsf.tex. +-\newif\ifwarnednoepsf +-\newhelp\noepsfhelp{epsf.tex must be installed for images to +- work. It is also included in the Texinfo distribution, or you can get +- it from ftp://tug.org/tex/epsf.tex.} +-% +-\def\image#1{% +- \ifx\epsfbox\thisisundefined +- \ifwarnednoepsf \else +- \errhelp = \noepsfhelp +- \errmessage{epsf.tex not found, images will be ignored}% +- \global\warnednoepsftrue +- \fi +- \else +- \imagexxx #1,,,,,\finish +- \fi +-} +-% +-% Arguments to @image: +-% #1 is (mandatory) image filename; we tack on .eps extension. +-% #2 is (optional) width, #3 is (optional) height. +-% #4 is (ignored optional) html alt text. +-% #5 is (ignored optional) extension. +-% #6 is just the usual extra ignored arg for parsing stuff. +-\newif\ifimagevmode +-\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup +- \catcode`\^^M = 5 % in case we're inside an example +- \normalturnoffactive % allow _ et al. in names +- % If the image is by itself, center it. +- \ifvmode +- \imagevmodetrue +- \else \ifx\centersub\centerV +- % for @center @image, we need a vbox so we can have our vertical space +- \imagevmodetrue +- \vbox\bgroup % vbox has better behavior than vtop herev +- \fi\fi +- % +- \ifimagevmode +- \nobreak\medskip +- % Usually we'll have text after the image which will insert +- % \parskip glue, so insert it here too to equalize the space +- % above and below. +- \nobreak\vskip\parskip +- \nobreak +- \fi +- % +- % Leave vertical mode so that indentation from an enclosing +- % environment such as @quotation is respected. +- % However, if we're at the top level, we don't want the +- % normal paragraph indentation. +- % On the other hand, if we are in the case of @center @image, we don't +- % want to start a paragraph, which will create a hsize-width box and +- % eradicate the centering. +- \ifx\centersub\centerV\else \noindent \fi +- % +- % Output the image. +- \ifpdf +- \dopdfimage{#1}{#2}{#3}% +- \else +- % \epsfbox itself resets \epsf?size at each figure. +- \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi +- \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi +- \epsfbox{#1.eps}% +- \fi +- % +- \ifimagevmode +- \medskip % space after a standalone image +- \fi +- \ifx\centersub\centerV \egroup \fi +-\endgroup} +- +- +-% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, +-% etc. We don't actually implement floating yet, we always include the +-% float "here". But it seemed the best name for the future. +-% +-\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} +- +-% There may be a space before second and/or third parameter; delete it. +-\def\eatcommaspace#1, {#1,} +- +-% #1 is the optional FLOATTYPE, the text label for this float, typically +-% "Figure", "Table", "Example", etc. Can't contain commas. If omitted, +-% this float will not be numbered and cannot be referred to. +-% +-% #2 is the optional xref label. Also must be present for the float to +-% be referable. +-% +-% #3 is the optional positioning argument; for now, it is ignored. It +-% will somehow specify the positions allowed to float to (here, top, bottom). +-% +-% We keep a separate counter for each FLOATTYPE, which we reset at each +-% chapter-level command. +-\let\resetallfloatnos=\empty +-% +-\def\dofloat#1,#2,#3,#4\finish{% +- \let\thiscaption=\empty +- \let\thisshortcaption=\empty +- % +- % don't lose footnotes inside @float. +- % +- % BEWARE: when the floats start float, we have to issue warning whenever an +- % insert appears inside a float which could possibly float. --kasal, 26may04 +- % +- \startsavinginserts +- % +- % We can't be used inside a paragraph. +- \par +- % +- \vtop\bgroup +- \def\floattype{#1}% +- \def\floatlabel{#2}% +- \def\floatloc{#3}% we do nothing with this yet. +- % +- \ifx\floattype\empty +- \let\safefloattype=\empty +- \else +- {% +- % the floattype might have accents or other special characters, +- % but we need to use it in a control sequence name. +- \indexnofonts +- \turnoffactive +- \xdef\safefloattype{\floattype}% +- }% +- \fi +- % +- % If label is given but no type, we handle that as the empty type. +- \ifx\floatlabel\empty \else +- % We want each FLOATTYPE to be numbered separately (Figure 1, +- % Table 1, Figure 2, ...). (And if no label, no number.) +- % +- \expandafter\getfloatno\csname\safefloattype floatno\endcsname +- \global\advance\floatno by 1 +- % +- {% +- % This magic value for \lastsection is output by \setref as the +- % XREFLABEL-title value. \xrefX uses it to distinguish float +- % labels (which have a completely different output format) from +- % node and anchor labels. And \xrdef uses it to construct the +- % lists of floats. +- % +- \edef\lastsection{\floatmagic=\safefloattype}% +- \setref{\floatlabel}{Yfloat}% +- }% +- \fi +- % +- % start with \parskip glue, I guess. +- \vskip\parskip +- % +- % Don't suppress indentation if a float happens to start a section. +- \restorefirstparagraphindent +-} +- +-% we have these possibilities: +-% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap +-% @float Foo,lbl & no caption: Foo 1.1 +-% @float Foo & @caption{Cap}: Foo: Cap +-% @float Foo & no caption: Foo +-% @float ,lbl & Caption{Cap}: 1.1: Cap +-% @float ,lbl & no caption: 1.1 +-% @float & @caption{Cap}: Cap +-% @float & no caption: +-% +-\def\Efloat{% +- \let\floatident = \empty +- % +- % In all cases, if we have a float type, it comes first. +- \ifx\floattype\empty \else \def\floatident{\floattype}\fi +- % +- % If we have an xref label, the number comes next. +- \ifx\floatlabel\empty \else +- \ifx\floattype\empty \else % if also had float type, need tie first. +- \appendtomacro\floatident{\tie}% +- \fi +- % the number. +- \appendtomacro\floatident{\chaplevelprefix\the\floatno}% +- \fi +- % +- % Start the printed caption with what we've constructed in +- % \floatident, but keep it separate; we need \floatident again. +- \let\captionline = \floatident +- % +- \ifx\thiscaption\empty \else +- \ifx\floatident\empty \else +- \appendtomacro\captionline{: }% had ident, so need a colon between +- \fi +- % +- % caption text. +- \appendtomacro\captionline{\scanexp\thiscaption}% +- \fi +- % +- % If we have anything to print, print it, with space before. +- % Eventually this needs to become an \insert. +- \ifx\captionline\empty \else +- \vskip.5\parskip +- \captionline +- % +- % Space below caption. +- \vskip\parskip +- \fi +- % +- % If have an xref label, write the list of floats info. Do this +- % after the caption, to avoid chance of it being a breakpoint. +- \ifx\floatlabel\empty \else +- % Write the text that goes in the lof to the aux file as +- % \floatlabel-lof. Besides \floatident, we include the short +- % caption if specified, else the full caption if specified, else nothing. +- {% +- \atdummies +- % +- % since we read the caption text in the macro world, where ^^M +- % is turned into a normal character, we have to scan it back, so +- % we don't write the literal three characters "^^M" into the aux file. +- \scanexp{% +- \xdef\noexpand\gtemp{% +- \ifx\thisshortcaption\empty +- \thiscaption +- \else +- \thisshortcaption +- \fi +- }% +- }% +- \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident +- \ifx\gtemp\empty \else : \gtemp \fi}}% +- }% +- \fi +- \egroup % end of \vtop +- % +- % place the captured inserts +- % +- % BEWARE: when the floats start floating, we have to issue warning +- % whenever an insert appears inside a float which could possibly +- % float. --kasal, 26may04 +- % +- \checkinserts +-} +- +-% Append the tokens #2 to the definition of macro #1, not expanding either. +-% +-\def\appendtomacro#1#2{% +- \expandafter\def\expandafter#1\expandafter{#1#2}% +-} +- +-% @caption, @shortcaption +-% +-\def\caption{\docaption\thiscaption} +-\def\shortcaption{\docaption\thisshortcaption} +-\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} +-\def\defcaption#1#2{\egroup \def#1{#2}} +- +-% The parameter is the control sequence identifying the counter we are +-% going to use. Create it if it doesn't exist and assign it to \floatno. +-\def\getfloatno#1{% +- \ifx#1\relax +- % Haven't seen this figure type before. +- \csname newcount\endcsname #1% +- % +- % Remember to reset this floatno at the next chap. +- \expandafter\gdef\expandafter\resetallfloatnos +- \expandafter{\resetallfloatnos #1=0 }% +- \fi +- \let\floatno#1% +-} +- +-% \setref calls this to get the XREFLABEL-snt value. We want an @xref +-% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we +-% first read the @float command. +-% +-\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% +- +-% Magic string used for the XREFLABEL-title value, so \xrefX can +-% distinguish floats from other xref types. +-\def\floatmagic{!!float!!} +- +-% #1 is the control sequence we are passed; we expand into a conditional +-% which is true if #1 represents a float ref. That is, the magic +-% \lastsection value which we \setref above. +-% +-\def\iffloat#1{\expandafter\doiffloat#1==\finish} +-% +-% #1 is (maybe) the \floatmagic string. If so, #2 will be the +-% (safe) float type for this float. We set \iffloattype to #2. +-% +-\def\doiffloat#1=#2=#3\finish{% +- \def\temp{#1}% +- \def\iffloattype{#2}% +- \ifx\temp\floatmagic +-} +- +-% @listoffloats FLOATTYPE - print a list of floats like a table of contents. +-% +-\parseargdef\listoffloats{% +- \def\floattype{#1}% floattype +- {% +- % the floattype might have accents or other special characters, +- % but we need to use it in a control sequence name. +- \indexnofonts +- \turnoffactive +- \xdef\safefloattype{\floattype}% +- }% +- % +- % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. +- \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax +- \ifhavexrefs +- % if the user said @listoffloats foo but never @float foo. +- \message{\linenumber No `\safefloattype' floats to list.}% +- \fi +- \else +- \begingroup +- \leftskip=\tocindent % indent these entries like a toc +- \let\do=\listoffloatsdo +- \csname floatlist\safefloattype\endcsname +- \endgroup +- \fi +-} +- +-% This is called on each entry in a list of floats. We're passed the +-% xref label, in the form LABEL-title, which is how we save it in the +-% aux file. We strip off the -title and look up \XRLABEL-lof, which +-% has the text we're supposed to typeset here. +-% +-% Figures without xref labels will not be included in the list (since +-% they won't appear in the aux file). +-% +-\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} +-\def\listoffloatsdoentry#1-title\finish{{% +- % Can't fully expand XR#1-lof because it can contain anything. Just +- % pass the control sequence. On the other hand, XR#1-pg is just the +- % page number, and we want to fully expand that so we can get a link +- % in pdf output. +- \toksA = \expandafter{\csname XR#1-lof\endcsname}% +- % +- % use the same \entry macro we use to generate the TOC and index. +- \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% +- \writeentry +-}} +- +- +-\message{localization,} +- +-% For single-language documents, @documentlanguage is usually given very +-% early, just after @documentencoding. Single argument is the language +-% (de) or locale (de_DE) abbreviation. +-% +-{ +- \catcode`\_ = \active +- \globaldefs=1 +-\parseargdef\documentlanguage{% +- \tex % read txi-??.tex file in plain TeX. +- % Read the file by the name they passed if it exists. +- \let_ = \normalunderscore % normal _ character for filename test +- \openin 1 txi-#1.tex +- \ifeof 1 +- \documentlanguagetrywithoutunderscore #1_\finish +- \else +- \globaldefs = 1 % everything in the txi-LL files needs to persist +- \input txi-#1.tex +- \fi +- \closein 1 +- \endgroup % end raw TeX +-} +-% +-% If they passed de_DE, and txi-de_DE.tex doesn't exist, +-% try txi-de.tex. +-% +-\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{% +- \openin 1 txi-#1.tex +- \ifeof 1 +- \errhelp = \nolanghelp +- \errmessage{Cannot read language file txi-#1.tex}% +- \else +- \globaldefs = 1 % everything in the txi-LL files needs to persist +- \input txi-#1.tex +- \fi +- \closein 1 +-} +-}% end of special _ catcode +-% +-\newhelp\nolanghelp{The given language definition file cannot be found or +-is empty. Maybe you need to install it? Putting it in the current +-directory should work if nowhere else does.} +- +-% This macro is called from txi-??.tex files; the first argument is the +-% \language name to set (without the "\lang@" prefix), the second and +-% third args are \{left,right}hyphenmin. +-% +-% The language names to pass are determined when the format is built. +-% See the etex.log file created at that time, e.g., +-% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log. +-% +-% With TeX Live 2008, etex now includes hyphenation patterns for all +-% available languages. This means we can support hyphenation in +-% Texinfo, at least to some extent. (This still doesn't solve the +-% accented characters problem.) +-% +-\catcode`@=11 +-\def\txisetlanguage#1#2#3{% +- % do not set the language if the name is undefined in the current TeX. +- \expandafter\ifx\csname lang@#1\endcsname \relax +- \message{no patterns for #1}% +- \else +- \global\language = \csname lang@#1\endcsname +- \fi +- % but there is no harm in adjusting the hyphenmin values regardless. +- \global\lefthyphenmin = #2\relax +- \global\righthyphenmin = #3\relax +-} +- +-% Helpers for encodings. +-% Set the catcode of characters 128 through 255 to the specified number. +-% +-\def\setnonasciicharscatcode#1{% +- \count255=128 +- \loop\ifnum\count255<256 +- \global\catcode\count255=#1\relax +- \advance\count255 by 1 +- \repeat +-} +- +-\def\setnonasciicharscatcodenonglobal#1{% +- \count255=128 +- \loop\ifnum\count255<256 +- \catcode\count255=#1\relax +- \advance\count255 by 1 +- \repeat +-} +- +-% @documentencoding sets the definition of non-ASCII characters +-% according to the specified encoding. +-% +-\parseargdef\documentencoding{% +- % Encoding being declared for the document. +- \def\declaredencoding{\csname #1.enc\endcsname}% +- % +- % Supported encodings: names converted to tokens in order to be able +- % to compare them with \ifx. +- \def\ascii{\csname US-ASCII.enc\endcsname}% +- \def\latnine{\csname ISO-8859-15.enc\endcsname}% +- \def\latone{\csname ISO-8859-1.enc\endcsname}% +- \def\lattwo{\csname ISO-8859-2.enc\endcsname}% +- \def\utfeight{\csname UTF-8.enc\endcsname}% +- % +- \ifx \declaredencoding \ascii +- \asciichardefs +- % +- \else \ifx \declaredencoding \lattwo +- \setnonasciicharscatcode\active +- \lattwochardefs +- % +- \else \ifx \declaredencoding \latone +- \setnonasciicharscatcode\active +- \latonechardefs +- % +- \else \ifx \declaredencoding \latnine +- \setnonasciicharscatcode\active +- \latninechardefs +- % +- \else \ifx \declaredencoding \utfeight +- \setnonasciicharscatcode\active +- \utfeightchardefs +- % +- \else +- \message{Unknown document encoding #1, ignoring.}% +- % +- \fi % utfeight +- \fi % latnine +- \fi % latone +- \fi % lattwo +- \fi % ascii +-} +- +-% A message to be logged when using a character that isn't available +-% the default font encoding (OT1). +-% +-\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}} +- +-% Take account of \c (plain) vs. \, (Texinfo) difference. +-\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} +- +-% First, make active non-ASCII characters in order for them to be +-% correctly categorized when TeX reads the replacement text of +-% macros containing the character definitions. +-\setnonasciicharscatcode\active +-% +-% Latin1 (ISO-8859-1) character definitions. +-\def\latonechardefs{% +- \gdef^^a0{\tie} +- \gdef^^a1{\exclamdown} +- \gdef^^a2{\missingcharmsg{CENT SIGN}} +- \gdef^^a3{{\pounds}} +- \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} +- \gdef^^a5{\missingcharmsg{YEN SIGN}} +- \gdef^^a6{\missingcharmsg{BROKEN BAR}} +- \gdef^^a7{\S} +- \gdef^^a8{\"{}} +- \gdef^^a9{\copyright} +- \gdef^^aa{\ordf} +- \gdef^^ab{\guillemetleft} +- \gdef^^ac{$\lnot$} +- \gdef^^ad{\-} +- \gdef^^ae{\registeredsymbol} +- \gdef^^af{\={}} +- % +- \gdef^^b0{\textdegree} +- \gdef^^b1{$\pm$} +- \gdef^^b2{$^2$} +- \gdef^^b3{$^3$} +- \gdef^^b4{\'{}} +- \gdef^^b5{$\mu$} +- \gdef^^b6{\P} +- % +- \gdef^^b7{$^.$} +- \gdef^^b8{\cedilla\ } +- \gdef^^b9{$^1$} +- \gdef^^ba{\ordm} +- % +- \gdef^^bb{\guillemetright} +- \gdef^^bc{$1\over4$} +- \gdef^^bd{$1\over2$} +- \gdef^^be{$3\over4$} +- \gdef^^bf{\questiondown} +- % +- \gdef^^c0{\`A} +- \gdef^^c1{\'A} +- \gdef^^c2{\^A} +- \gdef^^c3{\~A} +- \gdef^^c4{\"A} +- \gdef^^c5{\ringaccent A} +- \gdef^^c6{\AE} +- \gdef^^c7{\cedilla C} +- \gdef^^c8{\`E} +- \gdef^^c9{\'E} +- \gdef^^ca{\^E} +- \gdef^^cb{\"E} +- \gdef^^cc{\`I} +- \gdef^^cd{\'I} +- \gdef^^ce{\^I} +- \gdef^^cf{\"I} +- % +- \gdef^^d0{\DH} +- \gdef^^d1{\~N} +- \gdef^^d2{\`O} +- \gdef^^d3{\'O} +- \gdef^^d4{\^O} +- \gdef^^d5{\~O} +- \gdef^^d6{\"O} +- \gdef^^d7{$\times$} +- \gdef^^d8{\O} +- \gdef^^d9{\`U} +- \gdef^^da{\'U} +- \gdef^^db{\^U} +- \gdef^^dc{\"U} +- \gdef^^dd{\'Y} +- \gdef^^de{\TH} +- \gdef^^df{\ss} +- % +- \gdef^^e0{\`a} +- \gdef^^e1{\'a} +- \gdef^^e2{\^a} +- \gdef^^e3{\~a} +- \gdef^^e4{\"a} +- \gdef^^e5{\ringaccent a} +- \gdef^^e6{\ae} +- \gdef^^e7{\cedilla c} +- \gdef^^e8{\`e} +- \gdef^^e9{\'e} +- \gdef^^ea{\^e} +- \gdef^^eb{\"e} +- \gdef^^ec{\`{\dotless i}} +- \gdef^^ed{\'{\dotless i}} +- \gdef^^ee{\^{\dotless i}} +- \gdef^^ef{\"{\dotless i}} +- % +- \gdef^^f0{\dh} +- \gdef^^f1{\~n} +- \gdef^^f2{\`o} +- \gdef^^f3{\'o} +- \gdef^^f4{\^o} +- \gdef^^f5{\~o} +- \gdef^^f6{\"o} +- \gdef^^f7{$\div$} +- \gdef^^f8{\o} +- \gdef^^f9{\`u} +- \gdef^^fa{\'u} +- \gdef^^fb{\^u} +- \gdef^^fc{\"u} +- \gdef^^fd{\'y} +- \gdef^^fe{\th} +- \gdef^^ff{\"y} +-} +- +-% Latin9 (ISO-8859-15) encoding character definitions. +-\def\latninechardefs{% +- % Encoding is almost identical to Latin1. +- \latonechardefs +- % +- \gdef^^a4{\euro} +- \gdef^^a6{\v S} +- \gdef^^a8{\v s} +- \gdef^^b4{\v Z} +- \gdef^^b8{\v z} +- \gdef^^bc{\OE} +- \gdef^^bd{\oe} +- \gdef^^be{\"Y} +-} +- +-% Latin2 (ISO-8859-2) character definitions. +-\def\lattwochardefs{% +- \gdef^^a0{\tie} +- \gdef^^a1{\ogonek{A}} +- \gdef^^a2{\u{}} +- \gdef^^a3{\L} +- \gdef^^a4{\missingcharmsg{CURRENCY SIGN}} +- \gdef^^a5{\v L} +- \gdef^^a6{\'S} +- \gdef^^a7{\S} +- \gdef^^a8{\"{}} +- \gdef^^a9{\v S} +- \gdef^^aa{\cedilla S} +- \gdef^^ab{\v T} +- \gdef^^ac{\'Z} +- \gdef^^ad{\-} +- \gdef^^ae{\v Z} +- \gdef^^af{\dotaccent Z} +- % +- \gdef^^b0{\textdegree} +- \gdef^^b1{\ogonek{a}} +- \gdef^^b2{\ogonek{ }} +- \gdef^^b3{\l} +- \gdef^^b4{\'{}} +- \gdef^^b5{\v l} +- \gdef^^b6{\'s} +- \gdef^^b7{\v{}} +- \gdef^^b8{\cedilla\ } +- \gdef^^b9{\v s} +- \gdef^^ba{\cedilla s} +- \gdef^^bb{\v t} +- \gdef^^bc{\'z} +- \gdef^^bd{\H{}} +- \gdef^^be{\v z} +- \gdef^^bf{\dotaccent z} +- % +- \gdef^^c0{\'R} +- \gdef^^c1{\'A} +- \gdef^^c2{\^A} +- \gdef^^c3{\u A} +- \gdef^^c4{\"A} +- \gdef^^c5{\'L} +- \gdef^^c6{\'C} +- \gdef^^c7{\cedilla C} +- \gdef^^c8{\v C} +- \gdef^^c9{\'E} +- \gdef^^ca{\ogonek{E}} +- \gdef^^cb{\"E} +- \gdef^^cc{\v E} +- \gdef^^cd{\'I} +- \gdef^^ce{\^I} +- \gdef^^cf{\v D} +- % +- \gdef^^d0{\DH} +- \gdef^^d1{\'N} +- \gdef^^d2{\v N} +- \gdef^^d3{\'O} +- \gdef^^d4{\^O} +- \gdef^^d5{\H O} +- \gdef^^d6{\"O} +- \gdef^^d7{$\times$} +- \gdef^^d8{\v R} +- \gdef^^d9{\ringaccent U} +- \gdef^^da{\'U} +- \gdef^^db{\H U} +- \gdef^^dc{\"U} +- \gdef^^dd{\'Y} +- \gdef^^de{\cedilla T} +- \gdef^^df{\ss} +- % +- \gdef^^e0{\'r} +- \gdef^^e1{\'a} +- \gdef^^e2{\^a} +- \gdef^^e3{\u a} +- \gdef^^e4{\"a} +- \gdef^^e5{\'l} +- \gdef^^e6{\'c} +- \gdef^^e7{\cedilla c} +- \gdef^^e8{\v c} +- \gdef^^e9{\'e} +- \gdef^^ea{\ogonek{e}} +- \gdef^^eb{\"e} +- \gdef^^ec{\v e} +- \gdef^^ed{\'{\dotless{i}}} +- \gdef^^ee{\^{\dotless{i}}} +- \gdef^^ef{\v d} +- % +- \gdef^^f0{\dh} +- \gdef^^f1{\'n} +- \gdef^^f2{\v n} +- \gdef^^f3{\'o} +- \gdef^^f4{\^o} +- \gdef^^f5{\H o} +- \gdef^^f6{\"o} +- \gdef^^f7{$\div$} +- \gdef^^f8{\v r} +- \gdef^^f9{\ringaccent u} +- \gdef^^fa{\'u} +- \gdef^^fb{\H u} +- \gdef^^fc{\"u} +- \gdef^^fd{\'y} +- \gdef^^fe{\cedilla t} +- \gdef^^ff{\dotaccent{}} +-} +- +-% UTF-8 character definitions. +-% +-% This code to support UTF-8 is based on LaTeX's utf8.def, with some +-% changes for Texinfo conventions. It is included here under the GPL by +-% permission from Frank Mittelbach and the LaTeX team. +-% +-\newcount\countUTFx +-\newcount\countUTFy +-\newcount\countUTFz +- +-\gdef\UTFviiiTwoOctets#1#2{\expandafter +- \UTFviiiDefined\csname u8:#1\string #2\endcsname} +-% +-\gdef\UTFviiiThreeOctets#1#2#3{\expandafter +- \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} +-% +-\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter +- \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} +- +-\gdef\UTFviiiDefined#1{% +- \ifx #1\relax +- \message{\linenumber Unicode char \string #1 not defined for Texinfo}% +- \else +- \expandafter #1% +- \fi +-} +- +-\begingroup +- \catcode`\~13 +- \catcode`\"12 +- +- \def\UTFviiiLoop{% +- \global\catcode\countUTFx\active +- \uccode`\~\countUTFx +- \uppercase\expandafter{\UTFviiiTmp}% +- \advance\countUTFx by 1 +- \ifnum\countUTFx < \countUTFy +- \expandafter\UTFviiiLoop +- \fi} +- +- \countUTFx = "C2 +- \countUTFy = "E0 +- \def\UTFviiiTmp{% +- \xdef~{\noexpand\UTFviiiTwoOctets\string~}} +- \UTFviiiLoop +- +- \countUTFx = "E0 +- \countUTFy = "F0 +- \def\UTFviiiTmp{% +- \xdef~{\noexpand\UTFviiiThreeOctets\string~}} +- \UTFviiiLoop +- +- \countUTFx = "F0 +- \countUTFy = "F4 +- \def\UTFviiiTmp{% +- \xdef~{\noexpand\UTFviiiFourOctets\string~}} +- \UTFviiiLoop +-\endgroup +- +-\begingroup +- \catcode`\"=12 +- \catcode`\<=12 +- \catcode`\.=12 +- \catcode`\,=12 +- \catcode`\;=12 +- \catcode`\!=12 +- \catcode`\~=13 +- +- \gdef\DeclareUnicodeCharacter#1#2{% +- \countUTFz = "#1\relax +- %\wlog{\space\space defining Unicode char U+#1 (decimal \the\countUTFz)}% +- \begingroup +- \parseXMLCharref +- \def\UTFviiiTwoOctets##1##2{% +- \csname u8:##1\string ##2\endcsname}% +- \def\UTFviiiThreeOctets##1##2##3{% +- \csname u8:##1\string ##2\string ##3\endcsname}% +- \def\UTFviiiFourOctets##1##2##3##4{% +- \csname u8:##1\string ##2\string ##3\string ##4\endcsname}% +- \expandafter\expandafter\expandafter\expandafter +- \expandafter\expandafter\expandafter +- \gdef\UTFviiiTmp{#2}% +- \endgroup} +- +- \gdef\parseXMLCharref{% +- \ifnum\countUTFz < "A0\relax +- \errhelp = \EMsimple +- \errmessage{Cannot define Unicode char value < 00A0}% +- \else\ifnum\countUTFz < "800\relax +- \parseUTFviiiA,% +- \parseUTFviiiB C\UTFviiiTwoOctets.,% +- \else\ifnum\countUTFz < "10000\relax +- \parseUTFviiiA;% +- \parseUTFviiiA,% +- \parseUTFviiiB E\UTFviiiThreeOctets.{,;}% +- \else +- \parseUTFviiiA;% +- \parseUTFviiiA,% +- \parseUTFviiiA!% +- \parseUTFviiiB F\UTFviiiFourOctets.{!,;}% +- \fi\fi\fi +- } +- +- \gdef\parseUTFviiiA#1{% +- \countUTFx = \countUTFz +- \divide\countUTFz by 64 +- \countUTFy = \countUTFz +- \multiply\countUTFz by 64 +- \advance\countUTFx by -\countUTFz +- \advance\countUTFx by 128 +- \uccode `#1\countUTFx +- \countUTFz = \countUTFy} +- +- \gdef\parseUTFviiiB#1#2#3#4{% +- \advance\countUTFz by "#10\relax +- \uccode `#3\countUTFz +- \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} +-\endgroup +- +-\def\utfeightchardefs{% +- \DeclareUnicodeCharacter{00A0}{\tie} +- \DeclareUnicodeCharacter{00A1}{\exclamdown} +- \DeclareUnicodeCharacter{00A3}{\pounds} +- \DeclareUnicodeCharacter{00A8}{\"{ }} +- \DeclareUnicodeCharacter{00A9}{\copyright} +- \DeclareUnicodeCharacter{00AA}{\ordf} +- \DeclareUnicodeCharacter{00AB}{\guillemetleft} +- \DeclareUnicodeCharacter{00AD}{\-} +- \DeclareUnicodeCharacter{00AE}{\registeredsymbol} +- \DeclareUnicodeCharacter{00AF}{\={ }} +- +- \DeclareUnicodeCharacter{00B0}{\ringaccent{ }} +- \DeclareUnicodeCharacter{00B4}{\'{ }} +- \DeclareUnicodeCharacter{00B8}{\cedilla{ }} +- \DeclareUnicodeCharacter{00BA}{\ordm} +- \DeclareUnicodeCharacter{00BB}{\guillemetright} +- \DeclareUnicodeCharacter{00BF}{\questiondown} +- +- \DeclareUnicodeCharacter{00C0}{\`A} +- \DeclareUnicodeCharacter{00C1}{\'A} +- \DeclareUnicodeCharacter{00C2}{\^A} +- \DeclareUnicodeCharacter{00C3}{\~A} +- \DeclareUnicodeCharacter{00C4}{\"A} +- \DeclareUnicodeCharacter{00C5}{\AA} +- \DeclareUnicodeCharacter{00C6}{\AE} +- \DeclareUnicodeCharacter{00C7}{\cedilla{C}} +- \DeclareUnicodeCharacter{00C8}{\`E} +- \DeclareUnicodeCharacter{00C9}{\'E} +- \DeclareUnicodeCharacter{00CA}{\^E} +- \DeclareUnicodeCharacter{00CB}{\"E} +- \DeclareUnicodeCharacter{00CC}{\`I} +- \DeclareUnicodeCharacter{00CD}{\'I} +- \DeclareUnicodeCharacter{00CE}{\^I} +- \DeclareUnicodeCharacter{00CF}{\"I} +- +- \DeclareUnicodeCharacter{00D0}{\DH} +- \DeclareUnicodeCharacter{00D1}{\~N} +- \DeclareUnicodeCharacter{00D2}{\`O} +- \DeclareUnicodeCharacter{00D3}{\'O} +- \DeclareUnicodeCharacter{00D4}{\^O} +- \DeclareUnicodeCharacter{00D5}{\~O} +- \DeclareUnicodeCharacter{00D6}{\"O} +- \DeclareUnicodeCharacter{00D8}{\O} +- \DeclareUnicodeCharacter{00D9}{\`U} +- \DeclareUnicodeCharacter{00DA}{\'U} +- \DeclareUnicodeCharacter{00DB}{\^U} +- \DeclareUnicodeCharacter{00DC}{\"U} +- \DeclareUnicodeCharacter{00DD}{\'Y} +- \DeclareUnicodeCharacter{00DE}{\TH} +- \DeclareUnicodeCharacter{00DF}{\ss} +- +- \DeclareUnicodeCharacter{00E0}{\`a} +- \DeclareUnicodeCharacter{00E1}{\'a} +- \DeclareUnicodeCharacter{00E2}{\^a} +- \DeclareUnicodeCharacter{00E3}{\~a} +- \DeclareUnicodeCharacter{00E4}{\"a} +- \DeclareUnicodeCharacter{00E5}{\aa} +- \DeclareUnicodeCharacter{00E6}{\ae} +- \DeclareUnicodeCharacter{00E7}{\cedilla{c}} +- \DeclareUnicodeCharacter{00E8}{\`e} +- \DeclareUnicodeCharacter{00E9}{\'e} +- \DeclareUnicodeCharacter{00EA}{\^e} +- \DeclareUnicodeCharacter{00EB}{\"e} +- \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}} +- \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}} +- \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}} +- \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}} +- +- \DeclareUnicodeCharacter{00F0}{\dh} +- \DeclareUnicodeCharacter{00F1}{\~n} +- \DeclareUnicodeCharacter{00F2}{\`o} +- \DeclareUnicodeCharacter{00F3}{\'o} +- \DeclareUnicodeCharacter{00F4}{\^o} +- \DeclareUnicodeCharacter{00F5}{\~o} +- \DeclareUnicodeCharacter{00F6}{\"o} +- \DeclareUnicodeCharacter{00F8}{\o} +- \DeclareUnicodeCharacter{00F9}{\`u} +- \DeclareUnicodeCharacter{00FA}{\'u} +- \DeclareUnicodeCharacter{00FB}{\^u} +- \DeclareUnicodeCharacter{00FC}{\"u} +- \DeclareUnicodeCharacter{00FD}{\'y} +- \DeclareUnicodeCharacter{00FE}{\th} +- \DeclareUnicodeCharacter{00FF}{\"y} +- +- \DeclareUnicodeCharacter{0100}{\=A} +- \DeclareUnicodeCharacter{0101}{\=a} +- \DeclareUnicodeCharacter{0102}{\u{A}} +- \DeclareUnicodeCharacter{0103}{\u{a}} +- \DeclareUnicodeCharacter{0104}{\ogonek{A}} +- \DeclareUnicodeCharacter{0105}{\ogonek{a}} +- \DeclareUnicodeCharacter{0106}{\'C} +- \DeclareUnicodeCharacter{0107}{\'c} +- \DeclareUnicodeCharacter{0108}{\^C} +- \DeclareUnicodeCharacter{0109}{\^c} +- \DeclareUnicodeCharacter{0118}{\ogonek{E}} +- \DeclareUnicodeCharacter{0119}{\ogonek{e}} +- \DeclareUnicodeCharacter{010A}{\dotaccent{C}} +- \DeclareUnicodeCharacter{010B}{\dotaccent{c}} +- \DeclareUnicodeCharacter{010C}{\v{C}} +- \DeclareUnicodeCharacter{010D}{\v{c}} +- \DeclareUnicodeCharacter{010E}{\v{D}} +- +- \DeclareUnicodeCharacter{0112}{\=E} +- \DeclareUnicodeCharacter{0113}{\=e} +- \DeclareUnicodeCharacter{0114}{\u{E}} +- \DeclareUnicodeCharacter{0115}{\u{e}} +- \DeclareUnicodeCharacter{0116}{\dotaccent{E}} +- \DeclareUnicodeCharacter{0117}{\dotaccent{e}} +- \DeclareUnicodeCharacter{011A}{\v{E}} +- \DeclareUnicodeCharacter{011B}{\v{e}} +- \DeclareUnicodeCharacter{011C}{\^G} +- \DeclareUnicodeCharacter{011D}{\^g} +- \DeclareUnicodeCharacter{011E}{\u{G}} +- \DeclareUnicodeCharacter{011F}{\u{g}} +- +- \DeclareUnicodeCharacter{0120}{\dotaccent{G}} +- \DeclareUnicodeCharacter{0121}{\dotaccent{g}} +- \DeclareUnicodeCharacter{0124}{\^H} +- \DeclareUnicodeCharacter{0125}{\^h} +- \DeclareUnicodeCharacter{0128}{\~I} +- \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}} +- \DeclareUnicodeCharacter{012A}{\=I} +- \DeclareUnicodeCharacter{012B}{\={\dotless{i}}} +- \DeclareUnicodeCharacter{012C}{\u{I}} +- \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}} +- +- \DeclareUnicodeCharacter{0130}{\dotaccent{I}} +- \DeclareUnicodeCharacter{0131}{\dotless{i}} +- \DeclareUnicodeCharacter{0132}{IJ} +- \DeclareUnicodeCharacter{0133}{ij} +- \DeclareUnicodeCharacter{0134}{\^J} +- \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}} +- \DeclareUnicodeCharacter{0139}{\'L} +- \DeclareUnicodeCharacter{013A}{\'l} +- +- \DeclareUnicodeCharacter{0141}{\L} +- \DeclareUnicodeCharacter{0142}{\l} +- \DeclareUnicodeCharacter{0143}{\'N} +- \DeclareUnicodeCharacter{0144}{\'n} +- \DeclareUnicodeCharacter{0147}{\v{N}} +- \DeclareUnicodeCharacter{0148}{\v{n}} +- \DeclareUnicodeCharacter{014C}{\=O} +- \DeclareUnicodeCharacter{014D}{\=o} +- \DeclareUnicodeCharacter{014E}{\u{O}} +- \DeclareUnicodeCharacter{014F}{\u{o}} +- +- \DeclareUnicodeCharacter{0150}{\H{O}} +- \DeclareUnicodeCharacter{0151}{\H{o}} +- \DeclareUnicodeCharacter{0152}{\OE} +- \DeclareUnicodeCharacter{0153}{\oe} +- \DeclareUnicodeCharacter{0154}{\'R} +- \DeclareUnicodeCharacter{0155}{\'r} +- \DeclareUnicodeCharacter{0158}{\v{R}} +- \DeclareUnicodeCharacter{0159}{\v{r}} +- \DeclareUnicodeCharacter{015A}{\'S} +- \DeclareUnicodeCharacter{015B}{\'s} +- \DeclareUnicodeCharacter{015C}{\^S} +- \DeclareUnicodeCharacter{015D}{\^s} +- \DeclareUnicodeCharacter{015E}{\cedilla{S}} +- \DeclareUnicodeCharacter{015F}{\cedilla{s}} +- +- \DeclareUnicodeCharacter{0160}{\v{S}} +- \DeclareUnicodeCharacter{0161}{\v{s}} +- \DeclareUnicodeCharacter{0162}{\cedilla{t}} +- \DeclareUnicodeCharacter{0163}{\cedilla{T}} +- \DeclareUnicodeCharacter{0164}{\v{T}} +- +- \DeclareUnicodeCharacter{0168}{\~U} +- \DeclareUnicodeCharacter{0169}{\~u} +- \DeclareUnicodeCharacter{016A}{\=U} +- \DeclareUnicodeCharacter{016B}{\=u} +- \DeclareUnicodeCharacter{016C}{\u{U}} +- \DeclareUnicodeCharacter{016D}{\u{u}} +- \DeclareUnicodeCharacter{016E}{\ringaccent{U}} +- \DeclareUnicodeCharacter{016F}{\ringaccent{u}} +- +- \DeclareUnicodeCharacter{0170}{\H{U}} +- \DeclareUnicodeCharacter{0171}{\H{u}} +- \DeclareUnicodeCharacter{0174}{\^W} +- \DeclareUnicodeCharacter{0175}{\^w} +- \DeclareUnicodeCharacter{0176}{\^Y} +- \DeclareUnicodeCharacter{0177}{\^y} +- \DeclareUnicodeCharacter{0178}{\"Y} +- \DeclareUnicodeCharacter{0179}{\'Z} +- \DeclareUnicodeCharacter{017A}{\'z} +- \DeclareUnicodeCharacter{017B}{\dotaccent{Z}} +- \DeclareUnicodeCharacter{017C}{\dotaccent{z}} +- \DeclareUnicodeCharacter{017D}{\v{Z}} +- \DeclareUnicodeCharacter{017E}{\v{z}} +- +- \DeclareUnicodeCharacter{01C4}{D\v{Z}} +- \DeclareUnicodeCharacter{01C5}{D\v{z}} +- \DeclareUnicodeCharacter{01C6}{d\v{z}} +- \DeclareUnicodeCharacter{01C7}{LJ} +- \DeclareUnicodeCharacter{01C8}{Lj} +- \DeclareUnicodeCharacter{01C9}{lj} +- \DeclareUnicodeCharacter{01CA}{NJ} +- \DeclareUnicodeCharacter{01CB}{Nj} +- \DeclareUnicodeCharacter{01CC}{nj} +- \DeclareUnicodeCharacter{01CD}{\v{A}} +- \DeclareUnicodeCharacter{01CE}{\v{a}} +- \DeclareUnicodeCharacter{01CF}{\v{I}} +- +- \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}} +- \DeclareUnicodeCharacter{01D1}{\v{O}} +- \DeclareUnicodeCharacter{01D2}{\v{o}} +- \DeclareUnicodeCharacter{01D3}{\v{U}} +- \DeclareUnicodeCharacter{01D4}{\v{u}} +- +- \DeclareUnicodeCharacter{01E2}{\={\AE}} +- \DeclareUnicodeCharacter{01E3}{\={\ae}} +- \DeclareUnicodeCharacter{01E6}{\v{G}} +- \DeclareUnicodeCharacter{01E7}{\v{g}} +- \DeclareUnicodeCharacter{01E8}{\v{K}} +- \DeclareUnicodeCharacter{01E9}{\v{k}} +- +- \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}} +- \DeclareUnicodeCharacter{01F1}{DZ} +- \DeclareUnicodeCharacter{01F2}{Dz} +- \DeclareUnicodeCharacter{01F3}{dz} +- \DeclareUnicodeCharacter{01F4}{\'G} +- \DeclareUnicodeCharacter{01F5}{\'g} +- \DeclareUnicodeCharacter{01F8}{\`N} +- \DeclareUnicodeCharacter{01F9}{\`n} +- \DeclareUnicodeCharacter{01FC}{\'{\AE}} +- \DeclareUnicodeCharacter{01FD}{\'{\ae}} +- \DeclareUnicodeCharacter{01FE}{\'{\O}} +- \DeclareUnicodeCharacter{01FF}{\'{\o}} +- +- \DeclareUnicodeCharacter{021E}{\v{H}} +- \DeclareUnicodeCharacter{021F}{\v{h}} +- +- \DeclareUnicodeCharacter{0226}{\dotaccent{A}} +- \DeclareUnicodeCharacter{0227}{\dotaccent{a}} +- \DeclareUnicodeCharacter{0228}{\cedilla{E}} +- \DeclareUnicodeCharacter{0229}{\cedilla{e}} +- \DeclareUnicodeCharacter{022E}{\dotaccent{O}} +- \DeclareUnicodeCharacter{022F}{\dotaccent{o}} +- +- \DeclareUnicodeCharacter{0232}{\=Y} +- \DeclareUnicodeCharacter{0233}{\=y} +- \DeclareUnicodeCharacter{0237}{\dotless{j}} +- +- \DeclareUnicodeCharacter{02DB}{\ogonek{ }} +- +- \DeclareUnicodeCharacter{1E02}{\dotaccent{B}} +- \DeclareUnicodeCharacter{1E03}{\dotaccent{b}} +- \DeclareUnicodeCharacter{1E04}{\udotaccent{B}} +- \DeclareUnicodeCharacter{1E05}{\udotaccent{b}} +- \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}} +- \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}} +- \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}} +- \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}} +- \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}} +- \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}} +- \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}} +- \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}} +- +- \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}} +- \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}} +- +- \DeclareUnicodeCharacter{1E20}{\=G} +- \DeclareUnicodeCharacter{1E21}{\=g} +- \DeclareUnicodeCharacter{1E22}{\dotaccent{H}} +- \DeclareUnicodeCharacter{1E23}{\dotaccent{h}} +- \DeclareUnicodeCharacter{1E24}{\udotaccent{H}} +- \DeclareUnicodeCharacter{1E25}{\udotaccent{h}} +- \DeclareUnicodeCharacter{1E26}{\"H} +- \DeclareUnicodeCharacter{1E27}{\"h} +- +- \DeclareUnicodeCharacter{1E30}{\'K} +- \DeclareUnicodeCharacter{1E31}{\'k} +- \DeclareUnicodeCharacter{1E32}{\udotaccent{K}} +- \DeclareUnicodeCharacter{1E33}{\udotaccent{k}} +- \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}} +- \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}} +- \DeclareUnicodeCharacter{1E36}{\udotaccent{L}} +- \DeclareUnicodeCharacter{1E37}{\udotaccent{l}} +- \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}} +- \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}} +- \DeclareUnicodeCharacter{1E3E}{\'M} +- \DeclareUnicodeCharacter{1E3F}{\'m} +- +- \DeclareUnicodeCharacter{1E40}{\dotaccent{M}} +- \DeclareUnicodeCharacter{1E41}{\dotaccent{m}} +- \DeclareUnicodeCharacter{1E42}{\udotaccent{M}} +- \DeclareUnicodeCharacter{1E43}{\udotaccent{m}} +- \DeclareUnicodeCharacter{1E44}{\dotaccent{N}} +- \DeclareUnicodeCharacter{1E45}{\dotaccent{n}} +- \DeclareUnicodeCharacter{1E46}{\udotaccent{N}} +- \DeclareUnicodeCharacter{1E47}{\udotaccent{n}} +- \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}} +- \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}} +- +- \DeclareUnicodeCharacter{1E54}{\'P} +- \DeclareUnicodeCharacter{1E55}{\'p} +- \DeclareUnicodeCharacter{1E56}{\dotaccent{P}} +- \DeclareUnicodeCharacter{1E57}{\dotaccent{p}} +- \DeclareUnicodeCharacter{1E58}{\dotaccent{R}} +- \DeclareUnicodeCharacter{1E59}{\dotaccent{r}} +- \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}} +- \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}} +- \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}} +- \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}} +- +- \DeclareUnicodeCharacter{1E60}{\dotaccent{S}} +- \DeclareUnicodeCharacter{1E61}{\dotaccent{s}} +- \DeclareUnicodeCharacter{1E62}{\udotaccent{S}} +- \DeclareUnicodeCharacter{1E63}{\udotaccent{s}} +- \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}} +- \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}} +- \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}} +- \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}} +- \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}} +- \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}} +- +- \DeclareUnicodeCharacter{1E7C}{\~V} +- \DeclareUnicodeCharacter{1E7D}{\~v} +- \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}} +- \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}} +- +- \DeclareUnicodeCharacter{1E80}{\`W} +- \DeclareUnicodeCharacter{1E81}{\`w} +- \DeclareUnicodeCharacter{1E82}{\'W} +- \DeclareUnicodeCharacter{1E83}{\'w} +- \DeclareUnicodeCharacter{1E84}{\"W} +- \DeclareUnicodeCharacter{1E85}{\"w} +- \DeclareUnicodeCharacter{1E86}{\dotaccent{W}} +- \DeclareUnicodeCharacter{1E87}{\dotaccent{w}} +- \DeclareUnicodeCharacter{1E88}{\udotaccent{W}} +- \DeclareUnicodeCharacter{1E89}{\udotaccent{w}} +- \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}} +- \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}} +- \DeclareUnicodeCharacter{1E8C}{\"X} +- \DeclareUnicodeCharacter{1E8D}{\"x} +- \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}} +- \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}} +- +- \DeclareUnicodeCharacter{1E90}{\^Z} +- \DeclareUnicodeCharacter{1E91}{\^z} +- \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}} +- \DeclareUnicodeCharacter{1E93}{\udotaccent{z}} +- \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}} +- \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}} +- \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}} +- \DeclareUnicodeCharacter{1E97}{\"t} +- \DeclareUnicodeCharacter{1E98}{\ringaccent{w}} +- \DeclareUnicodeCharacter{1E99}{\ringaccent{y}} +- +- \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}} +- \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}} +- +- \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}} +- \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}} +- \DeclareUnicodeCharacter{1EBC}{\~E} +- \DeclareUnicodeCharacter{1EBD}{\~e} +- +- \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}} +- \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}} +- \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}} +- \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}} +- +- \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}} +- \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}} +- +- \DeclareUnicodeCharacter{1EF2}{\`Y} +- \DeclareUnicodeCharacter{1EF3}{\`y} +- \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}} +- +- \DeclareUnicodeCharacter{1EF8}{\~Y} +- \DeclareUnicodeCharacter{1EF9}{\~y} +- +- \DeclareUnicodeCharacter{2013}{--} +- \DeclareUnicodeCharacter{2014}{---} +- \DeclareUnicodeCharacter{2018}{\quoteleft} +- \DeclareUnicodeCharacter{2019}{\quoteright} +- \DeclareUnicodeCharacter{201A}{\quotesinglbase} +- \DeclareUnicodeCharacter{201C}{\quotedblleft} +- \DeclareUnicodeCharacter{201D}{\quotedblright} +- \DeclareUnicodeCharacter{201E}{\quotedblbase} +- \DeclareUnicodeCharacter{2022}{\bullet} +- \DeclareUnicodeCharacter{2026}{\dots} +- \DeclareUnicodeCharacter{2039}{\guilsinglleft} +- \DeclareUnicodeCharacter{203A}{\guilsinglright} +- \DeclareUnicodeCharacter{20AC}{\euro} +- +- \DeclareUnicodeCharacter{2192}{\expansion} +- \DeclareUnicodeCharacter{21D2}{\result} +- +- \DeclareUnicodeCharacter{2212}{\minus} +- \DeclareUnicodeCharacter{2217}{\point} +- \DeclareUnicodeCharacter{2261}{\equiv} +-}% end of \utfeightchardefs +- +- +-% US-ASCII character definitions. +-\def\asciichardefs{% nothing need be done +- \relax +-} +- +-% Make non-ASCII characters printable again for compatibility with +-% existing Texinfo documents that may use them, even without declaring a +-% document encoding. +-% +-\setnonasciicharscatcode \other +- +- +-\message{formatting,} +- +-\newdimen\defaultparindent \defaultparindent = 15pt +- +-\chapheadingskip = 15pt plus 4pt minus 2pt +-\secheadingskip = 12pt plus 3pt minus 2pt +-\subsecheadingskip = 9pt plus 2pt minus 2pt +- +-% Prevent underfull vbox error messages. +-\vbadness = 10000 +- +-% Don't be very finicky about underfull hboxes, either. +-\hbadness = 6666 +- +-% Following George Bush, get rid of widows and orphans. +-\widowpenalty=10000 +-\clubpenalty=10000 +- +-% Use TeX 3.0's \emergencystretch to help line breaking, but if we're +-% using an old version of TeX, don't do anything. We want the amount of +-% stretch added to depend on the line length, hence the dependence on +-% \hsize. We call this whenever the paper size is set. +-% +-\def\setemergencystretch{% +- \ifx\emergencystretch\thisisundefined +- % Allow us to assign to \emergencystretch anyway. +- \def\emergencystretch{\dimen0}% +- \else +- \emergencystretch = .15\hsize +- \fi +-} +- +-% Parameters in order: 1) textheight; 2) textwidth; +-% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; +-% 7) physical page height; 8) physical page width. +-% +-% We also call \setleading{\textleading}, so the caller should define +-% \textleading. The caller should also set \parskip. +-% +-\def\internalpagesizes#1#2#3#4#5#6#7#8{% +- \voffset = #3\relax +- \topskip = #6\relax +- \splittopskip = \topskip +- % +- \vsize = #1\relax +- \advance\vsize by \topskip +- \outervsize = \vsize +- \advance\outervsize by 2\topandbottommargin +- \pageheight = \vsize +- % +- \hsize = #2\relax +- \outerhsize = \hsize +- \advance\outerhsize by 0.5in +- \pagewidth = \hsize +- % +- \normaloffset = #4\relax +- \bindingoffset = #5\relax +- % +- \ifpdf +- \pdfpageheight #7\relax +- \pdfpagewidth #8\relax +- % if we don't reset these, they will remain at "1 true in" of +- % whatever layout pdftex was dumped with. +- \pdfhorigin = 1 true in +- \pdfvorigin = 1 true in +- \fi +- % +- \setleading{\textleading} +- % +- \parindent = \defaultparindent +- \setemergencystretch +-} +- +-% @letterpaper (the default). +-\def\letterpaper{{\globaldefs = 1 +- \parskip = 3pt plus 2pt minus 1pt +- \textleading = 13.2pt +- % +- % If page is nothing but text, make it come out even. +- \internalpagesizes{607.2pt}{6in}% that's 46 lines +- {\voffset}{.25in}% +- {\bindingoffset}{36pt}% +- {11in}{8.5in}% +-}} +- +-% Use @smallbook to reset parameters for 7x9.25 trim size. +-\def\smallbook{{\globaldefs = 1 +- \parskip = 2pt plus 1pt +- \textleading = 12pt +- % +- \internalpagesizes{7.5in}{5in}% +- {-.2in}{0in}% +- {\bindingoffset}{16pt}% +- {9.25in}{7in}% +- % +- \lispnarrowing = 0.3in +- \tolerance = 700 +- \hfuzz = 1pt +- \contentsrightmargin = 0pt +- \defbodyindent = .5cm +-}} +- +-% Use @smallerbook to reset parameters for 6x9 trim size. +-% (Just testing, parameters still in flux.) +-\def\smallerbook{{\globaldefs = 1 +- \parskip = 1.5pt plus 1pt +- \textleading = 12pt +- % +- \internalpagesizes{7.4in}{4.8in}% +- {-.2in}{-.4in}% +- {0pt}{14pt}% +- {9in}{6in}% +- % +- \lispnarrowing = 0.25in +- \tolerance = 700 +- \hfuzz = 1pt +- \contentsrightmargin = 0pt +- \defbodyindent = .4cm +-}} +- +-% Use @afourpaper to print on European A4 paper. +-\def\afourpaper{{\globaldefs = 1 +- \parskip = 3pt plus 2pt minus 1pt +- \textleading = 13.2pt +- % +- % Double-side printing via postscript on Laserjet 4050 +- % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. +- % To change the settings for a different printer or situation, adjust +- % \normaloffset until the front-side and back-side texts align. Then +- % do the same for \bindingoffset. You can set these for testing in +- % your texinfo source file like this: +- % @tex +- % \global\normaloffset = -6mm +- % \global\bindingoffset = 10mm +- % @end tex +- \internalpagesizes{673.2pt}{160mm}% that's 51 lines +- {\voffset}{\hoffset}% +- {\bindingoffset}{44pt}% +- {297mm}{210mm}% +- % +- \tolerance = 700 +- \hfuzz = 1pt +- \contentsrightmargin = 0pt +- \defbodyindent = 5mm +-}} +- +-% Use @afivepaper to print on European A5 paper. +-% From romildo@urano.iceb.ufop.br, 2 July 2000. +-% He also recommends making @example and @lisp be small. +-\def\afivepaper{{\globaldefs = 1 +- \parskip = 2pt plus 1pt minus 0.1pt +- \textleading = 12.5pt +- % +- \internalpagesizes{160mm}{120mm}% +- {\voffset}{\hoffset}% +- {\bindingoffset}{8pt}% +- {210mm}{148mm}% +- % +- \lispnarrowing = 0.2in +- \tolerance = 800 +- \hfuzz = 1.2pt +- \contentsrightmargin = 0pt +- \defbodyindent = 2mm +- \tableindent = 12mm +-}} +- +-% A specific text layout, 24x15cm overall, intended for A4 paper. +-\def\afourlatex{{\globaldefs = 1 +- \afourpaper +- \internalpagesizes{237mm}{150mm}% +- {\voffset}{4.6mm}% +- {\bindingoffset}{7mm}% +- {297mm}{210mm}% +- % +- % Must explicitly reset to 0 because we call \afourpaper. +- \globaldefs = 0 +-}} +- +-% Use @afourwide to print on A4 paper in landscape format. +-\def\afourwide{{\globaldefs = 1 +- \afourpaper +- \internalpagesizes{241mm}{165mm}% +- {\voffset}{-2.95mm}% +- {\bindingoffset}{7mm}% +- {297mm}{210mm}% +- \globaldefs = 0 +-}} +- +-% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +-% Perhaps we should allow setting the margins, \topskip, \parskip, +-% and/or leading, also. Or perhaps we should compute them somehow. +-% +-\parseargdef\pagesizes{\pagesizesyyy #1,,\finish} +-\def\pagesizesyyy#1,#2,#3\finish{{% +- \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi +- \globaldefs = 1 +- % +- \parskip = 3pt plus 2pt minus 1pt +- \setleading{\textleading}% +- % +- \dimen0 = #1\relax +- \advance\dimen0 by \voffset +- % +- \dimen2 = \hsize +- \advance\dimen2 by \normaloffset +- % +- \internalpagesizes{#1}{\hsize}% +- {\voffset}{\normaloffset}% +- {\bindingoffset}{44pt}% +- {\dimen0}{\dimen2}% +-}} +- +-% Set default to letter. +-% +-\letterpaper +- +- +-\message{and turning on texinfo input format.} +- +-\def^^L{\par} % remove \outer, so ^L can appear in an @comment +- +-% DEL is a comment character, in case @c does not suffice. +-\catcode`\^^? = 14 +- +-% Define macros to output various characters with catcode for normal text. +-\catcode`\"=\other \def\normaldoublequote{"} +-\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix +-\catcode`\+=\other \def\normalplus{+} +-\catcode`\<=\other \def\normalless{<} +-\catcode`\>=\other \def\normalgreater{>} +-\catcode`\^=\other \def\normalcaret{^} +-\catcode`\_=\other \def\normalunderscore{_} +-\catcode`\|=\other \def\normalverticalbar{|} +-\catcode`\~=\other \def\normaltilde{~} +- +-% This macro is used to make a character print one way in \tt +-% (where it can probably be output as-is), and another way in other fonts, +-% where something hairier probably needs to be done. +-% +-% #1 is what to print if we are indeed using \tt; #2 is what to print +-% otherwise. Since all the Computer Modern typewriter fonts have zero +-% interword stretch (and shrink), and it is reasonable to expect all +-% typewriter fonts to have this, we can check that font parameter. +-% +-\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi} +- +-% Same as above, but check for italic font. Actually this also catches +-% non-italic slanted fonts since it is impossible to distinguish them from +-% italic fonts. But since this is only used by $ and it uses \sl anyway +-% this is not a problem. +-\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} +- +-% Turn off all special characters except @ +-% (and those which the user can use as if they were ordinary). +-% Most of these we simply print from the \tt font, but for some, we can +-% use math or other variants that look better in normal text. +- +-\catcode`\"=\active +-\def\activedoublequote{{\tt\char34}} +-\let"=\activedoublequote +-\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde +-\chardef\hat=`\^ +-\catcode`\^=\active \def\activehat{{\tt \hat}} \let^ = \activehat +- +-\catcode`\_=\active +-\def_{\ifusingtt\normalunderscore\_} +-\let\realunder=_ +-% Subroutine for the previous macro. +-\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } +- +-\catcode`\|=\active +-\def|{{\tt\char124}} +- +-\chardef \less=`\< +-\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless +-\chardef \gtr=`\> +-\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr +-\catcode`\+=\active \def+{{\tt \char 43}} +-\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix +- +-% used for headline/footline in the output routine, in case the page +-% breaks in the middle of an @tex block. +-\def\texinfochars{% +- \let< = \activeless +- \let> = \activegtr +- \let~ = \activetilde +- \let^ = \activehat +- \markupsetuplqdefault \markupsetuprqdefault +- \let\b = \strong +- \let\i = \smartitalic +- % in principle, all other definitions in \tex have to be undone too. +-} +- +-% If a .fmt file is being used, characters that might appear in a file +-% name cannot be active until we have parsed the command line. +-% So turn them off again, and have \everyjob (or @setfilename) turn them on. +-% \otherifyactive is called near the end of this file. +-\def\otherifyactive{\catcode`+=\other \catcode`\_=\other} +- +-% Used sometimes to turn off (effectively) the active characters even after +-% parsing them. +-\def\turnoffactive{% +- \normalturnoffactive +- \otherbackslash +-} +- +-\catcode`\@=0 +- +-% \backslashcurfont outputs one backslash character in current font, +-% as in \char`\\. +-\global\chardef\backslashcurfont=`\\ +-\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work +- +-% \realbackslash is an actual character `\' with catcode other, and +-% \doublebackslash is two of them (for the pdf outlines). +-{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} +- +-% In texinfo, backslash is an active character; it prints the backslash +-% in fixed width font. +-\catcode`\\=\active % @ for escape char from now on. +- +-% The story here is that in math mode, the \char of \backslashcurfont +-% ends up printing the roman \ from the math symbol font (because \char +-% in math mode uses the \mathcode, and plain.tex sets +-% \mathcode`\\="026E). It seems better for @backslashchar{} to always +-% print a typewriter backslash, hence we use an explicit \mathchar, +-% which is the decimal equivalent of "715c (class 7, e.g., use \fam; +-% ignored family value; char position "5C). We can't use " for the +-% usual hex value because it has already been made active. +-@def@normalbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} +-@let@backslashchar = @normalbackslash % @backslashchar{} is for user documents. +- +-% On startup, @fixbackslash assigns: +-% @let \ = @normalbackslash +-% \rawbackslash defines an active \ to do \backslashcurfont. +-% \otherbackslash defines an active \ to be a literal `\' character with +-% catcode other. We switch back and forth between these. +-@gdef@rawbackslash{@let\=@backslashcurfont} +-@gdef@otherbackslash{@let\=@realbackslash} +- +-% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of +-% the literal character `\'. Also revert - to its normal character, in +-% case the active - from code has slipped in. +-% +-{@catcode`- = @active +- @gdef@normalturnoffactive{% +- @let-=@normaldash +- @let"=@normaldoublequote +- @let$=@normaldollar %$ font-lock fix +- @let+=@normalplus +- @let<=@normalless +- @let>=@normalgreater +- @let\=@normalbackslash +- @let^=@normalcaret +- @let_=@normalunderscore +- @let|=@normalverticalbar +- @let~=@normaltilde +- @markupsetuplqdefault +- @markupsetuprqdefault +- @unsepspaces +- } +-} +- +-% Make _ and + \other characters, temporarily. +-% This is canceled by @fixbackslash. +-@otherifyactive +- +-% If a .fmt file is being used, we don't want the `\input texinfo' to show up. +-% That is what \eatinput is for; after that, the `\' should revert to printing +-% a backslash. +-% +-@gdef@eatinput input texinfo{@fixbackslash} +-@global@let\ = @eatinput +- +-% On the other hand, perhaps the file did not have a `\input texinfo'. Then +-% the first `\' in the file would cause an error. This macro tries to fix +-% that, assuming it is called before the first `\' could plausibly occur. +-% Also turn back on active characters that might appear in the input +-% file name, in case not using a pre-dumped format. +-% +-@gdef@fixbackslash{% +- @ifx\@eatinput @let\ = @normalbackslash @fi +- @catcode`+=@active +- @catcode`@_=@active +-} +- +-% Say @foo, not \foo, in error messages. +-@escapechar = `@@ +- +-% These (along with & and #) are made active for url-breaking, so need +-% active definitions as the normal characters. +-@def@normaldot{.} +-@def@normalquest{?} +-@def@normalslash{/} +- +-% These look ok in all fonts, so just make them not special. +-% @hashchar{} gets its own user-level command, because of #line. +-@catcode`@& = @other @def@normalamp{&} +-@catcode`@# = @other @def@normalhash{#} +-@catcode`@% = @other @def@normalpercent{%} +- +-@let @hashchar = @normalhash +- +-@c Finally, make ` and ' active, so that txicodequoteundirected and +-@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we +-@c don't make ` and ' active, @code will not get them as active chars. +-@c Do this last of all since we use ` in the previous @catcode assignments. +-@catcode`@'=@active +-@catcode`@`=@active +-@markupsetuplqdefault +-@markupsetuprqdefault +- +-@c Local variables: +-@c eval: (add-hook 'write-file-hooks 'time-stamp) +-@c page-delimiter: "^\\\\message" +-@c time-stamp-start: "def\\\\texinfoversion{" +-@c time-stamp-format: "%:y-%02m-%02d.%02H" +-@c time-stamp-end: "}" +-@c End: +- +-@c vim:sw=2: +- +-@ignore +- arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115 +-@end ignore +diff -Nuar groff-1.22.3.old/font/devascii/devascii.am groff-1.22.3/font/devascii/devascii.am +--- groff-1.22.3.old/font/devascii/devascii.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devascii/devascii.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,46 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++devascii_srcdir = $(top_srcdir)/font/devascii ++DEVASCIIFONTS = R I B BI ++DEVASCIIFONTSFILES = \ ++ font/devascii/R font/devascii/I font/devascii/B font/devascii/BI ++ ++DEVASCIIRES = 240 ++DEVASCIICPI = 10 ++DEVASCIILPI = 6 ++ ++devasciifontdir = $(fontdir)/devascii ++devasciifont_DATA = $(DEVASCIIFONTSFILES) font/devascii/DESC ++MOSTLYCLEANFILES += $(DEVASCIIFONTSFILES) font/devascii/DESC ++EXTRA_DIST += \ ++ font/devascii/R.proto \ ++ font/devascii/DESC.proto ++ ++$(DEVASCIIFONTSFILES): $(devascii_srcdir)/R.proto ++ @echo Making $@ ++ $(MKDIR_P) `dirname $@` ++ $(RM) $@ ++ $(SHELL) $(GENFONTSSH) $(devascii_srcdir)/R.proto \ ++ $(DEVASCIIRES) $(DEVASCIICPI) `basename $@` > $@ ++ ++font/devascii/DESC: $(devascii_srcdir)/DESC.proto ++ @echo Making $@ ++ $(MKDIR_P) `dirname $@` ++ $(SHELL) $(GENDESCSH) $(devascii_srcdir)/DESC.proto \ ++ $(DEVASCIIRES) $(DEVASCIICPI) $(DEVASCIILPI) $(DEVASCIIFONTS) > $@ +diff -Nuar groff-1.22.3.old/font/devascii/.gitignore groff-1.22.3/font/devascii/.gitignore +--- groff-1.22.3.old/font/devascii/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devascii/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,5 @@ ++B ++BI ++DESC ++I ++R +diff -Nuar groff-1.22.3.old/font/devascii/Makefile.sub groff-1.22.3/font/devascii/Makefile.sub +--- groff-1.22.3.old/font/devascii/Makefile.sub 2014-11-04 10:38:35.401521797 +0200 ++++ groff-1.22.3/font/devascii/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,68 +0,0 @@ +-# Makefile.sub for `font devascii' +-# +-# File position: /font/devascii/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=ascii +-FONTS=R I B BI +-DEVFILES=$(FONTS) DESC +-MOSTLYCLEANADD=$(FONTS) DESC +- +-RES=240 +-CPI=10 +-LPI=6 +- +-RM=rm -f +- +-$(FONTS): R.proto +- @echo Making $@ +- @$(RM) $@ +- @charwidth=`expr $(RES) / $(CPI)` ; \ +- sed -e "s/^name [A-Z]*$$/name $@/" \ +- -e \ +- "s/^\\([^ ]*\\) [0-9][0-9]* /\\1 $$charwidth /" \ +- -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ +- -e "s/^internalname .*$$/internalname $@/" \ +- -e "/^internalname/s/BI/3/" \ +- -e "/^internalname/s/B/2/" \ +- -e "/^internalname/s/I/1/" \ +- -e "/^internalname .*[^ 0-9]/d" \ +- $(srcdir)/R.proto >$@ +- +-DESC: DESC.proto +- @echo Making $@ +- @sed -e "s/^res .*$$/res $(RES)/" \ +- -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \ +- -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \ +- -e "s/^fonts .*$$/fonts `set $(FONTS); echo $$#` $(FONTS)/" \ +- $(srcdir)/DESC.proto >$@ +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devcp1047/devcp1047.am groff-1.22.3/font/devcp1047/devcp1047.am +--- groff-1.22.3.old/font/devcp1047/devcp1047.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devcp1047/devcp1047.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,44 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++devcp1047_srcdir = $(top_srcdir)/font/devcp1047 ++DEVCP1047FONTS = R I B BI ++DEVCP1047FONTSFILES = \ ++ font/devcp1047/R font/devcp1047/I font/devcp1047/B font/devcp1047/BI ++ ++DEVCP1047RES = 240 ++DEVCP1047CPI = 10 ++DEVCP1047LPI = 6 ++ ++devcp1047fontdir = $(fontdir)/devcp1047 ++devcp1047font_DATA = $(DEVCP1047FONTSFILES) font/devcp1047/DESC ++MOSTLYCLEANFILES += $(DEVCP1047FONTSFILES) font/devcp1047/DESC ++EXTRA_DIST += font/devcp1047/R.proto font/devcp1047/DESC.proto ++ ++$(DEVCP1047FONTSFILES): $(devcp1047_srcdir)/R.proto ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @$(RM) $@ ++ @$(SHELL) $(GENFONTSSH) $(devcp1047_srcdir)/R.proto \ ++ $(DEVCP1047RES) $(DEVCP1047CPI) `basename $@` > $@ ++ ++font/devcp1047/DESC: $(devcp1047_srcdir)/DESC.proto ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @$(SHELL) $(GENDESCSH) $(devcp1047_srcdir)/DESC.proto \ ++ $(DEVCP1047RES) $(DEVCP1047CPI) $(DEVCP1047LPI) $(DEVCP1047FONTS) > $@ +diff -Nuar groff-1.22.3.old/font/devcp1047/.gitignore groff-1.22.3/font/devcp1047/.gitignore +--- groff-1.22.3.old/font/devcp1047/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devcp1047/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,5 @@ ++B ++BI ++DESC ++I ++R +diff -Nuar groff-1.22.3.old/font/devcp1047/Makefile.sub groff-1.22.3/font/devcp1047/Makefile.sub +--- groff-1.22.3.old/font/devcp1047/Makefile.sub 2014-11-04 10:38:35.414521634 +0200 ++++ groff-1.22.3/font/devcp1047/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,68 +0,0 @@ +-# Makefile.sub for `font devcp1047' +-# +-# File position: /font/devcp1047/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=cp1047 +-FONTS=R I B BI +-DEVFILES=$(FONTS) DESC +-MOSTLYCLEANADD=$(FONTS) DESC +- +-RES=240 +-CPI=10 +-LPI=6 +- +-RM=rm -f +- +-$(FONTS): R.proto +- @echo Making $@ +- @$(RM) $@ +- @charwidth=`expr $(RES) / $(CPI)` ; \ +- sed -e "s/^name [A-Z]*$$/name $@/" \ +- -e \ +- "s/^\\([^ ]*\\) [0-9][0-9]* /\\1 $$charwidth /" \ +- -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ +- -e "s/^internalname .*$$/internalname $@/" \ +- -e "/^internalname/s/BI/3/" \ +- -e "/^internalname/s/B/2/" \ +- -e "/^internalname/s/I/1/" \ +- -e "/^internalname .*[^ 0-9]/d" \ +- $(srcdir)/R.proto >$@ +- +-DESC: DESC.proto +- @echo Making $@ +- @sed -e "s/^res .*$$/res $(RES)/" \ +- -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \ +- -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \ +- -e "s/^fonts .*$$/fonts `set $(FONTS); echo $$#` $(FONTS)/" \ +- $(srcdir)/DESC.proto >$@ +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devdvi/devdvi.am groff-1.22.3/font/devdvi/devdvi.am +--- groff-1.22.3.old/font/devdvi/devdvi.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devdvi/devdvi.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,90 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++devdvi_srcdir = $(top_srcdir)/font/devdvi ++DEVDVIFONTFILES = \ ++ font/devdvi/TR \ ++ font/devdvi/TI \ ++ font/devdvi/TB \ ++ font/devdvi/TBI \ ++ font/devdvi/CW \ ++ font/devdvi/CWI \ ++ font/devdvi/HR \ ++ font/devdvi/HI \ ++ font/devdvi/HB \ ++ font/devdvi/HBI \ ++ font/devdvi/TREC \ ++ font/devdvi/TIEC \ ++ font/devdvi/TBEC \ ++ font/devdvi/TBIEC \ ++ font/devdvi/CWEC \ ++ font/devdvi/CWIEC \ ++ font/devdvi/HREC \ ++ font/devdvi/HIEC \ ++ font/devdvi/HBEC \ ++ font/devdvi/HBIEC \ ++ font/devdvi/TRTC \ ++ font/devdvi/TITC \ ++ font/devdvi/TBTC \ ++ font/devdvi/TBITC \ ++ font/devdvi/CWTC \ ++ font/devdvi/CWITC \ ++ font/devdvi/HRTC \ ++ font/devdvi/HITC \ ++ font/devdvi/HBTC \ ++ font/devdvi/HBITC \ ++ font/devdvi/MI \ ++ font/devdvi/S \ ++ font/devdvi/EX \ ++ font/devdvi/SA \ ++ font/devdvi/SB \ ++ font/devdvi/SC ++devdvifontdir = $(fontdir)/devdvi ++devdvifont_DATA = $(DEVDVIFONTFILES) font/devdvi/DESC ++ ++DEVDVIGENFILES = \ ++ font/devdvi/generate/Makefile \ ++ font/devdvi/generate/msam.map \ ++ font/devdvi/generate/msbm.map \ ++ font/devdvi/generate/texb.map \ ++ font/devdvi/generate/texex.map \ ++ font/devdvi/generate/texi.map \ ++ font/devdvi/generate/texmi.map \ ++ font/devdvi/generate/texr.map \ ++ font/devdvi/generate/texsy.map \ ++ font/devdvi/generate/textt.map \ ++ font/devdvi/generate/textex.map \ ++ font/devdvi/generate/ec.map \ ++ font/devdvi/generate/tc.map \ ++ font/devdvi/generate/CompileFonts ++devdvigendir = $(fontdir)/devdvi/generate ++devdvigen_DATA = $(DEVDVIGENFILES) ++ ++EXTRA_DIST += $(DEVDVIFONTFILES) $(DEVDVIGENFILES) font/devdvi/DESC.in ++MOSTLYCLEANFILES += font/devdvi/DESC ++ ++font/devdvi/DESC: $(devdvi_srcdir)/DESC.in ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @cat $(devdvi_srcdir)/DESC.in >$@ ++ @if test "$(PAGE)" = A4; then \ ++ echo "papersize a4" >>$@; \ ++ else \ ++ echo "papersize letter" >>$@; \ ++ fi ++ @test -z '$(DVIPRINT)' || echo print '$(DVIPRINT)' >>$@ +diff -Nuar groff-1.22.3.old/font/devdvi/.gitignore groff-1.22.3/font/devdvi/.gitignore +--- groff-1.22.3.old/font/devdvi/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devdvi/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++DESC +diff -Nuar groff-1.22.3.old/font/devdvi/Makefile.sub groff-1.22.3/font/devdvi/Makefile.sub +--- groff-1.22.3.old/font/devdvi/Makefile.sub 2014-11-04 10:38:35.350522434 +0200 ++++ groff-1.22.3/font/devdvi/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,58 +0,0 @@ +-# Makefile.sub for `font devdvi' +-# +-# File position: /font/devdvi/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=dvi +-DEVFILES=DESC \ +- TR TI TB TBI CW CWI HR HI HB HBI \ +- TREC TIEC TBEC TBIEC CWEC CWIEC HREC HIEC HBEC HBIEC \ +- TRTC TITC TBTC TBITC CWTC CWITC HRTC HITC HBTC HBITC \ +- MI S EX SA SB SC \ +- generate/Makefile \ +- generate/msam.map generate/msbm.map \ +- generate/texb.map generate/texex.map generate/texi.map generate/texmi.map \ +- generate/texr.map generate/texsy.map generate/textt.map generate/textex.map \ +- generate/ec.map generate/tc.map +-DEVSCRIPTS=generate/CompileFonts +- +-MOSTLYCLEANADD=DESC +- +-DESC: DESC.in +- cat $(srcdir)/DESC.in >DESC +- if test "$(PAGE)" = A4; then \ +- echo "papersize a4" >>DESC; \ +- else \ +- echo "papersize letter" >>DESC; \ +- fi +- test -z '$(DVIPRINT)' || echo print '$(DVIPRINT)' >>DESC +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devhtml/devhtml.am groff-1.22.3/font/devhtml/devhtml.am +--- groff-1.22.3.old/font/devhtml/devhtml.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devhtml/devhtml.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,56 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++devhtml_srcdir = $(top_srcdir)/font/devhtml ++DEVHTMLFONTS = R I B BI CR CI CB CBI S ++DEVHTMLFONTSFILES = \ ++ font/devhtml/R \ ++ font/devhtml/I \ ++ font/devhtml/B \ ++ font/devhtml/BI \ ++ font/devhtml/CR \ ++ font/devhtml/CI \ ++ font/devhtml/CB \ ++ font/devhtml/CBI \ ++ font/devhtml/S ++ ++DEVHTMLRES = 240 ++DEVHTMLCPI = 10 ++DEVHTMLLPI = 6 ++ ++devhtmlfontdir = $(fontdir)/devhtml ++devhtmlfont_DATA = $(DEVHTMLFONTSFILES) font/devhtml/DESC ++MOSTLYCLEANFILES += $(DEVHTMLFONTSFILES) font/devhtml/DESC ++EXTRA_DIST += \ ++ font/devhtml/R.proto \ ++ font/devhtml/DESC.proto \ ++ font/devhtml/R.in ++ ++$(DEVHTMLFONTSFILES): $(devhtml_srcdir)/R.proto ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @$(RM) $@ ++ @$(SHELL) $(GENFONTSSH) $(devhtml_srcdir)/R.proto \ ++ $(DEVHTMLRES) $(DEVHTMLCPI) `basename $@` > $@ ++ ++font/devhtml/DESC: $(devhtml_srcdir)/DESC.proto ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @$(SHELL) $(GENDESCSH) $(devhtml_srcdir)/DESC.proto \ ++ $(DEVHTMLRES) $(DEVHTMLCPI) $(DEVHTMLLPI) $(DEVHTMLFONTS) > $@ ++ @echo "image_generator $(GHOSTSCRIPT)" >> $@ +diff -Nuar groff-1.22.3.old/font/devhtml/.gitignore groff-1.22.3/font/devhtml/.gitignore +--- groff-1.22.3.old/font/devhtml/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devhtml/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,10 @@ ++B ++BI ++CB ++CBI ++CI ++CR ++DESC ++I ++R ++S +diff -Nuar groff-1.22.3.old/font/devhtml/Makefile.sub groff-1.22.3/font/devhtml/Makefile.sub +--- groff-1.22.3.old/font/devhtml/Makefile.sub 2014-11-04 10:38:35.356522359 +0200 ++++ groff-1.22.3/font/devhtml/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,71 +0,0 @@ +-# Makefile.sub for `font devhtml' +-# +-# File position: /font/devhtml/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=html +-PROTOFONTS=R I B BI CR CI CB CBI +-FONTS=$(PROTOFONTS) S +-DEVFILES=$(FONTS) DESC +-MOSTLYCLEANADD=$(FONTS) DESC +- +-RES=240 +-CPI=10 +-LPI=6 +- +-RM=rm -f +- +-$(FONTS): R.proto +- @echo Making $@ +- @$(RM) $@ +- @charwidth=`expr $(RES) / $(CPI)` ; \ +- sed -e "s/^name [A-Z]*$$/name $@/" \ +- -e \ +- "s/^\\([^ ]*\\) [0-9][0-9]* /\\1 $$charwidth /" \ +- -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ +- -e "s/^internalname .*$$/internalname $@/" \ +- -e "/^internalname/s/CR/4/" \ +- -e "/^internalname/s/BI/3/" \ +- -e "/^internalname/s/B/2/" \ +- -e "/^internalname/s/I/1/" \ +- -e "/^internalname .*[^ 0-9]/d" \ +- $(srcdir)/R.proto >$@ +- +-DESC: DESC.proto +- @echo Making $@ +- @sed -e "s/^res .*$$/res $(RES)/" \ +- -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \ +- -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \ +- -e "s/^fonts .*$$/fonts `set $(FONTS); echo $$#` $(FONTS)/" \ +- $(srcdir)/DESC.proto >$@ +- @echo "image_generator $(GHOSTSCRIPT)" >> $@ +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devlatin1/devlatin1.am groff-1.22.3/font/devlatin1/devlatin1.am +--- groff-1.22.3.old/font/devlatin1/devlatin1.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devlatin1/devlatin1.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,44 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++devlatin1_srcdir = $(top_srcdir)/font/devlatin1 ++DEVLATIN1FONTS = R I B BI ++DEVLATIN1FONTSFILES = \ ++ font/devlatin1/R font/devlatin1/I font/devlatin1/B font/devlatin1/BI ++ ++DEVLATIN1RES = 240 ++DEVLATIN1CPI = 10 ++DEVLATIN1LPI = 6 ++ ++devlatin1fontdir = $(fontdir)/devlatin1 ++devlatin1font_DATA = $(DEVLATIN1FONTSFILES) font/devlatin1/DESC ++MOSTLYCLEANFILES += $(DEVLATIN1FONTSFILES) font/devlatin1/DESC ++EXTRA_DIST += font/devlatin1/R.proto font/devlatin1/DESC.proto ++ ++$(DEVLATIN1FONTSFILES): $(devlatin1_srcdir)/R.proto ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @$(RM) $@ ++ @$(SHELL) $(GENFONTSSH) $(devlatin1_srcdir)/R.proto \ ++ $(DEVLATIN1RES) $(DEVLATIN1CPI) `basename $@` > $@ ++ ++font/devlatin1/DESC: $(devlatin1_srcdir)/DESC.proto ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @$(SHELL) $(GENDESCSH) $(devlatin1_srcdir)/DESC.proto \ ++ $(DEVLATIN1RES) $(DEVLATIN1CPI) $(DEVLATIN1LPI) $(DEVLATIN1FONTS) > $@ +diff -Nuar groff-1.22.3.old/font/devlatin1/.gitignore groff-1.22.3/font/devlatin1/.gitignore +--- groff-1.22.3.old/font/devlatin1/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devlatin1/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,5 @@ ++B ++BI ++DESC ++I ++R +diff -Nuar groff-1.22.3.old/font/devlatin1/Makefile.sub groff-1.22.3/font/devlatin1/Makefile.sub +--- groff-1.22.3.old/font/devlatin1/Makefile.sub 2014-11-04 10:38:35.405521747 +0200 ++++ groff-1.22.3/font/devlatin1/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,65 +0,0 @@ +-# Makefile.sub for `font devlatin1' +-# +-# File position: /font/devlatin1/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=latin1 +-FONTS=R I B BI +-DEVFILES=$(FONTS) DESC +-MOSTLYCLEANADD=$(FONTS) DESC +- +-RES=240 +-CPI=10 +-LPI=6 +- +-RM=rm -f +- +-$(FONTS): R.proto +- @echo Making $@ +- @$(RM) $@ +- @charwidth=`expr $(RES) / $(CPI)` ; \ +- sed -e "s/^name [A-Z]*$$/name $@/" \ +- -e \ +- "s/^\\([^ ]*\\) [0-9][0-9]* /\\1 $$charwidth /" \ +- -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ +- -e "s/^internalname .*$$/internalname $@/" \ +- -e "/^internalname/s/BI/3/" \ +- -e "/^internalname/s/B/2/" \ +- -e "/^internalname/s/I/1/" \ +- -e "/^internalname .*[^ 0-9]/d" \ +- $(srcdir)/R.proto >$@ +- +-DESC: DESC.proto +- @echo Making $@ +- @sed -e "s/^res .*$$/res $(RES)/" \ +- -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \ +- -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \ +- -e "s/^fonts .*$$/fonts `set $(FONTS); echo $$#` $(FONTS)/" \ +- $(srcdir)/DESC.proto >$@ +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devlbp/devlbp.am groff-1.22.3/font/devlbp/devlbp.am +--- groff-1.22.3.old/font/devlbp/devlbp.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devlbp/devlbp.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,54 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++LBPPRINT=$(PSPRINT) ++devlbp_srcdir = $(top_srcdir)/font/devlbp ++DEVLBPFONTFILES = \ ++ font/devlbp/HB \ ++ font/devlbp/HBI \ ++ font/devlbp/HI \ ++ font/devlbp/HR \ ++ font/devlbp/HNB \ ++ font/devlbp/HNBI \ ++ font/devlbp/HNI \ ++ font/devlbp/HNR \ ++ font/devlbp/TB \ ++ font/devlbp/TBI \ ++ font/devlbp/TI \ ++ font/devlbp/TR \ ++ font/devlbp/CR \ ++ font/devlbp/CB \ ++ font/devlbp/CI \ ++ font/devlbp/ER \ ++ font/devlbp/EB \ ++ font/devlbp/EI ++devlbpfontdir = $(fontdir)/devlbp ++devlbpfont_DATA = $(DEVLBPFONTFILES) font/devlbp/DESC ++EXTRA_DIST += $(DEVLBPFONTFILES) font/devlbp/DESC.in ++MOSTLYCLEANFILES += font/devlbp/DESC ++ ++font/devlbp/DESC: $(devlbp_srcdir)/DESC.in ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @cat $(devlbp_srcdir)/DESC.in >$@ ++ @if test "$(PAGE)" = A4; then \ ++ echo "papersize a4" >>$@; \ ++ else \ ++ echo "papersize letter" >>$@; \ ++ fi ++ @test -z '$(LBPPRINT)' || echo print '$(LBPPRINT)' >>$@ +diff -Nuar groff-1.22.3.old/font/devlbp/.gitignore groff-1.22.3/font/devlbp/.gitignore +--- groff-1.22.3.old/font/devlbp/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devlbp/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++DESC +diff -Nuar groff-1.22.3.old/font/devlbp/Makefile.sub groff-1.22.3/font/devlbp/Makefile.sub +--- groff-1.22.3.old/font/devlbp/Makefile.sub 2014-11-04 10:38:35.396521859 +0200 ++++ groff-1.22.3/font/devlbp/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,54 +0,0 @@ +-# Makefile.sub for `font devlbp' +-# +-# File position: /font/devlbp/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=lbp +-LBPPRINT=$(PSPRINT) +-DEVFILES=DESC \ +- HB HBI HI HR \ +- HNB HNBI HNI HNR \ +- TB TBI TI TR \ +- CR CB CI \ +- ER EB EI +- +-MOSTLYCLEANADD=DESC +- +-DESC: DESC.in +- cat $(srcdir)/DESC.in >DESC +- if test "$(PAGE)" = A4; then \ +- echo "papersize a4" >>DESC; \ +- else \ +- echo "papersize letter" >>DESC; \ +- fi +- test -z '$(LBPPRINT)' || echo print '$(LBPPRINT)' >>DESC +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devlj4/devlj4.am groff-1.22.3/font/devlj4/devlj4.am +--- groff-1.22.3.old/font/devlj4/devlj4.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devlj4/devlj4.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,104 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++devlj4_srcdir = $(top_srcdir)/font/devlj4 ++LJ4RES = 1200 ++LJ4PRINT = $(PSPRINT) ++DEVLJ4FONTFILES = \ ++ font/devlj4/AB \ ++ font/devlj4/ABI \ ++ font/devlj4/AI \ ++ font/devlj4/AR \ ++ font/devlj4/ALBB \ ++ font/devlj4/ALBR \ ++ font/devlj4/AOB \ ++ font/devlj4/AOI \ ++ font/devlj4/AOR \ ++ font/devlj4/CB \ ++ font/devlj4/CBI \ ++ font/devlj4/CI \ ++ font/devlj4/CR \ ++ font/devlj4/GB \ ++ font/devlj4/GBI \ ++ font/devlj4/GI \ ++ font/devlj4/GR \ ++ font/devlj4/LGB \ ++ font/devlj4/LGI \ ++ font/devlj4/LGR \ ++ font/devlj4/OB \ ++ font/devlj4/OBI \ ++ font/devlj4/OI \ ++ font/devlj4/OR \ ++ font/devlj4/TB \ ++ font/devlj4/TBI \ ++ font/devlj4/TI \ ++ font/devlj4/TR \ ++ font/devlj4/TNRB \ ++ font/devlj4/TNRBI \ ++ font/devlj4/TNRI \ ++ font/devlj4/TNRR \ ++ font/devlj4/UB \ ++ font/devlj4/UBI \ ++ font/devlj4/UI \ ++ font/devlj4/UR \ ++ font/devlj4/UCB \ ++ font/devlj4/UCBI \ ++ font/devlj4/UCI \ ++ font/devlj4/UCR \ ++ font/devlj4/CLARENDON \ ++ font/devlj4/CORONET \ ++ font/devlj4/MARIGOLD \ ++ font/devlj4/S \ ++ font/devlj4/SYMBOL \ ++ font/devlj4/WINGDINGS ++ ++devlj4fontdir = $(fontdir)/devlj4 ++dist_devlj4font_DATA = $(DEVLJ4FONTFILES) ++nodist_devlj4font_DATA = font/devlj4/DESC ++ ++DEVLJ4GENFILES = \ ++ font/devlj4/generate/Makefile \ ++ font/devlj4/generate/special.map \ ++ font/devlj4/generate/symbol.map \ ++ font/devlj4/generate/text.map \ ++ font/devlj4/generate/wingdings.map \ ++ font/devlj4/generate/special.awk ++devlj4fontgendir = $(devlj4fontdir)/generate ++dist_devlj4fontgen_DATA = $(DEVLJ4GENFILES) ++ ++EXTRA_DIST += font/devlj4/DESC.in ++ ++MOSTLYCLEANFILES += font/devlj4/DESC ++ ++font/devlj4/DESC: $(devlj4_srcdir)/DESC.in ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @echo "res $(LJ4RES)" >$@ ++ @echo "unitwidth `expr 7620000 / $(LJ4RES)`" >>$@ ++ @cat $(devlj4_srcdir)/DESC.in >>$@ ++ @if test "$(PAGE)" = A4; then \ ++ echo "papersize a4" >>$@; \ ++ else \ ++ echo "papersize letter" >>$@; \ ++ fi ++ @test -z '$(LJ4PRINT)' || echo print '$(LJ4PRINT)' >>$@ ++ ++fonts: devlj4_fonts ++devlj4_fonts: hpftodit font/devlj4/DESC ++ $(MAKE) -f $(devlj4_srcdir)/generate/Makefile \ ++ srcdir=$(devlj4_srcdir)/generate HPFTODIT=$(top_builddir)/hpftodit +diff -Nuar groff-1.22.3.old/font/devlj4/.gitignore groff-1.22.3/font/devlj4/.gitignore +--- groff-1.22.3.old/font/devlj4/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devlj4/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++DESC +diff -Nuar groff-1.22.3.old/font/devlj4/Makefile.sub groff-1.22.3/font/devlj4/Makefile.sub +--- groff-1.22.3.old/font/devlj4/Makefile.sub 2014-11-04 10:38:35.387521972 +0200 ++++ groff-1.22.3/font/devlj4/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,77 +0,0 @@ +-# Makefile.sub for `font devlj4' +-# +-# File position: /font/devlj4/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# Written by Werner Lemberg and +-# Bernd Warken . +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `groffer' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=lj4 +-LJ4RES=1200 +-LJ4PRINT=$(PSPRINT) +-DEVFILES=DESC \ +- AB ABI AI AR \ +- ALBB ALBR \ +- AOB AOI AOR \ +- CB CBI CI CR \ +- GB GBI GI GR \ +- LGB LGI LGR \ +- OB OBI OI OR \ +- TB TBI TI TR \ +- TNRB TNRBI TNRI TNRR \ +- UB UBI UI UR \ +- UCB UCBI UCI UCR \ +- CLARENDON CORONET MARIGOLD S \ +- SYMBOL WINGDINGS \ +- generate/Makefile \ +- generate/special.map \ +- generate/symbol.map \ +- generate/text.map \ +- generate/wingdings.map \ +- generate/special.awk +- +-MOSTLYCLEANADD=DESC +- +-DESC: DESC.in +- echo "res $(LJ4RES)" >DESC +- echo "unitwidth `expr 7620000 / $(LJ4RES)`" >>DESC +- cat $(srcdir)/DESC.in >>DESC +- if test "$(PAGE)" = A4; then \ +- echo "papersize a4" >>DESC; \ +- else \ +- echo "papersize letter" >>DESC; \ +- fi +- test -z '$(LJ4PRINT)' || echo print '$(LJ4PRINT)' >>DESC +- +-fonts: +- $(MAKE) -f $(srcdir)/generate/Makefile srcdir=$(srcdir)/generate \ +- HPFTODIT=$(top_builddir)/src/utils/hpftodit/hpftodit +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devpdf/devpdf.am groff-1.22.3/font/devpdf/devpdf.am +--- groff-1.22.3.old/font/devpdf/devpdf.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devpdf/devpdf.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,167 @@ ++# Copyright (C) 2011-2014 Free Software Foundation, Inc. ++# Free Software Foundation, Inc. ++# Original Makefile.sub Written ++# by Deri James ++# Automake migration by Bertrand Garrigues ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++devpdf_srcdir = $(top_srcdir)/font/devpdf ++GROFF_FONT_FILES=`cd $(top_builddir)/font/devpdf && grep -l internalname * | grep -v devpdf.am` ++ENC_FILES=`cd $(top_builddir)/font/devpdf; ls enc/*` ++MAP_FILES=`cd $(top_builddir)/font/devpdf; ls map/*` ++ ++MOSTLYCLEANFILES += \ ++ font/devpdf/download \ ++ font/devpdf/DESC \ ++ font/devpdf/Foundry \ ++ font/devpdf/build_font_files \ ++ font/devpdf/util/BuildFoundries ++ ++devpdffontdir = $(fontdir)/devpdf ++devpdffont_DATA = \ ++ font/devpdf/DESC \ ++ font/devpdf/Foundry ++ ++devpdffontencdir = $(devpdffontdir)/enc ++devpdffontenc_DATA = font/devpdf/enc/text.enc ++ ++devpdffontmapdir = $(devpdffontdir)/map ++DEVPDFFONTMAP_1 = \ ++ font/devpdf/map/dingbats.map \ ++ font/devpdf/map/symbolchars \ ++ font/devpdf/map/textmap ++DEVPDFFONTMAP_2 = font/devpdf/map/symbolmap ++devpdffontmap_DATA = $(DEVPDFFONTMAP_1) $(DEVPDFFONTMAP_2) ++ ++devpdffontutildir = $(devpdffontdir)/util ++nodist_devpdffontutil_DATA = font/devpdf/util/BuildFoundries ++ ++EXTRA_DIST += \ ++ font/devpdf/DESC.in \ ++ font/devpdf/Foundry.in \ ++ font/devpdf/util/BuildFoundries.pl ++ ++font/devpdf/enc/text.enc: ++ @$(MKDIR_P) $(top_builddir)/font/devpdf/enc ++ cp -f $(top_srcdir)/font/devps/text.enc \ ++ $(top_builddir)/font/devpdf/enc ++ ++font/devpdf/map/symbolmap: ++ @$(MKDIR_P) $(top_builddir)/font/devpdf/map ++ @cp -f $(top_srcdir)/font/devps/symbolmap \ ++ $(top_builddir)/font/devpdf/map ++ ++$(DEVPDFFONTMAP_1): ++ @$(MKDIR_P) $(top_builddir)/font/devpdf/map ++ @cp -f $(top_srcdir)/font/devps/generate/`basename $@` \ ++ $(top_builddir)/font/devpdf/map ++ ++font/devpdf/util/BuildFoundries: shdeps.sed $(devpdf_srcdir)/util/BuildFoundries.pl ++ @echo Making $@ ++ @$(MKDIR_P) $(top_builddir)/font/devpdf/util ++ @$(RM) $(top_builddir)/font/devpdf/util/BuildFoundries ++ @if test -n "$(PERL)"; then \ ++ sed -f $(SH_DEPS_SED_SCRIPT) \ ++ -e "s|/usr/bin/perl|$(PERL)|" \ ++ -e "s|[@]GROFF_GHOSTSCRIPT_INTERPRETERS[@]|$(GHOSTSCRIPT)|" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|" \ ++ -e "s|[@]GROFF_FONT_DIR[@]|$(fontdir)|" \ ++ $(devpdf_srcdir)/util/BuildFoundries.pl \ ++ >$(top_builddir)/font/devpdf/util/BuildFoundries ;\ ++ else \ ++ sed -f $(SH_DEPS_SED_SCRIPT) \ ++ -e "s|[@]VERSION[@]|$(VERSION)|" \ ++ -e "s|[@]GROFF_FONT_DIR[@]|$(fontdir)|" \ ++ $(devpdf_srcdir)/util/BuildFoundries.pl \ ++ >$(top_builddir)/font/devpdf/util/BuildFoundries ;\ ++ fi ++ @chmod +x $(top_builddir)/font/devpdf/util/BuildFoundries ++ ++font/devpdf/DESC: $(devpdf_srcdir)/DESC.in ++ @echo Making $@ ++ @$(MKDIR_P) $(top_builddir)/font/devpdf ++ @$(RM) $(top_builddir)/font/devpdf/DESC ++ @cat $(devpdf_srcdir)/DESC.in >$(top_builddir)/font/devpdf/DESC ++ @if test "$(PAGE)" = A4; then \ ++ echo "papersize a4" >>$(top_builddir)/font/devpdf/DESC; \ ++ else \ ++ echo "papersize letter" >>$(top_builddir)/font/devpdf/DESC; \ ++ fi ++ ++font/devpdf/Foundry: ++ @$(RM) $(top_builddir)/font/devpdf/Foundry ++ @cat $(devpdf_srcdir)/Foundry.in >$(top_builddir)/font/devpdf/Foundry ++ ++all: font/devpdf/build_font_files ++ ++# PATH : path to find afmtodit. We add $(abs_top_builddir) because afmtodit is ++# built in the top builddir. ++font/devpdf/build_font_files: afmtodit font/devpdf/DESC $(devpdffontenc_DATA) $(devpdffontmap_DATA) $(devpdffont_DATA) font/devpdf/util/BuildFoundries ++ @echo Making all fonts ++ @$(RM) $@ ++ @$(MKDIR_P) $(top_builddir)/font/devpdf ++ @echo "# foundry ps name psfile" > $(top_builddir)/font/devpdf/download ++ PATH="$(abs_top_builddir)$(GROFF_PATH_SEPARATOR)$(abs_top_builddir)/build-aux$(GROFF_PATH_SEPARATOR)$(PATH)" \ ++ $(abs_top_builddir)/font/devpdf/util/BuildFoundries $(abs_top_builddir)/font/devpdf \ ++ '$(abs_top_srcdir)/font/devps : $(abs_top_builddir)/font/devps' \ ++ >> $(top_builddir)/font/devpdf/download ++ @touch $@ ++ ++mostlyclean-local: mostlyclean_devpdf_extra ++mostlyclean_devpdf_extra: ++ @echo Cleaning font/devpdf ++ rm -rf $(top_builddir)/font/devpdf/enc $(top_builddir)/font/devpdf/map; ++ if test -d $(top_builddir)/font/devpdf; then \ ++ for f in $(GROFF_FONT_FILES); do \ ++ rm -f $(top_builddir)/font/devpdf/$$f; \ ++ done; \ ++ fi ++ ++install-data-local: install_devpdf ++install_devpdf: ++ @echo Installing devpdf files ++ -@test -d $(DESTDIR)$(devpdffontdir)/util \ ++ || $(mkinstalldirs) $(DESTDIR)$(devpdffontdir)/util ++ @for f in $(GROFF_FONT_FILES); do \ ++ $(RM) $(DESTDIR)$(devpdffontdir)/$$f; \ ++ if test -f $$f; then \ ++ $(INSTALL_DATA) $$f $(DESTDIR)$(devpdffontdir)/$$f; \ ++ else \ ++ $(INSTALL_DATA) $(top_builddir)/font/devpdf/$$f $(DESTDIR)$(devpdffontdir)/$$f; \ ++ fi; \ ++ done ++ $(INSTALL_DATA) $(top_builddir)/font/devpdf/download $(DESTDIR)$(devpdffontdir)/ ++ ++uninstall_groffdirs: uninstall_devpdf ++uninstall_devpdf: ++ @echo Uninstalling devpdf files ++ if test -d $(DESTDIR)$(devpdffontdir); then \ ++ for f in $(GROFF_FONT_FILES); do \ ++ rm -f $(DESTDIR)$(devpdffontdir)/$$f; \ ++ done; \ ++ if test -d $(DESTDIR)$(devpdffontutildir); then \ ++ rmdir $(DESTDIR)$(devpdffontutildir); \ ++ fi; \ ++ if test -d $(DESTDIR)$(devpdffontencdir); then \ ++ rmdir $(DESTDIR)$(devpdffontencdir); \ ++ fi; \ ++ if test -d $(DESTDIR)$(devpdffontmapdir); then \ ++ rmdir $(DESTDIR)$(devpdffontmapdir); \ ++ fi; \ ++ rm -f $(DESTDIR)$(devpdffontdir)/download; \ ++ rmdir $(DESTDIR)$(devpdffontdir); \ ++ fi +diff -Nuar groff-1.22.3.old/font/devpdf/Makefile.sub groff-1.22.3/font/devpdf/Makefile.sub +--- groff-1.22.3.old/font/devpdf/Makefile.sub 2014-11-04 10:38:35.427521472 +0200 ++++ groff-1.22.3/font/devpdf/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,139 +0,0 @@ +-# Makefile.sub for `font devpdf' +-# +-# File position: /font/devpdf/Makefile.sub +-# +-# Copyright (C) 2011-2014 Free Software Foundation, Inc. +-# Written by Deri James +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-DEV=pdf +-GROFF_FONT_FILES=`cd $(top_builddir)/font/devpdf \ +- && find * -maxdepth 0 -type f ! -name 'Makefile.sub*' \ +- -exec grep -l internalname {} \;` +-ENC_FILES=`cd $(top_builddir)/font/devpdf; ls enc/*` +-MAP_FILES=`cd $(top_builddir)/font/devpdf; ls map/*` +- +-MOSTLYCLEANADD=\ +- download \ +- DESC \ +- Foundry \ +- util/BuildFoundries \ +- $(GROFF_FONT_FILES) \ +- $(ENC_FILES) \ +- $(MAP_FILES) +- +-MOSTLYCLEANDIRADD=enc map +- +-DEVFILES=\ +- Foundry +- +-#DEVSCRIPTS=util/BuildFoundries +- +-DISTFILES=\ +- $(DEVFILES) \ +- $(DEVSCRIPTS) +- +-RM=rm -f +- +-all: DESC +- +-DESC: DESC.in +- $(RM) DESC +- cat $(srcdir)/DESC.in >$(top_builddir)/font/devpdf/DESC +- if test "$(PAGE)" = A4; then \ +- echo "papersize a4" >>$(top_builddir)/font/devpdf/DESC; \ +- else \ +- echo "papersize letter" >>$(top_builddir)/font/devpdf/DESC; \ +- fi +- $(RM) Foundry +- cat $(srcdir)/Foundry.in >$(top_builddir)/font/devpdf/Foundry +- -test -d $(top_builddir)/font/devpdf/enc \ +- || $(mkinstalldirs) $(top_builddir)/font/devpdf/enc +- -test -d $(top_builddir)/font/devpdf/map \ +- || $(mkinstalldirs) $(top_builddir)/font/devpdf/map +- cp -f $(top_srcdir)/font/devps/text.enc \ +- $(top_builddir)/font/devpdf/enc +- cp -f $(top_srcdir)/font/devps/symbolmap \ +- $(top_builddir)/font/devpdf/map +- cp -f $(top_srcdir)/font/devps/generate/dingbats.map \ +- $(top_builddir)/font/devpdf/map +- cp -f $(top_srcdir)/font/devps/generate/textmap \ +- $(top_builddir)/font/devpdf/map +- cp -f $(top_srcdir)/font/devps/generate/symbolchars \ +- $(top_builddir)/font/devpdf/map +- -test -d util || $(mkinstalldirs) util +- $(RM) util/BuildFoundries +- if test -n "$(PERL)"; then \ +- sed -f $(SH_DEPS_SED_SCRIPT) \ +- -e "s|/usr/bin/perl|$(PERL)|" \ +- -e "s|@GROFF_GHOSTSCRIPT_INTERPRETERS@|$(GHOSTSCRIPT)|" \ +- -e "s|@VERSION@|$(version)$(revision)|" \ +- -e "s|@GROFF_FONT_DIR@|$(fontdir)|" \ +- $(srcdir)/util/BuildFoundries.pl \ +- >$(top_builddir)/font/devpdf/util/BuildFoundries ;\ +- else \ +- sed -f $(SH_DEPS_SED_SCRIPT) \ +- -e "s|@VERSION@|$(version)$(revision)|" \ +- -e "s|@GROFF_FONT_DIR@|$(fontdir)|" \ +- $(srcdir)/util/BuildFoundries.pl \ +- >$(top_builddir)/font/devpdf/util/BuildFoundries ;\ +- fi +- chmod +x util/BuildFoundries +- echo "# foundry ps name psfile" > $(top_builddir)/font/devpdf/download +- PATH="$(top_builddir)/src/utils/afmtodit:$(GROFF_PATH_SEPARATOR)$(PATH)" \ +- util/BuildFoundries $(top_builddir)/font/devpdf \ +- '$(top_srcdir)/font/devps : $(top_builddir)/font/devps' \ +- >> $(top_builddir)/font/devpdf/download +- +-install_data: +- -test -d $(DESTDIR)$(fontsubdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(fontsubdir) +- -test -d $(DESTDIR)$(fontsubdir)/enc \ +- || $(mkinstalldirs) $(DESTDIR)$(fontsubdir)/enc +- -test -d $(DESTDIR)$(fontsubdir)/map \ +- || $(mkinstalldirs) $(DESTDIR)$(fontsubdir)/map +- -test -d $(DESTDIR)$(fontsubdir)/util \ +- || $(mkinstalldirs) $(DESTDIR)$(fontsubdir)/util +- for f in $(MOSTLYCLEANADD); do \ +- $(RM) $(DESTDIR)$(fontsubdir)/$$f; \ +- if test -f $$f; then \ +- $(INSTALL_DATA) $$f $(DESTDIR)$(fontsubdir)/$$f; \ +- else \ +- $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(fontsubdir)/$$f; \ +- fi; \ +- done +- +-uninstall_sub: +- -for f in $(MOSTLYCLEANADD); do \ +- $(RM) $(DESTDIR)$(fontsubdir)/$$f; \ +- done +- -d=$(DESTDIR)$(fontsubdir)/enc; \ +- if test -d $$d; then rmdir $$d; fi +- -d=$(DESTDIR)$(fontsubdir)/map; \ +- if test -d $$d; then rmdir $$d; fi +- -d=$(DESTDIR)$(fontsubdir)/util; \ +- if test -d $$d; then rmdir $$d; fi +- -d=$(DESTDIR)$(fontsubdir); \ +- if test -d $$d; then rmdir $$d; fi +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devps/devps.am groff-1.22.3/font/devps/devps.am +--- groff-1.22.3.old/font/devps/devps.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devps/devps.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,170 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++devps_srcdir = $(top_srcdir)/font/devps ++devps_builddir = $(top_builddir)/font/devps ++DEVPSFONTFILES = \ ++ font/devps/S \ ++ font/devps/SS \ ++ font/devps/ZD \ ++ font/devps/ZDR \ ++ font/devps/ZCMI \ ++ font/devps/AB \ ++ font/devps/ABI \ ++ font/devps/AI \ ++ font/devps/AR \ ++ font/devps/BMB \ ++ font/devps/BMBI \ ++ font/devps/BMI \ ++ font/devps/BMR \ ++ font/devps/CB \ ++ font/devps/CBI \ ++ font/devps/CI \ ++ font/devps/CR \ ++ font/devps/HB \ ++ font/devps/HBI \ ++ font/devps/HI \ ++ font/devps/HR \ ++ font/devps/HNB \ ++ font/devps/HNBI \ ++ font/devps/HNI \ ++ font/devps/HNR \ ++ font/devps/NB \ ++ font/devps/NBI \ ++ font/devps/NI \ ++ font/devps/NR \ ++ font/devps/PB \ ++ font/devps/PBI \ ++ font/devps/PI \ ++ font/devps/PR \ ++ font/devps/TB \ ++ font/devps/TBI \ ++ font/devps/TI \ ++ font/devps/TR \ ++ font/devps/EURO \ ++ font/devps/freeeuro.pfa \ ++ font/devps/freeeuro.afm \ ++ font/devps/text.enc \ ++ font/devps/download ++ ++DEVPSFONTFILES_GENERATED = \ ++ font/devps/DESC \ ++ font/devps/prologue \ ++ font/devps/zapfdr.pfa \ ++ font/devps/symbolsl.pfa ++devpsfontdir = $(fontdir)/devps ++dist_devpsfont_DATA = $(DEVPSFONTFILES) ++nodist_devpsfont_DATA = $(DEVPSFONTFILES_GENERATED) ++ ++# these files will be installed in oldfontdir ++OLDDEVPSFONTFILES = \ ++ font/devps/old/S \ ++ font/devps/old/SS \ ++ font/devps/old/CB \ ++ font/devps/old/CBI \ ++ font/devps/old/CI \ ++ font/devps/old/CR \ ++ font/devps/old/HB \ ++ font/devps/old/HBI \ ++ font/devps/old/HI \ ++ font/devps/old/HR \ ++ font/devps/old/HNB \ ++ font/devps/old/HNBI \ ++ font/devps/old/HNI \ ++ font/devps/old/HNR \ ++ font/devps/old/NB \ ++ font/devps/old/NBI \ ++ font/devps/old/NI \ ++ font/devps/old/NR \ ++ font/devps/old/PB \ ++ font/devps/old/PBI \ ++ font/devps/old/PI \ ++ font/devps/old/PR \ ++ font/devps/old/TB \ ++ font/devps/old/TBI \ ++ font/devps/old/TI \ ++ font/devps/old/TR \ ++ font/devps/old/symbol.afm \ ++ font/devps/old/symbolsl.afm \ ++ font/devps/old/zapfdr.afm \ ++ font/devps/old/zapfdr.ps ++olddevpsfontdir = $(oldfontdir)/devps ++dist_olddevpsfont_DATA = $(OLDDEVPSFONTFILES) ++ ++# Files installed in $(devfontdir)/generate ++DEVPSGENFILES = \ ++ font/devps/generate/Makefile \ ++ font/devps/generate/dingbats.map \ ++ font/devps/generate/dingbats.rmap \ ++ font/devps/generate/lgreekmap \ ++ font/devps/generate/symbolchars \ ++ font/devps/generate/symbolsl.afm \ ++ font/devps/generate/textmap ++DEVPSGENSCRIPTS = \ ++ font/devps/generate/afmname \ ++ font/devps/generate/symbol.sed ++devpsgendir = $(devpsfontdir)/generate ++dist_devpsgen_DATA = $(DEVPSGENFILES) $(DEVPSGENSCRIPTS) ++ ++MOSTLYCLEANFILES += $(DEVPSFONTFILES_GENERATED) ++EXTRA_DIST += \ ++ font/devps/symbolmap \ ++ font/devps/DESC.in \ ++ font/devps/prologue.ps \ ++ font/devps/psstrip.sed \ ++ font/devps/symbol.afm \ ++ font/devps/symbolsl.ps \ ++ font/devps/zapfdr.afm \ ++ font/devps/zapfdr.ps \ ++ font/devps/generate/freeeuro.sfd \ ++ font/devps/generate/make-zapfdr \ ++ font/devps/generate/symbolsl.awk \ ++ font/devps/generate/sfdtopfa.pe \ ++ font/devps/generate/zapfdr.sed ++ ++font/devps/DESC: $(devps_srcdir)/DESC.in ++ @$(MKDIR_P) font/devps ++ @cat $(devps_srcdir)/DESC.in >$@ ++ @echo broken $(BROKEN_SPOOLER_FLAGS) >>$@ ++ @if test "$(PAGE)" = A4; then \ ++ echo "papersize a4" >>$@; \ ++ else \ ++ echo "papersize letter" >>$@; \ ++ fi ++ @test -z '$(PSPRINT)' || echo print '$(PSPRINT)' >>$@ ++ ++fonts: devps_fonts ++# We add top_builddir to the PATH in case the only afmtodit available is the ++# one in the current build. ++devps_fonts: afmtodit font/devps/DESC ++ PATH=$(top_builddir)$(GROFF_PATH_SEPARATOR)$(PATH) \ ++ $(MAKE) -f $(devps_srcdir)/generate/Makefile \ ++ srcdir=$(devps_srcdir)/generate DESC=$(devps_srcdir)/DESC.in ++ ++font/devps/prologue: $(devps_srcdir)/prologue.ps ++ @$(MKDIR_P) font/devps ++ $(RM) $@ ++ sed -f $(devps_srcdir)/psstrip.sed $? >$@ ++font/devps/zapfdr.pfa: $(devps_srcdir)/zapfdr.ps ++ @$(MKDIR_P) font/devps ++ $(RM) $@ ++ sed -f $(devps_srcdir)/psstrip.sed $? >$@ ++font/devps/symbolsl.pfa: $(devps_srcdir)/symbolsl.ps ++ @$(MKDIR_P) font/devps ++ $(RM) $@ ++ sed -f $(devps_srcdir)/psstrip.sed $? >$@ +diff -Nuar groff-1.22.3.old/font/devps/.gitignore groff-1.22.3/font/devps/.gitignore +--- groff-1.22.3.old/font/devps/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devps/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,4 @@ ++DESC ++prologue ++symbolsl.pfa ++zapfdr.pfa +diff -Nuar groff-1.22.3.old/font/devps/Makefile.sub groff-1.22.3/font/devps/Makefile.sub +--- groff-1.22.3.old/font/devps/Makefile.sub 2014-11-04 10:38:35.340522559 +0200 ++++ groff-1.22.3/font/devps/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,92 +0,0 @@ +-# Makefile.sub for `font devps' +- +-# File position: /font/devps/Makefile.sub +- +-# Copyright (C) 2014 Free Software Foundation, Inc. +- +-# This file is part of `groffer' which is part of `groff'. +- +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +- +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +- +-######################################################################## +- +-DEV=ps +-DISTFILES=\ +- S SS \ +- ZD ZDR ZCMI \ +- AB ABI AI AR \ +- BMB BMBI BMI BMR \ +- CB CBI CI CR \ +- HB HBI HI HR \ +- HNB HNBI HNI HNR \ +- NB NBI NI NR \ +- PB PBI PI PR \ +- TB TBI TI TR \ +- EURO freeeuro.pfa freeeuro.afm \ +- text.enc download +-# these files must be in a subdirectory called `old' +-OLDDISTFILES=\ +- S SS \ +- CB CBI CI CR \ +- HB HBI HI HR \ +- HNB HNBI HNI HNR \ +- NB NBI NI NR \ +- PB PBI PI PR \ +- TB TBI TI TR \ +- symbol.afm symbolsl.afm \ +- zapfdr.afm zapfdr.ps +- +-PSFILES=prologue symbolsl.pfa zapfdr.pfa +-DEVGENFILES=generate/Makefile generate/dingbats.map \ +- generate/dingbats.rmap generate/lgreekmap \ +- generate/symbolchars generate/symbolsl.afm generate/textmap +-DEVGENSCRIPTS=generate/afmname generate/symbol.sed +-DEVFILES=DESC $(PSFILES) $(DISTFILES) $(DEVGENFILES) +-OLDDEVFILES=$(OLDDISTFILES) +-DEVSCRIPTS=$(DEVGENSCRIPTS) +- +-MOSTLYCLEANADD=DESC $(PSFILES) +- +-RM=rm -f +- +-DESC: DESC.in +- cat $(srcdir)/DESC.in >DESC +- echo broken $(BROKEN_SPOOLER_FLAGS) >>DESC +- if test "$(PAGE)" = A4; then \ +- echo "papersize a4" >>DESC; \ +- else \ +- echo "papersize letter" >>DESC; \ +- fi +- test -z '$(PSPRINT)' || echo print '$(PSPRINT)' >>DESC +- +-fonts: DESC +- $(MAKE) -f $(srcdir)/generate/Makefile \ +- srcdir=$(srcdir)/generate DESC=$(srcdir)/DESC.in +- +-prologue: prologue.ps +-zapfdr.pfa: zapfdr.ps +-symbolsl.pfa: symbolsl.ps +- +-$(PSFILES): +- $(RM) $@ +- sed -f $(srcdir)/psstrip.sed $? >$@ +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devutf8/devutf8.am groff-1.22.3/font/devutf8/devutf8.am +--- groff-1.22.3.old/font/devutf8/devutf8.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devutf8/devutf8.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,48 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++devutf8_srcdir = $(top_srcdir)/font/devutf8 ++DEVUTF8FONTS = R I B BI ++DEVUTF8FONTSFILES = \ ++ font/devutf8/R font/devutf8/I font/devutf8/B font/devutf8/BI ++ ++DEVUTF8RES = 240 ++DEVUTF8CPI = 10 ++DEVUTF8LPI = 6 ++ ++devutf8fontdir = $(fontdir)/devutf8 ++devutf8font_DATA = $(DEVUTF8FONTSFILES) font/devutf8/DESC ++MOSTLYCLEANFILES += $(DEVUTF8FONTSFILES) font/devutf8/DESC ++EXTRA_DIST += \ ++ font/devutf8/R.proto \ ++ font/devutf8/DESC.proto \ ++ font/devutf8/NOTES \ ++ font/devutf8/R.in ++ ++$(DEVUTF8FONTSFILES): $(devutf8_srcdir)/R.proto ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @$(RM) $@ ++ @$(SHELL) $(GENFONTSSH) $(devutf8_srcdir)/R.proto \ ++ $(DEVUTF8RES) $(DEVUTF8CPI) `basename $@` > $@ ++ ++font/devutf8/DESC: $(devutf8_srcdir)/DESC.proto ++ @echo Making $@ ++ @$(MKDIR_P) `dirname $@` ++ @$(SHELL) $(GENDESCSH) $(devutf8_srcdir)/DESC.proto \ ++ $(DEVUTF8RES) $(DEVUTF8CPI) $(DEVUTF8LPI) $(DEVUTF8FONTS) > $@ +diff -Nuar groff-1.22.3.old/font/devutf8/.gitignore groff-1.22.3/font/devutf8/.gitignore +--- groff-1.22.3.old/font/devutf8/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devutf8/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,5 @@ ++B ++BI ++DESC ++I ++R +diff -Nuar groff-1.22.3.old/font/devutf8/Makefile.sub groff-1.22.3/font/devutf8/Makefile.sub +--- groff-1.22.3.old/font/devutf8/Makefile.sub 2014-11-04 10:38:35.410521684 +0200 ++++ groff-1.22.3/font/devutf8/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,65 +0,0 @@ +-# Makefile.sub for `font devutf8' +-# +-# File position: /font/devutf8/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=utf8 +-FONTS=R I B BI +-DEVFILES=$(FONTS) DESC +-MOSTLYCLEANADD=$(FONTS) DESC +- +-RES=240 +-CPI=10 +-LPI=6 +- +-RM=rm -f +- +-$(FONTS): R.proto +- @echo Making $@ +- @$(RM) $@ +- @charwidth=`expr $(RES) / $(CPI)` ; \ +- sed -e "s/^name [A-Z]*$$/name $@/" \ +- -e \ +- "s/^\\([^ ]*\\) [0-9][0-9]* /\\1 $$charwidth /" \ +- -e "s/^spacewidth [0-9][0-9]*$$/spacewidth $$charwidth/" \ +- -e "s/^internalname .*$$/internalname $@/" \ +- -e "/^internalname/s/BI/3/" \ +- -e "/^internalname/s/B/2/" \ +- -e "/^internalname/s/I/1/" \ +- -e "/^internalname .*[^ 0-9]/d" \ +- $(srcdir)/R.proto >$@ +- +-DESC: DESC.proto +- @echo Making $@ +- @sed -e "s/^res .*$$/res $(RES)/" \ +- -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \ +- -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \ +- -e "s/^fonts .*$$/fonts `set $(FONTS); echo $$#` $(FONTS)/" \ +- $(srcdir)/DESC.proto >$@ +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devX100/devX100.am groff-1.22.3/font/devX100/devX100.am +--- groff-1.22.3.old/font/devX100/devX100.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devX100/devX100.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,44 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff'. ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++DEVX100FONTS = \ ++ font/devX100/DESC \ ++ font/devX100/TR \ ++ font/devX100/TI \ ++ font/devX100/TB \ ++ font/devX100/TBI \ ++ font/devX100/CR \ ++ font/devX100/CI \ ++ font/devX100/CB \ ++ font/devX100/CBI \ ++ font/devX100/HR \ ++ font/devX100/HI \ ++ font/devX100/HB \ ++ font/devX100/HBI \ ++ font/devX100/NR \ ++ font/devX100/NI \ ++ font/devX100/NB \ ++ font/devX100/NBI \ ++ font/devX100/S ++ ++if !WITHOUT_X11 ++devX100fontdir = $(fontdir)/devX100 ++devX100font_DATA = $(DEVX100FONTS) ++endif ++ ++EXTRA_DIST += $(DEVX100FONTS) +diff -Nuar groff-1.22.3.old/font/devX100/Makefile.sub groff-1.22.3/font/devX100/Makefile.sub +--- groff-1.22.3.old/font/devX100/Makefile.sub 2014-11-04 10:38:35.373522147 +0200 ++++ groff-1.22.3/font/devX100/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,37 +0,0 @@ +-# Makefile.sub for `font devX100' +-# +-# File position: /font/devX100/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=X100 +-DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devX100-12/devX100-12.am groff-1.22.3/font/devX100-12/devX100-12.am +--- groff-1.22.3.old/font/devX100-12/devX100-12.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devX100-12/devX100-12.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,44 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff'. ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++DEVX10012FONTS = \ ++ font/devX100-12/DESC \ ++ font/devX100-12/TR \ ++ font/devX100-12/TI \ ++ font/devX100-12/TB \ ++ font/devX100-12/TBI \ ++ font/devX100-12/CR \ ++ font/devX100-12/CI \ ++ font/devX100-12/CB \ ++ font/devX100-12/CBI \ ++ font/devX100-12/HR \ ++ font/devX100-12/HI \ ++ font/devX100-12/HB \ ++ font/devX100-12/HBI \ ++ font/devX100-12/NR \ ++ font/devX100-12/NI \ ++ font/devX100-12/NB \ ++ font/devX100-12/NBI \ ++ font/devX100-12/S ++ ++if !WITHOUT_X11 ++devX10012fontdir = $(fontdir)/devX100-12 ++devX10012font_DATA = $(DEVX10012FONTS) ++endif ++ ++EXTRA_DIST += $(DEVX10012FONTS) +diff -Nuar groff-1.22.3.old/font/devX100-12/Makefile.sub groff-1.22.3/font/devX100-12/Makefile.sub +--- groff-1.22.3.old/font/devX100-12/Makefile.sub 2014-11-04 10:38:35.379522072 +0200 ++++ groff-1.22.3/font/devX100-12/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,37 +0,0 @@ +-# Makefile.sub for `font devX100-12' +-# +-# File position: /font/devX100-12/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=X100-12 +-DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devX75/devX75.am groff-1.22.3/font/devX75/devX75.am +--- groff-1.22.3.old/font/devX75/devX75.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devX75/devX75.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,44 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++DEVX75FONTS = \ ++ font/devX75/DESC \ ++ font/devX75/TR \ ++ font/devX75/TI \ ++ font/devX75/TB \ ++ font/devX75/TBI \ ++ font/devX75/CR \ ++ font/devX75/CI \ ++ font/devX75/CB \ ++ font/devX75/CBI \ ++ font/devX75/HR \ ++ font/devX75/HI \ ++ font/devX75/HB \ ++ font/devX75/HBI \ ++ font/devX75/NR \ ++ font/devX75/NI \ ++ font/devX75/NB \ ++ font/devX75/NBI \ ++ font/devX75/S ++ ++if !WITHOUT_X11 ++devX75fontdir = $(fontdir)/devX75 ++devX75font_DATA = $(DEVX75FONTS) ++endif ++ ++EXTRA_DIST += $(DEVX75FONTS) +diff -Nuar groff-1.22.3.old/font/devX75/Makefile.sub groff-1.22.3/font/devX75/Makefile.sub +--- groff-1.22.3.old/font/devX75/Makefile.sub 2014-11-04 10:38:35.361522297 +0200 ++++ groff-1.22.3/font/devX75/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,37 +0,0 @@ +-# Makefile.sub for `font devX75' +-# +-# File position: /font/devX75/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=X75 +-DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/devX75-12/devX75-12.am groff-1.22.3/font/devX75-12/devX75-12.am +--- groff-1.22.3.old/font/devX75-12/devX75-12.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/devX75-12/devX75-12.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,42 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++DEVX7512FONTS = \ ++ font/devX75-12/DESC \ ++ font/devX75-12/TR \ ++ font/devX75-12/TI \ ++ font/devX75-12/TB \ ++ font/devX75-12/TBI \ ++ font/devX75-12/CR \ ++ font/devX75-12/CI \ ++ font/devX75-12/CB \ ++ font/devX75-12/CBI \ ++ font/devX75-12/HR \ ++ font/devX75-12/HI \ ++ font/devX75-12/HB \ ++ font/devX75-12/HBI \ ++ font/devX75-12/NR \ ++ font/devX75-12/NI \ ++ font/devX75-12/NB \ ++ font/devX75-12/NBI \ ++ font/devX75-12/S ++if !WITHOUT_X11 ++devX7512fontdir = $(fontdir)/devX75-12 ++devX7512font_DATA = $(DEVX7512FONTS) ++endif ++EXTRA_DIST += $(DEVX7512FONTS) +diff -Nuar groff-1.22.3.old/font/devX75-12/Makefile.sub groff-1.22.3/font/devX75-12/Makefile.sub +--- groff-1.22.3.old/font/devX75-12/Makefile.sub 2014-11-04 10:38:35.367522222 +0200 ++++ groff-1.22.3/font/devX75-12/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,37 +0,0 @@ +-# Makefile.sub for `font devX75-12' +-# +-# File position: /font/devX75-12/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-DEV=X75-12 +-DEVFILES=DESC TR TI TB TBI CR CI CB CBI HR HI HB HBI NR NI NB NBI S +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/font/scripts/gendesc.sh groff-1.22.3/font/scripts/gendesc.sh +--- groff-1.22.3.old/font/scripts/gendesc.sh 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/scripts/gendesc.sh 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,18 @@ ++#!/bin/sh ++# Usage: gendesc.sh ++if test -z "$1" || test -z "$2" || test -z "$3" || test -z "$4" || \ ++ test -z "$5"; then ++ echo "genfonts.sh: missing parameter"; exit 255; ++fi ++INPUT=$1 ++RES=$2 ++CPI=$3 ++LPI=$4 ++shift 4 ++NBFONTS=`echo $#` ++FONTS=`echo $*` ++sed -e "s/^res .*$/res $RES/" \ ++ -e "s/^hor .*$/hor `expr $RES / $CPI`/" \ ++ -e "s/^vert .*$/vert `expr $RES / $LPI`/" \ ++ -e "s/^fonts .*$/fonts $NBFONTS $FONTS/" \ ++ $INPUT +diff -Nuar groff-1.22.3.old/font/scripts/genfonts.sh groff-1.22.3/font/scripts/genfonts.sh +--- groff-1.22.3.old/font/scripts/genfonts.sh 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/scripts/genfonts.sh 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,23 @@ ++#!/bin/sh -xv ++# Usage: ++# genfonts.sh ++if test -z "$1" || test -z "$2" || test -z "$3" || test -z "$4"; then ++ echo "genfonts.sh: missing parameter"; exit 255; ++fi ++ ++INPUT=$1 ++RES=$2 ++CPI=$3 ++FONT=$4 ++charwidth=`expr $RES / $CPI` ; ++sed -e "s|^name [A-Z]*$|name $FONT|" \ ++ -e \ ++ "s/^\\([^ ]*\\) [0-9][0-9]* /\\1 $charwidth /" \ ++ -e "s/^spacewidth [0-9][0-9]*$/spacewidth $charwidth/" \ ++ -e "s|^internalname .*$|internalname $FONT|" \ ++ -e "/^internalname/s/CR/4/" \ ++ -e "/^internalname/s/BI/3/" \ ++ -e "/^internalname/s/B/2/" \ ++ -e "/^internalname/s/I/1/" \ ++ -e "/^internalname .*[^ 0-9]/d" \ ++ $INPUT +diff -Nuar groff-1.22.3.old/font/scripts/scripts.am groff-1.22.3/font/scripts/scripts.am +--- groff-1.22.3.old/font/scripts/scripts.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/font/scripts/scripts.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,4 @@ ++# Scripts for font files generation ++GENFONTSSH=$(top_srcdir)/font/scripts/genfonts.sh ++GENDESCSH = $(top_srcdir)/font/scripts/gendesc.sh ++EXTRA_DIST += $(GENFONTSSH) $(GENDESCSH) +diff -Nuar groff-1.22.3.old/.gitignore groff-1.22.3/.gitignore +--- groff-1.22.3.old/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,95 @@ ++*.[oan] ++*.hpp ++*.output ++*.pdf ++*-s ++.dirstamp ++.deps ++/Makefile ++/Makefile.in ++stamp-* ++/aclocal.m4 ++/autom4te.cache ++/build-aux ++/configure ++/config.log ++/src/include/stamp-h1 ++/font/devpdf/[A-Z]* ++/gnulib_m4 ++/INSTALL ++/lib ++/maint.mk ++/src/include/config.hin ++/GNUmakefile ++/README-release ++/addftinfo ++/afmtodit ++/charset.alias ++/chem ++/contrib/hdtbl/hdmisc.tmac ++/contrib/hdtbl/hdtbl.tmac ++/contrib/mom/om.tmac ++/defs.h ++/eqn ++/eqn2graph ++/font/devpdf/build_font_files ++/font/devpdf/download ++/font/devpdf/enc/ ++/font/devpdf/map/ ++/font/devpdf/util/BuildFoundries ++/gdiffmk ++/gideal ++/glilypond ++/gnu.eps ++/gperl ++/gpinyin ++/grap2graph ++/grn ++/grodvi ++/groff ++/groff_opts.tmp ++/groff_opts_no_arg.txt ++/groff_opts_with_arg.txt ++/groffer ++/grog ++/grolbp ++/grolj4 ++/gropdf ++/grops ++/grotty ++/gxditview ++/hpftodit ++/indxbib ++/lkbib ++/lookbib ++/mmroff ++/neqn ++/nroff ++/pdfmom ++/pdfroff ++/pdfroff-*/ ++/penguin.ps ++/pfbtops ++/pic ++/pic2graph ++/post-grohtml ++/pre-grohtml ++/preconv ++/ref-add.sed ++/ref-del.sed ++/refer ++/roff2dvi ++/roff2html ++/roff2pdf ++/roff2ps ++/roff2text ++/roff2x ++/shdeps.sed ++/soelim ++/tbl ++/test-groff ++/test-suite.log ++/tfmtodit ++/troff ++/xtotroff ++/gendef.sh +diff -Nuar groff-1.22.3.old/.gitmodules groff-1.22.3/.gitmodules +--- groff-1.22.3.old/.gitmodules 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/.gitmodules 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++[submodule "gnulib"] ++ path = gnulib ++ url = git://git.sv.gnu.org/gnulib.git +diff -Nuar groff-1.22.3.old/INSTALL groff-1.22.3/INSTALL +--- groff-1.22.3.old/INSTALL 2014-11-04 10:38:35.144525010 +0200 ++++ groff-1.22.3/INSTALL 1970-01-01 02:00:00.000000000 +0200 +@@ -1,140 +0,0 @@ +- Copyright 1997-2014 Free Software Foundation, Inc. +- +- Copying and distribution of this file, with or without modification, +- are permitted in any medium without royalty provided the copyright +- notice and this notice are preserved. +- +-This file contains information that supplements the generic +-installation instructions in file `INSTALL.gen'. +- +- +-Normal Installation +-=================== +- +-The simplest way to compile groff is: +- +- 1. `cd' to the directory containing groff's source code and type +- `./configure' to configure groff for your system. If you are +- using `csh' on an old version of System V, you might need to type +- `sh ./configure' instead to prevent `csh' from trying to execute +- `configure' itself. +- +- Running `configure' takes awhile. While running, it prints some +- messages telling which features it is checking for. +- +- 2. Type `make' to compile groff. +- +- 3. Type `sudo make install' to install the groff programs and any +- data files and documentation. `make install' is the only step for +- which you need `root' access; this is done by `sudo'. +- +- 4. You can remove the groff binaries and object files from the +- source code directory by typing `make clean'. To also remove the +- files that `configure' created (so you can compile groff for +- a different kind of computer), type `make distclean'. +- +- +-External Installation +-===================== +- +-It is also possible to perform the whole installation process outside +-of the source code directory. In this case a whole external build +-directory structure is created without changing any parts of the source +-code tree. This is useful if the source code is read-only or if +-several different installations, such as for multiple architectures, +-should be constructed. +- +-As an example we assume that the source code of the `groff' code is in +-`/usr/local/src/groff', and that the build process should be done +-within the directory `/home/my/groff.compile'. +- +- 0. Create `/home/my/groff.compile' and change to that directory. +- +- 1. Call `/usr/local/src/groff/configure' in that directory to +- configure groff for your system. If you are using `csh' on an old +- version of System V, you might need to type `sh +- /usr/local/src/groff/configure' instead. +- +- 2. Type `make' to compile groff in that directory. +- +- 3. Type `sudo make install' to install the groff programs and any +- data files and documentation. +- +- 4. You can remove the groff binaries and object files from the +- build directory by typing `make clean'. To also remove the +- files that `configure' created (so you can compile the package for +- a different kind of computer), type `make distclean'. +- +- +-Special Platforms +-================= +- +-For instructions how to build groff with DJGPP tools for MS-DOS and +-MS-Windows, see the file arch/djgpp/README. +- +-For instructions how to build groff with the MinGW tools for +-MS-Windows, see the file README.MinGW. +- +- +-Miscellaneous +-============= +- +-groff is written in C++, so you need a C++ compiler. The C++ source +-files use a suffix of `.cpp', so your C++ compiler must be able to +-handle this. If you don't already have a C++ compiler, we suggest gcc +-2.7.1 or later (gcc version 2 includes GNU C++ as well as GNU C). From +-gcc 2.5, it is no longer necessary to install libg++: the C++ header +-files needed by groff are created by the gcc installation process. To +-override configure's choice of C++ compiler, you can set the CXX +-environment variable. +- +-If you have a library that provides a faster malloc than your system's +-usual malloc, it is good idea to include it in LIBS. For example, +-using the malloc that comes with GNU Emacs version 20 can give a +-worthwhile (and sometimes spectacular) performance improvement. +- +-Many programs within the `groff' system are written in the Perl +-language. So you need a `perl' program with the least version of +-`v5.6.1'. +- +- +-If you want A4 or letter paper format and the configure script produces +-an incorrect guess, say +- +- PAGE=xxx ./configure +- +-where `xxx' should be either `A4' or `letter'. Note that this only +-affects the paper selection of some device drivers like grops (which +-can be still overridden on the command line). For compatibility with +-ditroff, the default page length in gtroff is always 11 inches. The +-page length can be changed with the `pl' request. +- +-When you have built groff but not installed yet, you can use the +-test-groff script to try groff out on one of the man pages. (Use the +-.n files not the .man files.) The test-groff script sets up environment +-variables to allow groff to run without being installed. For example, +-you could do +- +- ./test-groff -man -Tascii src/roff/groff/groff.n | less +- +-to display the groff(1) man page with the `less' pager. +- +-To get a DVI, PDF, or HTML version of the groff texinfo manual, say +-`make groff.dvi', `make groff.pdf', or `make groff.html', respectively, +-in the `doc' subdirectory (after configuring the groff package). Note +-that you need texinfo version 4.8 as a prerequisite. +- +-If you have problems, read the PROBLEMS file. If this doesn't help +-and you need support, please contact the `groff' mailing list. If you +-think that you have found a bug, please submit a report in our bug +-tracker at +- +- https://savannah.gnu.org/projects/groff +- +-Alternative, but less preferable, you may send a bug report using the +-form in the file BUG-REPORT. +- +-##### Emacs settings +-Local Variables: +-mode: text +-End: +diff -Nuar groff-1.22.3.old/INSTALL.extra groff-1.22.3/INSTALL.extra +--- groff-1.22.3.old/INSTALL.extra 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/INSTALL.extra 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,140 @@ ++ Copyright 1997-2014 Free Software Foundation, Inc. ++ ++ Copying and distribution of this file, with or without modification, ++ are permitted in any medium without royalty provided the copyright ++ notice and this notice are preserved. ++ ++This file contains information that supplements the generic ++installation instructions in file `INSTALL'. ++ ++ ++Normal Installation ++=================== ++ ++The simplest way to compile groff is: ++ ++ 1. `cd' to the directory containing groff's source code and type ++ `./configure' to configure groff for your system. If you are ++ using `csh' on an old version of System V, you might need to type ++ `sh ./configure' instead to prevent `csh' from trying to execute ++ `configure' itself. ++ ++ Running `configure' takes awhile. While running, it prints some ++ messages telling which features it is checking for. ++ ++ 2. Type `make' to compile groff. ++ ++ 3. Type `sudo make install' to install the groff programs and any ++ data files and documentation. `make install' is the only step for ++ which you need `root' access; this is done by `sudo'. ++ ++ 4. You can remove the groff binaries and object files from the ++ source code directory by typing `make clean'. To also remove the ++ files that `configure' created (so you can compile groff for ++ a different kind of computer), type `make distclean'. ++ ++ ++External Installation ++===================== ++ ++It is also possible to perform the whole installation process outside ++of the source code directory. In this case a whole external build ++directory structure is created without changing any parts of the source ++code tree. This is useful if the source code is read-only or if ++several different installations, such as for multiple architectures, ++should be constructed. ++ ++As an example we assume that the source code of the `groff' code is in ++`/usr/local/src/groff', and that the build process should be done ++within the directory `/home/my/groff.compile'. ++ ++ 0. Create `/home/my/groff.compile' and change to that directory. ++ ++ 1. Call `/usr/local/src/groff/configure' in that directory to ++ configure groff for your system. If you are using `csh' on an old ++ version of System V, you might need to type `sh ++ /usr/local/src/groff/configure' instead. ++ ++ 2. Type `make' to compile groff in that directory. ++ ++ 3. Type `sudo make install' to install the groff programs and any ++ data files and documentation. ++ ++ 4. You can remove the groff binaries and object files from the ++ build directory by typing `make clean'. To also remove the ++ files that `configure' created (so you can compile the package for ++ a different kind of computer), type `make distclean'. ++ ++ ++Special Platforms ++================= ++ ++For instructions how to build groff with DJGPP tools for MS-DOS and ++MS-Windows, see the file arch/djgpp/README. ++ ++For instructions how to build groff with the MinGW tools for ++MS-Windows, see the file README.MinGW. ++ ++ ++Miscellaneous ++============= ++ ++groff is written in C++, so you need a C++ compiler. The C++ source ++files use a suffix of `.cpp', so your C++ compiler must be able to ++handle this. If you don't already have a C++ compiler, we suggest gcc ++2.7.1 or later (gcc version 2 includes GNU C++ as well as GNU C). From ++gcc 2.5, it is no longer necessary to install libg++: the C++ header ++files needed by groff are created by the gcc installation process. To ++override configure's choice of C++ compiler, you can set the CXX ++environment variable. ++ ++If you have a library that provides a faster malloc than your system's ++usual malloc, it is good idea to include it in LIBS. For example, ++using the malloc that comes with GNU Emacs version 20 can give a ++worthwhile (and sometimes spectacular) performance improvement. ++ ++Many programs within the `groff' system are written in the Perl ++language. So you need a `perl' program with the least version of ++`v5.6.1'. ++ ++ ++If you want A4 or letter paper format and the configure script produces ++an incorrect guess, say ++ ++ PAGE=xxx ./configure ++ ++where `xxx' should be either `A4' or `letter'. Note that this only ++affects the paper selection of some device drivers like grops (which ++can be still overridden on the command line). For compatibility with ++ditroff, the default page length in gtroff is always 11 inches. The ++page length can be changed with the `pl' request. ++ ++When you have built groff but not installed yet, you can use the ++test-groff script to try groff out on one of the man pages. (Use the ++.n files not the .man files.) The test-groff script sets up environment ++variables to allow groff to run without being installed. For example, ++you could do ++ ++ ./test-groff -man -Tascii src/roff/groff/groff.n | less ++ ++to display the groff(1) man page with the `less' pager. ++ ++To get a DVI, PDF, or HTML version of the groff texinfo manual, say ++`make groff.dvi', `make groff.pdf', or `make groff.html', respectively, ++in the `doc' subdirectory (after configuring the groff package). Note ++that you need texinfo version 4.8 as a prerequisite. ++ ++If you have problems, read the PROBLEMS file. If this doesn't help ++and you need support, please contact the `groff' mailing list. If you ++think that you have found a bug, please submit a report in our bug ++tracker at ++ ++ https://savannah.gnu.org/projects/groff ++ ++Alternative, but less preferable, you may send a bug report using the ++form in the file BUG-REPORT. ++ ++##### Emacs settings ++Local Variables: ++mode: text ++End: +diff -Nuar groff-1.22.3.old/INSTALL.REPO groff-1.22.3/INSTALL.REPO +--- groff-1.22.3.old/INSTALL.REPO 2014-11-04 10:38:35.144525010 +0200 ++++ groff-1.22.3/INSTALL.REPO 2015-04-23 20:57:03.000000000 +0300 +@@ -5,31 +5,71 @@ + the copyright notice and this notice are preserved. + + This file contains information that supplements the generic +-installation instructions in file `INSTALL.gen'. It is meant for ++installation instructions in file `INSTALL'. It is meant for + people building directly from the development repository, rather than + a release or snapshot tarball. + + If you want to start compiling the `groff' system with an existing +-script `configure' you won't need the information in this file. ++script `configure' you won't need the information in this file. You ++need them only if you want to build groff from the git repository. + +-But if you want to use the `GNU autotools' (`aclocal', `autoreconf') +-for creating the following and some more files: ++1. Initial build ++---------------- + +- aclocal.m4 +- configure +- Makefile ++You will need autoconf version and 2.65 or higher and automake version ++1.12.2 or higher. These minimal versions are set in the bootstrap.conf ++file. ++ ++On operating systems supporting concurrent installation of multiple ++versions of the autotools, set the following environment variables: ++ ++ export AUTOMAKE_VERSION=1.12 ++ export AUTOCONF_VERSION=2.65 ++ ++First invoke the bootstrap script: ++ ++ $ ./bootstrap ++ ++This will: ++ ++ - clone the gnulib repository as a git submodule in 'gnulib', add ++ the needed gnulib sources files in 'lib', add the needed gnulib m4 ++ macros in 'gnulib_m4' ++ ++ - Invoke autoreconf that will call all the `GNU autotools' ++ (`aclocal', `autoconf', `automake') in the right order for ++ creating the following files: ++ ++ -- INSTALL (a symlink to gnulib's INSTALL file) ++ -- Makefile.in ++ -- aclocal.m4 ++ -- autom4te.cache/ ++ -- build-aux/ (that contains all the helper scripts) ++ -- configure ++ -- src/include/config.hin ++ ++Note that aclocal.m4 is generated and the groff m4 macros are included ++via the acinclude.m4 file. ++ ++At this point you can invoke the `configure' script (that generates ++the `config.status' script; it is the `config.status' script generates ++the Makefile) and call 'make' to build the groff project. You can do ++it in the source tree: ++ ++ $ ./configure ++ $ make ++ ++You can also build groff in an out of source build tree, which is cleaner: ++ ++ $ mkdir build ++ $ cd build ++ $ ../configure ++ $ make + +-To update file `aclocal.m4', run the shell command ++Note that parallel build is also supported and make can be invoked ++with the -j option, which will greatly speed up the build. + +- $ aclocal -I m4 +- +-To recreate the files `configure' and `Makefile', use the shell +-command +- +- $ autoreconf -I m4 +- +-The option `-I m4' is necessary. It refers to the subdirectory `m4' +-that has files with m4 macro definitions needed by the `autotools'. ++Notes: + + If you use an old `autoreconf' version < 2.69, there might be an error + warning like: +@@ -44,23 +84,28 @@ + Just ignore this. It doesn't occur in the actual versions of + `autoreconf'. + +-You may even use the shell command + +- $ autoconf -I m4 + +-instead of `autoreconf', but that will ignore some features. So +-`autoreconf' is better. ++2. Modification of autotools files ++---------------------------------- ++ ++Previously, when groff used `autoconf' only and not `automake', you ++had to invoke manually the autotools, depending on what you ++modified. For example, to change the file `aclocal.m4', you had to run ++the shell command 'aclocal -I m4', to recreate the files `configure' ++and `Makefile', you had to use the command 'autoreconf -I m4'. ++ ++Now, as groff uses `automake', you don't need to run `autoreconf'. If ++you make some changes in Makefile.am or configure.ac, all the files ++that need to be updated will be regenerated when you execute `make'. ++ ++ ++ ++3. Quick start on the usage of `automake' in groff ++-------------------------------------------------- ++ ++A little document explaining the basics of automake and its usage in ++groff is available in doc/automake.mom. It is currently not ++automatically generated, to build it: + +-`automake' is not used currently, however, we plan to convert the +-build system accordingly. If you have experience in creating +-`Makefile.am' files we would be glad if you could help us in the +-conversion process. Please contact the groff mailing list. +- +-After the use of the `GNU autotools', the usual compilation should +-work. If the run of `configure' produces error reports you have +-produced errors in the `autotools' modification. +- +-##### Emacs settings +-Local Variables: +-mode: text +-End: ++pdfmom automake.mom > automake.pdf +diff -Nuar groff-1.22.3.old/install-sh groff-1.22.3/install-sh +--- groff-1.22.3.old/install-sh 2014-11-04 10:38:35.144525010 +0200 ++++ groff-1.22.3/install-sh 1970-01-01 02:00:00.000000000 +0200 +@@ -1,501 +0,0 @@ +-#!/bin/sh +-# install - install a program, script, or datafile +- +-scriptversion=2013-12-25.23; # UTC +- +-# This originates from X11R5 (mit/util/scripts/install.sh), which was +-# later released in X11R6 (xc/config/util/install.sh) with the +-# following copyright and license. +-# +-# Copyright (C) 1994 X Consortium +-# +-# Permission is hereby granted, free of charge, to any person obtaining a copy +-# of this software and associated documentation files (the "Software"), to +-# deal in the Software without restriction, including without limitation the +-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +-# sell copies of the Software, and to permit persons to whom the Software is +-# furnished to do so, subject to the following conditions: +-# +-# The above copyright notice and this permission notice shall be included in +-# all copies or substantial portions of the Software. +-# +-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-# +-# Except as contained in this notice, the name of the X Consortium shall not +-# be used in advertising or otherwise to promote the sale, use or other deal- +-# ings in this Software without prior written authorization from the X Consor- +-# tium. +-# +-# +-# FSF changes to this file are in the public domain. +-# +-# Calling this script install-sh is preferred over install.sh, to prevent +-# 'make' implicit rules from creating a file called install from it +-# when there is no Makefile. +-# +-# This script is compatible with the BSD install script, but was written +-# from scratch. +- +-tab=' ' +-nl=' +-' +-IFS=" $tab$nl" +- +-# Set DOITPROG to "echo" to test this script. +- +-doit=${DOITPROG-} +-doit_exec=${doit:-exec} +- +-# Put in absolute file names if you don't have them in your path; +-# or use environment vars. +- +-chgrpprog=${CHGRPPROG-chgrp} +-chmodprog=${CHMODPROG-chmod} +-chownprog=${CHOWNPROG-chown} +-cmpprog=${CMPPROG-cmp} +-cpprog=${CPPROG-cp} +-mkdirprog=${MKDIRPROG-mkdir} +-mvprog=${MVPROG-mv} +-rmprog=${RMPROG-rm} +-stripprog=${STRIPPROG-strip} +- +-posix_mkdir= +- +-# Desired mode of installed file. +-mode=0755 +- +-chgrpcmd= +-chmodcmd=$chmodprog +-chowncmd= +-mvcmd=$mvprog +-rmcmd="$rmprog -f" +-stripcmd= +- +-src= +-dst= +-dir_arg= +-dst_arg= +- +-copy_on_change=false +-is_target_a_directory=possibly +- +-usage="\ +-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE +- or: $0 [OPTION]... SRCFILES... DIRECTORY +- or: $0 [OPTION]... -t DIRECTORY SRCFILES... +- or: $0 [OPTION]... -d DIRECTORIES... +- +-In the 1st form, copy SRCFILE to DSTFILE. +-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +-In the 4th, create DIRECTORIES. +- +-Options: +- --help display this help and exit. +- --version display version info and exit. +- +- -c (ignored) +- -C install only if different (preserve the last data modification time) +- -d create directories instead of installing files. +- -g GROUP $chgrpprog installed files to GROUP. +- -m MODE $chmodprog installed files to MODE. +- -o USER $chownprog installed files to USER. +- -s $stripprog installed files. +- -t DIRECTORY install into DIRECTORY. +- -T report an error if DSTFILE is a directory. +- +-Environment variables override the default commands: +- CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG +- RMPROG STRIPPROG +-" +- +-while test $# -ne 0; do +- case $1 in +- -c) ;; +- +- -C) copy_on_change=true;; +- +- -d) dir_arg=true;; +- +- -g) chgrpcmd="$chgrpprog $2" +- shift;; +- +- --help) echo "$usage"; exit $?;; +- +- -m) mode=$2 +- case $mode in +- *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) +- echo "$0: invalid mode: $mode" >&2 +- exit 1;; +- esac +- shift;; +- +- -o) chowncmd="$chownprog $2" +- shift;; +- +- -s) stripcmd=$stripprog;; +- +- -t) +- is_target_a_directory=always +- dst_arg=$2 +- # Protect names problematic for 'test' and other utilities. +- case $dst_arg in +- -* | [=\(\)!]) dst_arg=./$dst_arg;; +- esac +- shift;; +- +- -T) is_target_a_directory=never;; +- +- --version) echo "$0 $scriptversion"; exit $?;; +- +- --) shift +- break;; +- +- -*) echo "$0: invalid option: $1" >&2 +- exit 1;; +- +- *) break;; +- esac +- shift +-done +- +-# We allow the use of options -d and -T together, by making -d +-# take the precedence; this is for compatibility with GNU install. +- +-if test -n "$dir_arg"; then +- if test -n "$dst_arg"; then +- echo "$0: target directory not allowed when installing a directory." >&2 +- exit 1 +- fi +-fi +- +-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then +- # When -d is used, all remaining arguments are directories to create. +- # When -t is used, the destination is already specified. +- # Otherwise, the last argument is the destination. Remove it from $@. +- for arg +- do +- if test -n "$dst_arg"; then +- # $@ is not empty: it contains at least $arg. +- set fnord "$@" "$dst_arg" +- shift # fnord +- fi +- shift # arg +- dst_arg=$arg +- # Protect names problematic for 'test' and other utilities. +- case $dst_arg in +- -* | [=\(\)!]) dst_arg=./$dst_arg;; +- esac +- done +-fi +- +-if test $# -eq 0; then +- if test -z "$dir_arg"; then +- echo "$0: no input file specified." >&2 +- exit 1 +- fi +- # It's OK to call 'install-sh -d' without argument. +- # This can happen when creating conditional directories. +- exit 0 +-fi +- +-if test -z "$dir_arg"; then +- if test $# -gt 1 || test "$is_target_a_directory" = always; then +- if test ! -d "$dst_arg"; then +- echo "$0: $dst_arg: Is not a directory." >&2 +- exit 1 +- fi +- fi +-fi +- +-if test -z "$dir_arg"; then +- do_exit='(exit $ret); exit $ret' +- trap "ret=129; $do_exit" 1 +- trap "ret=130; $do_exit" 2 +- trap "ret=141; $do_exit" 13 +- trap "ret=143; $do_exit" 15 +- +- # Set umask so as not to create temps with too-generous modes. +- # However, 'strip' requires both read and write access to temps. +- case $mode in +- # Optimize common cases. +- *644) cp_umask=133;; +- *755) cp_umask=22;; +- +- *[0-7]) +- if test -z "$stripcmd"; then +- u_plus_rw= +- else +- u_plus_rw='% 200' +- fi +- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; +- *) +- if test -z "$stripcmd"; then +- u_plus_rw= +- else +- u_plus_rw=,u+rw +- fi +- cp_umask=$mode$u_plus_rw;; +- esac +-fi +- +-for src +-do +- # Protect names problematic for 'test' and other utilities. +- case $src in +- -* | [=\(\)!]) src=./$src;; +- esac +- +- if test -n "$dir_arg"; then +- dst=$src +- dstdir=$dst +- test -d "$dstdir" +- dstdir_status=$? +- else +- +- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command +- # might cause directories to be created, which would be especially bad +- # if $src (and thus $dsttmp) contains '*'. +- if test ! -f "$src" && test ! -d "$src"; then +- echo "$0: $src does not exist." >&2 +- exit 1 +- fi +- +- if test -z "$dst_arg"; then +- echo "$0: no destination specified." >&2 +- exit 1 +- fi +- dst=$dst_arg +- +- # If destination is a directory, append the input filename; won't work +- # if double slashes aren't ignored. +- if test -d "$dst"; then +- if test "$is_target_a_directory" = never; then +- echo "$0: $dst_arg: Is a directory" >&2 +- exit 1 +- fi +- dstdir=$dst +- dst=$dstdir/`basename "$src"` +- dstdir_status=0 +- else +- dstdir=`dirname "$dst"` +- test -d "$dstdir" +- dstdir_status=$? +- fi +- fi +- +- obsolete_mkdir_used=false +- +- if test $dstdir_status != 0; then +- case $posix_mkdir in +- '') +- # Create intermediate dirs using mode 755 as modified by the umask. +- # This is like FreeBSD 'install' as of 1997-10-28. +- umask=`umask` +- case $stripcmd.$umask in +- # Optimize common cases. +- *[2367][2367]) mkdir_umask=$umask;; +- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; +- +- *[0-7]) +- mkdir_umask=`expr $umask + 22 \ +- - $umask % 100 % 40 + $umask % 20 \ +- - $umask % 10 % 4 + $umask % 2 +- `;; +- *) mkdir_umask=$umask,go-w;; +- esac +- +- # With -d, create the new directory with the user-specified mode. +- # Otherwise, rely on $mkdir_umask. +- if test -n "$dir_arg"; then +- mkdir_mode=-m$mode +- else +- mkdir_mode= +- fi +- +- posix_mkdir=false +- case $umask in +- *[123567][0-7][0-7]) +- # POSIX mkdir -p sets u+wx bits regardless of umask, which +- # is incompatible with FreeBSD 'install' when (umask & 300) != 0. +- ;; +- *) +- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ +- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 +- +- if (umask $mkdir_umask && +- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 +- then +- if test -z "$dir_arg" || { +- # Check for POSIX incompatibilities with -m. +- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or +- # other-writable bit of parent directory when it shouldn't. +- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. +- ls_ld_tmpdir=`ls -ld "$tmpdir"` +- case $ls_ld_tmpdir in +- d????-?r-*) different_mode=700;; +- d????-?--*) different_mode=755;; +- *) false;; +- esac && +- $mkdirprog -m$different_mode -p -- "$tmpdir" && { +- ls_ld_tmpdir_1=`ls -ld "$tmpdir"` +- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" +- } +- } +- then posix_mkdir=: +- fi +- rmdir "$tmpdir/d" "$tmpdir" +- else +- # Remove any dirs left behind by ancient mkdir implementations. +- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null +- fi +- trap '' 0;; +- esac;; +- esac +- +- if +- $posix_mkdir && ( +- umask $mkdir_umask && +- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" +- ) +- then : +- else +- +- # The umask is ridiculous, or mkdir does not conform to POSIX, +- # or it failed possibly due to a race condition. Create the +- # directory the slow way, step by step, checking for races as we go. +- +- case $dstdir in +- /*) prefix='/';; +- [-=\(\)!]*) prefix='./';; +- *) prefix='';; +- esac +- +- oIFS=$IFS +- IFS=/ +- set -f +- set fnord $dstdir +- shift +- set +f +- IFS=$oIFS +- +- prefixes= +- +- for d +- do +- test X"$d" = X && continue +- +- prefix=$prefix$d +- if test -d "$prefix"; then +- prefixes= +- else +- if $posix_mkdir; then +- (umask=$mkdir_umask && +- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break +- # Don't fail if two instances are running concurrently. +- test -d "$prefix" || exit 1 +- else +- case $prefix in +- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; +- *) qprefix=$prefix;; +- esac +- prefixes="$prefixes '$qprefix'" +- fi +- fi +- prefix=$prefix/ +- done +- +- if test -n "$prefixes"; then +- # Don't fail if two instances are running concurrently. +- (umask $mkdir_umask && +- eval "\$doit_exec \$mkdirprog $prefixes") || +- test -d "$dstdir" || exit 1 +- obsolete_mkdir_used=true +- fi +- fi +- fi +- +- if test -n "$dir_arg"; then +- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && +- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && +- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || +- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 +- else +- +- # Make a couple of temp file names in the proper directory. +- dsttmp=$dstdir/_inst.$$_ +- rmtmp=$dstdir/_rm.$$_ +- +- # Trap to clean up those temp files at exit. +- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 +- +- # Copy the file name to the temp name. +- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && +- +- # and set any options; do chmod last to preserve setuid bits. +- # +- # If any of these fail, we abort the whole thing. If we want to +- # ignore errors from any of these, just make sure not to ignore +- # errors from the above "$doit $cpprog $src $dsttmp" command. +- # +- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && +- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && +- { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && +- { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && +- +- # If -C, don't bother to copy if it wouldn't change the file. +- if $copy_on_change && +- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && +- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && +- set -f && +- set X $old && old=:$2:$4:$5:$6 && +- set X $new && new=:$2:$4:$5:$6 && +- set +f && +- test "$old" = "$new" && +- $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 +- then +- rm -f "$dsttmp" +- else +- # Rename the file to the real destination. +- $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || +- +- # The rename failed, perhaps because mv can't rename something else +- # to itself, or perhaps because mv is so ancient that it does not +- # support -f. +- { +- # Now remove or move aside any old file at destination location. +- # We try this two ways since rm can't unlink itself on some +- # systems and the destination file might be busy for other +- # reasons. In this case, the final cleanup might fail but the new +- # file should still install successfully. +- { +- test ! -f "$dst" || +- $doit $rmcmd -f "$dst" 2>/dev/null || +- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && +- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } +- } || +- { echo "$0: cannot unlink or rename $dst" >&2 +- (exit 1); exit 1 +- } +- } && +- +- # Now rename the file to the real destination. +- $doit $mvcmd "$dsttmp" "$dst" +- } +- fi || exit 1 +- +- trap '' 0 +- fi +-done +- +-# Local variables: +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "scriptversion=" +-# time-stamp-format: "%:y-%02m-%02d.%02H" +-# time-stamp-time-zone: "UTC" +-# time-stamp-end: "; # UTC" +-# End: +diff -Nuar groff-1.22.3.old/m4/groff.m4 groff-1.22.3/m4/groff.m4 +--- groff-1.22.3.old/m4/groff.m4 2014-11-04 10:38:35.568519709 +0200 ++++ groff-1.22.3/m4/groff.m4 2015-04-23 20:57:03.000000000 +0300 +@@ -148,7 +148,11 @@ + # We need makeinfo 4.8 or newer. + + AC_DEFUN([GROFF_MAKEINFO], +- [if test $docadd_info = yes; then ++ # By default automake will set MAKEINFO to MAKEINFO = ${SHELL} /build-aux/missing makeinfo.As we need a more precise ++ # check of makeinfo version, we don't use it. ++ [MAKEINFO= ++ if test $docadd_info = yes; then + missing= + AC_CHECK_PROG([MAKEINFO], [makeinfo], [makeinfo]) + if test -z "$MAKEINFO"; then +@@ -173,13 +177,13 @@ + infofile=doc/groff.info + test -f ${infofile} || infofile=${srcdir}/${infofile} + if test ! -f ${infofile} \ +- || test ${srcdir}/doc/groff.texinfo -nt ${infofile}; then ++ || test ${srcdir}/doc/groff.texi -nt ${infofile}; then + AC_MSG_ERROR($missing + [Get the `texinfo' package version 4.8 or newer.]) + else + AC_MSG_WARN($missing + [Get the `texinfo' package version 4.8 or newer if you want to convert +-`groff.texinfo' into a PDF or HTML document.]) ++`groff.texi' into a PDF or HTML document.]) + fi + fi + +@@ -195,8 +199,8 @@ + AC_SUBST([MAKEINFO]) + AC_SUBST([make_infodoc]) + AC_SUBST([make_install_infodoc]) +- AC_SUBST([make_uninstall_infodoc])]) +- ++ AC_SUBST([make_uninstall_infodoc]) ++ AC_SUBST([makeinfo_version_numeric])]) + + # The following programs are needed for grohtml. + +@@ -902,6 +906,8 @@ + AC_SUBST([tmac_wrap])]) + + ++# Searching if a non-GNU Troff is installed. The built-in register ++# \n[.g] is always 1 in GNU Troff. + AC_DEFUN([GROFF_G], + [AC_MSG_CHECKING([for existing troff installation]) + if test "x`(echo .tm '|n(.g' | tr '|' '\\\\' | troff -z -i 2>&1) 2>/dev/null`" = x0; then +@@ -998,18 +1004,12 @@ + case "$host_os" in + *mingw*) + make_winscripts=winscripts +- make_install_winscripts=install_winscripts +- make_uninstall_winscripts=uninstall_winscripts + AC_MSG_RESULT([yes]) ;; + *) + make_winscripts= +- make_install_winscripts= +- make_uninstall_winscripts= + AC_MSG_RESULT([no]) ;; + esac +- AC_SUBST([make_winscripts]) +- AC_SUBST([make_install_winscripts]) +- AC_SUBST([make_uninstall_winscripts])]) ++ AC_SUBST([make_winscripts])]) + + + # Check whether we need a declaration for a function. +@@ -1353,3 +1353,22 @@ + AC_DEFUN([GROFF_REFERDIR_DEFAULT], + referdir=$libprogramdir/refer + AC_SUBST([referdir])) ++ ++# Check for xpmtoppm, for gnu.eps generation ++AC_DEFUN([GROFF_PROG_XPMTOPPM], ++ [AC_CHECK_PROG([XPMTOPPM], [xpmtoppm], [found], [missing])]) ++ ++# Check for make builtin variable RM ++AC_DEFUN([GROFF_MAKE_RM], ++ [AC_MSG_CHECKING(whether make has builtin variable RM) ++cat < test_make_rm.mk ++all: ++ @if test -n "\$(RM)"; then \ ++ echo "yes"; \ ++ else \ ++ echo "no"; \ ++ fi ++EOF ++ groff_is_rm_defined=`make -sf test_make_rm.mk` ++ AC_MSG_RESULT([$groff_is_rm_defined]) ++ rm -f test_make_rm.mk]) +diff -Nuar groff-1.22.3.old/Makefile groff-1.22.3/Makefile +--- groff-1.22.3.old/Makefile 2014-11-04 10:39:21.025951413 +0200 ++++ groff-1.22.3/Makefile 1970-01-01 02:00:00.000000000 +0200 +@@ -1,34 +0,0 @@ +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.init +-# +-SHELL=/bin/sh +- +-.PHONY: all +-all: +- $(SHELL) configure +- $(MAKE) all +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/Makefile.am groff-1.22.3/Makefile.am +--- groff-1.22.3.old/Makefile.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/Makefile.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,857 @@ ++# # Copyright (C) 1989-2014 Free Software Foundation, Inc. ++# Free Software Foundation, Inc. ++# Original Makefile.in written by James Clark (jjc@jclark.com) ++# Migrated to Automake by Bertrand Garrigues ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++# Makefile.am ++# ++ ++# The variables that are listed in the following comments will be ++# automatically set by automake in the generated Makefile.in ++ ++# SHELL ++ ++# PACKAGE_TARNAME ++ ++# srcdir ++ ++# top_srcdir ++ ++# VPATH ++ ++# top_builddir ++ ++# HOST ++# `HOST' is the canonical host specification, ++# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM ++# or ++# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM ++ ++# `RT_SEP' is the operating system's native PATH SEPARATOR CHAR, which ++# is to be used in runtime PATHs compiled into groff executables. ++RT_SEP=@GROFF_PATH_SEPARATOR@ ++ ++# `SH_SEP' is a alternative PATH SEPARATOR CHAR, to be used in shell ++# scripts and makefile rules; it may be the same as `RT_SEP', but, ++# particularly in some Microsoft environments, it may differ. ++SH_SEP=@PATH_SEPARATOR@ ++ ++# GLIBC2 ++# `GLIBC21' is yes if the host operating system uses GNU libc 2.1 or newer, ++# otherwise no. ++ ++ ++# VERSION is set by automake, based on what is passed to AC_INIT. We ++# pass GROFF_VERSION_STRING to it, which skips the revision if set to ++# 0. ++ ++# PAGE ++# Define `page' to be letter if your PostScript printer uses 8.5x11 ++# paper (USA) and define it to be A4, if it uses A4 paper (rest of the ++# world). ++ ++# GHOSTSCRIPT ++# The name of the ghostscript program. Normally, gs, on GNU/Linux ++# but it might be different on MS-DOS/MS-WIN32 systems. ++ ++# ALT_GHOSTSCRIPT_PROGS ++# `ALT_GHOSTSCRIPT_PROGS' specifies a list alternative names, ++# which can be tried if `GHOSTSCRIPT' cannot be found at run time. ++ ++# ALT_AWK_PROGS ++# Similarly, `ALT_AWK_PROGS' specifies a list of alternative names, ++# which can be tried at run time, to identify the awk program. ++ ++# BROKEN_SPOOLER_FLAGS ++# Normally the Postscript driver, grops, produces output that conforms ++# to version 3.0 of the Adobe Document Structuring Conventions. ++# Unfortunately some spoolers and previewers can't handle such output. ++# The BROKEN_SPOOLER_FLAGS variable tells grops what it should do to ++# make its output acceptable to such programs. This variable controls ++# only the default behaviour of grops; the behaviour can be changed at ++# runtime by the grops -b option (and so by groff -P-b). ++# Use a value of 0 if your spoolers and previewers are able to handle ++# conforming PostScript correctly. ++# Add 1 if no %%{Begin,End}DocumentSetup comments should be generated; ++# this is needed for early versions of TranScript that get confused by ++# anything between the %%EndProlog line and the first %%Page: comment. ++# Add 2 if lines in included files beginning with %! should be ++# stripped out; this is needed for the OpenWindows 2.0 pageview previewer. ++# Add 4 if %%Page, %%Trailer and %%EndProlog comments should be ++# stripped out of included files; this is needed for spoolers that ++# don't understand the %%{Begin,End}Document comments. I suspect this ++# includes early versions of TranScript. ++# Add 8 if the first line of the PostScript output should be %!PS-Adobe-2.0 ++# rather than %!PS-Adobe-3.0; this is needed when using Sun's Newsprint ++# with a printer that requires page reversal. ++ ++ ++# `DEVICE' is the default device. ++DEVICE=ps ++ ++# XDEVIDIRS ++# `XDEVDIRS' is either `font/devX{75,100}{,-12}' or empty. ++ ++# XPROGDIRS ++# `XPROGDIRS' is either `src/devices/xditview src/utils/xtotroff' or empty. ++ ++# XLIBDIRS ++# `XLIBDIRS' is either `src/libs/libxutil' or empty. ++ ++# `TTYDEVDIRS' is either `font/devascii font/devlatin1' (for ++# ASCII) or `font/devcp1047' (for EBCDIC) plus font/devutf8. ++TTYDEVDIRS=@TTYDEVDIRS@ font/devutf8 ++ ++# OTHERDEVDIRS ++# `OTHERDEVDIRS' is either `font/devlj4 font/devlbp' (for ASCII) or ++# empty (for EBCDIC). ++ ++# PSPRINT ++# `PSPRINT' is the command to use for printing a PostScript file, ++# for example `lpr'. ++ ++# DVIPRINT ++# `DVIPRINT' is the command to use for printing a TeX dvi file, ++# for example `lpr -d'. ++ ++# g ++# Prefix for names of programs that have Unix counterparts. ++# For example, if `g' is `g' then troff will be installed as ++# gtroff. This doesn't affect programs like grops or groff that have ++# no Unix counterparts. Note that the groff versions of eqn and tbl ++# will not work with Unix troff. ++ ++# prefix ++# exec_prefix ++# Common prefix for installation directories. ++# Used in definitions of exec_prefix, datasubdir, fontpath, manroot. ++# This must already exist when you do make install. ++ ++# bindir ++# `bindir' says where to install executables. ++ ++# libdir ++# `libdir' says where to install platform-dependent data. ++ ++# libprogramdir ++# `libprogramdir' is $(libdir)/groff ++ ++# `datasubdir' says where to install platform-independent data files. ++# datadir ++# datarootdir ++dataprogramdir=$(datadir)/groff ++datasubdir=$(dataprogramdir)/$(VERSION) ++ ++# infodir ++# `infodir' says where to install info files. ++ ++# docdir ++# `docdir' says where to install documentation files. The default ++# location is ${datarootdir}/doc/${PACKAGE}, but we add the version ++docdir=$(datarootdir)/doc/${PACKAGE}-$(VERSION) ++ ++# `exampledir' says where to install example files. ++exampledir=$(docdir)/examples ++ ++# `htmldocdir' says where to install documentation in HTML format. ++htmldocdir=$(docdir)/html ++ ++# `pdfdocdir' says where to install documentation in PDF format. ++pdfdocdir=$(docdir)/pdf ++ ++# `fontdir' says where to install dev*/*. ++fontdir=$(datasubdir)/font ++ ++# `oldfontdir' says where to install old font sets (as dev*/*). ++oldfontdir=$(datasubdir)/oldfont ++ ++# `localfontdir' says where local fonts will be installed (as dev*/*). ++localfontdir=$(dataprogramdir)/site-font ++ ++# `legacyfontdir' is for compatibility with non-GNU troff. ++legacyfontdir=/usr/lib/font ++ ++# `fontpath' says where to look for dev*/*. ++fontpath=$(localfontdir)$(RT_SEP)$(fontdir)$(RT_SEP)$(legacyfontdir) ++ ++# `tmacdir' says where to install macros. ++tmacdir=$(datasubdir)/tmac ++ ++# `systemtmacdir' says where to install platform-dependent macros. ++systemtmacdir=$(libprogramdir)/site-tmac ++ ++# `localtmacdir' says where local files will be installed. ++localtmacdir=$(dataprogramdir)/site-tmac ++ ++# appresdir ++# `appresdir' says where to install the application resource file for ++# gxditview. ++ ++# groffer_dir ++# glilypond_dir ++# grog_dir ++# gpinyin_dir ++ ++# `tmacpath' says where to look for macro files. ++# The current directory will be prepended in unsafe mode only; the home ++# directory will be always added. ++# `troffrc' and `troffrc-end' (and `eqnrc') are searched neither in the ++# current nor in the home directory. ++tmacpath=$(systemtmacdir)$(RT_SEP)$(localtmacdir)$(RT_SEP)$(tmacdir) ++ ++# sys_tmac_prefix ++# `sys_tmac_prefix' is prefix (if any) for system macro packages. ++ ++# pnmtops_nosetpage ++# `pnmtops_nosetpage' is the command to be run to generate an eps ++# file. Some versions of pnmtops provide the -nosetpage option. ++# We detect this and use it if present. ++ ++# tmac_wrap ++# `tmac_wrap' is list of system macro packages that should be made ++# available to groff by creating a corresponding macro package ++# in the groff macro directory that references the system macro ++# package. ++ ++# If there is a groff version of a macro package listed in $(tmac_wrap), ++# then the groff version will be installed with a prefix of this. ++# Don't make this empty. ++tmac_prefix=g ++ ++# The groff -mm macros will be available as -m$(tmac_m_prefix)m. ++tmac_m_prefix=\ ++ `for i in $(tmac_wrap) ""; do case "$$i" in m) echo $(tmac_prefix);; esac; done` ++# The groff -ms macros will be available as -m$(tmac_s_prefix)s. ++tmac_s_prefix=\ ++ `for i in $(tmac_wrap) ""; do case "$$i" in s) echo $(tmac_prefix);; esac; done` ++# The groff -man macros will be available as -m$(tmac_an_prefix)an. ++tmac_an_prefix=\ ++ `for i in $(tmac_wrap) ""; do case "$$i" in an) echo $(tmac_prefix);; esac; done` ++ ++# Extension to be used for refer index files. Index files are not ++# sharable between different architectures, so you might want to use ++# different suffixes for different architectures. Choose an extension ++# that doesn't conflict with refer or any other indexing program. ++indexext=.i ++ ++# Directory containing the default index for refer. ++indexdir=/usr/dict/papers ++ ++# The filename (without suffix) of the default index for refer. ++indexname=Ind ++ ++# common_words_file is a file containing a list of common words. ++# If your system provides /usr/lib/eign it will be copied onto this, ++# otherwise the supplied eign file will be used. ++common_words_file=$(datasubdir)/eign ++ ++# mandir ++# `manroot' is the root of the man page directory tree. ++manroot=$(mandir) ++ ++# `man1ext' is the man section for user commands. ++man1ext=1 ++man1dir=$(manroot)/man$(man1ext) ++ ++# `man5ext' is the man section for file formats. ++man5ext=5 ++man5dir=$(manroot)/man$(man5ext) ++ ++# `man7ext' is the man section for macros. ++man7ext=7 ++man7dir=$(manroot)/man$(man7ext) ++ ++# doc_dist_target_ok ++# `dist' target is disallowed in some `configure' combinations. ++ ++# The configure script checks whether the user wants the info documentation. ++# For the repo version this mechanism also suppresses building via `makeinfo'. ++# make_infodoc ++# make_install_infodoc ++# make_uninstall_infodoc ++ ++# The configure script checks whether all necessary utility programs for ++# grohtml are available -- only then we can build the HTML documentation. ++# make_htmldoc ++# make_install_htmldoc ++# make_uninstall_htmldoc ++ ++# make_htmlexamples ++# make_install_htmlexamples ++# make_uninstall_htmlexamples ++ ++# The configure script also checks whether all necessary utility programs ++# for pdfroff are available -- only then we can build PDF documentation. ++# make_pdfdoc ++# make_install_pdfdoc ++# make_uninstall_pdfdoc ++ ++# make_pdfexamples ++# make_install_pdfexamples ++# make_uninstall_pdfexamples ++ ++# `other' documentation, e.g., `meref.me' and `pic.ms', as well as their ++# generated counterparts.. ++# make_otherdoc ++# make_install_otherdoc ++# make_uninstall_otherdoc ++ ++# `examples' -- a generic switch, but the generated examples are furtherly ++# subdivided to catch HTML and PDF production availability. ++# make_examples ++# make_install_examples ++# make_uninstall_examples ++ ++# Windows `.cmd' files ++# make_winscripts ++# make_install_winscripts ++# make_uninstall_winscripts ++ ++# All the previous installation directories, when used, are prefixed with ++# $(DESTDIR) during install and uninstall, to support staged installations. ++ ++# config.h might set the following defines: ++# ++# WORDS_BIGENDIAN if your target platform is big-endian ++# IS_EBCDIC_HOST if the host's encoding is EBCDIC ++# ++# HAVE_DIRECT_H if you have ++# HAVE_DIRENT_H if you have ++# HAVE_CC_INTTYPES_H if you have a C++ ++# HAVE_PROCESS_H if you have ++# HAVE_LIMITS_H if you have ++# HAVE_CC_LIMITS_H if you have a C++ ++# HAVE_MATH_H if you have ++# HAVE_CC_OSFCN_H if you have a C++ ++# HAVE_STDDEF_H if you have ++# HAVE_STDLIB_H if you have ++# HAVE_STRING_H if you have ++# HAVE_STRINGS_H if you have ++# HAVE_SYS_DIR_H if you have ++# HAVE_SYS_PARAM_H if you have ++# HAVE_SYS_STAT_H if you have ++# HAVE_SYS_TIME_H if you have ++# HAVE_SYS_TYPES_H if you have ++# HAVE_UNISTD_H if you have ++# ++# HAVE_FMOD if you have fmod() ++# HAVE_GETCWD if you have getcwd() ++# HAVE_GETTIMEOFDAY if you have gettimeofday() ++# HAVE_ICONV if you have iconv() ++# HAVE_ISATTY if you have isatty() ++# HAVE_KILL if you have kill() ++# HAVE_LANGINFO_CODESET if you have nl_langinfo() ++# HAVE_MKSTEMP if you have mkstemp() ++# HAVE_MMAP if you have mmap() ++# HAVE_PUTENV if you have putenv() ++# HAVE_RENAME if you have rename() ++# HAVE_SETLOCALE if you have setlocale() ++# HAVE_SNPRINTF if you have snprintf() ++# HAVE_STRCASECMP if you have strcasecmp() ++# HAVE_STRNCASECMP if you have strncasecmp() ++# HAVE_STRERROR if you have strerror() ++# HAVE_STRSEP if you have strsep() ++# HAVE_STRTOL if you have strtol() ++# HAVE_SYMLINK if you have symlink() ++# HAVE_VSNPRINTF if you have vsnprintf() ++# ++# NEED_DECLARATION_GETTIMEOFTODAY ++# if your C++ doesn't declare ++# gettimeofday() ++# NEED_DECLARATION_HYPOT if your C++ doesn't declare hypot() ++# NEED_DECLARATION_PCLOSE if your C++ doesn't declare pclose() ++# NEED_DECLARATION_POPEN if your C++ doesn't declare popen() ++# NEED_DECLARATION_PUTENV if your C++ doesn't declare ++# putenv() ++# NEED_DECLARATION_RAND if your C++ doesn't declare rand() ++# NEED_DECLARATION_SNPRINTF if your C++ doesn't declare ++# snprintf() ++# NEED_DECLARATION_SRAND if your C++ doesn't declare srand() ++# NEED_DECLARATION_STRCASECMP if your C++ doesn't declare ++# strcasecmp() ++# NEED_DECLARATION_STRNCASECMP ++# if your C++ doesn't declare ++# strncasecmp() ++# NEED_DECLARATION_VFPRINTF if your C++ doesn't declare ++# vfprintf() ++# NEED_DECLARATION_VSNPRINTF if your C++ doesn't declare ++# vsnprintf() ++# ++# HAVE_DECL_GETC_UNLOCKED if you have getc_unlocked() ++# HAVE_DECL_SYS_SIGLIST if you have sys_siglist[] ++# ++# HAVE_STRUCT_EXCEPTION if defines struct exception ++# HAVE_SYS_NERR if you have sysnerr in or ++# HAVE_SYS_ERRLIST if you have sys_errlist in or ++# ++# ICONV_CONST=const if declaration of iconv() needs const ++# LONG_FOR_TIME_T if localtime() takes a long * not a time_t * ++# RETSIGTYPE=int if signal handlers return int not void ++# RET_TYPE_SRAND_IS_VOID if srand() returns void not int ++# ++# WCOREFLAG=0200 if the 0200 bit of the status returned by ++# wait() indicates whether a core image was ++# produced for a process that was terminated ++# by a signal ++# ++# HAVE_WORKING_O_NOATIME define if 's O_NOATIME flag works ++# HAVE_WORKING_O_NOFOLLOW define if 's O_NOFOLLOW flag works ++# ++# uintmax_t= define to `unsigned long' or `unsigned long ++# long' if does not exist ++# ++# TRADITIONAL_CPP if your C++ compiler uses a traditional ++# (Reiser) preprocessor ++# ARRAY_DELETE_NEEDS_SIZE if your C++ doesn't understand `delete []' ++# ++# PAGE=A4 if the the printer's page size is A4 ++# GHOSTSCRIPT=gs the name (and directory if required) of the ++# ghostscript program ++ ++# Include ++# ++# {fmod,getcwd,mkstemp,putenv,snprintf,strcasecmp, ++# strerror,strncasecmp,strtol}.$(OBJEXT) ++# ++# LIBOBJS ++# in LIBOBJS if your C library is missing the corresponding function. ++# vsnprintf is defined in the snprintf.$(OBJEXT) module. ++ ++# `CCC' is the compiler for C++ (.cpp) files. ++CCC=@CXX@ ++# CC ++# CFLAGS ++# CPPFLAGS ++# LDFLAGS ++ ++# X_CFLAGS ++# X_LIBS ++# X_EXTRA_LIBS ++# X_PRE_LIBS ++ ++# YACC ++ ++# GREP ++# EGREP ++ ++# MAKEINFO ++ ++# EXEEXT ++# OBJEXT ++# LIBEXT ++# LIBS ++# LIBM ++# LIBICONV ++# RANLIB ++# INSTALL ++# INSTALL_PROGRAM ++# INSTALL_SCRIPT ++# INSTALL_DATA ++# INSTALL_INFO ++# LN_S ++ ++AR=ar ++ETAGS=etags ++ETAGSFLAGS= ++# Flag that tells etags to assume C++. ++ETAGSCCFLAG=-C ++# Full path to perl. ++# PERL ++# PERLVERSION ++# Sed command with which to edit sh scripts. ++# SH_SCRIPT_SED_CMD ++# Sed script to deal with OS dependencies in sh scripts. ++SH_DEPS_SED_SCRIPT=$(top_builddir)/shdeps.sed ++ ++# The program to create directory hierarchies. ++# mkinstalldirs is now in gnulib/build-aux ++ ++PURIFY=purify ++PURIFYCCFLAGS= ++#PURIFYCCFLAGS=-g++=yes \ ++# -collector=`dirname \`$(CCC) -print-libgcc-file-name\``/ld ++ ++# Add groff and gnulib m4 macros ++ACLOCAL_AMFLAGS = -I m4 -I gnulib_m4 ++ ++# Common preprocessor flags: gnulib includes, common includes in ++# src/include, and config.h that is generated in the build tree ++AM_CPPFLAGS = \ ++ -I$(top_srcdir)/src/include \ ++ -I$(top_srcdir)/lib \ ++ -I$(top_builddir)/src/include \ ++ -I$(top_builddir)/lib ++ ++# The following Automake variables will be overloaded by the various ++# .am files ++bin_PROGRAMS = ++nobase_bin_PROGRAMS = ++bin_SCRIPTS = ++dist_bin_SCRIPTS = ++MOSTLYCLEANFILES = ++MOSTLYCLEANADD = ++noinst_LIBRARIES = ++BUILT_SOURCES = ++CLEANFILES = ++# gnulib asks to include this file ++EXTRA_DIST = gnulib_m4/gnulib-cache.m4 ++FONTFILES = ++PREFIXMAN1 = ++PREFIXMAN5 = ++PREFIXMAN7 = ++man1_MANS = ++man5_MANS = ++man7_MANS = ++ ++# for lex/yacc ++AM_YFLAGS = -d -v ++ ++SUFFIXES = ++ ++# tests launched by make check ++check_SCRIPTS = ++check_PROGRAMS = ++TESTS = ++AM_TESTS_ENVIRONMENT = \ ++ abs_top_srcdir=$(abs_top_srcdir) \ ++ abs_top_builddir=$(abs_top_builddir) \ ++ export abs_top_srcdir abs_top_builddir; ++ ++# We use Automake's Uniform Naming Scheme. ++# ++# prefixexecbin_PROGRAMS is the list of programs that may have a ++# NAMEPREFIX if an existing non-GNU troff system was detected. ++# ++# This is done by the m4 macro GROFF_G that checks for the presence of ++# GNU Troff built-in \n[.g] macro. If a Unix Troff binary was ++# detected, the following programs and scripts names will have a 'g' ++# prefix: chem, tbl, eqn, neqn, pic, soleimm grn, refer, lookbib, ++# troff, nroff. Also, PROG_PREFIX will be set to 'g' in the generated ++# header defs.h so that these programs could be called correctly. ++# ++# prefixexecbindir is used to temporary install these programs. They ++# are then moved to bindir during the install-exec-hook. Same thing ++# for the scripts. ++NAMEPREFIX=$(g) ++prefixexecbin_PROGRAMS = ++prefixexecbin_SCRIPTS = ++if USEPROGRAMPREFIX ++# We use datadir because the uninstall rule for the PROGRAMS attempt ++# to cd into prefixexecbindir, and thus if prefixexecbindir is removed ++# two consecutive uninstall would fail ++prefixexecbindir = $(datadir) ++else ++prefixexecbindir = $(bindir) ++endif ++ ++# Path to binaries and flags used by contribs and doc to generated doc. ++# These may be overridden if cross-compiling. ++GROFFBIN = $(abs_top_builddir)/groff ++GROFF_BIN_PATH = $(abs_top_builddir) ++PDFMOMBIN = $(abs_top_builddir)/pdfmom ++FFLAG=-F$(abs_top_builddir)/font -F$(abs_top_srcdir)/font ++TFLAG=-M$(abs_top_builddir)/tmac -M$(abs_top_srcdir)/tmac ++ ++# make builtin variable RM ++if MAKE_DONT_HAVE_RM ++RM = rm -f ++endif ++ ++# Non-recursive makefile system. See Automake manual '7.3 An ++# Alternative Approach to Subdirectories'. We use a single Makefile.am ++# that includes other .am files, rather than using SUBDIRS. Note that ++# relative paths in the following .am files are relative to the top ++# source directory. ++ ++include $(top_srcdir)/lib/gnulib.mk ++include $(top_srcdir)/arch/mingw/mingw.am ++include $(top_srcdir)/arch/misc/misc.am ++include $(top_srcdir)/contrib/chem/chem.am ++include $(top_srcdir)/contrib/eqn2graph/eqn2graph.am ++include $(top_srcdir)/contrib/gdiffmk/gdiffmk.am ++include $(top_srcdir)/contrib/glilypond/glilypond.am ++include $(top_srcdir)/contrib/gperl/gperl.am ++include $(top_srcdir)/contrib/gpinyin/gpinyin.am ++include $(top_srcdir)/contrib/grap2graph/grap2graph.am ++include $(top_srcdir)/contrib/groff_filenames/groff_filenames.am ++include $(top_srcdir)/contrib/groffer/groffer.am ++include $(top_srcdir)/contrib/hdtbl/hdtbl.am ++include $(top_srcdir)/contrib/mm/mm.am ++include $(top_srcdir)/contrib/mom/mom.am ++include $(top_srcdir)/contrib/pdfmark/pdfmark.am ++include $(top_srcdir)/contrib/pic2graph/pic2graph.am ++include $(top_srcdir)/doc/doc.am ++include $(top_srcdir)/font/devX100/devX100.am ++include $(top_srcdir)/font/devX100-12/devX100-12.am ++include $(top_srcdir)/font/devX75/devX75.am ++include $(top_srcdir)/font/devX75-12/devX75-12.am ++include $(top_srcdir)/font/devascii/devascii.am ++include $(top_srcdir)/font/devcp1047/devcp1047.am ++include $(top_srcdir)/font/devdvi/devdvi.am ++include $(top_srcdir)/font/devhtml/devhtml.am ++include $(top_srcdir)/font/devlatin1/devlatin1.am ++include $(top_srcdir)/font/devlbp/devlbp.am ++include $(top_srcdir)/font/devlj4/devlj4.am ++include $(top_srcdir)/font/devpdf/devpdf.am ++include $(top_srcdir)/font/devps/devps.am ++include $(top_srcdir)/font/devutf8/devutf8.am ++include $(top_srcdir)/font/scripts/scripts.am ++include $(top_srcdir)/man/man.am ++include $(top_srcdir)/src/include/include.am ++include $(top_srcdir)/src/libs/libbib/libbib.am ++include $(top_srcdir)/src/libs/libdriver/libdriver.am ++include $(top_srcdir)/src/libs/libgroff/libgroff.am ++include $(top_srcdir)/src/libs/libxutil/libxutil.am ++include $(top_srcdir)/src/devices/grodvi/grodvi.am ++include $(top_srcdir)/src/devices/grohtml/grohtml.am ++include $(top_srcdir)/src/devices/grolbp/grolbp.am ++include $(top_srcdir)/src/devices/grolj4/grolj4.am ++include $(top_srcdir)/src/devices/gropdf/gropdf.am ++include $(top_srcdir)/src/devices/grops/grops.am ++include $(top_srcdir)/src/devices/grotty/grotty.am ++include $(top_srcdir)/src/devices/xditview/xditview.am ++include $(top_srcdir)/src/preproc/eqn/eqn.am ++include $(top_srcdir)/src/preproc/grn/grn.am ++include $(top_srcdir)/src/preproc/html/html.am ++include $(top_srcdir)/src/preproc/pic/pic.am ++include $(top_srcdir)/src/preproc/preconv/preconv.am ++include $(top_srcdir)/src/preproc/refer/refer.am ++include $(top_srcdir)/src/preproc/soelim/soelim.am ++include $(top_srcdir)/src/preproc/tbl/tbl.am ++include $(top_srcdir)/src/roff/groff/groff.am ++include $(top_srcdir)/src/roff/grog/grog.am ++include $(top_srcdir)/src/roff/nroff/nroff.am ++include $(top_srcdir)/src/roff/troff/troff.am ++include $(top_srcdir)/src/utils/addftinfo/addftinfo.am ++include $(top_srcdir)/src/utils/afmtodit/afmtodit.am ++include $(top_srcdir)/src/utils/hpftodit/hpftodit.am ++include $(top_srcdir)/src/utils/indxbib/indxbib.am ++include $(top_srcdir)/src/utils/lkbib/lkbib.am ++include $(top_srcdir)/src/utils/lookbib/lookbib.am ++include $(top_srcdir)/src/utils/pfbtops/pfbtops.am ++include $(top_srcdir)/src/utils/tfmtodit/tfmtodit.am ++include $(top_srcdir)/src/utils/xtotroff/xtotroff.am ++include $(top_srcdir)/tmac/tmac.am ++ ++# Adding defs.h to BUILT_SOURCES will ensure that it will be built on ++# make all or make check before all other targets. However, if another ++# target is built from a clean build tree, (for example make groff) ++# the files in BUILT_SOURCES will not be built first. That is why ++# additional dependencies where added in the .am files that lists ++# objects that use defs (for exmaple in groff.am: ++# src/roff/groff/groff.$(OBJEXT): defs.h) ++BUILT_SOURCES += defs.h ++ ++# Same thing for gnulib's localcharset.c and configmake.h: gnulib uses ++# BUILT_SOURCES only, adding the following makes 'make lib/libgnu.a' ++# possible ++lib/localcharset.$(OBJEXT): lib/configmake.h ++ ++# if there is a name prefix we install the man pages by hand ++all: generate_man_files ++install-data-hook: install-prefix-man ++uninstall-hook: uninstall-prefix-man ++if USEPROGRAMPREFIX ++generate_man_files: $(PREFIXMAN1) ++install-prefix-man: ++ for f in $(PREFIXMAN1); do \ ++ manfile_final_name=`basename $$f | sed 's/n$$/1/'`; \ ++ cp -f $$f $(DESTDIR)$(man1dir)/$(NAMEPREFIX)$$manfile_final_name; \ ++ done ++ for f in $(PREFIXMAN5); do \ ++ manfile_final_name=`basename $$f | sed 's/n$$/5/'`; \ ++ cp -f $$f $(DESTDIR)$(man5dir)/$(NAMEPREFIX)$$manfile_final_name; \ ++ done ++ for f in $(PREFIXMAN7); do \ ++ manfile_final_name=`basename $$f | sed 's/n$$/7/'`; \ ++ cp -f $$f $(DESTDIR)$(man7dir)/$(NAMEPREFIX)$$manfile_final_name; \ ++ done ++uninstall-prefix-man: ++ for f in $(PREFIXMAN1); do \ ++ manfile_final_name=`basename $$f | sed 's/n$$/1/'`; \ ++ rm -f $(DESTDIR)$(man1dir)/$(NAMEPREFIX)$$manfile_final_name; \ ++ done ++ for f in $(PREFIXMAN5); do \ ++ manfile_final_name=`basename $$f | sed 's/n$$/5/'`; \ ++ rm -f $(DESTDIR)$(man5dir)/$(NAMEPREFIX)$$manfile_final_name; \ ++ done ++ for f in $(PREFIXMAN7); do \ ++ manfile_final_name=`basename $$f | sed 's/n$$/7/'`; \ ++ rm -f $(DESTDIR)$(man7dir)/$(NAMEPREFIX)$$manfile_final_name; \ ++ done ++else ++man1_MANS += $(PREFIXMAN1) ++man1_MANS += $(PREFIXMAN5) ++man1_MANS += $(PREFIXMAN7) ++install-prefix-man: ++uninstall-prefix-man: ++generate_man_files: ++endif ++ ++# Hook to create the 'current' symlink ++install-data-hook: create_current_symlink ++create_current_symlink: ++ cd $(DESTDIR)$(dataprogramdir); \ ++ rm -f current; \ ++ $(LN_S) $(VERSION) current ++ ++# Hook to move the binaries that potentially have a prefix from ++# prefixexecbindir to bindir. ++install-exec-hook: move_binaries_with_prefix ++move_binaries_with_prefix: ++if USEPROGRAMPREFIX ++ if test -n "$(NAMEPREFIX)"; then \ ++ for f in $(prefixexecbin_PROGRAMS) $(prefixexecbin_SCRIPTS); do \ ++ mv -f $(DESTDIR)$(prefixexecbindir)/$$f$(EXEEXT) \ ++ $(DESTDIR)$(bindir)/$(NAMEPREFIX)$$f$(EXEEXT); \ ++ done \ ++ fi ++endif ++ ++# Always create the site-font directory as a guide to the user. ++install-data-hook: install_site_font ++install_site_font: ++ -test -d $(DESTDIR)$(localfontdir) \ ++ || $(mkinstalldirs) $(DESTDIR)$(localfontdir) ++ ++# Create systemtmacdir if not present ++install-data-hook: install_tmacdir ++install_tmacdir: ++ -test -d $(DESTDIR)$(systemtmacdir) \ ++ || $(mkinstalldirs) $(DESTDIR)$(systemtmacdir) ++ ++# directories specific to groff ++uninstall-hook: uninstall_groffdirs ++uninstall_groffdirs: ++ if test -d $(DESTDIR)$(datasubdir); then \ ++ rm -rf $(DESTDIR)$(fontdir); \ ++ rm -rf $(DESTDIR)$(oldfontdir); \ ++ rmdir $(DESTDIR)$(datasubdir); \ ++ fi ++ if test -d $(DESTDIR)$(dataprogramdir); then \ ++ if test -h $(DESTDIR)$(dataprogramdir)/current; then \ ++ rm -f $(DESTDIR)$(dataprogramdir)/current; \ ++ fi; \ ++ if test -d $(DESTDIR)$(localfontdir); then \ ++ rm -f $(DESTDIR)$(localfontdir)/*; \ ++ rmdir $(DESTDIR)$(localfontdir); \ ++ fi; \ ++ rmdir $(DESTDIR)$(dataprogramdir); \ ++ fi ++ if test -d $(DESTDIR)$(grog_dir); then \ ++ rmdir $(DESTDIR)$(grog_dir); \ ++ fi ++ if test -d $(DESTDIR)$(libprogramdir); then \ ++ if test -d $(DESTDIR)$(systemtmacdir); then \ ++ rm -f $(DESTDIR)$(systemtmacdir)/*; \ ++ rmdir $(DESTDIR)$(systemtmacdir); \ ++ fi; \ ++ rmdir $(DESTDIR)$(libprogramdir); \ ++ fi ++ if test -d $(DESTDIR)$(docdir); then \ ++ if test -d $(DESTDIR)$(exampledir); then \ ++ rmdir $(DESTDIR)$(exampledir); \ ++ fi; \ ++ if test -d $(DESTDIR)$(htmldocdir); then \ ++ rmdir $(DESTDIR)$(htmldocdir); \ ++ fi; \ ++ rmdir $(DESTDIR)$(docdir); \ ++ fi ++ ++# Uninstall program that have a 'g' prefix ++uninstall-hook: uninstall_binaries_with_prefix ++uninstall_binaries_with_prefix: ++if USEPROGRAMPREFIX ++ if test -n "$(NAMEPREFIX)"; then \ ++ for f in $(prefixexecbin_PROGRAMS) $(prefixexecbin_SCRIPTS); do \ ++ rm -f $(DESTDIR)$(bindir)/$(NAMEPREFIX)$$f$(EXEEXT); \ ++ done; \ ++ fi ++endif ++ ++# Other files that should be present in the distribution tarball. ++EXTRA_DIST += \ ++ BUG-REPORT \ ++ ChangeLog.115 \ ++ ChangeLog.116 \ ++ ChangeLog.117 \ ++ ChangeLog.118 \ ++ ChangeLog.119 \ ++ ChangeLog.120 \ ++ ChangeLog.121 \ ++ FDL \ ++ FOR-RELEASE \ ++ gendef.sh \ ++ INSTALL.REPO \ ++ INSTALL.extra \ ++ INSTALL.gen \ ++ LICENSES \ ++ MANIFEST \ ++ mdate.sh \ ++ MORE.STUFF \ ++ PROBLEMS \ ++ PROJECTS \ ++ README.MinGW \ ++ TESTS \ ++ arch/djgpp \ ++ font/util/make-Rproto ++ ++MOSTLYCLEANFILES += $(prefixexecbin_SCRIPTS) $(bin_SCRIPTS) \ ++ $(man1_MANS) $(man5_MANS) $(man7_MANS) \ ++ $(PREFIXMAN1) $(PREFIXMAN5) $(PREFIXMAN7) \ ++ test-groff ++ ++# Rule to build .man files. The brackets around the @ are used to prevent the ++# substitution of the variable by automake. ++.man.n: ++ @echo Making $@ from $< ++ rm -f $@ ++ $(MKDIR_P) `dirname $@` ++ @LC_ALL=C \ ++ sed -e "s|[@]APPRESDIR[@]|$(appresdir)|g" \ ++ -e "s|[@]BINDIR[@]|$(bindir)|g" \ ++ -e "s|[@]BROKEN_SPOOLER_FLAGS[@]|$(BROKEN_SPOOLER_FLAGS)|g" \ ++ -e "s|[@]COMMON_WORDS_FILE[@]|$(common_words_file)|g" \ ++ -e "s|[@]DATASUBDIR[@]|$(datasubdir)|g" \ ++ -e "s|[@]DEFAULT_INDEX[@]|$(indexdir)/$(indexname)|g" \ ++ -e "s|[@]DEFAULT_INDEX_NAME[@]|$(indexname)|g" \ ++ -e "s|[@]DEVICE[@]|$(DEVICE)|g" \ ++ -e "s|[@]DOCDIR[@]|$(docdir)|g" \ ++ -e "s|[@]EXAMPLEDIR[@]|$(exampledir)|g" \ ++ -e "s|[@]FONTDIR[@]|$(fontdir)|g" \ ++ -e "s|[@]g[@]|$(g)|g" \ ++ -e "s![@]G[@]!`echo $(g) | tr [a-z] [A-Z]`!g" \ ++ -e "s|[@]HTMLDOCDIR[@]|$(htmldocdir)|g" \ ++ -e "s|[@]INDEX_SUFFIX[@]|$(indexext)|g" \ ++ -e "s|[@]LEGACYFONTDIR[@]|$(legacyfontdir)|g" \ ++ -e "s|[@]LOCALFONTDIR[@]|$(localfontdir)|g" \ ++ -e "s|[@]LOCALMACRODIR[@]|$(localtmacdir)|g" \ ++ -e "s|[@]MACRODIR[@]|$(tmacdir)|g" \ ++ -e "s|[@]MAN1EXT[@]|$(man1ext)|g" \ ++ -e "s|[@]MAN5EXT[@]|$(man5ext)|g" \ ++ -e "s|[@]MAN7EXT[@]|$(man7ext)|g" \ ++ -e "s|[@]MDATE[@]|`$(SHELL) $(top_srcdir)/mdate.sh $<`|g" \ ++ -e "s|[@]OLDFONTDIR[@]|$(oldfontdir)|g" \ ++ -e "s|[@]PDFDOCDIR[@]|$(pdfdocdir)|g" \ ++ -e "s|[@]SYSTEMMACRODIR[@]|$(systemtmacdir)|g" \ ++ -e "s|[@]TMAC_AN_PREFIX[@]|$(tmac_an_prefix)|g" \ ++ -e "s|[@]TMAC_M_PREFIX[@]|$(tmac_m_prefix)|g" \ ++ -e "s|[@]TMAC_MDIR[@]|$(tmacdir)/mm|g" \ ++ -e "s|[@]TMAC_S_PREFIX[@]|$(tmac_s_prefix)|g" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|g" \ ++ $< >$@ +diff -Nuar groff-1.22.3.old/Makefile.ccpg groff-1.22.3/Makefile.ccpg +--- groff-1.22.3.old/Makefile.ccpg 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/Makefile.ccpg 1970-01-01 02:00:00.000000000 +0200 +@@ -1,61 +0,0 @@ +-# Copyright (C) 1992-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.ccpg +-# +-MAKEFILEPARTS=\ +- $(top_srcdir)/Makefile.comm \ +- $(top_builddir)/Makefile.cfg \ +- $(srcdir)/Makefile.sub \ +- $(top_srcdir)/Makefile.ccpg \ +- Makefile.dep +- +-all: $(PROG) $(MANPAGES) +- +-$(PROG): $(OBJS) $(XLIBS) +- $(LINK.cpp) -o $@ $(OBJS) $(XLIBS) $(EXTRA_LDFLAGS) $(LIBS) $(MLIB) +- +-install_bin: install_prog +-install_prog: $(PROG) +-install_data: install_man +-install_man: $(MANPAGES) +-uninstall_sub: uninstall_prog uninstall_man +-depend: depend_src +-depend.temp: $(GENSRCS) $(YTABC) +-distfiles: $(YTABC) +-TAGS: TAGS_src +-TAGS_src: $(CCSRCS) $(CSRCS) $(GRAM) $(HDRS) +-Makefile: $(MAKEFILEPARTS) +-Makefile.dep: +- touch Makefile.dep +-$(top_builddir)/stamp-h $(MANPAGES): $(top_srcdir)/VERSION \ +- $(top_srcdir)/REVISION +- +-pure: $(PROG).pure +- +-$(PROG).pure: $(OBJS) $(XLIBS) +- $(PURIFY) $(PURIFYCCFLAGS) \ +- $(LINK.cpp) -o $@ $(OBJS) $(XLIBS) $(LIBS) $(MLIB) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/Makefile.comm groff-1.22.3/Makefile.comm +--- groff-1.22.3.old/Makefile.comm 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/Makefile.comm 1970-01-01 02:00:00.000000000 +0200 +@@ -1,354 +0,0 @@ +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.comm +-# +-INCLUDES=-I. -I$(srcdir) \ +- -I$(top_builddir)/src/include -I$(top_srcdir)/src/include \ +- -I$(top_builddir)/src/libs/gnulib/lib +-ALL_CCFLAGS=$(INCLUDES) $(CCDEFINES) $(CCFLAGS) $(CPPFLAGS) +-COMPILE.cpp=$(CCC) $(ALL_CCFLAGS) -c +-ALL_CFLAGS=$(INCLUDES) $(CDEFINES) $(CFLAGS) $(CPPFLAGS) +-COMPILE.c=$(CC) $(ALL_CFLAGS) -c +-LINK.cpp=$(CCC) $(CCFLAGS) $(LDFLAGS) +-LINK.c=$(CC) $(CFLAGS) $(LDFLAGS) +-LIBGROFF=$(top_builddir)/src/libs/libgroff/libgroff.$(LIBEXT) +-LIBBIB=$(top_builddir)/src/libs/libbib/libbib.$(LIBEXT) +-LIBDRIVER=$(top_builddir)/src/libs/libdriver/libdriver.$(LIBEXT) +-LIBXUTIL=$(top_builddir)/src/libs/libxutil/libxutil.$(LIBEXT) +-LIBGNU=$(top_builddir)/src/libs/gnulib/lib/libgnu.$(LIBEXT) +-MLIB= +-XLIBS= +-YTABH= +-YTABC= +-GRAM= +-LIBCLEAN= +-MOSTLYCLEANADD= +-MOSTLYCLEANDIRADD= +-MOSTLYCLEANNOTSRCDIRADD= +-MOSTLYCLEANFILES=$(MANCLEAN) $(PROG) $(OBJS) $(GENSRCS) $(GENHDRS) \ +- depend.temp core y.output $(MOSTLYCLEANADD) +-CLEANFILES=$(LIBCLEAN) +-DISTCLEANFILES=TAGS Makefile Makefile.dep +-REALCLEANFILES=$(YTABC) $(YTABH) +-NAMEPREFIX= +-HDRS= +-MANPAGES=$(MAN1) $(MAN5) $(MAN7) +-MANCLEAN=$(MANPAGES) +-fontsubdir=$(fontdir)/dev$(DEV) +-oldfontsubdir=$(oldfontdir)/dev$(DEV) +- +-all do_install install_bin install_data TAGS depend distfiles uninstall_sub: +- +-do_install: install_bin install_data +-uninstall: uninstall_sub +-pure: +-fonts: +- +-.PHONY: all clean distclean mostlyclean realclean extraclean depend distfiles +-.PHONY: install install_bin install_data +-.PHONY: uninstall uninstall_sub +-.PHONY: pure fonts +- +-mostlyclean: +- rm -f $(MOSTLYCLEANFILES) +- -rm -rf $(MOSTLYCLEANDIRADD) +- -@if test "`cd $(srcdir); pwd`" != "`pwd`"; then \ +- rm -f $(MOSTLYCLEANNOTSRCDIRADD); \ +- fi +- +-clean: mostlyclean +- rm -f $(CLEANFILES) +- +-distclean: clean +- rm -f $(DISTCLEANFILES) +- -@if test "`cd $(srcdir); pwd`" != "`pwd`"; then \ +- rm -f $(YTABC) $(YTABH); \ +- fi +- +-realclean: distclean +- rm -f $(REALCLEANFILES) +- +-extraclean: distclean +- rm -f \#* *~ =* core junk grot temp tmp tem *.new *.old *.orig +- +-.SUFFIXES: +-.SUFFIXES: .o .obj .cpp .c .y .man .n +- +-.cpp.o: +- $(COMPILE.cpp) $(EXTRA_CCFLAGS) $< +- +-.c.o: +- $(COMPILE.c) $(EXTRA_CFLAGS) $< +- +-.cpp.obj: +- $(COMPILE.cpp) $(EXTRA_CCFLAGS) $< +- +-.c.obj: +- $(COMPILE.c) $(EXTRA_CFLAGS) $< +- +-.y.cpp: +- if test -n "$(YTABH)"; then \ +- $(YACC) $(YACCFLAGS) -d $<; \ +- else \ +- $(YACC) $(YACCFLAGS) $<; \ +- fi +- -test -f y.tab.h && mv y.tab.h y_tab.h +- -test -f y.tab.c && mv y.tab.c y_tab.c +- sed "s/^#line \(.*\) \"y.tab.c\"/#line \1 \"$(YTABC)\"/" \ +- < y_tab.c > $(YTABC) +- rm -f y_tab.c +- test -z "$(YTABH)" || mv y_tab.h $(YTABH) +- +-# The next rule is needed for make of Solaris 2.5.1 to override its +-# built-in .y.o rule (which takes precedence over the .y.cpp rule above). +-.y.o: +- if test -n "$(YTABH)"; then \ +- $(YACC) $(YACCFLAGS) -d $<; \ +- else \ +- $(YACC) $(YACCFLAGS) $<; \ +- fi +- -test -f y.tab.h && mv y.tab.h y_tab.h +- -test -f y.tab.c && mv y.tab.c y_tab.c +- mv y_tab.c $(YTABC) +- test -z "$(YTABH)" || mv y_tab.h $(YTABH) +- $(COMPILE.cpp) $(EXTRA_CCFLAGS) $(YTABC) +- +-.man.n: +- @echo Making $@ from $< +- @rm -f $@ +- @LC_ALL=C \ +- sed -e "s|@APPRESDIR@|$(appresdir)|g" \ +- -e "s|@BINDIR@|$(bindir)|g" \ +- -e "s|@BROKEN_SPOOLER_FLAGS@|$(BROKEN_SPOOLER_FLAGS)|g" \ +- -e "s|@COMMON_WORDS_FILE@|$(common_words_file)|g" \ +- -e "s|@DATASUBDIR@|$(datasubdir)|g" \ +- -e "s|@DEFAULT_INDEX@|$(indexdir)/$(indexname)|g" \ +- -e "s|@DEFAULT_INDEX_NAME@|$(indexname)|g" \ +- -e "s|@DEVICE@|$(DEVICE)|g" \ +- -e "s|@DOCDIR@|$(docdir)|g" \ +- -e "s|@EXAMPLEDIR@|$(exampledir)|g" \ +- -e "s|@FONTDIR@|$(fontdir)|g" \ +- -e "s|@g@|$(g)|g" \ +- -e "s!@G@!`echo $(g) | tr [a-z] [A-Z]`!g" \ +- -e "s|@HTMLDOCDIR@|$(htmldocdir)|g" \ +- -e "s|@INDEX_SUFFIX@|$(indexext)|g" \ +- -e "s|@LEGACYFONTDIR@|$(legacyfontdir)|g" \ +- -e "s|@LOCALFONTDIR@|$(localfontdir)|g" \ +- -e "s|@LOCALMACRODIR@|$(localtmacdir)|g" \ +- -e "s|@MACRODIR@|$(tmacdir)|g" \ +- -e "s|@MAN1EXT@|$(man1ext)|g" \ +- -e "s|@MAN5EXT@|$(man5ext)|g" \ +- -e "s|@MAN7EXT@|$(man7ext)|g" \ +- -e "s|@MDATE@|`$(SHELL) $(top_srcdir)/mdate.sh $<`|g" \ +- -e "s|@OLDFONTDIR@|$(oldfontdir)|g" \ +- -e "s|@PDFDOCDIR@|$(pdfdocdir)|g" \ +- -e "s|@SYSTEMMACRODIR@|$(systemtmacdir)|g" \ +- -e "s|@TMAC_AN_PREFIX@|$(tmac_an_prefix)|g" \ +- -e "s|@TMAC_M_PREFIX@|$(tmac_m_prefix)|g" \ +- -e "s|@TMAC_MDIR@|$(tmacdir)/mm|g" \ +- -e "s|@TMAC_S_PREFIX@|$(tmac_s_prefix)|g" \ +- -e "s|@VERSION@|$(version)$(revision)|g" \ +- $< >$@ +- +-.PHONY: install_man +-install_man: +- -test -d $(DESTDIR)$(manroot) || $(mkinstalldirs) $(DESTDIR)$(manroot) +- -test -d $(DESTDIR)$(man1dir) || $(mkinstalldirs) $(DESTDIR)$(man1dir) +- @-pages="$(MAN1)"; \ +- for p in $$pages; do \ +- prog=`basename $$p .n`; \ +- target=$(DESTDIR)$(man1dir)/$(NAMEPREFIX)$$prog.$(man1ext); \ +- rm -f $$target; \ +- echo $(INSTALL_DATA) $$p $$target; \ +- $(INSTALL_DATA) $$p $$target; \ +- done +- -test -d $(DESTDIR)$(man5dir) || $(mkinstalldirs) $(DESTDIR)$(man5dir) +- @-pages="$(MAN5)"; \ +- for p in $$pages; do \ +- target=$(DESTDIR)$(man5dir)/`basename $$p .n`.$(man5ext); \ +- rm -f $$target; \ +- echo $(INSTALL_DATA) $$p $$target; \ +- $(INSTALL_DATA) $$p $$target; \ +- done +- -test -d $(DESTDIR)$(man7dir) || $(mkinstalldirs) $(DESTDIR)$(man7dir) +- @-pages="$(MAN7)"; \ +- for p in $$pages; do \ +- target=$(DESTDIR)$(man7dir)/`basename $$p .n`.$(man7ext); \ +- rm -f $$target; \ +- echo $(INSTALL_DATA) $$p $$target; \ +- $(INSTALL_DATA) $$p $$target; \ +- done +- +-.PHONY: uninstall_man +-uninstall_man: +- @-pages="$(MAN1)"; \ +- for p in $$pages; do \ +- target=$(DESTDIR)$(man1dir)/$(NAMEPREFIX); \ +- target=$$target`basename $$p .n`.$(man1ext); \ +- echo rm -f $$target; \ +- rm -f $$target; \ +- done +- @-pages="$(MAN5)"; \ +- for p in $$pages; do \ +- target=$(DESTDIR)$(man5dir)/`basename $$p .n`.$(man5ext); \ +- echo rm -f $$target; \ +- rm -f $$target; \ +- done +- @-pages="$(MAN7)"; \ +- for p in $$pages; do \ +- target=$(DESTDIR)$(man7dir)/`basename $$p .n`.$(man7ext); \ +- echo rm -f $$target; \ +- rm -f $$target; \ +- done +- +-.PHONY: install_prog +-install_prog: +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- rm -f $(DESTDIR)$(bindir)/$(NAMEPREFIX)$(PROG) +- $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(bindir)/$(NAMEPREFIX)$(PROG) +- +-.PHONY: uninstall_prog +-uninstall_prog: +- rm -f $(DESTDIR)$(bindir)/$(NAMEPREFIX)$(PROG) +- +-.PHONY: install_dev +-install_dev: +- -test -d $(DESTDIR)$(datadir) \ +- || $(mkinstalldirs) $(DESTDIR)$(datadir) +- -test -d $(DESTDIR)$(dataprogramdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(dataprogramdir) +- -test -d $(DESTDIR)$(datasubdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(datasubdir) +- -test -d $(DESTDIR)$(fontdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(fontdir) +- -test -d $(DESTDIR)$(fontsubdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(fontsubdir) +- -if test -d $(srcdir)/generate; then \ +- test -d $(DESTDIR)$(fontsubdir)/generate \ +- || $(mkinstalldirs) $(DESTDIR)$(fontsubdir)/generate; \ +- fi +- -if test -d $(srcdir)/enc; then \ +- test -d $(DESTDIR)$(fontsubdir)/enc \ +- || $(mkinstalldirs) $(DESTDIR)$(fontsubdir)/enc; \ +- fi +- -if test -d $(srcdir)/map; then \ +- test -d $(DESTDIR)$(fontsubdir)/map \ +- || $(mkinstalldirs) $(DESTDIR)$(fontsubdir)/map; \ +- fi +- -if test -d $(srcdir)/util; then \ +- test -d $(DESTDIR)$(fontsubdir)/util \ +- || $(mkinstalldirs) $(DESTDIR)$(fontsubdir)/util; \ +- fi +- -if test -d $(srcdir)/old; then \ +- test -d $(DESTDIR)$(oldfontdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(oldfontdir); \ +- test -d $(DESTDIR)$(oldfontsubdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(oldfontsubdir); \ +- fi +- -test -z "$(DEVFILES)" \ +- || for f in ""$(DEVFILES); do \ +- rm -f $(DESTDIR)$(fontsubdir)/$$f; \ +- if test -f $$f; then \ +- $(INSTALL_DATA) $$f $(DESTDIR)$(fontsubdir)/$$f; \ +- else \ +- $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(fontsubdir)/$$f; \ +- fi; \ +- done +- -test -z "$(OLDDEVFILES)" \ +- || for f in ""$(OLDDEVFILES); do \ +- rm -f $(DESTDIR)$(oldfontsubdir)/$$f; \ +- $(INSTALL_DATA) $(srcdir)/old/$$f \ +- $(DESTDIR)$(oldfontsubdir)/$$f; \ +- done +- -test -z "$(DEVSCRIPTS)" \ +- || for f in ""$(DEVSCRIPTS); do \ +- rm -f $(DESTDIR)$(fontsubdir)/$$f; \ +- if test -f $$f; then \ +- $(INSTALL_SCRIPT) $$f $(DESTDIR)$(fontsubdir)/$$f; \ +- else \ +- $(INSTALL_SCRIPT) $(srcdir)/$$f $(DESTDIR)$(fontsubdir)/$$f; \ +- fi; \ +- done +- +-.PHONY: uninstall_dev +-uninstall_dev: +- -test -z "$(DEVFILES)$(DEVSCRIPTS)" \ +- || for f in ""$(DEVFILES) $(DEVSCRIPTS); do \ +- rm -f $(DESTDIR)$(fontsubdir)/$$f; \ +- done +- -test -z "$(OLDDEVFILES)" \ +- || for f in ""$(OLDDEVFILES); do \ +- rm -f $(DESTDIR)$(oldfontsubdir)/$$f; \ +- done +- -d=$(DESTDIR)$(fontsubdir)/generate;\ +- if test -d $$d; then rmdir $$d; fi +- -d=$(DESTDIR)$(fontsubdir)/enc;\ +- if test -d $$d; then rmdir $$d; fi +- -d=$(DESTDIR)$(fontsubdir)/map;\ +- if test -d $$d; then rmdir $$d; fi +- -d=$(DESTDIR)$(fontsubdir)/util;\ +- if test -d $$d; then rmdir $$d; fi +- -test -d $(DESTDIR)$(fontsubdir) $$ \ +- rmdir $(DESTDIR)$(fontsubdir) +- -d=$(DESTDIR)$(oldfontsubdir);\ +- if test -d $$d; then rmdir $$d; fi +- +-.PHONY: depend_src +-depend_src: depend.temp +- mv depend.temp Makefile.dep +- +-depend.temp: FORCE +- > depend.temp +- if test -f "$(srcdir)/$(YTABC)"; then \ +- ytabc="$(srcdir)/$(YTABC)"; \ +- else \ +- ytabc="$(YTABC)"; \ +- fi; \ +- test -z "$(CCSRCS)$(YTABC)" \ +- || $(CCC) $(ALL_CCFLAGS) $(EXTRA_CCFLAGS) -MM $(CCSRCS) $$ytabc \ +- >>depend.temp +- test -z "$(CSRCS)" \ +- || $(CC) $(ALL_CFLAGS) $(EXTRA_CFLAGS) -MM $(CSRCS) >>depend.temp +- test -z "$(YTABH)" \ +- || (sed -e 's|$(YTABH)|$(YTABC)|g' depend.temp >depend1.temp; \ +- mv depend1.temp depend.temp) +- +-.PHONY: TAGS_src +-TAGS_src: +- $(ETAGS) $(ETAGSFLAGS) $(CCSRCS) $(CSRCS) +- test -z "$(GRAM)$(HDRS)" \ +- || $(ETAGS) $(ETAGSFLAGS) -a $(ETAGSCCFLAG) $(GRAM) $(HDRS) +- +-# This rule is only considered for the subdir_Makefile target. +-Makefile: +- echo srcdir=$(srcdir) >Makefile +- echo VPATH=$(VPATH) >>Makefile +- cat $(MAKEFILEPARTS) /dev/null >>Makefile +- +-FORCE: +- +-.NOEXPORT: +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/Makefile.cpg groff-1.22.3/Makefile.cpg +--- groff-1.22.3.old/Makefile.cpg 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/Makefile.cpg 1970-01-01 02:00:00.000000000 +0200 +@@ -1,55 +0,0 @@ +-# Copyright (C) 1992-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.cpg +-# +-MAKEFILEPARTS=\ +- $(top_srcdir)/Makefile.comm \ +- $(top_builddir)/Makefile.cfg \ +- $(srcdir)/Makefile.sub \ +- $(top_srcdir)/Makefile.cpg \ +- Makefile.dep +- +-all: $(PROG) $(MANPAGES) +- +-$(PROG): $(OBJS) $(XLIBS) +- $(LINK.c) -o $@ $(OBJS) $(XLIBS) $(EXTRA_LDFLAGS) $(LIBS) $(MLIB) +- +-install_bin: install_prog +-install_prog: $(PROG) +-install_data: install_man +-install_man: $(MANPAGES) +-uninstall_sub: uninstall_prog uninstall_man +-depend: depend_src +-depend.temp: $(GENSRCS) $(YTABC) +-distfiles: $(YTABC) +-TAGS: TAGS_src +-TAGS_src: $(CCSRCS) $(CSRCS) $(GRAM) $(HDRS) +-Makefile: $(MAKEFILEPARTS) +-Makefile.dep: +- touch Makefile.dep +-$(top_builddir)/stamp-h $(MANPAGES): $(top_srcdir)/VERSION \ +- $(top_srcdir)/REVISION +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/Makefile.dev groff-1.22.3/Makefile.dev +--- groff-1.22.3.old/Makefile.dev 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/Makefile.dev 1970-01-01 02:00:00.000000000 +0200 +@@ -1,32 +0,0 @@ +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.dev +-# +-all: $(DEVFILES) $(DEVSCRIPTS) +-install_data: install_dev +-uninstall_sub: uninstall_dev +-install_dev: $(DEVFILES) $(DEVSCRIPTS) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/Makefile.in groff-1.22.3/Makefile.in +--- groff-1.22.3.old/Makefile.in 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/Makefile.in 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1066 +0,0 @@ +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.in +-# +-SHELL=@SHELL@ +- +-PACKAGE_TARNAME=@PACKAGE_TARNAME@ +- +-srcdir=@srcdir@ +-top_srcdir=@abs_top_srcdir@ +-VPATH=@srcdir@ +-top_builddir=@abs_top_builddir@ +- +-# `HOST' is the canonical host specification, +-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +-# or +-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +-HOST=@host@ +- +-# `RT_SEP' is the operating system's native PATH SEPARATOR CHAR, which +-# is to be used in runtime PATHs compiled into groff executables. +-RT_SEP=@GROFF_PATH_SEPARATOR@ +- +-# `SH_SEP' is a alternative PATH SEPARATOR CHAR, to be used in shell +-# scripts and makefile rules; it may be the same as `RT_SEP', but, +-# particularly in some Microsoft environments, it may differ. +-SH_SEP=@PATH_SEPARATOR@ +- +-# `GLIBC21' is yes if the host operating system uses GNU libc 2.1 or newer, +-# otherwise no. +-GLIBC21=@GLIBC21@ +- +-version=`cat $(top_srcdir)/VERSION` +-# No additional number if revision is zero. +-revision=`sed -e 's/^0$$//' -e 's/^[1-9].*$$/.&/' $(top_srcdir)/REVISION` +- +-# Define `page' to be letter if your PostScript printer uses 8.5x11 +-# paper (USA) and define it to be A4, if it uses A4 paper (rest of the +-# world). +-PAGE=@PAGE@ +- +-# The name of the ghostscript program. Normally, gs, on GNU/Linux +-# but it might be different on MS-DOS/MS-WIN32 systems. +-GHOSTSCRIPT=@GHOSTSCRIPT@ +- +-# `ALT_GHOSTSCRIPT_PROGS' specifies a list alternative names, +-# which can be tried if `GHOSTSCRIPT' cannot be found at run time. +-ALT_GHOSTSCRIPT_PROGS=@ALT_GHOSTSCRIPT_PROGS@ +- +-# Similarly, `ALT_AWK_PROGS' specifies a list of alternative names, +-# which can be tried at run time, to identify the awk program. +-ALT_AWK_PROGS=@ALT_AWK_PROGS@ +- +-# Normally the Postscript driver, grops, produces output that conforms +-# to version 3.0 of the Adobe Document Structuring Conventions. +-# Unfortunately some spoolers and previewers can't handle such output. +-# The BROKEN_SPOOLER_FLAGS variable tells grops what it should do to +-# make its output acceptable to such programs. This variable controls +-# only the default behaviour of grops; the behaviour can be changed at +-# runtime by the grops -b option (and so by groff -P-b). +-# Use a value of 0 if your spoolers and previewers are able to handle +-# conforming PostScript correctly. +-# Add 1 if no %%{Begin,End}DocumentSetup comments should be generated; +-# this is needed for early versions of TranScript that get confused by +-# anything between the %%EndProlog line and the first %%Page: comment. +-# Add 2 if lines in included files beginning with %! should be +-# stripped out; this is needed for the OpenWindows 2.0 pageview previewer. +-# Add 4 if %%Page, %%Trailer and %%EndProlog comments should be +-# stripped out of included files; this is needed for spoolers that +-# don't understand the %%{Begin,End}Document comments. I suspect this +-# includes early versions of TranScript. +-# Add 8 if the first line of the PostScript output should be %!PS-Adobe-2.0 +-# rather than %!PS-Adobe-3.0; this is needed when using Sun's Newsprint +-# with a printer that requires page reversal. +-BROKEN_SPOOLER_FLAGS=@BROKEN_SPOOLER_FLAGS@ +- +-# `DEVICE' is the default device. +-DEVICE=ps +- +-# `XDEVDIRS' is either `font/devX{75,100}{,-12}' or empty. +-XDEVDIRS=@XDEVDIRS@ +- +-# `XPROGDIRS' is either `src/devices/xditview src/utils/xtotroff' or empty. +-XPROGDIRS=@XPROGDIRS@ +- +-# `XLIBDIRS' is either `src/libs/libxutil' or empty. +-XLIBDIRS=@XLIBDIRS@ +- +-# `TTYDEVDIRS' is either `font/devascii font/devlatin1' (for +-# ASCII) or `font/devcp1047' (for EBCDIC) plus font/devutf8. +-TTYDEVDIRS=@TTYDEVDIRS@ font/devutf8 +- +-# `OTHERDEVDIRS' is either `font/devlj4 font/devlbp' (for ASCII) or +-# empty (for EBCDIC). +-OTHERDEVDIRS=@OTHERDEVDIRS@ +- +-# `PSPRINT' is the command to use for printing a PostScript file, +-# for example `lpr'. +-PSPRINT=@PSPRINT@ +- +-# `DVIPRINT' is the command to use for printing a TeX dvi file, +-# for example `lpr -d'. +-DVIPRINT=@DVIPRINT@ +- +-# Prefix for names of programs that have Unix counterparts. +-# For example, if `g' is `g' then troff will be installed as +-# gtroff. This doesn't affect programs like grops or groff that have +-# no Unix counterparts. Note that the groff versions of eqn and tbl +-# will not work with Unix troff. +-g=@g@ +- +-# Common prefix for installation directories. +-# Used in definitions of exec_prefix, datasubdir, fontpath, manroot. +-# This must already exist when you do make install. +-prefix=@prefix@ +-exec_prefix=@exec_prefix@ +- +-# `bindir' says where to install executables. +-bindir=@bindir@ +- +-# `libdir' says where to install platform-dependent data. +-libdir=@libdir@ +-libprogramdir=$(libdir)/groff +- +-# `datasubdir' says where to install platform-independent data files. +-datadir=@datadir@ +-datarootdir=@datarootdir@ +-dataprogramdir=$(datadir)/groff +-datasubdir=$(dataprogramdir)/$(version)$(revision) +- +-# `infodir' says where to install info files. +-infodir=@infodir@ +- +-# `docdir' says where to install documentation files. +-docdir=@docdir@ +- +-# `exampledir' says where to install example files. +-exampledir=$(docdir)/examples +- +-# `htmldocdir' says where to install documentation in HTML format. +-htmldocdir=$(docdir)/html +- +-# `pdfdocdir' says where to install documentation in PDF format. +-pdfdocdir=$(docdir)/pdf +- +-# `fontdir' says where to install dev*/*. +-fontdir=$(datasubdir)/font +- +-# `oldfontdir' says where to install old font sets (as dev*/*). +-oldfontdir=$(datasubdir)/oldfont +- +-# `localfontdir' says where local fonts will be installed (as dev*/*). +-localfontdir=$(dataprogramdir)/site-font +- +-# `legacyfontdir' is for compatibility with non-GNU troff. +-legacyfontdir=/usr/lib/font +- +-# `fontpath' says where to look for dev*/*. +-fontpath=$(localfontdir)$(RT_SEP)$(fontdir)$(RT_SEP)$(legacyfontdir) +- +-# `tmacdir' says where to install macros. +-tmacdir=$(datasubdir)/tmac +- +-# `systemtmacdir' says where to install platform-dependent macros. +-systemtmacdir=$(libprogramdir)/site-tmac +- +-# `localtmacdir' says where local files will be installed. +-localtmacdir=$(dataprogramdir)/site-tmac +- +-# `appresdir' says where to install the application resource file for +-# gxditview. +-appresdir=@appresdir@ +- +-glilypond_dir=@glilypond_dir@ +-gpinyin_dir=@gpinyin_dir@ +-groffer_dir=@groffer_dir@ +-grog_dir=@grog_dir@ +-libprogramdir=@libprogramdir@ +-referdir=@referdir@ +- +-# `tmacpath' says where to look for macro files. +-# The current directory will be prepended in unsafe mode only; the home +-# directory will be always added. +-# `troffrc' and `troffrc-end' (and `eqnrc') are searched neither in the +-# current nor in the home directory. +-tmacpath=$(systemtmacdir)$(RT_SEP)$(localtmacdir)$(RT_SEP)$(tmacdir) +- +-# `sys_tmac_prefix' is prefix (if any) for system macro packages. +-sys_tmac_prefix=@sys_tmac_prefix@ +- +-# `pnmtops_nosetpage' is the command to be run to generate an eps +-# file. Some versions of pnmtops provide the -nosetpage option. +-# We detect this and use it if present. +-pnmtops_nosetpage=@pnmtops_nosetpage@ +- +-# `tmac_wrap' is list of system macro packages that should be made +-# available to groff by creating a corresponding macro package +-# in the groff macro directory that references the system macro +-# package. +-tmac_wrap=@tmac_wrap@ +- +-# If there is a groff version of a macro package listed in $(tmac_wrap), +-# then the groff version will be installed with a prefix of this. +-# Don't make this empty. +-tmac_prefix=g +- +-# The groff -mm macros will be available as -m$(tmac_m_prefix)m. +-tmac_m_prefix=\ +- `for i in $(tmac_wrap) ""; do case "$$i" in m) echo $(tmac_prefix);; esac; done` +-# The groff -ms macros will be available as -m$(tmac_s_prefix)s. +-tmac_s_prefix=\ +- `for i in $(tmac_wrap) ""; do case "$$i" in s) echo $(tmac_prefix);; esac; done` +-# The groff -man macros will be available as -m$(tmac_an_prefix)an. +-tmac_an_prefix=\ +- `for i in $(tmac_wrap) ""; do case "$$i" in an) echo $(tmac_prefix);; esac; done` +- +-# Extension to be used for refer index files. Index files are not +-# sharable between different architectures, so you might want to use +-# different suffixes for different architectures. Choose an extension +-# that doesn't conflict with refer or any other indexing program. +-indexext=.i +- +-# Directory containing the default index for refer. +-indexdir=/usr/dict/papers +- +-# The filename (without suffix) of the default index for refer. +-indexname=Ind +- +-# common_words_file is a file containing a list of common words. +-# If your system provides /usr/lib/eign it will be copied onto this, +-# otherwise the supplied eign file will be used. +-common_words_file=$(datasubdir)/eign +- +-# `manroot' is the root of the man page directory tree. +-mandir=@mandir@ +-manroot=$(mandir) +- +-# `man1ext' is the man section for user commands. +-man1ext=1 +-man1dir=$(manroot)/man$(man1ext) +- +-# `man5ext' is the man section for file formats. +-man5ext=5 +-man5dir=$(manroot)/man$(man5ext) +- +-# `man7ext' is the man section for macros. +-man7ext=7 +-man7dir=$(manroot)/man$(man7ext) +- +-# `dist' target is disallowed in some `configure' combinations. +-doc_dist_target_ok=@doc_dist_target_ok@ +- +-# The configure script checks whether the user wants the info documentation. +-# For the repo version this mechanism also suppresses building via `makeinfo'. +-make_infodoc=@make_infodoc@ +-make_install_infodoc=@make_install_infodoc@ +-make_uninstall_infodoc=@make_uninstall_infodoc@ +- +-# The configure script checks whether all necessary utility programs for +-# grohtml are available -- only then we can build the HTML documentation. +-make_htmldoc=@make_htmldoc@ +-make_install_htmldoc=@make_install_htmldoc@ +-make_uninstall_htmldoc=@make_uninstall_htmldoc@ +- +-make_htmlexamples=@make_htmlexamples@ +-make_install_htmlexamples=@make_install_htmlexamples@ +-make_uninstall_htmlexamples=@make_uninstall_htmlexamples@ +- +-# However, there may always be some prebuild HTML documentation +-make_install_shipped_htmldoc=@make_install_shipped_htmldoc@ +-make_uninstall_shipped_htmldoc=@make_uninstall_shipped_htmldoc@ +- +-# The configure script also checks whether all necessary utility programs +-# for pdfroff are available -- only then we can build PDF documentation. +-make_pdfdoc=@make_pdfdoc@ +-make_install_pdfdoc=@make_install_pdfdoc@ +-make_uninstall_pdfdoc=@make_uninstall_pdfdoc@ +- +-make_pdfexamples=@make_pdfexamples@ +-make_install_pdfexamples=@make_install_pdfexamples@ +-make_uninstall_pdfexamples=@make_uninstall_pdfexamples@ +- +-# `other' documentation, e.g., `meref.me' and `pic.ms', as well as their +-# generated counterparts.. +-make_otherdoc=@make_otherdoc@ +-make_install_otherdoc=@make_install_otherdoc@ +-make_uninstall_otherdoc=@make_uninstall_otherdoc@ +- +-# `examples' -- a generic switch, but the generated examples are furtherly +-# subdivided to catch HTML and PDF production availability. +-make_examples=@make_examples@ +-make_install_examples=@make_install_examples@ +-make_uninstall_examples=@make_uninstall_examples@ +- +-# Windows `.cmd' files +-make_winscripts=@make_winscripts@ +-make_install_winscripts=@make_install_winscripts@ +-make_uninstall_winscripts=@make_uninstall_winscripts@ +- +-# All the previous installation directories, when used, are prefixed with +-# $(DESTDIR) during install and uninstall, to support staged installations. +- +-# DEFINES should include the following: +-# +-# -DWORDS_BIGENDIAN if your target platform is big-endian +-# -DIS_EBCDIC_HOST if the host's encoding is EBCDIC +-# +-# -DHAVE_DIRECT_H if you have +-# -DHAVE_DIRENT_H if you have +-# -DHAVE_CC_INTTYPES_H if you have a C++ +-# -DHAVE_PROCESS_H if you have +-# -DHAVE_LIMITS_H if you have +-# -DHAVE_CC_LIMITS_H if you have a C++ +-# -DHAVE_MATH_H if you have +-# -DHAVE_CC_OSFCN_H if you have a C++ +-# -DHAVE_STDDEF_H if you have +-# -DHAVE_STDLIB_H if you have +-# -DHAVE_STRING_H if you have +-# -DHAVE_STRINGS_H if you have +-# -DHAVE_SYS_DIR_H if you have +-# -DHAVE_SYS_PARAM_H if you have +-# -DHAVE_SYS_STAT_H if you have +-# -DHAVE_SYS_TIME_H if you have +-# -DHAVE_SYS_TYPES_H if you have +-# -DHAVE_UNISTD_H if you have +-# +-# -DHAVE_FMOD if you have fmod() +-# -DHAVE_GETCWD if you have getcwd() +-# -DHAVE_GETTIMEOFDAY if you have gettimeofday() +-# -DHAVE_ICONV if you have iconv() +-# -DHAVE_ISATTY if you have isatty() +-# -DHAVE_KILL if you have kill() +-# -DHAVE_LANGINFO_CODESET if you have nl_langinfo() +-# -DHAVE_MKSTEMP if you have mkstemp() +-# -DHAVE_MMAP if you have mmap() +-# -DHAVE_PUTENV if you have putenv() +-# -DHAVE_RENAME if you have rename() +-# -DHAVE_SETLOCALE if you have setlocale() +-# -DHAVE_SNPRINTF if you have snprintf() +-# -DHAVE_STRCASECMP if you have strcasecmp() +-# -DHAVE_STRNCASECMP if you have strncasecmp() +-# -DHAVE_STRERROR if you have strerror() +-# -DHAVE_STRSEP if you have strsep() +-# -DHAVE_STRTOL if you have strtol() +-# -DHAVE_SYMLINK if you have symlink() +-# -DHAVE_VSNPRINTF if you have vsnprintf() +-# +-# -DNEED_DECLARATION_GETTIMEOFTODAY +-# if your C++ doesn't declare +-# gettimeofday() +-# -DNEED_DECLARATION_HYPOT if your C++ doesn't declare hypot() +-# -DNEED_DECLARATION_PCLOSE if your C++ doesn't declare pclose() +-# -DNEED_DECLARATION_POPEN if your C++ doesn't declare popen() +-# -DNEED_DECLARATION_PUTENV if your C++ doesn't declare +-# putenv() +-# -DNEED_DECLARATION_RAND if your C++ doesn't declare rand() +-# -DNEED_DECLARATION_SNPRINTF if your C++ doesn't declare +-# snprintf() +-# -DNEED_DECLARATION_SRAND if your C++ doesn't declare srand() +-# -DNEED_DECLARATION_STRCASECMP if your C++ doesn't declare +-# strcasecmp() +-# -DNEED_DECLARATION_STRNCASECMP +-# if your C++ doesn't declare +-# strncasecmp() +-# -DNEED_DECLARATION_VFPRINTF if your C++ doesn't declare +-# vfprintf() +-# -DNEED_DECLARATION_VSNPRINTF if your C++ doesn't declare +-# vsnprintf() +-# +-# -DHAVE_DECL_GETC_UNLOCKED if you have getc_unlocked() +-# -DHAVE_DECL_SYS_SIGLIST if you have sys_siglist[] +-# +-# -DHAVE_STRUCT_EXCEPTION if defines struct exception +-# -DHAVE_SYS_NERR if you have sysnerr in or +-# -DHAVE_SYS_ERRLIST if you have sys_errlist in or +-# +-# -DICONV_CONST=const if declaration of iconv() needs const +-# -DLONG_FOR_TIME_T if localtime() takes a long * not a time_t * +-# -DRETSIGTYPE=int if signal handlers return int not void +-# -DRET_TYPE_SRAND_IS_VOID if srand() returns void not int +-# +-# -DWCOREFLAG=0200 if the 0200 bit of the status returned by +-# wait() indicates whether a core image was +-# produced for a process that was terminated +-# by a signal +-# +-# -DHAVE_WORKING_O_NOATIME define if 's O_NOATIME flag works +-# -DHAVE_WORKING_O_NOFOLLOW define if 's O_NOFOLLOW flag works +-# +-# -Duintmax_t= define to `unsigned long' or `unsigned long +-# long' if does not exist +-# +-# -DTRADITIONAL_CPP if your C++ compiler uses a traditional +-# (Reiser) preprocessor +-# -DARRAY_DELETE_NEEDS_SIZE if your C++ doesn't understand `delete []' +-# +-# -DPAGE=A4 if the the printer's page size is A4 +-# -DGHOSTSCRIPT=gs the name (and directory if required) of the +-# ghostscript program +-# +-DEFINES=@DEFS@ +- +-# Include +-# +-# {fmod,getcwd,mkstemp,putenv,snprintf,strcasecmp, +-# strerror,strncasecmp,strtol}.$(OBJEXT) +-# +-# in LIBOBJS if your C library is missing the corresponding function. +-# vsnprintf is defined in the snprintf.$(OBJEXT) module. +-LIBOBJS=@LIBOBJS@ +- +-# `CCC' is the compiler for C++ (.cpp) files. +-CCC=@CXX@ +-CC=@CC@ +-# CCDEFINES are definitions for C++ compilations. +-CCDEFINES=$(DEFINES) +-# CDEFINES are definitions for C compilations. +-CDEFINES=$(DEFINES) +- +-CCFLAGS=@CXXFLAGS@ +-CFLAGS=@CFLAGS@ +-CPPFLAGS=@CPPFLAGS@ +-LDFLAGS=@LDFLAGS@ +- +-X_CFLAGS=@X_CFLAGS@ +-X_LIBS=@X_LIBS@ +-X_EXTRA_LIBS=@X_EXTRA_LIBS@ +-X_PRE_LIBS=@X_PRE_LIBS@ +- +-YACC=@YACC@ +-YACCFLAGS=-v +- +-GREP=@GREP@ +-EGREP=@EGREP@ +- +-MAKEINFO=@MAKEINFO@ +- +-EXEEXT=@EXEEXT@ +-OBJEXT=@OBJEXT@ +-LIBEXT=@LIBEXT@ +-LIBS=@LIBS@ +-LIBM=@LIBM@ +-LIBICONV=@LIBICONV@ +-RANLIB=@RANLIB@ +-INSTALL=@INSTALL@ +-INSTALL_PROGRAM=@INSTALL_PROGRAM@ +-INSTALL_SCRIPT=@INSTALL_SCRIPT@ +-INSTALL_DATA=@INSTALL_DATA@ +-INSTALL_INFO=@INSTALL_INFO@ +-LN_S=@LN_S@ +-AR=ar +-ETAGS=etags +-ETAGSFLAGS= +-# Flag that tells etags to assume C++. +-ETAGSCCFLAG=-C +-# Full path to perl. +-PERL=@PERL@ +-PERLVERSION=@PERLVERSION@ +-# Sed command with which to edit sh scripts. +-SH_SCRIPT_SED_CMD=@SH_SCRIPT_SED_CMD@ +-# Sed script to deal with OS dependencies in sh scripts. +-SH_DEPS_SED_SCRIPT=$(top_builddir)/arch/misc/shdeps.sed +- +-# The program to create directory hierarchies. +-mkinstalldirs= $(SHELL) $(top_srcdir)/mkinstalldirs +- +-PURIFY=purify +-PURIFYCCFLAGS= +-#PURIFYCCFLAGS=-g++=yes \ +-# -collector=`dirname \`$(CCC) -print-libgcc-file-name\``/ld +- +-# Passing down MAKEOVERRIDES prevents $(MAKE) from containing a second +-# copy of $(MDEFINES) when making individual directories; this could +-# cause the argument list to become too long on some systems. +-MDEFINES=\ +- "ALT_AWK_PROGS=$(ALT_AWK_PROGS)" \ +- "ALT_GHOSTSCRIPT_PROGS=$(ALT_GHOSTSCRIPT_PROGS)" \ +- "AR=$(AR)" \ +- "BROKEN_SPOOLER_FLAGS=$(BROKEN_SPOOLER_FLAGS)" \ +- "CC=$(CC)" \ +- "CCC=$(CCC)" \ +- "CCDEFINES=$(CCDEFINES)" \ +- "CCFLAGS=$(CCFLAGS)" \ +- "CDEFINES=$(CDEFINES)" \ +- "CFLAGS=$(CFLAGS)" \ +- "CPPFLAGS=$(CPPFLAGS)" \ +- "DEVICE=$(DEVICE)" \ +- "DVIPRINT=$(DVIPRINT)" \ +- "EGREP=$(EGREP)" \ +- "ETAGS=$(ETAGS)" \ +- "ETAGSCCFLAG=$(ETAGSCCFLAG)" \ +- "ETAGSFLAGS=$(ETAGSFLAGS)" \ +- "EXEEXT=$(EXEEXT)" \ +- "GLIBC21=$(GLIBC21)" \ +- "GREP=$(GREP)" \ +- "HOST=$(HOST)" \ +- "INSTALL_DATA=$(INSTALL_DATA)" \ +- "INSTALL_INFO=$(INSTALL_INFO)" \ +- "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ +- "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ +- "LDFLAGS=$(LDFLAGS)" \ +- "LIBEXT=$(LIBEXT)" \ +- "LIBICONV=$(LIBICONV)" \ +- "LIBM=$(LIBM)" \ +- "LIBOBJS=$(LIBOBJS)" \ +- "LIBS=$(LIBS)" \ +- "MAKEINFO=$(MAKEINFO)" \ +- "MAKEOVERRIDES=$(MAKEOVERRIDES)" \ +- "OBJEXT=$(OBJEXT)" \ +- "OTHERDEVDIRS=$(OTHERDEVDIRS)" \ +- "PAGE=$(PAGE)" \ +- "PERL=$(PERL)" \ +- "PERLVERSION=$(PERLVERSION)" \ +- "GHOSTSCRIPT=$(GHOSTSCRIPT)" \ +- "PSPRINT=$(PSPRINT)" \ +- "PURIFY=$(PURIFY)" \ +- "PURIFYCCFLAGS=$(PURIFYCCFLAGS)" \ +- "RANLIB=$(RANLIB)" \ +- "RT_SEP=$(RT_SEP)" \ +- "SH_SEP=$(SH_SEP)" \ +- "SHELL=$(SHELL)" \ +- "SH_SCRIPT_SED_CMD=$(SH_SCRIPT_SED_CMD)" \ +- "SH_DEPS_SED_SCRIPT=$(SH_DEPS_SED_SCRIPT)" \ +- "TTYDEVDIRS=$(TTYDEVDIRS)" \ +- "XDEVDIRS=$(XDEVDIRS)" \ +- "XLIBDIRS=$(XLIBDIRS)" \ +- "XPROGDIRS=$(XPROGDIRS)" \ +- "X_CFLAGS=$(X_CFLAGS)" \ +- "X_LIBS=$(X_LIBS)" \ +- "X_EXTRA_LIBS=$(X_EXTRA_LIBS)" \ +- "X_PRE_LIBS=$(X_PRE_LIBS)" \ +- "YACC=$(YACC)" \ +- "YACCFLAGS=$(YACCFLAGS)" \ +- "appresdir=$(appresdir)" \ +- "groffer_dir=$(groffer_dir)" \ +- "gpinyin_dir=$(gpinyin_dir)" \ +- "glilypond_dir=$(glilypond_dir)" \ +- "grog_dir=$(grog_dir)" \ +- "referdir=$(referdir)" \ +- "bindir=$(bindir)" \ +- "common_words_file=$(common_words_file)" \ +- "datadir=$(datadir)" \ +- "dataprogramdir=$(dataprogramdir)" \ +- "datasubdir=$(datasubdir)" \ +- "docdir=$(docdir)" \ +- "exampledir=$(exampledir)" \ +- "exec_prefix=$(exec_prefix)" \ +- "fontdir=$(fontdir)" \ +- "fontpath=$(fontpath)" \ +- "g=$(g)" \ +- "htmldocdir=$(htmldocdir)" \ +- "pdfdocdir=$(pdfdocdir)" \ +- "indexdir=$(indexdir)" \ +- "indexext=$(indexext)" \ +- "indexname=$(indexname)" \ +- "infodir=$(infodir)" \ +- "legacyfontdir=$(legacyfontdir)" \ +- "libdir=$(libdir)" \ +- "libprogramdir=$(libprogramdir)" \ +- "localfontdir=$(localfontdir)" \ +- "localtmacdir=$(localtmacdir)" \ +- "make_infodoc=$(make_infodoc)" \ +- "make_install_infodoc=$(make_install_infodoc)" \ +- "make_uninstall_infodoc=$(make_uninstall_infodoc)" \ +- "make_htmldoc=$(make_htmldoc)" \ +- "make_install_htmldoc=$(make_install_htmldoc)" \ +- "make_uninstall_htmldoc=$(make_uninstall_htmldoc)" \ +- "make_htmlexamples=$(make_htmlexamples)" \ +- "make_install_htmlexamples=$(make_install_htmlexamples)" \ +- "make_uninstall_htmlexamples=$(make_uninstall_htmlexamples)" \ +- "make_install_shipped_htmldoc=$(make_install_shipped_htmldoc)" \ +- "make_uninstall_shipped_htmldoc=$(make_uninstall_shipped_htmldoc)" \ +- "make_pdfdoc=$(make_pdfdoc)" \ +- "make_install_pdfdoc=$(make_install_pdfdoc)" \ +- "make_uninstall_pdfdoc=$(make_uninstall_pdfdoc)" \ +- "make_pdfexamples=$(make_pdfexamples)" \ +- "make_install_pdfexamples=$(make_install_pdfexamples)" \ +- "make_uninstall_pdfexamples=$(make_uninstall_pdfexamples)" \ +- "make_otherdoc=$(make_otherdoc)" \ +- "make_install_otherdoc=$(make_install_otherdoc)" \ +- "make_uninstall_otherdoc=$(make_uninstall_otherdoc)" \ +- "make_examples=$(make_examples)" \ +- "make_install_examples=$(make_install_examples)" \ +- "make_uninstall_examples=$(make_uninstall_examples)" \ +- "make_winscripts=$(make_winscripts)" \ +- "make_install_winscripts=$(make_install_winscripts)" \ +- "make_uninstall_winscripts=$(make_uninstall_winscripts)" \ +- "man1dir=$(man1dir)" \ +- "man1ext=$(man1ext)" \ +- "man5dir=$(man5dir)" \ +- "man5ext=$(man5ext)" \ +- "man7dir=$(man7dir)" \ +- "man7ext=$(man7ext)" \ +- "manroot=$(manroot)" \ +- "mkinstalldirs=$(mkinstalldirs)" \ +- "oldfontdir=$(oldfontdir)" \ +- "pnmtops_nosetpage=$(pnmtops_nosetpage)" \ +- "prefix=$(prefix)" \ +- "revision=$(revision)" \ +- "sys_tmac_prefix=$(sys_tmac_prefix)" \ +- "systemtmacdir=$(systemtmacdir)" \ +- "tmac_an_prefix=$(tmac_an_prefix)" \ +- "tmac_m_prefix=$(tmac_m_prefix)" \ +- "tmac_s_prefix=$(tmac_s_prefix)" \ +- "tmac_wrap=$(tmac_wrap)" \ +- "tmacdir=$(tmacdir)" \ +- "tmacpath=$(tmacpath)" \ +- "top_builddir=$(top_builddir)" \ +- "top_srcdir=$(top_srcdir)" \ +- "version=$(version)" +- +-MAKE_K_FLAG=`for f in x $(MAKEFLAGS); do \ +- case $$f in \ +- *=* | --[!k]*);; \ +- *k*) echo ' -k ';; \ +- esac; \ +- done` +- +-INCDIRS=\ +- src/include +-LIBDIRS=\ +- src/libs/libgroff \ +- src/libs/libdriver \ +- src/libs/libbib \ +- $(XLIBDIRS) +-ALLLIBDIRS=\ +- src/libs/libgroff \ +- src/libs/libdriver \ +- src/libs/libbib \ +- src/libs/libxutil +-CCPROGDIRS=\ +- src/roff/groff \ +- src/roff/troff \ +- src/preproc/preconv \ +- src/preproc/tbl \ +- src/preproc/pic \ +- src/preproc/eqn \ +- src/preproc/grn \ +- src/preproc/refer \ +- src/preproc/soelim \ +- src/preproc/html \ +- src/devices/grops \ +- src/devices/grotty \ +- src/devices/grodvi \ +- src/devices/grolj4 \ +- src/devices/grohtml \ +- src/devices/grolbp \ +- src/utils/tfmtodit \ +- src/utils/hpftodit \ +- src/utils/lookbib \ +- src/utils/indxbib \ +- src/utils/lkbib \ +- src/utils/addftinfo +-CPROGDIRS=\ +- src/utils/pfbtops +-SHPROGDIRS=\ +- src/devices/gropdf +-PROGDEPDIRS=\ +- arch/misc +-PROGDIRS=\ +- $(PROGDEPDIRS) \ +- $(CCPROGDIRS) \ +- $(CPROGDIRS) \ +- $(SHPROGDIRS) \ +- $(XPROGDIRS) +-ALLPROGDIRS=\ +- $(PROGDEPDIRS) \ +- $(CCPROGDIRS) \ +- $(CPROGDIRS) \ +- $(SHPROGDIRS) \ +- src/devices/xditview \ +- src/utils/xtotroff +-DEVDIRS=\ +- font/devps \ +- font/devdvi \ +- font/devhtml +-ALLTTYDEVDIRS=\ +- font/devascii \ +- font/devlatin1 \ +- font/devutf8 \ +- font/devcp1047 +-# `doc' must be processed before `contrib/pdfmark', +-# pdf stuff must be processed before `contrib/mom', +-# devpdf fonts depends on `afmtodit' +-OTHERDIRS=\ +- src/utils/afmtodit \ +- font/devpdf \ +- arch/mingw \ +- contrib/chem \ +- contrib/eqn2graph \ +- contrib/gdiffmk \ +- contrib/glilypond \ +- contrib/gperl \ +- contrib/gpinyin \ +- contrib/grap2graph \ +- contrib/groff_filenames \ +- contrib/groffer \ +- contrib/hdtbl \ +- contrib/mm \ +- contrib/pdfmark \ +- contrib/pic2graph \ +- contrib/mom \ +- doc \ +- man \ +- src/roff/grog \ +- src/roff/nroff \ +- tmac +- +-# OTHERDIRS is handled specially in the `$(TARGETS)' rule to avoid +-# dependency problems with parallel builds. +-ALLDIRS=\ +- $(INCDIRS) \ +- $(LIBDIRS) \ +- $(PROGDIRS) \ +- $(DEVDIRS) \ +- $(XDEVDIRS) \ +- $(OTHERDEVDIRS) \ +- $(TTYDEVDIRS) +-# $(OTHERDIRS) +-EXTRADIRS=\ +- font/devps/generate \ +- font/devdvi/generate \ +- font/devlj4/generate \ +- doc +-NOMAKEDIRS=\ +- m4 \ +- arch/djgpp \ +- contrib/chem/examples \ +- contrib/chem/examples/122 \ +- contrib/hdtbl/examples \ +- contrib/mm/examples \ +- contrib/mm/mm \ +- contrib/mom/examples \ +- contrib/mom/momdoc \ +- contrib/gdiffmk/tests \ +- src/libs/snprintf \ +- src/libs/gnulib/lib \ +- src/libs/gnulib/lib/uniwidth \ +- src/libs/gnulib/m4 \ +- src/libs/gnulib/build-aux \ +- src/libs/gnulib/build-aux/snippet \ +- src/libs/gnulib \ +- font/devps/old \ +- font/devpdf/util \ +- font/util +-GNULIBDIRS=\ +- src/libs/gnulib +-DISTDIRS=\ +- $(INCDIRS) \ +- $(ALLLIBDIRS) \ +- $(ALLPROGDIRS) \ +- $(DEVDIRS) \ +- $(XDEVDIRS) \ +- $(OTHERDEVDIRS) \ +- $(ALLTTYDEVDIRS) \ +- $(OTHERDIRS) \ +- $(EXTRADIRS) \ +- $(NOMAKEDIRS) \ +- $(GNULIBDIRS) +-TARGETS=\ +- all \ +- install_bin install_data \ +- clean distclean mostlyclean realclean extraclean \ +- distfiles \ +- TAGS \ +- depend \ +- uninstall_sub \ +- fonts +- +-# This ENVSETUP gork is required by the DJGPP build on Windows 9X, +-# where Make needs to be case-sensitive to find files like BI and VERSION. +-ENVSETUP=\ +- if test -f $(srcdir)/makefile.ccpg* && \ +- test -f $(srcdir)/Makefile.ccpg*; then \ +- FNCASE=y; export FNCASE; \ +- else :; \ +- fi +- +-do=all +-dodirs=$(ALLDIRS) $(OTHERDIRS) dot +-# Default target for subdir_Makefile +-subdir=src/roff/troff +- +-$(TARGETS): +- @$(ENVSETUP); $(MAKE) $(MAKE_K_FLAG) do=$@ $(ALLDIRS) +- @$(ENVSETUP); $(MAKE) $(MAKE_K_FLAG) do=$@ $(OTHERDIRS) dot +- +-clean: clean-gnulib +-clean-gnulib: +- @$(ENVSETUP); cd src/libs/gnulib; $(MAKE) $(MAKE_K_FLAG) clean +- +-distclean: distclean-gnulib +-distclean-gnulib: +- @$(ENVSETUP); cd src/libs/gnulib; $(MAKE) $(MAKE_K_FLAG) distclean +- rm -rf src/libs/gnulib/autom4te.cache +- +-dot: FORCE +- @$(ENVSETUP); \ +- $(MAKE) $(MAKE_K_FLAG) $(MDEFINES) srcdir=$(srcdir) VPATH=$(srcdir) \ +- -f $(top_srcdir)/Makefile.comm \ +- -f $(top_srcdir)/Makefile.sub $(do) +- +-$(LIBDIRS): FORCE $(INCDIRS) $(PROGDEPDIRS) $(GNULIBDIRS) +- @$(ENVSETUP); \ +- if test $(srcdir) = .; then \ +- srcdir=.; \ +- else \ +- srcdir=$(top_srcdir)/$@; \ +- fi; \ +- test -d $@ || $(mkinstalldirs) $@; \ +- cd $@; \ +- test -f Makefile.dep || touch Makefile.dep; \ +- $(MAKE) $(MAKE_K_FLAG) $(MDEFINES) srcdir=$$srcdir VPATH=$$srcdir \ +- -f $(top_srcdir)/Makefile.comm \ +- -f $$srcdir/Makefile.sub \ +- -f $(top_srcdir)/Makefile.lib \ +- -f Makefile.dep $(do) +- +-$(CPROGDIRS) $(XPROGDIRS): FORCE $(LIBDIRS) +- @$(ENVSETUP); \ +- if test $(srcdir) = .; then \ +- srcdir=.; \ +- else \ +- srcdir=$(top_srcdir)/$@; \ +- fi; \ +- test -d $@ || $(mkinstalldirs) $@; \ +- cd $@; \ +- test -f Makefile.dep || touch Makefile.dep; \ +- $(MAKE) $(MAKE_K_FLAG) $(MDEFINES) srcdir=$$srcdir VPATH=$$srcdir \ +- -f $(top_srcdir)/Makefile.comm \ +- -f $$srcdir/Makefile.sub \ +- -f $(top_srcdir)/Makefile.cpg \ +- -f Makefile.dep $(do) +- +-$(CCPROGDIRS): FORCE $(LIBDIRS) +- @$(ENVSETUP); \ +- if test $(srcdir) = .; then \ +- srcdir=.; \ +- else \ +- srcdir=$(top_srcdir)/$@; \ +- fi; \ +- test -d $@ || $(mkinstalldirs) $@; \ +- cd $@; \ +- test -f Makefile.dep || touch Makefile.dep; \ +- $(MAKE) $(MAKE_K_FLAG) $(MDEFINES) srcdir=$$srcdir VPATH=$$srcdir \ +- -f $(top_srcdir)/Makefile.comm \ +- -f $$srcdir/Makefile.sub \ +- -f $(top_srcdir)/Makefile.ccpg \ +- -f Makefile.dep $(do) +- +-$(DEVDIRS) $(XDEVDIRS) $(OTHERDEVDIRS) $(TTYDEVDIRS): FORCE \ +- $(PROGDEPDIRS) $(CCPROGDIRS) $(CPROGDIRS) +- @$(ENVSETUP); \ +- if test $(srcdir) = .; then \ +- srcdir=.; \ +- else \ +- srcdir=$(top_srcdir)/$@; \ +- fi; \ +- test -d $@ || $(mkinstalldirs) $@; \ +- cd $@; \ +- $(MAKE) $(MAKE_K_FLAG) $(MDEFINES) srcdir=$$srcdir VPATH=$$srcdir \ +- -f $(top_srcdir)/Makefile.comm \ +- -f $$srcdir/Makefile.sub \ +- -f $(top_srcdir)/Makefile.dev $(do) +- +-$(GNULIBDIRS): FORCE +- @$(ENVSETUP); \ +- if test $(srcdir) = .; then \ +- srcdir=.; \ +- else \ +- srcdir=$(top_srcdir)/$@; \ +- fi; \ +- test -d $@ || $(mkinstalldirs) $@; \ +- case $(do) in \ +- all) \ +- cd $@; \ +- args=`$(top_builddir)/config.status --config`; \ +- test -f Makefile \ +- || eval $$srcdir/configure "$$args" --srcdir=$$srcdir; \ +- $(MAKE) ACLOCAL=: AUTOCONF=: AUTOHEADER=: AUTOMAKE=: $(do) ;; \ +- esac +- +-$(OTHERDIRS): $(PROGDEPDIRS) $(CCPROGDIRS) $(CPROGDIRS) $(SHPROGDIRS) +- +-$(INCDIRS) $(PROGDEPDIRS) $(SHPROGDIRS) $(OTHERDIRS): FORCE +- @$(ENVSETUP); \ +- if test $(srcdir) = .; then \ +- srcdir=.; \ +- else \ +- srcdir=$(top_srcdir)/$@; \ +- fi; \ +- test -d $@ || $(mkinstalldirs) $@; \ +- cd $@; \ +- $(MAKE) $(MAKE_K_FLAG) $(MDEFINES) srcdir=$$srcdir VPATH=$$srcdir \ +- -f $(top_srcdir)/Makefile.comm \ +- -f $$srcdir/Makefile.sub \ +- -f $(top_srcdir)/Makefile.man $(do) +- +-.PHONY: dist +-dist: +- if test "${doc_dist_target_ok}" != yes; then \ +- echo "The \`dist' target is not applicable to this configuration"; \ +- exit 1; \ +- fi +- -rm -fr tmp +- rm -f groff-$(version)$(revision).tar.gz +- mkdir tmp +- for d in $(DISTDIRS); do \ +- $(mkinstalldirs) tmp/$$d; \ +- done +- cp Makefile tmp +- -cp * tmp 2>/dev/null +- -for d in $(DISTDIRS); do \ +- (cd tmp/$$d; \ +- cp $(top_srcdir)/$$d/* . 2>/dev/null;); \ +- done +- cd tmp; $(MAKE) srcdir=. VPATH=. distfiles +- cd tmp; $(MAKE) srcdir=. VPATH=. extraclean +- for d in $(EXTRADIRS); do \ +- (cd tmp/$$d; \ +- if test -f Makefile; then \ +- $(MAKE) extraclean; \ +- else \ +- $(MAKE) -f $(top_builddir)/$$d/Makefile extraclean; \ +- fi); \ +- done +- for d in $(GNULIBDIRS); do \ +- (cd tmp/$$d; \ +- if test -f config.status; then \ +- ./config.status; \ +- fi; \ +- if test -f Makefile; then \ +- $(MAKE) distclean; \ +- else \ +- $(MAKE) -f $(top_builddir)/$$d/Makefile distclean; \ +- fi; \ +- rm -rf autom4te.cache); \ +- done +- rm -f tmp/Makefile +- cp Makefile.init tmp/Makefile +- mv tmp groff-$(version)$(revision) +- tar cfh - groff-$(version)$(revision) \ +- | gzip -c >groff-$(version)$(revision).tar.gz +- rm -fr groff-$(version)$(revision) +- +-# $(PROGDIRS): libgroff +-# grops grotty grodvi: libdriver +-# refer lookbib indxbib lkbib: libbib +-# $(LIBDIRS) $(PROGDIRS): include +- +-.PHONY: $(ALLDIRS) dot $(TARGETS) FORCE +- +-# Create a Makefile in $(subdir). This is useful for development since it +-# avoids running make recursively. +-subdir_Makefile: Makefile.cfg +- $(MAKE) do=Makefile $(subdir) +- +-Makefile.cfg: Makefile +- >Makefile.cfg +- for var in $(MDEFINES); do \ +- echo "$$var" >>Makefile.cfg; \ +- done +- +-Makefile: Makefile.in +- $(SHELL) config.status +- +-.PHONY: install +-install: +- -test -d $(DESTDIR)$(prefix) \ +- || $(mkinstalldirs) $(DESTDIR)$(prefix) +- @$(ENVSETUP); $(MAKE) $(MAKE_K_FLAG) $(MDEFINES) \ +- do=do_install $(dodirs) +- cd $(DESTDIR)$(dataprogramdir); \ +- rm -f current; \ +- $(LN_S) $(version)$(revision) current +- +-.PHONY: uninstall +-uninstall: uninstall_sub uninstall_dirs +- +-.PHONY: uninstall_dirs +-# Use `rmdir' here so that the directories are only removed if they are empty. +-uninstall_dirs: +- rm -f $(DESTDIR)$(dataprogramdir)/current +- -rmdir \ +- $(DESTDIR)$(man1dir) \ +- $(DESTDIR)$(man5dir) \ +- $(DESTDIR)$(man7dir) \ +- $(DESTDIR)$(manroot) \ +- $(DESTDIR)$(tmacdir) \ +- $(DESTDIR)$(systemtmacdir) \ +- $(DESTDIR)$(localtmacdir) \ +- $(DESTDIR)$(fontdir) \ +- $(DESTDIR)$(localfontdir) \ +- $(DESTDIR)$(oldfontdir) \ +- $(DESTDIR)$(bindir) \ +- $(DESTDIR)$(datasubdir) \ +- $(DESTDIR)$(dataprogramdir) \ +- $(DESTDIR)$(libprogramdir) \ +- $(DESTDIR)$(libdir) \ +- $(DESTDIR)$(infodir) \ +- $(DESTDIR)$(exampledir) \ +- $(DESTDIR)$(htmldocdir) \ +- $(DESTDIR)$(pdfdocdir) \ +- $(DESTDIR)$(docdir) \ +- $(DESTDIR)$(datadir)/doc/groff \ +- $(DESTDIR)$(datadir)/doc \ +- $(DESTDIR)$(datadir) 2>/dev/null || : +- +-.PHONY: check +-check: +- @echo There is no validation suite for this package. +- +-#check: site.exp docheck +-#.PHONY: docheck +- +-#docheck: +-# if $(SHELL) -c "runtest --version" > /dev/null 2>&1; then \ +-# runtest; \ +-# else \ +-# echo "WARNING: could not find \`runtest'" 1>&2; \ +-# fi +- +-# This snippet has been taken from the automake package. +- +-#site.exp: +-# @echo "Making a new site.exp file..." +-# @echo "## these variables are automatically generated by make ##" >site.tmp +-# @echo "# Do not edit here. If you wish to override these values" >>site.tmp +-# @echo "# edit the last section" >>site.tmp +-# @echo "set tool groff" >>site.tmp +-# @echo "set srcdir $(srcdir)/testsuite" >>site.tmp +-# @echo "set objdir `pwd`" >> site.tmp +-# @echo "## All variables above are generated by configure. Do not edit! ##" >> site.tmp +-# @test ! -f site.exp \ +-# || sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp +-# @rm -f site.bak +-# @test ! -f site.exp || mv site.exp site.bak +-# @mv site.tmp site.exp +- +-FORCE: +- +-.NOEXPORT: +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/Makefile.init groff-1.22.3/Makefile.init +--- groff-1.22.3.old/Makefile.init 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/Makefile.init 1970-01-01 02:00:00.000000000 +0200 +@@ -1,34 +0,0 @@ +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.init +-# +-SHELL=/bin/sh +- +-.PHONY: all +-all: +- $(SHELL) configure +- $(MAKE) all +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/Makefile.lib groff-1.22.3/Makefile.lib +--- groff-1.22.3.old/Makefile.lib 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/Makefile.lib 1970-01-01 02:00:00.000000000 +0200 +@@ -1,48 +0,0 @@ +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.lib +-# +-LIBCLEAN=lib$(LIB).$(LIBEXT) +-MAKEFILEPARTS=\ +- $(top_srcdir)/Makefile.comm \ +- $(top_builddir)/Makefile.cfg \ +- $(srcdir)/Makefile.sub \ +- $(top_srcdir)/Makefile.lib \ +- Makefile.dep +- +-all: lib$(LIB).$(LIBEXT) +- +-lib$(LIB).$(LIBEXT): $(OBJS) +- $(AR) r $@ $? +- $(RANLIB) $@ +- +-depend: depend_src +-depend.temp: $(GENSRCS) +-TAGS: $(CCSRCS) $(CSRCS) +-Makefile: $(MAKEFILEPARTS) +-Makefile.dep: +- touch Makefile.dep +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/Makefile.man groff-1.22.3/Makefile.man +--- groff-1.22.3.old/Makefile.man 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/Makefile.man 1970-01-01 02:00:00.000000000 +0200 +@@ -1,34 +0,0 @@ +-# Copyright (C) 1992-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.man +-# +-all: $(MANPAGES) +-install_data: install_man +-install_man: $(MANPAGES) +-uninstall_sub: uninstall_man +-$(top_builddir)/stamp-h $(MANPAGES): $(top_srcdir)/VERSION \ +- $(top_srcdir)/REVISION +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/Makefile.sub groff-1.22.3/Makefile.sub +--- groff-1.22.3.old/Makefile.sub 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,83 +0,0 @@ +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-# Makefile.sub +-# +-DISTCLEANFILES=\ +- Makefile \ +- config.cache \ +- config.log \ +- config.status \ +- groff.log \ +- groff.sum \ +- src/include/config.h \ +- site.bak \ +- site.exp \ +- stamp-h \ +- test-groff +- +-MOSTLYCLEANADD=\ +- Makefile.cfg \ +- conftest* +- +-M4MACROS=\ +- $(srcdir)/m4/ax_compare_version.m4 \ +- $(srcdir)/m4/ax_prog_perl_version.m4 \ +- $(srcdir)/m4/codeset.m4 \ +- $(srcdir)/m4/fcntl-o.m4 \ +- $(srcdir)/m4/glibc21.m4 \ +- $(srcdir)/m4/groff.m4 \ +- $(srcdir)/m4/iconv.m4 \ +- $(srcdir)/m4/lib-ld.m4 \ +- $(srcdir)/m4/lib-link.m4 \ +- $(srcdir)/m4/lib-prefix.m4 \ +- $(srcdir)/m4/localcharset.m4 +- +-distfiles: configure +- +-$(srcdir)/configure: configure.ac $(srcdir)/aclocal.m4 +- cd $(srcdir) && autoconf && rm -rf autom4te.cache +- +-$(srcdir)/aclocal.m4: $(M4MACROS) +- cd $(srcdir) && aclocal -I m4 +- +-config.status: configure +- $(SHELL) config.status --recheck +- +-# autoheader might not change config.hin, so touch a stamp file. +-$(srcdir)/config.hin: stamp-h.in +-$(srcdir)/stamp-h.in: configure.ac $(srcdir)/aclocal.m4 +- cd $(srcdir) && autoheader +- echo timestamp > $(srcdir)/stamp-h.in +- +-config.h: stamp-h +-stamp-h: config.hin config.status +- $(SHELL) config.status +- +-# Always create the site-font directory as a guide to the user. +-install_data: +- -test -d $(DESTDIR)$(localfontdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(localfontdir) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/man/ditroff.man groff-1.22.3/man/ditroff.man +--- groff-1.22.3.old/man/ditroff.man 2014-11-04 10:38:35.517520346 +0200 ++++ groff-1.22.3/man/ditroff.man 2015-04-23 20:57:03.000000000 +0300 +@@ -7,7 +7,7 @@ + . + . + .de co +-Copyright \[co] 2001-2014 Free Software Foundation, Inc. ++Copyright \(co 2001-2014 Free Software Foundation, Inc. + + This file is part of groff, the GNU roff type-setting system. + +@@ -68,27 +68,27 @@ + creating an intermediate output format for troff that can be fed into + postprocessor programs which actually do the printout on the device. + . +-Kernighan\[aq]s version marks what is known as ++Kernighan\(aqs version marks what is known as + .I classical troff + today. + . +-In order to distinguish it from Ossanna\[aq]s original mono-device ++In order to distinguish it from Ossanna\(aqs original mono-device + version, it was called + .I ditroff + .RI ( d "evice " i "ndependent " troff ) +-on some systems, though this naming isn\[aq]t mentioned in the ++on some systems, though this naming isn\(aqt mentioned in the + classical documentation. + . + . + .P +-Today, any existing roff system is based on Kernighan\[aq]s ++Today, any existing roff system is based on Kernighan\(aqs + multi-device troff. + . + The distinction between + .I troff + and + .I ditroff +-isn\[aq]t necessary any longer, for each modern ++isn\(aqt necessary any longer, for each modern + .I troff + provides already the complete functionality of + .IR ditroff . +@@ -116,7 +116,7 @@ + .TP + .I [CSTR\~#54] + The 1992 revision of the +-.I Nroff/Troff User\[aq]s Manual ++.I Nroff/Troff User\(aqs Manual + by + .I J.\& F.\& Ossanna + and +diff -Nuar groff-1.22.3.old/man/.gitignore groff-1.22.3/man/.gitignore +--- groff-1.22.3.old/man/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/man/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,8 @@ ++ditroff.n ++groff.n ++groff_char.n ++groff_diff.n ++groff_font.n ++groff_out.n ++groff_tmac.n ++roff.n +diff -Nuar groff-1.22.3.old/man/groff_char.man groff-1.22.3/man/groff_char.man +--- groff-1.22.3.old/man/groff_char.man 2014-11-04 10:38:35.517520346 +0200 ++++ groff-1.22.3/man/groff_char.man 2015-04-23 20:57:03.000000000 +0300 +@@ -808,7 +808,7 @@ + glyphs. + . + For this reason, the four glyphs \[oq]lf\[cq], \[oq]rf\[cq], +-\[o]lc\[cq], and \[oq]rc\[cq] are not unified with similarly looking ++\[oq]lc\[cq], and \[oq]rc\[cq] are not unified with similarly looking + bracket pieces. + . + In +diff -Nuar groff-1.22.3.old/man/groff_diff.man groff-1.22.3/man/groff_diff.man +--- groff-1.22.3.old/man/groff_diff.man 2014-11-04 10:38:35.517520346 +0200 ++++ groff-1.22.3/man/groff_diff.man 2015-04-23 20:57:03.000000000 +0300 +@@ -9,6 +9,10 @@ + .\" Installed position: /share/man/man7/groff_diff.7 + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .de co + Copyright \[co] 1989-2014 Free Software Foundation, Inc. + . +@@ -3964,6 +3968,9 @@ + .au + . + . ++.cp \n[groff_C] ++. ++. + .\" -------------------------------------------------------------------- + .\" Emacs variables + .\" -------------------------------------------------------------------- +diff -Nuar groff-1.22.3.old/man/groff.man groff-1.22.3/man/groff.man +--- groff-1.22.3.old/man/groff.man 2014-11-04 10:38:35.518520334 +0200 ++++ groff-1.22.3/man/groff.man 2015-04-23 20:57:03.000000000 +0300 +@@ -13,7 +13,7 @@ + .de co + This file is part of groff, the GNU roff type-setting system. + +-Copyright \[co] 2000-2014 Free Software Foundation, Inc. ++Copyright \(co 2000-2014 Free Software Foundation, Inc. + + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 or +diff -Nuar groff-1.22.3.old/man/groff_out.man groff-1.22.3/man/groff_out.man +--- groff-1.22.3.old/man/groff_out.man 2014-11-04 10:38:35.518520334 +0200 ++++ groff-1.22.3/man/groff_out.man 2015-04-23 20:57:03.000000000 +0300 +@@ -9,6 +9,10 @@ + .\" Installed position: /share/man/man5/groff_out.5 + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" License and authors + .\" -------------------------------------------------------------------- +@@ -2002,6 +2006,9 @@ + .au + . + . ++.cp \n[groff_C] ++. ++. + .\" -------------------------------------------------------------------- + .\" Emacs settings + .\" -------------------------------------------------------------------- +diff -Nuar groff-1.22.3.old/man/groff_tmac.man groff-1.22.3/man/groff_tmac.man +--- groff-1.22.3.old/man/groff_tmac.man 2014-11-04 10:38:35.518520334 +0200 ++++ groff-1.22.3/man/groff_tmac.man 2015-04-23 20:57:03.000000000 +0300 +@@ -7,6 +7,10 @@ + .\" Source file position: /man/groff_tmac.man + .\" Installed position: /share/man/man5/groff_tmac.5 + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" Legalese + .\" -------------------------------------------------------------------- +@@ -1269,3 +1273,14 @@ + .SH AUTHOR + .\" -------------------------------------------------------------------- + .au ++. ++..cp \n[groff_C] ++. ++. ++.\" -------------------------------------------------------------------- ++.\" Emacs settings ++.\" -------------------------------------------------------------------- ++. ++.\" Local Variables: ++.\" mode: nroff ++.\" End: +diff -Nuar groff-1.22.3.old/man/Makefile.sub groff-1.22.3/man/Makefile.sub +--- groff-1.22.3.old/man/Makefile.sub 2014-11-04 10:38:35.518520334 +0200 ++++ groff-1.22.3/man/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,45 +0,0 @@ +-# Makefile.sub for `man' +-# +-# File position: /man/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-MAN5=\ +- groff_font.n \ +- groff_out.n \ +- groff_tmac.n +-MAN7=\ +- ditroff.n \ +- groff_char.n \ +- groff_diff.n \ +- groff.n \ +- roff.n +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/man/man.am groff-1.22.3/man/man.am +--- groff-1.22.3.old/man/man.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/man/man.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,42 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `groff' ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++man5_MANS += \ ++ man/groff_font.n \ ++ man/groff_out.n \ ++ man/groff_tmac.n ++man7_MANS += \ ++ man/ditroff.n \ ++ man/groff_char.n \ ++ man/groff_diff.n \ ++ man/groff.n \ ++ man/roff.n ++EXTRA_DIST += \ ++ man/groff_font.man \ ++ man/groff_out.man \ ++ man/groff_tmac.man \ ++ man/ditroff.man \ ++ man/groff_char.man \ ++ man/groff_diff.man \ ++ man/groff.man \ ++ man/roff.man ++ ++# Case of out-of-source build: we must create the 'man' directory. ++BUILT_SOURCES += man ++man: ++ $(MKDIR_P) $(top_builddir)/man +diff -Nuar groff-1.22.3.old/man/roff.man groff-1.22.3/man/roff.man +--- groff-1.22.3.old/man/roff.man 2014-11-04 10:38:35.518520334 +0200 ++++ groff-1.22.3/man/roff.man 2015-04-23 20:57:03.000000000 +0300 +@@ -5,6 +5,11 @@ + . + .\" this is man-page roff.7 + . ++. ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" Legalese + .\" -------------------------------------------------------------------- +@@ -1359,6 +1364,9 @@ + .au + . + . ++.cp \n[groff_C] ++. ++. + .\" -------------------------------------------------------------------- + .\" Emacs setup + .\" -------------------------------------------------------------------- +diff -Nuar groff-1.22.3.old/mkinstalldirs groff-1.22.3/mkinstalldirs +--- groff-1.22.3.old/mkinstalldirs 2014-11-04 10:38:35.145524997 +0200 ++++ groff-1.22.3/mkinstalldirs 1970-01-01 02:00:00.000000000 +0200 +@@ -1,162 +0,0 @@ +-#! /bin/sh +-# mkinstalldirs --- make directory hierarchy +- +-scriptversion=2009-04-28.21; # UTC +- +-# Original author: Noah Friedman +-# Created: 1993-05-16 +-# Public domain. +-# +-# This file is maintained in Automake, please report +-# bugs to or send patches to +-# . +- +-nl=' +-' +-IFS=" "" $nl" +-errstatus=0 +-dirmode= +- +-usage="\ +-Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... +- +-Create each directory DIR (with mode MODE, if specified), including all +-leading file name components. +- +-Report bugs to ." +- +-# process command line arguments +-while test $# -gt 0 ; do +- case $1 in +- -h | --help | --h*) # -h for help +- echo "$usage" +- exit $? +- ;; +- -m) # -m PERM arg +- shift +- test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } +- dirmode=$1 +- shift +- ;; +- --version) +- echo "$0 $scriptversion" +- exit $? +- ;; +- --) # stop option processing +- shift +- break +- ;; +- -*) # unknown option +- echo "$usage" 1>&2 +- exit 1 +- ;; +- *) # first non-opt arg +- break +- ;; +- esac +-done +- +-for file +-do +- if test -d "$file"; then +- shift +- else +- break +- fi +-done +- +-case $# in +- 0) exit 0 ;; +-esac +- +-# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +-# mkdir -p a/c at the same time, both will detect that a is missing, +-# one will create a, then the other will try to create a and die with +-# a "File exists" error. This is a problem when calling mkinstalldirs +-# from a parallel make. We use --version in the probe to restrict +-# ourselves to GNU mkdir, which is thread-safe. +-case $dirmode in +- '') +- if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then +- echo "mkdir -p -- $*" +- exec mkdir -p -- "$@" +- else +- # On NextStep and OpenStep, the 'mkdir' command does not +- # recognize any option. It will interpret all options as +- # directories to create, and then abort because '.' already +- # exists. +- test -d ./-p && rmdir ./-p +- test -d ./--version && rmdir ./--version +- fi +- ;; +- *) +- if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && +- test ! -d ./--version; then +- echo "mkdir -m $dirmode -p -- $*" +- exec mkdir -m "$dirmode" -p -- "$@" +- else +- # Clean up after NextStep and OpenStep mkdir. +- for d in ./-m ./-p ./--version "./$dirmode"; +- do +- test -d $d && rmdir $d +- done +- fi +- ;; +-esac +- +-for file +-do +- case $file in +- /*) pathcomp=/ ;; +- *) pathcomp= ;; +- esac +- oIFS=$IFS +- IFS=/ +- set fnord $file +- shift +- IFS=$oIFS +- +- for d +- do +- test "x$d" = x && continue +- +- pathcomp=$pathcomp$d +- case $pathcomp in +- -*) pathcomp=./$pathcomp ;; +- esac +- +- if test ! -d "$pathcomp"; then +- echo "mkdir $pathcomp" +- +- mkdir "$pathcomp" || lasterr=$? +- +- if test ! -d "$pathcomp"; then +- errstatus=$lasterr +- else +- if test ! -z "$dirmode"; then +- echo "chmod $dirmode $pathcomp" +- lasterr= +- chmod "$dirmode" "$pathcomp" || lasterr=$? +- +- if test ! -z "$lasterr"; then +- errstatus=$lasterr +- fi +- fi +- fi +- fi +- +- pathcomp=$pathcomp/ +- done +-done +- +-exit $errstatus +- +-# Local Variables: +-# mode: shell-script +-# sh-indentation: 2 +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "scriptversion=" +-# time-stamp-format: "%:y-%02m-%02d.%02H" +-# time-stamp-time-zone: "UTC" +-# time-stamp-end: "; # UTC" +-# End: +diff -Nuar groff-1.22.3.old/README.git groff-1.22.3/README.git +--- groff-1.22.3.old/README.git 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/README.git 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++This file is not distributed and is given to the bootstrap script to ++be sure that this script is invoked on a source tree checked out from ++the git repository and not from a tarball. +diff -Nuar groff-1.22.3.old/src/devices/grodvi/.gitignore groff-1.22.3/src/devices/grodvi/.gitignore +--- groff-1.22.3.old/src/devices/grodvi/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grodvi/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++grodvi ++grodvi.n +diff -Nuar groff-1.22.3.old/src/devices/grodvi/grodvi.am groff-1.22.3/src/devices/grodvi/grodvi.am +--- groff-1.22.3.old/src/devices/grodvi/grodvi.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grodvi/grodvi.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,28 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += grodvi ++grodvi_SOURCES = src/devices/grodvi/dvi.cpp ++grodvi_LDADD = \ ++ libdriver.a \ ++ libgroff.a \ ++ lib/libgnu.a $(LIBM) ++man1_MANS += src/devices/grodvi/grodvi.n ++EXTRA_DIST += src/devices/grodvi/grodvi.man ++ ++ +diff -Nuar groff-1.22.3.old/src/devices/grodvi/grodvi.man groff-1.22.3/src/devices/grodvi/grodvi.man +--- groff-1.22.3.old/src/devices/grodvi/grodvi.man 2014-11-04 10:38:35.270523434 +0200 ++++ groff-1.22.3/src/devices/grodvi/grodvi.man 2015-04-23 20:57:03.000000000 +0300 +@@ -5,7 +5,7 @@ + . + .\" copying (license) + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +diff -Nuar groff-1.22.3.old/src/devices/grodvi/Makefile.sub groff-1.22.3/src/devices/grodvi/Makefile.sub +--- groff-1.22.3.old/src/devices/grodvi/Makefile.sub 2014-11-04 10:38:35.270523434 +0200 ++++ groff-1.22.3/src/devices/grodvi/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,41 +0,0 @@ +-# Makefile.sub for `grodvi' +-# +-# File position: /src/devices/grodvi/Makefile.sub +-# +-# Copyright (C) 2014 +-# Free Software Foundation, Inc. +-# +-# Last update: 2 Sep 2014 +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=grodvi$(EXEEXT) +-MAN1=grodvi.n +-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU) +-MLIB=$(LIBM) +-OBJS=dvi.$(OBJEXT) +-CCSRCS=$(srcdir)/dvi.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/devices/grohtml/.gitignore groff-1.22.3/src/devices/grohtml/.gitignore +--- groff-1.22.3.old/src/devices/grohtml/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grohtml/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++grohtml.n ++post-grohtml +diff -Nuar groff-1.22.3.old/src/devices/grohtml/grohtml.am groff-1.22.3/src/devices/grohtml/grohtml.am +--- groff-1.22.3.old/src/devices/grohtml/grohtml.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grohtml/grohtml.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,34 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += post-grohtml ++post_grohtml_SOURCES = \ ++ src/devices/grohtml/post-html.cpp \ ++ src/devices/grohtml/html-table.cpp \ ++ src/devices/grohtml/html-text.cpp \ ++ src/devices/grohtml/output.cpp \ ++ src/devices/grohtml/html.h \ ++ src/devices/grohtml/html-text.h \ ++ src/devices/grohtml/html-table.h ++ ++post_grohtml_LDADD = $(LIBM) \ ++ libdriver.a \ ++ libgroff.a \ ++ lib/libgnu.a ++man1_MANS += src/devices/grohtml/grohtml.n ++EXTRA_DIST += src/devices/grohtml/grohtml.man +diff -Nuar groff-1.22.3.old/src/devices/grohtml/grohtml.man groff-1.22.3/src/devices/grohtml/grohtml.man +--- groff-1.22.3.old/src/devices/grohtml/grohtml.man 2014-11-04 10:38:35.279523322 +0200 ++++ groff-1.22.3/src/devices/grohtml/grohtml.man 2015-04-23 20:57:03.000000000 +0300 +@@ -5,7 +5,7 @@ + . + .\" license + .de co +-Copyright \[co] 1999-2014 Free Software Foundation, Inc. ++Copyright \(co 1999-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of this + manual provided the copyright notice and this permission notice are +@@ -102,7 +102,7 @@ + options can be passed to + .B grohtml + using +-.BR groff \[aq]s ++.BR groff \(aqs + .B \-P + option. + . +@@ -126,7 +126,7 @@ + all non-composite unicode characters. + . + In spite of this, groff may issue warnings about unknown special +-characters if they can\[aq]t be found during the first pass. ++characters if they can\(aqt be found during the first pass. + . + Such warnings can be safely ignored unless the special characters + appear inside a table or equation. +@@ -269,7 +269,7 @@ + . + Without the option the anchor value is the textual heading. + . +-This can cause problems when a heading contains a \[oq]?\[cq] on older ++This can cause problems when a heading contains a \(oq?\(cqa on older + versions of some browsers (Netscape). + . + This flag is automatically turned on if a heading contains an image. +diff -Nuar groff-1.22.3.old/src/devices/grohtml/Makefile.sub groff-1.22.3/src/devices/grohtml/Makefile.sub +--- groff-1.22.3.old/src/devices/grohtml/Makefile.sub 2014-11-04 10:38:35.279523322 +0200 ++++ groff-1.22.3/src/devices/grohtml/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,50 +0,0 @@ +-# Makefile.sub for `grohtml' +-# +-# File position: /src/devices/grohtml/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=post-grohtml$(EXEEXT) +-MAN1=grohtml.n +-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU) +-MLIB=$(LIBM) +-OBJS=\ +- post-html.$(OBJEXT) \ +- html-table.$(OBJEXT) \ +- html-text.$(OBJEXT) \ +- output.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/post-html.cpp \ +- $(srcdir)/html-table.cpp \ +- $(srcdir)/html-text.cpp \ +- $(srcdir)/output.cpp +-HDRS=\ +- $(srcdir)/html.h \ +- $(srcdir)/html-table.h \ +- $(srcdir)/html-text.h +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/devices/grolbp/.gitignore groff-1.22.3/src/devices/grolbp/.gitignore +--- groff-1.22.3.old/src/devices/grolbp/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grolbp/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++grolbp ++grolbp.n +diff -Nuar groff-1.22.3.old/src/devices/grolbp/grolbp.am groff-1.22.3/src/devices/grolbp/grolbp.am +--- groff-1.22.3.old/src/devices/grolbp/grolbp.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grolbp/grolbp.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,30 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += grolbp ++grolbp_SOURCES = \ ++ src/devices/grolbp/lbp.cpp \ ++ src/devices/grolbp/lbp.h \ ++ src/devices/grolbp/charset.h ++ ++grolbp_LDADD = $(LIBM) \ ++ libdriver.a \ ++ libgroff.a \ ++ lib/libgnu.a ++man1_MANS += src/devices/grolbp/grolbp.n ++EXTRA_DIST += src/devices/grolbp/grolbp.man +diff -Nuar groff-1.22.3.old/src/devices/grolbp/grolbp.man groff-1.22.3/src/devices/grolbp/grolbp.man +--- groff-1.22.3.old/src/devices/grolbp/grolbp.man 2014-11-04 10:38:35.284523259 +0200 ++++ groff-1.22.3/src/devices/grolbp/grolbp.man 2015-04-23 20:57:03.000000000 +0300 +@@ -10,7 +10,7 @@ + . + .\" license + .de co +-Copyright \[co] 1994-2014 Free Software Foundation, Inc. ++Copyright \(co 1994-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -112,7 +112,7 @@ + . + Note that there can be whitespace between a one-letter option and its + argument; on the other hand, there must be whitespace and/or an equal sign +-(\[oq]=\[cq]) between a long-name option and its argument. ++(\(oq=\(cq) between a long-name option and its argument. + . + .TP + .BI \-c numcopies +@@ -143,7 +143,7 @@ + .BI \-\-orientation= orientation + Print the document with + .I orientation +-orientation, which must be \[oq]portrait\[cq] or \[oq]landscape\[cq]. ++orientation, which must be \(oqportrait\(cq or \(oqlandscape\(cq. + . + .TP + .BI \-w width +@@ -153,7 +153,7 @@ + .I width + thousandths of an em. + . +-If this option isn\[aq]t specified, the line thickness defaults to 0.04\~em. ++If this option isn\(aqt specified, the line thickness defaults to 0.04\~em. + . + .TP + .B \-v +@@ -348,9 +348,9 @@ + indicating the font styles Roman, Italic and Bold respectively. + . + .IP +-For instance, if the printer\[aq]s ++For instance, if the printer\(aqs + .I font listing A +-shows font \[oq]Nelite12I.ISO_USA\[cq], the corresponding entry in the ++shows font \(oqNelite12I.ISO_USA\(cq, the corresponding entry in the + font description file is + .sp 1 + .in +2m +@@ -367,14 +367,14 @@ + .IP \(bu + For scalable fonts, + .I printer_font_name +-is identical to the font name as it appears in the printer\[aq]s ++is identical to the font name as it appears in the printer\(aqs + .IR "font listing A" . + . + .IP +-For instance, to select the \[oq]Swiss\[cq] font in bold style, which +-appears in the printer\[aq]s ++For instance, to select the \(oqSwiss\(cq font in bold style, which ++appears in the printer\(aqs + .I font listing A +-as \[oq]Swiss-Bold\[cq], the required ++as \(oqSwiss-Bold\(cq, the required + .B lbpname + command line is + .sp 1 +diff -Nuar groff-1.22.3.old/src/devices/grolbp/Makefile.sub groff-1.22.3/src/devices/grolbp/Makefile.sub +--- groff-1.22.3.old/src/devices/grolbp/Makefile.sub 2014-11-04 10:38:35.284523259 +0200 ++++ groff-1.22.3/src/devices/grolbp/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,38 +0,0 @@ +-# Makefile.sub for `grolbp' +-# +-# File position: /src/devices/grolbp/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=grolbp$(EXEEXT) +-MAN1=grolbp.n +-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU) +-MLIB=$(LIBM) +-OBJS=lbp.$(OBJEXT) +-CCSRCS=$(srcdir)/lbp.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/devices/grolj4/.gitignore groff-1.22.3/src/devices/grolj4/.gitignore +--- groff-1.22.3.old/src/devices/grolj4/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grolj4/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,4 @@ ++Makefile.dep ++grolj4 ++grolj4.n ++lj4_font.n +diff -Nuar groff-1.22.3.old/src/devices/grolj4/grolj4.am groff-1.22.3/src/devices/grolj4/grolj4.am +--- groff-1.22.3.old/src/devices/grolj4/grolj4.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grolj4/grolj4.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,30 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += grolj4 ++grolj4_SOURCES = src/devices/grolj4/lj4.cpp ++grolj4_LDADD = $(LIBM) \ ++ libdriver.a \ ++ libgroff.a \ ++ lib/libgnu.a ++man1_MANS += src/devices/grolj4/grolj4.n ++man5_MANS += src/devices/grolj4/lj4_font.n ++EXTRA_DIST += \ ++ src/devices/grolj4/grolj4.man \ ++ src/devices/grolj4/lj4_font.man ++ +diff -Nuar groff-1.22.3.old/src/devices/grolj4/grolj4.man groff-1.22.3/src/devices/grolj4/grolj4.man +--- groff-1.22.3.old/src/devices/grolj4/grolj4.man 2014-11-04 10:38:35.274523384 +0200 ++++ groff-1.22.3/src/devices/grolj4/grolj4.man 2015-04-23 20:57:03.000000000 +0300 +@@ -6,7 +6,7 @@ + . + .\" license + .de co +-Copyright \[co] 1994-2014 Free Software Foundation, Inc. ++Copyright \(co 1994-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -127,7 +127,7 @@ + .I n + thousandths of an em. + . +-If this option isn\[aq]t specified, the line thickness defaults to ++If this option isn\(aqt specified, the line thickness defaults to + 0.04\~em. + . + .TP +diff -Nuar groff-1.22.3.old/src/devices/grolj4/lj4_font.man groff-1.22.3/src/devices/grolj4/lj4_font.man +--- groff-1.22.3.old/src/devices/grolj4/lj4_font.man 2014-11-04 10:38:35.274523384 +0200 ++++ groff-1.22.3/src/devices/grolj4/lj4_font.man 2015-04-23 20:57:03.000000000 +0300 +@@ -6,7 +6,7 @@ + . + .\" license + .de co +-Copyright \[co] 2004-2014 Free Software Foundation, Inc. ++Copyright \(co 2004-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +diff -Nuar groff-1.22.3.old/src/devices/grolj4/Makefile.sub groff-1.22.3/src/devices/grolj4/Makefile.sub +--- groff-1.22.3.old/src/devices/grolj4/Makefile.sub 2014-11-04 10:38:35.274523384 +0200 ++++ groff-1.22.3/src/devices/grolj4/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,39 +0,0 @@ +-# Makefile.sub for `grolj4' +-# +-# File position: /src/devices/grolj4/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=grolj4$(EXEEXT) +-MAN1=grolj4.n +-MAN5=lj4_font.n +-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU) +-MLIB=$(LIBM) +-OBJS=lj4.$(OBJEXT) +-CCSRCS=$(srcdir)/lj4.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/devices/gropdf/gropdf.am groff-1.22.3/src/devices/gropdf/gropdf.am +--- groff-1.22.3.old/src/devices/gropdf/gropdf.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/gropdf/gropdf.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,49 @@ ++# Copyright (C) 2011-2014 ++# Free Software Foundation, Inc. ++# Original Makefile.sub written by Deri James . ++# Automake migration by Bertrand Garrigues ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++gropdf_dir = $(top_srcdir)/src/devices/gropdf ++ ++bin_SCRIPTS += gropdf pdfmom ++EXTRA_DIST += \ ++ src/devices/gropdf/TODO \ ++ src/devices/gropdf/gropdf.pl \ ++ src/devices/gropdf/pdfmom.pl \ ++ src/devices/gropdf/gropdf.man \ ++ src/devices/gropdf/pdfmom.man ++ ++man1_MANS += \ ++ src/devices/gropdf/gropdf.n \ ++ src/devices/gropdf/pdfmom.n ++ ++gropdf: $(gropdf_dir)/gropdf.pl $(SH_DEPS_SED_SCRIPT) ++ $(RM) $@ ++ sed -f $(SH_DEPS_SED_SCRIPT) \ ++ -e "s|[@]VERSION[@]|$(VERSION)|" \ ++ -e "s|[@]PERL[@]|$(PERL)|" \ ++ -e "s|[@]GROFF_FONT_DIR[@]|$(fontpath)|" \ ++ -e "s|[@]RT_SEP[@]|$(RT_SEP)|" $(gropdf_dir)/gropdf.pl >$@ ++ chmod +x $@ ++ ++pdfmom: $(gropdf_dir)/pdfmom.pl $(SH_DEPS_SED_SCRIPT) ++ $(RM) $@ ++ sed -f $(SH_DEPS_SED_SCRIPT) \ ++ -e "s|[@]VERSION[@]|$(VERSION)|" \ ++ -e "s|[@]PERL[@]|$(PERL)|" $(gropdf_dir)/pdfmom.pl >$@ ++ chmod +x $@ +diff -Nuar groff-1.22.3.old/src/devices/gropdf/gropdf.man groff-1.22.3/src/devices/gropdf/gropdf.man +--- groff-1.22.3.old/src/devices/gropdf/gropdf.man 2014-11-04 10:38:35.319522822 +0200 ++++ groff-1.22.3/src/devices/gropdf/gropdf.man 2015-04-23 20:57:03.000000000 +0300 +@@ -4,6 +4,10 @@ + gropdf \- PDF driver for groff + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" license + .de co + Copyright \[co] 2011-2014 Free Software Foundation, Inc. +@@ -994,7 +998,7 @@ + Foo-Bar-Bold.pfa is \[oq]XY-Foo-Bar-Bold\[cq] (the PS font name is + stored in the + .B internalname +-field in the \[oq]FBB\[cq] file) and belongs to foundry \[oq]F\[]cq] ++field in the \[oq]FBB\[cq] file) and belongs to foundry \[oq]F\[cq] + thus the following line should be added to \[oq]download\[cq]: + . + .RS +@@ -1103,6 +1107,9 @@ + .co + . + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" mode: nroff + .\" End: +diff -Nuar groff-1.22.3.old/src/devices/gropdf/gropdf.pl groff-1.22.3/src/devices/gropdf/gropdf.pl +--- groff-1.22.3.old/src/devices/gropdf/gropdf.pl 2014-11-04 10:38:35.319522822 +0200 ++++ groff-1.22.3/src/devices/gropdf/gropdf.pl 2015-04-23 20:57:03.000000000 +0300 +@@ -2,8 +2,8 @@ + # + # gropdf : PDF post processor for groff + # +-# Copyright (C) 2011-2014 Free Software Foundation, Inc. +-# Written by Deri James ++# Copyright (C) 2011-2015 Free Software Foundation, Inc. ++# Written by Deri James + # + # This file is part of groff. + # +@@ -22,7 +22,24 @@ + + use strict; + use Getopt::Long qw(:config bundling); +-use Compress::Zlib; ++ ++my $gotzlib=0; ++ ++my $rc = eval ++{ ++ require Compress::Zlib; ++ Compress::Zlib->import(); ++ 1; ++}; ++ ++if($rc) ++{ ++ $gotzlib=1; ++} ++else ++{ ++ Msg(0,"Perl module Compress::Zlib not available - cannot compress this pdf"); ++} + + my %cfg; + +@@ -465,7 +482,7 @@ + sub PDFDate + { + my $dt=shift; +- return(sprintf("D:%04d%02d%02d%02d%02d%02d% +02d'00'",$dt->[5]+1900,$dt->[4]+1,$dt->[3],$dt->[2],$dt->[1],$dt->[0],( localtime time() + 3600*( 12 - (gmtime)[2] ) )[2] - 12)); ++ return(sprintf("D:%04d%02d%02d%02d%02d%02d%+03d'00'",$dt->[5]+1900,$dt->[4]+1,$dt->[3],$dt->[2],$dt->[1],$dt->[0],( localtime time() + 3600*( 12 - (gmtime)[2] ) )[2] - 12)); + } + + sub ToPoints +@@ -767,7 +784,10 @@ + } + elsif ($pdfmark=~m/(.+) \/OUT/) + { +- my @xwds=split(' ',"<< $1 >>"); ++ my $t=$1; ++ $t=~s/\\\) /\\\\\) /g; ++ $t=~s/\\e/\\\\/g; ++ my @xwds=split(' ',"<< $t >>"); + my $out=ParsePDFValue(\@xwds); + + my $this=[$out,[]]; +@@ -1404,7 +1424,7 @@ + sysseek(PD,$o->{STREAMPOS}->[0],0); + Msg(0,'Failed to read all the stream') if $l != sysread(PD,$o->{STREAM},$l); + +- if (exists($o->{OBJ}->{'Filter'}) and $o->{OBJ}->{'Filter'} eq '/FlateDecode') ++ if ($gotzlib and exists($o->{OBJ}->{'Filter'}) and $o->{OBJ}->{'Filter'} eq '/FlateDecode') + { + $o->{STREAM}=Compress::Zlib::uncompress($o->{STREAM}); + delete($o->{OBJ }->{'Filter'}); +@@ -1889,7 +1909,7 @@ + $obj[$ono]->{XREF}=$fct; + if (exists($obj[$ono]->{STREAM})) + { +- if (!$debug && !exists($obj[$ono]->{DATA}->{'Filter'})) ++ if ($gotzlib && !$debug && !exists($obj[$ono]->{DATA}->{'Filter'})) + { + $obj[$ono]->{STREAM}=Compress::Zlib::compress($obj[$ono]->{STREAM}); + $obj[$ono]->{DATA}->{'Filter'}=['/FlateDecode']; +@@ -2121,14 +2141,31 @@ + {'Type' => '/Font', + 'Subtype' => '/Type1', + 'BaseFont' => '/'.$fnt{internalname}, ++ 'Widths' => $fnt{WID}, ++ 'FirstChar' => 0, ++ 'LastChar' => $lastchr, + 'Encoding' => BuildObj($objct+1, + {'Type' => '/Encoding', + 'Differences' => $fnt{GNO} + } +- ) ++ ), ++ 'FontDescriptor' => BuildObj($objct+2, ++ {'Type' => '/FontDescriptor', ++ 'FontName' => '/'.$fnt{internalname}, ++ 'Flags' => $t1flags, ++ 'FontBBox' => \@fntbbox, ++ 'ItalicAngle' => $slant, ++ 'Ascent' => $ascent, ++ 'Descent' => $fntbbox[1], ++ 'CapHeight' => $capheight, ++ 'StemV' => 0, ++ 'CharSet' => "($charset)", ++ } ++ ) + } + ); +- $objct+=1; ++ ++ $objct+=2; + $fontlst{$fontno}->{NM}='/F'.$fontno; + $pages->{'Resources'}->{'Font'}->{'F'.$fontno}=$fontlst{$fontno}->{OBJ}; + $fontlst{$fontno}->{FNT}=\%fnt; +@@ -3029,6 +3066,7 @@ + my $txt=shift; + my $w=0; + my $ck=0; ++ $txt=~s/^\\(\d\d\d)/chr($1)/e; + + foreach my $c (split('',$txt)) + { +@@ -3223,7 +3261,7 @@ + { + $fnt->{GNM}->{$chnm}=$unused++; + $fnt->{GNO}->[$unused]=$fnt->{GNO}->[$ch+1]; +- $fnt->{WID}->[$unused]=$fnt->{WID}->[$ch+1]; ++ $fnt->{WID}->[$unused]=$fnt->{WID}->[$ch]; + $ch=$unused-1; + return($ch); + } +diff -Nuar groff-1.22.3.old/src/devices/gropdf/Makefile.sub groff-1.22.3/src/devices/gropdf/Makefile.sub +--- groff-1.22.3.old/src/devices/gropdf/Makefile.sub 2014-11-04 10:38:35.319522822 +0200 ++++ groff-1.22.3/src/devices/gropdf/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,75 +0,0 @@ +-# Makefile.sub for `gropdf' +-# +-# File position: /src/devices/gropbf/Makefile.sub +-# +-# Copyright (C) 2011-2014 Free Software Foundation, Inc. +-# Written by Deri James +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-######################################################################## +- +-MAN1=\ +- gropdf.n \ +- pdfmom.n +- +-CMDFILES=\ +- gropdf \ +- pdfmom +- +-MOSTLYCLEANADD=\ +- gropdf \ +- pdfmom \ +- $(MAN1) +- +-RM=rm -f +- +-all: gropdf pdfmom +- +- +-gropdf: gropdf.pl $(SH_DEPS_SED_SCRIPT) +- $(RM) $@ +- sed -f $(SH_DEPS_SED_SCRIPT) \ +- -e "s|@VERSION@|$(version)$(revision)|" \ +- -e "s|@PERL@|$(PERL)|" \ +- -e "s|@GROFF_FONT_DIR@|$(fontpath)|" \ +- -e "s|@RT_SEP@|$(RT_SEP)|" $(srcdir)/gropdf.pl >$@ +- chmod +x $@ +- +-pdfmom: pdfmom.pl $(SH_DEPS_SED_SCRIPT) +- $(RM) $@ +- sed -f $(SH_DEPS_SED_SCRIPT) \ +- -e "s|@VERSION@|$(version)$(revision)|" \ +- -e "s|@PERL@|$(PERL)|" $(srcdir)/pdfmom.pl >$@ +- chmod +x $@ +- +-install_data: +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- for f in $(CMDFILES); do \ +- $(RM) $(DESTDIR)$(bindir)/$$f; \ +- $(INSTALL_SCRIPT) $$f $(DESTDIR)$(bindir)/$$f; \ +- done +- +-uninstall_sub: +- -for f in $(CMDFILES); do $(RM) $(DESTDIR)$(bindir)/$$f; done +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/devices/gropdf/pdfmom.man groff-1.22.3/src/devices/gropdf/pdfmom.man +--- groff-1.22.3.old/src/devices/gropdf/pdfmom.man 2014-11-04 10:38:35.319522822 +0200 ++++ groff-1.22.3/src/devices/gropdf/pdfmom.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 2012-2014 Free Software Foundation, Inc. ++Copyright \(co 2012-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -77,7 +77,7 @@ + .B \-Tpdf + option (which is the default), + .B pdfmom +-processes files using groff\[aq]s native PDF driver, ++processes files using groff\(aqs native PDF driver, + .BR gropdf . + . + If +@@ -85,7 +85,7 @@ + is given, processing is passed over to + .BR pdfroff , + which uses +-.BR groff \[aq]s ++.BR groff \(aqs + PostScript driver. + . + In either case, multiple runs of the source file are peformed in +@@ -144,7 +144,7 @@ + .P + .RS 2 + \&.\|.\|.: +-.B can\[aq]t transparently output node at top level ++.B can\(aqt transparently output node at top level + .RE + . + .P +diff -Nuar groff-1.22.3.old/src/devices/grops/.gitignore groff-1.22.3/src/devices/grops/.gitignore +--- groff-1.22.3.old/src/devices/grops/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grops/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++grops ++grops.n +diff -Nuar groff-1.22.3.old/src/devices/grops/grops.am groff-1.22.3/src/devices/grops/grops.am +--- groff-1.22.3.old/src/devices/grops/grops.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grops/grops.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,32 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += grops ++grops_SOURCES = \ ++ src/devices/grops/ps.cpp \ ++ src/devices/grops/psrm.cpp \ ++ src/devices/grops/ps.h ++grops_LDADD = $(LIBM) \ ++ libdriver.a \ ++ libgroff.a \ ++ lib/libgnu.a ++man1_MANS += src/devices/grops/grops.n ++EXTRA_DIST += \ ++ src/devices/grops/grops.man \ ++ src/devices/grops/psfig.diff \ ++ src/devices/grops/TODO +diff -Nuar groff-1.22.3.old/src/devices/grops/grops.man groff-1.22.3/src/devices/grops/grops.man +--- groff-1.22.3.old/src/devices/grops/grops.man 2014-11-04 10:38:35.259523572 +0200 ++++ groff-1.22.3/src/devices/grops/grops.man 2015-04-23 20:57:03.000000000 +0300 +@@ -3,6 +3,10 @@ + grops \- PostScript driver for groff + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" license + .de co + Copyright \[co] 1989-2014 Free Software Foundation, Inc. +@@ -1494,6 +1498,9 @@ + .co + . + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" mode: nroff + .\" End: +diff -Nuar groff-1.22.3.old/src/devices/grops/Makefile.sub groff-1.22.3/src/devices/grops/Makefile.sub +--- groff-1.22.3.old/src/devices/grops/Makefile.sub 2014-11-04 10:38:35.260523559 +0200 ++++ groff-1.22.3/src/devices/grops/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,44 +0,0 @@ +-# Makefile.sub for `grops' +-# +-# File position: /src/devices/grops/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=grops$(EXEEXT) +-MAN1=grops.n +-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU) +-MLIB=$(LIBM) +-OBJS=\ +- ps.$(OBJEXT) \ +- psrm.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/ps.cpp \ +- $(srcdir)/psrm.cpp +-HDRS=\ +- $(srcdir)/ps.h +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/devices/grotty/.gitignore groff-1.22.3/src/devices/grotty/.gitignore +--- groff-1.22.3.old/src/devices/grotty/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grotty/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++grotty ++grotty.n +diff -Nuar groff-1.22.3.old/src/devices/grotty/grotty.am groff-1.22.3/src/devices/grotty/grotty.am +--- groff-1.22.3.old/src/devices/grotty/grotty.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/grotty/grotty.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,28 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += grotty ++grotty_SOURCES = src/devices/grotty/tty.cpp ++grotty_LDADD = $(LIBM) \ ++ libdriver.a \ ++ libgroff.a \ ++ lib/libgnu.a ++man1_MANS += src/devices/grotty/grotty.n ++EXTRA_DIST += \ ++ src/devices/grotty/grotty.man \ ++ src/devices/grotty/TODO +diff -Nuar groff-1.22.3.old/src/devices/grotty/grotty.man groff-1.22.3/src/devices/grotty/grotty.man +--- groff-1.22.3.old/src/devices/grotty/grotty.man 2014-11-04 10:38:35.264523509 +0200 ++++ groff-1.22.3/src/devices/grotty/grotty.man 2015-04-23 20:57:03.000000000 +0300 +@@ -6,7 +6,7 @@ + . + .\" license + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +diff -Nuar groff-1.22.3.old/src/devices/grotty/Makefile.sub groff-1.22.3/src/devices/grotty/Makefile.sub +--- groff-1.22.3.old/src/devices/grotty/Makefile.sub 2014-11-04 10:38:35.265523497 +0200 ++++ groff-1.22.3/src/devices/grotty/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,38 +0,0 @@ +-# Makefile.sub for `grotty' +-# +-# File position: /src/devices/grotty/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=grotty$(EXEEXT) +-MAN1=grotty.n +-XLIBS=$(LIBDRIVER) $(LIBGROFF) $(LIBGNU) +-MLIB=$(LIBM) +-OBJS=tty.$(OBJEXT) +-CCSRCS=$(srcdir)/tty.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/devices/xditview/.gitignore groff-1.22.3/src/devices/xditview/.gitignore +--- groff-1.22.3.old/src/devices/xditview/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/xditview/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,4 @@ ++Makefile.dep ++GXditview-ad.h ++gxditview.n ++gxditview +diff -Nuar groff-1.22.3.old/src/devices/xditview/gxditview.man groff-1.22.3/src/devices/xditview/gxditview.man +--- groff-1.22.3.old/src/devices/xditview/gxditview.man 2014-11-04 10:38:35.326522734 +0200 ++++ groff-1.22.3/src/devices/xditview/gxditview.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989, Massachusetts Institute of Technology. ++Copyright \(co 1989, Massachusetts Institute of Technology. + .br + See + .BR X (7) +diff -Nuar groff-1.22.3.old/src/devices/xditview/Makefile.sub groff-1.22.3/src/devices/xditview/Makefile.sub +--- groff-1.22.3.old/src/devices/xditview/Makefile.sub 2014-11-04 10:38:35.326522734 +0200 ++++ groff-1.22.3/src/devices/xditview/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,89 +0,0 @@ +-# Makefile.sub for `xditview' +-# +-# File position: /src/devices/xditview/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=gxditview$(EXEEXT) +-MAN1=gxditview.n +-MLIB=$(LIBM) +-XLIBS=$(LIBXUTIL) +-EXTRA_CFLAGS=$(X_CFLAGS) -Dlint +-EXTRA_LDFLAGS=$(X_LIBS) $(X_PRE_LIBS) -lXaw -lXmu -lXt -lX11 $(X_EXTRA_LIBS) +-OBJS=\ +- device.$(OBJEXT) \ +- draw.$(OBJEXT) \ +- Dvi.$(OBJEXT) \ +- font.$(OBJEXT) \ +- lex.$(OBJEXT) \ +- page.$(OBJEXT) \ +- parse.$(OBJEXT) \ +- xditview.$(OBJEXT) +-CSRCS=\ +- $(srcdir)/device.c \ +- $(srcdir)/draw.c \ +- $(srcdir)/Dvi.c \ +- $(srcdir)/font.c \ +- $(srcdir)/lex.c \ +- $(srcdir)/page.c \ +- $(srcdir)/parse.c \ +- $(srcdir)/xditview.c +-HDRS=\ +- $(srcdir)/device.h \ +- $(srcdir)/Dvi.h \ +- $(srcdir)/DviP.h \ +- $(srcdir)/Menu.h +-GENHDRS=GXditview-ad.h +-RM=rm -f +- +-all depend: $(GENHDRS) +- +-GXditview-ad.h: $(srcdir)/GXditview.ad +- @echo Making $@ +- $(SHELL) $(srcdir)/ad2c $(srcdir)/GXditview.ad > $@ +- +-install_data: $(srcdir)/GXditview.ad $(srcdir)/GXditview-color.ad +- -test -d $(DESTDIR)$(appresdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(appresdir) +- if test -f $(DESTDIR)$(appresdir)/GXditview; then \ +- mv $(DESTDIR)$(appresdir)/GXditview \ +- $(DESTDIR)$(appresdir)/GXditview.old; \ +- fi +- if test -f $(DESTDIR)$(appresdir)/GXditview-color; then \ +- mv $(DESTDIR)$(appresdir)/GXditview-color \ +- $(DESTDIR)$(appresdir)/GXditview-color.old; \ +- fi +- $(INSTALL_DATA) $(srcdir)/GXditview.ad \ +- $(DESTDIR)$(appresdir)/GXditview +- $(INSTALL_DATA) $(srcdir)/GXditview-color.ad \ +- $(DESTDIR)$(appresdir)/GXditview-color +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(appresdir)/GXditview +- $(RM) $(DESTDIR)$(appresdir)/GXditview-color +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/devices/xditview/xditview.am groff-1.22.3/src/devices/xditview/xditview.am +--- groff-1.22.3.old/src/devices/xditview/xditview.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/devices/xditview/xditview.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,108 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++GXDITVIEWSOURCES = \ ++ src/devices/xditview/device.c \ ++ src/devices/xditview/draw.c \ ++ src/devices/xditview/Dvi.c \ ++ src/devices/xditview/font.c \ ++ src/devices/xditview/lex.c \ ++ src/devices/xditview/page.c \ ++ src/devices/xditview/parse.c \ ++ src/devices/xditview/xditview.c \ ++ src/devices/xditview/device.h \ ++ src/devices/xditview/DviP.h \ ++ src/devices/xditview/Menu.h \ ++ src/devices/xditview/Dvi.h ++ ++if WITHOUT_X11 ++EXTRA_DIST += $(GXDITVIEWSOURCES) ++else ++xditview_srcdir = $(top_srcdir)/src/devices/xditview ++bin_PROGRAMS += gxditview ++gxditview_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) -Dlint \ ++ -I$(top_builddir)/src/devices/xditview ++gxditview_LDADD = $(X_LIBS) $(X_PRE_LIBS) -lXaw -lXmu -lXt -lX11 \ ++ $(X_EXTRA_LIBS) $(LIBM) libxutil.a ++XDITVIEW_GENHDRS = src/devices/xditview/GXditview-ad.h ++gxditview_SOURCES = $(GXDITVIEWSOURCES) ++nodist_gxditview_SOURCES = $(XDITVIEW_GENHDRS) ++CLEANFILES += $(XDITVIEW_GENHDRS) ++ ++man1_MANS += src/devices/xditview/gxditview.n ++ ++# Because we defined gxditview_CPPFLAGS, automake renames all the xditview's ++# objects, adding an "gxditview-" prefix. ++src/devices/xditview/gxditview-device.$(OBJEXT): defs.h ++src/devices/xditview/gxditview-xditview.$(OBJEXT): $(XDITVIEW_GENHDRS) ++ ++src/devices/xditview/GXditview-ad.h: $(xditview_srcdir)/GXditview.ad ++ @echo Making $@ ++ $(SHELL) $(xditview_srcdir)/ad2c $(xditview_srcdir)/GXditview.ad > $@ ++endif ++ ++EXTRA_DIST += \ ++ src/devices/xditview/ad2c \ ++ src/devices/xditview/ChangeLog \ ++ src/devices/xditview/DESC.in \ ++ src/devices/xditview/FontMap \ ++ src/devices/xditview/GXditview-color.ad \ ++ src/devices/xditview/GXditview.ad \ ++ src/devices/xditview/README \ ++ src/devices/xditview/TODO \ ++ src/devices/xditview/gray1.bm \ ++ src/devices/xditview/gray2.bm \ ++ src/devices/xditview/gray3.bm \ ++ src/devices/xditview/gray4.bm \ ++ src/devices/xditview/gray5.bm \ ++ src/devices/xditview/gray6.bm \ ++ src/devices/xditview/gray7.bm \ ++ src/devices/xditview/gray8.bm \ ++ src/devices/xditview/xdit.bm \ ++ src/devices/xditview/xdit_mask.bm \ ++ src/devices/xditview/gxditview.man ++ ++# Custom installation of GXditview.ad and GXditview-color.ad ++install-data-local: install_xditview ++uninstall-local: uninstall_xditview ++ ++if WITHOUT_X11 ++install_xditview: ++uninstall_xditview: ++else ++install_xditview: $(xditview_srcdir)/GXditview.ad $(xditview_srcdir)/GXditview-color.ad ++ -test -d $(DESTDIR)$(appresdir) \ ++ || $(mkinstalldirs) $(DESTDIR)$(appresdir) ++ if test -f $(DESTDIR)$(appresdir)/GXditview; then \ ++ mv $(DESTDIR)$(appresdir)/GXditview \ ++ $(DESTDIR)$(appresdir)/GXditview.old; \ ++ fi ++ if test -f $(DESTDIR)$(appresdir)/GXditview-color; then \ ++ mv $(DESTDIR)$(appresdir)/GXditview-color \ ++ $(DESTDIR)$(appresdir)/GXditview-color.old; \ ++ fi ++ $(INSTALL_DATA) $(xditview_srcdir)/GXditview.ad \ ++ $(DESTDIR)$(appresdir)/GXditview ++ $(INSTALL_DATA) $(xditview_srcdir)/GXditview-color.ad \ ++ $(DESTDIR)$(appresdir)/GXditview-color ++ ++uninstall_xditview: ++ rm -f $(DESTDIR)$(appresdir)/GXditview ++ rm -f $(DESTDIR)$(appresdir)/GXditview-color ++ ++endif +diff -Nuar groff-1.22.3.old/src/include/config.hin groff-1.22.3/src/include/config.hin +--- groff-1.22.3.old/src/include/config.hin 2014-11-04 10:38:35.160524810 +0200 ++++ groff-1.22.3/src/include/config.hin 1970-01-01 02:00:00.000000000 +0200 +@@ -1,292 +0,0 @@ +-/* src/include/config.hin. Generated from configure.ac by autoheader. */ +- +-/* Define if building universal (internal helper macro) */ +-#undef AC_APPLE_UNIVERSAL_BUILD +- +-/* Define if your C++ doesn't understand `delete []'. */ +-#undef ARRAY_DELETE_NEEDS_SIZE +- +-/* Define if you have a C++ . */ +-#undef HAVE_CC_INTTYPES_H +- +-/* Define if you have a C++ . */ +-#undef HAVE_CC_LIMITS_H +- +-/* Define if you have a C++ . */ +-#undef HAVE_CC_OSFCN_H +- +-/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you +- don't. */ +-#undef HAVE_DECL_GETC_UNLOCKED +- +-/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you +- don't. */ +-#undef HAVE_DECL_SYS_SIGLIST +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_DIRECT_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_DIRENT_H +- +-/* Define to 1 if you have the `fmod' function. */ +-#undef HAVE_FMOD +- +-/* Define to 1 if you have the `getcwd' function. */ +-#undef HAVE_GETCWD +- +-/* Define to 1 if you have the `getpagesize' function. */ +-#undef HAVE_GETPAGESIZE +- +-/* Define to 1 if you have the `gettimeofday' function. */ +-#undef HAVE_GETTIMEOFDAY +- +-/* Define if you have the iconv() function and it works. */ +-#undef HAVE_ICONV +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_INTTYPES_H +- +-/* Define to 1 if you have the `isatty' function. */ +-#undef HAVE_ISATTY +- +-/* Define to 1 if you have the `kill' function. */ +-#undef HAVE_KILL +- +-/* Define if you have and nl_langinfo(CODESET). */ +-#undef HAVE_LANGINFO_CODESET +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_LIMITS_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_MATH_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_MEMORY_H +- +-/* Define if you have mkstemp(). */ +-#undef HAVE_MKSTEMP +- +-/* Define to 1 if you have a working `mmap' system call. */ +-#undef HAVE_MMAP +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_PROCESS_H +- +-/* Define to 1 if you have the `putenv' function. */ +-#undef HAVE_PUTENV +- +-/* Define to 1 if you have the `rename' function. */ +-#undef HAVE_RENAME +- +-/* Define to 1 if you have the `setlocale' function. */ +-#undef HAVE_SETLOCALE +- +-/* Define to 1 if you have the `snprintf' function. */ +-#undef HAVE_SNPRINTF +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_STDDEF_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_STDINT_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_STDLIB_H +- +-/* Define to 1 if you have the `strcasecmp' function. */ +-#undef HAVE_STRCASECMP +- +-/* Define to 1 if you have the `strerror' function. */ +-#undef HAVE_STRERROR +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_STRINGS_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_STRING_H +- +-/* Define to 1 if you have the `strncasecmp' function. */ +-#undef HAVE_STRNCASECMP +- +-/* Define to 1 if you have the `strsep' function. */ +-#undef HAVE_STRSEP +- +-/* Define to 1 if you have the `strtol' function. */ +-#undef HAVE_STRTOL +- +-/* Define if defines struct exception. */ +-#undef HAVE_STRUCT_EXCEPTION +- +-/* Define to 1 if you have the `symlink' function. */ +-#undef HAVE_SYMLINK +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_SYS_DIR_H +- +-/* Define if you have sys_errlist in , , or . */ +-#undef HAVE_SYS_ERRLIST +- +-/* Define if you have sys_nerr in , , or . */ +-#undef HAVE_SYS_NERR +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_SYS_PARAM_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_SYS_STAT_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_SYS_TIME_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_SYS_TYPES_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_UNISTD_H +- +-/* Define to 1 if you have the `vsnprintf' function. */ +-#undef HAVE_VSNPRINTF +- +-/* Define to 1 if O_NOATIME works. */ +-#undef HAVE_WORKING_O_NOATIME +- +-/* Define to 1 if O_NOFOLLOW works. */ +-#undef HAVE_WORKING_O_NOFOLLOW +- +-/* Define as const if the declaration of iconv() needs const. */ +-#undef ICONV_CONST +- +-/* Define if the host's encoding is EBCDIC. */ +-#undef IS_EBCDIC_HOST +- +-/* Define if localtime() takes a long * not a time_t *. */ +-#undef LONG_FOR_TIME_T +- +-/* Define if your C++ doesn't declare gettimeofday(). */ +-#undef NEED_DECLARATION_GETTIMEOFDAY +- +-/* Define if your C++ doesn't declare hypot(). */ +-#undef NEED_DECLARATION_HYPOT +- +-/* Define if your C++ doesn't declare pclose(). */ +-#undef NEED_DECLARATION_PCLOSE +- +-/* Define if your C++ doesn't declare popen(). */ +-#undef NEED_DECLARATION_POPEN +- +-/* Define if your C++ doesn't declare putenv(). */ +-#undef NEED_DECLARATION_PUTENV +- +-/* Define if your C++ doesn't declare rand(). */ +-#undef NEED_DECLARATION_RAND +- +-/* Define if your C++ doesn't declare snprintf(). */ +-#undef NEED_DECLARATION_SNPRINTF +- +-/* Define if your C++ doesn't declare srand(). */ +-#undef NEED_DECLARATION_SRAND +- +-/* Define if your C++ doesn't declare strcasecmp(). */ +-#undef NEED_DECLARATION_STRCASECMP +- +-/* Define if your C++ doesn't declare strncasecmp(). */ +-#undef NEED_DECLARATION_STRNCASECMP +- +-/* Define if your C++ doesn't declare vfprintf(). */ +-#undef NEED_DECLARATION_VFPRINTF +- +-/* Define if your C++ doesn't declare vsnprintf(). */ +-#undef NEED_DECLARATION_VSNPRINTF +- +-/* Define to the address where bug reports for this package should be sent. */ +-#undef PACKAGE_BUGREPORT +- +-/* Define to the full name of this package. */ +-#undef PACKAGE_NAME +- +-/* Define to the full name and version of this package. */ +-#undef PACKAGE_STRING +- +-/* Define to the one symbol short name of this package. */ +-#undef PACKAGE_TARNAME +- +-/* Define to the home page for this package. */ +-#undef PACKAGE_URL +- +-/* Define to the version of this package. */ +-#undef PACKAGE_VERSION +- +-/* Define if the printer's page size is A4. */ +-#undef PAGEA4 +- +-/* Define as the return type of signal handlers (`int' or `void'). */ +-#undef RETSIGTYPE +- +-/* Define if srand() returns void not int. */ +-#undef RET_TYPE_SRAND_IS_VOID +- +-/* Define to 1 if you have the ANSI C header files. */ +-#undef STDC_HEADERS +- +-/* Define if your C++ compiler uses a traditional (Reiser) preprocessor. */ +-#undef TRADITIONAL_CPP +- +-/* Enable extensions on AIX 3, Interix. */ +-#ifndef _ALL_SOURCE +-# undef _ALL_SOURCE +-#endif +-/* Enable GNU extensions on systems that have them. */ +-#ifndef _GNU_SOURCE +-# undef _GNU_SOURCE +-#endif +-/* Enable threading extensions on Solaris. */ +-#ifndef _POSIX_PTHREAD_SEMANTICS +-# undef _POSIX_PTHREAD_SEMANTICS +-#endif +-/* Enable extensions on HP NonStop. */ +-#ifndef _TANDEM_SOURCE +-# undef _TANDEM_SOURCE +-#endif +-/* Enable general extensions on Solaris. */ +-#ifndef __EXTENSIONS__ +-# undef __EXTENSIONS__ +-#endif +- +- +-/* Define if the 0200 bit of the status returned by wait() indicates whether a +- core image was produced for a process that was terminated by a signal. */ +-#undef WCOREFLAG +- +-/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most +- significant byte first (like Motorola and SPARC, unlike Intel). */ +-#if defined AC_APPLE_UNIVERSAL_BUILD +-# if defined __BIG_ENDIAN__ +-# define WORDS_BIGENDIAN 1 +-# endif +-#else +-# ifndef WORDS_BIGENDIAN +-# undef WORDS_BIGENDIAN +-# endif +-#endif +- +-/* Define to 1 if the X Window System is missing or not being used. */ +-#undef X_DISPLAY_MISSING +- +-/* Define to 1 if on MINIX. */ +-#undef _MINIX +- +-/* Define to 2 if the system does not provide POSIX.1 features except with +- this defined. */ +-#undef _POSIX_1_SOURCE +- +-/* Define if -D_POSIX_SOURCE is necessary. */ +-#undef _POSIX_SOURCE +- +-/* Define if you have ISC 3.x or 4.x. */ +-#undef _SYSV3 +- +-/* Define uintmax_t to `unsigned long' or `unsigned long long' if +- does not exist. */ +-#undef uintmax_t +diff -Nuar groff-1.22.3.old/src/include/.gitignore groff-1.22.3/src/include/.gitignore +--- groff-1.22.3.old/src/include/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/include/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,2 @@ ++config.h ++defs.h +diff -Nuar groff-1.22.3.old/src/include/include.am groff-1.22.3/src/include/include.am +--- groff-1.22.3.old/src/include/include.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/include/include.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,42 @@ ++# Automake rules for `include' ++# ++# File position: /src/include/include.am ++# ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see ++# . ++# ++######################################################################## ++ ++nodist_noinst_HEADERS = defs.h ++CLEANFILES += defs.h ++defs.h: config.status ++ @$(SHELL) $(top_srcdir)/gendef.sh defs.h \ ++ "PROG_PREFIX=\"$(g)\"" \ ++ "DEVICE=\"$(DEVICE)\"" \ ++ "INSTALLPATH=\"$(prefix)\"" \ ++ "BINPATH=\"$(bindir)\"" \ ++ "FONTPATH=\"$(fontpath)\"" \ ++ "MACROPATH=\"$(tmacpath)\"" \ ++ "INDEX_SUFFIX=\"$(indexext)\"" \ ++ "COMMON_WORDS_FILE=\"$(common_words_file)\"" \ ++ "DEFAULT_INDEX_DIR=\"$(indexdir)\"" \ ++ "DEFAULT_INDEX_NAME=\"$(indexname)\"" \ ++ "DEFAULT_INDEX=\"$(indexdir)/$(indexname)\"" ++ ++dist-hook: dist_include ++dist_include: ++ chmod u+w $(distdir)/src/include ++ cp -f $(top_srcdir)/src/include/*.h $(distdir)/src/include +diff -Nuar groff-1.22.3.old/src/include/lf.h groff-1.22.3/src/include/lf.h +--- groff-1.22.3.old/src/include/lf.h 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/include/lf.h 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,21 @@ ++// -*- C++ -*- ++/* Copyright (C) 2014 Free Software Foundation, Inc. ++ Written by Werner Lemberg (wl@gnu.org) ++ ++This file is part of groff. ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation, either version 3 of the License, or ++(at your option) any later version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program. If not, see . */ ++ ++int interpret_lf_args(const char *p); ++void normalize_for_lf (string &fn); +diff -Nuar groff-1.22.3.old/src/include/lib.h groff-1.22.3/src/include/lib.h +--- groff-1.22.3.old/src/include/lib.h 2014-11-04 10:38:35.161524797 +0200 ++++ groff-1.22.3/src/include/lib.h 2015-04-23 20:57:03.000000000 +0300 +@@ -98,8 +98,6 @@ + size_t file_name_max(const char *fname); + size_t path_name_max(); + +-int interpret_lf_args(const char *p); +- + extern char invalid_char_table[]; + + inline int invalid_input_char(int c) +diff -Nuar groff-1.22.3.old/src/include/Makefile.sub groff-1.22.3/src/include/Makefile.sub +--- groff-1.22.3.old/src/include/Makefile.sub 2014-11-04 10:38:35.161524797 +0200 ++++ groff-1.22.3/src/include/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,82 +0,0 @@ +-# Makefile.sub for `include' +-# +-# File position: /src/include/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-HDRS=\ +- assert.h \ +- cmap.h \ +- cset.h \ +- color.h \ +- device.h \ +- driver.h \ +- DviChar.h \ +- errarg.h \ +- error.h \ +- font.h \ +- geometry.h \ +- getopt.h \ +- getopt_int.h \ +- gettext.h \ +- htmlhint.h \ +- index.h \ +- lib.h \ +- macropath.h \ +- nonposix.h \ +- posix.h \ +- printer.h \ +- ptable.h \ +- refid.h \ +- relocate.h \ +- search.h \ +- searchpath.h \ +- stringclass.h \ +- symbol.h \ +- unicode.h \ +- XFontName.h +-GENHDRS=defs.h +- +-all depend: $(GENHDRS) +- +-defs.h: FORCE +- @$(SHELL) $(top_srcdir)/gendef.sh defs.h \ +- "PROG_PREFIX=\"$(g)\"" \ +- "DEVICE=\"$(DEVICE)\"" \ +- "INSTALLPATH=\"$(prefix)\"" \ +- "BINPATH=\"$(bindir)\"" \ +- "FONTPATH=\"$(fontpath)\"" \ +- "MACROPATH=\"$(tmacpath)\"" \ +- "INDEX_SUFFIX=\"$(indexext)\"" \ +- "COMMON_WORDS_FILE=\"$(common_words_file)\"" \ +- "DEFAULT_INDEX_DIR=\"$(indexdir)\"" \ +- "DEFAULT_INDEX_NAME=\"$(indexname)\"" \ +- "DEFAULT_INDEX=\"$(indexdir)/$(indexname)\"" +- +-FORCE: +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/aclocal.m4 groff-1.22.3/src/libs/gnulib/aclocal.m4 +--- groff-1.22.3.old/src/libs/gnulib/aclocal.m4 2014-11-04 10:38:35.674518384 +0200 ++++ groff-1.22.3/src/libs/gnulib/aclocal.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1174 +0,0 @@ +-# generated automatically by aclocal 1.14 -*- Autoconf -*- +- +-# Copyright (C) 1996-2013 Free Software Foundation, Inc. +- +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +-# PARTICULAR PURPOSE. +- +-m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +-m4_ifndef([AC_AUTOCONF_VERSION], +- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +-[m4_warning([this file was generated for autoconf 2.69. +-You have another version of autoconf. It may work, but is not guaranteed to. +-If you have problems, you may need to regenerate the build system entirely. +-To do so, use the procedure documented by the package, typically 'autoreconf'.])]) +- +-# Copyright (C) 2002-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# AM_AUTOMAKE_VERSION(VERSION) +-# ---------------------------- +-# Automake X.Y traces this macro to ensure aclocal.m4 has been +-# generated from the m4 files accompanying Automake X.Y. +-# (This private macro should not be called outside this file.) +-AC_DEFUN([AM_AUTOMAKE_VERSION], +-[am__api_version='1.14' +-dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +-dnl require some minimum version. Point them to the right macro. +-m4_if([$1], [1.14], [], +- [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +-]) +- +-# _AM_AUTOCONF_VERSION(VERSION) +-# ----------------------------- +-# aclocal traces this macro to find the Autoconf version. +-# This is a private macro too. Using m4_define simplifies +-# the logic in aclocal, which can simply ignore this definition. +-m4_define([_AM_AUTOCONF_VERSION], []) +- +-# AM_SET_CURRENT_AUTOMAKE_VERSION +-# ------------------------------- +-# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +-# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +-[AM_AUTOMAKE_VERSION([1.14])dnl +-m4_ifndef([AC_AUTOCONF_VERSION], +- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +-_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) +- +-# AM_AUX_DIR_EXPAND -*- Autoconf -*- +- +-# Copyright (C) 2001-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +-# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +-# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +-# +-# Of course, Automake must honor this variable whenever it calls a +-# tool from the auxiliary directory. The problem is that $srcdir (and +-# therefore $ac_aux_dir as well) can be either absolute or relative, +-# depending on how configure is run. This is pretty annoying, since +-# it makes $ac_aux_dir quite unusable in subdirectories: in the top +-# source directory, any form will work fine, but in subdirectories a +-# relative path needs to be adjusted first. +-# +-# $ac_aux_dir/missing +-# fails when called from a subdirectory if $ac_aux_dir is relative +-# $top_srcdir/$ac_aux_dir/missing +-# fails if $ac_aux_dir is absolute, +-# fails when called from a subdirectory in a VPATH build with +-# a relative $ac_aux_dir +-# +-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +-# are both prefixed by $srcdir. In an in-source build this is usually +-# harmless because $srcdir is '.', but things will broke when you +-# start a VPATH build or use an absolute $srcdir. +-# +-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +-# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +-# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +-# and then we would define $MISSING as +-# MISSING="\${SHELL} $am_aux_dir/missing" +-# This will work as long as MISSING is not called from configure, because +-# unfortunately $(top_srcdir) has no meaning in configure. +-# However there are other variables, like CC, which are often used in +-# configure, and could therefore not use this "fixed" $ac_aux_dir. +-# +-# Another solution, used here, is to always expand $ac_aux_dir to an +-# absolute PATH. The drawback is that using absolute paths prevent a +-# configured tree to be moved without reconfiguration. +- +-AC_DEFUN([AM_AUX_DIR_EXPAND], +-[dnl Rely on autoconf to set up CDPATH properly. +-AC_PREREQ([2.50])dnl +-# expand $ac_aux_dir to an absolute path +-am_aux_dir=`cd $ac_aux_dir && pwd` +-]) +- +-# AM_CONDITIONAL -*- Autoconf -*- +- +-# Copyright (C) 1997-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# AM_CONDITIONAL(NAME, SHELL-CONDITION) +-# ------------------------------------- +-# Define a conditional. +-AC_DEFUN([AM_CONDITIONAL], +-[AC_PREREQ([2.52])dnl +- m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], +- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +-AC_SUBST([$1_TRUE])dnl +-AC_SUBST([$1_FALSE])dnl +-_AM_SUBST_NOTMAKE([$1_TRUE])dnl +-_AM_SUBST_NOTMAKE([$1_FALSE])dnl +-m4_define([_AM_COND_VALUE_$1], [$2])dnl +-if $2; then +- $1_TRUE= +- $1_FALSE='#' +-else +- $1_TRUE='#' +- $1_FALSE= +-fi +-AC_CONFIG_COMMANDS_PRE( +-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then +- AC_MSG_ERROR([[conditional "$1" was never defined. +-Usually this means the macro was only invoked conditionally.]]) +-fi])]) +- +-# Copyright (C) 1999-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +- +-# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +-# written in clear, in which case automake, when reading aclocal.m4, +-# will think it sees a *use*, and therefore will trigger all it's +-# C support machinery. Also note that it means that autoscan, seeing +-# CC etc. in the Makefile, will ask for an AC_PROG_CC use... +- +- +-# _AM_DEPENDENCIES(NAME) +-# ---------------------- +-# See how the compiler implements dependency checking. +-# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +-# We try a few techniques and use that to set a single cache variable. +-# +-# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +-# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +-# dependency, and given that the user is not expected to run this macro, +-# just rely on AC_PROG_CC. +-AC_DEFUN([_AM_DEPENDENCIES], +-[AC_REQUIRE([AM_SET_DEPDIR])dnl +-AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +-AC_REQUIRE([AM_MAKE_INCLUDE])dnl +-AC_REQUIRE([AM_DEP_TRACK])dnl +- +-m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], +- [$1], [CXX], [depcc="$CXX" am_compiler_list=], +- [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], +- [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], +- [$1], [UPC], [depcc="$UPC" am_compiler_list=], +- [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], +- [depcc="$$1" am_compiler_list=]) +- +-AC_CACHE_CHECK([dependency style of $depcc], +- [am_cv_$1_dependencies_compiler_type], +-[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then +- # We make a subdir and do the tests there. Otherwise we can end up +- # making bogus files that we don't know about and never remove. For +- # instance it was reported that on HP-UX the gcc test will end up +- # making a dummy file named 'D' -- because '-MD' means "put the output +- # in D". +- rm -rf conftest.dir +- mkdir conftest.dir +- # Copy depcomp to subdir because otherwise we won't find it if we're +- # using a relative directory. +- cp "$am_depcomp" conftest.dir +- cd conftest.dir +- # We will build objects and dependencies in a subdirectory because +- # it helps to detect inapplicable dependency modes. For instance +- # both Tru64's cc and ICC support -MD to output dependencies as a +- # side effect of compilation, but ICC will put the dependencies in +- # the current directory while Tru64 will put them in the object +- # directory. +- mkdir sub +- +- am_cv_$1_dependencies_compiler_type=none +- if test "$am_compiler_list" = ""; then +- am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` +- fi +- am__universal=false +- m4_case([$1], [CC], +- [case " $depcc " in #( +- *\ -arch\ *\ -arch\ *) am__universal=true ;; +- esac], +- [CXX], +- [case " $depcc " in #( +- *\ -arch\ *\ -arch\ *) am__universal=true ;; +- esac]) +- +- for depmode in $am_compiler_list; do +- # Setup a source with many dependencies, because some compilers +- # like to wrap large dependency lists on column 80 (with \), and +- # we should not choose a depcomp mode which is confused by this. +- # +- # We need to recreate these files for each test, as the compiler may +- # overwrite some of them when testing with obscure command lines. +- # This happens at least with the AIX C compiler. +- : > sub/conftest.c +- for i in 1 2 3 4 5 6; do +- echo '#include "conftst'$i'.h"' >> sub/conftest.c +- # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with +- # Solaris 10 /bin/sh. +- echo '/* dummy */' > sub/conftst$i.h +- done +- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf +- +- # We check with '-c' and '-o' for the sake of the "dashmstdout" +- # mode. It turns out that the SunPro C++ compiler does not properly +- # handle '-M -o', and we need to detect this. Also, some Intel +- # versions had trouble with output in subdirs. +- am__obj=sub/conftest.${OBJEXT-o} +- am__minus_obj="-o $am__obj" +- case $depmode in +- gcc) +- # This depmode causes a compiler race in universal mode. +- test "$am__universal" = false || continue +- ;; +- nosideeffect) +- # After this tag, mechanisms are not by side-effect, so they'll +- # only be used when explicitly requested. +- if test "x$enable_dependency_tracking" = xyes; then +- continue +- else +- break +- fi +- ;; +- msvc7 | msvc7msys | msvisualcpp | msvcmsys) +- # This compiler won't grok '-c -o', but also, the minuso test has +- # not run yet. These depmodes are late enough in the game, and +- # so weak that their functioning should not be impacted. +- am__obj=conftest.${OBJEXT-o} +- am__minus_obj= +- ;; +- none) break ;; +- esac +- if depmode=$depmode \ +- source=sub/conftest.c object=$am__obj \ +- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ +- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ +- >/dev/null 2>conftest.err && +- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && +- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && +- grep $am__obj sub/conftest.Po > /dev/null 2>&1 && +- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then +- # icc doesn't choke on unknown options, it will just issue warnings +- # or remarks (even with -Werror). So we grep stderr for any message +- # that says an option was ignored or not supported. +- # When given -MP, icc 7.0 and 7.1 complain thusly: +- # icc: Command line warning: ignoring option '-M'; no argument required +- # The diagnosis changed in icc 8.0: +- # icc: Command line remark: option '-MP' not supported +- if (grep 'ignoring option' conftest.err || +- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else +- am_cv_$1_dependencies_compiler_type=$depmode +- break +- fi +- fi +- done +- +- cd .. +- rm -rf conftest.dir +-else +- am_cv_$1_dependencies_compiler_type=none +-fi +-]) +-AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +-AM_CONDITIONAL([am__fastdep$1], [ +- test "x$enable_dependency_tracking" != xno \ +- && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +-]) +- +- +-# AM_SET_DEPDIR +-# ------------- +-# Choose a directory name for dependency files. +-# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +-AC_DEFUN([AM_SET_DEPDIR], +-[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +-AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +-]) +- +- +-# AM_DEP_TRACK +-# ------------ +-AC_DEFUN([AM_DEP_TRACK], +-[AC_ARG_ENABLE([dependency-tracking], [dnl +-AS_HELP_STRING( +- [--enable-dependency-tracking], +- [do not reject slow dependency extractors]) +-AS_HELP_STRING( +- [--disable-dependency-tracking], +- [speeds up one-time build])]) +-if test "x$enable_dependency_tracking" != xno; then +- am_depcomp="$ac_aux_dir/depcomp" +- AMDEPBACKSLASH='\' +- am__nodep='_no' +-fi +-AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +-AC_SUBST([AMDEPBACKSLASH])dnl +-_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +-AC_SUBST([am__nodep])dnl +-_AM_SUBST_NOTMAKE([am__nodep])dnl +-]) +- +-# Generate code to set up dependency tracking. -*- Autoconf -*- +- +-# Copyright (C) 1999-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +- +-# _AM_OUTPUT_DEPENDENCY_COMMANDS +-# ------------------------------ +-AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +-[{ +- # Older Autoconf quotes --file arguments for eval, but not when files +- # are listed without --file. Let's play safe and only enable the eval +- # if we detect the quoting. +- case $CONFIG_FILES in +- *\'*) eval set x "$CONFIG_FILES" ;; +- *) set x $CONFIG_FILES ;; +- esac +- shift +- for mf +- do +- # Strip MF so we end up with the name of the file. +- mf=`echo "$mf" | sed -e 's/:.*$//'` +- # Check whether this is an Automake generated Makefile or not. +- # We used to match only the files named 'Makefile.in', but +- # some people rename them; so instead we look at the file content. +- # Grep'ing the first line is not enough: some people post-process +- # each Makefile.in and add a new line on top of each file to say so. +- # Grep'ing the whole file is not good either: AIX grep has a line +- # limit of 2048, but all sed's we know have understand at least 4000. +- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then +- dirpart=`AS_DIRNAME("$mf")` +- else +- continue +- fi +- # Extract the definition of DEPDIR, am__include, and am__quote +- # from the Makefile without running 'make'. +- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` +- test -z "$DEPDIR" && continue +- am__include=`sed -n 's/^am__include = //p' < "$mf"` +- test -z "$am__include" && continue +- am__quote=`sed -n 's/^am__quote = //p' < "$mf"` +- # Find all dependency output files, they are included files with +- # $(DEPDIR) in their names. We invoke sed twice because it is the +- # simplest approach to changing $(DEPDIR) to its actual value in the +- # expansion. +- for file in `sed -n " +- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ +- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do +- # Make sure the directory exists. +- test -f "$dirpart/$file" && continue +- fdir=`AS_DIRNAME(["$file"])` +- AS_MKDIR_P([$dirpart/$fdir]) +- # echo "creating $dirpart/$file" +- echo '# dummy' > "$dirpart/$file" +- done +- done +-} +-])# _AM_OUTPUT_DEPENDENCY_COMMANDS +- +- +-# AM_OUTPUT_DEPENDENCY_COMMANDS +-# ----------------------------- +-# This macro should only be invoked once -- use via AC_REQUIRE. +-# +-# This code is only required when automatic dependency tracking +-# is enabled. FIXME. This creates each '.P' file that we will +-# need in order to bootstrap the dependency handling code. +-AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +-[AC_CONFIG_COMMANDS([depfiles], +- [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], +- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +-]) +- +-# Do all the work for Automake. -*- Autoconf -*- +- +-# Copyright (C) 1996-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# This macro actually does too much. Some checks are only needed if +-# your package does certain things. But this isn't really a big deal. +- +-dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +-m4_define([AC_PROG_CC], +-m4_defn([AC_PROG_CC]) +-[_AM_PROG_CC_C_O +-]) +- +-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +-# AM_INIT_AUTOMAKE([OPTIONS]) +-# ----------------------------------------------- +-# The call with PACKAGE and VERSION arguments is the old style +-# call (pre autoconf-2.50), which is being phased out. PACKAGE +-# and VERSION should now be passed to AC_INIT and removed from +-# the call to AM_INIT_AUTOMAKE. +-# We support both call styles for the transition. After +-# the next Automake release, Autoconf can make the AC_INIT +-# arguments mandatory, and then we can depend on a new Autoconf +-# release and drop the old call support. +-AC_DEFUN([AM_INIT_AUTOMAKE], +-[AC_PREREQ([2.65])dnl +-dnl Autoconf wants to disallow AM_ names. We explicitly allow +-dnl the ones we care about. +-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +-AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +-AC_REQUIRE([AC_PROG_INSTALL])dnl +-if test "`cd $srcdir && pwd`" != "`pwd`"; then +- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output +- # is not polluted with repeated "-I." +- AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl +- # test to see if srcdir already configured +- if test -f $srcdir/config.status; then +- AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +- fi +-fi +- +-# test whether we have cygpath +-if test -z "$CYGPATH_W"; then +- if (cygpath --version) >/dev/null 2>/dev/null; then +- CYGPATH_W='cygpath -w' +- else +- CYGPATH_W=echo +- fi +-fi +-AC_SUBST([CYGPATH_W]) +- +-# Define the identity of the package. +-dnl Distinguish between old-style and new-style calls. +-m4_ifval([$2], +-[AC_DIAGNOSE([obsolete], +- [$0: two- and three-arguments forms are deprecated.]) +-m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl +- AC_SUBST([PACKAGE], [$1])dnl +- AC_SUBST([VERSION], [$2])], +-[_AM_SET_OPTIONS([$1])dnl +-dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +-m4_if( +- m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), +- [ok:ok],, +- [m4_fatal([AC_INIT should be called with package and version arguments])])dnl +- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl +- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl +- +-_AM_IF_OPTION([no-define],, +-[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) +- AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl +- +-# Some tools Automake needs. +-AC_REQUIRE([AM_SANITY_CHECK])dnl +-AC_REQUIRE([AC_ARG_PROGRAM])dnl +-AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +-AM_MISSING_PROG([AUTOCONF], [autoconf]) +-AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +-AM_MISSING_PROG([AUTOHEADER], [autoheader]) +-AM_MISSING_PROG([MAKEINFO], [makeinfo]) +-AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +-AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +-AC_REQUIRE([AC_PROG_MKDIR_P])dnl +-# For better backward compatibility. To be removed once Automake 1.9.x +-# dies out for good. For more background, see: +-# +-# +-AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +-# We need awk for the "check" target. The system "awk" is bad on +-# some platforms. +-AC_REQUIRE([AC_PROG_AWK])dnl +-AC_REQUIRE([AC_PROG_MAKE_SET])dnl +-AC_REQUIRE([AM_SET_LEADING_DOT])dnl +-_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], +- [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], +- [_AM_PROG_TAR([v7])])]) +-_AM_IF_OPTION([no-dependencies],, +-[AC_PROVIDE_IFELSE([AC_PROG_CC], +- [_AM_DEPENDENCIES([CC])], +- [m4_define([AC_PROG_CC], +- m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +-AC_PROVIDE_IFELSE([AC_PROG_CXX], +- [_AM_DEPENDENCIES([CXX])], +- [m4_define([AC_PROG_CXX], +- m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +-AC_PROVIDE_IFELSE([AC_PROG_OBJC], +- [_AM_DEPENDENCIES([OBJC])], +- [m4_define([AC_PROG_OBJC], +- m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +-AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], +- [_AM_DEPENDENCIES([OBJCXX])], +- [m4_define([AC_PROG_OBJCXX], +- m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +-]) +-AC_REQUIRE([AM_SILENT_RULES])dnl +-dnl The testsuite driver may need to know about EXEEXT, so add the +-dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +-dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +-AC_CONFIG_COMMANDS_PRE(dnl +-[m4_provide_if([_AM_COMPILER_EXEEXT], +- [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +- +-# POSIX will say in a future version that running "rm -f" with no argument +-# is OK; and we want to be able to make that assumption in our Makefile +-# recipes. So use an aggressive probe to check that the usage we want is +-# actually supported "in the wild" to an acceptable degree. +-# See automake bug#10828. +-# To make any issue more visible, cause the running configure to be aborted +-# by default if the 'rm' program in use doesn't match our expectations; the +-# user can still override this though. +-if rm -f && rm -fr && rm -rf; then : OK; else +- cat >&2 <<'END' +-Oops! +- +-Your 'rm' program seems unable to run without file operands specified +-on the command line, even when the '-f' option is present. This is contrary +-to the behaviour of most rm programs out there, and not conforming with +-the upcoming POSIX standard: +- +-Please tell bug-automake@gnu.org about your system, including the value +-of your $PATH and any error possibly output before this message. This +-can help us improve future automake versions. +- +-END +- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then +- echo 'Configuration will proceed anyway, since you have set the' >&2 +- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 +- echo >&2 +- else +- cat >&2 <<'END' +-Aborting the configuration process, to ensure you take notice of the issue. +- +-You can download and install GNU coreutils to get an 'rm' implementation +-that behaves properly: . +- +-If you want to complete the configuration process using your problematic +-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +-to "yes", and re-run configure. +- +-END +- AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) +- fi +-fi]) +- +-dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +-dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +-dnl mangled by Autoconf and run in a shell conditional statement. +-m4_define([_AC_COMPILER_EXEEXT], +-m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) +- +-# When config.status generates a header, we must update the stamp-h file. +-# This file resides in the same directory as the config header +-# that is generated. The stamp files are numbered to have different names. +- +-# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +-# loop where config.status creates the headers, so we can generate +-# our stamp files there. +-AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +-[# Compute $1's index in $config_headers. +-_am_arg=$1 +-_am_stamp_count=1 +-for _am_header in $config_headers :; do +- case $_am_header in +- $_am_arg | $_am_arg:* ) +- break ;; +- * ) +- _am_stamp_count=`expr $_am_stamp_count + 1` ;; +- esac +-done +-echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) +- +-# Copyright (C) 2001-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# AM_PROG_INSTALL_SH +-# ------------------ +-# Define $install_sh. +-AC_DEFUN([AM_PROG_INSTALL_SH], +-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +-if test x"${install_sh}" != xset; then +- case $am_aux_dir in +- *\ * | *\ *) +- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; +- *) +- install_sh="\${SHELL} $am_aux_dir/install-sh" +- esac +-fi +-AC_SUBST([install_sh])]) +- +-# Copyright (C) 2003-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# Check whether the underlying file-system supports filenames +-# with a leading dot. For instance MS-DOS doesn't. +-AC_DEFUN([AM_SET_LEADING_DOT], +-[rm -rf .tst 2>/dev/null +-mkdir .tst 2>/dev/null +-if test -d .tst; then +- am__leading_dot=. +-else +- am__leading_dot=_ +-fi +-rmdir .tst 2>/dev/null +-AC_SUBST([am__leading_dot])]) +- +-# Check to see how 'make' treats includes. -*- Autoconf -*- +- +-# Copyright (C) 2001-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# AM_MAKE_INCLUDE() +-# ----------------- +-# Check to see how make treats includes. +-AC_DEFUN([AM_MAKE_INCLUDE], +-[am_make=${MAKE-make} +-cat > confinc << 'END' +-am__doit: +- @echo this is the am__doit target +-.PHONY: am__doit +-END +-# If we don't find an include directive, just comment out the code. +-AC_MSG_CHECKING([for style of include used by $am_make]) +-am__include="#" +-am__quote= +-_am_result=none +-# First try GNU make style include. +-echo "include confinc" > confmf +-# Ignore all kinds of additional output from 'make'. +-case `$am_make -s -f confmf 2> /dev/null` in #( +-*the\ am__doit\ target*) +- am__include=include +- am__quote= +- _am_result=GNU +- ;; +-esac +-# Now try BSD make style include. +-if test "$am__include" = "#"; then +- echo '.include "confinc"' > confmf +- case `$am_make -s -f confmf 2> /dev/null` in #( +- *the\ am__doit\ target*) +- am__include=.include +- am__quote="\"" +- _am_result=BSD +- ;; +- esac +-fi +-AC_SUBST([am__include]) +-AC_SUBST([am__quote]) +-AC_MSG_RESULT([$_am_result]) +-rm -f confinc confmf +-]) +- +-# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- +- +-# Copyright (C) 1997-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# AM_MISSING_PROG(NAME, PROGRAM) +-# ------------------------------ +-AC_DEFUN([AM_MISSING_PROG], +-[AC_REQUIRE([AM_MISSING_HAS_RUN]) +-$1=${$1-"${am_missing_run}$2"} +-AC_SUBST($1)]) +- +-# AM_MISSING_HAS_RUN +-# ------------------ +-# Define MISSING if not defined so far and test if it is modern enough. +-# If it is, set am_missing_run to use it, otherwise, to nothing. +-AC_DEFUN([AM_MISSING_HAS_RUN], +-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +-AC_REQUIRE_AUX_FILE([missing])dnl +-if test x"${MISSING+set}" != xset; then +- case $am_aux_dir in +- *\ * | *\ *) +- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; +- *) +- MISSING="\${SHELL} $am_aux_dir/missing" ;; +- esac +-fi +-# Use eval to expand $SHELL +-if eval "$MISSING --is-lightweight"; then +- am_missing_run="$MISSING " +-else +- am_missing_run= +- AC_MSG_WARN(['missing' script is too old or missing]) +-fi +-]) +- +-# Helper functions for option handling. -*- Autoconf -*- +- +-# Copyright (C) 2001-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# _AM_MANGLE_OPTION(NAME) +-# ----------------------- +-AC_DEFUN([_AM_MANGLE_OPTION], +-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) +- +-# _AM_SET_OPTION(NAME) +-# -------------------- +-# Set option NAME. Presently that only means defining a flag for this option. +-AC_DEFUN([_AM_SET_OPTION], +-[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) +- +-# _AM_SET_OPTIONS(OPTIONS) +-# ------------------------ +-# OPTIONS is a space-separated list of Automake options. +-AC_DEFUN([_AM_SET_OPTIONS], +-[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) +- +-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +-# ------------------------------------------- +-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +-AC_DEFUN([_AM_IF_OPTION], +-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) +- +-# Copyright (C) 1999-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# _AM_PROG_CC_C_O +-# --------------- +-# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +-# to automatically call this. +-AC_DEFUN([_AM_PROG_CC_C_O], +-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +-AC_REQUIRE_AUX_FILE([compile])dnl +-AC_LANG_PUSH([C])dnl +-AC_CACHE_CHECK( +- [whether $CC understands -c and -o together], +- [am_cv_prog_cc_c_o], +- [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) +- # Make sure it works both with $CC and with simple cc. +- # Following AC_PROG_CC_C_O, we do the test twice because some +- # compilers refuse to overwrite an existing .o file with -o, +- # though they will create one. +- am_cv_prog_cc_c_o=yes +- for am_i in 1 2; do +- if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ +- && test -f conftest2.$ac_objext; then +- : OK +- else +- am_cv_prog_cc_c_o=no +- break +- fi +- done +- rm -f core conftest* +- unset am_i]) +-if test "$am_cv_prog_cc_c_o" != yes; then +- # Losing compiler, so override with the script. +- # FIXME: It is wrong to rewrite CC. +- # But if we don't then we get into trouble of one sort or another. +- # A longer-term fix would be to have automake use am__CC in this case, +- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" +- CC="$am_aux_dir/compile $CC" +-fi +-AC_LANG_POP([C])]) +- +-# For backward compatibility. +-AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) +- +-# Copyright (C) 2001-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# AM_RUN_LOG(COMMAND) +-# ------------------- +-# Run COMMAND, save the exit status in ac_status, and log it. +-# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +-AC_DEFUN([AM_RUN_LOG], +-[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD +- ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD +- ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD +- (exit $ac_status); }]) +- +-# Check to make sure that the build environment is sane. -*- Autoconf -*- +- +-# Copyright (C) 1996-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# AM_SANITY_CHECK +-# --------------- +-AC_DEFUN([AM_SANITY_CHECK], +-[AC_MSG_CHECKING([whether build environment is sane]) +-# Reject unsafe characters in $srcdir or the absolute working directory +-# name. Accept space and tab only in the latter. +-am_lf=' +-' +-case `pwd` in +- *[[\\\"\#\$\&\'\`$am_lf]]*) +- AC_MSG_ERROR([unsafe absolute working directory name]);; +-esac +-case $srcdir in +- *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) +- AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +-esac +- +-# Do 'set' in a subshell so we don't clobber the current shell's +-# arguments. Must try -L first in case configure is actually a +-# symlink; some systems play weird games with the mod time of symlinks +-# (eg FreeBSD returns the mod time of the symlink's containing +-# directory). +-if ( +- am_has_slept=no +- for am_try in 1 2; do +- echo "timestamp, slept: $am_has_slept" > conftest.file +- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` +- if test "$[*]" = "X"; then +- # -L didn't work. +- set X `ls -t "$srcdir/configure" conftest.file` +- fi +- if test "$[*]" != "X $srcdir/configure conftest.file" \ +- && test "$[*]" != "X conftest.file $srcdir/configure"; then +- +- # If neither matched, then we have a broken ls. This can happen +- # if, for instance, CONFIG_SHELL is bash and it inherits a +- # broken ls alias from the environment. This has actually +- # happened. Such a system could not be considered "sane". +- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +- alias in your environment]) +- fi +- if test "$[2]" = conftest.file || test $am_try -eq 2; then +- break +- fi +- # Just in case. +- sleep 1 +- am_has_slept=yes +- done +- test "$[2]" = conftest.file +- ) +-then +- # Ok. +- : +-else +- AC_MSG_ERROR([newly created file is older than distributed files! +-Check your system clock]) +-fi +-AC_MSG_RESULT([yes]) +-# If we didn't sleep, we still need to ensure time stamps of config.status and +-# generated files are strictly newer. +-am_sleep_pid= +-if grep 'slept: no' conftest.file >/dev/null 2>&1; then +- ( sleep 1 ) & +- am_sleep_pid=$! +-fi +-AC_CONFIG_COMMANDS_PRE( +- [AC_MSG_CHECKING([that generated files are newer than configure]) +- if test -n "$am_sleep_pid"; then +- # Hide warnings about reused PIDs. +- wait $am_sleep_pid 2>/dev/null +- fi +- AC_MSG_RESULT([done])]) +-rm -f conftest.file +-]) +- +-# Copyright (C) 2009-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# AM_SILENT_RULES([DEFAULT]) +-# -------------------------- +-# Enable less verbose build rules; with the default set to DEFAULT +-# ("yes" being less verbose, "no" or empty being verbose). +-AC_DEFUN([AM_SILENT_RULES], +-[AC_ARG_ENABLE([silent-rules], [dnl +-AS_HELP_STRING( +- [--enable-silent-rules], +- [less verbose build output (undo: "make V=1")]) +-AS_HELP_STRING( +- [--disable-silent-rules], +- [verbose build output (undo: "make V=0")])dnl +-]) +-case $enable_silent_rules in @%:@ ((( +- yes) AM_DEFAULT_VERBOSITY=0;; +- no) AM_DEFAULT_VERBOSITY=1;; +- *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +-esac +-dnl +-dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +-dnl do not support nested variable expansions. +-dnl See automake bug#9928 and bug#10237. +-am_make=${MAKE-make} +-AC_CACHE_CHECK([whether $am_make supports nested variables], +- [am_cv_make_support_nested_variables], +- [if AS_ECHO([['TRUE=$(BAR$(V)) +-BAR0=false +-BAR1=true +-V=1 +-am__doit: +- @$(TRUE) +-.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then +- am_cv_make_support_nested_variables=yes +-else +- am_cv_make_support_nested_variables=no +-fi]) +-if test $am_cv_make_support_nested_variables = yes; then +- dnl Using '$V' instead of '$(V)' breaks IRIX make. +- AM_V='$(V)' +- AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +-else +- AM_V=$AM_DEFAULT_VERBOSITY +- AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +-fi +-AC_SUBST([AM_V])dnl +-AM_SUBST_NOTMAKE([AM_V])dnl +-AC_SUBST([AM_DEFAULT_V])dnl +-AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +-AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +-AM_BACKSLASH='\' +-AC_SUBST([AM_BACKSLASH])dnl +-_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +-]) +- +-# Copyright (C) 2001-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# AM_PROG_INSTALL_STRIP +-# --------------------- +-# One issue with vendor 'install' (even GNU) is that you can't +-# specify the program used to strip binaries. This is especially +-# annoying in cross-compiling environments, where the build's strip +-# is unlikely to handle the host's binaries. +-# Fortunately install-sh will honor a STRIPPROG variable, so we +-# always use install-sh in "make install-strip", and initialize +-# STRIPPROG with the value of the STRIP variable (set by the user). +-AC_DEFUN([AM_PROG_INSTALL_STRIP], +-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +-# Installed binaries are usually stripped using 'strip' when the user +-# run "make install-strip". However 'strip' might not be the right +-# tool to use in cross-compilation environments, therefore Automake +-# will honor the 'STRIP' environment variable to overrule this program. +-dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +-if test "$cross_compiling" != no; then +- AC_CHECK_TOOL([STRIP], [strip], :) +-fi +-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +-AC_SUBST([INSTALL_STRIP_PROGRAM])]) +- +-# Copyright (C) 2006-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# _AM_SUBST_NOTMAKE(VARIABLE) +-# --------------------------- +-# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +-# This macro is traced by Automake. +-AC_DEFUN([_AM_SUBST_NOTMAKE]) +- +-# AM_SUBST_NOTMAKE(VARIABLE) +-# -------------------------- +-# Public sister of _AM_SUBST_NOTMAKE. +-AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) +- +-# Check how to create a tarball. -*- Autoconf -*- +- +-# Copyright (C) 2004-2013 Free Software Foundation, Inc. +-# +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# _AM_PROG_TAR(FORMAT) +-# -------------------- +-# Check how to create a tarball in format FORMAT. +-# FORMAT should be one of 'v7', 'ustar', or 'pax'. +-# +-# Substitute a variable $(am__tar) that is a command +-# writing to stdout a FORMAT-tarball containing the directory +-# $tardir. +-# tardir=directory && $(am__tar) > result.tar +-# +-# Substitute a variable $(am__untar) that extract such +-# a tarball read from stdin. +-# $(am__untar) < result.tar +-# +-AC_DEFUN([_AM_PROG_TAR], +-[# Always define AMTAR for backward compatibility. Yes, it's still used +-# in the wild :-( We should find a proper way to deprecate it ... +-AC_SUBST([AMTAR], ['$${TAR-tar}']) +- +-# We'll loop over all known methods to create a tar archive until one works. +-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +- +-m4_if([$1], [v7], +- [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], +- +- [m4_case([$1], +- [ustar], +- [# The POSIX 1988 'ustar' format is defined with fixed-size fields. +- # There is notably a 21 bits limit for the UID and the GID. In fact, +- # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 +- # and bug#13588). +- am_max_uid=2097151 # 2^21 - 1 +- am_max_gid=$am_max_uid +- # The $UID and $GID variables are not portable, so we need to resort +- # to the POSIX-mandated id(1) utility. Errors in the 'id' calls +- # below are definitely unexpected, so allow the users to see them +- # (that is, avoid stderr redirection). +- am_uid=`id -u || echo unknown` +- am_gid=`id -g || echo unknown` +- AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) +- if test $am_uid -le $am_max_uid; then +- AC_MSG_RESULT([yes]) +- else +- AC_MSG_RESULT([no]) +- _am_tools=none +- fi +- AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) +- if test $am_gid -le $am_max_gid; then +- AC_MSG_RESULT([yes]) +- else +- AC_MSG_RESULT([no]) +- _am_tools=none +- fi], +- +- [pax], +- [], +- +- [m4_fatal([Unknown tar format])]) +- +- AC_MSG_CHECKING([how to create a $1 tar archive]) +- +- # Go ahead even if we have the value already cached. We do so because we +- # need to set the values for the 'am__tar' and 'am__untar' variables. +- _am_tools=${am_cv_prog_tar_$1-$_am_tools} +- +- for _am_tool in $_am_tools; do +- case $_am_tool in +- gnutar) +- for _am_tar in tar gnutar gtar; do +- AM_RUN_LOG([$_am_tar --version]) && break +- done +- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' +- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' +- am__untar="$_am_tar -xf -" +- ;; +- plaintar) +- # Must skip GNU tar: if it does not support --format= it doesn't create +- # ustar tarball either. +- (tar --version) >/dev/null 2>&1 && continue +- am__tar='tar chf - "$$tardir"' +- am__tar_='tar chf - "$tardir"' +- am__untar='tar xf -' +- ;; +- pax) +- am__tar='pax -L -x $1 -w "$$tardir"' +- am__tar_='pax -L -x $1 -w "$tardir"' +- am__untar='pax -r' +- ;; +- cpio) +- am__tar='find "$$tardir" -print | cpio -o -H $1 -L' +- am__tar_='find "$tardir" -print | cpio -o -H $1 -L' +- am__untar='cpio -i -H $1 -d' +- ;; +- none) +- am__tar=false +- am__tar_=false +- am__untar=false +- ;; +- esac +- +- # If the value was cached, stop now. We just wanted to have am__tar +- # and am__untar set. +- test -n "${am_cv_prog_tar_$1}" && break +- +- # tar/untar a dummy directory, and stop if the command works. +- rm -rf conftest.dir +- mkdir conftest.dir +- echo GrepMe > conftest.dir/file +- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) +- rm -rf conftest.dir +- if test -s conftest.tar; then +- AM_RUN_LOG([$am__untar /dev/null 2>&1 && break +- fi +- done +- rm -rf conftest.dir +- +- AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +- AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +- +-AC_SUBST([am__tar]) +-AC_SUBST([am__untar]) +-]) # _AM_PROG_TAR +- +-m4_include([m4/00gnulib.m4]) +-m4_include([m4/codeset.m4]) +-m4_include([m4/configmake.m4]) +-m4_include([m4/extensions.m4]) +-m4_include([m4/extern-inline.m4]) +-m4_include([m4/fcntl-o.m4]) +-m4_include([m4/glibc21.m4]) +-m4_include([m4/gnulib-common.m4]) +-m4_include([m4/include_next.m4]) +-m4_include([m4/inttypes-pri.m4]) +-m4_include([m4/inttypes.m4]) +-m4_include([m4/libunistring-base.m4]) +-m4_include([m4/localcharset.m4]) +-m4_include([m4/longlong.m4]) +-m4_include([m4/multiarch.m4]) +-m4_include([m4/onceonly.m4]) +-m4_include([m4/stdbool.m4]) +-m4_include([m4/stddef_h.m4]) +-m4_include([m4/stdint.m4]) +-m4_include([m4/warn-on-use.m4]) +-m4_include([m4/wchar_h.m4]) +-m4_include([m4/wchar_t.m4]) +-m4_include([m4/wctype_h.m4]) +-m4_include([m4/wcwidth.m4]) +-m4_include([m4/wint_t.m4]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/build-aux/compile groff-1.22.3/src/libs/gnulib/build-aux/compile +--- groff-1.22.3.old/src/libs/gnulib/build-aux/compile 2014-11-04 10:38:35.646518734 +0200 ++++ groff-1.22.3/src/libs/gnulib/build-aux/compile 1970-01-01 02:00:00.000000000 +0200 +@@ -1,347 +0,0 @@ +-#! /bin/sh +-# Wrapper for compilers which do not understand '-c -o'. +- +-scriptversion=2012-10-14.11; # UTC +- +-# Copyright (C) 1999-2013 Free Software Foundation, Inc. +-# Written by Tom Tromey . +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2, or (at your option) +-# any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-# As a special exception to the GNU General Public License, if you +-# distribute this file as part of a program that contains a +-# configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that program. +- +-# This file is maintained in Automake, please report +-# bugs to or send patches to +-# . +- +-nl=' +-' +- +-# We need space, tab and new line, in precisely that order. Quoting is +-# there to prevent tools from complaining about whitespace usage. +-IFS=" "" $nl" +- +-file_conv= +- +-# func_file_conv build_file lazy +-# Convert a $build file to $host form and store it in $file +-# Currently only supports Windows hosts. If the determined conversion +-# type is listed in (the comma separated) LAZY, no conversion will +-# take place. +-func_file_conv () +-{ +- file=$1 +- case $file in +- / | /[!/]*) # absolute file, and not a UNC file +- if test -z "$file_conv"; then +- # lazily determine how to convert abs files +- case `uname -s` in +- MINGW*) +- file_conv=mingw +- ;; +- CYGWIN*) +- file_conv=cygwin +- ;; +- *) +- file_conv=wine +- ;; +- esac +- fi +- case $file_conv/,$2, in +- *,$file_conv,*) +- ;; +- mingw/*) +- file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` +- ;; +- cygwin/*) +- file=`cygpath -m "$file" || echo "$file"` +- ;; +- wine/*) +- file=`winepath -w "$file" || echo "$file"` +- ;; +- esac +- ;; +- esac +-} +- +-# func_cl_dashL linkdir +-# Make cl look for libraries in LINKDIR +-func_cl_dashL () +-{ +- func_file_conv "$1" +- if test -z "$lib_path"; then +- lib_path=$file +- else +- lib_path="$lib_path;$file" +- fi +- linker_opts="$linker_opts -LIBPATH:$file" +-} +- +-# func_cl_dashl library +-# Do a library search-path lookup for cl +-func_cl_dashl () +-{ +- lib=$1 +- found=no +- save_IFS=$IFS +- IFS=';' +- for dir in $lib_path $LIB +- do +- IFS=$save_IFS +- if $shared && test -f "$dir/$lib.dll.lib"; then +- found=yes +- lib=$dir/$lib.dll.lib +- break +- fi +- if test -f "$dir/$lib.lib"; then +- found=yes +- lib=$dir/$lib.lib +- break +- fi +- if test -f "$dir/lib$lib.a"; then +- found=yes +- lib=$dir/lib$lib.a +- break +- fi +- done +- IFS=$save_IFS +- +- if test "$found" != yes; then +- lib=$lib.lib +- fi +-} +- +-# func_cl_wrapper cl arg... +-# Adjust compile command to suit cl +-func_cl_wrapper () +-{ +- # Assume a capable shell +- lib_path= +- shared=: +- linker_opts= +- for arg +- do +- if test -n "$eat"; then +- eat= +- else +- case $1 in +- -o) +- # configure might choose to run compile as 'compile cc -o foo foo.c'. +- eat=1 +- case $2 in +- *.o | *.[oO][bB][jJ]) +- func_file_conv "$2" +- set x "$@" -Fo"$file" +- shift +- ;; +- *) +- func_file_conv "$2" +- set x "$@" -Fe"$file" +- shift +- ;; +- esac +- ;; +- -I) +- eat=1 +- func_file_conv "$2" mingw +- set x "$@" -I"$file" +- shift +- ;; +- -I*) +- func_file_conv "${1#-I}" mingw +- set x "$@" -I"$file" +- shift +- ;; +- -l) +- eat=1 +- func_cl_dashl "$2" +- set x "$@" "$lib" +- shift +- ;; +- -l*) +- func_cl_dashl "${1#-l}" +- set x "$@" "$lib" +- shift +- ;; +- -L) +- eat=1 +- func_cl_dashL "$2" +- ;; +- -L*) +- func_cl_dashL "${1#-L}" +- ;; +- -static) +- shared=false +- ;; +- -Wl,*) +- arg=${1#-Wl,} +- save_ifs="$IFS"; IFS=',' +- for flag in $arg; do +- IFS="$save_ifs" +- linker_opts="$linker_opts $flag" +- done +- IFS="$save_ifs" +- ;; +- -Xlinker) +- eat=1 +- linker_opts="$linker_opts $2" +- ;; +- -*) +- set x "$@" "$1" +- shift +- ;; +- *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) +- func_file_conv "$1" +- set x "$@" -Tp"$file" +- shift +- ;; +- *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) +- func_file_conv "$1" mingw +- set x "$@" "$file" +- shift +- ;; +- *) +- set x "$@" "$1" +- shift +- ;; +- esac +- fi +- shift +- done +- if test -n "$linker_opts"; then +- linker_opts="-link$linker_opts" +- fi +- exec "$@" $linker_opts +- exit 1 +-} +- +-eat= +- +-case $1 in +- '') +- echo "$0: No command. Try '$0 --help' for more information." 1>&2 +- exit 1; +- ;; +- -h | --h*) +- cat <<\EOF +-Usage: compile [--help] [--version] PROGRAM [ARGS] +- +-Wrapper for compilers which do not understand '-c -o'. +-Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +-arguments, and rename the output as expected. +- +-If you are trying to build a whole package this is not the +-right script to run: please start by reading the file 'INSTALL'. +- +-Report bugs to . +-EOF +- exit $? +- ;; +- -v | --v*) +- echo "compile $scriptversion" +- exit $? +- ;; +- cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) +- func_cl_wrapper "$@" # Doesn't return... +- ;; +-esac +- +-ofile= +-cfile= +- +-for arg +-do +- if test -n "$eat"; then +- eat= +- else +- case $1 in +- -o) +- # configure might choose to run compile as 'compile cc -o foo foo.c'. +- # So we strip '-o arg' only if arg is an object. +- eat=1 +- case $2 in +- *.o | *.obj) +- ofile=$2 +- ;; +- *) +- set x "$@" -o "$2" +- shift +- ;; +- esac +- ;; +- *.c) +- cfile=$1 +- set x "$@" "$1" +- shift +- ;; +- *) +- set x "$@" "$1" +- shift +- ;; +- esac +- fi +- shift +-done +- +-if test -z "$ofile" || test -z "$cfile"; then +- # If no '-o' option was seen then we might have been invoked from a +- # pattern rule where we don't need one. That is ok -- this is a +- # normal compilation that the losing compiler can handle. If no +- # '.c' file was seen then we are probably linking. That is also +- # ok. +- exec "$@" +-fi +- +-# Name of file we expect compiler to create. +-cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` +- +-# Create the lock directory. +-# Note: use '[/\\:.-]' here to ensure that we don't use the same name +-# that we are using for the .o file. Also, base the name on the expected +-# object file name, since that is what matters with a parallel build. +-lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +-while true; do +- if mkdir "$lockdir" >/dev/null 2>&1; then +- break +- fi +- sleep 1 +-done +-# FIXME: race condition here if user kills between mkdir and trap. +-trap "rmdir '$lockdir'; exit 1" 1 2 15 +- +-# Run the compile. +-"$@" +-ret=$? +- +-if test -f "$cofile"; then +- test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +-elif test -f "${cofile}bj"; then +- test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +-fi +- +-rmdir "$lockdir" +-exit $ret +- +-# Local Variables: +-# mode: shell-script +-# sh-indentation: 2 +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "scriptversion=" +-# time-stamp-format: "%:y-%02m-%02d.%02H" +-# time-stamp-time-zone: "UTC" +-# time-stamp-end: "; # UTC" +-# End: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/build-aux/config.guess groff-1.22.3/src/libs/gnulib/build-aux/config.guess +--- groff-1.22.3.old/src/libs/gnulib/build-aux/config.guess 2014-11-04 10:38:35.646518734 +0200 ++++ groff-1.22.3/src/libs/gnulib/build-aux/config.guess 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1420 +0,0 @@ +-#! /bin/sh +-# Attempt to guess a canonical system name. +-# Copyright 1992-2014 Free Software Foundation, Inc. +- +-timestamp='2014-03-23' +- +-# This file is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 3 of the License, or +-# (at your option) any later version. +-# +-# This program is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program; if not, see . +-# +-# As a special exception to the GNU General Public License, if you +-# distribute this file as part of a program that contains a +-# configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that +-# program. This Exception is an additional permission under section 7 +-# of the GNU General Public License, version 3 ("GPLv3"). +-# +-# Originally written by Per Bothner. +-# +-# You can get the latest version of this script from: +-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +-# +-# Please send patches with a ChangeLog entry to config-patches@gnu.org. +- +- +-me=`echo "$0" | sed -e 's,.*/,,'` +- +-usage="\ +-Usage: $0 [OPTION] +- +-Output the configuration name of the system \`$me' is run on. +- +-Operation modes: +- -h, --help print this help, then exit +- -t, --time-stamp print date of last modification, then exit +- -v, --version print version number, then exit +- +-Report bugs and patches to ." +- +-version="\ +-GNU config.guess ($timestamp) +- +-Originally written by Per Bothner. +-Copyright 1992-2014 Free Software Foundation, Inc. +- +-This is free software; see the source for copying conditions. There is NO +-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +- +-help=" +-Try \`$me --help' for more information." +- +-# Parse command line +-while test $# -gt 0 ; do +- case $1 in +- --time-stamp | --time* | -t ) +- echo "$timestamp" ; exit ;; +- --version | -v ) +- echo "$version" ; exit ;; +- --help | --h* | -h ) +- echo "$usage"; exit ;; +- -- ) # Stop option processing +- shift; break ;; +- - ) # Use stdin as input. +- break ;; +- -* ) +- echo "$me: invalid option $1$help" >&2 +- exit 1 ;; +- * ) +- break ;; +- esac +-done +- +-if test $# != 0; then +- echo "$me: too many arguments$help" >&2 +- exit 1 +-fi +- +-trap 'exit 1' 1 2 15 +- +-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +-# compiler to aid in system detection is discouraged as it requires +-# temporary files to be created and, as you can see below, it is a +-# headache to deal with in a portable fashion. +- +-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +-# use `HOST_CC' if defined, but it is deprecated. +- +-# Portable tmp directory creation inspired by the Autoconf team. +- +-set_cc_for_build=' +-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +-: ${TMPDIR=/tmp} ; +- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || +- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || +- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || +- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +-dummy=$tmp/dummy ; +-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +-case $CC_FOR_BUILD,$HOST_CC,$CC in +- ,,) echo "int x;" > $dummy.c ; +- for c in cc gcc c89 c99 ; do +- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then +- CC_FOR_BUILD="$c"; break ; +- fi ; +- done ; +- if test x"$CC_FOR_BUILD" = x ; then +- CC_FOR_BUILD=no_compiler_found ; +- fi +- ;; +- ,,*) CC_FOR_BUILD=$CC ;; +- ,*,*) CC_FOR_BUILD=$HOST_CC ;; +-esac ; set_cc_for_build= ;' +- +-# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +-# (ghazi@noc.rutgers.edu 1994-08-24) +-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +- PATH=$PATH:/.attbin ; export PATH +-fi +- +-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +- +-case "${UNAME_SYSTEM}" in +-Linux|GNU|GNU/*) +- # If the system lacks a compiler, then just pick glibc. +- # We could probably try harder. +- LIBC=gnu +- +- eval $set_cc_for_build +- cat <<-EOF > $dummy.c +- #include +- #if defined(__UCLIBC__) +- LIBC=uclibc +- #elif defined(__dietlibc__) +- LIBC=dietlibc +- #else +- LIBC=gnu +- #endif +- EOF +- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` +- ;; +-esac +- +-# Note: order is significant - the case branches are not exclusive. +- +-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +- *:NetBSD:*:*) +- # NetBSD (nbsd) targets should (where applicable) match one or +- # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, +- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently +- # switched to ELF, *-*-netbsd* would select the old +- # object file format. This provides both forward +- # compatibility and a consistent mechanism for selecting the +- # object file format. +- # +- # Note: NetBSD doesn't particularly care about the vendor +- # portion of the name. We always set it to "unknown". +- sysctl="sysctl -n hw.machine_arch" +- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ +- /usr/sbin/$sysctl 2>/dev/null || echo unknown)` +- case "${UNAME_MACHINE_ARCH}" in +- armeb) machine=armeb-unknown ;; +- arm*) machine=arm-unknown ;; +- sh3el) machine=shl-unknown ;; +- sh3eb) machine=sh-unknown ;; +- sh5el) machine=sh5le-unknown ;; +- *) machine=${UNAME_MACHINE_ARCH}-unknown ;; +- esac +- # The Operating System including object format, if it has switched +- # to ELF recently, or will in the future. +- case "${UNAME_MACHINE_ARCH}" in +- arm*|i386|m68k|ns32k|sh3*|sparc|vax) +- eval $set_cc_for_build +- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ +- | grep -q __ELF__ +- then +- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). +- # Return netbsd for either. FIX? +- os=netbsd +- else +- os=netbsdelf +- fi +- ;; +- *) +- os=netbsd +- ;; +- esac +- # The OS release +- # Debian GNU/NetBSD machines have a different userland, and +- # thus, need a distinct triplet. However, they do not need +- # kernel version information, so it can be replaced with a +- # suitable tag, in the style of linux-gnu. +- case "${UNAME_VERSION}" in +- Debian*) +- release='-gnu' +- ;; +- *) +- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` +- ;; +- esac +- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: +- # contains redundant information, the shorter form: +- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. +- echo "${machine}-${os}${release}" +- exit ;; +- *:Bitrig:*:*) +- UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` +- echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} +- exit ;; +- *:OpenBSD:*:*) +- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` +- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} +- exit ;; +- *:ekkoBSD:*:*) +- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} +- exit ;; +- *:SolidBSD:*:*) +- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} +- exit ;; +- macppc:MirBSD:*:*) +- echo powerpc-unknown-mirbsd${UNAME_RELEASE} +- exit ;; +- *:MirBSD:*:*) +- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} +- exit ;; +- alpha:OSF1:*:*) +- case $UNAME_RELEASE in +- *4.0) +- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` +- ;; +- *5.*) +- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` +- ;; +- esac +- # According to Compaq, /usr/sbin/psrinfo has been available on +- # OSF/1 and Tru64 systems produced since 1995. I hope that +- # covers most systems running today. This code pipes the CPU +- # types through head -n 1, so we only detect the type of CPU 0. +- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` +- case "$ALPHA_CPU_TYPE" in +- "EV4 (21064)") +- UNAME_MACHINE="alpha" ;; +- "EV4.5 (21064)") +- UNAME_MACHINE="alpha" ;; +- "LCA4 (21066/21068)") +- UNAME_MACHINE="alpha" ;; +- "EV5 (21164)") +- UNAME_MACHINE="alphaev5" ;; +- "EV5.6 (21164A)") +- UNAME_MACHINE="alphaev56" ;; +- "EV5.6 (21164PC)") +- UNAME_MACHINE="alphapca56" ;; +- "EV5.7 (21164PC)") +- UNAME_MACHINE="alphapca57" ;; +- "EV6 (21264)") +- UNAME_MACHINE="alphaev6" ;; +- "EV6.7 (21264A)") +- UNAME_MACHINE="alphaev67" ;; +- "EV6.8CB (21264C)") +- UNAME_MACHINE="alphaev68" ;; +- "EV6.8AL (21264B)") +- UNAME_MACHINE="alphaev68" ;; +- "EV6.8CX (21264D)") +- UNAME_MACHINE="alphaev68" ;; +- "EV6.9A (21264/EV69A)") +- UNAME_MACHINE="alphaev69" ;; +- "EV7 (21364)") +- UNAME_MACHINE="alphaev7" ;; +- "EV7.9 (21364A)") +- UNAME_MACHINE="alphaev79" ;; +- esac +- # A Pn.n version is a patched version. +- # A Vn.n version is a released version. +- # A Tn.n version is a released field test version. +- # A Xn.n version is an unreleased experimental baselevel. +- # 1.2 uses "1.2" for uname -r. +- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` +- # Reset EXIT trap before exiting to avoid spurious non-zero exit code. +- exitcode=$? +- trap '' 0 +- exit $exitcode ;; +- Alpha\ *:Windows_NT*:*) +- # How do we know it's Interix rather than the generic POSIX subsystem? +- # Should we change UNAME_MACHINE based on the output of uname instead +- # of the specific Alpha model? +- echo alpha-pc-interix +- exit ;; +- 21064:Windows_NT:50:3) +- echo alpha-dec-winnt3.5 +- exit ;; +- Amiga*:UNIX_System_V:4.0:*) +- echo m68k-unknown-sysv4 +- exit ;; +- *:[Aa]miga[Oo][Ss]:*:*) +- echo ${UNAME_MACHINE}-unknown-amigaos +- exit ;; +- *:[Mm]orph[Oo][Ss]:*:*) +- echo ${UNAME_MACHINE}-unknown-morphos +- exit ;; +- *:OS/390:*:*) +- echo i370-ibm-openedition +- exit ;; +- *:z/VM:*:*) +- echo s390-ibm-zvmoe +- exit ;; +- *:OS400:*:*) +- echo powerpc-ibm-os400 +- exit ;; +- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) +- echo arm-acorn-riscix${UNAME_RELEASE} +- exit ;; +- arm*:riscos:*:*|arm*:RISCOS:*:*) +- echo arm-unknown-riscos +- exit ;; +- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) +- echo hppa1.1-hitachi-hiuxmpp +- exit ;; +- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) +- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. +- if test "`(/bin/universe) 2>/dev/null`" = att ; then +- echo pyramid-pyramid-sysv3 +- else +- echo pyramid-pyramid-bsd +- fi +- exit ;; +- NILE*:*:*:dcosx) +- echo pyramid-pyramid-svr4 +- exit ;; +- DRS?6000:unix:4.0:6*) +- echo sparc-icl-nx6 +- exit ;; +- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) +- case `/usr/bin/uname -p` in +- sparc) echo sparc-icl-nx7; exit ;; +- esac ;; +- s390x:SunOS:*:*) +- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- sun4H:SunOS:5.*:*) +- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) +- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) +- echo i386-pc-auroraux${UNAME_RELEASE} +- exit ;; +- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) +- eval $set_cc_for_build +- SUN_ARCH="i386" +- # If there is a compiler, see if it is configured for 64-bit objects. +- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. +- # This test works for both compilers. +- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then +- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ +- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ +- grep IS_64BIT_ARCH >/dev/null +- then +- SUN_ARCH="x86_64" +- fi +- fi +- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- sun4*:SunOS:6*:*) +- # According to config.sub, this is the proper way to canonicalize +- # SunOS6. Hard to guess exactly what SunOS6 will be like, but +- # it's likely to be more like Solaris than SunOS4. +- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- sun4*:SunOS:*:*) +- case "`/usr/bin/arch -k`" in +- Series*|S4*) +- UNAME_RELEASE=`uname -v` +- ;; +- esac +- # Japanese Language versions have a version number like `4.1.3-JL'. +- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` +- exit ;; +- sun3*:SunOS:*:*) +- echo m68k-sun-sunos${UNAME_RELEASE} +- exit ;; +- sun*:*:4.2BSD:*) +- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` +- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 +- case "`/bin/arch`" in +- sun3) +- echo m68k-sun-sunos${UNAME_RELEASE} +- ;; +- sun4) +- echo sparc-sun-sunos${UNAME_RELEASE} +- ;; +- esac +- exit ;; +- aushp:SunOS:*:*) +- echo sparc-auspex-sunos${UNAME_RELEASE} +- exit ;; +- # The situation for MiNT is a little confusing. The machine name +- # can be virtually everything (everything which is not +- # "atarist" or "atariste" at least should have a processor +- # > m68000). The system name ranges from "MiNT" over "FreeMiNT" +- # to the lowercase version "mint" (or "freemint"). Finally +- # the system name "TOS" denotes a system which is actually not +- # MiNT. But MiNT is downward compatible to TOS, so this should +- # be no problem. +- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) +- echo m68k-atari-mint${UNAME_RELEASE} +- exit ;; +- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) +- echo m68k-atari-mint${UNAME_RELEASE} +- exit ;; +- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) +- echo m68k-atari-mint${UNAME_RELEASE} +- exit ;; +- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) +- echo m68k-milan-mint${UNAME_RELEASE} +- exit ;; +- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) +- echo m68k-hades-mint${UNAME_RELEASE} +- exit ;; +- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) +- echo m68k-unknown-mint${UNAME_RELEASE} +- exit ;; +- m68k:machten:*:*) +- echo m68k-apple-machten${UNAME_RELEASE} +- exit ;; +- powerpc:machten:*:*) +- echo powerpc-apple-machten${UNAME_RELEASE} +- exit ;; +- RISC*:Mach:*:*) +- echo mips-dec-mach_bsd4.3 +- exit ;; +- RISC*:ULTRIX:*:*) +- echo mips-dec-ultrix${UNAME_RELEASE} +- exit ;; +- VAX*:ULTRIX*:*:*) +- echo vax-dec-ultrix${UNAME_RELEASE} +- exit ;; +- 2020:CLIX:*:* | 2430:CLIX:*:*) +- echo clipper-intergraph-clix${UNAME_RELEASE} +- exit ;; +- mips:*:*:UMIPS | mips:*:*:RISCos) +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +-#ifdef __cplusplus +-#include /* for printf() prototype */ +- int main (int argc, char *argv[]) { +-#else +- int main (argc, argv) int argc; char *argv[]; { +-#endif +- #if defined (host_mips) && defined (MIPSEB) +- #if defined (SYSTYPE_SYSV) +- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); +- #endif +- #if defined (SYSTYPE_SVR4) +- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); +- #endif +- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) +- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); +- #endif +- #endif +- exit (-1); +- } +-EOF +- $CC_FOR_BUILD -o $dummy $dummy.c && +- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && +- SYSTEM_NAME=`$dummy $dummyarg` && +- { echo "$SYSTEM_NAME"; exit; } +- echo mips-mips-riscos${UNAME_RELEASE} +- exit ;; +- Motorola:PowerMAX_OS:*:*) +- echo powerpc-motorola-powermax +- exit ;; +- Motorola:*:4.3:PL8-*) +- echo powerpc-harris-powermax +- exit ;; +- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) +- echo powerpc-harris-powermax +- exit ;; +- Night_Hawk:Power_UNIX:*:*) +- echo powerpc-harris-powerunix +- exit ;; +- m88k:CX/UX:7*:*) +- echo m88k-harris-cxux7 +- exit ;; +- m88k:*:4*:R4*) +- echo m88k-motorola-sysv4 +- exit ;; +- m88k:*:3*:R3*) +- echo m88k-motorola-sysv3 +- exit ;; +- AViiON:dgux:*:*) +- # DG/UX returns AViiON for all architectures +- UNAME_PROCESSOR=`/usr/bin/uname -p` +- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] +- then +- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ +- [ ${TARGET_BINARY_INTERFACE}x = x ] +- then +- echo m88k-dg-dgux${UNAME_RELEASE} +- else +- echo m88k-dg-dguxbcs${UNAME_RELEASE} +- fi +- else +- echo i586-dg-dgux${UNAME_RELEASE} +- fi +- exit ;; +- M88*:DolphinOS:*:*) # DolphinOS (SVR3) +- echo m88k-dolphin-sysv3 +- exit ;; +- M88*:*:R3*:*) +- # Delta 88k system running SVR3 +- echo m88k-motorola-sysv3 +- exit ;; +- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) +- echo m88k-tektronix-sysv3 +- exit ;; +- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) +- echo m68k-tektronix-bsd +- exit ;; +- *:IRIX*:*:*) +- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` +- exit ;; +- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. +- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id +- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' +- i*86:AIX:*:*) +- echo i386-ibm-aix +- exit ;; +- ia64:AIX:*:*) +- if [ -x /usr/bin/oslevel ] ; then +- IBM_REV=`/usr/bin/oslevel` +- else +- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} +- fi +- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} +- exit ;; +- *:AIX:2:3) +- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- #include +- +- main() +- { +- if (!__power_pc()) +- exit(1); +- puts("powerpc-ibm-aix3.2.5"); +- exit(0); +- } +-EOF +- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` +- then +- echo "$SYSTEM_NAME" +- else +- echo rs6000-ibm-aix3.2.5 +- fi +- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then +- echo rs6000-ibm-aix3.2.4 +- else +- echo rs6000-ibm-aix3.2 +- fi +- exit ;; +- *:AIX:*:[4567]) +- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` +- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then +- IBM_ARCH=rs6000 +- else +- IBM_ARCH=powerpc +- fi +- if [ -x /usr/bin/oslevel ] ; then +- IBM_REV=`/usr/bin/oslevel` +- else +- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} +- fi +- echo ${IBM_ARCH}-ibm-aix${IBM_REV} +- exit ;; +- *:AIX:*:*) +- echo rs6000-ibm-aix +- exit ;; +- ibmrt:4.4BSD:*|romp-ibm:BSD:*) +- echo romp-ibm-bsd4.4 +- exit ;; +- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and +- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to +- exit ;; # report: romp-ibm BSD 4.3 +- *:BOSX:*:*) +- echo rs6000-bull-bosx +- exit ;; +- DPX/2?00:B.O.S.:*:*) +- echo m68k-bull-sysv3 +- exit ;; +- 9000/[34]??:4.3bsd:1.*:*) +- echo m68k-hp-bsd +- exit ;; +- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) +- echo m68k-hp-bsd4.4 +- exit ;; +- 9000/[34678]??:HP-UX:*:*) +- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` +- case "${UNAME_MACHINE}" in +- 9000/31? ) HP_ARCH=m68000 ;; +- 9000/[34]?? ) HP_ARCH=m68k ;; +- 9000/[678][0-9][0-9]) +- if [ -x /usr/bin/getconf ]; then +- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` +- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` +- case "${sc_cpu_version}" in +- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 +- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 +- 532) # CPU_PA_RISC2_0 +- case "${sc_kernel_bits}" in +- 32) HP_ARCH="hppa2.0n" ;; +- 64) HP_ARCH="hppa2.0w" ;; +- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 +- esac ;; +- esac +- fi +- if [ "${HP_ARCH}" = "" ]; then +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- +- #define _HPUX_SOURCE +- #include +- #include +- +- int main () +- { +- #if defined(_SC_KERNEL_BITS) +- long bits = sysconf(_SC_KERNEL_BITS); +- #endif +- long cpu = sysconf (_SC_CPU_VERSION); +- +- switch (cpu) +- { +- case CPU_PA_RISC1_0: puts ("hppa1.0"); break; +- case CPU_PA_RISC1_1: puts ("hppa1.1"); break; +- case CPU_PA_RISC2_0: +- #if defined(_SC_KERNEL_BITS) +- switch (bits) +- { +- case 64: puts ("hppa2.0w"); break; +- case 32: puts ("hppa2.0n"); break; +- default: puts ("hppa2.0"); break; +- } break; +- #else /* !defined(_SC_KERNEL_BITS) */ +- puts ("hppa2.0"); break; +- #endif +- default: puts ("hppa1.0"); break; +- } +- exit (0); +- } +-EOF +- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` +- test -z "$HP_ARCH" && HP_ARCH=hppa +- fi ;; +- esac +- if [ ${HP_ARCH} = "hppa2.0w" ] +- then +- eval $set_cc_for_build +- +- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating +- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler +- # generating 64-bit code. GNU and HP use different nomenclature: +- # +- # $ CC_FOR_BUILD=cc ./config.guess +- # => hppa2.0w-hp-hpux11.23 +- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess +- # => hppa64-hp-hpux11.23 +- +- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | +- grep -q __LP64__ +- then +- HP_ARCH="hppa2.0w" +- else +- HP_ARCH="hppa64" +- fi +- fi +- echo ${HP_ARCH}-hp-hpux${HPUX_REV} +- exit ;; +- ia64:HP-UX:*:*) +- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` +- echo ia64-hp-hpux${HPUX_REV} +- exit ;; +- 3050*:HI-UX:*:*) +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- #include +- int +- main () +- { +- long cpu = sysconf (_SC_CPU_VERSION); +- /* The order matters, because CPU_IS_HP_MC68K erroneously returns +- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct +- results, however. */ +- if (CPU_IS_PA_RISC (cpu)) +- { +- switch (cpu) +- { +- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; +- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; +- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; +- default: puts ("hppa-hitachi-hiuxwe2"); break; +- } +- } +- else if (CPU_IS_HP_MC68K (cpu)) +- puts ("m68k-hitachi-hiuxwe2"); +- else puts ("unknown-hitachi-hiuxwe2"); +- exit (0); +- } +-EOF +- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && +- { echo "$SYSTEM_NAME"; exit; } +- echo unknown-hitachi-hiuxwe2 +- exit ;; +- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) +- echo hppa1.1-hp-bsd +- exit ;; +- 9000/8??:4.3bsd:*:*) +- echo hppa1.0-hp-bsd +- exit ;; +- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) +- echo hppa1.0-hp-mpeix +- exit ;; +- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) +- echo hppa1.1-hp-osf +- exit ;; +- hp8??:OSF1:*:*) +- echo hppa1.0-hp-osf +- exit ;; +- i*86:OSF1:*:*) +- if [ -x /usr/sbin/sysversion ] ; then +- echo ${UNAME_MACHINE}-unknown-osf1mk +- else +- echo ${UNAME_MACHINE}-unknown-osf1 +- fi +- exit ;; +- parisc*:Lites*:*:*) +- echo hppa1.1-hp-lites +- exit ;; +- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) +- echo c1-convex-bsd +- exit ;; +- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) +- if getsysinfo -f scalar_acc +- then echo c32-convex-bsd +- else echo c2-convex-bsd +- fi +- exit ;; +- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) +- echo c34-convex-bsd +- exit ;; +- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) +- echo c38-convex-bsd +- exit ;; +- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) +- echo c4-convex-bsd +- exit ;; +- CRAY*Y-MP:*:*:*) +- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- CRAY*[A-Z]90:*:*:*) +- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ +- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ +- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ +- -e 's/\.[^.]*$/.X/' +- exit ;; +- CRAY*TS:*:*:*) +- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- CRAY*T3E:*:*:*) +- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- CRAY*SV1:*:*:*) +- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- *:UNICOS/mp:*:*) +- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' +- exit ;; +- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) +- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` +- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` +- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` +- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" +- exit ;; +- 5000:UNIX_System_V:4.*:*) +- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` +- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` +- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" +- exit ;; +- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) +- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} +- exit ;; +- sparc*:BSD/OS:*:*) +- echo sparc-unknown-bsdi${UNAME_RELEASE} +- exit ;; +- *:BSD/OS:*:*) +- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} +- exit ;; +- *:FreeBSD:*:*) +- UNAME_PROCESSOR=`/usr/bin/uname -p` +- case ${UNAME_PROCESSOR} in +- amd64) +- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; +- *) +- echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; +- esac +- exit ;; +- i*:CYGWIN*:*) +- echo ${UNAME_MACHINE}-pc-cygwin +- exit ;; +- *:MINGW64*:*) +- echo ${UNAME_MACHINE}-pc-mingw64 +- exit ;; +- *:MINGW*:*) +- echo ${UNAME_MACHINE}-pc-mingw32 +- exit ;; +- *:MSYS*:*) +- echo ${UNAME_MACHINE}-pc-msys +- exit ;; +- i*:windows32*:*) +- # uname -m includes "-pc" on this system. +- echo ${UNAME_MACHINE}-mingw32 +- exit ;; +- i*:PW*:*) +- echo ${UNAME_MACHINE}-pc-pw32 +- exit ;; +- *:Interix*:*) +- case ${UNAME_MACHINE} in +- x86) +- echo i586-pc-interix${UNAME_RELEASE} +- exit ;; +- authenticamd | genuineintel | EM64T) +- echo x86_64-unknown-interix${UNAME_RELEASE} +- exit ;; +- IA64) +- echo ia64-unknown-interix${UNAME_RELEASE} +- exit ;; +- esac ;; +- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) +- echo i${UNAME_MACHINE}-pc-mks +- exit ;; +- 8664:Windows_NT:*) +- echo x86_64-pc-mks +- exit ;; +- i*:Windows_NT*:* | Pentium*:Windows_NT*:*) +- # How do we know it's Interix rather than the generic POSIX subsystem? +- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we +- # UNAME_MACHINE based on the output of uname instead of i386? +- echo i586-pc-interix +- exit ;; +- i*:UWIN*:*) +- echo ${UNAME_MACHINE}-pc-uwin +- exit ;; +- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) +- echo x86_64-unknown-cygwin +- exit ;; +- p*:CYGWIN*:*) +- echo powerpcle-unknown-cygwin +- exit ;; +- prep*:SunOS:5.*:*) +- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` +- exit ;; +- *:GNU:*:*) +- # the GNU system +- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` +- exit ;; +- *:GNU/*:*:*) +- # other systems with GNU libc and userland +- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} +- exit ;; +- i*86:Minix:*:*) +- echo ${UNAME_MACHINE}-pc-minix +- exit ;; +- aarch64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- aarch64_be:Linux:*:*) +- UNAME_MACHINE=aarch64_be +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- alpha:Linux:*:*) +- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in +- EV5) UNAME_MACHINE=alphaev5 ;; +- EV56) UNAME_MACHINE=alphaev56 ;; +- PCA56) UNAME_MACHINE=alphapca56 ;; +- PCA57) UNAME_MACHINE=alphapca56 ;; +- EV6) UNAME_MACHINE=alphaev6 ;; +- EV67) UNAME_MACHINE=alphaev67 ;; +- EV68*) UNAME_MACHINE=alphaev68 ;; +- esac +- objdump --private-headers /bin/sh | grep -q ld.so.1 +- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- arc:Linux:*:* | arceb:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- arm*:Linux:*:*) +- eval $set_cc_for_build +- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ +- | grep -q __ARM_EABI__ +- then +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- else +- if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ +- | grep -q __ARM_PCS_VFP +- then +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi +- else +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf +- fi +- fi +- exit ;; +- avr32*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- cris:Linux:*:*) +- echo ${UNAME_MACHINE}-axis-linux-${LIBC} +- exit ;; +- crisv32:Linux:*:*) +- echo ${UNAME_MACHINE}-axis-linux-${LIBC} +- exit ;; +- frv:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- hexagon:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- i*86:Linux:*:*) +- echo ${UNAME_MACHINE}-pc-linux-${LIBC} +- exit ;; +- ia64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- m32r*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- m68*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- mips:Linux:*:* | mips64:Linux:*:*) +- eval $set_cc_for_build +- sed 's/^ //' << EOF >$dummy.c +- #undef CPU +- #undef ${UNAME_MACHINE} +- #undef ${UNAME_MACHINE}el +- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) +- CPU=${UNAME_MACHINE}el +- #else +- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) +- CPU=${UNAME_MACHINE} +- #else +- CPU= +- #endif +- #endif +-EOF +- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` +- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } +- ;; +- openrisc*:Linux:*:*) +- echo or1k-unknown-linux-${LIBC} +- exit ;; +- or32:Linux:*:* | or1k*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- padre:Linux:*:*) +- echo sparc-unknown-linux-${LIBC} +- exit ;; +- parisc64:Linux:*:* | hppa64:Linux:*:*) +- echo hppa64-unknown-linux-${LIBC} +- exit ;; +- parisc:Linux:*:* | hppa:Linux:*:*) +- # Look for CPU level +- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in +- PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; +- PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; +- *) echo hppa-unknown-linux-${LIBC} ;; +- esac +- exit ;; +- ppc64:Linux:*:*) +- echo powerpc64-unknown-linux-${LIBC} +- exit ;; +- ppc:Linux:*:*) +- echo powerpc-unknown-linux-${LIBC} +- exit ;; +- ppc64le:Linux:*:*) +- echo powerpc64le-unknown-linux-${LIBC} +- exit ;; +- ppcle:Linux:*:*) +- echo powerpcle-unknown-linux-${LIBC} +- exit ;; +- s390:Linux:*:* | s390x:Linux:*:*) +- echo ${UNAME_MACHINE}-ibm-linux-${LIBC} +- exit ;; +- sh64*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- sh*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- sparc:Linux:*:* | sparc64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- tile*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- vax:Linux:*:*) +- echo ${UNAME_MACHINE}-dec-linux-${LIBC} +- exit ;; +- x86_64:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- xtensa*:Linux:*:*) +- echo ${UNAME_MACHINE}-unknown-linux-${LIBC} +- exit ;; +- i*86:DYNIX/ptx:4*:*) +- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. +- # earlier versions are messed up and put the nodename in both +- # sysname and nodename. +- echo i386-sequent-sysv4 +- exit ;; +- i*86:UNIX_SV:4.2MP:2.*) +- # Unixware is an offshoot of SVR4, but it has its own version +- # number series starting with 2... +- # I am not positive that other SVR4 systems won't match this, +- # I just have to hope. -- rms. +- # Use sysv4.2uw... so that sysv4* matches it. +- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} +- exit ;; +- i*86:OS/2:*:*) +- # If we were able to find `uname', then EMX Unix compatibility +- # is probably installed. +- echo ${UNAME_MACHINE}-pc-os2-emx +- exit ;; +- i*86:XTS-300:*:STOP) +- echo ${UNAME_MACHINE}-unknown-stop +- exit ;; +- i*86:atheos:*:*) +- echo ${UNAME_MACHINE}-unknown-atheos +- exit ;; +- i*86:syllable:*:*) +- echo ${UNAME_MACHINE}-pc-syllable +- exit ;; +- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) +- echo i386-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- i*86:*DOS:*:*) +- echo ${UNAME_MACHINE}-pc-msdosdjgpp +- exit ;; +- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) +- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` +- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then +- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} +- else +- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} +- fi +- exit ;; +- i*86:*:5:[678]*) +- # UnixWare 7.x, OpenUNIX and OpenServer 6. +- case `/bin/uname -X | grep "^Machine"` in +- *486*) UNAME_MACHINE=i486 ;; +- *Pentium) UNAME_MACHINE=i586 ;; +- *Pent*|*Celeron) UNAME_MACHINE=i686 ;; +- esac +- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} +- exit ;; +- i*86:*:3.2:*) +- if test -f /usr/options/cb.name; then +- UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then +- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` +- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 +- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ +- && UNAME_MACHINE=i586 +- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ +- && UNAME_MACHINE=i686 +- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ +- && UNAME_MACHINE=i686 +- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL +- else +- echo ${UNAME_MACHINE}-pc-sysv32 +- fi +- exit ;; +- pc:*:*:*) +- # Left here for compatibility: +- # uname -m prints for DJGPP always 'pc', but it prints nothing about +- # the processor, so we play safe by assuming i586. +- # Note: whatever this is, it MUST be the same as what config.sub +- # prints for the "djgpp" host, or else GDB configury will decide that +- # this is a cross-build. +- echo i586-pc-msdosdjgpp +- exit ;; +- Intel:Mach:3*:*) +- echo i386-pc-mach3 +- exit ;; +- paragon:*:*:*) +- echo i860-intel-osf1 +- exit ;; +- i860:*:4.*:*) # i860-SVR4 +- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then +- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 +- else # Add other i860-SVR4 vendors below as they are discovered. +- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 +- fi +- exit ;; +- mini*:CTIX:SYS*5:*) +- # "miniframe" +- echo m68010-convergent-sysv +- exit ;; +- mc68k:UNIX:SYSTEM5:3.51m) +- echo m68k-convergent-sysv +- exit ;; +- M680?0:D-NIX:5.3:*) +- echo m68k-diab-dnix +- exit ;; +- M68*:*:R3V[5678]*:*) +- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; +- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) +- OS_REL='' +- test -r /etc/.relid \ +- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` +- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ +- && { echo i486-ncr-sysv4.3${OS_REL}; exit; } +- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ +- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; +- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) +- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ +- && { echo i486-ncr-sysv4; exit; } ;; +- NCR*:*:4.2:* | MPRAS*:*:4.2:*) +- OS_REL='.3' +- test -r /etc/.relid \ +- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` +- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ +- && { echo i486-ncr-sysv4.3${OS_REL}; exit; } +- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ +- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } +- /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ +- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; +- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) +- echo m68k-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- mc68030:UNIX_System_V:4.*:*) +- echo m68k-atari-sysv4 +- exit ;; +- TSUNAMI:LynxOS:2.*:*) +- echo sparc-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- rs6000:LynxOS:2.*:*) +- echo rs6000-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) +- echo powerpc-unknown-lynxos${UNAME_RELEASE} +- exit ;; +- SM[BE]S:UNIX_SV:*:*) +- echo mips-dde-sysv${UNAME_RELEASE} +- exit ;; +- RM*:ReliantUNIX-*:*:*) +- echo mips-sni-sysv4 +- exit ;; +- RM*:SINIX-*:*:*) +- echo mips-sni-sysv4 +- exit ;; +- *:SINIX-*:*:*) +- if uname -p 2>/dev/null >/dev/null ; then +- UNAME_MACHINE=`(uname -p) 2>/dev/null` +- echo ${UNAME_MACHINE}-sni-sysv4 +- else +- echo ns32k-sni-sysv +- fi +- exit ;; +- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort +- # says +- echo i586-unisys-sysv4 +- exit ;; +- *:UNIX_System_V:4*:FTX*) +- # From Gerald Hewes . +- # How about differentiating between stratus architectures? -djm +- echo hppa1.1-stratus-sysv4 +- exit ;; +- *:*:*:FTX*) +- # From seanf@swdc.stratus.com. +- echo i860-stratus-sysv4 +- exit ;; +- i*86:VOS:*:*) +- # From Paul.Green@stratus.com. +- echo ${UNAME_MACHINE}-stratus-vos +- exit ;; +- *:VOS:*:*) +- # From Paul.Green@stratus.com. +- echo hppa1.1-stratus-vos +- exit ;; +- mc68*:A/UX:*:*) +- echo m68k-apple-aux${UNAME_RELEASE} +- exit ;; +- news*:NEWS-OS:6*:*) +- echo mips-sony-newsos6 +- exit ;; +- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) +- if [ -d /usr/nec ]; then +- echo mips-nec-sysv${UNAME_RELEASE} +- else +- echo mips-unknown-sysv${UNAME_RELEASE} +- fi +- exit ;; +- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. +- echo powerpc-be-beos +- exit ;; +- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. +- echo powerpc-apple-beos +- exit ;; +- BePC:BeOS:*:*) # BeOS running on Intel PC compatible. +- echo i586-pc-beos +- exit ;; +- BePC:Haiku:*:*) # Haiku running on Intel PC compatible. +- echo i586-pc-haiku +- exit ;; +- x86_64:Haiku:*:*) +- echo x86_64-unknown-haiku +- exit ;; +- SX-4:SUPER-UX:*:*) +- echo sx4-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-5:SUPER-UX:*:*) +- echo sx5-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-6:SUPER-UX:*:*) +- echo sx6-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-7:SUPER-UX:*:*) +- echo sx7-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-8:SUPER-UX:*:*) +- echo sx8-nec-superux${UNAME_RELEASE} +- exit ;; +- SX-8R:SUPER-UX:*:*) +- echo sx8r-nec-superux${UNAME_RELEASE} +- exit ;; +- Power*:Rhapsody:*:*) +- echo powerpc-apple-rhapsody${UNAME_RELEASE} +- exit ;; +- *:Rhapsody:*:*) +- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} +- exit ;; +- *:Darwin:*:*) +- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown +- eval $set_cc_for_build +- if test "$UNAME_PROCESSOR" = unknown ; then +- UNAME_PROCESSOR=powerpc +- fi +- if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then +- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then +- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ +- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ +- grep IS_64BIT_ARCH >/dev/null +- then +- case $UNAME_PROCESSOR in +- i386) UNAME_PROCESSOR=x86_64 ;; +- powerpc) UNAME_PROCESSOR=powerpc64 ;; +- esac +- fi +- fi +- elif test "$UNAME_PROCESSOR" = i386 ; then +- # Avoid executing cc on OS X 10.9, as it ships with a stub +- # that puts up a graphical alert prompting to install +- # developer tools. Any system running Mac OS X 10.7 or +- # later (Darwin 11 and later) is required to have a 64-bit +- # processor. This is not true of the ARM version of Darwin +- # that Apple uses in portable devices. +- UNAME_PROCESSOR=x86_64 +- fi +- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} +- exit ;; +- *:procnto*:*:* | *:QNX:[0123456789]*:*) +- UNAME_PROCESSOR=`uname -p` +- if test "$UNAME_PROCESSOR" = "x86"; then +- UNAME_PROCESSOR=i386 +- UNAME_MACHINE=pc +- fi +- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} +- exit ;; +- *:QNX:*:4*) +- echo i386-pc-qnx +- exit ;; +- NEO-?:NONSTOP_KERNEL:*:*) +- echo neo-tandem-nsk${UNAME_RELEASE} +- exit ;; +- NSE-*:NONSTOP_KERNEL:*:*) +- echo nse-tandem-nsk${UNAME_RELEASE} +- exit ;; +- NSR-?:NONSTOP_KERNEL:*:*) +- echo nsr-tandem-nsk${UNAME_RELEASE} +- exit ;; +- *:NonStop-UX:*:*) +- echo mips-compaq-nonstopux +- exit ;; +- BS2000:POSIX*:*:*) +- echo bs2000-siemens-sysv +- exit ;; +- DS/*:UNIX_System_V:*:*) +- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} +- exit ;; +- *:Plan9:*:*) +- # "uname -m" is not consistent, so use $cputype instead. 386 +- # is converted to i386 for consistency with other x86 +- # operating systems. +- if test "$cputype" = "386"; then +- UNAME_MACHINE=i386 +- else +- UNAME_MACHINE="$cputype" +- fi +- echo ${UNAME_MACHINE}-unknown-plan9 +- exit ;; +- *:TOPS-10:*:*) +- echo pdp10-unknown-tops10 +- exit ;; +- *:TENEX:*:*) +- echo pdp10-unknown-tenex +- exit ;; +- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) +- echo pdp10-dec-tops20 +- exit ;; +- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) +- echo pdp10-xkl-tops20 +- exit ;; +- *:TOPS-20:*:*) +- echo pdp10-unknown-tops20 +- exit ;; +- *:ITS:*:*) +- echo pdp10-unknown-its +- exit ;; +- SEI:*:*:SEIUX) +- echo mips-sei-seiux${UNAME_RELEASE} +- exit ;; +- *:DragonFly:*:*) +- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` +- exit ;; +- *:*VMS:*:*) +- UNAME_MACHINE=`(uname -p) 2>/dev/null` +- case "${UNAME_MACHINE}" in +- A*) echo alpha-dec-vms ; exit ;; +- I*) echo ia64-dec-vms ; exit ;; +- V*) echo vax-dec-vms ; exit ;; +- esac ;; +- *:XENIX:*:SysV) +- echo i386-pc-xenix +- exit ;; +- i*86:skyos:*:*) +- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' +- exit ;; +- i*86:rdos:*:*) +- echo ${UNAME_MACHINE}-pc-rdos +- exit ;; +- i*86:AROS:*:*) +- echo ${UNAME_MACHINE}-pc-aros +- exit ;; +- x86_64:VMkernel:*:*) +- echo ${UNAME_MACHINE}-unknown-esx +- exit ;; +-esac +- +-cat >&2 < in order to provide the needed +-information to handle your system. +- +-config.guess timestamp = $timestamp +- +-uname -m = `(uname -m) 2>/dev/null || echo unknown` +-uname -r = `(uname -r) 2>/dev/null || echo unknown` +-uname -s = `(uname -s) 2>/dev/null || echo unknown` +-uname -v = `(uname -v) 2>/dev/null || echo unknown` +- +-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +-/bin/uname -X = `(/bin/uname -X) 2>/dev/null` +- +-hostinfo = `(hostinfo) 2>/dev/null` +-/bin/universe = `(/bin/universe) 2>/dev/null` +-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +-/bin/arch = `(/bin/arch) 2>/dev/null` +-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` +- +-UNAME_MACHINE = ${UNAME_MACHINE} +-UNAME_RELEASE = ${UNAME_RELEASE} +-UNAME_SYSTEM = ${UNAME_SYSTEM} +-UNAME_VERSION = ${UNAME_VERSION} +-EOF +- +-exit 1 +- +-# Local variables: +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "timestamp='" +-# time-stamp-format: "%:y-%02m-%02d" +-# time-stamp-end: "'" +-# End: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/build-aux/config.sub groff-1.22.3/src/libs/gnulib/build-aux/config.sub +--- groff-1.22.3.old/src/libs/gnulib/build-aux/config.sub 2014-11-04 10:38:35.646518734 +0200 ++++ groff-1.22.3/src/libs/gnulib/build-aux/config.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1805 +0,0 @@ +-#! /bin/sh +-# Configuration validation subroutine script. +-# Copyright 1992-2014 Free Software Foundation, Inc. +- +-timestamp='2014-09-26' +- +-# This file is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 3 of the License, or +-# (at your option) any later version. +-# +-# This program is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program; if not, see . +-# +-# As a special exception to the GNU General Public License, if you +-# distribute this file as part of a program that contains a +-# configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that +-# program. This Exception is an additional permission under section 7 +-# of the GNU General Public License, version 3 ("GPLv3"). +- +- +-# Please send patches with a ChangeLog entry to config-patches@gnu.org. +-# +-# Configuration subroutine to validate and canonicalize a configuration type. +-# Supply the specified configuration type as an argument. +-# If it is invalid, we print an error message on stderr and exit with code 1. +-# Otherwise, we print the canonical config type on stdout and succeed. +- +-# You can get the latest version of this script from: +-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +- +-# This file is supposed to be the same for all GNU packages +-# and recognize all the CPU types, system types and aliases +-# that are meaningful with *any* GNU software. +-# Each package is responsible for reporting which valid configurations +-# it does not support. The user should be able to distinguish +-# a failure to support a valid configuration from a meaningless +-# configuration. +- +-# The goal of this file is to map all the various variations of a given +-# machine specification into a single specification in the form: +-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +-# or in some cases, the newer four-part form: +-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +-# It is wrong to echo any other type of specification. +- +-me=`echo "$0" | sed -e 's,.*/,,'` +- +-usage="\ +-Usage: $0 [OPTION] CPU-MFR-OPSYS +- $0 [OPTION] ALIAS +- +-Canonicalize a configuration name. +- +-Operation modes: +- -h, --help print this help, then exit +- -t, --time-stamp print date of last modification, then exit +- -v, --version print version number, then exit +- +-Report bugs and patches to ." +- +-version="\ +-GNU config.sub ($timestamp) +- +-Copyright 1992-2014 Free Software Foundation, Inc. +- +-This is free software; see the source for copying conditions. There is NO +-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +- +-help=" +-Try \`$me --help' for more information." +- +-# Parse command line +-while test $# -gt 0 ; do +- case $1 in +- --time-stamp | --time* | -t ) +- echo "$timestamp" ; exit ;; +- --version | -v ) +- echo "$version" ; exit ;; +- --help | --h* | -h ) +- echo "$usage"; exit ;; +- -- ) # Stop option processing +- shift; break ;; +- - ) # Use stdin as input. +- break ;; +- -* ) +- echo "$me: invalid option $1$help" +- exit 1 ;; +- +- *local*) +- # First pass through any local machine types. +- echo $1 +- exit ;; +- +- * ) +- break ;; +- esac +-done +- +-case $# in +- 0) echo "$me: missing argument$help" >&2 +- exit 1;; +- 1) ;; +- *) echo "$me: too many arguments$help" >&2 +- exit 1;; +-esac +- +-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +-# Here we must recognize all the valid KERNEL-OS combinations. +-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +-case $maybe_os in +- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ +- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ +- knetbsd*-gnu* | netbsd*-gnu* | \ +- kopensolaris*-gnu* | \ +- storm-chaos* | os2-emx* | rtmk-nova*) +- os=-$maybe_os +- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` +- ;; +- android-linux) +- os=-linux-android +- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown +- ;; +- *) +- basic_machine=`echo $1 | sed 's/-[^-]*$//'` +- if [ $basic_machine != $1 ] +- then os=`echo $1 | sed 's/.*-/-/'` +- else os=; fi +- ;; +-esac +- +-### Let's recognize common machines as not being operating systems so +-### that things like config.sub decstation-3100 work. We also +-### recognize some manufacturers as not being operating systems, so we +-### can provide default operating systems below. +-case $os in +- -sun*os*) +- # Prevent following clause from handling this invalid input. +- ;; +- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ +- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ +- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ +- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ +- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ +- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ +- -apple | -axis | -knuth | -cray | -microblaze*) +- os= +- basic_machine=$1 +- ;; +- -bluegene*) +- os=-cnk +- ;; +- -sim | -cisco | -oki | -wec | -winbond) +- os= +- basic_machine=$1 +- ;; +- -scout) +- ;; +- -wrs) +- os=-vxworks +- basic_machine=$1 +- ;; +- -chorusos*) +- os=-chorusos +- basic_machine=$1 +- ;; +- -chorusrdb) +- os=-chorusrdb +- basic_machine=$1 +- ;; +- -hiux*) +- os=-hiuxwe2 +- ;; +- -sco6) +- os=-sco5v6 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco5) +- os=-sco3.2v5 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco4) +- os=-sco3.2v4 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco3.2.[4-9]*) +- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco3.2v[4-9]*) +- # Don't forget version if it is 3.2v4 or newer. +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco5v6*) +- # Don't forget version if it is 3.2v4 or newer. +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -sco*) +- os=-sco3.2v2 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -udk*) +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -isc) +- os=-isc2.2 +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -clix*) +- basic_machine=clipper-intergraph +- ;; +- -isc*) +- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` +- ;; +- -lynx*178) +- os=-lynxos178 +- ;; +- -lynx*5) +- os=-lynxos5 +- ;; +- -lynx*) +- os=-lynxos +- ;; +- -ptx*) +- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` +- ;; +- -windowsnt*) +- os=`echo $os | sed -e 's/windowsnt/winnt/'` +- ;; +- -psos*) +- os=-psos +- ;; +- -mint | -mint[0-9]*) +- basic_machine=m68k-atari +- os=-mint +- ;; +-esac +- +-# Decode aliases for certain CPU-COMPANY combinations. +-case $basic_machine in +- # Recognize the basic CPU types without company name. +- # Some are omitted here because they have special meanings below. +- 1750a | 580 \ +- | a29k \ +- | aarch64 | aarch64_be \ +- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ +- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ +- | am33_2.0 \ +- | arc | arceb \ +- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ +- | avr | avr32 \ +- | be32 | be64 \ +- | bfin \ +- | c4x | c8051 | clipper \ +- | d10v | d30v | dlx | dsp16xx \ +- | epiphany \ +- | fido | fr30 | frv \ +- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ +- | hexagon \ +- | i370 | i860 | i960 | ia64 \ +- | ip2k | iq2000 \ +- | k1om \ +- | le32 | le64 \ +- | lm32 \ +- | m32c | m32r | m32rle | m68000 | m68k | m88k \ +- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ +- | mips | mipsbe | mipseb | mipsel | mipsle \ +- | mips16 \ +- | mips64 | mips64el \ +- | mips64octeon | mips64octeonel \ +- | mips64orion | mips64orionel \ +- | mips64r5900 | mips64r5900el \ +- | mips64vr | mips64vrel \ +- | mips64vr4100 | mips64vr4100el \ +- | mips64vr4300 | mips64vr4300el \ +- | mips64vr5000 | mips64vr5000el \ +- | mips64vr5900 | mips64vr5900el \ +- | mipsisa32 | mipsisa32el \ +- | mipsisa32r2 | mipsisa32r2el \ +- | mipsisa32r6 | mipsisa32r6el \ +- | mipsisa64 | mipsisa64el \ +- | mipsisa64r2 | mipsisa64r2el \ +- | mipsisa64r6 | mipsisa64r6el \ +- | mipsisa64sb1 | mipsisa64sb1el \ +- | mipsisa64sr71k | mipsisa64sr71kel \ +- | mipsr5900 | mipsr5900el \ +- | mipstx39 | mipstx39el \ +- | mn10200 | mn10300 \ +- | moxie \ +- | mt \ +- | msp430 \ +- | nds32 | nds32le | nds32be \ +- | nios | nios2 | nios2eb | nios2el \ +- | ns16k | ns32k \ +- | open8 | or1k | or1knd | or32 \ +- | pdp10 | pdp11 | pj | pjl \ +- | powerpc | powerpc64 | powerpc64le | powerpcle \ +- | pyramid \ +- | riscv32 | riscv64 \ +- | rl78 | rx \ +- | score \ +- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ +- | sh64 | sh64le \ +- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ +- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ +- | spu \ +- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ +- | ubicom32 \ +- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ +- | we32k \ +- | x86 | xc16x | xstormy16 | xtensa \ +- | z8k | z80) +- basic_machine=$basic_machine-unknown +- ;; +- c54x) +- basic_machine=tic54x-unknown +- ;; +- c55x) +- basic_machine=tic55x-unknown +- ;; +- c6x) +- basic_machine=tic6x-unknown +- ;; +- leon|leon[3-9]) +- basic_machine=sparc-$basic_machine +- ;; +- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) +- basic_machine=$basic_machine-unknown +- os=-none +- ;; +- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) +- ;; +- ms1) +- basic_machine=mt-unknown +- ;; +- +- strongarm | thumb | xscale) +- basic_machine=arm-unknown +- ;; +- xgate) +- basic_machine=$basic_machine-unknown +- os=-none +- ;; +- xscaleeb) +- basic_machine=armeb-unknown +- ;; +- +- xscaleel) +- basic_machine=armel-unknown +- ;; +- +- # We use `pc' rather than `unknown' +- # because (1) that's what they normally are, and +- # (2) the word "unknown" tends to confuse beginning users. +- i*86 | x86_64) +- basic_machine=$basic_machine-pc +- ;; +- # Object if more than one company name word. +- *-*-*) +- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 +- exit 1 +- ;; +- # Recognize the basic CPU types with company name. +- 580-* \ +- | a29k-* \ +- | aarch64-* | aarch64_be-* \ +- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ +- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ +- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ +- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ +- | avr-* | avr32-* \ +- | be32-* | be64-* \ +- | bfin-* | bs2000-* \ +- | c[123]* | c30-* | [cjt]90-* | c4x-* \ +- | c8051-* | clipper-* | craynv-* | cydra-* \ +- | d10v-* | d30v-* | dlx-* \ +- | elxsi-* \ +- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ +- | h8300-* | h8500-* \ +- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ +- | hexagon-* \ +- | i*86-* | i860-* | i960-* | ia64-* \ +- | ip2k-* | iq2000-* \ +- | k1om-* \ +- | le32-* | le64-* \ +- | lm32-* \ +- | m32c-* | m32r-* | m32rle-* \ +- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ +- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ +- | microblaze-* | microblazeel-* \ +- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ +- | mips16-* \ +- | mips64-* | mips64el-* \ +- | mips64octeon-* | mips64octeonel-* \ +- | mips64orion-* | mips64orionel-* \ +- | mips64r5900-* | mips64r5900el-* \ +- | mips64vr-* | mips64vrel-* \ +- | mips64vr4100-* | mips64vr4100el-* \ +- | mips64vr4300-* | mips64vr4300el-* \ +- | mips64vr5000-* | mips64vr5000el-* \ +- | mips64vr5900-* | mips64vr5900el-* \ +- | mipsisa32-* | mipsisa32el-* \ +- | mipsisa32r2-* | mipsisa32r2el-* \ +- | mipsisa32r6-* | mipsisa32r6el-* \ +- | mipsisa64-* | mipsisa64el-* \ +- | mipsisa64r2-* | mipsisa64r2el-* \ +- | mipsisa64r6-* | mipsisa64r6el-* \ +- | mipsisa64sb1-* | mipsisa64sb1el-* \ +- | mipsisa64sr71k-* | mipsisa64sr71kel-* \ +- | mipsr5900-* | mipsr5900el-* \ +- | mipstx39-* | mipstx39el-* \ +- | mmix-* \ +- | mt-* \ +- | msp430-* \ +- | nds32-* | nds32le-* | nds32be-* \ +- | nios-* | nios2-* | nios2eb-* | nios2el-* \ +- | none-* | np1-* | ns16k-* | ns32k-* \ +- | open8-* \ +- | or1k*-* \ +- | orion-* \ +- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ +- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ +- | pyramid-* \ +- | rl78-* | romp-* | rs6000-* | rx-* \ +- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ +- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ +- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ +- | sparclite-* \ +- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ +- | tahoe-* \ +- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ +- | tile*-* \ +- | tron-* \ +- | ubicom32-* \ +- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ +- | vax-* \ +- | we32k-* \ +- | x86-* | x86_64-* | xc16x-* | xps100-* \ +- | xstormy16-* | xtensa*-* \ +- | ymp-* \ +- | z8k-* | z80-*) +- ;; +- # Recognize the basic CPU types without company name, with glob match. +- xtensa*) +- basic_machine=$basic_machine-unknown +- ;; +- # Recognize the various machine names and aliases which stand +- # for a CPU type and a company and sometimes even an OS. +- 386bsd) +- basic_machine=i386-unknown +- os=-bsd +- ;; +- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) +- basic_machine=m68000-att +- ;; +- 3b*) +- basic_machine=we32k-att +- ;; +- a29khif) +- basic_machine=a29k-amd +- os=-udi +- ;; +- abacus) +- basic_machine=abacus-unknown +- ;; +- adobe68k) +- basic_machine=m68010-adobe +- os=-scout +- ;; +- alliant | fx80) +- basic_machine=fx80-alliant +- ;; +- altos | altos3068) +- basic_machine=m68k-altos +- ;; +- am29k) +- basic_machine=a29k-none +- os=-bsd +- ;; +- amd64) +- basic_machine=x86_64-pc +- ;; +- amd64-*) +- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- amdahl) +- basic_machine=580-amdahl +- os=-sysv +- ;; +- amiga | amiga-*) +- basic_machine=m68k-unknown +- ;; +- amigaos | amigados) +- basic_machine=m68k-unknown +- os=-amigaos +- ;; +- amigaunix | amix) +- basic_machine=m68k-unknown +- os=-sysv4 +- ;; +- apollo68) +- basic_machine=m68k-apollo +- os=-sysv +- ;; +- apollo68bsd) +- basic_machine=m68k-apollo +- os=-bsd +- ;; +- aros) +- basic_machine=i386-pc +- os=-aros +- ;; +- aux) +- basic_machine=m68k-apple +- os=-aux +- ;; +- balance) +- basic_machine=ns32k-sequent +- os=-dynix +- ;; +- blackfin) +- basic_machine=bfin-unknown +- os=-linux +- ;; +- blackfin-*) +- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` +- os=-linux +- ;; +- bluegene*) +- basic_machine=powerpc-ibm +- os=-cnk +- ;; +- c54x-*) +- basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- c55x-*) +- basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- c6x-*) +- basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- c90) +- basic_machine=c90-cray +- os=-unicos +- ;; +- cegcc) +- basic_machine=arm-unknown +- os=-cegcc +- ;; +- convex-c1) +- basic_machine=c1-convex +- os=-bsd +- ;; +- convex-c2) +- basic_machine=c2-convex +- os=-bsd +- ;; +- convex-c32) +- basic_machine=c32-convex +- os=-bsd +- ;; +- convex-c34) +- basic_machine=c34-convex +- os=-bsd +- ;; +- convex-c38) +- basic_machine=c38-convex +- os=-bsd +- ;; +- cray | j90) +- basic_machine=j90-cray +- os=-unicos +- ;; +- craynv) +- basic_machine=craynv-cray +- os=-unicosmp +- ;; +- cr16 | cr16-*) +- basic_machine=cr16-unknown +- os=-elf +- ;; +- crds | unos) +- basic_machine=m68k-crds +- ;; +- crisv32 | crisv32-* | etraxfs*) +- basic_machine=crisv32-axis +- ;; +- cris | cris-* | etrax*) +- basic_machine=cris-axis +- ;; +- crx) +- basic_machine=crx-unknown +- os=-elf +- ;; +- da30 | da30-*) +- basic_machine=m68k-da30 +- ;; +- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) +- basic_machine=mips-dec +- ;; +- decsystem10* | dec10*) +- basic_machine=pdp10-dec +- os=-tops10 +- ;; +- decsystem20* | dec20*) +- basic_machine=pdp10-dec +- os=-tops20 +- ;; +- delta | 3300 | motorola-3300 | motorola-delta \ +- | 3300-motorola | delta-motorola) +- basic_machine=m68k-motorola +- ;; +- delta88) +- basic_machine=m88k-motorola +- os=-sysv3 +- ;; +- dicos) +- basic_machine=i686-pc +- os=-dicos +- ;; +- djgpp) +- basic_machine=i586-pc +- os=-msdosdjgpp +- ;; +- dpx20 | dpx20-*) +- basic_machine=rs6000-bull +- os=-bosx +- ;; +- dpx2* | dpx2*-bull) +- basic_machine=m68k-bull +- os=-sysv3 +- ;; +- ebmon29k) +- basic_machine=a29k-amd +- os=-ebmon +- ;; +- elxsi) +- basic_machine=elxsi-elxsi +- os=-bsd +- ;; +- encore | umax | mmax) +- basic_machine=ns32k-encore +- ;; +- es1800 | OSE68k | ose68k | ose | OSE) +- basic_machine=m68k-ericsson +- os=-ose +- ;; +- fx2800) +- basic_machine=i860-alliant +- ;; +- genix) +- basic_machine=ns32k-ns +- ;; +- gmicro) +- basic_machine=tron-gmicro +- os=-sysv +- ;; +- go32) +- basic_machine=i386-pc +- os=-go32 +- ;; +- h3050r* | hiux*) +- basic_machine=hppa1.1-hitachi +- os=-hiuxwe2 +- ;; +- h8300hms) +- basic_machine=h8300-hitachi +- os=-hms +- ;; +- h8300xray) +- basic_machine=h8300-hitachi +- os=-xray +- ;; +- h8500hms) +- basic_machine=h8500-hitachi +- os=-hms +- ;; +- harris) +- basic_machine=m88k-harris +- os=-sysv3 +- ;; +- hp300-*) +- basic_machine=m68k-hp +- ;; +- hp300bsd) +- basic_machine=m68k-hp +- os=-bsd +- ;; +- hp300hpux) +- basic_machine=m68k-hp +- os=-hpux +- ;; +- hp3k9[0-9][0-9] | hp9[0-9][0-9]) +- basic_machine=hppa1.0-hp +- ;; +- hp9k2[0-9][0-9] | hp9k31[0-9]) +- basic_machine=m68000-hp +- ;; +- hp9k3[2-9][0-9]) +- basic_machine=m68k-hp +- ;; +- hp9k6[0-9][0-9] | hp6[0-9][0-9]) +- basic_machine=hppa1.0-hp +- ;; +- hp9k7[0-79][0-9] | hp7[0-79][0-9]) +- basic_machine=hppa1.1-hp +- ;; +- hp9k78[0-9] | hp78[0-9]) +- # FIXME: really hppa2.0-hp +- basic_machine=hppa1.1-hp +- ;; +- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) +- # FIXME: really hppa2.0-hp +- basic_machine=hppa1.1-hp +- ;; +- hp9k8[0-9][13679] | hp8[0-9][13679]) +- basic_machine=hppa1.1-hp +- ;; +- hp9k8[0-9][0-9] | hp8[0-9][0-9]) +- basic_machine=hppa1.0-hp +- ;; +- hppa-next) +- os=-nextstep3 +- ;; +- hppaosf) +- basic_machine=hppa1.1-hp +- os=-osf +- ;; +- hppro) +- basic_machine=hppa1.1-hp +- os=-proelf +- ;; +- i370-ibm* | ibm*) +- basic_machine=i370-ibm +- ;; +- i*86v32) +- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` +- os=-sysv32 +- ;; +- i*86v4*) +- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` +- os=-sysv4 +- ;; +- i*86v) +- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` +- os=-sysv +- ;; +- i*86sol2) +- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` +- os=-solaris2 +- ;; +- i386mach) +- basic_machine=i386-mach +- os=-mach +- ;; +- i386-vsta | vsta) +- basic_machine=i386-unknown +- os=-vsta +- ;; +- iris | iris4d) +- basic_machine=mips-sgi +- case $os in +- -irix*) +- ;; +- *) +- os=-irix4 +- ;; +- esac +- ;; +- isi68 | isi) +- basic_machine=m68k-isi +- os=-sysv +- ;; +- leon-*|leon[3-9]-*) +- basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` +- ;; +- m68knommu) +- basic_machine=m68k-unknown +- os=-linux +- ;; +- m68knommu-*) +- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` +- os=-linux +- ;; +- m88k-omron*) +- basic_machine=m88k-omron +- ;; +- magnum | m3230) +- basic_machine=mips-mips +- os=-sysv +- ;; +- merlin) +- basic_machine=ns32k-utek +- os=-sysv +- ;; +- microblaze*) +- basic_machine=microblaze-xilinx +- ;; +- mingw64) +- basic_machine=x86_64-pc +- os=-mingw64 +- ;; +- mingw32) +- basic_machine=i686-pc +- os=-mingw32 +- ;; +- mingw32ce) +- basic_machine=arm-unknown +- os=-mingw32ce +- ;; +- miniframe) +- basic_machine=m68000-convergent +- ;; +- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) +- basic_machine=m68k-atari +- os=-mint +- ;; +- mips3*-*) +- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` +- ;; +- mips3*) +- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown +- ;; +- monitor) +- basic_machine=m68k-rom68k +- os=-coff +- ;; +- morphos) +- basic_machine=powerpc-unknown +- os=-morphos +- ;; +- moxiebox) +- basic_machine=moxie-unknown +- os=-moxiebox +- ;; +- msdos) +- basic_machine=i386-pc +- os=-msdos +- ;; +- ms1-*) +- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` +- ;; +- msys) +- basic_machine=i686-pc +- os=-msys +- ;; +- mvs) +- basic_machine=i370-ibm +- os=-mvs +- ;; +- nacl) +- basic_machine=le32-unknown +- os=-nacl +- ;; +- ncr3000) +- basic_machine=i486-ncr +- os=-sysv4 +- ;; +- netbsd386) +- basic_machine=i386-unknown +- os=-netbsd +- ;; +- netwinder) +- basic_machine=armv4l-rebel +- os=-linux +- ;; +- news | news700 | news800 | news900) +- basic_machine=m68k-sony +- os=-newsos +- ;; +- news1000) +- basic_machine=m68030-sony +- os=-newsos +- ;; +- news-3600 | risc-news) +- basic_machine=mips-sony +- os=-newsos +- ;; +- necv70) +- basic_machine=v70-nec +- os=-sysv +- ;; +- next | m*-next ) +- basic_machine=m68k-next +- case $os in +- -nextstep* ) +- ;; +- -ns2*) +- os=-nextstep2 +- ;; +- *) +- os=-nextstep3 +- ;; +- esac +- ;; +- nh3000) +- basic_machine=m68k-harris +- os=-cxux +- ;; +- nh[45]000) +- basic_machine=m88k-harris +- os=-cxux +- ;; +- nindy960) +- basic_machine=i960-intel +- os=-nindy +- ;; +- mon960) +- basic_machine=i960-intel +- os=-mon960 +- ;; +- nonstopux) +- basic_machine=mips-compaq +- os=-nonstopux +- ;; +- np1) +- basic_machine=np1-gould +- ;; +- neo-tandem) +- basic_machine=neo-tandem +- ;; +- nse-tandem) +- basic_machine=nse-tandem +- ;; +- nsr-tandem) +- basic_machine=nsr-tandem +- ;; +- op50n-* | op60c-*) +- basic_machine=hppa1.1-oki +- os=-proelf +- ;; +- openrisc | openrisc-*) +- basic_machine=or32-unknown +- ;; +- os400) +- basic_machine=powerpc-ibm +- os=-os400 +- ;; +- OSE68000 | ose68000) +- basic_machine=m68000-ericsson +- os=-ose +- ;; +- os68k) +- basic_machine=m68k-none +- os=-os68k +- ;; +- pa-hitachi) +- basic_machine=hppa1.1-hitachi +- os=-hiuxwe2 +- ;; +- paragon) +- basic_machine=i860-intel +- os=-osf +- ;; +- parisc) +- basic_machine=hppa-unknown +- os=-linux +- ;; +- parisc-*) +- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` +- os=-linux +- ;; +- pbd) +- basic_machine=sparc-tti +- ;; +- pbb) +- basic_machine=m68k-tti +- ;; +- pc532 | pc532-*) +- basic_machine=ns32k-pc532 +- ;; +- pc98) +- basic_machine=i386-pc +- ;; +- pc98-*) +- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pentium | p5 | k5 | k6 | nexgen | viac3) +- basic_machine=i586-pc +- ;; +- pentiumpro | p6 | 6x86 | athlon | athlon_*) +- basic_machine=i686-pc +- ;; +- pentiumii | pentium2 | pentiumiii | pentium3) +- basic_machine=i686-pc +- ;; +- pentium4) +- basic_machine=i786-pc +- ;; +- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) +- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pentiumpro-* | p6-* | 6x86-* | athlon-*) +- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) +- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pentium4-*) +- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- pn) +- basic_machine=pn-gould +- ;; +- power) basic_machine=power-ibm +- ;; +- ppc | ppcbe) basic_machine=powerpc-unknown +- ;; +- ppc-* | ppcbe-*) +- basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- ppcle | powerpclittle | ppc-le | powerpc-little) +- basic_machine=powerpcle-unknown +- ;; +- ppcle-* | powerpclittle-*) +- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- ppc64) basic_machine=powerpc64-unknown +- ;; +- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- ppc64le | powerpc64little | ppc64-le | powerpc64-little) +- basic_machine=powerpc64le-unknown +- ;; +- ppc64le-* | powerpc64little-*) +- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- ps2) +- basic_machine=i386-ibm +- ;; +- pw32) +- basic_machine=i586-unknown +- os=-pw32 +- ;; +- rdos | rdos64) +- basic_machine=x86_64-pc +- os=-rdos +- ;; +- rdos32) +- basic_machine=i386-pc +- os=-rdos +- ;; +- rom68k) +- basic_machine=m68k-rom68k +- os=-coff +- ;; +- rm[46]00) +- basic_machine=mips-siemens +- ;; +- rtpc | rtpc-*) +- basic_machine=romp-ibm +- ;; +- s390 | s390-*) +- basic_machine=s390-ibm +- ;; +- s390x | s390x-*) +- basic_machine=s390x-ibm +- ;; +- sa29200) +- basic_machine=a29k-amd +- os=-udi +- ;; +- sb1) +- basic_machine=mipsisa64sb1-unknown +- ;; +- sb1el) +- basic_machine=mipsisa64sb1el-unknown +- ;; +- sde) +- basic_machine=mipsisa32-sde +- os=-elf +- ;; +- sei) +- basic_machine=mips-sei +- os=-seiux +- ;; +- sequent) +- basic_machine=i386-sequent +- ;; +- sh) +- basic_machine=sh-hitachi +- os=-hms +- ;; +- sh5el) +- basic_machine=sh5le-unknown +- ;; +- sh64) +- basic_machine=sh64-unknown +- ;; +- sparclite-wrs | simso-wrs) +- basic_machine=sparclite-wrs +- os=-vxworks +- ;; +- sps7) +- basic_machine=m68k-bull +- os=-sysv2 +- ;; +- spur) +- basic_machine=spur-unknown +- ;; +- st2000) +- basic_machine=m68k-tandem +- ;; +- stratus) +- basic_machine=i860-stratus +- os=-sysv4 +- ;; +- strongarm-* | thumb-*) +- basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` +- ;; +- sun2) +- basic_machine=m68000-sun +- ;; +- sun2os3) +- basic_machine=m68000-sun +- os=-sunos3 +- ;; +- sun2os4) +- basic_machine=m68000-sun +- os=-sunos4 +- ;; +- sun3os3) +- basic_machine=m68k-sun +- os=-sunos3 +- ;; +- sun3os4) +- basic_machine=m68k-sun +- os=-sunos4 +- ;; +- sun4os3) +- basic_machine=sparc-sun +- os=-sunos3 +- ;; +- sun4os4) +- basic_machine=sparc-sun +- os=-sunos4 +- ;; +- sun4sol2) +- basic_machine=sparc-sun +- os=-solaris2 +- ;; +- sun3 | sun3-*) +- basic_machine=m68k-sun +- ;; +- sun4) +- basic_machine=sparc-sun +- ;; +- sun386 | sun386i | roadrunner) +- basic_machine=i386-sun +- ;; +- sv1) +- basic_machine=sv1-cray +- os=-unicos +- ;; +- symmetry) +- basic_machine=i386-sequent +- os=-dynix +- ;; +- t3e) +- basic_machine=alphaev5-cray +- os=-unicos +- ;; +- t90) +- basic_machine=t90-cray +- os=-unicos +- ;; +- tile*) +- basic_machine=$basic_machine-unknown +- os=-linux-gnu +- ;; +- tx39) +- basic_machine=mipstx39-unknown +- ;; +- tx39el) +- basic_machine=mipstx39el-unknown +- ;; +- toad1) +- basic_machine=pdp10-xkl +- os=-tops20 +- ;; +- tower | tower-32) +- basic_machine=m68k-ncr +- ;; +- tpf) +- basic_machine=s390x-ibm +- os=-tpf +- ;; +- udi29k) +- basic_machine=a29k-amd +- os=-udi +- ;; +- ultra3) +- basic_machine=a29k-nyu +- os=-sym1 +- ;; +- v810 | necv810) +- basic_machine=v810-nec +- os=-none +- ;; +- vaxv) +- basic_machine=vax-dec +- os=-sysv +- ;; +- vms) +- basic_machine=vax-dec +- os=-vms +- ;; +- vpp*|vx|vx-*) +- basic_machine=f301-fujitsu +- ;; +- vxworks960) +- basic_machine=i960-wrs +- os=-vxworks +- ;; +- vxworks68) +- basic_machine=m68k-wrs +- os=-vxworks +- ;; +- vxworks29k) +- basic_machine=a29k-wrs +- os=-vxworks +- ;; +- w65*) +- basic_machine=w65-wdc +- os=-none +- ;; +- w89k-*) +- basic_machine=hppa1.1-winbond +- os=-proelf +- ;; +- xbox) +- basic_machine=i686-pc +- os=-mingw32 +- ;; +- xps | xps100) +- basic_machine=xps100-honeywell +- ;; +- xscale-* | xscalee[bl]-*) +- basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` +- ;; +- ymp) +- basic_machine=ymp-cray +- os=-unicos +- ;; +- z8k-*-coff) +- basic_machine=z8k-unknown +- os=-sim +- ;; +- z80-*-coff) +- basic_machine=z80-unknown +- os=-sim +- ;; +- none) +- basic_machine=none-none +- os=-none +- ;; +- +-# Here we handle the default manufacturer of certain CPU types. It is in +-# some cases the only manufacturer, in others, it is the most popular. +- w89k) +- basic_machine=hppa1.1-winbond +- ;; +- op50n) +- basic_machine=hppa1.1-oki +- ;; +- op60c) +- basic_machine=hppa1.1-oki +- ;; +- romp) +- basic_machine=romp-ibm +- ;; +- mmix) +- basic_machine=mmix-knuth +- ;; +- rs6000) +- basic_machine=rs6000-ibm +- ;; +- vax) +- basic_machine=vax-dec +- ;; +- pdp10) +- # there are many clones, so DEC is not a safe bet +- basic_machine=pdp10-unknown +- ;; +- pdp11) +- basic_machine=pdp11-dec +- ;; +- we32k) +- basic_machine=we32k-att +- ;; +- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) +- basic_machine=sh-unknown +- ;; +- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) +- basic_machine=sparc-sun +- ;; +- cydra) +- basic_machine=cydra-cydrome +- ;; +- orion) +- basic_machine=orion-highlevel +- ;; +- orion105) +- basic_machine=clipper-highlevel +- ;; +- mac | mpw | mac-mpw) +- basic_machine=m68k-apple +- ;; +- pmac | pmac-mpw) +- basic_machine=powerpc-apple +- ;; +- *-unknown) +- # Make sure to match an already-canonicalized machine name. +- ;; +- *) +- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 +- exit 1 +- ;; +-esac +- +-# Here we canonicalize certain aliases for manufacturers. +-case $basic_machine in +- *-digital*) +- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +- ;; +- *-commodore*) +- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` +- ;; +- *) +- ;; +-esac +- +-# Decode manufacturer-specific aliases for certain operating systems. +- +-if [ x"$os" != x"" ] +-then +-case $os in +- # First match some system type aliases +- # that might get confused with valid system types. +- # -solaris* is a basic system type, with this one exception. +- -auroraux) +- os=-auroraux +- ;; +- -solaris1 | -solaris1.*) +- os=`echo $os | sed -e 's|solaris1|sunos4|'` +- ;; +- -solaris) +- os=-solaris2 +- ;; +- -svr4*) +- os=-sysv4 +- ;; +- -unixware*) +- os=-sysv4.2uw +- ;; +- -gnu/linux*) +- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` +- ;; +- # First accept the basic system types. +- # The portable systems comes first. +- # Each alternative MUST END IN A *, to match a version number. +- # -sysv* is not here because it comes later, after sysvr4. +- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ +- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ +- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ +- | -sym* | -kopensolaris* | -plan9* \ +- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ +- | -aos* | -aros* \ +- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ +- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ +- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ +- | -bitrig* | -openbsd* | -solidbsd* \ +- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ +- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ +- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ +- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ +- | -chorusos* | -chorusrdb* | -cegcc* \ +- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ +- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ +- | -linux-newlib* | -linux-musl* | -linux-uclibc* \ +- | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ +- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ +- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ +- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ +- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ +- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ +- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ +- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) +- # Remember, each alternative MUST END IN *, to match a version number. +- ;; +- -qnx*) +- case $basic_machine in +- x86-* | i*86-*) +- ;; +- *) +- os=-nto$os +- ;; +- esac +- ;; +- -nto-qnx*) +- ;; +- -nto*) +- os=`echo $os | sed -e 's|nto|nto-qnx|'` +- ;; +- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ +- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ +- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) +- ;; +- -mac*) +- os=`echo $os | sed -e 's|mac|macos|'` +- ;; +- -linux-dietlibc) +- os=-linux-dietlibc +- ;; +- -linux*) +- os=`echo $os | sed -e 's|linux|linux-gnu|'` +- ;; +- -sunos5*) +- os=`echo $os | sed -e 's|sunos5|solaris2|'` +- ;; +- -sunos6*) +- os=`echo $os | sed -e 's|sunos6|solaris3|'` +- ;; +- -opened*) +- os=-openedition +- ;; +- -os400*) +- os=-os400 +- ;; +- -wince*) +- os=-wince +- ;; +- -osfrose*) +- os=-osfrose +- ;; +- -osf*) +- os=-osf +- ;; +- -utek*) +- os=-bsd +- ;; +- -dynix*) +- os=-bsd +- ;; +- -acis*) +- os=-aos +- ;; +- -atheos*) +- os=-atheos +- ;; +- -syllable*) +- os=-syllable +- ;; +- -386bsd) +- os=-bsd +- ;; +- -ctix* | -uts*) +- os=-sysv +- ;; +- -nova*) +- os=-rtmk-nova +- ;; +- -ns2 ) +- os=-nextstep2 +- ;; +- -nsk*) +- os=-nsk +- ;; +- # Preserve the version number of sinix5. +- -sinix5.*) +- os=`echo $os | sed -e 's|sinix|sysv|'` +- ;; +- -sinix*) +- os=-sysv4 +- ;; +- -tpf*) +- os=-tpf +- ;; +- -triton*) +- os=-sysv3 +- ;; +- -oss*) +- os=-sysv3 +- ;; +- -svr4) +- os=-sysv4 +- ;; +- -svr3) +- os=-sysv3 +- ;; +- -sysvr4) +- os=-sysv4 +- ;; +- # This must come after -sysvr4. +- -sysv*) +- ;; +- -ose*) +- os=-ose +- ;; +- -es1800*) +- os=-ose +- ;; +- -xenix) +- os=-xenix +- ;; +- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) +- os=-mint +- ;; +- -aros*) +- os=-aros +- ;; +- -zvmoe) +- os=-zvmoe +- ;; +- -dicos*) +- os=-dicos +- ;; +- -nacl*) +- ;; +- -none) +- ;; +- *) +- # Get rid of the `-' at the beginning of $os. +- os=`echo $os | sed 's/[^-]*-//'` +- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 +- exit 1 +- ;; +-esac +-else +- +-# Here we handle the default operating systems that come with various machines. +-# The value should be what the vendor currently ships out the door with their +-# machine or put another way, the most popular os provided with the machine. +- +-# Note that if you're going to try to match "-MANUFACTURER" here (say, +-# "-sun"), then you have to tell the case statement up towards the top +-# that MANUFACTURER isn't an operating system. Otherwise, code above +-# will signal an error saying that MANUFACTURER isn't an operating +-# system, and we'll never get to this point. +- +-case $basic_machine in +- score-*) +- os=-elf +- ;; +- spu-*) +- os=-elf +- ;; +- *-acorn) +- os=-riscix1.2 +- ;; +- arm*-rebel) +- os=-linux +- ;; +- arm*-semi) +- os=-aout +- ;; +- c4x-* | tic4x-*) +- os=-coff +- ;; +- c8051-*) +- os=-elf +- ;; +- hexagon-*) +- os=-elf +- ;; +- tic54x-*) +- os=-coff +- ;; +- tic55x-*) +- os=-coff +- ;; +- tic6x-*) +- os=-coff +- ;; +- # This must come before the *-dec entry. +- pdp10-*) +- os=-tops20 +- ;; +- pdp11-*) +- os=-none +- ;; +- *-dec | vax-*) +- os=-ultrix4.2 +- ;; +- m68*-apollo) +- os=-domain +- ;; +- i386-sun) +- os=-sunos4.0.2 +- ;; +- m68000-sun) +- os=-sunos3 +- ;; +- m68*-cisco) +- os=-aout +- ;; +- mep-*) +- os=-elf +- ;; +- mips*-cisco) +- os=-elf +- ;; +- mips*-*) +- os=-elf +- ;; +- or32-*) +- os=-coff +- ;; +- *-tti) # must be before sparc entry or we get the wrong os. +- os=-sysv3 +- ;; +- sparc-* | *-sun) +- os=-sunos4.1.1 +- ;; +- *-be) +- os=-beos +- ;; +- *-haiku) +- os=-haiku +- ;; +- *-ibm) +- os=-aix +- ;; +- *-knuth) +- os=-mmixware +- ;; +- *-wec) +- os=-proelf +- ;; +- *-winbond) +- os=-proelf +- ;; +- *-oki) +- os=-proelf +- ;; +- *-hp) +- os=-hpux +- ;; +- *-hitachi) +- os=-hiux +- ;; +- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) +- os=-sysv +- ;; +- *-cbm) +- os=-amigaos +- ;; +- *-dg) +- os=-dgux +- ;; +- *-dolphin) +- os=-sysv3 +- ;; +- m68k-ccur) +- os=-rtu +- ;; +- m88k-omron*) +- os=-luna +- ;; +- *-next ) +- os=-nextstep +- ;; +- *-sequent) +- os=-ptx +- ;; +- *-crds) +- os=-unos +- ;; +- *-ns) +- os=-genix +- ;; +- i370-*) +- os=-mvs +- ;; +- *-next) +- os=-nextstep3 +- ;; +- *-gould) +- os=-sysv +- ;; +- *-highlevel) +- os=-bsd +- ;; +- *-encore) +- os=-bsd +- ;; +- *-sgi) +- os=-irix +- ;; +- *-siemens) +- os=-sysv4 +- ;; +- *-masscomp) +- os=-rtu +- ;; +- f30[01]-fujitsu | f700-fujitsu) +- os=-uxpv +- ;; +- *-rom68k) +- os=-coff +- ;; +- *-*bug) +- os=-coff +- ;; +- *-apple) +- os=-macos +- ;; +- *-atari*) +- os=-mint +- ;; +- *) +- os=-none +- ;; +-esac +-fi +- +-# Here we handle the case where we know the os, and the CPU type, but not the +-# manufacturer. We pick the logical manufacturer. +-vendor=unknown +-case $basic_machine in +- *-unknown) +- case $os in +- -riscix*) +- vendor=acorn +- ;; +- -sunos*) +- vendor=sun +- ;; +- -cnk*|-aix*) +- vendor=ibm +- ;; +- -beos*) +- vendor=be +- ;; +- -hpux*) +- vendor=hp +- ;; +- -mpeix*) +- vendor=hp +- ;; +- -hiux*) +- vendor=hitachi +- ;; +- -unos*) +- vendor=crds +- ;; +- -dgux*) +- vendor=dg +- ;; +- -luna*) +- vendor=omron +- ;; +- -genix*) +- vendor=ns +- ;; +- -mvs* | -opened*) +- vendor=ibm +- ;; +- -os400*) +- vendor=ibm +- ;; +- -ptx*) +- vendor=sequent +- ;; +- -tpf*) +- vendor=ibm +- ;; +- -vxsim* | -vxworks* | -windiss*) +- vendor=wrs +- ;; +- -aux*) +- vendor=apple +- ;; +- -hms*) +- vendor=hitachi +- ;; +- -mpw* | -macos*) +- vendor=apple +- ;; +- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) +- vendor=atari +- ;; +- -vos*) +- vendor=stratus +- ;; +- esac +- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` +- ;; +-esac +- +-echo $basic_machine$os +-exit +- +-# Local variables: +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "timestamp='" +-# time-stamp-format: "%:y-%02m-%02d" +-# time-stamp-end: "'" +-# End: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/build-aux/depcomp groff-1.22.3/src/libs/gnulib/build-aux/depcomp +--- groff-1.22.3.old/src/libs/gnulib/build-aux/depcomp 2014-11-04 10:38:35.646518734 +0200 ++++ groff-1.22.3/src/libs/gnulib/build-aux/depcomp 1970-01-01 02:00:00.000000000 +0200 +@@ -1,756 +0,0 @@ +-#! /bin/sh +-# depcomp - compile a program generating dependencies as side-effects +- +-scriptversion=2013-05-30.07; # UTC +- +-# Copyright (C) 1999-2013 Free Software Foundation, Inc. +- +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2, or (at your option) +-# any later version. +- +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-# As a special exception to the GNU General Public License, if you +-# distribute this file as part of a program that contains a +-# configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that program. +- +-# Originally written by Alexandre Oliva . +- +-case $1 in +- '') +- echo "$0: No command. Try '$0 --help' for more information." 1>&2 +- exit 1; +- ;; +- -h | --h*) +- cat <<\EOF +-Usage: depcomp [--help] [--version] PROGRAM [ARGS] +- +-Run PROGRAMS ARGS to compile a file, generating dependencies +-as side-effects. +- +-Environment variables: +- depmode Dependency tracking mode. +- source Source file read by 'PROGRAMS ARGS'. +- object Object file output by 'PROGRAMS ARGS'. +- DEPDIR directory where to store dependencies. +- depfile Dependency file to output. +- tmpdepfile Temporary file to use when outputting dependencies. +- libtool Whether libtool is used (yes/no). +- +-Report bugs to . +-EOF +- exit $? +- ;; +- -v | --v*) +- echo "depcomp $scriptversion" +- exit $? +- ;; +-esac +- +-# Get the directory component of the given path, and save it in the +-# global variables '$dir'. Note that this directory component will +-# be either empty or ending with a '/' character. This is deliberate. +-set_dir_from () +-{ +- case $1 in +- */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; +- *) dir=;; +- esac +-} +- +-# Get the suffix-stripped basename of the given path, and save it the +-# global variable '$base'. +-set_base_from () +-{ +- base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +-} +- +-# If no dependency file was actually created by the compiler invocation, +-# we still have to create a dummy depfile, to avoid errors with the +-# Makefile "include basename.Plo" scheme. +-make_dummy_depfile () +-{ +- echo "#dummy" > "$depfile" +-} +- +-# Factor out some common post-processing of the generated depfile. +-# Requires the auxiliary global variable '$tmpdepfile' to be set. +-aix_post_process_depfile () +-{ +- # If the compiler actually managed to produce a dependency file, +- # post-process it. +- if test -f "$tmpdepfile"; then +- # Each line is of the form 'foo.o: dependency.h'. +- # Do two passes, one to just change these to +- # $object: dependency.h +- # and one to simply output +- # dependency.h: +- # which is needed to avoid the deleted-header problem. +- { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" +- sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" +- } > "$depfile" +- rm -f "$tmpdepfile" +- else +- make_dummy_depfile +- fi +-} +- +-# A tabulation character. +-tab=' ' +-# A newline character. +-nl=' +-' +-# Character ranges might be problematic outside the C locale. +-# These definitions help. +-upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +-lower=abcdefghijklmnopqrstuvwxyz +-digits=0123456789 +-alpha=${upper}${lower} +- +-if test -z "$depmode" || test -z "$source" || test -z "$object"; then +- echo "depcomp: Variables source, object and depmode must be set" 1>&2 +- exit 1 +-fi +- +-# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +-depfile=${depfile-`echo "$object" | +- sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +-tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} +- +-rm -f "$tmpdepfile" +- +-# Avoid interferences from the environment. +-gccflag= dashmflag= +- +-# Some modes work just like other modes, but use different flags. We +-# parameterize here, but still list the modes in the big case below, +-# to make depend.m4 easier to write. Note that we *cannot* use a case +-# here, because this file can only contain one case statement. +-if test "$depmode" = hp; then +- # HP compiler uses -M and no extra arg. +- gccflag=-M +- depmode=gcc +-fi +- +-if test "$depmode" = dashXmstdout; then +- # This is just like dashmstdout with a different argument. +- dashmflag=-xM +- depmode=dashmstdout +-fi +- +-cygpath_u="cygpath -u -f -" +-if test "$depmode" = msvcmsys; then +- # This is just like msvisualcpp but w/o cygpath translation. +- # Just convert the backslash-escaped backslashes to single forward +- # slashes to satisfy depend.m4 +- cygpath_u='sed s,\\\\,/,g' +- depmode=msvisualcpp +-fi +- +-if test "$depmode" = msvc7msys; then +- # This is just like msvc7 but w/o cygpath translation. +- # Just convert the backslash-escaped backslashes to single forward +- # slashes to satisfy depend.m4 +- cygpath_u='sed s,\\\\,/,g' +- depmode=msvc7 +-fi +- +-if test "$depmode" = xlc; then +- # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. +- gccflag=-qmakedep=gcc,-MF +- depmode=gcc +-fi +- +-case "$depmode" in +-gcc3) +-## gcc 3 implements dependency tracking that does exactly what +-## we want. Yay! Note: for some reason libtool 1.4 doesn't like +-## it if -MD -MP comes after the -MF stuff. Hmm. +-## Unfortunately, FreeBSD c89 acceptance of flags depends upon +-## the command line argument order; so add the flags where they +-## appear in depend2.am. Note that the slowdown incurred here +-## affects only configure: in makefiles, %FASTDEP% shortcuts this. +- for arg +- do +- case $arg in +- -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; +- *) set fnord "$@" "$arg" ;; +- esac +- shift # fnord +- shift # $arg +- done +- "$@" +- stat=$? +- if test $stat -ne 0; then +- rm -f "$tmpdepfile" +- exit $stat +- fi +- mv "$tmpdepfile" "$depfile" +- ;; +- +-gcc) +-## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +-## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +-## (see the conditional assignment to $gccflag above). +-## There are various ways to get dependency output from gcc. Here's +-## why we pick this rather obscure method: +-## - Don't want to use -MD because we'd like the dependencies to end +-## up in a subdir. Having to rename by hand is ugly. +-## (We might end up doing this anyway to support other compilers.) +-## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +-## -MM, not -M (despite what the docs say). Also, it might not be +-## supported by the other compilers which use the 'gcc' depmode. +-## - Using -M directly means running the compiler twice (even worse +-## than renaming). +- if test -z "$gccflag"; then +- gccflag=-MD, +- fi +- "$@" -Wp,"$gccflag$tmpdepfile" +- stat=$? +- if test $stat -ne 0; then +- rm -f "$tmpdepfile" +- exit $stat +- fi +- rm -f "$depfile" +- echo "$object : \\" > "$depfile" +- # The second -e expression handles DOS-style file names with drive +- # letters. +- sed -e 's/^[^:]*: / /' \ +- -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +-## This next piece of magic avoids the "deleted header file" problem. +-## The problem is that when a header file which appears in a .P file +-## is deleted, the dependency causes make to die (because there is +-## typically no way to rebuild the header). We avoid this by adding +-## dummy dependencies for each header file. Too bad gcc doesn't do +-## this for us directly. +-## Some versions of gcc put a space before the ':'. On the theory +-## that the space means something, we add a space to the output as +-## well. hp depmode also adds that space, but also prefixes the VPATH +-## to the object. Take care to not repeat it in the output. +-## Some versions of the HPUX 10.20 sed can't process this invocation +-## correctly. Breaking it into two sed invocations is a workaround. +- tr ' ' "$nl" < "$tmpdepfile" \ +- | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ +- | sed -e 's/$/ :/' >> "$depfile" +- rm -f "$tmpdepfile" +- ;; +- +-hp) +- # This case exists only to let depend.m4 do its work. It works by +- # looking at the text of this script. This case will never be run, +- # since it is checked for above. +- exit 1 +- ;; +- +-xlc) +- # This case exists only to let depend.m4 do its work. It works by +- # looking at the text of this script. This case will never be run, +- # since it is checked for above. +- exit 1 +- ;; +- +-aix) +- # The C for AIX Compiler uses -M and outputs the dependencies +- # in a .u file. In older versions, this file always lives in the +- # current directory. Also, the AIX compiler puts '$object:' at the +- # start of each line; $object doesn't have directory information. +- # Version 6 uses the directory in both cases. +- set_dir_from "$object" +- set_base_from "$object" +- if test "$libtool" = yes; then +- tmpdepfile1=$dir$base.u +- tmpdepfile2=$base.u +- tmpdepfile3=$dir.libs/$base.u +- "$@" -Wc,-M +- else +- tmpdepfile1=$dir$base.u +- tmpdepfile2=$dir$base.u +- tmpdepfile3=$dir$base.u +- "$@" -M +- fi +- stat=$? +- if test $stat -ne 0; then +- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" +- exit $stat +- fi +- +- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" +- do +- test -f "$tmpdepfile" && break +- done +- aix_post_process_depfile +- ;; +- +-tcc) +- # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 +- # FIXME: That version still under development at the moment of writing. +- # Make that this statement remains true also for stable, released +- # versions. +- # It will wrap lines (doesn't matter whether long or short) with a +- # trailing '\', as in: +- # +- # foo.o : \ +- # foo.c \ +- # foo.h \ +- # +- # It will put a trailing '\' even on the last line, and will use leading +- # spaces rather than leading tabs (at least since its commit 0394caf7 +- # "Emit spaces for -MD"). +- "$@" -MD -MF "$tmpdepfile" +- stat=$? +- if test $stat -ne 0; then +- rm -f "$tmpdepfile" +- exit $stat +- fi +- rm -f "$depfile" +- # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. +- # We have to change lines of the first kind to '$object: \'. +- sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" +- # And for each line of the second kind, we have to emit a 'dep.h:' +- # dummy dependency, to avoid the deleted-header problem. +- sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" +- rm -f "$tmpdepfile" +- ;; +- +-## The order of this option in the case statement is important, since the +-## shell code in configure will try each of these formats in the order +-## listed in this file. A plain '-MD' option would be understood by many +-## compilers, so we must ensure this comes after the gcc and icc options. +-pgcc) +- # Portland's C compiler understands '-MD'. +- # Will always output deps to 'file.d' where file is the root name of the +- # source file under compilation, even if file resides in a subdirectory. +- # The object file name does not affect the name of the '.d' file. +- # pgcc 10.2 will output +- # foo.o: sub/foo.c sub/foo.h +- # and will wrap long lines using '\' : +- # foo.o: sub/foo.c ... \ +- # sub/foo.h ... \ +- # ... +- set_dir_from "$object" +- # Use the source, not the object, to determine the base name, since +- # that's sadly what pgcc will do too. +- set_base_from "$source" +- tmpdepfile=$base.d +- +- # For projects that build the same source file twice into different object +- # files, the pgcc approach of using the *source* file root name can cause +- # problems in parallel builds. Use a locking strategy to avoid stomping on +- # the same $tmpdepfile. +- lockdir=$base.d-lock +- trap " +- echo '$0: caught signal, cleaning up...' >&2 +- rmdir '$lockdir' +- exit 1 +- " 1 2 13 15 +- numtries=100 +- i=$numtries +- while test $i -gt 0; do +- # mkdir is a portable test-and-set. +- if mkdir "$lockdir" 2>/dev/null; then +- # This process acquired the lock. +- "$@" -MD +- stat=$? +- # Release the lock. +- rmdir "$lockdir" +- break +- else +- # If the lock is being held by a different process, wait +- # until the winning process is done or we timeout. +- while test -d "$lockdir" && test $i -gt 0; do +- sleep 1 +- i=`expr $i - 1` +- done +- fi +- i=`expr $i - 1` +- done +- trap - 1 2 13 15 +- if test $i -le 0; then +- echo "$0: failed to acquire lock after $numtries attempts" >&2 +- echo "$0: check lockdir '$lockdir'" >&2 +- exit 1 +- fi +- +- if test $stat -ne 0; then +- rm -f "$tmpdepfile" +- exit $stat +- fi +- rm -f "$depfile" +- # Each line is of the form `foo.o: dependent.h', +- # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. +- # Do two passes, one to just change these to +- # `$object: dependent.h' and one to simply `dependent.h:'. +- sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" +- # Some versions of the HPUX 10.20 sed can't process this invocation +- # correctly. Breaking it into two sed invocations is a workaround. +- sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ +- | sed -e 's/$/ :/' >> "$depfile" +- rm -f "$tmpdepfile" +- ;; +- +-hp2) +- # The "hp" stanza above does not work with aCC (C++) and HP's ia64 +- # compilers, which have integrated preprocessors. The correct option +- # to use with these is +Maked; it writes dependencies to a file named +- # 'foo.d', which lands next to the object file, wherever that +- # happens to be. +- # Much of this is similar to the tru64 case; see comments there. +- set_dir_from "$object" +- set_base_from "$object" +- if test "$libtool" = yes; then +- tmpdepfile1=$dir$base.d +- tmpdepfile2=$dir.libs/$base.d +- "$@" -Wc,+Maked +- else +- tmpdepfile1=$dir$base.d +- tmpdepfile2=$dir$base.d +- "$@" +Maked +- fi +- stat=$? +- if test $stat -ne 0; then +- rm -f "$tmpdepfile1" "$tmpdepfile2" +- exit $stat +- fi +- +- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" +- do +- test -f "$tmpdepfile" && break +- done +- if test -f "$tmpdepfile"; then +- sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" +- # Add 'dependent.h:' lines. +- sed -ne '2,${ +- s/^ *// +- s/ \\*$// +- s/$/:/ +- p +- }' "$tmpdepfile" >> "$depfile" +- else +- make_dummy_depfile +- fi +- rm -f "$tmpdepfile" "$tmpdepfile2" +- ;; +- +-tru64) +- # The Tru64 compiler uses -MD to generate dependencies as a side +- # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. +- # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put +- # dependencies in 'foo.d' instead, so we check for that too. +- # Subdirectories are respected. +- set_dir_from "$object" +- set_base_from "$object" +- +- if test "$libtool" = yes; then +- # Libtool generates 2 separate objects for the 2 libraries. These +- # two compilations output dependencies in $dir.libs/$base.o.d and +- # in $dir$base.o.d. We have to check for both files, because +- # one of the two compilations can be disabled. We should prefer +- # $dir$base.o.d over $dir.libs/$base.o.d because the latter is +- # automatically cleaned when .libs/ is deleted, while ignoring +- # the former would cause a distcleancheck panic. +- tmpdepfile1=$dir$base.o.d # libtool 1.5 +- tmpdepfile2=$dir.libs/$base.o.d # Likewise. +- tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 +- "$@" -Wc,-MD +- else +- tmpdepfile1=$dir$base.d +- tmpdepfile2=$dir$base.d +- tmpdepfile3=$dir$base.d +- "$@" -MD +- fi +- +- stat=$? +- if test $stat -ne 0; then +- rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" +- exit $stat +- fi +- +- for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" +- do +- test -f "$tmpdepfile" && break +- done +- # Same post-processing that is required for AIX mode. +- aix_post_process_depfile +- ;; +- +-msvc7) +- if test "$libtool" = yes; then +- showIncludes=-Wc,-showIncludes +- else +- showIncludes=-showIncludes +- fi +- "$@" $showIncludes > "$tmpdepfile" +- stat=$? +- grep -v '^Note: including file: ' "$tmpdepfile" +- if test $stat -ne 0; then +- rm -f "$tmpdepfile" +- exit $stat +- fi +- rm -f "$depfile" +- echo "$object : \\" > "$depfile" +- # The first sed program below extracts the file names and escapes +- # backslashes for cygpath. The second sed program outputs the file +- # name when reading, but also accumulates all include files in the +- # hold buffer in order to output them again at the end. This only +- # works with sed implementations that can handle large buffers. +- sed < "$tmpdepfile" -n ' +-/^Note: including file: *\(.*\)/ { +- s//\1/ +- s/\\/\\\\/g +- p +-}' | $cygpath_u | sort -u | sed -n ' +-s/ /\\ /g +-s/\(.*\)/'"$tab"'\1 \\/p +-s/.\(.*\) \\/\1:/ +-H +-$ { +- s/.*/'"$tab"'/ +- G +- p +-}' >> "$depfile" +- echo >> "$depfile" # make sure the fragment doesn't end with a backslash +- rm -f "$tmpdepfile" +- ;; +- +-msvc7msys) +- # This case exists only to let depend.m4 do its work. It works by +- # looking at the text of this script. This case will never be run, +- # since it is checked for above. +- exit 1 +- ;; +- +-#nosideeffect) +- # This comment above is used by automake to tell side-effect +- # dependency tracking mechanisms from slower ones. +- +-dashmstdout) +- # Important note: in order to support this mode, a compiler *must* +- # always write the preprocessed file to stdout, regardless of -o. +- "$@" || exit $? +- +- # Remove the call to Libtool. +- if test "$libtool" = yes; then +- while test "X$1" != 'X--mode=compile'; do +- shift +- done +- shift +- fi +- +- # Remove '-o $object'. +- IFS=" " +- for arg +- do +- case $arg in +- -o) +- shift +- ;; +- $object) +- shift +- ;; +- *) +- set fnord "$@" "$arg" +- shift # fnord +- shift # $arg +- ;; +- esac +- done +- +- test -z "$dashmflag" && dashmflag=-M +- # Require at least two characters before searching for ':' +- # in the target name. This is to cope with DOS-style filenames: +- # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. +- "$@" $dashmflag | +- sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" +- rm -f "$depfile" +- cat < "$tmpdepfile" > "$depfile" +- # Some versions of the HPUX 10.20 sed can't process this sed invocation +- # correctly. Breaking it into two sed invocations is a workaround. +- tr ' ' "$nl" < "$tmpdepfile" \ +- | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ +- | sed -e 's/$/ :/' >> "$depfile" +- rm -f "$tmpdepfile" +- ;; +- +-dashXmstdout) +- # This case only exists to satisfy depend.m4. It is never actually +- # run, as this mode is specially recognized in the preamble. +- exit 1 +- ;; +- +-makedepend) +- "$@" || exit $? +- # Remove any Libtool call +- if test "$libtool" = yes; then +- while test "X$1" != 'X--mode=compile'; do +- shift +- done +- shift +- fi +- # X makedepend +- shift +- cleared=no eat=no +- for arg +- do +- case $cleared in +- no) +- set ""; shift +- cleared=yes ;; +- esac +- if test $eat = yes; then +- eat=no +- continue +- fi +- case "$arg" in +- -D*|-I*) +- set fnord "$@" "$arg"; shift ;; +- # Strip any option that makedepend may not understand. Remove +- # the object too, otherwise makedepend will parse it as a source file. +- -arch) +- eat=yes ;; +- -*|$object) +- ;; +- *) +- set fnord "$@" "$arg"; shift ;; +- esac +- done +- obj_suffix=`echo "$object" | sed 's/^.*\././'` +- touch "$tmpdepfile" +- ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" +- rm -f "$depfile" +- # makedepend may prepend the VPATH from the source file name to the object. +- # No need to regex-escape $object, excess matching of '.' is harmless. +- sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" +- # Some versions of the HPUX 10.20 sed can't process the last invocation +- # correctly. Breaking it into two sed invocations is a workaround. +- sed '1,2d' "$tmpdepfile" \ +- | tr ' ' "$nl" \ +- | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ +- | sed -e 's/$/ :/' >> "$depfile" +- rm -f "$tmpdepfile" "$tmpdepfile".bak +- ;; +- +-cpp) +- # Important note: in order to support this mode, a compiler *must* +- # always write the preprocessed file to stdout. +- "$@" || exit $? +- +- # Remove the call to Libtool. +- if test "$libtool" = yes; then +- while test "X$1" != 'X--mode=compile'; do +- shift +- done +- shift +- fi +- +- # Remove '-o $object'. +- IFS=" " +- for arg +- do +- case $arg in +- -o) +- shift +- ;; +- $object) +- shift +- ;; +- *) +- set fnord "$@" "$arg" +- shift # fnord +- shift # $arg +- ;; +- esac +- done +- +- "$@" -E \ +- | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ +- -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ +- | sed '$ s: \\$::' > "$tmpdepfile" +- rm -f "$depfile" +- echo "$object : \\" > "$depfile" +- cat < "$tmpdepfile" >> "$depfile" +- sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" +- rm -f "$tmpdepfile" +- ;; +- +-msvisualcpp) +- # Important note: in order to support this mode, a compiler *must* +- # always write the preprocessed file to stdout. +- "$@" || exit $? +- +- # Remove the call to Libtool. +- if test "$libtool" = yes; then +- while test "X$1" != 'X--mode=compile'; do +- shift +- done +- shift +- fi +- +- IFS=" " +- for arg +- do +- case "$arg" in +- -o) +- shift +- ;; +- $object) +- shift +- ;; +- "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") +- set fnord "$@" +- shift +- shift +- ;; +- *) +- set fnord "$@" "$arg" +- shift +- shift +- ;; +- esac +- done +- "$@" -E 2>/dev/null | +- sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" +- rm -f "$depfile" +- echo "$object : \\" > "$depfile" +- sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" +- echo "$tab" >> "$depfile" +- sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" +- rm -f "$tmpdepfile" +- ;; +- +-msvcmsys) +- # This case exists only to let depend.m4 do its work. It works by +- # looking at the text of this script. This case will never be run, +- # since it is checked for above. +- exit 1 +- ;; +- +-none) +- exec "$@" +- ;; +- +-*) +- echo "Unknown depmode $depmode" 1>&2 +- exit 1 +- ;; +-esac +- +-exit 0 +- +-# Local Variables: +-# mode: shell-script +-# sh-indentation: 2 +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "scriptversion=" +-# time-stamp-format: "%:y-%02m-%02d.%02H" +-# time-stamp-time-zone: "UTC" +-# time-stamp-end: "; # UTC" +-# End: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/build-aux/install-sh groff-1.22.3/src/libs/gnulib/build-aux/install-sh +--- groff-1.22.3.old/src/libs/gnulib/build-aux/install-sh 2014-11-04 10:38:35.646518734 +0200 ++++ groff-1.22.3/src/libs/gnulib/build-aux/install-sh 1970-01-01 02:00:00.000000000 +0200 +@@ -1,501 +0,0 @@ +-#!/bin/sh +-# install - install a program, script, or datafile +- +-scriptversion=2013-12-25.23; # UTC +- +-# This originates from X11R5 (mit/util/scripts/install.sh), which was +-# later released in X11R6 (xc/config/util/install.sh) with the +-# following copyright and license. +-# +-# Copyright (C) 1994 X Consortium +-# +-# Permission is hereby granted, free of charge, to any person obtaining a copy +-# of this software and associated documentation files (the "Software"), to +-# deal in the Software without restriction, including without limitation the +-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +-# sell copies of the Software, and to permit persons to whom the Software is +-# furnished to do so, subject to the following conditions: +-# +-# The above copyright notice and this permission notice shall be included in +-# all copies or substantial portions of the Software. +-# +-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +-# +-# Except as contained in this notice, the name of the X Consortium shall not +-# be used in advertising or otherwise to promote the sale, use or other deal- +-# ings in this Software without prior written authorization from the X Consor- +-# tium. +-# +-# +-# FSF changes to this file are in the public domain. +-# +-# Calling this script install-sh is preferred over install.sh, to prevent +-# 'make' implicit rules from creating a file called install from it +-# when there is no Makefile. +-# +-# This script is compatible with the BSD install script, but was written +-# from scratch. +- +-tab=' ' +-nl=' +-' +-IFS=" $tab$nl" +- +-# Set DOITPROG to "echo" to test this script. +- +-doit=${DOITPROG-} +-doit_exec=${doit:-exec} +- +-# Put in absolute file names if you don't have them in your path; +-# or use environment vars. +- +-chgrpprog=${CHGRPPROG-chgrp} +-chmodprog=${CHMODPROG-chmod} +-chownprog=${CHOWNPROG-chown} +-cmpprog=${CMPPROG-cmp} +-cpprog=${CPPROG-cp} +-mkdirprog=${MKDIRPROG-mkdir} +-mvprog=${MVPROG-mv} +-rmprog=${RMPROG-rm} +-stripprog=${STRIPPROG-strip} +- +-posix_mkdir= +- +-# Desired mode of installed file. +-mode=0755 +- +-chgrpcmd= +-chmodcmd=$chmodprog +-chowncmd= +-mvcmd=$mvprog +-rmcmd="$rmprog -f" +-stripcmd= +- +-src= +-dst= +-dir_arg= +-dst_arg= +- +-copy_on_change=false +-is_target_a_directory=possibly +- +-usage="\ +-Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE +- or: $0 [OPTION]... SRCFILES... DIRECTORY +- or: $0 [OPTION]... -t DIRECTORY SRCFILES... +- or: $0 [OPTION]... -d DIRECTORIES... +- +-In the 1st form, copy SRCFILE to DSTFILE. +-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +-In the 4th, create DIRECTORIES. +- +-Options: +- --help display this help and exit. +- --version display version info and exit. +- +- -c (ignored) +- -C install only if different (preserve the last data modification time) +- -d create directories instead of installing files. +- -g GROUP $chgrpprog installed files to GROUP. +- -m MODE $chmodprog installed files to MODE. +- -o USER $chownprog installed files to USER. +- -s $stripprog installed files. +- -t DIRECTORY install into DIRECTORY. +- -T report an error if DSTFILE is a directory. +- +-Environment variables override the default commands: +- CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG +- RMPROG STRIPPROG +-" +- +-while test $# -ne 0; do +- case $1 in +- -c) ;; +- +- -C) copy_on_change=true;; +- +- -d) dir_arg=true;; +- +- -g) chgrpcmd="$chgrpprog $2" +- shift;; +- +- --help) echo "$usage"; exit $?;; +- +- -m) mode=$2 +- case $mode in +- *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) +- echo "$0: invalid mode: $mode" >&2 +- exit 1;; +- esac +- shift;; +- +- -o) chowncmd="$chownprog $2" +- shift;; +- +- -s) stripcmd=$stripprog;; +- +- -t) +- is_target_a_directory=always +- dst_arg=$2 +- # Protect names problematic for 'test' and other utilities. +- case $dst_arg in +- -* | [=\(\)!]) dst_arg=./$dst_arg;; +- esac +- shift;; +- +- -T) is_target_a_directory=never;; +- +- --version) echo "$0 $scriptversion"; exit $?;; +- +- --) shift +- break;; +- +- -*) echo "$0: invalid option: $1" >&2 +- exit 1;; +- +- *) break;; +- esac +- shift +-done +- +-# We allow the use of options -d and -T together, by making -d +-# take the precedence; this is for compatibility with GNU install. +- +-if test -n "$dir_arg"; then +- if test -n "$dst_arg"; then +- echo "$0: target directory not allowed when installing a directory." >&2 +- exit 1 +- fi +-fi +- +-if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then +- # When -d is used, all remaining arguments are directories to create. +- # When -t is used, the destination is already specified. +- # Otherwise, the last argument is the destination. Remove it from $@. +- for arg +- do +- if test -n "$dst_arg"; then +- # $@ is not empty: it contains at least $arg. +- set fnord "$@" "$dst_arg" +- shift # fnord +- fi +- shift # arg +- dst_arg=$arg +- # Protect names problematic for 'test' and other utilities. +- case $dst_arg in +- -* | [=\(\)!]) dst_arg=./$dst_arg;; +- esac +- done +-fi +- +-if test $# -eq 0; then +- if test -z "$dir_arg"; then +- echo "$0: no input file specified." >&2 +- exit 1 +- fi +- # It's OK to call 'install-sh -d' without argument. +- # This can happen when creating conditional directories. +- exit 0 +-fi +- +-if test -z "$dir_arg"; then +- if test $# -gt 1 || test "$is_target_a_directory" = always; then +- if test ! -d "$dst_arg"; then +- echo "$0: $dst_arg: Is not a directory." >&2 +- exit 1 +- fi +- fi +-fi +- +-if test -z "$dir_arg"; then +- do_exit='(exit $ret); exit $ret' +- trap "ret=129; $do_exit" 1 +- trap "ret=130; $do_exit" 2 +- trap "ret=141; $do_exit" 13 +- trap "ret=143; $do_exit" 15 +- +- # Set umask so as not to create temps with too-generous modes. +- # However, 'strip' requires both read and write access to temps. +- case $mode in +- # Optimize common cases. +- *644) cp_umask=133;; +- *755) cp_umask=22;; +- +- *[0-7]) +- if test -z "$stripcmd"; then +- u_plus_rw= +- else +- u_plus_rw='% 200' +- fi +- cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; +- *) +- if test -z "$stripcmd"; then +- u_plus_rw= +- else +- u_plus_rw=,u+rw +- fi +- cp_umask=$mode$u_plus_rw;; +- esac +-fi +- +-for src +-do +- # Protect names problematic for 'test' and other utilities. +- case $src in +- -* | [=\(\)!]) src=./$src;; +- esac +- +- if test -n "$dir_arg"; then +- dst=$src +- dstdir=$dst +- test -d "$dstdir" +- dstdir_status=$? +- else +- +- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command +- # might cause directories to be created, which would be especially bad +- # if $src (and thus $dsttmp) contains '*'. +- if test ! -f "$src" && test ! -d "$src"; then +- echo "$0: $src does not exist." >&2 +- exit 1 +- fi +- +- if test -z "$dst_arg"; then +- echo "$0: no destination specified." >&2 +- exit 1 +- fi +- dst=$dst_arg +- +- # If destination is a directory, append the input filename; won't work +- # if double slashes aren't ignored. +- if test -d "$dst"; then +- if test "$is_target_a_directory" = never; then +- echo "$0: $dst_arg: Is a directory" >&2 +- exit 1 +- fi +- dstdir=$dst +- dst=$dstdir/`basename "$src"` +- dstdir_status=0 +- else +- dstdir=`dirname "$dst"` +- test -d "$dstdir" +- dstdir_status=$? +- fi +- fi +- +- obsolete_mkdir_used=false +- +- if test $dstdir_status != 0; then +- case $posix_mkdir in +- '') +- # Create intermediate dirs using mode 755 as modified by the umask. +- # This is like FreeBSD 'install' as of 1997-10-28. +- umask=`umask` +- case $stripcmd.$umask in +- # Optimize common cases. +- *[2367][2367]) mkdir_umask=$umask;; +- .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; +- +- *[0-7]) +- mkdir_umask=`expr $umask + 22 \ +- - $umask % 100 % 40 + $umask % 20 \ +- - $umask % 10 % 4 + $umask % 2 +- `;; +- *) mkdir_umask=$umask,go-w;; +- esac +- +- # With -d, create the new directory with the user-specified mode. +- # Otherwise, rely on $mkdir_umask. +- if test -n "$dir_arg"; then +- mkdir_mode=-m$mode +- else +- mkdir_mode= +- fi +- +- posix_mkdir=false +- case $umask in +- *[123567][0-7][0-7]) +- # POSIX mkdir -p sets u+wx bits regardless of umask, which +- # is incompatible with FreeBSD 'install' when (umask & 300) != 0. +- ;; +- *) +- tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ +- trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 +- +- if (umask $mkdir_umask && +- exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 +- then +- if test -z "$dir_arg" || { +- # Check for POSIX incompatibilities with -m. +- # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or +- # other-writable bit of parent directory when it shouldn't. +- # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. +- ls_ld_tmpdir=`ls -ld "$tmpdir"` +- case $ls_ld_tmpdir in +- d????-?r-*) different_mode=700;; +- d????-?--*) different_mode=755;; +- *) false;; +- esac && +- $mkdirprog -m$different_mode -p -- "$tmpdir" && { +- ls_ld_tmpdir_1=`ls -ld "$tmpdir"` +- test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" +- } +- } +- then posix_mkdir=: +- fi +- rmdir "$tmpdir/d" "$tmpdir" +- else +- # Remove any dirs left behind by ancient mkdir implementations. +- rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null +- fi +- trap '' 0;; +- esac;; +- esac +- +- if +- $posix_mkdir && ( +- umask $mkdir_umask && +- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" +- ) +- then : +- else +- +- # The umask is ridiculous, or mkdir does not conform to POSIX, +- # or it failed possibly due to a race condition. Create the +- # directory the slow way, step by step, checking for races as we go. +- +- case $dstdir in +- /*) prefix='/';; +- [-=\(\)!]*) prefix='./';; +- *) prefix='';; +- esac +- +- oIFS=$IFS +- IFS=/ +- set -f +- set fnord $dstdir +- shift +- set +f +- IFS=$oIFS +- +- prefixes= +- +- for d +- do +- test X"$d" = X && continue +- +- prefix=$prefix$d +- if test -d "$prefix"; then +- prefixes= +- else +- if $posix_mkdir; then +- (umask=$mkdir_umask && +- $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break +- # Don't fail if two instances are running concurrently. +- test -d "$prefix" || exit 1 +- else +- case $prefix in +- *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; +- *) qprefix=$prefix;; +- esac +- prefixes="$prefixes '$qprefix'" +- fi +- fi +- prefix=$prefix/ +- done +- +- if test -n "$prefixes"; then +- # Don't fail if two instances are running concurrently. +- (umask $mkdir_umask && +- eval "\$doit_exec \$mkdirprog $prefixes") || +- test -d "$dstdir" || exit 1 +- obsolete_mkdir_used=true +- fi +- fi +- fi +- +- if test -n "$dir_arg"; then +- { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && +- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && +- { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || +- test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 +- else +- +- # Make a couple of temp file names in the proper directory. +- dsttmp=$dstdir/_inst.$$_ +- rmtmp=$dstdir/_rm.$$_ +- +- # Trap to clean up those temp files at exit. +- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 +- +- # Copy the file name to the temp name. +- (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && +- +- # and set any options; do chmod last to preserve setuid bits. +- # +- # If any of these fail, we abort the whole thing. If we want to +- # ignore errors from any of these, just make sure not to ignore +- # errors from the above "$doit $cpprog $src $dsttmp" command. +- # +- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && +- { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && +- { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && +- { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && +- +- # If -C, don't bother to copy if it wouldn't change the file. +- if $copy_on_change && +- old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && +- new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && +- set -f && +- set X $old && old=:$2:$4:$5:$6 && +- set X $new && new=:$2:$4:$5:$6 && +- set +f && +- test "$old" = "$new" && +- $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 +- then +- rm -f "$dsttmp" +- else +- # Rename the file to the real destination. +- $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || +- +- # The rename failed, perhaps because mv can't rename something else +- # to itself, or perhaps because mv is so ancient that it does not +- # support -f. +- { +- # Now remove or move aside any old file at destination location. +- # We try this two ways since rm can't unlink itself on some +- # systems and the destination file might be busy for other +- # reasons. In this case, the final cleanup might fail but the new +- # file should still install successfully. +- { +- test ! -f "$dst" || +- $doit $rmcmd -f "$dst" 2>/dev/null || +- { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && +- { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } +- } || +- { echo "$0: cannot unlink or rename $dst" >&2 +- (exit 1); exit 1 +- } +- } && +- +- # Now rename the file to the real destination. +- $doit $mvcmd "$dsttmp" "$dst" +- } +- fi || exit 1 +- +- trap '' 0 +- fi +-done +- +-# Local variables: +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "scriptversion=" +-# time-stamp-format: "%:y-%02m-%02d.%02H" +-# time-stamp-time-zone: "UTC" +-# time-stamp-end: "; # UTC" +-# End: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/build-aux/missing groff-1.22.3/src/libs/gnulib/build-aux/missing +--- groff-1.22.3.old/src/libs/gnulib/build-aux/missing 2014-11-04 10:38:35.646518734 +0200 ++++ groff-1.22.3/src/libs/gnulib/build-aux/missing 1970-01-01 02:00:00.000000000 +0200 +@@ -1,330 +0,0 @@ +-#! /bin/sh +-# Common stub for a few missing GNU programs while installing. +- +-scriptversion=2014-09-17.17; # UTC +- +-# Copyright (C) 1996-2014 Free Software Foundation, Inc. +-# Originally by Fran,cois Pinard , 1996. +- +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2, or (at your option) +-# any later version. +- +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-# As a special exception to the GNU General Public License, if you +-# distribute this file as part of a program that contains a +-# configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that program. +- +-if test $# -eq 0; then +- echo 1>&2 "Try '$0 --help' for more information" +- exit 1 +-fi +- +-run=: +-sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +-sed_minuso='s/.* -o \([^ ]*\).*/\1/p' +- +-# In the cases where this matters, 'missing' is being run in the +-# srcdir already. +-if test -f configure.ac; then +- configure_ac=configure.ac +-else +- configure_ac=configure.in +-fi +- +-msg="missing on your system" +- +-case $1 in +---run) +- # Try to run requested program, and just exit if it succeeds. +- run= +- shift +- "$@" && exit 0 +- # Exit code 63 means version mismatch. This often happens +- # when the user try to use an ancient version of a tool on +- # a file that requires a minimum version. In this case we +- # we should proceed has if the program had been absent, or +- # if --run hadn't been passed. +- if test $? = 63; then +- run=: +- msg="probably too old" +- fi +- ;; +- +- -h|--h|--he|--hel|--help) +- echo "\ +-$0 [OPTION]... PROGRAM [ARGUMENT]... +- +-Handle 'PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +-error status if there is no known handling for PROGRAM. +- +-Options: +- -h, --help display this help and exit +- -v, --version output version information and exit +- --run try to run the given command, and emulate it if it fails +- +-Supported PROGRAM values: +- aclocal touch file 'aclocal.m4' +- autoconf touch file 'configure' +- autoheader touch file 'config.h.in' +- autom4te touch the output file, or create a stub one +- automake touch all 'Makefile.in' files +- bison create 'y.tab.[ch]', if possible, from existing .[ch] +- flex create 'lex.yy.c', if possible, from existing .c +- help2man touch the output file +- lex create 'lex.yy.c', if possible, from existing .c +- makeinfo touch the output file +- yacc create 'y.tab.[ch]', if possible, from existing .[ch] +- +-Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +-'g' are ignored when checking the name. +- +-Send bug reports to ." +- exit $? +- ;; +- +- -v|--v|--ve|--ver|--vers|--versi|--versio|--version) +- echo "missing $scriptversion (GNU Automake)" +- exit $? +- ;; +- +- -*) +- echo 1>&2 "$0: Unknown '$1' option" +- echo 1>&2 "Try '$0 --help' for more information" +- exit 1 +- ;; +- +-esac +- +-# normalize program name to check for. +-program=`echo "$1" | sed ' +- s/^gnu-//; t +- s/^gnu//; t +- s/^g//; t'` +- +-# Now exit if we have it, but it failed. Also exit now if we +-# don't have it and --version was passed (most likely to detect +-# the program). This is about non-GNU programs, so use $1 not +-# $program. +-case $1 in +- lex*|yacc*) +- # Not GNU programs, they don't have --version. +- ;; +- +- *) +- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then +- # We have it, but it failed. +- exit 1 +- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then +- # Could not run --version or --help. This is probably someone +- # running '$TOOL --version' or '$TOOL --help' to check whether +- # $TOOL exists and not knowing $TOOL uses missing. +- exit 1 +- fi +- ;; +-esac +- +-# If it does not exist, or fails to run (possibly an outdated version), +-# try to emulate it. +-case $program in +- aclocal*) +- echo 1>&2 "\ +-WARNING: '$1' is $msg. You should only need it if +- you modified 'acinclude.m4' or '${configure_ac}'. You might want +- to install the Automake and Perl packages. Grab them from +- any GNU archive site." +- touch aclocal.m4 +- ;; +- +- autoconf*) +- echo 1>&2 "\ +-WARNING: '$1' is $msg. You should only need it if +- you modified '${configure_ac}'. You might want to install the +- Autoconf and GNU m4 packages. Grab them from any GNU +- archive site." +- touch configure +- ;; +- +- autoheader*) +- echo 1>&2 "\ +-WARNING: '$1' is $msg. You should only need it if +- you modified 'acconfig.h' or '${configure_ac}'. You might want +- to install the Autoconf and GNU m4 packages. Grab them +- from any GNU archive site." +- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` +- test -z "$files" && files="config.h" +- touch_files= +- for f in $files; do +- case $f in +- *:*) touch_files="$touch_files "`echo "$f" | +- sed -e 's/^[^:]*://' -e 's/:.*//'`;; +- *) touch_files="$touch_files $f.in";; +- esac +- done +- touch $touch_files +- ;; +- +- automake*) +- echo 1>&2 "\ +-WARNING: '$1' is $msg. You should only need it if +- you modified 'Makefile.am', 'acinclude.m4' or '${configure_ac}'. +- You might want to install the Automake and Perl packages. +- Grab them from any GNU archive site." +- find . -type f -name Makefile.am -print | +- sed 's/\.am$/.in/' | +- while read f; do touch "$f"; done +- ;; +- +- autom4te*) +- echo 1>&2 "\ +-WARNING: '$1' is needed, but is $msg. +- You might have modified some files without having the +- proper tools for further handling them. +- You can get '$1' as part of Autoconf from any GNU +- archive site." +- +- file=`echo "$*" | sed -n "$sed_output"` +- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` +- if test -f "$file"; then +- touch $file +- else +- test -z "$file" || exec >$file +- echo "#! /bin/sh" +- echo "# Created by GNU Automake missing as a replacement of" +- echo "# $ $@" +- echo "exit 0" +- chmod +x $file +- exit 1 +- fi +- ;; +- +- bison*|yacc*) +- echo 1>&2 "\ +-WARNING: '$1' $msg. You should only need it if +- you modified a '.y' file. You may need the Bison package +- in order for those modifications to take effect. You can get +- Bison from any GNU archive site." +- rm -f y.tab.c y.tab.h +- if test $# -ne 1; then +- eval LASTARG=\${$#} +- case $LASTARG in +- *.y) +- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` +- if test -f "$SRCFILE"; then +- cp "$SRCFILE" y.tab.c +- fi +- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` +- if test -f "$SRCFILE"; then +- cp "$SRCFILE" y.tab.h +- fi +- ;; +- esac +- fi +- if test ! -f y.tab.h; then +- echo >y.tab.h +- fi +- if test ! -f y.tab.c; then +- echo 'main() { return 0; }' >y.tab.c +- fi +- ;; +- +- lex*|flex*) +- echo 1>&2 "\ +-WARNING: '$1' is $msg. You should only need it if +- you modified a '.l' file. You may need the Flex package +- in order for those modifications to take effect. You can get +- Flex from any GNU archive site." +- rm -f lex.yy.c +- if test $# -ne 1; then +- eval LASTARG=\${$#} +- case $LASTARG in +- *.l) +- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` +- if test -f "$SRCFILE"; then +- cp "$SRCFILE" lex.yy.c +- fi +- ;; +- esac +- fi +- if test ! -f lex.yy.c; then +- echo 'main() { return 0; }' >lex.yy.c +- fi +- ;; +- +- help2man*) +- echo 1>&2 "\ +-WARNING: '$1' is $msg. You should only need it if +- you modified a dependency of a manual page. You may need the +- Help2man package in order for those modifications to take +- effect. You can get Help2man from any GNU archive site." +- +- file=`echo "$*" | sed -n "$sed_output"` +- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` +- if test -f "$file"; then +- touch $file +- else +- test -z "$file" || exec >$file +- echo ".ab help2man is required to generate this page" +- exit $? +- fi +- ;; +- +- makeinfo*) +- echo 1>&2 "\ +-WARNING: '$1' is $msg. You should only need it if +- you modified a '.texi' or '.texinfo' file, or any other file +- indirectly affecting the aspect of the manual. The spurious +- call might also be the consequence of using a buggy 'make' (AIX, +- DU, IRIX). You might want to install the Texinfo package or +- the GNU make package. Grab either from any GNU archive site." +- # The file to touch is that specified with -o ... +- file=`echo "$*" | sed -n "$sed_output"` +- test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` +- if test -z "$file"; then +- # ... or it is the one specified with @setfilename ... +- infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` +- file=`sed -n ' +- /^@setfilename/{ +- s/.* \([^ ]*\) *$/\1/ +- p +- q +- }' $infile` +- # ... or it is derived from the source name (dir/f.texi becomes f.info) +- test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info +- fi +- # If the file does not exist, the user really needs makeinfo; +- # let's fail without touching anything. +- test -f $file || exit 1 +- touch $file +- ;; +- +- *) +- echo 1>&2 "\ +-WARNING: '$1' is needed, and is $msg. +- You might have modified some files without having the +- proper tools for further handling them. Check the 'README' file, +- it often tells you about the needed prerequisites for installing +- this package. You may also peek at any GNU archive site, in case +- some other package would contain this missing '$1' program." +- exit 1 +- ;; +-esac +- +-exit 0 +- +-# Local variables: +-# eval: (add-hook 'write-file-hooks 'time-stamp) +-# time-stamp-start: "scriptversion=" +-# time-stamp-format: "%:y-%02m-%02d.%02H" +-# time-stamp-time-zone: "UTC" +-# time-stamp-end: "; # UTC" +-# End: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/build-aux/snippet/arg-nonnull.h groff-1.22.3/src/libs/gnulib/build-aux/snippet/arg-nonnull.h +--- groff-1.22.3.old/src/libs/gnulib/build-aux/snippet/arg-nonnull.h 2014-11-04 10:38:35.650518684 +0200 ++++ groff-1.22.3/src/libs/gnulib/build-aux/snippet/arg-nonnull.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,26 +0,0 @@ +-/* A C macro for declaring that specific arguments must not be NULL. +- Copyright (C) 2009-2014 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify it +- under the terms of the GNU Lesser General Public License as published +- by the Free Software Foundation; either version 2 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public License +- along with this program. If not, see . */ +- +-/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools +- that the values passed as arguments n, ..., m must be non-NULL pointers. +- n = 1 stands for the first argument, n = 2 for the second argument etc. */ +-#ifndef _GL_ARG_NONNULL +-# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3 +-# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params)) +-# else +-# define _GL_ARG_NONNULL(params) +-# endif +-#endif +diff -Nuar groff-1.22.3.old/src/libs/gnulib/build-aux/snippet/c++defs.h groff-1.22.3/src/libs/gnulib/build-aux/snippet/c++defs.h +--- groff-1.22.3.old/src/libs/gnulib/build-aux/snippet/c++defs.h 2014-11-04 10:38:35.650518684 +0200 ++++ groff-1.22.3/src/libs/gnulib/build-aux/snippet/c++defs.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,271 +0,0 @@ +-/* C++ compatible function declaration macros. +- Copyright (C) 2010-2014 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify it +- under the terms of the GNU Lesser General Public License as published +- by the Free Software Foundation; either version 2 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public License +- along with this program. If not, see . */ +- +-#ifndef _GL_CXXDEFS_H +-#define _GL_CXXDEFS_H +- +-/* The three most frequent use cases of these macros are: +- +- * For providing a substitute for a function that is missing on some +- platforms, but is declared and works fine on the platforms on which +- it exists: +- +- #if @GNULIB_FOO@ +- # if !@HAVE_FOO@ +- _GL_FUNCDECL_SYS (foo, ...); +- # endif +- _GL_CXXALIAS_SYS (foo, ...); +- _GL_CXXALIASWARN (foo); +- #elif defined GNULIB_POSIXCHECK +- ... +- #endif +- +- * For providing a replacement for a function that exists on all platforms, +- but is broken/insufficient and needs to be replaced on some platforms: +- +- #if @GNULIB_FOO@ +- # if @REPLACE_FOO@ +- # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +- # undef foo +- # define foo rpl_foo +- # endif +- _GL_FUNCDECL_RPL (foo, ...); +- _GL_CXXALIAS_RPL (foo, ...); +- # else +- _GL_CXXALIAS_SYS (foo, ...); +- # endif +- _GL_CXXALIASWARN (foo); +- #elif defined GNULIB_POSIXCHECK +- ... +- #endif +- +- * For providing a replacement for a function that exists on some platforms +- but is broken/insufficient and needs to be replaced on some of them and +- is additionally either missing or undeclared on some other platforms: +- +- #if @GNULIB_FOO@ +- # if @REPLACE_FOO@ +- # if !(defined __cplusplus && defined GNULIB_NAMESPACE) +- # undef foo +- # define foo rpl_foo +- # endif +- _GL_FUNCDECL_RPL (foo, ...); +- _GL_CXXALIAS_RPL (foo, ...); +- # else +- # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ +- _GL_FUNCDECL_SYS (foo, ...); +- # endif +- _GL_CXXALIAS_SYS (foo, ...); +- # endif +- _GL_CXXALIASWARN (foo); +- #elif defined GNULIB_POSIXCHECK +- ... +- #endif +-*/ +- +-/* _GL_EXTERN_C declaration; +- performs the declaration with C linkage. */ +-#if defined __cplusplus +-# define _GL_EXTERN_C extern "C" +-#else +-# define _GL_EXTERN_C extern +-#endif +- +-/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes); +- declares a replacement function, named rpl_func, with the given prototype, +- consisting of return type, parameters, and attributes. +- Example: +- _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) +- _GL_ARG_NONNULL ((1))); +- */ +-#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \ +- _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes) +-#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \ +- _GL_EXTERN_C rettype rpl_func parameters_and_attributes +- +-/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes); +- declares the system function, named func, with the given prototype, +- consisting of return type, parameters, and attributes. +- Example: +- _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...) +- _GL_ARG_NONNULL ((1))); +- */ +-#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \ +- _GL_EXTERN_C rettype func parameters_and_attributes +- +-/* _GL_CXXALIAS_RPL (func, rettype, parameters); +- declares a C++ alias called GNULIB_NAMESPACE::func +- that redirects to rpl_func, if GNULIB_NAMESPACE is defined. +- Example: +- _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); +- */ +-#define _GL_CXXALIAS_RPL(func,rettype,parameters) \ +- _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- rettype (*const func) parameters = ::rpl_func; \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); +- is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); +- except that the C function rpl_func may have a slightly different +- declaration. A cast is used to silence the "invalid conversion" error +- that would otherwise occur. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- rettype (*const func) parameters = \ +- reinterpret_cast(::rpl_func); \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIAS_SYS (func, rettype, parameters); +- declares a C++ alias called GNULIB_NAMESPACE::func +- that redirects to the system provided function func, if GNULIB_NAMESPACE +- is defined. +- Example: +- _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); +- */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +- /* If we were to write +- rettype (*const func) parameters = ::func; +- like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls +- better (remove an indirection through a 'static' pointer variable), +- but then the _GL_CXXALIASWARN macro below would cause a warning not only +- for uses of ::func but also for uses of GNULIB_NAMESPACE::func. */ +-# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- static rettype (*func) parameters = ::func; \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_SYS(func,rettype,parameters) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); +- is like _GL_CXXALIAS_SYS (func, rettype, parameters); +- except that the C function func may have a slightly different declaration. +- A cast is used to silence the "invalid conversion" error that would +- otherwise occur. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- static rettype (*func) parameters = \ +- reinterpret_cast(::func); \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); +- is like _GL_CXXALIAS_SYS (func, rettype, parameters); +- except that the C function is picked among a set of overloaded functions, +- namely the one with rettype2 and parameters2. Two consecutive casts +- are used to silence the "cannot find a match" and "invalid conversion" +- errors that would otherwise occur. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +- /* The outer cast must be a reinterpret_cast. +- The inner cast: When the function is defined as a set of overloaded +- functions, it works as a static_cast<>, choosing the designated variant. +- When the function is defined as a single variant, it works as a +- reinterpret_cast<>. The parenthesized cast syntax works both ways. */ +-# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ +- namespace GNULIB_NAMESPACE \ +- { \ +- static rettype (*func) parameters = \ +- reinterpret_cast( \ +- (rettype2(*)parameters2)(::func)); \ +- } \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#else +-# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIASWARN (func); +- causes a warning to be emitted when ::func is used but not when +- GNULIB_NAMESPACE::func is used. func must be defined without overloaded +- variants. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIASWARN(func) \ +- _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) +-# define _GL_CXXALIASWARN_1(func,namespace) \ +- _GL_CXXALIASWARN_2 (func, namespace) +-/* To work around GCC bug , +- we enable the warning only when not optimizing. */ +-# if !__OPTIMIZE__ +-# define _GL_CXXALIASWARN_2(func,namespace) \ +- _GL_WARN_ON_USE (func, \ +- "The symbol ::" #func " refers to the system function. " \ +- "Use " #namespace "::" #func " instead.") +-# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +-# define _GL_CXXALIASWARN_2(func,namespace) \ +- extern __typeof__ (func) func +-# else +-# define _GL_CXXALIASWARN_2(func,namespace) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-# endif +-#else +-# define _GL_CXXALIASWARN(func) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); +- causes a warning to be emitted when the given overloaded variant of ::func +- is used but not when GNULIB_NAMESPACE::func is used. */ +-#if defined __cplusplus && defined GNULIB_NAMESPACE +-# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ +- _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ +- GNULIB_NAMESPACE) +-# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ +- _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) +-/* To work around GCC bug , +- we enable the warning only when not optimizing. */ +-# if !__OPTIMIZE__ +-# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ +- _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \ +- "The symbol ::" #func " refers to the system function. " \ +- "Use " #namespace "::" #func " instead.") +-# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +-# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ +- extern __typeof__ (func) func +-# else +-# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-# endif +-#else +-# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ +- _GL_EXTERN_C int _gl_cxxalias_dummy +-#endif +- +-#endif /* _GL_CXXDEFS_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/build-aux/snippet/warn-on-use.h groff-1.22.3/src/libs/gnulib/build-aux/snippet/warn-on-use.h +--- groff-1.22.3.old/src/libs/gnulib/build-aux/snippet/warn-on-use.h 2014-11-04 10:38:35.651518671 +0200 ++++ groff-1.22.3/src/libs/gnulib/build-aux/snippet/warn-on-use.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,109 +0,0 @@ +-/* A C macro for emitting warnings if a function is used. +- Copyright (C) 2010-2014 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify it +- under the terms of the GNU Lesser General Public License as published +- by the Free Software Foundation; either version 2 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public License +- along with this program. If not, see . */ +- +-/* _GL_WARN_ON_USE (function, "literal string") issues a declaration +- for FUNCTION which will then trigger a compiler warning containing +- the text of "literal string" anywhere that function is called, if +- supported by the compiler. If the compiler does not support this +- feature, the macro expands to an unused extern declaration. +- +- This macro is useful for marking a function as a potential +- portability trap, with the intent that "literal string" include +- instructions on the replacement function that should be used +- instead. However, one of the reasons that a function is a +- portability trap is if it has the wrong signature. Declaring +- FUNCTION with a different signature in C is a compilation error, so +- this macro must use the same type as any existing declaration so +- that programs that avoid the problematic FUNCTION do not fail to +- compile merely because they included a header that poisoned the +- function. But this implies that _GL_WARN_ON_USE is only safe to +- use if FUNCTION is known to already have a declaration. Use of +- this macro implies that there must not be any other macro hiding +- the declaration of FUNCTION; but undefining FUNCTION first is part +- of the poisoning process anyway (although for symbols that are +- provided only via a macro, the result is a compilation error rather +- than a warning containing "literal string"). Also note that in +- C++, it is only safe to use if FUNCTION has no overloads. +- +- For an example, it is possible to poison 'getline' by: +- - adding a call to gl_WARN_ON_USE_PREPARE([[#include ]], +- [getline]) in configure.ac, which potentially defines +- HAVE_RAW_DECL_GETLINE +- - adding this code to a header that wraps the system : +- #undef getline +- #if HAVE_RAW_DECL_GETLINE +- _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but" +- "not universally present; use the gnulib module getline"); +- #endif +- +- It is not possible to directly poison global variables. But it is +- possible to write a wrapper accessor function, and poison that +- (less common usage, like &environ, will cause a compilation error +- rather than issue the nice warning, but the end result of informing +- the developer about their portability problem is still achieved): +- #if HAVE_RAW_DECL_ENVIRON +- static char ***rpl_environ (void) { return &environ; } +- _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared"); +- # undef environ +- # define environ (*rpl_environ ()) +- #endif +- */ +-#ifndef _GL_WARN_ON_USE +- +-# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) +-/* A compiler attribute is available in gcc versions 4.3.0 and later. */ +-# define _GL_WARN_ON_USE(function, message) \ +-extern __typeof__ (function) function __attribute__ ((__warning__ (message))) +-# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +-/* Verify the existence of the function. */ +-# define _GL_WARN_ON_USE(function, message) \ +-extern __typeof__ (function) function +-# else /* Unsupported. */ +-# define _GL_WARN_ON_USE(function, message) \ +-_GL_WARN_EXTERN_C int _gl_warn_on_use +-# endif +-#endif +- +-/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string") +- is like _GL_WARN_ON_USE (function, "string"), except that the function is +- declared with the given prototype, consisting of return type, parameters, +- and attributes. +- This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does +- not work in this case. */ +-#ifndef _GL_WARN_ON_USE_CXX +-# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) +-# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +-extern rettype function parameters_and_attributes \ +- __attribute__ ((__warning__ (msg))) +-# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING +-/* Verify the existence of the function. */ +-# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +-extern rettype function parameters_and_attributes +-# else /* Unsupported. */ +-# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \ +-_GL_WARN_EXTERN_C int _gl_warn_on_use +-# endif +-#endif +- +-/* _GL_WARN_EXTERN_C declaration; +- performs the declaration with C linkage. */ +-#ifndef _GL_WARN_EXTERN_C +-# if defined __cplusplus +-# define _GL_WARN_EXTERN_C extern "C" +-# else +-# define _GL_WARN_EXTERN_C extern +-# endif +-#endif +diff -Nuar groff-1.22.3.old/src/libs/gnulib/config.h.in groff-1.22.3/src/libs/gnulib/config.h.in +--- groff-1.22.3.old/src/libs/gnulib/config.h.in 2014-11-04 10:38:35.675518371 +0200 ++++ groff-1.22.3/src/libs/gnulib/config.h.in 1970-01-01 02:00:00.000000000 +0200 +@@ -1,457 +0,0 @@ +-/* config.h.in. Generated from configure.ac by autoheader. */ +- +-/* Define to the number of bits in type 'ptrdiff_t'. */ +-#undef BITSIZEOF_PTRDIFF_T +- +-/* Define to the number of bits in type 'sig_atomic_t'. */ +-#undef BITSIZEOF_SIG_ATOMIC_T +- +-/* Define to the number of bits in type 'size_t'. */ +-#undef BITSIZEOF_SIZE_T +- +-/* Define to the number of bits in type 'wchar_t'. */ +-#undef BITSIZEOF_WCHAR_T +- +-/* Define to the number of bits in type 'wint_t'. */ +-#undef BITSIZEOF_WINT_T +- +-/* Define to 1 when the gnulib module wcwidth should be tested. */ +-#undef GNULIB_TEST_WCWIDTH +- +-/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you +- don't. */ +-#undef HAVE_DECL_GETC_UNLOCKED +- +-/* Define to 1 if you have the declaration of `towlower', and to 0 if you +- don't. */ +-#undef HAVE_DECL_TOWLOWER +- +-/* Define to 1 if you have the declaration of `wcwidth', and to 0 if you +- don't. */ +-#undef HAVE_DECL_WCWIDTH +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_FEATURES_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_INTTYPES_H +- +-/* Define to 1 if you have the 'iswcntrl' function. */ +-#undef HAVE_ISWCNTRL +- +-/* Define if you have and nl_langinfo(CODESET). */ +-#undef HAVE_LANGINFO_CODESET +- +-/* Define to 1 if the system has the type 'long long int'. */ +-#undef HAVE_LONG_LONG_INT +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_MEMORY_H +- +-/* Define to 1 if btowc is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_BTOWC +- +-/* Define to 1 if imaxabs is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_IMAXABS +- +-/* Define to 1 if imaxdiv is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_IMAXDIV +- +-/* Define to 1 if iswctype is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_ISWCTYPE +- +-/* Define to 1 if mbrlen is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_MBRLEN +- +-/* Define to 1 if mbrtowc is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_MBRTOWC +- +-/* Define to 1 if mbsinit is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_MBSINIT +- +-/* Define to 1 if mbsnrtowcs is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_MBSNRTOWCS +- +-/* Define to 1 if mbsrtowcs is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_MBSRTOWCS +- +-/* Define to 1 if strtoimax is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_STRTOIMAX +- +-/* Define to 1 if strtoumax is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_STRTOUMAX +- +-/* Define to 1 if towctrans is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_TOWCTRANS +- +-/* Define to 1 if wcpcpy is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCPCPY +- +-/* Define to 1 if wcpncpy is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCPNCPY +- +-/* Define to 1 if wcrtomb is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCRTOMB +- +-/* Define to 1 if wcscasecmp is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSCASECMP +- +-/* Define to 1 if wcscat is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSCAT +- +-/* Define to 1 if wcschr is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSCHR +- +-/* Define to 1 if wcscmp is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSCMP +- +-/* Define to 1 if wcscoll is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSCOLL +- +-/* Define to 1 if wcscpy is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSCPY +- +-/* Define to 1 if wcscspn is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSCSPN +- +-/* Define to 1 if wcsdup is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSDUP +- +-/* Define to 1 if wcslen is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSLEN +- +-/* Define to 1 if wcsncasecmp is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSNCASECMP +- +-/* Define to 1 if wcsncat is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSNCAT +- +-/* Define to 1 if wcsncmp is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSNCMP +- +-/* Define to 1 if wcsncpy is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSNCPY +- +-/* Define to 1 if wcsnlen is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSNLEN +- +-/* Define to 1 if wcsnrtombs is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSNRTOMBS +- +-/* Define to 1 if wcspbrk is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSPBRK +- +-/* Define to 1 if wcsrchr is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSRCHR +- +-/* Define to 1 if wcsrtombs is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSRTOMBS +- +-/* Define to 1 if wcsspn is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSSPN +- +-/* Define to 1 if wcsstr is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSSTR +- +-/* Define to 1 if wcstok is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSTOK +- +-/* Define to 1 if wcswidth is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSWIDTH +- +-/* Define to 1 if wcsxfrm is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCSXFRM +- +-/* Define to 1 if wctob is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCTOB +- +-/* Define to 1 if wctrans is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCTRANS +- +-/* Define to 1 if wctype is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCTYPE +- +-/* Define to 1 if wcwidth is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WCWIDTH +- +-/* Define to 1 if wmemchr is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WMEMCHR +- +-/* Define to 1 if wmemcmp is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WMEMCMP +- +-/* Define to 1 if wmemcpy is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WMEMCPY +- +-/* Define to 1 if wmemmove is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WMEMMOVE +- +-/* Define to 1 if wmemset is declared even after undefining macros. */ +-#undef HAVE_RAW_DECL_WMEMSET +- +-/* Define to 1 if 'sig_atomic_t' is a signed integer type. */ +-#undef HAVE_SIGNED_SIG_ATOMIC_T +- +-/* Define to 1 if 'wchar_t' is a signed integer type. */ +-#undef HAVE_SIGNED_WCHAR_T +- +-/* Define to 1 if 'wint_t' is a signed integer type. */ +-#undef HAVE_SIGNED_WINT_T +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_STDINT_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_STDLIB_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_STRINGS_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_STRING_H +- +-/* Define to 1 if you have the 'symlink' function. */ +-#undef HAVE_SYMLINK +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_SYS_BITYPES_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_SYS_INTTYPES_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_SYS_STAT_H +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_SYS_TYPES_H +- +-/* Define to 1 if you have the `towlower' function. */ +-#undef HAVE_TOWLOWER +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_UNISTD_H +- +-/* Define to 1 if the system has the type 'unsigned long long int'. */ +-#undef HAVE_UNSIGNED_LONG_LONG_INT +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_WCHAR_H +- +-/* Define if you have the 'wchar_t' type. */ +-#undef HAVE_WCHAR_T +- +-/* Define to 1 if you have the header file. */ +-#undef HAVE_WCTYPE_H +- +-/* Define to 1 if you have the 'wcwidth' function. */ +-#undef HAVE_WCWIDTH +- +-/* Define if you have the 'wint_t' type. */ +-#undef HAVE_WINT_T +- +-/* Define to 1 if O_NOATIME works. */ +-#undef HAVE_WORKING_O_NOATIME +- +-/* Define to 1 if O_NOFOLLOW works. */ +-#undef HAVE_WORKING_O_NOFOLLOW +- +-/* Define to 1 if the system has the type `_Bool'. */ +-#undef HAVE__BOOL +- +-/* Name of package */ +-#undef PACKAGE +- +-/* Define to the address where bug reports for this package should be sent. */ +-#undef PACKAGE_BUGREPORT +- +-/* Define to the full name of this package. */ +-#undef PACKAGE_NAME +- +-/* Define to the full name and version of this package. */ +-#undef PACKAGE_STRING +- +-/* Define to the one symbol short name of this package. */ +-#undef PACKAGE_TARNAME +- +-/* Define to the home page for this package. */ +-#undef PACKAGE_URL +- +-/* Define to the version of this package. */ +-#undef PACKAGE_VERSION +- +-/* Define if exists and defines unusable PRI* macros. */ +-#undef PRI_MACROS_BROKEN +- +-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type +- 'ptrdiff_t'. */ +-#undef PTRDIFF_T_SUFFIX +- +-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type +- 'sig_atomic_t'. */ +-#undef SIG_ATOMIC_T_SUFFIX +- +-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type +- 'size_t'. */ +-#undef SIZE_T_SUFFIX +- +-/* Define to 1 if you have the ANSI C header files. */ +-#undef STDC_HEADERS +- +-/* Enable extensions on AIX 3, Interix. */ +-#ifndef _ALL_SOURCE +-# undef _ALL_SOURCE +-#endif +-/* Enable general extensions on OS X. */ +-#ifndef _DARWIN_C_SOURCE +-# undef _DARWIN_C_SOURCE +-#endif +-/* Enable GNU extensions on systems that have them. */ +-#ifndef _GNU_SOURCE +-# undef _GNU_SOURCE +-#endif +-/* Enable threading extensions on Solaris. */ +-#ifndef _POSIX_PTHREAD_SEMANTICS +-# undef _POSIX_PTHREAD_SEMANTICS +-#endif +-/* Enable extensions on HP NonStop. */ +-#ifndef _TANDEM_SOURCE +-# undef _TANDEM_SOURCE +-#endif +-/* Enable X/Open extensions if necessary. HP-UX 11.11 defines +- mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of +- whether compiling with -Ae or -D_HPUX_SOURCE=1. */ +-#ifndef _XOPEN_SOURCE +-# undef _XOPEN_SOURCE +-#endif +-/* Enable general extensions on Solaris. */ +-#ifndef __EXTENSIONS__ +-# undef __EXTENSIONS__ +-#endif +- +- +-/* Version number of package */ +-#undef VERSION +- +-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type +- 'wchar_t'. */ +-#undef WCHAR_T_SUFFIX +- +-/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type +- 'wint_t'. */ +-#undef WINT_T_SUFFIX +- +-/* Define to 1 if on MINIX. */ +-#undef _MINIX +- +-/* Define to 1 to make NetBSD features available. MINIX 3 needs this. */ +-#undef _NETBSD_SOURCE +- +-/* The _Noreturn keyword of C11. */ +-#if ! (defined _Noreturn \ +- || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__)) +-# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ +- || 0x5110 <= __SUNPRO_C) +-# define _Noreturn __attribute__ ((__noreturn__)) +-# elif defined _MSC_VER && 1200 <= _MSC_VER +-# define _Noreturn __declspec (noreturn) +-# else +-# define _Noreturn +-# endif +-#endif +- +- +-/* Define to 2 if the system does not provide POSIX.1 features except with +- this defined. */ +-#undef _POSIX_1_SOURCE +- +-/* Define to 1 if you need to in order for 'stat' and other things to work. */ +-#undef _POSIX_SOURCE +- +-/* _GL_INLINE is a portable alternative to ISO C99 plain 'inline'. +- _GL_EXTERN_INLINE is a portable alternative to 'extern inline'. +- _GL_INLINE_HEADER_BEGIN contains useful stuff to put +- in an include file, before uses of _GL_INLINE. +- It suppresses GCC's bogus "no previous prototype for 'FOO'" diagnostic, +- when FOO is an inline function in the header; see +- . +- _GL_INLINE_HEADER_END contains useful stuff to put +- in the same include file, after uses of _GL_INLINE. +- +- Suppress the use of extern inline on Apple's platforms, +- as Libc-825.25 (2012-09-19) is incompatible with it; see +- . +- Perhaps Apple will fix this some day. */ +-#if ((__GNUC__ \ +- ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \ +- : 199901L <= __STDC_VERSION__) \ +- && !defined __APPLE__) +-# define _GL_INLINE inline +-# define _GL_EXTERN_INLINE extern inline +-#elif 2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __APPLE__ +-# if __GNUC_GNU_INLINE__ +- /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */ +-# define _GL_INLINE extern inline __attribute__ ((__gnu_inline__)) +-# else +-# define _GL_INLINE extern inline +-# endif +-# define _GL_EXTERN_INLINE extern +-#else +-# define _GL_INLINE static _GL_UNUSED +-# define _GL_EXTERN_INLINE static _GL_UNUSED +-#endif +- +-#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +-# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ +-# define _GL_INLINE_HEADER_CONST_PRAGMA +-# else +-# define _GL_INLINE_HEADER_CONST_PRAGMA \ +- _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") +-# endif +-# define _GL_INLINE_HEADER_BEGIN \ +- _Pragma ("GCC diagnostic push") \ +- _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \ +- _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \ +- _GL_INLINE_HEADER_CONST_PRAGMA +-# define _GL_INLINE_HEADER_END \ +- _Pragma ("GCC diagnostic pop") +-#else +-# define _GL_INLINE_HEADER_BEGIN +-# define _GL_INLINE_HEADER_END +-#endif +- +-/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports +- the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of +- earlier versions), but does not display it by setting __GNUC_STDC_INLINE__. +- __APPLE__ && __MACH__ test for Mac OS X. +- __APPLE_CC__ tests for the Apple compiler and its version. +- __STDC_VERSION__ tests for the C99 mode. */ +-#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__ +-# define __GNUC_STDC_INLINE__ 1 +-#endif +- +-/* Define as a marker that can be attached to declarations that might not +- be used. This helps to reduce warnings, such as from +- GCC -Wunused-parameter. */ +-#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +-# define _GL_UNUSED __attribute__ ((__unused__)) +-#else +-# define _GL_UNUSED +-#endif +-/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name +- is a misnomer outside of parameter lists. */ +-#define _UNUSED_PARAMETER_ _GL_UNUSED +- +-/* The __pure__ attribute was added in gcc 2.96. */ +-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +-# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +-#else +-# define _GL_ATTRIBUTE_PURE /* empty */ +-#endif +- +-/* The __const__ attribute was added in gcc 2.95. */ +-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +-# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) +-#else +-# define _GL_ATTRIBUTE_CONST /* empty */ +-#endif +- +diff -Nuar groff-1.22.3.old/src/libs/gnulib/configure groff-1.22.3/src/libs/gnulib/configure +--- groff-1.22.3.old/src/libs/gnulib/configure 2014-11-04 10:38:35.676518359 +0200 ++++ groff-1.22.3/src/libs/gnulib/configure 1970-01-01 02:00:00.000000000 +0200 +@@ -1,9840 +0,0 @@ +-#! /bin/sh +-# Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.69 for dummy 0. +-# +-# +-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +-# +-# +-# This configure script is free software; the Free Software Foundation +-# gives unlimited permission to copy, distribute and modify it. +-## -------------------- ## +-## M4sh Initialization. ## +-## -------------------- ## +- +-# Be more Bourne compatible +-DUALCASE=1; export DUALCASE # for MKS sh +-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +- emulate sh +- NULLCMD=: +- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which +- # is contrary to our usage. Disable this feature. +- alias -g '${1+"$@"}'='"$@"' +- setopt NO_GLOB_SUBST +-else +- case `(set -o) 2>/dev/null` in #( +- *posix*) : +- set -o posix ;; #( +- *) : +- ;; +-esac +-fi +- +- +-as_nl=' +-' +-export as_nl +-# Printing a long string crashes Solaris 7 /usr/bin/printf. +-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +-# Prefer a ksh shell builtin over an external printf program on Solaris, +-# but without wasting forks for bash or zsh. +-if test -z "$BASH_VERSION$ZSH_VERSION" \ +- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then +- as_echo='print -r --' +- as_echo_n='print -rn --' +-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then +- as_echo='printf %s\n' +- as_echo_n='printf %s' +-else +- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then +- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' +- as_echo_n='/usr/ucb/echo -n' +- else +- as_echo_body='eval expr "X$1" : "X\\(.*\\)"' +- as_echo_n_body='eval +- arg=$1; +- case $arg in #( +- *"$as_nl"*) +- expr "X$arg" : "X\\(.*\\)$as_nl"; +- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; +- esac; +- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" +- ' +- export as_echo_n_body +- as_echo_n='sh -c $as_echo_n_body as_echo' +- fi +- export as_echo_body +- as_echo='sh -c $as_echo_body as_echo' +-fi +- +-# The user is always right. +-if test "${PATH_SEPARATOR+set}" != set; then +- PATH_SEPARATOR=: +- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { +- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || +- PATH_SEPARATOR=';' +- } +-fi +- +- +-# IFS +-# We need space, tab and new line, in precisely that order. Quoting is +-# there to prevent editors from complaining about space-tab. +-# (If _AS_PATH_WALK were called with IFS unset, it would disable word +-# splitting by setting IFS to empty value.) +-IFS=" "" $as_nl" +- +-# Find who we are. Look in the path if we contain no directory separator. +-as_myself= +-case $0 in #(( +- *[\\/]* ) as_myself=$0 ;; +- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +- done +-IFS=$as_save_IFS +- +- ;; +-esac +-# We did not find ourselves, most probably we were run as `sh COMMAND' +-# in which case we are not to be found in the path. +-if test "x$as_myself" = x; then +- as_myself=$0 +-fi +-if test ! -f "$as_myself"; then +- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 +- exit 1 +-fi +- +-# Unset variables that we do not need and which cause bugs (e.g. in +-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +-# suppresses any "Segmentation fault" message there. '((' could +-# trigger a bug in pdksh 5.2.14. +-for as_var in BASH_ENV ENV MAIL MAILPATH +-do eval test x\${$as_var+set} = xset \ +- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +-done +-PS1='$ ' +-PS2='> ' +-PS4='+ ' +- +-# NLS nuisances. +-LC_ALL=C +-export LC_ALL +-LANGUAGE=C +-export LANGUAGE +- +-# CDPATH. +-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +- +-# Use a proper internal environment variable to ensure we don't fall +- # into an infinite loop, continuously re-executing ourselves. +- if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then +- _as_can_reexec=no; export _as_can_reexec; +- # We cannot yet assume a decent shell, so we have to provide a +-# neutralization value for shells without unset; and this also +-# works around shells that cannot unset nonexistent variables. +-# Preserve -v and -x to the replacement shell. +-BASH_ENV=/dev/null +-ENV=/dev/null +-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +-case $- in # (((( +- *v*x* | *x*v* ) as_opts=-vx ;; +- *v* ) as_opts=-v ;; +- *x* ) as_opts=-x ;; +- * ) as_opts= ;; +-esac +-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +-# Admittedly, this is quite paranoid, since all the known shells bail +-# out after a failed `exec'. +-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +-as_fn_exit 255 +- fi +- # We don't want this to propagate to other subprocesses. +- { _as_can_reexec=; unset _as_can_reexec;} +-if test "x$CONFIG_SHELL" = x; then +- as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : +- emulate sh +- NULLCMD=: +- # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which +- # is contrary to our usage. Disable this feature. +- alias -g '\${1+\"\$@\"}'='\"\$@\"' +- setopt NO_GLOB_SUBST +-else +- case \`(set -o) 2>/dev/null\` in #( +- *posix*) : +- set -o posix ;; #( +- *) : +- ;; +-esac +-fi +-" +- as_required="as_fn_return () { (exit \$1); } +-as_fn_success () { as_fn_return 0; } +-as_fn_failure () { as_fn_return 1; } +-as_fn_ret_success () { return 0; } +-as_fn_ret_failure () { return 1; } +- +-exitcode=0 +-as_fn_success || { exitcode=1; echo as_fn_success failed.; } +-as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +-as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +-as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : +- +-else +- exitcode=1; echo positional parameters were not saved. +-fi +-test x\$exitcode = x0 || exit 1 +-test -x / || exit 1" +- as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO +- as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO +- eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && +- test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +-test \$(( 1 + 1 )) = 2 || exit 1" +- if (eval "$as_required") 2>/dev/null; then : +- as_have_required=yes +-else +- as_have_required=no +-fi +- if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : +- +-else +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-as_found=false +-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- as_found=: +- case $as_dir in #( +- /*) +- for as_base in sh bash ksh sh5; do +- # Try only shells that exist, to save several forks. +- as_shell=$as_dir/$as_base +- if { test -f "$as_shell" || test -f "$as_shell.exe"; } && +- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : +- CONFIG_SHELL=$as_shell as_have_required=yes +- if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : +- break 2 +-fi +-fi +- done;; +- esac +- as_found=false +-done +-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && +- { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : +- CONFIG_SHELL=$SHELL as_have_required=yes +-fi; } +-IFS=$as_save_IFS +- +- +- if test "x$CONFIG_SHELL" != x; then : +- export CONFIG_SHELL +- # We cannot yet assume a decent shell, so we have to provide a +-# neutralization value for shells without unset; and this also +-# works around shells that cannot unset nonexistent variables. +-# Preserve -v and -x to the replacement shell. +-BASH_ENV=/dev/null +-ENV=/dev/null +-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +-case $- in # (((( +- *v*x* | *x*v* ) as_opts=-vx ;; +- *v* ) as_opts=-v ;; +- *x* ) as_opts=-x ;; +- * ) as_opts= ;; +-esac +-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +-# Admittedly, this is quite paranoid, since all the known shells bail +-# out after a failed `exec'. +-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +-exit 255 +-fi +- +- if test x$as_have_required = xno; then : +- $as_echo "$0: This script requires a shell more modern than all" +- $as_echo "$0: the shells that I found on your system." +- if test x${ZSH_VERSION+set} = xset ; then +- $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" +- $as_echo "$0: be upgraded to zsh 4.3.4 or later." +- else +- $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +-$0: including any error possibly output before this +-$0: message. Then install a modern shell, or manually run +-$0: the script under such a shell if you do have one." +- fi +- exit 1 +-fi +-fi +-fi +-SHELL=${CONFIG_SHELL-/bin/sh} +-export SHELL +-# Unset more variables known to interfere with behavior of common tools. +-CLICOLOR_FORCE= GREP_OPTIONS= +-unset CLICOLOR_FORCE GREP_OPTIONS +- +-## --------------------- ## +-## M4sh Shell Functions. ## +-## --------------------- ## +-# as_fn_unset VAR +-# --------------- +-# Portably unset VAR. +-as_fn_unset () +-{ +- { eval $1=; unset $1;} +-} +-as_unset=as_fn_unset +- +-# as_fn_set_status STATUS +-# ----------------------- +-# Set $? to STATUS, without forking. +-as_fn_set_status () +-{ +- return $1 +-} # as_fn_set_status +- +-# as_fn_exit STATUS +-# ----------------- +-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +-as_fn_exit () +-{ +- set +e +- as_fn_set_status $1 +- exit $1 +-} # as_fn_exit +- +-# as_fn_mkdir_p +-# ------------- +-# Create "$as_dir" as a directory, including parents if necessary. +-as_fn_mkdir_p () +-{ +- +- case $as_dir in #( +- -*) as_dir=./$as_dir;; +- esac +- test -d "$as_dir" || eval $as_mkdir_p || { +- as_dirs= +- while :; do +- case $as_dir in #( +- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( +- *) as_qdir=$as_dir;; +- esac +- as_dirs="'$as_qdir' $as_dirs" +- as_dir=`$as_dirname -- "$as_dir" || +-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$as_dir" : 'X\(//\)[^/]' \| \ +- X"$as_dir" : 'X\(//\)$' \| \ +- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$as_dir" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- test -d "$as_dir" && break +- done +- test -z "$as_dirs" || eval "mkdir $as_dirs" +- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" +- +- +-} # as_fn_mkdir_p +- +-# as_fn_executable_p FILE +-# ----------------------- +-# Test if FILE is an executable regular file. +-as_fn_executable_p () +-{ +- test -f "$1" && test -x "$1" +-} # as_fn_executable_p +-# as_fn_append VAR VALUE +-# ---------------------- +-# Append the text in VALUE to the end of the definition contained in VAR. Take +-# advantage of any shell optimizations that allow amortized linear growth over +-# repeated appends, instead of the typical quadratic growth present in naive +-# implementations. +-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +- eval 'as_fn_append () +- { +- eval $1+=\$2 +- }' +-else +- as_fn_append () +- { +- eval $1=\$$1\$2 +- } +-fi # as_fn_append +- +-# as_fn_arith ARG... +-# ------------------ +-# Perform arithmetic evaluation on the ARGs, and store the result in the +-# global $as_val. Take advantage of shells that can avoid forks. The arguments +-# must be portable across $(()) and expr. +-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +- eval 'as_fn_arith () +- { +- as_val=$(( $* )) +- }' +-else +- as_fn_arith () +- { +- as_val=`expr "$@" || test $? -eq 1` +- } +-fi # as_fn_arith +- +- +-# as_fn_error STATUS ERROR [LINENO LOG_FD] +-# ---------------------------------------- +-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +-# script with STATUS, using 1 if that was 0. +-as_fn_error () +-{ +- as_status=$1; test $as_status -eq 0 && as_status=1 +- if test "$4"; then +- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 +- fi +- $as_echo "$as_me: error: $2" >&2 +- as_fn_exit $as_status +-} # as_fn_error +- +-if expr a : '\(a\)' >/dev/null 2>&1 && +- test "X`expr 00001 : '.*\(...\)'`" = X001; then +- as_expr=expr +-else +- as_expr=false +-fi +- +-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then +- as_basename=basename +-else +- as_basename=false +-fi +- +-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then +- as_dirname=dirname +-else +- as_dirname=false +-fi +- +-as_me=`$as_basename -- "$0" || +-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ +- X"$0" : 'X\(//\)$' \| \ +- X"$0" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X/"$0" | +- sed '/^.*\/\([^/][^/]*\)\/*$/{ +- s//\1/ +- q +- } +- /^X\/\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\/\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- +-# Avoid depending upon Character Ranges. +-as_cr_letters='abcdefghijklmnopqrstuvwxyz' +-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +-as_cr_Letters=$as_cr_letters$as_cr_LETTERS +-as_cr_digits='0123456789' +-as_cr_alnum=$as_cr_Letters$as_cr_digits +- +- +- as_lineno_1=$LINENO as_lineno_1a=$LINENO +- as_lineno_2=$LINENO as_lineno_2a=$LINENO +- eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && +- test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { +- # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) +- sed -n ' +- p +- /[$]LINENO/= +- ' <$as_myself | +- sed ' +- s/[$]LINENO.*/&-/ +- t lineno +- b +- :lineno +- N +- :loop +- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ +- t loop +- s/-\n.*// +- ' >$as_me.lineno && +- chmod +x "$as_me.lineno" || +- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } +- +- # If we had to re-execute with $CONFIG_SHELL, we're ensured to have +- # already done that, so ensure we don't try to do so again and fall +- # in an infinite loop. This has already happened in practice. +- _as_can_reexec=no; export _as_can_reexec +- # Don't try to exec as it changes $[0], causing all sort of problems +- # (the dirname of $[0] is not the place where we might find the +- # original and so on. Autoconf is especially sensitive to this). +- . "./$as_me.lineno" +- # Exit status is that of the last command. +- exit +-} +- +-ECHO_C= ECHO_N= ECHO_T= +-case `echo -n x` in #((((( +--n*) +- case `echo 'xy\c'` in +- *c*) ECHO_T=' ';; # ECHO_T is single tab character. +- xy) ECHO_C='\c';; +- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null +- ECHO_T=' ';; +- esac;; +-*) +- ECHO_N='-n';; +-esac +- +-rm -f conf$$ conf$$.exe conf$$.file +-if test -d conf$$.dir; then +- rm -f conf$$.dir/conf$$.file +-else +- rm -f conf$$.dir +- mkdir conf$$.dir 2>/dev/null +-fi +-if (echo >conf$$.file) 2>/dev/null; then +- if ln -s conf$$.file conf$$ 2>/dev/null; then +- as_ln_s='ln -s' +- # ... but there are two gotchas: +- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. +- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. +- # In both cases, we have to default to `cp -pR'. +- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || +- as_ln_s='cp -pR' +- elif ln conf$$.file conf$$ 2>/dev/null; then +- as_ln_s=ln +- else +- as_ln_s='cp -pR' +- fi +-else +- as_ln_s='cp -pR' +-fi +-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +-rmdir conf$$.dir 2>/dev/null +- +-if mkdir -p . 2>/dev/null; then +- as_mkdir_p='mkdir -p "$as_dir"' +-else +- test -d ./-p && rmdir ./-p +- as_mkdir_p=false +-fi +- +-as_test_x='test -x' +-as_executable_p=as_fn_executable_p +- +-# Sed expression to map a string onto a valid CPP name. +-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +- +-# Sed expression to map a string onto a valid variable name. +-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +- +- +-test -n "$DJDIR" || exec 7<&0 &1 +- +-# Name of the host. +-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +-# so uname gets run too. +-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` +- +-# +-# Initializations. +-# +-ac_default_prefix=/usr/local +-ac_clean_files= +-ac_config_libobj_dir=. +-LIBOBJS= +-cross_compiling=no +-subdirs= +-MFLAGS= +-MAKEFLAGS= +- +-# Identity of this package. +-PACKAGE_NAME='dummy' +-PACKAGE_TARNAME='dummy' +-PACKAGE_VERSION='0' +-PACKAGE_STRING='dummy 0' +-PACKAGE_BUGREPORT='' +-PACKAGE_URL='' +- +-# Factoring default headers for most tests. +-ac_includes_default="\ +-#include +-#ifdef HAVE_SYS_TYPES_H +-# include +-#endif +-#ifdef HAVE_SYS_STAT_H +-# include +-#endif +-#ifdef STDC_HEADERS +-# include +-# include +-#else +-# ifdef HAVE_STDLIB_H +-# include +-# endif +-#endif +-#ifdef HAVE_STRING_H +-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +-# include +-# endif +-# include +-#endif +-#ifdef HAVE_STRINGS_H +-# include +-#endif +-#ifdef HAVE_INTTYPES_H +-# include +-#endif +-#ifdef HAVE_STDINT_H +-# include +-#endif +-#ifdef HAVE_UNISTD_H +-# include +-#endif" +- +-gl_header_list= +-gl_func_list= +-ac_subst_vars='gl_LTLIBOBJS +-gl_LIBOBJS +-am__EXEEXT_FALSE +-am__EXEEXT_TRUE +-LTLIBOBJS +-LIBOBJS +-LIBGNU_LTLIBDEPS +-LIBGNU_LIBDEPS +-REPLACE_TOWLOWER +-REPLACE_ISWCNTRL +-HAVE_WCTYPE_H +-NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H +-NEXT_WCTYPE_H +-HAVE_ISWCNTRL +-REPLACE_ISWBLANK +-HAVE_WCTRANS_T +-HAVE_WCTYPE_T +-HAVE_ISWBLANK +-GNULIB_TOWCTRANS +-GNULIB_WCTRANS +-GNULIB_ISWCTYPE +-GNULIB_WCTYPE +-GNULIB_ISWBLANK +-HAVE_WINT_T +-HAVE_FEATURES_H +-NEXT_AS_FIRST_DIRECTIVE_WCHAR_H +-NEXT_WCHAR_H +-REPLACE_WCSWIDTH +-REPLACE_WCWIDTH +-REPLACE_WCSNRTOMBS +-REPLACE_WCSRTOMBS +-REPLACE_WCRTOMB +-REPLACE_MBSNRTOWCS +-REPLACE_MBSRTOWCS +-REPLACE_MBRLEN +-REPLACE_MBRTOWC +-REPLACE_MBSINIT +-REPLACE_WCTOB +-REPLACE_BTOWC +-REPLACE_MBSTATE_T +-HAVE_DECL_WCWIDTH +-HAVE_DECL_WCTOB +-HAVE_WCSWIDTH +-HAVE_WCSTOK +-HAVE_WCSSTR +-HAVE_WCSPBRK +-HAVE_WCSSPN +-HAVE_WCSCSPN +-HAVE_WCSRCHR +-HAVE_WCSCHR +-HAVE_WCSDUP +-HAVE_WCSXFRM +-HAVE_WCSCOLL +-HAVE_WCSNCASECMP +-HAVE_WCSCASECMP +-HAVE_WCSNCMP +-HAVE_WCSCMP +-HAVE_WCSNCAT +-HAVE_WCSCAT +-HAVE_WCPNCPY +-HAVE_WCSNCPY +-HAVE_WCPCPY +-HAVE_WCSCPY +-HAVE_WCSNLEN +-HAVE_WCSLEN +-HAVE_WMEMSET +-HAVE_WMEMMOVE +-HAVE_WMEMCPY +-HAVE_WMEMCMP +-HAVE_WMEMCHR +-HAVE_WCSNRTOMBS +-HAVE_WCSRTOMBS +-HAVE_WCRTOMB +-HAVE_MBSNRTOWCS +-HAVE_MBSRTOWCS +-HAVE_MBRLEN +-HAVE_MBRTOWC +-HAVE_MBSINIT +-HAVE_BTOWC +-GNULIB_WCSWIDTH +-GNULIB_WCSTOK +-GNULIB_WCSSTR +-GNULIB_WCSPBRK +-GNULIB_WCSSPN +-GNULIB_WCSCSPN +-GNULIB_WCSRCHR +-GNULIB_WCSCHR +-GNULIB_WCSDUP +-GNULIB_WCSXFRM +-GNULIB_WCSCOLL +-GNULIB_WCSNCASECMP +-GNULIB_WCSCASECMP +-GNULIB_WCSNCMP +-GNULIB_WCSCMP +-GNULIB_WCSNCAT +-GNULIB_WCSCAT +-GNULIB_WCPNCPY +-GNULIB_WCSNCPY +-GNULIB_WCPCPY +-GNULIB_WCSCPY +-GNULIB_WCSNLEN +-GNULIB_WCSLEN +-GNULIB_WMEMSET +-GNULIB_WMEMMOVE +-GNULIB_WMEMCPY +-GNULIB_WMEMCMP +-GNULIB_WMEMCHR +-GNULIB_WCWIDTH +-GNULIB_WCSNRTOMBS +-GNULIB_WCSRTOMBS +-GNULIB_WCRTOMB +-GNULIB_MBSNRTOWCS +-GNULIB_MBSRTOWCS +-GNULIB_MBRLEN +-GNULIB_MBRTOWC +-GNULIB_MBSINIT +-GNULIB_WCTOB +-GNULIB_BTOWC +-LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_FALSE +-LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE +-LIBUNISTRING_UNIWIDTH_H +-LIBUNISTRING_UNITYPES_H +-NEXT_AS_FIRST_DIRECTIVE_STDDEF_H +-NEXT_STDDEF_H +-GL_GENERATE_STDDEF_H_FALSE +-GL_GENERATE_STDDEF_H_TRUE +-STDDEF_H +-HAVE_WCHAR_T +-REPLACE_NULL +-HAVE__BOOL +-GL_GENERATE_STDBOOL_H_FALSE +-GL_GENERATE_STDBOOL_H_TRUE +-STDBOOL_H +-LOCALCHARSET_TESTS_ENVIRONMENT +-GLIBC21 +-NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H +-NEXT_INTTYPES_H +-UINT64_MAX_EQ_ULONG_MAX +-UINT32_MAX_LT_UINTMAX_MAX +-PRIPTR_PREFIX +-PRI_MACROS_BROKEN +-INT64_MAX_EQ_LONG_MAX +-INT32_MAX_LT_INTMAX_MAX +-REPLACE_STRTOIMAX +-HAVE_DECL_STRTOUMAX +-HAVE_DECL_STRTOIMAX +-HAVE_DECL_IMAXDIV +-HAVE_DECL_IMAXABS +-GNULIB_STRTOUMAX +-GNULIB_STRTOIMAX +-GNULIB_IMAXDIV +-GNULIB_IMAXABS +-GL_GENERATE_STDINT_H_FALSE +-GL_GENERATE_STDINT_H_TRUE +-STDINT_H +-WINT_T_SUFFIX +-WCHAR_T_SUFFIX +-SIG_ATOMIC_T_SUFFIX +-SIZE_T_SUFFIX +-PTRDIFF_T_SUFFIX +-HAVE_SIGNED_WINT_T +-HAVE_SIGNED_WCHAR_T +-HAVE_SIGNED_SIG_ATOMIC_T +-BITSIZEOF_WINT_T +-BITSIZEOF_WCHAR_T +-BITSIZEOF_SIG_ATOMIC_T +-BITSIZEOF_SIZE_T +-BITSIZEOF_PTRDIFF_T +-APPLE_UNIVERSAL_BUILD +-HAVE_SYS_BITYPES_H +-HAVE_SYS_INTTYPES_H +-HAVE_STDINT_H +-NEXT_AS_FIRST_DIRECTIVE_STDINT_H +-NEXT_STDINT_H +-PRAGMA_COLUMNS +-PRAGMA_SYSTEM_HEADER +-INCLUDE_NEXT_AS_FIRST_DIRECTIVE +-INCLUDE_NEXT +-HAVE_SYS_TYPES_H +-HAVE_INTTYPES_H +-HAVE_WCHAR_H +-HAVE_UNSIGNED_LONG_LONG_INT +-HAVE_LONG_LONG_INT +-pkglibexecdir +-runstatedir +-lispdir +-GL_COND_LIBTOOL_FALSE +-GL_COND_LIBTOOL_TRUE +-RANLIB +-ARFLAGS +-AR +-EGREP +-GREP +-CPP +-host_os +-host_vendor +-host_cpu +-host +-build_os +-build_vendor +-build_cpu +-build +-am__fastdepCC_FALSE +-am__fastdepCC_TRUE +-CCDEPMODE +-am__nodep +-AMDEPBACKSLASH +-AMDEP_FALSE +-AMDEP_TRUE +-am__quote +-am__include +-DEPDIR +-OBJEXT +-EXEEXT +-ac_ct_CC +-CPPFLAGS +-LDFLAGS +-CFLAGS +-CC +-AM_BACKSLASH +-AM_DEFAULT_VERBOSITY +-AM_DEFAULT_V +-AM_V +-am__untar +-am__tar +-AMTAR +-am__leading_dot +-SET_MAKE +-AWK +-mkdir_p +-MKDIR_P +-INSTALL_STRIP_PROGRAM +-STRIP +-install_sh +-MAKEINFO +-AUTOHEADER +-AUTOMAKE +-AUTOCONF +-ACLOCAL +-VERSION +-PACKAGE +-CYGPATH_W +-am__isrc +-INSTALL_DATA +-INSTALL_SCRIPT +-INSTALL_PROGRAM +-target_alias +-host_alias +-build_alias +-LIBS +-ECHO_T +-ECHO_N +-ECHO_C +-DEFS +-mandir +-localedir +-libdir +-psdir +-pdfdir +-dvidir +-htmldir +-infodir +-docdir +-oldincludedir +-includedir +-localstatedir +-sharedstatedir +-sysconfdir +-datadir +-datarootdir +-libexecdir +-sbindir +-bindir +-program_transform_name +-prefix +-exec_prefix +-PACKAGE_URL +-PACKAGE_BUGREPORT +-PACKAGE_STRING +-PACKAGE_VERSION +-PACKAGE_TARNAME +-PACKAGE_NAME +-PATH_SEPARATOR +-SHELL' +-ac_subst_files='' +-ac_user_opts=' +-enable_option_checking +-enable_silent_rules +-enable_dependency_tracking +-' +- ac_precious_vars='build_alias +-host_alias +-target_alias +-CC +-CFLAGS +-LDFLAGS +-LIBS +-CPPFLAGS +-CPP' +- +- +-# Initialize some variables set by options. +-ac_init_help= +-ac_init_version=false +-ac_unrecognized_opts= +-ac_unrecognized_sep= +-# The variables have the same names as the options, with +-# dashes changed to underlines. +-cache_file=/dev/null +-exec_prefix=NONE +-no_create= +-no_recursion= +-prefix=NONE +-program_prefix=NONE +-program_suffix=NONE +-program_transform_name=s,x,x, +-silent= +-site= +-srcdir= +-verbose= +-x_includes=NONE +-x_libraries=NONE +- +-# Installation directory options. +-# These are left unexpanded so users can "make install exec_prefix=/foo" +-# and all the variables that are supposed to be based on exec_prefix +-# by default will actually change. +-# Use braces instead of parens because sh, perl, etc. also accept them. +-# (The list follows the same order as the GNU Coding Standards.) +-bindir='${exec_prefix}/bin' +-sbindir='${exec_prefix}/sbin' +-libexecdir='${exec_prefix}/libexec' +-datarootdir='${prefix}/share' +-datadir='${datarootdir}' +-sysconfdir='${prefix}/etc' +-sharedstatedir='${prefix}/com' +-localstatedir='${prefix}/var' +-includedir='${prefix}/include' +-oldincludedir='/usr/include' +-docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +-infodir='${datarootdir}/info' +-htmldir='${docdir}' +-dvidir='${docdir}' +-pdfdir='${docdir}' +-psdir='${docdir}' +-libdir='${exec_prefix}/lib' +-localedir='${datarootdir}/locale' +-mandir='${datarootdir}/man' +- +-ac_prev= +-ac_dashdash= +-for ac_option +-do +- # If the previous option needs an argument, assign it. +- if test -n "$ac_prev"; then +- eval $ac_prev=\$ac_option +- ac_prev= +- continue +- fi +- +- case $ac_option in +- *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; +- *=) ac_optarg= ;; +- *) ac_optarg=yes ;; +- esac +- +- # Accept the important Cygnus configure options, so we can diagnose typos. +- +- case $ac_dashdash$ac_option in +- --) +- ac_dashdash=yes ;; +- +- -bindir | --bindir | --bindi | --bind | --bin | --bi) +- ac_prev=bindir ;; +- -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) +- bindir=$ac_optarg ;; +- +- -build | --build | --buil | --bui | --bu) +- ac_prev=build_alias ;; +- -build=* | --build=* | --buil=* | --bui=* | --bu=*) +- build_alias=$ac_optarg ;; +- +- -cache-file | --cache-file | --cache-fil | --cache-fi \ +- | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) +- ac_prev=cache_file ;; +- -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ +- | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) +- cache_file=$ac_optarg ;; +- +- --config-cache | -C) +- cache_file=config.cache ;; +- +- -datadir | --datadir | --datadi | --datad) +- ac_prev=datadir ;; +- -datadir=* | --datadir=* | --datadi=* | --datad=*) +- datadir=$ac_optarg ;; +- +- -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ +- | --dataroo | --dataro | --datar) +- ac_prev=datarootdir ;; +- -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ +- | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) +- datarootdir=$ac_optarg ;; +- +- -disable-* | --disable-*) +- ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` +- # Reject names that are not valid shell variable names. +- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && +- as_fn_error $? "invalid feature name: $ac_useropt" +- ac_useropt_orig=$ac_useropt +- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` +- case $ac_user_opts in +- *" +-"enable_$ac_useropt" +-"*) ;; +- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" +- ac_unrecognized_sep=', ';; +- esac +- eval enable_$ac_useropt=no ;; +- +- -docdir | --docdir | --docdi | --doc | --do) +- ac_prev=docdir ;; +- -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) +- docdir=$ac_optarg ;; +- +- -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) +- ac_prev=dvidir ;; +- -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) +- dvidir=$ac_optarg ;; +- +- -enable-* | --enable-*) +- ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` +- # Reject names that are not valid shell variable names. +- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && +- as_fn_error $? "invalid feature name: $ac_useropt" +- ac_useropt_orig=$ac_useropt +- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` +- case $ac_user_opts in +- *" +-"enable_$ac_useropt" +-"*) ;; +- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" +- ac_unrecognized_sep=', ';; +- esac +- eval enable_$ac_useropt=\$ac_optarg ;; +- +- -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ +- | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ +- | --exec | --exe | --ex) +- ac_prev=exec_prefix ;; +- -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ +- | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ +- | --exec=* | --exe=* | --ex=*) +- exec_prefix=$ac_optarg ;; +- +- -gas | --gas | --ga | --g) +- # Obsolete; use --with-gas. +- with_gas=yes ;; +- +- -help | --help | --hel | --he | -h) +- ac_init_help=long ;; +- -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) +- ac_init_help=recursive ;; +- -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) +- ac_init_help=short ;; +- +- -host | --host | --hos | --ho) +- ac_prev=host_alias ;; +- -host=* | --host=* | --hos=* | --ho=*) +- host_alias=$ac_optarg ;; +- +- -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) +- ac_prev=htmldir ;; +- -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ +- | --ht=*) +- htmldir=$ac_optarg ;; +- +- -includedir | --includedir | --includedi | --included | --include \ +- | --includ | --inclu | --incl | --inc) +- ac_prev=includedir ;; +- -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ +- | --includ=* | --inclu=* | --incl=* | --inc=*) +- includedir=$ac_optarg ;; +- +- -infodir | --infodir | --infodi | --infod | --info | --inf) +- ac_prev=infodir ;; +- -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) +- infodir=$ac_optarg ;; +- +- -libdir | --libdir | --libdi | --libd) +- ac_prev=libdir ;; +- -libdir=* | --libdir=* | --libdi=* | --libd=*) +- libdir=$ac_optarg ;; +- +- -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ +- | --libexe | --libex | --libe) +- ac_prev=libexecdir ;; +- -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ +- | --libexe=* | --libex=* | --libe=*) +- libexecdir=$ac_optarg ;; +- +- -localedir | --localedir | --localedi | --localed | --locale) +- ac_prev=localedir ;; +- -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) +- localedir=$ac_optarg ;; +- +- -localstatedir | --localstatedir | --localstatedi | --localstated \ +- | --localstate | --localstat | --localsta | --localst | --locals) +- ac_prev=localstatedir ;; +- -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ +- | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) +- localstatedir=$ac_optarg ;; +- +- -mandir | --mandir | --mandi | --mand | --man | --ma | --m) +- ac_prev=mandir ;; +- -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) +- mandir=$ac_optarg ;; +- +- -nfp | --nfp | --nf) +- # Obsolete; use --without-fp. +- with_fp=no ;; +- +- -no-create | --no-create | --no-creat | --no-crea | --no-cre \ +- | --no-cr | --no-c | -n) +- no_create=yes ;; +- +- -no-recursion | --no-recursion | --no-recursio | --no-recursi \ +- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) +- no_recursion=yes ;; +- +- -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ +- | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ +- | --oldin | --oldi | --old | --ol | --o) +- ac_prev=oldincludedir ;; +- -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ +- | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ +- | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) +- oldincludedir=$ac_optarg ;; +- +- -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) +- ac_prev=prefix ;; +- -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) +- prefix=$ac_optarg ;; +- +- -program-prefix | --program-prefix | --program-prefi | --program-pref \ +- | --program-pre | --program-pr | --program-p) +- ac_prev=program_prefix ;; +- -program-prefix=* | --program-prefix=* | --program-prefi=* \ +- | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) +- program_prefix=$ac_optarg ;; +- +- -program-suffix | --program-suffix | --program-suffi | --program-suff \ +- | --program-suf | --program-su | --program-s) +- ac_prev=program_suffix ;; +- -program-suffix=* | --program-suffix=* | --program-suffi=* \ +- | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) +- program_suffix=$ac_optarg ;; +- +- -program-transform-name | --program-transform-name \ +- | --program-transform-nam | --program-transform-na \ +- | --program-transform-n | --program-transform- \ +- | --program-transform | --program-transfor \ +- | --program-transfo | --program-transf \ +- | --program-trans | --program-tran \ +- | --progr-tra | --program-tr | --program-t) +- ac_prev=program_transform_name ;; +- -program-transform-name=* | --program-transform-name=* \ +- | --program-transform-nam=* | --program-transform-na=* \ +- | --program-transform-n=* | --program-transform-=* \ +- | --program-transform=* | --program-transfor=* \ +- | --program-transfo=* | --program-transf=* \ +- | --program-trans=* | --program-tran=* \ +- | --progr-tra=* | --program-tr=* | --program-t=*) +- program_transform_name=$ac_optarg ;; +- +- -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) +- ac_prev=pdfdir ;; +- -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) +- pdfdir=$ac_optarg ;; +- +- -psdir | --psdir | --psdi | --psd | --ps) +- ac_prev=psdir ;; +- -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) +- psdir=$ac_optarg ;; +- +- -q | -quiet | --quiet | --quie | --qui | --qu | --q \ +- | -silent | --silent | --silen | --sile | --sil) +- silent=yes ;; +- +- -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) +- ac_prev=sbindir ;; +- -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ +- | --sbi=* | --sb=*) +- sbindir=$ac_optarg ;; +- +- -sharedstatedir | --sharedstatedir | --sharedstatedi \ +- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ +- | --sharedst | --shareds | --shared | --share | --shar \ +- | --sha | --sh) +- ac_prev=sharedstatedir ;; +- -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ +- | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ +- | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ +- | --sha=* | --sh=*) +- sharedstatedir=$ac_optarg ;; +- +- -site | --site | --sit) +- ac_prev=site ;; +- -site=* | --site=* | --sit=*) +- site=$ac_optarg ;; +- +- -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) +- ac_prev=srcdir ;; +- -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) +- srcdir=$ac_optarg ;; +- +- -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ +- | --syscon | --sysco | --sysc | --sys | --sy) +- ac_prev=sysconfdir ;; +- -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ +- | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) +- sysconfdir=$ac_optarg ;; +- +- -target | --target | --targe | --targ | --tar | --ta | --t) +- ac_prev=target_alias ;; +- -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) +- target_alias=$ac_optarg ;; +- +- -v | -verbose | --verbose | --verbos | --verbo | --verb) +- verbose=yes ;; +- +- -version | --version | --versio | --versi | --vers | -V) +- ac_init_version=: ;; +- +- -with-* | --with-*) +- ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` +- # Reject names that are not valid shell variable names. +- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && +- as_fn_error $? "invalid package name: $ac_useropt" +- ac_useropt_orig=$ac_useropt +- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` +- case $ac_user_opts in +- *" +-"with_$ac_useropt" +-"*) ;; +- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" +- ac_unrecognized_sep=', ';; +- esac +- eval with_$ac_useropt=\$ac_optarg ;; +- +- -without-* | --without-*) +- ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` +- # Reject names that are not valid shell variable names. +- expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && +- as_fn_error $? "invalid package name: $ac_useropt" +- ac_useropt_orig=$ac_useropt +- ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` +- case $ac_user_opts in +- *" +-"with_$ac_useropt" +-"*) ;; +- *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" +- ac_unrecognized_sep=', ';; +- esac +- eval with_$ac_useropt=no ;; +- +- --x) +- # Obsolete; use --with-x. +- with_x=yes ;; +- +- -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ +- | --x-incl | --x-inc | --x-in | --x-i) +- ac_prev=x_includes ;; +- -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ +- | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) +- x_includes=$ac_optarg ;; +- +- -x-libraries | --x-libraries | --x-librarie | --x-librari \ +- | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) +- ac_prev=x_libraries ;; +- -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ +- | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) +- x_libraries=$ac_optarg ;; +- +- -*) as_fn_error $? "unrecognized option: \`$ac_option' +-Try \`$0 --help' for more information" +- ;; +- +- *=*) +- ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` +- # Reject names that are not valid shell variable names. +- case $ac_envvar in #( +- '' | [0-9]* | *[!_$as_cr_alnum]* ) +- as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; +- esac +- eval $ac_envvar=\$ac_optarg +- export $ac_envvar ;; +- +- *) +- # FIXME: should be removed in autoconf 3.0. +- $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 +- expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && +- $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 +- : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" +- ;; +- +- esac +-done +- +-if test -n "$ac_prev"; then +- ac_option=--`echo $ac_prev | sed 's/_/-/g'` +- as_fn_error $? "missing argument to $ac_option" +-fi +- +-if test -n "$ac_unrecognized_opts"; then +- case $enable_option_checking in +- no) ;; +- fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; +- *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; +- esac +-fi +- +-# Check all directory arguments for consistency. +-for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ +- datadir sysconfdir sharedstatedir localstatedir includedir \ +- oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ +- libdir localedir mandir +-do +- eval ac_val=\$$ac_var +- # Remove trailing slashes. +- case $ac_val in +- */ ) +- ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` +- eval $ac_var=\$ac_val;; +- esac +- # Be sure to have absolute directory names. +- case $ac_val in +- [\\/$]* | ?:[\\/]* ) continue;; +- NONE | '' ) case $ac_var in *prefix ) continue;; esac;; +- esac +- as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +-done +- +-# There might be people who depend on the old broken behavior: `$host' +-# used to hold the argument of --host etc. +-# FIXME: To remove some day. +-build=$build_alias +-host=$host_alias +-target=$target_alias +- +-# FIXME: To remove some day. +-if test "x$host_alias" != x; then +- if test "x$build_alias" = x; then +- cross_compiling=maybe +- elif test "x$build_alias" != "x$host_alias"; then +- cross_compiling=yes +- fi +-fi +- +-ac_tool_prefix= +-test -n "$host_alias" && ac_tool_prefix=$host_alias- +- +-test "$silent" = yes && exec 6>/dev/null +- +- +-ac_pwd=`pwd` && test -n "$ac_pwd" && +-ac_ls_di=`ls -di .` && +-ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || +- as_fn_error $? "working directory cannot be determined" +-test "X$ac_ls_di" = "X$ac_pwd_ls_di" || +- as_fn_error $? "pwd does not report name of working directory" +- +- +-# Find the source files, if location was not specified. +-if test -z "$srcdir"; then +- ac_srcdir_defaulted=yes +- # Try the directory containing this script, then the parent directory. +- ac_confdir=`$as_dirname -- "$as_myself" || +-$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$as_myself" : 'X\(//\)[^/]' \| \ +- X"$as_myself" : 'X\(//\)$' \| \ +- X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$as_myself" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- srcdir=$ac_confdir +- if test ! -r "$srcdir/$ac_unique_file"; then +- srcdir=.. +- fi +-else +- ac_srcdir_defaulted=no +-fi +-if test ! -r "$srcdir/$ac_unique_file"; then +- test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." +- as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +-fi +-ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +-ac_abs_confdir=`( +- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" +- pwd)` +-# When building in place, set srcdir=. +-if test "$ac_abs_confdir" = "$ac_pwd"; then +- srcdir=. +-fi +-# Remove unnecessary trailing slashes from srcdir. +-# Double slashes in file names in object file debugging info +-# mess up M-x gdb in Emacs. +-case $srcdir in +-*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +-esac +-for ac_var in $ac_precious_vars; do +- eval ac_env_${ac_var}_set=\${${ac_var}+set} +- eval ac_env_${ac_var}_value=\$${ac_var} +- eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} +- eval ac_cv_env_${ac_var}_value=\$${ac_var} +-done +- +-# +-# Report the --help message. +-# +-if test "$ac_init_help" = "long"; then +- # Omit some internal or obsolete options to make the list less imposing. +- # This message is too long to be a string in the A/UX 3.1 sh. +- cat <<_ACEOF +-\`configure' configures dummy 0 to adapt to many kinds of systems. +- +-Usage: $0 [OPTION]... [VAR=VALUE]... +- +-To assign environment variables (e.g., CC, CFLAGS...), specify them as +-VAR=VALUE. See below for descriptions of some of the useful variables. +- +-Defaults for the options are specified in brackets. +- +-Configuration: +- -h, --help display this help and exit +- --help=short display options specific to this package +- --help=recursive display the short help of all the included packages +- -V, --version display version information and exit +- -q, --quiet, --silent do not print \`checking ...' messages +- --cache-file=FILE cache test results in FILE [disabled] +- -C, --config-cache alias for \`--cache-file=config.cache' +- -n, --no-create do not create output files +- --srcdir=DIR find the sources in DIR [configure dir or \`..'] +- +-Installation directories: +- --prefix=PREFIX install architecture-independent files in PREFIX +- [$ac_default_prefix] +- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX +- [PREFIX] +- +-By default, \`make install' will install all the files in +-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +-an installation prefix other than \`$ac_default_prefix' using \`--prefix', +-for instance \`--prefix=\$HOME'. +- +-For better control, use the options below. +- +-Fine tuning of the installation directories: +- --bindir=DIR user executables [EPREFIX/bin] +- --sbindir=DIR system admin executables [EPREFIX/sbin] +- --libexecdir=DIR program executables [EPREFIX/libexec] +- --sysconfdir=DIR read-only single-machine data [PREFIX/etc] +- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] +- --localstatedir=DIR modifiable single-machine data [PREFIX/var] +- --libdir=DIR object code libraries [EPREFIX/lib] +- --includedir=DIR C header files [PREFIX/include] +- --oldincludedir=DIR C header files for non-gcc [/usr/include] +- --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] +- --datadir=DIR read-only architecture-independent data [DATAROOTDIR] +- --infodir=DIR info documentation [DATAROOTDIR/info] +- --localedir=DIR locale-dependent data [DATAROOTDIR/locale] +- --mandir=DIR man documentation [DATAROOTDIR/man] +- --docdir=DIR documentation root [DATAROOTDIR/doc/dummy] +- --htmldir=DIR html documentation [DOCDIR] +- --dvidir=DIR dvi documentation [DOCDIR] +- --pdfdir=DIR pdf documentation [DOCDIR] +- --psdir=DIR ps documentation [DOCDIR] +-_ACEOF +- +- cat <<\_ACEOF +- +-Program names: +- --program-prefix=PREFIX prepend PREFIX to installed program names +- --program-suffix=SUFFIX append SUFFIX to installed program names +- --program-transform-name=PROGRAM run sed PROGRAM on installed program names +- +-System types: +- --build=BUILD configure for building on BUILD [guessed] +- --host=HOST cross-compile to build programs to run on HOST [BUILD] +-_ACEOF +-fi +- +-if test -n "$ac_init_help"; then +- case $ac_init_help in +- short | recursive ) echo "Configuration of dummy 0:";; +- esac +- cat <<\_ACEOF +- +-Optional Features: +- --disable-option-checking ignore unrecognized --enable/--with options +- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) +- --enable-FEATURE[=ARG] include FEATURE [ARG=yes] +- --enable-silent-rules less verbose build output (undo: "make V=1") +- --disable-silent-rules verbose build output (undo: "make V=0") +- --enable-dependency-tracking +- do not reject slow dependency extractors +- --disable-dependency-tracking +- speeds up one-time build +- +-Some influential environment variables: +- CC C compiler command +- CFLAGS C compiler flags +- LDFLAGS linker flags, e.g. -L if you have libraries in a +- nonstandard directory +- LIBS libraries to pass to the linker, e.g. -l +- CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if +- you have headers in a nonstandard directory +- CPP C preprocessor +- +-Use these variables to override the choices made by `configure' or to help +-it to find libraries and programs with nonstandard names/locations. +- +-Report bugs to the package provider. +-_ACEOF +-ac_status=$? +-fi +- +-if test "$ac_init_help" = "recursive"; then +- # If there are subdirs, report their specific --help. +- for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue +- test -d "$ac_dir" || +- { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || +- continue +- ac_builddir=. +- +-case "$ac_dir" in +-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +-*) +- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` +- # A ".." for each directory in $ac_dir_suffix. +- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` +- case $ac_top_builddir_sub in +- "") ac_top_builddir_sub=. ac_top_build_prefix= ;; +- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; +- esac ;; +-esac +-ac_abs_top_builddir=$ac_pwd +-ac_abs_builddir=$ac_pwd$ac_dir_suffix +-# for backward compatibility: +-ac_top_builddir=$ac_top_build_prefix +- +-case $srcdir in +- .) # We are building in place. +- ac_srcdir=. +- ac_top_srcdir=$ac_top_builddir_sub +- ac_abs_top_srcdir=$ac_pwd ;; +- [\\/]* | ?:[\\/]* ) # Absolute name. +- ac_srcdir=$srcdir$ac_dir_suffix; +- ac_top_srcdir=$srcdir +- ac_abs_top_srcdir=$srcdir ;; +- *) # Relative name. +- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix +- ac_top_srcdir=$ac_top_build_prefix$srcdir +- ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +-esac +-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix +- +- cd "$ac_dir" || { ac_status=$?; continue; } +- # Check for guested configure. +- if test -f "$ac_srcdir/configure.gnu"; then +- echo && +- $SHELL "$ac_srcdir/configure.gnu" --help=recursive +- elif test -f "$ac_srcdir/configure"; then +- echo && +- $SHELL "$ac_srcdir/configure" --help=recursive +- else +- $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 +- fi || ac_status=$? +- cd "$ac_pwd" || { ac_status=$?; break; } +- done +-fi +- +-test -n "$ac_init_help" && exit $ac_status +-if $ac_init_version; then +- cat <<\_ACEOF +-dummy configure 0 +-generated by GNU Autoconf 2.69 +- +-Copyright (C) 2012 Free Software Foundation, Inc. +-This configure script is free software; the Free Software Foundation +-gives unlimited permission to copy, distribute and modify it. +-_ACEOF +- exit +-fi +- +-## ------------------------ ## +-## Autoconf initialization. ## +-## ------------------------ ## +- +-# ac_fn_c_try_compile LINENO +-# -------------------------- +-# Try to compile conftest.$ac_ext, and return whether this succeeded. +-ac_fn_c_try_compile () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- rm -f conftest.$ac_objext +- if { { ac_try="$ac_compile" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_compile") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- grep -v '^ *+' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- mv -f conftest.er1 conftest.err +- fi +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && { +- test -z "$ac_c_werror_flag" || +- test ! -s conftest.err +- } && test -s conftest.$ac_objext; then : +- ac_retval=0 +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=1 +-fi +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_c_try_compile +- +-# ac_fn_c_try_cpp LINENO +-# ---------------------- +-# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +-ac_fn_c_try_cpp () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- if { { ac_try="$ac_cpp conftest.$ac_ext" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- grep -v '^ *+' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- mv -f conftest.er1 conftest.err +- fi +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } > conftest.i && { +- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || +- test ! -s conftest.err +- }; then : +- ac_retval=0 +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=1 +-fi +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_c_try_cpp +- +-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +-# ------------------------------------------------------- +-# Tests whether HEADER exists, giving a warning if it cannot be compiled using +-# the include files in INCLUDES and setting the cache variable VAR +-# accordingly. +-ac_fn_c_check_header_mongrel () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- if eval \${$3+:} false; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +-$as_echo_n "checking for $2... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +-else +- # Is the header compilable? +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +-$as_echo_n "checking $2 usability... " >&6; } +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-#include <$2> +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_header_compiler=yes +-else +- ac_header_compiler=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +-$as_echo "$ac_header_compiler" >&6; } +- +-# Is the header present? +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +-$as_echo_n "checking $2 presence... " >&6; } +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include <$2> +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- ac_header_preproc=yes +-else +- ac_header_preproc=no +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +-$as_echo "$ac_header_preproc" >&6; } +- +-# So? What about this header? +-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( +- yes:no: ) +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +- ;; +- no:yes:* ) +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +-$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +-$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +- ;; +-esac +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +-$as_echo_n "checking for $2... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- eval "$3=\$ac_header_compiler" +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +-fi +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_header_mongrel +- +-# ac_fn_c_try_run LINENO +-# ---------------------- +-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +-# that executables *can* be run. +-ac_fn_c_try_run () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- if { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' +- { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; }; then : +- ac_retval=0 +-else +- $as_echo "$as_me: program exited with status $ac_status" >&5 +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=$ac_status +-fi +- rm -rf conftest.dSYM conftest_ipa8_conftest.oo +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_c_try_run +- +-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +-# ------------------------------------------------------- +-# Tests whether HEADER exists and can be compiled using the include files in +-# INCLUDES, setting the cache variable VAR accordingly. +-ac_fn_c_check_header_compile () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +-$as_echo_n "checking for $2... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-#include <$2> +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval "$3=yes" +-else +- eval "$3=no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_header_compile +- +-# ac_fn_c_try_link LINENO +-# ----------------------- +-# Try to link conftest.$ac_ext, and return whether this succeeded. +-ac_fn_c_try_link () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- rm -f conftest.$ac_objext conftest$ac_exeext +- if { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- grep -v '^ *+' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- mv -f conftest.er1 conftest.err +- fi +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && { +- test -z "$ac_c_werror_flag" || +- test ! -s conftest.err +- } && test -s conftest$ac_exeext && { +- test "$cross_compiling" = yes || +- test -x conftest$ac_exeext +- }; then : +- ac_retval=0 +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +- ac_retval=1 +-fi +- # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information +- # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would +- # interfere with the next link command; also delete a directory that is +- # left behind by Apple's compiler. We do this before executing the actions. +- rm -rf conftest.dSYM conftest_ipa8_conftest.oo +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- as_fn_set_status $ac_retval +- +-} # ac_fn_c_try_link +- +-# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +-# -------------------------------------------- +-# Tries to find the compile-time value of EXPR in a program that includes +-# INCLUDES, setting VAR accordingly. Returns whether the value could be +-# computed +-ac_fn_c_compute_int () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- if test "$cross_compiling" = yes; then +- # Depending upon the size, compute the lo and hi bounds. +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-static int test_array [1 - 2 * !(($2) >= 0)]; +-test_array [0] = 0; +-return test_array [0]; +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_lo=0 ac_mid=0 +- while :; do +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +-test_array [0] = 0; +-return test_array [0]; +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_hi=$ac_mid; break +-else +- as_fn_arith $ac_mid + 1 && ac_lo=$as_val +- if test $ac_lo -le $ac_mid; then +- ac_lo= ac_hi= +- break +- fi +- as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- done +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-static int test_array [1 - 2 * !(($2) < 0)]; +-test_array [0] = 0; +-return test_array [0]; +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_hi=-1 ac_mid=-1 +- while :; do +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +-test_array [0] = 0; +-return test_array [0]; +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_lo=$ac_mid; break +-else +- as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val +- if test $ac_mid -le $ac_hi; then +- ac_lo= ac_hi= +- break +- fi +- as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- done +-else +- ac_lo= ac_hi= +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-# Binary search between lo and hi bounds. +-while test "x$ac_lo" != "x$ac_hi"; do +- as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +-test_array [0] = 0; +-return test_array [0]; +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_hi=$ac_mid +-else +- as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-done +-case $ac_lo in #(( +-?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +-'') ac_retval=1 ;; +-esac +- else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-static long int longval () { return $2; } +-static unsigned long int ulongval () { return $2; } +-#include +-#include +-int +-main () +-{ +- +- FILE *f = fopen ("conftest.val", "w"); +- if (! f) +- return 1; +- if (($2) < 0) +- { +- long int i = longval (); +- if (i != ($2)) +- return 1; +- fprintf (f, "%ld", i); +- } +- else +- { +- unsigned long int i = ulongval (); +- if (i != ($2)) +- return 1; +- fprintf (f, "%lu", i); +- } +- /* Do not output a trailing newline, as this causes \r\n confusion +- on some platforms. */ +- return ferror (f) || fclose (f) != 0; +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- echo >>conftest.val; read $3 &5 +-$as_echo_n "checking for $2... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-/* Define $2 to an innocuous variant, in case declares $2. +- For example, HP-UX 11i declares gettimeofday. */ +-#define $2 innocuous_$2 +- +-/* System header to define __stub macros and hopefully few prototypes, +- which can conflict with char $2 (); below. +- Prefer to if __STDC__ is defined, since +- exists even on freestanding compilers. */ +- +-#ifdef __STDC__ +-# include +-#else +-# include +-#endif +- +-#undef $2 +- +-/* Override any GCC internal prototype to avoid an error. +- Use char because int might match the return type of a GCC +- builtin and then its argument prototype would still apply. */ +-#ifdef __cplusplus +-extern "C" +-#endif +-char $2 (); +-/* The GNU C library defines this for functions which it implements +- to always fail with ENOSYS. Some functions are actually named +- something starting with __ and the normal name is an alias. */ +-#if defined __stub_$2 || defined __stub___$2 +-choke me +-#endif +- +-int +-main () +-{ +-return $2 (); +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- eval "$3=yes" +-else +- eval "$3=no" +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_func +- +-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +-# --------------------------------------------- +-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +-# accordingly. +-ac_fn_c_check_decl () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- as_decl_name=`echo $2|sed 's/ *(.*//'` +- as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +-$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-#ifndef $as_decl_name +-#ifdef __cplusplus +- (void) $as_decl_use; +-#else +- (void) $as_decl_name; +-#endif +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval "$3=yes" +-else +- eval "$3=no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_decl +- +-# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +-# ------------------------------------------- +-# Tests whether TYPE exists after having included INCLUDES, setting cache +-# variable VAR accordingly. +-ac_fn_c_check_type () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +-$as_echo_n "checking for $2... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- eval "$3=no" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-if (sizeof ($2)) +- return 0; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-if (sizeof (($2))) +- return 0; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- +-else +- eval "$3=yes" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_type +-cat >config.log <<_ACEOF +-This file contains any messages produced by compilers while +-running configure, to aid debugging if configure makes a mistake. +- +-It was created by dummy $as_me 0, which was +-generated by GNU Autoconf 2.69. Invocation command line was +- +- $ $0 $@ +- +-_ACEOF +-exec 5>>config.log +-{ +-cat <<_ASUNAME +-## --------- ## +-## Platform. ## +-## --------- ## +- +-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +-uname -m = `(uname -m) 2>/dev/null || echo unknown` +-uname -r = `(uname -r) 2>/dev/null || echo unknown` +-uname -s = `(uname -s) 2>/dev/null || echo unknown` +-uname -v = `(uname -v) 2>/dev/null || echo unknown` +- +-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +-/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` +- +-/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +-/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +-/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +-/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` +- +-_ASUNAME +- +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- $as_echo "PATH: $as_dir" +- done +-IFS=$as_save_IFS +- +-} >&5 +- +-cat >&5 <<_ACEOF +- +- +-## ----------- ## +-## Core tests. ## +-## ----------- ## +- +-_ACEOF +- +- +-# Keep a trace of the command line. +-# Strip out --no-create and --no-recursion so they do not pile up. +-# Strip out --silent because we don't want to record it for future runs. +-# Also quote any args containing shell meta-characters. +-# Make two passes to allow for proper duplicate-argument suppression. +-ac_configure_args= +-ac_configure_args0= +-ac_configure_args1= +-ac_must_keep_next=false +-for ac_pass in 1 2 +-do +- for ac_arg +- do +- case $ac_arg in +- -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; +- -q | -quiet | --quiet | --quie | --qui | --qu | --q \ +- | -silent | --silent | --silen | --sile | --sil) +- continue ;; +- *\'*) +- ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; +- esac +- case $ac_pass in +- 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; +- 2) +- as_fn_append ac_configure_args1 " '$ac_arg'" +- if test $ac_must_keep_next = true; then +- ac_must_keep_next=false # Got value, back to normal. +- else +- case $ac_arg in +- *=* | --config-cache | -C | -disable-* | --disable-* \ +- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ +- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ +- | -with-* | --with-* | -without-* | --without-* | --x) +- case "$ac_configure_args0 " in +- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; +- esac +- ;; +- -* ) ac_must_keep_next=true ;; +- esac +- fi +- as_fn_append ac_configure_args " '$ac_arg'" +- ;; +- esac +- done +-done +-{ ac_configure_args0=; unset ac_configure_args0;} +-{ ac_configure_args1=; unset ac_configure_args1;} +- +-# When interrupted or exit'd, cleanup temporary files, and complete +-# config.log. We remove comments because anyway the quotes in there +-# would cause problems or look ugly. +-# WARNING: Use '\'' to represent an apostrophe within the trap. +-# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +-trap 'exit_status=$? +- # Save into config.log some information that might help in debugging. +- { +- echo +- +- $as_echo "## ---------------- ## +-## Cache variables. ## +-## ---------------- ##" +- echo +- # The following way of writing the cache mishandles newlines in values, +-( +- for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do +- eval ac_val=\$$ac_var +- case $ac_val in #( +- *${as_nl}*) +- case $ac_var in #( +- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; +- esac +- case $ac_var in #( +- _ | IFS | as_nl) ;; #( +- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( +- *) { eval $ac_var=; unset $ac_var;} ;; +- esac ;; +- esac +- done +- (set) 2>&1 | +- case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( +- *${as_nl}ac_space=\ *) +- sed -n \ +- "s/'\''/'\''\\\\'\'''\''/g; +- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" +- ;; #( +- *) +- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" +- ;; +- esac | +- sort +-) +- echo +- +- $as_echo "## ----------------- ## +-## Output variables. ## +-## ----------------- ##" +- echo +- for ac_var in $ac_subst_vars +- do +- eval ac_val=\$$ac_var +- case $ac_val in +- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; +- esac +- $as_echo "$ac_var='\''$ac_val'\''" +- done | sort +- echo +- +- if test -n "$ac_subst_files"; then +- $as_echo "## ------------------- ## +-## File substitutions. ## +-## ------------------- ##" +- echo +- for ac_var in $ac_subst_files +- do +- eval ac_val=\$$ac_var +- case $ac_val in +- *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; +- esac +- $as_echo "$ac_var='\''$ac_val'\''" +- done | sort +- echo +- fi +- +- if test -s confdefs.h; then +- $as_echo "## ----------- ## +-## confdefs.h. ## +-## ----------- ##" +- echo +- cat confdefs.h +- echo +- fi +- test "$ac_signal" != 0 && +- $as_echo "$as_me: caught signal $ac_signal" +- $as_echo "$as_me: exit $exit_status" +- } >&5 +- rm -f core *.core core.conftest.* && +- rm -f -r conftest* confdefs* conf$$* $ac_clean_files && +- exit $exit_status +-' 0 +-for ac_signal in 1 2 13 15; do +- trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +-done +-ac_signal=0 +- +-# confdefs.h avoids OS command line length limits that DEFS can exceed. +-rm -f -r conftest* confdefs.h +- +-$as_echo "/* confdefs.h */" > confdefs.h +- +-# Predefined preprocessor variables. +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_NAME "$PACKAGE_NAME" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_VERSION "$PACKAGE_VERSION" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_STRING "$PACKAGE_STRING" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +-_ACEOF +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE_URL "$PACKAGE_URL" +-_ACEOF +- +- +-# Let the site file select an alternate cache file if it wants to. +-# Prefer an explicitly selected file to automatically selected ones. +-ac_site_file1=NONE +-ac_site_file2=NONE +-if test -n "$CONFIG_SITE"; then +- # We do not want a PATH search for config.site. +- case $CONFIG_SITE in #(( +- -*) ac_site_file1=./$CONFIG_SITE;; +- */*) ac_site_file1=$CONFIG_SITE;; +- *) ac_site_file1=./$CONFIG_SITE;; +- esac +-elif test "x$prefix" != xNONE; then +- ac_site_file1=$prefix/share/config.site +- ac_site_file2=$prefix/etc/config.site +-else +- ac_site_file1=$ac_default_prefix/share/config.site +- ac_site_file2=$ac_default_prefix/etc/config.site +-fi +-for ac_site_file in "$ac_site_file1" "$ac_site_file2" +-do +- test "x$ac_site_file" = xNONE && continue +- if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +-$as_echo "$as_me: loading site script $ac_site_file" >&6;} +- sed 's/^/| /' "$ac_site_file" >&5 +- . "$ac_site_file" \ +- || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "failed to load site script $ac_site_file +-See \`config.log' for more details" "$LINENO" 5; } +- fi +-done +- +-if test -r "$cache_file"; then +- # Some versions of bash will fail to source /dev/null (special files +- # actually), so we avoid doing that. DJGPP emulates it as a regular file. +- if test /dev/null != "$cache_file" && test -f "$cache_file"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +-$as_echo "$as_me: loading cache $cache_file" >&6;} +- case $cache_file in +- [\\/]* | ?:[\\/]* ) . "$cache_file";; +- *) . "./$cache_file";; +- esac +- fi +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +-$as_echo "$as_me: creating cache $cache_file" >&6;} +- >$cache_file +-fi +- +-gl_header_list="$gl_header_list wchar.h" +-gl_header_list="$gl_header_list stdint.h" +-gl_header_list="$gl_header_list inttypes.h" +-gl_header_list="$gl_header_list unistd.h" +-gl_func_list="$gl_func_list symlink" +-gl_header_list="$gl_header_list features.h" +-gl_func_list="$gl_func_list iswcntrl" +-gl_header_list="$gl_header_list wctype.h" +-gl_func_list="$gl_func_list wcwidth" +-# Check that the precious variables saved in the cache have kept the same +-# value. +-ac_cache_corrupted=false +-for ac_var in $ac_precious_vars; do +- eval ac_old_set=\$ac_cv_env_${ac_var}_set +- eval ac_new_set=\$ac_env_${ac_var}_set +- eval ac_old_val=\$ac_cv_env_${ac_var}_value +- eval ac_new_val=\$ac_env_${ac_var}_value +- case $ac_old_set,$ac_new_set in +- set,) +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} +- ac_cache_corrupted=: ;; +- ,set) +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} +- ac_cache_corrupted=: ;; +- ,);; +- *) +- if test "x$ac_old_val" != "x$ac_new_val"; then +- # differences in whitespace do not lead to failure. +- ac_old_val_w=`echo x $ac_old_val` +- ac_new_val_w=`echo x $ac_new_val` +- if test "$ac_old_val_w" != "$ac_new_val_w"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} +- ac_cache_corrupted=: +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} +- eval $ac_var=\$ac_old_val +- fi +- { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +-$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +-$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} +- fi;; +- esac +- # Pass precious variables to config.status. +- if test "$ac_new_set" = set; then +- case $ac_new_val in +- *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; +- *) ac_arg=$ac_var=$ac_new_val ;; +- esac +- case " $ac_configure_args " in +- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. +- *) as_fn_append ac_configure_args " '$ac_arg'" ;; +- esac +- fi +-done +-if $ac_cache_corrupted; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +- { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} +- as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +-fi +-## -------------------- ## +-## Main body of script. ## +-## -------------------- ## +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +-ac_aux_dir= +-for ac_dir in build-aux "$srcdir"/build-aux; do +- if test -f "$ac_dir/install-sh"; then +- ac_aux_dir=$ac_dir +- ac_install_sh="$ac_aux_dir/install-sh -c" +- break +- elif test -f "$ac_dir/install.sh"; then +- ac_aux_dir=$ac_dir +- ac_install_sh="$ac_aux_dir/install.sh -c" +- break +- elif test -f "$ac_dir/shtool"; then +- ac_aux_dir=$ac_dir +- ac_install_sh="$ac_aux_dir/shtool install -c" +- break +- fi +-done +-if test -z "$ac_aux_dir"; then +- as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 +-fi +- +-# These three variables are undocumented and unsupported, +-# and are intended to be withdrawn in a future Autoconf release. +-# They can cause serious problems if a builder's source tree is in a directory +-# whose full name contains unusual characters. +-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. +- +- +-am__api_version='1.14' +- +-# Find a good install program. We prefer a C program (faster), +-# so one script is as good as another. But avoid the broken or +-# incompatible versions: +-# SysV /etc/install, /usr/sbin/install +-# SunOS /usr/etc/install +-# IRIX /sbin/install +-# AIX /bin/install +-# AmigaOS /C/install, which installs bootblocks on floppy discs +-# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +-# AFS /usr/afsws/bin/install, which mishandles nonexistent args +-# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +-# OS/2's system install, which has a completely different semantic +-# ./install, which can be erroneously created by make from ./install.sh. +-# Reject install programs that cannot install multiple files. +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +-$as_echo_n "checking for a BSD-compatible install... " >&6; } +-if test -z "$INSTALL"; then +-if ${ac_cv_path_install+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- # Account for people who put trailing slashes in PATH elements. +-case $as_dir/ in #(( +- ./ | .// | /[cC]/* | \ +- /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ +- ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ +- /usr/ucb/* ) ;; +- *) +- # OSF1 and SCO ODT 3.0 have their own names for install. +- # Don't use installbsd from OSF since it installs stuff as root +- # by default. +- for ac_prog in ginstall scoinst install; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then +- if test $ac_prog = install && +- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then +- # AIX install. It has an incompatible calling convention. +- : +- elif test $ac_prog = install && +- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then +- # program-specific install script used by HP pwplus--don't use. +- : +- else +- rm -rf conftest.one conftest.two conftest.dir +- echo one > conftest.one +- echo two > conftest.two +- mkdir conftest.dir +- if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && +- test -s conftest.one && test -s conftest.two && +- test -s conftest.dir/conftest.one && +- test -s conftest.dir/conftest.two +- then +- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" +- break 3 +- fi +- fi +- fi +- done +- done +- ;; +-esac +- +- done +-IFS=$as_save_IFS +- +-rm -rf conftest.one conftest.two conftest.dir +- +-fi +- if test "${ac_cv_path_install+set}" = set; then +- INSTALL=$ac_cv_path_install +- else +- # As a last resort, use the slow shell script. Don't cache a +- # value for INSTALL within a source directory, because that will +- # break other packages using the cache if that directory is +- # removed, or if the value is a relative name. +- INSTALL=$ac_install_sh +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +-$as_echo "$INSTALL" >&6; } +- +-# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +-# It thinks the first close brace ends the variable substitution. +-test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' +- +-test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' +- +-test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +-$as_echo_n "checking whether build environment is sane... " >&6; } +-# Reject unsafe characters in $srcdir or the absolute working directory +-# name. Accept space and tab only in the latter. +-am_lf=' +-' +-case `pwd` in +- *[\\\"\#\$\&\'\`$am_lf]*) +- as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +-esac +-case $srcdir in +- *[\\\"\#\$\&\'\`$am_lf\ \ ]*) +- as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +-esac +- +-# Do 'set' in a subshell so we don't clobber the current shell's +-# arguments. Must try -L first in case configure is actually a +-# symlink; some systems play weird games with the mod time of symlinks +-# (eg FreeBSD returns the mod time of the symlink's containing +-# directory). +-if ( +- am_has_slept=no +- for am_try in 1 2; do +- echo "timestamp, slept: $am_has_slept" > conftest.file +- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` +- if test "$*" = "X"; then +- # -L didn't work. +- set X `ls -t "$srcdir/configure" conftest.file` +- fi +- if test "$*" != "X $srcdir/configure conftest.file" \ +- && test "$*" != "X conftest.file $srcdir/configure"; then +- +- # If neither matched, then we have a broken ls. This can happen +- # if, for instance, CONFIG_SHELL is bash and it inherits a +- # broken ls alias from the environment. This has actually +- # happened. Such a system could not be considered "sane". +- as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +- alias in your environment" "$LINENO" 5 +- fi +- if test "$2" = conftest.file || test $am_try -eq 2; then +- break +- fi +- # Just in case. +- sleep 1 +- am_has_slept=yes +- done +- test "$2" = conftest.file +- ) +-then +- # Ok. +- : +-else +- as_fn_error $? "newly created file is older than distributed files! +-Check your system clock" "$LINENO" 5 +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-# If we didn't sleep, we still need to ensure time stamps of config.status and +-# generated files are strictly newer. +-am_sleep_pid= +-if grep 'slept: no' conftest.file >/dev/null 2>&1; then +- ( sleep 1 ) & +- am_sleep_pid=$! +-fi +- +-rm -f conftest.file +- +-test "$program_prefix" != NONE && +- program_transform_name="s&^&$program_prefix&;$program_transform_name" +-# Use a double $ so make ignores it. +-test "$program_suffix" != NONE && +- program_transform_name="s&\$&$program_suffix&;$program_transform_name" +-# Double any \ or $. +-# By default was `s,x,x', remove it if useless. +-ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +-program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` +- +-# expand $ac_aux_dir to an absolute path +-am_aux_dir=`cd $ac_aux_dir && pwd` +- +-if test x"${MISSING+set}" != xset; then +- case $am_aux_dir in +- *\ * | *\ *) +- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; +- *) +- MISSING="\${SHELL} $am_aux_dir/missing" ;; +- esac +-fi +-# Use eval to expand $SHELL +-if eval "$MISSING --is-lightweight"; then +- am_missing_run="$MISSING " +-else +- am_missing_run= +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +-$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +-fi +- +-if test x"${install_sh}" != xset; then +- case $am_aux_dir in +- *\ * | *\ *) +- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; +- *) +- install_sh="\${SHELL} $am_aux_dir/install-sh" +- esac +-fi +- +-# Installed binaries are usually stripped using 'strip' when the user +-# run "make install-strip". However 'strip' might not be the right +-# tool to use in cross-compilation environments, therefore Automake +-# will honor the 'STRIP' environment variable to overrule this program. +-if test "$cross_compiling" != no; then +- if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +-set dummy ${ac_tool_prefix}strip; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_STRIP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$STRIP"; then +- ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_STRIP="${ac_tool_prefix}strip" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-STRIP=$ac_cv_prog_STRIP +-if test -n "$STRIP"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +-$as_echo "$STRIP" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$ac_cv_prog_STRIP"; then +- ac_ct_STRIP=$STRIP +- # Extract the first word of "strip", so it can be a program name with args. +-set dummy strip; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_STRIP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_STRIP"; then +- ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_STRIP="strip" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +-if test -n "$ac_ct_STRIP"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +-$as_echo "$ac_ct_STRIP" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- if test "x$ac_ct_STRIP" = x; then +- STRIP=":" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- STRIP=$ac_ct_STRIP +- fi +-else +- STRIP="$ac_cv_prog_STRIP" +-fi +- +-fi +-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +-$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +-if test -z "$MKDIR_P"; then +- if ${ac_cv_path_mkdir+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_prog in mkdir gmkdir; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue +- case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( +- 'mkdir (GNU coreutils) '* | \ +- 'mkdir (coreutils) '* | \ +- 'mkdir (fileutils) '4.1*) +- ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext +- break 3;; +- esac +- done +- done +- done +-IFS=$as_save_IFS +- +-fi +- +- test -d ./--version && rmdir ./--version +- if test "${ac_cv_path_mkdir+set}" = set; then +- MKDIR_P="$ac_cv_path_mkdir -p" +- else +- # As a last resort, use the slow shell script. Don't cache a +- # value for MKDIR_P within a source directory, because that will +- # break other packages using the cache if that directory is +- # removed, or if the value is a relative name. +- MKDIR_P="$ac_install_sh -d" +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +-$as_echo "$MKDIR_P" >&6; } +- +-for ac_prog in gawk mawk nawk awk +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_AWK+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$AWK"; then +- ac_cv_prog_AWK="$AWK" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_AWK="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-AWK=$ac_cv_prog_AWK +-if test -n "$AWK"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +-$as_echo "$AWK" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$AWK" && break +-done +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +-set x ${MAKE-make} +-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +-if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat >conftest.make <<\_ACEOF +-SHELL = /bin/sh +-all: +- @echo '@@@%%%=$(MAKE)=@@@%%%' +-_ACEOF +-# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +-case `${MAKE-make} -f conftest.make 2>/dev/null` in +- *@@@%%%=?*=@@@%%%*) +- eval ac_cv_prog_make_${ac_make}_set=yes;; +- *) +- eval ac_cv_prog_make_${ac_make}_set=no;; +-esac +-rm -f conftest.make +-fi +-if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- SET_MAKE= +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- SET_MAKE="MAKE=${MAKE-make}" +-fi +- +-rm -rf .tst 2>/dev/null +-mkdir .tst 2>/dev/null +-if test -d .tst; then +- am__leading_dot=. +-else +- am__leading_dot=_ +-fi +-rmdir .tst 2>/dev/null +- +-# Check whether --enable-silent-rules was given. +-if test "${enable_silent_rules+set}" = set; then : +- enableval=$enable_silent_rules; +-fi +- +-case $enable_silent_rules in # ((( +- yes) AM_DEFAULT_VERBOSITY=0;; +- no) AM_DEFAULT_VERBOSITY=1;; +- *) AM_DEFAULT_VERBOSITY=1;; +-esac +-am_make=${MAKE-make} +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +-$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +-if ${am_cv_make_support_nested_variables+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if $as_echo 'TRUE=$(BAR$(V)) +-BAR0=false +-BAR1=true +-V=1 +-am__doit: +- @$(TRUE) +-.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then +- am_cv_make_support_nested_variables=yes +-else +- am_cv_make_support_nested_variables=no +-fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +-$as_echo "$am_cv_make_support_nested_variables" >&6; } +-if test $am_cv_make_support_nested_variables = yes; then +- AM_V='$(V)' +- AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +-else +- AM_V=$AM_DEFAULT_VERBOSITY +- AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +-fi +-AM_BACKSLASH='\' +- +-if test "`cd $srcdir && pwd`" != "`pwd`"; then +- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output +- # is not polluted with repeated "-I." +- am__isrc=' -I$(srcdir)' +- # test to see if srcdir already configured +- if test -f $srcdir/config.status; then +- as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 +- fi +-fi +- +-# test whether we have cygpath +-if test -z "$CYGPATH_W"; then +- if (cygpath --version) >/dev/null 2>/dev/null; then +- CYGPATH_W='cygpath -w' +- else +- CYGPATH_W=echo +- fi +-fi +- +- +-# Define the identity of the package. +- PACKAGE='dummy' +- VERSION='0' +- +- +-cat >>confdefs.h <<_ACEOF +-#define PACKAGE "$PACKAGE" +-_ACEOF +- +- +-cat >>confdefs.h <<_ACEOF +-#define VERSION "$VERSION" +-_ACEOF +- +-# Some tools Automake needs. +- +-ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} +- +- +-AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} +- +- +-AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} +- +- +-AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} +- +- +-MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} +- +-# For better backward compatibility. To be removed once Automake 1.9.x +-# dies out for good. For more background, see: +-# +-# +-mkdir_p='$(MKDIR_P)' +- +-# We need awk for the "check" target. The system "awk" is bad on +-# some platforms. +-# Always define AMTAR for backward compatibility. Yes, it's still used +-# in the wild :-( We should find a proper way to deprecate it ... +-AMTAR='$${TAR-tar}' +- +- +-# We'll loop over all known methods to create a tar archive until one works. +-_am_tools='gnutar pax cpio none' +- +-am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' +- +- +- +- +- +- +-# POSIX will say in a future version that running "rm -f" with no argument +-# is OK; and we want to be able to make that assumption in our Makefile +-# recipes. So use an aggressive probe to check that the usage we want is +-# actually supported "in the wild" to an acceptable degree. +-# See automake bug#10828. +-# To make any issue more visible, cause the running configure to be aborted +-# by default if the 'rm' program in use doesn't match our expectations; the +-# user can still override this though. +-if rm -f && rm -fr && rm -rf; then : OK; else +- cat >&2 <<'END' +-Oops! +- +-Your 'rm' program seems unable to run without file operands specified +-on the command line, even when the '-f' option is present. This is contrary +-to the behaviour of most rm programs out there, and not conforming with +-the upcoming POSIX standard: +- +-Please tell bug-automake@gnu.org about your system, including the value +-of your $PATH and any error possibly output before this message. This +-can help us improve future automake versions. +- +-END +- if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then +- echo 'Configuration will proceed anyway, since you have set the' >&2 +- echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 +- echo >&2 +- else +- cat >&2 <<'END' +-Aborting the configuration process, to ensure you take notice of the issue. +- +-You can download and install GNU coreutils to get an 'rm' implementation +-that behaves properly: . +- +-If you want to complete the configuration process using your problematic +-'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +-to "yes", and re-run configure. +- +-END +- as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 +- fi +-fi +- +-ac_config_headers="$ac_config_headers config.h" +- +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +-if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +-set dummy ${ac_tool_prefix}gcc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CC="${ac_tool_prefix}gcc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$ac_cv_prog_CC"; then +- ac_ct_CC=$CC +- # Extract the first word of "gcc", so it can be a program name with args. +-set dummy gcc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_CC"; then +- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_CC="gcc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_CC=$ac_cv_prog_ac_ct_CC +-if test -n "$ac_ct_CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +-$as_echo "$ac_ct_CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- if test "x$ac_ct_CC" = x; then +- CC="" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- CC=$ac_ct_CC +- fi +-else +- CC="$ac_cv_prog_CC" +-fi +- +-if test -z "$CC"; then +- if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +-set dummy ${ac_tool_prefix}cc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CC="${ac_tool_prefix}cc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- fi +-fi +-if test -z "$CC"; then +- # Extract the first word of "cc", so it can be a program name with args. +-set dummy cc; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +- ac_prog_rejected=no +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then +- ac_prog_rejected=yes +- continue +- fi +- ac_cv_prog_CC="cc" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-if test $ac_prog_rejected = yes; then +- # We found a bogon in the path, so make sure we never use it. +- set dummy $ac_cv_prog_CC +- shift +- if test $# != 0; then +- # We chose a different compiler from the bogus one. +- # However, it has the same basename, so the bogon will be chosen +- # first if we set CC to just the basename; use the full file name. +- shift +- ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" +- fi +-fi +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$CC"; then +- if test -n "$ac_tool_prefix"; then +- for ac_prog in cl.exe +- do +- # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +-set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$CC"; then +- ac_cv_prog_CC="$CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_CC="$ac_tool_prefix$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-CC=$ac_cv_prog_CC +-if test -n "$CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +-$as_echo "$CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$CC" && break +- done +-fi +-if test -z "$CC"; then +- ac_ct_CC=$CC +- for ac_prog in cl.exe +-do +- # Extract the first word of "$ac_prog", so it can be a program name with args. +-set dummy $ac_prog; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_CC+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_CC"; then +- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_CC="$ac_prog" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_CC=$ac_cv_prog_ac_ct_CC +-if test -n "$ac_ct_CC"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +-$as_echo "$ac_ct_CC" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +- test -n "$ac_ct_CC" && break +-done +- +- if test "x$ac_ct_CC" = x; then +- CC="" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- CC=$ac_ct_CC +- fi +-fi +- +-fi +- +- +-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "no acceptable C compiler found in \$PATH +-See \`config.log' for more details" "$LINENO" 5; } +- +-# Provide some information about the compiler. +-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +-set X $ac_compile +-ac_compiler=$2 +-for ac_option in --version -v -V -qversion; do +- { { ac_try="$ac_compiler $ac_option >&5" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_compiler $ac_option >&5") 2>conftest.err +- ac_status=$? +- if test -s conftest.err; then +- sed '10a\ +-... rest of stderr output deleted ... +- 10q' conftest.err >conftest.er1 +- cat conftest.er1 >&5 +- fi +- rm -f conftest.er1 conftest.err +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } +-done +- +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-ac_clean_files_save=$ac_clean_files +-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +-# Try to create an executable without -o first, disregard a.out. +-# It will help us diagnose broken compilers, and finding out an intuition +-# of exeext. +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +-$as_echo_n "checking whether the C compiler works... " >&6; } +-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +- +-# The possible output files: +-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" +- +-ac_rmfiles= +-for ac_file in $ac_files +-do +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; +- * ) ac_rmfiles="$ac_rmfiles $ac_file";; +- esac +-done +-rm -f $ac_rmfiles +- +-if { { ac_try="$ac_link_default" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link_default") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then : +- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +-# in a Makefile. We should not override ac_cv_exeext if it was cached, +-# so that the user can short-circuit this test for compilers unknown to +-# Autoconf. +-for ac_file in $ac_files '' +-do +- test -f "$ac_file" || continue +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) +- ;; +- [ab].out ) +- # We found the default executable, but exeext='' is most +- # certainly right. +- break;; +- *.* ) +- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; +- then :; else +- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` +- fi +- # We set ac_cv_exeext here because the later test for it is not +- # safe: cross compilers may not add the suffix if given an `-o' +- # argument, so we may need to know it at that point already. +- # Even if this section looks crufty: it has the advantage of +- # actually working. +- break;; +- * ) +- break;; +- esac +-done +-test "$ac_cv_exeext" = no && ac_cv_exeext= +- +-else +- ac_file='' +-fi +-if test -z "$ac_file"; then : +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-$as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error 77 "C compiler cannot create executables +-See \`config.log' for more details" "$LINENO" 5; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +-$as_echo_n "checking for C compiler default output file name... " >&6; } +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +-$as_echo "$ac_file" >&6; } +-ac_exeext=$ac_cv_exeext +- +-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +-ac_clean_files=$ac_clean_files_save +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +-$as_echo_n "checking for suffix of executables... " >&6; } +-if { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then : +- # If both `conftest.exe' and `conftest' are `present' (well, observable) +-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +-# work properly (i.e., refer to `conftest.exe'), while it won't with +-# `rm'. +-for ac_file in conftest.exe conftest conftest.*; do +- test -f "$ac_file" || continue +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; +- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` +- break;; +- * ) break;; +- esac +-done +-else +- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "cannot compute suffix of executables: cannot compile and link +-See \`config.log' for more details" "$LINENO" 5; } +-fi +-rm -f conftest conftest$ac_cv_exeext +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +-$as_echo "$ac_cv_exeext" >&6; } +- +-rm -f conftest.$ac_ext +-EXEEXT=$ac_cv_exeext +-ac_exeext=$EXEEXT +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-int +-main () +-{ +-FILE *f = fopen ("conftest.out", "w"); +- return ferror (f) || fclose (f) != 0; +- +- ; +- return 0; +-} +-_ACEOF +-ac_clean_files="$ac_clean_files conftest.out" +-# Check that the compiler produces executables we can run. If not, either +-# the compiler is broken, or we cross compile. +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +-$as_echo_n "checking whether we are cross compiling... " >&6; } +-if test "$cross_compiling" != yes; then +- { { ac_try="$ac_link" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_link") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } +- if { ac_try='./conftest$ac_cv_exeext' +- { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; }; then +- cross_compiling=no +- else +- if test "$cross_compiling" = maybe; then +- cross_compiling=yes +- else +- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "cannot run C compiled programs. +-If you meant to cross compile, use \`--host'. +-See \`config.log' for more details" "$LINENO" 5; } +- fi +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +-$as_echo "$cross_compiling" >&6; } +- +-rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +-ac_clean_files=$ac_clean_files_save +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +-$as_echo_n "checking for suffix of object files... " >&6; } +-if ${ac_cv_objext+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-rm -f conftest.o conftest.obj +-if { { ac_try="$ac_compile" +-case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_compile") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then : +- for ac_file in conftest.o conftest.obj conftest.*; do +- test -f "$ac_file" || continue; +- case $ac_file in +- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; +- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` +- break;; +- esac +-done +-else +- $as_echo "$as_me: failed program was:" >&5 +-sed 's/^/| /' conftest.$ac_ext >&5 +- +-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "cannot compute suffix of object files: cannot compile +-See \`config.log' for more details" "$LINENO" 5; } +-fi +-rm -f conftest.$ac_cv_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +-$as_echo "$ac_cv_objext" >&6; } +-OBJEXT=$ac_cv_objext +-ac_objext=$OBJEXT +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +-if ${ac_cv_c_compiler_gnu+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +-#ifndef __GNUC__ +- choke me +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_compiler_gnu=yes +-else +- ac_compiler_gnu=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-ac_cv_c_compiler_gnu=$ac_compiler_gnu +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +-$as_echo "$ac_cv_c_compiler_gnu" >&6; } +-if test $ac_compiler_gnu = yes; then +- GCC=yes +-else +- GCC= +-fi +-ac_test_CFLAGS=${CFLAGS+set} +-ac_save_CFLAGS=$CFLAGS +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +-$as_echo_n "checking whether $CC accepts -g... " >&6; } +-if ${ac_cv_prog_cc_g+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_save_c_werror_flag=$ac_c_werror_flag +- ac_c_werror_flag=yes +- ac_cv_prog_cc_g=no +- CFLAGS="-g" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_prog_cc_g=yes +-else +- CFLAGS="" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- +-else +- ac_c_werror_flag=$ac_save_c_werror_flag +- CFLAGS="-g" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_prog_cc_g=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- ac_c_werror_flag=$ac_save_c_werror_flag +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +-$as_echo "$ac_cv_prog_cc_g" >&6; } +-if test "$ac_test_CFLAGS" = set; then +- CFLAGS=$ac_save_CFLAGS +-elif test $ac_cv_prog_cc_g = yes; then +- if test "$GCC" = yes; then +- CFLAGS="-g -O2" +- else +- CFLAGS="-g" +- fi +-else +- if test "$GCC" = yes; then +- CFLAGS="-O2" +- else +- CFLAGS= +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +-if ${ac_cv_prog_cc_c89+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_cv_prog_cc_c89=no +-ac_save_CC=$CC +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-#include +-struct stat; +-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +-struct buf { int x; }; +-FILE * (*rcsopen) (struct buf *, struct stat *, int); +-static char *e (p, i) +- char **p; +- int i; +-{ +- return p[i]; +-} +-static char *f (char * (*g) (char **, int), char **p, ...) +-{ +- char *s; +- va_list v; +- va_start (v,p); +- s = g (p, va_arg (v,int)); +- va_end (v); +- return s; +-} +- +-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has +- function prototypes and stuff, but not '\xHH' hex character constants. +- These don't provoke an error unfortunately, instead are silently treated +- as 'x'. The following induces an error, until -std is added to get +- proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an +- array size at least. It's necessary to write '\x00'==0 to get something +- that's true only with -std. */ +-int osf4_cc_array ['\x00' == 0 ? 1 : -1]; +- +-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters +- inside strings and character constants. */ +-#define FOO(x) 'x' +-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; +- +-int test (int i, double x); +-struct s1 {int (*f) (int a);}; +-struct s2 {int (*f) (double a);}; +-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +-int argc; +-char **argv; +-int +-main () +-{ +-return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; +- ; +- return 0; +-} +-_ACEOF +-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ +- -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +-do +- CC="$ac_save_CC $ac_arg" +- if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_prog_cc_c89=$ac_arg +-fi +-rm -f core conftest.err conftest.$ac_objext +- test "x$ac_cv_prog_cc_c89" != "xno" && break +-done +-rm -f conftest.$ac_ext +-CC=$ac_save_CC +- +-fi +-# AC_CACHE_VAL +-case "x$ac_cv_prog_cc_c89" in +- x) +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +-$as_echo "none needed" >&6; } ;; +- xno) +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +-$as_echo "unsupported" >&6; } ;; +- *) +- CC="$CC $ac_cv_prog_cc_c89" +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +-esac +-if test "x$ac_cv_prog_cc_c89" != xno; then : +- +-fi +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +-$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +-if ${am_cv_prog_cc_c_o+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +- # Make sure it works both with $CC and with simple cc. +- # Following AC_PROG_CC_C_O, we do the test twice because some +- # compilers refuse to overwrite an existing .o file with -o, +- # though they will create one. +- am_cv_prog_cc_c_o=yes +- for am_i in 1 2; do +- if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 +- ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 +- ac_status=$? +- echo "$as_me:$LINENO: \$? = $ac_status" >&5 +- (exit $ac_status); } \ +- && test -f conftest2.$ac_objext; then +- : OK +- else +- am_cv_prog_cc_c_o=no +- break +- fi +- done +- rm -f core conftest* +- unset am_i +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +-$as_echo "$am_cv_prog_cc_c_o" >&6; } +-if test "$am_cv_prog_cc_c_o" != yes; then +- # Losing compiler, so override with the script. +- # FIXME: It is wrong to rewrite CC. +- # But if we don't then we get into trouble of one sort or another. +- # A longer-term fix would be to have automake use am__CC in this case, +- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" +- CC="$am_aux_dir/compile $CC" +-fi +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +-DEPDIR="${am__leading_dot}deps" +- +-ac_config_commands="$ac_config_commands depfiles" +- +- +-am_make=${MAKE-make} +-cat > confinc << 'END' +-am__doit: +- @echo this is the am__doit target +-.PHONY: am__doit +-END +-# If we don't find an include directive, just comment out the code. +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +-$as_echo_n "checking for style of include used by $am_make... " >&6; } +-am__include="#" +-am__quote= +-_am_result=none +-# First try GNU make style include. +-echo "include confinc" > confmf +-# Ignore all kinds of additional output from 'make'. +-case `$am_make -s -f confmf 2> /dev/null` in #( +-*the\ am__doit\ target*) +- am__include=include +- am__quote= +- _am_result=GNU +- ;; +-esac +-# Now try BSD make style include. +-if test "$am__include" = "#"; then +- echo '.include "confinc"' > confmf +- case `$am_make -s -f confmf 2> /dev/null` in #( +- *the\ am__doit\ target*) +- am__include=.include +- am__quote="\"" +- _am_result=BSD +- ;; +- esac +-fi +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +-$as_echo "$_am_result" >&6; } +-rm -f confinc confmf +- +-# Check whether --enable-dependency-tracking was given. +-if test "${enable_dependency_tracking+set}" = set; then : +- enableval=$enable_dependency_tracking; +-fi +- +-if test "x$enable_dependency_tracking" != xno; then +- am_depcomp="$ac_aux_dir/depcomp" +- AMDEPBACKSLASH='\' +- am__nodep='_no' +-fi +- if test "x$enable_dependency_tracking" != xno; then +- AMDEP_TRUE= +- AMDEP_FALSE='#' +-else +- AMDEP_TRUE='#' +- AMDEP_FALSE= +-fi +- +- +- +-depcc="$CC" am_compiler_list= +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +-$as_echo_n "checking dependency style of $depcc... " >&6; } +-if ${am_cv_CC_dependencies_compiler_type+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then +- # We make a subdir and do the tests there. Otherwise we can end up +- # making bogus files that we don't know about and never remove. For +- # instance it was reported that on HP-UX the gcc test will end up +- # making a dummy file named 'D' -- because '-MD' means "put the output +- # in D". +- rm -rf conftest.dir +- mkdir conftest.dir +- # Copy depcomp to subdir because otherwise we won't find it if we're +- # using a relative directory. +- cp "$am_depcomp" conftest.dir +- cd conftest.dir +- # We will build objects and dependencies in a subdirectory because +- # it helps to detect inapplicable dependency modes. For instance +- # both Tru64's cc and ICC support -MD to output dependencies as a +- # side effect of compilation, but ICC will put the dependencies in +- # the current directory while Tru64 will put them in the object +- # directory. +- mkdir sub +- +- am_cv_CC_dependencies_compiler_type=none +- if test "$am_compiler_list" = ""; then +- am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` +- fi +- am__universal=false +- case " $depcc " in #( +- *\ -arch\ *\ -arch\ *) am__universal=true ;; +- esac +- +- for depmode in $am_compiler_list; do +- # Setup a source with many dependencies, because some compilers +- # like to wrap large dependency lists on column 80 (with \), and +- # we should not choose a depcomp mode which is confused by this. +- # +- # We need to recreate these files for each test, as the compiler may +- # overwrite some of them when testing with obscure command lines. +- # This happens at least with the AIX C compiler. +- : > sub/conftest.c +- for i in 1 2 3 4 5 6; do +- echo '#include "conftst'$i'.h"' >> sub/conftest.c +- # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with +- # Solaris 10 /bin/sh. +- echo '/* dummy */' > sub/conftst$i.h +- done +- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf +- +- # We check with '-c' and '-o' for the sake of the "dashmstdout" +- # mode. It turns out that the SunPro C++ compiler does not properly +- # handle '-M -o', and we need to detect this. Also, some Intel +- # versions had trouble with output in subdirs. +- am__obj=sub/conftest.${OBJEXT-o} +- am__minus_obj="-o $am__obj" +- case $depmode in +- gcc) +- # This depmode causes a compiler race in universal mode. +- test "$am__universal" = false || continue +- ;; +- nosideeffect) +- # After this tag, mechanisms are not by side-effect, so they'll +- # only be used when explicitly requested. +- if test "x$enable_dependency_tracking" = xyes; then +- continue +- else +- break +- fi +- ;; +- msvc7 | msvc7msys | msvisualcpp | msvcmsys) +- # This compiler won't grok '-c -o', but also, the minuso test has +- # not run yet. These depmodes are late enough in the game, and +- # so weak that their functioning should not be impacted. +- am__obj=conftest.${OBJEXT-o} +- am__minus_obj= +- ;; +- none) break ;; +- esac +- if depmode=$depmode \ +- source=sub/conftest.c object=$am__obj \ +- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ +- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ +- >/dev/null 2>conftest.err && +- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && +- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && +- grep $am__obj sub/conftest.Po > /dev/null 2>&1 && +- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then +- # icc doesn't choke on unknown options, it will just issue warnings +- # or remarks (even with -Werror). So we grep stderr for any message +- # that says an option was ignored or not supported. +- # When given -MP, icc 7.0 and 7.1 complain thusly: +- # icc: Command line warning: ignoring option '-M'; no argument required +- # The diagnosis changed in icc 8.0: +- # icc: Command line remark: option '-MP' not supported +- if (grep 'ignoring option' conftest.err || +- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else +- am_cv_CC_dependencies_compiler_type=$depmode +- break +- fi +- fi +- done +- +- cd .. +- rm -rf conftest.dir +-else +- am_cv_CC_dependencies_compiler_type=none +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +-$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +-CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type +- +- if +- test "x$enable_dependency_tracking" != xno \ +- && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then +- am__fastdepCC_TRUE= +- am__fastdepCC_FALSE='#' +-else +- am__fastdepCC_TRUE='#' +- am__fastdepCC_FALSE= +-fi +- +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +-set x ${MAKE-make} +-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +-if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat >conftest.make <<\_ACEOF +-SHELL = /bin/sh +-all: +- @echo '@@@%%%=$(MAKE)=@@@%%%' +-_ACEOF +-# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +-case `${MAKE-make} -f conftest.make 2>/dev/null` in +- *@@@%%%=?*=@@@%%%*) +- eval ac_cv_prog_make_${ac_make}_set=yes;; +- *) +- eval ac_cv_prog_make_${ac_make}_set=no;; +-esac +-rm -f conftest.make +-fi +-if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +- SET_MAKE= +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- SET_MAKE="MAKE=${MAKE-make}" +-fi +- +- +-# For autobuild. +-# Make sure we can run config.sub. +-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || +- as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +-$as_echo_n "checking build system type... " >&6; } +-if ${ac_cv_build+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_build_alias=$build_alias +-test "x$ac_build_alias" = x && +- ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +-test "x$ac_build_alias" = x && +- as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || +- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +-$as_echo "$ac_cv_build" >&6; } +-case $ac_cv_build in +-*-*-*) ;; +-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +-esac +-build=$ac_cv_build +-ac_save_IFS=$IFS; IFS='-' +-set x $ac_cv_build +-shift +-build_cpu=$1 +-build_vendor=$2 +-shift; shift +-# Remember, the first character of IFS is used to create $*, +-# except with old shells: +-build_os=$* +-IFS=$ac_save_IFS +-case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +-$as_echo_n "checking host system type... " >&6; } +-if ${ac_cv_host+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test "x$host_alias" = x; then +- ac_cv_host=$ac_cv_build +-else +- ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || +- as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +-$as_echo "$ac_cv_host" >&6; } +-case $ac_cv_host in +-*-*-*) ;; +-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +-esac +-host=$ac_cv_host +-ac_save_IFS=$IFS; IFS='-' +-set x $ac_cv_host +-shift +-host_cpu=$1 +-host_vendor=$2 +-shift; shift +-# Remember, the first character of IFS is used to create $*, +-# except with old shells: +-host_os=$* +-IFS=$ac_save_IFS +-case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac +- +- +- +- +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +-$as_echo_n "checking how to run the C preprocessor... " >&6; } +-# On Suns, sometimes $CPP names a directory. +-if test -n "$CPP" && test -d "$CPP"; then +- CPP= +-fi +-if test -z "$CPP"; then +- if ${ac_cv_prog_CPP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- # Double quotes because CPP needs to be expanded +- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" +- do +- ac_preproc_ok=false +-for ac_c_preproc_warn_flag in '' yes +-do +- # Use a header file that comes with gcc, so configuring glibc +- # with a fresh cross-compiler works. +- # Prefer to if __STDC__ is defined, since +- # exists even on freestanding compilers. +- # On the NeXT, cc -E runs the code through the compiler's parser, +- # not just through cpp. "Syntax error" is here to catch this case. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#ifdef __STDC__ +-# include +-#else +-# include +-#endif +- Syntax error +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- +-else +- # Broken: fails on valid input. +-continue +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +- # OK, works on sane cases. Now check whether nonexistent headers +- # can be detected and how. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- # Broken: success on invalid input. +-continue +-else +- # Passes both tests. +-ac_preproc_ok=: +-break +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +-done +-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +-rm -f conftest.i conftest.err conftest.$ac_ext +-if $ac_preproc_ok; then : +- break +-fi +- +- done +- ac_cv_prog_CPP=$CPP +- +-fi +- CPP=$ac_cv_prog_CPP +-else +- ac_cv_prog_CPP=$CPP +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +-$as_echo "$CPP" >&6; } +-ac_preproc_ok=false +-for ac_c_preproc_warn_flag in '' yes +-do +- # Use a header file that comes with gcc, so configuring glibc +- # with a fresh cross-compiler works. +- # Prefer to if __STDC__ is defined, since +- # exists even on freestanding compilers. +- # On the NeXT, cc -E runs the code through the compiler's parser, +- # not just through cpp. "Syntax error" is here to catch this case. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#ifdef __STDC__ +-# include +-#else +-# include +-#endif +- Syntax error +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- +-else +- # Broken: fails on valid input. +-continue +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +- # OK, works on sane cases. Now check whether nonexistent headers +- # can be detected and how. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-_ACEOF +-if ac_fn_c_try_cpp "$LINENO"; then : +- # Broken: success on invalid input. +-continue +-else +- # Passes both tests. +-ac_preproc_ok=: +-break +-fi +-rm -f conftest.err conftest.i conftest.$ac_ext +- +-done +-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +-rm -f conftest.i conftest.err conftest.$ac_ext +-if $ac_preproc_ok; then : +- +-else +- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +-See \`config.log' for more details" "$LINENO" 5; } +-fi +- +-ac_ext=c +-ac_cpp='$CPP $CPPFLAGS' +-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +-ac_compiler_gnu=$ac_cv_c_compiler_gnu +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +-$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +-if ${ac_cv_path_GREP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -z "$GREP"; then +- ac_path_GREP_found=false +- # Loop through the user's path and test for each of PROGNAME-LIST +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_prog in grep ggrep; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" +- as_fn_executable_p "$ac_path_GREP" || continue +-# Check for GNU ac_path_GREP and select it if it is found. +- # Check for GNU $ac_path_GREP +-case `"$ac_path_GREP" --version 2>&1` in +-*GNU*) +- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +-*) +- ac_count=0 +- $as_echo_n 0123456789 >"conftest.in" +- while : +- do +- cat "conftest.in" "conftest.in" >"conftest.tmp" +- mv "conftest.tmp" "conftest.in" +- cp "conftest.in" "conftest.nl" +- $as_echo 'GREP' >> "conftest.nl" +- "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break +- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break +- as_fn_arith $ac_count + 1 && ac_count=$as_val +- if test $ac_count -gt ${ac_path_GREP_max-0}; then +- # Best one so far, save it but keep looking for a better one +- ac_cv_path_GREP="$ac_path_GREP" +- ac_path_GREP_max=$ac_count +- fi +- # 10*(2^10) chars as input seems more than enough +- test $ac_count -gt 10 && break +- done +- rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +-esac +- +- $ac_path_GREP_found && break 3 +- done +- done +- done +-IFS=$as_save_IFS +- if test -z "$ac_cv_path_GREP"; then +- as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 +- fi +-else +- ac_cv_path_GREP=$GREP +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +-$as_echo "$ac_cv_path_GREP" >&6; } +- GREP="$ac_cv_path_GREP" +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +-$as_echo_n "checking for egrep... " >&6; } +-if ${ac_cv_path_EGREP+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 +- then ac_cv_path_EGREP="$GREP -E" +- else +- if test -z "$EGREP"; then +- ac_path_EGREP_found=false +- # Loop through the user's path and test for each of PROGNAME-LIST +- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_prog in egrep; do +- for ac_exec_ext in '' $ac_executable_extensions; do +- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" +- as_fn_executable_p "$ac_path_EGREP" || continue +-# Check for GNU ac_path_EGREP and select it if it is found. +- # Check for GNU $ac_path_EGREP +-case `"$ac_path_EGREP" --version 2>&1` in +-*GNU*) +- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +-*) +- ac_count=0 +- $as_echo_n 0123456789 >"conftest.in" +- while : +- do +- cat "conftest.in" "conftest.in" >"conftest.tmp" +- mv "conftest.tmp" "conftest.in" +- cp "conftest.in" "conftest.nl" +- $as_echo 'EGREP' >> "conftest.nl" +- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break +- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break +- as_fn_arith $ac_count + 1 && ac_count=$as_val +- if test $ac_count -gt ${ac_path_EGREP_max-0}; then +- # Best one so far, save it but keep looking for a better one +- ac_cv_path_EGREP="$ac_path_EGREP" +- ac_path_EGREP_max=$ac_count +- fi +- # 10*(2^10) chars as input seems more than enough +- test $ac_count -gt 10 && break +- done +- rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +-esac +- +- $ac_path_EGREP_found && break 3 +- done +- done +- done +-IFS=$as_save_IFS +- if test -z "$ac_cv_path_EGREP"; then +- as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 +- fi +-else +- ac_cv_path_EGREP=$EGREP +-fi +- +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +-$as_echo "$ac_cv_path_EGREP" >&6; } +- EGREP="$ac_cv_path_EGREP" +- +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Minix Amsterdam compiler" >&5 +-$as_echo_n "checking for Minix Amsterdam compiler... " >&6; } +-if ${gl_cv_c_amsterdam_compiler+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef __ACK__ +-Amsterdam +-#endif +- +-_ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "Amsterdam" >/dev/null 2>&1; then : +- gl_cv_c_amsterdam_compiler=yes +-else +- gl_cv_c_amsterdam_compiler=no +-fi +-rm -f conftest* +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_c_amsterdam_compiler" >&5 +-$as_echo "$gl_cv_c_amsterdam_compiler" >&6; } +- if test -z "$AR"; then +- if test $gl_cv_c_amsterdam_compiler = yes; then +- AR='cc -c.a' +- if test -z "$ARFLAGS"; then +- ARFLAGS='-o' +- fi +- else +- if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +-set dummy ${ac_tool_prefix}ar; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_AR+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$AR"; then +- ac_cv_prog_AR="$AR" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_AR="${ac_tool_prefix}ar" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-AR=$ac_cv_prog_AR +-if test -n "$AR"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +-$as_echo "$AR" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$ac_cv_prog_AR"; then +- ac_ct_AR=$AR +- # Extract the first word of "ar", so it can be a program name with args. +-set dummy ar; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_AR+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_AR"; then +- ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_AR="ar" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_AR=$ac_cv_prog_ac_ct_AR +-if test -n "$ac_ct_AR"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +-$as_echo "$ac_ct_AR" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- if test "x$ac_ct_AR" = x; then +- AR="ar" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- AR=$ac_ct_AR +- fi +-else +- AR="$ac_cv_prog_AR" +-fi +- +- if test -z "$ARFLAGS"; then +- ARFLAGS='cru' +- fi +- fi +- else +- if test -z "$ARFLAGS"; then +- ARFLAGS='cru' +- fi +- fi +- +- +- if test -z "$RANLIB"; then +- if test $gl_cv_c_amsterdam_compiler = yes; then +- RANLIB=':' +- else +- if test -n "$ac_tool_prefix"; then +- # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +-set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_RANLIB+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$RANLIB"; then +- ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-RANLIB=$ac_cv_prog_RANLIB +-if test -n "$RANLIB"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +-$as_echo "$RANLIB" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- +-fi +-if test -z "$ac_cv_prog_RANLIB"; then +- ac_ct_RANLIB=$RANLIB +- # Extract the first word of "ranlib", so it can be a program name with args. +-set dummy ranlib; ac_word=$2 +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +-$as_echo_n "checking for $ac_word... " >&6; } +-if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test -n "$ac_ct_RANLIB"; then +- ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +-else +-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- for ac_exec_ext in '' $ac_executable_extensions; do +- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then +- ac_cv_prog_ac_ct_RANLIB="ranlib" +- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 +- break 2 +- fi +-done +- done +-IFS=$as_save_IFS +- +-fi +-fi +-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +-if test -n "$ac_ct_RANLIB"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +-$as_echo "$ac_ct_RANLIB" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +-fi +- +- if test "x$ac_ct_RANLIB" = x; then +- RANLIB=":" +- else +- case $cross_compiling:$ac_tool_warned in +-yes:) +-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +-ac_tool_warned=yes ;; +-esac +- RANLIB=$ac_ct_RANLIB +- fi +-else +- RANLIB="$ac_cv_prog_RANLIB" +-fi +- +- fi +- fi +- +- +- +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +-$as_echo_n "checking for ANSI C header files... " >&6; } +-if ${ac_cv_header_stdc+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-#include +-#include +-#include +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_header_stdc=yes +-else +- ac_cv_header_stdc=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-if test $ac_cv_header_stdc = yes; then +- # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-_ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "memchr" >/dev/null 2>&1; then : +- +-else +- ac_cv_header_stdc=no +-fi +-rm -f conftest* +- +-fi +- +-if test $ac_cv_header_stdc = yes; then +- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-_ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "free" >/dev/null 2>&1; then : +- +-else +- ac_cv_header_stdc=no +-fi +-rm -f conftest* +- +-fi +- +-if test $ac_cv_header_stdc = yes; then +- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +- if test "$cross_compiling" = yes; then : +- : +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-#include +-#if ((' ' & 0x0FF) == 0x020) +-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +-#else +-# define ISLOWER(c) \ +- (('a' <= (c) && (c) <= 'i') \ +- || ('j' <= (c) && (c) <= 'r') \ +- || ('s' <= (c) && (c) <= 'z')) +-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +-#endif +- +-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +-int +-main () +-{ +- int i; +- for (i = 0; i < 256; i++) +- if (XOR (islower (i), ISLOWER (i)) +- || toupper (i) != TOUPPER (i)) +- return 2; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- +-else +- ac_cv_header_stdc=no +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +-fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +-$as_echo "$ac_cv_header_stdc" >&6; } +-if test $ac_cv_header_stdc = yes; then +- +-$as_echo "#define STDC_HEADERS 1" >>confdefs.h +- +-fi +- +-# On IRIX 5.3, sys/types and inttypes.h are conflicting. +-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ +- inttypes.h stdint.h unistd.h +-do : +- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +-" +-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +-_ACEOF +- +-fi +- +-done +- +- +- +- ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +-if test "x$ac_cv_header_minix_config_h" = xyes; then : +- MINIX=yes +-else +- MINIX= +-fi +- +- +- if test "$MINIX" = yes; then +- +-$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h +- +- +-$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h +- +- +-$as_echo "#define _MINIX 1" >>confdefs.h +- +- +-$as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h +- +- fi +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +-$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +-if ${ac_cv_safe_to_define___extensions__+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-# define __EXTENSIONS__ 1 +- $ac_includes_default +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_safe_to_define___extensions__=yes +-else +- ac_cv_safe_to_define___extensions__=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +-$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } +- test $ac_cv_safe_to_define___extensions__ = yes && +- $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h +- +- $as_echo "#define _ALL_SOURCE 1" >>confdefs.h +- +- $as_echo "#define _DARWIN_C_SOURCE 1" >>confdefs.h +- +- $as_echo "#define _GNU_SOURCE 1" >>confdefs.h +- +- $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h +- +- $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5 +-$as_echo_n "checking whether _XOPEN_SOURCE should be defined... " >&6; } +-if ${ac_cv_should_define__xopen_source+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_cv_should_define__xopen_source=no +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- #include +- mbstate_t x; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- #define _XOPEN_SOURCE 500 +- #include +- mbstate_t x; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_should_define__xopen_source=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5 +-$as_echo "$ac_cv_should_define__xopen_source" >&6; } +- test $ac_cv_should_define__xopen_source = yes && +- $as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h +- +- +- +- +- +- +- +- +- if false; then +- GL_COND_LIBTOOL_TRUE= +- GL_COND_LIBTOOL_FALSE='#' +-else +- GL_COND_LIBTOOL_TRUE='#' +- GL_COND_LIBTOOL_FALSE= +-fi +- +-gl_cond_libtool=false +-gl_libdeps= +-gl_ltlibdeps= +- +- +-# Like AC_LIBOBJ, except that the module name goes +-# into gl_LIBOBJS instead of into LIBOBJS. +- +- +-# Like AC_REPLACE_FUNCS, except that the module name goes +-# into gl_LIBOBJS instead of into LIBOBJS. +- +- +-# Like AC_LIBSOURCES, except the directory where the source file is +-# expected is derived from the gnulib-tool parameterization, +-# and alloca is special cased (for the alloca-opt module). +-# We could also entirely rely on EXTRA_lib..._SOURCES. +- +- +- +- +- +- +- +- LIBC_FATAL_STDERR_=1 +- export LIBC_FATAL_STDERR_ +- +- +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 +-$as_echo_n "checking for unsigned long long int... " >&6; } +-if ${ac_cv_type_unsigned_long_long_int+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_cv_type_unsigned_long_long_int=yes +- if test "x${ac_cv_prog_cc_c99-no}" = xno; then +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- /* For now, do not test the preprocessor; as of 2007 there are too many +- implementations with broken preprocessors. Perhaps this can +- be revisited in 2012. In the meantime, code should not expect +- #if to work with literals wider than 32 bits. */ +- /* Test literals. */ +- long long int ll = 9223372036854775807ll; +- long long int nll = -9223372036854775807LL; +- unsigned long long int ull = 18446744073709551615ULL; +- /* Test constant expressions. */ +- typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) +- ? 1 : -1)]; +- typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 +- ? 1 : -1)]; +- int i = 63; +-int +-main () +-{ +-/* Test availability of runtime routines for shift and division. */ +- long long int llmax = 9223372036854775807ll; +- unsigned long long int ullmax = 18446744073709551615ull; +- return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) +- | (llmax / ll) | (llmax % ll) +- | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) +- | (ullmax / ull) | (ullmax % ull)); +- ; +- return 0; +-} +- +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- +-else +- ac_cv_type_unsigned_long_long_int=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5 +-$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; } +- if test $ac_cv_type_unsigned_long_long_int = yes; then +- +-$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h +- +- fi +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 +-$as_echo_n "checking for long long int... " >&6; } +-if ${ac_cv_type_long_long_int+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- ac_cv_type_long_long_int=yes +- if test "x${ac_cv_prog_cc_c99-no}" = xno; then +- ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int +- if test $ac_cv_type_long_long_int = yes; then +- if test "$cross_compiling" = yes; then : +- : +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- #ifndef LLONG_MAX +- # define HALF \ +- (1LL << (sizeof (long long int) * CHAR_BIT - 2)) +- # define LLONG_MAX (HALF - 1 + HALF) +- #endif +-int +-main () +-{ +-long long int n = 1; +- int i; +- for (i = 0; ; i++) +- { +- long long int m = n << i; +- if (m >> i != n) +- return 1; +- if (LLONG_MAX / 2 < m) +- break; +- } +- return 0; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- +-else +- ac_cv_type_long_long_int=no +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- fi +- fi +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 +-$as_echo "$ac_cv_type_long_long_int" >&6; } +- if test $ac_cv_type_long_long_int = yes; then +- +-$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h +- +- fi +- +- +- +- +- +- for ac_header in $gl_header_list +-do : +- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +-_ACEOF +- +-fi +- +-done +- +- +- +- +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the preprocessor supports include_next" >&5 +-$as_echo_n "checking whether the preprocessor supports include_next... " >&6; } +-if ${gl_cv_have_include_next+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- rm -rf conftestd1a conftestd1b conftestd2 +- mkdir conftestd1a conftestd1b conftestd2 +- cat < conftestd1a/conftest.h +-#define DEFINED_IN_CONFTESTD1 +-#include_next +-#ifdef DEFINED_IN_CONFTESTD2 +-int foo; +-#else +-#error "include_next doesn't work" +-#endif +-EOF +- cat < conftestd1b/conftest.h +-#define DEFINED_IN_CONFTESTD1 +-#include +-#include_next +-#ifdef DEFINED_IN_CONFTESTD2 +-int foo; +-#else +-#error "include_next doesn't work" +-#endif +-EOF +- cat < conftestd2/conftest.h +-#ifndef DEFINED_IN_CONFTESTD1 +-#error "include_next test doesn't work" +-#endif +-#define DEFINED_IN_CONFTESTD2 +-EOF +- gl_save_CPPFLAGS="$CPPFLAGS" +- CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_have_include_next=yes +-else +- CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2" +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_have_include_next=buggy +-else +- gl_cv_have_include_next=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- CPPFLAGS="$gl_save_CPPFLAGS" +- rm -rf conftestd1a conftestd1b conftestd2 +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_have_include_next" >&5 +-$as_echo "$gl_cv_have_include_next" >&6; } +- PRAGMA_SYSTEM_HEADER= +- if test $gl_cv_have_include_next = yes; then +- INCLUDE_NEXT=include_next +- INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next +- if test -n "$GCC"; then +- PRAGMA_SYSTEM_HEADER='#pragma GCC system_header' +- fi +- else +- if test $gl_cv_have_include_next = buggy; then +- INCLUDE_NEXT=include +- INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next +- else +- INCLUDE_NEXT=include +- INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include +- fi +- fi +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system header files limit the line length" >&5 +-$as_echo_n "checking whether system header files limit the line length... " >&6; } +-if ${gl_cv_pragma_columns+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#ifdef __TANDEM +-choke me +-#endif +- +-_ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "choke me" >/dev/null 2>&1; then : +- gl_cv_pragma_columns=yes +-else +- gl_cv_pragma_columns=no +-fi +-rm -f conftest* +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_pragma_columns" >&5 +-$as_echo "$gl_cv_pragma_columns" >&6; } +- if test $gl_cv_pragma_columns = yes; then +- PRAGMA_COLUMNS="#pragma COLUMNS 10000" +- else +- PRAGMA_COLUMNS= +- fi +- +- +- +- +- +- +- +- +- gl_cv_c_multiarch=no +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#ifndef __APPLE_CC__ +- not a universal capable compiler +- #endif +- typedef int dummy; +- +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- +- arch= +- prev= +- for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do +- if test -n "$prev"; then +- case $word in +- i?86 | x86_64 | ppc | ppc64) +- if test -z "$arch" || test "$arch" = "$word"; then +- arch="$word" +- else +- gl_cv_c_multiarch=yes +- fi +- ;; +- esac +- prev= +- else +- if test "x$word" = "x-arch"; then +- prev=arch +- fi +- fi +- done +- +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- if test $gl_cv_c_multiarch = yes; then +- APPLE_UNIVERSAL_BUILD=1 +- else +- APPLE_UNIVERSAL_BUILD=0 +- fi +- +- +- +- +- +- if test $ac_cv_type_long_long_int = yes; then +- HAVE_LONG_LONG_INT=1 +- else +- HAVE_LONG_LONG_INT=0 +- fi +- +- +- if test $ac_cv_type_unsigned_long_long_int = yes; then +- HAVE_UNSIGNED_LONG_LONG_INT=1 +- else +- HAVE_UNSIGNED_LONG_LONG_INT=0 +- fi +- +- +- +- : +- +- +- +- +- +- if test $ac_cv_header_wchar_h = yes; then +- HAVE_WCHAR_H=1 +- else +- HAVE_WCHAR_H=0 +- fi +- +- +- if test $ac_cv_header_inttypes_h = yes; then +- HAVE_INTTYPES_H=1 +- else +- HAVE_INTTYPES_H=0 +- fi +- +- +- if test $ac_cv_header_sys_types_h = yes; then +- HAVE_SYS_TYPES_H=1 +- else +- HAVE_SYS_TYPES_H=0 +- fi +- +- +- +- +- +- +- +- +- : +- +- +- +- +- +- +- +- +- if test $gl_cv_have_include_next = yes; then +- gl_cv_next_stdint_h='<'stdint.h'>' +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of " >&5 +-$as_echo_n "checking absolute name of ... " >&6; } +-if ${gl_cv_next_stdint_h+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- if test $ac_cv_header_stdint_h = yes; then +- +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-_ACEOF +- case "$host_os" in +- aix*) gl_absname_cpp="$ac_cpp -C" ;; +- *) gl_absname_cpp="$ac_cpp" ;; +- esac +- +- case "$host_os" in +- mingw*) +- gl_dirsep_regex='[/\\]' +- ;; +- *) +- gl_dirsep_regex='\/' +- ;; +- esac +- gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' +- +- gl_header_literal_regex=`echo 'stdint.h' \ +- | sed -e "$gl_make_literal_regex_sed"` +- gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ +- s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ +- s|^/[^/]|//&| +- p +- q +- }' +- gl_cv_next_stdint_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 | +- sed -n "$gl_absolute_header_sed"`'"' +- else +- gl_cv_next_stdint_h='<'stdint.h'>' +- fi +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_stdint_h" >&5 +-$as_echo "$gl_cv_next_stdint_h" >&6; } +- fi +- NEXT_STDINT_H=$gl_cv_next_stdint_h +- +- if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' +- gl_next_as_first_directive='<'stdint.h'>' +- else +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' +- gl_next_as_first_directive=$gl_cv_next_stdint_h +- fi +- NEXT_AS_FIRST_DIRECTIVE_STDINT_H=$gl_next_as_first_directive +- +- +- +- +- if test $ac_cv_header_stdint_h = yes; then +- HAVE_STDINT_H=1 +- else +- HAVE_STDINT_H=0 +- fi +- +- +- if test $ac_cv_header_stdint_h = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stdint.h conforms to C99" >&5 +-$as_echo_n "checking whether stdint.h conforms to C99... " >&6; } +-if ${gl_cv_header_working_stdint_h+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- gl_cv_header_working_stdint_h=no +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +-#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +-#include +-/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in . */ +-#if !(defined WCHAR_MIN && defined WCHAR_MAX) +-#error "WCHAR_MIN, WCHAR_MAX not defined in " +-#endif +- +- +- /* BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +- #include +- #include +- #if HAVE_WCHAR_H +- # include +- # include +- # include +- #endif +- +- +-#ifdef INT8_MAX +-int8_t a1 = INT8_MAX; +-int8_t a1min = INT8_MIN; +-#endif +-#ifdef INT16_MAX +-int16_t a2 = INT16_MAX; +-int16_t a2min = INT16_MIN; +-#endif +-#ifdef INT32_MAX +-int32_t a3 = INT32_MAX; +-int32_t a3min = INT32_MIN; +-#endif +-#ifdef INT64_MAX +-int64_t a4 = INT64_MAX; +-int64_t a4min = INT64_MIN; +-#endif +-#ifdef UINT8_MAX +-uint8_t b1 = UINT8_MAX; +-#else +-typedef int b1[(unsigned char) -1 != 255 ? 1 : -1]; +-#endif +-#ifdef UINT16_MAX +-uint16_t b2 = UINT16_MAX; +-#endif +-#ifdef UINT32_MAX +-uint32_t b3 = UINT32_MAX; +-#endif +-#ifdef UINT64_MAX +-uint64_t b4 = UINT64_MAX; +-#endif +-int_least8_t c1 = INT8_C (0x7f); +-int_least8_t c1max = INT_LEAST8_MAX; +-int_least8_t c1min = INT_LEAST8_MIN; +-int_least16_t c2 = INT16_C (0x7fff); +-int_least16_t c2max = INT_LEAST16_MAX; +-int_least16_t c2min = INT_LEAST16_MIN; +-int_least32_t c3 = INT32_C (0x7fffffff); +-int_least32_t c3max = INT_LEAST32_MAX; +-int_least32_t c3min = INT_LEAST32_MIN; +-int_least64_t c4 = INT64_C (0x7fffffffffffffff); +-int_least64_t c4max = INT_LEAST64_MAX; +-int_least64_t c4min = INT_LEAST64_MIN; +-uint_least8_t d1 = UINT8_C (0xff); +-uint_least8_t d1max = UINT_LEAST8_MAX; +-uint_least16_t d2 = UINT16_C (0xffff); +-uint_least16_t d2max = UINT_LEAST16_MAX; +-uint_least32_t d3 = UINT32_C (0xffffffff); +-uint_least32_t d3max = UINT_LEAST32_MAX; +-uint_least64_t d4 = UINT64_C (0xffffffffffffffff); +-uint_least64_t d4max = UINT_LEAST64_MAX; +-int_fast8_t e1 = INT_FAST8_MAX; +-int_fast8_t e1min = INT_FAST8_MIN; +-int_fast16_t e2 = INT_FAST16_MAX; +-int_fast16_t e2min = INT_FAST16_MIN; +-int_fast32_t e3 = INT_FAST32_MAX; +-int_fast32_t e3min = INT_FAST32_MIN; +-int_fast64_t e4 = INT_FAST64_MAX; +-int_fast64_t e4min = INT_FAST64_MIN; +-uint_fast8_t f1 = UINT_FAST8_MAX; +-uint_fast16_t f2 = UINT_FAST16_MAX; +-uint_fast32_t f3 = UINT_FAST32_MAX; +-uint_fast64_t f4 = UINT_FAST64_MAX; +-#ifdef INTPTR_MAX +-intptr_t g = INTPTR_MAX; +-intptr_t gmin = INTPTR_MIN; +-#endif +-#ifdef UINTPTR_MAX +-uintptr_t h = UINTPTR_MAX; +-#endif +-intmax_t i = INTMAX_MAX; +-uintmax_t j = UINTMAX_MAX; +- +-#include /* for CHAR_BIT */ +-#define TYPE_MINIMUM(t) \ +- ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t))) +-#define TYPE_MAXIMUM(t) \ +- ((t) ((t) 0 < (t) -1 \ +- ? (t) -1 \ +- : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) +-struct s { +- int check_PTRDIFF: +- PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t) +- && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t) +- ? 1 : -1; +- /* Detect bug in FreeBSD 6.0 / ia64. */ +- int check_SIG_ATOMIC: +- SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t) +- && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t) +- ? 1 : -1; +- int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1; +- int check_WCHAR: +- WCHAR_MIN == TYPE_MINIMUM (wchar_t) +- && WCHAR_MAX == TYPE_MAXIMUM (wchar_t) +- ? 1 : -1; +- /* Detect bug in mingw. */ +- int check_WINT: +- WINT_MIN == TYPE_MINIMUM (wint_t) +- && WINT_MAX == TYPE_MAXIMUM (wint_t) +- ? 1 : -1; +- +- /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */ +- int check_UINT8_C: +- (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1; +- int check_UINT16_C: +- (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1; +- +- /* Detect bugs in OpenBSD 3.9 stdint.h. */ +-#ifdef UINT8_MAX +- int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1; +-#endif +-#ifdef UINT16_MAX +- int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1; +-#endif +-#ifdef UINT32_MAX +- int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1; +-#endif +-#ifdef UINT64_MAX +- int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1; +-#endif +- int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1; +- int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1; +- int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1; +- int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1; +- int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1; +- int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1; +- int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1; +- int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1; +- int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1; +- int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1; +- int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1; +-}; +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- if test "$cross_compiling" = yes; then : +- gl_cv_header_working_stdint_h=yes +- +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- +-#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +-#include +- +- +- /* BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +- #include +- #include +- #if HAVE_WCHAR_H +- # include +- # include +- # include +- #endif +- +- +-#include +-#include +-#define MVAL(macro) MVAL1(macro) +-#define MVAL1(expression) #expression +-static const char *macro_values[] = +- { +-#ifdef INT8_MAX +- MVAL (INT8_MAX), +-#endif +-#ifdef INT16_MAX +- MVAL (INT16_MAX), +-#endif +-#ifdef INT32_MAX +- MVAL (INT32_MAX), +-#endif +-#ifdef INT64_MAX +- MVAL (INT64_MAX), +-#endif +-#ifdef UINT8_MAX +- MVAL (UINT8_MAX), +-#endif +-#ifdef UINT16_MAX +- MVAL (UINT16_MAX), +-#endif +-#ifdef UINT32_MAX +- MVAL (UINT32_MAX), +-#endif +-#ifdef UINT64_MAX +- MVAL (UINT64_MAX), +-#endif +- NULL +- }; +- +-int +-main () +-{ +- +- const char **mv; +- for (mv = macro_values; *mv != NULL; mv++) +- { +- const char *value = *mv; +- /* Test whether it looks like a cast expression. */ +- if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0 +- || strncmp (value, "((unsigned short)"/*)*/, 17) == 0 +- || strncmp (value, "((unsigned char)"/*)*/, 16) == 0 +- || strncmp (value, "((int)"/*)*/, 6) == 0 +- || strncmp (value, "((signed short)"/*)*/, 15) == 0 +- || strncmp (value, "((signed char)"/*)*/, 14) == 0) +- return mv - macro_values + 1; +- } +- return 0; +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- gl_cv_header_working_stdint_h=yes +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_stdint_h" >&5 +-$as_echo "$gl_cv_header_working_stdint_h" >&6; } +- fi +- if test "$gl_cv_header_working_stdint_h" = yes; then +- STDINT_H= +- else +- for ac_header in sys/inttypes.h sys/bitypes.h +-do : +- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +-_ACEOF +- +-fi +- +-done +- +- if test $ac_cv_header_sys_inttypes_h = yes; then +- HAVE_SYS_INTTYPES_H=1 +- else +- HAVE_SYS_INTTYPES_H=0 +- fi +- +- if test $ac_cv_header_sys_bitypes_h = yes; then +- HAVE_SYS_BITYPES_H=1 +- else +- HAVE_SYS_BITYPES_H=0 +- fi +- +- +- +- +- if test $APPLE_UNIVERSAL_BUILD = 0; then +- +- +- for gltype in ptrdiff_t size_t ; do +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bit size of $gltype" >&5 +-$as_echo_n "checking for bit size of $gltype... " >&6; } +-if eval \${gl_cv_bitsizeof_${gltype}+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if ac_fn_c_compute_int "$LINENO" "sizeof ($gltype) * CHAR_BIT" "result" " +- /* BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +- #include +- #include +- #if HAVE_WCHAR_H +- # include +- # include +- # include +- #endif +- +-#include "; then : +- +-else +- result=unknown +-fi +- +- eval gl_cv_bitsizeof_${gltype}=\$result +- +-fi +-eval ac_res=\$gl_cv_bitsizeof_${gltype} +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval result=\$gl_cv_bitsizeof_${gltype} +- if test $result = unknown; then +- result=0 +- fi +- GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` +- cat >>confdefs.h <<_ACEOF +-#define BITSIZEOF_${GLTYPE} $result +-_ACEOF +- +- eval BITSIZEOF_${GLTYPE}=\$result +- done +- +- +- fi +- +- +- for gltype in sig_atomic_t wchar_t wint_t ; do +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bit size of $gltype" >&5 +-$as_echo_n "checking for bit size of $gltype... " >&6; } +-if eval \${gl_cv_bitsizeof_${gltype}+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if ac_fn_c_compute_int "$LINENO" "sizeof ($gltype) * CHAR_BIT" "result" " +- /* BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +- #include +- #include +- #if HAVE_WCHAR_H +- # include +- # include +- # include +- #endif +- +-#include "; then : +- +-else +- result=unknown +-fi +- +- eval gl_cv_bitsizeof_${gltype}=\$result +- +-fi +-eval ac_res=\$gl_cv_bitsizeof_${gltype} +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval result=\$gl_cv_bitsizeof_${gltype} +- if test $result = unknown; then +- result=0 +- fi +- GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` +- cat >>confdefs.h <<_ACEOF +-#define BITSIZEOF_${GLTYPE} $result +-_ACEOF +- +- eval BITSIZEOF_${GLTYPE}=\$result +- done +- +- +- +- +- for gltype in sig_atomic_t wchar_t wint_t ; do +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gltype is signed" >&5 +-$as_echo_n "checking whether $gltype is signed... " >&6; } +-if eval \${gl_cv_type_${gltype}_signed+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- /* BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +- #include +- #include +- #if HAVE_WCHAR_H +- # include +- # include +- # include +- #endif +- +- int verify[2 * (($gltype) -1 < ($gltype) 0) - 1]; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- result=yes +-else +- result=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- eval gl_cv_type_${gltype}_signed=\$result +- +-fi +-eval ac_res=\$gl_cv_type_${gltype}_signed +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval result=\$gl_cv_type_${gltype}_signed +- GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` +- if test "$result" = yes; then +- cat >>confdefs.h <<_ACEOF +-#define HAVE_SIGNED_${GLTYPE} 1 +-_ACEOF +- +- eval HAVE_SIGNED_${GLTYPE}=1 +- else +- eval HAVE_SIGNED_${GLTYPE}=0 +- fi +- done +- +- +- gl_cv_type_ptrdiff_t_signed=yes +- gl_cv_type_size_t_signed=no +- if test $APPLE_UNIVERSAL_BUILD = 0; then +- +- +- for gltype in ptrdiff_t size_t ; do +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $gltype integer literal suffix" >&5 +-$as_echo_n "checking for $gltype integer literal suffix... " >&6; } +-if eval \${gl_cv_type_${gltype}_suffix+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- eval gl_cv_type_${gltype}_suffix=no +- eval result=\$gl_cv_type_${gltype}_signed +- if test "$result" = yes; then +- glsufu= +- else +- glsufu=u +- fi +- for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do +- case $glsuf in +- '') gltype1='int';; +- l) gltype1='long int';; +- ll) gltype1='long long int';; +- i64) gltype1='__int64';; +- u) gltype1='unsigned int';; +- ul) gltype1='unsigned long int';; +- ull) gltype1='unsigned long long int';; +- ui64)gltype1='unsigned __int64';; +- esac +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- /* BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +- #include +- #include +- #if HAVE_WCHAR_H +- # include +- # include +- # include +- #endif +- +- extern $gltype foo; +- extern $gltype1 foo; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval gl_cv_type_${gltype}_suffix=\$glsuf +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- eval result=\$gl_cv_type_${gltype}_suffix +- test "$result" != no && break +- done +-fi +-eval ac_res=\$gl_cv_type_${gltype}_suffix +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` +- eval result=\$gl_cv_type_${gltype}_suffix +- test "$result" = no && result= +- eval ${GLTYPE}_SUFFIX=\$result +- cat >>confdefs.h <<_ACEOF +-#define ${GLTYPE}_SUFFIX $result +-_ACEOF +- +- done +- +- +- fi +- +- +- for gltype in sig_atomic_t wchar_t wint_t ; do +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $gltype integer literal suffix" >&5 +-$as_echo_n "checking for $gltype integer literal suffix... " >&6; } +-if eval \${gl_cv_type_${gltype}_suffix+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- eval gl_cv_type_${gltype}_suffix=no +- eval result=\$gl_cv_type_${gltype}_signed +- if test "$result" = yes; then +- glsufu= +- else +- glsufu=u +- fi +- for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do +- case $glsuf in +- '') gltype1='int';; +- l) gltype1='long int';; +- ll) gltype1='long long int';; +- i64) gltype1='__int64';; +- u) gltype1='unsigned int';; +- ul) gltype1='unsigned long int';; +- ull) gltype1='unsigned long long int';; +- ui64)gltype1='unsigned __int64';; +- esac +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- /* BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +- #include +- #include +- #if HAVE_WCHAR_H +- # include +- # include +- # include +- #endif +- +- extern $gltype foo; +- extern $gltype1 foo; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval gl_cv_type_${gltype}_suffix=\$glsuf +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- eval result=\$gl_cv_type_${gltype}_suffix +- test "$result" != no && break +- done +-fi +-eval ac_res=\$gl_cv_type_${gltype}_suffix +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` +- eval result=\$gl_cv_type_${gltype}_suffix +- test "$result" = no && result= +- eval ${GLTYPE}_SUFFIX=\$result +- cat >>confdefs.h <<_ACEOF +-#define ${GLTYPE}_SUFFIX $result +-_ACEOF +- +- done +- +- +- +- if test $BITSIZEOF_WINT_T -lt 32; then +- BITSIZEOF_WINT_T=32 +- fi +- +- STDINT_H=stdint.h +- fi +- +- if test -n "$STDINT_H"; then +- GL_GENERATE_STDINT_H_TRUE= +- GL_GENERATE_STDINT_H_FALSE='#' +-else +- GL_GENERATE_STDINT_H_TRUE='#' +- GL_GENERATE_STDINT_H_FALSE= +-fi +- +- +- +- +- +- +- +- +- GNULIB_IMAXABS=0; +- GNULIB_IMAXDIV=0; +- GNULIB_STRTOIMAX=0; +- GNULIB_STRTOUMAX=0; +- HAVE_DECL_IMAXABS=1; +- HAVE_DECL_IMAXDIV=1; +- HAVE_DECL_STRTOIMAX=1; +- HAVE_DECL_STRTOUMAX=1; +- REPLACE_STRTOIMAX=0; +- INT32_MAX_LT_INTMAX_MAX=1; +- INT64_MAX_EQ_LONG_MAX='defined _LP64'; +- PRI_MACROS_BROKEN=0; +- PRIPTR_PREFIX=__PRIPTR_PREFIX; +- UINT32_MAX_LT_UINTMAX_MAX=1; +- UINT64_MAX_EQ_ULONG_MAX='defined _LP64'; +- +- +- +- +- : +- +- +- +- +- +- +- +- +- +- +- +- +- +- : +- +- +- +- +- +- +- +- +- if test $gl_cv_have_include_next = yes; then +- gl_cv_next_inttypes_h='<'inttypes.h'>' +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of " >&5 +-$as_echo_n "checking absolute name of ... " >&6; } +-if ${gl_cv_next_inttypes_h+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- if test $ac_cv_header_inttypes_h = yes; then +- +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-_ACEOF +- case "$host_os" in +- aix*) gl_absname_cpp="$ac_cpp -C" ;; +- *) gl_absname_cpp="$ac_cpp" ;; +- esac +- +- case "$host_os" in +- mingw*) +- gl_dirsep_regex='[/\\]' +- ;; +- *) +- gl_dirsep_regex='\/' +- ;; +- esac +- gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' +- +- gl_header_literal_regex=`echo 'inttypes.h' \ +- | sed -e "$gl_make_literal_regex_sed"` +- gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ +- s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ +- s|^/[^/]|//&| +- p +- q +- }' +- gl_cv_next_inttypes_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 | +- sed -n "$gl_absolute_header_sed"`'"' +- else +- gl_cv_next_inttypes_h='<'inttypes.h'>' +- fi +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_inttypes_h" >&5 +-$as_echo "$gl_cv_next_inttypes_h" >&6; } +- fi +- NEXT_INTTYPES_H=$gl_cv_next_inttypes_h +- +- if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' +- gl_next_as_first_directive='<'inttypes.h'>' +- else +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' +- gl_next_as_first_directive=$gl_cv_next_inttypes_h +- fi +- NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H=$gl_next_as_first_directive +- +- +- +- +- +- +- +- +- for gl_func in imaxabs imaxdiv strtoimax strtoumax; do +- as_gl_Symbol=`$as_echo "gl_cv_have_raw_decl_$gl_func" | $as_tr_sh` +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gl_func is declared without a macro" >&5 +-$as_echo_n "checking whether $gl_func is declared without a macro... " >&6; } +-if eval \${$as_gl_Symbol+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-int +-main () +-{ +-#undef $gl_func +- (void) $gl_func; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval "$as_gl_Symbol=yes" +-else +- eval "$as_gl_Symbol=no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$as_gl_Symbol +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- if eval test \"x\$"$as_gl_Symbol"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_RAW_DECL_$gl_func" | $as_tr_cpp` 1 +-_ACEOF +- +- eval ac_cv_have_decl_$gl_func=yes +-fi +- done +- +- +- +- for ac_header in inttypes.h +-do : +- ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" +-if test "x$ac_cv_header_inttypes_h" = xyes; then : +- cat >>confdefs.h <<_ACEOF +-#define HAVE_INTTYPES_H 1 +-_ACEOF +- +-fi +- +-done +- +- if test $ac_cv_header_inttypes_h = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the inttypes.h PRIxNN macros are broken" >&5 +-$as_echo_n "checking whether the inttypes.h PRIxNN macros are broken... " >&6; } +-if ${gt_cv_inttypes_pri_broken+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#ifdef PRId32 +-char *p = PRId32; +-#endif +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gt_cv_inttypes_pri_broken=no +-else +- gt_cv_inttypes_pri_broken=yes +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_inttypes_pri_broken" >&5 +-$as_echo "$gt_cv_inttypes_pri_broken" >&6; } +- fi +- if test "$gt_cv_inttypes_pri_broken" = yes; then +- +-cat >>confdefs.h <<_ACEOF +-#define PRI_MACROS_BROKEN 1 +-_ACEOF +- +- PRI_MACROS_BROKEN=1 +- else +- PRI_MACROS_BROKEN=0 +- fi +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5 +-$as_echo_n "checking for nl_langinfo and CODESET... " >&6; } +-if ${am_cv_langinfo_codeset+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +-int +-main () +-{ +-char* cs = nl_langinfo(CODESET); return !cs; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_link "$LINENO"; then : +- am_cv_langinfo_codeset=yes +-else +- am_cv_langinfo_codeset=no +-fi +-rm -f core conftest.err conftest.$ac_objext \ +- conftest$ac_exeext conftest.$ac_ext +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_langinfo_codeset" >&5 +-$as_echo "$am_cv_langinfo_codeset" >&6; } +- if test $am_cv_langinfo_codeset = yes; then +- +-$as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h +- +- fi +- +- +- +- +- +- +- +- +- +- +- for ac_func in $gl_func_list +-do : +- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +-if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +-_ACEOF +- +-fi +-done +- +- +- +- +- +- +- +- +- +- : +- +- +- +- +- +- +- : +- +- +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fcntl.h" >&5 +-$as_echo_n "checking for working fcntl.h... " >&6; } +-if ${gl_cv_header_working_fcntl_h+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- if test "$cross_compiling" = yes; then : +- gl_cv_header_working_fcntl_h=cross-compiling +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- #include +- #if HAVE_UNISTD_H +- # include +- #else /* on Windows with MSVC */ +- # include +- # include +- # defined sleep(n) _sleep ((n) * 1000) +- #endif +- #include +- #ifndef O_NOATIME +- #define O_NOATIME 0 +- #endif +- #ifndef O_NOFOLLOW +- #define O_NOFOLLOW 0 +- #endif +- static int const constants[] = +- { +- O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, +- O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY +- }; +- +-int +-main () +-{ +- +- int result = !constants; +- #if HAVE_SYMLINK +- { +- static char const sym[] = "conftest.sym"; +- if (symlink ("/dev/null", sym) != 0) +- result |= 2; +- else +- { +- int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0); +- if (fd >= 0) +- { +- close (fd); +- result |= 4; +- } +- } +- if (unlink (sym) != 0 || symlink (".", sym) != 0) +- result |= 2; +- else +- { +- int fd = open (sym, O_RDONLY | O_NOFOLLOW); +- if (fd >= 0) +- { +- close (fd); +- result |= 4; +- } +- } +- unlink (sym); +- } +- #endif +- { +- static char const file[] = "confdefs.h"; +- int fd = open (file, O_RDONLY | O_NOATIME); +- if (fd < 0) +- result |= 8; +- else +- { +- struct stat st0; +- if (fstat (fd, &st0) != 0) +- result |= 16; +- else +- { +- char c; +- sleep (1); +- if (read (fd, &c, 1) != 1) +- result |= 24; +- else +- { +- if (close (fd) != 0) +- result |= 32; +- else +- { +- struct stat st1; +- if (stat (file, &st1) != 0) +- result |= 40; +- else +- if (st0.st_atime != st1.st_atime) +- result |= 64; +- } +- } +- } +- } +- } +- return result; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- gl_cv_header_working_fcntl_h=yes +-else +- case $? in #( +- 4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( +- 64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #( +- 68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( +- *) gl_cv_header_working_fcntl_h='no';; +- esac +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_fcntl_h" >&5 +-$as_echo "$gl_cv_header_working_fcntl_h" >&6; } +- +- case $gl_cv_header_working_fcntl_h in #( +- *O_NOATIME* | no | cross-compiling) ac_val=0;; #( +- *) ac_val=1;; +- esac +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_WORKING_O_NOATIME $ac_val +-_ACEOF +- +- +- case $gl_cv_header_working_fcntl_h in #( +- *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #( +- *) ac_val=1;; +- esac +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_WORKING_O_NOFOLLOW $ac_val +-_ACEOF +- +- +- +- ac_fn_c_check_decl "$LINENO" "getc_unlocked" "ac_cv_have_decl_getc_unlocked" "$ac_includes_default" +-if test "x$ac_cv_have_decl_getc_unlocked" = xyes; then : +- ac_have_decl=1 +-else +- ac_have_decl=0 +-fi +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_DECL_GETC_UNLOCKED $ac_have_decl +-_ACEOF +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C Library >= 2.1 or uClibc" >&5 +-$as_echo_n "checking whether we are using the GNU C Library >= 2.1 or uClibc... " >&6; } +-if ${ac_cv_gnu_library_2_1+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-#ifdef __GNU_LIBRARY__ +- #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) +- Lucky GNU user +- #endif +-#endif +-#ifdef __UCLIBC__ +- Lucky user +-#endif +- +-_ACEOF +-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | +- $EGREP "Lucky" >/dev/null 2>&1; then : +- ac_cv_gnu_library_2_1=yes +-else +- ac_cv_gnu_library_2_1=no +-fi +-rm -f conftest* +- +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gnu_library_2_1" >&5 +-$as_echo "$ac_cv_gnu_library_2_1" >&6; } +- +- GLIBC21="$ac_cv_gnu_library_2_1" +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 +-$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } +-if ${ac_cv_header_stdbool_h+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- #include +- #ifndef bool +- "error: bool is not defined" +- #endif +- #ifndef false +- "error: false is not defined" +- #endif +- #if false +- "error: false is not 0" +- #endif +- #ifndef true +- "error: true is not defined" +- #endif +- #if true != 1 +- "error: true is not 1" +- #endif +- #ifndef __bool_true_false_are_defined +- "error: __bool_true_false_are_defined is not defined" +- #endif +- +- struct s { _Bool s: 1; _Bool t; } s; +- +- char a[true == 1 ? 1 : -1]; +- char b[false == 0 ? 1 : -1]; +- char c[__bool_true_false_are_defined == 1 ? 1 : -1]; +- char d[(bool) 0.5 == true ? 1 : -1]; +- /* See body of main program for 'e'. */ +- char f[(_Bool) 0.0 == false ? 1 : -1]; +- char g[true]; +- char h[sizeof (_Bool)]; +- char i[sizeof s.t]; +- enum { j = false, k = true, l = false * true, m = true * 256 }; +- /* The following fails for +- HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ +- _Bool n[m]; +- char o[sizeof n == m * sizeof n[0] ? 1 : -1]; +- char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; +- /* Catch a bug in an HP-UX C compiler. See +- http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html +- http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html +- */ +- _Bool q = true; +- _Bool *pq = &q; +- +-int +-main () +-{ +- +- bool e = &s; +- *pq |= q; +- *pq |= ! q; +- /* Refer to every declared value, to avoid compiler optimizations. */ +- return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l +- + !m + !n + !o + !p + !q + !pq); +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- ac_cv_header_stdbool_h=yes +-else +- ac_cv_header_stdbool_h=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 +-$as_echo "$ac_cv_header_stdbool_h" >&6; } +- ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" +-if test "x$ac_cv_type__Bool" = xyes; then : +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE__BOOL 1 +-_ACEOF +- +- +-fi +- +- +- +- REPLACE_NULL=0; +- HAVE_WCHAR_T=1; +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wchar_t" >&5 +-$as_echo_n "checking for wchar_t... " >&6; } +-if ${gt_cv_c_wchar_t+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- wchar_t foo = (wchar_t)'\0'; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gt_cv_c_wchar_t=yes +-else +- gt_cv_c_wchar_t=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_wchar_t" >&5 +-$as_echo "$gt_cv_c_wchar_t" >&6; } +- if test $gt_cv_c_wchar_t = yes; then +- +-$as_echo "#define HAVE_WCHAR_T 1" >>confdefs.h +- +- fi +- +- +- +- +- +- +- +-gl_libunistring_sed_extract_major='/^[0-9]/{s/^\([0-9]*\).*/\1/p;q;} +-i\ +-0 +-q +-' +-gl_libunistring_sed_extract_minor='/^[0-9][0-9]*[.][0-9]/{s/^[0-9]*[.]\([0-9]*\).*/\1/p;q;} +-i\ +-0 +-q +-' +-gl_libunistring_sed_extract_subminor='/^[0-9][0-9]*[.][0-9][0-9]*[.][0-9]/{s/^[0-9]*[.][0-9]*[.]\([0-9]*\).*/\1/p;q;} +-i\ +-0 +-q +-' +- +- +- if test "$HAVE_LIBUNISTRING" = yes; then +- LIBUNISTRING_VERSION_MAJOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_major"` +- LIBUNISTRING_VERSION_MINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_minor"` +- LIBUNISTRING_VERSION_SUBMINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_subminor"` +- fi +- +- +- GNULIB_BTOWC=0; +- GNULIB_WCTOB=0; +- GNULIB_MBSINIT=0; +- GNULIB_MBRTOWC=0; +- GNULIB_MBRLEN=0; +- GNULIB_MBSRTOWCS=0; +- GNULIB_MBSNRTOWCS=0; +- GNULIB_WCRTOMB=0; +- GNULIB_WCSRTOMBS=0; +- GNULIB_WCSNRTOMBS=0; +- GNULIB_WCWIDTH=0; +- GNULIB_WMEMCHR=0; +- GNULIB_WMEMCMP=0; +- GNULIB_WMEMCPY=0; +- GNULIB_WMEMMOVE=0; +- GNULIB_WMEMSET=0; +- GNULIB_WCSLEN=0; +- GNULIB_WCSNLEN=0; +- GNULIB_WCSCPY=0; +- GNULIB_WCPCPY=0; +- GNULIB_WCSNCPY=0; +- GNULIB_WCPNCPY=0; +- GNULIB_WCSCAT=0; +- GNULIB_WCSNCAT=0; +- GNULIB_WCSCMP=0; +- GNULIB_WCSNCMP=0; +- GNULIB_WCSCASECMP=0; +- GNULIB_WCSNCASECMP=0; +- GNULIB_WCSCOLL=0; +- GNULIB_WCSXFRM=0; +- GNULIB_WCSDUP=0; +- GNULIB_WCSCHR=0; +- GNULIB_WCSRCHR=0; +- GNULIB_WCSCSPN=0; +- GNULIB_WCSSPN=0; +- GNULIB_WCSPBRK=0; +- GNULIB_WCSSTR=0; +- GNULIB_WCSTOK=0; +- GNULIB_WCSWIDTH=0; +- HAVE_BTOWC=1; +- HAVE_MBSINIT=1; +- HAVE_MBRTOWC=1; +- HAVE_MBRLEN=1; +- HAVE_MBSRTOWCS=1; +- HAVE_MBSNRTOWCS=1; +- HAVE_WCRTOMB=1; +- HAVE_WCSRTOMBS=1; +- HAVE_WCSNRTOMBS=1; +- HAVE_WMEMCHR=1; +- HAVE_WMEMCMP=1; +- HAVE_WMEMCPY=1; +- HAVE_WMEMMOVE=1; +- HAVE_WMEMSET=1; +- HAVE_WCSLEN=1; +- HAVE_WCSNLEN=1; +- HAVE_WCSCPY=1; +- HAVE_WCPCPY=1; +- HAVE_WCSNCPY=1; +- HAVE_WCPNCPY=1; +- HAVE_WCSCAT=1; +- HAVE_WCSNCAT=1; +- HAVE_WCSCMP=1; +- HAVE_WCSNCMP=1; +- HAVE_WCSCASECMP=1; +- HAVE_WCSNCASECMP=1; +- HAVE_WCSCOLL=1; +- HAVE_WCSXFRM=1; +- HAVE_WCSDUP=1; +- HAVE_WCSCHR=1; +- HAVE_WCSRCHR=1; +- HAVE_WCSCSPN=1; +- HAVE_WCSSPN=1; +- HAVE_WCSPBRK=1; +- HAVE_WCSSTR=1; +- HAVE_WCSTOK=1; +- HAVE_WCSWIDTH=1; +- HAVE_DECL_WCTOB=1; +- HAVE_DECL_WCWIDTH=1; +- REPLACE_MBSTATE_T=0; +- REPLACE_BTOWC=0; +- REPLACE_WCTOB=0; +- REPLACE_MBSINIT=0; +- REPLACE_MBRTOWC=0; +- REPLACE_MBRLEN=0; +- REPLACE_MBSRTOWCS=0; +- REPLACE_MBSNRTOWCS=0; +- REPLACE_WCRTOMB=0; +- REPLACE_WCSRTOMBS=0; +- REPLACE_WCSNRTOMBS=0; +- REPLACE_WCWIDTH=0; +- REPLACE_WCSWIDTH=0; +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether uses 'inline' correctly" >&5 +-$as_echo_n "checking whether uses 'inline' correctly... " >&6; } +-if ${gl_cv_header_wchar_h_correct_inline+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- gl_cv_header_wchar_h_correct_inline=yes +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- #define wcstod renamed_wcstod +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-#include +-#include +-#include +-#include +-extern int zero (void); +-int main () { return zero(); } +- +-_ACEOF +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 +- (eval $ac_compile) 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then +- mv conftest.$ac_objext conftest1.$ac_objext +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- #define wcstod renamed_wcstod +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-#include +-#include +-#include +-#include +-int zero (void) { return 0; } +- +-_ACEOF +- if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 +- (eval $ac_compile) 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; then +- mv conftest.$ac_objext conftest2.$ac_objext +- if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&5 2>&1; then +- : +- else +- gl_cv_header_wchar_h_correct_inline=no +- fi +- fi +- fi +- rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_wchar_h_correct_inline" >&5 +-$as_echo "$gl_cv_header_wchar_h_correct_inline" >&6; } +- if test $gl_cv_header_wchar_h_correct_inline = no; then +- as_fn_error $? " cannot be used with this compiler ($CC $CFLAGS $CPPFLAGS). +-This is a known interoperability problem of glibc <= 2.5 with gcc >= 4.3 in +-C99 mode. You have four options: +- - Add the flag -fgnu89-inline to CC and reconfigure, or +- - Fix your include files, using parts of +- , or +- - Use a gcc version older than 4.3, or +- - Don't use the flags -std=c99 or -std=gnu99. +-Configuration aborted." "$LINENO" 5 +- fi +- +- +- +- +- +- +- +- +- : +- +- +- +- +- +- if test $ac_cv_header_features_h = yes; then +- HAVE_FEATURES_H=1 +- else +- HAVE_FEATURES_H=0 +- fi +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wint_t" >&5 +-$as_echo_n "checking for wint_t... " >&6; } +-if ${gt_cv_c_wint_t+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be included +- before . */ +-#include +-#include +-#include +-#include +- wint_t foo = (wchar_t)'\0'; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gt_cv_c_wint_t=yes +-else +- gt_cv_c_wint_t=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_wint_t" >&5 +-$as_echo "$gt_cv_c_wint_t" >&6; } +- if test $gt_cv_c_wint_t = yes; then +- +-$as_echo "#define HAVE_WINT_T 1" >>confdefs.h +- +- fi +- +- +- GNULIB_ISWBLANK=0; +- GNULIB_WCTYPE=0; +- GNULIB_ISWCTYPE=0; +- GNULIB_WCTRANS=0; +- GNULIB_TOWCTRANS=0; +- HAVE_ISWBLANK=1; +- HAVE_WCTYPE_T=1; +- HAVE_WCTRANS_T=1; +- REPLACE_ISWBLANK=0; +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +-gl_m4_base='m4' +- +- +- +- +- +- +- +- +- +-gl_source_base='lib' +- +- if test "x$datarootdir" = x; then +- datarootdir='${datadir}' +- +- fi +- if test "x$docdir" = x; then +- docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +- +- fi +- if test "x$htmldir" = x; then +- htmldir='${docdir}' +- +- fi +- if test "x$dvidir" = x; then +- dvidir='${docdir}' +- +- fi +- if test "x$pdfdir" = x; then +- pdfdir='${docdir}' +- +- fi +- if test "x$psdir" = x; then +- psdir='${docdir}' +- +- fi +- if test "x$lispdir" = x; then +- lispdir='${datarootdir}/emacs/site-lisp' +- +- fi +- if test "x$localedir" = x; then +- localedir='${datarootdir}/locale' +- +- fi +- if test "x$runstatedir" = x; then +- runstatedir='${localstatedir}/run' +- +- fi +- +- pkglibexecdir='${libexecdir}/${PACKAGE}' +- +- +- +- +- +- +- +- +- PRIPTR_PREFIX= +- if test -n "$STDINT_H"; then +- PRIPTR_PREFIX='"l"' +- else +- for glpfx in '' l ll I64; do +- case $glpfx in +- '') gltype1='int';; +- l) gltype1='long int';; +- ll) gltype1='long long int';; +- I64) gltype1='__int64';; +- esac +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- extern intptr_t foo; +- extern $gltype1 foo; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- PRIPTR_PREFIX='"'$glpfx'"' +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- test -n "$PRIPTR_PREFIX" && break +- done +- fi +- +- +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether INT32_MAX < INTMAX_MAX" >&5 +-$as_echo_n "checking whether INT32_MAX < INTMAX_MAX... " >&6; } +-if ${gl_cv_test_INT32_MAX_LT_INTMAX_MAX+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-/* Work also in C++ mode. */ +- #define __STDC_LIMIT_MACROS 1 +- +- /* Work if build is not clean. */ +- #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H +- +- #include +- #if HAVE_STDINT_H +- #include +- #endif +- +- #if defined INT32_MAX && defined INTMAX_MAX +- #define CONDITION (INT32_MAX < INTMAX_MAX) +- #elif HAVE_LONG_LONG_INT +- #define CONDITION (sizeof (int) < sizeof (long long int)) +- #else +- #define CONDITION 0 +- #endif +- int test[CONDITION ? 1 : -1]; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_test_INT32_MAX_LT_INTMAX_MAX=yes +-else +- gl_cv_test_INT32_MAX_LT_INTMAX_MAX=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_test_INT32_MAX_LT_INTMAX_MAX" >&5 +-$as_echo "$gl_cv_test_INT32_MAX_LT_INTMAX_MAX" >&6; } +- if test $gl_cv_test_INT32_MAX_LT_INTMAX_MAX = yes; then +- INT32_MAX_LT_INTMAX_MAX=1; +- else +- INT32_MAX_LT_INTMAX_MAX=0; +- fi +- +- +- if test $APPLE_UNIVERSAL_BUILD = 0; then +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether INT64_MAX == LONG_MAX" >&5 +-$as_echo_n "checking whether INT64_MAX == LONG_MAX... " >&6; } +-if ${gl_cv_test_INT64_MAX_EQ_LONG_MAX+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-/* Work also in C++ mode. */ +- #define __STDC_LIMIT_MACROS 1 +- +- /* Work if build is not clean. */ +- #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H +- +- #include +- #if HAVE_STDINT_H +- #include +- #endif +- +- #if defined INT64_MAX +- #define CONDITION (INT64_MAX == LONG_MAX) +- #elif HAVE_LONG_LONG_INT +- #define CONDITION (sizeof (long long int) == sizeof (long int)) +- #else +- #define CONDITION 0 +- #endif +- int test[CONDITION ? 1 : -1]; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_test_INT64_MAX_EQ_LONG_MAX=yes +-else +- gl_cv_test_INT64_MAX_EQ_LONG_MAX=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_test_INT64_MAX_EQ_LONG_MAX" >&5 +-$as_echo "$gl_cv_test_INT64_MAX_EQ_LONG_MAX" >&6; } +- if test $gl_cv_test_INT64_MAX_EQ_LONG_MAX = yes; then +- INT64_MAX_EQ_LONG_MAX=1; +- else +- INT64_MAX_EQ_LONG_MAX=0; +- fi +- +- +- else +- INT64_MAX_EQ_LONG_MAX=-1 +- fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether UINT32_MAX < UINTMAX_MAX" >&5 +-$as_echo_n "checking whether UINT32_MAX < UINTMAX_MAX... " >&6; } +-if ${gl_cv_test_UINT32_MAX_LT_UINTMAX_MAX+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-/* Work also in C++ mode. */ +- #define __STDC_LIMIT_MACROS 1 +- +- /* Work if build is not clean. */ +- #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H +- +- #include +- #if HAVE_STDINT_H +- #include +- #endif +- +- #if defined UINT32_MAX && defined UINTMAX_MAX +- #define CONDITION (UINT32_MAX < UINTMAX_MAX) +- #elif HAVE_LONG_LONG_INT +- #define CONDITION (sizeof (unsigned int) < sizeof (unsigned long long int)) +- #else +- #define CONDITION 0 +- #endif +- int test[CONDITION ? 1 : -1]; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_test_UINT32_MAX_LT_UINTMAX_MAX=yes +-else +- gl_cv_test_UINT32_MAX_LT_UINTMAX_MAX=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_test_UINT32_MAX_LT_UINTMAX_MAX" >&5 +-$as_echo "$gl_cv_test_UINT32_MAX_LT_UINTMAX_MAX" >&6; } +- if test $gl_cv_test_UINT32_MAX_LT_UINTMAX_MAX = yes; then +- UINT32_MAX_LT_UINTMAX_MAX=1; +- else +- UINT32_MAX_LT_UINTMAX_MAX=0; +- fi +- +- +- if test $APPLE_UNIVERSAL_BUILD = 0; then +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether UINT64_MAX == ULONG_MAX" >&5 +-$as_echo_n "checking whether UINT64_MAX == ULONG_MAX... " >&6; } +-if ${gl_cv_test_UINT64_MAX_EQ_ULONG_MAX+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-/* Work also in C++ mode. */ +- #define __STDC_LIMIT_MACROS 1 +- +- /* Work if build is not clean. */ +- #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H +- +- #include +- #if HAVE_STDINT_H +- #include +- #endif +- +- #if defined UINT64_MAX +- #define CONDITION (UINT64_MAX == ULONG_MAX) +- #elif HAVE_LONG_LONG_INT +- #define CONDITION (sizeof (unsigned long long int) == sizeof (unsigned long int)) +- #else +- #define CONDITION 0 +- #endif +- int test[CONDITION ? 1 : -1]; +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_test_UINT64_MAX_EQ_ULONG_MAX=yes +-else +- gl_cv_test_UINT64_MAX_EQ_ULONG_MAX=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_test_UINT64_MAX_EQ_ULONG_MAX" >&5 +-$as_echo "$gl_cv_test_UINT64_MAX_EQ_ULONG_MAX" >&6; } +- if test $gl_cv_test_UINT64_MAX_EQ_ULONG_MAX = yes; then +- UINT64_MAX_EQ_ULONG_MAX=1; +- else +- UINT64_MAX_EQ_ULONG_MAX=0; +- fi +- +- +- else +- UINT64_MAX_EQ_ULONG_MAX=-1 +- fi +- +- +- +- +- +- +- +- : +- +- +- +- +- +- +- +- +- +- LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\"" +- +- +- +- +- +- # Define two additional variables used in the Makefile substitution. +- +- if test "$ac_cv_header_stdbool_h" = yes; then +- STDBOOL_H='' +- else +- STDBOOL_H='stdbool.h' +- fi +- +- if test -n "$STDBOOL_H"; then +- GL_GENERATE_STDBOOL_H_TRUE= +- GL_GENERATE_STDBOOL_H_FALSE='#' +-else +- GL_GENERATE_STDBOOL_H_TRUE='#' +- GL_GENERATE_STDBOOL_H_FALSE= +-fi +- +- +- if test "$ac_cv_type__Bool" = yes; then +- HAVE__BOOL=1 +- else +- HAVE__BOOL=0 +- fi +- +- +- +- +- +- STDDEF_H= +- if test $gt_cv_c_wchar_t = no; then +- HAVE_WCHAR_T=0 +- STDDEF_H=stddef.h +- fi +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NULL can be used in arbitrary expressions" >&5 +-$as_echo_n "checking whether NULL can be used in arbitrary expressions... " >&6; } +-if ${gl_cv_decl_null_works+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- int test[2 * (sizeof NULL == sizeof (void *)) -1]; +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_decl_null_works=yes +-else +- gl_cv_decl_null_works=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_decl_null_works" >&5 +-$as_echo "$gl_cv_decl_null_works" >&6; } +- if test $gl_cv_decl_null_works = no; then +- REPLACE_NULL=1 +- STDDEF_H=stddef.h +- fi +- +- if test -n "$STDDEF_H"; then +- GL_GENERATE_STDDEF_H_TRUE= +- GL_GENERATE_STDDEF_H_FALSE='#' +-else +- GL_GENERATE_STDDEF_H_TRUE='#' +- GL_GENERATE_STDDEF_H_FALSE= +-fi +- +- if test -n "$STDDEF_H"; then +- +- +- +- +- +- +- +- +- if test $gl_cv_have_include_next = yes; then +- gl_cv_next_stddef_h='<'stddef.h'>' +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of " >&5 +-$as_echo_n "checking absolute name of ... " >&6; } +-if ${gl_cv_next_stddef_h+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-_ACEOF +- case "$host_os" in +- aix*) gl_absname_cpp="$ac_cpp -C" ;; +- *) gl_absname_cpp="$ac_cpp" ;; +- esac +- +- case "$host_os" in +- mingw*) +- gl_dirsep_regex='[/\\]' +- ;; +- *) +- gl_dirsep_regex='\/' +- ;; +- esac +- gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' +- +- gl_header_literal_regex=`echo 'stddef.h' \ +- | sed -e "$gl_make_literal_regex_sed"` +- gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ +- s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ +- s|^/[^/]|//&| +- p +- q +- }' +- gl_cv_next_stddef_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 | +- sed -n "$gl_absolute_header_sed"`'"' +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_stddef_h" >&5 +-$as_echo "$gl_cv_next_stddef_h" >&6; } +- fi +- NEXT_STDDEF_H=$gl_cv_next_stddef_h +- +- if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' +- gl_next_as_first_directive='<'stddef.h'>' +- else +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' +- gl_next_as_first_directive=$gl_cv_next_stddef_h +- fi +- NEXT_AS_FIRST_DIRECTIVE_STDDEF_H=$gl_next_as_first_directive +- +- +- +- +- fi +- +- +- +- +- if { test "$HAVE_LIBUNISTRING" != yes \ +- || { +- +- +- +- test $LIBUNISTRING_VERSION_MAJOR -lt 0 \ +- || { test $LIBUNISTRING_VERSION_MAJOR -eq 0 \ +- && { test $LIBUNISTRING_VERSION_MINOR -lt 9 \ +- || { test $LIBUNISTRING_VERSION_MINOR -eq 9 \ +- && test $LIBUNISTRING_VERSION_SUBMINOR -lt 0 +- } +- } +- } +- +- +- +- +- } +- }; then +- LIBUNISTRING_UNITYPES_H='unitypes.h' +- else +- LIBUNISTRING_UNITYPES_H= +- fi +- +- +- +- +- if { test "$HAVE_LIBUNISTRING" != yes \ +- || { +- +- +- +- test $LIBUNISTRING_VERSION_MAJOR -lt 0 \ +- || { test $LIBUNISTRING_VERSION_MAJOR -eq 0 \ +- && { test $LIBUNISTRING_VERSION_MINOR -lt 9 \ +- || { test $LIBUNISTRING_VERSION_MINOR -eq 9 \ +- && test $LIBUNISTRING_VERSION_SUBMINOR -lt 0 +- } +- } +- } +- +- +- +- +- } +- }; then +- LIBUNISTRING_UNIWIDTH_H='uniwidth.h' +- else +- LIBUNISTRING_UNIWIDTH_H= +- fi +- +- +- +- +- if { test "$HAVE_LIBUNISTRING" != yes \ +- || { +- +- +- +- test $LIBUNISTRING_VERSION_MAJOR -lt 0 \ +- || { test $LIBUNISTRING_VERSION_MAJOR -eq 0 \ +- && { test $LIBUNISTRING_VERSION_MINOR -lt 9 \ +- || { test $LIBUNISTRING_VERSION_MINOR -eq 9 \ +- && test $LIBUNISTRING_VERSION_SUBMINOR -lt 4 +- } +- } +- } +- +- +- +- +- } +- }; then +- LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE= +- LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_FALSE='#' +-else +- LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE='#' +- LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_FALSE= +-fi +- +- +- +- +- +- +- +- +- +- +- +- : +- +- +- +- +- +- +- +- +- if test $gl_cv_have_include_next = yes; then +- gl_cv_next_wchar_h='<'wchar.h'>' +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of " >&5 +-$as_echo_n "checking absolute name of ... " >&6; } +-if ${gl_cv_next_wchar_h+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- if test $ac_cv_header_wchar_h = yes; then +- +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-_ACEOF +- case "$host_os" in +- aix*) gl_absname_cpp="$ac_cpp -C" ;; +- *) gl_absname_cpp="$ac_cpp" ;; +- esac +- +- case "$host_os" in +- mingw*) +- gl_dirsep_regex='[/\\]' +- ;; +- *) +- gl_dirsep_regex='\/' +- ;; +- esac +- gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' +- +- gl_header_literal_regex=`echo 'wchar.h' \ +- | sed -e "$gl_make_literal_regex_sed"` +- gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ +- s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ +- s|^/[^/]|//&| +- p +- q +- }' +- gl_cv_next_wchar_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 | +- sed -n "$gl_absolute_header_sed"`'"' +- else +- gl_cv_next_wchar_h='<'wchar.h'>' +- fi +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_wchar_h" >&5 +-$as_echo "$gl_cv_next_wchar_h" >&6; } +- fi +- NEXT_WCHAR_H=$gl_cv_next_wchar_h +- +- if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' +- gl_next_as_first_directive='<'wchar.h'>' +- else +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' +- gl_next_as_first_directive=$gl_cv_next_wchar_h +- fi +- NEXT_AS_FIRST_DIRECTIVE_WCHAR_H=$gl_next_as_first_directive +- +- +- +- +- if test $ac_cv_header_wchar_h = yes; then +- HAVE_WCHAR_H=1 +- else +- HAVE_WCHAR_H=0 +- fi +- +- +- +- +- +- if test $gt_cv_c_wint_t = yes; then +- HAVE_WINT_T=1 +- else +- HAVE_WINT_T=0 +- fi +- +- +- +- for gl_func in btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb wcsrtombs wcsnrtombs wcwidth wmemchr wmemcmp wmemcpy wmemmove wmemset wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat wcscmp wcsncmp wcscasecmp wcsncasecmp wcscoll wcsxfrm wcsdup wcschr wcsrchr wcscspn wcsspn wcspbrk wcsstr wcstok wcswidth ; do +- as_gl_Symbol=`$as_echo "gl_cv_have_raw_decl_$gl_func" | $as_tr_sh` +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gl_func is declared without a macro" >&5 +-$as_echo_n "checking whether $gl_func is declared without a macro... " >&6; } +-if eval \${$as_gl_Symbol+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-#if !(defined __GLIBC__ && !defined __UCLIBC__) +-# include +-# include +-# include +-#endif +-#include +- +-int +-main () +-{ +-#undef $gl_func +- (void) $gl_func; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval "$as_gl_Symbol=yes" +-else +- eval "$as_gl_Symbol=no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$as_gl_Symbol +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- if eval test \"x\$"$as_gl_Symbol"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_RAW_DECL_$gl_func" | $as_tr_cpp` 1 +-_ACEOF +- +- eval ac_cv_have_decl_$gl_func=yes +-fi +- done +- +- +- +- +- +- +- +- : +- +- +- +- +- +- if test $ac_cv_func_iswcntrl = yes; then +- HAVE_ISWCNTRL=1 +- else +- HAVE_ISWCNTRL=0 +- fi +- +- +- +- if test $gt_cv_c_wint_t = yes; then +- HAVE_WINT_T=1 +- else +- HAVE_WINT_T=0 +- fi +- +- +- +- +- +- +- +- +- : +- +- +- +- +- +- +- +- +- if test $gl_cv_have_include_next = yes; then +- gl_cv_next_wctype_h='<'wctype.h'>' +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of " >&5 +-$as_echo_n "checking absolute name of ... " >&6; } +-if ${gl_cv_next_wctype_h+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- if test $ac_cv_header_wctype_h = yes; then +- +- +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- +-_ACEOF +- case "$host_os" in +- aix*) gl_absname_cpp="$ac_cpp -C" ;; +- *) gl_absname_cpp="$ac_cpp" ;; +- esac +- +- case "$host_os" in +- mingw*) +- gl_dirsep_regex='[/\\]' +- ;; +- *) +- gl_dirsep_regex='\/' +- ;; +- esac +- gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' +- +- gl_header_literal_regex=`echo 'wctype.h' \ +- | sed -e "$gl_make_literal_regex_sed"` +- gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ +- s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ +- s|^/[^/]|//&| +- p +- q +- }' +- gl_cv_next_wctype_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 | +- sed -n "$gl_absolute_header_sed"`'"' +- else +- gl_cv_next_wctype_h='<'wctype.h'>' +- fi +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_wctype_h" >&5 +-$as_echo "$gl_cv_next_wctype_h" >&6; } +- fi +- NEXT_WCTYPE_H=$gl_cv_next_wctype_h +- +- if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' +- gl_next_as_first_directive='<'wctype.h'>' +- else +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' +- gl_next_as_first_directive=$gl_cv_next_wctype_h +- fi +- NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H=$gl_next_as_first_directive +- +- +- +- +- if test $ac_cv_header_wctype_h = yes; then +- if test $ac_cv_func_iswcntrl = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iswcntrl works" >&5 +-$as_echo_n "checking whether iswcntrl works... " >&6; } +-if ${gl_cv_func_iswcntrl_works+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- if test "$cross_compiling" = yes; then : +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-#include +- #if __GNU_LIBRARY__ == 1 +- Linux libc5 i18n is broken. +- #endif +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_func_iswcntrl_works="guessing yes" +-else +- gl_cv_func_iswcntrl_works="guessing no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +- /* Tru64 with Desktop Toolkit C has a bug: must be +- included before . +- BSD/OS 4.0.1 has a bug: , and +- must be included before . */ +- #include +- #include +- #include +- #include +- #include +- int main () { return iswprint ('x') == 0; } +- +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- gl_cv_func_iswcntrl_works=yes +-else +- gl_cv_func_iswcntrl_works=no +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_iswcntrl_works" >&5 +-$as_echo "$gl_cv_func_iswcntrl_works" >&6; } +- fi +- HAVE_WCTYPE_H=1 +- else +- HAVE_WCTYPE_H=0 +- fi +- +- +- case "$gl_cv_func_iswcntrl_works" in +- *yes) REPLACE_ISWCNTRL=0 ;; +- *) REPLACE_ISWCNTRL=1 ;; +- esac +- +- +- if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then +- : +- fi +- +- if test $REPLACE_ISWCNTRL = 1; then +- REPLACE_TOWLOWER=1 +- else +- for ac_func in towlower +-do : +- ac_fn_c_check_func "$LINENO" "towlower" "ac_cv_func_towlower" +-if test "x$ac_cv_func_towlower" = xyes; then : +- cat >>confdefs.h <<_ACEOF +-#define HAVE_TOWLOWER 1 +-_ACEOF +- +-fi +-done +- +- if test $ac_cv_func_towlower = yes; then +- REPLACE_TOWLOWER=0 +- else +- ac_fn_c_check_decl "$LINENO" "towlower" "ac_cv_have_decl_towlower" "/* Tru64 with Desktop Toolkit C has a bug: must be +- included before . +- BSD/OS 4.0.1 has a bug: , and +- must be included before . */ +- #include +- #include +- #include +- #include +- #if HAVE_WCTYPE_H +- # include +- #endif +- +-" +-if test "x$ac_cv_have_decl_towlower" = xyes; then : +- ac_have_decl=1 +-else +- ac_have_decl=0 +-fi +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_DECL_TOWLOWER $ac_have_decl +-_ACEOF +- +- if test $ac_cv_have_decl_towlower = yes; then +- REPLACE_TOWLOWER=1 +- else +- REPLACE_TOWLOWER=0 +- fi +- fi +- fi +- +- +- if test $HAVE_ISWCNTRL = 0 || test $REPLACE_TOWLOWER = 1; then +- : +- fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wctype_t" >&5 +-$as_echo_n "checking for wctype_t... " >&6; } +-if ${gl_cv_type_wctype_t+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-/* Tru64 with Desktop Toolkit C has a bug: must be +- included before . +- BSD/OS 4.0.1 has a bug: , and +- must be included before . */ +- #include +- #include +- #include +- #include +- #if HAVE_WCTYPE_H +- # include +- #endif +- wctype_t a; +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_type_wctype_t=yes +-else +- gl_cv_type_wctype_t=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_type_wctype_t" >&5 +-$as_echo "$gl_cv_type_wctype_t" >&6; } +- if test $gl_cv_type_wctype_t = no; then +- HAVE_WCTYPE_T=0 +- fi +- +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wctrans_t" >&5 +-$as_echo_n "checking for wctrans_t... " >&6; } +-if ${gl_cv_type_wctrans_t+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-/* Tru64 with Desktop Toolkit C has a bug: must be +- included before . +- BSD/OS 4.0.1 has a bug: , and +- must be included before . */ +- #include +- #include +- #include +- #include +- #include +- wctrans_t a; +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- gl_cv_type_wctrans_t=yes +-else +- gl_cv_type_wctrans_t=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_type_wctrans_t" >&5 +-$as_echo "$gl_cv_type_wctrans_t" >&6; } +- if test $gl_cv_type_wctrans_t = no; then +- HAVE_WCTRANS_T=0 +- fi +- +- +- for gl_func in wctype iswctype wctrans towctrans ; do +- as_gl_Symbol=`$as_echo "gl_cv_have_raw_decl_$gl_func" | $as_tr_sh` +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gl_func is declared without a macro" >&5 +-$as_echo_n "checking whether $gl_func is declared without a macro... " >&6; } +-if eval \${$as_gl_Symbol+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-#if !(defined __GLIBC__ && !defined __UCLIBC__) +-# include +-# include +-# include +-# include +-#endif +-#include +- +-int +-main () +-{ +-#undef $gl_func +- (void) $gl_func; +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval "$as_gl_Symbol=yes" +-else +- eval "$as_gl_Symbol=no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$as_gl_Symbol +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- if eval test \"x\$"$as_gl_Symbol"\" = x"yes"; then : +- cat >>confdefs.h <<_ACEOF +-#define `$as_echo "HAVE_RAW_DECL_$gl_func" | $as_tr_cpp` 1 +-_ACEOF +- +- eval ac_cv_have_decl_$gl_func=yes +-fi +- done +- +- +- +- +- +- +- +- +- +- +- +- : +- +- +- +- +- +- +- : +- +- +- +- +- +- +- ac_fn_c_check_decl "$LINENO" "wcwidth" "ac_cv_have_decl_wcwidth" " +-/* AIX 3.2.5 declares wcwidth in . */ +-#include +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be included +- before . */ +-#include +-#include +-#include +-#include +- +-" +-if test "x$ac_cv_have_decl_wcwidth" = xyes; then : +- ac_have_decl=1 +-else +- ac_have_decl=0 +-fi +- +-cat >>confdefs.h <<_ACEOF +-#define HAVE_DECL_WCWIDTH $ac_have_decl +-_ACEOF +- +- if test $ac_cv_have_decl_wcwidth != yes; then +- HAVE_DECL_WCWIDTH=0 +- fi +- +- if test $ac_cv_func_wcwidth = yes; then +- HAVE_WCWIDTH=1 +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether wcwidth works reasonably in UTF-8 locales" >&5 +-$as_echo_n "checking whether wcwidth works reasonably in UTF-8 locales... " >&6; } +-if ${gl_cv_func_wcwidth_works+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- +- if test "$cross_compiling" = yes; then : +- +- case "$host_os" in +- # Guess yes on glibc and AIX 7 systems. +- *-gnu* | aix[7-9]*) gl_cv_func_wcwidth_works="guessing yes";; +- *) gl_cv_func_wcwidth_works="guessing no";; +- esac +- +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-#include +-/* AIX 3.2.5 declares wcwidth in . */ +-#include +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be included +- before . */ +-#include +-#include +-#include +-#include +-#if !HAVE_DECL_WCWIDTH +-extern +-# ifdef __cplusplus +-"C" +-# endif +-int wcwidth (int); +-#endif +-int main () +-{ +- int result = 0; +- if (setlocale (LC_ALL, "fr_FR.UTF-8") != NULL) +- { +- if (wcwidth (0x0301) > 0) +- result |= 1; +- if (wcwidth (0x05B0) > 0) +- result |= 2; +- if (wcwidth (0x200B) > 0) +- result |= 4; +- } +- return result; +-} +-_ACEOF +-if ac_fn_c_try_run "$LINENO"; then : +- gl_cv_func_wcwidth_works=yes +-else +- gl_cv_func_wcwidth_works=no +-fi +-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ +- conftest.$ac_objext conftest.beam conftest.$ac_ext +-fi +- +- +-fi +-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_wcwidth_works" >&5 +-$as_echo "$gl_cv_func_wcwidth_works" >&6; } +- case "$gl_cv_func_wcwidth_works" in +- *yes) ;; +- *no) REPLACE_WCWIDTH=1 ;; +- esac +- else +- HAVE_WCWIDTH=0 +- fi +- +- if test $HAVE_WCWIDTH = 0 || test $REPLACE_WCWIDTH = 1; then +- +- +- +- +- +- +- +- +- gl_LIBOBJS="$gl_LIBOBJS wcwidth.$ac_objext" +- +- fi +- +- +- +- +- +- GNULIB_WCWIDTH=1 +- +- +- +- +- +-$as_echo "#define GNULIB_TEST_WCWIDTH 1" >>confdefs.h +- +- +- +- +- +- +- +- +- +- +- +- +- LIBGNU_LIBDEPS="$gl_libdeps" +- +- LIBGNU_LTLIBDEPS="$gl_ltlibdeps" +- +- +- +-ac_config_files="$ac_config_files Makefile lib/Makefile m4/Makefile" +- +-cat >confcache <<\_ACEOF +-# This file is a shell script that caches the results of configure +-# tests run on this system so they can be shared between configure +-# scripts and configure runs, see configure's option --config-cache. +-# It is not useful on other systems. If it contains results you don't +-# want to keep, you may remove or edit it. +-# +-# config.status only pays attention to the cache file if you give it +-# the --recheck option to rerun configure. +-# +-# `ac_cv_env_foo' variables (set or unset) will be overridden when +-# loading this file, other *unset* `ac_cv_foo' will be assigned the +-# following values. +- +-_ACEOF +- +-# The following way of writing the cache mishandles newlines in values, +-# but we know of no workaround that is simple, portable, and efficient. +-# So, we kill variables containing newlines. +-# Ultrix sh set writes to stderr and can't be redirected directly, +-# and sets the high bit in the cache file unless we assign to the vars. +-( +- for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do +- eval ac_val=\$$ac_var +- case $ac_val in #( +- *${as_nl}*) +- case $ac_var in #( +- *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; +- esac +- case $ac_var in #( +- _ | IFS | as_nl) ;; #( +- BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( +- *) { eval $ac_var=; unset $ac_var;} ;; +- esac ;; +- esac +- done +- +- (set) 2>&1 | +- case $as_nl`(ac_space=' '; set) 2>&1` in #( +- *${as_nl}ac_space=\ *) +- # `set' does not quote correctly, so add quotes: double-quote +- # substitution turns \\\\ into \\, and sed turns \\ into \. +- sed -n \ +- "s/'/'\\\\''/g; +- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" +- ;; #( +- *) +- # `set' quotes correctly as required by POSIX, so do not add quotes. +- sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" +- ;; +- esac | +- sort +-) | +- sed ' +- /^ac_cv_env_/b end +- t clear +- :clear +- s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ +- t end +- s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ +- :end' >>confcache +-if diff "$cache_file" confcache >/dev/null 2>&1; then :; else +- if test -w "$cache_file"; then +- if test "x$cache_file" != "x/dev/null"; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +-$as_echo "$as_me: updating cache $cache_file" >&6;} +- if test ! -f "$cache_file" || test -h "$cache_file"; then +- cat confcache >"$cache_file" +- else +- case $cache_file in #( +- */* | ?:*) +- mv -f confcache "$cache_file"$$ && +- mv -f "$cache_file"$$ "$cache_file" ;; #( +- *) +- mv -f confcache "$cache_file" ;; +- esac +- fi +- fi +- else +- { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} +- fi +-fi +-rm -f confcache +- +-test "x$prefix" = xNONE && prefix=$ac_default_prefix +-# Let make expand exec_prefix. +-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' +- +-DEFS=-DHAVE_CONFIG_H +- +-ac_libobjs= +-ac_ltlibobjs= +-U= +-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue +- # 1. Remove the extension, and $U if already installed. +- ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' +- ac_i=`$as_echo "$ac_i" | sed "$ac_script"` +- # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR +- # will be set to the directory where LIBOBJS objects are built. +- as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" +- as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +-done +-LIBOBJS=$ac_libobjs +- +-LTLIBOBJS=$ac_ltlibobjs +- +- +-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +-$as_echo_n "checking that generated files are newer than configure... " >&6; } +- if test -n "$am_sleep_pid"; then +- # Hide warnings about reused PIDs. +- wait $am_sleep_pid 2>/dev/null +- fi +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +-$as_echo "done" >&6; } +- if test -n "$EXEEXT"; then +- am__EXEEXT_TRUE= +- am__EXEEXT_FALSE='#' +-else +- am__EXEEXT_TRUE='#' +- am__EXEEXT_FALSE= +-fi +- +-if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then +- as_fn_error $? "conditional \"AMDEP\" was never defined. +-Usually this means the macro was only invoked conditionally." "$LINENO" 5 +-fi +-if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then +- as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +-Usually this means the macro was only invoked conditionally." "$LINENO" 5 +-fi +-if test -z "${GL_COND_LIBTOOL_TRUE}" && test -z "${GL_COND_LIBTOOL_FALSE}"; then +- as_fn_error $? "conditional \"GL_COND_LIBTOOL\" was never defined. +-Usually this means the macro was only invoked conditionally." "$LINENO" 5 +-fi +-if test -z "${GL_GENERATE_STDINT_H_TRUE}" && test -z "${GL_GENERATE_STDINT_H_FALSE}"; then +- as_fn_error $? "conditional \"GL_GENERATE_STDINT_H\" was never defined. +-Usually this means the macro was only invoked conditionally." "$LINENO" 5 +-fi +-if test -z "${GL_GENERATE_STDBOOL_H_TRUE}" && test -z "${GL_GENERATE_STDBOOL_H_FALSE}"; then +- as_fn_error $? "conditional \"GL_GENERATE_STDBOOL_H\" was never defined. +-Usually this means the macro was only invoked conditionally." "$LINENO" 5 +-fi +-if test -z "${GL_GENERATE_STDDEF_H_TRUE}" && test -z "${GL_GENERATE_STDDEF_H_FALSE}"; then +- as_fn_error $? "conditional \"GL_GENERATE_STDDEF_H\" was never defined. +-Usually this means the macro was only invoked conditionally." "$LINENO" 5 +-fi +-if test -z "${LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE}" && test -z "${LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_FALSE}"; then +- as_fn_error $? "conditional \"LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH\" was never defined. +-Usually this means the macro was only invoked conditionally." "$LINENO" 5 +-fi +- +- gl_libobjs= +- gl_ltlibobjs= +- if test -n "$gl_LIBOBJS"; then +- # Remove the extension. +- sed_drop_objext='s/\.o$//;s/\.obj$//' +- for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do +- gl_libobjs="$gl_libobjs $i.$ac_objext" +- gl_ltlibobjs="$gl_ltlibobjs $i.lo" +- done +- fi +- gl_LIBOBJS=$gl_libobjs +- +- gl_LTLIBOBJS=$gl_ltlibobjs +- +- +- +-: "${CONFIG_STATUS=./config.status}" +-ac_write_fail=0 +-ac_clean_files_save=$ac_clean_files +-ac_clean_files="$ac_clean_files $CONFIG_STATUS" +-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +-as_write_fail=0 +-cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +-#! $SHELL +-# Generated by $as_me. +-# Run this file to recreate the current configuration. +-# Compiler output produced by configure, useful for debugging +-# configure, is in config.log if it exists. +- +-debug=false +-ac_cs_recheck=false +-ac_cs_silent=false +- +-SHELL=\${CONFIG_SHELL-$SHELL} +-export SHELL +-_ASEOF +-cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +-## -------------------- ## +-## M4sh Initialization. ## +-## -------------------- ## +- +-# Be more Bourne compatible +-DUALCASE=1; export DUALCASE # for MKS sh +-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +- emulate sh +- NULLCMD=: +- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which +- # is contrary to our usage. Disable this feature. +- alias -g '${1+"$@"}'='"$@"' +- setopt NO_GLOB_SUBST +-else +- case `(set -o) 2>/dev/null` in #( +- *posix*) : +- set -o posix ;; #( +- *) : +- ;; +-esac +-fi +- +- +-as_nl=' +-' +-export as_nl +-# Printing a long string crashes Solaris 7 /usr/bin/printf. +-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +-# Prefer a ksh shell builtin over an external printf program on Solaris, +-# but without wasting forks for bash or zsh. +-if test -z "$BASH_VERSION$ZSH_VERSION" \ +- && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then +- as_echo='print -r --' +- as_echo_n='print -rn --' +-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then +- as_echo='printf %s\n' +- as_echo_n='printf %s' +-else +- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then +- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' +- as_echo_n='/usr/ucb/echo -n' +- else +- as_echo_body='eval expr "X$1" : "X\\(.*\\)"' +- as_echo_n_body='eval +- arg=$1; +- case $arg in #( +- *"$as_nl"*) +- expr "X$arg" : "X\\(.*\\)$as_nl"; +- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; +- esac; +- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" +- ' +- export as_echo_n_body +- as_echo_n='sh -c $as_echo_n_body as_echo' +- fi +- export as_echo_body +- as_echo='sh -c $as_echo_body as_echo' +-fi +- +-# The user is always right. +-if test "${PATH_SEPARATOR+set}" != set; then +- PATH_SEPARATOR=: +- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { +- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || +- PATH_SEPARATOR=';' +- } +-fi +- +- +-# IFS +-# We need space, tab and new line, in precisely that order. Quoting is +-# there to prevent editors from complaining about space-tab. +-# (If _AS_PATH_WALK were called with IFS unset, it would disable word +-# splitting by setting IFS to empty value.) +-IFS=" "" $as_nl" +- +-# Find who we are. Look in the path if we contain no directory separator. +-as_myself= +-case $0 in #(( +- *[\\/]* ) as_myself=$0 ;; +- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +-for as_dir in $PATH +-do +- IFS=$as_save_IFS +- test -z "$as_dir" && as_dir=. +- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +- done +-IFS=$as_save_IFS +- +- ;; +-esac +-# We did not find ourselves, most probably we were run as `sh COMMAND' +-# in which case we are not to be found in the path. +-if test "x$as_myself" = x; then +- as_myself=$0 +-fi +-if test ! -f "$as_myself"; then +- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 +- exit 1 +-fi +- +-# Unset variables that we do not need and which cause bugs (e.g. in +-# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +-# suppresses any "Segmentation fault" message there. '((' could +-# trigger a bug in pdksh 5.2.14. +-for as_var in BASH_ENV ENV MAIL MAILPATH +-do eval test x\${$as_var+set} = xset \ +- && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +-done +-PS1='$ ' +-PS2='> ' +-PS4='+ ' +- +-# NLS nuisances. +-LC_ALL=C +-export LC_ALL +-LANGUAGE=C +-export LANGUAGE +- +-# CDPATH. +-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +- +- +-# as_fn_error STATUS ERROR [LINENO LOG_FD] +-# ---------------------------------------- +-# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +-# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +-# script with STATUS, using 1 if that was 0. +-as_fn_error () +-{ +- as_status=$1; test $as_status -eq 0 && as_status=1 +- if test "$4"; then +- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 +- fi +- $as_echo "$as_me: error: $2" >&2 +- as_fn_exit $as_status +-} # as_fn_error +- +- +-# as_fn_set_status STATUS +-# ----------------------- +-# Set $? to STATUS, without forking. +-as_fn_set_status () +-{ +- return $1 +-} # as_fn_set_status +- +-# as_fn_exit STATUS +-# ----------------- +-# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +-as_fn_exit () +-{ +- set +e +- as_fn_set_status $1 +- exit $1 +-} # as_fn_exit +- +-# as_fn_unset VAR +-# --------------- +-# Portably unset VAR. +-as_fn_unset () +-{ +- { eval $1=; unset $1;} +-} +-as_unset=as_fn_unset +-# as_fn_append VAR VALUE +-# ---------------------- +-# Append the text in VALUE to the end of the definition contained in VAR. Take +-# advantage of any shell optimizations that allow amortized linear growth over +-# repeated appends, instead of the typical quadratic growth present in naive +-# implementations. +-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +- eval 'as_fn_append () +- { +- eval $1+=\$2 +- }' +-else +- as_fn_append () +- { +- eval $1=\$$1\$2 +- } +-fi # as_fn_append +- +-# as_fn_arith ARG... +-# ------------------ +-# Perform arithmetic evaluation on the ARGs, and store the result in the +-# global $as_val. Take advantage of shells that can avoid forks. The arguments +-# must be portable across $(()) and expr. +-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +- eval 'as_fn_arith () +- { +- as_val=$(( $* )) +- }' +-else +- as_fn_arith () +- { +- as_val=`expr "$@" || test $? -eq 1` +- } +-fi # as_fn_arith +- +- +-if expr a : '\(a\)' >/dev/null 2>&1 && +- test "X`expr 00001 : '.*\(...\)'`" = X001; then +- as_expr=expr +-else +- as_expr=false +-fi +- +-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then +- as_basename=basename +-else +- as_basename=false +-fi +- +-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then +- as_dirname=dirname +-else +- as_dirname=false +-fi +- +-as_me=`$as_basename -- "$0" || +-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ +- X"$0" : 'X\(//\)$' \| \ +- X"$0" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X/"$0" | +- sed '/^.*\/\([^/][^/]*\)\/*$/{ +- s//\1/ +- q +- } +- /^X\/\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\/\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- +-# Avoid depending upon Character Ranges. +-as_cr_letters='abcdefghijklmnopqrstuvwxyz' +-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +-as_cr_Letters=$as_cr_letters$as_cr_LETTERS +-as_cr_digits='0123456789' +-as_cr_alnum=$as_cr_Letters$as_cr_digits +- +-ECHO_C= ECHO_N= ECHO_T= +-case `echo -n x` in #((((( +--n*) +- case `echo 'xy\c'` in +- *c*) ECHO_T=' ';; # ECHO_T is single tab character. +- xy) ECHO_C='\c';; +- *) echo `echo ksh88 bug on AIX 6.1` > /dev/null +- ECHO_T=' ';; +- esac;; +-*) +- ECHO_N='-n';; +-esac +- +-rm -f conf$$ conf$$.exe conf$$.file +-if test -d conf$$.dir; then +- rm -f conf$$.dir/conf$$.file +-else +- rm -f conf$$.dir +- mkdir conf$$.dir 2>/dev/null +-fi +-if (echo >conf$$.file) 2>/dev/null; then +- if ln -s conf$$.file conf$$ 2>/dev/null; then +- as_ln_s='ln -s' +- # ... but there are two gotchas: +- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. +- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. +- # In both cases, we have to default to `cp -pR'. +- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || +- as_ln_s='cp -pR' +- elif ln conf$$.file conf$$ 2>/dev/null; then +- as_ln_s=ln +- else +- as_ln_s='cp -pR' +- fi +-else +- as_ln_s='cp -pR' +-fi +-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +-rmdir conf$$.dir 2>/dev/null +- +- +-# as_fn_mkdir_p +-# ------------- +-# Create "$as_dir" as a directory, including parents if necessary. +-as_fn_mkdir_p () +-{ +- +- case $as_dir in #( +- -*) as_dir=./$as_dir;; +- esac +- test -d "$as_dir" || eval $as_mkdir_p || { +- as_dirs= +- while :; do +- case $as_dir in #( +- *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( +- *) as_qdir=$as_dir;; +- esac +- as_dirs="'$as_qdir' $as_dirs" +- as_dir=`$as_dirname -- "$as_dir" || +-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$as_dir" : 'X\(//\)[^/]' \| \ +- X"$as_dir" : 'X\(//\)$' \| \ +- X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$as_dir" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- test -d "$as_dir" && break +- done +- test -z "$as_dirs" || eval "mkdir $as_dirs" +- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" +- +- +-} # as_fn_mkdir_p +-if mkdir -p . 2>/dev/null; then +- as_mkdir_p='mkdir -p "$as_dir"' +-else +- test -d ./-p && rmdir ./-p +- as_mkdir_p=false +-fi +- +- +-# as_fn_executable_p FILE +-# ----------------------- +-# Test if FILE is an executable regular file. +-as_fn_executable_p () +-{ +- test -f "$1" && test -x "$1" +-} # as_fn_executable_p +-as_test_x='test -x' +-as_executable_p=as_fn_executable_p +- +-# Sed expression to map a string onto a valid CPP name. +-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +- +-# Sed expression to map a string onto a valid variable name. +-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +- +- +-exec 6>&1 +-## ----------------------------------- ## +-## Main body of $CONFIG_STATUS script. ## +-## ----------------------------------- ## +-_ASEOF +-test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-# Save the log message, to keep $0 and so on meaningful, and to +-# report actual input values of CONFIG_FILES etc. instead of their +-# values after options handling. +-ac_log=" +-This file was extended by dummy $as_me 0, which was +-generated by GNU Autoconf 2.69. Invocation command line was +- +- CONFIG_FILES = $CONFIG_FILES +- CONFIG_HEADERS = $CONFIG_HEADERS +- CONFIG_LINKS = $CONFIG_LINKS +- CONFIG_COMMANDS = $CONFIG_COMMANDS +- $ $0 $@ +- +-on `(hostname || uname -n) 2>/dev/null | sed 1q` +-" +- +-_ACEOF +- +-case $ac_config_files in *" +-"*) set x $ac_config_files; shift; ac_config_files=$*;; +-esac +- +-case $ac_config_headers in *" +-"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +-esac +- +- +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-# Files that config.status was made for. +-config_files="$ac_config_files" +-config_headers="$ac_config_headers" +-config_commands="$ac_config_commands" +- +-_ACEOF +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-ac_cs_usage="\ +-\`$as_me' instantiates files and other configuration actions +-from templates according to the current configuration. Unless the files +-and actions are specified as TAGs, all are instantiated by default. +- +-Usage: $0 [OPTION]... [TAG]... +- +- -h, --help print this help, then exit +- -V, --version print version number and configuration settings, then exit +- --config print configuration, then exit +- -q, --quiet, --silent +- do not print progress messages +- -d, --debug don't remove temporary files +- --recheck update $as_me by reconfiguring in the same conditions +- --file=FILE[:TEMPLATE] +- instantiate the configuration file FILE +- --header=FILE[:TEMPLATE] +- instantiate the configuration header FILE +- +-Configuration files: +-$config_files +- +-Configuration headers: +-$config_headers +- +-Configuration commands: +-$config_commands +- +-Report bugs to the package provider." +- +-_ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +-ac_cs_version="\\ +-dummy config.status 0 +-configured by $0, generated by GNU Autoconf 2.69, +- with options \\"\$ac_cs_config\\" +- +-Copyright (C) 2012 Free Software Foundation, Inc. +-This config.status script is free software; the Free Software Foundation +-gives unlimited permission to copy, distribute and modify it." +- +-ac_pwd='$ac_pwd' +-srcdir='$srcdir' +-INSTALL='$INSTALL' +-MKDIR_P='$MKDIR_P' +-AWK='$AWK' +-test -n "\$AWK" || AWK=awk +-_ACEOF +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-# The default lists apply if the user does not specify any file. +-ac_need_defaults=: +-while test $# != 0 +-do +- case $1 in +- --*=?*) +- ac_option=`expr "X$1" : 'X\([^=]*\)='` +- ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` +- ac_shift=: +- ;; +- --*=) +- ac_option=`expr "X$1" : 'X\([^=]*\)='` +- ac_optarg= +- ac_shift=: +- ;; +- *) +- ac_option=$1 +- ac_optarg=$2 +- ac_shift=shift +- ;; +- esac +- +- case $ac_option in +- # Handling of the options. +- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) +- ac_cs_recheck=: ;; +- --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) +- $as_echo "$ac_cs_version"; exit ;; +- --config | --confi | --conf | --con | --co | --c ) +- $as_echo "$ac_cs_config"; exit ;; +- --debug | --debu | --deb | --de | --d | -d ) +- debug=: ;; +- --file | --fil | --fi | --f ) +- $ac_shift +- case $ac_optarg in +- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; +- '') as_fn_error $? "missing file argument" ;; +- esac +- as_fn_append CONFIG_FILES " '$ac_optarg'" +- ac_need_defaults=false;; +- --header | --heade | --head | --hea ) +- $ac_shift +- case $ac_optarg in +- *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; +- esac +- as_fn_append CONFIG_HEADERS " '$ac_optarg'" +- ac_need_defaults=false;; +- --he | --h) +- # Conflict between --help and --header +- as_fn_error $? "ambiguous option: \`$1' +-Try \`$0 --help' for more information.";; +- --help | --hel | -h ) +- $as_echo "$ac_cs_usage"; exit ;; +- -q | -quiet | --quiet | --quie | --qui | --qu | --q \ +- | -silent | --silent | --silen | --sile | --sil | --si | --s) +- ac_cs_silent=: ;; +- +- # This is an error. +- -*) as_fn_error $? "unrecognized option: \`$1' +-Try \`$0 --help' for more information." ;; +- +- *) as_fn_append ac_config_targets " $1" +- ac_need_defaults=false ;; +- +- esac +- shift +-done +- +-ac_configure_extra_args= +- +-if $ac_cs_silent; then +- exec 6>/dev/null +- ac_configure_extra_args="$ac_configure_extra_args --silent" +-fi +- +-_ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-if \$ac_cs_recheck; then +- set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +- shift +- \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 +- CONFIG_SHELL='$SHELL' +- export CONFIG_SHELL +- exec "\$@" +-fi +- +-_ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-exec 5>>config.log +-{ +- echo +- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +-## Running $as_me. ## +-_ASBOX +- $as_echo "$ac_log" +-} >&5 +- +-_ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-# +-# INIT-COMMANDS +-# +-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +- +-_ACEOF +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +- +-# Handling of arguments. +-for ac_config_target in $ac_config_targets +-do +- case $ac_config_target in +- "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; +- "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; +- "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; +- "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; +- "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;; +- +- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; +- esac +-done +- +- +-# If the user did not use the arguments to specify the items to instantiate, +-# then the envvar interface is used. Set only those that are not. +-# We use the long form for the default assignment because of an extremely +-# bizarre bug on SunOS 4.1.3. +-if $ac_need_defaults; then +- test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +- test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +- test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +-fi +- +-# Have a temporary directory for convenience. Make it in the build tree +-# simply because there is no reason against having it here, and in addition, +-# creating and moving files from /tmp can sometimes cause problems. +-# Hook for its removal unless debugging. +-# Note that there is a small window in which the directory will not be cleaned: +-# after its creation but before its name has been assigned to `$tmp'. +-$debug || +-{ +- tmp= ac_tmp= +- trap 'exit_status=$? +- : "${ac_tmp:=$tmp}" +- { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +-' 0 +- trap 'as_fn_exit 1' 1 2 13 15 +-} +-# Create a (secure) tmp directory for tmp files. +- +-{ +- tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && +- test -d "$tmp" +-} || +-{ +- tmp=./conf$$-$RANDOM +- (umask 077 && mkdir "$tmp") +-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +-ac_tmp=$tmp +- +-# Set up the scripts for CONFIG_FILES section. +-# No need to generate them if there are no CONFIG_FILES. +-# This happens for instance with `./config.status config.h'. +-if test -n "$CONFIG_FILES"; then +- +- +-ac_cr=`echo X | tr X '\015'` +-# On cygwin, bash can eat \r inside `` if the user requested igncr. +-# But we know of no other shell where ac_cr would be empty at this +-# point, so we can use a bashism as a fallback. +-if test "x$ac_cr" = x; then +- eval ac_cr=\$\'\\r\' +-fi +-ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +-if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then +- ac_cs_awk_cr='\\r' +-else +- ac_cs_awk_cr=$ac_cr +-fi +- +-echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +-_ACEOF +- +- +-{ +- echo "cat >conf$$subs.awk <<_ACEOF" && +- echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && +- echo "_ACEOF" +-} >conf$$subs.sh || +- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +-ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +-ac_delim='%!_!# ' +-for ac_last_try in false false false false false :; do +- . ./conf$$subs.sh || +- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +- +- ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` +- if test $ac_delim_n = $ac_delim_num; then +- break +- elif $ac_last_try; then +- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +- else +- ac_delim="$ac_delim!$ac_delim _$ac_delim!! " +- fi +-done +-rm -f conf$$subs.sh +- +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +-_ACEOF +-sed -n ' +-h +-s/^/S["/; s/!.*/"]=/ +-p +-g +-s/^[^!]*!// +-:repl +-t repl +-s/'"$ac_delim"'$// +-t delim +-:nl +-h +-s/\(.\{148\}\)..*/\1/ +-t more1 +-s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +-p +-n +-b repl +-:more1 +-s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +-p +-g +-s/.\{148\}// +-t nl +-:delim +-h +-s/\(.\{148\}\)..*/\1/ +-t more2 +-s/["\\]/\\&/g; s/^/"/; s/$/"/ +-p +-b +-:more2 +-s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +-p +-g +-s/.\{148\}// +-t delim +-' >$CONFIG_STATUS || ac_write_fail=1 +-rm -f conf$$subs.awk +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-_ACAWK +-cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && +- for (key in S) S_is_set[key] = 1 +- FS = "" +- +-} +-{ +- line = $ 0 +- nfields = split(line, field, "@") +- substed = 0 +- len = length(field[1]) +- for (i = 2; i < nfields; i++) { +- key = field[i] +- keylen = length(key) +- if (S_is_set[key]) { +- value = S[key] +- line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) +- len += length(value) + length(field[++i]) +- substed = 1 +- } else +- len += 1 + keylen +- } +- +- print line +-} +- +-_ACAWK +-_ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then +- sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +-else +- cat +-fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ +- || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +-_ACEOF +- +-# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +-# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +-# trailing colons and then remove the whole line if VPATH becomes empty +-# (actually we leave an empty line to preserve line numbers). +-if test "x$srcdir" = x.; then +- ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +-h +-s/// +-s/^/:/ +-s/[ ]*$/:/ +-s/:\$(srcdir):/:/g +-s/:\${srcdir}:/:/g +-s/:@srcdir@:/:/g +-s/^:*// +-s/:*$// +-x +-s/\(=[ ]*\).*/\1/ +-G +-s/\n// +-s/^[^=]*=[ ]*$// +-}' +-fi +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-fi # test -n "$CONFIG_FILES" +- +-# Set up the scripts for CONFIG_HEADERS section. +-# No need to generate them if there are no CONFIG_HEADERS. +-# This happens for instance with `./config.status Makefile'. +-if test -n "$CONFIG_HEADERS"; then +-cat >"$ac_tmp/defines.awk" <<\_ACAWK || +-BEGIN { +-_ACEOF +- +-# Transform confdefs.h into an awk script `defines.awk', embedded as +-# here-document in config.status, that substitutes the proper values into +-# config.h.in to produce config.h. +- +-# Create a delimiter string that does not exist in confdefs.h, to ease +-# handling of long lines. +-ac_delim='%!_!# ' +-for ac_last_try in false false :; do +- ac_tt=`sed -n "/$ac_delim/p" confdefs.h` +- if test -z "$ac_tt"; then +- break +- elif $ac_last_try; then +- as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 +- else +- ac_delim="$ac_delim!$ac_delim _$ac_delim!! " +- fi +-done +- +-# For the awk script, D is an array of macro values keyed by name, +-# likewise P contains macro parameters if any. Preserve backslash +-# newline sequences. +- +-ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +-sed -n ' +-s/.\{148\}/&'"$ac_delim"'/g +-t rset +-:rset +-s/^[ ]*#[ ]*define[ ][ ]*/ / +-t def +-d +-:def +-s/\\$// +-t bsnl +-s/["\\]/\\&/g +-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +-D["\1"]=" \3"/p +-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +-d +-:bsnl +-s/["\\]/\\&/g +-s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +-D["\1"]=" \3\\\\\\n"\\/p +-t cont +-s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +-t cont +-d +-:cont +-n +-s/.\{148\}/&'"$ac_delim"'/g +-t clear +-:clear +-s/\\$// +-t bsnlc +-s/["\\]/\\&/g; s/^/"/; s/$/"/p +-d +-:bsnlc +-s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +-b cont +-' >$CONFIG_STATUS || ac_write_fail=1 +- +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +- for (key in D) D_is_set[key] = 1 +- FS = "" +-} +-/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { +- line = \$ 0 +- split(line, arg, " ") +- if (arg[1] == "#") { +- defundef = arg[2] +- mac1 = arg[3] +- } else { +- defundef = substr(arg[1], 2) +- mac1 = arg[2] +- } +- split(mac1, mac2, "(") #) +- macro = mac2[1] +- prefix = substr(line, 1, index(line, defundef) - 1) +- if (D_is_set[macro]) { +- # Preserve the white space surrounding the "#". +- print prefix "define", macro P[macro] D[macro] +- next +- } else { +- # Replace #undef with comments. This is necessary, for example, +- # in the case of _POSIX_SOURCE, which is predefined and required +- # on some systems where configure will not decide to define it. +- if (defundef == "undef") { +- print "/*", prefix defundef, macro, "*/" +- next +- } +- } +-} +-{ print } +-_ACAWK +-_ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +- as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +-fi # test -n "$CONFIG_HEADERS" +- +- +-eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +-shift +-for ac_tag +-do +- case $ac_tag in +- :[FHLC]) ac_mode=$ac_tag; continue;; +- esac +- case $ac_mode$ac_tag in +- :[FHL]*:*);; +- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; +- :[FH]-) ac_tag=-:-;; +- :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; +- esac +- ac_save_IFS=$IFS +- IFS=: +- set x $ac_tag +- IFS=$ac_save_IFS +- shift +- ac_file=$1 +- shift +- +- case $ac_mode in +- :L) ac_source=$1;; +- :[FH]) +- ac_file_inputs= +- for ac_f +- do +- case $ac_f in +- -) ac_f="$ac_tmp/stdin";; +- *) # Look for the file first in the build tree, then in the source tree +- # (if the path is not absolute). The absolute path cannot be DOS-style, +- # because $ac_f cannot contain `:'. +- test -f "$ac_f" || +- case $ac_f in +- [\\/$]*) false;; +- *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; +- esac || +- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; +- esac +- case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac +- as_fn_append ac_file_inputs " '$ac_f'" +- done +- +- # Let's still pretend it is `configure' which instantiates (i.e., don't +- # use $as_me), people would be surprised to read: +- # /* config.h. Generated by config.status. */ +- configure_input='Generated from '` +- $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' +- `' by configure.' +- if test x"$ac_file" != x-; then +- configure_input="$ac_file. $configure_input" +- { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +-$as_echo "$as_me: creating $ac_file" >&6;} +- fi +- # Neutralize special characters interpreted by sed in replacement strings. +- case $configure_input in #( +- *\&* | *\|* | *\\* ) +- ac_sed_conf_input=`$as_echo "$configure_input" | +- sed 's/[\\\\&|]/\\\\&/g'`;; #( +- *) ac_sed_conf_input=$configure_input;; +- esac +- +- case $ac_tag in +- *:-:* | *:-) cat >"$ac_tmp/stdin" \ +- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; +- esac +- ;; +- esac +- +- ac_dir=`$as_dirname -- "$ac_file" || +-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$ac_file" : 'X\(//\)[^/]' \| \ +- X"$ac_file" : 'X\(//\)$' \| \ +- X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$ac_file" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- as_dir="$ac_dir"; as_fn_mkdir_p +- ac_builddir=. +- +-case "$ac_dir" in +-.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +-*) +- ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` +- # A ".." for each directory in $ac_dir_suffix. +- ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` +- case $ac_top_builddir_sub in +- "") ac_top_builddir_sub=. ac_top_build_prefix= ;; +- *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; +- esac ;; +-esac +-ac_abs_top_builddir=$ac_pwd +-ac_abs_builddir=$ac_pwd$ac_dir_suffix +-# for backward compatibility: +-ac_top_builddir=$ac_top_build_prefix +- +-case $srcdir in +- .) # We are building in place. +- ac_srcdir=. +- ac_top_srcdir=$ac_top_builddir_sub +- ac_abs_top_srcdir=$ac_pwd ;; +- [\\/]* | ?:[\\/]* ) # Absolute name. +- ac_srcdir=$srcdir$ac_dir_suffix; +- ac_top_srcdir=$srcdir +- ac_abs_top_srcdir=$srcdir ;; +- *) # Relative name. +- ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix +- ac_top_srcdir=$ac_top_build_prefix$srcdir +- ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +-esac +-ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix +- +- +- case $ac_mode in +- :F) +- # +- # CONFIG_FILE +- # +- +- case $INSTALL in +- [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; +- *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; +- esac +- ac_MKDIR_P=$MKDIR_P +- case $MKDIR_P in +- [\\/$]* | ?:[\\/]* ) ;; +- */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; +- esac +-_ACEOF +- +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-# If the template does not know about datarootdir, expand it. +-# FIXME: This hack should be removed a few years after 2.60. +-ac_datarootdir_hack=; ac_datarootdir_seen= +-ac_sed_dataroot=' +-/datarootdir/ { +- p +- q +-} +-/@datadir@/p +-/@docdir@/p +-/@infodir@/p +-/@localedir@/p +-/@mandir@/p' +-case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +-*datarootdir*) ac_datarootdir_seen=yes;; +-*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +-_ACEOF +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +- ac_datarootdir_hack=' +- s&@datadir@&$datadir&g +- s&@docdir@&$docdir&g +- s&@infodir@&$infodir&g +- s&@localedir@&$localedir&g +- s&@mandir@&$mandir&g +- s&\\\${datarootdir}&$datarootdir&g' ;; +-esac +-_ACEOF +- +-# Neutralize VPATH when `$srcdir' = `.'. +-# Shell code in configure.ac might set extrasub. +-# FIXME: do we really want to maintain this feature? +-cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +-ac_sed_extra="$ac_vpsub +-$extrasub +-_ACEOF +-cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +-:t +-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +-s|@configure_input@|$ac_sed_conf_input|;t t +-s&@top_builddir@&$ac_top_builddir_sub&;t t +-s&@top_build_prefix@&$ac_top_build_prefix&;t t +-s&@srcdir@&$ac_srcdir&;t t +-s&@abs_srcdir@&$ac_abs_srcdir&;t t +-s&@top_srcdir@&$ac_top_srcdir&;t t +-s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +-s&@builddir@&$ac_builddir&;t t +-s&@abs_builddir@&$ac_abs_builddir&;t t +-s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +-s&@INSTALL@&$ac_INSTALL&;t t +-s&@MKDIR_P@&$ac_MKDIR_P&;t t +-$ac_datarootdir_hack +-" +-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ +- >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +- +-test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && +- { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && +- { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ +- "$ac_tmp/out"`; test -z "$ac_out"; } && +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +-which seems to be undefined. Please make sure it is defined" >&5 +-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +-which seems to be undefined. Please make sure it is defined" >&2;} +- +- rm -f "$ac_tmp/stdin" +- case $ac_file in +- -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; +- *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; +- esac \ +- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +- ;; +- :H) +- # +- # CONFIG_HEADER +- # +- if test x"$ac_file" != x-; then +- { +- $as_echo "/* $configure_input */" \ +- && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" +- } >"$ac_tmp/config.h" \ +- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +- if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +-$as_echo "$as_me: $ac_file is unchanged" >&6;} +- else +- rm -f "$ac_file" +- mv "$ac_tmp/config.h" "$ac_file" \ +- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +- fi +- else +- $as_echo "/* $configure_input */" \ +- && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ +- || as_fn_error $? "could not create -" "$LINENO" 5 +- fi +-# Compute "$ac_file"'s index in $config_headers. +-_am_arg="$ac_file" +-_am_stamp_count=1 +-for _am_header in $config_headers :; do +- case $_am_header in +- $_am_arg | $_am_arg:* ) +- break ;; +- * ) +- _am_stamp_count=`expr $_am_stamp_count + 1` ;; +- esac +-done +-echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +-$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$_am_arg" : 'X\(//\)[^/]' \| \ +- X"$_am_arg" : 'X\(//\)$' \| \ +- X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$_am_arg" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'`/stamp-h$_am_stamp_count +- ;; +- +- :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +-$as_echo "$as_me: executing $ac_file commands" >&6;} +- ;; +- esac +- +- +- case $ac_file$ac_mode in +- "depfiles":C) test x"$AMDEP_TRUE" != x"" || { +- # Older Autoconf quotes --file arguments for eval, but not when files +- # are listed without --file. Let's play safe and only enable the eval +- # if we detect the quoting. +- case $CONFIG_FILES in +- *\'*) eval set x "$CONFIG_FILES" ;; +- *) set x $CONFIG_FILES ;; +- esac +- shift +- for mf +- do +- # Strip MF so we end up with the name of the file. +- mf=`echo "$mf" | sed -e 's/:.*$//'` +- # Check whether this is an Automake generated Makefile or not. +- # We used to match only the files named 'Makefile.in', but +- # some people rename them; so instead we look at the file content. +- # Grep'ing the first line is not enough: some people post-process +- # each Makefile.in and add a new line on top of each file to say so. +- # Grep'ing the whole file is not good either: AIX grep has a line +- # limit of 2048, but all sed's we know have understand at least 4000. +- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then +- dirpart=`$as_dirname -- "$mf" || +-$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$mf" : 'X\(//\)[^/]' \| \ +- X"$mf" : 'X\(//\)$' \| \ +- X"$mf" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$mf" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- else +- continue +- fi +- # Extract the definition of DEPDIR, am__include, and am__quote +- # from the Makefile without running 'make'. +- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` +- test -z "$DEPDIR" && continue +- am__include=`sed -n 's/^am__include = //p' < "$mf"` +- test -z "$am__include" && continue +- am__quote=`sed -n 's/^am__quote = //p' < "$mf"` +- # Find all dependency output files, they are included files with +- # $(DEPDIR) in their names. We invoke sed twice because it is the +- # simplest approach to changing $(DEPDIR) to its actual value in the +- # expansion. +- for file in `sed -n " +- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ +- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do +- # Make sure the directory exists. +- test -f "$dirpart/$file" && continue +- fdir=`$as_dirname -- "$file" || +-$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ +- X"$file" : 'X\(//\)[^/]' \| \ +- X"$file" : 'X\(//\)$' \| \ +- X"$file" : 'X\(/\)' \| . 2>/dev/null || +-$as_echo X"$file" | +- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)[^/].*/{ +- s//\1/ +- q +- } +- /^X\(\/\/\)$/{ +- s//\1/ +- q +- } +- /^X\(\/\).*/{ +- s//\1/ +- q +- } +- s/.*/./; q'` +- as_dir=$dirpart/$fdir; as_fn_mkdir_p +- # echo "creating $dirpart/$file" +- echo '# dummy' > "$dirpart/$file" +- done +- done +-} +- ;; +- +- esac +-done # for ac_tag +- +- +-as_fn_exit 0 +-_ACEOF +-ac_clean_files=$ac_clean_files_save +- +-test $ac_write_fail = 0 || +- as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 +- +- +-# configure is writing to config.log, and then calls config.status. +-# config.status does its own redirection, appending to config.log. +-# Unfortunately, on DOS this fails, as config.log is still kept open +-# by configure, so config.status won't be able to write to it; its +-# output is simply discarded. So we exec the FD to /dev/null, +-# effectively closing config.log, so it can be properly (re)opened and +-# appended to by config.status. When coming back to configure, we +-# need to make the FD available again. +-if test "$no_create" != yes; then +- ac_cs_success=: +- ac_config_status_args= +- test "$silent" = yes && +- ac_config_status_args="$ac_config_status_args --quiet" +- exec 5>/dev/null +- $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false +- exec 5>>config.log +- # Use ||, not &&, to avoid exiting from the if with $? = 1, which +- # would make configure fail if this is the last instruction. +- $ac_cs_success || as_fn_exit 1 +-fi +-if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +-fi +- +diff -Nuar groff-1.22.3.old/src/libs/gnulib/configure.ac groff-1.22.3/src/libs/gnulib/configure.ac +--- groff-1.22.3.old/src/libs/gnulib/configure.ac 2014-11-04 10:38:35.676518359 +0200 ++++ groff-1.22.3/src/libs/gnulib/configure.ac 1970-01-01 02:00:00.000000000 +0200 +@@ -1,143 +0,0 @@ +-# Process this file with autoconf to produce a configure script. +-# +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT 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 can find the license text of GPL2 in the internet at +-# . +- +-AC_INIT([dummy], [0]) +-AC_CONFIG_AUX_DIR([build-aux]) +-AM_INIT_AUTOMAKE +- +-AC_CONFIG_HEADERS([config.h]) +- +-AC_PROG_CC +-AC_PROG_INSTALL +-AC_PROG_MAKE_SET +- +-# For autobuild. +-AC_CANONICAL_BUILD +-AC_CANONICAL_HOST +- +-m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace +-m4_pattern_allow([^gl_ES$])dnl a valid locale name +-m4_pattern_allow([^gl_LIBOBJS$])dnl a variable +-m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable +- +-gl_PROG_AR_RANLIB +- +-AM_PROG_CC_C_O +- +-gl_USE_SYSTEM_EXTENSIONS +-AM_CONDITIONAL([GL_COND_LIBTOOL], [false]) +-gl_cond_libtool=false +-gl_libdeps= +-gl_ltlibdeps= +-AC_DEFUN([gl_INIT], [ +-gl_m4_base='m4' +- m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ])) +- m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS])) +- m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES])) +- m4_pushdef([gl_LIBSOURCES_LIST], []) +- m4_pushdef([gl_LIBSOURCES_DIR], []) +- gl_COMMON +-gl_source_base='lib' +- gl_CONFIGMAKE_PREP +- AC_REQUIRE([gl_EXTERN_INLINE]) +- gl_INTTYPES_H +- gl_INTTYPES_INCOMPLETE +- gl_LOCALCHARSET +- LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\"" +- AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT]) +- gl_MULTIARCH +- AM_STDBOOL_H +- gl_STDDEF_H +- gl_STDINT_H +- gl_LIBUNISTRING_LIBHEADER([0.9], [unitypes.h]) +- gl_LIBUNISTRING_LIBHEADER([0.9], [uniwidth.h]) +- gl_LIBUNISTRING_MODULE([0.9.4], [uniwidth/width]) +- gl_WCHAR_H +- gl_WCTYPE_H +- gl_FUNC_WCWIDTH +- if test $HAVE_WCWIDTH = 0 || test $REPLACE_WCWIDTH = 1; then +- AC_LIBOBJ([wcwidth]) +- fi +- gl_WCHAR_MODULE_INDICATOR([wcwidth]) +- m4_ifval(gl_LIBSOURCES_LIST, [ +- m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || +- for gl_file in ]gl_LIBSOURCES_LIST[ ; do +- if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then +- echo "missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file" >&2 +- exit 1 +- fi +- done])dnl +- m4_if(m4_sysval, [0], [], +- [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) +- ]) +- m4_popdef([gl_LIBSOURCES_DIR]) +- m4_popdef([gl_LIBSOURCES_LIST]) +- m4_popdef([AC_LIBSOURCES]) +- m4_popdef([AC_REPLACE_FUNCS]) +- m4_popdef([AC_LIBOBJ]) +- AC_CONFIG_COMMANDS_PRE([ +- gl_libobjs= +- gl_ltlibobjs= +- if test -n "$gl_LIBOBJS"; then +- # Remove the extension. +- sed_drop_objext='s/\.o$//;s/\.obj$//' +- for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do +- gl_libobjs="$gl_libobjs $i.$ac_objext" +- gl_ltlibobjs="$gl_ltlibobjs $i.lo" +- done +- fi +- AC_SUBST([gl_LIBOBJS], [$gl_libobjs]) +- AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs]) +- ]) +- LIBGNU_LIBDEPS="$gl_libdeps" +- AC_SUBST([LIBGNU_LIBDEPS]) +- LIBGNU_LTLIBDEPS="$gl_ltlibdeps" +- AC_SUBST([LIBGNU_LTLIBDEPS]) +-]) +- +-# Like AC_LIBOBJ, except that the module name goes +-# into gl_LIBOBJS instead of into LIBOBJS. +-AC_DEFUN([gl_LIBOBJ], [ +- AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl +- gl_LIBOBJS="$gl_LIBOBJS $1.$ac_objext" +-]) +- +-# Like AC_REPLACE_FUNCS, except that the module name goes +-# into gl_LIBOBJS instead of into LIBOBJS. +-AC_DEFUN([gl_REPLACE_FUNCS], [ +- m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl +- AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)]) +-]) +- +-# Like AC_LIBSOURCES, except the directory where the source file is +-# expected is derived from the gnulib-tool parameterization, +-# and alloca is special cased (for the alloca-opt module). +-# We could also entirely rely on EXTRA_lib..._SOURCES. +-AC_DEFUN([gl_LIBSOURCES], [ +- m4_foreach([_gl_NAME], [$1], [ +- m4_if(_gl_NAME, [alloca.c], [], [ +- m4_define([gl_LIBSOURCES_DIR], [lib]) +- m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ]) +- ]) +- ]) +-]) +- +-gl_INIT +- +-AC_CONFIG_FILES([Makefile lib/Makefile m4/Makefile]) +-AC_OUTPUT +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/config.charset groff-1.22.3/src/libs/gnulib/lib/config.charset +--- groff-1.22.3.old/src/libs/gnulib/lib/config.charset 2014-11-04 10:38:35.629518946 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/config.charset 1970-01-01 02:00:00.000000000 +0200 +@@ -1,684 +0,0 @@ +-#! /bin/sh +-# Output a system dependent table of character encoding aliases. +-# +-# Copyright (C) 2000-2004, 2006-2014 Free Software Foundation, Inc. +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2, or (at your option) +-# any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License along +-# with this program; if not, see . +-# +-# The table consists of lines of the form +-# ALIAS CANONICAL +-# +-# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". +-# ALIAS is compared in a case sensitive way. +-# +-# CANONICAL is the GNU canonical name for this character encoding. +-# It must be an encoding supported by libiconv. Support by GNU libc is +-# also desirable. CANONICAL is case insensitive. Usually an upper case +-# MIME charset name is preferred. +-# The current list of GNU canonical charset names is as follows. +-# +-# name MIME? used by which systems +-# (darwin = Mac OS X, woe32 = native Windows) +-# +-# ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin cygwin +-# ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +-# ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +-# ISO-8859-3 Y glibc solaris cygwin +-# ISO-8859-4 Y osf solaris freebsd netbsd openbsd darwin +-# ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin +-# ISO-8859-6 Y glibc aix hpux solaris cygwin +-# ISO-8859-7 Y glibc aix hpux irix osf solaris netbsd openbsd darwin cygwin +-# ISO-8859-8 Y glibc aix hpux osf solaris cygwin +-# ISO-8859-9 Y glibc aix hpux irix osf solaris darwin cygwin +-# ISO-8859-13 glibc netbsd openbsd darwin cygwin +-# ISO-8859-14 glibc cygwin +-# ISO-8859-15 glibc aix osf solaris freebsd netbsd openbsd darwin cygwin +-# KOI8-R Y glibc solaris freebsd netbsd openbsd darwin +-# KOI8-U Y glibc freebsd netbsd openbsd darwin cygwin +-# KOI8-T glibc +-# CP437 dos +-# CP775 dos +-# CP850 aix osf dos +-# CP852 dos +-# CP855 dos +-# CP856 aix +-# CP857 dos +-# CP861 dos +-# CP862 dos +-# CP864 dos +-# CP865 dos +-# CP866 freebsd netbsd openbsd darwin dos +-# CP869 dos +-# CP874 woe32 dos +-# CP922 aix +-# CP932 aix cygwin woe32 dos +-# CP943 aix +-# CP949 osf darwin woe32 dos +-# CP950 woe32 dos +-# CP1046 aix +-# CP1124 aix +-# CP1125 dos +-# CP1129 aix +-# CP1131 darwin +-# CP1250 woe32 +-# CP1251 glibc solaris netbsd openbsd darwin cygwin woe32 +-# CP1252 aix woe32 +-# CP1253 woe32 +-# CP1254 woe32 +-# CP1255 glibc woe32 +-# CP1256 woe32 +-# CP1257 woe32 +-# GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin +-# EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin +-# EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin +-# EUC-TW glibc aix hpux irix osf solaris netbsd +-# BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin cygwin +-# BIG5-HKSCS glibc solaris darwin +-# GBK glibc aix osf solaris darwin cygwin woe32 dos +-# GB18030 glibc solaris netbsd darwin +-# SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin +-# JOHAB glibc solaris woe32 +-# TIS-620 glibc aix hpux osf solaris cygwin +-# VISCII Y glibc +-# TCVN5712-1 glibc +-# ARMSCII-8 glibc darwin +-# GEORGIAN-PS glibc cygwin +-# PT154 glibc +-# HP-ROMAN8 hpux +-# HP-ARABIC8 hpux +-# HP-GREEK8 hpux +-# HP-HEBREW8 hpux +-# HP-TURKISH8 hpux +-# HP-KANA8 hpux +-# DEC-KANJI osf +-# DEC-HANYU osf +-# UTF-8 Y glibc aix hpux osf solaris netbsd darwin cygwin +-# +-# Note: Names which are not marked as being a MIME name should not be used in +-# Internet protocols for information interchange (mail, news, etc.). +-# +-# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications +-# must understand both names and treat them as equivalent. +-# +-# The first argument passed to this file is the canonical host specification, +-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +-# or +-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +- +-host="$1" +-os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` +-echo "# This file contains a table of character encoding aliases," +-echo "# suitable for operating system '${os}'." +-echo "# It was automatically generated from config.charset." +-# List of references, updated during installation: +-echo "# Packages using this file: " +-case "$os" in +- linux-gnulibc1*) +- # Linux libc5 doesn't have nl_langinfo(CODESET); therefore +- # localcharset.c falls back to using the full locale name +- # from the environment variables. +- echo "C ASCII" +- echo "POSIX ASCII" +- for l in af af_ZA ca ca_ES da da_DK de de_AT de_BE de_CH de_DE de_LU \ +- en en_AU en_BW en_CA en_DK en_GB en_IE en_NZ en_US en_ZA \ +- en_ZW es es_AR es_BO es_CL es_CO es_DO es_EC es_ES es_GT \ +- es_HN es_MX es_PA es_PE es_PY es_SV es_US es_UY es_VE et \ +- et_EE eu eu_ES fi fi_FI fo fo_FO fr fr_BE fr_CA fr_CH fr_FR \ +- fr_LU ga ga_IE gl gl_ES id id_ID in in_ID is is_IS it it_CH \ +- it_IT kl kl_GL nl nl_BE nl_NL no no_NO pt pt_BR pt_PT sv \ +- sv_FI sv_SE; do +- echo "$l ISO-8859-1" +- echo "$l.iso-8859-1 ISO-8859-1" +- echo "$l.iso-8859-15 ISO-8859-15" +- echo "$l.iso-8859-15@euro ISO-8859-15" +- echo "$l@euro ISO-8859-15" +- echo "$l.cp-437 CP437" +- echo "$l.cp-850 CP850" +- echo "$l.cp-1252 CP1252" +- echo "$l.cp-1252@euro CP1252" +- #echo "$l.atari-st ATARI-ST" # not a commonly used encoding +- echo "$l.utf-8 UTF-8" +- echo "$l.utf-8@euro UTF-8" +- done +- for l in cs cs_CZ hr hr_HR hu hu_HU pl pl_PL ro ro_RO sk sk_SK sl \ +- sl_SI sr sr_CS sr_YU; do +- echo "$l ISO-8859-2" +- echo "$l.iso-8859-2 ISO-8859-2" +- echo "$l.cp-852 CP852" +- echo "$l.cp-1250 CP1250" +- echo "$l.utf-8 UTF-8" +- done +- for l in mk mk_MK ru ru_RU; do +- echo "$l ISO-8859-5" +- echo "$l.iso-8859-5 ISO-8859-5" +- echo "$l.koi8-r KOI8-R" +- echo "$l.cp-866 CP866" +- echo "$l.cp-1251 CP1251" +- echo "$l.utf-8 UTF-8" +- done +- for l in ar ar_SA; do +- echo "$l ISO-8859-6" +- echo "$l.iso-8859-6 ISO-8859-6" +- echo "$l.cp-864 CP864" +- #echo "$l.cp-868 CP868" # not a commonly used encoding +- echo "$l.cp-1256 CP1256" +- echo "$l.utf-8 UTF-8" +- done +- for l in el el_GR gr gr_GR; do +- echo "$l ISO-8859-7" +- echo "$l.iso-8859-7 ISO-8859-7" +- echo "$l.cp-869 CP869" +- echo "$l.cp-1253 CP1253" +- echo "$l.cp-1253@euro CP1253" +- echo "$l.utf-8 UTF-8" +- echo "$l.utf-8@euro UTF-8" +- done +- for l in he he_IL iw iw_IL; do +- echo "$l ISO-8859-8" +- echo "$l.iso-8859-8 ISO-8859-8" +- echo "$l.cp-862 CP862" +- echo "$l.cp-1255 CP1255" +- echo "$l.utf-8 UTF-8" +- done +- for l in tr tr_TR; do +- echo "$l ISO-8859-9" +- echo "$l.iso-8859-9 ISO-8859-9" +- echo "$l.cp-857 CP857" +- echo "$l.cp-1254 CP1254" +- echo "$l.utf-8 UTF-8" +- done +- for l in lt lt_LT lv lv_LV; do +- #echo "$l BALTIC" # not a commonly used encoding, wrong encoding name +- echo "$l ISO-8859-13" +- done +- for l in ru_UA uk uk_UA; do +- echo "$l KOI8-U" +- done +- for l in zh zh_CN; do +- #echo "$l GB_2312-80" # not a commonly used encoding, wrong encoding name +- echo "$l GB2312" +- done +- for l in ja ja_JP ja_JP.EUC; do +- echo "$l EUC-JP" +- done +- for l in ko ko_KR; do +- echo "$l EUC-KR" +- done +- for l in th th_TH; do +- echo "$l TIS-620" +- done +- for l in fa fa_IR; do +- #echo "$l ISIRI-3342" # a broken encoding +- echo "$l.utf-8 UTF-8" +- done +- ;; +- linux* | *-gnu*) +- # With glibc-2.1 or newer, we don't need any canonicalization, +- # because glibc has iconv and both glibc and libiconv support all +- # GNU canonical names directly. Therefore, the Makefile does not +- # need to install the alias file at all. +- # The following applies only to glibc-2.0.x and older libcs. +- echo "ISO_646.IRV:1983 ASCII" +- ;; +- aix*) +- echo "ISO8859-1 ISO-8859-1" +- echo "ISO8859-2 ISO-8859-2" +- echo "ISO8859-5 ISO-8859-5" +- echo "ISO8859-6 ISO-8859-6" +- echo "ISO8859-7 ISO-8859-7" +- echo "ISO8859-8 ISO-8859-8" +- echo "ISO8859-9 ISO-8859-9" +- echo "ISO8859-15 ISO-8859-15" +- echo "IBM-850 CP850" +- echo "IBM-856 CP856" +- echo "IBM-921 ISO-8859-13" +- echo "IBM-922 CP922" +- echo "IBM-932 CP932" +- echo "IBM-943 CP943" +- echo "IBM-1046 CP1046" +- echo "IBM-1124 CP1124" +- echo "IBM-1129 CP1129" +- echo "IBM-1252 CP1252" +- echo "IBM-eucCN GB2312" +- echo "IBM-eucJP EUC-JP" +- echo "IBM-eucKR EUC-KR" +- echo "IBM-eucTW EUC-TW" +- echo "big5 BIG5" +- echo "GBK GBK" +- echo "TIS-620 TIS-620" +- echo "UTF-8 UTF-8" +- ;; +- hpux*) +- echo "iso88591 ISO-8859-1" +- echo "iso88592 ISO-8859-2" +- echo "iso88595 ISO-8859-5" +- echo "iso88596 ISO-8859-6" +- echo "iso88597 ISO-8859-7" +- echo "iso88598 ISO-8859-8" +- echo "iso88599 ISO-8859-9" +- echo "iso885915 ISO-8859-15" +- echo "roman8 HP-ROMAN8" +- echo "arabic8 HP-ARABIC8" +- echo "greek8 HP-GREEK8" +- echo "hebrew8 HP-HEBREW8" +- echo "turkish8 HP-TURKISH8" +- echo "kana8 HP-KANA8" +- echo "tis620 TIS-620" +- echo "big5 BIG5" +- echo "eucJP EUC-JP" +- echo "eucKR EUC-KR" +- echo "eucTW EUC-TW" +- echo "hp15CN GB2312" +- #echo "ccdc ?" # what is this? +- echo "SJIS SHIFT_JIS" +- echo "utf8 UTF-8" +- ;; +- irix*) +- echo "ISO8859-1 ISO-8859-1" +- echo "ISO8859-2 ISO-8859-2" +- echo "ISO8859-5 ISO-8859-5" +- echo "ISO8859-7 ISO-8859-7" +- echo "ISO8859-9 ISO-8859-9" +- echo "eucCN GB2312" +- echo "eucJP EUC-JP" +- echo "eucKR EUC-KR" +- echo "eucTW EUC-TW" +- ;; +- osf*) +- echo "ISO8859-1 ISO-8859-1" +- echo "ISO8859-2 ISO-8859-2" +- echo "ISO8859-4 ISO-8859-4" +- echo "ISO8859-5 ISO-8859-5" +- echo "ISO8859-7 ISO-8859-7" +- echo "ISO8859-8 ISO-8859-8" +- echo "ISO8859-9 ISO-8859-9" +- echo "ISO8859-15 ISO-8859-15" +- echo "cp850 CP850" +- echo "big5 BIG5" +- echo "dechanyu DEC-HANYU" +- echo "dechanzi GB2312" +- echo "deckanji DEC-KANJI" +- echo "deckorean EUC-KR" +- echo "eucJP EUC-JP" +- echo "eucKR EUC-KR" +- echo "eucTW EUC-TW" +- echo "GBK GBK" +- echo "KSC5601 CP949" +- echo "sdeckanji EUC-JP" +- echo "SJIS SHIFT_JIS" +- echo "TACTIS TIS-620" +- echo "UTF-8 UTF-8" +- ;; +- solaris*) +- echo "646 ASCII" +- echo "ISO8859-1 ISO-8859-1" +- echo "ISO8859-2 ISO-8859-2" +- echo "ISO8859-3 ISO-8859-3" +- echo "ISO8859-4 ISO-8859-4" +- echo "ISO8859-5 ISO-8859-5" +- echo "ISO8859-6 ISO-8859-6" +- echo "ISO8859-7 ISO-8859-7" +- echo "ISO8859-8 ISO-8859-8" +- echo "ISO8859-9 ISO-8859-9" +- echo "ISO8859-15 ISO-8859-15" +- echo "koi8-r KOI8-R" +- echo "ansi-1251 CP1251" +- echo "BIG5 BIG5" +- echo "Big5-HKSCS BIG5-HKSCS" +- echo "gb2312 GB2312" +- echo "GBK GBK" +- echo "GB18030 GB18030" +- echo "cns11643 EUC-TW" +- echo "5601 EUC-KR" +- echo "ko_KR.johap92 JOHAB" +- echo "eucJP EUC-JP" +- echo "PCK SHIFT_JIS" +- echo "TIS620.2533 TIS-620" +- #echo "sun_eu_greek ?" # what is this? +- echo "UTF-8 UTF-8" +- ;; +- freebsd* | os2*) +- # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore +- # localcharset.c falls back to using the full locale name +- # from the environment variables. +- # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just +- # reuse FreeBSD's locale data for OS/2. +- echo "C ASCII" +- echo "US-ASCII ASCII" +- for l in la_LN lt_LN; do +- echo "$l.ASCII ASCII" +- done +- for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ +- fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ +- lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do +- echo "$l.ISO_8859-1 ISO-8859-1" +- echo "$l.DIS_8859-15 ISO-8859-15" +- done +- for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do +- echo "$l.ISO_8859-2 ISO-8859-2" +- done +- for l in la_LN lt_LT; do +- echo "$l.ISO_8859-4 ISO-8859-4" +- done +- for l in ru_RU ru_SU; do +- echo "$l.KOI8-R KOI8-R" +- echo "$l.ISO_8859-5 ISO-8859-5" +- echo "$l.CP866 CP866" +- done +- echo "uk_UA.KOI8-U KOI8-U" +- echo "zh_TW.BIG5 BIG5" +- echo "zh_TW.Big5 BIG5" +- echo "zh_CN.EUC GB2312" +- echo "ja_JP.EUC EUC-JP" +- echo "ja_JP.SJIS SHIFT_JIS" +- echo "ja_JP.Shift_JIS SHIFT_JIS" +- echo "ko_KR.EUC EUC-KR" +- ;; +- netbsd*) +- echo "646 ASCII" +- echo "ISO8859-1 ISO-8859-1" +- echo "ISO8859-2 ISO-8859-2" +- echo "ISO8859-4 ISO-8859-4" +- echo "ISO8859-5 ISO-8859-5" +- echo "ISO8859-7 ISO-8859-7" +- echo "ISO8859-13 ISO-8859-13" +- echo "ISO8859-15 ISO-8859-15" +- echo "eucCN GB2312" +- echo "eucJP EUC-JP" +- echo "eucKR EUC-KR" +- echo "eucTW EUC-TW" +- echo "BIG5 BIG5" +- echo "SJIS SHIFT_JIS" +- ;; +- openbsd*) +- echo "646 ASCII" +- echo "ISO8859-1 ISO-8859-1" +- echo "ISO8859-2 ISO-8859-2" +- echo "ISO8859-4 ISO-8859-4" +- echo "ISO8859-5 ISO-8859-5" +- echo "ISO8859-7 ISO-8859-7" +- echo "ISO8859-13 ISO-8859-13" +- echo "ISO8859-15 ISO-8859-15" +- ;; +- darwin[56]*) +- # Darwin 6.8 doesn't have nl_langinfo(CODESET); therefore +- # localcharset.c falls back to using the full locale name +- # from the environment variables. +- echo "C ASCII" +- for l in en_AU en_CA en_GB en_US la_LN; do +- echo "$l.US-ASCII ASCII" +- done +- for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ +- fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT nl_BE \ +- nl_NL no_NO pt_PT sv_SE; do +- echo "$l ISO-8859-1" +- echo "$l.ISO8859-1 ISO-8859-1" +- echo "$l.ISO8859-15 ISO-8859-15" +- done +- for l in la_LN; do +- echo "$l.ISO8859-1 ISO-8859-1" +- echo "$l.ISO8859-15 ISO-8859-15" +- done +- for l in cs_CZ hr_HR hu_HU la_LN pl_PL sl_SI; do +- echo "$l.ISO8859-2 ISO-8859-2" +- done +- for l in la_LN lt_LT; do +- echo "$l.ISO8859-4 ISO-8859-4" +- done +- for l in ru_RU; do +- echo "$l.KOI8-R KOI8-R" +- echo "$l.ISO8859-5 ISO-8859-5" +- echo "$l.CP866 CP866" +- done +- for l in bg_BG; do +- echo "$l.CP1251 CP1251" +- done +- echo "uk_UA.KOI8-U KOI8-U" +- echo "zh_TW.BIG5 BIG5" +- echo "zh_TW.Big5 BIG5" +- echo "zh_CN.EUC GB2312" +- echo "ja_JP.EUC EUC-JP" +- echo "ja_JP.SJIS SHIFT_JIS" +- echo "ko_KR.EUC EUC-KR" +- ;; +- darwin*) +- # Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is +- # useless: +- # - It returns the empty string when LANG is set to a locale of the +- # form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8 +- # LC_CTYPE file. +- # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by +- # the system; nl_langinfo(CODESET) returns "US-ASCII" in this case. +- # - The documentation says: +- # "... all code that calls BSD system routines should ensure +- # that the const *char parameters of these routines are in UTF-8 +- # encoding. All BSD system functions expect their string +- # parameters to be in UTF-8 encoding and nothing else." +- # It also says +- # "An additional caveat is that string parameters for files, +- # paths, and other file-system entities must be in canonical +- # UTF-8. In a canonical UTF-8 Unicode string, all decomposable +- # characters are decomposed ..." +- # but this is not true: You can pass non-decomposed UTF-8 strings +- # to file system functions, and it is the OS which will convert +- # them to decomposed UTF-8 before accessing the file system. +- # - The Apple Terminal application displays UTF-8 by default. +- # - However, other applications are free to use different encodings: +- # - xterm uses ISO-8859-1 by default. +- # - TextEdit uses MacRoman by default. +- # We prefer UTF-8 over decomposed UTF-8-MAC because one should +- # minimize the use of decomposed Unicode. Unfortunately, through the +- # Darwin file system, decomposed UTF-8 strings are leaked into user +- # space nevertheless. +- # Then there are also the locales with encodings other than US-ASCII +- # and UTF-8. These locales can be occasionally useful to users (e.g. +- # when grepping through ISO-8859-1 encoded text files), when all their +- # file names are in US-ASCII. +- echo "ISO8859-1 ISO-8859-1" +- echo "ISO8859-2 ISO-8859-2" +- echo "ISO8859-4 ISO-8859-4" +- echo "ISO8859-5 ISO-8859-5" +- echo "ISO8859-7 ISO-8859-7" +- echo "ISO8859-9 ISO-8859-9" +- echo "ISO8859-13 ISO-8859-13" +- echo "ISO8859-15 ISO-8859-15" +- echo "KOI8-R KOI8-R" +- echo "KOI8-U KOI8-U" +- echo "CP866 CP866" +- echo "CP949 CP949" +- echo "CP1131 CP1131" +- echo "CP1251 CP1251" +- echo "eucCN GB2312" +- echo "GB2312 GB2312" +- echo "eucJP EUC-JP" +- echo "eucKR EUC-KR" +- echo "Big5 BIG5" +- echo "Big5HKSCS BIG5-HKSCS" +- echo "GBK GBK" +- echo "GB18030 GB18030" +- echo "SJIS SHIFT_JIS" +- echo "ARMSCII-8 ARMSCII-8" +- echo "PT154 PT154" +- #echo "ISCII-DEV ?" +- echo "* UTF-8" +- ;; +- beos* | haiku*) +- # BeOS and Haiku have a single locale, and it has UTF-8 encoding. +- echo "* UTF-8" +- ;; +- msdosdjgpp*) +- # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore +- # localcharset.c falls back to using the full locale name +- # from the environment variables. +- echo "#" +- echo "# The encodings given here may not all be correct." +- echo "# If you find that the encoding given for your language and" +- echo "# country is not the one your DOS machine actually uses, just" +- echo "# correct it in this file, and send a mail to" +- echo "# Juan Manuel Guerrero " +- echo "# and Bruno Haible ." +- echo "#" +- echo "C ASCII" +- # ISO-8859-1 languages +- echo "ca CP850" +- echo "ca_ES CP850" +- echo "da CP865" # not CP850 ?? +- echo "da_DK CP865" # not CP850 ?? +- echo "de CP850" +- echo "de_AT CP850" +- echo "de_CH CP850" +- echo "de_DE CP850" +- echo "en CP850" +- echo "en_AU CP850" # not CP437 ?? +- echo "en_CA CP850" +- echo "en_GB CP850" +- echo "en_NZ CP437" +- echo "en_US CP437" +- echo "en_ZA CP850" # not CP437 ?? +- echo "es CP850" +- echo "es_AR CP850" +- echo "es_BO CP850" +- echo "es_CL CP850" +- echo "es_CO CP850" +- echo "es_CR CP850" +- echo "es_CU CP850" +- echo "es_DO CP850" +- echo "es_EC CP850" +- echo "es_ES CP850" +- echo "es_GT CP850" +- echo "es_HN CP850" +- echo "es_MX CP850" +- echo "es_NI CP850" +- echo "es_PA CP850" +- echo "es_PY CP850" +- echo "es_PE CP850" +- echo "es_SV CP850" +- echo "es_UY CP850" +- echo "es_VE CP850" +- echo "et CP850" +- echo "et_EE CP850" +- echo "eu CP850" +- echo "eu_ES CP850" +- echo "fi CP850" +- echo "fi_FI CP850" +- echo "fr CP850" +- echo "fr_BE CP850" +- echo "fr_CA CP850" +- echo "fr_CH CP850" +- echo "fr_FR CP850" +- echo "ga CP850" +- echo "ga_IE CP850" +- echo "gd CP850" +- echo "gd_GB CP850" +- echo "gl CP850" +- echo "gl_ES CP850" +- echo "id CP850" # not CP437 ?? +- echo "id_ID CP850" # not CP437 ?? +- echo "is CP861" # not CP850 ?? +- echo "is_IS CP861" # not CP850 ?? +- echo "it CP850" +- echo "it_CH CP850" +- echo "it_IT CP850" +- echo "lt CP775" +- echo "lt_LT CP775" +- echo "lv CP775" +- echo "lv_LV CP775" +- echo "nb CP865" # not CP850 ?? +- echo "nb_NO CP865" # not CP850 ?? +- echo "nl CP850" +- echo "nl_BE CP850" +- echo "nl_NL CP850" +- echo "nn CP865" # not CP850 ?? +- echo "nn_NO CP865" # not CP850 ?? +- echo "no CP865" # not CP850 ?? +- echo "no_NO CP865" # not CP850 ?? +- echo "pt CP850" +- echo "pt_BR CP850" +- echo "pt_PT CP850" +- echo "sv CP850" +- echo "sv_SE CP850" +- # ISO-8859-2 languages +- echo "cs CP852" +- echo "cs_CZ CP852" +- echo "hr CP852" +- echo "hr_HR CP852" +- echo "hu CP852" +- echo "hu_HU CP852" +- echo "pl CP852" +- echo "pl_PL CP852" +- echo "ro CP852" +- echo "ro_RO CP852" +- echo "sk CP852" +- echo "sk_SK CP852" +- echo "sl CP852" +- echo "sl_SI CP852" +- echo "sq CP852" +- echo "sq_AL CP852" +- echo "sr CP852" # CP852 or CP866 or CP855 ?? +- echo "sr_CS CP852" # CP852 or CP866 or CP855 ?? +- echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? +- # ISO-8859-3 languages +- echo "mt CP850" +- echo "mt_MT CP850" +- # ISO-8859-5 languages +- echo "be CP866" +- echo "be_BE CP866" +- echo "bg CP866" # not CP855 ?? +- echo "bg_BG CP866" # not CP855 ?? +- echo "mk CP866" # not CP855 ?? +- echo "mk_MK CP866" # not CP855 ?? +- echo "ru CP866" +- echo "ru_RU CP866" +- echo "uk CP1125" +- echo "uk_UA CP1125" +- # ISO-8859-6 languages +- echo "ar CP864" +- echo "ar_AE CP864" +- echo "ar_DZ CP864" +- echo "ar_EG CP864" +- echo "ar_IQ CP864" +- echo "ar_IR CP864" +- echo "ar_JO CP864" +- echo "ar_KW CP864" +- echo "ar_MA CP864" +- echo "ar_OM CP864" +- echo "ar_QA CP864" +- echo "ar_SA CP864" +- echo "ar_SY CP864" +- # ISO-8859-7 languages +- echo "el CP869" +- echo "el_GR CP869" +- # ISO-8859-8 languages +- echo "he CP862" +- echo "he_IL CP862" +- # ISO-8859-9 languages +- echo "tr CP857" +- echo "tr_TR CP857" +- # Japanese +- echo "ja CP932" +- echo "ja_JP CP932" +- # Chinese +- echo "zh_CN GBK" +- echo "zh_TW CP950" # not CP938 ?? +- # Korean +- echo "kr CP949" # not CP934 ?? +- echo "kr_KR CP949" # not CP934 ?? +- # Thai +- echo "th CP874" +- echo "th_TH CP874" +- # Other +- echo "eo CP850" +- echo "eo_EO CP850" +- ;; +-esac +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/intprops.h groff-1.22.3/src/libs/gnulib/lib/intprops.h +--- groff-1.22.3.old/src/libs/gnulib/lib/intprops.h 2014-11-04 10:38:35.629518946 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/intprops.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,320 +0,0 @@ +-/* intprops.h -- properties of integer types +- +- Copyright (C) 2001-2005, 2009-2014 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ +- +-/* Written by Paul Eggert. */ +- +-#ifndef _GL_INTPROPS_H +-#define _GL_INTPROPS_H +- +-#include +- +-/* Return an integer value, converted to the same type as the integer +- expression E after integer type promotion. V is the unconverted value. */ +-#define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) +- +-/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see +- . */ +-#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) +- +-/* The extra casts in the following macros work around compiler bugs, +- e.g., in Cray C 5.0.3.0. */ +- +-/* True if the arithmetic type T is an integer type. bool counts as +- an integer. */ +-#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) +- +-/* True if negative values of the signed integer type T use two's +- complement, ones' complement, or signed magnitude representation, +- respectively. Much GNU code assumes two's complement, but some +- people like to be portable to all possible C hosts. */ +-#define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) +-#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) +-#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) +- +-/* True if the signed integer expression E uses two's complement. */ +-#define _GL_INT_TWOS_COMPLEMENT(e) (~ _GL_INT_CONVERT (e, 0) == -1) +- +-/* True if the arithmetic type T is signed. */ +-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) +- +-/* Return 1 if the integer expression E, after integer promotion, has +- a signed type. */ +-#define _GL_INT_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) +- +- +-/* Minimum and maximum values for integer types and expressions. These +- macros have undefined behavior if T is signed and has padding bits. +- If this is a problem for you, please let us know how to fix it for +- your host. */ +- +-/* The maximum and minimum values for the integer type T. */ +-#define TYPE_MINIMUM(t) \ +- ((t) (! TYPE_SIGNED (t) \ +- ? (t) 0 \ +- : TYPE_SIGNED_MAGNITUDE (t) \ +- ? ~ (t) 0 \ +- : ~ TYPE_MAXIMUM (t))) +-#define TYPE_MAXIMUM(t) \ +- ((t) (! TYPE_SIGNED (t) \ +- ? (t) -1 \ +- : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) +- +-/* The maximum and minimum values for the type of the expression E, +- after integer promotion. E should not have side effects. */ +-#define _GL_INT_MINIMUM(e) \ +- (_GL_INT_SIGNED (e) \ +- ? - _GL_INT_TWOS_COMPLEMENT (e) - _GL_SIGNED_INT_MAXIMUM (e) \ +- : _GL_INT_CONVERT (e, 0)) +-#define _GL_INT_MAXIMUM(e) \ +- (_GL_INT_SIGNED (e) \ +- ? _GL_SIGNED_INT_MAXIMUM (e) \ +- : _GL_INT_NEGATE_CONVERT (e, 1)) +-#define _GL_SIGNED_INT_MAXIMUM(e) \ +- (((_GL_INT_CONVERT (e, 1) << (sizeof ((e) + 0) * CHAR_BIT - 2)) - 1) * 2 + 1) +- +- +-/* Return 1 if the __typeof__ keyword works. This could be done by +- 'configure', but for now it's easier to do it by hand. */ +-#if (2 <= __GNUC__ || defined __IBM__TYPEOF__ \ +- || (0x5110 <= __SUNPRO_C && !__STDC__)) +-# define _GL_HAVE___TYPEOF__ 1 +-#else +-# define _GL_HAVE___TYPEOF__ 0 +-#endif +- +-/* Return 1 if the integer type or expression T might be signed. Return 0 +- if it is definitely unsigned. This macro does not evaluate its argument, +- and expands to an integer constant expression. */ +-#if _GL_HAVE___TYPEOF__ +-# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) +-#else +-# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 +-#endif +- +-/* Bound on length of the string representing an unsigned integer +- value representable in B bits. log10 (2.0) < 146/485. The +- smallest value of B where this bound is not tight is 2621. */ +-#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) +- +-/* Bound on length of the string representing an integer type or expression T. +- Subtract 1 for the sign bit if T is signed, and then add 1 more for +- a minus sign if needed. +- +- Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is +- signed, this macro may overestimate the true bound by one byte when +- applied to unsigned types of size 2, 4, 16, ... bytes. */ +-#define INT_STRLEN_BOUND(t) \ +- (INT_BITS_STRLEN_BOUND (sizeof (t) * CHAR_BIT \ +- - _GL_SIGNED_TYPE_OR_EXPR (t)) \ +- + _GL_SIGNED_TYPE_OR_EXPR (t)) +- +-/* Bound on buffer size needed to represent an integer type or expression T, +- including the terminating null. */ +-#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) +- +- +-/* Range overflow checks. +- +- The INT__RANGE_OVERFLOW macros return 1 if the corresponding C +- operators might not yield numerically correct answers due to +- arithmetic overflow. They do not rely on undefined or +- implementation-defined behavior. Their implementations are simple +- and straightforward, but they are a bit harder to use than the +- INT__OVERFLOW macros described below. +- +- Example usage: +- +- long int i = ...; +- long int j = ...; +- if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX)) +- printf ("multiply would overflow"); +- else +- printf ("product is %ld", i * j); +- +- Restrictions on *_RANGE_OVERFLOW macros: +- +- These macros do not check for all possible numerical problems or +- undefined or unspecified behavior: they do not check for division +- by zero, for bad shift counts, or for shifting negative numbers. +- +- These macros may evaluate their arguments zero or multiple times, +- so the arguments should not have side effects. The arithmetic +- arguments (including the MIN and MAX arguments) must be of the same +- integer type after the usual arithmetic conversions, and the type +- must have minimum value MIN and maximum MAX. Unsigned types should +- use a zero MIN of the proper type. +- +- These macros are tuned for constant MIN and MAX. For commutative +- operations such as A + B, they are also tuned for constant B. */ +- +-/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic. +- See above for restrictions. */ +-#define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \ +- ((b) < 0 \ +- ? (a) < (min) - (b) \ +- : (max) - (b) < (a)) +- +-/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic. +- See above for restrictions. */ +-#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max) \ +- ((b) < 0 \ +- ? (max) + (b) < (a) \ +- : (a) < (min) + (b)) +- +-/* Return 1 if - A would overflow in [MIN,MAX] arithmetic. +- See above for restrictions. */ +-#define INT_NEGATE_RANGE_OVERFLOW(a, min, max) \ +- ((min) < 0 \ +- ? (a) < - (max) \ +- : 0 < (a)) +- +-/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. +- See above for restrictions. Avoid && and || as they tickle +- bugs in Sun C 5.11 2010/08/13 and other compilers; see +- . */ +-#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ +- ((b) < 0 \ +- ? ((a) < 0 \ +- ? (a) < (max) / (b) \ +- : (b) == -1 \ +- ? 0 \ +- : (min) / (b) < (a)) \ +- : (b) == 0 \ +- ? 0 \ +- : ((a) < 0 \ +- ? (a) < (min) / (b) \ +- : (max) / (b) < (a))) +- +-/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic. +- See above for restrictions. Do not check for division by zero. */ +-#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max) \ +- ((min) < 0 && (b) == -1 && (a) < - (max)) +- +-/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic. +- See above for restrictions. Do not check for division by zero. +- Mathematically, % should never overflow, but on x86-like hosts +- INT_MIN % -1 traps, and the C standard permits this, so treat this +- as an overflow too. */ +-#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max) \ +- INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max) +- +-/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic. +- See above for restrictions. Here, MIN and MAX are for A only, and B need +- not be of the same type as the other arguments. The C standard says that +- behavior is undefined for shifts unless 0 <= B < wordwidth, and that when +- A is negative then A << B has undefined behavior and A >> B has +- implementation-defined behavior, but do not check these other +- restrictions. */ +-#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ +- ((a) < 0 \ +- ? (a) < (min) >> (b) \ +- : (max) >> (b) < (a)) +- +- +-/* The _GL*_OVERFLOW macros have the same restrictions as the +- *_RANGE_OVERFLOW macros, except that they do not assume that operands +- (e.g., A and B) have the same type as MIN and MAX. Instead, they assume +- that the result (e.g., A + B) has that type. */ +-#define _GL_ADD_OVERFLOW(a, b, min, max) \ +- ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ +- : (a) < 0 ? (b) <= (a) + (b) \ +- : (b) < 0 ? (a) <= (a) + (b) \ +- : (a) + (b) < (b)) +-#define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ +- ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \ +- : (a) < 0 ? 1 \ +- : (b) < 0 ? (a) - (b) <= (a) \ +- : (a) < (b)) +-#define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ +- (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ +- || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) +-#define _GL_DIVIDE_OVERFLOW(a, b, min, max) \ +- ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ +- : (a) < 0 ? (b) <= (a) + (b) - 1 \ +- : (b) < 0 && (a) + (b) <= (a)) +-#define _GL_REMAINDER_OVERFLOW(a, b, min, max) \ +- ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ +- : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b) \ +- : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max)) +- +-/* Return a nonzero value if A is a mathematical multiple of B, where +- A is unsigned, B is negative, and MAX is the maximum value of A's +- type. A's type must be the same as (A % B)'s type. Normally (A % +- -B == 0) suffices, but things get tricky if -B would overflow. */ +-#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max) \ +- (((b) < -_GL_SIGNED_INT_MAXIMUM (b) \ +- ? (_GL_SIGNED_INT_MAXIMUM (b) == (max) \ +- ? (a) \ +- : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1)) \ +- : (a) % - (b)) \ +- == 0) +- +- +-/* Integer overflow checks. +- +- The INT__OVERFLOW macros return 1 if the corresponding C operators +- might not yield numerically correct answers due to arithmetic overflow. +- They work correctly on all known practical hosts, and do not rely +- on undefined behavior due to signed arithmetic overflow. +- +- Example usage: +- +- long int i = ...; +- long int j = ...; +- if (INT_MULTIPLY_OVERFLOW (i, j)) +- printf ("multiply would overflow"); +- else +- printf ("product is %ld", i * j); +- +- These macros do not check for all possible numerical problems or +- undefined or unspecified behavior: they do not check for division +- by zero, for bad shift counts, or for shifting negative numbers. +- +- These macros may evaluate their arguments zero or multiple times, so the +- arguments should not have side effects. +- +- These macros are tuned for their last argument being a constant. +- +- Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B, +- A % B, and A << B would overflow, respectively. */ +- +-#define INT_ADD_OVERFLOW(a, b) \ +- _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW) +-#define INT_SUBTRACT_OVERFLOW(a, b) \ +- _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW) +-#define INT_NEGATE_OVERFLOW(a) \ +- INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) +-#define INT_MULTIPLY_OVERFLOW(a, b) \ +- _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) +-#define INT_DIVIDE_OVERFLOW(a, b) \ +- _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW) +-#define INT_REMAINDER_OVERFLOW(a, b) \ +- _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW) +-#define INT_LEFT_SHIFT_OVERFLOW(a, b) \ +- INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ +- _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) +- +-/* Return 1 if the expression A B would overflow, +- where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test, +- assuming MIN and MAX are the minimum and maximum for the result type. +- Arguments should be free of side effects. */ +-#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ +- op_result_overflow (a, b, \ +- _GL_INT_MINIMUM (0 * (b) + (a)), \ +- _GL_INT_MAXIMUM (0 * (b) + (a))) +- +-#endif /* _GL_INTPROPS_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/inttypes.in.h groff-1.22.3/src/libs/gnulib/lib/inttypes.in.h +--- groff-1.22.3.old/src/libs/gnulib/lib/inttypes.in.h 2014-11-04 10:38:35.629518946 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/inttypes.in.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1130 +0,0 @@ +-/* Copyright (C) 2006-2014 Free Software Foundation, Inc. +- Written by Paul Eggert, Bruno Haible, Derek Price. +- This file is part of gnulib. +- +- This program is free software: you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ +- +-/* +- * ISO C 99 for platforms that lack it. +- * +- */ +- +-#if __GNUC__ >= 3 +-@PRAGMA_SYSTEM_HEADER@ +-#endif +-@PRAGMA_COLUMNS@ +- +-/* Include the original if it exists, and if this file +- has not been included yet or if this file includes gnulib stdint.h +- which in turn includes this file. +- The include_next requires a split double-inclusion guard. */ +-#if ! defined INTTYPES_H || defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H +-# if @HAVE_INTTYPES_H@ +- +- /* Some pre-C++11 implementations need this. */ +-# if defined __cplusplus && ! defined __STDC_FORMAT_MACROS +-# define __STDC_FORMAT_MACROS 1 +-# endif +- +-# @INCLUDE_NEXT@ @NEXT_INTTYPES_H@ +-# endif +-#endif +- +-#if ! defined INTTYPES_H && ! defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H +-#define INTTYPES_H +- +-/* Include or the gnulib replacement. +- But avoid namespace pollution on glibc systems. */ +-#ifndef __GLIBC__ +-# include +-#endif +-/* Get CHAR_BIT. */ +-#include +- +-#if !(INT_MIN == INT32_MIN && INT_MAX == INT32_MAX) +-# error "This file assumes that 'int' has exactly 32 bits. Please report your platform and compiler to ." +-#endif +- +-/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ +- +-/* The definition of _GL_ARG_NONNULL is copied here. */ +- +-/* The definition of _GL_WARN_ON_USE is copied here. */ +- +-/* 7.8.1 Macros for format specifiers */ +- +-#if defined _TNS_R_TARGET +- /* Tandem NonStop R series and compatible platforms released before +- July 2005 support %Ld but not %lld. */ +-# define _LONG_LONG_FORMAT_PREFIX "L" +-#else +-# define _LONG_LONG_FORMAT_PREFIX "ll" +-#endif +- +-#if !defined PRId8 || @PRI_MACROS_BROKEN@ +-# undef PRId8 +-# ifdef INT8_MAX +-# define PRId8 "d" +-# endif +-#endif +-#if !defined PRIi8 || @PRI_MACROS_BROKEN@ +-# undef PRIi8 +-# ifdef INT8_MAX +-# define PRIi8 "i" +-# endif +-#endif +-#if !defined PRIo8 || @PRI_MACROS_BROKEN@ +-# undef PRIo8 +-# ifdef UINT8_MAX +-# define PRIo8 "o" +-# endif +-#endif +-#if !defined PRIu8 || @PRI_MACROS_BROKEN@ +-# undef PRIu8 +-# ifdef UINT8_MAX +-# define PRIu8 "u" +-# endif +-#endif +-#if !defined PRIx8 || @PRI_MACROS_BROKEN@ +-# undef PRIx8 +-# ifdef UINT8_MAX +-# define PRIx8 "x" +-# endif +-#endif +-#if !defined PRIX8 || @PRI_MACROS_BROKEN@ +-# undef PRIX8 +-# ifdef UINT8_MAX +-# define PRIX8 "X" +-# endif +-#endif +-#if !defined PRId16 || @PRI_MACROS_BROKEN@ +-# undef PRId16 +-# ifdef INT16_MAX +-# define PRId16 "d" +-# endif +-#endif +-#if !defined PRIi16 || @PRI_MACROS_BROKEN@ +-# undef PRIi16 +-# ifdef INT16_MAX +-# define PRIi16 "i" +-# endif +-#endif +-#if !defined PRIo16 || @PRI_MACROS_BROKEN@ +-# undef PRIo16 +-# ifdef UINT16_MAX +-# define PRIo16 "o" +-# endif +-#endif +-#if !defined PRIu16 || @PRI_MACROS_BROKEN@ +-# undef PRIu16 +-# ifdef UINT16_MAX +-# define PRIu16 "u" +-# endif +-#endif +-#if !defined PRIx16 || @PRI_MACROS_BROKEN@ +-# undef PRIx16 +-# ifdef UINT16_MAX +-# define PRIx16 "x" +-# endif +-#endif +-#if !defined PRIX16 || @PRI_MACROS_BROKEN@ +-# undef PRIX16 +-# ifdef UINT16_MAX +-# define PRIX16 "X" +-# endif +-#endif +-#if !defined PRId32 || @PRI_MACROS_BROKEN@ +-# undef PRId32 +-# ifdef INT32_MAX +-# define PRId32 "d" +-# endif +-#endif +-#if !defined PRIi32 || @PRI_MACROS_BROKEN@ +-# undef PRIi32 +-# ifdef INT32_MAX +-# define PRIi32 "i" +-# endif +-#endif +-#if !defined PRIo32 || @PRI_MACROS_BROKEN@ +-# undef PRIo32 +-# ifdef UINT32_MAX +-# define PRIo32 "o" +-# endif +-#endif +-#if !defined PRIu32 || @PRI_MACROS_BROKEN@ +-# undef PRIu32 +-# ifdef UINT32_MAX +-# define PRIu32 "u" +-# endif +-#endif +-#if !defined PRIx32 || @PRI_MACROS_BROKEN@ +-# undef PRIx32 +-# ifdef UINT32_MAX +-# define PRIx32 "x" +-# endif +-#endif +-#if !defined PRIX32 || @PRI_MACROS_BROKEN@ +-# undef PRIX32 +-# ifdef UINT32_MAX +-# define PRIX32 "X" +-# endif +-#endif +-#ifdef INT64_MAX +-# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @INT64_MAX_EQ_LONG_MAX@) +-# define _PRI64_PREFIX "l" +-# elif defined _MSC_VER || defined __MINGW32__ +-# define _PRI64_PREFIX "I64" +-# elif @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +-# define _PRI64_PREFIX _LONG_LONG_FORMAT_PREFIX +-# endif +-# if !defined PRId64 || @PRI_MACROS_BROKEN@ +-# undef PRId64 +-# define PRId64 _PRI64_PREFIX "d" +-# endif +-# if !defined PRIi64 || @PRI_MACROS_BROKEN@ +-# undef PRIi64 +-# define PRIi64 _PRI64_PREFIX "i" +-# endif +-#endif +-#ifdef UINT64_MAX +-# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @UINT64_MAX_EQ_ULONG_MAX@) +-# define _PRIu64_PREFIX "l" +-# elif defined _MSC_VER || defined __MINGW32__ +-# define _PRIu64_PREFIX "I64" +-# elif @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +-# define _PRIu64_PREFIX _LONG_LONG_FORMAT_PREFIX +-# endif +-# if !defined PRIo64 || @PRI_MACROS_BROKEN@ +-# undef PRIo64 +-# define PRIo64 _PRIu64_PREFIX "o" +-# endif +-# if !defined PRIu64 || @PRI_MACROS_BROKEN@ +-# undef PRIu64 +-# define PRIu64 _PRIu64_PREFIX "u" +-# endif +-# if !defined PRIx64 || @PRI_MACROS_BROKEN@ +-# undef PRIx64 +-# define PRIx64 _PRIu64_PREFIX "x" +-# endif +-# if !defined PRIX64 || @PRI_MACROS_BROKEN@ +-# undef PRIX64 +-# define PRIX64 _PRIu64_PREFIX "X" +-# endif +-#endif +- +-#if !defined PRIdLEAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIdLEAST8 +-# define PRIdLEAST8 "d" +-#endif +-#if !defined PRIiLEAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIiLEAST8 +-# define PRIiLEAST8 "i" +-#endif +-#if !defined PRIoLEAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIoLEAST8 +-# define PRIoLEAST8 "o" +-#endif +-#if !defined PRIuLEAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIuLEAST8 +-# define PRIuLEAST8 "u" +-#endif +-#if !defined PRIxLEAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIxLEAST8 +-# define PRIxLEAST8 "x" +-#endif +-#if !defined PRIXLEAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIXLEAST8 +-# define PRIXLEAST8 "X" +-#endif +-#if !defined PRIdLEAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIdLEAST16 +-# define PRIdLEAST16 "d" +-#endif +-#if !defined PRIiLEAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIiLEAST16 +-# define PRIiLEAST16 "i" +-#endif +-#if !defined PRIoLEAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIoLEAST16 +-# define PRIoLEAST16 "o" +-#endif +-#if !defined PRIuLEAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIuLEAST16 +-# define PRIuLEAST16 "u" +-#endif +-#if !defined PRIxLEAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIxLEAST16 +-# define PRIxLEAST16 "x" +-#endif +-#if !defined PRIXLEAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIXLEAST16 +-# define PRIXLEAST16 "X" +-#endif +-#if !defined PRIdLEAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIdLEAST32 +-# define PRIdLEAST32 "d" +-#endif +-#if !defined PRIiLEAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIiLEAST32 +-# define PRIiLEAST32 "i" +-#endif +-#if !defined PRIoLEAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIoLEAST32 +-# define PRIoLEAST32 "o" +-#endif +-#if !defined PRIuLEAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIuLEAST32 +-# define PRIuLEAST32 "u" +-#endif +-#if !defined PRIxLEAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIxLEAST32 +-# define PRIxLEAST32 "x" +-#endif +-#if !defined PRIXLEAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIXLEAST32 +-# define PRIXLEAST32 "X" +-#endif +-#ifdef INT64_MAX +-# if !defined PRIdLEAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIdLEAST64 +-# define PRIdLEAST64 PRId64 +-# endif +-# if !defined PRIiLEAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIiLEAST64 +-# define PRIiLEAST64 PRIi64 +-# endif +-#endif +-#ifdef UINT64_MAX +-# if !defined PRIoLEAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIoLEAST64 +-# define PRIoLEAST64 PRIo64 +-# endif +-# if !defined PRIuLEAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIuLEAST64 +-# define PRIuLEAST64 PRIu64 +-# endif +-# if !defined PRIxLEAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIxLEAST64 +-# define PRIxLEAST64 PRIx64 +-# endif +-# if !defined PRIXLEAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIXLEAST64 +-# define PRIXLEAST64 PRIX64 +-# endif +-#endif +- +-#if !defined PRIdFAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIdFAST8 +-# if INT_FAST8_MAX > INT32_MAX +-# define PRIdFAST8 PRId64 +-# else +-# define PRIdFAST8 "d" +-# endif +-#endif +-#if !defined PRIiFAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIiFAST8 +-# if INT_FAST8_MAX > INT32_MAX +-# define PRIiFAST8 PRIi64 +-# else +-# define PRIiFAST8 "i" +-# endif +-#endif +-#if !defined PRIoFAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIoFAST8 +-# if UINT_FAST8_MAX > UINT32_MAX +-# define PRIoFAST8 PRIo64 +-# else +-# define PRIoFAST8 "o" +-# endif +-#endif +-#if !defined PRIuFAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIuFAST8 +-# if UINT_FAST8_MAX > UINT32_MAX +-# define PRIuFAST8 PRIu64 +-# else +-# define PRIuFAST8 "u" +-# endif +-#endif +-#if !defined PRIxFAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIxFAST8 +-# if UINT_FAST8_MAX > UINT32_MAX +-# define PRIxFAST8 PRIx64 +-# else +-# define PRIxFAST8 "x" +-# endif +-#endif +-#if !defined PRIXFAST8 || @PRI_MACROS_BROKEN@ +-# undef PRIXFAST8 +-# if UINT_FAST8_MAX > UINT32_MAX +-# define PRIXFAST8 PRIX64 +-# else +-# define PRIXFAST8 "X" +-# endif +-#endif +-#if !defined PRIdFAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIdFAST16 +-# if INT_FAST16_MAX > INT32_MAX +-# define PRIdFAST16 PRId64 +-# else +-# define PRIdFAST16 "d" +-# endif +-#endif +-#if !defined PRIiFAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIiFAST16 +-# if INT_FAST16_MAX > INT32_MAX +-# define PRIiFAST16 PRIi64 +-# else +-# define PRIiFAST16 "i" +-# endif +-#endif +-#if !defined PRIoFAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIoFAST16 +-# if UINT_FAST16_MAX > UINT32_MAX +-# define PRIoFAST16 PRIo64 +-# else +-# define PRIoFAST16 "o" +-# endif +-#endif +-#if !defined PRIuFAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIuFAST16 +-# if UINT_FAST16_MAX > UINT32_MAX +-# define PRIuFAST16 PRIu64 +-# else +-# define PRIuFAST16 "u" +-# endif +-#endif +-#if !defined PRIxFAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIxFAST16 +-# if UINT_FAST16_MAX > UINT32_MAX +-# define PRIxFAST16 PRIx64 +-# else +-# define PRIxFAST16 "x" +-# endif +-#endif +-#if !defined PRIXFAST16 || @PRI_MACROS_BROKEN@ +-# undef PRIXFAST16 +-# if UINT_FAST16_MAX > UINT32_MAX +-# define PRIXFAST16 PRIX64 +-# else +-# define PRIXFAST16 "X" +-# endif +-#endif +-#if !defined PRIdFAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIdFAST32 +-# if INT_FAST32_MAX > INT32_MAX +-# define PRIdFAST32 PRId64 +-# else +-# define PRIdFAST32 "d" +-# endif +-#endif +-#if !defined PRIiFAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIiFAST32 +-# if INT_FAST32_MAX > INT32_MAX +-# define PRIiFAST32 PRIi64 +-# else +-# define PRIiFAST32 "i" +-# endif +-#endif +-#if !defined PRIoFAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIoFAST32 +-# if UINT_FAST32_MAX > UINT32_MAX +-# define PRIoFAST32 PRIo64 +-# else +-# define PRIoFAST32 "o" +-# endif +-#endif +-#if !defined PRIuFAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIuFAST32 +-# if UINT_FAST32_MAX > UINT32_MAX +-# define PRIuFAST32 PRIu64 +-# else +-# define PRIuFAST32 "u" +-# endif +-#endif +-#if !defined PRIxFAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIxFAST32 +-# if UINT_FAST32_MAX > UINT32_MAX +-# define PRIxFAST32 PRIx64 +-# else +-# define PRIxFAST32 "x" +-# endif +-#endif +-#if !defined PRIXFAST32 || @PRI_MACROS_BROKEN@ +-# undef PRIXFAST32 +-# if UINT_FAST32_MAX > UINT32_MAX +-# define PRIXFAST32 PRIX64 +-# else +-# define PRIXFAST32 "X" +-# endif +-#endif +-#ifdef INT64_MAX +-# if !defined PRIdFAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIdFAST64 +-# define PRIdFAST64 PRId64 +-# endif +-# if !defined PRIiFAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIiFAST64 +-# define PRIiFAST64 PRIi64 +-# endif +-#endif +-#ifdef UINT64_MAX +-# if !defined PRIoFAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIoFAST64 +-# define PRIoFAST64 PRIo64 +-# endif +-# if !defined PRIuFAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIuFAST64 +-# define PRIuFAST64 PRIu64 +-# endif +-# if !defined PRIxFAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIxFAST64 +-# define PRIxFAST64 PRIx64 +-# endif +-# if !defined PRIXFAST64 || @PRI_MACROS_BROKEN@ +-# undef PRIXFAST64 +-# define PRIXFAST64 PRIX64 +-# endif +-#endif +- +-#if !defined PRIdMAX || @PRI_MACROS_BROKEN@ +-# undef PRIdMAX +-# if @INT32_MAX_LT_INTMAX_MAX@ +-# define PRIdMAX PRId64 +-# else +-# define PRIdMAX "ld" +-# endif +-#endif +-#if !defined PRIiMAX || @PRI_MACROS_BROKEN@ +-# undef PRIiMAX +-# if @INT32_MAX_LT_INTMAX_MAX@ +-# define PRIiMAX PRIi64 +-# else +-# define PRIiMAX "li" +-# endif +-#endif +-#if !defined PRIoMAX || @PRI_MACROS_BROKEN@ +-# undef PRIoMAX +-# if @UINT32_MAX_LT_UINTMAX_MAX@ +-# define PRIoMAX PRIo64 +-# else +-# define PRIoMAX "lo" +-# endif +-#endif +-#if !defined PRIuMAX || @PRI_MACROS_BROKEN@ +-# undef PRIuMAX +-# if @UINT32_MAX_LT_UINTMAX_MAX@ +-# define PRIuMAX PRIu64 +-# else +-# define PRIuMAX "lu" +-# endif +-#endif +-#if !defined PRIxMAX || @PRI_MACROS_BROKEN@ +-# undef PRIxMAX +-# if @UINT32_MAX_LT_UINTMAX_MAX@ +-# define PRIxMAX PRIx64 +-# else +-# define PRIxMAX "lx" +-# endif +-#endif +-#if !defined PRIXMAX || @PRI_MACROS_BROKEN@ +-# undef PRIXMAX +-# if @UINT32_MAX_LT_UINTMAX_MAX@ +-# define PRIXMAX PRIX64 +-# else +-# define PRIXMAX "lX" +-# endif +-#endif +- +-#if !defined PRIdPTR || @PRI_MACROS_BROKEN@ +-# undef PRIdPTR +-# ifdef INTPTR_MAX +-# define PRIdPTR @PRIPTR_PREFIX@ "d" +-# endif +-#endif +-#if !defined PRIiPTR || @PRI_MACROS_BROKEN@ +-# undef PRIiPTR +-# ifdef INTPTR_MAX +-# define PRIiPTR @PRIPTR_PREFIX@ "i" +-# endif +-#endif +-#if !defined PRIoPTR || @PRI_MACROS_BROKEN@ +-# undef PRIoPTR +-# ifdef UINTPTR_MAX +-# define PRIoPTR @PRIPTR_PREFIX@ "o" +-# endif +-#endif +-#if !defined PRIuPTR || @PRI_MACROS_BROKEN@ +-# undef PRIuPTR +-# ifdef UINTPTR_MAX +-# define PRIuPTR @PRIPTR_PREFIX@ "u" +-# endif +-#endif +-#if !defined PRIxPTR || @PRI_MACROS_BROKEN@ +-# undef PRIxPTR +-# ifdef UINTPTR_MAX +-# define PRIxPTR @PRIPTR_PREFIX@ "x" +-# endif +-#endif +-#if !defined PRIXPTR || @PRI_MACROS_BROKEN@ +-# undef PRIXPTR +-# ifdef UINTPTR_MAX +-# define PRIXPTR @PRIPTR_PREFIX@ "X" +-# endif +-#endif +- +-#if !defined SCNd8 || @PRI_MACROS_BROKEN@ +-# undef SCNd8 +-# ifdef INT8_MAX +-# define SCNd8 "hhd" +-# endif +-#endif +-#if !defined SCNi8 || @PRI_MACROS_BROKEN@ +-# undef SCNi8 +-# ifdef INT8_MAX +-# define SCNi8 "hhi" +-# endif +-#endif +-#if !defined SCNo8 || @PRI_MACROS_BROKEN@ +-# undef SCNo8 +-# ifdef UINT8_MAX +-# define SCNo8 "hho" +-# endif +-#endif +-#if !defined SCNu8 || @PRI_MACROS_BROKEN@ +-# undef SCNu8 +-# ifdef UINT8_MAX +-# define SCNu8 "hhu" +-# endif +-#endif +-#if !defined SCNx8 || @PRI_MACROS_BROKEN@ +-# undef SCNx8 +-# ifdef UINT8_MAX +-# define SCNx8 "hhx" +-# endif +-#endif +-#if !defined SCNd16 || @PRI_MACROS_BROKEN@ +-# undef SCNd16 +-# ifdef INT16_MAX +-# define SCNd16 "hd" +-# endif +-#endif +-#if !defined SCNi16 || @PRI_MACROS_BROKEN@ +-# undef SCNi16 +-# ifdef INT16_MAX +-# define SCNi16 "hi" +-# endif +-#endif +-#if !defined SCNo16 || @PRI_MACROS_BROKEN@ +-# undef SCNo16 +-# ifdef UINT16_MAX +-# define SCNo16 "ho" +-# endif +-#endif +-#if !defined SCNu16 || @PRI_MACROS_BROKEN@ +-# undef SCNu16 +-# ifdef UINT16_MAX +-# define SCNu16 "hu" +-# endif +-#endif +-#if !defined SCNx16 || @PRI_MACROS_BROKEN@ +-# undef SCNx16 +-# ifdef UINT16_MAX +-# define SCNx16 "hx" +-# endif +-#endif +-#if !defined SCNd32 || @PRI_MACROS_BROKEN@ +-# undef SCNd32 +-# ifdef INT32_MAX +-# define SCNd32 "d" +-# endif +-#endif +-#if !defined SCNi32 || @PRI_MACROS_BROKEN@ +-# undef SCNi32 +-# ifdef INT32_MAX +-# define SCNi32 "i" +-# endif +-#endif +-#if !defined SCNo32 || @PRI_MACROS_BROKEN@ +-# undef SCNo32 +-# ifdef UINT32_MAX +-# define SCNo32 "o" +-# endif +-#endif +-#if !defined SCNu32 || @PRI_MACROS_BROKEN@ +-# undef SCNu32 +-# ifdef UINT32_MAX +-# define SCNu32 "u" +-# endif +-#endif +-#if !defined SCNx32 || @PRI_MACROS_BROKEN@ +-# undef SCNx32 +-# ifdef UINT32_MAX +-# define SCNx32 "x" +-# endif +-#endif +-#ifdef INT64_MAX +-# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @INT64_MAX_EQ_LONG_MAX@) +-# define _SCN64_PREFIX "l" +-# elif defined _MSC_VER || defined __MINGW32__ +-# define _SCN64_PREFIX "I64" +-# elif @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +-# define _SCN64_PREFIX _LONG_LONG_FORMAT_PREFIX +-# endif +-# if !defined SCNd64 || @PRI_MACROS_BROKEN@ +-# undef SCNd64 +-# define SCNd64 _SCN64_PREFIX "d" +-# endif +-# if !defined SCNi64 || @PRI_MACROS_BROKEN@ +-# undef SCNi64 +-# define SCNi64 _SCN64_PREFIX "i" +-# endif +-#endif +-#ifdef UINT64_MAX +-# if (@APPLE_UNIVERSAL_BUILD@ ? defined _LP64 : @UINT64_MAX_EQ_ULONG_MAX@) +-# define _SCNu64_PREFIX "l" +-# elif defined _MSC_VER || defined __MINGW32__ +-# define _SCNu64_PREFIX "I64" +-# elif @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +-# define _SCNu64_PREFIX _LONG_LONG_FORMAT_PREFIX +-# endif +-# if !defined SCNo64 || @PRI_MACROS_BROKEN@ +-# undef SCNo64 +-# define SCNo64 _SCNu64_PREFIX "o" +-# endif +-# if !defined SCNu64 || @PRI_MACROS_BROKEN@ +-# undef SCNu64 +-# define SCNu64 _SCNu64_PREFIX "u" +-# endif +-# if !defined SCNx64 || @PRI_MACROS_BROKEN@ +-# undef SCNx64 +-# define SCNx64 _SCNu64_PREFIX "x" +-# endif +-#endif +- +-#if !defined SCNdLEAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNdLEAST8 +-# define SCNdLEAST8 "hhd" +-#endif +-#if !defined SCNiLEAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNiLEAST8 +-# define SCNiLEAST8 "hhi" +-#endif +-#if !defined SCNoLEAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNoLEAST8 +-# define SCNoLEAST8 "hho" +-#endif +-#if !defined SCNuLEAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNuLEAST8 +-# define SCNuLEAST8 "hhu" +-#endif +-#if !defined SCNxLEAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNxLEAST8 +-# define SCNxLEAST8 "hhx" +-#endif +-#if !defined SCNdLEAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNdLEAST16 +-# define SCNdLEAST16 "hd" +-#endif +-#if !defined SCNiLEAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNiLEAST16 +-# define SCNiLEAST16 "hi" +-#endif +-#if !defined SCNoLEAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNoLEAST16 +-# define SCNoLEAST16 "ho" +-#endif +-#if !defined SCNuLEAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNuLEAST16 +-# define SCNuLEAST16 "hu" +-#endif +-#if !defined SCNxLEAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNxLEAST16 +-# define SCNxLEAST16 "hx" +-#endif +-#if !defined SCNdLEAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNdLEAST32 +-# define SCNdLEAST32 "d" +-#endif +-#if !defined SCNiLEAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNiLEAST32 +-# define SCNiLEAST32 "i" +-#endif +-#if !defined SCNoLEAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNoLEAST32 +-# define SCNoLEAST32 "o" +-#endif +-#if !defined SCNuLEAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNuLEAST32 +-# define SCNuLEAST32 "u" +-#endif +-#if !defined SCNxLEAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNxLEAST32 +-# define SCNxLEAST32 "x" +-#endif +-#ifdef INT64_MAX +-# if !defined SCNdLEAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNdLEAST64 +-# define SCNdLEAST64 SCNd64 +-# endif +-# if !defined SCNiLEAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNiLEAST64 +-# define SCNiLEAST64 SCNi64 +-# endif +-#endif +-#ifdef UINT64_MAX +-# if !defined SCNoLEAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNoLEAST64 +-# define SCNoLEAST64 SCNo64 +-# endif +-# if !defined SCNuLEAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNuLEAST64 +-# define SCNuLEAST64 SCNu64 +-# endif +-# if !defined SCNxLEAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNxLEAST64 +-# define SCNxLEAST64 SCNx64 +-# endif +-#endif +- +-#if !defined SCNdFAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNdFAST8 +-# if INT_FAST8_MAX > INT32_MAX +-# define SCNdFAST8 SCNd64 +-# elif INT_FAST8_MAX == 0x7fff +-# define SCNdFAST8 "hd" +-# elif INT_FAST8_MAX == 0x7f +-# define SCNdFAST8 "hhd" +-# else +-# define SCNdFAST8 "d" +-# endif +-#endif +-#if !defined SCNiFAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNiFAST8 +-# if INT_FAST8_MAX > INT32_MAX +-# define SCNiFAST8 SCNi64 +-# elif INT_FAST8_MAX == 0x7fff +-# define SCNiFAST8 "hi" +-# elif INT_FAST8_MAX == 0x7f +-# define SCNiFAST8 "hhi" +-# else +-# define SCNiFAST8 "i" +-# endif +-#endif +-#if !defined SCNoFAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNoFAST8 +-# if UINT_FAST8_MAX > UINT32_MAX +-# define SCNoFAST8 SCNo64 +-# elif UINT_FAST8_MAX == 0xffff +-# define SCNoFAST8 "ho" +-# elif UINT_FAST8_MAX == 0xff +-# define SCNoFAST8 "hho" +-# else +-# define SCNoFAST8 "o" +-# endif +-#endif +-#if !defined SCNuFAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNuFAST8 +-# if UINT_FAST8_MAX > UINT32_MAX +-# define SCNuFAST8 SCNu64 +-# elif UINT_FAST8_MAX == 0xffff +-# define SCNuFAST8 "hu" +-# elif UINT_FAST8_MAX == 0xff +-# define SCNuFAST8 "hhu" +-# else +-# define SCNuFAST8 "u" +-# endif +-#endif +-#if !defined SCNxFAST8 || @PRI_MACROS_BROKEN@ +-# undef SCNxFAST8 +-# if UINT_FAST8_MAX > UINT32_MAX +-# define SCNxFAST8 SCNx64 +-# elif UINT_FAST8_MAX == 0xffff +-# define SCNxFAST8 "hx" +-# elif UINT_FAST8_MAX == 0xff +-# define SCNxFAST8 "hhx" +-# else +-# define SCNxFAST8 "x" +-# endif +-#endif +-#if !defined SCNdFAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNdFAST16 +-# if INT_FAST16_MAX > INT32_MAX +-# define SCNdFAST16 SCNd64 +-# elif INT_FAST16_MAX == 0x7fff +-# define SCNdFAST16 "hd" +-# else +-# define SCNdFAST16 "d" +-# endif +-#endif +-#if !defined SCNiFAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNiFAST16 +-# if INT_FAST16_MAX > INT32_MAX +-# define SCNiFAST16 SCNi64 +-# elif INT_FAST16_MAX == 0x7fff +-# define SCNiFAST16 "hi" +-# else +-# define SCNiFAST16 "i" +-# endif +-#endif +-#if !defined SCNoFAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNoFAST16 +-# if UINT_FAST16_MAX > UINT32_MAX +-# define SCNoFAST16 SCNo64 +-# elif UINT_FAST16_MAX == 0xffff +-# define SCNoFAST16 "ho" +-# else +-# define SCNoFAST16 "o" +-# endif +-#endif +-#if !defined SCNuFAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNuFAST16 +-# if UINT_FAST16_MAX > UINT32_MAX +-# define SCNuFAST16 SCNu64 +-# elif UINT_FAST16_MAX == 0xffff +-# define SCNuFAST16 "hu" +-# else +-# define SCNuFAST16 "u" +-# endif +-#endif +-#if !defined SCNxFAST16 || @PRI_MACROS_BROKEN@ +-# undef SCNxFAST16 +-# if UINT_FAST16_MAX > UINT32_MAX +-# define SCNxFAST16 SCNx64 +-# elif UINT_FAST16_MAX == 0xffff +-# define SCNxFAST16 "hx" +-# else +-# define SCNxFAST16 "x" +-# endif +-#endif +-#if !defined SCNdFAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNdFAST32 +-# if INT_FAST32_MAX > INT32_MAX +-# define SCNdFAST32 SCNd64 +-# else +-# define SCNdFAST32 "d" +-# endif +-#endif +-#if !defined SCNiFAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNiFAST32 +-# if INT_FAST32_MAX > INT32_MAX +-# define SCNiFAST32 SCNi64 +-# else +-# define SCNiFAST32 "i" +-# endif +-#endif +-#if !defined SCNoFAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNoFAST32 +-# if UINT_FAST32_MAX > UINT32_MAX +-# define SCNoFAST32 SCNo64 +-# else +-# define SCNoFAST32 "o" +-# endif +-#endif +-#if !defined SCNuFAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNuFAST32 +-# if UINT_FAST32_MAX > UINT32_MAX +-# define SCNuFAST32 SCNu64 +-# else +-# define SCNuFAST32 "u" +-# endif +-#endif +-#if !defined SCNxFAST32 || @PRI_MACROS_BROKEN@ +-# undef SCNxFAST32 +-# if UINT_FAST32_MAX > UINT32_MAX +-# define SCNxFAST32 SCNx64 +-# else +-# define SCNxFAST32 "x" +-# endif +-#endif +-#ifdef INT64_MAX +-# if !defined SCNdFAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNdFAST64 +-# define SCNdFAST64 SCNd64 +-# endif +-# if !defined SCNiFAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNiFAST64 +-# define SCNiFAST64 SCNi64 +-# endif +-#endif +-#ifdef UINT64_MAX +-# if !defined SCNoFAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNoFAST64 +-# define SCNoFAST64 SCNo64 +-# endif +-# if !defined SCNuFAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNuFAST64 +-# define SCNuFAST64 SCNu64 +-# endif +-# if !defined SCNxFAST64 || @PRI_MACROS_BROKEN@ +-# undef SCNxFAST64 +-# define SCNxFAST64 SCNx64 +-# endif +-#endif +- +-#if !defined SCNdMAX || @PRI_MACROS_BROKEN@ +-# undef SCNdMAX +-# if @INT32_MAX_LT_INTMAX_MAX@ +-# define SCNdMAX SCNd64 +-# else +-# define SCNdMAX "ld" +-# endif +-#endif +-#if !defined SCNiMAX || @PRI_MACROS_BROKEN@ +-# undef SCNiMAX +-# if @INT32_MAX_LT_INTMAX_MAX@ +-# define SCNiMAX SCNi64 +-# else +-# define SCNiMAX "li" +-# endif +-#endif +-#if !defined SCNoMAX || @PRI_MACROS_BROKEN@ +-# undef SCNoMAX +-# if @UINT32_MAX_LT_UINTMAX_MAX@ +-# define SCNoMAX SCNo64 +-# else +-# define SCNoMAX "lo" +-# endif +-#endif +-#if !defined SCNuMAX || @PRI_MACROS_BROKEN@ +-# undef SCNuMAX +-# if @UINT32_MAX_LT_UINTMAX_MAX@ +-# define SCNuMAX SCNu64 +-# else +-# define SCNuMAX "lu" +-# endif +-#endif +-#if !defined SCNxMAX || @PRI_MACROS_BROKEN@ +-# undef SCNxMAX +-# if @UINT32_MAX_LT_UINTMAX_MAX@ +-# define SCNxMAX SCNx64 +-# else +-# define SCNxMAX "lx" +-# endif +-#endif +- +-#if !defined SCNdPTR || @PRI_MACROS_BROKEN@ +-# undef SCNdPTR +-# ifdef INTPTR_MAX +-# define SCNdPTR @PRIPTR_PREFIX@ "d" +-# endif +-#endif +-#if !defined SCNiPTR || @PRI_MACROS_BROKEN@ +-# undef SCNiPTR +-# ifdef INTPTR_MAX +-# define SCNiPTR @PRIPTR_PREFIX@ "i" +-# endif +-#endif +-#if !defined SCNoPTR || @PRI_MACROS_BROKEN@ +-# undef SCNoPTR +-# ifdef UINTPTR_MAX +-# define SCNoPTR @PRIPTR_PREFIX@ "o" +-# endif +-#endif +-#if !defined SCNuPTR || @PRI_MACROS_BROKEN@ +-# undef SCNuPTR +-# ifdef UINTPTR_MAX +-# define SCNuPTR @PRIPTR_PREFIX@ "u" +-# endif +-#endif +-#if !defined SCNxPTR || @PRI_MACROS_BROKEN@ +-# undef SCNxPTR +-# ifdef UINTPTR_MAX +-# define SCNxPTR @PRIPTR_PREFIX@ "x" +-# endif +-#endif +- +-/* 7.8.2 Functions for greatest-width integer types */ +- +-#ifdef __cplusplus +-extern "C" { +-#endif +- +-#if @GNULIB_IMAXABS@ +-# if !@HAVE_DECL_IMAXABS@ +-extern intmax_t imaxabs (intmax_t); +-# endif +-#elif defined GNULIB_POSIXCHECK +-# undef imaxabs +-# if HAVE_RAW_DECL_IMAXABS +-_GL_WARN_ON_USE (imaxabs, "imaxabs is unportable - " +- "use gnulib module imaxabs for portability"); +-# endif +-#endif +- +-#if @GNULIB_IMAXDIV@ +-# if !@HAVE_DECL_IMAXDIV@ +-# if !GNULIB_defined_imaxdiv_t +-typedef struct { intmax_t quot; intmax_t rem; } imaxdiv_t; +-# define GNULIB_defined_imaxdiv_t 1 +-# endif +-extern imaxdiv_t imaxdiv (intmax_t, intmax_t); +-# endif +-#elif defined GNULIB_POSIXCHECK +-# undef imaxdiv +-# if HAVE_RAW_DECL_IMAXDIV +-_GL_WARN_ON_USE (imaxdiv, "imaxdiv is unportable - " +- "use gnulib module imaxdiv for portability"); +-# endif +-#endif +- +-#if @GNULIB_STRTOIMAX@ +-# if @REPLACE_STRTOIMAX@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef strtoimax +-# define strtoimax rpl_strtoimax +-# endif +-_GL_FUNCDECL_RPL (strtoimax, intmax_t, +- (const char *, char **, int) _GL_ARG_NONNULL ((1))); +-_GL_CXXALIAS_RPL (strtoimax, intmax_t, (const char *, char **, int)); +-# else +-# if !@HAVE_DECL_STRTOIMAX@ +-# undef strtoimax +-_GL_FUNCDECL_SYS (strtoimax, intmax_t, +- (const char *, char **, int) _GL_ARG_NONNULL ((1))); +-# endif +-_GL_CXXALIAS_SYS (strtoimax, intmax_t, (const char *, char **, int)); +-# endif +-_GL_CXXALIASWARN (strtoimax); +-#elif defined GNULIB_POSIXCHECK +-# undef strtoimax +-# if HAVE_RAW_DECL_STRTOIMAX +-_GL_WARN_ON_USE (strtoimax, "strtoimax is unportable - " +- "use gnulib module strtoimax for portability"); +-# endif +-#endif +- +-#if @GNULIB_STRTOUMAX@ +-# if !@HAVE_DECL_STRTOUMAX@ +-# undef strtoumax +-_GL_FUNCDECL_SYS (strtoumax, uintmax_t, +- (const char *, char **, int) _GL_ARG_NONNULL ((1))); +-# endif +-_GL_CXXALIAS_SYS (strtoumax, uintmax_t, (const char *, char **, int)); +-_GL_CXXALIASWARN (strtoumax); +-#elif defined GNULIB_POSIXCHECK +-# undef strtoumax +-# if HAVE_RAW_DECL_STRTOUMAX +-_GL_WARN_ON_USE (strtoumax, "strtoumax is unportable - " +- "use gnulib module strtoumax for portability"); +-# endif +-#endif +- +-/* Don't bother defining or declaring wcstoimax and wcstoumax, since +- wide-character functions like this are hardly ever useful. */ +- +-#ifdef __cplusplus +-} +-#endif +- +-#endif /* !defined INTTYPES_H && !defined _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/localcharset.c groff-1.22.3/src/libs/gnulib/lib/localcharset.c +--- groff-1.22.3.old/src/libs/gnulib/lib/localcharset.c 2014-11-04 10:38:35.629518946 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/localcharset.c 1970-01-01 02:00:00.000000000 +0200 +@@ -1,579 +0,0 @@ +-/* Determine a canonical name for the current locale's character encoding. +- +- Copyright (C) 2000-2006, 2008-2014 Free Software Foundation, Inc. +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2, or (at your option) +- any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License along +- with this program; if not, see . */ +- +-/* Written by Bruno Haible . */ +- +-#include +- +-/* Specification. */ +-#include "localcharset.h" +- +-#include +-#include +-#include +-#include +-#include +- +-#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET +-# define DARWIN7 /* Darwin 7 or newer, i.e. Mac OS X 10.3 or newer */ +-#endif +- +-#if defined _WIN32 || defined __WIN32__ +-# define WINDOWS_NATIVE +-# include +-#endif +- +-#if defined __EMX__ +-/* Assume EMX program runs on OS/2, even if compiled under DOS. */ +-# ifndef OS2 +-# define OS2 +-# endif +-#endif +- +-#if !defined WINDOWS_NATIVE +-# include +-# if HAVE_LANGINFO_CODESET +-# include +-# else +-# if 0 /* see comment below */ +-# include +-# endif +-# endif +-# ifdef __CYGWIN__ +-# define WIN32_LEAN_AND_MEAN +-# include +-# endif +-#elif defined WINDOWS_NATIVE +-# define WIN32_LEAN_AND_MEAN +-# include +-#endif +-#if defined OS2 +-# define INCL_DOS +-# include +-#endif +- +-/* For MB_CUR_MAX_L */ +-#if defined DARWIN7 +-# include +-#endif +- +-#if ENABLE_RELOCATABLE +-# include "relocatable.h" +-#else +-# define relocate(pathname) (pathname) +-#endif +- +-/* Get LIBDIR. */ +-#ifndef LIBDIR +-# include "configmake.h" +-#endif +- +-/* Define O_NOFOLLOW to 0 on platforms where it does not exist. */ +-#ifndef O_NOFOLLOW +-# define O_NOFOLLOW 0 +-#endif +- +-#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ +- /* Native Windows, Cygwin, OS/2, DOS */ +-# define ISSLASH(C) ((C) == '/' || (C) == '\\') +-#endif +- +-#ifndef DIRECTORY_SEPARATOR +-# define DIRECTORY_SEPARATOR '/' +-#endif +- +-#ifndef ISSLASH +-# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +-#endif +- +-#if HAVE_DECL_GETC_UNLOCKED +-# undef getc +-# define getc getc_unlocked +-#endif +- +-/* The following static variable is declared 'volatile' to avoid a +- possible multithread problem in the function get_charset_aliases. If we +- are running in a threaded environment, and if two threads initialize +- 'charset_aliases' simultaneously, both will produce the same value, +- and everything will be ok if the two assignments to 'charset_aliases' +- are atomic. But I don't know what will happen if the two assignments mix. */ +-#if __STDC__ != 1 +-# define volatile /* empty */ +-#endif +-/* Pointer to the contents of the charset.alias file, if it has already been +- read, else NULL. Its format is: +- ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ +-static const char * volatile charset_aliases; +- +-/* Return a pointer to the contents of the charset.alias file. */ +-static const char * +-get_charset_aliases (void) +-{ +- const char *cp; +- +- cp = charset_aliases; +- if (cp == NULL) +- { +-#if !(defined DARWIN7 || defined VMS || defined WINDOWS_NATIVE || defined __CYGWIN__) +- const char *dir; +- const char *base = "charset.alias"; +- char *file_name; +- +- /* Make it possible to override the charset.alias location. This is +- necessary for running the testsuite before "make install". */ +- dir = getenv ("CHARSETALIASDIR"); +- if (dir == NULL || dir[0] == '\0') +- dir = relocate (LIBDIR); +- +- /* Concatenate dir and base into freshly allocated file_name. */ +- { +- size_t dir_len = strlen (dir); +- size_t base_len = strlen (base); +- int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); +- file_name = (char *) malloc (dir_len + add_slash + base_len + 1); +- if (file_name != NULL) +- { +- memcpy (file_name, dir, dir_len); +- if (add_slash) +- file_name[dir_len] = DIRECTORY_SEPARATOR; +- memcpy (file_name + dir_len + add_slash, base, base_len + 1); +- } +- } +- +- if (file_name == NULL) +- /* Out of memory. Treat the file as empty. */ +- cp = ""; +- else +- { +- int fd; +- +- /* Open the file. Reject symbolic links on platforms that support +- O_NOFOLLOW. This is a security feature. Without it, an attacker +- could retrieve parts of the contents (namely, the tail of the +- first line that starts with "* ") of an arbitrary file by placing +- a symbolic link to that file under the name "charset.alias" in +- some writable directory and defining the environment variable +- CHARSETALIASDIR to point to that directory. */ +- fd = open (file_name, +- O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0)); +- if (fd < 0) +- /* File not found. Treat it as empty. */ +- cp = ""; +- else +- { +- FILE *fp; +- +- fp = fdopen (fd, "r"); +- if (fp == NULL) +- { +- /* Out of memory. Treat the file as empty. */ +- close (fd); +- cp = ""; +- } +- else +- { +- /* Parse the file's contents. */ +- char *res_ptr = NULL; +- size_t res_size = 0; +- +- for (;;) +- { +- int c; +- char buf1[50+1]; +- char buf2[50+1]; +- size_t l1, l2; +- char *old_res_ptr; +- +- c = getc (fp); +- if (c == EOF) +- break; +- if (c == '\n' || c == ' ' || c == '\t') +- continue; +- if (c == '#') +- { +- /* Skip comment, to end of line. */ +- do +- c = getc (fp); +- while (!(c == EOF || c == '\n')); +- if (c == EOF) +- break; +- continue; +- } +- ungetc (c, fp); +- if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) +- break; +- l1 = strlen (buf1); +- l2 = strlen (buf2); +- old_res_ptr = res_ptr; +- if (res_size == 0) +- { +- res_size = l1 + 1 + l2 + 1; +- res_ptr = (char *) malloc (res_size + 1); +- } +- else +- { +- res_size += l1 + 1 + l2 + 1; +- res_ptr = (char *) realloc (res_ptr, res_size + 1); +- } +- if (res_ptr == NULL) +- { +- /* Out of memory. */ +- res_size = 0; +- free (old_res_ptr); +- break; +- } +- strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); +- strcpy (res_ptr + res_size - (l2 + 1), buf2); +- } +- fclose (fp); +- if (res_size == 0) +- cp = ""; +- else +- { +- *(res_ptr + res_size) = '\0'; +- cp = res_ptr; +- } +- } +- } +- +- free (file_name); +- } +- +-#else +- +-# if defined DARWIN7 +- /* To avoid the trouble of installing a file that is shared by many +- GNU packages -- many packaging systems have problems with this --, +- simply inline the aliases here. */ +- cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" +- "ISO8859-2" "\0" "ISO-8859-2" "\0" +- "ISO8859-4" "\0" "ISO-8859-4" "\0" +- "ISO8859-5" "\0" "ISO-8859-5" "\0" +- "ISO8859-7" "\0" "ISO-8859-7" "\0" +- "ISO8859-9" "\0" "ISO-8859-9" "\0" +- "ISO8859-13" "\0" "ISO-8859-13" "\0" +- "ISO8859-15" "\0" "ISO-8859-15" "\0" +- "KOI8-R" "\0" "KOI8-R" "\0" +- "KOI8-U" "\0" "KOI8-U" "\0" +- "CP866" "\0" "CP866" "\0" +- "CP949" "\0" "CP949" "\0" +- "CP1131" "\0" "CP1131" "\0" +- "CP1251" "\0" "CP1251" "\0" +- "eucCN" "\0" "GB2312" "\0" +- "GB2312" "\0" "GB2312" "\0" +- "eucJP" "\0" "EUC-JP" "\0" +- "eucKR" "\0" "EUC-KR" "\0" +- "Big5" "\0" "BIG5" "\0" +- "Big5HKSCS" "\0" "BIG5-HKSCS" "\0" +- "GBK" "\0" "GBK" "\0" +- "GB18030" "\0" "GB18030" "\0" +- "SJIS" "\0" "SHIFT_JIS" "\0" +- "ARMSCII-8" "\0" "ARMSCII-8" "\0" +- "PT154" "\0" "PT154" "\0" +- /*"ISCII-DEV" "\0" "?" "\0"*/ +- "*" "\0" "UTF-8" "\0"; +-# endif +- +-# if defined VMS +- /* To avoid the troubles of an extra file charset.alias_vms in the +- sources of many GNU packages, simply inline the aliases here. */ +- /* The list of encodings is taken from the OpenVMS 7.3-1 documentation +- "Compaq C Run-Time Library Reference Manual for OpenVMS systems" +- section 10.7 "Handling Different Character Sets". */ +- cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" +- "ISO8859-2" "\0" "ISO-8859-2" "\0" +- "ISO8859-5" "\0" "ISO-8859-5" "\0" +- "ISO8859-7" "\0" "ISO-8859-7" "\0" +- "ISO8859-8" "\0" "ISO-8859-8" "\0" +- "ISO8859-9" "\0" "ISO-8859-9" "\0" +- /* Japanese */ +- "eucJP" "\0" "EUC-JP" "\0" +- "SJIS" "\0" "SHIFT_JIS" "\0" +- "DECKANJI" "\0" "DEC-KANJI" "\0" +- "SDECKANJI" "\0" "EUC-JP" "\0" +- /* Chinese */ +- "eucTW" "\0" "EUC-TW" "\0" +- "DECHANYU" "\0" "DEC-HANYU" "\0" +- "DECHANZI" "\0" "GB2312" "\0" +- /* Korean */ +- "DECKOREAN" "\0" "EUC-KR" "\0"; +-# endif +- +-# if defined WINDOWS_NATIVE || defined __CYGWIN__ +- /* To avoid the troubles of installing a separate file in the same +- directory as the DLL and of retrieving the DLL's directory at +- runtime, simply inline the aliases here. */ +- +- cp = "CP936" "\0" "GBK" "\0" +- "CP1361" "\0" "JOHAB" "\0" +- "CP20127" "\0" "ASCII" "\0" +- "CP20866" "\0" "KOI8-R" "\0" +- "CP20936" "\0" "GB2312" "\0" +- "CP21866" "\0" "KOI8-RU" "\0" +- "CP28591" "\0" "ISO-8859-1" "\0" +- "CP28592" "\0" "ISO-8859-2" "\0" +- "CP28593" "\0" "ISO-8859-3" "\0" +- "CP28594" "\0" "ISO-8859-4" "\0" +- "CP28595" "\0" "ISO-8859-5" "\0" +- "CP28596" "\0" "ISO-8859-6" "\0" +- "CP28597" "\0" "ISO-8859-7" "\0" +- "CP28598" "\0" "ISO-8859-8" "\0" +- "CP28599" "\0" "ISO-8859-9" "\0" +- "CP28605" "\0" "ISO-8859-15" "\0" +- "CP38598" "\0" "ISO-8859-8" "\0" +- "CP51932" "\0" "EUC-JP" "\0" +- "CP51936" "\0" "GB2312" "\0" +- "CP51949" "\0" "EUC-KR" "\0" +- "CP51950" "\0" "EUC-TW" "\0" +- "CP54936" "\0" "GB18030" "\0" +- "CP65001" "\0" "UTF-8" "\0"; +-# endif +-#endif +- +- charset_aliases = cp; +- } +- +- return cp; +-} +- +-/* Determine the current locale's character encoding, and canonicalize it +- into one of the canonical names listed in config.charset. +- The result must not be freed; it is statically allocated. +- If the canonical name cannot be determined, the result is a non-canonical +- name. */ +- +-#ifdef STATIC +-STATIC +-#endif +-const char * +-locale_charset (void) +-{ +- const char *codeset; +- const char *aliases; +- +-#if !(defined WINDOWS_NATIVE || defined OS2) +- +-# if HAVE_LANGINFO_CODESET +- +- /* Most systems support nl_langinfo (CODESET) nowadays. */ +- codeset = nl_langinfo (CODESET); +- +-# ifdef __CYGWIN__ +- /* Cygwin < 1.7 does not have locales. nl_langinfo (CODESET) always +- returns "US-ASCII". Return the suffix of the locale name from the +- environment variables (if present) or the codepage as a number. */ +- if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) +- { +- const char *locale; +- static char buf[2 + 10 + 1]; +- +- locale = getenv ("LC_ALL"); +- if (locale == NULL || locale[0] == '\0') +- { +- locale = getenv ("LC_CTYPE"); +- if (locale == NULL || locale[0] == '\0') +- locale = getenv ("LANG"); +- } +- if (locale != NULL && locale[0] != '\0') +- { +- /* If the locale name contains an encoding after the dot, return +- it. */ +- const char *dot = strchr (locale, '.'); +- +- if (dot != NULL) +- { +- const char *modifier; +- +- dot++; +- /* Look for the possible @... trailer and remove it, if any. */ +- modifier = strchr (dot, '@'); +- if (modifier == NULL) +- return dot; +- if (modifier - dot < sizeof (buf)) +- { +- memcpy (buf, dot, modifier - dot); +- buf [modifier - dot] = '\0'; +- return buf; +- } +- } +- } +- +- /* The Windows API has a function returning the locale's codepage as a +- number: GetACP(). This encoding is used by Cygwin, unless the user +- has set the environment variable CYGWIN=codepage:oem (which very few +- people do). +- Output directed to console windows needs to be converted (to +- GetOEMCP() if the console is using a raster font, or to +- GetConsoleOutputCP() if it is using a TrueType font). Cygwin does +- this conversion transparently (see winsup/cygwin/fhandler_console.cc), +- converting to GetConsoleOutputCP(). This leads to correct results, +- except when SetConsoleOutputCP has been called and a raster font is +- in use. */ +- sprintf (buf, "CP%u", GetACP ()); +- codeset = buf; +- } +-# endif +- +-# else +- +- /* On old systems which lack it, use setlocale or getenv. */ +- const char *locale = NULL; +- +- /* But most old systems don't have a complete set of locales. Some +- (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't +- use setlocale here; it would return "C" when it doesn't support the +- locale name the user has set. */ +-# if 0 +- locale = setlocale (LC_CTYPE, NULL); +-# endif +- if (locale == NULL || locale[0] == '\0') +- { +- locale = getenv ("LC_ALL"); +- if (locale == NULL || locale[0] == '\0') +- { +- locale = getenv ("LC_CTYPE"); +- if (locale == NULL || locale[0] == '\0') +- locale = getenv ("LANG"); +- } +- } +- +- /* On some old systems, one used to set locale = "iso8859_1". On others, +- you set it to "language_COUNTRY.charset". In any case, we resolve it +- through the charset.alias file. */ +- codeset = locale; +- +-# endif +- +-#elif defined WINDOWS_NATIVE +- +- static char buf[2 + 10 + 1]; +- +- /* The Windows API has a function returning the locale's codepage as +- a number, but the value doesn't change according to what the +- 'setlocale' call specified. So we use it as a last resort, in +- case the string returned by 'setlocale' doesn't specify the +- codepage. */ +- char *current_locale = setlocale (LC_ALL, NULL); +- char *pdot; +- +- /* If they set different locales for different categories, +- 'setlocale' will return a semi-colon separated list of locale +- values. To make sure we use the correct one, we choose LC_CTYPE. */ +- if (strchr (current_locale, ';')) +- current_locale = setlocale (LC_CTYPE, NULL); +- +- pdot = strrchr (current_locale, '.'); +- if (pdot) +- sprintf (buf, "CP%s", pdot + 1); +- else +- { +- /* The Windows API has a function returning the locale's codepage as a +- number: GetACP(). +- When the output goes to a console window, it needs to be provided in +- GetOEMCP() encoding if the console is using a raster font, or in +- GetConsoleOutputCP() encoding if it is using a TrueType font. +- But in GUI programs and for output sent to files and pipes, GetACP() +- encoding is the best bet. */ +- sprintf (buf, "CP%u", GetACP ()); +- } +- codeset = buf; +- +-#elif defined OS2 +- +- const char *locale; +- static char buf[2 + 10 + 1]; +- ULONG cp[3]; +- ULONG cplen; +- +- /* Allow user to override the codeset, as set in the operating system, +- with standard language environment variables. */ +- locale = getenv ("LC_ALL"); +- if (locale == NULL || locale[0] == '\0') +- { +- locale = getenv ("LC_CTYPE"); +- if (locale == NULL || locale[0] == '\0') +- locale = getenv ("LANG"); +- } +- if (locale != NULL && locale[0] != '\0') +- { +- /* If the locale name contains an encoding after the dot, return it. */ +- const char *dot = strchr (locale, '.'); +- +- if (dot != NULL) +- { +- const char *modifier; +- +- dot++; +- /* Look for the possible @... trailer and remove it, if any. */ +- modifier = strchr (dot, '@'); +- if (modifier == NULL) +- return dot; +- if (modifier - dot < sizeof (buf)) +- { +- memcpy (buf, dot, modifier - dot); +- buf [modifier - dot] = '\0'; +- return buf; +- } +- } +- +- /* Resolve through the charset.alias file. */ +- codeset = locale; +- } +- else +- { +- /* OS/2 has a function returning the locale's codepage as a number. */ +- if (DosQueryCp (sizeof (cp), cp, &cplen)) +- codeset = ""; +- else +- { +- sprintf (buf, "CP%u", cp[0]); +- codeset = buf; +- } +- } +- +-#endif +- +- if (codeset == NULL) +- /* The canonical name cannot be determined. */ +- codeset = ""; +- +- /* Resolve alias. */ +- for (aliases = get_charset_aliases (); +- *aliases != '\0'; +- aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) +- if (strcmp (codeset, aliases) == 0 +- || (aliases[0] == '*' && aliases[1] == '\0')) +- { +- codeset = aliases + strlen (aliases) + 1; +- break; +- } +- +- /* Don't return an empty string. GNU libc and GNU libiconv interpret +- the empty string as denoting "the locale's character encoding", +- thus GNU libiconv would call this function a second time. */ +- if (codeset[0] == '\0') +- codeset = "ASCII"; +- +-#ifdef DARWIN7 +- /* Mac OS X sets MB_CUR_MAX to 1 when LC_ALL=C, and "UTF-8" +- (the default codeset) does not work when MB_CUR_MAX is 1. */ +- if (strcmp (codeset, "UTF-8") == 0 && MB_CUR_MAX_L (uselocale (NULL)) <= 1) +- codeset = "ASCII"; +-#endif +- +- return codeset; +-} +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/localcharset.h groff-1.22.3/src/libs/gnulib/lib/localcharset.h +--- groff-1.22.3.old/src/libs/gnulib/lib/localcharset.h 2014-11-04 10:38:35.629518946 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/localcharset.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,40 +0,0 @@ +-/* Determine a canonical name for the current locale's character encoding. +- Copyright (C) 2000-2003, 2009-2014 Free Software Foundation, Inc. +- This file is part of the GNU CHARSET Library. +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2, or (at your option) +- any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License along +- with this program; if not, see . */ +- +-#ifndef _LOCALCHARSET_H +-#define _LOCALCHARSET_H +- +- +-#ifdef __cplusplus +-extern "C" { +-#endif +- +- +-/* Determine the current locale's character encoding, and canonicalize it +- into one of the canonical names listed in config.charset. +- The result must not be freed; it is statically allocated. +- If the canonical name cannot be determined, the result is a non-canonical +- name. */ +-extern const char * locale_charset (void); +- +- +-#ifdef __cplusplus +-} +-#endif +- +- +-#endif /* _LOCALCHARSET_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/Makefile.am groff-1.22.3/src/libs/gnulib/lib/Makefile.am +--- groff-1.22.3.old/src/libs/gnulib/lib/Makefile.am 2014-11-04 10:38:35.629518946 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/Makefile.am 1970-01-01 02:00:00.000000000 +0200 +@@ -1,544 +0,0 @@ +-## DO NOT EDIT! GENERATED AUTOMATICALLY! +-## Process this file with automake to produce Makefile.in. +-# Copyright (C) 2002-2014 Free Software Foundation, Inc. +-# +-# This file is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 3 of the License, or +-# (at your option) any later version. +-# +-# This file is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this file. If not, see . +-# +-# As a special exception to the GNU General Public License, +-# this file may be distributed as part of a program that +-# contains a configuration script generated by Autoconf, under +-# the same distribution terms as the rest of that program. +-# +-# Generated by gnulib-tool. +-# Reproduce by: gnulib-tool --import --dir=src/libs/gnulib --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl wcwidth +- +-AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects +- +-SUBDIRS = +-noinst_HEADERS = +-noinst_LIBRARIES = +-noinst_LTLIBRARIES = +-EXTRA_DIST = +-BUILT_SOURCES = +-SUFFIXES = +-MOSTLYCLEANFILES = core *.stackdump +-MOSTLYCLEANDIRS = +-CLEANFILES = +-DISTCLEANFILES = +-MAINTAINERCLEANFILES = +- +-AM_CPPFLAGS = +-AM_CFLAGS = +- +-noinst_LIBRARIES += libgnu.a +- +-libgnu_a_SOURCES = +-libgnu_a_LIBADD = $(gl_LIBOBJS) +-libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) +-EXTRA_libgnu_a_SOURCES = +- +-## begin gnulib module configmake +- +-# Listed in the same order as the GNU makefile conventions, and +-# provided by autoconf 2.59c+. +-# The Automake-defined pkg* macros are appended, in the order +-# listed in the Automake 1.10a+ documentation. +-configmake.h: Makefile +- $(AM_V_GEN)rm -f $@-t && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- echo '#define PREFIX "$(prefix)"'; \ +- echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ +- echo '#define BINDIR "$(bindir)"'; \ +- echo '#define SBINDIR "$(sbindir)"'; \ +- echo '#define LIBEXECDIR "$(libexecdir)"'; \ +- echo '#define DATAROOTDIR "$(datarootdir)"'; \ +- echo '#define DATADIR "$(datadir)"'; \ +- echo '#define SYSCONFDIR "$(sysconfdir)"'; \ +- echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \ +- echo '#define LOCALSTATEDIR "$(localstatedir)"'; \ +- echo '#define INCLUDEDIR "$(includedir)"'; \ +- echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \ +- echo '#define DOCDIR "$(docdir)"'; \ +- echo '#define INFODIR "$(infodir)"'; \ +- echo '#define HTMLDIR "$(htmldir)"'; \ +- echo '#define DVIDIR "$(dvidir)"'; \ +- echo '#define PDFDIR "$(pdfdir)"'; \ +- echo '#define PSDIR "$(psdir)"'; \ +- echo '#define LIBDIR "$(libdir)"'; \ +- echo '#define LISPDIR "$(lispdir)"'; \ +- echo '#define LOCALEDIR "$(localedir)"'; \ +- echo '#define MANDIR "$(mandir)"'; \ +- echo '#define MANEXT "$(manext)"'; \ +- echo '#define PKGDATADIR "$(pkgdatadir)"'; \ +- echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \ +- echo '#define PKGLIBDIR "$(pkglibdir)"'; \ +- echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ +- } | sed '/""/d' > $@-t && \ +- mv -f $@-t $@ +- +-BUILT_SOURCES += configmake.h +-CLEANFILES += configmake.h configmake.h-t +- +-## end gnulib module configmake +- +-## begin gnulib module localcharset +- +-libgnu_a_SOURCES += localcharset.h localcharset.c +- +-# We need the following in order to install a simple file in $(libdir) +-# which is shared with other installed packages. We use a list of referencing +-# packages so that "make uninstall" will remove the file if and only if it +-# is not used by another installed package. +-# On systems with glibc-2.1 or newer, the file is redundant, therefore we +-# avoid installing it. +- +-all-local: charset.alias ref-add.sed ref-del.sed +- +-charset_alias = $(DESTDIR)$(libdir)/charset.alias +-charset_tmp = $(DESTDIR)$(libdir)/charset.tmp +-install-exec-local: install-exec-localcharset +-install-exec-localcharset: all-local +- if test $(GLIBC21) = no; then \ +- case '$(host_os)' in \ +- darwin[56]*) \ +- need_charset_alias=true ;; \ +- darwin* | cygwin* | mingw* | pw32* | cegcc*) \ +- need_charset_alias=false ;; \ +- *) \ +- need_charset_alias=true ;; \ +- esac ; \ +- else \ +- need_charset_alias=false ; \ +- fi ; \ +- if $$need_charset_alias; then \ +- $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ +- fi ; \ +- if test -f $(charset_alias); then \ +- sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ +- $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ +- rm -f $(charset_tmp) ; \ +- else \ +- if $$need_charset_alias; then \ +- sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ +- $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ +- rm -f $(charset_tmp) ; \ +- fi ; \ +- fi +- +-uninstall-local: uninstall-localcharset +-uninstall-localcharset: all-local +- if test -f $(charset_alias); then \ +- sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ +- if grep '^# Packages using this file: $$' $(charset_tmp) \ +- > /dev/null; then \ +- rm -f $(charset_alias); \ +- else \ +- $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ +- fi; \ +- rm -f $(charset_tmp); \ +- fi +- +-charset.alias: config.charset +- $(AM_V_GEN)rm -f t-$@ $@ && \ +- $(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \ +- mv t-$@ $@ +- +-SUFFIXES += .sed .sin +-.sin.sed: +- $(AM_V_GEN)rm -f t-$@ $@ && \ +- sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \ +- mv t-$@ $@ +- +-CLEANFILES += charset.alias ref-add.sed ref-del.sed +- +-EXTRA_DIST += config.charset ref-add.sin ref-del.sin +- +-## end gnulib module localcharset +- +-## begin gnulib module snippet/arg-nonnull +- +-# The BUILT_SOURCES created by this Makefile snippet are not used via #include +-# statements but through direct file reference. Therefore this snippet must be +-# present in all Makefile.am that need it. This is ensured by the applicability +-# 'all' defined above. +- +-BUILT_SOURCES += arg-nonnull.h +-# The arg-nonnull.h that gets inserted into generated .h files is the same as +-# build-aux/snippet/arg-nonnull.h, except that it has the copyright header cut +-# off. +-arg-nonnull.h: $(top_srcdir)/build-aux/snippet/arg-nonnull.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- sed -n -e '/GL_ARG_NONNULL/,$$p' \ +- < $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ +- > $@-t && \ +- mv $@-t $@ +-MOSTLYCLEANFILES += arg-nonnull.h arg-nonnull.h-t +- +-ARG_NONNULL_H=arg-nonnull.h +- +-EXTRA_DIST += $(top_srcdir)/build-aux/snippet/arg-nonnull.h +- +-## end gnulib module snippet/arg-nonnull +- +-## begin gnulib module snippet/c++defs +- +-# The BUILT_SOURCES created by this Makefile snippet are not used via #include +-# statements but through direct file reference. Therefore this snippet must be +-# present in all Makefile.am that need it. This is ensured by the applicability +-# 'all' defined above. +- +-BUILT_SOURCES += c++defs.h +-# The c++defs.h that gets inserted into generated .h files is the same as +-# build-aux/snippet/c++defs.h, except that it has the copyright header cut off. +-c++defs.h: $(top_srcdir)/build-aux/snippet/c++defs.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- sed -n -e '/_GL_CXXDEFS/,$$p' \ +- < $(top_srcdir)/build-aux/snippet/c++defs.h \ +- > $@-t && \ +- mv $@-t $@ +-MOSTLYCLEANFILES += c++defs.h c++defs.h-t +- +-CXXDEFS_H=c++defs.h +- +-EXTRA_DIST += $(top_srcdir)/build-aux/snippet/c++defs.h +- +-## end gnulib module snippet/c++defs +- +-## begin gnulib module snippet/warn-on-use +- +-BUILT_SOURCES += warn-on-use.h +-# The warn-on-use.h that gets inserted into generated .h files is the same as +-# build-aux/snippet/warn-on-use.h, except that it has the copyright header cut +-# off. +-warn-on-use.h: $(top_srcdir)/build-aux/snippet/warn-on-use.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- sed -n -e '/^.ifndef/,$$p' \ +- < $(top_srcdir)/build-aux/snippet/warn-on-use.h \ +- > $@-t && \ +- mv $@-t $@ +-MOSTLYCLEANFILES += warn-on-use.h warn-on-use.h-t +- +-WARN_ON_USE_H=warn-on-use.h +- +-EXTRA_DIST += $(top_srcdir)/build-aux/snippet/warn-on-use.h +- +-## end gnulib module snippet/warn-on-use +- +-## begin gnulib module stddef +- +-BUILT_SOURCES += $(STDDEF_H) +- +-# We need the following in order to create when the system +-# doesn't have one that works with the given compiler. +-if GL_GENERATE_STDDEF_H +-stddef.h: stddef.in.h $(top_builddir)/config.status +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +- sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +- -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +- -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +- -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +- -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \ +- -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \ +- -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ +- < $(srcdir)/stddef.in.h; \ +- } > $@-t && \ +- mv $@-t $@ +-else +-stddef.h: $(top_builddir)/config.status +- rm -f $@ +-endif +-MOSTLYCLEANFILES += stddef.h stddef.h-t +- +-EXTRA_DIST += stddef.in.h +- +-## end gnulib module stddef +- +-## begin gnulib module stdint +- +-BUILT_SOURCES += $(STDINT_H) +- +-# We need the following in order to create when the system +-# doesn't have one that works with the given compiler. +-if GL_GENERATE_STDINT_H +-stdint.h: stdint.in.h $(top_builddir)/config.status +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +- -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ +- -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +- -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +- -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +- -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ +- -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ +- -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ +- -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ +- -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ +- -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ +- -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ +- -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ +- -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ +- -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ +- -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ +- -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ +- -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ +- -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ +- -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ +- -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ +- -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ +- -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ +- -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ +- -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ +- -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ +- -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ +- < $(srcdir)/stdint.in.h; \ +- } > $@-t && \ +- mv $@-t $@ +-else +-stdint.h: $(top_builddir)/config.status +- rm -f $@ +-endif +-MOSTLYCLEANFILES += stdint.h stdint.h-t +- +-EXTRA_DIST += stdint.in.h +- +-## end gnulib module stdint +- +-## begin gnulib module streq +- +- +-EXTRA_DIST += streq.h +- +-## end gnulib module streq +- +-## begin gnulib module unitypes +- +-BUILT_SOURCES += $(LIBUNISTRING_UNITYPES_H) +- +-unitypes.h: unitypes.in.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- cat $(srcdir)/unitypes.in.h; \ +- } > $@-t && \ +- mv -f $@-t $@ +-MOSTLYCLEANFILES += unitypes.h unitypes.h-t +- +-EXTRA_DIST += unitypes.in.h +- +-## end gnulib module unitypes +- +-## begin gnulib module uniwidth/base +- +-BUILT_SOURCES += $(LIBUNISTRING_UNIWIDTH_H) +- +-uniwidth.h: uniwidth.in.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- cat $(srcdir)/uniwidth.in.h; \ +- } > $@-t && \ +- mv -f $@-t $@ +-MOSTLYCLEANFILES += uniwidth.h uniwidth.h-t +- +-EXTRA_DIST += localcharset.h uniwidth.in.h +- +-## end gnulib module uniwidth/base +- +-## begin gnulib module uniwidth/width +- +-if LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH +-libgnu_a_SOURCES += uniwidth/width.c +-endif +- +-EXTRA_DIST += uniwidth/cjk.h +- +-## end gnulib module uniwidth/width +- +-## begin gnulib module wchar +- +-BUILT_SOURCES += wchar.h +- +-# We need the following in order to create when the system +-# version does not work standalone. +-wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +- -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +- -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +- -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +- -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \ +- -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ +- -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \ +- -e 's/@''GNULIB_BTOWC''@/$(GNULIB_BTOWC)/g' \ +- -e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \ +- -e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \ +- -e 's/@''GNULIB_MBRTOWC''@/$(GNULIB_MBRTOWC)/g' \ +- -e 's/@''GNULIB_MBRLEN''@/$(GNULIB_MBRLEN)/g' \ +- -e 's/@''GNULIB_MBSRTOWCS''@/$(GNULIB_MBSRTOWCS)/g' \ +- -e 's/@''GNULIB_MBSNRTOWCS''@/$(GNULIB_MBSNRTOWCS)/g' \ +- -e 's/@''GNULIB_WCRTOMB''@/$(GNULIB_WCRTOMB)/g' \ +- -e 's/@''GNULIB_WCSRTOMBS''@/$(GNULIB_WCSRTOMBS)/g' \ +- -e 's/@''GNULIB_WCSNRTOMBS''@/$(GNULIB_WCSNRTOMBS)/g' \ +- -e 's/@''GNULIB_WCWIDTH''@/$(GNULIB_WCWIDTH)/g' \ +- -e 's/@''GNULIB_WMEMCHR''@/$(GNULIB_WMEMCHR)/g' \ +- -e 's/@''GNULIB_WMEMCMP''@/$(GNULIB_WMEMCMP)/g' \ +- -e 's/@''GNULIB_WMEMCPY''@/$(GNULIB_WMEMCPY)/g' \ +- -e 's/@''GNULIB_WMEMMOVE''@/$(GNULIB_WMEMMOVE)/g' \ +- -e 's/@''GNULIB_WMEMSET''@/$(GNULIB_WMEMSET)/g' \ +- -e 's/@''GNULIB_WCSLEN''@/$(GNULIB_WCSLEN)/g' \ +- -e 's/@''GNULIB_WCSNLEN''@/$(GNULIB_WCSNLEN)/g' \ +- -e 's/@''GNULIB_WCSCPY''@/$(GNULIB_WCSCPY)/g' \ +- -e 's/@''GNULIB_WCPCPY''@/$(GNULIB_WCPCPY)/g' \ +- -e 's/@''GNULIB_WCSNCPY''@/$(GNULIB_WCSNCPY)/g' \ +- -e 's/@''GNULIB_WCPNCPY''@/$(GNULIB_WCPNCPY)/g' \ +- -e 's/@''GNULIB_WCSCAT''@/$(GNULIB_WCSCAT)/g' \ +- -e 's/@''GNULIB_WCSNCAT''@/$(GNULIB_WCSNCAT)/g' \ +- -e 's/@''GNULIB_WCSCMP''@/$(GNULIB_WCSCMP)/g' \ +- -e 's/@''GNULIB_WCSNCMP''@/$(GNULIB_WCSNCMP)/g' \ +- -e 's/@''GNULIB_WCSCASECMP''@/$(GNULIB_WCSCASECMP)/g' \ +- -e 's/@''GNULIB_WCSNCASECMP''@/$(GNULIB_WCSNCASECMP)/g' \ +- -e 's/@''GNULIB_WCSCOLL''@/$(GNULIB_WCSCOLL)/g' \ +- -e 's/@''GNULIB_WCSXFRM''@/$(GNULIB_WCSXFRM)/g' \ +- -e 's/@''GNULIB_WCSDUP''@/$(GNULIB_WCSDUP)/g' \ +- -e 's/@''GNULIB_WCSCHR''@/$(GNULIB_WCSCHR)/g' \ +- -e 's/@''GNULIB_WCSRCHR''@/$(GNULIB_WCSRCHR)/g' \ +- -e 's/@''GNULIB_WCSCSPN''@/$(GNULIB_WCSCSPN)/g' \ +- -e 's/@''GNULIB_WCSSPN''@/$(GNULIB_WCSSPN)/g' \ +- -e 's/@''GNULIB_WCSPBRK''@/$(GNULIB_WCSPBRK)/g' \ +- -e 's/@''GNULIB_WCSSTR''@/$(GNULIB_WCSSTR)/g' \ +- -e 's/@''GNULIB_WCSTOK''@/$(GNULIB_WCSTOK)/g' \ +- -e 's/@''GNULIB_WCSWIDTH''@/$(GNULIB_WCSWIDTH)/g' \ +- < $(srcdir)/wchar.in.h | \ +- sed -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \ +- -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \ +- -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \ +- -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \ +- -e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \ +- -e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \ +- -e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \ +- -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \ +- -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \ +- -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \ +- -e 's|@''HAVE_WMEMCHR''@|$(HAVE_WMEMCHR)|g' \ +- -e 's|@''HAVE_WMEMCMP''@|$(HAVE_WMEMCMP)|g' \ +- -e 's|@''HAVE_WMEMCPY''@|$(HAVE_WMEMCPY)|g' \ +- -e 's|@''HAVE_WMEMMOVE''@|$(HAVE_WMEMMOVE)|g' \ +- -e 's|@''HAVE_WMEMSET''@|$(HAVE_WMEMSET)|g' \ +- -e 's|@''HAVE_WCSLEN''@|$(HAVE_WCSLEN)|g' \ +- -e 's|@''HAVE_WCSNLEN''@|$(HAVE_WCSNLEN)|g' \ +- -e 's|@''HAVE_WCSCPY''@|$(HAVE_WCSCPY)|g' \ +- -e 's|@''HAVE_WCPCPY''@|$(HAVE_WCPCPY)|g' \ +- -e 's|@''HAVE_WCSNCPY''@|$(HAVE_WCSNCPY)|g' \ +- -e 's|@''HAVE_WCPNCPY''@|$(HAVE_WCPNCPY)|g' \ +- -e 's|@''HAVE_WCSCAT''@|$(HAVE_WCSCAT)|g' \ +- -e 's|@''HAVE_WCSNCAT''@|$(HAVE_WCSNCAT)|g' \ +- -e 's|@''HAVE_WCSCMP''@|$(HAVE_WCSCMP)|g' \ +- -e 's|@''HAVE_WCSNCMP''@|$(HAVE_WCSNCMP)|g' \ +- -e 's|@''HAVE_WCSCASECMP''@|$(HAVE_WCSCASECMP)|g' \ +- -e 's|@''HAVE_WCSNCASECMP''@|$(HAVE_WCSNCASECMP)|g' \ +- -e 's|@''HAVE_WCSCOLL''@|$(HAVE_WCSCOLL)|g' \ +- -e 's|@''HAVE_WCSXFRM''@|$(HAVE_WCSXFRM)|g' \ +- -e 's|@''HAVE_WCSDUP''@|$(HAVE_WCSDUP)|g' \ +- -e 's|@''HAVE_WCSCHR''@|$(HAVE_WCSCHR)|g' \ +- -e 's|@''HAVE_WCSRCHR''@|$(HAVE_WCSRCHR)|g' \ +- -e 's|@''HAVE_WCSCSPN''@|$(HAVE_WCSCSPN)|g' \ +- -e 's|@''HAVE_WCSSPN''@|$(HAVE_WCSSPN)|g' \ +- -e 's|@''HAVE_WCSPBRK''@|$(HAVE_WCSPBRK)|g' \ +- -e 's|@''HAVE_WCSSTR''@|$(HAVE_WCSSTR)|g' \ +- -e 's|@''HAVE_WCSTOK''@|$(HAVE_WCSTOK)|g' \ +- -e 's|@''HAVE_WCSWIDTH''@|$(HAVE_WCSWIDTH)|g' \ +- -e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \ +- -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \ +- | \ +- sed -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \ +- -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \ +- -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \ +- -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \ +- -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \ +- -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \ +- -e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \ +- -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \ +- -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \ +- -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \ +- -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \ +- -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \ +- -e 's|@''REPLACE_WCSWIDTH''@|$(REPLACE_WCSWIDTH)|g' \ +- -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ +- -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ +- -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ +- } > $@-t && \ +- mv $@-t $@ +-MOSTLYCLEANFILES += wchar.h wchar.h-t +- +-EXTRA_DIST += wchar.in.h +- +-## end gnulib module wchar +- +-## begin gnulib module wctype-h +- +-BUILT_SOURCES += wctype.h +-libgnu_a_SOURCES += wctype-h.c +- +-# We need the following in order to create when the system +-# doesn't have one that works with the given compiler. +-wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +- -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ +- -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +- -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +- -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +- -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ +- -e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \ +- -e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \ +- -e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \ +- -e 's/@''GNULIB_WCTRANS''@/$(GNULIB_WCTRANS)/g' \ +- -e 's/@''GNULIB_TOWCTRANS''@/$(GNULIB_TOWCTRANS)/g' \ +- -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \ +- -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \ +- -e 's/@''HAVE_WCTYPE_T''@/$(HAVE_WCTYPE_T)/g' \ +- -e 's/@''HAVE_WCTRANS_T''@/$(HAVE_WCTRANS_T)/g' \ +- -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \ +- -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \ +- -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \ +- -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \ +- -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ +- -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ +- < $(srcdir)/wctype.in.h; \ +- } > $@-t && \ +- mv $@-t $@ +-MOSTLYCLEANFILES += wctype.h wctype.h-t +- +-EXTRA_DIST += wctype.in.h +- +-## end gnulib module wctype-h +- +-## begin gnulib module wcwidth +- +- +-EXTRA_DIST += wcwidth.c +- +-EXTRA_libgnu_a_SOURCES += wcwidth.c +- +-## end gnulib module wcwidth +- +- +-mostlyclean-local: mostlyclean-generic +- @for dir in '' $(MOSTLYCLEANDIRS); do \ +- if test -n "$$dir" && test -d $$dir; then \ +- echo "rmdir $$dir"; rmdir $$dir; \ +- fi; \ +- done; \ +- : +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/Makefile.in groff-1.22.3/src/libs/gnulib/lib/Makefile.in +--- groff-1.22.3.old/src/libs/gnulib/lib/Makefile.in 2014-11-04 10:38:35.629518946 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/Makefile.in 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1285 +0,0 @@ +-# Makefile.in generated by automake 1.14 from Makefile.am. +-# @configure_input@ +- +-# Copyright (C) 1994-2013 Free Software Foundation, Inc. +- +-# This Makefile.in is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +-# PARTICULAR PURPOSE. +- +-@SET_MAKE@ +- +-# Copyright (C) 2002-2014 Free Software Foundation, Inc. +-# +-# This file is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 3 of the License, or +-# (at your option) any later version. +-# +-# This file is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this file. If not, see . +-# +-# As a special exception to the GNU General Public License, +-# this file may be distributed as part of a program that +-# contains a configuration script generated by Autoconf, under +-# the same distribution terms as the rest of that program. +-# +-# Generated by gnulib-tool. +-# Reproduce by: gnulib-tool --import --dir=src/libs/gnulib --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl wcwidth +- +- +- +-VPATH = @srcdir@ +-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +-am__make_running_with_option = \ +- case $${target_option-} in \ +- ?) ;; \ +- *) echo "am__make_running_with_option: internal error: invalid" \ +- "target option '$${target_option-}' specified" >&2; \ +- exit 1;; \ +- esac; \ +- has_opt=no; \ +- sane_makeflags=$$MAKEFLAGS; \ +- if $(am__is_gnu_make); then \ +- sane_makeflags=$$MFLAGS; \ +- else \ +- case $$MAKEFLAGS in \ +- *\\[\ \ ]*) \ +- bs=\\; \ +- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ +- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ +- esac; \ +- fi; \ +- skip_next=no; \ +- strip_trailopt () \ +- { \ +- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ +- }; \ +- for flg in $$sane_makeflags; do \ +- test $$skip_next = yes && { skip_next=no; continue; }; \ +- case $$flg in \ +- *=*|--*) continue;; \ +- -*I) strip_trailopt 'I'; skip_next=yes;; \ +- -*I?*) strip_trailopt 'I';; \ +- -*O) strip_trailopt 'O'; skip_next=yes;; \ +- -*O?*) strip_trailopt 'O';; \ +- -*l) strip_trailopt 'l'; skip_next=yes;; \ +- -*l?*) strip_trailopt 'l';; \ +- -[dEDm]) skip_next=yes;; \ +- -[JT]) skip_next=yes;; \ +- esac; \ +- case $$flg in \ +- *$$target_option*) has_opt=yes; break;; \ +- esac; \ +- done; \ +- test $$has_opt = yes +-am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +-am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +-pkgdatadir = $(datadir)/@PACKAGE@ +-pkgincludedir = $(includedir)/@PACKAGE@ +-pkglibdir = $(libdir)/@PACKAGE@ +-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +-install_sh_DATA = $(install_sh) -c -m 644 +-install_sh_PROGRAM = $(install_sh) -c +-install_sh_SCRIPT = $(install_sh) -c +-INSTALL_HEADER = $(INSTALL_DATA) +-transform = $(program_transform_name) +-NORMAL_INSTALL = : +-PRE_INSTALL = : +-POST_INSTALL = : +-NORMAL_UNINSTALL = : +-PRE_UNINSTALL = : +-POST_UNINSTALL = : +-build_triplet = @build@ +-host_triplet = @host@ +-@LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE@am__append_1 = uniwidth/width.c +-subdir = lib +-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ +- $(top_srcdir)/build-aux/depcomp $(noinst_HEADERS) +-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ +- $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/configmake.m4 \ +- $(top_srcdir)/m4/extensions.m4 \ +- $(top_srcdir)/m4/extern-inline.m4 $(top_srcdir)/m4/fcntl-o.m4 \ +- $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/gnulib-common.m4 \ +- $(top_srcdir)/m4/include_next.m4 \ +- $(top_srcdir)/m4/inttypes-pri.m4 $(top_srcdir)/m4/inttypes.m4 \ +- $(top_srcdir)/m4/libunistring-base.m4 \ +- $(top_srcdir)/m4/localcharset.m4 $(top_srcdir)/m4/longlong.m4 \ +- $(top_srcdir)/m4/multiarch.m4 $(top_srcdir)/m4/onceonly.m4 \ +- $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \ +- $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/warn-on-use.m4 \ +- $(top_srcdir)/m4/wchar_h.m4 $(top_srcdir)/m4/wchar_t.m4 \ +- $(top_srcdir)/m4/wctype_h.m4 $(top_srcdir)/m4/wcwidth.m4 \ +- $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/configure.ac +-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ +- $(ACLOCAL_M4) +-mkinstalldirs = $(install_sh) -d +-CONFIG_HEADER = $(top_builddir)/config.h +-CONFIG_CLEAN_FILES = +-CONFIG_CLEAN_VPATH_FILES = +-LIBRARIES = $(noinst_LIBRARIES) +-AM_V_AR = $(am__v_AR_@AM_V@) +-am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +-am__v_AR_0 = @echo " AR " $@; +-am__v_AR_1 = +-libgnu_a_AR = $(AR) $(ARFLAGS) +-am__DEPENDENCIES_1 = +-am__libgnu_a_SOURCES_DIST = localcharset.h localcharset.c \ +- uniwidth/width.c wctype-h.c +-am__dirstamp = $(am__leading_dot)dirstamp +-@LIBUNISTRING_COMPILE_UNIWIDTH_WIDTH_TRUE@am__objects_1 = uniwidth/width.$(OBJEXT) +-am_libgnu_a_OBJECTS = localcharset.$(OBJEXT) $(am__objects_1) \ +- wctype-h.$(OBJEXT) +-libgnu_a_OBJECTS = $(am_libgnu_a_OBJECTS) +-LTLIBRARIES = $(noinst_LTLIBRARIES) +-AM_V_P = $(am__v_P_@AM_V@) +-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +-am__v_P_0 = false +-am__v_P_1 = : +-AM_V_GEN = $(am__v_GEN_@AM_V@) +-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +-am__v_GEN_0 = @echo " GEN " $@; +-am__v_GEN_1 = +-AM_V_at = $(am__v_at_@AM_V@) +-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +-am__v_at_0 = @ +-am__v_at_1 = +-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +-depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +-am__depfiles_maybe = depfiles +-am__mv = mv -f +-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ +- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +-AM_V_CC = $(am__v_CC_@AM_V@) +-am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +-am__v_CC_0 = @echo " CC " $@; +-am__v_CC_1 = +-CCLD = $(CC) +-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +-AM_V_CCLD = $(am__v_CCLD_@AM_V@) +-am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +-am__v_CCLD_0 = @echo " CCLD " $@; +-am__v_CCLD_1 = +-SOURCES = $(libgnu_a_SOURCES) $(EXTRA_libgnu_a_SOURCES) +-DIST_SOURCES = $(am__libgnu_a_SOURCES_DIST) $(EXTRA_libgnu_a_SOURCES) +-RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ +- ctags-recursive dvi-recursive html-recursive info-recursive \ +- install-data-recursive install-dvi-recursive \ +- install-exec-recursive install-html-recursive \ +- install-info-recursive install-pdf-recursive \ +- install-ps-recursive install-recursive installcheck-recursive \ +- installdirs-recursive pdf-recursive ps-recursive \ +- tags-recursive uninstall-recursive +-am__can_run_installinfo = \ +- case $$AM_UPDATE_INFO_DIR in \ +- n|no|NO) false;; \ +- *) (install-info --version) >/dev/null 2>&1;; \ +- esac +-HEADERS = $(noinst_HEADERS) +-RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ +- distclean-recursive maintainer-clean-recursive +-am__recursive_targets = \ +- $(RECURSIVE_TARGETS) \ +- $(RECURSIVE_CLEAN_TARGETS) \ +- $(am__extra_recursive_targets) +-AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ +- distdir +-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +-# Read a list of newline-separated strings from the standard input, +-# and print each of them once, without duplicates. Input order is +-# *not* preserved. +-am__uniquify_input = $(AWK) '\ +- BEGIN { nonempty = 0; } \ +- { items[$$0] = 1; nonempty = 1; } \ +- END { if (nonempty) { for (i in items) print i; }; } \ +-' +-# Make sure the list of sources is unique. This is necessary because, +-# e.g., the same source file might be shared among _SOURCES variables +-# for different programs/libraries. +-am__define_uniq_tagged_files = \ +- list='$(am__tagged_files)'; \ +- unique=`for i in $$list; do \ +- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +- done | $(am__uniquify_input)` +-ETAGS = etags +-CTAGS = ctags +-DIST_SUBDIRS = $(SUBDIRS) +-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +-am__relativize = \ +- dir0=`pwd`; \ +- sed_first='s,^\([^/]*\)/.*$$,\1,'; \ +- sed_rest='s,^[^/]*/*,,'; \ +- sed_last='s,^.*/\([^/]*\)$$,\1,'; \ +- sed_butlast='s,/*[^/]*$$,,'; \ +- while test -n "$$dir1"; do \ +- first=`echo "$$dir1" | sed -e "$$sed_first"`; \ +- if test "$$first" != "."; then \ +- if test "$$first" = ".."; then \ +- dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ +- dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ +- else \ +- first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ +- if test "$$first2" = "$$first"; then \ +- dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ +- else \ +- dir2="../$$dir2"; \ +- fi; \ +- dir0="$$dir0"/"$$first"; \ +- fi; \ +- fi; \ +- dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ +- done; \ +- reldir="$$dir2" +-pkglibexecdir = @pkglibexecdir@ +-ACLOCAL = @ACLOCAL@ +-AMTAR = @AMTAR@ +-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +-APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@ +-AR = @AR@ +-ARFLAGS = @ARFLAGS@ +-AUTOCONF = @AUTOCONF@ +-AUTOHEADER = @AUTOHEADER@ +-AUTOMAKE = @AUTOMAKE@ +-AWK = @AWK@ +-BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +-BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +-BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +-BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +-BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +-CC = @CC@ +-CCDEPMODE = @CCDEPMODE@ +-CFLAGS = @CFLAGS@ +-CPP = @CPP@ +-CPPFLAGS = @CPPFLAGS@ +-CYGPATH_W = @CYGPATH_W@ +-DEFS = @DEFS@ +-DEPDIR = @DEPDIR@ +-ECHO_C = @ECHO_C@ +-ECHO_N = @ECHO_N@ +-ECHO_T = @ECHO_T@ +-EGREP = @EGREP@ +-EXEEXT = @EXEEXT@ +-GLIBC21 = @GLIBC21@ +-GNULIB_BTOWC = @GNULIB_BTOWC@ +-GNULIB_IMAXABS = @GNULIB_IMAXABS@ +-GNULIB_IMAXDIV = @GNULIB_IMAXDIV@ +-GNULIB_ISWBLANK = @GNULIB_ISWBLANK@ +-GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@ +-GNULIB_MBRLEN = @GNULIB_MBRLEN@ +-GNULIB_MBRTOWC = @GNULIB_MBRTOWC@ +-GNULIB_MBSINIT = @GNULIB_MBSINIT@ +-GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@ +-GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@ +-GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@ +-GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@ +-GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@ +-GNULIB_WCPCPY = @GNULIB_WCPCPY@ +-GNULIB_WCPNCPY = @GNULIB_WCPNCPY@ +-GNULIB_WCRTOMB = @GNULIB_WCRTOMB@ +-GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@ +-GNULIB_WCSCAT = @GNULIB_WCSCAT@ +-GNULIB_WCSCHR = @GNULIB_WCSCHR@ +-GNULIB_WCSCMP = @GNULIB_WCSCMP@ +-GNULIB_WCSCOLL = @GNULIB_WCSCOLL@ +-GNULIB_WCSCPY = @GNULIB_WCSCPY@ +-GNULIB_WCSCSPN = @GNULIB_WCSCSPN@ +-GNULIB_WCSDUP = @GNULIB_WCSDUP@ +-GNULIB_WCSLEN = @GNULIB_WCSLEN@ +-GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@ +-GNULIB_WCSNCAT = @GNULIB_WCSNCAT@ +-GNULIB_WCSNCMP = @GNULIB_WCSNCMP@ +-GNULIB_WCSNCPY = @GNULIB_WCSNCPY@ +-GNULIB_WCSNLEN = @GNULIB_WCSNLEN@ +-GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@ +-GNULIB_WCSPBRK = @GNULIB_WCSPBRK@ +-GNULIB_WCSRCHR = @GNULIB_WCSRCHR@ +-GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@ +-GNULIB_WCSSPN = @GNULIB_WCSSPN@ +-GNULIB_WCSSTR = @GNULIB_WCSSTR@ +-GNULIB_WCSTOK = @GNULIB_WCSTOK@ +-GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@ +-GNULIB_WCSXFRM = @GNULIB_WCSXFRM@ +-GNULIB_WCTOB = @GNULIB_WCTOB@ +-GNULIB_WCTRANS = @GNULIB_WCTRANS@ +-GNULIB_WCTYPE = @GNULIB_WCTYPE@ +-GNULIB_WCWIDTH = @GNULIB_WCWIDTH@ +-GNULIB_WMEMCHR = @GNULIB_WMEMCHR@ +-GNULIB_WMEMCMP = @GNULIB_WMEMCMP@ +-GNULIB_WMEMCPY = @GNULIB_WMEMCPY@ +-GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@ +-GNULIB_WMEMSET = @GNULIB_WMEMSET@ +-GREP = @GREP@ +-HAVE_BTOWC = @HAVE_BTOWC@ +-HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@ +-HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@ +-HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@ +-HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@ +-HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@ +-HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@ +-HAVE_FEATURES_H = @HAVE_FEATURES_H@ +-HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +-HAVE_ISWBLANK = @HAVE_ISWBLANK@ +-HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ +-HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +-HAVE_MBRLEN = @HAVE_MBRLEN@ +-HAVE_MBRTOWC = @HAVE_MBRTOWC@ +-HAVE_MBSINIT = @HAVE_MBSINIT@ +-HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@ +-HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@ +-HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +-HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +-HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +-HAVE_STDINT_H = @HAVE_STDINT_H@ +-HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +-HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +-HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +-HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +-HAVE_WCHAR_H = @HAVE_WCHAR_H@ +-HAVE_WCHAR_T = @HAVE_WCHAR_T@ +-HAVE_WCPCPY = @HAVE_WCPCPY@ +-HAVE_WCPNCPY = @HAVE_WCPNCPY@ +-HAVE_WCRTOMB = @HAVE_WCRTOMB@ +-HAVE_WCSCASECMP = @HAVE_WCSCASECMP@ +-HAVE_WCSCAT = @HAVE_WCSCAT@ +-HAVE_WCSCHR = @HAVE_WCSCHR@ +-HAVE_WCSCMP = @HAVE_WCSCMP@ +-HAVE_WCSCOLL = @HAVE_WCSCOLL@ +-HAVE_WCSCPY = @HAVE_WCSCPY@ +-HAVE_WCSCSPN = @HAVE_WCSCSPN@ +-HAVE_WCSDUP = @HAVE_WCSDUP@ +-HAVE_WCSLEN = @HAVE_WCSLEN@ +-HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@ +-HAVE_WCSNCAT = @HAVE_WCSNCAT@ +-HAVE_WCSNCMP = @HAVE_WCSNCMP@ +-HAVE_WCSNCPY = @HAVE_WCSNCPY@ +-HAVE_WCSNLEN = @HAVE_WCSNLEN@ +-HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@ +-HAVE_WCSPBRK = @HAVE_WCSPBRK@ +-HAVE_WCSRCHR = @HAVE_WCSRCHR@ +-HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@ +-HAVE_WCSSPN = @HAVE_WCSSPN@ +-HAVE_WCSSTR = @HAVE_WCSSTR@ +-HAVE_WCSTOK = @HAVE_WCSTOK@ +-HAVE_WCSWIDTH = @HAVE_WCSWIDTH@ +-HAVE_WCSXFRM = @HAVE_WCSXFRM@ +-HAVE_WCTRANS_T = @HAVE_WCTRANS_T@ +-HAVE_WCTYPE_H = @HAVE_WCTYPE_H@ +-HAVE_WCTYPE_T = @HAVE_WCTYPE_T@ +-HAVE_WINT_T = @HAVE_WINT_T@ +-HAVE_WMEMCHR = @HAVE_WMEMCHR@ +-HAVE_WMEMCMP = @HAVE_WMEMCMP@ +-HAVE_WMEMCPY = @HAVE_WMEMCPY@ +-HAVE_WMEMMOVE = @HAVE_WMEMMOVE@ +-HAVE_WMEMSET = @HAVE_WMEMSET@ +-HAVE__BOOL = @HAVE__BOOL@ +-INCLUDE_NEXT = @INCLUDE_NEXT@ +-INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ +-INSTALL = @INSTALL@ +-INSTALL_DATA = @INSTALL_DATA@ +-INSTALL_PROGRAM = @INSTALL_PROGRAM@ +-INSTALL_SCRIPT = @INSTALL_SCRIPT@ +-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +-INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@ +-INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@ +-LDFLAGS = @LDFLAGS@ +-LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +-LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +-LIBOBJS = @LIBOBJS@ +-LIBS = @LIBS@ +-LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@ +-LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@ +-LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ +-LTLIBOBJS = @LTLIBOBJS@ +-MAKEINFO = @MAKEINFO@ +-MKDIR_P = @MKDIR_P@ +-NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@ +-NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@ +-NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@ +-NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@ +-NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@ +-NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ +-NEXT_STDDEF_H = @NEXT_STDDEF_H@ +-NEXT_STDINT_H = @NEXT_STDINT_H@ +-NEXT_WCHAR_H = @NEXT_WCHAR_H@ +-NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ +-OBJEXT = @OBJEXT@ +-PACKAGE = @PACKAGE@ +-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +-PACKAGE_NAME = @PACKAGE_NAME@ +-PACKAGE_STRING = @PACKAGE_STRING@ +-PACKAGE_TARNAME = @PACKAGE_TARNAME@ +-PACKAGE_URL = @PACKAGE_URL@ +-PACKAGE_VERSION = @PACKAGE_VERSION@ +-PATH_SEPARATOR = @PATH_SEPARATOR@ +-PRAGMA_COLUMNS = @PRAGMA_COLUMNS@ +-PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ +-PRIPTR_PREFIX = @PRIPTR_PREFIX@ +-PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ +-PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +-RANLIB = @RANLIB@ +-REPLACE_BTOWC = @REPLACE_BTOWC@ +-REPLACE_ISWBLANK = @REPLACE_ISWBLANK@ +-REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@ +-REPLACE_MBRLEN = @REPLACE_MBRLEN@ +-REPLACE_MBRTOWC = @REPLACE_MBRTOWC@ +-REPLACE_MBSINIT = @REPLACE_MBSINIT@ +-REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@ +-REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@ +-REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@ +-REPLACE_NULL = @REPLACE_NULL@ +-REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@ +-REPLACE_TOWLOWER = @REPLACE_TOWLOWER@ +-REPLACE_WCRTOMB = @REPLACE_WCRTOMB@ +-REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@ +-REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@ +-REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@ +-REPLACE_WCTOB = @REPLACE_WCTOB@ +-REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ +-SET_MAKE = @SET_MAKE@ +-SHELL = @SHELL@ +-SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +-SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +-STDBOOL_H = @STDBOOL_H@ +-STDDEF_H = @STDDEF_H@ +-STDINT_H = @STDINT_H@ +-STRIP = @STRIP@ +-UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ +-UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ +-VERSION = @VERSION@ +-WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +-WINT_T_SUFFIX = @WINT_T_SUFFIX@ +-abs_builddir = @abs_builddir@ +-abs_srcdir = @abs_srcdir@ +-abs_top_builddir = @abs_top_builddir@ +-abs_top_srcdir = @abs_top_srcdir@ +-ac_ct_CC = @ac_ct_CC@ +-am__include = @am__include@ +-am__leading_dot = @am__leading_dot@ +-am__quote = @am__quote@ +-am__tar = @am__tar@ +-am__untar = @am__untar@ +-bindir = @bindir@ +-build = @build@ +-build_alias = @build_alias@ +-build_cpu = @build_cpu@ +-build_os = @build_os@ +-build_vendor = @build_vendor@ +-builddir = @builddir@ +-datadir = @datadir@ +-datarootdir = @datarootdir@ +-docdir = @docdir@ +-dvidir = @dvidir@ +-exec_prefix = @exec_prefix@ +-gl_LIBOBJS = @gl_LIBOBJS@ +-gl_LTLIBOBJS = @gl_LTLIBOBJS@ +-host = @host@ +-host_alias = @host_alias@ +-host_cpu = @host_cpu@ +-host_os = @host_os@ +-host_vendor = @host_vendor@ +-htmldir = @htmldir@ +-includedir = @includedir@ +-infodir = @infodir@ +-install_sh = @install_sh@ +-libdir = @libdir@ +-libexecdir = @libexecdir@ +-lispdir = @lispdir@ +-localedir = @localedir@ +-localstatedir = @localstatedir@ +-mandir = @mandir@ +-mkdir_p = @mkdir_p@ +-oldincludedir = @oldincludedir@ +-pdfdir = @pdfdir@ +-prefix = @prefix@ +-program_transform_name = @program_transform_name@ +-psdir = @psdir@ +-runstatedir = @runstatedir@ +-sbindir = @sbindir@ +-sharedstatedir = @sharedstatedir@ +-srcdir = @srcdir@ +-sysconfdir = @sysconfdir@ +-target_alias = @target_alias@ +-top_build_prefix = @top_build_prefix@ +-top_builddir = @top_builddir@ +-top_srcdir = @top_srcdir@ +-AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects +-SUBDIRS = +-noinst_HEADERS = +-noinst_LIBRARIES = libgnu.a +-noinst_LTLIBRARIES = +-EXTRA_DIST = config.charset ref-add.sin ref-del.sin \ +- $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ +- $(top_srcdir)/build-aux/snippet/c++defs.h \ +- $(top_srcdir)/build-aux/snippet/warn-on-use.h stddef.in.h \ +- stdint.in.h streq.h unitypes.in.h localcharset.h uniwidth.in.h \ +- uniwidth/cjk.h wchar.in.h wctype.in.h wcwidth.c +- +-# The BUILT_SOURCES created by this Makefile snippet are not used via #include +-# statements but through direct file reference. Therefore this snippet must be +-# present in all Makefile.am that need it. This is ensured by the applicability +-# 'all' defined above. +- +-# The BUILT_SOURCES created by this Makefile snippet are not used via #include +-# statements but through direct file reference. Therefore this snippet must be +-# present in all Makefile.am that need it. This is ensured by the applicability +-# 'all' defined above. +-BUILT_SOURCES = configmake.h arg-nonnull.h c++defs.h warn-on-use.h \ +- $(STDDEF_H) $(STDINT_H) $(LIBUNISTRING_UNITYPES_H) \ +- $(LIBUNISTRING_UNIWIDTH_H) wchar.h wctype.h +-SUFFIXES = .sed .sin +-MOSTLYCLEANFILES = core *.stackdump arg-nonnull.h arg-nonnull.h-t \ +- c++defs.h c++defs.h-t warn-on-use.h warn-on-use.h-t stddef.h \ +- stddef.h-t stdint.h stdint.h-t unitypes.h unitypes.h-t \ +- uniwidth.h uniwidth.h-t wchar.h wchar.h-t wctype.h wctype.h-t +-MOSTLYCLEANDIRS = +-CLEANFILES = configmake.h configmake.h-t charset.alias ref-add.sed \ +- ref-del.sed +-DISTCLEANFILES = +-MAINTAINERCLEANFILES = +-AM_CPPFLAGS = +-AM_CFLAGS = +-libgnu_a_SOURCES = localcharset.h localcharset.c $(am__append_1) \ +- wctype-h.c +-libgnu_a_LIBADD = $(gl_LIBOBJS) +-libgnu_a_DEPENDENCIES = $(gl_LIBOBJS) +-EXTRA_libgnu_a_SOURCES = wcwidth.c +-charset_alias = $(DESTDIR)$(libdir)/charset.alias +-charset_tmp = $(DESTDIR)$(libdir)/charset.tmp +-ARG_NONNULL_H = arg-nonnull.h +-CXXDEFS_H = c++defs.h +-WARN_ON_USE_H = warn-on-use.h +-all: $(BUILT_SOURCES) +- $(MAKE) $(AM_MAKEFLAGS) all-recursive +- +-.SUFFIXES: +-.SUFFIXES: .sed .sin .c .o .obj +-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +- @for dep in $?; do \ +- case '$(am__configure_deps)' in \ +- *$$dep*) \ +- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ +- && { if test -f $@; then exit 0; else break; fi; }; \ +- exit 1;; \ +- esac; \ +- done; \ +- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits lib/Makefile'; \ +- $(am__cd) $(top_srcdir) && \ +- $(AUTOMAKE) --gnits lib/Makefile +-.PRECIOUS: Makefile +-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status +- @case '$?' in \ +- *config.status*) \ +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ +- *) \ +- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ +- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ +- esac; +- +-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +- +-$(top_srcdir)/configure: $(am__configure_deps) +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +-$(ACLOCAL_M4): $(am__aclocal_m4_deps) +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +-$(am__aclocal_m4_deps): +- +-clean-noinstLIBRARIES: +- -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +-uniwidth/$(am__dirstamp): +- @$(MKDIR_P) uniwidth +- @: > uniwidth/$(am__dirstamp) +-uniwidth/$(DEPDIR)/$(am__dirstamp): +- @$(MKDIR_P) uniwidth/$(DEPDIR) +- @: > uniwidth/$(DEPDIR)/$(am__dirstamp) +-uniwidth/width.$(OBJEXT): uniwidth/$(am__dirstamp) \ +- uniwidth/$(DEPDIR)/$(am__dirstamp) +- +-libgnu.a: $(libgnu_a_OBJECTS) $(libgnu_a_DEPENDENCIES) $(EXTRA_libgnu_a_DEPENDENCIES) +- $(AM_V_at)-rm -f libgnu.a +- $(AM_V_AR)$(libgnu_a_AR) libgnu.a $(libgnu_a_OBJECTS) $(libgnu_a_LIBADD) +- $(AM_V_at)$(RANLIB) libgnu.a +- +-clean-noinstLTLIBRARIES: +- -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) +- @list='$(noinst_LTLIBRARIES)'; \ +- locs=`for p in $$list; do echo $$p; done | \ +- sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ +- sort -u`; \ +- test -z "$$locs" || { \ +- echo rm -f $${locs}; \ +- rm -f $${locs}; \ +- } +- +-mostlyclean-compile: +- -rm -f *.$(OBJEXT) +- -rm -f uniwidth/*.$(OBJEXT) +- +-distclean-compile: +- -rm -f *.tab.c +- +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localcharset.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wctype-h.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcwidth.Po@am__quote@ +-@AMDEP_TRUE@@am__include@ @am__quote@uniwidth/$(DEPDIR)/width.Po@am__quote@ +- +-.c.o: +-@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +-@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< +- +-.c.obj: +-@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +-@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +- +-# This directory's subdirectories are mostly independent; you can cd +-# into them and run 'make' without going through this Makefile. +-# To change the values of 'make' variables: instead of editing Makefiles, +-# (1) if the variable is set in 'config.status', edit 'config.status' +-# (which will cause the Makefiles to be regenerated when you run 'make'); +-# (2) otherwise, pass the desired values on the 'make' command line. +-$(am__recursive_targets): +- @fail=; \ +- if $(am__make_keepgoing); then \ +- failcom='fail=yes'; \ +- else \ +- failcom='exit 1'; \ +- fi; \ +- dot_seen=no; \ +- target=`echo $@ | sed s/-recursive//`; \ +- case "$@" in \ +- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ +- *) list='$(SUBDIRS)' ;; \ +- esac; \ +- for subdir in $$list; do \ +- echo "Making $$target in $$subdir"; \ +- if test "$$subdir" = "."; then \ +- dot_seen=yes; \ +- local_target="$$target-am"; \ +- else \ +- local_target="$$target"; \ +- fi; \ +- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ +- || eval $$failcom; \ +- done; \ +- if test "$$dot_seen" = "no"; then \ +- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ +- fi; test -z "$$fail" +- +-ID: $(am__tagged_files) +- $(am__define_uniq_tagged_files); mkid -fID $$unique +-tags: tags-recursive +-TAGS: tags +- +-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +- set x; \ +- here=`pwd`; \ +- if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ +- include_option=--etags-include; \ +- empty_fix=.; \ +- else \ +- include_option=--include; \ +- empty_fix=; \ +- fi; \ +- list='$(SUBDIRS)'; for subdir in $$list; do \ +- if test "$$subdir" = .; then :; else \ +- test ! -f $$subdir/TAGS || \ +- set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ +- fi; \ +- done; \ +- $(am__define_uniq_tagged_files); \ +- shift; \ +- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ +- test -n "$$unique" || unique=$$empty_fix; \ +- if test $$# -gt 0; then \ +- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +- "$$@" $$unique; \ +- else \ +- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +- $$unique; \ +- fi; \ +- fi +-ctags: ctags-recursive +- +-CTAGS: ctags +-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +- $(am__define_uniq_tagged_files); \ +- test -z "$(CTAGS_ARGS)$$unique" \ +- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ +- $$unique +- +-GTAGS: +- here=`$(am__cd) $(top_builddir) && pwd` \ +- && $(am__cd) $(top_srcdir) \ +- && gtags -i $(GTAGS_ARGS) "$$here" +-cscopelist: cscopelist-recursive +- +-cscopelist-am: $(am__tagged_files) +- list='$(am__tagged_files)'; \ +- case "$(srcdir)" in \ +- [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ +- *) sdir=$(subdir)/$(srcdir) ;; \ +- esac; \ +- for i in $$list; do \ +- if test -f "$$i"; then \ +- echo "$(subdir)/$$i"; \ +- else \ +- echo "$$sdir/$$i"; \ +- fi; \ +- done >> $(top_builddir)/cscope.files +- +-distclean-tags: +- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +- +-distdir: $(DISTFILES) +- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +- list='$(DISTFILES)'; \ +- dist_files=`for file in $$list; do echo $$file; done | \ +- sed -e "s|^$$srcdirstrip/||;t" \ +- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ +- case $$dist_files in \ +- */*) $(MKDIR_P) `echo "$$dist_files" | \ +- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ +- sort -u` ;; \ +- esac; \ +- for file in $$dist_files; do \ +- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ +- if test -d $$d/$$file; then \ +- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ +- if test -d "$(distdir)/$$file"; then \ +- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +- fi; \ +- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ +- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ +- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +- fi; \ +- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ +- else \ +- test -f "$(distdir)/$$file" \ +- || cp -p $$d/$$file "$(distdir)/$$file" \ +- || exit 1; \ +- fi; \ +- done +- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ +- if test "$$subdir" = .; then :; else \ +- $(am__make_dryrun) \ +- || test -d "$(distdir)/$$subdir" \ +- || $(MKDIR_P) "$(distdir)/$$subdir" \ +- || exit 1; \ +- dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ +- $(am__relativize); \ +- new_distdir=$$reldir; \ +- dir1=$$subdir; dir2="$(top_distdir)"; \ +- $(am__relativize); \ +- new_top_distdir=$$reldir; \ +- echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ +- echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ +- ($(am__cd) $$subdir && \ +- $(MAKE) $(AM_MAKEFLAGS) \ +- top_distdir="$$new_top_distdir" \ +- distdir="$$new_distdir" \ +- am__remove_distdir=: \ +- am__skip_length_check=: \ +- am__skip_mode_fix=: \ +- distdir) \ +- || exit 1; \ +- fi; \ +- done +-check-am: all-am +-check: $(BUILT_SOURCES) +- $(MAKE) $(AM_MAKEFLAGS) check-recursive +-all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS) all-local +-installdirs: installdirs-recursive +-installdirs-am: +-install: $(BUILT_SOURCES) +- $(MAKE) $(AM_MAKEFLAGS) install-recursive +-install-exec: install-exec-recursive +-install-data: install-data-recursive +-uninstall: uninstall-recursive +- +-install-am: all-am +- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +- +-installcheck: installcheck-recursive +-install-strip: +- if test -z '$(STRIP)'; then \ +- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +- install; \ +- else \ +- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ +- fi +-mostlyclean-generic: +- -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) +- +-clean-generic: +- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) +- +-distclean-generic: +- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) +- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) +- -rm -f uniwidth/$(DEPDIR)/$(am__dirstamp) +- -rm -f uniwidth/$(am__dirstamp) +- -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) +- +-maintainer-clean-generic: +- @echo "This command is intended for maintainers to use" +- @echo "it deletes files that may require special tools to rebuild." +- -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +- -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +-clean: clean-recursive +- +-clean-am: clean-generic clean-noinstLIBRARIES clean-noinstLTLIBRARIES \ +- mostlyclean-am +- +-distclean: distclean-recursive +- -rm -rf ./$(DEPDIR) uniwidth/$(DEPDIR) +- -rm -f Makefile +-distclean-am: clean-am distclean-compile distclean-generic \ +- distclean-tags +- +-dvi: dvi-recursive +- +-dvi-am: +- +-html: html-recursive +- +-html-am: +- +-info: info-recursive +- +-info-am: +- +-install-data-am: +- +-install-dvi: install-dvi-recursive +- +-install-dvi-am: +- +-install-exec-am: install-exec-local +- +-install-html: install-html-recursive +- +-install-html-am: +- +-install-info: install-info-recursive +- +-install-info-am: +- +-install-man: +- +-install-pdf: install-pdf-recursive +- +-install-pdf-am: +- +-install-ps: install-ps-recursive +- +-install-ps-am: +- +-installcheck-am: +- +-maintainer-clean: maintainer-clean-recursive +- -rm -rf ./$(DEPDIR) uniwidth/$(DEPDIR) +- -rm -f Makefile +-maintainer-clean-am: distclean-am maintainer-clean-generic +- +-mostlyclean: mostlyclean-recursive +- +-mostlyclean-am: mostlyclean-compile mostlyclean-generic \ +- mostlyclean-local +- +-pdf: pdf-recursive +- +-pdf-am: +- +-ps: ps-recursive +- +-ps-am: +- +-uninstall-am: uninstall-local +- +-.MAKE: $(am__recursive_targets) all check install install-am \ +- install-strip +- +-.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ +- check check-am clean clean-generic clean-noinstLIBRARIES \ +- clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ +- distclean-compile distclean-generic distclean-tags distdir dvi \ +- dvi-am html html-am info info-am install install-am \ +- install-data install-data-am install-dvi install-dvi-am \ +- install-exec install-exec-am install-exec-local install-html \ +- install-html-am install-info install-info-am install-man \ +- install-pdf install-pdf-am install-ps install-ps-am \ +- install-strip installcheck installcheck-am installdirs \ +- installdirs-am maintainer-clean maintainer-clean-generic \ +- mostlyclean mostlyclean-compile mostlyclean-generic \ +- mostlyclean-local pdf pdf-am ps ps-am tags tags-am uninstall \ +- uninstall-am uninstall-local +- +- +-# Listed in the same order as the GNU makefile conventions, and +-# provided by autoconf 2.59c+. +-# The Automake-defined pkg* macros are appended, in the order +-# listed in the Automake 1.10a+ documentation. +-configmake.h: Makefile +- $(AM_V_GEN)rm -f $@-t && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- echo '#define PREFIX "$(prefix)"'; \ +- echo '#define EXEC_PREFIX "$(exec_prefix)"'; \ +- echo '#define BINDIR "$(bindir)"'; \ +- echo '#define SBINDIR "$(sbindir)"'; \ +- echo '#define LIBEXECDIR "$(libexecdir)"'; \ +- echo '#define DATAROOTDIR "$(datarootdir)"'; \ +- echo '#define DATADIR "$(datadir)"'; \ +- echo '#define SYSCONFDIR "$(sysconfdir)"'; \ +- echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \ +- echo '#define LOCALSTATEDIR "$(localstatedir)"'; \ +- echo '#define INCLUDEDIR "$(includedir)"'; \ +- echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \ +- echo '#define DOCDIR "$(docdir)"'; \ +- echo '#define INFODIR "$(infodir)"'; \ +- echo '#define HTMLDIR "$(htmldir)"'; \ +- echo '#define DVIDIR "$(dvidir)"'; \ +- echo '#define PDFDIR "$(pdfdir)"'; \ +- echo '#define PSDIR "$(psdir)"'; \ +- echo '#define LIBDIR "$(libdir)"'; \ +- echo '#define LISPDIR "$(lispdir)"'; \ +- echo '#define LOCALEDIR "$(localedir)"'; \ +- echo '#define MANDIR "$(mandir)"'; \ +- echo '#define MANEXT "$(manext)"'; \ +- echo '#define PKGDATADIR "$(pkgdatadir)"'; \ +- echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \ +- echo '#define PKGLIBDIR "$(pkglibdir)"'; \ +- echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \ +- } | sed '/""/d' > $@-t && \ +- mv -f $@-t $@ +- +-# We need the following in order to install a simple file in $(libdir) +-# which is shared with other installed packages. We use a list of referencing +-# packages so that "make uninstall" will remove the file if and only if it +-# is not used by another installed package. +-# On systems with glibc-2.1 or newer, the file is redundant, therefore we +-# avoid installing it. +- +-all-local: charset.alias ref-add.sed ref-del.sed +-install-exec-local: install-exec-localcharset +-install-exec-localcharset: all-local +- if test $(GLIBC21) = no; then \ +- case '$(host_os)' in \ +- darwin[56]*) \ +- need_charset_alias=true ;; \ +- darwin* | cygwin* | mingw* | pw32* | cegcc*) \ +- need_charset_alias=false ;; \ +- *) \ +- need_charset_alias=true ;; \ +- esac ; \ +- else \ +- need_charset_alias=false ; \ +- fi ; \ +- if $$need_charset_alias; then \ +- $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ +- fi ; \ +- if test -f $(charset_alias); then \ +- sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ +- $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ +- rm -f $(charset_tmp) ; \ +- else \ +- if $$need_charset_alias; then \ +- sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ +- $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ +- rm -f $(charset_tmp) ; \ +- fi ; \ +- fi +- +-uninstall-local: uninstall-localcharset +-uninstall-localcharset: all-local +- if test -f $(charset_alias); then \ +- sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ +- if grep '^# Packages using this file: $$' $(charset_tmp) \ +- > /dev/null; then \ +- rm -f $(charset_alias); \ +- else \ +- $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ +- fi; \ +- rm -f $(charset_tmp); \ +- fi +- +-charset.alias: config.charset +- $(AM_V_GEN)rm -f t-$@ $@ && \ +- $(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \ +- mv t-$@ $@ +-.sin.sed: +- $(AM_V_GEN)rm -f t-$@ $@ && \ +- sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \ +- mv t-$@ $@ +-# The arg-nonnull.h that gets inserted into generated .h files is the same as +-# build-aux/snippet/arg-nonnull.h, except that it has the copyright header cut +-# off. +-arg-nonnull.h: $(top_srcdir)/build-aux/snippet/arg-nonnull.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- sed -n -e '/GL_ARG_NONNULL/,$$p' \ +- < $(top_srcdir)/build-aux/snippet/arg-nonnull.h \ +- > $@-t && \ +- mv $@-t $@ +-# The c++defs.h that gets inserted into generated .h files is the same as +-# build-aux/snippet/c++defs.h, except that it has the copyright header cut off. +-c++defs.h: $(top_srcdir)/build-aux/snippet/c++defs.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- sed -n -e '/_GL_CXXDEFS/,$$p' \ +- < $(top_srcdir)/build-aux/snippet/c++defs.h \ +- > $@-t && \ +- mv $@-t $@ +-# The warn-on-use.h that gets inserted into generated .h files is the same as +-# build-aux/snippet/warn-on-use.h, except that it has the copyright header cut +-# off. +-warn-on-use.h: $(top_srcdir)/build-aux/snippet/warn-on-use.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- sed -n -e '/^.ifndef/,$$p' \ +- < $(top_srcdir)/build-aux/snippet/warn-on-use.h \ +- > $@-t && \ +- mv $@-t $@ +- +-# We need the following in order to create when the system +-# doesn't have one that works with the given compiler. +-@GL_GENERATE_STDDEF_H_TRUE@stddef.h: stddef.in.h $(top_builddir)/config.status +-@GL_GENERATE_STDDEF_H_TRUE@ $(AM_V_GEN)rm -f $@-t $@ && \ +-@GL_GENERATE_STDDEF_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +-@GL_GENERATE_STDDEF_H_TRUE@ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +-@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +-@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +-@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +-@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \ +-@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \ +-@GL_GENERATE_STDDEF_H_TRUE@ -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \ +-@GL_GENERATE_STDDEF_H_TRUE@ < $(srcdir)/stddef.in.h; \ +-@GL_GENERATE_STDDEF_H_TRUE@ } > $@-t && \ +-@GL_GENERATE_STDDEF_H_TRUE@ mv $@-t $@ +-@GL_GENERATE_STDDEF_H_FALSE@stddef.h: $(top_builddir)/config.status +-@GL_GENERATE_STDDEF_H_FALSE@ rm -f $@ +- +-# We need the following in order to create when the system +-# doesn't have one that works with the given compiler. +-@GL_GENERATE_STDINT_H_TRUE@stdint.h: stdint.in.h $(top_builddir)/config.status +-@GL_GENERATE_STDINT_H_TRUE@ $(AM_V_GEN)rm -f $@-t $@ && \ +-@GL_GENERATE_STDINT_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +-@GL_GENERATE_STDINT_H_TRUE@ sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \ +-@GL_GENERATE_STDINT_H_TRUE@ < $(srcdir)/stdint.in.h; \ +-@GL_GENERATE_STDINT_H_TRUE@ } > $@-t && \ +-@GL_GENERATE_STDINT_H_TRUE@ mv $@-t $@ +-@GL_GENERATE_STDINT_H_FALSE@stdint.h: $(top_builddir)/config.status +-@GL_GENERATE_STDINT_H_FALSE@ rm -f $@ +- +-unitypes.h: unitypes.in.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- cat $(srcdir)/unitypes.in.h; \ +- } > $@-t && \ +- mv -f $@-t $@ +- +-uniwidth.h: uniwidth.in.h +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- cat $(srcdir)/uniwidth.in.h; \ +- } > $@-t && \ +- mv -f $@-t $@ +- +-# We need the following in order to create when the system +-# version does not work standalone. +-wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +- -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +- -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +- -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +- -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \ +- -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \ +- -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \ +- -e 's/@''GNULIB_BTOWC''@/$(GNULIB_BTOWC)/g' \ +- -e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \ +- -e 's/@''GNULIB_MBSINIT''@/$(GNULIB_MBSINIT)/g' \ +- -e 's/@''GNULIB_MBRTOWC''@/$(GNULIB_MBRTOWC)/g' \ +- -e 's/@''GNULIB_MBRLEN''@/$(GNULIB_MBRLEN)/g' \ +- -e 's/@''GNULIB_MBSRTOWCS''@/$(GNULIB_MBSRTOWCS)/g' \ +- -e 's/@''GNULIB_MBSNRTOWCS''@/$(GNULIB_MBSNRTOWCS)/g' \ +- -e 's/@''GNULIB_WCRTOMB''@/$(GNULIB_WCRTOMB)/g' \ +- -e 's/@''GNULIB_WCSRTOMBS''@/$(GNULIB_WCSRTOMBS)/g' \ +- -e 's/@''GNULIB_WCSNRTOMBS''@/$(GNULIB_WCSNRTOMBS)/g' \ +- -e 's/@''GNULIB_WCWIDTH''@/$(GNULIB_WCWIDTH)/g' \ +- -e 's/@''GNULIB_WMEMCHR''@/$(GNULIB_WMEMCHR)/g' \ +- -e 's/@''GNULIB_WMEMCMP''@/$(GNULIB_WMEMCMP)/g' \ +- -e 's/@''GNULIB_WMEMCPY''@/$(GNULIB_WMEMCPY)/g' \ +- -e 's/@''GNULIB_WMEMMOVE''@/$(GNULIB_WMEMMOVE)/g' \ +- -e 's/@''GNULIB_WMEMSET''@/$(GNULIB_WMEMSET)/g' \ +- -e 's/@''GNULIB_WCSLEN''@/$(GNULIB_WCSLEN)/g' \ +- -e 's/@''GNULIB_WCSNLEN''@/$(GNULIB_WCSNLEN)/g' \ +- -e 's/@''GNULIB_WCSCPY''@/$(GNULIB_WCSCPY)/g' \ +- -e 's/@''GNULIB_WCPCPY''@/$(GNULIB_WCPCPY)/g' \ +- -e 's/@''GNULIB_WCSNCPY''@/$(GNULIB_WCSNCPY)/g' \ +- -e 's/@''GNULIB_WCPNCPY''@/$(GNULIB_WCPNCPY)/g' \ +- -e 's/@''GNULIB_WCSCAT''@/$(GNULIB_WCSCAT)/g' \ +- -e 's/@''GNULIB_WCSNCAT''@/$(GNULIB_WCSNCAT)/g' \ +- -e 's/@''GNULIB_WCSCMP''@/$(GNULIB_WCSCMP)/g' \ +- -e 's/@''GNULIB_WCSNCMP''@/$(GNULIB_WCSNCMP)/g' \ +- -e 's/@''GNULIB_WCSCASECMP''@/$(GNULIB_WCSCASECMP)/g' \ +- -e 's/@''GNULIB_WCSNCASECMP''@/$(GNULIB_WCSNCASECMP)/g' \ +- -e 's/@''GNULIB_WCSCOLL''@/$(GNULIB_WCSCOLL)/g' \ +- -e 's/@''GNULIB_WCSXFRM''@/$(GNULIB_WCSXFRM)/g' \ +- -e 's/@''GNULIB_WCSDUP''@/$(GNULIB_WCSDUP)/g' \ +- -e 's/@''GNULIB_WCSCHR''@/$(GNULIB_WCSCHR)/g' \ +- -e 's/@''GNULIB_WCSRCHR''@/$(GNULIB_WCSRCHR)/g' \ +- -e 's/@''GNULIB_WCSCSPN''@/$(GNULIB_WCSCSPN)/g' \ +- -e 's/@''GNULIB_WCSSPN''@/$(GNULIB_WCSSPN)/g' \ +- -e 's/@''GNULIB_WCSPBRK''@/$(GNULIB_WCSPBRK)/g' \ +- -e 's/@''GNULIB_WCSSTR''@/$(GNULIB_WCSSTR)/g' \ +- -e 's/@''GNULIB_WCSTOK''@/$(GNULIB_WCSTOK)/g' \ +- -e 's/@''GNULIB_WCSWIDTH''@/$(GNULIB_WCSWIDTH)/g' \ +- < $(srcdir)/wchar.in.h | \ +- sed -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \ +- -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \ +- -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \ +- -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \ +- -e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \ +- -e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \ +- -e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \ +- -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \ +- -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \ +- -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \ +- -e 's|@''HAVE_WMEMCHR''@|$(HAVE_WMEMCHR)|g' \ +- -e 's|@''HAVE_WMEMCMP''@|$(HAVE_WMEMCMP)|g' \ +- -e 's|@''HAVE_WMEMCPY''@|$(HAVE_WMEMCPY)|g' \ +- -e 's|@''HAVE_WMEMMOVE''@|$(HAVE_WMEMMOVE)|g' \ +- -e 's|@''HAVE_WMEMSET''@|$(HAVE_WMEMSET)|g' \ +- -e 's|@''HAVE_WCSLEN''@|$(HAVE_WCSLEN)|g' \ +- -e 's|@''HAVE_WCSNLEN''@|$(HAVE_WCSNLEN)|g' \ +- -e 's|@''HAVE_WCSCPY''@|$(HAVE_WCSCPY)|g' \ +- -e 's|@''HAVE_WCPCPY''@|$(HAVE_WCPCPY)|g' \ +- -e 's|@''HAVE_WCSNCPY''@|$(HAVE_WCSNCPY)|g' \ +- -e 's|@''HAVE_WCPNCPY''@|$(HAVE_WCPNCPY)|g' \ +- -e 's|@''HAVE_WCSCAT''@|$(HAVE_WCSCAT)|g' \ +- -e 's|@''HAVE_WCSNCAT''@|$(HAVE_WCSNCAT)|g' \ +- -e 's|@''HAVE_WCSCMP''@|$(HAVE_WCSCMP)|g' \ +- -e 's|@''HAVE_WCSNCMP''@|$(HAVE_WCSNCMP)|g' \ +- -e 's|@''HAVE_WCSCASECMP''@|$(HAVE_WCSCASECMP)|g' \ +- -e 's|@''HAVE_WCSNCASECMP''@|$(HAVE_WCSNCASECMP)|g' \ +- -e 's|@''HAVE_WCSCOLL''@|$(HAVE_WCSCOLL)|g' \ +- -e 's|@''HAVE_WCSXFRM''@|$(HAVE_WCSXFRM)|g' \ +- -e 's|@''HAVE_WCSDUP''@|$(HAVE_WCSDUP)|g' \ +- -e 's|@''HAVE_WCSCHR''@|$(HAVE_WCSCHR)|g' \ +- -e 's|@''HAVE_WCSRCHR''@|$(HAVE_WCSRCHR)|g' \ +- -e 's|@''HAVE_WCSCSPN''@|$(HAVE_WCSCSPN)|g' \ +- -e 's|@''HAVE_WCSSPN''@|$(HAVE_WCSSPN)|g' \ +- -e 's|@''HAVE_WCSPBRK''@|$(HAVE_WCSPBRK)|g' \ +- -e 's|@''HAVE_WCSSTR''@|$(HAVE_WCSSTR)|g' \ +- -e 's|@''HAVE_WCSTOK''@|$(HAVE_WCSTOK)|g' \ +- -e 's|@''HAVE_WCSWIDTH''@|$(HAVE_WCSWIDTH)|g' \ +- -e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \ +- -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \ +- | \ +- sed -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \ +- -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \ +- -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \ +- -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \ +- -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \ +- -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \ +- -e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \ +- -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \ +- -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \ +- -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \ +- -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \ +- -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \ +- -e 's|@''REPLACE_WCSWIDTH''@|$(REPLACE_WCSWIDTH)|g' \ +- -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ +- -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ +- -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \ +- } > $@-t && \ +- mv $@-t $@ +- +-# We need the following in order to create when the system +-# doesn't have one that works with the given compiler. +-wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) +- $(AM_V_GEN)rm -f $@-t $@ && \ +- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ +- sed -e 's|@''GUARD_PREFIX''@|GL|g' \ +- -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \ +- -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \ +- -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ +- -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ +- -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \ +- -e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \ +- -e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \ +- -e 's/@''GNULIB_ISWCTYPE''@/$(GNULIB_ISWCTYPE)/g' \ +- -e 's/@''GNULIB_WCTRANS''@/$(GNULIB_WCTRANS)/g' \ +- -e 's/@''GNULIB_TOWCTRANS''@/$(GNULIB_TOWCTRANS)/g' \ +- -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \ +- -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \ +- -e 's/@''HAVE_WCTYPE_T''@/$(HAVE_WCTYPE_T)/g' \ +- -e 's/@''HAVE_WCTRANS_T''@/$(HAVE_WCTRANS_T)/g' \ +- -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \ +- -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \ +- -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \ +- -e 's/@''REPLACE_TOWLOWER''@/$(REPLACE_TOWLOWER)/g' \ +- -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ +- -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ +- < $(srcdir)/wctype.in.h; \ +- } > $@-t && \ +- mv $@-t $@ +- +-mostlyclean-local: mostlyclean-generic +- @for dir in '' $(MOSTLYCLEANDIRS); do \ +- if test -n "$$dir" && test -d $$dir; then \ +- echo "rmdir $$dir"; rmdir $$dir; \ +- fi; \ +- done; \ +- : +- +-# Tell versions [3.59,3.63) of GNU make to not export all variables. +-# Otherwise a system limit (for SysV at least) may be exceeded. +-.NOEXPORT: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/ref-add.sin groff-1.22.3/src/libs/gnulib/lib/ref-add.sin +--- groff-1.22.3.old/src/libs/gnulib/lib/ref-add.sin 2014-11-04 10:38:35.630518934 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/ref-add.sin 1970-01-01 02:00:00.000000000 +0200 +@@ -1,29 +0,0 @@ +-# Add this package to a list of references stored in a text file. +-# +-# Copyright (C) 2000, 2009-2014 Free Software Foundation, Inc. +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2, or (at your option) +-# any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License along +-# with this program; if not, see . +-# +-# Written by Bruno Haible . +-# +-/^# Packages using this file: / { +- s/# Packages using this file:// +- ta +- :a +- s/ @PACKAGE@ / @PACKAGE@ / +- tb +- s/ $/ @PACKAGE@ / +- :b +- s/^/# Packages using this file:/ +-} +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/ref-del.sin groff-1.22.3/src/libs/gnulib/lib/ref-del.sin +--- groff-1.22.3.old/src/libs/gnulib/lib/ref-del.sin 2014-11-04 10:38:35.630518934 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/ref-del.sin 1970-01-01 02:00:00.000000000 +0200 +@@ -1,24 +0,0 @@ +-# Remove this package from a list of references stored in a text file. +-# +-# Copyright (C) 2000, 2009-2014 Free Software Foundation, Inc. +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2, or (at your option) +-# any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License along +-# with this program; if not, see . +-# +-# Written by Bruno Haible . +-# +-/^# Packages using this file: / { +- s/# Packages using this file:// +- s/ @PACKAGE@ / / +- s/^/# Packages using this file:/ +-} +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/stdbool.in.h groff-1.22.3/src/libs/gnulib/lib/stdbool.in.h +--- groff-1.22.3.old/src/libs/gnulib/lib/stdbool.in.h 2014-11-04 10:38:35.630518934 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/stdbool.in.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,132 +0,0 @@ +-/* Copyright (C) 2001-2003, 2006-2014 Free Software Foundation, Inc. +- Written by Bruno Haible , 2001. +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2, or (at your option) +- any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, see . */ +- +-#ifndef _GL_STDBOOL_H +-#define _GL_STDBOOL_H +- +-/* ISO C 99 for platforms that lack it. */ +- +-/* Usage suggestions: +- +- Programs that use should be aware of some limitations +- and standards compliance issues. +- +- Standards compliance: +- +- - must be #included before 'bool', 'false', 'true' +- can be used. +- +- - You cannot assume that sizeof (bool) == 1. +- +- - Programs should not undefine the macros bool, true, and false, +- as C99 lists that as an "obsolescent feature". +- +- Limitations of this substitute, when used in a C89 environment: +- +- - must be #included before the '_Bool' type can be used. +- +- - You cannot assume that _Bool is a typedef; it might be a macro. +- +- - Bit-fields of type 'bool' are not supported. Portable code +- should use 'unsigned int foo : 1;' rather than 'bool foo : 1;'. +- +- - In C99, casts and automatic conversions to '_Bool' or 'bool' are +- performed in such a way that every nonzero value gets converted +- to 'true', and zero gets converted to 'false'. This doesn't work +- with this substitute. With this substitute, only the values 0 and 1 +- give the expected result when converted to _Bool' or 'bool'. +- +- - C99 allows the use of (_Bool)0.0 in constant expressions, but +- this substitute cannot always provide this property. +- +- Also, it is suggested that programs use 'bool' rather than '_Bool'; +- this isn't required, but 'bool' is more common. */ +- +- +-/* 7.16. Boolean type and values */ +- +-/* BeOS already #defines false 0, true 1. We use the same +- definitions below, but temporarily we have to #undef them. */ +-#if defined __BEOS__ && !defined __HAIKU__ +-# include /* defines bool but not _Bool */ +-# undef false +-# undef true +-#endif +- +-#ifdef __cplusplus +-# define _Bool bool +-# define bool bool +-#else +-# if defined __BEOS__ && !defined __HAIKU__ +- /* A compiler known to have 'bool'. */ +- /* If the compiler already has both 'bool' and '_Bool', we can assume they +- are the same types. */ +-# if !@HAVE__BOOL@ +-typedef bool _Bool; +-# endif +-# else +-# if !defined __GNUC__ +- /* If @HAVE__BOOL@: +- Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when +- the built-in _Bool type is used. See +- http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html +- http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html +- http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html +- Similar bugs are likely with other compilers as well; this file +- wouldn't be used if was working. +- So we override the _Bool type. +- If !@HAVE__BOOL@: +- Need to define _Bool ourselves. As 'signed char' or as an enum type? +- Use of a typedef, with SunPRO C, leads to a stupid +- "warning: _Bool is a keyword in ISO C99". +- Use of an enum type, with IRIX cc, leads to a stupid +- "warning(1185): enumerated type mixed with another type". +- Even the existence of an enum type, without a typedef, +- "Invalid enumerator. (badenum)" with HP-UX cc on Tru64. +- The only benefit of the enum, debuggability, is not important +- with these compilers. So use 'signed char' and no enum. */ +-# define _Bool signed char +-# else +- /* With this compiler, trust the _Bool type if the compiler has it. */ +-# if !@HAVE__BOOL@ +- /* For the sake of symbolic names in gdb, define true and false as +- enum constants, not only as macros. +- It is tempting to write +- typedef enum { false = 0, true = 1 } _Bool; +- so that gdb prints values of type 'bool' symbolically. But then +- values of type '_Bool' might promote to 'int' or 'unsigned int' +- (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int' +- (see ISO C 99 6.3.1.1.(2)). So add a negative value to the +- enum; this ensures that '_Bool' promotes to 'int'. */ +-typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool; +-# endif +-# endif +-# endif +-# define bool _Bool +-#endif +- +-/* The other macros must be usable in preprocessor directives. */ +-#ifdef __cplusplus +-# define false false +-# define true true +-#else +-# define false 0 +-# define true 1 +-#endif +- +-#define __bool_true_false_are_defined 1 +- +-#endif /* _GL_STDBOOL_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/stddef.in.h groff-1.22.3/src/libs/gnulib/lib/stddef.in.h +--- groff-1.22.3.old/src/libs/gnulib/lib/stddef.in.h 2014-11-04 10:38:35.630518934 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/stddef.in.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,86 +0,0 @@ +-/* A substitute for POSIX 2008 , for platforms that have issues. +- +- Copyright (C) 2009-2014 Free Software Foundation, Inc. +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2, or (at your option) +- any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, see . */ +- +-/* Written by Eric Blake. */ +- +-/* +- * POSIX 2008 for platforms that have issues. +- * +- */ +- +-#if __GNUC__ >= 3 +-@PRAGMA_SYSTEM_HEADER@ +-#endif +-@PRAGMA_COLUMNS@ +- +-#if defined __need_wchar_t || defined __need_size_t \ +- || defined __need_ptrdiff_t || defined __need_NULL \ +- || defined __need_wint_t +-/* Special invocation convention inside gcc header files. In +- particular, gcc provides a version of that blindly +- redefines NULL even when __need_wint_t was defined, even though +- wint_t is not normally provided by . Hence, we must +- remember if special invocation has ever been used to obtain wint_t, +- in which case we need to clean up NULL yet again. */ +- +-# if !(defined _@GUARD_PREFIX@_STDDEF_H && defined _GL_STDDEF_WINT_T) +-# ifdef __need_wint_t +-# undef _@GUARD_PREFIX@_STDDEF_H +-# define _GL_STDDEF_WINT_T +-# endif +-# @INCLUDE_NEXT@ @NEXT_STDDEF_H@ +-# endif +- +-#else +-/* Normal invocation convention. */ +- +-# ifndef _@GUARD_PREFIX@_STDDEF_H +- +-/* The include_next requires a split double-inclusion guard. */ +- +-# @INCLUDE_NEXT@ @NEXT_STDDEF_H@ +- +-# ifndef _@GUARD_PREFIX@_STDDEF_H +-# define _@GUARD_PREFIX@_STDDEF_H +- +-/* On NetBSD 5.0, the definition of NULL lacks proper parentheses. */ +-#if @REPLACE_NULL@ +-# undef NULL +-# ifdef __cplusplus +- /* ISO C++ says that the macro NULL must expand to an integer constant +- expression, hence '((void *) 0)' is not allowed in C++. */ +-# if __GNUG__ >= 3 +- /* GNU C++ has a __null macro that behaves like an integer ('int' or +- 'long') but has the same size as a pointer. Use that, to avoid +- warnings. */ +-# define NULL __null +-# else +-# define NULL 0L +-# endif +-# else +-# define NULL ((void *) 0) +-# endif +-#endif +- +-/* Some platforms lack wchar_t. */ +-#if !@HAVE_WCHAR_T@ +-# define wchar_t int +-#endif +- +-# endif /* _@GUARD_PREFIX@_STDDEF_H */ +-# endif /* _@GUARD_PREFIX@_STDDEF_H */ +-#endif /* __need_XXX */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/stdint.in.h groff-1.22.3/src/libs/gnulib/lib/stdint.in.h +--- groff-1.22.3.old/src/libs/gnulib/lib/stdint.in.h 2014-11-04 10:38:35.630518934 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/stdint.in.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,636 +0,0 @@ +-/* Copyright (C) 2001-2014 Free Software Foundation, Inc. +- Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood. +- This file is part of gnulib. +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3, or (at your option) +- any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, see . */ +- +-/* +- * ISO C 99 for platforms that lack it. +- * +- */ +- +-#ifndef _@GUARD_PREFIX@_STDINT_H +- +-#if __GNUC__ >= 3 +-@PRAGMA_SYSTEM_HEADER@ +-#endif +-@PRAGMA_COLUMNS@ +- +-/* When including a system file that in turn includes , +- use the system , not our substitute. This avoids +- problems with (for example) VMS, whose includes +- . */ +-#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H +- +-/* On Android (Bionic libc), includes this file before +- having defined 'time_t'. Therefore in this case avoid including +- other system header files; just include the system's . +- Ideally we should test __BIONIC__ here, but it is only defined after +- has been included; hence test __ANDROID__ instead. */ +-#if defined __ANDROID__ \ +- && defined _SYS_TYPES_H_ && !defined __need_size_t +-# @INCLUDE_NEXT@ @NEXT_STDINT_H@ +-#else +- +-/* Get those types that are already defined in other system include +- files, so that we can "#define int8_t signed char" below without +- worrying about a later system include file containing a "typedef +- signed char int8_t;" that will get messed up by our macro. Our +- macros should all be consistent with the system versions, except +- for the "fast" types and macros, which we recommend against using +- in public interfaces due to compiler differences. */ +- +-#if @HAVE_STDINT_H@ +-# if defined __sgi && ! defined __c99 +- /* Bypass IRIX's if in C89 mode, since it merely annoys users +- with "This header file is to be used only for c99 mode compilations" +- diagnostics. */ +-# define __STDINT_H__ +-# endif +- +- /* Some pre-C++11 implementations need this. */ +-# ifdef __cplusplus +-# ifndef __STDC_CONSTANT_MACROS +-# define __STDC_CONSTANT_MACROS 1 +-# endif +-# ifndef __STDC_LIMIT_MACROS +-# define __STDC_LIMIT_MACROS 1 +-# endif +-# endif +- +- /* Other systems may have an incomplete or buggy . +- Include it before , since any "#include " +- in would reinclude us, skipping our contents because +- _@GUARD_PREFIX@_STDINT_H is defined. +- The include_next requires a split double-inclusion guard. */ +-# @INCLUDE_NEXT@ @NEXT_STDINT_H@ +-#endif +- +-#if ! defined _@GUARD_PREFIX@_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H +-#define _@GUARD_PREFIX@_STDINT_H +- +-/* defines some of the stdint.h types as well, on glibc, +- IRIX 6.5, and OpenBSD 3.8 (via ). +- AIX 5.2 isn't needed and causes troubles. +- Mac OS X 10.4.6 includes (which is us), but +- relies on the system definitions, so include +- after @NEXT_STDINT_H@. */ +-#if @HAVE_SYS_TYPES_H@ && ! defined _AIX +-# include +-#endif +- +-/* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX, +- LONG_MIN, LONG_MAX, ULONG_MAX. */ +-#include +- +-#if @HAVE_INTTYPES_H@ +- /* In OpenBSD 3.8, includes , which defines +- int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__. +- also defines intptr_t and uintptr_t. */ +-# include +-#elif @HAVE_SYS_INTTYPES_H@ +- /* Solaris 7 has the types except the *_fast*_t types, and +- the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */ +-# include +-#endif +- +-#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__ +- /* Linux libc4 >= 4.6.7 and libc5 have a that defines +- int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is +- included by . */ +-# include +-#endif +- +-#undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H +- +-/* Minimum and maximum values for an integer type under the usual assumption. +- Return an unspecified value if BITS == 0, adding a check to pacify +- picky compilers. */ +- +-#define _STDINT_MIN(signed, bits, zero) \ +- ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero)) +- +-#define _STDINT_MAX(signed, bits, zero) \ +- ((signed) \ +- ? ~ _STDINT_MIN (signed, bits, zero) \ +- : /* The expression for the unsigned case. The subtraction of (signed) \ +- is a nop in the unsigned case and avoids "signed integer overflow" \ +- warnings in the signed case. */ \ +- ((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1) +- +-#if !GNULIB_defined_stdint_types +- +-/* 7.18.1.1. Exact-width integer types */ +- +-/* Here we assume a standard architecture where the hardware integer +- types have 8, 16, 32, optionally 64 bits. */ +- +-#undef int8_t +-#undef uint8_t +-typedef signed char gl_int8_t; +-typedef unsigned char gl_uint8_t; +-#define int8_t gl_int8_t +-#define uint8_t gl_uint8_t +- +-#undef int16_t +-#undef uint16_t +-typedef short int gl_int16_t; +-typedef unsigned short int gl_uint16_t; +-#define int16_t gl_int16_t +-#define uint16_t gl_uint16_t +- +-#undef int32_t +-#undef uint32_t +-typedef int gl_int32_t; +-typedef unsigned int gl_uint32_t; +-#define int32_t gl_int32_t +-#define uint32_t gl_uint32_t +- +-/* If the system defines INT64_MAX, assume int64_t works. That way, +- if the underlying platform defines int64_t to be a 64-bit long long +- int, the code below won't mistakenly define it to be a 64-bit long +- int, which would mess up C++ name mangling. We must use #ifdef +- rather than #if, to avoid an error with HP-UX 10.20 cc. */ +- +-#ifdef INT64_MAX +-# define GL_INT64_T +-#else +-/* Do not undefine int64_t if gnulib is not being used with 64-bit +- types, since otherwise it breaks platforms like Tandem/NSK. */ +-# if LONG_MAX >> 31 >> 31 == 1 +-# undef int64_t +-typedef long int gl_int64_t; +-# define int64_t gl_int64_t +-# define GL_INT64_T +-# elif defined _MSC_VER +-# undef int64_t +-typedef __int64 gl_int64_t; +-# define int64_t gl_int64_t +-# define GL_INT64_T +-# elif @HAVE_LONG_LONG_INT@ +-# undef int64_t +-typedef long long int gl_int64_t; +-# define int64_t gl_int64_t +-# define GL_INT64_T +-# endif +-#endif +- +-#ifdef UINT64_MAX +-# define GL_UINT64_T +-#else +-# if ULONG_MAX >> 31 >> 31 >> 1 == 1 +-# undef uint64_t +-typedef unsigned long int gl_uint64_t; +-# define uint64_t gl_uint64_t +-# define GL_UINT64_T +-# elif defined _MSC_VER +-# undef uint64_t +-typedef unsigned __int64 gl_uint64_t; +-# define uint64_t gl_uint64_t +-# define GL_UINT64_T +-# elif @HAVE_UNSIGNED_LONG_LONG_INT@ +-# undef uint64_t +-typedef unsigned long long int gl_uint64_t; +-# define uint64_t gl_uint64_t +-# define GL_UINT64_T +-# endif +-#endif +- +-/* Avoid collision with Solaris 2.5.1 etc. */ +-#define _UINT8_T +-#define _UINT32_T +-#define _UINT64_T +- +- +-/* 7.18.1.2. Minimum-width integer types */ +- +-/* Here we assume a standard architecture where the hardware integer +- types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types +- are the same as the corresponding N_t types. */ +- +-#undef int_least8_t +-#undef uint_least8_t +-#undef int_least16_t +-#undef uint_least16_t +-#undef int_least32_t +-#undef uint_least32_t +-#undef int_least64_t +-#undef uint_least64_t +-#define int_least8_t int8_t +-#define uint_least8_t uint8_t +-#define int_least16_t int16_t +-#define uint_least16_t uint16_t +-#define int_least32_t int32_t +-#define uint_least32_t uint32_t +-#ifdef GL_INT64_T +-# define int_least64_t int64_t +-#endif +-#ifdef GL_UINT64_T +-# define uint_least64_t uint64_t +-#endif +- +-/* 7.18.1.3. Fastest minimum-width integer types */ +- +-/* Note: Other substitutes may define these types differently. +- It is not recommended to use these types in public header files. */ +- +-/* Here we assume a standard architecture where the hardware integer +- types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types +- are taken from the same list of types. The following code normally +- uses types consistent with glibc, as that lessens the chance of +- incompatibility with older GNU hosts. */ +- +-#undef int_fast8_t +-#undef uint_fast8_t +-#undef int_fast16_t +-#undef uint_fast16_t +-#undef int_fast32_t +-#undef uint_fast32_t +-#undef int_fast64_t +-#undef uint_fast64_t +-typedef signed char gl_int_fast8_t; +-typedef unsigned char gl_uint_fast8_t; +- +-#ifdef __sun +-/* Define types compatible with SunOS 5.10, so that code compiled under +- earlier SunOS versions works with code compiled under SunOS 5.10. */ +-typedef int gl_int_fast32_t; +-typedef unsigned int gl_uint_fast32_t; +-#else +-typedef long int gl_int_fast32_t; +-typedef unsigned long int gl_uint_fast32_t; +-#endif +-typedef gl_int_fast32_t gl_int_fast16_t; +-typedef gl_uint_fast32_t gl_uint_fast16_t; +- +-#define int_fast8_t gl_int_fast8_t +-#define uint_fast8_t gl_uint_fast8_t +-#define int_fast16_t gl_int_fast16_t +-#define uint_fast16_t gl_uint_fast16_t +-#define int_fast32_t gl_int_fast32_t +-#define uint_fast32_t gl_uint_fast32_t +-#ifdef GL_INT64_T +-# define int_fast64_t int64_t +-#endif +-#ifdef GL_UINT64_T +-# define uint_fast64_t uint64_t +-#endif +- +-/* 7.18.1.4. Integer types capable of holding object pointers */ +- +-#undef intptr_t +-#undef uintptr_t +-typedef long int gl_intptr_t; +-typedef unsigned long int gl_uintptr_t; +-#define intptr_t gl_intptr_t +-#define uintptr_t gl_uintptr_t +- +-/* 7.18.1.5. Greatest-width integer types */ +- +-/* Note: These types are compiler dependent. It may be unwise to use them in +- public header files. */ +- +-/* If the system defines INTMAX_MAX, assume that intmax_t works, and +- similarly for UINTMAX_MAX and uintmax_t. This avoids problems with +- assuming one type where another is used by the system. */ +- +-#ifndef INTMAX_MAX +-# undef INTMAX_C +-# undef intmax_t +-# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +-typedef long long int gl_intmax_t; +-# define intmax_t gl_intmax_t +-# elif defined GL_INT64_T +-# define intmax_t int64_t +-# else +-typedef long int gl_intmax_t; +-# define intmax_t gl_intmax_t +-# endif +-#endif +- +-#ifndef UINTMAX_MAX +-# undef UINTMAX_C +-# undef uintmax_t +-# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +-typedef unsigned long long int gl_uintmax_t; +-# define uintmax_t gl_uintmax_t +-# elif defined GL_UINT64_T +-# define uintmax_t uint64_t +-# else +-typedef unsigned long int gl_uintmax_t; +-# define uintmax_t gl_uintmax_t +-# endif +-#endif +- +-/* Verify that intmax_t and uintmax_t have the same size. Too much code +- breaks if this is not the case. If this check fails, the reason is likely +- to be found in the autoconf macros. */ +-typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t) +- ? 1 : -1]; +- +-#define GNULIB_defined_stdint_types 1 +-#endif /* !GNULIB_defined_stdint_types */ +- +-/* 7.18.2. Limits of specified-width integer types */ +- +-/* 7.18.2.1. Limits of exact-width integer types */ +- +-/* Here we assume a standard architecture where the hardware integer +- types have 8, 16, 32, optionally 64 bits. */ +- +-#undef INT8_MIN +-#undef INT8_MAX +-#undef UINT8_MAX +-#define INT8_MIN (~ INT8_MAX) +-#define INT8_MAX 127 +-#define UINT8_MAX 255 +- +-#undef INT16_MIN +-#undef INT16_MAX +-#undef UINT16_MAX +-#define INT16_MIN (~ INT16_MAX) +-#define INT16_MAX 32767 +-#define UINT16_MAX 65535 +- +-#undef INT32_MIN +-#undef INT32_MAX +-#undef UINT32_MAX +-#define INT32_MIN (~ INT32_MAX) +-#define INT32_MAX 2147483647 +-#define UINT32_MAX 4294967295U +- +-#if defined GL_INT64_T && ! defined INT64_MAX +-/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0 +- evaluates the latter incorrectly in preprocessor expressions. */ +-# define INT64_MIN (- INTMAX_C (1) << 63) +-# define INT64_MAX INTMAX_C (9223372036854775807) +-#endif +- +-#if defined GL_UINT64_T && ! defined UINT64_MAX +-# define UINT64_MAX UINTMAX_C (18446744073709551615) +-#endif +- +-/* 7.18.2.2. Limits of minimum-width integer types */ +- +-/* Here we assume a standard architecture where the hardware integer +- types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types +- are the same as the corresponding N_t types. */ +- +-#undef INT_LEAST8_MIN +-#undef INT_LEAST8_MAX +-#undef UINT_LEAST8_MAX +-#define INT_LEAST8_MIN INT8_MIN +-#define INT_LEAST8_MAX INT8_MAX +-#define UINT_LEAST8_MAX UINT8_MAX +- +-#undef INT_LEAST16_MIN +-#undef INT_LEAST16_MAX +-#undef UINT_LEAST16_MAX +-#define INT_LEAST16_MIN INT16_MIN +-#define INT_LEAST16_MAX INT16_MAX +-#define UINT_LEAST16_MAX UINT16_MAX +- +-#undef INT_LEAST32_MIN +-#undef INT_LEAST32_MAX +-#undef UINT_LEAST32_MAX +-#define INT_LEAST32_MIN INT32_MIN +-#define INT_LEAST32_MAX INT32_MAX +-#define UINT_LEAST32_MAX UINT32_MAX +- +-#undef INT_LEAST64_MIN +-#undef INT_LEAST64_MAX +-#ifdef GL_INT64_T +-# define INT_LEAST64_MIN INT64_MIN +-# define INT_LEAST64_MAX INT64_MAX +-#endif +- +-#undef UINT_LEAST64_MAX +-#ifdef GL_UINT64_T +-# define UINT_LEAST64_MAX UINT64_MAX +-#endif +- +-/* 7.18.2.3. Limits of fastest minimum-width integer types */ +- +-/* Here we assume a standard architecture where the hardware integer +- types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types +- are taken from the same list of types. */ +- +-#undef INT_FAST8_MIN +-#undef INT_FAST8_MAX +-#undef UINT_FAST8_MAX +-#define INT_FAST8_MIN SCHAR_MIN +-#define INT_FAST8_MAX SCHAR_MAX +-#define UINT_FAST8_MAX UCHAR_MAX +- +-#undef INT_FAST16_MIN +-#undef INT_FAST16_MAX +-#undef UINT_FAST16_MAX +-#define INT_FAST16_MIN INT_FAST32_MIN +-#define INT_FAST16_MAX INT_FAST32_MAX +-#define UINT_FAST16_MAX UINT_FAST32_MAX +- +-#undef INT_FAST32_MIN +-#undef INT_FAST32_MAX +-#undef UINT_FAST32_MAX +-#ifdef __sun +-# define INT_FAST32_MIN INT_MIN +-# define INT_FAST32_MAX INT_MAX +-# define UINT_FAST32_MAX UINT_MAX +-#else +-# define INT_FAST32_MIN LONG_MIN +-# define INT_FAST32_MAX LONG_MAX +-# define UINT_FAST32_MAX ULONG_MAX +-#endif +- +-#undef INT_FAST64_MIN +-#undef INT_FAST64_MAX +-#ifdef GL_INT64_T +-# define INT_FAST64_MIN INT64_MIN +-# define INT_FAST64_MAX INT64_MAX +-#endif +- +-#undef UINT_FAST64_MAX +-#ifdef GL_UINT64_T +-# define UINT_FAST64_MAX UINT64_MAX +-#endif +- +-/* 7.18.2.4. Limits of integer types capable of holding object pointers */ +- +-#undef INTPTR_MIN +-#undef INTPTR_MAX +-#undef UINTPTR_MAX +-#define INTPTR_MIN LONG_MIN +-#define INTPTR_MAX LONG_MAX +-#define UINTPTR_MAX ULONG_MAX +- +-/* 7.18.2.5. Limits of greatest-width integer types */ +- +-#ifndef INTMAX_MAX +-# undef INTMAX_MIN +-# ifdef INT64_MAX +-# define INTMAX_MIN INT64_MIN +-# define INTMAX_MAX INT64_MAX +-# else +-# define INTMAX_MIN INT32_MIN +-# define INTMAX_MAX INT32_MAX +-# endif +-#endif +- +-#ifndef UINTMAX_MAX +-# ifdef UINT64_MAX +-# define UINTMAX_MAX UINT64_MAX +-# else +-# define UINTMAX_MAX UINT32_MAX +-# endif +-#endif +- +-/* 7.18.3. Limits of other integer types */ +- +-/* ptrdiff_t limits */ +-#undef PTRDIFF_MIN +-#undef PTRDIFF_MAX +-#if @APPLE_UNIVERSAL_BUILD@ +-# ifdef _LP64 +-# define PTRDIFF_MIN _STDINT_MIN (1, 64, 0l) +-# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l) +-# else +-# define PTRDIFF_MIN _STDINT_MIN (1, 32, 0) +-# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0) +-# endif +-#else +-# define PTRDIFF_MIN \ +- _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +-# define PTRDIFF_MAX \ +- _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@) +-#endif +- +-/* sig_atomic_t limits */ +-#undef SIG_ATOMIC_MIN +-#undef SIG_ATOMIC_MAX +-#define SIG_ATOMIC_MIN \ +- _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ +- 0@SIG_ATOMIC_T_SUFFIX@) +-#define SIG_ATOMIC_MAX \ +- _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \ +- 0@SIG_ATOMIC_T_SUFFIX@) +- +- +-/* size_t limit */ +-#undef SIZE_MAX +-#if @APPLE_UNIVERSAL_BUILD@ +-# ifdef _LP64 +-# define SIZE_MAX _STDINT_MAX (0, 64, 0ul) +-# else +-# define SIZE_MAX _STDINT_MAX (0, 32, 0ul) +-# endif +-#else +-# define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@) +-#endif +- +-/* wchar_t limits */ +-/* Get WCHAR_MIN, WCHAR_MAX. +- This include is not on the top, above, because on OSF/1 4.0 we have a +- sequence of nested includes +- -> -> -> , and the latter includes +- and assumes its types are already defined. */ +-#if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX) +- /* BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-# include +-# include +-# include +-# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +-# include +-# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H +-#endif +-#undef WCHAR_MIN +-#undef WCHAR_MAX +-#define WCHAR_MIN \ +- _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) +-#define WCHAR_MAX \ +- _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@) +- +-/* wint_t limits */ +-#undef WINT_MIN +-#undef WINT_MAX +-#define WINT_MIN \ +- _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +-#define WINT_MAX \ +- _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@) +- +-/* 7.18.4. Macros for integer constants */ +- +-/* 7.18.4.1. Macros for minimum-width integer constants */ +-/* According to ISO C 99 Technical Corrigendum 1 */ +- +-/* Here we assume a standard architecture where the hardware integer +- types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */ +- +-#undef INT8_C +-#undef UINT8_C +-#define INT8_C(x) x +-#define UINT8_C(x) x +- +-#undef INT16_C +-#undef UINT16_C +-#define INT16_C(x) x +-#define UINT16_C(x) x +- +-#undef INT32_C +-#undef UINT32_C +-#define INT32_C(x) x +-#define UINT32_C(x) x ## U +- +-#undef INT64_C +-#undef UINT64_C +-#if LONG_MAX >> 31 >> 31 == 1 +-# define INT64_C(x) x##L +-#elif defined _MSC_VER +-# define INT64_C(x) x##i64 +-#elif @HAVE_LONG_LONG_INT@ +-# define INT64_C(x) x##LL +-#endif +-#if ULONG_MAX >> 31 >> 31 >> 1 == 1 +-# define UINT64_C(x) x##UL +-#elif defined _MSC_VER +-# define UINT64_C(x) x##ui64 +-#elif @HAVE_UNSIGNED_LONG_LONG_INT@ +-# define UINT64_C(x) x##ULL +-#endif +- +-/* 7.18.4.2. Macros for greatest-width integer constants */ +- +-#ifndef INTMAX_C +-# if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1 +-# define INTMAX_C(x) x##LL +-# elif defined GL_INT64_T +-# define INTMAX_C(x) INT64_C(x) +-# else +-# define INTMAX_C(x) x##L +-# endif +-#endif +- +-#ifndef UINTMAX_C +-# if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1 +-# define UINTMAX_C(x) x##ULL +-# elif defined GL_UINT64_T +-# define UINTMAX_C(x) UINT64_C(x) +-# else +-# define UINTMAX_C(x) x##UL +-# endif +-#endif +- +-#endif /* _@GUARD_PREFIX@_STDINT_H */ +-#endif /* !(defined __ANDROID__ && ...) */ +-#endif /* !defined _@GUARD_PREFIX@_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/streq.h groff-1.22.3/src/libs/gnulib/lib/streq.h +--- groff-1.22.3.old/src/libs/gnulib/lib/streq.h 2014-11-04 10:38:35.630518934 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/streq.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,176 +0,0 @@ +-/* Optimized string comparison. +- Copyright (C) 2001-2002, 2007, 2009-2014 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify it +- under the terms of the GNU Lesser General Public License as published +- by the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public License +- along with this program. If not, see . */ +- +-/* Written by Bruno Haible . */ +- +-#ifndef _GL_STREQ_H +-#define _GL_STREQ_H +- +-#include +- +-/* STREQ_OPT allows to optimize string comparison with a small literal string. +- STREQ_OPT (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) +- is semantically equivalent to +- strcmp (s, "EUC-KR") == 0 +- just faster. */ +- +-/* Help GCC to generate good code for string comparisons with +- immediate strings. */ +-#if defined (__GNUC__) && defined (__OPTIMIZE__) +- +-static inline int +-streq9 (const char *s1, const char *s2) +-{ +- return strcmp (s1 + 9, s2 + 9) == 0; +-} +- +-static inline int +-streq8 (const char *s1, const char *s2, char s28) +-{ +- if (s1[8] == s28) +- { +- if (s28 == 0) +- return 1; +- else +- return streq9 (s1, s2); +- } +- else +- return 0; +-} +- +-static inline int +-streq7 (const char *s1, const char *s2, char s27, char s28) +-{ +- if (s1[7] == s27) +- { +- if (s27 == 0) +- return 1; +- else +- return streq8 (s1, s2, s28); +- } +- else +- return 0; +-} +- +-static inline int +-streq6 (const char *s1, const char *s2, char s26, char s27, char s28) +-{ +- if (s1[6] == s26) +- { +- if (s26 == 0) +- return 1; +- else +- return streq7 (s1, s2, s27, s28); +- } +- else +- return 0; +-} +- +-static inline int +-streq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28) +-{ +- if (s1[5] == s25) +- { +- if (s25 == 0) +- return 1; +- else +- return streq6 (s1, s2, s26, s27, s28); +- } +- else +- return 0; +-} +- +-static inline int +-streq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28) +-{ +- if (s1[4] == s24) +- { +- if (s24 == 0) +- return 1; +- else +- return streq5 (s1, s2, s25, s26, s27, s28); +- } +- else +- return 0; +-} +- +-static inline int +-streq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28) +-{ +- if (s1[3] == s23) +- { +- if (s23 == 0) +- return 1; +- else +- return streq4 (s1, s2, s24, s25, s26, s27, s28); +- } +- else +- return 0; +-} +- +-static inline int +-streq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +-{ +- if (s1[2] == s22) +- { +- if (s22 == 0) +- return 1; +- else +- return streq3 (s1, s2, s23, s24, s25, s26, s27, s28); +- } +- else +- return 0; +-} +- +-static inline int +-streq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +-{ +- if (s1[1] == s21) +- { +- if (s21 == 0) +- return 1; +- else +- return streq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28); +- } +- else +- return 0; +-} +- +-static inline int +-streq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28) +-{ +- if (s1[0] == s20) +- { +- if (s20 == 0) +- return 1; +- else +- return streq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28); +- } +- else +- return 0; +-} +- +-#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ +- streq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28) +- +-#else +- +-#define STREQ_OPT(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \ +- (strcmp (s1, s2) == 0) +- +-#endif +- +-#endif /* _GL_STREQ_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/unitypes.in.h groff-1.22.3/src/libs/gnulib/lib/unitypes.in.h +--- groff-1.22.3.old/src/libs/gnulib/lib/unitypes.in.h 2014-11-04 10:38:35.630518934 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/unitypes.in.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,46 +0,0 @@ +-/* Elementary types and macros for the GNU UniString library. +- Copyright (C) 2002, 2005-2006, 2009-2014 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify it +- under the terms of the GNU Lesser General Public License as published +- by the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public License +- along with this program. If not, see . */ +- +-#ifndef _UNITYPES_H +-#define _UNITYPES_H +- +-/* Get uint8_t, uint16_t, uint32_t. */ +-#include +- +-/* Type representing a Unicode character. */ +-typedef uint32_t ucs4_t; +- +-/* Attribute of a function whose result depends only on the arguments +- (not pointers!) and which has no side effects. */ +-#ifndef _UC_ATTRIBUTE_CONST +-# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +-# define _UC_ATTRIBUTE_CONST __attribute__ ((__const__)) +-# else +-# define _UC_ATTRIBUTE_CONST +-# endif +-#endif +- +-/* Attribute of a function whose result depends only on the arguments +- (possibly pointers) and global memory, and which has no side effects. */ +-#ifndef _UC_ATTRIBUTE_PURE +-# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +-# define _UC_ATTRIBUTE_PURE __attribute__ ((__pure__)) +-# else +-# define _UC_ATTRIBUTE_PURE +-# endif +-#endif +- +-#endif /* _UNITYPES_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/uniwidth/cjk.h groff-1.22.3/src/libs/gnulib/lib/uniwidth/cjk.h +--- groff-1.22.3.old/src/libs/gnulib/lib/uniwidth/cjk.h 2014-11-04 10:38:35.635518871 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/uniwidth/cjk.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,37 +0,0 @@ +-/* Test for CJK encoding. +- Copyright (C) 2001-2002, 2005-2007, 2009-2014 Free Software Foundation, Inc. +- Written by Bruno Haible , 2002. +- +- This program is free software: you can redistribute it and/or modify it +- under the terms of the GNU Lesser General Public License as published +- by the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public License +- along with this program. If not, see . */ +- +-#include "streq.h" +- +-static int +-is_cjk_encoding (const char *encoding) +-{ +- if (0 +- /* Legacy Japanese encodings */ +- || STREQ_OPT (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0) +- /* Legacy Chinese encodings */ +- || STREQ_OPT (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0) +- || STREQ_OPT (encoding, "GBK", 'G', 'B', 'K', 0, 0, 0, 0, 0, 0) +- || STREQ_OPT (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0) +- || STREQ_OPT (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0) +- /* Legacy Korean encodings */ +- || STREQ_OPT (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0) +- || STREQ_OPT (encoding, "CP949", 'C', 'P', '9', '4', '9', 0, 0, 0, 0) +- || STREQ_OPT (encoding, "JOHAB", 'J', 'O', 'H', 'A', 'B', 0, 0, 0, 0)) +- return 1; +- return 0; +-} +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/uniwidth/width.c groff-1.22.3/src/libs/gnulib/lib/uniwidth/width.c +--- groff-1.22.3.old/src/libs/gnulib/lib/uniwidth/width.c 2014-11-04 10:38:35.635518871 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/uniwidth/width.c 1970-01-01 02:00:00.000000000 +0200 +@@ -1,368 +0,0 @@ +-/* Determine display width of Unicode character. +- Copyright (C) 2001-2002, 2006-2014 Free Software Foundation, Inc. +- Written by Bruno Haible , 2002. +- +- This program is free software: you can redistribute it and/or modify it +- under the terms of the GNU Lesser General Public License as published +- by the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public License +- along with this program. If not, see . */ +- +-#include +- +-/* Specification. */ +-#include "uniwidth.h" +- +-#include "cjk.h" +- +-/* +- * Non-spacing attribute table. +- * Consists of: +- * - Non-spacing characters; generated from PropList.txt or +- * "grep '^[^;]*;[^;]*;[^;]*;[^;]*;NSM;' UnicodeData.txt" +- * - Format control characters; generated from +- * "grep '^[^;]*;[^;]*;Cf;' UnicodeData.txt" +- * - Zero width characters; generated from +- * "grep '^[^;]*;ZERO WIDTH ' UnicodeData.txt" +- */ +-static const unsigned char nonspacing_table_data[27*64] = { +- /* 0x0000-0x01ff */ +- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0x0000-0x003f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x0040-0x007f */ +- 0xff, 0xff, 0xff, 0xff, 0x00, 0x20, 0x00, 0x00, /* 0x0080-0x00bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00c0-0x00ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0100-0x013f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0140-0x017f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0180-0x01bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x01c0-0x01ff */ +- /* 0x0200-0x03ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0200-0x023f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0240-0x027f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0280-0x02bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x02c0-0x02ff */ +- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x0300-0x033f */ +- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, /* 0x0340-0x037f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0380-0x03bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x03c0-0x03ff */ +- /* 0x0400-0x05ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0400-0x043f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0440-0x047f */ +- 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0480-0x04bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04c0-0x04ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0500-0x053f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0540-0x057f */ +- 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xbf, /* 0x0580-0x05bf */ +- 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x05c0-0x05ff */ +- /* 0x0600-0x07ff */ +- 0x0f, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, /* 0x0600-0x063f */ +- 0x00, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, /* 0x0640-0x067f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0680-0x06bf */ +- 0x00, 0x00, 0xc0, 0xbf, 0x9f, 0x3d, 0x00, 0x00, /* 0x06c0-0x06ff */ +- 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, /* 0x0700-0x073f */ +- 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0740-0x077f */ +- 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, /* 0x0780-0x07bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x07c0-0x07ff */ +- /* 0x0800-0x09ff */ +- 0x00, 0x00, 0xc0, 0xfb, 0xef, 0x3e, 0x00, 0x00, /* 0x0800-0x083f */ +- 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, /* 0x0840-0x087f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0880-0x08bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08c0-0x08ff */ +- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, /* 0x0900-0x093f */ +- 0xfe, 0x21, 0xfe, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0940-0x097f */ +- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0980-0x09bf */ +- 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x09c0-0x09ff */ +- /* 0x0a00-0x0bff */ +- 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a00-0x0a3f */ +- 0x86, 0x39, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, /* 0x0a40-0x0a7f */ +- 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0a80-0x0abf */ +- 0xbe, 0x21, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0ac0-0x0aff */ +- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, /* 0x0b00-0x0b3f */ +- 0x1e, 0x20, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0b40-0x0b7f */ +- 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b80-0x0bbf */ +- 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0bc0-0x0bff */ +- /* 0x0c00-0x0dff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, /* 0x0c00-0x0c3f */ +- 0xc1, 0x3d, 0x60, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0c40-0x0c7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* 0x0c80-0x0cbf */ +- 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0cc0-0x0cff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d00-0x0d3f */ +- 0x1e, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, /* 0x0d40-0x0d7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d80-0x0dbf */ +- 0x00, 0x04, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0dc0-0x0dff */ +- /* 0x0e00-0x0fff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x07, /* 0x0e00-0x0e3f */ +- 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e40-0x0e7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x1b, /* 0x0e80-0x0ebf */ +- 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0ec0-0x0eff */ +- 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xa0, 0x02, /* 0x0f00-0x0f3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, /* 0x0f40-0x0f7f */ +- 0xdf, 0xe0, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, /* 0x0f80-0x0fbf */ +- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0fc0-0x0fff */ +- /* 0x1000-0x11ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0x66, /* 0x1000-0x103f */ +- 0x00, 0x00, 0x00, 0xc3, 0x01, 0x00, 0x1e, 0x00, /* 0x1040-0x107f */ +- 0x64, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x1080-0x10bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10c0-0x10ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1100-0x113f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1140-0x117f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1180-0x11bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11c0-0x11ff */ +- /* 0x1200-0x13ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1200-0x123f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1240-0x127f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1280-0x12bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x12c0-0x12ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1300-0x133f */ +- 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, /* 0x1340-0x137f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1380-0x13bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x13c0-0x13ff */ +- /* 0x1600-0x17ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1600-0x163f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1640-0x167f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1680-0x16bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x16c0-0x16ff */ +- 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, /* 0x1700-0x173f */ +- 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, /* 0x1740-0x177f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x3f, /* 0x1780-0x17bf */ +- 0x40, 0xfe, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x00, /* 0x17c0-0x17ff */ +- /* 0x1800-0x19ff */ +- 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1800-0x183f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1840-0x187f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x1880-0x18bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18c0-0x18ff */ +- 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x04, 0x0e, /* 0x1900-0x193f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1940-0x197f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1980-0x19bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x19c0-0x19ff */ +- /* 0x1a00-0x1bff */ +- 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, /* 0x1a00-0x1a3f */ +- 0x00, 0x00, 0x40, 0x7f, 0xe5, 0x1f, 0xf8, 0x9f, /* 0x1a40-0x1a7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a80-0x1abf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1ac0-0x1aff */ +- 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x17, /* 0x1b00-0x1b3f */ +- 0x04, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, /* 0x1b40-0x1b7f */ +- 0x03, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x00, /* 0x1b80-0x1bbf */ +- 0x00, 0x00, 0x00, 0x00, 0x40, 0xa3, 0x03, 0x00, /* 0x1bc0-0x1bff */ +- /* 0x1c00-0x1dff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xcf, 0x00, /* 0x1c00-0x1c3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c40-0x1c7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c80-0x1cbf */ +- 0x00, 0x00, 0xf7, 0xff, 0xfd, 0x21, 0x00, 0x00, /* 0x1cc0-0x1cff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d00-0x1d3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d40-0x1d7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d80-0x1dbf */ +- 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xf0, /* 0x1dc0-0x1dff */ +- /* 0x2000-0x21ff */ +- 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, /* 0x2000-0x203f */ +- 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, /* 0x2040-0x207f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2080-0x20bf */ +- 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, /* 0x20c0-0x20ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2100-0x213f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2140-0x217f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2180-0x21bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x21c0-0x21ff */ +- /* 0x2c00-0x2dff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c00-0x2c3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c40-0x2c7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c80-0x2cbf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, /* 0x2cc0-0x2cff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d00-0x2d3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x2d40-0x2d7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d80-0x2dbf */ +- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, /* 0x2dc0-0x2dff */ +- /* 0x3000-0x31ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, /* 0x3000-0x303f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3040-0x307f */ +- 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, /* 0x3080-0x30bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30c0-0x30ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3100-0x313f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3140-0x317f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3180-0x31bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x31c0-0x31ff */ +- /* 0xa600-0xa7ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa600-0xa63f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x30, /* 0xa640-0xa67f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa680-0xa6bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* 0xa6c0-0xa6ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa700-0xa73f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa740-0xa77f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa780-0xa7bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa7c0-0xa7ff */ +- /* 0xa800-0xa9ff */ +- 0x44, 0x08, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, /* 0xa800-0xa83f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa840-0xa87f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa880-0xa8bf */ +- 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, /* 0xa8c0-0xa8ff */ +- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, /* 0xa900-0xa93f */ +- 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa940-0xa97f */ +- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x13, /* 0xa980-0xa9bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa9c0-0xa9ff */ +- /* 0xaa00-0xabff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x66, 0x00, /* 0xaa00-0xaa3f */ +- 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa40-0xaa7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0xc1, /* 0xaa80-0xaabf */ +- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaac0-0xaaff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab00-0xab3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab40-0xab7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab80-0xabbf */ +- 0x00, 0x00, 0x00, 0x00, 0x20, 0x21, 0x00, 0x00, /* 0xabc0-0xabff */ +- /* 0xfa00-0xfbff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa00-0xfa3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa40-0xfa7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa80-0xfabf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfac0-0xfaff */ +- 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, /* 0xfb00-0xfb3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb40-0xfb7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb80-0xfbbf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfbc0-0xfbff */ +- /* 0xfe00-0xffff */ +- 0xff, 0xff, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, /* 0xfe00-0xfe3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe40-0xfe7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe80-0xfebf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xfec0-0xfeff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff00-0xff3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff40-0xff7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff80-0xffbf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, /* 0xffc0-0xffff */ +- /* 0x10000-0x101ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10000-0x1003f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10040-0x1007f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10080-0x100bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x100c0-0x100ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10100-0x1013f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10140-0x1017f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10180-0x101bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* 0x101c0-0x101ff */ +- /* 0x10a00-0x10bff */ +- 0x6e, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, /* 0x10a00-0x10a3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a40-0x10a7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10a80-0x10abf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10ac0-0x10aff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b00-0x10b3f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b40-0x10b7f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10b80-0x10bbf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10bc0-0x10bff */ +- /* 0x11000-0x111ff */ +- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 0x11000-0x1103f */ +- 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11040-0x1107f */ +- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x26, /* 0x11080-0x110bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110c0-0x110ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11100-0x1113f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11140-0x1117f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x11180-0x111bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x111c0-0x111ff */ +- /* 0x1d000-0x1d1ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d000-0x1d03f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d040-0x1d07f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d080-0x1d0bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0c0-0x1d0ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d100-0x1d13f */ +- 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0xf8, 0xff, /* 0x1d140-0x1d17f */ +- 0xe7, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* 0x1d180-0x1d1bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d1c0-0x1d1ff */ +- /* 0x1d200-0x1d3ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d200-0x1d23f */ +- 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d240-0x1d27f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d280-0x1d2bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d2c0-0x1d2ff */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d300-0x1d33f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d340-0x1d37f */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d380-0x1d3bf */ +- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x1d3c0-0x1d3ff */ +-}; +-static const signed char nonspacing_table_ind[240] = { +- 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000-0x0fff */ +- 8, 9, -1, 10, 11, 12, 13, -1, /* 0x1000-0x1fff */ +- 14, -1, -1, -1, -1, -1, 15, -1, /* 0x2000-0x2fff */ +- 16, -1, -1, -1, -1, -1, -1, -1, /* 0x3000-0x3fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x4000-0x4fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x5000-0x5fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x6000-0x6fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x7000-0x7fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x8000-0x8fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x9000-0x9fff */ +- -1, -1, -1, 17, 18, 19, -1, -1, /* 0xa000-0xafff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb000-0xbfff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc000-0xcfff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd000-0xdfff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe000-0xefff */ +- -1, -1, -1, -1, -1, 20, -1, 21, /* 0xf000-0xffff */ +- 22, -1, -1, -1, -1, 23, -1, -1, /* 0x10000-0x10fff */ +- 24, -1, -1, -1, -1, -1, -1, -1, /* 0x11000-0x11fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x12000-0x12fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x13000-0x13fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x14000-0x14fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x15000-0x15fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x16000-0x16fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x17000-0x17fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x18000-0x18fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x19000-0x19fff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1a000-0x1afff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1b000-0x1bfff */ +- -1, -1, -1, -1, -1, -1, -1, -1, /* 0x1c000-0x1cfff */ +- 25, 26, -1, -1, -1, -1, -1, -1 /* 0x1d000-0x1dfff */ +-}; +- +-/* Determine number of column positions required for UC. */ +-int +-uc_width (ucs4_t uc, const char *encoding) +-{ +- /* Test for non-spacing or control character. */ +- if ((uc >> 9) < 240) +- { +- int ind = nonspacing_table_ind[uc >> 9]; +- if (ind >= 0) +- if ((nonspacing_table_data[64*ind + ((uc >> 3) & 63)] >> (uc & 7)) & 1) +- { +- if (uc > 0 && uc < 0xa0) +- return -1; +- else +- return 0; +- } +- } +- else if ((uc >> 9) == (0xe0000 >> 9)) +- { +- if (uc >= 0xe0100) +- { +- if (uc <= 0xe01ef) +- return 0; +- } +- else +- { +- if (uc >= 0xe0020 ? uc <= 0xe007f : uc == 0xe0001) +- return 0; +- } +- } +- /* Test for double-width character. +- * Generated from "grep '^[^;]\{4,5\};[WF]' EastAsianWidth.txt" +- * and "grep '^[^;]\{4,5\};[^WF]' EastAsianWidth.txt" +- */ +- if (uc >= 0x1100 +- && ((uc < 0x1160) /* Hangul Jamo */ +- || (uc >= 0x2329 && uc < 0x232b) /* Angle Brackets */ +- || (uc >= 0x2e80 && uc < 0xa4d0 /* CJK ... Yi */ +- && !(uc == 0x303f) && !(uc >= 0x4dc0 && uc < 0x4e00)) +- || (uc >= 0xac00 && uc < 0xd7a4) /* Hangul Syllables */ +- || (uc >= 0xf900 && uc < 0xfb00) /* CJK Compatibility Ideographs */ +- || (uc >= 0xfe10 && uc < 0xfe20) /* Presentation Forms for Vertical */ +- || (uc >= 0xfe30 && uc < 0xfe70) /* CJK Compatibility Forms */ +- || (uc >= 0xff00 && uc < 0xff61) /* Fullwidth Forms */ +- || (uc >= 0xffe0 && uc < 0xffe7) /* Fullwidth Signs */ +- || (uc >= 0x20000 && uc <= 0x2ffff) /* Supplementary Ideographic Plane */ +- || (uc >= 0x30000 && uc <= 0x3ffff) /* Tertiary Ideographic Plane */ +- ) ) +- return 2; +- /* In ancient CJK encodings, Cyrillic and most other characters are +- double-width as well. */ +- if (uc >= 0x00A1 && uc < 0xFF61 && uc != 0x20A9 +- && is_cjk_encoding (encoding)) +- return 2; +- return 1; +-} +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/uniwidth.in.h groff-1.22.3/src/libs/gnulib/lib/uniwidth.in.h +--- groff-1.22.3.old/src/libs/gnulib/lib/uniwidth.in.h 2014-11-04 10:38:35.630518934 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/uniwidth.in.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,72 +0,0 @@ +-/* Display width functions. +- Copyright (C) 2001-2002, 2005, 2007, 2009-2014 Free Software Foundation, +- Inc. +- +- This program is free software: you can redistribute it and/or modify it +- under the terms of the GNU Lesser General Public License as published +- by the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +- Lesser General Public License for more details. +- +- You should have received a copy of the GNU Lesser General Public License +- along with this program. If not, see . */ +- +-#ifndef _UNIWIDTH_H +-#define _UNIWIDTH_H +- +-#include "unitypes.h" +- +-/* Get size_t. */ +-#include +- +-/* Get locale_charset() declaration. */ +-#include "localcharset.h" +- +-#ifdef __cplusplus +-extern "C" { +-#endif +- +- +-/* Display width. */ +- +-/* These functions are locale dependent. The encoding argument identifies +- the encoding (e.g. "ISO-8859-2" for Polish). */ +- +-/* Determine number of column positions required for UC. */ +-extern int +- uc_width (ucs4_t uc, const char *encoding) +- _UC_ATTRIBUTE_PURE; +- +-/* Determine number of column positions required for first N units +- (or fewer if S ends before this) in S. */ +-extern int +- u8_width (const uint8_t *s, size_t n, const char *encoding) +- _UC_ATTRIBUTE_PURE; +-extern int +- u16_width (const uint16_t *s, size_t n, const char *encoding) +- _UC_ATTRIBUTE_PURE; +-extern int +- u32_width (const uint32_t *s, size_t n, const char *encoding) +- _UC_ATTRIBUTE_PURE; +- +-/* Determine number of column positions required for S. */ +-extern int +- u8_strwidth (const uint8_t *s, const char *encoding) +- _UC_ATTRIBUTE_PURE; +-extern int +- u16_strwidth (const uint16_t *s, const char *encoding) +- _UC_ATTRIBUTE_PURE; +-extern int +- u32_strwidth (const uint32_t *s, const char *encoding) +- _UC_ATTRIBUTE_PURE; +- +- +-#ifdef __cplusplus +-} +-#endif +- +-#endif /* _UNIWIDTH_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/verify.h groff-1.22.3/src/libs/gnulib/lib/verify.h +--- groff-1.22.3.old/src/libs/gnulib/lib/verify.h 2014-11-04 10:38:35.630518934 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/verify.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,279 +0,0 @@ +-/* Compile-time assert-like macros. +- +- Copyright (C) 2005-2006, 2009-2014 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ +- +-/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ +- +-#ifndef _GL_VERIFY_H +-#define _GL_VERIFY_H +- +- +-/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11. +- This is supported by GCC 4.6.0 and later, in C mode, and its use +- here generates easier-to-read diagnostics when verify (R) fails. +- +- Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11. +- This will likely be supported by future GCC versions, in C++ mode. +- +- Use this only with GCC. If we were willing to slow 'configure' +- down we could also use it with other compilers, but since this +- affects only the quality of diagnostics, why bother? */ +-#if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \ +- && (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \ +- && !defined __cplusplus) +-# define _GL_HAVE__STATIC_ASSERT 1 +-#endif +-/* The condition (99 < __GNUC__) is temporary, until we know about the +- first G++ release that supports static_assert. */ +-#if (99 < __GNUC__) && defined __cplusplus +-# define _GL_HAVE_STATIC_ASSERT 1 +-#endif +- +-/* FreeBSD 9.1 , included by and lots of other +- system headers, defines a conflicting _Static_assert that is no +- better than ours; override it. */ +-#ifndef _GL_HAVE_STATIC_ASSERT +-# include +-# undef _Static_assert +-#endif +- +-/* Each of these macros verifies that its argument R is nonzero. To +- be portable, R should be an integer constant expression. Unlike +- assert (R), there is no run-time overhead. +- +- If _Static_assert works, verify (R) uses it directly. Similarly, +- _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct +- that is an operand of sizeof. +- +- The code below uses several ideas for C++ compilers, and for C +- compilers that do not support _Static_assert: +- +- * The first step is ((R) ? 1 : -1). Given an expression R, of +- integral or boolean or floating-point type, this yields an +- expression of integral type, whose value is later verified to be +- constant and nonnegative. +- +- * Next this expression W is wrapped in a type +- struct _gl_verify_type { +- unsigned int _gl_verify_error_if_negative: W; +- }. +- If W is negative, this yields a compile-time error. No compiler can +- deal with a bit-field of negative size. +- +- One might think that an array size check would have the same +- effect, that is, that the type struct { unsigned int dummy[W]; } +- would work as well. However, inside a function, some compilers +- (such as C++ compilers and GNU C) allow local parameters and +- variables inside array size expressions. With these compilers, +- an array size check would not properly diagnose this misuse of +- the verify macro: +- +- void function (int n) { verify (n < 0); } +- +- * For the verify macro, the struct _gl_verify_type will need to +- somehow be embedded into a declaration. To be portable, this +- declaration must declare an object, a constant, a function, or a +- typedef name. If the declared entity uses the type directly, +- such as in +- +- struct dummy {...}; +- typedef struct {...} dummy; +- extern struct {...} *dummy; +- extern void dummy (struct {...} *); +- extern struct {...} *dummy (void); +- +- two uses of the verify macro would yield colliding declarations +- if the entity names are not disambiguated. A workaround is to +- attach the current line number to the entity name: +- +- #define _GL_CONCAT0(x, y) x##y +- #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) +- extern struct {...} * _GL_CONCAT (dummy, __LINE__); +- +- But this has the problem that two invocations of verify from +- within the same macro would collide, since the __LINE__ value +- would be the same for both invocations. (The GCC __COUNTER__ +- macro solves this problem, but is not portable.) +- +- A solution is to use the sizeof operator. It yields a number, +- getting rid of the identity of the type. Declarations like +- +- extern int dummy [sizeof (struct {...})]; +- extern void dummy (int [sizeof (struct {...})]); +- extern int (*dummy (void)) [sizeof (struct {...})]; +- +- can be repeated. +- +- * Should the implementation use a named struct or an unnamed struct? +- Which of the following alternatives can be used? +- +- extern int dummy [sizeof (struct {...})]; +- extern int dummy [sizeof (struct _gl_verify_type {...})]; +- extern void dummy (int [sizeof (struct {...})]); +- extern void dummy (int [sizeof (struct _gl_verify_type {...})]); +- extern int (*dummy (void)) [sizeof (struct {...})]; +- extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})]; +- +- In the second and sixth case, the struct type is exported to the +- outer scope; two such declarations therefore collide. GCC warns +- about the first, third, and fourth cases. So the only remaining +- possibility is the fifth case: +- +- extern int (*dummy (void)) [sizeof (struct {...})]; +- +- * GCC warns about duplicate declarations of the dummy function if +- -Wredundant-decls is used. GCC 4.3 and later have a builtin +- __COUNTER__ macro that can let us generate unique identifiers for +- each dummy function, to suppress this warning. +- +- * This implementation exploits the fact that older versions of GCC, +- which do not support _Static_assert, also do not warn about the +- last declaration mentioned above. +- +- * GCC warns if -Wnested-externs is enabled and verify() is used +- within a function body; but inside a function, you can always +- arrange to use verify_expr() instead. +- +- * In C++, any struct definition inside sizeof is invalid. +- Use a template type to work around the problem. */ +- +-/* Concatenate two preprocessor tokens. */ +-#define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y) +-#define _GL_CONCAT0(x, y) x##y +- +-/* _GL_COUNTER is an integer, preferably one that changes each time we +- use it. Use __COUNTER__ if it works, falling back on __LINE__ +- otherwise. __LINE__ isn't perfect, but it's better than a +- constant. */ +-#if defined __COUNTER__ && __COUNTER__ != __COUNTER__ +-# define _GL_COUNTER __COUNTER__ +-#else +-# define _GL_COUNTER __LINE__ +-#endif +- +-/* Generate a symbol with the given prefix, making it unique if +- possible. */ +-#define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) +- +-/* Verify requirement R at compile-time, as an integer constant expression +- that returns 1. If R is false, fail at compile-time, preferably +- with a diagnostic that includes the string-literal DIAGNOSTIC. */ +- +-#define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ +- (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) +- +-#ifdef __cplusplus +-# if !GNULIB_defined_struct__gl_verify_type +-template +- struct _gl_verify_type { +- unsigned int _gl_verify_error_if_negative: w; +- }; +-# define GNULIB_defined_struct__gl_verify_type 1 +-# endif +-# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ +- _gl_verify_type<(R) ? 1 : -1> +-#elif defined _GL_HAVE__STATIC_ASSERT +-# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ +- struct { \ +- _Static_assert (R, DIAGNOSTIC); \ +- int _gl_dummy; \ +- } +-#else +-# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ +- struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } +-#endif +- +-/* Verify requirement R at compile-time, as a declaration without a +- trailing ';'. If R is false, fail at compile-time, preferably +- with a diagnostic that includes the string-literal DIAGNOSTIC. +- +- Unfortunately, unlike C11, this implementation must appear as an +- ordinary declaration, and cannot appear inside struct { ... }. */ +- +-#ifdef _GL_HAVE__STATIC_ASSERT +-# define _GL_VERIFY _Static_assert +-#else +-# define _GL_VERIFY(R, DIAGNOSTIC) \ +- extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ +- [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] +-#endif +- +-/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ +-#ifdef _GL_STATIC_ASSERT_H +-# if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert +-# define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) +-# endif +-# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert +-# define static_assert _Static_assert /* C11 requires this #define. */ +-# endif +-#endif +- +-/* @assert.h omit start@ */ +- +-/* Each of these macros verifies that its argument R is nonzero. To +- be portable, R should be an integer constant expression. Unlike +- assert (R), there is no run-time overhead. +- +- There are two macros, since no single macro can be used in all +- contexts in C. verify_true (R) is for scalar contexts, including +- integer constant expression contexts. verify (R) is for declaration +- contexts, e.g., the top level. */ +- +-/* Verify requirement R at compile-time, as an integer constant expression. +- Return 1. This is equivalent to verify_expr (R, 1). +- +- verify_true is obsolescent; please use verify_expr instead. */ +- +-#define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") +- +-/* Verify requirement R at compile-time. Return the value of the +- expression E. */ +- +-#define verify_expr(R, E) \ +- (_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E)) +- +-/* Verify requirement R at compile-time, as a declaration without a +- trailing ';'. */ +- +-#define verify(R) _GL_VERIFY (R, "verify (" #R ")") +- +-#ifndef __has_builtin +-# define __has_builtin(x) 0 +-#endif +- +-/* Assume that R always holds. This lets the compiler optimize +- accordingly. R should not have side-effects; it may or may not be +- evaluated. Behavior is undefined if R is false. */ +- +-#if (__has_builtin (__builtin_unreachable) \ +- || 4 < __GNUC__ + (5 <= __GNUC_MINOR__)) +-# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ()) +-#elif 1200 <= _MSC_VER +-# define assume(R) __assume (R) +-#elif (defined lint \ +- && (__has_builtin (__builtin_trap) \ +- || 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__)))) +- /* Doing it this way helps various packages when configured with +- --enable-gcc-warnings, which compiles with -Dlint. It's nicer +- when 'assume' silences warnings even with older GCCs. */ +-# define assume(R) ((R) ? (void) 0 : __builtin_trap ()) +-#else +-# define assume(R) ((void) (0 && (R))) +-#endif +- +-/* @assert.h omit end@ */ +- +-#endif +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/wchar.in.h groff-1.22.3/src/libs/gnulib/lib/wchar.in.h +--- groff-1.22.3.old/src/libs/gnulib/lib/wchar.in.h 2014-11-04 10:38:35.631518921 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/wchar.in.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1028 +0,0 @@ +-/* A substitute for ISO C99 , for platforms that have issues. +- +- Copyright (C) 2007-2014 Free Software Foundation, Inc. +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2, or (at your option) +- any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, see . */ +- +-/* Written by Eric Blake. */ +- +-/* +- * ISO C 99 for platforms that have issues. +- * +- * +- * For now, this just ensures proper prerequisite inclusion order and +- * the declaration of wcwidth(). +- */ +- +-#if __GNUC__ >= 3 +-@PRAGMA_SYSTEM_HEADER@ +-#endif +-@PRAGMA_COLUMNS@ +- +-#if defined __need_mbstate_t || defined __need_wint_t || (defined __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H +-/* Special invocation convention: +- - Inside glibc and uClibc header files. +- - On HP-UX 11.00 we have a sequence of nested includes +- -> -> , and the latter includes , +- once indirectly -> -> -> +- and once directly. In both situations 'wint_t' is not yet defined, +- therefore we cannot provide the function overrides; instead include only +- the system's . +- - On IRIX 6.5, similarly, we have an include -> , and +- the latter includes . But here, we have no way to detect whether +- is completely included or is still being included. */ +- +-#@INCLUDE_NEXT@ @NEXT_WCHAR_H@ +- +-#else +-/* Normal invocation convention. */ +- +-#ifndef _@GUARD_PREFIX@_WCHAR_H +- +-#define _GL_ALREADY_INCLUDING_WCHAR_H +- +-#if @HAVE_FEATURES_H@ +-# include /* for __GLIBC__ */ +-#endif +- +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . +- In some builds of uClibc, is nonexistent and wchar_t is defined +- by . +- But avoid namespace pollution on glibc systems. */ +-#if !(defined __GLIBC__ && !defined __UCLIBC__) +-# include +-#endif +-#ifndef __GLIBC__ +-# include +-# include +-#endif +- +-/* Include the original if it exists. +- Some builds of uClibc lack it. */ +-/* The include_next requires a split double-inclusion guard. */ +-#if @HAVE_WCHAR_H@ +-# @INCLUDE_NEXT@ @NEXT_WCHAR_H@ +-#endif +- +-#undef _GL_ALREADY_INCLUDING_WCHAR_H +- +-#ifndef _@GUARD_PREFIX@_WCHAR_H +-#define _@GUARD_PREFIX@_WCHAR_H +- +-/* The __attribute__ feature is available in gcc versions 2.5 and later. +- The attribute __pure__ was added in gcc 2.96. */ +-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +-# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +-#else +-# define _GL_ATTRIBUTE_PURE /* empty */ +-#endif +- +-/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ +- +-/* The definition of _GL_ARG_NONNULL is copied here. */ +- +-/* The definition of _GL_WARN_ON_USE is copied here. */ +- +- +-/* Define wint_t and WEOF. (Also done in wctype.in.h.) */ +-#if !@HAVE_WINT_T@ && !defined wint_t +-# define wint_t int +-# ifndef WEOF +-# define WEOF -1 +-# endif +-#else +-/* MSVC defines wint_t as 'unsigned short' in . +- This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be +- "unchanged by default argument promotions". Override it. */ +-# if defined _MSC_VER +-# if !GNULIB_defined_wint_t +-# include +-typedef unsigned int rpl_wint_t; +-# undef wint_t +-# define wint_t rpl_wint_t +-# define GNULIB_defined_wint_t 1 +-# endif +-# endif +-# ifndef WEOF +-# define WEOF ((wint_t) -1) +-# endif +-#endif +- +- +-/* Override mbstate_t if it is too small. +- On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for +- implementing mbrtowc for encodings like UTF-8. */ +-#if !(@HAVE_MBSINIT@ && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@ +-# if !GNULIB_defined_mbstate_t +-typedef int rpl_mbstate_t; +-# undef mbstate_t +-# define mbstate_t rpl_mbstate_t +-# define GNULIB_defined_mbstate_t 1 +-# endif +-#endif +- +- +-/* Convert a single-byte character to a wide character. */ +-#if @GNULIB_BTOWC@ +-# if @REPLACE_BTOWC@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef btowc +-# define btowc rpl_btowc +-# endif +-_GL_FUNCDECL_RPL (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); +-_GL_CXXALIAS_RPL (btowc, wint_t, (int c)); +-# else +-# if !@HAVE_BTOWC@ +-_GL_FUNCDECL_SYS (btowc, wint_t, (int c) _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (btowc, wint_t, (int c)); +-# endif +-_GL_CXXALIASWARN (btowc); +-#elif defined GNULIB_POSIXCHECK +-# undef btowc +-# if HAVE_RAW_DECL_BTOWC +-_GL_WARN_ON_USE (btowc, "btowc is unportable - " +- "use gnulib module btowc for portability"); +-# endif +-#endif +- +- +-/* Convert a wide character to a single-byte character. */ +-#if @GNULIB_WCTOB@ +-# if @REPLACE_WCTOB@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef wctob +-# define wctob rpl_wctob +-# endif +-_GL_FUNCDECL_RPL (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); +-_GL_CXXALIAS_RPL (wctob, int, (wint_t wc)); +-# else +-# if !defined wctob && !@HAVE_DECL_WCTOB@ +-/* wctob is provided by gnulib, or wctob exists but is not declared. */ +-_GL_FUNCDECL_SYS (wctob, int, (wint_t wc) _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wctob, int, (wint_t wc)); +-# endif +-_GL_CXXALIASWARN (wctob); +-#elif defined GNULIB_POSIXCHECK +-# undef wctob +-# if HAVE_RAW_DECL_WCTOB +-_GL_WARN_ON_USE (wctob, "wctob is unportable - " +- "use gnulib module wctob for portability"); +-# endif +-#endif +- +- +-/* Test whether *PS is in the initial state. */ +-#if @GNULIB_MBSINIT@ +-# if @REPLACE_MBSINIT@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef mbsinit +-# define mbsinit rpl_mbsinit +-# endif +-_GL_FUNCDECL_RPL (mbsinit, int, (const mbstate_t *ps)); +-_GL_CXXALIAS_RPL (mbsinit, int, (const mbstate_t *ps)); +-# else +-# if !@HAVE_MBSINIT@ +-_GL_FUNCDECL_SYS (mbsinit, int, (const mbstate_t *ps)); +-# endif +-_GL_CXXALIAS_SYS (mbsinit, int, (const mbstate_t *ps)); +-# endif +-_GL_CXXALIASWARN (mbsinit); +-#elif defined GNULIB_POSIXCHECK +-# undef mbsinit +-# if HAVE_RAW_DECL_MBSINIT +-_GL_WARN_ON_USE (mbsinit, "mbsinit is unportable - " +- "use gnulib module mbsinit for portability"); +-# endif +-#endif +- +- +-/* Convert a multibyte character to a wide character. */ +-#if @GNULIB_MBRTOWC@ +-# if @REPLACE_MBRTOWC@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef mbrtowc +-# define mbrtowc rpl_mbrtowc +-# endif +-_GL_FUNCDECL_RPL (mbrtowc, size_t, +- (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +-_GL_CXXALIAS_RPL (mbrtowc, size_t, +- (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +-# else +-# if !@HAVE_MBRTOWC@ +-_GL_FUNCDECL_SYS (mbrtowc, size_t, +- (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +-# endif +-_GL_CXXALIAS_SYS (mbrtowc, size_t, +- (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)); +-# endif +-_GL_CXXALIASWARN (mbrtowc); +-#elif defined GNULIB_POSIXCHECK +-# undef mbrtowc +-# if HAVE_RAW_DECL_MBRTOWC +-_GL_WARN_ON_USE (mbrtowc, "mbrtowc is unportable - " +- "use gnulib module mbrtowc for portability"); +-# endif +-#endif +- +- +-/* Recognize a multibyte character. */ +-#if @GNULIB_MBRLEN@ +-# if @REPLACE_MBRLEN@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef mbrlen +-# define mbrlen rpl_mbrlen +-# endif +-_GL_FUNCDECL_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +-_GL_CXXALIAS_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +-# else +-# if !@HAVE_MBRLEN@ +-_GL_FUNCDECL_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +-# endif +-_GL_CXXALIAS_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps)); +-# endif +-_GL_CXXALIASWARN (mbrlen); +-#elif defined GNULIB_POSIXCHECK +-# undef mbrlen +-# if HAVE_RAW_DECL_MBRLEN +-_GL_WARN_ON_USE (mbrlen, "mbrlen is unportable - " +- "use gnulib module mbrlen for portability"); +-# endif +-#endif +- +- +-/* Convert a string to a wide string. */ +-#if @GNULIB_MBSRTOWCS@ +-# if @REPLACE_MBSRTOWCS@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef mbsrtowcs +-# define mbsrtowcs rpl_mbsrtowcs +-# endif +-_GL_FUNCDECL_RPL (mbsrtowcs, size_t, +- (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) +- _GL_ARG_NONNULL ((2))); +-_GL_CXXALIAS_RPL (mbsrtowcs, size_t, +- (wchar_t *dest, const char **srcp, size_t len, +- mbstate_t *ps)); +-# else +-# if !@HAVE_MBSRTOWCS@ +-_GL_FUNCDECL_SYS (mbsrtowcs, size_t, +- (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps) +- _GL_ARG_NONNULL ((2))); +-# endif +-_GL_CXXALIAS_SYS (mbsrtowcs, size_t, +- (wchar_t *dest, const char **srcp, size_t len, +- mbstate_t *ps)); +-# endif +-_GL_CXXALIASWARN (mbsrtowcs); +-#elif defined GNULIB_POSIXCHECK +-# undef mbsrtowcs +-# if HAVE_RAW_DECL_MBSRTOWCS +-_GL_WARN_ON_USE (mbsrtowcs, "mbsrtowcs is unportable - " +- "use gnulib module mbsrtowcs for portability"); +-# endif +-#endif +- +- +-/* Convert a string to a wide string. */ +-#if @GNULIB_MBSNRTOWCS@ +-# if @REPLACE_MBSNRTOWCS@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef mbsnrtowcs +-# define mbsnrtowcs rpl_mbsnrtowcs +-# endif +-_GL_FUNCDECL_RPL (mbsnrtowcs, size_t, +- (wchar_t *dest, const char **srcp, size_t srclen, size_t len, +- mbstate_t *ps) +- _GL_ARG_NONNULL ((2))); +-_GL_CXXALIAS_RPL (mbsnrtowcs, size_t, +- (wchar_t *dest, const char **srcp, size_t srclen, size_t len, +- mbstate_t *ps)); +-# else +-# if !@HAVE_MBSNRTOWCS@ +-_GL_FUNCDECL_SYS (mbsnrtowcs, size_t, +- (wchar_t *dest, const char **srcp, size_t srclen, size_t len, +- mbstate_t *ps) +- _GL_ARG_NONNULL ((2))); +-# endif +-_GL_CXXALIAS_SYS (mbsnrtowcs, size_t, +- (wchar_t *dest, const char **srcp, size_t srclen, size_t len, +- mbstate_t *ps)); +-# endif +-_GL_CXXALIASWARN (mbsnrtowcs); +-#elif defined GNULIB_POSIXCHECK +-# undef mbsnrtowcs +-# if HAVE_RAW_DECL_MBSNRTOWCS +-_GL_WARN_ON_USE (mbsnrtowcs, "mbsnrtowcs is unportable - " +- "use gnulib module mbsnrtowcs for portability"); +-# endif +-#endif +- +- +-/* Convert a wide character to a multibyte character. */ +-#if @GNULIB_WCRTOMB@ +-# if @REPLACE_WCRTOMB@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef wcrtomb +-# define wcrtomb rpl_wcrtomb +-# endif +-_GL_FUNCDECL_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +-_GL_CXXALIAS_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +-# else +-# if !@HAVE_WCRTOMB@ +-_GL_FUNCDECL_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +-# endif +-_GL_CXXALIAS_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps)); +-# endif +-_GL_CXXALIASWARN (wcrtomb); +-#elif defined GNULIB_POSIXCHECK +-# undef wcrtomb +-# if HAVE_RAW_DECL_WCRTOMB +-_GL_WARN_ON_USE (wcrtomb, "wcrtomb is unportable - " +- "use gnulib module wcrtomb for portability"); +-# endif +-#endif +- +- +-/* Convert a wide string to a string. */ +-#if @GNULIB_WCSRTOMBS@ +-# if @REPLACE_WCSRTOMBS@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef wcsrtombs +-# define wcsrtombs rpl_wcsrtombs +-# endif +-_GL_FUNCDECL_RPL (wcsrtombs, size_t, +- (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) +- _GL_ARG_NONNULL ((2))); +-_GL_CXXALIAS_RPL (wcsrtombs, size_t, +- (char *dest, const wchar_t **srcp, size_t len, +- mbstate_t *ps)); +-# else +-# if !@HAVE_WCSRTOMBS@ +-_GL_FUNCDECL_SYS (wcsrtombs, size_t, +- (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps) +- _GL_ARG_NONNULL ((2))); +-# endif +-_GL_CXXALIAS_SYS (wcsrtombs, size_t, +- (char *dest, const wchar_t **srcp, size_t len, +- mbstate_t *ps)); +-# endif +-_GL_CXXALIASWARN (wcsrtombs); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsrtombs +-# if HAVE_RAW_DECL_WCSRTOMBS +-_GL_WARN_ON_USE (wcsrtombs, "wcsrtombs is unportable - " +- "use gnulib module wcsrtombs for portability"); +-# endif +-#endif +- +- +-/* Convert a wide string to a string. */ +-#if @GNULIB_WCSNRTOMBS@ +-# if @REPLACE_WCSNRTOMBS@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef wcsnrtombs +-# define wcsnrtombs rpl_wcsnrtombs +-# endif +-_GL_FUNCDECL_RPL (wcsnrtombs, size_t, +- (char *dest, const wchar_t **srcp, size_t srclen, size_t len, +- mbstate_t *ps) +- _GL_ARG_NONNULL ((2))); +-_GL_CXXALIAS_RPL (wcsnrtombs, size_t, +- (char *dest, const wchar_t **srcp, size_t srclen, size_t len, +- mbstate_t *ps)); +-# else +-# if !@HAVE_WCSNRTOMBS@ +-_GL_FUNCDECL_SYS (wcsnrtombs, size_t, +- (char *dest, const wchar_t **srcp, size_t srclen, size_t len, +- mbstate_t *ps) +- _GL_ARG_NONNULL ((2))); +-# endif +-_GL_CXXALIAS_SYS (wcsnrtombs, size_t, +- (char *dest, const wchar_t **srcp, size_t srclen, size_t len, +- mbstate_t *ps)); +-# endif +-_GL_CXXALIASWARN (wcsnrtombs); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsnrtombs +-# if HAVE_RAW_DECL_WCSNRTOMBS +-_GL_WARN_ON_USE (wcsnrtombs, "wcsnrtombs is unportable - " +- "use gnulib module wcsnrtombs for portability"); +-# endif +-#endif +- +- +-/* Return the number of screen columns needed for WC. */ +-#if @GNULIB_WCWIDTH@ +-# if @REPLACE_WCWIDTH@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef wcwidth +-# define wcwidth rpl_wcwidth +-# endif +-_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); +-_GL_CXXALIAS_RPL (wcwidth, int, (wchar_t)); +-# else +-# if !@HAVE_DECL_WCWIDTH@ +-/* wcwidth exists but is not declared. */ +-_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t) _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcwidth, int, (wchar_t)); +-# endif +-_GL_CXXALIASWARN (wcwidth); +-#elif defined GNULIB_POSIXCHECK +-# undef wcwidth +-# if HAVE_RAW_DECL_WCWIDTH +-_GL_WARN_ON_USE (wcwidth, "wcwidth is unportable - " +- "use gnulib module wcwidth for portability"); +-# endif +-#endif +- +- +-/* Search N wide characters of S for C. */ +-#if @GNULIB_WMEMCHR@ +-# if !@HAVE_WMEMCHR@ +-_GL_FUNCDECL_SYS (wmemchr, wchar_t *, (const wchar_t *s, wchar_t c, size_t n) +- _GL_ATTRIBUTE_PURE); +-# endif +- /* On some systems, this function is defined as an overloaded function: +- extern "C++" { +- const wchar_t * std::wmemchr (const wchar_t *, wchar_t, size_t); +- wchar_t * std::wmemchr (wchar_t *, wchar_t, size_t); +- } */ +-_GL_CXXALIAS_SYS_CAST2 (wmemchr, +- wchar_t *, (const wchar_t *, wchar_t, size_t), +- const wchar_t *, (const wchar_t *, wchar_t, size_t)); +-# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ +- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +-_GL_CXXALIASWARN1 (wmemchr, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); +-_GL_CXXALIASWARN1 (wmemchr, const wchar_t *, +- (const wchar_t *s, wchar_t c, size_t n)); +-# else +-_GL_CXXALIASWARN (wmemchr); +-# endif +-#elif defined GNULIB_POSIXCHECK +-# undef wmemchr +-# if HAVE_RAW_DECL_WMEMCHR +-_GL_WARN_ON_USE (wmemchr, "wmemchr is unportable - " +- "use gnulib module wmemchr for portability"); +-# endif +-#endif +- +- +-/* Compare N wide characters of S1 and S2. */ +-#if @GNULIB_WMEMCMP@ +-# if !@HAVE_WMEMCMP@ +-_GL_FUNCDECL_SYS (wmemcmp, int, +- (const wchar_t *s1, const wchar_t *s2, size_t n) +- _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wmemcmp, int, +- (const wchar_t *s1, const wchar_t *s2, size_t n)); +-_GL_CXXALIASWARN (wmemcmp); +-#elif defined GNULIB_POSIXCHECK +-# undef wmemcmp +-# if HAVE_RAW_DECL_WMEMCMP +-_GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - " +- "use gnulib module wmemcmp for portability"); +-# endif +-#endif +- +- +-/* Copy N wide characters of SRC to DEST. */ +-#if @GNULIB_WMEMCPY@ +-# if !@HAVE_WMEMCPY@ +-_GL_FUNCDECL_SYS (wmemcpy, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-# endif +-_GL_CXXALIAS_SYS (wmemcpy, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-_GL_CXXALIASWARN (wmemcpy); +-#elif defined GNULIB_POSIXCHECK +-# undef wmemcpy +-# if HAVE_RAW_DECL_WMEMCPY +-_GL_WARN_ON_USE (wmemcpy, "wmemcpy is unportable - " +- "use gnulib module wmemcpy for portability"); +-# endif +-#endif +- +- +-/* Copy N wide characters of SRC to DEST, guaranteeing correct behavior for +- overlapping memory areas. */ +-#if @GNULIB_WMEMMOVE@ +-# if !@HAVE_WMEMMOVE@ +-_GL_FUNCDECL_SYS (wmemmove, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-# endif +-_GL_CXXALIAS_SYS (wmemmove, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-_GL_CXXALIASWARN (wmemmove); +-#elif defined GNULIB_POSIXCHECK +-# undef wmemmove +-# if HAVE_RAW_DECL_WMEMMOVE +-_GL_WARN_ON_USE (wmemmove, "wmemmove is unportable - " +- "use gnulib module wmemmove for portability"); +-# endif +-#endif +- +- +-/* Set N wide characters of S to C. */ +-#if @GNULIB_WMEMSET@ +-# if !@HAVE_WMEMSET@ +-_GL_FUNCDECL_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); +-# endif +-_GL_CXXALIAS_SYS (wmemset, wchar_t *, (wchar_t *s, wchar_t c, size_t n)); +-_GL_CXXALIASWARN (wmemset); +-#elif defined GNULIB_POSIXCHECK +-# undef wmemset +-# if HAVE_RAW_DECL_WMEMSET +-_GL_WARN_ON_USE (wmemset, "wmemset is unportable - " +- "use gnulib module wmemset for portability"); +-# endif +-#endif +- +- +-/* Return the number of wide characters in S. */ +-#if @GNULIB_WCSLEN@ +-# if !@HAVE_WCSLEN@ +-_GL_FUNCDECL_SYS (wcslen, size_t, (const wchar_t *s) _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcslen, size_t, (const wchar_t *s)); +-_GL_CXXALIASWARN (wcslen); +-#elif defined GNULIB_POSIXCHECK +-# undef wcslen +-# if HAVE_RAW_DECL_WCSLEN +-_GL_WARN_ON_USE (wcslen, "wcslen is unportable - " +- "use gnulib module wcslen for portability"); +-# endif +-#endif +- +- +-/* Return the number of wide characters in S, but at most MAXLEN. */ +-#if @GNULIB_WCSNLEN@ +-# if !@HAVE_WCSNLEN@ +-_GL_FUNCDECL_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen) +- _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcsnlen, size_t, (const wchar_t *s, size_t maxlen)); +-_GL_CXXALIASWARN (wcsnlen); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsnlen +-# if HAVE_RAW_DECL_WCSNLEN +-_GL_WARN_ON_USE (wcsnlen, "wcsnlen is unportable - " +- "use gnulib module wcsnlen for portability"); +-# endif +-#endif +- +- +-/* Copy SRC to DEST. */ +-#if @GNULIB_WCSCPY@ +-# if !@HAVE_WCSCPY@ +-_GL_FUNCDECL_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); +-# endif +-_GL_CXXALIAS_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); +-_GL_CXXALIASWARN (wcscpy); +-#elif defined GNULIB_POSIXCHECK +-# undef wcscpy +-# if HAVE_RAW_DECL_WCSCPY +-_GL_WARN_ON_USE (wcscpy, "wcscpy is unportable - " +- "use gnulib module wcscpy for portability"); +-# endif +-#endif +- +- +-/* Copy SRC to DEST, returning the address of the terminating L'\0' in DEST. */ +-#if @GNULIB_WCPCPY@ +-# if !@HAVE_WCPCPY@ +-_GL_FUNCDECL_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); +-# endif +-_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src)); +-_GL_CXXALIASWARN (wcpcpy); +-#elif defined GNULIB_POSIXCHECK +-# undef wcpcpy +-# if HAVE_RAW_DECL_WCPCPY +-_GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - " +- "use gnulib module wcpcpy for portability"); +-# endif +-#endif +- +- +-/* Copy no more than N wide characters of SRC to DEST. */ +-#if @GNULIB_WCSNCPY@ +-# if !@HAVE_WCSNCPY@ +-_GL_FUNCDECL_SYS (wcsncpy, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-# endif +-_GL_CXXALIAS_SYS (wcsncpy, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-_GL_CXXALIASWARN (wcsncpy); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsncpy +-# if HAVE_RAW_DECL_WCSNCPY +-_GL_WARN_ON_USE (wcsncpy, "wcsncpy is unportable - " +- "use gnulib module wcsncpy for portability"); +-# endif +-#endif +- +- +-/* Copy no more than N characters of SRC to DEST, returning the address of +- the last character written into DEST. */ +-#if @GNULIB_WCPNCPY@ +-# if !@HAVE_WCPNCPY@ +-_GL_FUNCDECL_SYS (wcpncpy, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-# endif +-_GL_CXXALIAS_SYS (wcpncpy, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-_GL_CXXALIASWARN (wcpncpy); +-#elif defined GNULIB_POSIXCHECK +-# undef wcpncpy +-# if HAVE_RAW_DECL_WCPNCPY +-_GL_WARN_ON_USE (wcpncpy, "wcpncpy is unportable - " +- "use gnulib module wcpncpy for portability"); +-# endif +-#endif +- +- +-/* Append SRC onto DEST. */ +-#if @GNULIB_WCSCAT@ +-# if !@HAVE_WCSCAT@ +-_GL_FUNCDECL_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src)); +-# endif +-_GL_CXXALIAS_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src)); +-_GL_CXXALIASWARN (wcscat); +-#elif defined GNULIB_POSIXCHECK +-# undef wcscat +-# if HAVE_RAW_DECL_WCSCAT +-_GL_WARN_ON_USE (wcscat, "wcscat is unportable - " +- "use gnulib module wcscat for portability"); +-# endif +-#endif +- +- +-/* Append no more than N wide characters of SRC onto DEST. */ +-#if @GNULIB_WCSNCAT@ +-# if !@HAVE_WCSNCAT@ +-_GL_FUNCDECL_SYS (wcsncat, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-# endif +-_GL_CXXALIAS_SYS (wcsncat, wchar_t *, +- (wchar_t *dest, const wchar_t *src, size_t n)); +-_GL_CXXALIASWARN (wcsncat); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsncat +-# if HAVE_RAW_DECL_WCSNCAT +-_GL_WARN_ON_USE (wcsncat, "wcsncat is unportable - " +- "use gnulib module wcsncat for portability"); +-# endif +-#endif +- +- +-/* Compare S1 and S2. */ +-#if @GNULIB_WCSCMP@ +-# if !@HAVE_WCSCMP@ +-_GL_FUNCDECL_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2) +- _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcscmp, int, (const wchar_t *s1, const wchar_t *s2)); +-_GL_CXXALIASWARN (wcscmp); +-#elif defined GNULIB_POSIXCHECK +-# undef wcscmp +-# if HAVE_RAW_DECL_WCSCMP +-_GL_WARN_ON_USE (wcscmp, "wcscmp is unportable - " +- "use gnulib module wcscmp for portability"); +-# endif +-#endif +- +- +-/* Compare no more than N wide characters of S1 and S2. */ +-#if @GNULIB_WCSNCMP@ +-# if !@HAVE_WCSNCMP@ +-_GL_FUNCDECL_SYS (wcsncmp, int, +- (const wchar_t *s1, const wchar_t *s2, size_t n) +- _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcsncmp, int, +- (const wchar_t *s1, const wchar_t *s2, size_t n)); +-_GL_CXXALIASWARN (wcsncmp); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsncmp +-# if HAVE_RAW_DECL_WCSNCMP +-_GL_WARN_ON_USE (wcsncmp, "wcsncmp is unportable - " +- "use gnulib module wcsncmp for portability"); +-# endif +-#endif +- +- +-/* Compare S1 and S2, ignoring case. */ +-#if @GNULIB_WCSCASECMP@ +-# if !@HAVE_WCSCASECMP@ +-_GL_FUNCDECL_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2) +- _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcscasecmp, int, (const wchar_t *s1, const wchar_t *s2)); +-_GL_CXXALIASWARN (wcscasecmp); +-#elif defined GNULIB_POSIXCHECK +-# undef wcscasecmp +-# if HAVE_RAW_DECL_WCSCASECMP +-_GL_WARN_ON_USE (wcscasecmp, "wcscasecmp is unportable - " +- "use gnulib module wcscasecmp for portability"); +-# endif +-#endif +- +- +-/* Compare no more than N chars of S1 and S2, ignoring case. */ +-#if @GNULIB_WCSNCASECMP@ +-# if !@HAVE_WCSNCASECMP@ +-_GL_FUNCDECL_SYS (wcsncasecmp, int, +- (const wchar_t *s1, const wchar_t *s2, size_t n) +- _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcsncasecmp, int, +- (const wchar_t *s1, const wchar_t *s2, size_t n)); +-_GL_CXXALIASWARN (wcsncasecmp); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsncasecmp +-# if HAVE_RAW_DECL_WCSNCASECMP +-_GL_WARN_ON_USE (wcsncasecmp, "wcsncasecmp is unportable - " +- "use gnulib module wcsncasecmp for portability"); +-# endif +-#endif +- +- +-/* Compare S1 and S2, both interpreted as appropriate to the LC_COLLATE +- category of the current locale. */ +-#if @GNULIB_WCSCOLL@ +-# if !@HAVE_WCSCOLL@ +-_GL_FUNCDECL_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); +-# endif +-_GL_CXXALIAS_SYS (wcscoll, int, (const wchar_t *s1, const wchar_t *s2)); +-_GL_CXXALIASWARN (wcscoll); +-#elif defined GNULIB_POSIXCHECK +-# undef wcscoll +-# if HAVE_RAW_DECL_WCSCOLL +-_GL_WARN_ON_USE (wcscoll, "wcscoll is unportable - " +- "use gnulib module wcscoll for portability"); +-# endif +-#endif +- +- +-/* Transform S2 into array pointed to by S1 such that if wcscmp is applied +- to two transformed strings the result is the as applying 'wcscoll' to the +- original strings. */ +-#if @GNULIB_WCSXFRM@ +-# if !@HAVE_WCSXFRM@ +-_GL_FUNCDECL_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n)); +-# endif +-_GL_CXXALIAS_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n)); +-_GL_CXXALIASWARN (wcsxfrm); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsxfrm +-# if HAVE_RAW_DECL_WCSXFRM +-_GL_WARN_ON_USE (wcsxfrm, "wcsxfrm is unportable - " +- "use gnulib module wcsxfrm for portability"); +-# endif +-#endif +- +- +-/* Duplicate S, returning an identical malloc'd string. */ +-#if @GNULIB_WCSDUP@ +-# if !@HAVE_WCSDUP@ +-_GL_FUNCDECL_SYS (wcsdup, wchar_t *, (const wchar_t *s)); +-# endif +-_GL_CXXALIAS_SYS (wcsdup, wchar_t *, (const wchar_t *s)); +-_GL_CXXALIASWARN (wcsdup); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsdup +-# if HAVE_RAW_DECL_WCSDUP +-_GL_WARN_ON_USE (wcsdup, "wcsdup is unportable - " +- "use gnulib module wcsdup for portability"); +-# endif +-#endif +- +- +-/* Find the first occurrence of WC in WCS. */ +-#if @GNULIB_WCSCHR@ +-# if !@HAVE_WCSCHR@ +-_GL_FUNCDECL_SYS (wcschr, wchar_t *, (const wchar_t *wcs, wchar_t wc) +- _GL_ATTRIBUTE_PURE); +-# endif +- /* On some systems, this function is defined as an overloaded function: +- extern "C++" { +- const wchar_t * std::wcschr (const wchar_t *, wchar_t); +- wchar_t * std::wcschr (wchar_t *, wchar_t); +- } */ +-_GL_CXXALIAS_SYS_CAST2 (wcschr, +- wchar_t *, (const wchar_t *, wchar_t), +- const wchar_t *, (const wchar_t *, wchar_t)); +-# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ +- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +-_GL_CXXALIASWARN1 (wcschr, wchar_t *, (wchar_t *wcs, wchar_t wc)); +-_GL_CXXALIASWARN1 (wcschr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); +-# else +-_GL_CXXALIASWARN (wcschr); +-# endif +-#elif defined GNULIB_POSIXCHECK +-# undef wcschr +-# if HAVE_RAW_DECL_WCSCHR +-_GL_WARN_ON_USE (wcschr, "wcschr is unportable - " +- "use gnulib module wcschr for portability"); +-# endif +-#endif +- +- +-/* Find the last occurrence of WC in WCS. */ +-#if @GNULIB_WCSRCHR@ +-# if !@HAVE_WCSRCHR@ +-_GL_FUNCDECL_SYS (wcsrchr, wchar_t *, (const wchar_t *wcs, wchar_t wc) +- _GL_ATTRIBUTE_PURE); +-# endif +- /* On some systems, this function is defined as an overloaded function: +- extern "C++" { +- const wchar_t * std::wcsrchr (const wchar_t *, wchar_t); +- wchar_t * std::wcsrchr (wchar_t *, wchar_t); +- } */ +-_GL_CXXALIAS_SYS_CAST2 (wcsrchr, +- wchar_t *, (const wchar_t *, wchar_t), +- const wchar_t *, (const wchar_t *, wchar_t)); +-# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ +- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +-_GL_CXXALIASWARN1 (wcsrchr, wchar_t *, (wchar_t *wcs, wchar_t wc)); +-_GL_CXXALIASWARN1 (wcsrchr, const wchar_t *, (const wchar_t *wcs, wchar_t wc)); +-# else +-_GL_CXXALIASWARN (wcsrchr); +-# endif +-#elif defined GNULIB_POSIXCHECK +-# undef wcsrchr +-# if HAVE_RAW_DECL_WCSRCHR +-_GL_WARN_ON_USE (wcsrchr, "wcsrchr is unportable - " +- "use gnulib module wcsrchr for portability"); +-# endif +-#endif +- +- +-/* Return the length of the initial segmet of WCS which consists entirely +- of wide characters not in REJECT. */ +-#if @GNULIB_WCSCSPN@ +-# if !@HAVE_WCSCSPN@ +-_GL_FUNCDECL_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject) +- _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcscspn, size_t, (const wchar_t *wcs, const wchar_t *reject)); +-_GL_CXXALIASWARN (wcscspn); +-#elif defined GNULIB_POSIXCHECK +-# undef wcscspn +-# if HAVE_RAW_DECL_WCSCSPN +-_GL_WARN_ON_USE (wcscspn, "wcscspn is unportable - " +- "use gnulib module wcscspn for portability"); +-# endif +-#endif +- +- +-/* Return the length of the initial segmet of WCS which consists entirely +- of wide characters in ACCEPT. */ +-#if @GNULIB_WCSSPN@ +-# if !@HAVE_WCSSPN@ +-_GL_FUNCDECL_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept) +- _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcsspn, size_t, (const wchar_t *wcs, const wchar_t *accept)); +-_GL_CXXALIASWARN (wcsspn); +-#elif defined GNULIB_POSIXCHECK +-# undef wcsspn +-# if HAVE_RAW_DECL_WCSSPN +-_GL_WARN_ON_USE (wcsspn, "wcsspn is unportable - " +- "use gnulib module wcsspn for portability"); +-# endif +-#endif +- +- +-/* Find the first occurrence in WCS of any character in ACCEPT. */ +-#if @GNULIB_WCSPBRK@ +-# if !@HAVE_WCSPBRK@ +-_GL_FUNCDECL_SYS (wcspbrk, wchar_t *, +- (const wchar_t *wcs, const wchar_t *accept) +- _GL_ATTRIBUTE_PURE); +-# endif +- /* On some systems, this function is defined as an overloaded function: +- extern "C++" { +- const wchar_t * std::wcspbrk (const wchar_t *, const wchar_t *); +- wchar_t * std::wcspbrk (wchar_t *, const wchar_t *); +- } */ +-_GL_CXXALIAS_SYS_CAST2 (wcspbrk, +- wchar_t *, (const wchar_t *, const wchar_t *), +- const wchar_t *, (const wchar_t *, const wchar_t *)); +-# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ +- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +-_GL_CXXALIASWARN1 (wcspbrk, wchar_t *, +- (wchar_t *wcs, const wchar_t *accept)); +-_GL_CXXALIASWARN1 (wcspbrk, const wchar_t *, +- (const wchar_t *wcs, const wchar_t *accept)); +-# else +-_GL_CXXALIASWARN (wcspbrk); +-# endif +-#elif defined GNULIB_POSIXCHECK +-# undef wcspbrk +-# if HAVE_RAW_DECL_WCSPBRK +-_GL_WARN_ON_USE (wcspbrk, "wcspbrk is unportable - " +- "use gnulib module wcspbrk for portability"); +-# endif +-#endif +- +- +-/* Find the first occurrence of NEEDLE in HAYSTACK. */ +-#if @GNULIB_WCSSTR@ +-# if !@HAVE_WCSSTR@ +-_GL_FUNCDECL_SYS (wcsstr, wchar_t *, +- (const wchar_t *haystack, const wchar_t *needle) +- _GL_ATTRIBUTE_PURE); +-# endif +- /* On some systems, this function is defined as an overloaded function: +- extern "C++" { +- const wchar_t * std::wcsstr (const wchar_t *, const wchar_t *); +- wchar_t * std::wcsstr (wchar_t *, const wchar_t *); +- } */ +-_GL_CXXALIAS_SYS_CAST2 (wcsstr, +- wchar_t *, (const wchar_t *, const wchar_t *), +- const wchar_t *, (const wchar_t *, const wchar_t *)); +-# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \ +- && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) +-_GL_CXXALIASWARN1 (wcsstr, wchar_t *, +- (wchar_t *haystack, const wchar_t *needle)); +-_GL_CXXALIASWARN1 (wcsstr, const wchar_t *, +- (const wchar_t *haystack, const wchar_t *needle)); +-# else +-_GL_CXXALIASWARN (wcsstr); +-# endif +-#elif defined GNULIB_POSIXCHECK +-# undef wcsstr +-# if HAVE_RAW_DECL_WCSSTR +-_GL_WARN_ON_USE (wcsstr, "wcsstr is unportable - " +- "use gnulib module wcsstr for portability"); +-# endif +-#endif +- +- +-/* Divide WCS into tokens separated by characters in DELIM. */ +-#if @GNULIB_WCSTOK@ +-# if !@HAVE_WCSTOK@ +-_GL_FUNCDECL_SYS (wcstok, wchar_t *, +- (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); +-# endif +-_GL_CXXALIAS_SYS (wcstok, wchar_t *, +- (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr)); +-_GL_CXXALIASWARN (wcstok); +-#elif defined GNULIB_POSIXCHECK +-# undef wcstok +-# if HAVE_RAW_DECL_WCSTOK +-_GL_WARN_ON_USE (wcstok, "wcstok is unportable - " +- "use gnulib module wcstok for portability"); +-# endif +-#endif +- +- +-/* Determine number of column positions required for first N wide +- characters (or fewer if S ends before this) in S. */ +-#if @GNULIB_WCSWIDTH@ +-# if @REPLACE_WCSWIDTH@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# undef wcswidth +-# define wcswidth rpl_wcswidth +-# endif +-_GL_FUNCDECL_RPL (wcswidth, int, (const wchar_t *s, size_t n) +- _GL_ATTRIBUTE_PURE); +-_GL_CXXALIAS_RPL (wcswidth, int, (const wchar_t *s, size_t n)); +-# else +-# if !@HAVE_WCSWIDTH@ +-_GL_FUNCDECL_SYS (wcswidth, int, (const wchar_t *s, size_t n) +- _GL_ATTRIBUTE_PURE); +-# endif +-_GL_CXXALIAS_SYS (wcswidth, int, (const wchar_t *s, size_t n)); +-# endif +-_GL_CXXALIASWARN (wcswidth); +-#elif defined GNULIB_POSIXCHECK +-# undef wcswidth +-# if HAVE_RAW_DECL_WCSWIDTH +-_GL_WARN_ON_USE (wcswidth, "wcswidth is unportable - " +- "use gnulib module wcswidth for portability"); +-# endif +-#endif +- +- +-#endif /* _@GUARD_PREFIX@_WCHAR_H */ +-#endif /* _@GUARD_PREFIX@_WCHAR_H */ +-#endif +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/wctype-h.c groff-1.22.3/src/libs/gnulib/lib/wctype-h.c +--- groff-1.22.3.old/src/libs/gnulib/lib/wctype-h.c 2014-11-04 10:38:35.631518921 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/wctype-h.c 1970-01-01 02:00:00.000000000 +0200 +@@ -1,4 +0,0 @@ +-/* Normally this would be wctype.c, but that name's already taken. */ +-#include +-#define _GL_WCTYPE_INLINE _GL_EXTERN_INLINE +-#include "wctype.h" +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/wctype.in.h groff-1.22.3/src/libs/gnulib/lib/wctype.in.h +--- groff-1.22.3.old/src/libs/gnulib/lib/wctype.in.h 2014-11-04 10:38:35.631518921 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/wctype.in.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,523 +0,0 @@ +-/* A substitute for ISO C99 , for platforms that lack it. +- +- Copyright (C) 2006-2014 Free Software Foundation, Inc. +- +- This program is free software; you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 2, or (at your option) +- any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program; if not, see . */ +- +-/* Written by Bruno Haible and Paul Eggert. */ +- +-/* +- * ISO C 99 for platforms that lack it. +- * +- * +- * iswctype, towctrans, towlower, towupper, wctrans, wctype, +- * wctrans_t, and wctype_t are not yet implemented. +- */ +- +-#ifndef _@GUARD_PREFIX@_WCTYPE_H +- +-#if __GNUC__ >= 3 +-@PRAGMA_SYSTEM_HEADER@ +-#endif +-@PRAGMA_COLUMNS@ +- +- +-/* +- * XXX: As soon as groff uses gnulib in a saner way (i.e., only a single +- * `config.h' file for the whole package) this file should be replaced +- * with an unpatched version, not containing the next #include line. +- */ +-#include "../config.h" +- +- +-#if @HAVE_WINT_T@ +-/* Solaris 2.5 has a bug: must be included before . +- Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-# include +-# include +-# include +-# include +-#endif +- +-/* mingw has declarations of towupper and towlower in as +- well . Include in advance to avoid rpl_ prefix +- being added to the declarations. */ +-#ifdef __MINGW32__ +-# include +-#endif +- +-/* Include the original if it exists. +- BeOS 5 has the functions but no . */ +-/* The include_next requires a split double-inclusion guard. */ +-#if @HAVE_WCTYPE_H@ +-# @INCLUDE_NEXT@ @NEXT_WCTYPE_H@ +-#endif +- +-#ifndef _@GUARD_PREFIX@_WCTYPE_H +-#define _@GUARD_PREFIX@_WCTYPE_H +- +-#ifndef _GL_INLINE_HEADER_BEGIN +- #error "Please include config.h first." +-#endif +-_GL_INLINE_HEADER_BEGIN +-#ifndef _GL_WCTYPE_INLINE +-# define _GL_WCTYPE_INLINE _GL_INLINE +-#endif +- +-/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ +- +-/* The definition of _GL_WARN_ON_USE is copied here. */ +- +-/* Solaris 2.6 includes which includes which +- #defines a number of identifiers in the application namespace. Revert +- these #defines. */ +-#ifdef __sun +-# undef multibyte +-# undef eucw1 +-# undef eucw2 +-# undef eucw3 +-# undef scrw1 +-# undef scrw2 +-# undef scrw3 +-#endif +- +-/* Define wint_t and WEOF. (Also done in wchar.in.h.) */ +-#if !@HAVE_WINT_T@ && !defined wint_t +-# define wint_t int +-# ifndef WEOF +-# define WEOF -1 +-# endif +-#else +-/* MSVC defines wint_t as 'unsigned short' in . +- This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be +- "unchanged by default argument promotions". Override it. */ +-# if defined _MSC_VER +-# if !GNULIB_defined_wint_t +-# include +-typedef unsigned int rpl_wint_t; +-# undef wint_t +-# define wint_t rpl_wint_t +-# define GNULIB_defined_wint_t 1 +-# endif +-# endif +-# ifndef WEOF +-# define WEOF ((wint_t) -1) +-# endif +-#endif +- +- +-#if !GNULIB_defined_wctype_functions +- +-/* FreeBSD 4.4 to 4.11 has but lacks the functions. +- Linux libc5 has and the functions but they are broken. +- Assume all 11 functions (all isw* except iswblank) are implemented the +- same way, or not at all. */ +-# if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@ +- +-/* IRIX 5.3 has macros but no functions, its isw* macros refer to an +- undefined variable _ctmp_ and to macros like _P, and they +- refer to system functions like _iswctype that are not in the +- standard C library. Rather than try to get ancient buggy +- implementations like this to work, just disable them. */ +-# undef iswalnum +-# undef iswalpha +-# undef iswblank +-# undef iswcntrl +-# undef iswdigit +-# undef iswgraph +-# undef iswlower +-# undef iswprint +-# undef iswpunct +-# undef iswspace +-# undef iswupper +-# undef iswxdigit +-# undef towlower +-# undef towupper +- +-/* Linux libc5 has and the functions but they are broken. */ +-# if @REPLACE_ISWCNTRL@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define iswalnum rpl_iswalnum +-# define iswalpha rpl_iswalpha +-# define iswblank rpl_iswblank +-# define iswcntrl rpl_iswcntrl +-# define iswdigit rpl_iswdigit +-# define iswgraph rpl_iswgraph +-# define iswlower rpl_iswlower +-# define iswprint rpl_iswprint +-# define iswpunct rpl_iswpunct +-# define iswspace rpl_iswspace +-# define iswupper rpl_iswupper +-# define iswxdigit rpl_iswxdigit +-# endif +-# endif +-# if @REPLACE_TOWLOWER@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define towlower rpl_towlower +-# define towupper rpl_towupper +-# endif +-# endif +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswalnum +-# else +-iswalnum +-# endif +- (wint_t wc) +-{ +- return ((wc >= '0' && wc <= '9') +- || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')); +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswalpha +-# else +-iswalpha +-# endif +- (wint_t wc) +-{ +- return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'; +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswblank +-# else +-iswblank +-# endif +- (wint_t wc) +-{ +- return wc == ' ' || wc == '\t'; +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswcntrl +-# else +-iswcntrl +-# endif +- (wint_t wc) +-{ +- return (wc & ~0x1f) == 0 || wc == 0x7f; +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswdigit +-# else +-iswdigit +-# endif +- (wint_t wc) +-{ +- return wc >= '0' && wc <= '9'; +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswgraph +-# else +-iswgraph +-# endif +- (wint_t wc) +-{ +- return wc >= '!' && wc <= '~'; +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswlower +-# else +-iswlower +-# endif +- (wint_t wc) +-{ +- return wc >= 'a' && wc <= 'z'; +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswprint +-# else +-iswprint +-# endif +- (wint_t wc) +-{ +- return wc >= ' ' && wc <= '~'; +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswpunct +-# else +-iswpunct +-# endif +- (wint_t wc) +-{ +- return (wc >= '!' && wc <= '~' +- && !((wc >= '0' && wc <= '9') +- || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'))); +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswspace +-# else +-iswspace +-# endif +- (wint_t wc) +-{ +- return (wc == ' ' || wc == '\t' +- || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r'); +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswupper +-# else +-iswupper +-# endif +- (wint_t wc) +-{ +- return wc >= 'A' && wc <= 'Z'; +-} +- +-_GL_WCTYPE_INLINE int +-# if @REPLACE_ISWCNTRL@ +-rpl_iswxdigit +-# else +-iswxdigit +-# endif +- (wint_t wc) +-{ +- return ((wc >= '0' && wc <= '9') +- || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F')); +-} +- +-_GL_WCTYPE_INLINE wint_t +-# if @REPLACE_TOWLOWER@ +-rpl_towlower +-# else +-towlower +-# endif +- (wint_t wc) +-{ +- return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc); +-} +- +-_GL_WCTYPE_INLINE wint_t +-# if @REPLACE_TOWLOWER@ +-rpl_towupper +-# else +-towupper +-# endif +- (wint_t wc) +-{ +- return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc); +-} +- +-# elif @GNULIB_ISWBLANK@ && (! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@) +-/* Only the iswblank function is missing. */ +- +-# if @REPLACE_ISWBLANK@ +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define iswblank rpl_iswblank +-# endif +-_GL_FUNCDECL_RPL (iswblank, int, (wint_t wc)); +-# else +-_GL_FUNCDECL_SYS (iswblank, int, (wint_t wc)); +-# endif +- +-# endif +- +-# if defined __MINGW32__ +- +-/* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t. +- The functions towlower and towupper are implemented in the MSVCRT library +- to take a wchar_t argument and return a wchar_t result. mingw declares +- these functions to take a wint_t argument and return a wint_t result. +- This means that: +- 1. When the user passes an argument outside the range 0x0000..0xFFFF, the +- function will look only at the lower 16 bits. This is allowed according +- to POSIX. +- 2. The return value is returned in the lower 16 bits of the result register. +- The upper 16 bits are random: whatever happened to be in that part of the +- result register. We need to fix this by adding a zero-extend from +- wchar_t to wint_t after the call. */ +- +-_GL_WCTYPE_INLINE wint_t +-rpl_towlower (wint_t wc) +-{ +- return (wint_t) (wchar_t) towlower (wc); +-} +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define towlower rpl_towlower +-# endif +- +-_GL_WCTYPE_INLINE wint_t +-rpl_towupper (wint_t wc) +-{ +- return (wint_t) (wchar_t) towupper (wc); +-} +-# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +-# define towupper rpl_towupper +-# endif +- +-# endif /* __MINGW32__ */ +- +-# define GNULIB_defined_wctype_functions 1 +-#endif +- +-#if @REPLACE_ISWCNTRL@ +-_GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc)); +-_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc)); +-#else +-_GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswlower, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswprint, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswspace, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswupper, int, (wint_t wc)); +-_GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc)); +-#endif +-_GL_CXXALIASWARN (iswalnum); +-_GL_CXXALIASWARN (iswalpha); +-_GL_CXXALIASWARN (iswcntrl); +-_GL_CXXALIASWARN (iswdigit); +-_GL_CXXALIASWARN (iswgraph); +-_GL_CXXALIASWARN (iswlower); +-_GL_CXXALIASWARN (iswprint); +-_GL_CXXALIASWARN (iswpunct); +-_GL_CXXALIASWARN (iswspace); +-_GL_CXXALIASWARN (iswupper); +-_GL_CXXALIASWARN (iswxdigit); +- +-#if @GNULIB_ISWBLANK@ +-# if @REPLACE_ISWCNTRL@ || @REPLACE_ISWBLANK@ +-_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc)); +-# else +-_GL_CXXALIAS_SYS (iswblank, int, (wint_t wc)); +-# endif +-_GL_CXXALIASWARN (iswblank); +-#endif +- +-#if !@HAVE_WCTYPE_T@ +-# if !GNULIB_defined_wctype_t +-typedef void * wctype_t; +-# define GNULIB_defined_wctype_t 1 +-# endif +-#endif +- +-/* Get a descriptor for a wide character property. */ +-#if @GNULIB_WCTYPE@ +-# if !@HAVE_WCTYPE_T@ +-_GL_FUNCDECL_SYS (wctype, wctype_t, (const char *name)); +-# endif +-_GL_CXXALIAS_SYS (wctype, wctype_t, (const char *name)); +-_GL_CXXALIASWARN (wctype); +-#elif defined GNULIB_POSIXCHECK +-# undef wctype +-# if HAVE_RAW_DECL_WCTYPE +-_GL_WARN_ON_USE (wctype, "wctype is unportable - " +- "use gnulib module wctype for portability"); +-# endif +-#endif +- +-/* Test whether a wide character has a given property. +- The argument WC must be either a wchar_t value or WEOF. +- The argument DESC must have been returned by the wctype() function. */ +-#if @GNULIB_ISWCTYPE@ +-# if !@HAVE_WCTYPE_T@ +-_GL_FUNCDECL_SYS (iswctype, int, (wint_t wc, wctype_t desc)); +-# endif +-_GL_CXXALIAS_SYS (iswctype, int, (wint_t wc, wctype_t desc)); +-_GL_CXXALIASWARN (iswctype); +-#elif defined GNULIB_POSIXCHECK +-# undef iswctype +-# if HAVE_RAW_DECL_ISWCTYPE +-_GL_WARN_ON_USE (iswctype, "iswctype is unportable - " +- "use gnulib module iswctype for portability"); +-# endif +-#endif +- +-#if @REPLACE_TOWLOWER@ || defined __MINGW32__ +-_GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc)); +-_GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc)); +-#else +-_GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc)); +-_GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc)); +-#endif +-_GL_CXXALIASWARN (towlower); +-_GL_CXXALIASWARN (towupper); +- +-#if !@HAVE_WCTRANS_T@ +-# if !GNULIB_defined_wctrans_t +-typedef void * wctrans_t; +-# define GNULIB_defined_wctrans_t 1 +-# endif +-#endif +- +-/* Get a descriptor for a wide character case conversion. */ +-#if @GNULIB_WCTRANS@ +-# if !@HAVE_WCTRANS_T@ +-_GL_FUNCDECL_SYS (wctrans, wctrans_t, (const char *name)); +-# endif +-_GL_CXXALIAS_SYS (wctrans, wctrans_t, (const char *name)); +-_GL_CXXALIASWARN (wctrans); +-#elif defined GNULIB_POSIXCHECK +-# undef wctrans +-# if HAVE_RAW_DECL_WCTRANS +-_GL_WARN_ON_USE (wctrans, "wctrans is unportable - " +- "use gnulib module wctrans for portability"); +-# endif +-#endif +- +-/* Perform a given case conversion on a wide character. +- The argument WC must be either a wchar_t value or WEOF. +- The argument DESC must have been returned by the wctrans() function. */ +-#if @GNULIB_TOWCTRANS@ +-# if !@HAVE_WCTRANS_T@ +-_GL_FUNCDECL_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); +-# endif +-_GL_CXXALIAS_SYS (towctrans, wint_t, (wint_t wc, wctrans_t desc)); +-_GL_CXXALIASWARN (towctrans); +-#elif defined GNULIB_POSIXCHECK +-# undef towctrans +-# if HAVE_RAW_DECL_TOWCTRANS +-_GL_WARN_ON_USE (towctrans, "towctrans is unportable - " +- "use gnulib module towctrans for portability"); +-# endif +-#endif +- +-_GL_INLINE_HEADER_END +- +-#endif /* _@GUARD_PREFIX@_WCTYPE_H */ +-#endif /* _@GUARD_PREFIX@_WCTYPE_H */ +diff -Nuar groff-1.22.3.old/src/libs/gnulib/lib/wcwidth.c groff-1.22.3/src/libs/gnulib/lib/wcwidth.c +--- groff-1.22.3.old/src/libs/gnulib/lib/wcwidth.c 2014-11-04 10:38:35.631518921 +0200 ++++ groff-1.22.3/src/libs/gnulib/lib/wcwidth.c 1970-01-01 02:00:00.000000000 +0200 +@@ -1,50 +0,0 @@ +-/* Determine the number of screen columns needed for a character. +- Copyright (C) 2006-2007, 2010-2014 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation; either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ +- +-#include +- +-/* Specification. */ +-#include +- +-/* Get iswprint. */ +-#include +- +-#include "localcharset.h" +-#include "streq.h" +-#include "uniwidth.h" +- +-int +-wcwidth (wchar_t wc) +-#undef wcwidth +-{ +- /* In UTF-8 locales, use a Unicode aware width function. */ +- const char *encoding = locale_charset (); +- if (STREQ_OPT (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0 ,0)) +- { +- /* We assume that in a UTF-8 locale, a wide character is the same as a +- Unicode character. */ +- return uc_width (wc, encoding); +- } +- else +- { +- /* Otherwise, fall back to the system's wcwidth function. */ +-#if HAVE_WCWIDTH +- return wcwidth (wc); +-#else +- return wc == 0 ? 0 : iswprint (wc) ? 1 : -1; +-#endif +- } +-} +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/00gnulib.m4 groff-1.22.3/src/libs/gnulib/m4/00gnulib.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/00gnulib.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/00gnulib.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,46 +0,0 @@ +-# 00gnulib.m4 serial 3 +-dnl Copyright (C) 2009-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl This file must be named something that sorts before all other +-dnl gnulib-provided .m4 files. It is needed until such time as we can +-dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE and +-dnl m4_divert semantics. +- +-# Until autoconf 2.63, handling of the diversion stack required m4_init +-# to be called first; but this does not happen with aclocal. Wrapping +-# the entire execution in another layer of the diversion stack fixes this. +-# Worse, prior to autoconf 2.62, m4_wrap depended on the underlying m4 +-# for whether it was FIFO or LIFO; in order to properly balance with +-# m4_init, we need to undo our push just before anything wrapped within +-# the m4_init body. The way to ensure this is to wrap both sides of +-# m4_init with a one-shot macro that does the pop at the right time. +-m4_ifndef([_m4_divert_diversion], +-[m4_divert_push([KILL]) +-m4_define([gl_divert_fixup], [m4_divert_pop()m4_define([$0])]) +-m4_define([m4_init], +- [gl_divert_fixup()]m4_defn([m4_init])[gl_divert_fixup()])]) +- +- +-# AC_DEFUN_ONCE([NAME], VALUE) +-# ---------------------------- +-# Define NAME to expand to VALUE on the first use (whether by direct +-# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses. +-# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier. This +-# definition is slower than the version in Autoconf 2.64, because it +-# can only use interfaces that existed since 2.59; but it achieves the +-# same effect. Quoting is necessary to avoid confusing Automake. +-m4_version_prereq([2.63.263], [], +-[m4_define([AC][_DEFUN_ONCE], +- [AC][_DEFUN([$1], +- [AC_REQUIRE([_gl_DEFUN_ONCE([$1])], +- [m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl +-[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])]) +- +-# gl_00GNULIB +-# ----------- +-# Witness macro that this file has been included. Needed to force +-# Automake to include this file prior to all other gnulib .m4 files. +-AC_DEFUN([gl_00GNULIB]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/codeset.m4 groff-1.22.3/src/libs/gnulib/m4/codeset.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/codeset.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/codeset.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,23 +0,0 @@ +-# codeset.m4 serial 5 (gettext-0.18.2) +-dnl Copyright (C) 2000-2002, 2006, 2008-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Bruno Haible. +- +-AC_DEFUN([AM_LANGINFO_CODESET], +-[ +- AC_CACHE_CHECK([for nl_langinfo and CODESET], [am_cv_langinfo_codeset], +- [AC_LINK_IFELSE( +- [AC_LANG_PROGRAM( +- [[#include ]], +- [[char* cs = nl_langinfo(CODESET); return !cs;]])], +- [am_cv_langinfo_codeset=yes], +- [am_cv_langinfo_codeset=no]) +- ]) +- if test $am_cv_langinfo_codeset = yes; then +- AC_DEFINE([HAVE_LANGINFO_CODESET], [1], +- [Define if you have and nl_langinfo(CODESET).]) +- fi +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/configmake.m4 groff-1.22.3/src/libs/gnulib/m4/configmake.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/configmake.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/configmake.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,55 +0,0 @@ +-# configmake.m4 serial 2 +-dnl Copyright (C) 2010-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-# gl_CONFIGMAKE_PREP +-# ------------------ +-# Guarantee all of the standard directory variables, even when used with +-# autoconf 2.59 (datarootdir wasn't supported until 2.59c, and runstatedir +-# in 2.70) or automake 1.9.6 (pkglibexecdir wasn't supported until 1.10b, +-# and runstatedir in 1.14.1). +-AC_DEFUN([gl_CONFIGMAKE_PREP], +-[ +- dnl Technically, datadir should default to datarootdir. But if +- dnl autoconf is too old to provide datarootdir, then reversing the +- dnl definition is a reasonable compromise. Only AC_SUBST a variable +- dnl if it was not already defined earlier by autoconf. +- if test "x$datarootdir" = x; then +- AC_SUBST([datarootdir], ['${datadir}']) +- fi +- dnl Copy the approach used in autoconf 2.60. +- if test "x$docdir" = x; then +- AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME], +- ['${datarootdir}/doc/${PACKAGE_TARNAME}'], +- ['${datarootdir}/doc/${PACKAGE}'])]) +- fi +- dnl The remaining variables missing from autoconf 2.59 are easier. +- if test "x$htmldir" = x; then +- AC_SUBST([htmldir], ['${docdir}']) +- fi +- if test "x$dvidir" = x; then +- AC_SUBST([dvidir], ['${docdir}']) +- fi +- if test "x$pdfdir" = x; then +- AC_SUBST([pdfdir], ['${docdir}']) +- fi +- if test "x$psdir" = x; then +- AC_SUBST([psdir], ['${docdir}']) +- fi +- if test "x$lispdir" = x; then +- AC_SUBST([lispdir], ['${datarootdir}/emacs/site-lisp']) +- fi +- if test "x$localedir" = x; then +- AC_SUBST([localedir], ['${datarootdir}/locale']) +- fi +- dnl Added in autoconf 2.70 +- if test "x$runstatedir" = x; then +- AC_SUBST([runstatedir], ['${localstatedir}/run']) +- fi +- +- dnl Automake 1.9.6 only lacks pkglibexecdir; and since 1.11 merely +- dnl provides it without AC_SUBST, this blind use of AC_SUBST is safe. +- AC_SUBST([pkglibexecdir], ['${libexecdir}/${PACKAGE}']) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/extensions.m4 groff-1.22.3/src/libs/gnulib/m4/extensions.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/extensions.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/extensions.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,138 +0,0 @@ +-# serial 13 -*- Autoconf -*- +-# Enable extensions on systems that normally disable them. +- +-# Copyright (C) 2003, 2006-2014 Free Software Foundation, Inc. +-# This file is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from git +-# Autoconf. Perhaps we can remove this once we can assume Autoconf +-# 2.70 or later everywhere, but since Autoconf mutates rapidly +-# enough in this area it's likely we'll need to redefine +-# AC_USE_SYSTEM_EXTENSIONS for quite some time. +- +-# If autoconf reports a warning +-# warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS +-# or warning: AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS +-# the fix is +-# 1) to ensure that AC_USE_SYSTEM_EXTENSIONS is never directly invoked +-# but always AC_REQUIREd, +-# 2) to ensure that for each occurrence of +-# AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +-# or +-# AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) +-# the corresponding gnulib module description has 'extensions' among +-# its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS +-# invocation occurs in gl_EARLY, not in gl_INIT. +- +-# AC_USE_SYSTEM_EXTENSIONS +-# ------------------------ +-# Enable extensions on systems that normally disable them, +-# typically due to standards-conformance issues. +-# +-# Remember that #undef in AH_VERBATIM gets replaced with #define by +-# AC_DEFINE. The goal here is to define all known feature-enabling +-# macros, then, if reports of conflicts are made, disable macros that +-# cause problems on some platforms (such as __EXTENSIONS__). +-AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS], +-[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +-AC_BEFORE([$0], [AC_RUN_IFELSE])dnl +- +- AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=]) +- if test "$MINIX" = yes; then +- AC_DEFINE([_POSIX_SOURCE], [1], +- [Define to 1 if you need to in order for 'stat' and other +- things to work.]) +- AC_DEFINE([_POSIX_1_SOURCE], [2], +- [Define to 2 if the system does not provide POSIX.1 features +- except with this defined.]) +- AC_DEFINE([_MINIX], [1], +- [Define to 1 if on MINIX.]) +- AC_DEFINE([_NETBSD_SOURCE], [1], +- [Define to 1 to make NetBSD features available. MINIX 3 needs this.]) +- fi +- +-dnl Use a different key than __EXTENSIONS__, as that name broke existing +-dnl configure.ac when using autoheader 2.62. +- AH_VERBATIM([USE_SYSTEM_EXTENSIONS], +-[/* Enable extensions on AIX 3, Interix. */ +-#ifndef _ALL_SOURCE +-# undef _ALL_SOURCE +-#endif +-/* Enable general extensions on OS X. */ +-#ifndef _DARWIN_C_SOURCE +-# undef _DARWIN_C_SOURCE +-#endif +-/* Enable GNU extensions on systems that have them. */ +-#ifndef _GNU_SOURCE +-# undef _GNU_SOURCE +-#endif +-/* Enable threading extensions on Solaris. */ +-#ifndef _POSIX_PTHREAD_SEMANTICS +-# undef _POSIX_PTHREAD_SEMANTICS +-#endif +-/* Enable extensions on HP NonStop. */ +-#ifndef _TANDEM_SOURCE +-# undef _TANDEM_SOURCE +-#endif +-/* Enable X/Open extensions if necessary. HP-UX 11.11 defines +- mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of +- whether compiling with -Ae or -D_HPUX_SOURCE=1. */ +-#ifndef _XOPEN_SOURCE +-# undef _XOPEN_SOURCE +-#endif +-/* Enable general extensions on Solaris. */ +-#ifndef __EXTENSIONS__ +-# undef __EXTENSIONS__ +-#endif +-]) +- AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], +- [ac_cv_safe_to_define___extensions__], +- [AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM([[ +-# define __EXTENSIONS__ 1 +- ]AC_INCLUDES_DEFAULT])], +- [ac_cv_safe_to_define___extensions__=yes], +- [ac_cv_safe_to_define___extensions__=no])]) +- test $ac_cv_safe_to_define___extensions__ = yes && +- AC_DEFINE([__EXTENSIONS__]) +- AC_DEFINE([_ALL_SOURCE]) +- AC_DEFINE([_DARWIN_C_SOURCE]) +- AC_DEFINE([_GNU_SOURCE]) +- AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) +- AC_DEFINE([_TANDEM_SOURCE]) +- AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined], +- [ac_cv_should_define__xopen_source], +- [ac_cv_should_define__xopen_source=no +- AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM([[ +- #include +- mbstate_t x;]])], +- [], +- [AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM([[ +- #define _XOPEN_SOURCE 500 +- #include +- mbstate_t x;]])], +- [ac_cv_should_define__xopen_source=yes])])]) +- test $ac_cv_should_define__xopen_source = yes && +- AC_DEFINE([_XOPEN_SOURCE], [500]) +-])# AC_USE_SYSTEM_EXTENSIONS +- +-# gl_USE_SYSTEM_EXTENSIONS +-# ------------------------ +-# Enable extensions on systems that normally disable them, +-# typically due to standards-conformance issues. +-AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS], +-[ +- dnl Require this macro before AC_USE_SYSTEM_EXTENSIONS. +- dnl gnulib does not need it. But if it gets required by third-party macros +- dnl after AC_USE_SYSTEM_EXTENSIONS is required, autoconf 2.62..2.63 emit a +- dnl warning: "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS". +- dnl Note: We can do this only for one of the macros AC_AIX, AC_GNU_SOURCE, +- dnl AC_MINIX. If people still use AC_AIX or AC_MINIX, they are out of luck. +- AC_REQUIRE([AC_GNU_SOURCE]) +- +- AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/extern-inline.m4 groff-1.22.3/src/libs/gnulib/m4/extern-inline.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/extern-inline.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/extern-inline.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,62 +0,0 @@ +-dnl 'extern inline' a la ISO C99. +- +-dnl Copyright 2012-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-AC_DEFUN([gl_EXTERN_INLINE], +-[ +- AH_VERBATIM([extern_inline], +-[/* _GL_INLINE is a portable alternative to ISO C99 plain 'inline'. +- _GL_EXTERN_INLINE is a portable alternative to 'extern inline'. +- _GL_INLINE_HEADER_BEGIN contains useful stuff to put +- in an include file, before uses of _GL_INLINE. +- It suppresses GCC's bogus "no previous prototype for 'FOO'" diagnostic, +- when FOO is an inline function in the header; see +- . +- _GL_INLINE_HEADER_END contains useful stuff to put +- in the same include file, after uses of _GL_INLINE. +- +- Suppress the use of extern inline on Apple's platforms, +- as Libc-825.25 (2012-09-19) is incompatible with it; see +- . +- Perhaps Apple will fix this some day. */ +-#if ((__GNUC__ \ +- ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \ +- : 199901L <= __STDC_VERSION__) \ +- && !defined __APPLE__) +-# define _GL_INLINE inline +-# define _GL_EXTERN_INLINE extern inline +-#elif 2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __APPLE__ +-# if __GNUC_GNU_INLINE__ +- /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */ +-# define _GL_INLINE extern inline __attribute__ ((__gnu_inline__)) +-# else +-# define _GL_INLINE extern inline +-# endif +-# define _GL_EXTERN_INLINE extern +-#else +-# define _GL_INLINE static _GL_UNUSED +-# define _GL_EXTERN_INLINE static _GL_UNUSED +-#endif +- +-#if 4 < __GNUC__ + (6 <= __GNUC_MINOR__) +-# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ +-# define _GL_INLINE_HEADER_CONST_PRAGMA +-# else +-# define _GL_INLINE_HEADER_CONST_PRAGMA \ +- _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"") +-# endif +-# define _GL_INLINE_HEADER_BEGIN \ +- _Pragma ("GCC diagnostic push") \ +- _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \ +- _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \ +- _GL_INLINE_HEADER_CONST_PRAGMA +-# define _GL_INLINE_HEADER_END \ +- _Pragma ("GCC diagnostic pop") +-#else +-# define _GL_INLINE_HEADER_BEGIN +-# define _GL_INLINE_HEADER_END +-#endif]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/fcntl-o.m4 groff-1.22.3/src/libs/gnulib/m4/fcntl-o.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/fcntl-o.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/fcntl-o.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,134 +0,0 @@ +-# fcntl-o.m4 serial 4 +-dnl Copyright (C) 2006, 2009-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl Written by Paul Eggert. +- +-# Test whether the flags O_NOATIME and O_NOFOLLOW actually work. +-# Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise. +-# Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise. +-AC_DEFUN([gl_FCNTL_O_FLAGS], +-[ +- dnl Persuade glibc to define O_NOATIME and O_NOFOLLOW. +- dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes +- dnl AC_GNU_SOURCE. +- m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], +- [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])], +- [AC_REQUIRE([AC_GNU_SOURCE])]) +- +- AC_CHECK_HEADERS_ONCE([unistd.h]) +- AC_CHECK_FUNCS_ONCE([symlink]) +- AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h], +- [AC_RUN_IFELSE( +- [AC_LANG_PROGRAM( +- [[#include +- #include +- #if HAVE_UNISTD_H +- # include +- #else /* on Windows with MSVC */ +- # include +- # include +- # defined sleep(n) _sleep ((n) * 1000) +- #endif +- #include +- #ifndef O_NOATIME +- #define O_NOATIME 0 +- #endif +- #ifndef O_NOFOLLOW +- #define O_NOFOLLOW 0 +- #endif +- static int const constants[] = +- { +- O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, +- O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY +- }; +- ]], +- [[ +- int result = !constants; +- #if HAVE_SYMLINK +- { +- static char const sym[] = "conftest.sym"; +- if (symlink ("/dev/null", sym) != 0) +- result |= 2; +- else +- { +- int fd = open (sym, O_WRONLY | O_NOFOLLOW | O_CREAT, 0); +- if (fd >= 0) +- { +- close (fd); +- result |= 4; +- } +- } +- if (unlink (sym) != 0 || symlink (".", sym) != 0) +- result |= 2; +- else +- { +- int fd = open (sym, O_RDONLY | O_NOFOLLOW); +- if (fd >= 0) +- { +- close (fd); +- result |= 4; +- } +- } +- unlink (sym); +- } +- #endif +- { +- static char const file[] = "confdefs.h"; +- int fd = open (file, O_RDONLY | O_NOATIME); +- if (fd < 0) +- result |= 8; +- else +- { +- struct stat st0; +- if (fstat (fd, &st0) != 0) +- result |= 16; +- else +- { +- char c; +- sleep (1); +- if (read (fd, &c, 1) != 1) +- result |= 24; +- else +- { +- if (close (fd) != 0) +- result |= 32; +- else +- { +- struct stat st1; +- if (stat (file, &st1) != 0) +- result |= 40; +- else +- if (st0.st_atime != st1.st_atime) +- result |= 64; +- } +- } +- } +- } +- } +- return result;]])], +- [gl_cv_header_working_fcntl_h=yes], +- [case $? in #( +- 4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #( +- 64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #( +- 68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #( +- *) gl_cv_header_working_fcntl_h='no';; +- esac], +- [gl_cv_header_working_fcntl_h=cross-compiling])]) +- +- case $gl_cv_header_working_fcntl_h in #( +- *O_NOATIME* | no | cross-compiling) ac_val=0;; #( +- *) ac_val=1;; +- esac +- AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val], +- [Define to 1 if O_NOATIME works.]) +- +- case $gl_cv_header_working_fcntl_h in #( +- *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #( +- *) ac_val=1;; +- esac +- AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val], +- [Define to 1 if O_NOFOLLOW works.]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/glibc21.m4 groff-1.22.3/src/libs/gnulib/m4/glibc21.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/glibc21.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/glibc21.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,34 +0,0 @@ +-# glibc21.m4 serial 5 +-dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2014 Free Software Foundation, +-dnl Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-# Test for the GNU C Library, version 2.1 or newer, or uClibc. +-# From Bruno Haible. +- +-AC_DEFUN([gl_GLIBC21], +- [ +- AC_CACHE_CHECK([whether we are using the GNU C Library >= 2.1 or uClibc], +- [ac_cv_gnu_library_2_1], +- [AC_EGREP_CPP([Lucky], +- [ +-#include +-#ifdef __GNU_LIBRARY__ +- #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) +- Lucky GNU user +- #endif +-#endif +-#ifdef __UCLIBC__ +- Lucky user +-#endif +- ], +- [ac_cv_gnu_library_2_1=yes], +- [ac_cv_gnu_library_2_1=no]) +- ] +- ) +- AC_SUBST([GLIBC21]) +- GLIBC21="$ac_cv_gnu_library_2_1" +- ] +-) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/gnulib-cache.m4 groff-1.22.3/src/libs/gnulib/m4/gnulib-cache.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/gnulib-cache.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/gnulib-cache.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,47 +0,0 @@ +-# Copyright (C) 2002-2014 Free Software Foundation, Inc. +-# +-# This file is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 3 of the License, or +-# (at your option) any later version. +-# +-# This file is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this file. If not, see . +-# +-# As a special exception to the GNU General Public License, +-# this file may be distributed as part of a program that +-# contains a configuration script generated by Autoconf, under +-# the same distribution terms as the rest of that program. +-# +-# Generated by gnulib-tool. +-# +-# This file represents the specification of how gnulib-tool is used. +-# It acts as a cache: It is written and read by gnulib-tool. +-# In projects that use version control, this file is meant to be put under +-# version control, like the configure.ac and various Makefile.am files. +- +- +-# Specification in the form of a command-line invocation: +-# gnulib-tool --import --dir=src/libs/gnulib --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl wcwidth +- +-# Specification in the form of a few gnulib-tool.m4 macro invocations: +-gl_LOCAL_DIR([]) +-gl_MODULES([ +- wcwidth +-]) +-gl_AVOID([]) +-gl_SOURCE_BASE([lib]) +-gl_M4_BASE([m4]) +-gl_PO_BASE([]) +-gl_DOC_BASE([doc]) +-gl_TESTS_BASE([tests]) +-gl_LIB([libgnu]) +-gl_MAKEFILE_NAME([]) +-gl_MACRO_PREFIX([gl]) +-gl_PO_DOMAIN([]) +-gl_WITNESS_C_MACRO([]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/gnulib-common.m4 groff-1.22.3/src/libs/gnulib/m4/gnulib-common.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/gnulib-common.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/gnulib-common.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,377 +0,0 @@ +-# gnulib-common.m4 serial 33 +-dnl Copyright (C) 2007-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-# gl_COMMON +-# is expanded unconditionally through gnulib-tool magic. +-AC_DEFUN([gl_COMMON], [ +- dnl Use AC_REQUIRE here, so that the code is expanded once only. +- AC_REQUIRE([gl_00GNULIB]) +- AC_REQUIRE([gl_COMMON_BODY]) +-]) +-AC_DEFUN([gl_COMMON_BODY], [ +- AH_VERBATIM([_Noreturn], +-[/* The _Noreturn keyword of C11. */ +-#if ! (defined _Noreturn \ +- || (defined __STDC_VERSION__ && 201112 <= __STDC_VERSION__)) +-# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ +- || 0x5110 <= __SUNPRO_C) +-# define _Noreturn __attribute__ ((__noreturn__)) +-# elif defined _MSC_VER && 1200 <= _MSC_VER +-# define _Noreturn __declspec (noreturn) +-# else +-# define _Noreturn +-# endif +-#endif +-]) +- AH_VERBATIM([isoc99_inline], +-[/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports +- the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of +- earlier versions), but does not display it by setting __GNUC_STDC_INLINE__. +- __APPLE__ && __MACH__ test for Mac OS X. +- __APPLE_CC__ tests for the Apple compiler and its version. +- __STDC_VERSION__ tests for the C99 mode. */ +-#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__ +-# define __GNUC_STDC_INLINE__ 1 +-#endif]) +- AH_VERBATIM([unused_parameter], +-[/* Define as a marker that can be attached to declarations that might not +- be used. This helps to reduce warnings, such as from +- GCC -Wunused-parameter. */ +-#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +-# define _GL_UNUSED __attribute__ ((__unused__)) +-#else +-# define _GL_UNUSED +-#endif +-/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name +- is a misnomer outside of parameter lists. */ +-#define _UNUSED_PARAMETER_ _GL_UNUSED +- +-/* The __pure__ attribute was added in gcc 2.96. */ +-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +-# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +-#else +-# define _GL_ATTRIBUTE_PURE /* empty */ +-#endif +- +-/* The __const__ attribute was added in gcc 2.95. */ +-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +-# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) +-#else +-# define _GL_ATTRIBUTE_CONST /* empty */ +-#endif +-]) +- dnl Preparation for running test programs: +- dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not +- dnl to /dev/tty, so they can be redirected to log files. Such diagnostics +- dnl arise e.g., in the macros gl_PRINTF_DIRECTIVE_N, gl_SNPRINTF_DIRECTIVE_N. +- LIBC_FATAL_STDERR_=1 +- export LIBC_FATAL_STDERR_ +-]) +- +-# gl_MODULE_INDICATOR_CONDITION +-# expands to a C preprocessor expression that evaluates to 1 or 0, depending +-# whether a gnulib module that has been requested shall be considered present +-# or not. +-m4_define([gl_MODULE_INDICATOR_CONDITION], [1]) +- +-# gl_MODULE_INDICATOR_SET_VARIABLE([modulename]) +-# sets the shell variable that indicates the presence of the given module to +-# a C preprocessor expression that will evaluate to 1. +-AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE], +-[ +- gl_MODULE_INDICATOR_SET_VARIABLE_AUX( +- [GNULIB_[]m4_translit([[$1]], +- [abcdefghijklmnopqrstuvwxyz./-], +- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])], +- [gl_MODULE_INDICATOR_CONDITION]) +-]) +- +-# gl_MODULE_INDICATOR_SET_VARIABLE_AUX([variable]) +-# modifies the shell variable to include the gl_MODULE_INDICATOR_CONDITION. +-# The shell variable's value is a C preprocessor expression that evaluates +-# to 0 or 1. +-AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX], +-[ +- m4_if(m4_defn([gl_MODULE_INDICATOR_CONDITION]), [1], +- [ +- dnl Simplify the expression VALUE || 1 to 1. +- $1=1 +- ], +- [gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([$1], +- [gl_MODULE_INDICATOR_CONDITION])]) +-]) +- +-# gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([variable], [condition]) +-# modifies the shell variable to include the given condition. The shell +-# variable's value is a C preprocessor expression that evaluates to 0 or 1. +-AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR], +-[ +- dnl Simplify the expression 1 || CONDITION to 1. +- if test "$[]$1" != 1; then +- dnl Simplify the expression 0 || CONDITION to CONDITION. +- if test "$[]$1" = 0; then +- $1=$2 +- else +- $1="($[]$1 || $2)" +- fi +- fi +-]) +- +-# gl_MODULE_INDICATOR([modulename]) +-# defines a C macro indicating the presence of the given module +-# in a location where it can be used. +-# | Value | Value | +-# | in lib/ | in tests/ | +-# --------------------------------------------+---------+-----------+ +-# Module present among main modules: | 1 | 1 | +-# --------------------------------------------+---------+-----------+ +-# Module present among tests-related modules: | 0 | 1 | +-# --------------------------------------------+---------+-----------+ +-# Module not present at all: | 0 | 0 | +-# --------------------------------------------+---------+-----------+ +-AC_DEFUN([gl_MODULE_INDICATOR], +-[ +- AC_DEFINE_UNQUOTED([GNULIB_]m4_translit([[$1]], +- [abcdefghijklmnopqrstuvwxyz./-], +- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), +- [gl_MODULE_INDICATOR_CONDITION], +- [Define to a C preprocessor expression that evaluates to 1 or 0, +- depending whether the gnulib module $1 shall be considered present.]) +-]) +- +-# gl_MODULE_INDICATOR_FOR_TESTS([modulename]) +-# defines a C macro indicating the presence of the given module +-# in lib or tests. This is useful to determine whether the module +-# should be tested. +-# | Value | Value | +-# | in lib/ | in tests/ | +-# --------------------------------------------+---------+-----------+ +-# Module present among main modules: | 1 | 1 | +-# --------------------------------------------+---------+-----------+ +-# Module present among tests-related modules: | 1 | 1 | +-# --------------------------------------------+---------+-----------+ +-# Module not present at all: | 0 | 0 | +-# --------------------------------------------+---------+-----------+ +-AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], +-[ +- AC_DEFINE([GNULIB_TEST_]m4_translit([[$1]], +- [abcdefghijklmnopqrstuvwxyz./-], +- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), [1], +- [Define to 1 when the gnulib module $1 should be tested.]) +-]) +- +-# gl_ASSERT_NO_GNULIB_POSIXCHECK +-# asserts that there will never be a need to #define GNULIB_POSIXCHECK. +-# and thereby enables an optimization of configure and config.h. +-# Used by Emacs. +-AC_DEFUN([gl_ASSERT_NO_GNULIB_POSIXCHECK], +-[ +- dnl Override gl_WARN_ON_USE_PREPARE. +- dnl But hide this definition from 'aclocal'. +- AC_DEFUN([gl_W][ARN_ON_USE_PREPARE], []) +-]) +- +-# gl_ASSERT_NO_GNULIB_TESTS +-# asserts that there will be no gnulib tests in the scope of the configure.ac +-# and thereby enables an optimization of config.h. +-# Used by Emacs. +-AC_DEFUN([gl_ASSERT_NO_GNULIB_TESTS], +-[ +- dnl Override gl_MODULE_INDICATOR_FOR_TESTS. +- AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], []) +-]) +- +-# Test whether exists. +-# Set HAVE_FEATURES_H. +-AC_DEFUN([gl_FEATURES_H], +-[ +- AC_CHECK_HEADERS_ONCE([features.h]) +- if test $ac_cv_header_features_h = yes; then +- HAVE_FEATURES_H=1 +- else +- HAVE_FEATURES_H=0 +- fi +- AC_SUBST([HAVE_FEATURES_H]) +-]) +- +-# m4_foreach_w +-# is a backport of autoconf-2.59c's m4_foreach_w. +-# Remove this macro when we can assume autoconf >= 2.60. +-m4_ifndef([m4_foreach_w], +- [m4_define([m4_foreach_w], +- [m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])]) +- +-# AS_VAR_IF(VAR, VALUE, [IF-MATCH], [IF-NOT-MATCH]) +-# ---------------------------------------------------- +-# Backport of autoconf-2.63b's macro. +-# Remove this macro when we can assume autoconf >= 2.64. +-m4_ifndef([AS_VAR_IF], +-[m4_define([AS_VAR_IF], +-[AS_IF([test x"AS_VAR_GET([$1])" = x""$2], [$3], [$4])])]) +- +-# gl_PROG_CC_C99 +-# Modifies the value of the shell variable CC in an attempt to make $CC +-# understand ISO C99 source code. +-# This is like AC_PROG_CC_C99, except that +-# - AC_PROG_CC_C99 did not exist in Autoconf versions < 2.60, +-# - AC_PROG_CC_C99 does not mix well with AC_PROG_CC_STDC +-# , +-# but many more packages use AC_PROG_CC_STDC than AC_PROG_CC_C99 +-# . +-# Remaining problems: +-# - When AC_PROG_CC_STDC is invoked twice, it adds the C99 enabling options +-# to CC twice +-# . +-# - AC_PROG_CC_STDC is likely to change now that C11 is an ISO standard. +-AC_DEFUN([gl_PROG_CC_C99], +-[ +- dnl Change that version number to the minimum Autoconf version that supports +- dnl mixing AC_PROG_CC_C99 calls with AC_PROG_CC_STDC calls. +- m4_version_prereq([9.0], +- [AC_REQUIRE([AC_PROG_CC_C99])], +- [AC_REQUIRE([AC_PROG_CC_STDC])]) +-]) +- +-# gl_PROG_AR_RANLIB +-# Determines the values for AR, ARFLAGS, RANLIB that fit with the compiler. +-# The user can set the variables AR, ARFLAGS, RANLIB if he wants to override +-# the values. +-AC_DEFUN([gl_PROG_AR_RANLIB], +-[ +- dnl Minix 3 comes with two toolchains: The Amsterdam Compiler Kit compiler +- dnl as "cc", and GCC as "gcc". They have different object file formats and +- dnl library formats. In particular, the GNU binutils programs ar, ranlib +- dnl produce libraries that work only with gcc, not with cc. +- AC_REQUIRE([AC_PROG_CC]) +- AC_CACHE_CHECK([for Minix Amsterdam compiler], [gl_cv_c_amsterdam_compiler], +- [ +- AC_EGREP_CPP([Amsterdam], +- [ +-#ifdef __ACK__ +-Amsterdam +-#endif +- ], +- [gl_cv_c_amsterdam_compiler=yes], +- [gl_cv_c_amsterdam_compiler=no]) +- ]) +- if test -z "$AR"; then +- if test $gl_cv_c_amsterdam_compiler = yes; then +- AR='cc -c.a' +- if test -z "$ARFLAGS"; then +- ARFLAGS='-o' +- fi +- else +- dnl Use the Automake-documented default values for AR and ARFLAGS, +- dnl but prefer ${host}-ar over ar (useful for cross-compiling). +- AC_CHECK_TOOL([AR], [ar], [ar]) +- if test -z "$ARFLAGS"; then +- ARFLAGS='cru' +- fi +- fi +- else +- if test -z "$ARFLAGS"; then +- ARFLAGS='cru' +- fi +- fi +- AC_SUBST([AR]) +- AC_SUBST([ARFLAGS]) +- if test -z "$RANLIB"; then +- if test $gl_cv_c_amsterdam_compiler = yes; then +- RANLIB=':' +- else +- dnl Use the ranlib program if it is available. +- AC_PROG_RANLIB +- fi +- fi +- AC_SUBST([RANLIB]) +-]) +- +-# AC_PROG_MKDIR_P +-# is a backport of autoconf-2.60's AC_PROG_MKDIR_P, with a fix +-# for interoperability with automake-1.9.6 from autoconf-2.62. +-# Remove this macro when we can assume autoconf >= 2.62 or +-# autoconf >= 2.60 && automake >= 1.10. +-# AC_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness. +-m4_ifndef([AC_AUTOCONF_VERSION],[ +-m4_ifdef([AC_PROG_MKDIR_P], [ +- dnl For automake-1.9.6 && autoconf < 2.62: Ensure MKDIR_P is AC_SUBSTed. +- m4_define([AC_PROG_MKDIR_P], +- m4_defn([AC_PROG_MKDIR_P])[ +- AC_SUBST([MKDIR_P])])], [ +- dnl For autoconf < 2.60: Backport of AC_PROG_MKDIR_P. +- AC_DEFUN_ONCE([AC_PROG_MKDIR_P], +- [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake +- MKDIR_P='$(mkdir_p)' +- AC_SUBST([MKDIR_P])])]) +-]) +- +-# AC_C_RESTRICT +-# This definition overrides the AC_C_RESTRICT macro from autoconf 2.60..2.61, +-# so that mixed use of GNU C and GNU C++ and mixed use of Sun C and Sun C++ +-# works. +-# This definition can be removed once autoconf >= 2.62 can be assumed. +-# AC_AUTOCONF_VERSION was introduced in 2.62, so use that as the witness. +-m4_ifndef([AC_AUTOCONF_VERSION],[ +-AC_DEFUN([AC_C_RESTRICT], +-[AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict], +- [ac_cv_c_restrict=no +- # The order here caters to the fact that C++ does not require restrict. +- for ac_kw in __restrict __restrict__ _Restrict restrict; do +- AC_COMPILE_IFELSE([AC_LANG_PROGRAM( +- [[typedef int * int_ptr; +- int foo (int_ptr $ac_kw ip) { +- return ip[0]; +- }]], +- [[int s[1]; +- int * $ac_kw t = s; +- t[0] = 0; +- return foo(t)]])], +- [ac_cv_c_restrict=$ac_kw]) +- test "$ac_cv_c_restrict" != no && break +- done +- ]) +- AH_VERBATIM([restrict], +-[/* Define to the equivalent of the C99 'restrict' keyword, or to +- nothing if this is not supported. Do not define if restrict is +- supported directly. */ +-#undef restrict +-/* Work around a bug in Sun C++: it does not support _Restrict, even +- though the corresponding Sun C compiler does, which causes +- "#define restrict _Restrict" in the previous line. Perhaps some future +- version of Sun C++ will work with _Restrict; if so, it'll probably +- define __RESTRICT, just as Sun C does. */ +-#if defined __SUNPRO_CC && !defined __RESTRICT +-# define _Restrict +-#endif]) +- case $ac_cv_c_restrict in +- restrict) ;; +- no) AC_DEFINE([restrict], []) ;; +- *) AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;; +- esac +-]) +-]) +- +-# gl_BIGENDIAN +-# is like AC_C_BIGENDIAN, except that it can be AC_REQUIREd. +-# Note that AC_REQUIRE([AC_C_BIGENDIAN]) does not work reliably because some +-# macros invoke AC_C_BIGENDIAN with arguments. +-AC_DEFUN([gl_BIGENDIAN], +-[ +- AC_C_BIGENDIAN +-]) +- +-# gl_CACHE_VAL_SILENT(cache-id, command-to-set-it) +-# is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not +-# output a spurious "(cached)" mark in the midst of other configure output. +-# This macro should be used instead of AC_CACHE_VAL when it is not surrounded +-# by an AC_MSG_CHECKING/AC_MSG_RESULT pair. +-AC_DEFUN([gl_CACHE_VAL_SILENT], +-[ +- saved_as_echo_n="$as_echo_n" +- as_echo_n=':' +- AC_CACHE_VAL([$1], [$2]) +- as_echo_n="$saved_as_echo_n" +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/gnulib-comp.m4 groff-1.22.3/src/libs/gnulib/m4/gnulib-comp.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/gnulib-comp.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/gnulib-comp.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,278 +0,0 @@ +-# DO NOT EDIT! GENERATED AUTOMATICALLY! +-# Copyright (C) 2002-2014 Free Software Foundation, Inc. +-# +-# This file is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 3 of the License, or +-# (at your option) any later version. +-# +-# This file is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this file. If not, see . +-# +-# As a special exception to the GNU General Public License, +-# this file may be distributed as part of a program that +-# contains a configuration script generated by Autoconf, under +-# the same distribution terms as the rest of that program. +-# +-# Generated by gnulib-tool. +-# +-# This file represents the compiled summary of the specification in +-# gnulib-cache.m4. It lists the computed macro invocations that need +-# to be invoked from configure.ac. +-# In projects that use version control, this file can be treated like +-# other built files. +- +- +-# This macro should be invoked from src/libs/gnulib/configure.ac, in the section +-# "Checks for programs", right after AC_PROG_CC, and certainly before +-# any checks for libraries, header files, types and library functions. +-AC_DEFUN([gl_EARLY], +-[ +- m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace +- m4_pattern_allow([^gl_ES$])dnl a valid locale name +- m4_pattern_allow([^gl_LIBOBJS$])dnl a variable +- m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable +- AC_REQUIRE([gl_PROG_AR_RANLIB]) +- AC_REQUIRE([AM_PROG_CC_C_O]) +- # Code from module configmake: +- # Code from module extensions: +- AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) +- # Code from module extern-inline: +- # Code from module include_next: +- # Code from module localcharset: +- # Code from module multiarch: +- # Code from module snippet/arg-nonnull: +- # Code from module snippet/c++defs: +- # Code from module snippet/warn-on-use: +- # Code from module stddef: +- # Code from module stdint: +- # Code from module streq: +- # Code from module unitypes: +- # Code from module uniwidth/base: +- # Code from module uniwidth/width: +- # Code from module wchar: +- # Code from module wctype-h: +- # Code from module wcwidth: +-]) +- +-# This macro should be invoked from src/libs/gnulib/configure.ac, in the section +-# "Check for header files, types and library functions". +-AC_DEFUN([gl_INIT], +-[ +- AM_CONDITIONAL([GL_COND_LIBTOOL], [false]) +- gl_cond_libtool=false +- gl_libdeps= +- gl_ltlibdeps= +- gl_m4_base='m4' +- m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ])) +- m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS])) +- m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES])) +- m4_pushdef([gl_LIBSOURCES_LIST], []) +- m4_pushdef([gl_LIBSOURCES_DIR], []) +- gl_COMMON +- gl_source_base='lib' +- gl_CONFIGMAKE_PREP +- AC_REQUIRE([gl_EXTERN_INLINE]) +- gl_LOCALCHARSET +- LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(abs_top_builddir)/$gl_source_base\"" +- AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT]) +- gl_MULTIARCH +- gl_STDDEF_H +- gl_STDINT_H +- gl_LIBUNISTRING_LIBHEADER([0.9], [unitypes.h]) +- gl_LIBUNISTRING_LIBHEADER([0.9], [uniwidth.h]) +- gl_LIBUNISTRING_MODULE([0.9.4], [uniwidth/width]) +- gl_WCHAR_H +- gl_WCTYPE_H +- gl_FUNC_WCWIDTH +- if test $HAVE_WCWIDTH = 0 || test $REPLACE_WCWIDTH = 1; then +- AC_LIBOBJ([wcwidth]) +- fi +- gl_WCHAR_MODULE_INDICATOR([wcwidth]) +- # End of code from modules +- m4_ifval(gl_LIBSOURCES_LIST, [ +- m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || +- for gl_file in ]gl_LIBSOURCES_LIST[ ; do +- if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then +- echo "missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file" >&2 +- exit 1 +- fi +- done])dnl +- m4_if(m4_sysval, [0], [], +- [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) +- ]) +- m4_popdef([gl_LIBSOURCES_DIR]) +- m4_popdef([gl_LIBSOURCES_LIST]) +- m4_popdef([AC_LIBSOURCES]) +- m4_popdef([AC_REPLACE_FUNCS]) +- m4_popdef([AC_LIBOBJ]) +- AC_CONFIG_COMMANDS_PRE([ +- gl_libobjs= +- gl_ltlibobjs= +- if test -n "$gl_LIBOBJS"; then +- # Remove the extension. +- sed_drop_objext='s/\.o$//;s/\.obj$//' +- for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do +- gl_libobjs="$gl_libobjs $i.$ac_objext" +- gl_ltlibobjs="$gl_ltlibobjs $i.lo" +- done +- fi +- AC_SUBST([gl_LIBOBJS], [$gl_libobjs]) +- AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs]) +- ]) +- gltests_libdeps= +- gltests_ltlibdeps= +- m4_pushdef([AC_LIBOBJ], m4_defn([gltests_LIBOBJ])) +- m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gltests_REPLACE_FUNCS])) +- m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES])) +- m4_pushdef([gltests_LIBSOURCES_LIST], []) +- m4_pushdef([gltests_LIBSOURCES_DIR], []) +- gl_COMMON +- gl_source_base='tests' +-changequote(,)dnl +- gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS +-changequote([, ])dnl +- AC_SUBST([gltests_WITNESS]) +- gl_module_indicator_condition=$gltests_WITNESS +- m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition]) +- m4_popdef([gl_MODULE_INDICATOR_CONDITION]) +- m4_ifval(gltests_LIBSOURCES_LIST, [ +- m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ || +- for gl_file in ]gltests_LIBSOURCES_LIST[ ; do +- if test ! -r ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file ; then +- echo "missing file ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file" >&2 +- exit 1 +- fi +- done])dnl +- m4_if(m4_sysval, [0], [], +- [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) +- ]) +- m4_popdef([gltests_LIBSOURCES_DIR]) +- m4_popdef([gltests_LIBSOURCES_LIST]) +- m4_popdef([AC_LIBSOURCES]) +- m4_popdef([AC_REPLACE_FUNCS]) +- m4_popdef([AC_LIBOBJ]) +- AC_CONFIG_COMMANDS_PRE([ +- gltests_libobjs= +- gltests_ltlibobjs= +- if test -n "$gltests_LIBOBJS"; then +- # Remove the extension. +- sed_drop_objext='s/\.o$//;s/\.obj$//' +- for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do +- gltests_libobjs="$gltests_libobjs $i.$ac_objext" +- gltests_ltlibobjs="$gltests_ltlibobjs $i.lo" +- done +- fi +- AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs]) +- AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs]) +- ]) +- LIBGNU_LIBDEPS="$gl_libdeps" +- AC_SUBST([LIBGNU_LIBDEPS]) +- LIBGNU_LTLIBDEPS="$gl_ltlibdeps" +- AC_SUBST([LIBGNU_LTLIBDEPS]) +-]) +- +-# Like AC_LIBOBJ, except that the module name goes +-# into gl_LIBOBJS instead of into LIBOBJS. +-AC_DEFUN([gl_LIBOBJ], [ +- AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl +- gl_LIBOBJS="$gl_LIBOBJS $1.$ac_objext" +-]) +- +-# Like AC_REPLACE_FUNCS, except that the module name goes +-# into gl_LIBOBJS instead of into LIBOBJS. +-AC_DEFUN([gl_REPLACE_FUNCS], [ +- m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl +- AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)]) +-]) +- +-# Like AC_LIBSOURCES, except the directory where the source file is +-# expected is derived from the gnulib-tool parameterization, +-# and alloca is special cased (for the alloca-opt module). +-# We could also entirely rely on EXTRA_lib..._SOURCES. +-AC_DEFUN([gl_LIBSOURCES], [ +- m4_foreach([_gl_NAME], [$1], [ +- m4_if(_gl_NAME, [alloca.c], [], [ +- m4_define([gl_LIBSOURCES_DIR], [lib]) +- m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ]) +- ]) +- ]) +-]) +- +-# Like AC_LIBOBJ, except that the module name goes +-# into gltests_LIBOBJS instead of into LIBOBJS. +-AC_DEFUN([gltests_LIBOBJ], [ +- AS_LITERAL_IF([$1], [gltests_LIBSOURCES([$1.c])])dnl +- gltests_LIBOBJS="$gltests_LIBOBJS $1.$ac_objext" +-]) +- +-# Like AC_REPLACE_FUNCS, except that the module name goes +-# into gltests_LIBOBJS instead of into LIBOBJS. +-AC_DEFUN([gltests_REPLACE_FUNCS], [ +- m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl +- AC_CHECK_FUNCS([$1], , [gltests_LIBOBJ($ac_func)]) +-]) +- +-# Like AC_LIBSOURCES, except the directory where the source file is +-# expected is derived from the gnulib-tool parameterization, +-# and alloca is special cased (for the alloca-opt module). +-# We could also entirely rely on EXTRA_lib..._SOURCES. +-AC_DEFUN([gltests_LIBSOURCES], [ +- m4_foreach([_gl_NAME], [$1], [ +- m4_if(_gl_NAME, [alloca.c], [], [ +- m4_define([gltests_LIBSOURCES_DIR], [tests]) +- m4_append([gltests_LIBSOURCES_LIST], _gl_NAME, [ ]) +- ]) +- ]) +-]) +- +-# This macro records the list of files which have been installed by +-# gnulib-tool and may be removed by future gnulib-tool invocations. +-AC_DEFUN([gl_FILE_LIST], [ +- build-aux/snippet/arg-nonnull.h +- build-aux/snippet/c++defs.h +- build-aux/snippet/warn-on-use.h +- lib/config.charset +- lib/localcharset.c +- lib/localcharset.h +- lib/ref-add.sin +- lib/ref-del.sin +- lib/stddef.in.h +- lib/stdint.in.h +- lib/streq.h +- lib/unitypes.in.h +- lib/uniwidth.in.h +- lib/uniwidth/cjk.h +- lib/uniwidth/width.c +- lib/wchar.in.h +- lib/wctype-h.c +- lib/wctype.in.h +- lib/wcwidth.c +- m4/00gnulib.m4 +- m4/codeset.m4 +- m4/configmake.m4 +- m4/extensions.m4 +- m4/extern-inline.m4 +- m4/fcntl-o.m4 +- m4/glibc21.m4 +- m4/gnulib-common.m4 +- m4/include_next.m4 +- m4/libunistring-base.m4 +- m4/localcharset.m4 +- m4/longlong.m4 +- m4/multiarch.m4 +- m4/onceonly.m4 +- m4/stddef_h.m4 +- m4/stdint.m4 +- m4/warn-on-use.m4 +- m4/wchar_h.m4 +- m4/wchar_t.m4 +- m4/wctype_h.m4 +- m4/wcwidth.m4 +- m4/wint_t.m4 +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/gnulib-tool.m4 groff-1.22.3/src/libs/gnulib/m4/gnulib-tool.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/gnulib-tool.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/gnulib-tool.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,57 +0,0 @@ +-# gnulib-tool.m4 serial 2 +-dnl Copyright (C) 2004-2005, 2009-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl The following macros need not be invoked explicitly. +-dnl Invoking them does nothing except to declare default arguments +-dnl for "gnulib-tool --import". +- +-dnl Usage: gl_LOCAL_DIR([DIR]) +-AC_DEFUN([gl_LOCAL_DIR], []) +- +-dnl Usage: gl_MODULES([module1 module2 ...]) +-AC_DEFUN([gl_MODULES], []) +- +-dnl Usage: gl_AVOID([module1 module2 ...]) +-AC_DEFUN([gl_AVOID], []) +- +-dnl Usage: gl_SOURCE_BASE([DIR]) +-AC_DEFUN([gl_SOURCE_BASE], []) +- +-dnl Usage: gl_M4_BASE([DIR]) +-AC_DEFUN([gl_M4_BASE], []) +- +-dnl Usage: gl_PO_BASE([DIR]) +-AC_DEFUN([gl_PO_BASE], []) +- +-dnl Usage: gl_DOC_BASE([DIR]) +-AC_DEFUN([gl_DOC_BASE], []) +- +-dnl Usage: gl_TESTS_BASE([DIR]) +-AC_DEFUN([gl_TESTS_BASE], []) +- +-dnl Usage: gl_WITH_TESTS +-AC_DEFUN([gl_WITH_TESTS], []) +- +-dnl Usage: gl_LIB([LIBNAME]) +-AC_DEFUN([gl_LIB], []) +- +-dnl Usage: gl_LGPL or gl_LGPL([VERSION]) +-AC_DEFUN([gl_LGPL], []) +- +-dnl Usage: gl_MAKEFILE_NAME([FILENAME]) +-AC_DEFUN([gl_MAKEFILE_NAME], []) +- +-dnl Usage: gl_LIBTOOL +-AC_DEFUN([gl_LIBTOOL], []) +- +-dnl Usage: gl_MACRO_PREFIX([PREFIX]) +-AC_DEFUN([gl_MACRO_PREFIX], []) +- +-dnl Usage: gl_PO_DOMAIN([DOMAIN]) +-AC_DEFUN([gl_PO_DOMAIN], []) +- +-dnl Usage: gl_VC_FILES([BOOLEAN]) +-AC_DEFUN([gl_VC_FILES], []) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/include_next.m4 groff-1.22.3/src/libs/gnulib/m4/include_next.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/include_next.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/include_next.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,270 +0,0 @@ +-# include_next.m4 serial 23 +-dnl Copyright (C) 2006-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Paul Eggert and Derek Price. +- +-dnl Sets INCLUDE_NEXT and PRAGMA_SYSTEM_HEADER. +-dnl +-dnl INCLUDE_NEXT expands to 'include_next' if the compiler supports it, or to +-dnl 'include' otherwise. +-dnl +-dnl INCLUDE_NEXT_AS_FIRST_DIRECTIVE expands to 'include_next' if the compiler +-dnl supports it in the special case that it is the first include directive in +-dnl the given file, or to 'include' otherwise. +-dnl +-dnl PRAGMA_SYSTEM_HEADER can be used in files that contain #include_next, +-dnl so as to avoid GCC warnings when the gcc option -pedantic is used. +-dnl '#pragma GCC system_header' has the same effect as if the file was found +-dnl through the include search path specified with '-isystem' options (as +-dnl opposed to the search path specified with '-I' options). Namely, gcc +-dnl does not warn about some things, and on some systems (Solaris and Interix) +-dnl __STDC__ evaluates to 0 instead of to 1. The latter is an undesired side +-dnl effect; we are therefore careful to use 'defined __STDC__' or '1' instead +-dnl of plain '__STDC__'. +-dnl +-dnl PRAGMA_COLUMNS can be used in files that override system header files, so +-dnl as to avoid compilation errors on HP NonStop systems when the gnulib file +-dnl is included by a system header file that does a "#pragma COLUMNS 80" (which +-dnl has the effect of truncating the lines of that file and all files that it +-dnl includes to 80 columns) and the gnulib file has lines longer than 80 +-dnl columns. +- +-AC_DEFUN([gl_INCLUDE_NEXT], +-[ +- AC_LANG_PREPROC_REQUIRE() +- AC_CACHE_CHECK([whether the preprocessor supports include_next], +- [gl_cv_have_include_next], +- [rm -rf conftestd1a conftestd1b conftestd2 +- mkdir conftestd1a conftestd1b conftestd2 +- dnl IBM C 9.0, 10.1 (original versions, prior to the 2009-01 updates) on +- dnl AIX 6.1 support include_next when used as first preprocessor directive +- dnl in a file, but not when preceded by another include directive. Check +- dnl for this bug by including . +- dnl Additionally, with this same compiler, include_next is a no-op when +- dnl used in a header file that was included by specifying its absolute +- dnl file name. Despite these two bugs, include_next is used in the +- dnl compiler's . By virtue of the second bug, we need to use +- dnl include_next as well in this case. +- cat < conftestd1a/conftest.h +-#define DEFINED_IN_CONFTESTD1 +-#include_next +-#ifdef DEFINED_IN_CONFTESTD2 +-int foo; +-#else +-#error "include_next doesn't work" +-#endif +-EOF +- cat < conftestd1b/conftest.h +-#define DEFINED_IN_CONFTESTD1 +-#include +-#include_next +-#ifdef DEFINED_IN_CONFTESTD2 +-int foo; +-#else +-#error "include_next doesn't work" +-#endif +-EOF +- cat < conftestd2/conftest.h +-#ifndef DEFINED_IN_CONFTESTD1 +-#error "include_next test doesn't work" +-#endif +-#define DEFINED_IN_CONFTESTD2 +-EOF +- gl_save_CPPFLAGS="$CPPFLAGS" +- CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2" +-dnl We intentionally avoid using AC_LANG_SOURCE here. +- AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include ]], +- [gl_cv_have_include_next=yes], +- [CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2" +- AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include ]], +- [gl_cv_have_include_next=buggy], +- [gl_cv_have_include_next=no]) +- ]) +- CPPFLAGS="$gl_save_CPPFLAGS" +- rm -rf conftestd1a conftestd1b conftestd2 +- ]) +- PRAGMA_SYSTEM_HEADER= +- if test $gl_cv_have_include_next = yes; then +- INCLUDE_NEXT=include_next +- INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next +- if test -n "$GCC"; then +- PRAGMA_SYSTEM_HEADER='#pragma GCC system_header' +- fi +- else +- if test $gl_cv_have_include_next = buggy; then +- INCLUDE_NEXT=include +- INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next +- else +- INCLUDE_NEXT=include +- INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include +- fi +- fi +- AC_SUBST([INCLUDE_NEXT]) +- AC_SUBST([INCLUDE_NEXT_AS_FIRST_DIRECTIVE]) +- AC_SUBST([PRAGMA_SYSTEM_HEADER]) +- AC_CACHE_CHECK([whether system header files limit the line length], +- [gl_cv_pragma_columns], +- [dnl HP NonStop systems, which define __TANDEM, have this misfeature. +- AC_EGREP_CPP([choke me], +- [ +-#ifdef __TANDEM +-choke me +-#endif +- ], +- [gl_cv_pragma_columns=yes], +- [gl_cv_pragma_columns=no]) +- ]) +- if test $gl_cv_pragma_columns = yes; then +- PRAGMA_COLUMNS="#pragma COLUMNS 10000" +- else +- PRAGMA_COLUMNS= +- fi +- AC_SUBST([PRAGMA_COLUMNS]) +-]) +- +-# gl_CHECK_NEXT_HEADERS(HEADER1 HEADER2 ...) +-# ------------------------------------------ +-# For each arg foo.h, if #include_next works, define NEXT_FOO_H to be +-# ''; otherwise define it to be +-# '"///usr/include/foo.h"', or whatever other absolute file name is suitable. +-# Also, if #include_next works as first preprocessing directive in a file, +-# define NEXT_AS_FIRST_DIRECTIVE_FOO_H to be ''; otherwise define it to +-# be +-# '"///usr/include/foo.h"', or whatever other absolute file name is suitable. +-# That way, a header file with the following line: +-# #@INCLUDE_NEXT@ @NEXT_FOO_H@ +-# or +-# #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_FOO_H@ +-# behaves (after sed substitution) as if it contained +-# #include_next +-# even if the compiler does not support include_next. +-# The three "///" are to pacify Sun C 5.8, which otherwise would say +-# "warning: #include of /usr/include/... may be non-portable". +-# Use '""', not '<>', so that the /// cannot be confused with a C99 comment. +-# Note: This macro assumes that the header file is not empty after +-# preprocessing, i.e. it does not only define preprocessor macros but also +-# provides some type/enum definitions or function/variable declarations. +-# +-# This macro also checks whether each header exists, by invoking +-# AC_CHECK_HEADERS_ONCE or AC_CHECK_HEADERS on each argument. +-AC_DEFUN([gl_CHECK_NEXT_HEADERS], +-[ +- gl_NEXT_HEADERS_INTERNAL([$1], [check]) +-]) +- +-# gl_NEXT_HEADERS(HEADER1 HEADER2 ...) +-# ------------------------------------ +-# Like gl_CHECK_NEXT_HEADERS, except do not check whether the headers exist. +-# This is suitable for headers like that are standardized by C89 +-# and therefore can be assumed to exist. +-AC_DEFUN([gl_NEXT_HEADERS], +-[ +- gl_NEXT_HEADERS_INTERNAL([$1], [assume]) +-]) +- +-# The guts of gl_CHECK_NEXT_HEADERS and gl_NEXT_HEADERS. +-AC_DEFUN([gl_NEXT_HEADERS_INTERNAL], +-[ +- AC_REQUIRE([gl_INCLUDE_NEXT]) +- AC_REQUIRE([AC_CANONICAL_HOST]) +- +- m4_if([$2], [check], +- [AC_CHECK_HEADERS_ONCE([$1]) +- ]) +- +-dnl FIXME: gl_next_header and gl_header_exists must be used unquoted +-dnl until we can assume autoconf 2.64 or newer. +- m4_foreach_w([gl_HEADER_NAME], [$1], +- [AS_VAR_PUSHDEF([gl_next_header], +- [gl_cv_next_]m4_defn([gl_HEADER_NAME])) +- if test $gl_cv_have_include_next = yes; then +- AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>']) +- else +- AC_CACHE_CHECK( +- [absolute name of <]m4_defn([gl_HEADER_NAME])[>], +- m4_defn([gl_next_header]), +- [m4_if([$2], [check], +- [AS_VAR_PUSHDEF([gl_header_exists], +- [ac_cv_header_]m4_defn([gl_HEADER_NAME])) +- if test AS_VAR_GET(gl_header_exists) = yes; then +- AS_VAR_POPDEF([gl_header_exists]) +- ]) +- AC_LANG_CONFTEST( +- [AC_LANG_SOURCE( +- [[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]] +- )]) +- dnl AIX "xlc -E" and "cc -E" omit #line directives for header +- dnl files that contain only a #include of other header files and +- dnl no non-comment tokens of their own. This leads to a failure +- dnl to detect the absolute name of , , +- dnl and others. The workaround is to force preservation +- dnl of comments through option -C. This ensures all necessary +- dnl #line directives are present. GCC supports option -C as well. +- case "$host_os" in +- aix*) gl_absname_cpp="$ac_cpp -C" ;; +- *) gl_absname_cpp="$ac_cpp" ;; +- esac +-changequote(,) +- case "$host_os" in +- mingw*) +- dnl For the sake of native Windows compilers (excluding gcc), +- dnl treat backslash as a directory separator, like /. +- dnl Actually, these compilers use a double-backslash as +- dnl directory separator, inside the +- dnl # line "filename" +- dnl directives. +- gl_dirsep_regex='[/\\]' +- ;; +- *) +- gl_dirsep_regex='\/' +- ;; +- esac +- dnl A sed expression that turns a string into a basic regular +- dnl expression, for use within "/.../". +- gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g' +-changequote([,]) +- gl_header_literal_regex=`echo ']m4_defn([gl_HEADER_NAME])[' \ +- | sed -e "$gl_make_literal_regex_sed"` +- gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{ +- s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/ +-changequote(,)dnl +- s|^/[^/]|//&| +-changequote([,])dnl +- p +- q +- }' +- dnl eval is necessary to expand gl_absname_cpp. +- dnl Ultrix and Pyramid sh refuse to redirect output of eval, +- dnl so use subshell. +- AS_VAR_SET(gl_next_header, +- ['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | +- sed -n "$gl_absolute_header_sed"`'"']) +- m4_if([$2], [check], +- [else +- AS_VAR_SET(gl_next_header, ['<'gl_HEADER_NAME'>']) +- fi +- ]) +- ]) +- fi +- AC_SUBST( +- AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])), +- [AS_VAR_GET(gl_next_header)]) +- if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next' +- gl_next_as_first_directive='<'gl_HEADER_NAME'>' +- else +- # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include' +- gl_next_as_first_directive=AS_VAR_GET(gl_next_header) +- fi +- AC_SUBST( +- AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])), +- [$gl_next_as_first_directive]) +- AS_VAR_POPDEF([gl_next_header])]) +-]) +- +-# Autoconf 2.68 added warnings for our use of AC_COMPILE_IFELSE; +-# this fallback is safe for all earlier autoconf versions. +-m4_define_default([AC_LANG_DEFINES_PROVIDED]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/inttypes.m4 groff-1.22.3/src/libs/gnulib/m4/inttypes.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/inttypes.m4 2014-11-04 10:38:35.640518809 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/inttypes.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,157 +0,0 @@ +-# inttypes.m4 serial 26 +-dnl Copyright (C) 2006-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Derek Price, Bruno Haible. +-dnl Test whether is supported or must be substituted. +- +-AC_DEFUN([gl_INTTYPES_H], +-[ +- AC_REQUIRE([gl_INTTYPES_INCOMPLETE]) +- gl_INTTYPES_PRI_SCN +-]) +- +-AC_DEFUN_ONCE([gl_INTTYPES_INCOMPLETE], +-[ +- AC_REQUIRE([gl_STDINT_H]) +- AC_CHECK_HEADERS_ONCE([inttypes.h]) +- +- dnl Override always, so that the portability warnings work. +- AC_REQUIRE([gl_INTTYPES_H_DEFAULTS]) +- gl_CHECK_NEXT_HEADERS([inttypes.h]) +- +- AC_REQUIRE([gl_MULTIARCH]) +- +- dnl Check for declarations of anything we want to poison if the +- dnl corresponding gnulib module is not in use. +- gl_WARN_ON_USE_PREPARE([[#include +- ]], [imaxabs imaxdiv strtoimax strtoumax]) +-]) +- +-# Ensure that the PRI* and SCN* macros are defined appropriately. +-AC_DEFUN([gl_INTTYPES_PRI_SCN], +-[ +- AC_REQUIRE([gt_INTTYPES_PRI]) +- +- PRIPTR_PREFIX= +- if test -n "$STDINT_H"; then +- dnl Using the gnulib . It always defines intptr_t to 'long'. +- PRIPTR_PREFIX='"l"' +- else +- dnl Using the system's . +- for glpfx in '' l ll I64; do +- case $glpfx in +- '') gltype1='int';; +- l) gltype1='long int';; +- ll) gltype1='long long int';; +- I64) gltype1='__int64';; +- esac +- AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM([[#include +- extern intptr_t foo; +- extern $gltype1 foo;]])], +- [PRIPTR_PREFIX='"'$glpfx'"']) +- test -n "$PRIPTR_PREFIX" && break +- done +- fi +- AC_SUBST([PRIPTR_PREFIX]) +- +- gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION( +- [INT32_MAX_LT_INTMAX_MAX], +- [defined INT32_MAX && defined INTMAX_MAX], +- [INT32_MAX < INTMAX_MAX], +- [sizeof (int) < sizeof (long long int)]) +- if test $APPLE_UNIVERSAL_BUILD = 0; then +- gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION( +- [INT64_MAX_EQ_LONG_MAX], +- [defined INT64_MAX], +- [INT64_MAX == LONG_MAX], +- [sizeof (long long int) == sizeof (long int)]) +- else +- INT64_MAX_EQ_LONG_MAX=-1 +- fi +- gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION( +- [UINT32_MAX_LT_UINTMAX_MAX], +- [defined UINT32_MAX && defined UINTMAX_MAX], +- [UINT32_MAX < UINTMAX_MAX], +- [sizeof (unsigned int) < sizeof (unsigned long long int)]) +- if test $APPLE_UNIVERSAL_BUILD = 0; then +- gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION( +- [UINT64_MAX_EQ_ULONG_MAX], +- [defined UINT64_MAX], +- [UINT64_MAX == ULONG_MAX], +- [sizeof (unsigned long long int) == sizeof (unsigned long int)]) +- else +- UINT64_MAX_EQ_ULONG_MAX=-1 +- fi +-]) +- +-# Define the symbol $1 to be 1 if the condition is true, 0 otherwise. +-# If $2 is true, the condition is $3; otherwise if long long int is supported +-# approximate the condition with $4; otherwise, assume the condition is false. +-# The condition should work on all C99 platforms; the approximations should be +-# good enough to work on all practical pre-C99 platforms. +-# $2 is evaluated by the C preprocessor, $3 and $4 as compile-time constants. +-AC_DEFUN([gl_INTTYPES_CHECK_LONG_LONG_INT_CONDITION], +-[ +- AC_CACHE_CHECK([whether $3], +- [gl_cv_test_$1], +- [AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM( +- [[/* Work also in C++ mode. */ +- #define __STDC_LIMIT_MACROS 1 +- +- /* Work if build is not clean. */ +- #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H +- +- #include +- #if HAVE_STDINT_H +- #include +- #endif +- +- #if $2 +- #define CONDITION ($3) +- #elif HAVE_LONG_LONG_INT +- #define CONDITION ($4) +- #else +- #define CONDITION 0 +- #endif +- int test[CONDITION ? 1 : -1];]])], +- [gl_cv_test_$1=yes], +- [gl_cv_test_$1=no])]) +- if test $gl_cv_test_$1 = yes; then +- $1=1; +- else +- $1=0; +- fi +- AC_SUBST([$1]) +-]) +- +-AC_DEFUN([gl_INTTYPES_MODULE_INDICATOR], +-[ +- dnl Use AC_REQUIRE here, so that the default settings are expanded once only. +- AC_REQUIRE([gl_INTTYPES_H_DEFAULTS]) +- gl_MODULE_INDICATOR_SET_VARIABLE([$1]) +-]) +- +-AC_DEFUN([gl_INTTYPES_H_DEFAULTS], +-[ +- GNULIB_IMAXABS=0; AC_SUBST([GNULIB_IMAXABS]) +- GNULIB_IMAXDIV=0; AC_SUBST([GNULIB_IMAXDIV]) +- GNULIB_STRTOIMAX=0; AC_SUBST([GNULIB_STRTOIMAX]) +- GNULIB_STRTOUMAX=0; AC_SUBST([GNULIB_STRTOUMAX]) +- dnl Assume proper GNU behavior unless another module says otherwise. +- HAVE_DECL_IMAXABS=1; AC_SUBST([HAVE_DECL_IMAXABS]) +- HAVE_DECL_IMAXDIV=1; AC_SUBST([HAVE_DECL_IMAXDIV]) +- HAVE_DECL_STRTOIMAX=1; AC_SUBST([HAVE_DECL_STRTOIMAX]) +- HAVE_DECL_STRTOUMAX=1; AC_SUBST([HAVE_DECL_STRTOUMAX]) +- REPLACE_STRTOIMAX=0; AC_SUBST([REPLACE_STRTOIMAX]) +- INT32_MAX_LT_INTMAX_MAX=1; AC_SUBST([INT32_MAX_LT_INTMAX_MAX]) +- INT64_MAX_EQ_LONG_MAX='defined _LP64'; AC_SUBST([INT64_MAX_EQ_LONG_MAX]) +- PRI_MACROS_BROKEN=0; AC_SUBST([PRI_MACROS_BROKEN]) +- PRIPTR_PREFIX=__PRIPTR_PREFIX; AC_SUBST([PRIPTR_PREFIX]) +- UINT32_MAX_LT_UINTMAX_MAX=1; AC_SUBST([UINT32_MAX_LT_UINTMAX_MAX]) +- UINT64_MAX_EQ_ULONG_MAX='defined _LP64'; AC_SUBST([UINT64_MAX_EQ_ULONG_MAX]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/inttypes-pri.m4 groff-1.22.3/src/libs/gnulib/m4/inttypes-pri.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/inttypes-pri.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/inttypes-pri.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,42 +0,0 @@ +-# inttypes-pri.m4 serial 7 (gettext-0.18.2) +-dnl Copyright (C) 1997-2002, 2006, 2008-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Bruno Haible. +- +-AC_PREREQ([2.53]) +- +-# Define PRI_MACROS_BROKEN if exists and defines the PRI* +-# macros to non-string values. This is the case on AIX 4.3.3. +- +-AC_DEFUN([gt_INTTYPES_PRI], +-[ +- AC_CHECK_HEADERS([inttypes.h]) +- if test $ac_cv_header_inttypes_h = yes; then +- AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], +- [gt_cv_inttypes_pri_broken], +- [ +- AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM( +- [[ +-#include +-#ifdef PRId32 +-char *p = PRId32; +-#endif +- ]], +- [[]])], +- [gt_cv_inttypes_pri_broken=no], +- [gt_cv_inttypes_pri_broken=yes]) +- ]) +- fi +- if test "$gt_cv_inttypes_pri_broken" = yes; then +- AC_DEFINE_UNQUOTED([PRI_MACROS_BROKEN], [1], +- [Define if exists and defines unusable PRI* macros.]) +- PRI_MACROS_BROKEN=1 +- else +- PRI_MACROS_BROKEN=0 +- fi +- AC_SUBST([PRI_MACROS_BROKEN]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/libunistring-base.m4 groff-1.22.3/src/libs/gnulib/m4/libunistring-base.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/libunistring-base.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/libunistring-base.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,141 +0,0 @@ +-# libunistring-base.m4 serial 5 +-dnl Copyright (C) 2010-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Paolo Bonzini and Bruno Haible. +- +-dnl gl_LIBUNISTRING_MODULE([VERSION], [Module]) +-dnl Declares that the source files of Module should be compiled, unless we +-dnl are linking with libunistring and its version is >= the given VERSION. +-dnl Defines an automake conditional LIBUNISTRING_COMPILE_$MODULE that is +-dnl true if the source files of Module should be compiled. +-dnl This macro is to be used for public libunistring API, not for +-dnl undocumented API. +-dnl +-dnl You have to bump the VERSION argument to the next projected version +-dnl number each time you make a change that affects the behaviour of the +-dnl functions defined in Module (even if the sources of Module itself do not +-dnl change). +- +-AC_DEFUN([gl_LIBUNISTRING_MODULE], +-[ +- AC_REQUIRE([gl_LIBUNISTRING_LIB_PREPARE]) +- dnl Use the variables HAVE_LIBUNISTRING, LIBUNISTRING_VERSION from +- dnl gl_LIBUNISTRING_CORE if that macro has been run. +- AM_CONDITIONAL(AS_TR_CPP([LIBUNISTRING_COMPILE_$2]), +- [gl_LIBUNISTRING_VERSION_CMP([$1])]) +-]) +- +-dnl gl_LIBUNISTRING_LIBHEADER([VERSION], [HeaderFile]) +-dnl Declares that HeaderFile should be created, unless we are linking +-dnl with libunistring and its version is >= the given VERSION. +-dnl HeaderFile should be relative to the lib directory and end in '.h'. +-dnl Prepares for substituting LIBUNISTRING_HEADERFILE (to HeaderFile or empty). +-dnl +-dnl When we are linking with the already installed libunistring and its version +-dnl is < VERSION, we create HeaderFile here, because we may compile functions +-dnl (via gl_LIBUNISTRING_MODULE above) that are not contained in the installed +-dnl version. +-dnl When we are linking with the already installed libunistring and its version +-dnl is > VERSION, we don't create HeaderFile here: it could cause compilation +-dnl errors in other libunistring header files if some types are missing. +-dnl +-dnl You have to bump the VERSION argument to the next projected version +-dnl number each time you make a non-comment change to the HeaderFile. +- +-AC_DEFUN([gl_LIBUNISTRING_LIBHEADER], +-[ +- AC_REQUIRE([gl_LIBUNISTRING_LIB_PREPARE]) +- dnl Use the variables HAVE_LIBUNISTRING, LIBUNISTRING_VERSION from +- dnl gl_LIBUNISTRING_CORE if that macro has been run. +- if gl_LIBUNISTRING_VERSION_CMP([$1]); then +- LIBUNISTRING_[]AS_TR_CPP([$2])='$2' +- else +- LIBUNISTRING_[]AS_TR_CPP([$2])= +- fi +- AC_SUBST([LIBUNISTRING_]AS_TR_CPP([$2])) +-]) +- +-dnl Miscellaneous preparations/initializations. +- +-AC_DEFUN([gl_LIBUNISTRING_LIB_PREPARE], +-[ +- dnl Ensure that HAVE_LIBUNISTRING is fully determined at this point. +- m4_ifdef([gl_LIBUNISTRING], [AC_REQUIRE([gl_LIBUNISTRING])]) +- +- AC_REQUIRE([AC_PROG_AWK]) +- +-dnl Sed expressions to extract the parts of a version number. +-changequote(,) +-gl_libunistring_sed_extract_major='/^[0-9]/{s/^\([0-9]*\).*/\1/p;q;} +-i\ +-0 +-q +-' +-gl_libunistring_sed_extract_minor='/^[0-9][0-9]*[.][0-9]/{s/^[0-9]*[.]\([0-9]*\).*/\1/p;q;} +-i\ +-0 +-q +-' +-gl_libunistring_sed_extract_subminor='/^[0-9][0-9]*[.][0-9][0-9]*[.][0-9]/{s/^[0-9]*[.][0-9]*[.]\([0-9]*\).*/\1/p;q;} +-i\ +-0 +-q +-' +-changequote([,]) +- +- if test "$HAVE_LIBUNISTRING" = yes; then +- LIBUNISTRING_VERSION_MAJOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_major"` +- LIBUNISTRING_VERSION_MINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_minor"` +- LIBUNISTRING_VERSION_SUBMINOR=`echo "$LIBUNISTRING_VERSION" | sed -n -e "$gl_libunistring_sed_extract_subminor"` +- fi +-]) +- +-dnl gl_LIBUNISTRING_VERSION_CMP([VERSION]) +-dnl Expands to a shell statement that evaluates to true if LIBUNISTRING_VERSION +-dnl is less than the VERSION argument. +-AC_DEFUN([gl_LIBUNISTRING_VERSION_CMP], +-[ { test "$HAVE_LIBUNISTRING" != yes \ +- || { +- dnl AS_LITERAL_IF exists and works fine since autoconf-2.59 at least. +- AS_LITERAL_IF([$1], +- [dnl This is the optimized variant, that assumes the argument is a literal: +- m4_pushdef([requested_version_major], +- [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^\([0-9]*\).*], [\1]), [])]) +- m4_pushdef([requested_version_minor], +- [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^[0-9]*[.]\([0-9]*\).*], [\1]), [$1])]) +- m4_pushdef([requested_version_subminor], +- [gl_LIBUNISTRING_ARG_OR_ZERO(m4_bpatsubst([$1], [^[0-9]*[.][0-9]*[.]\([0-9]*\).*], [\1]), [$1])]) +- test $LIBUNISTRING_VERSION_MAJOR -lt requested_version_major \ +- || { test $LIBUNISTRING_VERSION_MAJOR -eq requested_version_major \ +- && { test $LIBUNISTRING_VERSION_MINOR -lt requested_version_minor \ +- || { test $LIBUNISTRING_VERSION_MINOR -eq requested_version_minor \ +- && test $LIBUNISTRING_VERSION_SUBMINOR -lt requested_version_subminor +- } +- } +- } +- m4_popdef([requested_version_subminor]) +- m4_popdef([requested_version_minor]) +- m4_popdef([requested_version_major]) +- ], +- [dnl This is the unoptimized variant: +- requested_version_major=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_major"` +- requested_version_minor=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_minor"` +- requested_version_subminor=`echo '$1' | sed -n -e "$gl_libunistring_sed_extract_subminor"` +- test $LIBUNISTRING_VERSION_MAJOR -lt $requested_version_major \ +- || { test $LIBUNISTRING_VERSION_MAJOR -eq $requested_version_major \ +- && { test $LIBUNISTRING_VERSION_MINOR -lt $requested_version_minor \ +- || { test $LIBUNISTRING_VERSION_MINOR -eq $requested_version_minor \ +- && test $LIBUNISTRING_VERSION_SUBMINOR -lt $requested_version_subminor +- } +- } +- } +- ]) +- } +- }]) +- +-dnl gl_LIBUNISTRING_ARG_OR_ZERO([ARG], [ORIG]) expands to ARG if it is not the +-dnl same as ORIG, otherwise to 0. +-m4_define([gl_LIBUNISTRING_ARG_OR_ZERO], [m4_if([$1], [$2], [0], [$1])]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/localcharset.m4 groff-1.22.3/src/libs/gnulib/m4/localcharset.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/localcharset.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/localcharset.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,17 +0,0 @@ +-# localcharset.m4 serial 7 +-dnl Copyright (C) 2002, 2004, 2006, 2009-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-AC_DEFUN([gl_LOCALCHARSET], +-[ +- dnl Prerequisites of lib/localcharset.c. +- AC_REQUIRE([AM_LANGINFO_CODESET]) +- AC_REQUIRE([gl_FCNTL_O_FLAGS]) +- AC_CHECK_DECLS_ONCE([getc_unlocked]) +- +- dnl Prerequisites of the lib/Makefile.am snippet. +- AC_REQUIRE([AC_CANONICAL_HOST]) +- AC_REQUIRE([gl_GLIBC21]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/longlong.m4 groff-1.22.3/src/libs/gnulib/m4/longlong.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/longlong.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/longlong.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,113 +0,0 @@ +-# longlong.m4 serial 17 +-dnl Copyright (C) 1999-2007, 2009-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Paul Eggert. +- +-# Define HAVE_LONG_LONG_INT if 'long long int' works. +-# This fixes a bug in Autoconf 2.61, and can be faster +-# than what's in Autoconf 2.62 through 2.68. +- +-# Note: If the type 'long long int' exists but is only 32 bits large +-# (as on some very old compilers), HAVE_LONG_LONG_INT will not be +-# defined. In this case you can treat 'long long int' like 'long int'. +- +-AC_DEFUN([AC_TYPE_LONG_LONG_INT], +-[ +- AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) +- AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int], +- [ac_cv_type_long_long_int=yes +- if test "x${ac_cv_prog_cc_c99-no}" = xno; then +- ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int +- if test $ac_cv_type_long_long_int = yes; then +- dnl Catch a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004. +- dnl If cross compiling, assume the bug is not important, since +- dnl nobody cross compiles for this platform as far as we know. +- AC_RUN_IFELSE( +- [AC_LANG_PROGRAM( +- [[@%:@include +- @%:@ifndef LLONG_MAX +- @%:@ define HALF \ +- (1LL << (sizeof (long long int) * CHAR_BIT - 2)) +- @%:@ define LLONG_MAX (HALF - 1 + HALF) +- @%:@endif]], +- [[long long int n = 1; +- int i; +- for (i = 0; ; i++) +- { +- long long int m = n << i; +- if (m >> i != n) +- return 1; +- if (LLONG_MAX / 2 < m) +- break; +- } +- return 0;]])], +- [], +- [ac_cv_type_long_long_int=no], +- [:]) +- fi +- fi]) +- if test $ac_cv_type_long_long_int = yes; then +- AC_DEFINE([HAVE_LONG_LONG_INT], [1], +- [Define to 1 if the system has the type 'long long int'.]) +- fi +-]) +- +-# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. +-# This fixes a bug in Autoconf 2.61, and can be faster +-# than what's in Autoconf 2.62 through 2.68. +- +-# Note: If the type 'unsigned long long int' exists but is only 32 bits +-# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT +-# will not be defined. In this case you can treat 'unsigned long long int' +-# like 'unsigned long int'. +- +-AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], +-[ +- AC_CACHE_CHECK([for unsigned long long int], +- [ac_cv_type_unsigned_long_long_int], +- [ac_cv_type_unsigned_long_long_int=yes +- if test "x${ac_cv_prog_cc_c99-no}" = xno; then +- AC_LINK_IFELSE( +- [_AC_TYPE_LONG_LONG_SNIPPET], +- [], +- [ac_cv_type_unsigned_long_long_int=no]) +- fi]) +- if test $ac_cv_type_unsigned_long_long_int = yes; then +- AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], +- [Define to 1 if the system has the type 'unsigned long long int'.]) +- fi +-]) +- +-# Expands to a C program that can be used to test for simultaneous support +-# of 'long long' and 'unsigned long long'. We don't want to say that +-# 'long long' is available if 'unsigned long long' is not, or vice versa, +-# because too many programs rely on the symmetry between signed and unsigned +-# integer types (excluding 'bool'). +-AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], +-[ +- AC_LANG_PROGRAM( +- [[/* For now, do not test the preprocessor; as of 2007 there are too many +- implementations with broken preprocessors. Perhaps this can +- be revisited in 2012. In the meantime, code should not expect +- #if to work with literals wider than 32 bits. */ +- /* Test literals. */ +- long long int ll = 9223372036854775807ll; +- long long int nll = -9223372036854775807LL; +- unsigned long long int ull = 18446744073709551615ULL; +- /* Test constant expressions. */ +- typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) +- ? 1 : -1)]; +- typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 +- ? 1 : -1)]; +- int i = 63;]], +- [[/* Test availability of runtime routines for shift and division. */ +- long long int llmax = 9223372036854775807ll; +- unsigned long long int ullmax = 18446744073709551615ull; +- return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) +- | (llmax / ll) | (llmax % ll) +- | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) +- | (ullmax / ull) | (ullmax % ull));]]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/Makefile.am groff-1.22.3/src/libs/gnulib/m4/Makefile.am +--- groff-1.22.3.old/src/libs/gnulib/m4/Makefile.am 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/Makefile.am 1970-01-01 02:00:00.000000000 +0200 +@@ -1,47 +0,0 @@ +-## Process this file with automake to produce Makefile.in. +- +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2, or (at your option) +-# any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-# As a special exception to the GNU General Public License, if you +-# distribute this file as part of a program that contains a +-# configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that program. +- +-EXTRA_DIST = +-EXTRA_DIST += 00gnulib.m4 +-EXTRA_DIST += codeset.m4 +-EXTRA_DIST += configmake.m4 +-EXTRA_DIST += extensions.m4 +-EXTRA_DIST += extern-inline.m4 +-EXTRA_DIST += fcntl-o.m4 +-EXTRA_DIST += glibc21.m4 +-EXTRA_DIST += gnulib-common.m4 +-EXTRA_DIST += include_next.m4 +-EXTRA_DIST += inttypes-pri.m4 +-EXTRA_DIST += inttypes.m4 +-EXTRA_DIST += libunistring-base.m4 +-EXTRA_DIST += localcharset.m4 +-EXTRA_DIST += longlong.m4 +-EXTRA_DIST += multiarch.m4 +-EXTRA_DIST += stdbool.m4 +-EXTRA_DIST += stddef_h.m4 +-EXTRA_DIST += stdint.m4 +-EXTRA_DIST += warn-on-use.m4 +-EXTRA_DIST += wchar_h.m4 +-EXTRA_DIST += wchar_t.m4 +-EXTRA_DIST += wctype_h.m4 +-EXTRA_DIST += wcwidth.m4 +-EXTRA_DIST += wint_t.m4 +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/Makefile.in groff-1.22.3/src/libs/gnulib/m4/Makefile.in +--- groff-1.22.3.old/src/libs/gnulib/m4/Makefile.in 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/Makefile.in 1970-01-01 02:00:00.000000000 +0200 +@@ -1,608 +0,0 @@ +-# Makefile.in generated by automake 1.14 from Makefile.am. +-# @configure_input@ +- +-# Copyright (C) 1994-2013 Free Software Foundation, Inc. +- +-# This Makefile.in is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +-# PARTICULAR PURPOSE. +- +-@SET_MAKE@ +- +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This program is free software; you can redistribute it and/or modify +-# it under the terms of the GNU General Public License as published by +-# the Free Software Foundation; either version 2, or (at your option) +-# any later version. +-# +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-# GNU General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-# As a special exception to the GNU General Public License, if you +-# distribute this file as part of a program that contains a +-# configuration script generated by Autoconf, you may include it under +-# the same distribution terms that you use for the rest of that program. +-VPATH = @srcdir@ +-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +-am__make_running_with_option = \ +- case $${target_option-} in \ +- ?) ;; \ +- *) echo "am__make_running_with_option: internal error: invalid" \ +- "target option '$${target_option-}' specified" >&2; \ +- exit 1;; \ +- esac; \ +- has_opt=no; \ +- sane_makeflags=$$MAKEFLAGS; \ +- if $(am__is_gnu_make); then \ +- sane_makeflags=$$MFLAGS; \ +- else \ +- case $$MAKEFLAGS in \ +- *\\[\ \ ]*) \ +- bs=\\; \ +- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ +- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ +- esac; \ +- fi; \ +- skip_next=no; \ +- strip_trailopt () \ +- { \ +- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ +- }; \ +- for flg in $$sane_makeflags; do \ +- test $$skip_next = yes && { skip_next=no; continue; }; \ +- case $$flg in \ +- *=*|--*) continue;; \ +- -*I) strip_trailopt 'I'; skip_next=yes;; \ +- -*I?*) strip_trailopt 'I';; \ +- -*O) strip_trailopt 'O'; skip_next=yes;; \ +- -*O?*) strip_trailopt 'O';; \ +- -*l) strip_trailopt 'l'; skip_next=yes;; \ +- -*l?*) strip_trailopt 'l';; \ +- -[dEDm]) skip_next=yes;; \ +- -[JT]) skip_next=yes;; \ +- esac; \ +- case $$flg in \ +- *$$target_option*) has_opt=yes; break;; \ +- esac; \ +- done; \ +- test $$has_opt = yes +-am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +-am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +-pkgdatadir = $(datadir)/@PACKAGE@ +-pkgincludedir = $(includedir)/@PACKAGE@ +-pkglibdir = $(libdir)/@PACKAGE@ +-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +-install_sh_DATA = $(install_sh) -c -m 644 +-install_sh_PROGRAM = $(install_sh) -c +-install_sh_SCRIPT = $(install_sh) -c +-INSTALL_HEADER = $(INSTALL_DATA) +-transform = $(program_transform_name) +-NORMAL_INSTALL = : +-PRE_INSTALL = : +-POST_INSTALL = : +-NORMAL_UNINSTALL = : +-PRE_UNINSTALL = : +-POST_UNINSTALL = : +-build_triplet = @build@ +-host_triplet = @host@ +-subdir = m4 +-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ +- $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/configmake.m4 \ +- $(top_srcdir)/m4/extensions.m4 \ +- $(top_srcdir)/m4/extern-inline.m4 $(top_srcdir)/m4/fcntl-o.m4 \ +- $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/gnulib-common.m4 \ +- $(top_srcdir)/m4/include_next.m4 \ +- $(top_srcdir)/m4/inttypes-pri.m4 $(top_srcdir)/m4/inttypes.m4 \ +- $(top_srcdir)/m4/libunistring-base.m4 \ +- $(top_srcdir)/m4/localcharset.m4 $(top_srcdir)/m4/longlong.m4 \ +- $(top_srcdir)/m4/multiarch.m4 $(top_srcdir)/m4/onceonly.m4 \ +- $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \ +- $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/warn-on-use.m4 \ +- $(top_srcdir)/m4/wchar_h.m4 $(top_srcdir)/m4/wchar_t.m4 \ +- $(top_srcdir)/m4/wctype_h.m4 $(top_srcdir)/m4/wcwidth.m4 \ +- $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/configure.ac +-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ +- $(ACLOCAL_M4) +-mkinstalldirs = $(install_sh) -d +-CONFIG_HEADER = $(top_builddir)/config.h +-CONFIG_CLEAN_FILES = +-CONFIG_CLEAN_VPATH_FILES = +-AM_V_P = $(am__v_P_@AM_V@) +-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +-am__v_P_0 = false +-am__v_P_1 = : +-AM_V_GEN = $(am__v_GEN_@AM_V@) +-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +-am__v_GEN_0 = @echo " GEN " $@; +-am__v_GEN_1 = +-AM_V_at = $(am__v_at_@AM_V@) +-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +-am__v_at_0 = @ +-am__v_at_1 = +-SOURCES = +-DIST_SOURCES = +-am__can_run_installinfo = \ +- case $$AM_UPDATE_INFO_DIR in \ +- n|no|NO) false;; \ +- *) (install-info --version) >/dev/null 2>&1;; \ +- esac +-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +-pkglibexecdir = @pkglibexecdir@ +-ACLOCAL = @ACLOCAL@ +-AMTAR = @AMTAR@ +-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +-APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@ +-AR = @AR@ +-ARFLAGS = @ARFLAGS@ +-AUTOCONF = @AUTOCONF@ +-AUTOHEADER = @AUTOHEADER@ +-AUTOMAKE = @AUTOMAKE@ +-AWK = @AWK@ +-BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +-BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +-BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +-BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +-BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +-CC = @CC@ +-CCDEPMODE = @CCDEPMODE@ +-CFLAGS = @CFLAGS@ +-CPP = @CPP@ +-CPPFLAGS = @CPPFLAGS@ +-CYGPATH_W = @CYGPATH_W@ +-DEFS = @DEFS@ +-DEPDIR = @DEPDIR@ +-ECHO_C = @ECHO_C@ +-ECHO_N = @ECHO_N@ +-ECHO_T = @ECHO_T@ +-EGREP = @EGREP@ +-EXEEXT = @EXEEXT@ +-GLIBC21 = @GLIBC21@ +-GNULIB_BTOWC = @GNULIB_BTOWC@ +-GNULIB_IMAXABS = @GNULIB_IMAXABS@ +-GNULIB_IMAXDIV = @GNULIB_IMAXDIV@ +-GNULIB_ISWBLANK = @GNULIB_ISWBLANK@ +-GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@ +-GNULIB_MBRLEN = @GNULIB_MBRLEN@ +-GNULIB_MBRTOWC = @GNULIB_MBRTOWC@ +-GNULIB_MBSINIT = @GNULIB_MBSINIT@ +-GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@ +-GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@ +-GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@ +-GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@ +-GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@ +-GNULIB_WCPCPY = @GNULIB_WCPCPY@ +-GNULIB_WCPNCPY = @GNULIB_WCPNCPY@ +-GNULIB_WCRTOMB = @GNULIB_WCRTOMB@ +-GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@ +-GNULIB_WCSCAT = @GNULIB_WCSCAT@ +-GNULIB_WCSCHR = @GNULIB_WCSCHR@ +-GNULIB_WCSCMP = @GNULIB_WCSCMP@ +-GNULIB_WCSCOLL = @GNULIB_WCSCOLL@ +-GNULIB_WCSCPY = @GNULIB_WCSCPY@ +-GNULIB_WCSCSPN = @GNULIB_WCSCSPN@ +-GNULIB_WCSDUP = @GNULIB_WCSDUP@ +-GNULIB_WCSLEN = @GNULIB_WCSLEN@ +-GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@ +-GNULIB_WCSNCAT = @GNULIB_WCSNCAT@ +-GNULIB_WCSNCMP = @GNULIB_WCSNCMP@ +-GNULIB_WCSNCPY = @GNULIB_WCSNCPY@ +-GNULIB_WCSNLEN = @GNULIB_WCSNLEN@ +-GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@ +-GNULIB_WCSPBRK = @GNULIB_WCSPBRK@ +-GNULIB_WCSRCHR = @GNULIB_WCSRCHR@ +-GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@ +-GNULIB_WCSSPN = @GNULIB_WCSSPN@ +-GNULIB_WCSSTR = @GNULIB_WCSSTR@ +-GNULIB_WCSTOK = @GNULIB_WCSTOK@ +-GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@ +-GNULIB_WCSXFRM = @GNULIB_WCSXFRM@ +-GNULIB_WCTOB = @GNULIB_WCTOB@ +-GNULIB_WCTRANS = @GNULIB_WCTRANS@ +-GNULIB_WCTYPE = @GNULIB_WCTYPE@ +-GNULIB_WCWIDTH = @GNULIB_WCWIDTH@ +-GNULIB_WMEMCHR = @GNULIB_WMEMCHR@ +-GNULIB_WMEMCMP = @GNULIB_WMEMCMP@ +-GNULIB_WMEMCPY = @GNULIB_WMEMCPY@ +-GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@ +-GNULIB_WMEMSET = @GNULIB_WMEMSET@ +-GREP = @GREP@ +-HAVE_BTOWC = @HAVE_BTOWC@ +-HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@ +-HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@ +-HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@ +-HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@ +-HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@ +-HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@ +-HAVE_FEATURES_H = @HAVE_FEATURES_H@ +-HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +-HAVE_ISWBLANK = @HAVE_ISWBLANK@ +-HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ +-HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +-HAVE_MBRLEN = @HAVE_MBRLEN@ +-HAVE_MBRTOWC = @HAVE_MBRTOWC@ +-HAVE_MBSINIT = @HAVE_MBSINIT@ +-HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@ +-HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@ +-HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +-HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +-HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +-HAVE_STDINT_H = @HAVE_STDINT_H@ +-HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +-HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +-HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +-HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +-HAVE_WCHAR_H = @HAVE_WCHAR_H@ +-HAVE_WCHAR_T = @HAVE_WCHAR_T@ +-HAVE_WCPCPY = @HAVE_WCPCPY@ +-HAVE_WCPNCPY = @HAVE_WCPNCPY@ +-HAVE_WCRTOMB = @HAVE_WCRTOMB@ +-HAVE_WCSCASECMP = @HAVE_WCSCASECMP@ +-HAVE_WCSCAT = @HAVE_WCSCAT@ +-HAVE_WCSCHR = @HAVE_WCSCHR@ +-HAVE_WCSCMP = @HAVE_WCSCMP@ +-HAVE_WCSCOLL = @HAVE_WCSCOLL@ +-HAVE_WCSCPY = @HAVE_WCSCPY@ +-HAVE_WCSCSPN = @HAVE_WCSCSPN@ +-HAVE_WCSDUP = @HAVE_WCSDUP@ +-HAVE_WCSLEN = @HAVE_WCSLEN@ +-HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@ +-HAVE_WCSNCAT = @HAVE_WCSNCAT@ +-HAVE_WCSNCMP = @HAVE_WCSNCMP@ +-HAVE_WCSNCPY = @HAVE_WCSNCPY@ +-HAVE_WCSNLEN = @HAVE_WCSNLEN@ +-HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@ +-HAVE_WCSPBRK = @HAVE_WCSPBRK@ +-HAVE_WCSRCHR = @HAVE_WCSRCHR@ +-HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@ +-HAVE_WCSSPN = @HAVE_WCSSPN@ +-HAVE_WCSSTR = @HAVE_WCSSTR@ +-HAVE_WCSTOK = @HAVE_WCSTOK@ +-HAVE_WCSWIDTH = @HAVE_WCSWIDTH@ +-HAVE_WCSXFRM = @HAVE_WCSXFRM@ +-HAVE_WCTRANS_T = @HAVE_WCTRANS_T@ +-HAVE_WCTYPE_H = @HAVE_WCTYPE_H@ +-HAVE_WCTYPE_T = @HAVE_WCTYPE_T@ +-HAVE_WINT_T = @HAVE_WINT_T@ +-HAVE_WMEMCHR = @HAVE_WMEMCHR@ +-HAVE_WMEMCMP = @HAVE_WMEMCMP@ +-HAVE_WMEMCPY = @HAVE_WMEMCPY@ +-HAVE_WMEMMOVE = @HAVE_WMEMMOVE@ +-HAVE_WMEMSET = @HAVE_WMEMSET@ +-HAVE__BOOL = @HAVE__BOOL@ +-INCLUDE_NEXT = @INCLUDE_NEXT@ +-INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ +-INSTALL = @INSTALL@ +-INSTALL_DATA = @INSTALL_DATA@ +-INSTALL_PROGRAM = @INSTALL_PROGRAM@ +-INSTALL_SCRIPT = @INSTALL_SCRIPT@ +-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +-INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@ +-INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@ +-LDFLAGS = @LDFLAGS@ +-LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +-LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +-LIBOBJS = @LIBOBJS@ +-LIBS = @LIBS@ +-LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@ +-LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@ +-LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ +-LTLIBOBJS = @LTLIBOBJS@ +-MAKEINFO = @MAKEINFO@ +-MKDIR_P = @MKDIR_P@ +-NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@ +-NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@ +-NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@ +-NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@ +-NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@ +-NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ +-NEXT_STDDEF_H = @NEXT_STDDEF_H@ +-NEXT_STDINT_H = @NEXT_STDINT_H@ +-NEXT_WCHAR_H = @NEXT_WCHAR_H@ +-NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ +-OBJEXT = @OBJEXT@ +-PACKAGE = @PACKAGE@ +-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +-PACKAGE_NAME = @PACKAGE_NAME@ +-PACKAGE_STRING = @PACKAGE_STRING@ +-PACKAGE_TARNAME = @PACKAGE_TARNAME@ +-PACKAGE_URL = @PACKAGE_URL@ +-PACKAGE_VERSION = @PACKAGE_VERSION@ +-PATH_SEPARATOR = @PATH_SEPARATOR@ +-PRAGMA_COLUMNS = @PRAGMA_COLUMNS@ +-PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ +-PRIPTR_PREFIX = @PRIPTR_PREFIX@ +-PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ +-PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +-RANLIB = @RANLIB@ +-REPLACE_BTOWC = @REPLACE_BTOWC@ +-REPLACE_ISWBLANK = @REPLACE_ISWBLANK@ +-REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@ +-REPLACE_MBRLEN = @REPLACE_MBRLEN@ +-REPLACE_MBRTOWC = @REPLACE_MBRTOWC@ +-REPLACE_MBSINIT = @REPLACE_MBSINIT@ +-REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@ +-REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@ +-REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@ +-REPLACE_NULL = @REPLACE_NULL@ +-REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@ +-REPLACE_TOWLOWER = @REPLACE_TOWLOWER@ +-REPLACE_WCRTOMB = @REPLACE_WCRTOMB@ +-REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@ +-REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@ +-REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@ +-REPLACE_WCTOB = @REPLACE_WCTOB@ +-REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ +-SET_MAKE = @SET_MAKE@ +-SHELL = @SHELL@ +-SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +-SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +-STDBOOL_H = @STDBOOL_H@ +-STDDEF_H = @STDDEF_H@ +-STDINT_H = @STDINT_H@ +-STRIP = @STRIP@ +-UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ +-UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ +-VERSION = @VERSION@ +-WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +-WINT_T_SUFFIX = @WINT_T_SUFFIX@ +-abs_builddir = @abs_builddir@ +-abs_srcdir = @abs_srcdir@ +-abs_top_builddir = @abs_top_builddir@ +-abs_top_srcdir = @abs_top_srcdir@ +-ac_ct_CC = @ac_ct_CC@ +-am__include = @am__include@ +-am__leading_dot = @am__leading_dot@ +-am__quote = @am__quote@ +-am__tar = @am__tar@ +-am__untar = @am__untar@ +-bindir = @bindir@ +-build = @build@ +-build_alias = @build_alias@ +-build_cpu = @build_cpu@ +-build_os = @build_os@ +-build_vendor = @build_vendor@ +-builddir = @builddir@ +-datadir = @datadir@ +-datarootdir = @datarootdir@ +-docdir = @docdir@ +-dvidir = @dvidir@ +-exec_prefix = @exec_prefix@ +-gl_LIBOBJS = @gl_LIBOBJS@ +-gl_LTLIBOBJS = @gl_LTLIBOBJS@ +-host = @host@ +-host_alias = @host_alias@ +-host_cpu = @host_cpu@ +-host_os = @host_os@ +-host_vendor = @host_vendor@ +-htmldir = @htmldir@ +-includedir = @includedir@ +-infodir = @infodir@ +-install_sh = @install_sh@ +-libdir = @libdir@ +-libexecdir = @libexecdir@ +-lispdir = @lispdir@ +-localedir = @localedir@ +-localstatedir = @localstatedir@ +-mandir = @mandir@ +-mkdir_p = @mkdir_p@ +-oldincludedir = @oldincludedir@ +-pdfdir = @pdfdir@ +-prefix = @prefix@ +-program_transform_name = @program_transform_name@ +-psdir = @psdir@ +-runstatedir = @runstatedir@ +-sbindir = @sbindir@ +-sharedstatedir = @sharedstatedir@ +-srcdir = @srcdir@ +-sysconfdir = @sysconfdir@ +-target_alias = @target_alias@ +-top_build_prefix = @top_build_prefix@ +-top_builddir = @top_builddir@ +-top_srcdir = @top_srcdir@ +-EXTRA_DIST = 00gnulib.m4 codeset.m4 configmake.m4 extensions.m4 \ +- extern-inline.m4 fcntl-o.m4 glibc21.m4 gnulib-common.m4 \ +- include_next.m4 inttypes-pri.m4 inttypes.m4 \ +- libunistring-base.m4 localcharset.m4 longlong.m4 multiarch.m4 \ +- stdbool.m4 stddef_h.m4 stdint.m4 warn-on-use.m4 wchar_h.m4 \ +- wchar_t.m4 wctype_h.m4 wcwidth.m4 wint_t.m4 +-all: all-am +- +-.SUFFIXES: +-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +- @for dep in $?; do \ +- case '$(am__configure_deps)' in \ +- *$$dep*) \ +- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ +- && { if test -f $@; then exit 0; else break; fi; }; \ +- exit 1;; \ +- esac; \ +- done; \ +- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile'; \ +- $(am__cd) $(top_srcdir) && \ +- $(AUTOMAKE) --gnu m4/Makefile +-.PRECIOUS: Makefile +-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status +- @case '$?' in \ +- *config.status*) \ +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ +- *) \ +- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ +- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ +- esac; +- +-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +- +-$(top_srcdir)/configure: $(am__configure_deps) +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +-$(ACLOCAL_M4): $(am__aclocal_m4_deps) +- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +-$(am__aclocal_m4_deps): +-tags TAGS: +- +-ctags CTAGS: +- +-cscope cscopelist: +- +- +-distdir: $(DISTFILES) +- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +- list='$(DISTFILES)'; \ +- dist_files=`for file in $$list; do echo $$file; done | \ +- sed -e "s|^$$srcdirstrip/||;t" \ +- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ +- case $$dist_files in \ +- */*) $(MKDIR_P) `echo "$$dist_files" | \ +- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ +- sort -u` ;; \ +- esac; \ +- for file in $$dist_files; do \ +- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ +- if test -d $$d/$$file; then \ +- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ +- if test -d "$(distdir)/$$file"; then \ +- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +- fi; \ +- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ +- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ +- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +- fi; \ +- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ +- else \ +- test -f "$(distdir)/$$file" \ +- || cp -p $$d/$$file "$(distdir)/$$file" \ +- || exit 1; \ +- fi; \ +- done +-check-am: all-am +-check: check-am +-all-am: Makefile +-installdirs: +-install: install-am +-install-exec: install-exec-am +-install-data: install-data-am +-uninstall: uninstall-am +- +-install-am: all-am +- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +- +-installcheck: installcheck-am +-install-strip: +- if test -z '$(STRIP)'; then \ +- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +- install; \ +- else \ +- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ +- fi +-mostlyclean-generic: +- +-clean-generic: +- +-distclean-generic: +- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) +- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) +- +-maintainer-clean-generic: +- @echo "This command is intended for maintainers to use" +- @echo "it deletes files that may require special tools to rebuild." +-clean: clean-am +- +-clean-am: clean-generic mostlyclean-am +- +-distclean: distclean-am +- -rm -f Makefile +-distclean-am: clean-am distclean-generic +- +-dvi: dvi-am +- +-dvi-am: +- +-html: html-am +- +-html-am: +- +-info: info-am +- +-info-am: +- +-install-data-am: +- +-install-dvi: install-dvi-am +- +-install-dvi-am: +- +-install-exec-am: +- +-install-html: install-html-am +- +-install-html-am: +- +-install-info: install-info-am +- +-install-info-am: +- +-install-man: +- +-install-pdf: install-pdf-am +- +-install-pdf-am: +- +-install-ps: install-ps-am +- +-install-ps-am: +- +-installcheck-am: +- +-maintainer-clean: maintainer-clean-am +- -rm -f Makefile +-maintainer-clean-am: distclean-am maintainer-clean-generic +- +-mostlyclean: mostlyclean-am +- +-mostlyclean-am: mostlyclean-generic +- +-pdf: pdf-am +- +-pdf-am: +- +-ps: ps-am +- +-ps-am: +- +-uninstall-am: +- +-.MAKE: install-am install-strip +- +-.PHONY: all all-am check check-am clean clean-generic cscopelist-am \ +- ctags-am distclean distclean-generic distdir dvi dvi-am html \ +- html-am info info-am install install-am install-data \ +- install-data-am install-dvi install-dvi-am install-exec \ +- install-exec-am install-html install-html-am install-info \ +- install-info-am install-man install-pdf install-pdf-am \ +- install-ps install-ps-am install-strip installcheck \ +- installcheck-am installdirs maintainer-clean \ +- maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ +- pdf-am ps ps-am tags-am uninstall uninstall-am +- +- +-# Tell versions [3.59,3.63) of GNU make to not export all variables. +-# Otherwise a system limit (for SysV at least) may be exceeded. +-.NOEXPORT: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/multiarch.m4 groff-1.22.3/src/libs/gnulib/m4/multiarch.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/multiarch.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/multiarch.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,62 +0,0 @@ +-# multiarch.m4 serial 7 +-dnl Copyright (C) 2008-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-# Determine whether the compiler is or may be producing universal binaries. +-# +-# On Mac OS X 10.5 and later systems, the user can create libraries and +-# executables that work on multiple system types--known as "fat" or +-# "universal" binaries--by specifying multiple '-arch' options to the +-# compiler but only a single '-arch' option to the preprocessor. Like +-# this: +-# +-# ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ +-# CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ +-# CPP="gcc -E" CXXCPP="g++ -E" +-# +-# Detect this situation and set APPLE_UNIVERSAL_BUILD accordingly. +- +-AC_DEFUN_ONCE([gl_MULTIARCH], +-[ +- dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN. +- gl_cv_c_multiarch=no +- AC_COMPILE_IFELSE( +- [AC_LANG_SOURCE( +- [[#ifndef __APPLE_CC__ +- not a universal capable compiler +- #endif +- typedef int dummy; +- ]])], +- [ +- dnl Check for potential -arch flags. It is not universal unless +- dnl there are at least two -arch flags with different values. +- arch= +- prev= +- for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do +- if test -n "$prev"; then +- case $word in +- i?86 | x86_64 | ppc | ppc64) +- if test -z "$arch" || test "$arch" = "$word"; then +- arch="$word" +- else +- gl_cv_c_multiarch=yes +- fi +- ;; +- esac +- prev= +- else +- if test "x$word" = "x-arch"; then +- prev=arch +- fi +- fi +- done +- ]) +- if test $gl_cv_c_multiarch = yes; then +- APPLE_UNIVERSAL_BUILD=1 +- else +- APPLE_UNIVERSAL_BUILD=0 +- fi +- AC_SUBST([APPLE_UNIVERSAL_BUILD]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/onceonly.m4 groff-1.22.3/src/libs/gnulib/m4/onceonly.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/onceonly.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/onceonly.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,104 +0,0 @@ +-# onceonly.m4 serial 9 +-dnl Copyright (C) 2002-2003, 2005-2006, 2008-2014 Free Software Foundation, +-dnl Inc. +-dnl +-dnl This file is free software; you can redistribute it and/or modify +-dnl it under the terms of the GNU General Public License as published by +-dnl the Free Software Foundation; either version 3 of the License, or +-dnl (at your option) any later version. +-dnl +-dnl This file is distributed in the hope that it will be useful, +-dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +-dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-dnl GNU General Public License for more details. +-dnl +-dnl You should have received a copy of the GNU General Public License +-dnl along with this file. If not, see . +-dnl +-dnl As a special exception to the GNU General Public License, +-dnl this file may be distributed as part of a program +-dnl that contains a configuration script generated by Autoconf, under +-dnl the same distribution terms as the rest of that program. +- +-dnl This file defines some "once only" variants of standard autoconf macros. +-dnl AC_CHECK_HEADERS_ONCE like AC_CHECK_HEADERS +-dnl AC_CHECK_FUNCS_ONCE like AC_CHECK_FUNCS +-dnl AC_CHECK_DECLS_ONCE like AC_CHECK_DECLS +-dnl AC_REQUIRE([AC_FUNC_STRCOLL]) like AC_FUNC_STRCOLL +-dnl The advantage is that the check for each of the headers/functions/decls +-dnl will be put only once into the 'configure' file. It keeps the size of +-dnl the 'configure' file down, and avoids redundant output when 'configure' +-dnl is run. +-dnl The drawback is that the checks cannot be conditionalized. If you write +-dnl if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi +-dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to +-dnl empty, and the check will be inserted before the body of the AC_DEFUNed +-dnl function. +- +-dnl The original code implemented AC_CHECK_HEADERS_ONCE and AC_CHECK_FUNCS_ONCE +-dnl in terms of AC_DEFUN and AC_REQUIRE. This implementation uses diversions to +-dnl named sections DEFAULTS and INIT_PREPARE in order to check all requested +-dnl headers at once, thus reducing the size of 'configure'. It is known to work +-dnl with autoconf 2.57..2.62 at least . The size reduction is ca. 9%. +- +-dnl Autoconf version 2.59 plus gnulib is required; this file is not needed +-dnl with Autoconf 2.60 or greater. But note that autoconf's implementation of +-dnl AC_CHECK_DECLS_ONCE expects a comma-separated list of symbols as first +-dnl argument! +-AC_PREREQ([2.59]) +- +-# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of +-# AC_CHECK_HEADERS(HEADER1 HEADER2 ...). +-AC_DEFUN([AC_CHECK_HEADERS_ONCE], [ +- : +- m4_foreach_w([gl_HEADER_NAME], [$1], [ +- AC_DEFUN([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, +- [./-], [___])), [ +- m4_divert_text([INIT_PREPARE], +- [gl_header_list="$gl_header_list gl_HEADER_NAME"]) +- gl_HEADERS_EXPANSION +- AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_HEADER_NAME])), +- [Define to 1 if you have the <]m4_defn([gl_HEADER_NAME])[> header file.]) +- ]) +- AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, +- [./-], [___]))) +- ]) +-]) +-m4_define([gl_HEADERS_EXPANSION], [ +- m4_divert_text([DEFAULTS], [gl_header_list=]) +- AC_CHECK_HEADERS([$gl_header_list]) +- m4_define([gl_HEADERS_EXPANSION], []) +-]) +- +-# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of +-# AC_CHECK_FUNCS(FUNC1 FUNC2 ...). +-AC_DEFUN([AC_CHECK_FUNCS_ONCE], [ +- : +- m4_foreach_w([gl_FUNC_NAME], [$1], [ +- AC_DEFUN([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME]), [ +- m4_divert_text([INIT_PREPARE], +- [gl_func_list="$gl_func_list gl_FUNC_NAME"]) +- gl_FUNCS_EXPANSION +- AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_FUNC_NAME])), +- [Define to 1 if you have the ']m4_defn([gl_FUNC_NAME])[' function.]) +- ]) +- AC_REQUIRE([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME])) +- ]) +-]) +-m4_define([gl_FUNCS_EXPANSION], [ +- m4_divert_text([DEFAULTS], [gl_func_list=]) +- AC_CHECK_FUNCS([$gl_func_list]) +- m4_define([gl_FUNCS_EXPANSION], []) +-]) +- +-# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of +-# AC_CHECK_DECLS(DECL1, DECL2, ...). +-AC_DEFUN([AC_CHECK_DECLS_ONCE], [ +- : +- m4_foreach_w([gl_DECL_NAME], [$1], [ +- AC_DEFUN([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME]), [ +- AC_CHECK_DECLS(m4_defn([gl_DECL_NAME])) +- ]) +- AC_REQUIRE([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME])) +- ]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/stdbool.m4 groff-1.22.3/src/libs/gnulib/m4/stdbool.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/stdbool.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/stdbool.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,100 +0,0 @@ +-# Check for stdbool.h that conforms to C99. +- +-dnl Copyright (C) 2002-2006, 2009-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-#serial 5 +- +-# Prepare for substituting if it is not supported. +- +-AC_DEFUN([AM_STDBOOL_H], +-[ +- AC_REQUIRE([AC_CHECK_HEADER_STDBOOL]) +- +- # Define two additional variables used in the Makefile substitution. +- +- if test "$ac_cv_header_stdbool_h" = yes; then +- STDBOOL_H='' +- else +- STDBOOL_H='stdbool.h' +- fi +- AC_SUBST([STDBOOL_H]) +- AM_CONDITIONAL([GL_GENERATE_STDBOOL_H], [test -n "$STDBOOL_H"]) +- +- if test "$ac_cv_type__Bool" = yes; then +- HAVE__BOOL=1 +- else +- HAVE__BOOL=0 +- fi +- AC_SUBST([HAVE__BOOL]) +-]) +- +-# AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future. +-AC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H]) +- +-# This version of the macro is needed in autoconf <= 2.68. +- +-AC_DEFUN([AC_CHECK_HEADER_STDBOOL], +- [AC_CACHE_CHECK([for stdbool.h that conforms to C99], +- [ac_cv_header_stdbool_h], +- [AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM( +- [[ +- #include +- #ifndef bool +- "error: bool is not defined" +- #endif +- #ifndef false +- "error: false is not defined" +- #endif +- #if false +- "error: false is not 0" +- #endif +- #ifndef true +- "error: true is not defined" +- #endif +- #if true != 1 +- "error: true is not 1" +- #endif +- #ifndef __bool_true_false_are_defined +- "error: __bool_true_false_are_defined is not defined" +- #endif +- +- struct s { _Bool s: 1; _Bool t; } s; +- +- char a[true == 1 ? 1 : -1]; +- char b[false == 0 ? 1 : -1]; +- char c[__bool_true_false_are_defined == 1 ? 1 : -1]; +- char d[(bool) 0.5 == true ? 1 : -1]; +- /* See body of main program for 'e'. */ +- char f[(_Bool) 0.0 == false ? 1 : -1]; +- char g[true]; +- char h[sizeof (_Bool)]; +- char i[sizeof s.t]; +- enum { j = false, k = true, l = false * true, m = true * 256 }; +- /* The following fails for +- HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ +- _Bool n[m]; +- char o[sizeof n == m * sizeof n[0] ? 1 : -1]; +- char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; +- /* Catch a bug in an HP-UX C compiler. See +- http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html +- http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html +- */ +- _Bool q = true; +- _Bool *pq = &q; +- ]], +- [[ +- bool e = &s; +- *pq |= q; +- *pq |= ! q; +- /* Refer to every declared value, to avoid compiler optimizations. */ +- return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l +- + !m + !n + !o + !p + !q + !pq); +- ]])], +- [ac_cv_header_stdbool_h=yes], +- [ac_cv_header_stdbool_h=no])]) +- AC_CHECK_TYPES([_Bool]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/stddef_h.m4 groff-1.22.3/src/libs/gnulib/m4/stddef_h.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/stddef_h.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/stddef_h.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,47 +0,0 @@ +-dnl A placeholder for POSIX 2008 , for platforms that have issues. +-# stddef_h.m4 serial 4 +-dnl Copyright (C) 2009-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-AC_DEFUN([gl_STDDEF_H], +-[ +- AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) +- AC_REQUIRE([gt_TYPE_WCHAR_T]) +- STDDEF_H= +- if test $gt_cv_c_wchar_t = no; then +- HAVE_WCHAR_T=0 +- STDDEF_H=stddef.h +- fi +- AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions], +- [gl_cv_decl_null_works], +- [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +- int test[2 * (sizeof NULL == sizeof (void *)) -1]; +-]])], +- [gl_cv_decl_null_works=yes], +- [gl_cv_decl_null_works=no])]) +- if test $gl_cv_decl_null_works = no; then +- REPLACE_NULL=1 +- STDDEF_H=stddef.h +- fi +- AC_SUBST([STDDEF_H]) +- AM_CONDITIONAL([GL_GENERATE_STDDEF_H], [test -n "$STDDEF_H"]) +- if test -n "$STDDEF_H"; then +- gl_NEXT_HEADERS([stddef.h]) +- fi +-]) +- +-AC_DEFUN([gl_STDDEF_MODULE_INDICATOR], +-[ +- dnl Use AC_REQUIRE here, so that the default settings are expanded once only. +- AC_REQUIRE([gl_STDDEF_H_DEFAULTS]) +- gl_MODULE_INDICATOR_SET_VARIABLE([$1]) +-]) +- +-AC_DEFUN([gl_STDDEF_H_DEFAULTS], +-[ +- dnl Assume proper GNU behavior unless another module says otherwise. +- REPLACE_NULL=0; AC_SUBST([REPLACE_NULL]) +- HAVE_WCHAR_T=1; AC_SUBST([HAVE_WCHAR_T]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/stdint.m4 groff-1.22.3/src/libs/gnulib/m4/stdint.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/stdint.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/stdint.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,484 +0,0 @@ +-# stdint.m4 serial 43 +-dnl Copyright (C) 2001-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Paul Eggert and Bruno Haible. +-dnl Test whether is supported or must be substituted. +- +-AC_DEFUN_ONCE([gl_STDINT_H], +-[ +- AC_PREREQ([2.59])dnl +- +- dnl Check for long long int and unsigned long long int. +- AC_REQUIRE([AC_TYPE_LONG_LONG_INT]) +- if test $ac_cv_type_long_long_int = yes; then +- HAVE_LONG_LONG_INT=1 +- else +- HAVE_LONG_LONG_INT=0 +- fi +- AC_SUBST([HAVE_LONG_LONG_INT]) +- AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT]) +- if test $ac_cv_type_unsigned_long_long_int = yes; then +- HAVE_UNSIGNED_LONG_LONG_INT=1 +- else +- HAVE_UNSIGNED_LONG_LONG_INT=0 +- fi +- AC_SUBST([HAVE_UNSIGNED_LONG_LONG_INT]) +- +- dnl Check for , in the same way as gl_WCHAR_H does. +- AC_CHECK_HEADERS_ONCE([wchar.h]) +- if test $ac_cv_header_wchar_h = yes; then +- HAVE_WCHAR_H=1 +- else +- HAVE_WCHAR_H=0 +- fi +- AC_SUBST([HAVE_WCHAR_H]) +- +- dnl Check for . +- dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_inttypes_h. +- if test $ac_cv_header_inttypes_h = yes; then +- HAVE_INTTYPES_H=1 +- else +- HAVE_INTTYPES_H=0 +- fi +- AC_SUBST([HAVE_INTTYPES_H]) +- +- dnl Check for . +- dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_sys_types_h. +- if test $ac_cv_header_sys_types_h = yes; then +- HAVE_SYS_TYPES_H=1 +- else +- HAVE_SYS_TYPES_H=0 +- fi +- AC_SUBST([HAVE_SYS_TYPES_H]) +- +- gl_CHECK_NEXT_HEADERS([stdint.h]) +- if test $ac_cv_header_stdint_h = yes; then +- HAVE_STDINT_H=1 +- else +- HAVE_STDINT_H=0 +- fi +- AC_SUBST([HAVE_STDINT_H]) +- +- dnl Now see whether we need a substitute . +- if test $ac_cv_header_stdint_h = yes; then +- AC_CACHE_CHECK([whether stdint.h conforms to C99], +- [gl_cv_header_working_stdint_h], +- [gl_cv_header_working_stdint_h=no +- AC_COMPILE_IFELSE([ +- AC_LANG_PROGRAM([[ +-#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +-#include +-/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in . */ +-#if !(defined WCHAR_MIN && defined WCHAR_MAX) +-#error "WCHAR_MIN, WCHAR_MAX not defined in " +-#endif +-] +-gl_STDINT_INCLUDES +-[ +-#ifdef INT8_MAX +-int8_t a1 = INT8_MAX; +-int8_t a1min = INT8_MIN; +-#endif +-#ifdef INT16_MAX +-int16_t a2 = INT16_MAX; +-int16_t a2min = INT16_MIN; +-#endif +-#ifdef INT32_MAX +-int32_t a3 = INT32_MAX; +-int32_t a3min = INT32_MIN; +-#endif +-#ifdef INT64_MAX +-int64_t a4 = INT64_MAX; +-int64_t a4min = INT64_MIN; +-#endif +-#ifdef UINT8_MAX +-uint8_t b1 = UINT8_MAX; +-#else +-typedef int b1[(unsigned char) -1 != 255 ? 1 : -1]; +-#endif +-#ifdef UINT16_MAX +-uint16_t b2 = UINT16_MAX; +-#endif +-#ifdef UINT32_MAX +-uint32_t b3 = UINT32_MAX; +-#endif +-#ifdef UINT64_MAX +-uint64_t b4 = UINT64_MAX; +-#endif +-int_least8_t c1 = INT8_C (0x7f); +-int_least8_t c1max = INT_LEAST8_MAX; +-int_least8_t c1min = INT_LEAST8_MIN; +-int_least16_t c2 = INT16_C (0x7fff); +-int_least16_t c2max = INT_LEAST16_MAX; +-int_least16_t c2min = INT_LEAST16_MIN; +-int_least32_t c3 = INT32_C (0x7fffffff); +-int_least32_t c3max = INT_LEAST32_MAX; +-int_least32_t c3min = INT_LEAST32_MIN; +-int_least64_t c4 = INT64_C (0x7fffffffffffffff); +-int_least64_t c4max = INT_LEAST64_MAX; +-int_least64_t c4min = INT_LEAST64_MIN; +-uint_least8_t d1 = UINT8_C (0xff); +-uint_least8_t d1max = UINT_LEAST8_MAX; +-uint_least16_t d2 = UINT16_C (0xffff); +-uint_least16_t d2max = UINT_LEAST16_MAX; +-uint_least32_t d3 = UINT32_C (0xffffffff); +-uint_least32_t d3max = UINT_LEAST32_MAX; +-uint_least64_t d4 = UINT64_C (0xffffffffffffffff); +-uint_least64_t d4max = UINT_LEAST64_MAX; +-int_fast8_t e1 = INT_FAST8_MAX; +-int_fast8_t e1min = INT_FAST8_MIN; +-int_fast16_t e2 = INT_FAST16_MAX; +-int_fast16_t e2min = INT_FAST16_MIN; +-int_fast32_t e3 = INT_FAST32_MAX; +-int_fast32_t e3min = INT_FAST32_MIN; +-int_fast64_t e4 = INT_FAST64_MAX; +-int_fast64_t e4min = INT_FAST64_MIN; +-uint_fast8_t f1 = UINT_FAST8_MAX; +-uint_fast16_t f2 = UINT_FAST16_MAX; +-uint_fast32_t f3 = UINT_FAST32_MAX; +-uint_fast64_t f4 = UINT_FAST64_MAX; +-#ifdef INTPTR_MAX +-intptr_t g = INTPTR_MAX; +-intptr_t gmin = INTPTR_MIN; +-#endif +-#ifdef UINTPTR_MAX +-uintptr_t h = UINTPTR_MAX; +-#endif +-intmax_t i = INTMAX_MAX; +-uintmax_t j = UINTMAX_MAX; +- +-#include /* for CHAR_BIT */ +-#define TYPE_MINIMUM(t) \ +- ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t))) +-#define TYPE_MAXIMUM(t) \ +- ((t) ((t) 0 < (t) -1 \ +- ? (t) -1 \ +- : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) +-struct s { +- int check_PTRDIFF: +- PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t) +- && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t) +- ? 1 : -1; +- /* Detect bug in FreeBSD 6.0 / ia64. */ +- int check_SIG_ATOMIC: +- SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t) +- && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t) +- ? 1 : -1; +- int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1; +- int check_WCHAR: +- WCHAR_MIN == TYPE_MINIMUM (wchar_t) +- && WCHAR_MAX == TYPE_MAXIMUM (wchar_t) +- ? 1 : -1; +- /* Detect bug in mingw. */ +- int check_WINT: +- WINT_MIN == TYPE_MINIMUM (wint_t) +- && WINT_MAX == TYPE_MAXIMUM (wint_t) +- ? 1 : -1; +- +- /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */ +- int check_UINT8_C: +- (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1; +- int check_UINT16_C: +- (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1; +- +- /* Detect bugs in OpenBSD 3.9 stdint.h. */ +-#ifdef UINT8_MAX +- int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1; +-#endif +-#ifdef UINT16_MAX +- int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1; +-#endif +-#ifdef UINT32_MAX +- int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1; +-#endif +-#ifdef UINT64_MAX +- int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1; +-#endif +- int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1; +- int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1; +- int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1; +- int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1; +- int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1; +- int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1; +- int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1; +- int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1; +- int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1; +- int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1; +- int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1; +-}; +- ]])], +- [dnl Determine whether the various *_MIN, *_MAX macros are usable +- dnl in preprocessor expression. We could do it by compiling a test +- dnl program for each of these macros. It is faster to run a program +- dnl that inspects the macro expansion. +- dnl This detects a bug on HP-UX 11.23/ia64. +- AC_RUN_IFELSE([ +- AC_LANG_PROGRAM([[ +-#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */ +-#include +-] +-gl_STDINT_INCLUDES +-[ +-#include +-#include +-#define MVAL(macro) MVAL1(macro) +-#define MVAL1(expression) #expression +-static const char *macro_values[] = +- { +-#ifdef INT8_MAX +- MVAL (INT8_MAX), +-#endif +-#ifdef INT16_MAX +- MVAL (INT16_MAX), +-#endif +-#ifdef INT32_MAX +- MVAL (INT32_MAX), +-#endif +-#ifdef INT64_MAX +- MVAL (INT64_MAX), +-#endif +-#ifdef UINT8_MAX +- MVAL (UINT8_MAX), +-#endif +-#ifdef UINT16_MAX +- MVAL (UINT16_MAX), +-#endif +-#ifdef UINT32_MAX +- MVAL (UINT32_MAX), +-#endif +-#ifdef UINT64_MAX +- MVAL (UINT64_MAX), +-#endif +- NULL +- }; +-]], [[ +- const char **mv; +- for (mv = macro_values; *mv != NULL; mv++) +- { +- const char *value = *mv; +- /* Test whether it looks like a cast expression. */ +- if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0 +- || strncmp (value, "((unsigned short)"/*)*/, 17) == 0 +- || strncmp (value, "((unsigned char)"/*)*/, 16) == 0 +- || strncmp (value, "((int)"/*)*/, 6) == 0 +- || strncmp (value, "((signed short)"/*)*/, 15) == 0 +- || strncmp (value, "((signed char)"/*)*/, 14) == 0) +- return mv - macro_values + 1; +- } +- return 0; +-]])], +- [gl_cv_header_working_stdint_h=yes], +- [], +- [dnl When cross-compiling, assume it works. +- gl_cv_header_working_stdint_h=yes +- ]) +- ]) +- ]) +- fi +- if test "$gl_cv_header_working_stdint_h" = yes; then +- STDINT_H= +- else +- dnl Check for , and for +- dnl (used in Linux libc4 >= 4.6.7 and libc5). +- AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h]) +- if test $ac_cv_header_sys_inttypes_h = yes; then +- HAVE_SYS_INTTYPES_H=1 +- else +- HAVE_SYS_INTTYPES_H=0 +- fi +- AC_SUBST([HAVE_SYS_INTTYPES_H]) +- if test $ac_cv_header_sys_bitypes_h = yes; then +- HAVE_SYS_BITYPES_H=1 +- else +- HAVE_SYS_BITYPES_H=0 +- fi +- AC_SUBST([HAVE_SYS_BITYPES_H]) +- +- gl_STDINT_TYPE_PROPERTIES +- STDINT_H=stdint.h +- fi +- AC_SUBST([STDINT_H]) +- AM_CONDITIONAL([GL_GENERATE_STDINT_H], [test -n "$STDINT_H"]) +-]) +- +-dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES) +-dnl Determine the size of each of the given types in bits. +-AC_DEFUN([gl_STDINT_BITSIZEOF], +-[ +- dnl Use a shell loop, to avoid bloating configure, and +- dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into +- dnl config.h.in, +- dnl - extra AC_SUBST calls, so that the right substitutions are made. +- m4_foreach_w([gltype], [$1], +- [AH_TEMPLATE([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), +- [Define to the number of bits in type ']gltype['.])]) +- for gltype in $1 ; do +- AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}], +- [AC_COMPUTE_INT([result], [sizeof ($gltype) * CHAR_BIT], +- [$2 +-#include ], [result=unknown]) +- eval gl_cv_bitsizeof_${gltype}=\$result +- ]) +- eval result=\$gl_cv_bitsizeof_${gltype} +- if test $result = unknown; then +- dnl Use a nonempty default, because some compilers, such as IRIX 5 cc, +- dnl do a syntax check even on unused #if conditions and give an error +- dnl on valid C code like this: +- dnl #if 0 +- dnl # if > 32 +- dnl # endif +- dnl #endif +- result=0 +- fi +- GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` +- AC_DEFINE_UNQUOTED([BITSIZEOF_${GLTYPE}], [$result]) +- eval BITSIZEOF_${GLTYPE}=\$result +- done +- m4_foreach_w([gltype], [$1], +- [AC_SUBST([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) +-]) +- +-dnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES) +-dnl Determine the signedness of each of the given types. +-dnl Define HAVE_SIGNED_TYPE if type is signed. +-AC_DEFUN([gl_CHECK_TYPES_SIGNED], +-[ +- dnl Use a shell loop, to avoid bloating configure, and +- dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into +- dnl config.h.in, +- dnl - extra AC_SUBST calls, so that the right substitutions are made. +- m4_foreach_w([gltype], [$1], +- [AH_TEMPLATE([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]), +- [Define to 1 if ']gltype[' is a signed integer type.])]) +- for gltype in $1 ; do +- AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed], +- [AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM([$2[ +- int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];]])], +- result=yes, result=no) +- eval gl_cv_type_${gltype}_signed=\$result +- ]) +- eval result=\$gl_cv_type_${gltype}_signed +- GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` +- if test "$result" = yes; then +- AC_DEFINE_UNQUOTED([HAVE_SIGNED_${GLTYPE}], [1]) +- eval HAVE_SIGNED_${GLTYPE}=1 +- else +- eval HAVE_SIGNED_${GLTYPE}=0 +- fi +- done +- m4_foreach_w([gltype], [$1], +- [AC_SUBST([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))]) +-]) +- +-dnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES) +-dnl Determine the suffix to use for integer constants of the given types. +-dnl Define t_SUFFIX for each such type. +-AC_DEFUN([gl_INTEGER_TYPE_SUFFIX], +-[ +- dnl Use a shell loop, to avoid bloating configure, and +- dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into +- dnl config.h.in, +- dnl - extra AC_SUBST calls, so that the right substitutions are made. +- m4_foreach_w([gltype], [$1], +- [AH_TEMPLATE(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX], +- [Define to l, ll, u, ul, ull, etc., as suitable for +- constants of type ']gltype['.])]) +- for gltype in $1 ; do +- AC_CACHE_CHECK([for $gltype integer literal suffix], +- [gl_cv_type_${gltype}_suffix], +- [eval gl_cv_type_${gltype}_suffix=no +- eval result=\$gl_cv_type_${gltype}_signed +- if test "$result" = yes; then +- glsufu= +- else +- glsufu=u +- fi +- for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do +- case $glsuf in +- '') gltype1='int';; +- l) gltype1='long int';; +- ll) gltype1='long long int';; +- i64) gltype1='__int64';; +- u) gltype1='unsigned int';; +- ul) gltype1='unsigned long int';; +- ull) gltype1='unsigned long long int';; +- ui64)gltype1='unsigned __int64';; +- esac +- AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM([$2[ +- extern $gltype foo; +- extern $gltype1 foo;]])], +- [eval gl_cv_type_${gltype}_suffix=\$glsuf]) +- eval result=\$gl_cv_type_${gltype}_suffix +- test "$result" != no && break +- done]) +- GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'` +- eval result=\$gl_cv_type_${gltype}_suffix +- test "$result" = no && result= +- eval ${GLTYPE}_SUFFIX=\$result +- AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], [$result]) +- done +- m4_foreach_w([gltype], [$1], +- [AC_SUBST(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])]) +-]) +- +-dnl gl_STDINT_INCLUDES +-AC_DEFUN([gl_STDINT_INCLUDES], +-[[ +- /* BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +- #include +- #include +- #if HAVE_WCHAR_H +- # include +- # include +- # include +- #endif +-]]) +- +-dnl gl_STDINT_TYPE_PROPERTIES +-dnl Compute HAVE_SIGNED_t, BITSIZEOF_t and t_SUFFIX, for all the types t +-dnl of interest to stdint.in.h. +-AC_DEFUN([gl_STDINT_TYPE_PROPERTIES], +-[ +- AC_REQUIRE([gl_MULTIARCH]) +- if test $APPLE_UNIVERSAL_BUILD = 0; then +- gl_STDINT_BITSIZEOF([ptrdiff_t size_t], +- [gl_STDINT_INCLUDES]) +- fi +- gl_STDINT_BITSIZEOF([sig_atomic_t wchar_t wint_t], +- [gl_STDINT_INCLUDES]) +- gl_CHECK_TYPES_SIGNED([sig_atomic_t wchar_t wint_t], +- [gl_STDINT_INCLUDES]) +- gl_cv_type_ptrdiff_t_signed=yes +- gl_cv_type_size_t_signed=no +- if test $APPLE_UNIVERSAL_BUILD = 0; then +- gl_INTEGER_TYPE_SUFFIX([ptrdiff_t size_t], +- [gl_STDINT_INCLUDES]) +- fi +- gl_INTEGER_TYPE_SUFFIX([sig_atomic_t wchar_t wint_t], +- [gl_STDINT_INCLUDES]) +- +- dnl If wint_t is smaller than 'int', it cannot satisfy the ISO C 99 +- dnl requirement that wint_t is "unchanged by default argument promotions". +- dnl In this case gnulib's and override wint_t. +- dnl Set the variable BITSIZEOF_WINT_T accordingly. +- if test $BITSIZEOF_WINT_T -lt 32; then +- BITSIZEOF_WINT_T=32 +- fi +-]) +- +-dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in. +-dnl Remove this when we can assume autoconf >= 2.61. +-m4_ifdef([AC_COMPUTE_INT], [], [ +- AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])]) +-]) +- +-# Hey Emacs! +-# Local Variables: +-# indent-tabs-mode: nil +-# End: +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/warn-on-use.m4 groff-1.22.3/src/libs/gnulib/m4/warn-on-use.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/warn-on-use.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/warn-on-use.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,47 +0,0 @@ +-# warn-on-use.m4 serial 5 +-dnl Copyright (C) 2010-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-# gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES) +-# --------------------------------------- +-# For each whitespace-separated element in the list of NAMES, define +-# HAVE_RAW_DECL_name if the function has a declaration among INCLUDES +-# even after being undefined as a macro. +-# +-# See warn-on-use.h for some hints on how to poison function names, as +-# well as ideas on poisoning global variables and macros. NAMES may +-# include global variables, but remember that only functions work with +-# _GL_WARN_ON_USE. Typically, INCLUDES only needs to list a single +-# header, but if the replacement header pulls in other headers because +-# some systems declare functions in the wrong header, then INCLUDES +-# should do likewise. +-# +-# It is generally safe to assume declarations for functions declared +-# in the intersection of C89 and C11 (such as printf) without +-# needing gl_WARN_ON_USE_PREPARE. +-AC_DEFUN([gl_WARN_ON_USE_PREPARE], +-[ +- m4_foreach_w([gl_decl], [$2], +- [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])), +- [Define to 1 if ]m4_defn([gl_decl])[ is declared even after +- undefining macros.])])dnl +-dnl FIXME: gl_Symbol must be used unquoted until we can assume +-dnl autoconf 2.64 or newer. +- for gl_func in m4_flatten([$2]); do +- AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl +- AC_CACHE_CHECK([whether $gl_func is declared without a macro], +- gl_Symbol, +- [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1], +-[@%:@undef $gl_func +- (void) $gl_func;])], +- [AS_VAR_SET(gl_Symbol, [yes])], [AS_VAR_SET(gl_Symbol, [no])])]) +- AS_VAR_IF(gl_Symbol, [yes], +- [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1]) +- dnl shortcut - if the raw declaration exists, then set a cache +- dnl variable to allow skipping any later AC_CHECK_DECL efforts +- eval ac_cv_have_decl_$gl_func=yes]) +- AS_VAR_POPDEF([gl_Symbol])dnl +- done +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/wchar_h.m4 groff-1.22.3/src/libs/gnulib/m4/wchar_h.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/wchar_h.m4 2014-11-04 10:38:35.641518796 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/wchar_h.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,225 +0,0 @@ +-dnl A placeholder for ISO C99 , for platforms that have issues. +- +-dnl Copyright (C) 2007-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl Written by Eric Blake. +- +-# wchar_h.m4 serial 39 +- +-AC_DEFUN([gl_WCHAR_H], +-[ +- AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) +- AC_REQUIRE([gl_WCHAR_H_INLINE_OK]) +- dnl Prepare for creating substitute . +- dnl Check for (missing in Linux uClibc when built without wide +- dnl character support). +- dnl is always overridden, because of GNULIB_POSIXCHECK. +- gl_CHECK_NEXT_HEADERS([wchar.h]) +- if test $ac_cv_header_wchar_h = yes; then +- HAVE_WCHAR_H=1 +- else +- HAVE_WCHAR_H=0 +- fi +- AC_SUBST([HAVE_WCHAR_H]) +- +- AC_REQUIRE([gl_FEATURES_H]) +- +- AC_REQUIRE([gt_TYPE_WINT_T]) +- if test $gt_cv_c_wint_t = yes; then +- HAVE_WINT_T=1 +- else +- HAVE_WINT_T=0 +- fi +- AC_SUBST([HAVE_WINT_T]) +- +- dnl Check for declarations of anything we want to poison if the +- dnl corresponding gnulib module is not in use. +- gl_WARN_ON_USE_PREPARE([[ +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-#if !(defined __GLIBC__ && !defined __UCLIBC__) +-# include +-# include +-# include +-#endif +-#include +- ]], +- [btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb +- wcsrtombs wcsnrtombs wcwidth wmemchr wmemcmp wmemcpy wmemmove wmemset +- wcslen wcsnlen wcscpy wcpcpy wcsncpy wcpncpy wcscat wcsncat wcscmp +- wcsncmp wcscasecmp wcsncasecmp wcscoll wcsxfrm wcsdup wcschr wcsrchr +- wcscspn wcsspn wcspbrk wcsstr wcstok wcswidth +- ]) +-]) +- +-dnl Check whether is usable at all. +-AC_DEFUN([gl_WCHAR_H_INLINE_OK], +-[ +- dnl Test whether suffers due to the transition from '__inline' to +- dnl 'gnu_inline'. See +- dnl and . In summary, +- dnl glibc version 2.5 or older, together with gcc version 4.3 or newer and +- dnl the option -std=c99 or -std=gnu99, leads to a broken . +- AC_CACHE_CHECK([whether uses 'inline' correctly], +- [gl_cv_header_wchar_h_correct_inline], +- [gl_cv_header_wchar_h_correct_inline=yes +- AC_LANG_CONFTEST([ +- AC_LANG_SOURCE([[#define wcstod renamed_wcstod +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-#include +-#include +-#include +-#include +-extern int zero (void); +-int main () { return zero(); } +-]])]) +- if AC_TRY_EVAL([ac_compile]); then +- mv conftest.$ac_objext conftest1.$ac_objext +- AC_LANG_CONFTEST([ +- AC_LANG_SOURCE([[#define wcstod renamed_wcstod +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-#include +-#include +-#include +-#include +-int zero (void) { return 0; } +-]])]) +- if AC_TRY_EVAL([ac_compile]); then +- mv conftest.$ac_objext conftest2.$ac_objext +- if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD 2>&1; then +- : +- else +- gl_cv_header_wchar_h_correct_inline=no +- fi +- fi +- fi +- rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext +- ]) +- if test $gl_cv_header_wchar_h_correct_inline = no; then +- AC_MSG_ERROR([ cannot be used with this compiler ($CC $CFLAGS $CPPFLAGS). +-This is a known interoperability problem of glibc <= 2.5 with gcc >= 4.3 in +-C99 mode. You have four options: +- - Add the flag -fgnu89-inline to CC and reconfigure, or +- - Fix your include files, using parts of +- , or +- - Use a gcc version older than 4.3, or +- - Don't use the flags -std=c99 or -std=gnu99. +-Configuration aborted.]) +- fi +-]) +- +-AC_DEFUN([gl_WCHAR_MODULE_INDICATOR], +-[ +- dnl Use AC_REQUIRE here, so that the default settings are expanded once only. +- AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) +- gl_MODULE_INDICATOR_SET_VARIABLE([$1]) +- dnl Define it also as a C macro, for the benefit of the unit tests. +- gl_MODULE_INDICATOR_FOR_TESTS([$1]) +-]) +- +-AC_DEFUN([gl_WCHAR_H_DEFAULTS], +-[ +- GNULIB_BTOWC=0; AC_SUBST([GNULIB_BTOWC]) +- GNULIB_WCTOB=0; AC_SUBST([GNULIB_WCTOB]) +- GNULIB_MBSINIT=0; AC_SUBST([GNULIB_MBSINIT]) +- GNULIB_MBRTOWC=0; AC_SUBST([GNULIB_MBRTOWC]) +- GNULIB_MBRLEN=0; AC_SUBST([GNULIB_MBRLEN]) +- GNULIB_MBSRTOWCS=0; AC_SUBST([GNULIB_MBSRTOWCS]) +- GNULIB_MBSNRTOWCS=0; AC_SUBST([GNULIB_MBSNRTOWCS]) +- GNULIB_WCRTOMB=0; AC_SUBST([GNULIB_WCRTOMB]) +- GNULIB_WCSRTOMBS=0; AC_SUBST([GNULIB_WCSRTOMBS]) +- GNULIB_WCSNRTOMBS=0; AC_SUBST([GNULIB_WCSNRTOMBS]) +- GNULIB_WCWIDTH=0; AC_SUBST([GNULIB_WCWIDTH]) +- GNULIB_WMEMCHR=0; AC_SUBST([GNULIB_WMEMCHR]) +- GNULIB_WMEMCMP=0; AC_SUBST([GNULIB_WMEMCMP]) +- GNULIB_WMEMCPY=0; AC_SUBST([GNULIB_WMEMCPY]) +- GNULIB_WMEMMOVE=0; AC_SUBST([GNULIB_WMEMMOVE]) +- GNULIB_WMEMSET=0; AC_SUBST([GNULIB_WMEMSET]) +- GNULIB_WCSLEN=0; AC_SUBST([GNULIB_WCSLEN]) +- GNULIB_WCSNLEN=0; AC_SUBST([GNULIB_WCSNLEN]) +- GNULIB_WCSCPY=0; AC_SUBST([GNULIB_WCSCPY]) +- GNULIB_WCPCPY=0; AC_SUBST([GNULIB_WCPCPY]) +- GNULIB_WCSNCPY=0; AC_SUBST([GNULIB_WCSNCPY]) +- GNULIB_WCPNCPY=0; AC_SUBST([GNULIB_WCPNCPY]) +- GNULIB_WCSCAT=0; AC_SUBST([GNULIB_WCSCAT]) +- GNULIB_WCSNCAT=0; AC_SUBST([GNULIB_WCSNCAT]) +- GNULIB_WCSCMP=0; AC_SUBST([GNULIB_WCSCMP]) +- GNULIB_WCSNCMP=0; AC_SUBST([GNULIB_WCSNCMP]) +- GNULIB_WCSCASECMP=0; AC_SUBST([GNULIB_WCSCASECMP]) +- GNULIB_WCSNCASECMP=0; AC_SUBST([GNULIB_WCSNCASECMP]) +- GNULIB_WCSCOLL=0; AC_SUBST([GNULIB_WCSCOLL]) +- GNULIB_WCSXFRM=0; AC_SUBST([GNULIB_WCSXFRM]) +- GNULIB_WCSDUP=0; AC_SUBST([GNULIB_WCSDUP]) +- GNULIB_WCSCHR=0; AC_SUBST([GNULIB_WCSCHR]) +- GNULIB_WCSRCHR=0; AC_SUBST([GNULIB_WCSRCHR]) +- GNULIB_WCSCSPN=0; AC_SUBST([GNULIB_WCSCSPN]) +- GNULIB_WCSSPN=0; AC_SUBST([GNULIB_WCSSPN]) +- GNULIB_WCSPBRK=0; AC_SUBST([GNULIB_WCSPBRK]) +- GNULIB_WCSSTR=0; AC_SUBST([GNULIB_WCSSTR]) +- GNULIB_WCSTOK=0; AC_SUBST([GNULIB_WCSTOK]) +- GNULIB_WCSWIDTH=0; AC_SUBST([GNULIB_WCSWIDTH]) +- dnl Assume proper GNU behavior unless another module says otherwise. +- HAVE_BTOWC=1; AC_SUBST([HAVE_BTOWC]) +- HAVE_MBSINIT=1; AC_SUBST([HAVE_MBSINIT]) +- HAVE_MBRTOWC=1; AC_SUBST([HAVE_MBRTOWC]) +- HAVE_MBRLEN=1; AC_SUBST([HAVE_MBRLEN]) +- HAVE_MBSRTOWCS=1; AC_SUBST([HAVE_MBSRTOWCS]) +- HAVE_MBSNRTOWCS=1; AC_SUBST([HAVE_MBSNRTOWCS]) +- HAVE_WCRTOMB=1; AC_SUBST([HAVE_WCRTOMB]) +- HAVE_WCSRTOMBS=1; AC_SUBST([HAVE_WCSRTOMBS]) +- HAVE_WCSNRTOMBS=1; AC_SUBST([HAVE_WCSNRTOMBS]) +- HAVE_WMEMCHR=1; AC_SUBST([HAVE_WMEMCHR]) +- HAVE_WMEMCMP=1; AC_SUBST([HAVE_WMEMCMP]) +- HAVE_WMEMCPY=1; AC_SUBST([HAVE_WMEMCPY]) +- HAVE_WMEMMOVE=1; AC_SUBST([HAVE_WMEMMOVE]) +- HAVE_WMEMSET=1; AC_SUBST([HAVE_WMEMSET]) +- HAVE_WCSLEN=1; AC_SUBST([HAVE_WCSLEN]) +- HAVE_WCSNLEN=1; AC_SUBST([HAVE_WCSNLEN]) +- HAVE_WCSCPY=1; AC_SUBST([HAVE_WCSCPY]) +- HAVE_WCPCPY=1; AC_SUBST([HAVE_WCPCPY]) +- HAVE_WCSNCPY=1; AC_SUBST([HAVE_WCSNCPY]) +- HAVE_WCPNCPY=1; AC_SUBST([HAVE_WCPNCPY]) +- HAVE_WCSCAT=1; AC_SUBST([HAVE_WCSCAT]) +- HAVE_WCSNCAT=1; AC_SUBST([HAVE_WCSNCAT]) +- HAVE_WCSCMP=1; AC_SUBST([HAVE_WCSCMP]) +- HAVE_WCSNCMP=1; AC_SUBST([HAVE_WCSNCMP]) +- HAVE_WCSCASECMP=1; AC_SUBST([HAVE_WCSCASECMP]) +- HAVE_WCSNCASECMP=1; AC_SUBST([HAVE_WCSNCASECMP]) +- HAVE_WCSCOLL=1; AC_SUBST([HAVE_WCSCOLL]) +- HAVE_WCSXFRM=1; AC_SUBST([HAVE_WCSXFRM]) +- HAVE_WCSDUP=1; AC_SUBST([HAVE_WCSDUP]) +- HAVE_WCSCHR=1; AC_SUBST([HAVE_WCSCHR]) +- HAVE_WCSRCHR=1; AC_SUBST([HAVE_WCSRCHR]) +- HAVE_WCSCSPN=1; AC_SUBST([HAVE_WCSCSPN]) +- HAVE_WCSSPN=1; AC_SUBST([HAVE_WCSSPN]) +- HAVE_WCSPBRK=1; AC_SUBST([HAVE_WCSPBRK]) +- HAVE_WCSSTR=1; AC_SUBST([HAVE_WCSSTR]) +- HAVE_WCSTOK=1; AC_SUBST([HAVE_WCSTOK]) +- HAVE_WCSWIDTH=1; AC_SUBST([HAVE_WCSWIDTH]) +- HAVE_DECL_WCTOB=1; AC_SUBST([HAVE_DECL_WCTOB]) +- HAVE_DECL_WCWIDTH=1; AC_SUBST([HAVE_DECL_WCWIDTH]) +- REPLACE_MBSTATE_T=0; AC_SUBST([REPLACE_MBSTATE_T]) +- REPLACE_BTOWC=0; AC_SUBST([REPLACE_BTOWC]) +- REPLACE_WCTOB=0; AC_SUBST([REPLACE_WCTOB]) +- REPLACE_MBSINIT=0; AC_SUBST([REPLACE_MBSINIT]) +- REPLACE_MBRTOWC=0; AC_SUBST([REPLACE_MBRTOWC]) +- REPLACE_MBRLEN=0; AC_SUBST([REPLACE_MBRLEN]) +- REPLACE_MBSRTOWCS=0; AC_SUBST([REPLACE_MBSRTOWCS]) +- REPLACE_MBSNRTOWCS=0; AC_SUBST([REPLACE_MBSNRTOWCS]) +- REPLACE_WCRTOMB=0; AC_SUBST([REPLACE_WCRTOMB]) +- REPLACE_WCSRTOMBS=0; AC_SUBST([REPLACE_WCSRTOMBS]) +- REPLACE_WCSNRTOMBS=0; AC_SUBST([REPLACE_WCSNRTOMBS]) +- REPLACE_WCWIDTH=0; AC_SUBST([REPLACE_WCWIDTH]) +- REPLACE_WCSWIDTH=0; AC_SUBST([REPLACE_WCSWIDTH]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/wchar_t.m4 groff-1.22.3/src/libs/gnulib/m4/wchar_t.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/wchar_t.m4 2014-11-04 10:38:35.642518784 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/wchar_t.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,24 +0,0 @@ +-# wchar_t.m4 serial 4 (gettext-0.18.2) +-dnl Copyright (C) 2002-2003, 2008-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Bruno Haible. +-dnl Test whether has the 'wchar_t' type. +-dnl Prerequisite: AC_PROG_CC +- +-AC_DEFUN([gt_TYPE_WCHAR_T], +-[ +- AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t], +- [AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM( +- [[#include +- wchar_t foo = (wchar_t)'\0';]], +- [[]])], +- [gt_cv_c_wchar_t=yes], +- [gt_cv_c_wchar_t=no])]) +- if test $gt_cv_c_wchar_t = yes; then +- AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.]) +- fi +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/wctype_h.m4 groff-1.22.3/src/libs/gnulib/m4/wctype_h.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/wctype_h.m4 2014-11-04 10:38:35.642518784 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/wctype_h.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,209 +0,0 @@ +-# wctype_h.m4 serial 18 +- +-dnl A placeholder for ISO C99 , for platforms that lack it. +- +-dnl Copyright (C) 2006-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl Written by Paul Eggert. +- +-AC_DEFUN([gl_WCTYPE_H], +-[ +- AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) +- AC_REQUIRE([AC_PROG_CC]) +- AC_REQUIRE([AC_CANONICAL_HOST]) +- AC_CHECK_FUNCS_ONCE([iswcntrl]) +- if test $ac_cv_func_iswcntrl = yes; then +- HAVE_ISWCNTRL=1 +- else +- HAVE_ISWCNTRL=0 +- fi +- AC_SUBST([HAVE_ISWCNTRL]) +- +- AC_REQUIRE([gt_TYPE_WINT_T]) +- if test $gt_cv_c_wint_t = yes; then +- HAVE_WINT_T=1 +- else +- HAVE_WINT_T=0 +- fi +- AC_SUBST([HAVE_WINT_T]) +- +- gl_CHECK_NEXT_HEADERS([wctype.h]) +- if test $ac_cv_header_wctype_h = yes; then +- if test $ac_cv_func_iswcntrl = yes; then +- dnl Linux libc5 has an iswprint function that returns 0 for all arguments. +- dnl The other functions are likely broken in the same way. +- AC_CACHE_CHECK([whether iswcntrl works], [gl_cv_func_iswcntrl_works], +- [ +- AC_RUN_IFELSE( +- [AC_LANG_SOURCE([[ +- /* Tru64 with Desktop Toolkit C has a bug: must be +- included before . +- BSD/OS 4.0.1 has a bug: , and +- must be included before . */ +- #include +- #include +- #include +- #include +- #include +- int main () { return iswprint ('x') == 0; } +- ]])], +- [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no], +- [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +- #if __GNU_LIBRARY__ == 1 +- Linux libc5 i18n is broken. +- #endif]], [])], +- [gl_cv_func_iswcntrl_works="guessing yes"], +- [gl_cv_func_iswcntrl_works="guessing no"]) +- ]) +- ]) +- fi +- HAVE_WCTYPE_H=1 +- else +- HAVE_WCTYPE_H=0 +- fi +- AC_SUBST([HAVE_WCTYPE_H]) +- +- case "$gl_cv_func_iswcntrl_works" in +- *yes) REPLACE_ISWCNTRL=0 ;; +- *) REPLACE_ISWCNTRL=1 ;; +- esac +- AC_SUBST([REPLACE_ISWCNTRL]) +- +- if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then +- dnl Redefine all of iswcntrl, ..., iswxdigit in . +- : +- fi +- +- if test $REPLACE_ISWCNTRL = 1; then +- REPLACE_TOWLOWER=1 +- else +- AC_CHECK_FUNCS([towlower]) +- if test $ac_cv_func_towlower = yes; then +- REPLACE_TOWLOWER=0 +- else +- AC_CHECK_DECLS([towlower],,, +- [[/* Tru64 with Desktop Toolkit C has a bug: must be +- included before . +- BSD/OS 4.0.1 has a bug: , and +- must be included before . */ +- #include +- #include +- #include +- #include +- #if HAVE_WCTYPE_H +- # include +- #endif +- ]]) +- if test $ac_cv_have_decl_towlower = yes; then +- dnl On Minix 3.1.8, the system's declares towlower() and +- dnl towupper() although it does not have the functions. Avoid a +- dnl collision with gnulib's replacement. +- REPLACE_TOWLOWER=1 +- else +- REPLACE_TOWLOWER=0 +- fi +- fi +- fi +- AC_SUBST([REPLACE_TOWLOWER]) +- +- if test $HAVE_ISWCNTRL = 0 || test $REPLACE_TOWLOWER = 1; then +- dnl Redefine towlower, towupper in . +- : +- fi +- +- dnl We assume that the wctype() and iswctype() functions exist if and only +- dnl if the type wctype_t is defined in or in if that +- dnl exists. +- dnl HP-UX 11.00 declares all these in and lacks . +- AC_CACHE_CHECK([for wctype_t], [gl_cv_type_wctype_t], +- [AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM( +- [[/* Tru64 with Desktop Toolkit C has a bug: must be +- included before . +- BSD/OS 4.0.1 has a bug: , and +- must be included before . */ +- #include +- #include +- #include +- #include +- #if HAVE_WCTYPE_H +- # include +- #endif +- wctype_t a; +- ]], +- [[]])], +- [gl_cv_type_wctype_t=yes], +- [gl_cv_type_wctype_t=no]) +- ]) +- if test $gl_cv_type_wctype_t = no; then +- HAVE_WCTYPE_T=0 +- fi +- +- dnl We assume that the wctrans() and towctrans() functions exist if and only +- dnl if the type wctrans_t is defined in . +- AC_CACHE_CHECK([for wctrans_t], [gl_cv_type_wctrans_t], +- [AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM( +- [[/* Tru64 with Desktop Toolkit C has a bug: must be +- included before . +- BSD/OS 4.0.1 has a bug: , and +- must be included before . */ +- #include +- #include +- #include +- #include +- #include +- wctrans_t a; +- ]], +- [[]])], +- [gl_cv_type_wctrans_t=yes], +- [gl_cv_type_wctrans_t=no]) +- ]) +- if test $gl_cv_type_wctrans_t = no; then +- HAVE_WCTRANS_T=0 +- fi +- +- dnl Check for declarations of anything we want to poison if the +- dnl corresponding gnulib module is not in use. +- gl_WARN_ON_USE_PREPARE([[ +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be +- included before . */ +-#if !(defined __GLIBC__ && !defined __UCLIBC__) +-# include +-# include +-# include +-# include +-#endif +-#include +- ]], +- [wctype iswctype wctrans towctrans +- ]) +-]) +- +-AC_DEFUN([gl_WCTYPE_MODULE_INDICATOR], +-[ +- dnl Use AC_REQUIRE here, so that the default settings are expanded once only. +- AC_REQUIRE([gl_WCTYPE_H_DEFAULTS]) +- gl_MODULE_INDICATOR_SET_VARIABLE([$1]) +- dnl Define it also as a C macro, for the benefit of the unit tests. +- gl_MODULE_INDICATOR_FOR_TESTS([$1]) +-]) +- +-AC_DEFUN([gl_WCTYPE_H_DEFAULTS], +-[ +- GNULIB_ISWBLANK=0; AC_SUBST([GNULIB_ISWBLANK]) +- GNULIB_WCTYPE=0; AC_SUBST([GNULIB_WCTYPE]) +- GNULIB_ISWCTYPE=0; AC_SUBST([GNULIB_ISWCTYPE]) +- GNULIB_WCTRANS=0; AC_SUBST([GNULIB_WCTRANS]) +- GNULIB_TOWCTRANS=0; AC_SUBST([GNULIB_TOWCTRANS]) +- dnl Assume proper GNU behavior unless another module says otherwise. +- HAVE_ISWBLANK=1; AC_SUBST([HAVE_ISWBLANK]) +- HAVE_WCTYPE_T=1; AC_SUBST([HAVE_WCTYPE_T]) +- HAVE_WCTRANS_T=1; AC_SUBST([HAVE_WCTRANS_T]) +- REPLACE_ISWBLANK=0; AC_SUBST([REPLACE_ISWBLANK]) +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/wcwidth.m4 groff-1.22.3/src/libs/gnulib/m4/wcwidth.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/wcwidth.m4 2014-11-04 10:38:35.642518784 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/wcwidth.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,101 +0,0 @@ +-# wcwidth.m4 serial 23 +-dnl Copyright (C) 2006-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-AC_DEFUN([gl_FUNC_WCWIDTH], +-[ +- AC_REQUIRE([gl_WCHAR_H_DEFAULTS]) +- AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles +- +- dnl Persuade glibc to declare wcwidth(). +- AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +- +- AC_REQUIRE([gt_TYPE_WCHAR_T]) +- AC_REQUIRE([gt_TYPE_WINT_T]) +- +- AC_CHECK_HEADERS_ONCE([wchar.h]) +- AC_CHECK_FUNCS_ONCE([wcwidth]) +- +- AC_CHECK_DECLS([wcwidth], [], [], [[ +-/* AIX 3.2.5 declares wcwidth in . */ +-#include +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be included +- before . */ +-#include +-#include +-#include +-#include +-]]) +- if test $ac_cv_have_decl_wcwidth != yes; then +- HAVE_DECL_WCWIDTH=0 +- fi +- +- if test $ac_cv_func_wcwidth = yes; then +- HAVE_WCWIDTH=1 +- dnl On Mac OS X 10.3, wcwidth(0x0301) (COMBINING ACUTE ACCENT) returns 1. +- dnl On OpenBSD 5.0, wcwidth(0x05B0) (HEBREW POINT SHEVA) returns 1. +- dnl On OSF/1 5.1, wcwidth(0x200B) (ZERO WIDTH SPACE) returns 1. +- dnl This leads to bugs in 'ls' (coreutils). +- AC_CACHE_CHECK([whether wcwidth works reasonably in UTF-8 locales], +- [gl_cv_func_wcwidth_works], +- [ +- AC_RUN_IFELSE( +- [AC_LANG_SOURCE([[ +-#include +-/* AIX 3.2.5 declares wcwidth in . */ +-#include +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be included +- before . */ +-#include +-#include +-#include +-#include +-#if !HAVE_DECL_WCWIDTH +-extern +-# ifdef __cplusplus +-"C" +-# endif +-int wcwidth (int); +-#endif +-int main () +-{ +- int result = 0; +- if (setlocale (LC_ALL, "fr_FR.UTF-8") != NULL) +- { +- if (wcwidth (0x0301) > 0) +- result |= 1; +- if (wcwidth (0x05B0) > 0) +- result |= 2; +- if (wcwidth (0x200B) > 0) +- result |= 4; +- } +- return result; +-}]])], +- [gl_cv_func_wcwidth_works=yes], +- [gl_cv_func_wcwidth_works=no], +- [ +-changequote(,)dnl +- case "$host_os" in +- # Guess yes on glibc and AIX 7 systems. +- *-gnu* | aix[7-9]*) gl_cv_func_wcwidth_works="guessing yes";; +- *) gl_cv_func_wcwidth_works="guessing no";; +- esac +-changequote([,])dnl +- ]) +- ]) +- case "$gl_cv_func_wcwidth_works" in +- *yes) ;; +- *no) REPLACE_WCWIDTH=1 ;; +- esac +- else +- HAVE_WCWIDTH=0 +- fi +- dnl We don't substitute HAVE_WCWIDTH. We assume that if the system does not +- dnl have the wcwidth function, then it does not declare it. +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/m4/wint_t.m4 groff-1.22.3/src/libs/gnulib/m4/wint_t.m4 +--- groff-1.22.3.old/src/libs/gnulib/m4/wint_t.m4 2014-11-04 10:38:35.642518784 +0200 ++++ groff-1.22.3/src/libs/gnulib/m4/wint_t.m4 1970-01-01 02:00:00.000000000 +0200 +@@ -1,32 +0,0 @@ +-# wint_t.m4 serial 5 (gettext-0.18.2) +-dnl Copyright (C) 2003, 2007-2014 Free Software Foundation, Inc. +-dnl This file is free software; the Free Software Foundation +-dnl gives unlimited permission to copy and/or distribute it, +-dnl with or without modifications, as long as this notice is preserved. +- +-dnl From Bruno Haible. +-dnl Test whether has the 'wint_t' type. +-dnl Prerequisite: AC_PROG_CC +- +-AC_DEFUN([gt_TYPE_WINT_T], +-[ +- AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t], +- [AC_COMPILE_IFELSE( +- [AC_LANG_PROGRAM( +- [[ +-/* Tru64 with Desktop Toolkit C has a bug: must be included before +- . +- BSD/OS 4.0.1 has a bug: , and must be included +- before . */ +-#include +-#include +-#include +-#include +- wint_t foo = (wchar_t)'\0';]], +- [[]])], +- [gt_cv_c_wint_t=yes], +- [gt_cv_c_wint_t=no])]) +- if test $gt_cv_c_wint_t = yes; then +- AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.]) +- fi +-]) +diff -Nuar groff-1.22.3.old/src/libs/gnulib/Makefile.am groff-1.22.3/src/libs/gnulib/Makefile.am +--- groff-1.22.3.old/src/libs/gnulib/Makefile.am 2014-11-04 10:38:35.676518359 +0200 ++++ groff-1.22.3/src/libs/gnulib/Makefile.am 1970-01-01 02:00:00.000000000 +0200 +@@ -1,20 +0,0 @@ +-## Process this file with automake to produce Makefile.in. +- +-# Makefile.am +- +-# Copyright (C) 1994-2014 Free Software Foundation, Inc. +- +-# This file is free software; the Free Software Foundation gives +-# unlimited permission to copy and/or distribute it, with or without +-# modifications, as long as this notice is preserved. +- +-# This program is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even +-# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-# PURPOSE. +- +-AUTOMAKE_OPTIONS = 1.5 foreign +- +-SUBDIRS = lib m4 +- +-ACLOCAL_AMFLAGS = -I m4 +diff -Nuar groff-1.22.3.old/src/libs/gnulib/Makefile.in groff-1.22.3/src/libs/gnulib/Makefile.in +--- groff-1.22.3.old/src/libs/gnulib/Makefile.in 2014-11-04 10:38:35.676518359 +0200 ++++ groff-1.22.3/src/libs/gnulib/Makefile.in 1970-01-01 02:00:00.000000000 +0200 +@@ -1,972 +0,0 @@ +-# Makefile.in generated by automake 1.14 from Makefile.am. +-# @configure_input@ +- +-# Copyright (C) 1994-2013 Free Software Foundation, Inc. +- +-# This Makefile.in is free software; the Free Software Foundation +-# gives unlimited permission to copy and/or distribute it, +-# with or without modifications, as long as this notice is preserved. +- +-# This program is distributed in the hope that it will be useful, +-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +-# PARTICULAR PURPOSE. +- +-@SET_MAKE@ +- +-# Makefile.am +- +-# Copyright (C) 1994-2014 Free Software Foundation, Inc. +- +-# This file is free software; the Free Software Foundation gives +-# unlimited permission to copy and/or distribute it, with or without +-# modifications, as long as this notice is preserved. +- +-# This program is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY, to the extent permitted by law; without even +-# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-# PURPOSE. +-VPATH = @srcdir@ +-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +-am__make_running_with_option = \ +- case $${target_option-} in \ +- ?) ;; \ +- *) echo "am__make_running_with_option: internal error: invalid" \ +- "target option '$${target_option-}' specified" >&2; \ +- exit 1;; \ +- esac; \ +- has_opt=no; \ +- sane_makeflags=$$MAKEFLAGS; \ +- if $(am__is_gnu_make); then \ +- sane_makeflags=$$MFLAGS; \ +- else \ +- case $$MAKEFLAGS in \ +- *\\[\ \ ]*) \ +- bs=\\; \ +- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ +- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ +- esac; \ +- fi; \ +- skip_next=no; \ +- strip_trailopt () \ +- { \ +- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ +- }; \ +- for flg in $$sane_makeflags; do \ +- test $$skip_next = yes && { skip_next=no; continue; }; \ +- case $$flg in \ +- *=*|--*) continue;; \ +- -*I) strip_trailopt 'I'; skip_next=yes;; \ +- -*I?*) strip_trailopt 'I';; \ +- -*O) strip_trailopt 'O'; skip_next=yes;; \ +- -*O?*) strip_trailopt 'O';; \ +- -*l) strip_trailopt 'l'; skip_next=yes;; \ +- -*l?*) strip_trailopt 'l';; \ +- -[dEDm]) skip_next=yes;; \ +- -[JT]) skip_next=yes;; \ +- esac; \ +- case $$flg in \ +- *$$target_option*) has_opt=yes; break;; \ +- esac; \ +- done; \ +- test $$has_opt = yes +-am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +-am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +-pkgdatadir = $(datadir)/@PACKAGE@ +-pkgincludedir = $(includedir)/@PACKAGE@ +-pkglibdir = $(libdir)/@PACKAGE@ +-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +-install_sh_DATA = $(install_sh) -c -m 644 +-install_sh_PROGRAM = $(install_sh) -c +-install_sh_SCRIPT = $(install_sh) -c +-INSTALL_HEADER = $(INSTALL_DATA) +-transform = $(program_transform_name) +-NORMAL_INSTALL = : +-PRE_INSTALL = : +-POST_INSTALL = : +-NORMAL_UNINSTALL = : +-PRE_UNINSTALL = : +-POST_UNINSTALL = : +-build_triplet = @build@ +-host_triplet = @host@ +-subdir = . +-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ +- $(top_srcdir)/configure $(am__configure_deps) \ +- $(srcdir)/config.h.in build-aux/compile build-aux/config.guess \ +- build-aux/config.sub build-aux/depcomp build-aux/install-sh \ +- build-aux/missing $(top_srcdir)/build-aux/compile \ +- $(top_srcdir)/build-aux/config.guess \ +- $(top_srcdir)/build-aux/config.sub \ +- $(top_srcdir)/build-aux/install-sh \ +- $(top_srcdir)/build-aux/missing +-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +-am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ +- $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/configmake.m4 \ +- $(top_srcdir)/m4/extensions.m4 \ +- $(top_srcdir)/m4/extern-inline.m4 $(top_srcdir)/m4/fcntl-o.m4 \ +- $(top_srcdir)/m4/glibc21.m4 $(top_srcdir)/m4/gnulib-common.m4 \ +- $(top_srcdir)/m4/include_next.m4 \ +- $(top_srcdir)/m4/inttypes-pri.m4 $(top_srcdir)/m4/inttypes.m4 \ +- $(top_srcdir)/m4/libunistring-base.m4 \ +- $(top_srcdir)/m4/localcharset.m4 $(top_srcdir)/m4/longlong.m4 \ +- $(top_srcdir)/m4/multiarch.m4 $(top_srcdir)/m4/onceonly.m4 \ +- $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \ +- $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/warn-on-use.m4 \ +- $(top_srcdir)/m4/wchar_h.m4 $(top_srcdir)/m4/wchar_t.m4 \ +- $(top_srcdir)/m4/wctype_h.m4 $(top_srcdir)/m4/wcwidth.m4 \ +- $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/configure.ac +-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ +- $(ACLOCAL_M4) +-am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ +- configure.lineno config.status.lineno +-mkinstalldirs = $(install_sh) -d +-CONFIG_HEADER = config.h +-CONFIG_CLEAN_FILES = +-CONFIG_CLEAN_VPATH_FILES = +-AM_V_P = $(am__v_P_@AM_V@) +-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +-am__v_P_0 = false +-am__v_P_1 = : +-AM_V_GEN = $(am__v_GEN_@AM_V@) +-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +-am__v_GEN_0 = @echo " GEN " $@; +-am__v_GEN_1 = +-AM_V_at = $(am__v_at_@AM_V@) +-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +-am__v_at_0 = @ +-am__v_at_1 = +-SOURCES = +-DIST_SOURCES = +-RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ +- ctags-recursive dvi-recursive html-recursive info-recursive \ +- install-data-recursive install-dvi-recursive \ +- install-exec-recursive install-html-recursive \ +- install-info-recursive install-pdf-recursive \ +- install-ps-recursive install-recursive installcheck-recursive \ +- installdirs-recursive pdf-recursive ps-recursive \ +- tags-recursive uninstall-recursive +-am__can_run_installinfo = \ +- case $$AM_UPDATE_INFO_DIR in \ +- n|no|NO) false;; \ +- *) (install-info --version) >/dev/null 2>&1;; \ +- esac +-RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ +- distclean-recursive maintainer-clean-recursive +-am__recursive_targets = \ +- $(RECURSIVE_TARGETS) \ +- $(RECURSIVE_CLEAN_TARGETS) \ +- $(am__extra_recursive_targets) +-AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ +- cscope distdir dist dist-all distcheck +-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ +- $(LISP)config.h.in +-# Read a list of newline-separated strings from the standard input, +-# and print each of them once, without duplicates. Input order is +-# *not* preserved. +-am__uniquify_input = $(AWK) '\ +- BEGIN { nonempty = 0; } \ +- { items[$$0] = 1; nonempty = 1; } \ +- END { if (nonempty) { for (i in items) print i; }; } \ +-' +-# Make sure the list of sources is unique. This is necessary because, +-# e.g., the same source file might be shared among _SOURCES variables +-# for different programs/libraries. +-am__define_uniq_tagged_files = \ +- list='$(am__tagged_files)'; \ +- unique=`for i in $$list; do \ +- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +- done | $(am__uniquify_input)` +-ETAGS = etags +-CTAGS = ctags +-CSCOPE = cscope +-DIST_SUBDIRS = $(SUBDIRS) +-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +-distdir = $(PACKAGE)-$(VERSION) +-top_distdir = $(distdir) +-am__remove_distdir = \ +- if test -d "$(distdir)"; then \ +- find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ +- && rm -rf "$(distdir)" \ +- || { sleep 5 && rm -rf "$(distdir)"; }; \ +- else :; fi +-am__post_remove_distdir = $(am__remove_distdir) +-am__relativize = \ +- dir0=`pwd`; \ +- sed_first='s,^\([^/]*\)/.*$$,\1,'; \ +- sed_rest='s,^[^/]*/*,,'; \ +- sed_last='s,^.*/\([^/]*\)$$,\1,'; \ +- sed_butlast='s,/*[^/]*$$,,'; \ +- while test -n "$$dir1"; do \ +- first=`echo "$$dir1" | sed -e "$$sed_first"`; \ +- if test "$$first" != "."; then \ +- if test "$$first" = ".."; then \ +- dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ +- dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ +- else \ +- first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ +- if test "$$first2" = "$$first"; then \ +- dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ +- else \ +- dir2="../$$dir2"; \ +- fi; \ +- dir0="$$dir0"/"$$first"; \ +- fi; \ +- fi; \ +- dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ +- done; \ +- reldir="$$dir2" +-DIST_ARCHIVES = $(distdir).tar.gz +-GZIP_ENV = --best +-DIST_TARGETS = dist-gzip +-distuninstallcheck_listfiles = find . -type f -print +-am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ +- | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +-distcleancheck_listfiles = find . -type f -print +-pkglibexecdir = @pkglibexecdir@ +-ACLOCAL = @ACLOCAL@ +-AMTAR = @AMTAR@ +-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +-APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@ +-AR = @AR@ +-ARFLAGS = @ARFLAGS@ +-AUTOCONF = @AUTOCONF@ +-AUTOHEADER = @AUTOHEADER@ +-AUTOMAKE = @AUTOMAKE@ +-AWK = @AWK@ +-BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@ +-BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@ +-BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@ +-BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@ +-BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@ +-CC = @CC@ +-CCDEPMODE = @CCDEPMODE@ +-CFLAGS = @CFLAGS@ +-CPP = @CPP@ +-CPPFLAGS = @CPPFLAGS@ +-CYGPATH_W = @CYGPATH_W@ +-DEFS = @DEFS@ +-DEPDIR = @DEPDIR@ +-ECHO_C = @ECHO_C@ +-ECHO_N = @ECHO_N@ +-ECHO_T = @ECHO_T@ +-EGREP = @EGREP@ +-EXEEXT = @EXEEXT@ +-GLIBC21 = @GLIBC21@ +-GNULIB_BTOWC = @GNULIB_BTOWC@ +-GNULIB_IMAXABS = @GNULIB_IMAXABS@ +-GNULIB_IMAXDIV = @GNULIB_IMAXDIV@ +-GNULIB_ISWBLANK = @GNULIB_ISWBLANK@ +-GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@ +-GNULIB_MBRLEN = @GNULIB_MBRLEN@ +-GNULIB_MBRTOWC = @GNULIB_MBRTOWC@ +-GNULIB_MBSINIT = @GNULIB_MBSINIT@ +-GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@ +-GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@ +-GNULIB_STRTOIMAX = @GNULIB_STRTOIMAX@ +-GNULIB_STRTOUMAX = @GNULIB_STRTOUMAX@ +-GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@ +-GNULIB_WCPCPY = @GNULIB_WCPCPY@ +-GNULIB_WCPNCPY = @GNULIB_WCPNCPY@ +-GNULIB_WCRTOMB = @GNULIB_WCRTOMB@ +-GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@ +-GNULIB_WCSCAT = @GNULIB_WCSCAT@ +-GNULIB_WCSCHR = @GNULIB_WCSCHR@ +-GNULIB_WCSCMP = @GNULIB_WCSCMP@ +-GNULIB_WCSCOLL = @GNULIB_WCSCOLL@ +-GNULIB_WCSCPY = @GNULIB_WCSCPY@ +-GNULIB_WCSCSPN = @GNULIB_WCSCSPN@ +-GNULIB_WCSDUP = @GNULIB_WCSDUP@ +-GNULIB_WCSLEN = @GNULIB_WCSLEN@ +-GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@ +-GNULIB_WCSNCAT = @GNULIB_WCSNCAT@ +-GNULIB_WCSNCMP = @GNULIB_WCSNCMP@ +-GNULIB_WCSNCPY = @GNULIB_WCSNCPY@ +-GNULIB_WCSNLEN = @GNULIB_WCSNLEN@ +-GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@ +-GNULIB_WCSPBRK = @GNULIB_WCSPBRK@ +-GNULIB_WCSRCHR = @GNULIB_WCSRCHR@ +-GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@ +-GNULIB_WCSSPN = @GNULIB_WCSSPN@ +-GNULIB_WCSSTR = @GNULIB_WCSSTR@ +-GNULIB_WCSTOK = @GNULIB_WCSTOK@ +-GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@ +-GNULIB_WCSXFRM = @GNULIB_WCSXFRM@ +-GNULIB_WCTOB = @GNULIB_WCTOB@ +-GNULIB_WCTRANS = @GNULIB_WCTRANS@ +-GNULIB_WCTYPE = @GNULIB_WCTYPE@ +-GNULIB_WCWIDTH = @GNULIB_WCWIDTH@ +-GNULIB_WMEMCHR = @GNULIB_WMEMCHR@ +-GNULIB_WMEMCMP = @GNULIB_WMEMCMP@ +-GNULIB_WMEMCPY = @GNULIB_WMEMCPY@ +-GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@ +-GNULIB_WMEMSET = @GNULIB_WMEMSET@ +-GREP = @GREP@ +-HAVE_BTOWC = @HAVE_BTOWC@ +-HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@ +-HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@ +-HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@ +-HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@ +-HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@ +-HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@ +-HAVE_FEATURES_H = @HAVE_FEATURES_H@ +-HAVE_INTTYPES_H = @HAVE_INTTYPES_H@ +-HAVE_ISWBLANK = @HAVE_ISWBLANK@ +-HAVE_ISWCNTRL = @HAVE_ISWCNTRL@ +-HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@ +-HAVE_MBRLEN = @HAVE_MBRLEN@ +-HAVE_MBRTOWC = @HAVE_MBRTOWC@ +-HAVE_MBSINIT = @HAVE_MBSINIT@ +-HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@ +-HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@ +-HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@ +-HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@ +-HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@ +-HAVE_STDINT_H = @HAVE_STDINT_H@ +-HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@ +-HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@ +-HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@ +-HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@ +-HAVE_WCHAR_H = @HAVE_WCHAR_H@ +-HAVE_WCHAR_T = @HAVE_WCHAR_T@ +-HAVE_WCPCPY = @HAVE_WCPCPY@ +-HAVE_WCPNCPY = @HAVE_WCPNCPY@ +-HAVE_WCRTOMB = @HAVE_WCRTOMB@ +-HAVE_WCSCASECMP = @HAVE_WCSCASECMP@ +-HAVE_WCSCAT = @HAVE_WCSCAT@ +-HAVE_WCSCHR = @HAVE_WCSCHR@ +-HAVE_WCSCMP = @HAVE_WCSCMP@ +-HAVE_WCSCOLL = @HAVE_WCSCOLL@ +-HAVE_WCSCPY = @HAVE_WCSCPY@ +-HAVE_WCSCSPN = @HAVE_WCSCSPN@ +-HAVE_WCSDUP = @HAVE_WCSDUP@ +-HAVE_WCSLEN = @HAVE_WCSLEN@ +-HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@ +-HAVE_WCSNCAT = @HAVE_WCSNCAT@ +-HAVE_WCSNCMP = @HAVE_WCSNCMP@ +-HAVE_WCSNCPY = @HAVE_WCSNCPY@ +-HAVE_WCSNLEN = @HAVE_WCSNLEN@ +-HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@ +-HAVE_WCSPBRK = @HAVE_WCSPBRK@ +-HAVE_WCSRCHR = @HAVE_WCSRCHR@ +-HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@ +-HAVE_WCSSPN = @HAVE_WCSSPN@ +-HAVE_WCSSTR = @HAVE_WCSSTR@ +-HAVE_WCSTOK = @HAVE_WCSTOK@ +-HAVE_WCSWIDTH = @HAVE_WCSWIDTH@ +-HAVE_WCSXFRM = @HAVE_WCSXFRM@ +-HAVE_WCTRANS_T = @HAVE_WCTRANS_T@ +-HAVE_WCTYPE_H = @HAVE_WCTYPE_H@ +-HAVE_WCTYPE_T = @HAVE_WCTYPE_T@ +-HAVE_WINT_T = @HAVE_WINT_T@ +-HAVE_WMEMCHR = @HAVE_WMEMCHR@ +-HAVE_WMEMCMP = @HAVE_WMEMCMP@ +-HAVE_WMEMCPY = @HAVE_WMEMCPY@ +-HAVE_WMEMMOVE = @HAVE_WMEMMOVE@ +-HAVE_WMEMSET = @HAVE_WMEMSET@ +-HAVE__BOOL = @HAVE__BOOL@ +-INCLUDE_NEXT = @INCLUDE_NEXT@ +-INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ +-INSTALL = @INSTALL@ +-INSTALL_DATA = @INSTALL_DATA@ +-INSTALL_PROGRAM = @INSTALL_PROGRAM@ +-INSTALL_SCRIPT = @INSTALL_SCRIPT@ +-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +-INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@ +-INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@ +-LDFLAGS = @LDFLAGS@ +-LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@ +-LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@ +-LIBOBJS = @LIBOBJS@ +-LIBS = @LIBS@ +-LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@ +-LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@ +-LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@ +-LTLIBOBJS = @LTLIBOBJS@ +-MAKEINFO = @MAKEINFO@ +-MKDIR_P = @MKDIR_P@ +-NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@ +-NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@ +-NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@ +-NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@ +-NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@ +-NEXT_INTTYPES_H = @NEXT_INTTYPES_H@ +-NEXT_STDDEF_H = @NEXT_STDDEF_H@ +-NEXT_STDINT_H = @NEXT_STDINT_H@ +-NEXT_WCHAR_H = @NEXT_WCHAR_H@ +-NEXT_WCTYPE_H = @NEXT_WCTYPE_H@ +-OBJEXT = @OBJEXT@ +-PACKAGE = @PACKAGE@ +-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +-PACKAGE_NAME = @PACKAGE_NAME@ +-PACKAGE_STRING = @PACKAGE_STRING@ +-PACKAGE_TARNAME = @PACKAGE_TARNAME@ +-PACKAGE_URL = @PACKAGE_URL@ +-PACKAGE_VERSION = @PACKAGE_VERSION@ +-PATH_SEPARATOR = @PATH_SEPARATOR@ +-PRAGMA_COLUMNS = @PRAGMA_COLUMNS@ +-PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ +-PRIPTR_PREFIX = @PRIPTR_PREFIX@ +-PRI_MACROS_BROKEN = @PRI_MACROS_BROKEN@ +-PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@ +-RANLIB = @RANLIB@ +-REPLACE_BTOWC = @REPLACE_BTOWC@ +-REPLACE_ISWBLANK = @REPLACE_ISWBLANK@ +-REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@ +-REPLACE_MBRLEN = @REPLACE_MBRLEN@ +-REPLACE_MBRTOWC = @REPLACE_MBRTOWC@ +-REPLACE_MBSINIT = @REPLACE_MBSINIT@ +-REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@ +-REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@ +-REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@ +-REPLACE_NULL = @REPLACE_NULL@ +-REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@ +-REPLACE_TOWLOWER = @REPLACE_TOWLOWER@ +-REPLACE_WCRTOMB = @REPLACE_WCRTOMB@ +-REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@ +-REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@ +-REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@ +-REPLACE_WCTOB = @REPLACE_WCTOB@ +-REPLACE_WCWIDTH = @REPLACE_WCWIDTH@ +-SET_MAKE = @SET_MAKE@ +-SHELL = @SHELL@ +-SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@ +-SIZE_T_SUFFIX = @SIZE_T_SUFFIX@ +-STDBOOL_H = @STDBOOL_H@ +-STDDEF_H = @STDDEF_H@ +-STDINT_H = @STDINT_H@ +-STRIP = @STRIP@ +-UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@ +-UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@ +-VERSION = @VERSION@ +-WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@ +-WINT_T_SUFFIX = @WINT_T_SUFFIX@ +-abs_builddir = @abs_builddir@ +-abs_srcdir = @abs_srcdir@ +-abs_top_builddir = @abs_top_builddir@ +-abs_top_srcdir = @abs_top_srcdir@ +-ac_ct_CC = @ac_ct_CC@ +-am__include = @am__include@ +-am__leading_dot = @am__leading_dot@ +-am__quote = @am__quote@ +-am__tar = @am__tar@ +-am__untar = @am__untar@ +-bindir = @bindir@ +-build = @build@ +-build_alias = @build_alias@ +-build_cpu = @build_cpu@ +-build_os = @build_os@ +-build_vendor = @build_vendor@ +-builddir = @builddir@ +-datadir = @datadir@ +-datarootdir = @datarootdir@ +-docdir = @docdir@ +-dvidir = @dvidir@ +-exec_prefix = @exec_prefix@ +-gl_LIBOBJS = @gl_LIBOBJS@ +-gl_LTLIBOBJS = @gl_LTLIBOBJS@ +-host = @host@ +-host_alias = @host_alias@ +-host_cpu = @host_cpu@ +-host_os = @host_os@ +-host_vendor = @host_vendor@ +-htmldir = @htmldir@ +-includedir = @includedir@ +-infodir = @infodir@ +-install_sh = @install_sh@ +-libdir = @libdir@ +-libexecdir = @libexecdir@ +-lispdir = @lispdir@ +-localedir = @localedir@ +-localstatedir = @localstatedir@ +-mandir = @mandir@ +-mkdir_p = @mkdir_p@ +-oldincludedir = @oldincludedir@ +-pdfdir = @pdfdir@ +-prefix = @prefix@ +-program_transform_name = @program_transform_name@ +-psdir = @psdir@ +-runstatedir = @runstatedir@ +-sbindir = @sbindir@ +-sharedstatedir = @sharedstatedir@ +-srcdir = @srcdir@ +-sysconfdir = @sysconfdir@ +-target_alias = @target_alias@ +-top_build_prefix = @top_build_prefix@ +-top_builddir = @top_builddir@ +-top_srcdir = @top_srcdir@ +-AUTOMAKE_OPTIONS = 1.5 foreign +-SUBDIRS = lib m4 +-ACLOCAL_AMFLAGS = -I m4 +-all: config.h +- $(MAKE) $(AM_MAKEFLAGS) all-recursive +- +-.SUFFIXES: +-am--refresh: Makefile +- @: +-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) +- @for dep in $?; do \ +- case '$(am__configure_deps)' in \ +- *$$dep*) \ +- echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ +- $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ +- && exit 0; \ +- exit 1;; \ +- esac; \ +- done; \ +- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ +- $(am__cd) $(top_srcdir) && \ +- $(AUTOMAKE) --foreign Makefile +-.PRECIOUS: Makefile +-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status +- @case '$?' in \ +- *config.status*) \ +- echo ' $(SHELL) ./config.status'; \ +- $(SHELL) ./config.status;; \ +- *) \ +- echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ +- cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ +- esac; +- +-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) +- $(SHELL) ./config.status --recheck +- +-$(top_srcdir)/configure: $(am__configure_deps) +- $(am__cd) $(srcdir) && $(AUTOCONF) +-$(ACLOCAL_M4): $(am__aclocal_m4_deps) +- $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +-$(am__aclocal_m4_deps): +- +-config.h: stamp-h1 +- @test -f $@ || rm -f stamp-h1 +- @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 +- +-stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status +- @rm -f stamp-h1 +- cd $(top_builddir) && $(SHELL) ./config.status config.h +-$(srcdir)/config.h.in: $(am__configure_deps) +- ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) +- rm -f stamp-h1 +- touch $@ +- +-distclean-hdr: +- -rm -f config.h stamp-h1 +- +-# This directory's subdirectories are mostly independent; you can cd +-# into them and run 'make' without going through this Makefile. +-# To change the values of 'make' variables: instead of editing Makefiles, +-# (1) if the variable is set in 'config.status', edit 'config.status' +-# (which will cause the Makefiles to be regenerated when you run 'make'); +-# (2) otherwise, pass the desired values on the 'make' command line. +-$(am__recursive_targets): +- @fail=; \ +- if $(am__make_keepgoing); then \ +- failcom='fail=yes'; \ +- else \ +- failcom='exit 1'; \ +- fi; \ +- dot_seen=no; \ +- target=`echo $@ | sed s/-recursive//`; \ +- case "$@" in \ +- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ +- *) list='$(SUBDIRS)' ;; \ +- esac; \ +- for subdir in $$list; do \ +- echo "Making $$target in $$subdir"; \ +- if test "$$subdir" = "."; then \ +- dot_seen=yes; \ +- local_target="$$target-am"; \ +- else \ +- local_target="$$target"; \ +- fi; \ +- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ +- || eval $$failcom; \ +- done; \ +- if test "$$dot_seen" = "no"; then \ +- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ +- fi; test -z "$$fail" +- +-ID: $(am__tagged_files) +- $(am__define_uniq_tagged_files); mkid -fID $$unique +-tags: tags-recursive +-TAGS: tags +- +-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +- set x; \ +- here=`pwd`; \ +- if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ +- include_option=--etags-include; \ +- empty_fix=.; \ +- else \ +- include_option=--include; \ +- empty_fix=; \ +- fi; \ +- list='$(SUBDIRS)'; for subdir in $$list; do \ +- if test "$$subdir" = .; then :; else \ +- test ! -f $$subdir/TAGS || \ +- set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ +- fi; \ +- done; \ +- $(am__define_uniq_tagged_files); \ +- shift; \ +- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ +- test -n "$$unique" || unique=$$empty_fix; \ +- if test $$# -gt 0; then \ +- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +- "$$@" $$unique; \ +- else \ +- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +- $$unique; \ +- fi; \ +- fi +-ctags: ctags-recursive +- +-CTAGS: ctags +-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +- $(am__define_uniq_tagged_files); \ +- test -z "$(CTAGS_ARGS)$$unique" \ +- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ +- $$unique +- +-GTAGS: +- here=`$(am__cd) $(top_builddir) && pwd` \ +- && $(am__cd) $(top_srcdir) \ +- && gtags -i $(GTAGS_ARGS) "$$here" +-cscope: cscope.files +- test ! -s cscope.files \ +- || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +-clean-cscope: +- -rm -f cscope.files +-cscope.files: clean-cscope cscopelist +-cscopelist: cscopelist-recursive +- +-cscopelist-am: $(am__tagged_files) +- list='$(am__tagged_files)'; \ +- case "$(srcdir)" in \ +- [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ +- *) sdir=$(subdir)/$(srcdir) ;; \ +- esac; \ +- for i in $$list; do \ +- if test -f "$$i"; then \ +- echo "$(subdir)/$$i"; \ +- else \ +- echo "$$sdir/$$i"; \ +- fi; \ +- done >> $(top_builddir)/cscope.files +- +-distclean-tags: +- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +- -rm -f cscope.out cscope.in.out cscope.po.out cscope.files +- +-distdir: $(DISTFILES) +- $(am__remove_distdir) +- test -d "$(distdir)" || mkdir "$(distdir)" +- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +- list='$(DISTFILES)'; \ +- dist_files=`for file in $$list; do echo $$file; done | \ +- sed -e "s|^$$srcdirstrip/||;t" \ +- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ +- case $$dist_files in \ +- */*) $(MKDIR_P) `echo "$$dist_files" | \ +- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ +- sort -u` ;; \ +- esac; \ +- for file in $$dist_files; do \ +- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ +- if test -d $$d/$$file; then \ +- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ +- if test -d "$(distdir)/$$file"; then \ +- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +- fi; \ +- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ +- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ +- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +- fi; \ +- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ +- else \ +- test -f "$(distdir)/$$file" \ +- || cp -p $$d/$$file "$(distdir)/$$file" \ +- || exit 1; \ +- fi; \ +- done +- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ +- if test "$$subdir" = .; then :; else \ +- $(am__make_dryrun) \ +- || test -d "$(distdir)/$$subdir" \ +- || $(MKDIR_P) "$(distdir)/$$subdir" \ +- || exit 1; \ +- dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ +- $(am__relativize); \ +- new_distdir=$$reldir; \ +- dir1=$$subdir; dir2="$(top_distdir)"; \ +- $(am__relativize); \ +- new_top_distdir=$$reldir; \ +- echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ +- echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ +- ($(am__cd) $$subdir && \ +- $(MAKE) $(AM_MAKEFLAGS) \ +- top_distdir="$$new_top_distdir" \ +- distdir="$$new_distdir" \ +- am__remove_distdir=: \ +- am__skip_length_check=: \ +- am__skip_mode_fix=: \ +- distdir) \ +- || exit 1; \ +- fi; \ +- done +- -test -n "$(am__skip_mode_fix)" \ +- || find "$(distdir)" -type d ! -perm -755 \ +- -exec chmod u+rwx,go+rx {} \; -o \ +- ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ +- ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ +- ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ +- || chmod -R a+r "$(distdir)" +-dist-gzip: distdir +- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz +- $(am__post_remove_distdir) +- +-dist-bzip2: distdir +- tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 +- $(am__post_remove_distdir) +- +-dist-lzip: distdir +- tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz +- $(am__post_remove_distdir) +- +-dist-xz: distdir +- tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz +- $(am__post_remove_distdir) +- +-dist-tarZ: distdir +- @echo WARNING: "Support for shar distribution archives is" \ +- "deprecated." >&2 +- @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 +- tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z +- $(am__post_remove_distdir) +- +-dist-shar: distdir +- @echo WARNING: "Support for distribution archives compressed with" \ +- "legacy program 'compress' is deprecated." >&2 +- @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 +- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz +- $(am__post_remove_distdir) +- +-dist-zip: distdir +- -rm -f $(distdir).zip +- zip -rq $(distdir).zip $(distdir) +- $(am__post_remove_distdir) +- +-dist dist-all: +- $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' +- $(am__post_remove_distdir) +- +-# This target untars the dist file and tries a VPATH configuration. Then +-# it guarantees that the distribution is self-contained by making another +-# tarfile. +-distcheck: dist +- case '$(DIST_ARCHIVES)' in \ +- *.tar.gz*) \ +- GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ +- *.tar.bz2*) \ +- bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ +- *.tar.lz*) \ +- lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ +- *.tar.xz*) \ +- xz -dc $(distdir).tar.xz | $(am__untar) ;;\ +- *.tar.Z*) \ +- uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ +- *.shar.gz*) \ +- GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ +- *.zip*) \ +- unzip $(distdir).zip ;;\ +- esac +- chmod -R a-w $(distdir) +- chmod u+w $(distdir) +- mkdir $(distdir)/_build $(distdir)/_inst +- chmod a-w $(distdir) +- test -d $(distdir)/_build || exit 0; \ +- dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ +- && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ +- && am__cwd=`pwd` \ +- && $(am__cd) $(distdir)/_build \ +- && ../configure --srcdir=.. --prefix="$$dc_install_base" \ +- $(AM_DISTCHECK_CONFIGURE_FLAGS) \ +- $(DISTCHECK_CONFIGURE_FLAGS) \ +- && $(MAKE) $(AM_MAKEFLAGS) \ +- && $(MAKE) $(AM_MAKEFLAGS) dvi \ +- && $(MAKE) $(AM_MAKEFLAGS) check \ +- && $(MAKE) $(AM_MAKEFLAGS) install \ +- && $(MAKE) $(AM_MAKEFLAGS) installcheck \ +- && $(MAKE) $(AM_MAKEFLAGS) uninstall \ +- && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ +- distuninstallcheck \ +- && chmod -R a-w "$$dc_install_base" \ +- && ({ \ +- (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ +- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ +- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ +- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ +- distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ +- } || { rm -rf "$$dc_destdir"; exit 1; }) \ +- && rm -rf "$$dc_destdir" \ +- && $(MAKE) $(AM_MAKEFLAGS) dist \ +- && rm -rf $(DIST_ARCHIVES) \ +- && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ +- && cd "$$am__cwd" \ +- || exit 1 +- $(am__post_remove_distdir) +- @(echo "$(distdir) archives ready for distribution: "; \ +- list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ +- sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +-distuninstallcheck: +- @test -n '$(distuninstallcheck_dir)' || { \ +- echo 'ERROR: trying to run $@ with an empty' \ +- '$$(distuninstallcheck_dir)' >&2; \ +- exit 1; \ +- }; \ +- $(am__cd) '$(distuninstallcheck_dir)' || { \ +- echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ +- exit 1; \ +- }; \ +- test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ +- || { echo "ERROR: files left after uninstall:" ; \ +- if test -n "$(DESTDIR)"; then \ +- echo " (check DESTDIR support)"; \ +- fi ; \ +- $(distuninstallcheck_listfiles) ; \ +- exit 1; } >&2 +-distcleancheck: distclean +- @if test '$(srcdir)' = . ; then \ +- echo "ERROR: distcleancheck can only run from a VPATH build" ; \ +- exit 1 ; \ +- fi +- @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ +- || { echo "ERROR: files left in build directory after distclean:" ; \ +- $(distcleancheck_listfiles) ; \ +- exit 1; } >&2 +-check-am: all-am +-check: check-recursive +-all-am: Makefile config.h +-installdirs: installdirs-recursive +-installdirs-am: +-install: install-recursive +-install-exec: install-exec-recursive +-install-data: install-data-recursive +-uninstall: uninstall-recursive +- +-install-am: all-am +- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +- +-installcheck: installcheck-recursive +-install-strip: +- if test -z '$(STRIP)'; then \ +- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +- install; \ +- else \ +- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ +- fi +-mostlyclean-generic: +- +-clean-generic: +- +-distclean-generic: +- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) +- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) +- +-maintainer-clean-generic: +- @echo "This command is intended for maintainers to use" +- @echo "it deletes files that may require special tools to rebuild." +-clean: clean-recursive +- +-clean-am: clean-generic mostlyclean-am +- +-distclean: distclean-recursive +- -rm -f $(am__CONFIG_DISTCLEAN_FILES) +- -rm -f Makefile +-distclean-am: clean-am distclean-generic distclean-hdr distclean-tags +- +-dvi: dvi-recursive +- +-dvi-am: +- +-html: html-recursive +- +-html-am: +- +-info: info-recursive +- +-info-am: +- +-install-data-am: +- +-install-dvi: install-dvi-recursive +- +-install-dvi-am: +- +-install-exec-am: +- +-install-html: install-html-recursive +- +-install-html-am: +- +-install-info: install-info-recursive +- +-install-info-am: +- +-install-man: +- +-install-pdf: install-pdf-recursive +- +-install-pdf-am: +- +-install-ps: install-ps-recursive +- +-install-ps-am: +- +-installcheck-am: +- +-maintainer-clean: maintainer-clean-recursive +- -rm -f $(am__CONFIG_DISTCLEAN_FILES) +- -rm -rf $(top_srcdir)/autom4te.cache +- -rm -f Makefile +-maintainer-clean-am: distclean-am maintainer-clean-generic +- +-mostlyclean: mostlyclean-recursive +- +-mostlyclean-am: mostlyclean-generic +- +-pdf: pdf-recursive +- +-pdf-am: +- +-ps: ps-recursive +- +-ps-am: +- +-uninstall-am: +- +-.MAKE: $(am__recursive_targets) all install-am install-strip +- +-.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ +- am--refresh check check-am clean clean-cscope clean-generic \ +- cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ +- dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ +- distcheck distclean distclean-generic distclean-hdr \ +- distclean-tags distcleancheck distdir distuninstallcheck dvi \ +- dvi-am html html-am info info-am install install-am \ +- install-data install-data-am install-dvi install-dvi-am \ +- install-exec install-exec-am install-html install-html-am \ +- install-info install-info-am install-man install-pdf \ +- install-pdf-am install-ps install-ps-am install-strip \ +- installcheck installcheck-am installdirs installdirs-am \ +- maintainer-clean maintainer-clean-generic mostlyclean \ +- mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ +- uninstall-am +- +- +-# Tell versions [3.59,3.63) of GNU make to not export all variables. +-# Otherwise a system limit (for SysV at least) may be exceeded. +-.NOEXPORT: +diff -Nuar groff-1.22.3.old/src/libs/libbib/.gitignore groff-1.22.3/src/libs/libbib/.gitignore +--- groff-1.22.3.old/src/libs/libbib/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/libs/libbib/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++Makefile.dep +diff -Nuar groff-1.22.3.old/src/libs/libbib/libbib.am groff-1.22.3/src/libs/libbib/libbib.am +--- groff-1.22.3.old/src/libs/libbib/libbib.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/libs/libbib/libbib.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,30 @@ ++# Automake rules for `libbib' ++# ++# File position: /src/libs/libbib/libbib.am ++# ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see ++# . ++# ++######################################################################## ++ ++noinst_LIBRARIES += libbib.a ++libbib_a_SOURCES = \ ++ src/libs/libbib/common.cpp \ ++ src/libs/libbib/index.cpp \ ++ src/libs/libbib/linear.cpp \ ++ src/libs/libbib/search.cpp \ ++ src/libs/libbib/map.c ++src/libs/libbib/index.$(OBJEXT): defs.h +diff -Nuar groff-1.22.3.old/src/libs/libbib/Makefile.sub groff-1.22.3/src/libs/libbib/Makefile.sub +--- groff-1.22.3.old/src/libs/libbib/Makefile.sub 2014-11-04 10:38:35.183524522 +0200 ++++ groff-1.22.3/src/libs/libbib/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,46 +0,0 @@ +-# Makefile.sub for `libbib' +-# +-# File position: /src/libs/libbib/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-LIB=bib +-OBJS=\ +- common.$(OBJEXT) \ +- index.$(OBJEXT) \ +- linear.$(OBJEXT) \ +- search.$(OBJEXT) \ +- map.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/common.cpp \ +- $(srcdir)/index.cpp \ +- $(srcdir)/linear.cpp \ +- $(srcdir)/search.cpp +-CSRCS=\ +- $(srcdir)/map.c +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/libs/libdriver/.gitignore groff-1.22.3/src/libs/libdriver/.gitignore +--- groff-1.22.3.old/src/libs/libdriver/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/libs/libdriver/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++Makefile.dep +diff -Nuar groff-1.22.3.old/src/libs/libdriver/libdriver.am groff-1.22.3/src/libs/libdriver/libdriver.am +--- groff-1.22.3.old/src/libs/libdriver/libdriver.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/libs/libdriver/libdriver.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,26 @@ ++# Automake rules for `libdriver' ++# ++# File position: /src/libs/libdriver/libdriver.am ++# ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see ++# . ++# ++######################################################################## ++ ++noinst_LIBRARIES += libdriver.a ++libdriver_a_SOURCES = \ ++ src/libs/libdriver/input.cpp \ ++ src/libs/libdriver/printer.cpp +diff -Nuar groff-1.22.3.old/src/libs/libdriver/Makefile.sub groff-1.22.3/src/libs/libdriver/Makefile.sub +--- groff-1.22.3.old/src/libs/libdriver/Makefile.sub 2014-11-04 10:38:35.178524584 +0200 ++++ groff-1.22.3/src/libs/libdriver/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,39 +0,0 @@ +-# Makefile.sub for `libdriver' +-# +-# File position: /src/libs/libdriver/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-LIB=driver +-OBJS=\ +- input.$(OBJEXT) \ +- printer.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/input.cpp \ +- $(srcdir)/printer.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/libs/libgroff/.gitignore groff-1.22.3/src/libs/libgroff/.gitignore +--- groff-1.22.3.old/src/libs/libgroff/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/libs/libgroff/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,5 @@ ++Makefile.dep ++version.cpp ++ref-del.sed ++ref-add.sed ++charset.alias +diff -Nuar groff-1.22.3.old/src/libs/libgroff/glyphuni.cpp groff-1.22.3/src/libs/libgroff/glyphuni.cpp +--- groff-1.22.3.old/src/libs/libgroff/glyphuni.cpp 2014-11-04 10:38:35.169524697 +0200 ++++ groff-1.22.3/src/libs/libgroff/glyphuni.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -474,12 +474,6 @@ + { "bracerightbt", "23AD" }, + { "an", "23AF" }, + { "br", "2502" }, +- { "rk", "251D" }, +- { "lk", "2525" }, +- { "lt", "256D" }, +- { "rt", "256E" }, +- { "rb", "256F" }, +- { "lb", "2570" }, + { "sq", "25A1" }, + { "lz", "25CA" }, + { "ci", "25CB" }, +diff -Nuar groff-1.22.3.old/src/libs/libgroff/lf.cpp groff-1.22.3/src/libs/libgroff/lf.cpp +--- groff-1.22.3.old/src/libs/libgroff/lf.cpp 2014-11-04 10:38:35.170524684 +0200 ++++ groff-1.22.3/src/libs/libgroff/lf.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -22,6 +22,7 @@ + #include "lib.h" + #include "cset.h" + #include "stringclass.h" ++#include "lf.h" + + extern void change_filename(const char *); + extern void change_lineno(int); +@@ -60,3 +61,18 @@ + change_lineno(ln); + return 1; + } ++ ++#if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__)) ++void normalize_for_lf (string &fn) ++{ ++ int fnlen = fn.length(); ++ for (int i = 0; i < fnlen; i++) { ++ if (fn[i] == '\\') ++ fn[i] = '/'; ++ } ++} ++#else ++void normalize_for_lf (string &) ++{ ++} ++#endif +diff -Nuar groff-1.22.3.old/src/libs/libgroff/libgroff.am groff-1.22.3/src/libs/libgroff/libgroff.am +--- groff-1.22.3.old/src/libs/libgroff/libgroff.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/libs/libgroff/libgroff.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,172 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++libgroff_srcdir = $(top_srcdir)/src/libs/libgroff ++noinst_LIBRARIES += libgroff.a ++libgroff_a_CPPFLAGS = \ ++ $(AM_CPPFLAGS) \ ++ -D__GETOPT_PREFIX=groff_ \ ++ -DENABLE_RELOCATABLE=1 \ ++ -DLIBDIR=\"$(libdir)\" ++ ++# Build from OBJS ++libgroff_a_SOURCES = \ ++ src/libs/libgroff/assert.cpp \ ++ src/libs/libgroff/change_lf.cpp \ ++ src/libs/libgroff/cmap.cpp \ ++ src/libs/libgroff/color.cpp \ ++ src/libs/libgroff/cset.cpp\ ++ src/libs/libgroff/device.cpp \ ++ src/libs/libgroff/errarg.cpp \ ++ src/libs/libgroff/error.cpp \ ++ src/libs/libgroff/fatal.cpp \ ++ src/libs/libgroff/filename.cpp \ ++ src/libs/libgroff/font.cpp \ ++ src/libs/libgroff/fontfile.cpp \ ++ src/libs/libgroff/geometry.cpp \ ++ src/libs/libgroff/getopt.c \ ++ src/libs/libgroff/getopt1.c \ ++ src/libs/libgroff/glyphuni.cpp \ ++ src/libs/libgroff/htmlhint.cpp \ ++ src/libs/libgroff/hypot.cpp \ ++ src/libs/libgroff/iftoa.c \ ++ src/libs/libgroff/invalid.cpp \ ++ src/libs/libgroff/itoa.c \ ++ src/libs/libgroff/lf.cpp \ ++ src/libs/libgroff/lineno.cpp \ ++ src/libs/libgroff/localcharset.c \ ++ src/libs/libgroff/macropath.cpp \ ++ src/libs/libgroff/matherr.c \ ++ src/libs/libgroff/maxfilename.cpp \ ++ src/libs/libgroff/maxpathname.cpp \ ++ src/libs/libgroff/mksdir.cpp \ ++ src/libs/libgroff/nametoindex.cpp \ ++ src/libs/libgroff/new.cpp \ ++ src/libs/libgroff/paper.cpp \ ++ src/libs/libgroff/prime.cpp \ ++ src/libs/libgroff/progname.c \ ++ src/libs/libgroff/ptable.cpp \ ++ src/libs/libgroff/quotearg.c \ ++ src/libs/libgroff/relocate.cpp \ ++ src/libs/libgroff/searchpath.cpp \ ++ src/libs/libgroff/spawnvp.c \ ++ src/libs/libgroff/string.cpp \ ++ src/libs/libgroff/strsave.cpp \ ++ src/libs/libgroff/symbol.cpp \ ++ src/libs/libgroff/tmpfile.cpp \ ++ src/libs/libgroff/tmpname.cpp \ ++ src/libs/libgroff/unicode.cpp \ ++ src/libs/libgroff/uniglyph.cpp \ ++ src/libs/libgroff/uniuni.cpp \ ++ src/libs/libgroff/relocatable.h ++nodist_libgroff_a_SOURCES = src/libs/libgroff/version.cpp ++ ++# TODO: these .c files could be removed (use gnulib instead), same ++# thing for snprintf. ++EXTRA_DIST += \ ++ src/libs/libgroff/mkstemp.cpp \ ++ src/libs/libgroff/fmod.c \ ++ src/libs/libgroff/getcwd.c \ ++ src/libs/libgroff/putenv.c \ ++ src/libs/libgroff/strcasecmp.c \ ++ src/libs/libgroff/strerror.c \ ++ src/libs/libgroff/strncasecmp.c \ ++ src/libs/libgroff/strtol.c \ ++ src/libs/libgroff/config.charset \ ++ src/libs/libgroff/ref-add.sin \ ++ src/libs/libgroff/ref-del.sin \ ++ src/libs/libgroff/make-uniuni \ ++ src/libs/snprintf/snprintf.c ++ ++src_version=`cat $(top_srcdir)/VERSION` ++src_revision=`cat $(top_srcdir)/REVISION` ++ ++CLEANFILES += \ ++ src/libs/libgroff/version.cpp \ ++ charset.alias \ ++ ref-add.sed \ ++ ref-del.sed ++ ++# .o files have a 'libgroff_a-' prefix because we set libgroff_a_CPPFLAGS ++src/libs/libgroff/libgroff_a-device.$(OBJEXT): defs.h ++src/libs/libgroff/libgroff_a-fontfile.$(OBJEXT): defs.h ++src/libs/libgroff/libgroff_a-macropath.$(OBJEXT): defs.h ++src/libs/libgroff/libgroff_a-relocate.$(OBJEXT): defs.h ++ ++src/libs/libgroff/version.cpp: $(top_srcdir)/VERSION $(top_srcdir)/REVISION ++ @echo Making version.cpp ++ @echo const char \*version_string = \"$(src_version)\"\; >$@ ++ @echo const char \*revision_string = \"$(src_revision)\"\; >>$@ ++ @echo extern \"C\" { >>$@ ++ @echo const char \*Version_string = \"$(src_version).$(src_revision)\"\; >>$@ ++ @echo } >>$@ \ ++ | sed -e 's/\.0\"/\"/' >>$@ ++ ++# Data for localcharset.c. Taken from libiconv/libcharset. ++ ++LIBGROFF_PACKAGE = groff ++ ++all: charset.alias ref-add.sed ref-del.sed ++ ++charset.alias: $(libgroff_srcdir)/config.charset ++ $(SHELL) $(libgroff_srcdir)/config.charset '$(HOST)' > t-$@ ++ mv t-$@ $@ ++ ++ref-add.sed : $(libgroff_srcdir)/ref-add.sin ++ sed -e '/^#/d' \ ++ -e 's/@''PACKAGE''@/$(LIBGROFF_PACKAGE)/g' $(libgroff_srcdir)/ref-add.sin > t-$@ ++ mv t-$@ $@ ++ ++ref-del.sed : $(libgroff_srcdir)/ref-del.sin ++ sed -e '/^#/d' \ ++ -e 's/@''PACKAGE''@/$(LIBGROFF_PACKAGE)/g' $(libgroff_srcdir)/ref-del.sin > t-$@ ++ mv t-$@ $@ ++ ++install-data-local: install_charset_data ++install_charset_data: ++ -test $(GLIBC21) != no || $(mkinstalldirs) $(DESTDIR)$(libdir) ++ if test -f $(DESTDIR)$(libdir)/charset.alias; then \ ++ sed -f ref-add.sed $(DESTDIR)$(libdir)/charset.alias \ ++ > $(DESTDIR)$(libdir)/t-charset.alias; \ ++ $(INSTALL_DATA) $(DESTDIR)$(libdir)/t-charset.alias \ ++ $(DESTDIR)$(libdir)/charset.alias; \ ++ rm -f $(DESTDIR)$(libdir)/t-charset.alias; \ ++ else \ ++ if test $(GLIBC21) = no; then \ ++ sed -f ref-add.sed charset.alias \ ++ > $(DESTDIR)$(libdir)/t-charset.alias; \ ++ $(INSTALL_DATA) $(DESTDIR)$(libdir)/t-charset.alias \ ++ $(DESTDIR)$(libdir)/charset.alias; \ ++ rm -f $(DESTDIR)$(libdir)/t-charset.alias; \ ++ fi; \ ++ fi ++ ++uninstall-local: uninstall_charset_data ++uninstall_charset_data: ++ -if test -f $(DESTDIR)$(libdir)/charset.alias; then \ ++ sed -f ref-del.sed $(DESTDIR)$(libdir)/charset.alias \ ++ > $(DESTDIR)$(libdir)/t-charset.alias; \ ++ if grep '^# Packages using this file: $$' \ ++ $(DESTDIR)$(libdir)/t-charset.alias > /dev/null; then \ ++ rm -f $(DESTDIR)$(libdir)/charset.alias; \ ++ else \ ++ $(INSTALL_DATA) $(DESTDIR)$(libdir)/t-charset.alias \ ++ $(DESTDIR)$(libdir)/charset.alias; \ ++ fi; \ ++ rm -f $(DESTDIR)$(libdir)/t-charset.alias; \ ++ fi +diff -Nuar groff-1.22.3.old/src/libs/libgroff/Makefile.sub groff-1.22.3/src/libs/libgroff/Makefile.sub +--- groff-1.22.3.old/src/libs/libgroff/Makefile.sub 2014-11-04 10:38:35.170524684 +0200 ++++ groff-1.22.3/src/libs/libgroff/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,223 +0,0 @@ +-# Makefile.sub for `libgroff' +-# +-# File position: /src/libs/libgroff/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-LIB=groff +-EXTRA_CFLAGS=-D__GETOPT_PREFIX=groff_ \ +- -DENABLE_RELOCATABLE=1 \ +- -DLIBDIR=\"$(libdir)\" +-OBJS=\ +- assert.$(OBJEXT) \ +- change_lf.$(OBJEXT) \ +- cmap.$(OBJEXT) \ +- color.$(OBJEXT) \ +- cset.$(OBJEXT) \ +- device.$(OBJEXT) \ +- errarg.$(OBJEXT) \ +- error.$(OBJEXT) \ +- fatal.$(OBJEXT) \ +- filename.$(OBJEXT) \ +- font.$(OBJEXT) \ +- fontfile.$(OBJEXT) \ +- geometry.$(OBJEXT) \ +- getopt.$(OBJEXT) \ +- getopt1.$(OBJEXT) \ +- glyphuni.$(OBJEXT) \ +- htmlhint.$(OBJEXT) \ +- hypot.$(OBJEXT) \ +- iftoa.$(OBJEXT) \ +- invalid.$(OBJEXT) \ +- itoa.$(OBJEXT) \ +- lf.$(OBJEXT) \ +- lineno.$(OBJEXT) \ +- localcharset.$(OBJEXT) \ +- macropath.$(OBJEXT) \ +- matherr.$(OBJEXT) \ +- maxfilename.$(OBJEXT) \ +- maxpathname.$(OBJEXT) \ +- mksdir.$(OBJEXT) \ +- nametoindex.$(OBJEXT) \ +- new.$(OBJEXT) \ +- paper.$(OBJEXT) \ +- prime.$(OBJEXT) \ +- progname.$(OBJEXT) \ +- ptable.$(OBJEXT) \ +- quotearg.$(OBJEXT) \ +- relocate.$(OBJEXT) \ +- searchpath.$(OBJEXT) \ +- spawnvp.$(OBJEXT) \ +- string.$(OBJEXT) \ +- strsave.$(OBJEXT) \ +- symbol.$(OBJEXT) \ +- tmpfile.$(OBJEXT) \ +- tmpname.$(OBJEXT) \ +- unicode.$(OBJEXT) \ +- uniglyph.$(OBJEXT) \ +- uniuni.$(OBJEXT) \ +- version.$(OBJEXT) \ +- $(LIBOBJS) +-CCSRCS=\ +- $(srcdir)/assert.cpp \ +- $(srcdir)/change_lf.cpp \ +- $(srcdir)/cmap.cpp \ +- $(srcdir)/color.cpp \ +- $(srcdir)/cset.cpp \ +- $(srcdir)/device.cpp \ +- $(srcdir)/errarg.cpp \ +- $(srcdir)/error.cpp \ +- $(srcdir)/fatal.cpp \ +- $(srcdir)/filename.cpp \ +- $(srcdir)/font.cpp \ +- $(srcdir)/fontfile.cpp \ +- $(srcdir)/geometry.cpp \ +- $(srcdir)/glyphuni.cpp \ +- $(srcdir)/htmlhint.cpp \ +- $(srcdir)/hypot.cpp \ +- $(srcdir)/invalid.cpp \ +- $(srcdir)/lf.cpp \ +- $(srcdir)/lineno.cpp \ +- $(srcdir)/macropath.cpp \ +- $(srcdir)/maxfilename.cpp \ +- $(srcdir)/maxpathname.cpp \ +- $(srcdir)/mksdir.cpp \ +- $(srcdir)/mkstemp.cpp \ +- $(srcdir)/nametoindex.cpp \ +- $(srcdir)/new.cpp \ +- $(srcdir)/paper.cpp \ +- $(srcdir)/prime.cpp \ +- $(srcdir)/ptable.cpp \ +- $(srcdir)/relocate.cpp \ +- $(srcdir)/searchpath.cpp \ +- $(srcdir)/string.cpp \ +- $(srcdir)/strsave.cpp \ +- $(srcdir)/symbol.cpp \ +- $(srcdir)/tmpfile.cpp \ +- $(srcdir)/tmpname.cpp \ +- $(srcdir)/unicode.cpp \ +- $(srcdir)/uniglyph.cpp \ +- $(srcdir)/uniuni.cpp \ +- version.cpp +-CSRCS=\ +- $(srcdir)/fmod.c \ +- $(srcdir)/getcwd.c \ +- $(srcdir)/getopt.c \ +- $(srcdir)/getopt1.c \ +- $(srcdir)/iftoa.c \ +- $(srcdir)/itoa.c \ +- $(srcdir)/localcharset.c \ +- $(srcdir)/matherr.c \ +- $(srcdir)/progname.c \ +- $(srcdir)/putenv.c \ +- $(srcdir)/quotearg.c \ +- $(srcdir)/spawnvp.c \ +- $(srcdir)/strcasecmp.c \ +- $(srcdir)/strerror.c \ +- $(srcdir)/strncasecmp.c \ +- $(srcdir)/strtol.c \ +- $(srcdir)/../snprintf/snprintf.c +-GENSRCS=\ +- version.cpp +-RM=rm -f +- +-src_version=`cat $(top_srcdir)/VERSION` +-src_revision=`cat $(top_srcdir)/REVISION` +- +-version.cpp: $(top_srcdir)/VERSION $(top_srcdir)/REVISION +- @echo Making version.cpp +- @echo const char \*version_string = \"$(src_version)\"\; >$@ +- @echo const char \*revision_string = \"$(src_revision)\"\; >>$@ +- @echo extern \"C\" const char \*Version_string = \"$(src_version).$(src_revision)\"\; \ +- | sed -e 's/\.0\"/\"/' >>$@ +- +-# We have to avoid $(COMPILE.c) since we must not use groff's `assert.h' +-snprintf.$(OBJEXT): $(srcdir)/../snprintf/snprintf.c +- $(CC) -c $(CDEFINES) $(CFLAGS) $(CPPFLAGS) \ +- $(srcdir)/../snprintf/snprintf.c +- +-# Data for localcharset.c. Taken from libiconv/libcharset. +- +-all: charset.alias ref-add.sed ref-del.sed +- +-charset.alias: $(srcdir)/config.charset +- $(SHELL) $(srcdir)/config.charset '$(HOST)' > t-$@ +- mv t-$@ $@ +- +-PACKAGE=groff +- +-ref-add.sed : $(srcdir)/ref-add.sin +- sed -e '/^#/d' \ +- -e 's/@''PACKAGE''@/$(PACKAGE)/g' $(srcdir)/ref-add.sin > t-$@ +- mv t-$@ $@ +- +-ref-del.sed : $(srcdir)/ref-del.sin +- sed -e '/^#/d' \ +- -e 's/@''PACKAGE''@/$(PACKAGE)/g' $(srcdir)/ref-del.sin > t-$@ +- mv t-$@ $@ +- +-MKINSTALLDIRS = $(SHELL) $(top_srcdir)/mkinstalldirs +- +-install_data: install_charset_data +-install_charset_data: +- -test $(GLIBC21) != no || $(MKINSTALLDIRS) $(DESTDIR)$(libdir) +- if test -f $(DESTDIR)$(libdir)/charset.alias; then \ +- sed -f ref-add.sed $(DESTDIR)$(libdir)/charset.alias \ +- > $(DESTDIR)$(libdir)/t-charset.alias; \ +- $(INSTALL_DATA) $(DESTDIR)$(libdir)/t-charset.alias \ +- $(DESTDIR)$(libdir)/charset.alias; \ +- $(RM) $(DESTDIR)$(libdir)/t-charset.alias; \ +- else \ +- if test $(GLIBC21) = no; then \ +- sed -f ref-add.sed charset.alias \ +- > $(DESTDIR)$(libdir)/t-charset.alias; \ +- $(INSTALL_DATA) $(DESTDIR)$(libdir)/t-charset.alias \ +- $(DESTDIR)$(libdir)/charset.alias; \ +- $(RM) $(DESTDIR)$(libdir)/t-charset.alias; \ +- fi; \ +- fi +- +-uninstall_sub: uninstall_charset_data +-uninstall_charset_data: +- -if test -f $(DESTDIR)$(libdir)/charset.alias; then \ +- sed -f ref-del.sed $(DESTDIR)$(libdir)/charset.alias \ +- > $(DESTDIR)$(libdir)/t-charset.alias; \ +- if grep '^# Packages using this file: $$' \ +- $(DESTDIR)$(libdir)/t-charset.alias > /dev/null; then \ +- $(RM) $(DESTDIR)$(libdir)/charset.alias; \ +- else \ +- $(INSTALL_DATA) $(DESTDIR)$(libdir)/t-charset.alias \ +- $(DESTDIR)$(libdir)/charset.alias; \ +- fi; \ +- $(RM) $(DESTDIR)$(libdir)/t-charset.alias; \ +- fi +- +-clean: clean_charset +-clean_charset: +- $(RM) charset.alias ref-add.sed ref-del.sed +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/libs/libgroff/make-uniuni groff-1.22.3/src/libs/libgroff/make-uniuni +--- groff-1.22.3.old/src/libs/libgroff/make-uniuni 2014-11-04 10:38:35.170524684 +0200 ++++ groff-1.22.3/src/libs/libgroff/make-uniuni 2015-04-23 20:57:03.000000000 +0300 +@@ -74,8 +74,7 @@ + # Write preamble. + cat < + + This file is part of groff. +diff -Nuar groff-1.22.3.old/src/libs/libgroff/uniglyph.cpp groff-1.22.3/src/libs/libgroff/uniglyph.cpp +--- groff-1.22.3.old/src/libs/libgroff/uniglyph.cpp 2014-11-04 10:38:35.172524659 +0200 ++++ groff-1.22.3/src/libs/libgroff/uniglyph.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -460,12 +460,6 @@ + //{ "23AD", "bracerightbt" }, + { "23AF", "an" }, + { "2502", "br" }, +- { "251D", "rk" }, +- { "2525", "lk" }, +- { "256D", "lt" }, +- { "256E", "rt" }, +- { "256F", "rb" }, +- { "2570", "lb" }, + { "25A1", "sq" }, + { "25CA", "lz" }, + { "25CB", "ci" }, +diff -Nuar groff-1.22.3.old/src/libs/libgroff/uniuni.cpp groff-1.22.3/src/libs/libgroff/uniuni.cpp +--- groff-1.22.3.old/src/libs/libgroff/uniuni.cpp 2014-11-04 10:38:35.173524647 +0200 ++++ groff-1.22.3/src/libs/libgroff/uniuni.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -18,8 +18,8 @@ + along with this program. If not, see . */ + + // This code has been algorithmically derived from the file +-// UnicodeData.txt, version 4.1.0, available from unicode.org, +-// on 2005-12-09. ++// UnicodeData.txt, version 7.0.0, available from unicode.org, ++// on 2014-12-16. + + #include "lib.h" + #include "stringclass.h" +@@ -446,6 +446,17 @@ + { "0FAC", "20FAB_0FB7" }, + { "0FB9", "20F90_0FB5" }, + { "1026", "21025_102E" }, ++ { "1B06", "21B05_1B35" }, ++ { "1B08", "21B07_1B35" }, ++ { "1B0A", "21B09_1B35" }, ++ { "1B0C", "21B0B_1B35" }, ++ { "1B0E", "21B0D_1B35" }, ++ { "1B12", "21B11_1B35" }, ++ { "1B3B", "21B3A_1B35" }, ++ { "1B3D", "21B3C_1B35" }, ++ { "1B40", "21B3E_1B35" }, ++ { "1B41", "21B3F_1B35" }, ++ { "1B43", "21B42_1B35" }, + { "1E00", "20041_0325" }, + { "1E01", "20061_0325" }, + { "1E02", "20042_0307" }, +@@ -1320,6 +1331,8 @@ + { "FA2B", "198FC" }, + { "FA2C", "19928" }, + { "FA2D", "19DB4" }, ++ { "FA2E", "190DE" }, ++ { "FA2F", "196B7" }, + { "FA30", "14FAE" }, + { "FA31", "150E7" }, + { "FA32", "1514D" }, +@@ -1379,6 +1392,9 @@ + { "FA68", "196E3" }, + { "FA69", "197FF" }, + { "FA6A", "1983B" }, ++ { "FA6B", "16075" }, ++ { "FA6C", "1242EE" }, ++ { "FA6D", "18218" }, + { "FA70", "14E26" }, + { "FA71", "151B5" }, + { "FA72", "15168" }, +@@ -1519,6 +1535,18 @@ + { "FB4C", "205D1_05BF" }, + { "FB4D", "205DB_05BF" }, + { "FB4E", "205E4_05BF" }, ++ { "1109A", "211099_110BA" }, ++ { "1109C", "21109B_110BA" }, ++ { "110AB", "2110A5_110BA" }, ++ { "1112E", "211131_11127" }, ++ { "1112F", "211132_11127" }, ++ { "1134B", "211347_1133E" }, ++ { "1134C", "211347_11357" }, ++ { "114BB", "2114B9_114BA" }, ++ { "114BC", "2114B9_114B0" }, ++ { "114BE", "2114B9_114BD" }, ++ { "115BA", "2115B8_115AF" }, ++ { "115BB", "2115B9_115AF" }, + { "1D15E", "21D157_1D165" }, + { "1D15F", "21D158_1D165" }, + { "1D160", "31D158_1D165_1D16E" }, +diff -Nuar groff-1.22.3.old/src/libs/libxutil/.gitignore groff-1.22.3/src/libs/libxutil/.gitignore +--- groff-1.22.3.old/src/libs/libxutil/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/libs/libxutil/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++Makefile.dep +diff -Nuar groff-1.22.3.old/src/libs/libxutil/libxutil.am groff-1.22.3/src/libs/libxutil/libxutil.am +--- groff-1.22.3.old/src/libs/libxutil/libxutil.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/libs/libxutil/libxutil.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,30 @@ ++# Automake rules for `libxutil' ++# ++# File position: /src/libs/libxutil/libxutil.am ++# ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see ++# . ++# ++######################################################################## ++ ++if !WITHOUT_X11 ++noinst_LIBRARIES += libxutil.a ++libxutil_a_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) ++libxutil_a_SOURCES = \ ++ src/libs/libxutil/DviChar.c \ ++ src/libs/libxutil/XFontName.c \ ++ src/libs/libxutil/xmalloc.c ++endif +diff -Nuar groff-1.22.3.old/src/libs/libxutil/Makefile.sub groff-1.22.3/src/libs/libxutil/Makefile.sub +--- groff-1.22.3.old/src/libs/libxutil/Makefile.sub 2014-11-04 10:38:35.187524472 +0200 ++++ groff-1.22.3/src/libs/libxutil/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,42 +0,0 @@ +-# Makefile.sub for `libxutil' +-# +-# File position: /src/libs/libxutil/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-LIB=xutil +-EXTRA_CFLAGS=$(X_CFLAGS) +-OBJS=\ +- DviChar.$(OBJEXT) \ +- XFontName.$(OBJEXT) \ +- xmalloc.$(OBJEXT) +-CSRCS=\ +- $(srcdir)/DviChar.c \ +- $(srcdir)/XFontName.c \ +- $(srcdir)/xmalloc.c +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/preproc/eqn/eqn.am groff-1.22.3/src/preproc/eqn/eqn.am +--- groff-1.22.3.old/src/preproc/eqn/eqn.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/eqn/eqn.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,64 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++prefixexecbin_PROGRAMS += eqn ++prefixexecbin_SCRIPTS += neqn ++eqn_CPPFLAGS = \ ++ $(AM_CPPFLAGS) \ ++ -I $(top_srcdir)/src/preproc/eqn \ ++ -I $(top_builddir)/src/preproc/eqn ++eqn_LDADD = $(LIBM) libgroff.a ++eqn_SOURCES = \ ++ src/preproc/eqn/main.cpp \ ++ src/preproc/eqn/lex.cpp \ ++ src/preproc/eqn/box.cpp \ ++ src/preproc/eqn/limit.cpp \ ++ src/preproc/eqn/list.cpp \ ++ src/preproc/eqn/over.cpp \ ++ src/preproc/eqn/text.cpp \ ++ src/preproc/eqn/script.cpp \ ++ src/preproc/eqn/mark.cpp \ ++ src/preproc/eqn/other.cpp \ ++ src/preproc/eqn/delim.cpp \ ++ src/preproc/eqn/sqrt.cpp \ ++ src/preproc/eqn/pile.cpp \ ++ src/preproc/eqn/special.cpp \ ++ src/preproc/eqn/eqn.ypp \ ++ src/preproc/eqn/box.h \ ++ src/preproc/eqn/pbox.h \ ++ src/preproc/eqn/eqn.h ++ ++PREFIXMAN1 += src/preproc/eqn/eqn.n src/preproc/eqn/neqn.n ++EXTRA_DIST += \ ++ src/preproc/eqn/TODO \ ++ src/preproc/eqn/neqn.sh \ ++ src/preproc/eqn/eqn.man \ ++ src/preproc/eqn/neqn.man ++ ++src/preproc/eqn/eqn-lex.$(OBJEXT): src/preproc/eqn/eqn.hpp ++CLEANFILES += \ ++ src/preproc/eqn/eqn.hpp \ ++ src/preproc/eqn/eqn.cpp \ ++ src/preproc/eqn/eqn.output ++ ++neqn: $(top_srcdir)/src/preproc/eqn/neqn.sh $(SH_DEPS_SED_SCRIPT) ++ $(RM) $@ ++ sed -e 's/[@]g[@]/$(g)/g' \ ++ -f $(SH_DEPS_SED_SCRIPT) \ ++ -e $(SH_SCRIPT_SED_CMD) $(top_srcdir)/src/preproc/eqn/neqn.sh >$@ ++ chmod +x $@ +diff -Nuar groff-1.22.3.old/src/preproc/eqn/eqn.cpp groff-1.22.3/src/preproc/eqn/eqn.cpp +--- groff-1.22.3.old/src/preproc/eqn/eqn.cpp 2014-11-04 10:38:38.327485217 +0200 ++++ groff-1.22.3/src/preproc/eqn/eqn.cpp 1970-01-01 02:00:00.000000000 +0200 +@@ -1,2163 +0,0 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ +- +-/* Bison implementation for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation, either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* C LALR(1) parser skeleton written by Richard Stallman, by +- simplifying the original so-called "semantic" parser. */ +- +-/* All symbols defined below should begin with yy or YY, to avoid +- infringing on user name space. This should be done even for local +- variables, as they might otherwise be expanded by user macros. +- There are some unavoidable exceptions within include files to +- define necessary library symbols; they are noted "INFRINGES ON +- USER NAME SPACE" below. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 +- +-/* Bison version. */ +-#define YYBISON_VERSION "3.0.2" +- +-/* Skeleton name. */ +-#define YYSKELETON_NAME "yacc.c" +- +-/* Pure parsers. */ +-#define YYPURE 0 +- +-/* Push parsers. */ +-#define YYPUSH 0 +- +-/* Pull parsers. */ +-#define YYPULL 1 +- +- +- +- +-/* Copy the first part of user declarations. */ +-#line 18 "eqn.y" /* yacc.c:339 */ +- +-#include +-#include +-#include +- +-#include "lib.h" +-#include "box.h" +-extern int non_empty_flag; +-int yylex(); +-void yyerror(const char *); +- +-#line 78 "eqn.cpp" /* yacc.c:339 */ +- +-# ifndef YY_NULLPTR +-# if defined __cplusplus && 201103L <= __cplusplus +-# define YY_NULLPTR nullptr +-# else +-# define YY_NULLPTR 0 +-# endif +-# endif +- +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 0 +-#endif +- +-/* In a future release of Bison, this section will be replaced +- by #include "y.tab.h". */ +-#ifndef YY_YY_Y_TAB_H_INCLUDED +-# define YY_YY_Y_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; +-#endif +- +-/* Token type. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- enum yytokentype +- { +- OVER = 258, +- SMALLOVER = 259, +- SQRT = 260, +- SUB = 261, +- SUP = 262, +- LPILE = 263, +- RPILE = 264, +- CPILE = 265, +- PILE = 266, +- LEFT = 267, +- RIGHT = 268, +- TO = 269, +- FROM = 270, +- SIZE = 271, +- FONT = 272, +- ROMAN = 273, +- BOLD = 274, +- ITALIC = 275, +- FAT = 276, +- ACCENT = 277, +- BAR = 278, +- UNDER = 279, +- ABOVE = 280, +- TEXT = 281, +- QUOTED_TEXT = 282, +- FWD = 283, +- BACK = 284, +- DOWN = 285, +- UP = 286, +- MATRIX = 287, +- COL = 288, +- LCOL = 289, +- RCOL = 290, +- CCOL = 291, +- MARK = 292, +- LINEUP = 293, +- TYPE = 294, +- VCENTER = 295, +- PRIME = 296, +- SPLIT = 297, +- NOSPLIT = 298, +- UACCENT = 299, +- SPECIAL = 300, +- SPACE = 301, +- GFONT = 302, +- GSIZE = 303, +- DEFINE = 304, +- NDEFINE = 305, +- TDEFINE = 306, +- SDEFINE = 307, +- UNDEF = 308, +- IFDEF = 309, +- INCLUDE = 310, +- DELIM = 311, +- CHARTYPE = 312, +- SET = 313, +- GRFONT = 314, +- GBFONT = 315 +- }; +-#endif +-/* Tokens. */ +-#define OVER 258 +-#define SMALLOVER 259 +-#define SQRT 260 +-#define SUB 261 +-#define SUP 262 +-#define LPILE 263 +-#define RPILE 264 +-#define CPILE 265 +-#define PILE 266 +-#define LEFT 267 +-#define RIGHT 268 +-#define TO 269 +-#define FROM 270 +-#define SIZE 271 +-#define FONT 272 +-#define ROMAN 273 +-#define BOLD 274 +-#define ITALIC 275 +-#define FAT 276 +-#define ACCENT 277 +-#define BAR 278 +-#define UNDER 279 +-#define ABOVE 280 +-#define TEXT 281 +-#define QUOTED_TEXT 282 +-#define FWD 283 +-#define BACK 284 +-#define DOWN 285 +-#define UP 286 +-#define MATRIX 287 +-#define COL 288 +-#define LCOL 289 +-#define RCOL 290 +-#define CCOL 291 +-#define MARK 292 +-#define LINEUP 293 +-#define TYPE 294 +-#define VCENTER 295 +-#define PRIME 296 +-#define SPLIT 297 +-#define NOSPLIT 298 +-#define UACCENT 299 +-#define SPECIAL 300 +-#define SPACE 301 +-#define GFONT 302 +-#define GSIZE 303 +-#define DEFINE 304 +-#define NDEFINE 305 +-#define TDEFINE 306 +-#define SDEFINE 307 +-#define UNDEF 308 +-#define IFDEF 309 +-#define INCLUDE 310 +-#define DELIM 311 +-#define CHARTYPE 312 +-#define SET 313 +-#define GRFONT 314 +-#define GBFONT 315 +- +-/* Value type. */ +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE +-{ +-#line 30 "eqn.y" /* yacc.c:355 */ +- +- char *str; +- box *b; +- pile_box *pb; +- matrix_box *mb; +- int n; +- column *col; +- +-#line 247 "eqn.cpp" /* yacc.c:355 */ +-}; +-# define YYSTYPE_IS_TRIVIAL 1 +-# define YYSTYPE_IS_DECLARED 1 +-#endif +- +- +-extern YYSTYPE yylval; +- +-int yyparse (void); +- +-#endif /* !YY_YY_Y_TAB_H_INCLUDED */ +- +-/* Copy the second part of user declarations. */ +- +-#line 262 "eqn.cpp" /* yacc.c:358 */ +- +-#ifdef short +-# undef short +-#endif +- +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; +-#endif +- +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; +-#else +-typedef signed char yytype_int8; +-#endif +- +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; +-#else +-typedef unsigned short int yytype_uint16; +-#endif +- +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; +-#else +-typedef short int yytype_int16; +-#endif +- +-#ifndef YYSIZE_T +-# ifdef __SIZE_TYPE__ +-# define YYSIZE_T __SIZE_TYPE__ +-# elif defined size_t +-# define YYSIZE_T size_t +-# elif ! defined YYSIZE_T +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# else +-# define YYSIZE_T unsigned int +-# endif +-#endif +- +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +- +-#ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS +-# if ENABLE_NLS +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +-# endif +-# endif +-# ifndef YY_ +-# define YY_(Msgid) Msgid +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE +-# if (defined __GNUC__ \ +- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ +- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +-# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +-# else +-# define YY_ATTRIBUTE(Spec) /* empty */ +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE_PURE +-# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +-#endif +- +-#ifndef YY_ATTRIBUTE_UNUSED +-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +-#endif +- +-#if !defined _Noreturn \ +- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +-# if defined _MSC_VER && 1200 <= _MSC_VER +-# define _Noreturn __declspec (noreturn) +-# else +-# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +-# endif +-#endif +- +-/* Suppress unused-variable warnings by "using" E. */ +-#if ! defined lint || defined __GNUC__ +-# define YYUSE(E) ((void) (E)) +-#else +-# define YYUSE(E) /* empty */ +-#endif +- +-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +-/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +- _Pragma ("GCC diagnostic push") \ +- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +- _Pragma ("GCC diagnostic pop") +-#else +-# define YY_INITIAL_VALUE(Value) Value +-#endif +-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END +-#endif +-#ifndef YY_INITIAL_VALUE +-# define YY_INITIAL_VALUE(Value) /* Nothing. */ +-#endif +- +- +-#if ! defined yyoverflow || YYERROR_VERBOSE +- +-/* The parser invokes alloca or malloc; define the necessary symbols. */ +- +-# ifdef YYSTACK_USE_ALLOCA +-# if YYSTACK_USE_ALLOCA +-# ifdef __GNUC__ +-# define YYSTACK_ALLOC __builtin_alloca +-# elif defined __BUILTIN_VA_ARG_INCR +-# include /* INFRINGES ON USER NAME SPACE */ +-# elif defined _AIX +-# define YYSTACK_ALLOC __alloca +-# elif defined _MSC_VER +-# include /* INFRINGES ON USER NAME SPACE */ +-# define alloca _alloca +-# else +-# define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +-# include /* INFRINGES ON USER NAME SPACE */ +- /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +-# ifndef EXIT_SUCCESS +-# define EXIT_SUCCESS 0 +-# endif +-# endif +-# endif +-# endif +-# endif +- +-# ifdef YYSTACK_ALLOC +- /* Pacify GCC's 'empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +-# ifndef YYSTACK_ALLOC_MAXIMUM +- /* The OS might guarantee only one guard page at the bottom of the stack, +- and a page size can be as small as 4096 bytes. So we cannot safely +- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number +- to allow for a few compiler-allocated temporary stack slots. */ +-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +-# endif +-# else +-# define YYSTACK_ALLOC YYMALLOC +-# define YYSTACK_FREE YYFREE +-# ifndef YYSTACK_ALLOC_MAXIMUM +-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +-# endif +-# if (defined __cplusplus && ! defined EXIT_SUCCESS \ +- && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef EXIT_SUCCESS +-# define EXIT_SUCCESS 0 +-# endif +-# endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc +-# if ! defined malloc && ! defined EXIT_SUCCESS +-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# ifndef YYFREE +-# define YYFREE free +-# if ! defined free && ! defined EXIT_SUCCESS +-void free (void *); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- +- +-#if (! defined yyoverflow \ +- && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +- +-/* A type that is properly aligned for any stack member. */ +-union yyalloc +-{ +- yytype_int16 yyss_alloc; +- YYSTYPE yyvs_alloc; +-}; +- +-/* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +- +-/* The size of an array large to enough to hold all stacks, each with +- N elements. */ +-# define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) +- +-# define YYCOPY_NEEDED 1 +- +-/* Relocate STACK from its old location to the new one. The +- local variables YYSIZE and YYSTACKSIZE give the old and new number of +- elements in the stack, and YYPTR gives the new location of the +- stack. Advance YYPTR to a properly aligned location for the next +- stack. */ +-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ +- Stack = &yyptr->Stack_alloc; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (0) +- +-#endif +- +-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +-/* Copy COUNT objects from SRC to DST. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(Dst, Src, Count) \ +- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +-# else +-# define YYCOPY(Dst, Src, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (Dst)[yyi] = (Src)[yyi]; \ +- } \ +- while (0) +-# endif +-# endif +-#endif /* !YYCOPY_NEEDED */ +- +-/* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 72 +-/* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 379 +- +-/* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 66 +-/* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 18 +-/* YYNRULES -- Number of rules. */ +-#define YYNRULES 75 +-/* YYNSTATES -- Number of states. */ +-#define YYNSTATES 142 +- +-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned +- by yylex, with out-of-bounds checking. */ +-#define YYUNDEFTOK 2 +-#define YYMAXUTOK 315 +- +-#define YYTRANSLATE(YYX) \ +- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +- +-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM +- as returned by yylex, without out-of-bounds checking. */ +-static const yytype_uint8 yytranslate[] = +-{ +- 0, 2, 2, 2, 2, 2, 2, 2, 2, 63, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 61, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 64, 2, 65, 62, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, +- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, +- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, +- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, +- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, +- 55, 56, 57, 58, 59, 60 +-}; +- +-#if YYDEBUG +- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +-static const yytype_uint16 yyrline[] = +-{ +- 0, 121, 121, 123, 128, 130, 141, 143, 145, 150, +- 152, 154, 156, 158, 163, 165, 167, 169, 174, 176, +- 181, 183, 185, 190, 192, 194, 196, 198, 200, 202, +- 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, +- 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, +- 244, 246, 248, 250, 252, 254, 259, 269, 271, 276, +- 278, 283, 285, 290, 292, 297, 299, 304, 306, 308, +- 310, 314, 316, 321, 323, 325 +-}; +-#endif +- +-#if YYDEBUG || YYERROR_VERBOSE || 0 +-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +-static const char *const yytname[] = +-{ +- "$end", "error", "$undefined", "OVER", "SMALLOVER", "SQRT", "SUB", +- "SUP", "LPILE", "RPILE", "CPILE", "PILE", "LEFT", "RIGHT", "TO", "FROM", +- "SIZE", "FONT", "ROMAN", "BOLD", "ITALIC", "FAT", "ACCENT", "BAR", +- "UNDER", "ABOVE", "TEXT", "QUOTED_TEXT", "FWD", "BACK", "DOWN", "UP", +- "MATRIX", "COL", "LCOL", "RCOL", "CCOL", "MARK", "LINEUP", "TYPE", +- "VCENTER", "PRIME", "SPLIT", "NOSPLIT", "UACCENT", "SPECIAL", "SPACE", +- "GFONT", "GSIZE", "DEFINE", "NDEFINE", "TDEFINE", "SDEFINE", "UNDEF", +- "IFDEF", "INCLUDE", "DELIM", "CHARTYPE", "SET", "GRFONT", "GBFONT", +- "'^'", "'~'", "'\\t'", "'{'", "'}'", "$accept", "top", "equation", +- "mark", "from_to", "sqrt_over", "script", "nonsup", "simple", "number", +- "pile_element_list", "pile_arg", "column_list", "column_element_list", +- "column_arg", "column", "text", "delim", YY_NULLPTR +-}; +-#endif +- +-# ifdef YYPRINT +-/* YYTOKNUM[NUM] -- (External) token number corresponding to the +- (internal) symbol number NUM (which must be that of a token). */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, +- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, +- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, +- 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, +- 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, +- 315, 94, 126, 9, 123, 125 +-}; +-# endif +- +-#define YYPACT_NINF -76 +- +-#define yypact_value_is_default(Yystate) \ +- (!!((Yystate) == (-76))) +- +-#define YYTABLE_NINF -1 +- +-#define yytable_value_is_error(Yytable_value) \ +- 0 +- +- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-static const yytype_int16 yypact[] = +-{ +- 230, 269, 6, 6, 6, 6, 2, 14, 14, 308, +- 308, 308, 308, -76, -76, 14, 14, 14, 14, -50, +- 230, 230, 14, 308, 4, 23, 14, -76, -76, -76, +- 230, 24, 230, -76, -76, 70, -76, -76, 20, -76, +- -76, -76, 230, -44, -76, -76, -76, -76, -76, -76, +- -76, -76, 230, 308, 308, 57, 57, 57, 57, 308, +- 308, 308, 308, 3, -76, -76, 308, 57, -76, -76, +- 308, 130, -76, -76, 269, 269, 269, 269, 308, 308, +- 308, -76, -76, -76, 308, 230, -12, 230, 191, 57, +- 57, 57, 57, 57, 57, 8, 8, 8, 8, 12, +- -76, 57, 57, -76, -76, -76, -76, 79, -76, 335, +- -76, -76, -76, 230, -76, -6, 2, 230, 28, -76, +- -76, -76, -76, -76, -76, 269, 269, 308, 230, -76, +- -76, 230, -3, 230, -76, -76, -76, 230, -76, -2, +- 230, -76 +-}; +- +- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +- Performed when YYTABLE does not specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = +-{ +- 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 23, 24, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, +- 0, 0, 3, 4, 6, 9, 14, 18, 20, 15, +- 71, 72, 0, 0, 32, 56, 33, 34, 31, 74, +- 75, 73, 0, 0, 0, 43, 44, 45, 46, 0, +- 0, 0, 0, 0, 7, 8, 0, 54, 25, 26, +- 0, 0, 1, 5, 0, 0, 0, 0, 0, 0, +- 0, 38, 39, 40, 0, 57, 0, 0, 37, 48, +- 47, 49, 50, 52, 51, 0, 0, 0, 0, 0, +- 61, 53, 55, 30, 16, 17, 10, 11, 21, 20, +- 19, 41, 42, 0, 59, 0, 0, 0, 0, 67, +- 68, 69, 70, 35, 62, 0, 0, 0, 58, 60, +- 36, 63, 0, 0, 12, 13, 22, 0, 65, 0, +- 64, 66 +-}; +- +- /* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = +-{ +- -76, -76, 0, -17, -75, 1, -67, -13, 46, -7, +- 9, 13, -76, -47, 22, -4, -1, -29 +-}; +- +- /* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int16 yydefgoto[] = +-{ +- -1, 31, 85, 33, 34, 35, 36, 37, 38, 43, +- 86, 44, 99, 132, 119, 100, 45, 52 +-}; +- +- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule whose +- number is the opposite. If YYTABLE_NINF, syntax error. */ +-static const yytype_uint8 yytable[] = +-{ +- 32, 106, 39, 64, 65, 51, 53, 54, 59, 60, +- 61, 62, 110, 113, 63, 73, 46, 47, 48, 113, +- 87, 66, 137, 137, 72, 70, 78, 79, 40, 41, +- 71, 68, 40, 41, 40, 41, 95, 96, 97, 98, +- 40, 41, 80, 81, 82, 95, 96, 97, 98, 69, +- 134, 135, 88, 114, 73, 55, 56, 57, 58, 129, +- 136, 83, 138, 141, 84, 108, 49, 50, 73, 67, +- 42, 73, 117, 74, 75, 104, 105, 123, 107, 80, +- 81, 82, 74, 75, 76, 77, 139, 130, 118, 118, +- 118, 118, 133, 125, 126, 124, 115, 0, 83, 89, +- 90, 84, 0, 0, 0, 91, 92, 93, 94, 0, +- 0, 73, 101, 128, 73, 51, 102, 131, 120, 121, +- 122, 0, 0, 73, 109, 0, 111, 0, 0, 0, +- 112, 0, 0, 131, 0, 1, 0, 140, 2, 3, +- 4, 5, 6, 0, 0, 0, 7, 8, 9, 10, +- 11, 12, 0, 0, 0, 0, 13, 14, 15, 16, +- 17, 18, 19, 0, 0, 0, 0, 20, 21, 22, +- 23, 0, 24, 25, 0, 26, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 27, 28, 29, 30, 103, 1, 0, 0, 2, +- 3, 4, 5, 6, 116, 0, 0, 7, 8, 9, +- 10, 11, 12, 0, 0, 0, 0, 13, 14, 15, +- 16, 17, 18, 19, 0, 0, 0, 0, 20, 21, +- 22, 23, 0, 24, 25, 1, 26, 0, 2, 3, +- 4, 5, 6, 0, 0, 0, 7, 8, 9, 10, +- 11, 12, 27, 28, 29, 30, 13, 14, 15, 16, +- 17, 18, 19, 0, 0, 0, 0, 20, 21, 22, +- 23, 0, 24, 25, 1, 26, 0, 2, 3, 4, +- 5, 6, 0, 0, 0, 7, 8, 9, 10, 11, +- 12, 27, 28, 29, 30, 13, 14, 15, 16, 17, +- 18, 19, 0, 0, 0, 0, 0, 0, 22, 23, +- 0, 24, 25, 0, 26, 0, 2, 3, 4, 5, +- 6, 0, 0, 0, 7, 8, 9, 10, 11, 12, +- 27, 28, 29, 30, 13, 14, 15, 16, 17, 18, +- 19, 78, 127, 0, 0, 0, 0, 22, 23, 0, +- 24, 25, 0, 26, 0, 0, 0, 80, 81, 82, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, +- 28, 29, 30, 0, 0, 0, 83, 0, 0, 84 +-}; +- +-static const yytype_int16 yycheck[] = +-{ +- 0, 76, 1, 20, 21, 6, 7, 8, 15, 16, +- 17, 18, 79, 25, 64, 32, 3, 4, 5, 25, +- 64, 22, 25, 25, 0, 26, 6, 7, 26, 27, +- 30, 27, 26, 27, 26, 27, 33, 34, 35, 36, +- 26, 27, 22, 23, 24, 33, 34, 35, 36, 26, +- 125, 126, 52, 65, 71, 9, 10, 11, 12, 65, +- 127, 41, 65, 65, 44, 78, 64, 65, 85, 23, +- 64, 88, 64, 3, 4, 74, 75, 65, 77, 22, +- 23, 24, 3, 4, 14, 15, 133, 116, 95, 96, +- 97, 98, 64, 14, 15, 99, 87, -1, 41, 53, +- 54, 44, -1, -1, -1, 59, 60, 61, 62, -1, +- -1, 128, 66, 113, 131, 116, 70, 117, 96, 97, +- 98, -1, -1, 140, 78, -1, 80, -1, -1, -1, +- 84, -1, -1, 133, -1, 5, -1, 137, 8, 9, +- 10, 11, 12, -1, -1, -1, 16, 17, 18, 19, +- 20, 21, -1, -1, -1, -1, 26, 27, 28, 29, +- 30, 31, 32, -1, -1, -1, -1, 37, 38, 39, +- 40, -1, 42, 43, -1, 45, -1, -1, -1, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +- -1, 61, 62, 63, 64, 65, 5, -1, -1, 8, +- 9, 10, 11, 12, 13, -1, -1, 16, 17, 18, +- 19, 20, 21, -1, -1, -1, -1, 26, 27, 28, +- 29, 30, 31, 32, -1, -1, -1, -1, 37, 38, +- 39, 40, -1, 42, 43, 5, 45, -1, 8, 9, +- 10, 11, 12, -1, -1, -1, 16, 17, 18, 19, +- 20, 21, 61, 62, 63, 64, 26, 27, 28, 29, +- 30, 31, 32, -1, -1, -1, -1, 37, 38, 39, +- 40, -1, 42, 43, 5, 45, -1, 8, 9, 10, +- 11, 12, -1, -1, -1, 16, 17, 18, 19, 20, +- 21, 61, 62, 63, 64, 26, 27, 28, 29, 30, +- 31, 32, -1, -1, -1, -1, -1, -1, 39, 40, +- -1, 42, 43, -1, 45, -1, 8, 9, 10, 11, +- 12, -1, -1, -1, 16, 17, 18, 19, 20, 21, +- 61, 62, 63, 64, 26, 27, 28, 29, 30, 31, +- 32, 6, 7, -1, -1, -1, -1, 39, 40, -1, +- 42, 43, -1, 45, -1, -1, -1, 22, 23, 24, +- -1, -1, -1, -1, -1, -1, -1, -1, -1, 61, +- 62, 63, 64, -1, -1, -1, 41, -1, -1, 44 +-}; +- +- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = +-{ +- 0, 5, 8, 9, 10, 11, 12, 16, 17, 18, +- 19, 20, 21, 26, 27, 28, 29, 30, 31, 32, +- 37, 38, 39, 40, 42, 43, 45, 61, 62, 63, +- 64, 67, 68, 69, 70, 71, 72, 73, 74, 71, +- 26, 27, 64, 75, 77, 82, 77, 77, 77, 64, +- 65, 82, 83, 82, 82, 74, 74, 74, 74, 75, +- 75, 75, 75, 64, 69, 69, 82, 74, 27, 26, +- 82, 68, 0, 69, 3, 4, 14, 15, 6, 7, +- 22, 23, 24, 41, 44, 68, 76, 64, 68, 74, +- 74, 74, 74, 74, 74, 33, 34, 35, 36, 78, +- 81, 74, 74, 65, 71, 71, 70, 71, 73, 74, +- 72, 74, 74, 25, 65, 76, 13, 64, 75, 80, +- 80, 80, 80, 65, 81, 14, 15, 7, 68, 65, +- 83, 68, 79, 64, 70, 70, 72, 25, 65, 79, +- 68, 65 +-}; +- +- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 66, 67, 67, 68, 68, 69, 69, 69, 70, +- 70, 70, 70, 70, 71, 71, 71, 71, 72, 72, +- 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, +- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, +- 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, +- 74, 74, 74, 74, 74, 74, 75, 76, 76, 77, +- 77, 78, 78, 79, 79, 80, 80, 81, 81, 81, +- 81, 82, 82, 83, 83, 83 +-}; +- +- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = +-{ +- 0, 2, 0, 1, 1, 2, 1, 2, 2, 1, +- 3, 3, 5, 5, 1, 2, 3, 3, 1, 3, +- 1, 3, 5, 1, 1, 2, 2, 1, 1, 1, +- 3, 2, 2, 2, 2, 4, 5, 3, 2, 2, +- 2, 3, 3, 2, 2, 2, 2, 3, 3, 3, +- 3, 3, 3, 3, 2, 3, 1, 1, 3, 3, +- 4, 1, 2, 1, 3, 3, 4, 2, 2, 2, +- 2, 1, 1, 1, 1, 1 +-}; +- +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-#define YYRECOVERING() (!!yyerrstatus) +- +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- YYPOPSTACK (yylen); \ +- yystate = *yyssp; \ +- goto yybackup; \ +- } \ +- else \ +- { \ +- yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (0) +- +-/* Error token number */ +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (0) +- +-/* This macro is provided for backward compatibility. */ +-#ifndef YY_LOCATION_PRINT +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-#endif +- +- +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (0) +- +- +-/*----------------------------------------. +-| Print this symbol's value on YYOUTPUT. | +-`----------------------------------------*/ +- +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-{ +- FILE *yyo = yyoutput; +- YYUSE (yyo); +- if (!yyvaluep) +- return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# endif +- YYUSE (yytype); +-} +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-{ +- YYFPRINTF (yyoutput, "%s %s (", +- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); +- +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); +- YYFPRINTF (yyoutput, ")"); +-} +- +-/*------------------------------------------------------------------. +-| yy_stack_print -- Print the state stack from its BOTTOM up to its | +-| TOP (included). | +-`------------------------------------------------------------------*/ +- +-static void +-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +-{ +- YYFPRINTF (stderr, "Stack now"); +- for (; yybottom <= yytop; yybottom++) +- { +- int yybot = *yybottom; +- YYFPRINTF (stderr, " %d", yybot); +- } +- YYFPRINTF (stderr, "\n"); +-} +- +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (0) +- +- +-/*------------------------------------------------. +-| Report that the YYRULE is going to be reduced. | +-`------------------------------------------------*/ +- +-static void +-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +-{ +- unsigned long int yylno = yyrline[yyrule]; +- int yynrhs = yyr2[yyrule]; +- int yyi; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); +- /* The symbols being reduced. */ +- for (yyi = 0; yyi < yynrhs; yyi++) +- { +- YYFPRINTF (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, +- yystos[yyssp[yyi + 1 - yynrhs]], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); +- YYFPRINTF (stderr, "\n"); +- } +-} +- +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyssp, yyvsp, Rule); \ +-} while (0) +- +-/* Nonzero means print parse trace. It is left uninitialized so that +- multiple parsers can coexist. */ +-int yydebug; +-#else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +-# define YY_STACK_PRINT(Bottom, Top) +-# define YY_REDUCE_PRINT(Rule) +-#endif /* !YYDEBUG */ +- +- +-/* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH +-# define YYINITDEPTH 200 +-#endif +- +-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +- if the built-in stack extension method is used). +- +- Do not make this value too large; the results are undefined if +- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +- evaluated with infinite-precision integer arithmetic. */ +- +-#ifndef YYMAXDEPTH +-# define YYMAXDEPTH 10000 +-#endif +- +- +-#if YYERROR_VERBOSE +- +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else +-/* Return the length of YYSTR. */ +-static YYSIZE_T +-yystrlen (const char *yystr) +-{ +- YYSIZE_T yylen; +- for (yylen = 0; yystr[yylen]; yylen++) +- continue; +- return yylen; +-} +-# endif +-# endif +- +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else +-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +- YYDEST. */ +-static char * +-yystpcpy (char *yydest, const char *yysrc) +-{ +- char *yyd = yydest; +- const char *yys = yysrc; +- +- while ((*yyd++ = *yys++) != '\0') +- continue; +- +- return yyd - 1; +-} +-# endif +-# endif +- +-# ifndef yytnamerr +-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +- quotes and backslashes, so that it's suitable for yyerror. The +- heuristic is that double-quoting is unnecessary unless the string +- contains an apostrophe, a comma, or backslash (other than +- backslash-backslash). YYSTR is taken from yytname. If YYRES is +- null, do not copy; instead, return the length of what the result +- would have been. */ +-static YYSIZE_T +-yytnamerr (char *yyres, const char *yystr) +-{ +- if (*yystr == '"') +- { +- YYSIZE_T yyn = 0; +- char const *yyp = yystr; +- +- for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } +- do_not_strip_quotes: ; +- } +- +- if (! yyres) +- return yystrlen (yystr); +- +- return yystpcpy (yyres, yystr) - yyres; +-} +-# endif +- +-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message +- about the unexpected token YYTOKEN for the state stack whose top is +- YYSSP. +- +- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is +- not large enough to hold the message. In that case, also set +- *YYMSG_ALLOC to the required number of bytes. Return 2 if the +- required number of bytes is too large to store. */ +-static int +-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, +- yytype_int16 *yyssp, int yytoken) +-{ +- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); +- YYSIZE_T yysize = yysize0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- /* Internationalized format string. */ +- const char *yyformat = YY_NULLPTR; +- /* Arguments of yyformat. */ +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- /* Number of reported tokens (one for the "unexpected", one per +- "expected"). */ +- int yycount = 0; +- +- /* There are many possibilities here to consider: +- - If this state is a consistent state with a default action, then +- the only way this function was invoked is if the default action +- is an error action. In that case, don't check for expected +- tokens because there are none. +- - The only way there can be no lookahead present (in yychar) is if +- this state is a consistent state with a default action. Thus, +- detecting the absence of a lookahead is sufficient to determine +- that there is no unexpected or expected token to report. In that +- case, just report a simple "syntax error". +- - Don't assume there isn't a lookahead just because this state is a +- consistent state with a default action. There might have been a +- previous inconsistent state, consistent state with a non-default +- action, or user semantic action that manipulated yychar. +- - Of course, the expected token list depends on states to have +- correct lookahead information, and it depends on the parser not +- to perform extra reductions after fetching a lookahead from the +- scanner and before detecting a syntax error. Thus, state merging +- (from LALR or IELR) and default reductions corrupt the expected +- token list. However, the list is correct for canonical LR with +- one exception: it will still contain any token that will not be +- accepted due to an error action in a later state. +- */ +- if (yytoken != YYEMPTY) +- { +- int yyn = yypact[*yyssp]; +- yyarg[yycount++] = yytname[yytoken]; +- if (!yypact_value_is_default (yyn)) +- { +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. In other words, skip the first -YYN actions for +- this state because they are default actions. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yyx; +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR +- && !yytable_value_is_error (yytable[yyx + yyn])) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- { +- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); +- if (! (yysize <= yysize1 +- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } +- } +- } +- } +- +- switch (yycount) +- { +-# define YYCASE_(N, S) \ +- case N: \ +- yyformat = S; \ +- break +- YYCASE_(0, YY_("syntax error")); +- YYCASE_(1, YY_("syntax error, unexpected %s")); +- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); +- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); +- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); +- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +-# undef YYCASE_ +- } +- +- { +- YYSIZE_T yysize1 = yysize + yystrlen (yyformat); +- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } +- +- if (*yymsg_alloc < yysize) +- { +- *yymsg_alloc = 2 * yysize; +- if (! (yysize <= *yymsg_alloc +- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) +- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; +- return 1; +- } +- +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- { +- char *yyp = *yymsg; +- int yyi = 0; +- while ((*yyp = *yyformat) != '\0') +- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyformat += 2; +- } +- else +- { +- yyp++; +- yyformat++; +- } +- } +- return 0; +-} +-#endif /* YYERROR_VERBOSE */ +- +-/*-----------------------------------------------. +-| Release the memory associated to this symbol. | +-`-----------------------------------------------*/ +- +-static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-{ +- YYUSE (yyvaluep); +- if (!yymsg) +- yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +- +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- YYUSE (yytype); +- YY_IGNORE_MAYBE_UNINITIALIZED_END +-} +- +- +- +- +-/* The lookahead symbol. */ +-int yychar; +- +-/* The semantic value of the lookahead symbol. */ +-YYSTYPE yylval; +-/* Number of syntax errors so far. */ +-int yynerrs; +- +- +-/*----------. +-| yyparse. | +-`----------*/ +- +-int +-yyparse (void) +-{ +- int yystate; +- /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- +- /* The stacks and their tools: +- 'yyss': related to states. +- 'yyvs': related to semantic values. +- +- Refer to the stacks through separate pointers, to allow yyoverflow +- to reallocate them elsewhere. */ +- +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss; +- yytype_int16 *yyssp; +- +- /* The semantic value stack. */ +- YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs; +- YYSTYPE *yyvsp; +- +- YYSIZE_T yystacksize; +- +- int yyn; +- int yyresult; +- /* Lookahead token as an internal (translated) token number. */ +- int yytoken = 0; +- /* The variables used to return semantic value and location from the +- action routines. */ +- YYSTYPE yyval; +- +-#if YYERROR_VERBOSE +- /* Buffer for error messages, and its allocated size. */ +- char yymsgbuf[128]; +- char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif +- +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) +- +- /* The number of symbols on the RHS of the reduced rule. +- Keep to zero when no symbol should be popped. */ +- int yylen = 0; +- +- yyssp = yyss = yyssa; +- yyvsp = yyvs = yyvsa; +- yystacksize = YYINITDEPTH; +- +- YYDPRINTF ((stderr, "Starting parse\n")); +- +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; +- yychar = YYEMPTY; /* Cause a token to be read. */ +- goto yysetstate; +- +-/*------------------------------------------------------------. +-| yynewstate -- Push a new state, which is found in yystate. | +-`------------------------------------------------------------*/ +- yynewstate: +- /* In all cases, when you get here, the value and location stacks +- have just been pushed. So pushing a state here evens the stacks. */ +- yyssp++; +- +- yysetstate: +- *yyssp = yystate; +- +- if (yyss + yystacksize - 1 <= yyssp) +- { +- /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = yyssp - yyss + 1; +- +-#ifdef yyoverflow +- { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; +- } +-#else /* no yyoverflow */ +-# ifndef YYSTACK_RELOCATE +- goto yyexhaustedlab; +-# else +- /* Extend the stack our own way. */ +- if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; +- yystacksize *= 2; +- if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; +- +- { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss_alloc, yyss); +- YYSTACK_RELOCATE (yyvs_alloc, yyvs); +-# undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); +- } +-# endif +-#endif /* no yyoverflow */ +- +- yyssp = yyss + yysize - 1; +- yyvsp = yyvs + yysize - 1; +- +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); +- +- if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; +- } +- +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +- +- if (yystate == YYFINAL) +- YYACCEPT; +- +- goto yybackup; +- +-/*-----------. +-| yybackup. | +-`-----------*/ +-yybackup: +- +- /* Do appropriate processing given the current state. Read a +- lookahead token if we need one and don't already have one. */ +- +- /* First try to decide what to do without reference to lookahead token. */ +- yyn = yypact[yystate]; +- if (yypact_value_is_default (yyn)) +- goto yydefault; +- +- /* Not known => get a lookahead token if don't already have one. */ +- +- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ +- if (yychar == YYEMPTY) +- { +- YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = yylex (); +- } +- +- if (yychar <= YYEOF) +- { +- yychar = yytoken = YYEOF; +- YYDPRINTF ((stderr, "Now at end of input.\n")); +- } +- else +- { +- yytoken = YYTRANSLATE (yychar); +- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +- } +- +- /* If the proper action on seeing token YYTOKEN is to reduce or to +- detect an error, take that action. */ +- yyn += yytoken; +- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +- goto yydefault; +- yyn = yytable[yyn]; +- if (yyn <= 0) +- { +- if (yytable_value_is_error (yyn)) +- goto yyerrlab; +- yyn = -yyn; +- goto yyreduce; +- } +- +- /* Count tokens shifted since error; after three, turn off error +- status. */ +- if (yyerrstatus) +- yyerrstatus--; +- +- /* Shift the lookahead token. */ +- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token. */ +- yychar = YYEMPTY; +- +- yystate = yyn; +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END +- +- goto yynewstate; +- +- +-/*-----------------------------------------------------------. +-| yydefault -- do the default action for the current state. | +-`-----------------------------------------------------------*/ +-yydefault: +- yyn = yydefact[yystate]; +- if (yyn == 0) +- goto yyerrlab; +- goto yyreduce; +- +- +-/*-----------------------------. +-| yyreduce -- Do a reduction. | +-`-----------------------------*/ +-yyreduce: +- /* yyn is the number of a rule to reduce with. */ +- yylen = yyr2[yyn]; +- +- /* If YYLEN is nonzero, implement the default value of the action: +- '$$ = $1'. +- +- Otherwise, the following line sets YYVAL to garbage. +- This behavior is undocumented and Bison +- users should not rely upon it. Assigning to YYVAL +- unconditionally makes the parser a bit smaller, and it avoids a +- GCC warning that YYVAL may be used uninitialized. */ +- yyval = yyvsp[1-yylen]; +- +- +- YY_REDUCE_PRINT (yyn); +- switch (yyn) +- { +- case 3: +-#line 124 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].b)->top_level(); non_empty_flag = 1; } +-#line 1488 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 4: +-#line 129 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = (yyvsp[0].b); } +-#line 1494 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 5: +-#line 131 "eqn.y" /* yacc.c:1646 */ +- { +- list_box *lb = (yyvsp[-1].b)->to_list_box(); +- if (!lb) +- lb = new list_box((yyvsp[-1].b)); +- lb->append((yyvsp[0].b)); +- (yyval.b) = lb; +- } +-#line 1506 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 6: +-#line 142 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = (yyvsp[0].b); } +-#line 1512 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 7: +-#line 144 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_mark_box((yyvsp[0].b)); } +-#line 1518 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 8: +-#line 146 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_lineup_box((yyvsp[0].b)); } +-#line 1524 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 9: +-#line 151 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = (yyvsp[0].b); } +-#line 1530 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 10: +-#line 153 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_limit_box((yyvsp[-2].b), 0, (yyvsp[0].b)); } +-#line 1536 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 11: +-#line 155 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_limit_box((yyvsp[-2].b), (yyvsp[0].b), 0); } +-#line 1542 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 12: +-#line 157 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_limit_box((yyvsp[-4].b), (yyvsp[-2].b), (yyvsp[0].b)); } +-#line 1548 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 13: +-#line 159 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_limit_box((yyvsp[-4].b), make_limit_box((yyvsp[-2].b), (yyvsp[0].b), 0), 0); } +-#line 1554 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 14: +-#line 164 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = (yyvsp[0].b); } +-#line 1560 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 15: +-#line 166 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_sqrt_box((yyvsp[0].b)); } +-#line 1566 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 16: +-#line 168 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_over_box((yyvsp[-2].b), (yyvsp[0].b)); } +-#line 1572 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 17: +-#line 170 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_small_over_box((yyvsp[-2].b), (yyvsp[0].b)); } +-#line 1578 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 18: +-#line 175 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = (yyvsp[0].b); } +-#line 1584 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 19: +-#line 177 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_script_box((yyvsp[-2].b), 0, (yyvsp[0].b)); } +-#line 1590 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 20: +-#line 182 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = (yyvsp[0].b); } +-#line 1596 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 21: +-#line 184 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_script_box((yyvsp[-2].b), (yyvsp[0].b), 0); } +-#line 1602 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 22: +-#line 186 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_script_box((yyvsp[-4].b), (yyvsp[-2].b), (yyvsp[0].b)); } +-#line 1608 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 23: +-#line 191 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = split_text((yyvsp[0].str)); } +-#line 1614 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 24: +-#line 193 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new quoted_text_box((yyvsp[0].str)); } +-#line 1620 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 25: +-#line 195 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = split_text((yyvsp[0].str)); } +-#line 1626 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 26: +-#line 197 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new quoted_text_box((yyvsp[0].str)); } +-#line 1632 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 27: +-#line 199 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new half_space_box; } +-#line 1638 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 28: +-#line 201 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new space_box; } +-#line 1644 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 29: +-#line 203 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new tab_box; } +-#line 1650 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 30: +-#line 205 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = (yyvsp[-1].b); } +-#line 1656 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 31: +-#line 207 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].pb)->set_alignment(CENTER_ALIGN); (yyval.b) = (yyvsp[0].pb); } +-#line 1662 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 32: +-#line 209 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].pb)->set_alignment(LEFT_ALIGN); (yyval.b) = (yyvsp[0].pb); } +-#line 1668 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 33: +-#line 211 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].pb)->set_alignment(RIGHT_ALIGN); (yyval.b) = (yyvsp[0].pb); } +-#line 1674 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 34: +-#line 213 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].pb)->set_alignment(CENTER_ALIGN); (yyval.b) = (yyvsp[0].pb); } +-#line 1680 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 35: +-#line 215 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = (yyvsp[-1].mb); } +-#line 1686 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 36: +-#line 217 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_delim_box((yyvsp[-3].str), (yyvsp[-2].b), (yyvsp[0].str)); } +-#line 1692 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 37: +-#line 219 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_delim_box((yyvsp[-1].str), (yyvsp[0].b), 0); } +-#line 1698 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 38: +-#line 221 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_overline_box((yyvsp[-1].b)); } +-#line 1704 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 39: +-#line 223 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_underline_box((yyvsp[-1].b)); } +-#line 1710 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 40: +-#line 225 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_prime_box((yyvsp[-1].b)); } +-#line 1716 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 41: +-#line 227 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_accent_box((yyvsp[-2].b), (yyvsp[0].b)); } +-#line 1722 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 42: +-#line 229 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_uaccent_box((yyvsp[-2].b), (yyvsp[0].b)); } +-#line 1728 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 43: +-#line 231 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new font_box(strsave(get_grfont()), (yyvsp[0].b)); } +-#line 1734 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 44: +-#line 233 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new font_box(strsave(get_gbfont()), (yyvsp[0].b)); } +-#line 1740 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 45: +-#line 235 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new font_box(strsave(get_gfont()), (yyvsp[0].b)); } +-#line 1746 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 46: +-#line 237 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new fat_box((yyvsp[0].b)); } +-#line 1752 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 47: +-#line 239 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new font_box((yyvsp[-1].str), (yyvsp[0].b)); } +-#line 1758 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 48: +-#line 241 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new size_box((yyvsp[-1].str), (yyvsp[0].b)); } +-#line 1764 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 49: +-#line 243 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new hmotion_box((yyvsp[-1].n), (yyvsp[0].b)); } +-#line 1770 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 50: +-#line 245 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new hmotion_box(-(yyvsp[-1].n), (yyvsp[0].b)); } +-#line 1776 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 51: +-#line 247 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new vmotion_box((yyvsp[-1].n), (yyvsp[0].b)); } +-#line 1782 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 52: +-#line 249 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new vmotion_box(-(yyvsp[-1].n), (yyvsp[0].b)); } +-#line 1788 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 53: +-#line 251 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].b)->set_spacing_type((yyvsp[-1].str)); (yyval.b) = (yyvsp[0].b); } +-#line 1794 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 54: +-#line 253 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = new vcenter_box((yyvsp[0].b)); } +-#line 1800 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 55: +-#line 255 "eqn.y" /* yacc.c:1646 */ +- { (yyval.b) = make_special_box((yyvsp[-1].str), (yyvsp[0].b)); } +-#line 1806 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 56: +-#line 260 "eqn.y" /* yacc.c:1646 */ +- { +- int n; +- if (sscanf((yyvsp[0].str), "%d", &n) == 1) +- (yyval.n) = n; +- a_delete (yyvsp[0].str); +- } +-#line 1817 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 57: +-#line 270 "eqn.y" /* yacc.c:1646 */ +- { (yyval.pb) = new pile_box((yyvsp[0].b)); } +-#line 1823 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 58: +-#line 272 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[-2].pb)->append((yyvsp[0].b)); (yyval.pb) = (yyvsp[-2].pb); } +-#line 1829 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 59: +-#line 277 "eqn.y" /* yacc.c:1646 */ +- { (yyval.pb) = (yyvsp[-1].pb); } +-#line 1835 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 60: +-#line 279 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[-1].pb)->set_space((yyvsp[-3].n)); (yyval.pb) = (yyvsp[-1].pb); } +-#line 1841 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 61: +-#line 284 "eqn.y" /* yacc.c:1646 */ +- { (yyval.mb) = new matrix_box((yyvsp[0].col)); } +-#line 1847 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 62: +-#line 286 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[-1].mb)->append((yyvsp[0].col)); (yyval.mb) = (yyvsp[-1].mb); } +-#line 1853 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 63: +-#line 291 "eqn.y" /* yacc.c:1646 */ +- { (yyval.col) = new column((yyvsp[0].b)); } +-#line 1859 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 64: +-#line 293 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[-2].col)->append((yyvsp[0].b)); (yyval.col) = (yyvsp[-2].col); } +-#line 1865 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 65: +-#line 298 "eqn.y" /* yacc.c:1646 */ +- { (yyval.col) = (yyvsp[-1].col); } +-#line 1871 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 66: +-#line 300 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[-1].col)->set_space((yyvsp[-3].n)); (yyval.col) = (yyvsp[-1].col); } +-#line 1877 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 67: +-#line 305 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].col)->set_alignment(CENTER_ALIGN); (yyval.col) = (yyvsp[0].col); } +-#line 1883 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 68: +-#line 307 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].col)->set_alignment(LEFT_ALIGN); (yyval.col) = (yyvsp[0].col); } +-#line 1889 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 69: +-#line 309 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].col)->set_alignment(RIGHT_ALIGN); (yyval.col) = (yyvsp[0].col); } +-#line 1895 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 70: +-#line 311 "eqn.y" /* yacc.c:1646 */ +- { (yyvsp[0].col)->set_alignment(CENTER_ALIGN); (yyval.col) = (yyvsp[0].col); } +-#line 1901 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 71: +-#line 315 "eqn.y" /* yacc.c:1646 */ +- { (yyval.str) = (yyvsp[0].str); } +-#line 1907 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 72: +-#line 317 "eqn.y" /* yacc.c:1646 */ +- { (yyval.str) = (yyvsp[0].str); } +-#line 1913 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 73: +-#line 322 "eqn.y" /* yacc.c:1646 */ +- { (yyval.str) = (yyvsp[0].str); } +-#line 1919 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 74: +-#line 324 "eqn.y" /* yacc.c:1646 */ +- { (yyval.str) = strsave("{"); } +-#line 1925 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- case 75: +-#line 326 "eqn.y" /* yacc.c:1646 */ +- { (yyval.str) = strsave("}"); } +-#line 1931 "eqn.cpp" /* yacc.c:1646 */ +- break; +- +- +-#line 1935 "eqn.cpp" /* yacc.c:1646 */ +- default: break; +- } +- /* User semantic actions sometimes alter yychar, and that requires +- that yytoken be updated with the new translation. We take the +- approach of translating immediately before every use of yytoken. +- One alternative is translating here after every semantic action, +- but that translation would be missed if the semantic action invokes +- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or +- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an +- incorrect destructor might then be invoked immediately. In the +- case of YYERROR or YYBACKUP, subsequent parser actions might lead +- to an incorrect destructor call or verbose syntax error message +- before the lookahead is translated. */ +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); +- +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- +- *++yyvsp = yyval; +- +- /* Now 'shift' the result of the reduction. Determine what state +- that goes to, based on the state we popped back to and the rule +- number reduced by. */ +- +- yyn = yyr1[yyn]; +- +- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +- yystate = yytable[yystate]; +- else +- yystate = yydefgoto[yyn - YYNTOKENS]; +- +- goto yynewstate; +- +- +-/*--------------------------------------. +-| yyerrlab -- here on detecting error. | +-`--------------------------------------*/ +-yyerrlab: +- /* Make sure we have latest lookahead translation. See comments at +- user semantic actions for why this is necessary. */ +- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); +- +- /* If not already recovering from an error, report this error. */ +- if (!yyerrstatus) +- { +- ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (YY_("syntax error")); +-#else +-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ +- yyssp, yytoken) +- { +- char const *yymsgp = YY_("syntax error"); +- int yysyntax_error_status; +- yysyntax_error_status = YYSYNTAX_ERROR; +- if (yysyntax_error_status == 0) +- yymsgp = yymsg; +- else if (yysyntax_error_status == 1) +- { +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); +- if (!yymsg) +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- yysyntax_error_status = 2; +- } +- else +- { +- yysyntax_error_status = YYSYNTAX_ERROR; +- yymsgp = yymsg; +- } +- } +- yyerror (yymsgp); +- if (yysyntax_error_status == 2) +- goto yyexhaustedlab; +- } +-# undef YYSYNTAX_ERROR +-#endif +- } +- +- +- +- if (yyerrstatus == 3) +- { +- /* If just tried and failed to reuse lookahead token after an +- error, discard it. */ +- +- if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } +- else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } +- } +- +- /* Else will try to reuse lookahead token after shifting the error +- token. */ +- goto yyerrlab1; +- +- +-/*---------------------------------------------------. +-| yyerrorlab -- error raised explicitly by YYERROR. | +-`---------------------------------------------------*/ +-yyerrorlab: +- +- /* Pacify compilers like GCC when the user code never invokes +- YYERROR and the label yyerrorlab therefore never appears in user +- code. */ +- if (/*CONSTCOND*/ 0) +- goto yyerrorlab; +- +- /* Do not reclaim the symbols of the rule whose action triggered +- this YYERROR. */ +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- yystate = *yyssp; +- goto yyerrlab1; +- +- +-/*-------------------------------------------------------------. +-| yyerrlab1 -- common code for both syntax error and YYERROR. | +-`-------------------------------------------------------------*/ +-yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ +- +- for (;;) +- { +- yyn = yypact[yystate]; +- if (!yypact_value_is_default (yyn)) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } +- +- /* Pop the current state because it cannot handle the error token. */ +- if (yyssp == yyss) +- YYABORT; +- +- +- yydestruct ("Error: popping", +- yystos[yystate], yyvsp); +- YYPOPSTACK (1); +- yystate = *yyssp; +- YY_STACK_PRINT (yyss, yyssp); +- } +- +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END +- +- +- /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +- +- yystate = yyn; +- goto yynewstate; +- +- +-/*-------------------------------------. +-| yyacceptlab -- YYACCEPT comes here. | +-`-------------------------------------*/ +-yyacceptlab: +- yyresult = 0; +- goto yyreturn; +- +-/*-----------------------------------. +-| yyabortlab -- YYABORT comes here. | +-`-----------------------------------*/ +-yyabortlab: +- yyresult = 1; +- goto yyreturn; +- +-#if !defined yyoverflow || YYERROR_VERBOSE +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ +-yyexhaustedlab: +- yyerror (YY_("memory exhausted")); +- yyresult = 2; +- /* Fall through. */ +-#endif +- +-yyreturn: +- if (yychar != YYEMPTY) +- { +- /* Make sure we have latest lookahead translation. See comments at +- user semantic actions for why this is necessary. */ +- yytoken = YYTRANSLATE (yychar); +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); +- } +- /* Do not reclaim the symbols of the rule whose action triggered +- this YYABORT or YYACCEPT. */ +- YYPOPSTACK (yylen); +- YY_STACK_PRINT (yyss, yyssp); +- while (yyssp != yyss) +- { +- yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); +- YYPOPSTACK (1); +- } +-#ifndef yyoverflow +- if (yyss != yyssa) +- YYSTACK_FREE (yyss); +-#endif +-#if YYERROR_VERBOSE +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +-#endif +- return yyresult; +-} +-#line 329 "eqn.y" /* yacc.c:1906 */ +- +diff -Nuar groff-1.22.3.old/src/preproc/eqn/eqn.man groff-1.22.3/src/preproc/eqn/eqn.man +--- groff-1.22.3.old/src/preproc/eqn/eqn.man 2014-11-04 10:38:35.232523909 +0200 ++++ groff-1.22.3/src/preproc/eqn/eqn.man 2015-04-23 20:57:03.000000000 +0300 +@@ -3,6 +3,10 @@ + @g@eqn \- format equations for troff or MathML + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" license (copying) + .de co + Copyright \[co] 1989-2014 Free Software Foundation, Inc. +@@ -341,7 +345,7 @@ + . + .TP + punctuation +-a punctuation character such as \[oq],\[cl]; ++a punctuation character such as \[oq],\[cq]; + . + .TP + inner +@@ -468,7 +472,7 @@ + about the math axis. + . + The math axis is the vertical position about which characters such as +-\[oq]\[pl]\[]cq and \[oq]\[mi]\[cq] are centered; also it is the ++\[oq]\[pl]\[cq] and \[oq]\[mi]\[cq] are centered; also it is the + vertical position used for the bar of fractions. + . + For example, +@@ -1401,6 +1405,9 @@ + .co + . + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" mode: nroff + .\" End: +diff -Nuar groff-1.22.3.old/src/preproc/eqn/eqn_tab.h groff-1.22.3/src/preproc/eqn/eqn_tab.h +--- groff-1.22.3.old/src/preproc/eqn/eqn_tab.h 2014-11-04 10:38:38.300485555 +0200 ++++ groff-1.22.3/src/preproc/eqn/eqn_tab.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,193 +0,0 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ +- +-/* Bison interface for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation, either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-#ifndef YY_YY_Y_TAB_H_INCLUDED +-# define YY_YY_Y_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; +-#endif +- +-/* Token type. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- enum yytokentype +- { +- OVER = 258, +- SMALLOVER = 259, +- SQRT = 260, +- SUB = 261, +- SUP = 262, +- LPILE = 263, +- RPILE = 264, +- CPILE = 265, +- PILE = 266, +- LEFT = 267, +- RIGHT = 268, +- TO = 269, +- FROM = 270, +- SIZE = 271, +- FONT = 272, +- ROMAN = 273, +- BOLD = 274, +- ITALIC = 275, +- FAT = 276, +- ACCENT = 277, +- BAR = 278, +- UNDER = 279, +- ABOVE = 280, +- TEXT = 281, +- QUOTED_TEXT = 282, +- FWD = 283, +- BACK = 284, +- DOWN = 285, +- UP = 286, +- MATRIX = 287, +- COL = 288, +- LCOL = 289, +- RCOL = 290, +- CCOL = 291, +- MARK = 292, +- LINEUP = 293, +- TYPE = 294, +- VCENTER = 295, +- PRIME = 296, +- SPLIT = 297, +- NOSPLIT = 298, +- UACCENT = 299, +- SPECIAL = 300, +- SPACE = 301, +- GFONT = 302, +- GSIZE = 303, +- DEFINE = 304, +- NDEFINE = 305, +- TDEFINE = 306, +- SDEFINE = 307, +- UNDEF = 308, +- IFDEF = 309, +- INCLUDE = 310, +- DELIM = 311, +- CHARTYPE = 312, +- SET = 313, +- GRFONT = 314, +- GBFONT = 315 +- }; +-#endif +-/* Tokens. */ +-#define OVER 258 +-#define SMALLOVER 259 +-#define SQRT 260 +-#define SUB 261 +-#define SUP 262 +-#define LPILE 263 +-#define RPILE 264 +-#define CPILE 265 +-#define PILE 266 +-#define LEFT 267 +-#define RIGHT 268 +-#define TO 269 +-#define FROM 270 +-#define SIZE 271 +-#define FONT 272 +-#define ROMAN 273 +-#define BOLD 274 +-#define ITALIC 275 +-#define FAT 276 +-#define ACCENT 277 +-#define BAR 278 +-#define UNDER 279 +-#define ABOVE 280 +-#define TEXT 281 +-#define QUOTED_TEXT 282 +-#define FWD 283 +-#define BACK 284 +-#define DOWN 285 +-#define UP 286 +-#define MATRIX 287 +-#define COL 288 +-#define LCOL 289 +-#define RCOL 290 +-#define CCOL 291 +-#define MARK 292 +-#define LINEUP 293 +-#define TYPE 294 +-#define VCENTER 295 +-#define PRIME 296 +-#define SPLIT 297 +-#define NOSPLIT 298 +-#define UACCENT 299 +-#define SPECIAL 300 +-#define SPACE 301 +-#define GFONT 302 +-#define GSIZE 303 +-#define DEFINE 304 +-#define NDEFINE 305 +-#define TDEFINE 306 +-#define SDEFINE 307 +-#define UNDEF 308 +-#define IFDEF 309 +-#define INCLUDE 310 +-#define DELIM 311 +-#define CHARTYPE 312 +-#define SET 313 +-#define GRFONT 314 +-#define GBFONT 315 +- +-/* Value type. */ +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE +-{ +-#line 30 "eqn.y" /* yacc.c:1909 */ +- +- char *str; +- box *b; +- pile_box *pb; +- matrix_box *mb; +- int n; +- column *col; +- +-#line 183 "y.tab.h" /* yacc.c:1909 */ +-}; +-# define YYSTYPE_IS_TRIVIAL 1 +-# define YYSTYPE_IS_DECLARED 1 +-#endif +- +- +-extern YYSTYPE yylval; +- +-int yyparse (void); +- +-#endif /* !YY_YY_Y_TAB_H_INCLUDED */ +diff -Nuar groff-1.22.3.old/src/preproc/eqn/eqn.y groff-1.22.3/src/preproc/eqn/eqn.y +--- groff-1.22.3.old/src/preproc/eqn/eqn.y 2014-11-04 10:38:35.232523909 +0200 ++++ groff-1.22.3/src/preproc/eqn/eqn.y 1970-01-01 02:00:00.000000000 +0200 +@@ -1,329 +0,0 @@ +-/* Copyright (C) 1989-2014 Free Software Foundation, Inc. +- Written by James Clark (jjc@jclark.com) +- +-This file is part of groff. +- +-groff is free software; you can redistribute it and/or modify it under +-the terms of the GNU General Public License as published by the Free +-Software Foundation, either version 3 of the License, or +-(at your option) any later version. +- +-groff is distributed in the hope that it will be useful, but WITHOUT ANY +-WARRANTY; without even the implied warranty of MERCHANTABILITY or +-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-for more details. +- +-You should have received a copy of the GNU General Public License +-along with this program. If not, see . */ +-%{ +-#include +-#include +-#include +- +-#include "lib.h" +-#include "box.h" +-extern int non_empty_flag; +-int yylex(); +-void yyerror(const char *); +-%} +- +-%union { +- char *str; +- box *b; +- pile_box *pb; +- matrix_box *mb; +- int n; +- column *col; +-} +- +-%token OVER +-%token SMALLOVER +-%token SQRT +-%token SUB +-%token SUP +-%token LPILE +-%token RPILE +-%token CPILE +-%token PILE +-%token LEFT +-%token RIGHT +-%token TO +-%token FROM +-%token SIZE +-%token FONT +-%token ROMAN +-%token BOLD +-%token ITALIC +-%token FAT +-%token ACCENT +-%token BAR +-%token UNDER +-%token ABOVE +-%token TEXT +-%token QUOTED_TEXT +-%token FWD +-%token BACK +-%token DOWN +-%token UP +-%token MATRIX +-%token COL +-%token LCOL +-%token RCOL +-%token CCOL +-%token MARK +-%token LINEUP +-%token TYPE +-%token VCENTER +-%token PRIME +-%token SPLIT +-%token NOSPLIT +-%token UACCENT +-%token SPECIAL +- +-/* these are handled in the lexer */ +-%token SPACE +-%token GFONT +-%token GSIZE +-%token DEFINE +-%token NDEFINE +-%token TDEFINE +-%token SDEFINE +-%token UNDEF +-%token IFDEF +-%token INCLUDE +-%token DELIM +-%token CHARTYPE +-%token SET +-%token GRFONT +-%token GBFONT +- +-/* The original eqn manual says that `left' is right associative. It's lying. +-Consider `left ( ~ left ( ~ right ) right )'. */ +- +-%right LEFT +-%left RIGHT +-%right LPILE RPILE CPILE PILE TEXT QUOTED_TEXT MATRIX MARK LINEUP '^' '~' '\t' '{' SPLIT NOSPLIT +-%right FROM TO +-%left SQRT OVER SMALLOVER +-%right SUB SUP +-%right ROMAN BOLD ITALIC FAT FONT SIZE FWD BACK DOWN UP TYPE VCENTER SPECIAL +-%right BAR UNDER PRIME +-%left ACCENT UACCENT +- +-%type mark from_to sqrt_over script simple equation nonsup +-%type number +-%type text delim +-%type pile_element_list pile_arg +-%type column_list +-%type
    column column_arg column_element_list +- +-%% +-top: +- /* empty */ +- | equation +- { $1->top_level(); non_empty_flag = 1; } +- ; +- +-equation: +- mark +- { $$ = $1; } +- | equation mark +- { +- list_box *lb = $1->to_list_box(); +- if (!lb) +- lb = new list_box($1); +- lb->append($2); +- $$ = lb; +- } +- ; +- +-mark: +- from_to +- { $$ = $1; } +- | MARK mark +- { $$ = make_mark_box($2); } +- | LINEUP mark +- { $$ = make_lineup_box($2); } +- ; +- +-from_to: +- sqrt_over %prec FROM +- { $$ = $1; } +- | sqrt_over TO from_to +- { $$ = make_limit_box($1, 0, $3); } +- | sqrt_over FROM sqrt_over +- { $$ = make_limit_box($1, $3, 0); } +- | sqrt_over FROM sqrt_over TO from_to +- { $$ = make_limit_box($1, $3, $5); } +- | sqrt_over FROM sqrt_over FROM from_to +- { $$ = make_limit_box($1, make_limit_box($3, $5, 0), 0); } +- ; +- +-sqrt_over: +- script +- { $$ = $1; } +- | SQRT sqrt_over +- { $$ = make_sqrt_box($2); } +- | sqrt_over OVER sqrt_over +- { $$ = make_over_box($1, $3); } +- | sqrt_over SMALLOVER sqrt_over +- { $$ = make_small_over_box($1, $3); } +- ; +- +-script: +- nonsup +- { $$ = $1; } +- | simple SUP script +- { $$ = make_script_box($1, 0, $3); } +- ; +- +-nonsup: +- simple %prec SUP +- { $$ = $1; } +- | simple SUB nonsup +- { $$ = make_script_box($1, $3, 0); } +- | simple SUB simple SUP script +- { $$ = make_script_box($1, $3, $5); } +- ; +- +-simple: +- TEXT +- { $$ = split_text($1); } +- | QUOTED_TEXT +- { $$ = new quoted_text_box($1); } +- | SPLIT QUOTED_TEXT +- { $$ = split_text($2); } +- | NOSPLIT TEXT +- { $$ = new quoted_text_box($2); } +- | '^' +- { $$ = new half_space_box; } +- | '~' +- { $$ = new space_box; } +- | '\t' +- { $$ = new tab_box; } +- | '{' equation '}' +- { $$ = $2; } +- | PILE pile_arg +- { $2->set_alignment(CENTER_ALIGN); $$ = $2; } +- | LPILE pile_arg +- { $2->set_alignment(LEFT_ALIGN); $$ = $2; } +- | RPILE pile_arg +- { $2->set_alignment(RIGHT_ALIGN); $$ = $2; } +- | CPILE pile_arg +- { $2->set_alignment(CENTER_ALIGN); $$ = $2; } +- | MATRIX '{' column_list '}' +- { $$ = $3; } +- | LEFT delim equation RIGHT delim +- { $$ = make_delim_box($2, $3, $5); } +- | LEFT delim equation +- { $$ = make_delim_box($2, $3, 0); } +- | simple BAR +- { $$ = make_overline_box($1); } +- | simple UNDER +- { $$ = make_underline_box($1); } +- | simple PRIME +- { $$ = make_prime_box($1); } +- | simple ACCENT simple +- { $$ = make_accent_box($1, $3); } +- | simple UACCENT simple +- { $$ = make_uaccent_box($1, $3); } +- | ROMAN simple +- { $$ = new font_box(strsave(get_grfont()), $2); } +- | BOLD simple +- { $$ = new font_box(strsave(get_gbfont()), $2); } +- | ITALIC simple +- { $$ = new font_box(strsave(get_gfont()), $2); } +- | FAT simple +- { $$ = new fat_box($2); } +- | FONT text simple +- { $$ = new font_box($2, $3); } +- | SIZE text simple +- { $$ = new size_box($2, $3); } +- | FWD number simple +- { $$ = new hmotion_box($2, $3); } +- | BACK number simple +- { $$ = new hmotion_box(-$2, $3); } +- | UP number simple +- { $$ = new vmotion_box($2, $3); } +- | DOWN number simple +- { $$ = new vmotion_box(-$2, $3); } +- | TYPE text simple +- { $3->set_spacing_type($2); $$ = $3; } +- | VCENTER simple +- { $$ = new vcenter_box($2); } +- | SPECIAL text simple +- { $$ = make_special_box($2, $3); } +- ; +- +-number: +- text +- { +- int n; +- if (sscanf($1, "%d", &n) == 1) +- $$ = n; +- a_delete $1; +- } +- ; +- +-pile_element_list: +- equation +- { $$ = new pile_box($1); } +- | pile_element_list ABOVE equation +- { $1->append($3); $$ = $1; } +- ; +- +-pile_arg: +- '{' pile_element_list '}' +- { $$ = $2; } +- | number '{' pile_element_list '}' +- { $3->set_space($1); $$ = $3; } +- ; +- +-column_list: +- column +- { $$ = new matrix_box($1); } +- | column_list column +- { $1->append($2); $$ = $1; } +- ; +- +-column_element_list: +- equation +- { $$ = new column($1); } +- | column_element_list ABOVE equation +- { $1->append($3); $$ = $1; } +- ; +- +-column_arg: +- '{' column_element_list '}' +- { $$ = $2; } +- | number '{' column_element_list '}' +- { $3->set_space($1); $$ = $3; } +- ; +- +-column: +- COL column_arg +- { $2->set_alignment(CENTER_ALIGN); $$ = $2; } +- | LCOL column_arg +- { $2->set_alignment(LEFT_ALIGN); $$ = $2; } +- | RCOL column_arg +- { $2->set_alignment(RIGHT_ALIGN); $$ = $2; } +- | CCOL column_arg +- { $2->set_alignment(CENTER_ALIGN); $$ = $2; } +- ; +- +-text: TEXT +- { $$ = $1; } +- | QUOTED_TEXT +- { $$ = $1; } +- ; +- +-delim: +- text +- { $$ = $1; } +- | '{' +- { $$ = strsave("{"); } +- | '}' +- { $$ = strsave("}"); } +- ; +- +-%% +diff -Nuar groff-1.22.3.old/src/preproc/eqn/eqn.ypp groff-1.22.3/src/preproc/eqn/eqn.ypp +--- groff-1.22.3.old/src/preproc/eqn/eqn.ypp 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/eqn/eqn.ypp 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,329 @@ ++/* Copyright (C) 1989-2014 Free Software Foundation, Inc. ++ Written by James Clark (jjc@jclark.com) ++ ++This file is part of groff. ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation, either version 3 of the License, or ++(at your option) any later version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program. If not, see . */ ++%{ ++#include ++#include ++#include ++ ++#include "lib.h" ++#include "box.h" ++extern int non_empty_flag; ++int yylex(); ++void yyerror(const char *); ++%} ++ ++%union { ++ char *str; ++ box *b; ++ pile_box *pb; ++ matrix_box *mb; ++ int n; ++ column *col; ++} ++ ++%token OVER ++%token SMALLOVER ++%token SQRT ++%token SUB ++%token SUP ++%token LPILE ++%token RPILE ++%token CPILE ++%token PILE ++%token LEFT ++%token RIGHT ++%token TO ++%token FROM ++%token SIZE ++%token FONT ++%token ROMAN ++%token BOLD ++%token ITALIC ++%token FAT ++%token ACCENT ++%token BAR ++%token UNDER ++%token ABOVE ++%token TEXT ++%token QUOTED_TEXT ++%token FWD ++%token BACK ++%token DOWN ++%token UP ++%token MATRIX ++%token COL ++%token LCOL ++%token RCOL ++%token CCOL ++%token MARK ++%token LINEUP ++%token TYPE ++%token VCENTER ++%token PRIME ++%token SPLIT ++%token NOSPLIT ++%token UACCENT ++%token SPECIAL ++ ++/* these are handled in the lexer */ ++%token SPACE ++%token GFONT ++%token GSIZE ++%token DEFINE ++%token NDEFINE ++%token TDEFINE ++%token SDEFINE ++%token UNDEF ++%token IFDEF ++%token INCLUDE ++%token DELIM ++%token CHARTYPE ++%token SET ++%token GRFONT ++%token GBFONT ++ ++/* The original eqn manual says that `left' is right associative. It's lying. ++Consider `left ( ~ left ( ~ right ) right )'. */ ++ ++%right LEFT ++%left RIGHT ++%right LPILE RPILE CPILE PILE TEXT QUOTED_TEXT MATRIX MARK LINEUP '^' '~' '\t' '{' SPLIT NOSPLIT ++%right FROM TO ++%left SQRT OVER SMALLOVER ++%right SUB SUP ++%right ROMAN BOLD ITALIC FAT FONT SIZE FWD BACK DOWN UP TYPE VCENTER SPECIAL ++%right BAR UNDER PRIME ++%left ACCENT UACCENT ++ ++%type mark from_to sqrt_over script simple equation nonsup ++%type number ++%type text delim ++%type pile_element_list pile_arg ++%type column_list ++%type column column_arg column_element_list ++ ++%% ++top: ++ /* empty */ ++ | equation ++ { $1->top_level(); non_empty_flag = 1; } ++ ; ++ ++equation: ++ mark ++ { $$ = $1; } ++ | equation mark ++ { ++ list_box *lb = $1->to_list_box(); ++ if (!lb) ++ lb = new list_box($1); ++ lb->append($2); ++ $$ = lb; ++ } ++ ; ++ ++mark: ++ from_to ++ { $$ = $1; } ++ | MARK mark ++ { $$ = make_mark_box($2); } ++ | LINEUP mark ++ { $$ = make_lineup_box($2); } ++ ; ++ ++from_to: ++ sqrt_over %prec FROM ++ { $$ = $1; } ++ | sqrt_over TO from_to ++ { $$ = make_limit_box($1, 0, $3); } ++ | sqrt_over FROM sqrt_over ++ { $$ = make_limit_box($1, $3, 0); } ++ | sqrt_over FROM sqrt_over TO from_to ++ { $$ = make_limit_box($1, $3, $5); } ++ | sqrt_over FROM sqrt_over FROM from_to ++ { $$ = make_limit_box($1, make_limit_box($3, $5, 0), 0); } ++ ; ++ ++sqrt_over: ++ script ++ { $$ = $1; } ++ | SQRT sqrt_over ++ { $$ = make_sqrt_box($2); } ++ | sqrt_over OVER sqrt_over ++ { $$ = make_over_box($1, $3); } ++ | sqrt_over SMALLOVER sqrt_over ++ { $$ = make_small_over_box($1, $3); } ++ ; ++ ++script: ++ nonsup ++ { $$ = $1; } ++ | simple SUP script ++ { $$ = make_script_box($1, 0, $3); } ++ ; ++ ++nonsup: ++ simple %prec SUP ++ { $$ = $1; } ++ | simple SUB nonsup ++ { $$ = make_script_box($1, $3, 0); } ++ | simple SUB simple SUP script ++ { $$ = make_script_box($1, $3, $5); } ++ ; ++ ++simple: ++ TEXT ++ { $$ = split_text($1); } ++ | QUOTED_TEXT ++ { $$ = new quoted_text_box($1); } ++ | SPLIT QUOTED_TEXT ++ { $$ = split_text($2); } ++ | NOSPLIT TEXT ++ { $$ = new quoted_text_box($2); } ++ | '^' ++ { $$ = new half_space_box; } ++ | '~' ++ { $$ = new space_box; } ++ | '\t' ++ { $$ = new tab_box; } ++ | '{' equation '}' ++ { $$ = $2; } ++ | PILE pile_arg ++ { $2->set_alignment(CENTER_ALIGN); $$ = $2; } ++ | LPILE pile_arg ++ { $2->set_alignment(LEFT_ALIGN); $$ = $2; } ++ | RPILE pile_arg ++ { $2->set_alignment(RIGHT_ALIGN); $$ = $2; } ++ | CPILE pile_arg ++ { $2->set_alignment(CENTER_ALIGN); $$ = $2; } ++ | MATRIX '{' column_list '}' ++ { $$ = $3; } ++ | LEFT delim equation RIGHT delim ++ { $$ = make_delim_box($2, $3, $5); } ++ | LEFT delim equation ++ { $$ = make_delim_box($2, $3, 0); } ++ | simple BAR ++ { $$ = make_overline_box($1); } ++ | simple UNDER ++ { $$ = make_underline_box($1); } ++ | simple PRIME ++ { $$ = make_prime_box($1); } ++ | simple ACCENT simple ++ { $$ = make_accent_box($1, $3); } ++ | simple UACCENT simple ++ { $$ = make_uaccent_box($1, $3); } ++ | ROMAN simple ++ { $$ = new font_box(strsave(get_grfont()), $2); } ++ | BOLD simple ++ { $$ = new font_box(strsave(get_gbfont()), $2); } ++ | ITALIC simple ++ { $$ = new font_box(strsave(get_gfont()), $2); } ++ | FAT simple ++ { $$ = new fat_box($2); } ++ | FONT text simple ++ { $$ = new font_box($2, $3); } ++ | SIZE text simple ++ { $$ = new size_box($2, $3); } ++ | FWD number simple ++ { $$ = new hmotion_box($2, $3); } ++ | BACK number simple ++ { $$ = new hmotion_box(-$2, $3); } ++ | UP number simple ++ { $$ = new vmotion_box($2, $3); } ++ | DOWN number simple ++ { $$ = new vmotion_box(-$2, $3); } ++ | TYPE text simple ++ { $3->set_spacing_type($2); $$ = $3; } ++ | VCENTER simple ++ { $$ = new vcenter_box($2); } ++ | SPECIAL text simple ++ { $$ = make_special_box($2, $3); } ++ ; ++ ++number: ++ text ++ { ++ int n; ++ if (sscanf($1, "%d", &n) == 1) ++ $$ = n; ++ a_delete $1; ++ } ++ ; ++ ++pile_element_list: ++ equation ++ { $$ = new pile_box($1); } ++ | pile_element_list ABOVE equation ++ { $1->append($3); $$ = $1; } ++ ; ++ ++pile_arg: ++ '{' pile_element_list '}' ++ { $$ = $2; } ++ | number '{' pile_element_list '}' ++ { $3->set_space($1); $$ = $3; } ++ ; ++ ++column_list: ++ column ++ { $$ = new matrix_box($1); } ++ | column_list column ++ { $1->append($2); $$ = $1; } ++ ; ++ ++column_element_list: ++ equation ++ { $$ = new column($1); } ++ | column_element_list ABOVE equation ++ { $1->append($3); $$ = $1; } ++ ; ++ ++column_arg: ++ '{' column_element_list '}' ++ { $$ = $2; } ++ | number '{' column_element_list '}' ++ { $3->set_space($1); $$ = $3; } ++ ; ++ ++column: ++ COL column_arg ++ { $2->set_alignment(CENTER_ALIGN); $$ = $2; } ++ | LCOL column_arg ++ { $2->set_alignment(LEFT_ALIGN); $$ = $2; } ++ | RCOL column_arg ++ { $2->set_alignment(RIGHT_ALIGN); $$ = $2; } ++ | CCOL column_arg ++ { $2->set_alignment(CENTER_ALIGN); $$ = $2; } ++ ; ++ ++text: TEXT ++ { $$ = $1; } ++ | QUOTED_TEXT ++ { $$ = $1; } ++ ; ++ ++delim: ++ text ++ { $$ = $1; } ++ | '{' ++ { $$ = strsave("{"); } ++ | '}' ++ { $$ = strsave("}"); } ++ ; ++ ++%% +diff -Nuar groff-1.22.3.old/src/preproc/eqn/.gitignore groff-1.22.3/src/preproc/eqn/.gitignore +--- groff-1.22.3.old/src/preproc/eqn/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/eqn/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++eqn.cpp +diff -Nuar groff-1.22.3.old/src/preproc/eqn/lex.cpp groff-1.22.3/src/preproc/eqn/lex.cpp +--- groff-1.22.3.old/src/preproc/eqn/lex.cpp 2014-11-04 10:38:35.232523909 +0200 ++++ groff-1.22.3/src/preproc/eqn/lex.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -18,7 +18,7 @@ + along with this program. If not, see . */ + + #include "eqn.h" +-#include "eqn_tab.h" ++#include "eqn.hpp" + #include "stringclass.h" + #include "ptable.h" + +diff -Nuar groff-1.22.3.old/src/preproc/eqn/main.cpp groff-1.22.3/src/preproc/eqn/main.cpp +--- groff-1.22.3.old/src/preproc/eqn/main.cpp 2014-11-04 10:38:35.232523909 +0200 ++++ groff-1.22.3/src/preproc/eqn/main.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -25,6 +25,7 @@ + #include "htmlhint.h" + #include "pbox.h" + #include "ctype.h" ++#include "lf.h" + + #define STARTUP_FILE "eqnrc" + +@@ -66,9 +67,12 @@ + { + string linebuf; + string str; ++ string fn(filename); ++ fn += '\0'; ++ normalize_for_lf(fn); ++ current_filename = fn.contents(); + if (output_format == troff) +- printf(".lf 1 %s\n", filename); +- current_filename = filename; ++ printf(".lf 1 %s\n", current_filename); + current_lineno = 0; + while (read_line(fp, &linebuf)) { + if (linebuf.length() >= 4 +diff -Nuar groff-1.22.3.old/src/preproc/eqn/Makefile.sub groff-1.22.3/src/preproc/eqn/Makefile.sub +--- groff-1.22.3.old/src/preproc/eqn/Makefile.sub 2014-11-04 10:38:35.233523897 +0200 ++++ groff-1.22.3/src/preproc/eqn/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,93 +0,0 @@ +-# Makefile.sub for `preproc eqn' +-# +-# File position: /src/preproc/eqn/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=eqn$(EXEEXT) +-MAN1=eqn.n neqn.n +-XLIBS=$(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=\ +- eqn.$(OBJEXT) \ +- main.$(OBJEXT) \ +- lex.$(OBJEXT) \ +- box.$(OBJEXT) \ +- limit.$(OBJEXT) \ +- list.$(OBJEXT) \ +- over.$(OBJEXT) \ +- text.$(OBJEXT) \ +- script.$(OBJEXT) \ +- mark.$(OBJEXT) \ +- other.$(OBJEXT) \ +- delim.$(OBJEXT) \ +- sqrt.$(OBJEXT) \ +- pile.$(OBJEXT) \ +- special.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/main.cpp \ +- $(srcdir)/lex.cpp \ +- $(srcdir)/box.cpp \ +- $(srcdir)/limit.cpp \ +- $(srcdir)/list.cpp \ +- $(srcdir)/over.cpp \ +- $(srcdir)/text.cpp \ +- $(srcdir)/script.cpp \ +- $(srcdir)/mark.cpp \ +- $(srcdir)/other.cpp \ +- $(srcdir)/delim.cpp \ +- $(srcdir)/sqrt.cpp \ +- $(srcdir)/pile.cpp \ +- $(srcdir)/special.cpp +-HDRS=\ +- $(srcdir)/box.h \ +- $(srcdir)/eqn.h \ +- $(srcdir)/pbox.h +-GRAM=$(srcdir)/eqn.y +-YTABC=eqn.cpp +-YTABH=eqn_tab.h +-NAMEPREFIX=$(g) +-MOSTLYCLEANADD=neqn +-RM=rm -f +- +-all: neqn +- +-neqn: neqn.sh $(SH_DEPS_SED_SCRIPT) +- $(RM) $@ +- sed -e 's/@g@/$(g)/g' \ +- -f $(SH_DEPS_SED_SCRIPT) \ +- -e $(SH_SCRIPT_SED_CMD) $(srcdir)/neqn.sh >$@ +- chmod +x $@ +- +-install_data: neqn +- $(RM) $(DESTDIR)$(bindir)/$(NAMEPREFIX)neqn +- $(INSTALL_SCRIPT) neqn $(DESTDIR)$(bindir)/$(NAMEPREFIX)neqn +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/$(NAMEPREFIX)neqn +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/preproc/eqn/neqn.man groff-1.22.3/src/preproc/eqn/neqn.man +--- groff-1.22.3.old/src/preproc/eqn/neqn.man 2014-11-04 10:38:35.233523897 +0200 ++++ groff-1.22.3/src/preproc/eqn/neqn.man 2015-04-23 20:57:03.000000000 +0300 +@@ -5,7 +5,7 @@ + . + .\" license + .de co +-Copyright \[co] 2001-2014 Free Software Foundation, Inc. ++Copyright \(co 2001-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +diff -Nuar groff-1.22.3.old/src/preproc/grn/.gitignore groff-1.22.3/src/preproc/grn/.gitignore +--- groff-1.22.3.old/src/preproc/grn/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/grn/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++grn ++grn.n +diff -Nuar groff-1.22.3.old/src/preproc/grn/grn.am groff-1.22.3/src/preproc/grn/grn.am +--- groff-1.22.3.old/src/preproc/grn/grn.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/grn/grn.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,29 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++prefixexecbin_PROGRAMS += grn ++grn_SOURCES = \ ++ src/preproc/grn/hdb.cpp \ ++ src/preproc/grn/hpoint.cpp \ ++ src/preproc/grn/hgraph.cpp \ ++ src/preproc/grn/main.cpp \ ++ src/preproc/grn/gprint.h ++src/preproc/grn/main.$(OBJEXT): defs.h ++grn_LDADD = libgroff.a lib/libgnu.a $(LIBM) ++PREFIXMAN1 += src/preproc/grn/grn.n ++EXTRA_DIST += src/preproc/grn/README src/preproc/grn/grn.man +diff -Nuar groff-1.22.3.old/src/preproc/grn/grn.man groff-1.22.3/src/preproc/grn/grn.man +--- groff-1.22.3.old/src/preproc/grn/grn.man 2014-11-04 10:38:35.239523822 +0200 ++++ groff-1.22.3/src/preproc/grn/grn.man 2015-04-23 20:57:03.000000000 +0300 +@@ -10,7 +10,7 @@ + . + .\" license + .de co +-Copyright \[co] 2000-2014 Free Software Foundation, Inc. ++Copyright \(co 2000-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +diff -Nuar groff-1.22.3.old/src/preproc/grn/Makefile.sub groff-1.22.3/src/preproc/grn/Makefile.sub +--- groff-1.22.3.old/src/preproc/grn/Makefile.sub 2014-11-04 10:38:35.239523822 +0200 ++++ groff-1.22.3/src/preproc/grn/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,49 +0,0 @@ +-# Makefile.sub for `preproc grn +-# +-# File position: /src/preproc/grn/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=grn$(EXEEXT) +-MAN1=grn.n +-MLIB=$(LIBM) +-XLIBS=$(LIBGROFF) $(LIBGNU) +-OBJS=\ +- hdb.$(OBJEXT) \ +- hpoint.$(OBJEXT) \ +- hgraph.$(OBJEXT) \ +- main.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/hdb.cpp \ +- $(srcdir)/hpoint.cpp \ +- $(srcdir)/hgraph.cpp \ +- $(srcdir)/main.cpp +-HDRS=\ +- $(srcdir)/gprint.h +-NAMEPREFIX=$(g) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/preproc/html/.gitignore groff-1.22.3/src/preproc/html/.gitignore +--- groff-1.22.3.old/src/preproc/html/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/html/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,2 @@ ++Makefile.dep ++pre-grohtml +diff -Nuar groff-1.22.3.old/src/preproc/html/html.am groff-1.22.3/src/preproc/html/html.am +--- groff-1.22.3.old/src/preproc/html/html.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/html/html.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,26 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += pre-grohtml ++pre_grohtml_LDADD = libgroff.a lib/libgnu.a $(LIBM) ++pre_grohtml_SOURCES = \ ++ src/preproc/html/pre-html.cpp \ ++ src/preproc/html/pushback.cpp \ ++ src/preproc/html/pre-html.h \ ++ src/preproc/html/pushback.h ++src/preproc/html/pre-html.$(OBJEXT): defs.h +diff -Nuar groff-1.22.3.old/src/preproc/html/Makefile.sub groff-1.22.3/src/preproc/html/Makefile.sub +--- groff-1.22.3.old/src/preproc/html/Makefile.sub 2014-11-04 10:38:35.255523622 +0200 ++++ groff-1.22.3/src/preproc/html/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,39 +0,0 @@ +-# Makefile.sub for `preproc html' +-# +-# File position: /src/preproc/html/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=pre-grohtml$(EXEEXT) +-# MAN1=pre-grohtml.n +-MAN1= +-XLIBS=$(LIBGROFF) $(LIBGNU) +-MLIB=$(LIBM) +-OBJS=pre-html.$(OBJEXT) pushback.$(OBJEXT) +-CCSRCS=$(srcdir)/pre-html.cpp $(srcdir)/pushback.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/preproc/pic/.gitignore groff-1.22.3/src/preproc/pic/.gitignore +--- groff-1.22.3.old/src/preproc/pic/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/pic/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1 @@ ++pic.cpp +diff -Nuar groff-1.22.3.old/src/preproc/pic/lex.cpp groff-1.22.3/src/preproc/pic/lex.cpp +--- groff-1.22.3.old/src/preproc/pic/lex.cpp 2014-11-04 10:38:35.225523997 +0200 ++++ groff-1.22.3/src/preproc/pic/lex.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -20,7 +20,7 @@ + #include "pic.h" + #include "ptable.h" + #include "object.h" +-#include "pic_tab.h" ++#include "pic.hpp" + + declare_ptable(char) + implement_ptable(char) +diff -Nuar groff-1.22.3.old/src/preproc/pic/main.cpp groff-1.22.3/src/preproc/pic/main.cpp +--- groff-1.22.3.old/src/preproc/pic/main.cpp 2014-11-04 10:38:35.226523984 +0200 ++++ groff-1.22.3/src/preproc/pic/main.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -309,8 +309,11 @@ + fatal("can't open `%1': %2", filename, strerror(errno)); + } + } +- out->set_location(filename, 1); +- current_filename = filename; ++ string fn(filename); ++ fn += '\0'; ++ normalize_for_lf(fn); ++ current_filename = fn.contents(); ++ out->set_location(current_filename, 1); + current_lineno = 1; + enum { START, MIDDLE, HAD_DOT, HAD_P, HAD_PS, HAD_l, HAD_lf } state = START; + for (;;) { +diff -Nuar groff-1.22.3.old/src/preproc/pic/Makefile.sub groff-1.22.3/src/preproc/pic/Makefile.sub +--- groff-1.22.3.old/src/preproc/pic/Makefile.sub 2014-11-04 10:38:35.226523984 +0200 ++++ groff-1.22.3/src/preproc/pic/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,63 +0,0 @@ +-# Makefile.sub for `preproc pic' +-# +-# File position: /src/preproc/pic/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=pic$(EXEEXT) +-MAN1=pic.n +-XLIBS=$(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=\ +- pic.$(OBJEXT) \ +- lex.$(OBJEXT) \ +- main.$(OBJEXT) \ +- object.$(OBJEXT) \ +- common.$(OBJEXT) \ +- troff.$(OBJEXT) \ +- tex.$(OBJEXT) +- # fig.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/lex.cpp \ +- $(srcdir)/main.cpp \ +- $(srcdir)/object.cpp \ +- $(srcdir)/common.cpp \ +- $(srcdir)/troff.cpp \ +- $(srcdir)/tex.cpp +-HDRS=\ +- $(srcdir)/common.h \ +- $(srcdir)/object.h \ +- $(srcdir)/output.h \ +- $(srcdir)/pic.h \ +- $(srcdir)/position.h \ +- $(srcdir)/text.h +-GRAM=$(srcdir)/pic.y +-YTABC=pic.cpp +-YTABH=pic_tab.h +-NAMEPREFIX=$(g) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/preproc/pic/pic.am groff-1.22.3/src/preproc/pic/pic.am +--- groff-1.22.3.old/src/preproc/pic/pic.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/pic/pic.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,49 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++prefixexecbin_PROGRAMS += pic ++pic_LDADD = libgroff.a $(LIBM) ++pic_SOURCES = \ ++ src/preproc/pic/pic.ypp \ ++ src/preproc/pic/lex.cpp \ ++ src/preproc/pic/main.cpp \ ++ src/preproc/pic/object.cpp \ ++ src/preproc/pic/common.cpp \ ++ src/preproc/pic/troff.cpp \ ++ src/preproc/pic/tex.cpp \ ++ src/preproc/pic/pic.h \ ++ src/preproc/pic/position.h \ ++ src/preproc/pic/text.h \ ++ src/preproc/pic/common.h \ ++ src/preproc/pic/output.h \ ++ src/preproc/pic/object.h ++ ++pic_CPPFLAGS = $(AM_CPPFLAGS) \ ++ -I $(top_srcdir)/src/preproc/pic \ ++ -I $(top_builddir)/src/preproc/pic ++PREFIXMAN1 += src/preproc/pic/pic.n ++ ++src/preproc/pic/pic-lex.$(OBJEXT): src/preproc/pic/pic.hpp ++EXTRA_DIST += \ ++ src/preproc/pic/pic.man \ ++ src/preproc/pic/TODO ++CLEANFILES += \ ++ src/preproc/pic/pic.cpp \ ++ src/preproc/pic/pic.hpp \ ++ src/preproc/pic/pic.output ++ +diff -Nuar groff-1.22.3.old/src/preproc/pic/pic.cpp groff-1.22.3/src/preproc/pic/pic.cpp +--- groff-1.22.3.old/src/preproc/pic/pic.cpp 2014-11-04 10:38:37.823491518 +0200 ++++ groff-1.22.3/src/preproc/pic/pic.cpp 1970-01-01 02:00:00.000000000 +0200 +@@ -1,5008 +0,0 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ +- +-/* Bison implementation for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation, either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* C LALR(1) parser skeleton written by Richard Stallman, by +- simplifying the original so-called "semantic" parser. */ +- +-/* All symbols defined below should begin with yy or YY, to avoid +- infringing on user name space. This should be done even for local +- variables, as they might otherwise be expanded by user macros. +- There are some unavoidable exceptions within include files to +- define necessary library symbols; they are noted "INFRINGES ON +- USER NAME SPACE" below. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 +- +-/* Bison version. */ +-#define YYBISON_VERSION "3.0.2" +- +-/* Skeleton name. */ +-#define YYSKELETON_NAME "yacc.c" +- +-/* Pure parsers. */ +-#define YYPURE 0 +- +-/* Push parsers. */ +-#define YYPUSH 0 +- +-/* Pull parsers. */ +-#define YYPULL 1 +- +- +- +- +-/* Copy the first part of user declarations. */ +-#line 19 "pic.y" /* yacc.c:339 */ +- +-#include "pic.h" +-#include "ptable.h" +-#include "object.h" +- +-extern int delim_flag; +-extern void copy_rest_thru(const char *, const char *); +-extern void copy_file_thru(const char *, const char *, const char *); +-extern void push_body(const char *); +-extern void do_for(char *var, double from, double to, +- int by_is_multiplicative, double by, char *body); +-extern void do_lookahead(); +- +-/* Maximum number of characters produced by printf("%g") */ +-#define GDIGITS 14 +- +-int yylex(); +-void yyerror(const char *); +- +-void reset(const char *nm); +-void reset_all(); +- +-place *lookup_label(const char *); +-void define_label(const char *label, const place *pl); +- +-direction current_direction; +-position current_position; +- +-implement_ptable(place) +- +-PTABLE(place) top_table; +- +-PTABLE(place) *current_table = &top_table; +-saved_state *current_saved_state = 0; +- +-object_list olist; +- +-const char *ordinal_postfix(int n); +-const char *object_type_name(object_type type); +-char *format_number(const char *form, double n); +-char *do_sprintf(const char *form, const double *v, int nv); +- +- +-#line 110 "pic.cpp" /* yacc.c:339 */ +- +-# ifndef YY_NULLPTR +-# if defined __cplusplus && 201103L <= __cplusplus +-# define YY_NULLPTR nullptr +-# else +-# define YY_NULLPTR 0 +-# endif +-# endif +- +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 0 +-#endif +- +-/* In a future release of Bison, this section will be replaced +- by #include "y.tab.h". */ +-#ifndef YY_YY_Y_TAB_H_INCLUDED +-# define YY_YY_Y_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; +-#endif +- +-/* Token type. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- enum yytokentype +- { +- LABEL = 258, +- VARIABLE = 259, +- NUMBER = 260, +- TEXT = 261, +- COMMAND_LINE = 262, +- DELIMITED = 263, +- ORDINAL = 264, +- TH = 265, +- LEFT_ARROW_HEAD = 266, +- RIGHT_ARROW_HEAD = 267, +- DOUBLE_ARROW_HEAD = 268, +- LAST = 269, +- BOX = 270, +- CIRCLE = 271, +- ELLIPSE = 272, +- ARC = 273, +- LINE = 274, +- ARROW = 275, +- MOVE = 276, +- SPLINE = 277, +- HEIGHT = 278, +- RADIUS = 279, +- FIGNAME = 280, +- WIDTH = 281, +- DIAMETER = 282, +- UP = 283, +- DOWN = 284, +- RIGHT = 285, +- LEFT = 286, +- FROM = 287, +- TO = 288, +- AT = 289, +- WITH = 290, +- BY = 291, +- THEN = 292, +- SOLID = 293, +- DOTTED = 294, +- DASHED = 295, +- CHOP = 296, +- SAME = 297, +- INVISIBLE = 298, +- LJUST = 299, +- RJUST = 300, +- ABOVE = 301, +- BELOW = 302, +- OF = 303, +- THE = 304, +- WAY = 305, +- BETWEEN = 306, +- AND = 307, +- HERE = 308, +- DOT_N = 309, +- DOT_E = 310, +- DOT_W = 311, +- DOT_S = 312, +- DOT_NE = 313, +- DOT_SE = 314, +- DOT_NW = 315, +- DOT_SW = 316, +- DOT_C = 317, +- DOT_START = 318, +- DOT_END = 319, +- DOT_X = 320, +- DOT_Y = 321, +- DOT_HT = 322, +- DOT_WID = 323, +- DOT_RAD = 324, +- SIN = 325, +- COS = 326, +- ATAN2 = 327, +- LOG = 328, +- EXP = 329, +- SQRT = 330, +- K_MAX = 331, +- K_MIN = 332, +- INT = 333, +- RAND = 334, +- SRAND = 335, +- COPY = 336, +- THRU = 337, +- TOP = 338, +- BOTTOM = 339, +- UPPER = 340, +- LOWER = 341, +- SH = 342, +- PRINT = 343, +- CW = 344, +- CCW = 345, +- FOR = 346, +- DO = 347, +- IF = 348, +- ELSE = 349, +- ANDAND = 350, +- OROR = 351, +- NOTEQUAL = 352, +- EQUALEQUAL = 353, +- LESSEQUAL = 354, +- GREATEREQUAL = 355, +- LEFT_CORNER = 356, +- RIGHT_CORNER = 357, +- NORTH = 358, +- SOUTH = 359, +- EAST = 360, +- WEST = 361, +- CENTER = 362, +- END = 363, +- START = 364, +- RESET = 365, +- UNTIL = 366, +- PLOT = 367, +- THICKNESS = 368, +- FILL = 369, +- COLORED = 370, +- OUTLINED = 371, +- SHADED = 372, +- XSLANTED = 373, +- YSLANTED = 374, +- ALIGNED = 375, +- SPRINTF = 376, +- COMMAND = 377, +- DEFINE = 378, +- UNDEF = 379 +- }; +-#endif +-/* Tokens. */ +-#define LABEL 258 +-#define VARIABLE 259 +-#define NUMBER 260 +-#define TEXT 261 +-#define COMMAND_LINE 262 +-#define DELIMITED 263 +-#define ORDINAL 264 +-#define TH 265 +-#define LEFT_ARROW_HEAD 266 +-#define RIGHT_ARROW_HEAD 267 +-#define DOUBLE_ARROW_HEAD 268 +-#define LAST 269 +-#define BOX 270 +-#define CIRCLE 271 +-#define ELLIPSE 272 +-#define ARC 273 +-#define LINE 274 +-#define ARROW 275 +-#define MOVE 276 +-#define SPLINE 277 +-#define HEIGHT 278 +-#define RADIUS 279 +-#define FIGNAME 280 +-#define WIDTH 281 +-#define DIAMETER 282 +-#define UP 283 +-#define DOWN 284 +-#define RIGHT 285 +-#define LEFT 286 +-#define FROM 287 +-#define TO 288 +-#define AT 289 +-#define WITH 290 +-#define BY 291 +-#define THEN 292 +-#define SOLID 293 +-#define DOTTED 294 +-#define DASHED 295 +-#define CHOP 296 +-#define SAME 297 +-#define INVISIBLE 298 +-#define LJUST 299 +-#define RJUST 300 +-#define ABOVE 301 +-#define BELOW 302 +-#define OF 303 +-#define THE 304 +-#define WAY 305 +-#define BETWEEN 306 +-#define AND 307 +-#define HERE 308 +-#define DOT_N 309 +-#define DOT_E 310 +-#define DOT_W 311 +-#define DOT_S 312 +-#define DOT_NE 313 +-#define DOT_SE 314 +-#define DOT_NW 315 +-#define DOT_SW 316 +-#define DOT_C 317 +-#define DOT_START 318 +-#define DOT_END 319 +-#define DOT_X 320 +-#define DOT_Y 321 +-#define DOT_HT 322 +-#define DOT_WID 323 +-#define DOT_RAD 324 +-#define SIN 325 +-#define COS 326 +-#define ATAN2 327 +-#define LOG 328 +-#define EXP 329 +-#define SQRT 330 +-#define K_MAX 331 +-#define K_MIN 332 +-#define INT 333 +-#define RAND 334 +-#define SRAND 335 +-#define COPY 336 +-#define THRU 337 +-#define TOP 338 +-#define BOTTOM 339 +-#define UPPER 340 +-#define LOWER 341 +-#define SH 342 +-#define PRINT 343 +-#define CW 344 +-#define CCW 345 +-#define FOR 346 +-#define DO 347 +-#define IF 348 +-#define ELSE 349 +-#define ANDAND 350 +-#define OROR 351 +-#define NOTEQUAL 352 +-#define EQUALEQUAL 353 +-#define LESSEQUAL 354 +-#define GREATEREQUAL 355 +-#define LEFT_CORNER 356 +-#define RIGHT_CORNER 357 +-#define NORTH 358 +-#define SOUTH 359 +-#define EAST 360 +-#define WEST 361 +-#define CENTER 362 +-#define END 363 +-#define START 364 +-#define RESET 365 +-#define UNTIL 366 +-#define PLOT 367 +-#define THICKNESS 368 +-#define FILL 369 +-#define COLORED 370 +-#define OUTLINED 371 +-#define SHADED 372 +-#define XSLANTED 373 +-#define YSLANTED 374 +-#define ALIGNED 375 +-#define SPRINTF 376 +-#define COMMAND 377 +-#define DEFINE 378 +-#define UNDEF 379 +- +-/* Value type. */ +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE +-{ +-#line 65 "pic.y" /* yacc.c:355 */ +- +- char *str; +- int n; +- double x; +- struct { double x, y; } pair; +- struct { double x; char *body; } if_data; +- struct { char *str; const char *filename; int lineno; } lstr; +- struct { double *v; int nv; int maxv; } dv; +- struct { double val; int is_multiplicative; } by; +- place pl; +- object *obj; +- corner crn; +- path *pth; +- object_spec *spec; +- saved_state *pstate; +- graphics_state state; +- object_type obtype; +- +-#line 417 "pic.cpp" /* yacc.c:355 */ +-}; +-# define YYSTYPE_IS_TRIVIAL 1 +-# define YYSTYPE_IS_DECLARED 1 +-#endif +- +- +-extern YYSTYPE yylval; +- +-int yyparse (void); +- +-#endif /* !YY_YY_Y_TAB_H_INCLUDED */ +- +-/* Copy the second part of user declarations. */ +- +-#line 432 "pic.cpp" /* yacc.c:358 */ +- +-#ifdef short +-# undef short +-#endif +- +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; +-#endif +- +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; +-#else +-typedef signed char yytype_int8; +-#endif +- +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; +-#else +-typedef unsigned short int yytype_uint16; +-#endif +- +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; +-#else +-typedef short int yytype_int16; +-#endif +- +-#ifndef YYSIZE_T +-# ifdef __SIZE_TYPE__ +-# define YYSIZE_T __SIZE_TYPE__ +-# elif defined size_t +-# define YYSIZE_T size_t +-# elif ! defined YYSIZE_T +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# else +-# define YYSIZE_T unsigned int +-# endif +-#endif +- +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +- +-#ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS +-# if ENABLE_NLS +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +-# endif +-# endif +-# ifndef YY_ +-# define YY_(Msgid) Msgid +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE +-# if (defined __GNUC__ \ +- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ +- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +-# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +-# else +-# define YY_ATTRIBUTE(Spec) /* empty */ +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE_PURE +-# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +-#endif +- +-#ifndef YY_ATTRIBUTE_UNUSED +-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +-#endif +- +-#if !defined _Noreturn \ +- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +-# if defined _MSC_VER && 1200 <= _MSC_VER +-# define _Noreturn __declspec (noreturn) +-# else +-# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +-# endif +-#endif +- +-/* Suppress unused-variable warnings by "using" E. */ +-#if ! defined lint || defined __GNUC__ +-# define YYUSE(E) ((void) (E)) +-#else +-# define YYUSE(E) /* empty */ +-#endif +- +-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +-/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +- _Pragma ("GCC diagnostic push") \ +- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +- _Pragma ("GCC diagnostic pop") +-#else +-# define YY_INITIAL_VALUE(Value) Value +-#endif +-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END +-#endif +-#ifndef YY_INITIAL_VALUE +-# define YY_INITIAL_VALUE(Value) /* Nothing. */ +-#endif +- +- +-#if ! defined yyoverflow || YYERROR_VERBOSE +- +-/* The parser invokes alloca or malloc; define the necessary symbols. */ +- +-# ifdef YYSTACK_USE_ALLOCA +-# if YYSTACK_USE_ALLOCA +-# ifdef __GNUC__ +-# define YYSTACK_ALLOC __builtin_alloca +-# elif defined __BUILTIN_VA_ARG_INCR +-# include /* INFRINGES ON USER NAME SPACE */ +-# elif defined _AIX +-# define YYSTACK_ALLOC __alloca +-# elif defined _MSC_VER +-# include /* INFRINGES ON USER NAME SPACE */ +-# define alloca _alloca +-# else +-# define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +-# include /* INFRINGES ON USER NAME SPACE */ +- /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +-# ifndef EXIT_SUCCESS +-# define EXIT_SUCCESS 0 +-# endif +-# endif +-# endif +-# endif +-# endif +- +-# ifdef YYSTACK_ALLOC +- /* Pacify GCC's 'empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +-# ifndef YYSTACK_ALLOC_MAXIMUM +- /* The OS might guarantee only one guard page at the bottom of the stack, +- and a page size can be as small as 4096 bytes. So we cannot safely +- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number +- to allow for a few compiler-allocated temporary stack slots. */ +-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +-# endif +-# else +-# define YYSTACK_ALLOC YYMALLOC +-# define YYSTACK_FREE YYFREE +-# ifndef YYSTACK_ALLOC_MAXIMUM +-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +-# endif +-# if (defined __cplusplus && ! defined EXIT_SUCCESS \ +- && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef EXIT_SUCCESS +-# define EXIT_SUCCESS 0 +-# endif +-# endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc +-# if ! defined malloc && ! defined EXIT_SUCCESS +-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# ifndef YYFREE +-# define YYFREE free +-# if ! defined free && ! defined EXIT_SUCCESS +-void free (void *); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- +- +-#if (! defined yyoverflow \ +- && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +- +-/* A type that is properly aligned for any stack member. */ +-union yyalloc +-{ +- yytype_int16 yyss_alloc; +- YYSTYPE yyvs_alloc; +-}; +- +-/* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +- +-/* The size of an array large to enough to hold all stacks, each with +- N elements. */ +-# define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) +- +-# define YYCOPY_NEEDED 1 +- +-/* Relocate STACK from its old location to the new one. The +- local variables YYSIZE and YYSTACKSIZE give the old and new number of +- elements in the stack, and YYPTR gives the new location of the +- stack. Advance YYPTR to a properly aligned location for the next +- stack. */ +-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ +- Stack = &yyptr->Stack_alloc; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (0) +- +-#endif +- +-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +-/* Copy COUNT objects from SRC to DST. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(Dst, Src, Count) \ +- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +-# else +-# define YYCOPY(Dst, Src, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (Dst)[yyi] = (Src)[yyi]; \ +- } \ +- while (0) +-# endif +-# endif +-#endif /* !YYCOPY_NEEDED */ +- +-/* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 6 +-/* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 2438 +- +-/* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 146 +-/* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 49 +-/* YYNRULES -- Number of rules. */ +-#define YYNRULES 260 +-/* YYNSTATES -- Number of states. */ +-#define YYNSTATES 454 +- +-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned +- by yylex, with out-of-bounds checking. */ +-#define YYUNDEFTOK 2 +-#define YYMAXUTOK 379 +- +-#define YYTRANSLATE(YYX) \ +- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +- +-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM +- as returned by yylex, without out-of-bounds checking. */ +-static const yytype_uint8 yytranslate[] = +-{ +- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 137, 2, 2, 2, 136, 2, 2, +- 126, 145, 134, 132, 129, 133, 125, 135, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 141, 139, +- 130, 140, 131, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 128, 2, 144, 138, 2, 127, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 142, 2, 143, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, +- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, +- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, +- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, +- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, +- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, +- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, +- 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, +- 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, +- 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, +- 115, 116, 117, 118, 119, 120, 121, 122, 123, 124 +-}; +- +-#if YYDEBUG +- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +-static const yytype_uint16 yyrline[] = +-{ +- 0, 275, 275, 276, 285, 290, 292, 296, 298, 302, +- 303, 307, 315, 320, 332, 334, 336, 338, 340, 345, +- 350, 357, 356, 367, 375, 377, 374, 388, 390, 387, +- 400, 399, 408, 417, 416, 430, 431, 436, 437, 441, +- 446, 451, 459, 461, 480, 487, 489, 500, 499, 511, +- 512, 517, 519, 524, 530, 536, 538, 540, 542, 544, +- 546, 548, 555, 559, 564, 572, 586, 592, 600, 607, +- 613, 606, 622, 632, 633, 638, 640, 642, 644, 649, +- 656, 663, 670, 677, 682, 687, 695, 694, 721, 727, +- 733, 739, 745, 764, 771, 778, 785, 792, 799, 806, +- 813, 820, 827, 842, 854, 860, 869, 876, 901, 905, +- 911, 917, 923, 929, 934, 940, 946, 952, 959, 968, +- 975, 991, 1008, 1013, 1018, 1023, 1028, 1033, 1038, 1043, +- 1051, 1061, 1071, 1081, 1091, 1097, 1105, 1107, 1119, 1124, +- 1154, 1156, 1162, 1171, 1173, 1178, 1183, 1188, 1193, 1198, +- 1203, 1209, 1214, 1222, 1223, 1227, 1232, 1238, 1240, 1246, +- 1252, 1258, 1267, 1277, 1279, 1288, 1290, 1298, 1300, 1305, +- 1320, 1338, 1340, 1342, 1344, 1346, 1348, 1350, 1352, 1354, +- 1359, 1361, 1369, 1373, 1375, 1383, 1385, 1391, 1397, 1403, +- 1409, 1418, 1420, 1422, 1424, 1426, 1428, 1430, 1432, 1434, +- 1436, 1438, 1440, 1442, 1444, 1446, 1448, 1450, 1452, 1454, +- 1456, 1458, 1460, 1462, 1464, 1466, 1468, 1470, 1472, 1474, +- 1476, 1478, 1480, 1485, 1487, 1492, 1497, 1505, 1507, 1514, +- 1521, 1528, 1535, 1542, 1544, 1546, 1548, 1556, 1564, 1577, +- 1579, 1581, 1590, 1599, 1612, 1621, 1630, 1639, 1641, 1643, +- 1645, 1647, 1653, 1658, 1660, 1662, 1664, 1666, 1668, 1670, +- 1672 +-}; +-#endif +- +-#if YYDEBUG || YYERROR_VERBOSE || 0 +-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +-static const char *const yytname[] = +-{ +- "$end", "error", "$undefined", "LABEL", "VARIABLE", "NUMBER", "TEXT", +- "COMMAND_LINE", "DELIMITED", "ORDINAL", "TH", "LEFT_ARROW_HEAD", +- "RIGHT_ARROW_HEAD", "DOUBLE_ARROW_HEAD", "LAST", "BOX", "CIRCLE", +- "ELLIPSE", "ARC", "LINE", "ARROW", "MOVE", "SPLINE", "HEIGHT", "RADIUS", +- "FIGNAME", "WIDTH", "DIAMETER", "UP", "DOWN", "RIGHT", "LEFT", "FROM", +- "TO", "AT", "WITH", "BY", "THEN", "SOLID", "DOTTED", "DASHED", "CHOP", +- "SAME", "INVISIBLE", "LJUST", "RJUST", "ABOVE", "BELOW", "OF", "THE", +- "WAY", "BETWEEN", "AND", "HERE", "DOT_N", "DOT_E", "DOT_W", "DOT_S", +- "DOT_NE", "DOT_SE", "DOT_NW", "DOT_SW", "DOT_C", "DOT_START", "DOT_END", +- "DOT_X", "DOT_Y", "DOT_HT", "DOT_WID", "DOT_RAD", "SIN", "COS", "ATAN2", +- "LOG", "EXP", "SQRT", "K_MAX", "K_MIN", "INT", "RAND", "SRAND", "COPY", +- "THRU", "TOP", "BOTTOM", "UPPER", "LOWER", "SH", "PRINT", "CW", "CCW", +- "FOR", "DO", "IF", "ELSE", "ANDAND", "OROR", "NOTEQUAL", "EQUALEQUAL", +- "LESSEQUAL", "GREATEREQUAL", "LEFT_CORNER", "RIGHT_CORNER", "NORTH", +- "SOUTH", "EAST", "WEST", "CENTER", "END", "START", "RESET", "UNTIL", +- "PLOT", "THICKNESS", "FILL", "COLORED", "OUTLINED", "SHADED", "XSLANTED", +- "YSLANTED", "ALIGNED", "SPRINTF", "COMMAND", "DEFINE", "UNDEF", "'.'", +- "'('", "'`'", "'['", "','", "'<'", "'>'", "'+'", "'-'", "'*'", "'/'", +- "'%'", "'!'", "'^'", "';'", "'='", "':'", "'{'", "'}'", "']'", "')'", +- "$accept", "top", "element_list", "middle_element_list", +- "optional_separator", "separator", "placeless_element", "$@1", "$@2", +- "$@3", "$@4", "$@5", "$@6", "$@7", "macro_name", "reset_variables", +- "print_args", "print_arg", "simple_if", "$@8", "until", "any_expr", +- "text_expr", "optional_by", "element", "@9", "$@10", "optional_element", +- "object_spec", "@11", "text", "sprintf_args", "position", +- "position_not_place", "between", "expr_pair", "place", "label", +- "ordinal", "optional_ordinal_last", "nth_primitive", "object_type", +- "label_path", "relative_path", "path", "corner", "expr", +- "expr_lower_than", "expr_not_lower_than", YY_NULLPTR +-}; +-#endif +- +-# ifdef YYPRINT +-/* YYTOKNUM[NUM] -- (External) token number corresponding to the +- (internal) symbol number NUM (which must be that of a token). */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, +- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, +- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, +- 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, +- 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, +- 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, +- 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, +- 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, +- 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, +- 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, +- 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, +- 375, 376, 377, 378, 379, 46, 40, 96, 91, 44, +- 60, 62, 43, 45, 42, 47, 37, 33, 94, 59, +- 61, 58, 123, 125, 93, 41 +-}; +-# endif +- +-#define YYPACT_NINF -240 +- +-#define yypact_value_is_default(Yystate) \ +- (!!((Yystate) == (-240))) +- +-#define YYTABLE_NINF -206 +- +-#define yytable_value_is_error(Yytable_value) \ +- 0 +- +- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-static const yytype_int16 yypact[] = +-{ +- -114, -240, 20, -240, 757, -107, -240, -98, -123, -240, +- -240, -240, -240, -240, -240, -240, -240, -240, -240, -106, +- -240, -240, -240, -240, 9, -240, 1087, 46, 1172, 49, +- 1597, -70, 1087, -240, -240, -114, -240, 3, -33, -240, +- 877, -240, -240, -114, 1172, -60, 36, -14, -240, 74, +- -240, -240, -240, -240, -240, -240, -240, -240, -240, -240, +- -240, -240, -240, -240, -240, -240, -240, -240, -240, -34, +- -18, 8, 38, 47, 51, 65, 101, 102, 112, 122, +- -240, -240, 21, 150, -240, -240, -240, -240, -240, -240, +- -240, -240, -240, 1257, 1172, 1597, 1597, 1087, -240, -240, +- -43, -240, -240, 357, 2242, 59, 258, -240, 10, 2147, +- -240, 1, 6, 1172, 1172, 145, -1, 2, 357, 2273, +- -240, -240, 220, 249, 1087, -114, -114, -240, 721, -240, +- 252, -240, -240, -240, -240, 1597, 1597, 1597, 1597, 2024, +- 2024, 1853, 1939, 1682, 1682, 1682, 1427, 1767, -240, -240, +- 2024, 2024, 2024, -240, -240, -240, -240, -240, -240, -240, +- -240, 1597, 2024, 23, 23, 23, 1597, 1597, -240, -240, +- 2282, 593, -240, 1172, -240, -240, -240, -240, 250, -240, +- 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 1172, 458, +- 1172, -240, -240, -240, -240, -240, -240, -240, -240, 121, +- 107, 123, 256, 2157, 137, 261, 134, 134, -240, 1767, +- 1767, -240, -240, -240, -240, -240, 276, -240, -240, -240, +- -240, -240, -240, -240, -240, -240, -240, 138, -240, -240, +- 24, 156, 235, -240, 1597, 1597, 1597, 1597, 1597, 1597, +- 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1682, +- 1682, 1597, -240, 134, -240, 1172, 1172, 23, 23, 1172, +- 1172, -240, -240, 143, 757, 153, -240, -240, 280, 2282, +- 2282, 2282, 2282, 2282, 2282, 2282, 2282, -43, 2147, -43, +- -43, 2253, 275, 275, 295, 1002, -43, 2081, -240, -240, +- 10, 1342, -240, 694, 2282, 2282, 2282, 2282, 2282, -240, +- -240, -240, 2282, 2282, -98, -123, 16, 28, -240, -43, +- 56, 302, -240, 291, -240, 155, 160, 172, 161, 164, +- 167, 184, 185, 181, -240, 186, 188, -240, 1682, 1767, +- 1767, -240, -240, 1682, 1682, -240, -240, -240, -240, -240, +- 156, 279, 314, 2291, 440, 440, 413, 413, 2282, 413, +- 413, -72, -72, 134, 134, 134, 134, -49, 117, 343, +- 322, -240, 314, 239, 2300, -240, -240, -240, 314, 239, +- 2300, -119, -240, -240, -240, -240, -240, 2116, 2116, -240, +- 206, 333, -240, 123, 2131, -240, 228, -240, -240, 1172, +- -240, -240, -240, 1172, 1172, -240, -240, -240, -110, 195, +- 197, -47, 128, 292, 1682, 1682, 1597, -240, 1597, -240, +- 757, -240, -240, 2116, -240, 228, 338, -240, 200, 202, +- 212, -240, -240, -240, 1682, 1682, -240, -43, -27, 360, +- 2282, -240, -240, 214, -240, -240, -240, -240, -240, -73, +- 30, -240, 1512, 268, -240, -240, 216, 1597, 2282, -240, +- -240, 2282, 354, -240 +-}; +- +- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +- Performed when YYTABLE does not specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint16 yydefact[] = +-{ +- 7, 9, 0, 3, 2, 8, 1, 0, 0, 136, +- 18, 75, 76, 77, 78, 79, 80, 81, 82, 0, +- 14, 15, 17, 16, 0, 21, 0, 0, 0, 36, +- 0, 0, 0, 86, 69, 7, 72, 35, 32, 5, +- 65, 83, 10, 7, 0, 0, 0, 23, 27, 0, +- 162, 226, 227, 165, 167, 205, 204, 161, 191, 192, +- 193, 194, 195, 196, 197, 198, 199, 200, 201, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 202, 203, 0, 0, 210, 211, 216, 217, 218, 219, +- 220, 222, 221, 0, 0, 0, 0, 20, 42, 45, +- 46, 140, 143, 141, 157, 0, 0, 163, 0, 44, +- 223, 224, 0, 0, 0, 0, 52, 0, 0, 51, +- 224, 39, 84, 0, 19, 7, 7, 4, 8, 40, +- 0, 33, 124, 125, 126, 0, 0, 0, 0, 93, +- 95, 97, 99, 0, 0, 0, 0, 0, 107, 108, +- 109, 111, 120, 122, 123, 130, 131, 132, 133, 127, +- 128, 0, 113, 0, 0, 0, 0, 0, 135, 129, +- 92, 0, 12, 0, 38, 37, 11, 24, 0, 22, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 208, 206, 212, 214, 209, 207, 213, 215, 0, +- 0, 143, 141, 51, 224, 0, 239, 260, 43, 0, +- 0, 228, 229, 230, 231, 232, 0, 158, 179, 168, +- 171, 172, 173, 174, 175, 176, 177, 0, 169, 170, +- 0, 159, 0, 153, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 61, 260, 47, 0, 0, 0, 0, 0, +- 0, 85, 138, 0, 0, 0, 6, 41, 0, 88, +- 89, 90, 91, 94, 96, 98, 100, 101, 0, 102, +- 103, 162, 165, 167, 0, 0, 105, 183, 185, 104, +- 182, 0, 106, 0, 110, 112, 121, 134, 114, 118, +- 119, 117, 115, 116, 162, 226, 205, 204, 66, 0, +- 67, 68, 13, 0, 28, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 251, 0, 0, 240, 0, 0, +- 0, 156, 142, 0, 0, 166, 144, 146, 164, 178, +- 160, 0, 258, 259, 257, 256, 253, 255, 155, 225, +- 254, 233, 234, 235, 236, 237, 238, 0, 0, 0, +- 0, 55, 56, 58, 59, 54, 53, 57, 258, 60, +- 259, 0, 87, 70, 34, 190, 182, 0, 0, 180, +- 0, 0, 184, 0, 51, 25, 49, 241, 242, 0, +- 244, 245, 246, 0, 0, 249, 250, 252, 0, 144, +- 146, 0, 0, 0, 0, 0, 0, 48, 0, 137, +- 73, 189, 188, 0, 181, 49, 0, 29, 0, 0, +- 0, 148, 145, 147, 0, 0, 154, 149, 0, 62, +- 139, 74, 71, 0, 26, 50, 243, 247, 248, 149, +- 0, 151, 0, 0, 186, 150, 151, 0, 63, 30, +- 152, 64, 0, 31 +-}; +- +- /* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int16 yypgoto[] = +-{ +- -240, -240, 17, -240, 12, 329, -240, -240, -240, -240, +- -240, -240, -240, -240, -240, -240, 334, -76, -240, -240, +- -42, 13, -103, -240, -127, -240, -240, -240, -240, -240, +- 5, -240, 99, 194, 169, -44, 4, -100, -240, -240, +- -240, -104, -240, -239, -240, -50, -26, -240, 61 +-}; +- +- /* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int16 yydefgoto[] = +-{ +- -1, 2, 3, 35, 264, 5, 36, 49, 313, 415, +- 178, 386, 452, 268, 176, 37, 97, 98, 38, 360, +- 417, 199, 116, 443, 39, 126, 410, 432, 40, 125, +- 117, 371, 100, 101, 249, 102, 118, 104, 105, 106, +- 107, 228, 287, 288, 289, 108, 119, 110, 120 +-}; +- +- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule whose +- number is the opposite. If YYTABLE_NINF, syntax error. */ +-static const yytype_int16 yytable[] = +-{ +- 109, 266, 229, 404, 122, 424, 109, 129, 231, 41, +- 408, 252, 4, 50, 170, 47, -17, 44, 45, 53, +- 6, 208, 209, 210, 54, 1, 409, 50, -16, 9, +- 103, 99, 42, 53, 46, 421, 103, 99, 54, 174, +- 175, 115, 375, 43, 308, 169, 380, 127, 208, 201, +- 112, 191, 192, 121, 217, 171, 123, 172, 230, 209, +- 210, 131, 245, 246, 247, 218, 248, 203, 177, 206, +- 207, 109, 445, 219, 220, 221, 222, 223, 224, 225, +- 173, 226, 179, 209, 210, 209, 210, 111, 253, 209, +- 210, 48, 180, 111, 255, 256, 290, 202, 109, 257, +- 258, 103, 99, 292, 441, 209, 210, 205, 181, 269, +- 270, 271, 272, 273, 274, 275, 276, 278, 278, 278, +- 278, 293, 193, 194, 294, 295, 296, 261, 103, 99, +- 340, 250, 130, 41, 182, 297, 298, 94, 411, 412, +- 302, 303, 263, 265, 31, 278, 251, 103, 103, 103, +- 103, 94, 361, 363, 204, -17, 367, 369, 111, -17, +- -17, 446, 209, 210, 183, 336, 337, -16, 299, 300, +- 301, -16, -16, 184, 433, 311, 41, 185, 377, 378, +- 195, 196, 254, 293, 293, 111, 312, 227, -140, -140, +- 231, 186, 200, 315, 316, 317, 318, 319, 320, 321, +- 322, 323, 325, 326, 111, 111, 111, 111, 342, 343, +- 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, +- 354, 355, 356, 278, 278, 359, 9, 187, 188, 362, +- 364, 376, 111, 368, 370, 290, 328, 382, 189, 329, +- 330, 201, 277, 279, 280, 286, 405, 383, 190, 209, +- 210, 197, 198, 103, 103, 262, 267, 425, 314, 203, +- 209, 210, 365, 366, 218, 384, 327, 334, 331, 41, +- 309, 335, 248, 220, 221, 222, 223, 224, 225, 338, +- 226, 216, 339, 431, 341, 399, 400, 372, 374, 202, +- 220, 221, 222, 223, 224, 225, 373, 226, 379, 385, +- 387, 389, 278, 293, 293, 388, 390, 278, 278, 391, +- 111, 111, 392, 393, 394, 234, 235, 236, 237, 238, +- 239, 211, 212, 213, 214, 215, 395, 376, 376, 403, +- 407, 396, 103, 397, 255, 413, 414, 103, 103, 416, +- 422, 31, 423, 426, 435, 436, 204, 437, 357, 358, +- 241, 242, 243, 244, 245, 246, 247, 438, 248, 444, +- 449, 450, 453, 376, 128, 310, 124, 211, 212, 213, +- 214, 215, 333, 434, 0, 0, 406, 0, 278, 278, +- 429, 0, 430, 0, 200, 0, 227, 0, 0, 111, +- 0, 0, 0, 0, 111, 111, 442, 0, 278, 278, +- 0, 332, 418, 227, 0, 0, 419, 420, 103, 103, +- 0, 236, 237, 238, 239, 41, 448, 0, 0, 0, +- 0, 451, 211, 212, 213, 214, 215, 398, 103, 103, +- 0, 0, 401, 402, -141, -141, 0, 0, 234, 235, +- 236, 237, 238, 239, 241, 242, 243, 244, 245, 246, +- 247, 0, 248, 0, 0, 234, 235, 236, 237, 238, +- 239, 50, 51, 52, 9, 111, 111, 53, 0, 0, +- 0, 0, 54, 241, 242, 243, 244, 245, 246, 247, +- 0, 248, 0, 0, 0, 111, 111, 0, 55, 56, +- 241, 242, 243, 244, 245, 246, 247, 0, 248, 0, +- 0, 0, 0, 427, 428, 0, 0, 0, 0, 0, +- 0, 57, 58, 59, 60, 61, 62, 63, 64, 65, +- 66, 67, 68, 439, 440, 0, 0, 0, 69, 70, +- 71, 72, 73, 74, 75, 76, 77, 78, 79, 238, +- 239, 80, 81, 82, 83, 243, 244, 245, 246, 247, +- 0, 248, 0, 0, 0, 0, 0, 0, 0, 84, +- 85, 86, 87, 88, 89, 90, 91, 92, 0, 0, +- 241, 242, 243, 244, 245, 246, 247, 0, 248, 31, +- 0, 0, 0, 0, 113, 94, 0, 0, 0, 0, +- 0, 95, 0, 0, 0, 114, 304, 305, 52, 9, +- 10, 0, 53, 324, 0, 0, 0, 54, 11, 12, +- 13, 14, 15, 16, 17, 18, 0, 0, 19, 0, +- 0, 20, 21, 306, 307, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 57, 58, 59, 60, +- 61, 62, 63, 64, 65, 66, 67, 68, 0, 0, +- 0, 0, 0, 69, 70, 71, 72, 73, 74, 75, +- 76, 77, 78, 79, 24, 0, 80, 81, 82, 83, +- 25, 26, 0, 0, 27, 0, 28, 0, 0, 0, +- 0, 0, 0, 0, 84, 85, 86, 87, 88, 89, +- 90, 91, 92, 29, 0, 30, 0, 0, 0, 0, +- 0, 0, 0, 0, 31, 32, 0, 0, 0, 93, +- 94, 33, 0, 0, 7, 8, 95, 9, 10, 0, +- 96, 0, 0, 0, 0, 34, 11, 12, 13, 14, +- 15, 16, 17, 18, 0, 0, 19, 0, 0, 20, +- 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, +- 7, 8, 0, 9, 10, 0, 0, 0, 0, 0, +- 0, 0, 11, 12, 13, 14, 15, 16, 17, 18, +- 0, 0, 19, 0, 0, 20, 21, 22, 23, 234, +- 235, 236, 237, 238, 239, 0, 0, 0, 0, 0, +- 0, 0, 24, 0, 0, 0, 0, 0, 25, 26, +- 0, 0, 27, 0, 28, 0, 0, 0, 0, 0, +- 0, 0, 0, 240, 241, 242, 243, 244, 245, 246, +- 247, 29, 248, 30, 0, 0, 0, 0, 24, 0, +- 0, 0, 31, 32, 25, 26, 0, 0, 27, 33, +- 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 42, 0, 0, 34, 0, 0, 0, 29, 0, 30, +- 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, +- 50, 51, 52, 9, 0, 33, 53, 0, 132, 133, +- 134, 54, 0, 0, 0, 0, 0, 0, 0, 34, +- 135, 136, 0, 137, 138, 139, 140, 141, 142, 143, +- 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, +- 154, 155, 156, 157, 158, 0, 0, 0, 0, 0, +- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, +- 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, +- 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, +- 80, 81, 82, 83, 0, 0, 159, 160, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 84, 85, +- 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, +- 161, 162, 163, 164, 165, 166, 167, 168, 31, 0, +- 0, 0, 0, 113, 94, 50, 51, 52, 9, 0, +- 95, 53, 0, 0, 96, 0, 54, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 57, 58, 59, 60, 61, +- 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, +- 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, +- 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, +- 50, 51, 52, 9, 0, 0, 53, 0, 0, 0, +- 0, 54, 0, 84, 85, 86, 87, 88, 89, 90, +- 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, +- 0, 0, 0, 31, 0, 0, 0, 284, 93, 94, +- 0, 0, 0, 0, 0, 95, 0, 0, 0, 114, +- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, +- 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, +- 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, +- 80, 81, 82, 83, 0, 50, 51, 52, 9, 0, +- 0, 53, 0, 0, 0, 0, 54, 0, 84, 85, +- 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, +- 0, 0, 55, 56, 0, 0, 0, 0, 31, 0, +- 0, 0, 0, 93, 94, 0, 0, 0, 0, 0, +- 95, 0, 0, 0, 96, 57, 58, 59, 60, 61, +- 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, +- 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, +- 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, +- 50, 51, 52, 9, 0, 0, 53, 0, 0, 0, +- 0, 54, 0, 84, 85, 86, 87, 88, 89, 90, +- 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, +- 0, 0, 0, 31, 0, 0, 0, 0, 113, 94, +- 0, 0, 0, 0, 0, 95, 0, 0, 0, 114, +- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, +- 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, +- 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, +- 80, 81, 82, 83, 0, 50, 51, 52, 9, 0, +- 0, 53, 0, 0, 0, 0, 54, 0, 84, 85, +- 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, +- 0, 0, 55, 56, 0, 0, 0, 0, 31, 0, +- 0, 0, 0, 93, 94, 0, 0, 0, 0, 0, +- 95, 0, 0, 0, 114, 57, 58, 59, 60, 61, +- 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, +- 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, +- 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, +- 281, 51, 52, 0, 0, 0, 282, 0, 0, 0, +- 0, 283, 0, 84, 85, 86, 87, 88, 89, 90, +- 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, +- 0, 0, 0, 31, 0, 0, 0, 0, 291, 94, +- 0, 0, 0, 0, 0, 95, 0, 0, 0, 114, +- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, +- 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, +- 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, +- 80, 81, 82, 83, 0, 50, 51, 52, 0, 0, +- 0, 53, 0, 0, 0, 0, 54, 0, 84, 85, +- 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, +- 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, +- 0, 0, 284, 285, 94, 0, 0, 0, 0, 0, +- 95, 0, 0, 0, 96, 57, 58, 59, 60, 61, +- 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, +- 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, +- 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, +- 50, 51, 52, 0, 0, 0, 53, 0, 0, 0, +- 0, 54, 0, 84, 85, 86, 87, 88, 89, 90, +- 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 113, 94, +- 0, 0, 0, 0, 0, 95, 447, 0, 0, 96, +- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, +- 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, +- 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, +- 80, 81, 82, 83, 0, 50, 51, 52, 0, 0, +- 0, 53, 0, 0, 0, 0, 54, 0, 84, 85, +- 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, +- 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 113, 94, 0, 0, 0, 0, 0, +- 95, 0, 0, 0, 96, 57, 58, 59, 60, 61, +- 62, 63, 64, 65, 66, 67, 68, 0, 0, 0, +- 0, 0, 69, 70, 71, 72, 73, 74, 75, 76, +- 77, 78, 79, 0, 0, 80, 81, 82, 83, 0, +- 50, 51, 52, 0, 0, 0, 53, 0, 0, 0, +- 0, 54, 0, 84, 85, 86, 87, 88, 89, 90, +- 91, 92, 0, 0, 0, 0, 0, 55, 56, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 93, 94, +- 0, 0, 0, 0, 0, 95, 0, 0, 0, 96, +- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, +- 67, 68, 0, 0, 0, 0, 0, 69, 70, 71, +- 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, +- 80, 81, 82, 83, 0, 0, 50, 51, 52, 0, +- 0, 0, 53, 0, 0, 0, 0, 54, 84, 85, +- 86, 87, 88, 89, 90, 91, 92, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 291, 94, 0, 0, 0, 0, 0, +- 95, -205, 0, 0, 96, 0, 57, 58, 59, 60, +- 61, 62, 63, 64, 65, 66, 67, 68, 0, 0, +- 0, 0, 0, 69, 70, 71, 72, 73, 74, 75, +- 76, 77, 78, 79, 0, 0, 80, 81, 82, 83, +- 0, 0, 50, 51, 52, 0, 0, 0, 53, 0, +- 0, 0, 0, 54, 84, 85, 86, 87, 88, 89, +- 90, 91, 92, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, +- 94, 0, 0, 0, 0, 0, 95, -204, 0, 0, +- 96, 0, 57, 58, 59, 60, 61, 62, 63, 64, +- 65, 66, 67, 68, 0, 0, 0, 0, 0, 69, +- 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, +- 0, 0, 80, 81, 82, 83, 0, 50, 51, 52, +- 0, 0, 0, 53, 0, 0, 0, 0, 54, 0, +- 84, 85, 86, 87, 88, 89, 90, 91, 92, 0, +- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 113, 94, 0, 0, 0, +- 0, 0, 95, 0, 0, 0, 96, 57, 58, 59, +- 60, 61, 62, 63, 64, 65, 66, 67, 68, 0, +- 0, 0, 0, 0, 69, 70, 71, 72, 73, 74, +- 75, 76, 77, 78, 79, 0, 0, 80, 81, 82, +- 83, 55, 56, 0, 0, 0, 0, 0, 0, 0, +- 0, 0, 0, 0, 0, 84, 85, 86, 87, 88, +- 89, 90, 91, 92, 0, 58, 59, 60, 61, 62, +- 63, 64, 65, 66, 67, 68, 55, 56, 0, 0, +- 113, 94, 0, 0, 0, 0, 0, 95, 0, 0, +- 0, 96, 0, 0, 80, 81, 82, 83, 0, 0, +- 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, +- 68, 0, 84, 85, 86, 87, 88, 89, 90, 91, +- 92, 0, 0, 0, 0, 232, 0, 0, 233, 80, +- 81, 82, 83, 0, 0, 232, 381, 0, 233, 0, +- 0, 0, 0, 0, 0, 0, 0, 84, 85, 86, +- 87, 88, 89, 90, 91, 92, 259, 260, 236, 237, +- 238, 239, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 284, 234, 235, 236, 237, 238, 239, 0, 0, +- 0, 0, 259, 260, 236, 237, 238, 239, 0, 0, +- 240, 241, 242, 243, 244, 245, 246, 247, 0, 248, +- 0, 0, 0, 0, 0, 0, 240, 241, 242, 243, +- 244, 245, 246, 247, 0, 248, 240, 241, 242, 243, +- 244, 245, 246, 247, 0, 248, 58, 59, 60, 61, +- 62, 63, 64, 65, 66, 67, 68, 58, 59, 60, +- 61, 62, 63, 64, 65, 66, 67, 68, 0, 0, +- 0, 0, 0, 0, 0, 80, 81, 82, 83, 0, +- 0, 0, 0, 0, 0, 0, 80, 81, 82, 83, +- 0, 0, 0, 84, 85, 86, 87, 88, 89, 90, +- 91, 92, 0, 0, 84, 85, 86, 87, 88, 89, +- 90, 91, 92, 0, 0, 0, 0, 216, 259, 260, +- 236, 237, 238, 239, 0, 0, 0, 234, 235, 236, +- 237, 238, 239, 0, 0, 0, 234, 0, 236, 237, +- 238, 239, 0, 0, 0, 259, 0, 236, 237, 238, +- 239, 0, 0, 241, 242, 243, 244, 245, 246, 247, +- 0, 248, 241, 242, 243, 244, 245, 246, 247, 0, +- 248, 241, 242, 243, 244, 245, 246, 247, 0, 248, +- 241, 242, 243, 244, 245, 246, 247, 0, 248 +-}; +- +-static const yytype_int16 yycheck[] = +-{ +- 26, 128, 106, 52, 30, 52, 32, 4, 108, 4, +- 129, 114, 0, 3, 40, 6, 0, 140, 141, 9, +- 0, 97, 132, 133, 14, 139, 145, 3, 0, 6, +- 26, 26, 139, 9, 140, 145, 32, 32, 14, 3, +- 4, 28, 281, 141, 171, 40, 285, 35, 124, 93, +- 4, 30, 31, 4, 104, 43, 126, 44, 48, 132, +- 133, 94, 134, 135, 136, 6, 138, 93, 82, 95, +- 96, 97, 145, 14, 15, 16, 17, 18, 19, 20, +- 140, 22, 8, 132, 133, 132, 133, 26, 114, 132, +- 133, 82, 126, 32, 95, 96, 146, 93, 124, 97, +- 98, 97, 97, 147, 131, 132, 133, 94, 126, 135, +- 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, +- 146, 147, 101, 102, 150, 151, 152, 122, 124, 124, +- 230, 130, 129, 128, 126, 161, 162, 127, 377, 378, +- 166, 167, 125, 126, 121, 171, 140, 143, 144, 145, +- 146, 127, 255, 256, 93, 139, 259, 260, 97, 143, +- 144, 131, 132, 133, 126, 209, 210, 139, 163, 164, +- 165, 143, 144, 126, 413, 171, 171, 126, 282, 283, +- 30, 31, 37, 209, 210, 124, 173, 128, 132, 133, +- 290, 126, 93, 180, 181, 182, 183, 184, 185, 186, +- 187, 188, 189, 190, 143, 144, 145, 146, 234, 235, +- 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, +- 246, 247, 248, 249, 250, 251, 6, 126, 126, 255, +- 256, 281, 171, 259, 260, 285, 129, 287, 126, 132, +- 133, 285, 143, 144, 145, 146, 129, 291, 126, 132, +- 133, 101, 102, 249, 250, 6, 4, 129, 8, 285, +- 132, 133, 257, 258, 6, 291, 145, 130, 145, 264, +- 171, 10, 138, 15, 16, 17, 18, 19, 20, 3, +- 22, 125, 144, 410, 49, 329, 330, 144, 8, 285, +- 15, 16, 17, 18, 19, 20, 143, 22, 3, 8, +- 145, 129, 328, 329, 330, 145, 145, 333, 334, 145, +- 249, 250, 145, 129, 129, 95, 96, 97, 98, 99, +- 100, 65, 66, 67, 68, 69, 145, 377, 378, 50, +- 8, 145, 328, 145, 95, 129, 3, 333, 334, 111, +- 145, 121, 145, 51, 6, 145, 285, 145, 249, 250, +- 130, 131, 132, 133, 134, 135, 136, 145, 138, 145, +- 92, 145, 8, 413, 35, 171, 32, 65, 66, 67, +- 68, 69, 203, 415, -1, -1, 33, -1, 404, 405, +- 406, -1, 408, -1, 285, -1, 128, -1, -1, 328, +- -1, -1, -1, -1, 333, 334, 36, -1, 424, 425, +- -1, 145, 389, 128, -1, -1, 393, 394, 404, 405, +- -1, 97, 98, 99, 100, 410, 442, -1, -1, -1, +- -1, 447, 65, 66, 67, 68, 69, 328, 424, 425, +- -1, -1, 333, 334, 132, 133, -1, -1, 95, 96, +- 97, 98, 99, 100, 130, 131, 132, 133, 134, 135, +- 136, -1, 138, -1, -1, 95, 96, 97, 98, 99, +- 100, 3, 4, 5, 6, 404, 405, 9, -1, -1, +- -1, -1, 14, 130, 131, 132, 133, 134, 135, 136, +- -1, 138, -1, -1, -1, 424, 425, -1, 30, 31, +- 130, 131, 132, 133, 134, 135, 136, -1, 138, -1, +- -1, -1, -1, 404, 405, -1, -1, -1, -1, -1, +- -1, 53, 54, 55, 56, 57, 58, 59, 60, 61, +- 62, 63, 64, 424, 425, -1, -1, -1, 70, 71, +- 72, 73, 74, 75, 76, 77, 78, 79, 80, 99, +- 100, 83, 84, 85, 86, 132, 133, 134, 135, 136, +- -1, 138, -1, -1, -1, -1, -1, -1, -1, 101, +- 102, 103, 104, 105, 106, 107, 108, 109, -1, -1, +- 130, 131, 132, 133, 134, 135, 136, -1, 138, 121, +- -1, -1, -1, -1, 126, 127, -1, -1, -1, -1, +- -1, 133, -1, -1, -1, 137, 3, 4, 5, 6, +- 7, -1, 9, 145, -1, -1, -1, 14, 15, 16, +- 17, 18, 19, 20, 21, 22, -1, -1, 25, -1, +- -1, 28, 29, 30, 31, -1, -1, -1, -1, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +- -1, -1, -1, -1, -1, -1, 53, 54, 55, 56, +- 57, 58, 59, 60, 61, 62, 63, 64, -1, -1, +- -1, -1, -1, 70, 71, 72, 73, 74, 75, 76, +- 77, 78, 79, 80, 81, -1, 83, 84, 85, 86, +- 87, 88, -1, -1, 91, -1, 93, -1, -1, -1, +- -1, -1, -1, -1, 101, 102, 103, 104, 105, 106, +- 107, 108, 109, 110, -1, 112, -1, -1, -1, -1, +- -1, -1, -1, -1, 121, 122, -1, -1, -1, 126, +- 127, 128, -1, -1, 3, 4, 133, 6, 7, -1, +- 137, -1, -1, -1, -1, 142, 15, 16, 17, 18, +- 19, 20, 21, 22, -1, -1, 25, -1, -1, 28, +- 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, +- 3, 4, -1, 6, 7, -1, -1, -1, -1, -1, +- -1, -1, 15, 16, 17, 18, 19, 20, 21, 22, +- -1, -1, 25, -1, -1, 28, 29, 30, 31, 95, +- 96, 97, 98, 99, 100, -1, -1, -1, -1, -1, +- -1, -1, 81, -1, -1, -1, -1, -1, 87, 88, +- -1, -1, 91, -1, 93, -1, -1, -1, -1, -1, +- -1, -1, -1, 129, 130, 131, 132, 133, 134, 135, +- 136, 110, 138, 112, -1, -1, -1, -1, 81, -1, +- -1, -1, 121, 122, 87, 88, -1, -1, 91, 128, +- 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, +- 139, -1, -1, 142, -1, -1, -1, 110, -1, 112, +- -1, -1, -1, -1, -1, -1, -1, -1, 121, 122, +- 3, 4, 5, 6, -1, 128, 9, -1, 11, 12, +- 13, 14, -1, -1, -1, -1, -1, -1, -1, 142, +- 23, 24, -1, 26, 27, 28, 29, 30, 31, 32, +- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, +- 43, 44, 45, 46, 47, -1, -1, -1, -1, -1, +- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +- 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, +- 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, +- 83, 84, 85, 86, -1, -1, 89, 90, -1, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, 101, 102, +- 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, +- 113, 114, 115, 116, 117, 118, 119, 120, 121, -1, +- -1, -1, -1, 126, 127, 3, 4, 5, 6, -1, +- 133, 9, -1, -1, 137, -1, 14, -1, -1, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +- -1, -1, 30, 31, -1, -1, -1, -1, -1, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +- -1, -1, -1, -1, -1, 53, 54, 55, 56, 57, +- 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, +- -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, +- 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, +- 3, 4, 5, 6, -1, -1, 9, -1, -1, -1, +- -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, +- 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, +- -1, -1, -1, 121, -1, -1, -1, 125, 126, 127, +- -1, -1, -1, -1, -1, 133, -1, -1, -1, 137, +- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +- 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, +- 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, +- 83, 84, 85, 86, -1, 3, 4, 5, 6, -1, +- -1, 9, -1, -1, -1, -1, 14, -1, 101, 102, +- 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, +- -1, -1, 30, 31, -1, -1, -1, -1, 121, -1, +- -1, -1, -1, 126, 127, -1, -1, -1, -1, -1, +- 133, -1, -1, -1, 137, 53, 54, 55, 56, 57, +- 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, +- -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, +- 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, +- 3, 4, 5, 6, -1, -1, 9, -1, -1, -1, +- -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, +- 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, +- -1, -1, -1, 121, -1, -1, -1, -1, 126, 127, +- -1, -1, -1, -1, -1, 133, -1, -1, -1, 137, +- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +- 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, +- 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, +- 83, 84, 85, 86, -1, 3, 4, 5, 6, -1, +- -1, 9, -1, -1, -1, -1, 14, -1, 101, 102, +- 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, +- -1, -1, 30, 31, -1, -1, -1, -1, 121, -1, +- -1, -1, -1, 126, 127, -1, -1, -1, -1, -1, +- 133, -1, -1, -1, 137, 53, 54, 55, 56, 57, +- 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, +- -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, +- 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, +- 3, 4, 5, -1, -1, -1, 9, -1, -1, -1, +- -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, +- 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, +- -1, -1, -1, 121, -1, -1, -1, -1, 126, 127, +- -1, -1, -1, -1, -1, 133, -1, -1, -1, 137, +- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +- 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, +- 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, +- 83, 84, 85, 86, -1, 3, 4, 5, -1, -1, +- -1, 9, -1, -1, -1, -1, 14, -1, 101, 102, +- 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, +- -1, -1, 30, 31, -1, -1, -1, -1, -1, -1, +- -1, -1, 125, 126, 127, -1, -1, -1, -1, -1, +- 133, -1, -1, -1, 137, 53, 54, 55, 56, 57, +- 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, +- -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, +- 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, +- 3, 4, 5, -1, -1, -1, 9, -1, -1, -1, +- -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, +- 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, 126, 127, +- -1, -1, -1, -1, -1, 133, 134, -1, -1, 137, +- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +- 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, +- 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, +- 83, 84, 85, 86, -1, 3, 4, 5, -1, -1, +- -1, 9, -1, -1, -1, -1, 14, -1, 101, 102, +- 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, +- -1, -1, 30, 31, -1, -1, -1, -1, -1, -1, +- -1, -1, -1, 126, 127, -1, -1, -1, -1, -1, +- 133, -1, -1, -1, 137, 53, 54, 55, 56, 57, +- 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, +- -1, -1, 70, 71, 72, 73, 74, 75, 76, 77, +- 78, 79, 80, -1, -1, 83, 84, 85, 86, -1, +- 3, 4, 5, -1, -1, -1, 9, -1, -1, -1, +- -1, 14, -1, 101, 102, 103, 104, 105, 106, 107, +- 108, 109, -1, -1, -1, -1, -1, 30, 31, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, 126, 127, +- -1, -1, -1, -1, -1, 133, -1, -1, -1, 137, +- 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, +- 63, 64, -1, -1, -1, -1, -1, 70, 71, 72, +- 73, 74, 75, 76, 77, 78, 79, 80, -1, -1, +- 83, 84, 85, 86, -1, -1, 3, 4, 5, -1, +- -1, -1, 9, -1, -1, -1, -1, 14, 101, 102, +- 103, 104, 105, 106, 107, 108, 109, -1, -1, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +- -1, -1, -1, 126, 127, -1, -1, -1, -1, -1, +- 133, 48, -1, -1, 137, -1, 53, 54, 55, 56, +- 57, 58, 59, 60, 61, 62, 63, 64, -1, -1, +- -1, -1, -1, 70, 71, 72, 73, 74, 75, 76, +- 77, 78, 79, 80, -1, -1, 83, 84, 85, 86, +- -1, -1, 3, 4, 5, -1, -1, -1, 9, -1, +- -1, -1, -1, 14, 101, 102, 103, 104, 105, 106, +- 107, 108, 109, -1, -1, -1, -1, -1, -1, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, -1, 126, +- 127, -1, -1, -1, -1, -1, 133, 48, -1, -1, +- 137, -1, 53, 54, 55, 56, 57, 58, 59, 60, +- 61, 62, 63, 64, -1, -1, -1, -1, -1, 70, +- 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, +- -1, -1, 83, 84, 85, 86, -1, 3, 4, 5, +- -1, -1, -1, 9, -1, -1, -1, -1, 14, -1, +- 101, 102, 103, 104, 105, 106, 107, 108, 109, -1, +- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +- -1, -1, -1, -1, -1, 126, 127, -1, -1, -1, +- -1, -1, 133, -1, -1, -1, 137, 53, 54, 55, +- 56, 57, 58, 59, 60, 61, 62, 63, 64, -1, +- -1, -1, -1, -1, 70, 71, 72, 73, 74, 75, +- 76, 77, 78, 79, 80, -1, -1, 83, 84, 85, +- 86, 30, 31, -1, -1, -1, -1, -1, -1, -1, +- -1, -1, -1, -1, -1, 101, 102, 103, 104, 105, +- 106, 107, 108, 109, -1, 54, 55, 56, 57, 58, +- 59, 60, 61, 62, 63, 64, 30, 31, -1, -1, +- 126, 127, -1, -1, -1, -1, -1, 133, -1, -1, +- -1, 137, -1, -1, 83, 84, 85, 86, -1, -1, +- 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, +- 64, -1, 101, 102, 103, 104, 105, 106, 107, 108, +- 109, -1, -1, -1, -1, 48, -1, -1, 51, 83, +- 84, 85, 86, -1, -1, 48, 125, -1, 51, -1, +- -1, -1, -1, -1, -1, -1, -1, 101, 102, 103, +- 104, 105, 106, 107, 108, 109, 95, 96, 97, 98, +- 99, 100, -1, -1, -1, -1, -1, -1, -1, -1, +- -1, 125, 95, 96, 97, 98, 99, 100, -1, -1, +- -1, -1, 95, 96, 97, 98, 99, 100, -1, -1, +- 129, 130, 131, 132, 133, 134, 135, 136, -1, 138, +- -1, -1, -1, -1, -1, -1, 129, 130, 131, 132, +- 133, 134, 135, 136, -1, 138, 129, 130, 131, 132, +- 133, 134, 135, 136, -1, 138, 54, 55, 56, 57, +- 58, 59, 60, 61, 62, 63, 64, 54, 55, 56, +- 57, 58, 59, 60, 61, 62, 63, 64, -1, -1, +- -1, -1, -1, -1, -1, 83, 84, 85, 86, -1, +- -1, -1, -1, -1, -1, -1, 83, 84, 85, 86, +- -1, -1, -1, 101, 102, 103, 104, 105, 106, 107, +- 108, 109, -1, -1, 101, 102, 103, 104, 105, 106, +- 107, 108, 109, -1, -1, -1, -1, 125, 95, 96, +- 97, 98, 99, 100, -1, -1, -1, 95, 96, 97, +- 98, 99, 100, -1, -1, -1, 95, -1, 97, 98, +- 99, 100, -1, -1, -1, 95, -1, 97, 98, 99, +- 100, -1, -1, 130, 131, 132, 133, 134, 135, 136, +- -1, 138, 130, 131, 132, 133, 134, 135, 136, -1, +- 138, 130, 131, 132, 133, 134, 135, 136, -1, 138, +- 130, 131, 132, 133, 134, 135, 136, -1, 138 +-}; +- +- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = +-{ +- 0, 139, 147, 148, 150, 151, 0, 3, 4, 6, +- 7, 15, 16, 17, 18, 19, 20, 21, 22, 25, +- 28, 29, 30, 31, 81, 87, 88, 91, 93, 110, +- 112, 121, 122, 128, 142, 149, 152, 161, 164, 170, +- 174, 176, 139, 141, 140, 141, 140, 6, 82, 153, +- 3, 4, 5, 9, 14, 30, 31, 53, 54, 55, +- 56, 57, 58, 59, 60, 61, 62, 63, 64, 70, +- 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, +- 83, 84, 85, 86, 101, 102, 103, 104, 105, 106, +- 107, 108, 109, 126, 127, 133, 137, 162, 163, 176, +- 178, 179, 181, 182, 183, 184, 185, 186, 191, 192, +- 193, 194, 4, 126, 137, 167, 168, 176, 182, 192, +- 194, 4, 192, 126, 162, 175, 171, 150, 151, 4, +- 129, 94, 11, 12, 13, 23, 24, 26, 27, 28, +- 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, +- 39, 40, 41, 42, 43, 44, 45, 46, 47, 89, +- 90, 113, 114, 115, 116, 117, 118, 119, 120, 176, +- 192, 150, 167, 140, 3, 4, 160, 82, 156, 8, +- 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, +- 126, 30, 31, 101, 102, 30, 31, 101, 102, 167, +- 178, 181, 182, 192, 194, 167, 192, 192, 163, 132, +- 133, 65, 66, 67, 68, 69, 125, 191, 6, 14, +- 15, 16, 17, 18, 19, 20, 22, 128, 187, 187, +- 48, 183, 48, 51, 95, 96, 97, 98, 99, 100, +- 129, 130, 131, 132, 133, 134, 135, 136, 138, 180, +- 130, 140, 168, 192, 37, 95, 96, 97, 98, 95, +- 96, 176, 6, 148, 150, 148, 170, 4, 159, 192, +- 192, 192, 192, 192, 192, 192, 192, 178, 192, 178, +- 178, 3, 9, 14, 125, 126, 178, 188, 189, 190, +- 191, 126, 181, 192, 192, 192, 192, 192, 192, 176, +- 176, 176, 192, 192, 3, 4, 30, 31, 170, 178, +- 179, 182, 167, 154, 8, 167, 167, 167, 167, 167, +- 167, 167, 167, 167, 145, 167, 167, 145, 129, 132, +- 133, 145, 145, 180, 130, 10, 181, 181, 3, 144, +- 183, 49, 192, 192, 192, 192, 192, 192, 192, 192, +- 192, 192, 192, 192, 192, 192, 192, 178, 178, 192, +- 165, 168, 192, 168, 192, 176, 176, 168, 192, 168, +- 192, 177, 144, 143, 8, 189, 191, 187, 187, 3, +- 189, 125, 191, 181, 192, 8, 157, 145, 145, 129, +- 145, 145, 145, 129, 129, 145, 145, 145, 178, 181, +- 181, 178, 178, 50, 52, 129, 33, 8, 129, 145, +- 172, 189, 189, 129, 3, 155, 111, 166, 167, 167, +- 167, 145, 145, 145, 52, 129, 51, 178, 178, 192, +- 192, 170, 173, 189, 166, 6, 145, 145, 145, 178, +- 178, 131, 36, 169, 145, 145, 131, 134, 192, 92, +- 145, 192, 158, 8 +-}; +- +- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 146, 147, 147, 148, 149, 149, 150, 150, 151, +- 151, 152, 152, 152, 152, 152, 152, 152, 152, 152, +- 152, 153, 152, 152, 154, 155, 152, 156, 157, 152, +- 158, 152, 152, 159, 152, 152, 152, 160, 160, 161, +- 161, 161, 162, 162, 163, 163, 163, 165, 164, 166, +- 166, 167, 167, 168, 168, 168, 168, 168, 168, 168, +- 168, 168, 169, 169, 169, 170, 170, 170, 170, 171, +- 172, 170, 170, 173, 173, 174, 174, 174, 174, 174, +- 174, 174, 174, 174, 174, 174, 175, 174, 174, 174, +- 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +- 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +- 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +- 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, +- 174, 174, 174, 174, 174, 174, 176, 176, 177, 177, +- 178, 178, 178, 179, 179, 179, 179, 179, 179, 179, +- 179, 179, 179, 180, 180, 181, 181, 182, 182, 182, +- 182, 182, 183, 183, 183, 184, 184, 185, 185, 186, +- 186, 187, 187, 187, 187, 187, 187, 187, 187, 187, +- 188, 188, 189, 189, 189, 190, 190, 190, 190, 190, +- 190, 191, 191, 191, 191, 191, 191, 191, 191, 191, +- 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +- 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, +- 191, 191, 191, 192, 192, 193, 194, 194, 194, 194, +- 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, +- 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, +- 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, +- 194 +-}; +- +- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = +-{ +- 0, 2, 1, 1, 3, 1, 3, 0, 1, 1, +- 2, 3, 3, 4, 1, 1, 1, 1, 1, 2, +- 2, 0, 3, 2, 0, 0, 7, 0, 0, 6, +- 0, 10, 1, 0, 4, 1, 1, 1, 1, 2, +- 2, 3, 1, 2, 1, 1, 1, 0, 5, 0, +- 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, +- 3, 2, 0, 2, 3, 1, 4, 4, 4, 0, +- 0, 6, 1, 0, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 2, 3, 0, 4, 3, 3, +- 3, 3, 2, 2, 3, 2, 3, 2, 3, 2, +- 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, +- 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, +- 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 3, 2, 1, 5, 0, 3, +- 1, 1, 3, 1, 3, 5, 3, 5, 5, 5, +- 7, 6, 8, 1, 4, 3, 3, 1, 2, 2, +- 3, 1, 1, 1, 3, 1, 3, 1, 2, 2, +- 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, +- 2, 3, 1, 1, 2, 1, 5, 4, 3, 3, +- 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, +- 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 3, 1, 1, 2, 2, +- 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, +- 3, 4, 4, 6, 4, 4, 4, 6, 6, 4, +- 4, 3, 4, 3, 3, 3, 3, 3, 3, 3, +- 2 +-}; +- +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-#define YYRECOVERING() (!!yyerrstatus) +- +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- YYPOPSTACK (yylen); \ +- yystate = *yyssp; \ +- goto yybackup; \ +- } \ +- else \ +- { \ +- yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (0) +- +-/* Error token number */ +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (0) +- +-/* This macro is provided for backward compatibility. */ +-#ifndef YY_LOCATION_PRINT +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-#endif +- +- +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (0) +- +- +-/*----------------------------------------. +-| Print this symbol's value on YYOUTPUT. | +-`----------------------------------------*/ +- +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-{ +- FILE *yyo = yyoutput; +- YYUSE (yyo); +- if (!yyvaluep) +- return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# endif +- YYUSE (yytype); +-} +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-{ +- YYFPRINTF (yyoutput, "%s %s (", +- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); +- +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); +- YYFPRINTF (yyoutput, ")"); +-} +- +-/*------------------------------------------------------------------. +-| yy_stack_print -- Print the state stack from its BOTTOM up to its | +-| TOP (included). | +-`------------------------------------------------------------------*/ +- +-static void +-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +-{ +- YYFPRINTF (stderr, "Stack now"); +- for (; yybottom <= yytop; yybottom++) +- { +- int yybot = *yybottom; +- YYFPRINTF (stderr, " %d", yybot); +- } +- YYFPRINTF (stderr, "\n"); +-} +- +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (0) +- +- +-/*------------------------------------------------. +-| Report that the YYRULE is going to be reduced. | +-`------------------------------------------------*/ +- +-static void +-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +-{ +- unsigned long int yylno = yyrline[yyrule]; +- int yynrhs = yyr2[yyrule]; +- int yyi; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); +- /* The symbols being reduced. */ +- for (yyi = 0; yyi < yynrhs; yyi++) +- { +- YYFPRINTF (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, +- yystos[yyssp[yyi + 1 - yynrhs]], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); +- YYFPRINTF (stderr, "\n"); +- } +-} +- +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyssp, yyvsp, Rule); \ +-} while (0) +- +-/* Nonzero means print parse trace. It is left uninitialized so that +- multiple parsers can coexist. */ +-int yydebug; +-#else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +-# define YY_STACK_PRINT(Bottom, Top) +-# define YY_REDUCE_PRINT(Rule) +-#endif /* !YYDEBUG */ +- +- +-/* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH +-# define YYINITDEPTH 200 +-#endif +- +-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +- if the built-in stack extension method is used). +- +- Do not make this value too large; the results are undefined if +- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +- evaluated with infinite-precision integer arithmetic. */ +- +-#ifndef YYMAXDEPTH +-# define YYMAXDEPTH 10000 +-#endif +- +- +-#if YYERROR_VERBOSE +- +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else +-/* Return the length of YYSTR. */ +-static YYSIZE_T +-yystrlen (const char *yystr) +-{ +- YYSIZE_T yylen; +- for (yylen = 0; yystr[yylen]; yylen++) +- continue; +- return yylen; +-} +-# endif +-# endif +- +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else +-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +- YYDEST. */ +-static char * +-yystpcpy (char *yydest, const char *yysrc) +-{ +- char *yyd = yydest; +- const char *yys = yysrc; +- +- while ((*yyd++ = *yys++) != '\0') +- continue; +- +- return yyd - 1; +-} +-# endif +-# endif +- +-# ifndef yytnamerr +-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +- quotes and backslashes, so that it's suitable for yyerror. The +- heuristic is that double-quoting is unnecessary unless the string +- contains an apostrophe, a comma, or backslash (other than +- backslash-backslash). YYSTR is taken from yytname. If YYRES is +- null, do not copy; instead, return the length of what the result +- would have been. */ +-static YYSIZE_T +-yytnamerr (char *yyres, const char *yystr) +-{ +- if (*yystr == '"') +- { +- YYSIZE_T yyn = 0; +- char const *yyp = yystr; +- +- for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } +- do_not_strip_quotes: ; +- } +- +- if (! yyres) +- return yystrlen (yystr); +- +- return yystpcpy (yyres, yystr) - yyres; +-} +-# endif +- +-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message +- about the unexpected token YYTOKEN for the state stack whose top is +- YYSSP. +- +- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is +- not large enough to hold the message. In that case, also set +- *YYMSG_ALLOC to the required number of bytes. Return 2 if the +- required number of bytes is too large to store. */ +-static int +-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, +- yytype_int16 *yyssp, int yytoken) +-{ +- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); +- YYSIZE_T yysize = yysize0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- /* Internationalized format string. */ +- const char *yyformat = YY_NULLPTR; +- /* Arguments of yyformat. */ +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- /* Number of reported tokens (one for the "unexpected", one per +- "expected"). */ +- int yycount = 0; +- +- /* There are many possibilities here to consider: +- - If this state is a consistent state with a default action, then +- the only way this function was invoked is if the default action +- is an error action. In that case, don't check for expected +- tokens because there are none. +- - The only way there can be no lookahead present (in yychar) is if +- this state is a consistent state with a default action. Thus, +- detecting the absence of a lookahead is sufficient to determine +- that there is no unexpected or expected token to report. In that +- case, just report a simple "syntax error". +- - Don't assume there isn't a lookahead just because this state is a +- consistent state with a default action. There might have been a +- previous inconsistent state, consistent state with a non-default +- action, or user semantic action that manipulated yychar. +- - Of course, the expected token list depends on states to have +- correct lookahead information, and it depends on the parser not +- to perform extra reductions after fetching a lookahead from the +- scanner and before detecting a syntax error. Thus, state merging +- (from LALR or IELR) and default reductions corrupt the expected +- token list. However, the list is correct for canonical LR with +- one exception: it will still contain any token that will not be +- accepted due to an error action in a later state. +- */ +- if (yytoken != YYEMPTY) +- { +- int yyn = yypact[*yyssp]; +- yyarg[yycount++] = yytname[yytoken]; +- if (!yypact_value_is_default (yyn)) +- { +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. In other words, skip the first -YYN actions for +- this state because they are default actions. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yyx; +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR +- && !yytable_value_is_error (yytable[yyx + yyn])) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- { +- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); +- if (! (yysize <= yysize1 +- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } +- } +- } +- } +- +- switch (yycount) +- { +-# define YYCASE_(N, S) \ +- case N: \ +- yyformat = S; \ +- break +- YYCASE_(0, YY_("syntax error")); +- YYCASE_(1, YY_("syntax error, unexpected %s")); +- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); +- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); +- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); +- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +-# undef YYCASE_ +- } +- +- { +- YYSIZE_T yysize1 = yysize + yystrlen (yyformat); +- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } +- +- if (*yymsg_alloc < yysize) +- { +- *yymsg_alloc = 2 * yysize; +- if (! (yysize <= *yymsg_alloc +- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) +- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; +- return 1; +- } +- +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- { +- char *yyp = *yymsg; +- int yyi = 0; +- while ((*yyp = *yyformat) != '\0') +- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyformat += 2; +- } +- else +- { +- yyp++; +- yyformat++; +- } +- } +- return 0; +-} +-#endif /* YYERROR_VERBOSE */ +- +-/*-----------------------------------------------. +-| Release the memory associated to this symbol. | +-`-----------------------------------------------*/ +- +-static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-{ +- YYUSE (yyvaluep); +- if (!yymsg) +- yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +- +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- YYUSE (yytype); +- YY_IGNORE_MAYBE_UNINITIALIZED_END +-} +- +- +- +- +-/* The lookahead symbol. */ +-int yychar; +- +-/* The semantic value of the lookahead symbol. */ +-YYSTYPE yylval; +-/* Number of syntax errors so far. */ +-int yynerrs; +- +- +-/*----------. +-| yyparse. | +-`----------*/ +- +-int +-yyparse (void) +-{ +- int yystate; +- /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- +- /* The stacks and their tools: +- 'yyss': related to states. +- 'yyvs': related to semantic values. +- +- Refer to the stacks through separate pointers, to allow yyoverflow +- to reallocate them elsewhere. */ +- +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss; +- yytype_int16 *yyssp; +- +- /* The semantic value stack. */ +- YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs; +- YYSTYPE *yyvsp; +- +- YYSIZE_T yystacksize; +- +- int yyn; +- int yyresult; +- /* Lookahead token as an internal (translated) token number. */ +- int yytoken = 0; +- /* The variables used to return semantic value and location from the +- action routines. */ +- YYSTYPE yyval; +- +-#if YYERROR_VERBOSE +- /* Buffer for error messages, and its allocated size. */ +- char yymsgbuf[128]; +- char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif +- +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) +- +- /* The number of symbols on the RHS of the reduced rule. +- Keep to zero when no symbol should be popped. */ +- int yylen = 0; +- +- yyssp = yyss = yyssa; +- yyvsp = yyvs = yyvsa; +- yystacksize = YYINITDEPTH; +- +- YYDPRINTF ((stderr, "Starting parse\n")); +- +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; +- yychar = YYEMPTY; /* Cause a token to be read. */ +- goto yysetstate; +- +-/*------------------------------------------------------------. +-| yynewstate -- Push a new state, which is found in yystate. | +-`------------------------------------------------------------*/ +- yynewstate: +- /* In all cases, when you get here, the value and location stacks +- have just been pushed. So pushing a state here evens the stacks. */ +- yyssp++; +- +- yysetstate: +- *yyssp = yystate; +- +- if (yyss + yystacksize - 1 <= yyssp) +- { +- /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = yyssp - yyss + 1; +- +-#ifdef yyoverflow +- { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; +- } +-#else /* no yyoverflow */ +-# ifndef YYSTACK_RELOCATE +- goto yyexhaustedlab; +-# else +- /* Extend the stack our own way. */ +- if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; +- yystacksize *= 2; +- if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; +- +- { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss_alloc, yyss); +- YYSTACK_RELOCATE (yyvs_alloc, yyvs); +-# undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); +- } +-# endif +-#endif /* no yyoverflow */ +- +- yyssp = yyss + yysize - 1; +- yyvsp = yyvs + yysize - 1; +- +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); +- +- if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; +- } +- +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +- +- if (yystate == YYFINAL) +- YYACCEPT; +- +- goto yybackup; +- +-/*-----------. +-| yybackup. | +-`-----------*/ +-yybackup: +- +- /* Do appropriate processing given the current state. Read a +- lookahead token if we need one and don't already have one. */ +- +- /* First try to decide what to do without reference to lookahead token. */ +- yyn = yypact[yystate]; +- if (yypact_value_is_default (yyn)) +- goto yydefault; +- +- /* Not known => get a lookahead token if don't already have one. */ +- +- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ +- if (yychar == YYEMPTY) +- { +- YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = yylex (); +- } +- +- if (yychar <= YYEOF) +- { +- yychar = yytoken = YYEOF; +- YYDPRINTF ((stderr, "Now at end of input.\n")); +- } +- else +- { +- yytoken = YYTRANSLATE (yychar); +- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +- } +- +- /* If the proper action on seeing token YYTOKEN is to reduce or to +- detect an error, take that action. */ +- yyn += yytoken; +- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +- goto yydefault; +- yyn = yytable[yyn]; +- if (yyn <= 0) +- { +- if (yytable_value_is_error (yyn)) +- goto yyerrlab; +- yyn = -yyn; +- goto yyreduce; +- } +- +- /* Count tokens shifted since error; after three, turn off error +- status. */ +- if (yyerrstatus) +- yyerrstatus--; +- +- /* Shift the lookahead token. */ +- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token. */ +- yychar = YYEMPTY; +- +- yystate = yyn; +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END +- +- goto yynewstate; +- +- +-/*-----------------------------------------------------------. +-| yydefault -- do the default action for the current state. | +-`-----------------------------------------------------------*/ +-yydefault: +- yyn = yydefact[yystate]; +- if (yyn == 0) +- goto yyerrlab; +- goto yyreduce; +- +- +-/*-----------------------------. +-| yyreduce -- Do a reduction. | +-`-----------------------------*/ +-yyreduce: +- /* yyn is the number of a rule to reduce with. */ +- yylen = yyr2[yyn]; +- +- /* If YYLEN is nonzero, implement the default value of the action: +- '$$ = $1'. +- +- Otherwise, the following line sets YYVAL to garbage. +- This behavior is undocumented and Bison +- users should not rely upon it. Assigning to YYVAL +- unconditionally makes the parser a bit smaller, and it avoids a +- GCC warning that YYVAL may be used uninitialized. */ +- yyval = yyvsp[1-yylen]; +- +- +- YY_REDUCE_PRINT (yyn); +- switch (yyn) +- { +- case 3: +-#line 277 "pic.y" /* yacc.c:1646 */ +- { +- if (olist.head) +- print_picture(olist.head); +- } +-#line 2260 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 4: +-#line 286 "pic.y" /* yacc.c:1646 */ +- { (yyval.pl) = (yyvsp[-1].pl); } +-#line 2266 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 5: +-#line 291 "pic.y" /* yacc.c:1646 */ +- { (yyval.pl) = (yyvsp[0].pl); } +-#line 2272 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 6: +-#line 293 "pic.y" /* yacc.c:1646 */ +- { (yyval.pl) = (yyvsp[-2].pl); } +-#line 2278 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 11: +-#line 308 "pic.y" /* yacc.c:1646 */ +- { +- a_delete graphname; +- graphname = new char[strlen((yyvsp[0].str)) + 1]; +- strcpy(graphname, (yyvsp[0].str)); +- a_delete (yyvsp[0].str); +- } +-#line 2289 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 12: +-#line 316 "pic.y" /* yacc.c:1646 */ +- { +- define_variable((yyvsp[-2].str), (yyvsp[0].x)); +- a_delete (yyvsp[-2].str); +- } +-#line 2298 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 13: +-#line 321 "pic.y" /* yacc.c:1646 */ +- { +- place *p = lookup_label((yyvsp[-3].str)); +- if (!p) { +- lex_error("variable `%1' not defined", (yyvsp[-3].str)); +- YYABORT; +- } +- p->obj = 0; +- p->x = (yyvsp[0].x); +- p->y = 0.0; +- a_delete (yyvsp[-3].str); +- } +-#line 2314 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 14: +-#line 333 "pic.y" /* yacc.c:1646 */ +- { current_direction = UP_DIRECTION; } +-#line 2320 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 15: +-#line 335 "pic.y" /* yacc.c:1646 */ +- { current_direction = DOWN_DIRECTION; } +-#line 2326 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 16: +-#line 337 "pic.y" /* yacc.c:1646 */ +- { current_direction = LEFT_DIRECTION; } +-#line 2332 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 17: +-#line 339 "pic.y" /* yacc.c:1646 */ +- { current_direction = RIGHT_DIRECTION; } +-#line 2338 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 18: +-#line 341 "pic.y" /* yacc.c:1646 */ +- { +- olist.append(make_command_object((yyvsp[0].lstr).str, (yyvsp[0].lstr).filename, +- (yyvsp[0].lstr).lineno)); +- } +-#line 2347 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 19: +-#line 346 "pic.y" /* yacc.c:1646 */ +- { +- olist.append(make_command_object((yyvsp[0].lstr).str, (yyvsp[0].lstr).filename, +- (yyvsp[0].lstr).lineno)); +- } +-#line 2356 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 20: +-#line 351 "pic.y" /* yacc.c:1646 */ +- { +- fprintf(stderr, "%s\n", (yyvsp[0].lstr).str); +- a_delete (yyvsp[0].lstr).str; +- fflush(stderr); +- } +-#line 2366 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 21: +-#line 357 "pic.y" /* yacc.c:1646 */ +- { delim_flag = 1; } +-#line 2372 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 22: +-#line 359 "pic.y" /* yacc.c:1646 */ +- { +- delim_flag = 0; +- if (safer_flag) +- lex_error("unsafe to run command `%1'", (yyvsp[0].str)); +- else +- system((yyvsp[0].str)); +- a_delete (yyvsp[0].str); +- } +-#line 2385 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 23: +-#line 368 "pic.y" /* yacc.c:1646 */ +- { +- if (yychar < 0) +- do_lookahead(); +- do_copy((yyvsp[0].lstr).str); +- // do not delete the filename +- } +-#line 2396 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 24: +-#line 375 "pic.y" /* yacc.c:1646 */ +- { delim_flag = 2; } +-#line 2402 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 25: +-#line 377 "pic.y" /* yacc.c:1646 */ +- { delim_flag = 0; } +-#line 2408 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 26: +-#line 379 "pic.y" /* yacc.c:1646 */ +- { +- if (yychar < 0) +- do_lookahead(); +- copy_file_thru((yyvsp[-5].lstr).str, (yyvsp[-2].str), (yyvsp[0].str)); +- // do not delete the filename +- a_delete (yyvsp[-2].str); +- a_delete (yyvsp[0].str); +- } +-#line 2421 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 27: +-#line 388 "pic.y" /* yacc.c:1646 */ +- { delim_flag = 2; } +-#line 2427 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 28: +-#line 390 "pic.y" /* yacc.c:1646 */ +- { delim_flag = 0; } +-#line 2433 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 29: +-#line 392 "pic.y" /* yacc.c:1646 */ +- { +- if (yychar < 0) +- do_lookahead(); +- copy_rest_thru((yyvsp[-2].str), (yyvsp[0].str)); +- a_delete (yyvsp[-2].str); +- a_delete (yyvsp[0].str); +- } +-#line 2445 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 30: +-#line 400 "pic.y" /* yacc.c:1646 */ +- { delim_flag = 1; } +-#line 2451 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 31: +-#line 402 "pic.y" /* yacc.c:1646 */ +- { +- delim_flag = 0; +- if (yychar < 0) +- do_lookahead(); +- do_for((yyvsp[-8].str), (yyvsp[-6].x), (yyvsp[-4].x), (yyvsp[-3].by).is_multiplicative, (yyvsp[-3].by).val, (yyvsp[0].str)); +- } +-#line 2462 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 32: +-#line 409 "pic.y" /* yacc.c:1646 */ +- { +- if (yychar < 0) +- do_lookahead(); +- if ((yyvsp[0].if_data).x != 0.0) +- push_body((yyvsp[0].if_data).body); +- a_delete (yyvsp[0].if_data).body; +- } +-#line 2474 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 33: +-#line 417 "pic.y" /* yacc.c:1646 */ +- { delim_flag = 1; } +-#line 2480 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 34: +-#line 419 "pic.y" /* yacc.c:1646 */ +- { +- delim_flag = 0; +- if (yychar < 0) +- do_lookahead(); +- if ((yyvsp[-3].if_data).x != 0.0) +- push_body((yyvsp[-3].if_data).body); +- else +- push_body((yyvsp[0].str)); +- a_delete (yyvsp[-3].if_data).body; +- a_delete (yyvsp[0].str); +- } +-#line 2496 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 36: +-#line 432 "pic.y" /* yacc.c:1646 */ +- { define_variable("scale", 1.0); } +-#line 2502 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 39: +-#line 442 "pic.y" /* yacc.c:1646 */ +- { +- reset((yyvsp[0].str)); +- a_delete (yyvsp[0].str); +- } +-#line 2511 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 40: +-#line 447 "pic.y" /* yacc.c:1646 */ +- { +- reset((yyvsp[0].str)); +- a_delete (yyvsp[0].str); +- } +-#line 2520 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 41: +-#line 452 "pic.y" /* yacc.c:1646 */ +- { +- reset((yyvsp[0].str)); +- a_delete (yyvsp[0].str); +- } +-#line 2529 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 42: +-#line 460 "pic.y" /* yacc.c:1646 */ +- { (yyval.lstr) = (yyvsp[0].lstr); } +-#line 2535 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 43: +-#line 462 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.lstr).str = new char[strlen((yyvsp[-1].lstr).str) + strlen((yyvsp[0].lstr).str) + 1]; +- strcpy((yyval.lstr).str, (yyvsp[-1].lstr).str); +- strcat((yyval.lstr).str, (yyvsp[0].lstr).str); +- a_delete (yyvsp[-1].lstr).str; +- a_delete (yyvsp[0].lstr).str; +- if ((yyvsp[-1].lstr).filename) { +- (yyval.lstr).filename = (yyvsp[-1].lstr).filename; +- (yyval.lstr).lineno = (yyvsp[-1].lstr).lineno; +- } +- else if ((yyvsp[0].lstr).filename) { +- (yyval.lstr).filename = (yyvsp[0].lstr).filename; +- (yyval.lstr).lineno = (yyvsp[0].lstr).lineno; +- } +- } +-#line 2555 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 44: +-#line 481 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.lstr).str = new char[GDIGITS + 1]; +- sprintf((yyval.lstr).str, "%g", (yyvsp[0].x)); +- (yyval.lstr).filename = 0; +- (yyval.lstr).lineno = 0; +- } +-#line 2566 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 45: +-#line 488 "pic.y" /* yacc.c:1646 */ +- { (yyval.lstr) = (yyvsp[0].lstr); } +-#line 2572 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 46: +-#line 490 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.lstr).str = new char[GDIGITS + 2 + GDIGITS + 1]; +- sprintf((yyval.lstr).str, "%g, %g", (yyvsp[0].pair).x, (yyvsp[0].pair).y); +- (yyval.lstr).filename = 0; +- (yyval.lstr).lineno = 0; +- } +-#line 2583 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 47: +-#line 500 "pic.y" /* yacc.c:1646 */ +- { delim_flag = 1; } +-#line 2589 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 48: +-#line 502 "pic.y" /* yacc.c:1646 */ +- { +- delim_flag = 0; +- (yyval.if_data).x = (yyvsp[-3].x); +- (yyval.if_data).body = (yyvsp[0].str); +- } +-#line 2599 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 49: +-#line 511 "pic.y" /* yacc.c:1646 */ +- { (yyval.str) = 0; } +-#line 2605 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 50: +-#line 513 "pic.y" /* yacc.c:1646 */ +- { (yyval.str) = (yyvsp[0].lstr).str; } +-#line 2611 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 51: +-#line 518 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[0].x); } +-#line 2617 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 52: +-#line 520 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[0].x); } +-#line 2623 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 53: +-#line 525 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.x) = strcmp((yyvsp[-2].lstr).str, (yyvsp[0].lstr).str) == 0; +- a_delete (yyvsp[-2].lstr).str; +- a_delete (yyvsp[0].lstr).str; +- } +-#line 2633 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 54: +-#line 531 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.x) = strcmp((yyvsp[-2].lstr).str, (yyvsp[0].lstr).str) != 0; +- a_delete (yyvsp[-2].lstr).str; +- a_delete (yyvsp[0].lstr).str; +- } +-#line 2643 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 55: +-#line 537 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) != 0.0 && (yyvsp[0].x) != 0.0); } +-#line 2649 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 56: +-#line 539 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) != 0.0 && (yyvsp[0].x) != 0.0); } +-#line 2655 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 57: +-#line 541 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) != 0.0 && (yyvsp[0].x) != 0.0); } +-#line 2661 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 58: +-#line 543 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) != 0.0 || (yyvsp[0].x) != 0.0); } +-#line 2667 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 59: +-#line 545 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) != 0.0 || (yyvsp[0].x) != 0.0); } +-#line 2673 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 60: +-#line 547 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) != 0.0 || (yyvsp[0].x) != 0.0); } +-#line 2679 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 61: +-#line 549 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[0].x) == 0.0); } +-#line 2685 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 62: +-#line 555 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.by).val = 1.0; +- (yyval.by).is_multiplicative = 0; +- } +-#line 2694 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 63: +-#line 560 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.by).val = (yyvsp[0].x); +- (yyval.by).is_multiplicative = 0; +- } +-#line 2703 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 64: +-#line 565 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.by).val = (yyvsp[0].x); +- (yyval.by).is_multiplicative = 1; +- } +-#line 2712 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 65: +-#line 573 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pl).obj = (yyvsp[0].spec)->make_object(¤t_position, +- ¤t_direction); +- if ((yyval.pl).obj == 0) +- YYABORT; +- delete (yyvsp[0].spec); +- if ((yyval.pl).obj) +- olist.append((yyval.pl).obj); +- else { +- (yyval.pl).x = current_position.x; +- (yyval.pl).y = current_position.y; +- } +- } +-#line 2730 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 66: +-#line 587 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pl) = (yyvsp[0].pl); +- define_label((yyvsp[-3].str), & (yyval.pl)); +- a_delete (yyvsp[-3].str); +- } +-#line 2740 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 67: +-#line 593 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pl).obj = 0; +- (yyval.pl).x = (yyvsp[0].pair).x; +- (yyval.pl).y = (yyvsp[0].pair).y; +- define_label((yyvsp[-3].str), & (yyval.pl)); +- a_delete (yyvsp[-3].str); +- } +-#line 2752 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 68: +-#line 601 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pl) = (yyvsp[0].pl); +- define_label((yyvsp[-3].str), & (yyval.pl)); +- a_delete (yyvsp[-3].str); +- } +-#line 2762 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 69: +-#line 607 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.state).x = current_position.x; +- (yyval.state).y = current_position.y; +- (yyval.state).dir = current_direction; +- } +-#line 2772 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 70: +-#line 613 "pic.y" /* yacc.c:1646 */ +- { +- current_position.x = (yyvsp[-2].state).x; +- current_position.y = (yyvsp[-2].state).y; +- current_direction = (yyvsp[-2].state).dir; +- } +-#line 2782 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 71: +-#line 619 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pl) = (yyvsp[-3].pl); +- } +-#line 2790 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 72: +-#line 623 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pl).obj = 0; +- (yyval.pl).x = current_position.x; +- (yyval.pl).y = current_position.y; +- } +-#line 2800 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 73: +-#line 632 "pic.y" /* yacc.c:1646 */ +- {} +-#line 2806 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 74: +-#line 634 "pic.y" /* yacc.c:1646 */ +- {} +-#line 2812 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 75: +-#line 639 "pic.y" /* yacc.c:1646 */ +- { (yyval.spec) = new object_spec(BOX_OBJECT); } +-#line 2818 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 76: +-#line 641 "pic.y" /* yacc.c:1646 */ +- { (yyval.spec) = new object_spec(CIRCLE_OBJECT); } +-#line 2824 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 77: +-#line 643 "pic.y" /* yacc.c:1646 */ +- { (yyval.spec) = new object_spec(ELLIPSE_OBJECT); } +-#line 2830 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 78: +-#line 645 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = new object_spec(ARC_OBJECT); +- (yyval.spec)->dir = current_direction; +- } +-#line 2839 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 79: +-#line 650 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = new object_spec(LINE_OBJECT); +- lookup_variable("lineht", & (yyval.spec)->segment_height); +- lookup_variable("linewid", & (yyval.spec)->segment_width); +- (yyval.spec)->dir = current_direction; +- } +-#line 2850 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 80: +-#line 657 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = new object_spec(ARROW_OBJECT); +- lookup_variable("lineht", & (yyval.spec)->segment_height); +- lookup_variable("linewid", & (yyval.spec)->segment_width); +- (yyval.spec)->dir = current_direction; +- } +-#line 2861 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 81: +-#line 664 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = new object_spec(MOVE_OBJECT); +- lookup_variable("moveht", & (yyval.spec)->segment_height); +- lookup_variable("movewid", & (yyval.spec)->segment_width); +- (yyval.spec)->dir = current_direction; +- } +-#line 2872 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 82: +-#line 671 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = new object_spec(SPLINE_OBJECT); +- lookup_variable("lineht", & (yyval.spec)->segment_height); +- lookup_variable("linewid", & (yyval.spec)->segment_width); +- (yyval.spec)->dir = current_direction; +- } +-#line 2883 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 83: +-#line 678 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = new object_spec(TEXT_OBJECT); +- (yyval.spec)->text = new text_item((yyvsp[0].lstr).str, (yyvsp[0].lstr).filename, (yyvsp[0].lstr).lineno); +- } +-#line 2892 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 84: +-#line 683 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = new object_spec(TEXT_OBJECT); +- (yyval.spec)->text = new text_item(format_number(0, (yyvsp[0].x)), 0, -1); +- } +-#line 2901 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 85: +-#line 688 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = new object_spec(TEXT_OBJECT); +- (yyval.spec)->text = new text_item(format_number((yyvsp[0].lstr).str, (yyvsp[-1].x)), +- (yyvsp[0].lstr).filename, (yyvsp[0].lstr).lineno); +- a_delete (yyvsp[0].lstr).str; +- } +-#line 2912 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 86: +-#line 695 "pic.y" /* yacc.c:1646 */ +- { +- saved_state *p = new saved_state; +- (yyval.pstate) = p; +- p->x = current_position.x; +- p->y = current_position.y; +- p->dir = current_direction; +- p->tbl = current_table; +- p->prev = current_saved_state; +- current_position.x = 0.0; +- current_position.y = 0.0; +- current_table = new PTABLE(place); +- current_saved_state = p; +- olist.append(make_mark_object()); +- } +-#line 2931 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 87: +-#line 710 "pic.y" /* yacc.c:1646 */ +- { +- current_position.x = (yyvsp[-2].pstate)->x; +- current_position.y = (yyvsp[-2].pstate)->y; +- current_direction = (yyvsp[-2].pstate)->dir; +- (yyval.spec) = new object_spec(BLOCK_OBJECT); +- olist.wrap_up_block(& (yyval.spec)->oblist); +- (yyval.spec)->tbl = current_table; +- current_table = (yyvsp[-2].pstate)->tbl; +- current_saved_state = (yyvsp[-2].pstate)->prev; +- delete (yyvsp[-2].pstate); +- } +-#line 2947 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 88: +-#line 722 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->height = (yyvsp[0].x); +- (yyval.spec)->flags |= HAS_HEIGHT; +- } +-#line 2957 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 89: +-#line 728 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->radius = (yyvsp[0].x); +- (yyval.spec)->flags |= HAS_RADIUS; +- } +-#line 2967 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 90: +-#line 734 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->width = (yyvsp[0].x); +- (yyval.spec)->flags |= HAS_WIDTH; +- } +-#line 2977 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 91: +-#line 740 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->radius = (yyvsp[0].x)/2.0; +- (yyval.spec)->flags |= HAS_RADIUS; +- } +-#line 2987 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 92: +-#line 746 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= HAS_SEGMENT; +- switch ((yyval.spec)->dir) { +- case UP_DIRECTION: +- (yyval.spec)->segment_pos.y += (yyvsp[0].x); +- break; +- case DOWN_DIRECTION: +- (yyval.spec)->segment_pos.y -= (yyvsp[0].x); +- break; +- case RIGHT_DIRECTION: +- (yyval.spec)->segment_pos.x += (yyvsp[0].x); +- break; +- case LEFT_DIRECTION: +- (yyval.spec)->segment_pos.x -= (yyvsp[0].x); +- break; +- } +- } +-#line 3010 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 93: +-#line 765 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->dir = UP_DIRECTION; +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.y += (yyval.spec)->segment_height; +- } +-#line 3021 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 94: +-#line 772 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->dir = UP_DIRECTION; +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.y += (yyvsp[0].x); +- } +-#line 3032 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 95: +-#line 779 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->dir = DOWN_DIRECTION; +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.y -= (yyval.spec)->segment_height; +- } +-#line 3043 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 96: +-#line 786 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->dir = DOWN_DIRECTION; +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.y -= (yyvsp[0].x); +- } +-#line 3054 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 97: +-#line 793 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->dir = RIGHT_DIRECTION; +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.x += (yyval.spec)->segment_width; +- } +-#line 3065 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 98: +-#line 800 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->dir = RIGHT_DIRECTION; +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.x += (yyvsp[0].x); +- } +-#line 3076 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 99: +-#line 807 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->dir = LEFT_DIRECTION; +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.x -= (yyval.spec)->segment_width; +- } +-#line 3087 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 100: +-#line 814 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->dir = LEFT_DIRECTION; +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.x -= (yyvsp[0].x); +- } +-#line 3098 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 101: +-#line 821 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= HAS_FROM; +- (yyval.spec)->from.x = (yyvsp[0].pair).x; +- (yyval.spec)->from.y = (yyvsp[0].pair).y; +- } +-#line 3109 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 102: +-#line 828 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- if ((yyval.spec)->flags & HAS_SEGMENT) +- (yyval.spec)->segment_list = new segment((yyval.spec)->segment_pos, +- (yyval.spec)->segment_is_absolute, +- (yyval.spec)->segment_list); +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.x = (yyvsp[0].pair).x; +- (yyval.spec)->segment_pos.y = (yyvsp[0].pair).y; +- (yyval.spec)->segment_is_absolute = 1; +- (yyval.spec)->flags |= HAS_TO; +- (yyval.spec)->to.x = (yyvsp[0].pair).x; +- (yyval.spec)->to.y = (yyvsp[0].pair).y; +- } +-#line 3128 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 103: +-#line 843 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= HAS_AT; +- (yyval.spec)->at.x = (yyvsp[0].pair).x; +- (yyval.spec)->at.y = (yyvsp[0].pair).y; +- if ((yyval.spec)->type != ARC_OBJECT) { +- (yyval.spec)->flags |= HAS_FROM; +- (yyval.spec)->from.x = (yyvsp[0].pair).x; +- (yyval.spec)->from.y = (yyvsp[0].pair).y; +- } +- } +-#line 3144 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 104: +-#line 855 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= HAS_WITH; +- (yyval.spec)->with = (yyvsp[0].pth); +- } +-#line 3154 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 105: +-#line 861 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= HAS_WITH; +- position pos; +- pos.x = (yyvsp[0].pair).x; +- pos.y = (yyvsp[0].pair).y; +- (yyval.spec)->with = new path(pos); +- } +-#line 3167 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 106: +-#line 870 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= HAS_SEGMENT; +- (yyval.spec)->segment_pos.x += (yyvsp[0].pair).x; +- (yyval.spec)->segment_pos.y += (yyvsp[0].pair).y; +- } +-#line 3178 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 107: +-#line 877 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- if (!((yyval.spec)->flags & HAS_SEGMENT)) +- switch ((yyval.spec)->dir) { +- case UP_DIRECTION: +- (yyval.spec)->segment_pos.y += (yyval.spec)->segment_width; +- break; +- case DOWN_DIRECTION: +- (yyval.spec)->segment_pos.y -= (yyval.spec)->segment_width; +- break; +- case RIGHT_DIRECTION: +- (yyval.spec)->segment_pos.x += (yyval.spec)->segment_width; +- break; +- case LEFT_DIRECTION: +- (yyval.spec)->segment_pos.x -= (yyval.spec)->segment_width; +- break; +- } +- (yyval.spec)->segment_list = new segment((yyval.spec)->segment_pos, +- (yyval.spec)->segment_is_absolute, +- (yyval.spec)->segment_list); +- (yyval.spec)->flags &= ~HAS_SEGMENT; +- (yyval.spec)->segment_pos.x = (yyval.spec)->segment_pos.y = 0.0; +- (yyval.spec)->segment_is_absolute = 0; +- } +-#line 3207 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 108: +-#line 902 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); // nothing +- } +-#line 3215 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 109: +-#line 906 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= IS_DOTTED; +- lookup_variable("dashwid", & (yyval.spec)->dash_width); +- } +-#line 3225 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 110: +-#line 912 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= IS_DOTTED; +- (yyval.spec)->dash_width = (yyvsp[0].x); +- } +-#line 3235 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 111: +-#line 918 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= IS_DASHED; +- lookup_variable("dashwid", & (yyval.spec)->dash_width); +- } +-#line 3245 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 112: +-#line 924 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= IS_DASHED; +- (yyval.spec)->dash_width = (yyvsp[0].x); +- } +-#line 3255 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 113: +-#line 930 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= IS_DEFAULT_FILLED; +- } +-#line 3264 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 114: +-#line 935 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= IS_FILLED; +- (yyval.spec)->fill = (yyvsp[0].x); +- } +-#line 3274 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 115: +-#line 941 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= IS_XSLANTED; +- (yyval.spec)->xslanted = (yyvsp[0].x); +- } +-#line 3284 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 116: +-#line 947 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= IS_YSLANTED; +- (yyval.spec)->yslanted = (yyvsp[0].x); +- } +-#line 3294 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 117: +-#line 953 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= (IS_SHADED | IS_FILLED); +- (yyval.spec)->shaded = new char[strlen((yyvsp[0].lstr).str)+1]; +- strcpy((yyval.spec)->shaded, (yyvsp[0].lstr).str); +- } +-#line 3305 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 118: +-#line 960 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= (IS_SHADED | IS_OUTLINED | IS_FILLED); +- (yyval.spec)->shaded = new char[strlen((yyvsp[0].lstr).str)+1]; +- strcpy((yyval.spec)->shaded, (yyvsp[0].lstr).str); +- (yyval.spec)->outlined = new char[strlen((yyvsp[0].lstr).str)+1]; +- strcpy((yyval.spec)->outlined, (yyvsp[0].lstr).str); +- } +-#line 3318 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 119: +-#line 969 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= IS_OUTLINED; +- (yyval.spec)->outlined = new char[strlen((yyvsp[0].lstr).str)+1]; +- strcpy((yyval.spec)->outlined, (yyvsp[0].lstr).str); +- } +-#line 3329 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 120: +-#line 976 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- // line chop chop means line chop 0 chop 0 +- if ((yyval.spec)->flags & IS_DEFAULT_CHOPPED) { +- (yyval.spec)->flags |= IS_CHOPPED; +- (yyval.spec)->flags &= ~IS_DEFAULT_CHOPPED; +- (yyval.spec)->start_chop = (yyval.spec)->end_chop = 0.0; +- } +- else if ((yyval.spec)->flags & IS_CHOPPED) { +- (yyval.spec)->end_chop = 0.0; +- } +- else { +- (yyval.spec)->flags |= IS_DEFAULT_CHOPPED; +- } +- } +-#line 3349 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 121: +-#line 992 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- if ((yyval.spec)->flags & IS_DEFAULT_CHOPPED) { +- (yyval.spec)->flags |= IS_CHOPPED; +- (yyval.spec)->flags &= ~IS_DEFAULT_CHOPPED; +- (yyval.spec)->start_chop = 0.0; +- (yyval.spec)->end_chop = (yyvsp[0].x); +- } +- else if ((yyval.spec)->flags & IS_CHOPPED) { +- (yyval.spec)->end_chop = (yyvsp[0].x); +- } +- else { +- (yyval.spec)->start_chop = (yyval.spec)->end_chop = (yyvsp[0].x); +- (yyval.spec)->flags |= IS_CHOPPED; +- } +- } +-#line 3370 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 122: +-#line 1009 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= IS_SAME; +- } +-#line 3379 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 123: +-#line 1014 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= IS_INVISIBLE; +- } +-#line 3388 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 124: +-#line 1019 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= HAS_LEFT_ARROW_HEAD; +- } +-#line 3397 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 125: +-#line 1024 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= HAS_RIGHT_ARROW_HEAD; +- } +-#line 3406 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 126: +-#line 1029 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD); +- } +-#line 3415 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 127: +-#line 1034 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= IS_CLOCKWISE; +- } +-#line 3424 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 128: +-#line 1039 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags &= ~IS_CLOCKWISE; +- } +-#line 3433 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 129: +-#line 1044 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- text_item **p; +- for (p = & (yyval.spec)->text; *p; p = &(*p)->next) +- ; +- *p = new text_item((yyvsp[0].lstr).str, (yyvsp[0].lstr).filename, (yyvsp[0].lstr).lineno); +- } +-#line 3445 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 130: +-#line 1052 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- if ((yyval.spec)->text) { +- text_item *p; +- for (p = (yyval.spec)->text; p->next; p = p->next) +- ; +- p->adj.h = LEFT_ADJUST; +- } +- } +-#line 3459 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 131: +-#line 1062 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- if ((yyval.spec)->text) { +- text_item *p; +- for (p = (yyval.spec)->text; p->next; p = p->next) +- ; +- p->adj.h = RIGHT_ADJUST; +- } +- } +-#line 3473 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 132: +-#line 1072 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- if ((yyval.spec)->text) { +- text_item *p; +- for (p = (yyval.spec)->text; p->next; p = p->next) +- ; +- p->adj.v = ABOVE_ADJUST; +- } +- } +-#line 3487 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 133: +-#line 1082 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- if ((yyval.spec)->text) { +- text_item *p; +- for (p = (yyval.spec)->text; p->next; p = p->next) +- ; +- p->adj.v = BELOW_ADJUST; +- } +- } +-#line 3501 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 134: +-#line 1092 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-2].spec); +- (yyval.spec)->flags |= HAS_THICKNESS; +- (yyval.spec)->thickness = (yyvsp[0].x); +- } +-#line 3511 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 135: +-#line 1098 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.spec) = (yyvsp[-1].spec); +- (yyval.spec)->flags |= IS_ALIGNED; +- } +-#line 3520 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 136: +-#line 1106 "pic.y" /* yacc.c:1646 */ +- { (yyval.lstr) = (yyvsp[0].lstr); } +-#line 3526 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 137: +-#line 1108 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.lstr).filename = (yyvsp[-2].lstr).filename; +- (yyval.lstr).lineno = (yyvsp[-2].lstr).lineno; +- (yyval.lstr).str = do_sprintf((yyvsp[-2].lstr).str, (yyvsp[-1].dv).v, (yyvsp[-1].dv).nv); +- a_delete (yyvsp[-1].dv).v; +- a_delete (yyvsp[-2].lstr).str; +- } +-#line 3538 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 138: +-#line 1119 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.dv).v = 0; +- (yyval.dv).nv = 0; +- (yyval.dv).maxv = 0; +- } +-#line 3548 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 139: +-#line 1125 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.dv) = (yyvsp[-2].dv); +- if ((yyval.dv).nv >= (yyval.dv).maxv) { +- if ((yyval.dv).nv == 0) { +- (yyval.dv).v = new double[4]; +- (yyval.dv).maxv = 4; +- } +- else { +- double *oldv = (yyval.dv).v; +- (yyval.dv).maxv *= 2; +-#if 0 +- (yyval.dv).v = new double[(yyval.dv).maxv]; +- memcpy((yyval.dv).v, oldv, (yyval.dv).nv*sizeof(double)); +-#else +- // workaround for bug in Compaq C++ V6.5-033 +- // for Compaq Tru64 UNIX V5.1A (Rev. 1885) +- double *foo = new double[(yyval.dv).maxv]; +- memcpy(foo, oldv, (yyval.dv).nv*sizeof(double)); +- (yyval.dv).v = foo; +-#endif +- a_delete oldv; +- } +- } +- (yyval.dv).v[(yyval.dv).nv] = (yyvsp[0].x); +- (yyval.dv).nv += 1; +- } +-#line 3579 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 140: +-#line 1155 "pic.y" /* yacc.c:1646 */ +- { (yyval.pair) = (yyvsp[0].pair); } +-#line 3585 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 141: +-#line 1157 "pic.y" /* yacc.c:1646 */ +- { +- position pos = (yyvsp[0].pl); +- (yyval.pair).x = pos.x; +- (yyval.pair).y = pos.y; +- } +-#line 3595 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 142: +-#line 1163 "pic.y" /* yacc.c:1646 */ +- { +- position pos = (yyvsp[-1].pl); +- (yyval.pair).x = pos.x; +- (yyval.pair).y = pos.y; +- } +-#line 3605 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 143: +-#line 1172 "pic.y" /* yacc.c:1646 */ +- { (yyval.pair) = (yyvsp[0].pair); } +-#line 3611 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 144: +-#line 1174 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (yyvsp[-2].pair).x + (yyvsp[0].pair).x; +- (yyval.pair).y = (yyvsp[-2].pair).y + (yyvsp[0].pair).y; +- } +-#line 3620 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 145: +-#line 1179 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (yyvsp[-3].pair).x + (yyvsp[-1].pair).x; +- (yyval.pair).y = (yyvsp[-3].pair).y + (yyvsp[-1].pair).y; +- } +-#line 3629 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 146: +-#line 1184 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (yyvsp[-2].pair).x - (yyvsp[0].pair).x; +- (yyval.pair).y = (yyvsp[-2].pair).y - (yyvsp[0].pair).y; +- } +-#line 3638 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 147: +-#line 1189 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (yyvsp[-3].pair).x - (yyvsp[-1].pair).x; +- (yyval.pair).y = (yyvsp[-3].pair).y - (yyvsp[-1].pair).y; +- } +-#line 3647 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 148: +-#line 1194 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (yyvsp[-3].pair).x; +- (yyval.pair).y = (yyvsp[-1].pair).y; +- } +-#line 3656 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 149: +-#line 1199 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (1.0 - (yyvsp[-4].x))*(yyvsp[-2].pair).x + (yyvsp[-4].x)*(yyvsp[0].pair).x; +- (yyval.pair).y = (1.0 - (yyvsp[-4].x))*(yyvsp[-2].pair).y + (yyvsp[-4].x)*(yyvsp[0].pair).y; +- } +-#line 3665 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 150: +-#line 1204 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (1.0 - (yyvsp[-5].x))*(yyvsp[-3].pair).x + (yyvsp[-5].x)*(yyvsp[-1].pair).x; +- (yyval.pair).y = (1.0 - (yyvsp[-5].x))*(yyvsp[-3].pair).y + (yyvsp[-5].x)*(yyvsp[-1].pair).y; +- } +-#line 3674 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 151: +-#line 1210 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (1.0 - (yyvsp[-5].x))*(yyvsp[-3].pair).x + (yyvsp[-5].x)*(yyvsp[-1].pair).x; +- (yyval.pair).y = (1.0 - (yyvsp[-5].x))*(yyvsp[-3].pair).y + (yyvsp[-5].x)*(yyvsp[-1].pair).y; +- } +-#line 3683 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 152: +-#line 1215 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (1.0 - (yyvsp[-6].x))*(yyvsp[-4].pair).x + (yyvsp[-6].x)*(yyvsp[-2].pair).x; +- (yyval.pair).y = (1.0 - (yyvsp[-6].x))*(yyvsp[-4].pair).y + (yyvsp[-6].x)*(yyvsp[-2].pair).y; +- } +-#line 3692 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 155: +-#line 1228 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pair).x = (yyvsp[-2].x); +- (yyval.pair).y = (yyvsp[0].x); +- } +-#line 3701 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 156: +-#line 1233 "pic.y" /* yacc.c:1646 */ +- { (yyval.pair) = (yyvsp[-1].pair); } +-#line 3707 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 157: +-#line 1239 "pic.y" /* yacc.c:1646 */ +- { (yyval.pl) = (yyvsp[0].pl); } +-#line 3713 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 158: +-#line 1241 "pic.y" /* yacc.c:1646 */ +- { +- path pth((yyvsp[0].crn)); +- if (!pth.follow((yyvsp[-1].pl), & (yyval.pl))) +- YYABORT; +- } +-#line 3723 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 159: +-#line 1247 "pic.y" /* yacc.c:1646 */ +- { +- path pth((yyvsp[-1].crn)); +- if (!pth.follow((yyvsp[0].pl), & (yyval.pl))) +- YYABORT; +- } +-#line 3733 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 160: +-#line 1253 "pic.y" /* yacc.c:1646 */ +- { +- path pth((yyvsp[-2].crn)); +- if (!pth.follow((yyvsp[0].pl), & (yyval.pl))) +- YYABORT; +- } +-#line 3743 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 161: +-#line 1259 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pl).x = current_position.x; +- (yyval.pl).y = current_position.y; +- (yyval.pl).obj = 0; +- } +-#line 3753 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 162: +-#line 1268 "pic.y" /* yacc.c:1646 */ +- { +- place *p = lookup_label((yyvsp[0].str)); +- if (!p) { +- lex_error("there is no place `%1'", (yyvsp[0].str)); +- YYABORT; +- } +- (yyval.pl) = *p; +- a_delete (yyvsp[0].str); +- } +-#line 3767 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 163: +-#line 1278 "pic.y" /* yacc.c:1646 */ +- { (yyval.pl).obj = (yyvsp[0].obj); } +-#line 3773 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 164: +-#line 1280 "pic.y" /* yacc.c:1646 */ +- { +- path pth((yyvsp[0].str)); +- if (!pth.follow((yyvsp[-2].pl), & (yyval.pl))) +- YYABORT; +- } +-#line 3783 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 165: +-#line 1289 "pic.y" /* yacc.c:1646 */ +- { (yyval.n) = (yyvsp[0].n); } +-#line 3789 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 166: +-#line 1291 "pic.y" /* yacc.c:1646 */ +- { +- // XXX Check for overflow (and non-integers?). +- (yyval.n) = (int)(yyvsp[-1].x); +- } +-#line 3798 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 167: +-#line 1299 "pic.y" /* yacc.c:1646 */ +- { (yyval.n) = 1; } +-#line 3804 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 168: +-#line 1301 "pic.y" /* yacc.c:1646 */ +- { (yyval.n) = (yyvsp[-1].n); } +-#line 3810 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 169: +-#line 1306 "pic.y" /* yacc.c:1646 */ +- { +- int count = 0; +- object *p; +- for (p = olist.head; p != 0; p = p->next) +- if (p->type() == (yyvsp[0].obtype) && ++count == (yyvsp[-1].n)) { +- (yyval.obj) = p; +- break; +- } +- if (p == 0) { +- lex_error("there is no %1%2 %3", (yyvsp[-1].n), ordinal_postfix((yyvsp[-1].n)), +- object_type_name((yyvsp[0].obtype))); +- YYABORT; +- } +- } +-#line 3829 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 170: +-#line 1321 "pic.y" /* yacc.c:1646 */ +- { +- int count = 0; +- object *p; +- for (p = olist.tail; p != 0; p = p->prev) +- if (p->type() == (yyvsp[0].obtype) && ++count == (yyvsp[-1].n)) { +- (yyval.obj) = p; +- break; +- } +- if (p == 0) { +- lex_error("there is no %1%2 last %3", (yyvsp[-1].n), +- ordinal_postfix((yyvsp[-1].n)), object_type_name((yyvsp[0].obtype))); +- YYABORT; +- } +- } +-#line 3848 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 171: +-#line 1339 "pic.y" /* yacc.c:1646 */ +- { (yyval.obtype) = BOX_OBJECT; } +-#line 3854 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 172: +-#line 1341 "pic.y" /* yacc.c:1646 */ +- { (yyval.obtype) = CIRCLE_OBJECT; } +-#line 3860 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 173: +-#line 1343 "pic.y" /* yacc.c:1646 */ +- { (yyval.obtype) = ELLIPSE_OBJECT; } +-#line 3866 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 174: +-#line 1345 "pic.y" /* yacc.c:1646 */ +- { (yyval.obtype) = ARC_OBJECT; } +-#line 3872 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 175: +-#line 1347 "pic.y" /* yacc.c:1646 */ +- { (yyval.obtype) = LINE_OBJECT; } +-#line 3878 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 176: +-#line 1349 "pic.y" /* yacc.c:1646 */ +- { (yyval.obtype) = ARROW_OBJECT; } +-#line 3884 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 177: +-#line 1351 "pic.y" /* yacc.c:1646 */ +- { (yyval.obtype) = SPLINE_OBJECT; } +-#line 3890 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 178: +-#line 1353 "pic.y" /* yacc.c:1646 */ +- { (yyval.obtype) = BLOCK_OBJECT; } +-#line 3896 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 179: +-#line 1355 "pic.y" /* yacc.c:1646 */ +- { (yyval.obtype) = TEXT_OBJECT; } +-#line 3902 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 180: +-#line 1360 "pic.y" /* yacc.c:1646 */ +- { (yyval.pth) = new path((yyvsp[0].str)); } +-#line 3908 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 181: +-#line 1362 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pth) = (yyvsp[-2].pth); +- (yyval.pth)->append((yyvsp[0].str)); +- } +-#line 3917 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 182: +-#line 1370 "pic.y" /* yacc.c:1646 */ +- { (yyval.pth) = new path((yyvsp[0].crn)); } +-#line 3923 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 183: +-#line 1374 "pic.y" /* yacc.c:1646 */ +- { (yyval.pth) = (yyvsp[0].pth); } +-#line 3929 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 184: +-#line 1376 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pth) = (yyvsp[-1].pth); +- (yyval.pth)->append((yyvsp[0].crn)); +- } +-#line 3938 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 185: +-#line 1384 "pic.y" /* yacc.c:1646 */ +- { (yyval.pth) = (yyvsp[0].pth); } +-#line 3944 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 186: +-#line 1386 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.pth) = (yyvsp[-3].pth); +- (yyval.pth)->set_ypath((yyvsp[-1].pth)); +- } +-#line 3953 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 187: +-#line 1392 "pic.y" /* yacc.c:1646 */ +- { +- lex_warning("`%1%2 last %3' in `with' argument ignored", +- (yyvsp[-3].n), ordinal_postfix((yyvsp[-3].n)), object_type_name((yyvsp[-1].obtype))); +- (yyval.pth) = (yyvsp[0].pth); +- } +-#line 3963 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 188: +-#line 1398 "pic.y" /* yacc.c:1646 */ +- { +- lex_warning("`last %1' in `with' argument ignored", +- object_type_name((yyvsp[-1].obtype))); +- (yyval.pth) = (yyvsp[0].pth); +- } +-#line 3973 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 189: +-#line 1404 "pic.y" /* yacc.c:1646 */ +- { +- lex_warning("`%1%2 %3' in `with' argument ignored", +- (yyvsp[-2].n), ordinal_postfix((yyvsp[-2].n)), object_type_name((yyvsp[-1].obtype))); +- (yyval.pth) = (yyvsp[0].pth); +- } +-#line 3983 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 190: +-#line 1410 "pic.y" /* yacc.c:1646 */ +- { +- lex_warning("initial `%1' in `with' argument ignored", (yyvsp[-1].str)); +- a_delete (yyvsp[-1].str); +- (yyval.pth) = (yyvsp[0].pth); +- } +-#line 3993 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 191: +-#line 1419 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::north; } +-#line 3999 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 192: +-#line 1421 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::east; } +-#line 4005 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 193: +-#line 1423 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::west; } +-#line 4011 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 194: +-#line 1425 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::south; } +-#line 4017 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 195: +-#line 1427 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::north_east; } +-#line 4023 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 196: +-#line 1429 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object:: south_east; } +-#line 4029 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 197: +-#line 1431 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::north_west; } +-#line 4035 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 198: +-#line 1433 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::south_west; } +-#line 4041 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 199: +-#line 1435 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::center; } +-#line 4047 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 200: +-#line 1437 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::start; } +-#line 4053 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 201: +-#line 1439 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::end; } +-#line 4059 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 202: +-#line 1441 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::north; } +-#line 4065 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 203: +-#line 1443 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::south; } +-#line 4071 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 204: +-#line 1445 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::west; } +-#line 4077 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 205: +-#line 1447 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::east; } +-#line 4083 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 206: +-#line 1449 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::north_west; } +-#line 4089 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 207: +-#line 1451 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::south_west; } +-#line 4095 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 208: +-#line 1453 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::north_east; } +-#line 4101 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 209: +-#line 1455 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::south_east; } +-#line 4107 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 210: +-#line 1457 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::west; } +-#line 4113 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 211: +-#line 1459 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::east; } +-#line 4119 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 212: +-#line 1461 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::north_west; } +-#line 4125 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 213: +-#line 1463 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::south_west; } +-#line 4131 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 214: +-#line 1465 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::north_east; } +-#line 4137 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 215: +-#line 1467 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::south_east; } +-#line 4143 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 216: +-#line 1469 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::north; } +-#line 4149 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 217: +-#line 1471 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::south; } +-#line 4155 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 218: +-#line 1473 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::east; } +-#line 4161 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 219: +-#line 1475 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::west; } +-#line 4167 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 220: +-#line 1477 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::center; } +-#line 4173 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 221: +-#line 1479 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::start; } +-#line 4179 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 222: +-#line 1481 "pic.y" /* yacc.c:1646 */ +- { (yyval.crn) = &object::end; } +-#line 4185 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 223: +-#line 1486 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[0].x); } +-#line 4191 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 224: +-#line 1488 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[0].x); } +-#line 4197 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 225: +-#line 1493 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) < (yyvsp[0].x)); } +-#line 4203 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 226: +-#line 1498 "pic.y" /* yacc.c:1646 */ +- { +- if (!lookup_variable((yyvsp[0].str), & (yyval.x))) { +- lex_error("there is no variable `%1'", (yyvsp[0].str)); +- YYABORT; +- } +- a_delete (yyvsp[0].str); +- } +-#line 4215 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 227: +-#line 1506 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[0].x); } +-#line 4221 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 228: +-#line 1508 "pic.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[-1].pl).obj != 0) +- (yyval.x) = (yyvsp[-1].pl).obj->origin().x; +- else +- (yyval.x) = (yyvsp[-1].pl).x; +- } +-#line 4232 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 229: +-#line 1515 "pic.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[-1].pl).obj != 0) +- (yyval.x) = (yyvsp[-1].pl).obj->origin().y; +- else +- (yyval.x) = (yyvsp[-1].pl).y; +- } +-#line 4243 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 230: +-#line 1522 "pic.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[-1].pl).obj != 0) +- (yyval.x) = (yyvsp[-1].pl).obj->height(); +- else +- (yyval.x) = 0.0; +- } +-#line 4254 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 231: +-#line 1529 "pic.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[-1].pl).obj != 0) +- (yyval.x) = (yyvsp[-1].pl).obj->width(); +- else +- (yyval.x) = 0.0; +- } +-#line 4265 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 232: +-#line 1536 "pic.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[-1].pl).obj != 0) +- (yyval.x) = (yyvsp[-1].pl).obj->radius(); +- else +- (yyval.x) = 0.0; +- } +-#line 4276 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 233: +-#line 1543 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[-2].x) + (yyvsp[0].x); } +-#line 4282 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 234: +-#line 1545 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[-2].x) - (yyvsp[0].x); } +-#line 4288 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 235: +-#line 1547 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[-2].x) * (yyvsp[0].x); } +-#line 4294 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 236: +-#line 1549 "pic.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[0].x) == 0.0) { +- lex_error("division by zero"); +- YYABORT; +- } +- (yyval.x) = (yyvsp[-2].x)/(yyvsp[0].x); +- } +-#line 4306 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 237: +-#line 1557 "pic.y" /* yacc.c:1646 */ +- { +- if ((yyvsp[0].x) == 0.0) { +- lex_error("modulus by zero"); +- YYABORT; +- } +- (yyval.x) = fmod((yyvsp[-2].x), (yyvsp[0].x)); +- } +-#line 4318 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 238: +-#line 1565 "pic.y" /* yacc.c:1646 */ +- { +- errno = 0; +- (yyval.x) = pow((yyvsp[-2].x), (yyvsp[0].x)); +- if (errno == EDOM) { +- lex_error("arguments to `^' operator out of domain"); +- YYABORT; +- } +- if (errno == ERANGE) { +- lex_error("result of `^' operator out of range"); +- YYABORT; +- } +- } +-#line 4335 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 239: +-#line 1578 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = -(yyvsp[0].x); } +-#line 4341 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 240: +-#line 1580 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[-1].x); } +-#line 4347 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 241: +-#line 1582 "pic.y" /* yacc.c:1646 */ +- { +- errno = 0; +- (yyval.x) = sin((yyvsp[-1].x)); +- if (errno == ERANGE) { +- lex_error("sin result out of range"); +- YYABORT; +- } +- } +-#line 4360 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 242: +-#line 1591 "pic.y" /* yacc.c:1646 */ +- { +- errno = 0; +- (yyval.x) = cos((yyvsp[-1].x)); +- if (errno == ERANGE) { +- lex_error("cos result out of range"); +- YYABORT; +- } +- } +-#line 4373 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 243: +-#line 1600 "pic.y" /* yacc.c:1646 */ +- { +- errno = 0; +- (yyval.x) = atan2((yyvsp[-3].x), (yyvsp[-1].x)); +- if (errno == EDOM) { +- lex_error("atan2 argument out of domain"); +- YYABORT; +- } +- if (errno == ERANGE) { +- lex_error("atan2 result out of range"); +- YYABORT; +- } +- } +-#line 4390 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 244: +-#line 1613 "pic.y" /* yacc.c:1646 */ +- { +- errno = 0; +- (yyval.x) = log10((yyvsp[-1].x)); +- if (errno == ERANGE) { +- lex_error("log result out of range"); +- YYABORT; +- } +- } +-#line 4403 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 245: +-#line 1622 "pic.y" /* yacc.c:1646 */ +- { +- errno = 0; +- (yyval.x) = pow(10.0, (yyvsp[-1].x)); +- if (errno == ERANGE) { +- lex_error("exp result out of range"); +- YYABORT; +- } +- } +-#line 4416 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 246: +-#line 1631 "pic.y" /* yacc.c:1646 */ +- { +- errno = 0; +- (yyval.x) = sqrt((yyvsp[-1].x)); +- if (errno == EDOM) { +- lex_error("sqrt argument out of domain"); +- YYABORT; +- } +- } +-#line 4429 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 247: +-#line 1640 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[-3].x) > (yyvsp[-1].x) ? (yyvsp[-3].x) : (yyvsp[-1].x); } +-#line 4435 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 248: +-#line 1642 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[-3].x) < (yyvsp[-1].x) ? (yyvsp[-3].x) : (yyvsp[-1].x); } +-#line 4441 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 249: +-#line 1644 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = (yyvsp[-1].x) < 0 ? -floor(-(yyvsp[-1].x)) : floor((yyvsp[-1].x)); } +-#line 4447 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 250: +-#line 1646 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*(yyvsp[-1].x)); } +-#line 4453 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 251: +-#line 1648 "pic.y" /* yacc.c:1646 */ +- { +- /* return a random number in the range [0,1) */ +- /* portable, but not very random */ +- (yyval.x) = (rand() & 0x7fff) / double(0x8000); +- } +-#line 4463 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 252: +-#line 1654 "pic.y" /* yacc.c:1646 */ +- { +- (yyval.x) = 0; +- srand((unsigned int)(yyvsp[-1].x)); +- } +-#line 4472 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 253: +-#line 1659 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) <= (yyvsp[0].x)); } +-#line 4478 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 254: +-#line 1661 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) > (yyvsp[0].x)); } +-#line 4484 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 255: +-#line 1663 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) >= (yyvsp[0].x)); } +-#line 4490 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 256: +-#line 1665 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) == (yyvsp[0].x)); } +-#line 4496 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 257: +-#line 1667 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) != (yyvsp[0].x)); } +-#line 4502 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 258: +-#line 1669 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) != 0.0 && (yyvsp[0].x) != 0.0); } +-#line 4508 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 259: +-#line 1671 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[-2].x) != 0.0 || (yyvsp[0].x) != 0.0); } +-#line 4514 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- case 260: +-#line 1673 "pic.y" /* yacc.c:1646 */ +- { (yyval.x) = ((yyvsp[0].x) == 0.0); } +-#line 4520 "pic.cpp" /* yacc.c:1646 */ +- break; +- +- +-#line 4524 "pic.cpp" /* yacc.c:1646 */ +- default: break; +- } +- /* User semantic actions sometimes alter yychar, and that requires +- that yytoken be updated with the new translation. We take the +- approach of translating immediately before every use of yytoken. +- One alternative is translating here after every semantic action, +- but that translation would be missed if the semantic action invokes +- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or +- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an +- incorrect destructor might then be invoked immediately. In the +- case of YYERROR or YYBACKUP, subsequent parser actions might lead +- to an incorrect destructor call or verbose syntax error message +- before the lookahead is translated. */ +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); +- +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- +- *++yyvsp = yyval; +- +- /* Now 'shift' the result of the reduction. Determine what state +- that goes to, based on the state we popped back to and the rule +- number reduced by. */ +- +- yyn = yyr1[yyn]; +- +- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +- yystate = yytable[yystate]; +- else +- yystate = yydefgoto[yyn - YYNTOKENS]; +- +- goto yynewstate; +- +- +-/*--------------------------------------. +-| yyerrlab -- here on detecting error. | +-`--------------------------------------*/ +-yyerrlab: +- /* Make sure we have latest lookahead translation. See comments at +- user semantic actions for why this is necessary. */ +- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); +- +- /* If not already recovering from an error, report this error. */ +- if (!yyerrstatus) +- { +- ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (YY_("syntax error")); +-#else +-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ +- yyssp, yytoken) +- { +- char const *yymsgp = YY_("syntax error"); +- int yysyntax_error_status; +- yysyntax_error_status = YYSYNTAX_ERROR; +- if (yysyntax_error_status == 0) +- yymsgp = yymsg; +- else if (yysyntax_error_status == 1) +- { +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); +- if (!yymsg) +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- yysyntax_error_status = 2; +- } +- else +- { +- yysyntax_error_status = YYSYNTAX_ERROR; +- yymsgp = yymsg; +- } +- } +- yyerror (yymsgp); +- if (yysyntax_error_status == 2) +- goto yyexhaustedlab; +- } +-# undef YYSYNTAX_ERROR +-#endif +- } +- +- +- +- if (yyerrstatus == 3) +- { +- /* If just tried and failed to reuse lookahead token after an +- error, discard it. */ +- +- if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } +- else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } +- } +- +- /* Else will try to reuse lookahead token after shifting the error +- token. */ +- goto yyerrlab1; +- +- +-/*---------------------------------------------------. +-| yyerrorlab -- error raised explicitly by YYERROR. | +-`---------------------------------------------------*/ +-yyerrorlab: +- +- /* Pacify compilers like GCC when the user code never invokes +- YYERROR and the label yyerrorlab therefore never appears in user +- code. */ +- if (/*CONSTCOND*/ 0) +- goto yyerrorlab; +- +- /* Do not reclaim the symbols of the rule whose action triggered +- this YYERROR. */ +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- yystate = *yyssp; +- goto yyerrlab1; +- +- +-/*-------------------------------------------------------------. +-| yyerrlab1 -- common code for both syntax error and YYERROR. | +-`-------------------------------------------------------------*/ +-yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ +- +- for (;;) +- { +- yyn = yypact[yystate]; +- if (!yypact_value_is_default (yyn)) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } +- +- /* Pop the current state because it cannot handle the error token. */ +- if (yyssp == yyss) +- YYABORT; +- +- +- yydestruct ("Error: popping", +- yystos[yystate], yyvsp); +- YYPOPSTACK (1); +- yystate = *yyssp; +- YY_STACK_PRINT (yyss, yyssp); +- } +- +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END +- +- +- /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +- +- yystate = yyn; +- goto yynewstate; +- +- +-/*-------------------------------------. +-| yyacceptlab -- YYACCEPT comes here. | +-`-------------------------------------*/ +-yyacceptlab: +- yyresult = 0; +- goto yyreturn; +- +-/*-----------------------------------. +-| yyabortlab -- YYABORT comes here. | +-`-----------------------------------*/ +-yyabortlab: +- yyresult = 1; +- goto yyreturn; +- +-#if !defined yyoverflow || YYERROR_VERBOSE +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ +-yyexhaustedlab: +- yyerror (YY_("memory exhausted")); +- yyresult = 2; +- /* Fall through. */ +-#endif +- +-yyreturn: +- if (yychar != YYEMPTY) +- { +- /* Make sure we have latest lookahead translation. See comments at +- user semantic actions for why this is necessary. */ +- yytoken = YYTRANSLATE (yychar); +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); +- } +- /* Do not reclaim the symbols of the rule whose action triggered +- this YYABORT or YYACCEPT. */ +- YYPOPSTACK (yylen); +- YY_STACK_PRINT (yyss, yyssp); +- while (yyssp != yyss) +- { +- yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); +- YYPOPSTACK (1); +- } +-#ifndef yyoverflow +- if (yyss != yyssa) +- YYSTACK_FREE (yyss); +-#endif +-#if YYERROR_VERBOSE +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +-#endif +- return yyresult; +-} +-#line 1677 "pic.y" /* yacc.c:1906 */ +- +- +-/* bison defines const to be empty unless __STDC__ is defined, which it +-isn't under cfront */ +- +-#ifdef const +-#undef const +-#endif +- +-static struct { +- const char *name; +- double val; +- int scaled; // non-zero if val should be multiplied by scale +-} defaults_table[] = { +- { "arcrad", .25, 1 }, +- { "arrowht", .1, 1 }, +- { "arrowwid", .05, 1 }, +- { "circlerad", .25, 1 }, +- { "boxht", .5, 1 }, +- { "boxwid", .75, 1 }, +- { "boxrad", 0.0, 1 }, +- { "dashwid", .05, 1 }, +- { "ellipseht", .5, 1 }, +- { "ellipsewid", .75, 1 }, +- { "moveht", .5, 1 }, +- { "movewid", .5, 1 }, +- { "lineht", .5, 1 }, +- { "linewid", .5, 1 }, +- { "textht", 0.0, 1 }, +- { "textwid", 0.0, 1 }, +- { "scale", 1.0, 0 }, +- { "linethick", -1.0, 0 }, // in points +- { "fillval", .5, 0 }, +- { "arrowhead", 1.0, 0 }, +- { "maxpswid", 8.5, 0 }, +- { "maxpsht", 11.0, 0 }, +-}; +- +-place *lookup_label(const char *label) +-{ +- saved_state *state = current_saved_state; +- PTABLE(place) *tbl = current_table; +- for (;;) { +- place *pl = tbl->lookup(label); +- if (pl) +- return pl; +- if (!state) +- return 0; +- tbl = state->tbl; +- state = state->prev; +- } +-} +- +-void define_label(const char *label, const place *pl) +-{ +- place *p = new place[1]; +- *p = *pl; +- current_table->define(label, p); +-} +- +-int lookup_variable(const char *name, double *val) +-{ +- place *pl = lookup_label(name); +- if (pl) { +- *val = pl->x; +- return 1; +- } +- return 0; +-} +- +-void define_variable(const char *name, double val) +-{ +- place *p = new place[1]; +- p->obj = 0; +- p->x = val; +- p->y = 0.0; +- current_table->define(name, p); +- if (strcmp(name, "scale") == 0) { +- // When the scale changes, reset all scaled pre-defined variables to +- // their default values. +- for (unsigned int i = 0; +- i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) +- if (defaults_table[i].scaled) +- define_variable(defaults_table[i].name, val*defaults_table[i].val); +- } +-} +- +-// called once only (not once per parse) +- +-void parse_init() +-{ +- current_direction = RIGHT_DIRECTION; +- current_position.x = 0.0; +- current_position.y = 0.0; +- // This resets everything to its default value. +- reset_all(); +-} +- +-void reset(const char *nm) +-{ +- for (unsigned int i = 0; +- i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) +- if (strcmp(nm, defaults_table[i].name) == 0) { +- double val = defaults_table[i].val; +- if (defaults_table[i].scaled) { +- double scale; +- lookup_variable("scale", &scale); +- val *= scale; +- } +- define_variable(defaults_table[i].name, val); +- return; +- } +- lex_error("`%1' is not a predefined variable", nm); +-} +- +-void reset_all() +-{ +- // We only have to explicitly reset the pre-defined variables that +- // aren't scaled because `scale' is not scaled, and changing the +- // value of `scale' will reset all the pre-defined variables that +- // are scaled. +- for (unsigned int i = 0; +- i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) +- if (!defaults_table[i].scaled) +- define_variable(defaults_table[i].name, defaults_table[i].val); +-} +- +-// called after each parse +- +-void parse_cleanup() +-{ +- while (current_saved_state != 0) { +- delete current_table; +- current_table = current_saved_state->tbl; +- saved_state *tem = current_saved_state; +- current_saved_state = current_saved_state->prev; +- delete tem; +- } +- assert(current_table == &top_table); +- PTABLE_ITERATOR(place) iter(current_table); +- const char *key; +- place *pl; +- while (iter.next(&key, &pl)) +- if (pl->obj != 0) { +- position pos = pl->obj->origin(); +- pl->obj = 0; +- pl->x = pos.x; +- pl->y = pos.y; +- } +- while (olist.head != 0) { +- object *tem = olist.head; +- olist.head = olist.head->next; +- delete tem; +- } +- olist.tail = 0; +- current_direction = RIGHT_DIRECTION; +- current_position.x = 0.0; +- current_position.y = 0.0; +-} +- +-const char *ordinal_postfix(int n) +-{ +- if (n < 10 || n > 20) +- switch (n % 10) { +- case 1: +- return "st"; +- case 2: +- return "nd"; +- case 3: +- return "rd"; +- } +- return "th"; +-} +- +-const char *object_type_name(object_type type) +-{ +- switch (type) { +- case BOX_OBJECT: +- return "box"; +- case CIRCLE_OBJECT: +- return "circle"; +- case ELLIPSE_OBJECT: +- return "ellipse"; +- case ARC_OBJECT: +- return "arc"; +- case SPLINE_OBJECT: +- return "spline"; +- case LINE_OBJECT: +- return "line"; +- case ARROW_OBJECT: +- return "arrow"; +- case MOVE_OBJECT: +- return "move"; +- case TEXT_OBJECT: +- return "\"\""; +- case BLOCK_OBJECT: +- return "[]"; +- case OTHER_OBJECT: +- case MARK_OBJECT: +- default: +- break; +- } +- return "object"; +-} +- +-static char sprintf_buf[1024]; +- +-char *format_number(const char *form, double n) +-{ +- if (form == 0) +- form = "%g"; +- return do_sprintf(form, &n, 1); +-} +- +-char *do_sprintf(const char *form, const double *v, int nv) +-{ +- string result; +- int i = 0; +- string one_format; +- while (*form) { +- if (*form == '%') { +- one_format += *form++; +- for (; *form != '\0' && strchr("#-+ 0123456789.", *form) != 0; form++) +- one_format += *form; +- if (*form == '\0' || strchr("eEfgG%", *form) == 0) { +- lex_error("bad sprintf format"); +- result += one_format; +- result += form; +- break; +- } +- if (*form == '%') { +- one_format += *form++; +- one_format += '\0'; +- snprintf(sprintf_buf, sizeof(sprintf_buf), +- "%s", one_format.contents()); +- } +- else { +- if (i >= nv) { +- lex_error("too few arguments to snprintf"); +- result += one_format; +- result += form; +- break; +- } +- one_format += *form++; +- one_format += '\0'; +- snprintf(sprintf_buf, sizeof(sprintf_buf), +- one_format.contents(), v[i++]); +- } +- one_format.clear(); +- result += sprintf_buf; +- } +- else +- result += *form++; +- } +- result += '\0'; +- return strsave(result.contents()); +-} +diff -Nuar groff-1.22.3.old/src/preproc/pic/pic.h groff-1.22.3/src/preproc/pic/pic.h +--- groff-1.22.3.old/src/preproc/pic/pic.h 2014-11-04 10:38:35.226523984 +0200 ++++ groff-1.22.3/src/preproc/pic/pic.h 2015-04-23 20:57:03.000000000 +0300 +@@ -50,6 +50,7 @@ + #include "assert.h" + #include "cset.h" + #include "stringclass.h" ++#include "lf.h" + #include "errarg.h" + #include "error.h" + #include "position.h" +diff -Nuar groff-1.22.3.old/src/preproc/pic/pic.man groff-1.22.3/src/preproc/pic/pic.man +--- groff-1.22.3.old/src/preproc/pic/pic.man 2014-11-04 10:38:35.226523984 +0200 ++++ groff-1.22.3/src/preproc/pic/pic.man 2015-04-23 20:57:03.000000000 +0300 +@@ -3,6 +3,10 @@ + @g@pic \- compile pictures for troff or TeX + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" License (copying) + .\" -------------------------------------------------------------------- +@@ -1343,6 +1347,9 @@ + .co + . + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" mode: nroff + .\" End: +diff -Nuar groff-1.22.3.old/src/preproc/pic/pic_tab.h groff-1.22.3/src/preproc/pic/pic_tab.h +--- groff-1.22.3.old/src/preproc/pic/pic_tab.h 2014-11-04 10:38:37.791491918 +0200 ++++ groff-1.22.3/src/preproc/pic/pic_tab.h 1970-01-01 02:00:00.000000000 +0200 +@@ -1,331 +0,0 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ +- +-/* Bison interface for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation, either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-#ifndef YY_YY_Y_TAB_H_INCLUDED +-# define YY_YY_Y_TAB_H_INCLUDED +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; +-#endif +- +-/* Token type. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- enum yytokentype +- { +- LABEL = 258, +- VARIABLE = 259, +- NUMBER = 260, +- TEXT = 261, +- COMMAND_LINE = 262, +- DELIMITED = 263, +- ORDINAL = 264, +- TH = 265, +- LEFT_ARROW_HEAD = 266, +- RIGHT_ARROW_HEAD = 267, +- DOUBLE_ARROW_HEAD = 268, +- LAST = 269, +- BOX = 270, +- CIRCLE = 271, +- ELLIPSE = 272, +- ARC = 273, +- LINE = 274, +- ARROW = 275, +- MOVE = 276, +- SPLINE = 277, +- HEIGHT = 278, +- RADIUS = 279, +- FIGNAME = 280, +- WIDTH = 281, +- DIAMETER = 282, +- UP = 283, +- DOWN = 284, +- RIGHT = 285, +- LEFT = 286, +- FROM = 287, +- TO = 288, +- AT = 289, +- WITH = 290, +- BY = 291, +- THEN = 292, +- SOLID = 293, +- DOTTED = 294, +- DASHED = 295, +- CHOP = 296, +- SAME = 297, +- INVISIBLE = 298, +- LJUST = 299, +- RJUST = 300, +- ABOVE = 301, +- BELOW = 302, +- OF = 303, +- THE = 304, +- WAY = 305, +- BETWEEN = 306, +- AND = 307, +- HERE = 308, +- DOT_N = 309, +- DOT_E = 310, +- DOT_W = 311, +- DOT_S = 312, +- DOT_NE = 313, +- DOT_SE = 314, +- DOT_NW = 315, +- DOT_SW = 316, +- DOT_C = 317, +- DOT_START = 318, +- DOT_END = 319, +- DOT_X = 320, +- DOT_Y = 321, +- DOT_HT = 322, +- DOT_WID = 323, +- DOT_RAD = 324, +- SIN = 325, +- COS = 326, +- ATAN2 = 327, +- LOG = 328, +- EXP = 329, +- SQRT = 330, +- K_MAX = 331, +- K_MIN = 332, +- INT = 333, +- RAND = 334, +- SRAND = 335, +- COPY = 336, +- THRU = 337, +- TOP = 338, +- BOTTOM = 339, +- UPPER = 340, +- LOWER = 341, +- SH = 342, +- PRINT = 343, +- CW = 344, +- CCW = 345, +- FOR = 346, +- DO = 347, +- IF = 348, +- ELSE = 349, +- ANDAND = 350, +- OROR = 351, +- NOTEQUAL = 352, +- EQUALEQUAL = 353, +- LESSEQUAL = 354, +- GREATEREQUAL = 355, +- LEFT_CORNER = 356, +- RIGHT_CORNER = 357, +- NORTH = 358, +- SOUTH = 359, +- EAST = 360, +- WEST = 361, +- CENTER = 362, +- END = 363, +- START = 364, +- RESET = 365, +- UNTIL = 366, +- PLOT = 367, +- THICKNESS = 368, +- FILL = 369, +- COLORED = 370, +- OUTLINED = 371, +- SHADED = 372, +- XSLANTED = 373, +- YSLANTED = 374, +- ALIGNED = 375, +- SPRINTF = 376, +- COMMAND = 377, +- DEFINE = 378, +- UNDEF = 379 +- }; +-#endif +-/* Tokens. */ +-#define LABEL 258 +-#define VARIABLE 259 +-#define NUMBER 260 +-#define TEXT 261 +-#define COMMAND_LINE 262 +-#define DELIMITED 263 +-#define ORDINAL 264 +-#define TH 265 +-#define LEFT_ARROW_HEAD 266 +-#define RIGHT_ARROW_HEAD 267 +-#define DOUBLE_ARROW_HEAD 268 +-#define LAST 269 +-#define BOX 270 +-#define CIRCLE 271 +-#define ELLIPSE 272 +-#define ARC 273 +-#define LINE 274 +-#define ARROW 275 +-#define MOVE 276 +-#define SPLINE 277 +-#define HEIGHT 278 +-#define RADIUS 279 +-#define FIGNAME 280 +-#define WIDTH 281 +-#define DIAMETER 282 +-#define UP 283 +-#define DOWN 284 +-#define RIGHT 285 +-#define LEFT 286 +-#define FROM 287 +-#define TO 288 +-#define AT 289 +-#define WITH 290 +-#define BY 291 +-#define THEN 292 +-#define SOLID 293 +-#define DOTTED 294 +-#define DASHED 295 +-#define CHOP 296 +-#define SAME 297 +-#define INVISIBLE 298 +-#define LJUST 299 +-#define RJUST 300 +-#define ABOVE 301 +-#define BELOW 302 +-#define OF 303 +-#define THE 304 +-#define WAY 305 +-#define BETWEEN 306 +-#define AND 307 +-#define HERE 308 +-#define DOT_N 309 +-#define DOT_E 310 +-#define DOT_W 311 +-#define DOT_S 312 +-#define DOT_NE 313 +-#define DOT_SE 314 +-#define DOT_NW 315 +-#define DOT_SW 316 +-#define DOT_C 317 +-#define DOT_START 318 +-#define DOT_END 319 +-#define DOT_X 320 +-#define DOT_Y 321 +-#define DOT_HT 322 +-#define DOT_WID 323 +-#define DOT_RAD 324 +-#define SIN 325 +-#define COS 326 +-#define ATAN2 327 +-#define LOG 328 +-#define EXP 329 +-#define SQRT 330 +-#define K_MAX 331 +-#define K_MIN 332 +-#define INT 333 +-#define RAND 334 +-#define SRAND 335 +-#define COPY 336 +-#define THRU 337 +-#define TOP 338 +-#define BOTTOM 339 +-#define UPPER 340 +-#define LOWER 341 +-#define SH 342 +-#define PRINT 343 +-#define CW 344 +-#define CCW 345 +-#define FOR 346 +-#define DO 347 +-#define IF 348 +-#define ELSE 349 +-#define ANDAND 350 +-#define OROR 351 +-#define NOTEQUAL 352 +-#define EQUALEQUAL 353 +-#define LESSEQUAL 354 +-#define GREATEREQUAL 355 +-#define LEFT_CORNER 356 +-#define RIGHT_CORNER 357 +-#define NORTH 358 +-#define SOUTH 359 +-#define EAST 360 +-#define WEST 361 +-#define CENTER 362 +-#define END 363 +-#define START 364 +-#define RESET 365 +-#define UNTIL 366 +-#define PLOT 367 +-#define THICKNESS 368 +-#define FILL 369 +-#define COLORED 370 +-#define OUTLINED 371 +-#define SHADED 372 +-#define XSLANTED 373 +-#define YSLANTED 374 +-#define ALIGNED 375 +-#define SPRINTF 376 +-#define COMMAND 377 +-#define DEFINE 378 +-#define UNDEF 379 +- +-/* Value type. */ +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE +-{ +-#line 65 "pic.y" /* yacc.c:1909 */ +- +- char *str; +- int n; +- double x; +- struct { double x, y; } pair; +- struct { double x; char *body; } if_data; +- struct { char *str; const char *filename; int lineno; } lstr; +- struct { double *v; int nv; int maxv; } dv; +- struct { double val; int is_multiplicative; } by; +- place pl; +- object *obj; +- corner crn; +- path *pth; +- object_spec *spec; +- saved_state *pstate; +- graphics_state state; +- object_type obtype; +- +-#line 321 "y.tab.h" /* yacc.c:1909 */ +-}; +-# define YYSTYPE_IS_TRIVIAL 1 +-# define YYSTYPE_IS_DECLARED 1 +-#endif +- +- +-extern YYSTYPE yylval; +- +-int yyparse (void); +- +-#endif /* !YY_YY_Y_TAB_H_INCLUDED */ +diff -Nuar groff-1.22.3.old/src/preproc/pic/pic.y groff-1.22.3/src/preproc/pic/pic.y +--- groff-1.22.3.old/src/preproc/pic/pic.y 2014-11-04 10:38:35.226523984 +0200 ++++ groff-1.22.3/src/preproc/pic/pic.y 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1933 +0,0 @@ +-/* Copyright (C) 1989-2014 Free Software Foundation, Inc. +- Written by James Clark (jjc@jclark.com) +- +-This file is part of groff. +- +-groff is free software; you can redistribute it and/or modify it under +-the terms of the GNU General Public License as published by the Free +-Software Foundation, either version 3 of the License, or +-(at your option) any later version. +- +-groff is distributed in the hope that it will be useful, but WITHOUT ANY +-WARRANTY; without even the implied warranty of MERCHANTABILITY or +-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-for more details. +- +-You should have received a copy of the GNU General Public License +-along with this program. If not, see . */ +- +-%{ +-#include "pic.h" +-#include "ptable.h" +-#include "object.h" +- +-extern int delim_flag; +-extern void copy_rest_thru(const char *, const char *); +-extern void copy_file_thru(const char *, const char *, const char *); +-extern void push_body(const char *); +-extern void do_for(char *var, double from, double to, +- int by_is_multiplicative, double by, char *body); +-extern void do_lookahead(); +- +-/* Maximum number of characters produced by printf("%g") */ +-#define GDIGITS 14 +- +-int yylex(); +-void yyerror(const char *); +- +-void reset(const char *nm); +-void reset_all(); +- +-place *lookup_label(const char *); +-void define_label(const char *label, const place *pl); +- +-direction current_direction; +-position current_position; +- +-implement_ptable(place) +- +-PTABLE(place) top_table; +- +-PTABLE(place) *current_table = &top_table; +-saved_state *current_saved_state = 0; +- +-object_list olist; +- +-const char *ordinal_postfix(int n); +-const char *object_type_name(object_type type); +-char *format_number(const char *form, double n); +-char *do_sprintf(const char *form, const double *v, int nv); +- +-%} +- +-%expect 2 +- +-%union { +- char *str; +- int n; +- double x; +- struct { double x, y; } pair; +- struct { double x; char *body; } if_data; +- struct { char *str; const char *filename; int lineno; } lstr; +- struct { double *v; int nv; int maxv; } dv; +- struct { double val; int is_multiplicative; } by; +- place pl; +- object *obj; +- corner crn; +- path *pth; +- object_spec *spec; +- saved_state *pstate; +- graphics_state state; +- object_type obtype; +-} +- +-%token LABEL +-%token VARIABLE +-%token NUMBER +-%token TEXT +-%token COMMAND_LINE +-%token DELIMITED +-%token ORDINAL +-%token TH +-%token LEFT_ARROW_HEAD +-%token RIGHT_ARROW_HEAD +-%token DOUBLE_ARROW_HEAD +-%token LAST +-%token BOX +-%token CIRCLE +-%token ELLIPSE +-%token ARC +-%token LINE +-%token ARROW +-%token MOVE +-%token SPLINE +-%token HEIGHT +-%token RADIUS +-%token FIGNAME +-%token WIDTH +-%token DIAMETER +-%token UP +-%token DOWN +-%token RIGHT +-%token LEFT +-%token FROM +-%token TO +-%token AT +-%token WITH +-%token BY +-%token THEN +-%token SOLID +-%token DOTTED +-%token DASHED +-%token CHOP +-%token SAME +-%token INVISIBLE +-%token LJUST +-%token RJUST +-%token ABOVE +-%token BELOW +-%token OF +-%token THE +-%token WAY +-%token BETWEEN +-%token AND +-%token HERE +-%token DOT_N +-%token DOT_E +-%token DOT_W +-%token DOT_S +-%token DOT_NE +-%token DOT_SE +-%token DOT_NW +-%token DOT_SW +-%token DOT_C +-%token DOT_START +-%token DOT_END +-%token DOT_X +-%token DOT_Y +-%token DOT_HT +-%token DOT_WID +-%token DOT_RAD +-%token SIN +-%token COS +-%token ATAN2 +-%token LOG +-%token EXP +-%token SQRT +-%token K_MAX +-%token K_MIN +-%token INT +-%token RAND +-%token SRAND +-%token COPY +-%token THRU +-%token TOP +-%token BOTTOM +-%token UPPER +-%token LOWER +-%token SH +-%token PRINT +-%token CW +-%token CCW +-%token FOR +-%token DO +-%token IF +-%token ELSE +-%token ANDAND +-%token OROR +-%token NOTEQUAL +-%token EQUALEQUAL +-%token LESSEQUAL +-%token GREATEREQUAL +-%token LEFT_CORNER +-%token RIGHT_CORNER +-%token NORTH +-%token SOUTH +-%token EAST +-%token WEST +-%token CENTER +-%token END +-%token START +-%token RESET +-%token UNTIL +-%token PLOT +-%token THICKNESS +-%token FILL +-%token COLORED +-%token OUTLINED +-%token SHADED +-%token XSLANTED +-%token YSLANTED +-%token ALIGNED +-%token SPRINTF +-%token COMMAND +- +-%token DEFINE +-%token UNDEF +- +-%left '.' +- +-/* this ensures that plot 17 "%g" parses as (plot 17 "%g") */ +-%left PLOT +-%left TEXT SPRINTF +- +-/* give text adjustments higher precedence than TEXT, so that +-box "foo" above ljust == box ("foo" above ljust) +-*/ +- +-%left LJUST RJUST ABOVE BELOW +- +-%left LEFT RIGHT +-/* Give attributes that take an optional expression a higher +-precedence than left and right, so that eg `line chop left' +-parses properly. */ +-%left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED +-%left XSLANTED YSLANTED +-%left LABEL +- +-%left VARIABLE NUMBER '(' SIN COS ATAN2 LOG EXP SQRT K_MAX K_MIN INT RAND SRAND LAST +-%left ORDINAL HERE '`' +- +-%left BOX CIRCLE ELLIPSE ARC LINE ARROW SPLINE '[' +- +-/* these need to be lower than '-' */ +-%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS +- +-/* these must have higher precedence than CHOP so that `label %prec CHOP' +-works */ +-%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C +-%left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER +-%left UPPER LOWER NORTH SOUTH EAST WEST CENTER START END +- +-%left ',' +-%left OROR +-%left ANDAND +-%left EQUALEQUAL NOTEQUAL +-%left '<' '>' LESSEQUAL GREATEREQUAL +- +-%left BETWEEN OF +-%left AND +- +-%left '+' '-' +-%left '*' '/' '%' +-%right '!' +-%right '^' +- +-%type expr expr_lower_than expr_not_lower_than any_expr text_expr +-%type optional_by +-%type expr_pair position_not_place +-%type simple_if +-%type nth_primitive +-%type corner +-%type path label_path relative_path +-%type place label element element_list middle_element_list +-%type object_spec +-%type position +-%type object_type +-%type optional_ordinal_last ordinal +-%type macro_name until +-%type sprintf_args +-%type text print_args print_arg +- +-%% +- +-top: +- optional_separator +- | element_list +- { +- if (olist.head) +- print_picture(olist.head); +- } +- ; +- +- +-element_list: +- optional_separator middle_element_list optional_separator +- { $$ = $2; } +- ; +- +-middle_element_list: +- element +- { $$ = $1; } +- | middle_element_list separator element +- { $$ = $1; } +- ; +- +-optional_separator: +- /* empty */ +- | separator +- ; +- +-separator: +- ';' +- | separator ';' +- ; +- +-placeless_element: +- FIGNAME '=' macro_name +- { +- a_delete graphname; +- graphname = new char[strlen($3) + 1]; +- strcpy(graphname, $3); +- a_delete $3; +- } +- | +- VARIABLE '=' any_expr +- { +- define_variable($1, $3); +- a_delete $1; +- } +- | VARIABLE ':' '=' any_expr +- { +- place *p = lookup_label($1); +- if (!p) { +- lex_error("variable `%1' not defined", $1); +- YYABORT; +- } +- p->obj = 0; +- p->x = $4; +- p->y = 0.0; +- a_delete $1; +- } +- | UP +- { current_direction = UP_DIRECTION; } +- | DOWN +- { current_direction = DOWN_DIRECTION; } +- | LEFT +- { current_direction = LEFT_DIRECTION; } +- | RIGHT +- { current_direction = RIGHT_DIRECTION; } +- | COMMAND_LINE +- { +- olist.append(make_command_object($1.str, $1.filename, +- $1.lineno)); +- } +- | COMMAND print_args +- { +- olist.append(make_command_object($2.str, $2.filename, +- $2.lineno)); +- } +- | PRINT print_args +- { +- fprintf(stderr, "%s\n", $2.str); +- a_delete $2.str; +- fflush(stderr); +- } +- | SH +- { delim_flag = 1; } +- DELIMITED +- { +- delim_flag = 0; +- if (safer_flag) +- lex_error("unsafe to run command `%1'", $3); +- else +- system($3); +- a_delete $3; +- } +- | COPY TEXT +- { +- if (yychar < 0) +- do_lookahead(); +- do_copy($2.str); +- // do not delete the filename +- } +- | COPY TEXT THRU +- { delim_flag = 2; } +- DELIMITED +- { delim_flag = 0; } +- until +- { +- if (yychar < 0) +- do_lookahead(); +- copy_file_thru($2.str, $5, $7); +- // do not delete the filename +- a_delete $5; +- a_delete $7; +- } +- | COPY THRU +- { delim_flag = 2; } +- DELIMITED +- { delim_flag = 0; } +- until +- { +- if (yychar < 0) +- do_lookahead(); +- copy_rest_thru($4, $6); +- a_delete $4; +- a_delete $6; +- } +- | FOR VARIABLE '=' expr TO expr optional_by DO +- { delim_flag = 1; } +- DELIMITED +- { +- delim_flag = 0; +- if (yychar < 0) +- do_lookahead(); +- do_for($2, $4, $6, $7.is_multiplicative, $7.val, $10); +- } +- | simple_if +- { +- if (yychar < 0) +- do_lookahead(); +- if ($1.x != 0.0) +- push_body($1.body); +- a_delete $1.body; +- } +- | simple_if ELSE +- { delim_flag = 1; } +- DELIMITED +- { +- delim_flag = 0; +- if (yychar < 0) +- do_lookahead(); +- if ($1.x != 0.0) +- push_body($1.body); +- else +- push_body($4); +- a_delete $1.body; +- a_delete $4; +- } +- | reset_variables +- | RESET +- { define_variable("scale", 1.0); } +- ; +- +-macro_name: +- VARIABLE +- | LABEL +- ; +- +-reset_variables: +- RESET VARIABLE +- { +- reset($2); +- a_delete $2; +- } +- | reset_variables VARIABLE +- { +- reset($2); +- a_delete $2; +- } +- | reset_variables ',' VARIABLE +- { +- reset($3); +- a_delete $3; +- } +- ; +- +-print_args: +- print_arg +- { $$ = $1; } +- | print_args print_arg +- { +- $$.str = new char[strlen($1.str) + strlen($2.str) + 1]; +- strcpy($$.str, $1.str); +- strcat($$.str, $2.str); +- a_delete $1.str; +- a_delete $2.str; +- if ($1.filename) { +- $$.filename = $1.filename; +- $$.lineno = $1.lineno; +- } +- else if ($2.filename) { +- $$.filename = $2.filename; +- $$.lineno = $2.lineno; +- } +- } +- ; +- +-print_arg: +- expr %prec ',' +- { +- $$.str = new char[GDIGITS + 1]; +- sprintf($$.str, "%g", $1); +- $$.filename = 0; +- $$.lineno = 0; +- } +- | text +- { $$ = $1; } +- | position %prec ',' +- { +- $$.str = new char[GDIGITS + 2 + GDIGITS + 1]; +- sprintf($$.str, "%g, %g", $1.x, $1.y); +- $$.filename = 0; +- $$.lineno = 0; +- } +- ; +- +-simple_if: +- IF any_expr THEN +- { delim_flag = 1; } +- DELIMITED +- { +- delim_flag = 0; +- $$.x = $2; +- $$.body = $5; +- } +- ; +- +-until: +- /* empty */ +- { $$ = 0; } +- | UNTIL TEXT +- { $$ = $2.str; } +- ; +- +-any_expr: +- expr +- { $$ = $1; } +- | text_expr +- { $$ = $1; } +- ; +- +-text_expr: +- text EQUALEQUAL text +- { +- $$ = strcmp($1.str, $3.str) == 0; +- a_delete $1.str; +- a_delete $3.str; +- } +- | text NOTEQUAL text +- { +- $$ = strcmp($1.str, $3.str) != 0; +- a_delete $1.str; +- a_delete $3.str; +- } +- | text_expr ANDAND text_expr +- { $$ = ($1 != 0.0 && $3 != 0.0); } +- | text_expr ANDAND expr +- { $$ = ($1 != 0.0 && $3 != 0.0); } +- | expr ANDAND text_expr +- { $$ = ($1 != 0.0 && $3 != 0.0); } +- | text_expr OROR text_expr +- { $$ = ($1 != 0.0 || $3 != 0.0); } +- | text_expr OROR expr +- { $$ = ($1 != 0.0 || $3 != 0.0); } +- | expr OROR text_expr +- { $$ = ($1 != 0.0 || $3 != 0.0); } +- | '!' text_expr +- { $$ = ($2 == 0.0); } +- ; +- +- +-optional_by: +- /* empty */ +- { +- $$.val = 1.0; +- $$.is_multiplicative = 0; +- } +- | BY expr +- { +- $$.val = $2; +- $$.is_multiplicative = 0; +- } +- | BY '*' expr +- { +- $$.val = $3; +- $$.is_multiplicative = 1; +- } +- ; +- +-element: +- object_spec +- { +- $$.obj = $1->make_object(¤t_position, +- ¤t_direction); +- if ($$.obj == 0) +- YYABORT; +- delete $1; +- if ($$.obj) +- olist.append($$.obj); +- else { +- $$.x = current_position.x; +- $$.y = current_position.y; +- } +- } +- | LABEL ':' optional_separator element +- { +- $$ = $4; +- define_label($1, & $$); +- a_delete $1; +- } +- | LABEL ':' optional_separator position_not_place +- { +- $$.obj = 0; +- $$.x = $4.x; +- $$.y = $4.y; +- define_label($1, & $$); +- a_delete $1; +- } +- | LABEL ':' optional_separator place +- { +- $$ = $4; +- define_label($1, & $$); +- a_delete $1; +- } +- | '{' +- { +- $$.x = current_position.x; +- $$.y = current_position.y; +- $$.dir = current_direction; +- } +- element_list '}' +- { +- current_position.x = $2.x; +- current_position.y = $2.y; +- current_direction = $2.dir; +- } +- optional_element +- { +- $$ = $3; +- } +- | placeless_element +- { +- $$.obj = 0; +- $$.x = current_position.x; +- $$.y = current_position.y; +- } +- ; +- +-optional_element: +- /* empty */ +- {} +- | element +- {} +- ; +- +-object_spec: +- BOX +- { $$ = new object_spec(BOX_OBJECT); } +- | CIRCLE +- { $$ = new object_spec(CIRCLE_OBJECT); } +- | ELLIPSE +- { $$ = new object_spec(ELLIPSE_OBJECT); } +- | ARC +- { +- $$ = new object_spec(ARC_OBJECT); +- $$->dir = current_direction; +- } +- | LINE +- { +- $$ = new object_spec(LINE_OBJECT); +- lookup_variable("lineht", & $$->segment_height); +- lookup_variable("linewid", & $$->segment_width); +- $$->dir = current_direction; +- } +- | ARROW +- { +- $$ = new object_spec(ARROW_OBJECT); +- lookup_variable("lineht", & $$->segment_height); +- lookup_variable("linewid", & $$->segment_width); +- $$->dir = current_direction; +- } +- | MOVE +- { +- $$ = new object_spec(MOVE_OBJECT); +- lookup_variable("moveht", & $$->segment_height); +- lookup_variable("movewid", & $$->segment_width); +- $$->dir = current_direction; +- } +- | SPLINE +- { +- $$ = new object_spec(SPLINE_OBJECT); +- lookup_variable("lineht", & $$->segment_height); +- lookup_variable("linewid", & $$->segment_width); +- $$->dir = current_direction; +- } +- | text %prec TEXT +- { +- $$ = new object_spec(TEXT_OBJECT); +- $$->text = new text_item($1.str, $1.filename, $1.lineno); +- } +- | PLOT expr +- { +- $$ = new object_spec(TEXT_OBJECT); +- $$->text = new text_item(format_number(0, $2), 0, -1); +- } +- | PLOT expr text +- { +- $$ = new object_spec(TEXT_OBJECT); +- $$->text = new text_item(format_number($3.str, $2), +- $3.filename, $3.lineno); +- a_delete $3.str; +- } +- | '[' +- { +- saved_state *p = new saved_state; +- $$ = p; +- p->x = current_position.x; +- p->y = current_position.y; +- p->dir = current_direction; +- p->tbl = current_table; +- p->prev = current_saved_state; +- current_position.x = 0.0; +- current_position.y = 0.0; +- current_table = new PTABLE(place); +- current_saved_state = p; +- olist.append(make_mark_object()); +- } +- element_list ']' +- { +- current_position.x = $2->x; +- current_position.y = $2->y; +- current_direction = $2->dir; +- $$ = new object_spec(BLOCK_OBJECT); +- olist.wrap_up_block(& $$->oblist); +- $$->tbl = current_table; +- current_table = $2->tbl; +- current_saved_state = $2->prev; +- delete $2; +- } +- | object_spec HEIGHT expr +- { +- $$ = $1; +- $$->height = $3; +- $$->flags |= HAS_HEIGHT; +- } +- | object_spec RADIUS expr +- { +- $$ = $1; +- $$->radius = $3; +- $$->flags |= HAS_RADIUS; +- } +- | object_spec WIDTH expr +- { +- $$ = $1; +- $$->width = $3; +- $$->flags |= HAS_WIDTH; +- } +- | object_spec DIAMETER expr +- { +- $$ = $1; +- $$->radius = $3/2.0; +- $$->flags |= HAS_RADIUS; +- } +- | object_spec expr %prec HEIGHT +- { +- $$ = $1; +- $$->flags |= HAS_SEGMENT; +- switch ($$->dir) { +- case UP_DIRECTION: +- $$->segment_pos.y += $2; +- break; +- case DOWN_DIRECTION: +- $$->segment_pos.y -= $2; +- break; +- case RIGHT_DIRECTION: +- $$->segment_pos.x += $2; +- break; +- case LEFT_DIRECTION: +- $$->segment_pos.x -= $2; +- break; +- } +- } +- | object_spec UP +- { +- $$ = $1; +- $$->dir = UP_DIRECTION; +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.y += $$->segment_height; +- } +- | object_spec UP expr +- { +- $$ = $1; +- $$->dir = UP_DIRECTION; +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.y += $3; +- } +- | object_spec DOWN +- { +- $$ = $1; +- $$->dir = DOWN_DIRECTION; +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.y -= $$->segment_height; +- } +- | object_spec DOWN expr +- { +- $$ = $1; +- $$->dir = DOWN_DIRECTION; +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.y -= $3; +- } +- | object_spec RIGHT +- { +- $$ = $1; +- $$->dir = RIGHT_DIRECTION; +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.x += $$->segment_width; +- } +- | object_spec RIGHT expr +- { +- $$ = $1; +- $$->dir = RIGHT_DIRECTION; +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.x += $3; +- } +- | object_spec LEFT +- { +- $$ = $1; +- $$->dir = LEFT_DIRECTION; +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.x -= $$->segment_width; +- } +- | object_spec LEFT expr +- { +- $$ = $1; +- $$->dir = LEFT_DIRECTION; +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.x -= $3; +- } +- | object_spec FROM position +- { +- $$ = $1; +- $$->flags |= HAS_FROM; +- $$->from.x = $3.x; +- $$->from.y = $3.y; +- } +- | object_spec TO position +- { +- $$ = $1; +- if ($$->flags & HAS_SEGMENT) +- $$->segment_list = new segment($$->segment_pos, +- $$->segment_is_absolute, +- $$->segment_list); +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.x = $3.x; +- $$->segment_pos.y = $3.y; +- $$->segment_is_absolute = 1; +- $$->flags |= HAS_TO; +- $$->to.x = $3.x; +- $$->to.y = $3.y; +- } +- | object_spec AT position +- { +- $$ = $1; +- $$->flags |= HAS_AT; +- $$->at.x = $3.x; +- $$->at.y = $3.y; +- if ($$->type != ARC_OBJECT) { +- $$->flags |= HAS_FROM; +- $$->from.x = $3.x; +- $$->from.y = $3.y; +- } +- } +- | object_spec WITH path +- { +- $$ = $1; +- $$->flags |= HAS_WITH; +- $$->with = $3; +- } +- | object_spec WITH position %prec ',' +- { +- $$ = $1; +- $$->flags |= HAS_WITH; +- position pos; +- pos.x = $3.x; +- pos.y = $3.y; +- $$->with = new path(pos); +- } +- | object_spec BY expr_pair +- { +- $$ = $1; +- $$->flags |= HAS_SEGMENT; +- $$->segment_pos.x += $3.x; +- $$->segment_pos.y += $3.y; +- } +- | object_spec THEN +- { +- $$ = $1; +- if (!($$->flags & HAS_SEGMENT)) +- switch ($$->dir) { +- case UP_DIRECTION: +- $$->segment_pos.y += $$->segment_width; +- break; +- case DOWN_DIRECTION: +- $$->segment_pos.y -= $$->segment_width; +- break; +- case RIGHT_DIRECTION: +- $$->segment_pos.x += $$->segment_width; +- break; +- case LEFT_DIRECTION: +- $$->segment_pos.x -= $$->segment_width; +- break; +- } +- $$->segment_list = new segment($$->segment_pos, +- $$->segment_is_absolute, +- $$->segment_list); +- $$->flags &= ~HAS_SEGMENT; +- $$->segment_pos.x = $$->segment_pos.y = 0.0; +- $$->segment_is_absolute = 0; +- } +- | object_spec SOLID +- { +- $$ = $1; // nothing +- } +- | object_spec DOTTED +- { +- $$ = $1; +- $$->flags |= IS_DOTTED; +- lookup_variable("dashwid", & $$->dash_width); +- } +- | object_spec DOTTED expr +- { +- $$ = $1; +- $$->flags |= IS_DOTTED; +- $$->dash_width = $3; +- } +- | object_spec DASHED +- { +- $$ = $1; +- $$->flags |= IS_DASHED; +- lookup_variable("dashwid", & $$->dash_width); +- } +- | object_spec DASHED expr +- { +- $$ = $1; +- $$->flags |= IS_DASHED; +- $$->dash_width = $3; +- } +- | object_spec FILL +- { +- $$ = $1; +- $$->flags |= IS_DEFAULT_FILLED; +- } +- | object_spec FILL expr +- { +- $$ = $1; +- $$->flags |= IS_FILLED; +- $$->fill = $3; +- } +- | object_spec XSLANTED expr +- { +- $$ = $1; +- $$->flags |= IS_XSLANTED; +- $$->xslanted = $3; +- } +- | object_spec YSLANTED expr +- { +- $$ = $1; +- $$->flags |= IS_YSLANTED; +- $$->yslanted = $3; +- } +- | object_spec SHADED text +- { +- $$ = $1; +- $$->flags |= (IS_SHADED | IS_FILLED); +- $$->shaded = new char[strlen($3.str)+1]; +- strcpy($$->shaded, $3.str); +- } +- | object_spec COLORED text +- { +- $$ = $1; +- $$->flags |= (IS_SHADED | IS_OUTLINED | IS_FILLED); +- $$->shaded = new char[strlen($3.str)+1]; +- strcpy($$->shaded, $3.str); +- $$->outlined = new char[strlen($3.str)+1]; +- strcpy($$->outlined, $3.str); +- } +- | object_spec OUTLINED text +- { +- $$ = $1; +- $$->flags |= IS_OUTLINED; +- $$->outlined = new char[strlen($3.str)+1]; +- strcpy($$->outlined, $3.str); +- } +- | object_spec CHOP +- { +- $$ = $1; +- // line chop chop means line chop 0 chop 0 +- if ($$->flags & IS_DEFAULT_CHOPPED) { +- $$->flags |= IS_CHOPPED; +- $$->flags &= ~IS_DEFAULT_CHOPPED; +- $$->start_chop = $$->end_chop = 0.0; +- } +- else if ($$->flags & IS_CHOPPED) { +- $$->end_chop = 0.0; +- } +- else { +- $$->flags |= IS_DEFAULT_CHOPPED; +- } +- } +- | object_spec CHOP expr +- { +- $$ = $1; +- if ($$->flags & IS_DEFAULT_CHOPPED) { +- $$->flags |= IS_CHOPPED; +- $$->flags &= ~IS_DEFAULT_CHOPPED; +- $$->start_chop = 0.0; +- $$->end_chop = $3; +- } +- else if ($$->flags & IS_CHOPPED) { +- $$->end_chop = $3; +- } +- else { +- $$->start_chop = $$->end_chop = $3; +- $$->flags |= IS_CHOPPED; +- } +- } +- | object_spec SAME +- { +- $$ = $1; +- $$->flags |= IS_SAME; +- } +- | object_spec INVISIBLE +- { +- $$ = $1; +- $$->flags |= IS_INVISIBLE; +- } +- | object_spec LEFT_ARROW_HEAD +- { +- $$ = $1; +- $$->flags |= HAS_LEFT_ARROW_HEAD; +- } +- | object_spec RIGHT_ARROW_HEAD +- { +- $$ = $1; +- $$->flags |= HAS_RIGHT_ARROW_HEAD; +- } +- | object_spec DOUBLE_ARROW_HEAD +- { +- $$ = $1; +- $$->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD); +- } +- | object_spec CW +- { +- $$ = $1; +- $$->flags |= IS_CLOCKWISE; +- } +- | object_spec CCW +- { +- $$ = $1; +- $$->flags &= ~IS_CLOCKWISE; +- } +- | object_spec text %prec TEXT +- { +- $$ = $1; +- text_item **p; +- for (p = & $$->text; *p; p = &(*p)->next) +- ; +- *p = new text_item($2.str, $2.filename, $2.lineno); +- } +- | object_spec LJUST +- { +- $$ = $1; +- if ($$->text) { +- text_item *p; +- for (p = $$->text; p->next; p = p->next) +- ; +- p->adj.h = LEFT_ADJUST; +- } +- } +- | object_spec RJUST +- { +- $$ = $1; +- if ($$->text) { +- text_item *p; +- for (p = $$->text; p->next; p = p->next) +- ; +- p->adj.h = RIGHT_ADJUST; +- } +- } +- | object_spec ABOVE +- { +- $$ = $1; +- if ($$->text) { +- text_item *p; +- for (p = $$->text; p->next; p = p->next) +- ; +- p->adj.v = ABOVE_ADJUST; +- } +- } +- | object_spec BELOW +- { +- $$ = $1; +- if ($$->text) { +- text_item *p; +- for (p = $$->text; p->next; p = p->next) +- ; +- p->adj.v = BELOW_ADJUST; +- } +- } +- | object_spec THICKNESS expr +- { +- $$ = $1; +- $$->flags |= HAS_THICKNESS; +- $$->thickness = $3; +- } +- | object_spec ALIGNED +- { +- $$ = $1; +- $$->flags |= IS_ALIGNED; +- } +- ; +- +-text: +- TEXT +- { $$ = $1; } +- | SPRINTF '(' TEXT sprintf_args ')' +- { +- $$.filename = $3.filename; +- $$.lineno = $3.lineno; +- $$.str = do_sprintf($3.str, $4.v, $4.nv); +- a_delete $4.v; +- a_delete $3.str; +- } +- ; +- +-sprintf_args: +- /* empty */ +- { +- $$.v = 0; +- $$.nv = 0; +- $$.maxv = 0; +- } +- | sprintf_args ',' expr +- { +- $$ = $1; +- if ($$.nv >= $$.maxv) { +- if ($$.nv == 0) { +- $$.v = new double[4]; +- $$.maxv = 4; +- } +- else { +- double *oldv = $$.v; +- $$.maxv *= 2; +-#if 0 +- $$.v = new double[$$.maxv]; +- memcpy($$.v, oldv, $$.nv*sizeof(double)); +-#else +- // workaround for bug in Compaq C++ V6.5-033 +- // for Compaq Tru64 UNIX V5.1A (Rev. 1885) +- double *foo = new double[$$.maxv]; +- memcpy(foo, oldv, $$.nv*sizeof(double)); +- $$.v = foo; +-#endif +- a_delete oldv; +- } +- } +- $$.v[$$.nv] = $3; +- $$.nv += 1; +- } +- ; +- +-position: +- position_not_place +- { $$ = $1; } +- | place +- { +- position pos = $1; +- $$.x = pos.x; +- $$.y = pos.y; +- } +- | '(' place ')' +- { +- position pos = $2; +- $$.x = pos.x; +- $$.y = pos.y; +- } +- ; +- +-position_not_place: +- expr_pair +- { $$ = $1; } +- | position '+' expr_pair +- { +- $$.x = $1.x + $3.x; +- $$.y = $1.y + $3.y; +- } +- | '(' position '+' expr_pair ')' +- { +- $$.x = $2.x + $4.x; +- $$.y = $2.y + $4.y; +- } +- | position '-' expr_pair +- { +- $$.x = $1.x - $3.x; +- $$.y = $1.y - $3.y; +- } +- | '(' position '-' expr_pair ')' +- { +- $$.x = $2.x - $4.x; +- $$.y = $2.y - $4.y; +- } +- | '(' position ',' position ')' +- { +- $$.x = $2.x; +- $$.y = $4.y; +- } +- | expr between position AND position +- { +- $$.x = (1.0 - $1)*$3.x + $1*$5.x; +- $$.y = (1.0 - $1)*$3.y + $1*$5.y; +- } +- | '(' expr between position AND position ')' +- { +- $$.x = (1.0 - $2)*$4.x + $2*$6.x; +- $$.y = (1.0 - $2)*$4.y + $2*$6.y; +- } +- /* the next two rules cause harmless shift/reduce warnings */ +- | expr_not_lower_than '<' position ',' position '>' +- { +- $$.x = (1.0 - $1)*$3.x + $1*$5.x; +- $$.y = (1.0 - $1)*$3.y + $1*$5.y; +- } +- | '(' expr_not_lower_than '<' position ',' position '>' ')' +- { +- $$.x = (1.0 - $2)*$4.x + $2*$6.x; +- $$.y = (1.0 - $2)*$4.y + $2*$6.y; +- } +- ; +- +-between: +- BETWEEN +- | OF THE WAY BETWEEN +- ; +- +-expr_pair: +- expr ',' expr +- { +- $$.x = $1; +- $$.y = $3; +- } +- | '(' expr_pair ')' +- { $$ = $2; } +- ; +- +-place: +- /* line at A left == line (at A) left */ +- label %prec CHOP +- { $$ = $1; } +- | label corner +- { +- path pth($2); +- if (!pth.follow($1, & $$)) +- YYABORT; +- } +- | corner label +- { +- path pth($1); +- if (!pth.follow($2, & $$)) +- YYABORT; +- } +- | corner OF label +- { +- path pth($1); +- if (!pth.follow($3, & $$)) +- YYABORT; +- } +- | HERE +- { +- $$.x = current_position.x; +- $$.y = current_position.y; +- $$.obj = 0; +- } +- ; +- +-label: +- LABEL +- { +- place *p = lookup_label($1); +- if (!p) { +- lex_error("there is no place `%1'", $1); +- YYABORT; +- } +- $$ = *p; +- a_delete $1; +- } +- | nth_primitive +- { $$.obj = $1; } +- | label '.' LABEL +- { +- path pth($3); +- if (!pth.follow($1, & $$)) +- YYABORT; +- } +- ; +- +-ordinal: +- ORDINAL +- { $$ = $1; } +- | '`' any_expr TH +- { +- // XXX Check for overflow (and non-integers?). +- $$ = (int)$2; +- } +- ; +- +-optional_ordinal_last: +- LAST +- { $$ = 1; } +- | ordinal LAST +- { $$ = $1; } +- ; +- +-nth_primitive: +- ordinal object_type +- { +- int count = 0; +- object *p; +- for (p = olist.head; p != 0; p = p->next) +- if (p->type() == $2 && ++count == $1) { +- $$ = p; +- break; +- } +- if (p == 0) { +- lex_error("there is no %1%2 %3", $1, ordinal_postfix($1), +- object_type_name($2)); +- YYABORT; +- } +- } +- | optional_ordinal_last object_type +- { +- int count = 0; +- object *p; +- for (p = olist.tail; p != 0; p = p->prev) +- if (p->type() == $2 && ++count == $1) { +- $$ = p; +- break; +- } +- if (p == 0) { +- lex_error("there is no %1%2 last %3", $1, +- ordinal_postfix($1), object_type_name($2)); +- YYABORT; +- } +- } +- ; +- +-object_type: +- BOX +- { $$ = BOX_OBJECT; } +- | CIRCLE +- { $$ = CIRCLE_OBJECT; } +- | ELLIPSE +- { $$ = ELLIPSE_OBJECT; } +- | ARC +- { $$ = ARC_OBJECT; } +- | LINE +- { $$ = LINE_OBJECT; } +- | ARROW +- { $$ = ARROW_OBJECT; } +- | SPLINE +- { $$ = SPLINE_OBJECT; } +- | '[' ']' +- { $$ = BLOCK_OBJECT; } +- | TEXT +- { $$ = TEXT_OBJECT; } +- ; +- +-label_path: +- '.' LABEL +- { $$ = new path($2); } +- | label_path '.' LABEL +- { +- $$ = $1; +- $$->append($3); +- } +- ; +- +-relative_path: +- corner %prec CHOP +- { $$ = new path($1); } +- /* give this a lower precedence than LEFT and RIGHT so that +- [A: box] with .A left == [A: box] with (.A left) */ +- | label_path %prec TEXT +- { $$ = $1; } +- | label_path corner +- { +- $$ = $1; +- $$->append($2); +- } +- ; +- +-path: +- relative_path +- { $$ = $1; } +- | '(' relative_path ',' relative_path ')' +- { +- $$ = $2; +- $$->set_ypath($4); +- } +- /* The rest of these rules are a compatibility sop. */ +- | ORDINAL LAST object_type relative_path +- { +- lex_warning("`%1%2 last %3' in `with' argument ignored", +- $1, ordinal_postfix($1), object_type_name($3)); +- $$ = $4; +- } +- | LAST object_type relative_path +- { +- lex_warning("`last %1' in `with' argument ignored", +- object_type_name($2)); +- $$ = $3; +- } +- | ORDINAL object_type relative_path +- { +- lex_warning("`%1%2 %3' in `with' argument ignored", +- $1, ordinal_postfix($1), object_type_name($2)); +- $$ = $3; +- } +- | LABEL relative_path +- { +- lex_warning("initial `%1' in `with' argument ignored", $1); +- a_delete $1; +- $$ = $2; +- } +- ; +- +-corner: +- DOT_N +- { $$ = &object::north; } +- | DOT_E +- { $$ = &object::east; } +- | DOT_W +- { $$ = &object::west; } +- | DOT_S +- { $$ = &object::south; } +- | DOT_NE +- { $$ = &object::north_east; } +- | DOT_SE +- { $$ = &object:: south_east; } +- | DOT_NW +- { $$ = &object::north_west; } +- | DOT_SW +- { $$ = &object::south_west; } +- | DOT_C +- { $$ = &object::center; } +- | DOT_START +- { $$ = &object::start; } +- | DOT_END +- { $$ = &object::end; } +- | TOP +- { $$ = &object::north; } +- | BOTTOM +- { $$ = &object::south; } +- | LEFT +- { $$ = &object::west; } +- | RIGHT +- { $$ = &object::east; } +- | UPPER LEFT +- { $$ = &object::north_west; } +- | LOWER LEFT +- { $$ = &object::south_west; } +- | UPPER RIGHT +- { $$ = &object::north_east; } +- | LOWER RIGHT +- { $$ = &object::south_east; } +- | LEFT_CORNER +- { $$ = &object::west; } +- | RIGHT_CORNER +- { $$ = &object::east; } +- | UPPER LEFT_CORNER +- { $$ = &object::north_west; } +- | LOWER LEFT_CORNER +- { $$ = &object::south_west; } +- | UPPER RIGHT_CORNER +- { $$ = &object::north_east; } +- | LOWER RIGHT_CORNER +- { $$ = &object::south_east; } +- | NORTH +- { $$ = &object::north; } +- | SOUTH +- { $$ = &object::south; } +- | EAST +- { $$ = &object::east; } +- | WEST +- { $$ = &object::west; } +- | CENTER +- { $$ = &object::center; } +- | START +- { $$ = &object::start; } +- | END +- { $$ = &object::end; } +- ; +- +-expr: +- expr_lower_than +- { $$ = $1; } +- | expr_not_lower_than +- { $$ = $1; } +- ; +- +-expr_lower_than: +- expr '<' expr +- { $$ = ($1 < $3); } +- ; +- +-expr_not_lower_than: +- VARIABLE +- { +- if (!lookup_variable($1, & $$)) { +- lex_error("there is no variable `%1'", $1); +- YYABORT; +- } +- a_delete $1; +- } +- | NUMBER +- { $$ = $1; } +- | place DOT_X +- { +- if ($1.obj != 0) +- $$ = $1.obj->origin().x; +- else +- $$ = $1.x; +- } +- | place DOT_Y +- { +- if ($1.obj != 0) +- $$ = $1.obj->origin().y; +- else +- $$ = $1.y; +- } +- | place DOT_HT +- { +- if ($1.obj != 0) +- $$ = $1.obj->height(); +- else +- $$ = 0.0; +- } +- | place DOT_WID +- { +- if ($1.obj != 0) +- $$ = $1.obj->width(); +- else +- $$ = 0.0; +- } +- | place DOT_RAD +- { +- if ($1.obj != 0) +- $$ = $1.obj->radius(); +- else +- $$ = 0.0; +- } +- | expr '+' expr +- { $$ = $1 + $3; } +- | expr '-' expr +- { $$ = $1 - $3; } +- | expr '*' expr +- { $$ = $1 * $3; } +- | expr '/' expr +- { +- if ($3 == 0.0) { +- lex_error("division by zero"); +- YYABORT; +- } +- $$ = $1/$3; +- } +- | expr '%' expr +- { +- if ($3 == 0.0) { +- lex_error("modulus by zero"); +- YYABORT; +- } +- $$ = fmod($1, $3); +- } +- | expr '^' expr +- { +- errno = 0; +- $$ = pow($1, $3); +- if (errno == EDOM) { +- lex_error("arguments to `^' operator out of domain"); +- YYABORT; +- } +- if (errno == ERANGE) { +- lex_error("result of `^' operator out of range"); +- YYABORT; +- } +- } +- | '-' expr %prec '!' +- { $$ = -$2; } +- | '(' any_expr ')' +- { $$ = $2; } +- | SIN '(' any_expr ')' +- { +- errno = 0; +- $$ = sin($3); +- if (errno == ERANGE) { +- lex_error("sin result out of range"); +- YYABORT; +- } +- } +- | COS '(' any_expr ')' +- { +- errno = 0; +- $$ = cos($3); +- if (errno == ERANGE) { +- lex_error("cos result out of range"); +- YYABORT; +- } +- } +- | ATAN2 '(' any_expr ',' any_expr ')' +- { +- errno = 0; +- $$ = atan2($3, $5); +- if (errno == EDOM) { +- lex_error("atan2 argument out of domain"); +- YYABORT; +- } +- if (errno == ERANGE) { +- lex_error("atan2 result out of range"); +- YYABORT; +- } +- } +- | LOG '(' any_expr ')' +- { +- errno = 0; +- $$ = log10($3); +- if (errno == ERANGE) { +- lex_error("log result out of range"); +- YYABORT; +- } +- } +- | EXP '(' any_expr ')' +- { +- errno = 0; +- $$ = pow(10.0, $3); +- if (errno == ERANGE) { +- lex_error("exp result out of range"); +- YYABORT; +- } +- } +- | SQRT '(' any_expr ')' +- { +- errno = 0; +- $$ = sqrt($3); +- if (errno == EDOM) { +- lex_error("sqrt argument out of domain"); +- YYABORT; +- } +- } +- | K_MAX '(' any_expr ',' any_expr ')' +- { $$ = $3 > $5 ? $3 : $5; } +- | K_MIN '(' any_expr ',' any_expr ')' +- { $$ = $3 < $5 ? $3 : $5; } +- | INT '(' any_expr ')' +- { $$ = $3 < 0 ? -floor(-$3) : floor($3); } +- | RAND '(' any_expr ')' +- { $$ = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*$3); } +- | RAND '(' ')' +- { +- /* return a random number in the range [0,1) */ +- /* portable, but not very random */ +- $$ = (rand() & 0x7fff) / double(0x8000); +- } +- | SRAND '(' any_expr ')' +- { +- $$ = 0; +- srand((unsigned int)$3); +- } +- | expr LESSEQUAL expr +- { $$ = ($1 <= $3); } +- | expr '>' expr +- { $$ = ($1 > $3); } +- | expr GREATEREQUAL expr +- { $$ = ($1 >= $3); } +- | expr EQUALEQUAL expr +- { $$ = ($1 == $3); } +- | expr NOTEQUAL expr +- { $$ = ($1 != $3); } +- | expr ANDAND expr +- { $$ = ($1 != 0.0 && $3 != 0.0); } +- | expr OROR expr +- { $$ = ($1 != 0.0 || $3 != 0.0); } +- | '!' expr +- { $$ = ($2 == 0.0); } +- +- ; +- +-%% +- +-/* bison defines const to be empty unless __STDC__ is defined, which it +-isn't under cfront */ +- +-#ifdef const +-#undef const +-#endif +- +-static struct { +- const char *name; +- double val; +- int scaled; // non-zero if val should be multiplied by scale +-} defaults_table[] = { +- { "arcrad", .25, 1 }, +- { "arrowht", .1, 1 }, +- { "arrowwid", .05, 1 }, +- { "circlerad", .25, 1 }, +- { "boxht", .5, 1 }, +- { "boxwid", .75, 1 }, +- { "boxrad", 0.0, 1 }, +- { "dashwid", .05, 1 }, +- { "ellipseht", .5, 1 }, +- { "ellipsewid", .75, 1 }, +- { "moveht", .5, 1 }, +- { "movewid", .5, 1 }, +- { "lineht", .5, 1 }, +- { "linewid", .5, 1 }, +- { "textht", 0.0, 1 }, +- { "textwid", 0.0, 1 }, +- { "scale", 1.0, 0 }, +- { "linethick", -1.0, 0 }, // in points +- { "fillval", .5, 0 }, +- { "arrowhead", 1.0, 0 }, +- { "maxpswid", 8.5, 0 }, +- { "maxpsht", 11.0, 0 }, +-}; +- +-place *lookup_label(const char *label) +-{ +- saved_state *state = current_saved_state; +- PTABLE(place) *tbl = current_table; +- for (;;) { +- place *pl = tbl->lookup(label); +- if (pl) +- return pl; +- if (!state) +- return 0; +- tbl = state->tbl; +- state = state->prev; +- } +-} +- +-void define_label(const char *label, const place *pl) +-{ +- place *p = new place[1]; +- *p = *pl; +- current_table->define(label, p); +-} +- +-int lookup_variable(const char *name, double *val) +-{ +- place *pl = lookup_label(name); +- if (pl) { +- *val = pl->x; +- return 1; +- } +- return 0; +-} +- +-void define_variable(const char *name, double val) +-{ +- place *p = new place[1]; +- p->obj = 0; +- p->x = val; +- p->y = 0.0; +- current_table->define(name, p); +- if (strcmp(name, "scale") == 0) { +- // When the scale changes, reset all scaled pre-defined variables to +- // their default values. +- for (unsigned int i = 0; +- i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) +- if (defaults_table[i].scaled) +- define_variable(defaults_table[i].name, val*defaults_table[i].val); +- } +-} +- +-// called once only (not once per parse) +- +-void parse_init() +-{ +- current_direction = RIGHT_DIRECTION; +- current_position.x = 0.0; +- current_position.y = 0.0; +- // This resets everything to its default value. +- reset_all(); +-} +- +-void reset(const char *nm) +-{ +- for (unsigned int i = 0; +- i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) +- if (strcmp(nm, defaults_table[i].name) == 0) { +- double val = defaults_table[i].val; +- if (defaults_table[i].scaled) { +- double scale; +- lookup_variable("scale", &scale); +- val *= scale; +- } +- define_variable(defaults_table[i].name, val); +- return; +- } +- lex_error("`%1' is not a predefined variable", nm); +-} +- +-void reset_all() +-{ +- // We only have to explicitly reset the pre-defined variables that +- // aren't scaled because `scale' is not scaled, and changing the +- // value of `scale' will reset all the pre-defined variables that +- // are scaled. +- for (unsigned int i = 0; +- i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) +- if (!defaults_table[i].scaled) +- define_variable(defaults_table[i].name, defaults_table[i].val); +-} +- +-// called after each parse +- +-void parse_cleanup() +-{ +- while (current_saved_state != 0) { +- delete current_table; +- current_table = current_saved_state->tbl; +- saved_state *tem = current_saved_state; +- current_saved_state = current_saved_state->prev; +- delete tem; +- } +- assert(current_table == &top_table); +- PTABLE_ITERATOR(place) iter(current_table); +- const char *key; +- place *pl; +- while (iter.next(&key, &pl)) +- if (pl->obj != 0) { +- position pos = pl->obj->origin(); +- pl->obj = 0; +- pl->x = pos.x; +- pl->y = pos.y; +- } +- while (olist.head != 0) { +- object *tem = olist.head; +- olist.head = olist.head->next; +- delete tem; +- } +- olist.tail = 0; +- current_direction = RIGHT_DIRECTION; +- current_position.x = 0.0; +- current_position.y = 0.0; +-} +- +-const char *ordinal_postfix(int n) +-{ +- if (n < 10 || n > 20) +- switch (n % 10) { +- case 1: +- return "st"; +- case 2: +- return "nd"; +- case 3: +- return "rd"; +- } +- return "th"; +-} +- +-const char *object_type_name(object_type type) +-{ +- switch (type) { +- case BOX_OBJECT: +- return "box"; +- case CIRCLE_OBJECT: +- return "circle"; +- case ELLIPSE_OBJECT: +- return "ellipse"; +- case ARC_OBJECT: +- return "arc"; +- case SPLINE_OBJECT: +- return "spline"; +- case LINE_OBJECT: +- return "line"; +- case ARROW_OBJECT: +- return "arrow"; +- case MOVE_OBJECT: +- return "move"; +- case TEXT_OBJECT: +- return "\"\""; +- case BLOCK_OBJECT: +- return "[]"; +- case OTHER_OBJECT: +- case MARK_OBJECT: +- default: +- break; +- } +- return "object"; +-} +- +-static char sprintf_buf[1024]; +- +-char *format_number(const char *form, double n) +-{ +- if (form == 0) +- form = "%g"; +- return do_sprintf(form, &n, 1); +-} +- +-char *do_sprintf(const char *form, const double *v, int nv) +-{ +- string result; +- int i = 0; +- string one_format; +- while (*form) { +- if (*form == '%') { +- one_format += *form++; +- for (; *form != '\0' && strchr("#-+ 0123456789.", *form) != 0; form++) +- one_format += *form; +- if (*form == '\0' || strchr("eEfgG%", *form) == 0) { +- lex_error("bad sprintf format"); +- result += one_format; +- result += form; +- break; +- } +- if (*form == '%') { +- one_format += *form++; +- one_format += '\0'; +- snprintf(sprintf_buf, sizeof(sprintf_buf), +- "%s", one_format.contents()); +- } +- else { +- if (i >= nv) { +- lex_error("too few arguments to snprintf"); +- result += one_format; +- result += form; +- break; +- } +- one_format += *form++; +- one_format += '\0'; +- snprintf(sprintf_buf, sizeof(sprintf_buf), +- one_format.contents(), v[i++]); +- } +- one_format.clear(); +- result += sprintf_buf; +- } +- else +- result += *form++; +- } +- result += '\0'; +- return strsave(result.contents()); +-} +diff -Nuar groff-1.22.3.old/src/preproc/pic/pic.ypp groff-1.22.3/src/preproc/pic/pic.ypp +--- groff-1.22.3.old/src/preproc/pic/pic.ypp 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/pic/pic.ypp 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,1933 @@ ++/* Copyright (C) 1989-2014 Free Software Foundation, Inc. ++ Written by James Clark (jjc@jclark.com) ++ ++This file is part of groff. ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation, either version 3 of the License, or ++(at your option) any later version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program. If not, see . */ ++ ++%{ ++#include "pic.h" ++#include "ptable.h" ++#include "object.h" ++ ++extern int delim_flag; ++extern void copy_rest_thru(const char *, const char *); ++extern void copy_file_thru(const char *, const char *, const char *); ++extern void push_body(const char *); ++extern void do_for(char *var, double from, double to, ++ int by_is_multiplicative, double by, char *body); ++extern void do_lookahead(); ++ ++/* Maximum number of characters produced by printf("%g") */ ++#define GDIGITS 14 ++ ++int yylex(); ++void yyerror(const char *); ++ ++void reset(const char *nm); ++void reset_all(); ++ ++place *lookup_label(const char *); ++void define_label(const char *label, const place *pl); ++ ++direction current_direction; ++position current_position; ++ ++implement_ptable(place) ++ ++PTABLE(place) top_table; ++ ++PTABLE(place) *current_table = &top_table; ++saved_state *current_saved_state = 0; ++ ++object_list olist; ++ ++const char *ordinal_postfix(int n); ++const char *object_type_name(object_type type); ++char *format_number(const char *form, double n); ++char *do_sprintf(const char *form, const double *v, int nv); ++ ++%} ++ ++%expect 2 ++ ++%union { ++ char *str; ++ int n; ++ double x; ++ struct { double x, y; } pair; ++ struct { double x; char *body; } if_data; ++ struct { char *str; const char *filename; int lineno; } lstr; ++ struct { double *v; int nv; int maxv; } dv; ++ struct { double val; int is_multiplicative; } by; ++ place pl; ++ object *obj; ++ corner crn; ++ path *pth; ++ object_spec *spec; ++ saved_state *pstate; ++ graphics_state state; ++ object_type obtype; ++} ++ ++%token LABEL ++%token VARIABLE ++%token NUMBER ++%token TEXT ++%token COMMAND_LINE ++%token DELIMITED ++%token ORDINAL ++%token TH ++%token LEFT_ARROW_HEAD ++%token RIGHT_ARROW_HEAD ++%token DOUBLE_ARROW_HEAD ++%token LAST ++%token BOX ++%token CIRCLE ++%token ELLIPSE ++%token ARC ++%token LINE ++%token ARROW ++%token MOVE ++%token SPLINE ++%token HEIGHT ++%token RADIUS ++%token FIGNAME ++%token WIDTH ++%token DIAMETER ++%token UP ++%token DOWN ++%token RIGHT ++%token LEFT ++%token FROM ++%token TO ++%token AT ++%token WITH ++%token BY ++%token THEN ++%token SOLID ++%token DOTTED ++%token DASHED ++%token CHOP ++%token SAME ++%token INVISIBLE ++%token LJUST ++%token RJUST ++%token ABOVE ++%token BELOW ++%token OF ++%token THE ++%token WAY ++%token BETWEEN ++%token AND ++%token HERE ++%token DOT_N ++%token DOT_E ++%token DOT_W ++%token DOT_S ++%token DOT_NE ++%token DOT_SE ++%token DOT_NW ++%token DOT_SW ++%token DOT_C ++%token DOT_START ++%token DOT_END ++%token DOT_X ++%token DOT_Y ++%token DOT_HT ++%token DOT_WID ++%token DOT_RAD ++%token SIN ++%token COS ++%token ATAN2 ++%token LOG ++%token EXP ++%token SQRT ++%token K_MAX ++%token K_MIN ++%token INT ++%token RAND ++%token SRAND ++%token COPY ++%token THRU ++%token TOP ++%token BOTTOM ++%token UPPER ++%token LOWER ++%token SH ++%token PRINT ++%token CW ++%token CCW ++%token FOR ++%token DO ++%token IF ++%token ELSE ++%token ANDAND ++%token OROR ++%token NOTEQUAL ++%token EQUALEQUAL ++%token LESSEQUAL ++%token GREATEREQUAL ++%token LEFT_CORNER ++%token RIGHT_CORNER ++%token NORTH ++%token SOUTH ++%token EAST ++%token WEST ++%token CENTER ++%token END ++%token START ++%token RESET ++%token UNTIL ++%token PLOT ++%token THICKNESS ++%token FILL ++%token COLORED ++%token OUTLINED ++%token SHADED ++%token XSLANTED ++%token YSLANTED ++%token ALIGNED ++%token SPRINTF ++%token COMMAND ++ ++%token DEFINE ++%token UNDEF ++ ++%left '.' ++ ++/* this ensures that plot 17 "%g" parses as (plot 17 "%g") */ ++%left PLOT ++%left TEXT SPRINTF ++ ++/* give text adjustments higher precedence than TEXT, so that ++box "foo" above ljust == box ("foo" above ljust) ++*/ ++ ++%left LJUST RJUST ABOVE BELOW ++ ++%left LEFT RIGHT ++/* Give attributes that take an optional expression a higher ++precedence than left and right, so that eg `line chop left' ++parses properly. */ ++%left CHOP SOLID DASHED DOTTED UP DOWN FILL COLORED OUTLINED ++%left XSLANTED YSLANTED ++%left LABEL ++ ++%left VARIABLE NUMBER '(' SIN COS ATAN2 LOG EXP SQRT K_MAX K_MIN INT RAND SRAND LAST ++%left ORDINAL HERE '`' ++ ++%left BOX CIRCLE ELLIPSE ARC LINE ARROW SPLINE '[' ++ ++/* these need to be lower than '-' */ ++%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS ++ ++/* these must have higher precedence than CHOP so that `label %prec CHOP' ++works */ ++%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C ++%left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER ++%left UPPER LOWER NORTH SOUTH EAST WEST CENTER START END ++ ++%left ',' ++%left OROR ++%left ANDAND ++%left EQUALEQUAL NOTEQUAL ++%left '<' '>' LESSEQUAL GREATEREQUAL ++ ++%left BETWEEN OF ++%left AND ++ ++%left '+' '-' ++%left '*' '/' '%' ++%right '!' ++%right '^' ++ ++%type expr expr_lower_than expr_not_lower_than any_expr text_expr ++%type optional_by ++%type expr_pair position_not_place ++%type simple_if ++%type nth_primitive ++%type corner ++%type path label_path relative_path ++%type place label element element_list middle_element_list ++%type object_spec ++%type position ++%type object_type ++%type optional_ordinal_last ordinal ++%type macro_name until ++%type sprintf_args ++%type text print_args print_arg ++ ++%% ++ ++top: ++ optional_separator ++ | element_list ++ { ++ if (olist.head) ++ print_picture(olist.head); ++ } ++ ; ++ ++ ++element_list: ++ optional_separator middle_element_list optional_separator ++ { $$ = $2; } ++ ; ++ ++middle_element_list: ++ element ++ { $$ = $1; } ++ | middle_element_list separator element ++ { $$ = $1; } ++ ; ++ ++optional_separator: ++ /* empty */ ++ | separator ++ ; ++ ++separator: ++ ';' ++ | separator ';' ++ ; ++ ++placeless_element: ++ FIGNAME '=' macro_name ++ { ++ a_delete graphname; ++ graphname = new char[strlen($3) + 1]; ++ strcpy(graphname, $3); ++ a_delete $3; ++ } ++ | ++ VARIABLE '=' any_expr ++ { ++ define_variable($1, $3); ++ a_delete $1; ++ } ++ | VARIABLE ':' '=' any_expr ++ { ++ place *p = lookup_label($1); ++ if (!p) { ++ lex_error("variable `%1' not defined", $1); ++ YYABORT; ++ } ++ p->obj = 0; ++ p->x = $4; ++ p->y = 0.0; ++ a_delete $1; ++ } ++ | UP ++ { current_direction = UP_DIRECTION; } ++ | DOWN ++ { current_direction = DOWN_DIRECTION; } ++ | LEFT ++ { current_direction = LEFT_DIRECTION; } ++ | RIGHT ++ { current_direction = RIGHT_DIRECTION; } ++ | COMMAND_LINE ++ { ++ olist.append(make_command_object($1.str, $1.filename, ++ $1.lineno)); ++ } ++ | COMMAND print_args ++ { ++ olist.append(make_command_object($2.str, $2.filename, ++ $2.lineno)); ++ } ++ | PRINT print_args ++ { ++ fprintf(stderr, "%s\n", $2.str); ++ a_delete $2.str; ++ fflush(stderr); ++ } ++ | SH ++ { delim_flag = 1; } ++ DELIMITED ++ { ++ delim_flag = 0; ++ if (safer_flag) ++ lex_error("unsafe to run command `%1'", $3); ++ else ++ system($3); ++ a_delete $3; ++ } ++ | COPY TEXT ++ { ++ if (yychar < 0) ++ do_lookahead(); ++ do_copy($2.str); ++ // do not delete the filename ++ } ++ | COPY TEXT THRU ++ { delim_flag = 2; } ++ DELIMITED ++ { delim_flag = 0; } ++ until ++ { ++ if (yychar < 0) ++ do_lookahead(); ++ copy_file_thru($2.str, $5, $7); ++ // do not delete the filename ++ a_delete $5; ++ a_delete $7; ++ } ++ | COPY THRU ++ { delim_flag = 2; } ++ DELIMITED ++ { delim_flag = 0; } ++ until ++ { ++ if (yychar < 0) ++ do_lookahead(); ++ copy_rest_thru($4, $6); ++ a_delete $4; ++ a_delete $6; ++ } ++ | FOR VARIABLE '=' expr TO expr optional_by DO ++ { delim_flag = 1; } ++ DELIMITED ++ { ++ delim_flag = 0; ++ if (yychar < 0) ++ do_lookahead(); ++ do_for($2, $4, $6, $7.is_multiplicative, $7.val, $10); ++ } ++ | simple_if ++ { ++ if (yychar < 0) ++ do_lookahead(); ++ if ($1.x != 0.0) ++ push_body($1.body); ++ a_delete $1.body; ++ } ++ | simple_if ELSE ++ { delim_flag = 1; } ++ DELIMITED ++ { ++ delim_flag = 0; ++ if (yychar < 0) ++ do_lookahead(); ++ if ($1.x != 0.0) ++ push_body($1.body); ++ else ++ push_body($4); ++ a_delete $1.body; ++ a_delete $4; ++ } ++ | reset_variables ++ | RESET ++ { define_variable("scale", 1.0); } ++ ; ++ ++macro_name: ++ VARIABLE ++ | LABEL ++ ; ++ ++reset_variables: ++ RESET VARIABLE ++ { ++ reset($2); ++ a_delete $2; ++ } ++ | reset_variables VARIABLE ++ { ++ reset($2); ++ a_delete $2; ++ } ++ | reset_variables ',' VARIABLE ++ { ++ reset($3); ++ a_delete $3; ++ } ++ ; ++ ++print_args: ++ print_arg ++ { $$ = $1; } ++ | print_args print_arg ++ { ++ $$.str = new char[strlen($1.str) + strlen($2.str) + 1]; ++ strcpy($$.str, $1.str); ++ strcat($$.str, $2.str); ++ a_delete $1.str; ++ a_delete $2.str; ++ if ($1.filename) { ++ $$.filename = $1.filename; ++ $$.lineno = $1.lineno; ++ } ++ else if ($2.filename) { ++ $$.filename = $2.filename; ++ $$.lineno = $2.lineno; ++ } ++ } ++ ; ++ ++print_arg: ++ expr %prec ',' ++ { ++ $$.str = new char[GDIGITS + 1]; ++ sprintf($$.str, "%g", $1); ++ $$.filename = 0; ++ $$.lineno = 0; ++ } ++ | text ++ { $$ = $1; } ++ | position %prec ',' ++ { ++ $$.str = new char[GDIGITS + 2 + GDIGITS + 1]; ++ sprintf($$.str, "%g, %g", $1.x, $1.y); ++ $$.filename = 0; ++ $$.lineno = 0; ++ } ++ ; ++ ++simple_if: ++ IF any_expr THEN ++ { delim_flag = 1; } ++ DELIMITED ++ { ++ delim_flag = 0; ++ $$.x = $2; ++ $$.body = $5; ++ } ++ ; ++ ++until: ++ /* empty */ ++ { $$ = 0; } ++ | UNTIL TEXT ++ { $$ = $2.str; } ++ ; ++ ++any_expr: ++ expr ++ { $$ = $1; } ++ | text_expr ++ { $$ = $1; } ++ ; ++ ++text_expr: ++ text EQUALEQUAL text ++ { ++ $$ = strcmp($1.str, $3.str) == 0; ++ a_delete $1.str; ++ a_delete $3.str; ++ } ++ | text NOTEQUAL text ++ { ++ $$ = strcmp($1.str, $3.str) != 0; ++ a_delete $1.str; ++ a_delete $3.str; ++ } ++ | text_expr ANDAND text_expr ++ { $$ = ($1 != 0.0 && $3 != 0.0); } ++ | text_expr ANDAND expr ++ { $$ = ($1 != 0.0 && $3 != 0.0); } ++ | expr ANDAND text_expr ++ { $$ = ($1 != 0.0 && $3 != 0.0); } ++ | text_expr OROR text_expr ++ { $$ = ($1 != 0.0 || $3 != 0.0); } ++ | text_expr OROR expr ++ { $$ = ($1 != 0.0 || $3 != 0.0); } ++ | expr OROR text_expr ++ { $$ = ($1 != 0.0 || $3 != 0.0); } ++ | '!' text_expr ++ { $$ = ($2 == 0.0); } ++ ; ++ ++ ++optional_by: ++ /* empty */ ++ { ++ $$.val = 1.0; ++ $$.is_multiplicative = 0; ++ } ++ | BY expr ++ { ++ $$.val = $2; ++ $$.is_multiplicative = 0; ++ } ++ | BY '*' expr ++ { ++ $$.val = $3; ++ $$.is_multiplicative = 1; ++ } ++ ; ++ ++element: ++ object_spec ++ { ++ $$.obj = $1->make_object(¤t_position, ++ ¤t_direction); ++ if ($$.obj == 0) ++ YYABORT; ++ delete $1; ++ if ($$.obj) ++ olist.append($$.obj); ++ else { ++ $$.x = current_position.x; ++ $$.y = current_position.y; ++ } ++ } ++ | LABEL ':' optional_separator element ++ { ++ $$ = $4; ++ define_label($1, & $$); ++ a_delete $1; ++ } ++ | LABEL ':' optional_separator position_not_place ++ { ++ $$.obj = 0; ++ $$.x = $4.x; ++ $$.y = $4.y; ++ define_label($1, & $$); ++ a_delete $1; ++ } ++ | LABEL ':' optional_separator place ++ { ++ $$ = $4; ++ define_label($1, & $$); ++ a_delete $1; ++ } ++ | '{' ++ { ++ $$.x = current_position.x; ++ $$.y = current_position.y; ++ $$.dir = current_direction; ++ } ++ element_list '}' ++ { ++ current_position.x = $2.x; ++ current_position.y = $2.y; ++ current_direction = $2.dir; ++ } ++ optional_element ++ { ++ $$ = $3; ++ } ++ | placeless_element ++ { ++ $$.obj = 0; ++ $$.x = current_position.x; ++ $$.y = current_position.y; ++ } ++ ; ++ ++optional_element: ++ /* empty */ ++ {} ++ | element ++ {} ++ ; ++ ++object_spec: ++ BOX ++ { $$ = new object_spec(BOX_OBJECT); } ++ | CIRCLE ++ { $$ = new object_spec(CIRCLE_OBJECT); } ++ | ELLIPSE ++ { $$ = new object_spec(ELLIPSE_OBJECT); } ++ | ARC ++ { ++ $$ = new object_spec(ARC_OBJECT); ++ $$->dir = current_direction; ++ } ++ | LINE ++ { ++ $$ = new object_spec(LINE_OBJECT); ++ lookup_variable("lineht", & $$->segment_height); ++ lookup_variable("linewid", & $$->segment_width); ++ $$->dir = current_direction; ++ } ++ | ARROW ++ { ++ $$ = new object_spec(ARROW_OBJECT); ++ lookup_variable("lineht", & $$->segment_height); ++ lookup_variable("linewid", & $$->segment_width); ++ $$->dir = current_direction; ++ } ++ | MOVE ++ { ++ $$ = new object_spec(MOVE_OBJECT); ++ lookup_variable("moveht", & $$->segment_height); ++ lookup_variable("movewid", & $$->segment_width); ++ $$->dir = current_direction; ++ } ++ | SPLINE ++ { ++ $$ = new object_spec(SPLINE_OBJECT); ++ lookup_variable("lineht", & $$->segment_height); ++ lookup_variable("linewid", & $$->segment_width); ++ $$->dir = current_direction; ++ } ++ | text %prec TEXT ++ { ++ $$ = new object_spec(TEXT_OBJECT); ++ $$->text = new text_item($1.str, $1.filename, $1.lineno); ++ } ++ | PLOT expr ++ { ++ $$ = new object_spec(TEXT_OBJECT); ++ $$->text = new text_item(format_number(0, $2), 0, -1); ++ } ++ | PLOT expr text ++ { ++ $$ = new object_spec(TEXT_OBJECT); ++ $$->text = new text_item(format_number($3.str, $2), ++ $3.filename, $3.lineno); ++ a_delete $3.str; ++ } ++ | '[' ++ { ++ saved_state *p = new saved_state; ++ $$ = p; ++ p->x = current_position.x; ++ p->y = current_position.y; ++ p->dir = current_direction; ++ p->tbl = current_table; ++ p->prev = current_saved_state; ++ current_position.x = 0.0; ++ current_position.y = 0.0; ++ current_table = new PTABLE(place); ++ current_saved_state = p; ++ olist.append(make_mark_object()); ++ } ++ element_list ']' ++ { ++ current_position.x = $2->x; ++ current_position.y = $2->y; ++ current_direction = $2->dir; ++ $$ = new object_spec(BLOCK_OBJECT); ++ olist.wrap_up_block(& $$->oblist); ++ $$->tbl = current_table; ++ current_table = $2->tbl; ++ current_saved_state = $2->prev; ++ delete $2; ++ } ++ | object_spec HEIGHT expr ++ { ++ $$ = $1; ++ $$->height = $3; ++ $$->flags |= HAS_HEIGHT; ++ } ++ | object_spec RADIUS expr ++ { ++ $$ = $1; ++ $$->radius = $3; ++ $$->flags |= HAS_RADIUS; ++ } ++ | object_spec WIDTH expr ++ { ++ $$ = $1; ++ $$->width = $3; ++ $$->flags |= HAS_WIDTH; ++ } ++ | object_spec DIAMETER expr ++ { ++ $$ = $1; ++ $$->radius = $3/2.0; ++ $$->flags |= HAS_RADIUS; ++ } ++ | object_spec expr %prec HEIGHT ++ { ++ $$ = $1; ++ $$->flags |= HAS_SEGMENT; ++ switch ($$->dir) { ++ case UP_DIRECTION: ++ $$->segment_pos.y += $2; ++ break; ++ case DOWN_DIRECTION: ++ $$->segment_pos.y -= $2; ++ break; ++ case RIGHT_DIRECTION: ++ $$->segment_pos.x += $2; ++ break; ++ case LEFT_DIRECTION: ++ $$->segment_pos.x -= $2; ++ break; ++ } ++ } ++ | object_spec UP ++ { ++ $$ = $1; ++ $$->dir = UP_DIRECTION; ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.y += $$->segment_height; ++ } ++ | object_spec UP expr ++ { ++ $$ = $1; ++ $$->dir = UP_DIRECTION; ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.y += $3; ++ } ++ | object_spec DOWN ++ { ++ $$ = $1; ++ $$->dir = DOWN_DIRECTION; ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.y -= $$->segment_height; ++ } ++ | object_spec DOWN expr ++ { ++ $$ = $1; ++ $$->dir = DOWN_DIRECTION; ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.y -= $3; ++ } ++ | object_spec RIGHT ++ { ++ $$ = $1; ++ $$->dir = RIGHT_DIRECTION; ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.x += $$->segment_width; ++ } ++ | object_spec RIGHT expr ++ { ++ $$ = $1; ++ $$->dir = RIGHT_DIRECTION; ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.x += $3; ++ } ++ | object_spec LEFT ++ { ++ $$ = $1; ++ $$->dir = LEFT_DIRECTION; ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.x -= $$->segment_width; ++ } ++ | object_spec LEFT expr ++ { ++ $$ = $1; ++ $$->dir = LEFT_DIRECTION; ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.x -= $3; ++ } ++ | object_spec FROM position ++ { ++ $$ = $1; ++ $$->flags |= HAS_FROM; ++ $$->from.x = $3.x; ++ $$->from.y = $3.y; ++ } ++ | object_spec TO position ++ { ++ $$ = $1; ++ if ($$->flags & HAS_SEGMENT) ++ $$->segment_list = new segment($$->segment_pos, ++ $$->segment_is_absolute, ++ $$->segment_list); ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.x = $3.x; ++ $$->segment_pos.y = $3.y; ++ $$->segment_is_absolute = 1; ++ $$->flags |= HAS_TO; ++ $$->to.x = $3.x; ++ $$->to.y = $3.y; ++ } ++ | object_spec AT position ++ { ++ $$ = $1; ++ $$->flags |= HAS_AT; ++ $$->at.x = $3.x; ++ $$->at.y = $3.y; ++ if ($$->type != ARC_OBJECT) { ++ $$->flags |= HAS_FROM; ++ $$->from.x = $3.x; ++ $$->from.y = $3.y; ++ } ++ } ++ | object_spec WITH path ++ { ++ $$ = $1; ++ $$->flags |= HAS_WITH; ++ $$->with = $3; ++ } ++ | object_spec WITH position %prec ',' ++ { ++ $$ = $1; ++ $$->flags |= HAS_WITH; ++ position pos; ++ pos.x = $3.x; ++ pos.y = $3.y; ++ $$->with = new path(pos); ++ } ++ | object_spec BY expr_pair ++ { ++ $$ = $1; ++ $$->flags |= HAS_SEGMENT; ++ $$->segment_pos.x += $3.x; ++ $$->segment_pos.y += $3.y; ++ } ++ | object_spec THEN ++ { ++ $$ = $1; ++ if (!($$->flags & HAS_SEGMENT)) ++ switch ($$->dir) { ++ case UP_DIRECTION: ++ $$->segment_pos.y += $$->segment_width; ++ break; ++ case DOWN_DIRECTION: ++ $$->segment_pos.y -= $$->segment_width; ++ break; ++ case RIGHT_DIRECTION: ++ $$->segment_pos.x += $$->segment_width; ++ break; ++ case LEFT_DIRECTION: ++ $$->segment_pos.x -= $$->segment_width; ++ break; ++ } ++ $$->segment_list = new segment($$->segment_pos, ++ $$->segment_is_absolute, ++ $$->segment_list); ++ $$->flags &= ~HAS_SEGMENT; ++ $$->segment_pos.x = $$->segment_pos.y = 0.0; ++ $$->segment_is_absolute = 0; ++ } ++ | object_spec SOLID ++ { ++ $$ = $1; // nothing ++ } ++ | object_spec DOTTED ++ { ++ $$ = $1; ++ $$->flags |= IS_DOTTED; ++ lookup_variable("dashwid", & $$->dash_width); ++ } ++ | object_spec DOTTED expr ++ { ++ $$ = $1; ++ $$->flags |= IS_DOTTED; ++ $$->dash_width = $3; ++ } ++ | object_spec DASHED ++ { ++ $$ = $1; ++ $$->flags |= IS_DASHED; ++ lookup_variable("dashwid", & $$->dash_width); ++ } ++ | object_spec DASHED expr ++ { ++ $$ = $1; ++ $$->flags |= IS_DASHED; ++ $$->dash_width = $3; ++ } ++ | object_spec FILL ++ { ++ $$ = $1; ++ $$->flags |= IS_DEFAULT_FILLED; ++ } ++ | object_spec FILL expr ++ { ++ $$ = $1; ++ $$->flags |= IS_FILLED; ++ $$->fill = $3; ++ } ++ | object_spec XSLANTED expr ++ { ++ $$ = $1; ++ $$->flags |= IS_XSLANTED; ++ $$->xslanted = $3; ++ } ++ | object_spec YSLANTED expr ++ { ++ $$ = $1; ++ $$->flags |= IS_YSLANTED; ++ $$->yslanted = $3; ++ } ++ | object_spec SHADED text ++ { ++ $$ = $1; ++ $$->flags |= (IS_SHADED | IS_FILLED); ++ $$->shaded = new char[strlen($3.str)+1]; ++ strcpy($$->shaded, $3.str); ++ } ++ | object_spec COLORED text ++ { ++ $$ = $1; ++ $$->flags |= (IS_SHADED | IS_OUTLINED | IS_FILLED); ++ $$->shaded = new char[strlen($3.str)+1]; ++ strcpy($$->shaded, $3.str); ++ $$->outlined = new char[strlen($3.str)+1]; ++ strcpy($$->outlined, $3.str); ++ } ++ | object_spec OUTLINED text ++ { ++ $$ = $1; ++ $$->flags |= IS_OUTLINED; ++ $$->outlined = new char[strlen($3.str)+1]; ++ strcpy($$->outlined, $3.str); ++ } ++ | object_spec CHOP ++ { ++ $$ = $1; ++ // line chop chop means line chop 0 chop 0 ++ if ($$->flags & IS_DEFAULT_CHOPPED) { ++ $$->flags |= IS_CHOPPED; ++ $$->flags &= ~IS_DEFAULT_CHOPPED; ++ $$->start_chop = $$->end_chop = 0.0; ++ } ++ else if ($$->flags & IS_CHOPPED) { ++ $$->end_chop = 0.0; ++ } ++ else { ++ $$->flags |= IS_DEFAULT_CHOPPED; ++ } ++ } ++ | object_spec CHOP expr ++ { ++ $$ = $1; ++ if ($$->flags & IS_DEFAULT_CHOPPED) { ++ $$->flags |= IS_CHOPPED; ++ $$->flags &= ~IS_DEFAULT_CHOPPED; ++ $$->start_chop = 0.0; ++ $$->end_chop = $3; ++ } ++ else if ($$->flags & IS_CHOPPED) { ++ $$->end_chop = $3; ++ } ++ else { ++ $$->start_chop = $$->end_chop = $3; ++ $$->flags |= IS_CHOPPED; ++ } ++ } ++ | object_spec SAME ++ { ++ $$ = $1; ++ $$->flags |= IS_SAME; ++ } ++ | object_spec INVISIBLE ++ { ++ $$ = $1; ++ $$->flags |= IS_INVISIBLE; ++ } ++ | object_spec LEFT_ARROW_HEAD ++ { ++ $$ = $1; ++ $$->flags |= HAS_LEFT_ARROW_HEAD; ++ } ++ | object_spec RIGHT_ARROW_HEAD ++ { ++ $$ = $1; ++ $$->flags |= HAS_RIGHT_ARROW_HEAD; ++ } ++ | object_spec DOUBLE_ARROW_HEAD ++ { ++ $$ = $1; ++ $$->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD); ++ } ++ | object_spec CW ++ { ++ $$ = $1; ++ $$->flags |= IS_CLOCKWISE; ++ } ++ | object_spec CCW ++ { ++ $$ = $1; ++ $$->flags &= ~IS_CLOCKWISE; ++ } ++ | object_spec text %prec TEXT ++ { ++ $$ = $1; ++ text_item **p; ++ for (p = & $$->text; *p; p = &(*p)->next) ++ ; ++ *p = new text_item($2.str, $2.filename, $2.lineno); ++ } ++ | object_spec LJUST ++ { ++ $$ = $1; ++ if ($$->text) { ++ text_item *p; ++ for (p = $$->text; p->next; p = p->next) ++ ; ++ p->adj.h = LEFT_ADJUST; ++ } ++ } ++ | object_spec RJUST ++ { ++ $$ = $1; ++ if ($$->text) { ++ text_item *p; ++ for (p = $$->text; p->next; p = p->next) ++ ; ++ p->adj.h = RIGHT_ADJUST; ++ } ++ } ++ | object_spec ABOVE ++ { ++ $$ = $1; ++ if ($$->text) { ++ text_item *p; ++ for (p = $$->text; p->next; p = p->next) ++ ; ++ p->adj.v = ABOVE_ADJUST; ++ } ++ } ++ | object_spec BELOW ++ { ++ $$ = $1; ++ if ($$->text) { ++ text_item *p; ++ for (p = $$->text; p->next; p = p->next) ++ ; ++ p->adj.v = BELOW_ADJUST; ++ } ++ } ++ | object_spec THICKNESS expr ++ { ++ $$ = $1; ++ $$->flags |= HAS_THICKNESS; ++ $$->thickness = $3; ++ } ++ | object_spec ALIGNED ++ { ++ $$ = $1; ++ $$->flags |= IS_ALIGNED; ++ } ++ ; ++ ++text: ++ TEXT ++ { $$ = $1; } ++ | SPRINTF '(' TEXT sprintf_args ')' ++ { ++ $$.filename = $3.filename; ++ $$.lineno = $3.lineno; ++ $$.str = do_sprintf($3.str, $4.v, $4.nv); ++ a_delete $4.v; ++ a_delete $3.str; ++ } ++ ; ++ ++sprintf_args: ++ /* empty */ ++ { ++ $$.v = 0; ++ $$.nv = 0; ++ $$.maxv = 0; ++ } ++ | sprintf_args ',' expr ++ { ++ $$ = $1; ++ if ($$.nv >= $$.maxv) { ++ if ($$.nv == 0) { ++ $$.v = new double[4]; ++ $$.maxv = 4; ++ } ++ else { ++ double *oldv = $$.v; ++ $$.maxv *= 2; ++#if 0 ++ $$.v = new double[$$.maxv]; ++ memcpy($$.v, oldv, $$.nv*sizeof(double)); ++#else ++ // workaround for bug in Compaq C++ V6.5-033 ++ // for Compaq Tru64 UNIX V5.1A (Rev. 1885) ++ double *foo = new double[$$.maxv]; ++ memcpy(foo, oldv, $$.nv*sizeof(double)); ++ $$.v = foo; ++#endif ++ a_delete oldv; ++ } ++ } ++ $$.v[$$.nv] = $3; ++ $$.nv += 1; ++ } ++ ; ++ ++position: ++ position_not_place ++ { $$ = $1; } ++ | place ++ { ++ position pos = $1; ++ $$.x = pos.x; ++ $$.y = pos.y; ++ } ++ | '(' place ')' ++ { ++ position pos = $2; ++ $$.x = pos.x; ++ $$.y = pos.y; ++ } ++ ; ++ ++position_not_place: ++ expr_pair ++ { $$ = $1; } ++ | position '+' expr_pair ++ { ++ $$.x = $1.x + $3.x; ++ $$.y = $1.y + $3.y; ++ } ++ | '(' position '+' expr_pair ')' ++ { ++ $$.x = $2.x + $4.x; ++ $$.y = $2.y + $4.y; ++ } ++ | position '-' expr_pair ++ { ++ $$.x = $1.x - $3.x; ++ $$.y = $1.y - $3.y; ++ } ++ | '(' position '-' expr_pair ')' ++ { ++ $$.x = $2.x - $4.x; ++ $$.y = $2.y - $4.y; ++ } ++ | '(' position ',' position ')' ++ { ++ $$.x = $2.x; ++ $$.y = $4.y; ++ } ++ | expr between position AND position ++ { ++ $$.x = (1.0 - $1)*$3.x + $1*$5.x; ++ $$.y = (1.0 - $1)*$3.y + $1*$5.y; ++ } ++ | '(' expr between position AND position ')' ++ { ++ $$.x = (1.0 - $2)*$4.x + $2*$6.x; ++ $$.y = (1.0 - $2)*$4.y + $2*$6.y; ++ } ++ /* the next two rules cause harmless shift/reduce warnings */ ++ | expr_not_lower_than '<' position ',' position '>' ++ { ++ $$.x = (1.0 - $1)*$3.x + $1*$5.x; ++ $$.y = (1.0 - $1)*$3.y + $1*$5.y; ++ } ++ | '(' expr_not_lower_than '<' position ',' position '>' ')' ++ { ++ $$.x = (1.0 - $2)*$4.x + $2*$6.x; ++ $$.y = (1.0 - $2)*$4.y + $2*$6.y; ++ } ++ ; ++ ++between: ++ BETWEEN ++ | OF THE WAY BETWEEN ++ ; ++ ++expr_pair: ++ expr ',' expr ++ { ++ $$.x = $1; ++ $$.y = $3; ++ } ++ | '(' expr_pair ')' ++ { $$ = $2; } ++ ; ++ ++place: ++ /* line at A left == line (at A) left */ ++ label %prec CHOP ++ { $$ = $1; } ++ | label corner ++ { ++ path pth($2); ++ if (!pth.follow($1, & $$)) ++ YYABORT; ++ } ++ | corner label ++ { ++ path pth($1); ++ if (!pth.follow($2, & $$)) ++ YYABORT; ++ } ++ | corner OF label ++ { ++ path pth($1); ++ if (!pth.follow($3, & $$)) ++ YYABORT; ++ } ++ | HERE ++ { ++ $$.x = current_position.x; ++ $$.y = current_position.y; ++ $$.obj = 0; ++ } ++ ; ++ ++label: ++ LABEL ++ { ++ place *p = lookup_label($1); ++ if (!p) { ++ lex_error("there is no place `%1'", $1); ++ YYABORT; ++ } ++ $$ = *p; ++ a_delete $1; ++ } ++ | nth_primitive ++ { $$.obj = $1; } ++ | label '.' LABEL ++ { ++ path pth($3); ++ if (!pth.follow($1, & $$)) ++ YYABORT; ++ } ++ ; ++ ++ordinal: ++ ORDINAL ++ { $$ = $1; } ++ | '`' any_expr TH ++ { ++ // XXX Check for overflow (and non-integers?). ++ $$ = (int)$2; ++ } ++ ; ++ ++optional_ordinal_last: ++ LAST ++ { $$ = 1; } ++ | ordinal LAST ++ { $$ = $1; } ++ ; ++ ++nth_primitive: ++ ordinal object_type ++ { ++ int count = 0; ++ object *p; ++ for (p = olist.head; p != 0; p = p->next) ++ if (p->type() == $2 && ++count == $1) { ++ $$ = p; ++ break; ++ } ++ if (p == 0) { ++ lex_error("there is no %1%2 %3", $1, ordinal_postfix($1), ++ object_type_name($2)); ++ YYABORT; ++ } ++ } ++ | optional_ordinal_last object_type ++ { ++ int count = 0; ++ object *p; ++ for (p = olist.tail; p != 0; p = p->prev) ++ if (p->type() == $2 && ++count == $1) { ++ $$ = p; ++ break; ++ } ++ if (p == 0) { ++ lex_error("there is no %1%2 last %3", $1, ++ ordinal_postfix($1), object_type_name($2)); ++ YYABORT; ++ } ++ } ++ ; ++ ++object_type: ++ BOX ++ { $$ = BOX_OBJECT; } ++ | CIRCLE ++ { $$ = CIRCLE_OBJECT; } ++ | ELLIPSE ++ { $$ = ELLIPSE_OBJECT; } ++ | ARC ++ { $$ = ARC_OBJECT; } ++ | LINE ++ { $$ = LINE_OBJECT; } ++ | ARROW ++ { $$ = ARROW_OBJECT; } ++ | SPLINE ++ { $$ = SPLINE_OBJECT; } ++ | '[' ']' ++ { $$ = BLOCK_OBJECT; } ++ | TEXT ++ { $$ = TEXT_OBJECT; } ++ ; ++ ++label_path: ++ '.' LABEL ++ { $$ = new path($2); } ++ | label_path '.' LABEL ++ { ++ $$ = $1; ++ $$->append($3); ++ } ++ ; ++ ++relative_path: ++ corner %prec CHOP ++ { $$ = new path($1); } ++ /* give this a lower precedence than LEFT and RIGHT so that ++ [A: box] with .A left == [A: box] with (.A left) */ ++ | label_path %prec TEXT ++ { $$ = $1; } ++ | label_path corner ++ { ++ $$ = $1; ++ $$->append($2); ++ } ++ ; ++ ++path: ++ relative_path ++ { $$ = $1; } ++ | '(' relative_path ',' relative_path ')' ++ { ++ $$ = $2; ++ $$->set_ypath($4); ++ } ++ /* The rest of these rules are a compatibility sop. */ ++ | ORDINAL LAST object_type relative_path ++ { ++ lex_warning("`%1%2 last %3' in `with' argument ignored", ++ $1, ordinal_postfix($1), object_type_name($3)); ++ $$ = $4; ++ } ++ | LAST object_type relative_path ++ { ++ lex_warning("`last %1' in `with' argument ignored", ++ object_type_name($2)); ++ $$ = $3; ++ } ++ | ORDINAL object_type relative_path ++ { ++ lex_warning("`%1%2 %3' in `with' argument ignored", ++ $1, ordinal_postfix($1), object_type_name($2)); ++ $$ = $3; ++ } ++ | LABEL relative_path ++ { ++ lex_warning("initial `%1' in `with' argument ignored", $1); ++ a_delete $1; ++ $$ = $2; ++ } ++ ; ++ ++corner: ++ DOT_N ++ { $$ = &object::north; } ++ | DOT_E ++ { $$ = &object::east; } ++ | DOT_W ++ { $$ = &object::west; } ++ | DOT_S ++ { $$ = &object::south; } ++ | DOT_NE ++ { $$ = &object::north_east; } ++ | DOT_SE ++ { $$ = &object:: south_east; } ++ | DOT_NW ++ { $$ = &object::north_west; } ++ | DOT_SW ++ { $$ = &object::south_west; } ++ | DOT_C ++ { $$ = &object::center; } ++ | DOT_START ++ { $$ = &object::start; } ++ | DOT_END ++ { $$ = &object::end; } ++ | TOP ++ { $$ = &object::north; } ++ | BOTTOM ++ { $$ = &object::south; } ++ | LEFT ++ { $$ = &object::west; } ++ | RIGHT ++ { $$ = &object::east; } ++ | UPPER LEFT ++ { $$ = &object::north_west; } ++ | LOWER LEFT ++ { $$ = &object::south_west; } ++ | UPPER RIGHT ++ { $$ = &object::north_east; } ++ | LOWER RIGHT ++ { $$ = &object::south_east; } ++ | LEFT_CORNER ++ { $$ = &object::west; } ++ | RIGHT_CORNER ++ { $$ = &object::east; } ++ | UPPER LEFT_CORNER ++ { $$ = &object::north_west; } ++ | LOWER LEFT_CORNER ++ { $$ = &object::south_west; } ++ | UPPER RIGHT_CORNER ++ { $$ = &object::north_east; } ++ | LOWER RIGHT_CORNER ++ { $$ = &object::south_east; } ++ | NORTH ++ { $$ = &object::north; } ++ | SOUTH ++ { $$ = &object::south; } ++ | EAST ++ { $$ = &object::east; } ++ | WEST ++ { $$ = &object::west; } ++ | CENTER ++ { $$ = &object::center; } ++ | START ++ { $$ = &object::start; } ++ | END ++ { $$ = &object::end; } ++ ; ++ ++expr: ++ expr_lower_than ++ { $$ = $1; } ++ | expr_not_lower_than ++ { $$ = $1; } ++ ; ++ ++expr_lower_than: ++ expr '<' expr ++ { $$ = ($1 < $3); } ++ ; ++ ++expr_not_lower_than: ++ VARIABLE ++ { ++ if (!lookup_variable($1, & $$)) { ++ lex_error("there is no variable `%1'", $1); ++ YYABORT; ++ } ++ a_delete $1; ++ } ++ | NUMBER ++ { $$ = $1; } ++ | place DOT_X ++ { ++ if ($1.obj != 0) ++ $$ = $1.obj->origin().x; ++ else ++ $$ = $1.x; ++ } ++ | place DOT_Y ++ { ++ if ($1.obj != 0) ++ $$ = $1.obj->origin().y; ++ else ++ $$ = $1.y; ++ } ++ | place DOT_HT ++ { ++ if ($1.obj != 0) ++ $$ = $1.obj->height(); ++ else ++ $$ = 0.0; ++ } ++ | place DOT_WID ++ { ++ if ($1.obj != 0) ++ $$ = $1.obj->width(); ++ else ++ $$ = 0.0; ++ } ++ | place DOT_RAD ++ { ++ if ($1.obj != 0) ++ $$ = $1.obj->radius(); ++ else ++ $$ = 0.0; ++ } ++ | expr '+' expr ++ { $$ = $1 + $3; } ++ | expr '-' expr ++ { $$ = $1 - $3; } ++ | expr '*' expr ++ { $$ = $1 * $3; } ++ | expr '/' expr ++ { ++ if ($3 == 0.0) { ++ lex_error("division by zero"); ++ YYABORT; ++ } ++ $$ = $1/$3; ++ } ++ | expr '%' expr ++ { ++ if ($3 == 0.0) { ++ lex_error("modulus by zero"); ++ YYABORT; ++ } ++ $$ = fmod($1, $3); ++ } ++ | expr '^' expr ++ { ++ errno = 0; ++ $$ = pow($1, $3); ++ if (errno == EDOM) { ++ lex_error("arguments to `^' operator out of domain"); ++ YYABORT; ++ } ++ if (errno == ERANGE) { ++ lex_error("result of `^' operator out of range"); ++ YYABORT; ++ } ++ } ++ | '-' expr %prec '!' ++ { $$ = -$2; } ++ | '(' any_expr ')' ++ { $$ = $2; } ++ | SIN '(' any_expr ')' ++ { ++ errno = 0; ++ $$ = sin($3); ++ if (errno == ERANGE) { ++ lex_error("sin result out of range"); ++ YYABORT; ++ } ++ } ++ | COS '(' any_expr ')' ++ { ++ errno = 0; ++ $$ = cos($3); ++ if (errno == ERANGE) { ++ lex_error("cos result out of range"); ++ YYABORT; ++ } ++ } ++ | ATAN2 '(' any_expr ',' any_expr ')' ++ { ++ errno = 0; ++ $$ = atan2($3, $5); ++ if (errno == EDOM) { ++ lex_error("atan2 argument out of domain"); ++ YYABORT; ++ } ++ if (errno == ERANGE) { ++ lex_error("atan2 result out of range"); ++ YYABORT; ++ } ++ } ++ | LOG '(' any_expr ')' ++ { ++ errno = 0; ++ $$ = log10($3); ++ if (errno == ERANGE) { ++ lex_error("log result out of range"); ++ YYABORT; ++ } ++ } ++ | EXP '(' any_expr ')' ++ { ++ errno = 0; ++ $$ = pow(10.0, $3); ++ if (errno == ERANGE) { ++ lex_error("exp result out of range"); ++ YYABORT; ++ } ++ } ++ | SQRT '(' any_expr ')' ++ { ++ errno = 0; ++ $$ = sqrt($3); ++ if (errno == EDOM) { ++ lex_error("sqrt argument out of domain"); ++ YYABORT; ++ } ++ } ++ | K_MAX '(' any_expr ',' any_expr ')' ++ { $$ = $3 > $5 ? $3 : $5; } ++ | K_MIN '(' any_expr ',' any_expr ')' ++ { $$ = $3 < $5 ? $3 : $5; } ++ | INT '(' any_expr ')' ++ { $$ = $3 < 0 ? -floor(-$3) : floor($3); } ++ | RAND '(' any_expr ')' ++ { $$ = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*$3); } ++ | RAND '(' ')' ++ { ++ /* return a random number in the range [0,1) */ ++ /* portable, but not very random */ ++ $$ = (rand() & 0x7fff) / double(0x8000); ++ } ++ | SRAND '(' any_expr ')' ++ { ++ $$ = 0; ++ srand((unsigned int)$3); ++ } ++ | expr LESSEQUAL expr ++ { $$ = ($1 <= $3); } ++ | expr '>' expr ++ { $$ = ($1 > $3); } ++ | expr GREATEREQUAL expr ++ { $$ = ($1 >= $3); } ++ | expr EQUALEQUAL expr ++ { $$ = ($1 == $3); } ++ | expr NOTEQUAL expr ++ { $$ = ($1 != $3); } ++ | expr ANDAND expr ++ { $$ = ($1 != 0.0 && $3 != 0.0); } ++ | expr OROR expr ++ { $$ = ($1 != 0.0 || $3 != 0.0); } ++ | '!' expr ++ { $$ = ($2 == 0.0); } ++ ++ ; ++ ++%% ++ ++/* bison defines const to be empty unless __STDC__ is defined, which it ++isn't under cfront */ ++ ++#ifdef const ++#undef const ++#endif ++ ++static struct { ++ const char *name; ++ double val; ++ int scaled; // non-zero if val should be multiplied by scale ++} defaults_table[] = { ++ { "arcrad", .25, 1 }, ++ { "arrowht", .1, 1 }, ++ { "arrowwid", .05, 1 }, ++ { "circlerad", .25, 1 }, ++ { "boxht", .5, 1 }, ++ { "boxwid", .75, 1 }, ++ { "boxrad", 0.0, 1 }, ++ { "dashwid", .05, 1 }, ++ { "ellipseht", .5, 1 }, ++ { "ellipsewid", .75, 1 }, ++ { "moveht", .5, 1 }, ++ { "movewid", .5, 1 }, ++ { "lineht", .5, 1 }, ++ { "linewid", .5, 1 }, ++ { "textht", 0.0, 1 }, ++ { "textwid", 0.0, 1 }, ++ { "scale", 1.0, 0 }, ++ { "linethick", -1.0, 0 }, // in points ++ { "fillval", .5, 0 }, ++ { "arrowhead", 1.0, 0 }, ++ { "maxpswid", 8.5, 0 }, ++ { "maxpsht", 11.0, 0 }, ++}; ++ ++place *lookup_label(const char *label) ++{ ++ saved_state *state = current_saved_state; ++ PTABLE(place) *tbl = current_table; ++ for (;;) { ++ place *pl = tbl->lookup(label); ++ if (pl) ++ return pl; ++ if (!state) ++ return 0; ++ tbl = state->tbl; ++ state = state->prev; ++ } ++} ++ ++void define_label(const char *label, const place *pl) ++{ ++ place *p = new place[1]; ++ *p = *pl; ++ current_table->define(label, p); ++} ++ ++int lookup_variable(const char *name, double *val) ++{ ++ place *pl = lookup_label(name); ++ if (pl) { ++ *val = pl->x; ++ return 1; ++ } ++ return 0; ++} ++ ++void define_variable(const char *name, double val) ++{ ++ place *p = new place[1]; ++ p->obj = 0; ++ p->x = val; ++ p->y = 0.0; ++ current_table->define(name, p); ++ if (strcmp(name, "scale") == 0) { ++ // When the scale changes, reset all scaled pre-defined variables to ++ // their default values. ++ for (unsigned int i = 0; ++ i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) ++ if (defaults_table[i].scaled) ++ define_variable(defaults_table[i].name, val*defaults_table[i].val); ++ } ++} ++ ++// called once only (not once per parse) ++ ++void parse_init() ++{ ++ current_direction = RIGHT_DIRECTION; ++ current_position.x = 0.0; ++ current_position.y = 0.0; ++ // This resets everything to its default value. ++ reset_all(); ++} ++ ++void reset(const char *nm) ++{ ++ for (unsigned int i = 0; ++ i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) ++ if (strcmp(nm, defaults_table[i].name) == 0) { ++ double val = defaults_table[i].val; ++ if (defaults_table[i].scaled) { ++ double scale; ++ lookup_variable("scale", &scale); ++ val *= scale; ++ } ++ define_variable(defaults_table[i].name, val); ++ return; ++ } ++ lex_error("`%1' is not a predefined variable", nm); ++} ++ ++void reset_all() ++{ ++ // We only have to explicitly reset the pre-defined variables that ++ // aren't scaled because `scale' is not scaled, and changing the ++ // value of `scale' will reset all the pre-defined variables that ++ // are scaled. ++ for (unsigned int i = 0; ++ i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) ++ if (!defaults_table[i].scaled) ++ define_variable(defaults_table[i].name, defaults_table[i].val); ++} ++ ++// called after each parse ++ ++void parse_cleanup() ++{ ++ while (current_saved_state != 0) { ++ delete current_table; ++ current_table = current_saved_state->tbl; ++ saved_state *tem = current_saved_state; ++ current_saved_state = current_saved_state->prev; ++ delete tem; ++ } ++ assert(current_table == &top_table); ++ PTABLE_ITERATOR(place) iter(current_table); ++ const char *key; ++ place *pl; ++ while (iter.next(&key, &pl)) ++ if (pl->obj != 0) { ++ position pos = pl->obj->origin(); ++ pl->obj = 0; ++ pl->x = pos.x; ++ pl->y = pos.y; ++ } ++ while (olist.head != 0) { ++ object *tem = olist.head; ++ olist.head = olist.head->next; ++ delete tem; ++ } ++ olist.tail = 0; ++ current_direction = RIGHT_DIRECTION; ++ current_position.x = 0.0; ++ current_position.y = 0.0; ++} ++ ++const char *ordinal_postfix(int n) ++{ ++ if (n < 10 || n > 20) ++ switch (n % 10) { ++ case 1: ++ return "st"; ++ case 2: ++ return "nd"; ++ case 3: ++ return "rd"; ++ } ++ return "th"; ++} ++ ++const char *object_type_name(object_type type) ++{ ++ switch (type) { ++ case BOX_OBJECT: ++ return "box"; ++ case CIRCLE_OBJECT: ++ return "circle"; ++ case ELLIPSE_OBJECT: ++ return "ellipse"; ++ case ARC_OBJECT: ++ return "arc"; ++ case SPLINE_OBJECT: ++ return "spline"; ++ case LINE_OBJECT: ++ return "line"; ++ case ARROW_OBJECT: ++ return "arrow"; ++ case MOVE_OBJECT: ++ return "move"; ++ case TEXT_OBJECT: ++ return "\"\""; ++ case BLOCK_OBJECT: ++ return "[]"; ++ case OTHER_OBJECT: ++ case MARK_OBJECT: ++ default: ++ break; ++ } ++ return "object"; ++} ++ ++static char sprintf_buf[1024]; ++ ++char *format_number(const char *form, double n) ++{ ++ if (form == 0) ++ form = "%g"; ++ return do_sprintf(form, &n, 1); ++} ++ ++char *do_sprintf(const char *form, const double *v, int nv) ++{ ++ string result; ++ int i = 0; ++ string one_format; ++ while (*form) { ++ if (*form == '%') { ++ one_format += *form++; ++ for (; *form != '\0' && strchr("#-+ 0123456789.", *form) != 0; form++) ++ one_format += *form; ++ if (*form == '\0' || strchr("eEfgG%", *form) == 0) { ++ lex_error("bad sprintf format"); ++ result += one_format; ++ result += form; ++ break; ++ } ++ if (*form == '%') { ++ one_format += *form++; ++ one_format += '\0'; ++ snprintf(sprintf_buf, sizeof(sprintf_buf), ++ "%s", one_format.contents()); ++ } ++ else { ++ if (i >= nv) { ++ lex_error("too few arguments to snprintf"); ++ result += one_format; ++ result += form; ++ break; ++ } ++ one_format += *form++; ++ one_format += '\0'; ++ snprintf(sprintf_buf, sizeof(sprintf_buf), ++ one_format.contents(), v[i++]); ++ } ++ one_format.clear(); ++ result += sprintf_buf; ++ } ++ else ++ result += *form++; ++ } ++ result += '\0'; ++ return strsave(result.contents()); ++} +diff -Nuar groff-1.22.3.old/src/preproc/preconv/.gitignore groff-1.22.3/src/preproc/preconv/.gitignore +--- groff-1.22.3.old/src/preproc/preconv/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/preconv/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++preconv ++preconv.n +diff -Nuar groff-1.22.3.old/src/preproc/preconv/Makefile.sub groff-1.22.3/src/preproc/preconv/Makefile.sub +--- groff-1.22.3.old/src/preproc/preconv/Makefile.sub 2014-11-04 10:38:35.214524134 +0200 ++++ groff-1.22.3/src/preproc/preconv/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,39 +0,0 @@ +-# Makefile.sub for `preproc preconv' +-# +-# File position: /src/preproc/preconv/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=preconv$(EXEEXT) +-MAN1=preconv.n +-XLIBS=$(LIBGROFF) +-MLIB=$(LIBM) +-EXTRA_LDFLAGS=$(LIBICONV) +-OBJS=preconv.$(OBJEXT) +-CCSRCS=$(srcdir)/preconv.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/preproc/preconv/preconv.am groff-1.22.3/src/preproc/preconv/preconv.am +--- groff-1.22.3.old/src/preproc/preconv/preconv.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/preconv/preconv.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,23 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += preconv ++preconv_LDADD = libgroff.a $(LIBM) $(LIBICONV) ++preconv_SOURCES = src/preproc/preconv/preconv.cpp ++man1_MANS += src/preproc/preconv/preconv.n ++EXTRA_DIST += src/preproc/preconv/preconv.man +diff -Nuar groff-1.22.3.old/src/preproc/preconv/preconv.cpp groff-1.22.3/src/preproc/preconv/preconv.cpp +--- groff-1.22.3.old/src/preproc/preconv/preconv.cpp 2014-11-04 10:38:35.214524134 +0200 ++++ groff-1.22.3/src/preproc/preconv/preconv.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -27,6 +27,7 @@ + #include "localcharset.h" + #include "nonposix.h" + #include "stringclass.h" ++#include "lf.h" + + #include + +@@ -1065,8 +1066,12 @@ + } + if (debug_flag) + fprintf(stderr, " encoding used: `%s'\n", encoding); +- if (!raw_flag) +- printf(".lf 1 %s\n", filename); ++ if (!raw_flag) { ++ string fn(filename); ++ fn += '\0'; ++ normalize_for_lf(fn); ++ printf(".lf 1 %s\n", fn.contents()); ++ } + int success = 1; + // Call converter (converters write to stdout). + if (!strcasecmp(encoding, "ISO-8859-1")) +diff -Nuar groff-1.22.3.old/src/preproc/preconv/preconv.man groff-1.22.3/src/preproc/preconv/preconv.man +--- groff-1.22.3.old/src/preproc/preconv/preconv.man 2014-11-04 10:38:35.214524134 +0200 ++++ groff-1.22.3/src/preproc/preconv/preconv.man 2015-04-23 20:57:03.000000000 +0300 +@@ -3,6 +3,10 @@ + preconv \- convert encoding of input files to something GNU troff understands + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" license (copying) + .de co + Copyright \[co] 2006-2014 Free Software Foundation, Inc. +@@ -355,6 +359,9 @@ + .co + . + . ++.cp \n[groff_C] ++. ++. + .\" Emacs setting + .\" Local Variables: + .\" mode: nroff +diff -Nuar groff-1.22.3.old/src/preproc/refer/.gitignore groff-1.22.3/src/preproc/refer/.gitignore +--- groff-1.22.3.old/src/preproc/refer/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/refer/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,5 @@ ++Makefile.dep ++refer ++refer.n ++y.output ++label.cpp +diff -Nuar groff-1.22.3.old/src/preproc/refer/label.cpp groff-1.22.3/src/preproc/refer/label.cpp +--- groff-1.22.3.old/src/preproc/refer/label.cpp 2014-11-04 10:38:38.659481067 +0200 ++++ groff-1.22.3/src/preproc/refer/label.cpp 1970-01-01 02:00:00.000000000 +0200 +@@ -1,2701 +0,0 @@ +-/* A Bison parser, made by GNU Bison 3.0.2. */ +- +-/* Bison implementation for Yacc-like parsers in C +- +- Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. +- +- This program is free software: you can redistribute it and/or modify +- it under the terms of the GNU General Public License as published by +- the Free Software Foundation, either version 3 of the License, or +- (at your option) any later version. +- +- This program is distributed in the hope that it will be useful, +- but WITHOUT ANY WARRANTY; without even the implied warranty of +- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- GNU General Public License for more details. +- +- You should have received a copy of the GNU General Public License +- along with this program. If not, see . */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* C LALR(1) parser skeleton written by Richard Stallman, by +- simplifying the original so-called "semantic" parser. */ +- +-/* All symbols defined below should begin with yy or YY, to avoid +- infringing on user name space. This should be done even for local +- variables, as they might otherwise be expanded by user macros. +- There are some unavoidable exceptions within include files to +- define necessary library symbols; they are noted "INFRINGES ON +- USER NAME SPACE" below. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 +- +-/* Bison version. */ +-#define YYBISON_VERSION "3.0.2" +- +-/* Skeleton name. */ +-#define YYSKELETON_NAME "yacc.c" +- +-/* Pure parsers. */ +-#define YYPURE 0 +- +-/* Push parsers. */ +-#define YYPUSH 0 +- +-/* Pull parsers. */ +-#define YYPULL 1 +- +- +- +- +-/* Copy the first part of user declarations. */ +-#line 20 "label.y" /* yacc.c:339 */ +- +- +-#include "refer.h" +-#include "refid.h" +-#include "ref.h" +-#include "token.h" +- +-int yylex(); +-void yyerror(const char *); +-int yyparse(); +- +-static const char *format_serial(char c, int n); +- +-struct label_info { +- int start; +- int length; +- int count; +- int total; +- label_info(const string &); +-}; +- +-label_info *lookup_label(const string &label); +- +-struct expression { +- enum { +- // Does the tentative label depend on the reference? +- CONTAINS_VARIABLE = 01, +- CONTAINS_STAR = 02, +- CONTAINS_FORMAT = 04, +- CONTAINS_AT = 010 +- }; +- virtual ~expression() { } +- virtual void evaluate(int, const reference &, string &, +- substring_position &) = 0; +- virtual unsigned analyze() { return 0; } +-}; +- +-class at_expr : public expression { +-public: +- at_expr() { } +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { return CONTAINS_VARIABLE|CONTAINS_AT; } +-}; +- +-class format_expr : public expression { +- char type; +- int width; +- int first_number; +-public: +- format_expr(char c, int w = 0, int f = 1) +- : type(c), width(w), first_number(f) { } +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { return CONTAINS_FORMAT; } +-}; +- +-class field_expr : public expression { +- int number; +- char name; +-public: +- field_expr(char nm, int num) : number(num), name(nm) { } +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { return CONTAINS_VARIABLE; } +-}; +- +-class literal_expr : public expression { +- string s; +-public: +- literal_expr(const char *ptr, int len) : s(ptr, len) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class unary_expr : public expression { +-protected: +- expression *expr; +-public: +- unary_expr(expression *e) : expr(e) { } +- ~unary_expr() { delete expr; } +- void evaluate(int, const reference &, string &, substring_position &) = 0; +- unsigned analyze() { return expr ? expr->analyze() : 0; } +-}; +- +-// This caches the analysis of an expression. +- +-class analyzed_expr : public unary_expr { +- unsigned flags; +-public: +- analyzed_expr(expression *); +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { return flags; } +-}; +- +-class star_expr : public unary_expr { +-public: +- star_expr(expression *e) : unary_expr(e) { } +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { +- return ((expr ? (expr->analyze() & ~CONTAINS_VARIABLE) : 0) +- | CONTAINS_STAR); +- } +-}; +- +-typedef void map_func(const char *, const char *, string &); +- +-class map_expr : public unary_expr { +- map_func *func; +-public: +- map_expr(expression *e, map_func *f) : unary_expr(e), func(f) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-typedef const char *extractor_func(const char *, const char *, const char **); +- +-class extractor_expr : public unary_expr { +- int part; +- extractor_func *func; +-public: +- enum { BEFORE = +1, MATCH = 0, AFTER = -1 }; +- extractor_expr(expression *e, extractor_func *f, int pt) +- : unary_expr(e), part(pt), func(f) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class truncate_expr : public unary_expr { +- int n; +-public: +- truncate_expr(expression *e, int i) : unary_expr(e), n(i) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class separator_expr : public unary_expr { +-public: +- separator_expr(expression *e) : unary_expr(e) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class binary_expr : public expression { +-protected: +- expression *expr1; +- expression *expr2; +-public: +- binary_expr(expression *e1, expression *e2) : expr1(e1), expr2(e2) { } +- ~binary_expr() { delete expr1; delete expr2; } +- void evaluate(int, const reference &, string &, substring_position &) = 0; +- unsigned analyze() { +- return (expr1 ? expr1->analyze() : 0) | (expr2 ? expr2->analyze() : 0); +- } +-}; +- +-class alternative_expr : public binary_expr { +-public: +- alternative_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class list_expr : public binary_expr { +-public: +- list_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class substitute_expr : public binary_expr { +-public: +- substitute_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class ternary_expr : public expression { +-protected: +- expression *expr1; +- expression *expr2; +- expression *expr3; +-public: +- ternary_expr(expression *e1, expression *e2, expression *e3) +- : expr1(e1), expr2(e2), expr3(e3) { } +- ~ternary_expr() { delete expr1; delete expr2; delete expr3; } +- void evaluate(int, const reference &, string &, substring_position &) = 0; +- unsigned analyze() { +- return ((expr1 ? expr1->analyze() : 0) +- | (expr2 ? expr2->analyze() : 0) +- | (expr3 ? expr3->analyze() : 0)); +- } +-}; +- +-class conditional_expr : public ternary_expr { +-public: +- conditional_expr(expression *e1, expression *e2, expression *e3) +- : ternary_expr(e1, e2, e3) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-static expression *parsed_label = 0; +-static expression *parsed_date_label = 0; +-static expression *parsed_short_label = 0; +- +-static expression *parse_result; +- +-string literals; +- +- +-#line 266 "label.cpp" /* yacc.c:339 */ +- +-# ifndef YY_NULLPTR +-# if defined __cplusplus && 201103L <= __cplusplus +-# define YY_NULLPTR nullptr +-# else +-# define YY_NULLPTR 0 +-# endif +-# endif +- +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 0 +-#endif +- +- +-/* Debug traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +-#if YYDEBUG +-extern int yydebug; +-#endif +- +-/* Token type. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- enum yytokentype +- { +- TOKEN_LETTER = 258, +- TOKEN_LITERAL = 259, +- TOKEN_DIGIT = 260 +- }; +-#endif +-/* Tokens. */ +-#define TOKEN_LETTER 258 +-#define TOKEN_LITERAL 259 +-#define TOKEN_DIGIT 260 +- +-/* Value type. */ +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE YYSTYPE; +-union YYSTYPE +-{ +-#line 220 "label.y" /* yacc.c:355 */ +- +- int num; +- expression *expr; +- struct { int ndigits; int val; } dig; +- struct { int start; int len; } str; +- +-#line 320 "label.cpp" /* yacc.c:355 */ +-}; +-# define YYSTYPE_IS_TRIVIAL 1 +-# define YYSTYPE_IS_DECLARED 1 +-#endif +- +- +-extern YYSTYPE yylval; +- +-int yyparse (void); +- +- +- +-/* Copy the second part of user declarations. */ +- +-#line 335 "label.cpp" /* yacc.c:358 */ +- +-#ifdef short +-# undef short +-#endif +- +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; +-#endif +- +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; +-#else +-typedef signed char yytype_int8; +-#endif +- +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; +-#else +-typedef unsigned short int yytype_uint16; +-#endif +- +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; +-#else +-typedef short int yytype_int16; +-#endif +- +-#ifndef YYSIZE_T +-# ifdef __SIZE_TYPE__ +-# define YYSIZE_T __SIZE_TYPE__ +-# elif defined size_t +-# define YYSIZE_T size_t +-# elif ! defined YYSIZE_T +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# else +-# define YYSIZE_T unsigned int +-# endif +-#endif +- +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +- +-#ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS +-# if ENABLE_NLS +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +-# endif +-# endif +-# ifndef YY_ +-# define YY_(Msgid) Msgid +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE +-# if (defined __GNUC__ \ +- && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ +- || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +-# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +-# else +-# define YY_ATTRIBUTE(Spec) /* empty */ +-# endif +-#endif +- +-#ifndef YY_ATTRIBUTE_PURE +-# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +-#endif +- +-#ifndef YY_ATTRIBUTE_UNUSED +-# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +-#endif +- +-#if !defined _Noreturn \ +- && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +-# if defined _MSC_VER && 1200 <= _MSC_VER +-# define _Noreturn __declspec (noreturn) +-# else +-# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +-# endif +-#endif +- +-/* Suppress unused-variable warnings by "using" E. */ +-#if ! defined lint || defined __GNUC__ +-# define YYUSE(E) ((void) (E)) +-#else +-# define YYUSE(E) /* empty */ +-#endif +- +-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +-/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +- _Pragma ("GCC diagnostic push") \ +- _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ +- _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ +- _Pragma ("GCC diagnostic pop") +-#else +-# define YY_INITIAL_VALUE(Value) Value +-#endif +-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +-# define YY_IGNORE_MAYBE_UNINITIALIZED_END +-#endif +-#ifndef YY_INITIAL_VALUE +-# define YY_INITIAL_VALUE(Value) /* Nothing. */ +-#endif +- +- +-#if ! defined yyoverflow || YYERROR_VERBOSE +- +-/* The parser invokes alloca or malloc; define the necessary symbols. */ +- +-# ifdef YYSTACK_USE_ALLOCA +-# if YYSTACK_USE_ALLOCA +-# ifdef __GNUC__ +-# define YYSTACK_ALLOC __builtin_alloca +-# elif defined __BUILTIN_VA_ARG_INCR +-# include /* INFRINGES ON USER NAME SPACE */ +-# elif defined _AIX +-# define YYSTACK_ALLOC __alloca +-# elif defined _MSC_VER +-# include /* INFRINGES ON USER NAME SPACE */ +-# define alloca _alloca +-# else +-# define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +-# include /* INFRINGES ON USER NAME SPACE */ +- /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +-# ifndef EXIT_SUCCESS +-# define EXIT_SUCCESS 0 +-# endif +-# endif +-# endif +-# endif +-# endif +- +-# ifdef YYSTACK_ALLOC +- /* Pacify GCC's 'empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +-# ifndef YYSTACK_ALLOC_MAXIMUM +- /* The OS might guarantee only one guard page at the bottom of the stack, +- and a page size can be as small as 4096 bytes. So we cannot safely +- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number +- to allow for a few compiler-allocated temporary stack slots. */ +-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +-# endif +-# else +-# define YYSTACK_ALLOC YYMALLOC +-# define YYSTACK_FREE YYFREE +-# ifndef YYSTACK_ALLOC_MAXIMUM +-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +-# endif +-# if (defined __cplusplus && ! defined EXIT_SUCCESS \ +- && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef EXIT_SUCCESS +-# define EXIT_SUCCESS 0 +-# endif +-# endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc +-# if ! defined malloc && ! defined EXIT_SUCCESS +-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# ifndef YYFREE +-# define YYFREE free +-# if ! defined free && ! defined EXIT_SUCCESS +-void free (void *); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- +- +-#if (! defined yyoverflow \ +- && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +- +-/* A type that is properly aligned for any stack member. */ +-union yyalloc +-{ +- yytype_int16 yyss_alloc; +- YYSTYPE yyvs_alloc; +-}; +- +-/* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +- +-/* The size of an array large to enough to hold all stacks, each with +- N elements. */ +-# define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) +- +-# define YYCOPY_NEEDED 1 +- +-/* Relocate STACK from its old location to the new one. The +- local variables YYSIZE and YYSTACKSIZE give the old and new number of +- elements in the stack, and YYPTR gives the new location of the +- stack. Advance YYPTR to a properly aligned location for the next +- stack. */ +-# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ +- Stack = &yyptr->Stack_alloc; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (0) +- +-#endif +- +-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +-/* Copy COUNT objects from SRC to DST. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(Dst, Src, Count) \ +- __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +-# else +-# define YYCOPY(Dst, Src, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (Dst)[yyi] = (Src)[yyi]; \ +- } \ +- while (0) +-# endif +-# endif +-#endif /* !YYCOPY_NEEDED */ +- +-/* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 21 +-/* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 39 +- +-/* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 21 +-/* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 12 +-/* YYNRULES -- Number of rules. */ +-#define YYNRULES 34 +-/* YYNSTATES -- Number of states. */ +-#define YYNSTATES 49 +- +-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned +- by yylex, with out-of-bounds checking. */ +-#define YYUNDEFTOK 2 +-#define YYMAXUTOK 260 +- +-#define YYTRANSLATE(YYX) \ +- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +- +-/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM +- as returned by yylex, without out-of-bounds checking. */ +-static const yytype_uint8 yytranslate[] = +-{ +- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 12, 9, 2, +- 17, 18, 16, 14, 2, 15, 13, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, +- 19, 2, 20, 6, 11, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 8, 2, 10, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, +- 5 +-}; +- +-#if YYDEBUG +- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +-static const yytype_uint16 yyrline[] = +-{ +- 0, 248, 248, 253, 255, 261, 262, 267, 269, 271, +- 276, 278, 283, 285, 290, 292, 297, 299, 301, 317, +- 321, 352, 354, 356, 358, 360, 366, 367, 372, 374, +- 379, 381, 388, 389, 391 +-}; +-#endif +- +-#if YYDEBUG || YYERROR_VERBOSE || 0 +-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +-static const char *const yytname[] = +-{ +- "$end", "error", "$undefined", "TOKEN_LETTER", "TOKEN_LITERAL", +- "TOKEN_DIGIT", "'?'", "':'", "'|'", "'&'", "'~'", "'@'", "'%'", "'.'", +- "'+'", "'-'", "'*'", "'('", "')'", "'<'", "'>'", "$accept", "expr", +- "conditional", "optional_conditional", "alternative", "list", +- "substitute", "string", "optional_number", "number", "digits", "flag", YY_NULLPTR +-}; +-#endif +- +-# ifdef YYPRINT +-/* YYTOKNUM[NUM] -- (External) token number corresponding to the +- (internal) symbol number NUM (which must be that of a token). */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 260, 63, 58, 124, 38, +- 126, 64, 37, 46, 43, 45, 42, 40, 41, 60, +- 62 +-}; +-# endif +- +-#define YYPACT_NINF -26 +- +-#define yypact_value_is_default(Yystate) \ +- (!!((Yystate) == (-26))) +- +-#define YYTABLE_NINF -1 +- +-#define yytable_value_is_error(Yytable_value) \ +- 0 +- +- /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-static const yytype_int8 yypact[] = +-{ +- 2, 11, -26, -26, 12, 2, 2, 24, -26, -26, +- 21, 2, 18, -6, -26, 26, -26, -26, 27, 15, +- 14, -26, 2, 2, 2, 18, 2, -3, 11, 11, +- -26, -26, -26, -26, -26, 28, 2, 2, -6, -26, +- -26, 33, 26, 26, 2, 11, -26, -26, 26 +-}; +- +- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. +- Performed when YYTABLE does not specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = +-{ +- 5, 16, 15, 14, 0, 5, 5, 0, 6, 2, +- 3, 7, 10, 12, 28, 17, 18, 30, 19, 0, +- 0, 1, 5, 0, 0, 11, 0, 32, 0, 0, +- 23, 29, 31, 24, 25, 0, 8, 9, 13, 33, +- 34, 0, 21, 22, 0, 26, 4, 20, 27 +-}; +- +- /* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = +-{ +- -26, -26, -7, -4, -26, -1, -11, 13, -26, -25, +- -26, -26 +-}; +- +- /* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int8 yydefgoto[] = +-{ +- -1, 7, 8, 9, 10, 11, 12, 13, 47, 15, +- 18, 41 +-}; +- +- /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule whose +- number is the opposite. If YYTABLE_NINF, syntax error. */ +-static const yytype_uint8 yytable[] = +-{ +- 25, 19, 20, 42, 43, 1, 2, 27, 28, 29, +- 30, 39, 40, 3, 4, 16, 14, 17, 35, 5, +- 48, 6, 36, 37, 21, 25, 25, 22, 26, 23, +- 24, 31, 32, 33, 34, 44, 45, 46, 0, 38 +-}; +- +-static const yytype_int8 yycheck[] = +-{ +- 11, 5, 6, 28, 29, 3, 4, 13, 14, 15, +- 16, 14, 15, 11, 12, 3, 5, 5, 22, 17, +- 45, 19, 23, 24, 0, 36, 37, 6, 10, 8, +- 9, 5, 5, 18, 20, 7, 3, 44, -1, 26 +-}; +- +- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = +-{ +- 0, 3, 4, 11, 12, 17, 19, 22, 23, 24, +- 25, 26, 27, 28, 5, 30, 3, 5, 31, 24, +- 24, 0, 6, 8, 9, 27, 10, 13, 14, 15, +- 16, 5, 5, 18, 20, 24, 26, 26, 28, 14, +- 15, 32, 30, 30, 7, 3, 23, 29, 30 +-}; +- +- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 21, 22, 23, 23, 24, 24, 25, 25, 25, +- 26, 26, 27, 27, 28, 28, 28, 28, 28, 28, +- 28, 28, 28, 28, 28, 28, 29, 29, 30, 30, +- 31, 31, 32, 32, 32 +-}; +- +- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = +-{ +- 0, 2, 1, 1, 5, 0, 1, 1, 3, 3, +- 1, 2, 1, 3, 1, 1, 1, 2, 2, 2, +- 5, 3, 3, 2, 3, 3, 0, 1, 1, 2, +- 1, 2, 0, 1, 1 +-}; +- +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-#define YYRECOVERING() (!!yyerrstatus) +- +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- YYPOPSTACK (yylen); \ +- yystate = *yyssp; \ +- goto yybackup; \ +- } \ +- else \ +- { \ +- yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (0) +- +-/* Error token number */ +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (0) +- +-/* This macro is provided for backward compatibility. */ +-#ifndef YY_LOCATION_PRINT +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-#endif +- +- +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (0) +- +- +-/*----------------------------------------. +-| Print this symbol's value on YYOUTPUT. | +-`----------------------------------------*/ +- +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-{ +- FILE *yyo = yyoutput; +- YYUSE (yyo); +- if (!yyvaluep) +- return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# endif +- YYUSE (yytype); +-} +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-{ +- YYFPRINTF (yyoutput, "%s %s (", +- yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); +- +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); +- YYFPRINTF (yyoutput, ")"); +-} +- +-/*------------------------------------------------------------------. +-| yy_stack_print -- Print the state stack from its BOTTOM up to its | +-| TOP (included). | +-`------------------------------------------------------------------*/ +- +-static void +-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +-{ +- YYFPRINTF (stderr, "Stack now"); +- for (; yybottom <= yytop; yybottom++) +- { +- int yybot = *yybottom; +- YYFPRINTF (stderr, " %d", yybot); +- } +- YYFPRINTF (stderr, "\n"); +-} +- +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (0) +- +- +-/*------------------------------------------------. +-| Report that the YYRULE is going to be reduced. | +-`------------------------------------------------*/ +- +-static void +-yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +-{ +- unsigned long int yylno = yyrline[yyrule]; +- int yynrhs = yyr2[yyrule]; +- int yyi; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); +- /* The symbols being reduced. */ +- for (yyi = 0; yyi < yynrhs; yyi++) +- { +- YYFPRINTF (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, +- yystos[yyssp[yyi + 1 - yynrhs]], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); +- YYFPRINTF (stderr, "\n"); +- } +-} +- +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyssp, yyvsp, Rule); \ +-} while (0) +- +-/* Nonzero means print parse trace. It is left uninitialized so that +- multiple parsers can coexist. */ +-int yydebug; +-#else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +-# define YY_STACK_PRINT(Bottom, Top) +-# define YY_REDUCE_PRINT(Rule) +-#endif /* !YYDEBUG */ +- +- +-/* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH +-# define YYINITDEPTH 200 +-#endif +- +-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +- if the built-in stack extension method is used). +- +- Do not make this value too large; the results are undefined if +- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +- evaluated with infinite-precision integer arithmetic. */ +- +-#ifndef YYMAXDEPTH +-# define YYMAXDEPTH 10000 +-#endif +- +- +-#if YYERROR_VERBOSE +- +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else +-/* Return the length of YYSTR. */ +-static YYSIZE_T +-yystrlen (const char *yystr) +-{ +- YYSIZE_T yylen; +- for (yylen = 0; yystr[yylen]; yylen++) +- continue; +- return yylen; +-} +-# endif +-# endif +- +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else +-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +- YYDEST. */ +-static char * +-yystpcpy (char *yydest, const char *yysrc) +-{ +- char *yyd = yydest; +- const char *yys = yysrc; +- +- while ((*yyd++ = *yys++) != '\0') +- continue; +- +- return yyd - 1; +-} +-# endif +-# endif +- +-# ifndef yytnamerr +-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +- quotes and backslashes, so that it's suitable for yyerror. The +- heuristic is that double-quoting is unnecessary unless the string +- contains an apostrophe, a comma, or backslash (other than +- backslash-backslash). YYSTR is taken from yytname. If YYRES is +- null, do not copy; instead, return the length of what the result +- would have been. */ +-static YYSIZE_T +-yytnamerr (char *yyres, const char *yystr) +-{ +- if (*yystr == '"') +- { +- YYSIZE_T yyn = 0; +- char const *yyp = yystr; +- +- for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } +- do_not_strip_quotes: ; +- } +- +- if (! yyres) +- return yystrlen (yystr); +- +- return yystpcpy (yyres, yystr) - yyres; +-} +-# endif +- +-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message +- about the unexpected token YYTOKEN for the state stack whose top is +- YYSSP. +- +- Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is +- not large enough to hold the message. In that case, also set +- *YYMSG_ALLOC to the required number of bytes. Return 2 if the +- required number of bytes is too large to store. */ +-static int +-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, +- yytype_int16 *yyssp, int yytoken) +-{ +- YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); +- YYSIZE_T yysize = yysize0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- /* Internationalized format string. */ +- const char *yyformat = YY_NULLPTR; +- /* Arguments of yyformat. */ +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- /* Number of reported tokens (one for the "unexpected", one per +- "expected"). */ +- int yycount = 0; +- +- /* There are many possibilities here to consider: +- - If this state is a consistent state with a default action, then +- the only way this function was invoked is if the default action +- is an error action. In that case, don't check for expected +- tokens because there are none. +- - The only way there can be no lookahead present (in yychar) is if +- this state is a consistent state with a default action. Thus, +- detecting the absence of a lookahead is sufficient to determine +- that there is no unexpected or expected token to report. In that +- case, just report a simple "syntax error". +- - Don't assume there isn't a lookahead just because this state is a +- consistent state with a default action. There might have been a +- previous inconsistent state, consistent state with a non-default +- action, or user semantic action that manipulated yychar. +- - Of course, the expected token list depends on states to have +- correct lookahead information, and it depends on the parser not +- to perform extra reductions after fetching a lookahead from the +- scanner and before detecting a syntax error. Thus, state merging +- (from LALR or IELR) and default reductions corrupt the expected +- token list. However, the list is correct for canonical LR with +- one exception: it will still contain any token that will not be +- accepted due to an error action in a later state. +- */ +- if (yytoken != YYEMPTY) +- { +- int yyn = yypact[*yyssp]; +- yyarg[yycount++] = yytname[yytoken]; +- if (!yypact_value_is_default (yyn)) +- { +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. In other words, skip the first -YYN actions for +- this state because they are default actions. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yyx; +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR +- && !yytable_value_is_error (yytable[yyx + yyn])) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- { +- YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); +- if (! (yysize <= yysize1 +- && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } +- } +- } +- } +- +- switch (yycount) +- { +-# define YYCASE_(N, S) \ +- case N: \ +- yyformat = S; \ +- break +- YYCASE_(0, YY_("syntax error")); +- YYCASE_(1, YY_("syntax error, unexpected %s")); +- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); +- YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); +- YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); +- YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +-# undef YYCASE_ +- } +- +- { +- YYSIZE_T yysize1 = yysize + yystrlen (yyformat); +- if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) +- return 2; +- yysize = yysize1; +- } +- +- if (*yymsg_alloc < yysize) +- { +- *yymsg_alloc = 2 * yysize; +- if (! (yysize <= *yymsg_alloc +- && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) +- *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; +- return 1; +- } +- +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- { +- char *yyp = *yymsg; +- int yyi = 0; +- while ((*yyp = *yyformat) != '\0') +- if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyformat += 2; +- } +- else +- { +- yyp++; +- yyformat++; +- } +- } +- return 0; +-} +-#endif /* YYERROR_VERBOSE */ +- +-/*-----------------------------------------------. +-| Release the memory associated to this symbol. | +-`-----------------------------------------------*/ +- +-static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-{ +- YYUSE (yyvaluep); +- if (!yymsg) +- yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +- +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- YYUSE (yytype); +- YY_IGNORE_MAYBE_UNINITIALIZED_END +-} +- +- +- +- +-/* The lookahead symbol. */ +-int yychar; +- +-/* The semantic value of the lookahead symbol. */ +-YYSTYPE yylval; +-/* Number of syntax errors so far. */ +-int yynerrs; +- +- +-/*----------. +-| yyparse. | +-`----------*/ +- +-int +-yyparse (void) +-{ +- int yystate; +- /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- +- /* The stacks and their tools: +- 'yyss': related to states. +- 'yyvs': related to semantic values. +- +- Refer to the stacks through separate pointers, to allow yyoverflow +- to reallocate them elsewhere. */ +- +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss; +- yytype_int16 *yyssp; +- +- /* The semantic value stack. */ +- YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs; +- YYSTYPE *yyvsp; +- +- YYSIZE_T yystacksize; +- +- int yyn; +- int yyresult; +- /* Lookahead token as an internal (translated) token number. */ +- int yytoken = 0; +- /* The variables used to return semantic value and location from the +- action routines. */ +- YYSTYPE yyval; +- +-#if YYERROR_VERBOSE +- /* Buffer for error messages, and its allocated size. */ +- char yymsgbuf[128]; +- char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif +- +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) +- +- /* The number of symbols on the RHS of the reduced rule. +- Keep to zero when no symbol should be popped. */ +- int yylen = 0; +- +- yyssp = yyss = yyssa; +- yyvsp = yyvs = yyvsa; +- yystacksize = YYINITDEPTH; +- +- YYDPRINTF ((stderr, "Starting parse\n")); +- +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; +- yychar = YYEMPTY; /* Cause a token to be read. */ +- goto yysetstate; +- +-/*------------------------------------------------------------. +-| yynewstate -- Push a new state, which is found in yystate. | +-`------------------------------------------------------------*/ +- yynewstate: +- /* In all cases, when you get here, the value and location stacks +- have just been pushed. So pushing a state here evens the stacks. */ +- yyssp++; +- +- yysetstate: +- *yyssp = yystate; +- +- if (yyss + yystacksize - 1 <= yyssp) +- { +- /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = yyssp - yyss + 1; +- +-#ifdef yyoverflow +- { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; +- } +-#else /* no yyoverflow */ +-# ifndef YYSTACK_RELOCATE +- goto yyexhaustedlab; +-# else +- /* Extend the stack our own way. */ +- if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; +- yystacksize *= 2; +- if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; +- +- { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss_alloc, yyss); +- YYSTACK_RELOCATE (yyvs_alloc, yyvs); +-# undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); +- } +-# endif +-#endif /* no yyoverflow */ +- +- yyssp = yyss + yysize - 1; +- yyvsp = yyvs + yysize - 1; +- +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); +- +- if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; +- } +- +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +- +- if (yystate == YYFINAL) +- YYACCEPT; +- +- goto yybackup; +- +-/*-----------. +-| yybackup. | +-`-----------*/ +-yybackup: +- +- /* Do appropriate processing given the current state. Read a +- lookahead token if we need one and don't already have one. */ +- +- /* First try to decide what to do without reference to lookahead token. */ +- yyn = yypact[yystate]; +- if (yypact_value_is_default (yyn)) +- goto yydefault; +- +- /* Not known => get a lookahead token if don't already have one. */ +- +- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ +- if (yychar == YYEMPTY) +- { +- YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = yylex (); +- } +- +- if (yychar <= YYEOF) +- { +- yychar = yytoken = YYEOF; +- YYDPRINTF ((stderr, "Now at end of input.\n")); +- } +- else +- { +- yytoken = YYTRANSLATE (yychar); +- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +- } +- +- /* If the proper action on seeing token YYTOKEN is to reduce or to +- detect an error, take that action. */ +- yyn += yytoken; +- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +- goto yydefault; +- yyn = yytable[yyn]; +- if (yyn <= 0) +- { +- if (yytable_value_is_error (yyn)) +- goto yyerrlab; +- yyn = -yyn; +- goto yyreduce; +- } +- +- /* Count tokens shifted since error; after three, turn off error +- status. */ +- if (yyerrstatus) +- yyerrstatus--; +- +- /* Shift the lookahead token. */ +- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token. */ +- yychar = YYEMPTY; +- +- yystate = yyn; +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END +- +- goto yynewstate; +- +- +-/*-----------------------------------------------------------. +-| yydefault -- do the default action for the current state. | +-`-----------------------------------------------------------*/ +-yydefault: +- yyn = yydefact[yystate]; +- if (yyn == 0) +- goto yyerrlab; +- goto yyreduce; +- +- +-/*-----------------------------. +-| yyreduce -- Do a reduction. | +-`-----------------------------*/ +-yyreduce: +- /* yyn is the number of a rule to reduce with. */ +- yylen = yyr2[yyn]; +- +- /* If YYLEN is nonzero, implement the default value of the action: +- '$$ = $1'. +- +- Otherwise, the following line sets YYVAL to garbage. +- This behavior is undocumented and Bison +- users should not rely upon it. Assigning to YYVAL +- unconditionally makes the parser a bit smaller, and it avoids a +- GCC warning that YYVAL may be used uninitialized. */ +- yyval = yyvsp[1-yylen]; +- +- +- YY_REDUCE_PRINT (yyn); +- switch (yyn) +- { +- case 2: +-#line 249 "label.y" /* yacc.c:1646 */ +- { parse_result = ((yyvsp[0].expr) ? new analyzed_expr((yyvsp[0].expr)) : 0); } +-#line 1435 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 3: +-#line 254 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = (yyvsp[0].expr); } +-#line 1441 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 4: +-#line 256 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new conditional_expr((yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); } +-#line 1447 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 5: +-#line 261 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = 0; } +-#line 1453 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 6: +-#line 263 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = (yyvsp[0].expr); } +-#line 1459 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 7: +-#line 268 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = (yyvsp[0].expr); } +-#line 1465 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 8: +-#line 270 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new alternative_expr((yyvsp[-2].expr), (yyvsp[0].expr)); } +-#line 1471 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 9: +-#line 272 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new conditional_expr((yyvsp[-2].expr), (yyvsp[0].expr), 0); } +-#line 1477 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 10: +-#line 277 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = (yyvsp[0].expr); } +-#line 1483 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 11: +-#line 279 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new list_expr((yyvsp[-1].expr), (yyvsp[0].expr)); } +-#line 1489 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 12: +-#line 284 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = (yyvsp[0].expr); } +-#line 1495 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 13: +-#line 286 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new substitute_expr((yyvsp[-2].expr), (yyvsp[0].expr)); } +-#line 1501 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 14: +-#line 291 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new at_expr; } +-#line 1507 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 15: +-#line 293 "label.y" /* yacc.c:1646 */ +- { +- (yyval.expr) = new literal_expr(literals.contents() + (yyvsp[0].str).start, +- (yyvsp[0].str).len); +- } +-#line 1516 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 16: +-#line 298 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new field_expr((yyvsp[0].num), 0); } +-#line 1522 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 17: +-#line 300 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new field_expr((yyvsp[-1].num), (yyvsp[0].num) - 1); } +-#line 1528 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 18: +-#line 302 "label.y" /* yacc.c:1646 */ +- { +- switch ((yyvsp[0].num)) { +- case 'I': +- case 'i': +- case 'A': +- case 'a': +- (yyval.expr) = new format_expr((yyvsp[0].num)); +- break; +- default: +- command_error("unrecognized format `%1'", char((yyvsp[0].num))); +- (yyval.expr) = new format_expr('a'); +- break; +- } +- } +-#line 1547 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 19: +-#line 318 "label.y" /* yacc.c:1646 */ +- { +- (yyval.expr) = new format_expr('0', (yyvsp[0].dig).ndigits, (yyvsp[0].dig).val); +- } +-#line 1555 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 20: +-#line 322 "label.y" /* yacc.c:1646 */ +- { +- switch ((yyvsp[-1].num)) { +- case 'l': +- (yyval.expr) = new map_expr((yyvsp[-4].expr), lowercase); +- break; +- case 'u': +- (yyval.expr) = new map_expr((yyvsp[-4].expr), uppercase); +- break; +- case 'c': +- (yyval.expr) = new map_expr((yyvsp[-4].expr), capitalize); +- break; +- case 'r': +- (yyval.expr) = new map_expr((yyvsp[-4].expr), reverse_name); +- break; +- case 'a': +- (yyval.expr) = new map_expr((yyvsp[-4].expr), abbreviate_name); +- break; +- case 'y': +- (yyval.expr) = new extractor_expr((yyvsp[-4].expr), find_year, (yyvsp[-2].num)); +- break; +- case 'n': +- (yyval.expr) = new extractor_expr((yyvsp[-4].expr), find_last_name, (yyvsp[-2].num)); +- break; +- default: +- (yyval.expr) = (yyvsp[-4].expr); +- command_error("unknown function `%1'", char((yyvsp[-1].num))); +- break; +- } +- } +-#line 1589 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 21: +-#line 353 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new truncate_expr((yyvsp[-2].expr), (yyvsp[0].num)); } +-#line 1595 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 22: +-#line 355 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new truncate_expr((yyvsp[-2].expr), -(yyvsp[0].num)); } +-#line 1601 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 23: +-#line 357 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new star_expr((yyvsp[-1].expr)); } +-#line 1607 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 24: +-#line 359 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = (yyvsp[-1].expr); } +-#line 1613 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 25: +-#line 361 "label.y" /* yacc.c:1646 */ +- { (yyval.expr) = new separator_expr((yyvsp[-1].expr)); } +-#line 1619 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 26: +-#line 366 "label.y" /* yacc.c:1646 */ +- { (yyval.num) = -1; } +-#line 1625 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 27: +-#line 368 "label.y" /* yacc.c:1646 */ +- { (yyval.num) = (yyvsp[0].num); } +-#line 1631 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 28: +-#line 373 "label.y" /* yacc.c:1646 */ +- { (yyval.num) = (yyvsp[0].num); } +-#line 1637 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 29: +-#line 375 "label.y" /* yacc.c:1646 */ +- { (yyval.num) = (yyvsp[-1].num)*10 + (yyvsp[0].num); } +-#line 1643 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 30: +-#line 380 "label.y" /* yacc.c:1646 */ +- { (yyval.dig).ndigits = 1; (yyval.dig).val = (yyvsp[0].num); } +-#line 1649 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 31: +-#line 382 "label.y" /* yacc.c:1646 */ +- { (yyval.dig).ndigits = (yyvsp[-1].dig).ndigits + 1; (yyval.dig).val = (yyvsp[-1].dig).val*10 + (yyvsp[0].num); } +-#line 1655 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 32: +-#line 388 "label.y" /* yacc.c:1646 */ +- { (yyval.num) = 0; } +-#line 1661 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 33: +-#line 390 "label.y" /* yacc.c:1646 */ +- { (yyval.num) = 1; } +-#line 1667 "label.cpp" /* yacc.c:1646 */ +- break; +- +- case 34: +-#line 392 "label.y" /* yacc.c:1646 */ +- { (yyval.num) = -1; } +-#line 1673 "label.cpp" /* yacc.c:1646 */ +- break; +- +- +-#line 1677 "label.cpp" /* yacc.c:1646 */ +- default: break; +- } +- /* User semantic actions sometimes alter yychar, and that requires +- that yytoken be updated with the new translation. We take the +- approach of translating immediately before every use of yytoken. +- One alternative is translating here after every semantic action, +- but that translation would be missed if the semantic action invokes +- YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or +- if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an +- incorrect destructor might then be invoked immediately. In the +- case of YYERROR or YYBACKUP, subsequent parser actions might lead +- to an incorrect destructor call or verbose syntax error message +- before the lookahead is translated. */ +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); +- +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- +- *++yyvsp = yyval; +- +- /* Now 'shift' the result of the reduction. Determine what state +- that goes to, based on the state we popped back to and the rule +- number reduced by. */ +- +- yyn = yyr1[yyn]; +- +- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +- yystate = yytable[yystate]; +- else +- yystate = yydefgoto[yyn - YYNTOKENS]; +- +- goto yynewstate; +- +- +-/*--------------------------------------. +-| yyerrlab -- here on detecting error. | +-`--------------------------------------*/ +-yyerrlab: +- /* Make sure we have latest lookahead translation. See comments at +- user semantic actions for why this is necessary. */ +- yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); +- +- /* If not already recovering from an error, report this error. */ +- if (!yyerrstatus) +- { +- ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (YY_("syntax error")); +-#else +-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ +- yyssp, yytoken) +- { +- char const *yymsgp = YY_("syntax error"); +- int yysyntax_error_status; +- yysyntax_error_status = YYSYNTAX_ERROR; +- if (yysyntax_error_status == 0) +- yymsgp = yymsg; +- else if (yysyntax_error_status == 1) +- { +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); +- if (!yymsg) +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- yysyntax_error_status = 2; +- } +- else +- { +- yysyntax_error_status = YYSYNTAX_ERROR; +- yymsgp = yymsg; +- } +- } +- yyerror (yymsgp); +- if (yysyntax_error_status == 2) +- goto yyexhaustedlab; +- } +-# undef YYSYNTAX_ERROR +-#endif +- } +- +- +- +- if (yyerrstatus == 3) +- { +- /* If just tried and failed to reuse lookahead token after an +- error, discard it. */ +- +- if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } +- else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } +- } +- +- /* Else will try to reuse lookahead token after shifting the error +- token. */ +- goto yyerrlab1; +- +- +-/*---------------------------------------------------. +-| yyerrorlab -- error raised explicitly by YYERROR. | +-`---------------------------------------------------*/ +-yyerrorlab: +- +- /* Pacify compilers like GCC when the user code never invokes +- YYERROR and the label yyerrorlab therefore never appears in user +- code. */ +- if (/*CONSTCOND*/ 0) +- goto yyerrorlab; +- +- /* Do not reclaim the symbols of the rule whose action triggered +- this YYERROR. */ +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- yystate = *yyssp; +- goto yyerrlab1; +- +- +-/*-------------------------------------------------------------. +-| yyerrlab1 -- common code for both syntax error and YYERROR. | +-`-------------------------------------------------------------*/ +-yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ +- +- for (;;) +- { +- yyn = yypact[yystate]; +- if (!yypact_value_is_default (yyn)) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } +- +- /* Pop the current state because it cannot handle the error token. */ +- if (yyssp == yyss) +- YYABORT; +- +- +- yydestruct ("Error: popping", +- yystos[yystate], yyvsp); +- YYPOPSTACK (1); +- yystate = *yyssp; +- YY_STACK_PRINT (yyss, yyssp); +- } +- +- YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +- *++yyvsp = yylval; +- YY_IGNORE_MAYBE_UNINITIALIZED_END +- +- +- /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +- +- yystate = yyn; +- goto yynewstate; +- +- +-/*-------------------------------------. +-| yyacceptlab -- YYACCEPT comes here. | +-`-------------------------------------*/ +-yyacceptlab: +- yyresult = 0; +- goto yyreturn; +- +-/*-----------------------------------. +-| yyabortlab -- YYABORT comes here. | +-`-----------------------------------*/ +-yyabortlab: +- yyresult = 1; +- goto yyreturn; +- +-#if !defined yyoverflow || YYERROR_VERBOSE +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ +-yyexhaustedlab: +- yyerror (YY_("memory exhausted")); +- yyresult = 2; +- /* Fall through. */ +-#endif +- +-yyreturn: +- if (yychar != YYEMPTY) +- { +- /* Make sure we have latest lookahead translation. See comments at +- user semantic actions for why this is necessary. */ +- yytoken = YYTRANSLATE (yychar); +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); +- } +- /* Do not reclaim the symbols of the rule whose action triggered +- this YYABORT or YYACCEPT. */ +- YYPOPSTACK (yylen); +- YY_STACK_PRINT (yyss, yyssp); +- while (yyssp != yyss) +- { +- yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); +- YYPOPSTACK (1); +- } +-#ifndef yyoverflow +- if (yyss != yyssa) +- YYSTACK_FREE (yyss); +-#endif +-#if YYERROR_VERBOSE +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +-#endif +- return yyresult; +-} +-#line 395 "label.y" /* yacc.c:1906 */ +- +- +-/* bison defines const to be empty unless __STDC__ is defined, which it +-isn't under cfront */ +- +-#ifdef const +-#undef const +-#endif +- +-const char *spec_ptr; +-const char *spec_end; +-const char *spec_cur; +- +-static char uppercase_array[] = { +- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', +- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', +- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', +- 'Y', 'Z', +-}; +- +-static char lowercase_array[] = { +- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', +- 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', +- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', +- 'y', 'z', +-}; +- +-int yylex() +-{ +- while (spec_ptr < spec_end && csspace(*spec_ptr)) +- spec_ptr++; +- spec_cur = spec_ptr; +- if (spec_ptr >= spec_end) +- return 0; +- unsigned char c = *spec_ptr++; +- if (csalpha(c)) { +- yylval.num = c; +- return TOKEN_LETTER; +- } +- if (csdigit(c)) { +- yylval.num = c - '0'; +- return TOKEN_DIGIT; +- } +- if (c == '\'') { +- yylval.str.start = literals.length(); +- for (; spec_ptr < spec_end; spec_ptr++) { +- if (*spec_ptr == '\'') { +- if (++spec_ptr < spec_end && *spec_ptr == '\'') +- literals += '\''; +- else { +- yylval.str.len = literals.length() - yylval.str.start; +- return TOKEN_LITERAL; +- } +- } +- else +- literals += *spec_ptr; +- } +- yylval.str.len = literals.length() - yylval.str.start; +- return TOKEN_LITERAL; +- } +- return c; +-} +- +-int set_label_spec(const char *label_spec) +-{ +- spec_cur = spec_ptr = label_spec; +- spec_end = strchr(label_spec, '\0'); +- literals.clear(); +- if (yyparse()) +- return 0; +- delete parsed_label; +- parsed_label = parse_result; +- return 1; +-} +- +-int set_date_label_spec(const char *label_spec) +-{ +- spec_cur = spec_ptr = label_spec; +- spec_end = strchr(label_spec, '\0'); +- literals.clear(); +- if (yyparse()) +- return 0; +- delete parsed_date_label; +- parsed_date_label = parse_result; +- return 1; +-} +- +-int set_short_label_spec(const char *label_spec) +-{ +- spec_cur = spec_ptr = label_spec; +- spec_end = strchr(label_spec, '\0'); +- literals.clear(); +- if (yyparse()) +- return 0; +- delete parsed_short_label; +- parsed_short_label = parse_result; +- return 1; +-} +- +-void yyerror(const char *message) +-{ +- if (spec_cur < spec_end) +- command_error("label specification %1 before `%2'", message, spec_cur); +- else +- command_error("label specification %1 at end of string", +- message, spec_cur); +-} +- +-void at_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (tentative) +- ref.canonicalize_authors(result); +- else { +- const char *end, *start = ref.get_authors(&end); +- if (start) +- result.append(start, end - start); +- } +-} +- +-void format_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (tentative) +- return; +- const label_info *lp = ref.get_label_ptr(); +- int num = lp == 0 ? ref.get_number() : lp->count; +- if (type != '0') +- result += format_serial(type, num + 1); +- else { +- const char *ptr = i_to_a(num + first_number); +- int pad = width - strlen(ptr); +- while (--pad >= 0) +- result += '0'; +- result += ptr; +- } +-} +- +-static const char *format_serial(char c, int n) +-{ +- assert(n > 0); +- static char buf[128]; // more than enough. +- switch (c) { +- case 'i': +- case 'I': +- { +- char *p = buf; +- // troff uses z and w to represent 10000 and 5000 in Roman +- // numerals; I can find no historical basis for this usage +- const char *s = c == 'i' ? "zwmdclxvi" : "ZWMDCLXVI"; +- if (n >= 40000) +- return i_to_a(n); +- while (n >= 10000) { +- *p++ = s[0]; +- n -= 10000; +- } +- for (int i = 1000; i > 0; i /= 10, s += 2) { +- int m = n/i; +- n -= m*i; +- switch (m) { +- case 3: +- *p++ = s[2]; +- /* falls through */ +- case 2: +- *p++ = s[2]; +- /* falls through */ +- case 1: +- *p++ = s[2]; +- break; +- case 4: +- *p++ = s[2]; +- *p++ = s[1]; +- break; +- case 8: +- *p++ = s[1]; +- *p++ = s[2]; +- *p++ = s[2]; +- *p++ = s[2]; +- break; +- case 7: +- *p++ = s[1]; +- *p++ = s[2]; +- *p++ = s[2]; +- break; +- case 6: +- *p++ = s[1]; +- *p++ = s[2]; +- break; +- case 5: +- *p++ = s[1]; +- break; +- case 9: +- *p++ = s[2]; +- *p++ = s[0]; +- } +- } +- *p = 0; +- break; +- } +- case 'a': +- case 'A': +- { +- char *p = buf; +- // this is derived from troff/reg.c +- while (n > 0) { +- int d = n % 26; +- if (d == 0) +- d = 26; +- n -= d; +- n /= 26; +- *p++ = c == 'a' ? lowercase_array[d - 1] : +- uppercase_array[d - 1]; +- } +- *p-- = 0; +- // Reverse it. +- char *q = buf; +- while (q < p) { +- char temp = *q; +- *q = *p; +- *p = temp; +- --p; +- ++q; +- } +- break; +- } +- default: +- assert(0); +- } +- return buf; +-} +- +-void field_expr::evaluate(int, const reference &ref, +- string &result, substring_position &) +-{ +- const char *end; +- const char *start = ref.get_field(name, &end); +- if (start) { +- start = nth_field(number, start, &end); +- if (start) +- result.append(start, end - start); +- } +-} +- +-void literal_expr::evaluate(int, const reference &, +- string &result, substring_position &) +-{ +- result += s; +-} +- +-analyzed_expr::analyzed_expr(expression *e) +-: unary_expr(e), flags(e ? e->analyze() : 0) +-{ +-} +- +-void analyzed_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- if (expr) +- expr->evaluate(tentative, ref, result, pos); +-} +- +-void star_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- const label_info *lp = ref.get_label_ptr(); +- if (!tentative +- && (lp == 0 || lp->total > 1) +- && expr) +- expr->evaluate(tentative, ref, result, pos); +-} +- +-void separator_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- int start_length = result.length(); +- int is_first = pos.start < 0; +- if (expr) +- expr->evaluate(tentative, ref, result, pos); +- if (is_first) { +- pos.start = start_length; +- pos.length = result.length() - start_length; +- } +-} +- +-void map_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (expr) { +- string temp; +- substring_position temp_pos; +- expr->evaluate(tentative, ref, temp, temp_pos); +- (*func)(temp.contents(), temp.contents() + temp.length(), result); +- } +-} +- +-void extractor_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (expr) { +- string temp; +- substring_position temp_pos; +- expr->evaluate(tentative, ref, temp, temp_pos); +- const char *end, *start = (*func)(temp.contents(), +- temp.contents() + temp.length(), +- &end); +- switch (part) { +- case BEFORE: +- if (start) +- result.append(temp.contents(), start - temp.contents()); +- else +- result += temp; +- break; +- case MATCH: +- if (start) +- result.append(start, end - start); +- break; +- case AFTER: +- if (start) +- result.append(end, temp.contents() + temp.length() - end); +- break; +- default: +- assert(0); +- } +- } +-} +- +-static void first_part(int len, const char *ptr, const char *end, +- string &result) +-{ +- for (;;) { +- const char *token_start = ptr; +- if (!get_token(&ptr, end)) +- break; +- const token_info *ti = lookup_token(token_start, ptr); +- int counts = ti->sortify_non_empty(token_start, ptr); +- if (counts && --len < 0) +- break; +- if (counts || ti->is_accent()) +- result.append(token_start, ptr - token_start); +- } +-} +- +-static void last_part(int len, const char *ptr, const char *end, +- string &result) +-{ +- const char *start = ptr; +- int count = 0; +- for (;;) { +- const char *token_start = ptr; +- if (!get_token(&ptr, end)) +- break; +- const token_info *ti = lookup_token(token_start, ptr); +- if (ti->sortify_non_empty(token_start, ptr)) +- count++; +- } +- ptr = start; +- int skip = count - len; +- if (skip > 0) { +- for (;;) { +- const char *token_start = ptr; +- if (!get_token(&ptr, end)) +- assert(0); +- const token_info *ti = lookup_token(token_start, ptr); +- if (ti->sortify_non_empty(token_start, ptr) && --skip < 0) { +- ptr = token_start; +- break; +- } +- } +- } +- first_part(len, ptr, end, result); +-} +- +-void truncate_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (expr) { +- string temp; +- substring_position temp_pos; +- expr->evaluate(tentative, ref, temp, temp_pos); +- const char *start = temp.contents(); +- const char *end = start + temp.length(); +- if (n > 0) +- first_part(n, start, end, result); +- else if (n < 0) +- last_part(-n, start, end, result); +- } +-} +- +-void alternative_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- int start_length = result.length(); +- if (expr1) +- expr1->evaluate(tentative, ref, result, pos); +- if (result.length() == start_length && expr2) +- expr2->evaluate(tentative, ref, result, pos); +-} +- +-void list_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- if (expr1) +- expr1->evaluate(tentative, ref, result, pos); +- if (expr2) +- expr2->evaluate(tentative, ref, result, pos); +-} +- +-void substitute_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- int start_length = result.length(); +- if (expr1) +- expr1->evaluate(tentative, ref, result, pos); +- if (result.length() > start_length && result[result.length() - 1] == '-') { +- // ought to see if pos covers the - +- result.set_length(result.length() - 1); +- if (expr2) +- expr2->evaluate(tentative, ref, result, pos); +- } +-} +- +-void conditional_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- string temp; +- substring_position temp_pos; +- if (expr1) +- expr1->evaluate(tentative, ref, temp, temp_pos); +- if (temp.length() > 0) { +- if (expr2) +- expr2->evaluate(tentative, ref, result, pos); +- } +- else { +- if (expr3) +- expr3->evaluate(tentative, ref, result, pos); +- } +-} +- +-void reference::pre_compute_label() +-{ +- if (parsed_label != 0 +- && (parsed_label->analyze() & expression::CONTAINS_VARIABLE)) { +- label.clear(); +- substring_position temp_pos; +- parsed_label->evaluate(1, *this, label, temp_pos); +- label_ptr = lookup_label(label); +- } +-} +- +-void reference::compute_label() +-{ +- label.clear(); +- if (parsed_label) +- parsed_label->evaluate(0, *this, label, separator_pos); +- if (short_label_flag && parsed_short_label) +- parsed_short_label->evaluate(0, *this, short_label, short_separator_pos); +- if (date_as_label) { +- string new_date; +- if (parsed_date_label) { +- substring_position temp_pos; +- parsed_date_label->evaluate(0, *this, new_date, temp_pos); +- } +- set_date(new_date); +- } +- if (label_ptr) +- label_ptr->count += 1; +-} +- +-void reference::immediate_compute_label() +-{ +- if (label_ptr) +- label_ptr->total = 2; // force use of disambiguator +- compute_label(); +-} +- +-int reference::merge_labels(reference **v, int n, label_type type, +- string &result) +-{ +- if (abbreviate_label_ranges) +- return merge_labels_by_number(v, n, type, result); +- else +- return merge_labels_by_parts(v, n, type, result); +-} +- +-int reference::merge_labels_by_number(reference **v, int n, label_type type, +- string &result) +-{ +- if (n <= 1) +- return 0; +- int num = get_number(); +- // Only merge three or more labels. +- if (v[0]->get_number() != num + 1 +- || v[1]->get_number() != num + 2) +- return 0; +- int i; +- for (i = 2; i < n; i++) +- if (v[i]->get_number() != num + i + 1) +- break; +- result = get_label(type); +- result += label_range_indicator; +- result += v[i - 1]->get_label(type); +- return i; +-} +- +-const substring_position &reference::get_separator_pos(label_type type) const +-{ +- if (type == SHORT_LABEL && short_label_flag) +- return short_separator_pos; +- else +- return separator_pos; +-} +- +-const string &reference::get_label(label_type type) const +-{ +- if (type == SHORT_LABEL && short_label_flag) +- return short_label; +- else +- return label; +-} +- +-int reference::merge_labels_by_parts(reference **v, int n, label_type type, +- string &result) +-{ +- if (n <= 0) +- return 0; +- const string &lb = get_label(type); +- const substring_position &sp = get_separator_pos(type); +- if (sp.start < 0 +- || sp.start != v[0]->get_separator_pos(type).start +- || memcmp(lb.contents(), v[0]->get_label(type).contents(), +- sp.start) != 0) +- return 0; +- result = lb; +- int i = 0; +- do { +- result += separate_label_second_parts; +- const substring_position &s = v[i]->get_separator_pos(type); +- int sep_end_pos = s.start + s.length; +- result.append(v[i]->get_label(type).contents() + sep_end_pos, +- v[i]->get_label(type).length() - sep_end_pos); +- } while (++i < n +- && sp.start == v[i]->get_separator_pos(type).start +- && memcmp(lb.contents(), v[i]->get_label(type).contents(), +- sp.start) == 0); +- return i; +-} +- +-string label_pool; +- +-label_info::label_info(const string &s) +-: start(label_pool.length()), length(s.length()), count(0), total(1) +-{ +- label_pool += s; +-} +- +-static label_info **label_table = 0; +-static int label_table_size = 0; +-static int label_table_used = 0; +- +-label_info *lookup_label(const string &label) +-{ +- if (label_table == 0) { +- label_table = new label_info *[17]; +- label_table_size = 17; +- for (int i = 0; i < 17; i++) +- label_table[i] = 0; +- } +- unsigned h = hash_string(label.contents(), label.length()) % label_table_size; +- label_info **ptr; +- for (ptr = label_table + h; +- *ptr != 0; +- (ptr == label_table) +- ? (ptr = label_table + label_table_size - 1) +- : ptr--) +- if ((*ptr)->length == label.length() +- && memcmp(label_pool.contents() + (*ptr)->start, label.contents(), +- label.length()) == 0) { +- (*ptr)->total += 1; +- return *ptr; +- } +- label_info *result = *ptr = new label_info(label); +- if (++label_table_used * 2 > label_table_size) { +- // Rehash the table. +- label_info **old_table = label_table; +- int old_size = label_table_size; +- label_table_size = next_size(label_table_size); +- label_table = new label_info *[label_table_size]; +- int i; +- for (i = 0; i < label_table_size; i++) +- label_table[i] = 0; +- for (i = 0; i < old_size; i++) +- if (old_table[i]) { +- h = hash_string(label_pool.contents() + old_table[i]->start, +- old_table[i]->length); +- label_info **p; +- for (p = label_table + (h % label_table_size); +- *p != 0; +- (p == label_table) +- ? (p = label_table + label_table_size - 1) +- : --p) +- ; +- *p = old_table[i]; +- } +- a_delete old_table; +- } +- return result; +-} +- +-void clear_labels() +-{ +- for (int i = 0; i < label_table_size; i++) { +- delete label_table[i]; +- label_table[i] = 0; +- } +- label_table_used = 0; +- label_pool.clear(); +-} +- +-static void consider_authors(reference **start, reference **end, int i); +- +-void compute_labels(reference **v, int n) +-{ +- if (parsed_label +- && (parsed_label->analyze() & expression::CONTAINS_AT) +- && sort_fields.length() >= 2 +- && sort_fields[0] == 'A' +- && sort_fields[1] == '+') +- consider_authors(v, v + n, 0); +- for (int i = 0; i < n; i++) +- v[i]->compute_label(); +-} +- +- +-/* A reference with a list of authors _needs_ author i +-where 0 <= i <= N if there exists a reference with a list of authors +- such that != and M >= i +-and Aj = Bj for 0 <= j < i. In this case if we can't say ``A0, +-A1,...,A(i-1) et al'' because this would match both and +-. If a reference needs author i we only have to call +-need_author(j) for some j >= i such that the reference also needs +-author j. */ +- +-/* This function handles 2 tasks: +-determine which authors are needed (cannot be elided with et al.); +-determine which authors can have only last names in the labels. +- +-References >= start and < end have the same first i author names. +-Also they're sorted by A+. */ +- +-static void consider_authors(reference **start, reference **end, int i) +-{ +- if (start >= end) +- return; +- reference **p = start; +- if (i >= (*p)->get_nauthors()) { +- for (++p; p < end && i >= (*p)->get_nauthors(); p++) +- ; +- if (p < end && i > 0) { +- // If we have an author list and an author list , +- // then both lists need C. +- for (reference **q = start; q < end; q++) +- (*q)->need_author(i - 1); +- } +- start = p; +- } +- while (p < end) { +- reference **last_name_start = p; +- reference **name_start = p; +- for (++p; +- p < end && i < (*p)->get_nauthors() +- && same_author_last_name(**last_name_start, **p, i); +- p++) { +- if (!same_author_name(**name_start, **p, i)) { +- consider_authors(name_start, p, i + 1); +- name_start = p; +- } +- } +- consider_authors(name_start, p, i + 1); +- if (last_name_start == name_start) { +- for (reference **q = last_name_start; q < p; q++) +- (*q)->set_last_name_unambiguous(i); +- } +- // If we have an author list and , then the lists +- // need author D and E respectively. +- if (name_start > start || p < end) { +- for (reference **q = last_name_start; q < p; q++) +- (*q)->need_author(i); +- } +- } +-} +- +-int same_author_last_name(const reference &r1, const reference &r2, int n) +-{ +- const char *ae1; +- const char *as1 = r1.get_sort_field(0, n, 0, &ae1); +- const char *ae2; +- const char *as2 = r2.get_sort_field(0, n, 0, &ae2); +- if (!as1 && !as2) return 1; // they are the same +- if (!as1 || !as2) return 0; +- return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; +-} +- +-int same_author_name(const reference &r1, const reference &r2, int n) +-{ +- const char *ae1; +- const char *as1 = r1.get_sort_field(0, n, -1, &ae1); +- const char *ae2; +- const char *as2 = r2.get_sort_field(0, n, -1, &ae2); +- if (!as1 && !as2) return 1; // they are the same +- if (!as1 || !as2) return 0; +- return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; +-} +- +- +-void int_set::set(int i) +-{ +- assert(i >= 0); +- int bytei = i >> 3; +- if (bytei >= v.length()) { +- int old_length = v.length(); +- v.set_length(bytei + 1); +- for (int j = old_length; j <= bytei; j++) +- v[j] = 0; +- } +- v[bytei] |= 1 << (i & 7); +-} +- +-int int_set::get(int i) const +-{ +- assert(i >= 0); +- int bytei = i >> 3; +- return bytei >= v.length() ? 0 : (v[bytei] & (1 << (i & 7))) != 0; +-} +- +-void reference::set_last_name_unambiguous(int i) +-{ +- last_name_unambiguous.set(i); +-} +- +-void reference::need_author(int n) +-{ +- if (n > last_needed_author) +- last_needed_author = n; +-} +- +-const char *reference::get_authors(const char **end) const +-{ +- if (!computed_authors) { +- ((reference *)this)->computed_authors = 1; +- string &result = ((reference *)this)->authors; +- int na = get_nauthors(); +- result.clear(); +- for (int i = 0; i < na; i++) { +- if (last_name_unambiguous.get(i)) { +- const char *e, *start = get_author_last_name(i, &e); +- assert(start != 0); +- result.append(start, e - start); +- } +- else { +- const char *e, *start = get_author(i, &e); +- assert(start != 0); +- result.append(start, e - start); +- } +- if (i == last_needed_author +- && et_al.length() > 0 +- && et_al_min_elide > 0 +- && last_needed_author + et_al_min_elide < na +- && na >= et_al_min_total) { +- result += et_al; +- break; +- } +- if (i < na - 1) { +- if (na == 2) +- result += join_authors_exactly_two; +- else if (i < na - 2) +- result += join_authors_default; +- else +- result += join_authors_last_two; +- } +- } +- } +- const char *start = authors.contents(); +- *end = start + authors.length(); +- return start; +-} +- +-int reference::get_nauthors() const +-{ +- if (nauthors < 0) { +- const char *dummy; +- int na; +- for (na = 0; get_author(na, &dummy) != 0; na++) +- ; +- ((reference *)this)->nauthors = na; +- } +- return nauthors; +-} +diff -Nuar groff-1.22.3.old/src/preproc/refer/label.y groff-1.22.3/src/preproc/refer/label.y +--- groff-1.22.3.old/src/preproc/refer/label.y 2014-11-04 10:38:35.244523759 +0200 ++++ groff-1.22.3/src/preproc/refer/label.y 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1191 +0,0 @@ +-/* -*- C++ -*- +- Copyright (C) 1989-2014 Free Software Foundation, Inc. +- Written by James Clark (jjc@jclark.com) +- +-This file is part of groff. +- +-groff is free software; you can redistribute it and/or modify it under +-the terms of the GNU General Public License as published by the Free +-Software Foundation, either version 3 of the License, or +-(at your option) any later version. +- +-groff is distributed in the hope that it will be useful, but WITHOUT ANY +-WARRANTY; without even the implied warranty of MERCHANTABILITY or +-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-for more details. +- +-You should have received a copy of the GNU General Public License +-along with this program. If not, see . */ +- +-%{ +- +-#include "refer.h" +-#include "refid.h" +-#include "ref.h" +-#include "token.h" +- +-int yylex(); +-void yyerror(const char *); +-int yyparse(); +- +-static const char *format_serial(char c, int n); +- +-struct label_info { +- int start; +- int length; +- int count; +- int total; +- label_info(const string &); +-}; +- +-label_info *lookup_label(const string &label); +- +-struct expression { +- enum { +- // Does the tentative label depend on the reference? +- CONTAINS_VARIABLE = 01, +- CONTAINS_STAR = 02, +- CONTAINS_FORMAT = 04, +- CONTAINS_AT = 010 +- }; +- virtual ~expression() { } +- virtual void evaluate(int, const reference &, string &, +- substring_position &) = 0; +- virtual unsigned analyze() { return 0; } +-}; +- +-class at_expr : public expression { +-public: +- at_expr() { } +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { return CONTAINS_VARIABLE|CONTAINS_AT; } +-}; +- +-class format_expr : public expression { +- char type; +- int width; +- int first_number; +-public: +- format_expr(char c, int w = 0, int f = 1) +- : type(c), width(w), first_number(f) { } +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { return CONTAINS_FORMAT; } +-}; +- +-class field_expr : public expression { +- int number; +- char name; +-public: +- field_expr(char nm, int num) : number(num), name(nm) { } +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { return CONTAINS_VARIABLE; } +-}; +- +-class literal_expr : public expression { +- string s; +-public: +- literal_expr(const char *ptr, int len) : s(ptr, len) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class unary_expr : public expression { +-protected: +- expression *expr; +-public: +- unary_expr(expression *e) : expr(e) { } +- ~unary_expr() { delete expr; } +- void evaluate(int, const reference &, string &, substring_position &) = 0; +- unsigned analyze() { return expr ? expr->analyze() : 0; } +-}; +- +-// This caches the analysis of an expression. +- +-class analyzed_expr : public unary_expr { +- unsigned flags; +-public: +- analyzed_expr(expression *); +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { return flags; } +-}; +- +-class star_expr : public unary_expr { +-public: +- star_expr(expression *e) : unary_expr(e) { } +- void evaluate(int, const reference &, string &, substring_position &); +- unsigned analyze() { +- return ((expr ? (expr->analyze() & ~CONTAINS_VARIABLE) : 0) +- | CONTAINS_STAR); +- } +-}; +- +-typedef void map_func(const char *, const char *, string &); +- +-class map_expr : public unary_expr { +- map_func *func; +-public: +- map_expr(expression *e, map_func *f) : unary_expr(e), func(f) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-typedef const char *extractor_func(const char *, const char *, const char **); +- +-class extractor_expr : public unary_expr { +- int part; +- extractor_func *func; +-public: +- enum { BEFORE = +1, MATCH = 0, AFTER = -1 }; +- extractor_expr(expression *e, extractor_func *f, int pt) +- : unary_expr(e), part(pt), func(f) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class truncate_expr : public unary_expr { +- int n; +-public: +- truncate_expr(expression *e, int i) : unary_expr(e), n(i) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class separator_expr : public unary_expr { +-public: +- separator_expr(expression *e) : unary_expr(e) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class binary_expr : public expression { +-protected: +- expression *expr1; +- expression *expr2; +-public: +- binary_expr(expression *e1, expression *e2) : expr1(e1), expr2(e2) { } +- ~binary_expr() { delete expr1; delete expr2; } +- void evaluate(int, const reference &, string &, substring_position &) = 0; +- unsigned analyze() { +- return (expr1 ? expr1->analyze() : 0) | (expr2 ? expr2->analyze() : 0); +- } +-}; +- +-class alternative_expr : public binary_expr { +-public: +- alternative_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class list_expr : public binary_expr { +-public: +- list_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class substitute_expr : public binary_expr { +-public: +- substitute_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-class ternary_expr : public expression { +-protected: +- expression *expr1; +- expression *expr2; +- expression *expr3; +-public: +- ternary_expr(expression *e1, expression *e2, expression *e3) +- : expr1(e1), expr2(e2), expr3(e3) { } +- ~ternary_expr() { delete expr1; delete expr2; delete expr3; } +- void evaluate(int, const reference &, string &, substring_position &) = 0; +- unsigned analyze() { +- return ((expr1 ? expr1->analyze() : 0) +- | (expr2 ? expr2->analyze() : 0) +- | (expr3 ? expr3->analyze() : 0)); +- } +-}; +- +-class conditional_expr : public ternary_expr { +-public: +- conditional_expr(expression *e1, expression *e2, expression *e3) +- : ternary_expr(e1, e2, e3) { } +- void evaluate(int, const reference &, string &, substring_position &); +-}; +- +-static expression *parsed_label = 0; +-static expression *parsed_date_label = 0; +-static expression *parsed_short_label = 0; +- +-static expression *parse_result; +- +-string literals; +- +-%} +- +-%union { +- int num; +- expression *expr; +- struct { int ndigits; int val; } dig; +- struct { int start; int len; } str; +-} +- +-/* uppercase or lowercase letter */ +-%token TOKEN_LETTER +-/* literal characters */ +-%token TOKEN_LITERAL +-/* digit */ +-%token TOKEN_DIGIT +- +-%type conditional +-%type alternative +-%type list +-%type string +-%type substitute +-%type optional_conditional +-%type number +-%type digits +-%type optional_number +-%type flag +- +-%% +- +-expr: +- optional_conditional +- { parse_result = ($1 ? new analyzed_expr($1) : 0); } +- ; +- +-conditional: +- alternative +- { $$ = $1; } +- | alternative '?' optional_conditional ':' conditional +- { $$ = new conditional_expr($1, $3, $5); } +- ; +- +-optional_conditional: +- /* empty */ +- { $$ = 0; } +- | conditional +- { $$ = $1; } +- ; +- +-alternative: +- list +- { $$ = $1; } +- | alternative '|' list +- { $$ = new alternative_expr($1, $3); } +- | alternative '&' list +- { $$ = new conditional_expr($1, $3, 0); } +- ; +- +-list: +- substitute +- { $$ = $1; } +- | list substitute +- { $$ = new list_expr($1, $2); } +- ; +- +-substitute: +- string +- { $$ = $1; } +- | substitute '~' string +- { $$ = new substitute_expr($1, $3); } +- ; +- +-string: +- '@' +- { $$ = new at_expr; } +- | TOKEN_LITERAL +- { +- $$ = new literal_expr(literals.contents() + $1.start, +- $1.len); +- } +- | TOKEN_LETTER +- { $$ = new field_expr($1, 0); } +- | TOKEN_LETTER number +- { $$ = new field_expr($1, $2 - 1); } +- | '%' TOKEN_LETTER +- { +- switch ($2) { +- case 'I': +- case 'i': +- case 'A': +- case 'a': +- $$ = new format_expr($2); +- break; +- default: +- command_error("unrecognized format `%1'", char($2)); +- $$ = new format_expr('a'); +- break; +- } +- } +- +- | '%' digits +- { +- $$ = new format_expr('0', $2.ndigits, $2.val); +- } +- | string '.' flag TOKEN_LETTER optional_number +- { +- switch ($4) { +- case 'l': +- $$ = new map_expr($1, lowercase); +- break; +- case 'u': +- $$ = new map_expr($1, uppercase); +- break; +- case 'c': +- $$ = new map_expr($1, capitalize); +- break; +- case 'r': +- $$ = new map_expr($1, reverse_name); +- break; +- case 'a': +- $$ = new map_expr($1, abbreviate_name); +- break; +- case 'y': +- $$ = new extractor_expr($1, find_year, $3); +- break; +- case 'n': +- $$ = new extractor_expr($1, find_last_name, $3); +- break; +- default: +- $$ = $1; +- command_error("unknown function `%1'", char($4)); +- break; +- } +- } +- +- | string '+' number +- { $$ = new truncate_expr($1, $3); } +- | string '-' number +- { $$ = new truncate_expr($1, -$3); } +- | string '*' +- { $$ = new star_expr($1); } +- | '(' optional_conditional ')' +- { $$ = $2; } +- | '<' optional_conditional '>' +- { $$ = new separator_expr($2); } +- ; +- +-optional_number: +- /* empty */ +- { $$ = -1; } +- | number +- { $$ = $1; } +- ; +- +-number: +- TOKEN_DIGIT +- { $$ = $1; } +- | number TOKEN_DIGIT +- { $$ = $1*10 + $2; } +- ; +- +-digits: +- TOKEN_DIGIT +- { $$.ndigits = 1; $$.val = $1; } +- | digits TOKEN_DIGIT +- { $$.ndigits = $1.ndigits + 1; $$.val = $1.val*10 + $2; } +- ; +- +- +-flag: +- /* empty */ +- { $$ = 0; } +- | '+' +- { $$ = 1; } +- | '-' +- { $$ = -1; } +- ; +- +-%% +- +-/* bison defines const to be empty unless __STDC__ is defined, which it +-isn't under cfront */ +- +-#ifdef const +-#undef const +-#endif +- +-const char *spec_ptr; +-const char *spec_end; +-const char *spec_cur; +- +-static char uppercase_array[] = { +- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', +- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', +- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', +- 'Y', 'Z', +-}; +- +-static char lowercase_array[] = { +- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', +- 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', +- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', +- 'y', 'z', +-}; +- +-int yylex() +-{ +- while (spec_ptr < spec_end && csspace(*spec_ptr)) +- spec_ptr++; +- spec_cur = spec_ptr; +- if (spec_ptr >= spec_end) +- return 0; +- unsigned char c = *spec_ptr++; +- if (csalpha(c)) { +- yylval.num = c; +- return TOKEN_LETTER; +- } +- if (csdigit(c)) { +- yylval.num = c - '0'; +- return TOKEN_DIGIT; +- } +- if (c == '\'') { +- yylval.str.start = literals.length(); +- for (; spec_ptr < spec_end; spec_ptr++) { +- if (*spec_ptr == '\'') { +- if (++spec_ptr < spec_end && *spec_ptr == '\'') +- literals += '\''; +- else { +- yylval.str.len = literals.length() - yylval.str.start; +- return TOKEN_LITERAL; +- } +- } +- else +- literals += *spec_ptr; +- } +- yylval.str.len = literals.length() - yylval.str.start; +- return TOKEN_LITERAL; +- } +- return c; +-} +- +-int set_label_spec(const char *label_spec) +-{ +- spec_cur = spec_ptr = label_spec; +- spec_end = strchr(label_spec, '\0'); +- literals.clear(); +- if (yyparse()) +- return 0; +- delete parsed_label; +- parsed_label = parse_result; +- return 1; +-} +- +-int set_date_label_spec(const char *label_spec) +-{ +- spec_cur = spec_ptr = label_spec; +- spec_end = strchr(label_spec, '\0'); +- literals.clear(); +- if (yyparse()) +- return 0; +- delete parsed_date_label; +- parsed_date_label = parse_result; +- return 1; +-} +- +-int set_short_label_spec(const char *label_spec) +-{ +- spec_cur = spec_ptr = label_spec; +- spec_end = strchr(label_spec, '\0'); +- literals.clear(); +- if (yyparse()) +- return 0; +- delete parsed_short_label; +- parsed_short_label = parse_result; +- return 1; +-} +- +-void yyerror(const char *message) +-{ +- if (spec_cur < spec_end) +- command_error("label specification %1 before `%2'", message, spec_cur); +- else +- command_error("label specification %1 at end of string", +- message, spec_cur); +-} +- +-void at_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (tentative) +- ref.canonicalize_authors(result); +- else { +- const char *end, *start = ref.get_authors(&end); +- if (start) +- result.append(start, end - start); +- } +-} +- +-void format_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (tentative) +- return; +- const label_info *lp = ref.get_label_ptr(); +- int num = lp == 0 ? ref.get_number() : lp->count; +- if (type != '0') +- result += format_serial(type, num + 1); +- else { +- const char *ptr = i_to_a(num + first_number); +- int pad = width - strlen(ptr); +- while (--pad >= 0) +- result += '0'; +- result += ptr; +- } +-} +- +-static const char *format_serial(char c, int n) +-{ +- assert(n > 0); +- static char buf[128]; // more than enough. +- switch (c) { +- case 'i': +- case 'I': +- { +- char *p = buf; +- // troff uses z and w to represent 10000 and 5000 in Roman +- // numerals; I can find no historical basis for this usage +- const char *s = c == 'i' ? "zwmdclxvi" : "ZWMDCLXVI"; +- if (n >= 40000) +- return i_to_a(n); +- while (n >= 10000) { +- *p++ = s[0]; +- n -= 10000; +- } +- for (int i = 1000; i > 0; i /= 10, s += 2) { +- int m = n/i; +- n -= m*i; +- switch (m) { +- case 3: +- *p++ = s[2]; +- /* falls through */ +- case 2: +- *p++ = s[2]; +- /* falls through */ +- case 1: +- *p++ = s[2]; +- break; +- case 4: +- *p++ = s[2]; +- *p++ = s[1]; +- break; +- case 8: +- *p++ = s[1]; +- *p++ = s[2]; +- *p++ = s[2]; +- *p++ = s[2]; +- break; +- case 7: +- *p++ = s[1]; +- *p++ = s[2]; +- *p++ = s[2]; +- break; +- case 6: +- *p++ = s[1]; +- *p++ = s[2]; +- break; +- case 5: +- *p++ = s[1]; +- break; +- case 9: +- *p++ = s[2]; +- *p++ = s[0]; +- } +- } +- *p = 0; +- break; +- } +- case 'a': +- case 'A': +- { +- char *p = buf; +- // this is derived from troff/reg.c +- while (n > 0) { +- int d = n % 26; +- if (d == 0) +- d = 26; +- n -= d; +- n /= 26; +- *p++ = c == 'a' ? lowercase_array[d - 1] : +- uppercase_array[d - 1]; +- } +- *p-- = 0; +- // Reverse it. +- char *q = buf; +- while (q < p) { +- char temp = *q; +- *q = *p; +- *p = temp; +- --p; +- ++q; +- } +- break; +- } +- default: +- assert(0); +- } +- return buf; +-} +- +-void field_expr::evaluate(int, const reference &ref, +- string &result, substring_position &) +-{ +- const char *end; +- const char *start = ref.get_field(name, &end); +- if (start) { +- start = nth_field(number, start, &end); +- if (start) +- result.append(start, end - start); +- } +-} +- +-void literal_expr::evaluate(int, const reference &, +- string &result, substring_position &) +-{ +- result += s; +-} +- +-analyzed_expr::analyzed_expr(expression *e) +-: unary_expr(e), flags(e ? e->analyze() : 0) +-{ +-} +- +-void analyzed_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- if (expr) +- expr->evaluate(tentative, ref, result, pos); +-} +- +-void star_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- const label_info *lp = ref.get_label_ptr(); +- if (!tentative +- && (lp == 0 || lp->total > 1) +- && expr) +- expr->evaluate(tentative, ref, result, pos); +-} +- +-void separator_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- int start_length = result.length(); +- int is_first = pos.start < 0; +- if (expr) +- expr->evaluate(tentative, ref, result, pos); +- if (is_first) { +- pos.start = start_length; +- pos.length = result.length() - start_length; +- } +-} +- +-void map_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (expr) { +- string temp; +- substring_position temp_pos; +- expr->evaluate(tentative, ref, temp, temp_pos); +- (*func)(temp.contents(), temp.contents() + temp.length(), result); +- } +-} +- +-void extractor_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (expr) { +- string temp; +- substring_position temp_pos; +- expr->evaluate(tentative, ref, temp, temp_pos); +- const char *end, *start = (*func)(temp.contents(), +- temp.contents() + temp.length(), +- &end); +- switch (part) { +- case BEFORE: +- if (start) +- result.append(temp.contents(), start - temp.contents()); +- else +- result += temp; +- break; +- case MATCH: +- if (start) +- result.append(start, end - start); +- break; +- case AFTER: +- if (start) +- result.append(end, temp.contents() + temp.length() - end); +- break; +- default: +- assert(0); +- } +- } +-} +- +-static void first_part(int len, const char *ptr, const char *end, +- string &result) +-{ +- for (;;) { +- const char *token_start = ptr; +- if (!get_token(&ptr, end)) +- break; +- const token_info *ti = lookup_token(token_start, ptr); +- int counts = ti->sortify_non_empty(token_start, ptr); +- if (counts && --len < 0) +- break; +- if (counts || ti->is_accent()) +- result.append(token_start, ptr - token_start); +- } +-} +- +-static void last_part(int len, const char *ptr, const char *end, +- string &result) +-{ +- const char *start = ptr; +- int count = 0; +- for (;;) { +- const char *token_start = ptr; +- if (!get_token(&ptr, end)) +- break; +- const token_info *ti = lookup_token(token_start, ptr); +- if (ti->sortify_non_empty(token_start, ptr)) +- count++; +- } +- ptr = start; +- int skip = count - len; +- if (skip > 0) { +- for (;;) { +- const char *token_start = ptr; +- if (!get_token(&ptr, end)) +- assert(0); +- const token_info *ti = lookup_token(token_start, ptr); +- if (ti->sortify_non_empty(token_start, ptr) && --skip < 0) { +- ptr = token_start; +- break; +- } +- } +- } +- first_part(len, ptr, end, result); +-} +- +-void truncate_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &) +-{ +- if (expr) { +- string temp; +- substring_position temp_pos; +- expr->evaluate(tentative, ref, temp, temp_pos); +- const char *start = temp.contents(); +- const char *end = start + temp.length(); +- if (n > 0) +- first_part(n, start, end, result); +- else if (n < 0) +- last_part(-n, start, end, result); +- } +-} +- +-void alternative_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- int start_length = result.length(); +- if (expr1) +- expr1->evaluate(tentative, ref, result, pos); +- if (result.length() == start_length && expr2) +- expr2->evaluate(tentative, ref, result, pos); +-} +- +-void list_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- if (expr1) +- expr1->evaluate(tentative, ref, result, pos); +- if (expr2) +- expr2->evaluate(tentative, ref, result, pos); +-} +- +-void substitute_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- int start_length = result.length(); +- if (expr1) +- expr1->evaluate(tentative, ref, result, pos); +- if (result.length() > start_length && result[result.length() - 1] == '-') { +- // ought to see if pos covers the - +- result.set_length(result.length() - 1); +- if (expr2) +- expr2->evaluate(tentative, ref, result, pos); +- } +-} +- +-void conditional_expr::evaluate(int tentative, const reference &ref, +- string &result, substring_position &pos) +-{ +- string temp; +- substring_position temp_pos; +- if (expr1) +- expr1->evaluate(tentative, ref, temp, temp_pos); +- if (temp.length() > 0) { +- if (expr2) +- expr2->evaluate(tentative, ref, result, pos); +- } +- else { +- if (expr3) +- expr3->evaluate(tentative, ref, result, pos); +- } +-} +- +-void reference::pre_compute_label() +-{ +- if (parsed_label != 0 +- && (parsed_label->analyze() & expression::CONTAINS_VARIABLE)) { +- label.clear(); +- substring_position temp_pos; +- parsed_label->evaluate(1, *this, label, temp_pos); +- label_ptr = lookup_label(label); +- } +-} +- +-void reference::compute_label() +-{ +- label.clear(); +- if (parsed_label) +- parsed_label->evaluate(0, *this, label, separator_pos); +- if (short_label_flag && parsed_short_label) +- parsed_short_label->evaluate(0, *this, short_label, short_separator_pos); +- if (date_as_label) { +- string new_date; +- if (parsed_date_label) { +- substring_position temp_pos; +- parsed_date_label->evaluate(0, *this, new_date, temp_pos); +- } +- set_date(new_date); +- } +- if (label_ptr) +- label_ptr->count += 1; +-} +- +-void reference::immediate_compute_label() +-{ +- if (label_ptr) +- label_ptr->total = 2; // force use of disambiguator +- compute_label(); +-} +- +-int reference::merge_labels(reference **v, int n, label_type type, +- string &result) +-{ +- if (abbreviate_label_ranges) +- return merge_labels_by_number(v, n, type, result); +- else +- return merge_labels_by_parts(v, n, type, result); +-} +- +-int reference::merge_labels_by_number(reference **v, int n, label_type type, +- string &result) +-{ +- if (n <= 1) +- return 0; +- int num = get_number(); +- // Only merge three or more labels. +- if (v[0]->get_number() != num + 1 +- || v[1]->get_number() != num + 2) +- return 0; +- int i; +- for (i = 2; i < n; i++) +- if (v[i]->get_number() != num + i + 1) +- break; +- result = get_label(type); +- result += label_range_indicator; +- result += v[i - 1]->get_label(type); +- return i; +-} +- +-const substring_position &reference::get_separator_pos(label_type type) const +-{ +- if (type == SHORT_LABEL && short_label_flag) +- return short_separator_pos; +- else +- return separator_pos; +-} +- +-const string &reference::get_label(label_type type) const +-{ +- if (type == SHORT_LABEL && short_label_flag) +- return short_label; +- else +- return label; +-} +- +-int reference::merge_labels_by_parts(reference **v, int n, label_type type, +- string &result) +-{ +- if (n <= 0) +- return 0; +- const string &lb = get_label(type); +- const substring_position &sp = get_separator_pos(type); +- if (sp.start < 0 +- || sp.start != v[0]->get_separator_pos(type).start +- || memcmp(lb.contents(), v[0]->get_label(type).contents(), +- sp.start) != 0) +- return 0; +- result = lb; +- int i = 0; +- do { +- result += separate_label_second_parts; +- const substring_position &s = v[i]->get_separator_pos(type); +- int sep_end_pos = s.start + s.length; +- result.append(v[i]->get_label(type).contents() + sep_end_pos, +- v[i]->get_label(type).length() - sep_end_pos); +- } while (++i < n +- && sp.start == v[i]->get_separator_pos(type).start +- && memcmp(lb.contents(), v[i]->get_label(type).contents(), +- sp.start) == 0); +- return i; +-} +- +-string label_pool; +- +-label_info::label_info(const string &s) +-: start(label_pool.length()), length(s.length()), count(0), total(1) +-{ +- label_pool += s; +-} +- +-static label_info **label_table = 0; +-static int label_table_size = 0; +-static int label_table_used = 0; +- +-label_info *lookup_label(const string &label) +-{ +- if (label_table == 0) { +- label_table = new label_info *[17]; +- label_table_size = 17; +- for (int i = 0; i < 17; i++) +- label_table[i] = 0; +- } +- unsigned h = hash_string(label.contents(), label.length()) % label_table_size; +- label_info **ptr; +- for (ptr = label_table + h; +- *ptr != 0; +- (ptr == label_table) +- ? (ptr = label_table + label_table_size - 1) +- : ptr--) +- if ((*ptr)->length == label.length() +- && memcmp(label_pool.contents() + (*ptr)->start, label.contents(), +- label.length()) == 0) { +- (*ptr)->total += 1; +- return *ptr; +- } +- label_info *result = *ptr = new label_info(label); +- if (++label_table_used * 2 > label_table_size) { +- // Rehash the table. +- label_info **old_table = label_table; +- int old_size = label_table_size; +- label_table_size = next_size(label_table_size); +- label_table = new label_info *[label_table_size]; +- int i; +- for (i = 0; i < label_table_size; i++) +- label_table[i] = 0; +- for (i = 0; i < old_size; i++) +- if (old_table[i]) { +- h = hash_string(label_pool.contents() + old_table[i]->start, +- old_table[i]->length); +- label_info **p; +- for (p = label_table + (h % label_table_size); +- *p != 0; +- (p == label_table) +- ? (p = label_table + label_table_size - 1) +- : --p) +- ; +- *p = old_table[i]; +- } +- a_delete old_table; +- } +- return result; +-} +- +-void clear_labels() +-{ +- for (int i = 0; i < label_table_size; i++) { +- delete label_table[i]; +- label_table[i] = 0; +- } +- label_table_used = 0; +- label_pool.clear(); +-} +- +-static void consider_authors(reference **start, reference **end, int i); +- +-void compute_labels(reference **v, int n) +-{ +- if (parsed_label +- && (parsed_label->analyze() & expression::CONTAINS_AT) +- && sort_fields.length() >= 2 +- && sort_fields[0] == 'A' +- && sort_fields[1] == '+') +- consider_authors(v, v + n, 0); +- for (int i = 0; i < n; i++) +- v[i]->compute_label(); +-} +- +- +-/* A reference with a list of authors _needs_ author i +-where 0 <= i <= N if there exists a reference with a list of authors +- such that != and M >= i +-and Aj = Bj for 0 <= j < i. In this case if we can't say ``A0, +-A1,...,A(i-1) et al'' because this would match both and +-. If a reference needs author i we only have to call +-need_author(j) for some j >= i such that the reference also needs +-author j. */ +- +-/* This function handles 2 tasks: +-determine which authors are needed (cannot be elided with et al.); +-determine which authors can have only last names in the labels. +- +-References >= start and < end have the same first i author names. +-Also they're sorted by A+. */ +- +-static void consider_authors(reference **start, reference **end, int i) +-{ +- if (start >= end) +- return; +- reference **p = start; +- if (i >= (*p)->get_nauthors()) { +- for (++p; p < end && i >= (*p)->get_nauthors(); p++) +- ; +- if (p < end && i > 0) { +- // If we have an author list and an author list , +- // then both lists need C. +- for (reference **q = start; q < end; q++) +- (*q)->need_author(i - 1); +- } +- start = p; +- } +- while (p < end) { +- reference **last_name_start = p; +- reference **name_start = p; +- for (++p; +- p < end && i < (*p)->get_nauthors() +- && same_author_last_name(**last_name_start, **p, i); +- p++) { +- if (!same_author_name(**name_start, **p, i)) { +- consider_authors(name_start, p, i + 1); +- name_start = p; +- } +- } +- consider_authors(name_start, p, i + 1); +- if (last_name_start == name_start) { +- for (reference **q = last_name_start; q < p; q++) +- (*q)->set_last_name_unambiguous(i); +- } +- // If we have an author list and , then the lists +- // need author D and E respectively. +- if (name_start > start || p < end) { +- for (reference **q = last_name_start; q < p; q++) +- (*q)->need_author(i); +- } +- } +-} +- +-int same_author_last_name(const reference &r1, const reference &r2, int n) +-{ +- const char *ae1; +- const char *as1 = r1.get_sort_field(0, n, 0, &ae1); +- const char *ae2; +- const char *as2 = r2.get_sort_field(0, n, 0, &ae2); +- if (!as1 && !as2) return 1; // they are the same +- if (!as1 || !as2) return 0; +- return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; +-} +- +-int same_author_name(const reference &r1, const reference &r2, int n) +-{ +- const char *ae1; +- const char *as1 = r1.get_sort_field(0, n, -1, &ae1); +- const char *ae2; +- const char *as2 = r2.get_sort_field(0, n, -1, &ae2); +- if (!as1 && !as2) return 1; // they are the same +- if (!as1 || !as2) return 0; +- return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; +-} +- +- +-void int_set::set(int i) +-{ +- assert(i >= 0); +- int bytei = i >> 3; +- if (bytei >= v.length()) { +- int old_length = v.length(); +- v.set_length(bytei + 1); +- for (int j = old_length; j <= bytei; j++) +- v[j] = 0; +- } +- v[bytei] |= 1 << (i & 7); +-} +- +-int int_set::get(int i) const +-{ +- assert(i >= 0); +- int bytei = i >> 3; +- return bytei >= v.length() ? 0 : (v[bytei] & (1 << (i & 7))) != 0; +-} +- +-void reference::set_last_name_unambiguous(int i) +-{ +- last_name_unambiguous.set(i); +-} +- +-void reference::need_author(int n) +-{ +- if (n > last_needed_author) +- last_needed_author = n; +-} +- +-const char *reference::get_authors(const char **end) const +-{ +- if (!computed_authors) { +- ((reference *)this)->computed_authors = 1; +- string &result = ((reference *)this)->authors; +- int na = get_nauthors(); +- result.clear(); +- for (int i = 0; i < na; i++) { +- if (last_name_unambiguous.get(i)) { +- const char *e, *start = get_author_last_name(i, &e); +- assert(start != 0); +- result.append(start, e - start); +- } +- else { +- const char *e, *start = get_author(i, &e); +- assert(start != 0); +- result.append(start, e - start); +- } +- if (i == last_needed_author +- && et_al.length() > 0 +- && et_al_min_elide > 0 +- && last_needed_author + et_al_min_elide < na +- && na >= et_al_min_total) { +- result += et_al; +- break; +- } +- if (i < na - 1) { +- if (na == 2) +- result += join_authors_exactly_two; +- else if (i < na - 2) +- result += join_authors_default; +- else +- result += join_authors_last_two; +- } +- } +- } +- const char *start = authors.contents(); +- *end = start + authors.length(); +- return start; +-} +- +-int reference::get_nauthors() const +-{ +- if (nauthors < 0) { +- const char *dummy; +- int na; +- for (na = 0; get_author(na, &dummy) != 0; na++) +- ; +- ((reference *)this)->nauthors = na; +- } +- return nauthors; +-} +diff -Nuar groff-1.22.3.old/src/preproc/refer/label.ypp groff-1.22.3/src/preproc/refer/label.ypp +--- groff-1.22.3.old/src/preproc/refer/label.ypp 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/refer/label.ypp 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,1191 @@ ++/* -*- C++ -*- ++ Copyright (C) 1989-2014 Free Software Foundation, Inc. ++ Written by James Clark (jjc@jclark.com) ++ ++This file is part of groff. ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation, either version 3 of the License, or ++(at your option) any later version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ANY ++WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program. If not, see . */ ++ ++%{ ++ ++#include "refer.h" ++#include "refid.h" ++#include "ref.h" ++#include "token.h" ++ ++int yylex(); ++void yyerror(const char *); ++int yyparse(); ++ ++static const char *format_serial(char c, int n); ++ ++struct label_info { ++ int start; ++ int length; ++ int count; ++ int total; ++ label_info(const string &); ++}; ++ ++label_info *lookup_label(const string &label); ++ ++struct expression { ++ enum { ++ // Does the tentative label depend on the reference? ++ CONTAINS_VARIABLE = 01, ++ CONTAINS_STAR = 02, ++ CONTAINS_FORMAT = 04, ++ CONTAINS_AT = 010 ++ }; ++ virtual ~expression() { } ++ virtual void evaluate(int, const reference &, string &, ++ substring_position &) = 0; ++ virtual unsigned analyze() { return 0; } ++}; ++ ++class at_expr : public expression { ++public: ++ at_expr() { } ++ void evaluate(int, const reference &, string &, substring_position &); ++ unsigned analyze() { return CONTAINS_VARIABLE|CONTAINS_AT; } ++}; ++ ++class format_expr : public expression { ++ char type; ++ int width; ++ int first_number; ++public: ++ format_expr(char c, int w = 0, int f = 1) ++ : type(c), width(w), first_number(f) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++ unsigned analyze() { return CONTAINS_FORMAT; } ++}; ++ ++class field_expr : public expression { ++ int number; ++ char name; ++public: ++ field_expr(char nm, int num) : number(num), name(nm) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++ unsigned analyze() { return CONTAINS_VARIABLE; } ++}; ++ ++class literal_expr : public expression { ++ string s; ++public: ++ literal_expr(const char *ptr, int len) : s(ptr, len) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++}; ++ ++class unary_expr : public expression { ++protected: ++ expression *expr; ++public: ++ unary_expr(expression *e) : expr(e) { } ++ ~unary_expr() { delete expr; } ++ void evaluate(int, const reference &, string &, substring_position &) = 0; ++ unsigned analyze() { return expr ? expr->analyze() : 0; } ++}; ++ ++// This caches the analysis of an expression. ++ ++class analyzed_expr : public unary_expr { ++ unsigned flags; ++public: ++ analyzed_expr(expression *); ++ void evaluate(int, const reference &, string &, substring_position &); ++ unsigned analyze() { return flags; } ++}; ++ ++class star_expr : public unary_expr { ++public: ++ star_expr(expression *e) : unary_expr(e) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++ unsigned analyze() { ++ return ((expr ? (expr->analyze() & ~CONTAINS_VARIABLE) : 0) ++ | CONTAINS_STAR); ++ } ++}; ++ ++typedef void map_func(const char *, const char *, string &); ++ ++class map_expr : public unary_expr { ++ map_func *func; ++public: ++ map_expr(expression *e, map_func *f) : unary_expr(e), func(f) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++}; ++ ++typedef const char *extractor_func(const char *, const char *, const char **); ++ ++class extractor_expr : public unary_expr { ++ int part; ++ extractor_func *func; ++public: ++ enum { BEFORE = +1, MATCH = 0, AFTER = -1 }; ++ extractor_expr(expression *e, extractor_func *f, int pt) ++ : unary_expr(e), part(pt), func(f) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++}; ++ ++class truncate_expr : public unary_expr { ++ int n; ++public: ++ truncate_expr(expression *e, int i) : unary_expr(e), n(i) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++}; ++ ++class separator_expr : public unary_expr { ++public: ++ separator_expr(expression *e) : unary_expr(e) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++}; ++ ++class binary_expr : public expression { ++protected: ++ expression *expr1; ++ expression *expr2; ++public: ++ binary_expr(expression *e1, expression *e2) : expr1(e1), expr2(e2) { } ++ ~binary_expr() { delete expr1; delete expr2; } ++ void evaluate(int, const reference &, string &, substring_position &) = 0; ++ unsigned analyze() { ++ return (expr1 ? expr1->analyze() : 0) | (expr2 ? expr2->analyze() : 0); ++ } ++}; ++ ++class alternative_expr : public binary_expr { ++public: ++ alternative_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++}; ++ ++class list_expr : public binary_expr { ++public: ++ list_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++}; ++ ++class substitute_expr : public binary_expr { ++public: ++ substitute_expr(expression *e1, expression *e2) : binary_expr(e1, e2) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++}; ++ ++class ternary_expr : public expression { ++protected: ++ expression *expr1; ++ expression *expr2; ++ expression *expr3; ++public: ++ ternary_expr(expression *e1, expression *e2, expression *e3) ++ : expr1(e1), expr2(e2), expr3(e3) { } ++ ~ternary_expr() { delete expr1; delete expr2; delete expr3; } ++ void evaluate(int, const reference &, string &, substring_position &) = 0; ++ unsigned analyze() { ++ return ((expr1 ? expr1->analyze() : 0) ++ | (expr2 ? expr2->analyze() : 0) ++ | (expr3 ? expr3->analyze() : 0)); ++ } ++}; ++ ++class conditional_expr : public ternary_expr { ++public: ++ conditional_expr(expression *e1, expression *e2, expression *e3) ++ : ternary_expr(e1, e2, e3) { } ++ void evaluate(int, const reference &, string &, substring_position &); ++}; ++ ++static expression *parsed_label = 0; ++static expression *parsed_date_label = 0; ++static expression *parsed_short_label = 0; ++ ++static expression *parse_result; ++ ++string literals; ++ ++%} ++ ++%union { ++ int num; ++ expression *expr; ++ struct { int ndigits; int val; } dig; ++ struct { int start; int len; } str; ++} ++ ++/* uppercase or lowercase letter */ ++%token TOKEN_LETTER ++/* literal characters */ ++%token TOKEN_LITERAL ++/* digit */ ++%token TOKEN_DIGIT ++ ++%type conditional ++%type alternative ++%type list ++%type string ++%type substitute ++%type optional_conditional ++%type number ++%type digits ++%type optional_number ++%type flag ++ ++%% ++ ++expr: ++ optional_conditional ++ { parse_result = ($1 ? new analyzed_expr($1) : 0); } ++ ; ++ ++conditional: ++ alternative ++ { $$ = $1; } ++ | alternative '?' optional_conditional ':' conditional ++ { $$ = new conditional_expr($1, $3, $5); } ++ ; ++ ++optional_conditional: ++ /* empty */ ++ { $$ = 0; } ++ | conditional ++ { $$ = $1; } ++ ; ++ ++alternative: ++ list ++ { $$ = $1; } ++ | alternative '|' list ++ { $$ = new alternative_expr($1, $3); } ++ | alternative '&' list ++ { $$ = new conditional_expr($1, $3, 0); } ++ ; ++ ++list: ++ substitute ++ { $$ = $1; } ++ | list substitute ++ { $$ = new list_expr($1, $2); } ++ ; ++ ++substitute: ++ string ++ { $$ = $1; } ++ | substitute '~' string ++ { $$ = new substitute_expr($1, $3); } ++ ; ++ ++string: ++ '@' ++ { $$ = new at_expr; } ++ | TOKEN_LITERAL ++ { ++ $$ = new literal_expr(literals.contents() + $1.start, ++ $1.len); ++ } ++ | TOKEN_LETTER ++ { $$ = new field_expr($1, 0); } ++ | TOKEN_LETTER number ++ { $$ = new field_expr($1, $2 - 1); } ++ | '%' TOKEN_LETTER ++ { ++ switch ($2) { ++ case 'I': ++ case 'i': ++ case 'A': ++ case 'a': ++ $$ = new format_expr($2); ++ break; ++ default: ++ command_error("unrecognized format `%1'", char($2)); ++ $$ = new format_expr('a'); ++ break; ++ } ++ } ++ ++ | '%' digits ++ { ++ $$ = new format_expr('0', $2.ndigits, $2.val); ++ } ++ | string '.' flag TOKEN_LETTER optional_number ++ { ++ switch ($4) { ++ case 'l': ++ $$ = new map_expr($1, lowercase); ++ break; ++ case 'u': ++ $$ = new map_expr($1, uppercase); ++ break; ++ case 'c': ++ $$ = new map_expr($1, capitalize); ++ break; ++ case 'r': ++ $$ = new map_expr($1, reverse_name); ++ break; ++ case 'a': ++ $$ = new map_expr($1, abbreviate_name); ++ break; ++ case 'y': ++ $$ = new extractor_expr($1, find_year, $3); ++ break; ++ case 'n': ++ $$ = new extractor_expr($1, find_last_name, $3); ++ break; ++ default: ++ $$ = $1; ++ command_error("unknown function `%1'", char($4)); ++ break; ++ } ++ } ++ ++ | string '+' number ++ { $$ = new truncate_expr($1, $3); } ++ | string '-' number ++ { $$ = new truncate_expr($1, -$3); } ++ | string '*' ++ { $$ = new star_expr($1); } ++ | '(' optional_conditional ')' ++ { $$ = $2; } ++ | '<' optional_conditional '>' ++ { $$ = new separator_expr($2); } ++ ; ++ ++optional_number: ++ /* empty */ ++ { $$ = -1; } ++ | number ++ { $$ = $1; } ++ ; ++ ++number: ++ TOKEN_DIGIT ++ { $$ = $1; } ++ | number TOKEN_DIGIT ++ { $$ = $1*10 + $2; } ++ ; ++ ++digits: ++ TOKEN_DIGIT ++ { $$.ndigits = 1; $$.val = $1; } ++ | digits TOKEN_DIGIT ++ { $$.ndigits = $1.ndigits + 1; $$.val = $1.val*10 + $2; } ++ ; ++ ++ ++flag: ++ /* empty */ ++ { $$ = 0; } ++ | '+' ++ { $$ = 1; } ++ | '-' ++ { $$ = -1; } ++ ; ++ ++%% ++ ++/* bison defines const to be empty unless __STDC__ is defined, which it ++isn't under cfront */ ++ ++#ifdef const ++#undef const ++#endif ++ ++const char *spec_ptr; ++const char *spec_end; ++const char *spec_cur; ++ ++static char uppercase_array[] = { ++ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', ++ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', ++ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', ++ 'Y', 'Z', ++}; ++ ++static char lowercase_array[] = { ++ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', ++ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', ++ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', ++ 'y', 'z', ++}; ++ ++int yylex() ++{ ++ while (spec_ptr < spec_end && csspace(*spec_ptr)) ++ spec_ptr++; ++ spec_cur = spec_ptr; ++ if (spec_ptr >= spec_end) ++ return 0; ++ unsigned char c = *spec_ptr++; ++ if (csalpha(c)) { ++ yylval.num = c; ++ return TOKEN_LETTER; ++ } ++ if (csdigit(c)) { ++ yylval.num = c - '0'; ++ return TOKEN_DIGIT; ++ } ++ if (c == '\'') { ++ yylval.str.start = literals.length(); ++ for (; spec_ptr < spec_end; spec_ptr++) { ++ if (*spec_ptr == '\'') { ++ if (++spec_ptr < spec_end && *spec_ptr == '\'') ++ literals += '\''; ++ else { ++ yylval.str.len = literals.length() - yylval.str.start; ++ return TOKEN_LITERAL; ++ } ++ } ++ else ++ literals += *spec_ptr; ++ } ++ yylval.str.len = literals.length() - yylval.str.start; ++ return TOKEN_LITERAL; ++ } ++ return c; ++} ++ ++int set_label_spec(const char *label_spec) ++{ ++ spec_cur = spec_ptr = label_spec; ++ spec_end = strchr(label_spec, '\0'); ++ literals.clear(); ++ if (yyparse()) ++ return 0; ++ delete parsed_label; ++ parsed_label = parse_result; ++ return 1; ++} ++ ++int set_date_label_spec(const char *label_spec) ++{ ++ spec_cur = spec_ptr = label_spec; ++ spec_end = strchr(label_spec, '\0'); ++ literals.clear(); ++ if (yyparse()) ++ return 0; ++ delete parsed_date_label; ++ parsed_date_label = parse_result; ++ return 1; ++} ++ ++int set_short_label_spec(const char *label_spec) ++{ ++ spec_cur = spec_ptr = label_spec; ++ spec_end = strchr(label_spec, '\0'); ++ literals.clear(); ++ if (yyparse()) ++ return 0; ++ delete parsed_short_label; ++ parsed_short_label = parse_result; ++ return 1; ++} ++ ++void yyerror(const char *message) ++{ ++ if (spec_cur < spec_end) ++ command_error("label specification %1 before `%2'", message, spec_cur); ++ else ++ command_error("label specification %1 at end of string", ++ message, spec_cur); ++} ++ ++void at_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &) ++{ ++ if (tentative) ++ ref.canonicalize_authors(result); ++ else { ++ const char *end, *start = ref.get_authors(&end); ++ if (start) ++ result.append(start, end - start); ++ } ++} ++ ++void format_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &) ++{ ++ if (tentative) ++ return; ++ const label_info *lp = ref.get_label_ptr(); ++ int num = lp == 0 ? ref.get_number() : lp->count; ++ if (type != '0') ++ result += format_serial(type, num + 1); ++ else { ++ const char *ptr = i_to_a(num + first_number); ++ int pad = width - strlen(ptr); ++ while (--pad >= 0) ++ result += '0'; ++ result += ptr; ++ } ++} ++ ++static const char *format_serial(char c, int n) ++{ ++ assert(n > 0); ++ static char buf[128]; // more than enough. ++ switch (c) { ++ case 'i': ++ case 'I': ++ { ++ char *p = buf; ++ // troff uses z and w to represent 10000 and 5000 in Roman ++ // numerals; I can find no historical basis for this usage ++ const char *s = c == 'i' ? "zwmdclxvi" : "ZWMDCLXVI"; ++ if (n >= 40000) ++ return i_to_a(n); ++ while (n >= 10000) { ++ *p++ = s[0]; ++ n -= 10000; ++ } ++ for (int i = 1000; i > 0; i /= 10, s += 2) { ++ int m = n/i; ++ n -= m*i; ++ switch (m) { ++ case 3: ++ *p++ = s[2]; ++ /* falls through */ ++ case 2: ++ *p++ = s[2]; ++ /* falls through */ ++ case 1: ++ *p++ = s[2]; ++ break; ++ case 4: ++ *p++ = s[2]; ++ *p++ = s[1]; ++ break; ++ case 8: ++ *p++ = s[1]; ++ *p++ = s[2]; ++ *p++ = s[2]; ++ *p++ = s[2]; ++ break; ++ case 7: ++ *p++ = s[1]; ++ *p++ = s[2]; ++ *p++ = s[2]; ++ break; ++ case 6: ++ *p++ = s[1]; ++ *p++ = s[2]; ++ break; ++ case 5: ++ *p++ = s[1]; ++ break; ++ case 9: ++ *p++ = s[2]; ++ *p++ = s[0]; ++ } ++ } ++ *p = 0; ++ break; ++ } ++ case 'a': ++ case 'A': ++ { ++ char *p = buf; ++ // this is derived from troff/reg.c ++ while (n > 0) { ++ int d = n % 26; ++ if (d == 0) ++ d = 26; ++ n -= d; ++ n /= 26; ++ *p++ = c == 'a' ? lowercase_array[d - 1] : ++ uppercase_array[d - 1]; ++ } ++ *p-- = 0; ++ // Reverse it. ++ char *q = buf; ++ while (q < p) { ++ char temp = *q; ++ *q = *p; ++ *p = temp; ++ --p; ++ ++q; ++ } ++ break; ++ } ++ default: ++ assert(0); ++ } ++ return buf; ++} ++ ++void field_expr::evaluate(int, const reference &ref, ++ string &result, substring_position &) ++{ ++ const char *end; ++ const char *start = ref.get_field(name, &end); ++ if (start) { ++ start = nth_field(number, start, &end); ++ if (start) ++ result.append(start, end - start); ++ } ++} ++ ++void literal_expr::evaluate(int, const reference &, ++ string &result, substring_position &) ++{ ++ result += s; ++} ++ ++analyzed_expr::analyzed_expr(expression *e) ++: unary_expr(e), flags(e ? e->analyze() : 0) ++{ ++} ++ ++void analyzed_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &pos) ++{ ++ if (expr) ++ expr->evaluate(tentative, ref, result, pos); ++} ++ ++void star_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &pos) ++{ ++ const label_info *lp = ref.get_label_ptr(); ++ if (!tentative ++ && (lp == 0 || lp->total > 1) ++ && expr) ++ expr->evaluate(tentative, ref, result, pos); ++} ++ ++void separator_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &pos) ++{ ++ int start_length = result.length(); ++ int is_first = pos.start < 0; ++ if (expr) ++ expr->evaluate(tentative, ref, result, pos); ++ if (is_first) { ++ pos.start = start_length; ++ pos.length = result.length() - start_length; ++ } ++} ++ ++void map_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &) ++{ ++ if (expr) { ++ string temp; ++ substring_position temp_pos; ++ expr->evaluate(tentative, ref, temp, temp_pos); ++ (*func)(temp.contents(), temp.contents() + temp.length(), result); ++ } ++} ++ ++void extractor_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &) ++{ ++ if (expr) { ++ string temp; ++ substring_position temp_pos; ++ expr->evaluate(tentative, ref, temp, temp_pos); ++ const char *end, *start = (*func)(temp.contents(), ++ temp.contents() + temp.length(), ++ &end); ++ switch (part) { ++ case BEFORE: ++ if (start) ++ result.append(temp.contents(), start - temp.contents()); ++ else ++ result += temp; ++ break; ++ case MATCH: ++ if (start) ++ result.append(start, end - start); ++ break; ++ case AFTER: ++ if (start) ++ result.append(end, temp.contents() + temp.length() - end); ++ break; ++ default: ++ assert(0); ++ } ++ } ++} ++ ++static void first_part(int len, const char *ptr, const char *end, ++ string &result) ++{ ++ for (;;) { ++ const char *token_start = ptr; ++ if (!get_token(&ptr, end)) ++ break; ++ const token_info *ti = lookup_token(token_start, ptr); ++ int counts = ti->sortify_non_empty(token_start, ptr); ++ if (counts && --len < 0) ++ break; ++ if (counts || ti->is_accent()) ++ result.append(token_start, ptr - token_start); ++ } ++} ++ ++static void last_part(int len, const char *ptr, const char *end, ++ string &result) ++{ ++ const char *start = ptr; ++ int count = 0; ++ for (;;) { ++ const char *token_start = ptr; ++ if (!get_token(&ptr, end)) ++ break; ++ const token_info *ti = lookup_token(token_start, ptr); ++ if (ti->sortify_non_empty(token_start, ptr)) ++ count++; ++ } ++ ptr = start; ++ int skip = count - len; ++ if (skip > 0) { ++ for (;;) { ++ const char *token_start = ptr; ++ if (!get_token(&ptr, end)) ++ assert(0); ++ const token_info *ti = lookup_token(token_start, ptr); ++ if (ti->sortify_non_empty(token_start, ptr) && --skip < 0) { ++ ptr = token_start; ++ break; ++ } ++ } ++ } ++ first_part(len, ptr, end, result); ++} ++ ++void truncate_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &) ++{ ++ if (expr) { ++ string temp; ++ substring_position temp_pos; ++ expr->evaluate(tentative, ref, temp, temp_pos); ++ const char *start = temp.contents(); ++ const char *end = start + temp.length(); ++ if (n > 0) ++ first_part(n, start, end, result); ++ else if (n < 0) ++ last_part(-n, start, end, result); ++ } ++} ++ ++void alternative_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &pos) ++{ ++ int start_length = result.length(); ++ if (expr1) ++ expr1->evaluate(tentative, ref, result, pos); ++ if (result.length() == start_length && expr2) ++ expr2->evaluate(tentative, ref, result, pos); ++} ++ ++void list_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &pos) ++{ ++ if (expr1) ++ expr1->evaluate(tentative, ref, result, pos); ++ if (expr2) ++ expr2->evaluate(tentative, ref, result, pos); ++} ++ ++void substitute_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &pos) ++{ ++ int start_length = result.length(); ++ if (expr1) ++ expr1->evaluate(tentative, ref, result, pos); ++ if (result.length() > start_length && result[result.length() - 1] == '-') { ++ // ought to see if pos covers the - ++ result.set_length(result.length() - 1); ++ if (expr2) ++ expr2->evaluate(tentative, ref, result, pos); ++ } ++} ++ ++void conditional_expr::evaluate(int tentative, const reference &ref, ++ string &result, substring_position &pos) ++{ ++ string temp; ++ substring_position temp_pos; ++ if (expr1) ++ expr1->evaluate(tentative, ref, temp, temp_pos); ++ if (temp.length() > 0) { ++ if (expr2) ++ expr2->evaluate(tentative, ref, result, pos); ++ } ++ else { ++ if (expr3) ++ expr3->evaluate(tentative, ref, result, pos); ++ } ++} ++ ++void reference::pre_compute_label() ++{ ++ if (parsed_label != 0 ++ && (parsed_label->analyze() & expression::CONTAINS_VARIABLE)) { ++ label.clear(); ++ substring_position temp_pos; ++ parsed_label->evaluate(1, *this, label, temp_pos); ++ label_ptr = lookup_label(label); ++ } ++} ++ ++void reference::compute_label() ++{ ++ label.clear(); ++ if (parsed_label) ++ parsed_label->evaluate(0, *this, label, separator_pos); ++ if (short_label_flag && parsed_short_label) ++ parsed_short_label->evaluate(0, *this, short_label, short_separator_pos); ++ if (date_as_label) { ++ string new_date; ++ if (parsed_date_label) { ++ substring_position temp_pos; ++ parsed_date_label->evaluate(0, *this, new_date, temp_pos); ++ } ++ set_date(new_date); ++ } ++ if (label_ptr) ++ label_ptr->count += 1; ++} ++ ++void reference::immediate_compute_label() ++{ ++ if (label_ptr) ++ label_ptr->total = 2; // force use of disambiguator ++ compute_label(); ++} ++ ++int reference::merge_labels(reference **v, int n, label_type type, ++ string &result) ++{ ++ if (abbreviate_label_ranges) ++ return merge_labels_by_number(v, n, type, result); ++ else ++ return merge_labels_by_parts(v, n, type, result); ++} ++ ++int reference::merge_labels_by_number(reference **v, int n, label_type type, ++ string &result) ++{ ++ if (n <= 1) ++ return 0; ++ int num = get_number(); ++ // Only merge three or more labels. ++ if (v[0]->get_number() != num + 1 ++ || v[1]->get_number() != num + 2) ++ return 0; ++ int i; ++ for (i = 2; i < n; i++) ++ if (v[i]->get_number() != num + i + 1) ++ break; ++ result = get_label(type); ++ result += label_range_indicator; ++ result += v[i - 1]->get_label(type); ++ return i; ++} ++ ++const substring_position &reference::get_separator_pos(label_type type) const ++{ ++ if (type == SHORT_LABEL && short_label_flag) ++ return short_separator_pos; ++ else ++ return separator_pos; ++} ++ ++const string &reference::get_label(label_type type) const ++{ ++ if (type == SHORT_LABEL && short_label_flag) ++ return short_label; ++ else ++ return label; ++} ++ ++int reference::merge_labels_by_parts(reference **v, int n, label_type type, ++ string &result) ++{ ++ if (n <= 0) ++ return 0; ++ const string &lb = get_label(type); ++ const substring_position &sp = get_separator_pos(type); ++ if (sp.start < 0 ++ || sp.start != v[0]->get_separator_pos(type).start ++ || memcmp(lb.contents(), v[0]->get_label(type).contents(), ++ sp.start) != 0) ++ return 0; ++ result = lb; ++ int i = 0; ++ do { ++ result += separate_label_second_parts; ++ const substring_position &s = v[i]->get_separator_pos(type); ++ int sep_end_pos = s.start + s.length; ++ result.append(v[i]->get_label(type).contents() + sep_end_pos, ++ v[i]->get_label(type).length() - sep_end_pos); ++ } while (++i < n ++ && sp.start == v[i]->get_separator_pos(type).start ++ && memcmp(lb.contents(), v[i]->get_label(type).contents(), ++ sp.start) == 0); ++ return i; ++} ++ ++string label_pool; ++ ++label_info::label_info(const string &s) ++: start(label_pool.length()), length(s.length()), count(0), total(1) ++{ ++ label_pool += s; ++} ++ ++static label_info **label_table = 0; ++static int label_table_size = 0; ++static int label_table_used = 0; ++ ++label_info *lookup_label(const string &label) ++{ ++ if (label_table == 0) { ++ label_table = new label_info *[17]; ++ label_table_size = 17; ++ for (int i = 0; i < 17; i++) ++ label_table[i] = 0; ++ } ++ unsigned h = hash_string(label.contents(), label.length()) % label_table_size; ++ label_info **ptr; ++ for (ptr = label_table + h; ++ *ptr != 0; ++ (ptr == label_table) ++ ? (ptr = label_table + label_table_size - 1) ++ : ptr--) ++ if ((*ptr)->length == label.length() ++ && memcmp(label_pool.contents() + (*ptr)->start, label.contents(), ++ label.length()) == 0) { ++ (*ptr)->total += 1; ++ return *ptr; ++ } ++ label_info *result = *ptr = new label_info(label); ++ if (++label_table_used * 2 > label_table_size) { ++ // Rehash the table. ++ label_info **old_table = label_table; ++ int old_size = label_table_size; ++ label_table_size = next_size(label_table_size); ++ label_table = new label_info *[label_table_size]; ++ int i; ++ for (i = 0; i < label_table_size; i++) ++ label_table[i] = 0; ++ for (i = 0; i < old_size; i++) ++ if (old_table[i]) { ++ h = hash_string(label_pool.contents() + old_table[i]->start, ++ old_table[i]->length); ++ label_info **p; ++ for (p = label_table + (h % label_table_size); ++ *p != 0; ++ (p == label_table) ++ ? (p = label_table + label_table_size - 1) ++ : --p) ++ ; ++ *p = old_table[i]; ++ } ++ a_delete old_table; ++ } ++ return result; ++} ++ ++void clear_labels() ++{ ++ for (int i = 0; i < label_table_size; i++) { ++ delete label_table[i]; ++ label_table[i] = 0; ++ } ++ label_table_used = 0; ++ label_pool.clear(); ++} ++ ++static void consider_authors(reference **start, reference **end, int i); ++ ++void compute_labels(reference **v, int n) ++{ ++ if (parsed_label ++ && (parsed_label->analyze() & expression::CONTAINS_AT) ++ && sort_fields.length() >= 2 ++ && sort_fields[0] == 'A' ++ && sort_fields[1] == '+') ++ consider_authors(v, v + n, 0); ++ for (int i = 0; i < n; i++) ++ v[i]->compute_label(); ++} ++ ++ ++/* A reference with a list of authors _needs_ author i ++where 0 <= i <= N if there exists a reference with a list of authors ++ such that != and M >= i ++and Aj = Bj for 0 <= j < i. In this case if we can't say ``A0, ++A1,...,A(i-1) et al'' because this would match both and ++. If a reference needs author i we only have to call ++need_author(j) for some j >= i such that the reference also needs ++author j. */ ++ ++/* This function handles 2 tasks: ++determine which authors are needed (cannot be elided with et al.); ++determine which authors can have only last names in the labels. ++ ++References >= start and < end have the same first i author names. ++Also they're sorted by A+. */ ++ ++static void consider_authors(reference **start, reference **end, int i) ++{ ++ if (start >= end) ++ return; ++ reference **p = start; ++ if (i >= (*p)->get_nauthors()) { ++ for (++p; p < end && i >= (*p)->get_nauthors(); p++) ++ ; ++ if (p < end && i > 0) { ++ // If we have an author list and an author list , ++ // then both lists need C. ++ for (reference **q = start; q < end; q++) ++ (*q)->need_author(i - 1); ++ } ++ start = p; ++ } ++ while (p < end) { ++ reference **last_name_start = p; ++ reference **name_start = p; ++ for (++p; ++ p < end && i < (*p)->get_nauthors() ++ && same_author_last_name(**last_name_start, **p, i); ++ p++) { ++ if (!same_author_name(**name_start, **p, i)) { ++ consider_authors(name_start, p, i + 1); ++ name_start = p; ++ } ++ } ++ consider_authors(name_start, p, i + 1); ++ if (last_name_start == name_start) { ++ for (reference **q = last_name_start; q < p; q++) ++ (*q)->set_last_name_unambiguous(i); ++ } ++ // If we have an author list and , then the lists ++ // need author D and E respectively. ++ if (name_start > start || p < end) { ++ for (reference **q = last_name_start; q < p; q++) ++ (*q)->need_author(i); ++ } ++ } ++} ++ ++int same_author_last_name(const reference &r1, const reference &r2, int n) ++{ ++ const char *ae1; ++ const char *as1 = r1.get_sort_field(0, n, 0, &ae1); ++ const char *ae2; ++ const char *as2 = r2.get_sort_field(0, n, 0, &ae2); ++ if (!as1 && !as2) return 1; // they are the same ++ if (!as1 || !as2) return 0; ++ return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; ++} ++ ++int same_author_name(const reference &r1, const reference &r2, int n) ++{ ++ const char *ae1; ++ const char *as1 = r1.get_sort_field(0, n, -1, &ae1); ++ const char *ae2; ++ const char *as2 = r2.get_sort_field(0, n, -1, &ae2); ++ if (!as1 && !as2) return 1; // they are the same ++ if (!as1 || !as2) return 0; ++ return ae1 - as1 == ae2 - as2 && memcmp(as1, as2, ae1 - as1) == 0; ++} ++ ++ ++void int_set::set(int i) ++{ ++ assert(i >= 0); ++ int bytei = i >> 3; ++ if (bytei >= v.length()) { ++ int old_length = v.length(); ++ v.set_length(bytei + 1); ++ for (int j = old_length; j <= bytei; j++) ++ v[j] = 0; ++ } ++ v[bytei] |= 1 << (i & 7); ++} ++ ++int int_set::get(int i) const ++{ ++ assert(i >= 0); ++ int bytei = i >> 3; ++ return bytei >= v.length() ? 0 : (v[bytei] & (1 << (i & 7))) != 0; ++} ++ ++void reference::set_last_name_unambiguous(int i) ++{ ++ last_name_unambiguous.set(i); ++} ++ ++void reference::need_author(int n) ++{ ++ if (n > last_needed_author) ++ last_needed_author = n; ++} ++ ++const char *reference::get_authors(const char **end) const ++{ ++ if (!computed_authors) { ++ ((reference *)this)->computed_authors = 1; ++ string &result = ((reference *)this)->authors; ++ int na = get_nauthors(); ++ result.clear(); ++ for (int i = 0; i < na; i++) { ++ if (last_name_unambiguous.get(i)) { ++ const char *e, *start = get_author_last_name(i, &e); ++ assert(start != 0); ++ result.append(start, e - start); ++ } ++ else { ++ const char *e, *start = get_author(i, &e); ++ assert(start != 0); ++ result.append(start, e - start); ++ } ++ if (i == last_needed_author ++ && et_al.length() > 0 ++ && et_al_min_elide > 0 ++ && last_needed_author + et_al_min_elide < na ++ && na >= et_al_min_total) { ++ result += et_al; ++ break; ++ } ++ if (i < na - 1) { ++ if (na == 2) ++ result += join_authors_exactly_two; ++ else if (i < na - 2) ++ result += join_authors_default; ++ else ++ result += join_authors_last_two; ++ } ++ } ++ } ++ const char *start = authors.contents(); ++ *end = start + authors.length(); ++ return start; ++} ++ ++int reference::get_nauthors() const ++{ ++ if (nauthors < 0) { ++ const char *dummy; ++ int na; ++ for (na = 0; get_author(na, &dummy) != 0; na++) ++ ; ++ ((reference *)this)->nauthors = na; ++ } ++ return nauthors; ++} +diff -Nuar groff-1.22.3.old/src/preproc/refer/Makefile.sub groff-1.22.3/src/preproc/refer/Makefile.sub +--- groff-1.22.3.old/src/preproc/refer/Makefile.sub 2014-11-04 10:38:35.245523747 +0200 ++++ groff-1.22.3/src/preproc/refer/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,65 +0,0 @@ +-# Makefile.sub for `preproc refer' +-# +-# File position: /src/preproc/refer/Makefile.sub +-# +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=refer$(EXEEXT) +-MAN1=refer.n +-XLIBS=$(LIBBIB) $(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=\ +- command.$(OBJEXT) \ +- label.$(OBJEXT) \ +- ref.$(OBJEXT) \ +- refer.$(OBJEXT) \ +- token.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/command.cpp \ +- $(srcdir)/ref.cpp \ +- $(srcdir)/refer.cpp \ +- $(srcdir)/token.cpp +-HDRS=\ +- $(srcdir)/refer.h \ +- $(srcdir)/token.h \ +- $(srcdir)/command.h \ +- $(srcdir)/ref.h +-GRAM=$(srcdir)/label.y +-YTABC=label.cpp +-NAMEPREFIX=$(g) +- +-.PHONY: install_data +-install_data: refer +- -test -d $(DESTDIR)$(referdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(referdir) +- +-.PHONY: uninstall_data +-uninstall_sub: +- -test -d $(DESTDIR)$(referdir) && rmdir $(DESTDIR)$(referdir) +- +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/preproc/refer/refer.am groff-1.22.3/src/preproc/refer/refer.am +--- groff-1.22.3.old/src/preproc/refer/refer.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/refer/refer.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,44 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++prefixexecbin_PROGRAMS += refer ++refer_CPPFLAGS = $(AM_CPPFLAGS) -I $(top_srcdir)/src/preproc/refer ++refer_LDADD = libbib.a libgroff.a $(LIBM) ++refer_SOURCES = \ ++ src/preproc/refer/command.cpp \ ++ src/preproc/refer/ref.cpp \ ++ src/preproc/refer/refer.cpp \ ++ src/preproc/refer/token.cpp \ ++ src/preproc/refer/label.ypp \ ++ src/preproc/refer/refer.h \ ++ src/preproc/refer/ref.h \ ++ src/preproc/refer/token.h \ ++ src/preproc/refer/command.h ++PREFIXMAN1 += src/preproc/refer/refer.n ++EXTRA_DIST += src/preproc/refer/TODO src/preproc/refer/refer.man ++CLEANFILES += \ ++ src/preproc/refer/label.cpp \ ++ src/preproc/refer/label.hpp \ ++ src/preproc/refer/label.output ++# As refer_CPPFLAGS was set, all the .o have a 'refer-' prefix ++src/preproc/refer/refer-command.$(OBJEXT): defs.h ++src/preproc/refer/refer-ref.$(OBJEXT): defs.h ++src/preproc/refer/refer-refer.$(OBJEXT): defs.h ++src/preproc/refer/refer-token.$(OBJEXT): defs.h ++src/preproc/refer/refer-label.$(OBJEXT): defs.h ++ +diff -Nuar groff-1.22.3.old/src/preproc/refer/refer.cpp groff-1.22.3/src/preproc/refer/refer.cpp +--- groff-1.22.3.old/src/preproc/refer/refer.cpp 2014-11-04 10:38:35.245523747 +0200 ++++ groff-1.22.3/src/preproc/refer/refer.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -432,8 +432,11 @@ + return; + } + } +- current_filename = filename; +- fprintf(outfp, ".lf 1 %s\n", filename); ++ string fn(filename); ++ fn += '\0'; ++ normalize_for_lf(fn); ++ current_filename = fn.contents(); ++ fprintf(outfp, ".lf 1 %s\n", current_filename); + string line; + current_lineno = 0; + for (;;) { +diff -Nuar groff-1.22.3.old/src/preproc/refer/refer.h groff-1.22.3/src/preproc/refer/refer.h +--- groff-1.22.3.old/src/preproc/refer/refer.h 2014-11-04 10:38:35.245523747 +0200 ++++ groff-1.22.3/src/preproc/refer/refer.h 2015-04-23 20:57:03.000000000 +0300 +@@ -28,6 +28,7 @@ + #include "stringclass.h" + #include "cset.h" + #include "cmap.h" ++#include "lf.h" + + #include "defs.h" + +diff -Nuar groff-1.22.3.old/src/preproc/refer/refer.man groff-1.22.3/src/preproc/refer/refer.man +--- groff-1.22.3.old/src/preproc/refer/refer.man 2014-11-04 10:38:35.245523747 +0200 ++++ groff-1.22.3/src/preproc/refer/refer.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +diff -Nuar groff-1.22.3.old/src/preproc/soelim/.gitignore groff-1.22.3/src/preproc/soelim/.gitignore +--- groff-1.22.3.old/src/preproc/soelim/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/soelim/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++soelim ++soelim.n +diff -Nuar groff-1.22.3.old/src/preproc/soelim/Makefile.sub groff-1.22.3/src/preproc/soelim/Makefile.sub +--- groff-1.22.3.old/src/preproc/soelim/Makefile.sub 2014-11-04 10:38:35.250523684 +0200 ++++ groff-1.22.3/src/preproc/soelim/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,39 +0,0 @@ +-# Makefile.sub for `preproc soelim' +-# +-# File position: /src/preproc/soelim/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=soelim$(EXEEXT) +-MAN1=soelim.n +-XLIBS=$(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=soelim.$(OBJEXT) +-CCSRCS=$(srcdir)/soelim.cpp +-NAMEPREFIX=$(g) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/preproc/soelim/soelim.am groff-1.22.3/src/preproc/soelim/soelim.am +--- groff-1.22.3.old/src/preproc/soelim/soelim.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/soelim/soelim.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,25 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++prefixexecbin_PROGRAMS += soelim ++soelim_LDADD = libgroff.a $(LIBM) ++soelim_SOURCES = src/preproc/soelim/soelim.cpp ++PREFIXMAN1 += src/preproc/soelim/soelim.n ++EXTRA_DIST += \ ++ src/preproc/soelim/TODO \ ++ src/preproc/soelim/soelim.man +diff -Nuar groff-1.22.3.old/src/preproc/soelim/soelim.cpp groff-1.22.3/src/preproc/soelim/soelim.cpp +--- groff-1.22.3.old/src/preproc/soelim/soelim.cpp 2014-11-04 10:38:35.250523684 +0200 ++++ groff-1.22.3/src/preproc/soelim/soelim.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -28,6 +28,7 @@ + #include "stringclass.h" + #include "nonposix.h" + #include "searchpath.h" ++#include "lf.h" + + // The include search path initially contains only the current directory. + static search_path include_search_path(0, 0, 0, 1); +@@ -161,6 +162,7 @@ + error("can't open `%1': %2", whole_filename.contents(), strerror(err)); + return 0; + } ++ normalize_for_lf(whole_filename); + current_filename = whole_filename.contents(); + current_lineno = 1; + set_location(); +diff -Nuar groff-1.22.3.old/src/preproc/soelim/soelim.man groff-1.22.3/src/preproc/soelim/soelim.man +--- groff-1.22.3.old/src/preproc/soelim/soelim.man 2014-11-04 10:38:35.250523684 +0200 ++++ groff-1.22.3/src/preproc/soelim/soelim.man 2015-04-23 20:57:03.000000000 +0300 +@@ -5,6 +5,10 @@ + @g@soelim \- interpret .so requests in groff input + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" license (copying) + .de co + Copyright \[co] 1989-2014 Free Software Foundation, Inc. +@@ -275,6 +279,9 @@ + .co + . + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" mode: nroff + .\" End: +diff -Nuar groff-1.22.3.old/src/preproc/tbl/.gitignore groff-1.22.3/src/preproc/tbl/.gitignore +--- groff-1.22.3.old/src/preproc/tbl/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/tbl/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++tbl ++tbl.n +diff -Nuar groff-1.22.3.old/src/preproc/tbl/main.cpp groff-1.22.3/src/preproc/tbl/main.cpp +--- groff-1.22.3.old/src/preproc/tbl/main.cpp 2014-11-04 10:38:35.220524059 +0200 ++++ groff-1.22.3/src/preproc/tbl/main.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -1615,7 +1615,10 @@ + fatal("can't open `%1': %2", argv[i], strerror(errno)); + else { + current_lineno = 1; +- current_filename = argv[i]; ++ string fn(argv[i]); ++ fn += '\0'; ++ normalize_for_lf(fn); ++ current_filename = fn.contents(); + printf(".lf 1 %s\n", current_filename); + process_input_file(fp); + } +diff -Nuar groff-1.22.3.old/src/preproc/tbl/Makefile.sub groff-1.22.3/src/preproc/tbl/Makefile.sub +--- groff-1.22.3.old/src/preproc/tbl/Makefile.sub 2014-11-04 10:38:35.220524059 +0200 ++++ groff-1.22.3/src/preproc/tbl/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,45 +0,0 @@ +-# Makefile.sub for `preproc tbl' +-# +-# File position: /src/preproc/tbl/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=tbl$(EXEEXT) +-MAN1=tbl.n +-XLIBS=$(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=\ +- main.$(OBJEXT) \ +- table.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/main.cpp \ +- $(srcdir)/table.cpp +-HDRS=\ +- $(srcdir)/table.h +-NAMEPREFIX=$(g) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/preproc/tbl/table.cpp groff-1.22.3/src/preproc/tbl/table.cpp +--- groff-1.22.3.old/src/preproc/tbl/table.cpp 2014-11-04 10:38:35.221524047 +0200 ++++ groff-1.22.3/src/preproc/tbl/table.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -2966,7 +2966,10 @@ + && strcmp(fn, last_filename) == 0) + printfs(".lf %1\n", as_string(ln)); + else { +- printfs(".lf %1 %2\n", as_string(ln), fn); ++ string filename(fn); ++ filename += '\0'; ++ normalize_for_lf(filename); ++ printfs(".lf %1 %2\n", as_string(ln), filename.contents()); + last_filename = fn; + location_force_filename = 0; + } +diff -Nuar groff-1.22.3.old/src/preproc/tbl/table.h groff-1.22.3/src/preproc/tbl/table.h +--- groff-1.22.3.old/src/preproc/tbl/table.h 2014-11-04 10:38:35.221524047 +0200 ++++ groff-1.22.3/src/preproc/tbl/table.h 2015-04-23 20:57:03.000000000 +0300 +@@ -29,6 +29,7 @@ + #include "stringclass.h" + #include "errarg.h" + #include "error.h" ++#include "lf.h" + + // PREFIX and PREFIX_CHAR must be the same. + #define PREFIX "3" +diff -Nuar groff-1.22.3.old/src/preproc/tbl/tbl.am groff-1.22.3/src/preproc/tbl/tbl.am +--- groff-1.22.3.old/src/preproc/tbl/tbl.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/preproc/tbl/tbl.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,26 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++prefixexecbin_PROGRAMS += tbl ++tbl_LDADD = libgroff.a $(LIBM) ++tbl_SOURCES = \ ++ src/preproc/tbl/main.cpp \ ++ src/preproc/tbl/table.cpp \ ++ src/preproc/tbl/table.h ++PREFIXMAN1 += src/preproc/tbl/tbl.n ++EXTRA_DIST += src/preproc/tbl/tbl.man +diff -Nuar groff-1.22.3.old/src/preproc/tbl/tbl.man groff-1.22.3/src/preproc/tbl/tbl.man +--- groff-1.22.3.old/src/preproc/tbl/tbl.man 2014-11-04 10:38:35.221524047 +0200 ++++ groff-1.22.3/src/preproc/tbl/tbl.man 2015-04-23 20:57:03.000000000 +0300 +@@ -4,6 +4,10 @@ + @g@tbl \- format tables for troff + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" license + .de co + Copyright \[co] 1989-2014 Free Software Foundation, Inc. +@@ -1225,6 +1229,9 @@ + .co + . + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" mode: nroff + .\" End: +diff -Nuar groff-1.22.3.old/src/roff/groff/.gitignore groff-1.22.3/src/roff/groff/.gitignore +--- groff-1.22.3.old/src/roff/groff/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/roff/groff/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++groff ++groff.n +diff -Nuar groff-1.22.3.old/src/roff/groff/groff.am groff-1.22.3/src/roff/groff/groff.am +--- groff-1.22.3.old/src/roff/groff/groff.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/roff/groff/groff.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,60 @@ ++# Copyright (C) 1993-2014 ++# Free Software Foundation, Inc. ++# ++# Original Makefile.sub rewritten by ++# Bernd Warken ++# and Werner LEMBERG ++# ++# Automake migration by ++# Bertrand Garrigues ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++######################################################################## ++ ++bin_PROGRAMS += groff ++groff_LDADD = \ ++ libgroff.a \ ++ lib/libgnu.a \ ++ $(LIBM) ++groff_SOURCES = \ ++ src/roff/groff/groff.cpp \ ++ src/roff/groff/pipeline.c \ ++ src/roff/groff/pipeline.h ++src/roff/groff/groff.$(OBJEXT): defs.h ++man1_MANS += src/roff/groff/groff.n ++EXTRA_DIST += src/roff/groff/groff.man ++GROFF_OPTS_OUTPUT = \ ++ groff_opts_no_arg.txt \ ++ groff_opts_with_arg.txt ++groffoptsdir = $(libprogramdir) ++groffopts_DATA = $(GROFF_OPTS_OUTPUT) ++ ++MOSTLYCLEANFILES += groff_opts.tmp $(GROFF_OPTS_OUTPUT) ++ ++groff_opts.tmp: src/roff/groff/groff.cpp ++ @$(GREP) -e ':.*:.*:' $? | sed -e 's/[ \t",]//g' > $@ ++ @echo -n 'groff options: ' ++ @cat $@ ++ ++groff_opts_no_arg.txt: groff_opts.tmp ++ @sed -e 's/[a-zA-Z]://g' $? > $@ ++ @echo -n 'no arg: ' ++ @cat $@ ++ ++groff_opts_with_arg.txt: groff_opts_no_arg.txt ++ @rm -f $@ ++ @sed "s/[`cat $?`:]//g" groff_opts.tmp > $@ ++ @echo -n 'with arg: ' ++ @cat $@ +diff -Nuar groff-1.22.3.old/src/roff/groff/groff.cpp groff-1.22.3/src/roff/groff/groff.cpp +--- groff-1.22.3.old/src/roff/groff/groff.cpp 2014-11-04 10:38:35.195524372 +0200 ++++ groff-1.22.3/src/roff/groff/groff.cpp 2015-04-23 20:57:03.000000000 +0300 +@@ -701,7 +701,13 @@ + { + str += ' '; + int needs_quoting = 0; ++ // Native Windows programs don't support '..' style of quoting, so ++ // always behave as if ARG included the single quote character. ++#if defined(_WIN32) && !defined(__CYGWIN__) ++ int contains_single_quote = 1; ++#else + int contains_single_quote = 0; ++#endif + const char*p; + for (p = arg; *p != '\0'; p++) + switch (*p) { +@@ -731,10 +737,17 @@ + str += '"'; + for (p = arg; *p != '\0'; p++) + switch (*p) { ++#if !(defined(_WIN32) && !defined(__CYGWIN__)) + case '"': + case '\\': + case '$': + str += '\\'; ++#else ++ case '"': ++ case '\\': ++ if (*p == '"' || (*p == '\\' && p[1] == '"')) ++ str += '\\'; ++#endif + // fall through + default: + str += *p; +diff -Nuar groff-1.22.3.old/src/roff/groff/groff.man groff-1.22.3/src/roff/groff/groff.man +--- groff-1.22.3.old/src/roff/groff/groff.man 2014-11-04 10:38:35.195524372 +0200 ++++ groff-1.22.3/src/roff/groff/groff.man 2015-04-23 20:57:03.000000000 +0300 +@@ -5,6 +5,10 @@ + .\" groff.man -> groff.1 + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" Legal Terms + .\" -------------------------------------------------------------------- +@@ -2026,6 +2030,9 @@ + .au + . + . ++.cp \n[groff_C] ++. ++. + .\" -------------------------------------------------------------------- + .\" Emacs setup + .\" -------------------------------------------------------------------- +diff -Nuar groff-1.22.3.old/src/roff/groff/Makefile.sub groff-1.22.3/src/roff/groff/Makefile.sub +--- groff-1.22.3.old/src/roff/groff/Makefile.sub 2014-11-04 10:38:35.195524372 +0200 ++++ groff-1.22.3/src/roff/groff/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,82 +0,0 @@ +-# Makefile.sub for `src roff groff' +- +-# File position: /src/roff/groff/Makefile.sub +- +-# Copyright (C) 1993-2014 Free Software Foundation, Inc. +- +-# Rewritten by Bernd Warken and +-# Werner LEMBERG +- +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +- +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-######################################################################## +- +-PROG=groff$(EXEEXT) +-MAN1=groff.n +-XLIBS=$(LIBGROFF) $(LIBGNU) +-MLIB=$(LIBM) +-OBJS=groff.$(OBJEXT) pipeline.$(OBJEXT) +-CCSRCS=$(srcdir)/groff.cpp +-CSRCS=$(srcdir)/pipeline.c +-HDRS=$(srcdir)/pipeline.h +- +-GROFF_OPTS_OUTPUT=\ +- groff_opts_no_arg.txt \ +- groff_opts_with_arg.txt +- +-MOSTLYCLEANADD=groff_opts.tmp $(GROFF_OPTS_OUTPUT) +- +-RM=rm -f +- +-all: $(srcdir)/groff.cpp groff_opts.tmp $(GROFF_OPTS_OUTPUT) +- +-groff_opts.tmp: $(srcdir)/groff.cpp +- @$(GREP) -e ':.*:.*:' $? | sed -e 's/[ \t",]//g' > $@ +- @echo -n 'groff options: ' +- @cat $@ +- +-groff_opts_no_arg.txt: groff_opts.tmp +- @sed -e 's/[a-zA-Z]://g' $? > $@ +- @echo -n 'no arg: ' +- @cat $@ +- +-groff_opts_with_arg.txt: groff_opts_no_arg.txt +- @sed "s/[`cat $?`:]//g" groff_opts.tmp > $@ +- @echo -n 'with arg: ' +- @cat $@ +- +-install_data: $(GROFF_OPTS_OUTPUT) +- -test -d $(DESTDIR)$(libprogramdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(libprogramdir) +- for f in $(GROFF_OPTS_OUTPUT); do \ +- $(RM) $(DESTDIR)$(libprogramdir)/$$f; \ +- $(INSTALL_SCRIPT) $$f $(DESTDIR)$(libprogramdir); \ +- done +- +-uninstall_sub: +- -for f in $(GROFF_OPTS_OUTPUT); do \ +- $(RM) $(DESTDIR)$(libprogramdir)/$$f;\ +- done +-# XXX This will be removed by `uninstall_dirs' in `$(top_srcdir)/Makefile.in' +-# XXX (And only from there it is successful on an empty directory) +-# -d=$(DESTDIR)$(libprogramdir);\ +-# if test -d $$d; then rmdir $$d; fi +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/roff/grog/.gitignore groff-1.22.3/src/roff/grog/.gitignore +--- groff-1.22.3.old/src/roff/grog/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/roff/grog/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,2 @@ ++grog ++grog.n +diff -Nuar groff-1.22.3.old/src/roff/grog/grog.am groff-1.22.3/src/roff/grog/grog.am +--- groff-1.22.3.old/src/roff/grog/grog.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/roff/grog/grog.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,49 @@ ++# grog.am for `grog' ++# ++# File position: /src/roff/grog/grog.am ++# ++# Copyright (C) 1993-2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of `grog' which is part of `groff'. ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++grog_srcdir = $(top_srcdir)/src/roff/grog ++bin_SCRIPTS += grog ++GROG = src/roff/grog/subs.pl ++ ++# grog_dir is defined by a m4 macro ++grogdir = $(grog_dir) ++dist_grog_DATA = $(GROG) ++man1_MANS += src/roff/grog/grog.n ++EXTRA_DIST += \ ++ src/roff/grog/grog.man \ ++ src/roff/grog/grog.pl ++ ++# Perl version works for all parts of `groff'. ++ ++grog: $(grog_srcdir)/grog.pl $(GROG) $(SH_DEPS_SED_SCRIPT) ++ $(RM) $@ ++ sed -f "$(SH_DEPS_SED_SCRIPT)" \ ++ -e "1s|^\(#! \).*perl|\\1$(PERL)|" \ ++ -e "s|[@]g[@]|$(g)|g" \ ++ -e "s|[@]BINDIR[@]|$(DESTDIR)$(bindir)|g" \ ++ -e "s|[@]libdir[@]|$(DESTDIR)$(libdir)|g" \ ++ -e "s|[@]EGREP[@]|$(EGREP)|g" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|" \ ++ -e "s|[@]grog_dir[@]|$(grog_dir)|" \ ++ -e "$(SH_SCRIPT_SED_CMD)" \ ++ $(grog_srcdir)/grog.pl >$@ ++ chmod +x $@ +diff -Nuar groff-1.22.3.old/src/roff/grog/grog.man groff-1.22.3/src/roff/grog/grog.man +--- groff-1.22.3.old/src/roff/grog/grog.man 2014-11-04 10:38:35.522520284 +0200 ++++ groff-1.22.3/src/roff/grog/grog.man 2015-04-23 20:57:03.000000000 +0300 +@@ -12,7 +12,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + This file is part of grog, which is part of groff, a free software + project. You can redistribute it and/or modify it under the terms of +@@ -48,12 +48,12 @@ + .\" -------------------------------------------------------------------- + . + .\" Ellipsis ... +-.ie t .ds EL \fS\N'188'\fP +-.el .ds EL \&.\|.\|.\&\ ++.ie t .ds EL \fS\N'188'\fP\" ++.el .ds EL \&.\|.\|.\&\" + .\" called with \*(EL + . + .\" Bullet +-.ie t .ds BU \[bu] ++.ie t .ds BU \(bu + .el .ds BU * + .\" used in `.IP \*(BU 2m' (former .Topic) + . +@@ -513,12 +513,12 @@ + .RS + Man-pages of section 1 can be viewed with either + .RS +-\[Do] ++\(Do + .BI man " name" + .RE + for text mode or + .RS +-\[Do] ++\(Do + .BI groffer " name" + .RE + for graphical mode (default is PDF mode). +@@ -535,12 +535,12 @@ + .RS + Man-pages of section 7 can be viewed with either with + .RS +-\[Do] ++\(Do + .BI "man 7 " name + .RE + for text mode or + .RS +-\[Do] ++\(Do + .BI "groffer 7 " name + .RE + for graphical mode (default is PDF mode). +diff -Nuar groff-1.22.3.old/src/roff/grog/Makefile.sub groff-1.22.3/src/roff/grog/Makefile.sub +--- groff-1.22.3.old/src/roff/grog/Makefile.sub 2014-11-04 10:38:35.523520271 +0200 ++++ groff-1.22.3/src/roff/grog/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,79 +0,0 @@ +-# Makefile.sub for `grog' +- +-# File position: /src/roff/grog/Makefile.sub +- +-# Copyright (C) 1993-2014 Free Software Foundation, Inc. +- +-# This file is part of `grog' which is part of `groff'. +- +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +- +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +- +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +- +-######################################################################## +- +-MAN1=grog.n +-MOSTLYCLEANADD=grog $(MAN1) +- +-# not all make programs have $(RM) predefined. +-RM=rm -f +- +-all: grog $(MAN1) +- +-# lib .pl-files +-GROG=$(srcdir)/subs.pl +-GROG_=`echo $(GROG) | sed 's|$(srcdir)/||g'` +- +- +-# Perl version works for all parts of `groff'. +- +-grog: grog.pl $(GROG) $(SH_DEPS_SED_SCRIPT) +- $(RM) $@ +- sed -f "$(SH_DEPS_SED_SCRIPT)" \ +- -e "1s|^\(#! \).*perl|\\1$(PERL)|" \ +- -e "s|@g@|$(g)|g" \ +- -e "s|@BINDIR@|$(DESTDIR)$(bindir)|g" \ +- -e "s|@grog_dir@|$(DESTDIR)$(grog_dir)|g" \ +- -e "s|@EGREP@|$(EGREP)|g" \ +- -e "s|@VERSION@|$(version)$(revision)|" \ +- -e "$(SH_SCRIPT_SED_CMD)" \ +- $(srcdir)/grog.pl >$@ +- chmod +x $@ +- +-.PHONY: install_data +-install_data: grog +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/grog +- $(INSTALL_SCRIPT) grog $(DESTDIR)$(bindir)/grog +- -test -d $(DESTDIR)$(grog_dir) || $(mkinstalldirs) $(DESTDIR)$(grog_dir) +- for f in $(GROG_); do \ +- $(RM) $(DESTDIR)$(grog_dir)/$$f; \ +- $(INSTALL_SCRIPT) $(srcdir)/$$f $(DESTDIR)$(grog_dir)/$$f; \ +- done +- +-.PHONY: uninstall_data +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/grog +- -for f in $(GROG_); do \ +- $(RM) $(DESTDIR)$(grog_dir)/$$f; \ +- done +- -d=$(DESTDIR)$(grog_dir);\ +- if test -d $$d; then rmdir $$d; fi +- +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/roff/nroff/.gitignore groff-1.22.3/src/roff/nroff/.gitignore +--- groff-1.22.3.old/src/roff/nroff/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/roff/nroff/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,2 @@ ++nroff ++nroff.n +diff -Nuar groff-1.22.3.old/src/roff/nroff/Makefile.sub groff-1.22.3/src/roff/nroff/Makefile.sub +--- groff-1.22.3.old/src/roff/nroff/Makefile.sub 2014-11-04 10:38:35.526520234 +0200 ++++ groff-1.22.3/src/roff/nroff/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,53 +0,0 @@ +-# Makefile.sub for `src roff nroff' +-# +-# File position: /src/roff/nroff/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-MAN1=nroff.n +-NAMEPREFIX=$(g) +-MOSTLYCLEANADD=nroff +-RM=rm -f +- +-all: nroff +- +-nroff: nroff.sh $(SH_DEPS_SED_SCRIPT) +- $(RM) $@ +- sed -f $(SH_DEPS_SED_SCRIPT) \ +- -e $(SH_SCRIPT_SED_CMD) \ +- -e "s|@VERSION@|$(version)$(revision)|" $(srcdir)/nroff.sh >$@ +- chmod +x $@ +- +-install_data: nroff +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/$(NAMEPREFIX)nroff +- $(INSTALL_SCRIPT) nroff $(DESTDIR)$(bindir)/$(NAMEPREFIX)nroff +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/$(NAMEPREFIX)nroff +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/roff/nroff/nroff.am groff-1.22.3/src/roff/nroff/nroff.am +--- groff-1.22.3.old/src/roff/nroff/nroff.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/roff/nroff/nroff.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,31 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++prefixexecbin_SCRIPTS += nroff ++nroff_srcdir = $(top_srcdir)/src/roff/nroff ++PREFIXMAN1 += src/roff/nroff/nroff.n ++EXTRA_DIST += \ ++ src/roff/nroff/nroff.man \ ++ src/roff/nroff/nroff.sh ++ ++nroff: $(nroff_srcdir)/nroff.sh $(SH_DEPS_SED_SCRIPT) ++ rm -f $@ ++ sed -f $(SH_DEPS_SED_SCRIPT) \ ++ -e $(SH_SCRIPT_SED_CMD) \ ++ -e "s|[@]VERSION[@]|$(VERSION)|" $(nroff_srcdir)/nroff.sh >$@ ++ chmod +x $@ +diff -Nuar groff-1.22.3.old/src/roff/nroff/nroff.man groff-1.22.3/src/roff/nroff/nroff.man +--- groff-1.22.3.old/src/roff/nroff/nroff.man 2014-11-04 10:38:35.526520234 +0200 ++++ groff-1.22.3/src/roff/nroff/nroff.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -78,7 +78,7 @@ + .BR nroff + to select the output encoding emitted by + .BR grotty , +-groff\[aq]s TTY output device. ++groff\(aqs TTY output device. + . + If neither the + .B GROFF_TYPESETTER +@@ -108,7 +108,7 @@ + .B \-c + options + are equivalent to +-.BR grotty \[aq]s ++.BR grotty \(aqs + options + .B \-h + (using tabs in the output) and +@@ -168,7 +168,7 @@ + .B GROFF_TYPESETTER + The default device for + .BR groff . +-If not set (which is the normal case), it defaults to \[oq]ps\[cq]. ++If not set (which is the normal case), it defaults to \(oqps\(cq. + . + .TP + .SM +@@ -177,7 +177,7 @@ + .B groff + executable before searching in PATH. + . +-If unset, \[oq]@BINDIR@\[cq] is used. ++If unset, \(oq@BINDIR@\(cq is used. + . + . + .\" -------------------------------------------------------------------- +diff -Nuar groff-1.22.3.old/src/roff/troff/.gitignore groff-1.22.3/src/roff/troff/.gitignore +--- groff-1.22.3.old/src/roff/troff/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/roff/troff/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,4 @@ ++Makefile.dep ++majorminor.cpp ++troff ++troff.n +diff -Nuar groff-1.22.3.old/src/roff/troff/Makefile.sub groff-1.22.3/src/roff/troff/Makefile.sub +--- groff-1.22.3.old/src/roff/troff/Makefile.sub 2014-11-04 10:38:35.203524272 +0200 ++++ groff-1.22.3/src/roff/troff/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,82 +0,0 @@ +-# Makefile.sub for `src roff troff' +-# +-# File position: /src/roff/troff/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=troff$(EXEEXT) +-MAN1=troff.n +-XLIBS=$(LIBGROFF) $(LIBGNU) +-MLIB=$(LIBM) +-OBJS=\ +- dictionary.$(OBJEXT) \ +- div.$(OBJEXT) \ +- env.$(OBJEXT) \ +- input.$(OBJEXT) \ +- majorminor.$(OBJEXT) \ +- mtsm.$(OBJEXT) \ +- node.$(OBJEXT) \ +- number.$(OBJEXT) \ +- reg.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/dictionary.cpp \ +- $(srcdir)/div.cpp \ +- $(srcdir)/env.cpp \ +- $(srcdir)/input.cpp \ +- majorminor.cpp \ +- $(srcdir)/mtsm.cpp \ +- $(srcdir)/node.cpp \ +- $(srcdir)/number.cpp \ +- $(srcdir)/reg.cpp +-HDRS=\ +- $(srcdir)/charinfo.h \ +- $(srcdir)/dictionary.h \ +- $(srcdir)/div.h \ +- $(srcdir)/env.h \ +- $(srcdir)/hvunits.h \ +- $(srcdir)/input.h \ +- $(srcdir)/mtsm.h \ +- $(srcdir)/node.h \ +- $(srcdir)/reg.h \ +- $(srcdir)/request.h \ +- $(srcdir)/token.h \ +- $(srcdir)/troff.h +-GENSRCS=majorminor.cpp +-NAMEPREFIX=$(g) +-RM=rm -f +- +-majorminor.cpp: $(top_srcdir)/VERSION $(top_srcdir)/REVISION +- @echo Making $@ +- @$(RM) $@ +- @echo const char \*major_version = \ +- \"`sed -e 's/^\([^.]*\)\..*$$/\1/' $(top_srcdir)/VERSION`\"\; >$@ +- @echo const char \*minor_version = \ +- \"`sed -e 's/^[^.]*\.\([0-9]*\).*$$/\1/' $(top_srcdir)/VERSION`\"\; \ +- >>$@ +- @echo const char \*revision = \"`cat $(top_srcdir)/REVISION`\"\; >>$@ +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/roff/troff/troff.am groff-1.22.3/src/roff/troff/troff.am +--- groff-1.22.3.old/src/roff/troff/troff.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/roff/troff/troff.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,61 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++prefixexecbin_PROGRAMS += troff ++PREFIXMAN1 += src/roff/troff/troff.n ++EXTRA_DIST += \ ++ src/roff/troff/column.cpp \ ++ src/roff/troff/troff.man \ ++ src/roff/troff/TODO ++troff_LDADD = libgroff.a lib/libgnu.a $(LIBM) ++troff_SOURCES = \ ++ src/roff/troff/dictionary.cpp \ ++ src/roff/troff/div.cpp \ ++ src/roff/troff/env.cpp \ ++ src/roff/troff/input.cpp \ ++ src/roff/troff/mtsm.cpp \ ++ src/roff/troff/node.cpp \ ++ src/roff/troff/number.cpp \ ++ src/roff/troff/reg.cpp \ ++ src/roff/troff/env.h \ ++ src/roff/troff/node.h \ ++ src/roff/troff/troff.h \ ++ src/roff/troff/div.h \ ++ src/roff/troff/reg.h \ ++ src/roff/troff/dictionary.h \ ++ src/roff/troff/input.h \ ++ src/roff/troff/mtsm.h \ ++ src/roff/troff/token.h \ ++ src/roff/troff/charinfo.h \ ++ src/roff/troff/request.h \ ++ src/roff/troff/hvunits.h ++ ++nodist_troff_SOURCES = src/roff/troff/majorminor.cpp ++ ++src/roff/troff/input.$(OBJEXT): defs.h ++CLEANFILES += src/roff/troff/majorminor.cpp ++ ++src/roff/troff/majorminor.cpp: $(top_srcdir)/VERSION $(top_srcdir)/REVISION ++ @echo Making $@ ++ @$(RM) $@ ++ @echo const char \*major_version = \ ++ \"`sed -e 's/^\([^.]*\)\..*$$/\1/' $(top_srcdir)/VERSION`\"\; >$@ ++ @echo const char \*minor_version = \ ++ \"`sed -e 's/^[^.]*\.\([0-9]*\).*$$/\1/' $(top_srcdir)/VERSION`\"\; \ ++ >>$@ ++ @echo const char \*revision = \"`cat $(top_srcdir)/REVISION`\"\; >>$@ +diff -Nuar groff-1.22.3.old/src/roff/troff/troff.man groff-1.22.3/src/roff/troff/troff.man +--- groff-1.22.3.old/src/roff/troff/troff.man 2014-11-04 10:38:35.204524259 +0200 ++++ groff-1.22.3/src/roff/troff/troff.man 2015-04-23 20:57:03.000000000 +0300 +@@ -11,7 +11,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + This file is part of groff, the GNU roff type-setting system, which + is a GNU free software project.. +@@ -98,7 +98,7 @@ + This backtrace should help track down the cause of the error. + . + The line numbers given in the backtrace may not always be correct, for +-.BR @g@troff \[aq]s ++.BR @g@troff \(aqs + idea of line numbers gets confused by + .B as + or +@@ -131,7 +131,7 @@ + Inhibit all error messages of + .BR @g@troff . + . +-Note that this doesn\[aq]t affect messages output to standard error by ++Note that this doesn\(aqt affect messages output to standard error by + macro packages using the + .B tm + or +@@ -188,7 +188,7 @@ + Read in the file + .IB name .tmac\fR. + . +-If it isn\[aq]t found, try ++If it isn\(aqt found, try + .BI tmac. name + instead. + . +@@ -253,7 +253,7 @@ + . + .TP + .B \-R +-Don\[aq]t load ++Don\(aqt load + .B troffrc + and + .BR troffrc-end . +@@ -467,7 +467,7 @@ + .TP + .BR right-brace "\t4096" + Use of +-.B \[rs]} ++.B \(rs} + where a number was expected. + . + .TP +diff -Nuar groff-1.22.3.old/src/utils/addftinfo/addftinfo.am groff-1.22.3/src/utils/addftinfo/addftinfo.am +--- groff-1.22.3.old/src/utils/addftinfo/addftinfo.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/addftinfo/addftinfo.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,30 @@ ++# Automake rules for `src utils addftinfo' ++# ++# File position: /src/utils/addftinfo/addftinfo.am ++# ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see ++# . ++# ++######################################################################## ++ ++bin_PROGRAMS += addftinfo ++man1_MANS += src/utils/addftinfo/addftinfo.n ++EXTRA_DIST += src/utils/addftinfo/addftinfo.man ++addftinfo_LDADD = libgroff.a ++addftinfo_SOURCES = \ ++ src/utils/addftinfo/addftinfo.cpp \ ++ src/utils/addftinfo/guess.cpp \ ++ src/utils/addftinfo/guess.h +diff -Nuar groff-1.22.3.old/src/utils/addftinfo/addftinfo.man groff-1.22.3/src/utils/addftinfo/addftinfo.man +--- groff-1.22.3.old/src/utils/addftinfo/addftinfo.man 2014-11-04 10:38:35.310522934 +0200 ++++ groff-1.22.3/src/utils/addftinfo/addftinfo.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -31,8 +31,8 @@ + .\" -------------------------------------------------------------------- + . + .\" Ellipsis ... +-.ie t .ds EL \fS\N'188'\fP +-.el .ds EL \&.\|.\|.\&\ ++.ie t .ds EL \fS\N'188'\fP\" ++.el .ds EL \&.\|.\|.\&\" + .\" called with \*(EL + . + . +@@ -88,7 +88,7 @@ + .SH OPTIONS + .\" -------------------------------------------------------------------- + . +-.B \[en]v ++.B \-v + prints the version number. + . + . +@@ -107,35 +107,35 @@ + must be one of: + . + .TP +-.B \[en]x\-height ++.B \-x\-height + The height of lowercase letters without ascenders such as x. + . + .TP +-.B \[en]fig-height ++.B \-fig\-height + The height of figures (digits). + . + .TP +-.B \[en]asc-height ++.B \-asc\-height + The height of characters with ascenders, such as b, d or l. + . + .TP +-.B \[en]body\-height ++.B \-body\-height + The height of characters such as parentheses. + . + .TP +-.B \[en]cap-height ++.B \-cap\-height + The height of uppercase letters such as A. + . + .TP +-.B \[en]comma\-depth ++.B \-comma\-depth + The depth of a comma. + . + .TP +-.B \[en]desc\-depth ++.B \-desc\-depth + The depth of characters with descenders, such as p, q, or y. + . + .TP +-.B \[en]body\-depth ++.B \-body\-depth + The depth of characters such as parentheses. + . + . +diff -Nuar groff-1.22.3.old/src/utils/addftinfo/.gitignore groff-1.22.3/src/utils/addftinfo/.gitignore +--- groff-1.22.3.old/src/utils/addftinfo/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/addftinfo/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++addftinfo ++addftinfo.n +diff -Nuar groff-1.22.3.old/src/utils/addftinfo/Makefile.sub groff-1.22.3/src/utils/addftinfo/Makefile.sub +--- groff-1.22.3.old/src/utils/addftinfo/Makefile.sub 2014-11-04 10:38:35.310522934 +0200 ++++ groff-1.22.3/src/utils/addftinfo/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,43 +0,0 @@ +-# Makefile.sub for `src utils addftinfo' +-# +-# File position: /src/utils/addftinfo/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=addftinfo$(EXEEXT) +-MAN1=addftinfo.n +-XLIBS=$(LIBGROFF) +-OBJS=\ +- addftinfo.$(OBJEXT) \ +- guess.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/addftinfo.cpp \ +- $(srcdir)/guess.cpp +-HDRS=\ +- $(srcdir)/guess.h +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/utils/afmtodit/afmtodit.am groff-1.22.3/src/utils/afmtodit/afmtodit.am +--- groff-1.22.3.old/src/utils/afmtodit/afmtodit.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/afmtodit/afmtodit.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,49 @@ ++# Automake rules for `src utils afmtodit' ++# ++# File position: /src/utils/afmtodit/afmtdodit.am ++# ++# Copyright (C) 2013-2014 Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# ++######################################################################## ++ ++afmtodit_srcdir = $(top_srcdir)/src/utils/afmtodit ++ ++bin_SCRIPTS += afmtodit ++man1_MANS += src/utils/afmtodit/afmtodit.n ++EXTRA_DIST += \ ++ src/utils/afmtodit/afmtodit.man \ ++ src/utils/afmtodit/afmtodit.pl \ ++ src/utils/afmtodit/afmtodit.tables \ ++ src/utils/afmtodit/make-afmtodit-tables ++ ++afmtodit: $(afmtodit_srcdir)/afmtodit.pl $(afmtodit_srcdir)/afmtodit.tables ++ if test -n "$(PERL)"; then \ ++ sed -e "s|/usr/bin/perl|$(PERL)|" \ ++ -e "s|[@]VERSION[@]|$(VERSION)|" \ ++ -e "s|[@]FONTDIR[@]|$(fontdir)|" \ ++ -e "/[@]afmtodit.tables[@]/ r $(afmtodit_srcdir)/afmtodit.tables" \ ++ -e "/[@]afmtodit.tables[@]/ d" \ ++ $(afmtodit_srcdir)/afmtodit.pl >afmtodit; \ ++ else \ ++ sed -e "s|[@]VERSION[@]|$(VERSION)|" \ ++ -e "s|[@]FONTDIR[@]|$(fontdir)|" \ ++ -e "/[@]afmtodit.tables[@]/ r $(afmtodit_srcdir)/afmtodit.tables" \ ++ -e "/[@]afmtodit.tables[@]/ d" \ ++ $(afmtodit_srcdir)/afmtodit.pl >afmtodit; \ ++ fi ++ chmod +x afmtodit +diff -Nuar groff-1.22.3.old/src/utils/afmtodit/afmtodit.man groff-1.22.3/src/utils/afmtodit/afmtodit.man +--- groff-1.22.3.old/src/utils/afmtodit/afmtodit.man 2014-11-04 10:38:35.421521547 +0200 ++++ groff-1.22.3/src/utils/afmtodit/afmtodit.man 2015-04-23 20:57:03.000000000 +0300 +@@ -7,7 +7,7 @@ + .\" Leagal Terms + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -115,8 +115,8 @@ + .B # + and blank lines are ignored. + . +-If the file isn\[aq]t found in the current directory, it is searched +-in the \[oq]devps/generate\[cq] subdirectory of the default font ++If the file isn\(aqt found in the current directory, it is searched ++in the \(oqdevps/generate\(cq subdirectory of the default font + directory. + . + . +@@ -134,7 +134,7 @@ + escape sequence in + .BR troff . + . +-In particular, this is true for glyph variants like \[oq]foo.bar\[cq]; ++In particular, this is true for glyph variants like \(oqfoo.bar\(cq; + all glyph names containing one or more periods are mapped to unnamed + entities. + . +@@ -143,7 +143,7 @@ + is not specified, the encoding defined in the AFM file (i.e., entries + with non-negative character codes) is used. + . +-Please refer to section \[oq]Using Symbols\[cq] in the groff info file ++Please refer to section \(oqUsing Symbols\(cq in the groff info file + which describes how groff glyph names are constructed. + . + . +@@ -154,7 +154,7 @@ + code used in the AFM file in the unlikely case that it is greater than + 255) in the groff font file. + . +-Glyph indices of unencoded characters don\[aq]t have a specific order; ++Glyph indices of unencoded characters don\(aqt have a specific order; + it is best to access them with glyph names only. + . + . +@@ -239,7 +239,7 @@ + rather than the default + .BR DESC . + . +-If not found in the current directory, the \[oq]devps\[qc] ++If not found in the current directory, the \(oqdevps\(cq + subdirectory of the default font directory is searched (this is true + for both the default device description file and a file given with + option +@@ -255,7 +255,7 @@ + is described in + .BR grops (@MAN1EXT@). + . +-If not found in the current directory, the \[oq]devps\[cq] ++If not found in the current directory, the \(oqdevps\(cq + subdirectory of the default font directory is searched. + . + .TP +@@ -270,7 +270,7 @@ + .I n + thousandths of an em + plus the amount by which the right edge of the character's bounding box +-is to the right of the character\[aq]s origin. ++is to the right of the character\(aqs origin. + . + If this would result in a negative italic correction, use a zero + italic correction instead. +@@ -290,7 +290,7 @@ + .I n + thousandths of an em + plus the amount by which the left edge of the character's bounding box +-is to the left of the character\[aq]s origin. ++is to the left of the character\(aqs origin. + . + The left italic correction may be negative unless option + .B \-m +@@ -387,7 +387,7 @@ + . + . + .LP +-The groff info file, section \[oq]Using Symbols\[cq]. ++The groff info file, section \(oqUsing Symbols\(cq. + . + . + .\" -------------------------------------------------------------------- +diff -Nuar groff-1.22.3.old/src/utils/afmtodit/.gitignore groff-1.22.3/src/utils/afmtodit/.gitignore +--- groff-1.22.3.old/src/utils/afmtodit/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/afmtodit/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,2 @@ ++afmtodit ++afmtodit.n +diff -Nuar groff-1.22.3.old/src/utils/afmtodit/Makefile.sub groff-1.22.3/src/utils/afmtodit/Makefile.sub +--- groff-1.22.3.old/src/utils/afmtodit/Makefile.sub 2014-11-04 10:38:35.422521534 +0200 ++++ groff-1.22.3/src/utils/afmtodit/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,61 +0,0 @@ +-# Makefile.sub for `src utils afmtodit' +-# +-# File position: /src/utils/afmtodit/Makefile.sub +-# +-# Copyright (C) 2013-2014 Free Software Foundation, Inc. +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-######################################################################## +- +-MAN1=afmtodit.n +-MOSTLYCLEANADD=afmtodit +-RM=rm -f +- +-all: afmtodit +- +-afmtodit: afmtodit.pl afmtodit.tables +- if test -n "$(PERL)"; then \ +- sed -e "s|/usr/bin/perl|$(PERL)|" \ +- -e "s|@VERSION@|$(version)$(revision)|" \ +- -e "s|@FONTDIR@|$(fontdir)|" \ +- -e "/@afmtodit.tables@/ r $(srcdir)/afmtodit.tables" \ +- -e "/@afmtodit.tables@/ d" \ +- $(srcdir)/afmtodit.pl >afmtodit; \ +- else \ +- sed -e "s|@VERSION@|$(version)$(revision)|" \ +- -e "s|@FONTDIR@|$(fontdir)|" \ +- -e "/@afmtodit.tables@/ r $(srcdir)/afmtodit.tables" \ +- -e "/@afmtodit.tables@/ d" \ +- $(srcdir)/afmtodit.pl >afmtodit; \ +- fi +- chmod +x afmtodit +- +-install_data: afmtodit +- -test -d $(DESTDIR)$(bindir) || $(mkinstalldirs) $(DESTDIR)$(bindir) +- $(RM) $(DESTDIR)$(bindir)/afmtodit +- $(INSTALL_SCRIPT) afmtodit $(DESTDIR)$(bindir)/afmtodit +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(bindir)/afmtodit +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/utils/hpftodit/.gitignore groff-1.22.3/src/utils/hpftodit/.gitignore +--- groff-1.22.3.old/src/utils/hpftodit/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/hpftodit/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++hpftodit ++hpftodit.n +diff -Nuar groff-1.22.3.old/src/utils/hpftodit/hpftodit.am groff-1.22.3/src/utils/hpftodit/hpftodit.am +--- groff-1.22.3.old/src/utils/hpftodit/hpftodit.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/hpftodit/hpftodit.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,29 @@ ++# Automake rules for `src utils hpftodit' ++# ++# File position: /src/utils/hpftodit/hpftodit.am ++# ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# ++# `groff' is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 2 of the License, or ++# (at your option) any later version. ++# ++# `groff' is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see ++# . ++# ++######################################################################## ++ ++bin_PROGRAMS += hpftodit ++man1_MANS += src/utils/hpftodit/hpftodit.n ++EXTRA_DIST += src/utils/hpftodit/hpftodit.man ++hpftodit_LDADD = libgroff.a $(LIBM) ++hpftodit_SOURCES = \ ++ src/utils/hpftodit/hpftodit.cpp \ ++ src/utils/hpftodit/hpuni.cpp +diff -Nuar groff-1.22.3.old/src/utils/hpftodit/hpftodit.man groff-1.22.3/src/utils/hpftodit/hpftodit.man +--- groff-1.22.3.old/src/utils/hpftodit/hpftodit.man 2014-11-04 10:38:35.293523147 +0200 ++++ groff-1.22.3/src/utils/hpftodit/hpftodit.man 2015-04-23 20:57:03.000000000 +0300 +@@ -4,6 +4,10 @@ + hpftodit \- create font description files for use with groff \-Tlj4 + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" Legal Terms + .\" -------------------------------------------------------------------- +@@ -380,6 +384,9 @@ + .co + . + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" mode: nroff + .\" End: +diff -Nuar groff-1.22.3.old/src/utils/hpftodit/Makefile.sub groff-1.22.3/src/utils/hpftodit/Makefile.sub +--- groff-1.22.3.old/src/utils/hpftodit/Makefile.sub 2014-11-04 10:38:35.293523147 +0200 ++++ groff-1.22.3/src/utils/hpftodit/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,40 +0,0 @@ +-# Makefile.sub for `src utils hpftodit' +-# +-# File position: /src/utils/hpftodit/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=hpftodit$(EXEEXT) +-MAN1=hpftodit.n +-XLIBS=$(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=hpftodit.$(OBJEXT) \ +- hpuni.$(OBJEXT) +-CCSRCS=$(srcdir)/hpftodit.cpp \ +- $(srcdir)/hpuni.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/utils/indxbib/.gitignore groff-1.22.3/src/utils/indxbib/.gitignore +--- groff-1.22.3.old/src/utils/indxbib/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/indxbib/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++indxbib ++indxbib.n +diff -Nuar groff-1.22.3.old/src/utils/indxbib/indxbib.am groff-1.22.3/src/utils/indxbib/indxbib.am +--- groff-1.22.3.old/src/utils/indxbib/indxbib.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/indxbib/indxbib.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,51 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++indxbib_srcdir = $(top_srcdir)/src/utils/indxbib ++prefixexecbin_PROGRAMS += indxbib ++indxbib_SOURCES = \ ++ src/utils/indxbib/indxbib.cpp \ ++ src/utils/indxbib/signal.c ++src/utils/indxbib/indxbib.$(OBJEXT): defs.h ++indxbib_LDADD = libbib.a libgroff.a $(LIBM) ++PREFIXMAN1 += src/utils/indxbib/indxbib.n ++EXTRA_DIST += \ ++ src/utils/indxbib/indxbib.man \ ++ src/utils/indxbib/eign ++ ++install-data-local: install_indxbib ++install_indxbib: $(indxbib_srcdir)/eign ++ -test -d $(DESTDIR)$(datadir) \ ++ || $(mkinstalldirs) $(DESTDIR)$(datadir) ++ -test -d $(DESTDIR)$(dataprogramdir) \ ++ || $(mkinstalldirs) $(DESTDIR)$(dataprogramdir) ++ -test -d $(DESTDIR)$(datasubdir) \ ++ || $(mkinstalldirs) $(DESTDIR)$(datasubdir) ++ if test -f /usr/lib/eign; then \ ++ rm -f $(DESTDIR)$(common_words_file); \ ++ ln -s /usr/lib/eign $(DESTDIR)$(common_words_file) 2>/dev/null \ ++ || ln /usr/lib/eign $(DESTDIR)$(common_words_file) 2>/dev/null \ ++ || cp /usr/lib/eign $(DESTDIR)$(common_words_file); \ ++ else \ ++ rm -f $(DESTDIR)$(common_words_file); \ ++ $(INSTALL_DATA) $(indxbib_srcdir)/eign $(DESTDIR)$(common_words_file); \ ++ fi ++ ++uninstall-local: uninstall_indxbib ++uninstall_indxbib: ++ rm -f $(DESTDIR)$(common_words_file) +diff -Nuar groff-1.22.3.old/src/utils/indxbib/indxbib.man groff-1.22.3/src/utils/indxbib/indxbib.man +--- groff-1.22.3.old/src/utils/indxbib/indxbib.man 2014-11-04 10:38:35.301523047 +0200 ++++ groff-1.22.3/src/utils/indxbib/indxbib.man 2015-04-23 20:57:03.000000000 +0300 +@@ -4,7 +4,7 @@ + . + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -167,7 +167,7 @@ + . + .TP + .BI \-i string +-Don\[aq]t index the contents of fields whose names are in ++Don\(aqt index the contents of fields whose names are in + .IR string . + . + Initially +diff -Nuar groff-1.22.3.old/src/utils/indxbib/Makefile.sub groff-1.22.3/src/utils/indxbib/Makefile.sub +--- groff-1.22.3.old/src/utils/indxbib/Makefile.sub 2014-11-04 10:38:35.301523047 +0200 ++++ groff-1.22.3/src/utils/indxbib/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,65 +0,0 @@ +-# Makefile.sub for `src utils indxbib' +-# +-# File position: /src/utils/indxbib/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=indxbib$(EXEEXT) +-MAN1=indxbib.n +-XLIBS=$(LIBBIB) $(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=\ +- indxbib.$(OBJEXT) \ +- signal.$(OBJEXT) +-CCSRCS=\ +- $(srcdir)/indxbib.cpp +-CSRCS=\ +- $(srcdir)/signal.c +-NAMEPREFIX=$(g) +-RM=rm -f +- +-install_data: $(srcdir)/eign +- -test -d $(DESTDIR)$(datadir) \ +- || $(mkinstalldirs) $(DESTDIR)$(datadir) +- -test -d $(DESTDIR)$(dataprogramdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(dataprogramdir) +- -test -d $(DESTDIR)$(datasubdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(datasubdir) +- if test -f /usr/lib/eign; then \ +- $(MK) $(DESTDIR)$(common_words_file); \ +- ln -s /usr/lib/eign $(DESTDIR)$(common_words_file) 2>/dev/null \ +- || ln /usr/lib/eign $(DESTDIR)$(common_words_file) 2>/dev/null \ +- || cp /usr/lib/eign $(DESTDIR)$(common_words_file); \ +- else \ +- $(RM) $(DESTDIR)$(common_words_file); \ +- $(INSTALL_DATA) $(srcdir)/eign $(DESTDIR)$(common_words_file); \ +- fi +- +-uninstall_sub: +- $(RM) $(DESTDIR)$(common_words_file) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/utils/lkbib/.gitignore groff-1.22.3/src/utils/lkbib/.gitignore +--- groff-1.22.3.old/src/utils/lkbib/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/lkbib/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++lkbib ++lkbib.n +diff -Nuar groff-1.22.3.old/src/utils/lkbib/lkbib.am groff-1.22.3/src/utils/lkbib/lkbib.am +--- groff-1.22.3.old/src/utils/lkbib/lkbib.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/lkbib/lkbib.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,24 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += lkbib ++man1_MANS += src/utils/lkbib/lkbib.n ++EXTRA_DIST += src/utils/lkbib/lkbib.man ++lkbib_LDADD = libbib.a libgroff.a $(LIBM) ++lkbib_SOURCES = src/utils/lkbib/lkbib.cpp ++src/utils/lkbib/lkbib.$(OBJEXT): defs.h +diff -Nuar groff-1.22.3.old/src/utils/lkbib/lkbib.man groff-1.22.3/src/utils/lkbib/lkbib.man +--- groff-1.22.3.old/src/utils/lkbib/lkbib.man 2014-11-04 10:38:35.305522997 +0200 ++++ groff-1.22.3/src/utils/lkbib/lkbib.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +diff -Nuar groff-1.22.3.old/src/utils/lkbib/Makefile.sub groff-1.22.3/src/utils/lkbib/Makefile.sub +--- groff-1.22.3.old/src/utils/lkbib/Makefile.sub 2014-11-04 10:38:35.305522997 +0200 ++++ groff-1.22.3/src/utils/lkbib/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,38 +0,0 @@ +-# Makefile.sub for `src utils lkbib' +-# +-# File position: /src/utils/lkbib/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=lkbib$(EXEEXT) +-MAN1=lkbib.n +-XLIBS=$(LIBBIB) $(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=lkbib.$(OBJEXT) +-CCSRCS=$(srcdir)/lkbib.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/utils/lookbib/.gitignore groff-1.22.3/src/utils/lookbib/.gitignore +--- groff-1.22.3.old/src/utils/lookbib/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/lookbib/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++lookbib ++lookbib.n +diff -Nuar groff-1.22.3.old/src/utils/lookbib/lookbib.am groff-1.22.3/src/utils/lookbib/lookbib.am +--- groff-1.22.3.old/src/utils/lookbib/lookbib.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/lookbib/lookbib.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,23 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++prefixexecbin_PROGRAMS += lookbib ++PREFIXMAN1 += src/utils/lookbib/lookbib.n ++EXTRA_DIST += src/utils/lookbib/lookbib.man ++lookbib_LDADD = libbib.a libgroff.a $(LIBM) ++lookbib_SOURCES = src/utils/lookbib/lookbib.cpp +diff -Nuar groff-1.22.3.old/src/utils/lookbib/lookbib.man groff-1.22.3/src/utils/lookbib/lookbib.man +--- groff-1.22.3.old/src/utils/lookbib/lookbib.man 2014-11-04 10:38:35.297523097 +0200 ++++ groff-1.22.3/src/utils/lookbib/lookbib.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +diff -Nuar groff-1.22.3.old/src/utils/lookbib/Makefile.sub groff-1.22.3/src/utils/lookbib/Makefile.sub +--- groff-1.22.3.old/src/utils/lookbib/Makefile.sub 2014-11-04 10:38:35.297523097 +0200 ++++ groff-1.22.3/src/utils/lookbib/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,39 +0,0 @@ +-# Makefile.sub for `src utils lookbib' +-# +-# File position: /src/utils/lookbib/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=lookbib$(EXEEXT) +-MAN1=lookbib.n +-XLIBS=$(LIBBIB) $(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=lookbib.$(OBJEXT) +-CCSRCS=$(srcdir)/lookbib.cpp +-NAMEPREFIX=$(g) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/utils/pfbtops/.gitignore groff-1.22.3/src/utils/pfbtops/.gitignore +--- groff-1.22.3.old/src/utils/pfbtops/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/pfbtops/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++pfbtops ++pfbtops.n +diff -Nuar groff-1.22.3.old/src/utils/pfbtops/Makefile.sub groff-1.22.3/src/utils/pfbtops/Makefile.sub +--- groff-1.22.3.old/src/utils/pfbtops/Makefile.sub 2014-11-04 10:38:35.314522884 +0200 ++++ groff-1.22.3/src/utils/pfbtops/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,39 +0,0 @@ +-# Makefile.sub for `src utils pfbtops' +-# +-# File position: /src/utils/pfbtops/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=pfbtops$(EXEEXT) +-MAN1=pfbtops.n +-OBJS=pfbtops.$(OBJEXT) +-CSRCS=$(srcdir)/pfbtops.c +-XLIBS=$(LIBGROFF) +-MLIB=$(LIBM) +-LINK.c=$(CCC) $(CCFLAGS) $(LDFLAGS) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/utils/pfbtops/pfbtops.am groff-1.22.3/src/utils/pfbtops/pfbtops.am +--- groff-1.22.3.old/src/utils/pfbtops/pfbtops.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/pfbtops/pfbtops.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,26 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += pfbtops ++man1_MANS += src/utils/pfbtops/pfbtops.n ++EXTRA_DIST += src/utils/pfbtops/pfbtops.man ++pfbtops_SOURCES = src/utils/pfbtops/pfbtops.c ++pfbtops_LDADD = libgroff.a $(LIBM) ++# We use the following trick to force the use of C++ compiler ++# See the Automake manual, "Libtool Convenience Libraries" ++nodist_EXTRA_pfbtops_SOURCES = src/utils/pfbtops/dummy.cpp +diff -Nuar groff-1.22.3.old/src/utils/pfbtops/pfbtops.man groff-1.22.3/src/utils/pfbtops/pfbtops.man +--- groff-1.22.3.old/src/utils/pfbtops/pfbtops.man 2014-11-04 10:38:35.314522884 +0200 ++++ groff-1.22.3/src/utils/pfbtops/pfbtops.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +diff -Nuar groff-1.22.3.old/src/utils/tfmtodit/.gitignore groff-1.22.3/src/utils/tfmtodit/.gitignore +--- groff-1.22.3.old/src/utils/tfmtodit/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/tfmtodit/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,3 @@ ++Makefile.dep ++tfmtodit ++tfmtodit.n +diff -Nuar groff-1.22.3.old/src/utils/tfmtodit/Makefile.sub groff-1.22.3/src/utils/tfmtodit/Makefile.sub +--- groff-1.22.3.old/src/utils/tfmtodit/Makefile.sub 2014-11-04 10:38:35.288523209 +0200 ++++ groff-1.22.3/src/utils/tfmtodit/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,38 +0,0 @@ +-# Makefile.sub for `src utils tfmtodit' +-# +-# File position: /src/utils/tfmtodit/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=tfmtodit$(EXEEXT) +-MAN1=tfmtodit.n +-XLIBS=$(LIBGROFF) +-MLIB=$(LIBM) +-OBJS=tfmtodit.$(OBJEXT) +-CCSRCS=$(srcdir)/tfmtodit.cpp +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/utils/tfmtodit/tfmtodit.am groff-1.22.3/src/utils/tfmtodit/tfmtodit.am +--- groff-1.22.3.old/src/utils/tfmtodit/tfmtodit.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/tfmtodit/tfmtodit.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,23 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++bin_PROGRAMS += tfmtodit ++man1_MANS += src/utils/tfmtodit/tfmtodit.n ++EXTRA_DIST += src/utils/tfmtodit/tfmtodit.man ++tfmtodit_SOURCES = src/utils/tfmtodit/tfmtodit.cpp ++tfmtodit_LDADD = libgroff.a $(LIBM) +diff -Nuar groff-1.22.3.old/src/utils/tfmtodit/tfmtodit.man groff-1.22.3/src/utils/tfmtodit/tfmtodit.man +--- groff-1.22.3.old/src/utils/tfmtodit/tfmtodit.man 2014-11-04 10:38:35.288523209 +0200 ++++ groff-1.22.3/src/utils/tfmtodit/tfmtodit.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 1989-2014 Free Software Foundation, Inc. ++Copyright \(co 1989-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -120,7 +120,7 @@ + command in the DESC file; + if it is not special, there is no need to list it, since + .B troff +-can automatically mount it when it\[aq]s first used. ++can automatically mount it when it\(aqs first used. + . + . + .LP +diff -Nuar groff-1.22.3.old/src/utils/xtotroff/.gitignore groff-1.22.3/src/utils/xtotroff/.gitignore +--- groff-1.22.3.old/src/utils/xtotroff/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/xtotroff/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,4 @@ ++Makefile ++xtotroff.n ++xtotroff ++Makefile.dep +diff -Nuar groff-1.22.3.old/src/utils/xtotroff/Makefile.sub groff-1.22.3/src/utils/xtotroff/Makefile.sub +--- groff-1.22.3.old/src/utils/xtotroff/Makefile.sub 2014-11-04 10:38:35.331522672 +0200 ++++ groff-1.22.3/src/utils/xtotroff/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,40 +0,0 @@ +-# Makefile.sub for `src utils xtotroff' +-# +-# File position: /src/utils/stotroff/Makefile.sub +-# +-# Copyright (C) 2014 Free Software Foundation, Inc. +-# +-# This file is part of `font utf8' which is part of `groff'. +-# +-# `groff' is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License as published by +-# the Free Software Foundation, either version 2 of the License, or +-# (at your option) any later version. +-# +-# `groff' is distributed in the hope that it will be useful, but +-# WITHOUT ANY WARRANTY; without even the implied warranty of +-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +-# General Public License for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see +-# . +-# +-######################################################################## +- +-PROG=xtotroff$(EXEEXT) +-MAN1=xtotroff.n +-MLIB=$(LIBM) +-XLIBS=$(LIBXUTIL) $(LIBGROFF) +-EXTRA_CFLAGS=$(X_CFLAGS) +-EXTRA_LDFLAGS=$(X_LIBS) $(X_PRE_LIBS) -lXaw -lXt -lX11 $(X_EXTRA_LIBS) +-OBJS=xtotroff.$(OBJEXT) +-CSRCS=$(srcdir)/xtotroff.c +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/src/utils/xtotroff/xtotroff.am groff-1.22.3/src/utils/xtotroff/xtotroff.am +--- groff-1.22.3.old/src/utils/xtotroff/xtotroff.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/src/utils/xtotroff/xtotroff.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,28 @@ ++# Copyright (C) 2014 ++# Free Software Foundation, Inc. ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++if !WITHOUT_X11 ++bin_PROGRAMS += xtotroff ++man1_MANS += src/utils/xtotroff/xtotroff.n ++xtotroff_SOURCES = src/utils/xtotroff/xtotroff.c ++XLIBS=$(LIBXUTIL) $(LIBGROFF) ++xtotroff_LDADD = libxutil.a libgroff.a $(X_LIBS) $(X_PRE_LIBS) \ ++ -lXaw -lXt -lX11 $(X_EXTRA_LIBS) $(LIBM) ++xtotroff_CPPFLAGS = $(AM_CPPFLAGS) $(X_CFLAGS) ++endif ++EXTRA_DIST += src/utils/xtotroff/xtotroff.man +diff -Nuar groff-1.22.3.old/src/utils/xtotroff/xtotroff.man groff-1.22.3/src/utils/xtotroff/xtotroff.man +--- groff-1.22.3.old/src/utils/xtotroff/xtotroff.man 2014-11-04 10:38:35.331522672 +0200 ++++ groff-1.22.3/src/utils/xtotroff/xtotroff.man 2015-04-23 20:57:03.000000000 +0300 +@@ -8,7 +8,7 @@ + .\" -------------------------------------------------------------------- + . + .de co +-Copyright \[co] 2004-2014 Free Software Foundation, Inc. ++Copyright \(co 2004-2014 Free Software Foundation, Inc. + + Permission is granted to make and distribute verbatim copies of + this manual provided the copyright notice and this permission notice +@@ -116,8 +116,8 @@ + .\" -------------------------------------------------------------------- + .SH BUGS + .\" -------------------------------------------------------------------- +-The only supported font encodings are \[oq]iso8859-1\[cq] and +-\[cq]adobe-fontspecific\[cq]. ++The only supported font encodings are \(oqiso8859-1\(cq and ++\(cqadobe-fontspecific\(cq. + . + . + .\" -------------------------------------------------------------------- +diff -Nuar groff-1.22.3.old/stamp-h.in groff-1.22.3/stamp-h.in +--- groff-1.22.3.old/stamp-h.in 2014-11-04 10:38:35.146524985 +0200 ++++ groff-1.22.3/stamp-h.in 1970-01-01 02:00:00.000000000 +0200 +@@ -1 +0,0 @@ +-timestamp +diff -Nuar groff-1.22.3.old/test-groff.in groff-1.22.3/test-groff.in +--- groff-1.22.3.old/test-groff.in 2014-11-04 10:38:35.146524985 +0200 ++++ groff-1.22.3/test-groff.in 2015-04-23 20:57:03.000000000 +0300 +@@ -20,35 +20,17 @@ + # This script runs groff without requiring that it be installed. + + SEP='@PATH_SEPARATOR@' +-builddir=@abs_top_builddir@/src ++builddir=@abs_top_builddir@ + srcdir=@abs_top_srcdir@ + +-GROFF_BIN_PATH=\ +-$builddir/roff/groff$SEP\ +-$builddir/roff/troff$SEP\ +-$builddir/preproc/preconv$SEP\ +-$builddir/preproc/pic$SEP\ +-$builddir/preproc/eqn$SEP\ +-$builddir/preproc/tbl$SEP\ +-$builddir/preproc/grn$SEP\ +-$builddir/preproc/refer$SEP\ +-$builddir/preproc/soelim$SEP\ +-$builddir/preproc/html$SEP\ +-$builddir/devices/grops$SEP\ +-$builddir/devices/grodvi$SEP\ +-$builddir/devices/grotty$SEP\ +-$builddir/devices/grolj4$SEP\ +-$builddir/devices/grolbp$SEP\ +-$builddir/devices/grohtml$SEP\ +-$builddir/devices/gropdf$SEP\ +-$builddir/devices/xditview ++GROFF_BIN_PATH=$builddir + + XENVIRONMENT=$srcdir/src/devices/xditview/GXditview.ad + export XENVIRONMENT + + GROFF_COMMAND_PREFIX= +-GROFF_FONT_PATH=$builddir/../font$SEP$srcdir/font +-GROFF_TMAC_PATH=$srcdir/tmac ++GROFF_FONT_PATH=$builddir/font$SEP$srcdir/font ++GROFF_TMAC_PATH=$srcdir/tmac$SEP$builddir/tmac$SEP$srcdir/contrib/mom$SEP$builddir/contrib/mom + export GROFF_BIN_PATH GROFF_COMMAND_PREFIX GROFF_FONT_PATH GROFF_TMAC_PATH + +-exec $builddir/roff/groff/groff ${1+"$@"} ++exec $builddir/groff ${1+"$@"} +diff -Nuar groff-1.22.3.old/TESTS groff-1.22.3/TESTS +--- groff-1.22.3.old/TESTS 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/TESTS 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,654 @@ ++This file gives information on the tests that were made during the ++Automake migration. ++ ++Environment ++----------- ++Arch Linux x64 with: ++ - Autoconf 2.69 ++ - Automake 1.14.1 ++ - GNU Make 4.0 ++ ++Current status ++-------------- ++ - Gnulib integrated ++ - Automake support ++ - Build src/libs/* ++ - Build src/utils/* ++ - Build src/preproc/* ++ - Build src/devices/* ++ - Build src/roff/* ++ - Build font/* ++ - man files from 'man' directory installed ++ - tmac files from 'tmac' directory installed ++ - Build and installation of contrib ++ - Build and installation of doc, including texinfo doc ++ ++Tests ++----- ++ ++0. Sum up of a full test pass ++----------------------------- ++ ++0.1. Build ++ ++ ./bootstrap ++ mkdir build ++ cd build ++ ../configure ++ make -j ++ ++0.2 Install ++ ++ mkdir -p ~/tmp/automake ++ make install DESTDIR=~/tmp/automake ++ ++-> Comparison with the tree installed by the the reference version ++ ++ make uninstall DESTDIR=~/tmp/automake ++ ++-> Check what is left in the installation tree ++ ++ make uninstall DESTDIR=~/tmp/automake ++ ++-> Check that this same command did not fail ++ ++0.3 Distcheck ++ ++ mkdir -p ~/tmp/distcheck ++ make distcheck DESTDIR=~/tmp/distcheck ++ ++-> Will attempt to untar the dist, make an out-of-source build, clean ++ and check that nothing is level, install, uninstall and check that ++ nothing is left in the install tree. This should not fail. ++ ++0.4 Dist ++ ++ make dist ++ ++-> Comparison of the generated tarball with the git tree ++-> Manually build an install from the tarball and compare the ++ installation tree with the reference version's installation tree. ++ ++Note that discheck checks that install does not fail, uninstall does ++not leave any file, but cannot check if a generated file that should ++not be distributed was distributed, or that files are missing in the ++installation tree. ++ ++0.5 Check ++ ++ make check ++ ++-> All tests should pass ++ ++0.6 Clean ++ ++ make mostlyclean ++ ++-> Check what is left in the build tree. ++ ++ make clean ++ ++-> Check what is left in the build tree. This is also automatically ++ checked by 'distcheck'. ++ ++ make distclean ++ ++-> Check what is left in the build tree ++ ++ ++1. Generation of build system files ++----------------------------------- ++ ++ ./bootstrap ++ ++Generated the following files and directories: ++ INSTALL ++ Makefile.in ++ aclocal.m4 ++ autom4te.cache/ ++ build-aux/ ++ configure ++ gnulib_m4/ ++ lib/ ++ src/include/config.hin ++ ++2. Tests of various targets ++--------------------------- ++ ++Tests done in 2 configurations: ++ ++ - Out-of source build mode ++ ++ mkdir build ++ cd build ++ ../configure ++ ++ - In source build: ++ ../configure ++ ++2.1 make ++ ++Following files are generated: ++ ++ - src/include/config.h ++ - lib/libgnu.a ++ ++from arch/misc: ++ - shdeps.sed ++ ++from src/libs: ++ - libbib.a ++ - libdriver.a ++ - libgroff.a, version.cpp and extra files (charset.alias, ++ ref-add.sed, ref-del.sed) ++ - libxutils.a ++ ++from src/utils: ++ - addftinfo ++ - afmtodit ++ - hpftodit ++ - indxbib ++ - lkbib ++ - lookbib ++ - pfbtops ++ - tfmtodit ++ - xtotroff ++ - man files (.n) in src/utils ++ ++from src/preproc: ++ - eqn ++ - grn ++ - pre-grohtml ++ - pic ++ - preconv ++ - refer ++ - soelim ++ - tbl ++ - Yacc and Lex support: the following files are generated: ++ -- eqn/eqn.cpp ++ -- eqn/eqn.hpp (previously eqn_tab.h) ++ -- pic/pic.cpp ++ -- pic/pic.hpp (previously pic_tab.h) ++ -- pic/pic.output ++ -- refer/label.cpp ++ -- refer/label.hpp ++ Compared to the previous build system, the only relevant diff is ++ an extra protection #define in label.cpp ++#ifndef YY_YY_SRC_PREPROC_REFER_LABEL_HPP_INCLUDED ++# define YY_YY_SRC_PREPROC_REFER_LABEL_HPP_INCLUDED ++ ++from src/devices: ++ - grodvi ++ - pre-grohtml ++ - post-grohtml ++ - grolbp ++ - grolj4 ++ - gropdf ++ - pdfmom ++ - grops ++ - grotty ++ - gxditview ++ ++from src/roff ++ - groff ++ - grog ++ - nroff ++ - troff ++ ++from font: font files in ++ - devascii ++ - devcp1047 ++ - devdvi ++ - devhtml ++ - devlatin1 ++ - devlbp ++ - devlj4 ++ - devpdf ++ - devps ++ - devutf8 ++ ++from contrib/chem: ++ - `chem' script and 3 README files ++ ++from contrib/eqn2graph: ++ - `eqn2graph' script ++ ++from contrib/gdiffmk: ++ - `gdiffmk' script ++ ++from contrib/gperl ++ - `gperl' script ++ ++from contrib/gpinyin ++ - `gpinyin' script ++ ++from contrib/grap2graph ++ - `grap2graph' script ++ ++from contrib/pic2graph ++ - `pic2graph' script ++ ++from contrib/glilypond ++ - `glilypond' script ++ ++from contrib/groffer ++ - `groffer' script, all the man files. ++ ++from contrib/hdtbl ++ - hdtbl examples and tmac files ++ ++from contrib/mm ++ - .n files ++ ++from contrib/pdfmark ++ - pdfmark.pdf ++ - pdfroff ++ ++from contrib/mom ++ - pdfmom ++ - 4 .pdf example files ++ ++from doc ++ - gnu.eps ++ - html and doc files ++ ++from doc, texinfo files: ++ ++ - By default, only doc/groff.info is built, as GNU standards require ++ to install only info doc. ++ ++ - Additional optional targets are available to build the doc in various formats: ++ -- make doc_txt ++ -- make doc_dvi ++ -- make doc_pdf ++ -- make doc_html (this will build the html in 2 directories: all ++ in 1 .html file, and 1 file per node). Note also that if ++ texinfo version is < 5.0, the resulting (mono) file will be ++ patched by fixinfo.sh ++ -- make doc_all will build all the 4 previous formats ++ ++In order to check and improve the dependencies, the following targets ++were built from a clean environment: ++ - make lib/libgnu.a ++ - make libbib.a ++ - make libdriver.a ++ - make libgroff.a ++ - make libxutil.a ++ - make addftinfo ++ - make afmtodit ++ - make hpftodit ++ - make indxbib ++ - make lkbib ++ - make lookbib ++ - make pfbtops ++ - make tfmtodit ++ - make xtotroff ++ - make eqn ++ - make grn ++ - make pre-grohtml ++ - make pic ++ - make preconv ++ - make refer ++ - make soelim ++ - make tbl ++ - make grodvi ++ - make post-grohtml ++ - make grolbp ++ - make grolj4 ++ - make gropdf ++ - make pdfmom ++ - make grops ++ - make grotty ++ - make gxditview ++ - make groff ++ - make grog ++ - make nroff ++ - make troff ++ - make chem ++ - make eqn2graph ++ - make gdiffmk ++ - make gperl ++ - make gpinyin ++ - make grap2graph ++ - make pic2graph ++ - make glilypond ++ - make groffer ++ - make pdfroff ++ - make contrib/pdfmark/pdfmark.pdf ++ - make pdfmom ++ - make contrib/mom/examples/mom-pdf.pdf ++ ++2.2 make clean ++ ++The following files remain (this is expected): ++ - Makefile ++ - config.status ++ - config.log ++ - doc/groff.info-1 ++ - doc/groff.info-3 ++ - src/include/config.h ++ - src/include/stamp-h1 ++ - .deps directories and .dirstamp files ++ ++2.3 make mostlyclean ++ ++ Like 'make clean', but the following files also remain (expected): ++ - lib*.a ++ - libgroff.a's charset.alias, ref-add.sed, ref-del.sed, and ++ version.cpp. ++ - gnulib's charset.alias, ref-add.sed, ref-del.sed and configmake.h ++ - src/preproc generated .cpp, hpp, and .output files ++ - Scripts (listed in bin_SCRIPTS) are added to the MOSTLYCLEANFILES ++ list. ++ ++Differences with former build system: ++ ++ - Programs (listed in bin_PROGRAMS) are not cleaned by 'make ++ mostlyclean'. This could be changed if needed (MOSTLYCLEANFILES += ++ $(bin_PROGRAMS)). ++ ++2.4 make distclean ++ ++ Like 'make clean', but the following files are also cleaned: ++ - Makefile ++ - config.status ++ - config.log ++ - src/include/config.h ++ - src/include/stamp-h1 ++ - .deps directories and .dirstamp files ++ ++ In a out-of-source build, nothing remains in the build directory ++ expect empty directories. ++ ++ The files generated by bootstrap and needed by the configure script ++ are untouched: ++ INSTALL ++ Makefile.in ++ aclocal.m4 ++ build-aux/ ++ configure ++ gnulib_m4/ ++ lib/ ++ src/include/config.hin ++ ++2.5 make maintainer-clean ++ ++ Like 'make distclean' ++ ++2.6 make install ++ ++ mkdir -p ~/tmp/automake ++ make install DESTDIR=~/tmp/automake ++ ++ - If file charset.alias is always present in ++ $(DESTDIR)/usr/local/lib, make install update it by adding 'groff' ++ to the list of programs using it. Otherwise nothing is installed. ++ ++ - Programs from 'src' installed in $(DESTDIR)/usr/local/bin: ++ ++ - man files from man, src are installed in ++ $(DESTDIR)/usr/local/share/man/man1, man5 and man7. ++ ++ - $(DESTDIR)/usr/local/share/groff/1.22.3/eign (from src/utils/indxbib) ++ ++ - In $(DESTDIR)/usr/local/lib/X11/app-defaults: GXditview and ++ GXditview-color. If these files are already present, they are ++ first moved to GXditview.old and GXditview-color.old. ++ ++ - usr/local/lib/groff: ++ -- groff_opts_no_arg.txt and groff_opts_with_arg.txt are installed ++ -- grog/sub.pl ++ ++ - font files are installed in $(DESTDIR)/usr/local/groff/1.22.3/font ++ and oldfont and identical to the one installed with the previous ++ build system, except the fonts from devpdf which are not generated ++ identically at each build. ++ ++ - tmac files from 'tmac' dir are installed in ++ $(DESTDIR)/usr/local/groff/1.22.3/tmac. Some files are first ++ stripped (comments removed) at build time. Checked that they are ++ strictly identical to the one install by the original build ++ system. ++ ++ - contrib scripts installed in $(DESTDIR)/usr/local/bin ++ ++ - contrib/chem: ++ ++ -- chem.pic installed in ++ $(DESTDIR)/usr/local/share/groff/1.22.3/pic/chem.pic ++ ++ -- other chem files installed in ++ $(DESTDIR)/usr/local/share/doc/groff-1.22.3/examples, identical to ++ the old build system. ++ ++ -- contrib/chem/README is strangely build but not installed, this ++ is the behaviour on the old build system. ++ ++ - contrib/hdtbl: ++ ++ -- example files in ++ $(DESTDIR)/usr/local/share/doc/groff-1.22.3/examples/hdtbl ++ ++ -- hdtbl.tmac and hdmisc.tmac installed in ++ $(DESTDIR)/usr/local/share/groff-1.22.3/tmac ++ ++ - contrib/mm ++ ++ -- tmac files in tmacdir, misc files in ++ $(DESTDIR)/usr/local/share/groff/1.22.3/tmac/mm ++ ++ -- refer-mm.tmac in tmacdir ++ ++ - contrib/pdfmark ++ ++ -- tmac files ++ -- pdfmark.pdf ++ ++ - contrib/mom ++ -- example files in $(DESTDIR)/usr/local/share/doc/groff-1.22.3/examples/mom ++ -- html files in $(DESTDIR)/usr/local/share/doc/groff-1.22.3/html/mom ++ ++ - doc ++ ++ -- webpageXX.html files ++ -- picXX.html files ++ -- info file from groff.texinfo ++ ++Diff with previous build system after final (full tree comparison): ++ - devcp1047 fonts are installed $(DESTDIR)/usr/local/groff/1.22.3/font ++ - devpdf fonts (not identical at each build) ++ - in hdbtbl, parts of some .ps are not identical at each build. ++ - timetamp in man files or html files ++ ++2.7 make uninstall ++ ++ - Note: target 'uninstall_groffdirs' is a dependency of standard ++ target uninstall-hook, and removes groff's specific directories ++ (exampledir, libprogramdir etc ...). contrib that create ++ sub-directories in these groff specific directories should also ++ add a custom rule that is a dependency of uninstall_groffdirs to ++ remove the directories it created, otherwise uninstall-hook will ++ fail du to the impossibility to remove non-empty dir. ++ ++ - Tree after uninstall: ++. ++└── usr ++ └── local ++ ├── bin ++ ├── lib ++ │   └── X11 ++ │   └── app-defaults ++ └── share ++ ├── doc ++ ├── info ++ │   └── dir ++ └── man ++ ├── man1 ++ ├── man5 ++ └── man7 ++ ++13 directories, 1 file ++ ++ - Notes: ++ -- $(DESTDIR)/usr/local/lib/charset.alias is removed if exists ++ -- $(DESTDIR)/usr/local/lib/X11/app-defaults/GXditview and ++ GXditview-color are removed. However, GXditview.old and ++ GXditview-color.old are not removed (this is the behaviour on the ++ old build system) ++ ++2.8 make dist ++ ++ groff-1.22.3.tar.gz is generated. ++ ++ - Files/directories that are not distributed on purpose: ++ all .gitignore files ++ .gitmodules ++ bootstrap ++ bootstrap.conf ++ gnulib/ ++ README.git ++ ++ - Files/directories not present in the git tree that are ++ distributed: ++ build-aux/ ++ gnulib_m4/ ++ lib/ ++ src/include/config.hin ++ INSTALL ++ Makefile.in ++ aclocal.m4 ++ configure ++ src/preproc/eqn/eqn.cpp ++ src/preproc/eqn/eqn.hpp ++ src/preproc/pic/pic.cpp ++ src/preproc/pic/pic.hpp ++ src/preproc/refer/label.hpp ++ src/preproc/refere/label.cpp ++ doc/gnu.eps ++ ++Note: when building from a tarball, we will use doc/gnu.eps. ++ ++2.9 make check ++ ++ (manually called automake --add-missing to add build-aux/test-driver) ++ - gdiffmk's test script is now plugged to the 'make check' ++ target. The original runtests.in is renamed to runtests.sh with ++ absolute paths. The new script gdiffmk_tests.sh is used to call ++ runtests.sh in $(top_builddir)/contrib/gdiff/tests, because ++ runtest.sh will generate some result files. ++ ++2.10 make distcheck ++ ++ This will attempt to make a tarball, and from this tarball, build ++the package(out-of-source build), check it, clean it (checking that no ++file remains), install it, uninstall it (checking that no file remains ++in the install tree). ++ ++ make distcheck ++ ++ - All phases now succeed ++ ++3. Additional tests ++------------------- ++ ++3.1 Build without X support ++ ++ Calling configure with option --without-x doesn't build: ++ - gxidview ++ - libxutil.a ++ - xtotroff ++ ++ The following fonts are not installed: ++ - dev/X100 ++ - devX100-12 ++ - devX75 ++ - devX75-12 ++ ++ 'make distcheck' passes correctly, and the tarball generated by ++ 'make dist' is identical to the one generated with X support. ++ ++3.2 Options to build the doc ++ ++ - Default behavour ++ -- By default all the documentation (except texinfo documents) ++ will be installed in: ++ $(DESTDIR)/usr/local/share/doc/groff-1.22.3/ ++ -- The only texinfo documentation installed by default is: ++ $(DESTDIR)/usr/local/share/info/groff.info ++ ++ - Passing to configure option: --with-doc=no ++ ++ No doc is built nor installed, $(DESTDIR)/usr/local/share/doc ++ is not even created. groff.info is not installed. ++ ++ - Passing to configure option: --with-doc=examples ++ ++ Only $(DESTDIR)/usr/local/share/doc/groff-1.22.3/examples is ++ present, and contain files in format other than html and pdf ++ formats. ++ ++ - Passing to configure option: --with-doc=html ++ ++ Only $(DESTDIR)/usr/local/share/doc/groff-1.22.3/html/ is present. ++ ++ - Passing to configure option: --with-doc=pdf ++ Only ++ $(DESTDIR)/usr/local/share/doc/groff-1.22.3/pdf/pdfmark.pdf ++ is present ++ ++ - Passing to configure option: --with-doc=other ++ ++ Only .me and .ps files are present in ++ $(DESTDIR)/usr/local/share/doc/groff-1.22.3/ ++ ++ - Passing to configure option: --with-doc=info ++ $(DESTDIR)/usr/local/share/doc is not created. ++ Only $(DESTDIR/usr/local/share/info/ is installed ++ ++ - Note that pre-built HTML doc in contrib/mom is installed even if ++ the tools needed to build html doc are not available. ++ ++ ++3.3 Build in presence of an non-GNU Troff installation ++ ++ - To simulate the existence of a non-GNU Troff, removed any existing ++ troff, and added a dummy troff script in /usr/bin/troff that ++ contains: ++ ++ #!/bin/sh ++ echo 0 ++ ++ and built groff as usuall. ++ ++ - Programs listed in prefixexecbin_PROGRAMS, scripts listed in ++ prefixecbin_SCRIPTS and man pages listed in PREFIXMAN1 are ++ correctly installed with a 'g' prefix. All targets (clean, ++ install/uninstall, distcheck) work as usual. No diff with the old ++ build system. ++ ++3.4 Build in presence of system tmac files ++ ++ - Create 3 dummy files in /usr/lib/tmac: tmac.an, tmac.m, tmac.s, ++ that all contain: ++ ++.if ++ ++ - Build and install as usual: ++ ++ -- $(DESTDIR)/usr/local/lib/groff/site-tmac/ contains 3 files: ++ an.tmac, m.tmac, s.tmac. ++ -- In $(DESTDIR)/usr/local/share/groff/1.22.3/tmac 6 files have a ++ 'g' prefix: gan.tmac, gm.tmac, gmm.tmac, gmmse.tmac, gmse.tmac, ++ gs.tmac. ++ ++3.5 Parallel build ++ ++ - Checked that usage of option -j when invoking `make' works correctly. ++ ++4. Notes ++-------- ++ ++ - Gnulib: some files of src/libs/libgroff could be replaced by their ++ gnulib equivalent ++ ++ - Gnulib: git-version-gen could be used +diff -Nuar groff-1.22.3.old/tmac/andoc.tmac groff-1.22.3/tmac/andoc.tmac +--- groff-1.22.3.old/tmac/andoc.tmac 2014-11-04 10:38:35.532520159 +0200 ++++ groff-1.22.3/tmac/andoc.tmac 2015-04-23 20:57:03.000000000 +0300 +@@ -34,35 +34,50 @@ + .als andoc-em em + .als andoc-bp bp + . +-.de1 reload-doc +-. ch an-header \" remove trap set by an-old.tmac +-. ch an-footer \" remove trap set by an-old.tmac +-. ch an-p-footer \" remove trap set by an-old.tmac +-. +-. als em andoc-em +-. als bp andoc-bp +-. rm Dd \" disable load-only-once, see doc.tmac + . +-. mso doc.tmac ++.\" We must not use `.de1' for `reload-doc' or `reload-man'! `doc.tmac' ++.\" unconditionally switches compatibility mode off, but `.de1' would ignore ++.\" this, restoring the mode that was active before. Similarly, we have to ++.\" switch back to the original compatibility mode for man documents in case ++.\" there is a mix of mdoc and man input files. ++.\" ++.\" Due to a bug in GNU troff it necessary to have a no-op line between ++.\" `.do' and `\*'. ++. ++. ++.de reload-doc ++. do ch an-header \" remove trap set by an-old.tmac ++. do ch an-footer \" remove trap set by an-old.tmac ++. do ch an-p-footer \" remove trap set by an-old.tmac ++. ++. do als em andoc-em ++. do als bp andoc-bp ++. do rm Dd \" disable load-only-once, see doc.tmac + . +-. als TH reload-man +-\\*[Dd]\\ ++. do mso doc.tmac ++. ++. do als TH reload-man ++. ++\\*(Dd\\ + .. + . +-.de1 reload-man +-. ch header \" remove trap set by doc.tmac +-. ch footer \" remove trap set by doc.tmac +-. +-. als em andoc-em +-. als bp andoc-bp +-. rm RI \" disable load-only-once, see an-old.tmac +-. blm \" no blank line macro +-. rm TH ++.de reload-man ++. do cp \n(.C \" restore original compatibility mode ++. ++. do ch header \" remove trap set by doc.tmac ++. do ch footer \" remove trap set by doc.tmac ++. ++. do als em andoc-em ++. do als bp andoc-bp ++. do rm RI \" disable load-only-once, see an-old.tmac ++. do blm \" no blank line macro ++. do rm TH ++. ++. do mso an-old.tmac + . +-. mso an-old.tmac ++. do als Dd reload-doc + . +-. als Dd reload-doc +-\\*[TH]\\ ++\\*(TH\\ + .. + . + .als TH reload-man +diff -Nuar groff-1.22.3.old/tmac/doc-common groff-1.22.3/tmac/doc-common +--- groff-1.22.3.old/tmac/doc-common 2014-11-04 10:38:35.533520146 +0200 ++++ groff-1.22.3/tmac/doc-common 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1376 +0,0 @@ +-.\" -*- nroff -*- +-.\" +-.\" Copyright (c) 1991, 1993 +-.\" The Regents of the University of California. All rights reserved. +-.\" +-.\" Redistribution and use in source and binary forms, with or without +-.\" modification, are permitted provided that the following conditions +-.\" are met: +-.\" 1. Redistributions of source code must retain the above copyright +-.\" notice, this list of conditions and the following disclaimer. +-.\" 2. Redistributions in binary form must reproduce the above copyright +-.\" notice, this list of conditions and the following disclaimer in the +-.\" documentation and/or other materials provided with the distribution. +-.\" 3. [Deleted. See +-.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +-.\" 4. Neither the name of the University nor the names of its contributors +-.\" may be used to endorse or promote products derived from this software +-.\" without specific prior written permission. +-.\" +-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-.\" SUCH DAMAGE. +-.\" +-.\" @(#)doc-common 8.1 (Berkeley) 06/08/93 +-.\" +-.\" %beginstrip% +-. +-. +-.\" Macro Identifiers. For each user macro a corresponding register with +-.\" the same name must exist. Its value must not be zero. +-. +-.nr %A 1 +-.nr %B 1 +-.nr %C 1 +-.nr %D 1 +-.nr %I 1 +-.nr %J 1 +-.nr %N 1 +-.nr %O 1 +-.nr %P 1 +-.nr %Q 1 +-.nr %R 1 +-.nr %T 1 +-.nr %U 1 +-.nr %V 1 +-.nr Ac 3 +-.nr Ad 12n +-.nr An 12n +-.nr Ao 12n +-.nr Ap 2 +-.nr Aq 12n +-.nr Ar 12n +-.nr At 1 +-.nr Bc 3 +-.nr Bf 8n\" ? +-.nr Bk 8n\" ? +-.nr Bl 1 +-.nr Bo 12n +-.nr Bq 12n +-.nr Brc 3 +-.nr Bro 12n +-.nr Brq 12n +-.nr Bsx 1 +-.nr Bt 8n\" ? +-.nr Bx 1 +-.nr Cd 12n +-.nr Cm 10n +-.nr D1 8n\" ? +-.nr Dc 3 +-.nr Dl 8n\" ? +-.nr Dt 8n\" ? +-.nr Do 12n +-.nr Dq 12n +-.nr Ds 6n\" many manpages still use this as a -width value +-.nr Dv 12n +-.nr Dx 1 +-.nr Ec 3 +-.nr Ef 8n\" ? +-.nr Ek 8n\" ? +-.nr El 1 +-.nr Em 10n +-.nr En 12n +-.nr Eo 12n +-.nr Eq 12n +-.nr Er 17n +-.nr Es 12n +-.nr Ev 15n +-.nr Ex 1 +-.nr Fa 12n +-.nr Fc 3 +-.nr Fd 12n\" ? +-.nr Fl 10n +-.nr Fn 16n +-.nr Fo 16n +-.nr Fr 12n\" ? +-.nr Ft 8n\" ? +-.nr Fx 1 +-.nr Ic 10n +-.nr In 12n +-.nr It 8n\" ? +-.nr Lb 11n +-.nr Li 16n +-.nr Lk 6n\" ? +-.nr Lp 8n\" ? +-.nr Me 6n +-.nr Ms 6n +-.nr Mt 6n\" ? +-.nr Nd 8n\" ? +-.nr Nm 10n +-.nr No 12n +-.nr Ns 2 +-.nr Nx 1 +-.nr Oc 3 +-.nr Oo 10n +-.nr Op 14n +-.nr Os 6n\" ? +-.nr Ox 1 +-.nr Pa 32n +-.nr Pc 3 +-.nr Pf 12n +-.nr Po 12n +-.nr Pp 8n\" ? +-.nr Pq 12n +-.nr Qc 3 +-.nr Ql 16n +-.nr Qo 12n +-.nr Qq 12n +-.nr Rv 1 +-.nr Sc 3 +-.nr Sh 8n +-.nr Sm 8n\" ? +-.nr So 12n +-.nr Sq 12n +-.nr Ss 8n +-.nr St 8n\" ? +-.nr Sx 16n +-.nr Sy 6n +-.nr Ta 2 +-.nr Tn 10n +-.nr Ud 8n\" ? +-.nr Ux 1 +-.nr Va 12n +-.nr Vt 8n\" ? +-.nr Xc 3 +-.nr Xo 1 +-.nr Xr 10n +-. +-. +-.\" macros which must be processed after the closing delimiter of `Op' +-.\" and friends +-.ds doc-after-Ao +-.ds doc-after-Bo +-.ds doc-after-Bro +-.ds doc-after-Do +-.ds doc-after-Eo +-.ds doc-after-Fo +-.ds doc-after-Ns +-.ds doc-after-Oo +-.ds doc-after-Po +-.ds doc-after-Qo +-.ds doc-after-So +-.ds doc-after-Xo +-. +-. +-.nr doc-display-indent 6n +-. +-. +-.\" space strings +-. +-.ds doc-soft-space " \" +-.ds doc-hard-space \~ +-.ds doc-tab \t +-. +-. +-.eo +-. +-. +-.\" punctuation values (suffix=3, prefix=4) +-. +-.nr doc-punct. 3 +-.nr doc-punct, 3 +-.nr doc-punct: 3 +-.nr doc-punct; 3 +-.nr doc-punct( 4 +-.nr doc-punct) 3 +-.nr doc-punct[ 4 +-.nr doc-punct] 3 +-.nr doc-punct? 3 +-.nr doc-punct! 3 +-. +-. +-.\" header assembly macros +-. +-.\" NS doc-document-title global string +-.\" NS the title of the manual page +-. +-.ds doc-document-title UNTITLED +-. +-. +-.\" NS doc-volume global string +-.\" NS the volume where the manual page belongs to +-. +-.ds doc-volume LOCAL +-. +-. +-.\" NS doc-section global string +-.\" NS the manual section +-. +-.ds doc-section Null +-. +-. +-.\" NS Dt user macro (not parsed, not callable) +-.\" NS document title +-.\" NS +-.\" NS modifies: +-.\" NS doc-document-title +-.\" NS doc-section +-.\" NS doc-volume +-.\" NS doc-command-name +-.\" NS +-.\" NS local variables: +-.\" NS doc-volume-as-XXX +-.\" NS doc-volume-ds-XXX +-.\" NS +-.\" NS width register `Dt' set above +-. +-.\" an alternative, more detailed scheme for naming the manual sections +-.\" +-.ds doc-volume-operating-system BSD +-.nr doc-volume-operating-system-ateol 0 +-.ds doc-volume-ds-1 General Commands Manual +-.ds doc-volume-ds-2 System Calls Manual +-.ds doc-volume-ds-3 Library Functions Manual +-.ds doc-volume-ds-4 Kernel Interfaces Manual +-.ds doc-volume-ds-5 File Formats Manual +-.ds doc-volume-ds-6 Games Manual +-.ds doc-volume-ds-7 Miscellaneous Information Manual +-.ds doc-volume-ds-8 System Manager's Manual +-.ds doc-volume-ds-9 Kernel Developer's Manual +-. +-.ds doc-volume-ds-USD User's Supplementary Documents +-.ds doc-volume-ds-PS1 Programmer's Supplementary Documents +-.ds doc-volume-ds-AMD Ancestral Manual Documents +-.ds doc-volume-ds-SMM System Manager's Manual +-.ds doc-volume-ds-URM User's Reference Manual +-.ds doc-volume-ds-PRM Programmer's Manual +-.ds doc-volume-ds-KM Kernel Manual +-.ds doc-volume-ds-IND Manual Master Index +-.ds doc-volume-ds-LOCAL Local Manual +-.ds doc-volume-ds-CON Contributed Software Manual +-. +-.als doc-volume-ds-MMI doc-volume-ds-IND +-.als doc-volume-ds-LOC doc-volume-ds-LOCAL +-. +-.ds doc-volume-as-alpha alpha +-.als doc-volume-as-Alpha doc-volume-as-alpha +-.ds doc-volume-as-acorn26 acorn26 +-.ds doc-volume-as-acorn32 acorn32 +-.ds doc-volume-as-algor algor +-.ds doc-volume-as-amd64 amd64 +-.ds doc-volume-as-amiga amiga +-.ds doc-volume-as-amigappc amigappc +-.ds doc-volume-as-arc arc +-.ds doc-volume-as-arm arm +-.ds doc-volume-as-arm26 arm26 +-.ds doc-volume-as-arm32 arm32 +-.ds doc-volume-as-armish armish +-.ds doc-volume-as-atari atari +-.ds doc-volume-as-aviion aviion +-.ds doc-volume-as-beagle beagle +-.ds doc-volume-as-bebox bebox +-.ds doc-volume-as-cats cats +-.ds doc-volume-as-cesfic cesfic +-.ds doc-volume-as-cobalt cobalt +-.ds doc-volume-as-dreamcast dreamcast +-.ds doc-volume-as-emips emips +-.ds doc-volume-as-evbarm evbarm +-.ds doc-volume-as-evbmips evbmips +-.ds doc-volume-as-evbppc evbppc +-.ds doc-volume-as-evbsh3 evbsh3 +-.ds doc-volume-as-ews4800mips ews4800mips +-.ds doc-volume-as-hp300 hp300 +-.ds doc-volume-as-hp700 hp700 +-.ds doc-volume-as-hpcarm hpcarm +-.ds doc-volume-as-hpcmips hpcmips +-.ds doc-volume-as-hpcsh hpcsh +-.ds doc-volume-as-hppa hppa +-.ds doc-volume-as-hppa64 hppa64 +-.ds doc-volume-as-i386 i386 +-.ds doc-volume-as-ia64 ia64 +-.ds doc-volume-as-ibmnws ibmnws +-.ds doc-volume-as-iyonix iyonix +-.ds doc-volume-as-landisk landisk +-.ds doc-volume-as-loongson loongson +-.ds doc-volume-as-luna68k luna68k +-.ds doc-volume-as-luna88k luna88k +-.ds doc-volume-as-m68k m68k +-.ds doc-volume-as-mac68k mac68k +-.ds doc-volume-as-macppc macppc +-.ds doc-volume-as-mips mips +-.ds doc-volume-as-mips64 mips64 +-.ds doc-volume-as-mipsco mipsco +-.ds doc-volume-as-mmeye mmeye +-.ds doc-volume-as-mvme68k mvme68k +-.ds doc-volume-as-mvme88k mvme88k +-.ds doc-volume-as-mvmeppc mvmeppc +-.ds doc-volume-as-netwinder netwinder +-.ds doc-volume-as-news68k news68k +-.ds doc-volume-as-newsmips newsmips +-.ds doc-volume-as-next68k next68k +-.ds doc-volume-as-ofppc ofppc +-.ds doc-volume-as-palm palm +-.ds doc-volume-as-pc532 pc532 +-.ds doc-volume-as-playstation2 playstation2 +-.ds doc-volume-as-pmax pmax +-.ds doc-volume-as-pmppc pmppc +-.ds doc-volume-as-powerpc powerpc +-.ds doc-volume-as-prep prep +-.ds doc-volume-as-rs6000 rs6000 +-.ds doc-volume-as-sandpoint sandpoint +-.ds doc-volume-as-sbmips sbmips +-.ds doc-volume-as-sgi sgi +-.ds doc-volume-as-sgimips sgimips +-.ds doc-volume-as-sh3 sh3 +-.ds doc-volume-as-shark shark +-.ds doc-volume-as-socppc socppc +-.ds doc-volume-as-solbourne solbourne +-.ds doc-volume-as-sparc sparc +-.ds doc-volume-as-sparc64 sparc64 +-.ds doc-volume-as-sun2 sun2 +-.ds doc-volume-as-sun3 sun3 +-.ds doc-volume-as-tahoe tahoe +-.ds doc-volume-as-vax vax +-.ds doc-volume-as-x68k x68k +-.ds doc-volume-as-x86_64 x86_64 +-.ds doc-volume-as-xen xen +-.ds doc-volume-as-zaurus zaurus +-. +-.de Dt +-. \" reset default arguments +-. ds doc-document-title UNTITLED +-. ds doc-volume LOCAL +-. ds doc-section Null +-. ds doc-command-name +-. +-. if !"\$1"" \ +-. ds doc-document-title "\$1 +-. +-. if !"\$2"" \{\ +-. ds doc-section \$2 +-. ie \B\$2 \{\ +-. if ((\$2 >= 1) & (\$2 <= 9)) \{\ +-. ie \n[doc-volume-operating-system-ateol] \{\ +-. ds doc-volume "\*[doc-volume-ds-\$2] \*[doc-volume-operating-system] +-. if \A\$3 \{\ +-. if d doc-volume-as-\$3 \ +-. as doc-volume "/\*[doc-volume-as-\$3] +-. \}\} +-. el \{\ +-. ds doc-volume "\*[doc-volume-operating-system] +-. if \A\$3 \{\ +-. if d doc-volume-as-\$3 \ +-. as doc-volume "/\*[doc-volume-as-\$3] +-. \} +-. as doc-volume " \*[doc-volume-ds-\$2] +-. \}\}\} +-. el \{\ +-. ie "\$2"unass" \ +-. ds doc-volume DRAFT +-. el \{ .ie "\$2"draft" \ +-. ds doc-volume DRAFT +-. el .if "\$2"paper" \ +-. ds doc-volume UNTITLED +-. \}\} +-. if \A\$3 \{\ +-. if d doc-volume-ds-\$3 \ +-. ds doc-volume "\*[doc-volume-ds-\$3] +-. \}\}\} +-. +-. if !"\$3"" \ +-. if "\*[doc-volume]"LOCAL" \ +-. ds doc-volume \$3 +-. +-. if !\n[cR] \ +-. if \n[nl] \{\ +- . doc-setup-header +-. bp +-. \} +-.. +-. +-. +-.\" NS doc-default-operating-system global string +-.\" NS the exact (default) version of the operating system +-.\" NS +-.\" NS override this in `mdoc.local', if necessary +-. +-.ds doc-default-operating-system BSD +-. +-. +-.\" NS doc-operating-system global string +-.\" NS the exact version of the operating system +-. +-.ds doc-operating-system +-. +-. +-.\" NS Os user macro (not parsed, not callable) +-.\" NS operating system +-.\" NS +-.\" NS modifies: +-.\" NS doc-operating-system +-.\" NS doc-command-name +-.\" NS +-.\" NS local variables: +-.\" NS doc-operating-system-XXX-XXX +-.\" NS +-.\" NS width register `Os' set above +-. +-.ds doc-operating-system-ATT-7 7th\~Edition +-.als doc-operating-system-ATT-7th doc-operating-system-ATT-7 +-.ds doc-operating-system-ATT-3 System\~III +-.als doc-operating-system-ATT-III doc-operating-system-ATT-3 +-.ds doc-operating-system-ATT-V System\~V +-.ds doc-operating-system-ATT-V.2 System\~V Release\~2 +-.ds doc-operating-system-ATT-V.3 System\~V Release\~3 +-.ds doc-operating-system-ATT-V.4 System\~V Release\~4 +-. +-.ds doc-operating-system-BSD-3 3rd\~Berkeley Distribution +-.ds doc-operating-system-BSD-4 4th\~Berkeley Distribution +-.ds doc-operating-system-BSD-4.1 4.1\~Berkeley Distribution +-.ds doc-operating-system-BSD-4.2 4.2\~Berkeley Distribution +-.ds doc-operating-system-BSD-4.3 4.3\~Berkeley Distribution +-.ds doc-operating-system-BSD-4.3T 4.3-Tahoe Berkeley Distribution +-.ds doc-operating-system-BSD-4.3R 4.3-Reno Berkeley Distribution +-.als doc-operating-system-BSD-4.3t doc-operating-system-BSD-4.3T +-.als doc-operating-system-BSD-4.3r doc-operating-system-BSD-4.3R +-.ds doc-operating-system-BSD-4.4 4.4BSD +-. +-.ds doc-operating-system-NetBSD-0.8 0.8 +-.ds doc-operating-system-NetBSD-0.8a 0.8A +-.ds doc-operating-system-NetBSD-0.9 0.9 +-.ds doc-operating-system-NetBSD-0.9a 0.9A +-.ds doc-operating-system-NetBSD-1.0 1.0 +-.ds doc-operating-system-NetBSD-1.0a 1.0A +-.ds doc-operating-system-NetBSD-1.1 1.1 +-.ds doc-operating-system-NetBSD-1.2 1.2 +-.ds doc-operating-system-NetBSD-1.2a 1.2A +-.ds doc-operating-system-NetBSD-1.2b 1.2B +-.ds doc-operating-system-NetBSD-1.2c 1.2C +-.ds doc-operating-system-NetBSD-1.2d 1.2D +-.ds doc-operating-system-NetBSD-1.2e 1.2E +-.ds doc-operating-system-NetBSD-1.3 1.3 +-.ds doc-operating-system-NetBSD-1.3a 1.3A +-.ds doc-operating-system-NetBSD-1.4 1.4 +-.ds doc-operating-system-NetBSD-1.4.1 1.4.1 +-.ds doc-operating-system-NetBSD-1.4.2 1.4.2 +-.ds doc-operating-system-NetBSD-1.4.3 1.4.3 +-.ds doc-operating-system-NetBSD-1.5 1.5 +-.ds doc-operating-system-NetBSD-1.5.1 1.5.1 +-.ds doc-operating-system-NetBSD-1.5.2 1.5.2 +-.ds doc-operating-system-NetBSD-1.5.3 1.5.3 +-.ds doc-operating-system-NetBSD-1.6 1.6 +-.ds doc-operating-system-NetBSD-1.6.1 1.6.1 +-.ds doc-operating-system-NetBSD-1.6.2 1.6.2 +-.ds doc-operating-system-NetBSD-1.6.3 1.6.3 +-.ds doc-operating-system-NetBSD-2.0 2.0 +-.ds doc-operating-system-NetBSD-2.0.1 2.0.1 +-.ds doc-operating-system-NetBSD-2.0.2 2.0.2 +-.ds doc-operating-system-NetBSD-2.0.3 2.0.3 +-.ds doc-operating-system-NetBSD-2.1 2.1 +-.ds doc-operating-system-NetBSD-3.0 3.0 +-.ds doc-operating-system-NetBSD-3.0.1 3.0.1 +-.ds doc-operating-system-NetBSD-3.0.2 3.0.2 +-.ds doc-operating-system-NetBSD-3.0.3 3.0.3 +-.ds doc-operating-system-NetBSD-3.1 3.1 +-.ds doc-operating-system-NetBSD-3.1.1 3.1.1 +-.ds doc-operating-system-NetBSD-4.0 4.0 +-.ds doc-operating-system-NetBSD-4.0.1 4.0.1 +-.ds doc-operating-system-NetBSD-5.0 5.0 +-.ds doc-operating-system-NetBSD-5.0.1 5.0.1 +-.ds doc-operating-system-NetBSD-5.0.2 5.0.2 +-.ds doc-operating-system-NetBSD-5.1 5.1 +-.ds doc-operating-system-NetBSD-5.1.2 5.1.2 +-.ds doc-operating-system-NetBSD-5.1.3 5.1.3 +-.ds doc-operating-system-NetBSD-5.1.4 5.1.4 +-.ds doc-operating-system-NetBSD-5.2 5.2 +-.ds doc-operating-system-NetBSD-5.2.1 5.2.1 +-.ds doc-operating-system-NetBSD-5.2.2 5.2.2 +-.ds doc-operating-system-NetBSD-6.0 6.0 +-.ds doc-operating-system-NetBSD-6.0.1 6.0.1 +-.ds doc-operating-system-NetBSD-6.0.2 6.0.2 +-.ds doc-operating-system-NetBSD-6.0.3 6.0.3 +-.ds doc-operating-system-NetBSD-6.0.4 6.0.4 +-.ds doc-operating-system-NetBSD-6.0.5 6.0.5 +-.ds doc-operating-system-NetBSD-6.1 6.1 +-.ds doc-operating-system-NetBSD-6.1.1 6.1.1 +-.ds doc-operating-system-NetBSD-6.1.2 6.1.2 +-.ds doc-operating-system-NetBSD-6.1.3 6.1.3 +-.ds doc-operating-system-NetBSD-6.1.4 6.1.4 +-. +-.ds doc-operating-system-OpenBSD-2.0 2.0 +-.ds doc-operating-system-OpenBSD-2.1 2.1 +-.ds doc-operating-system-OpenBSD-2.2 2.2 +-.ds doc-operating-system-OpenBSD-2.3 2.3 +-.ds doc-operating-system-OpenBSD-2.4 2.4 +-.ds doc-operating-system-OpenBSD-2.5 2.5 +-.ds doc-operating-system-OpenBSD-2.6 2.6 +-.ds doc-operating-system-OpenBSD-2.7 2.7 +-.ds doc-operating-system-OpenBSD-2.8 2.8 +-.ds doc-operating-system-OpenBSD-2.9 2.9 +-.ds doc-operating-system-OpenBSD-3.0 3.0 +-.ds doc-operating-system-OpenBSD-3.1 3.1 +-.ds doc-operating-system-OpenBSD-3.2 3.2 +-.ds doc-operating-system-OpenBSD-3.3 3.3 +-.ds doc-operating-system-OpenBSD-3.4 3.4 +-.ds doc-operating-system-OpenBSD-3.5 3.5 +-.ds doc-operating-system-OpenBSD-3.6 3.6 +-.ds doc-operating-system-OpenBSD-3.7 3.7 +-.ds doc-operating-system-OpenBSD-3.8 3.8 +-.ds doc-operating-system-OpenBSD-3.9 3.9 +-.ds doc-operating-system-OpenBSD-4.0 4.0 +-.ds doc-operating-system-OpenBSD-4.1 4.1 +-.ds doc-operating-system-OpenBSD-4.2 4.2 +-.ds doc-operating-system-OpenBSD-4.3 4.3 +-.ds doc-operating-system-OpenBSD-4.4 4.4 +-.ds doc-operating-system-OpenBSD-4.5 4.5 +-.ds doc-operating-system-OpenBSD-4.6 4.6 +-.ds doc-operating-system-OpenBSD-4.7 4.7 +-.ds doc-operating-system-OpenBSD-4.8 4.8 +-.ds doc-operating-system-OpenBSD-4.9 4.9 +-.ds doc-operating-system-OpenBSD-5.0 5.0 +-.ds doc-operating-system-OpenBSD-5.1 5.1 +-.ds doc-operating-system-OpenBSD-5.2 5.2 +-.ds doc-operating-system-OpenBSD-5.3 5.3 +-.ds doc-operating-system-OpenBSD-5.4 5.4 +-.ds doc-operating-system-OpenBSD-5.5 5.5 +-.ds doc-operating-system-OpenBSD-5.6 5.6 +-. +-.ds doc-operating-system-FreeBSD-1.0 1.0 +-.ds doc-operating-system-FreeBSD-1.1 1.1 +-.ds doc-operating-system-FreeBSD-1.1.5 1.1.5 +-.ds doc-operating-system-FreeBSD-1.1.5.1 1.1.5.1 +-.ds doc-operating-system-FreeBSD-2.0 2.0 +-.ds doc-operating-system-FreeBSD-2.0.5 2.0.5 +-.ds doc-operating-system-FreeBSD-2.1 2.1 +-.ds doc-operating-system-FreeBSD-2.1.5 2.1.5 +-.ds doc-operating-system-FreeBSD-2.1.6 2.1.6 +-.ds doc-operating-system-FreeBSD-2.1.7 2.1.7 +-.ds doc-operating-system-FreeBSD-2.2 2.2 +-.ds doc-operating-system-FreeBSD-2.2.1 2.2.1 +-.ds doc-operating-system-FreeBSD-2.2.2 2.2.2 +-.ds doc-operating-system-FreeBSD-2.2.5 2.2.5 +-.ds doc-operating-system-FreeBSD-2.2.6 2.2.6 +-.ds doc-operating-system-FreeBSD-2.2.7 2.2.7 +-.ds doc-operating-system-FreeBSD-2.2.8 2.2.8 +-.ds doc-operating-system-FreeBSD-2.2.9 2.2.9 +-.ds doc-operating-system-FreeBSD-3.0 3.0 +-.ds doc-operating-system-FreeBSD-3.1 3.1 +-.ds doc-operating-system-FreeBSD-3.2 3.2 +-.ds doc-operating-system-FreeBSD-3.3 3.3 +-.ds doc-operating-system-FreeBSD-3.4 3.4 +-.ds doc-operating-system-FreeBSD-3.5 3.5 +-.ds doc-operating-system-FreeBSD-4.0 4.0 +-.ds doc-operating-system-FreeBSD-4.1 4.1 +-.ds doc-operating-system-FreeBSD-4.1.1 4.1.1 +-.ds doc-operating-system-FreeBSD-4.2 4.2 +-.ds doc-operating-system-FreeBSD-4.3 4.3 +-.ds doc-operating-system-FreeBSD-4.4 4.4 +-.ds doc-operating-system-FreeBSD-4.5 4.5 +-.ds doc-operating-system-FreeBSD-4.6 4.6 +-.ds doc-operating-system-FreeBSD-4.6.2 4.6.2 +-.ds doc-operating-system-FreeBSD-4.7 4.7 +-.ds doc-operating-system-FreeBSD-4.8 4.8 +-.ds doc-operating-system-FreeBSD-4.9 4.9 +-.ds doc-operating-system-FreeBSD-4.10 4.10 +-.ds doc-operating-system-FreeBSD-4.11 4.11 +-.ds doc-operating-system-FreeBSD-5.0 5.0 +-.ds doc-operating-system-FreeBSD-5.1 5.1 +-.ds doc-operating-system-FreeBSD-5.2 5.2 +-.ds doc-operating-system-FreeBSD-5.2.1 5.2.1 +-.ds doc-operating-system-FreeBSD-5.3 5.3 +-.ds doc-operating-system-FreeBSD-5.4 5.4 +-.ds doc-operating-system-FreeBSD-5.5 5.5 +-.ds doc-operating-system-FreeBSD-6.0 6.0 +-.ds doc-operating-system-FreeBSD-6.1 6.1 +-.ds doc-operating-system-FreeBSD-6.2 6.2 +-.ds doc-operating-system-FreeBSD-6.3 6.3 +-.ds doc-operating-system-FreeBSD-6.4 6.4 +-.ds doc-operating-system-FreeBSD-7.0 7.0 +-.ds doc-operating-system-FreeBSD-7.1 7.1 +-.ds doc-operating-system-FreeBSD-7.2 7.2 +-.ds doc-operating-system-FreeBSD-7.3 7.3 +-.ds doc-operating-system-FreeBSD-7.4 7.4 +-.ds doc-operating-system-FreeBSD-8.0 8.0 +-.ds doc-operating-system-FreeBSD-8.1 8.1 +-.ds doc-operating-system-FreeBSD-8.2 8.2 +-.ds doc-operating-system-FreeBSD-8.3 8.3 +-.ds doc-operating-system-FreeBSD-8.4 8.4 +-.ds doc-operating-system-FreeBSD-9.0 9.0 +-.ds doc-operating-system-FreeBSD-9.1 9.1 +-.ds doc-operating-system-FreeBSD-9.2 9.2 +-.ds doc-operating-system-FreeBSD-9.3 9.3 +-.ds doc-operating-system-FreeBSD-10.0 10.0 +-. +-.ds doc-operating-system-Darwin-8.0.0 8.0.0 +-.ds doc-operating-system-Darwin-8.1.0 8.1.0 +-.ds doc-operating-system-Darwin-8.2.0 8.2.0 +-.ds doc-operating-system-Darwin-8.3.0 8.3.0 +-.ds doc-operating-system-Darwin-8.4.0 8.4.0 +-.ds doc-operating-system-Darwin-8.5.0 8.5.0 +-.ds doc-operating-system-Darwin-8.6.0 8.6.0 +-.ds doc-operating-system-Darwin-8.7.0 8.7.0 +-.ds doc-operating-system-Darwin-8.8.0 8.8.0 +-.ds doc-operating-system-Darwin-8.9.0 8.9.0 +-.ds doc-operating-system-Darwin-8.10.0 8.10.0 +-.ds doc-operating-system-Darwin-8.11.0 8.11.0 +-.ds doc-operating-system-Darwin-9.0.0 9.0.0 +-.ds doc-operating-system-Darwin-9.1.0 9.1.0 +-.ds doc-operating-system-Darwin-9.2.0 9.2.0 +-.ds doc-operating-system-Darwin-9.3.0 9.3.0 +-.ds doc-operating-system-Darwin-9.4.0 9.4.0 +-.ds doc-operating-system-Darwin-9.5.0 9.5.0 +-.ds doc-operating-system-Darwin-9.6.0 9.6.0 +-.ds doc-operating-system-Darwin-9.7.0 9.7.0 +-.ds doc-operating-system-Darwin-9.8.0 9.8.0 +-.ds doc-operating-system-Darwin-10.0.0 10.0.0 +-.ds doc-operating-system-Darwin-10.1.0 10.1.0 +-.ds doc-operating-system-Darwin-10.2.0 10.2.0 +-.ds doc-operating-system-Darwin-10.3.0 10.3.0 +-.ds doc-operating-system-Darwin-10.4.0 10.4.0 +-.ds doc-operating-system-Darwin-10.5.0 10.5.0 +-.ds doc-operating-system-Darwin-10.6.0 10.6.0 +-.ds doc-operating-system-Darwin-10.7.0 10.7.0 +-.ds doc-operating-system-Darwin-10.8.0 10.8.0 +-.ds doc-operating-system-Darwin-11.0.0 11.0.0 +-.ds doc-operating-system-Darwin-11.1.0 11.1.0 +-.ds doc-operating-system-Darwin-11.2.0 11.2.0 +-.ds doc-operating-system-Darwin-11.3.0 11.3.0 +-.ds doc-operating-system-Darwin-11.4.0 11.4.0 +-.ds doc-operating-system-Darwin-11.5.0 11.5.0 +-.ds doc-operating-system-Darwin-12.0.0 12.0.0 +-.ds doc-operating-system-Darwin-12.1.0 12.1.0 +-.ds doc-operating-system-Darwin-12.2.0 12.2.0 +-.ds doc-operating-system-Darwin-13.0.0 13.0.0 +-.ds doc-operating-system-Darwin-13.1.0 13.1.0 +-.ds doc-operating-system-Darwin-13.2.0 13.2.0 +-.ds doc-operating-system-Darwin-13.3.0 13.3.0 +-.ds doc-operating-system-Darwin-13.4.0 13.4.0 +-.ds doc-operating-system-Darwin-14.0.0 14.0.0 +-. +-.ds doc-operating-system-DragonFly-1.0 1.0 +-.ds doc-operating-system-DragonFly-1.1 1.1 +-.ds doc-operating-system-DragonFly-1.2 1.2 +-.ds doc-operating-system-DragonFly-1.3 1.3 +-.ds doc-operating-system-DragonFly-1.4 1.4 +-.ds doc-operating-system-DragonFly-1.5 1.5 +-.ds doc-operating-system-DragonFly-1.6 1.6 +-.ds doc-operating-system-DragonFly-1.7 1.7 +-.ds doc-operating-system-DragonFly-1.8 1.8 +-.ds doc-operating-system-DragonFly-1.8.1 1.8.1 +-.ds doc-operating-system-DragonFly-1.9 1.9 +-.ds doc-operating-system-DragonFly-1.10 1.10 +-.ds doc-operating-system-DragonFly-1.11 1.11 +-.ds doc-operating-system-DragonFly-1.12 1.12 +-.ds doc-operating-system-DragonFly-1.12.2 1.12.2 +-.ds doc-operating-system-DragonFly-1.13 1.13 +-.ds doc-operating-system-DragonFly-2.0 2.0 +-.ds doc-operating-system-DragonFly-2.1 2.1 +-.ds doc-operating-system-DragonFly-2.2 2.2 +-.ds doc-operating-system-DragonFly-2.3 2.3 +-.ds doc-operating-system-DragonFly-2.4 2.4 +-.ds doc-operating-system-DragonFly-2.5 2.5 +-.ds doc-operating-system-DragonFly-2.6 2.6 +-.ds doc-operating-system-DragonFly-2.7 2.7 +-.ds doc-operating-system-DragonFly-2.8 2.8 +-.ds doc-operating-system-DragonFly-2.9 2.9 +-.ds doc-operating-system-DragonFly-2.9.1 2.9.1 +-.ds doc-operating-system-DragonFly-2.10 2.10 +-.ds doc-operating-system-DragonFly-2.10.1 2.10.1 +-.ds doc-operating-system-DragonFly-2.11 2.11 +-.ds doc-operating-system-DragonFly-2.12 2.12 +-.ds doc-operating-system-DragonFly-2.13 2.13 +-.ds doc-operating-system-DragonFly-3.0 3.0 +-.ds doc-operating-system-DragonFly-3.1 3.1 +-.ds doc-operating-system-DragonFly-3.2 3.2 +-.ds doc-operating-system-DragonFly-3.3 3.3 +-.ds doc-operating-system-DragonFly-3.4 3.4 +-.ds doc-operating-system-DragonFly-3.5 3.5 +-.ds doc-operating-system-DragonFly-3.6 3.6 +-.ds doc-operating-system-DragonFly-3.7 3.7 +-.ds doc-operating-system-DragonFly-3.8 3.8 +-. +-.de Os +-. ds doc-command-name +-. +-. ie "\$1"" \ +-. ds doc-operating-system "\*[doc-default-operating-system] +-. el \{ .ie "\$1"ATT" \{\ +-. ds doc-operating-system AT&T +-. if \A\$2 \{\ +-. ie d doc-operating-system-ATT-\$2 \ +-. as doc-operating-system " \*[doc-operating-system-ATT-\$2] +-. el \ +-. as doc-operating-system " UNIX +-. \}\} +-. el \{ .ie "\$1"BSD" \{\ +-. if \A\$2 \{\ +-. ie d doc-operating-system-BSD-\$2 \ +-. ds doc-operating-system "\*[doc-operating-system-BSD-\$2] +-. el \ +-. tm mdoc warning: .Os: Unknown BSD version `\$2' (#\n[.c]) +-. \}\} +-. el \{ .ie "\$1"FreeBSD" \{\ +-. ds doc-operating-system FreeBSD +-. if \A\$2 \{\ +-. ie d doc-operating-system-FreeBSD-\$2 \ +-. as doc-operating-system \~\*[doc-operating-system-FreeBSD-\$2] +-. el \ +-. tm mdoc warning: .Os: Unknown FreeBSD version `\$2' (#\n[.c]) +-. \}\} +-. el \{ .ie "\$1"DragonFly" \{\ +-. ds doc-operating-system DragonFly +-. if \A\$2 \{\ +-. ie d doc-operating-system-DragonFly-\$2 \ +-. as doc-operating-system \~\*[doc-operating-system-DragonFly-\$2] +-. el \ +-. tm mdoc warning: .Os: Unknown DragonFly version `\$2' (#\n[.c]) +-. \}\} +-. el \{ .ie "\$1"NetBSD" \{\ +-. ds doc-operating-system NetBSD +-. if \A\$2 \{\ +-. ie d doc-operating-system-NetBSD-\$2 \ +-. as doc-operating-system \~\*[doc-operating-system-NetBSD-\$2] +-. el \ +-. tm mdoc warning: .Os: Unknown NetBSD version `\$2' (#\n[.c]) +-. \}\} +-. el \{ .ie "\$1"OpenBSD" \{\ +-. ds doc-operating-system OpenBSD +-. if \A\$2 \{\ +-. ie d doc-operating-system-OpenBSD-\$2 \ +-. as doc-operating-system \~\*[doc-operating-system-OpenBSD-\$2] +-. el \ +-. tm mdoc warning: .Os: Unknown OpenBSD version `\$2' (#\n[.c]) +-. \}\} +-. el \{ .ie "\$1"Darwin" \{\ +-. ds doc-operating-system Darwin +-. if \A\$2 \{\ +-. ie d doc-operating-system-Darwin-\$2 \ +-. as doc-operating-system \~\*[doc-operating-system-Darwin-\$2] +-. el \ +-. tm mdoc warning: .Os: Unknown Darwin version `\$2' (#\n[.c]) +-. \}\} +-. el \{\ +-. ds doc-operating-system \$1 +-. if !"\$2"" \ +-. as doc-operating-system " \$2 +-. \}\}\}\}\}\}\}\} +-.. +-. +-. +-.\" NS doc-date-string global string +-.\" NS the manual page date as set by `Dd' +-. +-.ds doc-date-string +-. +-. +-.\" NS Dd user macro (not parsed, not callable) +-.\" NS set document date +-.\" NS +-.\" NS modifies: +-.\" NS doc-date-string +-.\" NS doc-command-name +-.\" NS +-.\" NS local variables: +-.\" NS doc-date-XXX +-.\" NS +-.\" NS width register `Dd' set above +-. +-.ds doc-date-1 January +-.ds doc-date-2 February +-.ds doc-date-3 March +-.ds doc-date-4 April +-.ds doc-date-5 May +-.ds doc-date-6 June +-.ds doc-date-7 July +-.ds doc-date-8 August +-.ds doc-date-9 September +-.ds doc-date-10 October +-.ds doc-date-11 November +-.ds doc-date-12 December +-. +-.de Dd +-. ds doc-command-name +-. +-. ie \n[.$] \{\ +-. ie "\$1"$Mdocdate:" \ +-. ds doc-date-string \$2\~\$3, \$4 +-. el .ie (\n[.$] == 3) \ +-. ds doc-date-string \$1\~\$2 \$3 +-. el \{\ +-. ds doc-date-string "\*[doc-date-\n[mo]] +-. as doc-date-string \~\n[dy], \n[year] +-. \} +-. \} +-. el \ +-. ds doc-date-string Epoch +-.. +-. +-. +-.\" NS doc-hyphen-flags global register +-.\" NS the parameter for the `.hy' request +-.\" NS +-.\" NS override this in `mdoc.local', if necessary. +-. +-.nr doc-hyphen-flags 12 +-. +-. +-.\" NS doc-header macro +-.\" NS print page header +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dh +-.\" NS doc-reg-dh1 +-. +-.de doc-header +-. ev doc-env-dh +-. doc-setup-page-layout +-. if !\n[cR] \ +-. sp \n[doc-header-space]u +-. nr doc-reg-dh \w'\*[doc-caption-font]\*[doc-header-string]\f[]' +-. nr doc-reg-dh1 \w'\*[doc-caption-font2]\*[doc-volume]\f[]' +-. if (\n[doc-reg-dh] + \n[doc-reg-dh1] + \n[doc-reg-dh] >= \n[.lt]) \{\ +-. while (\n[doc-reg-dh] + \n[doc-reg-dh1] + \n[doc-reg-dh] >= \n[.lt]) \{\ +-. substring doc-header-string 0 -2 +-. nr doc-reg-dh \w'\*[doc-caption-font]\*[doc-header-string]\|.\|.\|.\f[]' +-. \} +-. as doc-header-string "\|.\|.\|. +-. \} +-. tl \*[doc-caption-font]\*[doc-header-string]\f[]\*[doc-caption-font2]\*[doc-volume]\f[]\*[doc-caption-font]\*[doc-header-string]\f[] +-. ie !\n[cR] \ +-. sp \n[doc-header-space]u +-. el \ +-. sp 1v +-. ev +-. ns +-.. +-. +-. +-.\" NS doc-footer macro +-.\" NS print page footer +-. +-.de doc-footer +-. ie \n[cR] \ +-. br +-. el \{\ +-. ev doc-caption-enviroment +-. doc-setup-page-layout +-. sp \n[doc-footer-space]u +-. ie \n[D] \{\ +-. ie o \ +-. tl %\*[doc-caption-font2]\*[doc-date-string]\f[]\*[doc-caption-font]\*[doc-operating-system]\f[] +-. el \ +-. tl \*[doc-caption-font]\*[doc-operating-system]\f[]\*[doc-caption-font2]\*[doc-date-string]\f[]% +-. \} +-. el \ +-. tl \*[doc-caption-font]\*[doc-operating-system]\f[]\*[doc-caption-font2]\*[doc-date-string]\f[]% +-. bp +-. ev +-. \} +-.. +-. +-. +-.\" NS doc-check-depth macro +-.\" NS check paired macros +-. +-.de doc-check-depth +-. if \n[doc-list-depth] \{\ +-. tm mdoc warning: A .Bl directive has no matching .El (#\n[.c]) +-. nr doc-list-depth 0 +-. \} +-. if \n[doc-display-depth] \{\ +-. tm mdoc warning: A .Bd directive has no matching .Ed (#\n[.c]) +-. nr doc-display-depth 0 +-. \} +-. if \n[doc-fontmode-depth] \{\ +-. tm mdoc warning: A .Bf directive has no matching .Ef (#\n[.c]) +-. nr doc-fontmode-depth 0 +-. \} +-.. +-. +-. +-.\" NS doc-end-macro macro +-.\" NS finish output +-. +-.de doc-end-macro +-. \" We may still have a partial line in the environment. If this is the +-. \" case, and we happen to be on the last line of the page, the `.fl' +-. \" request will cause the page to be ejected and troff will immediately +-. \" exit. If we are in nroff mode, this would be unfortunate, since we +-. \" would never get a chance to output the footer. So we fudge the page +-. \" length to make sure that the last page is never ejected until we want +-. \" it to be. +-. +-. if \n[cR] \ +-. pl +3v +-. fl +-. +-. doc-check-depth +-. +-. if \n[cR] \{\ +-. sp +-. tl \*[doc-caption-font]\*[doc-operating-system]\f[]\*[doc-caption-font2]\*[doc-date-string]\f[]\*[doc-caption-font]\*[doc-operating-system]\f[] +-. \" suppress empty lines after the footer +-. pl \n[nl]u +-. \} +-.. +-. +-. +-.\" NS doc-paragraph macro +-.\" NS insert a paragraph +-. +-.de doc-paragraph +-. sp \n[doc-paragraph-space]u +-. if !\n[cR] \ +-. ne 2 +-. ns +-.. +-. +-. +-.\" NS Pp user macro (not parsed, not callable) +-.\" NS new paragraph +-.\" NS +-.\" NS width register `Pp' set above +-. +-.als Pp doc-paragraph +-. +-. +-.\" NS Lp user macro (not parsed, not callable) +-.\" NS same as .Pp +-.\" NS +-.\" NS width register `Lp' set above +-. +-.als Lp doc-paragraph +-. +-. +-.de LP +-. tm Not a \-mdoc command: .LP (#\n[.c]) +-.. +-. +-. +-.de PP +-. tm Not a \-mdoc command: .PP (#\n[.c]) +-.. +-. +-. +-.de pp +-. tm Not a \-mdoc command: .pp (#\n[.c]) +-.. +-. +-. +-.de SH +-. tm Not a \-mdoc command: .SH (#\n[.c]) +-.. +-. +-. +-.\" NS Nd user macro (not parsed, not callable) +-.\" NS print name description +-.\" NS +-.\" NS width register `Nd' set above +-. +-.de Nd +-. nop \[em] \$* +-.. +-. +-. +-.\" NS doc-in-synopsis-section global register (bool) +-.\" NS whether we are in the `synopsis' section +-. +-.nr doc-in-synopsis-section 0 +-. +-. +-.\" NS doc-in-library-section global register (bool) +-.\" NS whether we are in the `library' section +-. +-.nr doc-in-library-section 0 +-. +-. +-.\" NS doc-in-see-also-section global register (bool) +-.\" NS whether we are in the `see also' section +-. +-.nr doc-in-see-also-section 0 +-. +-. +-.\" NS doc-in-files-section global register (bool) +-.\" NS whether we are in the `files' section +-. +-.nr doc-in-files-section 0 +-. +-. +-.\" NS doc-in-authors-section global register (bool) +-.\" NS whether we are in the `authors' section +-. +-.nr doc-in-authors-section 0 +-. +-. +-.\" NS doc-first-parameter macro +-.\" NS return first parameter +-.\" NS +-.\" NS local variables: +-.\" NS doc-str-dfp +-. +-.de doc-first-parameter +-. ds doc-str-dfp "\$1 +-.. +-. +-. +-.\" NS Sh user macro (not callable) +-.\" NS section headers +-.\" NS +-.\" NS modifies: +-.\" NS doc-func-args-processed +-.\" NS doc-func-count +-.\" NS doc-in-authors-section +-.\" NS doc-in-files-section +-.\" NS doc-in-library-section +-.\" NS doc-in-see-also-section +-.\" NS doc-in-synopsis-section +-.\" NS doc-indent-synopsis +-.\" NS doc-indent-synopsis-active +-.\" NS doc-is-func +-.\" NS doc-num-func-args +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-Sh +-.\" NS doc-reg-Sh1 +-.\" NS doc-section-XXX +-.\" NS +-.\" NS width register `Sh' set in doc-common +-. +-.ds doc-section-name NAME +-.ds doc-section-synopsis SYNOPSIS +-.ds doc-section-library LIBRARY +-.ds doc-section-description DESCRIPTION +-.ds doc-section-see-also SEE +-.ds doc-section-files FILES +-.ds doc-section-authors AUTHORS +-. +-.de Sh +-. ie \n[doc-arg-limit] \{\ +-. \" we only allow `Sh' within `Sh'; it will change the font back to +-. \" `doc-Sh-font' +-. ie "\*[doc-macro-name]"Sh" \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Sh-font]\c +-. doc-print-recursive +-. \} +-. el \{\ +-. tm Usage: .Sh section_name ... (#\n[.c]) +-. doc-reset-args +-. \}\} +-. el \{\ +-. tm Usage: .Sh not callable by other macros (#\n[.c]) +-. doc-reset-args +-. \}\} +-. el \{\ +-. if !\n[.$] \{\ +-. tm Usage: .Sh section_name ... (#\n[.c]) +-. return +-. \} +-. +-. ds doc-macro-name Sh +-. doc-parse-args \$@ +-. +-. if t \ +-. ad +-. +-. \" this resolves e.g. `.Sh "SEE ALSO"' +-. doc-first-parameter \$* +-. +-. ie "\*[doc-str-dfp]"\*[doc-section-name]" \{\ +-. doc-setup-header +-. in 0 +-. \} +-. el \{\ +-. nr doc-in-synopsis-section 0 +-. nr doc-in-library-section 0 +-. nr doc-in-see-also-section 0 +-. nr doc-in-files-section 0 +-. nr doc-in-authors-section 0 +-. +-. ie "\*[doc-str-dfp]"\*[doc-section-synopsis]" \{\ +-. if t \ +-. na +-. nr doc-in-synopsis-section 1 +-. nr doc-indent-synopsis 0 +-. nr doc-indent-synopsis-active 0 +-. \} +-. el \{ .ie "\*[doc-str-dfp]"\*[doc-section-library]" \{\ +-. nr doc-in-library-section 1 +-. \} +-. el \{ .ie "\*[doc-str-dfp]"\*[doc-section-description]" \{\ +-. nr doc-is-func 0 +-. nr doc-func-count 0 +-. nr doc-func-args-processed 0 +-. nr doc-num-func-args 0 +-. \} +-. el \{ .ie "\*[doc-str-dfp]"\*[doc-section-see-also]" \{\ +-. if t \ +-. na +-. nr doc-in-see-also-section 1 +-. \} +-. el \{ .ie "\*[doc-str-dfp]"\*[doc-section-files]" \ +-. nr doc-in-files-section 1 +-. el .if "\*[doc-str-dfp]"\*[doc-section-authors]" \ +-. nr doc-in-authors-section 1 +-. \}\}\}\} +-. +-. in 0 +-. nr doc-have-author 0 +-. \} +-. +-. doc-setup-page-layout +-. sp +-. ns +-. ta T .5i +-. if !\n[cR] \ +-. ne 3 +-. fi +-. +-. if t \{\ +-. nr doc-reg-Sh \n[.ss] +-. nr doc-reg-Sh1 \n[.sss] +-. ss (\n[.ss] * 5 / 3) (\n[.sss] * 5 / 3) +-. \} +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Sh-font]\c +-. doc-print-recursive +-. +-. if t \ +-. ss \n[doc-reg-Sh] \n[doc-reg-Sh1] +-. +-. in +\n[doc-subheader-indent]u +-. ns +-. +-. doc-check-depth +-. \} +-.. +-. +-. +-.\" NS Ss user macro (not callable) +-.\" NS subsection +-.\" NS +-.\" NS local variable: +-.\" NS doc-reg-Ss +-.\" NS doc-reg-Ss1 +-.\" NS +-.\" NS width register `Ss' set above +-. +-.de Ss +-. ie \n[doc-arg-limit] \{\ +-. \" we only allow `Ss' within `Ss'; it will change the font back to +-. \" `doc-Sh-font' +-. ie "\*[doc-macro-name]"Ss" \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Sh-font]\c +-. doc-print-recursive +-. \} +-. el \{\ +-. tm Usage: .Ss subsection_name ... (#\n[.c]) +-. doc-reset-args +-. \}\} +-. el \{\ +-. tm Usage: .Ss not callable by other macros (#\n[.c]) +-. doc-reset-args +-. \}\} +-. el \{\ +-. if !\n[.$] \{\ +-. tm Usage: .Ss subsection_name ... (#\n[.c]) +-. return +-. \} +-. +-. ds doc-macro-name Ss +-. doc-parse-args \$@ +-. +-. sp +-. if !\n[cR] \ +-. ne 3 +-. ti -.25i +-. +-. nr doc-reg-Ss \n[.ss] +-. nr doc-reg-Ss1 \n[.sss] +-. ss (\n[.ss] * 5 / 4) (\n[.sss] * 5 / 4) +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Sh-font]\c +-. doc-print-recursive +-. +-. ss \n[doc-reg-Ss] \n[doc-reg-Ss1] +-. +-. ta T .5i +-. if !\n[cR] \ +-. ne 2 +-. br +-. ns +-. +-. doc-check-depth +-. \} +-.. +-. +-. +-.\" NS Rd macro (not parsed, not callable) +-.\" NS print global register dump to stderr +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-Rd +-. +-.de Rd +-. tm MDOC GLOBAL REGISTER DUMP +-. tm doc-macro-name == `\*[doc-macro-name]' +-. tm doc-arg-limit == \n[doc-arg-limit] +-. tm doc-num-args == \n[doc-num-args] +-. tm doc-arg-ptr == \n[doc-arg-ptr] +-. +-. nr doc-reg-Rd 1 +-. while (\n[doc-reg-Rd] <= \n[doc-arg-limit]) \{\ +-. tm doc-arg\n[doc-reg-Rd] == `\*[doc-arg\n[doc-reg-Rd]]' +-. tm doc-type\n[doc-reg-Rd] == \n[doc-type\n[doc-reg-Rd]] +-. tm doc-space\n[doc-reg-Rd] == `\*[doc-space\n[doc-reg-Rd]]' +-. nr doc-reg-Rd +1 +-. \} +-. +-. tm doc-curr-font == \n[doc-curr-font] +-. tm doc-curr-size == \n[doc-curr-size] +-. tm doc-indent-synopsis == \n[doc-indent-synopsis] +-. tm doc-indent-synopsis-active == \n[doc-indent-synopsis-active] +-. tm doc-have-decl == \n[doc-have-decl] +-. tm doc-have-var == \n[doc-have-var] +-. tm doc-command-name == `\*[doc-command-name]' +-. tm doc-quote-left == `\*[doc-quote-left]' +-. tm doc-quote-right == `\*[doc-quote-right]' +-. tm doc-nesting-level == \n[doc-nesting-level] +-. tm doc-in-list == \n[doc-in-list] +-. tm doc-space == `\*[doc-space]' +-. tm doc-saved-space == `\*[doc-saved-space]' +-. tm doc-space-mode == \n[doc-space-mode] +-. tm doc-have-space == \n[doc-have-space] +-. tm doc-have-slot == \n[doc-have-slot] +-. tm doc-keep-type == \n[doc-keep-type] +-. tm doc-display-depth == \n[doc-display-depth] +-. tm doc-is-compact == \n[doc-is-compact] +-. +-. nr doc-reg-Rd 0 +-. while (\n[doc-reg-Rd] <= \n[doc-display-depth]) \{\ +-. tm doc-display-type-stack\n[doc-reg-Rd] == `\*[doc-display-type-stack\n[doc-reg-Rd]]' +-. tm doc-display-indent-stack\n[doc-reg-Rd] == \n[doc-display-indent-stack\n[doc-reg-Rd]] +-. tm doc-display-ad-stack\n[doc-reg-Rd] == \n[doc-display-ad-stack\n[doc-reg-Rd]] +-. tm doc-display-fi-stack\n[doc-reg-Rd] == \n[doc-display-fi-stack\n[doc-reg-Rd]] +-. tm doc-display-ft-stack\n[doc-reg-Rd] == \n[doc-display-ft-stack\n[doc-reg-Rd]] +-. tm doc-display-ps-stack\n[doc-reg-Rd] == \n[doc-display-ps-stack\n[doc-reg-Rd]] +-. nr doc-reg-Rd +1 +-. \} +-. +-. tm doc-fontmode-depth == \n[doc-fontmode-depth] +-. +-. nr doc-reg-Rd 1 +-. while (\n[doc-reg-Rd] <= \n[doc-fontmode-depth]) \{\ +-. tm doc-fontmode-font-stack\n[doc-reg-Rd] == `\n[doc-fontmode-font-stack\n[doc-reg-Rd]]' +-. tm doc-fontmode-size-stack\n[doc-reg-Rd] == `\n[doc-fontmode-size-stack\n[doc-reg-Rd]]' +-. nr doc-reg-Rd +1 +-. \} +-. +-. tm doc-list-depth == \n[doc-list-depth] +-. +-. nr doc-reg-Rd 1 +-. while (\n[doc-reg-Rd] <= \n[doc-list-depth]) \{\ +-. tm doc-list-type-stack\n[doc-reg-Rd] == `\*[doc-list-type-stack\n[doc-reg-Rd]]' +-. tm doc-list-have-indent-stack\n[doc-reg-Rd] == \n[doc-list-have-indent-stack\n[doc-reg-Rd]] +-. tm doc-list-indent-stack\n[doc-reg-Rd] == \n[doc-list-indent-stack\n[doc-reg-Rd]] +-. tm doc-compact-list-stack\n[doc-reg-Rd] == \n[doc-compact-list-stack\n[doc-reg-Rd]] +-. tm doc-tag-prefix-stack\n[doc-reg-Rd] == `\*[doc-tag-prefix-stack\n[doc-reg-Rd]]' +-. tm doc-tag-width-stack\n[doc-reg-Rd] == `\*[doc-tag-width-stack\n[doc-reg-Rd]]' +-. tm doc-list-offset-stack\n[doc-reg-Rd] == \n[doc-list-offset-stack\n[doc-reg-Rd]] +-. tm doc-enum-list-count-stack\n[doc-reg-Rd] == \n[doc-enum-list-count-stack\n[doc-reg-Rd]] +-. nr doc-reg-Rd +1 +-. \} +-. +-. tm doc-saved-Pa-font == `\*[doc-saved-Pa-font]' +-. tm doc-curr-type == \n[doc-curr-type] +-. tm doc-curr-arg == `\*[doc-curr-arg]' +-. tm doc-diag-list-input-line-count == \n[doc-diag-list-input-line-count] +-. tm doc-num-columns == \n[doc-num-columns] +-. tm doc-column-indent-width == \n[doc-column-indent-width] +-. tm doc-is-func == \n[doc-is-func] +-. tm doc-have-old-func == \n[doc-have-old-func] +-. tm doc-func-arg-count == \n[doc-func-arg-count] +-. tm doc-func-arg == `\*[doc-func-arg]' +-. tm doc-num-func-args == \n[doc-num-func-args] +-. tm doc-func-args-processed == \n[doc-func-args-processed] +-. tm doc-have-func == \n[doc-have-func] +-. tm doc-is-reference == \n[doc-is-reference] +-. tm doc-reference-count == \n[doc-reference-count] +-. tm doc-author-count == \n[doc-author-count] +-. +-. nr doc-reg-Rd 0 +-. while (\n[doc-reg-Rd] <= \n[doc-author-count]) \{\ +-. tm doc-author-name\n[doc-reg-Rd] == `\*[doc-author-name\n[doc-reg-Rd]]' +-. nr doc-reg-Rd +1 +-. \} +-. +-. tm doc-book-count == \n[doc-book-count] +-. tm doc-book-name == `\*[doc-book-name]' +-. tm doc-date-count == \n[doc-date-count] +-. tm doc-date == `\*[doc-date]' +-. tm doc-publisher-count == \n[doc-publisher-count] +-. tm doc-publisher-name == `\*[doc-publisher-name]' +-. tm doc-journal-count == \n[doc-journal-count] +-. tm doc-journal-name == `\*[doc-journal-name]' +-. tm doc-issue-count == \n[doc-issue-count] +-. tm doc-issue-name == `\*[doc-issue-name]' +-. tm doc-optional-count == \n[doc-optional-count] +-. tm doc-optional-string == `\*[doc-optional-string]' +-. tm doc-page-number-count == \n[doc-page-number-count] +-. tm doc-page-number-string == `\*[doc-page-number-string]' +-. tm doc-corporate-count == \n[doc-corporate-count] +-. tm doc-corporate-name == `\*[doc-corporate-name]' +-. tm doc-report-count == \n[doc-report-count] +-. tm doc-report-name == `\*[doc-report-name]' +-. tm doc-reference-title-count == \n[doc-reference-title-count] +-. tm doc-reference-title-name == `\*[doc-reference-title-name]' +-. tm doc-reference-title-name-for-book == `\*[doc-reference-title-name-for-book]' +-. tm doc-url-count == \n[doc-url-count] +-. tm doc-url-name == `\*[doc-url-name]' +-. tm doc-volume-count == \n[doc-volume-count] +-. tm doc-volume-name == `\*[doc-volume-name]' +-. tm doc-have-author == \n[doc-have-author] +-. +-. tm doc-document-title == `\*[doc-document-title]' +-. tm doc-volume == `\*[doc-volume]' +-. tm doc-section == `\*[doc-section]' +-. tm doc-operating-system == `\*[doc-operating-system]' +-. tm doc-date-string == `\*[doc-date-string]' +-. tm doc-header-space == \n[doc-header-space] +-. tm doc-footer-space == \n[doc-footer-space] +-. tm doc-display-vertical == \n[doc-display-vertical] +-. tm doc-header-string == `\*[doc-header-string]' +-. tm doc-in-synopsis-section == \n[doc-in-synopsis-section] +-. tm doc-in-library-section == \n[doc-in-library-section] +-. tm doc-in-see-also-section == \n[doc-in-see-also-section] +-. tm doc-in-files-section == \n[doc-in-files-section] +-. tm doc-in-authors-section == \n[doc-in-authors-section] +-. +-. tm END OF GLOBAL REGISTER DUMP +-.. +-. +-. +-.ec +-. +-.\" EOF +diff -Nuar groff-1.22.3.old/tmac/doc-common-u groff-1.22.3/tmac/doc-common-u +--- groff-1.22.3.old/tmac/doc-common-u 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/doc-common-u 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,1376 @@ ++.\" -*- nroff -*- ++.\" ++.\" Copyright (c) 1991, 1993 ++.\" The Regents of the University of California. All rights reserved. ++.\" ++.\" Redistribution and use in source and binary forms, with or without ++.\" modification, are permitted provided that the following conditions ++.\" are met: ++.\" 1. Redistributions of source code must retain the above copyright ++.\" notice, this list of conditions and the following disclaimer. ++.\" 2. Redistributions in binary form must reproduce the above copyright ++.\" notice, this list of conditions and the following disclaimer in the ++.\" documentation and/or other materials provided with the distribution. ++.\" 3. [Deleted. See ++.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] ++.\" 4. Neither the name of the University nor the names of its contributors ++.\" may be used to endorse or promote products derived from this software ++.\" without specific prior written permission. ++.\" ++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++.\" SUCH DAMAGE. ++.\" ++.\" @(#)doc-common 8.1 (Berkeley) 06/08/93 ++.\" ++.\" %beginstrip% ++. ++. ++.\" Macro Identifiers. For each user macro a corresponding register with ++.\" the same name must exist. Its value must not be zero. ++. ++.nr %A 1 ++.nr %B 1 ++.nr %C 1 ++.nr %D 1 ++.nr %I 1 ++.nr %J 1 ++.nr %N 1 ++.nr %O 1 ++.nr %P 1 ++.nr %Q 1 ++.nr %R 1 ++.nr %T 1 ++.nr %U 1 ++.nr %V 1 ++.nr Ac 3 ++.nr Ad 12n ++.nr An 12n ++.nr Ao 12n ++.nr Ap 2 ++.nr Aq 12n ++.nr Ar 12n ++.nr At 1 ++.nr Bc 3 ++.nr Bf 8n\" ? ++.nr Bk 8n\" ? ++.nr Bl 1 ++.nr Bo 12n ++.nr Bq 12n ++.nr Brc 3 ++.nr Bro 12n ++.nr Brq 12n ++.nr Bsx 1 ++.nr Bt 8n\" ? ++.nr Bx 1 ++.nr Cd 12n ++.nr Cm 10n ++.nr D1 8n\" ? ++.nr Dc 3 ++.nr Dl 8n\" ? ++.nr Dt 8n\" ? ++.nr Do 12n ++.nr Dq 12n ++.nr Ds 6n\" many manpages still use this as a -width value ++.nr Dv 12n ++.nr Dx 1 ++.nr Ec 3 ++.nr Ef 8n\" ? ++.nr Ek 8n\" ? ++.nr El 1 ++.nr Em 10n ++.nr En 12n ++.nr Eo 12n ++.nr Eq 12n ++.nr Er 17n ++.nr Es 12n ++.nr Ev 15n ++.nr Ex 1 ++.nr Fa 12n ++.nr Fc 3 ++.nr Fd 12n\" ? ++.nr Fl 10n ++.nr Fn 16n ++.nr Fo 16n ++.nr Fr 12n\" ? ++.nr Ft 8n\" ? ++.nr Fx 1 ++.nr Ic 10n ++.nr In 12n ++.nr It 8n\" ? ++.nr Lb 11n ++.nr Li 16n ++.nr Lk 6n\" ? ++.nr Lp 8n\" ? ++.nr Me 6n ++.nr Ms 6n ++.nr Mt 6n\" ? ++.nr Nd 8n\" ? ++.nr Nm 10n ++.nr No 12n ++.nr Ns 2 ++.nr Nx 1 ++.nr Oc 3 ++.nr Oo 10n ++.nr Op 14n ++.nr Os 6n\" ? ++.nr Ox 1 ++.nr Pa 32n ++.nr Pc 3 ++.nr Pf 12n ++.nr Po 12n ++.nr Pp 8n\" ? ++.nr Pq 12n ++.nr Qc 3 ++.nr Ql 16n ++.nr Qo 12n ++.nr Qq 12n ++.nr Rv 1 ++.nr Sc 3 ++.nr Sh 8n ++.nr Sm 8n\" ? ++.nr So 12n ++.nr Sq 12n ++.nr Ss 8n ++.nr St 8n\" ? ++.nr Sx 16n ++.nr Sy 6n ++.nr Ta 2 ++.nr Tn 10n ++.nr Ud 8n\" ? ++.nr Ux 1 ++.nr Va 12n ++.nr Vt 8n\" ? ++.nr Xc 3 ++.nr Xo 1 ++.nr Xr 10n ++. ++. ++.\" macros which must be processed after the closing delimiter of `Op' ++.\" and friends ++.ds doc-after-Ao ++.ds doc-after-Bo ++.ds doc-after-Bro ++.ds doc-after-Do ++.ds doc-after-Eo ++.ds doc-after-Fo ++.ds doc-after-Ns ++.ds doc-after-Oo ++.ds doc-after-Po ++.ds doc-after-Qo ++.ds doc-after-So ++.ds doc-after-Xo ++. ++. ++.nr doc-display-indent 6n ++. ++. ++.\" space strings ++. ++.ds doc-soft-space " \" ++.ds doc-hard-space \~ ++.ds doc-tab \t ++. ++. ++.eo ++. ++. ++.\" punctuation values (suffix=3, prefix=4) ++. ++.nr doc-punct. 3 ++.nr doc-punct, 3 ++.nr doc-punct: 3 ++.nr doc-punct; 3 ++.nr doc-punct( 4 ++.nr doc-punct) 3 ++.nr doc-punct[ 4 ++.nr doc-punct] 3 ++.nr doc-punct? 3 ++.nr doc-punct! 3 ++. ++. ++.\" header assembly macros ++. ++.\" NS doc-document-title global string ++.\" NS the title of the manual page ++. ++.ds doc-document-title UNTITLED ++. ++. ++.\" NS doc-volume global string ++.\" NS the volume where the manual page belongs to ++. ++.ds doc-volume LOCAL ++. ++. ++.\" NS doc-section global string ++.\" NS the manual section ++. ++.ds doc-section Null ++. ++. ++.\" NS Dt user macro (not parsed, not callable) ++.\" NS document title ++.\" NS ++.\" NS modifies: ++.\" NS doc-document-title ++.\" NS doc-section ++.\" NS doc-volume ++.\" NS doc-command-name ++.\" NS ++.\" NS local variables: ++.\" NS doc-volume-as-XXX ++.\" NS doc-volume-ds-XXX ++.\" NS ++.\" NS width register `Dt' set above ++. ++.\" an alternative, more detailed scheme for naming the manual sections ++.\" ++.ds doc-volume-operating-system BSD ++.nr doc-volume-operating-system-ateol 0 ++.ds doc-volume-ds-1 General Commands Manual ++.ds doc-volume-ds-2 System Calls Manual ++.ds doc-volume-ds-3 Library Functions Manual ++.ds doc-volume-ds-4 Kernel Interfaces Manual ++.ds doc-volume-ds-5 File Formats Manual ++.ds doc-volume-ds-6 Games Manual ++.ds doc-volume-ds-7 Miscellaneous Information Manual ++.ds doc-volume-ds-8 System Manager's Manual ++.ds doc-volume-ds-9 Kernel Developer's Manual ++. ++.ds doc-volume-ds-USD User's Supplementary Documents ++.ds doc-volume-ds-PS1 Programmer's Supplementary Documents ++.ds doc-volume-ds-AMD Ancestral Manual Documents ++.ds doc-volume-ds-SMM System Manager's Manual ++.ds doc-volume-ds-URM User's Reference Manual ++.ds doc-volume-ds-PRM Programmer's Manual ++.ds doc-volume-ds-KM Kernel Manual ++.ds doc-volume-ds-IND Manual Master Index ++.ds doc-volume-ds-LOCAL Local Manual ++.ds doc-volume-ds-CON Contributed Software Manual ++. ++.als doc-volume-ds-MMI doc-volume-ds-IND ++.als doc-volume-ds-LOC doc-volume-ds-LOCAL ++. ++.ds doc-volume-as-alpha alpha ++.als doc-volume-as-Alpha doc-volume-as-alpha ++.ds doc-volume-as-acorn26 acorn26 ++.ds doc-volume-as-acorn32 acorn32 ++.ds doc-volume-as-algor algor ++.ds doc-volume-as-amd64 amd64 ++.ds doc-volume-as-amiga amiga ++.ds doc-volume-as-amigappc amigappc ++.ds doc-volume-as-arc arc ++.ds doc-volume-as-arm arm ++.ds doc-volume-as-arm26 arm26 ++.ds doc-volume-as-arm32 arm32 ++.ds doc-volume-as-armish armish ++.ds doc-volume-as-atari atari ++.ds doc-volume-as-aviion aviion ++.ds doc-volume-as-beagle beagle ++.ds doc-volume-as-bebox bebox ++.ds doc-volume-as-cats cats ++.ds doc-volume-as-cesfic cesfic ++.ds doc-volume-as-cobalt cobalt ++.ds doc-volume-as-dreamcast dreamcast ++.ds doc-volume-as-emips emips ++.ds doc-volume-as-evbarm evbarm ++.ds doc-volume-as-evbmips evbmips ++.ds doc-volume-as-evbppc evbppc ++.ds doc-volume-as-evbsh3 evbsh3 ++.ds doc-volume-as-ews4800mips ews4800mips ++.ds doc-volume-as-hp300 hp300 ++.ds doc-volume-as-hp700 hp700 ++.ds doc-volume-as-hpcarm hpcarm ++.ds doc-volume-as-hpcmips hpcmips ++.ds doc-volume-as-hpcsh hpcsh ++.ds doc-volume-as-hppa hppa ++.ds doc-volume-as-hppa64 hppa64 ++.ds doc-volume-as-i386 i386 ++.ds doc-volume-as-ia64 ia64 ++.ds doc-volume-as-ibmnws ibmnws ++.ds doc-volume-as-iyonix iyonix ++.ds doc-volume-as-landisk landisk ++.ds doc-volume-as-loongson loongson ++.ds doc-volume-as-luna68k luna68k ++.ds doc-volume-as-luna88k luna88k ++.ds doc-volume-as-m68k m68k ++.ds doc-volume-as-mac68k mac68k ++.ds doc-volume-as-macppc macppc ++.ds doc-volume-as-mips mips ++.ds doc-volume-as-mips64 mips64 ++.ds doc-volume-as-mipsco mipsco ++.ds doc-volume-as-mmeye mmeye ++.ds doc-volume-as-mvme68k mvme68k ++.ds doc-volume-as-mvme88k mvme88k ++.ds doc-volume-as-mvmeppc mvmeppc ++.ds doc-volume-as-netwinder netwinder ++.ds doc-volume-as-news68k news68k ++.ds doc-volume-as-newsmips newsmips ++.ds doc-volume-as-next68k next68k ++.ds doc-volume-as-ofppc ofppc ++.ds doc-volume-as-palm palm ++.ds doc-volume-as-pc532 pc532 ++.ds doc-volume-as-playstation2 playstation2 ++.ds doc-volume-as-pmax pmax ++.ds doc-volume-as-pmppc pmppc ++.ds doc-volume-as-powerpc powerpc ++.ds doc-volume-as-prep prep ++.ds doc-volume-as-rs6000 rs6000 ++.ds doc-volume-as-sandpoint sandpoint ++.ds doc-volume-as-sbmips sbmips ++.ds doc-volume-as-sgi sgi ++.ds doc-volume-as-sgimips sgimips ++.ds doc-volume-as-sh3 sh3 ++.ds doc-volume-as-shark shark ++.ds doc-volume-as-socppc socppc ++.ds doc-volume-as-solbourne solbourne ++.ds doc-volume-as-sparc sparc ++.ds doc-volume-as-sparc64 sparc64 ++.ds doc-volume-as-sun2 sun2 ++.ds doc-volume-as-sun3 sun3 ++.ds doc-volume-as-tahoe tahoe ++.ds doc-volume-as-vax vax ++.ds doc-volume-as-x68k x68k ++.ds doc-volume-as-x86_64 x86_64 ++.ds doc-volume-as-xen xen ++.ds doc-volume-as-zaurus zaurus ++. ++.de Dt ++. \" reset default arguments ++. ds doc-document-title UNTITLED ++. ds doc-volume LOCAL ++. ds doc-section Null ++. ds doc-command-name ++. ++. if !"\$1"" \ ++. ds doc-document-title "\$1 ++. ++. if !"\$2"" \{\ ++. ds doc-section \$2 ++. ie \B\$2 \{\ ++. if ((\$2 >= 1) & (\$2 <= 9)) \{\ ++. ie \n[doc-volume-operating-system-ateol] \{\ ++. ds doc-volume "\*[doc-volume-ds-\$2] \*[doc-volume-operating-system] ++. if \A\$3 \{\ ++. if d doc-volume-as-\$3 \ ++. as doc-volume "/\*[doc-volume-as-\$3] ++. \}\} ++. el \{\ ++. ds doc-volume "\*[doc-volume-operating-system] ++. if \A\$3 \{\ ++. if d doc-volume-as-\$3 \ ++. as doc-volume "/\*[doc-volume-as-\$3] ++. \} ++. as doc-volume " \*[doc-volume-ds-\$2] ++. \}\}\} ++. el \{\ ++. ie "\$2"unass" \ ++. ds doc-volume DRAFT ++. el \{ .ie "\$2"draft" \ ++. ds doc-volume DRAFT ++. el .if "\$2"paper" \ ++. ds doc-volume UNTITLED ++. \}\} ++. if \A\$3 \{\ ++. if d doc-volume-ds-\$3 \ ++. ds doc-volume "\*[doc-volume-ds-\$3] ++. \}\}\} ++. ++. if !"\$3"" \ ++. if "\*[doc-volume]"LOCAL" \ ++. ds doc-volume \$3 ++. ++. if !\n[cR] \ ++. if \n[nl] \{\ ++. doc-setup-header ++. bp ++. \} ++.. ++. ++. ++.\" NS doc-default-operating-system global string ++.\" NS the exact (default) version of the operating system ++.\" NS ++.\" NS override this in `mdoc.local', if necessary ++. ++.ds doc-default-operating-system BSD ++. ++. ++.\" NS doc-operating-system global string ++.\" NS the exact version of the operating system ++. ++.ds doc-operating-system ++. ++. ++.\" NS Os user macro (not parsed, not callable) ++.\" NS operating system ++.\" NS ++.\" NS modifies: ++.\" NS doc-operating-system ++.\" NS doc-command-name ++.\" NS ++.\" NS local variables: ++.\" NS doc-operating-system-XXX-XXX ++.\" NS ++.\" NS width register `Os' set above ++. ++.ds doc-operating-system-ATT-7 7th\~Edition ++.als doc-operating-system-ATT-7th doc-operating-system-ATT-7 ++.ds doc-operating-system-ATT-3 System\~III ++.als doc-operating-system-ATT-III doc-operating-system-ATT-3 ++.ds doc-operating-system-ATT-V System\~V ++.ds doc-operating-system-ATT-V.2 System\~V Release\~2 ++.ds doc-operating-system-ATT-V.3 System\~V Release\~3 ++.ds doc-operating-system-ATT-V.4 System\~V Release\~4 ++. ++.ds doc-operating-system-BSD-3 3rd\~Berkeley Distribution ++.ds doc-operating-system-BSD-4 4th\~Berkeley Distribution ++.ds doc-operating-system-BSD-4.1 4.1\~Berkeley Distribution ++.ds doc-operating-system-BSD-4.2 4.2\~Berkeley Distribution ++.ds doc-operating-system-BSD-4.3 4.3\~Berkeley Distribution ++.ds doc-operating-system-BSD-4.3T 4.3-Tahoe Berkeley Distribution ++.ds doc-operating-system-BSD-4.3R 4.3-Reno Berkeley Distribution ++.als doc-operating-system-BSD-4.3t doc-operating-system-BSD-4.3T ++.als doc-operating-system-BSD-4.3r doc-operating-system-BSD-4.3R ++.ds doc-operating-system-BSD-4.4 4.4BSD ++. ++.ds doc-operating-system-NetBSD-0.8 0.8 ++.ds doc-operating-system-NetBSD-0.8a 0.8A ++.ds doc-operating-system-NetBSD-0.9 0.9 ++.ds doc-operating-system-NetBSD-0.9a 0.9A ++.ds doc-operating-system-NetBSD-1.0 1.0 ++.ds doc-operating-system-NetBSD-1.0a 1.0A ++.ds doc-operating-system-NetBSD-1.1 1.1 ++.ds doc-operating-system-NetBSD-1.2 1.2 ++.ds doc-operating-system-NetBSD-1.2a 1.2A ++.ds doc-operating-system-NetBSD-1.2b 1.2B ++.ds doc-operating-system-NetBSD-1.2c 1.2C ++.ds doc-operating-system-NetBSD-1.2d 1.2D ++.ds doc-operating-system-NetBSD-1.2e 1.2E ++.ds doc-operating-system-NetBSD-1.3 1.3 ++.ds doc-operating-system-NetBSD-1.3a 1.3A ++.ds doc-operating-system-NetBSD-1.4 1.4 ++.ds doc-operating-system-NetBSD-1.4.1 1.4.1 ++.ds doc-operating-system-NetBSD-1.4.2 1.4.2 ++.ds doc-operating-system-NetBSD-1.4.3 1.4.3 ++.ds doc-operating-system-NetBSD-1.5 1.5 ++.ds doc-operating-system-NetBSD-1.5.1 1.5.1 ++.ds doc-operating-system-NetBSD-1.5.2 1.5.2 ++.ds doc-operating-system-NetBSD-1.5.3 1.5.3 ++.ds doc-operating-system-NetBSD-1.6 1.6 ++.ds doc-operating-system-NetBSD-1.6.1 1.6.1 ++.ds doc-operating-system-NetBSD-1.6.2 1.6.2 ++.ds doc-operating-system-NetBSD-1.6.3 1.6.3 ++.ds doc-operating-system-NetBSD-2.0 2.0 ++.ds doc-operating-system-NetBSD-2.0.1 2.0.1 ++.ds doc-operating-system-NetBSD-2.0.2 2.0.2 ++.ds doc-operating-system-NetBSD-2.0.3 2.0.3 ++.ds doc-operating-system-NetBSD-2.1 2.1 ++.ds doc-operating-system-NetBSD-3.0 3.0 ++.ds doc-operating-system-NetBSD-3.0.1 3.0.1 ++.ds doc-operating-system-NetBSD-3.0.2 3.0.2 ++.ds doc-operating-system-NetBSD-3.0.3 3.0.3 ++.ds doc-operating-system-NetBSD-3.1 3.1 ++.ds doc-operating-system-NetBSD-3.1.1 3.1.1 ++.ds doc-operating-system-NetBSD-4.0 4.0 ++.ds doc-operating-system-NetBSD-4.0.1 4.0.1 ++.ds doc-operating-system-NetBSD-5.0 5.0 ++.ds doc-operating-system-NetBSD-5.0.1 5.0.1 ++.ds doc-operating-system-NetBSD-5.0.2 5.0.2 ++.ds doc-operating-system-NetBSD-5.1 5.1 ++.ds doc-operating-system-NetBSD-5.1.2 5.1.2 ++.ds doc-operating-system-NetBSD-5.1.3 5.1.3 ++.ds doc-operating-system-NetBSD-5.1.4 5.1.4 ++.ds doc-operating-system-NetBSD-5.2 5.2 ++.ds doc-operating-system-NetBSD-5.2.1 5.2.1 ++.ds doc-operating-system-NetBSD-5.2.2 5.2.2 ++.ds doc-operating-system-NetBSD-6.0 6.0 ++.ds doc-operating-system-NetBSD-6.0.1 6.0.1 ++.ds doc-operating-system-NetBSD-6.0.2 6.0.2 ++.ds doc-operating-system-NetBSD-6.0.3 6.0.3 ++.ds doc-operating-system-NetBSD-6.0.4 6.0.4 ++.ds doc-operating-system-NetBSD-6.0.5 6.0.5 ++.ds doc-operating-system-NetBSD-6.1 6.1 ++.ds doc-operating-system-NetBSD-6.1.1 6.1.1 ++.ds doc-operating-system-NetBSD-6.1.2 6.1.2 ++.ds doc-operating-system-NetBSD-6.1.3 6.1.3 ++.ds doc-operating-system-NetBSD-6.1.4 6.1.4 ++. ++.ds doc-operating-system-OpenBSD-2.0 2.0 ++.ds doc-operating-system-OpenBSD-2.1 2.1 ++.ds doc-operating-system-OpenBSD-2.2 2.2 ++.ds doc-operating-system-OpenBSD-2.3 2.3 ++.ds doc-operating-system-OpenBSD-2.4 2.4 ++.ds doc-operating-system-OpenBSD-2.5 2.5 ++.ds doc-operating-system-OpenBSD-2.6 2.6 ++.ds doc-operating-system-OpenBSD-2.7 2.7 ++.ds doc-operating-system-OpenBSD-2.8 2.8 ++.ds doc-operating-system-OpenBSD-2.9 2.9 ++.ds doc-operating-system-OpenBSD-3.0 3.0 ++.ds doc-operating-system-OpenBSD-3.1 3.1 ++.ds doc-operating-system-OpenBSD-3.2 3.2 ++.ds doc-operating-system-OpenBSD-3.3 3.3 ++.ds doc-operating-system-OpenBSD-3.4 3.4 ++.ds doc-operating-system-OpenBSD-3.5 3.5 ++.ds doc-operating-system-OpenBSD-3.6 3.6 ++.ds doc-operating-system-OpenBSD-3.7 3.7 ++.ds doc-operating-system-OpenBSD-3.8 3.8 ++.ds doc-operating-system-OpenBSD-3.9 3.9 ++.ds doc-operating-system-OpenBSD-4.0 4.0 ++.ds doc-operating-system-OpenBSD-4.1 4.1 ++.ds doc-operating-system-OpenBSD-4.2 4.2 ++.ds doc-operating-system-OpenBSD-4.3 4.3 ++.ds doc-operating-system-OpenBSD-4.4 4.4 ++.ds doc-operating-system-OpenBSD-4.5 4.5 ++.ds doc-operating-system-OpenBSD-4.6 4.6 ++.ds doc-operating-system-OpenBSD-4.7 4.7 ++.ds doc-operating-system-OpenBSD-4.8 4.8 ++.ds doc-operating-system-OpenBSD-4.9 4.9 ++.ds doc-operating-system-OpenBSD-5.0 5.0 ++.ds doc-operating-system-OpenBSD-5.1 5.1 ++.ds doc-operating-system-OpenBSD-5.2 5.2 ++.ds doc-operating-system-OpenBSD-5.3 5.3 ++.ds doc-operating-system-OpenBSD-5.4 5.4 ++.ds doc-operating-system-OpenBSD-5.5 5.5 ++.ds doc-operating-system-OpenBSD-5.6 5.6 ++. ++.ds doc-operating-system-FreeBSD-1.0 1.0 ++.ds doc-operating-system-FreeBSD-1.1 1.1 ++.ds doc-operating-system-FreeBSD-1.1.5 1.1.5 ++.ds doc-operating-system-FreeBSD-1.1.5.1 1.1.5.1 ++.ds doc-operating-system-FreeBSD-2.0 2.0 ++.ds doc-operating-system-FreeBSD-2.0.5 2.0.5 ++.ds doc-operating-system-FreeBSD-2.1 2.1 ++.ds doc-operating-system-FreeBSD-2.1.5 2.1.5 ++.ds doc-operating-system-FreeBSD-2.1.6 2.1.6 ++.ds doc-operating-system-FreeBSD-2.1.7 2.1.7 ++.ds doc-operating-system-FreeBSD-2.2 2.2 ++.ds doc-operating-system-FreeBSD-2.2.1 2.2.1 ++.ds doc-operating-system-FreeBSD-2.2.2 2.2.2 ++.ds doc-operating-system-FreeBSD-2.2.5 2.2.5 ++.ds doc-operating-system-FreeBSD-2.2.6 2.2.6 ++.ds doc-operating-system-FreeBSD-2.2.7 2.2.7 ++.ds doc-operating-system-FreeBSD-2.2.8 2.2.8 ++.ds doc-operating-system-FreeBSD-2.2.9 2.2.9 ++.ds doc-operating-system-FreeBSD-3.0 3.0 ++.ds doc-operating-system-FreeBSD-3.1 3.1 ++.ds doc-operating-system-FreeBSD-3.2 3.2 ++.ds doc-operating-system-FreeBSD-3.3 3.3 ++.ds doc-operating-system-FreeBSD-3.4 3.4 ++.ds doc-operating-system-FreeBSD-3.5 3.5 ++.ds doc-operating-system-FreeBSD-4.0 4.0 ++.ds doc-operating-system-FreeBSD-4.1 4.1 ++.ds doc-operating-system-FreeBSD-4.1.1 4.1.1 ++.ds doc-operating-system-FreeBSD-4.2 4.2 ++.ds doc-operating-system-FreeBSD-4.3 4.3 ++.ds doc-operating-system-FreeBSD-4.4 4.4 ++.ds doc-operating-system-FreeBSD-4.5 4.5 ++.ds doc-operating-system-FreeBSD-4.6 4.6 ++.ds doc-operating-system-FreeBSD-4.6.2 4.6.2 ++.ds doc-operating-system-FreeBSD-4.7 4.7 ++.ds doc-operating-system-FreeBSD-4.8 4.8 ++.ds doc-operating-system-FreeBSD-4.9 4.9 ++.ds doc-operating-system-FreeBSD-4.10 4.10 ++.ds doc-operating-system-FreeBSD-4.11 4.11 ++.ds doc-operating-system-FreeBSD-5.0 5.0 ++.ds doc-operating-system-FreeBSD-5.1 5.1 ++.ds doc-operating-system-FreeBSD-5.2 5.2 ++.ds doc-operating-system-FreeBSD-5.2.1 5.2.1 ++.ds doc-operating-system-FreeBSD-5.3 5.3 ++.ds doc-operating-system-FreeBSD-5.4 5.4 ++.ds doc-operating-system-FreeBSD-5.5 5.5 ++.ds doc-operating-system-FreeBSD-6.0 6.0 ++.ds doc-operating-system-FreeBSD-6.1 6.1 ++.ds doc-operating-system-FreeBSD-6.2 6.2 ++.ds doc-operating-system-FreeBSD-6.3 6.3 ++.ds doc-operating-system-FreeBSD-6.4 6.4 ++.ds doc-operating-system-FreeBSD-7.0 7.0 ++.ds doc-operating-system-FreeBSD-7.1 7.1 ++.ds doc-operating-system-FreeBSD-7.2 7.2 ++.ds doc-operating-system-FreeBSD-7.3 7.3 ++.ds doc-operating-system-FreeBSD-7.4 7.4 ++.ds doc-operating-system-FreeBSD-8.0 8.0 ++.ds doc-operating-system-FreeBSD-8.1 8.1 ++.ds doc-operating-system-FreeBSD-8.2 8.2 ++.ds doc-operating-system-FreeBSD-8.3 8.3 ++.ds doc-operating-system-FreeBSD-8.4 8.4 ++.ds doc-operating-system-FreeBSD-9.0 9.0 ++.ds doc-operating-system-FreeBSD-9.1 9.1 ++.ds doc-operating-system-FreeBSD-9.2 9.2 ++.ds doc-operating-system-FreeBSD-9.3 9.3 ++.ds doc-operating-system-FreeBSD-10.0 10.0 ++. ++.ds doc-operating-system-Darwin-8.0.0 8.0.0 ++.ds doc-operating-system-Darwin-8.1.0 8.1.0 ++.ds doc-operating-system-Darwin-8.2.0 8.2.0 ++.ds doc-operating-system-Darwin-8.3.0 8.3.0 ++.ds doc-operating-system-Darwin-8.4.0 8.4.0 ++.ds doc-operating-system-Darwin-8.5.0 8.5.0 ++.ds doc-operating-system-Darwin-8.6.0 8.6.0 ++.ds doc-operating-system-Darwin-8.7.0 8.7.0 ++.ds doc-operating-system-Darwin-8.8.0 8.8.0 ++.ds doc-operating-system-Darwin-8.9.0 8.9.0 ++.ds doc-operating-system-Darwin-8.10.0 8.10.0 ++.ds doc-operating-system-Darwin-8.11.0 8.11.0 ++.ds doc-operating-system-Darwin-9.0.0 9.0.0 ++.ds doc-operating-system-Darwin-9.1.0 9.1.0 ++.ds doc-operating-system-Darwin-9.2.0 9.2.0 ++.ds doc-operating-system-Darwin-9.3.0 9.3.0 ++.ds doc-operating-system-Darwin-9.4.0 9.4.0 ++.ds doc-operating-system-Darwin-9.5.0 9.5.0 ++.ds doc-operating-system-Darwin-9.6.0 9.6.0 ++.ds doc-operating-system-Darwin-9.7.0 9.7.0 ++.ds doc-operating-system-Darwin-9.8.0 9.8.0 ++.ds doc-operating-system-Darwin-10.0.0 10.0.0 ++.ds doc-operating-system-Darwin-10.1.0 10.1.0 ++.ds doc-operating-system-Darwin-10.2.0 10.2.0 ++.ds doc-operating-system-Darwin-10.3.0 10.3.0 ++.ds doc-operating-system-Darwin-10.4.0 10.4.0 ++.ds doc-operating-system-Darwin-10.5.0 10.5.0 ++.ds doc-operating-system-Darwin-10.6.0 10.6.0 ++.ds doc-operating-system-Darwin-10.7.0 10.7.0 ++.ds doc-operating-system-Darwin-10.8.0 10.8.0 ++.ds doc-operating-system-Darwin-11.0.0 11.0.0 ++.ds doc-operating-system-Darwin-11.1.0 11.1.0 ++.ds doc-operating-system-Darwin-11.2.0 11.2.0 ++.ds doc-operating-system-Darwin-11.3.0 11.3.0 ++.ds doc-operating-system-Darwin-11.4.0 11.4.0 ++.ds doc-operating-system-Darwin-11.5.0 11.5.0 ++.ds doc-operating-system-Darwin-12.0.0 12.0.0 ++.ds doc-operating-system-Darwin-12.1.0 12.1.0 ++.ds doc-operating-system-Darwin-12.2.0 12.2.0 ++.ds doc-operating-system-Darwin-13.0.0 13.0.0 ++.ds doc-operating-system-Darwin-13.1.0 13.1.0 ++.ds doc-operating-system-Darwin-13.2.0 13.2.0 ++.ds doc-operating-system-Darwin-13.3.0 13.3.0 ++.ds doc-operating-system-Darwin-13.4.0 13.4.0 ++.ds doc-operating-system-Darwin-14.0.0 14.0.0 ++. ++.ds doc-operating-system-DragonFly-1.0 1.0 ++.ds doc-operating-system-DragonFly-1.1 1.1 ++.ds doc-operating-system-DragonFly-1.2 1.2 ++.ds doc-operating-system-DragonFly-1.3 1.3 ++.ds doc-operating-system-DragonFly-1.4 1.4 ++.ds doc-operating-system-DragonFly-1.5 1.5 ++.ds doc-operating-system-DragonFly-1.6 1.6 ++.ds doc-operating-system-DragonFly-1.7 1.7 ++.ds doc-operating-system-DragonFly-1.8 1.8 ++.ds doc-operating-system-DragonFly-1.8.1 1.8.1 ++.ds doc-operating-system-DragonFly-1.9 1.9 ++.ds doc-operating-system-DragonFly-1.10 1.10 ++.ds doc-operating-system-DragonFly-1.11 1.11 ++.ds doc-operating-system-DragonFly-1.12 1.12 ++.ds doc-operating-system-DragonFly-1.12.2 1.12.2 ++.ds doc-operating-system-DragonFly-1.13 1.13 ++.ds doc-operating-system-DragonFly-2.0 2.0 ++.ds doc-operating-system-DragonFly-2.1 2.1 ++.ds doc-operating-system-DragonFly-2.2 2.2 ++.ds doc-operating-system-DragonFly-2.3 2.3 ++.ds doc-operating-system-DragonFly-2.4 2.4 ++.ds doc-operating-system-DragonFly-2.5 2.5 ++.ds doc-operating-system-DragonFly-2.6 2.6 ++.ds doc-operating-system-DragonFly-2.7 2.7 ++.ds doc-operating-system-DragonFly-2.8 2.8 ++.ds doc-operating-system-DragonFly-2.9 2.9 ++.ds doc-operating-system-DragonFly-2.9.1 2.9.1 ++.ds doc-operating-system-DragonFly-2.10 2.10 ++.ds doc-operating-system-DragonFly-2.10.1 2.10.1 ++.ds doc-operating-system-DragonFly-2.11 2.11 ++.ds doc-operating-system-DragonFly-2.12 2.12 ++.ds doc-operating-system-DragonFly-2.13 2.13 ++.ds doc-operating-system-DragonFly-3.0 3.0 ++.ds doc-operating-system-DragonFly-3.1 3.1 ++.ds doc-operating-system-DragonFly-3.2 3.2 ++.ds doc-operating-system-DragonFly-3.3 3.3 ++.ds doc-operating-system-DragonFly-3.4 3.4 ++.ds doc-operating-system-DragonFly-3.5 3.5 ++.ds doc-operating-system-DragonFly-3.6 3.6 ++.ds doc-operating-system-DragonFly-3.7 3.7 ++.ds doc-operating-system-DragonFly-3.8 3.8 ++. ++.de Os ++. ds doc-command-name ++. ++. ie "\$1"" \ ++. ds doc-operating-system "\*[doc-default-operating-system] ++. el \{ .ie "\$1"ATT" \{\ ++. ds doc-operating-system AT&T ++. if \A\$2 \{\ ++. ie d doc-operating-system-ATT-\$2 \ ++. as doc-operating-system " \*[doc-operating-system-ATT-\$2] ++. el \ ++. as doc-operating-system " UNIX ++. \}\} ++. el \{ .ie "\$1"BSD" \{\ ++. if \A\$2 \{\ ++. ie d doc-operating-system-BSD-\$2 \ ++. ds doc-operating-system "\*[doc-operating-system-BSD-\$2] ++. el \ ++. tm mdoc warning: .Os: Unknown BSD version `\$2' (#\n[.c]) ++. \}\} ++. el \{ .ie "\$1"FreeBSD" \{\ ++. ds doc-operating-system FreeBSD ++. if \A\$2 \{\ ++. ie d doc-operating-system-FreeBSD-\$2 \ ++. as doc-operating-system \~\*[doc-operating-system-FreeBSD-\$2] ++. el \ ++. tm mdoc warning: .Os: Unknown FreeBSD version `\$2' (#\n[.c]) ++. \}\} ++. el \{ .ie "\$1"DragonFly" \{\ ++. ds doc-operating-system DragonFly ++. if \A\$2 \{\ ++. ie d doc-operating-system-DragonFly-\$2 \ ++. as doc-operating-system \~\*[doc-operating-system-DragonFly-\$2] ++. el \ ++. tm mdoc warning: .Os: Unknown DragonFly version `\$2' (#\n[.c]) ++. \}\} ++. el \{ .ie "\$1"NetBSD" \{\ ++. ds doc-operating-system NetBSD ++. if \A\$2 \{\ ++. ie d doc-operating-system-NetBSD-\$2 \ ++. as doc-operating-system \~\*[doc-operating-system-NetBSD-\$2] ++. el \ ++. tm mdoc warning: .Os: Unknown NetBSD version `\$2' (#\n[.c]) ++. \}\} ++. el \{ .ie "\$1"OpenBSD" \{\ ++. ds doc-operating-system OpenBSD ++. if \A\$2 \{\ ++. ie d doc-operating-system-OpenBSD-\$2 \ ++. as doc-operating-system \~\*[doc-operating-system-OpenBSD-\$2] ++. el \ ++. tm mdoc warning: .Os: Unknown OpenBSD version `\$2' (#\n[.c]) ++. \}\} ++. el \{ .ie "\$1"Darwin" \{\ ++. ds doc-operating-system Darwin ++. if \A\$2 \{\ ++. ie d doc-operating-system-Darwin-\$2 \ ++. as doc-operating-system \~\*[doc-operating-system-Darwin-\$2] ++. el \ ++. tm mdoc warning: .Os: Unknown Darwin version `\$2' (#\n[.c]) ++. \}\} ++. el \{\ ++. ds doc-operating-system \$1 ++. if !"\$2"" \ ++. as doc-operating-system " \$2 ++. \}\}\}\}\}\}\}\} ++.. ++. ++. ++.\" NS doc-date-string global string ++.\" NS the manual page date as set by `Dd' ++. ++.ds doc-date-string ++. ++. ++.\" NS Dd user macro (not parsed, not callable) ++.\" NS set document date ++.\" NS ++.\" NS modifies: ++.\" NS doc-date-string ++.\" NS doc-command-name ++.\" NS ++.\" NS local variables: ++.\" NS doc-date-XXX ++.\" NS ++.\" NS width register `Dd' set above ++. ++.ds doc-date-1 January ++.ds doc-date-2 February ++.ds doc-date-3 March ++.ds doc-date-4 April ++.ds doc-date-5 May ++.ds doc-date-6 June ++.ds doc-date-7 July ++.ds doc-date-8 August ++.ds doc-date-9 September ++.ds doc-date-10 October ++.ds doc-date-11 November ++.ds doc-date-12 December ++. ++.de Dd ++. ds doc-command-name ++. ++. ie \n[.$] \{\ ++. ie "\$1"$Mdocdate:" \ ++. ds doc-date-string \$2\~\$3, \$4 ++. el \{ .ie (\n[.$] == 3) \ ++. ds doc-date-string \$1\~\$2 \$3 ++. el \{\ ++. ds doc-date-string "\*[doc-date-\n[mo]] ++. as doc-date-string \~\n[dy], \n[year] ++. \}\} ++. \} ++. el \ ++. ds doc-date-string Epoch ++.. ++. ++. ++.\" NS doc-hyphen-flags global register ++.\" NS the parameter for the `.hy' request ++.\" NS ++.\" NS override this in `mdoc.local', if necessary. ++. ++.nr doc-hyphen-flags 12 ++. ++. ++.\" NS doc-header macro ++.\" NS print page header ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dh ++.\" NS doc-reg-dh1 ++. ++.de doc-header ++. ev doc-env-dh ++. doc-setup-page-layout ++. if !\n[cR] \ ++. sp \n[doc-header-space]u ++. nr doc-reg-dh \w'\*[doc-caption-font]\*[doc-header-string]\f[]' ++. nr doc-reg-dh1 \w'\*[doc-caption-font2]\*[doc-volume]\f[]' ++. if (\n[doc-reg-dh] + \n[doc-reg-dh1] + \n[doc-reg-dh] >= \n[.lt]) \{\ ++. while (\n[doc-reg-dh] + \n[doc-reg-dh1] + \n[doc-reg-dh] >= \n[.lt]) \{\ ++. substring doc-header-string 0 -2 ++. nr doc-reg-dh \w'\*[doc-caption-font]\*[doc-header-string]\|.\|.\|.\f[]' ++. \} ++. as doc-header-string "\|.\|.\|. ++. \} ++. tl \*[doc-caption-font]\*[doc-header-string]\f[]\*[doc-caption-font2]\*[doc-volume]\f[]\*[doc-caption-font]\*[doc-header-string]\f[] ++. ie !\n[cR] \ ++. sp \n[doc-header-space]u ++. el \ ++. sp 1v ++. ev ++. ns ++.. ++. ++. ++.\" NS doc-footer macro ++.\" NS print page footer ++. ++.de doc-footer ++. ie \n[cR] \ ++. br ++. el \{\ ++. ev doc-caption-enviroment ++. doc-setup-page-layout ++. sp \n[doc-footer-space]u ++. ie \n[D] \{\ ++. ie o \ ++. tl %\*[doc-caption-font2]\*[doc-date-string]\f[]\*[doc-caption-font]\*[doc-operating-system]\f[] ++. el \ ++. tl \*[doc-caption-font]\*[doc-operating-system]\f[]\*[doc-caption-font2]\*[doc-date-string]\f[]% ++. \} ++. el \ ++. tl \*[doc-caption-font]\*[doc-operating-system]\f[]\*[doc-caption-font2]\*[doc-date-string]\f[]% ++. bp ++. ev ++. \} ++.. ++. ++. ++.\" NS doc-check-depth macro ++.\" NS check paired macros ++. ++.de doc-check-depth ++. if \n[doc-list-depth] \{\ ++. tm mdoc warning: A .Bl directive has no matching .El (#\n[.c]) ++. nr doc-list-depth 0 ++. \} ++. if \n[doc-display-depth] \{\ ++. tm mdoc warning: A .Bd directive has no matching .Ed (#\n[.c]) ++. nr doc-display-depth 0 ++. \} ++. if \n[doc-fontmode-depth] \{\ ++. tm mdoc warning: A .Bf directive has no matching .Ef (#\n[.c]) ++. nr doc-fontmode-depth 0 ++. \} ++.. ++. ++. ++.\" NS doc-end-macro macro ++.\" NS finish output ++. ++.de doc-end-macro ++. \" We may still have a partial line in the environment. If this is the ++. \" case, and we happen to be on the last line of the page, the `.fl' ++. \" request will cause the page to be ejected and troff will immediately ++. \" exit. If we are in nroff mode, this would be unfortunate, since we ++. \" would never get a chance to output the footer. So we fudge the page ++. \" length to make sure that the last page is never ejected until we want ++. \" it to be. ++. ++. if \n[cR] \ ++. pl +3v ++. fl ++. ++. doc-check-depth ++. ++. if \n[cR] \{\ ++. sp ++. tl \*[doc-caption-font]\*[doc-operating-system]\f[]\*[doc-caption-font2]\*[doc-date-string]\f[]\*[doc-caption-font]\*[doc-operating-system]\f[] ++. \" suppress empty lines after the footer ++. pl \n[nl]u ++. \} ++.. ++. ++. ++.\" NS doc-paragraph macro ++.\" NS insert a paragraph ++. ++.de doc-paragraph ++. sp \n[doc-paragraph-space]u ++. if !\n[cR] \ ++. ne 2 ++. ns ++.. ++. ++. ++.\" NS Pp user macro (not parsed, not callable) ++.\" NS new paragraph ++.\" NS ++.\" NS width register `Pp' set above ++. ++.als Pp doc-paragraph ++. ++. ++.\" NS Lp user macro (not parsed, not callable) ++.\" NS same as .Pp ++.\" NS ++.\" NS width register `Lp' set above ++. ++.als Lp doc-paragraph ++. ++. ++.de LP ++. tm Not a \-mdoc command: .LP (#\n[.c]) ++.. ++. ++. ++.de PP ++. tm Not a \-mdoc command: .PP (#\n[.c]) ++.. ++. ++. ++.de pp ++. tm Not a \-mdoc command: .pp (#\n[.c]) ++.. ++. ++. ++.de SH ++. tm Not a \-mdoc command: .SH (#\n[.c]) ++.. ++. ++. ++.\" NS Nd user macro (not parsed, not callable) ++.\" NS print name description ++.\" NS ++.\" NS width register `Nd' set above ++. ++.de Nd ++. nop \[em] \$* ++.. ++. ++. ++.\" NS doc-in-synopsis-section global register (bool) ++.\" NS whether we are in the `synopsis' section ++. ++.nr doc-in-synopsis-section 0 ++. ++. ++.\" NS doc-in-library-section global register (bool) ++.\" NS whether we are in the `library' section ++. ++.nr doc-in-library-section 0 ++. ++. ++.\" NS doc-in-see-also-section global register (bool) ++.\" NS whether we are in the `see also' section ++. ++.nr doc-in-see-also-section 0 ++. ++. ++.\" NS doc-in-files-section global register (bool) ++.\" NS whether we are in the `files' section ++. ++.nr doc-in-files-section 0 ++. ++. ++.\" NS doc-in-authors-section global register (bool) ++.\" NS whether we are in the `authors' section ++. ++.nr doc-in-authors-section 0 ++. ++. ++.\" NS doc-first-parameter macro ++.\" NS return first parameter ++.\" NS ++.\" NS local variables: ++.\" NS doc-str-dfp ++. ++.de doc-first-parameter ++. ds doc-str-dfp "\$1 ++.. ++. ++. ++.\" NS Sh user macro (not callable) ++.\" NS section headers ++.\" NS ++.\" NS modifies: ++.\" NS doc-func-args-processed ++.\" NS doc-func-count ++.\" NS doc-in-authors-section ++.\" NS doc-in-files-section ++.\" NS doc-in-library-section ++.\" NS doc-in-see-also-section ++.\" NS doc-in-synopsis-section ++.\" NS doc-indent-synopsis ++.\" NS doc-indent-synopsis-active ++.\" NS doc-is-func ++.\" NS doc-num-func-args ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-Sh ++.\" NS doc-reg-Sh1 ++.\" NS doc-section-XXX ++.\" NS ++.\" NS width register `Sh' set in doc-common ++. ++.ds doc-section-name NAME ++.ds doc-section-synopsis SYNOPSIS ++.ds doc-section-library LIBRARY ++.ds doc-section-description DESCRIPTION ++.ds doc-section-see-also SEE ++.ds doc-section-files FILES ++.ds doc-section-authors AUTHORS ++. ++.de Sh ++. ie \n[doc-arg-limit] \{\ ++. \" we only allow `Sh' within `Sh'; it will change the font back to ++. \" `doc-Sh-font' ++. ie "\*[doc-macro-name]"Sh" \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Sh-font]\c ++. doc-print-recursive ++. \} ++. el \{\ ++. tm Usage: .Sh section_name ... (#\n[.c]) ++. doc-reset-args ++. \}\} ++. el \{\ ++. tm Usage: .Sh not callable by other macros (#\n[.c]) ++. doc-reset-args ++. \}\} ++. el \{\ ++. if !\n[.$] \{\ ++. tm Usage: .Sh section_name ... (#\n[.c]) ++. return ++. \} ++. ++. ds doc-macro-name Sh ++. doc-parse-args \$@ ++. ++. if t \ ++. ad ++. ++. \" this resolves e.g. `.Sh "SEE ALSO"' ++. doc-first-parameter \$* ++. ++. ie "\*[doc-str-dfp]"\*[doc-section-name]" \{\ ++. doc-setup-header ++. in 0 ++. \} ++. el \{\ ++. nr doc-in-synopsis-section 0 ++. nr doc-in-library-section 0 ++. nr doc-in-see-also-section 0 ++. nr doc-in-files-section 0 ++. nr doc-in-authors-section 0 ++. ++. ie "\*[doc-str-dfp]"\*[doc-section-synopsis]" \{\ ++. if t \ ++. na ++. nr doc-in-synopsis-section 1 ++. nr doc-indent-synopsis 0 ++. nr doc-indent-synopsis-active 0 ++. \} ++. el \{ .ie "\*[doc-str-dfp]"\*[doc-section-library]" \{\ ++. nr doc-in-library-section 1 ++. \} ++. el \{ .ie "\*[doc-str-dfp]"\*[doc-section-description]" \{\ ++. nr doc-is-func 0 ++. nr doc-func-count 0 ++. nr doc-func-args-processed 0 ++. nr doc-num-func-args 0 ++. \} ++. el \{ .ie "\*[doc-str-dfp]"\*[doc-section-see-also]" \{\ ++. if t \ ++. na ++. nr doc-in-see-also-section 1 ++. \} ++. el \{ .ie "\*[doc-str-dfp]"\*[doc-section-files]" \ ++. nr doc-in-files-section 1 ++. el .if "\*[doc-str-dfp]"\*[doc-section-authors]" \ ++. nr doc-in-authors-section 1 ++. \}\}\}\} ++. ++. in 0 ++. nr doc-have-author 0 ++. \} ++. ++. doc-setup-page-layout ++. sp ++. ns ++. ta T .5i ++. if !\n[cR] \ ++. ne 3 ++. fi ++. ++. if t \{\ ++. nr doc-reg-Sh \n[.ss] ++. nr doc-reg-Sh1 \n[.sss] ++. ss (\n[.ss] * 5 / 3) (\n[.sss] * 5 / 3) ++. \} ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Sh-font]\c ++. doc-print-recursive ++. ++. if t \ ++. ss \n[doc-reg-Sh] \n[doc-reg-Sh1] ++. ++. in +\n[doc-subheader-indent]u ++. ns ++. ++. doc-check-depth ++. \} ++.. ++. ++. ++.\" NS Ss user macro (not callable) ++.\" NS subsection ++.\" NS ++.\" NS local variable: ++.\" NS doc-reg-Ss ++.\" NS doc-reg-Ss1 ++.\" NS ++.\" NS width register `Ss' set above ++. ++.de Ss ++. ie \n[doc-arg-limit] \{\ ++. \" we only allow `Ss' within `Ss'; it will change the font back to ++. \" `doc-Sh-font' ++. ie "\*[doc-macro-name]"Ss" \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Sh-font]\c ++. doc-print-recursive ++. \} ++. el \{\ ++. tm Usage: .Ss subsection_name ... (#\n[.c]) ++. doc-reset-args ++. \}\} ++. el \{\ ++. tm Usage: .Ss not callable by other macros (#\n[.c]) ++. doc-reset-args ++. \}\} ++. el \{\ ++. if !\n[.$] \{\ ++. tm Usage: .Ss subsection_name ... (#\n[.c]) ++. return ++. \} ++. ++. ds doc-macro-name Ss ++. doc-parse-args \$@ ++. ++. sp ++. if !\n[cR] \ ++. ne 3 ++. ti -.25i ++. ++. nr doc-reg-Ss \n[.ss] ++. nr doc-reg-Ss1 \n[.sss] ++. ss (\n[.ss] * 5 / 4) (\n[.sss] * 5 / 4) ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Sh-font]\c ++. doc-print-recursive ++. ++. ss \n[doc-reg-Ss] \n[doc-reg-Ss1] ++. ++. ta T .5i ++. if !\n[cR] \ ++. ne 2 ++. br ++. ns ++. ++. doc-check-depth ++. \} ++.. ++. ++. ++.\" NS Rd macro (not parsed, not callable) ++.\" NS print global register dump to stderr ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-Rd ++. ++.de Rd ++. tm MDOC GLOBAL REGISTER DUMP ++. tm doc-macro-name == `\*[doc-macro-name]' ++. tm doc-arg-limit == \n[doc-arg-limit] ++. tm doc-num-args == \n[doc-num-args] ++. tm doc-arg-ptr == \n[doc-arg-ptr] ++. ++. nr doc-reg-Rd 1 ++. while (\n[doc-reg-Rd] <= \n[doc-arg-limit]) \{\ ++. tm doc-arg\n[doc-reg-Rd] == `\*[doc-arg\n[doc-reg-Rd]]' ++. tm doc-type\n[doc-reg-Rd] == \n[doc-type\n[doc-reg-Rd]] ++. tm doc-space\n[doc-reg-Rd] == `\*[doc-space\n[doc-reg-Rd]]' ++. nr doc-reg-Rd +1 ++. \} ++. ++. tm doc-curr-font == \n[doc-curr-font] ++. tm doc-curr-size == \n[doc-curr-size] ++. tm doc-indent-synopsis == \n[doc-indent-synopsis] ++. tm doc-indent-synopsis-active == \n[doc-indent-synopsis-active] ++. tm doc-have-decl == \n[doc-have-decl] ++. tm doc-have-var == \n[doc-have-var] ++. tm doc-command-name == `\*[doc-command-name]' ++. tm doc-quote-left == `\*[doc-quote-left]' ++. tm doc-quote-right == `\*[doc-quote-right]' ++. tm doc-nesting-level == \n[doc-nesting-level] ++. tm doc-in-list == \n[doc-in-list] ++. tm doc-space == `\*[doc-space]' ++. tm doc-saved-space == `\*[doc-saved-space]' ++. tm doc-space-mode == \n[doc-space-mode] ++. tm doc-have-space == \n[doc-have-space] ++. tm doc-have-slot == \n[doc-have-slot] ++. tm doc-keep-type == \n[doc-keep-type] ++. tm doc-display-depth == \n[doc-display-depth] ++. tm doc-is-compact == \n[doc-is-compact] ++. ++. nr doc-reg-Rd 0 ++. while (\n[doc-reg-Rd] <= \n[doc-display-depth]) \{\ ++. tm doc-display-type-stack\n[doc-reg-Rd] == `\*[doc-display-type-stack\n[doc-reg-Rd]]' ++. tm doc-display-indent-stack\n[doc-reg-Rd] == \n[doc-display-indent-stack\n[doc-reg-Rd]] ++. tm doc-display-ad-stack\n[doc-reg-Rd] == \n[doc-display-ad-stack\n[doc-reg-Rd]] ++. tm doc-display-fi-stack\n[doc-reg-Rd] == \n[doc-display-fi-stack\n[doc-reg-Rd]] ++. tm doc-display-ft-stack\n[doc-reg-Rd] == \n[doc-display-ft-stack\n[doc-reg-Rd]] ++. tm doc-display-ps-stack\n[doc-reg-Rd] == \n[doc-display-ps-stack\n[doc-reg-Rd]] ++. nr doc-reg-Rd +1 ++. \} ++. ++. tm doc-fontmode-depth == \n[doc-fontmode-depth] ++. ++. nr doc-reg-Rd 1 ++. while (\n[doc-reg-Rd] <= \n[doc-fontmode-depth]) \{\ ++. tm doc-fontmode-font-stack\n[doc-reg-Rd] == `\n[doc-fontmode-font-stack\n[doc-reg-Rd]]' ++. tm doc-fontmode-size-stack\n[doc-reg-Rd] == `\n[doc-fontmode-size-stack\n[doc-reg-Rd]]' ++. nr doc-reg-Rd +1 ++. \} ++. ++. tm doc-list-depth == \n[doc-list-depth] ++. ++. nr doc-reg-Rd 1 ++. while (\n[doc-reg-Rd] <= \n[doc-list-depth]) \{\ ++. tm doc-list-type-stack\n[doc-reg-Rd] == `\*[doc-list-type-stack\n[doc-reg-Rd]]' ++. tm doc-list-have-indent-stack\n[doc-reg-Rd] == \n[doc-list-have-indent-stack\n[doc-reg-Rd]] ++. tm doc-list-indent-stack\n[doc-reg-Rd] == \n[doc-list-indent-stack\n[doc-reg-Rd]] ++. tm doc-compact-list-stack\n[doc-reg-Rd] == \n[doc-compact-list-stack\n[doc-reg-Rd]] ++. tm doc-tag-prefix-stack\n[doc-reg-Rd] == `\*[doc-tag-prefix-stack\n[doc-reg-Rd]]' ++. tm doc-tag-width-stack\n[doc-reg-Rd] == `\*[doc-tag-width-stack\n[doc-reg-Rd]]' ++. tm doc-list-offset-stack\n[doc-reg-Rd] == \n[doc-list-offset-stack\n[doc-reg-Rd]] ++. tm doc-enum-list-count-stack\n[doc-reg-Rd] == \n[doc-enum-list-count-stack\n[doc-reg-Rd]] ++. nr doc-reg-Rd +1 ++. \} ++. ++. tm doc-saved-Pa-font == `\*[doc-saved-Pa-font]' ++. tm doc-curr-type == \n[doc-curr-type] ++. tm doc-curr-arg == `\*[doc-curr-arg]' ++. tm doc-diag-list-input-line-count == \n[doc-diag-list-input-line-count] ++. tm doc-num-columns == \n[doc-num-columns] ++. tm doc-column-indent-width == \n[doc-column-indent-width] ++. tm doc-is-func == \n[doc-is-func] ++. tm doc-have-old-func == \n[doc-have-old-func] ++. tm doc-func-arg-count == \n[doc-func-arg-count] ++. tm doc-func-arg == `\*[doc-func-arg]' ++. tm doc-num-func-args == \n[doc-num-func-args] ++. tm doc-func-args-processed == \n[doc-func-args-processed] ++. tm doc-have-func == \n[doc-have-func] ++. tm doc-is-reference == \n[doc-is-reference] ++. tm doc-reference-count == \n[doc-reference-count] ++. tm doc-author-count == \n[doc-author-count] ++. ++. nr doc-reg-Rd 0 ++. while (\n[doc-reg-Rd] <= \n[doc-author-count]) \{\ ++. tm doc-author-name\n[doc-reg-Rd] == `\*[doc-author-name\n[doc-reg-Rd]]' ++. nr doc-reg-Rd +1 ++. \} ++. ++. tm doc-book-count == \n[doc-book-count] ++. tm doc-book-name == `\*[doc-book-name]' ++. tm doc-date-count == \n[doc-date-count] ++. tm doc-date == `\*[doc-date]' ++. tm doc-publisher-count == \n[doc-publisher-count] ++. tm doc-publisher-name == `\*[doc-publisher-name]' ++. tm doc-journal-count == \n[doc-journal-count] ++. tm doc-journal-name == `\*[doc-journal-name]' ++. tm doc-issue-count == \n[doc-issue-count] ++. tm doc-issue-name == `\*[doc-issue-name]' ++. tm doc-optional-count == \n[doc-optional-count] ++. tm doc-optional-string == `\*[doc-optional-string]' ++. tm doc-page-number-count == \n[doc-page-number-count] ++. tm doc-page-number-string == `\*[doc-page-number-string]' ++. tm doc-corporate-count == \n[doc-corporate-count] ++. tm doc-corporate-name == `\*[doc-corporate-name]' ++. tm doc-report-count == \n[doc-report-count] ++. tm doc-report-name == `\*[doc-report-name]' ++. tm doc-reference-title-count == \n[doc-reference-title-count] ++. tm doc-reference-title-name == `\*[doc-reference-title-name]' ++. tm doc-reference-title-name-for-book == `\*[doc-reference-title-name-for-book]' ++. tm doc-url-count == \n[doc-url-count] ++. tm doc-url-name == `\*[doc-url-name]' ++. tm doc-volume-count == \n[doc-volume-count] ++. tm doc-volume-name == `\*[doc-volume-name]' ++. tm doc-have-author == \n[doc-have-author] ++. ++. tm doc-document-title == `\*[doc-document-title]' ++. tm doc-volume == `\*[doc-volume]' ++. tm doc-section == `\*[doc-section]' ++. tm doc-operating-system == `\*[doc-operating-system]' ++. tm doc-date-string == `\*[doc-date-string]' ++. tm doc-header-space == \n[doc-header-space] ++. tm doc-footer-space == \n[doc-footer-space] ++. tm doc-display-vertical == \n[doc-display-vertical] ++. tm doc-header-string == `\*[doc-header-string]' ++. tm doc-in-synopsis-section == \n[doc-in-synopsis-section] ++. tm doc-in-library-section == \n[doc-in-library-section] ++. tm doc-in-see-also-section == \n[doc-in-see-also-section] ++. tm doc-in-files-section == \n[doc-in-files-section] ++. tm doc-in-authors-section == \n[doc-in-authors-section] ++. ++. tm END OF GLOBAL REGISTER DUMP ++.. ++. ++. ++.ec ++. ++.\" EOF +diff -Nuar groff-1.22.3.old/tmac/doc-ditroff groff-1.22.3/tmac/doc-ditroff +--- groff-1.22.3.old/tmac/doc-ditroff 2014-11-04 10:38:35.533520146 +0200 ++++ groff-1.22.3/tmac/doc-ditroff 1970-01-01 02:00:00.000000000 +0200 +@@ -1,334 +0,0 @@ +-.\" -*- nroff -*- +-.\" +-.\" Copyright (c) 1991, 1993 +-.\" The Regents of the University of California. All rights reserved. +-.\" +-.\" Redistribution and use in source and binary forms, with or without +-.\" modification, are permitted provided that the following conditions +-.\" are met: +-.\" 1. Redistributions of source code must retain the above copyright +-.\" notice, this list of conditions and the following disclaimer. +-.\" 2. Redistributions in binary form must reproduce the above copyright +-.\" notice, this list of conditions and the following disclaimer in the +-.\" documentation and/or other materials provided with the distribution. +-.\" 3. [Deleted. See +-.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +-.\" 4. Neither the name of the University nor the names of its contributors +-.\" may be used to endorse or promote products derived from this software +-.\" without specific prior written permission. +-.\" +-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-.\" SUCH DAMAGE. +-.\" +-.\" @(#)doc-ditroff 8.1 (Berkeley) 06/08/93 +-.\" +-.\" %beginstrip% +-. +-. +-.eo +-. +-.\" use -rD=1 for double-sided printing +-. +-.if !r D .nr D 0 +-. +-.\" use -rcR=1 to force the creation of a single, very long page +-. +-.if !r cR .nr cR 0 +-. +-.\" use -rS={11,12} to change the font size from 10pt to 11pt or 12pt. +-. +-.if !r S .nr S 10 +-. +-. +-.ec +-. +-. +-.ie (\n[S] == 11) \{\ +-. ps 10.95z +-. vs 13.6p +-.\} +-.el \{ .ie (\n[S] == 12) \{\ +-. ps 12z +-. vs 14.5p +-.\} +-.el \{\ +-. ps 10z +-. vs 12p +-.\}\} +-. +-. +-.\" the `doc-xx-font' strings must not be empty! +-. +-.ds doc-caption-font \f[R]\s[\n[.ps]u] +-.ds doc-caption-font2 \f[R]\s[\n[.ps]u] +-.ds doc-Ad-font \f[I]\s[\n[.ps]u] +-.ds doc-Ar-font \f[CO]\s[\n[.ps]u] +-.ds doc-Cm-font \f[CB]\s[\n[.ps]u] +-.ds doc-Em-font \f[I]\s[\n[.ps]u] +-.ds doc-Er-font \f[C]\s[\n[.ps]u] +-.ds doc-Ev-font \f[C]\s[\n[.ps]u] +-.ds doc-Fa-font \f[CO]\s[\n[.ps]u] +-.ds doc-Fd-font \f[CB]\s[\n[.ps]u] +-.ds doc-Fl-font \f[CB]\s[\n[.ps]u] +-.ds doc-Fn-font \f[CB]\s[\n[.ps]u] +-.ds doc-Ft-font \f[CO]\s[\n[.ps]u] +-.ds doc-Ic-font \f[CB]\s[\n[.ps]u] +-.ds doc-Li-font \f[C] +-.ds doc-Me-font \f[B]\s[\n[.ps]u] +-.ds doc-Nm-font \f[CB]\s[\n[.ps]u] +-.ds doc-No-font \f[R]\s[\n[.ps]u] +-.ds doc-Pa-font \f[C]\s[\n[.ps]u] +-.ds doc-Sh-font \f[B]\s[\n[.ps]u] +-.ds doc-Sy-font \f[B]\s[\n[.ps]u] +-.ds doc-Sx-font \f[B]\s[\n[.ps]u] +-.ds doc-Tn-font-shape \f[R] +-\# XXX: adapt to discrete LaTeX font sizes +-.ds doc-Tn-font-size \s[(\n[.ps]u - 1z)] +-.ds doc-Va-font \f[I]\s[\n[.ps]u] +-.ds doc-Xr-font \f[C]\s[\n[.ps]u] +-. +-.ds doc-left-parenthesis \f[R]\|(\|\f[]\s[\n[.ps]u] +-.ds doc-right-parenthesis \f[R]\|)\|\f[]\s[\n[.ps]u] +-.ds lp \f[R](\f[]\s[\n[.ps]u] +-.ds rp \f[R])\f[]\s[\n[.ps]u] +-.ds doc-left-bracket \f[R]\^[\^\f[]\s[\n[.ps]u] +-.ds doc-right-bracket \f[R]\^]\f[]\s[\n[.ps]u] +-. +-.tr *\[**] +-. +-.\" miscellaneous +-.nr doc-subheader-indent (\w\f[C],u * 5u) +-.nr doc-paragraph-space .5v +-. +-.nr doc-digit-width \w'\0'u +-.nr doc-fixed-width \w\f[C]0 +-. +-.eo +-. +-. +-.\" NS doc-header-space global register +-.\" NS the space between header and body +-. +-.nr doc-header-space .5i +-. +-. +-.\" NS doc-footer-space global register +-.\" NS the space between body and footer +-. +-.nr doc-footer-space .5i +-. +-. +-.\" NS doc-display-vertical global register +-.\" NS vertical space between list elements etc. +-. +-.nr doc-display-vertical 0 +-. +-. +-.\" NS doc-setup-page-layout macro +-.\" NS set up page layout +-.\" NS +-.\" NS modifies: +-.\" NS doc-display-vertical +-. +-.de doc-setup-page-layout +-. ie r LL \ +-. ll \n[LL]u +-. el \ +-. ll 6.5i +-. +-. ie r LT \ +-. lt \n[LT]u +-. el \ +-. lt 6.5i +-. +-. po 1i +-. +-. nr doc-display-vertical .5v +-.. +-. +-. +-.ds doc-left-singlequote \[oq] +-.ds doc-right-singlequote \[cq] +-. +-.\" the following strings are `official' +-.ds <= \[<=] +-.ds >= \[>=] +-.ds Lq \[lq] +-.ds Rq \[rq] +-.ds ua \[ua] +-.ds aa \[aa] +-.ds ga \[ga] +-.ds q \[dq] +-.ds Pi \[*p] +-.ds Ne \[!=] +-.ds Le \[<=] +-.ds Ge \[>=] +-.ds Lt < +-.ds Gt > +-.ds Pm \[+-] +-.ds If \[if] +-.ds Na \f[I]NaN\f[] +-.ds Ba \f[R]|\f[] +-.ds Am & +-. +-. +-.\" NS doc-header-string global string +-.\" NS the final string used for the manual page header +-. +-.ds doc-header-string +-. +-. +-.\" NS doc-setup-header macro +-.\" NS install and initialize header and footer support +-.\" NS +-.\" NS modifies: +-.\" NS doc-header-string +-. +-.de doc-setup-header +-. ds doc-header-string "\*[doc-document-title] +-. if !"\*[doc-section]"Null" \ +-. as doc-header-string \|(\*[doc-section]) +-. +-. wh 0 doc-header +-. wh -1.25i doc-footer +-. +-. br +-. +-. e@ doc-end-macro +-.. +-. +-. +-.\" NS doc-get-width macro +-.\" NS computes the width of a string as a multiple of `doc-fixed-width': +-.\" NS `.doc-get-width string' +-.\" NS +-.\" NS modifies: +-.\" NS doc-width +-. +-.de doc-get-width +-. nr doc-width \w\f[C]\$1 +-. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ +-. ie (\n[doc-width] % \n[doc-fixed-width]) \ +-. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) +-. el \ +-. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) +-. \} +-. el \{\ +-. ie \n[doc-width] \ +-. nr doc-width 1 +-. el \ +-. nr doc-width 0 +-. \} +-.. +-. +-. +-.\" NS doc-get-arg-width macro +-.\" NS computes the width of an argument as a multiple of +-.\" NS `doc-fixed-width': `.doc-get-arg-width arg-index' +-.\" NS +-.\" NS modifies: +-.\" NS doc-width +-. +-.de doc-get-arg-width +-. nr doc-width \w\f[C]\*[doc-arg\$1] +-. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ +-. ie (\n[doc-width] % \n[doc-fixed-width]) \ +-. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) +-. el \ +-. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) +-. \} +-. el \{\ +-. ie \n[doc-width] \ +-. nr doc-width 1 +-. el \ +-. nr doc-width 0 +-. \} +-.. +-. +-. +-.\" NS Ql user macro +-.\" NS quoted literal define +-.\" NS +-.\" NS modifies: +-.\" NS doc-argXXX +-.\" NS doc-arg-limit +-.\" NS doc-arg-ptr +-.\" NS doc-macro-name +-.\" NS doc-spaceXXX +-.\" NS doc-typeXXX +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-Ql +-.\" NS doc-reg-Ql1 +-.\" NS doc-reg-Ql2 +-.\" NS +-.\" NS width register `Ql' set in doc-common +-. +-.de Ql +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Ql +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Ql argument ... (#\n[.c]) +-. \} +-. +-. nr doc-reg-Ql (\n[doc-arg-ptr] + 1) +-. doc-get-arg-width \n[doc-reg-Ql] +-. +-. \" don't use quotes if we have more than two succeeding string arguments +-. nr doc-reg-Ql +1 +-. if (\n[doc-arg-limit] >= \n[doc-reg-Ql]) \ +-. if (\n[doc-type\n[doc-reg-Ql]] == 2) \ +-. nr doc-width 3 +-. +-. \" make a difference in quotation style for strings longer +-. \" than two characters +-. ie (\n[doc-width] > 2) \ +-. Li +-. el \{\ +-. ie \n[doc-arg-ptr] \{\ +-. \" we replace `Ql' with `Li' +-. ds doc-arg\n[doc-arg-ptr] Li +-. nr doc-arg-ptr -1 +-. \} +-. el \{\ +-. \" if .Ql has been called directly, we must shift all elements in +-. \" the argument vector to the right so that we can insert `Li' +-. nr doc-reg-Ql \n[doc-arg-limit] +-. nr doc-reg-Ql1 (\n[doc-arg-limit] + 1) +-. while \n[doc-reg-Ql] \{\ +-. rn doc-arg\n[doc-reg-Ql] doc-arg\n[doc-reg-Ql1] +-. rnn doc-type\n[doc-reg-Ql] doc-type\n[doc-reg-Ql1] +-. rn doc-space\n[doc-reg-Ql] doc-space\n[doc-reg-Ql1] +-. nr doc-reg-Ql -1 +-. nr doc-reg-Ql1 -1 +-. \} +-. ds doc-arg1 Li +-. nr doc-type1 1 +-. ds doc-space1 +-. nr doc-arg-limit +1 +-. \} +-. +-. ds doc-quote-left "\*[doc-left-singlequote] +-. ds doc-quote-right "\*[doc-right-singlequote] +-. doc-enclose-string +-. \} +-.. +-. +-. +-.ec +-. +-.\" EOF +diff -Nuar groff-1.22.3.old/tmac/doc-ditroff-u groff-1.22.3/tmac/doc-ditroff-u +--- groff-1.22.3.old/tmac/doc-ditroff-u 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/doc-ditroff-u 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,334 @@ ++.\" -*- nroff -*- ++.\" ++.\" Copyright (c) 1991, 1993 ++.\" The Regents of the University of California. All rights reserved. ++.\" ++.\" Redistribution and use in source and binary forms, with or without ++.\" modification, are permitted provided that the following conditions ++.\" are met: ++.\" 1. Redistributions of source code must retain the above copyright ++.\" notice, this list of conditions and the following disclaimer. ++.\" 2. Redistributions in binary form must reproduce the above copyright ++.\" notice, this list of conditions and the following disclaimer in the ++.\" documentation and/or other materials provided with the distribution. ++.\" 3. [Deleted. See ++.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] ++.\" 4. Neither the name of the University nor the names of its contributors ++.\" may be used to endorse or promote products derived from this software ++.\" without specific prior written permission. ++.\" ++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++.\" SUCH DAMAGE. ++.\" ++.\" @(#)doc-ditroff 8.1 (Berkeley) 06/08/93 ++.\" ++.\" %beginstrip% ++. ++. ++.eo ++. ++.\" use -rD=1 for double-sided printing ++. ++.if !r D .nr D 0 ++. ++.\" use -rcR=1 to force the creation of a single, very long page ++. ++.if !r cR .nr cR 0 ++. ++.\" use -rS={11,12} to change the font size from 10pt to 11pt or 12pt. ++. ++.if !r S .nr S 10 ++. ++. ++.ec ++. ++. ++.ie (\n[S] == 11) \{\ ++. ps 10.95z ++. vs 13.6p ++.\} ++.el \{ .ie (\n[S] == 12) \{\ ++. ps 12z ++. vs 14.5p ++.\} ++.el \{\ ++. ps 10z ++. vs 12p ++.\}\} ++. ++. ++.\" the `doc-xx-font' strings must not be empty! ++. ++.ds doc-caption-font \f[R]\s[\n[.ps]u] ++.ds doc-caption-font2 \f[R]\s[\n[.ps]u] ++.ds doc-Ad-font \f[I]\s[\n[.ps]u] ++.ds doc-Ar-font \f[CO]\s[\n[.ps]u] ++.ds doc-Cm-font \f[CB]\s[\n[.ps]u] ++.ds doc-Em-font \f[I]\s[\n[.ps]u] ++.ds doc-Er-font \f[C]\s[\n[.ps]u] ++.ds doc-Ev-font \f[C]\s[\n[.ps]u] ++.ds doc-Fa-font \f[CO]\s[\n[.ps]u] ++.ds doc-Fd-font \f[CB]\s[\n[.ps]u] ++.ds doc-Fl-font \f[CB]\s[\n[.ps]u] ++.ds doc-Fn-font \f[CB]\s[\n[.ps]u] ++.ds doc-Ft-font \f[CO]\s[\n[.ps]u] ++.ds doc-Ic-font \f[CB]\s[\n[.ps]u] ++.ds doc-Li-font \f[C] ++.ds doc-Me-font \f[B]\s[\n[.ps]u] ++.ds doc-Nm-font \f[CB]\s[\n[.ps]u] ++.ds doc-No-font \f[R]\s[\n[.ps]u] ++.ds doc-Pa-font \f[C]\s[\n[.ps]u] ++.ds doc-Sh-font \f[B]\s[\n[.ps]u] ++.ds doc-Sy-font \f[B]\s[\n[.ps]u] ++.ds doc-Sx-font \f[B]\s[\n[.ps]u] ++.ds doc-Tn-font-shape \f[R] ++\# XXX: adapt to discrete LaTeX font sizes ++.ds doc-Tn-font-size \s[(\n[.ps]u - 1z)] ++.ds doc-Va-font \f[I]\s[\n[.ps]u] ++.ds doc-Xr-font \f[C]\s[\n[.ps]u] ++. ++.ds doc-left-parenthesis \f[R]\|(\|\f[]\s[\n[.ps]u] ++.ds doc-right-parenthesis \f[R]\|)\|\f[]\s[\n[.ps]u] ++.ds lp \f[R](\f[]\s[\n[.ps]u] ++.ds rp \f[R])\f[]\s[\n[.ps]u] ++.ds doc-left-bracket \f[R]\^[\^\f[]\s[\n[.ps]u] ++.ds doc-right-bracket \f[R]\^]\f[]\s[\n[.ps]u] ++. ++.tr *\[**] ++. ++.\" miscellaneous ++.nr doc-subheader-indent (\w\f[C],u * 5u) ++.nr doc-paragraph-space .5v ++. ++.nr doc-digit-width \w'\0'u ++.nr doc-fixed-width \w\f[C]0 ++. ++.eo ++. ++. ++.\" NS doc-header-space global register ++.\" NS the space between header and body ++. ++.nr doc-header-space .5i ++. ++. ++.\" NS doc-footer-space global register ++.\" NS the space between body and footer ++. ++.nr doc-footer-space .5i ++. ++. ++.\" NS doc-display-vertical global register ++.\" NS vertical space between list elements etc. ++. ++.nr doc-display-vertical 0 ++. ++. ++.\" NS doc-setup-page-layout macro ++.\" NS set up page layout ++.\" NS ++.\" NS modifies: ++.\" NS doc-display-vertical ++. ++.de doc-setup-page-layout ++. ie r LL \ ++. ll \n[LL]u ++. el \ ++. ll 6.5i ++. ++. ie r LT \ ++. lt \n[LT]u ++. el \ ++. lt 6.5i ++. ++. po 1i ++. ++. nr doc-display-vertical .5v ++.. ++. ++. ++.ds doc-left-singlequote \[oq] ++.ds doc-right-singlequote \[cq] ++. ++.\" the following strings are `official' ++.ds <= \[<=] ++.ds >= \[>=] ++.ds Lq \[lq] ++.ds Rq \[rq] ++.ds ua \[ua] ++.ds aa \[aa] ++.ds ga \[ga] ++.ds q \[dq] ++.ds Pi \[*p] ++.ds Ne \[!=] ++.ds Le \[<=] ++.ds Ge \[>=] ++.ds Lt < ++.ds Gt > ++.ds Pm \[+-] ++.ds If \[if] ++.ds Na \f[I]NaN\f[] ++.ds Ba \f[R]|\f[] ++.ds Am & ++. ++. ++.\" NS doc-header-string global string ++.\" NS the final string used for the manual page header ++. ++.ds doc-header-string ++. ++. ++.\" NS doc-setup-header macro ++.\" NS install and initialize header and footer support ++.\" NS ++.\" NS modifies: ++.\" NS doc-header-string ++. ++.de doc-setup-header ++. ds doc-header-string "\*[doc-document-title] ++. if !"\*[doc-section]"Null" \ ++. as doc-header-string \|(\*[doc-section]) ++. ++. wh 0 doc-header ++. wh -1.25i doc-footer ++. ++. br ++. ++. e@ doc-end-macro ++.. ++. ++. ++.\" NS doc-get-width macro ++.\" NS computes the width of a string as a multiple of `doc-fixed-width': ++.\" NS `.doc-get-width string' ++.\" NS ++.\" NS modifies: ++.\" NS doc-width ++. ++.de doc-get-width ++. nr doc-width \w\f[C]\$1 ++. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ ++. ie (\n[doc-width] % \n[doc-fixed-width]) \ ++. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) ++. el \ ++. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) ++. \} ++. el \{\ ++. ie \n[doc-width] \ ++. nr doc-width 1 ++. el \ ++. nr doc-width 0 ++. \} ++.. ++. ++. ++.\" NS doc-get-arg-width macro ++.\" NS computes the width of an argument as a multiple of ++.\" NS `doc-fixed-width': `.doc-get-arg-width arg-index' ++.\" NS ++.\" NS modifies: ++.\" NS doc-width ++. ++.de doc-get-arg-width ++. nr doc-width \w\f[C]\*[doc-arg\$1] ++. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ ++. ie (\n[doc-width] % \n[doc-fixed-width]) \ ++. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) ++. el \ ++. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) ++. \} ++. el \{\ ++. ie \n[doc-width] \ ++. nr doc-width 1 ++. el \ ++. nr doc-width 0 ++. \} ++.. ++. ++. ++.\" NS Ql user macro ++.\" NS quoted literal define ++.\" NS ++.\" NS modifies: ++.\" NS doc-argXXX ++.\" NS doc-arg-limit ++.\" NS doc-arg-ptr ++.\" NS doc-macro-name ++.\" NS doc-spaceXXX ++.\" NS doc-typeXXX ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-Ql ++.\" NS doc-reg-Ql1 ++.\" NS doc-reg-Ql2 ++.\" NS ++.\" NS width register `Ql' set in doc-common ++. ++.de Ql ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Ql ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Ql argument ... (#\n[.c]) ++. \} ++. ++. nr doc-reg-Ql (\n[doc-arg-ptr] + 1) ++. doc-get-arg-width \n[doc-reg-Ql] ++. ++. \" don't use quotes if we have more than two succeeding string arguments ++. nr doc-reg-Ql +1 ++. if (\n[doc-arg-limit] >= \n[doc-reg-Ql]) \ ++. if (\n[doc-type\n[doc-reg-Ql]] == 2) \ ++. nr doc-width 3 ++. ++. \" make a difference in quotation style for strings longer ++. \" than two characters ++. ie (\n[doc-width] > 2) \ ++. Li ++. el \{\ ++. ie \n[doc-arg-ptr] \{\ ++. \" we replace `Ql' with `Li' ++. ds doc-arg\n[doc-arg-ptr] Li ++. nr doc-arg-ptr -1 ++. \} ++. el \{\ ++. \" if .Ql has been called directly, we must shift all elements in ++. \" the argument vector to the right so that we can insert `Li' ++. nr doc-reg-Ql \n[doc-arg-limit] ++. nr doc-reg-Ql1 (\n[doc-arg-limit] + 1) ++. while \n[doc-reg-Ql] \{\ ++. rn doc-arg\n[doc-reg-Ql] doc-arg\n[doc-reg-Ql1] ++. rnn doc-type\n[doc-reg-Ql] doc-type\n[doc-reg-Ql1] ++. rn doc-space\n[doc-reg-Ql] doc-space\n[doc-reg-Ql1] ++. nr doc-reg-Ql -1 ++. nr doc-reg-Ql1 -1 ++. \} ++. ds doc-arg1 Li ++. nr doc-type1 1 ++. ds doc-space1 ++. nr doc-arg-limit +1 ++. \} ++. ++. ds doc-quote-left "\*[doc-left-singlequote] ++. ds doc-quote-right "\*[doc-right-singlequote] ++. doc-enclose-string ++. \} ++.. ++. ++. ++.ec ++. ++.\" EOF +diff -Nuar groff-1.22.3.old/tmac/doc-nroff groff-1.22.3/tmac/doc-nroff +--- groff-1.22.3.old/tmac/doc-nroff 2014-11-04 10:38:35.533520146 +0200 ++++ groff-1.22.3/tmac/doc-nroff 1970-01-01 02:00:00.000000000 +0200 +@@ -1,277 +0,0 @@ +-.\" -*- nroff -*- +-.\" +-.\" Copyright (c) 1991, 1993 +-.\" The Regents of the University of California. All rights reserved. +-.\" +-.\" Redistribution and use in source and binary forms, with or without +-.\" modification, are permitted provided that the following conditions +-.\" are met: +-.\" 1. Redistributions of source code must retain the above copyright +-.\" notice, this list of conditions and the following disclaimer. +-.\" 2. Redistributions in binary form must reproduce the above copyright +-.\" notice, this list of conditions and the following disclaimer in the +-.\" documentation and/or other materials provided with the distribution. +-.\" 3. [Deleted. See +-.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +-.\" 4. Neither the name of the University nor the names of its contributors +-.\" may be used to endorse or promote products derived from this software +-.\" without specific prior written permission. +-.\" +-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-.\" SUCH DAMAGE. +-.\" +-.\" @(#)doc-nroff 8.1 (Berkeley) 06/08/93 +-.\" +-.\" %beginstrip% +-. +-. +-.eo +-. +-.\" use -rD=1 for double-sided printing +-. +-.if !r D .nr D 0 +-. +-.\" use -rcR=0 to have multiple pages instead of a single, very long page +-. +-.if !r cR .nr cR 1 +-. +-.\" the following switch is ignored in nroff mode +-. +-.nr S 10 +-. +-.\" the `doc-xx-font' strings must not be empty! +-. +-.ds doc-caption-font \f[R] +-.ds doc-caption-font2 \f[R] +-.ds doc-Ad-font \f[I] +-.ds doc-Ar-font \f[I] +-.ds doc-Cm-font \f[B] +-.ds doc-Em-font \f[I] +-.ds doc-Er-font \f[R] +-.ds doc-Ev-font \f[R] +-.ds doc-Fa-font \f[I] +-.ds doc-Fd-font \f[B] +-.ds doc-Fl-font \f[B] +-.ds doc-Fn-font \f[B] +-.ds doc-Ft-font \f[I] +-.ds doc-Ic-font \f[B] +-.ds doc-Li-font \f[R] +-.ds doc-Me-font \f[B] +-.ds doc-Nm-font \f[B] +-.ds doc-No-font \f[R] +-.ds doc-Pa-font \f[I] +-.ds doc-Sh-font \f[B] +-.ds doc-Sy-font \f[B] +-.ds doc-Sx-font \f[I] +-.ds doc-Tn-font-shape \f[R] +-.ds doc-Tn-font-size +-.ds doc-Va-font \f[I] +-.ds doc-Xr-font \f[R] +-. +-.ds doc-left-parenthesis \f[R](\f[] +-.ds doc-right-parenthesis \f[R])\f[] +-.ds lp \f[R](\f[] +-.ds rp \f[R])\f[] +-.ds doc-left-bracket \f[R][\f[] +-.ds doc-right-bracket \f[R]]\f[] +-. +-.\" miscellaneous +-.nr doc-subheader-indent .5i +-.nr doc-paragraph-space 1v +-. +-.ec +-.nr doc-digit-width \w'\0\0'u +-.nr doc-fixed-width \w'0' +-.eo +-. +-. +-.\" NS doc-header-space global register +-.\" NS the space between header and body +-. +-.nr doc-header-space 0.5i +-. +-. +-.\" NS doc-footer-space global register +-.\" NS the space between body and footer +-. +-.nr doc-footer-space 0.5i +-. +-. +-.\" NS doc-display-vertical global register +-.\" NS vertical space between list elements etc. +-. +-.nr doc-display-vertical 0 +-. +-. +-.\" NS doc-setup-page-layout macro +-.\" NS set up page layout +-.\" NS +-.\" NS modifies: +-.\" NS doc-display-vertical +-. +-.de doc-setup-page-layout +-. ie r LL \ +-. ll \n[LL]u +-. el \ +-. ll 78n +-. +-. ie r LT \ +-. lt \n[LT]u +-. el \ +-. lt 78n +-. +-. po 0i +-. +-. nr doc-display-vertical 1v +-. ad l +-. na +-.. +-. +-. +-.ec +-. +-.ds doc-left-singlequote \[oq] +-.ds doc-right-singlequote \[cq] +-. +-.\" the following strings are `official' +-.ds <= \[<=] +-.ds >= \[>=] +-.ds aa \[aa] +-.ds ga \[ga] +-.ds q \[dq] +-.ds Ne \[!=] +-.ds Le \[<=] +-.ds Ge \[>=] +-.ds Lt < +-.ds Gt > +-.ds Pm \[+-] +-.ds Na \f[I]NaN\f[] +-.ds Ba \f[R]|\f[] +-.ds Am & +-. +-.\" Unicode TTYs have all glyph forms; for other TTY character sets we need +-.\" character representations which are different from GNU troff's standard +-.\" forms. +-.ie '\*[.T]'utf8' \{\ +-. ds Rq \[rq] +-. ds Lq \[lq] +-. ds ua \[ua] +-. ds Pi \[*p] +-. ds If \[if] +-.\} +-.el \{\ +-. ds Rq '' +-. ds Lq `` +-. ds ua ^ +-. ds Pi pi +-. ds If infinity +-.\} +-. +-.eo +-. +-. +-.\" NS doc-header-string global string +-.\" NS the final string used for the manual page header +-. +-.ds doc-header-string +-. +-. +-.\" NS doc-setup-header macro +-.\" NS install and initialize header and footer support +-.\" NS +-.\" NS modifies: +-.\" NS doc-header-string +-. +-.de doc-setup-header +-. ds doc-header-string "\*[doc-document-title] +-. if !"\*[doc-section]"Null" \ +-. as doc-header-string (\*[doc-section]) +-. +-. ie \n[cR] \ +-. doc-header +-. el \{\ +-. wh 0 doc-header +-. wh -1.167i doc-footer +-. \} +-. +-. e@ doc-end-macro +-.. +-. +-. +-.\" NS doc-get-width macro +-.\" NS computes the width of a string as a multiple of `doc-fixed-width': +-.\" NS `.doc-get-width string' +-.\" NS +-.\" NS modifies: +-.\" NS doc-width +-. +-.de doc-get-width +-. nr doc-width \w\$1 +-. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ +-. ie (\n[doc-width] % \n[doc-fixed-width]) \ +-. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) +-. el \ +-. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) +-. \} +-. el \ +-. nr doc-width 0 +-.. +-. +-. +-.\" NS doc-get-arg-width macro +-.\" NS computes the width of an argument as a multiple of +-.\" NS `doc-fixed-width': `.doc-get-arg-width arg-index' +-.\" NS +-.\" NS modifies: +-.\" NS doc-width +-. +-.de doc-get-arg-width +-. nr doc-width \w\*[doc-arg\$1] +-. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ +-. ie (\n[doc-width] % \n[doc-fixed-width]) \ +-. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) +-. el \ +-. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) +-. \} +-. el \ +-. nr doc-width 0 +-.. +-. +-. +-.\" NS Ql user macro +-.\" NS quoted literal define +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Ql' set in doc-common +-. +-.de Ql +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \ +-. ds doc-macro-name Ql +-. el \ +-. tm Usage: .Ql argument ... (#\n[.c]) +-. \} +-. +-. ds doc-quote-left "\*[doc-left-singlequote] +-. ds doc-quote-right "\*[doc-right-singlequote] +-. +-. doc-enclose-string \$@ +-.. +-. +-. +-.ec +-. +-.\" EOF +diff -Nuar groff-1.22.3.old/tmac/doc-nroff-u groff-1.22.3/tmac/doc-nroff-u +--- groff-1.22.3.old/tmac/doc-nroff-u 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/doc-nroff-u 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,277 @@ ++.\" -*- nroff -*- ++.\" ++.\" Copyright (c) 1991, 1993 ++.\" The Regents of the University of California. All rights reserved. ++.\" ++.\" Redistribution and use in source and binary forms, with or without ++.\" modification, are permitted provided that the following conditions ++.\" are met: ++.\" 1. Redistributions of source code must retain the above copyright ++.\" notice, this list of conditions and the following disclaimer. ++.\" 2. Redistributions in binary form must reproduce the above copyright ++.\" notice, this list of conditions and the following disclaimer in the ++.\" documentation and/or other materials provided with the distribution. ++.\" 3. [Deleted. See ++.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] ++.\" 4. Neither the name of the University nor the names of its contributors ++.\" may be used to endorse or promote products derived from this software ++.\" without specific prior written permission. ++.\" ++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++.\" SUCH DAMAGE. ++.\" ++.\" @(#)doc-nroff 8.1 (Berkeley) 06/08/93 ++.\" ++.\" %beginstrip% ++. ++. ++.eo ++. ++.\" use -rD=1 for double-sided printing ++. ++.if !r D .nr D 0 ++. ++.\" use -rcR=0 to have multiple pages instead of a single, very long page ++. ++.if !r cR .nr cR 1 ++. ++.\" the following switch is ignored in nroff mode ++. ++.nr S 10 ++. ++.\" the `doc-xx-font' strings must not be empty! ++. ++.ds doc-caption-font \f[R] ++.ds doc-caption-font2 \f[R] ++.ds doc-Ad-font \f[I] ++.ds doc-Ar-font \f[I] ++.ds doc-Cm-font \f[B] ++.ds doc-Em-font \f[I] ++.ds doc-Er-font \f[R] ++.ds doc-Ev-font \f[R] ++.ds doc-Fa-font \f[I] ++.ds doc-Fd-font \f[B] ++.ds doc-Fl-font \f[B] ++.ds doc-Fn-font \f[B] ++.ds doc-Ft-font \f[I] ++.ds doc-Ic-font \f[B] ++.ds doc-Li-font \f[R] ++.ds doc-Me-font \f[B] ++.ds doc-Nm-font \f[B] ++.ds doc-No-font \f[R] ++.ds doc-Pa-font \f[I] ++.ds doc-Sh-font \f[B] ++.ds doc-Sy-font \f[B] ++.ds doc-Sx-font \f[I] ++.ds doc-Tn-font-shape \f[R] ++.ds doc-Tn-font-size ++.ds doc-Va-font \f[I] ++.ds doc-Xr-font \f[R] ++. ++.ds doc-left-parenthesis \f[R](\f[] ++.ds doc-right-parenthesis \f[R])\f[] ++.ds lp \f[R](\f[] ++.ds rp \f[R])\f[] ++.ds doc-left-bracket \f[R][\f[] ++.ds doc-right-bracket \f[R]]\f[] ++. ++.\" miscellaneous ++.nr doc-subheader-indent .5i ++.nr doc-paragraph-space 1v ++. ++.ec ++.nr doc-digit-width \w'\0\0'u ++.nr doc-fixed-width \w'0' ++.eo ++. ++. ++.\" NS doc-header-space global register ++.\" NS the space between header and body ++. ++.nr doc-header-space 0.5i ++. ++. ++.\" NS doc-footer-space global register ++.\" NS the space between body and footer ++. ++.nr doc-footer-space 0.5i ++. ++. ++.\" NS doc-display-vertical global register ++.\" NS vertical space between list elements etc. ++. ++.nr doc-display-vertical 0 ++. ++. ++.\" NS doc-setup-page-layout macro ++.\" NS set up page layout ++.\" NS ++.\" NS modifies: ++.\" NS doc-display-vertical ++. ++.de doc-setup-page-layout ++. ie r LL \ ++. ll \n[LL]u ++. el \ ++. ll 78n ++. ++. ie r LT \ ++. lt \n[LT]u ++. el \ ++. lt 78n ++. ++. po 0i ++. ++. nr doc-display-vertical 1v ++. ad l ++. na ++.. ++. ++. ++.ec ++. ++.ds doc-left-singlequote \[oq] ++.ds doc-right-singlequote \[cq] ++. ++.\" the following strings are `official' ++.ds <= \[<=] ++.ds >= \[>=] ++.ds aa \[aa] ++.ds ga \[ga] ++.ds q \[dq] ++.ds Ne \[!=] ++.ds Le \[<=] ++.ds Ge \[>=] ++.ds Lt < ++.ds Gt > ++.ds Pm \[+-] ++.ds Na \f[I]NaN\f[] ++.ds Ba \f[R]|\f[] ++.ds Am & ++. ++.\" Unicode TTYs have all glyph forms; for other TTY character sets we need ++.\" character representations which are different from GNU troff's standard ++.\" forms. ++.ie '\*[.T]'utf8' \{\ ++. ds Rq \[rq] ++. ds Lq \[lq] ++. ds ua \[ua] ++. ds Pi \[*p] ++. ds If \[if] ++.\} ++.el \{\ ++. ds Rq '' ++. ds Lq `` ++. ds ua ^ ++. ds Pi pi ++. ds If infinity ++.\} ++. ++.eo ++. ++. ++.\" NS doc-header-string global string ++.\" NS the final string used for the manual page header ++. ++.ds doc-header-string ++. ++. ++.\" NS doc-setup-header macro ++.\" NS install and initialize header and footer support ++.\" NS ++.\" NS modifies: ++.\" NS doc-header-string ++. ++.de doc-setup-header ++. ds doc-header-string "\*[doc-document-title] ++. if !"\*[doc-section]"Null" \ ++. as doc-header-string (\*[doc-section]) ++. ++. ie \n[cR] \ ++. doc-header ++. el \{\ ++. wh 0 doc-header ++. wh -1.167i doc-footer ++. \} ++. ++. e@ doc-end-macro ++.. ++. ++. ++.\" NS doc-get-width macro ++.\" NS computes the width of a string as a multiple of `doc-fixed-width': ++.\" NS `.doc-get-width string' ++.\" NS ++.\" NS modifies: ++.\" NS doc-width ++. ++.de doc-get-width ++. nr doc-width \w\$1 ++. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ ++. ie (\n[doc-width] % \n[doc-fixed-width]) \ ++. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) ++. el \ ++. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) ++. \} ++. el \ ++. nr doc-width 0 ++.. ++. ++. ++.\" NS doc-get-arg-width macro ++.\" NS computes the width of an argument as a multiple of ++.\" NS `doc-fixed-width': `.doc-get-arg-width arg-index' ++.\" NS ++.\" NS modifies: ++.\" NS doc-width ++. ++.de doc-get-arg-width ++. nr doc-width \w\*[doc-arg\$1] ++. ie (\n[doc-width] >= \n[doc-fixed-width]) \{\ ++. ie (\n[doc-width] % \n[doc-fixed-width]) \ ++. nr doc-width ((\n[doc-width] / \n[doc-fixed-width]) + 1) ++. el \ ++. nr doc-width (\n[doc-width] / \n[doc-fixed-width]) ++. \} ++. el \ ++. nr doc-width 0 ++.. ++. ++. ++.\" NS Ql user macro ++.\" NS quoted literal define ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Ql' set in doc-common ++. ++.de Ql ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \ ++. ds doc-macro-name Ql ++. el \ ++. tm Usage: .Ql argument ... (#\n[.c]) ++. \} ++. ++. ds doc-quote-left "\*[doc-left-singlequote] ++. ds doc-quote-right "\*[doc-right-singlequote] ++. ++. doc-enclose-string \$@ ++.. ++. ++. ++.ec ++. ++.\" EOF +diff -Nuar groff-1.22.3.old/tmac/doc-old.tmac groff-1.22.3/tmac/doc-old.tmac +--- groff-1.22.3.old/tmac/doc-old.tmac 2014-11-04 10:38:35.533520146 +0200 ++++ groff-1.22.3/tmac/doc-old.tmac 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1857 +0,0 @@ +-.\" -*- nroff -*- +-.\" +-.\" Copyright (c) 1990 The Regents of the University of California. +-.\" All rights reserved. +-.\" +-.\" Redistribution and use in source and binary forms, with or without +-.\" modification, are permitted provided that the following conditions +-.\" are met: +-.\" 1. Redistributions of source code must retain the above copyright +-.\" notice, this list of conditions and the following disclaimer. +-.\" 2. Redistributions in binary form must reproduce the above copyright +-.\" notice, this list of conditions and the following disclaimer in the +-.\" documentation and/or other materials provided with the distribution. +-.\" 3. [Deleted. See +-.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +-.\" 4. Neither the name of the University nor the names of its contributors +-.\" may be used to endorse or promote products derived from this software +-.\" without specific prior written permission. +-.\" +-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-.\" SUCH DAMAGE. +-.\" +-.\" @(#)doc-old.tmac 5.2 (Berkeley) 3/13/91 +-.\" Slightly modified by jjc@jclark.com to work with groff as well. +-.\" +-.\" Assume nroff on crt's only if cR==1 +-.if n .nr cR 1 +-.\" STRING CONSTANTS +-.\" DITROFF +-.if t \{\ +-.\" Address Style +-.ds aD \fI +-.\" Argument Reference Style +-.ds aR \f(CO +-.\" Interactive Command Modifier (flag) +-.ds cM \f(CB +-.\" Emphasis (in the English sense - usually italics) +-.ds eM \fI +-.\" Errno Style +-.ds eR \fC +-.\" Environment Variable Style +-.ds eV \fC +-.\" Command Line Flag Style +-.ds fL \f(CB +-.\" Header String Style +-.ds Hs \fR +-.\" Interactive Command Style +-.ds iC \f(CB +-.\" Literal Style +-.ds lI \fC +-.\" Left Parenthesis Style +-.ds lP \fR\|(\|\fP +-.\" Right Parenthesis Style +-.ds rP \fR\|)\|\fP +-.\" Options Open Bracket Style +-.ds lB \fR\^[\^\fP +-.\" Options Open Bracket Style +-.ds rB \fR\^]\fP +-.\" Name (subject of manpage) Style +-.ds nM \f(CB +-.\" Pathname Style +-.ds pA \fC +-.\" Accepted punctuation string for -mdoc syntax +-.ds Pu \fR[.,:;(\^)[\^]\fR] +-.\" Section Header Style +-.ds Sp \s12\fB +-.\" .ds sT \s-2\fR +-.\" Symbolic Emphasis (boldface) +-.ds sY \f(CB +-.\" Generic Variable Style +-.ds vA \fI +-.\" Volume Title Style +-.ds Vs \fR +-.\" Cross Reference STyle (man page only) +-.ds xR \fC +-.\" Math * +-.tr *\(** +-.\} +-.\" NROFF +-.if n \{\ +-.\" Address Style +-.ds aD \fI +-.\" Argument Reference Style +-.ds aR \fI +-.\" Interactive Command Modifier (flag) +-.ds cM \fB +-.\" Emphasis (in the English sense - usually italics) +-.ds eM \fI +-.\" Errno Style +-.ds eR \fR +-.\" Environment Variable Style +-.ds eV \fR +-.\" Command Line Flag Style +-.ds fL \fB +-.\" Header String Style +-.ds Hs \fR +-.\" Interactive Command Style +-.ds iC \fB +-.\" Literal Style +-.ds lI \fR +-.\" Left Parenthesis Style +-.ds lP \fR\|(\fP +-.\" Right Parenthesis Style +-.ds rP \fR\|)\fP +-.\" Options Open Bracket Style +-.ds lB \fR\|[\|\fP +-.\" Options Open Bracket Style +-.ds rB \fR\|]\fP +-.\" Name (subject of manpage) Style +-.ds nM \fB +-.\" Pathname Style +-.ds pA \fI +-.\" Accepted punctuation string for -mdoc syntax +-.ds Pu [.,;:()[]] +-.\" Section Header Style +-.ds Sp \s12\fB +-.\" .ds sT \s-2\fR +-.\" .ds sT \s-2\fR +-.\" Symbol, Mode or Mask Style +-.ds sY \fB +-.\" Generic Variable Style +-.ds vA \fI +-.\" Volume Title Style +-.ds Vs \fR +-.\" Cross Reference Style (man page only) +-.ds xR \fR +-.\} +-.\" INDENTS - Subheaders(sI), Text(Ti) between Section Headers and Subsects +-.if t \{\ +-. nr sI \w'\fC,'u*5 +-. nr Ti \n(sIu +-.\} +-.if n \{\ +-. nr sI .5i +-. nr Ti .5i +-.\} +-.\" Flags for macros names which are used only for .Ds +-.nr dI 6n +-.nr dC 1 +-.nr dL 1 +-.nr dR 1 +-.\" INDENT WIDTHS (for Lists) +-.\" Width Needed for Address Tag (indented amount) +-.nr Ad 12n +-.\" Angle Quote Width +-.nr Aq 12n +-.\" Width Needed for Argument +-.nr Ar 12n +-.\" Width Needed for Column offset +-.nr Cl 15n +-.\" Width neeeded for Interactive Command Modifier +-.nr Cm 10n +-.\" Width Needed for Complex Expressions +-.nr Cx 20n +-.\" Indent Width Needed for Display (right and left margins) +-.nr Ds 6n +-.\" Double Quote Width +-.nr Dq 12n +-.\" tI is dependent on Ds and used by .Dp +-.nr tI \n(Dsu +-.\" Width Needed for Display +-.nr Em 10n +-.\" Width Needed for Errno Types +-.nr Er 15n +-.\" Width Needed for Environment Variables +-.nr Ev 15n +-.\" Width Needed for Example Indent +-.nr Ex 10n +-.\" Width Needed for Flag +-.nr Fl 10n +-.\" Width Needed for Function +-.nr Fn 16n +-.\" Width neeeded for Interactive Command Name +-.nr Ic 10n +-.\" Width Needed for Constant +-.nr Li 16n +-.\" Width Needed for Math Symbol ? not sure if needed +-.nr Ms 6n +-.\" Width Needed for Name +-.nr Nm 10n +-.\" Width Needed for Option Begin +-.nr Ob 14n +-.\" Width Needed for Option End +-.nr Oe 14n +-.\" Width Needed for Option (one line) +-.nr Op 14n +-.\" Width Needed for Pathname +-.nr Pa 32n +-.\" Parenthesis Quote Width +-.nr Pq 12n +-.\" Single Quote Width +-.nr Sq 12n +-.\" Width Needed for Symbols, Modes or Masks +-.nr Sy 6n +-.\" Width needed for default or unknown text width +-.nr Tx 22n +-.\" Width Needed for Generic Variable +-.nr Va 12n +-.\" Width Needed for Cross Reference, should the cross ref be annotated. +-.nr Xr 10n +-.\" PARAGRAPH SPACE +-.if t \{\ +-. nr Pp .5v +-.\} +-.if n \{\ +-. nr Pp 1v +-.\} +-.\" PAGE LAYOUT +-.\" .Li Tagged Paragraph Style - zero if break on oversized tag +-.\" one if add em space and continue filling line. +-.nr tP 0 +-.\" Page Layout Macro +-.de pL +-.\" DITROFF +-.ie t \{\ +-.\" Header Margin +-. nr Hm .5i +-.\" Footer Margin +-. nr Fm .5i +-.\" Line length +-. nr ll 5.5i +-.\" Line length +-. ll 5.5i +-.\" Title length +-. nr lt 5.5i +-.\" Title length +-. lt 5.5i +-.\" Page offset +-. nr po 1.56i +-.\" Page offset +-. po 1.56i +-.\" Vertical space distance (from Section headers/Lists/Subsections) +-. nr vV .5v +-.\" em space +-. ds tP \|\|\|\|\|\| +-.\} +-.el \{\ +-.\" Line length +-. nr ll 78n +-. ll 78n +-.\" Title length +-. nr lt 78n +-.\" Title length +-. lt 78n +-.\" Page offset +-. nr po 0i +-.\" Page offset +-. po 0i +-.\" Vertical space distance (from Section headers/Lists/Subsections) +-. nr vV 1v +-.\" em space +-. ds tP \0\0 +-.\" Test for crt +-. ie \\n(cR .nr Hm 0 +-. el .nr Hm .5i +-.\" Footer Margin +-. nr Fm .5i +-.\} +-.. +-.\" Adjustment mode +-.if n \{\ +-.ad l +-.na +-.. +-.\} +-.\" PREDEFINED STRINGS +-.if t \{\ +-. ds <= \(<= +-. ds >= \(>= +-. ds Lq \&`` +-. ds Rq \&'' +-. ds ua \(ua +-. ds aa \(aa +-. ds ga \(ga +-. ds sR \(aa +-. ds sL \(ga +-.\} +-.if n \{\ +-. ds <= \&<\&= +-. ds >= \&>\&= +-. ds Rq '' +-. ds Lq `` +-. ds ua ^ +-. ds aa ' +-. ds ga ` +-. ds sL ` +-. ds sR ' +-.\} +-.\" Note: The distances from the bottom or top of the page are set +-.\" in headers (macro .hK): to -1.25 for troff, and -1.167 for nroff +-.\" bottoms, and top is 0. +-.\" +-.\" .Dt Document/manpage_title section/chapter volume +-.\" The \{ and \} is necessary as roff doesn't nest if-elses +-.\" properly, especially with .ds. +-.\" TODO: separate Dt into Dt, Ch and Vt for supp docs. +-.de Dt +-.ds dT UNTITLED +-.ds vT Local +-.ds cH Null +-.\" Volume and Section Number or Chapter Number +-.if !"\\$1"" .ds dT \\$1 +-.if !"\\$2"" \{\ +-. ds cH \\$2 +-. if "\\$3"" \{\ +-. \" Volume Title if none given +-. if \\$2>=1 .if \\$2<=8 \{\ +-. ds vT UNIX Reference Manual +-. if \\$2>1 .if \\$2<6 .ds vT UNIX Programmer's Manual +-. if "\\$2"8" .ds vT UNIX System Manager's Manual +-. \} +-. if "\\$2"unass" .ds vT DRAFT +-. if "\\$2"draft" .ds vT DRAFT +-. if "\\$2"paper" .ds vT Null +-. \} +-.\} +-.if !"\\$3"" \{\ +-. \" Volume Title if given +-. if "\\$3"USD" .ds vT UNIX User's Supplementary Documents +-. if "\\$3"PS1" .ds vT UNIX Programmers's Supplementary Documents +-. if "\\$3"AMD" .ds vT UNIX Ancestral Manual Documents +-. if "\\$3"SMM" .ds vT UNIX System Manager's Manual +-. if "\\$3"URM" .ds vT UNIX Reference Manual +-. if "\\$3"PRM" .ds vT UNIX Programmers's Manual +-. if "\\$3"IND" .ds vT UNIX Manual Master Index +-. if "\\$3"CON" .ds vT UNIX Contributed Software Manual +-. if "\\$3"IMP" .ds vT UNIX Implementation Notes +-. if "\\$3"HOW" .ds vT UNIX How Pocket Manual +-. if "\\$3"LOCAL" .ds vT UNIX Local Manual +-. if "\\*(vT"Local" .ds vT \\$3 +-.\} +-.. +-.\" +-.\" .Os Operating System/Standard and Release or Version Number +-.\" +-.de Os +-.ds oS Null +-.if "\\$1"" \{\ +-. ds oS \fIBSD Experimental\fP +-.\" . ds oS (\fIBag o' Bits\fP) +-.\} +-.if "\\$2"" \{\ +-. ds o1 Non-Null +-.\} +-.if "\\$1"ATT" \{\ +-. ds oS AT&T +-. if "\\$2"" .as oS \0UNIX +-. if "\\$2"7th" .as oS \07th Edition +-. if "\\$2"7" .as oS \07th Edition +-. if "\\$2"III" .as oS \0System III +-. if "\\$2"3" .as oS \0System III +-. if "\\$2"V" .as oS \0System V +-. if "\\$2"V.2" .as oS \0System V Release 2 +-. if "\\$2"V.3" .as oS \0System V Release 3 +-. if "\\$2"V.4" .as oS \0System V Release 4 +-.\} +-.if "\\$1"BSD" \{\ +-. if "\\$2"3" .ds oS 3rd Berkeley Distribution +-. if "\\$2"4" .ds oS 4th Berkeley Distribution +-. if "\\$2"4.1" .ds oS 4.1 Berkeley Distribution +-. if "\\$2"4.2" .ds oS 4.2 Berkeley Distribution +-. if "\\$2"4.3" .ds oS 4.3 Berkeley Distribution +-. if "\\$2"4.3+" .ds oS 4.3+tahoe Berkeley Distribution +-.\} +-.if "\\*(oS"Null" .ds oS \\$1 +-.if "\\*(o1"Non-Null" .as oS \0\\$2 +-.rm o1 +-.. +-.\" +-.\" Standards +-.\" +-.\" .de St +-.\" .ds sT Null +-.\" .if "\\$1"POSIX" \{\ +-.\" . ds sT IEEE Standard POSIX +-.\" . if \\$2 .as sT \0\\$2 +-.\" .\} +-.\" .if "\\$1"ANSI" \{\ +-.\" . ds sT ANSI Standard +-.\" . if \\$2 .as sT \0\\$2 +-.\" .\} +-.\" .if "\\$1"ISO" \{\ +-.\" . ds sT ISO Standard +-.\" . if \\$2 .as sT \0\\$2 +-.\" .\} +-.\" .if "\\*(sT"Null" .ds sR \\$3 +-.\" .. +-.\" +-.\" .de Gp +-.\" .ie !"\\$1"" .ds gP \&\\$1 \\$2 \\$3 \\$4 \\$5 +-.\" .el .ds gP Null +-.\" .. +-.\" +-.\" +-.de Dd +-.nr aa 0 +-.ie \\n(.$>0 \{\ +-. ie \\n(.$<4 \{\ +-. ds dD \\$1 \\$2 \\$3 +-. \} +-. el .tm Usage: .Dd Month Day, Year (e.g July 4, 1977). +-.\} +-.el \{\ +-. ds dD Epoch +-.\} +-.. +-.\" +-.\" House Keeping Macro - Make sense of dT, cH, vT, sT, gP and dS +-.\" TODO: Try to get else's for efficiency +-.\" TODO: GET RID OF .wh -1.167i (its in v7) +-.\" +-.\" +-.de hK +-.nr % 1 +-.ds hT \\*(dT +-.if !"\\*(cH"Null" \{\ +-. ie !"\\*(gP"Null" .as hT \|(\|\\*(cH\\*(gP\|) +-. el .as hT \\|(\\|\\*(cH\\|) +-.\} +-.if "\\*(cH"Null" .if !"\\*(gP"Null" .as hT \&\|(\|\\*(gP\|) +-.if t \{\ +-. wh 0 hM +-. wh -1.25i fM +-.\} +-.if n \{\ +-. ie \\n(cR \{\ +-. hM +-. wh -0v fM +-. \} +-. el \{\ +-. wh 0 hM +-. wh -1.167i fM +-. \} +-.\} +-.if n \{\ +-. if \\n(nl==0:\\n(nl==-1 'bp +-.\} +-.if t 'bp +-.em lM +-.. +-.\" Header Macro +-.\" +-.de hM +-.ev 1 +-.pL +-.if !\\n(cR 'sp \\n(Hmu +-.tl @\\*(Hs\\*(hT\fP@\\*(Vs\\*(vT\fP@\\*(Hs\\*(hT\fP@ +-'sp \\n(Hmu +-.ev +-.. +-.\" +-.de fM +-.ev 1 +-.pL +-.if !\\n(cR \{\ +-' sp \\n(Fmu +-. tl @\\*(Hs\\*(oS\fP@\\*(Vs\\*(dD\fP@%@ +-' bp +-.\} +-.if \\n(cR \{\ +-.\" . tl @\\*(Hs\\*(oS\fP@\\*(Vs\\*(dD\fP@%@ +-.\" ' bp +-.\} +-.ev +-.. +-.de lM +-.fl +-.if \\n(cR \{\ +-. fM +-. pl \\n(nlu +-.\} +-.. +-.de Pp +-.sp \\n(Ppu +-.ne 2 +-.ns +-.. +-.de Lp +-.Pp +-.. +-.de LP +-.tm Not a \-mdoc command: .LP +-.. +-.de PP +-.tm Not a \-mdoc command: .PP +-.. +-.de pp +-.tm Not a \-mdoc command: .pp +-.. +-.de Co +-.tm Not a \-mdoc command: .Co +-.. +-.nr z. 1 +-.nr z, 1 +-.nr z: 1 +-.nr z; 1 +-.nr z) 1 +-.nr z( 1 +-.nr z[ 1 +-.nr z] 1 +-.\" This is disgusting, troff not parse if stmt properly +-.nr z1 0 +-.nr z2 0 +-.nr z3 0 +-.nr z4 0 +-.nr z5 0 +-.nr z6 0 +-.nr z7 0 +-.nr z8 0 +-.nr z9 0 +-.nr z0 0 +-.nr z# 0 +-.\" +-.de Ad +-.ie \\n(.$==0 \{\ +-. tm Usage: .Ad address [...] \\*(Pu +-.\} +-.el \{\ +-. ds sV \\*(aD +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.\" Command Line Argument Macro +-.\" +-.de Ar +-.ie \\n(.$==0 \{\ +-. ie !"\\*(iM"" .as f1 \&[\|\\*(aRfile\ ...\fP\|] +-. el \&[\|\\*(aRfile\ ...\fP\|] +-.\} +-.el \{\ +-. ds sV \\*(aR +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.de Em +-.ie \\n(.$==0 \{\ +-. tm Usage: .Em text ... \\*(Pu +-.\} +-.el \{\ +-. ds sV \\*(eM +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.de Er +-.ie \\n(.$==0 \{\ +-. tm Usage: .Er ERRNOTYPE ... \\*(Pu +-. \} +-.el \{\ +-. ds sV \\*(eR +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.de Ev +-.ie \\n(.$==0 \{\ +-. tm Usage: .Ev ENVIRONMENT_VARIABLE(s) ... \\*(Pu +-. \} +-.el \{\ +-. ds sV \\*(eV +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.\" Flag Name Macro +-.\" +-.de Fl +-.ie \\n(.$==0 \{\ +-. ie !"\\*(iM"" .as f1 \&\\*(fL\-\fP +-. el \&\\*(fL\-\fP +-.\} +-.el \{\ +-. nr rZ 0 +-. sW \\$1 +-. if (\\n(sW==1&\\n(.$==1) .rZ \\$1 +-. ds sV \\*(fL +-. nr cF \\n(.f +-. ie \\n(rZ \{\ +-. ie "\\*(iM"" .ds f1 \&\\*(sV\-\f\\n(cF\\$1 +-. el \&\\*(sV\-\f\\n(cF\\$1 +-. \} +-. el \{\ +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. fB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-. \} +-.\} +-.. +-.\" Interactive Commands Macro +-.\" +-.de Ic +-.ie \\n(.$==0 \{\ +-. tm Usage: .Ic Interactive Commands(s) ... \\*(Pu +-.\} +-.el \{\ +-. ds sV \\*(iC +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.\" Interactive Command Modifiers (flags) +-.\" +-.de Cm +-.ie \\n(.$==0 \{\ +-. tm Usage: .Cm Interactive Command Modifier(s) ... \\*(Pu +-.\} +-.el \{\ +-. ds sV \\*(cM +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.de Li +-.ie \\n(.$==0 \{\ +-. tm Usage: .Li literal ... \\*(Pu +-. \} +-.el \{\ +-. ds sV \\*(lI +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" If in nroff or any other case where the default font +-.\" is constant width, and literal means zilch, single quote instead. +-.ie n \{\ +-.de Ql +-. ie \\n(.$==0 \{\ +-. tm Usage: .Ql literal ... \\*(Pu +-. \} +-. el \{\ +-. Sq \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. \} +-.. +-.\} +-.el \{\ +-.de Ql +-. ie \\n(.$==0 \{\ +-. tm Usage: .Ql literal ... \\*(Pu +-. \} +-. el \{\ +-. Li \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. \} +-.. +-.\} +-.\" +-.de Nm +-.ie \\n(.$==0 \{\ +-. if "\\*(n1"" .tm Usage: .Nm Name(s) ... \\*(Pu +-. ie !"\\*(iM"" .as f1 \&\\*(nM\\*(n1\\$1\fP +-. el \&\\*(nM\\*(n1\\$1\fP +-.\} +-.el \{\ +-. ds sV \\*(nM +-. nr cF \\n(.f +-. if \\n(nS \{\ +-. rs +-. in -\\n(iSu +-. ie \\n(nS>1 .br +-. el \{\ +-. sW \\$1 +-. nr iS ((\\n(sW+1)*\\n(fW)u +-. \} +-. in +\\n(iSu +-. ti -\\n(iSu +-. nr nS \\n(nS+1 +-. \} +-. if "\\*(n1"" .ds n1 \\$1 +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.de Pa +-.ie \\n(.$==0 \{\ +-\&\\*(pA~\fP +-.\} +-.el \{\ +-. ds sV \\*(pA +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.de Sy +-.ie \\n(.$==0 \{\ +-. tm Usage: .Sy Symbolic Text ... \\*(Pu +-. \} +-.el \{\ +-. ds sV \\*(sY +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.de Ms +-.ie \\n(.$==0 \{\ +-. tm Usage: .Ms Math Symbol ... \\*(Pu +-. \} +-.el \{\ +-. ds sV \\*(sY +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.de Va +-.ie \\n(.$==0 \{\ +-. tm Usage: .Va variable_name(s) ... \\*(Pu +-.\} +-.el \{\ +-. ds sV \\*(vA +-. nr cF \\n(.f +-. ie "\\*(iM"" .ds f1 \&\\*(sV +-. el .as f1 \&\\*(sV +-. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-.\} +-.. +-.\" +-.de nB +-.hy 0 +-.if \\n(.$==0 .tm Usage error: called with empty arguments (empty quotes)? +-.ie \\n(.$>1 \{\ +-. rZ \\$1 +-. ie \\n(rZ .as f1 \&\f\\n(cF\\$1\fP +-. el .as f1 \&\\$1 +-. rZ \\$2 +-. if !\\n(rZ \{\ +-. ie !"\\*(iM""\{\ +-.\" I surrender +-. if "\\*(iM"Tp" .as f1 \&\ \& +-. if "\\*(iM"Dp" .as f1 \&\ \& +-. if "\\*(iM"Op" .as f1 \&\ \& +-. if "\\*(iM"Cx" .as f1 \&\ \& +-. if "\\*(iM"Dq" .as f1 \& \& +-. if "\\*(iM"Sq" .as f1 \& \& +-. if "\\*(iM"Pq" .as f1 \& \& +-. if "\\*(iM"Aq" .as f1 \& \& +-. \} +-. el .as f1 \& \& +-. \} +-. nB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.\} +-.el \{\ +-. rZ \\$1 +-. ie \\n(rZ .as f1 \&\f\\n(cF\\$1 +-. el .as f1 \&\\$1\f\\n(cF +-. if "\\*(iM"" \{\&\\*(f1 +-. ds f1 +-. \} +-. hy +-.\} +-.. +-.de fB +-.hy 0 +-.if \\n(.$==0 .tm Usage error: called with empty arguments (empty quotes)? +-.ie \\n(.$>1 \{\ +-. rZ \\$1 +-. ie \\n(rZ .as f1 \&\f\\n(cF\\$1\fP +-. el \{\ +-. ie "\\$1"-" .as f1 \&\-\- +-. el .as f1 \&\-\\$1 +-. \} +-. rZ \\$2 +-. if !\\n(rZ \{\ +-. ie !"\\*(iM""\{\ +-.\" I surrender +-. if "\\*(iM"Tp" .as f1 \&\ \& +-. if "\\*(iM"Dp" .as f1 \&\ \& +-. if "\\*(iM"Op" .as f1 \&\ \& +-. if "\\*(iM"Cx" .as f1 \&\ \& +-. if "\\*(iM"Dq" .as f1 \& \& +-. if "\\*(iM"Sq" .as f1 \& \& +-. if "\\*(iM"Pq" .as f1 \& \& +-. if "\\*(iM"Aq" .as f1 \& \& +-. \} +-. el .as f1 \& \& +-. \} +-. fB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.\} +-.el \{\ +-. rZ \\$1 +-. ie \\n(rZ .as f1 \&\f\\n(cF\\$1 +-. el \{\ +-. ie "\\$1"-" .as f1 \&\-\-\f\\n(cF +-. el .as f1 \&\-\\$1\f\\n(cF +-. \} +-. if "\\*(iM"" \{\&\\*(f1 +-. ds f1 +-. \} +-. hy +-.\} +-.. +-.\" +-.\" Single quoted Items +-.\" eF, sB g[0-9] and f2 +-.de Sq +-.nr eF 0 +-.ie \\n(.$==0 \{\ +-. ie "\\*(iM"" \&\\*(sL\&\\*sR +-. el .as f1 \&\\*(sL\&\\*(sR +-.\} +-.el \{\ +-. ie "\\*(iM"" \{\ +-. ds f1 \&\\*(sL +-. ds iM Sq +-. \} +-. el .as f1 \&\\*(sL +-. sB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ie \\n(eF>0 .\\*(g1 \\*(g2 \\*(g3 \\*(g4 \\*(g5 \\*(g6 \\*(g7 \\*(g8 +-. el .as f1 \\*(g0 +-. as f1 \\*(sR +-. if !"\\*(f2"" .as f1 \\*(f2 +-. if "\\*(iM"Sq" \{\ +-\&\\*(f1 +-. ds f1 +-. ds iM +-. \} +-. ds f2 +-. rm g0 g1 g2 g3 g4 g5 g6 g7 g8 g9 +-. nr eF 0 +-.\} +-.. +-.\" +-.\" Double quoted Items +-.de Dq +-.nr Ef 0 +-.ie \\n(.$==0 \{\ +-. ie "\\*(iM"" \&\\*(Lq\&\\*(Rq +-. el .as f1 \&\\*(Lq\&\\*(Rq +-.\} +-.el \{\ +-. ie "\\*(iM"" \{\ +-. ds f1 \&\\*(Lq +-. ds iM Dq +-. \} +-. el .as f1 \&\\*(Lq +-. Sb \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ie \\n(Ef>0 .\\*(k1 \\*(k2 \\*(k3 \\*(k4 \\*(k5 \\*(k6 \\*(k7 \\*(k8 +-. el .as f1 \\*(k0 +-. as f1 \\*(Rq +-. if !"\\*(f4"" .as f1 \\*(f4 +-. if "\\*(iM"Dq" \{\ +-\&\\*(f1 +-. ds f1 +-. ds iM +-. \} +-. ds f4 +-. rm k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 +-. nr Ef 0 +-.\} +-.. +-.\" +-.\" Parenthesis quoted Items +-.de Pq +-.nr pQ 0 +-.ie \\n(.$==0 \{\ +-. ie "\\*(iM"" \&(\&) +-. el .as f1 \&(\&) +-.\} +-.el \{\ +-. ie "\\*(iM"" \{\ +-. ds f1 \&( +-. ds iM Pq +-. \} +-. el .as f1 \&( +-. pB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ie \\n(pQ>0 .\\*(y1 \\*(y2 \\*(y3 \\*(y4 \\*(y5 \\*(y6 \\*(y7 \\*(y8 +-. el .as f1 \\*(y0 +-. as f1 \&) +-. if !"\\*(f3"" .as f1 \\*(f3 +-. if "\\*(iM"Pq" \{\ +-\&\\*(f1 +-. ds f1 +-. ds iM +-. \} +-. ds f3 +-. rm y0 y1 y2 y3 y4 y5 y6 y7 y8 y9 +-. nr pQ 0 +-.\} +-.. +-.\" eF, sB g[0-9] and f2 +-.de sB +-.hy 0 +-.ie \\n(.$==0 .tm Sick Logic: macro sB +-.el \{\ +-. ie \\n(eF>=1 .nr eF \\n(eF+1 +-. el \{\ +-. mN \\$1 +-. if \\n(mN .nr eF \\n(eF+1 +-. \} +-. rZ \\$1 +-. ie \\n(rZ .as f2 \\$1 +-. el \{\ +-. ie \\n(eF<1 .as g\\n(eF \\$1 +-. el .as g\\n(eF \\$1 +-. \} +-. if \\n(.$>1 \{\ +-. rZ \\$2 +-. if \\n(rZ==0 \{\ +-. if \\n(eF<1 \{\ +-. as g\\n(eF \& \& +-. \} +-. \} +-. sB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. \} +-.\} +-.. +-.de Sb +-.hy 0 +-.ie \\n(.$==0 .tm Sick Logic: macro Sb +-.el \{\ +-. ie \\n(Ef>=1 .nr Ef \\n(Ef+1 +-. el \{\ +-. mN \\$1 +-. if \\n(mN .nr Ef \\n(Ef+1 +-. \} +-. rZ \\$1 +-. ie \\n(rZ .as f4 \\$1 +-. el \{\ +-. ie \\n(Ef<1 .as k\\n(Ef \\$1 +-. el .as k\\n(Ef \\$1 +-. \} +-. if \\n(.$>1 \{\ +-. rZ \\$2 +-. if \\n(rZ==0 \{\ +-. if \\n(Ef<1 \{\ +-. as k\\n(Ef \& \& +-. \} +-. \} +-. Sb \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. \} +-.\} +-.. +-.de pB +-.hy 0 +-.ie \\n(.$==0 .tm Sick Logic: macro pB +-.el \{\ +-. ie \\n(pQ>=1 .nr pQ \\n(pQ+1 +-. el \{\ +-. mN \\$1 +-. if \\n(mN .nr pQ \\n(pQ+1 +-. \} +-. rZ \\$1 +-. ie \\n(rZ .as f3 \\$1 +-. el \{\ +-. ie \\n(pQ<1 .as y\\n(pQ \\$1 +-. el .as y\\n(pQ \\$1 +-. \} +-. if \\n(.$>1 \{\ +-. rZ \\$2 +-. if \\n(rZ==0 \{\ +-. if \\n(pQ<1 \{\ +-. as y\\n(pQ \& \& +-. \} +-. \} +-. pB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. \} +-.\} +-.. +-.de aQ +-.hy 0 +-.ie \\n(.$==0 .tm Bad Syntax: .Aq +-.el \{\ +-. ie \\n(aQ>=1 .nr aQ \\n(aQ+1 +-. el \{\ +-. mN \\$1 +-. if \\n(mN .nr aQ \\n(aQ+1 +-. \} +-. rZ \\$1 +-. ie \\n(rZ .as aZ \\$1 +-. el \{\ +-. ie \\n(aQ<1 .as a\\n(aQ \\$1 +-. el .as a\\n(aQ \\$1 +-. \} +-. if \\n(.$>1 \{\ +-. rZ \\$2 +-. if \\n(rZ==0 \{\ +-. if \\n(aQ<1 \{\ +-. as a\\n(aQ \& \& +-. \} +-. \} +-. aQ \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. \} +-.\} +-.. +-.\" Angle Bracket Quoted Items +-.de Aq +-.nr aQ 0 +-.ie \\n(.$==0 \{\ +-. ie "\\*(iM"" \&<\&> +-. el .as f1 \&<\&> +-.\} +-.el \{\ +-. ie "\\*(iM"" \{\ +-. ds f1 \&< +-. ds iM Aq +-. \} +-. el .as f1 \&< +-. aQ \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +-. ie \\n(aQ>0 .\\*(a1 \\*(a2 \\*(a3 \\*(a4 \\*(a5 \\*(a6 \\*(a7 \\*(a8 +-. el .as f1 \\*(a0 +-. as f1 \&> +-. if !"\\*(aZ"" .as f1 \\*(aZ +-. if "\\*(iM"Aq" \{\ +-\&\\*(f1 +-. ds f1 +-. ds iM +-. \} +-. ds aZ +-. rm a0 a1 a2 a3 a4 a5 a6 a7 a8 +-. nr aQ 0 +-.\} +-.. +-.\" macro Name test, return macro register value if true +-.if \n(.g .ig +-.de mN +-.nr mN 0 +-.sW \\$1 +-.if \\n(sW==2 \{\ +-. if \\n(\\$1 .nr mN \\n(\\$1 +-.\} +-.. +-.if !\n(.g .ig +-.de mN +-.nr mN 0 +-.if \A'\\$1' \{\ +-. sW \\$1 +-. if \\n(sW==2 \{\ +-. if \\n(\\$1 .nr mN \\n(\\$1 +-. \} +-.\} +-.. +-.\" Punctuation test (using z registers), return 1 if true +-.if \n(.g .ig +-.de rZ +-.nr rZ 0 +-.sW \\$1 +-.if \\n(sW==1 \{\ +-. if \\n(z\\$1==1 \{\ +-. nr rZ 1 +-. \} +-.\} +-.. +-.if !\n(.g .ig +-.de rZ +-.nr rZ 0 +-.if \A'\\$1' \{\ +-. sW \\$1 +-. if \\n(sW==1 \{\ +-. if \\n(z\\$1==1 \{\ +-. nr rZ 1 +-. \} +-. \} +-.\} +-.. +-.\" +-.\" sW returns number of characters in a string +-.if t \{\ +-.nr fW \w'\fC,' +-.de sW +-.nr sW \w'\fC\\$1' +-.\} +-.if n \{\ +-.nr fW \w'0' +-.de sW +-.nr sW \w'\\$1' +-.\} +-.ie \\n(sW>=\\n(fW \{\ +-. ie \\n(sW%\\n(fW .nr sW (\\n(sW/\\n(fW)+1 +-. el .nr sW \\n(sW/\\n(fW +-.\} +-.el .nr sW 0 +-.. +-.\" Option Expression - +-.\" TODO - add line overflow check (right!) +-.nr eP 0 +-.ds e1 +-.nr oE 0 +-.nr hP 0 +-.ds hP +-.nr Ep 0 +-.de Op +-.hy 0 +-.if "\\*(iM"" \{\ +-. ds iM Op +-. ds f1 \& +-.\} +-.as f1 \&\\*(lB +-.\" .tm Op: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.dO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.ie !"\\$1"Cx" .oE +-.el .nr oE \\n(oE+1 +-.. +-.\" +-.\" just for mike, with every bite of garlic in mind (oops, i mean burp). +-.\" dO: go dOwn an argument vector and test each argument to see if +-.\" a macro name or punctuation. stash in respective place along +-.\" with its arguments. +-.nr oO 0 +-.nr oP 0 +-.nr aO 0 +-.de dO +-.mN \\$1 +-.ie \\n(mN \{\ +-. if \\n(oP \{\ +-. if \\n(hP \{\ +-. nr oZ 1 +-. oZ +-. Oz +-. \} +-. if \\n(e1==1 \{\ +-.\\*(e1 \\*(e2 \\*(e3 \\*(e4 \\*(e5 \\*(e6 \\*(e7 \\*(e8 \\*(e9 +-. \} +-. uO +-. if !(\\n(oO:\\n(aO) .as f1 \& \& +-. \} +-. ie "\\$1"Op" \{\ +-. as f1 \&\\*(lB +-. nr aO \\n(aO+1 +-. \} +-. el \{\ +-. nr eP \\n(eP+1 +-. ds e\\n(eP \\$1 +-. nr e\\n(eP 1 +-. \} +-.\} +-.el \{\ +-.\" .tm dO: $1: \\$1: eP \\n(eP e[\\n(eP]: \\*(e\\n(ePEE +-. rZ \\$1 +-. ie \\n(rZ \{\ +-.\" .tm dO:rZ: $1: \\$1: eP \\n(eP e[\\n(eP]: \\*(e\\n(eP +-. nr hP \\n(hP+1 +-. ds h\\n(hP \\$1 +-. \} +-. el \{\ +-.\" .tm dO:word $1: \\$1: eP \\n(eP e[\\n(eP]: \\*(e\\n(ePEE +-. if \\n(eP==0:\\n(e\\n(eP==1 .nr eP \\n(eP+1 +-. if \\n(eZ .as e\\n(eP \& \& +-. as e\\n(eP " \&\\$1 +-.\" . ds e\\n(eP \&\\$1 +-. nr eZ \\n(eZ+1 +-. \} +-.\} +-.nr oP 1 +-.ie \\n(.$>1 \{\ +-. dO \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.\} +-.el \{\ +-. ie \\n(e1 \{\ +-.\\*(e1 \\*(e2 \\*(e3 \\*(e4 \\*(e5 \\*(e6 \\*(e7 \\*(e8 \\*(e9 +-. \} +-. el \{\ +-. as f1 \\*(e1 +-. \} +-.\} +-.. +-.\" handle old style arguments such as the arg -Idir +-.\" in adb, .Oo is a toggle. +-.de Oo +-.ie \\n(oO .nr oO 0 +-.el .nr oO 1 +-.. +-.\" stash punctuation +-.de oZ +-.if \\n(hP>=\\n(oZ \{\ +-. nr eP \\n(eP+1 +-. ds e\\n(eP \\*(h\\n(oZ +-. nr oZ \\n(oZ+1 +-. oZ +-.\} +-.. +-.\" clean up punctuation vector +-.de Oz +-.if \\n(hP>0 \{\ +-. rm h\\n(hP +-. nr hP \\n(hP-1 +-. Oz +-.\} +-.. +-.\" uO: go back up created vector cleaning it up along the way +-.de uO +-.if \\n(eP>0 \{\ +-. rm e\\n(eP +-. rr e\\n(eP +-. nr eP \\n(eP-1 +-. nr oP 0 +-. nr eZ 0 +-. uO +-.\} +-.. +-.\" option end +-.de oE +-.uO +-.ie \\n(hP \{\ +-. as f1 \\*(rB\\*(h1\\*(h2\\*(h3 +-. Oz +-. nr oZ 0 +-.\} +-.el \{\ +-. as f1 \\*(rB +-.\} +-.ie "\\*(iM"Op" \{\ +-. if \\n(aO .aO +-.if t \{\ +-. if (\\n(.lu-\\n(.ku-\\n(.ou-(2*\\n(fWu))<\w'\fC\\*(f1'u .br +-.\} +-.if n \{\ +-. nr aa \w'\\*(f1'u +-.\" . nr qq \\n(.lu-\\n(.ku-\\n(.ou +-.\" \&aa == \\n(aa, f1==\\*(f1, qq==\\n(qq +-. if (\\n(.lu-\\n(.ku-\\n(.ou-\\n(aau)<=(8*\\n(fWu) .br +-.\} +-\&\\*(f1 +-. ds iM +-. ds f1 +-. hy +-.\} +-.el .nr oE \\n(oE-1 +-.. +-.de aO +-.as f1 \\*(rB +-.nr aO \\n(aO-1 +-.if \\n(aO >0 .aO +-.. +-.\" +-.de Xr +-.if \\n(.$<=1 \{\ +-. ie \\n(.$==1 \{\ +-. if !"\\*(iM"" .as f1 \&\\*(xR\\$1\fP +-. if "\\*(iM"" \&\\*(xR\\$1\fP +-. \} +-. el .tm Xr Usage: .Xr manpage_name [section#] \\*(Pu +-.\} +-.if \\n(.$==2 \{\ +-. rZ \\$2 +-. ie "\\*(iM"" \{\ +-. ie \\n(rZ \&\\*(xR\\$1\fP\\$2 +-. el \&\\*(xR\\$1\fP(\\$2) +-. \} +-. el \{\ +-. ie \\n(rZ .as f1 \&\\*(xR\\$1\fP\\$2 +-. el .as f1 \&\\*(xR\\$1\fP(\\$2) +-. \} +-.\} +-.if \\n(.$>=3 \{\ +-. rZ \\$2 +-. ie \\n(rZ \{\ +-. ie !"\\*(iM"" .as f1 \&\\*(xR\\$1\fP\\$2\\$3\\$4\\$5\\$6\\$7\\$8 +-. el \&\\*(xR\\$1\fP\\$2\\$3\\$4\\$5\\$6\\$7\\$8 +-. \} +-. el \{\ +-. rZ \\$3 +-. ie \\n(rZ \{\ +-. if !"\\*(iM"" \{\ +-. as f1 \&\\*(xR\\$1\fP(\\$2)\\$3\\$4\\$5\\$6\\$7\\$8 +-. \} +-. if "\\*(iM"" \{\ +-\&\\*(xR\\$1\fP(\\$2)\\$3\\$4\\$5\\$6\\$7\\$8 +-. \} +-. \} +-. el \{\ +-. tm rZ = \\n(rZ the arg is \\$3 +-. tm Xr-XX Usage: .Xr manpage_name [section#] \\*(Pu +-. \} +-. \} +-.\} +-.. +-.\" +-.\" +-.de Ex +-.tm Ex defunct, Use .Dl: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.. +-.\" Display (one) Line of text. +-.de Dl +-.ie "\\*(iM"" \{\ +-' ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +-. in \\n(.iu+\\n(Dsu +-. mN \\$1 +-. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. el \{\ +-. nr cF \\n(.f +-.\" Literal font is none specified +-\&\\*(lI\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. ft \\n(cF +-. \} +-. in \\n(.iu-\\n(Dsu +-.\} +-.el \{\ +-. mN \\$1 +-. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +-. el \{\ +-. nr cF \\n(.f +-. ds f1 \&\\*(lI\\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +-. as f1 \&\f\\n(cF +-. \} +-.\} +-.. +-.\" +-.\" +-.\" user set Tagged Paragraph Width (used in both Dp and Tp) +-.de Tw +-.ie \\n(.$==0 \{\ +-. nr aa 0 +-.\} +-.el \{\ +-. mN \\$1 +-. ie \\n(sW>2 \{\ +-. nr tW (\\n(sW+3)*\\n(fWu) +-. \} +-. el \{\ +-. ie \\n(mN .nr tW \\n(mN +-. el .nr tW \\$1 +-. \} +-. nr tF 1 +-.\} +-.. +-.\" +-.de Dw +-.Tw \\$1 +-.. +-.\" +-.de Di +-.ie \\n(.$==0 \{\ +-. nr tI \\n(Dsu +-.\} +-.el \{\ +-. sW \\$1 +-. if \\n(sW>=2 \{\ +-. nr tI \\$1u +-. \} +-. if \\n(sW<2 \{\ +-. if "\\$1"L" \{\ +-. nr tI 0 +-. \} +-. \} +-.\} +-.. +-.\" tagged paragraph +-.\" initialize baby stack variables +-.nr np 0 +-.nr p1 0 +-.ds s\n(np +-.\" +-.de Tp +-.ie "\\$1"" .pE p s np +-.el \{\ +-. ds iM Tp +-. mN \\$1 +-. ie \\n(tF \{\ +-. ds tC Tw +-. nr tC 1 +-. nr tF 0 +-. \} +-. el \{\ +-. if !"Tw"\\*(s\\n(np" \{\ +-. ie \\n(mN \{\ +-. ds tC \\$1 +-. nr tW \\n(mN +-. \} +-. el \{\ +-. ds tC Tx +-. nr tW \\n(Tx +-. \} +-. if !"\\*(tC"\\*(s\\n(np" .nr tC 1 +-. \} +-. \} +-. sp \\n(vVu +-. if !\\n(cR .ne 2 +-. if \\n(tC \{\ +-. nr np \\n(np+1 +-. nr p\\n(np \\n(tW +-. ds s\\n(np \\*(tC +-. nr tC 0 +-. ds tC +-. in \\n(.iu+\\n(p\\n(npu +-. \} +-. ie \\n(mN \{\ +-. ds f1 +-. \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. if !"\\$1"Cx" .pT st p np +-. \} +-. el \{\ +-. br +-. ev 1 +-. fi +-. di Td +-\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. br +-. di +-. ev +-. na +-. ds tD \\*(Td\\ +-. pT di p np +-. \} +-.\} +-.. +-.\" +-.\" +-.\" Complex Expression Macro +-.\" +-.\" TODO: add length across line boundary check (like Li) +-.de Cx +-.hy 0 +-.ie \\n(.$==0 \{\ +-. if "\\*(iM"Cx" \{\ +-. ds iM +-. if \\n(oE .oE +-\&\\*(f1 +-. ds f1 +-. \} +-. if "\\*(iM"Tp" .pT st p np +-. if "\\*(iM"Dp" .pT st q mp +-.\} +-.el \{\ +-. if "\\*(iM"" \{\ +-. ds iM Cx +-. ds f1 \& +-. \} +-. mN \\$1 +-.\" Here are the args: `\\$1' `\\$2' `\\$3' `\\$4' +-. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. el \{\ +-. as f1 \&\\$1 +-. if \\n(.$>1 .Cx \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. \} +-.\} +-.. +-.\" Prefix string in default font to content specified string +-.de Pf +-.Cx \\$1 +-.\\$2 \\$3 \\$4 \\$5 +-.Cx +-.. +-.\" Suffix string in default font to content specified string +-.de Sf +-.Cx \\$1 \\$2 +-.Cx \\$3 +-.Cx +-.. +-.\" Simple Option Begin +-.de Ob +-.hy 0 +-.ie "\\*(iM"" \{\ +-. ev 2 +-. fi +-. di oB +-.\} +-.el \{\ +-.tm shouldn't be here +-. as f1 \&[ +-. mN \\$1 +-. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. el \{\ +-. as f1 \&\\$1 +-. if \\n(.$>1 .Oc \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. \} +-.\} +-.. +-.de Oc +-.as f1 \&\\$1 +-.if \\n(.$>1 .Oc \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.. +-.de Oe +-.hy 0 +-.ie "\\*(iM"" \{\ +-. br +-. di +-. ev +-. ds bO \\*(oB\\ +-\&[\\*(bO\&] +-.\} +-.el \{\ +-. as f1 \&] +-.\} +-.. +-.\" White space for Cx +-.de Ws +-.Cx \&\ \& +-.. +-.\" tagged paragraph +-.\" initialize baby stack variables +-.nr mp 0 +-.nr q1 0 +-.ds r\n(np +-.\" +-.\" Complex Dp tag +-.de Dc +-.Dp Cx \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +-.. +-.\" Complex Tp tag +-.de Tc +-.Tp Cx \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +-.. +-.\" Tag with a flag and an argument with a space +-.de Ta +-.if "\\$2"" \{\ +-. Tp Fl \\$1 +-.\} +-.el \{\ +-. Tp Fl \\$1 +-. Cx \&\ \& +-. Ar \\$2 \\$3 +-. Cx +-.\} +-.. +-.de Da +-.Dp Cx Fl \\$1 +-.Ws +-.Ar \\$2 \\$3 +-.Cx +-.. +-.de To +-.Tp Cx Fl \\$1 +-.Ar \\$2 \\$3 +-.Cx +-.. +-.de Do +-.Dp Cx Fl \\$1 +-.Ar \\$2 \\$3 +-.Cx +-.. +-.\" Blended tag toggle +-.de Bt +-.ie \\n(tP==0 .nr tP 1 +-.el .nr tP 0 +-.. +-.\" Bullet paragraph +-.de Bu +-.Tp Sy \&\(bu +-.. +-.\" Display tagged paragraph +-.de Dp +-.ie "\\$1"" \{\ +-. pE q r mp +-. sp \\n(vVu +-.\} +-.el \{\ +-. ds iM Dp +-. mN \\$1 +-. ie \\n(tF \{\ +-. ds tC Tw +-. nr tC 1 +-. nr tF 0 +-. \} +-. el \{\ +-. if !"Tw"\\*(r\\n(mp" \{\ +-. ie \\n(mN \{\ +-. ds tC \\$1 +-. nr tW \\n(mN +-. \} +-. el \{\ +-. ds tC Tx +-. nr tW \\n(Tx +-. \} +-. if !"\\*(tC"\\*(r\\n(mp" .nr tC 1 +-. \} +-. \} +-. if !\\n(cR .ne 2 +-. if \\n(tC \{\ +-. nr mp \\n(mp+1 +-. nr q\\n(mp \\n(tW +-. ds r\\n(mp \\*(tC +-. nr tC 0 +-. ds tC +-. ie \\n(tIu==\\n(Dsu .nr i\\n(mp \\n(Dsu +-. el \{\ +-. nr i\\n(mp \\n(tIu +-. nr tI \\n(Dsu +-. \} +-. in \\n(.iu+\\n(i\\n(mpu +-. sp \\n(vVu +-. in \\n(.iu+\\n(\\q\\n(mpu +-. \} +-. ie \\n(mN \{\ +-. \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. if !"\\$1"Cx" .pT st q mp +-. \} +-. el \{\ +-. br +-. ev 1 +-. fi +-. di Td +-\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. br +-. di +-. ev +-. na +-. ds tD \\*(Td\\ +-. pT di q mp +-. \} +-.\} +-.. +-.\" +-.\" .pE number_stack string_stack counter +-.de pE +-.ie "\\$3"mp" \{\ +-. in \\n(.iu-(\\n(\\$1\\n(\\$3u)-(\\n(i\\n(mpu) +-. rr i\\n(mp +-.\} +-.el .in \\n(.iu-\\n(\\$1\\n(\\$3u +-.\" .in \\n(.iu-\\n(\\$1\\n(\\$3u +-.if \\n(\\$3<=0 .tm Extraneous call .Tp or .Dp +-.rr \\$1\\n(\\$3 +-.rm \\$2\\n(\\$3 +-.nr \\$3 \\n(\\$3-1 +-.ds iM +-.. +-.\" +-.\" .pT [st or di] number_stack counter +-.de pT +-.ie "\\$1"st" \{\ +-. nr bb \\n(\\$2\\n(\\$3u +-. ti -\\n(bbu +-. ie (\\n(\\$2\\n(\\$3u-2n)<=\w'\\*(f1'u \{\&\\*(f1\\*(tP +-. if \\n(tP==0 .br +-. \} +-. el \\*(f1\h'|\\n(\\$2\\n(\\$3u'\c +-.\} +-.el \{\ +-. ti -\\n(\\$2\\n(\\$3u +-. ie (\\n(\\$2\\n(\\$3u-2n)<=\\n(dlu \{\&\\*(tD\\*(tP +-. if !\\n(tP .br +-. \} +-. el \\*(tD\h'|\\n(\\$2\\n(\\$3u'\c +-. if t 'ad +-.\} +-. ds iM +-. ds f1 +-'fi +-.. +-.\" +-.\" The new SH +-.\" +-.de Sh +-.\" set Sh state off, check for list state before calling indent (.In) +-.nr nS 0 +-.nr sE 0 +-.ie "\\$1"NAME" \{\ +-.\" name state on, housekeep (headers & footers) +-. hK +-' in 0 +-.\} +-.el \{\ +-. if "\\$1"SYNOPSIS" .nr nS 1 +-. in 0 +-.\} +-.pL +-'sp +-.ns +-.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +-.if !\\n(cR .ne 3 +-'fi +-\&\fB\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 \|\\$7 \|\\$8 \|\\$9 +-\&\fP\& +-.in \\n(.iu+\\n(Tiu +-.if "\\$1"SEE" .nr sE 1 +-.ns +-.. +-.\" +-.\" Nd minus sign for an en dash used in .Sh Name +-.de Nd +-\&\-\& \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.. +-.de Ss +-.sp +-.ti -.25i +-\&\fB\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 \|\\$7 \|\\$8 \|\\$9 +-\&\fP\& +-.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +-.if !\\n(cR .ne 2 +-.br +-.. +-.\" .if "\\$1"Ss" .in \\n(.iu+\\n(sIu +-.\".. +-.\" +-.\" +-.\" Column Macro +-.\" +-.hy 0 +-.de Cw +-.ie \\n(.$==0 \{\ +-. br +-. in \\n(.iu-\\n(eWu +-. ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +-.\} +-.el \{\ +-. Pp +-. if \\n(.$==1 \{\ +-. ta \w'\\$1 'u +-. nr eW \w'\\$1 'u +-' in \\n(.iu+\\n(eWu +-. \} +-. if \\n(.$==2 \{\ +-. ta \w'\\$1 'u +\w'\\$2 'u +-. nr eW \w'\\$1 'u+\w'\\$2 'u +-' in \\n(.iu+\\n(eWu +-. \} +-. if \\n(.$==3 \{\ +-. ta \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +-. nr eW \w'\\$1 'u+\w'\\$2 'u+\w'\\$3 'u +-' in \\n(.iu+\\n(eWu +-. \} +-. if \\n(.$==4 \{\ +-. ta \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +\w'\\$4 'u +-. nr eW \w'\\$1 'u+\w'\\$2 'u+\w'\\$3 'u +\w'\\$4 'u +-' in \\n(.iu+\\n(eWu +-. \} +-. if \\n(.$==5 \{\ +-.ta \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +\w'\\$4 'u +\w'\\$5 'u +-.nr eW \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +\w'\\$4 'u +\w'\\$5 'u +-' in \\n(.iu+\\n(eWu +-. \} +-.\} +-.. +-.de Cl +-.ti -\\n(eWu +-.mN \\$1 +-.ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.el \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.. +-.nr dQ 0 +-.de Ds +-.ie !"\\$1"" \{\ +-. mN d\\$1 +-. if \\n(mN \{\ +-. nr dQ \\n(dQ+1 +-. d\\$1 +-. \} +-.\} +-.el .br +-.nf +-.. +-.de Df +-.ie !"\\$1"" \{\ +-. mN d\\$1 +-. if \\n(mN \{\ +-. nr dQ \\n(dQ+1 +-. d\\$1 +-. \} +-.\} +-.el .br +-.. +-.de Dn +-\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-.nf +-.. +-.de dI +-.nr d\\n(dQ \\n(dIu +-.in \\n(.iu+\\n(dIu +-.. +-.de dC +-.nr d\\n(dQ (\\n(.l-\\n(.i)/4u +-.in \\n(.iu+\\n(d\\n(dQu +-.. +-.de dR +-.nr d\\n(dQ (\\n(.l/3)u +-.in \\n(.iu+\\n(d\\n(dQu +-.. +-.de dL +-.nr aa 0 +-.. +-.de De +-.br +-.if \\n(d\\n(dQ \{\ +-. in \\n(.iu-\\n(d\\n(dQu +-. rr d\\n(dQ +-. nr dQ \\n(dQ-1 +-.\} +-.fi +-.. +-.\" +-.de Fn +-.ie \\n(.$==0 \{\ +-. tm Usage: .Fn function_name function_arg(s) ... \\*(Pu +-.\} +-.el \{\ +-. nr cF \\n(.f +-. ie \\n(.$==1 .ds f1 \&\\*(nM\\$1\fP\\*(lP\fP\\*(rP\fP +-. el \{\ +-. ds f1 \\*(nM\\$1\fP\\*(lP +-. nr aa 0 +-. rC \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 +-. \} +-. if "\\*(iM"" \{\\&\\*(f1 +-. ds f1 +-. \} +-.\} +-.. +-.\" +-.de rC +-.rZ \\$1 +-.ie \\n(rZ \{\ +-. as f1 \f\\n(cF\\*(rP\f\\n(cF\\$1\\$2\\$3\\$4\\$5\\$6\\$7 +-.\} +-.el \{\ +-. ie \\n(aa .as f1 \fP, \\*(aR\\$1 +-. el .as f1 \\*(aR\\$1 +-. nr aa 1 +-. ie \\n(.$>1 .rC \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 +-. el .as f1 \fP\\*(rP\fP +-.\} +-.. +diff -Nuar groff-1.22.3.old/tmac/doc-old.tmac-u groff-1.22.3/tmac/doc-old.tmac-u +--- groff-1.22.3.old/tmac/doc-old.tmac-u 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/doc-old.tmac-u 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,1857 @@ ++.\" -*- nroff -*- ++.\" ++.\" Copyright (c) 1990 The Regents of the University of California. ++.\" All rights reserved. ++.\" ++.\" Redistribution and use in source and binary forms, with or without ++.\" modification, are permitted provided that the following conditions ++.\" are met: ++.\" 1. Redistributions of source code must retain the above copyright ++.\" notice, this list of conditions and the following disclaimer. ++.\" 2. Redistributions in binary form must reproduce the above copyright ++.\" notice, this list of conditions and the following disclaimer in the ++.\" documentation and/or other materials provided with the distribution. ++.\" 3. [Deleted. See ++.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] ++.\" 4. Neither the name of the University nor the names of its contributors ++.\" may be used to endorse or promote products derived from this software ++.\" without specific prior written permission. ++.\" ++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++.\" SUCH DAMAGE. ++.\" ++.\" @(#)doc-old.tmac 5.2 (Berkeley) 3/13/91 ++.\" Slightly modified by jjc@jclark.com to work with groff as well. ++.\" ++.\" Assume nroff on crt's only if cR==1 ++.if n .nr cR 1 ++.\" STRING CONSTANTS ++.\" DITROFF ++.if t \{\ ++.\" Address Style ++.ds aD \fI ++.\" Argument Reference Style ++.ds aR \f(CO ++.\" Interactive Command Modifier (flag) ++.ds cM \f(CB ++.\" Emphasis (in the English sense - usually italics) ++.ds eM \fI ++.\" Errno Style ++.ds eR \fC ++.\" Environment Variable Style ++.ds eV \fC ++.\" Command Line Flag Style ++.ds fL \f(CB ++.\" Header String Style ++.ds Hs \fR ++.\" Interactive Command Style ++.ds iC \f(CB ++.\" Literal Style ++.ds lI \fC ++.\" Left Parenthesis Style ++.ds lP \fR\|(\|\fP ++.\" Right Parenthesis Style ++.ds rP \fR\|)\|\fP ++.\" Options Open Bracket Style ++.ds lB \fR\^[\^\fP ++.\" Options Open Bracket Style ++.ds rB \fR\^]\fP ++.\" Name (subject of manpage) Style ++.ds nM \f(CB ++.\" Pathname Style ++.ds pA \fC ++.\" Accepted punctuation string for -mdoc syntax ++.ds Pu \fR[.,:;(\^)[\^]\fR] ++.\" Section Header Style ++.ds Sp \s12\fB ++.\" .ds sT \s-2\fR ++.\" Symbolic Emphasis (boldface) ++.ds sY \f(CB ++.\" Generic Variable Style ++.ds vA \fI ++.\" Volume Title Style ++.ds Vs \fR ++.\" Cross Reference STyle (man page only) ++.ds xR \fC ++.\" Math * ++.tr *\(** ++.\} ++.\" NROFF ++.if n \{\ ++.\" Address Style ++.ds aD \fI ++.\" Argument Reference Style ++.ds aR \fI ++.\" Interactive Command Modifier (flag) ++.ds cM \fB ++.\" Emphasis (in the English sense - usually italics) ++.ds eM \fI ++.\" Errno Style ++.ds eR \fR ++.\" Environment Variable Style ++.ds eV \fR ++.\" Command Line Flag Style ++.ds fL \fB ++.\" Header String Style ++.ds Hs \fR ++.\" Interactive Command Style ++.ds iC \fB ++.\" Literal Style ++.ds lI \fR ++.\" Left Parenthesis Style ++.ds lP \fR\|(\fP ++.\" Right Parenthesis Style ++.ds rP \fR\|)\fP ++.\" Options Open Bracket Style ++.ds lB \fR\|[\|\fP ++.\" Options Open Bracket Style ++.ds rB \fR\|]\fP ++.\" Name (subject of manpage) Style ++.ds nM \fB ++.\" Pathname Style ++.ds pA \fI ++.\" Accepted punctuation string for -mdoc syntax ++.ds Pu [.,;:()[]] ++.\" Section Header Style ++.ds Sp \s12\fB ++.\" .ds sT \s-2\fR ++.\" .ds sT \s-2\fR ++.\" Symbol, Mode or Mask Style ++.ds sY \fB ++.\" Generic Variable Style ++.ds vA \fI ++.\" Volume Title Style ++.ds Vs \fR ++.\" Cross Reference Style (man page only) ++.ds xR \fR ++.\} ++.\" INDENTS - Subheaders(sI), Text(Ti) between Section Headers and Subsects ++.if t \{\ ++. nr sI \w'\fC,'u*5 ++. nr Ti \n(sIu ++.\} ++.if n \{\ ++. nr sI .5i ++. nr Ti .5i ++.\} ++.\" Flags for macros names which are used only for .Ds ++.nr dI 6n ++.nr dC 1 ++.nr dL 1 ++.nr dR 1 ++.\" INDENT WIDTHS (for Lists) ++.\" Width Needed for Address Tag (indented amount) ++.nr Ad 12n ++.\" Angle Quote Width ++.nr Aq 12n ++.\" Width Needed for Argument ++.nr Ar 12n ++.\" Width Needed for Column offset ++.nr Cl 15n ++.\" Width neeeded for Interactive Command Modifier ++.nr Cm 10n ++.\" Width Needed for Complex Expressions ++.nr Cx 20n ++.\" Indent Width Needed for Display (right and left margins) ++.nr Ds 6n ++.\" Double Quote Width ++.nr Dq 12n ++.\" tI is dependent on Ds and used by .Dp ++.nr tI \n(Dsu ++.\" Width Needed for Display ++.nr Em 10n ++.\" Width Needed for Errno Types ++.nr Er 15n ++.\" Width Needed for Environment Variables ++.nr Ev 15n ++.\" Width Needed for Example Indent ++.nr Ex 10n ++.\" Width Needed for Flag ++.nr Fl 10n ++.\" Width Needed for Function ++.nr Fn 16n ++.\" Width neeeded for Interactive Command Name ++.nr Ic 10n ++.\" Width Needed for Constant ++.nr Li 16n ++.\" Width Needed for Math Symbol ? not sure if needed ++.nr Ms 6n ++.\" Width Needed for Name ++.nr Nm 10n ++.\" Width Needed for Option Begin ++.nr Ob 14n ++.\" Width Needed for Option End ++.nr Oe 14n ++.\" Width Needed for Option (one line) ++.nr Op 14n ++.\" Width Needed for Pathname ++.nr Pa 32n ++.\" Parenthesis Quote Width ++.nr Pq 12n ++.\" Single Quote Width ++.nr Sq 12n ++.\" Width Needed for Symbols, Modes or Masks ++.nr Sy 6n ++.\" Width needed for default or unknown text width ++.nr Tx 22n ++.\" Width Needed for Generic Variable ++.nr Va 12n ++.\" Width Needed for Cross Reference, should the cross ref be annotated. ++.nr Xr 10n ++.\" PARAGRAPH SPACE ++.if t \{\ ++. nr Pp .5v ++.\} ++.if n \{\ ++. nr Pp 1v ++.\} ++.\" PAGE LAYOUT ++.\" .Li Tagged Paragraph Style - zero if break on oversized tag ++.\" one if add em space and continue filling line. ++.nr tP 0 ++.\" Page Layout Macro ++.de pL ++.\" DITROFF ++.ie t \{\ ++.\" Header Margin ++. nr Hm .5i ++.\" Footer Margin ++. nr Fm .5i ++.\" Line length ++. nr ll 5.5i ++.\" Line length ++. ll 5.5i ++.\" Title length ++. nr lt 5.5i ++.\" Title length ++. lt 5.5i ++.\" Page offset ++. nr po 1.56i ++.\" Page offset ++. po 1.56i ++.\" Vertical space distance (from Section headers/Lists/Subsections) ++. nr vV .5v ++.\" em space ++. ds tP \|\|\|\|\|\| ++.\} ++.el \{\ ++.\" Line length ++. nr ll 78n ++. ll 78n ++.\" Title length ++. nr lt 78n ++.\" Title length ++. lt 78n ++.\" Page offset ++. nr po 0i ++.\" Page offset ++. po 0i ++.\" Vertical space distance (from Section headers/Lists/Subsections) ++. nr vV 1v ++.\" em space ++. ds tP \0\0 ++.\" Test for crt ++. ie \\n(cR .nr Hm 0 ++. el .nr Hm .5i ++.\" Footer Margin ++. nr Fm .5i ++.\} ++.. ++.\" Adjustment mode ++.if n \{\ ++.ad l ++.na ++.. ++.\} ++.\" PREDEFINED STRINGS ++.if t \{\ ++. ds <= \(<= ++. ds >= \(>= ++. ds Lq \&`` ++. ds Rq \&'' ++. ds ua \(ua ++. ds aa \(aa ++. ds ga \(ga ++. ds sR \(aa ++. ds sL \(ga ++.\} ++.if n \{\ ++. ds <= \&<\&= ++. ds >= \&>\&= ++. ds Rq '' ++. ds Lq `` ++. ds ua ^ ++. ds aa ' ++. ds ga ` ++. ds sL ` ++. ds sR ' ++.\} ++.\" Note: The distances from the bottom or top of the page are set ++.\" in headers (macro .hK): to -1.25 for troff, and -1.167 for nroff ++.\" bottoms, and top is 0. ++.\" ++.\" .Dt Document/manpage_title section/chapter volume ++.\" The \{ and \} is necessary as roff doesn't nest if-elses ++.\" properly, especially with .ds. ++.\" TODO: separate Dt into Dt, Ch and Vt for supp docs. ++.de Dt ++.ds dT UNTITLED ++.ds vT Local ++.ds cH Null ++.\" Volume and Section Number or Chapter Number ++.if !"\\$1"" .ds dT \\$1 ++.if !"\\$2"" \{\ ++. ds cH \\$2 ++. if "\\$3"" \{\ ++. \" Volume Title if none given ++. if \\$2>=1 .if \\$2<=8 \{\ ++. ds vT UNIX Reference Manual ++. if \\$2>1 .if \\$2<6 .ds vT UNIX Programmer's Manual ++. if "\\$2"8" .ds vT UNIX System Manager's Manual ++. \} ++. if "\\$2"unass" .ds vT DRAFT ++. if "\\$2"draft" .ds vT DRAFT ++. if "\\$2"paper" .ds vT Null ++. \} ++.\} ++.if !"\\$3"" \{\ ++. \" Volume Title if given ++. if "\\$3"USD" .ds vT UNIX User's Supplementary Documents ++. if "\\$3"PS1" .ds vT UNIX Programmers's Supplementary Documents ++. if "\\$3"AMD" .ds vT UNIX Ancestral Manual Documents ++. if "\\$3"SMM" .ds vT UNIX System Manager's Manual ++. if "\\$3"URM" .ds vT UNIX Reference Manual ++. if "\\$3"PRM" .ds vT UNIX Programmers's Manual ++. if "\\$3"IND" .ds vT UNIX Manual Master Index ++. if "\\$3"CON" .ds vT UNIX Contributed Software Manual ++. if "\\$3"IMP" .ds vT UNIX Implementation Notes ++. if "\\$3"HOW" .ds vT UNIX How Pocket Manual ++. if "\\$3"LOCAL" .ds vT UNIX Local Manual ++. if "\\*(vT"Local" .ds vT \\$3 ++.\} ++.. ++.\" ++.\" .Os Operating System/Standard and Release or Version Number ++.\" ++.de Os ++.ds oS Null ++.if "\\$1"" \{\ ++. ds oS \fIBSD Experimental\fP ++.\" . ds oS (\fIBag o' Bits\fP) ++.\} ++.if "\\$2"" \{\ ++. ds o1 Non-Null ++.\} ++.if "\\$1"ATT" \{\ ++. ds oS AT&T ++. if "\\$2"" .as oS \0UNIX ++. if "\\$2"7th" .as oS \07th Edition ++. if "\\$2"7" .as oS \07th Edition ++. if "\\$2"III" .as oS \0System III ++. if "\\$2"3" .as oS \0System III ++. if "\\$2"V" .as oS \0System V ++. if "\\$2"V.2" .as oS \0System V Release 2 ++. if "\\$2"V.3" .as oS \0System V Release 3 ++. if "\\$2"V.4" .as oS \0System V Release 4 ++.\} ++.if "\\$1"BSD" \{\ ++. if "\\$2"3" .ds oS 3rd Berkeley Distribution ++. if "\\$2"4" .ds oS 4th Berkeley Distribution ++. if "\\$2"4.1" .ds oS 4.1 Berkeley Distribution ++. if "\\$2"4.2" .ds oS 4.2 Berkeley Distribution ++. if "\\$2"4.3" .ds oS 4.3 Berkeley Distribution ++. if "\\$2"4.3+" .ds oS 4.3+tahoe Berkeley Distribution ++.\} ++.if "\\*(oS"Null" .ds oS \\$1 ++.if "\\*(o1"Non-Null" .as oS \0\\$2 ++.rm o1 ++.. ++.\" ++.\" Standards ++.\" ++.\" .de St ++.\" .ds sT Null ++.\" .if "\\$1"POSIX" \{\ ++.\" . ds sT IEEE Standard POSIX ++.\" . if \\$2 .as sT \0\\$2 ++.\" .\} ++.\" .if "\\$1"ANSI" \{\ ++.\" . ds sT ANSI Standard ++.\" . if \\$2 .as sT \0\\$2 ++.\" .\} ++.\" .if "\\$1"ISO" \{\ ++.\" . ds sT ISO Standard ++.\" . if \\$2 .as sT \0\\$2 ++.\" .\} ++.\" .if "\\*(sT"Null" .ds sR \\$3 ++.\" .. ++.\" ++.\" .de Gp ++.\" .ie !"\\$1"" .ds gP \&\\$1 \\$2 \\$3 \\$4 \\$5 ++.\" .el .ds gP Null ++.\" .. ++.\" ++.\" ++.de Dd ++.nr aa 0 ++.ie \\n(.$>0 \{\ ++. ie \\n(.$<4 \{\ ++. ds dD \\$1 \\$2 \\$3 ++. \} ++. el .tm Usage: .Dd Month Day, Year (e.g July 4, 1977). ++.\} ++.el \{\ ++. ds dD Epoch ++.\} ++.. ++.\" ++.\" House Keeping Macro - Make sense of dT, cH, vT, sT, gP and dS ++.\" TODO: Try to get else's for efficiency ++.\" TODO: GET RID OF .wh -1.167i (its in v7) ++.\" ++.\" ++.de hK ++.nr % 1 ++.ds hT \\*(dT ++.if !"\\*(cH"Null" \{\ ++. ie !"\\*(gP"Null" .as hT \|(\|\\*(cH\\*(gP\|) ++. el .as hT \\|(\\|\\*(cH\\|) ++.\} ++.if "\\*(cH"Null" .if !"\\*(gP"Null" .as hT \&\|(\|\\*(gP\|) ++.if t \{\ ++. wh 0 hM ++. wh -1.25i fM ++.\} ++.if n \{\ ++. ie \\n(cR \{\ ++. hM ++. wh -0v fM ++. \} ++. el \{\ ++. wh 0 hM ++. wh -1.167i fM ++. \} ++.\} ++.if n \{\ ++. if \\n(nl==0:\\n(nl==-1 'bp ++.\} ++.if t 'bp ++.em lM ++.. ++.\" Header Macro ++.\" ++.de hM ++.ev 1 ++.pL ++.if !\\n(cR 'sp \\n(Hmu ++.tl @\\*(Hs\\*(hT\fP@\\*(Vs\\*(vT\fP@\\*(Hs\\*(hT\fP@ ++'sp \\n(Hmu ++.ev ++.. ++.\" ++.de fM ++.ev 1 ++.pL ++.if !\\n(cR \{\ ++' sp \\n(Fmu ++. tl @\\*(Hs\\*(oS\fP@\\*(Vs\\*(dD\fP@%@ ++' bp ++.\} ++.if \\n(cR \{\ ++.\" . tl @\\*(Hs\\*(oS\fP@\\*(Vs\\*(dD\fP@%@ ++.\" ' bp ++.\} ++.ev ++.. ++.de lM ++.fl ++.if \\n(cR \{\ ++. fM ++. pl \\n(nlu ++.\} ++.. ++.de Pp ++.sp \\n(Ppu ++.ne 2 ++.ns ++.. ++.de Lp ++.Pp ++.. ++.de LP ++.tm Not a \-mdoc command: .LP ++.. ++.de PP ++.tm Not a \-mdoc command: .PP ++.. ++.de pp ++.tm Not a \-mdoc command: .pp ++.. ++.de Co ++.tm Not a \-mdoc command: .Co ++.. ++.nr z. 1 ++.nr z, 1 ++.nr z: 1 ++.nr z; 1 ++.nr z) 1 ++.nr z( 1 ++.nr z[ 1 ++.nr z] 1 ++.\" This is disgusting, troff not parse if stmt properly ++.nr z1 0 ++.nr z2 0 ++.nr z3 0 ++.nr z4 0 ++.nr z5 0 ++.nr z6 0 ++.nr z7 0 ++.nr z8 0 ++.nr z9 0 ++.nr z0 0 ++.nr z# 0 ++.\" ++.de Ad ++.ie \\n(.$==0 \{\ ++. tm Usage: .Ad address [...] \\*(Pu ++.\} ++.el \{\ ++. ds sV \\*(aD ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.\" Command Line Argument Macro ++.\" ++.de Ar ++.ie \\n(.$==0 \{\ ++. ie !"\\*(iM"" .as f1 \&[\|\\*(aRfile\ ...\fP\|] ++. el \&[\|\\*(aRfile\ ...\fP\|] ++.\} ++.el \{\ ++. ds sV \\*(aR ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.de Em ++.ie \\n(.$==0 \{\ ++. tm Usage: .Em text ... \\*(Pu ++.\} ++.el \{\ ++. ds sV \\*(eM ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.de Er ++.ie \\n(.$==0 \{\ ++. tm Usage: .Er ERRNOTYPE ... \\*(Pu ++. \} ++.el \{\ ++. ds sV \\*(eR ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.de Ev ++.ie \\n(.$==0 \{\ ++. tm Usage: .Ev ENVIRONMENT_VARIABLE(s) ... \\*(Pu ++. \} ++.el \{\ ++. ds sV \\*(eV ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.\" Flag Name Macro ++.\" ++.de Fl ++.ie \\n(.$==0 \{\ ++. ie !"\\*(iM"" .as f1 \&\\*(fL\-\fP ++. el \&\\*(fL\-\fP ++.\} ++.el \{\ ++. nr rZ 0 ++. sW \\$1 ++. if (\\n(sW==1&\\n(.$==1) .rZ \\$1 ++. ds sV \\*(fL ++. nr cF \\n(.f ++. ie \\n(rZ \{\ ++. ie "\\*(iM"" .ds f1 \&\\*(sV\-\f\\n(cF\\$1 ++. el \&\\*(sV\-\f\\n(cF\\$1 ++. \} ++. el \{\ ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. fB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++. \} ++.\} ++.. ++.\" Interactive Commands Macro ++.\" ++.de Ic ++.ie \\n(.$==0 \{\ ++. tm Usage: .Ic Interactive Commands(s) ... \\*(Pu ++.\} ++.el \{\ ++. ds sV \\*(iC ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.\" Interactive Command Modifiers (flags) ++.\" ++.de Cm ++.ie \\n(.$==0 \{\ ++. tm Usage: .Cm Interactive Command Modifier(s) ... \\*(Pu ++.\} ++.el \{\ ++. ds sV \\*(cM ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.de Li ++.ie \\n(.$==0 \{\ ++. tm Usage: .Li literal ... \\*(Pu ++. \} ++.el \{\ ++. ds sV \\*(lI ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" If in nroff or any other case where the default font ++.\" is constant width, and literal means zilch, single quote instead. ++.ie n \{\ ++.de Ql ++. ie \\n(.$==0 \{\ ++. tm Usage: .Ql literal ... \\*(Pu ++. \} ++. el \{\ ++. Sq \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. \} ++.. ++.\} ++.el \{\ ++.de Ql ++. ie \\n(.$==0 \{\ ++. tm Usage: .Ql literal ... \\*(Pu ++. \} ++. el \{\ ++. Li \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. \} ++.. ++.\} ++.\" ++.de Nm ++.ie \\n(.$==0 \{\ ++. if "\\*(n1"" .tm Usage: .Nm Name(s) ... \\*(Pu ++. ie !"\\*(iM"" .as f1 \&\\*(nM\\*(n1\\$1\fP ++. el \&\\*(nM\\*(n1\\$1\fP ++.\} ++.el \{\ ++. ds sV \\*(nM ++. nr cF \\n(.f ++. if \\n(nS \{\ ++. rs ++. in -\\n(iSu ++. ie \\n(nS>1 .br ++. el \{\ ++. sW \\$1 ++. nr iS ((\\n(sW+1)*\\n(fW)u ++. \} ++. in +\\n(iSu ++. ti -\\n(iSu ++. nr nS \\n(nS+1 ++. \} ++. if "\\*(n1"" .ds n1 \\$1 ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.de Pa ++.ie \\n(.$==0 \{\ ++\&\\*(pA~\fP ++.\} ++.el \{\ ++. ds sV \\*(pA ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.de Sy ++.ie \\n(.$==0 \{\ ++. tm Usage: .Sy Symbolic Text ... \\*(Pu ++. \} ++.el \{\ ++. ds sV \\*(sY ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.de Ms ++.ie \\n(.$==0 \{\ ++. tm Usage: .Ms Math Symbol ... \\*(Pu ++. \} ++.el \{\ ++. ds sV \\*(sY ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.de Va ++.ie \\n(.$==0 \{\ ++. tm Usage: .Va variable_name(s) ... \\*(Pu ++.\} ++.el \{\ ++. ds sV \\*(vA ++. nr cF \\n(.f ++. ie "\\*(iM"" .ds f1 \&\\*(sV ++. el .as f1 \&\\*(sV ++. nB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++.\} ++.. ++.\" ++.de nB ++.hy 0 ++.if \\n(.$==0 .tm Usage error: called with empty arguments (empty quotes)? ++.ie \\n(.$>1 \{\ ++. rZ \\$1 ++. ie \\n(rZ .as f1 \&\f\\n(cF\\$1\fP ++. el .as f1 \&\\$1 ++. rZ \\$2 ++. if !\\n(rZ \{\ ++. ie !"\\*(iM""\{\ ++.\" I surrender ++. if "\\*(iM"Tp" .as f1 \&\ \& ++. if "\\*(iM"Dp" .as f1 \&\ \& ++. if "\\*(iM"Op" .as f1 \&\ \& ++. if "\\*(iM"Cx" .as f1 \&\ \& ++. if "\\*(iM"Dq" .as f1 \& \& ++. if "\\*(iM"Sq" .as f1 \& \& ++. if "\\*(iM"Pq" .as f1 \& \& ++. if "\\*(iM"Aq" .as f1 \& \& ++. \} ++. el .as f1 \& \& ++. \} ++. nB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.\} ++.el \{\ ++. rZ \\$1 ++. ie \\n(rZ .as f1 \&\f\\n(cF\\$1 ++. el .as f1 \&\\$1\f\\n(cF ++. if "\\*(iM"" \{\&\\*(f1 ++. ds f1 ++. \} ++. hy ++.\} ++.. ++.de fB ++.hy 0 ++.if \\n(.$==0 .tm Usage error: called with empty arguments (empty quotes)? ++.ie \\n(.$>1 \{\ ++. rZ \\$1 ++. ie \\n(rZ .as f1 \&\f\\n(cF\\$1\fP ++. el \{\ ++. ie "\\$1"-" .as f1 \&\-\- ++. el .as f1 \&\-\\$1 ++. \} ++. rZ \\$2 ++. if !\\n(rZ \{\ ++. ie !"\\*(iM""\{\ ++.\" I surrender ++. if "\\*(iM"Tp" .as f1 \&\ \& ++. if "\\*(iM"Dp" .as f1 \&\ \& ++. if "\\*(iM"Op" .as f1 \&\ \& ++. if "\\*(iM"Cx" .as f1 \&\ \& ++. if "\\*(iM"Dq" .as f1 \& \& ++. if "\\*(iM"Sq" .as f1 \& \& ++. if "\\*(iM"Pq" .as f1 \& \& ++. if "\\*(iM"Aq" .as f1 \& \& ++. \} ++. el .as f1 \& \& ++. \} ++. fB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.\} ++.el \{\ ++. rZ \\$1 ++. ie \\n(rZ .as f1 \&\f\\n(cF\\$1 ++. el \{\ ++. ie "\\$1"-" .as f1 \&\-\-\f\\n(cF ++. el .as f1 \&\-\\$1\f\\n(cF ++. \} ++. if "\\*(iM"" \{\&\\*(f1 ++. ds f1 ++. \} ++. hy ++.\} ++.. ++.\" ++.\" Single quoted Items ++.\" eF, sB g[0-9] and f2 ++.de Sq ++.nr eF 0 ++.ie \\n(.$==0 \{\ ++. ie "\\*(iM"" \&\\*(sL\&\\*sR ++. el .as f1 \&\\*(sL\&\\*(sR ++.\} ++.el \{\ ++. ie "\\*(iM"" \{\ ++. ds f1 \&\\*(sL ++. ds iM Sq ++. \} ++. el .as f1 \&\\*(sL ++. sB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ie \\n(eF>0 .\\*(g1 \\*(g2 \\*(g3 \\*(g4 \\*(g5 \\*(g6 \\*(g7 \\*(g8 ++. el .as f1 \\*(g0 ++. as f1 \\*(sR ++. if !"\\*(f2"" .as f1 \\*(f2 ++. if "\\*(iM"Sq" \{\ ++\&\\*(f1 ++. ds f1 ++. ds iM ++. \} ++. ds f2 ++. rm g0 g1 g2 g3 g4 g5 g6 g7 g8 g9 ++. nr eF 0 ++.\} ++.. ++.\" ++.\" Double quoted Items ++.de Dq ++.nr Ef 0 ++.ie \\n(.$==0 \{\ ++. ie "\\*(iM"" \&\\*(Lq\&\\*(Rq ++. el .as f1 \&\\*(Lq\&\\*(Rq ++.\} ++.el \{\ ++. ie "\\*(iM"" \{\ ++. ds f1 \&\\*(Lq ++. ds iM Dq ++. \} ++. el .as f1 \&\\*(Lq ++. Sb \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ie \\n(Ef>0 .\\*(k1 \\*(k2 \\*(k3 \\*(k4 \\*(k5 \\*(k6 \\*(k7 \\*(k8 ++. el .as f1 \\*(k0 ++. as f1 \\*(Rq ++. if !"\\*(f4"" .as f1 \\*(f4 ++. if "\\*(iM"Dq" \{\ ++\&\\*(f1 ++. ds f1 ++. ds iM ++. \} ++. ds f4 ++. rm k0 k1 k2 k3 k4 k5 k6 k7 k8 k9 ++. nr Ef 0 ++.\} ++.. ++.\" ++.\" Parenthesis quoted Items ++.de Pq ++.nr pQ 0 ++.ie \\n(.$==0 \{\ ++. ie "\\*(iM"" \&(\&) ++. el .as f1 \&(\&) ++.\} ++.el \{\ ++. ie "\\*(iM"" \{\ ++. ds f1 \&( ++. ds iM Pq ++. \} ++. el .as f1 \&( ++. pB \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ie \\n(pQ>0 .\\*(y1 \\*(y2 \\*(y3 \\*(y4 \\*(y5 \\*(y6 \\*(y7 \\*(y8 ++. el .as f1 \\*(y0 ++. as f1 \&) ++. if !"\\*(f3"" .as f1 \\*(f3 ++. if "\\*(iM"Pq" \{\ ++\&\\*(f1 ++. ds f1 ++. ds iM ++. \} ++. ds f3 ++. rm y0 y1 y2 y3 y4 y5 y6 y7 y8 y9 ++. nr pQ 0 ++.\} ++.. ++.\" eF, sB g[0-9] and f2 ++.de sB ++.hy 0 ++.ie \\n(.$==0 .tm Sick Logic: macro sB ++.el \{\ ++. ie \\n(eF>=1 .nr eF \\n(eF+1 ++. el \{\ ++. mN \\$1 ++. if \\n(mN .nr eF \\n(eF+1 ++. \} ++. rZ \\$1 ++. ie \\n(rZ .as f2 \\$1 ++. el \{\ ++. ie \\n(eF<1 .as g\\n(eF \\$1 ++. el .as g\\n(eF \\$1 ++. \} ++. if \\n(.$>1 \{\ ++. rZ \\$2 ++. if \\n(rZ==0 \{\ ++. if \\n(eF<1 \{\ ++. as g\\n(eF \& \& ++. \} ++. \} ++. sB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. \} ++.\} ++.. ++.de Sb ++.hy 0 ++.ie \\n(.$==0 .tm Sick Logic: macro Sb ++.el \{\ ++. ie \\n(Ef>=1 .nr Ef \\n(Ef+1 ++. el \{\ ++. mN \\$1 ++. if \\n(mN .nr Ef \\n(Ef+1 ++. \} ++. rZ \\$1 ++. ie \\n(rZ .as f4 \\$1 ++. el \{\ ++. ie \\n(Ef<1 .as k\\n(Ef \\$1 ++. el .as k\\n(Ef \\$1 ++. \} ++. if \\n(.$>1 \{\ ++. rZ \\$2 ++. if \\n(rZ==0 \{\ ++. if \\n(Ef<1 \{\ ++. as k\\n(Ef \& \& ++. \} ++. \} ++. Sb \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. \} ++.\} ++.. ++.de pB ++.hy 0 ++.ie \\n(.$==0 .tm Sick Logic: macro pB ++.el \{\ ++. ie \\n(pQ>=1 .nr pQ \\n(pQ+1 ++. el \{\ ++. mN \\$1 ++. if \\n(mN .nr pQ \\n(pQ+1 ++. \} ++. rZ \\$1 ++. ie \\n(rZ .as f3 \\$1 ++. el \{\ ++. ie \\n(pQ<1 .as y\\n(pQ \\$1 ++. el .as y\\n(pQ \\$1 ++. \} ++. if \\n(.$>1 \{\ ++. rZ \\$2 ++. if \\n(rZ==0 \{\ ++. if \\n(pQ<1 \{\ ++. as y\\n(pQ \& \& ++. \} ++. \} ++. pB \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. \} ++.\} ++.. ++.de aQ ++.hy 0 ++.ie \\n(.$==0 .tm Bad Syntax: .Aq ++.el \{\ ++. ie \\n(aQ>=1 .nr aQ \\n(aQ+1 ++. el \{\ ++. mN \\$1 ++. if \\n(mN .nr aQ \\n(aQ+1 ++. \} ++. rZ \\$1 ++. ie \\n(rZ .as aZ \\$1 ++. el \{\ ++. ie \\n(aQ<1 .as a\\n(aQ \\$1 ++. el .as a\\n(aQ \\$1 ++. \} ++. if \\n(.$>1 \{\ ++. rZ \\$2 ++. if \\n(rZ==0 \{\ ++. if \\n(aQ<1 \{\ ++. as a\\n(aQ \& \& ++. \} ++. \} ++. aQ \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. \} ++.\} ++.. ++.\" Angle Bracket Quoted Items ++.de Aq ++.nr aQ 0 ++.ie \\n(.$==0 \{\ ++. ie "\\*(iM"" \&<\&> ++. el .as f1 \&<\&> ++.\} ++.el \{\ ++. ie "\\*(iM"" \{\ ++. ds f1 \&< ++. ds iM Aq ++. \} ++. el .as f1 \&< ++. aQ \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 ++. ie \\n(aQ>0 .\\*(a1 \\*(a2 \\*(a3 \\*(a4 \\*(a5 \\*(a6 \\*(a7 \\*(a8 ++. el .as f1 \\*(a0 ++. as f1 \&> ++. if !"\\*(aZ"" .as f1 \\*(aZ ++. if "\\*(iM"Aq" \{\ ++\&\\*(f1 ++. ds f1 ++. ds iM ++. \} ++. ds aZ ++. rm a0 a1 a2 a3 a4 a5 a6 a7 a8 ++. nr aQ 0 ++.\} ++.. ++.\" macro Name test, return macro register value if true ++.if \n(.g .ig ++.de mN ++.nr mN 0 ++.sW \\$1 ++.if \\n(sW==2 \{\ ++. if \\n(\\$1 .nr mN \\n(\\$1 ++.\} ++.. ++.if !\n(.g .ig ++.de mN ++.nr mN 0 ++.if \A'\\$1' \{\ ++. sW \\$1 ++. if \\n(sW==2 \{\ ++. if \\n(\\$1 .nr mN \\n(\\$1 ++. \} ++.\} ++.. ++.\" Punctuation test (using z registers), return 1 if true ++.if \n(.g .ig ++.de rZ ++.nr rZ 0 ++.sW \\$1 ++.if \\n(sW==1 \{\ ++. if \\n(z\\$1==1 \{\ ++. nr rZ 1 ++. \} ++.\} ++.. ++.if !\n(.g .ig ++.de rZ ++.nr rZ 0 ++.if \A'\\$1' \{\ ++. sW \\$1 ++. if \\n(sW==1 \{\ ++. if \\n(z\\$1==1 \{\ ++. nr rZ 1 ++. \} ++. \} ++.\} ++.. ++.\" ++.\" sW returns number of characters in a string ++.if t \{\ ++.nr fW \w'\fC,' ++.de sW ++.nr sW \w'\fC\\$1' ++.\} ++.if n \{\ ++.nr fW \w'0' ++.de sW ++.nr sW \w'\\$1' ++.\} ++.ie \\n(sW>=\\n(fW \{\ ++. ie \\n(sW%\\n(fW .nr sW (\\n(sW/\\n(fW)+1 ++. el .nr sW \\n(sW/\\n(fW ++.\} ++.el .nr sW 0 ++.. ++.\" Option Expression - ++.\" TODO - add line overflow check (right!) ++.nr eP 0 ++.ds e1 ++.nr oE 0 ++.nr hP 0 ++.ds hP ++.nr Ep 0 ++.de Op ++.hy 0 ++.if "\\*(iM"" \{\ ++. ds iM Op ++. ds f1 \& ++.\} ++.as f1 \&\\*(lB ++.\" .tm Op: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.dO \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.ie !"\\$1"Cx" .oE ++.el .nr oE \\n(oE+1 ++.. ++.\" ++.\" just for mike, with every bite of garlic in mind (oops, i mean burp). ++.\" dO: go dOwn an argument vector and test each argument to see if ++.\" a macro name or punctuation. stash in respective place along ++.\" with its arguments. ++.nr oO 0 ++.nr oP 0 ++.nr aO 0 ++.de dO ++.mN \\$1 ++.ie \\n(mN \{\ ++. if \\n(oP \{\ ++. if \\n(hP \{\ ++. nr oZ 1 ++. oZ ++. Oz ++. \} ++. if \\n(e1==1 \{\ ++.\\*(e1 \\*(e2 \\*(e3 \\*(e4 \\*(e5 \\*(e6 \\*(e7 \\*(e8 \\*(e9 ++. \} ++. uO ++. if !(\\n(oO:\\n(aO) .as f1 \& \& ++. \} ++. ie "\\$1"Op" \{\ ++. as f1 \&\\*(lB ++. nr aO \\n(aO+1 ++. \} ++. el \{\ ++. nr eP \\n(eP+1 ++. ds e\\n(eP \\$1 ++. nr e\\n(eP 1 ++. \} ++.\} ++.el \{\ ++.\" .tm dO: $1: \\$1: eP \\n(eP e[\\n(eP]: \\*(e\\n(ePEE ++. rZ \\$1 ++. ie \\n(rZ \{\ ++.\" .tm dO:rZ: $1: \\$1: eP \\n(eP e[\\n(eP]: \\*(e\\n(eP ++. nr hP \\n(hP+1 ++. ds h\\n(hP \\$1 ++. \} ++. el \{\ ++.\" .tm dO:word $1: \\$1: eP \\n(eP e[\\n(eP]: \\*(e\\n(ePEE ++. if \\n(eP==0:\\n(e\\n(eP==1 .nr eP \\n(eP+1 ++. if \\n(eZ .as e\\n(eP \& \& ++. as e\\n(eP " \&\\$1 ++.\" . ds e\\n(eP \&\\$1 ++. nr eZ \\n(eZ+1 ++. \} ++.\} ++.nr oP 1 ++.ie \\n(.$>1 \{\ ++. dO \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.\} ++.el \{\ ++. ie \\n(e1 \{\ ++.\\*(e1 \\*(e2 \\*(e3 \\*(e4 \\*(e5 \\*(e6 \\*(e7 \\*(e8 \\*(e9 ++. \} ++. el \{\ ++. as f1 \\*(e1 ++. \} ++.\} ++.. ++.\" handle old style arguments such as the arg -Idir ++.\" in adb, .Oo is a toggle. ++.de Oo ++.ie \\n(oO .nr oO 0 ++.el .nr oO 1 ++.. ++.\" stash punctuation ++.de oZ ++.if \\n(hP>=\\n(oZ \{\ ++. nr eP \\n(eP+1 ++. ds e\\n(eP \\*(h\\n(oZ ++. nr oZ \\n(oZ+1 ++. oZ ++.\} ++.. ++.\" clean up punctuation vector ++.de Oz ++.if \\n(hP>0 \{\ ++. rm h\\n(hP ++. nr hP \\n(hP-1 ++. Oz ++.\} ++.. ++.\" uO: go back up created vector cleaning it up along the way ++.de uO ++.if \\n(eP>0 \{\ ++. rm e\\n(eP ++. rr e\\n(eP ++. nr eP \\n(eP-1 ++. nr oP 0 ++. nr eZ 0 ++. uO ++.\} ++.. ++.\" option end ++.de oE ++.uO ++.ie \\n(hP \{\ ++. as f1 \\*(rB\\*(h1\\*(h2\\*(h3 ++. Oz ++. nr oZ 0 ++.\} ++.el \{\ ++. as f1 \\*(rB ++.\} ++.ie "\\*(iM"Op" \{\ ++. if \\n(aO .aO ++.if t \{\ ++. if (\\n(.lu-\\n(.ku-\\n(.ou-(2*\\n(fWu))<\w'\fC\\*(f1'u .br ++.\} ++.if n \{\ ++. nr aa \w'\\*(f1'u ++.\" . nr qq \\n(.lu-\\n(.ku-\\n(.ou ++.\" \&aa == \\n(aa, f1==\\*(f1, qq==\\n(qq ++. if (\\n(.lu-\\n(.ku-\\n(.ou-\\n(aau)<=(8*\\n(fWu) .br ++.\} ++\&\\*(f1 ++. ds iM ++. ds f1 ++. hy ++.\} ++.el .nr oE \\n(oE-1 ++.. ++.de aO ++.as f1 \\*(rB ++.nr aO \\n(aO-1 ++.if \\n(aO >0 .aO ++.. ++.\" ++.de Xr ++.if \\n(.$<=1 \{\ ++. ie \\n(.$==1 \{\ ++. if !"\\*(iM"" .as f1 \&\\*(xR\\$1\fP ++. if "\\*(iM"" \&\\*(xR\\$1\fP ++. \} ++. el .tm Xr Usage: .Xr manpage_name [section#] \\*(Pu ++.\} ++.if \\n(.$==2 \{\ ++. rZ \\$2 ++. ie "\\*(iM"" \{\ ++. ie \\n(rZ \&\\*(xR\\$1\fP\\$2 ++. el \&\\*(xR\\$1\fP(\\$2) ++. \} ++. el \{\ ++. ie \\n(rZ .as f1 \&\\*(xR\\$1\fP\\$2 ++. el .as f1 \&\\*(xR\\$1\fP(\\$2) ++. \} ++.\} ++.if \\n(.$>=3 \{\ ++. rZ \\$2 ++. ie \\n(rZ \{\ ++. ie !"\\*(iM"" .as f1 \&\\*(xR\\$1\fP\\$2\\$3\\$4\\$5\\$6\\$7\\$8 ++. el \&\\*(xR\\$1\fP\\$2\\$3\\$4\\$5\\$6\\$7\\$8 ++. \} ++. el \{\ ++. rZ \\$3 ++. ie \\n(rZ \{\ ++. if !"\\*(iM"" \{\ ++. as f1 \&\\*(xR\\$1\fP(\\$2)\\$3\\$4\\$5\\$6\\$7\\$8 ++. \} ++. if "\\*(iM"" \{\ ++\&\\*(xR\\$1\fP(\\$2)\\$3\\$4\\$5\\$6\\$7\\$8 ++. \} ++. \} ++. el \{\ ++. tm rZ = \\n(rZ the arg is \\$3 ++. tm Xr-XX Usage: .Xr manpage_name [section#] \\*(Pu ++. \} ++. \} ++.\} ++.. ++.\" ++.\" ++.de Ex ++.tm Ex defunct, Use .Dl: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.. ++.\" Display (one) Line of text. ++.de Dl ++.ie "\\*(iM"" \{\ ++' ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i ++. in \\n(.iu+\\n(Dsu ++. mN \\$1 ++. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. el \{\ ++. nr cF \\n(.f ++.\" Literal font is none specified ++\&\\*(lI\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. ft \\n(cF ++. \} ++. in \\n(.iu-\\n(Dsu ++.\} ++.el \{\ ++. mN \\$1 ++. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 ++. el \{\ ++. nr cF \\n(.f ++. ds f1 \&\\*(lI\\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 ++. as f1 \&\f\\n(cF ++. \} ++.\} ++.. ++.\" ++.\" ++.\" user set Tagged Paragraph Width (used in both Dp and Tp) ++.de Tw ++.ie \\n(.$==0 \{\ ++. nr aa 0 ++.\} ++.el \{\ ++. mN \\$1 ++. ie \\n(sW>2 \{\ ++. nr tW (\\n(sW+3)*\\n(fWu) ++. \} ++. el \{\ ++. ie \\n(mN .nr tW \\n(mN ++. el .nr tW \\$1 ++. \} ++. nr tF 1 ++.\} ++.. ++.\" ++.de Dw ++.Tw \\$1 ++.. ++.\" ++.de Di ++.ie \\n(.$==0 \{\ ++. nr tI \\n(Dsu ++.\} ++.el \{\ ++. sW \\$1 ++. if \\n(sW>=2 \{\ ++. nr tI \\$1u ++. \} ++. if \\n(sW<2 \{\ ++. if "\\$1"L" \{\ ++. nr tI 0 ++. \} ++. \} ++.\} ++.. ++.\" tagged paragraph ++.\" initialize baby stack variables ++.nr np 0 ++.nr p1 0 ++.ds s\n(np ++.\" ++.de Tp ++.ie "\\$1"" .pE p s np ++.el \{\ ++. ds iM Tp ++. mN \\$1 ++. ie \\n(tF \{\ ++. ds tC Tw ++. nr tC 1 ++. nr tF 0 ++. \} ++. el \{\ ++. if !"Tw"\\*(s\\n(np" \{\ ++. ie \\n(mN \{\ ++. ds tC \\$1 ++. nr tW \\n(mN ++. \} ++. el \{\ ++. ds tC Tx ++. nr tW \\n(Tx ++. \} ++. if !"\\*(tC"\\*(s\\n(np" .nr tC 1 ++. \} ++. \} ++. sp \\n(vVu ++. if !\\n(cR .ne 2 ++. if \\n(tC \{\ ++. nr np \\n(np+1 ++. nr p\\n(np \\n(tW ++. ds s\\n(np \\*(tC ++. nr tC 0 ++. ds tC ++. in \\n(.iu+\\n(p\\n(npu ++. \} ++. ie \\n(mN \{\ ++. ds f1 ++. \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. if !"\\$1"Cx" .pT st p np ++. \} ++. el \{\ ++. br ++. ev 1 ++. fi ++. di Td ++\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. br ++. di ++. ev ++. na ++. ds tD \\*(Td\\ ++. pT di p np ++. \} ++.\} ++.. ++.\" ++.\" ++.\" Complex Expression Macro ++.\" ++.\" TODO: add length across line boundary check (like Li) ++.de Cx ++.hy 0 ++.ie \\n(.$==0 \{\ ++. if "\\*(iM"Cx" \{\ ++. ds iM ++. if \\n(oE .oE ++\&\\*(f1 ++. ds f1 ++. \} ++. if "\\*(iM"Tp" .pT st p np ++. if "\\*(iM"Dp" .pT st q mp ++.\} ++.el \{\ ++. if "\\*(iM"" \{\ ++. ds iM Cx ++. ds f1 \& ++. \} ++. mN \\$1 ++.\" Here are the args: `\\$1' `\\$2' `\\$3' `\\$4' ++. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. el \{\ ++. as f1 \&\\$1 ++. if \\n(.$>1 .Cx \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. \} ++.\} ++.. ++.\" Prefix string in default font to content specified string ++.de Pf ++.Cx \\$1 ++.\\$2 \\$3 \\$4 \\$5 ++.Cx ++.. ++.\" Suffix string in default font to content specified string ++.de Sf ++.Cx \\$1 \\$2 ++.Cx \\$3 ++.Cx ++.. ++.\" Simple Option Begin ++.de Ob ++.hy 0 ++.ie "\\*(iM"" \{\ ++. ev 2 ++. fi ++. di oB ++.\} ++.el \{\ ++.tm shouldn't be here ++. as f1 \&[ ++. mN \\$1 ++. ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. el \{\ ++. as f1 \&\\$1 ++. if \\n(.$>1 .Oc \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. \} ++.\} ++.. ++.de Oc ++.as f1 \&\\$1 ++.if \\n(.$>1 .Oc \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.. ++.de Oe ++.hy 0 ++.ie "\\*(iM"" \{\ ++. br ++. di ++. ev ++. ds bO \\*(oB\\ ++\&[\\*(bO\&] ++.\} ++.el \{\ ++. as f1 \&] ++.\} ++.. ++.\" White space for Cx ++.de Ws ++.Cx \&\ \& ++.. ++.\" tagged paragraph ++.\" initialize baby stack variables ++.nr mp 0 ++.nr q1 0 ++.ds r\n(np ++.\" ++.\" Complex Dp tag ++.de Dc ++.Dp Cx \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 ++.. ++.\" Complex Tp tag ++.de Tc ++.Tp Cx \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 ++.. ++.\" Tag with a flag and an argument with a space ++.de Ta ++.if "\\$2"" \{\ ++. Tp Fl \\$1 ++.\} ++.el \{\ ++. Tp Fl \\$1 ++. Cx \&\ \& ++. Ar \\$2 \\$3 ++. Cx ++.\} ++.. ++.de Da ++.Dp Cx Fl \\$1 ++.Ws ++.Ar \\$2 \\$3 ++.Cx ++.. ++.de To ++.Tp Cx Fl \\$1 ++.Ar \\$2 \\$3 ++.Cx ++.. ++.de Do ++.Dp Cx Fl \\$1 ++.Ar \\$2 \\$3 ++.Cx ++.. ++.\" Blended tag toggle ++.de Bt ++.ie \\n(tP==0 .nr tP 1 ++.el .nr tP 0 ++.. ++.\" Bullet paragraph ++.de Bu ++.Tp Sy \&\(bu ++.. ++.\" Display tagged paragraph ++.de Dp ++.ie "\\$1"" \{\ ++. pE q r mp ++. sp \\n(vVu ++.\} ++.el \{\ ++. ds iM Dp ++. mN \\$1 ++. ie \\n(tF \{\ ++. ds tC Tw ++. nr tC 1 ++. nr tF 0 ++. \} ++. el \{\ ++. if !"Tw"\\*(r\\n(mp" \{\ ++. ie \\n(mN \{\ ++. ds tC \\$1 ++. nr tW \\n(mN ++. \} ++. el \{\ ++. ds tC Tx ++. nr tW \\n(Tx ++. \} ++. if !"\\*(tC"\\*(r\\n(mp" .nr tC 1 ++. \} ++. \} ++. if !\\n(cR .ne 2 ++. if \\n(tC \{\ ++. nr mp \\n(mp+1 ++. nr q\\n(mp \\n(tW ++. ds r\\n(mp \\*(tC ++. nr tC 0 ++. ds tC ++. ie \\n(tIu==\\n(Dsu .nr i\\n(mp \\n(Dsu ++. el \{\ ++. nr i\\n(mp \\n(tIu ++. nr tI \\n(Dsu ++. \} ++. in \\n(.iu+\\n(i\\n(mpu ++. sp \\n(vVu ++. in \\n(.iu+\\n(\\q\\n(mpu ++. \} ++. ie \\n(mN \{\ ++. \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. if !"\\$1"Cx" .pT st q mp ++. \} ++. el \{\ ++. br ++. ev 1 ++. fi ++. di Td ++\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. br ++. di ++. ev ++. na ++. ds tD \\*(Td\\ ++. pT di q mp ++. \} ++.\} ++.. ++.\" ++.\" .pE number_stack string_stack counter ++.de pE ++.ie "\\$3"mp" \{\ ++. in \\n(.iu-(\\n(\\$1\\n(\\$3u)-(\\n(i\\n(mpu) ++. rr i\\n(mp ++.\} ++.el .in \\n(.iu-\\n(\\$1\\n(\\$3u ++.\" .in \\n(.iu-\\n(\\$1\\n(\\$3u ++.if \\n(\\$3<=0 .tm Extraneous call .Tp or .Dp ++.rr \\$1\\n(\\$3 ++.rm \\$2\\n(\\$3 ++.nr \\$3 \\n(\\$3-1 ++.ds iM ++.. ++.\" ++.\" .pT [st or di] number_stack counter ++.de pT ++.ie "\\$1"st" \{\ ++. nr bb \\n(\\$2\\n(\\$3u ++. ti -\\n(bbu ++. ie (\\n(\\$2\\n(\\$3u-2n)<=\w'\\*(f1'u \{\&\\*(f1\\*(tP ++. if \\n(tP==0 .br ++. \} ++. el \\*(f1\h'|\\n(\\$2\\n(\\$3u'\c ++.\} ++.el \{\ ++. ti -\\n(\\$2\\n(\\$3u ++. ie (\\n(\\$2\\n(\\$3u-2n)<=\\n(dlu \{\&\\*(tD\\*(tP ++. if !\\n(tP .br ++. \} ++. el \\*(tD\h'|\\n(\\$2\\n(\\$3u'\c ++. if t 'ad ++.\} ++. ds iM ++. ds f1 ++'fi ++.. ++.\" ++.\" The new SH ++.\" ++.de Sh ++.\" set Sh state off, check for list state before calling indent (.In) ++.nr nS 0 ++.nr sE 0 ++.ie "\\$1"NAME" \{\ ++.\" name state on, housekeep (headers & footers) ++. hK ++' in 0 ++.\} ++.el \{\ ++. if "\\$1"SYNOPSIS" .nr nS 1 ++. in 0 ++.\} ++.pL ++'sp ++.ns ++.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i ++.if !\\n(cR .ne 3 ++'fi ++\&\fB\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 \|\\$7 \|\\$8 \|\\$9 ++\&\fP\& ++.in \\n(.iu+\\n(Tiu ++.if "\\$1"SEE" .nr sE 1 ++.ns ++.. ++.\" ++.\" Nd minus sign for an en dash used in .Sh Name ++.de Nd ++\&\-\& \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.. ++.de Ss ++.sp ++.ti -.25i ++\&\fB\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 \|\\$7 \|\\$8 \|\\$9 ++\&\fP\& ++.ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i ++.if !\\n(cR .ne 2 ++.br ++.. ++.\" .if "\\$1"Ss" .in \\n(.iu+\\n(sIu ++.\".. ++.\" ++.\" ++.\" Column Macro ++.\" ++.hy 0 ++.de Cw ++.ie \\n(.$==0 \{\ ++. br ++. in \\n(.iu-\\n(eWu ++. ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i ++.\} ++.el \{\ ++. Pp ++. if \\n(.$==1 \{\ ++. ta \w'\\$1 'u ++. nr eW \w'\\$1 'u ++' in \\n(.iu+\\n(eWu ++. \} ++. if \\n(.$==2 \{\ ++. ta \w'\\$1 'u +\w'\\$2 'u ++. nr eW \w'\\$1 'u+\w'\\$2 'u ++' in \\n(.iu+\\n(eWu ++. \} ++. if \\n(.$==3 \{\ ++. ta \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u ++. nr eW \w'\\$1 'u+\w'\\$2 'u+\w'\\$3 'u ++' in \\n(.iu+\\n(eWu ++. \} ++. if \\n(.$==4 \{\ ++. ta \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +\w'\\$4 'u ++. nr eW \w'\\$1 'u+\w'\\$2 'u+\w'\\$3 'u +\w'\\$4 'u ++' in \\n(.iu+\\n(eWu ++. \} ++. if \\n(.$==5 \{\ ++.ta \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +\w'\\$4 'u +\w'\\$5 'u ++.nr eW \w'\\$1 'u +\w'\\$2 'u +\w'\\$3 'u +\w'\\$4 'u +\w'\\$5 'u ++' in \\n(.iu+\\n(eWu ++. \} ++.\} ++.. ++.de Cl ++.ti -\\n(eWu ++.mN \\$1 ++.ie \\n(mN .\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.el \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.. ++.nr dQ 0 ++.de Ds ++.ie !"\\$1"" \{\ ++. mN d\\$1 ++. if \\n(mN \{\ ++. nr dQ \\n(dQ+1 ++. d\\$1 ++. \} ++.\} ++.el .br ++.nf ++.. ++.de Df ++.ie !"\\$1"" \{\ ++. mN d\\$1 ++. if \\n(mN \{\ ++. nr dQ \\n(dQ+1 ++. d\\$1 ++. \} ++.\} ++.el .br ++.. ++.de Dn ++\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++.nf ++.. ++.de dI ++.nr d\\n(dQ \\n(dIu ++.in \\n(.iu+\\n(dIu ++.. ++.de dC ++.nr d\\n(dQ (\\n(.l-\\n(.i)/4u ++.in \\n(.iu+\\n(d\\n(dQu ++.. ++.de dR ++.nr d\\n(dQ (\\n(.l/3)u ++.in \\n(.iu+\\n(d\\n(dQu ++.. ++.de dL ++.nr aa 0 ++.. ++.de De ++.br ++.if \\n(d\\n(dQ \{\ ++. in \\n(.iu-\\n(d\\n(dQu ++. rr d\\n(dQ ++. nr dQ \\n(dQ-1 ++.\} ++.fi ++.. ++.\" ++.de Fn ++.ie \\n(.$==0 \{\ ++. tm Usage: .Fn function_name function_arg(s) ... \\*(Pu ++.\} ++.el \{\ ++. nr cF \\n(.f ++. ie \\n(.$==1 .ds f1 \&\\*(nM\\$1\fP\\*(lP\fP\\*(rP\fP ++. el \{\ ++. ds f1 \\*(nM\\$1\fP\\*(lP ++. nr aa 0 ++. rC \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 ++. \} ++. if "\\*(iM"" \{\\&\\*(f1 ++. ds f1 ++. \} ++.\} ++.. ++.\" ++.de rC ++.rZ \\$1 ++.ie \\n(rZ \{\ ++. as f1 \f\\n(cF\\*(rP\f\\n(cF\\$1\\$2\\$3\\$4\\$5\\$6\\$7 ++.\} ++.el \{\ ++. ie \\n(aa .as f1 \fP, \\*(aR\\$1 ++. el .as f1 \\*(aR\\$1 ++. nr aa 1 ++. ie \\n(.$>1 .rC \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 ++. el .as f1 \fP\\*(rP\fP ++.\} ++.. +diff -Nuar groff-1.22.3.old/tmac/doc-syms groff-1.22.3/tmac/doc-syms +--- groff-1.22.3.old/tmac/doc-syms 2014-11-04 10:38:35.533520146 +0200 ++++ groff-1.22.3/tmac/doc-syms 1970-01-01 02:00:00.000000000 +0200 +@@ -1,880 +0,0 @@ +-.\" -*- nroff -*- +-.\" +-.\" Copyright (c) 1991, 1993 +-.\" The Regents of the University of California. All rights reserved. +-.\" +-.\" Redistribution and use in source and binary forms, with or without +-.\" modification, are permitted provided that the following conditions +-.\" are met: +-.\" 1. Redistributions of source code must retain the above copyright +-.\" notice, this list of conditions and the following disclaimer. +-.\" 2. Redistributions in binary form must reproduce the above copyright +-.\" notice, this list of conditions and the following disclaimer in the +-.\" documentation and/or other materials provided with the distribution. +-.\" 3. [Deleted. See +-.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +-.\" 4. Neither the name of the University nor the names of its contributors +-.\" may be used to endorse or promote products derived from this software +-.\" without specific prior written permission. +-.\" +-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-.\" SUCH DAMAGE. +-.\" +-.\" @(#)doc-syms 8.1 (Berkeley) 06/08/93 +-.\" +-.\" %beginstrip% +-. +-. +-.eo +-. +-.\" NS Ux user macro +-.\" NS print UNIX +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-str-Ux +-.\" NS +-.\" NS width register `Ux' defined in doc-common +-. +-.de Ux +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-Ux \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. if !\n[doc-arg-limit] \ +-. if \n[.$] \{\ +-. ds doc-macro-name Ux +-. doc-parse-args \$@ +-. \} +-. +-. \" replace current argument with result +-. ds doc-arg\n[doc-arg-ptr] \*[doc-Tn-font-size]UNIX\*[doc-str-Ux] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. if \n[doc-num-args] \ +-. doc-parse-space-vector +-. +-. doc-print-recursive +-.. +-. +-. +-.\" NS Bx user macro +-.\" NS print BSD (fix smaller nroff version) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-str-Bx +-.\" NS doc-str-Bx1 +-.\" NS doc-str-Bx-XXX +-.\" NS +-.\" NS width register `Bx' defined in doc-common +-. +-.ds doc-str-Bx-Reno \-Reno +-.ds doc-str-Bx-reno \-Reno +-.ds doc-str-Bx-Tahoe \-Tahoe +-.ds doc-str-Bx-tahoe \-Tahoe +-.ds doc-str-Bx-Lite \-Lite +-.ds doc-str-Bx-lite \-Lite +-.ds doc-str-Bx-Lite2 \-Lite2 +-.ds doc-str-Bx-lite2 \-Lite2 +-. +-.de Bx +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-Bx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. \" default value if no argument +-. ds doc-str-Bx1 \*[doc-Tn-font-size]BSD\*[doc-str-Bx] +-. +-. if !\n[doc-arg-limit] \ +-. if \n[.$] \{\ +-. ds doc-macro-name Bx +-. doc-parse-args \$@ +-. \} +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. ie "\*[doc-arg\n[doc-arg-ptr]]"-alpha" \ +-. as doc-str-Bx1 " (currently in alpha test) +-. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-beta" \ +-. as doc-str-Bx1 " (currently in beta test) +-. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-devel" \ +-. as doc-str-Bx1 " (currently under development) +-. el \{\ +-. ds doc-str-Bx1 \&\*[doc-arg\n[doc-arg-ptr]]\^\*[doc-Tn-font-size] +-. as doc-str-Bx1 BSD\*[doc-str-Bx] +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. ie d doc-str-Bx-\*[doc-arg\n[doc-arg-ptr]] \ +-. as doc-str-Bx1 "\*[doc-str-Bx-\*[doc-arg\n[doc-arg-ptr]]] +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. el \ +-. nr doc-arg-ptr -1 +-. \}\}\}\}\} +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. +-. \" replace current argument with result +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Bx1] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. if \n[doc-num-args] \ +-. doc-parse-space-vector +-. +-. doc-print-recursive +-.. +-. +-. +-.\" NS Ud user macro (not parsed, not callable) +-.\" NS print "currently under development" (HISTORY section) +-.\" NS +-.\" NS width register `Ud' defined in doc-common +-. +-.de Ud +-. nop \¤tly under development. +-.. +-. +-. +-.\" NS At user macro +-.\" NS print AT&T UNIX +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-str-At +-.\" NS doc-str-At1 +-.\" NS doc-str-At-XXX +-.\" NS +-.\" NS width register `At' defined in doc-common +-. +-.ds doc-str-At-32v \&Version\~32V +-.as doc-str-At-32v " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] +-.ds doc-str-At-v1 \&Version\~1 +-.as doc-str-At-v1 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] +-.ds doc-str-At-v2 \&Version\~2 +-.as doc-str-At-v2 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] +-.ds doc-str-At-v3 \&Version\~3 +-.as doc-str-At-v3 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] +-.ds doc-str-At-v4 \&Version\~4 +-.as doc-str-At-v4 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] +-.ds doc-str-At-v5 \&Version\~5 +-.as doc-str-At-v5 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] +-.ds doc-str-At-v6 \&Version\~6 +-.as doc-str-At-v6 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] +-.ds doc-str-At-v7 \&Version\~7 +-.as doc-str-At-v7 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] +-.ds doc-str-At-III \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~III +-.as doc-str-At-III " \*[doc-Tn-font-size]UNIX\*[doc-str-At] +-.ds doc-str-At-V \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V +-.as doc-str-At-V " \*[doc-Tn-font-size]UNIX\*[doc-str-At] +-.ds doc-str-At-V.1 \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V Release\~1 +-.as doc-str-At-V.1 " \*[doc-Tn-font-size]UNIX\*[doc-str-At] +-.ds doc-str-At-V.2 \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V Release\~2 +-.as doc-str-At-V.2 " \*[doc-Tn-font-size]UNIX\*[doc-str-At] +-.ds doc-str-At-V.3 \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V Release\~3 +-.as doc-str-At-V.3 " \*[doc-Tn-font-size]UNIX\*[doc-str-At] +-.ds doc-str-At-V.4 \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V Release\~4 +-.as doc-str-At-V.4 " \*[doc-Tn-font-size]UNIX\*[doc-str-At] +-. +-.de At +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-At \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. \" default value if no argument +-. ds doc-str-At1 \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] +-. +-. if !\n[doc-arg-limit] \ +-. if \n[.$] \{\ +-. ds doc-macro-name At +-. doc-parse-args \$@ +-. \} +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ +-. ie d doc-str-At-\*[doc-arg\n[doc-arg-ptr]] \ +-. ds doc-str-At1 "\*[doc-str-At-\*[doc-arg\n[doc-arg-ptr]]] +-. el \{\ +-. tmc mdoc warning: .At: Unknown AT&T UNIX version +-. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +-. nr doc-arg-ptr -1 +-. \}\} +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. +-. \" replace current argument with result +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-At1] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. if \n[doc-num-args] \ +-. doc-parse-space-vector +-. +-. doc-print-recursive +-.. +-. +-. +-.\" NS Dx user macro +-.\" NS print DragonFly +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-str-Dx +-.\" NS doc-str-Dx1 +-.\" NS +-.\" NS width register `Dx' defined in doc-common +-. +-.\" we use the doc-operating-system-DragonFly-* strings defined in doc-common +-. +-.de Dx +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-Dx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. \" default value if no argument +-. ds doc-str-Dx1 \*[doc-Tn-font-size]\%DragonFly\*[doc-str-Dx] +-. +-. if !\n[doc-arg-limit] \ +-. if \n[.$] \{\ +-. ds doc-macro-name Dx +-. doc-parse-args \$@ +-. \} +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ +-. ie d doc-operating-system-DragonFly-\*[doc-arg\n[doc-arg-ptr]] \ +-. as doc-str-Dx1 \~\*[doc-operating-system-DragonFly-\*[doc-arg\n[doc-arg-ptr]]] +-. el \{\ +-. tmc mdoc warning: .Dx: Unknown DragonFly version +-. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +-. as doc-str-Dx1 \~\*[doc-arg\n[doc-arg-ptr]] +-. \}\} +-. el \ +-. as doc-str-Dx1 \~\*[doc-arg\n[doc-arg-ptr]] +-. \} +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. +-. \" replace current argument with result +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Dx1] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. if \n[doc-num-args] \ +-. doc-parse-space-vector +-. +-. doc-print-recursive +-.. +-. +-. +-.\" NS Fx user macro +-.\" NS print FreeBSD +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-str-Fx +-.\" NS doc-str-Fx1 +-.\" NS +-.\" NS width register `Fx' defined in doc-common +-. +-.\" we use the doc-operating-system-FreeBSD-* strings defined in doc-common +-. +-.de Fx +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-Fx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. \" default value if no argument +-. ds doc-str-Fx1 \*[doc-Tn-font-size]\%FreeBSD\*[doc-str-Fx] +-. +-. if !\n[doc-arg-limit] \ +-. if \n[.$] \{\ +-. ds doc-macro-name Fx +-. doc-parse-args \$@ +-. \} +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ +-. ie d doc-operating-system-FreeBSD-\*[doc-arg\n[doc-arg-ptr]] \ +-. as doc-str-Fx1 \~\*[doc-operating-system-FreeBSD-\*[doc-arg\n[doc-arg-ptr]]] +-. el \{\ +-. tmc mdoc warning: .Fx: Unknown FreeBSD version +-. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +-. as doc-str-Fx1 \~\*[doc-arg\n[doc-arg-ptr]] +-. \}\} +-. el \ +-. as doc-str-Fx1 \~\*[doc-arg\n[doc-arg-ptr]] +-. \} +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. +-. \" replace current argument with result +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Fx1] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. if \n[doc-num-args] \ +-. doc-parse-space-vector +-. +-. doc-print-recursive +-.. +-. +-. +-.\" NS Nx user macro +-.\" NS print NetBSD +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-str-Nx +-.\" NS doc-str-Nx1 +-.\" NS +-.\" NS width register `Nx' defined in doc-common +-. +-.\" we use the doc-operating-system-NetBSD-* strings defined in doc-common +-. +-.de Nx +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-Nx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. \" default value if no argument +-. ds doc-str-Nx1 \*[doc-Tn-font-size]\%N\s[\n[doc-curr-size]u]et +-. as doc-str-Nx1 \*[doc-Tn-font-size]BSD\*[doc-str-Nx] +-. +-. if !\n[doc-arg-limit] \ +-. if \n[.$] \{\ +-. ds doc-macro-name Nx +-. doc-parse-args \$@ +-. \} +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ +-. ie d doc-operating-system-NetBSD-\*[doc-arg\n[doc-arg-ptr]] \ +-. as doc-str-Nx1 \~\*[doc-operating-system-NetBSD-\*[doc-arg\n[doc-arg-ptr]]] +-. el \{\ +-. tmc mdoc warning: .Nx: Unknown NetBSD version +-. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +-. as doc-str-Nx1 \~\*[doc-arg\n[doc-arg-ptr]] +-. \}\} +-. el \ +-. as doc-str-Nx1 \~\*[doc-arg\n[doc-arg-ptr]] +-. \} +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. +-. \" replace current argument with result +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Nx1] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. if \n[doc-num-args] \ +-. doc-parse-space-vector +-. +-. doc-print-recursive +-.. +-. +-. +-.\" NS Ox user macro +-.\" NS print OpenBSD +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-str-Ox +-.\" NS doc-str-Ox1 +-.\" NS +-.\" NS width register `Ox' defined in doc-common +-. +-.de Ox +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-Ox \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. \" default value if no argument +-. ds doc-str-Ox1 \*[doc-Tn-font-size]\%OpenBSD\*[doc-str-Ox] +-. +-. if !\n[doc-arg-limit] \ +-. if \n[.$] \{\ +-. ds doc-macro-name Ox +-. doc-parse-args \$@ +-. \} +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \ +-. as doc-str-Ox1 \~\*[doc-arg\n[doc-arg-ptr]] +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. +-. \" replace current argument with result +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Ox1] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. if \n[doc-num-args] \ +-. doc-parse-space-vector +-. +-. doc-print-recursive +-.. +-. +-. +-.\" NS Bsx user macro +-.\" NS print BSD/OS +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-str-Bsx +-.\" NS doc-str-Bsx1 +-.\" NS +-.\" NS width register `Bsx' defined in doc-common +-. +-.de Bsx +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-Bsx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. \" default value if no argument +-. ds doc-str-Bsx1 \*[doc-Tn-font-size]BSD/OS\*[doc-str-Bsx] +-. +-. if !\n[doc-arg-limit] \ +-. if \n[.$] \{\ +-. ds doc-macro-name Bsx +-. doc-parse-args \$@ +-. \} +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \ +-. as doc-str-Bsx1 \~\*[doc-arg\n[doc-arg-ptr]] +-. el \ +-. nr doc-arg-ptr -1 +-. \} +-. +-. \" replace current argument with result +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Bsx1] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. if \n[doc-num-args] \ +-. doc-parse-space-vector +-. +-. doc-print-recursive +-.. +-. +-. +-.\" The Bt macro should go away now +-. +-.\" NS Bt user macro (not parsed, not callable) +-.\" NS print "is currently in beta test." (HISTORY section) +-.\" NS +-.\" NS width register `Bt' defined in doc-common +-. +-.de Bt +-. nop \&is currently in beta test. +-.. +-. +-. +-.\" NS Px user macro +-.\" NS print POSIX +-. +-.ds Px \*[doc-Tn-font-size]\%POSIX +-. +-. +-.\" NS Ai user macro +-.\" NS print ANSI +-. +-.ds Ai \*[doc-Tn-font-size]\%ANSI +-. +-. +-.\" NS St user macro +-.\" NS standards (posix, ansi - formal standard names) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-reg-St +-.\" NS doc-str-St +-.\" NS doc-str-St1 +-.\" NS doc-str-St-XXX +-.\" NS +-.\" NS width register `St' defined in doc-common +-. +-.\" ANSI/ISO C +-.ds doc-str-St--ansiC-89 \*[Ai] \*[doc-str-St]X\^3.159-1989 +-.as doc-str-St--ansiC-89 " (\*[Lq]\)\*[Ai]\~C89\*[doc-str-St]\*[Rq]) +-.als doc-str-St--ansiC doc-str-St--ansiC-89 +-.ds doc-str-St--isoC \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899:1990 +-.as doc-str-St--isoC " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^90\*[doc-str-St]\*[Rq]) +-.als doc-str-St--isoC-90 doc-str-St--isoC +-.ds doc-str-St--isoC-2011 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899:2011 +-.as doc-str-St--isoC-2011 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^11\*[doc-str-St]\*[Rq]) +-.ds doc-str-St--isoC-99 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899:1999 +-.as doc-str-St--isoC-99 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^99\*[doc-str-St]\*[Rq]) +-.ds doc-str-St--isoC-amd1 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899/AMD1:1995 +-.as doc-str-St--isoC-amd1 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^90\*[doc-str-St], Amendment 1\*[Rq]) +-.ds doc-str-St--isoC-tcor1 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899/TCOR1:1994 +-.as doc-str-St--isoC-tcor1 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^90\*[doc-str-St], Technical Corrigendum 1\*[Rq]) +-.ds doc-str-St--isoC-tcor2 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899/TCOR2:1995 +-.as doc-str-St--isoC-tcor2 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^90\*[doc-str-St], Technical Corrigendum 2\*[Rq]) +-. +-.\" POSIX Part 1: System API +-.ds doc-str-St--p1003.1 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1 +-.as doc-str-St--p1003.1 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.ds doc-str-St--p1003.1b \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1b +-.as doc-str-St--p1003.1b " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.ds doc-str-St--p1003.1-88 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1-1988 +-.as doc-str-St--p1003.1-88 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.ds doc-str-St--p1003.1-90 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9945-1:1990 +-.as doc-str-St--p1003.1-90 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.als doc-str-St--iso9945-1-90 doc-str-St--p1003.1-90 +-.ds doc-str-St--p1003.1b-93 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1b-1993 +-.as doc-str-St--p1003.1b-93 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.ds doc-str-St--p1003.1c-95 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1c-1995 +-.as doc-str-St--p1003.1c-95 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.ds doc-str-St--p1003.1i-95 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1i-1995 +-.as doc-str-St--p1003.1i-95 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.ds doc-str-St--p1003.1-96 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9945-1:1996 +-.as doc-str-St--p1003.1-96 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.als doc-str-St--iso9945-1-96 doc-str-St--p1003.1-96 +-.ds doc-str-St--p1003.1g-2000 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1g-2000 +-.as doc-str-St--p1003.1g-2000 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.ds doc-str-St--p1003.1-2001 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1-2001 +-.as doc-str-St--p1003.1-2001 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.ds doc-str-St--p1003.1-2004 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1-2004 +-.as doc-str-St--p1003.1-2004 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-.ds doc-str-St--p1003.1-2008 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1-2008 +-.as doc-str-St--p1003.1-2008 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) +-. +-.\" POSIX Part 2: Shell and Utilities +-.ds doc-str-St--p1003.2 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.2 +-.as doc-str-St--p1003.2 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) +-.ds doc-str-St--p1003.2-92 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.2-1992 +-.as doc-str-St--p1003.2-92 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) +-.ds doc-str-St--p1003.2a-92 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.2a-1992 +-.as doc-str-St--p1003.2a-92 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) +-.ds doc-str-St--iso9945-2-93 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9945-2:1993 +-.as doc-str-St--iso9945-2-93 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) +-. +-.\" X/Open +-.ds doc-str-St--susv2 Version\~2 of the Single \*[doc-Tn-font-size]UNIX\*[doc-str-St] Specification +-.as doc-str-St--susv2 " (\*[Lq]\*[doc-Tn-font-size]SUSv2\*[doc-str-St]\*[Rq]) +-.ds doc-str-St--susv3 Version\~3 of the Single \*[doc-Tn-font-size]UNIX\*[doc-str-St] Specification +-.as doc-str-St--susv3 " (\*[Lq]\*[doc-Tn-font-size]SUSv3\*[doc-str-St]\*[Rq]) +-.ds doc-str-St--svid4 System\~V Interface Definition, Fourth Edition +-.as doc-str-St--svid4 " (\*[Lq]\*[doc-Tn-font-size]SVID\*[doc-str-St]\^4\*[Rq]) +-.ds doc-str-St--xbd5 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Base Definitions Issue\~5 +-.as doc-str-St--xbd5 " (\*[Lq]\*[doc-Tn-font-size]XBD\*[doc-str-St]\^5\*[Rq]) +-.ds doc-str-St--xcu5 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Commands and Utilities Issue\~5 +-.as doc-str-St--xcu5 " (\*[Lq]\*[doc-Tn-font-size]XCU\*[doc-str-St]\^5\*[Rq]) +-.ds doc-str-St--xcurses4.2 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Curses Issue\~4, Version\~2 +-.as doc-str-St--xcurses4.2 " (\*[Lq]\*[doc-Tn-font-size]XCURSES\*[doc-str-St]\^4.2\*[Rq]) +-.ds doc-str-St--xns5 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Networking Services Issue\~5 +-.as doc-str-St--xns5 " (\*[Lq]\*[doc-Tn-font-size]XNS\*[doc-str-St]\^5\*[Rq]) +-.ds doc-str-St--xns5.2 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Networking Services Issue\~5.2 +-.as doc-str-St--xns5.2 " (\*[Lq]\*[doc-Tn-font-size]XNS\*[doc-str-St]\^5.2\*[Rq]) +-.ds doc-str-St--xpg3 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Portability Guide Issue\~3 +-.as doc-str-St--xpg3 " (\*[Lq]\*[doc-Tn-font-size]XPG\*[doc-str-St]\^3\*[Rq]) +-.ds doc-str-St--xpg4 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Portability Guide Issue\~4 +-.as doc-str-St--xpg4 " (\*[Lq]\*[doc-Tn-font-size]XPG\*[doc-str-St]\^4\*[Rq]) +-.ds doc-str-St--xpg4.2 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Portability Guide Issue\~4, Version\~2 +-.as doc-str-St--xpg4.2 " (\*[Lq]\*[doc-Tn-font-size]XPG\*[doc-str-St]\^4.2\*[Rq]) +-.ds doc-str-St--xsh5 \*[doc-Tn-font-size]X/Open\*[doc-str-St] System Interfaces and Headers Issue\~5 +-.as doc-str-St--xsh5 " (\*[Lq]\*[doc-Tn-font-size]XSH\*[doc-str-St]\^5\*[Rq]) +-. +-.\" Miscellaneous +-.ds doc-str-St--ieee754 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 754-1985 +-.ds doc-str-St--ieee1275-94 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1275-1994 +-.as doc-str-St--ieee1275-94 " (\*[Lq]\*[doc-Tn-font-size]Open Firmware\*[doc-str-St]\*[Rq]) +-.ds doc-str-St--iso8601 \*[doc-Tn-font-size]ISO\*[doc-str-St] 8601 +-.ds doc-str-St--iso8802-3 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 8802-3:1989 +-. +-.de St +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name St +-. doc-parse-args \$@ +-. \} +-. el \ +-. doc-St-usage +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-St \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. ds doc-str-St1 +-. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ +-. ie d doc-str-St-\*[doc-arg\n[doc-arg-ptr]] \ +-. ds doc-str-St1 "\*[doc-str-St-\*[doc-arg\n[doc-arg-ptr]]] +-. el \{\ +-. tmc "mdoc warning: .St: Unknown standard abbreviation +-. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) +-. tm1 " Please refer to the groff_mdoc(7) manpage for a +-. tm1 " list of available standard abbreviations. +-. \}\} +-. el \ +-. doc-St-usage +-. +-. \" replacing argument with result +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-St1] +-. +-. doc-print-recursive +-. \} +-. el \{\ +-. doc-St-usage +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS doc-St-usage macro +-. +-.de doc-St-usage +-. tm1 "Usage: .St standard (#\n[.c]) +-. tm1 " Please refer to the groff_mdoc(7) manpage for a list of +-. tm1 " available standard abbreviations. +-.. +-. +-. +-.\" NS Lb user macro +-.\" NS formal library names for LIBRARY sections +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-reg-Lb +-.\" NS doc-str-Lb +-.\" NS doc-str-Lb1 +-.\" NS doc-str-Lb-XXX +-.\" NS +-.\" NS width register `Lb' defined in doc-common +-. +-.ds doc-str-Lb-libarchive Reading and Writing Streaming Archives Library (libarchive, \-larchive) +-.ds doc-str-Lb-libarm ARM Architecture Library (libarm, \-larm) +-.ds doc-str-Lb-libarm32 ARM32 Architecture Library (libarm32, \-larm32) +-.ds doc-str-Lb-libbluetooth Bluetooth Library (libbluetooth, \-lbluetooth) +-.ds doc-str-Lb-libbsm Basic Security Module Library (libbsm, \-lbsm) +-.ds doc-str-Lb-libc Standard C\~Library (libc, \-lc) +-.ds doc-str-Lb-libc_r Reentrant C\~Library (libc_r, \-lc_r) +-.ds doc-str-Lb-libcalendar Calendar Arithmetic Library (libcalendar, \-lcalendar) +-.ds doc-str-Lb-libcam Common Access Method User Library (libcam, \-lcam) +-.ds doc-str-Lb-libcdk Curses Development Kit Library (libcdk, \-lcdk) +-.ds doc-str-Lb-libcipher FreeSec Crypt Library (libcipher, \-lcipher) +-.ds doc-str-Lb-libcompat Compatibility Library (libcompat, \-lcompat) +-.ds doc-str-Lb-libcrypt Crypt Library (libcrypt, \-lcrypt) +-.ds doc-str-Lb-libcurses Curses Library (libcurses, \-lcurses) +-.ds doc-str-Lb-libdevinfo Device and Resource Information Utility Library (libdevinfo, \-ldevinfo) +-.ds doc-str-Lb-libdevstat Device Statistics Library (libdevstat, \-ldevstat) +-.ds doc-str-Lb-libdisk Interface to Slice and Partition Labels Library (libdisk, \-ldisk) +-.ds doc-str-Lb-libdwarf DWARF Access Library (libdwarf, \-ldwarf) +-.ds doc-str-Lb-libedit Command Line Editor Library (libedit, \-ledit) +-.ds doc-str-Lb-libelf ELF Access Library (libelf, \-lelf) +-.ds doc-str-Lb-libevent Event Notification Library (libevent, \-levent) +-.ds doc-str-Lb-libfetch File Transfer Library for URLs (libfetch, \-lfetch) +-.ds doc-str-Lb-libform Curses Form Library (libform, \-lform) +-.ds doc-str-Lb-libgeom Userland API Library for kernel GEOM subsystem (libgeom, \-lgeom) +-.ds doc-str-Lb-libgpib General-Purpose Instrument Bus (GPIB) library (libgpib, \-lgpib) +-.ds doc-str-Lb-libi386 i386 Architecture Library (libi386, \-li386) +-.ds doc-str-Lb-libintl Internationalized Message Handling Library (libintl, \-lintl) +-.ds doc-str-Lb-libipsec IPsec Policy Control Library (libipsec, \-lipsec) +-.ds doc-str-Lb-libipx IPX Address Conversion Support Library (libipx, \-lipx) +-.ds doc-str-Lb-libiscsi iSCSI protocol library (libiscsi, \-liscsi) +-.ds doc-str-Lb-libjail Jail Library (libjail, \-ljail) +-.ds doc-str-Lb-libkiconv Kernel side iconv library (libkiconv, \-lkiconv) +-.ds doc-str-Lb-libkse N:M Threading Library (libkse, \-lkse) +-.ds doc-str-Lb-libkvm Kernel Data Access Library (libkvm, \-lkvm) +-.ds doc-str-Lb-libm Math Library (libm, \-lm) +-.ds doc-str-Lb-libm68k m68k Architecture Library (libm68k, \-lm68k) +-.ds doc-str-Lb-libmagic Magic Number Recognition Library (libmagic, \-lmagic) +-.ds doc-str-Lb-libmd Message Digest (MD4, MD5, etc.) Support Library (libmd, \-lmd) +-.ds doc-str-Lb-libmemstat Kernel Memory Allocator Statistics Library (libmemstat, \-lmemstat) +-.ds doc-str-Lb-libmenu Curses Menu Library (libmenu, \-lmenu) +-.ds doc-str-Lb-libnetgraph Netgraph User Library (libnetgraph, \-lnetgraph) +-.ds doc-str-Lb-libnetpgp Netpgp signing, verification, encryption and decryption (libnetpgp, \-lnetpgp) +-.ds doc-str-Lb-libossaudio OSS Audio Emulation Library (libossaudio, \-lossaudio) +-.ds doc-str-Lb-libpam Pluggable Authentication Module Library (libpam, \-lpam) +-.ds doc-str-Lb-libpcap Packet Capture Library (libpcap, \-lpcap) +-.ds doc-str-Lb-libpci PCI Bus Access Library (libpci, \-lpci) +-.ds doc-str-Lb-libpmc Performance Counters Library (libpmc, \-lpmc) +-.ds doc-str-Lb-libposix \*[Px] \*[doc-str-Lb]Compatibility Library (libposix, \-lposix) +-.ds doc-str-Lb-libprop Property Container Object Library (libprop, \-lprop) +-.ds doc-str-Lb-libpthread \*[Px] \*[doc-str-Lb]Threads Library (libpthread, \-lpthread) +-.ds doc-str-Lb-libpuffs puffs Convenience Library (libpuffs, \-lpuffs) +-.ds doc-str-Lb-librefuse File System in Userspace Convenience Library (librefuse, \-lrefuse) +-.ds doc-str-Lb-libresolv DNS Resolver Library (libresolv, \-lresolv) +-.ds doc-str-Lb-librpcsec_gss RPC GSS-API Authentication Library (librpcsec_gss, \-lrpcsec_gss) +-.ds doc-str-Lb-librpcsvc RPC Service Library (librpcsvc, \-lrpcsvc) +-.ds doc-str-Lb-librt \*[Px] \*[doc-str-Lb]Real-time Library (librt, \-lrt) +-.ds doc-str-Lb-libsdp Bluetooth Service Discovery Protocol User Library (libsdp, \-lsdp) +-.ds doc-str-Lb-libssp Buffer Overflow Protection Library (libssp, \-lssp) +-.ds doc-str-Lb-libSystem System Library (libSystem, \-lSystem) +-.ds doc-str-Lb-libtermcap Termcap Access Library (libtermcap, \-ltermcap) +-.ds doc-str-Lb-libterminfo Terminal Information Library (libterminfo, \-lterminfo) +-.ds doc-str-Lb-libthr 1:1 Threading Library (libthr, \-lthr) +-.ds doc-str-Lb-libufs UFS File System Access Library (libufs, \-lufs) +-.ds doc-str-Lb-libugidfw File System Firewall Interface Library (libugidfw, \-lugidfw) +-.ds doc-str-Lb-libulog User Login Record Library (libulog, \-lulog) +-.ds doc-str-Lb-libusbhid USB Human Interface Devices Library (libusbhid, \-lusbhid) +-.ds doc-str-Lb-libutil System Utilities Library (libutil, \-lutil) +-.ds doc-str-Lb-libvgl Video Graphics Library (libvgl, \-lvgl) +-.ds doc-str-Lb-libx86_64 x86_64 Architecture Library (libx86_64, \-lx86_64) +-.ds doc-str-Lb-libz Compression Library (libz, \-lz) +-. +-.de Lb +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Lb +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Lb library_name ... (#\n[.c]) +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-str-Lb \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] +-. +-. ie d doc-str-Lb-\*[doc-arg\n[doc-arg-ptr]] \ +-. ds doc-str-Lb1 "\*[doc-str-Lb-\*[doc-arg\n[doc-arg-ptr]]] +-. el \{\ +-. tmc "mdoc warning: .Lb: no description for library +-. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' available (#\n[.c]) +-. ds doc-str-Lb1 library \*[Lq]\*[doc-arg\n[doc-arg-ptr]]\*[Rq] +-. \} +-. +-. \" replacing argument with result +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Lb1] +-. +-. if \n[doc-in-library-section] \ +-. br +-. doc-print-recursive +-. if \n[doc-in-library-section] \ +-. br +-. \} +-. el \{\ +-. tm Usage: .Lb library_name ... (#\n[.c]) +-. doc-reset-args +-. \} +-.. +-. +-. +-.ec +-. +-.\" EOF +diff -Nuar groff-1.22.3.old/tmac/doc-syms-u groff-1.22.3/tmac/doc-syms-u +--- groff-1.22.3.old/tmac/doc-syms-u 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/doc-syms-u 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,880 @@ ++.\" -*- nroff -*- ++.\" ++.\" Copyright (c) 1991, 1993 ++.\" The Regents of the University of California. All rights reserved. ++.\" ++.\" Redistribution and use in source and binary forms, with or without ++.\" modification, are permitted provided that the following conditions ++.\" are met: ++.\" 1. Redistributions of source code must retain the above copyright ++.\" notice, this list of conditions and the following disclaimer. ++.\" 2. Redistributions in binary form must reproduce the above copyright ++.\" notice, this list of conditions and the following disclaimer in the ++.\" documentation and/or other materials provided with the distribution. ++.\" 3. [Deleted. See ++.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] ++.\" 4. Neither the name of the University nor the names of its contributors ++.\" may be used to endorse or promote products derived from this software ++.\" without specific prior written permission. ++.\" ++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++.\" SUCH DAMAGE. ++.\" ++.\" @(#)doc-syms 8.1 (Berkeley) 06/08/93 ++.\" ++.\" %beginstrip% ++. ++. ++.eo ++. ++.\" NS Ux user macro ++.\" NS print UNIX ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-str-Ux ++.\" NS ++.\" NS width register `Ux' defined in doc-common ++. ++.de Ux ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-Ux \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. if !\n[doc-arg-limit] \ ++. if \n[.$] \{\ ++. ds doc-macro-name Ux ++. doc-parse-args \$@ ++. \} ++. ++. \" replace current argument with result ++. ds doc-arg\n[doc-arg-ptr] \*[doc-Tn-font-size]UNIX\*[doc-str-Ux] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. if \n[doc-num-args] \ ++. doc-parse-space-vector ++. ++. doc-print-recursive ++.. ++. ++. ++.\" NS Bx user macro ++.\" NS print BSD (fix smaller nroff version) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-str-Bx ++.\" NS doc-str-Bx1 ++.\" NS doc-str-Bx-XXX ++.\" NS ++.\" NS width register `Bx' defined in doc-common ++. ++.ds doc-str-Bx-Reno \-Reno ++.ds doc-str-Bx-reno \-Reno ++.ds doc-str-Bx-Tahoe \-Tahoe ++.ds doc-str-Bx-tahoe \-Tahoe ++.ds doc-str-Bx-Lite \-Lite ++.ds doc-str-Bx-lite \-Lite ++.ds doc-str-Bx-Lite2 \-Lite2 ++.ds doc-str-Bx-lite2 \-Lite2 ++. ++.de Bx ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-Bx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. \" default value if no argument ++. ds doc-str-Bx1 \*[doc-Tn-font-size]BSD\*[doc-str-Bx] ++. ++. if !\n[doc-arg-limit] \ ++. if \n[.$] \{\ ++. ds doc-macro-name Bx ++. doc-parse-args \$@ ++. \} ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. ie "\*[doc-arg\n[doc-arg-ptr]]"-alpha" \ ++. as doc-str-Bx1 " (currently in alpha test) ++. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-beta" \ ++. as doc-str-Bx1 " (currently in beta test) ++. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-devel" \ ++. as doc-str-Bx1 " (currently under development) ++. el \{\ ++. ds doc-str-Bx1 \&\*[doc-arg\n[doc-arg-ptr]]\^\*[doc-Tn-font-size] ++. as doc-str-Bx1 BSD\*[doc-str-Bx] ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. ie d doc-str-Bx-\*[doc-arg\n[doc-arg-ptr]] \ ++. as doc-str-Bx1 "\*[doc-str-Bx-\*[doc-arg\n[doc-arg-ptr]]] ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. el \ ++. nr doc-arg-ptr -1 ++. \}\}\}\}\} ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. ++. \" replace current argument with result ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Bx1] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. if \n[doc-num-args] \ ++. doc-parse-space-vector ++. ++. doc-print-recursive ++.. ++. ++. ++.\" NS Ud user macro (not parsed, not callable) ++.\" NS print "currently under development" (HISTORY section) ++.\" NS ++.\" NS width register `Ud' defined in doc-common ++. ++.de Ud ++. nop \¤tly under development. ++.. ++. ++. ++.\" NS At user macro ++.\" NS print AT&T UNIX ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-str-At ++.\" NS doc-str-At1 ++.\" NS doc-str-At-XXX ++.\" NS ++.\" NS width register `At' defined in doc-common ++. ++.ds doc-str-At-32v \&Version\~32V ++.as doc-str-At-32v " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] ++.ds doc-str-At-v1 \&Version\~1 ++.as doc-str-At-v1 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] ++.ds doc-str-At-v2 \&Version\~2 ++.as doc-str-At-v2 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] ++.ds doc-str-At-v3 \&Version\~3 ++.as doc-str-At-v3 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] ++.ds doc-str-At-v4 \&Version\~4 ++.as doc-str-At-v4 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] ++.ds doc-str-At-v5 \&Version\~5 ++.as doc-str-At-v5 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] ++.ds doc-str-At-v6 \&Version\~6 ++.as doc-str-At-v6 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] ++.ds doc-str-At-v7 \&Version\~7 ++.as doc-str-At-v7 " \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] ++.ds doc-str-At-III \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~III ++.as doc-str-At-III " \*[doc-Tn-font-size]UNIX\*[doc-str-At] ++.ds doc-str-At-V \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V ++.as doc-str-At-V " \*[doc-Tn-font-size]UNIX\*[doc-str-At] ++.ds doc-str-At-V.1 \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V Release\~1 ++.as doc-str-At-V.1 " \*[doc-Tn-font-size]UNIX\*[doc-str-At] ++.ds doc-str-At-V.2 \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V Release\~2 ++.as doc-str-At-V.2 " \*[doc-Tn-font-size]UNIX\*[doc-str-At] ++.ds doc-str-At-V.3 \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V Release\~3 ++.as doc-str-At-V.3 " \*[doc-Tn-font-size]UNIX\*[doc-str-At] ++.ds doc-str-At-V.4 \*[doc-Tn-font-size]AT&T\*[doc-str-At] System\~V Release\~4 ++.as doc-str-At-V.4 " \*[doc-Tn-font-size]UNIX\*[doc-str-At] ++. ++.de At ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-At \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. \" default value if no argument ++. ds doc-str-At1 \*[doc-Tn-font-size]AT&T UNIX\*[doc-str-At] ++. ++. if !\n[doc-arg-limit] \ ++. if \n[.$] \{\ ++. ds doc-macro-name At ++. doc-parse-args \$@ ++. \} ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ ++. ie d doc-str-At-\*[doc-arg\n[doc-arg-ptr]] \ ++. ds doc-str-At1 "\*[doc-str-At-\*[doc-arg\n[doc-arg-ptr]]] ++. el \{\ ++. tmc mdoc warning: .At: Unknown AT&T UNIX version ++. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) ++. nr doc-arg-ptr -1 ++. \}\} ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. ++. \" replace current argument with result ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-At1] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. if \n[doc-num-args] \ ++. doc-parse-space-vector ++. ++. doc-print-recursive ++.. ++. ++. ++.\" NS Dx user macro ++.\" NS print DragonFly ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-str-Dx ++.\" NS doc-str-Dx1 ++.\" NS ++.\" NS width register `Dx' defined in doc-common ++. ++.\" we use the doc-operating-system-DragonFly-* strings defined in doc-common ++. ++.de Dx ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-Dx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. \" default value if no argument ++. ds doc-str-Dx1 \*[doc-Tn-font-size]\%DragonFly\*[doc-str-Dx] ++. ++. if !\n[doc-arg-limit] \ ++. if \n[.$] \{\ ++. ds doc-macro-name Dx ++. doc-parse-args \$@ ++. \} ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ ++. ie d doc-operating-system-DragonFly-\*[doc-arg\n[doc-arg-ptr]] \ ++. as doc-str-Dx1 \~\*[doc-operating-system-DragonFly-\*[doc-arg\n[doc-arg-ptr]]] ++. el \{\ ++. tmc mdoc warning: .Dx: Unknown DragonFly version ++. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) ++. as doc-str-Dx1 \~\*[doc-arg\n[doc-arg-ptr]] ++. \}\} ++. el \ ++. as doc-str-Dx1 \~\*[doc-arg\n[doc-arg-ptr]] ++. \} ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. ++. \" replace current argument with result ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Dx1] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. if \n[doc-num-args] \ ++. doc-parse-space-vector ++. ++. doc-print-recursive ++.. ++. ++. ++.\" NS Fx user macro ++.\" NS print FreeBSD ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-str-Fx ++.\" NS doc-str-Fx1 ++.\" NS ++.\" NS width register `Fx' defined in doc-common ++. ++.\" we use the doc-operating-system-FreeBSD-* strings defined in doc-common ++. ++.de Fx ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-Fx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. \" default value if no argument ++. ds doc-str-Fx1 \*[doc-Tn-font-size]\%FreeBSD\*[doc-str-Fx] ++. ++. if !\n[doc-arg-limit] \ ++. if \n[.$] \{\ ++. ds doc-macro-name Fx ++. doc-parse-args \$@ ++. \} ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ ++. ie d doc-operating-system-FreeBSD-\*[doc-arg\n[doc-arg-ptr]] \ ++. as doc-str-Fx1 \~\*[doc-operating-system-FreeBSD-\*[doc-arg\n[doc-arg-ptr]]] ++. el \{\ ++. tmc mdoc warning: .Fx: Unknown FreeBSD version ++. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) ++. as doc-str-Fx1 \~\*[doc-arg\n[doc-arg-ptr]] ++. \}\} ++. el \ ++. as doc-str-Fx1 \~\*[doc-arg\n[doc-arg-ptr]] ++. \} ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. ++. \" replace current argument with result ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Fx1] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. if \n[doc-num-args] \ ++. doc-parse-space-vector ++. ++. doc-print-recursive ++.. ++. ++. ++.\" NS Nx user macro ++.\" NS print NetBSD ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-str-Nx ++.\" NS doc-str-Nx1 ++.\" NS ++.\" NS width register `Nx' defined in doc-common ++. ++.\" we use the doc-operating-system-NetBSD-* strings defined in doc-common ++. ++.de Nx ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-Nx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. \" default value if no argument ++. ds doc-str-Nx1 \*[doc-Tn-font-size]\%N\s[\n[doc-curr-size]u]et ++. as doc-str-Nx1 \*[doc-Tn-font-size]BSD\*[doc-str-Nx] ++. ++. if !\n[doc-arg-limit] \ ++. if \n[.$] \{\ ++. ds doc-macro-name Nx ++. doc-parse-args \$@ ++. \} ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ ++. ie d doc-operating-system-NetBSD-\*[doc-arg\n[doc-arg-ptr]] \ ++. as doc-str-Nx1 \~\*[doc-operating-system-NetBSD-\*[doc-arg\n[doc-arg-ptr]]] ++. el \{\ ++. tmc mdoc warning: .Nx: Unknown NetBSD version ++. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) ++. as doc-str-Nx1 \~\*[doc-arg\n[doc-arg-ptr]] ++. \}\} ++. el \ ++. as doc-str-Nx1 \~\*[doc-arg\n[doc-arg-ptr]] ++. \} ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. ++. \" replace current argument with result ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Nx1] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. if \n[doc-num-args] \ ++. doc-parse-space-vector ++. ++. doc-print-recursive ++.. ++. ++. ++.\" NS Ox user macro ++.\" NS print OpenBSD ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-str-Ox ++.\" NS doc-str-Ox1 ++.\" NS ++.\" NS width register `Ox' defined in doc-common ++. ++.de Ox ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-Ox \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. \" default value if no argument ++. ds doc-str-Ox1 \*[doc-Tn-font-size]\%OpenBSD\*[doc-str-Ox] ++. ++. if !\n[doc-arg-limit] \ ++. if \n[.$] \{\ ++. ds doc-macro-name Ox ++. doc-parse-args \$@ ++. \} ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \ ++. as doc-str-Ox1 \~\*[doc-arg\n[doc-arg-ptr]] ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. ++. \" replace current argument with result ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Ox1] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. if \n[doc-num-args] \ ++. doc-parse-space-vector ++. ++. doc-print-recursive ++.. ++. ++. ++.\" NS Bsx user macro ++.\" NS print BSD/OS ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-str-Bsx ++.\" NS doc-str-Bsx1 ++.\" NS ++.\" NS width register `Bsx' defined in doc-common ++. ++.de Bsx ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-Bsx \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. \" default value if no argument ++. ds doc-str-Bsx1 \*[doc-Tn-font-size]BSD/OS\*[doc-str-Bsx] ++. ++. if !\n[doc-arg-limit] \ ++. if \n[.$] \{\ ++. ds doc-macro-name Bsx ++. doc-parse-args \$@ ++. \} ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \ ++. as doc-str-Bsx1 \~\*[doc-arg\n[doc-arg-ptr]] ++. el \ ++. nr doc-arg-ptr -1 ++. \} ++. ++. \" replace current argument with result ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Bsx1] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. if \n[doc-num-args] \ ++. doc-parse-space-vector ++. ++. doc-print-recursive ++.. ++. ++. ++.\" The Bt macro should go away now ++. ++.\" NS Bt user macro (not parsed, not callable) ++.\" NS print "is currently in beta test." (HISTORY section) ++.\" NS ++.\" NS width register `Bt' defined in doc-common ++. ++.de Bt ++. nop \&is currently in beta test. ++.. ++. ++. ++.\" NS Px user macro ++.\" NS print POSIX ++. ++.ds Px \*[doc-Tn-font-size]\%POSIX ++. ++. ++.\" NS Ai user macro ++.\" NS print ANSI ++. ++.ds Ai \*[doc-Tn-font-size]\%ANSI ++. ++. ++.\" NS St user macro ++.\" NS standards (posix, ansi - formal standard names) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-reg-St ++.\" NS doc-str-St ++.\" NS doc-str-St1 ++.\" NS doc-str-St-XXX ++.\" NS ++.\" NS width register `St' defined in doc-common ++. ++.\" ANSI/ISO C ++.ds doc-str-St--ansiC-89 \*[Ai] \*[doc-str-St]X\^3.159-1989 ++.as doc-str-St--ansiC-89 " (\*[Lq]\)\*[Ai]\~C89\*[doc-str-St]\*[Rq]) ++.als doc-str-St--ansiC doc-str-St--ansiC-89 ++.ds doc-str-St--isoC \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899:1990 ++.as doc-str-St--isoC " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^90\*[doc-str-St]\*[Rq]) ++.als doc-str-St--isoC-90 doc-str-St--isoC ++.ds doc-str-St--isoC-2011 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899:2011 ++.as doc-str-St--isoC-2011 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^11\*[doc-str-St]\*[Rq]) ++.ds doc-str-St--isoC-99 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899:1999 ++.as doc-str-St--isoC-99 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^99\*[doc-str-St]\*[Rq]) ++.ds doc-str-St--isoC-amd1 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899/AMD1:1995 ++.as doc-str-St--isoC-amd1 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^90\*[doc-str-St], Amendment 1\*[Rq]) ++.ds doc-str-St--isoC-tcor1 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899/TCOR1:1994 ++.as doc-str-St--isoC-tcor1 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^90\*[doc-str-St], Technical Corrigendum 1\*[Rq]) ++.ds doc-str-St--isoC-tcor2 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9899/TCOR2:1995 ++.as doc-str-St--isoC-tcor2 " (\*[Lq]\*[doc-Tn-font-size]ISO\~C\^90\*[doc-str-St], Technical Corrigendum 2\*[Rq]) ++. ++.\" POSIX Part 1: System API ++.ds doc-str-St--p1003.1 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1 ++.as doc-str-St--p1003.1 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.ds doc-str-St--p1003.1b \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1b ++.as doc-str-St--p1003.1b " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.ds doc-str-St--p1003.1-88 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1-1988 ++.as doc-str-St--p1003.1-88 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.ds doc-str-St--p1003.1-90 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9945-1:1990 ++.as doc-str-St--p1003.1-90 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.als doc-str-St--iso9945-1-90 doc-str-St--p1003.1-90 ++.ds doc-str-St--p1003.1b-93 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1b-1993 ++.as doc-str-St--p1003.1b-93 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.ds doc-str-St--p1003.1c-95 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1c-1995 ++.as doc-str-St--p1003.1c-95 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.ds doc-str-St--p1003.1i-95 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1i-1995 ++.as doc-str-St--p1003.1i-95 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.ds doc-str-St--p1003.1-96 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9945-1:1996 ++.as doc-str-St--p1003.1-96 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.als doc-str-St--iso9945-1-96 doc-str-St--p1003.1-96 ++.ds doc-str-St--p1003.1g-2000 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1g-2000 ++.as doc-str-St--p1003.1g-2000 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.ds doc-str-St--p1003.1-2001 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1-2001 ++.as doc-str-St--p1003.1-2001 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.ds doc-str-St--p1003.1-2004 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1-2004 ++.as doc-str-St--p1003.1-2004 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++.ds doc-str-St--p1003.1-2008 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.1-2008 ++.as doc-str-St--p1003.1-2008 " (\*[Lq]\)\*[Px]\*[doc-str-St].1\*[Rq]) ++. ++.\" POSIX Part 2: Shell and Utilities ++.ds doc-str-St--p1003.2 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.2 ++.as doc-str-St--p1003.2 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) ++.ds doc-str-St--p1003.2-92 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.2-1992 ++.as doc-str-St--p1003.2-92 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) ++.ds doc-str-St--p1003.2a-92 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1003.2a-1992 ++.as doc-str-St--p1003.2a-92 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) ++.ds doc-str-St--iso9945-2-93 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 9945-2:1993 ++.as doc-str-St--iso9945-2-93 " (\*[Lq]\)\*[Px]\*[doc-str-St].2\*[Rq]) ++. ++.\" X/Open ++.ds doc-str-St--susv2 Version\~2 of the Single \*[doc-Tn-font-size]UNIX\*[doc-str-St] Specification ++.as doc-str-St--susv2 " (\*[Lq]\*[doc-Tn-font-size]SUSv2\*[doc-str-St]\*[Rq]) ++.ds doc-str-St--susv3 Version\~3 of the Single \*[doc-Tn-font-size]UNIX\*[doc-str-St] Specification ++.as doc-str-St--susv3 " (\*[Lq]\*[doc-Tn-font-size]SUSv3\*[doc-str-St]\*[Rq]) ++.ds doc-str-St--svid4 System\~V Interface Definition, Fourth Edition ++.as doc-str-St--svid4 " (\*[Lq]\*[doc-Tn-font-size]SVID\*[doc-str-St]\^4\*[Rq]) ++.ds doc-str-St--xbd5 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Base Definitions Issue\~5 ++.as doc-str-St--xbd5 " (\*[Lq]\*[doc-Tn-font-size]XBD\*[doc-str-St]\^5\*[Rq]) ++.ds doc-str-St--xcu5 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Commands and Utilities Issue\~5 ++.as doc-str-St--xcu5 " (\*[Lq]\*[doc-Tn-font-size]XCU\*[doc-str-St]\^5\*[Rq]) ++.ds doc-str-St--xcurses4.2 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Curses Issue\~4, Version\~2 ++.as doc-str-St--xcurses4.2 " (\*[Lq]\*[doc-Tn-font-size]XCURSES\*[doc-str-St]\^4.2\*[Rq]) ++.ds doc-str-St--xns5 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Networking Services Issue\~5 ++.as doc-str-St--xns5 " (\*[Lq]\*[doc-Tn-font-size]XNS\*[doc-str-St]\^5\*[Rq]) ++.ds doc-str-St--xns5.2 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Networking Services Issue\~5.2 ++.as doc-str-St--xns5.2 " (\*[Lq]\*[doc-Tn-font-size]XNS\*[doc-str-St]\^5.2\*[Rq]) ++.ds doc-str-St--xpg3 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Portability Guide Issue\~3 ++.as doc-str-St--xpg3 " (\*[Lq]\*[doc-Tn-font-size]XPG\*[doc-str-St]\^3\*[Rq]) ++.ds doc-str-St--xpg4 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Portability Guide Issue\~4 ++.as doc-str-St--xpg4 " (\*[Lq]\*[doc-Tn-font-size]XPG\*[doc-str-St]\^4\*[Rq]) ++.ds doc-str-St--xpg4.2 \*[doc-Tn-font-size]X/Open\*[doc-str-St] Portability Guide Issue\~4, Version\~2 ++.as doc-str-St--xpg4.2 " (\*[Lq]\*[doc-Tn-font-size]XPG\*[doc-str-St]\^4.2\*[Rq]) ++.ds doc-str-St--xsh5 \*[doc-Tn-font-size]X/Open\*[doc-str-St] System Interfaces and Headers Issue\~5 ++.as doc-str-St--xsh5 " (\*[Lq]\*[doc-Tn-font-size]XSH\*[doc-str-St]\^5\*[Rq]) ++. ++.\" Miscellaneous ++.ds doc-str-St--ieee754 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 754-1985 ++.ds doc-str-St--ieee1275-94 \*[doc-Tn-font-size]\%IEEE\*[doc-str-St] Std 1275-1994 ++.as doc-str-St--ieee1275-94 " (\*[Lq]\*[doc-Tn-font-size]Open Firmware\*[doc-str-St]\*[Rq]) ++.ds doc-str-St--iso8601 \*[doc-Tn-font-size]ISO\*[doc-str-St] 8601 ++.ds doc-str-St--iso8802-3 \*[doc-Tn-font-size]ISO/IEC\*[doc-str-St] 8802-3:1989 ++. ++.de St ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name St ++. doc-parse-args \$@ ++. \} ++. el \ ++. doc-St-usage ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-St \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. ds doc-str-St1 ++. ie \A\*[doc-arg\n[doc-arg-ptr]] \{\ ++. ie d doc-str-St-\*[doc-arg\n[doc-arg-ptr]] \ ++. ds doc-str-St1 "\*[doc-str-St-\*[doc-arg\n[doc-arg-ptr]]] ++. el \{\ ++. tmc "mdoc warning: .St: Unknown standard abbreviation ++. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' (#\n[.c]) ++. tm1 " Please refer to the groff_mdoc(7) manpage for a ++. tm1 " list of available standard abbreviations. ++. \}\} ++. el \ ++. doc-St-usage ++. ++. \" replacing argument with result ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-St1] ++. ++. doc-print-recursive ++. \} ++. el \{\ ++. doc-St-usage ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS doc-St-usage macro ++. ++.de doc-St-usage ++. tm1 "Usage: .St standard (#\n[.c]) ++. tm1 " Please refer to the groff_mdoc(7) manpage for a list of ++. tm1 " available standard abbreviations. ++.. ++. ++. ++.\" NS Lb user macro ++.\" NS formal library names for LIBRARY sections ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-reg-Lb ++.\" NS doc-str-Lb ++.\" NS doc-str-Lb1 ++.\" NS doc-str-Lb-XXX ++.\" NS ++.\" NS width register `Lb' defined in doc-common ++. ++.ds doc-str-Lb-libarchive Reading and Writing Streaming Archives Library (libarchive, \-larchive) ++.ds doc-str-Lb-libarm ARM Architecture Library (libarm, \-larm) ++.ds doc-str-Lb-libarm32 ARM32 Architecture Library (libarm32, \-larm32) ++.ds doc-str-Lb-libbluetooth Bluetooth Library (libbluetooth, \-lbluetooth) ++.ds doc-str-Lb-libbsm Basic Security Module Library (libbsm, \-lbsm) ++.ds doc-str-Lb-libc Standard C\~Library (libc, \-lc) ++.ds doc-str-Lb-libc_r Reentrant C\~Library (libc_r, \-lc_r) ++.ds doc-str-Lb-libcalendar Calendar Arithmetic Library (libcalendar, \-lcalendar) ++.ds doc-str-Lb-libcam Common Access Method User Library (libcam, \-lcam) ++.ds doc-str-Lb-libcdk Curses Development Kit Library (libcdk, \-lcdk) ++.ds doc-str-Lb-libcipher FreeSec Crypt Library (libcipher, \-lcipher) ++.ds doc-str-Lb-libcompat Compatibility Library (libcompat, \-lcompat) ++.ds doc-str-Lb-libcrypt Crypt Library (libcrypt, \-lcrypt) ++.ds doc-str-Lb-libcurses Curses Library (libcurses, \-lcurses) ++.ds doc-str-Lb-libdevinfo Device and Resource Information Utility Library (libdevinfo, \-ldevinfo) ++.ds doc-str-Lb-libdevstat Device Statistics Library (libdevstat, \-ldevstat) ++.ds doc-str-Lb-libdisk Interface to Slice and Partition Labels Library (libdisk, \-ldisk) ++.ds doc-str-Lb-libdwarf DWARF Access Library (libdwarf, \-ldwarf) ++.ds doc-str-Lb-libedit Command Line Editor Library (libedit, \-ledit) ++.ds doc-str-Lb-libelf ELF Access Library (libelf, \-lelf) ++.ds doc-str-Lb-libevent Event Notification Library (libevent, \-levent) ++.ds doc-str-Lb-libfetch File Transfer Library for URLs (libfetch, \-lfetch) ++.ds doc-str-Lb-libform Curses Form Library (libform, \-lform) ++.ds doc-str-Lb-libgeom Userland API Library for kernel GEOM subsystem (libgeom, \-lgeom) ++.ds doc-str-Lb-libgpib General-Purpose Instrument Bus (GPIB) library (libgpib, \-lgpib) ++.ds doc-str-Lb-libi386 i386 Architecture Library (libi386, \-li386) ++.ds doc-str-Lb-libintl Internationalized Message Handling Library (libintl, \-lintl) ++.ds doc-str-Lb-libipsec IPsec Policy Control Library (libipsec, \-lipsec) ++.ds doc-str-Lb-libipx IPX Address Conversion Support Library (libipx, \-lipx) ++.ds doc-str-Lb-libiscsi iSCSI protocol library (libiscsi, \-liscsi) ++.ds doc-str-Lb-libjail Jail Library (libjail, \-ljail) ++.ds doc-str-Lb-libkiconv Kernel side iconv library (libkiconv, \-lkiconv) ++.ds doc-str-Lb-libkse N:M Threading Library (libkse, \-lkse) ++.ds doc-str-Lb-libkvm Kernel Data Access Library (libkvm, \-lkvm) ++.ds doc-str-Lb-libm Math Library (libm, \-lm) ++.ds doc-str-Lb-libm68k m68k Architecture Library (libm68k, \-lm68k) ++.ds doc-str-Lb-libmagic Magic Number Recognition Library (libmagic, \-lmagic) ++.ds doc-str-Lb-libmd Message Digest (MD4, MD5, etc.) Support Library (libmd, \-lmd) ++.ds doc-str-Lb-libmemstat Kernel Memory Allocator Statistics Library (libmemstat, \-lmemstat) ++.ds doc-str-Lb-libmenu Curses Menu Library (libmenu, \-lmenu) ++.ds doc-str-Lb-libnetgraph Netgraph User Library (libnetgraph, \-lnetgraph) ++.ds doc-str-Lb-libnetpgp Netpgp signing, verification, encryption and decryption (libnetpgp, \-lnetpgp) ++.ds doc-str-Lb-libossaudio OSS Audio Emulation Library (libossaudio, \-lossaudio) ++.ds doc-str-Lb-libpam Pluggable Authentication Module Library (libpam, \-lpam) ++.ds doc-str-Lb-libpcap Packet Capture Library (libpcap, \-lpcap) ++.ds doc-str-Lb-libpci PCI Bus Access Library (libpci, \-lpci) ++.ds doc-str-Lb-libpmc Performance Counters Library (libpmc, \-lpmc) ++.ds doc-str-Lb-libposix \*[Px] \*[doc-str-Lb]Compatibility Library (libposix, \-lposix) ++.ds doc-str-Lb-libprop Property Container Object Library (libprop, \-lprop) ++.ds doc-str-Lb-libpthread \*[Px] \*[doc-str-Lb]Threads Library (libpthread, \-lpthread) ++.ds doc-str-Lb-libpuffs puffs Convenience Library (libpuffs, \-lpuffs) ++.ds doc-str-Lb-librefuse File System in Userspace Convenience Library (librefuse, \-lrefuse) ++.ds doc-str-Lb-libresolv DNS Resolver Library (libresolv, \-lresolv) ++.ds doc-str-Lb-librpcsec_gss RPC GSS-API Authentication Library (librpcsec_gss, \-lrpcsec_gss) ++.ds doc-str-Lb-librpcsvc RPC Service Library (librpcsvc, \-lrpcsvc) ++.ds doc-str-Lb-librt \*[Px] \*[doc-str-Lb]Real-time Library (librt, \-lrt) ++.ds doc-str-Lb-libsdp Bluetooth Service Discovery Protocol User Library (libsdp, \-lsdp) ++.ds doc-str-Lb-libssp Buffer Overflow Protection Library (libssp, \-lssp) ++.ds doc-str-Lb-libSystem System Library (libSystem, \-lSystem) ++.ds doc-str-Lb-libtermcap Termcap Access Library (libtermcap, \-ltermcap) ++.ds doc-str-Lb-libterminfo Terminal Information Library (libterminfo, \-lterminfo) ++.ds doc-str-Lb-libthr 1:1 Threading Library (libthr, \-lthr) ++.ds doc-str-Lb-libufs UFS File System Access Library (libufs, \-lufs) ++.ds doc-str-Lb-libugidfw File System Firewall Interface Library (libugidfw, \-lugidfw) ++.ds doc-str-Lb-libulog User Login Record Library (libulog, \-lulog) ++.ds doc-str-Lb-libusbhid USB Human Interface Devices Library (libusbhid, \-lusbhid) ++.ds doc-str-Lb-libutil System Utilities Library (libutil, \-lutil) ++.ds doc-str-Lb-libvgl Video Graphics Library (libvgl, \-lvgl) ++.ds doc-str-Lb-libx86_64 x86_64 Architecture Library (libx86_64, \-lx86_64) ++.ds doc-str-Lb-libz Compression Library (libz, \-lz) ++. ++.de Lb ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Lb ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Lb library_name ... (#\n[.c]) ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-str-Lb \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u] ++. ++. ie d doc-str-Lb-\*[doc-arg\n[doc-arg-ptr]] \ ++. ds doc-str-Lb1 "\*[doc-str-Lb-\*[doc-arg\n[doc-arg-ptr]]] ++. el \{\ ++. tmc "mdoc warning: .Lb: no description for library ++. tm1 " `\*[doc-arg\n[doc-arg-ptr]]' available (#\n[.c]) ++. ds doc-str-Lb1 library \*[Lq]\*[doc-arg\n[doc-arg-ptr]]\*[Rq] ++. \} ++. ++. \" replacing argument with result ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Lb1] ++. ++. if \n[doc-in-library-section] \ ++. br ++. doc-print-recursive ++. if \n[doc-in-library-section] \ ++. br ++. \} ++. el \{\ ++. tm Usage: .Lb library_name ... (#\n[.c]) ++. doc-reset-args ++. \} ++.. ++. ++. ++.ec ++. ++.\" EOF +diff -Nuar groff-1.22.3.old/tmac/doc.tmac groff-1.22.3/tmac/doc.tmac +--- groff-1.22.3.old/tmac/doc.tmac 2014-11-04 10:38:35.534520134 +0200 ++++ groff-1.22.3/tmac/doc.tmac 1970-01-01 02:00:00.000000000 +0200 +@@ -1,6599 +0,0 @@ +-.\" -*- nroff -*- +-.\" +-.\" Copyright (c) 1991, 1993 +-.\" The Regents of the University of California. All rights reserved. +-.\" +-.\" Redistribution and use in source and binary forms, with or without +-.\" modification, are permitted provided that the following conditions +-.\" are met: +-.\" 1. Redistributions of source code must retain the above copyright +-.\" notice, this list of conditions and the following disclaimer. +-.\" 2. Redistributions in binary form must reproduce the above copyright +-.\" notice, this list of conditions and the following disclaimer in the +-.\" documentation and/or other materials provided with the distribution. +-.\" 3. [Deleted. See +-.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] +-.\" 4. Neither the name of the University nor the names of its contributors +-.\" may be used to endorse or promote products derived from this software +-.\" without specific prior written permission. +-.\" +-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-.\" SUCH DAMAGE. +-.\" +-.\" @(#)doc 8.1 (Berkeley) 06/08/93 +-.\" +-.\" Modified by jjc@jclark.com as follows: the doc-* files are assumed to be +-.\" installed as mdoc/doc-* rather than tmac.doc-* (the filename +-.\" `tmac.doc-common' would be too long); when using groff, the doc-* files +-.\" are loaded using the `mso' request. +-.\" +-.\" Modified by +-.\" +-.\" Werner LEMBERG and +-.\" Ruslan Ermilov +-.\" +-.\" to make it more readable: using long names and many groff features, +-.\" updating and extending documentation, etc. +-.\" +-.\" %beginstrip% +-. +-. +-.if !\n(.g \ +-. ab This version of mdoc can be run with GNU troff only! +-. +-. +-.do if d Dd .nx +-. +-. +-.cp 0 +-. +-. +-.if (\n[.x]\n[.y] < 118) \ +-. ab You need GNU troff version 1.18 or higher to run this version of mdoc! +-. +-. +-.\" Load start-up files +-.ie t \ +-. mso mdoc/doc-ditroff +-.el \ +-. mso mdoc/doc-nroff +-. +-.mso mdoc/doc-common +-.mso mdoc/doc-syms +-. +-. +-.eo +-. +-. +-.\" NS doc-macro-name global string +-.\" NS name of calling request (set in each user-requestable macro) +-. +-.ds doc-macro-name +-.als doc-arg0 doc-macro-name +-. +-. +-.\" NS doc-arg-limit global register +-.\" NS total number of arguments +-. +-.nr doc-arg-limit 0 +-. +-. +-.\" NS doc-num-args global register +-.\" NS number of arguments to handle (must be set to \n[.$] prior to +-.\" NS `doc-parse-arg-vector' request) +-. +-.nr doc-num-args 0 +-. +-. +-.\" NS doc-arg-ptr global register +-.\" NS argument pointer +-. +-.nr doc-arg-ptr 0 +-. +-. +-.\" NS doc-argXXX global string +-.\" NS argument vector +-.\" NS +-.\" NS limit: +-.\" NS doc-arg-limit +-. +-.ds doc-arg1 +-. +-. +-.\" NS doc-typeXXX global register +-.\" NS argument type vector (macro=1, string=2, punctuation suffix=3, +-.\" NS punctuation prefix=4) +-.\" NS +-.\" NS limit: +-.\" NS doc-arg-limit +-. +-.nr doc-type1 0 +-. +-. +-.\" NS doc-spaceXXX global string +-.\" NS space vector +-.\" NS +-.\" NS limit: +-.\" NS doc-arg-limit +-. +-.ds doc-space1 +-. +-. +-.\" NS doc-parse-args macro +-.\" NS parse arguments (recursively) (`.doc-parse-args arg ...') +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-limit +-.\" NS doc-arg-ptr +-.\" NS doc-argXXX +-.\" NS doc-spaceXXX +-.\" NS doc-typeXXX +-.\" NS doc-arg-ptr +-.\" NS doc-have-space +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dpa +-.\" NS doc-reg-dpa1 +-.\" NS doc-str-dpa +-. +-.de doc-parse-args +-. if !\n[doc-arg-limit] \ +-. doc-set-spacing-1 +-. +-. nr doc-have-space 0 +-. +-. if !\n[.$] \ +-. return +-. +-. nr doc-arg-limit +1 +-. +-. \" handle `|' and `...' specially +-. ie "\$1"|" \ +-. ds doc-arg\n[doc-arg-limit] \f[R]|\f[] +-. el \{ .ie "\$1"..." \ +-. ds doc-arg\n[doc-arg-limit] \|.\|.\|. +-. el \ +-. ds doc-arg\n[doc-arg-limit] "\$1 +-. \} +-. +-. \" get argument type and set spacing +-. doc-get-arg-type* \n[doc-arg-limit] +-. nr doc-type\n[doc-arg-limit] \n[doc-arg-type] +-. doc-set-spacing-\n[doc-arg-type] +-. +-. \" check whether we have processed the last parameter +-. ie (\n[.$] == 1) \ +-. nr doc-arg-ptr 0 +-. el \{\ +-. shift +-. doc-parse-args \$@ +-. \} +-. +-. nh +-.. +-. +-. +-.\" NS doc-parse-arg-vector macro +-.\" NS parse argument vector (recursive) +-.\" NS +-.\" NS cf. comments in doc-parse-args +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-limit +-.\" NS doc-arg-ptr +-.\" NS doc-argXXX +-.\" NS doc-num-args +-.\" NS doc-spaceXXX +-.\" NS doc-typeXXX +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dpav +-.\" NS doc-reg-dpav1 +-.\" NS doc-str-dpav +-. +-.de doc-parse-arg-vector +-. if !\n[doc-arg-limit] \ +-. doc-set-spacing-1 +-. +-. nr doc-arg-limit +1 +-. +-. ie "\*[doc-arg\n[doc-arg-limit]]"|" \ +-. ds doc-arg\n[doc-arg-limit] \f[R]|\f[] +-. el \{ .if "\*[doc-arg\n[doc-arg-limit]]"..." \ +-. ds doc-arg\n[doc-arg-limit] \|.\|.\|. +-. \} +-. +-. doc-get-arg-type* \n[doc-arg-limit] +-. nr doc-type\n[doc-arg-limit] \n[doc-arg-type] +-. doc-set-spacing-\n[doc-arg-type] +-. +-. ie (\n[doc-num-args] == 1) \{\ +-. nr doc-arg-ptr 0 +-. nr doc-num-args 0 +-. \} +-. el \{\ +-. nr doc-num-args -1 +-. doc-parse-arg-vector +-. \} +-. +-. nh +-.. +-. +-. +-.\" NS doc-parse-space-vector macro +-.\" NS parse space vector (recursive) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-limit +-.\" NS doc-num-args +-.\" NS doc-spaceXXX +-. +-.de doc-parse-space-vector +-. nr doc-arg-limit +1 +-. +-. doc-set-spacing-\n[doc-type\n[doc-arg-limit]] +-. +-. ie (\n[doc-num-args] == 1) \ +-. nr doc-num-args 0 +-. el \{\ +-. nr doc-num-args -1 +-. doc-parse-space-vector +-. \} +-.. +-. +-. +-.\" NS doc-remaining-args macro +-.\" NS output remaining arguments as-is, separated by spaces (until +-.\" NS `doc-num-args' is exhausted) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-num-args +-. +-.de doc-remaining-args +-. nr doc-arg-ptr +1 +-. nop \)\*[doc-arg\n[doc-arg-ptr]]\c +-. +-. ie (\n[doc-num-args] == 1) \{\ +-. nr doc-arg-ptr 0 +-. nr doc-num-args 0 +-. \} +-. el \{\ +-. nop \)\*[doc-space]\c +-. nr doc-num-args -1 +-. doc-remaining-args +-. \} +-.. +-. +-. +-.\" NS doc-append-arg macro +-.\" NS append one argument to argument vector: +-.\" NS `.doc-append-arg [arg] [type]' +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-limit +-.\" NS doc-argXXX +-.\" NS doc-typeXXX +-. +-.de doc-append-arg +-. nr doc-arg-limit +1 +-. ds doc-arg\n[doc-arg-limit] "\$1 +-. nr doc-type\n[doc-arg-limit] \$2 +-. doc-set-spacing-\$2 +-.. +-. +-. +-.\" NS doc-print-and-reset macro +-.\" NS finish input line and clean up argument vectors +-. +-.de doc-print-and-reset +-. if \n[doc-space-mode] \ +-. nop \) +-. doc-reset-args +-.. +-. +-. +-.\" NS doc-reset-args macro +-.\" NS reset argument counters +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-limit +-.\" NS doc-arg-ptr +-.\" NS doc-have-slot +-. +-.de doc-reset-args +-. nr doc-arg-limit 0 +-. nr doc-arg-ptr 0 +-. nr doc-have-slot 0 +-. +-. hy \n[doc-hyphen-flags] +-.. +-. +-. +-.ec +-. +-.\" NS doc-curr-font global register +-.\" NS saved current font +-. +-.nr doc-curr-font \n[.f] +-. +-. +-.\" NS doc-curr-size global register +-.\" NS saved current font size +-. +-.nr doc-curr-size \n[.ps] +-. +-.eo +-. +-. +-.\" NS Fl user macro +-.\" NS handle flags (appends `-' and prints flags): `.Fl [arg ...]' +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-Fl (for communication with doc-flag-recursion) +-.\" NS +-.\" NS width register `Fl' set in doc-common +-. +-.de Fl +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Fl-font]\c +-. +-. if !\n[doc-arg-limit] \{\ +-. ds doc-macro-name Fl +-. doc-parse-args \$@ +-. +-. \" no arguments +-. if !\n[.$] \ +-. nop \|\-\|\f[]\s[0] +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ +-. \" last argument +-. nop \|\-\f[]\s[0]\c +-. doc-print-and-reset +-. \} +-. el \{\ +-. ie (\n[doc-type\n[doc-arg-ptr]] == 1) \{\ +-. nop \|\-\f[]\s[0]\c +-. \*[doc-arg\n[doc-arg-ptr]] +-. \} +-. el \{\ +-. if (\n[doc-type\n[doc-arg-ptr]] == 3) \ +-. nop \|\-\|\c +-. +-. nr doc-reg-Fl 1 +-. doc-flag-recursion +-. \}\} +-.. +-. +-. +-.\" NS doc-flag-recursion macro +-.\" NS `Fl' flag recursion routine (special handling) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dfr +-.\" NS doc-reg-dfr1 +-.\" NS doc-str-dfr +-. +-.de doc-flag-recursion +-. nr doc-reg-dfr1 \n[doc-type\n[doc-arg-ptr]] +-. ds doc-str-dfr "\*[doc-arg\n[doc-arg-ptr]] +-. +-. ie (\n[doc-reg-dfr1] == 1) \{\ +-. nop \f[]\s[0]\c +-. \*[doc-str-dfr] +-. \} +-. el \{\ +-. nr doc-reg-dfr \n[doc-arg-ptr] +-. +-. ie (\n[doc-reg-dfr1] == 2) \{\ +-. \" handle vertical bar -- doc-reg-Fl is set for the first call of +-. \" doc-flag-recursion only; we need this to make `.Fl | ...' work +-. \" correctly +-. ie "\*[doc-str-dfr]"\*[Ba]" \{\ +-. if \n[doc-reg-Fl] \ +-. nop \|\-\*[doc-space]\c +-. nop \)\*[Ba]\c +-. \} +-. el \{\ +-. ie "\*[doc-str-dfr]"\f[R]|\f[]" \{\ +-. if \n[doc-reg-Fl] \ +-. nop \|\-\*[doc-space]\c +-. nop \f[R]|\f[]\c +-. \} +-. el \{\ +-. \" two consecutive hyphen characters? +-. ie "\*[doc-str-dfr]"-" \ +-. nop \|\-\^\-\|\c +-. el \ +-. nop \|\%\-\*[doc-str-dfr]\&\c +-. \}\}\} +-. el \{\ +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c +-. nop \)\*[doc-str-dfr]\f[]\s[0]\c +-. \} +-. +-. ie (\n[doc-arg-limit] == \n[doc-arg-ptr]) \{\ +-. \" last argument +-. if (\n[doc-reg-dfr1] == 4) \ +-. nop \|\-\c +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c +-. doc-print-and-reset +-. \} +-. el \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-type\n[doc-arg-ptr]] == 3) \{\ +-. ie (\n[doc-type\n[doc-reg-dfr]] == 4) \ +-. nop \|\-\c +-. el \ +-. nop \)\*[doc-space\n[doc-reg-dfr]]\c +-. \} +-. el \ +-. nop \)\*[doc-space\n[doc-reg-dfr]]\c +-. +-. shift +-. nr doc-reg-Fl 0 +-. doc-flag-recursion \$@ +-. \}\} +-.. +-. +-. +-.\" NS doc-print-recursive macro +-.\" NS general name recursion routine (print remaining arguments) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dpr +-.\" NS doc-reg-dpr1 +-.\" NS doc-str-dpr +-. +-.de doc-print-recursive +-. nr doc-reg-dpr1 \n[doc-type\n[doc-arg-ptr]] +-. ds doc-str-dpr "\*[doc-arg\n[doc-arg-ptr]] +-. +-. ie (\n[doc-reg-dpr1] == 1) \{\ +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c +-. \*[doc-str-dpr] +-. \} +-. el \{\ +-. nr doc-reg-dpr \n[doc-arg-ptr] +-. +-. \" the `\%' prevents hyphenation on a dash (`-') +-. ie (\n[doc-reg-dpr1] == 2) \ +-. nop \%\*[doc-str-dpr]\&\c +-. el \{\ +-. \" punctuation character +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c +-. nop \)\*[doc-str-dpr]\f[]\s[0]\c +-. \} +-. +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ +-. \" last argument +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c +-. doc-print-and-reset +-. \} +-. el \{\ +-. nop \)\*[doc-space\n[doc-reg-dpr]]\c +-. doc-print-recursive +-. \}\} +-.. +-. +-. +-.\" NS doc-print-prefixes macro +-.\" NS print leading prefixes +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-. +-.de doc-print-prefixes +-. while (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. if !(\n[doc-type\n[doc-arg-ptr]] == 4) \ +-. break +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c +-. nop \)\*[doc-arg\n[doc-arg-ptr]]\f[]\s[0]\c +-. nr doc-arg-ptr +1 +-. \} +-.. +-. +-. +-.\" NS doc-generic-macro macro +-.\" NS this is the skeleton for most simple macros +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-. +-.de doc-generic-macro +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name \$0 +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .\$0 \*[doc-\$0-usage] ... (#\n[.c]) +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. if (\n[doc-type\n[doc-arg-ptr]] == 1) \{\ +-. tmc mdoc warning: Using a macro as first argument +-. tm1 " cancels effect of .\$0 (#\n[.c]) +-. +-. \" the right action here would be to reset the argument counters +-. \" and bail out -- unfortunately, a small number of manual pages +-. \" (less than 2% for FreeBSD which has been used for testing) +-. \" relied on the old behaviour (silently ignore this error), +-. \" so it is commented out +-. +-.\" doc-reset-args +-. \} +-.\" el \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-\$0-font]\c +-. doc-print-recursive +-.\" \} +-. \} +-. el \{\ +-. tm Usage: .\$0 \*[doc-\$0-usage] ... (#\n[.c]) +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS Ar user macro +-.\" NS command line `argument' macro: `.Ar [args ...]' +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variable: +-.\" NS doc-str-Ar-default +-.\" NS +-.\" NS width register `Ar' set in doc-common +-. +-.ds doc-str-Ar-default "file\ .\|.\|. +-. +-.de Ar +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Ar-font]\c +-. +-. if !\n[doc-arg-limit] \{\ +-. ds doc-macro-name Ar +-. doc-parse-args \$@ +-. +-. \" no argument +-. if !\n[.$] \ +-. nop \)\*[doc-str-Ar-default]\&\f[]\s[0] +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. doc-print-prefixes +-. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ +-. nop \)\*[doc-str-Ar-default]\&\f[]\s[0]\c +-. doc-print-and-reset +-. \} +-. el \{\ +-. if !(\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. \" replace previous argument (Ar) with default value +-. nr doc-arg-ptr -1 +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Ar-default] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. doc-parse-space-vector +-. \} +-. doc-print-recursive +-. \} +-.. +-. +-. +-.\" NS Ad user macro +-.\" NS Addresses +-.\" NS +-.\" NS width register `Ad' set in doc-common +-. +-.als Ad doc-generic-macro +-.ds doc-Ad-usage address +-. +-. +-.\" NS doc-indent-synopsis global register +-.\" NS indentation in synopsis +-. +-.nr doc-indent-synopsis 0 +-. +-. +-.\" NS doc-indent-synopsis-active global register (bool) +-.\" NS indentation in synopsis active +-. +-.nr doc-indent-synopsis-active 0 +-. +-. +-.\" NS Cd user macro +-.\" NS config declaration (for section 4 SYNOPSIS) +-.\" NS +-.\" NS this function causes a break; it uses the `Nm' font +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-indent-synopsis +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Cd' set in doc-common +-. +-.de Cd +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Cd +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Cd configuration_file_declaration ... (#\n[.c]) +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. ie \n[doc-in-synopsis-section] \{\ +-. ie "\*[doc-macro-name]"Cd" \{\ +-. br +-. if !\n[doc-indent-synopsis] \ +-. nr doc-indent-synopsis \n[doc-display-indent]u +-. if !\n[doc-indent-synopsis-active] \ +-. in +\n[doc-indent-synopsis]u +-. ti -\n[doc-indent-synopsis]u +-. nop \*[doc-Nm-font]\c +-. doc-print-recursive +-. if !\n[doc-indent-synopsis-active] \ +-. in -\n[doc-indent-synopsis]u +-. \} +-. el \{\ +-. nop \*[doc-Nm-font]\c +-. doc-print-recursive +-. \}\} +-. el \{\ +-. nop \*[doc-Nm-font]\c +-. doc-print-recursive +-. \}\} +-. el \{\ +-. tm Usage: .Cd configuration_file_declaration ... (#\n[.c]) +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS Cm user macro +-.\" NS interactive command modifier (flag) +-.\" NS +-.\" NS width register `Cm' set in doc-common +-. +-.als Cm doc-generic-macro +-.ds doc-Cm-usage interactive_command_modifier +-. +-. +-.\" NS Dv user macro +-.\" NS defined variable +-.\" NS +-.\" NS this function uses the `Er' font +-.\" NS +-.\" NS width register `Dv' set in doc-common +-. +-.als Dv doc-generic-macro +-.ds doc-Dv-usage defined_variable +-.als doc-Dv-font doc-Er-font +-. +-. +-.\" NS Em user macro +-.\" NS emphasis +-.\" NS +-.\" NS width register `Em' set in doc-common +-. +-.als Em doc-generic-macro +-.ds doc-Em-usage text +-. +-. +-.\" NS Er user macro +-.\" NS errno type +-.\" NS +-.\" NS width register `Er' set in doc-common +-. +-.als Er doc-generic-macro +-.ds doc-Er-usage text +-. +-. +-.\" NS Ev user macro +-.\" NS environment variable +-.\" NS +-.\" NS width register `Ev' set in doc-common +-. +-.als Ev doc-generic-macro +-.ds doc-Ev-usage text +-. +-. +-.\" NS doc-have-decl global register (bool) +-.\" NS subroutine test (in synopsis only) +-. +-.nr doc-have-decl 0 +-. +-. +-.\" NS doc-have-var global register (bool) +-.\" NS whether last type is a variable type +-. +-.nr doc-have-var 0 +-. +-. +-.\" NS doc-do-func-decl macro +-.\" NS do something special while in SYNOPSIS +-.\" NS +-.\" NS modifies: +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-have-decl +-.\" NS doc-have-var +-. +-.de doc-do-func-decl +-. if \n[doc-in-synopsis-section] \{\ +-. \" if a variable type was the last thing given, want vertical space +-. if \n[doc-have-var] \{\ +-. doc-paragraph +-. nr doc-have-var 0 +-. \} +-. \" if a subroutine was the last thing given, want vertical space +-. if \n[doc-have-func] \{\ +-. ie \n[doc-have-decl] \ +-. br +-. el \ +-. doc-paragraph +-. \} +-. nr doc-have-decl 1 +-. \} +-. +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-.. +-. +-. +-.\" NS Fd user macro +-.\" NS function declaration -- not callable +-.\" NS +-.\" NS this function causes a break +-.\" NS +-.\" NS width register `Fd' set in doc-common +-. +-.de Fd +-. ie ((\n[.$] >= 1) & (\n[doc-arg-limit] == 0)) \{\ +-. doc-do-func-decl +-. nop \*[doc-Fd-font]\$* +-. br +-. ft \n[doc-curr-font] +-. ps \n[doc-curr-size]u +-. \} +-. el \{\ +-. tm Usage: .Fd function_declaration -- Fd is not callable (#\n[.c]) +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS In user macro +-.\" NS #include statement in SYNOPSIS +-.\" NS if not in SYNOPSIS +-.\" NS +-.\" NS this function causes a break; it uses the `Fd' font +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-indent-synopsis +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `In' set in doc-common +-. +-.de In +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name In +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .In include_file ... (#\n[.c]) +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. doc-print-prefixes +-. ie ((\n[doc-arg-limit] >= \n[doc-arg-ptr]) & (\n[doc-type\n[doc-arg-ptr]] == 2)) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. ie \n[doc-in-synopsis-section] \{\ +-. ie "\*[doc-macro-name]"In" \{\ +-. doc-do-func-decl +-. nop \*[doc-Fd-font]#include <\*[doc-arg\n[doc-arg-ptr]]> +-. ft \n[doc-curr-font] +-. ps \n[doc-curr-size]u +-. br +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ +-. doc-print-recursive +-. el \ +-. doc-reset-args +-. \} +-. el \{\ +-. ds doc-arg\n[doc-arg-ptr] "<\*[doc-Pa-font]\*[doc-arg\n[doc-arg-ptr]] +-. as doc-arg\n[doc-arg-ptr] \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]> +-. doc-print-recursive +-. \}\} +-. el \{\ +-. ds doc-arg\n[doc-arg-ptr] "<\*[doc-Pa-font]\*[doc-arg\n[doc-arg-ptr]] +-. as doc-arg\n[doc-arg-ptr] \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]> +-. doc-print-recursive +-. \}\} +-. el \{\ +-. tm Usage: .In include_file ... (#\n[.c]) +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS Fr user macro +-.\" NS function return value +-.\" NS +-.\" NS this function uses the `Ar' font +-.\" NS +-.\" NS width register `Fr' set in doc-common +-. +-.als Fr doc-generic-macro +-.ds doc-Fr-usage function_return_value +-.als doc-Fr-font doc-Ar-font +-. +-. +-.\" NS Ic user macro +-.\" NS interactive command +-.\" NS +-.\" NS width register `Ic' set in doc-common +-. +-.als Ic doc-generic-macro +-.ds doc-Ic-usage interactive_command +-. +-. +-.\" NS Li user macro +-.\" NS literals +-.\" NS +-.\" NS width register `Li' set in doc-common +-. +-.als Li doc-generic-macro +-.ds doc-Li-usage argument +-. +-. +-.\" NS Ms user macro +-.\" NS math symbol +-.\" NS +-.\" NS this function uses the `Sy' font +-.\" NS +-.\" NS width register `Ms' set in doc-common +-. +-.als Ms doc-generic-macro +-.ds doc-Ms-usage math_symbol +-.als doc-Ms-font doc-Sy-font +-. +-. +-.\" NS doc-command-name global string +-.\" NS save first invocation of .Nm +-. +-.ds doc-command-name +-. +-. +-.\" NS Nm user macro +-.\" NS name of command or page topic +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-command-name +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-indent-synopsis +-.\" NS doc-indent-synopsis-active +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Nm' set in doc-common +-. +-.de Nm +-. if !\n[doc-arg-limit] \{\ +-. ds doc-macro-name Nm +-. ie \n[.$] \ +-. doc-parse-args \$@ +-. el \{\ +-. ie "\*[doc-command-name]"" \ +-. tm Usage: .Nm name ... (#\n[.c]) +-. el \ +-. doc-parse-args \*[doc-command-name] +-. \}\} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. doc-print-prefixes +-. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ +-. \" last argument +-. ie "\*[doc-command-name]"" \{\ +-. tm Usage: .Nm name ... (#\n[.c]) +-. doc-reset-args +-. \} +-. el \{\ +-. nop \*[doc-Nm-font]\*[doc-command-name]\f[]\s[0]\c +-. doc-print-and-reset +-. \}\} +-. el \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. ie !(\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. ie "\*[doc-command-name]"" \ +-. tm Usage: .Nm name ... (#\n[.c]) +-. el \{\ +-. \" replace previous argument (Nm) with default value +-. nr doc-arg-ptr -1 +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-Nm-font]\*[doc-command-name]\f[]\s[0] +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. doc-parse-space-vector +-. \}\} +-. el \{\ +-. \" handle `.Nm ...' in SYNOPSIS +-. if \n[doc-in-synopsis-section] \{\ +-. if "\*[doc-macro-name]"Nm" \{\ +-. br +-. if !\n[doc-indent-synopsis] \{\ +-. doc-get-width "\*[doc-arg\n[doc-arg-ptr]]" +-. nr doc-indent-synopsis ((\n[doc-width]u + 1u) * \n[doc-fixed-width]u) +-. \} +-. if !\n[doc-indent-synopsis-active] \{\ +-. in +\n[doc-indent-synopsis]u +-. nr doc-indent-synopsis-active 1 +-. \} +-. ti -\n[doc-indent-synopsis]u +-. \}\} +-. if "\*[doc-command-name]"" \ +-. ds doc-command-name "\*[doc-arg\n[doc-arg-ptr]] +-. +-. nop \*[doc-Nm-font]\c +-. \} +-. doc-print-recursive +-. \} +-.. +-. +-. +-.\" NS Pa user macro +-.\" NS pathname: `.Pa [arg ...]' +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Pa' set in doc-common +-. +-.de Pa +-. if !\n[doc-arg-limit] \{\ +-. ds doc-macro-name Pa +-. doc-parse-args \$@ +-. +-. \" default value +-. if !\n[.$] \ +-. nop \*[doc-Pa-font]~\f[]\s[0] +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. doc-print-prefixes +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Pa-font]\c +-. if !(\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. \" replace previous argument (Pa) with default value +-. nr doc-arg-ptr -1 +-. ds doc-arg\n[doc-arg-ptr] ~ +-. nr doc-type\n[doc-arg-ptr] 2 +-. ds doc-space\n[doc-arg-ptr] "\*[doc-space] +-. +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. doc-parse-space-vector +-. \} +-. doc-print-recursive +-. \} +-. el \{\ +-. nop \*[doc-Pa-font]~\f[]\s[0]\c +-. doc-print-and-reset +-. \} +-.. +-. +-. +-.\" NS Sy user macro +-.\" NS symbolics +-.\" NS +-.\" NS width register `Sy' set in doc-common +-. +-.als Sy doc-generic-macro +-.ds doc-Sy-usage symbolic_text +-. +-. +-.\" NS Me user macro +-.\" NS menu entries +-.\" NS +-.\" NS width register `Me' set in doc-common +-. +-.als Me doc-generic-macro +-.ds doc-Me-usage menu_entry +-. +-. +-.\" NS Tn user macro +-.\" NS trade name +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Tn' set in doc-common +-. +-.de Tn +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Tn +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Tn trade_name ... (#\n[.c]) +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \)\*[doc-Tn-font-size]\c +-. ie !\n[doc-is-reference] \{\ +-. nop \)\*[doc-Tn-font-shape]\c +-. doc-print-recursive +-. \} +-. el \ +-. doc-do-references +-. \} +-. el \{\ +-. tm Usage: .Tn trade_name ... (#\n[.c]) +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS Va user macro +-.\" NS variable name +-.\" NS +-.\" NS width register `Va' set in doc-common +-. +-.als Va doc-generic-macro +-.ds doc-Va-usage variable_name +-. +-. +-.\" NS No user macro +-.\" NS normal text macro (default text style if mess up) +-.\" NS +-.\" NS width register `No' set in doc-common +-. +-.als No doc-generic-macro +-.ds doc-No-usage normal_text +-. +-. +-.\" NS doc-quote-left global string +-.\" NS left quotation character for `doc-enclose-string' and +-.\" NS `doc-enclose-open' +-. +-.ds doc-quote-left +-. +-. +-.\" NS doc-quote-right global string +-.\" NS right quotation character for `doc-enclose-string' and +-.\" NS `doc-enclose-close' +-. +-.ds doc-quote-right +-. +-. +-.\" NS Op user macro +-.\" NS option expression (i.e., enclose string in square brackets) +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Op' set in doc-common +-. +-.de Op +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Op +-. +-. ds doc-quote-left "\*[doc-left-bracket] +-. ds doc-quote-right "\*[doc-right-bracket] +-. +-. doc-enclose-string \$@ +-.. +-. +-. +-.\" NS Aq user macro +-.\" NS enclose string in angle brackets +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Aq' set in doc-common +-. +-.de Aq +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Aq +-. +-. ie "\*[doc-macro-name]"An" \{\ +-. ds doc-quote-left < +-. ds doc-quote-right > +-. \} +-. el \{\ +-. ds doc-quote-left \[la] +-. ds doc-quote-right \[ra] +-. \} +-. +-. doc-enclose-string \$@ +-.. +-. +-. +-.\" NS Bq user macro +-.\" NS enclose string in square brackets +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Bq' set in doc-common +-. +-.de Bq +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Bq +-. +-. ds doc-quote-left "\*[doc-left-bracket] +-. ds doc-quote-right "\*[doc-right-bracket] +-. +-. doc-enclose-string \$@ +-.. +-. +-. +-.\" NS Brq user macro +-.\" NS enclose string in braces +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Brq' set in doc-common +-. +-.de Brq +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Brq +-. +-. ds doc-quote-left { +-. ds doc-quote-right } +-. +-. doc-enclose-string \$@ +-.. +-. +-. +-.\" NS Dq user macro +-.\" NS enclose string in double quotes +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Dq' set in doc-common +-. +-.de Dq +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Dq +-. +-. ds doc-quote-left "\*[Lq] +-. ds doc-quote-right "\*[Rq] +-. +-. doc-enclose-string \$@ +-.. +-. +-. +-.\" NS Eq user macro +-.\" NS enclose string in user-defined quotes (args 1 and 2) +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Eq' set in doc-common +-. +-.de Eq +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Eq +-. +-. ds doc-quote-left "\$1 +-. ds doc-quote-right "\$2 +-. +-. shift 2 +-. doc-enclose-string \$@ +-.. +-. +-. +-.\" NS Pq user macro +-.\" NS enclose string in parentheses +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Pq' set in doc-common +-. +-.de Pq +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Pq +-. +-. ds doc-quote-left "\*[doc-left-parenthesis] +-. ds doc-quote-right "\*[doc-right-parenthesis] +-. +-. doc-enclose-string \$@ +-.. +-. +-. +-.\" NS Ql user macro +-.\" NS quoted literal +-.\" +-.\" is in file doc-[dit|n]roff +-. +-. +-.\" NS Qq user macro +-.\" NS enclose string in straight double quotes +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Qq' set in doc-common +-. +-.de Qq +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Qq +-. +-. ds doc-quote-left "\*[q] +-. ds doc-quote-right "\*[q] +-. +-. doc-enclose-string \$@ +-.. +-. +-. +-.\" NS Sq user macro +-.\" NS enclose string in single quotes +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Sq' set in doc-common +-. +-.de Sq +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Sq +-. +-. ds doc-quote-left "\*[doc-left-singlequote] +-. ds doc-quote-right "\*[doc-right-singlequote] +-. +-. doc-enclose-string \$@ +-.. +-. +-. +-.\" NS Es user macro +-.\" NS set up arguments (i.e., the left and right quotation character as +-.\" NS first and second argument) for .En call +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-. +-.de Es +-. if !\n[doc-arg-limit] \{\ +-. ie (\n[.$] > 2) \{\ +-. ds doc-macro-name Es +-. doc-parse-args \$@ +-. \} +-. el \{\ +-. ds doc-quote-left "\$1 +-. ds doc-quote-right "\$2 +-. \}\} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. ds doc-quote-left "\*[doc-arg\n[doc-arg-ptr]] +-. nr doc-arg-ptr +1 +-. ds doc-quote-right "\*[doc-arg\n[doc-arg-ptr]] +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ +-. doc-do-\n[doc-type\n[doc-arg-ptr]] +-. el \ +-. doc-print-and-reset +-.. +-. +-. +-.\" NS doc-have-slot global register (bool) +-.\" NS set if `doc-enclose-string' has created a slot for closing +-.\" NS delimiter +-. +-.nr doc-have-slot 0 +-. +-. +-.\" NS doc-enclose-string macro +-.\" NS enclose string with given args (e.g. [ and ]) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-argXXX +-.\" NS doc-have-slot +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-des +-.\" NS doc-reg-des1 +-.\" NS doc-reg-des2 +-.\" NS +-.\" NS requires: +-.\" NS doc-quote-left +-.\" NS doc-quote-right +-. +-.de doc-enclose-string +-. if \n[doc-in-synopsis-section] \ +-. doc-set-hard-space +-. +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \ +-. doc-parse-args \$@ +-. el \{\ +-. nop \)\*[doc-quote-left]\*[doc-quote-right] +-. \}\} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. nr doc-arg-ptr +1 +-. doc-print-prefixes +-. \" the final `\)' prevents hyphenation in case the next character is `\%' +-. nop \)\*[doc-quote-left]\)\c +-. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ +-. \" last argument +-. nop \)\*[doc-quote-right]\)\c +-. doc-print-and-reset +-. \} +-. el \{\ +-. \" test whether last arguments are of type closing punctuation +-. \" resp. suffix +-. ie (\n[doc-type\n[doc-arg-limit]] == 3) \{\ +-. nr doc-reg-des (\n[doc-arg-limit] - 1) +-. while (\n[doc-type\n[doc-reg-des]] == 3) \ +-. nr doc-reg-des -1 +-. +-. \" prepend closing delimiter +-. nr doc-reg-des +1 +-. ds doc-arg\n[doc-reg-des] "\*[doc-quote-right]\)\*[doc-arg\n[doc-reg-des]] +-. \} +-. el \{\ +-. \" test whether last arguments are macros which continue the line +-. \" logically +-. nr doc-reg-des \n[doc-arg-limit] +-. while (\n[doc-reg-des] >= \n[doc-arg-ptr]) \{\ +-. if !\A\*[doc-arg\n[doc-reg-des]] \ +-. break +-. if !d doc-after-\*[doc-arg\n[doc-reg-des]] \ +-. break +-. nr doc-reg-des -1 +-. \} +-. +-. \" if there are no trailing macros to be skipped, append argument +-. ie (\n[doc-reg-des] == \n[doc-arg-limit]) \ +-. doc-append-arg "\)\*[doc-quote-right]\)" 3 +-. el \{\ +-. \" if a previous call to `doc-enclose-string' has already created +-. \" a slot, prepend argument +-. ie \n[doc-have-slot] \ +-. ds doc-arg\n[doc-reg-des] "\*[doc-quote-right]\)\*[doc-arg\n[doc-reg-des]] +-. el \{\ +-. \" we have to shift all arguments to the right +-. nr doc-reg-des +1 +-. nr doc-reg-des1 \n[doc-arg-limit] +-. nr doc-reg-des2 (\n[doc-arg-limit] + 1) +-. while (\n[doc-reg-des1] >= \n[doc-reg-des]) \{\ +-. rn doc-arg\n[doc-reg-des1] doc-arg\n[doc-reg-des2] +-. rnn doc-type\n[doc-reg-des1] doc-type\n[doc-reg-des2] +-. rn doc-space\n[doc-reg-des1] doc-space\n[doc-reg-des2] +-. nr doc-reg-des1 -1 +-. nr doc-reg-des2 -1 +-. \} +-. nr doc-arg-limit +1 +-. +-. \" finally, insert closing delimiter into the freed slot and +-. \" recompute spacing vector +-. ds doc-arg\n[doc-reg-des] "\)\*[doc-quote-right]\) +-. nr doc-type\n[doc-reg-des] 3 +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-reg-des] + 1) +-. nr doc-arg-limit (\n[doc-reg-des] - 1) +-. doc-parse-space-vector +-. nr doc-have-slot 1 +-. \}\}\} +-. +-. doc-do-\n[doc-type\n[doc-arg-ptr]] +-. \} +-. +-. if \n[doc-in-synopsis-section] \ +-. doc-set-soft-space +-.. +-. +-. +-.\" NS En user macro +-.\" NS enclose arguments with quotation characters set up with `.Es' +-. +-.als En doc-enclose-string +-. +-. +-.\" NS Ao user macro +-.\" NS angle open +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Ao' set in doc-common +-. +-.de Ao +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Ao +-. +-. ie "\*[doc-macro-name]"An" \ +-. ds doc-quote-left < +-. el \ +-. ds doc-quote-left \[la] +-. +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Ac user macro +-.\" NS angle close +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Ac' set in doc-common +-. +-.de Ac +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Ac +-. +-. ie "\*[doc-macro-name]"An" \ +-. ds doc-quote-right > +-. el \ +-. ds doc-quote-right \[ra] +-. +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS Bo user macro +-.\" NS bracket open +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Bo' set in doc-common +-. +-.de Bo +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Bo +-. +-. ds doc-quote-left "\*[doc-left-bracket] +-. +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Bc user macro +-.\" NS bracket close +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Bc' set in doc-common +-. +-.de Bc +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Bc +-. +-. ds doc-quote-right "\*[doc-right-bracket] +-. +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS Bro user macro +-.\" NS brace open +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Bro' set in doc-common +-. +-.de Bro +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Bo +-. +-. ds doc-quote-left { +-. +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Brc user macro +-.\" NS brace close +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Brc' set in doc-common +-. +-.de Brc +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Bc +-. +-. ds doc-quote-right } +-. +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS Do user macro +-.\" NS double quote open +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Do' set in doc-common +-. +-.de Do +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Do +-. +-. ds doc-quote-left "\*[Lq] +-. +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Dc user macro +-.\" NS double quote close +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Dc' set in doc-common +-. +-.de Dc +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Dc +-. +-. ds doc-quote-right "\*[Rq] +-. +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS Eo user macro +-.\" NS enclose open (using first argument as beginning of enclosure) +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Eo' set in doc-common +-. +-.de Eo +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Eo +-. +-. ds doc-quote-left "\$1 +-. +-. shift +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Ec user macro +-.\" NS enclose close (using first argument as end of enclosure) +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Ec' set in doc-common +-. +-.de Ec +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Ec +-. +-. ds doc-quote-right "\$1 +-. +-. shift +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS Oo user macro +-.\" NS option open +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Oo' set in doc-common +-. +-.de Oo +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Oo +-. +-. ds doc-quote-left [ +-. +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Oc user macro +-.\" NS option close +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Oc' set in doc-common +-. +-.de Oc +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Oc +-. +-. ds doc-quote-right ] +-. +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS Po user macro +-.\" NS parenthesis open +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Po' set in doc-common +-. +-.de Po +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Po +-. +-. ds doc-quote-left "\*[doc-left-parenthesis] +-. +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Pc user macro +-.\" NS parenthesis close +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Pc' set in doc-common +-. +-.de Pc +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Pc +-. +-. ds doc-quote-right "\*[doc-right-parenthesis] +-. +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS Qo user macro +-.\" NS straight double quote open +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Qo' set in doc-common +-. +-.de Qo +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Qo +-. +-. ds doc-quote-left "\*[q] +-. +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Qc user macro +-.\" NS straight double quote close +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Qc' set in doc-common +-. +-.de Qc +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Qc +-. +-. ds doc-quote-right "\*[q] +-. +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS So user macro +-.\" NS single quote open +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `So' set in doc-common +-. +-.de So +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name So +-. +-. ds doc-quote-left "\*[doc-left-singlequote] +-. +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Sc user macro +-.\" NS single quote close +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Sc' set in doc-common +-. +-.de Sc +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Sc +-. +-. ds doc-quote-right "\*[doc-right-singlequote] +-. +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS Xo user macro +-.\" NS extend open +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Xo' set in doc-common +-. +-.de Xo +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Xo +-. +-. ds doc-quote-left +-. +-. doc-enclose-open \$@ +-.. +-. +-. +-.\" NS Xc user macro +-.\" NS extend close +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS doc-quote-right +-.\" NS +-.\" NS width register `Xc' set in doc-common +-. +-.de Xc +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Xc +-. +-. ds doc-quote-right +-. +-. doc-enclose-close \$@ +-.. +-. +-. +-.\" NS doc-nesting-level global register +-.\" NS used by `doc-enclose-open' and `doc-enclose-close' +-. +-.nr doc-nesting-level 0 +-. +-. +-.\" NS doc-in-list global register (bool) +-.\" NS whether we are in (logical) .It +-. +-.nr doc-in-list 0 +-. +-. +-.\" NS doc-enclose-open macro +-.\" NS enclose string open +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-nesting-level +-. +-.de doc-enclose-open +-. if !\n[doc-arg-limit] \ +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. doc-print-prefixes +-. nr doc-arg-ptr -1 +-. +-. nop \)\*[doc-quote-left]\)\c +-. +-. \" start enclosure box +-. box doc-enclosure-box\n[doc-nesting-level] +-. ev doc-enclosure-env\n[doc-nesting-level] +-. evc 0 +-. in 0 +-. nf +-. \" we insert something to make .chop always work +-. nop \&\c +-. +-. \" increase nesting level *after* parsing of arguments +-. nr doc-nesting-level +1 +-. +-. if \n[doc-arg-limit] \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ +-. doc-print-recursive +-. el \ +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS doc-enclose-close macro +-.\" NS enclose string close +-.\" NS +-.\" NS modifies: +-.\" NS doc-nesting-level +-. +-.de doc-enclose-close +-. nr doc-nesting-level -1 +-. +-. \" finish enclosure box +-. br +-. ev +-. box +-. chop doc-enclosure-box\n[doc-nesting-level] +-. unformat doc-enclosure-box\n[doc-nesting-level] +-. +-. nh +-. nop \*[doc-enclosure-box\n[doc-nesting-level]]\c +-. nop \)\*[doc-quote-right]\)\c +-. +-. if !\n[doc-arg-limit] \{\ +-. doc-parse-args \$@ +-. +-. if !\n[.$] \ +-. doc-print-and-reset +-. \} +-. +-. if \n[doc-arg-limit] \{\ +-. ie (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nop \)\*[doc-space\n[doc-arg-ptr]]\c +-. nr doc-arg-ptr +1 +-. doc-print-recursive +-. \} +-. el \ +-. doc-print-and-reset +-. \} +-. +-. \" shall we finish .It macro? +-. if !"\*[doc-macro-name]"It" \ +-. if \n[doc-in-list] \ +-. if !\n[doc-nesting-level] \ +-. doc-\*[doc-list-type-stack\n[doc-list-depth]] +-.. +-. +-. +-.\" NS Pf user macro +-.\" NS prefix: `.Pf prefix arg ...' +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-macro-name +-.\" NS doc-quote-left +-.\" NS +-.\" NS width register `Pf' set in doc-common +-. +-.de Pf +-. if !\n[doc-arg-limit] \ +-. ds doc-macro-name Pf +-. +-. ie \n[doc-arg-limit] \{\ +-. ie ((\n[doc-arg-limit] - \n[doc-arg-ptr]) > 1) \{\ +-. nr doc-arg-ptr +1 +-. nop \)\*[doc-arg\n[doc-arg-ptr]]\c +-. \} +-. el \ +-. tm mdoc warning: .Pf: trailing prefix (#\n[.c]) +-. \} +-. el \{\ +-. nop \)\$1\)\c +-. shift +-. ie \n[.$] \ +-. doc-parse-args \$@ +-. el \{\ +-. tm mdoc warning: .Pf: missing arguments (#\n[.c]) +-. nop \) +-. \}\} +-. +-. if \n[doc-arg-limit] \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \ +-. doc-print-and-reset +-. el \ +-. doc-do-\n[doc-type\n[doc-arg-ptr]] +-. \} +-.. +-. +-. +-.\" NS Ns user macro +-.\" NS remove space (space removal done by `doc-parse-args') +-.\" NS +-.\" NS modifies: +-.\" NS doc-argXXX +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Ns' set in doc-common +-. +-.de Ns +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Ns +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Ns must be called with arguments (#\n[.c]) +-. \} +-. +-. if \n[doc-arg-limit] \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ +-. doc-print-recursive +-. el \ +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS Ap user macro +-.\" NS append an apostrophe +-.\" NS +-.\" NS width register `Ap' set in doc-common +-. +-.de Ap +-. ie !\n[doc-arg-limit] \ +-. tm Usage: `Ap' cannot be first macro on a line (no `.Ap') (#\n[.c]) +-. el \{\ +-. nop \)'\)\c +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ +-. doc-print-recursive +-. el \ +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS doc-space global string +-.\" NS current inter-argument space +-. +-.ds doc-space "\*[doc-soft-space] +-. +-. +-.\" NS doc-soft-space constant string +-.\" NS soft (stretchable) space (defined in doc-common) +-. +-. +-.\" NS doc-hard-space constant string +-.\" NS hard (unpaddable) space (defined in doc-common) +-. +-. +-.\" NS doc-set-hard-space macro +-.\" NS set current space string to hard (unpaddable) space. +-.\" NS +-.\" NS modifies: +-.\" NS doc-saved-space +-.\" NS doc-space +-. +-.de doc-set-hard-space +-. ie "\*[doc-space]"" \ +-. ds doc-saved-space "\*[doc-hard-space] +-. el \ +-. ds doc-space "\*[doc-hard-space] +-.. +-. +-. +-.\" NS doc-set-soft-space macro +-.\" NS set current space string to soft space +-.\" NS +-.\" NS modifies: +-.\" NS doc-saved-space +-.\" NS doc-space +-. +-.de doc-set-soft-space +-. ie "\*[doc-space]"" \ +-. ds doc-saved-space "\*[doc-soft-space] +-. el \ +-. ds doc-space "\*[doc-soft-space] +-.. +-. +-. +-.\" NS doc-space-mode global register (bool) +-.\" NS default is one (space mode on) +-. +-.nr doc-space-mode 1 +-. +-. +-.\" NS doc-saved-space global string +-.\" NS saved value of `doc-space' +-. +-.ds doc-saved-space "\*[doc-space] +-. +-. +-.\" NS doc-have-space global register (bool) +-.\" NS set if last command was horizontal space +-. +-.nr doc-have-space 0 +-. +-. +-.\" NS Sm user macro +-.\" NS space mode (`.Sm'/`.Sm on'/`.Sm off') +-.\" NS +-.\" NS without argument, toggle space mode +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-limit +-.\" NS doc-arg-ptr +-.\" NS doc-argXXX +-.\" NS doc-macro-name +-.\" NS doc-num-args +-.\" NS doc-saved-space +-.\" NS doc-space +-.\" NS doc-space-mode +-.\" NS doc-spaceXXX +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-Sm +-.\" NS +-.\" NS width register `Sm' set in doc-common +-. +-.de Sm +-. ie \n[doc-have-space] \ +-. nr doc-reg-Sm 0 +-. el \ +-. nr doc-reg-Sm 1 +-. +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Sm +-. doc-parse-args \$@ +-. \} +-. el \{\ +-. ie \n[doc-space-mode] \{\ +-. ds doc-saved-space "\*[doc-space] +-. ds doc-space +-. nr doc-space-mode 0 +-. \} +-. el \{\ +-. ds doc-space "\*[doc-saved-space] +-. nr doc-space-mode 1 +-. +-. \" finish line only if it is interrupted and `doc-have-space' +-. \" isn't set +-. if \n[doc-reg-Sm] \ +-. if \n[.int] \ +-. nop \) +-. \} +-. \}\} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. +-. \" avoid a warning message in case `Sm' is the last parameter +-. if !d doc-arg\n[doc-arg-ptr] \ +-. ds doc-arg\n[doc-arg-ptr] +-. +-. ie "\*[doc-arg\n[doc-arg-ptr]]"on" \{\ +-. ds doc-space "\*[doc-saved-space] +-. nr doc-space-mode 1 +-. \} +-. el \{\ +-. ie "\*[doc-arg\n[doc-arg-ptr]]"off" \{\ +-. ds doc-saved-space "\*[doc-space] +-. ds doc-space +-. nr doc-space-mode 0 +-. \} +-. el \{\ +-. \" no argument for Sm +-. nr doc-arg-ptr -1 +-. ie \n[doc-space-mode] \{\ +-. ds doc-saved-space "\*[doc-space] +-. ds doc-space +-. nr doc-space-mode 0 +-. \} +-. el \{\ +-. ds doc-space "\*[doc-saved-space] +-. nr doc-space-mode 1 +-. \} +-. \}\} +-. +-. ie \n[doc-space-mode] \{\ +-. \" recompute space vector for remaining arguments +-. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) +-. nr doc-arg-limit \n[doc-arg-ptr] +-. if \n[doc-num-args] \ +-. doc-parse-space-vector +-. +-. \" finish line only if it is interrupted and `doc-have-space' +-. \" isn't set +-. if \n[doc-reg-Sm] \ +-. if \n[.int] \ +-. nop \) +-. \} +-. el \{\ +-. \" reset remaining space vector elements +-. nr doc-reg-Sm (\n[doc-arg-ptr] + 1) +-. while (\n[doc-reg-Sm] <= \n[doc-arg-limit]) \{\ +-. ds doc-space\n[doc-reg-Sm] +-. nr doc-reg-Sm +1 +-. \" the body of a `while' request must end with the fitting `\}'! +-. \} +-. \} +-. +-. \" do we have parameters to print? +-. ie (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. \" skip `Sm' argument +-. nr doc-arg-ptr +1 +-. doc-print-recursive +-. \} +-. el \ +-. doc-reset-args +-.. +-. +-. +-.\" NS doc-arg-type immediate register +-.\" NS argument type (macro=1, string=2, punctuation suffix=3, +-.\" NS punctuation prefix=4) +-. +-.nr doc-arg-type 0 +-. +-. +-.\" NS doc-get-arg-type macro +-.\" NS get argument type +-.\" NS +-.\" NS this macro expects the width of the argument in `doc-width' +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-type +-. +-.de doc-get-arg-type +-. nr doc-arg-type 2 +-. +-. if ((\n[doc-width] < 4) & \A\$1) \{\ +-. ie (\n[doc-width] == 1) \{\ +-. if r doc-punct\$1 \ +-. nr doc-arg-type \n[doc-punct\$1] +-. \} +-. el \ +-. if r \$1 \ +-. if d \$1 \ +-. nr doc-arg-type 1 +-. \} +-.. +-. +-. +-.\" NS doc-get-arg-type* macro +-.\" NS similar to as `doc-get-arg-type' but uses doc-argXXX strings +-.\" NS +-.\" NS this macro sets the `doc-width' register using the `length' request +-.\" NS to get the number of characters in a string literally +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-type +-.\" NS doc-width +-. +-.de doc-get-arg-type* +-. nr doc-arg-type 2 +-. length doc-width "\*[doc-arg\$1] +-. +-. if ((\n[doc-width] < 4) & \A\*[doc-arg\$1]) \{\ +-. ie (\n[doc-width] == 1) \{\ +-. if r doc-punct\*[doc-arg\$1] \ +-. nr doc-arg-type \n[doc-punct\*[doc-arg\$1]] +-. \} +-. el \ +-. if r \*[doc-arg\$1] \ +-. if d \*[doc-arg\$1] \ +-. nr doc-arg-type 1 +-. \} +-.. +-. +-. +-.\" NS doc-set-spacing-1 macro +-.\" NS set spacing for macros +-.\" NS +-.\" NS modifies: +-.\" NS doc-spaceXXX +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dssfm +-.\" NS doc-reg-dssfm1 +-. +-.de doc-set-spacing-1 +-. nr doc-reg-dssfm1 \n[\*[doc-arg\n[doc-arg-limit]]] +-. +-. \" closing macros like .Ac, Bc., etc. have value 3 (remove space before +-. \" argument) +-. ie (\n[doc-reg-dssfm1] == 3) \{\ +-. if \n[doc-arg-limit] \{\ +-. nr doc-reg-dssfm (\n[doc-arg-limit] - 1) +-. ds doc-space\n[doc-reg-dssfm] +-. \} +-. ds doc-space\n[doc-arg-limit] "\*[doc-space] +-. \} +-. el \{\ +-. \" macros like .Ap and .Ns have value 2 (remove space before and after +-. \" argument) +-. ie (\n[doc-reg-dssfm1] == 2) \{\ +-. if \n[doc-arg-limit] \{\ +-. nr doc-reg-dssfm (\n[doc-arg-limit] - 1) +-. ds doc-space\n[doc-reg-dssfm] +-. \} +-. ds doc-space\n[doc-arg-limit] +-. \} +-. el \ +-. ds doc-space\n[doc-arg-limit] +-. \} +-.. +-. +-. +-.\" NS doc-set-spacing-2 macro +-.\" NS set spacing for strings +-.\" NS +-.\" NS modifies: +-.\" NS doc-spaceXXX +-. +-.de doc-set-spacing-2 +-. ds doc-space\n[doc-arg-limit] "\*[doc-space] +-.. +-. +-. +-.\" NS doc-set-spacing-3 macro +-.\" NS set spacing for punctuation suffixes +-.\" NS +-.\" NS modifies: +-.\" NS doc-spaceXXX +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dssfps +-. +-.de doc-set-spacing-3 +-. if \n[doc-arg-limit] \{\ +-. nr doc-reg-dssfps (\n[doc-arg-limit] - 1) +-. ds doc-space\n[doc-reg-dssfps] +-. \} +-. +-. ds doc-space\n[doc-arg-limit] "\*[doc-space] +-.. +-. +-. +-.\" NS doc-set-spacing-4 macro +-.\" NS set spacing for punctuation prefixes +-.\" NS +-.\" NS modifies: +-.\" NS doc-spaceXXX +-. +-.de doc-set-spacing-4 +-. ds doc-space\n[doc-arg-limit] +-.. +-. +-. +-.\" type switches (on current argument doc-arg-ptr) +-. +-. +-.\" NS doc-do-1 macro +-.\" NS call request if macro +-. +-.de doc-do-1 +-. \*[doc-arg\n[doc-arg-ptr]] +-.. +-. +-. +-.\" NS doc-do-2 macro +-.\" NS call .doc-print-recursive if string +-. +-.als doc-do-2 doc-print-recursive +-. +-. +-.\" NS doc-do-3 macro +-.\" NS call .doc-print-recursive if punctuation suffix +-. +-.als doc-do-3 doc-print-recursive +-. +-. +-.\" NS doc-do-4 macro +-.\" NS call .doc-print-recursive if punctuation prefix +-. +-.als doc-do-4 doc-print-recursive +-. +-. +-.\" NS doc-fontmode-depth global register +-.\" NS font mode level +-. +-.nr doc-fontmode-depth 0 +-. +-. +-.\" NS doc-fontmode-font-stackXXX global register +-.\" NS stack of saved current font values from `Bf' macro +-.\" NS +-.\" NS limit: +-.\" NS doc-fontmode-depth +-. +-.nr doc-fontmode-font-stack0 0 +-. +-. +-.\" NS doc-fontmode-size-stackXXX global register +-.\" NS stack of saved current size values from `Bf' macro +-.\" NS +-.\" NS limit: +-.\" NS doc-fontmode-depth +-. +-.nr doc-fontmode-size-stack0 0 +-. +-. +-.\" NS Bf user macro +-.\" NS begin font mode (will be begin-mode/end-mode in groff & TeX) +-.\" NS +-.\" NS modifies: +-.\" NS doc-fontmode-depth +-.\" NS doc-fontmode-font-stackXXX +-.\" NS doc-fontmode-size-stackXXX +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Bf' set in doc-common +-. +-.de Bf +-. ds doc-macro-name Bf +-. +-. ie \n[.$] \{\ +-. nr doc-fontmode-depth +1 +-. +-. \" save current font and size +-. nr doc-fontmode-font-stack\n[doc-fontmode-depth] \n[.f] +-. nr doc-fontmode-size-stack\n[doc-fontmode-depth] \n[.ps] +-. +-. ie "\$1"Em" \ +-. nop \*[doc-Em-font]\c +-. el \{ .ie "\$1"Li" \ +-. nop \*[doc-Li-font]\c +-. el \{ .ie "\$1"Sy" \ +-. nop \*[doc-Sy-font]\c +-. el \{ .ie "\$1"-emphasis" \ +-. nop \*[doc-Em-font]\c +-. el \{ .ie "\$1"-literal" \ +-. nop \*[doc-Li-font]\c +-. el \{ .ie "\$1"-symbolic" \ +-. nop \*[doc-Sy-font]\c +-. el \{\ +-. tmc mdoc warning: Unknown keyword `\$1' in .Bf macro +-. tm1 " (#\n[.c]) +-. \}\}\}\}\}\}\} +-. el \ +-. tm Usage: .Bf [Em | -emphasis | Li | -literal | Sy | -symbolic] (#\n[.c]) +-.. +-. +-. +-.\" NS Ef user macro +-.\" NS end font mode +-.\" NS +-.\" NS modifies: +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Ef' set in doc-common +-. +-.de Ef +-. ds doc-macro-name Ef +-. +-. ie \n[doc-fontmode-depth] \{\ +-. \" restore saved font and size +-. nop \)\f[\n[doc-fontmode-font-stack\n[doc-fontmode-depth]]]\c +-. nop \)\s[\n[doc-fontmode-size-stack\n[doc-fontmode-depth]]u]\c +-. +-. nr doc-fontmode-font-stack\n[doc-fontmode-depth] 0 +-. nr doc-curr-font \n[.f] +-. nr doc-fontmode-size-stack\n[doc-fontmode-depth] 0 +-. nr doc-curr-size \n[.ps] +-. nr doc-fontmode-depth -1 +-. \} +-. el \ +-. tm mdoc warning: Extraneous .Ef (#\n[.c]) +-.. +-. +-. +-.\" NS doc-keep-type global register +-.\" NS current keep type; 1 is `-words', 2 is `-lines', 3 is unknown +-. +-.nr doc-keep-type 0 +-. +-. +-.\" NS Bk user macro +-.\" NS begin keep +-.\" NS +-.\" NS modifies: +-.\" NS doc-keep-type +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Bk' set in doc-common +-. +-.de Bk +-. ds doc-macro-name Bk +-. +-. if \n[doc-keep-type] \ +-. tm .Bk: nesting keeps not implemented yet. (#\n[.c]) +-. +-. ie "\$1"-lines" \{\ +-. nr doc-keep-type 2 +-. tm .Bk -lines: Not implemented yet. (#\n[.c]) +-. \} +-. el \{ .ie "\$1"-words" \{\ +-. nr doc-keep-type 1 +-. doc-set-hard-space +-. \} +-. el \{ .ie "\$1"" \{\ +-. \" default +-. nr doc-keep-type 1 +-. doc-set-hard-space +-. \} +-. el \{\ +-. tm mdoc warning: Unknown keyword `\$1' in .Bk macro (#\n[.c]) +-. nr doc-keep-type 3 +-. \}\}\} +-. +-\#. nr doc-nesting-level +1 +-.. +-. +-. +-.\" NS Ek user macro +-.\" NS end keep +-.\" NS +-.\" NS modifies: +-.\" NS doc-keep-type +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Ek' set in doc-common +-. +-.de Ek +-. ds doc-macro-name Ek +-. +-\#. nr doc-nesting-level -1 +-. +-. ie \n[.$] \ +-. tm Usage: .Ek (does not take arguments) (#\n[.c]) +-. el \{\ +-. if !\n[doc-keep-type] \ +-. tm mdoc warning: .Ek found without .Bk before (#\n[.c]) +-. +-. ie (\n[doc-keep-type] == 1) \ +-. doc-set-soft-space +-. el \{ .if (\n[doc-keep-type] == 2) \ +-. tm .Bk -lines: Not implemented yet. (#\n[.c]) +-. \}\} +-. +-. nr doc-keep-type 0 +-. +-\#. if !"\*[doc-out-string]"" \ +-\#. doc-print-out-string +-.. +-. +-. +-.\" NS doc-display-depth global register +-.\" NS display level +-. +-.nr doc-display-depth 0 +-. +-. +-.\" NS doc-is-compact global register (bool) +-.\" NS set if the `compact' keyword is given +-. +-.nr doc-is-compact 0 +-. +-. +-.\" NS doc-display-type-stackXXX global string +-.\" NS the display type stack +-.\" NS +-.\" NS limit: +-.\" NS doc-display-depth +-. +-.ds doc-display-type-stack0 +-. +-. +-.\" NS doc-display-indent-stackXXX global register +-.\" NS stack of display indentation values +-.\" NS +-.\" NS limit: +-.\" NS doc-display-depth +-. +-.nr doc-display-indent-stack0 0 +-. +-. +-.\" NS doc-display-ad-stackXXX global register +-.\" NS stack of saved adjustment modes +-.\" NS +-.\" NS limit: +-.\" NS doc-display-depth +-. +-.nr doc-display-ad-stack0 0 +-. +-. +-.\" NS doc-display-fi-stackXXX global register +-.\" NS stack of saved fill modes +-.\" NS +-.\" NS limit: +-.\" NS doc-display-depth +-. +-.nr doc-display-fi-stack0 0 +-. +-. +-.\" NS doc-display-ft-stackXXX global register +-.\" NS stack of saved fonts +-.\" NS +-.\" NS limit: +-.\" NS doc-display-depth +-. +-.nr doc-display-ft-stack0 0 +-. +-. +-.\" NS doc-display-ps-stackXXX global register +-.\" NS stack of saved font sizes +-.\" NS +-.\" NS limit: +-.\" NS doc-display-depth +-. +-.nr doc-display-ps-stack0 0 +-. +-. +-.\" NS Bd user macro +-.\" NS begin display +-.\" NS +-.\" NS width register `Bd' set in doc-common +-.\" NS +-.\" NS modifies: +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-display-depth +-.\" NS doc-display-ad-stackXXX +-.\" NS doc-display-fi-stackXXX +-.\" NS doc-display-ft-stackXXX +-.\" NS doc-display-ps-stackXXX +-.\" NS doc-display-file +-.\" NS doc-display-indent-stackXXX +-.\" NS doc-display-type-stackXXX +-.\" NS doc-is-compact +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-Bd +-. +-.de Bd +-. ds doc-macro-name Bd +-. +-. if !\n[.$] \{\ +-. tm1 "Usage: .Bd {-literal | -filled | -ragged | -centered | -unfilled} +-. tm1 " [-offset [string]] [-compact] [-file name] (#\n[.c]) +-. return +-. \} +-. +-. nr doc-is-compact 0 +-. ds doc-display-file +-. nr doc-reg-Bd 1 +-. nr doc-display-depth +1 +-. +-. \" save current adjustment and fill modes +-. nr doc-display-ad-stack\n[doc-display-depth] \n[.j] +-. nr doc-display-fi-stack\n[doc-display-depth] \n[.u] +-. +-. ie "\$1"-literal" \{\ +-. ds doc-display-type-stack\n[doc-display-depth] literal +-. nr doc-display-ft-stack\n[doc-display-depth] \n[.f] +-. nr doc-display-ps-stack\n[doc-display-depth] \n[.ps] +-. +-. ie t \ +-. ta T 9n +-. el \ +-. ta T 8n +-. nf +-. \} +-. el \{ .ie "\$1"-filled" \{\ +-. ds doc-display-type-stack\n[doc-display-depth] filled +-. ad b +-. fi +-. \} +-. el \{ .ie "\$1"-ragged" \{\ +-. ds doc-display-type-stack\n[doc-display-depth] ragged +-. na +-. fi +-. \} +-. el \{ .ie "\$1"-centered" \{\ +-. ds doc-display-type-stack\n[doc-display-depth] centered +-. ad c +-. fi +-. \} +-. el \{ .ie "\$1"-unfilled" \{\ +-. ds doc-display-type-stack\n[doc-display-depth] unfilled +-. nf +-. \} +-. el \{\ +-. tm1 "mdoc warning: Unknown keyword `\$1' (or missing display type) +-. tm1 " in .Bd macro (#\n[.c]) +-. nr doc-reg-Bd 0 +-. \}\}\}\}\} +-. +-. \" have we seen an argument? +-. if \n[doc-reg-Bd] \{\ +-. shift +-. \" check other arguments +-. if \n[.$] \ +-. doc-do-Bd-args \$@ +-. \} +-. +-. \" avoid warning about non-existent register +-. if !r doc-display-indent-stack\n[doc-display-depth] \ +-. nr doc-display-indent-stack\n[doc-display-depth] 0 +-. +-. if \n[doc-display-indent-stack\n[doc-display-depth]] \ +-. in +\n[doc-display-indent-stack\n[doc-display-depth]]u +-. +-. if !\n[doc-is-compact] \ +-. sp \n[doc-display-vertical]u +-. +-. if "\*[doc-display-type-stack\n[doc-display-depth]]"literal" \ +-. if t \ +-. nop \*[doc-Li-font]\c +-. +-. if !\n[cR] \ +-. ne 2v +-. +-. if !"\*[doc-display-file]"" \ +-. so \*[doc-display-file] +-. +-. nr doc-is-compact 0 +-. ds doc-display-file +-.. +-. +-. +-.\" NS doc-do-Bd-args macro +-.\" NS resolve remaining .Bd arguments +-.\" NS +-.\" NS modifies: +-.\" NS doc-display-file +-.\" NS doc-display-indent-stackXXX +-.\" NS doc-is-compact +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-ddBa +-.\" NS doc-reg-ddBa1 +-.\" NS doc-reg-ddBa2 +-.\" NS doc-reg-ddBa3 +-.\" NS doc-reg-ddBa4 +-.\" NS doc-str-ddBa +-. +-.de doc-do-Bd-args +-. nr doc-reg-ddBa 1 +-. +-. ie "\$1"-offset" \{\ +-. nr doc-reg-ddBa 2 +-. +-. ie "\$2"left" \ +-. nr doc-display-indent-stack\n[doc-display-depth] 0 +-. el \{ .ie "\$2"right" \ +-. nr doc-display-indent-stack\n[doc-display-depth] (\n[.l]u / 3u) +-. el \{ .ie "\$2"center" \ +-. nr doc-display-indent-stack\n[doc-display-depth] ((\n[.l]u - \n[.i]u) / 4u) +-. el \{ .ie "\$2"indent" \ +-. nr doc-display-indent-stack\n[doc-display-depth] \n[doc-display-indent]u +-. el \{ .ie "\$2"indent-two" \ +-. nr doc-display-indent-stack\n[doc-display-depth] (\n[doc-display-indent]u + \n[doc-display-indent]u) +-. el \ +-. nr doc-reg-ddBa 1 +-. \}\}\}\} +-. +-. \" not a known keyword +-. if (\n[doc-reg-ddBa] == 1) \{\ +-. nr doc-reg-ddBa 2 +-. +-. nr doc-reg-ddBa1 0 +-. if \B(\$2) \{\ +-. \" disable warnings related to scaling indicators (32) +-. nr doc-reg-ddBa2 \n[.warn] +-. warn (\n[.warn] - (\n[.warn] / 32 % 2 * 32)) +-. +-. \" values without a scaling indicator are taken as strings; +-. \" we test whether the parameter string with and without the last +-. \" character yields identical numerical results (ignoring the +-. \" scaling indicator) +-. ds doc-str-ddBa "\$2 +-. substring doc-str-ddBa 0 -2 +-. if \B(\*[doc-str-ddBa]) \{\ +-. nr doc-reg-ddBa3 (;(\$2)) +-. nr doc-reg-ddBa4 (\*[doc-str-ddBa]) +-. if (\n[doc-reg-ddBa3] == \n[doc-reg-ddBa4]) \ +-. nr doc-reg-ddBa1 1 +-. \} +-. +-. \" enable all warnings again +-. warn \n[doc-reg-ddBa2] +-. \} +-. +-. ie \n[doc-reg-ddBa1] \ +-. nr doc-display-indent-stack\n[doc-display-depth] \$2 +-. el \{\ +-. doc-get-width "\$2" +-. ie (\n[doc-width] <= 3) \{\ +-. \" if the offset parameter is a macro, use the macro's +-. \" width as specified in doc-common +-. doc-get-arg-type "\$2" +-. ie (\n[doc-arg-type] == 1) \ +-. nr doc-display-indent-stack\n[doc-display-depth] \n[\$2] +-. el \ +-. nr doc-display-indent-stack\n[doc-display-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +-. \} +-. el \ +-. nr doc-display-indent-stack\n[doc-display-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +-. \}\} +-. \} +-. el \{ .ie "\$1"-compact" \ +-. nr doc-is-compact 1 +-. el \{ .ie "\$1"-file" \{\ +-. ie !"\$2"" \{\ +-. ds doc-display-file "\$2 +-. nr doc-reg-ddBa 2 +-. \} +-. el \ +-. tm mdoc warning: .Bd `-file' keyword requires argument (#\n[.c]) +-. \} +-. el \ +-. tm mdoc warning: Unknown keyword `\$1' in .Bd macro (#\n[.c]) +-. \}\} +-. +-. if (\n[doc-reg-ddBa] < \n[.$]) \{\ +-. shift \n[doc-reg-ddBa] +-. doc-do-Bd-args \$@ +-. \} +-.. +-. +-. +-.\" NS Ed user macro +-.\" NS end display +-.\" NS +-.\" NS modifies: +-.\" NS doc-display-depth +-.\" NS doc-display-indent-stackXXX +-.\" NS doc-display-type-stackXXX +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Ed' set in doc-common +-. +-.de Ed +-. ds doc-macro-name Ed +-. +-. br +-. +-. if !\n[doc-display-depth] \{\ +-. tm mdoc warning: Extraneous .Ed (#\n[.c]) +-. nr doc-display-depth 1 +-. \} +-. +-. if "\*[doc-display-type-stack\n[doc-display-depth]]"literal" \{\ +-. ft \n[doc-display-ft-stack\n[doc-display-depth]] +-. ps \n[doc-display-ps-stack\n[doc-display-depth]]u +-. \} +-. +-. in -\n[doc-display-indent-stack\n[doc-display-depth]]u +-. +-. \" restore saved adjustment and fill modes +-. ie \n[doc-display-fi-stack\n[doc-display-depth]] \ +-. fi +-. el \ +-. nf +-. ad \n[doc-display-ad-stack\n[doc-display-depth]] +-. +-. nr doc-display-indent-stack\n[doc-display-depth] 0 +-. ds doc-display-type-stack\n[doc-display-depth] +-. nr doc-display-depth -1 +-.. +-. +-. +-.\" NS doc-list-type-stackXXX global string +-.\" NS stack of list types +-.\" NS +-.\" NS limit: +-.\" NS doc-list-depth +-. +-.ds doc-list-type-stack1 +-. +-. +-.\" NS doc-list-indent-stackXXX global register +-.\" NS stack of list indentation values +-.\" NS +-.\" NS limit: +-.\" NS doc-list-depth +-. +-.nr doc-list-indent-stack1 0 +-. +-. +-.\" NS doc-list-have-indent-stackXXX global register (bool) +-.\" NS an indentation value is active +-.\" NS +-.\" NS limit: +-.\" NS doc-list-depth +-. +-.nr doc-list-have-indent-stack1 0 +-. +-. +-.\" NS Bl user macro +-.\" NS begin list +-.\" NS +-.\" NS width register `Bl' set in doc-common +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-argXXX +-.\" NS doc-list-depth +-.\" NS doc-list-have-indent-stackXXX +-.\" NS doc-list-indent-stackXXX +-.\" NS doc-list-type-stackXXX +-.\" NS doc-macro-name +-.\" NS doc-num-args +-.\" NS doc-num-columns +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-Bl +-. +-.de Bl +-. if !\n[.$] \{\ +-. doc-Bl-usage +-. return +-. \} +-. +-. ds doc-macro-name Bl +-. nr doc-list-depth +1 +-. nr doc-arg-ptr 1 +-. +-. ie "\$1"-hang" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] hang-list +-. nr doc-list-indent-stack\n[doc-list-depth] 6n +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. el \{ .ie "\$1"-tag" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] tag-list +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. el \{ .ie "\$1"-item" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] item-list +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. el \{ .ie "\$1"-enum" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] enum-list +-. nr doc-list-indent-stack\n[doc-list-depth] 3n +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. el \{ .ie "\$1"-bullet" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] bullet-list +-. nr doc-list-indent-stack\n[doc-list-depth] 2n +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. el \{ .ie "\$1"-dash" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] dash-list +-. nr doc-list-indent-stack\n[doc-list-depth] 2n +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. el \{ .ie "\$1"-hyphen" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] dash-list +-. nr doc-list-indent-stack\n[doc-list-depth] 2n +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. el \{ .ie "\$1"-inset" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] inset-list +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. el \{ .ie "\$1"-diag" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] diag-list +-. \} +-. el \{ .ie "\$1"-ohang" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] ohang-list +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. el \{ .ie "\$1"-column" \{\ +-. ds doc-list-type-stack\n[doc-list-depth] column-list +-. linetabs 1 +-. \} +-. el \{\ +-. tm1 "mdoc warning: Unknown list type `\$1' (or missing list type) +-. tm1 " in .Bl macro +-. tm +-. nr doc-arg-ptr 0 +-. \}\}\}\}\}\}\}\}\}\}\} +-. +-. \" we have seen a list type +-. if !\n[doc-arg-ptr] \{\ +-. doc-Bl-usage +-. doc-reset-args +-. nr doc-list-depth -1 +-. return +-. \} +-. +-. shift +-. +-. \" fill argument vector +-. nr doc-reg-Bl 1 +-. while (\n[doc-reg-Bl] <= \n[.$]) \{\ +-. ds doc-arg\n[doc-reg-Bl] "\$[\n[doc-reg-Bl]] +-. \" dummy type and space so that doc-save-global-vars() doesn't warn +-. nr doc-type\n[doc-reg-Bl] 0 +-. ds doc-space\n[doc-reg-Bl] +-. nr doc-reg-Bl +1 +-. \} +-. +-. doc-increment-list-stack +-. +-. if \n[.$] \{\ +-. nr doc-arg-limit \n[.$] +-. nr doc-arg-ptr 0 +-. doc-do-Bl-args +-. +-. in +\n[doc-list-offset-stack\n[doc-list-depth]]u +-. +-. \" initialize column list +-. if "\*[doc-list-type-stack\n[doc-list-depth]]"column-list" \{\ +-. doc-set-column-tab \n[doc-num-columns] +-' in -\n[doc-column-indent-width]u +-. if !\n[doc-compact-list-stack\n[doc-list-depth]] \ +-. sp \n[doc-display-vertical]u +-. +-. nf +-. nr doc-num-columns 0 +-. \}\} +-. +-. doc-reset-args +-.. +-. +-. +-.\" NS doc-Bl-usage macro +-. +-.de doc-Bl-usage +-. tm1 "Usage: .Bl {-hang | -ohang | -tag | -diag | -inset} +-. tm1 " [-width ] +-. tm1 " [-offset ] [-compact] +-. tm1 " .Bl -column [-offset ] ... +-. tm1 " .Bl {-item | -enum [-nested] | -bullet | -hyphen | -dash} +-. tm1 " [-offset ] [-compact] (#\n[.c]) +-.. +-. +-. +-.\" NS doc-do-Bl-args macro +-.\" NS resolve remaining .Bl arguments +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-argXXX +-.\" NS doc-compact-list-stackXXX +-.\" NS doc-list-indent-stackXXX +-.\" NS doc-list-offset-stackXXX +-.\" NS doc-num-columns +-.\" NS doc-tag-prefix-stackXXX +-.\" NS doc-tag-width-stackXXX +-.\" NS +-.\" NS local variables: +-.\" NS doc-box-dBla +-.\" NS doc-env-dBla +-.\" NS doc-reg-dBla +-.\" NS doc-reg-dBla1 +-.\" NS doc-reg-dBla2 +-.\" NS doc-reg-dBla3 +-.\" NS doc-reg-dBla4 +-.\" NS doc-str-dBla +-.\" NS doc-str-dBla1 +-. +-.de doc-do-Bl-args +-. nr doc-arg-ptr +1 +-. +-. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \ +-. return +-. +-. \" avoid a warning message in case e.g. `-offset' has no parameter +-. nr doc-reg-dBla (\n[doc-arg-ptr] + 1) +-. if !d doc-arg\n[doc-reg-dBla] \ +-. ds doc-arg\n[doc-reg-dBla] +-. +-. nr doc-reg-dBla 1 +-. +-. ie "\*[doc-arg\n[doc-arg-ptr]]"-compact" \ +-. nr doc-compact-list-stack\n[doc-list-depth] 1 +-. +-. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-nested" \{\ +-. ie (\n[doc-list-depth] > 1) \{\ +-. nr doc-reg-dBla1 (\n[doc-list-depth] - 1) +-. ds doc-tag-prefix-stack\n[doc-list-depth] "\*[doc-tag-prefix-stack\n[doc-reg-dBla1]] +-. as doc-tag-prefix-stack\n[doc-list-depth] \n[doc-enum-list-count-stack\n[doc-reg-dBla1]]. +-. length doc-reg-dBla1 "\*[doc-tag-prefix-stack\n[doc-list-depth]] +-. nr doc-list-indent-stack\n[doc-list-depth] +\n[doc-reg-dBla1]n +-. \} +-. el \ +-. tm mdoc warning: `-nested' allowed with nested .Bl macros only (#\n[.c]) +-. \} +-. +-. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-width" \{\ +-. nr doc-arg-ptr +1 +-. ds doc-tag-width-stack\n[doc-list-depth] TagwidtH +-. +-. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +-. substring doc-str-dBla 0 0 +-. ie .\*[doc-str-dBla] \{\ +-. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +-. substring doc-str-dBla 1 +-. doc-first-parameter \*[doc-str-dBla] +-. doc-get-width "\*[doc-str-dfp] +-. doc-get-arg-type "\*[doc-str-dfp] +-. ie (\n[doc-arg-type] == 1) \ +-. nr doc-reg-dBla1 1 +-. el \ +-. nr doc-reg-dBla1 0 +-. \} +-. el \ +-. nr doc-reg-dBla1 0 +-. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +-. +-. ie \n[doc-reg-dBla1] \{\ +-. \" execute string in a box to get the width of the diversion +-. ds doc-str-dBla \*[doc-arg\n[doc-arg-ptr]] +-. doc-save-global-vars +-. doc-reset-args +-. box doc-box-dBla +-. ev doc-env-dBla +-. evc 0 +-. in 0 +-. nf +-. nop \*[doc-str-dBla] +-. br +-. ev +-. box +-. doc-restore-global-vars +-. doc-get-width \h'\n[dl]u' +-. nr doc-list-indent-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +-. \} +-. el \{\ +-. \" test whether argument is a valid numeric expression +-. nr doc-reg-dBla1 0 +-. if \B(\*[doc-str-dBla]) \{\ +-. \" disable warnings related to scaling indicators (32) +-. nr doc-reg-dBla2 \n[.warn] +-. warn (\n[.warn] - (\n[.warn] / 32 % 2 * 32)) +-. +-. \" values without a scaling indicator are taken as strings; +-. \" we test whether the parameter string with and without the last +-. \" character yields identical numerical results (ignoring the +-. \" scaling indicator) +-. ds doc-str-dBla1 "\*[doc-str-dBla] +-. substring doc-str-dBla1 0 -2 +-. if \B(\*[doc-str-dBla1]) \{\ +-. nr doc-reg-dBla3 (;(\*[doc-str-dBla])) +-. nr doc-reg-dBla4 (\*[doc-str-dBla1]) +-. if (\n[doc-reg-dBla3] == \n[doc-reg-dBla4]) \ +-. nr doc-reg-dBla1 1 +-. \} +-. +-. \" enable all warnings again +-. warn \n[doc-reg-dBla2] +-. \} +-. +-. ie \n[doc-reg-dBla1] \ +-. nr doc-list-indent-stack\n[doc-list-depth] (\*[doc-str-dBla]) +-. el \{\ +-. doc-get-arg-width \n[doc-arg-ptr] +-. ie (\n[doc-width] == 2) \{\ +-. \" if the width parameter is a macro, use the macro's +-. \" width as specified in doc-common +-. doc-get-arg-type \*[doc-str-dBla] +-. ie (\n[doc-arg-type] == 1) \ +-. nr doc-list-indent-stack\n[doc-list-depth] \n[\*[doc-str-dBla]] +-. el \ +-. nr doc-list-indent-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +-. \} +-. el \ +-. nr doc-list-indent-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +-. \}\}\} +-. +-. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-offset" \{\ +-. nr doc-arg-ptr +1 +-. +-. ie "\*[doc-arg\n[doc-arg-ptr]]"indent" \ +-. nr doc-list-offset-stack\n[doc-list-depth] \n[doc-display-indent]u +-. el \{\ +-. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +-. nr doc-reg-dBla1 0 +-. if \B(\*[doc-str-dBla]) \{\ +-. nr doc-reg-dBla2 \n[.warn] +-. warn (\n[.warn] - (\n[.warn] / 32 % 2 * 32)) +-. +-. ds doc-str-dBla1 "\*[doc-str-dBla] +-. substring doc-str-dBla1 0 -2 +-. if \B(\*[doc-str-dBla1]) \{\ +-. nr doc-reg-dBla3 (;(\*[doc-str-dBla])) +-. nr doc-reg-dBla4 (\*[doc-str-dBla1]) +-. if (\n[doc-reg-dBla3] == \n[doc-reg-dBla4]) \ +-. nr doc-reg-dBla1 1 +-. \} +-. +-. warn \n[doc-reg-dBla2] +-. \} +-. +-. ie \n[doc-reg-dBla1] \ +-. nr doc-list-offset-stack\n[doc-list-depth] \*[doc-str-dBla] +-. el \{\ +-. doc-get-arg-width \n[doc-arg-ptr] +-. ie (\n[doc-width] <= 3) \{\ +-. \" if the offset parameter is a macro, use the macro's +-. \" width as specified in doc-common +-. doc-get-arg-type \*[doc-str-dBla] +-. ie (\n[doc-arg-type] == 1) \ +-. nr doc-list-offset-stack\n[doc-list-depth] \n[\*[doc-str-dBla]] +-. el \ +-. nr doc-list-offset-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +-. \} +-. el \ +-. nr doc-list-offset-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) +-. \}\}\} +-. el \ +-. nr doc-reg-dBla 0 +-. \}\}\} +-. +-. \" not a known keyword, so it specifies the width of the next column +-. \" (if it is a column list) +-. if !\n[doc-reg-dBla] \{\ +-. ie "\*[doc-list-type-stack\n[doc-list-depth]]"column-list" \{\ +-. nr doc-num-columns +1 +-. ds doc-str-dBla \*[doc-arg\n[doc-arg-ptr]] +-. substring doc-str-dBla 0 0 +-. ie .\*[doc-str-dBla] \{\ +-. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +-. substring doc-str-dBla 1 +-. doc-first-parameter \*[doc-str-dBla] +-. doc-get-width "\*[doc-str-dfp] +-. doc-get-arg-type "\*[doc-str-dfp] +-. ie (\n[doc-arg-type] == 1) \ +-. nr doc-reg-dBla1 1 +-. el \ +-. nr doc-reg-dBla1 0 +-. \} +-. el \ +-. nr doc-reg-dBla1 0 +-. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] +-. +-. ie \n[doc-reg-dBla1] \{\ +-. \" execute string in a box to get the width of the diversion +-. ds doc-str-dBla \*[doc-arg\n[doc-arg-ptr]] +-. doc-save-global-vars +-. doc-reset-args +-. box doc-box-dBla +-. ev doc-env-dBla +-. evc 0 +-. in 0 +-. nf +-. nop \*[doc-str-dBla] +-. br +-. ev +-. box +-. doc-restore-global-vars +-. ds doc-arg\n[doc-num-columns] "\h'\n[dl]u' +-. \} +-. el \ +-. ds doc-arg\n[doc-num-columns] "\*[doc-arg\n[doc-arg-ptr]] +-. \} +-. el \{\ +-. tmc mdoc warning: Unknown keyword `\*[doc-arg\n[doc-arg-ptr]]' +-. tm1 " in .Bl macro (#\n[.c]) +-. \}\} +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \ +-. doc-do-Bl-args +-.. +-. +-. +-.\" NS doc-save-global-vars macro +-.\" NS save all global variables +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dsgv +-. +-.de doc-save-global-vars +-. ds doc-macro-name-saved "\*[doc-macro-name] +-. nr doc-arg-limit-saved \n[doc-arg-limit] +-. nr doc-num-args-saved \n[doc-num-args] +-. nr doc-arg-ptr-saved \n[doc-arg-ptr] +-. +-. nr doc-reg-dsgv 1 +-. while (\n[doc-reg-dsgv] <= \n[doc-arg-limit]) \{\ +-. ds doc-arg\n[doc-reg-dsgv]-saved "\*[doc-arg\n[doc-reg-dsgv]] +-. nr doc-type\n[doc-reg-dsgv]-saved \n[doc-type\n[doc-reg-dsgv]] +-. ds doc-space\n[doc-reg-dsgv]-saved "\*[doc-space\n[doc-reg-dsgv]] +-. nr doc-reg-dsgv +1 +-. \} +-. +-. nr doc-curr-font-saved \n[doc-curr-font] +-. nr doc-curr-size-saved \n[doc-curr-size] +-. nr doc-in-synopsis-section-saved \n[doc-in-synopsis-section] +-. nr doc-in-library-section-saved \n[doc-in-library-section] +-. nr doc-indent-synopsis-saved \n[doc-indent-synopsis] +-. nr doc-indent-synopsis-active-saved \n[doc-indent-synopsis-active] +-. nr doc-have-decl-saved \n[doc-have-decl] +-. nr doc-have-var-saved \n[doc-have-var] +-. ds doc-command-name-saved "\*[doc-command-name] +-. ds doc-quote-left-saved "\*[doc-quote-left] +-. ds doc-quote-right-saved "\*[doc-quote-right] +-. nr doc-nesting-level-saved \n[doc-nesting-level] +-. nr doc-in-list-saved \n[doc-in-list] +-. ds doc-space-saved "\*[doc-space] +-. ds doc-saved-space-saved "\*[doc-saved-space] +-. nr doc-space-mode-saved \n[doc-space-mode] +-. nr doc-have-space-saved \n[doc-have-space] +-. nr doc-have-slot-saved \n[doc-have-slot] +-. nr doc-keep-type-saved \n[doc-keep-type] +-. nr doc-display-depth-saved \n[doc-display-depth] +-. nr doc-is-compact-saved \n[doc-is-compact] +-. +-. nr doc-reg-dsgv 0 +-. while (\n[doc-reg-dsgv] <= \n[doc-display-depth]) \{\ +-. ds doc-display-type-stack\n[doc-reg-dsgv]-saved "\*[doc-display-type-stack\n[doc-reg-dsgv]] +-. nr doc-display-indent-stack\n[doc-reg-dsgv]-saved \n[doc-display-indent-stack\n[doc-reg-dsgv]] +-. nr doc-display-ad-stack\n[doc-reg-dsgv]-saved \n[doc-display-ad-stack\n[doc-reg-dsgv]] +-. nr doc-display-fi-stack\n[doc-reg-dsgv]-saved \n[doc-display-fi-stack\n[doc-reg-dsgv]] +-. nr doc-display-ft-stack\n[doc-reg-dsgv]-saved \n[doc-display-ft-stack\n[doc-reg-dsgv]] +-. nr doc-display-ps-stack\n[doc-reg-dsgv]-saved \n[doc-display-ps-stack\n[doc-reg-dsgv]] +-. nr doc-reg-dsgv +1 +-. \} +-. +-. nr doc-fontmode-depth-saved \n[doc-fontmode-depth] +-. +-. nr doc-reg-dsgv 1 +-. while (\n[doc-reg-dsgv] <= \n[doc-fontmode-depth]) \{\ +-. nr doc-fontmode-font-stack\n[doc-reg-dsgv]-saved \n[doc-fontmode-font-stack\n[doc-reg-dsgv]] +-. nr doc-fontmode-size-stack\n[doc-reg-dsgv]-saved \n[doc-fontmode-size-stack\n[doc-reg-dsgv]] +-. nr doc-reg-dsgv +1 +-. \} +-. +-. nr doc-list-depth-saved \n[doc-list-depth] +-. +-. nr doc-reg-dsgv 1 +-. while (\n[doc-reg-dsgv] <= \n[doc-list-depth]) \{\ +-. ds doc-list-type-stack\n[doc-reg-dsgv]-saved "\*[doc-list-type-stack\n[doc-reg-dsgv]] +-. nr doc-list-have-indent-stack\n[doc-reg-dsgv]-saved \n[doc-list-have-indent-stack\n[doc-reg-dsgv]] +-. nr doc-list-indent-stack\n[doc-reg-dsgv]-saved \n[doc-list-indent-stack\n[doc-reg-dsgv]] +-. nr doc-compact-list-stack\n[doc-reg-dsgv]-saved \n[doc-compact-list-stack\n[doc-reg-dsgv]] +-. ds doc-tag-prefix-stack\n[doc-reg-dsgv]-saved "\*[doc-tag-prefix-stack\n[doc-reg-dsgv]] +-. ds doc-tag-width-stack\n[doc-reg-dsgv]-saved "\*[doc-tag-width-stack\n[doc-reg-dsgv]] +-. nr doc-list-offset-stack\n[doc-reg-dsgv]-saved \n[doc-list-offset-stack\n[doc-reg-dsgv]] +-. nr doc-enum-list-count-stack\n[doc-reg-dsgv]-saved \n[doc-enum-list-count-stack\n[doc-reg-dsgv]] +-. nr doc-reg-dsgv +1 +-. \} +-. +-. ds doc-saved-Pa-font-saved "\*[doc-saved-Pa-font] +-. nr doc-curr-type-saved \n[doc-curr-type] +-. ds doc-curr-arg-saved "\*[doc-curr-arg] +-. nr doc-diag-list-input-line-count-saved \n[doc-diag-list-input-line-count] +-. nr doc-num-columns-saved \n[doc-num-columns] +-. nr doc-column-indent-width-saved \n[doc-column-indent-width] +-. nr doc-is-func-saved \n[doc-is-func] +-. nr doc-have-old-func-saved \n[doc-have-old-func] +-. nr doc-func-arg-count-saved \n[doc-func-arg-count] +-. ds doc-func-arg-saved "\*[doc-func-arg] +-. nr doc-num-func-args-saved \n[doc-num-func-args] +-. nr doc-func-args-processed-saved \n[doc-func-args-processed] +-. nr doc-have-func-saved \n[doc-have-func] +-. nr doc-is-reference-saved \n[doc-is-reference] +-. nr doc-reference-count-saved \n[doc-reference-count] +-. nr doc-author-count-saved \n[doc-author-count] +-. +-. nr doc-reg-dsgv 0 +-. while (\n[doc-reg-dsgv] <= \n[doc-author-count]) \{\ +-. ds doc-author-name\n[doc-reg-dsgv]-saved "\*[doc-author-name\n[doc-reg-dsgv]] +-. nr doc-reg-dsgv +1 +-. \} +-. +-. nr doc-book-count-saved \n[doc-book-count] +-. ds doc-book-name-saved "\*[doc-book-name] +-. nr doc-city-count-saved \n[doc-city-count] +-. ds doc-city-name-saved "\*[doc-city-name] +-. nr doc-date-count-saved \n[doc-date-count] +-. ds doc-date-saved "\*[doc-date] +-. nr doc-publisher-count-saved \n[doc-publisher-count] +-. ds doc-publisher-name-saved "\*[doc-publisher-name] +-. nr doc-journal-count-saved \n[doc-journal-count] +-. ds doc-journal-name-saved "\*[doc-journal-name] +-. nr doc-issue-count-saved \n[doc-issue-count] +-. ds doc-issue-name-saved "\*[doc-issue-name] +-. nr doc-optional-count-saved \n[doc-optional-count] +-. ds doc-optional-string-saved "\*[doc-optional-string] +-. nr doc-page-number-count-saved \n[doc-page-number-count] +-. ds doc-page-number-string-saved "\*[doc-page-number-string] +-. nr doc-corporate-count-saved \n[doc-corporate-count] +-. ds doc-corporate-name-saved "\*[doc-corporate-name] +-. nr doc-report-count-saved \n[doc-report-count] +-. ds doc-report-name-saved "\*[doc-report-name] +-. nr doc-reference-title-count-saved \n[doc-reference-title-count] +-. ds doc-reference-title-name-saved "\*[doc-reference-title-name] +-. ds doc-reference-title-name-for-book-saved "\*[doc-reference-title-name-for-book] +-. nr doc-url-count-saved \n[doc-url-count] +-. ds doc-url-name-saved "\*[doc-url-name] +-. nr doc-volume-count-saved \n[doc-volume-count] +-. ds doc-volume-name-saved "\*[doc-volume-name] +-. nr doc-have-author-saved \n[doc-have-author] +-. +-. ds doc-document-title-saved "\*[doc-document-title] +-. ds doc-volume-saved "\*[doc-volume] +-. ds doc-section-saved "\*[doc-section] +-. ds doc-operating-system-saved "\*[doc-operating-system] +-. ds doc-date-string-saved "\*[doc-date-string] +-. nr doc-header-space-saved \n[doc-header-space] +-. nr doc-footer-space-saved \n[doc-footer-space] +-. nr doc-display-vertical-saved \n[doc-display-vertical] +-. ds doc-header-string-saved "\*[doc-header-string] +-. nr doc-in-see-also-section-saved \n[doc-in-see-also-section] +-. nr doc-in-files-section-saved \n[doc-in-files-section] +-. nr doc-in-authors-section-saved \n[doc-in-authors-section] +-.. +-. +-. +-.\" NS doc-restore-global-vars macro +-.\" NS restore all global variables +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-drgv +-. +-.de doc-restore-global-vars +-. ds doc-macro-name "\*[doc-macro-name-saved] +-. nr doc-arg-limit \n[doc-arg-limit-saved] +-. nr doc-num-args \n[doc-num-args-saved] +-. nr doc-arg-ptr \n[doc-arg-ptr-saved] +-. +-. nr doc-reg-drgv 1 +-. while (\n[doc-reg-drgv] <= \n[doc-arg-limit]) \{\ +-. ds doc-arg\n[doc-reg-drgv] "\*[doc-arg\n[doc-reg-drgv]-saved] +-. nr doc-type\n[doc-reg-drgv] \n[doc-type\n[doc-reg-drgv]-saved] +-. ds doc-space\n[doc-reg-drgv] "\*[doc-space\n[doc-reg-drgv]-saved] +-. nr doc-reg-drgv +1 +-. \} +-. +-. nr doc-curr-font \n[doc-curr-font-saved] +-. nr doc-curr-size \n[doc-curr-size-saved] +-. nr doc-in-synopsis-section \n[doc-in-synopsis-section-saved] +-. nr doc-in-library-section \n[doc-in-library-section-saved] +-. nr doc-indent-synopsis \n[doc-indent-synopsis-saved] +-. nr doc-indent-synopsis-active \n[doc-indent-synopsis-active-saved] +-. nr doc-have-decl \n[doc-have-decl-saved] +-. nr doc-have-var \n[doc-have-var-saved] +-. ds doc-command-name "\*[doc-command-name-saved] +-. ds doc-quote-left "\*[doc-quote-left-saved] +-. ds doc-quote-right "\*[doc-quote-right-saved] +-. nr doc-nesting-level \n[doc-nesting-level-saved] +-. nr doc-in-list \n[doc-in-list-saved] +-. ds doc-space "\*[doc-space-saved] +-. ds doc-saved-space "\*[doc-saved-space-saved] +-. nr doc-space-mode \n[doc-space-mode-saved] +-. nr doc-have-space \n[doc-have-space-saved] +-. nr doc-have-slot \n[doc-have-slot-saved] +-. nr doc-keep-type \n[doc-keep-type-saved] +-. nr doc-display-depth \n[doc-display-depth-saved] +-. nr doc-is-compact \n[doc-is-compact-saved] +-. +-. nr doc-reg-drgv 0 +-. while (\n[doc-reg-drgv] <= \n[doc-display-depth]) \{\ +-. ds doc-display-type-stack\n[doc-reg-drgv] "\*[doc-display-type-stack\n[doc-reg-drgv]-saved] +-. nr doc-display-indent-stack\n[doc-reg-drgv] \n[doc-display-indent-stack\n[doc-reg-drgv]-saved] +-. nr doc-display-ad-stack\n[doc-reg-drgv] \n[doc-display-ad-stack\n[doc-reg-drgv]-saved] +-. nr doc-display-fi-stack\n[doc-reg-drgv] \n[doc-display-fi-stack\n[doc-reg-drgv]-saved] +-. nr doc-display-ft-stack\n[doc-reg-drgv] \n[doc-display-ft-stack\n[doc-reg-drgv]-saved] +-. nr doc-display-ps-stack\n[doc-reg-drgv] \n[doc-display-ps-stack\n[doc-reg-drgv]-saved] +-. nr doc-reg-drgv +1 +-. \} +-. +-. nr doc-fontmode-depth \n[doc-fontmode-depth-saved] +-. +-. nr doc-reg-drgv 1 +-. while (\n[doc-reg-drgv] <= \n[doc-fontmode-depth]) \{\ +-. nr doc-fontmode-font-stack\n[doc-reg-drgv] \n[doc-fontmode-font-stack\n[doc-reg-drgv]]-saved +-. nr doc-fontmode-size-stack\n[doc-reg-drgv] \n[doc-fontmode-size-stack\n[doc-reg-drgv]]-saved +-. nr doc-reg-drgv +1 +-. \} +-. +-. nr doc-list-depth \n[doc-list-depth-saved] +-. +-. nr doc-reg-drgv 1 +-. while (\n[doc-reg-drgv] <= \n[doc-list-depth]) \{\ +-. ds doc-list-type-stack\n[doc-reg-drgv] "\*[doc-list-type-stack\n[doc-reg-drgv]-saved] +-. nr doc-list-have-indent-stack\n[doc-reg-drgv] \n[doc-list-have-indent-stack\n[doc-reg-drgv]-saved] +-. nr doc-list-indent-stack\n[doc-reg-drgv] \n[doc-list-indent-stack\n[doc-reg-drgv]-saved] +-. nr doc-compact-list-stack\n[doc-reg-drgv] \n[doc-compact-list-stack\n[doc-reg-drgv]-saved] +-. ds doc-tag-prefix-stack\n[doc-reg-drgv] "\*[doc-tag-prefix-stack\n[doc-reg-drgv]-saved] +-. ds doc-tag-width-stack\n[doc-reg-drgv] "\*[doc-tag-width-stack\n[doc-reg-drgv]-saved] +-. nr doc-list-offset-stack\n[doc-reg-drgv] \n[doc-list-offset-stack\n[doc-reg-drgv]-saved] +-. nr doc-enum-list-count-stack\n[doc-reg-drgv] \n[doc-enum-list-count-stack\n[doc-reg-drgv]-saved] +-. nr doc-reg-drgv +1 +-. \} +-. +-. ds doc-saved-Pa-font "\*[doc-saved-Pa-font-saved] +-. nr doc-curr-type \n[doc-curr-type-saved] +-. ds doc-curr-arg "\*[doc-curr-arg-saved] +-. nr doc-diag-list-input-line-count \n[doc-diag-list-input-line-count-saved] +-. nr doc-num-columns \n[doc-num-columns-saved] +-. nr doc-column-indent-width \n[doc-column-indent-width-saved] +-. nr doc-is-func \n[doc-is-func-saved] +-. nr doc-have-old-func \n[doc-have-old-func-saved] +-. nr doc-func-arg-count \n[doc-func-arg-count-saved] +-. ds doc-func-arg "\*[doc-func-arg-saved] +-. nr doc-num-func-args \n[doc-num-func-args-saved] +-. nr doc-func-args-processed \n[doc-func-args-processed-saved] +-. nr doc-have-func \n[doc-have-func-saved] +-. nr doc-is-reference \n[doc-is-reference-saved] +-. nr doc-reference-count \n[doc-reference-count-saved] +-. nr doc-author-count \n[doc-author-count-saved] +-. +-. nr doc-reg-drgv 0 +-. while (\n[doc-reg-drgv] <= \n[doc-author-count]) \{\ +-. ds doc-author-name\n[doc-reg-drgv] "\*[doc-author-name\n[doc-reg-drgv]-saved] +-. nr doc-reg-drgv +1 +-. \} +-. +-. nr doc-book-count \n[doc-book-count-saved] +-. ds doc-book-name "\*[doc-book-name-saved] +-. nr doc-city-count \n[doc-city-count-saved] +-. ds doc-city-name "\*[doc-city-name-saved] +-. nr doc-date-count \n[doc-date-count-saved] +-. ds doc-date "\*[doc-date-saved] +-. nr doc-publisher-count \n[doc-publisher-count-saved] +-. ds doc-publisher-name "\*[doc-publisher-name-saved] +-. nr doc-journal-count \n[doc-journal-count-saved] +-. ds doc-journal-name "\*[doc-journal-name-saved] +-. nr doc-issue-count \n[doc-issue-count-saved] +-. ds doc-issue-name "\*[doc-issue-name-saved] +-. nr doc-optional-count \n[doc-optional-count-saved] +-. ds doc-optional-string "\*[doc-optional-string-saved] +-. nr doc-page-number-count \n[doc-page-number-count-saved] +-. ds doc-page-number-string "\*[doc-page-number-string-saved] +-. nr doc-corporate-count \n[doc-corporate-count-saved] +-. ds doc-corporate-name "\*[doc-corporate-name-saved] +-. nr doc-report-count \n[doc-report-count-saved] +-. ds doc-report-name "\*[doc-report-name-saved] +-. nr doc-reference-title-count \n[doc-reference-title-count-saved] +-. ds doc-reference-title-name "\*[doc-reference-title-name-saved] +-. ds doc-reference-title-name-for-book "\*[doc-reference-title-name-for-book-saved] +-. nr doc-url-count \n[doc-url-count-saved] +-. ds doc-url-name "\*[doc-url-name-saved] +-. nr doc-volume-count \n[doc-volume-count-saved] +-. ds doc-volume-name "\*[doc-volume-name-saved] +-. nr doc-have-author \n[doc-have-author-saved] +-. +-. ds doc-document-title "\*[doc-document-title-saved] +-. ds doc-volume "\*[doc-volume-saved] +-. ds doc-section "\*[doc-section-saved] +-. ds doc-operating-system "\*[doc-operating-system-saved] +-. ds doc-date-string "\*[doc-date-string-saved] +-. nr doc-header-space \n[doc-header-space-saved] +-. nr doc-footer-space \n[doc-footer-space-saved] +-. nr doc-display-vertical \n[doc-display-vertical-saved] +-. ds doc-header-string "\*[doc-header-string-saved] +-. nr doc-in-see-also-section \n[doc-in-see-also-section-saved] +-. nr doc-in-files-section \n[doc-in-files-section-saved] +-. nr doc-in-authors-section \n[doc-in-authors-section-saved] +-.. +-. +-. +-.\" NS El user macro +-.\" NS end list +-.\" NS +-.\" NS modifies: +-.\" NS doc-list-depth +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variables: +-.\" NS doc-str-El +-.\" NS +-.\" NS width register `El' set in doc-common +-. +-.de El +-. if \n[.$] \{\ +-. tm Usage: .El (does not take arguments) (#\n[.c]) +-. return +-. \} +-. +-. ds doc-macro-name El +-. ds doc-str-El \*[doc-list-type-stack\n[doc-list-depth]] +-. +-. ie "\*[doc-str-El]"diag-list" \ +-. doc-end-list 0 +-. el \{ .ie "\*[doc-str-El]"column-list" \ +-. doc-end-column-list +-. el \{ .ie "\*[doc-str-El]"item-list" \ +-. doc-end-list 0 +-. el \{ .ie "\*[doc-str-El]"ohang-list" \ +-. doc-end-list 0 +-. el \{ .ie "\*[doc-str-El]"inset-list" \ +-. doc-end-list 0 +-. el \ +-. doc-end-list 1 +-. \}\}\}\} +-. +-. br +-.. +-. +-. +-.\" NS doc-saved-Pa-font global string +-.\" NS saved doc-Pa-font string for section FILES (no underline if +-.\" NS nroff) +-. +-.ds doc-saved-Pa-font +-. +-. +-.\" NS doc-curr-type global register +-.\" NS current argument type +-. +-.nr doc-curr-type 0 +-. +-. +-.\" NS doc-curr-arg global string +-.\" NS current argument +-. +-.ds doc-curr-arg +-. +-. +-.\" NS doc-item-boxXXX global box +-.\" NS item boxes associated list depth +-.\" NS +-.\" NS limit: +-.\" NS doc-list-depth +-. +-. +-.\" NS It user macro +-.\" NS list item +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-argXXX +-.\" NS doc-curr-arg +-.\" NS doc-curr-type +-.\" NS doc-in-list +-.\" NS doc-macro-name +-.\" NS doc-num-args +-.\" NS doc-saved-Pa-font +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-It +-.\" NS doc-str-It +-.\" NS doc-XXX-list-type +-.\" NS +-.\" NS width register `It' set in doc-common +-. +-.nr doc-bullet-list-type 1 +-.nr doc-column-list-type 0 +-.nr doc-dash-list-type 1 +-.nr doc-diag-list-type 0 +-.nr doc-enum-list-type 1 +-.nr doc-hang-list-type 2 +-.nr doc-inset-list-type 2 +-.nr doc-item-list-type 1 +-.nr doc-ohang-list-type 2 +-.nr doc-tag-list-type 2 +-. +-.de It +-. ds doc-str-It \*[doc-list-type-stack\n[doc-list-depth]] +-. +-. if "\*[doc-str-It]"" \ +-. tm mdoc error: .It without preceding .Bl (#\n[.c]) +-. +-. if \n[doc-nesting-level] \{\ +-. tmc "mdoc error: .It found in enclosing (e.g. .Ac ... .It ... .Ao) +-. tm1 " (#\n[.c]) +-. \} +-. +-. br +-. if !\n[cR] \ +-. ne 3v +-. +-. if \n[.$] \{\ +-. ds doc-macro-name It +-. +-. \" fill argument vector +-. nr doc-reg-It 1 +-. while (\n[doc-reg-It] <= \n[.$]) \{\ +-. ds doc-arg\n[doc-reg-It] "\$[\n[doc-reg-It]] +-. nr doc-reg-It +1 +-. \} +-. +-. nr doc-num-args \n[.$] +-. nr doc-arg-ptr 0 +-. \} +-. +-. nr doc-reg-It \n[doc-\*[doc-str-It]-type] +-. +-. if \n[doc-reg-It] \{\ +-. \" start item box +-. box doc-item-box\n[doc-list-depth] +-. ev doc-item-env\n[doc-list-depth] +-. evc 0 +-. in 0 +-. nf +-. \} +-. +-. ie (\n[doc-reg-It] == 1) \{\ +-. if \n[.$] \{\ +-. tm1 "mdoc warning: .It macros in lists of type `\*[doc-str-It]' +-. tm1 " don't take arguments (#\n[.c]) +-. \}\} +-. el \{\ +-. ie \n[.$] \{\ +-. if (\n[doc-reg-It] == 2) \{\ +-. \" handle list types with arguments +-. doc-parse-arg-vector +-. +-. nr doc-in-list 1 +-. nr doc-arg-ptr 1 +-. nr doc-curr-type \n[doc-type1] +-. ds doc-curr-arg "\*[doc-arg1] +-. +-. if \n[doc-in-files-section] \{\ +-. ds doc-saved-Pa-font "\*[doc-Pa-font] +-. if n \ +-. ds doc-Pa-font "\*[doc-No-font] +-. \} +-. +-. ie (\n[doc-type1] == 1) \ +-. \*[doc-arg1] +-. el \{\ +-. nr doc-arg-ptr 1 +-. doc-print-recursive +-. \}\}\} +-. el \{\ +-. tm1 "mdoc warning: .It macros in lists of type `\*[doc-str-It]' +-. tm1 " require arguments (#\n[.c]) +-. \} +-. \} +-. +-. \" the previous call of `.doc-print-recursive' can contain calls to +-. \" opening macros like `.Ao'; we then defer the call of `doc-xxx-list' +-. if !\n[doc-nesting-level] \ +-. doc-\*[doc-str-It] +-.. +-. +-. +-.\" NS doc-inset-list macro +-.\" NS .It item of list-type inset +-.\" NS +-.\" NS modifies: +-.\" NS doc-in-list +-. +-.de doc-inset-list +-. \" finish item box +-. br +-. ev +-. box +-. unformat doc-item-box\n[doc-list-depth] +-. +-. doc-set-vertical-and-indent 0 +-. br +-. +-. nh +-. doc-item-box\n[doc-list-depth] +-. +-. if \n[doc-in-files-section] \ +-. if n \ +-. ds doc-Pa-font "\*[doc-saved-Pa-font] +-. +-. nr doc-in-list 0 +-. doc-reset-args +-.. +-. +-. +-.\" NS doc-hang-list macro +-.\" NS .It item of list-type hanging tag (as opposed to tagged) +-.\" NS +-.\" NS modifies: +-.\" NS doc-have-space +-.\" NS doc-in-list +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dhl +-.\" NS doc-reg-dhl1 +-. +-.de doc-hang-list +-. \" finish item box +-. br +-. ev +-. box +-. unformat doc-item-box\n[doc-list-depth] +-. +-. doc-set-vertical-and-indent 1 +-. nr doc-reg-dhl (\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) +-. ti -\n[doc-reg-dhl]u +-. +-. nh +-. ie (\n[dl]u > \n[doc-list-indent-stack\n[doc-list-depth]]u) \ +-. doc-item-box\n[doc-list-depth] +-. el \{\ +-. chop doc-item-box\n[doc-list-depth] +-. nr doc-reg-dhl1 \n[.k]u +-. nop \*[doc-item-box\n[doc-list-depth]]\c +-. nop \h'|(\n[doc-reg-dhl1]u - \n[.k]u + \n[doc-reg-dhl]u)'\c +-. nr doc-have-space 1 +-. \} +-. +-. if \n[doc-in-files-section] \ +-. if n \ +-. ds doc-Pa-font "\*[doc-saved-Pa-font] +-. +-. nr doc-in-list 0 +-. doc-reset-args +-.. +-. +-. +-.\" NS doc-ohang-list macro +-.\" NS .It item of list-type overhanging tag +-.\" NS +-.\" NS modifies: +-.\" NS doc-in-list +-. +-.de doc-ohang-list +-. \" finish item box +-. br +-. ev +-. box +-. unformat doc-item-box\n[doc-list-depth] +-. +-. doc-set-vertical-and-indent 0 +-. nh +-. doc-item-box\n[doc-list-depth] +-. br +-. +-. if \n[doc-in-files-section] \ +-. if n \ +-. ds doc-Pa-font "\*[doc-saved-Pa-font] +-. +-. nr doc-in-list 0 +-. doc-reset-args +-.. +-. +-. +-.\" NS doc-item-list macro +-.\" NS .It item of list-type [empty tag] +-. +-.de doc-item-list +-. \" finish (dummy) item box +-. br +-. ev +-. box +-. +-. doc-set-vertical-and-indent 0 +-. br +-. +-. doc-reset-args +-.. +-. +-. +-.\" NS doc-enum-list-count-stackXXX global register +-.\" NS stack of current enum count values +-.\" NS +-.\" NS limit: +-.\" NS doc-list-depth +-. +-.nr doc-enum-list-count-stack1 0 +-. +-. +-.\" NS doc-enum-list macro +-.\" NS enumerated list +-.\" NS +-.\" NS modifies: +-.\" NS doc-enum-list-count-stackXXX +-.\" NS doc-in-list +-. +-.de doc-enum-list +-. nr doc-in-list 1 +-. nr doc-enum-list-count-stack\n[doc-list-depth] +1 +-\# XXX +-\#.ll \n[doc-list-indent-stack\n[doc-list-depth]]u +-\#.rj +-. nop \*[doc-tag-prefix-stack\n[doc-list-depth]]\c +-. nop \n[doc-enum-list-count-stack\n[doc-list-depth]].\& +-. doc-do-list +-.. +-. +-. +-.\" NS doc-bullet-list macro +-.\" NS bullet paragraph list +-.\" NS +-.\" NS modifies: +-.\" NS doc-in-list +-. +-.de doc-bullet-list +-. nr doc-in-list 1 +-. nop \)\*[doc-Sy-font]\[bu]\f[] +-. doc-do-list +-.. +-. +-. +-.\" NS doc-dash-list macro +-.\" NS hyphen paragraph list (sub bullet list) +-.\" NS +-.\" NS modifies: +-.\" NS doc-in-list +-. +-.de doc-dash-list +-. nr doc-in-list 1 +-. nop \)\*[doc-Sy-font]\-\f[] +-. doc-do-list +-.. +-. +-. +-.\" NS doc-do-list macro +-.\" NS .It item of list-type enum/bullet/hyphen +-. +-.als doc-do-list doc-hang-list +-. +-. +-.\" NS doc-diag-list-input-line-count global register +-.\" NS saved line number to be checked in next diag-list item +-. +-.nr doc-diag-list-input-line-count 0 +-. +-. +-.\" NS doc-diag-list macro +-.\" NS .It item of list-type diagnostic-message +-.\" NS +-.\" NS modifies: +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-diag-list-input-line-count +-. +-.de doc-diag-list +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. ie ((\n[.c] - \n[doc-diag-list-input-line-count]) > 1) \{\ +-. ie !\n[doc-compact-list-stack\n[doc-list-depth]] \ +-. doc-paragraph +-. el \ +-. br +-. \} +-. el \ +-. br +-. nr doc-diag-list-input-line-count \n[.c] +-. +-. nh +-. nop \*[doc-Sy-font]\c +-. if \n[doc-num-args] \ +-. doc-remaining-args +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\*[doc-hard-space]\c +-. +-. doc-print-and-reset +-.. +-. +-. +-.\" NS doc-tag-list macro +-.\" NS .It item of list-type `tag' +-.\" NS +-.\" NS modifies: +-.\" NS doc-have-space +-.\" NS doc-in-list +-.\" NS +-.\" NS local variables: +-.\" NS doc-box-dtl +-.\" NS doc-reg-dtl +-.\" NS doc-reg-dtl1 +-. +-.de doc-tag-list +-. \" finish item box +-. br +-. ev +-. box +-. unformat doc-item-box\n[doc-list-depth] +-. +-. \" we use a box without `.nf' to compute the tag width (via `dl' register) +-. box doc-box-dtl +-. ev doc-env-dtl +-. evc 0 +-. fi +-. ad 0 +-. in 0 +-. doc-item-box\n[doc-list-depth] +-. br +-. ev +-. box +-. +-. if !"TagwidtH"\*[doc-tag-width-stack\n[doc-list-depth]]" \{\ +-. if !\n[doc-list-have-indent-stack\n[doc-list-depth]] \{\ +-. in -(\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) +-. nr doc-list-have-indent-stack\n[doc-list-depth] 1 +-. \} +-. doc-get-tag-width +-. \} +-. doc-set-vertical-and-indent 1 +-. nr doc-reg-dtl (\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) +-. ti -\n[doc-reg-dtl]u +-. +-. nh +-. doc-item-box\n[doc-list-depth] +-. ie (\n[dl]u > \n[doc-list-indent-stack\n[doc-list-depth]]u) \ +-. br +-. el \{\ +-. \" format the tag separately to prevent stretching of spaces +-. vpt 0 +-. br +-. sp -1 +-. vpt 1 +-. nop \&\c +-. nr doc-have-space 1 +-. \} +-. +-. if \n[doc-in-files-section] \ +-. if n \ +-. ds doc-Pa-font "\*[doc-saved-Pa-font] +-. +-. nr doc-in-list 0 +-. doc-reset-args +-.. +-. +-. +-.\" NS doc-get-tag-width macro +-.\" NS resolve unknown tag width (`tag' list-type only) +-.\" NS +-.\" NS modifies: +-.\" NS doc-list-indent-stackXXX +-.\" NS doc-tag-width-stackXXX +-.\" NS +-.\" NS requires: +-.\" NS doc-curr-arg +-.\" NS doc-curr-type +-. +-.de doc-get-tag-width +-. ie (\n[doc-curr-type] == 1) \{\ +-. ds doc-tag-width-stack\n[doc-list-depth] \*[doc-curr-arg] +-. nr doc-list-indent-stack\n[doc-list-depth] \n[\*[doc-curr-arg]] +-. \} +-. el \{\ +-. ds doc-tag-width-stack\n[doc-list-depth] No +-. nr doc-list-indent-stack\n[doc-list-depth] \n[No] +-. \} +-.. +-. +-. +-.\" NS doc-set-vertical-and-indent macro +-.\" NS set up vertical spacing (if not compact) and indentation (with +-.\" NS offset if argument is non-zero) +-.\" NS +-.\" NS modifies: +-.\" NS doc-list-have-indent-stackXXX +-. +-.de doc-set-vertical-and-indent +-. if !\n[doc-compact-list-stack\n[doc-list-depth]] \ +-. sp \n[doc-display-vertical]u +-. +-. if \n[doc-list-have-indent-stack\n[doc-list-depth]] \{\ +-. nr doc-list-have-indent-stack\n[doc-list-depth] 0 +-. if \$1 \ +-. in +(\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) +-. \} +-. +-. if !\n[cR] \ +-. ne 2v +-.. +-. +-. +-.\" NS doc-list-depth global register +-.\" NS list type stack counter +-. +-.nr doc-list-depth 0 +-. +-. +-.\" NS doc-num-columns global register +-.\" NS number of columns +-. +-.nr doc-num-columns 0 +-. +-. +-.\" NS doc-compact-list-stackXXX global register (bool) +-.\" NS stack of flags to indicate whether a particular list is compact +-.\" NS +-.\" NS limit: +-.\" NS doc-list-depth +-. +-.nr doc-compact-list-stack1 0 +-. +-. +-.\" NS doc-tag-prefix-stackXXX global string +-.\" NS stack of tag prefixes (currently used for -nested -enum lists) +-.\" NS +-.\" NS limit: +-.\" NS doc-list-depth +-. +-.ds doc-tag-prefix-stack1 +-. +-. +-.\" NS doc-tag-width-stackXXX global string +-.\" NS stack of strings indicating how to set up current element of +-.\" NS doc-list-indent-stackXXX -- if set to TagwidtH, user has set it +-.\" NS directly; if it is a macro name, use the macro's width value; +-.\" NS otherwise, `doc-get-tag-width' uses width value of `No'. +-.\" NS +-.\" NS limit: +-.\" NS doc-list-depth +-. +-.ds doc-tag-width-stack0 +-.ds doc-tag-width-stack1 +-. +-. +-.\" NS doc-list-offset-stackXXX global register +-.\" NS stack of list offsets +-.\" NS +-.\" NS limit: +-.\" NS doc-list-depth +-. +-.nr doc-list-offset-stack1 0 +-. +-. +-.\" NS doc-end-list macro +-.\" NS list end function; resets indentation (and offset if argument is +-.\" NS non-zero) +-.\" NS +-.\" NS modifies: +-.\" NS doc-list-depth +-.\" NS doc-list-offset-stackXXX +-. +-.de doc-end-list +-. if \$1 \ +-' in -(\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) +-. +-' in -\n[doc-list-offset-stack\n[doc-list-depth]]u +-. +-. if (\n[doc-list-depth] <= 0) \ +-. tm mdoc warning: extraneous .El call (#\n[.c]) +-. +-. doc-decrement-list-stack +-. nr doc-list-depth -1 +-.. +-. +-. +-.\" NS doc-increment-list-stack macro +-.\" NS set up next block for list +-.\" NS +-.\" NS modifies: +-.\" NS doc-compact-list-stackXXX +-.\" NS doc-list-have-indent-stackXXX +-.\" NS doc-list-indent-stackXXX +-.\" NS doc-list-offset-stackXXX +-.\" NS doc-list-type-stackXXX +-.\" NS doc-tag-prefix-stackXXX +-.\" NS doc-tag-width-stackXXX +-.\" NS doc-enum-list-count-stackXXX +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dils +-. +-.de doc-increment-list-stack +-. nr doc-reg-dils (\n[doc-list-depth] + 1) +-. nr doc-list-have-indent-stack\n[doc-reg-dils] 0 +-. nr doc-list-indent-stack\n[doc-reg-dils] 0 +-. nr doc-list-offset-stack\n[doc-reg-dils] 0 +-. ds doc-tag-prefix-stack\n[doc-reg-dils] +-. ds doc-tag-width-stack\n[doc-reg-dils] \*[doc-tag-width-stack\n[doc-list-depth]] +-. ds doc-list-type-stack\n[doc-reg-dils] +-. nr doc-compact-list-stack\n[doc-reg-dils] 0 +-. nr doc-enum-list-count-stack\n[doc-reg-dils] 0 +-.. +-. +-. +-.\" NS doc-decrement-list-stack macro +-.\" NS decrement stack +-.\" NS +-.\" NS modifies: +-.\" NS doc-compact-list-stackXXX +-.\" NS doc-list-have-indent-stackXXX +-.\" NS doc-list-indent-stackXXX +-.\" NS doc-list-offset-stackXXX +-.\" NS doc-list-type-stackXXX +-.\" NS doc-tag-prefix-stackXXX +-.\" NS doc-tag-width-stackXXX +-.\" NS doc-enum-list-count-stackXXX +-. +-.de doc-decrement-list-stack +-. ds doc-list-type-stack\n[doc-list-depth] +-. nr doc-list-have-indent-stack\n[doc-list-depth] 0 +-. nr doc-list-indent-stack\n[doc-list-depth] 0 +-. nr doc-list-offset-stack\n[doc-list-depth] 0 +-. ds doc-tag-prefix-stack\n[doc-list-depth] +-. ds doc-tag-width-stack\n[doc-list-depth] +-. nr doc-compact-list-stack\n[doc-list-depth] 0 +-. nr doc-enum-list-count-stack\n[doc-list-depth] 0 +-.. +-. +-. +-.\" NS Xr user macro +-.\" NS cross reference (for man pages only) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-macro-name +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-Xr +-.\" NS +-.\" NS width register `Xr' set in doc-common +-. +-.de Xr +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Xr +-. doc-parse-args \$@ +-. \} +-. el \ +-. doc-Xr-usage +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. doc-print-prefixes +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. \" first argument must be a string +-. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ds doc-arg\n[doc-arg-ptr] \*[doc-Xr-font]\*[doc-arg\n[doc-arg-ptr]]\f[]\s[0] +-. +-. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ +-. nr doc-reg-Xr (\n[doc-arg-ptr] + 1) +-. \" modify second argument if it is a string and +-. \" remove space in between +-. if (\n[doc-type\n[doc-reg-Xr]] == 2) \{\ +-. ds doc-arg\n[doc-reg-Xr] \*[lp]\*[doc-arg\n[doc-reg-Xr]]\*[rp] +-. ds doc-space\n[doc-arg-ptr] +-. \} +-. \} +-. doc-print-recursive +-. \} +-. el \ +-. doc-Xr-usage +-. \} +-. el \ +-. doc-Xr-usage +-.. +-. +-. +-.\" NS doc-Xr-usage macro +-. +-.de doc-Xr-usage +-. tm Usage: .Xr manpage_name [section#] ... (#\n[.c]) +-. doc-reset-args +-.. +-. +-. +-.\" NS Sx user macro +-.\" NS cross section reference +-.\" NS +-.\" NS width register `Sx' set in doc-common +-. +-.als Sx doc-generic-macro +-.ds doc-Sx-usage section_header +-. +-. +-.\" NS doc-end-column-list macro +-.\" NS column-list end-list +-.\" NS +-.\" NS modifies: +-.\" NS doc-list-depth +-. +-.de doc-end-column-list +-. linetabs 0 +-' in -(\n[doc-list-offset-stack\n[doc-list-depth]]u + \n[doc-list-indent-stack\n[doc-list-depth]]u) +-. ta T .5i +-. fi +-. doc-decrement-list-stack +-. nr doc-list-depth -1 +-.. +-. +-. +-.\" NS doc-column-indent-width global register +-.\" NS holds the indent width for a column list +-. +-.nr doc-column-indent-width 0 +-. +-. +-.\" NS doc-set-column-tab macro +-.\" NS establish tabs for list-type column: `.doc-set-column-tab num_cols' +-.\" NS +-.\" NS modifies: +-.\" NS doc-column-indent-width +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dsct +-.\" NS doc-str-dsct +-.\" NS doc-str-dsct1 +-. +-.de doc-set-column-tab +-. ds doc-str-dsct +-. nr doc-reg-dsct 1 +-. nr doc-column-indent-width 0 +-. +-. ie (\$1 < 5) \ +-. ds doc-str-dsct1 " \" +-. el \{\ +-. ie (\$1 == 5) \ +-. ds doc-str-dsct1 " \" +-. el \{\ +-. \" XXX: this is packed abnormally close -- intercolumn width +-. \" should be configurable +-. ds doc-str-dsct1 " \" +-. \}\} +-. +-. while (\n[doc-reg-dsct] <= \$1) \{\ +-. as doc-str-dsct " +\w\*[doc-arg\n[doc-reg-dsct]]\*[doc-str-dsct1]u +-. nr doc-column-indent-width +\w\*[doc-arg\n[doc-reg-dsct]]\*[doc-str-dsct1]u +-. nr doc-reg-dsct +1 +-. \} +-. +-. ta \*[doc-str-dsct] +-' in +\n[doc-column-indent-width]u +-.. +-. +-. +-.\" NS doc-column-list macro +-.\" NS column items +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-list-indent-stackXXX +-.\" NS doc-spaceXXX +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dcl +-. +-.de doc-column-list +-. if \n[doc-num-args] \ +-. doc-parse-arg-vector +-. nr doc-arg-ptr +1 +-. +-. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ +-. tm Usage: .It column_string [Ta [column_string ...] ] (#\n[.c]) +-. return +-. \} +-. +-. if "\*[doc-arg\n[doc-arg-ptr]]"Ta" \{\ +-. nr doc-reg-dcl (\n[doc-arg-ptr] - 1) +-. ds doc-space\n[doc-reg-dcl] +-. \} +-. +-. if !\n[doc-list-indent-stack\n[doc-list-depth]] \ +-. nr doc-list-indent-stack\n[doc-list-depth] \n[doc-column-indent-width]u +-. if !\n[.u] \{\ +-. fi +-. in +\n[doc-column-indent-width]u +-. \} +-. ti -\n[doc-column-indent-width]u +-. +-. doc-do-\n[doc-type\n[doc-arg-ptr]] +-.. +-. +-. +-.\" NS Ta user macro +-.\" NS append tab (\t) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS +-.\" NS width register `Ta' set in doc-common +-. +-.de Ta +-. ie \n[doc-arg-limit] \{\ +-. nr doc-arg-ptr +1 +-. nop \*[doc-tab]\c +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ +-. doc-do-\n[doc-type\n[doc-arg-ptr]] +-. el \ +-. doc-reset-args +-. \} +-. el \{\ +-. tm1 "Usage: Ta must follow column entry: e.g. +-. tm1 " .It column_string [Ta [column_string ...]] (#\n[.c]) +-. \} +-.. +-. +-. +-.\" NS Dl user macro +-.\" NS display (one line) literal +-.\" NS +-.\" NS this function uses the `Li' font +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Dl' set in doc-common +-. +-.de Dl +-. ta T .5i +-. in +\n[doc-display-indent]u +-. +-. ie \n[doc-arg-limit] \{\ +-. tm Usage: .Dl not callable by other macros (#\n[.c]) +-. doc-reset-args +-. \} +-. el \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Dl +-. doc-parse-args \$@ +-. nr doc-arg-ptr 1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Li-font]\c +-. doc-print-recursive +-. \} +-. el \ +-. tm Usage: .Dl argument ... (#\n[.c]) +-. \} +-. +-. in -\n[doc-display-indent]u +-.. +-. +-. +-.\" NS D1 user macro +-.\" NS display (one line) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `D1' set in doc-common +-. +-.de D1 +-. ta T .5i +-. in +\n[doc-display-indent]u +-. +-. ie \n[doc-arg-limit] \{\ +-. tm Usage: .D1 not callable by other macros (#\n[.c]) +-. doc-reset-args +-. \} +-. el \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name D1 +-. doc-parse-args \$@ +-. nr doc-arg-ptr 1 +-. doc-print-recursive +-. \} +-. el \ +-. tm Usage: .D1 argument ... (#\n[.c]) +-. \} +-. +-. in -\n[doc-display-indent]u +-.. +-. +-. +-.\" NS Vt user macro +-.\" NS variable type (for forcing old style variable declarations); +-.\" NS this is not done in the same manner as .Ot for fortrash -- +-.\" NS clean up later +-.\" NS +-.\" NS modifies: +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-have-decl +-.\" NS doc-have-var +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Vt' set in doc-common +-. +-.de Vt +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Vt +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Vt variable_type ... (#\n[.c]) +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ +-. tm Usage: .Vt variable_type ... (#\n[.c]) +-. doc-reset-args +-. return +-. \} +-. +-. if \n[doc-in-synopsis-section] \{\ +-. \" if a function declaration was the last thing given, +-. \" want vertical space +-. if \n[doc-have-decl] \{\ +-. doc-paragraph +-. nr doc-have-decl 0 +-. \} +-. +-. \" if a subroutine was the last thing given, want vertical space +-. if \n[doc-have-func] \{\ +-. ie \n[doc-have-var] \ +-. br +-. el \ +-. doc-paragraph +-. \} +-. +-. nr doc-have-var 1 +-. \} +-. +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Ft-font]\c +-. doc-print-recursive +-. +-. if \n[doc-in-synopsis-section] \{\ +-. ie \n[doc-have-old-func] \ +-. nop \*[doc-soft-space]\c +-. el \ +-. br +-. \} +-.. +-. +-. +-.\" NS doc-is-func global register (bool) +-.\" NS set if subroutine (in synopsis only) (fortran only) +-. +-.nr doc-is-func 0 +-. +-. +-.\" NS Ft user macro +-.\" NS function type +-.\" NS +-.\" NS modifies: +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-have-decl +-.\" NS doc-have-var +-.\" NS doc-is-func +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Ft' set in doc-common +-. +-.de Ft +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Ft +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Ft function_type ... (#\n[.c]) +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. nr doc-arg-ptr +1 +-. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ +-. tm Usage: .Ft function_type ... (#\n[.c]) +-. doc-reset-args +-. return +-. \} +-. +-. if \n[doc-in-synopsis-section] \{\ +-. if (\n[doc-have-func] : \n[doc-have-decl]) \{\ +-. doc-paragraph +-. nr doc-have-decl 0 +-. nr doc-have-var 0 +-. \} +-. +-. if \n[doc-have-var] \{\ +-. doc-paragraph +-. nr doc-have-var 0 +-. \} +-. +-. nr doc-is-func 1 +-. \} +-. +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Ft-font]\c +-. doc-print-recursive +-.. +-. +-. +-.\" NS doc-have-old-func global register (bool) +-.\" NS set if `Ot' has been called +-. +-.nr doc-have-old-func 0 +-. +-. +-.\" NS Ot user macro +-.\" NS old function type (fortran -- no newline) +-.\" NS +-.\" NS modifies: +-.\" NS doc-have-decl +-.\" NS doc-have-old-func +-.\" NS doc-have-var +-.\" NS doc-is-func +-.\" NS +-.\" NS width register `Ot' set in doc-common +-. +-.de Ot +-. nr doc-have-old-func 1 +-. +-. if \n[doc-in-synopsis-section] \{\ +-. if (\n[doc-have-func] : \n[doc-have-decl]) \{\ +-. doc-paragraph +-. nr doc-have-decl 0 +-. nr doc-have-var 0 +-. \} +-. +-. if \n[doc-have-var] \{\ +-. doc-paragraph +-. nr doc-have-var 0 +-. \} +-. +-. nr doc-is-func 1 +-. \} +-. +-. if \n[.$] \ +-. nop \*[doc-Ft-font]\$*\c +-. nop \ \f[]\c +-.. +-. +-. +-.\" NS Fa user macro +-.\" NS function arguments +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Fa' set in doc-common +-. +-.de Fa +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Fa +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Fa function_arguments ... (#\n[.c]) +-. \} +-. +-. ie \n[doc-func-arg-count] \ +-. doc-do-func +-. el \{\ +-. nr doc-arg-ptr +1 +-. if (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Fa-font]\c +-. doc-print-recursive +-. +-. if \n[doc-in-synopsis-section] \ +-. if \n[doc-have-func] \ +-. br +-. \}\} +-.. +-. +-. +-.\" NS doc-func-arg-count global register +-.\" NS how many function arguments have been processed so far +-. +-.nr doc-func-arg-count 0 +-. +-. +-.\" NS doc-func-arg global string +-.\" NS work buffer for function name strings +-. +-.ds doc-func-arg +-. +-. +-.\" NS doc-num-func-args global register +-.\" NS number of function arguments +-. +-.nr doc-num-func-args 0 +-. +-. +-.\" NS doc-func-args-processed global register +-.\" NS function arguments processed so far +-. +-.nr doc-func-args-processed 0 +-. +-. +-.\" NS doc-do-func macro +-.\" NS internal .Fa for .Fc +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-argXXX +-.\" NS doc-func-arg +-.\" NS doc-func-arg-count +-.\" NS doc-func-args-processed +-.\" NS doc-num-func-args +-. +-.de doc-do-func +-. if (\n[doc-arg-limit] <= \n[doc-arg-ptr]) \{\ +-. doc-reset-args +-. return +-. \} +-. +-. nr doc-arg-ptr +1 +-. +-. ds doc-func-arg +-. nr doc-num-func-args 0 +-. nr doc-func-args-processed 0 +-. +-. doc-build-func-string \*[doc-arg\n[doc-arg-ptr]] +-. if (\n[doc-num-func-args] > 1) \ +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-func-arg] +-. +-. if (\n[doc-func-arg-count] > 1) \{\ +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\|\c +-. if !"\*[doc-arg\n[doc-arg-ptr]]"/*" \ +-. if !"\*[doc-arg\n[doc-arg-ptr]]"*/" \ +-. nop ,\)\c +-. nop \)\*[doc-space\n[doc-arg-ptr]]\*[doc-Fa-font]\c +-. nop \)\*[doc-arg\n[doc-arg-ptr]]\f[]\s[0]\c +-. \} +-. +-. if (\n[doc-func-arg-count] == 1) \{\ +-. nop \)\*[doc-Fa-font]\*[doc-arg\n[doc-arg-ptr]]\c +-. nop \f[]\s[0]\c +-. \} +-. nr doc-func-arg-count +1 +-. doc-do-func +-.. +-. +-. +-.\" NS doc-have-func global register (bool) +-.\" NS whether we have more than one function in synopsis +-. +-.nr doc-have-func 0 +-. +-. +-.\" NS Fn user macro +-.\" NS functions +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-have-decl +-.\" NS doc-have-func +-.\" NS doc-have-var +-.\" NS doc-indent-synopsis +-.\" NS doc-is-func +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Fn' set in doc-common +-. +-.de Fn +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Fn +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Fn function_name [function_arg] ... (#\n[.c]) +-. \} +-. +-. if !\n[doc-arg-limit] \ +-. return +-. +-. if \n[doc-in-synopsis-section] \{\ +-. \" if there is/has been more than one subroutine declaration +-. ie \n[doc-is-func] \{\ +-. br +-. nr doc-have-var 0 +-. nr doc-have-decl 0 +-. nr doc-is-func 0 +-. \} +-. el \{\ +-. if \n[doc-have-func] \{\ +-. doc-paragraph +-. nr doc-have-var 0 +-. nr doc-have-decl 0 +-. \}\} +-. +-. if \n[doc-have-decl] \{\ +-. doc-paragraph +-. nr doc-have-var 0 +-. \} +-. +-. if \n[doc-have-var] \{\ +-. doc-paragraph +-. nr doc-have-decl 0 +-. \} +-. +-. nr doc-have-func 1 +-. nr doc-is-func 0 +-. +-. br +-. if !\n[doc-indent-synopsis] \ +-. nr doc-indent-synopsis (4u * \n[doc-fixed-width]u) +-. if !\n[doc-indent-synopsis-active] \ +-. in +\n[doc-indent-synopsis]u +-. ti -\n[doc-indent-synopsis]u +-. \} +-. +-. nr doc-arg-ptr +1 +-. doc-print-prefixes +-. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ +-. tm Usage: .Fn function_name [function_arg] ... (#\n[.c]) +-. doc-reset-args +-. return +-. \} +-. +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. nop \*[doc-Fn-font]\*[doc-arg\n[doc-arg-ptr]]\c +-. nop \f[]\s[0]\*[lp]\)\c +-. +-. nr doc-arg-ptr +1 +-. if (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. if (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. nop \*[doc-Fa-font]\c +-. doc-do-func-args +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c +-. \}\} +-. +-. nop \)\*[rp]\)\c +-. if \n[doc-in-synopsis-section] \ +-. nop \);\)\c +-. +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. \" output the space (if needed) +-. nr doc-arg-ptr -1 +-. nop \)\*[doc-space\n[doc-arg-ptr]]\c +-. nr doc-arg-ptr +1 +-. +-. doc-print-recursive +-. \} +-. el \ +-. doc-print-and-reset +-. +-. if \n[doc-in-synopsis-section] \ +-. if !\n[doc-indent-synopsis-active] \ +-. in -\n[doc-indent-synopsis]u +-.. +-. +-. +-.\" NS doc-do-func-args macro +-.\" NS handle function arguments +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-argXXX +-.\" NS doc-func-arg +-.\" NS doc-func-args-processed +-.\" NS doc-num-func-args +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-ddfa +-. +-.de doc-do-func-args +-. if \n[doc-in-synopsis-section] \{\ +-. ds doc-func-arg +-. nr doc-num-func-args 0 +-. nr doc-func-args-processed 0 +-. +-. doc-build-func-string \*[doc-arg\n[doc-arg-ptr]] +-. if (\n[doc-num-func-args] > 1) \ +-. ds doc-arg\n[doc-arg-ptr] "\*[doc-func-arg] +-. \} +-. +-. nop \)\*[doc-arg\n[doc-arg-ptr]]\c +-. nr doc-arg-ptr +1 +-. +-. if (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. if (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ +-. nr doc-reg-ddfa (\n[doc-arg-ptr] - 1) +-. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\|\c +-. if !"\*[doc-arg\n[doc-arg-ptr]]"/*" \ +-. if !"\*[doc-arg\n[doc-arg-ptr]]"*/" \ +-. nop ,\)\c +-. nop \)\*[doc-space\n[doc-reg-ddfa]]\f[]\s[0]\|\c +-. doc-do-func-args +-. \}\} +-.. +-. +-. +-.\" NS doc-saved-nesting-level global register +-. +-.nr doc-saved-nesting-level 0 +-. +-. +-.\" NS doc-in-func-enclosure global register (bool) +-. +-.nr doc-in-func-enclosure 0 +-. +-. +-.\" NS Fo user macro +-.\" NS function open +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-func-arg-count +-.\" NS doc-have-decl +-.\" NS doc-have-func +-.\" NS doc-have-var +-.\" NS doc-in-func-enclosure +-.\" NS doc-indent-synopsis +-.\" NS doc-is-func +-.\" NS doc-macro-name +-.\" NS doc-saved-nesting-level +-.\" NS +-.\" NS width register `Fo' set in doc-common +-. +-.de Fo +-. if (\n[doc-in-func-enclosure]) \{\ +-. tm mdoc error: .Fo/.Fc can't be nested (#\n[.c]) +-. return +-. \} +-. +-. nr doc-saved-nesting-level \n[doc-nesting-level] +-. nr doc-in-func-enclosure 1 +-. +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ds doc-macro-name Fo +-. doc-parse-args \$@ +-. \} +-. el \ +-. tm Usage: .Fo function_name (#\n[.c]) +-. \} +-. +-. if \n[doc-in-synopsis-section] \{\ +-. \" if there is/has been more than one subroutine declaration +-. ie \n[doc-is-func] \{\ +-. br +-. nr doc-have-var 0 +-. nr doc-have-decl 0 +-. nr doc-is-func 0 +-. \} +-. el \{\ +-. if \n[doc-have-func] \{\ +-. doc-paragraph +-. nr doc-have-var 0 +-. nr doc-have-decl 0 +-. \}\} +-. +-. if \n[doc-have-decl] \{\ +-. doc-paragraph +-. nr doc-have-var 0 +-. \} +-. +-. if \n[doc-have-var] \{\ +-. doc-paragraph +-. nr doc-have-decl 0 +-. \} +-. +-. nr doc-have-func 1 +-. nr doc-is-func 0 +-. +-. br +-. if !\n[doc-indent-synopsis] \ +-. nr doc-indent-synopsis (4u * \n[doc-fixed-width]u) +-. \} +-. +-. \" start function box +-. box doc-func-box +-. ev doc-func-env +-. evc 0 +-. in 0 +-. nf +-. +-. nr doc-arg-ptr +1 +-. doc-print-prefixes +-. if (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-func-arg-count 1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. nop \*[doc-Fn-font]\*[doc-arg\n[doc-arg-ptr]]\c +-. nop \f[]\s[0]\*[lp]\)\c +-. doc-reset-args +-. \} +-.. +-. +-. +-.\" NS Fc user macro +-.\" NS function close +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-func-arg-count +-.\" NS doc-in-func-enclosure +-.\" NS doc-saved-nesting-level +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `Fc' set in doc-common +-. +-.de Fc +-. if !\n[doc-in-func-enclosure] \{\ +-. tm mdoc warning: Extraneous .Fc (#\n[.c]) +-. return +-. \} +-. +-. if \n[.$] \{\ +-. ds doc-macro-name Fc +-. \" the first (dummy) argument is used to get the correct spacing +-. doc-parse-args \) \$@ +-. \} +-. +-. if !(\n[doc-saved-nesting-level] == \n[doc-nesting-level]) \ +-. tm mdoc warning: Unbalanced enclosure commands within .Fo/.Fc +-. +-. nr doc-func-arg-count 0 +-. nr doc-in-func-enclosure 0 +-. +-. ie \n[doc-in-synopsis-section] \ +-. nop \|\*[rp];\) +-. el \ +-. nop \|\*[rp]\) +-. +-. \" finish function box +-. br +-. ev +-. box +-. chop doc-func-box +-. unformat doc-func-box +-. +-. if \n[doc-in-synopsis-section] \{\ +-. if !\n[doc-indent-synopsis-active] \ +-. in +\n[doc-indent-synopsis]u +-. ti -\n[doc-indent-synopsis]u +-. \} +-. +-. nh +-. nop \*[doc-func-box]\c +-. +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. doc-print-recursive +-. \} +-. el \ +-. doc-print-and-reset +-. +-. if \n[doc-in-synopsis-section] \ +-. if !\n[doc-indent-synopsis-active] \ +-. in -\n[doc-indent-synopsis]u +-.. +-. +-. +-.\" NS doc-build-func-string macro +-.\" NS collect function arguments and set hard spaces in between +-.\" NS +-.\" NS modifies: +-.\" NS doc-func-arg +-.\" NS doc-func-args-processed +-.\" NS doc-num-func-args +-. +-.de doc-build-func-string +-. if !\n[doc-num-func-args] \{\ +-. nr doc-num-func-args \n[.$] +-. nr doc-func-args-processed 0 +-. ds doc-func-arg +-. \} +-. +-. nr doc-func-args-processed +1 +-. as doc-func-arg "\$1 +-. +-. if (\n[doc-func-args-processed] < \n[doc-num-func-args]) \{\ +-. as doc-func-arg "\*[doc-hard-space] +-. +-. shift +-. doc-build-func-string \$@ +-. \} +-.. +-. +-. +-.\" Very crude references: Stash all reference info into boxes, print out +-.\" reference on .Re macro and clean up. Ordering very limited, no fancy +-.\" citations, but can do articles, journals, and books -- need to add +-.\" several missing options (like city etc). Should be able to grab a refer +-.\" entry, massage it a wee bit (prefix a `.' to the %[A-Z]) and not worry +-.\" (ha!). +-. +-. +-.\" NS doc-is-reference global register (bool) +-.\" NS set if in reference +-. +-.nr doc-is-reference 0 +-. +-. +-.\" NS doc-reference-count global register +-.\" NS reference element counter +-. +-.nr doc-reference-count 0 +-. +-. +-.\" NS Rs user macro +-.\" NS reference start +-.\" NS +-.\" NS modifies: +-.\" NS doc-is-reference +-.\" NS doc-reference-count +-.\" NS +-.\" NS width register `Rs' set in doc-common +-. +-.de Rs +-. ie \n[.$] \ +-. tm Usage: .Rs (does not take arguments) (#\n[.c]) +-. el \{\ +-. nr doc-is-reference 1 +-. doc-reset-reference +-. if \n[doc-in-see-also-section] \ +-. doc-paragraph +-. nr doc-reference-count 0 +-. \} +-.. +-. +-. +-.\" NS Re user macro +-.\" NS reference end +-.\" NS +-.\" NS modifies: +-.\" NS doc-is-reference +-.\" NS +-.\" NS width register `Re' set in doc-common +-. +-.de Re +-. ie \n[.$] \ +-. tm Usage: .Re (does not take arguments) (#\n[.c]) +-. el \{\ +-. if !\n[doc-is-reference] \{\ +-. tm mdoc warning: Extraneous .Re (#\n[.c]) +-. return +-. \} +-. doc-print-reference +-. doc-reset-reference +-. nr doc-is-reference 0 +-. \} +-.. +-. +-. +-.\" NS doc-reset-reference macro +-.\" NS reference cleanup +-.\" NS +-.\" NS modifies: +-.\" NS doc-author-count +-.\" NS doc-author-nameXXX +-.\" NS doc-book-count +-.\" NS doc-book-name +-.\" NS doc-city-count +-.\" NS doc-city-name +-.\" NS doc-corporate-count +-.\" NS doc-corporate-name +-.\" NS doc-date +-.\" NS doc-date-count +-.\" NS doc-issue-count +-.\" NS doc-issue-name +-.\" NS doc-journal-count +-.\" NS doc-journal-name +-.\" NS doc-optional-count +-.\" NS doc-optional-string +-.\" NS doc-page-number-count +-.\" NS doc-page-number-string +-.\" NS doc-publisher-count +-.\" NS doc-publisher-name +-.\" NS doc-reference-count +-.\" NS doc-reference-title-count +-.\" NS doc-reference-title-name +-.\" NS doc-reference-title-name-for-book +-.\" NS doc-report-count +-.\" NS doc-report-name +-.\" NS doc-url-count +-.\" NS doc-url-name +-.\" NS doc-volume-count +-.\" NS doc-volume-name +-. +-.de doc-reset-reference +-. while (\n[doc-author-count]) \{\ +-. ds doc-author-name\n[doc-author-count] +-. nr doc-author-count -1 +-. \} +-. nr doc-journal-count 0 +-. nr doc-issue-count 0 +-. nr doc-optional-count 0 +-. nr doc-corporate-count 0 +-. nr doc-report-count 0 +-. nr doc-reference-title-count 0 +-. nr doc-url-count 0 +-. nr doc-volume-count 0 +-. nr doc-city-count 0 +-. nr doc-date-count 0 +-. nr doc-page-number-count 0 +-. nr doc-book-count 0 +-. nr doc-publisher-count 0 +-. nr doc-reference-count 0 +-. +-. ds doc-journal-name +-. ds doc-issue-name +-. ds doc-optional-string +-. ds doc-corporate-name +-. ds doc-report-name +-. ds doc-reference-title-name +-. ds doc-reference-title-name-for-book +-. ds doc-url-name +-. ds doc-volume-name +-. ds doc-city-name +-. ds doc-date +-. ds doc-page-number-string +-. ds doc-book-name +-. ds doc-publisher-name +-.. +-. +-. +-.\" NS doc-finish-reference macro +-.\" NS auxiliary macro for doc-print-reference +-.\" NS +-.\" NS modifies: +-.\" NS doc-reference-count +-. +-.de doc-finish-reference +-. nr doc-reference-count -\$1 +-. ie \n[doc-reference-count] \ +-. nop \), +-. el \ +-. nop \). +-.. +-. +-. +-.\" NS doc-print-reference macro +-.\" NS reference print +-.\" NS +-.\" NS modifies: +-.\" NS doc-reference-count +-. +-.de doc-print-reference +-. +-. nh +-. +-. if \n[doc-author-count] \{\ +-. doc-print-reference-authors +-. nr doc-reference-count -\n[doc-author-count] +-. \} +-. +-. if \n[doc-reference-title-count] \{\ +-. unformat doc-reference-title-name +-. chop doc-reference-title-name +-. unformat doc-reference-title-name-for-book +-. chop doc-reference-title-name-for-book +-. ie ((\n[doc-journal-count] == 1) : (\n[doc-book-count] == 1)) \{\ +-. nop \)\*[q]\)\*[doc-reference-title-name-for-book]\)\*[q]\c +-. doc-finish-reference \n[doc-reference-title-count] +-. \} +-. el \{\ +-. nop \*[doc-reference-title-name]\c +-. doc-finish-reference \n[doc-reference-title-count] +-. \}\} +-. +-. if \n[doc-book-count] \{\ +-. unformat doc-book-name +-. chop doc-book-name +-. nop \*[doc-book-name]\c +-. doc-finish-reference \n[doc-book-count] +-. \} +-. +-. if \n[doc-publisher-count] \{\ +-. unformat doc-publisher-name +-. chop doc-publisher-name +-. nop \*[doc-publisher-name]\c +-. doc-finish-reference \n[doc-publisher-count] +-. \} +-. +-. if \n[doc-journal-count] \{\ +-. unformat doc-journal-name +-. chop doc-journal-name +-. nop \*[doc-journal-name]\c +-. doc-finish-reference \n[doc-journal-count] +-. \} +-. +-. if \n[doc-report-count] \{\ +-. unformat doc-report-name +-. chop doc-report-name +-. nop \*[doc-report-name]\c +-. doc-finish-reference \n[doc-report-count] +-. \} +-. +-. if \n[doc-issue-count] \{\ +-. unformat doc-issue-name +-. chop doc-issue-name +-. nop \*[doc-issue-name]\c +-. doc-finish-reference \n[doc-issue-count] +-. \} +-. +-. if \n[doc-volume-count] \{\ +-. unformat doc-volume-name +-. chop doc-volume-name +-. nop \*[doc-volume-name]\c +-. doc-finish-reference \n[doc-volume-count] +-. \} +-. +-. if \n[doc-url-count] \{\ +-. unformat doc-url-name +-. chop doc-url-name +-. nop \*[doc-url-name]\c +-. doc-finish-reference \n[doc-url-count] +-. \} +-. +-. if \n[doc-page-number-count] \{\ +-. unformat doc-page-number-string +-. chop doc-page-number-string +-. nop \*[doc-page-number-string]\c +-. doc-finish-reference \n[doc-page-number-count] +-. \} +-. +-. if \n[doc-corporate-count] \{\ +-. unformat doc-corporate-name +-. chop doc-corporate-name +-. nop \*[doc-corporate-name]\c +-. doc-finish-reference \n[doc-corporate-count] +-. \} +-. +-. if \n[doc-city-count] \{\ +-. unformat doc-city-name +-. chop doc-city-name +-. nop \*[doc-city-name]\c +-. doc-finish-reference \n[doc-city-count] +-. \} +-. +-. if \n[doc-date-count] \{\ +-. unformat doc-date +-. chop doc-date +-. nop \*[doc-date]\c +-. doc-finish-reference \n[doc-date-count] +-. \} +-. +-. if \n[doc-optional-count] \{\ +-. unformat doc-optional-string +-. chop doc-optional-string +-. nop \*[doc-optional-string]\c +-. doc-finish-reference \n[doc-optional-count] +-. \} +-. +-. if \n[doc-reference-count] \ +-. tm mdoc warning: unresolved reference problem +-. +-. hy \n[doc-hyphen-flags] +-.. +-. +-. +-.\" NS doc-print-reference-authors macro +-.\" NS print out reference authors +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-dpra +-.\" NS doc-str-dpra +-. +-.ds doc-str-dpra "and +-. +-.de doc-print-reference-authors +-. nr doc-reg-dpra 1 +-. +-. while (\n[doc-reg-dpra] < \n[doc-author-count]) \{\ +-. unformat doc-author-name\n[doc-reg-dpra] +-. chop doc-author-name\n[doc-reg-dpra] +-. ie (\n[doc-author-count] > 2) \ +-. nop \)\*[doc-author-name\n[doc-reg-dpra]], +-. el \ +-. nop \)\*[doc-author-name\n[doc-reg-dpra]] +-. nr doc-reg-dpra +1 +-. \} +-. +-. unformat doc-author-name\n[doc-reg-dpra] +-. chop doc-author-name\n[doc-reg-dpra] +-. if (\n[doc-author-count] > 1) \ +-. nop \)\*[doc-str-dpra] +-. nop \)\*[doc-author-name\n[doc-reg-dpra]], +-.. +-. +-. +-.\" NS doc-author-count global register +-.\" NS counter of author references +-. +-.nr doc-author-count 0 +-. +-. +-.\" NS doc-author-nameXXX global box +-.\" NS array of author names +-.\" NS +-.\" NS limit: +-.\" NS doc-author-count +-. +-.ds doc-author-name0 +-. +-. +-.\" NS %A user macro +-.\" NS reference author(s) +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-author-count +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%A +-.\" NS +-.\" NS width register `%A' set in doc-common +-. +-.de %A +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%A author_name ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-author-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %A +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" save to reference box +-. box doc-author-name\n[doc-author-count] +-. ev doc-env-%A +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS doc-book-count global register +-.\" NS counter of book references +-. +-.nr doc-book-count 0 +-. +-. +-.\" NS doc-book-name global box +-.\" NS string of collected book references +-. +-.ds doc-book-name +-. +-. +-.\" NS %B user macro +-.\" NS [reference] book name +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-book-count +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%B +-.\" NS +-.\" NS width register `%B' set in doc-common +-. +-.de %B +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%B book_name ... (#\n[.c]) +-. return +-. \} +-. +-. if \n[doc-is-reference] \{\ +-. nr doc-book-count +1 +-. nr doc-reference-count +1 +-. \} +-. +-. ds doc-macro-name %B +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. ie \n[doc-is-reference] \{\ +-. \" append to reference box +-. boxa doc-book-name +-. ev doc-env-%B +-. evc 0 +-. in 0 +-. nf +-. nop \*[doc-Em-font]\c +-. doc-do-references +-. \} +-. el \{\ +-. nop \*[doc-Em-font]\c +-. doc-print-recursive +-. \} +-.. +-. +-. +-.\" NS doc-city-count global register +-.\" NS counter of city references +-. +-.nr doc-city-count 0 +-. +-. +-.\" NS doc-city-name global box +-.\" NS string of collected city references +-. +-.ds doc-city-name +-. +-. +-.\" NS %C user macro +-.\" NS [reference] city +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-city-count +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%C +-.\" NS +-.\" NS width register `%C' set in doc-common +-. +-.de %C +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%C city_name ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-city-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %C +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-city-name +-. ev doc-env-%C +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS doc-date-count global register +-.\" NS counter of date references +-. +-.nr doc-date-count 0 +-. +-. +-.\" NS doc-date global box +-.\" NS string of collected date references +-. +-.ds doc-date +-. +-. +-.\" NS %D user macro +-.\" NS [reference] date +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-date-count +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%D +-.\" NS +-.\" NS width register `%D' set in doc-common +-. +-.de %D +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%D date ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-date-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %D +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-date +-. ev doc-env-%D +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS doc-publisher-count global register +-.\" NS counter of publisher references +-. +-.nr doc-publisher-count 0 +-. +-. +-.\" NS doc-publisher-name global box +-.\" NS string of collected publisher references +-. +-.ds doc-publisher-name +-. +-. +-.\" NS %I user macro +-.\" NS [reference] issuer/publisher name +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-publisher-count +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%I +-.\" NS +-.\" NS width register `%I' set in doc-common +-. +-.de %I +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%I issuer/publisher_name ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-publisher-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %I +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-publisher-name +-. ev doc-env-%I +-. evc 0 +-. in 0 +-. nf +-. nop \*[doc-Em-font]\c +-. doc-do-references +-.. +-. +-. +-.\" NS doc-journal-count global register +-.\" NS counter of journal references +-. +-.nr doc-journal-count 0 +-. +-. +-.\" NS doc-journal-name global box +-.\" NS string of collected journal references +-. +-.ds doc-journal-name +-. +-. +-.\" NS %J user macro +-.\" NS [reference] Journal Name +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-journal-count +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%J +-.\" NS +-.\" NS width register `%J' set in doc-common +-. +-.de %J +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%J journal_name ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-journal-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %J +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-journal-name +-. ev doc-env-%J +-. evc 0 +-. in 0 +-. nf +-. nop \*[doc-Em-font]\c +-. doc-do-references +-.. +-. +-. +-.\" NS doc-issue-count global register +-.\" NS counter of issue number references +-. +-.nr doc-issue-count 0 +-. +-. +-.\" NS doc-issue-name global box +-.\" NS string of collected issue number references +-. +-.ds doc-issue-name +-. +-. +-.\" NS %N user macro +-.\" NS [reference] issue number +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-issue-count +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%N +-.\" NS +-.\" NS width register `%N' set in doc-common +-. +-.de %N +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%N issue_number ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-issue-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %N +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-issue-name +-. ev doc-env-%N +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS doc-optional-count global register +-.\" NS counter of optional information references +-. +-.nr doc-optional-count 0 +-. +-. +-.\" NS doc-optional-string global box +-.\" NS string of collected optional information references +-. +-.ds doc-optional-string +-. +-. +-.\" NS %O user macro +-.\" NS [reference] optional information +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-optional-count +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%O +-.\" NS +-.\" NS width register `%O' set in doc-common +-. +-.de %O +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%O optional_information ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-optional-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %O +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-optional-string +-. ev doc-env-%O +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS doc-page-number-count global register +-.\" NS counter of page number references +-. +-.nr doc-page-number-count 0 +-. +-. +-.\" NS doc-page-number-string global box +-.\" NS string of collected page number references +-. +-.ds doc-page-number-string +-. +-. +-.\" NS %P user macro +-.\" NS [reference] page numbers +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-page-number-count +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%P +-.\" NS +-.\" NS width register `%P' set in doc-common +-. +-.de %P +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%P page_number ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-page-number-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %P +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-page-number-string +-. ev doc-env-%P +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS doc-corporate-count global register +-.\" NS counter of corporate references +-. +-.nr doc-corporate-count 0 +-. +-. +-.\" NS doc-corporate-name global box +-.\" NS string of collected corporate references +-. +-.ds doc-corporate-name +-. +-. +-.\" NS %Q user macro +-.\" NS corporate or foreign author +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-corporate-count +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%Q +-.\" NS +-.\" NS width register `%Q' set in doc-common +-. +-.de %Q +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%Q corporate_or_foreign_author ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-corporate-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %Q +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-corporate-name +-. ev doc-env-%Q +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS doc-report-count global register +-.\" NS counter of report references +-. +-.nr doc-report-count 0 +-. +-. +-.\" NS doc-report-name global box +-.\" NS string of collected report references +-. +-.ds doc-report-name +-. +-. +-.\" NS %R user macro +-.\" NS [reference] report name +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS doc-report-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%R +-.\" NS +-.\" NS width register `%R' set in doc-common +-. +-.de %R +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%R reference_report ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-report-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %R +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-report-name +-. ev doc-env-%R +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS doc-reference-title-count global register +-.\" NS counter of reference title references +-. +-.nr doc-reference-title-count 0 +-. +-. +-.\" NS doc-reference-title-name global box +-.\" NS string of collected reference title references +-. +-.ds doc-reference-title-name +-. +-. +-.\" NS doc-reference-title-name-for-book global box +-.\" NS string of collected reference title references +-.\" NS (saved with another font; this is a shortcoming of groff) +-. +-.ds doc-reference-title-name-for-book +-. +-. +-.\" NS %T user macro +-.\" NS reference title +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-reference-title-count +-.\" NS doc-report-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%T +-.\" NS +-.\" NS width register `%T' set in doc-common +-. +-.de %T +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%T reference_title ... (#\n[.c]) +-. return +-. \} +-. +-. if \n[doc-is-reference] \{\ +-. nr doc-reference-title-count +1 +-. nr doc-reference-count +1 +-. \} +-. +-. ds doc-macro-name %T +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. ie \n[doc-is-reference] \{\ +-. \" append to reference box +-. boxa doc-reference-title-name-for-book +-. ev doc-env-%T +-. evc 0 +-. in 0 +-. nf +-. nop \*[doc-No-font]\c +-. doc-do-references +-. +-. \" do it a second time with another font +-. ds doc-macro-name %T +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. boxa doc-reference-title-name +-. ev doc-env-%T +-. evc 0 +-. in 0 +-. nf +-. nop \*[doc-Em-font]\c +-. doc-do-references +-. \} +-. el \{\ +-. nop \*[doc-Em-font]\c +-. doc-print-recursive +-. \} +-.. +-. +-. +-.\" NS doc-url-count global register +-.\" NS counter of hypertext references +-. +-.nr doc-url-count 0 +-. +-. +-.\" NS doc-url-name global box +-.\" NS string of collected hypertext references +-. +-.ds doc-url-name +-. +-. +-.\" NS doc-volume-count global register +-.\" NS counter of reference title references +-. +-.nr doc-volume-count 0 +-. +-. +-.\" NS doc-volume-name global box +-.\" NS string of collected volume references +-. +-.ds doc-volume-name +-. +-. +-.\" NS %U user macro +-.\" NS hypertext reference +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS doc-url-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%U +-.\" NS +-.\" NS width register `%U' set in doc-common +-. +-.de %U +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%U URL ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-url-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %U +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-url-name +-. ev doc-env-%U +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS %V user macro +-.\" NS reference volume +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-macro-name +-.\" NS doc-reference-count +-.\" NS doc-volume-count +-.\" NS +-.\" NS local variables: +-.\" NS doc-env-%V +-.\" NS +-.\" NS width register `%V' set in doc-common +-. +-.de %V +-. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ +-. tm Usage: .%V volume ... (#\n[.c]) +-. return +-. \} +-. +-. nr doc-volume-count +1 +-. nr doc-reference-count +1 +-. +-. ds doc-macro-name %V +-. doc-parse-args \$@ +-. +-. nr doc-arg-ptr +1 +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. +-. \" append to reference box +-. boxa doc-volume-name +-. ev doc-env-%V +-. evc 0 +-. in 0 +-. nf +-. doc-do-references +-.. +-. +-. +-.\" NS doc-do-references macro +-.\" NS reference recursion routine +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-ddr +-.\" NS doc-reg-ddr1 +-. +-.de doc-do-references +-. if !\n[doc-is-reference] \ +-. tm mdoc error: .\*[doc-macro-name] found outside of .Rs ... .Re (#\n[.c]) +-. +-. nr doc-reg-ddr1 \n[doc-type\n[doc-arg-ptr]] +-. +-. ie (\n[doc-reg-ddr1] == 1) \{\ +-. \" .nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c +-. doc-append-arg \c 3 +-. \*[doc-arg\n[doc-arg-ptr]] +-. \} +-. el \{\ +-. nop \)\*[doc-arg\n[doc-arg-ptr]]\c +-. +-. ie (\n[doc-arg-limit] == \n[doc-arg-ptr]) \{\ +-. \" finish reference box +-. br +-. ev +-. boxa +-. +-. doc-reset-args +-. \} +-. el \{\ +-. nr doc-reg-ddr \n[doc-arg-ptr] +-. nr doc-arg-ptr +1 +-. nop \)\*[doc-space\n[doc-reg-ddr]]\c +-. doc-do-references +-. \}\} +-.. +-. +-. +-.\" NS Hf user macro +-.\" NS source include header files. +-.\" NS +-.\" NS modifies: +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS +-.\" NS width register `Hf' set in doc-common +-. +-.de Hf +-. ie ((\n[.$] == 1) & (\n[doc-arg-limit] == 0)) \{\ +-. doc-paragraph +-. nop File: +-. Pa \$1 +-. +-. Bd -literal +-. so \$1 +-. Ed +-. +-. doc-paragraph +-. \} +-. el \ +-. Usage: .Hf file (#\n[.c]) +-.. +-. +-. +-.\" NS doc-have-author global register (bool) +-.\" NS set in `An' +-. +-.nr doc-have-author 0 +-. +-. +-.\" NS An user macro +-.\" NS author name +-.\" NS +-.\" NS modifies: +-.\" NS doc-arg-ptr +-.\" NS doc-curr-font +-.\" NS doc-curr-size +-.\" NS doc-have-author +-.\" NS doc-macro-name +-.\" NS +-.\" NS width register `An' set in doc-common +-. +-.de An +-. if !\n[doc-arg-limit] \{\ +-. ie \n[.$] \{\ +-. ie "\$1"-nosplit" \ +-. nr doc-in-authors-section 0 +-. el \{ .ie "\$1"-split" \ +-. nr doc-in-authors-section 1 +-. el \{\ +-. ds doc-macro-name An +-. doc-parse-args \$@ +-. \}\}\} +-. el \{\ +-. tm1 "Usage: .An {-nosplit | -split} +-. tm1 " .An author_name ... (#\n[.c]) +-. \}\} +-. +-. if \n[doc-in-authors-section] \{\ +-. ie \n[doc-have-author] \ +-. br +-. el \ +-. nr doc-have-author 1 +-. \} +-. +-. if \n[doc-arg-limit] \{\ +-. nr doc-arg-ptr +1 +-. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ +-. nr doc-curr-font \n[.f] +-. nr doc-curr-size \n[.ps] +-. doc-print-recursive +-. \} +-. el \{\ +-. tm Usage: .An author_name ... (#\n[.c]) +-. doc-reset-args +-. \}\} +-.. +-. +-. +-.\" NS Rv user macro +-.\" NS return values +-.\" NS +-.\" NS width register `Rv' set in doc-common +-.\" NS +-.\" NS local variables: +-.\" NS doc-str-Rv-std-prefix +-.\" NS doc-str-Rv-std-suffix +-.\" NS doc-str-Rv-stds-prefix +-.\" NS doc-str-Rv-stds-and +-.\" NS doc-str-Rv-stds-suffix +-.\" NS doc-str-Rv-std0 +-. +-.ds doc-str-Rv-std-prefix "The +-.ds doc-str-Rv-std-suffix "function returns the value\~0 if successful; +-.as doc-str-Rv-std-suffix " otherwise the value\~\-1 is returned and +-.as doc-str-Rv-std-suffix " the global variable \*[doc-Va-font]errno\f[] +-.as doc-str-Rv-std-suffix " is set to indicate the error. +-. +-.ds doc-str-Rv-stds-prefix "The +-.ds doc-str-Rv-stds-and "and +-.ds doc-str-Rv-stds-suffix "functions return the value\~0 if successful; +-.as doc-str-Rv-stds-suffix " otherwise the value\~\-1 is returned and +-.as doc-str-Rv-stds-suffix " the global variable \*[doc-Va-font]errno\f[] +-.as doc-str-Rv-stds-suffix " is set to indicate the error. +-. +-.ds doc-str-Rv-std0 "Upon successful completion, the value\~0 is returned; +-.as doc-str-Rv-std0 " otherwise the value\~\-1 is returned and +-.as doc-str-Rv-std0 " the global variable \*[doc-Va-font]errno\f[] +-.as doc-str-Rv-std0 " is set to indicate the error. +-. +-.de Rv +-. +-.\" XXX: what does this function without `-std'? +-. +-. if \n[doc-arg-limit] \{\ +-. tm Usage: .Rv not callable by other macros (#\n[.c]) +-. doc-reset-args +-. return +-. \} +-. +-. if !\n[.$] \{\ +-. tm Usage: .Rv [-std] [ ...] (#\n[.c]) +-. return +-. \} +-. +-. if "\$1"-std" \{\ +-. nr doc-reg-Rv \*[doc-section] +-. if ((\n[doc-reg-Rv] < 2) : (\n[doc-reg-Rv] > 3)) \ +-. tm Usage: .Rv -std in sections 2 and 3 only (#\n[.c]) +-. br +-. shift +-. ie (\n[.$] > 1) \{\ +-. nop \)\*[doc-str-Rv-stds-prefix] +-. nr doc-reg-Rv 1 +-. while (\n[doc-reg-Rv] < \n[.$]) \{\ +-. ie (\n[.$] > 2) \ +-. Fn \$\n[doc-reg-Rv] , +-. el \ +-. Fn \$\n[doc-reg-Rv] +-. nr doc-reg-Rv +1 +-. \} +-. nop \)\*[doc-str-Rv-stds-and] +-. Fn \$\n[.$] +-. nop \)\*[doc-str-Rv-stds-suffix] +-. \} +-. el \{ .ie (\n[.$] == 1) \{\ +-. nop \)\*[doc-str-Rv-std-prefix] +-. Fn \$1 +-. nop \)\*[doc-str-Rv-std-suffix] +-. \} +-. el \{\ +-. nop \)\*[doc-str-Rv-std0] +-. \}\}\} +-.. +-. +-. +-.\" NS Ex user macro +-.\" NS exit status +-.\" NS +-.\" NS width register `Ex' set in doc-common +-.\" NS +-.\" NS local variables: +-.\" NS doc-str-Ex-std-prefix +-.\" NS doc-str-Ex-std-suffix +-. +-.ds doc-str-Ex-std-prefix "The +-.ds doc-str-Ex-std-suffix "utility exits\~0 on success, +-.as doc-str-Ex-std-suffix " and\~>0 if an error occurs. +-. +-.ds doc-str-Ex-stds-prefix "The +-.als doc-str-Ex-stds-and doc-str-Rv-stds-and +-.ds doc-str-Ex-stds-suffix "utilities exit\~0 on success, +-.as doc-str-Ex-stds-suffix " and\~>0 if an error occurs. +-. +-.de Ex +-. +-.\" XXX: what does this function without `-std'? +-. +-. if \n[doc-arg-limit] \{\ +-. tm Usage: .Ex not callable by other macros (#\n[.c]) +-. doc-reset-args +-. return +-. \} +-. +-. if !\n[.$] \{\ +-. tm Usage: .Ex [-std] [ ...] (#\n[.c]) +-. return +-. \} +-. +-. if "\$1"-std" \{\ +-. nr doc-reg-Ex \*[doc-section] +-. if !((\n[doc-reg-Ex] == 1) : (\n[doc-reg-Ex] == 6) : (\n[doc-reg-Ex] == 8)) \ +-. tm Usage: .Ex -std in sections 1, 6 and 8 only (#\n[.c]) +-. br +-. shift +-. ie (\n[.$] > 1) \{\ +-. nop \)\*[doc-str-Ex-stds-prefix] +-. nr doc-reg-Ex 1 +-. while (\n[doc-reg-Ex] < \n[.$]) \{\ +-. ie (\n[.$] > 2) \ +-. Nm \$\n[doc-reg-Ex] , +-. el \ +-. Nm \$\n[doc-reg-Ex] +-. nr doc-reg-Ex +1 +-. \} +-. nop \)\*[doc-str-Ex-stds-and] +-. Nm \$\n[.$] +-. nop \)\*[doc-str-Ex-stds-suffix] +-. \} +-. el \{\ +-. nop \)\*[doc-str-Ex-std-prefix] +-. Nm \$1 +-. nop \)\*[doc-str-Ex-std-suffix] +-. \}\} +-.. +-. +-. +-.\" NS Mt user macro +-.\" NS mailto (for conversion to HTML) +-. +-.de Mt +-. \" XXX: error handling missing +-. Pa \$@ +-.. +-. +-. +-.\" NS Lk user macro +-.\" NS link (for conversion to HTML) +-.\" NS +-.\" NS local variables: +-.\" NS doc-reg-Lk +-.\" NS doc-str-Lk +-. +-.de Lk +-. ds doc-str-Lk Sy \$@ +-. +-. ie (\n[.$] > 1) \{\ +-. doc-get-arg-type \$2 +-. ie (\n[doc-arg-type] < 3) \{\ +-. Em \)\$2: +-. ds doc-str-Lk Sy "\$1" +-. doc-get-width "\$1" +-. shift 2 +-. if \n[.$] \ +-. as doc-str-Lk " \$@ +-. \} +-. el \ +-. doc-get-width "\$1" +-. \} +-. el \ +-. doc-get-width "\$1" +-. +-. ie n \ +-. nr doc-reg-Lk 26 +-. el \ +-. nr doc-reg-Lk 38 +-. ie (\n[doc-width] >= \n[doc-reg-Lk]) \ +-. D1 \*[doc-str-Lk] +-. el \ +-. \*[doc-str-Lk] +-.. +-. +-. +-.\" NS doc-defunct-macro macro +-.\" NS this is the skeleton for defunct macros +-.\" NS +-. +-.de doc-defunct-macro +-. tmc mdoc error: .\$0 defunct +-. if d doc-\$0-usage \ +-. tmc , \*[doc-\$0-usage] +-. tm1 " (#\n[.c]) +-.. +-. +-. +-.\" obsolete macros +-. +-.als Db doc-defunct-macro +-. +-.als Ds doc-defunct-macro +-. +-.als Or doc-defunct-macro +-.ds doc-Or-usage use `|' +-. +-.als Sf doc-defunct-macro +-.ds doc-Sf-usage use .Pf or .Ns +-. +-. +-.rn em e@ +-. +-.de em +-. tm1 "mdoc error: end-macro (.em) respecification is not allowed. (#\n[.c]) +-. tm1 " Should this have been `.Em ...'? +-. ab +-.. +-. +-. +-.\" NS doc-empty-line macro +-.\" NS emit warning and print empty line +-. +-.de doc-empty-line +-. if !\n[doc-display-depth] \ +-. tm mdoc warning: Empty input line #\n[.c] +-. sp +-.. +-. +-.blm doc-empty-line +-. +-. +-.ec +-. +-. +-.\" For UTF-8, map some characters conservatively for the sake +-.\" of easy cut and paste. +-. +-.if '\*[.T]'utf8' \{\ +-. rchar \- - ' ` +-. +-. char \- \N'45' +-. char - \N'45' +-. char ' \N'39' +-. char ` \N'96' +-.\} +-. +-. +-.\" load local modifications +-.mso mdoc.local +-. +-.\" EOF +diff -Nuar groff-1.22.3.old/tmac/doc.tmac-u groff-1.22.3/tmac/doc.tmac-u +--- groff-1.22.3.old/tmac/doc.tmac-u 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/doc.tmac-u 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,6599 @@ ++.\" -*- nroff -*- ++.\" ++.\" Copyright (c) 1991, 1993 ++.\" The Regents of the University of California. All rights reserved. ++.\" ++.\" Redistribution and use in source and binary forms, with or without ++.\" modification, are permitted provided that the following conditions ++.\" are met: ++.\" 1. Redistributions of source code must retain the above copyright ++.\" notice, this list of conditions and the following disclaimer. ++.\" 2. Redistributions in binary form must reproduce the above copyright ++.\" notice, this list of conditions and the following disclaimer in the ++.\" documentation and/or other materials provided with the distribution. ++.\" 3. [Deleted. See ++.\" ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change] ++.\" 4. Neither the name of the University nor the names of its contributors ++.\" may be used to endorse or promote products derived from this software ++.\" without specific prior written permission. ++.\" ++.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ++.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++.\" SUCH DAMAGE. ++.\" ++.\" @(#)doc 8.1 (Berkeley) 06/08/93 ++.\" ++.\" Modified by jjc@jclark.com as follows: the doc-* files are assumed to be ++.\" installed as mdoc/doc-* rather than tmac.doc-* (the filename ++.\" `tmac.doc-common' would be too long); when using groff, the doc-* files ++.\" are loaded using the `mso' request. ++.\" ++.\" Modified by ++.\" ++.\" Werner LEMBERG and ++.\" Ruslan Ermilov ++.\" ++.\" to make it more readable: using long names and many groff features, ++.\" updating and extending documentation, etc. ++.\" ++.\" %beginstrip% ++. ++. ++.if !\n(.g \ ++. ab This version of mdoc can be run with GNU troff only! ++. ++. ++.do if d Dd .nx ++. ++. ++.cp 0 ++. ++. ++.if (\n[.x]\n[.y] < 118) \ ++. ab You need GNU troff version 1.18 or higher to run this version of mdoc! ++. ++. ++.\" Load start-up files ++.ie t \ ++. mso mdoc/doc-ditroff ++.el \ ++. mso mdoc/doc-nroff ++. ++.mso mdoc/doc-common ++.mso mdoc/doc-syms ++. ++. ++.eo ++. ++. ++.\" NS doc-macro-name global string ++.\" NS name of calling request (set in each user-requestable macro) ++. ++.ds doc-macro-name ++.als doc-arg0 doc-macro-name ++. ++. ++.\" NS doc-arg-limit global register ++.\" NS total number of arguments ++. ++.nr doc-arg-limit 0 ++. ++. ++.\" NS doc-num-args global register ++.\" NS number of arguments to handle (must be set to \n[.$] prior to ++.\" NS `doc-parse-arg-vector' request) ++. ++.nr doc-num-args 0 ++. ++. ++.\" NS doc-arg-ptr global register ++.\" NS argument pointer ++. ++.nr doc-arg-ptr 0 ++. ++. ++.\" NS doc-argXXX global string ++.\" NS argument vector ++.\" NS ++.\" NS limit: ++.\" NS doc-arg-limit ++. ++.ds doc-arg1 ++. ++. ++.\" NS doc-typeXXX global register ++.\" NS argument type vector (macro=1, string=2, punctuation suffix=3, ++.\" NS punctuation prefix=4) ++.\" NS ++.\" NS limit: ++.\" NS doc-arg-limit ++. ++.nr doc-type1 0 ++. ++. ++.\" NS doc-spaceXXX global string ++.\" NS space vector ++.\" NS ++.\" NS limit: ++.\" NS doc-arg-limit ++. ++.ds doc-space1 ++. ++. ++.\" NS doc-parse-args macro ++.\" NS parse arguments (recursively) (`.doc-parse-args arg ...') ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-limit ++.\" NS doc-arg-ptr ++.\" NS doc-argXXX ++.\" NS doc-spaceXXX ++.\" NS doc-typeXXX ++.\" NS doc-arg-ptr ++.\" NS doc-have-space ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dpa ++.\" NS doc-reg-dpa1 ++.\" NS doc-str-dpa ++. ++.de doc-parse-args ++. if !\n[doc-arg-limit] \ ++. doc-set-spacing-1 ++. ++. nr doc-have-space 0 ++. ++. if !\n[.$] \ ++. return ++. ++. nr doc-arg-limit +1 ++. ++. \" handle `|' and `...' specially ++. ie "\$1"|" \ ++. ds doc-arg\n[doc-arg-limit] \f[R]|\f[] ++. el \{ .ie "\$1"..." \ ++. ds doc-arg\n[doc-arg-limit] \|.\|.\|. ++. el \ ++. ds doc-arg\n[doc-arg-limit] "\$1 ++. \} ++. ++. \" get argument type and set spacing ++. doc-get-arg-type* \n[doc-arg-limit] ++. nr doc-type\n[doc-arg-limit] \n[doc-arg-type] ++. doc-set-spacing-\n[doc-arg-type] ++. ++. \" check whether we have processed the last parameter ++. ie (\n[.$] == 1) \ ++. nr doc-arg-ptr 0 ++. el \{\ ++. shift ++. doc-parse-args \$@ ++. \} ++. ++. nh ++.. ++. ++. ++.\" NS doc-parse-arg-vector macro ++.\" NS parse argument vector (recursive) ++.\" NS ++.\" NS cf. comments in doc-parse-args ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-limit ++.\" NS doc-arg-ptr ++.\" NS doc-argXXX ++.\" NS doc-num-args ++.\" NS doc-spaceXXX ++.\" NS doc-typeXXX ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dpav ++.\" NS doc-reg-dpav1 ++.\" NS doc-str-dpav ++. ++.de doc-parse-arg-vector ++. if !\n[doc-arg-limit] \ ++. doc-set-spacing-1 ++. ++. nr doc-arg-limit +1 ++. ++. ie "\*[doc-arg\n[doc-arg-limit]]"|" \ ++. ds doc-arg\n[doc-arg-limit] \f[R]|\f[] ++. el \{ .if "\*[doc-arg\n[doc-arg-limit]]"..." \ ++. ds doc-arg\n[doc-arg-limit] \|.\|.\|. ++. \} ++. ++. doc-get-arg-type* \n[doc-arg-limit] ++. nr doc-type\n[doc-arg-limit] \n[doc-arg-type] ++. doc-set-spacing-\n[doc-arg-type] ++. ++. ie (\n[doc-num-args] == 1) \{\ ++. nr doc-arg-ptr 0 ++. nr doc-num-args 0 ++. \} ++. el \{\ ++. nr doc-num-args -1 ++. doc-parse-arg-vector ++. \} ++. ++. nh ++.. ++. ++. ++.\" NS doc-parse-space-vector macro ++.\" NS parse space vector (recursive) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-limit ++.\" NS doc-num-args ++.\" NS doc-spaceXXX ++. ++.de doc-parse-space-vector ++. nr doc-arg-limit +1 ++. ++. doc-set-spacing-\n[doc-type\n[doc-arg-limit]] ++. ++. ie (\n[doc-num-args] == 1) \ ++. nr doc-num-args 0 ++. el \{\ ++. nr doc-num-args -1 ++. doc-parse-space-vector ++. \} ++.. ++. ++. ++.\" NS doc-remaining-args macro ++.\" NS output remaining arguments as-is, separated by spaces (until ++.\" NS `doc-num-args' is exhausted) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-num-args ++. ++.de doc-remaining-args ++. nr doc-arg-ptr +1 ++. nop \)\*[doc-arg\n[doc-arg-ptr]]\c ++. ++. ie (\n[doc-num-args] == 1) \{\ ++. nr doc-arg-ptr 0 ++. nr doc-num-args 0 ++. \} ++. el \{\ ++. nop \)\*[doc-space]\c ++. nr doc-num-args -1 ++. doc-remaining-args ++. \} ++.. ++. ++. ++.\" NS doc-append-arg macro ++.\" NS append one argument to argument vector: ++.\" NS `.doc-append-arg [arg] [type]' ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-limit ++.\" NS doc-argXXX ++.\" NS doc-typeXXX ++. ++.de doc-append-arg ++. nr doc-arg-limit +1 ++. ds doc-arg\n[doc-arg-limit] "\$1 ++. nr doc-type\n[doc-arg-limit] \$2 ++. doc-set-spacing-\$2 ++.. ++. ++. ++.\" NS doc-print-and-reset macro ++.\" NS finish input line and clean up argument vectors ++. ++.de doc-print-and-reset ++. if \n[doc-space-mode] \ ++. nop \) ++. doc-reset-args ++.. ++. ++. ++.\" NS doc-reset-args macro ++.\" NS reset argument counters ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-limit ++.\" NS doc-arg-ptr ++.\" NS doc-have-slot ++. ++.de doc-reset-args ++. nr doc-arg-limit 0 ++. nr doc-arg-ptr 0 ++. nr doc-have-slot 0 ++. ++. hy \n[doc-hyphen-flags] ++.. ++. ++. ++.ec ++. ++.\" NS doc-curr-font global register ++.\" NS saved current font ++. ++.nr doc-curr-font \n[.f] ++. ++. ++.\" NS doc-curr-size global register ++.\" NS saved current font size ++. ++.nr doc-curr-size \n[.ps] ++. ++.eo ++. ++. ++.\" NS Fl user macro ++.\" NS handle flags (appends `-' and prints flags): `.Fl [arg ...]' ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-Fl (for communication with doc-flag-recursion) ++.\" NS ++.\" NS width register `Fl' set in doc-common ++. ++.de Fl ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Fl-font]\c ++. ++. if !\n[doc-arg-limit] \{\ ++. ds doc-macro-name Fl ++. doc-parse-args \$@ ++. ++. \" no arguments ++. if !\n[.$] \ ++. nop \|\-\|\f[]\s[0] ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ ++. \" last argument ++. nop \|\-\f[]\s[0]\c ++. doc-print-and-reset ++. \} ++. el \{\ ++. ie (\n[doc-type\n[doc-arg-ptr]] == 1) \{\ ++. nop \|\-\f[]\s[0]\c ++. \*[doc-arg\n[doc-arg-ptr]] ++. \} ++. el \{\ ++. if (\n[doc-type\n[doc-arg-ptr]] == 3) \ ++. nop \|\-\|\c ++. ++. nr doc-reg-Fl 1 ++. doc-flag-recursion ++. \}\} ++.. ++. ++. ++.\" NS doc-flag-recursion macro ++.\" NS `Fl' flag recursion routine (special handling) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dfr ++.\" NS doc-reg-dfr1 ++.\" NS doc-str-dfr ++. ++.de doc-flag-recursion ++. nr doc-reg-dfr1 \n[doc-type\n[doc-arg-ptr]] ++. ds doc-str-dfr "\*[doc-arg\n[doc-arg-ptr]] ++. ++. ie (\n[doc-reg-dfr1] == 1) \{\ ++. nop \f[]\s[0]\c ++. \*[doc-str-dfr] ++. \} ++. el \{\ ++. nr doc-reg-dfr \n[doc-arg-ptr] ++. ++. ie (\n[doc-reg-dfr1] == 2) \{\ ++. \" handle vertical bar -- doc-reg-Fl is set for the first call of ++. \" doc-flag-recursion only; we need this to make `.Fl | ...' work ++. \" correctly ++. ie "\*[doc-str-dfr]"\*[Ba]" \{\ ++. if \n[doc-reg-Fl] \ ++. nop \|\-\*[doc-space]\c ++. nop \)\*[Ba]\c ++. \} ++. el \{\ ++. ie "\*[doc-str-dfr]"\f[R]|\f[]" \{\ ++. if \n[doc-reg-Fl] \ ++. nop \|\-\*[doc-space]\c ++. nop \f[R]|\f[]\c ++. \} ++. el \{\ ++. \" two consecutive hyphen characters? ++. ie "\*[doc-str-dfr]"-" \ ++. nop \|\-\^\-\|\c ++. el \ ++. nop \|\%\-\*[doc-str-dfr]\&\c ++. \}\}\} ++. el \{\ ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c ++. nop \)\*[doc-str-dfr]\f[]\s[0]\c ++. \} ++. ++. ie (\n[doc-arg-limit] == \n[doc-arg-ptr]) \{\ ++. \" last argument ++. if (\n[doc-reg-dfr1] == 4) \ ++. nop \|\-\c ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c ++. doc-print-and-reset ++. \} ++. el \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-type\n[doc-arg-ptr]] == 3) \{\ ++. ie (\n[doc-type\n[doc-reg-dfr]] == 4) \ ++. nop \|\-\c ++. el \ ++. nop \)\*[doc-space\n[doc-reg-dfr]]\c ++. \} ++. el \ ++. nop \)\*[doc-space\n[doc-reg-dfr]]\c ++. ++. shift ++. nr doc-reg-Fl 0 ++. doc-flag-recursion \$@ ++. \}\} ++.. ++. ++. ++.\" NS doc-print-recursive macro ++.\" NS general name recursion routine (print remaining arguments) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dpr ++.\" NS doc-reg-dpr1 ++.\" NS doc-str-dpr ++. ++.de doc-print-recursive ++. nr doc-reg-dpr1 \n[doc-type\n[doc-arg-ptr]] ++. ds doc-str-dpr "\*[doc-arg\n[doc-arg-ptr]] ++. ++. ie (\n[doc-reg-dpr1] == 1) \{\ ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c ++. \*[doc-str-dpr] ++. \} ++. el \{\ ++. nr doc-reg-dpr \n[doc-arg-ptr] ++. ++. \" the `\%' prevents hyphenation on a dash (`-') ++. ie (\n[doc-reg-dpr1] == 2) \ ++. nop \%\*[doc-str-dpr]\&\c ++. el \{\ ++. \" punctuation character ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c ++. nop \)\*[doc-str-dpr]\f[]\s[0]\c ++. \} ++. ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ ++. \" last argument ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c ++. doc-print-and-reset ++. \} ++. el \{\ ++. nop \)\*[doc-space\n[doc-reg-dpr]]\c ++. doc-print-recursive ++. \}\} ++.. ++. ++. ++.\" NS doc-print-prefixes macro ++.\" NS print leading prefixes ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++. ++.de doc-print-prefixes ++. while (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. if !(\n[doc-type\n[doc-arg-ptr]] == 4) \ ++. break ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c ++. nop \)\*[doc-arg\n[doc-arg-ptr]]\f[]\s[0]\c ++. nr doc-arg-ptr +1 ++. \} ++.. ++. ++. ++.\" NS doc-generic-macro macro ++.\" NS this is the skeleton for most simple macros ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++. ++.de doc-generic-macro ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name \$0 ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .\$0 \*[doc-\$0-usage] ... (#\n[.c]) ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. if (\n[doc-type\n[doc-arg-ptr]] == 1) \{\ ++. tmc mdoc warning: Using a macro as first argument ++. tm1 " cancels effect of .\$0 (#\n[.c]) ++. ++. \" the right action here would be to reset the argument counters ++. \" and bail out -- unfortunately, a small number of manual pages ++. \" (less than 2% for FreeBSD which has been used for testing) ++. \" relied on the old behaviour (silently ignore this error), ++. \" so it is commented out ++. ++.\" doc-reset-args ++. \} ++.\" el \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-\$0-font]\c ++. doc-print-recursive ++.\" \} ++. \} ++. el \{\ ++. tm Usage: .\$0 \*[doc-\$0-usage] ... (#\n[.c]) ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS Ar user macro ++.\" NS command line `argument' macro: `.Ar [args ...]' ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variable: ++.\" NS doc-str-Ar-default ++.\" NS ++.\" NS width register `Ar' set in doc-common ++. ++.ds doc-str-Ar-default "file\ .\|.\|. ++. ++.de Ar ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Ar-font]\c ++. ++. if !\n[doc-arg-limit] \{\ ++. ds doc-macro-name Ar ++. doc-parse-args \$@ ++. ++. \" no argument ++. if !\n[.$] \ ++. nop \)\*[doc-str-Ar-default]\&\f[]\s[0] ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. doc-print-prefixes ++. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ ++. nop \)\*[doc-str-Ar-default]\&\f[]\s[0]\c ++. doc-print-and-reset ++. \} ++. el \{\ ++. if !(\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. \" replace previous argument (Ar) with default value ++. nr doc-arg-ptr -1 ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-str-Ar-default] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. doc-parse-space-vector ++. \} ++. doc-print-recursive ++. \} ++.. ++. ++. ++.\" NS Ad user macro ++.\" NS Addresses ++.\" NS ++.\" NS width register `Ad' set in doc-common ++. ++.als Ad doc-generic-macro ++.ds doc-Ad-usage address ++. ++. ++.\" NS doc-indent-synopsis global register ++.\" NS indentation in synopsis ++. ++.nr doc-indent-synopsis 0 ++. ++. ++.\" NS doc-indent-synopsis-active global register (bool) ++.\" NS indentation in synopsis active ++. ++.nr doc-indent-synopsis-active 0 ++. ++. ++.\" NS Cd user macro ++.\" NS config declaration (for section 4 SYNOPSIS) ++.\" NS ++.\" NS this function causes a break; it uses the `Nm' font ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-indent-synopsis ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Cd' set in doc-common ++. ++.de Cd ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Cd ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Cd configuration_file_declaration ... (#\n[.c]) ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. ie \n[doc-in-synopsis-section] \{\ ++. ie "\*[doc-macro-name]"Cd" \{\ ++. br ++. if !\n[doc-indent-synopsis] \ ++. nr doc-indent-synopsis \n[doc-display-indent]u ++. if !\n[doc-indent-synopsis-active] \ ++. in +\n[doc-indent-synopsis]u ++. ti -\n[doc-indent-synopsis]u ++. nop \*[doc-Nm-font]\c ++. doc-print-recursive ++. if !\n[doc-indent-synopsis-active] \ ++. in -\n[doc-indent-synopsis]u ++. \} ++. el \{\ ++. nop \*[doc-Nm-font]\c ++. doc-print-recursive ++. \}\} ++. el \{\ ++. nop \*[doc-Nm-font]\c ++. doc-print-recursive ++. \}\} ++. el \{\ ++. tm Usage: .Cd configuration_file_declaration ... (#\n[.c]) ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS Cm user macro ++.\" NS interactive command modifier (flag) ++.\" NS ++.\" NS width register `Cm' set in doc-common ++. ++.als Cm doc-generic-macro ++.ds doc-Cm-usage interactive_command_modifier ++. ++. ++.\" NS Dv user macro ++.\" NS defined variable ++.\" NS ++.\" NS this function uses the `Er' font ++.\" NS ++.\" NS width register `Dv' set in doc-common ++. ++.als Dv doc-generic-macro ++.ds doc-Dv-usage defined_variable ++.als doc-Dv-font doc-Er-font ++. ++. ++.\" NS Em user macro ++.\" NS emphasis ++.\" NS ++.\" NS width register `Em' set in doc-common ++. ++.als Em doc-generic-macro ++.ds doc-Em-usage text ++. ++. ++.\" NS Er user macro ++.\" NS errno type ++.\" NS ++.\" NS width register `Er' set in doc-common ++. ++.als Er doc-generic-macro ++.ds doc-Er-usage text ++. ++. ++.\" NS Ev user macro ++.\" NS environment variable ++.\" NS ++.\" NS width register `Ev' set in doc-common ++. ++.als Ev doc-generic-macro ++.ds doc-Ev-usage text ++. ++. ++.\" NS doc-have-decl global register (bool) ++.\" NS subroutine test (in synopsis only) ++. ++.nr doc-have-decl 0 ++. ++. ++.\" NS doc-have-var global register (bool) ++.\" NS whether last type is a variable type ++. ++.nr doc-have-var 0 ++. ++. ++.\" NS doc-do-func-decl macro ++.\" NS do something special while in SYNOPSIS ++.\" NS ++.\" NS modifies: ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-have-decl ++.\" NS doc-have-var ++. ++.de doc-do-func-decl ++. if \n[doc-in-synopsis-section] \{\ ++. \" if a variable type was the last thing given, want vertical space ++. if \n[doc-have-var] \{\ ++. doc-paragraph ++. nr doc-have-var 0 ++. \} ++. \" if a subroutine was the last thing given, want vertical space ++. if \n[doc-have-func] \{\ ++. ie \n[doc-have-decl] \ ++. br ++. el \ ++. doc-paragraph ++. \} ++. nr doc-have-decl 1 ++. \} ++. ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++.. ++. ++. ++.\" NS Fd user macro ++.\" NS function declaration -- not callable ++.\" NS ++.\" NS this function causes a break ++.\" NS ++.\" NS width register `Fd' set in doc-common ++. ++.de Fd ++. ie ((\n[.$] >= 1) & (\n[doc-arg-limit] == 0)) \{\ ++. doc-do-func-decl ++. nop \*[doc-Fd-font]\$* ++. br ++. ft \n[doc-curr-font] ++. ps \n[doc-curr-size]u ++. \} ++. el \{\ ++. tm Usage: .Fd function_declaration -- Fd is not callable (#\n[.c]) ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS In user macro ++.\" NS #include statement in SYNOPSIS ++.\" NS if not in SYNOPSIS ++.\" NS ++.\" NS this function causes a break; it uses the `Fd' font ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-indent-synopsis ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `In' set in doc-common ++. ++.de In ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name In ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .In include_file ... (#\n[.c]) ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. doc-print-prefixes ++. ie ((\n[doc-arg-limit] >= \n[doc-arg-ptr]) & (\n[doc-type\n[doc-arg-ptr]] == 2)) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. ie \n[doc-in-synopsis-section] \{\ ++. ie "\*[doc-macro-name]"In" \{\ ++. doc-do-func-decl ++. nop \*[doc-Fd-font]#include <\*[doc-arg\n[doc-arg-ptr]]> ++. ft \n[doc-curr-font] ++. ps \n[doc-curr-size]u ++. br ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ ++. doc-print-recursive ++. el \ ++. doc-reset-args ++. \} ++. el \{\ ++. ds doc-arg\n[doc-arg-ptr] "<\*[doc-Pa-font]\*[doc-arg\n[doc-arg-ptr]] ++. as doc-arg\n[doc-arg-ptr] \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]> ++. doc-print-recursive ++. \}\} ++. el \{\ ++. ds doc-arg\n[doc-arg-ptr] "<\*[doc-Pa-font]\*[doc-arg\n[doc-arg-ptr]] ++. as doc-arg\n[doc-arg-ptr] \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]> ++. doc-print-recursive ++. \}\} ++. el \{\ ++. tm Usage: .In include_file ... (#\n[.c]) ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS Fr user macro ++.\" NS function return value ++.\" NS ++.\" NS this function uses the `Ar' font ++.\" NS ++.\" NS width register `Fr' set in doc-common ++. ++.als Fr doc-generic-macro ++.ds doc-Fr-usage function_return_value ++.als doc-Fr-font doc-Ar-font ++. ++. ++.\" NS Ic user macro ++.\" NS interactive command ++.\" NS ++.\" NS width register `Ic' set in doc-common ++. ++.als Ic doc-generic-macro ++.ds doc-Ic-usage interactive_command ++. ++. ++.\" NS Li user macro ++.\" NS literals ++.\" NS ++.\" NS width register `Li' set in doc-common ++. ++.als Li doc-generic-macro ++.ds doc-Li-usage argument ++. ++. ++.\" NS Ms user macro ++.\" NS math symbol ++.\" NS ++.\" NS this function uses the `Sy' font ++.\" NS ++.\" NS width register `Ms' set in doc-common ++. ++.als Ms doc-generic-macro ++.ds doc-Ms-usage math_symbol ++.als doc-Ms-font doc-Sy-font ++. ++. ++.\" NS doc-command-name global string ++.\" NS save first invocation of .Nm ++. ++.ds doc-command-name ++. ++. ++.\" NS Nm user macro ++.\" NS name of command or page topic ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-command-name ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-indent-synopsis ++.\" NS doc-indent-synopsis-active ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Nm' set in doc-common ++. ++.de Nm ++. if !\n[doc-arg-limit] \{\ ++. ds doc-macro-name Nm ++. ie \n[.$] \ ++. doc-parse-args \$@ ++. el \{\ ++. ie "\*[doc-command-name]"" \ ++. tm Usage: .Nm name ... (#\n[.c]) ++. el \ ++. doc-parse-args \*[doc-command-name] ++. \}\} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. doc-print-prefixes ++. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ ++. \" last argument ++. ie "\*[doc-command-name]"" \{\ ++. tm Usage: .Nm name ... (#\n[.c]) ++. doc-reset-args ++. \} ++. el \{\ ++. nop \*[doc-Nm-font]\*[doc-command-name]\f[]\s[0]\c ++. doc-print-and-reset ++. \}\} ++. el \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. ie !(\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. ie "\*[doc-command-name]"" \ ++. tm Usage: .Nm name ... (#\n[.c]) ++. el \{\ ++. \" replace previous argument (Nm) with default value ++. nr doc-arg-ptr -1 ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-Nm-font]\*[doc-command-name]\f[]\s[0] ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. doc-parse-space-vector ++. \}\} ++. el \{\ ++. \" handle `.Nm ...' in SYNOPSIS ++. if \n[doc-in-synopsis-section] \{\ ++. if "\*[doc-macro-name]"Nm" \{\ ++. br ++. if !\n[doc-indent-synopsis] \{\ ++. doc-get-width "\*[doc-arg\n[doc-arg-ptr]]" ++. nr doc-indent-synopsis ((\n[doc-width]u + 1u) * \n[doc-fixed-width]u) ++. \} ++. if !\n[doc-indent-synopsis-active] \{\ ++. in +\n[doc-indent-synopsis]u ++. nr doc-indent-synopsis-active 1 ++. \} ++. ti -\n[doc-indent-synopsis]u ++. \}\} ++. if "\*[doc-command-name]"" \ ++. ds doc-command-name "\*[doc-arg\n[doc-arg-ptr]] ++. ++. nop \*[doc-Nm-font]\c ++. \} ++. doc-print-recursive ++. \} ++.. ++. ++. ++.\" NS Pa user macro ++.\" NS pathname: `.Pa [arg ...]' ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Pa' set in doc-common ++. ++.de Pa ++. if !\n[doc-arg-limit] \{\ ++. ds doc-macro-name Pa ++. doc-parse-args \$@ ++. ++. \" default value ++. if !\n[.$] \ ++. nop \*[doc-Pa-font]~\f[]\s[0] ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. doc-print-prefixes ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Pa-font]\c ++. if !(\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. \" replace previous argument (Pa) with default value ++. nr doc-arg-ptr -1 ++. ds doc-arg\n[doc-arg-ptr] ~ ++. nr doc-type\n[doc-arg-ptr] 2 ++. ds doc-space\n[doc-arg-ptr] "\*[doc-space] ++. ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. doc-parse-space-vector ++. \} ++. doc-print-recursive ++. \} ++. el \{\ ++. nop \*[doc-Pa-font]~\f[]\s[0]\c ++. doc-print-and-reset ++. \} ++.. ++. ++. ++.\" NS Sy user macro ++.\" NS symbolics ++.\" NS ++.\" NS width register `Sy' set in doc-common ++. ++.als Sy doc-generic-macro ++.ds doc-Sy-usage symbolic_text ++. ++. ++.\" NS Me user macro ++.\" NS menu entries ++.\" NS ++.\" NS width register `Me' set in doc-common ++. ++.als Me doc-generic-macro ++.ds doc-Me-usage menu_entry ++. ++. ++.\" NS Tn user macro ++.\" NS trade name ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Tn' set in doc-common ++. ++.de Tn ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Tn ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Tn trade_name ... (#\n[.c]) ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \)\*[doc-Tn-font-size]\c ++. ie !\n[doc-is-reference] \{\ ++. nop \)\*[doc-Tn-font-shape]\c ++. doc-print-recursive ++. \} ++. el \ ++. doc-do-references ++. \} ++. el \{\ ++. tm Usage: .Tn trade_name ... (#\n[.c]) ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS Va user macro ++.\" NS variable name ++.\" NS ++.\" NS width register `Va' set in doc-common ++. ++.als Va doc-generic-macro ++.ds doc-Va-usage variable_name ++. ++. ++.\" NS No user macro ++.\" NS normal text macro (default text style if mess up) ++.\" NS ++.\" NS width register `No' set in doc-common ++. ++.als No doc-generic-macro ++.ds doc-No-usage normal_text ++. ++. ++.\" NS doc-quote-left global string ++.\" NS left quotation character for `doc-enclose-string' and ++.\" NS `doc-enclose-open' ++. ++.ds doc-quote-left ++. ++. ++.\" NS doc-quote-right global string ++.\" NS right quotation character for `doc-enclose-string' and ++.\" NS `doc-enclose-close' ++. ++.ds doc-quote-right ++. ++. ++.\" NS Op user macro ++.\" NS option expression (i.e., enclose string in square brackets) ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Op' set in doc-common ++. ++.de Op ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Op ++. ++. ds doc-quote-left "\*[doc-left-bracket] ++. ds doc-quote-right "\*[doc-right-bracket] ++. ++. doc-enclose-string \$@ ++.. ++. ++. ++.\" NS Aq user macro ++.\" NS enclose string in angle brackets ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Aq' set in doc-common ++. ++.de Aq ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Aq ++. ++. ie "\*[doc-macro-name]"An" \{\ ++. ds doc-quote-left < ++. ds doc-quote-right > ++. \} ++. el \{\ ++. ds doc-quote-left \[la] ++. ds doc-quote-right \[ra] ++. \} ++. ++. doc-enclose-string \$@ ++.. ++. ++. ++.\" NS Bq user macro ++.\" NS enclose string in square brackets ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Bq' set in doc-common ++. ++.de Bq ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Bq ++. ++. ds doc-quote-left "\*[doc-left-bracket] ++. ds doc-quote-right "\*[doc-right-bracket] ++. ++. doc-enclose-string \$@ ++.. ++. ++. ++.\" NS Brq user macro ++.\" NS enclose string in braces ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Brq' set in doc-common ++. ++.de Brq ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Brq ++. ++. ds doc-quote-left { ++. ds doc-quote-right } ++. ++. doc-enclose-string \$@ ++.. ++. ++. ++.\" NS Dq user macro ++.\" NS enclose string in double quotes ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Dq' set in doc-common ++. ++.de Dq ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Dq ++. ++. ds doc-quote-left "\*[Lq] ++. ds doc-quote-right "\*[Rq] ++. ++. doc-enclose-string \$@ ++.. ++. ++. ++.\" NS Eq user macro ++.\" NS enclose string in user-defined quotes (args 1 and 2) ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Eq' set in doc-common ++. ++.de Eq ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Eq ++. ++. ds doc-quote-left "\$1 ++. ds doc-quote-right "\$2 ++. ++. shift 2 ++. doc-enclose-string \$@ ++.. ++. ++. ++.\" NS Pq user macro ++.\" NS enclose string in parentheses ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Pq' set in doc-common ++. ++.de Pq ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Pq ++. ++. ds doc-quote-left "\*[doc-left-parenthesis] ++. ds doc-quote-right "\*[doc-right-parenthesis] ++. ++. doc-enclose-string \$@ ++.. ++. ++. ++.\" NS Ql user macro ++.\" NS quoted literal ++.\" ++.\" is in file doc-[dit|n]roff ++. ++. ++.\" NS Qq user macro ++.\" NS enclose string in straight double quotes ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Qq' set in doc-common ++. ++.de Qq ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Qq ++. ++. ds doc-quote-left "\*[q] ++. ds doc-quote-right "\*[q] ++. ++. doc-enclose-string \$@ ++.. ++. ++. ++.\" NS Sq user macro ++.\" NS enclose string in single quotes ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Sq' set in doc-common ++. ++.de Sq ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Sq ++. ++. ds doc-quote-left "\*[doc-left-singlequote] ++. ds doc-quote-right "\*[doc-right-singlequote] ++. ++. doc-enclose-string \$@ ++.. ++. ++. ++.\" NS Es user macro ++.\" NS set up arguments (i.e., the left and right quotation character as ++.\" NS first and second argument) for .En call ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++. ++.de Es ++. if !\n[doc-arg-limit] \{\ ++. ie (\n[.$] > 2) \{\ ++. ds doc-macro-name Es ++. doc-parse-args \$@ ++. \} ++. el \{\ ++. ds doc-quote-left "\$1 ++. ds doc-quote-right "\$2 ++. \}\} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. ds doc-quote-left "\*[doc-arg\n[doc-arg-ptr]] ++. nr doc-arg-ptr +1 ++. ds doc-quote-right "\*[doc-arg\n[doc-arg-ptr]] ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ ++. doc-do-\n[doc-type\n[doc-arg-ptr]] ++. el \ ++. doc-print-and-reset ++.. ++. ++. ++.\" NS doc-have-slot global register (bool) ++.\" NS set if `doc-enclose-string' has created a slot for closing ++.\" NS delimiter ++. ++.nr doc-have-slot 0 ++. ++. ++.\" NS doc-enclose-string macro ++.\" NS enclose string with given args (e.g. [ and ]) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-argXXX ++.\" NS doc-have-slot ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-des ++.\" NS doc-reg-des1 ++.\" NS doc-reg-des2 ++.\" NS ++.\" NS requires: ++.\" NS doc-quote-left ++.\" NS doc-quote-right ++. ++.de doc-enclose-string ++. if \n[doc-in-synopsis-section] \ ++. doc-set-hard-space ++. ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \ ++. doc-parse-args \$@ ++. el \{\ ++. nop \)\*[doc-quote-left]\*[doc-quote-right] ++. \}\} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. nr doc-arg-ptr +1 ++. doc-print-prefixes ++. \" the final `\)' prevents hyphenation in case the next character is `\%' ++. nop \)\*[doc-quote-left]\)\c ++. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ ++. \" last argument ++. nop \)\*[doc-quote-right]\)\c ++. doc-print-and-reset ++. \} ++. el \{\ ++. \" test whether last arguments are of type closing punctuation ++. \" resp. suffix ++. ie (\n[doc-type\n[doc-arg-limit]] == 3) \{\ ++. nr doc-reg-des (\n[doc-arg-limit] - 1) ++. while (\n[doc-type\n[doc-reg-des]] == 3) \ ++. nr doc-reg-des -1 ++. ++. \" prepend closing delimiter ++. nr doc-reg-des +1 ++. ds doc-arg\n[doc-reg-des] "\*[doc-quote-right]\)\*[doc-arg\n[doc-reg-des]] ++. \} ++. el \{\ ++. \" test whether last arguments are macros which continue the line ++. \" logically ++. nr doc-reg-des \n[doc-arg-limit] ++. while (\n[doc-reg-des] >= \n[doc-arg-ptr]) \{\ ++. if !\A\*[doc-arg\n[doc-reg-des]] \ ++. break ++. if !d doc-after-\*[doc-arg\n[doc-reg-des]] \ ++. break ++. nr doc-reg-des -1 ++. \} ++. ++. \" if there are no trailing macros to be skipped, append argument ++. ie (\n[doc-reg-des] == \n[doc-arg-limit]) \ ++. doc-append-arg "\)\*[doc-quote-right]\)" 3 ++. el \{\ ++. \" if a previous call to `doc-enclose-string' has already created ++. \" a slot, prepend argument ++. ie \n[doc-have-slot] \ ++. ds doc-arg\n[doc-reg-des] "\*[doc-quote-right]\)\*[doc-arg\n[doc-reg-des]] ++. el \{\ ++. \" we have to shift all arguments to the right ++. nr doc-reg-des +1 ++. nr doc-reg-des1 \n[doc-arg-limit] ++. nr doc-reg-des2 (\n[doc-arg-limit] + 1) ++. while (\n[doc-reg-des1] >= \n[doc-reg-des]) \{\ ++. rn doc-arg\n[doc-reg-des1] doc-arg\n[doc-reg-des2] ++. rnn doc-type\n[doc-reg-des1] doc-type\n[doc-reg-des2] ++. rn doc-space\n[doc-reg-des1] doc-space\n[doc-reg-des2] ++. nr doc-reg-des1 -1 ++. nr doc-reg-des2 -1 ++. \} ++. nr doc-arg-limit +1 ++. ++. \" finally, insert closing delimiter into the freed slot and ++. \" recompute spacing vector ++. ds doc-arg\n[doc-reg-des] "\)\*[doc-quote-right]\) ++. nr doc-type\n[doc-reg-des] 3 ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-reg-des] + 1) ++. nr doc-arg-limit (\n[doc-reg-des] - 1) ++. doc-parse-space-vector ++. nr doc-have-slot 1 ++. \}\}\} ++. ++. doc-do-\n[doc-type\n[doc-arg-ptr]] ++. \} ++. ++. if \n[doc-in-synopsis-section] \ ++. doc-set-soft-space ++.. ++. ++. ++.\" NS En user macro ++.\" NS enclose arguments with quotation characters set up with `.Es' ++. ++.als En doc-enclose-string ++. ++. ++.\" NS Ao user macro ++.\" NS angle open ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Ao' set in doc-common ++. ++.de Ao ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Ao ++. ++. ie "\*[doc-macro-name]"An" \ ++. ds doc-quote-left < ++. el \ ++. ds doc-quote-left \[la] ++. ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Ac user macro ++.\" NS angle close ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Ac' set in doc-common ++. ++.de Ac ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Ac ++. ++. ie "\*[doc-macro-name]"An" \ ++. ds doc-quote-right > ++. el \ ++. ds doc-quote-right \[ra] ++. ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS Bo user macro ++.\" NS bracket open ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Bo' set in doc-common ++. ++.de Bo ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Bo ++. ++. ds doc-quote-left "\*[doc-left-bracket] ++. ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Bc user macro ++.\" NS bracket close ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Bc' set in doc-common ++. ++.de Bc ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Bc ++. ++. ds doc-quote-right "\*[doc-right-bracket] ++. ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS Bro user macro ++.\" NS brace open ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Bro' set in doc-common ++. ++.de Bro ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Bo ++. ++. ds doc-quote-left { ++. ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Brc user macro ++.\" NS brace close ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Brc' set in doc-common ++. ++.de Brc ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Bc ++. ++. ds doc-quote-right } ++. ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS Do user macro ++.\" NS double quote open ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Do' set in doc-common ++. ++.de Do ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Do ++. ++. ds doc-quote-left "\*[Lq] ++. ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Dc user macro ++.\" NS double quote close ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Dc' set in doc-common ++. ++.de Dc ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Dc ++. ++. ds doc-quote-right "\*[Rq] ++. ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS Eo user macro ++.\" NS enclose open (using first argument as beginning of enclosure) ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Eo' set in doc-common ++. ++.de Eo ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Eo ++. ++. ds doc-quote-left "\$1 ++. ++. shift ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Ec user macro ++.\" NS enclose close (using first argument as end of enclosure) ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Ec' set in doc-common ++. ++.de Ec ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Ec ++. ++. ds doc-quote-right "\$1 ++. ++. shift ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS Oo user macro ++.\" NS option open ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Oo' set in doc-common ++. ++.de Oo ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Oo ++. ++. ds doc-quote-left [ ++. ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Oc user macro ++.\" NS option close ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Oc' set in doc-common ++. ++.de Oc ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Oc ++. ++. ds doc-quote-right ] ++. ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS Po user macro ++.\" NS parenthesis open ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Po' set in doc-common ++. ++.de Po ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Po ++. ++. ds doc-quote-left "\*[doc-left-parenthesis] ++. ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Pc user macro ++.\" NS parenthesis close ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Pc' set in doc-common ++. ++.de Pc ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Pc ++. ++. ds doc-quote-right "\*[doc-right-parenthesis] ++. ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS Qo user macro ++.\" NS straight double quote open ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Qo' set in doc-common ++. ++.de Qo ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Qo ++. ++. ds doc-quote-left "\*[q] ++. ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Qc user macro ++.\" NS straight double quote close ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Qc' set in doc-common ++. ++.de Qc ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Qc ++. ++. ds doc-quote-right "\*[q] ++. ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS So user macro ++.\" NS single quote open ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `So' set in doc-common ++. ++.de So ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name So ++. ++. ds doc-quote-left "\*[doc-left-singlequote] ++. ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Sc user macro ++.\" NS single quote close ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Sc' set in doc-common ++. ++.de Sc ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Sc ++. ++. ds doc-quote-right "\*[doc-right-singlequote] ++. ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS Xo user macro ++.\" NS extend open ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Xo' set in doc-common ++. ++.de Xo ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Xo ++. ++. ds doc-quote-left ++. ++. doc-enclose-open \$@ ++.. ++. ++. ++.\" NS Xc user macro ++.\" NS extend close ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS doc-quote-right ++.\" NS ++.\" NS width register `Xc' set in doc-common ++. ++.de Xc ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Xc ++. ++. ds doc-quote-right ++. ++. doc-enclose-close \$@ ++.. ++. ++. ++.\" NS doc-nesting-level global register ++.\" NS used by `doc-enclose-open' and `doc-enclose-close' ++. ++.nr doc-nesting-level 0 ++. ++. ++.\" NS doc-in-list global register (bool) ++.\" NS whether we are in (logical) .It ++. ++.nr doc-in-list 0 ++. ++. ++.\" NS doc-enclose-open macro ++.\" NS enclose string open ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-nesting-level ++. ++.de doc-enclose-open ++. if !\n[doc-arg-limit] \ ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. doc-print-prefixes ++. nr doc-arg-ptr -1 ++. ++. nop \)\*[doc-quote-left]\)\c ++. ++. \" start enclosure box ++. box doc-enclosure-box\n[doc-nesting-level] ++. ev doc-enclosure-env\n[doc-nesting-level] ++. evc 0 ++. in 0 ++. nf ++. \" we insert something to make .chop always work ++. nop \&\c ++. ++. \" increase nesting level *after* parsing of arguments ++. nr doc-nesting-level +1 ++. ++. if \n[doc-arg-limit] \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ ++. doc-print-recursive ++. el \ ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS doc-enclose-close macro ++.\" NS enclose string close ++.\" NS ++.\" NS modifies: ++.\" NS doc-nesting-level ++. ++.de doc-enclose-close ++. nr doc-nesting-level -1 ++. ++. \" finish enclosure box ++. br ++. ev ++. box ++. chop doc-enclosure-box\n[doc-nesting-level] ++. unformat doc-enclosure-box\n[doc-nesting-level] ++. ++. nh ++. nop \*[doc-enclosure-box\n[doc-nesting-level]]\c ++. nop \)\*[doc-quote-right]\)\c ++. ++. if !\n[doc-arg-limit] \{\ ++. doc-parse-args \$@ ++. ++. if !\n[.$] \ ++. doc-print-and-reset ++. \} ++. ++. if \n[doc-arg-limit] \{\ ++. ie (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nop \)\*[doc-space\n[doc-arg-ptr]]\c ++. nr doc-arg-ptr +1 ++. doc-print-recursive ++. \} ++. el \ ++. doc-print-and-reset ++. \} ++. ++. \" shall we finish .It macro? ++. if !"\*[doc-macro-name]"It" \ ++. if \n[doc-in-list] \ ++. if !\n[doc-nesting-level] \ ++. doc-\*[doc-list-type-stack\n[doc-list-depth]] ++.. ++. ++. ++.\" NS Pf user macro ++.\" NS prefix: `.Pf prefix arg ...' ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-macro-name ++.\" NS doc-quote-left ++.\" NS ++.\" NS width register `Pf' set in doc-common ++. ++.de Pf ++. if !\n[doc-arg-limit] \ ++. ds doc-macro-name Pf ++. ++. ie \n[doc-arg-limit] \{\ ++. ie ((\n[doc-arg-limit] - \n[doc-arg-ptr]) > 1) \{\ ++. nr doc-arg-ptr +1 ++. nop \)\*[doc-arg\n[doc-arg-ptr]]\c ++. \} ++. el \ ++. tm mdoc warning: .Pf: trailing prefix (#\n[.c]) ++. \} ++. el \{\ ++. nop \)\$1\)\c ++. shift ++. ie \n[.$] \ ++. doc-parse-args \$@ ++. el \{\ ++. tm mdoc warning: .Pf: missing arguments (#\n[.c]) ++. nop \) ++. \}\} ++. ++. if \n[doc-arg-limit] \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] < \n[doc-arg-ptr]) \ ++. doc-print-and-reset ++. el \ ++. doc-do-\n[doc-type\n[doc-arg-ptr]] ++. \} ++.. ++. ++. ++.\" NS Ns user macro ++.\" NS remove space (space removal done by `doc-parse-args') ++.\" NS ++.\" NS modifies: ++.\" NS doc-argXXX ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Ns' set in doc-common ++. ++.de Ns ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Ns ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Ns must be called with arguments (#\n[.c]) ++. \} ++. ++. if \n[doc-arg-limit] \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ ++. doc-print-recursive ++. el \ ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS Ap user macro ++.\" NS append an apostrophe ++.\" NS ++.\" NS width register `Ap' set in doc-common ++. ++.de Ap ++. ie !\n[doc-arg-limit] \ ++. tm Usage: `Ap' cannot be first macro on a line (no `.Ap') (#\n[.c]) ++. el \{\ ++. nop \)'\)\c ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ ++. doc-print-recursive ++. el \ ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS doc-space global string ++.\" NS current inter-argument space ++. ++.ds doc-space "\*[doc-soft-space] ++. ++. ++.\" NS doc-soft-space constant string ++.\" NS soft (stretchable) space (defined in doc-common) ++. ++. ++.\" NS doc-hard-space constant string ++.\" NS hard (unpaddable) space (defined in doc-common) ++. ++. ++.\" NS doc-set-hard-space macro ++.\" NS set current space string to hard (unpaddable) space. ++.\" NS ++.\" NS modifies: ++.\" NS doc-saved-space ++.\" NS doc-space ++. ++.de doc-set-hard-space ++. ie "\*[doc-space]"" \ ++. ds doc-saved-space "\*[doc-hard-space] ++. el \ ++. ds doc-space "\*[doc-hard-space] ++.. ++. ++. ++.\" NS doc-set-soft-space macro ++.\" NS set current space string to soft space ++.\" NS ++.\" NS modifies: ++.\" NS doc-saved-space ++.\" NS doc-space ++. ++.de doc-set-soft-space ++. ie "\*[doc-space]"" \ ++. ds doc-saved-space "\*[doc-soft-space] ++. el \ ++. ds doc-space "\*[doc-soft-space] ++.. ++. ++. ++.\" NS doc-space-mode global register (bool) ++.\" NS default is one (space mode on) ++. ++.nr doc-space-mode 1 ++. ++. ++.\" NS doc-saved-space global string ++.\" NS saved value of `doc-space' ++. ++.ds doc-saved-space "\*[doc-space] ++. ++. ++.\" NS doc-have-space global register (bool) ++.\" NS set if last command was horizontal space ++. ++.nr doc-have-space 0 ++. ++. ++.\" NS Sm user macro ++.\" NS space mode (`.Sm'/`.Sm on'/`.Sm off') ++.\" NS ++.\" NS without argument, toggle space mode ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-limit ++.\" NS doc-arg-ptr ++.\" NS doc-argXXX ++.\" NS doc-macro-name ++.\" NS doc-num-args ++.\" NS doc-saved-space ++.\" NS doc-space ++.\" NS doc-space-mode ++.\" NS doc-spaceXXX ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-Sm ++.\" NS ++.\" NS width register `Sm' set in doc-common ++. ++.de Sm ++. ie \n[doc-have-space] \ ++. nr doc-reg-Sm 0 ++. el \ ++. nr doc-reg-Sm 1 ++. ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Sm ++. doc-parse-args \$@ ++. \} ++. el \{\ ++. ie \n[doc-space-mode] \{\ ++. ds doc-saved-space "\*[doc-space] ++. ds doc-space ++. nr doc-space-mode 0 ++. \} ++. el \{\ ++. ds doc-space "\*[doc-saved-space] ++. nr doc-space-mode 1 ++. ++. \" finish line only if it is interrupted and `doc-have-space' ++. \" isn't set ++. if \n[doc-reg-Sm] \ ++. if \n[.int] \ ++. nop \) ++. \} ++. \}\} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. ++. \" avoid a warning message in case `Sm' is the last parameter ++. if !d doc-arg\n[doc-arg-ptr] \ ++. ds doc-arg\n[doc-arg-ptr] ++. ++. ie "\*[doc-arg\n[doc-arg-ptr]]"on" \{\ ++. ds doc-space "\*[doc-saved-space] ++. nr doc-space-mode 1 ++. \} ++. el \{\ ++. ie "\*[doc-arg\n[doc-arg-ptr]]"off" \{\ ++. ds doc-saved-space "\*[doc-space] ++. ds doc-space ++. nr doc-space-mode 0 ++. \} ++. el \{\ ++. \" no argument for Sm ++. nr doc-arg-ptr -1 ++. ie \n[doc-space-mode] \{\ ++. ds doc-saved-space "\*[doc-space] ++. ds doc-space ++. nr doc-space-mode 0 ++. \} ++. el \{\ ++. ds doc-space "\*[doc-saved-space] ++. nr doc-space-mode 1 ++. \} ++. \}\} ++. ++. ie \n[doc-space-mode] \{\ ++. \" recompute space vector for remaining arguments ++. nr doc-num-args (\n[doc-arg-limit] - \n[doc-arg-ptr]) ++. nr doc-arg-limit \n[doc-arg-ptr] ++. if \n[doc-num-args] \ ++. doc-parse-space-vector ++. ++. \" finish line only if it is interrupted and `doc-have-space' ++. \" isn't set ++. if \n[doc-reg-Sm] \ ++. if \n[.int] \ ++. nop \) ++. \} ++. el \{\ ++. \" reset remaining space vector elements ++. nr doc-reg-Sm (\n[doc-arg-ptr] + 1) ++. while (\n[doc-reg-Sm] <= \n[doc-arg-limit]) \{\ ++. ds doc-space\n[doc-reg-Sm] ++. nr doc-reg-Sm +1 ++. \" the body of a `while' request must end with the fitting `\}'! ++. \} ++. \} ++. ++. \" do we have parameters to print? ++. ie (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. \" skip `Sm' argument ++. nr doc-arg-ptr +1 ++. doc-print-recursive ++. \} ++. el \ ++. doc-reset-args ++.. ++. ++. ++.\" NS doc-arg-type immediate register ++.\" NS argument type (macro=1, string=2, punctuation suffix=3, ++.\" NS punctuation prefix=4) ++. ++.nr doc-arg-type 0 ++. ++. ++.\" NS doc-get-arg-type macro ++.\" NS get argument type ++.\" NS ++.\" NS this macro expects the width of the argument in `doc-width' ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-type ++. ++.de doc-get-arg-type ++. nr doc-arg-type 2 ++. ++. if ((\n[doc-width] < 4) & \A\$1) \{\ ++. ie (\n[doc-width] == 1) \{\ ++. if r doc-punct\$1 \ ++. nr doc-arg-type \n[doc-punct\$1] ++. \} ++. el \ ++. if r \$1 \ ++. if d \$1 \ ++. nr doc-arg-type 1 ++. \} ++.. ++. ++. ++.\" NS doc-get-arg-type* macro ++.\" NS similar to as `doc-get-arg-type' but uses doc-argXXX strings ++.\" NS ++.\" NS this macro sets the `doc-width' register using the `length' request ++.\" NS to get the number of characters in a string literally ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-type ++.\" NS doc-width ++. ++.de doc-get-arg-type* ++. nr doc-arg-type 2 ++. length doc-width "\*[doc-arg\$1] ++. ++. if ((\n[doc-width] < 4) & \A\*[doc-arg\$1]) \{\ ++. ie (\n[doc-width] == 1) \{\ ++. if r doc-punct\*[doc-arg\$1] \ ++. nr doc-arg-type \n[doc-punct\*[doc-arg\$1]] ++. \} ++. el \ ++. if r \*[doc-arg\$1] \ ++. if d \*[doc-arg\$1] \ ++. nr doc-arg-type 1 ++. \} ++.. ++. ++. ++.\" NS doc-set-spacing-1 macro ++.\" NS set spacing for macros ++.\" NS ++.\" NS modifies: ++.\" NS doc-spaceXXX ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dssfm ++.\" NS doc-reg-dssfm1 ++. ++.de doc-set-spacing-1 ++. nr doc-reg-dssfm1 \n[\*[doc-arg\n[doc-arg-limit]]] ++. ++. \" closing macros like .Ac, Bc., etc. have value 3 (remove space before ++. \" argument) ++. ie (\n[doc-reg-dssfm1] == 3) \{\ ++. if \n[doc-arg-limit] \{\ ++. nr doc-reg-dssfm (\n[doc-arg-limit] - 1) ++. ds doc-space\n[doc-reg-dssfm] ++. \} ++. ds doc-space\n[doc-arg-limit] "\*[doc-space] ++. \} ++. el \{\ ++. \" macros like .Ap and .Ns have value 2 (remove space before and after ++. \" argument) ++. ie (\n[doc-reg-dssfm1] == 2) \{\ ++. if \n[doc-arg-limit] \{\ ++. nr doc-reg-dssfm (\n[doc-arg-limit] - 1) ++. ds doc-space\n[doc-reg-dssfm] ++. \} ++. ds doc-space\n[doc-arg-limit] ++. \} ++. el \ ++. ds doc-space\n[doc-arg-limit] ++. \} ++.. ++. ++. ++.\" NS doc-set-spacing-2 macro ++.\" NS set spacing for strings ++.\" NS ++.\" NS modifies: ++.\" NS doc-spaceXXX ++. ++.de doc-set-spacing-2 ++. ds doc-space\n[doc-arg-limit] "\*[doc-space] ++.. ++. ++. ++.\" NS doc-set-spacing-3 macro ++.\" NS set spacing for punctuation suffixes ++.\" NS ++.\" NS modifies: ++.\" NS doc-spaceXXX ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dssfps ++. ++.de doc-set-spacing-3 ++. if \n[doc-arg-limit] \{\ ++. nr doc-reg-dssfps (\n[doc-arg-limit] - 1) ++. ds doc-space\n[doc-reg-dssfps] ++. \} ++. ++. ds doc-space\n[doc-arg-limit] "\*[doc-space] ++.. ++. ++. ++.\" NS doc-set-spacing-4 macro ++.\" NS set spacing for punctuation prefixes ++.\" NS ++.\" NS modifies: ++.\" NS doc-spaceXXX ++. ++.de doc-set-spacing-4 ++. ds doc-space\n[doc-arg-limit] ++.. ++. ++. ++.\" type switches (on current argument doc-arg-ptr) ++. ++. ++.\" NS doc-do-1 macro ++.\" NS call request if macro ++. ++.de doc-do-1 ++. \*[doc-arg\n[doc-arg-ptr]] ++.. ++. ++. ++.\" NS doc-do-2 macro ++.\" NS call .doc-print-recursive if string ++. ++.als doc-do-2 doc-print-recursive ++. ++. ++.\" NS doc-do-3 macro ++.\" NS call .doc-print-recursive if punctuation suffix ++. ++.als doc-do-3 doc-print-recursive ++. ++. ++.\" NS doc-do-4 macro ++.\" NS call .doc-print-recursive if punctuation prefix ++. ++.als doc-do-4 doc-print-recursive ++. ++. ++.\" NS doc-fontmode-depth global register ++.\" NS font mode level ++. ++.nr doc-fontmode-depth 0 ++. ++. ++.\" NS doc-fontmode-font-stackXXX global register ++.\" NS stack of saved current font values from `Bf' macro ++.\" NS ++.\" NS limit: ++.\" NS doc-fontmode-depth ++. ++.nr doc-fontmode-font-stack0 0 ++. ++. ++.\" NS doc-fontmode-size-stackXXX global register ++.\" NS stack of saved current size values from `Bf' macro ++.\" NS ++.\" NS limit: ++.\" NS doc-fontmode-depth ++. ++.nr doc-fontmode-size-stack0 0 ++. ++. ++.\" NS Bf user macro ++.\" NS begin font mode (will be begin-mode/end-mode in groff & TeX) ++.\" NS ++.\" NS modifies: ++.\" NS doc-fontmode-depth ++.\" NS doc-fontmode-font-stackXXX ++.\" NS doc-fontmode-size-stackXXX ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Bf' set in doc-common ++. ++.de Bf ++. ds doc-macro-name Bf ++. ++. ie \n[.$] \{\ ++. nr doc-fontmode-depth +1 ++. ++. \" save current font and size ++. nr doc-fontmode-font-stack\n[doc-fontmode-depth] \n[.f] ++. nr doc-fontmode-size-stack\n[doc-fontmode-depth] \n[.ps] ++. ++. ie "\$1"Em" \ ++. nop \*[doc-Em-font]\c ++. el \{ .ie "\$1"Li" \ ++. nop \*[doc-Li-font]\c ++. el \{ .ie "\$1"Sy" \ ++. nop \*[doc-Sy-font]\c ++. el \{ .ie "\$1"-emphasis" \ ++. nop \*[doc-Em-font]\c ++. el \{ .ie "\$1"-literal" \ ++. nop \*[doc-Li-font]\c ++. el \{ .ie "\$1"-symbolic" \ ++. nop \*[doc-Sy-font]\c ++. el \{\ ++. tmc mdoc warning: Unknown keyword `\$1' in .Bf macro ++. tm1 " (#\n[.c]) ++. \}\}\}\}\}\}\} ++. el \ ++. tm Usage: .Bf [Em | -emphasis | Li | -literal | Sy | -symbolic] (#\n[.c]) ++.. ++. ++. ++.\" NS Ef user macro ++.\" NS end font mode ++.\" NS ++.\" NS modifies: ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Ef' set in doc-common ++. ++.de Ef ++. ds doc-macro-name Ef ++. ++. ie \n[doc-fontmode-depth] \{\ ++. \" restore saved font and size ++. nop \)\f[\n[doc-fontmode-font-stack\n[doc-fontmode-depth]]]\c ++. nop \)\s[\n[doc-fontmode-size-stack\n[doc-fontmode-depth]]u]\c ++. ++. nr doc-fontmode-font-stack\n[doc-fontmode-depth] 0 ++. nr doc-curr-font \n[.f] ++. nr doc-fontmode-size-stack\n[doc-fontmode-depth] 0 ++. nr doc-curr-size \n[.ps] ++. nr doc-fontmode-depth -1 ++. \} ++. el \ ++. tm mdoc warning: Extraneous .Ef (#\n[.c]) ++.. ++. ++. ++.\" NS doc-keep-type global register ++.\" NS current keep type; 1 is `-words', 2 is `-lines', 3 is unknown ++. ++.nr doc-keep-type 0 ++. ++. ++.\" NS Bk user macro ++.\" NS begin keep ++.\" NS ++.\" NS modifies: ++.\" NS doc-keep-type ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Bk' set in doc-common ++. ++.de Bk ++. ds doc-macro-name Bk ++. ++. if \n[doc-keep-type] \ ++. tm .Bk: nesting keeps not implemented yet. (#\n[.c]) ++. ++. ie "\$1"-lines" \{\ ++. nr doc-keep-type 2 ++. tm .Bk -lines: Not implemented yet. (#\n[.c]) ++. \} ++. el \{ .ie "\$1"-words" \{\ ++. nr doc-keep-type 1 ++. doc-set-hard-space ++. \} ++. el \{ .ie "\$1"" \{\ ++. \" default ++. nr doc-keep-type 1 ++. doc-set-hard-space ++. \} ++. el \{\ ++. tm mdoc warning: Unknown keyword `\$1' in .Bk macro (#\n[.c]) ++. nr doc-keep-type 3 ++. \}\}\} ++. ++\#. nr doc-nesting-level +1 ++.. ++. ++. ++.\" NS Ek user macro ++.\" NS end keep ++.\" NS ++.\" NS modifies: ++.\" NS doc-keep-type ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Ek' set in doc-common ++. ++.de Ek ++. ds doc-macro-name Ek ++. ++\#. nr doc-nesting-level -1 ++. ++. ie \n[.$] \ ++. tm Usage: .Ek (does not take arguments) (#\n[.c]) ++. el \{\ ++. if !\n[doc-keep-type] \ ++. tm mdoc warning: .Ek found without .Bk before (#\n[.c]) ++. ++. ie (\n[doc-keep-type] == 1) \ ++. doc-set-soft-space ++. el \{ .if (\n[doc-keep-type] == 2) \ ++. tm .Bk -lines: Not implemented yet. (#\n[.c]) ++. \}\} ++. ++. nr doc-keep-type 0 ++. ++\#. if !"\*[doc-out-string]"" \ ++\#. doc-print-out-string ++.. ++. ++. ++.\" NS doc-display-depth global register ++.\" NS display level ++. ++.nr doc-display-depth 0 ++. ++. ++.\" NS doc-is-compact global register (bool) ++.\" NS set if the `compact' keyword is given ++. ++.nr doc-is-compact 0 ++. ++. ++.\" NS doc-display-type-stackXXX global string ++.\" NS the display type stack ++.\" NS ++.\" NS limit: ++.\" NS doc-display-depth ++. ++.ds doc-display-type-stack0 ++. ++. ++.\" NS doc-display-indent-stackXXX global register ++.\" NS stack of display indentation values ++.\" NS ++.\" NS limit: ++.\" NS doc-display-depth ++. ++.nr doc-display-indent-stack0 0 ++. ++. ++.\" NS doc-display-ad-stackXXX global register ++.\" NS stack of saved adjustment modes ++.\" NS ++.\" NS limit: ++.\" NS doc-display-depth ++. ++.nr doc-display-ad-stack0 0 ++. ++. ++.\" NS doc-display-fi-stackXXX global register ++.\" NS stack of saved fill modes ++.\" NS ++.\" NS limit: ++.\" NS doc-display-depth ++. ++.nr doc-display-fi-stack0 0 ++. ++. ++.\" NS doc-display-ft-stackXXX global register ++.\" NS stack of saved fonts ++.\" NS ++.\" NS limit: ++.\" NS doc-display-depth ++. ++.nr doc-display-ft-stack0 0 ++. ++. ++.\" NS doc-display-ps-stackXXX global register ++.\" NS stack of saved font sizes ++.\" NS ++.\" NS limit: ++.\" NS doc-display-depth ++. ++.nr doc-display-ps-stack0 0 ++. ++. ++.\" NS Bd user macro ++.\" NS begin display ++.\" NS ++.\" NS width register `Bd' set in doc-common ++.\" NS ++.\" NS modifies: ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-display-depth ++.\" NS doc-display-ad-stackXXX ++.\" NS doc-display-fi-stackXXX ++.\" NS doc-display-ft-stackXXX ++.\" NS doc-display-ps-stackXXX ++.\" NS doc-display-file ++.\" NS doc-display-indent-stackXXX ++.\" NS doc-display-type-stackXXX ++.\" NS doc-is-compact ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-Bd ++. ++.de Bd ++. ds doc-macro-name Bd ++. ++. if !\n[.$] \{\ ++. tm1 "Usage: .Bd {-literal | -filled | -ragged | -centered | -unfilled} ++. tm1 " [-offset [string]] [-compact] [-file name] (#\n[.c]) ++. return ++. \} ++. ++. nr doc-is-compact 0 ++. ds doc-display-file ++. nr doc-reg-Bd 1 ++. nr doc-display-depth +1 ++. ++. \" save current adjustment and fill modes ++. nr doc-display-ad-stack\n[doc-display-depth] \n[.j] ++. nr doc-display-fi-stack\n[doc-display-depth] \n[.u] ++. ++. ie "\$1"-literal" \{\ ++. ds doc-display-type-stack\n[doc-display-depth] literal ++. nr doc-display-ft-stack\n[doc-display-depth] \n[.f] ++. nr doc-display-ps-stack\n[doc-display-depth] \n[.ps] ++. ++. ie t \ ++. ta T 9n ++. el \ ++. ta T 8n ++. nf ++. \} ++. el \{ .ie "\$1"-filled" \{\ ++. ds doc-display-type-stack\n[doc-display-depth] filled ++. ad b ++. fi ++. \} ++. el \{ .ie "\$1"-ragged" \{\ ++. ds doc-display-type-stack\n[doc-display-depth] ragged ++. na ++. fi ++. \} ++. el \{ .ie "\$1"-centered" \{\ ++. ds doc-display-type-stack\n[doc-display-depth] centered ++. ad c ++. fi ++. \} ++. el \{ .ie "\$1"-unfilled" \{\ ++. ds doc-display-type-stack\n[doc-display-depth] unfilled ++. nf ++. \} ++. el \{\ ++. tm1 "mdoc warning: Unknown keyword `\$1' (or missing display type) ++. tm1 " in .Bd macro (#\n[.c]) ++. nr doc-reg-Bd 0 ++. \}\}\}\}\} ++. ++. \" have we seen an argument? ++. if \n[doc-reg-Bd] \{\ ++. shift ++. \" check other arguments ++. if \n[.$] \ ++. doc-do-Bd-args \$@ ++. \} ++. ++. \" avoid warning about non-existent register ++. if !r doc-display-indent-stack\n[doc-display-depth] \ ++. nr doc-display-indent-stack\n[doc-display-depth] 0 ++. ++. if \n[doc-display-indent-stack\n[doc-display-depth]] \ ++. in +\n[doc-display-indent-stack\n[doc-display-depth]]u ++. ++. if !\n[doc-is-compact] \ ++. sp \n[doc-display-vertical]u ++. ++. if "\*[doc-display-type-stack\n[doc-display-depth]]"literal" \ ++. if t \ ++. nop \*[doc-Li-font]\c ++. ++. if !\n[cR] \ ++. ne 2v ++. ++. if !"\*[doc-display-file]"" \ ++. so \*[doc-display-file] ++. ++. nr doc-is-compact 0 ++. ds doc-display-file ++.. ++. ++. ++.\" NS doc-do-Bd-args macro ++.\" NS resolve remaining .Bd arguments ++.\" NS ++.\" NS modifies: ++.\" NS doc-display-file ++.\" NS doc-display-indent-stackXXX ++.\" NS doc-is-compact ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-ddBa ++.\" NS doc-reg-ddBa1 ++.\" NS doc-reg-ddBa2 ++.\" NS doc-reg-ddBa3 ++.\" NS doc-reg-ddBa4 ++.\" NS doc-str-ddBa ++. ++.de doc-do-Bd-args ++. nr doc-reg-ddBa 1 ++. ++. ie "\$1"-offset" \{\ ++. nr doc-reg-ddBa 2 ++. ++. ie "\$2"left" \ ++. nr doc-display-indent-stack\n[doc-display-depth] 0 ++. el \{ .ie "\$2"right" \ ++. nr doc-display-indent-stack\n[doc-display-depth] (\n[.l]u / 3u) ++. el \{ .ie "\$2"center" \ ++. nr doc-display-indent-stack\n[doc-display-depth] ((\n[.l]u - \n[.i]u) / 4u) ++. el \{ .ie "\$2"indent" \ ++. nr doc-display-indent-stack\n[doc-display-depth] \n[doc-display-indent]u ++. el \{ .ie "\$2"indent-two" \ ++. nr doc-display-indent-stack\n[doc-display-depth] (\n[doc-display-indent]u + \n[doc-display-indent]u) ++. el \ ++. nr doc-reg-ddBa 1 ++. \}\}\}\} ++. ++. \" not a known keyword ++. if (\n[doc-reg-ddBa] == 1) \{\ ++. nr doc-reg-ddBa 2 ++. ++. nr doc-reg-ddBa1 0 ++. if \B(\$2) \{\ ++. \" disable warnings related to scaling indicators (32) ++. nr doc-reg-ddBa2 \n[.warn] ++. warn (\n[.warn] - (\n[.warn] / 32 % 2 * 32)) ++. ++. \" values without a scaling indicator are taken as strings; ++. \" we test whether the parameter string with and without the last ++. \" character yields identical numerical results (ignoring the ++. \" scaling indicator) ++. ds doc-str-ddBa "\$2 ++. substring doc-str-ddBa 0 -2 ++. if \B(\*[doc-str-ddBa]) \{\ ++. nr doc-reg-ddBa3 (;(\$2)) ++. nr doc-reg-ddBa4 (\*[doc-str-ddBa]) ++. if (\n[doc-reg-ddBa3] == \n[doc-reg-ddBa4]) \ ++. nr doc-reg-ddBa1 1 ++. \} ++. ++. \" enable all warnings again ++. warn \n[doc-reg-ddBa2] ++. \} ++. ++. ie \n[doc-reg-ddBa1] \ ++. nr doc-display-indent-stack\n[doc-display-depth] \$2 ++. el \{\ ++. doc-get-width "\$2" ++. ie (\n[doc-width] <= 3) \{\ ++. \" if the offset parameter is a macro, use the macro's ++. \" width as specified in doc-common ++. doc-get-arg-type "\$2" ++. ie (\n[doc-arg-type] == 1) \ ++. nr doc-display-indent-stack\n[doc-display-depth] \n[\$2] ++. el \ ++. nr doc-display-indent-stack\n[doc-display-depth] (\n[doc-width]u * \n[doc-fixed-width]u) ++. \} ++. el \ ++. nr doc-display-indent-stack\n[doc-display-depth] (\n[doc-width]u * \n[doc-fixed-width]u) ++. \}\} ++. \} ++. el \{ .ie "\$1"-compact" \ ++. nr doc-is-compact 1 ++. el \{ .ie "\$1"-file" \{\ ++. ie !"\$2"" \{\ ++. ds doc-display-file "\$2 ++. nr doc-reg-ddBa 2 ++. \} ++. el \ ++. tm mdoc warning: .Bd `-file' keyword requires argument (#\n[.c]) ++. \} ++. el \ ++. tm mdoc warning: Unknown keyword `\$1' in .Bd macro (#\n[.c]) ++. \}\} ++. ++. if (\n[doc-reg-ddBa] < \n[.$]) \{\ ++. shift \n[doc-reg-ddBa] ++. doc-do-Bd-args \$@ ++. \} ++.. ++. ++. ++.\" NS Ed user macro ++.\" NS end display ++.\" NS ++.\" NS modifies: ++.\" NS doc-display-depth ++.\" NS doc-display-indent-stackXXX ++.\" NS doc-display-type-stackXXX ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Ed' set in doc-common ++. ++.de Ed ++. ds doc-macro-name Ed ++. ++. br ++. ++. if !\n[doc-display-depth] \{\ ++. tm mdoc warning: Extraneous .Ed (#\n[.c]) ++. nr doc-display-depth 1 ++. \} ++. ++. if "\*[doc-display-type-stack\n[doc-display-depth]]"literal" \{\ ++. ft \n[doc-display-ft-stack\n[doc-display-depth]] ++. ps \n[doc-display-ps-stack\n[doc-display-depth]]u ++. \} ++. ++. in -\n[doc-display-indent-stack\n[doc-display-depth]]u ++. ++. \" restore saved adjustment and fill modes ++. ie \n[doc-display-fi-stack\n[doc-display-depth]] \ ++. fi ++. el \ ++. nf ++. ad \n[doc-display-ad-stack\n[doc-display-depth]] ++. ++. nr doc-display-indent-stack\n[doc-display-depth] 0 ++. ds doc-display-type-stack\n[doc-display-depth] ++. nr doc-display-depth -1 ++.. ++. ++. ++.\" NS doc-list-type-stackXXX global string ++.\" NS stack of list types ++.\" NS ++.\" NS limit: ++.\" NS doc-list-depth ++. ++.ds doc-list-type-stack1 ++. ++. ++.\" NS doc-list-indent-stackXXX global register ++.\" NS stack of list indentation values ++.\" NS ++.\" NS limit: ++.\" NS doc-list-depth ++. ++.nr doc-list-indent-stack1 0 ++. ++. ++.\" NS doc-list-have-indent-stackXXX global register (bool) ++.\" NS an indentation value is active ++.\" NS ++.\" NS limit: ++.\" NS doc-list-depth ++. ++.nr doc-list-have-indent-stack1 0 ++. ++. ++.\" NS Bl user macro ++.\" NS begin list ++.\" NS ++.\" NS width register `Bl' set in doc-common ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-argXXX ++.\" NS doc-list-depth ++.\" NS doc-list-have-indent-stackXXX ++.\" NS doc-list-indent-stackXXX ++.\" NS doc-list-type-stackXXX ++.\" NS doc-macro-name ++.\" NS doc-num-args ++.\" NS doc-num-columns ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-Bl ++. ++.de Bl ++. if !\n[.$] \{\ ++. doc-Bl-usage ++. return ++. \} ++. ++. ds doc-macro-name Bl ++. nr doc-list-depth +1 ++. nr doc-arg-ptr 1 ++. ++. ie "\$1"-hang" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] hang-list ++. nr doc-list-indent-stack\n[doc-list-depth] 6n ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. el \{ .ie "\$1"-tag" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] tag-list ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. el \{ .ie "\$1"-item" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] item-list ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. el \{ .ie "\$1"-enum" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] enum-list ++. nr doc-list-indent-stack\n[doc-list-depth] 3n ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. el \{ .ie "\$1"-bullet" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] bullet-list ++. nr doc-list-indent-stack\n[doc-list-depth] 2n ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. el \{ .ie "\$1"-dash" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] dash-list ++. nr doc-list-indent-stack\n[doc-list-depth] 2n ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. el \{ .ie "\$1"-hyphen" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] dash-list ++. nr doc-list-indent-stack\n[doc-list-depth] 2n ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. el \{ .ie "\$1"-inset" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] inset-list ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. el \{ .ie "\$1"-diag" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] diag-list ++. \} ++. el \{ .ie "\$1"-ohang" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] ohang-list ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. el \{ .ie "\$1"-column" \{\ ++. ds doc-list-type-stack\n[doc-list-depth] column-list ++. linetabs 1 ++. \} ++. el \{\ ++. tm1 "mdoc warning: Unknown list type `\$1' (or missing list type) ++. tm1 " in .Bl macro ++. tm ++. nr doc-arg-ptr 0 ++. \}\}\}\}\}\}\}\}\}\}\} ++. ++. \" we have seen a list type ++. if !\n[doc-arg-ptr] \{\ ++. doc-Bl-usage ++. doc-reset-args ++. nr doc-list-depth -1 ++. return ++. \} ++. ++. shift ++. ++. \" fill argument vector ++. nr doc-reg-Bl 1 ++. while (\n[doc-reg-Bl] <= \n[.$]) \{\ ++. ds doc-arg\n[doc-reg-Bl] "\$[\n[doc-reg-Bl]] ++. \" dummy type and space so that doc-save-global-vars() doesn't warn ++. nr doc-type\n[doc-reg-Bl] 0 ++. ds doc-space\n[doc-reg-Bl] ++. nr doc-reg-Bl +1 ++. \} ++. ++. doc-increment-list-stack ++. ++. if \n[.$] \{\ ++. nr doc-arg-limit \n[.$] ++. nr doc-arg-ptr 0 ++. doc-do-Bl-args ++. ++. in +\n[doc-list-offset-stack\n[doc-list-depth]]u ++. ++. \" initialize column list ++. if "\*[doc-list-type-stack\n[doc-list-depth]]"column-list" \{\ ++. doc-set-column-tab \n[doc-num-columns] ++' in -\n[doc-column-indent-width]u ++. if !\n[doc-compact-list-stack\n[doc-list-depth]] \ ++. sp \n[doc-display-vertical]u ++. ++. nf ++. nr doc-num-columns 0 ++. \}\} ++. ++. doc-reset-args ++.. ++. ++. ++.\" NS doc-Bl-usage macro ++. ++.de doc-Bl-usage ++. tm1 "Usage: .Bl {-hang | -ohang | -tag | -diag | -inset} ++. tm1 " [-width ] ++. tm1 " [-offset ] [-compact] ++. tm1 " .Bl -column [-offset ] ... ++. tm1 " .Bl {-item | -enum [-nested] | -bullet | -hyphen | -dash} ++. tm1 " [-offset ] [-compact] (#\n[.c]) ++.. ++. ++. ++.\" NS doc-do-Bl-args macro ++.\" NS resolve remaining .Bl arguments ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-argXXX ++.\" NS doc-compact-list-stackXXX ++.\" NS doc-list-indent-stackXXX ++.\" NS doc-list-offset-stackXXX ++.\" NS doc-num-columns ++.\" NS doc-tag-prefix-stackXXX ++.\" NS doc-tag-width-stackXXX ++.\" NS ++.\" NS local variables: ++.\" NS doc-box-dBla ++.\" NS doc-env-dBla ++.\" NS doc-reg-dBla ++.\" NS doc-reg-dBla1 ++.\" NS doc-reg-dBla2 ++.\" NS doc-reg-dBla3 ++.\" NS doc-reg-dBla4 ++.\" NS doc-str-dBla ++.\" NS doc-str-dBla1 ++. ++.de doc-do-Bl-args ++. nr doc-arg-ptr +1 ++. ++. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \ ++. return ++. ++. \" avoid a warning message in case e.g. `-offset' has no parameter ++. nr doc-reg-dBla (\n[doc-arg-ptr] + 1) ++. if (\n[doc-arg-limit] < \n[doc-reg-dBla]) \ ++. ds doc-arg\n[doc-reg-dBla] ++. ++. nr doc-reg-dBla 1 ++. ++. ie "\*[doc-arg\n[doc-arg-ptr]]"-compact" \ ++. nr doc-compact-list-stack\n[doc-list-depth] 1 ++. ++. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-nested" \{\ ++. ie (\n[doc-list-depth] > 1) \{\ ++. nr doc-reg-dBla1 (\n[doc-list-depth] - 1) ++. ds doc-tag-prefix-stack\n[doc-list-depth] "\*[doc-tag-prefix-stack\n[doc-reg-dBla1]] ++. as doc-tag-prefix-stack\n[doc-list-depth] \n[doc-enum-list-count-stack\n[doc-reg-dBla1]]. ++. length doc-reg-dBla1 "\*[doc-tag-prefix-stack\n[doc-list-depth]] ++. nr doc-list-indent-stack\n[doc-list-depth] +\n[doc-reg-dBla1]n ++. \} ++. el \ ++. tm mdoc warning: `-nested' allowed with nested .Bl macros only (#\n[.c]) ++. \} ++. ++. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-width" \{\ ++. nr doc-arg-ptr +1 ++. ds doc-tag-width-stack\n[doc-list-depth] TagwidtH ++. ++. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] ++. substring doc-str-dBla 0 0 ++. ie .\*[doc-str-dBla] \{\ ++. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] ++. substring doc-str-dBla 1 ++. doc-first-parameter \*[doc-str-dBla] ++. doc-get-width "\*[doc-str-dfp] ++. doc-get-arg-type "\*[doc-str-dfp] ++. ie (\n[doc-arg-type] == 1) \ ++. nr doc-reg-dBla1 1 ++. el \ ++. nr doc-reg-dBla1 0 ++. \} ++. el \ ++. nr doc-reg-dBla1 0 ++. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] ++. ++. ie \n[doc-reg-dBla1] \{\ ++. \" execute string in a box to get the width of the diversion ++. ds doc-str-dBla \*[doc-arg\n[doc-arg-ptr]] ++. doc-save-global-vars ++. doc-reset-args ++. box doc-box-dBla ++. ev doc-env-dBla ++. evc 0 ++. in 0 ++. nf ++. nop \*[doc-str-dBla] ++. br ++. ev ++. box ++. doc-restore-global-vars ++. doc-get-width \h'\n[dl]u' ++. nr doc-list-indent-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) ++. \} ++. el \{\ ++. \" test whether argument is a valid numeric expression ++. nr doc-reg-dBla1 0 ++. if \B(\*[doc-str-dBla]) \{\ ++. \" disable warnings related to scaling indicators (32) ++. nr doc-reg-dBla2 \n[.warn] ++. warn (\n[.warn] - (\n[.warn] / 32 % 2 * 32)) ++. ++. \" values without a scaling indicator are taken as strings; ++. \" we test whether the parameter string with and without the last ++. \" character yields identical numerical results (ignoring the ++. \" scaling indicator) ++. ds doc-str-dBla1 "\*[doc-str-dBla] ++. substring doc-str-dBla1 0 -2 ++. if \B(\*[doc-str-dBla1]) \{\ ++. nr doc-reg-dBla3 (;(\*[doc-str-dBla])) ++. nr doc-reg-dBla4 (\*[doc-str-dBla1]) ++. if (\n[doc-reg-dBla3] == \n[doc-reg-dBla4]) \ ++. nr doc-reg-dBla1 1 ++. \} ++. ++. \" enable all warnings again ++. warn \n[doc-reg-dBla2] ++. \} ++. ++. ie \n[doc-reg-dBla1] \ ++. nr doc-list-indent-stack\n[doc-list-depth] (\*[doc-str-dBla]) ++. el \{\ ++. doc-get-arg-width \n[doc-arg-ptr] ++. ie (\n[doc-width] == 2) \{\ ++. \" if the width parameter is a macro, use the macro's ++. \" width as specified in doc-common ++. doc-get-arg-type \*[doc-str-dBla] ++. ie (\n[doc-arg-type] == 1) \ ++. nr doc-list-indent-stack\n[doc-list-depth] \n[\*[doc-str-dBla]] ++. el \ ++. nr doc-list-indent-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) ++. \} ++. el \ ++. nr doc-list-indent-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) ++. \}\}\} ++. ++. el \{ .ie "\*[doc-arg\n[doc-arg-ptr]]"-offset" \{\ ++. nr doc-arg-ptr +1 ++. ++. ie "\*[doc-arg\n[doc-arg-ptr]]"indent" \ ++. nr doc-list-offset-stack\n[doc-list-depth] \n[doc-display-indent]u ++. el \{\ ++. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] ++. nr doc-reg-dBla1 0 ++. if \B(\*[doc-str-dBla]) \{\ ++. nr doc-reg-dBla2 \n[.warn] ++. warn (\n[.warn] - (\n[.warn] / 32 % 2 * 32)) ++. ++. ds doc-str-dBla1 "\*[doc-str-dBla] ++. substring doc-str-dBla1 0 -2 ++. if \B(\*[doc-str-dBla1]) \{\ ++. nr doc-reg-dBla3 (;(\*[doc-str-dBla])) ++. nr doc-reg-dBla4 (\*[doc-str-dBla1]) ++. if (\n[doc-reg-dBla3] == \n[doc-reg-dBla4]) \ ++. nr doc-reg-dBla1 1 ++. \} ++. ++. warn \n[doc-reg-dBla2] ++. \} ++. ++. ie \n[doc-reg-dBla1] \ ++. nr doc-list-offset-stack\n[doc-list-depth] \*[doc-str-dBla] ++. el \{\ ++. doc-get-arg-width \n[doc-arg-ptr] ++. ie (\n[doc-width] <= 3) \{\ ++. \" if the offset parameter is a macro, use the macro's ++. \" width as specified in doc-common ++. doc-get-arg-type \*[doc-str-dBla] ++. ie (\n[doc-arg-type] == 1) \ ++. nr doc-list-offset-stack\n[doc-list-depth] \n[\*[doc-str-dBla]] ++. el \ ++. nr doc-list-offset-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) ++. \} ++. el \ ++. nr doc-list-offset-stack\n[doc-list-depth] (\n[doc-width]u * \n[doc-fixed-width]u) ++. \}\}\} ++. el \ ++. nr doc-reg-dBla 0 ++. \}\}\} ++. ++. \" not a known keyword, so it specifies the width of the next column ++. \" (if it is a column list) ++. if !\n[doc-reg-dBla] \{\ ++. ie "\*[doc-list-type-stack\n[doc-list-depth]]"column-list" \{\ ++. nr doc-num-columns +1 ++. ds doc-str-dBla \*[doc-arg\n[doc-arg-ptr]] ++. substring doc-str-dBla 0 0 ++. ie .\*[doc-str-dBla] \{\ ++. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] ++. substring doc-str-dBla 1 ++. doc-first-parameter \*[doc-str-dBla] ++. doc-get-width "\*[doc-str-dfp] ++. doc-get-arg-type "\*[doc-str-dfp] ++. ie (\n[doc-arg-type] == 1) \ ++. nr doc-reg-dBla1 1 ++. el \ ++. nr doc-reg-dBla1 0 ++. \} ++. el \ ++. nr doc-reg-dBla1 0 ++. ds doc-str-dBla "\*[doc-arg\n[doc-arg-ptr]] ++. ++. ie \n[doc-reg-dBla1] \{\ ++. \" execute string in a box to get the width of the diversion ++. ds doc-str-dBla \*[doc-arg\n[doc-arg-ptr]] ++. doc-save-global-vars ++. doc-reset-args ++. box doc-box-dBla ++. ev doc-env-dBla ++. evc 0 ++. in 0 ++. nf ++. nop \*[doc-str-dBla] ++. br ++. ev ++. box ++. doc-restore-global-vars ++. ds doc-arg\n[doc-num-columns] "\h'\n[dl]u' ++. \} ++. el \ ++. ds doc-arg\n[doc-num-columns] "\*[doc-arg\n[doc-arg-ptr]] ++. \} ++. el \{\ ++. tmc mdoc warning: Unknown keyword `\*[doc-arg\n[doc-arg-ptr]]' ++. tm1 " in .Bl macro (#\n[.c]) ++. \}\} ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \ ++. doc-do-Bl-args ++.. ++. ++. ++.\" NS doc-save-global-vars macro ++.\" NS save all global variables ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dsgv ++. ++.de doc-save-global-vars ++. ds doc-macro-name-saved "\*[doc-macro-name] ++. nr doc-arg-limit-saved \n[doc-arg-limit] ++. nr doc-num-args-saved \n[doc-num-args] ++. nr doc-arg-ptr-saved \n[doc-arg-ptr] ++. ++. nr doc-reg-dsgv 1 ++. while (\n[doc-reg-dsgv] <= \n[doc-arg-limit]) \{\ ++. ds doc-arg\n[doc-reg-dsgv]-saved "\*[doc-arg\n[doc-reg-dsgv]] ++. nr doc-type\n[doc-reg-dsgv]-saved \n[doc-type\n[doc-reg-dsgv]] ++. ds doc-space\n[doc-reg-dsgv]-saved "\*[doc-space\n[doc-reg-dsgv]] ++. nr doc-reg-dsgv +1 ++. \} ++. ++. nr doc-curr-font-saved \n[doc-curr-font] ++. nr doc-curr-size-saved \n[doc-curr-size] ++. nr doc-in-synopsis-section-saved \n[doc-in-synopsis-section] ++. nr doc-in-library-section-saved \n[doc-in-library-section] ++. nr doc-indent-synopsis-saved \n[doc-indent-synopsis] ++. nr doc-indent-synopsis-active-saved \n[doc-indent-synopsis-active] ++. nr doc-have-decl-saved \n[doc-have-decl] ++. nr doc-have-var-saved \n[doc-have-var] ++. ds doc-command-name-saved "\*[doc-command-name] ++. ds doc-quote-left-saved "\*[doc-quote-left] ++. ds doc-quote-right-saved "\*[doc-quote-right] ++. nr doc-nesting-level-saved \n[doc-nesting-level] ++. nr doc-in-list-saved \n[doc-in-list] ++. ds doc-space-saved "\*[doc-space] ++. ds doc-saved-space-saved "\*[doc-saved-space] ++. nr doc-space-mode-saved \n[doc-space-mode] ++. nr doc-have-space-saved \n[doc-have-space] ++. nr doc-have-slot-saved \n[doc-have-slot] ++. nr doc-keep-type-saved \n[doc-keep-type] ++. nr doc-display-depth-saved \n[doc-display-depth] ++. nr doc-is-compact-saved \n[doc-is-compact] ++. ++. nr doc-reg-dsgv 0 ++. while (\n[doc-reg-dsgv] <= \n[doc-display-depth]) \{\ ++. ds doc-display-type-stack\n[doc-reg-dsgv]-saved "\*[doc-display-type-stack\n[doc-reg-dsgv]] ++. nr doc-display-indent-stack\n[doc-reg-dsgv]-saved \n[doc-display-indent-stack\n[doc-reg-dsgv]] ++. nr doc-display-ad-stack\n[doc-reg-dsgv]-saved \n[doc-display-ad-stack\n[doc-reg-dsgv]] ++. nr doc-display-fi-stack\n[doc-reg-dsgv]-saved \n[doc-display-fi-stack\n[doc-reg-dsgv]] ++. nr doc-display-ft-stack\n[doc-reg-dsgv]-saved \n[doc-display-ft-stack\n[doc-reg-dsgv]] ++. nr doc-display-ps-stack\n[doc-reg-dsgv]-saved \n[doc-display-ps-stack\n[doc-reg-dsgv]] ++. nr doc-reg-dsgv +1 ++. \} ++. ++. nr doc-fontmode-depth-saved \n[doc-fontmode-depth] ++. ++. nr doc-reg-dsgv 1 ++. while (\n[doc-reg-dsgv] <= \n[doc-fontmode-depth]) \{\ ++. nr doc-fontmode-font-stack\n[doc-reg-dsgv]-saved \n[doc-fontmode-font-stack\n[doc-reg-dsgv]] ++. nr doc-fontmode-size-stack\n[doc-reg-dsgv]-saved \n[doc-fontmode-size-stack\n[doc-reg-dsgv]] ++. nr doc-reg-dsgv +1 ++. \} ++. ++. nr doc-list-depth-saved \n[doc-list-depth] ++. ++. nr doc-reg-dsgv 1 ++. while (\n[doc-reg-dsgv] <= \n[doc-list-depth]) \{\ ++. ds doc-list-type-stack\n[doc-reg-dsgv]-saved "\*[doc-list-type-stack\n[doc-reg-dsgv]] ++. nr doc-list-have-indent-stack\n[doc-reg-dsgv]-saved \n[doc-list-have-indent-stack\n[doc-reg-dsgv]] ++. nr doc-list-indent-stack\n[doc-reg-dsgv]-saved \n[doc-list-indent-stack\n[doc-reg-dsgv]] ++. nr doc-compact-list-stack\n[doc-reg-dsgv]-saved \n[doc-compact-list-stack\n[doc-reg-dsgv]] ++. ds doc-tag-prefix-stack\n[doc-reg-dsgv]-saved "\*[doc-tag-prefix-stack\n[doc-reg-dsgv]] ++. ds doc-tag-width-stack\n[doc-reg-dsgv]-saved "\*[doc-tag-width-stack\n[doc-reg-dsgv]] ++. nr doc-list-offset-stack\n[doc-reg-dsgv]-saved \n[doc-list-offset-stack\n[doc-reg-dsgv]] ++. nr doc-enum-list-count-stack\n[doc-reg-dsgv]-saved \n[doc-enum-list-count-stack\n[doc-reg-dsgv]] ++. nr doc-reg-dsgv +1 ++. \} ++. ++. ds doc-saved-Pa-font-saved "\*[doc-saved-Pa-font] ++. nr doc-curr-type-saved \n[doc-curr-type] ++. ds doc-curr-arg-saved "\*[doc-curr-arg] ++. nr doc-diag-list-input-line-count-saved \n[doc-diag-list-input-line-count] ++. nr doc-num-columns-saved \n[doc-num-columns] ++. nr doc-column-indent-width-saved \n[doc-column-indent-width] ++. nr doc-is-func-saved \n[doc-is-func] ++. nr doc-have-old-func-saved \n[doc-have-old-func] ++. nr doc-func-arg-count-saved \n[doc-func-arg-count] ++. ds doc-func-arg-saved "\*[doc-func-arg] ++. nr doc-num-func-args-saved \n[doc-num-func-args] ++. nr doc-func-args-processed-saved \n[doc-func-args-processed] ++. nr doc-have-func-saved \n[doc-have-func] ++. nr doc-is-reference-saved \n[doc-is-reference] ++. nr doc-reference-count-saved \n[doc-reference-count] ++. nr doc-author-count-saved \n[doc-author-count] ++. ++. nr doc-reg-dsgv 0 ++. while (\n[doc-reg-dsgv] <= \n[doc-author-count]) \{\ ++. ds doc-author-name\n[doc-reg-dsgv]-saved "\*[doc-author-name\n[doc-reg-dsgv]] ++. nr doc-reg-dsgv +1 ++. \} ++. ++. nr doc-book-count-saved \n[doc-book-count] ++. ds doc-book-name-saved "\*[doc-book-name] ++. nr doc-city-count-saved \n[doc-city-count] ++. ds doc-city-name-saved "\*[doc-city-name] ++. nr doc-date-count-saved \n[doc-date-count] ++. ds doc-date-saved "\*[doc-date] ++. nr doc-publisher-count-saved \n[doc-publisher-count] ++. ds doc-publisher-name-saved "\*[doc-publisher-name] ++. nr doc-journal-count-saved \n[doc-journal-count] ++. ds doc-journal-name-saved "\*[doc-journal-name] ++. nr doc-issue-count-saved \n[doc-issue-count] ++. ds doc-issue-name-saved "\*[doc-issue-name] ++. nr doc-optional-count-saved \n[doc-optional-count] ++. ds doc-optional-string-saved "\*[doc-optional-string] ++. nr doc-page-number-count-saved \n[doc-page-number-count] ++. ds doc-page-number-string-saved "\*[doc-page-number-string] ++. nr doc-corporate-count-saved \n[doc-corporate-count] ++. ds doc-corporate-name-saved "\*[doc-corporate-name] ++. nr doc-report-count-saved \n[doc-report-count] ++. ds doc-report-name-saved "\*[doc-report-name] ++. nr doc-reference-title-count-saved \n[doc-reference-title-count] ++. ds doc-reference-title-name-saved "\*[doc-reference-title-name] ++. ds doc-reference-title-name-for-book-saved "\*[doc-reference-title-name-for-book] ++. nr doc-url-count-saved \n[doc-url-count] ++. ds doc-url-name-saved "\*[doc-url-name] ++. nr doc-volume-count-saved \n[doc-volume-count] ++. ds doc-volume-name-saved "\*[doc-volume-name] ++. nr doc-have-author-saved \n[doc-have-author] ++. ++. ds doc-document-title-saved "\*[doc-document-title] ++. ds doc-volume-saved "\*[doc-volume] ++. ds doc-section-saved "\*[doc-section] ++. ds doc-operating-system-saved "\*[doc-operating-system] ++. ds doc-date-string-saved "\*[doc-date-string] ++. nr doc-header-space-saved \n[doc-header-space] ++. nr doc-footer-space-saved \n[doc-footer-space] ++. nr doc-display-vertical-saved \n[doc-display-vertical] ++. ds doc-header-string-saved "\*[doc-header-string] ++. nr doc-in-see-also-section-saved \n[doc-in-see-also-section] ++. nr doc-in-files-section-saved \n[doc-in-files-section] ++. nr doc-in-authors-section-saved \n[doc-in-authors-section] ++.. ++. ++. ++.\" NS doc-restore-global-vars macro ++.\" NS restore all global variables ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-drgv ++. ++.de doc-restore-global-vars ++. ds doc-macro-name "\*[doc-macro-name-saved] ++. nr doc-arg-limit \n[doc-arg-limit-saved] ++. nr doc-num-args \n[doc-num-args-saved] ++. nr doc-arg-ptr \n[doc-arg-ptr-saved] ++. ++. nr doc-reg-drgv 1 ++. while (\n[doc-reg-drgv] <= \n[doc-arg-limit]) \{\ ++. ds doc-arg\n[doc-reg-drgv] "\*[doc-arg\n[doc-reg-drgv]-saved] ++. nr doc-type\n[doc-reg-drgv] \n[doc-type\n[doc-reg-drgv]-saved] ++. ds doc-space\n[doc-reg-drgv] "\*[doc-space\n[doc-reg-drgv]-saved] ++. nr doc-reg-drgv +1 ++. \} ++. ++. nr doc-curr-font \n[doc-curr-font-saved] ++. nr doc-curr-size \n[doc-curr-size-saved] ++. nr doc-in-synopsis-section \n[doc-in-synopsis-section-saved] ++. nr doc-in-library-section \n[doc-in-library-section-saved] ++. nr doc-indent-synopsis \n[doc-indent-synopsis-saved] ++. nr doc-indent-synopsis-active \n[doc-indent-synopsis-active-saved] ++. nr doc-have-decl \n[doc-have-decl-saved] ++. nr doc-have-var \n[doc-have-var-saved] ++. ds doc-command-name "\*[doc-command-name-saved] ++. ds doc-quote-left "\*[doc-quote-left-saved] ++. ds doc-quote-right "\*[doc-quote-right-saved] ++. nr doc-nesting-level \n[doc-nesting-level-saved] ++. nr doc-in-list \n[doc-in-list-saved] ++. ds doc-space "\*[doc-space-saved] ++. ds doc-saved-space "\*[doc-saved-space-saved] ++. nr doc-space-mode \n[doc-space-mode-saved] ++. nr doc-have-space \n[doc-have-space-saved] ++. nr doc-have-slot \n[doc-have-slot-saved] ++. nr doc-keep-type \n[doc-keep-type-saved] ++. nr doc-display-depth \n[doc-display-depth-saved] ++. nr doc-is-compact \n[doc-is-compact-saved] ++. ++. nr doc-reg-drgv 0 ++. while (\n[doc-reg-drgv] <= \n[doc-display-depth]) \{\ ++. ds doc-display-type-stack\n[doc-reg-drgv] "\*[doc-display-type-stack\n[doc-reg-drgv]-saved] ++. nr doc-display-indent-stack\n[doc-reg-drgv] \n[doc-display-indent-stack\n[doc-reg-drgv]-saved] ++. nr doc-display-ad-stack\n[doc-reg-drgv] \n[doc-display-ad-stack\n[doc-reg-drgv]-saved] ++. nr doc-display-fi-stack\n[doc-reg-drgv] \n[doc-display-fi-stack\n[doc-reg-drgv]-saved] ++. nr doc-display-ft-stack\n[doc-reg-drgv] \n[doc-display-ft-stack\n[doc-reg-drgv]-saved] ++. nr doc-display-ps-stack\n[doc-reg-drgv] \n[doc-display-ps-stack\n[doc-reg-drgv]-saved] ++. nr doc-reg-drgv +1 ++. \} ++. ++. nr doc-fontmode-depth \n[doc-fontmode-depth-saved] ++. ++. nr doc-reg-drgv 1 ++. while (\n[doc-reg-drgv] <= \n[doc-fontmode-depth]) \{\ ++. nr doc-fontmode-font-stack\n[doc-reg-drgv] \n[doc-fontmode-font-stack\n[doc-reg-drgv]]-saved ++. nr doc-fontmode-size-stack\n[doc-reg-drgv] \n[doc-fontmode-size-stack\n[doc-reg-drgv]]-saved ++. nr doc-reg-drgv +1 ++. \} ++. ++. nr doc-list-depth \n[doc-list-depth-saved] ++. ++. nr doc-reg-drgv 1 ++. while (\n[doc-reg-drgv] <= \n[doc-list-depth]) \{\ ++. ds doc-list-type-stack\n[doc-reg-drgv] "\*[doc-list-type-stack\n[doc-reg-drgv]-saved] ++. nr doc-list-have-indent-stack\n[doc-reg-drgv] \n[doc-list-have-indent-stack\n[doc-reg-drgv]-saved] ++. nr doc-list-indent-stack\n[doc-reg-drgv] \n[doc-list-indent-stack\n[doc-reg-drgv]-saved] ++. nr doc-compact-list-stack\n[doc-reg-drgv] \n[doc-compact-list-stack\n[doc-reg-drgv]-saved] ++. ds doc-tag-prefix-stack\n[doc-reg-drgv] "\*[doc-tag-prefix-stack\n[doc-reg-drgv]-saved] ++. ds doc-tag-width-stack\n[doc-reg-drgv] "\*[doc-tag-width-stack\n[doc-reg-drgv]-saved] ++. nr doc-list-offset-stack\n[doc-reg-drgv] \n[doc-list-offset-stack\n[doc-reg-drgv]-saved] ++. nr doc-enum-list-count-stack\n[doc-reg-drgv] \n[doc-enum-list-count-stack\n[doc-reg-drgv]-saved] ++. nr doc-reg-drgv +1 ++. \} ++. ++. ds doc-saved-Pa-font "\*[doc-saved-Pa-font-saved] ++. nr doc-curr-type \n[doc-curr-type-saved] ++. ds doc-curr-arg "\*[doc-curr-arg-saved] ++. nr doc-diag-list-input-line-count \n[doc-diag-list-input-line-count-saved] ++. nr doc-num-columns \n[doc-num-columns-saved] ++. nr doc-column-indent-width \n[doc-column-indent-width-saved] ++. nr doc-is-func \n[doc-is-func-saved] ++. nr doc-have-old-func \n[doc-have-old-func-saved] ++. nr doc-func-arg-count \n[doc-func-arg-count-saved] ++. ds doc-func-arg "\*[doc-func-arg-saved] ++. nr doc-num-func-args \n[doc-num-func-args-saved] ++. nr doc-func-args-processed \n[doc-func-args-processed-saved] ++. nr doc-have-func \n[doc-have-func-saved] ++. nr doc-is-reference \n[doc-is-reference-saved] ++. nr doc-reference-count \n[doc-reference-count-saved] ++. nr doc-author-count \n[doc-author-count-saved] ++. ++. nr doc-reg-drgv 0 ++. while (\n[doc-reg-drgv] <= \n[doc-author-count]) \{\ ++. ds doc-author-name\n[doc-reg-drgv] "\*[doc-author-name\n[doc-reg-drgv]-saved] ++. nr doc-reg-drgv +1 ++. \} ++. ++. nr doc-book-count \n[doc-book-count-saved] ++. ds doc-book-name "\*[doc-book-name-saved] ++. nr doc-city-count \n[doc-city-count-saved] ++. ds doc-city-name "\*[doc-city-name-saved] ++. nr doc-date-count \n[doc-date-count-saved] ++. ds doc-date "\*[doc-date-saved] ++. nr doc-publisher-count \n[doc-publisher-count-saved] ++. ds doc-publisher-name "\*[doc-publisher-name-saved] ++. nr doc-journal-count \n[doc-journal-count-saved] ++. ds doc-journal-name "\*[doc-journal-name-saved] ++. nr doc-issue-count \n[doc-issue-count-saved] ++. ds doc-issue-name "\*[doc-issue-name-saved] ++. nr doc-optional-count \n[doc-optional-count-saved] ++. ds doc-optional-string "\*[doc-optional-string-saved] ++. nr doc-page-number-count \n[doc-page-number-count-saved] ++. ds doc-page-number-string "\*[doc-page-number-string-saved] ++. nr doc-corporate-count \n[doc-corporate-count-saved] ++. ds doc-corporate-name "\*[doc-corporate-name-saved] ++. nr doc-report-count \n[doc-report-count-saved] ++. ds doc-report-name "\*[doc-report-name-saved] ++. nr doc-reference-title-count \n[doc-reference-title-count-saved] ++. ds doc-reference-title-name "\*[doc-reference-title-name-saved] ++. ds doc-reference-title-name-for-book "\*[doc-reference-title-name-for-book-saved] ++. nr doc-url-count \n[doc-url-count-saved] ++. ds doc-url-name "\*[doc-url-name-saved] ++. nr doc-volume-count \n[doc-volume-count-saved] ++. ds doc-volume-name "\*[doc-volume-name-saved] ++. nr doc-have-author \n[doc-have-author-saved] ++. ++. ds doc-document-title "\*[doc-document-title-saved] ++. ds doc-volume "\*[doc-volume-saved] ++. ds doc-section "\*[doc-section-saved] ++. ds doc-operating-system "\*[doc-operating-system-saved] ++. ds doc-date-string "\*[doc-date-string-saved] ++. nr doc-header-space \n[doc-header-space-saved] ++. nr doc-footer-space \n[doc-footer-space-saved] ++. nr doc-display-vertical \n[doc-display-vertical-saved] ++. ds doc-header-string "\*[doc-header-string-saved] ++. nr doc-in-see-also-section \n[doc-in-see-also-section-saved] ++. nr doc-in-files-section \n[doc-in-files-section-saved] ++. nr doc-in-authors-section \n[doc-in-authors-section-saved] ++.. ++. ++. ++.\" NS El user macro ++.\" NS end list ++.\" NS ++.\" NS modifies: ++.\" NS doc-list-depth ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variables: ++.\" NS doc-str-El ++.\" NS ++.\" NS width register `El' set in doc-common ++. ++.de El ++. if \n[.$] \{\ ++. tm Usage: .El (does not take arguments) (#\n[.c]) ++. return ++. \} ++. ++. ds doc-macro-name El ++. ds doc-str-El \*[doc-list-type-stack\n[doc-list-depth]] ++. ++. ie "\*[doc-str-El]"diag-list" \ ++. doc-end-list 0 ++. el \{ .ie "\*[doc-str-El]"column-list" \ ++. doc-end-column-list ++. el \{ .ie "\*[doc-str-El]"item-list" \ ++. doc-end-list 0 ++. el \{ .ie "\*[doc-str-El]"ohang-list" \ ++. doc-end-list 0 ++. el \{ .ie "\*[doc-str-El]"inset-list" \ ++. doc-end-list 0 ++. el \ ++. doc-end-list 1 ++. \}\}\}\} ++. ++. br ++.. ++. ++. ++.\" NS doc-saved-Pa-font global string ++.\" NS saved doc-Pa-font string for section FILES (no underline if ++.\" NS nroff) ++. ++.ds doc-saved-Pa-font ++. ++. ++.\" NS doc-curr-type global register ++.\" NS current argument type ++. ++.nr doc-curr-type 0 ++. ++. ++.\" NS doc-curr-arg global string ++.\" NS current argument ++. ++.ds doc-curr-arg ++. ++. ++.\" NS doc-item-boxXXX global box ++.\" NS item boxes associated list depth ++.\" NS ++.\" NS limit: ++.\" NS doc-list-depth ++. ++. ++.\" NS It user macro ++.\" NS list item ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-argXXX ++.\" NS doc-curr-arg ++.\" NS doc-curr-type ++.\" NS doc-in-list ++.\" NS doc-macro-name ++.\" NS doc-num-args ++.\" NS doc-saved-Pa-font ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-It ++.\" NS doc-str-It ++.\" NS doc-XXX-list-type ++.\" NS ++.\" NS width register `It' set in doc-common ++. ++.nr doc-bullet-list-type 1 ++.nr doc-column-list-type 0 ++.nr doc-dash-list-type 1 ++.nr doc-diag-list-type 0 ++.nr doc-enum-list-type 1 ++.nr doc-hang-list-type 2 ++.nr doc-inset-list-type 2 ++.nr doc-item-list-type 1 ++.nr doc-ohang-list-type 2 ++.nr doc-tag-list-type 2 ++. ++.de It ++. ds doc-str-It \*[doc-list-type-stack\n[doc-list-depth]] ++. ++. if "\*[doc-str-It]"" \ ++. tm mdoc error: .It without preceding .Bl (#\n[.c]) ++. ++. if \n[doc-nesting-level] \{\ ++. tmc "mdoc error: .It found in enclosing (e.g. .Ac ... .It ... .Ao) ++. tm1 " (#\n[.c]) ++. \} ++. ++. br ++. if !\n[cR] \ ++. ne 3v ++. ++. if \n[.$] \{\ ++. ds doc-macro-name It ++. ++. \" fill argument vector ++. nr doc-reg-It 1 ++. while (\n[doc-reg-It] <= \n[.$]) \{\ ++. ds doc-arg\n[doc-reg-It] "\$[\n[doc-reg-It]] ++. nr doc-reg-It +1 ++. \} ++. ++. nr doc-num-args \n[.$] ++. nr doc-arg-ptr 0 ++. \} ++. ++. nr doc-reg-It \n[doc-\*[doc-str-It]-type] ++. ++. if \n[doc-reg-It] \{\ ++. \" start item box ++. box doc-item-box\n[doc-list-depth] ++. ev doc-item-env\n[doc-list-depth] ++. evc 0 ++. in 0 ++. nf ++. \} ++. ++. ie (\n[doc-reg-It] == 1) \{\ ++. if \n[.$] \{\ ++. tm1 "mdoc warning: .It macros in lists of type `\*[doc-str-It]' ++. tm1 " don't take arguments (#\n[.c]) ++. \}\} ++. el \{\ ++. ie \n[.$] \{\ ++. if (\n[doc-reg-It] == 2) \{\ ++. \" handle list types with arguments ++. doc-parse-arg-vector ++. ++. nr doc-in-list 1 ++. nr doc-arg-ptr 1 ++. nr doc-curr-type \n[doc-type1] ++. ds doc-curr-arg "\*[doc-arg1] ++. ++. if \n[doc-in-files-section] \{\ ++. ds doc-saved-Pa-font "\*[doc-Pa-font] ++. if n \ ++. ds doc-Pa-font "\*[doc-No-font] ++. \} ++. ++. ie (\n[doc-type1] == 1) \ ++. \*[doc-arg1] ++. el \{\ ++. nr doc-arg-ptr 1 ++. doc-print-recursive ++. \}\}\} ++. el \{\ ++. tm1 "mdoc warning: .It macros in lists of type `\*[doc-str-It]' ++. tm1 " require arguments (#\n[.c]) ++. \} ++. \} ++. ++. \" the previous call of `.doc-print-recursive' can contain calls to ++. \" opening macros like `.Ao'; we then defer the call of `doc-xxx-list' ++. if !\n[doc-nesting-level] \ ++. doc-\*[doc-str-It] ++.. ++. ++. ++.\" NS doc-inset-list macro ++.\" NS .It item of list-type inset ++.\" NS ++.\" NS modifies: ++.\" NS doc-in-list ++. ++.de doc-inset-list ++. \" finish item box ++. br ++. ev ++. box ++. unformat doc-item-box\n[doc-list-depth] ++. ++. doc-set-vertical-and-indent 0 ++. br ++. ++. nh ++. doc-item-box\n[doc-list-depth] ++. ++. if \n[doc-in-files-section] \ ++. if n \ ++. ds doc-Pa-font "\*[doc-saved-Pa-font] ++. ++. nr doc-in-list 0 ++. doc-reset-args ++.. ++. ++. ++.\" NS doc-hang-list macro ++.\" NS .It item of list-type hanging tag (as opposed to tagged) ++.\" NS ++.\" NS modifies: ++.\" NS doc-have-space ++.\" NS doc-in-list ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dhl ++.\" NS doc-reg-dhl1 ++. ++.de doc-hang-list ++. \" finish item box ++. br ++. ev ++. box ++. unformat doc-item-box\n[doc-list-depth] ++. ++. doc-set-vertical-and-indent 1 ++. nr doc-reg-dhl (\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) ++. ti -\n[doc-reg-dhl]u ++. ++. nh ++. ie (\n[dl]u > \n[doc-list-indent-stack\n[doc-list-depth]]u) \ ++. doc-item-box\n[doc-list-depth] ++. el \{\ ++. chop doc-item-box\n[doc-list-depth] ++. nr doc-reg-dhl1 \n[.k]u ++. nop \*[doc-item-box\n[doc-list-depth]]\c ++. nop \h'|(\n[doc-reg-dhl1]u - \n[.k]u + \n[doc-reg-dhl]u)'\c ++. nr doc-have-space 1 ++. \} ++. ++. if \n[doc-in-files-section] \ ++. if n \ ++. ds doc-Pa-font "\*[doc-saved-Pa-font] ++. ++. nr doc-in-list 0 ++. doc-reset-args ++.. ++. ++. ++.\" NS doc-ohang-list macro ++.\" NS .It item of list-type overhanging tag ++.\" NS ++.\" NS modifies: ++.\" NS doc-in-list ++. ++.de doc-ohang-list ++. \" finish item box ++. br ++. ev ++. box ++. unformat doc-item-box\n[doc-list-depth] ++. ++. doc-set-vertical-and-indent 0 ++. nh ++. doc-item-box\n[doc-list-depth] ++. br ++. ++. if \n[doc-in-files-section] \ ++. if n \ ++. ds doc-Pa-font "\*[doc-saved-Pa-font] ++. ++. nr doc-in-list 0 ++. doc-reset-args ++.. ++. ++. ++.\" NS doc-item-list macro ++.\" NS .It item of list-type [empty tag] ++. ++.de doc-item-list ++. \" finish (dummy) item box ++. br ++. ev ++. box ++. ++. doc-set-vertical-and-indent 0 ++. br ++. ++. doc-reset-args ++.. ++. ++. ++.\" NS doc-enum-list-count-stackXXX global register ++.\" NS stack of current enum count values ++.\" NS ++.\" NS limit: ++.\" NS doc-list-depth ++. ++.nr doc-enum-list-count-stack1 0 ++. ++. ++.\" NS doc-enum-list macro ++.\" NS enumerated list ++.\" NS ++.\" NS modifies: ++.\" NS doc-enum-list-count-stackXXX ++.\" NS doc-in-list ++. ++.de doc-enum-list ++. nr doc-in-list 1 ++. nr doc-enum-list-count-stack\n[doc-list-depth] +1 ++\# XXX ++\#.ll \n[doc-list-indent-stack\n[doc-list-depth]]u ++\#.rj ++. nop \*[doc-tag-prefix-stack\n[doc-list-depth]]\c ++. nop \n[doc-enum-list-count-stack\n[doc-list-depth]].\& ++. doc-do-list ++.. ++. ++. ++.\" NS doc-bullet-list macro ++.\" NS bullet paragraph list ++.\" NS ++.\" NS modifies: ++.\" NS doc-in-list ++. ++.de doc-bullet-list ++. nr doc-in-list 1 ++. nop \)\*[doc-Sy-font]\[bu]\f[] ++. doc-do-list ++.. ++. ++. ++.\" NS doc-dash-list macro ++.\" NS hyphen paragraph list (sub bullet list) ++.\" NS ++.\" NS modifies: ++.\" NS doc-in-list ++. ++.de doc-dash-list ++. nr doc-in-list 1 ++. nop \)\*[doc-Sy-font]\-\f[] ++. doc-do-list ++.. ++. ++. ++.\" NS doc-do-list macro ++.\" NS .It item of list-type enum/bullet/hyphen ++. ++.als doc-do-list doc-hang-list ++. ++. ++.\" NS doc-diag-list-input-line-count global register ++.\" NS saved line number to be checked in next diag-list item ++. ++.nr doc-diag-list-input-line-count 0 ++. ++. ++.\" NS doc-diag-list macro ++.\" NS .It item of list-type diagnostic-message ++.\" NS ++.\" NS modifies: ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-diag-list-input-line-count ++. ++.de doc-diag-list ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. ie ((\n[.c] - \n[doc-diag-list-input-line-count]) > 1) \{\ ++. ie !\n[doc-compact-list-stack\n[doc-list-depth]] \ ++. doc-paragraph ++. el \ ++. br ++. \} ++. el \ ++. br ++. nr doc-diag-list-input-line-count \n[.c] ++. ++. nh ++. nop \*[doc-Sy-font]\c ++. if \n[doc-num-args] \ ++. doc-remaining-args ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\*[doc-hard-space]\c ++. ++. doc-print-and-reset ++.. ++. ++. ++.\" NS doc-tag-list macro ++.\" NS .It item of list-type `tag' ++.\" NS ++.\" NS modifies: ++.\" NS doc-have-space ++.\" NS doc-in-list ++.\" NS ++.\" NS local variables: ++.\" NS doc-box-dtl ++.\" NS doc-reg-dtl ++.\" NS doc-reg-dtl1 ++. ++.de doc-tag-list ++. \" finish item box ++. br ++. ev ++. box ++. unformat doc-item-box\n[doc-list-depth] ++. ++. \" we use a box without `.nf' to compute the tag width (via `dl' register) ++. box doc-box-dtl ++. ev doc-env-dtl ++. evc 0 ++. fi ++. ad 0 ++. in 0 ++. doc-item-box\n[doc-list-depth] ++. br ++. ev ++. box ++. ++. if !"TagwidtH"\*[doc-tag-width-stack\n[doc-list-depth]]" \{\ ++. if !\n[doc-list-have-indent-stack\n[doc-list-depth]] \{\ ++. in -(\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) ++. nr doc-list-have-indent-stack\n[doc-list-depth] 1 ++. \} ++. doc-get-tag-width ++. \} ++. doc-set-vertical-and-indent 1 ++. nr doc-reg-dtl (\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) ++. ti -\n[doc-reg-dtl]u ++. ++. nh ++. doc-item-box\n[doc-list-depth] ++. ie (\n[dl]u > \n[doc-list-indent-stack\n[doc-list-depth]]u) \ ++. br ++. el \{\ ++. \" format the tag separately to prevent stretching of spaces ++. vpt 0 ++. br ++. sp -1 ++. vpt 1 ++. nop \&\c ++. nr doc-have-space 1 ++. \} ++. ++. if \n[doc-in-files-section] \ ++. if n \ ++. ds doc-Pa-font "\*[doc-saved-Pa-font] ++. ++. nr doc-in-list 0 ++. doc-reset-args ++.. ++. ++. ++.\" NS doc-get-tag-width macro ++.\" NS resolve unknown tag width (`tag' list-type only) ++.\" NS ++.\" NS modifies: ++.\" NS doc-list-indent-stackXXX ++.\" NS doc-tag-width-stackXXX ++.\" NS ++.\" NS requires: ++.\" NS doc-curr-arg ++.\" NS doc-curr-type ++. ++.de doc-get-tag-width ++. ie (\n[doc-curr-type] == 1) \{\ ++. ds doc-tag-width-stack\n[doc-list-depth] \*[doc-curr-arg] ++. nr doc-list-indent-stack\n[doc-list-depth] \n[\*[doc-curr-arg]] ++. \} ++. el \{\ ++. ds doc-tag-width-stack\n[doc-list-depth] No ++. nr doc-list-indent-stack\n[doc-list-depth] \n[No] ++. \} ++.. ++. ++. ++.\" NS doc-set-vertical-and-indent macro ++.\" NS set up vertical spacing (if not compact) and indentation (with ++.\" NS offset if argument is non-zero) ++.\" NS ++.\" NS modifies: ++.\" NS doc-list-have-indent-stackXXX ++. ++.de doc-set-vertical-and-indent ++. if !\n[doc-compact-list-stack\n[doc-list-depth]] \ ++. sp \n[doc-display-vertical]u ++. ++. if \n[doc-list-have-indent-stack\n[doc-list-depth]] \{\ ++. nr doc-list-have-indent-stack\n[doc-list-depth] 0 ++. if \$1 \ ++. in +(\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) ++. \} ++. ++. if !\n[cR] \ ++. ne 2v ++.. ++. ++. ++.\" NS doc-list-depth global register ++.\" NS list type stack counter ++. ++.nr doc-list-depth 0 ++. ++. ++.\" NS doc-num-columns global register ++.\" NS number of columns ++. ++.nr doc-num-columns 0 ++. ++. ++.\" NS doc-compact-list-stackXXX global register (bool) ++.\" NS stack of flags to indicate whether a particular list is compact ++.\" NS ++.\" NS limit: ++.\" NS doc-list-depth ++. ++.nr doc-compact-list-stack1 0 ++. ++. ++.\" NS doc-tag-prefix-stackXXX global string ++.\" NS stack of tag prefixes (currently used for -nested -enum lists) ++.\" NS ++.\" NS limit: ++.\" NS doc-list-depth ++. ++.ds doc-tag-prefix-stack1 ++. ++. ++.\" NS doc-tag-width-stackXXX global string ++.\" NS stack of strings indicating how to set up current element of ++.\" NS doc-list-indent-stackXXX -- if set to TagwidtH, user has set it ++.\" NS directly; if it is a macro name, use the macro's width value; ++.\" NS otherwise, `doc-get-tag-width' uses width value of `No'. ++.\" NS ++.\" NS limit: ++.\" NS doc-list-depth ++. ++.ds doc-tag-width-stack0 ++.ds doc-tag-width-stack1 ++. ++. ++.\" NS doc-list-offset-stackXXX global register ++.\" NS stack of list offsets ++.\" NS ++.\" NS limit: ++.\" NS doc-list-depth ++. ++.nr doc-list-offset-stack1 0 ++. ++. ++.\" NS doc-end-list macro ++.\" NS list end function; resets indentation (and offset if argument is ++.\" NS non-zero) ++.\" NS ++.\" NS modifies: ++.\" NS doc-list-depth ++.\" NS doc-list-offset-stackXXX ++. ++.de doc-end-list ++. if \$1 \ ++' in -(\n[doc-list-indent-stack\n[doc-list-depth]]u + \n[doc-digit-width]u) ++. ++' in -\n[doc-list-offset-stack\n[doc-list-depth]]u ++. ++. if (\n[doc-list-depth] <= 0) \ ++. tm mdoc warning: extraneous .El call (#\n[.c]) ++. ++. doc-decrement-list-stack ++. nr doc-list-depth -1 ++.. ++. ++. ++.\" NS doc-increment-list-stack macro ++.\" NS set up next block for list ++.\" NS ++.\" NS modifies: ++.\" NS doc-compact-list-stackXXX ++.\" NS doc-list-have-indent-stackXXX ++.\" NS doc-list-indent-stackXXX ++.\" NS doc-list-offset-stackXXX ++.\" NS doc-list-type-stackXXX ++.\" NS doc-tag-prefix-stackXXX ++.\" NS doc-tag-width-stackXXX ++.\" NS doc-enum-list-count-stackXXX ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dils ++. ++.de doc-increment-list-stack ++. nr doc-reg-dils (\n[doc-list-depth] + 1) ++. nr doc-list-have-indent-stack\n[doc-reg-dils] 0 ++. nr doc-list-indent-stack\n[doc-reg-dils] 0 ++. nr doc-list-offset-stack\n[doc-reg-dils] 0 ++. ds doc-tag-prefix-stack\n[doc-reg-dils] ++. ds doc-tag-width-stack\n[doc-reg-dils] \*[doc-tag-width-stack\n[doc-list-depth]] ++. ds doc-list-type-stack\n[doc-reg-dils] ++. nr doc-compact-list-stack\n[doc-reg-dils] 0 ++. nr doc-enum-list-count-stack\n[doc-reg-dils] 0 ++.. ++. ++. ++.\" NS doc-decrement-list-stack macro ++.\" NS decrement stack ++.\" NS ++.\" NS modifies: ++.\" NS doc-compact-list-stackXXX ++.\" NS doc-list-have-indent-stackXXX ++.\" NS doc-list-indent-stackXXX ++.\" NS doc-list-offset-stackXXX ++.\" NS doc-list-type-stackXXX ++.\" NS doc-tag-prefix-stackXXX ++.\" NS doc-tag-width-stackXXX ++.\" NS doc-enum-list-count-stackXXX ++. ++.de doc-decrement-list-stack ++. ds doc-list-type-stack\n[doc-list-depth] ++. nr doc-list-have-indent-stack\n[doc-list-depth] 0 ++. nr doc-list-indent-stack\n[doc-list-depth] 0 ++. nr doc-list-offset-stack\n[doc-list-depth] 0 ++. ds doc-tag-prefix-stack\n[doc-list-depth] ++. ds doc-tag-width-stack\n[doc-list-depth] ++. nr doc-compact-list-stack\n[doc-list-depth] 0 ++. nr doc-enum-list-count-stack\n[doc-list-depth] 0 ++.. ++. ++. ++.\" NS Xr user macro ++.\" NS cross reference (for man pages only) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-macro-name ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-Xr ++.\" NS ++.\" NS width register `Xr' set in doc-common ++. ++.de Xr ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Xr ++. doc-parse-args \$@ ++. \} ++. el \ ++. doc-Xr-usage ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. doc-print-prefixes ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. \" first argument must be a string ++. ie (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ds doc-arg\n[doc-arg-ptr] \*[doc-Xr-font]\*[doc-arg\n[doc-arg-ptr]]\f[]\s[0] ++. ++. if (\n[doc-arg-limit] > \n[doc-arg-ptr]) \{\ ++. nr doc-reg-Xr (\n[doc-arg-ptr] + 1) ++. \" modify second argument if it is a string and ++. \" remove space in between ++. if (\n[doc-type\n[doc-reg-Xr]] == 2) \{\ ++. ds doc-arg\n[doc-reg-Xr] \*[lp]\*[doc-arg\n[doc-reg-Xr]]\*[rp] ++. ds doc-space\n[doc-arg-ptr] ++. \} ++. \} ++. doc-print-recursive ++. \} ++. el \ ++. doc-Xr-usage ++. \} ++. el \ ++. doc-Xr-usage ++.. ++. ++. ++.\" NS doc-Xr-usage macro ++. ++.de doc-Xr-usage ++. tm Usage: .Xr manpage_name [section#] ... (#\n[.c]) ++. doc-reset-args ++.. ++. ++. ++.\" NS Sx user macro ++.\" NS cross section reference ++.\" NS ++.\" NS width register `Sx' set in doc-common ++. ++.als Sx doc-generic-macro ++.ds doc-Sx-usage section_header ++. ++. ++.\" NS doc-end-column-list macro ++.\" NS column-list end-list ++.\" NS ++.\" NS modifies: ++.\" NS doc-list-depth ++. ++.de doc-end-column-list ++. linetabs 0 ++' in -(\n[doc-list-offset-stack\n[doc-list-depth]]u + \n[doc-list-indent-stack\n[doc-list-depth]]u) ++. ta T .5i ++. fi ++. doc-decrement-list-stack ++. nr doc-list-depth -1 ++.. ++. ++. ++.\" NS doc-column-indent-width global register ++.\" NS holds the indent width for a column list ++. ++.nr doc-column-indent-width 0 ++. ++. ++.\" NS doc-set-column-tab macro ++.\" NS establish tabs for list-type column: `.doc-set-column-tab num_cols' ++.\" NS ++.\" NS modifies: ++.\" NS doc-column-indent-width ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dsct ++.\" NS doc-str-dsct ++.\" NS doc-str-dsct1 ++. ++.de doc-set-column-tab ++. ds doc-str-dsct ++. nr doc-reg-dsct 1 ++. nr doc-column-indent-width 0 ++. ++. ie (\$1 < 5) \ ++. ds doc-str-dsct1 " \" ++. el \{\ ++. ie (\$1 == 5) \ ++. ds doc-str-dsct1 " \" ++. el \{\ ++. \" XXX: this is packed abnormally close -- intercolumn width ++. \" should be configurable ++. ds doc-str-dsct1 " \" ++. \}\} ++. ++. while (\n[doc-reg-dsct] <= \$1) \{\ ++. as doc-str-dsct " +\w\*[doc-arg\n[doc-reg-dsct]]\*[doc-str-dsct1]u ++. nr doc-column-indent-width +\w\*[doc-arg\n[doc-reg-dsct]]\*[doc-str-dsct1]u ++. nr doc-reg-dsct +1 ++. \} ++. ++. ta \*[doc-str-dsct] ++' in +\n[doc-column-indent-width]u ++.. ++. ++. ++.\" NS doc-column-list macro ++.\" NS column items ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-list-indent-stackXXX ++.\" NS doc-spaceXXX ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dcl ++. ++.de doc-column-list ++. if \n[doc-num-args] \ ++. doc-parse-arg-vector ++. nr doc-arg-ptr +1 ++. ++. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ ++. tm Usage: .It column_string [Ta [column_string ...] ] (#\n[.c]) ++. return ++. \} ++. ++. if "\*[doc-arg\n[doc-arg-ptr]]"Ta" \{\ ++. nr doc-reg-dcl (\n[doc-arg-ptr] - 1) ++. ds doc-space\n[doc-reg-dcl] ++. \} ++. ++. if !\n[doc-list-indent-stack\n[doc-list-depth]] \ ++. nr doc-list-indent-stack\n[doc-list-depth] \n[doc-column-indent-width]u ++. if !\n[.u] \{\ ++. fi ++. in +\n[doc-column-indent-width]u ++. \} ++. ti -\n[doc-column-indent-width]u ++. ++. doc-do-\n[doc-type\n[doc-arg-ptr]] ++.. ++. ++. ++.\" NS Ta user macro ++.\" NS append tab (\t) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS ++.\" NS width register `Ta' set in doc-common ++. ++.de Ta ++. ie \n[doc-arg-limit] \{\ ++. nr doc-arg-ptr +1 ++. nop \*[doc-tab]\c ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \ ++. doc-do-\n[doc-type\n[doc-arg-ptr]] ++. el \ ++. doc-reset-args ++. \} ++. el \{\ ++. tm1 "Usage: Ta must follow column entry: e.g. ++. tm1 " .It column_string [Ta [column_string ...]] (#\n[.c]) ++. \} ++.. ++. ++. ++.\" NS Dl user macro ++.\" NS display (one line) literal ++.\" NS ++.\" NS this function uses the `Li' font ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Dl' set in doc-common ++. ++.de Dl ++. ta T .5i ++. in +\n[doc-display-indent]u ++. ++. ie \n[doc-arg-limit] \{\ ++. tm Usage: .Dl not callable by other macros (#\n[.c]) ++. doc-reset-args ++. \} ++. el \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Dl ++. doc-parse-args \$@ ++. nr doc-arg-ptr 1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Li-font]\c ++. doc-print-recursive ++. \} ++. el \ ++. tm Usage: .Dl argument ... (#\n[.c]) ++. \} ++. ++. in -\n[doc-display-indent]u ++.. ++. ++. ++.\" NS D1 user macro ++.\" NS display (one line) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `D1' set in doc-common ++. ++.de D1 ++. ta T .5i ++. in +\n[doc-display-indent]u ++. ++. ie \n[doc-arg-limit] \{\ ++. tm Usage: .D1 not callable by other macros (#\n[.c]) ++. doc-reset-args ++. \} ++. el \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name D1 ++. doc-parse-args \$@ ++. nr doc-arg-ptr 1 ++. doc-print-recursive ++. \} ++. el \ ++. tm Usage: .D1 argument ... (#\n[.c]) ++. \} ++. ++. in -\n[doc-display-indent]u ++.. ++. ++. ++.\" NS Vt user macro ++.\" NS variable type (for forcing old style variable declarations); ++.\" NS this is not done in the same manner as .Ot for fortrash -- ++.\" NS clean up later ++.\" NS ++.\" NS modifies: ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-have-decl ++.\" NS doc-have-var ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Vt' set in doc-common ++. ++.de Vt ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Vt ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Vt variable_type ... (#\n[.c]) ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ ++. tm Usage: .Vt variable_type ... (#\n[.c]) ++. doc-reset-args ++. return ++. \} ++. ++. if \n[doc-in-synopsis-section] \{\ ++. \" if a function declaration was the last thing given, ++. \" want vertical space ++. if \n[doc-have-decl] \{\ ++. doc-paragraph ++. nr doc-have-decl 0 ++. \} ++. ++. \" if a subroutine was the last thing given, want vertical space ++. if \n[doc-have-func] \{\ ++. ie \n[doc-have-var] \ ++. br ++. el \ ++. doc-paragraph ++. \} ++. ++. nr doc-have-var 1 ++. \} ++. ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Ft-font]\c ++. doc-print-recursive ++. ++. if \n[doc-in-synopsis-section] \{\ ++. ie \n[doc-have-old-func] \ ++. nop \*[doc-soft-space]\c ++. el \ ++. br ++. \} ++.. ++. ++. ++.\" NS doc-is-func global register (bool) ++.\" NS set if subroutine (in synopsis only) (fortran only) ++. ++.nr doc-is-func 0 ++. ++. ++.\" NS Ft user macro ++.\" NS function type ++.\" NS ++.\" NS modifies: ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-have-decl ++.\" NS doc-have-var ++.\" NS doc-is-func ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Ft' set in doc-common ++. ++.de Ft ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Ft ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Ft function_type ... (#\n[.c]) ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. nr doc-arg-ptr +1 ++. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ ++. tm Usage: .Ft function_type ... (#\n[.c]) ++. doc-reset-args ++. return ++. \} ++. ++. if \n[doc-in-synopsis-section] \{\ ++. if (\n[doc-have-func] : \n[doc-have-decl]) \{\ ++. doc-paragraph ++. nr doc-have-decl 0 ++. nr doc-have-var 0 ++. \} ++. ++. if \n[doc-have-var] \{\ ++. doc-paragraph ++. nr doc-have-var 0 ++. \} ++. ++. nr doc-is-func 1 ++. \} ++. ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Ft-font]\c ++. doc-print-recursive ++.. ++. ++. ++.\" NS doc-have-old-func global register (bool) ++.\" NS set if `Ot' has been called ++. ++.nr doc-have-old-func 0 ++. ++. ++.\" NS Ot user macro ++.\" NS old function type (fortran -- no newline) ++.\" NS ++.\" NS modifies: ++.\" NS doc-have-decl ++.\" NS doc-have-old-func ++.\" NS doc-have-var ++.\" NS doc-is-func ++.\" NS ++.\" NS width register `Ot' set in doc-common ++. ++.de Ot ++. nr doc-have-old-func 1 ++. ++. if \n[doc-in-synopsis-section] \{\ ++. if (\n[doc-have-func] : \n[doc-have-decl]) \{\ ++. doc-paragraph ++. nr doc-have-decl 0 ++. nr doc-have-var 0 ++. \} ++. ++. if \n[doc-have-var] \{\ ++. doc-paragraph ++. nr doc-have-var 0 ++. \} ++. ++. nr doc-is-func 1 ++. \} ++. ++. if \n[.$] \ ++. nop \*[doc-Ft-font]\$*\c ++. nop \ \f[]\c ++.. ++. ++. ++.\" NS Fa user macro ++.\" NS function arguments ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Fa' set in doc-common ++. ++.de Fa ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Fa ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Fa function_arguments ... (#\n[.c]) ++. \} ++. ++. ie \n[doc-func-arg-count] \ ++. doc-do-func ++. el \{\ ++. nr doc-arg-ptr +1 ++. if (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Fa-font]\c ++. doc-print-recursive ++. ++. if \n[doc-in-synopsis-section] \ ++. if \n[doc-have-func] \ ++. br ++. \}\} ++.. ++. ++. ++.\" NS doc-func-arg-count global register ++.\" NS how many function arguments have been processed so far ++. ++.nr doc-func-arg-count 0 ++. ++. ++.\" NS doc-func-arg global string ++.\" NS work buffer for function name strings ++. ++.ds doc-func-arg ++. ++. ++.\" NS doc-num-func-args global register ++.\" NS number of function arguments ++. ++.nr doc-num-func-args 0 ++. ++. ++.\" NS doc-func-args-processed global register ++.\" NS function arguments processed so far ++. ++.nr doc-func-args-processed 0 ++. ++. ++.\" NS doc-do-func macro ++.\" NS internal .Fa for .Fc ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-argXXX ++.\" NS doc-func-arg ++.\" NS doc-func-arg-count ++.\" NS doc-func-args-processed ++.\" NS doc-num-func-args ++. ++.de doc-do-func ++. if (\n[doc-arg-limit] <= \n[doc-arg-ptr]) \{\ ++. doc-reset-args ++. return ++. \} ++. ++. nr doc-arg-ptr +1 ++. ++. ds doc-func-arg ++. nr doc-num-func-args 0 ++. nr doc-func-args-processed 0 ++. ++. doc-build-func-string \*[doc-arg\n[doc-arg-ptr]] ++. if (\n[doc-num-func-args] > 1) \ ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-func-arg] ++. ++. if (\n[doc-func-arg-count] > 1) \{\ ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\|\c ++. if !"\*[doc-arg\n[doc-arg-ptr]]"/*" \ ++. if !"\*[doc-arg\n[doc-arg-ptr]]"*/" \ ++. nop ,\)\c ++. nop \)\*[doc-space\n[doc-arg-ptr]]\*[doc-Fa-font]\c ++. nop \)\*[doc-arg\n[doc-arg-ptr]]\f[]\s[0]\c ++. \} ++. ++. if (\n[doc-func-arg-count] == 1) \{\ ++. nop \)\*[doc-Fa-font]\*[doc-arg\n[doc-arg-ptr]]\c ++. nop \f[]\s[0]\c ++. \} ++. nr doc-func-arg-count +1 ++. doc-do-func ++.. ++. ++. ++.\" NS doc-have-func global register (bool) ++.\" NS whether we have more than one function in synopsis ++. ++.nr doc-have-func 0 ++. ++. ++.\" NS Fn user macro ++.\" NS functions ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-have-decl ++.\" NS doc-have-func ++.\" NS doc-have-var ++.\" NS doc-indent-synopsis ++.\" NS doc-is-func ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Fn' set in doc-common ++. ++.de Fn ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Fn ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Fn function_name [function_arg] ... (#\n[.c]) ++. \} ++. ++. if !\n[doc-arg-limit] \ ++. return ++. ++. if \n[doc-in-synopsis-section] \{\ ++. \" if there is/has been more than one subroutine declaration ++. ie \n[doc-is-func] \{\ ++. br ++. nr doc-have-var 0 ++. nr doc-have-decl 0 ++. nr doc-is-func 0 ++. \} ++. el \{\ ++. if \n[doc-have-func] \{\ ++. doc-paragraph ++. nr doc-have-var 0 ++. nr doc-have-decl 0 ++. \}\} ++. ++. if \n[doc-have-decl] \{\ ++. doc-paragraph ++. nr doc-have-var 0 ++. \} ++. ++. if \n[doc-have-var] \{\ ++. doc-paragraph ++. nr doc-have-decl 0 ++. \} ++. ++. nr doc-have-func 1 ++. nr doc-is-func 0 ++. ++. br ++. if !\n[doc-indent-synopsis] \ ++. nr doc-indent-synopsis (4u * \n[doc-fixed-width]u) ++. if !\n[doc-indent-synopsis-active] \ ++. in +\n[doc-indent-synopsis]u ++. ti -\n[doc-indent-synopsis]u ++. \} ++. ++. nr doc-arg-ptr +1 ++. doc-print-prefixes ++. if (\n[doc-arg-limit] < \n[doc-arg-ptr]) \{\ ++. tm Usage: .Fn function_name [function_arg] ... (#\n[.c]) ++. doc-reset-args ++. return ++. \} ++. ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. nop \*[doc-Fn-font]\*[doc-arg\n[doc-arg-ptr]]\c ++. nop \f[]\s[0]\*[lp]\)\c ++. ++. nr doc-arg-ptr +1 ++. if (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. if (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. nop \*[doc-Fa-font]\c ++. doc-do-func-args ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c ++. \}\} ++. ++. nop \)\*[rp]\)\c ++. if \n[doc-in-synopsis-section] \ ++. nop \);\)\c ++. ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. \" output the space (if needed) ++. nr doc-arg-ptr -1 ++. nop \)\*[doc-space\n[doc-arg-ptr]]\c ++. nr doc-arg-ptr +1 ++. ++. doc-print-recursive ++. \} ++. el \ ++. doc-print-and-reset ++. ++. if \n[doc-in-synopsis-section] \ ++. if !\n[doc-indent-synopsis-active] \ ++. in -\n[doc-indent-synopsis]u ++.. ++. ++. ++.\" NS doc-do-func-args macro ++.\" NS handle function arguments ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-argXXX ++.\" NS doc-func-arg ++.\" NS doc-func-args-processed ++.\" NS doc-num-func-args ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-ddfa ++. ++.de doc-do-func-args ++. if \n[doc-in-synopsis-section] \{\ ++. ds doc-func-arg ++. nr doc-num-func-args 0 ++. nr doc-func-args-processed 0 ++. ++. doc-build-func-string \*[doc-arg\n[doc-arg-ptr]] ++. if (\n[doc-num-func-args] > 1) \ ++. ds doc-arg\n[doc-arg-ptr] "\*[doc-func-arg] ++. \} ++. ++. nop \)\*[doc-arg\n[doc-arg-ptr]]\c ++. nr doc-arg-ptr +1 ++. ++. if (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. if (\n[doc-type\n[doc-arg-ptr]] == 2) \{\ ++. nr doc-reg-ddfa (\n[doc-arg-ptr] - 1) ++. nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\|\c ++. if !"\*[doc-arg\n[doc-arg-ptr]]"/*" \ ++. if !"\*[doc-arg\n[doc-arg-ptr]]"*/" \ ++. nop ,\)\c ++. nop \)\*[doc-space\n[doc-reg-ddfa]]\f[]\s[0]\|\c ++. doc-do-func-args ++. \}\} ++.. ++. ++. ++.\" NS doc-saved-nesting-level global register ++. ++.nr doc-saved-nesting-level 0 ++. ++. ++.\" NS doc-in-func-enclosure global register (bool) ++. ++.nr doc-in-func-enclosure 0 ++. ++. ++.\" NS Fo user macro ++.\" NS function open ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-func-arg-count ++.\" NS doc-have-decl ++.\" NS doc-have-func ++.\" NS doc-have-var ++.\" NS doc-in-func-enclosure ++.\" NS doc-indent-synopsis ++.\" NS doc-is-func ++.\" NS doc-macro-name ++.\" NS doc-saved-nesting-level ++.\" NS ++.\" NS width register `Fo' set in doc-common ++. ++.de Fo ++. if (\n[doc-in-func-enclosure]) \{\ ++. tm mdoc error: .Fo/.Fc can't be nested (#\n[.c]) ++. return ++. \} ++. ++. nr doc-saved-nesting-level \n[doc-nesting-level] ++. nr doc-in-func-enclosure 1 ++. ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ds doc-macro-name Fo ++. doc-parse-args \$@ ++. \} ++. el \ ++. tm Usage: .Fo function_name (#\n[.c]) ++. \} ++. ++. if \n[doc-in-synopsis-section] \{\ ++. \" if there is/has been more than one subroutine declaration ++. ie \n[doc-is-func] \{\ ++. br ++. nr doc-have-var 0 ++. nr doc-have-decl 0 ++. nr doc-is-func 0 ++. \} ++. el \{\ ++. if \n[doc-have-func] \{\ ++. doc-paragraph ++. nr doc-have-var 0 ++. nr doc-have-decl 0 ++. \}\} ++. ++. if \n[doc-have-decl] \{\ ++. doc-paragraph ++. nr doc-have-var 0 ++. \} ++. ++. if \n[doc-have-var] \{\ ++. doc-paragraph ++. nr doc-have-decl 0 ++. \} ++. ++. nr doc-have-func 1 ++. nr doc-is-func 0 ++. ++. br ++. if !\n[doc-indent-synopsis] \ ++. nr doc-indent-synopsis (4u * \n[doc-fixed-width]u) ++. \} ++. ++. \" start function box ++. box doc-func-box ++. ev doc-func-env ++. evc 0 ++. in 0 ++. nf ++. ++. nr doc-arg-ptr +1 ++. doc-print-prefixes ++. if (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-func-arg-count 1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. nop \*[doc-Fn-font]\*[doc-arg\n[doc-arg-ptr]]\c ++. nop \f[]\s[0]\*[lp]\)\c ++. doc-reset-args ++. \} ++.. ++. ++. ++.\" NS Fc user macro ++.\" NS function close ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-func-arg-count ++.\" NS doc-in-func-enclosure ++.\" NS doc-saved-nesting-level ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `Fc' set in doc-common ++. ++.de Fc ++. if !\n[doc-in-func-enclosure] \{\ ++. tm mdoc warning: Extraneous .Fc (#\n[.c]) ++. return ++. \} ++. ++. if \n[.$] \{\ ++. ds doc-macro-name Fc ++. \" the first (dummy) argument is used to get the correct spacing ++. doc-parse-args \) \$@ ++. \} ++. ++. if !(\n[doc-saved-nesting-level] == \n[doc-nesting-level]) \ ++. tm mdoc warning: Unbalanced enclosure commands within .Fo/.Fc ++. ++. nr doc-func-arg-count 0 ++. nr doc-in-func-enclosure 0 ++. ++. ie \n[doc-in-synopsis-section] \ ++. nop \|\*[rp];\) ++. el \ ++. nop \|\*[rp]\) ++. ++. \" finish function box ++. br ++. ev ++. box ++. chop doc-func-box ++. unformat doc-func-box ++. ++. if \n[doc-in-synopsis-section] \{\ ++. if !\n[doc-indent-synopsis-active] \ ++. in +\n[doc-indent-synopsis]u ++. ti -\n[doc-indent-synopsis]u ++. \} ++. ++. nh ++. nop \*[doc-func-box]\c ++. ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. doc-print-recursive ++. \} ++. el \ ++. doc-print-and-reset ++. ++. if \n[doc-in-synopsis-section] \ ++. if !\n[doc-indent-synopsis-active] \ ++. in -\n[doc-indent-synopsis]u ++.. ++. ++. ++.\" NS doc-build-func-string macro ++.\" NS collect function arguments and set hard spaces in between ++.\" NS ++.\" NS modifies: ++.\" NS doc-func-arg ++.\" NS doc-func-args-processed ++.\" NS doc-num-func-args ++. ++.de doc-build-func-string ++. if !\n[doc-num-func-args] \{\ ++. nr doc-num-func-args \n[.$] ++. nr doc-func-args-processed 0 ++. ds doc-func-arg ++. \} ++. ++. nr doc-func-args-processed +1 ++. as doc-func-arg "\$1 ++. ++. if (\n[doc-func-args-processed] < \n[doc-num-func-args]) \{\ ++. as doc-func-arg "\*[doc-hard-space] ++. ++. shift ++. doc-build-func-string \$@ ++. \} ++.. ++. ++. ++.\" Very crude references: Stash all reference info into boxes, print out ++.\" reference on .Re macro and clean up. Ordering very limited, no fancy ++.\" citations, but can do articles, journals, and books -- need to add ++.\" several missing options (like city etc). Should be able to grab a refer ++.\" entry, massage it a wee bit (prefix a `.' to the %[A-Z]) and not worry ++.\" (ha!). ++. ++. ++.\" NS doc-is-reference global register (bool) ++.\" NS set if in reference ++. ++.nr doc-is-reference 0 ++. ++. ++.\" NS doc-reference-count global register ++.\" NS reference element counter ++. ++.nr doc-reference-count 0 ++. ++. ++.\" NS Rs user macro ++.\" NS reference start ++.\" NS ++.\" NS modifies: ++.\" NS doc-is-reference ++.\" NS doc-reference-count ++.\" NS ++.\" NS width register `Rs' set in doc-common ++. ++.de Rs ++. ie \n[.$] \ ++. tm Usage: .Rs (does not take arguments) (#\n[.c]) ++. el \{\ ++. nr doc-is-reference 1 ++. doc-reset-reference ++. if \n[doc-in-see-also-section] \ ++. doc-paragraph ++. nr doc-reference-count 0 ++. \} ++.. ++. ++. ++.\" NS Re user macro ++.\" NS reference end ++.\" NS ++.\" NS modifies: ++.\" NS doc-is-reference ++.\" NS ++.\" NS width register `Re' set in doc-common ++. ++.de Re ++. ie \n[.$] \ ++. tm Usage: .Re (does not take arguments) (#\n[.c]) ++. el \{\ ++. if !\n[doc-is-reference] \{\ ++. tm mdoc warning: Extraneous .Re (#\n[.c]) ++. return ++. \} ++. doc-print-reference ++. doc-reset-reference ++. nr doc-is-reference 0 ++. \} ++.. ++. ++. ++.\" NS doc-reset-reference macro ++.\" NS reference cleanup ++.\" NS ++.\" NS modifies: ++.\" NS doc-author-count ++.\" NS doc-author-nameXXX ++.\" NS doc-book-count ++.\" NS doc-book-name ++.\" NS doc-city-count ++.\" NS doc-city-name ++.\" NS doc-corporate-count ++.\" NS doc-corporate-name ++.\" NS doc-date ++.\" NS doc-date-count ++.\" NS doc-issue-count ++.\" NS doc-issue-name ++.\" NS doc-journal-count ++.\" NS doc-journal-name ++.\" NS doc-optional-count ++.\" NS doc-optional-string ++.\" NS doc-page-number-count ++.\" NS doc-page-number-string ++.\" NS doc-publisher-count ++.\" NS doc-publisher-name ++.\" NS doc-reference-count ++.\" NS doc-reference-title-count ++.\" NS doc-reference-title-name ++.\" NS doc-reference-title-name-for-book ++.\" NS doc-report-count ++.\" NS doc-report-name ++.\" NS doc-url-count ++.\" NS doc-url-name ++.\" NS doc-volume-count ++.\" NS doc-volume-name ++. ++.de doc-reset-reference ++. while (\n[doc-author-count]) \{\ ++. ds doc-author-name\n[doc-author-count] ++. nr doc-author-count -1 ++. \} ++. nr doc-journal-count 0 ++. nr doc-issue-count 0 ++. nr doc-optional-count 0 ++. nr doc-corporate-count 0 ++. nr doc-report-count 0 ++. nr doc-reference-title-count 0 ++. nr doc-url-count 0 ++. nr doc-volume-count 0 ++. nr doc-city-count 0 ++. nr doc-date-count 0 ++. nr doc-page-number-count 0 ++. nr doc-book-count 0 ++. nr doc-publisher-count 0 ++. nr doc-reference-count 0 ++. ++. ds doc-journal-name ++. ds doc-issue-name ++. ds doc-optional-string ++. ds doc-corporate-name ++. ds doc-report-name ++. ds doc-reference-title-name ++. ds doc-reference-title-name-for-book ++. ds doc-url-name ++. ds doc-volume-name ++. ds doc-city-name ++. ds doc-date ++. ds doc-page-number-string ++. ds doc-book-name ++. ds doc-publisher-name ++.. ++. ++. ++.\" NS doc-finish-reference macro ++.\" NS auxiliary macro for doc-print-reference ++.\" NS ++.\" NS modifies: ++.\" NS doc-reference-count ++. ++.de doc-finish-reference ++. nr doc-reference-count -\$1 ++. ie \n[doc-reference-count] \ ++. nop \), ++. el \ ++. nop \). ++.. ++. ++. ++.\" NS doc-print-reference macro ++.\" NS reference print ++.\" NS ++.\" NS modifies: ++.\" NS doc-reference-count ++. ++.de doc-print-reference ++. ++. nh ++. ++. if \n[doc-author-count] \{\ ++. doc-print-reference-authors ++. nr doc-reference-count -\n[doc-author-count] ++. \} ++. ++. if \n[doc-reference-title-count] \{\ ++. unformat doc-reference-title-name ++. chop doc-reference-title-name ++. unformat doc-reference-title-name-for-book ++. chop doc-reference-title-name-for-book ++. ie ((\n[doc-journal-count] == 1) : (\n[doc-book-count] == 1)) \{\ ++. nop \)\*[q]\)\*[doc-reference-title-name-for-book]\)\*[q]\c ++. doc-finish-reference \n[doc-reference-title-count] ++. \} ++. el \{\ ++. nop \*[doc-reference-title-name]\c ++. doc-finish-reference \n[doc-reference-title-count] ++. \}\} ++. ++. if \n[doc-book-count] \{\ ++. unformat doc-book-name ++. chop doc-book-name ++. nop \*[doc-book-name]\c ++. doc-finish-reference \n[doc-book-count] ++. \} ++. ++. if \n[doc-publisher-count] \{\ ++. unformat doc-publisher-name ++. chop doc-publisher-name ++. nop \*[doc-publisher-name]\c ++. doc-finish-reference \n[doc-publisher-count] ++. \} ++. ++. if \n[doc-journal-count] \{\ ++. unformat doc-journal-name ++. chop doc-journal-name ++. nop \*[doc-journal-name]\c ++. doc-finish-reference \n[doc-journal-count] ++. \} ++. ++. if \n[doc-report-count] \{\ ++. unformat doc-report-name ++. chop doc-report-name ++. nop \*[doc-report-name]\c ++. doc-finish-reference \n[doc-report-count] ++. \} ++. ++. if \n[doc-issue-count] \{\ ++. unformat doc-issue-name ++. chop doc-issue-name ++. nop \*[doc-issue-name]\c ++. doc-finish-reference \n[doc-issue-count] ++. \} ++. ++. if \n[doc-volume-count] \{\ ++. unformat doc-volume-name ++. chop doc-volume-name ++. nop \*[doc-volume-name]\c ++. doc-finish-reference \n[doc-volume-count] ++. \} ++. ++. if \n[doc-url-count] \{\ ++. unformat doc-url-name ++. chop doc-url-name ++. nop \*[doc-url-name]\c ++. doc-finish-reference \n[doc-url-count] ++. \} ++. ++. if \n[doc-page-number-count] \{\ ++. unformat doc-page-number-string ++. chop doc-page-number-string ++. nop \*[doc-page-number-string]\c ++. doc-finish-reference \n[doc-page-number-count] ++. \} ++. ++. if \n[doc-corporate-count] \{\ ++. unformat doc-corporate-name ++. chop doc-corporate-name ++. nop \*[doc-corporate-name]\c ++. doc-finish-reference \n[doc-corporate-count] ++. \} ++. ++. if \n[doc-city-count] \{\ ++. unformat doc-city-name ++. chop doc-city-name ++. nop \*[doc-city-name]\c ++. doc-finish-reference \n[doc-city-count] ++. \} ++. ++. if \n[doc-date-count] \{\ ++. unformat doc-date ++. chop doc-date ++. nop \*[doc-date]\c ++. doc-finish-reference \n[doc-date-count] ++. \} ++. ++. if \n[doc-optional-count] \{\ ++. unformat doc-optional-string ++. chop doc-optional-string ++. nop \*[doc-optional-string]\c ++. doc-finish-reference \n[doc-optional-count] ++. \} ++. ++. if \n[doc-reference-count] \ ++. tm mdoc warning: unresolved reference problem ++. ++. hy \n[doc-hyphen-flags] ++.. ++. ++. ++.\" NS doc-print-reference-authors macro ++.\" NS print out reference authors ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-dpra ++.\" NS doc-str-dpra ++. ++.ds doc-str-dpra "and ++. ++.de doc-print-reference-authors ++. nr doc-reg-dpra 1 ++. ++. while (\n[doc-reg-dpra] < \n[doc-author-count]) \{\ ++. unformat doc-author-name\n[doc-reg-dpra] ++. chop doc-author-name\n[doc-reg-dpra] ++. ie (\n[doc-author-count] > 2) \ ++. nop \)\*[doc-author-name\n[doc-reg-dpra]], ++. el \ ++. nop \)\*[doc-author-name\n[doc-reg-dpra]] ++. nr doc-reg-dpra +1 ++. \} ++. ++. unformat doc-author-name\n[doc-reg-dpra] ++. chop doc-author-name\n[doc-reg-dpra] ++. if (\n[doc-author-count] > 1) \ ++. nop \)\*[doc-str-dpra] ++. nop \)\*[doc-author-name\n[doc-reg-dpra]], ++.. ++. ++. ++.\" NS doc-author-count global register ++.\" NS counter of author references ++. ++.nr doc-author-count 0 ++. ++. ++.\" NS doc-author-nameXXX global box ++.\" NS array of author names ++.\" NS ++.\" NS limit: ++.\" NS doc-author-count ++. ++.ds doc-author-name0 ++. ++. ++.\" NS %A user macro ++.\" NS reference author(s) ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-author-count ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%A ++.\" NS ++.\" NS width register `%A' set in doc-common ++. ++.de %A ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%A author_name ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-author-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %A ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" save to reference box ++. box doc-author-name\n[doc-author-count] ++. ev doc-env-%A ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS doc-book-count global register ++.\" NS counter of book references ++. ++.nr doc-book-count 0 ++. ++. ++.\" NS doc-book-name global box ++.\" NS string of collected book references ++. ++.ds doc-book-name ++. ++. ++.\" NS %B user macro ++.\" NS [reference] book name ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-book-count ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%B ++.\" NS ++.\" NS width register `%B' set in doc-common ++. ++.de %B ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%B book_name ... (#\n[.c]) ++. return ++. \} ++. ++. if \n[doc-is-reference] \{\ ++. nr doc-book-count +1 ++. nr doc-reference-count +1 ++. \} ++. ++. ds doc-macro-name %B ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. ie \n[doc-is-reference] \{\ ++. \" append to reference box ++. boxa doc-book-name ++. ev doc-env-%B ++. evc 0 ++. in 0 ++. nf ++. nop \*[doc-Em-font]\c ++. doc-do-references ++. \} ++. el \{\ ++. nop \*[doc-Em-font]\c ++. doc-print-recursive ++. \} ++.. ++. ++. ++.\" NS doc-city-count global register ++.\" NS counter of city references ++. ++.nr doc-city-count 0 ++. ++. ++.\" NS doc-city-name global box ++.\" NS string of collected city references ++. ++.ds doc-city-name ++. ++. ++.\" NS %C user macro ++.\" NS [reference] city ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-city-count ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%C ++.\" NS ++.\" NS width register `%C' set in doc-common ++. ++.de %C ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%C city_name ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-city-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %C ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-city-name ++. ev doc-env-%C ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS doc-date-count global register ++.\" NS counter of date references ++. ++.nr doc-date-count 0 ++. ++. ++.\" NS doc-date global box ++.\" NS string of collected date references ++. ++.ds doc-date ++. ++. ++.\" NS %D user macro ++.\" NS [reference] date ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-date-count ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%D ++.\" NS ++.\" NS width register `%D' set in doc-common ++. ++.de %D ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%D date ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-date-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %D ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-date ++. ev doc-env-%D ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS doc-publisher-count global register ++.\" NS counter of publisher references ++. ++.nr doc-publisher-count 0 ++. ++. ++.\" NS doc-publisher-name global box ++.\" NS string of collected publisher references ++. ++.ds doc-publisher-name ++. ++. ++.\" NS %I user macro ++.\" NS [reference] issuer/publisher name ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-publisher-count ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%I ++.\" NS ++.\" NS width register `%I' set in doc-common ++. ++.de %I ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%I issuer/publisher_name ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-publisher-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %I ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-publisher-name ++. ev doc-env-%I ++. evc 0 ++. in 0 ++. nf ++. nop \*[doc-Em-font]\c ++. doc-do-references ++.. ++. ++. ++.\" NS doc-journal-count global register ++.\" NS counter of journal references ++. ++.nr doc-journal-count 0 ++. ++. ++.\" NS doc-journal-name global box ++.\" NS string of collected journal references ++. ++.ds doc-journal-name ++. ++. ++.\" NS %J user macro ++.\" NS [reference] Journal Name ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-journal-count ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%J ++.\" NS ++.\" NS width register `%J' set in doc-common ++. ++.de %J ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%J journal_name ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-journal-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %J ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-journal-name ++. ev doc-env-%J ++. evc 0 ++. in 0 ++. nf ++. nop \*[doc-Em-font]\c ++. doc-do-references ++.. ++. ++. ++.\" NS doc-issue-count global register ++.\" NS counter of issue number references ++. ++.nr doc-issue-count 0 ++. ++. ++.\" NS doc-issue-name global box ++.\" NS string of collected issue number references ++. ++.ds doc-issue-name ++. ++. ++.\" NS %N user macro ++.\" NS [reference] issue number ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-issue-count ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%N ++.\" NS ++.\" NS width register `%N' set in doc-common ++. ++.de %N ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%N issue_number ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-issue-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %N ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-issue-name ++. ev doc-env-%N ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS doc-optional-count global register ++.\" NS counter of optional information references ++. ++.nr doc-optional-count 0 ++. ++. ++.\" NS doc-optional-string global box ++.\" NS string of collected optional information references ++. ++.ds doc-optional-string ++. ++. ++.\" NS %O user macro ++.\" NS [reference] optional information ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-optional-count ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%O ++.\" NS ++.\" NS width register `%O' set in doc-common ++. ++.de %O ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%O optional_information ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-optional-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %O ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-optional-string ++. ev doc-env-%O ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS doc-page-number-count global register ++.\" NS counter of page number references ++. ++.nr doc-page-number-count 0 ++. ++. ++.\" NS doc-page-number-string global box ++.\" NS string of collected page number references ++. ++.ds doc-page-number-string ++. ++. ++.\" NS %P user macro ++.\" NS [reference] page numbers ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-page-number-count ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%P ++.\" NS ++.\" NS width register `%P' set in doc-common ++. ++.de %P ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%P page_number ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-page-number-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %P ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-page-number-string ++. ev doc-env-%P ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS doc-corporate-count global register ++.\" NS counter of corporate references ++. ++.nr doc-corporate-count 0 ++. ++. ++.\" NS doc-corporate-name global box ++.\" NS string of collected corporate references ++. ++.ds doc-corporate-name ++. ++. ++.\" NS %Q user macro ++.\" NS corporate or foreign author ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-corporate-count ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%Q ++.\" NS ++.\" NS width register `%Q' set in doc-common ++. ++.de %Q ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%Q corporate_or_foreign_author ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-corporate-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %Q ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-corporate-name ++. ev doc-env-%Q ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS doc-report-count global register ++.\" NS counter of report references ++. ++.nr doc-report-count 0 ++. ++. ++.\" NS doc-report-name global box ++.\" NS string of collected report references ++. ++.ds doc-report-name ++. ++. ++.\" NS %R user macro ++.\" NS [reference] report name ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS doc-report-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%R ++.\" NS ++.\" NS width register `%R' set in doc-common ++. ++.de %R ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%R reference_report ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-report-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %R ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-report-name ++. ev doc-env-%R ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS doc-reference-title-count global register ++.\" NS counter of reference title references ++. ++.nr doc-reference-title-count 0 ++. ++. ++.\" NS doc-reference-title-name global box ++.\" NS string of collected reference title references ++. ++.ds doc-reference-title-name ++. ++. ++.\" NS doc-reference-title-name-for-book global box ++.\" NS string of collected reference title references ++.\" NS (saved with another font; this is a shortcoming of groff) ++. ++.ds doc-reference-title-name-for-book ++. ++. ++.\" NS %T user macro ++.\" NS reference title ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-reference-title-count ++.\" NS doc-report-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%T ++.\" NS ++.\" NS width register `%T' set in doc-common ++. ++.de %T ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%T reference_title ... (#\n[.c]) ++. return ++. \} ++. ++. if \n[doc-is-reference] \{\ ++. nr doc-reference-title-count +1 ++. nr doc-reference-count +1 ++. \} ++. ++. ds doc-macro-name %T ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ie \n[doc-is-reference] \{\ ++. \" append to reference box ++. boxa doc-reference-title-name-for-book ++. ev doc-env-%T ++. evc 0 ++. in 0 ++. nf ++. nop \*[doc-No-font]\c ++. doc-do-references ++. ++. \" do it a second time with another font ++. ds doc-macro-name %T ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. boxa doc-reference-title-name ++. ev doc-env-%T ++. evc 0 ++. in 0 ++. nf ++. nop \*[doc-Em-font]\c ++. doc-do-references ++. \} ++. el \{\ ++. nop \*[doc-Em-font]\c ++. doc-print-recursive ++. \} ++.. ++. ++. ++.\" NS doc-url-count global register ++.\" NS counter of hypertext references ++. ++.nr doc-url-count 0 ++. ++. ++.\" NS doc-url-name global box ++.\" NS string of collected hypertext references ++. ++.ds doc-url-name ++. ++. ++.\" NS doc-volume-count global register ++.\" NS counter of reference title references ++. ++.nr doc-volume-count 0 ++. ++. ++.\" NS doc-volume-name global box ++.\" NS string of collected volume references ++. ++.ds doc-volume-name ++. ++. ++.\" NS %U user macro ++.\" NS hypertext reference ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS doc-url-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%U ++.\" NS ++.\" NS width register `%U' set in doc-common ++. ++.de %U ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%U URL ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-url-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %U ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-url-name ++. ev doc-env-%U ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS %V user macro ++.\" NS reference volume ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-macro-name ++.\" NS doc-reference-count ++.\" NS doc-volume-count ++.\" NS ++.\" NS local variables: ++.\" NS doc-env-%V ++.\" NS ++.\" NS width register `%V' set in doc-common ++. ++.de %V ++. if (\n[doc-arg-limit] : (\n[.$] == 0)) \{\ ++. tm Usage: .%V volume ... (#\n[.c]) ++. return ++. \} ++. ++. nr doc-volume-count +1 ++. nr doc-reference-count +1 ++. ++. ds doc-macro-name %V ++. doc-parse-args \$@ ++. ++. nr doc-arg-ptr +1 ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. ++. \" append to reference box ++. boxa doc-volume-name ++. ev doc-env-%V ++. evc 0 ++. in 0 ++. nf ++. doc-do-references ++.. ++. ++. ++.\" NS doc-do-references macro ++.\" NS reference recursion routine ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-ddr ++.\" NS doc-reg-ddr1 ++. ++.de doc-do-references ++. if !\n[doc-is-reference] \ ++. tm mdoc error: .\*[doc-macro-name] found outside of .Rs ... .Re (#\n[.c]) ++. ++. nr doc-reg-ddr1 \n[doc-type\n[doc-arg-ptr]] ++. ++. ie (\n[doc-reg-ddr1] == 1) \{\ ++. \" .nop \f[\n[doc-curr-font]]\s[\n[doc-curr-size]u]\c ++. doc-append-arg \c 3 ++. \*[doc-arg\n[doc-arg-ptr]] ++. \} ++. el \{\ ++. nop \)\*[doc-arg\n[doc-arg-ptr]]\c ++. ++. ie (\n[doc-arg-limit] == \n[doc-arg-ptr]) \{\ ++. \" finish reference box ++. br ++. ev ++. boxa ++. ++. doc-reset-args ++. \} ++. el \{\ ++. nr doc-reg-ddr \n[doc-arg-ptr] ++. nr doc-arg-ptr +1 ++. nop \)\*[doc-space\n[doc-reg-ddr]]\c ++. doc-do-references ++. \}\} ++.. ++. ++. ++.\" NS Hf user macro ++.\" NS source include header files. ++.\" NS ++.\" NS modifies: ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS ++.\" NS width register `Hf' set in doc-common ++. ++.de Hf ++. ie ((\n[.$] == 1) & (\n[doc-arg-limit] == 0)) \{\ ++. doc-paragraph ++. nop File: ++. Pa \$1 ++. ++. Bd -literal ++. so \$1 ++. Ed ++. ++. doc-paragraph ++. \} ++. el \ ++. Usage: .Hf file (#\n[.c]) ++.. ++. ++. ++.\" NS doc-have-author global register (bool) ++.\" NS set in `An' ++. ++.nr doc-have-author 0 ++. ++. ++.\" NS An user macro ++.\" NS author name ++.\" NS ++.\" NS modifies: ++.\" NS doc-arg-ptr ++.\" NS doc-curr-font ++.\" NS doc-curr-size ++.\" NS doc-have-author ++.\" NS doc-macro-name ++.\" NS ++.\" NS width register `An' set in doc-common ++. ++.de An ++. if !\n[doc-arg-limit] \{\ ++. ie \n[.$] \{\ ++. ie "\$1"-nosplit" \ ++. nr doc-in-authors-section 0 ++. el \{ .ie "\$1"-split" \ ++. nr doc-in-authors-section 1 ++. el \{\ ++. ds doc-macro-name An ++. doc-parse-args \$@ ++. \}\}\} ++. el \{\ ++. tm1 "Usage: .An {-nosplit | -split} ++. tm1 " .An author_name ... (#\n[.c]) ++. \}\} ++. ++. if \n[doc-in-authors-section] \{\ ++. ie \n[doc-have-author] \ ++. br ++. el \ ++. nr doc-have-author 1 ++. \} ++. ++. if \n[doc-arg-limit] \{\ ++. nr doc-arg-ptr +1 ++. ie (\n[doc-arg-limit] >= \n[doc-arg-ptr]) \{\ ++. nr doc-curr-font \n[.f] ++. nr doc-curr-size \n[.ps] ++. doc-print-recursive ++. \} ++. el \{\ ++. tm Usage: .An author_name ... (#\n[.c]) ++. doc-reset-args ++. \}\} ++.. ++. ++. ++.\" NS Rv user macro ++.\" NS return values ++.\" NS ++.\" NS width register `Rv' set in doc-common ++.\" NS ++.\" NS local variables: ++.\" NS doc-str-Rv-std-prefix ++.\" NS doc-str-Rv-std-suffix ++.\" NS doc-str-Rv-stds-prefix ++.\" NS doc-str-Rv-stds-and ++.\" NS doc-str-Rv-stds-suffix ++.\" NS doc-str-Rv-std0 ++. ++.ds doc-str-Rv-std-prefix "The ++.ds doc-str-Rv-std-suffix "function returns the value\~0 if successful; ++.as doc-str-Rv-std-suffix " otherwise the value\~\-1 is returned and ++.as doc-str-Rv-std-suffix " the global variable \*[doc-Va-font]errno\f[] ++.as doc-str-Rv-std-suffix " is set to indicate the error. ++. ++.ds doc-str-Rv-stds-prefix "The ++.ds doc-str-Rv-stds-and "and ++.ds doc-str-Rv-stds-suffix "functions return the value\~0 if successful; ++.as doc-str-Rv-stds-suffix " otherwise the value\~\-1 is returned and ++.as doc-str-Rv-stds-suffix " the global variable \*[doc-Va-font]errno\f[] ++.as doc-str-Rv-stds-suffix " is set to indicate the error. ++. ++.ds doc-str-Rv-std0 "Upon successful completion, the value\~0 is returned; ++.as doc-str-Rv-std0 " otherwise the value\~\-1 is returned and ++.as doc-str-Rv-std0 " the global variable \*[doc-Va-font]errno\f[] ++.as doc-str-Rv-std0 " is set to indicate the error. ++. ++.de Rv ++. ++.\" XXX: what does this function without `-std'? ++. ++. if \n[doc-arg-limit] \{\ ++. tm Usage: .Rv not callable by other macros (#\n[.c]) ++. doc-reset-args ++. return ++. \} ++. ++. if !\n[.$] \{\ ++. tm Usage: .Rv [-std] [ ...] (#\n[.c]) ++. return ++. \} ++. ++. if "\$1"-std" \{\ ++. nr doc-reg-Rv \*[doc-section] ++. if ((\n[doc-reg-Rv] < 2) : (\n[doc-reg-Rv] > 3)) \ ++. tm Usage: .Rv -std in sections 2 and 3 only (#\n[.c]) ++. br ++. shift ++. ie (\n[.$] > 1) \{\ ++. nop \)\*[doc-str-Rv-stds-prefix] ++. nr doc-reg-Rv 1 ++. while (\n[doc-reg-Rv] < \n[.$]) \{\ ++. ie (\n[.$] > 2) \ ++. Fn \$\n[doc-reg-Rv] , ++. el \ ++. Fn \$\n[doc-reg-Rv] ++. nr doc-reg-Rv +1 ++. \} ++. nop \)\*[doc-str-Rv-stds-and] ++. Fn \$\n[.$] ++. nop \)\*[doc-str-Rv-stds-suffix] ++. \} ++. el \{ .ie (\n[.$] == 1) \{\ ++. nop \)\*[doc-str-Rv-std-prefix] ++. Fn \$1 ++. nop \)\*[doc-str-Rv-std-suffix] ++. \} ++. el \{\ ++. nop \)\*[doc-str-Rv-std0] ++. \}\}\} ++.. ++. ++. ++.\" NS Ex user macro ++.\" NS exit status ++.\" NS ++.\" NS width register `Ex' set in doc-common ++.\" NS ++.\" NS local variables: ++.\" NS doc-str-Ex-std-prefix ++.\" NS doc-str-Ex-std-suffix ++. ++.ds doc-str-Ex-std-prefix "The ++.ds doc-str-Ex-std-suffix "utility exits\~0 on success, ++.as doc-str-Ex-std-suffix " and\~>0 if an error occurs. ++. ++.ds doc-str-Ex-stds-prefix "The ++.als doc-str-Ex-stds-and doc-str-Rv-stds-and ++.ds doc-str-Ex-stds-suffix "utilities exit\~0 on success, ++.as doc-str-Ex-stds-suffix " and\~>0 if an error occurs. ++. ++.de Ex ++. ++.\" XXX: what does this function without `-std'? ++. ++. if \n[doc-arg-limit] \{\ ++. tm Usage: .Ex not callable by other macros (#\n[.c]) ++. doc-reset-args ++. return ++. \} ++. ++. if !\n[.$] \{\ ++. tm Usage: .Ex [-std] [ ...] (#\n[.c]) ++. return ++. \} ++. ++. if "\$1"-std" \{\ ++. nr doc-reg-Ex \*[doc-section] ++. if !((\n[doc-reg-Ex] == 1) : (\n[doc-reg-Ex] == 6) : (\n[doc-reg-Ex] == 8)) \ ++. tm Usage: .Ex -std in sections 1, 6 and 8 only (#\n[.c]) ++. br ++. shift ++. ie (\n[.$] > 1) \{\ ++. nop \)\*[doc-str-Ex-stds-prefix] ++. nr doc-reg-Ex 1 ++. while (\n[doc-reg-Ex] < \n[.$]) \{\ ++. ie (\n[.$] > 2) \ ++. Nm \$\n[doc-reg-Ex] , ++. el \ ++. Nm \$\n[doc-reg-Ex] ++. nr doc-reg-Ex +1 ++. \} ++. nop \)\*[doc-str-Ex-stds-and] ++. Nm \$\n[.$] ++. nop \)\*[doc-str-Ex-stds-suffix] ++. \} ++. el \{\ ++. nop \)\*[doc-str-Ex-std-prefix] ++. Nm \$1 ++. nop \)\*[doc-str-Ex-std-suffix] ++. \}\} ++.. ++. ++. ++.\" NS Mt user macro ++.\" NS mailto (for conversion to HTML) ++. ++.de Mt ++. \" XXX: error handling missing ++. Pa \$@ ++.. ++. ++. ++.\" NS Lk user macro ++.\" NS link (for conversion to HTML) ++.\" NS ++.\" NS local variables: ++.\" NS doc-reg-Lk ++.\" NS doc-str-Lk ++. ++.de Lk ++. ds doc-str-Lk Sy \$@ ++. ++. ie (\n[.$] > 1) \{\ ++. doc-get-arg-type \$2 ++. ie (\n[doc-arg-type] < 3) \{\ ++. Em \)\$2: ++. ds doc-str-Lk Sy "\$1" ++. doc-get-width "\$1" ++. shift 2 ++. if \n[.$] \ ++. as doc-str-Lk " \$@ ++. \} ++. el \ ++. doc-get-width "\$1" ++. \} ++. el \ ++. doc-get-width "\$1" ++. ++. ie n \ ++. nr doc-reg-Lk 26 ++. el \ ++. nr doc-reg-Lk 38 ++. ie (\n[doc-width] >= \n[doc-reg-Lk]) \ ++. D1 \*[doc-str-Lk] ++. el \ ++. \*[doc-str-Lk] ++.. ++. ++. ++.\" NS doc-defunct-macro macro ++.\" NS this is the skeleton for defunct macros ++.\" NS ++. ++.de doc-defunct-macro ++. tmc mdoc error: .\$0 defunct ++. if d doc-\$0-usage \ ++. tmc , \*[doc-\$0-usage] ++. tm1 " (#\n[.c]) ++.. ++. ++. ++.\" obsolete macros ++. ++.als Db doc-defunct-macro ++. ++.als Ds doc-defunct-macro ++. ++.als Or doc-defunct-macro ++.ds doc-Or-usage use `|' ++. ++.als Sf doc-defunct-macro ++.ds doc-Sf-usage use .Pf or .Ns ++. ++. ++.rn em e@ ++. ++.de em ++. tm1 "mdoc error: end-macro (.em) respecification is not allowed. (#\n[.c]) ++. tm1 " Should this have been `.Em ...'? ++. ab ++.. ++. ++. ++.\" NS doc-empty-line macro ++.\" NS emit warning and print empty line ++. ++.de doc-empty-line ++. if !\n[doc-display-depth] \ ++. tm mdoc warning: Empty input line #\n[.c] ++. sp ++.. ++. ++.blm doc-empty-line ++. ++. ++.ec ++. ++. ++.\" For UTF-8, map some characters conservatively for the sake ++.\" of easy cut and paste. ++. ++.if '\*[.T]'utf8' \{\ ++. rchar \- - ' ` ++. ++. char \- \N'45' ++. char - \N'45' ++. char ' \N'39' ++. char ` \N'96' ++.\} ++. ++. ++.\" load local modifications ++.mso mdoc.local ++. ++.\" EOF +diff -Nuar groff-1.22.3.old/tmac/e.tmac groff-1.22.3/tmac/e.tmac +--- groff-1.22.3.old/tmac/e.tmac 2014-11-04 10:38:35.534520134 +0200 ++++ groff-1.22.3/tmac/e.tmac 1970-01-01 02:00:00.000000000 +0200 +@@ -1,2037 +0,0 @@ +-.\" -*- nroff -*- +-.\" +-.\" @(#)e.tmac 2.31 (Berkeley) 5/21/88 +-.\" Modified by James Clark for use with groff. +-.\" +-.\" Copyright (c) 1988 Regents of the University of California. +-.\" All rights reserved. +-.\" +-.\" Redistribution and use in source and binary forms are permitted +-.\" provided that this notice is preserved and that due credit is given +-.\" to the University of California at Berkeley. The name of the University +-.\" may not be used to endorse or promote products derived from this +-.\" software without specific prior written permission. This software +-.\" is provided ``as is'' without express or implied warranty. +-.\" %beginstrip% +-.\" +-.\"********************************************************************** +-.\"* * +-.\"* ****** - M E N R O F F / T R O F F M A C R O S ****** * +-.\"* * +-.\"* Produced for your edification and enjoyment by: * +-.\"* Eric Allman * +-.\"* Electronics Research Laboratory * +-.\"* U.C. Berkeley. * +-.\"* current address: * +-.\"* Britton-Lee, Inc. * +-.\"* 1919 Addison Street Suite 105 * +-.\"* Berkeley, California 94704 * +-.\"* * +-.\"* VERSION 2.31 First Release: 11 Sept 1978 * +-.\"* * +-.\"* Documentation is available. * +-.\"* * +-.\"********************************************************************** +-.\" +-.\" Code on .de commands: +-.\" *** a user interface macro. +-.\" &&& a user interface macro which is redefined +-.\" when used to be the real thing. +-.\" $$$ a macro which may be redefined by the user +-.\" to provide variant functions. +-.\" --- an internal macro. +-.\" +-. +-.do nr need_eo_h 0 +-.do nr need_eo_tl 0 +-.do nr need_tl 1 +-. +-.do mso devtag.tmac +-. +-.if !\n(.g .ig +-.de @R \" --- initialize number register to 0, if undefined +-.if !r\\$1 .nr \\$1 0 +-.. +-. +-.\" --- check whether grohtml needs end of title/heading +-.de @html_check_need_title +-.do if (\\n[need_eo_tl] == 1) \ +-\{\ +-. do nr need_eo_tl 0 +-. do DEVTAG-EO-TL +-.\} +-.do if (\\n[need_tl] == 1) \ +-\{\ +-. do DEVTAG-TL +-. do nr need_tl 0 +-. do nr need_eo_tl 1 +-.\} +-.do if \\n[need_eo_h]>0 .do DEVTAG-EO-H +-.do nr need_eo_h 0 +-.. +-. +-.de @check_need_title +-.. +-. +-.ie '\*(.T'html' \ +-. do als check_need_title @html_check_need_title +-.el \ +-. do als check_need_title @check_need_title +-. +-.@R pf +-.if \n(pf .nx +-. +-.if !\n(.g .ig +-.de @S \" --- initialize string/macro to empty, if undefined +-.if !d\\$1 .ds \\$1 \" empty +-.. +-. +-.@R @\" \" debugging level +-. +-. +-.\" *** INTERNAL GP MACROS *** +-. +-. +-.de @C \" --- change ev's, taking info with us +-.nr _S \\n(.s +-.nr _V \\n(.v +-.nr _F \\n(.f +-.nr _J \\n(.j +-.do ds _A \\n[.fam] +-.nr _I \\n(.i +-.ev \\$1 +-.ps \\n(_S +-.vs \\n(_Vu +-.ft \\n(_F +-.ad \\n(_J +-.do @fam \\*(_A +-'in \\n(_Iu +-.xl \\n($lu +-.lt \\n($lu +-.rr _S +-.rr _V +-.rr _F +-.rr _I +-.rr _J +-.ls 1 +-'ce 0 +-.. +-. +-.de @D \" --- determine display type (Indent, Left, Center) +-.ds |p "\\$3 +-.nr _d 0 +-.if "\\$2"C" \ +-. nr _d 1 +-.if "\\$2"L" \ +-. nr _d 2 +-.if "\\$2"I" \ +-. nr _d 3 +-.if "\\$2"M" \ +-. nr _d 4 +-.if !\\n(_d \ +-\{\ +-. nr _d \\$1 +-. ds |p "\\$2 +-.\} +-. +-.. +-. +-.de @z \" --- end macro +-.if \n@>1 .tm >> @z, .z=\\n(.z ?a=\\n(?a +-.if !"\\n(.z"" \ +-\{\ +-. tm Line \\n(c. -- Unclosed block, footnote, or other diversion (\\n(.z) +-. di +-. ex +-.\} +-.if \\n(?a \ +-. bp \" force out final table +-.ds bp +-.ds @b\" \" don't start another page +-.br +-.if \n@>1 .tm << @z +-.. +-. +-. +-.\" *** STANDARD HEADERS AND FOOTERS *** +-. +-. +-.ie \n(.g .ds $* \\\\$* +-.el .ds $* \\\\$1 \\\\$2 \\\\$3 \\\\$4 \\\\$5 \\\\$6 \\\\$7 \\\\$8 \\\\$9 +-. +-.de he \" *** define header +-.ie !\\n(.$ \ +-\{\ +-. rm |4 +-. rm |5 +-.\} +-.el \ +-\{\ +-. ds |4 "\*($* +-. ds |5 "\*($* +-.\} +-.. +-. +-.de eh \" *** define even header +-.ie !\\n(.$ \ +-. rm |4 +-.el \ +-. ds |4 "\*($* +-.. +-. +-.de oh \" *** define odd header +-.ie !\\n(.$ \ +-. rm |5 +-.el \ +-. ds |5 "\*($* +-.. +-. +-.de fo \" *** define footer +-.ie !\\n(.$ \ +-\{\ +-. rm |6 +-. rm |7 +-.\} +-.el \ +-\{\ +-. ds |6 "\*($* +-. ds |7 "\*($* +-.\} +-.. +-. +-.de ef \" *** define even foot +-.ie !\\n(.$ \ +-. rm |6 +-.el \ +-. ds |6 "\*($* +-.. +-. +-.de of \" *** define odd footer +-.ie !\\n(.$ \ +-. rm |7 +-.el \ +-. ds |7 "\*($* +-.. +-. +-.de ep \" *** end page (must always be followed by a .bp) +-.if \\n(nl>0 \ +-\{\ +-. wh 0 +-. rs +-. @b +-.\} +-.. +-. +-. +-.\" *** INTERNAL HEADER AND FOOTER MACROS *** +-. +-. +-.de @h \" --- header +-.if \n@>1 .tm >> @h %=\\n% ?a=\\n(?a ?b=\\n(?b ?w=\\n(?w +-.if (\\n(.i+\\n(.o)>=\\n(.l \ +-. tm Line \\n(c. -- Offset + indent exceeds line length +-.\" initialize a pile of junk +-.nr ?h \\n(?H \" transfer "next page" to "this page" +-.nr ?H 0 +-.nr ?c \\n(?C +-.nr ?C 0 +-.rn |4 |0 +-.rn |5 |1 +-.rn |6 |2 +-.rn |7 |3 +-.nr _w 0 \" reset max footnote width +-.nr ?W 0 \" no wide floats this page (yet) +-.nr ?I 1 +-.\" begin actual header stuff +-.ev 2 +-.rs +-.if \\n(hm>0 \ +-. if !'\*(.T'html' \ +-. sp |\\n(hmu \" move to header position +-.@t $h\" \" output header title +-.if \\n(tm<=0 \ +-. nr tm \n(.Vu +-.if !'\*(.T'html' \ +-. sp |\\n(tmu \" move to top of text +-.ev +-.mk _k \" for columned output +-.if \\n(?n=1 .nm 1 \" restore line numbering if n1 mode +-.nr $c 1 \" set first column +-.if \n@>4 .tm -- @h >> .ns nl=\\n(nl %=\\n% _k=\\n(_k tm=\\n(tm +-.ie \\n(?s \ +-\{\ +-. nr ?s 0 +-. rs +-' @b +-.\} +-.el \ +-. @n\" \" begin the column +-.if \n@>2 .tm << @h +-.. +-. +-.de @n \" --- new column or page +-.if \n@>3 .tm >> @n nl=\\n(nl %=\\n% ?f=\\n(?f ?o=\\n(?o +-.if \\n(bm<=0 \ +-. nr bm \\n(.Vu +-.if (\\n(_w<=\\n($l)&(\\n(?W=0) \ +-\{\ +-. nr _b (\\n(ppp*\\n($vu)/200u \" compute fudge factor (must be < 1P) +-. if \\n(_bu>((\\n(bmu-\\n(fmu-((\\n(tpp*\\n($vu)/100u))/2u) \ +-. nr _b (\\n(ppp*\\n($vu)/100u-\n(.Vu +-. nr _b +\\n(bmu +-.\} +-.nr _B \\n(_bu +-.ch @f +-.wh -\\n(_bu @f +-.nr _b +(\\n(ppp*\\n($vu)/100u \" add 1 paragraph v in case of sweep past +-.if \n@>2 .tm @n .p=\\n(.p bm=\\n(bm _b=\\n(_b _B=\\n(_B +-.nr ?f 0 \" reset footnote flag +-.if \\n(?o \ +-\{\ +-. (f _\" \" reprocess footnotes which run off page +-. nf +-. |o +-. fi +-. )f +-. rm |o +-.\} +-.nr ?o 0 +-.if \\n(?T \ +-\{\ +-. nr _i \\n(.i +-. if \\n(?n \ +-. nm \\n(ln +-. in 0 +-. |h\" \" output the table header +-. in \\n(_iu +-. if \\n(?n \ +-. nm +-. rr _i +-. mk #T \" for tbl commands +-. ns +-.\} +-.if (\\n(?a)&((\\n($c<2):(\\n(?w=0)) \ +-\{\ +-. nr ?a 0 \" output floating keep +-. @k |t +-. if \\n(?w \ +-. mk _k \" don't overstrike wide keeps +-. nr ?w 0 +-.\} +-.os +-.$H\" \" special column header macro +-.ns +-.. +-. +-.de @f \" --- footer +-.if \n@>1 .tm >> @f %=\\n% nl=\\n(nl ?a=\\n(?a ?b=\\n(?b ?f=\\n(?f +-.if \n@>2 .nr VL \\n(.pu-\\n(nlu +-.if \n@>2 .tm @f bm=\\n(bm _B=\\n(_B _b=\\n(_b .p-nl=\\n(VL +-.ec +-.if \\n(?T \ +-\{\ +-. nr T. 1 \" for tbl commands (to output bottom line) +-. T# 1\" \" output the sides and bottom lines +-. br +-.\} +-.ev 2 +-.ce 0 +-.if \\n(?b \ +-\{\ +-. nr ?b 0 +-. @k |b\" \" output bottom of page tables +-.\} +-.if \\n(?f \ +-. @o\" \" output footnote if present +-.ie \\n($c<\\n($m \ +-. @c\" \" handle new column +-.el \ +-. @e\" \" new page +-.ev +-.if \n@>2 .tm << @f +-.. +-. +-.de @o \" --- output footnote +-.nf +-.ls 1 +-.in 0 +-.if \n@>2 .tm @o last printed text = \\n(nl placing @r trap at -\\n(_B +-.wh -\\n(_Bu @r +-.if \\n(?n \ +-. nm \\n(ln +-.|f +-.if \\n(?n \ +-. nm +-.fi +-.if \n@>2 .tm @o triggered @r (?o) = \\n(?o +-.if \\n(?o \ +-\{\ +-. di \" just in case triggered @r +-. if \\n(dn=0 \ +-\{\ +-. rm |o +-. nr ?o 0 +-. \} +-. nr dn \\n(_D +-. rr _D +-.\} +-.rm |f +-.ch @r +-.. +-. +-.de @c \" --- new column +-.if \n@>2 .tm >> @c %=\\n% +-.rs +-.sp |\\n(_ku +-.@O +\\n($lu+\\n($su +-.nr $c +1 +-.@n +-.. +-. +-.de @e \" --- end page +-.if \n@>2 .tm >> @e +-.@O \\n(_ou +-.rs +-.sp |\\n(.pu-\\n(fmu-((\\n(tpp*\\n($vu)/100u) \" move to footer position +-.@t $f\" \" output footer title +-.nr ?h 0 +-.bp +-.. +-. +-.de @t \" --- output header or footer title +-.if !\\n(?h \ +-\{\ +-. sz \\n(tp\" \" set header/footer type fonts, etc. +-. @F \\n(tf +-. lt \\n(_Lu \" make title span entire page +-. if \\n(?n \ +-. nm \\n(ln +-. nf +-. \\$1 +-. br +-. if \\n(?n \ +-. nm +-.\} +-.. +-. +-.de $h \" $$$ print header +-.ds |z +-.if !\\n(?c \ +-\{\ +-. if e .ds |z "\\*(|0 +-. if o .ds |z "\\*(|1 +-.\} +-.if !\(ts\\*(|z\(ts\(ts \ +-' tl \\*(|z +-.rm |z +-.. +-. +-.de $f \" $$$ print footer +-.ds |z +-.if \\n(?c \ +-\{\ +-. if e .ds |z "\\*(|0 +-. if o .ds |z "\\*(|1 +-.\} +-.if \(ts\\*(|z\(ts\(ts \ +-\{\ +-. if e .ds |z "\\*(|2 +-. if o .ds |z "\\*(|3 +-.\} +-.if !\(ts\\*(|z\(ts\(ts \ +-' tl \\*(|z +-.rm |z +-.. +-. +-.de @r \" --- reprocess overflow footnotes +-.if \n@>3 .tm >> @r .z=\\n(.z ?f=\\n(?f ?a=\\n(?a ?b=\\n(?b _b=\\n(_b +-.di |o \" save overflow footnote +-.nr ?o 1 +-.nr _D \\n(dn +-.ns +-.. +-. +-. +-.\" *** COMMANDS WITH VARIANT DEFINITIONS *** +-. +-. +-.if !'\*(.T'html' .rn bp @b \" --- begin page +-. +-.de bp \" *** begin new page (overrides columns) +-.nr $c \\n($m \" force new page, not new column +-.ie \\n(nl>0 \ +-. @b \\$1 +-.el \ +-\{\ +-. if \\n(.$>0 \ +-. pn \\$1 +-. if \\n(?I \ +-. @h\" \" 'spring' the header trap +-.\} +-.br +-.wh 0 @h \" reset header +-.. +-. +-.rn ll xl \" *** special line length (local) +-.de ll \" *** line length (global to environments) +-.xl \\$1 +-.lt \\$1 +-.nr $l \\n(.l +-.if (\\n($m<=1):(\\n($l>\\n(_L) \ +-. nr _L \\n(.l +-.. +-. +-.rn po @O \" --- local page offset +-. +-.de po \" *** page offset +-.@O \\$1 +-.nr _o \\n(.o +-.. +-. +-.\" Redefine the fam request to set the family in +-.\" environment 2 as well as the current environment. +-.if !\n(.g .ig +-.do rn fam @fam \" --- set family in current environment +-.do de fam \" *** set font family in ev 2 and current ev +-.do @fam \\$1 +-.ev 2 +-.do @fam \\$1 +-.ev +-.. +-. +-. +-.\" *** MISCELLANEOUS ROFF COMMANDS *** +-. +-. +-.de hx \" *** suppress headers and footers next page +-.nr ?H 1 +-.. +-. +-.de ix \" *** indent, no break +-'in \\$1 +-.. +-. +-.de bl \" *** contiguous blank lines +-.br +-.@s \\$1 +-.sp \\$1 +-.. +-. +-.de @s \" --- diversion-surviving space test +-.ne \\$1 +-.rs +-.if !'\\n(.z'' \!.@s \\$1 +-.. +-. +-.de n1 \" *** line numbering 1 +-.nm 1 +-.ll -\w'0000'u +-.nr ?n 1 +-.. +-. +-.de n2 \" *** line numbering 2 +-.ie \\n(.$ \ +-\{\ +-. ie !`\\$2`c` \ +-. po -\w'0000'u +-. el \ +-. ll -\w'0000'u +-. ie \\B`\\$1` \ +-\{\ +-. ds |i \\$1 +-. ds |j \\$1 +-. do substring |i 0 0 \" pick off leading char and rest to check +-. do substring |j 1 \" for +N / -N +-. ie `\\*(|i`+` \ +-. nr ln (\\n[_ln])+\\*(|j +-. el \ +-. ie `\\*(|i`-` \ +-. nr ln (\\n[_ln])-\\*(|j +-. el \ +-. nr ln \\$1 \" unsigned N +-. nm \\n(ln +-. nr ?n 2 +-. rm |i |j +-.\} +-. el \ +-. tm Line \\n(.c -- Bad .n2 value +-.\} +-.el \ +-\{\ +-. nm +-. nr _ln \\n(ln +-. po +\w'0000'u +-. ll \\n($lu +-. nr ?n 0 +-. nr ln 0 +-.\} +-.. +-. +-.de pa \" *** new page +-.bp \\$1 +-.. +-. +-.de ro \" *** roman page numbers +-.af % i +-.. +-. +-.de ar \" *** arabic page numbers +-.af % 1 +-.. +-. +-.de m1 \" *** position one space +-.nr _0 \\n(hmu +-.nr hm \\$1v +-.nr tm +\\n(hmu-\\n(_0u +-.rr _0 +-.. +-. +-.de m2 \" *** position two space +-.nr tm \\n(hmu+\\n(tpp+\\$1v +-.. +-. +-.de m3 \" *** position three space +-.nr bm \\n(fmu+\\n(tpp+\\$1v +-.. +-. +-.de m4 \" *** position four space +-.nr _0 \\n(fmu +-.nr fm \\$1v +-.nr bm +\\n(fmu-\\n(_0u +-.. +-. +-.de sk \" *** leave a blank page (next page) +-.if \\n(.$>0 \ +-. tm Line \\n(c. -- I cannot skip multiple pages +-.nr ?s 1 +-.. +-. +-. +-.\" *** MISCELLANEOUS USER SUPPORT COMMANDS *** +-. +-. +-.if !\n(.g .ig +-.de re \" *** reset tabs (TROFF defines 15 stops default) +-.ta T 0.5i +-.. +-. +-.if \n(.g .ig +-.de re +-.ta 0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +-.. +-. +-.de ba \" *** set base indent +-.ie \\n(.$ \ +-. nr $i \\$1n +-.el \ +-. nr $i \\n(siu*\\n($0u +-.. +-. +-.de hl \" *** draw horizontal line +-.br +-.if '\*(.T'html' \ +-\{\ +-. HR +-. do return +-.\} +-.ie \n(.g .do nr _I \\n[.in] +-.el .nr _I \\n(.i +-\l'\\n(.lu-\\n(_Iu' +-.sp +-.. +-. +-. +-.\" *** PARAGRAPHING *** +-. +-. +-.de pp \" *** paragraph +-.lp \\n(piu +-.. +-. +-.de lp \" *** left aligned paragraph +-.@p +-.if \\n(.$ \ +-. ti +\\$1 +-.nr $p 0 1 +-.. +-. +-.de ip \" *** indented paragraph w/ optional tag +-.if (\\n(ii>0)&(\\n(ii<1n) \ +-. nr ii \\n(iin +-.nr _0 \\n(ii +-.if \\n(.$>1 \ +-. nr _0 \\$2n +-.@p \\n(_0u +-.nr _I \\n(.iu +-.in 0 +-.di |i +-\&\\$1 +-.br +-.di +-.in \\n(_Iu +-.ds |j \\*(|i\\ +-.ie \\w"\\*(|j" \ +-\{\ +-. ti -\\n(_0u +-. ie \\w"\\*(|j">=\\n(_0 \ +-\{\ +-. do DEVTAG-COL 1 +-\\*(|j +-. do DEVTAG-COL-NEXT 2 +-. br +-. \} +-. el \ +-\{\ +-. do DEVTAG-COL 1 +-\\*(|j\h'|\\n(_0u'\c +-. do DEVTAG-COL 2 +-. \} +-.\} +-.el .do DEVTAG-COL 2 +-.rr _0 +-.rm |i |j +-.. +-. +-.de np \" *** numbered paragraph +-.\" use string comparison in case user has changed format of $p +-.if '\\n($p'-1' \ +-. nr $p 0 \" reset number after .bu +-.nr $p +1 \" increment paragraph number +-.@p \w'\0(000)\0'u +-.ti -\w'\0(000)\0'u +-\0(\\n($p)\h'|\w'\0(000)\0'u'\c +-.. +-. +-.de bu \" *** bulleted paragraph +-.br +-.\" use string comparison in case user has changed format of $p +-.if '\\n($p'-1' \ +-. ns \" don't space between .bu paragraphs +-.nr $p 0-1 \" mark "bulleted paragraph" mode +-.@p \w'\0\(bu\0'u +-.ti -\w'\0\(bu\0'u +-\0\(bu\0\c +-.. +-. +-.de @p \" --- initialize for paragraph +-.do check_need_title +-.if "\\n(.z"|e" .tm Line \\n(c. -- Unmatched continued equation +-.in \\n($iu+\\n(pou +-.if \\n(.$ \ +-. in +\\$1n +-.ce 0 +-.fi +-.@F \\n(pf +-.sz \\n(pp +-.sp \\n(psu +-.ne \\n(.Lv+\\n(.Vu +-.ns +-.. +-. +-. +-.\" *** SECTION HEADINGS *** +-. +-. +-.de sh \" *** section heading +-.fi +-.do check_need_title +-.if (\\n(si>0)&(\\n(si<1n) \ +-. nr si \\n(sin +-.if '\*(.T'html' .nr si 0 +-.ce 0 +-.if '\*(.T'html' \ +-\{\ +-. do DEVTAG-SH \\$1 +-. do nr need_eo_h 1 +-.\} +-.@d "\\$1" +1 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 +-.if !"\\$2"_" \ +-\{\ +-. ds |n \&\\$2 +-. $p "\\*(|n" "\\*($n" \\n($0 +-. $0 "\\*(|n" "\\*($n" \\n($0 +-. rm |n +-.\} +-.nr $p 0 1 \" reset .np count +-.. +-. +-.de @d \" --- change section depth +-.if !""\\$1" \ +-. nr $0 \\$1 +-.if \\n($0&(\\n(.$>1) \ +-. nr $\\n($0 \\$2 +-.ds $n \&\" +-.ie \\n($0>=1 \ +-\{\ +-. if '\\n($1'0' \ +-. nr $1 1 +-. if (\\n(.$>=3) .if !"\\$3"-" \ +-. nr $1 \\$3 +-. as $n \\n($1 +-.\} +-.el \ +-. nr $1 0 +-.ie \\n($0>=2 \ +-\{\ +-. if '\\n($2'0' \ +-. nr $2 1 +-. if (\\n(.$>=4) .if !"\\$4"-" \ +-. nr $2 \\$4 +-. as $n .\\n($2 +-.\} +-.el \ +-. nr $2 0 +-.ie \\n($0>=3 \ +-\{\ +-. if '\\n($3'0' \ +-. nr $3 1 +-. if (\\n(.$>=5) .if !"\\$5"-" \ +-. nr $3 \\$5 +-. as $n .\\n($3 +-.\} +-.el \ +-. nr $3 0 +-.ie \\n($0>=4 \ +-\{\ +-. if '\\n($4'0' \ +-. nr $4 1 +-. if (\\n(.$>=6) .if !"\\$6"-" \ +-. nr $4 \\$6 +-. as $n .\\n($4 +-.\} +-.el \ +-. nr $4 0 +-.ie \\n($0>=5 \ +-\{\ +-. if '\\n($5'0' \ +-. nr $5 1 +-. if (\\n(.$>=7) .if !"\\$7"-" \ +-. nr $5 \\$7 +-. as $n .\\n($5 +-.\} +-.el \ +-. nr $5 0 +-.ie \\n($0>=6 \ +-\{\ +-. if '\\n($6'0' \ +-. nr $6 1 +-. if (\\n(.$>=8) .if !"\\$8"-" \ +-. nr $6 \\$8 +-. as $n .\\n($6 +-.\} +-.el \ +-. nr $6 0 +-.. +-. +-.de sx \" *** heading up, no increment (2.1.1 -> 2.1) +-.ce 0 +-.ul 0 +-.nr _0 \\n($0-1 +-.if \\n(.$ .nr _0 +1 +-.if \\n(.$ .nr _0 \\$1 +-.@d \\n(_0 +-.rr _0 +-.$p "" "" \\n($0 +-.nr $p 0 1 \" reset .np count +-.. +-. +-.de uh \" *** unnumbered section heading +-.$p "\\$1" +-.$0 "\\$1" +-.. +-. +-.de $p \" $$$ print section heading +-.if (\\n(si>0)&(\\n(.$>2) \ +-. nr $i \\$3*\\n(si +-.in \\n($iu +-.ie !"\\$1\\$2"" \ +-\{\ +-. sp \\n(ssu \" one of them is non-null +-. ne \\n(.Lv+\\n(.Vu+\\n(psu+((\\n(spp*\\n($vu*\\n(.Lu)/100u) +-. \" exdent if \\$3 > 0 +-. ie 0\\$3 \ +-. ti -(\\n(siu-\\n(sou) +-. el \ +-. ti +\\n(sou +-. @F \\n(sf +-. sz \\n(sp +-. if 0\\$3 \ +-. $\\$3 +-. if \w"\\$2">0 \\$2. +-. if \w"\\$1">0 \\$1\f1\ \ \& +-.\} +-.el \ +-. sp \\n(psu +-.@F \\n(pf +-.sz \\n(pp +-.. +-. +-. +-.\" *** COLUMNED OUTPUT *** +-. +-. +-.de 2c \" *** double columned output +-.br +-.if \\n($m>1 \ +-. 1c\" \" revert to 1c if already 2c +-.nr $c 1 +-.nr $m 2 +-.if \\n(.$>1 \ +-. nr $m \\$2 +-.if \\n(.$>0 \ +-. nr $s \\$1n \" param 1: column separation +-.nr $l (\\n(.l-((\\n($m-1)*\\n($s))/\\n($m +-.xl \\n($lu +-.mk _k +-.ns +-.. +-. +-.de 1c \" *** single columned output +-.br +-.nr $c 1 +-.nr $m 1 +-.ll \\n(_Lu \" return to normal output +-.sp |\\n(.hu +-.@O \\n(_ou +-.. +-. +-.de bc \" *** begin column +-.sp 24i +-.. +-. +-. +-.\" *** FLOATING TABLES AND NONFLOATING BLOCKS *** +-. +-. +-.de (z \" *** begin floating keep +-.if \n@>4 .tm >> (z, .z=\n(.z +-.@D 4 \\$1 \\$2 +-.@( +-.. +-. +-.de )z \" *** end floating keep +-.if \n@>4 .tm >> )z, .z=\n(.z +-.sp \\n(zsu +-.@) +-.if \n@>4 .tm -- )z << @), .z=\n(.z +-.rr _0 +-.if !\\n(?b \ +-. nr dn +(\\n(ppp*\\n($vu)/200u+\\n(zsu +-.nr dl -\n(.H \" fudge factor necessary to make it work +-.ie ((\\n(dn+\n(.V)>=\\n(.t):(\\n(?a):((\\n(dl>\\n($l)&(\\n($c>1)) \ +-\{\ +-. nr ?a 1 +-. if (\\n(dl>\\n($l)&(\\n($m>1) \ +-. nr ?w 1 \" mark wider than one column (top) +-. ds |x |t +-.\} +-.el \ +-\{\ +-. nr ?b 1 +-. if (\\n(dl>\\n($l)&(\\n($m>1) \ +-. nr ?W 1 \" mark wider than one column (bottom) +-. nr _b +\\n(dnu +-. \" avoid moving @f back past the current position +-. if \\n(.p-\\n(nl-\n(.V<\\n(_b \ +-. nr _b \\n(.p-\\n(nl-\n(.V +-. ch @f -\\n(_bu +-. ds |x |b +-.\} +-.da \\*(|x \" copy to save macro +-.nf +-.ls 1 +-.nr ?k 1 +-.if \n@>4 .tm -- )z >> \\*(|x +-\!.if \\\\n(nl>(\\\\n(tm+2v) .ne \\n(dnu-\\n(zsu +-.|k\" \" and the body +-.ec +-.if \n@>4 .tm -- )z << \\*(|x, .z=\\n(.z +-.nr ?k 0 +-.rm |k\" \" remove the temp macro +-.da +-.in 0 +-.ls 1 +-.xl \\n($lu +-.ev +-.if \n@>4 .tm << )z, .z=\\n(.z +-.. +-. +-.de @k \" --- output floating keep +-.if \n@>4 .tm >> @k, $1=\\$1, .z=\\n(.z +-.ev 1 +-.nf +-.ls 1 +-.in 0 +-.sp \\n(zsu +-.if \\n(?n \ +-. nm \\n(ln +-.\\$1 +-.if \\n(?n \ +-. nm +-.ec +-.br +-.rm \\$1 +-.ev +-.. +-. +-.de (t \" XXX temp ref to (z +-.(z \\$1 \\$2 +-.. +-. +-.de )t \" XXX temp ref to )t +-.)z \\$1 \\$2 +-.. +-. +-.de (b \" *** begin block +-.br +-.@D 3 \\$1 \\$2 +-.sp \\n(bsu +-.@( +-.if '\*(.T'html' .sp \\n(bsu +-.. +-. +-.de )b \" *** end block +-.br +-.@) +-.if (\\n(bt=0):(\\n(.t<\\n(bt) \ +-. ne \\n(dnu \" make it all on one page +-.@k |k +-.ev \" return from display environment +-.sp \\n(bsu+\\n(.Lv-1v +-.. +-. +-.de @( \" --- begin keep +-.if !"\\n(.z"" .tm Line \\n(c. -- Invalid nested keep \\n(.z +-.@M +-.di |k +-\!'rs +-.. +-. +-.de @M \" --- set modes for display +-.nr ?k 1 +-.@C 1 +-.@F \\n(df +-.if \\n($R .@V +-.vs \\n(.sp*\\n($Vu/100u +-.nf +-.if "\\*(|p"F" \ +-. fi \" set fill mode if "F" parameter +-.if \\n(_d=4 \ +-. in 0 +-.if \\n(_d=3 \ +-\{\ +-. in +\\n(biu +-. xl -\\n(biu +-.\} +-.if \\n(_d=1 \ +-. ce 10000 +-.. +-. +-.de @) \" --- end keep +-.br +-.if !"\\n(.z"|k" .tm Line \\n(c. -- Close of a keep which has never been opened +-.nr ?k 0 +-.di +-.in 0 +-.ce 0 +-.. +-. +-.de (c \" *** begin block centered text +-.br +-.if "\\n(.z"|c" .tm Line \\n(c. -- Nested .(c requests +-.if \\n(?n .nm +-.di |c +-.. +-. +-.de )c \" *** end block centered text +-.if !"\\n(.z"|c" .tm Line \\n(c. -- Unmatched .)c +-.br \" force out final line +-.di +-.if \n@>4 .tm >> .)c .l=\\n(.l .i=\\n(.i $i=\\n($i dl=\\n(dl +-.ev 1 +-.ls 1 +-.in (\\n(.lu-\\n(.iu-\\n(dlu)/2u +-.if \n@>4 .tm -- .)c << .in .l=\\n(.l .i=\\n(.i dl=\\n(dl +-.if \\n(?n \ +-. nm \\n(ln +-.nf +-.|c +-.ec +-.in +-.ls +-.if \\n(?n \ +-. nm +-.ev +-.rm |c +-.. +-. +-. +-.\" *** BLOCK QUOTES (OR WHATEVER) AND LISTS *** +-. +-. +-.de (q \" *** begin block quote +-.br +-.@C 1 +-.fi +-.sp \\n(qsu +-.in +\\n(qiu +-.xl -\\n(qiu +-.sz \\n(qp +-.if \\n(?n \ +-. nm \\n(ln +-.. +-. +-.de )q \" *** end block quote +-.br +-.if \\n(?n \ +-. nm +-.ev +-.sp \\n(qsu+\\n(.Lv-1v +-.nr ?k 0 +-.. +-. +-.de (l \" *** begin list +-.br +-.sp \\n(bsu +-.@D 3 \\$1 \\$2 +-.@M +-.if \\n(?n \ +-. nm \\n(ln +-.if '\*(.T'html' .sp \\n(bsu +-.. +-. +-.de )l \" *** end list +-.br +-.if \\n(?n \ +-. nm +-.ev +-.sp \\n(bsu+\\n(.Lv-1v +-.nr ?k 0 +-.. +-. +-. +-.\" *** PREPROCESSOR SUPPORT *** +-. +-. +-.\" +-.\" EQN +-.\" +-.de EQ \" *** equation start +-.do if \\n[need_eo_h]>0 .do DEVTAG-EO-H +-.do nr need_eo_h 0 +-.ec +-.if "\*(.T"html" \ +-\{\ +-. do nr e-EQ-ll \\n(.l +-. ll 1000n +-.\} +-.do HTML-IMAGE +-.if !\\n(?e \ +-\{\ +-. if "\\n(.z"|e" .tm Line \\n(c. -- Nested .EQ request +-. @D 1 "\\$1" "\\$2" +-. @C 2 +-. di |e +-.\} +-.ls 1 +-.in 0 +-.nf +-.. +-. +-.de EN \" *** equation end +-.br +-.do HTML-IMAGE-END +-.if "\*(.T"html" \ +-. do ll \\n[e-EQ-ll]u +-.ie "\\$1"C" \ +-\{\ +-. nr ?e 1 +-. sp \\n(esu +-.\} +-.el \ +-\{\ +-. nr ?e 0 +-. di +-. if \\n(dn \ +-. @q\" \" actual equation output +-. rm |e +-. ev +-.\} +-.. +-. +-.de @q \" --- equation output +-.nr _Q \\n(dnu +-.ev +-.sp \\n(esu \" output rest of preceding text +-.if !"\\n(.z"" \!.ne \\n(_Qu +-.ne \\n(_Qu+\n(.Vu \" keep it on one page +-.@C 2\" \" .ev 2 may be jumbled from header +-.if \\n(_d=1 \ +-. in (\\n(.lu+\\n($iu-\\n(dlu)/2u +-.if \\n(_d=2 \ +-. in \\n($iu +-.if \\n(_d=3 \ +-. in \\n(biu+\\n($iu +-.if \\n(_d=4 \ +-. in 0 +-.mk _q +-.if \n@>1 .tm --@e: _Q=\\n(_Q _q=\\n(_q nl=\\n(nl |p=\\*(|p +-.if !"\\*(|p"" \ +-\{\ +-. rs +-. sp (\\n(_Qu-\\n(.vu)/2u +-. tl """\\*(|p" +-. rt \\n(_qu +-.\} +-.if \\n(?n \ +-. nm \\n(ln +-.|e +-.if \\n(?n \ +-. nm +-.sp |\\n(_qu+\\n(_Qu +-.sp \\n(esu+\\n(.Lv-1v +-.rr _q +-.rr _Q +-.. +-. +-.\" +-.\" TBL +-.\" +-.de TS \" *** table start +-.sp \\n(bsu +-.if "\*(.T"html" \ +-\{\ +-. do nr e-TS-ll \\n(.l +-. ll 1000n +-.\} +-.do HTML-IMAGE +-.@C 1 +-.fi \" drop into fill mode for text boxes +-.if "\\$1"H" \ +-\{\ +-. di |h \" save header part +-. nr ?T 1 +-.\} +-.ls 1 +-.ch @f -(\\n(_bu+1v) \" set pseudo-trap for bottom line +-.if \\n(.p-\\n(_b-1v<=\\n(nl \ +-. ch @f \\n(nlu+\n(.Vu +-.. +-. +-.de TH \" *** end header part of table +-.nr T. 0 +-.T# 0 +-.if \\n(?n \!.nm +-.di +-.nr _T \\n(?T +-.nr ?T 0 +-.ne \\n(dnu+1v +-.nr ?T \\n(_T +-.nr _i \\n(.i +-.if \\n(?n .nm \\n(ln +-.in 0 +-.|h\" \" put in the initial header +-.in \\n(_iu +-.rr _i +-.mk #T +-.. +-. +-.de TE \" *** table end +-.nr ?T 0 +-.ch @f -\\n(_bu \" reset pseudo-trap +-.if \\n(.p-\\n(_b<=\\n(nl \ +-. ch @f \\n(nlu+\n(.Vu +-.ev +-.do HTML-IMAGE-END +-.if "\*(.T"html" \ +-. do ll \\n[e-TS-ll]u +-.sp \\n(bsu+\\n(.Lv-1v +-.re +-.. +-. +-.de T& +-.. +-. +-.\" +-.\" REFER +-.\" +-.mso refer-me.tmac +-. +-.\" +-.\" IDEAL +-.\" +-.de IS \" *** start ideal picture +-.nr g7 \\n(.u +-.ls 1 +-.. +-. +-.de IF +-.if \\n(g7 .fi +-.ls +-.. +-. +-.de IE \" *** end ideal picture +-.if \\n(g7 .fi +-.ls +-.. +-. +-.\" +-.\" PIC +-.\" +-.de PS \" *** start picture: $1=height, $2=width in units or inches +-.sp 0.3 +-.do HTML-IMAGE +-.nr g7 \\$2 +-.in (u;\\n(.l-\\n(g7>?0/2) +-.ne \\$1u +-.nr g7 \\n(.u +-.ls 1 +-.if \\n(?n \ +-\{\ +-. de PS_nm_check && \" define macro to emit .nm at top diversion +-. if \n@>4 .tm -- PS: \\\\$1 \\\\$2 .z=\\\\n(.z PS_nm_cnt=\\\\n[PS_nm_cnt] +-. \" \" multiple .PS/.PE in a keep. +-. if `\\\\$2`init` \ +-. do nr PS_nm_cnt \\\\n[PS_nm_cnt]+1 +-. ie `\\\\n(.z`` \ +-\{\ +-. if `\\\\$1`suspend` \ +-. nm +-. if `\\\\$1`resume` \ +-\{\ +-. nm \\\\n(ln +-. do nr PS_nm_cnt \\\\n[PS_nm_cnt]-1 +-. do if !\\\\n[PS_nm_cnt] \ +-\{\ +-. do rm PS_nm_check +-. do rr PS_nm_cnt +-.\} +-.\} +-.\} +-.el \!.PS_nm_check \\\\$1 +-.&& +-. mk _q \" emit a single numbered line for PS picture +-. rs +-\&\ +-. br +-. rt \\n(_qu +-. PS_nm_check suspend init +-.\} +-.. +-. +-.de PE \" *** end picture +-.if \\n(?n .PS_nm_check resume +-.ls +-.in +-.if \\n(g7 .fi +-.do HTML-IMAGE-END +-.sp .6 +-.. +-. +-.\" +-.\" GREMLIN +-.\" +-.de GS \" *** start gremlin picture +-.ie '\*(.T'html' \ +-\{\ +-. ie "\\$1"L" .do HTML-IMAGE-LEFT +-. el .ie "\\$1"R" .do HTML-IMAGE-RIGHT +-. el .do HTML-IMAGE +-.\} +-.el \ +-\{\ +-. nr g7 (\\n(.lu-\\n(g1u)/2u +-. if "\\$1"L" .nr g7 \\n(.iu +-. if "\\$1"R" .nr g7 \\n(.lu-\\n(g1u +-. in \\n(g7u +-. nr g7 \\n(.u +-. ls 1 +-. nf +-. ne \\n(g2u +-.\} +-.. +-. +-.de GE \" *** end gremlin picture +-.ie '\*(.T'html' .do HTML-IMAGE-END +-.el \ +-\{\ +-. GF +-. sp .6 +-.\} +-.. +-. +-.de GF \" *** finish gremlin picture; stay at top +-.ls +-.in +-.if \\n(g7 .fi +-.. +-. +-. +-.\" *** FONT AIDS *** +-. +-. +-.de sz \" *** set point size and vertical spacing +-.ps \\$1 +-.if \\n($r .@v +-.vs \\n(.sp*\\n($vu/100u \" default vs at pointsize + 20% +-.. +-. +-.de @v \" --- possibly set $v from $r +-.if (1i>=240u)&(1p<=\\n($r)&(\\n($r<=4p) .nr $v \\n($r00/1p +-.. +-. +-.de @V \" --- possibly set $V from $R +-.if (1i>=240u)&(1p<=\\n($R)&(\\n($R<=4p) .nr $V \\n($R00/1p +-.. +-. +-.de @E \" --- store in _F argument to \f for restoring font +-.ie \\n(.f<10 \ +-. ds _F \\n(.f +-.el \ +-\{\ +-. ie \\n(.f<100&\n(.g \ +-. ds _F (\\n(.f +-. el \ +-. ds _F P +-.\} +-.. +-. +-.de r \" *** enter roman font +-.do check_need_title +-.@E +-.ft 1 +-.if \\n(.$ \&\\$1\f\\*(_F\\$2 +-.do check_need_title +-.. +-. +-.de i \" *** enter italic +-.do check_need_title +-.@E +-.ft 2 +-.if \\n(.$ \&\\$1\f\\*(_F\\$2 +-.do check_need_title +-.. +-. +-.de b \" *** enter boldface +-.do check_need_title +-.@E +-.ft 3 +-.if \\n(.$ \&\\$1\f\\*(_F\\$2 +-.do check_need_title +-.. +-. +-.de rb \" *** enter real boldface +-.do check_need_title +-.@E +-.ft 3 +-.if \\n(.$ \&\\$1\f\\*(_F\\$2 +-.do check_need_title +-.. +-. +-.de bi \" *** enter bold italic +-.do check_need_title +-.@E +-.ft 4 +-.if \\n(.$ \&\\$1\f\\*(_F\\$2 +-.do check_need_title +-.. +-. +-.de u \" *** enter underlined word +-\&\\$1\l'|0\(ul'\\$2 +-.. +-. +-.\" a better version of u +-.if !\n(.g .ig +-.de u +-\Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2 +-.. +-. +-.de q \" *** enter quoted word +-\&\\*(lq\\$1\\*(rq\\$2 +-.. +-. +-.de bx \" *** enter boxed word +-.ie '\*(.T'html' \\$1\\$2 +-.el \k~\(br\|\\$1\|\(br\l'|\\n~u\(rn'\l'|\\n~u\(ul'\^\\$2 +-.. +-. +-.de sm \" *** print in smaller font +-\s-1\\$1\\s0\\$2 +-.. +-. +-.de @F \" --- change font (0 -> no change) +-.nr ~ \\$1 +-.if \\n~>0 \ +-. ft \\n~ +-.rr ~ +-.. +-. +-. +-.\" *** FOOTNOTING *** +-. +-. +-.de (f \" *** begin footnote +-.ec +-.if "\\n(.z"|f" .tm Line \\n(c. -- Invalid footnote nesting +-.ie "\\n(.z"" \ +-\{\ +-. nr _D \\n(dn +-. nr _0 1v+\\n(nlu +-. ev 2 +-. nm +-. da |f +-. in 0 +-. xl \\n($lu-\\n(fuu +-. @F \\n(ff +-. sz \\n(fp +-. vs \\n(.sp*\\n($Vu/100u +-. if !\\n(?f \ +-\{\ +-. nr _b +1v \" allow space for $s +-. $s +-. \} +-. br +-. if \\n(.p-\\n(_b-\\n(_0-\\n(.h-1v-\\n(fs<0 \ +-\{\ +-. da\" \" won't fit on page at all +-. bc +-. if !\\n(?f \ +-. rm |f +-. da |f +-.\" next five lines could be dropped if headers had their own environment +-. in 0 \" reset everything from .bc +-. xl \\n($lu-\\n(fuu +-. @F \\n(ff +-. sz \\n(fp +-. vs \\n(.sp*\\n($Vu/100u +-. if !\\n(?f \ +-. $s +-. br +-. \} +-. rr _0 +-. sp \\n(fsu +-. nr ?f 1 +-. fi +-. if !"\\$1"_" \ +-. ti \\n(fiu +-. if \n@>2 .tm << (f $f=\\n($f +-.\} +-.el \ +-\{\ +-. ev 2 +-. nm +-. in 0 +-. xl \\n($lu-\\n(fuu +-. @F \\n(ff +-. sz \\n(fp +-. vs \\n(.sp*\\n($Vu/100u +-. fi +-\!.(f \\$1 +-\!.@N +-.\} +-.. +-. +-.de @N \" --- set no fill mode in the top-level diversion +-.ie "\\n(.z"" .nf +-.el \!.@N +-.. +-. +-.de )f \" *** end footnote +-.ie "\\n(.z"|f" \ +-\{\ +-. if \\n* \ +-. nr $f +1 +-. ds * \\*{\\n($f\\*}\k* +-. nr * 0 +-. in 0 +-. da +-. ev +-. if \\n(_w<\\n(dl \ +-. nr _w \\n(dl \" compute maximum fn width +-. nr _b +\\n(dn +-. ch @f -\\n(_bu +-. if \\n(.p-\\n(_b<=\\n(nl \ +-. ch @f \\n(nlu+\n(.Vu +-. nr dn \\n(_D +-. rr _D +-.\} +-.el \ +-\{\ +-. br +-\!.)f +-. ev +-.\} +-.. +-. +-.@R ff +-.if \n(ff<=0 \ +-. nr ff 1 \" footnote font: Times Roman +-.@R fp +-.if \n(fp<=0 \ +-. nr fp 8 \" footnote pointsize +-. +-.de $s \" $$$ footnote separator +-\l'2i' +-.. +-. +-. +-.\" *** DELAYED TEXT *** +-. +-. +-.de (d \" *** begin delayed text +-.am |d )d +-.sp \\n(bsu +-.. +-. +-.de )d \" *** end delayed text +-.if \\n# \ +-. nr $d +1 +-.ds # [\\n($d]\k# +-.rr # +-.. +-. +-.de pd \" *** print delayed text +-.|d +-.rm |d +-.nr $d 1 1 +-.ds # [1]\k# +-.. +-. +-. +-.\" *** INDEXES (TABLE OF CONTENTS) *** +-. +-. +-.nr _x 0 1 +-.do nr _xn 0 +-.af _x a +-. +-.de (x \" *** begin index entry +-.if \n@>4 .tm >> (x, .z=\\n(.z +-.ds |X x +-.if \\n(.$>0 \ +-. ds |X \\$1 +-.ie "\\n(.z"" \ +-. nr _z 0 +-.el \ +-. nr _z 1 +-.@\\n(_z +-.. +-. +-.de @0 \" --- finish (x if no current diversion +-.am %\\*(|X )x +-.sp \\n(xsu +-.ti -\\n(piu +-.. +-. +-.de @1 \" --- finish (x if current diversion +-.if "\\n(_x"z" .nr _x 0 +-.de =\\n+(_x )x +-.. +-. +-.de )x \" *** end index entry +-.if \n@>4 .tm >> )x, .z=\\n(.z +-.ie "\\n(.z"" \ +-\{\ +-. ds |x \\n% +-. if \\n(.$>0 \ +-. ds |x \\$1 +-. if "\\*(|x"_" \ +-. ig .. +-. am %\\*(|X .. +-. if \w"\\$2">(\\n(.l-\\n(.i-\\n(.k) \ +-. ti +\\n(xuu +-\\\\a\\\\t\\$2\\*(|x +-... +-. rm |x +-. rm |X +-.\} +-.el \ +-\{\ +-\!.(x \\*(|X +-\!\\\\*(=\\n(_x\\\\ +-\!.)x \\$1 \\$2 +-\!.rm =\\n(_x +-.\} +-.. +-. +-.de xp \" *** print the index +-.br +-.@C 2 +-.ls 1 +-.vs \\n(.sp*\\n($Vu/100u +-.fi +-.in +\\n(piu +-.ds |X x +-.if \\n(.$>0 \ +-. ds |X \\$1 +-.xl -(\\n(xuu+\w'...'u) +-.di |x +-.%\\*(|X +-.br +-.di +-.rm %\\*(|X +-.xl \\n($lu +-.rm |X +-.ev +-.nf +-.in 0 +-.ta \\n(.lu-\\n(xuuR \\n(.luR +-.|x +-.fi +-.in +-.rm |x +-.. +-. +-. +-.\" *** HTML VERSIONS OF .x(, .x), AND .xp *** +-. +-. +-.de (x-html \" --- create TAG and divert text +-.nr _x +1 +-.do nr _xn +1 +-.do TAG "_x\\n[_x] +-.br +-.do di |x\\n[_xn] +-.br +-.. +-. +-.de )x-html \" --- end diversion +-.br +-.di +-.. +-. +-.de xp-html \" --- create list of links +-.do nr _xx 1 +-.br +-.do ev xp-html-ev +-.sp +-.do ULS +-.do while \\n[_xx]<=\\n[_xn] \ +-\{\ +-. br +-. do unformat |x\\n[_xx] +-. do di xp-html-div +-. br +-. ll 100i +-. fi +-. do |x\\n[_xx] +-. br +-. di +-. do asciify xp-html-div +-. do rm xp-html-as +-. do as xp-html-as # +-. do as xp-html-as _x\\n[_xx] +-. ll +-. LI +-. do URL \\*[xp-html-as] "\\*[xp-html-div] +-. do rm xp-html-as +-. do nr _xx +1 +-.\} +-.do ULE +-.sp +-.ev +-.. +-. +-.if '\*(.T'html' \ +-\{\ +-. rm (x +-. do als (x (x-html +-. rm )x +-. do als )x )x-html +-. rm xp +-. do als xp xp-html +-.\} +-. +-. +-.\" *** CHAPTERS AND TITLES *** +-. +-. +-.de +c \" *** begin chapter +-.ep\" \" force out footnotes +-.if \\n(?o:\\n(?a \ +-\{\ +-. bp \" force out a table or more footnote +-. rs +-. ep +-.\} +-.nr ?C 1 +-.nr $f 1 1 +-.ds * \\*{1\\*}\k* +-.if \\n(?R \ +-. pn 1 +-.bp +-.in \\n($iu \" reset the indent +-.rs +-.ie \\n(.$ \ +-. $c "\\$1" +-.el \ +-. sp 3 +-.. +-. +-.de ++ \" *** declare chapter type +-.nr _0 0 +-.if "\\$1"C" \ +-. nr _0 1 \" chapter +-.if "\\$1"RC" \ +-. nr _0 11 \" renumbered chapter +-.if "\\$1"A" \ +-. nr _0 2 \" appendix +-.if "\\$1"RA" \ +-. nr _0 12 \" renumbered appendix +-.if "\\$1"P" \ +-. nr _0 3 \" preliminary material +-.if "\\$1"B" \ +-. nr _0 4 \" bibliographic material +-.if "\\$1"AB" \ +-. nr _0 5 \" abstract +-.if \\n(_0=0 \ +-. tm Line \\n(c. -- Bad mode to .++ +-.nr ?R 0 +-.if \\n(_0>10 \ +-.\{ +-. nr ?R 1 +-. nr _0 -10 +-.\} +-.nr ch 0 1 +-.if (\\n(_0=3):(\\n(_0=5) \ +-. pn 1 \" must do before .ep +-.if !\\n(_0=\\n(_M .if \\n(_M=3 \ +-. pn 1 \" must do before .ep +-.ep\" \" end page for correct page number types +-.if \\n(_0=1 \ +-\{\ +-. af ch 1 +-. af % 1 +-.\} +-.if \\n(_0=2 \ +-\{\ +-. af ch A +-. af % 1 +-.\} +-.if \\n(_0=3 \ +-. af % i +-.if \\n(_0=4 \ +-. af % 1 +-.if \\n(_0=5 \ +-. af % 1 +-.if \\n(.$>1 \ +-. he \\$2 +-.nr _M \\n(_0 +-.rr _0 +-.. +-. +-.de $c \" $$$ print chapter title +-.sz 12 +-.ft 3 +-.ce 1000 +-.if \\n(_M<3 \ +-. nr ch +1 +-.ie \\n(_M=1 CHAPTER\ \ \\n(ch +-.el .if \\n(_M=2 APPENDIX\ \ \\n(ch +-.if \w"\\$1" .sp 3-\\n(.L +-.if \w"\\$1" \\$1 +-.if (\\n(_M<3):(\w"\\$1") \ +-. sp 4-\\n(.L +-.ce 0 +-.ft +-.sz +-.ie \\n(_M=1 \ +-. $C Chapter \\n(ch "\\$1" +-.el .if \\n(_M=2 \ +-. $C Appendix \\n(ch "\\$1" +-.. +-. +-.de tp \" *** title page +-.hx +-.bp +-.br +-.rs +-.pn \\n% +-.. +-. +-.\" *** DATES *** +-.if \n(mo=1 .ds mo January +-.if \n(mo=2 .ds mo February +-.if \n(mo=3 .ds mo March +-.if \n(mo=4 .ds mo April +-.if \n(mo=5 .ds mo May +-.if \n(mo=6 .ds mo June +-.if \n(mo=7 .ds mo July +-.if \n(mo=8 .ds mo August +-.if \n(mo=9 .ds mo September +-.if \n(mo=10 .ds mo October +-.if \n(mo=11 .ds mo November +-.if \n(mo=12 .ds mo December +-.if \n(dw=1 .ds dw Sunday +-.if \n(dw=2 .ds dw Monday +-.if \n(dw=3 .ds dw Tuesday +-.if \n(dw=4 .ds dw Wednesday +-.if \n(dw=5 .ds dw Thursday +-.if \n(dw=6 .ds dw Friday +-.if \n(dw=7 .ds dw Saturday +-.nr y2 \n(yr%100 +-.af y2 00 +-.nr y4 \n(yr+1900 +-.ds td \*(mo \n(dy, \n(y4 +-. +-. +-.\" *** PARAMETRIC INITIALIZATIONS *** +-. +-. +-.rr x +-.nr $v \n(.v00+\n(.sp-1/\n(.sp \" vs as percentage of ps for .sz request +-.nr $V \n($v \" same for displays & footnotes +-.nr hm 4v \" header margin +-.nr tm 7v \" top margin +-.nr bm 6v \" bottom margin +-.nr fm 3v \" footer margin +-.nr tf 3 \" title font: (real) Times Bold +-.nr tp 10 \" title point size +-.hy 14 +-.nr bi 4m \" indent for blocks +-.nr pi 5n \" indent for paragraphs +-.nr pf 1 \" normal text font +-.nr pp 10 \" normal text point size +-.nr qi 4n \" indent for quotes +-.nr qp -1 \" down one point +-.nr ii 5n \" indent for .ip's and .np's +-.nr $m 1 \" max number of columns +-.nr $s 4n \" column separation +-.nr sf 3 \" section font -- Times Bold +-.nr sp 10 \" section title pointsize +-.nr ss 12p \" section prespacing +-.nr si 0 \" section indent +-. +-. +-.\" *** OTHER INITIALIZATION *** +-. +-. +-.\" GNU pic sets this register to 1, to indicate that \x should not be used. +-.@R 0x +-.ds { \v'-0.4m'\x'\\n(0x=0*-0.2m'\s-3 +-.ds } \s0\v'0.4m' +-.\" for compatibility with traditional -me +-.\" (the first will work only in compatibility mode) +-.ds [ \*{ +-.ds ] \*} +-.ds < \v'0.4m'\x'\\n(0x=0*0.2m'\s-3 +-.ds > \s0\v'-0.4m' +-.ds - \(em +-.\" Avoid warnings from groff -ww. +-.@S |0 +-.@S |1 +-.@S |2 +-.@S |3 +-.@S $H +-.@S $0 +-.@S $1 +-.@S $2 +-.@S $3 +-.@S $4 +-.@S $5 +-.@S $6 +-.@S $7 +-.@S $8 +-.@S $9 +-.@S .. +-. +-.@R po\" \" simulated page offset +-.@R $0\" \" section depth +-.@R $i\" \" paragraph base indent +-.@R $p\" \" numbered paragraph number +-.@R $r\" \" ratio of vs to ps (may override $v) +-.@R $R\" \" same for displays (may override $V) +-.@R df\" \" display font: same as surrounding text +-.@R so\" \" additional section title offset +-.@R fu\" \" footnote undent +-.@R bt\" \" block keep threshold +-.@R *\" \" has \** been referenced? +-.@R ?a\" \" pending floating keep at page top? +-.@R ?b\" \" pending floating keep at page bottom? +-.@R ?C\" \" at chapter header? +-.@R ?e\" \" in equation? +-.@R ?H\" \" suppress headers and footers next page? +-.@R ?I\" \" has the header trap been sprung? +-.@R ?n\" \" n1 mode? +-.@R ?o\" \" footnote overflow? +-.@R ?R\" \" renumbered chapter? +-.@R ?s\" \" skip next page? +-.@R ?T\" \" inside .TS H? +-.@R ?W\" \" wide floating keep at page bottom? +-.@R ?w\" \" wide floating keep at page top? +-. +-.nr fi 0.3i +-.nr _o \n(.o +-.nr $b 3 \" bold +-.nr ps 0.35v +-.if \n(ps<\n(.V .nr ps \n(.V +-.nr bs \n(ps \" block pre/post spacing +-.nr qs \n(ps \" quote pre/post spacing +-.nr zs 1v \" float-block pre/postspacing +-.nr xs 0.2v \" index prespacing +-.nr xu 0.5i \" index undent +-.nr fs 0.2v \" footnote prespacing +-.nr es 0.5v \" equation pre/postspacing +-.if \n(es<\n(.V .nr es \n(.V +-.wh 0 @h \" set header +-.nr $l \n(.lu \" line length +-.nr _L \n(.lu \" line length of page +-.nr $c 1 \" current column number +-.nr $f 1 1 \" footnote number +-.ds * \*{1\*}\k*\" \" footnote "name" +-.nr $d 1 1 \" delayed text number +-.ds # [1]\k#\" \" delayed text "name" +-.nr _M 1 \" chapter mode is chapter +-.ds lq \(lq\" \" left quote +-.ds rq \(rq\" \" right quote +-.em @z +-. +-. +-.\" *** FOREIGN LETTERS AND SPECIAL CHARACTERS *** +-. +-. +-.ds #h ((1u-(\\\\n(.fu%2u))*0.13m) +-.ds #v 0.6m +-. +-.\" \" accents +-.ds ' \k_\h'-(\\n(.wu*8/10-\*(#h)'\(aa\h'|\\n_u' +-.ds ` \k_\h'-(\\n(.wu*7/10-\*(#h)'\(ga\h'|\\n_u' +-. +-.\" \" umlaut +-.ds : \k_\h'-(\\n(.wu*8/10-\*(#h+0.1m)'\v'-\*(#v'\z.\h'0.2m'.\h'|\\n_u'\v'\*(#v' +-. +-.\" \" circumflex and tilde +-.ds ^ \k_\h'-(\\n(.wu-\*(#h-0.05m)'^\h'|\\n_u' +-.ds ~ \k_\h'-(\\n(.wu-\*(#h-0.05m)'~\h'|\\n_u' +-. +-.\" \" cedilla and czech +-.ds , \k_\h'-(\\n(.wu)',\h'|\\n_u' +-.ds v \k_\h'-(\\n(.wu*9/10-\*(#h)'\v'-\*(#v'\s-4v\s0\v'\*(#v'\h'|\\n_u' +-. +-.\" \" Norwegian A or angstrom +-.ds o \k_\h'-(\\n(.wu+\w'\(de'u-\*(#h)/2u'\v'-0.4n'\z\(de\v'0.4n'\h'|\\n_u' +-. +-.\" \" there exists, for all +-.ds qe \s-2\v'0.45m'\z\(em\v'-0.625m'\z\(em\v'-0.625m'\(em\v'0.8m'\s0\h'-0.1m'\v'-0.05m'\(br\v'0.05m'\h'0.1m' +-.ds qa \z\e\h'0.35m'\z\(sl\h'-0.33m'\v'-0.3m'\s-4\(em\s0\v'0.3m'\h'0.15m' +-.rm #h #v +-.ll 6.0i +-.lt 6.0i +-. +-.de @U +-.tm The \\$1 macro has been removed from this version of the -me macros. +-.. +-. +-.de lo +-.@U lo +-.. +-. +-.de th +-.@U th +-.. +-. +-.de ac +-.@U ac +-.. +-. +-.\" EOF +diff -Nuar groff-1.22.3.old/tmac/e.tmac-u groff-1.22.3/tmac/e.tmac-u +--- groff-1.22.3.old/tmac/e.tmac-u 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/e.tmac-u 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,2037 @@ ++.\" -*- nroff -*- ++.\" ++.\" @(#)e.tmac 2.31 (Berkeley) 5/21/88 ++.\" Modified by James Clark for use with groff. ++.\" ++.\" Copyright (c) 1988 Regents of the University of California. ++.\" All rights reserved. ++.\" ++.\" Redistribution and use in source and binary forms are permitted ++.\" provided that this notice is preserved and that due credit is given ++.\" to the University of California at Berkeley. The name of the University ++.\" may not be used to endorse or promote products derived from this ++.\" software without specific prior written permission. This software ++.\" is provided ``as is'' without express or implied warranty. ++.\" %beginstrip% ++.\" ++.\"********************************************************************** ++.\"* * ++.\"* ****** - M E N R O F F / T R O F F M A C R O S ****** * ++.\"* * ++.\"* Produced for your edification and enjoyment by: * ++.\"* Eric Allman * ++.\"* Electronics Research Laboratory * ++.\"* U.C. Berkeley. * ++.\"* current address: * ++.\"* Britton-Lee, Inc. * ++.\"* 1919 Addison Street Suite 105 * ++.\"* Berkeley, California 94704 * ++.\"* * ++.\"* VERSION 2.31 First Release: 11 Sept 1978 * ++.\"* * ++.\"* Documentation is available. * ++.\"* * ++.\"********************************************************************** ++.\" ++.\" Code on .de commands: ++.\" *** a user interface macro. ++.\" &&& a user interface macro which is redefined ++.\" when used to be the real thing. ++.\" $$$ a macro which may be redefined by the user ++.\" to provide variant functions. ++.\" --- an internal macro. ++.\" ++. ++.do nr need_eo_h 0 ++.do nr need_eo_tl 0 ++.do nr need_tl 1 ++. ++.do mso devtag.tmac ++. ++.if !\n(.g .ig ++.de @R \" --- initialize number register to 0, if undefined ++.if !r\\$1 .nr \\$1 0 ++.. ++. ++.\" --- check whether grohtml needs end of title/heading ++.de @html_check_need_title ++.do if (\\n[need_eo_tl] == 1) \ ++\{\ ++. do nr need_eo_tl 0 ++. do DEVTAG-EO-TL ++.\} ++.do if (\\n[need_tl] == 1) \ ++\{\ ++. do DEVTAG-TL ++. do nr need_tl 0 ++. do nr need_eo_tl 1 ++.\} ++.do if \\n[need_eo_h]>0 .do DEVTAG-EO-H ++.do nr need_eo_h 0 ++.. ++. ++.de @check_need_title ++.. ++. ++.ie '\*(.T'html' \ ++. do als check_need_title @html_check_need_title ++.el \ ++. do als check_need_title @check_need_title ++. ++.@R pf ++.if \n(pf .nx ++. ++.if !\n(.g .ig ++.de @S \" --- initialize string/macro to empty, if undefined ++.if !d\\$1 .ds \\$1 \" empty ++.. ++. ++.@R @\" \" debugging level ++. ++. ++.\" *** INTERNAL GP MACROS *** ++. ++. ++.de @C \" --- change ev's, taking info with us ++.nr _S \\n(.s ++.nr _V \\n(.v ++.nr _F \\n(.f ++.nr _J \\n(.j ++.do ds _A \\n[.fam] ++.nr _I \\n(.i ++.ev \\$1 ++.ps \\n(_S ++.vs \\n(_Vu ++.ft \\n(_F ++.ad \\n(_J ++.do @fam \\*(_A ++'in \\n(_Iu ++.xl \\n($lu ++.lt \\n($lu ++.rr _S ++.rr _V ++.rr _F ++.rr _I ++.rr _J ++.ls 1 ++'ce 0 ++.. ++. ++.de @D \" --- determine display type (Indent, Left, Center) ++.ds |p "\\$3 ++.nr _d 0 ++.if "\\$2"C" \ ++. nr _d 1 ++.if "\\$2"L" \ ++. nr _d 2 ++.if "\\$2"I" \ ++. nr _d 3 ++.if "\\$2"M" \ ++. nr _d 4 ++.if !\\n(_d \ ++\{\ ++. nr _d \\$1 ++. ds |p "\\$2 ++.\} ++. ++.. ++. ++.de @z \" --- end macro ++.if \n@>1 .tm >> @z, .z=\\n(.z ?a=\\n(?a ++.if !"\\n(.z"" \ ++\{\ ++. tm Line \\n(c. -- Unclosed block, footnote, or other diversion (\\n(.z) ++. di ++. ex ++.\} ++.if \\n(?a \ ++. bp \" force out final table ++.ds bp ++.ds @b\" \" don't start another page ++.br ++.if \n@>1 .tm << @z ++.. ++. ++. ++.\" *** STANDARD HEADERS AND FOOTERS *** ++. ++. ++.ie \n(.g .ds $* \\\\$* ++.el .ds $* \\\\$1 \\\\$2 \\\\$3 \\\\$4 \\\\$5 \\\\$6 \\\\$7 \\\\$8 \\\\$9 ++. ++.de he \" *** define header ++.ie !\\n(.$ \ ++\{\ ++. rm |4 ++. rm |5 ++.\} ++.el \ ++\{\ ++. ds |4 "\*($* ++. ds |5 "\*($* ++.\} ++.. ++. ++.de eh \" *** define even header ++.ie !\\n(.$ \ ++. rm |4 ++.el \ ++. ds |4 "\*($* ++.. ++. ++.de oh \" *** define odd header ++.ie !\\n(.$ \ ++. rm |5 ++.el \ ++. ds |5 "\*($* ++.. ++. ++.de fo \" *** define footer ++.ie !\\n(.$ \ ++\{\ ++. rm |6 ++. rm |7 ++.\} ++.el \ ++\{\ ++. ds |6 "\*($* ++. ds |7 "\*($* ++.\} ++.. ++. ++.de ef \" *** define even foot ++.ie !\\n(.$ \ ++. rm |6 ++.el \ ++. ds |6 "\*($* ++.. ++. ++.de of \" *** define odd footer ++.ie !\\n(.$ \ ++. rm |7 ++.el \ ++. ds |7 "\*($* ++.. ++. ++.de ep \" *** end page (must always be followed by a .bp) ++.if \\n(nl>0 \ ++\{\ ++. wh 0 ++. rs ++. @b ++.\} ++.. ++. ++. ++.\" *** INTERNAL HEADER AND FOOTER MACROS *** ++. ++. ++.de @h \" --- header ++.if \n@>1 .tm >> @h %=\\n% ?a=\\n(?a ?b=\\n(?b ?w=\\n(?w ++.if (\\n(.i+\\n(.o)>=\\n(.l \ ++. tm Line \\n(c. -- Offset + indent exceeds line length ++.\" initialize a pile of junk ++.nr ?h \\n(?H \" transfer "next page" to "this page" ++.nr ?H 0 ++.nr ?c \\n(?C ++.nr ?C 0 ++.rn |4 |0 ++.rn |5 |1 ++.rn |6 |2 ++.rn |7 |3 ++.nr _w 0 \" reset max footnote width ++.nr ?W 0 \" no wide floats this page (yet) ++.nr ?I 1 ++.\" begin actual header stuff ++.ev 2 ++.rs ++.if \\n(hm>0 \ ++. if !'\*(.T'html' \ ++. sp |\\n(hmu \" move to header position ++.@t $h\" \" output header title ++.if \\n(tm<=0 \ ++. nr tm \n(.Vu ++.if !'\*(.T'html' \ ++. sp |\\n(tmu \" move to top of text ++.ev ++.mk _k \" for columned output ++.if \\n(?n=1 .nm 1 \" restore line numbering if n1 mode ++.nr $c 1 \" set first column ++.if \n@>4 .tm -- @h >> .ns nl=\\n(nl %=\\n% _k=\\n(_k tm=\\n(tm ++.ie \\n(?s \ ++\{\ ++. nr ?s 0 ++. rs ++' @b ++.\} ++.el \ ++. @n\" \" begin the column ++.if \n@>2 .tm << @h ++.. ++. ++.de @n \" --- new column or page ++.if \n@>3 .tm >> @n nl=\\n(nl %=\\n% ?f=\\n(?f ?o=\\n(?o ++.if \\n(bm<=0 \ ++. nr bm \\n(.Vu ++.if (\\n(_w<=\\n($l)&(\\n(?W=0) \ ++\{\ ++. nr _b (\\n(ppp*\\n($vu)/200u \" compute fudge factor (must be < 1P) ++. if \\n(_bu>((\\n(bmu-\\n(fmu-((\\n(tpp*\\n($vu)/100u))/2u) \ ++. nr _b (\\n(ppp*\\n($vu)/100u-\n(.Vu ++. nr _b +\\n(bmu ++.\} ++.nr _B \\n(_bu ++.ch @f ++.wh -\\n(_bu @f ++.nr _b +(\\n(ppp*\\n($vu)/100u \" add 1 paragraph v in case of sweep past ++.if \n@>2 .tm @n .p=\\n(.p bm=\\n(bm _b=\\n(_b _B=\\n(_B ++.nr ?f 0 \" reset footnote flag ++.if \\n(?o \ ++\{\ ++. (f _\" \" reprocess footnotes which run off page ++. nf ++. |o ++. fi ++. )f ++. rm |o ++.\} ++.nr ?o 0 ++.if \\n(?T \ ++\{\ ++. nr _i \\n(.i ++. if \\n(?n \ ++. nm \\n(ln ++. in 0 ++. |h\" \" output the table header ++. in \\n(_iu ++. if \\n(?n \ ++. nm ++. rr _i ++. mk #T \" for tbl commands ++. ns ++.\} ++.if (\\n(?a)&((\\n($c<2):(\\n(?w=0)) \ ++\{\ ++. nr ?a 0 \" output floating keep ++. @k |t ++. if \\n(?w \ ++. mk _k \" don't overstrike wide keeps ++. nr ?w 0 ++.\} ++.os ++.$H\" \" special column header macro ++.ns ++.. ++. ++.de @f \" --- footer ++.if \n@>1 .tm >> @f %=\\n% nl=\\n(nl ?a=\\n(?a ?b=\\n(?b ?f=\\n(?f ++.if \n@>2 .nr VL \\n(.pu-\\n(nlu ++.if \n@>2 .tm @f bm=\\n(bm _B=\\n(_B _b=\\n(_b .p-nl=\\n(VL ++.ec ++.if \\n(?T \ ++\{\ ++. nr T. 1 \" for tbl commands (to output bottom line) ++. T# 1\" \" output the sides and bottom lines ++. br ++.\} ++.ev 2 ++.ce 0 ++.if \\n(?b \ ++\{\ ++. nr ?b 0 ++. @k |b\" \" output bottom of page tables ++.\} ++.if \\n(?f \ ++. @o\" \" output footnote if present ++.ie \\n($c<\\n($m \ ++. @c\" \" handle new column ++.el \ ++. @e\" \" new page ++.ev ++.if \n@>2 .tm << @f ++.. ++. ++.de @o \" --- output footnote ++.nf ++.ls 1 ++.in 0 ++.if \n@>2 .tm @o last printed text = \\n(nl placing @r trap at -\\n(_B ++.wh -\\n(_Bu @r ++.if \\n(?n \ ++. nm \\n(ln ++.|f ++.if \\n(?n \ ++. nm ++.fi ++.if \n@>2 .tm @o triggered @r (?o) = \\n(?o ++.if \\n(?o \ ++\{\ ++. di \" just in case triggered @r ++. if \\n(dn=0 \ ++\{\ ++. rm |o ++. nr ?o 0 ++. \} ++. nr dn \\n(_D ++. rr _D ++.\} ++.rm |f ++.ch @r ++.. ++. ++.de @c \" --- new column ++.if \n@>2 .tm >> @c %=\\n% ++.rs ++.sp |\\n(_ku ++.@O +\\n($lu+\\n($su ++.nr $c +1 ++.@n ++.. ++. ++.de @e \" --- end page ++.if \n@>2 .tm >> @e ++.@O \\n(_ou ++.rs ++.sp |\\n(.pu-\\n(fmu-((\\n(tpp*\\n($vu)/100u) \" move to footer position ++.@t $f\" \" output footer title ++.nr ?h 0 ++.bp ++.. ++. ++.de @t \" --- output header or footer title ++.if !\\n(?h \ ++\{\ ++. sz \\n(tp\" \" set header/footer type fonts, etc. ++. @F \\n(tf ++. lt \\n(_Lu \" make title span entire page ++. if \\n(?n \ ++. nm \\n(ln ++. nf ++. \\$1 ++. br ++. if \\n(?n \ ++. nm ++.\} ++.. ++. ++.de $h \" $$$ print header ++.ds |z ++.if !\\n(?c \ ++\{\ ++. if e .ds |z "\\*(|0 ++. if o .ds |z "\\*(|1 ++.\} ++.if !\(ts\\*(|z\(ts\(ts \ ++' tl \\*(|z ++.rm |z ++.. ++. ++.de $f \" $$$ print footer ++.ds |z ++.if \\n(?c \ ++\{\ ++. if e .ds |z "\\*(|0 ++. if o .ds |z "\\*(|1 ++.\} ++.if \(ts\\*(|z\(ts\(ts \ ++\{\ ++. if e .ds |z "\\*(|2 ++. if o .ds |z "\\*(|3 ++.\} ++.if !\(ts\\*(|z\(ts\(ts \ ++' tl \\*(|z ++.rm |z ++.. ++. ++.de @r \" --- reprocess overflow footnotes ++.if \n@>3 .tm >> @r .z=\\n(.z ?f=\\n(?f ?a=\\n(?a ?b=\\n(?b _b=\\n(_b ++.di |o \" save overflow footnote ++.nr ?o 1 ++.nr _D \\n(dn ++.ns ++.. ++. ++. ++.\" *** COMMANDS WITH VARIANT DEFINITIONS *** ++. ++. ++.if !'\*(.T'html' .rn bp @b \" --- begin page ++. ++.de bp \" *** begin new page (overrides columns) ++.nr $c \\n($m \" force new page, not new column ++.ie \\n(nl>0 \ ++. @b \\$1 ++.el \ ++\{\ ++. if \\n(.$>0 \ ++. pn \\$1 ++. if \\n(?I \ ++. @h\" \" 'spring' the header trap ++.\} ++.br ++.wh 0 @h \" reset header ++.. ++. ++.rn ll xl \" *** special line length (local) ++.de ll \" *** line length (global to environments) ++.xl \\$1 ++.lt \\$1 ++.nr $l \\n(.l ++.if (\\n($m<=1):(\\n($l>\\n(_L) \ ++. nr _L \\n(.l ++.. ++. ++.rn po @O \" --- local page offset ++. ++.de po \" *** page offset ++.@O \\$1 ++.nr _o \\n(.o ++.. ++. ++.\" Redefine the fam request to set the family in ++.\" environment 2 as well as the current environment. ++.if !\n(.g .ig ++.do rn fam @fam \" --- set family in current environment ++.do de fam \" *** set font family in ev 2 and current ev ++.do @fam \\$1 ++.ev 2 ++.do @fam \\$1 ++.ev ++.. ++. ++. ++.\" *** MISCELLANEOUS ROFF COMMANDS *** ++. ++. ++.de hx \" *** suppress headers and footers next page ++.nr ?H 1 ++.. ++. ++.de ix \" *** indent, no break ++'in \\$1 ++.. ++. ++.de bl \" *** contiguous blank lines ++.br ++.@s \\$1 ++.sp \\$1 ++.. ++. ++.de @s \" --- diversion-surviving space test ++.ne \\$1 ++.rs ++.if !'\\n(.z'' \!.@s \\$1 ++.. ++. ++.de n1 \" *** line numbering 1 ++.nm 1 ++.ll -\w'0000'u ++.nr ?n 1 ++.. ++. ++.de n2 \" *** line numbering 2 ++.ie \\n(.$ \ ++\{\ ++. ie !`\\$2`c` \ ++. po -\w'0000'u ++. el \ ++. ll -\w'0000'u ++. ie \\B`\\$1` \ ++\{\ ++. ds |i \\$1 ++. ds |j \\$1 ++. do substring |i 0 0 \" pick off leading char and rest to check ++. do substring |j 1 \" for +N / -N ++. ie `\\*(|i`+` \ ++. nr ln (\\n[_ln])+\\*(|j ++. el \ ++. ie `\\*(|i`-` \ ++. nr ln (\\n[_ln])-\\*(|j ++. el \ ++. nr ln \\$1 \" unsigned N ++. nm \\n(ln ++. nr ?n 2 ++. rm |i |j ++.\} ++. el \ ++. tm Line \\n(.c -- Bad .n2 value ++.\} ++.el \ ++\{\ ++. nm ++. nr _ln \\n(ln ++. po +\w'0000'u ++. ll \\n($lu ++. nr ?n 0 ++. nr ln 0 ++.\} ++.. ++. ++.de pa \" *** new page ++.bp \\$1 ++.. ++. ++.de ro \" *** roman page numbers ++.af % i ++.. ++. ++.de ar \" *** arabic page numbers ++.af % 1 ++.. ++. ++.de m1 \" *** position one space ++.nr _0 \\n(hmu ++.nr hm \\$1v ++.nr tm +\\n(hmu-\\n(_0u ++.rr _0 ++.. ++. ++.de m2 \" *** position two space ++.nr tm \\n(hmu+\\n(tpp+\\$1v ++.. ++. ++.de m3 \" *** position three space ++.nr bm \\n(fmu+\\n(tpp+\\$1v ++.. ++. ++.de m4 \" *** position four space ++.nr _0 \\n(fmu ++.nr fm \\$1v ++.nr bm +\\n(fmu-\\n(_0u ++.. ++. ++.de sk \" *** leave a blank page (next page) ++.if \\n(.$>0 \ ++. tm Line \\n(c. -- I cannot skip multiple pages ++.nr ?s 1 ++.. ++. ++. ++.\" *** MISCELLANEOUS USER SUPPORT COMMANDS *** ++. ++. ++.if !\n(.g .ig ++.de re \" *** reset tabs (TROFF defines 15 stops default) ++.ta T 0.5i ++.. ++. ++.if \n(.g .ig ++.de re ++.ta 0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i +0.5i ++.. ++. ++.de ba \" *** set base indent ++.ie \\n(.$ \ ++. nr $i \\$1n ++.el \ ++. nr $i \\n(siu*\\n($0u ++.. ++. ++.de hl \" *** draw horizontal line ++.br ++.if '\*(.T'html' \ ++\{\ ++. HR ++. do return ++.\} ++.ie \n(.g .do nr _I \\n[.in] ++.el .nr _I \\n(.i ++\l'\\n(.lu-\\n(_Iu' ++.sp ++.. ++. ++. ++.\" *** PARAGRAPHING *** ++. ++. ++.de pp \" *** paragraph ++.lp \\n(piu ++.. ++. ++.de lp \" *** left aligned paragraph ++.@p ++.if \\n(.$ \ ++. ti +\\$1 ++.nr $p 0 1 ++.. ++. ++.de ip \" *** indented paragraph w/ optional tag ++.if (\\n(ii>0)&(\\n(ii<1n) \ ++. nr ii \\n(iin ++.nr _0 \\n(ii ++.if \\n(.$>1 \ ++. nr _0 \\$2n ++.@p \\n(_0u ++.nr _I \\n(.iu ++.in 0 ++.di |i ++\&\\$1 ++.br ++.di ++.in \\n(_Iu ++.ds |j \\*(|i\\ ++.ie \\w"\\*(|j" \ ++\{\ ++. ti -\\n(_0u ++. ie \\w"\\*(|j">=\\n(_0 \ ++\{\ ++. do DEVTAG-COL 1 ++\\*(|j ++. do DEVTAG-COL-NEXT 2 ++. br ++. \} ++. el \ ++\{\ ++. do DEVTAG-COL 1 ++\\*(|j\h'|\\n(_0u'\c ++. do DEVTAG-COL 2 ++. \} ++.\} ++.el .do DEVTAG-COL 2 ++.rr _0 ++.rm |i |j ++.. ++. ++.de np \" *** numbered paragraph ++.\" use string comparison in case user has changed format of $p ++.if '\\n($p'-1' \ ++. nr $p 0 \" reset number after .bu ++.nr $p +1 \" increment paragraph number ++.@p \w'\0(000)\0'u ++.ti -\w'\0(000)\0'u ++\0(\\n($p)\h'|\w'\0(000)\0'u'\c ++.. ++. ++.de bu \" *** bulleted paragraph ++.br ++.\" use string comparison in case user has changed format of $p ++.if '\\n($p'-1' \ ++. ns \" don't space between .bu paragraphs ++.nr $p 0-1 \" mark "bulleted paragraph" mode ++.@p \w'\0\(bu\0'u ++.ti -\w'\0\(bu\0'u ++\0\(bu\0\c ++.. ++. ++.de @p \" --- initialize for paragraph ++.do check_need_title ++.if "\\n(.z"|e" .tm Line \\n(c. -- Unmatched continued equation ++.in \\n($iu+\\n(pou ++.if \\n(.$ \ ++. in +\\$1n ++.ce 0 ++.fi ++.@F \\n(pf ++.sz \\n(pp ++.sp \\n(psu ++.ne \\n(.Lv+\\n(.Vu ++.ns ++.. ++. ++. ++.\" *** SECTION HEADINGS *** ++. ++. ++.de sh \" *** section heading ++.fi ++.do check_need_title ++.if (\\n(si>0)&(\\n(si<1n) \ ++. nr si \\n(sin ++.if '\*(.T'html' .nr si 0 ++.ce 0 ++.if '\*(.T'html' \ ++\{\ ++. do DEVTAG-SH \\$1 ++. do nr need_eo_h 1 ++.\} ++.@d "\\$1" +1 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 ++.if !"\\$2"_" \ ++\{\ ++. ds |n \&\\$2 ++. $p "\\*(|n" "\\*($n" \\n($0 ++. $0 "\\*(|n" "\\*($n" \\n($0 ++. rm |n ++.\} ++.nr $p 0 1 \" reset .np count ++.. ++. ++.de @d \" --- change section depth ++.if !""\\$1" \ ++. nr $0 \\$1 ++.if \\n($0&(\\n(.$>1) \ ++. nr $\\n($0 \\$2 ++.ds $n \&\" ++.ie \\n($0>=1 \ ++\{\ ++. if '\\n($1'0' \ ++. nr $1 1 ++. if (\\n(.$>=3) .if !"\\$3"-" \ ++. nr $1 \\$3 ++. as $n \\n($1 ++.\} ++.el \ ++. nr $1 0 ++.ie \\n($0>=2 \ ++\{\ ++. if '\\n($2'0' \ ++. nr $2 1 ++. if (\\n(.$>=4) .if !"\\$4"-" \ ++. nr $2 \\$4 ++. as $n .\\n($2 ++.\} ++.el \ ++. nr $2 0 ++.ie \\n($0>=3 \ ++\{\ ++. if '\\n($3'0' \ ++. nr $3 1 ++. if (\\n(.$>=5) .if !"\\$5"-" \ ++. nr $3 \\$5 ++. as $n .\\n($3 ++.\} ++.el \ ++. nr $3 0 ++.ie \\n($0>=4 \ ++\{\ ++. if '\\n($4'0' \ ++. nr $4 1 ++. if (\\n(.$>=6) .if !"\\$6"-" \ ++. nr $4 \\$6 ++. as $n .\\n($4 ++.\} ++.el \ ++. nr $4 0 ++.ie \\n($0>=5 \ ++\{\ ++. if '\\n($5'0' \ ++. nr $5 1 ++. if (\\n(.$>=7) .if !"\\$7"-" \ ++. nr $5 \\$7 ++. as $n .\\n($5 ++.\} ++.el \ ++. nr $5 0 ++.ie \\n($0>=6 \ ++\{\ ++. if '\\n($6'0' \ ++. nr $6 1 ++. if (\\n(.$>=8) .if !"\\$8"-" \ ++. nr $6 \\$8 ++. as $n .\\n($6 ++.\} ++.el \ ++. nr $6 0 ++.. ++. ++.de sx \" *** heading up, no increment (2.1.1 -> 2.1) ++.ce 0 ++.ul 0 ++.nr _0 \\n($0-1 ++.if \\n(.$ .nr _0 +1 ++.if \\n(.$ .nr _0 \\$1 ++.@d \\n(_0 ++.rr _0 ++.$p "" "" \\n($0 ++.nr $p 0 1 \" reset .np count ++.. ++. ++.de uh \" *** unnumbered section heading ++.$p "\\$1" ++.$0 "\\$1" ++.. ++. ++.de $p \" $$$ print section heading ++.if (\\n(si>0)&(\\n(.$>2) \ ++. nr $i \\$3*\\n(si ++.in \\n($iu ++.ie !"\\$1\\$2"" \ ++\{\ ++. sp \\n(ssu \" one of them is non-null ++. ne \\n(.Lv+\\n(.Vu+\\n(psu+((\\n(spp*\\n($vu*\\n(.Lu)/100u) ++. \" exdent if \\$3 > 0 ++. ie 0\\$3 \ ++. ti -(\\n(siu-\\n(sou) ++. el \ ++. ti +\\n(sou ++. @F \\n(sf ++. sz \\n(sp ++. if 0\\$3 \ ++. $\\$3 ++. if \w"\\$2">0 \\$2. ++. if \w"\\$1">0 \\$1\f1\ \ \& ++.\} ++.el \ ++. sp \\n(psu ++.@F \\n(pf ++.sz \\n(pp ++.. ++. ++. ++.\" *** COLUMNED OUTPUT *** ++. ++. ++.de 2c \" *** double columned output ++.br ++.if \\n($m>1 \ ++. 1c\" \" revert to 1c if already 2c ++.nr $c 1 ++.nr $m 2 ++.if \\n(.$>1 \ ++. nr $m \\$2 ++.if \\n(.$>0 \ ++. nr $s \\$1n \" param 1: column separation ++.nr $l (\\n(.l-((\\n($m-1)*\\n($s))/\\n($m ++.xl \\n($lu ++.mk _k ++.ns ++.. ++. ++.de 1c \" *** single columned output ++.br ++.nr $c 1 ++.nr $m 1 ++.ll \\n(_Lu \" return to normal output ++.sp |\\n(.hu ++.@O \\n(_ou ++.. ++. ++.de bc \" *** begin column ++.sp 24i ++.. ++. ++. ++.\" *** FLOATING TABLES AND NONFLOATING BLOCKS *** ++. ++. ++.de (z \" *** begin floating keep ++.if \n@>4 .tm >> (z, .z=\n(.z ++.@D 4 \\$1 \\$2 ++.@( ++.. ++. ++.de )z \" *** end floating keep ++.if \n@>4 .tm >> )z, .z=\n(.z ++.sp \\n(zsu ++.@) ++.if \n@>4 .tm -- )z << @), .z=\n(.z ++.rr _0 ++.if !\\n(?b \ ++. nr dn +(\\n(ppp*\\n($vu)/200u+\\n(zsu ++.nr dl -\n(.H \" fudge factor necessary to make it work ++.ie ((\\n(dn+\n(.V)>=\\n(.t):(\\n(?a):((\\n(dl>\\n($l)&(\\n($c>1)) \ ++\{\ ++. nr ?a 1 ++. if (\\n(dl>\\n($l)&(\\n($m>1) \ ++. nr ?w 1 \" mark wider than one column (top) ++. ds |x |t ++.\} ++.el \ ++\{\ ++. nr ?b 1 ++. if (\\n(dl>\\n($l)&(\\n($m>1) \ ++. nr ?W 1 \" mark wider than one column (bottom) ++. nr _b +\\n(dnu ++. \" avoid moving @f back past the current position ++. if \\n(.p-\\n(nl-\n(.V<\\n(_b \ ++. nr _b \\n(.p-\\n(nl-\n(.V ++. ch @f -\\n(_bu ++. ds |x |b ++.\} ++.da \\*(|x \" copy to save macro ++.nf ++.ls 1 ++.nr ?k 1 ++.if \n@>4 .tm -- )z >> \\*(|x ++\!.if \\\\n(nl>(\\\\n(tm+2v) .ne \\n(dnu-\\n(zsu ++.|k\" \" and the body ++.ec ++.if \n@>4 .tm -- )z << \\*(|x, .z=\\n(.z ++.nr ?k 0 ++.rm |k\" \" remove the temp macro ++.da ++.in 0 ++.ls 1 ++.xl \\n($lu ++.ev ++.if \n@>4 .tm << )z, .z=\\n(.z ++.. ++. ++.de @k \" --- output floating keep ++.if \n@>4 .tm >> @k, $1=\\$1, .z=\\n(.z ++.ev 1 ++.nf ++.ls 1 ++.in 0 ++.sp \\n(zsu ++.if \\n(?n \ ++. nm \\n(ln ++.\\$1 ++.if \\n(?n \ ++. nm ++.ec ++.br ++.rm \\$1 ++.ev ++.. ++. ++.de (t \" XXX temp ref to (z ++.(z \\$1 \\$2 ++.. ++. ++.de )t \" XXX temp ref to )t ++.)z \\$1 \\$2 ++.. ++. ++.de (b \" *** begin block ++.br ++.@D 3 \\$1 \\$2 ++.sp \\n(bsu ++.@( ++.if '\*(.T'html' .sp \\n(bsu ++.. ++. ++.de )b \" *** end block ++.br ++.@) ++.if (\\n(bt=0):(\\n(.t<\\n(bt) \ ++. ne \\n(dnu \" make it all on one page ++.@k |k ++.ev \" return from display environment ++.sp \\n(bsu+\\n(.Lv-1v ++.. ++. ++.de @( \" --- begin keep ++.if !"\\n(.z"" .tm Line \\n(c. -- Invalid nested keep \\n(.z ++.@M ++.di |k ++\!'rs ++.. ++. ++.de @M \" --- set modes for display ++.nr ?k 1 ++.@C 1 ++.@F \\n(df ++.if \\n($R .@V ++.vs \\n(.sp*\\n($Vu/100u ++.nf ++.if "\\*(|p"F" \ ++. fi \" set fill mode if "F" parameter ++.if \\n(_d=4 \ ++. in 0 ++.if \\n(_d=3 \ ++\{\ ++. in +\\n(biu ++. xl -\\n(biu ++.\} ++.if \\n(_d=1 \ ++. ce 10000 ++.. ++. ++.de @) \" --- end keep ++.br ++.if !"\\n(.z"|k" .tm Line \\n(c. -- Close of a keep which has never been opened ++.nr ?k 0 ++.di ++.in 0 ++.ce 0 ++.. ++. ++.de (c \" *** begin block centered text ++.br ++.if "\\n(.z"|c" .tm Line \\n(c. -- Nested .(c requests ++.if \\n(?n .nm ++.di |c ++.. ++. ++.de )c \" *** end block centered text ++.if !"\\n(.z"|c" .tm Line \\n(c. -- Unmatched .)c ++.br \" force out final line ++.di ++.if \n@>4 .tm >> .)c .l=\\n(.l .i=\\n(.i $i=\\n($i dl=\\n(dl ++.ev 1 ++.ls 1 ++.in (\\n(.lu-\\n(.iu-\\n(dlu)/2u ++.if \n@>4 .tm -- .)c << .in .l=\\n(.l .i=\\n(.i dl=\\n(dl ++.if \\n(?n \ ++. nm \\n(ln ++.nf ++.|c ++.ec ++.in ++.ls ++.if \\n(?n \ ++. nm ++.ev ++.rm |c ++.. ++. ++. ++.\" *** BLOCK QUOTES (OR WHATEVER) AND LISTS *** ++. ++. ++.de (q \" *** begin block quote ++.br ++.@C 1 ++.fi ++.sp \\n(qsu ++.in +\\n(qiu ++.xl -\\n(qiu ++.sz \\n(qp ++.if \\n(?n \ ++. nm \\n(ln ++.. ++. ++.de )q \" *** end block quote ++.br ++.if \\n(?n \ ++. nm ++.ev ++.sp \\n(qsu+\\n(.Lv-1v ++.nr ?k 0 ++.. ++. ++.de (l \" *** begin list ++.br ++.sp \\n(bsu ++.@D 3 \\$1 \\$2 ++.@M ++.if \\n(?n \ ++. nm \\n(ln ++.if '\*(.T'html' .sp \\n(bsu ++.. ++. ++.de )l \" *** end list ++.br ++.if \\n(?n \ ++. nm ++.ev ++.sp \\n(bsu+\\n(.Lv-1v ++.nr ?k 0 ++.. ++. ++. ++.\" *** PREPROCESSOR SUPPORT *** ++. ++. ++.\" ++.\" EQN ++.\" ++.de EQ \" *** equation start ++.do if \\n[need_eo_h]>0 .do DEVTAG-EO-H ++.do nr need_eo_h 0 ++.ec ++.if "\*(.T"html" \ ++\{\ ++. do nr e-EQ-ll \\n(.l ++. ll 1000n ++.\} ++.do HTML-IMAGE ++.if !\\n(?e \ ++\{\ ++. if "\\n(.z"|e" .tm Line \\n(c. -- Nested .EQ request ++. @D 1 "\\$1" "\\$2" ++. @C 2 ++. di |e ++.\} ++.ls 1 ++.in 0 ++.nf ++.. ++. ++.de EN \" *** equation end ++.br ++.do HTML-IMAGE-END ++.if "\*(.T"html" \ ++. do ll \\n[e-EQ-ll]u ++.ie "\\$1"C" \ ++\{\ ++. nr ?e 1 ++. sp \\n(esu ++.\} ++.el \ ++\{\ ++. nr ?e 0 ++. di ++. if \\n(dn \ ++. @q\" \" actual equation output ++. rm |e ++. ev ++.\} ++.. ++. ++.de @q \" --- equation output ++.nr _Q \\n(dnu ++.ev ++.sp \\n(esu \" output rest of preceding text ++.if !"\\n(.z"" \!.ne \\n(_Qu ++.ne \\n(_Qu+\n(.Vu \" keep it on one page ++.@C 2\" \" .ev 2 may be jumbled from header ++.if \\n(_d=1 \ ++. in (\\n(.lu+\\n($iu-\\n(dlu)/2u ++.if \\n(_d=2 \ ++. in \\n($iu ++.if \\n(_d=3 \ ++. in \\n(biu+\\n($iu ++.if \\n(_d=4 \ ++. in 0 ++.mk _q ++.if \n@>1 .tm --@e: _Q=\\n(_Q _q=\\n(_q nl=\\n(nl |p=\\*(|p ++.if !"\\*(|p"" \ ++\{\ ++. rs ++. sp (\\n(_Qu-\\n(.vu)/2u ++. tl """\\*(|p" ++. rt \\n(_qu ++.\} ++.if \\n(?n \ ++. nm \\n(ln ++.|e ++.if \\n(?n \ ++. nm ++.sp |\\n(_qu+\\n(_Qu ++.sp \\n(esu+\\n(.Lv-1v ++.rr _q ++.rr _Q ++.. ++. ++.\" ++.\" TBL ++.\" ++.de TS \" *** table start ++.sp \\n(bsu ++.if "\*(.T"html" \ ++\{\ ++. do nr e-TS-ll \\n(.l ++. ll 1000n ++.\} ++.do HTML-IMAGE ++.@C 1 ++.fi \" drop into fill mode for text boxes ++.if "\\$1"H" \ ++\{\ ++. di |h \" save header part ++. nr ?T 1 ++.\} ++.ls 1 ++.ch @f -(\\n(_bu+1v) \" set pseudo-trap for bottom line ++.if \\n(.p-\\n(_b-1v<=\\n(nl \ ++. ch @f \\n(nlu+\n(.Vu ++.. ++. ++.de TH \" *** end header part of table ++.nr T. 0 ++.T# 0 ++.if \\n(?n \!.nm ++.di ++.nr _T \\n(?T ++.nr ?T 0 ++.ne \\n(dnu+1v ++.nr ?T \\n(_T ++.nr _i \\n(.i ++.if \\n(?n .nm \\n(ln ++.in 0 ++.|h\" \" put in the initial header ++.in \\n(_iu ++.rr _i ++.mk #T ++.. ++. ++.de TE \" *** table end ++.nr ?T 0 ++.ch @f -\\n(_bu \" reset pseudo-trap ++.if \\n(.p-\\n(_b<=\\n(nl \ ++. ch @f \\n(nlu+\n(.Vu ++.ev ++.do HTML-IMAGE-END ++.if "\*(.T"html" \ ++. do ll \\n[e-TS-ll]u ++.sp \\n(bsu+\\n(.Lv-1v ++.re ++.. ++. ++.de T& ++.. ++. ++.\" ++.\" REFER ++.\" ++.mso refer-me.tmac ++. ++.\" ++.\" IDEAL ++.\" ++.de IS \" *** start ideal picture ++.nr g7 \\n(.u ++.ls 1 ++.. ++. ++.de IF ++.if \\n(g7 .fi ++.ls ++.. ++. ++.de IE \" *** end ideal picture ++.if \\n(g7 .fi ++.ls ++.. ++. ++.\" ++.\" PIC ++.\" ++.de PS \" *** start picture: $1=height, $2=width in units or inches ++.sp 0.3 ++.do HTML-IMAGE ++.nr g7 \\$2 ++.in (u;\\n(.l-\\n(g7>?0/2) ++.ne \\$1u ++.nr g7 \\n(.u ++.ls 1 ++.if \\n(?n \ ++\{\ ++. de PS_nm_check && \" define macro to emit .nm at top diversion ++. if \n@>4 .tm -- PS: \\\\$1 \\\\$2 .z=\\\\n(.z PS_nm_cnt=\\\\n[PS_nm_cnt] ++. \" \" multiple .PS/.PE in a keep. ++. if `\\\\$2`init` \ ++. do nr PS_nm_cnt \\\\n[PS_nm_cnt]+1 ++. ie `\\\\n(.z`` \ ++\{\ ++. if `\\\\$1`suspend` \ ++. nm ++. if `\\\\$1`resume` \ ++\{\ ++. nm \\\\n(ln ++. do nr PS_nm_cnt \\\\n[PS_nm_cnt]-1 ++. do if !\\\\n[PS_nm_cnt] \ ++\{\ ++. do rm PS_nm_check ++. do rr PS_nm_cnt ++.\} ++.\} ++.\} ++.el \!.PS_nm_check \\\\$1 ++.&& ++. mk _q \" emit a single numbered line for PS picture ++. rs ++\&\ ++. br ++. rt \\n(_qu ++. PS_nm_check suspend init ++.\} ++.. ++. ++.de PE \" *** end picture ++.if \\n(?n .PS_nm_check resume ++.ls ++.in ++.if \\n(g7 .fi ++.do HTML-IMAGE-END ++.sp .6 ++.. ++. ++.\" ++.\" GREMLIN ++.\" ++.de GS \" *** start gremlin picture ++.ie '\*(.T'html' \ ++\{\ ++. ie "\\$1"L" .do HTML-IMAGE-LEFT ++. el .ie "\\$1"R" .do HTML-IMAGE-RIGHT ++. el .do HTML-IMAGE ++.\} ++.el \ ++\{\ ++. nr g7 (\\n(.lu-\\n(g1u)/2u ++. if "\\$1"L" .nr g7 \\n(.iu ++. if "\\$1"R" .nr g7 \\n(.lu-\\n(g1u ++. in \\n(g7u ++. nr g7 \\n(.u ++. ls 1 ++. nf ++. ne \\n(g2u ++.\} ++.. ++. ++.de GE \" *** end gremlin picture ++.ie '\*(.T'html' .do HTML-IMAGE-END ++.el \ ++\{\ ++. GF ++. sp .6 ++.\} ++.. ++. ++.de GF \" *** finish gremlin picture; stay at top ++.ls ++.in ++.if \\n(g7 .fi ++.. ++. ++. ++.\" *** FONT AIDS *** ++. ++. ++.de sz \" *** set point size and vertical spacing ++.ps \\$1 ++.if \\n($r .@v ++.vs \\n(.sp*\\n($vu/100u \" default vs at pointsize + 20% ++.. ++. ++.de @v \" --- possibly set $v from $r ++.if (1i>=240u)&(1p<=\\n($r)&(\\n($r<=4p) .nr $v \\n($r00/1p ++.. ++. ++.de @V \" --- possibly set $V from $R ++.if (1i>=240u)&(1p<=\\n($R)&(\\n($R<=4p) .nr $V \\n($R00/1p ++.. ++. ++.de @E \" --- store in _F argument to \f for restoring font ++.ie \\n(.f<10 \ ++. ds _F \\n(.f ++.el \ ++\{\ ++. ie \\n(.f<100&\n(.g \ ++. ds _F (\\n(.f ++. el \ ++. ds _F P ++.\} ++.. ++. ++.de r \" *** enter roman font ++.do check_need_title ++.@E ++.ft 1 ++.if \\n(.$ \&\\$1\f\\*(_F\\$2 ++.do check_need_title ++.. ++. ++.de i \" *** enter italic ++.do check_need_title ++.@E ++.ft 2 ++.if \\n(.$ \&\\$1\f\\*(_F\\$2 ++.do check_need_title ++.. ++. ++.de b \" *** enter boldface ++.do check_need_title ++.@E ++.ft 3 ++.if \\n(.$ \&\\$1\f\\*(_F\\$2 ++.do check_need_title ++.. ++. ++.de rb \" *** enter real boldface ++.do check_need_title ++.@E ++.ft 3 ++.if \\n(.$ \&\\$1\f\\*(_F\\$2 ++.do check_need_title ++.. ++. ++.de bi \" *** enter bold italic ++.do check_need_title ++.@E ++.ft 4 ++.if \\n(.$ \&\\$1\f\\*(_F\\$2 ++.do check_need_title ++.. ++. ++.de u \" *** enter underlined word ++\&\\$1\l'|0\(ul'\\$2 ++.. ++. ++.\" a better version of u ++.if !\n(.g .ig ++.de u ++\Z'\\$1'\v'.25m'\D'l \w'\\$1'u 0'\v'-.25m'\\$2 ++.. ++. ++.de q \" *** enter quoted word ++\&\\*(lq\\$1\\*(rq\\$2 ++.. ++. ++.de bx \" *** enter boxed word ++.ie '\*(.T'html' \\$1\\$2 ++.el \k~\(br\|\\$1\|\(br\l'|\\n~u\(rn'\l'|\\n~u\(ul'\^\\$2 ++.. ++. ++.de sm \" *** print in smaller font ++\s-1\\$1\\s0\\$2 ++.. ++. ++.de @F \" --- change font (0 -> no change) ++.nr ~ \\$1 ++.if \\n~>0 \ ++. ft \\n~ ++.rr ~ ++.. ++. ++. ++.\" *** FOOTNOTING *** ++. ++. ++.de (f \" *** begin footnote ++.ec ++.if "\\n(.z"|f" .tm Line \\n(c. -- Invalid footnote nesting ++.ie "\\n(.z"" \ ++\{\ ++. nr _D \\n(dn ++. nr _0 1v+\\n(nlu ++. ev 2 ++. nm ++. da |f ++. in 0 ++. xl \\n($lu-\\n(fuu ++. @F \\n(ff ++. sz \\n(fp ++. vs \\n(.sp*\\n($Vu/100u ++. if !\\n(?f \ ++\{\ ++. nr _b +1v \" allow space for $s ++. $s ++. \} ++. br ++. if \\n(.p-\\n(_b-\\n(_0-\\n(.h-1v-\\n(fs<0 \ ++\{\ ++. da\" \" won't fit on page at all ++. bc ++. if !\\n(?f \ ++. rm |f ++. da |f ++.\" next five lines could be dropped if headers had their own environment ++. in 0 \" reset everything from .bc ++. xl \\n($lu-\\n(fuu ++. @F \\n(ff ++. sz \\n(fp ++. vs \\n(.sp*\\n($Vu/100u ++. if !\\n(?f \ ++. $s ++. br ++. \} ++. rr _0 ++. sp \\n(fsu ++. nr ?f 1 ++. fi ++. if !"\\$1"_" \ ++. ti \\n(fiu ++. if \n@>2 .tm << (f $f=\\n($f ++.\} ++.el \ ++\{\ ++. ev 2 ++. nm ++. in 0 ++. xl \\n($lu-\\n(fuu ++. @F \\n(ff ++. sz \\n(fp ++. vs \\n(.sp*\\n($Vu/100u ++. fi ++\!.(f \\$1 ++\!.@N ++.\} ++.. ++. ++.de @N \" --- set no fill mode in the top-level diversion ++.ie "\\n(.z"" .nf ++.el \!.@N ++.. ++. ++.de )f \" *** end footnote ++.ie "\\n(.z"|f" \ ++\{\ ++. if \\n* \ ++. nr $f +1 ++. ds * \\*{\\n($f\\*}\k* ++. nr * 0 ++. in 0 ++. da ++. ev ++. if \\n(_w<\\n(dl \ ++. nr _w \\n(dl \" compute maximum fn width ++. nr _b +\\n(dn ++. ch @f -\\n(_bu ++. if \\n(.p-\\n(_b<=\\n(nl \ ++. ch @f \\n(nlu+\n(.Vu ++. nr dn \\n(_D ++. rr _D ++.\} ++.el \ ++\{\ ++. br ++\!.)f ++. ev ++.\} ++.. ++. ++.@R ff ++.if \n(ff<=0 \ ++. nr ff 1 \" footnote font: Times Roman ++.@R fp ++.if \n(fp<=0 \ ++. nr fp 8 \" footnote pointsize ++. ++.de $s \" $$$ footnote separator ++\l'2i' ++.. ++. ++. ++.\" *** DELAYED TEXT *** ++. ++. ++.de (d \" *** begin delayed text ++.am |d )d ++.sp \\n(bsu ++.. ++. ++.de )d \" *** end delayed text ++.if \\n# \ ++. nr $d +1 ++.ds # [\\n($d]\k# ++.rr # ++.. ++. ++.de pd \" *** print delayed text ++.|d ++.rm |d ++.nr $d 1 1 ++.ds # [1]\k# ++.. ++. ++. ++.\" *** INDEXES (TABLE OF CONTENTS) *** ++. ++. ++.nr _x 0 1 ++.do nr _xn 0 ++.af _x a ++. ++.de (x \" *** begin index entry ++.if \n@>4 .tm >> (x, .z=\\n(.z ++.ds |X x ++.if \\n(.$>0 \ ++. ds |X \\$1 ++.ie "\\n(.z"" \ ++. nr _z 0 ++.el \ ++. nr _z 1 ++.@\\n(_z ++.. ++. ++.de @0 \" --- finish (x if no current diversion ++.am %\\*(|X )x ++.sp \\n(xsu ++.ti -\\n(piu ++.. ++. ++.de @1 \" --- finish (x if current diversion ++.if "\\n(_x"z" .nr _x 0 ++.de =\\n+(_x )x ++.. ++. ++.de )x \" *** end index entry ++.if \n@>4 .tm >> )x, .z=\\n(.z ++.ie "\\n(.z"" \ ++\{\ ++. ds |x \\n% ++. if \\n(.$>0 \ ++. ds |x \\$1 ++. if "\\*(|x"_" \ ++. ig .. ++. am %\\*(|X .. ++. if \w"\\$2">(\\n(.l-\\n(.i-\\n(.k) \ ++. ti +\\n(xuu ++\\\\a\\\\t\\$2\\*(|x ++... ++. rm |x ++. rm |X ++.\} ++.el \ ++\{\ ++\!.(x \\*(|X ++\!\\\\*(=\\n(_x\\\\ ++\!.)x \\$1 \\$2 ++\!.rm =\\n(_x ++.\} ++.. ++. ++.de xp \" *** print the index ++.br ++.@C 2 ++.ls 1 ++.vs \\n(.sp*\\n($Vu/100u ++.fi ++.in +\\n(piu ++.ds |X x ++.if \\n(.$>0 \ ++. ds |X \\$1 ++.xl -(\\n(xuu+\w'...'u) ++.di |x ++.%\\*(|X ++.br ++.di ++.rm %\\*(|X ++.xl \\n($lu ++.rm |X ++.ev ++.nf ++.in 0 ++.ta \\n(.lu-\\n(xuuR \\n(.luR ++.|x ++.fi ++.in ++.rm |x ++.. ++. ++. ++.\" *** HTML VERSIONS OF .x(, .x), AND .xp *** ++. ++. ++.de (x-html \" --- create TAG and divert text ++.nr _x +1 ++.do nr _xn +1 ++.do TAG "_x\\n[_x] ++.br ++.do di |x\\n[_xn] ++.br ++.. ++. ++.de )x-html \" --- end diversion ++.br ++.di ++.. ++. ++.de xp-html \" --- create list of links ++.do nr _xx 1 ++.br ++.do ev xp-html-ev ++.sp ++.do ULS ++.do while \\n[_xx]<=\\n[_xn] \ ++\{\ ++. br ++. do unformat |x\\n[_xx] ++. do di xp-html-div ++. br ++. ll 100i ++. fi ++. do |x\\n[_xx] ++. br ++. di ++. do asciify xp-html-div ++. do rm xp-html-as ++. do as xp-html-as # ++. do as xp-html-as _x\\n[_xx] ++. ll ++. LI ++. do URL \\*[xp-html-as] "\\*[xp-html-div] ++. do rm xp-html-as ++. do nr _xx +1 ++.\} ++.do ULE ++.sp ++.ev ++.. ++. ++.if '\*(.T'html' \ ++\{\ ++. rm (x ++. do als (x (x-html ++. rm )x ++. do als )x )x-html ++. rm xp ++. do als xp xp-html ++.\} ++. ++. ++.\" *** CHAPTERS AND TITLES *** ++. ++. ++.de +c \" *** begin chapter ++.ep\" \" force out footnotes ++.if \\n(?o:\\n(?a \ ++\{\ ++. bp \" force out a table or more footnote ++. rs ++. ep ++.\} ++.nr ?C 1 ++.nr $f 1 1 ++.ds * \\*{1\\*}\k* ++.if \\n(?R \ ++. pn 1 ++.bp ++.in \\n($iu \" reset the indent ++.rs ++.ie \\n(.$ \ ++. $c "\\$1" ++.el \ ++. sp 3 ++.. ++. ++.de ++ \" *** declare chapter type ++.nr _0 0 ++.if "\\$1"C" \ ++. nr _0 1 \" chapter ++.if "\\$1"RC" \ ++. nr _0 11 \" renumbered chapter ++.if "\\$1"A" \ ++. nr _0 2 \" appendix ++.if "\\$1"RA" \ ++. nr _0 12 \" renumbered appendix ++.if "\\$1"P" \ ++. nr _0 3 \" preliminary material ++.if "\\$1"B" \ ++. nr _0 4 \" bibliographic material ++.if "\\$1"AB" \ ++. nr _0 5 \" abstract ++.if \\n(_0=0 \ ++. tm Line \\n(c. -- Bad mode to .++ ++.nr ?R 0 ++.if \\n(_0>10 \ ++.\{ ++. nr ?R 1 ++. nr _0 -10 ++.\} ++.nr ch 0 1 ++.if (\\n(_0=3):(\\n(_0=5) \ ++. pn 1 \" must do before .ep ++.if !\\n(_0=\\n(_M .if \\n(_M=3 \ ++. pn 1 \" must do before .ep ++.ep\" \" end page for correct page number types ++.if \\n(_0=1 \ ++\{\ ++. af ch 1 ++. af % 1 ++.\} ++.if \\n(_0=2 \ ++\{\ ++. af ch A ++. af % 1 ++.\} ++.if \\n(_0=3 \ ++. af % i ++.if \\n(_0=4 \ ++. af % 1 ++.if \\n(_0=5 \ ++. af % 1 ++.if \\n(.$>1 \ ++. he \\$2 ++.nr _M \\n(_0 ++.rr _0 ++.. ++. ++.de $c \" $$$ print chapter title ++.sz 12 ++.ft 3 ++.ce 1000 ++.if \\n(_M<3 \ ++. nr ch +1 ++.ie \\n(_M=1 CHAPTER\ \ \\n(ch ++.el .if \\n(_M=2 APPENDIX\ \ \\n(ch ++.if \w"\\$1" .sp 3-\\n(.L ++.if \w"\\$1" \\$1 ++.if (\\n(_M<3):(\w"\\$1") \ ++. sp 4-\\n(.L ++.ce 0 ++.ft ++.sz ++.ie \\n(_M=1 \ ++. $C Chapter \\n(ch "\\$1" ++.el .if \\n(_M=2 \ ++. $C Appendix \\n(ch "\\$1" ++.. ++. ++.de tp \" *** title page ++.hx ++.bp ++.br ++.rs ++.pn \\n% ++.. ++. ++.\" *** DATES *** ++.if \n(mo=1 .ds mo January ++.if \n(mo=2 .ds mo February ++.if \n(mo=3 .ds mo March ++.if \n(mo=4 .ds mo April ++.if \n(mo=5 .ds mo May ++.if \n(mo=6 .ds mo June ++.if \n(mo=7 .ds mo July ++.if \n(mo=8 .ds mo August ++.if \n(mo=9 .ds mo September ++.if \n(mo=10 .ds mo October ++.if \n(mo=11 .ds mo November ++.if \n(mo=12 .ds mo December ++.if \n(dw=1 .ds dw Sunday ++.if \n(dw=2 .ds dw Monday ++.if \n(dw=3 .ds dw Tuesday ++.if \n(dw=4 .ds dw Wednesday ++.if \n(dw=5 .ds dw Thursday ++.if \n(dw=6 .ds dw Friday ++.if \n(dw=7 .ds dw Saturday ++.nr y2 \n(yr%100 ++.af y2 00 ++.nr y4 \n(yr+1900 ++.ds td \*(mo \n(dy, \n(y4 ++. ++. ++.\" *** PARAMETRIC INITIALIZATIONS *** ++. ++. ++.rr x ++.nr $v \n(.v00+\n(.sp-1/\n(.sp \" vs as percentage of ps for .sz request ++.nr $V \n($v \" same for displays & footnotes ++.nr hm 4v \" header margin ++.nr tm 7v \" top margin ++.nr bm 6v \" bottom margin ++.nr fm 3v \" footer margin ++.nr tf 3 \" title font: (real) Times Bold ++.nr tp 10 \" title point size ++.hy 14 ++.nr bi 4m \" indent for blocks ++.nr pi 5n \" indent for paragraphs ++.nr pf 1 \" normal text font ++.nr pp 10 \" normal text point size ++.nr qi 4n \" indent for quotes ++.nr qp -1 \" down one point ++.nr ii 5n \" indent for .ip's and .np's ++.nr $m 1 \" max number of columns ++.nr $s 4n \" column separation ++.nr sf 3 \" section font -- Times Bold ++.nr sp 10 \" section title pointsize ++.nr ss 12p \" section prespacing ++.nr si 0 \" section indent ++. ++. ++.\" *** OTHER INITIALIZATION *** ++. ++. ++.\" GNU pic sets this register to 1, to indicate that \x should not be used. ++.@R 0x ++.ds { \v'-0.4m'\x'\\n(0x=0*-0.2m'\s-3 ++.ds } \s0\v'0.4m' ++.\" for compatibility with traditional -me ++.\" (the first will work only in compatibility mode) ++.ds [ \*{ ++.ds ] \*} ++.ds < \v'0.4m'\x'\\n(0x=0*0.2m'\s-3 ++.ds > \s0\v'-0.4m' ++.ds - \(em ++.\" Avoid warnings from groff -ww. ++.@S |0 ++.@S |1 ++.@S |2 ++.@S |3 ++.@S $H ++.@S $0 ++.@S $1 ++.@S $2 ++.@S $3 ++.@S $4 ++.@S $5 ++.@S $6 ++.@S $7 ++.@S $8 ++.@S $9 ++.@S .. ++. ++.@R po\" \" simulated page offset ++.@R $0\" \" section depth ++.@R $i\" \" paragraph base indent ++.@R $p\" \" numbered paragraph number ++.@R $r\" \" ratio of vs to ps (may override $v) ++.@R $R\" \" same for displays (may override $V) ++.@R df\" \" display font: same as surrounding text ++.@R so\" \" additional section title offset ++.@R fu\" \" footnote undent ++.@R bt\" \" block keep threshold ++.@R *\" \" has \** been referenced? ++.@R ?a\" \" pending floating keep at page top? ++.@R ?b\" \" pending floating keep at page bottom? ++.@R ?C\" \" at chapter header? ++.@R ?e\" \" in equation? ++.@R ?H\" \" suppress headers and footers next page? ++.@R ?I\" \" has the header trap been sprung? ++.@R ?n\" \" n1 mode? ++.@R ?o\" \" footnote overflow? ++.@R ?R\" \" renumbered chapter? ++.@R ?s\" \" skip next page? ++.@R ?T\" \" inside .TS H? ++.@R ?W\" \" wide floating keep at page bottom? ++.@R ?w\" \" wide floating keep at page top? ++. ++.nr fi 0.3i ++.nr _o \n(.o ++.nr $b 3 \" bold ++.nr ps 0.35v ++.if \n(ps<\n(.V .nr ps \n(.V ++.nr bs \n(ps \" block pre/post spacing ++.nr qs \n(ps \" quote pre/post spacing ++.nr zs 1v \" float-block pre/postspacing ++.nr xs 0.2v \" index prespacing ++.nr xu 0.5i \" index undent ++.nr fs 0.2v \" footnote prespacing ++.nr es 0.5v \" equation pre/postspacing ++.if \n(es<\n(.V .nr es \n(.V ++.wh 0 @h \" set header ++.nr $l \n(.lu \" line length ++.nr _L \n(.lu \" line length of page ++.nr $c 1 \" current column number ++.nr $f 1 1 \" footnote number ++.ds * \*{1\*}\k*\" \" footnote "name" ++.nr $d 1 1 \" delayed text number ++.ds # [1]\k#\" \" delayed text "name" ++.nr _M 1 \" chapter mode is chapter ++.ds lq \(lq\" \" left quote ++.ds rq \(rq\" \" right quote ++.em @z ++. ++. ++.\" *** FOREIGN LETTERS AND SPECIAL CHARACTERS *** ++. ++. ++.ds #h ((1u-(\\\\n(.fu%2u))*0.13m) ++.ds #v 0.6m ++. ++.\" \" accents ++.ds ' \k_\h'-(\\n(.wu*8/10-\*(#h)'\(aa\h'|\\n_u' ++.ds ` \k_\h'-(\\n(.wu*7/10-\*(#h)'\(ga\h'|\\n_u' ++. ++.\" \" umlaut ++.ds : \k_\h'-(\\n(.wu*8/10-\*(#h+0.1m)'\v'-\*(#v'\z.\h'0.2m'.\h'|\\n_u'\v'\*(#v' ++. ++.\" \" circumflex and tilde ++.ds ^ \k_\h'-(\\n(.wu-\*(#h-0.05m)'^\h'|\\n_u' ++.ds ~ \k_\h'-(\\n(.wu-\*(#h-0.05m)'~\h'|\\n_u' ++. ++.\" \" cedilla and czech ++.ds , \k_\h'-(\\n(.wu)',\h'|\\n_u' ++.ds v \k_\h'-(\\n(.wu*9/10-\*(#h)'\v'-\*(#v'\s-4v\s0\v'\*(#v'\h'|\\n_u' ++. ++.\" \" Norwegian A or angstrom ++.ds o \k_\h'-(\\n(.wu+\w'\(de'u-\*(#h)/2u'\v'-0.4n'\z\(de\v'0.4n'\h'|\\n_u' ++. ++.\" \" there exists, for all ++.ds qe \s-2\v'0.45m'\z\(em\v'-0.625m'\z\(em\v'-0.625m'\(em\v'0.8m'\s0\h'-0.1m'\v'-0.05m'\(br\v'0.05m'\h'0.1m' ++.ds qa \z\e\h'0.35m'\z\(sl\h'-0.33m'\v'-0.3m'\s-4\(em\s0\v'0.3m'\h'0.15m' ++.rm #h #v ++.ll 6.0i ++.lt 6.0i ++. ++.de @U ++.tm The \\$1 macro has been removed from this version of the -me macros. ++.. ++. ++.de lo ++.@U lo ++.. ++. ++.de th ++.@U th ++.. ++. ++.de ac ++.@U ac ++.. ++. ++.\" EOF +diff -Nuar groff-1.22.3.old/tmac/.gitignore groff-1.22.3/tmac/.gitignore +--- groff-1.22.3.old/tmac/.gitignore 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/.gitignore 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,18 @@ ++*-s ++*-sed ++*-wrap ++groff_man.n ++groff_mdoc.n ++groff_me.n ++groff_ms.n ++groff_www.n ++groff_trace.n ++stamp-strip ++doc-common ++doc-ditroff ++doc-nroff ++doc-old.tmac ++doc-syms ++doc.tmac ++e.tmac ++www.tmac +diff -Nuar groff-1.22.3.old/tmac/groff_man.man groff-1.22.3/tmac/groff_man.man +--- groff-1.22.3.old/tmac/groff_man.man 2014-11-04 10:38:35.534520134 +0200 ++++ groff-1.22.3/tmac/groff_man.man 2015-04-23 20:57:03.000000000 +0300 +@@ -4,6 +4,10 @@ + groff_man \- groff man macros to support generation of man pages + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" Legal Terms + .\" -------------------------------------------------------------------- +@@ -1269,6 +1273,9 @@ + .au + . + . ++.cp \n[groff_C] ++. ++. + .\" -------------------------------------------------------------------- + .\" ### Emacs settings: + .\" Local Variables: +diff -Nuar groff-1.22.3.old/tmac/groff_trace.man groff-1.22.3/tmac/groff_trace.man +--- groff-1.22.3.old/tmac/groff_trace.man 2014-11-04 10:38:35.535520121 +0200 ++++ groff-1.22.3/tmac/groff_trace.man 2015-04-23 20:57:03.000000000 +0300 +@@ -6,6 +6,10 @@ + .\" File position: /tmac/groff_trace.man + . + . ++.do nr groff_C \n[.C] ++.cp 0 ++. ++. + .\" -------------------------------------------------------------------- + .\" Legal Terms + .\" -------------------------------------------------------------------- +@@ -323,6 +327,9 @@ + .au + . + . ++.cp \n[groff_C] ++. ++. + .\" Local Variables: + .\" mode: nroff + .\" End: +diff -Nuar groff-1.22.3.old/tmac/Makefile.sub groff-1.22.3/tmac/Makefile.sub +--- groff-1.22.3.old/tmac/Makefile.sub 2014-11-04 10:38:35.537520096 +0200 ++++ groff-1.22.3/tmac/Makefile.sub 1970-01-01 02:00:00.000000000 +0200 +@@ -1,184 +0,0 @@ +-# Makefile.sub for `tmac' +-# +-# File position: /tmac/Makefile.sub +-# +-# Copyright (C) 1989-2014 Free Software Foundation, Inc. +-# Written by James Clark (jjc@jclark.com) +-# +-# This file is part of groff. +-# +-# groff is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation, either version 3 of the License, or +-# (at your option) any later version. +-# +-# groff is distributed in the hope that it will be useful, but WITHOUT ANY +-# WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# for more details. +-# +-# You should have received a copy of the GNU General Public License +-# along with this program. If not, see . +-# +-######################################################################## +- +-MAN7=\ +- groff_ms.n \ +- groff_man.n \ +- groff_me.n \ +- groff_mdoc.n \ +- groff_trace.n \ +- groff_www.n +- +-NORMALFILES=\ +- man.tmac mandoc.tmac andoc.tmac an-old.tmac an-ext.tmac \ +- ms.tmac \ +- me.tmac \ +- mdoc.tmac \ +- pic.tmac \ +- a4.tmac papersize.tmac \ +- 62bit.tmac \ +- ec.tmac \ +- safer.tmac \ +- trace.tmac \ +- ps.tmac psold.tmac pspic.tmac psatk.tmac \ +- pdf.tmac \ +- dvi.tmac \ +- tty.tmac tty-char.tmac \ +- latin1.tmac latin2.tmac latin5.tmac latin9.tmac cp1047.tmac \ +- unicode.tmac \ +- X.tmac Xps.tmac \ +- lj4.tmac \ +- lbp.tmac \ +- html.tmac html-end.tmac \ +- devtag.tmac \ +- europs.tmac \ +- composite.tmac fallbacks.tmac \ +- eqnrc \ +- refer.tmac refer-me.tmac refer-ms.tmac \ +- troffrc troffrc-end \ +- trans.tmac \ +- hyphen.us hyphenex.us \ +- fr.tmac hyphen.fr \ +- sv.tmac hyphen.sv \ +- de.tmac den.tmac hyphen.det hyphen.den hyphenex.det \ +- cs.tmac hyphen.cs hyphenex.cs \ +- ja.tmac +- +-# These files are handled specially during installation and deinstallation. +-SPECIALFILES=an.tmac s.tmac www.tmac +- +-# These files are processed with `strip.sed'. +-STRIPFILES=e.tmac doc.tmac doc-old.tmac +-MDOCFILES=doc-common doc-ditroff doc-nroff doc-syms +-mdocdir=$(tmacdir)/mdoc +- +-MOSTLYCLEANADD=\ +- stamp-wrap stamp-sed *-wrap www.tmac-sed \ +- stamp-strip e.tmac-s doc.tmac-s doc-old.tmac-s \ +- doc-common-s doc-ditroff-s doc-nroff-s doc-syms-s mdoc.local-s +-tmac_s_prefix= +-tmac_an_prefix= +-tmac_wrap= +-sys_tmac_prefix= +-pnmtops_nosetpage="pnmtops" +- +-RM=rm -f +- +-all: stamp-strip stamp-wrap stamp-sed +- +-install_data: $(NORMALFILES) $(SPECIALFILES) man.local \ +- stamp-strip stamp-wrap stamp-sed +- -test -d $(DESTDIR)$(tmacdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(tmacdir) +- -test -d $(DESTDIR)$(systemtmacdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(systemtmacdir) +- -test -d $(DESTDIR)$(localtmacdir) \ +- || $(mkinstalldirs) $(DESTDIR)$(localtmacdir) +- if test -n "$(tmac_wrap)"; then \ +- for m in ""$(tmac_wrap); do \ +- $(INSTALL_DATA) $$m-wrap $(DESTDIR)$(systemtmacdir)/$$m.tmac; \ +- done; \ +- fi +- for f in $(NORMALFILES); do \ +- $(RM) $(DESTDIR)$(tmacdir)/$$f; \ +- $(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(tmacdir)/$$f; \ +- done +- $(RM) $(DESTDIR)$(tmacdir)/$(tmac_s_prefix)s.tmac +- $(INSTALL_DATA) $(srcdir)/s.tmac \ +- $(DESTDIR)$(tmacdir)/$(tmac_s_prefix)s.tmac +- $(RM) $(DESTDIR)$(tmacdir)/$(tmac_an_prefix)an.tmac +- $(INSTALL_DATA) $(srcdir)/an.tmac \ +- $(DESTDIR)$(tmacdir)/$(tmac_an_prefix)an.tmac +- $(RM) $(DESTDIR)$(tmacdir)/www.tmac +- $(INSTALL_DATA) www.tmac-sed $(DESTDIR)$(tmacdir)/www.tmac +- for f in $(STRIPFILES); do \ +- $(RM) $(DESTDIR)$(tmacdir)/$$f; \ +- $(INSTALL_DATA) $$f-s $(DESTDIR)$(tmacdir)/$$f; \ +- done +- -test -d $(DESTDIR)$(mdocdir) || $(mkinstalldirs) $(DESTDIR)$(mdocdir) +- for f in $(MDOCFILES); do \ +- $(RM) $(DESTDIR)$(mdocdir)/$$f; \ +- $(INSTALL_DATA) $$f-s $(DESTDIR)$(mdocdir)/$$f; \ +- done +- -test -f $(DESTDIR)$(localtmacdir)/man.local \ +- || $(INSTALL_DATA) $(srcdir)/man.local \ +- $(DESTDIR)$(localtmacdir)/man.local +- -test -f $(DESTDIR)$(localtmacdir)/mdoc.local \ +- || $(INSTALL_DATA) mdoc.local-s $(DESTDIR)$(localtmacdir)/mdoc.local +- +-stamp-strip: $(STRIPFILES) $(MDOCFILES) mdoc.local +- for f in $(STRIPFILES) $(MDOCFILES) mdoc.local; do \ +- $(RM) $$f-s; \ +- sed -f $(srcdir)/strip.sed $(srcdir)/$$f >$$f-s; \ +- done +- touch $@ +- +-stamp-wrap: +- if test -n "$(tmac_wrap)"; then \ +- for m in ""$(tmac_wrap); do \ +- $(RM) $$m-wrap; \ +- if test "$$m" = an; then \ +- echo .do mso andoc.tmac >>$$m-wrap; \ +- fi; \ +- echo .cp 1 >>$$m-wrap; \ +- echo .so $(sys_tmac_prefix)$$m >>$$m-wrap; \ +- done; \ +- fi +- touch $@ +- +-stamp-sed: www.tmac +- sed -e "s;@PNMTOPS_NOSETPAGE@;$(pnmtops_nosetpage);g" \ +- $(srcdir)/www.tmac > www.tmac-sed +- touch $@ +- +-uninstall_sub: +- -if test -n "$(tmac_wrap)"; then \ +- for m in ""$(tmac_wrap); do \ +- $(RM) $(DESTDIR)$(systemtmacdir)/$$m.tmac; \ +- done; \ +- fi +- -for f in $(NORMALFILES) $(STRIPFILES); do \ +- $(RM) $(DESTDIR)$(tmacdir)/$$f; \ +- done +- $(RM) $(DESTDIR)$(tmacdir)/$(tmac_s_prefix)s.tmac +- $(RM) $(DESTDIR)$(tmacdir)/$(tmac_an_prefix)an.tmac +- $(RM) $(DESTDIR)$(tmacdir)/www.tmac +- -if cmp -s $(DESTDIR)$(localtmacdir)/man.local \ +- $(srcdir)/man.local; then \ +- $(RM) $(DESTDIR)$(localtmacdir)/man.local; \ +- fi +- -if cmp -s $(DESTDIR)$(localtmacdir)/mdoc.local \ +- $(srcdir)/mdoc.local; then \ +- $(RM) $(DESTDIR)$(localtmacdir)/mdoc.local; \ +- fi +- -for f in $(MDOCFILES); do $(RM) $(DESTDIR)$(mdocdir)/$$f; done +- -test -d $(DESTDIR)$(mdocdir) && rmdir $(DESTDIR)$(mdocdir) +- +-######################################################################## +-# Emacs settings +-######################################################################## +-# +-# Local Variables: +-# mode: makefile +-# End: +diff -Nuar groff-1.22.3.old/tmac/strip.sed groff-1.22.3/tmac/strip.sed +--- groff-1.22.3.old/tmac/strip.sed 2014-11-04 10:38:35.539520071 +0200 ++++ groff-1.22.3/tmac/strip.sed 2015-04-23 20:57:03.000000000 +0300 +@@ -1,3 +1,6 @@ ++2 i\ ++.\\" This is a generated file, created by `tmac/strip.sed' in groff's\ ++.\\" source code bundle from a file having `-u' appended to its name. + # strip comments, spaces, etc., after a line containing `%beginstrip%' + /%beginstrip%/,$ { + s/^\.[ ]*/./ +diff -Nuar groff-1.22.3.old/tmac/tmac.am groff-1.22.3/tmac/tmac.am +--- groff-1.22.3.old/tmac/tmac.am 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/tmac.am 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,216 @@ ++# Copyright (C) 1989-2007, 2009-2012, 2014 ++# Free Software Foundation, Inc. ++# Written by James Clark (jjc@jclark.com) ++# Automake migration by Bertrand Garrigues ++# ++# This file is part of groff. ++# ++# groff is free software; you can redistribute it and/or modify it under ++# the terms of the GNU General Public License as published by the Free ++# Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# groff is distributed in the hope that it will be useful, but WITHOUT ANY ++# WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++tmac_srcdir = $(top_srcdir)/tmac ++tmac_builddir = $(top_builddir)/tmac ++ ++man7_MANS += \ ++ tmac/groff_ms.n \ ++ tmac/groff_man.n \ ++ tmac/groff_me.n \ ++ tmac/groff_mdoc.n \ ++ tmac/groff_trace.n \ ++ tmac/groff_www.n ++ ++TMACNORMALFILES = \ ++ tmac/man.tmac \ ++ tmac/mandoc.tmac \ ++ tmac/andoc.tmac \ ++ tmac/an-old.tmac \ ++ tmac/an-ext.tmac \ ++ tmac/ms.tmac \ ++ tmac/me.tmac \ ++ tmac/mdoc.tmac \ ++ tmac/pic.tmac \ ++ tmac/a4.tmac \ ++ tmac/papersize.tmac \ ++ tmac/62bit.tmac \ ++ tmac/ec.tmac \ ++ tmac/safer.tmac \ ++ tmac/trace.tmac \ ++ tmac/ps.tmac \ ++ tmac/psold.tmac \ ++ tmac/pspic.tmac \ ++ tmac/psatk.tmac \ ++ tmac/pdf.tmac \ ++ tmac/dvi.tmac \ ++ tmac/tty.tmac \ ++ tmac/tty-char.tmac \ ++ tmac/latin1.tmac \ ++ tmac/latin2.tmac \ ++ tmac/latin5.tmac \ ++ tmac/latin9.tmac \ ++ tmac/cp1047.tmac \ ++ tmac/unicode.tmac \ ++ tmac/X.tmac \ ++ tmac/Xps.tmac \ ++ tmac/lj4.tmac \ ++ tmac/lbp.tmac \ ++ tmac/html.tmac \ ++ tmac/html-end.tmac \ ++ tmac/devtag.tmac \ ++ tmac/europs.tmac \ ++ tmac/composite.tmac \ ++ tmac/fallbacks.tmac \ ++ tmac/eqnrc \ ++ tmac/refer.tmac \ ++ tmac/refer-me.tmac \ ++ tmac/refer-ms.tmac \ ++ tmac/troffrc \ ++ tmac/troffrc-end \ ++ tmac/trans.tmac \ ++ tmac/hyphen.us \ ++ tmac/hyphenex.us \ ++ tmac/fr.tmac \ ++ tmac/hyphen.fr \ ++ tmac/sv.tmac \ ++ tmac/hyphen.sv \ ++ tmac/de.tmac \ ++ tmac/den.tmac \ ++ tmac/hyphen.det \ ++ tmac/hyphen.den \ ++ tmac/hyphenex.det \ ++ tmac/cs.tmac \ ++ tmac/hyphen.cs \ ++ tmac/hyphenex.cs \ ++ tmac/ja.tmac ++NORMALFILES = `echo $(TMACNORMALFILES) | sed -e "s|tmac/||g"` ++ ++# TMACSTRIPFILES are built from their unstripped version (-u) ++TMACSTRIPFILES = tmac/e.tmac tmac/doc.tmac tmac/doc-old.tmac ++ ++# Files installed in tmacdir ++dist_tmac_DATA = $(TMACNORMALFILES) tmac/an.tmac tmac/s.tmac ++nodist_tmac_DATA = $(TMACSTRIPFILES) tmac/www.tmac ++ ++TMACMDOCFILES = \ ++ tmac/doc-common \ ++ tmac/doc-ditroff \ ++ tmac/doc-nroff \ ++ tmac/doc-syms ++MDOCFILES = `echo $(TMACMDOCFILES) | sed -e "s|tmac/||g"` ++mdocdir=$(tmacdir)/mdoc ++# Files installed in mdocdir ++nodist_mdoc_DATA = $(TMACMDOCFILES) ++ ++# Installed in localtmacdir ++dist_localtmac_DATA = tmac/man.local tmac/mdoc.local ++ ++MOSTLYCLEANFILES += $(TMACMDOCFILES) tmac/www.tmac $(TMACSTRIPFILES) \ ++ tmac/stamp-wrap \ ++ tmac/*-wrap ++ ++EXTRA_DIST += \ ++ tmac/fixmacros.sed \ ++ tmac/groff_ms.man \ ++ tmac/groff_man.man \ ++ tmac/groff_me.man \ ++ tmac/groff_mdoc.man \ ++ tmac/groff_trace.man \ ++ tmac/groff_www.man \ ++ tmac/hyphenex.pl \ ++ tmac/LOCALIZATION \ ++ tmac/man.ultrix \ ++ tmac/psfig.tmac \ ++ tmac/ptx.tmac \ ++ tmac/strip.sed \ ++ tmac/TESTING-HINTS \ ++ tmac/TODO \ ++ tmac/www.tmac.in ++ ++dist-hook: tmac-dist-hook ++tmac-dist-hook: ++ chmod u+w $(distdir)/tmac ++ for f in $(TMACMDOCFILES) $(TMACSTRIPFILES); do \ ++ cp -f $(top_srcdir)/$$f-u $(distdir)/tmac; \ ++ done ++ ++ ++# If the system comes with its own tmac macro installation (/usr/lib/tmac ++# contains tmac.an, tmac.m, tmac.s), ms and man macros are installed as ++# gs.tmac and gan.tmac, instead of s.tmac and an.tmac. Also, an.tmac, ++# m.tmac and s.tmac files are installed in /lib/groff/site-tmac. ++all: tmac/stamp-wrap ++ ++$(TMACMDOCFILES) $(TMACSTRIPFILES): ++ $(MKDIR_P) $(top_builddir)/tmac ++ for f in $(TMACMDOCFILES) $(TMACSTRIPFILES); do \ ++ sed -f $(tmac_srcdir)/strip.sed $(top_srcdir)/$$f-u > $(top_builddir)/$$f; \ ++ done ++ ++tmac/stamp-wrap: ++ $(MKDIR_P) $(top_builddir)/tmac; ++ if test -n "$(tmac_wrap)"; then \ ++ for m in ""$(tmac_wrap); do \ ++ $(RM) $(top_builddir)/tmac/$$m-wrap; \ ++ if test "$$m" = an; then \ ++ echo .do mso andoc.tmac >>$(top_builddir)/tmac/$$m-wrap; \ ++ fi; \ ++ echo .cp 1 >>$(top_builddir)/tmac/$$m-wrap; \ ++ echo .so $(sys_tmac_prefix)$$m >>$(top_builddir)/tmac/$$m-wrap; \ ++ done; \ ++ fi ++ touch $@ ++ ++tmac/www.tmac: tmac/www.tmac.in ++ $(MKDIR_P) $(top_builddir)/tmac ++ sed -e "s;[@]PNMTOPS_NOSETPAGE[@];$(pnmtops_nosetpage);g" \ ++ $(tmac_srcdir)/www.tmac.in > $(top_builddir)/tmac/www.tmac ++ ++install-data-local: install_tmac_wrap ++install_tmac_wrap: ++ $(MKDIR_P) $(DESTDIR)$(systemtmacdir); ++ if test -n "$(tmac_wrap)"; then \ ++ for m in ""$(tmac_wrap); do \ ++ $(INSTALL_DATA) $(tmac_builddir)/$$m-wrap \ ++ $(DESTDIR)$(systemtmacdir)/$$m.tmac; \ ++ done; \ ++ fi ++ ++install-data-hook: install_tmac_wrap_hook ++install_tmac_wrap_hook: ++ if test -n "$(tmac_wrap)"; then \ ++ if test -f $(DESTDIR)$(tmacdir)/s.tmac; then \ ++ mv $(DESTDIR)$(tmacdir)/s.tmac \ ++ $(DESTDIR)$(tmacdir)/$(tmac_s_prefix)s.tmac; \ ++ fi; \ ++ if test -f $(DESTDIR)$(tmacdir)/an.tmac; then \ ++ mv $(DESTDIR)$(tmacdir)/an.tmac \ ++ $(DESTDIR)$(tmacdir)/$(tmac_an_prefix)an.tmac; \ ++ fi; \ ++ fi ++ ++uninstall_groffdirs: uninstall_tmac_hook ++uninstall_tmac_hook: ++ if test -n "$(tmac_wrap)"; then \ ++ for m in ""$(tmac_wrap); do \ ++ $(RM) $(DESTDIR)$(systemtmacdir)/$$m.tmac; \ ++ done; \ ++ $(RM) -f $(DESTDIR)$(tmacdir)/$(tmac_an_prefix)an.tmac; \ ++ $(RM) -f $(DESTDIR)$(tmacdir)/$(tmac_s_prefix)s.tmac; \ ++ fi ++ if test -d $(DESTDIR)$(mdocdir); then \ ++ rmdir $(DESTDIR)$(mdocdir); \ ++ fi ++ if test -d $(DESTDIR)$(tmacdir); then \ ++ rmdir $(DESTDIR)$(tmacdir); \ ++ fi ++ if test -d $(DESTDIR)$(localtmacdir); then \ ++ rmdir $(DESTDIR)$(localtmacdir); \ ++ fi +diff -Nuar groff-1.22.3.old/tmac/www.tmac groff-1.22.3/tmac/www.tmac +--- groff-1.22.3.old/tmac/www.tmac 2014-11-04 10:38:35.540520059 +0200 ++++ groff-1.22.3/tmac/www.tmac 1970-01-01 02:00:00.000000000 +0200 +@@ -1,1625 +0,0 @@ +-.ig +-www.tmac - macro package for adding HTML elements to roff documents. +- +-File position: /tmac/www.tmac +-Installed position: groff's main macro directory. +- +------------------------------------------------------------------------- +- Legalese +------------------------------------------------------------------------- +- +-This file is part of groff, the GNU roff type-setting system. +- +-Copyright (C) 2001-2014 Free Software Foundation, Inc. +-written by Gaius Mulley , with additions by +-Werner Lemberg and +-Bernd Warken . +- +-groff is free software; you can redistribute it and/or modify it under +-the terms of the GNU General Public License as published by the Free +-Software Foundation, either version 3 of the License, or +-(at your option) any later version. +- +-groff is distributed in the hope that it will be useful, but WITHOUT +-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-for more details. +- +-You should have received a copy of the GNU General Public License +-along with this program. If not, see . +- +- +------------------------------------------------------------------------- +- Description +------------------------------------------------------------------------- +- +-A simple set of macros to provide HTML (or XHTML) documents with basic +-www functionality. It should work with any macro set. In the following, +-HTML always denotes XHTML also. +-.. +-. +-. +-.\" -------------------------------------------------------------------- +-.\" Setup +-.\" -------------------------------------------------------------------- +-. +-.do if d www:lenstr .nx +-. +-.do mso devtag.tmac +-. +-.nr _C \n(.C +-.cp 0 +-. +-. +-.ie r xhtml \ +-. ds www-> />\" +-.el \ +-. ds www-> >\" +-. +-.nr www-html 0 +-.if '\*[.T]'html' \ +-. nr www-html 1 +-. +-.\" set up www-image-template +-. +-.if !d www-image-template \ +-. ds www-image-template +-. +-.if r ps4html \{\ +-. \" remove the title command when we are generating images for HTML +-. \" (stops a title accidentally appearing inside an image) +-. di www-notitle +-. tl '''' +-. di +-. rm tl +-. de tl +-. . +-.\} +-. +-. +-.\" -------------------------------------------------------------------- +-.\" Test for `.substring'; result in register `www.substring_ok'. +-.\" The automated break points in .URL addresses are only added if +-.\" this register is non-zero. +-.\" +-.nr www:substring_ok 0 +-.de www:@test_substring +-. if !d substring \ +-. return +-. ds \\$0:s abcdefg\" +-. substring \\$0:s 1 1 +-. if !'\\*[\\$0:s]'b' \{\ +-. rm \\$0:s +-. return +-. \} +-. ds \\$0:s abcdefg\" +-. substring \\$0:s 0 0 +-. if !'\\*[\\$0:s]'a' \{\ +-. rm \\$0:s +-. return +-. \} +-. ds \\$0:s abcdefg\" +-. substring \\$0:s 1 -1 +-. if !'\\*[\\$0:s]'bcdefg' \{\ +-. rm \\$0:s +-. return +-. \} +-. nr www:substring_ok 1 +-. rm \\$0:s +-.. +-.www:@test_substring +-.rm www:@test_substring +-. +-. +-.\" -------------------------------------------------------------------- +-.\" Local Macros +-.\" -------------------------------------------------------------------- +-. +-.\" -------------------------------------------------------------------- +-.\" www:paraspace +-.\" +-.\" Space before paragraph. Use \n[PD] if it exists. +-.\" +-.nr www:pd 0.5v +-. +-.de www:paraspace +-. ie r PD \ +-. sp \\n[PD]u +-. el \ +-. sp \\n[www:pd]u +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" www:error (...) +-.\" +-.\" Print error message. +-.\" +-.de www-error +-. tm \\n[.F]:\\n[.c]: macro error: \\$* +-.. +-. +-.als www:error www-error +-. +-.\" -------------------------------------------------------------------- +-.\" www:lenstr ( ) +-.\" +-.\" Store length of string named into register named +-.\" . +-.\" +-.de www:lenstr +-. if !(\\n[.$] == 2) \{\ +-. tm .\\$0 expects 2 arguments. +-. ab +-. \} +-. length \\$0:n x\\*[\\$2] +-. nr \\$1 (\\n[\\$0:n] - 1) +-. rr \\$0:n +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" www:splitstr () +-.\" +-.\" Add a space character between any two adjacent characters in string +-.\" and restore result into the string variable ; space +-.\" characters are first replaced by the word `space'. +-.\" +-.de www:splitstr +-. if !(\\n[.$] == 1) \ +-. www:error .\\$0 expects 1 argument. +-. if '\\*[\\$1]'' \ +-. return +-. ds \\$0:r "\\*[\\$1]\" +-. ds \\$0:s +-. while 1 \{\ +-. ds \\$0:c "\\*[\\$0:r]\" +-. substring \\$0:c 0 0 +-. ie '\\*[\\$0:c]' ' \ +-. as \\$0:s " space\" +-. el \ +-. as \\$0:s " \\*[\\$0:c]\" +-. www:lenstr \\$0:n \\$0:r +-. if (\\n[\\$0:n] <= 1) \ +-. break +-. substring \\$0:r 1 -1 +-. \} +-. if !'\\*[\\$0:s]'' \ +-. substring \\$0:s 1 -1 +-. ds \\$1 \\*[\\$0:s]\" +-. rm \\$0:c +-. rr \\$0:n +-. rm \\$0:r +-. rm \\$0:s +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" www:url_breaks () +-.\" +-.\" Add `\:' (possible break point) within URL strings after `/'. +-.\" +-.\" Smart about multiple `/', existing `\:', and space characters; +-.\" does not set a break point if less than 5 characters would go to +-.\" the next line. +-.\" +-.de www:url_breaks +-. if !(\\n[.$] == 1) \ +-. www:error .\\$0 expects 1 argument. +-. if !\n[www:substring_ok] \ +-. return +-. ds \\$0:s "\\*[\\$1]\" +-. www:splitstr \\$0:s +-. www:url_breaks_split \\$0:s \\*[\\$0:s] +-. ds \\$1 "\\*[\\$0:s]\" +-. rm \\$0:s +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" www:url_breaks_split ( [...]) +-.\" +-.\" Add `\:' within URL strings, but arguments are a split string. +-.\" +-.\" Arguments: >=2: [...] +-.\" +-.de www:url_breaks_split +-. nr \\$0:min 5 \" minimal number of characters for next line +-. if (\\n[.$] < 2) \ +-. www:error .\\$0 expects at least 2 arguments. +-. ds \\$0:res \\$1\" +-. shift +-. ds \\$0:s +-. nr \\$0:done 0 +-. while !\\n[\\$0:done] \{\ +-. if (\\n[.$] <= 0) \ +-. break +-. if '\\$1'space' \{\ +-. as \\$0:s " \" +-. shift +-. continue +-. \} +-. if (\\n[.$] < \\n[\\$0:min]) \{\ +-. as \\$0:s "\\$1\" +-. shift +-. continue +-. \} +-. if !'\\$1'/' \{\ +-. as \\$0:s "\\$1\" +-. shift +-. continue +-. \} +-. \" we are at a `/' character +-. while '\\$1'/' \{\ +-. as \\$0:s /\" +-. if (\\n[.$] == 0) \{\ +-. nr \\$0:done 1 +-. break +-. \} +-. shift +-. \} +-. if \\n[\\$0:done] \ +-. break +-. if (\\n[.$] < \\n[\\$0:min]) \ +-. continue +-. if '\\$1'\:' \ +-. shift +-. as \\$0:s \:\" +-. \} +-. ds \\*[\\$0:res] \\*[\\$0:s]\" +-. rm \\$0:res +-. rm \\$0:s +-.. +-. +-. +-.\" -------------------------------------------------------------------- +-.\" User Interface +-.\" -------------------------------------------------------------------- +-. +-.\" -------------------------------------------------------------------- +-.\" HTML +-.\" +-.\" The main auxiliary macro for the HTML interface. +-.\" +-.de HTML +-. if \\n[www-html] \{\ +-. \" was implemented via .nop \&\X^html:\\$*^ but +-. \" is now implemented using HTML-NS to utilize code factoring. +-. \" +-. \" the `\&' makes the vertical mode leave, so to say +-. \" +-. nop \&\c +-. HTML-NS \\$* +-. nop \& +-. \} +-.. +-. +-.\" +-.\" An auxiliary macro for HTML (without following space). +-.\" +-.de HTML-NS +-. nop \X^html:\\$*^\c +-.. +-. +-.\" +-.\" Emit an HTML tag after shutting down a (possibly open) paragraph. +-.\" +-.de HTML

    +-. ie \\n[www-html] \{\ +-. \" the `\&' makes the vertical mode leave, so to say +-. nop \&\X^html

    :\\$*^ +-. \} +-. el \ +-. www:paraspace +-.. +-. +-.\" +-.\" Emit an HTML tag. If text has been written in the paragraph +-.\" then do not shut the paragraph down. +-.\" If text was not written, remove the empty +-.\" paragraph tag and emit the desired HTML tag. +-.\" +-.de HTML +-. if \\n[www-html] \ +-. nop \&\X^html:\\$*^ +-.. +-. +-.\" +-.\" Emit a MATH tag. If text has been written in the paragraph +-.\" then do not shut the paragraph down. +-.\" If text was not written, remove the empty +-.\" paragraph tag and emit the desired math tag. +-.\" +-.de MATH +-. if \\n[www-html] \ +-. nop \&\X^math:\\$*^ +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" HX n +-.\" +-.\" Automatic heading level cut off. +-.\" +-.\" N is the depth limit of automatically linked headings. So a depth +-.\" of 2 would cause grohtml to generate a list of links for `.NH 1' +-.\" and `.NH 2' but not for `.NH 3'. +-.\" +-.de HX +-. if \\n[www-html] \ +-. nop \X^index:\\$*^ +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" BCL foreground background active not-visited visited +-.\" +-.de BCL +-. HTML " +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" BGIMG imagefile +-.\" +-.de BGIMG +-. HTML " +-.. +-. +-.\" www:url_check_tag str +-.\" If url named by \*[str] is internal (starts with #), +-.\" redefine \*[str] to be the value of the string TAG_url. +-. +-.de www:url_check_tag +-. ds \\$0:tmp \\*[\\$1]\" +-. substring \\$0:tmp 0 0 +-. if '\\*[\\$0:tmp]'#' \{\ +-. ds \\$0:tmp \\*[\\$1]\" +-. substring \\$0:tmp 1 +-. ds \\$0:tmp TAG_\\*[\\$0:tmp]\" +-. +-. ie d \\*[\\$0:tmp] \ +-. ds \\$1 \\*[\\*[\\$0:tmp]]\" +-. el \ +-. ds \\$1 see below\" +-. \} +-. rm \\$0:tmp +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" URL url [description] [after] +-.\" +-.\" If description is absent then the url becomes the anchor text. +-.\" +-.de URL +-. if !'\\$1'' \{\ +-. ds \\$0:adr \\$1\" +-. www:url_check_tag \\$0:adr +-. if !\\n[www-html] \ +-. www:url_breaks \\$0:adr +-. \} +-. ie \\n[www-html] \{\ +-. ie '\\$3'' \ +-. ds \\$0:after \&\" +-. el \ +-. ds \\$0:after \&\\$3\" +-. +-. ie '\\$2'' \ +-. HTML-NS
    \\*[\\$0:adr]" +-. el \ +-. HTML-NS \\$2" +-. +-. nop \\*[\\$0:after] +-. rm \\$0:after +-. \} +-. el \{\ +-. if !r ps4html \ +-. ad l +-. +-. ie '\\$2'' \{\ +-. ie '\\$1'' \{\ +-. if !'\\$3'' \ +-. nop \\$3 +-. \} +-. el \{\ +-. ie \\n[.color] \ +-. nop \%\\*[www:open]\m[\\*[www:color]]\f[\\*[www:fontstyle]]\\*[\\$0:adr]\f[]\m[]\\*[www:close]\\$3 +-. el \ +-. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\*[\\$0:adr]\f[]\\*[www:close]\\$3 +-. \} +-. \} +-. el \{\ +-. ie '\\$1'' \{\ +-. ie \\n[.color] \ +-. nop \m[\\*[www:color]]\\$2\m[]\\$3 +-. el \ +-. nop \f[\\*[www:fontstyle]]\\$2\f[]\\$3 +-. \} +-. el \{\ +-. ie \\n[.color] \{\ +-. nop \m[\\*[www:color]]\\$2\m[] +-. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\*[\\$0:adr]\f[]\\*[www:close]\\$3 +-. \} +-. el \{\ +-. nop \f[\\*[www:fontstyle]]\\$2\f[] +-. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\*[\\$0:adr]\f[]\\*[www:close]\\$3 +-. \} +-. \} +-. \} +-. +-. if !r ps4html \ +-. ad +-. \} +-. rm \\$0:adr +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" FTP url description [after] +-.\" +-.\" Same as URL. +-.\" +-.als FTP URL +-. +-.\" -------------------------------------------------------------------- +-.\" MTO address description [after] +-.\" +-.\" ADDRESS is the email address (without the `mailto:' prefix). +-.\" +-.\" DESCRIPTION is the optional name. If an empty argument is given, +-.\" ADDRESS is used instead. +-.\" +-.\" AFTER is optional stuff printed immediately after ADDRESS +-.\" (resp. DESCRIPTION). +-.\" +-.\" Example: +-.\" +-.\" Foobar has been written by +-.\" .MTO fred@foo.bar "Fredrick Bloggs" . +-.\" +-.de MTO +-. ie \\n[www-html] \{\ +-. ie '\\$2'' \ +-. URL mailto:\\$1 \\$1 "\\$3" +-. el \ +-. URL mailto:\\$1 "\\$2" "\\$3" +-. \} +-. el \{\ +-. ie '\\$2'' \{\ +-. ie '\\$1'' \{\ +-. ie !'\\$3'' \ +-. nop \\$3 +-. \} +-. el \{\ +-. ie \\n[.color] \ +-. nop \%\m[\\*[www:color]]\f[\\*[www:fontstyle]]\\$1\f[]\m[]\\$3 +-. el \ +-. nop \%\f[\\*[www:fontstyle]]\\$1\f[]\\$3 +-. \} +-. \} +-. el \{\ +-. ie '\\$1'' \{\ +-. ie \\n[.color] \ +-. nop \m[\\*[www:color]]\\$2\m[]\\$3 +-. el \ +-. nop \f[\\*[www:fontstyle]]\\$2\f[]\\$3 +-. \} +-. el \{\ +-. ie \\n[.color] \{\ +-. nop \m[\\*[www:color]]\\$2\m[] +-. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\$1\f[]\\*[www:close]\\$3 +-. \} +-. el \{\ +-. nop \f[\\*[www:fontstyle]]\\$2\f[] +-. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\$1\f[]\\*[www:close]\\$3 +-. \} +-. \} +-. \} +-. \} +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" TAG name [text] +-.\" +-.\" Generate an HTML name NAME. +-.\" Define string TAG_NAME to TEXT, if present, otherwise to \n[PN]. +-.\" Register PN is the current page number. +-.\" +-.de TAG +-. HTML " +-. ie '\\$2'' \ +-. if !rPN \ +-. nr PN \\n% +-. ds TAG_\\$1 \\n[PN]\" +-. el \ +-. ds TAG_\\$1 \\$2\" +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" IMG [-R|-L|-C] filename [width] [height] +-.\" +-.\" Include an image of any type (only works for -Thtml). +-.\" +-.\" Alignment is centered by default (-C). +-.\" Default value for WIDTH is 1i. +-.\" If HEIGHT is not given, WIDTH is used as the height. +-.\" +-.de IMG +-. ie \\n[www-html] \{\ +-. ie '\\$2'-R' \ +-. DEVTAG .right-image +-. el \{\ +-. ie '\\$2'-L' \ +-. DEVTAG .left-image +-. el \ +-. DEVTAG .centered-image +-. \} +-. nr www-width 100 +-. if !'\\$3'' \ +-. nr www-width \\$3 +-. nr www-height \\n[www-width] +-. if !'\\$4'' \ +-. nr www-height \\$4 +-. HTML ]" +-. \} +-. el \ +-. nop \\*[www:open]\f[\\*[www:fontstyle]]\\$1\f[]\\*[www:close] +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" PIMG [-R|-L|-C] filename [width] [height] +-.\" +-.\" Include a PNG image. It works for -Tps and -Thtml. +-.\" The default value for WIDTH and HEIGHT is zero; the default +-.\" alignment is centering (-C). +-.\" +-.\" Note: This macro can only be used with the `-U' option of groff, +-.\" activating unsafe mode, if not used with -Thtml; the PNG image +-.\" is then converted to the EPS format using netpbm utilities. +-.\" +-.de PIMG +-. ds www-pic-align -C\" +-. ie '\\$1'-R' \{\ +-. ds www-pic-align -R\" +-. shift +-. \} +-. el \{\ +-. if '\\$1'-L' \{\ +-. ds www-pic-align -L\" +-. shift +-. \} +-. \} +-. if '\\$1'-C' \ +-. shift +-. +-. ie \\n[www-html] \{\ +-. ds www-htmlalign align="center"\" +-. if '\\*[www-pic-align]'-R' \ +-. ds www-htmlalign align="right"\" +-. if '\\*[www-pic-align]'-L' \ +-. ds www-htmlalign align="left"\" +-. +-. nr www-width 0 +-. nr www-height 0 +-. if !'\\$2'' \ +-. nr www-width (\\$3 * 100 / 240) +-. if !'\\$3'' \ +-. nr www-height (\\$4 * 100 / 240) +-. ie (\\n[www-width] == 0) \{\ +-. ie (\\n[www-height] == 0) \ +-. HTML

    ]

    " +-. el \ +-. HTML

    ]

    " +-. \} +-. el \{\ +-. ie (\\n[www-height] == 0) \ +-. HTML

    ]

    " +-. el \ +-. HTML

    ]

    " +-. \} +-. \} +-. el \{\ +-. if !r ps4html \{\ +-. www-make-unique-name +-. sy pngtopnm \\$1 \ +- | pnmcrop -white \ +- | @PNMTOPS_NOSETPAGE@ -noturn \ +- > \\*[www-unique-name].eps +-. shift +-. PSPIC \\*[www-pic-align] \\*[www-unique-name].eps \\$* +-. \} +-. \} +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" auxiliary definitions for MPIMG +-.\" +-.nr www-left-ll-trap 0 +-.nr www-left-po-trap 0 +-.nr www-right-ll-trap 0 +-. +-.de www-finish-left-po +-. po -(\\n[www-left-indent]u + \\n[www-image-gap]u) +-. wh \\n[www-left-po-trap]u +-. nr www-left-indent 0 +-.. +-. +-.\" called when the -R picture is finished +-.de www-finish-right-ll +-. ll +(\\n[www-right-indent]u + \\n[www-image-gap]u) +-. +-. \" now check whether we need to inline www-finish-left-ll +-. if (\\n[www-left-ll-trap]u > 0) \ +-. if ((\\n[www-right-ll-trap]u + 1v) >= \\n[www-left-ll-trap]u) \{\ +-. mk www-left-po-trap +-. nr www-left-po-trap +1v +-. wh \\n[www-left-po-trap]u www-finish-left-po +-. ll +\\n[www-left-indent]u +-. wh \\n[www-left-ll-trap]u +-. nr www-left-ll-trap 0 +-. \} +-. +-. \" and check whether we need to inline www-finish-left-po +-. if (\\n[www-left-po-trap]u > 0) \ +-. if ((\\n[www-right-ll-trap]u + 1v) >= \\n[www-left-po-trap]u) \{\ +-. po -\\n[www-left-indent]u +-. wh \\n[www-left-po-trap]u +-. nr www-left-indent 0 +-. \} +-. +-. wh \\n[www-right-ll-trap]u +-. nr www-right-ll-trap 0 +-.. +-. +-.de www-finish-left-ll +-. if (\\n[www-right-ll-trap] > 0) \ +-. if ((\\n[www-left-ll-trap] + 1v) >= \\n[www-right-ll-trap]) \{\ +-. ll +\\n[www-right-indent]u +-. nr www-right-ll-trap 0 +-. \} +-. +-. mk www-left-po-trap +-. nr www-left-po-trap +1v +-. wh \\n[www-left-po-trap]u www-finish-left-po +-. ll +(\\n[www-left-indent]u + \\n[www-image-gap]u) +-. wh \\n[www-left-ll-trap]u +-. nr www-left-ll-trap 0 +-.. +-. +-.\" www-handle-percent arg N1 N2 S1 +-.\" arg - input string (number or number%) +-.\" output parameters: +-.\" N1 - name of number register 1=absolute 0=percentage +-.\" N2 - number register name for absolute value +-.\" S1 - string register name for percentage value +-.\" +-.de www-handle-percent +-. ds www-percent \\$1\" +-. substring www-percent -1 -1 +-. +-. ie '\\*[www-percent]'%' \{\ +-. ds www-abs \\$1\" +-. substring www-abs 0 -2 +-. nr \\$2 0 +-. nr \\$3 \\*[www-abs] +-. ds \\$4 \\$1\" +-. \} +-. el \{\ +-. nr \\$2 1 +-. nr \\$3 \\$1 +-. ds \\$4 none\" +-. \} +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" MPIMG [-R|-L] [-G gap] filename [width [height]] +-.\" +-.\" Include a PNG image and wrap text around it. It works for +-.\" -Tps and -Thtml. The default value for WIDTH is 1i; default value +-.\" for HEIGHT is WIDTH; the default alignment is left (-L). +-.\" -G is used to insert a gap between the text and the image. +-.\" The height and width can also be given as a percentage. +-.\" The PostScript device converts the percentage width into an +-.\" absolute value by using \\n[.l], and the height by using \\n[.p]. +-.\" +-.\" +-.\" Note: This macro can only be used with the `-U' option of groff, +-.\" activating unsafe mode, if not used with -Thtml; the PNG image +-.\" is then converted to the EPS format using netpbm utilities. +-.\" +-.nr www-htmlimage-gap 0 +-. +-.de MPIMG +-. nr www-image-just 1 +-. nr www-image-gap 0 +-. while (\\n[.$] > 0) \{\ +-. if '-L'\\$1' \{\ +-. nr www-image-just 1 +-. shift +-. continue +-. \} +-. if '-R'\\$1' \{\ +-. nr www-image-just 0 +-. shift +-. continue +-. \} +-. if '-G'\\$1' \{\ +-. nr www-image-gap \\$2 +-. nr www-htmlimage-gap (\\$2 * 100 / 240) +-. shift 2 +-. continue +-. \} +-. break +-. \} +-. +-. nr www-width 1i +-. nr www-height 1i +-. ds www-size-specs width="\\n[www-width]" height="\\n[www-height]"\" +-. ie !'\\$2'' \{\ +-. nr www-is-absolute 0 +-. nr www-absolute 0 +-. ds www-percentage none\" +-. www-handle-percent \\$2 www-is-absolute www-absolute www-percentage +-. ie !\\n[www-is-absolute] \{\ +-. \" percentage of linelength requested +-. nr www-width (\\n[www-absolute] * \\n[.l] / 100) +-. if \\n[www-html] \ +-. nr www-width (\\n[www-width] * 100 / 240) +-. ds www-size-specs width="\\*[www-percentage]"\" +-. \} +-. el \{\ +-. nr www-width \\n[www-absolute] +-. if \\n[www-html] \ +-. nr www-width (\\n[www-width] * 100 / 240) +-. ds www-size-specs width="\\n[www-width]"\" +-. \} +-. +-. nr www-height \\n[www-width] +-. ie !'\\$3'' \{\ +-. nr www-is-absolute 0 +-. nr www-absolute 0 +-. ds www-percentage none\" +-. www-handle-percent \\$3 www-is-absolute www-absolute www-percentage +-. ie !\\n[www-is-absolute] \{\ +-. \" percentage of pagelength requested +-. nr www-height (\\n[www-absolute] * \\n[.p] / 100) +-. if \\n[www-html] \ +-. nr www-height (\\n[www-height] * 100 / 240) +-. ds www-size-specs "\\*[www-size-specs] height="\\*[www-percentage]"\" +-. \} +-. el \{\ +-. nr www-height \\n[www-absolute] +-. if \\n[www-html] \ +-. nr www-height (\\n[www-height] * 100 / 240) +-. ds www-size-specs "\\*[www-size-specs] height="\\*[www-height]"\" +-. \} +-. \} +-. \} +-. el \{\ +-. \" height not specified; use width value +-. ie !\\n[www-is-absolute] \{\ +-. \" percentage value +-. ds www-size-specs "\\*[www-size-specs] height="\\*[www-percentage]"\" +-. nr www-height \\n[www-width] +-. \} +-. el \{\ +-. ds www-size-specs "\\*[www-size-specs] height="\\*[www-width]"\" +-. nr www-height \\n[www-width] +-. \} +-. \} +-. +-. ie \\n[www-html] \{\ +-. ie !\\n[www-image-just] \ +-. HTML ]" +-. el \ +-. HTML ]" +-. \} +-. el \{\ +-. tm www-width is \\n[www-width] +-. tm www-height is \\n[www-height] +-. if !r ps4html \{\ +-. www-make-unique-name +-. sy pngtopnm \\$1 \ +- | pnmcrop -white \ +- | @PNMTOPS_NOSETPAGE@ -noturn \ +- > \\*[www-unique-name].eps +-. ie !\\n[www-image-just] \{\ +-. \" we must now disable a possible left image trap +-. sp -1 +-. if (\\n[www-left-ll-trap] > 0) \ +-. wh \\n[www-left-ll-trap]u +-. if (\\n[www-left-po-trap] > 0) \ +-. wh \\n[www-left-po-trap]u +-. PSPIC -R \\*[www-unique-name].eps \\n[www-width]u \\n[www-height]u +-. sp -\\n[ps-desht]u +-. +-. nr www-right-indent \\n[ps-deswid]u +-. \" we want to have some space between text and image, +-. \" so the line length must be shorter +-. ll -(\\n[www-right-indent]u + \\n[www-image-gap]u) +-. mk www-right-ll-trap +-. nr www-right-ll-trap +(\\n[ps-desht]u - 1v) +-. wh \\n[www-right-ll-trap]u www-finish-right-ll +-. +-. \" now restore possible left trap +-. if (\\n[www-left-ll-trap] > 0) \ +-. wh \\n[www-left-ll-trap]u www-finish-left-ll +-. if (\\n[www-left-po-trap] > 0) \ +-. wh \\n[www-left-po-trap]u +-. \} +-. el \{\ +-. \" we must now disable a possible right image trap +-. if (\\n[www-right-ll-trap] > 0) \ +-. wh \\n[www-right-ll-trap]u +-. PSPIC -L \\*[www-unique-name].eps \\n[www-width]u \\n[www-height]u +-. sp -\\n[ps-desht]u +-. +-. nr www-left-indent \\n[ps-deswid]u +-. \" increase offset by gap +-. po +(\\n[www-left-indent]u + \\n[www-image-gap]u) +-. \" decrease line length by gap +-. ll -(\\n[www-left-indent]u + \\n[www-image-gap]u) +-. mk www-left-ll-trap +-. nr www-left-ll-trap +(\\n[ps-desht]u - 1v) +-. wh \\n[www-left-ll-trap]u www-finish-left-ll +-. +-. \" now restore possible right trap +-. if (\\n[www-right-ll-trap] > 0) \ +-. wh \\n[www-right-ll-trap]u www-finish-right-ll +-. \} +-. \} +-. \} +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" HnS n +-.\" +-.\" Begin heading. Heading level is N. +-.\" +-.\" HnE +-.\" +-.\" End heading. +-.\" +-.\" If your heading contains URL, FTP, MTO macros you might wish to +-.\" disable automatic links to headings. This can be done via `-P-l' +-.\" from the command line or by using a cakk to `.HX 0'. +-.\" +-.nr www-heading-no -1 +-. +-.de HnS +-. ie '\\$1'' \ +-. nr www-heading-no 1 +-. el \ +-. nr www-heading-no \\$1 +-. DEVTAG-NH \\n[www-heading-no] +-.. +-. +-.de HnE +-. if (\\n[www-heading-no] == -1) \ +-. www-error HnE found without a corresponding HnS +-. DEVTAG-EO-H +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" LK +-.\" +-.\" Emit the automatically collected links derived from +-.\" section/numbered headings at this position. +-.\" +-.de LK +-. DEVTAG .links +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" HR +-.\" +-.\" Produce a horizontal line. +-.\" +-.de HR +-. HTML

    ] +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" NHR +-.\" +-.\" Suppress the generation of the top and bottom rules which grohtml +-.\" emits by default. +-.\" +-.de NHR +-. DEVTAG .no-auto-rule +-.. +-. +-.\" +-.\" www-end-nowhere - end of input trap called to finish diversion. +-.\" +-.de www-end-nowhere +-. if !\\n[www-html] \ +-. di +-. DEVTAG-EO-TL +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" HTL +-.\" +-.\" Generate an HTML title only. This differs from the -ms .TL macro +-.\" which generates both an HTML title and an H1 heading. +-.\" +-.\" This is useful when an author wishes to use an HTML title as search +-.\" engine fodder but a graphic title in the document. +-.\" +-.\" The macro terminates when a space or break is seen (.sp, .br). +-.\" +-.de HTL +-. DEVTAG .html-tl +-. if !\\n[www-html] \ +-. di www-nowhere +-. it 2 www-end-nowhere +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" auxiliary definitions for lists +-.\" +-.ds www-ul-level1 \[bu]\ \ \" +-.ds www-ul-level2 \[sq]\ \ \" +-.ds www-ul-level3 \[ci]\ \ \" +-.nr www-ul-level 0 +-. +-.ds www-ol-level1 decimal\" +-.ds www-ol-level2 lower-alpha\" +-.ds www-ol-level3 lower-roman\" +-.ds www-ol-tmp 00\ \ \" +-.nr www-ol-ctr1 0 1 +-.nr www-ol-ctr2 0 1 +-.nr www-ol-ctr3 0 1 +-.af www-ol-ctr2 a +-.af www-ol-ctr3 i +-.nr www-ol-level 0 +-. +-.nr www-dl-level 0 +-.nr www-dl-shift 5n +-. +-.\" +-.\" allow nested lists +-.\" +-.nr www-depth 0 +-.nr www-li-indent \n[.i] +-.ds www-level0 nop\" +-.ds www-level1 +-.ds www-level2 +-.ds www-level3 +-.ds www-level4 +-.ds www-level5 +-.ds www-level6 +-.ds www-level7 +-.ds www-level8 +-.ds www-level9 +-. +-.\" which macro to use for LI +-.de www-push-li +-. nr www-li-indent \\n[.i] +-. nr www-depth +1 +-. ds www-level\\n[www-depth] \\$1\" +-. ds www-ltag\\n[www-depth] +-. als LI \\$1 +-.. +-. +-.de www-pop-li +-. nr www-depth -1 +-. als LI \\*[www-level\\n[www-depth]] +-.. +-. +-.\" www-emit-ltag - shut down a previous open list tag +-.\" before issuing a new tag \\$1. +-.\" It then records tag \\$1 is open. +-. +-.de www-emit-ltag +-. if !'\\*[www-ltag\\n[www-depth]]'' \ +-. HTML-NS +-. if !'\\$1'' \ +-. HTML-NS <\\$1> +-. ds www-ltag\\n[www-depth] \\$1\" +-.. +-. +-.\" +-.\" Auxiliary macro for ULS. +-.\" +-.de www-push-ul-level +-. nr www-ul-level +1 +-. if (\\n[www-ul-level] > 3) \ +-. www-error ULS: too many levels of indentation (\\n[www-ul-level]) +-.. +-.\" +-.\" Auxiliary macro for ULE. +-.\" +-.de www-pop-ul-level +-. if !\\n[www-ul-level] \ +-. www-error ULE: trying to terminate a list which does not exist +-. nr www-ul-level -1 +-.. +-. +-.\" +-.\" Auxiliary macro for OLS. +-.\" +-.de www-push-ol-level +-. nr www-ol-level +1 +-. if (\\n[www-ol-level] > 3) \ +-. www-error OLS: too many levels of indentation (\\n[www-ol-level]) +-.. +-. +-.\" +-.\" Auxiliary macro for OLE. +-.\" +-.de www-pop-ol-level +-. if !\\n[www-ol-level] \ +-. www-error OLE: trying to terminate a list which does not exist +-. nr www-ol-level -1 +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" ULS +-.\" +-.\" Start an unordered list. +-.\" +-.de ULS +-. www-push-li www-li-ul +-. www-push-ul-level +-. ie \\n[www-html] \{\ +-. www-emit-ltag +-. HTML

      +-. \} +-. el \ +-. nr www-li-indent +\w'\\*[www-ul-level\\n[www-ul-level]]'u +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" ULE +-.\" +-.\" End an unordered list. +-.\" +-.de ULE +-. ie \\n[www-html] \{\ +-. www-emit-ltag +-. HTML

    +-. \} +-. el \{\ +-. nr www-li-indent -\w'\\*[www-ul-level\\n[www-ul-level]]'u +-. in \\n[www-li-indent]u +-. \} +-. www-pop-ul-level +-. www-pop-li +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" OLS +-.\" +-.\" Start an ordered list. +-.\" +-.de OLS +-. www-push-li www-li-ol +-. www-push-ol-level +-. ie \\n[www-html] \{\ +-. www-emit-ltag +-. HTML

      " +-. \} +-. el \ +-. nr www-li-indent +\w'\\*[www-ol-tmp]'u +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" OLE +-.\" +-.\" End an ordered list. +-.\" +-.de OLE +-. ie \\n[www-html] \{\ +-. www-emit-ltag +-. HTML
    +-. \} +-. el \{\ +-. nr www-li-indent -\w'\\*[www-ol-tmp]'u +-. in \\n[www-li-indent]u +-. nr www-ol-ctr\\n[www-ol-level] 0 1 +-. \} +-. www-pop-ol-level +-. www-pop-li +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" DLS +-.\" +-.\" Start a definition list. +-.\" +-.de DLS +-. www-push-li www-li-dl +-. nr www-dl-level +1 +-. ie \\n[www-html] \{\ +-. www-emit-ltag +-. HTML

    +-. \} +-. el \{\ +-. nr www-li-indent +\\n[www-dl-shift]u +-. in \\n[www-li-indent]u +-. \} +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" DLE +-.\" +-.\" End a definition list. +-.\" +-.de DLE +-. ie \\n[www-html] \{\ +-. www-emit-ltag +-. HTML
    +-. \} +-. el \{\ +-. nr www-li-indent -\\n[www-dl-shift]u +-. in \\n[www-li-indent]u +-. \} +-. nr www-dl-level -1 +-. www-pop-li +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" LI +-.\" +-.\" Insert a list item. +-.\" +-. +-.\" ******** +-.\" www-li-ul - bulleted list item +-.\" +-.de www-li-ul +-. ie \\n[www-html] \ +-. www-emit-ltag li +-. el \{\ +-. www:paraspace +-. if rPORPHANS \ +-. ne \\n[PORPHANS]v +-. in \\n[www-li-indent]u +-. ti -\w'\\*[www-ul-level\\n[www-ul-level]]'u +-. nop \\*[www-ul-level\\n[www-ul-level]]\c +-. \} +-.. +-. +-.\" ******** +-.\" www-li-ol - numbered list item +-.\" +-.de www-li-ol +-. ie \\n[www-html] \ +-. www-emit-ltag li +-. el \{\ +-. www:paraspace +-. if rPORPHANS \ +-. ne \\n[PORPHANS]v +-. in \\n[www-li-indent]u +-. ti -\w'\\n+[www-ol-ctr\\n[www-ol-level]]\ \ 'u +-. nop \\n[www-ol-ctr\\n[www-ol-level]]\ \ \c +-. \} +-.. +-. +-.\" ******** +-.\" www-li-dl - definition list item +-.\" +-.de www-li-dl +-. ie \\n[www-html] \{\ +-. HTML
    \\$1
    +-. www-emit-ltag dd +-. \} +-. el \{\ +-. www:paraspace +-. if rPORPHANS \ +-. ne \\n[PORPHANS]v +-. in \\n[www-li-indent]u +-. ti -\\n[www-dl-shift]u +-. nop \&\\$1 +-. br +-. \} +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" DC l text [color] +-.\" +-.\" L is the letter to be dropped and enlarged. +-.\" +-.\" TEXT is the following text whose height the first letter should not +-.\" exceed. +-.\" +-.\" COLOR is the optional color of the dropped letter (default black). +-.\" +-.de DC +-. ds www-dropcolor black\" +-. if !'\\$3'' \ +-. ds www-dropcolor \\$3\" +-. ie '\*[.T]'html' \{\ +-. www-make-unique-name +-. nr www-drop-width (100u * \\n[.v]u * 3u / \\n[.l]u) +-. MPIMG -L \\*[www-unique-name].png \\n[www-drop-width]% +-. \} +-. el \{\ +-. ie r ps4html \{\ +-. www-make-unique-name +-. \" To avoid interferences with another DC macro call which is located +-. \" very near to the current one, we draw the glyph on a separate page. +-. \" Otherwise it could theoretically happen that the dropped capital +-. \" glyphs overlap. +-. bp +-. ev www-DC +-. vs 320p +-. nop \O[5i\\*[www-unique-name].png]\O[1] +-. nop \m[\\*[www-dropcolor]]\s[160]\O[3]\\$1\O[4] +-. nop \O[2]\O[0] +-. br +-. ev +-. bp +-. \} +-. el \{\ +-. ie n \ +-. nop \\$1\c +-. el \{\ +-. nr dummy \w'\\$1'u +-. nr dcht ((\\n[.v] + \\n[rst]) * \\n[.ps] / \\n[rst]) +-. char \[dcap] \m[\\*[www-dropcolor]]\s'\\n[dcht]u'\\$1 +-. nop \v'\\n[.v]u'\\[dcap]\v'-\\n[.v]u'\c +-' ti \w'\\[dcap]'u +-. \} +-. \} +-. \} +-. nop \\$2 +-.. +-. +-.\" +-.\" supplementary macros used by other macro sets +-.\" +-.\" here are some tags specially for -Tps or -Thtml when invoked by +-.\" pre-html to generate PNG images from postscript. +-. +-.\" -------------------------------------------------------------------- +-.\" HTML-DO-IMAGE - tell troff to issue an image marker which can be +-.\" read back by pre-html +-.\" +-.de HTML-DO-IMAGE +-. if r ps4html \ +-. nop \O[5\\$2\\$1.png]\O[1]\O[3] +-. if \\n[www-html] \ +-. nop \O[5\\$2\\$1.png]\O[0]\O[3] +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" HTML-IMAGE-END - terminate an image for HTML +-.\" +-.de HTML-IMAGE-END +-. if r ps4html \ +-. nop \O[4]\O[2]\O[0] +-. if \\n[www-html] \ +-. nop \O[4]\O[2]\O[1] +-.. +-. +-.nr www-png-no 0 +-. +-.\" -------------------------------------------------------------------- +-.\" www-make-unique-name - generate another unique name in string +-.\" `www-unique-name' +-.\" +-.de www-make-unique-name +-. nr www-png-no +1 +-. ds www-unique-name \\*[www-image-template]\\n[www-png-no]\" +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" HTML-IMAGE and friends tell grohtml that this region of text needs +-.\" to be rendered as an image. +-.\" +-.de HTML-IMAGE +-. \" generates a centered image +-. www-make-unique-name +-. HTML-DO-IMAGE \\*[www-unique-name] c +-.. +-. +-.de HTML-IMAGE-RIGHT +-. www-make-unique-name +-. HTML-DO-IMAGE \\*[www-unique-name] r +-.. +-. +-.de HTML-IMAGE-LEFT +-. www-make-unique-name +-. HTML-DO-IMAGE \\*[www-unique-name] l +-.. +-. +-.de HTML-IMAGE-INLINE +-. www-make-unique-name +-. HTML-DO-IMAGE \\*[www-unique-name] i +-.. +-. +-.\" EQN-HTML-IMAGE and friends check to see whether the equation is +-.\" not in an image, in which case it allows HTML +-.\" (mathml) to be generated (if -Txhtml was specified). +-. +-.de EQN-HTML-IMAGE +-. \" generates a centered image +-. www-make-unique-name +-. EQN-HTML-DO-IMAGE \\*[www-unique-name] c +-.. +-. +-.de EQN-HTML-IMAGE-RIGHT +-. www-make-unique-name +-. EQN-HTML-DO-IMAGE \\*[www-unique-name] r +-.. +-. +-.de EQN-HTML-IMAGE-LEFT +-. www-make-unique-name +-. EQN-HTML-DO-IMAGE \\*[www-unique-name] l +-.. +-. +-.de EQN-HTML-IMAGE-INLINE +-. www-make-unique-name +-. EQN-HTML-DO-IMAGE \\*[www-unique-name] i +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" EQN-HTML-DO-IMAGE - tell troff to issue an image marker which can be +-.\" read back by pre-html +-.\" +-.de EQN-HTML-DO-IMAGE +-. ie r xhtml \{\ +-. if !(\\n[.O] == 0) \{\ +-. if r ps4html \ +-. nop \O[5\\$2\\$1.png]\O[1]\O[3] +-. if \\n[www-html] \ +-. nop \O[5\\$2\\$1.png]\O[0]\O[3] +-. \} +-. \} +-. el \ +-. HTML-DO-IMAGE \\$* +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" EQN-HTML-IMAGE-END - terminate an image for HTML +-.\" +-.de EQN-HTML-IMAGE-END +-. ie r xhtml \{\ +-. if !(\\n[.O] == 0) \{\ +-. if r ps4html \ +-. nop \O[4]\O[2]\O[0] +-. if \\n[www-html] \ +-. nop \O[4]\O[2]\O[1] +-. \} +-. \} +-. el \ +-. HTML-IMAGE-END +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" Setup around HTML-IMAGE and friends +-.\" +-.\" now set up TS, TE, EQ, EN default macros +-.\" +-.\" we must not use `.als': the definition of .TE in s.tmac, for example, +-.\" calls .HTML-IMAGE-END, which would refer to itself due to the alias, +-.\" causing an endless loop +-.\" +-.if !d TS \{\ +-. de TS +-. HTML-IMAGE \\$@ +-. if \\n[www-html] \{\ +-. nr www-TS-ll \\n[.l] +-. ll 1000n +-. \} +-. . +-.\} +-.if !d TE \{\ +-. de TE +-. if \\n[www-html] \ +-. ll \\n[www-TS-ll]u +-. HTML-IMAGE-END \\$@ +-. . +-.\} +-.if !d EQ \{\ +-. de EQ +-. EQN-HTML-IMAGE \\$@ +-. if \\n[www-html] \{\ +-. nr www-EQ-ll \\n[.l] +-. ll 1000n +-. \} +-. . +-.\} +-.if !d EN \{\ +-. de EN +-. if \\n[www-html] \ +-. ll \\n[www-EQ-ll]u +-. EQN-HTML-IMAGE-END \\$@ +-. . +-.\} +-. +-.\" -------------------------------------------------------------------- +-.\" JOBNAME +-.\" +-.\" Generate multiple output files containing the HTML. +-.\" A file is split whenever a .SH or .NH 1 is encountered. +-.\" The argument to JOBNAME is the file stem for future output files. +-.\" +-.de JOBNAME +-. DEVTAG .job-name \\$1 +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" HEAD +-.\" +-.\" Add information to the section of the HTML +-.\" document +-.\" +-.de HEAD +-. DEVTAG .head "\\$*" +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" start of some code +-.\" +-.de CDS +-. ft C +-. nf +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" end of some code +-.\" +-.de CDE +-. fi +-. ft P +-.. +-. +-.ds www-nav-colour #eeeeee\" +-.nr www-nav-width-left 30 +-.nr www-nav-width-right 70 +-. +-.\" -------------------------------------------------------------------- +-.\" LNS - left navigation start +-.\" +-.de LNS +-. HTML

    " +-. LK +-. HTML

    " +-. nr SH-open 1 +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" LNE - left navigation end +-.\" +-.de LNE +-. HTML

    +-. HR +-.. +-. +-.nr SH-open 0 +-.nr needs-begin 0 +-. +-.\" +-.\" some auxiliary macros for left navigation lists +-.\" +-.de www-SH +-. if (0\\$1 == 0) \{\ +-. if (\\n[SH-open] == 1) \ +-. LNE +-. nr needs-begin 1 +-. @SH-old +-. \} +-.. +-. +-.de www-NH +-. if (0\\$1 <= 1) \{\ +-. if (\\n[SH-open] == 1) \ +-. LNE +-. nr needs-begin 1 +-. @NH-old +-. \} +-.. +-. +-.de www-LP +-. @LP-old +-. if (\\n[needs-begin] == 1) \{\ +-. HR +-. LNS +-. \} +-. nr needs-begin 0 +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" ALN [colour] [left width percentage] +-.\" +-.\" Turn on automatic left navigation. This macro should only be +-.\" called once (normally at the start of the document) as it +-.\" indicates that all top-level section headings form a navigation +-.\" list on the left of the main text. +-.\" +-.de ALN +-. if '\*[.T]'html' \{\ +-. if !'\\$1'' \ +-. ds www-nav-colour \\$1\" +-. if (0\\$2 > 0) \{\ +-. nr www-nav-width-left \\$2 +-. nr www-nav-width-right (100 - \\$2) +-. \} +-. rn @SH @SH-old +-. rn www-SH @SH +-. rn @NH @NH-old +-. rn www-NH @NH +-. rn @LP @LP-old +-. rn www-LP @LP +-. \} +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" LINKSTYLE color [fontstyle [openglyph closeglyph]] +-.\" +-.\" Initialize www.tmac so that when this macro set is used with +-.\" non-HTML devices the urls are rendered the user defined attributes. +-.\" For example: +-.\" +-.\" LINKSTYLE blue CR < > +-.\" +-.de LINKSTYLE +-. if (\\n[.$] < 1) \ +-. www:error .\\$0 expects at least 1 argument. +-. ds www:color \\$1\" +-. shift +-. if (\\n[.$] < 1) \ +-. return +-. ds www:fontstyle \\$1\" +-. shift +-. if (\\n[.$] < 1) \ +-. www:error .\\$0 expects that both the open and close glyph is specified +-. ds www:open \\$1\" +-. ds www:close \\$2\" +-.. +-. +-.\" MATHML - enable eqn mathml output to pass through to the device +-.\" driver +-. +-.de MATHML +-. if (\\n[.O] == 0) \ +-. MATH \\$* +-.. +-. +-.\" -------------------------------------------------------------------- +-.\" final setup +-.\" -------------------------------------------------------------------- +-. +-.LINKSTYLE blue C \[la] \[ra] +-. +-.if \n[www-html] \{\ +-. nh +-. nr HY 0 +-.\} +-. +-.if r ps4html .nop \O[0] +-.cp \n(_C +-. +-.\" now set +-. +-.\" -------------------------------------------------------------------- +-.\" Emacs settings +-.\" -------------------------------------------------------------------- +-. +-.\" Local Variables: +-.\" mode: nroff +-.\" End: +-.\" EOF +diff -Nuar groff-1.22.3.old/tmac/www.tmac.in groff-1.22.3/tmac/www.tmac.in +--- groff-1.22.3.old/tmac/www.tmac.in 1970-01-01 02:00:00.000000000 +0200 ++++ groff-1.22.3/tmac/www.tmac.in 2015-04-23 20:57:03.000000000 +0300 +@@ -0,0 +1,1625 @@ ++.ig ++www.tmac - macro package for adding HTML elements to roff documents. ++ ++File position: /tmac/www.tmac ++Installed position: groff's main macro directory. ++ ++------------------------------------------------------------------------ ++ Legalese ++------------------------------------------------------------------------ ++ ++This file is part of groff, the GNU roff type-setting system. ++ ++Copyright (C) 2001-2014 Free Software Foundation, Inc. ++written by Gaius Mulley , with additions by ++Werner Lemberg and ++Bernd Warken . ++ ++groff is free software; you can redistribute it and/or modify it under ++the terms of the GNU General Public License as published by the Free ++Software Foundation, either version 3 of the License, or ++(at your option) any later version. ++ ++groff is distributed in the hope that it will be useful, but WITHOUT ++ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program. If not, see . ++ ++ ++------------------------------------------------------------------------ ++ Description ++------------------------------------------------------------------------ ++ ++A simple set of macros to provide HTML (or XHTML) documents with basic ++www functionality. It should work with any macro set. In the following, ++HTML always denotes XHTML also. ++.. ++. ++. ++.\" -------------------------------------------------------------------- ++.\" Setup ++.\" -------------------------------------------------------------------- ++. ++.do if d www:lenstr .nx ++. ++.do mso devtag.tmac ++. ++.nr _C \n(.C ++.cp 0 ++. ++. ++.ie r xhtml \ ++. ds www-> />\" ++.el \ ++. ds www-> >\" ++. ++.nr www-html 0 ++.if '\*[.T]'html' \ ++. nr www-html 1 ++. ++.\" set up www-image-template ++. ++.if !d www-image-template \ ++. ds www-image-template ++. ++.if r ps4html \{\ ++. \" remove the title command when we are generating images for HTML ++. \" (stops a title accidentally appearing inside an image) ++. di www-notitle ++. tl '''' ++. di ++. rm tl ++. de tl ++. . ++.\} ++. ++. ++.\" -------------------------------------------------------------------- ++.\" Test for `.substring'; result in register `www.substring_ok'. ++.\" The automated break points in .URL addresses are only added if ++.\" this register is non-zero. ++.\" ++.nr www:substring_ok 0 ++.de www:@test_substring ++. if !d substring \ ++. return ++. ds \\$0:s abcdefg\" ++. substring \\$0:s 1 1 ++. if !'\\*[\\$0:s]'b' \{\ ++. rm \\$0:s ++. return ++. \} ++. ds \\$0:s abcdefg\" ++. substring \\$0:s 0 0 ++. if !'\\*[\\$0:s]'a' \{\ ++. rm \\$0:s ++. return ++. \} ++. ds \\$0:s abcdefg\" ++. substring \\$0:s 1 -1 ++. if !'\\*[\\$0:s]'bcdefg' \{\ ++. rm \\$0:s ++. return ++. \} ++. nr www:substring_ok 1 ++. rm \\$0:s ++.. ++.www:@test_substring ++.rm www:@test_substring ++. ++. ++.\" -------------------------------------------------------------------- ++.\" Local Macros ++.\" -------------------------------------------------------------------- ++. ++.\" -------------------------------------------------------------------- ++.\" www:paraspace ++.\" ++.\" Space before paragraph. Use \n[PD] if it exists. ++.\" ++.nr www:pd 0.5v ++. ++.de www:paraspace ++. ie r PD \ ++. sp \\n[PD]u ++. el \ ++. sp \\n[www:pd]u ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" www:error (...) ++.\" ++.\" Print error message. ++.\" ++.de www-error ++. tm \\n[.F]:\\n[.c]: macro error: \\$* ++.. ++. ++.als www:error www-error ++. ++.\" -------------------------------------------------------------------- ++.\" www:lenstr ( ) ++.\" ++.\" Store length of string named into register named ++.\" . ++.\" ++.de www:lenstr ++. if !(\\n[.$] == 2) \{\ ++. tm .\\$0 expects 2 arguments. ++. ab ++. \} ++. length \\$0:n x\\*[\\$2] ++. nr \\$1 (\\n[\\$0:n] - 1) ++. rr \\$0:n ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" www:splitstr () ++.\" ++.\" Add a space character between any two adjacent characters in string ++.\" and restore result into the string variable ; space ++.\" characters are first replaced by the word `space'. ++.\" ++.de www:splitstr ++. if !(\\n[.$] == 1) \ ++. www:error .\\$0 expects 1 argument. ++. if '\\*[\\$1]'' \ ++. return ++. ds \\$0:r "\\*[\\$1]\" ++. ds \\$0:s ++. while 1 \{\ ++. ds \\$0:c "\\*[\\$0:r]\" ++. substring \\$0:c 0 0 ++. ie '\\*[\\$0:c]' ' \ ++. as \\$0:s " space\" ++. el \ ++. as \\$0:s " \\*[\\$0:c]\" ++. www:lenstr \\$0:n \\$0:r ++. if (\\n[\\$0:n] <= 1) \ ++. break ++. substring \\$0:r 1 -1 ++. \} ++. if !'\\*[\\$0:s]'' \ ++. substring \\$0:s 1 -1 ++. ds \\$1 \\*[\\$0:s]\" ++. rm \\$0:c ++. rr \\$0:n ++. rm \\$0:r ++. rm \\$0:s ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" www:url_breaks () ++.\" ++.\" Add `\:' (possible break point) within URL strings after `/'. ++.\" ++.\" Smart about multiple `/', existing `\:', and space characters; ++.\" does not set a break point if less than 5 characters would go to ++.\" the next line. ++.\" ++.de www:url_breaks ++. if !(\\n[.$] == 1) \ ++. www:error .\\$0 expects 1 argument. ++. if !\n[www:substring_ok] \ ++. return ++. ds \\$0:s "\\*[\\$1]\" ++. www:splitstr \\$0:s ++. www:url_breaks_split \\$0:s \\*[\\$0:s] ++. ds \\$1 "\\*[\\$0:s]\" ++. rm \\$0:s ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" www:url_breaks_split ( [...]) ++.\" ++.\" Add `\:' within URL strings, but arguments are a split string. ++.\" ++.\" Arguments: >=2: [...] ++.\" ++.de www:url_breaks_split ++. nr \\$0:min 5 \" minimal number of characters for next line ++. if (\\n[.$] < 2) \ ++. www:error .\\$0 expects at least 2 arguments. ++. ds \\$0:res \\$1\" ++. shift ++. ds \\$0:s ++. nr \\$0:done 0 ++. while !\\n[\\$0:done] \{\ ++. if (\\n[.$] <= 0) \ ++. break ++. if '\\$1'space' \{\ ++. as \\$0:s " \" ++. shift ++. continue ++. \} ++. if (\\n[.$] < \\n[\\$0:min]) \{\ ++. as \\$0:s "\\$1\" ++. shift ++. continue ++. \} ++. if !'\\$1'/' \{\ ++. as \\$0:s "\\$1\" ++. shift ++. continue ++. \} ++. \" we are at a `/' character ++. while '\\$1'/' \{\ ++. as \\$0:s /\" ++. if (\\n[.$] == 0) \{\ ++. nr \\$0:done 1 ++. break ++. \} ++. shift ++. \} ++. if \\n[\\$0:done] \ ++. break ++. if (\\n[.$] < \\n[\\$0:min]) \ ++. continue ++. if '\\$1'\:' \ ++. shift ++. as \\$0:s \:\" ++. \} ++. ds \\*[\\$0:res] \\*[\\$0:s]\" ++. rm \\$0:res ++. rm \\$0:s ++.. ++. ++. ++.\" -------------------------------------------------------------------- ++.\" User Interface ++.\" -------------------------------------------------------------------- ++. ++.\" -------------------------------------------------------------------- ++.\" HTML ++.\" ++.\" The main auxiliary macro for the HTML interface. ++.\" ++.de HTML ++. if \\n[www-html] \{\ ++. \" was implemented via .nop \&\X^html:\\$*^ but ++. \" is now implemented using HTML-NS to utilize code factoring. ++. \" ++. \" the `\&' makes the vertical mode leave, so to say ++. \" ++. nop \&\c ++. HTML-NS \\$* ++. nop \& ++. \} ++.. ++. ++.\" ++.\" An auxiliary macro for HTML (without following space). ++.\" ++.de HTML-NS ++. nop \X^html:\\$*^\c ++.. ++. ++.\" ++.\" Emit an HTML tag after shutting down a (possibly open) paragraph. ++.\" ++.de HTML

    ++. ie \\n[www-html] \{\ ++. \" the `\&' makes the vertical mode leave, so to say ++. nop \&\X^html

    :\\$*^ ++. \} ++. el \ ++. www:paraspace ++.. ++. ++.\" ++.\" Emit an HTML tag. If text has been written in the paragraph ++.\" then do not shut the paragraph down. ++.\" If text was not written, remove the empty ++.\" paragraph tag and emit the desired HTML tag. ++.\" ++.de HTML ++. if \\n[www-html] \ ++. nop \&\X^html:\\$*^ ++.. ++. ++.\" ++.\" Emit a MATH tag. If text has been written in the paragraph ++.\" then do not shut the paragraph down. ++.\" If text was not written, remove the empty ++.\" paragraph tag and emit the desired math tag. ++.\" ++.de MATH ++. if \\n[www-html] \ ++. nop \&\X^math:\\$*^ ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" HX n ++.\" ++.\" Automatic heading level cut off. ++.\" ++.\" N is the depth limit of automatically linked headings. So a depth ++.\" of 2 would cause grohtml to generate a list of links for `.NH 1' ++.\" and `.NH 2' but not for `.NH 3'. ++.\" ++.de HX ++. if \\n[www-html] \ ++. nop \X^index:\\$*^ ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" BCL foreground background active not-visited visited ++.\" ++.de BCL ++. HTML " ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" BGIMG imagefile ++.\" ++.de BGIMG ++. HTML " ++.. ++. ++.\" www:url_check_tag str ++.\" If url named by \*[str] is internal (starts with #), ++.\" redefine \*[str] to be the value of the string TAG_url. ++. ++.de www:url_check_tag ++. ds \\$0:tmp \\*[\\$1]\" ++. substring \\$0:tmp 0 0 ++. if '\\*[\\$0:tmp]'#' \{\ ++. ds \\$0:tmp \\*[\\$1]\" ++. substring \\$0:tmp 1 ++. ds \\$0:tmp TAG_\\*[\\$0:tmp]\" ++. ++. ie d \\*[\\$0:tmp] \ ++. ds \\$1 \\*[\\*[\\$0:tmp]]\" ++. el \ ++. ds \\$1 see below\" ++. \} ++. rm \\$0:tmp ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" URL url [description] [after] ++.\" ++.\" If description is absent then the url becomes the anchor text. ++.\" ++.de URL ++. if !'\\$1'' \{\ ++. ds \\$0:adr \\$1\" ++. www:url_check_tag \\$0:adr ++. if !\\n[www-html] \ ++. www:url_breaks \\$0:adr ++. \} ++. ie \\n[www-html] \{\ ++. ie '\\$3'' \ ++. ds \\$0:after \&\" ++. el \ ++. ds \\$0:after \&\\$3\" ++. ++. ie '\\$2'' \ ++. HTML-NS \\*[\\$0:adr]" ++. el \ ++. HTML-NS \\$2" ++. ++. nop \\*[\\$0:after] ++. rm \\$0:after ++. \} ++. el \{\ ++. if !r ps4html \ ++. ad l ++. ++. ie '\\$2'' \{\ ++. ie '\\$1'' \{\ ++. if !'\\$3'' \ ++. nop \\$3 ++. \} ++. el \{\ ++. ie \\n[.color] \ ++. nop \%\\*[www:open]\m[\\*[www:color]]\f[\\*[www:fontstyle]]\\*[\\$0:adr]\f[]\m[]\\*[www:close]\\$3 ++. el \ ++. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\*[\\$0:adr]\f[]\\*[www:close]\\$3 ++. \} ++. \} ++. el \{\ ++. ie '\\$1'' \{\ ++. ie \\n[.color] \ ++. nop \m[\\*[www:color]]\\$2\m[]\\$3 ++. el \ ++. nop \f[\\*[www:fontstyle]]\\$2\f[]\\$3 ++. \} ++. el \{\ ++. ie \\n[.color] \{\ ++. nop \m[\\*[www:color]]\\$2\m[] ++. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\*[\\$0:adr]\f[]\\*[www:close]\\$3 ++. \} ++. el \{\ ++. nop \f[\\*[www:fontstyle]]\\$2\f[] ++. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\*[\\$0:adr]\f[]\\*[www:close]\\$3 ++. \} ++. \} ++. \} ++. ++. if !r ps4html \ ++. ad ++. \} ++. rm \\$0:adr ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" FTP url description [after] ++.\" ++.\" Same as URL. ++.\" ++.als FTP URL ++. ++.\" -------------------------------------------------------------------- ++.\" MTO address description [after] ++.\" ++.\" ADDRESS is the email address (without the `mailto:' prefix). ++.\" ++.\" DESCRIPTION is the optional name. If an empty argument is given, ++.\" ADDRESS is used instead. ++.\" ++.\" AFTER is optional stuff printed immediately after ADDRESS ++.\" (resp. DESCRIPTION). ++.\" ++.\" Example: ++.\" ++.\" Foobar has been written by ++.\" .MTO fred@foo.bar "Fredrick Bloggs" . ++.\" ++.de MTO ++. ie \\n[www-html] \{\ ++. ie '\\$2'' \ ++. URL mailto:\\$1 \\$1 "\\$3" ++. el \ ++. URL mailto:\\$1 "\\$2" "\\$3" ++. \} ++. el \{\ ++. ie '\\$2'' \{\ ++. ie '\\$1'' \{\ ++. ie !'\\$3'' \ ++. nop \\$3 ++. \} ++. el \{\ ++. ie \\n[.color] \ ++. nop \%\m[\\*[www:color]]\f[\\*[www:fontstyle]]\\$1\f[]\m[]\\$3 ++. el \ ++. nop \%\f[\\*[www:fontstyle]]\\$1\f[]\\$3 ++. \} ++. \} ++. el \{\ ++. ie '\\$1'' \{\ ++. ie \\n[.color] \ ++. nop \m[\\*[www:color]]\\$2\m[]\\$3 ++. el \ ++. nop \f[\\*[www:fontstyle]]\\$2\f[]\\$3 ++. \} ++. el \{\ ++. ie \\n[.color] \{\ ++. nop \m[\\*[www:color]]\\$2\m[] ++. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\$1\f[]\\*[www:close]\\$3 ++. \} ++. el \{\ ++. nop \f[\\*[www:fontstyle]]\\$2\f[] ++. nop \%\\*[www:open]\f[\\*[www:fontstyle]]\\$1\f[]\\*[www:close]\\$3 ++. \} ++. \} ++. \} ++. \} ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" TAG name [text] ++.\" ++.\" Generate an HTML name NAME. ++.\" Define string TAG_NAME to TEXT, if present, otherwise to \n[PN]. ++.\" Register PN is the current page number. ++.\" ++.de TAG ++. HTML " ++. ie '\\$2'' \ ++. if !rPN \ ++. nr PN \\n% ++. ds TAG_\\$1 \\n[PN]\" ++. el \ ++. ds TAG_\\$1 \\$2\" ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" IMG [-R|-L|-C] filename [width] [height] ++.\" ++.\" Include an image of any type (only works for -Thtml). ++.\" ++.\" Alignment is centered by default (-C). ++.\" Default value for WIDTH is 1i. ++.\" If HEIGHT is not given, WIDTH is used as the height. ++.\" ++.de IMG ++. ie \\n[www-html] \{\ ++. ie '\\$2'-R' \ ++. DEVTAG .right-image ++. el \{\ ++. ie '\\$2'-L' \ ++. DEVTAG .left-image ++. el \ ++. DEVTAG .centered-image ++. \} ++. nr www-width 100 ++. if !'\\$3'' \ ++. nr www-width \\$3 ++. nr www-height \\n[www-width] ++. if !'\\$4'' \ ++. nr www-height \\$4 ++. HTML ]" ++. \} ++. el \ ++. nop \\*[www:open]\f[\\*[www:fontstyle]]\\$1\f[]\\*[www:close] ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" PIMG [-R|-L|-C] filename [width] [height] ++.\" ++.\" Include a PNG image. It works for -Tps and -Thtml. ++.\" The default value for WIDTH and HEIGHT is zero; the default ++.\" alignment is centering (-C). ++.\" ++.\" Note: This macro can only be used with the `-U' option of groff, ++.\" activating unsafe mode, if not used with -Thtml; the PNG image ++.\" is then converted to the EPS format using netpbm utilities. ++.\" ++.de PIMG ++. ds www-pic-align -C\" ++. ie '\\$1'-R' \{\ ++. ds www-pic-align -R\" ++. shift ++. \} ++. el \{\ ++. if '\\$1'-L' \{\ ++. ds www-pic-align -L\" ++. shift ++. \} ++. \} ++. if '\\$1'-C' \ ++. shift ++. ++. ie \\n[www-html] \{\ ++. ds www-htmlalign align="center"\" ++. if '\\*[www-pic-align]'-R' \ ++. ds www-htmlalign align="right"\" ++. if '\\*[www-pic-align]'-L' \ ++. ds www-htmlalign align="left"\" ++. ++. nr www-width 0 ++. nr www-height 0 ++. if !'\\$2'' \ ++. nr www-width (\\$3 * 100 / 240) ++. if !'\\$3'' \ ++. nr www-height (\\$4 * 100 / 240) ++. ie (\\n[www-width] == 0) \{\ ++. ie (\\n[www-height] == 0) \ ++. HTML

    ]

    " ++. el \ ++. HTML

    ]

    " ++. \} ++. el \{\ ++. ie (\\n[www-height] == 0) \ ++. HTML

    ]

    " ++. el \ ++. HTML

    ]

    " ++. \} ++. \} ++. el \{\ ++. if !r ps4html \{\ ++. www-make-unique-name ++. sy pngtopnm \\$1 \ ++ | pnmcrop -white \ ++ | @PNMTOPS_NOSETPAGE@ -noturn \ ++ > \\*[www-unique-name].eps ++. shift ++. PSPIC \\*[www-pic-align] \\*[www-unique-name].eps \\$* ++. \} ++. \} ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" auxiliary definitions for MPIMG ++.\" ++.nr www-left-ll-trap 0 ++.nr www-left-po-trap 0 ++.nr www-right-ll-trap 0 ++. ++.de www-finish-left-po ++. po -(\\n[www-left-indent]u + \\n[www-image-gap]u) ++. wh \\n[www-left-po-trap]u ++. nr www-left-indent 0 ++.. ++. ++.\" called when the -R picture is finished ++.de www-finish-right-ll ++. ll +(\\n[www-right-indent]u + \\n[www-image-gap]u) ++. ++. \" now check whether we need to inline www-finish-left-ll ++. if (\\n[www-left-ll-trap]u > 0) \ ++. if ((\\n[www-right-ll-trap]u + 1v) >= \\n[www-left-ll-trap]u) \{\ ++. mk www-left-po-trap ++. nr www-left-po-trap +1v ++. wh \\n[www-left-po-trap]u www-finish-left-po ++. ll +\\n[www-left-indent]u ++. wh \\n[www-left-ll-trap]u ++. nr www-left-ll-trap 0 ++. \} ++. ++. \" and check whether we need to inline www-finish-left-po ++. if (\\n[www-left-po-trap]u > 0) \ ++. if ((\\n[www-right-ll-trap]u + 1v) >= \\n[www-left-po-trap]u) \{\ ++. po -\\n[www-left-indent]u ++. wh \\n[www-left-po-trap]u ++. nr www-left-indent 0 ++. \} ++. ++. wh \\n[www-right-ll-trap]u ++. nr www-right-ll-trap 0 ++.. ++. ++.de www-finish-left-ll ++. if (\\n[www-right-ll-trap] > 0) \ ++. if ((\\n[www-left-ll-trap] + 1v) >= \\n[www-right-ll-trap]) \{\ ++. ll +\\n[www-right-indent]u ++. nr www-right-ll-trap 0 ++. \} ++. ++. mk www-left-po-trap ++. nr www-left-po-trap +1v ++. wh \\n[www-left-po-trap]u www-finish-left-po ++. ll +(\\n[www-left-indent]u + \\n[www-image-gap]u) ++. wh \\n[www-left-ll-trap]u ++. nr www-left-ll-trap 0 ++.. ++. ++.\" www-handle-percent arg N1 N2 S1 ++.\" arg - input string (number or number%) ++.\" output parameters: ++.\" N1 - name of number register 1=absolute 0=percentage ++.\" N2 - number register name for absolute value ++.\" S1 - string register name for percentage value ++.\" ++.de www-handle-percent ++. ds www-percent \\$1\" ++. substring www-percent -1 -1 ++. ++. ie '\\*[www-percent]'%' \{\ ++. ds www-abs \\$1\" ++. substring www-abs 0 -2 ++. nr \\$2 0 ++. nr \\$3 \\*[www-abs] ++. ds \\$4 \\$1\" ++. \} ++. el \{\ ++. nr \\$2 1 ++. nr \\$3 \\$1 ++. ds \\$4 none\" ++. \} ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" MPIMG [-R|-L] [-G gap] filename [width [height]] ++.\" ++.\" Include a PNG image and wrap text around it. It works for ++.\" -Tps and -Thtml. The default value for WIDTH is 1i; default value ++.\" for HEIGHT is WIDTH; the default alignment is left (-L). ++.\" -G is used to insert a gap between the text and the image. ++.\" The height and width can also be given as a percentage. ++.\" The PostScript device converts the percentage width into an ++.\" absolute value by using \\n[.l], and the height by using \\n[.p]. ++.\" ++.\" ++.\" Note: This macro can only be used with the `-U' option of groff, ++.\" activating unsafe mode, if not used with -Thtml; the PNG image ++.\" is then converted to the EPS format using netpbm utilities. ++.\" ++.nr www-htmlimage-gap 0 ++. ++.de MPIMG ++. nr www-image-just 1 ++. nr www-image-gap 0 ++. while (\\n[.$] > 0) \{\ ++. if '-L'\\$1' \{\ ++. nr www-image-just 1 ++. shift ++. continue ++. \} ++. if '-R'\\$1' \{\ ++. nr www-image-just 0 ++. shift ++. continue ++. \} ++. if '-G'\\$1' \{\ ++. nr www-image-gap \\$2 ++. nr www-htmlimage-gap (\\$2 * 100 / 240) ++. shift 2 ++. continue ++. \} ++. break ++. \} ++. ++. nr www-width 1i ++. nr www-height 1i ++. ds www-size-specs width="\\n[www-width]" height="\\n[www-height]"\" ++. ie !'\\$2'' \{\ ++. nr www-is-absolute 0 ++. nr www-absolute 0 ++. ds www-percentage none\" ++. www-handle-percent \\$2 www-is-absolute www-absolute www-percentage ++. ie !\\n[www-is-absolute] \{\ ++. \" percentage of linelength requested ++. nr www-width (\\n[www-absolute] * \\n[.l] / 100) ++. if \\n[www-html] \ ++. nr www-width (\\n[www-width] * 100 / 240) ++. ds www-size-specs width="\\*[www-percentage]"\" ++. \} ++. el \{\ ++. nr www-width \\n[www-absolute] ++. if \\n[www-html] \ ++. nr www-width (\\n[www-width] * 100 / 240) ++. ds www-size-specs width="\\n[www-width]"\" ++. \} ++. ++. nr www-height \\n[www-width] ++. ie !'\\$3'' \{\ ++. nr www-is-absolute 0 ++. nr www-absolute 0 ++. ds www-percentage none\" ++. www-handle-percent \\$3 www-is-absolute www-absolute www-percentage ++. ie !\\n[www-is-absolute] \{\ ++. \" percentage of pagelength requested ++. nr www-height (\\n[www-absolute] * \\n[.p] / 100) ++. if \\n[www-html] \ ++. nr www-height (\\n[www-height] * 100 / 240) ++. ds www-size-specs "\\*[www-size-specs] height="\\*[www-percentage]"\" ++. \} ++. el \{\ ++. nr www-height \\n[www-absolute] ++. if \\n[www-html] \ ++. nr www-height (\\n[www-height] * 100 / 240) ++. ds www-size-specs "\\*[www-size-specs] height="\\*[www-height]"\" ++. \} ++. \} ++. \} ++. el \{\ ++. \" height not specified; use width value ++. ie !\\n[www-is-absolute] \{\ ++. \" percentage value ++. ds www-size-specs "\\*[www-size-specs] height="\\*[www-percentage]"\" ++. nr www-height \\n[www-width] ++. \} ++. el \{\ ++. ds www-size-specs "\\*[www-size-specs] height="\\*[www-width]"\" ++. nr www-height \\n[www-width] ++. \} ++. \} ++. ++. ie \\n[www-html] \{\ ++. ie !\\n[www-image-just] \ ++. HTML ]" ++. el \ ++. HTML ]" ++. \} ++. el \{\ ++. tm www-width is \\n[www-width] ++. tm www-height is \\n[www-height] ++. if !r ps4html \{\ ++. www-make-unique-name ++. sy pngtopnm \\$1 \ ++ | pnmcrop -white \ ++ | @PNMTOPS_NOSETPAGE@ -noturn \ ++ > \\*[www-unique-name].eps ++. ie !\\n[www-image-just] \{\ ++. \" we must now disable a possible left image trap ++. sp -1 ++. if (\\n[www-left-ll-trap] > 0) \ ++. wh \\n[www-left-ll-trap]u ++. if (\\n[www-left-po-trap] > 0) \ ++. wh \\n[www-left-po-trap]u ++. PSPIC -R \\*[www-unique-name].eps \\n[www-width]u \\n[www-height]u ++. sp -\\n[ps-desht]u ++. ++. nr www-right-indent \\n[ps-deswid]u ++. \" we want to have some space between text and image, ++. \" so the line length must be shorter ++. ll -(\\n[www-right-indent]u + \\n[www-image-gap]u) ++. mk www-right-ll-trap ++. nr www-right-ll-trap +(\\n[ps-desht]u - 1v) ++. wh \\n[www-right-ll-trap]u www-finish-right-ll ++. ++. \" now restore possible left trap ++. if (\\n[www-left-ll-trap] > 0) \ ++. wh \\n[www-left-ll-trap]u www-finish-left-ll ++. if (\\n[www-left-po-trap] > 0) \ ++. wh \\n[www-left-po-trap]u ++. \} ++. el \{\ ++. \" we must now disable a possible right image trap ++. if (\\n[www-right-ll-trap] > 0) \ ++. wh \\n[www-right-ll-trap]u ++. PSPIC -L \\*[www-unique-name].eps \\n[www-width]u \\n[www-height]u ++. sp -\\n[ps-desht]u ++. ++. nr www-left-indent \\n[ps-deswid]u ++. \" increase offset by gap ++. po +(\\n[www-left-indent]u + \\n[www-image-gap]u) ++. \" decrease line length by gap ++. ll -(\\n[www-left-indent]u + \\n[www-image-gap]u) ++. mk www-left-ll-trap ++. nr www-left-ll-trap +(\\n[ps-desht]u - 1v) ++. wh \\n[www-left-ll-trap]u www-finish-left-ll ++. ++. \" now restore possible right trap ++. if (\\n[www-right-ll-trap] > 0) \ ++. wh \\n[www-right-ll-trap]u www-finish-right-ll ++. \} ++. \} ++. \} ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" HnS n ++.\" ++.\" Begin heading. Heading level is N. ++.\" ++.\" HnE ++.\" ++.\" End heading. ++.\" ++.\" If your heading contains URL, FTP, MTO macros you might wish to ++.\" disable automatic links to headings. This can be done via `-P-l' ++.\" from the command line or by using a cakk to `.HX 0'. ++.\" ++.nr www-heading-no -1 ++. ++.de HnS ++. ie '\\$1'' \ ++. nr www-heading-no 1 ++. el \ ++. nr www-heading-no \\$1 ++. DEVTAG-NH \\n[www-heading-no] ++.. ++. ++.de HnE ++. if (\\n[www-heading-no] == -1) \ ++. www-error HnE found without a corresponding HnS ++. DEVTAG-EO-H ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" LK ++.\" ++.\" Emit the automatically collected links derived from ++.\" section/numbered headings at this position. ++.\" ++.de LK ++. DEVTAG .links ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" HR ++.\" ++.\" Produce a horizontal line. ++.\" ++.de HR ++. HTML

    ] ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" NHR ++.\" ++.\" Suppress the generation of the top and bottom rules which grohtml ++.\" emits by default. ++.\" ++.de NHR ++. DEVTAG .no-auto-rule ++.. ++. ++.\" ++.\" www-end-nowhere - end of input trap called to finish diversion. ++.\" ++.de www-end-nowhere ++. if !\\n[www-html] \ ++. di ++. DEVTAG-EO-TL ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" HTL ++.\" ++.\" Generate an HTML title only. This differs from the -ms .TL macro ++.\" which generates both an HTML title and an H1 heading. ++.\" ++.\" This is useful when an author wishes to use an HTML title as search ++.\" engine fodder but a graphic title in the document. ++.\" ++.\" The macro terminates when a space or break is seen (.sp, .br). ++.\" ++.de HTL ++. DEVTAG .html-tl ++. if !\\n[www-html] \ ++. di www-nowhere ++. it 2 www-end-nowhere ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" auxiliary definitions for lists ++.\" ++.ds www-ul-level1 \[bu]\ \ \" ++.ds www-ul-level2 \[sq]\ \ \" ++.ds www-ul-level3 \[ci]\ \ \" ++.nr www-ul-level 0 ++. ++.ds www-ol-level1 decimal\" ++.ds www-ol-level2 lower-alpha\" ++.ds www-ol-level3 lower-roman\" ++.ds www-ol-tmp 00\ \ \" ++.nr www-ol-ctr1 0 1 ++.nr www-ol-ctr2 0 1 ++.nr www-ol-ctr3 0 1 ++.af www-ol-ctr2 a ++.af www-ol-ctr3 i ++.nr www-ol-level 0 ++. ++.nr www-dl-level 0 ++.nr www-dl-shift 5n ++. ++.\" ++.\" allow nested lists ++.\" ++.nr www-depth 0 ++.nr www-li-indent \n[.i] ++.ds www-level0 nop\" ++.ds www-level1 ++.ds www-level2 ++.ds www-level3 ++.ds www-level4 ++.ds www-level5 ++.ds www-level6 ++.ds www-level7 ++.ds www-level8 ++.ds www-level9 ++. ++.\" which macro to use for LI ++.de www-push-li ++. nr www-li-indent \\n[.i] ++. nr www-depth +1 ++. ds www-level\\n[www-depth] \\$1\" ++. ds www-ltag\\n[www-depth] ++. als LI \\$1 ++.. ++. ++.de www-pop-li ++. nr www-depth -1 ++. als LI \\*[www-level\\n[www-depth]] ++.. ++. ++.\" www-emit-ltag - shut down a previous open list tag ++.\" before issuing a new tag \\$1. ++.\" It then records tag \\$1 is open. ++. ++.de www-emit-ltag ++. if !'\\*[www-ltag\\n[www-depth]]'' \ ++. HTML-NS ++. if !'\\$1'' \ ++. HTML-NS <\\$1> ++. ds www-ltag\\n[www-depth] \\$1\" ++.. ++. ++.\" ++.\" Auxiliary macro for ULS. ++.\" ++.de www-push-ul-level ++. nr www-ul-level +1 ++. if (\\n[www-ul-level] > 3) \ ++. www-error ULS: too many levels of indentation (\\n[www-ul-level]) ++.. ++.\" ++.\" Auxiliary macro for ULE. ++.\" ++.de www-pop-ul-level ++. if !\\n[www-ul-level] \ ++. www-error ULE: trying to terminate a list which does not exist ++. nr www-ul-level -1 ++.. ++. ++.\" ++.\" Auxiliary macro for OLS. ++.\" ++.de www-push-ol-level ++. nr www-ol-level +1 ++. if (\\n[www-ol-level] > 3) \ ++. www-error OLS: too many levels of indentation (\\n[www-ol-level]) ++.. ++. ++.\" ++.\" Auxiliary macro for OLE. ++.\" ++.de www-pop-ol-level ++. if !\\n[www-ol-level] \ ++. www-error OLE: trying to terminate a list which does not exist ++. nr www-ol-level -1 ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" ULS ++.\" ++.\" Start an unordered list. ++.\" ++.de ULS ++. www-push-li www-li-ul ++. www-push-ul-level ++. ie \\n[www-html] \{\ ++. www-emit-ltag ++. HTML

      ++. \} ++. el \ ++. nr www-li-indent +\w'\\*[www-ul-level\\n[www-ul-level]]'u ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" ULE ++.\" ++.\" End an unordered list. ++.\" ++.de ULE ++. ie \\n[www-html] \{\ ++. www-emit-ltag ++. HTML

    ++. \} ++. el \{\ ++. nr www-li-indent -\w'\\*[www-ul-level\\n[www-ul-level]]'u ++. in \\n[www-li-indent]u ++. \} ++. www-pop-ul-level ++. www-pop-li ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" OLS ++.\" ++.\" Start an ordered list. ++.\" ++.de OLS ++. www-push-li www-li-ol ++. www-push-ol-level ++. ie \\n[www-html] \{\ ++. www-emit-ltag ++. HTML

      " ++. \} ++. el \ ++. nr www-li-indent +\w'\\*[www-ol-tmp]'u ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" OLE ++.\" ++.\" End an ordered list. ++.\" ++.de OLE ++. ie \\n[www-html] \{\ ++. www-emit-ltag ++. HTML
    ++. \} ++. el \{\ ++. nr www-li-indent -\w'\\*[www-ol-tmp]'u ++. in \\n[www-li-indent]u ++. nr www-ol-ctr\\n[www-ol-level] 0 1 ++. \} ++. www-pop-ol-level ++. www-pop-li ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" DLS ++.\" ++.\" Start a definition list. ++.\" ++.de DLS ++. www-push-li www-li-dl ++. nr www-dl-level +1 ++. ie \\n[www-html] \{\ ++. www-emit-ltag ++. HTML

    ++. \} ++. el \{\ ++. nr www-li-indent +\\n[www-dl-shift]u ++. in \\n[www-li-indent]u ++. \} ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" DLE ++.\" ++.\" End a definition list. ++.\" ++.de DLE ++. ie \\n[www-html] \{\ ++. www-emit-ltag ++. HTML
    ++. \} ++. el \{\ ++. nr www-li-indent -\\n[www-dl-shift]u ++. in \\n[www-li-indent]u ++. \} ++. nr www-dl-level -1 ++. www-pop-li ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" LI ++.\" ++.\" Insert a list item. ++.\" ++. ++.\" ******** ++.\" www-li-ul - bulleted list item ++.\" ++.de www-li-ul ++. ie \\n[www-html] \ ++. www-emit-ltag li ++. el \{\ ++. www:paraspace ++. if rPORPHANS \ ++. ne \\n[PORPHANS]v ++. in \\n[www-li-indent]u ++. ti -\w'\\*[www-ul-level\\n[www-ul-level]]'u ++. nop \\*[www-ul-level\\n[www-ul-level]]\c ++. \} ++.. ++. ++.\" ******** ++.\" www-li-ol - numbered list item ++.\" ++.de www-li-ol ++. ie \\n[www-html] \ ++. www-emit-ltag li ++. el \{\ ++. www:paraspace ++. if rPORPHANS \ ++. ne \\n[PORPHANS]v ++. in \\n[www-li-indent]u ++. ti -\w'\\n+[www-ol-ctr\\n[www-ol-level]]\ \ 'u ++. nop \\n[www-ol-ctr\\n[www-ol-level]]\ \ \c ++. \} ++.. ++. ++.\" ******** ++.\" www-li-dl - definition list item ++.\" ++.de www-li-dl ++. ie \\n[www-html] \{\ ++. HTML
    \\$1
    ++. www-emit-ltag dd ++. \} ++. el \{\ ++. www:paraspace ++. if rPORPHANS \ ++. ne \\n[PORPHANS]v ++. in \\n[www-li-indent]u ++. ti -\\n[www-dl-shift]u ++. nop \&\\$1 ++. br ++. \} ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" DC l text [color] ++.\" ++.\" L is the letter to be dropped and enlarged. ++.\" ++.\" TEXT is the following text whose height the first letter should not ++.\" exceed. ++.\" ++.\" COLOR is the optional color of the dropped letter (default black). ++.\" ++.de DC ++. ds www-dropcolor black\" ++. if !'\\$3'' \ ++. ds www-dropcolor \\$3\" ++. ie '\*[.T]'html' \{\ ++. www-make-unique-name ++. nr www-drop-width (100u * \\n[.v]u * 3u / \\n[.l]u) ++. MPIMG -L \\*[www-unique-name].png \\n[www-drop-width]% ++. \} ++. el \{\ ++. ie r ps4html \{\ ++. www-make-unique-name ++. \" To avoid interferences with another DC macro call which is located ++. \" very near to the current one, we draw the glyph on a separate page. ++. \" Otherwise it could theoretically happen that the dropped capital ++. \" glyphs overlap. ++. bp ++. ev www-DC ++. vs 320p ++. nop \O[5i\\*[www-unique-name].png]\O[1] ++. nop \m[\\*[www-dropcolor]]\s[160]\O[3]\\$1\O[4] ++. nop \O[2]\O[0] ++. br ++. ev ++. bp ++. \} ++. el \{\ ++. ie n \ ++. nop \\$1\c ++. el \{\ ++. nr dummy \w'\\$1'u ++. nr dcht ((\\n[.v] + \\n[rst]) * \\n[.ps] / \\n[rst]) ++. char \[dcap] \m[\\*[www-dropcolor]]\s'\\n[dcht]u'\\$1 ++. nop \v'\\n[.v]u'\\[dcap]\v'-\\n[.v]u'\c ++' ti \w'\\[dcap]'u ++. \} ++. \} ++. \} ++. nop \\$2 ++.. ++. ++.\" ++.\" supplementary macros used by other macro sets ++.\" ++.\" here are some tags specially for -Tps or -Thtml when invoked by ++.\" pre-html to generate PNG images from postscript. ++. ++.\" -------------------------------------------------------------------- ++.\" HTML-DO-IMAGE - tell troff to issue an image marker which can be ++.\" read back by pre-html ++.\" ++.de HTML-DO-IMAGE ++. if r ps4html \ ++. nop \O[5\\$2\\$1.png]\O[1]\O[3] ++. if \\n[www-html] \ ++. nop \O[5\\$2\\$1.png]\O[0]\O[3] ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" HTML-IMAGE-END - terminate an image for HTML ++.\" ++.de HTML-IMAGE-END ++. if r ps4html \ ++. nop \O[4]\O[2]\O[0] ++. if \\n[www-html] \ ++. nop \O[4]\O[2]\O[1] ++.. ++. ++.nr www-png-no 0 ++. ++.\" -------------------------------------------------------------------- ++.\" www-make-unique-name - generate another unique name in string ++.\" `www-unique-name' ++.\" ++.de www-make-unique-name ++. nr www-png-no +1 ++. ds www-unique-name \\*[www-image-template]\\n[www-png-no]\" ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" HTML-IMAGE and friends tell grohtml that this region of text needs ++.\" to be rendered as an image. ++.\" ++.de HTML-IMAGE ++. \" generates a centered image ++. www-make-unique-name ++. HTML-DO-IMAGE \\*[www-unique-name] c ++.. ++. ++.de HTML-IMAGE-RIGHT ++. www-make-unique-name ++. HTML-DO-IMAGE \\*[www-unique-name] r ++.. ++. ++.de HTML-IMAGE-LEFT ++. www-make-unique-name ++. HTML-DO-IMAGE \\*[www-unique-name] l ++.. ++. ++.de HTML-IMAGE-INLINE ++. www-make-unique-name ++. HTML-DO-IMAGE \\*[www-unique-name] i ++.. ++. ++.\" EQN-HTML-IMAGE and friends check to see whether the equation is ++.\" not in an image, in which case it allows HTML ++.\" (mathml) to be generated (if -Txhtml was specified). ++. ++.de EQN-HTML-IMAGE ++. \" generates a centered image ++. www-make-unique-name ++. EQN-HTML-DO-IMAGE \\*[www-unique-name] c ++.. ++. ++.de EQN-HTML-IMAGE-RIGHT ++. www-make-unique-name ++. EQN-HTML-DO-IMAGE \\*[www-unique-name] r ++.. ++. ++.de EQN-HTML-IMAGE-LEFT ++. www-make-unique-name ++. EQN-HTML-DO-IMAGE \\*[www-unique-name] l ++.. ++. ++.de EQN-HTML-IMAGE-INLINE ++. www-make-unique-name ++. EQN-HTML-DO-IMAGE \\*[www-unique-name] i ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" EQN-HTML-DO-IMAGE - tell troff to issue an image marker which can be ++.\" read back by pre-html ++.\" ++.de EQN-HTML-DO-IMAGE ++. ie r xhtml \{\ ++. if !(\\n[.O] == 0) \{\ ++. if r ps4html \ ++. nop \O[5\\$2\\$1.png]\O[1]\O[3] ++. if \\n[www-html] \ ++. nop \O[5\\$2\\$1.png]\O[0]\O[3] ++. \} ++. \} ++. el \ ++. HTML-DO-IMAGE \\$* ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" EQN-HTML-IMAGE-END - terminate an image for HTML ++.\" ++.de EQN-HTML-IMAGE-END ++. ie r xhtml \{\ ++. if !(\\n[.O] == 0) \{\ ++. if r ps4html \ ++. nop \O[4]\O[2]\O[0] ++. if \\n[www-html] \ ++. nop \O[4]\O[2]\O[1] ++. \} ++. \} ++. el \ ++. HTML-IMAGE-END ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" Setup around HTML-IMAGE and friends ++.\" ++.\" now set up TS, TE, EQ, EN default macros ++.\" ++.\" we must not use `.als': the definition of .TE in s.tmac, for example, ++.\" calls .HTML-IMAGE-END, which would refer to itself due to the alias, ++.\" causing an endless loop ++.\" ++.if !d TS \{\ ++. de TS ++. HTML-IMAGE \\$@ ++. if \\n[www-html] \{\ ++. nr www-TS-ll \\n[.l] ++. ll 1000n ++. \} ++. . ++.\} ++.if !d TE \{\ ++. de TE ++. if \\n[www-html] \ ++. ll \\n[www-TS-ll]u ++. HTML-IMAGE-END \\$@ ++. . ++.\} ++.if !d EQ \{\ ++. de EQ ++. EQN-HTML-IMAGE \\$@ ++. if \\n[www-html] \{\ ++. nr www-EQ-ll \\n[.l] ++. ll 1000n ++. \} ++. . ++.\} ++.if !d EN \{\ ++. de EN ++. if \\n[www-html] \ ++. ll \\n[www-EQ-ll]u ++. EQN-HTML-IMAGE-END \\$@ ++. . ++.\} ++. ++.\" -------------------------------------------------------------------- ++.\" JOBNAME ++.\" ++.\" Generate multiple output files containing the HTML. ++.\" A file is split whenever a .SH or .NH 1 is encountered. ++.\" The argument to JOBNAME is the file stem for future output files. ++.\" ++.de JOBNAME ++. DEVTAG .job-name \\$1 ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" HEAD ++.\" ++.\" Add information to the section of the HTML ++.\" document ++.\" ++.de HEAD ++. DEVTAG .head "\\$*" ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" start of some code ++.\" ++.de CDS ++. ft C ++. nf ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" end of some code ++.\" ++.de CDE ++. fi ++. ft P ++.. ++. ++.ds www-nav-colour #eeeeee\" ++.nr www-nav-width-left 30 ++.nr www-nav-width-right 70 ++. ++.\" -------------------------------------------------------------------- ++.\" LNS - left navigation start ++.\" ++.de LNS ++. HTML

    " ++. LK ++. HTML

    " ++. nr SH-open 1 ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" LNE - left navigation end ++.\" ++.de LNE ++. HTML

    ++. HR ++.. ++. ++.nr SH-open 0 ++.nr needs-begin 0 ++. ++.\" ++.\" some auxiliary macros for left navigation lists ++.\" ++.de www-SH ++. if (0\\$1 == 0) \{\ ++. if (\\n[SH-open] == 1) \ ++. LNE ++. nr needs-begin 1 ++. @SH-old ++. \} ++.. ++. ++.de www-NH ++. if (0\\$1 <= 1) \{\ ++. if (\\n[SH-open] == 1) \ ++. LNE ++. nr needs-begin 1 ++. @NH-old ++. \} ++.. ++. ++.de www-LP ++. @LP-old ++. if (\\n[needs-begin] == 1) \{\ ++. HR ++. LNS ++. \} ++. nr needs-begin 0 ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" ALN [colour] [left width percentage] ++.\" ++.\" Turn on automatic left navigation. This macro should only be ++.\" called once (normally at the start of the document) as it ++.\" indicates that all top-level section headings form a navigation ++.\" list on the left of the main text. ++.\" ++.de ALN ++. if '\*[.T]'html' \{\ ++. if !'\\$1'' \ ++. ds www-nav-colour \\$1\" ++. if (0\\$2 > 0) \{\ ++. nr www-nav-width-left \\$2 ++. nr www-nav-width-right (100 - \\$2) ++. \} ++. rn @SH @SH-old ++. rn www-SH @SH ++. rn @NH @NH-old ++. rn www-NH @NH ++. rn @LP @LP-old ++. rn www-LP @LP ++. \} ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" LINKSTYLE color [fontstyle [openglyph closeglyph]] ++.\" ++.\" Initialize www.tmac so that when this macro set is used with ++.\" non-HTML devices the urls are rendered the user defined attributes. ++.\" For example: ++.\" ++.\" LINKSTYLE blue CR < > ++.\" ++.de LINKSTYLE ++. if (\\n[.$] < 1) \ ++. www:error .\\$0 expects at least 1 argument. ++. ds www:color \\$1\" ++. shift ++. if (\\n[.$] < 1) \ ++. return ++. ds www:fontstyle \\$1\" ++. shift ++. if (\\n[.$] < 1) \ ++. www:error .\\$0 expects that both the open and close glyph is specified ++. ds www:open \\$1\" ++. ds www:close \\$2\" ++.. ++. ++.\" MATHML - enable eqn mathml output to pass through to the device ++.\" driver ++. ++.de MATHML ++. if (\\n[.O] == 0) \ ++. MATH \\$* ++.. ++. ++.\" -------------------------------------------------------------------- ++.\" final setup ++.\" -------------------------------------------------------------------- ++. ++.LINKSTYLE blue C \[la] \[ra] ++. ++.if \n[www-html] \{\ ++. nh ++. nr HY 0 ++.\} ++. ++.if r ps4html .nop \O[0] ++.cp \n(_C ++. ++.\" now set ++. ++.\" -------------------------------------------------------------------- ++.\" Emacs settings ++.\" -------------------------------------------------------------------- ++. ++.\" Local Variables: ++.\" mode: nroff ++.\" End: ++.\" EOF diff --git a/system/base/groff/pspec.xml b/system/base/groff/pspec.xml index f77b3f03..b410ef9e 100644 --- a/system/base/groff/pspec.xml +++ b/system/base/groff/pspec.xml @@ -14,10 +14,14 @@ app:console A document formatting system groff is a document formatting system. Groff takes standard text and formatting commands as input and produces formatted output. - http://ftp.gnu.org/gnu/groff/groff-1.22.2.tar.gz + http://ftp.gnu.org/gnu/groff/groff-1.22.3.tar.gz texinfo + + groff-1.19.2-man-unicode-dashes.patch + groff-1.22.3-parallel-mom.patch + @@ -31,7 +35,6 @@ /usr/bin /usr/lib /usr/share/groff - /usr/share/X11/app-defaults @@ -49,6 +52,13 @@ + + 2015-04-02 + 1.22.3 + Release bump, remove X builddep. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 1.22.2 diff --git a/system/base/iputils/actions.py b/system/base/iputils/actions.py deleted file mode 100644 index 661fe8eb..00000000 --- a/system/base/iputils/actions.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Licensed under the GNU General Public License, version 3. -# See the file http://www.gnu.org/licenses/gpl.txt - -from pisi.actionsapi import shelltools -from pisi.actionsapi import autotools -from pisi.actionsapi import pisitools -from pisi.actionsapi import get - -def build(): - autotools.make("CCOPT='%s -fpie' CC=%s" % (get.CFLAGS(), get.CC())) - - autotools.compile("ifenslave.c -o ifenslave") - -def install(): - for app in ["ping", "ping6"]: - pisitools.dobin(app) - - for app in ["clockdiff", "arping", "rdisc", "tracepath", "tracepath6", "traceroute6", "ifenslave"]: - pisitools.dosbin(app) - - # We will not need these if we set cap on postInstall like Fedora - shelltools.chmod("%s/usr/bin/ping" % get.installDIR(), 04711) - shelltools.chmod("%s/usr/bin/ping6" % get.installDIR(), 04711) - - pisitools.dodoc("RELNOTES") diff --git a/system/base/iputils/files/021109-uclibc-no-ether_ntohost.patch b/system/base/iputils/files/021109-uclibc-no-ether_ntohost.patch deleted file mode 100644 index e790d2b5..00000000 --- a/system/base/iputils/files/021109-uclibc-no-ether_ntohost.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- iputils/rarpd.c.mps 2004-06-10 15:27:01.000000000 +0200 -+++ iputils/rarpd.c 2004-06-10 15:26:29.000000000 +0200 -@@ -42,7 +42,9 @@ int listen_arp; - char *ifname; - char *tftp_dir = "/etc/tftpboot"; - -+#ifndef __UCLIBC__ - extern int ether_ntohost(char *name, unsigned char *ea); -+#endif - void usage(void) __attribute__((noreturn)); - - struct iflink -@@ -305,7 +307,11 @@ struct rarp_map *rarp_lookup(int ifindex - 6, - }; - -+#ifndef __UCLIBC__ - if (ether_ntohost(ename, lladdr) != 0 || -+#else -+ if ( -+#endif - (hp = gethostbyname(ename)) == NULL) { - if (verbose) - syslog(LOG_INFO, "not found in /etc/ethers"); diff --git a/system/base/iputils/files/docs.patch b/system/base/iputils/files/docs.patch deleted file mode 100644 index c2e023ec..00000000 --- a/system/base/iputils/files/docs.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/doc/Makefile 2007-11-27 02:57:27.000000000 +0200 -+++ b/doc/Makefile 2007-11-27 04:55:23.000000000 +0200 -@@ -13,25 +13,17 @@ - # So, scope it to a temporary dir and clean all after each run. - - $(HTMLFILES): index.db -- @-rm -rf tmp.db2html -- @mkdir tmp.db2html -- @set -e; cd tmp.db2html; docbook2html ../$< ; mv *.html .. -- @-rm -rf tmp.db2html -+ @docbook2html $< - - iputils.html: iputils.db -- @-rm -rf tmp.db2html -- @mkdir tmp.db2html -- @set -e; cd tmp.db2html; docbook2html -u -o html ../$< ; mv html/$@ .. -- @-rm -rf tmp.db2html -+ @docbook2html -u $< - - # docbook2man produces utterly ugly output and I did not find - # any way to customize this but hacking backend perl script a little. - # Well, hence... - - $(MANFILES): index.db -- @-mkdir tmp.db2man -- @set -e; cd tmp.db2man; nsgmls ../$< | sgmlspl ../docbook2man-spec.pl ; mv $@ .. -- @-rm -rf tmp.db2man -+ @nsgmls $< |sgmlspl docbook2man-spec.pl - - clean: - @rm -rf $(MANFILES) $(HTMLFILES) iputils.html tmp.db2html tmp.db2man diff --git a/system/base/iputils/files/fedora/iputils-20020124-countermeasures.patch b/system/base/iputils/files/fedora/iputils-20020124-countermeasures.patch deleted file mode 100644 index 5e6f4bcd..00000000 --- a/system/base/iputils/files/fedora/iputils-20020124-countermeasures.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- iputils/ping_common.c.countermeasures Tue May 21 10:06:05 2002 -+++ iputils/ping_common.c Tue May 21 10:12:42 2002 -@@ -628,7 +628,8 @@ - tvsub(tv, &tmp_tv); - triptime = tv->tv_sec * 1000000 + tv->tv_usec; - if (triptime < 0) { -- fprintf(stderr, "Warning: time of day goes back (%ldus), taking countermeasures.\n", triptime); -+ if (options & F_VERBOSE) -+ fprintf(stderr, "Warning: time of day goes back (%ldus), taking countermeasures.\n", triptime); - triptime = 0; - if (!(options & F_LATENCY)) { - gettimeofday(tv, NULL); diff --git a/system/base/iputils/files/fedora/iputils-20020927-ping-subint.patch b/system/base/iputils/files/fedora/iputils-20020927-ping-subint.patch deleted file mode 100644 index e19e724f..00000000 --- a/system/base/iputils/files/fedora/iputils-20020927-ping-subint.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- iputils-ss021109-vanilla/ping.c Thu Nov 7 23:53:21 2002 -+++ iputils/ping.c Sun Jan 12 03:39:24 2003 -@@ -285,6 +285,9 @@ - perror("ping: IP_MULTICAST_IF"); - exit(2); - } -+ } else if (icmp_sock >= 0) { -+ /* We possible tried to SO_BINDTODEVICE() a subinterface like 'eth0:1' */ -+ perror("Warning: cannot bind to specified iface, falling back"); - } - } - } diff --git a/system/base/iputils/files/fedora/iputils-20070202-traffic_class.patch b/system/base/iputils/files/fedora/iputils-20070202-traffic_class.patch deleted file mode 100644 index 8a4ddf0f..00000000 --- a/system/base/iputils/files/fedora/iputils-20070202-traffic_class.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up iputils-s20070202/ping6.c.flowlabel iputils-s20070202/ping6.c ---- iputils-s20070202/ping6.c.flowlabel 2008-02-01 11:10:53.000000000 +0100 -+++ iputils-s20070202/ping6.c 2008-02-01 11:16:47.000000000 +0100 -@@ -86,6 +86,10 @@ char copyright[] = - #define SOL_ICMPV6 IPPROTO_ICMPV6 - #endif - -+#ifndef IVP6_FLOWINFO_SEND -+#define IPV6_FLOWINFO_SEND 33 -+#endif -+ - /* RFC3542 */ - #ifndef ICMP6_DST_UNREACH_BEYONDSCOPE - #define ICMP6_DST_UNREACH_BEYONDSCOPE ICMP6_DST_UNREACH_NOTNEIGHBOR diff --git a/system/base/iputils/files/fedora/iputils-20100418-convtoint.patch b/system/base/iputils/files/fedora/iputils-20100418-convtoint.patch deleted file mode 100644 index 77c2256c..00000000 --- a/system/base/iputils/files/fedora/iputils-20100418-convtoint.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up iputils-s20100418/tracepath6.c.convtoint iputils-s20100418/tracepath6.c ---- iputils-s20100418/tracepath6.c.convtoint 2010-04-23 11:28:15.294593391 +0200 -+++ iputils-s20100418/tracepath6.c 2010-04-23 11:28:23.544605551 +0200 -@@ -89,7 +89,7 @@ void print_host(const char *a, const cha - } - if (plen >= HOST_COLUMN_SIZE) - plen = HOST_COLUMN_SIZE - 1; -- printf("%*s", HOST_COLUMN_SIZE - plen, ""); -+ printf("%*s", HOST_COLUMN_SIZE - (int)plen, ""); - } - - int recverr(int fd, int ttl) -diff -up iputils-s20100418/tracepath.c.convtoint iputils-s20100418/tracepath.c ---- iputils-s20100418/tracepath.c.convtoint 2010-04-23 11:26:20.273555629 +0200 -+++ iputils-s20100418/tracepath.c 2010-04-23 11:26:20.281562493 +0200 -@@ -77,7 +77,7 @@ void print_host(const char *a, const cha - } - if (plen >= HOST_COLUMN_SIZE) - plen = HOST_COLUMN_SIZE - 1; -- printf("%*s", HOST_COLUMN_SIZE - plen, ""); -+ printf("%*s", HOST_COLUMN_SIZE - (int)plen, ""); - } - - int recverr(int fd, int ttl) diff --git a/system/base/iputils/files/fedora/rdisc.service b/system/base/iputils/files/fedora/rdisc.service deleted file mode 100644 index 70a3d3aa..00000000 --- a/system/base/iputils/files/fedora/rdisc.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=rdisc daemon which discovers routers on the local subnet -After=syslog.target network.target - -[Service] -Type=forking -EnvironmentFile=/etc/conf.d/rdisc -ExecStart=/sbin/rdisc $RDISCOPTS - -[Install] -WantedBy=multi-user.target diff --git a/system/base/iputils/files/fedora/rdisc.sysconfig b/system/base/iputils/files/fedora/rdisc.sysconfig deleted file mode 100644 index bd11c2ad..00000000 --- a/system/base/iputils/files/fedora/rdisc.sysconfig +++ /dev/null @@ -1 +0,0 @@ -RDISCOPTS="-s" diff --git a/system/base/iputils/files/ifenslave/README.bonding b/system/base/iputils/files/ifenslave/README.bonding deleted file mode 100644 index 61f516b1..00000000 --- a/system/base/iputils/files/ifenslave/README.bonding +++ /dev/null @@ -1,2440 +0,0 @@ - - Linux Ethernet Bonding Driver HOWTO - - Latest update: 23 September 2009 - -Initial release : Thomas Davis -Corrections, HA extensions : 2000/10/03-15 : - - Willy Tarreau - - Constantine Gavrilov - - Chad N. Tindel - - Janice Girouard - - Jay Vosburgh - -Reorganized and updated Feb 2005 by Jay Vosburgh -Added Sysfs information: 2006/04/24 - - Mitch Williams - -Introduction -============ - - The Linux bonding driver provides a method for aggregating -multiple network interfaces into a single logical "bonded" interface. -The behavior of the bonded interfaces depends upon the mode; generally -speaking, modes provide either hot standby or load balancing services. -Additionally, link integrity monitoring may be performed. - - The bonding driver originally came from Donald Becker's -beowulf patches for kernel 2.0. It has changed quite a bit since, and -the original tools from extreme-linux and beowulf sites will not work -with this version of the driver. - - For new versions of the driver, updated userspace tools, and -who to ask for help, please follow the links at the end of this file. - -Table of Contents -================= - -1. Bonding Driver Installation - -2. Bonding Driver Options - -3. Configuring Bonding Devices -3.1 Configuration with Sysconfig Support -3.1.1 Using DHCP with Sysconfig -3.1.2 Configuring Multiple Bonds with Sysconfig -3.2 Configuration with Initscripts Support -3.2.1 Using DHCP with Initscripts -3.2.2 Configuring Multiple Bonds with Initscripts -3.3 Configuring Bonding Manually with Ifenslave -3.3.1 Configuring Multiple Bonds Manually -3.4 Configuring Bonding Manually via Sysfs - -4. Querying Bonding Configuration -4.1 Bonding Configuration -4.2 Network Configuration - -5. Switch Configuration - -6. 802.1q VLAN Support - -7. Link Monitoring -7.1 ARP Monitor Operation -7.2 Configuring Multiple ARP Targets -7.3 MII Monitor Operation - -8. Potential Trouble Sources -8.1 Adventures in Routing -8.2 Ethernet Device Renaming -8.3 Painfully Slow Or No Failed Link Detection By Miimon - -9. SNMP agents - -10. Promiscuous mode - -11. Configuring Bonding for High Availability -11.1 High Availability in a Single Switch Topology -11.2 High Availability in a Multiple Switch Topology -11.2.1 HA Bonding Mode Selection for Multiple Switch Topology -11.2.2 HA Link Monitoring for Multiple Switch Topology - -12. Configuring Bonding for Maximum Throughput -12.1 Maximum Throughput in a Single Switch Topology -12.1.1 MT Bonding Mode Selection for Single Switch Topology -12.1.2 MT Link Monitoring for Single Switch Topology -12.2 Maximum Throughput in a Multiple Switch Topology -12.2.1 MT Bonding Mode Selection for Multiple Switch Topology -12.2.2 MT Link Monitoring for Multiple Switch Topology - -13. Switch Behavior Issues -13.1 Link Establishment and Failover Delays -13.2 Duplicated Incoming Packets - -14. Hardware Specific Considerations -14.1 IBM BladeCenter - -15. Frequently Asked Questions - -16. Resources and Links - - -1. Bonding Driver Installation -============================== - - Most popular distro kernels ship with the bonding driver -already available as a module and the ifenslave user level control -program installed and ready for use. If your distro does not, or you -have need to compile bonding from source (e.g., configuring and -installing a mainline kernel from kernel.org), you'll need to perform -the following steps: - -1.1 Configure and build the kernel with bonding ------------------------------------------------ - - The current version of the bonding driver is available in the -drivers/net/bonding subdirectory of the most recent kernel source -(which is available on http://kernel.org). Most users "rolling their -own" will want to use the most recent kernel from kernel.org. - - Configure kernel with "make menuconfig" (or "make xconfig" or -"make config"), then select "Bonding driver support" in the "Network -device support" section. It is recommended that you configure the -driver as module since it is currently the only way to pass parameters -to the driver or configure more than one bonding device. - - Build and install the new kernel and modules, then continue -below to install ifenslave. - -1.2 Install ifenslave Control Utility -------------------------------------- - - The ifenslave user level control program is included in the -kernel source tree, in the file Documentation/networking/ifenslave.c. -It is generally recommended that you use the ifenslave that -corresponds to the kernel that you are using (either from the same -source tree or supplied with the distro), however, ifenslave -executables from older kernels should function (but features newer -than the ifenslave release are not supported). Running an ifenslave -that is newer than the kernel is not supported, and may or may not -work. - - To install ifenslave, do the following: - -# gcc -Wall -O -I/usr/src/linux/include ifenslave.c -o ifenslave -# cp ifenslave /sbin/ifenslave - - If your kernel source is not in "/usr/src/linux," then replace -"/usr/src/linux/include" in the above with the location of your kernel -source include directory. - - You may wish to back up any existing /sbin/ifenslave, or, for -testing or informal use, tag the ifenslave to the kernel version -(e.g., name the ifenslave executable /sbin/ifenslave-2.6.10). - -IMPORTANT NOTE: - - If you omit the "-I" or specify an incorrect directory, you -may end up with an ifenslave that is incompatible with the kernel -you're trying to build it for. Some distros (e.g., Red Hat from 7.1 -onwards) do not have /usr/include/linux symbolically linked to the -default kernel source include directory. - -SECOND IMPORTANT NOTE: - If you plan to configure bonding using sysfs, you do not need -to use ifenslave. - -2. Bonding Driver Options -========================= - - Options for the bonding driver are supplied as parameters to the -bonding module at load time, or are specified via sysfs. - - Module options may be given as command line arguments to the -insmod or modprobe command, but are usually specified in either the -/etc/modules.conf or /etc/modprobe.conf configuration file, or in a -distro-specific configuration file (some of which are detailed in the next -section). - - Details on bonding support for sysfs is provided in the -"Configuring Bonding Manually via Sysfs" section, below. - - The available bonding driver parameters are listed below. If a -parameter is not specified the default value is used. When initially -configuring a bond, it is recommended "tail -f /var/log/messages" be -run in a separate window to watch for bonding driver error messages. - - It is critical that either the miimon or arp_interval and -arp_ip_target parameters be specified, otherwise serious network -degradation will occur during link failures. Very few devices do not -support at least miimon, so there is really no reason not to use it. - - Options with textual values will accept either the text name -or, for backwards compatibility, the option value. E.g., -"mode=802.3ad" and "mode=4" set the same mode. - - The parameters are as follows: - -ad_select - - Specifies the 802.3ad aggregation selection logic to use. The - possible values and their effects are: - - stable or 0 - - The active aggregator is chosen by largest aggregate - bandwidth. - - Reselection of the active aggregator occurs only when all - slaves of the active aggregator are down or the active - aggregator has no slaves. - - This is the default value. - - bandwidth or 1 - - The active aggregator is chosen by largest aggregate - bandwidth. Reselection occurs if: - - - A slave is added to or removed from the bond - - - Any slave's link state changes - - - Any slave's 802.3ad association state changes - - - The bond's administrative state changes to up - - count or 2 - - The active aggregator is chosen by the largest number of - ports (slaves). Reselection occurs as described under the - "bandwidth" setting, above. - - The bandwidth and count selection policies permit failover of - 802.3ad aggregations when partial failure of the active aggregator - occurs. This keeps the aggregator with the highest availability - (either in bandwidth or in number of ports) active at all times. - - This option was added in bonding version 3.4.0. - -arp_interval - - Specifies the ARP link monitoring frequency in milliseconds. - - The ARP monitor works by periodically checking the slave - devices to determine whether they have sent or received - traffic recently (the precise criteria depends upon the - bonding mode, and the state of the slave). Regular traffic is - generated via ARP probes issued for the addresses specified by - the arp_ip_target option. - - This behavior can be modified by the arp_validate option, - below. - - If ARP monitoring is used in an etherchannel compatible mode - (modes 0 and 2), the switch should be configured in a mode - that evenly distributes packets across all links. If the - switch is configured to distribute the packets in an XOR - fashion, all replies from the ARP targets will be received on - the same link which could cause the other team members to - fail. ARP monitoring should not be used in conjunction with - miimon. A value of 0 disables ARP monitoring. The default - value is 0. - -arp_ip_target - - Specifies the IP addresses to use as ARP monitoring peers when - arp_interval is > 0. These are the targets of the ARP request - sent to determine the health of the link to the targets. - Specify these values in ddd.ddd.ddd.ddd format. Multiple IP - addresses must be separated by a comma. At least one IP - address must be given for ARP monitoring to function. The - maximum number of targets that can be specified is 16. The - default value is no IP addresses. - -arp_validate - - Specifies whether or not ARP probes and replies should be - validated in the active-backup mode. This causes the ARP - monitor to examine the incoming ARP requests and replies, and - only consider a slave to be up if it is receiving the - appropriate ARP traffic. - - Possible values are: - - none or 0 - - No validation is performed. This is the default. - - active or 1 - - Validation is performed only for the active slave. - - backup or 2 - - Validation is performed only for backup slaves. - - all or 3 - - Validation is performed for all slaves. - - For the active slave, the validation checks ARP replies to - confirm that they were generated by an arp_ip_target. Since - backup slaves do not typically receive these replies, the - validation performed for backup slaves is on the ARP request - sent out via the active slave. It is possible that some - switch or network configurations may result in situations - wherein the backup slaves do not receive the ARP requests; in - such a situation, validation of backup slaves must be - disabled. - - This option is useful in network configurations in which - multiple bonding hosts are concurrently issuing ARPs to one or - more targets beyond a common switch. Should the link between - the switch and target fail (but not the switch itself), the - probe traffic generated by the multiple bonding instances will - fool the standard ARP monitor into considering the links as - still up. Use of the arp_validate option can resolve this, as - the ARP monitor will only consider ARP requests and replies - associated with its own instance of bonding. - - This option was added in bonding version 3.1.0. - -downdelay - - Specifies the time, in milliseconds, to wait before disabling - a slave after a link failure has been detected. This option - is only valid for the miimon link monitor. The downdelay - value should be a multiple of the miimon value; if not, it - will be rounded down to the nearest multiple. The default - value is 0. - -fail_over_mac - - Specifies whether active-backup mode should set all slaves to - the same MAC address at enslavement (the traditional - behavior), or, when enabled, perform special handling of the - bond's MAC address in accordance with the selected policy. - - Possible values are: - - none or 0 - - This setting disables fail_over_mac, and causes - bonding to set all slaves of an active-backup bond to - the same MAC address at enslavement time. This is the - default. - - active or 1 - - The "active" fail_over_mac policy indicates that the - MAC address of the bond should always be the MAC - address of the currently active slave. The MAC - address of the slaves is not changed; instead, the MAC - address of the bond changes during a failover. - - This policy is useful for devices that cannot ever - alter their MAC address, or for devices that refuse - incoming broadcasts with their own source MAC (which - interferes with the ARP monitor). - - The down side of this policy is that every device on - the network must be updated via gratuitous ARP, - vs. just updating a switch or set of switches (which - often takes place for any traffic, not just ARP - traffic, if the switch snoops incoming traffic to - update its tables) for the traditional method. If the - gratuitous ARP is lost, communication may be - disrupted. - - When this policy is used in conjuction with the mii - monitor, devices which assert link up prior to being - able to actually transmit and receive are particularly - susceptible to loss of the gratuitous ARP, and an - appropriate updelay setting may be required. - - follow or 2 - - The "follow" fail_over_mac policy causes the MAC - address of the bond to be selected normally (normally - the MAC address of the first slave added to the bond). - However, the second and subsequent slaves are not set - to this MAC address while they are in a backup role; a - slave is programmed with the bond's MAC address at - failover time (and the formerly active slave receives - the newly active slave's MAC address). - - This policy is useful for multiport devices that - either become confused or incur a performance penalty - when multiple ports are programmed with the same MAC - address. - - - The default policy is none, unless the first slave cannot - change its MAC address, in which case the active policy is - selected by default. - - This option may be modified via sysfs only when no slaves are - present in the bond. - - This option was added in bonding version 3.2.0. The "follow" - policy was added in bonding version 3.3.0. - -lacp_rate - - Option specifying the rate in which we'll ask our link partner - to transmit LACPDU packets in 802.3ad mode. Possible values - are: - - slow or 0 - Request partner to transmit LACPDUs every 30 seconds - - fast or 1 - Request partner to transmit LACPDUs every 1 second - - The default is slow. - -max_bonds - - Specifies the number of bonding devices to create for this - instance of the bonding driver. E.g., if max_bonds is 3, and - the bonding driver is not already loaded, then bond0, bond1 - and bond2 will be created. The default value is 1. Specifying - a value of 0 will load bonding, but will not create any devices. - -miimon - - Specifies the MII link monitoring frequency in milliseconds. - This determines how often the link state of each slave is - inspected for link failures. A value of zero disables MII - link monitoring. A value of 100 is a good starting point. - The use_carrier option, below, affects how the link state is - determined. See the High Availability section for additional - information. The default value is 0. - -mode - - Specifies one of the bonding policies. The default is - balance-rr (round robin). Possible values are: - - balance-rr or 0 - - Round-robin policy: Transmit packets in sequential - order from the first available slave through the - last. This mode provides load balancing and fault - tolerance. - - active-backup or 1 - - Active-backup policy: Only one slave in the bond is - active. A different slave becomes active if, and only - if, the active slave fails. The bond's MAC address is - externally visible on only one port (network adapter) - to avoid confusing the switch. - - In bonding version 2.6.2 or later, when a failover - occurs in active-backup mode, bonding will issue one - or more gratuitous ARPs on the newly active slave. - One gratuitous ARP is issued for the bonding master - interface and each VLAN interfaces configured above - it, provided that the interface has at least one IP - address configured. Gratuitous ARPs issued for VLAN - interfaces are tagged with the appropriate VLAN id. - - This mode provides fault tolerance. The primary - option, documented below, affects the behavior of this - mode. - - balance-xor or 2 - - XOR policy: Transmit based on the selected transmit - hash policy. The default policy is a simple [(source - MAC address XOR'd with destination MAC address) modulo - slave count]. Alternate transmit policies may be - selected via the xmit_hash_policy option, described - below. - - This mode provides load balancing and fault tolerance. - - broadcast or 3 - - Broadcast policy: transmits everything on all slave - interfaces. This mode provides fault tolerance. - - 802.3ad or 4 - - IEEE 802.3ad Dynamic link aggregation. Creates - aggregation groups that share the same speed and - duplex settings. Utilizes all slaves in the active - aggregator according to the 802.3ad specification. - - Slave selection for outgoing traffic is done according - to the transmit hash policy, which may be changed from - the default simple XOR policy via the xmit_hash_policy - option, documented below. Note that not all transmit - policies may be 802.3ad compliant, particularly in - regards to the packet mis-ordering requirements of - section 43.2.4 of the 802.3ad standard. Differing - peer implementations will have varying tolerances for - noncompliance. - - Prerequisites: - - 1. Ethtool support in the base drivers for retrieving - the speed and duplex of each slave. - - 2. A switch that supports IEEE 802.3ad Dynamic link - aggregation. - - Most switches will require some type of configuration - to enable 802.3ad mode. - - balance-tlb or 5 - - Adaptive transmit load balancing: channel bonding that - does not require any special switch support. The - outgoing traffic is distributed according to the - current load (computed relative to the speed) on each - slave. Incoming traffic is received by the current - slave. If the receiving slave fails, another slave - takes over the MAC address of the failed receiving - slave. - - Prerequisite: - - Ethtool support in the base drivers for retrieving the - speed of each slave. - - balance-alb or 6 - - Adaptive load balancing: includes balance-tlb plus - receive load balancing (rlb) for IPV4 traffic, and - does not require any special switch support. The - receive load balancing is achieved by ARP negotiation. - The bonding driver intercepts the ARP Replies sent by - the local system on their way out and overwrites the - source hardware address with the unique hardware - address of one of the slaves in the bond such that - different peers use different hardware addresses for - the server. - - Receive traffic from connections created by the server - is also balanced. When the local system sends an ARP - Request the bonding driver copies and saves the peer's - IP information from the ARP packet. When the ARP - Reply arrives from the peer, its hardware address is - retrieved and the bonding driver initiates an ARP - reply to this peer assigning it to one of the slaves - in the bond. A problematic outcome of using ARP - negotiation for balancing is that each time that an - ARP request is broadcast it uses the hardware address - of the bond. Hence, peers learn the hardware address - of the bond and the balancing of receive traffic - collapses to the current slave. This is handled by - sending updates (ARP Replies) to all the peers with - their individually assigned hardware address such that - the traffic is redistributed. Receive traffic is also - redistributed when a new slave is added to the bond - and when an inactive slave is re-activated. The - receive load is distributed sequentially (round robin) - among the group of highest speed slaves in the bond. - - When a link is reconnected or a new slave joins the - bond the receive traffic is redistributed among all - active slaves in the bond by initiating ARP Replies - with the selected MAC address to each of the - clients. The updelay parameter (detailed below) must - be set to a value equal or greater than the switch's - forwarding delay so that the ARP Replies sent to the - peers will not be blocked by the switch. - - Prerequisites: - - 1. Ethtool support in the base drivers for retrieving - the speed of each slave. - - 2. Base driver support for setting the hardware - address of a device while it is open. This is - required so that there will always be one slave in the - team using the bond hardware address (the - curr_active_slave) while having a unique hardware - address for each slave in the bond. If the - curr_active_slave fails its hardware address is - swapped with the new curr_active_slave that was - chosen. - -num_grat_arp - - Specifies the number of gratuitous ARPs to be issued after a - failover event. One gratuitous ARP is issued immediately after - the failover, subsequent ARPs are sent at a rate of one per link - monitor interval (arp_interval or miimon, whichever is active). - - The valid range is 0 - 255; the default value is 1. This option - affects only the active-backup mode. This option was added for - bonding version 3.3.0. - -num_unsol_na - - Specifies the number of unsolicited IPv6 Neighbor Advertisements - to be issued after a failover event. One unsolicited NA is issued - immediately after the failover. - - The valid range is 0 - 255; the default value is 1. This option - affects only the active-backup mode. This option was added for - bonding version 3.4.0. - -primary - - A string (eth0, eth2, etc) specifying which slave is the - primary device. The specified device will always be the - active slave while it is available. Only when the primary is - off-line will alternate devices be used. This is useful when - one slave is preferred over another, e.g., when one slave has - higher throughput than another. - - The primary option is only valid for active-backup mode. - -primary_reselect - - Specifies the reselection policy for the primary slave. This - affects how the primary slave is chosen to become the active slave - when failure of the active slave or recovery of the primary slave - occurs. This option is designed to prevent flip-flopping between - the primary slave and other slaves. Possible values are: - - always or 0 (default) - - The primary slave becomes the active slave whenever it - comes back up. - - better or 1 - - The primary slave becomes the active slave when it comes - back up, if the speed and duplex of the primary slave is - better than the speed and duplex of the current active - slave. - - failure or 2 - - The primary slave becomes the active slave only if the - current active slave fails and the primary slave is up. - - The primary_reselect setting is ignored in two cases: - - If no slaves are active, the first slave to recover is - made the active slave. - - When initially enslaved, the primary slave is always made - the active slave. - - Changing the primary_reselect policy via sysfs will cause an - immediate selection of the best active slave according to the new - policy. This may or may not result in a change of the active - slave, depending upon the circumstances. - - This option was added for bonding version 3.6.0. - -updelay - - Specifies the time, in milliseconds, to wait before enabling a - slave after a link recovery has been detected. This option is - only valid for the miimon link monitor. The updelay value - should be a multiple of the miimon value; if not, it will be - rounded down to the nearest multiple. The default value is 0. - -use_carrier - - Specifies whether or not miimon should use MII or ETHTOOL - ioctls vs. netif_carrier_ok() to determine the link - status. The MII or ETHTOOL ioctls are less efficient and - utilize a deprecated calling sequence within the kernel. The - netif_carrier_ok() relies on the device driver to maintain its - state with netif_carrier_on/off; at this writing, most, but - not all, device drivers support this facility. - - If bonding insists that the link is up when it should not be, - it may be that your network device driver does not support - netif_carrier_on/off. The default state for netif_carrier is - "carrier on," so if a driver does not support netif_carrier, - it will appear as if the link is always up. In this case, - setting use_carrier to 0 will cause bonding to revert to the - MII / ETHTOOL ioctl method to determine the link state. - - A value of 1 enables the use of netif_carrier_ok(), a value of - 0 will use the deprecated MII / ETHTOOL ioctls. The default - value is 1. - -xmit_hash_policy - - Selects the transmit hash policy to use for slave selection in - balance-xor and 802.3ad modes. Possible values are: - - layer2 - - Uses XOR of hardware MAC addresses to generate the - hash. The formula is - - (source MAC XOR destination MAC) modulo slave count - - This algorithm will place all traffic to a particular - network peer on the same slave. - - This algorithm is 802.3ad compliant. - - layer2+3 - - This policy uses a combination of layer2 and layer3 - protocol information to generate the hash. - - Uses XOR of hardware MAC addresses and IP addresses to - generate the hash. The formula is - - (((source IP XOR dest IP) AND 0xffff) XOR - ( source MAC XOR destination MAC )) - modulo slave count - - This algorithm will place all traffic to a particular - network peer on the same slave. For non-IP traffic, - the formula is the same as for the layer2 transmit - hash policy. - - This policy is intended to provide a more balanced - distribution of traffic than layer2 alone, especially - in environments where a layer3 gateway device is - required to reach most destinations. - - This algorithm is 802.3ad compliant. - - layer3+4 - - This policy uses upper layer protocol information, - when available, to generate the hash. This allows for - traffic to a particular network peer to span multiple - slaves, although a single connection will not span - multiple slaves. - - The formula for unfragmented TCP and UDP packets is - - ((source port XOR dest port) XOR - ((source IP XOR dest IP) AND 0xffff) - modulo slave count - - For fragmented TCP or UDP packets and all other IP - protocol traffic, the source and destination port - information is omitted. For non-IP traffic, the - formula is the same as for the layer2 transmit hash - policy. - - This policy is intended to mimic the behavior of - certain switches, notably Cisco switches with PFC2 as - well as some Foundry and IBM products. - - This algorithm is not fully 802.3ad compliant. A - single TCP or UDP conversation containing both - fragmented and unfragmented packets will see packets - striped across two interfaces. This may result in out - of order delivery. Most traffic types will not meet - this criteria, as TCP rarely fragments traffic, and - most UDP traffic is not involved in extended - conversations. Other implementations of 802.3ad may - or may not tolerate this noncompliance. - - The default value is layer2. This option was added in bonding - version 2.6.3. In earlier versions of bonding, this parameter - does not exist, and the layer2 policy is the only policy. The - layer2+3 value was added for bonding version 3.2.2. - - -3. Configuring Bonding Devices -============================== - - You can configure bonding using either your distro's network -initialization scripts, or manually using either ifenslave or the -sysfs interface. Distros generally use one of two packages for the -network initialization scripts: initscripts or sysconfig. Recent -versions of these packages have support for bonding, while older -versions do not. - - We will first describe the options for configuring bonding for -distros using versions of initscripts and sysconfig with full or -partial support for bonding, then provide information on enabling -bonding without support from the network initialization scripts (i.e., -older versions of initscripts or sysconfig). - - If you're unsure whether your distro uses sysconfig or -initscripts, or don't know if it's new enough, have no fear. -Determining this is fairly straightforward. - - First, issue the command: - -$ rpm -qf /sbin/ifup - - It will respond with a line of text starting with either -"initscripts" or "sysconfig," followed by some numbers. This is the -package that provides your network initialization scripts. - - Next, to determine if your installation supports bonding, -issue the command: - -$ grep ifenslave /sbin/ifup - - If this returns any matches, then your initscripts or -sysconfig has support for bonding. - -3.1 Configuration with Sysconfig Support ----------------------------------------- - - This section applies to distros using a version of sysconfig -with bonding support, for example, SuSE Linux Enterprise Server 9. - - SuSE SLES 9's networking configuration system does support -bonding, however, at this writing, the YaST system configuration -front end does not provide any means to work with bonding devices. -Bonding devices can be managed by hand, however, as follows. - - First, if they have not already been configured, configure the -slave devices. On SLES 9, this is most easily done by running the -yast2 sysconfig configuration utility. The goal is for to create an -ifcfg-id file for each slave device. The simplest way to accomplish -this is to configure the devices for DHCP (this is only to get the -file ifcfg-id file created; see below for some issues with DHCP). The -name of the configuration file for each device will be of the form: - -ifcfg-id-xx:xx:xx:xx:xx:xx - - Where the "xx" portion will be replaced with the digits from -the device's permanent MAC address. - - Once the set of ifcfg-id-xx:xx:xx:xx:xx:xx files has been -created, it is necessary to edit the configuration files for the slave -devices (the MAC addresses correspond to those of the slave devices). -Before editing, the file will contain multiple lines, and will look -something like this: - -BOOTPROTO='dhcp' -STARTMODE='on' -USERCTL='no' -UNIQUE='XNzu.WeZGOGF+4wE' -_nm_name='bus-pci-0001:61:01.0' - - Change the BOOTPROTO and STARTMODE lines to the following: - -BOOTPROTO='none' -STARTMODE='off' - - Do not alter the UNIQUE or _nm_name lines. Remove any other -lines (USERCTL, etc). - - Once the ifcfg-id-xx:xx:xx:xx:xx:xx files have been modified, -it's time to create the configuration file for the bonding device -itself. This file is named ifcfg-bondX, where X is the number of the -bonding device to create, starting at 0. The first such file is -ifcfg-bond0, the second is ifcfg-bond1, and so on. The sysconfig -network configuration system will correctly start multiple instances -of bonding. - - The contents of the ifcfg-bondX file is as follows: - -BOOTPROTO="static" -BROADCAST="10.0.2.255" -IPADDR="10.0.2.10" -NETMASK="255.255.0.0" -NETWORK="10.0.2.0" -REMOTE_IPADDR="" -STARTMODE="onboot" -BONDING_MASTER="yes" -BONDING_MODULE_OPTS="mode=active-backup miimon=100" -BONDING_SLAVE0="eth0" -BONDING_SLAVE1="bus-pci-0000:06:08.1" - - Replace the sample BROADCAST, IPADDR, NETMASK and NETWORK -values with the appropriate values for your network. - - The STARTMODE specifies when the device is brought online. -The possible values are: - - onboot: The device is started at boot time. If you're not - sure, this is probably what you want. - - manual: The device is started only when ifup is called - manually. Bonding devices may be configured this - way if you do not wish them to start automatically - at boot for some reason. - - hotplug: The device is started by a hotplug event. This is not - a valid choice for a bonding device. - - off or ignore: The device configuration is ignored. - - The line BONDING_MASTER='yes' indicates that the device is a -bonding master device. The only useful value is "yes." - - The contents of BONDING_MODULE_OPTS are supplied to the -instance of the bonding module for this device. Specify the options -for the bonding mode, link monitoring, and so on here. Do not include -the max_bonds bonding parameter; this will confuse the configuration -system if you have multiple bonding devices. - - Finally, supply one BONDING_SLAVEn="slave device" for each -slave. where "n" is an increasing value, one for each slave. The -"slave device" is either an interface name, e.g., "eth0", or a device -specifier for the network device. The interface name is easier to -find, but the ethN names are subject to change at boot time if, e.g., -a device early in the sequence has failed. The device specifiers -(bus-pci-0000:06:08.1 in the example above) specify the physical -network device, and will not change unless the device's bus location -changes (for example, it is moved from one PCI slot to another). The -example above uses one of each type for demonstration purposes; most -configurations will choose one or the other for all slave devices. - - When all configuration files have been modified or created, -networking must be restarted for the configuration changes to take -effect. This can be accomplished via the following: - -# /etc/init.d/network restart - - Note that the network control script (/sbin/ifdown) will -remove the bonding module as part of the network shutdown processing, -so it is not necessary to remove the module by hand if, e.g., the -module parameters have changed. - - Also, at this writing, YaST/YaST2 will not manage bonding -devices (they do not show bonding interfaces on its list of network -devices). It is necessary to edit the configuration file by hand to -change the bonding configuration. - - Additional general options and details of the ifcfg file -format can be found in an example ifcfg template file: - -/etc/sysconfig/network/ifcfg.template - - Note that the template does not document the various BONDING_ -settings described above, but does describe many of the other options. - -3.1.1 Using DHCP with Sysconfig -------------------------------- - - Under sysconfig, configuring a device with BOOTPROTO='dhcp' -will cause it to query DHCP for its IP address information. At this -writing, this does not function for bonding devices; the scripts -attempt to obtain the device address from DHCP prior to adding any of -the slave devices. Without active slaves, the DHCP requests are not -sent to the network. - -3.1.2 Configuring Multiple Bonds with Sysconfig ------------------------------------------------ - - The sysconfig network initialization system is capable of -handling multiple bonding devices. All that is necessary is for each -bonding instance to have an appropriately configured ifcfg-bondX file -(as described above). Do not specify the "max_bonds" parameter to any -instance of bonding, as this will confuse sysconfig. If you require -multiple bonding devices with identical parameters, create multiple -ifcfg-bondX files. - - Because the sysconfig scripts supply the bonding module -options in the ifcfg-bondX file, it is not necessary to add them to -the system /etc/modules.conf or /etc/modprobe.conf configuration file. - -3.2 Configuration with Initscripts Support ------------------------------------------- - - This section applies to distros using a recent version of -initscripts with bonding support, for example, Red Hat Enterprise Linux -version 3 or later, Fedora, etc. On these systems, the network -initialization scripts have knowledge of bonding, and can be configured to -control bonding devices. Note that older versions of the initscripts -package have lower levels of support for bonding; this will be noted where -applicable. - - These distros will not automatically load the network adapter -driver unless the ethX device is configured with an IP address. -Because of this constraint, users must manually configure a -network-script file for all physical adapters that will be members of -a bondX link. Network script files are located in the directory: - -/etc/sysconfig/network-scripts - - The file name must be prefixed with "ifcfg-eth" and suffixed -with the adapter's physical adapter number. For example, the script -for eth0 would be named /etc/sysconfig/network-scripts/ifcfg-eth0. -Place the following text in the file: - -DEVICE=eth0 -USERCTL=no -ONBOOT=yes -MASTER=bond0 -SLAVE=yes -BOOTPROTO=none - - The DEVICE= line will be different for every ethX device and -must correspond with the name of the file, i.e., ifcfg-eth1 must have -a device line of DEVICE=eth1. The setting of the MASTER= line will -also depend on the final bonding interface name chosen for your bond. -As with other network devices, these typically start at 0, and go up -one for each device, i.e., the first bonding instance is bond0, the -second is bond1, and so on. - - Next, create a bond network script. The file name for this -script will be /etc/sysconfig/network-scripts/ifcfg-bondX where X is -the number of the bond. For bond0 the file is named "ifcfg-bond0", -for bond1 it is named "ifcfg-bond1", and so on. Within that file, -place the following text: - -DEVICE=bond0 -IPADDR=192.168.1.1 -NETMASK=255.255.255.0 -NETWORK=192.168.1.0 -BROADCAST=192.168.1.255 -ONBOOT=yes -BOOTPROTO=none -USERCTL=no - - Be sure to change the networking specific lines (IPADDR, -NETMASK, NETWORK and BROADCAST) to match your network configuration. - - For later versions of initscripts, such as that found with Fedora -7 (or later) and Red Hat Enterprise Linux version 5 (or later), it is possible, -and, indeed, preferable, to specify the bonding options in the ifcfg-bond0 -file, e.g. a line of the format: - -BONDING_OPTS="mode=active-backup arp_interval=60 arp_ip_target=192.168.1.254" - - will configure the bond with the specified options. The options -specified in BONDING_OPTS are identical to the bonding module parameters -except for the arp_ip_target field when using versions of initscripts older -than and 8.57 (Fedora 8) and 8.45.19 (Red Hat Enterprise Linux 5.2). When -using older versions each target should be included as a separate option and -should be preceded by a '+' to indicate it should be added to the list of -queried targets, e.g., - - arp_ip_target=+192.168.1.1 arp_ip_target=+192.168.1.2 - - is the proper syntax to specify multiple targets. When specifying -options via BONDING_OPTS, it is not necessary to edit /etc/modules.conf or -/etc/modprobe.conf. - - For even older versions of initscripts that do not support -BONDING_OPTS, it is necessary to edit /etc/modules.conf (or -/etc/modprobe.conf, depending upon your distro) to load the bonding module -with your desired options when the bond0 interface is brought up. The -following lines in /etc/modules.conf (or modprobe.conf) will load the -bonding module, and select its options: - -alias bond0 bonding -options bond0 mode=balance-alb miimon=100 - - Replace the sample parameters with the appropriate set of -options for your configuration. - - Finally run "/etc/rc.d/init.d/network restart" as root. This -will restart the networking subsystem and your bond link should be now -up and running. - -3.2.1 Using DHCP with Initscripts ---------------------------------- - - Recent versions of initscripts (the versions supplied with Fedora -Core 3 and Red Hat Enterprise Linux 4, or later versions, are reported to -work) have support for assigning IP information to bonding devices via -DHCP. - - To configure bonding for DHCP, configure it as described -above, except replace the line "BOOTPROTO=none" with "BOOTPROTO=dhcp" -and add a line consisting of "TYPE=Bonding". Note that the TYPE value -is case sensitive. - -3.2.2 Configuring Multiple Bonds with Initscripts -------------------------------------------------- - - Initscripts packages that are included with Fedora 7 and Red Hat -Enterprise Linux 5 support multiple bonding interfaces by simply -specifying the appropriate BONDING_OPTS= in ifcfg-bondX where X is the -number of the bond. This support requires sysfs support in the kernel, -and a bonding driver of version 3.0.0 or later. Other configurations may -not support this method for specifying multiple bonding interfaces; for -those instances, see the "Configuring Multiple Bonds Manually" section, -below. - -3.3 Configuring Bonding Manually with Ifenslave ------------------------------------------------ - - This section applies to distros whose network initialization -scripts (the sysconfig or initscripts package) do not have specific -knowledge of bonding. One such distro is SuSE Linux Enterprise Server -version 8. - - The general method for these systems is to place the bonding -module parameters into /etc/modules.conf or /etc/modprobe.conf (as -appropriate for the installed distro), then add modprobe and/or -ifenslave commands to the system's global init script. The name of -the global init script differs; for sysconfig, it is -/etc/init.d/boot.local and for initscripts it is /etc/rc.d/rc.local. - - For example, if you wanted to make a simple bond of two e100 -devices (presumed to be eth0 and eth1), and have it persist across -reboots, edit the appropriate file (/etc/init.d/boot.local or -/etc/rc.d/rc.local), and add the following: - -modprobe bonding mode=balance-alb miimon=100 -modprobe e100 -ifconfig bond0 192.168.1.1 netmask 255.255.255.0 up -ifenslave bond0 eth0 -ifenslave bond0 eth1 - - Replace the example bonding module parameters and bond0 -network configuration (IP address, netmask, etc) with the appropriate -values for your configuration. - - Unfortunately, this method will not provide support for the -ifup and ifdown scripts on the bond devices. To reload the bonding -configuration, it is necessary to run the initialization script, e.g., - -# /etc/init.d/boot.local - - or - -# /etc/rc.d/rc.local - - It may be desirable in such a case to create a separate script -which only initializes the bonding configuration, then call that -separate script from within boot.local. This allows for bonding to be -enabled without re-running the entire global init script. - - To shut down the bonding devices, it is necessary to first -mark the bonding device itself as being down, then remove the -appropriate device driver modules. For our example above, you can do -the following: - -# ifconfig bond0 down -# rmmod bonding -# rmmod e100 - - Again, for convenience, it may be desirable to create a script -with these commands. - - -3.3.1 Configuring Multiple Bonds Manually ------------------------------------------ - - This section contains information on configuring multiple -bonding devices with differing options for those systems whose network -initialization scripts lack support for configuring multiple bonds. - - If you require multiple bonding devices, but all with the same -options, you may wish to use the "max_bonds" module parameter, -documented above. - - To create multiple bonding devices with differing options, it is -preferrable to use bonding parameters exported by sysfs, documented in the -section below. - - For versions of bonding without sysfs support, the only means to -provide multiple instances of bonding with differing options is to load -the bonding driver multiple times. Note that current versions of the -sysconfig network initialization scripts handle this automatically; if -your distro uses these scripts, no special action is needed. See the -section Configuring Bonding Devices, above, if you're not sure about your -network initialization scripts. - - To load multiple instances of the module, it is necessary to -specify a different name for each instance (the module loading system -requires that every loaded module, even multiple instances of the same -module, have a unique name). This is accomplished by supplying multiple -sets of bonding options in /etc/modprobe.conf, for example: - -alias bond0 bonding -options bond0 -o bond0 mode=balance-rr miimon=100 - -alias bond1 bonding -options bond1 -o bond1 mode=balance-alb miimon=50 - - will load the bonding module two times. The first instance is -named "bond0" and creates the bond0 device in balance-rr mode with an -miimon of 100. The second instance is named "bond1" and creates the -bond1 device in balance-alb mode with an miimon of 50. - - In some circumstances (typically with older distributions), -the above does not work, and the second bonding instance never sees -its options. In that case, the second options line can be substituted -as follows: - -install bond1 /sbin/modprobe --ignore-install bonding -o bond1 \ - mode=balance-alb miimon=50 - - This may be repeated any number of times, specifying a new and -unique name in place of bond1 for each subsequent instance. - - It has been observed that some Red Hat supplied kernels are unable -to rename modules at load time (the "-o bond1" part). Attempts to pass -that option to modprobe will produce an "Operation not permitted" error. -This has been reported on some Fedora Core kernels, and has been seen on -RHEL 4 as well. On kernels exhibiting this problem, it will be impossible -to configure multiple bonds with differing parameters (as they are older -kernels, and also lack sysfs support). - -3.4 Configuring Bonding Manually via Sysfs ------------------------------------------- - - Starting with version 3.0.0, Channel Bonding may be configured -via the sysfs interface. This interface allows dynamic configuration -of all bonds in the system without unloading the module. It also -allows for adding and removing bonds at runtime. Ifenslave is no -longer required, though it is still supported. - - Use of the sysfs interface allows you to use multiple bonds -with different configurations without having to reload the module. -It also allows you to use multiple, differently configured bonds when -bonding is compiled into the kernel. - - You must have the sysfs filesystem mounted to configure -bonding this way. The examples in this document assume that you -are using the standard mount point for sysfs, e.g. /sys. If your -sysfs filesystem is mounted elsewhere, you will need to adjust the -example paths accordingly. - -Creating and Destroying Bonds ------------------------------ -To add a new bond foo: -# echo +foo > /sys/class/net/bonding_masters - -To remove an existing bond bar: -# echo -bar > /sys/class/net/bonding_masters - -To show all existing bonds: -# cat /sys/class/net/bonding_masters - -NOTE: due to 4K size limitation of sysfs files, this list may be -truncated if you have more than a few hundred bonds. This is unlikely -to occur under normal operating conditions. - -Adding and Removing Slaves --------------------------- - Interfaces may be enslaved to a bond using the file -/sys/class/net//bonding/slaves. The semantics for this file -are the same as for the bonding_masters file. - -To enslave interface eth0 to bond bond0: -# ifconfig bond0 up -# echo +eth0 > /sys/class/net/bond0/bonding/slaves - -To free slave eth0 from bond bond0: -# echo -eth0 > /sys/class/net/bond0/bonding/slaves - - When an interface is enslaved to a bond, symlinks between the -two are created in the sysfs filesystem. In this case, you would get -/sys/class/net/bond0/slave_eth0 pointing to /sys/class/net/eth0, and -/sys/class/net/eth0/master pointing to /sys/class/net/bond0. - - This means that you can tell quickly whether or not an -interface is enslaved by looking for the master symlink. Thus: -# echo -eth0 > /sys/class/net/eth0/master/bonding/slaves -will free eth0 from whatever bond it is enslaved to, regardless of -the name of the bond interface. - -Changing a Bond's Configuration -------------------------------- - Each bond may be configured individually by manipulating the -files located in /sys/class/net//bonding - - The names of these files correspond directly with the command- -line parameters described elsewhere in this file, and, with the -exception of arp_ip_target, they accept the same values. To see the -current setting, simply cat the appropriate file. - - A few examples will be given here; for specific usage -guidelines for each parameter, see the appropriate section in this -document. - -To configure bond0 for balance-alb mode: -# ifconfig bond0 down -# echo 6 > /sys/class/net/bond0/bonding/mode - - or - -# echo balance-alb > /sys/class/net/bond0/bonding/mode - NOTE: The bond interface must be down before the mode can be -changed. - -To enable MII monitoring on bond0 with a 1 second interval: -# echo 1000 > /sys/class/net/bond0/bonding/miimon - NOTE: If ARP monitoring is enabled, it will disabled when MII -monitoring is enabled, and vice-versa. - -To add ARP targets: -# echo +192.168.0.100 > /sys/class/net/bond0/bonding/arp_ip_target -# echo +192.168.0.101 > /sys/class/net/bond0/bonding/arp_ip_target - NOTE: up to 16 target addresses may be specified. - -To remove an ARP target: -# echo -192.168.0.100 > /sys/class/net/bond0/bonding/arp_ip_target - -Example Configuration ---------------------- - We begin with the same example that is shown in section 3.3, -executed with sysfs, and without using ifenslave. - - To make a simple bond of two e100 devices (presumed to be eth0 -and eth1), and have it persist across reboots, edit the appropriate -file (/etc/init.d/boot.local or /etc/rc.d/rc.local), and add the -following: - -modprobe bonding -modprobe e100 -echo balance-alb > /sys/class/net/bond0/bonding/mode -ifconfig bond0 192.168.1.1 netmask 255.255.255.0 up -echo 100 > /sys/class/net/bond0/bonding/miimon -echo +eth0 > /sys/class/net/bond0/bonding/slaves -echo +eth1 > /sys/class/net/bond0/bonding/slaves - - To add a second bond, with two e1000 interfaces in -active-backup mode, using ARP monitoring, add the following lines to -your init script: - -modprobe e1000 -echo +bond1 > /sys/class/net/bonding_masters -echo active-backup > /sys/class/net/bond1/bonding/mode -ifconfig bond1 192.168.2.1 netmask 255.255.255.0 up -echo +192.168.2.100 /sys/class/net/bond1/bonding/arp_ip_target -echo 2000 > /sys/class/net/bond1/bonding/arp_interval -echo +eth2 > /sys/class/net/bond1/bonding/slaves -echo +eth3 > /sys/class/net/bond1/bonding/slaves - - -4. Querying Bonding Configuration -================================= - -4.1 Bonding Configuration -------------------------- - - Each bonding device has a read-only file residing in the -/proc/net/bonding directory. The file contents include information -about the bonding configuration, options and state of each slave. - - For example, the contents of /proc/net/bonding/bond0 after the -driver is loaded with parameters of mode=0 and miimon=1000 is -generally as follows: - - Ethernet Channel Bonding Driver: 2.6.1 (October 29, 2004) - Bonding Mode: load balancing (round-robin) - Currently Active Slave: eth0 - MII Status: up - MII Polling Interval (ms): 1000 - Up Delay (ms): 0 - Down Delay (ms): 0 - - Slave Interface: eth1 - MII Status: up - Link Failure Count: 1 - - Slave Interface: eth0 - MII Status: up - Link Failure Count: 1 - - The precise format and contents will change depending upon the -bonding configuration, state, and version of the bonding driver. - -4.2 Network configuration -------------------------- - - The network configuration can be inspected using the ifconfig -command. Bonding devices will have the MASTER flag set; Bonding slave -devices will have the SLAVE flag set. The ifconfig output does not -contain information on which slaves are associated with which masters. - - In the example below, the bond0 interface is the master -(MASTER) while eth0 and eth1 are slaves (SLAVE). Notice all slaves of -bond0 have the same MAC address (HWaddr) as bond0 for all modes except -TLB and ALB that require a unique MAC address for each slave. - -# /sbin/ifconfig -bond0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 - inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0 - UP BROADCAST RUNNING MASTER MULTICAST MTU:1500 Metric:1 - RX packets:7224794 errors:0 dropped:0 overruns:0 frame:0 - TX packets:3286647 errors:1 dropped:0 overruns:1 carrier:0 - collisions:0 txqueuelen:0 - -eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 - UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1 - RX packets:3573025 errors:0 dropped:0 overruns:0 frame:0 - TX packets:1643167 errors:1 dropped:0 overruns:1 carrier:0 - collisions:0 txqueuelen:100 - Interrupt:10 Base address:0x1080 - -eth1 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 - UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1 - RX packets:3651769 errors:0 dropped:0 overruns:0 frame:0 - TX packets:1643480 errors:0 dropped:0 overruns:0 carrier:0 - collisions:0 txqueuelen:100 - Interrupt:9 Base address:0x1400 - -5. Switch Configuration -======================= - - For this section, "switch" refers to whatever system the -bonded devices are directly connected to (i.e., where the other end of -the cable plugs into). This may be an actual dedicated switch device, -or it may be another regular system (e.g., another computer running -Linux), - - The active-backup, balance-tlb and balance-alb modes do not -require any specific configuration of the switch. - - The 802.3ad mode requires that the switch have the appropriate -ports configured as an 802.3ad aggregation. The precise method used -to configure this varies from switch to switch, but, for example, a -Cisco 3550 series switch requires that the appropriate ports first be -grouped together in a single etherchannel instance, then that -etherchannel is set to mode "lacp" to enable 802.3ad (instead of -standard EtherChannel). - - The balance-rr, balance-xor and broadcast modes generally -require that the switch have the appropriate ports grouped together. -The nomenclature for such a group differs between switches, it may be -called an "etherchannel" (as in the Cisco example, above), a "trunk -group" or some other similar variation. For these modes, each switch -will also have its own configuration options for the switch's transmit -policy to the bond. Typical choices include XOR of either the MAC or -IP addresses. The transmit policy of the two peers does not need to -match. For these three modes, the bonding mode really selects a -transmit policy for an EtherChannel group; all three will interoperate -with another EtherChannel group. - - -6. 802.1q VLAN Support -====================== - - It is possible to configure VLAN devices over a bond interface -using the 8021q driver. However, only packets coming from the 8021q -driver and passing through bonding will be tagged by default. Self -generated packets, for example, bonding's learning packets or ARP -packets generated by either ALB mode or the ARP monitor mechanism, are -tagged internally by bonding itself. As a result, bonding must -"learn" the VLAN IDs configured above it, and use those IDs to tag -self generated packets. - - For reasons of simplicity, and to support the use of adapters -that can do VLAN hardware acceleration offloading, the bonding -interface declares itself as fully hardware offloading capable, it gets -the add_vid/kill_vid notifications to gather the necessary -information, and it propagates those actions to the slaves. In case -of mixed adapter types, hardware accelerated tagged packets that -should go through an adapter that is not offloading capable are -"un-accelerated" by the bonding driver so the VLAN tag sits in the -regular location. - - VLAN interfaces *must* be added on top of a bonding interface -only after enslaving at least one slave. The bonding interface has a -hardware address of 00:00:00:00:00:00 until the first slave is added. -If the VLAN interface is created prior to the first enslavement, it -would pick up the all-zeroes hardware address. Once the first slave -is attached to the bond, the bond device itself will pick up the -slave's hardware address, which is then available for the VLAN device. - - Also, be aware that a similar problem can occur if all slaves -are released from a bond that still has one or more VLAN interfaces on -top of it. When a new slave is added, the bonding interface will -obtain its hardware address from the first slave, which might not -match the hardware address of the VLAN interfaces (which was -ultimately copied from an earlier slave). - - There are two methods to insure that the VLAN device operates -with the correct hardware address if all slaves are removed from a -bond interface: - - 1. Remove all VLAN interfaces then recreate them - - 2. Set the bonding interface's hardware address so that it -matches the hardware address of the VLAN interfaces. - - Note that changing a VLAN interface's HW address would set the -underlying device -- i.e. the bonding interface -- to promiscuous -mode, which might not be what you want. - - -7. Link Monitoring -================== - - The bonding driver at present supports two schemes for -monitoring a slave device's link state: the ARP monitor and the MII -monitor. - - At the present time, due to implementation restrictions in the -bonding driver itself, it is not possible to enable both ARP and MII -monitoring simultaneously. - -7.1 ARP Monitor Operation -------------------------- - - The ARP monitor operates as its name suggests: it sends ARP -queries to one or more designated peer systems on the network, and -uses the response as an indication that the link is operating. This -gives some assurance that traffic is actually flowing to and from one -or more peers on the local network. - - The ARP monitor relies on the device driver itself to verify -that traffic is flowing. In particular, the driver must keep up to -date the last receive time, dev->last_rx, and transmit start time, -dev->trans_start. If these are not updated by the driver, then the -ARP monitor will immediately fail any slaves using that driver, and -those slaves will stay down. If networking monitoring (tcpdump, etc) -shows the ARP requests and replies on the network, then it may be that -your device driver is not updating last_rx and trans_start. - -7.2 Configuring Multiple ARP Targets ------------------------------------- - - While ARP monitoring can be done with just one target, it can -be useful in a High Availability setup to have several targets to -monitor. In the case of just one target, the target itself may go -down or have a problem making it unresponsive to ARP requests. Having -an additional target (or several) increases the reliability of the ARP -monitoring. - - Multiple ARP targets must be separated by commas as follows: - -# example options for ARP monitoring with three targets -alias bond0 bonding -options bond0 arp_interval=60 arp_ip_target=192.168.0.1,192.168.0.3,192.168.0.9 - - For just a single target the options would resemble: - -# example options for ARP monitoring with one target -alias bond0 bonding -options bond0 arp_interval=60 arp_ip_target=192.168.0.100 - - -7.3 MII Monitor Operation -------------------------- - - The MII monitor monitors only the carrier state of the local -network interface. It accomplishes this in one of three ways: by -depending upon the device driver to maintain its carrier state, by -querying the device's MII registers, or by making an ethtool query to -the device. - - If the use_carrier module parameter is 1 (the default value), -then the MII monitor will rely on the driver for carrier state -information (via the netif_carrier subsystem). As explained in the -use_carrier parameter information, above, if the MII monitor fails to -detect carrier loss on the device (e.g., when the cable is physically -disconnected), it may be that the driver does not support -netif_carrier. - - If use_carrier is 0, then the MII monitor will first query the -device's (via ioctl) MII registers and check the link state. If that -request fails (not just that it returns carrier down), then the MII -monitor will make an ethtool ETHOOL_GLINK request to attempt to obtain -the same information. If both methods fail (i.e., the driver either -does not support or had some error in processing both the MII register -and ethtool requests), then the MII monitor will assume the link is -up. - -8. Potential Sources of Trouble -=============================== - -8.1 Adventures in Routing -------------------------- - - When bonding is configured, it is important that the slave -devices not have routes that supersede routes of the master (or, -generally, not have routes at all). For example, suppose the bonding -device bond0 has two slaves, eth0 and eth1, and the routing table is -as follows: - -Kernel IP routing table -Destination Gateway Genmask Flags MSS Window irtt Iface -10.0.0.0 0.0.0.0 255.255.0.0 U 40 0 0 eth0 -10.0.0.0 0.0.0.0 255.255.0.0 U 40 0 0 eth1 -10.0.0.0 0.0.0.0 255.255.0.0 U 40 0 0 bond0 -127.0.0.0 0.0.0.0 255.0.0.0 U 40 0 0 lo - - This routing configuration will likely still update the -receive/transmit times in the driver (needed by the ARP monitor), but -may bypass the bonding driver (because outgoing traffic to, in this -case, another host on network 10 would use eth0 or eth1 before bond0). - - The ARP monitor (and ARP itself) may become confused by this -configuration, because ARP requests (generated by the ARP monitor) -will be sent on one interface (bond0), but the corresponding reply -will arrive on a different interface (eth0). This reply looks to ARP -as an unsolicited ARP reply (because ARP matches replies on an -interface basis), and is discarded. The MII monitor is not affected -by the state of the routing table. - - The solution here is simply to insure that slaves do not have -routes of their own, and if for some reason they must, those routes do -not supersede routes of their master. This should generally be the -case, but unusual configurations or errant manual or automatic static -route additions may cause trouble. - -8.2 Ethernet Device Renaming ----------------------------- - - On systems with network configuration scripts that do not -associate physical devices directly with network interface names (so -that the same physical device always has the same "ethX" name), it may -be necessary to add some special logic to either /etc/modules.conf or -/etc/modprobe.conf (depending upon which is installed on the system). - - For example, given a modules.conf containing the following: - -alias bond0 bonding -options bond0 mode=some-mode miimon=50 -alias eth0 tg3 -alias eth1 tg3 -alias eth2 e1000 -alias eth3 e1000 - - If neither eth0 and eth1 are slaves to bond0, then when the -bond0 interface comes up, the devices may end up reordered. This -happens because bonding is loaded first, then its slave device's -drivers are loaded next. Since no other drivers have been loaded, -when the e1000 driver loads, it will receive eth0 and eth1 for its -devices, but the bonding configuration tries to enslave eth2 and eth3 -(which may later be assigned to the tg3 devices). - - Adding the following: - -add above bonding e1000 tg3 - - causes modprobe to load e1000 then tg3, in that order, when -bonding is loaded. This command is fully documented in the -modules.conf manual page. - - On systems utilizing modprobe.conf (or modprobe.conf.local), -an equivalent problem can occur. In this case, the following can be -added to modprobe.conf (or modprobe.conf.local, as appropriate), as -follows (all on one line; it has been split here for clarity): - -install bonding /sbin/modprobe tg3; /sbin/modprobe e1000; - /sbin/modprobe --ignore-install bonding - - This will, when loading the bonding module, rather than -performing the normal action, instead execute the provided command. -This command loads the device drivers in the order needed, then calls -modprobe with --ignore-install to cause the normal action to then take -place. Full documentation on this can be found in the modprobe.conf -and modprobe manual pages. - -8.3. Painfully Slow Or No Failed Link Detection By Miimon ---------------------------------------------------------- - - By default, bonding enables the use_carrier option, which -instructs bonding to trust the driver to maintain carrier state. - - As discussed in the options section, above, some drivers do -not support the netif_carrier_on/_off link state tracking system. -With use_carrier enabled, bonding will always see these links as up, -regardless of their actual state. - - Additionally, other drivers do support netif_carrier, but do -not maintain it in real time, e.g., only polling the link state at -some fixed interval. In this case, miimon will detect failures, but -only after some long period of time has expired. If it appears that -miimon is very slow in detecting link failures, try specifying -use_carrier=0 to see if that improves the failure detection time. If -it does, then it may be that the driver checks the carrier state at a -fixed interval, but does not cache the MII register values (so the -use_carrier=0 method of querying the registers directly works). If -use_carrier=0 does not improve the failover, then the driver may cache -the registers, or the problem may be elsewhere. - - Also, remember that miimon only checks for the device's -carrier state. It has no way to determine the state of devices on or -beyond other ports of a switch, or if a switch is refusing to pass -traffic while still maintaining carrier on. - -9. SNMP agents -=============== - - If running SNMP agents, the bonding driver should be loaded -before any network drivers participating in a bond. This requirement -is due to the interface index (ipAdEntIfIndex) being associated to -the first interface found with a given IP address. That is, there is -only one ipAdEntIfIndex for each IP address. For example, if eth0 and -eth1 are slaves of bond0 and the driver for eth0 is loaded before the -bonding driver, the interface for the IP address will be associated -with the eth0 interface. This configuration is shown below, the IP -address 192.168.1.1 has an interface index of 2 which indexes to eth0 -in the ifDescr table (ifDescr.2). - - interfaces.ifTable.ifEntry.ifDescr.1 = lo - interfaces.ifTable.ifEntry.ifDescr.2 = eth0 - interfaces.ifTable.ifEntry.ifDescr.3 = eth1 - interfaces.ifTable.ifEntry.ifDescr.4 = eth2 - interfaces.ifTable.ifEntry.ifDescr.5 = eth3 - interfaces.ifTable.ifEntry.ifDescr.6 = bond0 - ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.10.10.10 = 5 - ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.192.168.1.1 = 2 - ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.74.20.94 = 4 - ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.127.0.0.1 = 1 - - This problem is avoided by loading the bonding driver before -any network drivers participating in a bond. Below is an example of -loading the bonding driver first, the IP address 192.168.1.1 is -correctly associated with ifDescr.2. - - interfaces.ifTable.ifEntry.ifDescr.1 = lo - interfaces.ifTable.ifEntry.ifDescr.2 = bond0 - interfaces.ifTable.ifEntry.ifDescr.3 = eth0 - interfaces.ifTable.ifEntry.ifDescr.4 = eth1 - interfaces.ifTable.ifEntry.ifDescr.5 = eth2 - interfaces.ifTable.ifEntry.ifDescr.6 = eth3 - ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.10.10.10 = 6 - ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.192.168.1.1 = 2 - ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.74.20.94 = 5 - ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.127.0.0.1 = 1 - - While some distributions may not report the interface name in -ifDescr, the association between the IP address and IfIndex remains -and SNMP functions such as Interface_Scan_Next will report that -association. - -10. Promiscuous mode -==================== - - When running network monitoring tools, e.g., tcpdump, it is -common to enable promiscuous mode on the device, so that all traffic -is seen (instead of seeing only traffic destined for the local host). -The bonding driver handles promiscuous mode changes to the bonding -master device (e.g., bond0), and propagates the setting to the slave -devices. - - For the balance-rr, balance-xor, broadcast, and 802.3ad modes, -the promiscuous mode setting is propagated to all slaves. - - For the active-backup, balance-tlb and balance-alb modes, the -promiscuous mode setting is propagated only to the active slave. - - For balance-tlb mode, the active slave is the slave currently -receiving inbound traffic. - - For balance-alb mode, the active slave is the slave used as a -"primary." This slave is used for mode-specific control traffic, for -sending to peers that are unassigned or if the load is unbalanced. - - For the active-backup, balance-tlb and balance-alb modes, when -the active slave changes (e.g., due to a link failure), the -promiscuous setting will be propagated to the new active slave. - -11. Configuring Bonding for High Availability -============================================= - - High Availability refers to configurations that provide -maximum network availability by having redundant or backup devices, -links or switches between the host and the rest of the world. The -goal is to provide the maximum availability of network connectivity -(i.e., the network always works), even though other configurations -could provide higher throughput. - -11.1 High Availability in a Single Switch Topology --------------------------------------------------- - - If two hosts (or a host and a single switch) are directly -connected via multiple physical links, then there is no availability -penalty to optimizing for maximum bandwidth. In this case, there is -only one switch (or peer), so if it fails, there is no alternative -access to fail over to. Additionally, the bonding load balance modes -support link monitoring of their members, so if individual links fail, -the load will be rebalanced across the remaining devices. - - See Section 13, "Configuring Bonding for Maximum Throughput" -for information on configuring bonding with one peer device. - -11.2 High Availability in a Multiple Switch Topology ----------------------------------------------------- - - With multiple switches, the configuration of bonding and the -network changes dramatically. In multiple switch topologies, there is -a trade off between network availability and usable bandwidth. - - Below is a sample network, configured to maximize the -availability of the network: - - | | - |port3 port3| - +-----+----+ +-----+----+ - | |port2 ISL port2| | - | switch A +--------------------------+ switch B | - | | | | - +-----+----+ +-----++---+ - |port1 port1| - | +-------+ | - +-------------+ host1 +---------------+ - eth0 +-------+ eth1 - - In this configuration, there is a link between the two -switches (ISL, or inter switch link), and multiple ports connecting to -the outside world ("port3" on each switch). There is no technical -reason that this could not be extended to a third switch. - -11.2.1 HA Bonding Mode Selection for Multiple Switch Topology -------------------------------------------------------------- - - In a topology such as the example above, the active-backup and -broadcast modes are the only useful bonding modes when optimizing for -availability; the other modes require all links to terminate on the -same peer for them to behave rationally. - -active-backup: This is generally the preferred mode, particularly if - the switches have an ISL and play together well. If the - network configuration is such that one switch is specifically - a backup switch (e.g., has lower capacity, higher cost, etc), - then the primary option can be used to insure that the - preferred link is always used when it is available. - -broadcast: This mode is really a special purpose mode, and is suitable - only for very specific needs. For example, if the two - switches are not connected (no ISL), and the networks beyond - them are totally independent. In this case, if it is - necessary for some specific one-way traffic to reach both - independent networks, then the broadcast mode may be suitable. - -11.2.2 HA Link Monitoring Selection for Multiple Switch Topology ----------------------------------------------------------------- - - The choice of link monitoring ultimately depends upon your -switch. If the switch can reliably fail ports in response to other -failures, then either the MII or ARP monitors should work. For -example, in the above example, if the "port3" link fails at the remote -end, the MII monitor has no direct means to detect this. The ARP -monitor could be configured with a target at the remote end of port3, -thus detecting that failure without switch support. - - In general, however, in a multiple switch topology, the ARP -monitor can provide a higher level of reliability in detecting end to -end connectivity failures (which may be caused by the failure of any -individual component to pass traffic for any reason). Additionally, -the ARP monitor should be configured with multiple targets (at least -one for each switch in the network). This will insure that, -regardless of which switch is active, the ARP monitor has a suitable -target to query. - - Note, also, that of late many switches now support a functionality -generally referred to as "trunk failover." This is a feature of the -switch that causes the link state of a particular switch port to be set -down (or up) when the state of another switch port goes down (or up). -Its purpose is to propagate link failures from logically "exterior" ports -to the logically "interior" ports that bonding is able to monitor via -miimon. Availability and configuration for trunk failover varies by -switch, but this can be a viable alternative to the ARP monitor when using -suitable switches. - -12. Configuring Bonding for Maximum Throughput -============================================== - -12.1 Maximizing Throughput in a Single Switch Topology ------------------------------------------------------- - - In a single switch configuration, the best method to maximize -throughput depends upon the application and network environment. The -various load balancing modes each have strengths and weaknesses in -different environments, as detailed below. - - For this discussion, we will break down the topologies into -two categories. Depending upon the destination of most traffic, we -categorize them into either "gatewayed" or "local" configurations. - - In a gatewayed configuration, the "switch" is acting primarily -as a router, and the majority of traffic passes through this router to -other networks. An example would be the following: - - - +----------+ +----------+ - | |eth0 port1| | to other networks - | Host A +---------------------+ router +-------------------> - | +---------------------+ | Hosts B and C are out - | |eth1 port2| | here somewhere - +----------+ +----------+ - - The router may be a dedicated router device, or another host -acting as a gateway. For our discussion, the important point is that -the majority of traffic from Host A will pass through the router to -some other network before reaching its final destination. - - In a gatewayed network configuration, although Host A may -communicate with many other systems, all of its traffic will be sent -and received via one other peer on the local network, the router. - - Note that the case of two systems connected directly via -multiple physical links is, for purposes of configuring bonding, the -same as a gatewayed configuration. In that case, it happens that all -traffic is destined for the "gateway" itself, not some other network -beyond the gateway. - - In a local configuration, the "switch" is acting primarily as -a switch, and the majority of traffic passes through this switch to -reach other stations on the same network. An example would be the -following: - - +----------+ +----------+ +--------+ - | |eth0 port1| +-------+ Host B | - | Host A +------------+ switch |port3 +--------+ - | +------------+ | +--------+ - | |eth1 port2| +------------------+ Host C | - +----------+ +----------+port4 +--------+ - - - Again, the switch may be a dedicated switch device, or another -host acting as a gateway. For our discussion, the important point is -that the majority of traffic from Host A is destined for other hosts -on the same local network (Hosts B and C in the above example). - - In summary, in a gatewayed configuration, traffic to and from -the bonded device will be to the same MAC level peer on the network -(the gateway itself, i.e., the router), regardless of its final -destination. In a local configuration, traffic flows directly to and -from the final destinations, thus, each destination (Host B, Host C) -will be addressed directly by their individual MAC addresses. - - This distinction between a gatewayed and a local network -configuration is important because many of the load balancing modes -available use the MAC addresses of the local network source and -destination to make load balancing decisions. The behavior of each -mode is described below. - - -12.1.1 MT Bonding Mode Selection for Single Switch Topology ------------------------------------------------------------ - - This configuration is the easiest to set up and to understand, -although you will have to decide which bonding mode best suits your -needs. The trade offs for each mode are detailed below: - -balance-rr: This mode is the only mode that will permit a single - TCP/IP connection to stripe traffic across multiple - interfaces. It is therefore the only mode that will allow a - single TCP/IP stream to utilize more than one interface's - worth of throughput. This comes at a cost, however: the - striping generally results in peer systems receiving packets out - of order, causing TCP/IP's congestion control system to kick - in, often by retransmitting segments. - - It is possible to adjust TCP/IP's congestion limits by - altering the net.ipv4.tcp_reordering sysctl parameter. The - usual default value is 3, and the maximum useful value is 127. - For a four interface balance-rr bond, expect that a single - TCP/IP stream will utilize no more than approximately 2.3 - interface's worth of throughput, even after adjusting - tcp_reordering. - - Note that the fraction of packets that will be delivered out of - order is highly variable, and is unlikely to be zero. The level - of reordering depends upon a variety of factors, including the - networking interfaces, the switch, and the topology of the - configuration. Speaking in general terms, higher speed network - cards produce more reordering (due to factors such as packet - coalescing), and a "many to many" topology will reorder at a - higher rate than a "many slow to one fast" configuration. - - Many switches do not support any modes that stripe traffic - (instead choosing a port based upon IP or MAC level addresses); - for those devices, traffic for a particular connection flowing - through the switch to a balance-rr bond will not utilize greater - than one interface's worth of bandwidth. - - If you are utilizing protocols other than TCP/IP, UDP for - example, and your application can tolerate out of order - delivery, then this mode can allow for single stream datagram - performance that scales near linearly as interfaces are added - to the bond. - - This mode requires the switch to have the appropriate ports - configured for "etherchannel" or "trunking." - -active-backup: There is not much advantage in this network topology to - the active-backup mode, as the inactive backup devices are all - connected to the same peer as the primary. In this case, a - load balancing mode (with link monitoring) will provide the - same level of network availability, but with increased - available bandwidth. On the plus side, active-backup mode - does not require any configuration of the switch, so it may - have value if the hardware available does not support any of - the load balance modes. - -balance-xor: This mode will limit traffic such that packets destined - for specific peers will always be sent over the same - interface. Since the destination is determined by the MAC - addresses involved, this mode works best in a "local" network - configuration (as described above), with destinations all on - the same local network. This mode is likely to be suboptimal - if all your traffic is passed through a single router (i.e., a - "gatewayed" network configuration, as described above). - - As with balance-rr, the switch ports need to be configured for - "etherchannel" or "trunking." - -broadcast: Like active-backup, there is not much advantage to this - mode in this type of network topology. - -802.3ad: This mode can be a good choice for this type of network - topology. The 802.3ad mode is an IEEE standard, so all peers - that implement 802.3ad should interoperate well. The 802.3ad - protocol includes automatic configuration of the aggregates, - so minimal manual configuration of the switch is needed - (typically only to designate that some set of devices is - available for 802.3ad). The 802.3ad standard also mandates - that frames be delivered in order (within certain limits), so - in general single connections will not see misordering of - packets. The 802.3ad mode does have some drawbacks: the - standard mandates that all devices in the aggregate operate at - the same speed and duplex. Also, as with all bonding load - balance modes other than balance-rr, no single connection will - be able to utilize more than a single interface's worth of - bandwidth. - - Additionally, the linux bonding 802.3ad implementation - distributes traffic by peer (using an XOR of MAC addresses), - so in a "gatewayed" configuration, all outgoing traffic will - generally use the same device. Incoming traffic may also end - up on a single device, but that is dependent upon the - balancing policy of the peer's 8023.ad implementation. In a - "local" configuration, traffic will be distributed across the - devices in the bond. - - Finally, the 802.3ad mode mandates the use of the MII monitor, - therefore, the ARP monitor is not available in this mode. - -balance-tlb: The balance-tlb mode balances outgoing traffic by peer. - Since the balancing is done according to MAC address, in a - "gatewayed" configuration (as described above), this mode will - send all traffic across a single device. However, in a - "local" network configuration, this mode balances multiple - local network peers across devices in a vaguely intelligent - manner (not a simple XOR as in balance-xor or 802.3ad mode), - so that mathematically unlucky MAC addresses (i.e., ones that - XOR to the same value) will not all "bunch up" on a single - interface. - - Unlike 802.3ad, interfaces may be of differing speeds, and no - special switch configuration is required. On the down side, - in this mode all incoming traffic arrives over a single - interface, this mode requires certain ethtool support in the - network device driver of the slave interfaces, and the ARP - monitor is not available. - -balance-alb: This mode is everything that balance-tlb is, and more. - It has all of the features (and restrictions) of balance-tlb, - and will also balance incoming traffic from local network - peers (as described in the Bonding Module Options section, - above). - - The only additional down side to this mode is that the network - device driver must support changing the hardware address while - the device is open. - -12.1.2 MT Link Monitoring for Single Switch Topology ----------------------------------------------------- - - The choice of link monitoring may largely depend upon which -mode you choose to use. The more advanced load balancing modes do not -support the use of the ARP monitor, and are thus restricted to using -the MII monitor (which does not provide as high a level of end to end -assurance as the ARP monitor). - -12.2 Maximum Throughput in a Multiple Switch Topology ------------------------------------------------------ - - Multiple switches may be utilized to optimize for throughput -when they are configured in parallel as part of an isolated network -between two or more systems, for example: - - +-----------+ - | Host A | - +-+---+---+-+ - | | | - +--------+ | +---------+ - | | | - +------+---+ +-----+----+ +-----+----+ - | Switch A | | Switch B | | Switch C | - +------+---+ +-----+----+ +-----+----+ - | | | - +--------+ | +---------+ - | | | - +-+---+---+-+ - | Host B | - +-----------+ - - In this configuration, the switches are isolated from one -another. One reason to employ a topology such as this is for an -isolated network with many hosts (a cluster configured for high -performance, for example), using multiple smaller switches can be more -cost effective than a single larger switch, e.g., on a network with 24 -hosts, three 24 port switches can be significantly less expensive than -a single 72 port switch. - - If access beyond the network is required, an individual host -can be equipped with an additional network device connected to an -external network; this host then additionally acts as a gateway. - -12.2.1 MT Bonding Mode Selection for Multiple Switch Topology -------------------------------------------------------------- - - In actual practice, the bonding mode typically employed in -configurations of this type is balance-rr. Historically, in this -network configuration, the usual caveats about out of order packet -delivery are mitigated by the use of network adapters that do not do -any kind of packet coalescing (via the use of NAPI, or because the -device itself does not generate interrupts until some number of -packets has arrived). When employed in this fashion, the balance-rr -mode allows individual connections between two hosts to effectively -utilize greater than one interface's bandwidth. - -12.2.2 MT Link Monitoring for Multiple Switch Topology ------------------------------------------------------- - - Again, in actual practice, the MII monitor is most often used -in this configuration, as performance is given preference over -availability. The ARP monitor will function in this topology, but its -advantages over the MII monitor are mitigated by the volume of probes -needed as the number of systems involved grows (remember that each -host in the network is configured with bonding). - -13. Switch Behavior Issues -========================== - -13.1 Link Establishment and Failover Delays -------------------------------------------- - - Some switches exhibit undesirable behavior with regard to the -timing of link up and down reporting by the switch. - - First, when a link comes up, some switches may indicate that -the link is up (carrier available), but not pass traffic over the -interface for some period of time. This delay is typically due to -some type of autonegotiation or routing protocol, but may also occur -during switch initialization (e.g., during recovery after a switch -failure). If you find this to be a problem, specify an appropriate -value to the updelay bonding module option to delay the use of the -relevant interface(s). - - Second, some switches may "bounce" the link state one or more -times while a link is changing state. This occurs most commonly while -the switch is initializing. Again, an appropriate updelay value may -help. - - Note that when a bonding interface has no active links, the -driver will immediately reuse the first link that goes up, even if the -updelay parameter has been specified (the updelay is ignored in this -case). If there are slave interfaces waiting for the updelay timeout -to expire, the interface that first went into that state will be -immediately reused. This reduces down time of the network if the -value of updelay has been overestimated, and since this occurs only in -cases with no connectivity, there is no additional penalty for -ignoring the updelay. - - In addition to the concerns about switch timings, if your -switches take a long time to go into backup mode, it may be desirable -to not activate a backup interface immediately after a link goes down. -Failover may be delayed via the downdelay bonding module option. - -13.2 Duplicated Incoming Packets --------------------------------- - - NOTE: Starting with version 3.0.2, the bonding driver has logic to -suppress duplicate packets, which should largely eliminate this problem. -The following description is kept for reference. - - It is not uncommon to observe a short burst of duplicated -traffic when the bonding device is first used, or after it has been -idle for some period of time. This is most easily observed by issuing -a "ping" to some other host on the network, and noticing that the -output from ping flags duplicates (typically one per slave). - - For example, on a bond in active-backup mode with five slaves -all connected to one switch, the output may appear as follows: - -# ping -n 10.0.4.2 -PING 10.0.4.2 (10.0.4.2) from 10.0.3.10 : 56(84) bytes of data. -64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.7 ms -64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!) -64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!) -64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!) -64 bytes from 10.0.4.2: icmp_seq=1 ttl=64 time=13.8 ms (DUP!) -64 bytes from 10.0.4.2: icmp_seq=2 ttl=64 time=0.216 ms -64 bytes from 10.0.4.2: icmp_seq=3 ttl=64 time=0.267 ms -64 bytes from 10.0.4.2: icmp_seq=4 ttl=64 time=0.222 ms - - This is not due to an error in the bonding driver, rather, it -is a side effect of how many switches update their MAC forwarding -tables. Initially, the switch does not associate the MAC address in -the packet with a particular switch port, and so it may send the -traffic to all ports until its MAC forwarding table is updated. Since -the interfaces attached to the bond may occupy multiple ports on a -single switch, when the switch (temporarily) floods the traffic to all -ports, the bond device receives multiple copies of the same packet -(one per slave device). - - The duplicated packet behavior is switch dependent, some -switches exhibit this, and some do not. On switches that display this -behavior, it can be induced by clearing the MAC forwarding table (on -most Cisco switches, the privileged command "clear mac address-table -dynamic" will accomplish this). - -14. Hardware Specific Considerations -==================================== - - This section contains additional information for configuring -bonding on specific hardware platforms, or for interfacing bonding -with particular switches or other devices. - -14.1 IBM BladeCenter --------------------- - - This applies to the JS20 and similar systems. - - On the JS20 blades, the bonding driver supports only -balance-rr, active-backup, balance-tlb and balance-alb modes. This is -largely due to the network topology inside the BladeCenter, detailed -below. - -JS20 network adapter information --------------------------------- - - All JS20s come with two Broadcom Gigabit Ethernet ports -integrated on the planar (that's "motherboard" in IBM-speak). In the -BladeCenter chassis, the eth0 port of all JS20 blades is hard wired to -I/O Module #1; similarly, all eth1 ports are wired to I/O Module #2. -An add-on Broadcom daughter card can be installed on a JS20 to provide -two more Gigabit Ethernet ports. These ports, eth2 and eth3, are -wired to I/O Modules 3 and 4, respectively. - - Each I/O Module may contain either a switch or a passthrough -module (which allows ports to be directly connected to an external -switch). Some bonding modes require a specific BladeCenter internal -network topology in order to function; these are detailed below. - - Additional BladeCenter-specific networking information can be -found in two IBM Redbooks (www.ibm.com/redbooks): - -"IBM eServer BladeCenter Networking Options" -"IBM eServer BladeCenter Layer 2-7 Network Switching" - -BladeCenter networking configuration ------------------------------------- - - Because a BladeCenter can be configured in a very large number -of ways, this discussion will be confined to describing basic -configurations. - - Normally, Ethernet Switch Modules (ESMs) are used in I/O -modules 1 and 2. In this configuration, the eth0 and eth1 ports of a -JS20 will be connected to different internal switches (in the -respective I/O modules). - - A passthrough module (OPM or CPM, optical or copper, -passthrough module) connects the I/O module directly to an external -switch. By using PMs in I/O module #1 and #2, the eth0 and eth1 -interfaces of a JS20 can be redirected to the outside world and -connected to a common external switch. - - Depending upon the mix of ESMs and PMs, the network will -appear to bonding as either a single switch topology (all PMs) or as a -multiple switch topology (one or more ESMs, zero or more PMs). It is -also possible to connect ESMs together, resulting in a configuration -much like the example in "High Availability in a Multiple Switch -Topology," above. - -Requirements for specific modes -------------------------------- - - The balance-rr mode requires the use of passthrough modules -for devices in the bond, all connected to an common external switch. -That switch must be configured for "etherchannel" or "trunking" on the -appropriate ports, as is usual for balance-rr. - - The balance-alb and balance-tlb modes will function with -either switch modules or passthrough modules (or a mix). The only -specific requirement for these modes is that all network interfaces -must be able to reach all destinations for traffic sent over the -bonding device (i.e., the network must converge at some point outside -the BladeCenter). - - The active-backup mode has no additional requirements. - -Link monitoring issues ----------------------- - - When an Ethernet Switch Module is in place, only the ARP -monitor will reliably detect link loss to an external switch. This is -nothing unusual, but examination of the BladeCenter cabinet would -suggest that the "external" network ports are the ethernet ports for -the system, when it fact there is a switch between these "external" -ports and the devices on the JS20 system itself. The MII monitor is -only able to detect link failures between the ESM and the JS20 system. - - When a passthrough module is in place, the MII monitor does -detect failures to the "external" port, which is then directly -connected to the JS20 system. - -Other concerns --------------- - - The Serial Over LAN (SoL) link is established over the primary -ethernet (eth0) only, therefore, any loss of link to eth0 will result -in losing your SoL connection. It will not fail over with other -network traffic, as the SoL system is beyond the control of the -bonding driver. - - It may be desirable to disable spanning tree on the switch -(either the internal Ethernet Switch Module, or an external switch) to -avoid fail-over delay issues when using bonding. - - -15. Frequently Asked Questions -============================== - -1. Is it SMP safe? - - Yes. The old 2.0.xx channel bonding patch was not SMP safe. -The new driver was designed to be SMP safe from the start. - -2. What type of cards will work with it? - - Any Ethernet type cards (you can even mix cards - a Intel -EtherExpress PRO/100 and a 3com 3c905b, for example). For most modes, -devices need not be of the same speed. - - Starting with version 3.2.1, bonding also supports Infiniband -slaves in active-backup mode. - -3. How many bonding devices can I have? - - There is no limit. - -4. How many slaves can a bonding device have? - - This is limited only by the number of network interfaces Linux -supports and/or the number of network cards you can place in your -system. - -5. What happens when a slave link dies? - - If link monitoring is enabled, then the failing device will be -disabled. The active-backup mode will fail over to a backup link, and -other modes will ignore the failed link. The link will continue to be -monitored, and should it recover, it will rejoin the bond (in whatever -manner is appropriate for the mode). See the sections on High -Availability and the documentation for each mode for additional -information. - - Link monitoring can be enabled via either the miimon or -arp_interval parameters (described in the module parameters section, -above). In general, miimon monitors the carrier state as sensed by -the underlying network device, and the arp monitor (arp_interval) -monitors connectivity to another host on the local network. - - If no link monitoring is configured, the bonding driver will -be unable to detect link failures, and will assume that all links are -always available. This will likely result in lost packets, and a -resulting degradation of performance. The precise performance loss -depends upon the bonding mode and network configuration. - -6. Can bonding be used for High Availability? - - Yes. See the section on High Availability for details. - -7. Which switches/systems does it work with? - - The full answer to this depends upon the desired mode. - - In the basic balance modes (balance-rr and balance-xor), it -works with any system that supports etherchannel (also called -trunking). Most managed switches currently available have such -support, and many unmanaged switches as well. - - The advanced balance modes (balance-tlb and balance-alb) do -not have special switch requirements, but do need device drivers that -support specific features (described in the appropriate section under -module parameters, above). - - In 802.3ad mode, it works with systems that support IEEE -802.3ad Dynamic Link Aggregation. Most managed and many unmanaged -switches currently available support 802.3ad. - - The active-backup mode should work with any Layer-II switch. - -8. Where does a bonding device get its MAC address from? - - When using slave devices that have fixed MAC addresses, or when -the fail_over_mac option is enabled, the bonding device's MAC address is -the MAC address of the active slave. - - For other configurations, if not explicitly configured (with -ifconfig or ip link), the MAC address of the bonding device is taken from -its first slave device. This MAC address is then passed to all following -slaves and remains persistent (even if the first slave is removed) until -the bonding device is brought down or reconfigured. - - If you wish to change the MAC address, you can set it with -ifconfig or ip link: - -# ifconfig bond0 hw ether 00:11:22:33:44:55 - -# ip link set bond0 address 66:77:88:99:aa:bb - - The MAC address can be also changed by bringing down/up the -device and then changing its slaves (or their order): - -# ifconfig bond0 down ; modprobe -r bonding -# ifconfig bond0 .... up -# ifenslave bond0 eth... - - This method will automatically take the address from the next -slave that is added. - - To restore your slaves' MAC addresses, you need to detach them -from the bond (`ifenslave -d bond0 eth0'). The bonding driver will -then restore the MAC addresses that the slaves had before they were -enslaved. - -16. Resources and Links -======================= - -The latest version of the bonding driver can be found in the latest -version of the linux kernel, found on http://kernel.org - -The latest version of this document can be found in either the latest -kernel source (named Documentation/networking/bonding.txt), or on the -bonding sourceforge site: - -http://www.sourceforge.net/projects/bonding - -Discussions regarding the bonding driver take place primarily on the -bonding-devel mailing list, hosted at sourceforge.net. If you have -questions or problems, post them to the list. The list address is: - -bonding-devel@lists.sourceforge.net - - The administrative interface (to subscribe or unsubscribe) can -be found at: - -https://lists.sourceforge.net/lists/listinfo/bonding-devel - -Donald Becker's Ethernet Drivers and diag programs may be found at : - - http://www.scyld.com/network/ - -You will also find a lot of information regarding Ethernet, NWay, MII, -etc. at www.scyld.com. - --- END -- diff --git a/system/base/iputils/files/ifenslave/ifenslave.8 b/system/base/iputils/files/ifenslave/ifenslave.8 deleted file mode 100644 index 89998923..00000000 --- a/system/base/iputils/files/ifenslave/ifenslave.8 +++ /dev/null @@ -1,68 +0,0 @@ -.Dd 2004-04-09 -.Dt IFENSLAVE 8 -.\" Manual page created by Guus Sliepen -.Sh NAME -.Nm ifenslave -.Nd Attach and detach slave network devices to a bonding device. -.Sh SYNOPSIS -.Nm -.Op Fl acdfhuvV -.Op Fl -all-interfaces -.Op Fl -change-active -.Op Fl -detach -.Op Fl -force -.Op Fl -help -.Op Fl -usage -.Op Fl -verbose -.Op Fl -version -.Ar master -.Ar slave -.No ... -.Sh DESCRIPTION -.Nm -is a tool to attach and detach slave network devices to a bonding device. -A bonding device will act like a normal Ethernet network device to the kernel, -but will send out the packets via the slave devices using a simple round-robin scheduler. -This allows for simple load-balancing, -identical to "channel bonding" or "trunking" techniques used in switches. -.Pp -The kernel must have support for bonding devices for -.Nm -to be useful. -.Sh OPTIONS -.Bl -tag -width indent -.It Fl a, -all-interfaces -Show information about all interfaces. -.It Fl c, -change-active -Change active slave. -.It Fl d, -detach -Removes slave interfaces from the bonding device. -.It Fl f, -force -Force actions to be taken if one of the specified interfaces appears not to belong to an Ethernet device. -.It Fl h, -help -Display a help message and exit. -.It Fl u, -usage -Show usage information and exit. -.It Fl v, -verbose -Print warning and debug messages. -.It Fl V, -version -Show version information and exit. -.El -If not options are given, the default action will be to enslave interfaces. -.Sh EXAMPLE -The following example shows how to setup a bonding device and -enslave two real Ethernet devices to it: -.Bd -literal -# modprobe bonding -# ifconfig bond0 192.168.0.1 netmask 255.255.0.0 -# ifenslave bond0 eth0 eth1 -.Ed -.Sh AUTHOR -.Nm -was originally written by -.An Donald Becker Aq becker@cesdis.gsfc.nasa.gov , -and has since been updated by various kernel developers. -.Pp -This manual page was written by -.An Guus Sliepen Aq guus@debian.org -for the Debian GNU/Linux system. diff --git a/system/base/iputils/files/ifenslave/ifenslave.c b/system/base/iputils/files/ifenslave/ifenslave.c deleted file mode 100644 index bd375058..00000000 --- a/system/base/iputils/files/ifenslave/ifenslave.c +++ /dev/null @@ -1,1103 +0,0 @@ -/* Mode: C; - * ifenslave.c: Configure network interfaces for parallel routing. - * - * This program controls the Linux implementation of running multiple - * network interfaces in parallel. - * - * Author: Donald Becker - * Copyright 1994-1996 Donald Becker - * - * This program is free software; you can redistribute it - * and/or modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation. - * - * The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O - * Center of Excellence in Space Data and Information Sciences - * Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 - * - * Changes : - * - 2000/10/02 Willy Tarreau : - * - few fixes. Master's MAC address is now correctly taken from - * the first device when not previously set ; - * - detach support : call BOND_RELEASE to detach an enslaved interface. - * - give a mini-howto from command-line help : # ifenslave -h - * - * - 2001/02/16 Chad N. Tindel : - * - Master is now brought down before setting the MAC address. In - * the 2.4 kernel you can't change the MAC address while the device is - * up because you get EBUSY. - * - * - 2001/09/13 Takao Indoh - * - Added the ability to change the active interface on a mode 1 bond - * at runtime. - * - * - 2001/10/23 Chad N. Tindel : - * - No longer set the MAC address of the master. The bond device will - * take care of this itself - * - Try the SIOC*** versions of the bonding ioctls before using the - * old versions - * - 2002/02/18 Erik Habbinga : - * - ifr2.ifr_flags was not initialized in the hwaddr_notset case, - * SIOCGIFFLAGS now called before hwaddr_notset test - * - * - 2002/10/31 Tony Cureington : - * - If the master does not have a hardware address when the first slave - * is enslaved, the master is assigned the hardware address of that - * slave - there is a comment in bonding.c stating "ifenslave takes - * care of this now." This corrects the problem of slaves having - * different hardware addresses in active-backup mode when - * multiple interfaces are specified on a single ifenslave command - * (ifenslave bond0 eth0 eth1). - * - * - 2003/03/18 - Tsippy Mendelson and - * Shmulik Hen - * - Moved setting the slave's mac address and openning it, from - * the application to the driver. This enables support of modes - * that need to use the unique mac address of each slave. - * The driver also takes care of closing the slave and restoring its - * original mac address upon release. - * In addition, block possibility of enslaving before the master is up. - * This prevents putting the system in an undefined state. - * - * - 2003/05/01 - Amir Noam - * - Added ABI version control to restore compatibility between - * new/old ifenslave and new/old bonding. - * - Prevent adding an adapter that is already a slave. - * Fixes the problem of stalling the transmission and leaving - * the slave in a down state. - * - * - 2003/05/01 - Shmulik Hen - * - Prevent enslaving if the bond device is down. - * Fixes the problem of leaving the system in unstable state and - * halting when trying to remove the module. - * - Close socket on all abnormal exists. - * - Add versioning scheme that follows that of the bonding driver. - * current version is 1.0.0 as a base line. - * - * - 2003/05/22 - Jay Vosburgh - * - ifenslave -c was broken; it's now fixed - * - Fixed problem with routes vanishing from master during enslave - * processing. - * - * - 2003/05/27 - Amir Noam - * - Fix backward compatibility issues: - * For drivers not using ABI versions, slave was set down while - * it should be left up before enslaving. - * Also, master was not set down and the default set_mac_address() - * would fail and generate an error message in the system log. - * - For opt_c: slave should not be set to the master's setting - * while it is running. It was already set during enslave. To - * simplify things, it is now handled separately. - * - * - 2003/12/01 - Shmulik Hen - * - Code cleanup and style changes - * set version to 1.1.0 - */ - -#define APP_VERSION "1.1.0" -#define APP_RELDATE "December 1, 2003" -#define APP_NAME "ifenslave" - -static char *version = -APP_NAME ".c:v" APP_VERSION " (" APP_RELDATE ")\n" -"o Donald Becker (becker@cesdis.gsfc.nasa.gov).\n" -"o Detach support added on 2000/10/02 by Willy Tarreau (willy at meta-x.org).\n" -"o 2.4 kernel support added on 2001/02/16 by Chad N. Tindel\n" -" (ctindel at ieee dot org).\n"; - -static const char *usage_msg = -"Usage: ifenslave [-f] [...]\n" -" ifenslave -d [...]\n" -" ifenslave -c \n" -" ifenslave --help\n"; - -static const char *help_msg = -"\n" -" To create a bond device, simply follow these three steps :\n" -" - ensure that the required drivers are properly loaded :\n" -" # modprobe bonding ; modprobe <3c59x|eepro100|pcnet32|tulip|...>\n" -" - assign an IP address to the bond device :\n" -" # ifconfig bond0 netmask broadcast \n" -" - attach all the interfaces you need to the bond device :\n" -" # ifenslave [{-f|--force}] bond0 eth0 [eth1 [eth2]...]\n" -" If bond0 didn't have a MAC address, it will take eth0's. Then, all\n" -" interfaces attached AFTER this assignment will get the same MAC addr.\n" -" (except for ALB/TLB modes)\n" -"\n" -" To set the bond device down and automatically release all the slaves :\n" -" # ifconfig bond0 down\n" -"\n" -" To detach a dead interface without setting the bond device down :\n" -" # ifenslave {-d|--detach} bond0 eth0 [eth1 [eth2]...]\n" -"\n" -" To change active slave :\n" -" # ifenslave {-c|--change-active} bond0 eth0\n" -"\n" -" To show master interface info\n" -" # ifenslave bond0\n" -"\n" -" To show all interfaces info\n" -" # ifenslave {-a|--all-interfaces}\n" -"\n" -" To be more verbose\n" -" # ifenslave {-v|--verbose} ...\n" -"\n" -" # ifenslave {-u|--usage} Show usage\n" -" # ifenslave {-V|--version} Show version\n" -" # ifenslave {-h|--help} This message\n" -"\n"; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef unsigned long long u64; /* hack, so we may include kernel's ethtool.h */ -typedef __uint32_t u32; /* ditto */ -typedef __uint16_t u16; /* ditto */ -typedef __uint8_t u8; /* ditto */ -#include - -struct option longopts[] = { - /* { name has_arg *flag val } */ - {"all-interfaces", 0, 0, 'a'}, /* Show all interfaces. */ - {"change-active", 0, 0, 'c'}, /* Change the active slave. */ - {"detach", 0, 0, 'd'}, /* Detach a slave interface. */ - {"force", 0, 0, 'f'}, /* Force the operation. */ - {"help", 0, 0, 'h'}, /* Give help */ - {"usage", 0, 0, 'u'}, /* Give usage */ - {"verbose", 0, 0, 'v'}, /* Report each action taken. */ - {"version", 0, 0, 'V'}, /* Emit version information. */ - { 0, 0, 0, 0} -}; - -/* Command-line flags. */ -unsigned int -opt_a = 0, /* Show-all-interfaces flag. */ -opt_c = 0, /* Change-active-slave flag. */ -opt_d = 0, /* Detach a slave interface. */ -opt_f = 0, /* Force the operation. */ -opt_h = 0, /* Help */ -opt_u = 0, /* Usage */ -opt_v = 0, /* Verbose flag. */ -opt_V = 0; /* Version */ - -int skfd = -1; /* AF_INET socket for ioctl() calls.*/ -int abi_ver = 0; /* userland - kernel ABI version */ -int hwaddr_set = 0; /* Master's hwaddr is set */ -int saved_errno; - -struct ifreq master_mtu, master_flags, master_hwaddr; -struct ifreq slave_mtu, slave_flags, slave_hwaddr; - -struct dev_ifr { - struct ifreq *req_ifr; - char *req_name; - int req_type; -}; - -struct dev_ifr master_ifra[] = { - {&master_mtu, "SIOCGIFMTU", SIOCGIFMTU}, - {&master_flags, "SIOCGIFFLAGS", SIOCGIFFLAGS}, - {&master_hwaddr, "SIOCGIFHWADDR", SIOCGIFHWADDR}, - {NULL, "", 0} -}; - -struct dev_ifr slave_ifra[] = { - {&slave_mtu, "SIOCGIFMTU", SIOCGIFMTU}, - {&slave_flags, "SIOCGIFFLAGS", SIOCGIFFLAGS}, - {&slave_hwaddr, "SIOCGIFHWADDR", SIOCGIFHWADDR}, - {NULL, "", 0} -}; - -static void if_print(char *ifname); -static int get_drv_info(char *master_ifname); -static int get_if_settings(char *ifname, struct dev_ifr ifra[]); -static int get_slave_flags(char *slave_ifname); -static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr); -static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr); -static int set_slave_mtu(char *slave_ifname, int mtu); -static int set_if_flags(char *ifname, short flags); -static int set_if_up(char *ifname, short flags); -static int set_if_down(char *ifname, short flags); -static int clear_if_addr(char *ifname); -static int set_if_addr(char *master_ifname, char *slave_ifname); -static int change_active(char *master_ifname, char *slave_ifname); -static int enslave(char *master_ifname, char *slave_ifname); -static int release(char *master_ifname, char *slave_ifname); -#define v_print(fmt, args...) \ - if (opt_v) \ - fprintf(stderr, fmt, ## args ) - -int main(int argc, char *argv[]) -{ - char **spp, *master_ifname, *slave_ifname; - int c, i, rv; - int res = 0; - int exclusive = 0; - - while ((c = getopt_long(argc, argv, "acdfhuvV", longopts, 0)) != EOF) { - switch (c) { - case 'a': opt_a++; exclusive++; break; - case 'c': opt_c++; exclusive++; break; - case 'd': opt_d++; exclusive++; break; - case 'f': opt_f++; exclusive++; break; - case 'h': opt_h++; exclusive++; break; - case 'u': opt_u++; exclusive++; break; - case 'v': opt_v++; break; - case 'V': opt_V++; exclusive++; break; - - case '?': - fprintf(stderr, usage_msg); - res = 2; - goto out; - } - } - - /* options check */ - if (exclusive > 1) { - fprintf(stderr, usage_msg); - res = 2; - goto out; - } - - if (opt_v || opt_V) { - printf(version); - if (opt_V) { - res = 0; - goto out; - } - } - - if (opt_u) { - printf(usage_msg); - res = 0; - goto out; - } - - if (opt_h) { - printf(usage_msg); - printf(help_msg); - res = 0; - goto out; - } - - /* Open a basic socket */ - if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket"); - res = 1; - goto out; - } - - if (opt_a) { - if (optind == argc) { - /* No remaining args */ - /* show all interfaces */ - if_print((char *)NULL); - goto out; - } else { - /* Just show usage */ - fprintf(stderr, usage_msg); - res = 2; - goto out; - } - } - - /* Copy the interface name */ - spp = argv + optind; - master_ifname = *spp++; - - if (master_ifname == NULL) { - fprintf(stderr, usage_msg); - res = 2; - goto out; - } - - /* exchange abi version with bonding module */ - res = get_drv_info(master_ifname); - if (res) { - fprintf(stderr, - "Master '%s': Error: handshake with driver failed. " - "Aborting\n", - master_ifname); - goto out; - } - - slave_ifname = *spp++; - - if (slave_ifname == NULL) { - if (opt_d || opt_c) { - fprintf(stderr, usage_msg); - res = 2; - goto out; - } - - /* A single arg means show the - * configuration for this interface - */ - if_print(master_ifname); - goto out; - } - - res = get_if_settings(master_ifname, master_ifra); - if (res) { - /* Probably a good reason not to go on */ - fprintf(stderr, - "Master '%s': Error: get settings failed: %s. " - "Aborting\n", - master_ifname, strerror(res)); - goto out; - } - - /* check if master is indeed a master; - * if not then fail any operation - */ - if (!(master_flags.ifr_flags & IFF_MASTER)) { - fprintf(stderr, - "Illegal operation; the specified interface '%s' " - "is not a master. Aborting\n", - master_ifname); - res = 1; - goto out; - } - - /* check if master is up; if not then fail any operation */ - if (!(master_flags.ifr_flags & IFF_UP)) { - fprintf(stderr, - "Illegal operation; the specified master interface " - "'%s' is not up.\n", - master_ifname); - res = 1; - goto out; - } - - /* Only for enslaving */ - if (!opt_c && !opt_d) { - sa_family_t master_family = master_hwaddr.ifr_hwaddr.sa_family; - unsigned char *hwaddr = - (unsigned char *)master_hwaddr.ifr_hwaddr.sa_data; - - /* The family '1' is ARPHRD_ETHER for ethernet. */ - if (master_family != 1 && !opt_f) { - fprintf(stderr, - "Illegal operation: The specified master " - "interface '%s' is not ethernet-like.\n " - "This program is designed to work with " - "ethernet-like network interfaces.\n " - "Use the '-f' option to force the " - "operation.\n", - master_ifname); - res = 1; - goto out; - } - - /* Check master's hw addr */ - for (i = 0; i < 6; i++) { - if (hwaddr[i] != 0) { - hwaddr_set = 1; - break; - } - } - - if (hwaddr_set) { - v_print("current hardware address of master '%s' " - "is %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " - "type %d\n", - master_ifname, - hwaddr[0], hwaddr[1], - hwaddr[2], hwaddr[3], - hwaddr[4], hwaddr[5], - master_family); - } - } - - /* Accepts only one slave */ - if (opt_c) { - /* change active slave */ - res = get_slave_flags(slave_ifname); - if (res) { - fprintf(stderr, - "Slave '%s': Error: get flags failed. " - "Aborting\n", - slave_ifname); - goto out; - } - res = change_active(master_ifname, slave_ifname); - if (res) { - fprintf(stderr, - "Master '%s', Slave '%s': Error: " - "Change active failed\n", - master_ifname, slave_ifname); - } - } else { - /* Accept multiple slaves */ - do { - if (opt_d) { - /* detach a slave interface from the master */ - rv = get_slave_flags(slave_ifname); - if (rv) { - /* Can't work with this slave. */ - /* remember the error and skip it*/ - fprintf(stderr, - "Slave '%s': Error: get flags " - "failed. Skipping\n", - slave_ifname); - res = rv; - continue; - } - rv = release(master_ifname, slave_ifname); - if (rv) { - fprintf(stderr, - "Master '%s', Slave '%s': Error: " - "Release failed\n", - master_ifname, slave_ifname); - res = rv; - } - } else { - /* attach a slave interface to the master */ - rv = get_if_settings(slave_ifname, slave_ifra); - if (rv) { - /* Can't work with this slave. */ - /* remember the error and skip it*/ - fprintf(stderr, - "Slave '%s': Error: get " - "settings failed: %s. " - "Skipping\n", - slave_ifname, strerror(rv)); - res = rv; - continue; - } - rv = enslave(master_ifname, slave_ifname); - if (rv) { - fprintf(stderr, - "Master '%s', Slave '%s': Error: " - "Enslave failed\n", - master_ifname, slave_ifname); - res = rv; - } - } - } while ((slave_ifname = *spp++) != NULL); - } - -out: - if (skfd >= 0) { - close(skfd); - } - - return res; -} - -static short mif_flags; - -/* Get the inteface configuration from the kernel. */ -static int if_getconfig(char *ifname) -{ - struct ifreq ifr; - int metric, mtu; /* Parameters of the master interface. */ - struct sockaddr dstaddr, broadaddr, netmask; - unsigned char *hwaddr; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) - return -1; - mif_flags = ifr.ifr_flags; - printf("The result of SIOCGIFFLAGS on %s is %x.\n", - ifname, ifr.ifr_flags); - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0) - return -1; - printf("The result of SIOCGIFADDR is %2.2x.%2.2x.%2.2x.%2.2x.\n", - ifr.ifr_addr.sa_data[2], ifr.ifr_addr.sa_data[3], - ifr.ifr_addr.sa_data[4], ifr.ifr_addr.sa_data[5]); - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) - return -1; - - /* Gotta convert from 'char' to unsigned for printf(). */ - hwaddr = (unsigned char *)ifr.ifr_hwaddr.sa_data; - printf("The result of SIOCGIFHWADDR is type %d " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", - ifr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], - hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) { - metric = 0; - } else - metric = ifr.ifr_metric; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) - mtu = 0; - else - mtu = ifr.ifr_mtu; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) < 0) { - memset(&dstaddr, 0, sizeof(struct sockaddr)); - } else - dstaddr = ifr.ifr_dstaddr; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) < 0) { - memset(&broadaddr, 0, sizeof(struct sockaddr)); - } else - broadaddr = ifr.ifr_broadaddr; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFNETMASK, &ifr) < 0) { - memset(&netmask, 0, sizeof(struct sockaddr)); - } else - netmask = ifr.ifr_netmask; - - return 0; -} - -static void if_print(char *ifname) -{ - char buff[1024]; - struct ifconf ifc; - struct ifreq *ifr; - int i; - - if (ifname == (char *)NULL) { - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) { - perror("SIOCGIFCONF failed"); - return; - } - - ifr = ifc.ifc_req; - for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) { - if (if_getconfig(ifr->ifr_name) < 0) { - fprintf(stderr, - "%s: unknown interface.\n", - ifr->ifr_name); - continue; - } - - if (((mif_flags & IFF_UP) == 0) && !opt_a) continue; - /*ife_print(&ife);*/ - } - } else { - if (if_getconfig(ifname) < 0) { - fprintf(stderr, - "%s: unknown interface.\n", ifname); - } - } -} - -static int get_drv_info(char *master_ifname) -{ - struct ifreq ifr; - struct ethtool_drvinfo info; - char *endptr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); - ifr.ifr_data = (caddr_t)&info; - - info.cmd = ETHTOOL_GDRVINFO; - strncpy(info.driver, "ifenslave", 32); - snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION); - - if (ioctl(skfd, SIOCETHTOOL, &ifr) < 0) { - if (errno == EOPNOTSUPP) { - goto out; - } - - saved_errno = errno; - v_print("Master '%s': Error: get bonding info failed %s\n", - master_ifname, strerror(saved_errno)); - return 1; - } - - abi_ver = strtoul(info.fw_version, &endptr, 0); - if (*endptr) { - v_print("Master '%s': Error: got invalid string as an ABI " - "version from the bonding module\n", - master_ifname); - return 1; - } - -out: - v_print("ABI ver is %d\n", abi_ver); - - return 0; -} - -static int change_active(char *master_ifname, char *slave_ifname) -{ - struct ifreq ifr; - int res = 0; - - if (!(slave_flags.ifr_flags & IFF_SLAVE)) { - fprintf(stderr, - "Illegal operation: The specified slave interface " - "'%s' is not a slave\n", - slave_ifname); - return 1; - } - - strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); - strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ); - if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &ifr) < 0) && - (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &ifr) < 0)) { - saved_errno = errno; - v_print("Master '%s': Error: SIOCBONDCHANGEACTIVE failed: " - "%s\n", - master_ifname, strerror(saved_errno)); - res = 1; - } - - return res; -} - -static int enslave(char *master_ifname, char *slave_ifname) -{ - struct ifreq ifr; - int res = 0; - - if (slave_flags.ifr_flags & IFF_SLAVE) { - fprintf(stderr, - "Illegal operation: The specified slave interface " - "'%s' is already a slave\n", - slave_ifname); - return 1; - } - - res = set_if_down(slave_ifname, slave_flags.ifr_flags); - if (res) { - fprintf(stderr, - "Slave '%s': Error: bring interface down failed\n", - slave_ifname); - return res; - } - - if (abi_ver < 2) { - /* Older bonding versions would panic if the slave has no IP - * address, so get the IP setting from the master. - */ - set_if_addr(master_ifname, slave_ifname); - } else { - res = clear_if_addr(slave_ifname); - if (res) { - fprintf(stderr, - "Slave '%s': Error: clear address failed\n", - slave_ifname); - return res; - } - } - - if (master_mtu.ifr_mtu != slave_mtu.ifr_mtu) { - res = set_slave_mtu(slave_ifname, master_mtu.ifr_mtu); - if (res) { - fprintf(stderr, - "Slave '%s': Error: set MTU failed\n", - slave_ifname); - return res; - } - } - - if (hwaddr_set) { - /* Master already has an hwaddr - * so set it's hwaddr to the slave - */ - if (abi_ver < 1) { - /* The driver is using an old ABI, so - * the application sets the slave's - * hwaddr - */ - res = set_slave_hwaddr(slave_ifname, - &(master_hwaddr.ifr_hwaddr)); - if (res) { - fprintf(stderr, - "Slave '%s': Error: set hw address " - "failed\n", - slave_ifname); - goto undo_mtu; - } - - /* For old ABI the application needs to bring the - * slave back up - */ - res = set_if_up(slave_ifname, slave_flags.ifr_flags); - if (res) { - fprintf(stderr, - "Slave '%s': Error: bring interface " - "down failed\n", - slave_ifname); - goto undo_slave_mac; - } - } - /* The driver is using a new ABI, - * so the driver takes care of setting - * the slave's hwaddr and bringing - * it up again - */ - } else { - /* No hwaddr for master yet, so - * set the slave's hwaddr to it - */ - if (abi_ver < 1) { - /* For old ABI, the master needs to be - * down before setting it's hwaddr - */ - res = set_if_down(master_ifname, master_flags.ifr_flags); - if (res) { - fprintf(stderr, - "Master '%s': Error: bring interface " - "down failed\n", - master_ifname); - goto undo_mtu; - } - } - - res = set_master_hwaddr(master_ifname, - &(slave_hwaddr.ifr_hwaddr)); - if (res) { - fprintf(stderr, - "Master '%s': Error: set hw address " - "failed\n", - master_ifname); - goto undo_mtu; - } - - if (abi_ver < 1) { - /* For old ABI, bring the master - * back up - */ - res = set_if_up(master_ifname, master_flags.ifr_flags); - if (res) { - fprintf(stderr, - "Master '%s': Error: bring interface " - "up failed\n", - master_ifname); - goto undo_master_mac; - } - } - - hwaddr_set = 1; - } - - /* Do the real thing */ - strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); - strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ); - if ((ioctl(skfd, SIOCBONDENSLAVE, &ifr) < 0) && - (ioctl(skfd, BOND_ENSLAVE_OLD, &ifr) < 0)) { - saved_errno = errno; - v_print("Master '%s': Error: SIOCBONDENSLAVE failed: %s\n", - master_ifname, strerror(saved_errno)); - res = 1; - } - - if (res) { - goto undo_master_mac; - } - - return 0; - -/* rollback (best effort) */ -undo_master_mac: - set_master_hwaddr(master_ifname, &(master_hwaddr.ifr_hwaddr)); - hwaddr_set = 0; - goto undo_mtu; -undo_slave_mac: - set_slave_hwaddr(slave_ifname, &(slave_hwaddr.ifr_hwaddr)); -undo_mtu: - set_slave_mtu(slave_ifname, slave_mtu.ifr_mtu); - return res; -} - -static int release(char *master_ifname, char *slave_ifname) -{ - struct ifreq ifr; - int res = 0; - - if (!(slave_flags.ifr_flags & IFF_SLAVE)) { - fprintf(stderr, - "Illegal operation: The specified slave interface " - "'%s' is not a slave\n", - slave_ifname); - return 1; - } - - strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); - strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ); - if ((ioctl(skfd, SIOCBONDRELEASE, &ifr) < 0) && - (ioctl(skfd, BOND_RELEASE_OLD, &ifr) < 0)) { - saved_errno = errno; - v_print("Master '%s': Error: SIOCBONDRELEASE failed: %s\n", - master_ifname, strerror(saved_errno)); - return 1; - } else if (abi_ver < 1) { - /* The driver is using an old ABI, so we'll set the interface - * down to avoid any conflicts due to same MAC/IP - */ - res = set_if_down(slave_ifname, slave_flags.ifr_flags); - if (res) { - fprintf(stderr, - "Slave '%s': Error: bring interface " - "down failed\n", - slave_ifname); - } - } - - /* set to default mtu */ - set_slave_mtu(slave_ifname, 1500); - - return res; -} - -static int get_if_settings(char *ifname, struct dev_ifr ifra[]) -{ - int i; - int res = 0; - - for (i = 0; ifra[i].req_ifr; i++) { - strncpy(ifra[i].req_ifr->ifr_name, ifname, IFNAMSIZ); - res = ioctl(skfd, ifra[i].req_type, ifra[i].req_ifr); - if (res < 0) { - saved_errno = errno; - v_print("Interface '%s': Error: %s failed: %s\n", - ifname, ifra[i].req_name, - strerror(saved_errno)); - - return saved_errno; - } - } - - return 0; -} - -static int get_slave_flags(char *slave_ifname) -{ - int res = 0; - - strncpy(slave_flags.ifr_name, slave_ifname, IFNAMSIZ); - res = ioctl(skfd, SIOCGIFFLAGS, &slave_flags); - if (res < 0) { - saved_errno = errno; - v_print("Slave '%s': Error: SIOCGIFFLAGS failed: %s\n", - slave_ifname, strerror(saved_errno)); - } else { - v_print("Slave %s: flags %04X.\n", - slave_ifname, slave_flags.ifr_flags); - } - - return res; -} - -static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr) -{ - unsigned char *addr = (unsigned char *)hwaddr->sa_data; - struct ifreq ifr; - int res = 0; - - strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); - memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr)); - res = ioctl(skfd, SIOCSIFHWADDR, &ifr); - if (res < 0) { - saved_errno = errno; - v_print("Master '%s': Error: SIOCSIFHWADDR failed: %s\n", - master_ifname, strerror(saved_errno)); - return res; - } else { - v_print("Master '%s': hardware address set to " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", - master_ifname, addr[0], addr[1], addr[2], - addr[3], addr[4], addr[5]); - } - - return res; -} - -static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr) -{ - unsigned char *addr = (unsigned char *)hwaddr->sa_data; - struct ifreq ifr; - int res = 0; - - strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ); - memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr)); - res = ioctl(skfd, SIOCSIFHWADDR, &ifr); - if (res < 0) { - saved_errno = errno; - - v_print("Slave '%s': Error: SIOCSIFHWADDR failed: %s\n", - slave_ifname, strerror(saved_errno)); - - if (saved_errno == EBUSY) { - v_print(" The device is busy: it must be idle " - "before running this command.\n"); - } else if (saved_errno == EOPNOTSUPP) { - v_print(" The device does not support setting " - "the MAC address.\n" - " Your kernel likely does not support slave " - "devices.\n"); - } else if (saved_errno == EINVAL) { - v_print(" The device's address type does not match " - "the master's address type.\n"); - } - return res; - } else { - v_print("Slave '%s': hardware address set to " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", - slave_ifname, addr[0], addr[1], addr[2], - addr[3], addr[4], addr[5]); - } - - return res; -} - -static int set_slave_mtu(char *slave_ifname, int mtu) -{ - struct ifreq ifr; - int res = 0; - - ifr.ifr_mtu = mtu; - strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ); - - res = ioctl(skfd, SIOCSIFMTU, &ifr); - if (res < 0) { - saved_errno = errno; - v_print("Slave '%s': Error: SIOCSIFMTU failed: %s\n", - slave_ifname, strerror(saved_errno)); - } else { - v_print("Slave '%s': MTU set to %d.\n", slave_ifname, mtu); - } - - return res; -} - -static int set_if_flags(char *ifname, short flags) -{ - struct ifreq ifr; - int res = 0; - - ifr.ifr_flags = flags; - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - - res = ioctl(skfd, SIOCSIFFLAGS, &ifr); - if (res < 0) { - saved_errno = errno; - v_print("Interface '%s': Error: SIOCSIFFLAGS failed: %s\n", - ifname, strerror(saved_errno)); - } else { - v_print("Interface '%s': flags set to %04X.\n", ifname, flags); - } - - return res; -} - -static int set_if_up(char *ifname, short flags) -{ - return set_if_flags(ifname, flags | IFF_UP); -} - -static int set_if_down(char *ifname, short flags) -{ - return set_if_flags(ifname, flags & ~IFF_UP); -} - -static int clear_if_addr(char *ifname) -{ - struct ifreq ifr; - int res = 0; - - strncpy(ifr.ifr_name, ifname, IFNAMSIZ); - ifr.ifr_addr.sa_family = AF_INET; - memset(ifr.ifr_addr.sa_data, 0, sizeof(ifr.ifr_addr.sa_data)); - - res = ioctl(skfd, SIOCSIFADDR, &ifr); - if (res < 0) { - saved_errno = errno; - v_print("Interface '%s': Error: SIOCSIFADDR failed: %s\n", - ifname, strerror(saved_errno)); - } else { - v_print("Interface '%s': address cleared\n", ifname); - } - - return res; -} - -static int set_if_addr(char *master_ifname, char *slave_ifname) -{ - struct ifreq ifr; - int res; - unsigned char *ipaddr; - int i; - struct { - char *req_name; - char *desc; - int g_ioctl; - int s_ioctl; - } ifra[] = { - {"IFADDR", "addr", SIOCGIFADDR, SIOCSIFADDR}, - {"DSTADDR", "destination addr", SIOCGIFDSTADDR, SIOCSIFDSTADDR}, - {"BRDADDR", "broadcast addr", SIOCGIFBRDADDR, SIOCSIFBRDADDR}, - {"NETMASK", "netmask", SIOCGIFNETMASK, SIOCSIFNETMASK}, - {NULL, NULL, 0, 0}, - }; - - for (i = 0; ifra[i].req_name; i++) { - strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ); - res = ioctl(skfd, ifra[i].g_ioctl, &ifr); - if (res < 0) { - int saved_errno = errno; - - v_print("Interface '%s': Error: SIOCG%s failed: %s\n", - master_ifname, ifra[i].req_name, - strerror(saved_errno)); - - ifr.ifr_addr.sa_family = AF_INET; - memset(ifr.ifr_addr.sa_data, 0, - sizeof(ifr.ifr_addr.sa_data)); - } - - strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ); - res = ioctl(skfd, ifra[i].s_ioctl, &ifr); - if (res < 0) { - int saved_errno = errno; - - v_print("Interface '%s': Error: SIOCS%s failed: %s\n", - slave_ifname, ifra[i].req_name, - strerror(saved_errno)); - - } - - ipaddr = (unsigned char *)ifr.ifr_addr.sa_data; - v_print("Interface '%s': set IP %s to %d.%d.%d.%d\n", - slave_ifname, ifra[i].desc, - ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); - } - - return 0; -} - -/* - * Local variables: - * version-control: t - * kept-new-versions: 5 - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * compile-command: "gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave" - * End: - */ - diff --git a/system/base/iputils/files/iputils-20071127-kernel-ifaddr.patch b/system/base/iputils/files/iputils-20071127-kernel-ifaddr.patch deleted file mode 100644 index 9c13f7e1..00000000 --- a/system/base/iputils/files/iputils-20071127-kernel-ifaddr.patch +++ /dev/null @@ -1,55 +0,0 @@ ---- a/rarpd.c -+++ b/rarpd.c -@@ -55,10 +55,10 @@ struct iflink - unsigned char lladdr[16]; - char name[IFNAMSIZ]; -- struct ifaddr *ifa_list; -+ struct kern_ifaddr *ifa_list; - } *ifl_list; - --struct ifaddr -+struct kern_ifaddr - { -- struct ifaddr *next; -+ struct kern_ifaddr *next; - __u32 prefix; - __u32 mask; -@@ -92,5 +92,5 @@ void load_if(void) - struct ifreq *ifrp, *ifend; - struct iflink *ifl; -- struct ifaddr *ifa; -+ struct kern_ifaddr *ifa; - struct ifconf ifc; - struct ifreq ibuf[256]; -@@ -183,5 +183,5 @@ void load_if(void) - if (mask == 0 || prefix == 0) - continue; -- ifa = (struct ifaddr*)malloc(sizeof(*ifa)); -+ ifa = (struct kern_ifaddr*)malloc(sizeof(*ifa)); - memset(ifa, 0, sizeof(*ifa)); - ifa->local = addr; -@@ -239,8 +239,8 @@ int bootable(__u32 addr) - } - --struct ifaddr *select_ipaddr(int ifindex, __u32 *sel_addr, __u32 **alist) -+struct kern_ifaddr *select_ipaddr(int ifindex, __u32 *sel_addr, __u32 **alist) - { - struct iflink *ifl; -- struct ifaddr *ifa; -+ struct kern_ifaddr *ifa; - int retry = 0; - int i; -@@ -298,5 +298,5 @@ struct rarp_map *rarp_lookup(int ifindex - if (r == NULL) { - if (hatype == ARPHRD_ETHER && halen == 6) { -- struct ifaddr *ifa; -+ struct kern_ifaddr *ifa; - struct hostent *hp; - char ename[256]; -@@ -371,5 +371,5 @@ int put_myipaddr(unsigned char **ptr_p, - __u32 laddr = 0; - struct iflink *ifl; -- struct ifaddr *ifa; -+ struct kern_ifaddr *ifa; - - for (ifl=ifl_list; ifl; ifl = ifl->next) diff --git a/system/base/iputils/files/iputils-20071127-nonroot-floodping.patch b/system/base/iputils/files/iputils-20071127-nonroot-floodping.patch deleted file mode 100644 index cae87791..00000000 --- a/system/base/iputils/files/iputils-20071127-nonroot-floodping.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- iputils-s20071127/ping_common.h.orig 2008-06-10 11:16:06.000000000 +0100 -+++ iputils-s20071127/ping_common.h 2008-06-10 11:16:18.000000000 +0100 -@@ -28,7 +28,7 @@ - - #define MAXWAIT 10 /* max seconds to wait for response */ - #define MININTERVAL 10 /* Minimal interpacket gap */ --#define MINUSERINTERVAL 200 /* Minimal allowed interval for non-root */ -+#define MINUSERINTERVAL 0 /* Minimal allowed interval for non-root */ - - #define SCHINT(a) (((a) <= MININTERVAL) ? MININTERVAL : (a)) - diff --git a/system/base/iputils/files/iputils-20100418-so_mark.patch b/system/base/iputils/files/iputils-20100418-so_mark.patch deleted file mode 100644 index 0d7c7860..00000000 --- a/system/base/iputils/files/iputils-20100418-so_mark.patch +++ /dev/null @@ -1,22 +0,0 @@ -https://bugs.gentoo.org/335347 - -fix building with older linux headers that don't define SO_MARK - ---- ping_common.c.org -+++ ping_common.c -@@ -485,6 +485,7 @@ - fprintf(stderr, "Warning: no SO_TIMESTAMP support, falling back to SIOCGSTAMP\n"); - } - #endif -+#ifdef SO_MARK - if (options & F_MARK) { - if (setsockopt(icmp_sock, SOL_SOCKET, SO_MARK, - &mark, sizeof(mark)) == -1) { -@@ -494,6 +495,7 @@ - fprintf(stderr, "Warning: Failed to set mark %d\n", mark); - } - } -+#endif - - /* Set some SNDTIMEO to prevent blocking forever - * on sends, when device is too slow or stalls. Just put limit diff --git a/system/base/iputils/files/iputils-20121221-crypto-build.patch b/system/base/iputils/files/iputils-20121221-crypto-build.patch deleted file mode 100644 index 1ec3c101..00000000 --- a/system/base/iputils/files/iputils-20121221-crypto-build.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 568e990d30fc7e9416e0a6f8c74ea5013921eaec Mon Sep 17 00:00:00 2001 -From: Arjan van de Ven -Date: Wed, 16 Jan 2013 03:12:15 +0900 -Subject: [PATCH [iputils]] ping6: Fix build command line argument with gnutls. - -The ping6 command can use either openssl or gnutls... -and the Makefile has a bunch of setup for defining which of the two to use. - -Unfortunately, the final -D define on the commandline to enable gnutls -inside the ping6.c file didn't actually make it onto the gcc -commandline. -This patch adds the $(DEF_CRYPTO) Makefile variable to fix this gap. - -Signed-off-by: Arjan van de Ven -Signed-off-by: YOSHIFUJI Hideaki ---- - Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile b/Makefile -index c62d9df..89249f5 100644 ---- a/Makefile -+++ b/Makefile -@@ -149,7 +149,7 @@ LIB_clockdiff = $(LIB_CAP) - DEF_ping_common = $(DEF_CAP) $(DEF_IDN) - DEF_ping = $(DEF_CAP) $(DEF_IDN) $(DEF_WITHOUT_IFADDRS) - LIB_ping = $(LIB_CAP) $(LIB_IDN) --DEF_ping6 = $(DEF_CAP) $(DEF_IDN) $(DEF_WITHOUT_IFADDRS) $(DEF_ENABLE_PING6_RTHDR) -+DEF_ping6 = $(DEF_CAP) $(DEF_IDN) $(DEF_WITHOUT_IFADDRS) $(DEF_ENABLE_PING6_RTHDR) $(DEF_CRYPTO) - LIB_ping6 = $(LIB_CAP) $(LIB_IDN) $(LIB_RESOLV) $(LIB_CRYPTO) - - ping: ping_common.o --- -1.8.0.2 - diff --git a/system/base/iputils/files/iputils-20121221-makefile.patch b/system/base/iputils/files/iputils-20121221-makefile.patch deleted file mode 100644 index 66424c85..00000000 --- a/system/base/iputils/files/iputils-20121221-makefile.patch +++ /dev/null @@ -1,61 +0,0 @@ -From c66609d2c830d6fe06f48f5d38c54eb5cc6f2975 Mon Sep 17 00:00:00 2001 -From: Mike Frysinger -Date: Thu, 24 Jan 2013 23:36:16 -0500 -Subject: [PATCH [iputils]] fix handling of CFLAGS - -This defaults CFLAGS to -O3 without clobbering settings people have set -up in the environment already. - -Signed-off-by: Mike Frysinger ---- - Makefile | 13 +++++-------- - 1 file changed, 5 insertions(+), 8 deletions(-) - -diff --git a/Makefile b/Makefile -index 2c49940..ecabac3 100644 ---- a/Makefile -+++ b/Makefile -@@ -2,8 +2,6 @@ - # Configuration - # - --# CC --CC=gcc - # Path to parent kernel include files directory - LIBC_INCLUDE=/usr/include - # Libraries -@@ -48,11 +46,10 @@ ENABLE_RDISC_SERVER=no - - # ------------------------------------- - # What a pity, all new gccs are buggy and -Werror does not work. Sigh. --# CCOPT=-fno-strict-aliasing -Wstrict-prototypes -Wall -Werror -g --CCOPT=-fno-strict-aliasing -Wstrict-prototypes -Wall -g --CCOPTOPT=-O3 --GLIBCFIX=-D_GNU_SOURCE --DEFINES= -+# CFLAGS+=-fno-strict-aliasing -Wstrict-prototypes -Wall -Werror -g -+CFLAGS?=-O3 -g -+CFLAGS+=-fno-strict-aliasing -Wstrict-prototypes -Wall -+CPPFLAGS+=-D_GNU_SOURCE - LDLIB= - - FUNC_LIB = $(if $(filter static,$(1)),$(LDFLAG_STATIC) $(2) $(LDFLAG_DYNAMIC),$(2)) -@@ -113,7 +110,6 @@ IPV4_TARGETS=tracepath ping clockdiff rdisc arping tftpd rarpd - IPV6_TARGETS=tracepath6 traceroute6 ping6 - TARGETS=$(IPV4_TARGETS) $(IPV6_TARGETS) - --CFLAGS=$(CCOPTOPT) $(CCOPT) $(GLIBCFIX) $(DEFINES) - LDLIBS=$(LDLIB) $(ADDLIB) - - UNAME_N:=$(shell uname -n) -@@ -132,6 +128,7 @@ all: $(TARGETS) - $(COMPILE.c) $< $(DEF_$(patsubst %.o,%,$@)) -S -o $@ - %.o: %.c - $(COMPILE.c) $< $(DEF_$(patsubst %.o,%,$@)) -o $@ -+LINK.o += $(CFLAGS) - $(TARGETS): %: %.o - $(LINK.o) $^ $(LIB_$@) $(LDLIBS) -o $@ - --- -1.8.0.2 - diff --git a/system/base/iputils/files/iputils-20121221-openssl.patch b/system/base/iputils/files/iputils-20121221-openssl.patch deleted file mode 100644 index 1c6ba81d..00000000 --- a/system/base/iputils/files/iputils-20121221-openssl.patch +++ /dev/null @@ -1,92 +0,0 @@ -From b57d77dcfa5cb363b7eba5b331324669a8505ac4 Mon Sep 17 00:00:00 2001 -From: Mike Frysinger -Date: Thu, 24 Jan 2013 23:32:39 -0500 -Subject: [PATCH [iputils]] ping6: allow disabling of openssl support - -Signed-off-by: Mike Frysinger ---- - Makefile | 5 ++++- - ping6.c | 14 +++++++++++++- - 2 files changed, 17 insertions(+), 2 deletions(-) - -diff --git a/Makefile b/Makefile -index 89249f5..2c49940 100644 ---- a/Makefile -+++ b/Makefile -@@ -36,7 +36,7 @@ ARPING_DEFAULT_DEVICE= - - # GNU TLS library for ping6 [yes|no|static] - USE_GNUTLS=yes --# Crypto library for ping6 [shared|static] -+# Crypto library for ping6 [shared|static|no] - USE_CRYPTO=shared - # Resolv library for ping6 [yes|static] - USE_RESOLV=yes -@@ -63,7 +63,10 @@ ifneq ($(USE_GNUTLS),no) - LIB_CRYPTO = $(call FUNC_LIB,$(USE_GNUTLS),$(LDFLAG_GNUTLS)) - DEF_CRYPTO = -DUSE_GNUTLS - else -+ifneq ($(USE_CRYPTO),no) - LIB_CRYPTO = $(call FUNC_LIB,$(USE_CRYPTO),$(LDFLAG_CRYPTO)) -+ DEF_CRYPTO = -DUSE_OPENSSL -+endif - endif - - # USE_RESOLV: LIB_RESOLV -diff --git a/ping6.c b/ping6.c -index c39864d..f2f90af 100644 ---- a/ping6.c -+++ b/ping6.c -@@ -168,8 +168,10 @@ static int icmp_sock; - - #ifdef USE_GNUTLS - # include --#else -+# define USE_CRYPTO -+#elif defined USE_OPENSSL - # include -+# define USE_CRYPTO - #endif - - /* Node Information query */ -@@ -326,6 +328,7 @@ static void niquery_init_nonce(void) - #if !PING6_NONCE_MEMORY - static int niquery_nonce(__u8 *nonce, int fill) - { -+# ifdef USE_CRYPTO - static __u8 digest[MD5_DIGEST_LENGTH]; - static int seq = -1; - -@@ -348,6 +351,10 @@ static int niquery_nonce(__u8 *nonce, int fill) - return -1; - return ntohsp((__u16 *)nonce); - } -+# else -+ fprintf(stderr, "ping6: function not available; crypto disabled\n"); -+ exit(3); -+# endif - } - #endif - -@@ -502,6 +509,7 @@ static int niquery_option_subject_addr_handler(int index, const char *arg) - - static int niquery_option_subject_name_handler(int index, const char *arg) - { -+#ifdef USE_CRYPTO - static char nigroup_buf[INET6_ADDRSTRLEN + 1 + IFNAMSIZ]; - unsigned char *dnptrs[2], **dpp, **lastdnptr; - int n; -@@ -627,6 +635,10 @@ errexit: - free(idn); - free(name); - exit(1); -+#else -+ fprintf(stderr, "ping6: function not available; crypto disabled\n"); -+ exit(3); -+#endif - } - - int niquery_option_help_handler(int index, const char *arg) --- -1.8.0.2 - diff --git a/system/base/iputils/files/iputils-20121221-owl-pingsock.diff b/system/base/iputils/files/iputils-20121221-owl-pingsock.diff deleted file mode 100644 index 283aa989..00000000 --- a/system/base/iputils/files/iputils-20121221-owl-pingsock.diff +++ /dev/null @@ -1,224 +0,0 @@ -http://openwall.info/wiki/people/segoon/ping - ---- iputils-s20101006/ping.c -+++ iputils-s20101006/ping.c -@@ -88,6 +88,7 @@ struct sockaddr_in whereto; /* who to pi - int optlen = 0; - int settos = 0; /* Set TOS, Precendence or other QOS options */ - int icmp_sock; /* socket file descriptor */ -+int using_ping_socket = 0; - u_char outpack[0x10000]; - int maxpacket = sizeof(outpack); - -@@ -123,7 +124,11 @@ main(int argc, char **argv) - char *target, hnamebuf[MAX_HOSTNAMELEN]; - char rspace[3 + 4 * NROUTES + 1]; /* record route space */ - -- icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); -+ icmp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); -+ if (icmp_sock != -1) -+ using_ping_socket = 1; -+ else -+ icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); - socket_errno = errno; - - uid = getuid(); -@@ -377,13 +382,35 @@ main(int argc, char **argv) - } - } - -- if ((options&F_STRICTSOURCE) && -- bind(icmp_sock, (struct sockaddr*)&source, sizeof(source)) == -1) { -- perror("bind"); -- exit(2); -+ if (!using_ping_socket) { -+ if ((options&F_STRICTSOURCE) && -+ bind(icmp_sock, (struct sockaddr*)&source, sizeof(source)) == -1) { -+ perror("bind"); -+ exit(2); -+ } -+ } else { -+ struct sockaddr_in sa; -+ socklen_t sl; -+ -+ sa.sin_family = AF_INET; -+ sa.sin_port = 0; -+ sa.sin_addr.s_addr = (options&F_STRICTSOURCE) ? -+ source.sin_addr.s_addr : 0; -+ sl = sizeof(sa); -+ -+ if (bind(icmp_sock, (struct sockaddr *) &sa, sl) == -1) { -+ perror("bind"); -+ exit(2); -+ } -+ -+ if (getsockname(icmp_sock, (struct sockaddr *) &sa, &sl) == -1) { -+ perror("getsockname"); -+ exit(2); -+ } -+ ident = sa.sin_port; - } - -- if (1) { -+ if (!using_ping_socket) { - struct icmp_filter filt; - filt.data = ~((1<ee_origin == SO_EE_ORIGIN_ICMP) { - struct sockaddr_in *sin = (struct sockaddr_in*)(e+1); -+ int error_pkt; - - if (res < sizeof(icmph) || - target.sin_addr.s_addr != whereto.sin_addr.s_addr || -@@ -576,9 +610,18 @@ int receive_error_msg() - goto out; - } - -- acknowledge(ntohs(icmph.un.echo.sequence)); -+ error_pkt = (e->ee_type != ICMP_REDIRECT && -+ e->ee_type != ICMP_SOURCE_QUENCH); -+ if (error_pkt) { -+ acknowledge(ntohs(icmph.un.echo.sequence)); -+ net_errors++; -+ nerrors++; -+ } -+ else { -+ saved_errno = 0; -+ } - -- if (!working_recverr) { -+ if (!using_ping_socket && !working_recverr) { - struct icmp_filter filt; - working_recverr = 1; - /* OK, it works. Add stronger filter. */ -@@ -589,15 +632,14 @@ int receive_error_msg() - perror("\rWARNING: setsockopt(ICMP_FILTER)"); - } - -- net_errors++; -- nerrors++; - if (options & F_QUIET) - goto out; - if (options & F_FLOOD) { -- write_stdout("\bE", 2); -+ if (error_pkt) -+ write_stdout("\bE", 2); - } else { - print_timestamp(); -- printf("From %s icmp_seq=%u ", pr_addr(sin->sin_addr.s_addr), ntohs(icmph.un.echo.sequence)); -+ printf("From %s: icmp_seq=%u ", pr_addr(sin->sin_addr.s_addr), ntohs(icmph.un.echo.sequence)); - pr_icmph(e->ee_type, e->ee_code, e->ee_info, NULL); - fflush(stdout); - } -@@ -695,15 +737,41 @@ parse_reply(struct msghdr *msg, int cc, - struct iphdr *ip; - int hlen; - int csfailed; -+ struct cmsghdr *cmsg; -+ int ttl; -+ __u8 *opts; -+ int optlen; - - /* Check the IP header */ - ip = (struct iphdr *)buf; -- hlen = ip->ihl*4; -- if (cc < hlen + 8 || ip->ihl < 5) { -- if (options & F_VERBOSE) -- fprintf(stderr, "ping: packet too short (%d bytes) from %s\n", cc, -- pr_addr(from->sin_addr.s_addr)); -- return 1; -+ if (!using_ping_socket) { -+ hlen = ip->ihl*4; -+ if (cc < hlen + 8 || ip->ihl < 5) { -+ if (options & F_VERBOSE) -+ fprintf(stderr, "ping: packet too short (%d bytes) from %s\n", cc, -+ pr_addr(from->sin_addr.s_addr)); -+ return 1; -+ } -+ ttl = ip->ttl; -+ opts = buf + sizeof(struct iphdr); -+ optlen = hlen - sizeof(struct iphdr); -+ } else { -+ hlen = 0; -+ ttl = 0; -+ opts = buf; -+ optlen = 0; -+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { -+ if (cmsg->cmsg_level != SOL_IP) -+ continue; -+ if (cmsg->cmsg_type == IP_TTL) { -+ if (cmsg->cmsg_len < sizeof(int)) -+ continue; -+ ttl = *(int *) CMSG_DATA(cmsg); -+ } else if (cmsg->cmsg_type == IP_RETOPTS) { -+ opts = (__u8 *) CMSG_DATA(cmsg); -+ optlen = cmsg->cmsg_len; -+ } -+ } - } - - /* Now the ICMP part */ -@@ -716,7 +784,7 @@ parse_reply(struct msghdr *msg, int cc, - return 1; /* 'Twas not our ECHO */ - if (gather_statistics((__u8*)icp, sizeof(*icp), cc, - ntohs(icp->un.echo.sequence), -- ip->ttl, 0, tv, pr_addr(from->sin_addr.s_addr), -+ ttl, 0, tv, pr_addr(from->sin_addr.s_addr), - pr_echo_reply)) - return 0; - } else { -@@ -807,7 +875,7 @@ parse_reply(struct msghdr *msg, int cc, - } - - if (!(options & F_FLOOD)) { -- pr_options(buf + sizeof(struct iphdr), hlen); -+ pr_options(opts, optlen + sizeof(struct iphdr)); - - if (options & F_AUDIBLE) - putchar('\a'); -@@ -916,8 +984,7 @@ void pr_icmph(__u8 type, __u8 code, __u3 - printf("Redirect, Bad Code: %d", code); - break; - } -- if (icp) -- printf("(New nexthop: %s)\n", pr_addr(icp->un.gateway)); -+ printf("(New nexthop: %s)\n", pr_addr(icp ? icp->un.gateway : info)); - if (icp && (options & F_VERBOSE)) - pr_iph((struct iphdr*)(icp + 1)); - break; -@@ -1217,7 +1284,7 @@ void install_filter(void) - insns - }; - -- if (once) -+ if (once || using_ping_socket) - return; - once = 1; - ---- iputils-s20101006/ping_common.c -+++ iputils-s20101006/ping_common.c -@@ -515,7 +515,8 @@ void setup(int icmp_sock) - *p++ = i; - } - -- ident = htons(getpid() & 0xFFFF); -+ if (!ident) -+ ident = htons(getpid() & 0xFFFF); - - set_signal(SIGINT, sigexit); - set_signal(SIGALRM, sigexit); diff --git a/system/base/iputils/files/iputils-20121221-printf-size.patch b/system/base/iputils/files/iputils-20121221-printf-size.patch deleted file mode 100644 index 6d6c3b7d..00000000 --- a/system/base/iputils/files/iputils-20121221-printf-size.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 23fcb10ae15a96aa9e5a823cfe0b612d9522691c Mon Sep 17 00:00:00 2001 -From: Mike Frysinger -Date: Sat, 14 Aug 2010 01:16:42 -0400 -Subject: [PATCH [iputils]] tracepath: re-use printf return in print_host - -Since the printf funcs already return the length of chars displayed, -use that value instead of re-calculating the length with strlen. - -This also fixes the handling of the strlen return -- it's a size_t, -not an int. - -Signed-off-by: Mike Frysinger ---- - tracepath.c | 11 ++++------- - tracepath6.c | 11 ++++------- - 2 files changed, 8 insertions(+), 14 deletions(-) - -diff --git a/tracepath.c b/tracepath.c -index 8a08f1d..f155816 100644 ---- a/tracepath.c -+++ b/tracepath.c -@@ -73,13 +73,10 @@ void data_wait(int fd) - - void print_host(const char *a, const char *b, int both) - { -- int plen = 0; -- printf("%s", a); -- plen = strlen(a); -- if (both) { -- printf(" (%s)", b); -- plen += strlen(b) + 3; -- } -+ int plen; -+ plen = printf("%s", a); -+ if (both) -+ plen += printf(" (%s)", b); - if (plen >= HOST_COLUMN_SIZE) - plen = HOST_COLUMN_SIZE - 1; - printf("%*s", HOST_COLUMN_SIZE - plen, ""); -diff --git a/tracepath6.c b/tracepath6.c -index 126fadf..bee95c3 100644 ---- a/tracepath6.c -+++ b/tracepath6.c -@@ -86,13 +86,10 @@ void data_wait(int fd) - - void print_host(const char *a, const char *b, int both) - { -- int plen = 0; -- printf("%s", a); -- plen = strlen(a); -- if (both) { -- printf(" (%s)", b); -- plen += strlen(b) + 3; -- } -+ int plen; -+ plen = printf("%s", a); -+ if (both) -+ plen += printf(" (%s)", b); - if (plen >= HOST_COLUMN_SIZE) - plen = HOST_COLUMN_SIZE - 1; - printf("%*s", HOST_COLUMN_SIZE - plen, ""); --- -1.8.0.2 - diff --git a/system/base/iputils/files/man/arping.8 b/system/base/iputils/files/man/arping.8 deleted file mode 100644 index af98087a..00000000 --- a/system/base/iputils/files/man/arping.8 +++ /dev/null @@ -1,110 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "ARPING" "8" "24 Mayıs 2011" "iputils-101006" "System Manager's Manual: iputils" -.SH NAME -arping \- send ARP REQUEST to a neighbour host -.SH SYNOPSIS - -\fBarping\fR [ \fB-AbDfhqUV\fR] [ \fB-c \fIcount\fB\fR] [ \fB-w \fIdeadline\fB\fR] [ \fB-s \fIsource\fB\fR] \fB-I \fIinterface\fB\fR \fB\fIdestination\fB\fR - -.SH "DESCRIPTION" -.PP -Ping \fIdestination\fR on device \fIinterface\fR by ARP packets, -using source address \fIsource\fR. -.SH "OPTIONS" -.TP -\fB-A\fR -The same as \fB-U\fR, but ARP REPLY packets used instead -of ARP REQUEST. -.TP -\fB-b\fR -Send only MAC level broadcasts. Normally \fBarping\fR starts -from sending broadcast, and switch to unicast after reply received. -.TP -\fB-c \fIcount\fB\fR -Stop after sending \fIcount\fR ARP REQUEST -packets. With -\fIdeadline\fR -option, \fBarping\fR waits for -\fIcount\fR ARP REPLY packets, until the timeout expires. -.TP -\fB-D\fR -Duplicate address detection mode (DAD). See -RFC2131, 4.4.1. -Returns 0, if DAD succeeded i.e. no replies are received -.TP -\fB-f\fR -Finish after the first reply confirming that target is alive. -.TP -\fB-I \fIinterface\fB\fR -Name of network device where to send ARP REQUEST packets. This option -is required. -.TP -\fB-h\fR -Print help page and exit. -.TP -\fB-q\fR -Quiet output. Nothing is displayed. -.TP -\fB-s \fIsource\fB\fR -IP source address to use in ARP packets. -If this option is absent, source address is: -.RS -.TP 0.2i -\(bu -In DAD mode (with option \fB-D\fR) set to 0.0.0.0. -.TP 0.2i -\(bu -In Unsolicited ARP mode (with options \fB-U\fR or \fB-A\fR) -set to \fIdestination\fR. -.TP 0.2i -\(bu -Otherwise, it is calculated from routing tables. -.RE -.TP -\fB-U\fR -Unsolicited ARP mode to update neighbours' ARP caches. -No replies are expected. -.TP -\fB-V\fR -Print version of the program and exit. -.TP -\fB-w \fIdeadline\fB\fR -Specify a timeout, in seconds, before -\fBarping\fR -exits regardless of how many -packets have been sent or received. In this case -\fBarping\fR -does not stop after -\fIcount\fR -packet are sent, it waits either for -\fIdeadline\fR -expire or until -\fIcount\fR -probes are answered. -.SH "SEE ALSO" -.PP -\fBping\fR(8), -\fBclockdiff\fR(8), -\fBtracepath\fR(8). -.SH "AUTHOR" -.PP -\fBarping\fR was written by -Alexey Kuznetsov -. -It is now maintained by -YOSHIFUJI Hideaki -. -.SH "SECURITY" -.PP -\fBarping\fR requires CAP_NET_RAWIO capability -to be executed. It is not recommended to be used as set-uid root, -because it allows user to modify ARP caches of neighbour hosts. -.SH "AVAILABILITY" -.PP -\fBarping\fR is part of \fIiputils\fR package -and the latest versions are available in source form at -http://www.skbuff.net/iputils/iputils-current.tar.bz2. diff --git a/system/base/iputils/files/man/clockdiff.8 b/system/base/iputils/files/man/clockdiff.8 deleted file mode 100644 index 764dcd5e..00000000 --- a/system/base/iputils/files/man/clockdiff.8 +++ /dev/null @@ -1,81 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "CLOCKDIFF" "8" "24 Mayıs 2011" "iputils-101006" "System Manager's Manual: iputils" -.SH NAME -clockdiff \- measure clock difference between hosts -.SH SYNOPSIS - -\fBclockdiff\fR [ \fB-o\fR] [ \fB-o1\fR] \fB\fIdestination\fB\fR - -.SH "DESCRIPTION" -.PP -\fBclockdiff\fR Measures clock difference between us and -\fIdestination\fR with 1 msec resolution using ICMP TIMESTAMP -[2] -packets or, optionally, IP TIMESTAMP option -[3] -option added to ICMP ECHO. -[1] -.SH "OPTIONS" -.TP -\fB-o\fR -Use IP TIMESTAMP with ICMP ECHO instead of ICMP TIMESTAMP -messages. It is useful with some destinations, which do not support -ICMP TIMESTAMP (f.e. Solaris <2.4). -.TP -\fB-o1\fR -Slightly different form of \fB-o\fR, namely it uses three-term -IP TIMESTAMP with prespecified hop addresses instead of four term one. -What flavor works better depends on target host. Particularly, -\fB-o\fR is better for Linux. -.SH "WARNINGS" -.TP 0.2i -\(bu -Some nodes (Cisco) use non-standard timestamps, which is allowed -by RFC, but makes timestamps mostly useless. -.TP 0.2i -\(bu -Some nodes generate messed timestamps (Solaris>2.4), when -run \fBxntpd\fR. Seems, its IP stack uses a corrupted clock source, -which is synchronized to time-of-day clock periodically and jumps -randomly making timestamps mostly useless. Good news is that you can -use NTP in this case, which is even better. -.TP 0.2i -\(bu -\fBclockdiff\fR shows difference in time modulo 24 days. -.SH "SEE ALSO" -.PP -\fBping\fR(8), -\fBarping\fR(8), -\fBtracepath\fR(8). -.SH "REFERENCES" -.PP -[1] ICMP ECHO, -RFC0792, page 14. -.PP -[2] ICMP TIMESTAMP, -RFC0792, page 16. -.PP -[3] IP TIMESTAMP option, -RFC0791, 3.1, page 16. -.SH "AUTHOR" -.PP -\fBclockdiff\fR was compiled by -Alexey Kuznetsov -. It was based on code borrowed -from BSD \fBtimed\fR daemon. -It is now maintained by -YOSHIFUJI Hideaki -. -.SH "SECURITY" -.PP -\fBclockdiff\fR requires CAP_NET_RAWIO capability -to be executed. It is safe to be used as set-uid root. -.SH "AVAILABILITY" -.PP -\fBclockdiff\fR is part of \fIiputils\fR package -and the latest versions are available in source form at -http://www.skbuff.net/iputils/iputils-current.tar.bz2. diff --git a/system/base/iputils/files/man/ping.8 b/system/base/iputils/files/man/ping.8 deleted file mode 100644 index d0615b11..00000000 --- a/system/base/iputils/files/man/ping.8 +++ /dev/null @@ -1,408 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "PING" "8" "24 Mayıs 2011" "iputils-101006" "System Manager's Manual: iputils" -.SH NAME -ping, ping6 \- send ICMP ECHO_REQUEST to network hosts -.SH SYNOPSIS - -\fBping\fR [ \fB-LRUbdfnqrvVaAB\fR] [ \fB-c \fIcount\fB\fR] [ \fB-m \fImark\fB\fR] [ \fB-i \fIinterval\fB\fR] [ \fB-l \fIpreload\fB\fR] [ \fB-p \fIpattern\fB\fR] [ \fB-s \fIpacketsize\fB\fR] [ \fB-t \fIttl\fB\fR] [ \fB-w \fIdeadline\fB\fR] [ \fB-F \fIflowlabel\fB\fR] [ \fB-I \fIinterface\fB\fR] [ \fB-M \fIhint\fB\fR] [ \fB-N \fInioption\fB\fR] [ \fB-Q \fItos\fB\fR] [ \fB-S \fIsndbuf\fB\fR] [ \fB-T \fItimestamp option\fB\fR] [ \fB-W \fItimeout\fB\fR] [ \fB\fIhop\fB\fR\fI ...\fR] \fB\fIdestination\fB\fR - -.SH "DESCRIPTION" -.PP -\fBping\fR uses the ICMP protocol's mandatory ECHO_REQUEST -datagram to elicit an ICMP ECHO_RESPONSE from a host or gateway. -ECHO_REQUEST datagrams (``pings'') have an IP and ICMP -header, followed by a struct timeval and then an arbitrary -number of ``pad'' bytes used to fill out the packet. -.PP -\fBping6\fR can also send Node Information Queries (RFC4620). -.SH "OPTIONS" -.TP -\fB-a\fR -Audible ping. -.TP -\fB-A\fR -Adaptive ping. Interpacket interval adapts to round-trip time, so that -effectively not more than one (or more, if preload is set) unanswered probe -is present in the network. Minimal interval is 200msec for not super-user. -On networks with low rtt this mode is essentially equivalent to flood mode. -.TP -\fB-b\fR -Allow pinging a broadcast address. -.TP -\fB-B\fR -Do not allow \fBping\fR to change source address of probes. -The address is bound to one selected when \fBping\fR starts. -.TP -\fB-m \fImark\fB\fR -use \fImark\fR to tag the packets going out. This is useful -for variety of reasons within the kernel such as using policy -routing to select specific outbound processing. -.TP -\fB-c \fIcount\fB\fR -Stop after sending \fIcount\fR ECHO_REQUEST -packets. With -\fIdeadline\fR -option, \fBping\fR waits for -\fIcount\fR ECHO_REPLY packets, until the timeout expires. -.TP -\fB-d\fR -Set the SO_DEBUG option on the socket being used. -Essentially, this socket option is not used by Linux kernel. -.TP -\fB-F \fIflow label\fB\fR -Allocate and set 20 bit flow label on echo request packets. -(Only \fBping6\fR). If value is zero, kernel allocates random flow label. -.TP -\fB-f\fR -Flood ping. For every ECHO_REQUEST sent a period ``.'' is printed, -while for ever ECHO_REPLY received a backspace is printed. -This provides a rapid display of how many packets are being dropped. -If interval is not given, it sets interval to zero and -outputs packets as fast as they come back or one hundred times per second, -whichever is more. -Only the super-user may use this option with zero interval. -.TP -\fB-i \fIinterval\fB\fR -Wait \fIinterval\fR seconds between sending each packet. -The default is to wait for one second between each packet normally, -or not to wait in flood mode. Only super-user may set interval -to values less 0.2 seconds. -.TP -\fB-I \fIinterface address\fB\fR -Set source address to specified interface address. Argument -may be numeric IP address or name of device. When pinging IPv6 -link-local address this option is required. -.TP -\fB-l \fIpreload\fB\fR -If \fIpreload\fR is specified, -\fBping\fR sends that many packets not waiting for reply. -Only the super-user may select preload more than 3. -.TP -\fB-L\fR -Suppress loopback of multicast packets. This flag only applies if the ping -destination is a multicast address. -.TP -\fB-N \fInioption\fB\fR -Send ICMPv6 Node Information Queries (RFC4620), instead of Echo Request. -.RS -.TP -\fBname\fR -Queries for Node Names. -.RE -.RS -.TP -\fBipv6\fR -Queries for IPv6 Addresses. There are several IPv6 specific flags. -.RS -.TP -\fBipv6-global\fR -Request IPv6 global-scope addresses. -.RE -.RS -.TP -\fBipv6-sitelocal\fR -Request IPv6 site-local addresses. -.RE -.RS -.TP -\fBipv6-linklocal\fR -Request IPv6 link-local addresses. -.RE -.RS -.TP -\fBipv6-all\fR -Request IPv6 addresses on other interfaces. -.RE -.RE -.RS -.TP -\fBipv4\fR -Queries for IPv4 Addresses. There is one IPv4 specific flag. -.RS -.TP -\fBipv4-all\fR -Request IPv4 addresses on other interfaces. -.RE -.RE -.RS -.TP -\fBsubject-ipv6=\fIipv6addr\fB\fR -IPv6 subject address. -.RE -.RS -.TP -\fBsubject-ipv4=\fIipv4addr\fB\fR -IPv4 subject address. -.RE -.RS -.TP -\fBsubject-name=\fInodename\fB\fR -Subject name. If it contains more than one dot, -fully-qualified domain name is assumed. -.RE -.RS -.TP -\fBsubject-fqdn=\fInodename\fB\fR -Subject name. Fully-qualified domain name is -always assumed. -.RE -.TP -\fB-n\fR -Numeric output only. -No attempt will be made to lookup symbolic names for host addresses. -.TP -\fB-p \fIpattern\fB\fR -You may specify up to 16 ``pad'' bytes to fill out the packet you send. -This is useful for diagnosing data-dependent problems in a network. -For example, \fB-p ff\fR will cause the sent packet -to be filled with all ones. -.TP -\fB-D\fR -Print timestamp (unix time + microseconds as in gettimeofday) before -each line. -.TP -\fB-Q \fItos\fB\fR -Set Quality of Service -related bits in ICMP datagrams. -\fItos\fR can be either decimal or hex number. -Traditionally (RFC1349), these have been interpreted as: 0 for reserved -(currently being redefined as congestion control), 1-4 for Type of Service -and 5-7 for Precedence. -Possible settings for Type of Service are: minimal cost: 0x02, -reliability: 0x04, throughput: 0x08, low delay: 0x10. Multiple TOS bits -should not be set simultaneously. Possible settings for -special Precedence range from priority (0x20) to net control (0xe0). You -must be root (CAP_NET_ADMIN capability) to use Critical or -higher precedence value. You cannot set -bit 0x01 (reserved) unless ECN has been enabled in the kernel. -In RFC2474, these fields has been redefined as 8-bit Differentiated -Services (DS), consisting of: bits 0-1 of separate data (ECN will be used, -here), and bits 2-7 of Differentiated Services Codepoint (DSCP). -.TP -\fB-q\fR -Quiet output. -Nothing is displayed except the summary lines at startup time and -when finished. -.TP -\fB-R\fR -Record route. -Includes the RECORD_ROUTE option in the ECHO_REQUEST -packet and displays the route buffer on returned packets. -Note that the IP header is only large enough for nine such routes. -Many hosts ignore or discard this option. -.TP -\fB-r\fR -Bypass the normal routing tables and send directly to a host on an attached -interface. -If the host is not on a directly-attached network, an error is returned. -This option can be used to ping a local host through an interface -that has no route through it provided the option \fB-I\fR is also -used. -.TP -\fB-s \fIpacketsize\fB\fR -Specifies the number of data bytes to be sent. -The default is 56, which translates into 64 ICMP -data bytes when combined with the 8 bytes of ICMP header data. -.TP -\fB-S \fIsndbuf\fB\fR -Set socket sndbuf. If not specified, it is selected to buffer -not more than one packet. -.TP -\fB-t \fIttl\fB\fR -Set the IP Time to Live. -.TP -\fB-T \fItimestamp option\fB\fR -Set special IP timestamp options. -\fItimestamp option\fR may be either -\fItsonly\fR (only timestamps), -\fItsandaddr\fR (timestamps and addresses) or -\fItsprespec host1 [host2 [host3 [host4]]]\fR -(timestamp prespecified hops). -.TP -\fB-M \fIhint\fB\fR -Select Path MTU Discovery strategy. -\fIhint\fR may be either \fIdo\fR -(prohibit fragmentation, even local one), -\fIwant\fR (do PMTU discovery, fragment locally when packet size -is large), or \fIdont\fR (do not set DF flag). -.TP -\fB-U\fR -Print full user-to-user latency (the old behaviour). Normally -\fBping\fR -prints network round trip time, which can be different -f.e. due to DNS failures. -.TP -\fB-v\fR -Verbose output. -.TP -\fB-V\fR -Show version and exit. -.TP -\fB-w \fIdeadline\fB\fR -Specify a timeout, in seconds, before -\fBping\fR -exits regardless of how many -packets have been sent or received. In this case -\fBping\fR -does not stop after -\fIcount\fR -packet are sent, it waits either for -\fIdeadline\fR -expire or until -\fIcount\fR -probes are answered or for some error notification from network. -.TP -\fB-W \fItimeout\fB\fR -Time to wait for a response, in seconds. The option affects only timeout -in absence of any responses, otherwise \fBping\fR waits for two RTTs. -.PP -When using \fBping\fR for fault isolation, it should first be run -on the local host, to verify that the local network interface is up -and running. Then, hosts and gateways further and further away should be -``pinged''. Round-trip times and packet loss statistics are computed. -If duplicate packets are received, they are not included in the packet -loss calculation, although the round trip time of these packets is used -in calculating the minimum/average/maximum round-trip time numbers. -When the specified number of packets have been sent (and received) or -if the program is terminated with a -SIGINT, a brief summary is displayed. Shorter current statistics -can be obtained without termination of process with signal -SIGQUIT. -.PP -If \fBping\fR does not receive any reply packets at all it will -exit with code 1. If a packet -\fIcount\fR -and -\fIdeadline\fR -are both specified, and fewer than -\fIcount\fR -packets are received by the time the -\fIdeadline\fR -has arrived, it will also exit with code 1. -On other error it exits with code 2. Otherwise it exits with code 0. This -makes it possible to use the exit code to see if a host is alive or -not. -.PP -This program is intended for use in network testing, measurement and -management. -Because of the load it can impose on the network, it is unwise to use -\fBping\fR during normal operations or from automated scripts. -.SH "ICMP PACKET DETAILS" -.PP -An IP header without options is 20 bytes. -An ICMP ECHO_REQUEST packet contains an additional 8 bytes worth -of ICMP header followed by an arbitrary amount of data. -When a \fIpacketsize\fR is given, this indicated the size of this -extra piece of data (the default is 56). Thus the amount of data received -inside of an IP packet of type ICMP ECHO_REPLY will always be 8 bytes -more than the requested data space (the ICMP header). -.PP -If the data space is at least of size of struct timeval -\fBping\fR uses the beginning bytes of this space to include -a timestamp which it uses in the computation of round trip times. -If the data space is shorter, no round trip times are given. -.SH "DUPLICATE AND DAMAGED PACKETS" -.PP -\fBping\fR will report duplicate and damaged packets. -Duplicate packets should never occur, and seem to be caused by -inappropriate link-level retransmissions. -Duplicates may occur in many situations and are rarely (if ever) a -good sign, although the presence of low levels of duplicates may not -always be cause for alarm. -.PP -Damaged packets are obviously serious cause for alarm and often -indicate broken hardware somewhere in the -\fBping\fR packet's path (in the network or in the hosts). -.SH "TRYING DIFFERENT DATA PATTERNS" -.PP -The (inter)network layer should never treat packets differently depending -on the data contained in the data portion. -Unfortunately, data-dependent problems have been known to sneak into -networks and remain undetected for long periods of time. -In many cases the particular pattern that will have problems is something -that doesn't have sufficient ``transitions'', such as all ones or all -zeros, or a pattern right at the edge, such as almost all zeros. -It isn't necessarily enough to specify a data pattern of all zeros (for -example) on the command line because the pattern that is of interest is -at the data link level, and the relationship between what you type and -what the controllers transmit can be complicated. -.PP -This means that if you have a data-dependent problem you will probably -have to do a lot of testing to find it. -If you are lucky, you may manage to find a file that either can't be sent -across your network or that takes much longer to transfer than other -similar length files. -You can then examine this file for repeated patterns that you can test -using the \fB-p\fR option of \fBping\fR. -.SH "TTL DETAILS" -.PP -The TTL value of an IP packet represents the maximum number of IP routers -that the packet can go through before being thrown away. -In current practice you can expect each router in the Internet to decrement -the TTL field by exactly one. -.PP -The TCP/IP specification states that the TTL field for TCP -packets should be set to 60, but many systems use smaller values -(4.3 BSD uses 30, 4.2 used 15). -.PP -The maximum possible value of this field is 255, and most Unix systems set -the TTL field of ICMP ECHO_REQUEST packets to 255. -This is why you will find you can ``ping'' some hosts, but not reach them -with -\fBtelnet\fR(1) -or -\fBftp\fR(1). -.PP -In normal operation ping prints the TTL value from the packet it receives. -When a remote system receives a ping packet, it can do one of three things -with the TTL field in its response: -.TP 0.2i -\(bu -Not change it; this is what Berkeley Unix systems did before the -4.3BSD Tahoe release. In this case the TTL value in the received packet -will be 255 minus the number of routers in the round-trip path. -.TP 0.2i -\(bu -Set it to 255; this is what current Berkeley Unix systems do. -In this case the TTL value in the received packet will be 255 minus the -number of routers in the path \fBfrom\fR -the remote system \fBto\fR the \fBping\fRing host. -.TP 0.2i -\(bu -Set it to some other value. Some machines use the same value for -ICMP packets that they use for TCP packets, for example either 30 or 60. -Others may use completely wild values. -.SH "BUGS" -.TP 0.2i -\(bu -Many Hosts and Gateways ignore the RECORD_ROUTE option. -.TP 0.2i -\(bu -The maximum IP header length is too small for options like -RECORD_ROUTE to be completely useful. -There's not much that that can be done about this, however. -.TP 0.2i -\(bu -Flood pinging is not recommended in general, and flood pinging the -broadcast address should only be done under very controlled conditions. -.SH "SEE ALSO" -.PP -\fBnetstat\fR(1), -\fBifconfig\fR(8). -.SH "HISTORY" -.PP -The \fBping\fR command appeared in 4.3BSD. -.PP -The version described here is its descendant specific to Linux. -.SH "SECURITY" -.PP -\fBping\fR requires CAP_NET_RAWIO capability -to be executed. It may be used as set-uid root. -.SH "AVAILABILITY" -.PP -\fBping\fR is part of \fIiputils\fR package -and the latest versions are available in source form at -http://www.skbuff.net/iputils/iputils-current.tar.bz2. diff --git a/system/base/iputils/files/man/rarpd.8 b/system/base/iputils/files/man/rarpd.8 deleted file mode 100644 index 0e68d549..00000000 --- a/system/base/iputils/files/man/rarpd.8 +++ /dev/null @@ -1,84 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "RARPD" "8" "24 Mayıs 2011" "iputils-101006" "System Manager's Manual: iputils" -.SH NAME -rarpd \- answer RARP REQUESTs -.SH SYNOPSIS - -\fBarping\fR [ \fB-aAvde\fR] [ \fB-b \fIbootdir\fB\fR] [ \fB\fIinterface\fB\fR] - -.SH "DESCRIPTION" -.PP -Listens -RARP -requests from clients. Provided MAC address of client -is found in \fI/etc/ethers\fR database and -obtained host name is resolvable to an IP address appropriate -for attached network, \fBrarpd\fR answers to client with RARPD -reply carrying an IP address. -.PP -To allow multiple boot servers on the network \fBrarpd\fR -optionally checks for presence Sun-like bootable image in TFTP directory. -It should have form \fBHexadecimal_IP.ARCH\fR, f.e. to load -sparc 193.233.7.98 \fIC1E90762.SUN4M\fR is linked to -an image appropriate for SUM4M in directory \fI/etc/tftpboot\fR. -.SH "WARNING" -.PP -This facility is deeply obsoleted by -BOOTP -and later -DHCP protocols. -However, some clients really still need this to boot. -.SH "OPTIONS" -.TP -\fB-a\fR -Listen on all the interfaces. Currently it is an internal -option, its function is overridden with \fIinterface\fR -argument. It should not be used. -.TP -\fB-A\fR -Listen not only RARP but also ARP messages, some rare clients -use ARP by some unknown reason. -.TP -\fB-v\fR -Be verbose. -.TP -\fB-d\fR -Debug mode. Do not go to background. -.TP -\fB-e\fR -Do not check for presence of a boot image, reply if MAC address -resolves to a valid IP address using \fI/etc/ethers\fR -database and DNS. -.TP -\fB-b \fIbootdir\fB\fR -TFTP boot directory. Default is \fI/etc/tftpboot\fR -.SH "SEE ALSO" -.PP -\fBarping\fR(8), -\fBtftpd\fR(8). -.SH "AUTHOR" -.PP -\fBrarpd\fR was written by -Alexey Kuznetsov -. -It is now maintained by -YOSHIFUJI Hideaki -. -.SH "SECURITY" -.PP -\fBrarpd\fR requires CAP_NET_RAWIO capability -to listen and send RARP and ARP packets. It also needs CAP_NET_ADMIN -to give to kernel hint for ARP resolution; this is not strictly required, -but some (most of, to be more exact) clients are so badly broken that -are not able to answer ARP before they are finally booted. This is -not wonderful taking into account that clients using RARPD in 2002 -are all unsupported relic creatures of 90's and even earlier. -.SH "AVAILABILITY" -.PP -\fBrarpd\fR is part of \fIiputils\fR package -and the latest versions are available in source form at -http://www.skbuff.net/iputils/iputils-current.tar.bz2. diff --git a/system/base/iputils/files/man/rdisc.8 b/system/base/iputils/files/man/rdisc.8 deleted file mode 100644 index b8acca56..00000000 --- a/system/base/iputils/files/man/rdisc.8 +++ /dev/null @@ -1,110 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "RDISC" "8" "24 Mayıs 2011" "iputils-101006" "System Manager's Manual: iputils" -.SH NAME -rdisc \- network router discovery daemon -.SH SYNOPSIS - -\fBrdisc\fR [ \fB-abdfstvV\fR] [ \fB\fIsend_address\fB\fR] [ \fB\fIreceive_address\fB\fR] - -.SH "DESCRIPTION" -.PP -\fBrdisc\fR implements client side of the ICMP router discover protocol. -\fBrdisc\fR is invoked at boot time to populate the network -routing tables with default routes. -.PP -\fBrdisc\fR listens on the ALL_HOSTS (224.0.0.1) multicast address -(or \fIreceive_address\fR provided it is given) -for ROUTER_ADVERTISE messages from routers. The received -messages are handled by first ignoring those listed router addresses -with which the host does not share a network. Among the remaining addresses -the ones with the highest preference are selected as default routers -and a default route is entered in the kernel routing table -for each one of them. -.PP -Optionally, \fBrdisc\fR can avoid waiting for routers to announce -themselves by sending out a few ROUTER_SOLICITATION messages -to the ALL_ROUTERS (224.0.0.2) multicast address -(or \fIsend_address\fR provided it is given) -when it is started. -.PP -A timer is associated with each router address and the address will -no longer be considered for inclusion in the the routing tables if the -timer expires before a new -\fBadvertise\fR message is received from the router. -The address will also be excluded from consideration if the host receives an -\fBadvertise\fR -message with the preference being maximally negative. -.PP -Server side of router discovery protocol is supported by Cisco IOS -and by any more or less complete UNIX routing daemon, f.e \fBgated\fR. -.SH "OPTIONS" -.TP -\fB-a\fR -Accept all routers independently of the preference they have in their -\fBadvertise\fR messages. -Normally \fBrdisc\fR only accepts (and enters in the kernel routing -tables) the router or routers with the highest preference. -.TP -\fB-b\fR -Opposite to \fB-a\fR, i.e. install only router with the best -preference value. It is default behaviour. -.TP -\fB-d\fR -Send debugging messages to syslog. -.TP -\fB-f\fR -Run \fBrdisc\fR forever even if no routers are found. -Normally \fBrdisc\fR gives up if it has not received any -\fBadvertise\fR message after after soliciting three times, -in which case it exits with a non-zero exit code. -If \fB-f\fR is not specified in the first form then -\fB-s\fR must be specified. -.TP -\fB-s\fR -Send three \fBsolicitation\fR messages initially to quickly discover -the routers when the system is booted. -When \fB-s\fR is specified \fBrdisc\fR -exits with a non-zero exit code if it can not find any routers. -This can be overridden with the \fB-f\fR option. -.TP -\fB-t\fR -Test mode. Do not go to background. -.TP -\fB-v\fR -Be verbose i.e. send lots of debugging messages to syslog. -.TP -\fB-V\fR -Print version and exit. -.SH "HISTORY" -.PP -This program was developed by Sun Microsystems (see copyright -notice in source file). It was ported to Linux by -Alexey Kuznetsov -. -It is now maintained by -YOSHIFUJI Hideaki -. -.SH "SEE ALSO" -.PP -\fBicmp\fR(7), -\fBinet\fR(7), -\fBping\fR(8). -.SH "REFERENCES" -.PP -Deering, S.E.,ed "ICMP Router Discovery Messages", -RFC1256, Network Information Center, SRI International, -Menlo Park, Calif., September 1991. -.SH "SECURITY" -.PP -\fBrdisc\fR requires CAP_NET_RAWIO to listen -and send ICMP messages and capability CAP_NET_ADMIN -to update routing tables. -.SH "AVAILABILITY" -.PP -\fBrdisc\fR is part of \fIiputils\fR package -and the latest versions are available in source form at -http://www.skbuff.net/iputils/iputils-current.tar.bz2. diff --git a/system/base/iputils/files/man/tracepath.8 b/system/base/iputils/files/man/tracepath.8 deleted file mode 100644 index ed780bf9..00000000 --- a/system/base/iputils/files/man/tracepath.8 +++ /dev/null @@ -1,97 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "TRACEPATH" "8" "24 Mayıs 2011" "iputils-101006" "System Manager's Manual: iputils" -.SH NAME -tracepath, tracepath6 \- traces path to a network host discovering MTU along this path -.SH SYNOPSIS - -\fBtracepath\fR [ \fB-n\fR] [ \fB-b\fR] [ \fB-l \fIpktlen\fB\fR] \fB\fIdestination\fB\fR [ \fB\fIport\fB\fR] - -.SH "DESCRIPTION" -.PP -It traces path to \fIdestination\fR discovering MTU along this path. -It uses UDP port \fIport\fR or some random port. -It is similar to \fBtraceroute\fR, only does not require superuser -privileges and has no fancy options. -.PP -\fBtracepath6\fR is good replacement for \fBtraceroute6\fR -and classic example of application of Linux error queues. -The situation with IPv4 is worse, because commercial -IP routers do not return enough information in ICMP error messages. -Probably, it will change, when they will be updated. -For now it uses Van Jacobson's trick, sweeping a range -of UDP ports to maintain trace history. -.SH "OPTIONS" -.TP -\fB-n\fR -Print primarily IP addresses numerically. -.TP -\fB-b\fR -Print both of host names and IP addresses. -.TP -\fB-l\fR -Sets the initial packet length to \fIpktlen\fR instead of -65536 for \fBtracepath\fR or 128000 for \fBtracepath6\fR. -.SH "OUTPUT" -.PP - -.nf -root@mops:~ # tracepath6 3ffe:2400:0:109::2 - 1?: [LOCALHOST] pmtu 1500 - 1: dust.inr.ac.ru 0.411ms - 2: dust.inr.ac.ru asymm 1 0.390ms pmtu 1480 - 2: 3ffe:2400:0:109::2 463.514ms reached - Resume: pmtu 1480 hops 2 back 2 -.fi -.PP -The first column shows TTL of the probe, followed by colon. -Usually value of TTL is obtained from reply from network, -but sometimes reply does not contain necessary information and -we have to guess it. In this case the number is followed by ?. -.PP -The second column shows the network hop, which replied to the probe. -It is either address of router or word [LOCALHOST], if -the probe was not sent to the network. -.PP -The rest of line shows miscellaneous information about path to -the correspinding network hop. As rule it contains value of RTT. -Additionally, it can show Path MTU, when it changes. -If the path is asymmetric -or the probe finishes before it reach prescribed hop, difference -between number of hops in forward and backward direction is shown -following keyword async. This information is not reliable. -F.e. the third line shows asymmetry of 1, it is because the first probe -with TTL of 2 was rejected at the first hop due to Path MTU Discovery. -.PP -The last line summarizes information about all the path to the destination, -it shows detected Path MTU, amount of hops to the destination and our -guess about amount of hops from the destination to us, which can be -different when the path is asymmetric. -.SH "SEE ALSO" -.PP -\fBtraceroute\fR(8), -\fBtraceroute6\fR(8), -\fBping\fR(8). -.SH "AUTHOR" -.PP -\fBtracepath\fR was written by -Alexey Kuznetsov -. -.SH "SECURITY" -.PP -No security issues. -.PP -This lapidary deserves to be elaborated. -\fBtracepath\fR is not a privileged program, unlike -\fBtraceroute\fR, \fBping\fR and other beasts of this kind. -\fBtracepath\fR may be executed by everyone who has some access -to network, enough to send UDP datagrams to investigated destination -using given port. -.SH "AVAILABILITY" -.PP -\fBtracepath\fR is part of \fIiputils\fR package -and the latest versions are available in source form at -http://www.skbuff.net/iputils/iputils-current.tar.bz2. diff --git a/system/base/iputils/files/man/traceroute6.8 b/system/base/iputils/files/man/traceroute6.8 deleted file mode 100644 index 7dfe99d3..00000000 --- a/system/base/iputils/files/man/traceroute6.8 +++ /dev/null @@ -1,42 +0,0 @@ -.\" This manpage has been automatically generated by docbook2man -.\" from a DocBook document. This tool can be found at: -.\" -.\" Please send any bug reports, improvements, comments, patches, -.\" etc. to Steve Cheng . -.TH "TRACEROUTE6" "8" "24 Mayıs 2011" "iputils-101006" "System Manager's Manual: iputils" -.SH NAME -traceroute6 \- traces path to a network host -.SH SYNOPSIS - -\fBtraceroute6\fR [ \fB-dnrvV\fR] [ \fB-i \fIinterface\fB\fR] [ \fB-m \fImax_ttl\fB\fR] [ \fB-p \fIport\fB\fR] [ \fB-q \fImax_probes\fB\fR] [ \fB-s \fIsource\fB\fR] [ \fB-w \fIwait time\fB\fR] \fB\fIdestination\fB\fR [ \fB\fIsize\fB\fR] - -.SH "DESCRIPTION" -.PP -Description can be found in -\fBtraceroute\fR(8), -all the references to IP replaced to IPv6. It is needless to copy -the description from there. -.SH "SEE ALSO" -.PP -\fBtraceroute\fR(8), -\fBtracepath\fR(8), -\fBping\fR(8). -.SH "HISTORY" -.PP -This program has long history. Author of \fBtraceroute\fR -is Van Jacobson and it first appeared in 1988. This clone is -based on a port of \fBtraceroute\fR to IPv6 published -in NRL IPv6 distribution in 1996. In turn, it was ported -to Linux by Pedro Roque. After this it was kept in sync by -Alexey Kuznetsov -. And eventually entered -\fBiputils\fR package. -.SH "SECURITY" -.PP -\fBtracepath6\fR requires CAP_NET_RAWIO capability -to be executed. It is safe to be used as set-uid root. -.SH "AVAILABILITY" -.PP -\fBtraceroute6\fR is part of \fIiputils\fR package -and the latest versions are available in source form at -http://www.skbuff.net/iputils/iputils-current.tar.bz2. diff --git a/system/base/iputils/pspec.xml b/system/base/iputils/pspec.xml deleted file mode 100644 index 3686682d..00000000 --- a/system/base/iputils/pspec.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - - iputils - http://www.linux-ipv6.org - - PisiLinux Community - admins@pisilinux.org - - BSD - app:console - Network monitoring tools including ping and ping6 - iputils contains network monitoring tools including ping and ping6. - http://www.skbuff.net/iputils/iputils-s20121221.tar.bz2 - - - ifenslave/ifenslave.c - - - openssl-devel - libidn-devel - gnutls-devel - - - - 021109-uclibc-no-ether_ntohost.patch - - iputils-20121221-printf-size.patch - iputils-20121221-owl-pingsock.diff - iputils-20121221-openssl.patch - iputils-20121221-makefile.patch - iputils-20121221-crypto-build.patch - iputils-20100418-so_mark.patch - iputils-20071127-nonroot-floodping.patch - iputils-20071127-kernel-ifaddr.patch - - - - fedora/iputils-20020124-countermeasures.patch - - fedora/iputils-20020927-ping-subint.patch - - fedora/iputils-20070202-traffic_class.patch - - fedora/iputils-20100418-convtoint.patch - - - - - - - docs.patch - - - - - iputils - - libcap - gnutls - - - /bin - /usr/bin - /usr/sbin - /sbin - /lib/systemd/system - /etc/conf.d/rdisc - /usr/share/doc - /usr/share/man - - - - man/arping.8 - man/clockdiff.8 - man/ping.8 - man/rarpd.8 - man/rdisc.8 - man/tracepath.8 - man/traceroute6.8 - ifenslave/ifenslave.8 - ifenslave/README.bonding - - - fedora/rdisc.sysconfig - fedora/rdisc.service - - - - - - 2014-05-11 - 20121221 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-26 - 20121221 - Fix dep, release bump. - PisiLinux Community - admins@pisilinux.org - - - 2013-01-14 - 20121221 - New release - PisiLinux Community - admins@pisilinux.org - - - 2012-08-23 - 20101006 - First release - PisiLinux Community - admins@pisilinux.org - - - diff --git a/system/base/iputils/translations.xml b/system/base/iputils/translations.xml deleted file mode 100644 index ed28e723..00000000 --- a/system/base/iputils/translations.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - iputils - ping ve ping6 uygulamalarını da içeren ağ izleme araçları - Iputils, ping ve ping6 gibi ağ izleme araçlarını içeren bir pakettir. - Iputils contient les outils de surveillance réseau incluant ping et ping6. - - diff --git a/system/base/json-c/pspec.xml b/system/base/json-c/pspec.xml index 5083824a..7a3ad3a7 100644 --- a/system/base/json-c/pspec.xml +++ b/system/base/json-c/pspec.xml @@ -45,6 +45,9 @@ json-c-32bit emul32 32-bit shared libraries for json-c + + glibc-32bit + emul32 /usr/lib32 @@ -53,7 +56,7 @@ - 2014-07-04 + 2015-04-30 0.12 Version bump and security update(CVE-2013-6371, CVE-2013-6370). Vedat Demir diff --git a/system/base/kbd/actions.py b/system/base/kbd/actions.py index 3b6b49b0..4ed46171 100644 --- a/system/base/kbd/actions.py +++ b/system/base/kbd/actions.py @@ -8,19 +8,22 @@ from pisi.actionsapi import pisitools from pisi.actionsapi import get def setup(): - autotools.configure("--enable-nls") + autotools.configure("--enable-nls \ + --prefix=/usr \ + --datadir=/usr/share/kbd \ + --mandir=/usr/share/man") def build(): - autotools.make() + autotools.make("KEYCODES_PROGS=yes RESIZECONS_PROGS=yes") def install(): - autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + autotools.rawInstall("KEYCODES_PROGS=yes RESIZECONS_PROGS=yes DESTDIR=%s" % get.installDIR()) for exe in ("loadkeys", "setfont", "unicode_start", "unicode_stop"): pisitools.domove("/usr/bin/%s" % exe, "/bin") pisitools.dosym("/bin/%s" % exe, "/usr/bin/%s" % exe) - pisitools.remove("/usr/share/keymaps/i386/qwerty/trf.map.gz") + pisitools.remove("/usr/share/kbd/keymaps/i386/qwerty/trf.map.gz") - pisitools.dohtml("doc/*") + pisitools.dohtml("docs/doc/*.html") pisitools.dodoc("AUTHORS", "ChangeLog", "COPYING", "README") diff --git a/system/base/kbd/files/archlinux/fix-dvorak-es.patch b/system/base/kbd/files/archlinux/fix-dvorak-es.patch new file mode 100644 index 00000000..95760fd3 --- /dev/null +++ b/system/base/kbd/files/archlinux/fix-dvorak-es.patch @@ -0,0 +1,11 @@ +--- kbd-1.15.5/data/keymaps/i386/dvorak/dvorak-es.map.old 2013-05-08 14:58:03.393349828 +0200 ++++ kbd-1.15.5/data/keymaps/i386/dvorak/dvorak-es.map 2013-05-08 14:58:20.206415053 +0200 +@@ -4,7 +4,7 @@ + + keymaps 0-2,4,5,6,8-10,12,14 + include "linux-with-alt-and-altgr" +-include "euro" ++include "euro.map" + strings as usual + + keycode 1 = Escape diff --git a/system/base/kbd/files/archlinux/fix-euro2.patch b/system/base/kbd/files/archlinux/fix-euro2.patch new file mode 100644 index 00000000..572cba74 --- /dev/null +++ b/system/base/kbd/files/archlinux/fix-euro2.patch @@ -0,0 +1,9 @@ +--- kbd-1.15.5/data/keymaps/i386/include/euro2.map.old 2013-05-08 15:00:25.917752313 +0200 ++++ kbd-1.15.5/data/keymaps/i386/include/euro2.map 2013-05-08 15:00:54.943957367 +0200 +@@ -2,5 +2,5 @@ + # [Say: "loadkeys euro2" to get Euro and cent with AltGr (right alt) + # on the positions where many keyboards have E and C. + # To get it displayed, use a latin0 (i.e., latin9) font.] +-altgr keycode 18 = currency ++altgr keycode 18 = euro + altgr keycode 46 = cent diff --git a/system/base/kbd/pspec.xml b/system/base/kbd/pspec.xml index 785ac8c6..175d479b 100644 --- a/system/base/kbd/pspec.xml +++ b/system/base/kbd/pspec.xml @@ -12,36 +12,26 @@ app:console Keyboard and console utilities The kbd package contains keytable files and keyboard utilities compatible with kernel version 1.1.54 and later. - ftp://ftp.altlinux.org/pub/people/legion/kbd/kbd-1.15.5.tar.gz - http://source.pisilinux.org/1.0/kbd-latarcyrheb-16-fixed.tar.bz2 - http://source.pisilinux.org/1.0/kbd-latsun-fonts.tar.bz2 - http://source.pisilinux.org/1.0/ro_maps.tar.bz2 + https://www.kernel.org/pub/linux/utils/kbd/kbd-2.0.2.tar.xz + http://source.pisilinux.org/1.0/kbd-latarcyrheb-16-fixed.tar.bz2 + http://source.pisilinux.org/1.0/kbd-latsun-fonts.tar.bz2 + http://source.pisilinux.org/1.0/ro_maps.tar.bz2 gettext gzip + pam-devel + check-devel - kbd-1.15.5-loadkeys-parse.patch - - - mandriva/kbd-1.15-mandriva.patch mandriva/kbd-1.15-tilde_twosuperior_french_kbd.patch mandriva/kbd-1.12-data_thai.patch mandriva/kbd-1.15-remove-unneeded-calls.patch - - - fedora/kbd-1.15-keycodes-man.patch - - + + + archlinux/fix-dvorak-es.patch + archlinux/fix-euro2.patch pisilinux/unicode_start-default-font.patch @@ -51,6 +41,7 @@ pisilinux/currency.patch pisilinux/trf-keymap-fixes.patch pisilinux/trf-capslock-fix.patch + @@ -64,23 +55,30 @@ /usr/bin /usr/share/doc /usr/share/man - /usr/share/keymaps - /usr/share/locale - /usr/share/unimaps - /usr/share/consolefonts - /usr/share/consoletrans + /usr/share/kbd/keymaps + /usr/share/kbd/locale + /usr/share/kbd/unimaps + /usr/share/kbd/consolefonts + /usr/share/kbd/consoletrans - pisilinux/lat5u-12.psf.gz - pisilinux/lat5u-14.psf.gz - pisilinux/lat5u-16.psf.gz + pisilinux/lat5u-12.psf.gz + pisilinux/lat5u-14.psf.gz + pisilinux/lat5u-16.psf.gz - mandriva/mac-fr-ext_new.kmap.gz + mandriva/mac-fr-ext_new.kmap.gz + + 2015-05-08 + 2.0.2 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 1.15.5 diff --git a/system/base/kmod/actions.py b/system/base/kmod/actions.py index 28246c96..9687ff35 100644 --- a/system/base/kmod/actions.py +++ b/system/base/kmod/actions.py @@ -17,8 +17,9 @@ def setup(): def build(): autotools.make() -def check(): - autotools.make("check") +# need git for check +#def check(): +# autotools.make("check") def install(): autotools.rawInstall("DESTDIR=%s" % get.installDIR()) diff --git a/system/base/kmod/files/depmod-search.conf b/system/base/kmod/files/depmod-search.conf new file mode 100644 index 00000000..36f2cf7d --- /dev/null +++ b/system/base/kmod/files/depmod-search.conf @@ -0,0 +1,5 @@ +# +# /usr/lib/depmod.d/search.conf +# + +search updates extramodules built-in diff --git a/system/base/kmod/files/kmod-15-dynamic-kmod.patch b/system/base/kmod/files/kmod-15-dynamic-kmod.patch new file mode 100644 index 00000000..fc46f578 --- /dev/null +++ b/system/base/kmod/files/kmod-15-dynamic-kmod.patch @@ -0,0 +1,23 @@ +diff --git a/sys-apps/kmod/files/kmod-15-dynamic-kmod.patch b/sys-apps/kmod/files/kmod-15-dynamic-kmod.patch +new file mode 100644 +index 0000000..c93bea6 +--- /dev/null ++++ b/sys-apps/kmod/files/kmod-15-dynamic-kmod.patch + +@@ -0,0 +1,16 @@ ++do not statically link kmod against its own libraries ++ ++https://bugs.gentoo.org/493630 ++http://thread.gmane.org/gmane.linux.kernel.modules/1206 ++ ++--- a/Makefile.in +++++ b/Makefile.in ++@@ -817,7 +817,7 @@ ++ @BUILD_TOOLS_TRUE@ tools/static-nodes.c ++ ++ @BUILD_TOOLS_TRUE@tools_kmod_LDADD = libkmod/libkmod-util.la \ ++-@BUILD_TOOLS_TRUE@ libkmod/libkmod-internal.la +++@BUILD_TOOLS_TRUE@ libkmod/libkmod.la ++ ++ ++ # ------------------------------------------------------------------------------ diff --git a/system/base/kmod/pspec.xml b/system/base/kmod/pspec.xml index 4dcbc239..01662c52 100644 --- a/system/base/kmod/pspec.xml +++ b/system/base/kmod/pspec.xml @@ -12,11 +12,19 @@ app:console Linux kernel module management utilities Linux kernel module management utilities - ftp://ftp.kernel.org/pub/linux/utils/kernel/kmod/kmod-19.tar.xz + https://www.kernel.org/pub/linux/utils/kernel/kmod/kmod-20.tar.xz chrpath - libxslt + + xz-32bit + xz-devel + zlib-32bit + zlib-devel + kernel-module-headers + + kmod-15-dynamic-kmod.patch + @@ -47,6 +55,8 @@ modprobe.conf depmod.conf + + depmod-search.conf @@ -88,6 +98,7 @@ xz-32bit zlib-32bit + glibc-32bit /usr/lib32 @@ -95,6 +106,13 @@ + + 2015-03-26 + 20 + Version bump,add patch and fix deps. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-11-18 19 diff --git a/system/base/libX11/actions.py b/system/base/libX11/actions.py deleted file mode 100644 index 4d41b1e2..00000000 --- a/system/base/libX11/actions.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Licensed under the GNU General Public License, version 3. -# See the file http://www.gnu.org/licenses/gpl.txt - -from pisi.actionsapi import get -from pisi.actionsapi import autotools -from pisi.actionsapi import pisitools -from pisi.actionsapi import shelltools - -def setup(): - autotools.autoreconf("-vif") - autotools.configure("--disable-static") - - pisitools.dosed("libtool", "^(hardcode_libdir_flag_spec=).*", '\\1""') - pisitools.dosed("libtool", "^(runpath_var=)LD_RUN_PATH", "\\1DIE_RPATH_DIE") - pisitools.dosed("libtool"," -shared ", " -Wl,--as-needed -shared ") - -def build(): - autotools.make() - -def install(): - autotools.rawInstall("DESTDIR=%s" % get.installDIR()) - if get.buildTYPE() == "emul32": return - - pisitools.dodoc("AUTHORS", "COPYING", "NEWS", "README") diff --git a/system/base/libX11/files/fix-null-pointer.patch b/system/base/libX11/files/fix-null-pointer.patch deleted file mode 100644 index 8b37f365..00000000 --- a/system/base/libX11/files/fix-null-pointer.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur libX11-1.3.5//src/xlibi18n/ICWrap.c libX11-1.3.5.tpg//src/xlibi18n/ICWrap.c ---- libX11-1.3.5//src/xlibi18n/ICWrap.c 2010-08-10 04:59:44.000000000 +0000 -+++ libX11-1.3.5.tpg//src/xlibi18n/ICWrap.c 2010-09-17 17:11:21.000000000 +0000 -@@ -283,7 +283,7 @@ - XIMArg *args; - char *ret; - -- if (!ic->core.im) -+ if (!ic || !ic->core.im) - return (char *) NULL; - - /* diff --git a/system/base/libX11/files/fix-segfault.diff b/system/base/libX11/files/fix-segfault.diff deleted file mode 100644 index a38c0ce2..00000000 --- a/system/base/libX11/files/fix-segfault.diff +++ /dev/null @@ -1,50 +0,0 @@ -Index: libX11-1.4.99.1/src/Xrm.c -=================================================================== ---- libX11-1.4.99.1.orig/src/Xrm.c -+++ libX11-1.4.99.1/src/Xrm.c -@@ -2540,30 +2540,40 @@ Bool XrmQGetResource( - VClosureRec closure; - - if (db && *names) { -- _XLockMutex(&db->linfo); -+ if ((_XLockMutex_fn) && db->linfo.lock ) { -+ _XLockMutex(&db->linfo); -+ } - closure.type = pType; - closure.value = pValue; - table = db->table; - if (names[1]) { - if (table && !table->leaf) { - if (GetNEntry(table, names, classes, &closure)) { -- _XUnlockMutex(&db->linfo); -+ if ((_XUnlockMutex_fn) && db->linfo.lock ) { -+ _XUnlockMutex(&db->linfo); -+ } - return True; - } - } else if (table && table->hasloose && - GetLooseVEntry((LTable)table, names, classes, &closure)) { -- _XUnlockMutex (&db->linfo); -+ if ((_XUnlockMutex_fn) && db->linfo.lock ) { -+ _XUnlockMutex (&db->linfo); -+ } - return True; - } - } else { - if (table && !table->leaf) - table = table->next; - if (table && GetVEntry((LTable)table, names, classes, &closure)) { -- _XUnlockMutex(&db->linfo); -+ if ((_XUnlockMutex_fn) && db->linfo.lock ) { -+ _XUnlockMutex(&db->linfo); -+ } - return True; - } - } -- _XUnlockMutex(&db->linfo); -+ if ((_XUnlockMutex_fn) && db->linfo.lock ) { -+ _XUnlockMutex(&db->linfo); -+ } - } - *pType = NULLQUARK; - pValue->addr = (XPointer)NULL; diff --git a/system/base/libX11/pspec.xml b/system/base/libX11/pspec.xml deleted file mode 100644 index 82f3791f..00000000 --- a/system/base/libX11/pspec.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - libX11 - http://www.x.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - X.Org X11 library - Core X11 protocol client library. - mirrors://xorg/individual/lib/libX11-1.6.2.tar.bz2 - - libxcb-devel - xorg-proto - xtrans - - - fix-segfault.diff - fix-null-pointer.patch - - - - - libX11 - - libxcb - - - /usr/lib/libX11* - /usr/lib/X11 - /usr/share/X11 - /usr/share/doc/libX11 - - - - - libX11-devel - system.devel - Development files for X11 library - - libX11 - libxcb-devel - xorg-proto - - - /usr/include/X11 - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/man - - - - - libX11-32bit - emul32 - 32-bit shared libraries for libX11 - emul32 - - libxcb-32bit - - - libX11 - libxcb-32bit - - - /usr/lib32 - - - - - - 2014-05-11 - 1.6.2 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-07 - 1.6.2 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-09-12 - 1.6.2 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-07-30 - 1.6.1 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-06-21 - 1.6.0 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-11-24 - 1.5.0 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - diff --git a/system/base/libX11/translations.xml b/system/base/libX11/translations.xml deleted file mode 100644 index f7b669ff..00000000 --- a/system/base/libX11/translations.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - libX11 - X.Org X11 kitaplığı - Librairie X11 de X.Org. - X.Org X11 Bibliothek - - - - libX11-devel - libX11 için geliştirme dosyaları - - - - libX11-32bit - libX11 için 32-bit paylaşımlı kitaplıklar - - diff --git a/system/base/libXau/actions.py b/system/base/libXau/actions.py deleted file mode 100644 index 1e2e53ca..00000000 --- a/system/base/libXau/actions.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Licensed under the GNU General Public License, version 3. -# See the file http://www.gnu.org/licenses/gpl.txt - -from pisi.actionsapi import get -from pisi.actionsapi import autotools -from pisi.actionsapi import shelltools - -def setup(): - autotools.autoreconf("-vif") - autotools.configure("--disable-static") - -def build(): - autotools.make() - -def install(): - autotools.rawInstall("DESTDIR=%s" % get.installDIR()) - diff --git a/system/base/libXau/files/visibility.patch b/system/base/libXau/files/visibility.patch deleted file mode 100644 index 5a338a16..00000000 --- a/system/base/libXau/files/visibility.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- libXau-1.0.3/AuDispose.c.orig 2007-11-23 17:51:27.000000000 -0200 -+++ libXau-1.0.3/AuDispose.c 2007-11-23 17:51:34.000000000 -0200 -@@ -33,7 +33,7 @@ in this Software without prior written a - #include - #include - --void -+_X_EXPORT void - XauDisposeAuth (Xauth *auth) - { - if (auth) { ---- libXau-1.0.3/AuRead.c.orig 2007-11-23 17:52:14.000000000 -0200 -+++ libXau-1.0.3/AuRead.c 2007-11-23 17:52:21.000000000 -0200 -@@ -69,7 +69,7 @@ read_counted_string (unsigned short *cou - return 1; - } - --Xauth * -+_X_EXPORT Xauth * - XauReadAuth (FILE *auth_file) - { - Xauth local; diff --git a/system/base/libXau/pspec.xml b/system/base/libXau/pspec.xml deleted file mode 100644 index a13e5ff5..00000000 --- a/system/base/libXau/pspec.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - libXau - http://www.x.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - X.Org Au library - libXau provides functions to manage X authorization files - http://xorg.freedesktop.org/archive/individual/lib/libXau-1.0.8.tar.gz - - visibility.patch - - - - - libXau - - /usr/lib - - - - - libXau-devel - system.devel - Development files for libXau - - libXau - - - /usr/include/X11 - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/man - - - - - libXau-32bit - emul32 - 32-bit shared libraries for libXau - emul32 - - libXau - - - /usr/lib32 - - - - - - 2014-05-11 - 1.0.8 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-07 - 1.0.8 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-06-21 - 1.0.8 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-08-23 - 1.0.7 - First release - PisiLinux Community - admins@pisilinux.org - - - diff --git a/system/base/libXau/translations.xml b/system/base/libXau/translations.xml deleted file mode 100644 index a48e4482..00000000 --- a/system/base/libXau/translations.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - libXau - X.Org Au kitaplığı. - Librairie Au de X.Org. - X.Org Au Bibliothek - libXau, X yetkilendirme dosyalarını yönetmek için işlevler sağlar. - - - - libXau-devel - libXau için geliştirme dosyaları - - - - libXau-32bit - libXau için 32-bit paylaşımlı kitaplıklar - - diff --git a/system/base/libXdmcp/pspec.xml b/system/base/libXdmcp/pspec.xml deleted file mode 100644 index 87eca840..00000000 --- a/system/base/libXdmcp/pspec.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - libXdmcp - http://x.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - X.Org Xdmcp library - LibXdmcp is the X Display Manager Control Protocol library. - http://xorg.freedesktop.org/archive/individual/lib/libXdmcp-1.1.1.tar.bz2 - - - - libXdmcp - - /usr/lib - /usr/share/doc - - - - - libXdmcp-devel - system.devel - Development files for libXdmcp - - libXdmcp - - - /usr/include/X11 - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - /usr/share/doc/*/*.xml - - - - - libXdmcp-32bit - emul32 - 32-bit shared libraries for libXdmcp - emul32 - - libXdmcp - - - /usr/lib32 - - - - - - 2014-05-11 - 1.1.1 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2013-10-08 - 1.1.1 - Rebuild, clean actions.py. - Serdar Soytetir - kaptan@pisilinux.org - - - 2012-08-23 - 1.1.1 - First release - PisiLinux Community - admins@pisilinux.org - - - diff --git a/system/base/libXdmcp/translations.xml b/system/base/libXdmcp/translations.xml deleted file mode 100644 index 7eb6f757..00000000 --- a/system/base/libXdmcp/translations.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - libXdmcp - X.Org Xdmcp kitaplığı. - Librairie Xdmcp de X.Org. - X.Org Xdmcp Bibliothek - LibXdmcp, X Ekran Yöneticisi Denetim Protokolü kitaplığıdır. - - - - libXdmcp-devel - libXdmcp için geliştirme dosyaları - - - - libXdmcp-32bit - libXdmcp için 32-bit paylaşımlı kitaplıklar - - diff --git a/system/base/libcap/pspec.xml b/system/base/libcap/pspec.xml index 43a0f57d..68ca1abe 100644 --- a/system/base/libcap/pspec.xml +++ b/system/base/libcap/pspec.xml @@ -16,7 +16,7 @@ https://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/libcap-2.24.tar.xz attr-devel - pam + pam-devel @@ -56,9 +56,10 @@ emul32 attr-32bit + glibc-32bit - libcap + glibc-32bit attr-32bit @@ -67,6 +68,13 @@ + + 2015-03-16 + 2.24 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 2.24 diff --git a/system/base/libgcrypt/pspec.xml b/system/base/libgcrypt/pspec.xml index 7c74ee80..6799f13d 100644 --- a/system/base/libgcrypt/pspec.xml +++ b/system/base/libgcrypt/pspec.xml @@ -12,7 +12,7 @@ library General purpose crypto library Libgcrypt is a general purpose crypto library based on the code used in GNU Privacy Guard. - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.1.tar.bz2 + http://source.pisilinux.org/1.0/libgcrypt-1.6.3.tar.bz2 libgpg-error-devel @@ -57,9 +57,11 @@ emul32 libgpg-error-32bit + glibc-32bit libgpg-error-32bit + glibc-32bit libgcrypt @@ -68,6 +70,13 @@ + + 2015-04-13 + 1.6.3 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 1.6.1 diff --git a/system/base/libgpg-error/pspec.xml b/system/base/libgpg-error/pspec.xml index ef455176..a2a7a799 100644 --- a/system/base/libgpg-error/pspec.xml +++ b/system/base/libgpg-error/pspec.xml @@ -13,7 +13,7 @@ library Library for error values used by GnuPG components libgpg-error is a library that defines common error values for all GnuPG components. - ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.12.tar.bz2 + ftp://ftp.gnupg.org/gcrypt/libgpg-error/libgpg-error-1.19.tar.bz2 @@ -22,6 +22,8 @@ /usr/bin /usr/lib /usr/share/doc + /usr/share/info + /usr/share/man /usr/share/locale @@ -34,7 +36,7 @@ libgpg-error - /usr/bin/*-config + /usr/bin/gpg-error-config /usr/include /usr/lib/pkgconfig /usr/lib32/pkgconfig @@ -47,8 +49,12 @@ emul32 32-bit shared libraries for libgpg-error emul32 + + glibc-32bit + libgpg-error + glibc-32bit /usr/lib32 @@ -56,6 +62,13 @@ + + 2015-04-13 + 1.19 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 1.12 diff --git a/system/base/libidn/pspec.xml b/system/base/libidn/pspec.xml index 6a830f5f..ce45c4b3 100644 --- a/system/base/libidn/pspec.xml +++ b/system/base/libidn/pspec.xml @@ -34,6 +34,9 @@ libidn-devel system.devel Development files for libidn + + glibc-32bit + libidn diff --git a/system/base/libpcre/pspec.xml b/system/base/libpcre/pspec.xml index 1795b1ca..d1725719 100644 --- a/system/base/libpcre/pspec.xml +++ b/system/base/libpcre/pspec.xml @@ -58,6 +58,7 @@ emul32 readline-32bit + glibc-32bit libgcc diff --git a/system/devel/libunwind/actions.py b/system/base/libunwind/actions.py similarity index 100% rename from system/devel/libunwind/actions.py rename to system/base/libunwind/actions.py diff --git a/system/devel/libunwind/pspec.xml b/system/base/libunwind/pspec.xml similarity index 100% rename from system/devel/libunwind/pspec.xml rename to system/base/libunwind/pspec.xml diff --git a/system/devel/libunwind/translations.xml b/system/base/libunwind/translations.xml similarity index 100% rename from system/devel/libunwind/translations.xml rename to system/base/libunwind/translations.xml diff --git a/system/base/libusb-compat/pspec.xml b/system/base/libusb-compat/pspec.xml index 940ba512..4983026c 100644 --- a/system/base/libusb-compat/pspec.xml +++ b/system/base/libusb-compat/pspec.xml @@ -53,9 +53,12 @@ emul32 libusb-32bit + glibc-32bit libusb-32bit + libusb + glibc-32bit libusb-compat @@ -65,7 +68,7 @@ - 2014-09-08 + 2015-05-05 0.1.5 Rebuild for libusbx libusb changes diff --git a/system/base/libusb/actions.py b/system/base/libusb/actions.py index 144f72f0..47def8af 100644 --- a/system/base/libusb/actions.py +++ b/system/base/libusb/actions.py @@ -9,7 +9,9 @@ from pisi.actionsapi import pisitools from pisi.actionsapi import get def setup(): - autotools.configure("--disable-static") + autotools.configure("--disable-static \ + --enable-udev") + def build(): autotools.make() diff --git a/system/base/libusb/pspec.xml b/system/base/libusb/pspec.xml index 74c7f89d..7b1fcd4e 100644 --- a/system/base/libusb/pspec.xml +++ b/system/base/libusb/pspec.xml @@ -14,7 +14,7 @@ Project's main aim is to create a library for use by user level applications to access USB devices regardless of OS. http://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-1.0.19/libusb-1.0.19.tar.bz2 - libudev-devel + eudev-devel @@ -27,7 +27,7 @@ libusbx - libudev + eudev /usr/bin @@ -68,11 +68,12 @@ 32-bit shared libraries for libusb emul32 - libudev-32bit + glibc-32bit libusb - libudev-32bit + eudev-32bit + glibc-32bit /usr/lib32 @@ -81,7 +82,7 @@ - 2014-09-08 + 2014-04-30 1.0.19 rename libusbx to libusb like upsteam diff --git a/system/base/libuser/actions.py b/system/base/libuser/actions.py new file mode 100644 index 00000000..074bd724 --- /dev/null +++ b/system/base/libuser/actions.py @@ -0,0 +1,35 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 3. +# See the file http://www.gnu.org/licenses/gpl.txt + +from pisi.actionsapi import autotools +from pisi.actionsapi import pisitools +from pisi.actionsapi import shelltools +from pisi.actionsapi import get + +def setup(): + shelltools.export("AUTOPOINT", "true") + + autotools.configure("--with-python \ + --without-ldap \ + --without-sasl \ + --with-popt \ + --disable-rpath \ + --enable-gtk-doc-html=no \ + --disable-gtk-doc") + + pisitools.dosed("libtool"," -shared ", " -Wl,--as-needed -shared ") + +def build(): + autotools.make() + + autotools.make("-C po update-gmo") + +def install(): + autotools.rawInstall("DESTDIR='%s'" % get.installDIR()) + + pisitools.removeDir("/usr/share/gtk-doc") + + pisitools.dodoc("ABOUT*", "AUTHORS", "COPYING", "NEWS", "README") diff --git a/system/base/libuser/files/add-python-linkage.diff b/system/base/libuser/files/add-python-linkage.diff new file mode 100644 index 00000000..23562d28 --- /dev/null +++ b/system/base/libuser/files/add-python-linkage.diff @@ -0,0 +1,11 @@ +--- Makefile.am.OSmanOS 2012-11-08 04:25:58.000000000 +0200 ++++ Makefile.am 2013-02-14 18:27:39.272866825 +0200 +@@ -198,7 +198,7 @@ + python_libusermodule_la_SOURCES = python/libusermodule.c python/common.h \ + python/debug.h + python_libusermodule_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_CPPFLAGS) +-python_libusermodule_la_LDFLAGS = -module -avoid-version $(GOBJECT_LIBS) ++python_libusermodule_la_LDFLAGS = -module -avoid-version $(GOBJECT_LIBS) -lpython$(PYTHON_VERSION) + python_libusermodule_la_LIBADD = lib/libuser.la + + samples_enum_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS) diff --git a/system/base/libuser/files/disable-sgml2x-conversion.diff b/system/base/libuser/files/disable-sgml2x-conversion.diff new file mode 100644 index 00000000..cf406615 --- /dev/null +++ b/system/base/libuser/files/disable-sgml2x-conversion.diff @@ -0,0 +1,18 @@ +Index: libuser-0.56.17/docs/Makefile.am +=================================================================== +--- libuser-0.56.17.orig/docs/Makefile.am ++++ libuser-0.56.17/docs/Makefile.am +@@ -1,12 +1,10 @@ +-SUBDIRS = reference +- + man_MANS = libuser.conf.5 + + CLEANFILES = $(man_MANS) sgml/libuser.html sgml/libuser-1.html \ + sgml/libuser-2.html sgml/libuser.txt + EXTRA_DIST = attributes.txt libuser.conf.5.in rfc2307.txt sgml/libuser.sgml + +-all: sgml/libuser.txt sgml/libuser.html ++all: libuser.conf.5 + + libuser.conf.5: $(srcdir)/libuser.conf.5.in Makefile + sed 's,@sysconfdir\@,$(sysconfdir),g' \ diff --git a/system/base/libuser/files/libuser-0.56.15-fix_blowfish.patch b/system/base/libuser/files/libuser-0.56.15-fix_blowfish.patch new file mode 100644 index 00000000..cc8bcf5b --- /dev/null +++ b/system/base/libuser/files/libuser-0.56.15-fix_blowfish.patch @@ -0,0 +1,28 @@ +--- lib/util.c 2010-05-20 15:46:11.000000000 +0200 ++++ lib/util.c 2010-05-20 16:23:28.000000000 +0200 +@@ -116,14 +116,14 @@ + } + + static const struct { +- const char initial[5]; ++ const char initial[8]; + char separator[2]; + size_t salt_length; + gboolean sha_rounds; + } salt_type_info[] = { + {"$1$", "$", 8, FALSE }, + /* FIXME: number of rounds, base64 of 128 bits */ +- {"$2a$", "$", 8, FALSE }, ++ {"$2a$08$", "$", 22, FALSE }, + {"$5$", "$", 16, TRUE }, + {"$6$", "$", 16, TRUE }, + { "", "", 2 }, +@@ -230,7 +230,7 @@ + } salt_types[] = { + { "des", "", FALSE }, + { "md5", "$1$", FALSE }, +- { "blowfish", "$2a$", FALSE }, ++ { "blowfish", "$2a$08$", FALSE }, + { "sha256", "$5$", TRUE }, + { "sha512", "$6$", TRUE }, + }; diff --git a/system/base/libuser/files/libuser-0.56.9-fix-str-fmt.patch b/system/base/libuser/files/libuser-0.56.9-fix-str-fmt.patch new file mode 100644 index 00000000..4210d77e --- /dev/null +++ b/system/base/libuser/files/libuser-0.56.9-fix-str-fmt.patch @@ -0,0 +1,22 @@ +--- modules/files.c.str 2008-12-27 08:27:58.000000000 +0100 ++++ modules/files.c 2008-12-27 08:28:24.000000000 +0100 +@@ -281,7 +281,7 @@ + string, &err); + if (ret == FALSE) { + g_assert(err != NULL); +- g_warning(lu_strerror(err)); ++ g_warning("%s",lu_strerror(err)); + lu_error_free(&err); + } + return ret; +--- modules/ldap.c.str 2008-12-27 08:28:41.000000000 +0100 ++++ modules/ldap.c 2008-12-27 08:29:03.000000000 +0100 +@@ -677,7 +677,7 @@ + (&value, attr, val, &error); + if (ok == FALSE) { + g_assert(error != NULL); +- g_warning(lu_strerror(error)); ++ g_warning("%s",lu_strerror(error)); + lu_error_free(&error); + } else { + lu_ent_add_current(ent, attr, diff --git a/system/base/libuser/pspec.xml b/system/base/libuser/pspec.xml new file mode 100644 index 00000000..8dcc364b --- /dev/null +++ b/system/base/libuser/pspec.xml @@ -0,0 +1,122 @@ + + + + + libuser + https://fedorahosted.org/libuser + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + library + A user and group account administration library + libuser implements a standardized interface for manipulating and administering user and group accounts. The library uses pluggable back-ends to interface to its data sources. + https://fedorahosted.org/releases/l/i/libuser/libuser-0.61.tar.xz + + pam-devel + popt-devel + glib2-devel + python-devel + + + libuser-0.56.15-fix_blowfish.patch + libuser-0.56.9-fix-str-fmt.patch + + + + + + libuser + + pam + popt + glib2 + python + + + /etc + /usr/share/man + /usr/share/doc + /usr/share/locale + /usr/bin + /usr/sbin + /usr/lib + + + + + + + + + libuser-devel + system.devel + Development files for libuser + + libuser + glib2-devel + + + /usr/include + /usr/lib/pkgconfig + + + + + + 2015-04-07 + 0.61 + Version bump, build without-sasl + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 0.60 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 0.60 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2013-07-28 + 0.59 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-01-14 + 0.58.0 + New release + PisiLinux Community + admins@pisilinux.org + + + 2012-08-23 + 0.57.6 + First release + PisiLinux Community + admins@pisilinux.org + + + diff --git a/system/base/libuser/translations.xml b/system/base/libuser/translations.xml new file mode 100644 index 00000000..54c68e51 --- /dev/null +++ b/system/base/libuser/translations.xml @@ -0,0 +1,18 @@ + + + + libuser + Kullanıcı ve grup hesap yönetim kitaplığı + libuser kullanıcı ve grup hesaplarını yönetmek ve işlemek için standart bir arayüz sunar. Kitaplık, sağladığı arayüzün verilere erişimi için genişletilebilir arkauçlar kullanmaktadır. + + + + libuser-devel + libuser için geliştirme dosyaları + + + + libuser-ldap + libuser için LDAP kitaplığı + + diff --git a/system/base/libxcb/actions.py b/system/base/libxcb/actions.py deleted file mode 100644 index 291ea490..00000000 --- a/system/base/libxcb/actions.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Licensed under the GNU General Public License, version 3. -# See the file http://www.gnu.org/licenses/gpl.txt - -from pisi.actionsapi import autotools -from pisi.actionsapi import pisitools -from pisi.actionsapi import get - -def setup(): - pisitools.flags.add("-DNDEBUG") - - autotools.autoreconf("-vif") - autotools.configure("--disable-static \ - --enable-xevie \ - --enable-xprint \ - --enable-xinput \ - --enable-xkb \ - --without-doxygen") - - pisitools.dosed("libtool"," -shared ", " -Wl,--as-needed -shared ") - -def build(): - autotools.make() - -def install(): - autotools.rawInstall("-j1 DESTDIR=%s" % get.installDIR()) - - pisitools.dodoc("COPYING", "NEWS", "README") diff --git a/system/base/libxcb/files/pthread-stubs.pc b/system/base/libxcb/files/pthread-stubs.pc deleted file mode 100644 index ad7b91b6..00000000 --- a/system/base/libxcb/files/pthread-stubs.pc +++ /dev/null @@ -1,8 +0,0 @@ -prefix=/usr -exec_prefix=${prefix} -libdir=${exec_prefix}/lib - -Name: pthread stubs -Description: Stubs missing from libc for standard pthread functions -Version: 0.3 -Libs: diff --git a/system/base/libxcb/pspec.xml b/system/base/libxcb/pspec.xml deleted file mode 100644 index de4bda32..00000000 --- a/system/base/libxcb/pspec.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - - - libxcb - http://xcb.freedesktop.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - The X protocol C-language Binding (XCB) - The X protocol C-language Binding (XCB) is a replacement for Xlib featuring a small footprint, latency hiding, direct access to the protocol, improved threading support, and extensibility. - http://xcb.freedesktop.org/dist/libxcb-1.11.tar.bz2 - - libXau-devel - libXdmcp-devel - libxslt - xcb-proto - - - - - libxcb - - libXau - libXdmcp - glibc - - - /usr/lib - /usr/share/man - /usr/share/doc - - - - - libxcb-devel - system.devel - Development files for libxcb - - libxcb - - - /usr/include/xcb - /usr/lib/pkgconfig - /usr/lib32/pkgconfig - - - pthread-stubs.pc - - - - - libxcb-32bit - emul32 - 32-bit shared libraries for libxcb - emul32 - - libXau-32bit - libXdmcp-32bit - - - libxcb - libXau-32bit - libXdmcp-32bit - - - /usr/lib32 - - - - - - 2014-09-02 - 1.11 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 1.10 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-03-07 - 1.10 - Version bump. - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-10-08 - 1.9.1 - Rebuild. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-07-28 - 1.9.1 - Version bump. - Marcin Bojara - marcin@pisilinux.org - - - 2012-11-18 - 1.9 - First release - Erdinç Gültekin - admins@pisilinux.org - - - diff --git a/system/base/libxcb/translations.xml b/system/base/libxcb/translations.xml deleted file mode 100644 index d1bf19d2..00000000 --- a/system/base/libxcb/translations.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - libxcb - X protokolü için C dili bağlayıcısı (XCB) - - - - libxcb-devel - libxcb için geliştirme dosyaları - - - - libxcb-32bit - libxcb için 32-bit paylaşımlı kitaplıklar - - diff --git a/system/base/libxml2/pspec.xml b/system/base/libxml2/pspec.xml index 92f33d6c..2d4950d2 100644 --- a/system/base/libxml2/pspec.xml +++ b/system/base/libxml2/pspec.xml @@ -14,7 +14,7 @@ Libxml2 is the XML C parser and toolkit developed for the Gnome project (but usable outside of the Gnome platform). ftp://xmlsoft.org/libxml2/libxml2-2.9.1.tar.gz - python + python-devel xz-devel zlib-devel readline-devel @@ -75,6 +75,7 @@ xz-32bit zlib-32bit readline-32bit + glibc-32bit libxml2 diff --git a/system/base/lsb-release/pspec.xml b/system/base/lsb-release/pspec.xml index c91f6793..3e9a5072 100644 --- a/system/base/lsb-release/pspec.xml +++ b/system/base/lsb-release/pspec.xml @@ -13,6 +13,9 @@ LSB version query program lsb-release prints certain LSB (Linux Standard Base) and distribution information. mirrors://sourceforge/project/lsb/lsb_release/1.4/lsb-release-1.4.tar.gz + + util-linux + diff --git a/system/base/lzo/pspec.xml b/system/base/lzo/pspec.xml index c566e779..248caa24 100644 --- a/system/base/lzo/pspec.xml +++ b/system/base/lzo/pspec.xml @@ -12,7 +12,7 @@ library An extremely fast compression and decompression library lzo is a library with very high compression and decompression speeds and very small memory usage. Provides low compression ratios but very high speeds. - http://www.oberhumer.com/opensource/lzo/download/lzo-2.08.tar.gz + http://www.oberhumer.com/opensource/lzo/download/lzo-2.09.tar.gz @@ -39,12 +39,25 @@ emul32 32-bit shared libraries for lzo emul32 + + glibc-32bit + + + glibc-32bit + /usr/lib32 + + 2015-04-12 + 2.09 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-07-03 2.08 diff --git a/system/base/man-pages/pspec.xml b/system/base/man-pages/pspec.xml index 603838fc..1242b96a 100644 --- a/system/base/man-pages/pspec.xml +++ b/system/base/man-pages/pspec.xml @@ -12,8 +12,8 @@ data:doc A somewhat comprehensive collection of Linux man pages A large collection of man pages (documentation) from the Linux Documentation Project (LDP). - http://ftp.kernel.org/pub/linux/docs/man-pages/man-pages-3.70.tar.xz - http://www.kernel.org/pub/linux/docs/man-pages/man-pages-posix/man-pages-posix-2003-a.tar.xz + https://www.kernel.org/pub/linux/docs/man-pages/man-pages-3.81.tar.xz + http://www.kernel.org/pub/linux/docs/man-pages/man-pages-posix/man-pages-posix-2003-a.tar.xz @@ -32,6 +32,13 @@ + + 2015-03-09 + 3.81 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-07-13 3.70 diff --git a/system/base/mkinitramfs/actions.py b/system/base/mkinitramfs/actions.py deleted file mode 100644 index 7223540b..00000000 --- a/system/base/mkinitramfs/actions.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Licensed under the GNU General Public License, version 3. -# See the file http://www.gnu.org/licenses/gpl.txt - -from pisi.actionsapi import pisitools -from pisi.actionsapi import shelltools - - -WorkDir = "./" - -def setup(): - shelltools.move("README.mkinitramfs", "README") - -def install(): - pisitools.dodir("/etc/initramfs.d") - pisitools.dodoc("README") - diff --git a/system/base/mkinitramfs/comar/pakhandler.py b/system/base/mkinitramfs/comar/pakhandler.py deleted file mode 100644 index 39a202f9..00000000 --- a/system/base/mkinitramfs/comar/pakhandler.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -import piksemel -import subprocess - -def generate_initramfs(filepath): - patterns = ("lib/initramfs", "boot/kernel", "bin/busybox") - doc = piksemel.parse(filepath) - for item in doc.tags("File"): - path = item.getTagData("Path") - if path.startswith(patterns): - for kernel in os.listdir("/etc/kernel"): - subprocess.call(["/sbin/mkinitramfs", "--type", kernel]) - return - -def setupPackage(metapath, filepath): - generate_initramfs(filepath) - -def cleanupPackage(metapath, filepath): - pass - -def postCleanupPackage(metapath, filepath): - generate_initramfs(filepath) diff --git a/system/base/mkinitramfs/files/hotplug b/system/base/mkinitramfs/files/hotplug deleted file mode 100644 index 6168aec4..00000000 --- a/system/base/mkinitramfs/files/hotplug +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# Simple script to handle uevents -# - -if [ "$SUBSYSTEM/$ACTION" == "firmware/add" ]; then - [ -e "/sys$DEVPATH/loading" ] || exit 1 - DIR=/lib/firmware - [ -e "$DIR/$FIRMWARE" ] || exit 1 - echo 1 > /sys$DEVPATH/loading - cat "$DIR/$FIRMWARE" > /sys$DEVPATH/data - echo 0 > /sys$DEVPATH/loading - exit 0 -fi diff --git a/system/base/mkinitramfs/files/init b/system/base/mkinitramfs/files/init deleted file mode 100644 index 8345cde5..00000000 --- a/system/base/mkinitramfs/files/init +++ /dev/null @@ -1,593 +0,0 @@ -#!/bin/sh -# -# Simple init script that should handle both -# livecd/livedisk, thinclient and hdd boot -# - -PATH=/usr/sbin:/usr/bin:/sbin:/bin -INITRAMFSCONF="/etc/initramfs.conf" - -ROOT_LINKS="bin sbin lib boot usr opt" -ROOT_TREES="etc root home var run" -TMPFS_DIRS="dev mnt mnt/cdrom mnt/livecd mnt/thin tmp sys proc media" -LOOPBACKFILE="/boot/pisi.sqfs" - -NORESUME=0 -LIVE=0 -NFSROOT=0 -QUIET=0 -RAID_INCREMENTAL=1 -RAID=0 -LVM=0 -COPYTORAM=0 -SPLASH=0 -WIPEMEM=0 - -HOTPLUG="/sbin/hotplug" - -MNTDIR="" -FS_TYPE="" -INITRAMFS="" -ROOT_FLAGS="" -ROOT_DEVICE="" -ROOT_TARGET="" -RESUME_DEVICE="" -WIPEMEM_OPTS="-llv" - -########################### -# Miscellaneous functions # -########################### - -info() { - echo "<6>initramfs: $1" > /dev/kmsg -} - -log_output() { - $@ | echo "<6>`sed 's#^\(.*\)$#initramfs:\1#g'`" > /dev/kmsg -} - -fall2sh() { - # Kill any possible plymouth instances - test -x /bin/plymouth && /bin/plymouth quit &> /dev/null - kill -9 $(pidof plymouthd) &> /dev/null - - echo "--> $*" - echo "Reboot with initramfs=shell(noprobe) to further debug the issue." - - # Use a login shell for sourcing /etc/profile - /bin/sh -l -} - -run_dhcpc() { - udhcpc -C -i eth0 -s /etc/udhcpc.script -} - -################## -# Device probers # -################## - -probe_devices() { - # Set hotplug helper for firmware loading - echo $HOTPLUG > /proc/sys/kernel/hotplug - - if [ "x$1" = "x--with-kms" ]; then - probe_kms - test -x /bin/plymouth && /bin/plymouth show-splash - fi - - probe_pci_devices - probe_virtio_devices - probe_usb_devices - - # Unset hotplug helper - echo > /proc/sys/kernel/hotplug - - [ "${RAID}" -eq "1" ] && probe_raid - [ "${LVM}" -eq "1" ] && probe_lvm -} - -probe_kms() { - for device in /sys/bus/pci/devices/*/boot_vga; do - [ -f $device ] || continue - info "Loading KMS driver" - grep -q 1 $device && modprobe -bq `cat ${device%boot_vga}modalias` - done - if [ ! -c /dev/fb0 ]; then - echo "options uvesafb scroll=ywrap mtrr=0 nocrtc=1 mode_option=1024x768-32" > /etc/modprobe.d/uvesafb.conf - modprobe -bq uvesafb - fi -} - -probe_pci_devices() { - info "Probing PCI devices" - local MODULES="" - for module in /sys/bus/pci/devices/*/modalias; do - [ -f $module ] || continue - MODULES="$MODULES $(cat $module)" - done - modprobe -bqa $MODULES -} - -probe_usb_devices() { - info "Probing USB devices" - local MODULES="" - for module in /sys/bus/usb/devices/*/modalias; do - [ -f $module ] || continue - MODULES="$MODULES $(cat $module)" - done - modprobe -bqa $MODULES -} - -probe_raid() { - info "Probing RAID devices" - modprobe -bqa dm-mod raid0 raid1 raid10 raid456 - if [ -x /sbin/mdadm ] - then - /sbin/mdadm --examine --scan > /etc/mdadm.conf - /sbin/mdadm -As - fi -} - -probe_lvm() { - info "Probing LVM devices" - modprobe -qa dm-mod - if [ -x /sbin/lvm ] - then - /sbin/lvm vgscan --ignorelockingfailure &> /dev/null - /sbin/lvm vgchange -ay --sysinit --ignorelockingfailure &> /dev/null - /sbin/lvm vgmknodes --ignorelockingfailure &> /dev/null - fi -} -probe_virtio_devices() { - local MODULES="" - for module in /sys/bus/virtio/devices/*/modalias; do - [ -f $module ] || continue - MODULES="$MODULES $(cat $module)" - done - modprobe -bqa $MODULES -} - -################################# -# Filesystem specific functions # -################################# - -mount_rootfs() { - FS_TYPE=`disktype $ROOT_DEVICE | grep KERNELMODULE | awk '{print $2}'` - info "Mounting rootfs: $ROOT_DEVICE ($FS_TYPE)" - mount -r -t $FS_TYPE -n ${ROOT_FLAGS} ${ROOT_DEVICE} /newroot -} - -find_live_mount() { - if [ "$#" -gt "0" ] - then - for x in $* - do - # this is used for non Linux fs detection - FS_TYPE=`disktype $1 | grep KERNELMODULE | awk '{print $2}'` - if [ -n "$FS_TYPE" -a -f /lib/modules/*/$FS_TYPE.ko ] - then - modprobe $FS_TYPE 1> /dev/null 2>&1 - fi - - mount -r ${x} /newroot/mnt/cdrom > /dev/null 2>&1 - - if [ "$?" = "0" ] - then - # Check for cdroot image - if [ -e /newroot/mnt/cdrom/${LOOPBACKFILE} ] - then - ROOT_DEVICE="/newroot${x}" - if [ "$COPYTORAM" == "1" ] - then - info "Copying Live Media files to RAM" - mkdir /newroot/mnt/cdromtemp - cp -af /newroot/mnt/cdrom/* /newroot/mnt/cdromtemp/ - umount /newroot/mnt/cdrom - rmdir /newroot/mnt/cdrom - mv /newroot/mnt/cdromtemp /newroot/mnt/cdrom - fi - break - else - umount /newroot/mnt/cdrom - fi - fi - done - fi -} - -manage_tmpfs() { - mount -t tmpfs tmpfs /newroot - - for d in ${TMPFS_DIRS}; do - mkdir -p "/newroot/${d}" - done -} - -mount_nfs() { - FS_LOCATION='mnt/thin' - - # Change directory to /newroot - cd /newroot - - # FIXME: busybox mount does not load automatically - modprobe -q nfs - - # mount nfs - if [ -z "/etc/udhcpc.info" ] - then - fall2sh "/etc/udhcpc.info not found" - fi - - . /etc/udhcpc.info - - if [ -z "${ROOTPATH}" ] - then - fall2sh "NFS rootpath not found" - fi - - echo "Mounting NFS from $ROOTPATH" - mount -o tcp,nolock,ro $ROOTPATH /newroot/mnt/thin - - if [ "$?" != '0' ] - then - fall2sh "Could not nfs root" - fi - - # Create necessary links - for x in ${ROOT_LINKS}; do - ln -s "${FS_LOCATION}/${x}" "${x}" - done - - if [ -e "${FS_LOCATION}/lib32" ] - then - ln -s "${FS_LOCATION}/lib32" "lib32" - fi - - # We need this for x86_64 - ln -s "${FS_LOCATION}/lib" "lib64" - - chmod 1777 tmp - (cd /newroot/${FS_LOCATION}; cp -a ${ROOT_TREES} /newroot) - - # Needed for ltspfs mechanism - echo "$IP $HOSTNAME" >> /newroot/etc/hosts -} - -mount_cdroot() { - FS_LOCATION="mnt/livecd" - - # Change directory to /newroot - cd /newroot - - # These are not loaded automatically - modprobe -q squashfs - - # Loop type squashfs - mount -t squashfs -o loop,ro /newroot/mnt/cdrom/${LOOPBACKFILE} /newroot/mnt/livecd - - if [ "$?" != "0" ] - then - fall2sh "Could not mount root image" - fi - - # Create necessary links - for x in ${ROOT_LINKS}; do - ln -s "${FS_LOCATION}/${x}" "${x}" - done - - if [ -e "${FS_LOCATION}/lib32" ] - then - ln -s "${FS_LOCATION}/lib32" "lib32" - fi - - # We need this for x86_64 - ln -s "${FS_LOCATION}/lib" "lib64" - - chmod 1777 tmp - (cd /newroot/${FS_LOCATION}; cp -a ${ROOT_TREES} /newroot) - - # FIXME: the device list is taken from udev, we can't rely on sys entries since pluggable means different - # in kernel world. Suggestions that do not include this kind of regexp mania are welcome - - # for userspace applications - REAL_ROOT_TYPE=`echo "${ROOT_DEVICE}" | sed -e 's/^\/newroot\/dev\///' | grep -qE '^sr[0-9]*|^hd[a-z]|^pcd[0-9]|^xvd*' && echo "optical" || echo "harddisk"` - echo "${REAL_ROOT_TYPE}" > /newroot/run/pisilinux/livemedia - - # this is needed for yali - MNTDIR=`grep \/mnt\/cdrom\ /proc/mounts|sed 's/\/newroot//g'` - echo "$MNTDIR" >> /newroot/etc/fstab -} - -############################## -# Config and cmdline parsers # -############################## - -# FIXME: maybe we should just source the file instead of parsing -# also consider merging conf parser and cmdline parser -parse_config() { - while read inputline; - do - case "${inputline}" in - raid=*) - RAID=$(echo $inputline|cut -f2- -d=) - ;; - lvm=*) - LVM=$(echo $inputline|cut -f2- -d=) - ;; - thin=*) - NFSROOT=$(echo $inputline|cut -f2- -d=) - ;; - root=*) - ROOT_TARGET=$(echo $inputline|cut -f2- -d=) - ;; - rootflags=*) - ROOT_FLAGS=$(echo $inputline|cut -f2- -d=) - ;; - liveroot=*) - # Installation or livecd, enable RAID by default - # to be able to read existing RAID installations - LIVE=1 - RAID_INCREMENTAL=0 - LIVEROOT=$(echo $inputline|cut -f2- -d=) - ;; - resume=*) - RESUME_DEVICE="${inputline#resume=}" - ;; - noresume) - NORESUME=1 - ;; - copytoram) - COPYTORAM=1 - ;; - wipemem) - WIPEMEM=1 - ;; - wipememopts=*) - WIPEMEM=1 - WIPEMEM_OPTS=$(echo $inputline|cut -f2- -d=) - ;; - splash) - SPLASH=1 - ;; - init=*) - INIT="${inputline#INIT=}" - ;; - esac - done < $INITRAMFSCONF -} - -parse_cmdline() { - for x in `cat /proc/cmdline`; do - case "${x}" in - [0123456Ss]) - # Normalize 'S' to 's' - LEVEL=`echo ${x}|tr A-Z a-z` - ;; - mudur=*) - for m in `echo ${x}|cut -f2 -d=|sed 's/,/ /g'`; do - case "${m}" in - livecd) - LIVE=1 - ;; - livedisk) - LIVE=1 - ;; - raid) - RAID=1 - ;; - lvm) - LVM=1 - ;; - thin) - NFSROOT=1 - ;; - esac - done - ;; - initramfs=*) - INITRAMFS=`echo ${x}|cut -f2- -d=` - ;; - root=*) - ROOT_TARGET=`echo ${x}|cut -f2- -d=` - ;; - rootflags=*) - ROOT_FLAGS="-o ${x#rootflags=}" - ;; - liveroot=*) - LIVE=1 - LIVEROOT=$(echo ${x}|cut -f2- -d=) - ;; - resume=*) - RESUME_DEVICE="${x#resume=}" - ;; - noresume) - NORESUME=1 - ;; - init=*) - INIT="${x#init=}" - ;; - copytoram) - COPYTORAM=1 - ;; - wipemem) - WIPEMEM=1 - ;; - wipememopts=*) - WIPEMEM=1 - WIPEMEM_OPTS=$(echo $x|cut -f2- -d=) - ;; - splash) - SPLASH=1 - ;; - single) - LEVEL="s" - ;; - quiet) - QUIET=1 - ;; - blacklist=*) - modules=${x#blacklist=} - for module in ${modules//,/ }; do - echo "blacklist $module" >> /etc/modprobe.d/cmdline.conf - done - ;; - esac - done - - if [ -f /etc/modprobe.d/cmdline.conf ]; then - cp /etc/modprobe.d/cmdline.conf /dev/.modprobe.initramfs.conf - fi -} - - -#################### -# init starts here # -#################### - -info "Starting init on initramfs" - -# Mount needed filesystems -mount -n -t proc proc /proc -mount -n -t sysfs sysfs /sys -# Added to start udev properly -#mkdir -m 0755 /run -#mount -t tmpfs tmpfs /run - -# Prepare /dev (Needs kernel >= 2.6.32) -mount -t devtmpfs devtmpfs /dev -mkdir -m 0755 /dev/pts -mount -t devpts -o gid=5,mode=620 devpts /dev/pts - -# First parse config file, then cmdline to allow overwriting internal config -if [ -f "$INITRAMFSCONF" ] -then - #. $INITRAMFSCONF - parse_config -fi - -# Parse command line parameters -parse_cmdline - -# Minimize printk log -test "x$QUIET" = "x1" && echo "1" > /proc/sys/kernel/printk - -# Initialize plymouth daemon if found and splash is true -# Don't even launch plymouthd if we're in single-user mode -if [ "$LEVEL" != "s" -a "$SPLASH" = "1" -a -x /sbin/plymouthd ]; then - /sbin/plymouthd --attach-to-session -fi - -# Handle initramfs= parameter -if [ "${INITRAMFS}" == "shellnoprobe" ] -then - fall2sh "Starting up a shell without probing" -elif [ "${INITRAMFS}" == "shell" ] -then - probe_devices --with-kms - fall2sh "Starting up a shell" -fi - -if [ "${WIPEMEM}" = "1" ] -then - info "Wiping out memory, system will be shutdown after completion" - sdmem ${WIPEMEM_OPTS} - poweroff -f -fi - -# Probe devices -probe_devices --with-kms - -if [ -x /usr/sbin/resume -a -b "$RESUME_DEVICE" -a "x$NORESUME" != "x1" ] -then - if [ "x$SPLASH" == "x1" ] - then - SPLASHPARAM="-P splash=y" - else - SPLASHPARAM="-P splash=n" - fi - # FIXME: This will fail if resume= contains LABEL/UUID - info "Attempting to resume from hibernation" - /usr/sbin/resume $SPLASHPARAM $RESUME_DEVICE -fi - -echo 0x0100 > /proc/sys/kernel/real-root-dev - -if [ "${LIVE}" -eq "1" ] -then - ROOT_DEVICE="" - manage_tmpfs - - # modprobe filesystems that are not in kernel, for live disks - modprobe -qa nls_cp857 nls_utf8 vfat - - for i in `seq 50` - do - t=`findfs ${LIVEROOT} 2>/dev/null` - find_live_mount "$t" - - if [ "${ROOT_DEVICE}" != "" ] - then - break - else - probe_devices - usleep 200000 - fi - done - - if [ "${ROOT_DEVICE}" == "" ] - then - fall2sh "Could not find mount media" - fi - - mount_cdroot - -elif [ "${NFSROOT}" -eq "1" ] -then - run_dhcpc - manage_tmpfs - mount_nfs - - # set hostname for mudur - hostname $HOSTNAME - -else - # Wait until ROOT_DEVICE appears - for i in `seq 50` - do - # let findfs handle all conversion - ROOT_DEVICE=`findfs ${ROOT_TARGET} 2>/dev/null` - - if [ ! -b "${ROOT_DEVICE}" ] - then - probe_devices - usleep 200000 - else - break - fi - done - if [ ! -b "${ROOT_DEVICE}" ] - then - fall2sh "Could not find boot device" - else - mount_rootfs - fi -fi - -[ "${INIT}" == "" ] && INIT="/sbin/init"; - -# This stops /lib/udev/rules.d/65-md-incremental.rules from medling with mdraid sets. -[ "${RAID_INCREMENTAL}" -eq "0" ] && touch /dev/.in_sysinit - -# Move mounts instead of umount/mount -mount --move /dev /newroot/dev -mount --move /proc /newroot/proc -mount --move /sys /newroot/sys -# Added to start udev properly -#mount --move /run /newroot/run - - -# And we start -info "Switching to the real root" -test -x /bin/plymouth && /bin/plymouth update-root-fs --new-root-dir=/newroot -exec /bin/switch_root -c /dev/console /newroot ${INIT} ${LEVEL} - diff --git a/system/base/mkinitramfs/files/initramfs.conf b/system/base/mkinitramfs/files/initramfs.conf deleted file mode 100644 index 5c9df8f9..00000000 --- a/system/base/mkinitramfs/files/initramfs.conf +++ /dev/null @@ -1,29 +0,0 @@ -# -# this file is used to configure initramfs, lowercase is preferred -# - -# Set to 1 to enable probing raid modules and -# calling /sbin/mdadm if it exists -# raid=1 - -# Set to 1 to enable probing lvm modules and -# calling /sbin/lvm if it exists -# lvm=1 - -# Set to 1 to mount rootfs over NFS -# thin=0 - -# Set root device -# root=LABEL=MyPisiLinuxSystem - -# Set rootfs's mount flags -# rootflags=acl,xattr - -# Set resume partition -# resume=/dev/sdb5 - -# Set to 1 to disable resuming -# noresume=0 - -# Set Live media label -# liveroot=LABEL=PisiLiveImage diff --git a/system/base/mkinitramfs/files/mkinitramfs b/system/base/mkinitramfs/files/mkinitramfs deleted file mode 100644 index adc54211..00000000 --- a/system/base/mkinitramfs/files/mkinitramfs +++ /dev/null @@ -1,586 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# PisiLinux initramfs creator -# - -import os -import sys -import glob -import stat -import shutil -import tempfile -import subprocess - -from optparse import OptionParser - -config = {"rootDir" : "/", - "tmpDir" : "", - "debug" : False, - "dryrun" : False, - "destDir" : "/boot", - "blackList" : ["pktcdvd", "floppy"], - "kernelType" : "kernel", - "initramfsConf" : "/etc/initramfs.conf", - "kernelVersion" : "", -} - -def loadFile(_file): - try: - f = file(_file) - d = [a.lstrip().rstrip("\n") for a in f] - d = filter(lambda x: not (x.startswith("#") or x == ""), d) - f.close() - return d - except: - return [] - -def writeFile(_file, data): - f = open(_file, "w") - f.write(data) - f.close() - -def mkdir(_dir): - os.makedirs(_dir) - -def dohardlink(destination, source): - os.link(destination, source) - -def dosymlink(destination, source): - os.symlink(destination, source) - -def mknod(nodfile, nodtype, major, minor, perms=0666): - # c for character b for block devices, mknod style - if nodtype == "c": - devtype = stat.S_IFCHR - else: - devtype = stat.S_IFBLK - - os.mknod(nodfile, perms | devtype, os.makedev(major, minor)) - -def copy(source, destination): - # First let's check for the target directory and create if - # it doesn't exist - destdir = os.path.dirname(destination) - if not os.path.isdir(destdir): - mkdir(destdir) - - try: - shutil.copy2(source, destination) - except IOError: - printWarn("Could not find %s" % source) - -def touch(_file): - if os.path.exists(_file): - os.utime(_file, None) - else: - f = open(_file, 'w') - f.close() - -def capture(*cmd): - a = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - return a.communicate() - -def run(*cmd): - f = file("/dev/null", "w") - return subprocess.call(cmd, shell=True, stdout=f, stderr=f) - -def printFail(msg): - print "ERROR: %s" % msg - - tempdir.cleanup() - sys.exit(1) - -def printWarn(msg): - print "WARNING: %s" % msg - -def setKernelVersion(Version=""): - if Version == "": - kver = "".join(loadFile("/etc/kernel/%s" % config["kernelType"])) - else: - kver = Version - - # FIXME: we should do this an option and in a try/except - if kver == "": - print "could not find version of %s, autodetecting" % config["kernelType"] - kver = os.uname()[2] - - config["kernelVersion"] = kver - -class BaseSystem: - def __init__(self): - self.kver = config["kernelVersion"] - self.tmpDir = config["tmpDir"] - self.baseDirs = ["bin", "sbin", "etc/initramfs.d", "dev", "dev/loop", "lib", "newroot", "proc", "sys"] - - self.deviceNodes = {"null" : ["c", 1, 3], - "console" : ["c", 5, 1], - "tty" : ["c", 5, 0], - "tty0" : ["c", 4, 0], - "tty1" : ["c", 4, 1], - "ram0" : ["b", 1, 0], - "fb0" : ["c", 29, 0], - "urandom" : ["c", 1, 9], - "kmsg" : ["c", 1, 11], - } - - self.baseFileList = { - "/bin/busybox" : "/bin/", - "/bin/busybox.links" : "/bin/", - "/usr/bin/disktype" : "/bin/", - "/usr/bin/sdmem" : "/bin/", - "/lib/initramfs/init" : "/", - "/lib/initramfs/hotplug" : "/sbin/", - "/lib/initramfs/udhcpc.script" : "/etc/", - "/lib/initramfs/profile.rc" : "/etc/profile", - } - - self.modprobeBlacklistFileList = dict([(k,"/etc/modprobe.d") for k in glob.glob("/etc/modprobe.d/blacklist*conf")]) - - self.suspendFileList = { - "/etc/suspend.conf" : "/etc/", - "/usr/sbin/resume" : "/bin/", - } - - - def getNewRoot(self, dir): - cleandir = dir.lstrip("/") - return os.path.join(self.tmpDir, cleandir) - - def createBaseDirectories(self): - for i in self.baseDirs: - mkdir(self.getNewRoot(i)) - - mkdir(self.getNewRoot("/lib/modules/%s" % self.kver)) - mkdir(self.getNewRoot("/lib/firmware")) - mkdir(self.getNewRoot("/etc/modprobe.d")) - - def copyBasefiles(self): - for i in self.baseFileList: - copy(i, self.getNewRoot(self.baseFileList[i])) - - for i in ["/init", "/etc/udhcpc.script"]: - os.chmod(self.getNewRoot(i), 0755) - - for i in ["ext2", "ext3", "ext4", "reiserfs", "xfs"]: - touch(self.getNewRoot("/bin/fsck.%s" % i)) - - writeFile(self.getNewRoot("/etc/fstab"), "none none none defaults 0 0") - - def createConfig(self): - # FIXME: Parse config files and create a proper one by hand - configFileSource = config["initramfsConf"] - if os.path.exists(configFileSource): - copy(configFileSource, self.getNewRoot(configFileSource)) - - def createNodes(self): - for i in self.deviceNodes: - k = self.deviceNodes[i] - mknod(self.getNewRoot("dev/%s" % i), k[0], k[1], k[2]) - - for i in range(8): - mknod(self.getNewRoot("dev/loop/%i" % i), "b", 7, i) - dosymlink("loop/%i" % i, self.getNewRoot("dev/loop%i" % i)) - - def createBaseSymlinks(self): - for i in loadFile(self.getNewRoot("/bin/busybox.links")): - # FIXME: python dosym does not play nice with cpio, it creates 120MB initramfs - # dosymlink("busybox", self.getNewRoot("/bin/%s" % i.split("/")[-1])) - dohardlink(self.getNewRoot("/bin/busybox"), self.getNewRoot("/bin/%s" % i.split("/")[-1])) - - # FIXME: maybe we should symlink sbin to bin - dohardlink(self.getNewRoot("/bin/busybox"), self.getNewRoot("/sbin/modprobe")) - - def addRaid(self): - mdadmFile = "/sbin/mdadm.static" - if os.path.exists(mdadmFile): - copy(mdadmFile, self.getNewRoot(mdadmFile.replace(".static", ""))) - - def addLvm(self): - lvmFile = "/sbin/lvm.static" - if os.path.exists(lvmFile): - copy(lvmFile, self.getNewRoot(lvmFile.replace(".static", ""))) - - def addSuspend(self): - for i in self.suspendFileList: - copy(i, self.getNewRoot(self.suspendFileList[i])) - - def addModprobeBlacklists(self): - for i in self.modprobeBlacklistFileList: - copy(i, self.getNewRoot(self.modprobeBlacklistFileList[i])) - - def create(self): - self.createBaseDirectories() - self.copyBasefiles() - self.createNodes() - self.createBaseSymlinks() - self.createConfig() - self.addRaid() - self.addLvm() - self.addSuspend() - self.addModprobeBlacklists() - -class KernelModule: - def __init__(self): - self.modulesList = [] - self.allModules = [] - self.blackList = config["blackList"] - self.kernelVersion = config["kernelVersion"] - - self.targetDir = config["tmpDir"] - self.rootDir = config["rootDir"] - self.modulesDir = os.path.join(self.rootDir, "lib/modules/%s" % self.kernelVersion) - self.firmwareDir = os.path.join(self.rootDir, "lib/firmware") - - self.addNetworkModule = config["networkModule"] - self.addNetworkModuleBasic = config["networkModuleBasic"] - - self.addDRMModules = not config["excludeDRM"] - self.findAllModules() - - self.scsiDirs = ["kernel/drivers/scsi"] - self.scsiModules = ["mptfc", "mptsas", "mptscsih", "mptspi", "zfcp"] - - self.mdDirs = ["kernel/drivers/md"] - self.ataDirs = ["kernel/drivers/ata"] - self.mmcDirs = ["kernel/drivers/mmc"] - self.ideDirs = ["kernel/drivers/ide"] - self.blockDirs = ["kernel/drivers/block"] - - self.firewireModules = ["firewire-ohci", "firewire-sbp2", "firewire-net", "firewire-core"] - self.i2oModules = ["i2o_block"] - self.usbModules = ["usb-storage", "sd_mod", "usbcore", "ehci-hcd", "ohci-hcd", "uhci-hcd"] - - self.filesystemModules = ["ext2", "ext3", "ext4", "reiser4", "jfs", "reiserfs", "xfs", "vfat", "fat", "ntfs", "unionfs", "cramfs", "nfs", "nls_utf8", "nls_iso8859_9", "nls_cp857", "nls_iso8859-1", "nls_ascii", "nls_cp850", "squashfs"] - - self.networkBaseModules = ["af_packet", "mii", "8390", "via-rhine", "8139too", "ne2k-pci", "e100", "sky2", "tg3", "skge"] - self.networkDirs = ["kernel/drivers/net"] - - self.drmDir = "kernel/drivers/gpu/drm" - - self.virtioModules = ["virtio", "virtio_balloon", "virtio_blk", "virtio_net", "virtio_pci"] - self.xenModules = ["xenblk", "xenfb", "gntdev", "xennet", "xenkbd"] - - - def tidyModuleList(self): - ml = list(set(self.modulesList)) - ml.sort() - self.modulesList = ml - - def depmod(self, targetdir): - cmd = "/sbin/depmod -a -b %s -F %s/System.map %s" - capture(cmd % (targetdir, self.modulesDir, self.kernelVersion)) - - def installModules(self): - for i in self.modulesList: - if os.path.basename(i).replace(".ko", "") not in self.blackList: - copy(i, os.path.join(self.targetDir, self.modulesDir.replace(self.rootDir, "/").lstrip("/"))) - - def findAllModules(self): - foundModules = [] - - if not os.path.exists(self.modulesDir): - printFail("There is no %s, please check your kernel version" % self.modulesDir) - - for root, directory, files in os.walk(self.modulesDir): - for name in files: - if name.endswith(".ko"): - foundModules.append(os.path.join(root, name)) - - self.allModules = foundModules - - def findModuleDeps(self): - deps = [] - depdata = loadFile(os.path.join(self.modulesDir, "modules.dep")) - - for line in depdata: - for i in self.modulesList: - if "%s:" % i.replace("%s/" % self.modulesDir, "") in line: - deps.extend(line.split(":")[1].strip().split(" ")) - - # return [os.path.join(self.modulesDir, x) for x in deps if not x == ""] - self.modulesList.extend([os.path.join(self.modulesDir, x) for x in deps if not x == ""]) - - def appendFirmwares(self): - ret = capture("/sbin/modinfo -F firmware %s/*.ko" % os.path.join(self.targetDir, self.modulesDir.replace(self.rootDir, "/").lstrip("/")))[0] - fwlist = ret.strip("\n").split("\n") - - targetbase = os.path.join(self.targetDir, "lib/firmware") - - for i in fwlist: - src = os.path.join(self.firmwareDir, i) - target = os.path.join(targetbase, os.path.dirname(i)) - - if os.path.exists(src): - if not os.path.exists(target): - mkdir(target) - - copy(src, target) - - else: - printWarn("Could not find firmware %s" % src) - pass - - def updateModuleDependencies(self, force=False): - # this is here to prevent a race condition with pakhandler, when installing a system from scratch - if force or not os.path.exists("%s/modules.dep" % self.modulesDir): - printWarn("Could not find module dependencies in %s, running depmod for system" % self.modulesDir) - self.depmod(self.rootDir) - - def addDir(self, mdir): - newModules = [] - dirtoadd = os.path.join(self.modulesDir, mdir) - - for line in self.allModules: - if line.startswith(dirtoadd): - newModules.append(line) - - self.modulesList.extend(newModules) - - def addModule(self, module): - if module.endswith(".ko"): - module = module[:-3] - - for line in self.allModules: - # FIXME: I still don't trust the _ versus - case, try to be sure of it in kernel - if line.replace("-", "_").endswith("/%s.ko" % module.replace("-", "_")): - self.modulesList.append(line) - return - - def addScsi(self): - for i in self.scsiDirs: - self.addDir(i) - - for i in self.scsiModules: - self.addModule(i) - - def addAta(self): - for i in self.ataDirs: - self.addDir(i) - - def addMmc(self): - for i in self.mmcDirs: - self.addDir(i) - - def addBlock(self): - for i in self.blockDirs: - self.addDir(i) - - def addIde(self): - for i in self.ideDirs: - self.addDir(i) - - def addNetwork(self): - if self.addNetworkModule: - for i in self.networkDirs: - self.addDir(i) - - if self.addNetworkModuleBasic: - for i in self.networkBaseModules: - self.addModule(i) - - def addDRM(self): - if self.addDRMModules: - for i in glob.glob("%s/*/*.ko" % os.path.join(self.modulesDir, self.drmDir)): - # Check for drm_crtc_init symbol - if not os.system("grep -qw drm_crtc_init %s" % i): - self.addModule(i.partition(self.modulesDir+'/')[-1]) - - # Add uvesafb as a fallback - if os.path.exists("/sbin/v86d"): - copy("/sbin/v86d", os.path.join(self.targetDir, "sbin/")) - self.addModule("kernel/drivers/video/uvesafb.ko") - - def addMd(self): - for i in self.mdDirs: - self.addDir(i) - - def addFirewire(self): - for i in self.firewireModules: - self.addModule(i) - - def addI2o(self): - for i in self.i2oModules: - self.addModule(i) - - def addUsb(self): - for i in self.usbModules: - self.addModule(i) - - def addFilesystem(self): - for i in self.filesystemModules: - self.addModule(i) - - def addVirtio(self): - for i in self.virtioModules: - self.addModule(i) - - def addXen(self): - for i in self.xenModules: - self.addModule(i) - - def addGeneric(self): - self.addScsi() - self.addAta() - self.addMmc() - self.addBlock() - self.addIde() - self.addNetwork() - self.addMd() - self.addFirewire() - self.addI2o() - self.addUsb() - self.addFilesystem() - self.addVirtio() - self.addDRM() - - def autoGenerate(self): - self.updateModuleDependencies() - self.addGeneric() - self.findModuleDeps() - self.tidyModuleList() - self.installModules() - self.appendFirmwares() - self.depmod(self.targetDir) - -class Plymouth: - def __init__(self): - self.fileList = "/lib/initramfs/plymouth.list" - self.targetDir = config["tmpDir"] - self.theme = "pisilinux" - self.themeDir = "/usr/share/plymouth/themes" - - def install_current_theme(self): - self.theme = os.popen("plymouth-set-default-theme").read().strip() - if os.path.exists("%s/%s" % (self.themeDir, self.theme)): - for themeFile in glob.glob("%s/%s/*" % (self.themeDir, self.theme)): - copy(themeFile, os.path.join(self.targetDir, themeFile[1:])) - - def install(self): - """Will install plymouth related base stuff.""" - if os.path.exists(self.fileList): - with open(self.fileList, "r") as files: - for _file in files: - filename = _file.strip() - copy(filename.strip(), os.path.join(self.targetDir, filename[1:])) - - self.install_current_theme() - -class Initramfs: - def __init__(self): - self.destDir = config["destDir"] - self.sourceDir = config["tmpDir"] - self.initramfs = "initramfs-%s" % config["kernelVersion"] - - def create(self): - if not os.path.exists(self.destDir): - mkdir(self.destDir) - - cmd = "(cd %s && find . | cpio --quiet --dereference -o -H newc | gzip -6 > %s)" - capture(cmd % (self.sourceDir, os.path.join(self.destDir, self.initramfs))) - -class Tempdir: - def __init__(self): - self.tmpDir = "" - self.keepTmp = False - - def create(self): - self.tmpDir = tempfile.mkdtemp(prefix="mkinitramfs-") - - def cleanup(self): - if self.keepTmp: - printWarn("Keeping temporary directory %s" % self.tmpDir) - else: - shutil.rmtree(self.tmpDir) - - -if __name__ == "__main__": - tempdir = Tempdir() - tempdir.create() - config["tmpDir"] = tempdir.tmpDir - - parser = OptionParser() - parser.add_option("-k", "--kernel", dest="kernelVersion", type="string", - help="kernel version to create initramfs for") - - parser.add_option("-t", "--type", dest="type", type="string", default="kernel", - help="kernel type to create initramfs for") - - parser.add_option("-o", "--output", dest="destDir", type="string", metavar="DIR", default="/boot", - help="create initramfs in DIR") - - parser.add_option("-c", "--configfile", dest="configFile", type="string", metavar="FILE", default="/etc/initramfs.conf", - help="use FILE for initramfs config file, default is /etc/initramfs.conf") - - parser.add_option("-r", "--rootdir", dest="rootDir", type="string", metavar="DIR", default="/", - help="use DIR as basedir for kernel modules") - - parser.add_option("-f", "--filename", dest="filename", type="string", metavar="FILE", - help="use FILE for initramfs file name") - - parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False, - help="print extra debug info") - - parser.add_option("--blacklist", dest="blackList", type="string", metavar="FILES", default="", - help="define modules to be blacklisted, seperated by comma. Example: e100,rtl819,ahci") - - parser.add_option("--network", action="store_true", dest="networkModule", default=False, - help="add network modules") - - parser.add_option("--nodrm", action="store_true", dest="excludeDRM", default=False, - help="Don't include KMS capable DRM modules") - - parser.add_option("--network-generic", action="store_true", dest="networkModuleBasic", default=False, - help="add only generic network modules") - - parser.add_option("--keeptmp", action="store_true", dest="keepTmp", default=False, - help="whether to keep temporary dir after operation") - - parser.add_option("-n", "--dry-run", action="store_true", dest="dryrun", default=False, - help="do not perform any action, just show what will be done") - - parser.add_option("--list-modules", action="store_true", dest="listModules", default=False, - help="do not perform any action, just show what will be done") - - parser.add_option("--list-base", action="store_true", dest="listBase", default=False, - help="do not perform any action, just show what will be done") - - (opts, args) = parser.parse_args() - - config["initramfsConf"] = opts.configFile - - config["destDir"] = os.path.abspath(opts.destDir) - config["rootDir"] = os.path.abspath(opts.rootDir) - - config["debug"] = opts.debug - config["dryrun"] = opts.dryrun - tempdir.keepTmp = opts.keepTmp - - config["kernelType"] = opts.type - config["networkModule"] = opts.networkModule - config["networkModuleBasic"] = opts.networkModuleBasic - config["excludeDRM"] = opts.excludeDRM - - if "," in opts.blackList: - config["blackList"].extend(opts.blackList.split(",")) - - if opts.kernelVersion: - config["kernelVersion"] = opts.kernelVersion - else: - setKernelVersion() - - basesystem = BaseSystem() - basesystem.create() - - # Check for plymouth and install if found - plymouth = Plymouth() - plymouth.install() - - kernelmodule = KernelModule() - kernelmodule.autoGenerate() - - initramfs = Initramfs() - initramfs.create() - - tempdir.cleanup() - diff --git a/system/base/mkinitramfs/files/profile.rc b/system/base/mkinitramfs/files/profile.rc deleted file mode 100644 index 64884402..00000000 --- a/system/base/mkinitramfs/files/profile.rc +++ /dev/null @@ -1,6 +0,0 @@ -# Simple profile file for sh - -alias ls='ls --color=auto' -alias ll='ls --color -l' - -export PS1="\[\033[1;31m\]initramfs \[\033[1;34m\]\W # \[\033[00m\]" diff --git a/system/base/mkinitramfs/files/udhcpc.script b/system/base/mkinitramfs/files/udhcpc.script deleted file mode 100644 index 2fcc4d0b..00000000 --- a/system/base/mkinitramfs/files/udhcpc.script +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/sh - -PATH=/bin:/usr/bin:/sbin:/usr/sbin - -RESOLV_CONF="/etc/resolv.conf" - -UDHCPC_INFO="/etc/udhcpc.info" - -update_interface() -{ - [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" - [ -n "$subnet" ] && NETMASK="netmask $subnet" - /bin/ifconfig $interface $ip $BROADCAST $NETMASK -} - -update_routes() -{ - if [ -n "$router" ] - then - echo "deleting routes" - while /bin/route del default gw 0.0.0.0 dev $interface > /dev/null 2>&1 - do : - done - - for i in $router - do - /bin/route add default gw $i dev $interface - done - fi -} - -update_dns() -{ - echo -n > $RESOLV_CONF - [ -n "$domain" ] && echo domain $domain >> $RESOLV_CONF - for i in $dns - do - echo adding dns $i - echo nameserver $i >> $RESOLV_CONF - done -} - -deconfig() -{ - /bin/ifconfig $interface 0.0.0.0 -} - -update_udhcpc_info() -{ - cat > $UDHCPC_INFO < - - - - mkinitramfs - http://www.busybox.net - - PisiLinux Community - admins@pisilinux.org - - GPLv2 - app:console - A tool to create the initramfs image - mkinitramfs contains a tool to create the initramfs image with busybox. - http://source.pisilinux.org/1.0/README.mkinitramfs - - - - mkinitramfs - - disktype - busybox - - - /etc - /sbin - /lib/initramfs - /usr/share/doc/mkinitramfs - - - mkinitramfs - init - udhcpc.script - hotplug - profile.rc - initramfs.conf - - - System.PackageHandler - - - - - - 2014-05-11 - 1.0.7 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-10 - 1.0.7 - Fix probing LVM devices - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-10 - 1.0.7 - Disable mount tmpfs on /run - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-05 - 1.0.7 - Add missing method to pakhandler.py - Marcin Bojara - marcin@pisilinux.org - - - 2013-09-03 - 1.0.7 - Fix default plymouth theme name. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-06-17 - 1.0.7 - Fix resume path. - Marcin Bojara - marcin@pisilinux.org - - - 2013-02-13 - 1.0.7 - Change loopbackimage address and name. - Serdar Soytetir - kaptan@pisilinux.org - - - 2013-01-13 - 1.0.7 - First release - Serdar Soytetir - kaptan@pisilinux.org - - - diff --git a/system/base/mkinitramfs/translations.xml b/system/base/mkinitramfs/translations.xml deleted file mode 100644 index 23a58871..00000000 --- a/system/base/mkinitramfs/translations.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - mkinitramfs - initramfs image dosyası yaratmak için araç - initramfs image dosyası yaratmak için araç - Un outil pour créer les images initramfs - - diff --git a/system/base/mudur/actions.py b/system/base/mudur/actions.py new file mode 100644 index 00000000..d957743c --- /dev/null +++ b/system/base/mudur/actions.py @@ -0,0 +1,20 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 3. +# See the file http://www.gnu.org/licenses/gpl.txt + +from pisi.actionsapi import shelltools +from pisi.actionsapi import pisitools +from pisi.actionsapi import get + +def install(): + pisitools.dosed("bin/adduser.py", "plugdev", "removable") + shelltools.system("./setup.py install %s" % get.installDIR()) + + # in new tarball remove + shelltools.chmod(get.installDIR() + "/sbin/mudur_cgroupfs.py" , 0755) + + pisitools.dodir("/etc/mudur/services/enabled") + pisitools.dodir("/etc/mudur/services/disabled") + pisitools.dodir("/etc/mudur/services/conditional") diff --git a/system/base/mudur/comar/disk.py b/system/base/mudur/comar/disk.py new file mode 100644 index 00000000..fe9687bb --- /dev/null +++ b/system/base/mudur/comar/disk.py @@ -0,0 +1,492 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import glob +import os +import sys +import subprocess + +FSTAB = '/etc/fstab' + +""" +Quick list is used for improving efficiency of the script. +Stores device names and uuids pairs for partitions so prevents multiple +communication with subprocesses. +""" +quickList = {} + +FAIL_FSTAB = { + "en": "Unable to read '%s'.", + "tr": "'%s' okunamadı.", + "fr": "Impossible de lire '%s' .", + "es": "No posible leer '%s'.", + "de": "'%s' konnte nicht gelesen werden.", + "nl": "Kan '%s' niet lezen.", +} + +FAIL_PATH = { + "en": "'%s' is not a valid mount point.", + "tr": "'%s' geçerli bir bağlama noktası değil.", + "fr": "'%s' n'est pas un point de montage valide.", + "es": "'%s' no es un punto de montaje válido.", + "de": "'%s' ist kein gültiger Mount-Punkt.", + "nl": "'%s' is geen geldig aankoppelpunt.", +} + +FAIL_PATH_ALREADY_EXIST = { + "en": "'%s' is already being used by an entry.", + "tr": "'%s' zaten bir kayıt tarafından kullanılıyor.", + "fr": "'%s' est déjà utilisé par une entrée.", + "es": "Ya '%s' siendo utilizado por una entrada.", + "de": "'%s' wird bereits durch einen Eintrag verwendet.", + "nl": "'%s' bruges allerede af en post.", +} + +FAIL_ENTRY = { + "en": "Device '%s' not found in entry list.", + "tr": "'%s' aygıtı listede bulunamadı.", + "fr": "Le matériel '%s' n'a pas été trouvé dans la liste.", + "es": "Dispositivo '%s' no encontrado en lista de entrada.", + "de": "Gerät '%s' ist nicht in der Liste eingetragen.", + "nl": "Apparaat '%s' is niet in invoerlijst gevonden.", +} + +FAIL_ROOT = { + "en": "'%s' is mounted to root directory, operation cancelled.", + "tr": "'%s' diski kök dizine bağlı, işlem iptal edildi.", + "fr": "'%s' est monté sur le répertoire racine, opération annulée.", + "es": "'%s' está montado com root, operación cancelada.", + "de": "'%s' ist als Root gemounted, Vorgang abgebrochen.", + "nl": "'%s' is in root-map aangekoppeld, bewerking geannuleerd.", +} + +FAIL_MOUNTED = { + "en": "'%s' is mounted to another directory, operation cancelled.", + "tr": "'%s' başka bir dizine bağlı, işlem iptal edildi.", + "fr": "'%s' est monté sur un autre répertoire, opération annulée.", + "es": "'%s' está montado en otro directorio, operación cancelada.", + "de": "'%s' ist schon auf einem anderen Mount-Punkt gemounted, Vorgang abgebrochen.", + "nl": "'%s' is in een andere map aangekoppeld, bewerking geannuleerd.", +} + +FAIL_OPERATION = { + "en": "Operation failed:\n\n %s", + "tr": "İşlem başarısız:\n\n %s", + "fr": "L'opération a échoué : \n\n %s", + "es": "Operación fallada:\n\n %s", + "de": "Vorgang fehlerhaft:\n\n %s", + "nl": "Mislukte bewerking:\n\n %s", +} + +class DMException(Exception): + pass + +def parseFstab(fstab): + if not os.access(fstab, os.R_OK): + raise DMException, _(FAIL_FSTAB) % fstab + entries = [] + for line in open(fstab): + line = line.strip() + # Check len(line) for empty lines. + if line.startswith('#') or len(line) == 0: + continue + line = line.replace('\t', ' ').split() + # Replace UUID value with device name after reading it from fstab + if line[0].startswith('UUID='): + line[0] = getPartitionNameByUUID(line[0]) + entries.append(line) + elif line[0].startswith('LABEL='): + line[0] = getDeviceByLabel(line[0].replace('LABEL=', '')) + entries.append(line) + elif line[0].startswith('/dev/'): + entries.append(line) + return entries + +def createPath(device, path): + real_path = path + if not os.path.exists(path) and os.path.exists(os.path.dirname(path)): + # Mount point does not exist, but parent directory does. + path = os.path.dirname(path) + if not os.path.ismount(path) and not os.path.islink(path) and os.path.isdir(path): + os.mkdir(real_path, 0755) + return True + else: + if os.path.ismount(path): + # Path is already mounted, allow user to use that mount point if it's already mounted + for _device, _path in getMounted(): + if device == _device and _path == path: + return True + else: + if not os.path.islink(path) and os.path.isdir(path) and os.listdir(path) == []: + return True + return False + +def getMounted(): + parts = [] + for line in open('/proc/mounts'): + if line.startswith('/dev/'): + device, path, other = line.split(" ", 2) + parts.append((device, path, )) + return parts + +def getFSType(device): + if device.startswith('UUID='): + device = getPartitionNameByUUID(device) + cmd = "/sbin/blkid -s TYPE -o value %s" % device + proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) + return proc.communicate()[0].strip() + +def getUUID(part): + """ + Finds UUID for the given partition. + """ + global quickList + if len(quickList) == 0: + fillQuickList() + return quickList[part] + +def getPartitionNameByUUID(part): + """ + Finds name of the partition for the given UUId. + """ + global quickList + part = part.replace('UUID=', '') + if len(quickList) == 0: + fillQuickList() + for devName, uuid in quickList.items(): + if uuid == part: + return devName + return '' + +def fillQuickList(): + """ + Fills the quick list. + """ + global quickList + cmd = "/sbin/blkid" + proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) + for line in proc.stdout: + line = line.replace(':', '').strip() + propList = line.split() + devName = label = uuid = fsType = '' + devName = propList[0] + for property in propList: + if property.startswith('UUID'): + uuid = property.replace('UUID=', '').replace('"', '') + quickList[devName] = uuid + +def runCommand(cmd): + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + err = proc.communicate()[1].strip() + if len(err): + fail(_(FAIL_OPERATION) % err) + +# Disk.Manager methods + +def isMounted(device): + """ + Searches the given partition in mounted devices. If partition is + mounted, returns mount point else returns none. + """ + for _device, _path in getMounted(): + if device == _device: + return _path + return '' + +def getDevices(): + from pardus.diskutils import EDD + return EDD().blockDevices() + +def getDeviceByLabel(label): + root = '/dev/disk/by-label' + path = os.path.join(root, label) + if os.access(path, os.R_OK): + return os.path.realpath(os.path.join(root, os.readlink(path))) + else: + return '' + +def getDeviceParts(device): + if not os.path.exists(device): + return [] + parts = [] + for part in glob.glob("%s*" % device): + if not part == device and not getFSType(part) == "": + parts.append(part) + return parts + +def getLabel(device): + """ + Finds label for the given partition. + """ + cmd = "/sbin/blkid -s LABEL -o value %s" % device + proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) + return proc.communicate()[0].strip() + +def getPath(device): + """ + Gets partition name and determine a path for that partition. + """ + # If there is a entry record for this partition in fstab + # use path in there. + if device in listEntries(): + path_, fsType_, options_ = getEntry(device) + return path_ + path = '/media/' + label = getLabel(device) + # There may be partitions without a label + if not label: + if not os.path.exists(path+'disk'): + path = path+'disk' + elif not os.path.ismount(path+'disk'): + path = path+'disk' + else: + for i in range(1, len(getMounted())): + if not os.path.exists(path+'disk-'+str(i)): + path = path+'disk-'+str(i) + break + elif not os.path.ismount(path+'disk-'+str(i)): + path = path+'disk-'+str(i) + break + # Labels may be same + else: + if not os.path.exists(path+label): + path = path+label + elif not os.path.ismount(path+label): + path = path+label + else: + for i in range(1, len(getMounted())): + if not os.path.exists(path+label+'-'+str(i)): + path = path+label+'-'+str(i) + break + elif not os.path.ismount(path+label+'-'+str(i)): + path = path+label+'-'+str(i) + break + return path + +def mount(device, path): + if not path: + path = getPath(device) + if not createPath(device, path): + # Can't create new path + fail(_(FAIL_PATH) % path) + elif device in [x[0] for x in getMounted()]: + # Device is mounted + fail(_(FAIL_MOUNTED) % device) + runCommand(['/bin/mount', device, path]) + +def umount(device): + for dev, path in getMounted(): + if dev == device and path == "/": + fail(_(FAIL_ROOT) % device) + runCommand(['/bin/umount', device]) + +def listEntries(): + try: + devices = [x[0] for x in parseFstab(FSTAB)] + return devices + except DMException: + return [] + +def listPaths(): + """ + Return paths of the entries in fstab. + """ + try: + paths = [x[1] for x in parseFstab(FSTAB)] + return paths + except DMException: + return [] + +def isLabelRecord(device): + for line in open(FSTAB): + line = line.strip().replace('\t', ' ').split() + if line: + if line[0] == 'LABEL=' + getLabel(device): + return True + +def addEntry(device, path, fsType, options): + path_own = False + if device in listEntries(): + old_path, old_fsType, old_options = getEntry(device) + # Do not change root + if old_path == "/" and not old_path == path: + fail(_(FAIL_ROOT) % device) + # Who has that mount point? me? + if old_path == path: + path_own = True + else: + # If the path value already exist in fstab, cut the operation + if path in listPaths(): + fail(_(FAIL_PATH_ALREADY_EXIST) % path) + old_path = None + if not createPath(device, path): + # Can't create new path + fail(_(FAIL_PATH) % path) + #elif device in [x[0] for x in getMounted()]: + # Device is mounted + #fail(_(FAIL_MOUNTED) % device) + partText = '' + # Before removing the entry check if it is a label record or uuid record + # Remove previous one to prevent duplicates + if old_path: + if isLabelRecord(device): + partText = 'LABEL='+getLabel(device) + else: + partText = 'UUID='+getUUID(device) + else: + partText = 'UUID='+getUUID(device) + # Add new entry + _options = [] + for key, value in options.iteritems(): + if value: + _options.append('%s=%s' % (key, value)) + else: + _options.append(key) + if not file(FSTAB).read()[-1] == '\n': + file(FSTAB, 'a').write('\n') + _options = ','.join(_options) + + addit = True + # If the partition is not already mounted the given path and, + # if the partition is not mounted anywhere, try to create a path + # and mount there. + if not path_own: + if not createPath(device, path): + addit = False + # Can't create new path + fail(_(FAIL_PATH) % path) + if not device in [x[0] for x in getMounted()]: + # Mount device + try: + mount(device, path) + except: + addit = False + raise + if addit: + # try to remove old entry before + if old_path: + removeEntry(device, silent=True) + if _options: + file(FSTAB, 'a').write('%s %s %s %s 0 0\n' % (partText, path, fsType, _options)) + else: + file(FSTAB, 'a').write('%s %s %s defaults 0 0\n' % (partText, path, fsType)) + # Notify clients + notify("Disk.Manager", "changed", ()) + +def getEntry(device): + entries = parseFstab(FSTAB) + for entry in entries: + if entry[0] == device: + _path, _fsType, _options, _dump, _pass = entry[1:] + options = {} + for part in _options.split(','): + if "=" in part: + key, value = part.split('=', 1) + options[key] = value + else: + options[part] = "" + return _path, _fsType, options + fail(_(FAIL_ENTRY) % device) + +def removeEntry(device, silent=False): + if isMounted(device) == '/': + fail(_(FAIL_ROOT) % device) + if device not in listEntries(): + return + newlines = [] + for line in open(FSTAB): + line = line.strip() + if not len(line) == 0 and not (line.replace('\t', ' ').split()[0] == 'UUID='+getUUID(device) or line.replace('\t', ' ').split()[0] == 'LABEL='+getLabel(device) or line.replace('\t', ' ').split()[0] == device): + newlines.append(line) + file(FSTAB, 'w').write('\n'.join(newlines)) + if not file(FSTAB).read()[-1] == '\n': + file(FSTAB, 'a').write('\n') + # Notify clients + if not silent: + notify("Disk.Manager", "changed", ()) + + +import errno +from time import sleep +from fcntl import ioctl + +# Path to sync executable +PATH_SYNC = '/bin/sync' + +# Emulate required asm-generic/ioctl.h macros +_IOC_NRBITS = 8 +_IOC_TYPEBITS = 8 +_IOC_SIZEBITS = 14 +_IOC_DIRBITS = 2 + +_IOC_NRMASK = ((1 << _IOC_NRBITS) - 1) +_IOC_TYPEMASK = ((1 << _IOC_TYPEBITS) - 1) +_IOC_SIZEMASK = ((1 << _IOC_SIZEBITS) - 1) +_IOC_DIRMASK = ((1 << _IOC_DIRBITS) - 1) + +_IOC_NRSHIFT = 0 +_IOC_TYPESHIFT = (_IOC_NRSHIFT + _IOC_NRBITS) +_IOC_SIZESHIFT = (_IOC_TYPESHIFT + _IOC_TYPEBITS) +_IOC_DIRSHIFT = (_IOC_SIZESHIFT + _IOC_SIZEBITS) + +# Direction bits. +_IOC_NONE = 0 +_IOC_WRITE = 1 +_IOC_READ = 2 + +def _IOC(dir,type,nr,size): + return (((dir) << _IOC_DIRSHIFT) | \ + (type << _IOC_TYPESHIFT) | \ + ((nr) << _IOC_NRSHIFT) | \ + ((size) << _IOC_SIZESHIFT)) + +def _IO(type, nr): + """Note: type is specified in hex and nr in decimal.""" + return _IOC(_IOC_NONE,(type),(nr),0) + +def BLKRRPART(): + """Returns ioctl number for re-reading partition table.""" + # Kernels >2.6.17 have BLKRRPART defined in include/linux/fs.h. + return _IO(0x12, 95) +# ------------------------------------------- + +def refreshPartitionTable(device): + """Re-Read partition table on device.""" + + try: + fd = os.open(device, os.O_RDONLY) + except EnvironmentError, (error, strerror): + print 'Could not open device %s. Reason: %s.'%(device, strerror) + sys.exit(-1) + + # Sync and wait for Sync to complete + os.system(PATH_SYNC) + sleep(2) + + # Call required ioctl to re-read partition table + try: + ioctl(fd, BLKRRPART()) + except EnvironmentError, (error, message): + # Attempt ioctl call twice in case an older kernel (1.2.x) is being used + os.system(PATH_SYNC) + sleep(2) + + try: + ioctl(fd, BLKRRPART()) + except EnvironmentError, (error, strerror): + print 'IOCTL Error: %s for device %s.'%(strerror, device) + sys.exit(-1) + + print 'Successfully re-read partition table on device %s.'%(device) + # Sync file buffers + os.fsync(fd) + os.close(fd) + + # Final sync + print "Syncing %s ... " % (device), + os.system(PATH_SYNC) + sleep(4) # for sync() + print "Done." + + + diff --git a/system/base/mudur/comar/netfs.py b/system/base/mudur/comar/netfs.py new file mode 100644 index 00000000..291173ca --- /dev/null +++ b/system/base/mudur/comar/netfs.py @@ -0,0 +1,48 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from comar.service import * +import time + +from pardus.fstabutils import Fstab + +serviceType = "local" +serviceDefault = "off" +serviceDesc = _({"en": "Remote Filesystem Mounter", + "tr": "Uzak Dosyasistemi Bağlayıcı"}) + +DATAFILE = "/var/run/netfs.status" + +MSG_NM_NOT_RUNNING = _({"en": "NetworkManager service is not running", + "tr": "NetworkManager hizmeti çalışmıyor", + }) + +@synchronized +def start(): + # Mount all remote filesystems + if run("/usr/bin/nm-online -q -t 10") != 0: + # NM is not running + fail(MSG_NM_NOT_RUNNING) + + fstab = Fstab() + for entry in fstab.get_entries(): + if entry.is_remote_mount(): + if entry.is_nfs(): + # Start rpcbind if fs is nfs|nfs4 + startDependencies("rpcbind") + # Mount it + entry.mount() + +@synchronized +def stop(): + # Unmount all remote filesystems + fstab = Fstab() + for entry in fstab.get_entries(): + if entry.is_remote_mount(): + entry.unmount() + +def status(): + fstab = Fstab() + for entry in fstab.get_entries(): + if entry.is_remote_mount() and entry.is_mounted(): + return True diff --git a/system/base/mudur/comar/package.py b/system/base/mudur/comar/package.py new file mode 100644 index 00000000..5a814f1c --- /dev/null +++ b/system/base/mudur/comar/package.py @@ -0,0 +1,17 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import os +import re +import shutil + +def postInstall(fromVersion, fromRelease, toVersion, toRelease): + shutil.copyfile("/etc/fstab", "/etc/fstab.bak") + new = [] + for line in [line.strip() for line in open("/etc/fstab.bak")]: + if re.search("\s+\/(run|dev\/shm)\s+", line): continue + new.append(line) + new.append("tmpfs /run tmpfs nodev,nosuid,size=10%,mode=755 0 0\n") + with open("/etc/fstab", "w") as f: f.write("\n".join(new)) + + # add disks into fstab + # os.system("/sbin/update-fstab") diff --git a/system/base/mudur/comar/pakhandler.py b/system/base/mudur/comar/pakhandler.py new file mode 100644 index 00000000..45c2972c --- /dev/null +++ b/system/base/mudur/comar/pakhandler.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +import piksemel +import imp + +def doenv(filetag): + for item in filetag: + path = item.getTagData("Path") + if path.startswith("etc/env.d"): + updenv = imp.load_source("updenv", "/sbin/update-environment") + updenv.update_environment("/") + return + +def setupPackage(metapath, filepath): + doc = piksemel.parse(filepath) + doenv(doc.tags("File")) + +def cleanupPackage(metapath, filepath): + pass + +def postCleanupPackage(metapath, filepath): + doc = piksemel.parse(filepath) + doenv(doc.tags("File")) diff --git a/system/base/mudur/comar/system.py b/system/base/mudur/comar/system.py new file mode 100644 index 00000000..d615a6fb --- /dev/null +++ b/system/base/mudur/comar/system.py @@ -0,0 +1,122 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from pardus.fileutils import FileLock +from pardus.localedata import languages as LANGUAGES + +# Mudur configuration file + +CONF = "/etc/conf.d/mudur" +TTY_DEFAULT = 6 + +# Required utils + +def getConf(key, default=None): + lock = FileLock(CONF) + lock.lock(shared=True) + value = default + for line in file(CONF): + line = line.strip() + try: + _key, _value = line.split("=", 1) + except ValueError: + continue + _key = _key.strip() + if key == _key: + value = _value.strip() + if value.startswith('"') or value.startswith("'"): + value = value[1:-1] + break + lock.unlock() + return value + +def setConf(key, value=None): + lock = FileLock(CONF) + lock.lock(shared=False) + data = file(CONF).read() + lines = data.split("\n") + for index, line in enumerate(lines): + try: + _key, _value = line.split("=", 1) + except ValueError: + continue + _key = _key.strip() + if key == _key or (_key.startswith("#") and _key[1:].strip() == key): + if value: + lines[index] = "%s = '%s'" % (key, value) + elif not line.startswith("#"): + lines[index] = "# %s" % line + file(CONF, "w").write("\n".join(lines)) + lock.unlock() + +# System.Settings methods + +def listLanguages(): + languages = [] + for code, info in LANGUAGES.iteritems(): + languages.append((code, str(info.name))) + return languages + +def getLanguage(): + return getConf("language", "en") + +def setLanguage(lang): + if not len(lang): + lang = None + setConf("language", lang) + + +def listKeymaps(language): + keymaps = [] + if language and language in LANGUAGES: + for keymap in LANGUAGES[language].keymaps: + keymaps.append((keymap.console_layout, str(keymap.name))) + else: + for language in LANGUAGES: + for keymap in LANGUAGES[language].keymaps: + keymaps.append((keymap.console_layout, str(keymap.name))) + return keymaps + +def getKeymap(): + return getConf("keymap", "us") + +def setKeymap(keymap): + if not len(keymap): + keymap = None + setConf("keymap", keymap) + + +def getHeadStart(): + return getConf("head_start") + +def setHeadStart(package): + if not len(package): + package = None + setConf("head_start", package) + + +def getClock(): + is_utc = getConf("clock", "local") == "UTC" + adjust = getConf("clock_adjust", "no") == "yes" + return is_utc, adjust + +def setClock(is_utc, adjust): + if is_utc: + setConf("clock", "UTC") + else: + setConf("clock", "local") + if adjust: + setConf("clock_adjust", "yes") + else: + setConf("clock_adjust", "no") + + +def getTTYs(): + count = getConf("tty_number", TTY_DEFAULT) + try: + return int(count) + except (ValueError, TypeError): + return TypeError + +def setTTYs(count): + setConf("tty_number", count) diff --git a/system/base/mudur/files/boot_option.patch b/system/base/mudur/files/boot_option.patch new file mode 100644 index 00000000..4e90c66e --- /dev/null +++ b/system/base/mudur/files/boot_option.patch @@ -0,0 +1,43 @@ +fix issue #562 +https://github.com/pisilinux/PisiLinux/issues/562 + +--- bin/mudur.py.orig 2015-05-11 20:46:23.509195049 +0200 ++++ bin/mudur.py 2015-05-11 22:26:06.000000000 +0200 +@@ -1406,7 +1406,7 @@ + UI.info(_("Creating tmpfiles")) + if not os.path.isdir("/run/tmpfiles.d"): create_directory("/run/tmpfiles.d") + run("/usr/bin/kmod", "static-nodes", "--format=tmpfiles", "--output=/run/tmpfiles.d/kmod.conf") +- out = [line for line in capture("/sbin/mudur_tmpfiles.py")[0].split("\n") if line.strip()] ++ out = [line for line in capture("/sbin/mudur_tmpfiles.py", "--boot")[0].split("\n") if line.strip()] + if out: LOGGER.log("Errors during tmpfiles creation.\n\t%s" % "\n\t".join(out)) + run("mount", "-t", "tmpfs", "tmpfs", "/dev/shm") + +--- bin/mudur_tmpfiles.py.orig 2015-05-11 20:46:23.519200049 +0200 ++++ bin/mudur_tmpfiles.py 2015-05-11 20:40:04.000000000 +0200 +@@ -80,6 +80,7 @@ + + if __name__ == "__main__": + if ("-h" or "--help") in sys.argv: usage() ++ boot = True if "--boot" in sys.argv else False + + config_files = {} + errors = [] +@@ -90,7 +91,7 @@ + except KeyError: + config_files[head] = [tail] + +- if sys.argv[1:]: ++ if sys.argv[1:] and not boot: + for arg in sys.argv[1:]: + (head, tail) = os.path.split(arg) + if not tail.endswith(".conf"): errors.append("%s is not .conf file" % tail) +@@ -130,6 +131,9 @@ + if i == "-": fields[n] = "" + if not fields[3]: fields[3] = "root" + if not fields[4]: fields[4] = "root" ++ if fields[0].endswith("!"): ++ if not boot: continue ++ else: fields[0] = fields[0].replace("!", "") + if not fields[0] in ["c", "d", "D", "f", "F", "L", "w"]: errors.append("%s - wrong type in file: %s" % (fields[0], os.path.join(d, f))) + elif fields[0] == "L": + if not fields[6]: errors.append("No arg for type 'L' specified in file: %s" % os.path.join(d, f)) diff --git a/system/base/mudur/files/mount_cgroupfs.patch b/system/base/mudur/files/mount_cgroupfs.patch new file mode 100644 index 00000000..009d1be5 --- /dev/null +++ b/system/base/mudur/files/mount_cgroupfs.patch @@ -0,0 +1,115 @@ +diff -Nuar mudur-4.4.0.orig/bin/mudur_cgroupfs.py mudur-4.4.0/bin/mudur_cgroupfs.py +--- mudur-4.4.0.orig/bin/mudur_cgroupfs.py 1970-01-01 02:00:00.000000000 +0200 ++++ mudur-4.4.0/bin/mudur_cgroupfs.py 2015-05-13 22:58:43.264005210 +0300 +@@ -0,0 +1,81 @@ ++# -*- coding : utf-8 -*- ++import os, sys ++ ++def mountpoint(path): ++ status = os.system("mountpoint -q %s" % path) ++ if status == 0: ++ return True ++ else: ++ return False ++ ++class Controller: ++ def __init__(self, subsysname, hierarchy, num_cgroups, enabled ): ++ self.subsysname = subsysname ++ self.hierarchy = hierarchy ++ self.num_cgroups = num_cgroups ++ self.enabled = enabled ++ ++ def mount(self): ++ if self.enabled == 1: ++ os.chdir("/sys/fs/cgroup") ++ if mountpoint(self.subsysname) == False: ++ s = self.subsysname ++ status = os.system("mkdir -p %s; mount -n -t cgroup -o %s cgroup %s" % (s, s,s)) ++ if status == 0: ++ return True ++ else: ++ return False ++ ++ ++class Cgroupfs: ++ def __init__(self): ++ self.controllers = {} ++ if self.check_fstab == True: ++ print("cgroupfs in fstab, exiting.") ++ sys.exit(-1) ++ ++ if self.kernel_support() == False: ++ print("No kernel support for cgroupfs, exiting.") ++ sys.exit(-2) ++ ++ if self.check_sysfs() == False: ++ print("/sys/fs/cgroups directory not found, exiting") ++ sys.exit(-3) ++ ++ self.mount_cgroup() ++ self.find_controllers() ++ for cname, c in self.controllers.items(): ++ c.mount() ++ ++ def check_fstab(self): ++ found = False ++ for line in open("/etc/fstab").readlines(): ++ if line[0] == "#": ++ continue ++ else: ++ if line.find("cgroup"): ++ found = True ++ return found ++ ++ def kernel_support(self): ++ return os.path.isfile("/proc/cgroups") ++ ++ def check_sysfs(self): ++ return os.path.isdir("/sys/fs/cgroup") ++ ++ def mount_cgroup(self): ++ if mountpoint("/sys/fs/cgroup") == False: ++ cmd = " mount -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup" ++ return os.system(cmd) ++ ++ def find_controllers(self): ++ for line in open("/proc/cgroups").readlines(): ++ line = line.strip() ++ if line[0] == "#": ++ continue ++ else: ++ subsysname, hierarchy, num_cgroups, enabled = line.split() ++ enb = int(enabled) ++ hie = int(hierarchy) ++ numc= int(num_cgroups) ++ self.controllers[subsysname] = Controller(subsysname, hie, numc, enb) +diff -Nuar mudur-4.4.0.orig/bin/mudur.py mudur-4.4.0/bin/mudur.py +--- mudur-4.4.0.orig/bin/mudur.py 2015-05-13 22:57:33.660007190 +0300 ++++ mudur-4.4.0/bin/mudur.py 2015-05-13 22:59:17.161004246 +0300 +@@ -22,6 +22,7 @@ + import signal + import gettext + import subprocess ++from mudur_cgroupfs import Cgroupfs + + ######## + # i18n # +@@ -1025,6 +1026,7 @@ + break + df.close() + run_full("/bin/mount", "-t", "tmpfs", "-o", "nodev,nosuid,size=10%,mode=755", "tmpfs", "/run") ++ c = Cgroupfs() + + def mount_remote_filesystems(): + """Mounts remote filesystems.""" +diff -Nuar mudur-4.4.0.orig/setup.py mudur-4.4.0/setup.py +--- mudur-4.4.0.orig/setup.py 2014-03-07 23:15:31.000000000 +0200 ++++ mudur-4.4.0/setup.py 2015-05-13 23:05:23.092993840 +0300 +@@ -77,6 +77,7 @@ + + install_file("bin/mudur.py", prefix, "sbin/mudur.py") + install_file("bin/mudur_tmpfiles.py", prefix, "sbin/mudur_tmpfiles.py") ++ install_file("bin/mudur_cgroupfs.py", prefix, "sbin/mudur_cgroupfs.py") + install_file("bin/update-environment.py", prefix, "sbin/update-environment") + install_file("bin/update-fstab.py", prefix, "sbin/update-fstab") + install_file("bin/compat.py", prefix, "etc/init.d/compat.py") diff --git a/system/base/mudur/files/no_err-no_msg.patch b/system/base/mudur/files/no_err-no_msg.patch new file mode 100644 index 00000000..bc5e8715 --- /dev/null +++ b/system/base/mudur/files/no_err-no_msg.patch @@ -0,0 +1,11 @@ +--- bin/mudur.py~ 2014-06-14 14:28:45.136961885 +0200 ++++ bin/mudur.py 2014-06-14 14:29:12.000000000 +0200 +@@ -1406,7 +1406,7 @@ + UI.info(_("Creating tmpfiles")) + if not os.path.isdir("/run/tmpfiles.d"): create_directory("/run/tmpfiles.d") + run("/usr/bin/kmod", "static-nodes", "--format=tmpfiles", "--output=/run/tmpfiles.d/kmod.conf") +- out = capture("/sbin/mudur_tmpfiles.py")[0].strip().split("\n") ++ out = [line for line in capture("/sbin/mudur_tmpfiles.py")[0].split("\n") if line.strip()] + if out: LOGGER.log("Errors during tmpfiles creation.\n\t%s" % "\n\t".join(out)) + run("mount", "-t", "tmpfs", "tmpfs", "/dev/shm") + diff --git a/system/base/mudur/files/recreate_dir_if_new_uid_or_gid.patch b/system/base/mudur/files/recreate_dir_if_new_uid_or_gid.patch new file mode 100644 index 00000000..556614aa --- /dev/null +++ b/system/base/mudur/files/recreate_dir_if_new_uid_or_gid.patch @@ -0,0 +1,13 @@ +--- bin/mudur_tmpfiles.py~ 2014-05-16 03:56:41.000000000 +0200 ++++ bin/mudur_tmpfiles.py 2014-06-11 21:54:58.333421994 +0200 +@@ -37,6 +37,10 @@ + open(path, mode).write(content) + + def create(type, path, mode, uid, gid, age, arg): ++ if type == "d" and \ ++ os.path.isdir(path) and \ ++ (not uid == os.stat(path).st_uid or not gid == os.stat(path).st_gid): ++ type = "D" + if type == "L": + if not os.path.islink(path): os.symlink(arg, path) + return diff --git a/system/base/mudur/files/set_file_mode.patch b/system/base/mudur/files/set_file_mode.patch new file mode 100644 index 00000000..1b17a63b --- /dev/null +++ b/system/base/mudur/files/set_file_mode.patch @@ -0,0 +1,10 @@ +--- bin/mudur_tmpfiles.py~ 2014-08-03 17:48:07.461463934 +0200 ++++ bin/mudur_tmpfiles.py 2014-08-03 17:49:06.951461761 +0200 +@@ -63,6 +63,7 @@ + os.makedirs(os.path.dirname(path)) + os.chown(os.path.dirname(path), uid, gid) + write_file(path, arg, mode = "a" if type == "f" else "w") ++ os.chmod(path, mode) + os.chown(path, uid, gid) + + USAGE = """\ diff --git a/system/base/mudur/pspec.xml b/system/base/mudur/pspec.xml new file mode 100644 index 00000000..8bfea587 --- /dev/null +++ b/system/base/mudur/pspec.xml @@ -0,0 +1,188 @@ + + + + + mudur + http://www.pisilinux.org + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + Pisi Linux boot and initialization system + mudur handles mounting of the filesystems, loading of the device drivers, starting of the system services, and other jobs during the Pisi Linux boot and shutdown sequences. + http://source.pisilinux.org/1.0/mudur-4.4.0.tar.xz + + set_file_mode.patch + no_err-no_msg.patch + recreate_dir_if_new_uid_or_gid.patch + boot_option.patch + mount_cgroupfs.patch + + + + + mudur + + kbd + bash + dbus + kmod + eudev + comar + procps + python + rsyslog + sysvinit + coreutils + e2fsprogs + net-tools + baselayout + util-linux + wireless-tools + pisilinux-python + + + /etc/conf.d + /etc/mudur/services + /etc/init.d + /sbin + /bin + /usr/share/locale + + + System.PackageHandler + System.Service + System.Package + System.Settings + Disk.Manager + + + + + + 2015-05-13 + 4.4.0 + fix issue #562, rebuild, depend new kbd and eudev, mount cgroups + Marcin Bojara + marcin@pisilinux.org + + + 2014-08-03 + 4.4.0 + Set mode for newly created files. + Marcin Bojara + marcin@pisilinux.org + + + 2014-06-11 + 4.4.0 + Recreate dir if uid or gid has been changed. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-11 + 4.4.0 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-05-06 + 4.4.0 + No error line in log file when tmpfiles created successfully. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-16 + 4.4.0 + Remove /dev/shm line from /etc/fstab. + Add mounting /run to fstab for fresh installed system. + Marcin Bojara + marcin@pisilinux.org + + + 2014-03-07 + 4.4.0 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-02-13 + 4.3.1 + Mount or remount tmpfs at /run. + Starts with kmod.conf and baselayout.conf at the begining. + Strip mudur_tmpfiles output. + Marcin Bojara + marcin@pisilinux.org + + + 2014-02-10 + 4.3.1 + Try to fix D-Bus start issue using cleanup_run. + Serdar Soytetir + kaptan@pisilinux.org + + + 2014-01-21 + 4.3.1 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-19 + 4.3.0 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-10-28 + 4.2.0 + rebuild + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-10 + 4.2.0 + Run udev after remount rootfs. + Fix /run/shm mode. + Marcin Bojara + marcin@pisilinux.org + + + 2013-09-05 + 4.2.0 + Add missing method to pakhandler.py + Marcin Bojara + marcin@pisilinux.org + + + 2013-06-26 + 4.2.0 + Fix migration from /var/run to /run + Marcin Bojara + marcin@pisilinux.org + + + 2013-05-15 + 4.2.0 + Fix default groups for /sbin/useradd + Marcin Bojara + marcin@pisilinux.org + + + 2012-12-02 + 4.2.0 + First release + Serdar Soytetir + kaptan@pisilinux.org + + + diff --git a/system/base/mudur/translations.xml b/system/base/mudur/translations.xml new file mode 100644 index 00000000..7449fd6e --- /dev/null +++ b/system/base/mudur/translations.xml @@ -0,0 +1,9 @@ + + + + mudur + Pisi Linux açılış sistemi + Pisi Linux açılış ve kapanışı sırasında, dosya sistemlerinin bağlanması, donanım sürücülerinin yüklenmesi, servislerin başlatılması gibi işleri yürütür. + Gère le montage de systèmes de fichier, le chargement de pilotes de périphérique, le démarrage des services système et d'autres tâches pendant les séquences de démarrage et d'arrêt de Pisi Linux. + + diff --git a/system/base/ncurses/pspec.xml b/system/base/ncurses/pspec.xml index 7ff72743..cb1500b0 100644 --- a/system/base/ncurses/pspec.xml +++ b/system/base/ncurses/pspec.xml @@ -52,6 +52,9 @@ emul32 32-bit shared libraries for ncurses _emul32 + + glibc-32bit + ncurses diff --git a/system/base/nettle/pspec.xml b/system/base/nettle/pspec.xml index 2418b57f..4237d5c6 100644 --- a/system/base/nettle/pspec.xml +++ b/system/base/nettle/pspec.xml @@ -9,7 +9,6 @@ admins@pisilinux.org LGPLv2.1 - util.crypt library The Nettle package contains the low-level cryptographic library The Nettle package contains the low-level cryptographic library that is designed to fit easily in many contexts. @@ -54,10 +53,12 @@ emul32 gmp-32bit + glibc-32bit - nettle-devel - gmp-32bit + nettle + glibc-32bit + gmp /usr/lib32/ diff --git a/system/base/nspr/pspec.xml b/system/base/nspr/pspec.xml index 79d5f187..6c577d5a 100644 --- a/system/base/nspr/pspec.xml +++ b/system/base/nspr/pspec.xml @@ -12,7 +12,7 @@ library Netscape Portable Runtime Netscape Portable Runtime (NSPR) provides a platform-neutral API for system level and libc like functions. The API is used in the Mozilla client, many of Netscape/AOL/iPlanet's and other software offerings. - ftp://ftp.mozilla.org/pub/mozilla.org/nspr/releases/v4.10.7/src/nspr-4.10.7.tar.gz + ftp://ftp.mozilla.org/pub/mozilla.org/nspr/releases/v4.10.8/src/nspr-4.10.8.tar.gz nspr.pc.in generate-pc-config.sh @@ -41,6 +41,13 @@ + + 2015-04-02 + 4.10.8 + Version bump. + Hakan Yıldız + hknyldz93@gmail.com + 2014-12-06 4.10.7 diff --git a/system/base/ntfs-3g/actions.py b/system/base/ntfs-3g/actions.py index 64538470..da1adee3 100644 --- a/system/base/ntfs-3g/actions.py +++ b/system/base/ntfs-3g/actions.py @@ -11,18 +11,21 @@ from pisi.actionsapi import get def setup(): shelltools.export("CFLAGS", "%s -D_FILE_OFFSET_BITS=64" % get.CFLAGS()) - autotools.configure("--disable-static \ - --with-fuse=external \ - --enable-extras \ - --enable-posix-acls \ - --enable-ldscript \ - --disable-ldconfig") + autotools.configure("--prefix=/usr \ + --sbin=/usr/bin \ + --mandir=/usr/share/man \ + --disable-ldconfig \ + --disable-static \ + --with-fuse=external \ + --enable-posix-acls \ + --enable-extras") def build(): autotools.make() def install(): - autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + autotools.rawInstall("DESTDIR=%s rootbindir=/usr/bin rootsbindir=/usr/bin rootlibdir=/usr/lib" % get.installDIR()) + pisitools.domove("/usr/bin/ntfs-3g.*", "/bin") # Create some compat symlinks diff --git a/system/base/ntfs-3g/files/ntfsprogs_destdir.patch b/system/base/ntfs-3g/files/ntfsprogs_destdir.patch new file mode 100644 index 00000000..96723054 --- /dev/null +++ b/system/base/ntfs-3g/files/ntfsprogs_destdir.patch @@ -0,0 +1,47 @@ +diff -Naur ntfs-3g_ntfsprogs-2015.3.14.orig/ntfsprogs/Makefile.in ntfs-3g_ntfsprogs-2015.3.14/ntfsprogs/Makefile.in +--- ntfs-3g_ntfsprogs-2015.3.14.orig/ntfsprogs/Makefile.in 2015-03-14 16:10:28.000000000 +0200 ++++ ntfs-3g_ntfsprogs-2015.3.14/ntfsprogs/Makefile.in 2015-05-06 10:22:31.563526903 +0300 +@@ -1348,15 +1348,15 @@ + # mkfs.ntfs[.8] hard link + + @ENABLE_NTFSPROGS_TRUE@install-exec-hook: +-@ENABLE_NTFSPROGS_TRUE@ $(INSTALL) -d $(DESTDIR)/sbin +-@ENABLE_NTFSPROGS_TRUE@ $(LN_S) -f $(sbindir)/mkntfs $(DESTDIR)/sbin/mkfs.ntfs ++@ENABLE_NTFSPROGS_TRUE@ $(INSTALL) -d $(DESTDIR)/usr/bin ++@ENABLE_NTFSPROGS_TRUE@ $(LN_S) -f $(sbindir)/mkntfs $(DESTDIR)/usr/bin/mkfs.ntfs + + @ENABLE_NTFSPROGS_TRUE@install-data-hook: + @ENABLE_NTFSPROGS_TRUE@ $(INSTALL) -d $(DESTDIR)$(man8dir) + @ENABLE_NTFSPROGS_TRUE@ $(LN_S) -f mkntfs.8 $(DESTDIR)$(man8dir)/mkfs.ntfs.8 + + @ENABLE_NTFSPROGS_TRUE@uninstall-local: +-@ENABLE_NTFSPROGS_TRUE@ $(RM) -f $(DESTDIR)/sbin/mkfs.ntfs ++@ENABLE_NTFSPROGS_TRUE@ $(RM) -f $(DESTDIR)/usr/bin/mkfs.ntfs + @ENABLE_NTFSPROGS_TRUE@ $(RM) -f $(DESTDIR)$(man8dir)/mkfs.ntfs.8 + + # Tell versions [3.59,3.63) of GNU make to not export all variables. +diff -Naur ntfs-3g_ntfsprogs-2015.3.14.orig/src/Makefile.in ntfs-3g_ntfsprogs-2015.3.14/src/Makefile.in +--- ntfs-3g_ntfsprogs-2015.3.14.orig/src/Makefile.in 2015-03-14 16:10:28.000000000 +0200 ++++ ntfs-3g_ntfsprogs-2015.3.14/src/Makefile.in 2015-05-06 10:22:31.566526903 +0300 +@@ -1040,9 +1040,9 @@ + @ENABLE_NTFS_3G_TRUE@@RUN_LDCONFIG_TRUE@ $(LDCONFIG) + + @ENABLE_MOUNT_HELPER_TRUE@@ENABLE_NTFS_3G_TRUE@install-exec-local: install-rootbinPROGRAMS +-@ENABLE_MOUNT_HELPER_TRUE@@ENABLE_NTFS_3G_TRUE@ $(MKDIR_P) "$(DESTDIR)/sbin" +-@ENABLE_MOUNT_HELPER_TRUE@@ENABLE_NTFS_3G_TRUE@ $(LN_S) -f "$(rootbindir)/ntfs-3g" "$(DESTDIR)/sbin/mount.ntfs-3g" +-@ENABLE_MOUNT_HELPER_TRUE@@ENABLE_NTFS_3G_TRUE@ $(LN_S) -f "$(rootbindir)/lowntfs-3g" "$(DESTDIR)/sbin/mount.lowntfs-3g" ++@ENABLE_MOUNT_HELPER_TRUE@@ENABLE_NTFS_3G_TRUE@ $(MKDIR_P) "$(DESTDIR)/usr/bin" ++@ENABLE_MOUNT_HELPER_TRUE@@ENABLE_NTFS_3G_TRUE@ $(LN_S) -f "$(rootbindir)/ntfs-3g" "$(DESTDIR)/usr/bin/mount.ntfs-3g" ++@ENABLE_MOUNT_HELPER_TRUE@@ENABLE_NTFS_3G_TRUE@ $(LN_S) -f "$(rootbindir)/lowntfs-3g" "$(DESTDIR)/usr/bin/mount.lowntfs-3g" + + @ENABLE_NTFS_3G_TRUE@install-data-local: install-man8 + @ENABLE_NTFS_3G_TRUE@ $(LN_S) -f ntfs-3g.8 "$(DESTDIR)$(man8dir)/mount.ntfs-3g.8" +@@ -1050,7 +1050,7 @@ + + @ENABLE_NTFS_3G_TRUE@uninstall-local: + @ENABLE_NTFS_3G_TRUE@ $(RM) -f "$(DESTDIR)$(man8dir)/mount.ntfs-3g.8" +-@ENABLE_MOUNT_HELPER_TRUE@@ENABLE_NTFS_3G_TRUE@ $(RM) -f "$(DESTDIR)/sbin/mount.ntfs-3g" "$(DESTDIR)/sbin/mount.lowntfs-3g" ++@ENABLE_MOUNT_HELPER_TRUE@@ENABLE_NTFS_3G_TRUE@ $(RM) -f "$(DESTDIR)/usr/bin/mount.ntfs-3g" "$(DESTDIR)/sbin/mount.lowntfs-3g" + + # Tell versions [3.59,3.63) of GNU make to not export all variables. + # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/system/base/ntfs-3g/pspec.xml b/system/base/ntfs-3g/pspec.xml index 83d4897c..707a842f 100644 --- a/system/base/ntfs-3g/pspec.xml +++ b/system/base/ntfs-3g/pspec.xml @@ -14,7 +14,10 @@ app:console Userspace driver for NTFS read/write support ntfs-3g allows regular users read/write access to NTFS filesystems. - http://tuxera.com/opensource/ntfs-3g_ntfsprogs-2014.2.15.tgz + http://tuxera.com/opensource/ntfs-3g_ntfsprogs-2015.3.14.tgz + + ntfsprogs_destdir.patch + @@ -47,8 +50,9 @@ Userspace tools for NTFS filesystems. The goals of the Linux-NTFS project are to develop reliable and full-featured access to NTFS by the Linux kernel driver and to provide a wide collection of NTFS utilities. ntfs-3g + fuse glibc - libuuid + libutil-linux /sbin/mkfs.ntfs @@ -60,6 +64,13 @@ + + 2015-05-06 + 2015.3.14 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-12-13 2014.2.15 diff --git a/system/base/openssl/pspec.xml b/system/base/openssl/pspec.xml index bc049ac7..221d00d7 100644 --- a/system/base/openssl/pspec.xml +++ b/system/base/openssl/pspec.xml @@ -13,12 +13,13 @@ library Toolkit for SSL v2/v3 and TLS v1 OpenSSL is a cryptography toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) network protocols and related cryptography standards required by them. - ftp://ftp.openssl.org/source/openssl-1.0.2.tar.gz + ftp://ftp.openssl.org/source/openssl-1.0.2a.tar.gz openssl-1.0.0-beta4-ca-dir.patch - zlib + zlib-devel + xorg-util perl sed @@ -26,12 +27,12 @@ openssl-1.0.0a-ldflags-norpath.patch openssl-1.0.0-beta4-ca-dir.patch openssl-1.0.0-beta5-enginesdir.patch - openssl-1.0.2-parallel-build.patch + openssl-1.0.2-ipv6.patch openssl-1.0.2-s_client-verify.patch openssl-include.patch openssl_fix_for_x32.patch - openssl-optflags.patch + @@ -79,6 +80,7 @@ openssl zlib-32bit + glibc-32bit /usr/lib32 @@ -86,6 +88,13 @@ + + 2015-04-11 + 1.0.2a + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2015-02-17 1.0.2 diff --git a/system/base/os-prober/pspec.xml b/system/base/os-prober/pspec.xml index 372bc290..a30dcb36 100644 --- a/system/base/os-prober/pspec.xml +++ b/system/base/os-prober/pspec.xml @@ -12,7 +12,7 @@ app:console Utility to detect other OSes on a set of drives os-probe detects other OSes available on a system and outputs the results in a generic machine-readable format. Support for new OSes and Linux distributions can be added easily. - ftp://ftp.debian.org/debian/pool/main/o/os-prober/os-prober_1.63.tar.gz + http://http.debian.net/debian/pool/main/o/os-prober/os-prober_1.65.tar.xz os-prober @@ -25,6 +25,13 @@ + + 2015-05-03 + 1.65 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 1.63 diff --git a/system/base/pam/actions.py b/system/base/pam/actions.py index 3404fab6..b9525ce6 100644 --- a/system/base/pam/actions.py +++ b/system/base/pam/actions.py @@ -14,8 +14,11 @@ def setup(): autotools.autoreconf("-fi") autotools.configure("--enable-nls \ + --disable-audit \ --enable-securedir=/lib/security \ --enable-isadir=/lib/security") + + pisitools.dosed("libtool", " -shared ", " -Wl,-O1,--as-needed -shared ") def build(): # Update .po files diff --git a/system/base/pam/pspec.xml b/system/base/pam/pspec.xml index f7c95189..ceae70de 100644 --- a/system/base/pam/pspec.xml +++ b/system/base/pam/pspec.xml @@ -21,7 +21,6 @@ perl gettext cracklib - audit-devel @@ -35,7 +34,6 @@ pam - audit cracklib @@ -71,6 +69,13 @@ + + 2015-04-01 + 1.1.8 + Rebuild, remove unused. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-06-10 1.1.8 diff --git a/system/base/pcmciautils/pspec.xml b/system/base/pcmciautils/pspec.xml index b0fe6cc7..b740e6c4 100644 --- a/system/base/pcmciautils/pspec.xml +++ b/system/base/pcmciautils/pspec.xml @@ -12,9 +12,9 @@ app:console Various utilities dealing with the PCMCIA bus pcmciautils contains the initialization tools necessary to allow the PCMCIA subsystem to behave as every other hotpluggable bus system. - http://ftp.task.gda.pl/vol/d0s0/ftp.kernel.org/pub/linux/utils/kernel/pcmcia/pcmciautils-018.tar.bz2 + https://sources.archlinux.org/other/pcmciautils/pcmciautils-018.tar.xz - sysfsutils + sysfsutils-devel diff --git a/system/base/piksemel/pspec.xml b/system/base/piksemel/pspec.xml index 0bb3831b..88ca2b76 100644 --- a/system/base/piksemel/pspec.xml +++ b/system/base/piksemel/pspec.xml @@ -14,7 +14,7 @@ A simple, fast, small and robust XML parser for Python, based on iksemel. http://source.pisilinux.org/1.0/piksemel-1.3.1.tar.gz - python + python-devel symbol-visibility.patch diff --git a/system/base/pisi/files/qt5.py b/system/base/pisi/files/qt5.py new file mode 100644 index 00000000..5cbdbf00 --- /dev/null +++ b/system/base/pisi/files/qt5.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2010 TUBITAK/UEKAE +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# Please read the COPYING file. + +import glob +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + +# Pisi Modules +import pisi.context as ctx + +# ActionsAPI Modules +import pisi.actionsapi + +# ActionsAPI Modules +from pisi.actionsapi import get +from pisi.actionsapi import cmaketools +from pisi.actionsapi import shelltools + +basename = "qt5" + +prefix = "/%s" % get.defaultprefixDIR() +libdir = "%s/lib" % prefix +libexecdir = "%s/libexec" % prefix +sysconfdir= "/etc" +bindir = "%s/bin" % prefix +includedir = "%s/include" % prefix + +# qt5 spesific variables + +headerdir = "%s/include/%s" % (prefix, basename) +datadir = "%s/share/%s" % (prefix, basename) +docdir = "/%s/%s" % (get.docDIR(), basename) +archdatadir = "%s/%s" % (libdir, basename) +examplesdir = "%s/%s/examples" % (libdir, basename) +importdir = "%s/%s/imports" % (libdir, basename) +plugindir = "%s/%s/plugins" % (libdir, basename) +qmldir = "%s/%s/qmldir" % (libdir, basename) +testdir = "%s/share/%s" % (prefix, basename) +translationdir = "%s/translations" % datadir + +qmake = "%s/qmake-qt5" % bindir + +class ConfigureError(pisi.actionsapi.Error): + def __init__(self, value=''): + pisi.actionsapi.Error.__init__(self, value) + self.value = value + ctx.ui.error(value) + +def configure(projectfile='', parameters='', installPrefix=prefix): + if projectfile != '' and not shelltools.can_access_file(projectfile): + raise ConfigureError(_("Project file '%s' not found.") % projectfile) + + profiles = glob.glob("*.pro") + if len(profiles) > 1 and projectfile == '': + raise ConfigureError(_("It seems there are more than one .pro file, you must specify one. (Possible .pro files: %s)") % ", ".join(profiles)) + + shelltools.system("%s -makefile %s PREFIX='%s' QMAKE_CFLAGS+='%s' QMAKE_CXXFLAGS+='%s' %s" % (qmake, projectfile, installPrefix, get.CFLAGS(), get.CXXFLAGS(), parameters)) + +def make(parameters=''): + cmaketools.make(parameters) + +def install(parameters='', argument='install'): + cmaketools.install('INSTALL_ROOT="%s" %s' % (get.installDIR(), parameters), argument) + diff --git a/system/base/pisi/pspec.xml b/system/base/pisi/pspec.xml index ed9321d4..b8b1438b 100644 --- a/system/base/pisi/pspec.xml +++ b/system/base/pisi/pspec.xml @@ -22,6 +22,7 @@ plyvel python gettext + intltool leveldb-devel @@ -48,6 +49,9 @@ comar-api urlgrabber python-psutil + libunwind + python-pyliblzma mudur @@ -70,6 +74,7 @@ pisi.xml pkgconfig.py tmpfiles.conf + qt5.py System.Package @@ -78,6 +83,13 @@ + + 2015-05-04 + 2.6 + Add qt5 api + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + 2014-12-07 2.6 @@ -303,4 +315,4 @@ marcin@pisilinux.org - \ No newline at end of file + diff --git a/system/base/pisilinux-python/files/remove_libX11_dep.patch b/system/base/pisilinux-python/files/remove_libX11_dep.patch new file mode 100644 index 00000000..691ffc77 --- /dev/null +++ b/system/base/pisilinux-python/files/remove_libX11_dep.patch @@ -0,0 +1,147 @@ +diff -Nuar pardus-python-0.4.8.orig/pardus/__init__.py pardus-python-0.4.8/pardus/__init__.py +--- pardus-python-0.4.8.orig/pardus/__init__.py 2010-12-09 14:47:32.000000000 +0200 ++++ pardus-python-0.4.8/pardus/__init__.py 2015-03-06 17:46:44.000000000 +0200 +@@ -24,8 +24,7 @@ + "netfilterutils", + "shellutils", + "strutils", +- "sysutils", +- "xorg"] ++ "sysutils"] + + + def versionString(): +diff -Nuar pardus-python-0.4.8.orig/pardus/xorg/capslock.c pardus-python-0.4.8/pardus/xorg/capslock.c +--- pardus-python-0.4.8.orig/pardus/xorg/capslock.c 2010-12-09 14:47:32.000000000 +0200 ++++ pardus-python-0.4.8/pardus/xorg/capslock.c 1970-01-01 02:00:00.000000000 +0200 +@@ -1,59 +0,0 @@ +-/* +-* Copyright (c) 2005, TUBITAK/UEKAE +-* +-* This program is free software; you can redistribute it and/or modify it +-* under the terms of the GNU General Public License as published by the +-* Free Software Foundation; either version 2 of the License, or (at your +-* option) any later version. Please read the COPYING file. +-*/ +- +-#include +-#include +- +- +-PyDoc_STRVAR(isOn__doc__, +-"isOn()\n" +-"\n" +-"method checked if CapsLock is on\n"); +- +-PyObject* +-capslock_isOn(PyObject *self, PyObject *args) +-{ +- int capsLocked; +- unsigned int lmask; +- Window dummy1, dummy2; +- int dummy3, dummy4, dummy5, dummy6; +- Display *display; +- +- display = XOpenDisplay(0); +- XQueryPointer(display, DefaultRootWindow(display), +- &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, &dummy6, +- &lmask); +- capsLocked = lmask & LockMask; +- XCloseDisplay(display); +- +- if (capsLocked) +- { +- Py_INCREF(Py_True); +- return Py_True; +- } +- +- Py_INCREF(Py_False); +- return Py_False; +-} +- +-static PyMethodDef capslock_methods[] = { +- {"isOn", (PyCFunction)capslock_isOn, METH_NOARGS, isOn__doc__}, +- {NULL, NULL} +-}; +- +-PyMODINIT_FUNC +-initcapslock(void) +-{ +- PyObject *m; +- +- m = Py_InitModule("capslock", capslock_methods); +- +- return; +-} +- +diff -Nuar pardus-python-0.4.8.orig/pardus/xorg/__init__.py pardus-python-0.4.8/pardus/xorg/__init__.py +--- pardus-python-0.4.8.orig/pardus/xorg/__init__.py 2010-12-09 14:47:32.000000000 +0200 ++++ pardus-python-0.4.8/pardus/xorg/__init__.py 1970-01-01 02:00:00.000000000 +0200 +@@ -1,6 +0,0 @@ +-# -*- coding: utf-8 -*- +- +-import capslock +-import xterm +- +-__all__ = ["capslock", "xterm"] +diff -Nuar pardus-python-0.4.8.orig/pardus/xorg/xterm.py pardus-python-0.4.8/pardus/xorg/xterm.py +--- pardus-python-0.4.8.orig/pardus/xorg/xterm.py 2010-12-09 14:47:32.000000000 +0200 ++++ pardus-python-0.4.8/pardus/xorg/xterm.py 1970-01-01 02:00:00.000000000 +0200 +@@ -1,31 +0,0 @@ +-# -*- coding: utf-8 -*- +-# +-# Copyright (C) 2006, TUBITAK/UEKAE +-# +-# This program is free software; you can redistribute it and/or modify it under +-# the terms of the GNU General Public License as published by the Free +-# Software Foundation; either version 2 of the License, or (at your option) +-# any later version. +-# +-# Please read the COPYING file. +-# +- +-import sys +-import os +- +- +-def set_title(message): +- """Set message as console window title.""" +- if os.environ.has_key("TERM") and sys.stderr.isatty(): +- terminalType = os.environ["TERM"] +- for term in ["xterm", "Eterm", "aterm", "rxvt", "screen", "kterm", "rxvt-unicode"]: +- if terminalType.startswith(term): +- sys.stderr.write("\x1b]2;"+str(message)+"\x07") +- sys.stderr.flush() +- break +- +- +-def reset_title(): +- """Reset console window title.""" +- if os.environ.has_key("TERM"): +- set_title("") +diff -Nuar pardus-python-0.4.8.orig/setup.py pardus-python-0.4.8/setup.py +--- pardus-python-0.4.8.orig/setup.py 2010-12-09 14:47:32.000000000 +0200 ++++ pardus-python-0.4.8/setup.py 2015-03-06 17:50:11.000000000 +0200 +@@ -15,8 +15,6 @@ + setup.py + pardus/*.py + pardus/*.c +- pardus/xorg/*.py +- pardus/xorg/*.c + po/*.po + po/*.pot + tools/*.py +@@ -82,11 +80,8 @@ + author="Pardus Developers", + author_email="info@pardus.org.tr", + url="http://www.pardus.org.tr/", +- packages = ['pardus', 'pardus.xorg'], +- ext_modules = [Extension('pardus.xorg.capslock', +- sources=['pardus/xorg/capslock.c'], +- libraries=['X11']), +- Extension('pardus.csapi', ++ packages = ['pardus'], ++ ext_modules = [Extension('pardus.csapi', + sources=['pardus/csapi.c'], + libraries=[]), + ], diff --git a/system/base/pisilinux-python/pspec.xml b/system/base/pisilinux-python/pspec.xml index f35ba7a4..c076e1d5 100644 --- a/system/base/pisilinux-python/pspec.xml +++ b/system/base/pisilinux-python/pspec.xml @@ -14,16 +14,19 @@ Python modules for Pisi Linux provides functions for common task, with the aim of easing development. http://source.pisilinux.org/1.0/pisilinux-python-0.4.8.tar.gz - python - libX11-devel + python-devel + + + remove_libX11_dep.patch + pisilinux-python python - libX11 + /usr/lib @@ -33,6 +36,13 @@ + + 2015-03-11 + 0.4.8 + Remove libX11 dependency. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 0.4.8 diff --git a/system/base/plyvel/pspec.xml b/system/base/plyvel/pspec.xml index 079a033b..2035903a 100644 --- a/system/base/plyvel/pspec.xml +++ b/system/base/plyvel/pspec.xml @@ -11,7 +11,10 @@ Plyvel, a fast and feature-rich Python interface to LevelDB. Plyvel has a rich feature set, high performance, and a friendly Pythonic API. - cython + cython + python-devel + leveldb-devel + python-setuptools https://pypi.python.org/packages/source/p/plyvel/plyvel-0.8.tar.gz diff --git a/system/base/polkit/actions.py b/system/base/polkit/actions.py index 2c03cc7d..40c46a66 100644 --- a/system/base/polkit/actions.py +++ b/system/base/polkit/actions.py @@ -10,21 +10,19 @@ from pisi.actionsapi import pisitools from pisi.actionsapi import get def setup(): - #Use it for root user instead of wheel group - #shelltools.system("sed -i -e 's|unix-group:wheel|unix-user:0|' src/polkitbackend/*-default.rules") - # Use it if we have spidermonkey 1.8.7 or newer... - #shelltools.system("sed -i -e '/mozjs/s:185:187:g' configure") - #look http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/sys-auth/polkit/polkit-0.107.ebuild - #shelltools.system("cmd='sed -i -e "/mozjs/s:185:187:g" configure src/polkitbackend/polkitbackendjsauthority.c'") - autotools.autoreconf("-fi") + #autotools.autoreconf("-fi") autotools.configure("--with-pam-module-dir=/lib/security/ \ - --with-os-type=PisiLinux \ + --with-os-type=pardus \ + --with-mozjs=mozjs-17.0 \ + --with-dbus \ --enable-examples \ - --enable-introspection \ + --disable-introspection \ --enable-libsystemd-login=no \ + --with-systemdsystemunitdir=no \ --disable-man-pages \ --disable-gtk-doc \ --disable-static") + pisitools.dosed("libtool"," -shared ", " -Wl,--as-needed -shared ") def build(): diff --git a/system/base/polkit/pspec.xml b/system/base/polkit/pspec.xml index c0888a7d..1e1e7508 100644 --- a/system/base/polkit/pspec.xml +++ b/system/base/polkit/pspec.xml @@ -22,6 +22,7 @@ expat-devel dbus-glib-devel spidermonkey-devel + intltool disable-docs.patch @@ -84,6 +85,13 @@ + + 2015-05-08 + 0.112 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-06-10 0.112 diff --git a/system/base/procps/pspec.xml b/system/base/procps/pspec.xml index a39502a9..6cc35f57 100644 --- a/system/base/procps/pspec.xml +++ b/system/base/procps/pspec.xml @@ -14,7 +14,7 @@ procps is the package that has a bunch of small useful utilities that give information about processes using the /proc filesystem. The package includes the programs ps, top, vmstat, w, kill, free, slabtop, and skill. http://procps.sf.net/procps-3.2.8.tar.gz - ncurses + ncurses-devel procps-3.2.5-proc-mount.patch diff --git a/system/base/psmisc/files/psmisc-fuser.patch b/system/base/psmisc/files/psmisc-fuser.patch new file mode 100644 index 00000000..b7645f20 --- /dev/null +++ b/system/base/psmisc/files/psmisc-fuser.patch @@ -0,0 +1,11 @@ +--- a/src/fuser.c ++++ b/src/fuser.c +@@ -1174,7 +1174,7 @@ + usage(_("No process specification given")); + + /* Check if -M flag was used and if so check mounts */ +- if (opts * OPT_ISMOUNTPOINT) { ++ if (opts & OPT_ISMOUNTPOINT) { + check_mountpoints(&mounts, &names_head, &names_tail); + } + diff --git a/system/base/psmisc/pspec.xml b/system/base/psmisc/pspec.xml index dc22952f..217a19cc 100644 --- a/system/base/psmisc/pspec.xml +++ b/system/base/psmisc/pspec.xml @@ -12,11 +12,14 @@ app:console A set of tools that use the proc filesystem PSmisc is a collection of small utilities using /proc file system, and providing the system administrator with some help in common tasks. - mirrors://sourceforge/psmisc/psmisc-22.20.tar.gz + mirrors://sourceforge/psmisc/psmisc-22.21.tar.gz - ncurses + ncurses-devel gettext + + psmisc-fuser.patch + @@ -34,6 +37,13 @@ + + 2015-05-03 + 22.21 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 22.20 diff --git a/system/base/pycurl/actions.py b/system/base/pycurl/actions.py index 9efee7f8..874532a8 100644 --- a/system/base/pycurl/actions.py +++ b/system/base/pycurl/actions.py @@ -6,8 +6,11 @@ from pisi.actionsapi import pythonmodules from pisi.actionsapi import pisitools +from pisi.actionsapi import shelltools from pisi.actionsapi import get +shelltools.export("PYCURL_SSL_LIBRARY", "openssl") + def install(): # no static libs pisitools.dosed("setup.py", ", \"--static-libs\"") diff --git a/system/base/pycurl/pspec.xml b/system/base/pycurl/pspec.xml index fefebe3f..9d642c50 100644 --- a/system/base/pycurl/pspec.xml +++ b/system/base/pycurl/pspec.xml @@ -14,9 +14,9 @@ PycURL is a Python interface to libcurl. PycURL can be used to fetch objects identified by a URL from a Python program. http://pycurl.sourceforge.net/download/pycurl-7.19.3.1.tar.gz - curl - python - openssl + curl-devel + python-devel + openssl-devel diff --git a/system/base/pypolkit/pspec.xml b/system/base/pypolkit/pspec.xml index 619f96ed..065ed896 100644 --- a/system/base/pypolkit/pspec.xml +++ b/system/base/pypolkit/pspec.xml @@ -14,9 +14,9 @@ pypolkit is a Python binding for the PolicyKit library. http://source.pisilinux.org/1.0/pypolkit-1.0.2.tar.gz - glib2 - python - polkit-devel + glib2-devel + python-devel + polkit-devel @@ -34,6 +34,13 @@ + + 2015-05-08 + 1.0.2 + Rebuild. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 1.0.2 diff --git a/system/base/python-psutil/actions.py b/system/base/python-psutil/actions.py new file mode 100644 index 00000000..46897e82 --- /dev/null +++ b/system/base/python-psutil/actions.py @@ -0,0 +1,16 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# Licensed under the GNU General Public License, version 3. +# See the file http://www.gnu.org/copyleft/gpl.txt. + +from pisi.actionsapi import pythonmodules +from pisi.actionsapi import pisitools + +def build(): + pythonmodules.compile() + +def install(): + pythonmodules.install() + + pisitools.dodoc("LICENSE", "README.rst", "INSTALL.rst") diff --git a/system/base/python-psutil/pspec.xml b/system/base/python-psutil/pspec.xml new file mode 100644 index 00000000..1757a0a7 --- /dev/null +++ b/system/base/python-psutil/pspec.xml @@ -0,0 +1,55 @@ + + + + + python-psutil + https://github.com/giampaolo/psutil + + PisiLinux Community + admins@pisilinux.org + + BSD + library + A cross-platform process utilities module for Python + python-psutil is a module providing an interface for retrieving information on all running processes and system utilization (CPU, memory) in a portable way by using Python, implementing many functionalities offered by command line tools like ps, top, kill, lsof and netstat. + https://github.com/giampaolo/psutil/archive/release-2.2.1.tar.gz + + python-devel + + + + + python-psutil + + python + + + /usr/lib + /usr/share/doc + + + + + + 2015-04-12 + 2.2.1 + Version bump + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2013-11-19 + 1.1.3 + Version bump + Burak Fazıl Ertürk + burakerturk@pisilinux.org + + + 2012-11-16 + 0.6.1 + First release + Erdinç Gültekin + admins@pisilinux.org + + + diff --git a/system/base/python-psutil/translations.xml b/system/base/python-psutil/translations.xml new file mode 100644 index 00000000..95d95c82 --- /dev/null +++ b/system/base/python-psutil/translations.xml @@ -0,0 +1,8 @@ + + + + python-psutil + Platform bağımsız, süreçler hakkında bilgi sağlayan bir Python modülü + python-psutil, bütün çalışan süreçler ve sistem kullanımı (MİB - Merkezi İşlem Birim(CPU) ve hafıza gibi) hakkında bilgilere erişimek için arayüz sunan bir Python modülüdür. ps, top, kill, lsof, netstat gibi bir çok komut satırı araçlarının sunduğu işlevselliği sağlamaktadır. + + diff --git a/system/base/python-pyliblzma/pspec.xml b/system/base/python-pyliblzma/pspec.xml index 26399655..0dd6ef01 100644 --- a/system/base/python-pyliblzma/pspec.xml +++ b/system/base/python-pyliblzma/pspec.xml @@ -14,7 +14,9 @@ pyliblzma provides a python interface for the liblzma library to read/write data that has been compressed/decompressed with lzma utils. http://pypi.python.org/packages/source/p/pyliblzma/pyliblzma-0.5.3.tar.bz2 - xz + xz-devel + python-setuptools + python-devel diff --git a/system/base/python/pspec.xml b/system/base/python/pspec.xml index 9314ac48..76087d7a 100644 --- a/system/base/python/pspec.xml +++ b/system/base/python/pspec.xml @@ -15,11 +15,11 @@ http://www.python.org/ftp/python/2.7.9/Python-2.7.9.tar.xz bzip2 - tcl-devel + gdbm-devel zlib-devel expat-devel - tcltk-devel + libffi-devel sqlite-devel ncurses-devel @@ -93,7 +93,7 @@ - + - + diff --git a/system/base/readline/pspec.xml b/system/base/readline/pspec.xml index eeb87e4a..facd29b6 100644 --- a/system/base/readline/pspec.xml +++ b/system/base/readline/pspec.xml @@ -40,6 +40,9 @@ readline-devel system.devel Development files for readline + + glibc-32bit + readline @@ -60,6 +63,7 @@ readline ncurses-32bit + glibc-32bit /usr/lib32 diff --git a/system/base/rsyslog/actions.py b/system/base/rsyslog/actions.py index b3aa2e4b..6aa2836f 100644 --- a/system/base/rsyslog/actions.py +++ b/system/base/rsyslog/actions.py @@ -9,7 +9,7 @@ from pisi.actionsapi import autotools from pisi.actionsapi import pisitools def setup(): - pisitools.cflags.add('-fpie -DSYSLOGD_PIDNAME=\\"syslogd.pid\\"') + #pisitools.cflags.add('-fpie -DSYSLOGD_PIDNAME=\\"syslogd.pid\\"') pisitools.ldflags.add("-pie -Wl,-z,relro -Wl,-z,now") autotools.configure("\ @@ -25,8 +25,9 @@ def setup(): --disable-testbench \ --disable-mmnormalize \ --disable-gssapi-krb5 \ + --disable-generate-man-pages \ + --disable-uuid \ --enable-mail \ - --enable-uuid \ --enable-zlib \ --enable-imdiag \ --enable-imfile \ @@ -47,6 +48,7 @@ def setup(): --enable-unlimited-select \ --enable-pmaixforwardedfrom \ --enable-cached-man-pages \ + --with-systemdsystemunitdir=no \ ") pisitools.dosed("libtool", " -shared ", " -Wl,-O1,--as-needed -shared ") diff --git a/system/base/rsyslog/comar/service.py b/system/base/rsyslog/comar/service.py index 00b5d989..68e12266 100644 --- a/system/base/rsyslog/comar/service.py +++ b/system/base/rsyslog/comar/service.py @@ -6,12 +6,12 @@ serviceDesc = _({"en": "System Message Logger", "tr": "Sistem Günlükleme Hizmeti"}) serviceDefault = "on" -PIDFILE = "/run/syslogd.pid" +PIDFILE = "/var/run/rsyslogd.pid" @synchronized def start(): startService(command="/usr/bin/rsyslogd", - args=config.get("SYSLOGD_OPTIONS", "-c 4"), + args=config.get("SYSLOGD_OPTIONS", ""), pidfile=PIDFILE, detach=True) diff --git a/system/base/rsyslog/files/50-default.conf b/system/base/rsyslog/files/50-default.conf new file mode 100644 index 00000000..9ae85782 --- /dev/null +++ b/system/base/rsyslog/files/50-default.conf @@ -0,0 +1,95 @@ +####################### +### DEFAULT ACTIONS ### +####################### + +auth,authpriv.* action( + type="omfile" + File="/var/log/auth.log" + FileCreateMode="0600" + FileOwner="root" + FileGroup="adm" + Sync="off" +) + +cron.* action( + type="omfile" + File="/var/log/cron.log" + FileOwner="root" + FileGroup="adm" +) + +daemon.* action( + type="omfile" + File="/var/log/daemon.log" + FileOwner="root" + FileGroup="adm" +) + +kern.* action( + type="omfile" + File="/var/log/kern.log" + FileOwner="root" + FileGroup="adm" +) + +lpr.* action( + type="omfile" + File="/var/log/lpr.log" + FileOwner="root" + FileGroup="adm" +) + +mail.* action( + type="omfile" + File="/var/log/mail.log" + FileOwner="root" + FileGroup="adm" +) + +news.* action( + type="omfile" + File="/var/log/news.log" + FileOwner="root" + FileGroup="adm" +) + +user.* action( + type="omfile" + File="/var/log/user.log" + FileOwner="root" + FileGroup="adm" +) + +*.=debug;auth,authpriv,news,mail.none action( + type="omfile" + File="/var/log/debug.log" + FileOwner="root" + FileGroup="adm" +) + +*.info;auth,authpriv,cron,daemon,lpr,mail,news.none action( + type="omfile" + File="/var/log/messages" + FileOwner="root" + FileGroup="adm" +) + +# Uncomment the following directive to re-enable the +# deprecated "/var/log/syslog" log file (don't forget to re-enable log +# rotation in "/etc/logrotate.d/rsyslog" if you do that!) +#*.*;auth,authpriv.none action( +# type="omfile" +# File="/var/log/syslog" +# FileOwner="root" +# FileGroup="adm" +#) + +*.emerg action( + type="omusrmsg" + Users="*" + action.execOnlyOnceEveryInterval="10" +) + +# Create an additional socket for the default chroot location +# (used by net-misc/openssh[hpn], see https://bugs.gentoo.org/490744) +input(type="imuxsock" Socket="/var/empty/dev/log") diff --git a/system/base/rsyslog/files/rsyslog.conf b/system/base/rsyslog/files/rsyslog.conf index 9d83e590..da484598 100644 --- a/system/base/rsyslog/files/rsyslog.conf +++ b/system/base/rsyslog/files/rsyslog.conf @@ -1,95 +1,61 @@ -#rsyslog v3 config file +# /etc/rsyslog.conf +# +# This configuration is based on RainerScript, the new recommended syntax +# for RSYSLOG. See http://www.rsyslog.com/doc/rainerscript.html for further +# details. +# +# But if you don't want to learn something new at moment, don't worry: The +# legacy syntax is still supported. +# +# You may want to use the new RSYSLOG configuration builder to create your +# own more advanced configuration: http://www.rsyslog.com/rsyslog-configuration-builder/ -# if you experience problems, check -# http://www.rsyslog.com/troubleshoot for assistance - -#### MODULES #### - -$ModLoad imuxsock.so # provides support for local system logging (e.g. via logger command) -$ModLoad imklog.so # provides kernel logging support (previously done by rklogd) -$ModLoad immark.so # provides --MARK-- message capability - -# Provides UDP syslog reception -#$ModLoad imudp.so -#$UDPServerRun 514 - -# Provides TCP syslog reception -#$ModLoad imtcp.so -#$InputTCPServerRun 514 +# Check config syntax on startup and abort if unclean (default: off) +#$AbortOnUncleanConfig on -#### GLOBAL DIRECTIVES #### +############### +### MODULES ### +############### -# Use default timestamp format -$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat +# Read syslog messages from default Unix socket /dev/log (e.g. via logger command) +module(load="imuxsock") -# File syncing capability is disabled by default. This feature is usually not required, -# not useful and an extreme performance hit -#$ActionFileEnableSync on +# Read messages from the kernel log and submits them to the syslog engine +module(load="imklog") + +# Inject "--MARK--" messages every $Interval (seconds) +#module(load="immark" Interval="600") + +# Read syslog messages from UDP +#module(load="imudp") +#input(type="imudp" port="514") + +# Read syslog messages from TCP +#module(load="imtcp") +#input(type="imtcp" port="514") -## ### begin forwarding rule ### -# The statement between the begin ... end define a SINGLE forwarding -# rule. They belong together, do NOT split them. If you create multiple -# forwarding rules, duplicate the whole block! -# Remote Logging (we use TCP for reliable delivery) -# -# An on-disk queue is created for this action. If the remote host is -# down, messages are spooled to disk and sent when it is up again. -#$WorkDirectory /var/spppl/rsyslog # where to place spool files -#$ActionQueueFileName fwdRule1 # unique name prefix for spool files -#$ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible) -#$ActionQueueSaveOnShutdown on # save messages to disk on shutdown -#$ActionQueueType LinkedList # run asynchronously -#$ActionResumeRetryCount -1 # infinite retries if host is down -# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional -#*.* @@remote-host:514 -# ### end of the forwarding rule ### +######################### +### GLOBAL DIRECTIVES ### +######################### + +# Where to place spool and state files +$WorkDirectory /var/spool/rsyslog + +# Reduce repeating messages (default: off) +#$RepeatedMsgReduction on + +# Set defaults for every output file +$Umask 0022 + +module( + load="builtin:omfile" + Template="RSYSLOG_TraditionalFileFormat" + FileCreateMode="0644" + DirCreateMode="0755" +) -#### RULES #### - -auth,authpriv.* /var/log/auth.log -*.*;auth,authpriv.none -/var/log/syslog - -daemon.* -/var/log/daemon.log -user.* -/var/log/user.log - -# Log kernel stuff -kern.* -/var/log/kern.log - -# Log all the mail messages in one place. -mail.* -/var/log/mail.log - -# Log cron stuff -cron.* /var/log/cron.log - -# -# Logging for the mail system. Split it up so that -# it is easy to write scripts to parse these files. -# -mail.info -/var/log/mail.info -mail.warn -/var/log/mail.warn -mail.err /var/log/mail.err - -# Logging for INN news system -# -news.crit /var/log/news/news.crit -news.err /var/log/news/news.err -news.notice -/var/log/news/news.notice - -# -# Some `catch-all' logfiles. -# -*.=debug;\ - auth,authpriv.none;\ - news.none;mail.none -/var/log/debug -*.=info;*.=notice;*.=warn;\ - auth,authpriv.none;\ - cron,daemon.none;\ - mail,news.none -/var/log/messages - -# Emergencies are sent to everybody logged in. -# -*.emerg * - +# Include all conf files in /etc/rsyslog.d/ +$IncludeConfig /etc/rsyslog.d/*.conf diff --git a/system/base/rsyslog/files/rsyslog.logrotate b/system/base/rsyslog/files/rsyslog.logrotate index 640a16cc..1eae30e0 100644 --- a/system/base/rsyslog/files/rsyslog.logrotate +++ b/system/base/rsyslog/files/rsyslog.logrotate @@ -1,6 +1,37 @@ -/var/log/messages /var/log/mail.log /var/log/cron.log { - sharedscripts - postrotate - /bin/kill -HUP `cat /run/syslogd.pid 2> /dev/null` 2> /dev/null || true - endscript +# Uncomment the following directive if you have re-enabled +# "/var/log/syslog" in "/etc/rsyslog.d/50-default.conf" +#/var/log/syslog +#{ +# rotate 7 +# daily +# missingok +# notifempty +# delaycompress +# compress +# postrotate +# test -r /run/rsyslogd.pid && kill -HUP $(cat /run/rsyslogd.pid) &>/dev/null +# endscript +#} + +/var/log/auth.log +/var/log/cron.log +/var/log/daemon.log +/var/log/kern.log +/var/log/lpr.log +/var/log/mail.log +/var/log/news.log +/var/log/user.log +/var/log/debug.log +/var/log/messages +{ + rotate 4 + weekly + missingok + notifempty + compress + delaycompress + sharedscripts + postrotate + test -r /run/rsyslogd.pid && kill -HUP $(cat /run/rsyslogd.pid) &>/dev/null + endscript } diff --git a/system/base/rsyslog/files/rsyslog.sysconfig b/system/base/rsyslog/files/rsyslog.sysconfig index 6f10db83..d8cbe875 100644 --- a/system/base/rsyslog/files/rsyslog.sysconfig +++ b/system/base/rsyslog/files/rsyslog.sysconfig @@ -1,5 +1,30 @@ -# Options to syslogd -# syslogd options are deprecated since rsyslog v3 -# if you want to use them, switch to compatibility mode 2 by "-c 2" -SYSLOGD_OPTIONS="-c 4" +# /etc/conf.d/rsyslog +# Configuration file +RSYSLOG_CONFIGFILE="/etc/rsyslog.conf" + +# PID file +# If you should ever change this, remember to update +# "/etc/logrotate.d/rsyslog", too. +RSYSLOG_PIDFILE="/run/rsyslogd.pid" + +# You can use this configuration option to pass additional options to the +# start-stop-daemon, see start-stop-daemon(8) for more details. +# Per default we wait 1000ms after we have started the service to ensure +# that the daemon is really up and running. +RSYSLOG_SSDARGS="--wait 1000" + +# The termination timeout (start-stop-daemon parameter "retry") ensures +# that the service will be terminated within a given time (60 + 5 seconds +# per default) when you are stopping the service. +# You need to increase the value when you are working with a large queue. +# See http://www.rsyslog.com/doc/queues.html for further information. +RSYSLOG_TERMTIMEOUT="TERM/60/KILL/5" + + +# Options to rsyslogd +# See rsyslogd(8) for more details +# Notes: +# * Do not specify another PIDFILE but use the variable above to change the location +# * Do not specify another CONFIGFILE but use the variable above to change the location +RSYSLOG_OPTS="" diff --git a/system/base/rsyslog/pspec.xml b/system/base/rsyslog/pspec.xml index 53707d4f..8c118646 100644 --- a/system/base/rsyslog/pspec.xml +++ b/system/base/rsyslog/pspec.xml @@ -12,7 +12,7 @@ service Enhanced system logging and kernel message trapping daemons rsyslog is an enhanced multi-threaded syslogd supporting, among others, MySQL, syslog/tcp, RFC 3195, permitted sender lists, filtering on any message part, and fine grain output format control. It is quite compatible with stock sysklogd and can be used as a drop-in replacement. - http://www.rsyslog.com/files/download/rsyslog/rsyslog-7.6.3.tar.gz + http://www.rsyslog.com/files/download/rsyslog/rsyslog-8.9.0.tar.gz zlib-devel json-c-devel @@ -28,7 +28,6 @@ zlib json-c libestr - libuuid libgcrypt liblogging @@ -39,11 +38,13 @@ /usr/share/doc /etc/logrotate.d /etc/conf.d + /etc/rsyslog.d /etc/rsyslog.conf rsyslog.logrotate rsyslog.conf + 50-default.conf rsyslog.sysconfig @@ -52,6 +53,13 @@ + + 2015-05-05 + 8.9.0 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 7.6.3 diff --git a/system/base/run-parts/pspec.xml b/system/base/run-parts/pspec.xml index bd29e759..efd312a8 100644 --- a/system/base/run-parts/pspec.xml +++ b/system/base/run-parts/pspec.xml @@ -9,7 +9,7 @@ GPLv2+ run scripts or programs in a directory run scripts or programs in a directory - ftp://ftp.archlinux.org/other/run-parts/debianutils_4.4.tar.gz + https://sources.archlinux.org/other/run-parts/debianutils_4.4.tar.gz @@ -23,9 +23,9 @@ - 2014-05-11 + 2015-04-11 4.4 - Release bump. + Release bump, fix source url Marcin Bojara marcin@pisilinux.org diff --git a/system/base/shadow/actions.py b/system/base/shadow/actions.py index a5881c7d..66287e9d 100644 --- a/system/base/shadow/actions.py +++ b/system/base/shadow/actions.py @@ -12,7 +12,7 @@ from pisi.actionsapi import get def setup(): autotools.configure("--enable-shadowgrp \ --without-selinux \ - --with-audit \ + --without-audit \ --without-libcrack \ --with-libpam \ --with-sha-crypt \ diff --git a/system/base/shadow/pspec.xml b/system/base/shadow/pspec.xml index 8dd7093b..4e2f9463 100644 --- a/system/base/shadow/pspec.xml +++ b/system/base/shadow/pspec.xml @@ -15,9 +15,8 @@ http://pkg-shadow.alioth.debian.org/releases/shadow-4.2.1.tar.xz pam-devel - audit-devel gettext-devel - skey-devel + shadow-strncpy-usage.patch @@ -31,7 +30,6 @@ acl attr pam - audit /bin @@ -71,9 +69,9 @@ - 2014-12-13 + 2015-04-01 4.2.1 - Version bump. + Version bump., remove build with audit Yusuf Aydemir yusuf.aydemir@pisilinux.org diff --git a/system/base/snappy/pspec.xml b/system/base/snappy/pspec.xml index 57fdf76b..a677d2ba 100755 --- a/system/base/snappy/pspec.xml +++ b/system/base/snappy/pspec.xml @@ -14,6 +14,7 @@ Snappy is a compression/decompression library. It does not aim for maximum compression, or compatibility with any other compression library; instead, it aims for very high speeds and reasonable compression. lzo-devel + zlib-devel http://snappy.googlecode.com/files/snappy-1.1.1.tar.gz @@ -22,6 +23,9 @@ snappy + + libgcc + /usr/lib /usr/share/doc diff --git a/system/base/spidermonkey/pspec.xml b/system/base/spidermonkey/pspec.xml index ed040c7c..2fe96352 100644 --- a/system/base/spidermonkey/pspec.xml +++ b/system/base/spidermonkey/pspec.xml @@ -17,6 +17,7 @@ zlib-devel nspr-devel readline-devel + libffi-devel @@ -53,6 +54,13 @@ + + 2015-05-08 + 17.0.0 + Rebuild. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 17.0.0 diff --git a/system/base/sqlite/actions.py b/system/base/sqlite/actions.py index 3f58c4bb..3266033d 100644 --- a/system/base/sqlite/actions.py +++ b/system/base/sqlite/actions.py @@ -13,23 +13,45 @@ from pisi.actionsapi import get # but cannot be seen with sqlite query. However, it can be seen by opening the file with a text editor. # SQLITE_SECURE_DELETE overwrites written data with zeros. def setup(): - pisitools.cflags.add("-DSQLITE_SECURE_DELETE=1", - "-DSQLITE_ENABLE_UNLOCK_NOTIFY=1", - "-DSQLITE_ENABLE_COLUMN_METADATA=1", - "-DSQLITE_DISABLE_DIRSYNC=1", - "-DSQLITE_ENABLE_FTS3=3", - "-DSQLITE_ENABLE_RTREE=1", - "-DNDEBUG=1", - "-fno-strict-aliasing") + pisitools.cflags.add("-DSQLITE_SECURE_DELETE", + "-DSQLITE_ENABLE_UNLOCK_NOTIFY", + "-DSQLITE_ENABLE_COLUMN_METADATA", + "-DSQLITE_DISABLE_DIRSYNC", + "-DSQLITE_ENABLE_FTS3", + "-DSQLITE_ENABLE_FTS4", + "-DSQLITE_ENABLE_FTS3_PARENTHESIS", + "-DSQLITE_ENABLE_STMT_SCANSTATUS", + "-DSQLITE_SOUNDEX", + "-DSQLITE_ENABLE_RTREE", + "-DSQLITE_ENABLE_API_ARMOR") + pisitools.cflags.sub("-O[s\d]", "-O3") + autotools.configure("--disable-static \ --enable-readline \ --enable-threadsafe") - + + shelltools.cd("tea") + autotools.configure(" \ + --enable-shared \ + --with-tcl='/usr/lib/' \ + --with-tclinclude='/usr/include' \ + --enable-64bit \ + --enable-threads") + + #pisitools.dosed("libtool", " -shared ", " -Wl,-O1,--as-needed -shared ") + def build(): autotools.make() - + + shelltools.cd("tea") + autotools.make() + def install(): autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + + shelltools.cd("%s/sqlite-autoconf-3080803/tea" % get.workDIR()) + autotools.rawInstall("DESTDIR=%s" % get.installDIR()) + pisitools.dodoc("README*") diff --git a/system/base/sqlite/pspec.xml b/system/base/sqlite/pspec.xml index d8b200e2..61abdd95 100644 --- a/system/base/sqlite/pspec.xml +++ b/system/base/sqlite/pspec.xml @@ -12,7 +12,8 @@ library An SQL Database Engine in a C Library SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine. Supports databases up to 2 terabytes in size. - http://www.sqlite.org/2014/sqlite-autoconf-3080702.tar.gz + http://www.sqlite.org/2015/sqlite-autoconf-3080803.tar.gz + http://www.sqlite.org/2015/sqlite-doc-3080803.zip readline-devel @@ -50,16 +51,54 @@ emul32 32-bit shared libraries for sqlite emul32 + + glibc-32bit + sqlite + glibc-32bit /usr/lib32 + + + sqlite-tcl + + tcl-devel + + + sqlite + + + /usr/lib/sqlite3.8.8.3 + + + + + sqlite-tcl-32bit + + glibc-32bit + + + sqlite + glibc-32bit + + + /usr/lib32/sqlite3.8.8.3/ + + - + + 2015-02-28 + 3.8.8.3 + Version bump. + Vedat Demir + vedat@pisilinux.org + + 2015-01-31 3.8.8.2 Version bump. diff --git a/system/base/timezone/actions.py b/system/base/timezone/actions.py index 9b072dd9..6a6114ff 100644 --- a/system/base/timezone/actions.py +++ b/system/base/timezone/actions.py @@ -10,6 +10,7 @@ from pisi.actionsapi import shelltools from pisi.actionsapi import get WorkDir = "." + ZoneDir = "/usr/share/zoneinfo" TargetDir = "%s/%s" % (get.installDIR(), ZoneDir) @@ -18,8 +19,8 @@ PosixDir = "%s/posix" % TargetDir timezones = ["etcetera", "southamerica", "northamerica", "europe", "africa", "antarctica", \ - "asia", "australasia", "factory", "backward", "pacificnew", \ - "systemv" ] + "asia", "australasia", "factory", "backward", "pacificnew", \ + "systemv" ] def setup(): pisitools.dodir (ZoneDir) @@ -38,7 +39,9 @@ def install(): shelltools.system (part2) part3 = "zic -L leapseconds -d %s -y \"%s/yearistype.sh\" %s" % (RightDir, get.workDIR(), tzdata) shelltools.system (part3) + shelltools.system ("zic -d %s -y \"%s/yearistype.sh\" %s -p Europe/Istanbul" % (TargetDir, get.workDIR(), tzdata)) - shelltools.system ("zic -d %s -p Europe/Istanbul" % TargetDir) + #shelltools.system ("zic -d %s -p Europe/Istanbul" % TargetDir) + diff --git a/system/base/timezone/files/timezone-data-2015c-makefile.patch b/system/base/timezone/files/timezone-data-2015c-makefile.patch new file mode 100644 index 00000000..082cf648 --- /dev/null +++ b/system/base/timezone/files/timezone-data-2015c-makefile.patch @@ -0,0 +1,86 @@ + - Fix up default paths + - Support env CC + - Don't build/install libtz.a + - Don't install man-pages provided by sys-apps/man-pages + - Move zic, zdump to sbin and tzselect to bin ala glibc + - Do not run network based unittests + +--- a/Makefile ++++ b/Makefile +@@ -45,21 +45,21 @@ POSIXRULES= America/New_York + + # Everything gets put in subdirectories of. . . + +-TOPDIR= /usr/local ++TOPDIR= /usr + + # "Compiled" time zone information is placed in the "TZDIR" directory + # (and subdirectories). + # Use an absolute path name for TZDIR unless you're just testing the software. + + TZDIR_BASENAME= zoneinfo +-TZDIR= $(TOPDIR)/etc/$(TZDIR_BASENAME) ++TZDIR= $(TOPDIR)/share/$(TZDIR_BASENAME) + + # Types to try, as an alternative to time_t. int64_t should be first. + TIME_T_ALTERNATIVES= int64_t int32_t uint32_t uint64_t + + # The "tzselect", "zic", and "zdump" commands get installed in. . . + +-ETCDIR= $(TOPDIR)/etc ++SBINDIR= $(TOPDIR)/sbin + + # If you "make INSTALL", the "date" command gets installed in. . . + +@@ -67,7 +67,7 @@ BINDIR= $(TOPDIR)/bin + + # Manual pages go in subdirectories of. . . + +-MANDIR= $(TOPDIR)/man ++MANDIR= $(TOPDIR)/share/man + + # Library functions are put in an archive in LIBDIR. + +@@ -298,8 +298,10 @@ GZIPFLAGS= -9n + + ############################################################################### + +-cc= cc +-CC= $(cc) -DTZDIR=\"$(TZDIR)\" ++CPPFLAGS+= -DTZDIR=\"$(TZDIR)\" ++ifeq ($(NLS),1) ++CPPFLAGS+= -DHAVE_GETTEXT=1 -DTZ_DOMAIN=\"libc\" ++endif + + AR= ar + +@@ -352,17 +354,14 @@ ALL: all date + install: all $(DATA) $(REDO) $(MANS) + mkdir -p $(DESTDIR)$(ETCDIR) $(DESTDIR)$(TZDIR) \ +- $(DESTDIR)$(LIBDIR) \ ++ $(DESTDIR)$(SBINDIR) $(DESTDIR)$(BINDIR) \ + $(DESTDIR)$(MANDIR)/man3 $(DESTDIR)$(MANDIR)/man5 \ + $(DESTDIR)$(MANDIR)/man8 + $(ZIC) -y $(YEARISTYPE) \ + -d $(DESTDIR)$(TZDIR) -l $(LOCALTIME) -p $(POSIXRULES) + cp -f iso3166.tab $(ZONETABLES) $(DESTDIR)$(TZDIR)/. +- cp tzselect zic zdump $(DESTDIR)$(ETCDIR)/. ++ cp zic zdump $(DESTDIR)$(SBINDIR)/. ++ cp tzselect $(DESTDIR)$(BINDIR)/. +- cp libtz.a $(DESTDIR)$(LIBDIR)/. +- $(RANLIB) $(DESTDIR)$(LIBDIR)/libtz.a + cp -f newctime.3 newtzset.3 $(DESTDIR)$(MANDIR)/man3/. +- cp -f tzfile.5 $(DESTDIR)$(MANDIR)/man5/. +- cp -f tzselect.8 zdump.8 zic.8 $(DESTDIR)$(MANDIR)/man8/. + + INSTALL: ALL install date.1 + mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1 +@@ -440,7 +442,7 @@ tzselect: tzselect.ksh + chmod +x $@ + + check: check_character_set check_white_space check_links check_sorted \ +- check_tables check_web ++ check_tables + + check_character_set: $(ENCHILADA) + LC_ALL=en_US.utf8 && export LC_ALL && \ diff --git a/system/base/timezone/pspec.xml b/system/base/timezone/pspec.xml index 50a4cede..15c8cc03 100644 --- a/system/base/timezone/pspec.xml +++ b/system/base/timezone/pspec.xml @@ -14,11 +14,18 @@ data Timezone data files and tools timezone includes timezone data files and tools to use them. Package contents are synchronized with glibc tree. - http://www.iana.org/time-zones/repository/releases/tzdata2014b.tar.gz + http://www.iana.org/time-zones/repository/releases/tzdata2015d.tar.gz + perl gawk + + timezone-data-2015c-makefile.patch + + + + @@ -29,6 +36,13 @@ + + 2015-05-09 + 2015d + Version bump. + Vedat Demir + vedat@pisilinux.org + 2014-05-11 2014b diff --git a/system/base/udev/pspec.xml b/system/base/udev/pspec.xml index 439be79e..ffb1ae86 100644 --- a/system/base/udev/pspec.xml +++ b/system/base/udev/pspec.xml @@ -14,11 +14,11 @@ udev allows Linux users to have a dynamic /dev directory and it provides the ability to have persistent device names. http://www.freedesktop.org/software/systemd/systemd-214.tar.xz - glib2 + glib2-devel gperf acl-devel libkmod-devel - libblkid-devel + libutil-linux-devel @@ -28,7 +28,7 @@ libudev acl libkmod - libblkid + libutil-linux util-linux @@ -138,7 +138,7 @@ emul32 libkmod-32bit - libblkid-32bit + libutil-linux-32bit libudev @@ -169,7 +169,7 @@ - 2014-07-01 + 2015-05-01 214 Version bump. Marcin Bojara diff --git a/system/base/util-linux/actions.py b/system/base/util-linux/actions.py index 87b0073d..048f4bea 100644 --- a/system/base/util-linux/actions.py +++ b/system/base/util-linux/actions.py @@ -58,14 +58,13 @@ def setup(): options += "\ --bindir=/bin \ --sbindir=/sbin \ - --enable-static \ --enable-partx \ --enable-raw \ --enable-write \ --enable-tunelp \ - --with-audit \ + --without-audit \ --with-udev \ - --with-utempter \ + --without-utempter \ " autotools.autoreconf("-fi") @@ -87,5 +86,7 @@ def install(): if get.buildTYPE() == "emul32": return + #pisitools.removeDir("/usr/lib32/pkgconfig") + pisitools.dodoc("ABOUT-NLS", "AUTHORS", "ChangeLog", "COPYING", "README*") pisitools.insinto("/%s/%s" % (get.docDIR(), get.srcNAME()), "Documentation") diff --git a/system/base/util-linux/files/uuidd.tmpfiles b/system/base/util-linux/files/uuidd.tmpfiles new file mode 100644 index 00000000..d4bf4f75 --- /dev/null +++ b/system/base/util-linux/files/uuidd.tmpfiles @@ -0,0 +1 @@ +d /run/uuidd 0755 root root diff --git a/system/base/util-linux/pspec.xml b/system/base/util-linux/pspec.xml index 4581aa9e..fb4f5424 100644 --- a/system/base/util-linux/pspec.xml +++ b/system/base/util-linux/pspec.xml @@ -13,38 +13,41 @@ library Various useful Linux utilities The util-linux package contains a large variety of low-level system utilities that are necessary for a Linux system to function. - http://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.1.tar.xz + https://www.kernel.org/pub/linux/utils/util-linux/v2.26/util-linux-2.26.1.tar.xz - zlib - audit + zlib-devel + eudev-devel + python-devel shadow - ncurses + ncurses-devel libcap-ng-devel - utempter-devel + glibc-32bit + - ntfs-3g.patch + - upstream/util-linux-ng-2.21-login-lastlog.patch - + upstream/util-linux-ng-2.21-login-lastlog.patch + util-linux - libuuid - libblkid + libutil-linux zlib perl - audit ncurses - libudev - utempter + eudev + libcap-ng + + util-linux + /etc /bin @@ -58,9 +61,6 @@ /usr/share/getopt /usr/share/bash-completion/completions /usr/share/locale - /usr/include - /usr/lib - /lib @@ -71,101 +71,107 @@ util.misc Helper daemon to guarantee uniqueness of time-based UUIDs - libuuid + libutil-linux + + uuidd + /usr/bin/uuidgen /usr/sbin/uuidd + /usr/lib/tmpfiles.d/uuidd.conf /usr/share/man/man1/uuidgen.1 /usr/share/man/man8/uuidd.8 + + uuidd.tmpfiles + - libuuid + libutil-linux library - A library for UUID processing + util-linux runtime library + + python + + + libblkid + libuuid + + + libblkid + libuuid + + /lib + /usr/lib /usr/share/man/man3/uuid* - /lib/libuuid.* - /usr/lib/libuuid.so - - - - - libuuid-devel - header - system.devel - libuuid header files - - libuuid - - - /usr/include/uuid/* - /usr/lib/pkgconfig/ - /usr/lib32/pkgconfig/uuid.pc - /usr/lib32/pkgconfig/blkid.pc - - - - - libblkid - library - A library for block device identifying - - libuuid - - /usr/share/man/man3/libblkid* /usr/share/man/man8/blkid* - /lib/libblkid.* - /usr/lib/libblkid.so + - libblkid-devel + libutil-linux-devel header system.devel - libblkid header files + libutil-linux header files - libblkid + libutil-linux + + libblkid-devel + libuuid-devel + + + libblkid-devel + libuuid-devel + - /usr/include/blkid/* - /usr/lib/pkgconfig/blkid.pc + /usr/include/ + /usr/lib/pkgconfig/*.pc - libuuid-32bit + libutil-linux-32bit emul32 - 32-bit shared libraries for libuuid + 32-bit shared libraries for libutil-linux emul32 - libuuid + glibc-32bit + + libblkid-32bit + libuuid-32bit + + + libblkid-32bit + libuuid-32bit + - /usr/lib32/libuuid.* - - - - - libblkid-32bit - emul32 - 32-bit shared libraries for libblkid - emul32 - - libblkid - libuuid-32bit - - - /usr/lib32/libblkid.* + /usr/lib32/ + + 2015-04-29 + 2.26.1 + Version bump, change pisi + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2015-04-01 + 2.26.1 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 2.24.1 diff --git a/system/base/util-linux/pspec.xml.new b/system/base/util-linux/pspec.xml.new new file mode 100644 index 00000000..aefea02f --- /dev/null +++ b/system/base/util-linux/pspec.xml.new @@ -0,0 +1,236 @@ + + + + + util-linux + http://userweb.kernel.org/~kzak/util-linux-ng/ + + PisiLinux Community + admins@pisilinux.org + + GPLv2 + app:console + library + Various useful Linux utilities + The util-linux package contains a large variety of low-level system utilities that are necessary for a Linux system to function. + https://www.kernel.org/pub/linux/utils/util-linux/v2.26/util-linux-2.26.1.tar.xz + + zlib-devel + udev-devel + python-devel + libudev-devel + shadow + ncurses-devel + libcap-ng-devel + glibc-32bit + + + + + + upstream/util-linux-ng-2.21-login-lastlog.patch + + + + + util-linux + + libuuid + libblkid + zlib + perl + python + ncurses + libudev + + libcap-ng + + + /etc + /bin + /sbin + /usr/bin + /usr/sbin + /usr/share/doc + /usr/share/man + /usr/share/info + /usr/share/misc + /usr/share/getopt + /usr/share/bash-completion/completions + /usr/share/locale + /usr/include + /usr/lib + /lib + + + + + + uuidd + service + app:console + util.misc + Helper daemon to guarantee uniqueness of time-based UUIDs + + libuuid + + + + /usr/bin/uuidgen + /usr/sbin/uuidd + /usr/lib/tmpfiles.d/uuidd.conf + /usr/share/man/man1/uuidgen.1 + /usr/share/man/man8/uuidd.8 + + + uuidd.tmpfiles + + + + + libuuid + library + A library for UUID processing + + /usr/share/man/man3/uuid* + /lib/libuuid.* + /usr/lib/libuuid.so + + + + + libuuid-devel + header + system.devel + libuuid header files + + libuuid + + + /usr/include/uuid/* + /usr/lib/pkgconfig/ + /usr/lib32/pkgconfig/uuid.pc + + + + + libblkid + library + A library for block device identifying + + libuuid + + + /usr/share/man/man3/libblkid* + /usr/share/man/man8/blkid* + /lib/libblkid.* + /usr/lib/libblkid.so + + + + + libblkid-devel + header + system.devel + libblkid header files + + libblkid + + + /usr/include/blkid/* + /usr/lib/pkgconfig/blkid.pc + /usr/lib32/pkgconfig/blkid.pc + + + + + libuuid-32bit + emul32 + 32-bit shared libraries for libuuid + emul32 + + glibc-32bit + + + /usr/lib32/libuuid.* + + + + + libblkid-32bit + emul32 + 32-bit shared libraries for libblkid + emul32 + + libblkid + libuuid-32bit + libuuid + glibc-32bit + + + /usr/lib32/libblkid.* + + + + + + 2015-04-01 + 2.26.1 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + + + 2014-05-11 + 2.24.1 + Release bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-04-08 + 2.24.1 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2014-01-20 + 2.24 + Version bump. + Marcin Bojara + marcin@pisilinux.org + + + 2013-07-27 + 2.22.2 + Move pc files to devel pack, rebuild + PisiLinux Community + admins@pisilinux.org + + + 2013-07-26 + 2.22.2 + Release bump for rebuild. + PisiLinux Community + admins@pisilinux.org + + + 2013-01-14 + 2.22.2 + New release + PisiLinux Community + admins@pisilinux.org + + + 2012-11-17 + 2.22.1 + First release + Marcin Bojara + marcin@pisilinux.org + + + diff --git a/system/base/util-linux/translations.xml b/system/base/util-linux/translations.xml index 5f4eb08d..9554333c 100644 --- a/system/base/util-linux/translations.xml +++ b/system/base/util-linux/translations.xml @@ -8,13 +8,13 @@ - libuuid - UUID üretimi için bir kitaplık + libutil-linux + util-linux için kitaplıklar - + - libblkid - Disk tanımlama için bir kitaplık + libutil-linux-devel + util-linux kitaplıkları için başlık dosyaları @@ -23,7 +23,7 @@ - libuuid-32bit - libuuid için 32-bit paylaşımlı kitaplıklar + libutil-linux-32bit + util-linux için 32-bit paylaşımlı kitaplıklar diff --git a/system/base/vixie-cron/pspec.xml b/system/base/vixie-cron/pspec.xml index 72588a23..378bffc0 100644 --- a/system/base/vixie-cron/pspec.xml +++ b/system/base/vixie-cron/pspec.xml @@ -15,7 +15,7 @@ ftp://ftp.linux.org.tr/pub/gentoo/distfiles/vixie-cron-4.1.tar.bz2 sed - pam + pam-devel vixie-cron-4.1-gentoo-r4.patch.bz2 @@ -56,7 +56,7 @@ - 2014-05-11 + 2015-05-04 4.1 Release bump. Marcin Bojara diff --git a/system/base/which/pspec.xml b/system/base/which/pspec.xml index 8c8903e4..ddac1e8d 100644 --- a/system/base/which/pspec.xml +++ b/system/base/which/pspec.xml @@ -12,9 +12,9 @@ app:console Prints the location of specified executable in your path which , Locates a program file in the user's path. - mirrors://gnu/which/which-2.20.tar.gz + mirrors://gnu/which/which-2.21.tar.gz - which-gentoo.patch + @@ -29,6 +29,13 @@ + + 2015-04-06 + 2.21 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + 2014-05-11 2.20 diff --git a/system/base/wireless-tools/pspec.xml b/system/base/wireless-tools/pspec.xml index ad8aac31..a4bad7fb 100644 --- a/system/base/wireless-tools/pspec.xml +++ b/system/base/wireless-tools/pspec.xml @@ -12,7 +12,7 @@ app:console A collection of tools to configure wireless lan cards The Wireless Tools (WT) is a set of tools allowing to manipulate the Wireless Extensions, a generic application programming interface allowing a driver to expose to the user space configuration and statistics specific to common Wireless LANs. They use a textual interface and are rather crude, but aim to support the full Wireless Extension. - http://svn.mandriva.com/svn/packages/cooker/wireless-tools/current/SOURCES/wireless_tools.30.pre9.tar.gz + http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/wireless_tools.30.pre9.tar.gz no-ldconfig.patch wireless_tools.27-wireless-man-upd.patch @@ -49,6 +49,13 @@ + + 2015-05-08 + 30 + Release bump. + Vedat Demir + vedat@pisilinux.org + 2014-05-11 30 diff --git a/system/base/xz/pspec.xml b/system/base/xz/pspec.xml index 6288a2ec..81181d20 100644 --- a/system/base/xz/pspec.xml +++ b/system/base/xz/pspec.xml @@ -15,7 +15,7 @@ library XZ compression utilities XZ Utils provide a general purpose data compression library and command line tools. The .xz format supports multiple compression algorithms, which are called "filters" in context of XZ Utils. The primary filter is currently LZMA2. - http://tukaani.org/xz/xz-5.0.7.tar.gz + http://tukaani.org/xz/xz-5.2.1.tar.xz @@ -48,7 +48,11 @@ emul32 32bit shared libraries for xz emul32 + + glibc-32bit + + glibc-32bit xz @@ -57,6 +61,13 @@ + + 2015-03-08 + 5.2.1 + Version bump. + Serdar Soytetir + kaptan@pisilinux.org + 2014-10-01 5.0.7 diff --git a/system/base/zlib/pspec.xml b/system/base/zlib/pspec.xml index 43f1191f..b9d4a5bf 100644 --- a/system/base/zlib/pspec.xml +++ b/system/base/zlib/pspec.xml @@ -79,7 +79,11 @@ emul32 32-bit shared libraries for zlib emul32 + + glibc-32bit + + glibc-32bit zlib diff --git a/system/boot/component.xml b/system/boot/component.xml new file mode 100644 index 00000000..6b85d682 --- /dev/null +++ b/system/boot/component.xml @@ -0,0 +1,3 @@ + + system.boot + diff --git a/system/base/grub2/actions.py b/system/boot/grub2/actions.py similarity index 100% rename from system/base/grub2/actions.py rename to system/boot/grub2/actions.py diff --git a/system/base/grub2/files/grub-defaults b/system/boot/grub2/files/grub-defaults similarity index 100% rename from system/base/grub2/files/grub-defaults rename to system/boot/grub2/files/grub-defaults diff --git a/system/base/grub2/files/grub-defaults.orig b/system/boot/grub2/files/grub-defaults.orig similarity index 100% rename from system/base/grub2/files/grub-defaults.orig rename to system/boot/grub2/files/grub-defaults.orig diff --git a/system/base/grub2/files/mkconfig-fix.patch b/system/boot/grub2/files/mkconfig-fix.patch similarity index 100% rename from system/base/grub2/files/mkconfig-fix.patch rename to system/boot/grub2/files/mkconfig-fix.patch diff --git a/system/base/grub2/files/pisi-grub-bg.png b/system/boot/grub2/files/pisi-grub-bg.png similarity index 100% rename from system/base/grub2/files/pisi-grub-bg.png rename to system/boot/grub2/files/pisi-grub-bg.png diff --git a/system/base/grub2/files/pisi_name_and_initramfs.patch b/system/boot/grub2/files/pisi_name_and_initramfs.patch similarity index 100% rename from system/base/grub2/files/pisi_name_and_initramfs.patch rename to system/boot/grub2/files/pisi_name_and_initramfs.patch diff --git a/system/base/grub2/pspec.xml b/system/boot/grub2/pspec.xml similarity index 99% rename from system/base/grub2/pspec.xml rename to system/boot/grub2/pspec.xml index bf2b58a4..0c2c026c 100644 --- a/system/base/grub2/pspec.xml +++ b/system/boot/grub2/pspec.xml @@ -26,6 +26,7 @@ help2man texinfo freetype-devel + freetype zlib-devel ncurses-devel xz-devel diff --git a/system/base/grub2/translations.xml b/system/boot/grub2/translations.xml similarity index 100% rename from system/base/grub2/translations.xml rename to system/boot/grub2/translations.xml diff --git a/system/devel/autogen/actions.py b/system/devel/autogen/actions.py index d6c65b12..14f603ab 100644 --- a/system/devel/autogen/actions.py +++ b/system/devel/autogen/actions.py @@ -13,6 +13,8 @@ from pisi.actionsapi import get def setup(): autotools.autoreconf("-vfi") autotools.configure("--disable-static") + + pisitools.dosed("libtool", " -shared ", " -Wl,-O1,--as-needed -shared ") def build(): autotools.make() diff --git a/system/devel/autogen/pspec.xml b/system/devel/autogen/pspec.xml index b3284e8c..e146e5a5 100644 --- a/system/devel/autogen/pspec.xml +++ b/system/devel/autogen/pspec.xml @@ -14,8 +14,11 @@ autogen is a tool designed to simplify the creation and maintenance of programs that contain large amounts of repetitious text. ftp://ftp.gnu.org/gnu/autogen/rel5.18.4/autogen-5.18.4.tar.xz + gc-devel + gmp-devel guile-devel libxml2-devel + which diff --git a/system/devel/binutils/actions.py b/system/devel/binutils/actions.py index 66cb3ba9..6d35e26f 100644 --- a/system/devel/binutils/actions.py +++ b/system/devel/binutils/actions.py @@ -78,6 +78,6 @@ def install(): for i in unneeded_man: pisitools.remove("/usr/share/man/man1/%s" %i) - pisitools.remove("/usr/share/info/configure.info") - pisitools.remove("/usr/share/info/standards.info") + #pisitools.remove("/usr/share/info/configure.info") + #pisitools.remove("/usr/share/info/standards.info") diff --git a/system/devel/binutils/files/binutils-2.24-gold-testsuite-plugin.patch b/system/devel/binutils/files/binutils-2.24-gold-testsuite-plugin.patch index 43302a42..9f5acad6 100644 --- a/system/devel/binutils/files/binutils-2.24-gold-testsuite-plugin.patch +++ b/system/devel/binutils/files/binutils-2.24-gold-testsuite-plugin.patch @@ -1,2888 +1,229 @@ - - - -svntogit/packages.git - Git clone of the 'packages' repository - - - - - - - -
    - -
    - -
    -
    -
    - - - -
    -summaryrefslogtreecommitdiffstats
    - - - -
    -
    -
    blob: 9f5acad662239ae07827cf009a51c92b7fc336d3 (plain) - - -
    1
    -2
    -3
    -4
    -5
    -6
    -7
    -8
    -9
    -10
    -11
    -12
    -13
    -14
    -15
    -16
    -17
    -18
    -19
    -20
    -21
    -22
    -23
    -24
    -25
    -26
    -27
    -28
    -29
    -30
    -31
    -32
    -33
    -34
    -35
    -36
    -37
    -38
    -39
    -40
    -41
    -42
    -43
    -44
    -45
    -46
    -47
    -48
    -49
    -50
    -51
    -52
    -53
    -54
    -55
    -56
    -57
    -58
    -59
    -60
    -61
    -62
    -63
    -64
    -65
    -66
    -67
    -68
    -69
    -70
    -71
    -72
    -73
    -74
    -75
    -76
    -77
    -78
    -79
    -80
    -81
    -82
    -83
    -84
    -85
    -86
    -87
    -88
    -89
    -90
    -91
    -92
    -93
    -94
    -95
    -96
    -97
    -98
    -99
    -100
    -101
    -102
    -103
    -104
    -105
    -106
    -107
    -108
    -109
    -110
    -111
    -112
    -113
    -114
    -115
    -116
    -117
    -118
    -119
    -120
    -121
    -122
    -123
    -124
    -125
    -126
    -127
    -128
    -129
    -130
    -131
    -132
    -133
    -134
    -135
    -136
    -137
    -138
    -139
    -140
    -141
    -142
    -143
    -144
    -145
    -146
    -147
    -148
    -149
    -150
    -151
    -152
    -153
    -154
    -155
    -156
    -157
    -158
    -159
    -160
    -161
    -162
    -163
    -164
    -165
    -166
    -167
    -168
    -169
    -170
    -171
    -172
    -173
    -174
    -175
    -176
    -177
    -178
    -179
    -180
    -181
    -182
    -183
    -184
    -185
    -186
    -187
    -188
    -189
    -190
    -191
    -192
    -193
    -194
    -195
    -196
    -197
    -198
    -199
    -200
    -201
    -202
    -203
    -204
    -205
    -206
    -207
    -208
    -209
    -210
    -211
    -212
    -213
    -214
    -215
    -216
    -217
    -218
    -219
    -220
    -221
    -222
    -223
    -224
    -225
    -226
    -227
    -228
    -229
    -
    diff --git a/gold/configure b/gold/configure
    +diff --git a/gold/configure b/gold/configure
     index 2257324..f61307b 100755
    ---- a/gold/configure
    -+++ b/gold/configure
    -@@ -594,10 +594,12 @@ LTLIBOBJS
    +--- a/gold/configure
    ++++ b/gold/configure
    +@@ -594,10 +594,12 @@ LTLIBOBJS
      MAINT
      MAINTAINER_MODE_FALSE
      MAINTAINER_MODE_TRUE
    --HAVE_PUBNAMES_FALSE
    --HAVE_PUBNAMES_TRUE
    +-HAVE_PUBNAMES_FALSE
    +-HAVE_PUBNAMES_TRUE
      DLOPEN_LIBS
      CXXCPP
    -+HAVE_NO_USE_LINKER_PLUGIN_FALSE
    -+HAVE_NO_USE_LINKER_PLUGIN_TRUE
    -+HAVE_PUBNAMES_FALSE
    -+HAVE_PUBNAMES_TRUE
    ++HAVE_NO_USE_LINKER_PLUGIN_FALSE
    ++HAVE_NO_USE_LINKER_PLUGIN_TRUE
    ++HAVE_PUBNAMES_FALSE
    ++HAVE_PUBNAMES_TRUE
      HAVE_ZLIB_FALSE
      HAVE_ZLIB_TRUE
      LIBOBJS
    -@@ -6991,6 +6993,50 @@ cat >>confdefs.h <<_ACEOF
    +@@ -6991,6 +6993,50 @@ cat >>confdefs.h <<_ACEOF
      _ACEOF
      
      
    -+save_CFLAGS="$CFLAGS"
    -+CFLAGS="$CFLAGS -Werror -gpubnames"
    -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    -+/* end confdefs.h.  */
    -+int i;
    -+_ACEOF
    -+if ac_fn_c_try_compile "$LINENO"; then :
    -+  have_pubnames=yes
    -+else
    -+  have_pubnames=no
    -+fi
    -+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    -+CFLAGS="$save_CFLAGS"
    -+ if test "$have_pubnames" = "yes"; then
    -+  HAVE_PUBNAMES_TRUE=
    -+  HAVE_PUBNAMES_FALSE='#'
    -+else
    -+  HAVE_PUBNAMES_TRUE='#'
    -+  HAVE_PUBNAMES_FALSE=
    -+fi
    -+
    -+
    -+save_CFLAGS="$CFLAGS"
    -+CFLAGS="$CFLAGS -Werror -fno-use-linker-plugin"
    -+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    -+/* end confdefs.h.  */
    -+int i;
    -+_ACEOF
    -+if ac_fn_c_try_compile "$LINENO"; then :
    -+  have_no_use_linker_plugin=yes
    -+else
    -+  have_no_use_linker_plugin=no
    -+fi
    -+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    -+CFLAGS="$save_CFLAGS"
    -+ if test "$have_no_use_linker_plugin" = "yes"; then
    -+  HAVE_NO_USE_LINKER_PLUGIN_TRUE=
    -+  HAVE_NO_USE_LINKER_PLUGIN_FALSE='#'
    -+else
    -+  HAVE_NO_USE_LINKER_PLUGIN_TRUE='#'
    -+  HAVE_NO_USE_LINKER_PLUGIN_FALSE=
    -+fi
    -+
    -+
    ++save_CFLAGS="$CFLAGS"
    ++CFLAGS="$CFLAGS -Werror -gpubnames"
    ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    ++/* end confdefs.h.  */
    ++int i;
    ++_ACEOF
    ++if ac_fn_c_try_compile "$LINENO"; then :
    ++  have_pubnames=yes
    ++else
    ++  have_pubnames=no
    ++fi
    ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    ++CFLAGS="$save_CFLAGS"
    ++ if test "$have_pubnames" = "yes"; then
    ++  HAVE_PUBNAMES_TRUE=
    ++  HAVE_PUBNAMES_FALSE='#'
    ++else
    ++  HAVE_PUBNAMES_TRUE='#'
    ++  HAVE_PUBNAMES_FALSE=
    ++fi
    ++
    ++
    ++save_CFLAGS="$CFLAGS"
    ++CFLAGS="$CFLAGS -Werror -fno-use-linker-plugin"
    ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    ++/* end confdefs.h.  */
    ++int i;
    ++_ACEOF
    ++if ac_fn_c_try_compile "$LINENO"; then :
    ++  have_no_use_linker_plugin=yes
    ++else
    ++  have_no_use_linker_plugin=no
    ++fi
    ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    ++CFLAGS="$save_CFLAGS"
    ++ if test "$have_no_use_linker_plugin" = "yes"; then
    ++  HAVE_NO_USE_LINKER_PLUGIN_TRUE=
    ++  HAVE_NO_USE_LINKER_PLUGIN_FALSE='#'
    ++else
    ++  HAVE_NO_USE_LINKER_PLUGIN_TRUE='#'
    ++  HAVE_NO_USE_LINKER_PLUGIN_FALSE=
    ++fi
    ++
    ++
      ac_ext=cpp
      ac_cpp='$CXXCPP $CPPFLAGS'
    - ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    -@@ -7515,28 +7561,6 @@ $as_echo "#define HAVE_STAT_ST_MTIM 1" >>confdefs.h
    + ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    +@@ -7515,28 +7561,6 @@ $as_echo "#define HAVE_STAT_ST_MTIM 1" >>confdefs.h
      
      fi
      
    --save_CXXFLAGS="$CXXFLAGS"
    --CXXFLAGS="$CXXFLAGS -Werror -gpubnames"
    --cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    --/* end confdefs.h.  */
    --int i;
    --_ACEOF
    --if ac_fn_cxx_try_compile "$LINENO"; then :
    --  have_pubnames=yes
    --else
    --  have_pubnames=no
    --fi
    --rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    --CXXFLAGS="$save_CXXFLAGS"
    -- if test "$have_pubnames" = "yes"; then
    --  HAVE_PUBNAMES_TRUE=
    --  HAVE_PUBNAMES_FALSE='#'
    --else
    --  HAVE_PUBNAMES_TRUE='#'
    --  HAVE_PUBNAMES_FALSE=
    --fi
    --
    --
    +-save_CXXFLAGS="$CXXFLAGS"
    +-CXXFLAGS="$CXXFLAGS -Werror -gpubnames"
    +-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +-/* end confdefs.h.  */
    +-int i;
    +-_ACEOF
    +-if ac_fn_cxx_try_compile "$LINENO"; then :
    +-  have_pubnames=yes
    +-else
    +-  have_pubnames=no
    +-fi
    +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    +-CXXFLAGS="$save_CXXFLAGS"
    +- if test "$have_pubnames" = "yes"; then
    +-  HAVE_PUBNAMES_TRUE=
    +-  HAVE_PUBNAMES_FALSE='#'
    +-else
    +-  HAVE_PUBNAMES_TRUE='#'
    +-  HAVE_PUBNAMES_FALSE=
    +-fi
    +-
    +-
      ac_ext=c
      ac_cpp='$CPP $CPPFLAGS'
    - ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    -@@ -7837,6 +7861,10 @@ if test -z "${HAVE_PUBNAMES_TRUE}" && test -z "${HAVE_PUBNAMES_FALSE}"; then
    -   as_fn_error "conditional \"HAVE_PUBNAMES\" was never defined.
    - Usually this means the macro was only invoked conditionally." "$LINENO" 5
    + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    +@@ -7837,6 +7861,10 @@ if test -z "${HAVE_PUBNAMES_TRUE}" && test -z "${HAVE_PUBNAMES_FALSE}"; then
    +   as_fn_error "conditional \"HAVE_PUBNAMES\" was never defined.
    + Usually this means the macro was only invoked conditionally." "$LINENO" 5
      fi
    -+if test -z "${HAVE_NO_USE_LINKER_PLUGIN_TRUE}" && test -z "${HAVE_NO_USE_LINKER_PLUGIN_FALSE}"; then
    -+  as_fn_error "conditional \"HAVE_NO_USE_LINKER_PLUGIN\" was never defined.
    -+Usually this means the macro was only invoked conditionally." "$LINENO" 5
    -+fi
    - if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
    -   as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
    - Usually this means the macro was only invoked conditionally." "$LINENO" 5
    ++if test -z "${HAVE_NO_USE_LINKER_PLUGIN_TRUE}" && test -z "${HAVE_NO_USE_LINKER_PLUGIN_FALSE}"; then
    ++  as_fn_error "conditional \"HAVE_NO_USE_LINKER_PLUGIN\" was never defined.
    ++Usually this means the macro was only invoked conditionally." "$LINENO" 5
    ++fi
    + if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
    +   as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
    + Usually this means the macro was only invoked conditionally." "$LINENO" 5
     diff --git a/gold/configure.ac b/gold/configure.ac
     index 803cf46..7ad7302 100644
    ---- a/gold/configure.ac
    -+++ b/gold/configure.ac
    -@@ -520,6 +520,25 @@ dnl multiple declarations of functions like basename when compiling
    +--- a/gold/configure.ac
    ++++ b/gold/configure.ac
    +@@ -520,6 +520,25 @@ dnl multiple declarations of functions like basename when compiling
      dnl with C++.
      AC_CHECK_DECLS([basename, ffs, asprintf, vasprintf, snprintf, vsnprintf, strverscmp])
      
    -+dnl Check if gcc supports the -gpubnames option.
    -+dnl Use -Werror in case of compilers that make unknown -g options warnings.
    -+dnl They would pass the test here, but fail in actual use when $WARN_CFLAGS
    -+dnl gets set later by default Autoconf magic to include -Werror.  (We are
    -+dnl assuming here that there is no compiler that groks -gpubnames
    -+dnl but does not grok -Werror.)
    -+save_CFLAGS="$CFLAGS"
    -+CFLAGS="$CFLAGS -Werror -gpubnames"
    -+AC_COMPILE_IFELSE([int i;], [have_pubnames=yes], [have_pubnames=no])
    -+CFLAGS="$save_CFLAGS"
    -+AM_CONDITIONAL(HAVE_PUBNAMES, test "$have_pubnames" = "yes")
    -+
    -+dnl Check if gcc supports the -fno-use-linker-plugin option.
    -+save_CFLAGS="$CFLAGS"
    -+CFLAGS="$CFLAGS -Werror -fno-use-linker-plugin"
    -+AC_COMPILE_IFELSE([int i;], [have_no_use_linker_plugin=yes], [have_no_use_linker_plugin=no])
    -+CFLAGS="$save_CFLAGS"
    -+AM_CONDITIONAL(HAVE_NO_USE_LINKER_PLUGIN, test "$have_no_use_linker_plugin" = "yes")
    -+
    ++dnl Check if gcc supports the -gpubnames option.
    ++dnl Use -Werror in case of compilers that make unknown -g options warnings.
    ++dnl They would pass the test here, but fail in actual use when $WARN_CFLAGS
    ++dnl gets set later by default Autoconf magic to include -Werror.  (We are
    ++dnl assuming here that there is no compiler that groks -gpubnames
    ++dnl but does not grok -Werror.)
    ++save_CFLAGS="$CFLAGS"
    ++CFLAGS="$CFLAGS -Werror -gpubnames"
    ++AC_COMPILE_IFELSE([int i;], [have_pubnames=yes], [have_pubnames=no])
    ++CFLAGS="$save_CFLAGS"
    ++AM_CONDITIONAL(HAVE_PUBNAMES, test "$have_pubnames" = "yes")
    ++
    ++dnl Check if gcc supports the -fno-use-linker-plugin option.
    ++save_CFLAGS="$CFLAGS"
    ++CFLAGS="$CFLAGS -Werror -fno-use-linker-plugin"
    ++AC_COMPILE_IFELSE([int i;], [have_no_use_linker_plugin=yes], [have_no_use_linker_plugin=no])
    ++CFLAGS="$save_CFLAGS"
    ++AM_CONDITIONAL(HAVE_NO_USE_LINKER_PLUGIN, test "$have_no_use_linker_plugin" = "yes")
    ++
      AC_LANG_PUSH(C++)
      
      AC_CHECK_HEADERS(unordered_set unordered_map)
    -@@ -601,18 +620,6 @@ if test "$gold_cv_stat_st_mtim" = "yes"; then
    +@@ -601,18 +620,6 @@ if test "$gold_cv_stat_st_mtim" = "yes"; then
      	    [Define if struct stat has a field st_mtim with timespec for mtime])
      fi
      
    --dnl Check if gcc supports the -gpubnames option.
    --dnl Use -Werror in case of compilers that make unknown -g options warnings.
    --dnl They would pass the test here, but fail in actual use when $WARN_CFLAGS
    --dnl gets set later by default Autoconf magic to include -Werror.  (We are
    --dnl assuming here that there is no compiler that groks -gpubnames
    --dnl but does not grok -Werror.)
    --save_CXXFLAGS="$CXXFLAGS"
    --CXXFLAGS="$CXXFLAGS -Werror -gpubnames"
    --AC_COMPILE_IFELSE([int i;], [have_pubnames=yes], [have_pubnames=no])
    --CXXFLAGS="$save_CXXFLAGS"
    --AM_CONDITIONAL(HAVE_PUBNAMES, test "$have_pubnames" = "yes")
    --
    +-dnl Check if gcc supports the -gpubnames option.
    +-dnl Use -Werror in case of compilers that make unknown -g options warnings.
    +-dnl They would pass the test here, but fail in actual use when $WARN_CFLAGS
    +-dnl gets set later by default Autoconf magic to include -Werror.  (We are
    +-dnl assuming here that there is no compiler that groks -gpubnames
    +-dnl but does not grok -Werror.)
    +-save_CXXFLAGS="$CXXFLAGS"
    +-CXXFLAGS="$CXXFLAGS -Werror -gpubnames"
    +-AC_COMPILE_IFELSE([int i;], [have_pubnames=yes], [have_pubnames=no])
    +-CXXFLAGS="$save_CXXFLAGS"
    +-AM_CONDITIONAL(HAVE_PUBNAMES, test "$have_pubnames" = "yes")
    +-
      AC_LANG_POP(C++)
      
      AC_CHECK_HEADERS(locale.h)
     diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
     index aa41290..52cc05e 100644
    ---- a/gold/testsuite/Makefile.am
    -+++ b/gold/testsuite/Makefile.am
    -@@ -19,18 +19,25 @@ AM_CPPFLAGS = \
    - 	-DLOCALEDIR="\"$(datadir)/locale\"" \
    - 	@INCINTL@
    +--- a/gold/testsuite/Makefile.am
    ++++ b/gold/testsuite/Makefile.am
    +@@ -19,18 +19,25 @@ AM_CPPFLAGS = \
    + 	-DLOCALEDIR="\"$(datadir)/locale\"" \
    + 	@INCINTL@
      
    -+# Some versions of GCC now automatically enable linker plugins,
    -+# but we want to run our tests without GCC's plugins.
    -+if HAVE_NO_USE_LINKER_PLUGIN
    -+OPT_NO_PLUGINS = -fno-use-linker-plugin
    -+endif
    -+
    ++# Some versions of GCC now automatically enable linker plugins,
    ++# but we want to run our tests without GCC's plugins.
    ++if HAVE_NO_USE_LINKER_PLUGIN
    ++OPT_NO_PLUGINS = -fno-use-linker-plugin
    ++endif
    ++
      # COMPILE1, LINK1, CXXCOMPILE1, CXXLINK1 are renamed from COMPILE, LINK,
      # CXXCOMPILE and CXXLINK generated by automake 1.11.1.  FIXME: they should
      # be updated if they are different from automake used by gold.
      COMPILE1 = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
      	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
    --LINK1 = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
    -+LINK1 = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(OPT_NO_PLUGINS) \
    -+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
    +-LINK1 = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
    ++LINK1 = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(OPT_NO_PLUGINS) \
    ++	$(AM_LDFLAGS) $(LDFLAGS) -o $@
      CXXCOMPILE1 = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
      	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
    --CXXLINK1 = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
    --	-o $@
    -+CXXLINK1 = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(OPT_NO_PLUGINS) \
    -+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
    +-CXXLINK1 = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
    +-	-o $@
    ++CXXLINK1 = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(OPT_NO_PLUGINS) \
    ++	$(AM_LDFLAGS) $(LDFLAGS) -o $@
      
    --# Strip out -Wp,-D_FORTIFY_SOURCE=, which is rrelevant for the gold
    -+# Strip out -Wp,-D_FORTIFY_SOURCE=, which is irrelevant for the gold
    +-# Strip out -Wp,-D_FORTIFY_SOURCE=, which is rrelevant for the gold
    ++# Strip out -Wp,-D_FORTIFY_SOURCE=, which is irrelevant for the gold
      # testsuite and incompatible with -O0 used in gold tests, from
      # COMPILE, LINK, CXXCOMPILE and CXXLINK.
      COMPILE = `echo $(COMPILE1) | sed -e 's/-Wp,-D_FORTIFY_SOURCE=[0-9[0-9]]*//'`
     diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
     index 60c2c10..da0a338 100644
    ---- a/gold/testsuite/Makefile.in
    -+++ b/gold/testsuite/Makefile.in
    -@@ -2096,21 +2096,27 @@ AM_CPPFLAGS = \
    - 	@INCINTL@
    +--- a/gold/testsuite/Makefile.in
    ++++ b/gold/testsuite/Makefile.in
    +@@ -2096,21 +2096,27 @@ AM_CPPFLAGS = \
    + 	@INCINTL@
      
      
    -+# Some versions of GCC now automatically enable linker plugins,
    -+# but we want to run our tests without GCC's plugins.
    -+@HAVE_NO_USE_LINKER_PLUGIN_TRUE@OPT_NO_PLUGINS = -fno-use-linker-plugin
    -+
    ++# Some versions of GCC now automatically enable linker plugins,
    ++# but we want to run our tests without GCC's plugins.
    ++@HAVE_NO_USE_LINKER_PLUGIN_TRUE@OPT_NO_PLUGINS = -fno-use-linker-plugin
    ++
      # COMPILE1, LINK1, CXXCOMPILE1, CXXLINK1 are renamed from COMPILE, LINK,
      # CXXCOMPILE and CXXLINK generated by automake 1.11.1.  FIXME: they should
      # be updated if they are different from automake used by gold.
      COMPILE1 = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
      	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
      
    --LINK1 = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
    -+LINK1 = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(OPT_NO_PLUGINS) \
    -+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
    -+
    +-LINK1 = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
    ++LINK1 = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(OPT_NO_PLUGINS) \
    ++	$(AM_LDFLAGS) $(LDFLAGS) -o $@
    ++
      CXXCOMPILE1 = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
      	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
      
    --CXXLINK1 = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
    --	-o $@
    -+CXXLINK1 = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(OPT_NO_PLUGINS) \
    -+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
    +-CXXLINK1 = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
    +-	-o $@
    ++CXXLINK1 = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(OPT_NO_PLUGINS) \
    ++	$(AM_LDFLAGS) $(LDFLAGS) -o $@
      
      
    --# Strip out -Wp,-D_FORTIFY_SOURCE=, which is rrelevant for the gold
    -+# Strip out -Wp,-D_FORTIFY_SOURCE=, which is irrelevant for the gold
    +-# Strip out -Wp,-D_FORTIFY_SOURCE=, which is rrelevant for the gold
    ++# Strip out -Wp,-D_FORTIFY_SOURCE=, which is irrelevant for the gold
      # testsuite and incompatible with -O0 used in gold tests, from
      # COMPILE, LINK, CXXCOMPILE and CXXLINK.
      COMPILE = `echo $(COMPILE1) | sed -e 's/-Wp,-D_FORTIFY_SOURCE=[0-9[0-9]]*//'`
    -
    -
    -
    -

    Copyright © 2002-2014 Judd Vinet and Aaron Griffin. The Arch Linux name and logo -are recognized trademarks. Some rights reserved. The registered trademark -Linux® is used pursuant to a sublicense from LMI, the exclusive licensee -of Linus Torvalds, owner of the mark on a world-wide basis.

    -
    -
    - - diff --git a/system/devel/binutils/files/binutils-2.25-roundup.patch b/system/devel/binutils/files/binutils-2.25-roundup.patch new file mode 100644 index 00000000..3113e11b --- /dev/null +++ b/system/devel/binutils/files/binutils-2.25-roundup.patch @@ -0,0 +1,1660 @@ +diff --git a/bfd/ChangeLog b/bfd/ChangeLog +index f2ee1ba..6d936e2 100644 +--- a/bfd/ChangeLog ++++ b/bfd/ChangeLog +@@ -1,3 +1,34 @@ ++2015-01-22 Thomas Preud'homme ++ ++ Backport from mainline ++ 2015-01-13 Thomas Preud'homme ++ ++ * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Use SYMBOLIC_BIND ++ to check if a symbol should be bound symbolically. ++ ++2015-01-20 Chung-Lin Tang ++ ++ Backport from master ++ * elf32-nios2.c (elf_backend_default_execstack): Define as 0. ++ ++2015-01-11 H.J. Lu ++ ++ PR ld/17827 ++ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): For PIE, ++ only discard space for pc-relative relocs symbols which turn ++ out to need copy relocs. ++ ++2015-01-05 H.J. Lu ++ ++ PR ld/17773 ++ * elflink.c (bfd_elf_final_link): Assign the file position for ++ the symbol string table only there are symbols to be emitted. ++ ++2014-12-23 Tristan Gingold ++ ++ * version.m4: Bump version to 2.25.0 ++ * configure: Regenerate. ++ + 2014-12-23 Tristan Gingold + + * version.m4: Bump version to 2.25 +diff --git a/bfd/configure b/bfd/configure +index 7016194..85e6b82 100755 +--- a/bfd/configure ++++ b/bfd/configure +@@ -1,6 +1,6 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.64 for bfd 2.25. ++# Generated by GNU Autoconf 2.64 for bfd 2.25.0. + # + # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, + # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software +@@ -556,8 +556,8 @@ MAKEFLAGS= + # Identity of this package. + PACKAGE_NAME='bfd' + PACKAGE_TARNAME='bfd' +-PACKAGE_VERSION='2.25' +-PACKAGE_STRING='bfd 2.25' ++PACKAGE_VERSION='2.25.0' ++PACKAGE_STRING='bfd 2.25.0' + PACKAGE_BUGREPORT='' + PACKAGE_URL='' + +@@ -1349,7 +1349,7 @@ if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +-\`configure' configures bfd 2.25 to adapt to many kinds of systems. ++\`configure' configures bfd 2.25.0 to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + +@@ -1420,7 +1420,7 @@ fi + + if test -n "$ac_init_help"; then + case $ac_init_help in +- short | recursive ) echo "Configuration of bfd 2.25:";; ++ short | recursive ) echo "Configuration of bfd 2.25.0:";; + esac + cat <<\_ACEOF + +@@ -1541,7 +1541,7 @@ fi + test -n "$ac_init_help" && exit $ac_status + if $ac_init_version; then + cat <<\_ACEOF +-bfd configure 2.25 ++bfd configure 2.25.0 + generated by GNU Autoconf 2.64 + + Copyright (C) 2009 Free Software Foundation, Inc. +@@ -2183,7 +2183,7 @@ cat >config.log <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + +-It was created by bfd $as_me 2.25, which was ++It was created by bfd $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + $ $0 $@ +@@ -3991,7 +3991,7 @@ fi + + # Define the identity of the package. + PACKAGE='bfd' +- VERSION='2.25' ++ VERSION='2.25.0' + + + cat >>confdefs.h <<_ACEOF +@@ -16567,7 +16567,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + # report actual input values of CONFIG_FILES etc. instead of their + # values after options handling. + ac_log=" +-This file was extended by bfd $as_me 2.25, which was ++This file was extended by bfd $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES +@@ -16631,7 +16631,7 @@ Report bugs to the package provider." + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_cs_version="\\ +-bfd config.status 2.25 ++bfd config.status 2.25.0 + configured by $0, generated by GNU Autoconf 2.64, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +diff --git a/bfd/elf32-nios2.c b/bfd/elf32-nios2.c +index 9b3f436..2739961 100644 +--- a/bfd/elf32-nios2.c ++++ b/bfd/elf32-nios2.c +@@ -5307,5 +5307,6 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] = + #define TARGET_BIG_NAME "elf32-bignios2" + + #define elf_backend_got_header_size 12 ++#define elf_backend_default_execstack 0 + + #include "elf32-target.h" +diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c +index fefb08c..706ab5a 100644 +--- a/bfd/elf64-x86-64.c ++++ b/bfd/elf64-x86-64.c +@@ -2677,13 +2677,23 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) + return FALSE; + } +- /* For PIE, discard space for relocs against symbols which +- turn out to need copy relocs. */ ++ /* For PIE, discard space for pc-relative relocs against ++ symbols which turn out to need copy relocs. */ + else if (info->executable + && (h->needs_copy || eh->needs_copy) + && h->def_dynamic + && !h->def_regular) +- eh->dyn_relocs = NULL; ++ { ++ struct elf_dyn_relocs **pp; ++ ++ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; ) ++ { ++ if (p->pc_count != 0) ++ *pp = p->next; ++ else ++ pp = &p->next; ++ } ++ } + } + } + else if (ELIMINATE_COPY_RELOCS) +diff --git a/bfd/elflink.c b/bfd/elflink.c +index 94ab762..e9bd56c 100644 +--- a/bfd/elflink.c ++++ b/bfd/elflink.c +@@ -10438,7 +10438,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) + unsigned int i; + Elf_Internal_Shdr *symtab_hdr; + Elf_Internal_Shdr *symtab_shndx_hdr; +- Elf_Internal_Shdr *symstrtab_hdr; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + struct elf_outext_info eoinfo; + bfd_boolean merged; +@@ -11139,25 +11138,28 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) + } + + +- /* Finish up and write out the symbol string table (.strtab) +- section. */ +- symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; +- /* sh_name was set in prep_headers. */ +- symstrtab_hdr->sh_type = SHT_STRTAB; +- symstrtab_hdr->sh_flags = 0; +- symstrtab_hdr->sh_addr = 0; +- symstrtab_hdr->sh_size = _bfd_stringtab_size (flinfo.symstrtab); +- symstrtab_hdr->sh_entsize = 0; +- symstrtab_hdr->sh_link = 0; +- symstrtab_hdr->sh_info = 0; +- /* sh_offset is set just below. */ +- symstrtab_hdr->sh_addralign = 1; +- +- off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE); +- elf_next_file_pos (abfd) = off; +- + if (bfd_get_symcount (abfd) > 0) + { ++ /* Finish up and write out the symbol string table (.strtab) ++ section. */ ++ Elf_Internal_Shdr *symstrtab_hdr; ++ ++ symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; ++ /* sh_name was set in prep_headers. */ ++ symstrtab_hdr->sh_type = SHT_STRTAB; ++ symstrtab_hdr->sh_flags = 0; ++ symstrtab_hdr->sh_addr = 0; ++ symstrtab_hdr->sh_size = _bfd_stringtab_size (flinfo.symstrtab); ++ symstrtab_hdr->sh_entsize = 0; ++ symstrtab_hdr->sh_link = 0; ++ symstrtab_hdr->sh_info = 0; ++ /* sh_offset is set just below. */ ++ symstrtab_hdr->sh_addralign = 1; ++ ++ off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, ++ off, TRUE); ++ elf_next_file_pos (abfd) = off; ++ + if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 + || ! _bfd_stringtab_emit (abfd, flinfo.symstrtab)) + return FALSE; +diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c +index 0879db9..9939fcf 100644 +--- a/bfd/elfnn-aarch64.c ++++ b/bfd/elfnn-aarch64.c +@@ -4329,7 +4329,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto, + memset (&outrel, 0, sizeof outrel); + else if (h != NULL + && h->dynindx != -1 +- && (!info->shared || !info->symbolic || !h->def_regular)) ++ && (!info->shared || !SYMBOLIC_BIND (info, h) || !h->def_regular)) + outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); + else + { +diff --git a/bfd/version.h b/bfd/version.h +index c806928..8a10575 100644 +--- a/bfd/version.h ++++ b/bfd/version.h +@@ -1,4 +1,4 @@ +-#define BFD_VERSION_DATE 20141223 ++#define BFD_VERSION_DATE 20150207 + #define BFD_VERSION @bfd_version@ + #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ + #define REPORT_BUGS_TO @report_bugs_to@ +diff --git a/bfd/version.m4 b/bfd/version.m4 +index 4c966bc..57a10f8 100644 +--- a/bfd/version.m4 ++++ b/bfd/version.m4 +@@ -1 +1 @@ +-m4_define([BFD_VERSION], [2.25]) ++m4_define([BFD_VERSION], [2.25.0]) +diff --git a/binutils/ChangeLog b/binutils/ChangeLog +index db0941d..f26c706 100644 +--- a/binutils/ChangeLog ++++ b/binutils/ChangeLog +@@ -2,6 +2,10 @@ + + * configure: Regenerate. + ++2014-12-23 Tristan Gingold ++ ++ * configure: Regenerate. ++ + 2014-11-17 Nick Clifton + + Apply trunk patches: +diff --git a/binutils/configure b/binutils/configure +index b31248f..7c5b074 100755 +--- a/binutils/configure ++++ b/binutils/configure +@@ -1,6 +1,6 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.64 for binutils 2.25. ++# Generated by GNU Autoconf 2.64 for binutils 2.25.0. + # + # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, + # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software +@@ -556,8 +556,8 @@ MAKEFLAGS= + # Identity of this package. + PACKAGE_NAME='binutils' + PACKAGE_TARNAME='binutils' +-PACKAGE_VERSION='2.25' +-PACKAGE_STRING='binutils 2.25' ++PACKAGE_VERSION='2.25.0' ++PACKAGE_STRING='binutils 2.25.0' + PACKAGE_BUGREPORT='' + PACKAGE_URL='' + +@@ -1333,7 +1333,7 @@ if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +-\`configure' configures binutils 2.25 to adapt to many kinds of systems. ++\`configure' configures binutils 2.25.0 to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + +@@ -1404,7 +1404,7 @@ fi + + if test -n "$ac_init_help"; then + case $ac_init_help in +- short | recursive ) echo "Configuration of binutils 2.25:";; ++ short | recursive ) echo "Configuration of binutils 2.25.0:";; + esac + cat <<\_ACEOF + +@@ -1525,7 +1525,7 @@ fi + test -n "$ac_init_help" && exit $ac_status + if $ac_init_version; then + cat <<\_ACEOF +-binutils configure 2.25 ++binutils configure 2.25.0 + generated by GNU Autoconf 2.64 + + Copyright (C) 2009 Free Software Foundation, Inc. +@@ -1935,7 +1935,7 @@ cat >config.log <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + +-It was created by binutils $as_me 2.25, which was ++It was created by binutils $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + $ $0 $@ +@@ -3743,7 +3743,7 @@ fi + + # Define the identity of the package. + PACKAGE='binutils' +- VERSION='2.25' ++ VERSION='2.25.0' + + + cat >>confdefs.h <<_ACEOF +@@ -14850,7 +14850,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + # report actual input values of CONFIG_FILES etc. instead of their + # values after options handling. + ac_log=" +-This file was extended by binutils $as_me 2.25, which was ++This file was extended by binutils $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES +@@ -14914,7 +14914,7 @@ Report bugs to the package provider." + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_cs_version="\\ +-binutils config.status 2.25 ++binutils config.status 2.25.0 + configured by $0, generated by GNU Autoconf 2.64, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +diff --git a/gas/ChangeLog b/gas/ChangeLog +index de5e997..b4f0eea 100644 +--- a/gas/ChangeLog ++++ b/gas/ChangeLog +@@ -1,3 +1,12 @@ ++2015-01-28 Matthew Wahab ++ ++ * config/tc-arm.c (parse_ifimm_zero): Accept #0x0 as a synonym for #0, ++ restoring previous behaviour. ++ ++2014-12-23 Tristan Gingold ++ ++ * configure: Regenerate. ++ + 2014-12-23 Tristan Gingold + + * configure: Regenerate. +diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c +index 5077f87..2db6c2d 100644 +--- a/gas/config/tc-arm.c ++++ b/gas/config/tc-arm.c +@@ -4959,6 +4959,16 @@ parse_ifimm_zero (char **in) + return FALSE; + + ++*in; ++ ++ /* Accept #0x0 as a synonym for #0. */ ++ if (strncmp (*in, "0x", 2) == 0) ++ { ++ int val; ++ if (parse_immediate (in, &val, 0, 0, TRUE) == FAIL) ++ return FALSE; ++ return TRUE; ++ } ++ + error_code = atof_generic (in, ".", EXP_CHARS, + &generic_floating_point_number); + +diff --git a/gas/configure b/gas/configure +index 76b5f20..e9ba550 100755 +--- a/gas/configure ++++ b/gas/configure +@@ -1,6 +1,6 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.64 for gas 2.25. ++# Generated by GNU Autoconf 2.64 for gas 2.25.0. + # + # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, + # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software +@@ -556,8 +556,8 @@ MAKEFLAGS= + # Identity of this package. + PACKAGE_NAME='gas' + PACKAGE_TARNAME='gas' +-PACKAGE_VERSION='2.25' +-PACKAGE_STRING='gas 2.25' ++PACKAGE_VERSION='2.25.0' ++PACKAGE_STRING='gas 2.25.0' + PACKAGE_BUGREPORT='' + PACKAGE_URL='' + +@@ -1320,7 +1320,7 @@ if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +-\`configure' configures gas 2.25 to adapt to many kinds of systems. ++\`configure' configures gas 2.25.0 to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + +@@ -1391,7 +1391,7 @@ fi + + if test -n "$ac_init_help"; then + case $ac_init_help in +- short | recursive ) echo "Configuration of gas 2.25:";; ++ short | recursive ) echo "Configuration of gas 2.25.0:";; + esac + cat <<\_ACEOF + +@@ -1505,7 +1505,7 @@ fi + test -n "$ac_init_help" && exit $ac_status + if $ac_init_version; then + cat <<\_ACEOF +-gas configure 2.25 ++gas configure 2.25.0 + generated by GNU Autoconf 2.64 + + Copyright (C) 2009 Free Software Foundation, Inc. +@@ -1915,7 +1915,7 @@ cat >config.log <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + +-It was created by gas $as_me 2.25, which was ++It was created by gas $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + $ $0 $@ +@@ -3723,7 +3723,7 @@ fi + + # Define the identity of the package. + PACKAGE='gas' +- VERSION='2.25' ++ VERSION='2.25.0' + + + cat >>confdefs.h <<_ACEOF +@@ -15061,7 +15061,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + # report actual input values of CONFIG_FILES etc. instead of their + # values after options handling. + ac_log=" +-This file was extended by gas $as_me 2.25, which was ++This file was extended by gas $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES +@@ -15125,7 +15125,7 @@ Report bugs to the package provider." + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_cs_version="\\ +-gas config.status 2.25 ++gas config.status 2.25.0 + configured by $0, generated by GNU Autoconf 2.64, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog +index d53d518..cea61aa 100644 +--- a/gas/testsuite/ChangeLog ++++ b/gas/testsuite/ChangeLog +@@ -1,3 +1,9 @@ ++2015-01-28 Matthew Fortune ++ ++ * gas/arm/ual-vcmp.s: Add vcmp, vcmpe with #0x0 operand. ++ * gas/ual/vcmp.d: Update expected output. ++ * gas/ual/vcmp-zero-bad.l: Likewise ++ + 2014-12-19 Matthew Fortune + + * gas/mips/r6-64.s: Remove .align directives from LDPC +diff --git a/gas/testsuite/gas/arm/ual-vcmp.d b/gas/testsuite/gas/arm/ual-vcmp.d +index 2e9fb3d..5b1b6ce 100644 +--- a/gas/testsuite/gas/arm/ual-vcmp.d ++++ b/gas/testsuite/gas/arm/ual-vcmp.d +@@ -14,11 +14,15 @@ Disassembly of section .text: + 0+014 <[^>]*> eeb53a40 vcmp.f32 s6, #0.0 + 0+018 <[^>]*> eef53ac0 vcmpe.f32 s7, #0.0 + 0+01c <[^>]*> eeb54ac0 vcmpe.f32 s8, #0.0 +-0+020 <[^>]*> eeb50b40 vcmp.f64 d0, #0.0 +-0+024 <[^>]*> eeb51b40 vcmp.f64 d1, #0.0 +-0+028 <[^>]*> eeb52bc0 vcmpe.f64 d2, #0.0 +-0+02c <[^>]*> eeb53bc0 vcmpe.f64 d3, #0.0 +-0+030 <[^>]*> eeb54b40 vcmp.f64 d4, #0.0 +-0+034 <[^>]*> eeb55b40 vcmp.f64 d5, #0.0 +-0+038 <[^>]*> eeb56bc0 vcmpe.f64 d6, #0.0 +-0+03c <[^>]*> eeb57bc0 vcmpe.f64 d7, #0.0 +\ No newline at end of file ++0+020 <[^>]*> eef54a40 vcmp.f32 s9, #0.0 ++0+024 <[^>]*> eeb55ac0 vcmpe.f32 s10, #0.0 ++0+028 <[^>]*> eeb50b40 vcmp.f64 d0, #0.0 ++0+02c <[^>]*> eeb51b40 vcmp.f64 d1, #0.0 ++0+030 <[^>]*> eeb52bc0 vcmpe.f64 d2, #0.0 ++0+034 <[^>]*> eeb53bc0 vcmpe.f64 d3, #0.0 ++0+038 <[^>]*> eeb54b40 vcmp.f64 d4, #0.0 ++0+03c <[^>]*> eeb55b40 vcmp.f64 d5, #0.0 ++0+040 <[^>]*> eeb56bc0 vcmpe.f64 d6, #0.0 ++0+044 <[^>]*> eeb57bc0 vcmpe.f64 d7, #0.0 ++0+048 <[^>]*> eeb58b40 vcmp.f64 d8, #0.0 ++0+04c <[^>]*> eeb59bc0 vcmpe.f64 d9, #0.0 +\ No newline at end of file +diff --git a/gas/testsuite/gas/arm/ual-vcmp.s b/gas/testsuite/gas/arm/ual-vcmp.s +index 79efa4e..1b9ffa6 100644 +--- a/gas/testsuite/gas/arm/ual-vcmp.s ++++ b/gas/testsuite/gas/arm/ual-vcmp.s +@@ -10,6 +10,8 @@ vcmp.f32 s5, #0.0e2 + vcmp.f32 s6, #0e-3 + vcmpe.f32 s7, #0.0000 + vcmpe.f32 s8, #.0 ++vcmp.f32 s9, #0x0 ++vcmpe.f32 s10, #0x0 + + vcmp.f64 d0, #0.0 + vcmp.f64 d1, #0 +@@ -19,3 +21,5 @@ vcmp.f64 d4, #0.0e5 + vcmp.f64 d5, #0e-2 + vcmpe.f64 d6, #0.00 + vcmpe.f64 d7, #.0 ++vcmp.f64 d8, #0x0 ++vcmpe.f64 d9, #0x0 +diff --git a/gas/testsuite/gas/arm/vcmp-zero-bad.l b/gas/testsuite/gas/arm/vcmp-zero-bad.l +index 975d02b..bce8e4a 100644 +--- a/gas/testsuite/gas/arm/vcmp-zero-bad.l ++++ b/gas/testsuite/gas/arm/vcmp-zero-bad.l +@@ -4,5 +4,5 @@ + [^:]*:7: Error: only floating point zero is allowed as immediate value -- `vcmpe.f32 s3,5' + [^:]*:8: Error: only floating point zero is allowed as immediate value -- `vcmpe.f32 s4,#-0.0' + [^:]*:10: Error: only floating point zero is allowed as immediate value -- `vcmp.f64 d0,#-1' +-[^:]*:11: Error: garbage following instruction -- `vcmpe.f64 d3,#0x35' ++[^:]*:11: Error: only floating point zero is allowed as immediate value -- `vcmpe.f64 d3,#0x35' + [^:]*:12: Error: only floating point zero is allowed as immediate value -- `vcmpe.f64 d4,0xf' +diff --git a/gold/ChangeLog b/gold/ChangeLog +index 2220da2..f10d114 100644 +--- a/gold/ChangeLog ++++ b/gold/ChangeLog +@@ -1,3 +1,36 @@ ++2015-01-06 H.J. Lu ++ Cary Coutant ++ ++ PR gold/17729 ++ * configure.ac (DEFAULT_TARGET_X86_64): Don't set for x32. ++ (DEFAULT_TARGET_X32): Set for x32. ++ * x86_64.cc (cmp_insn_32): New. ++ (lea_r10_insn_32): Likewise. ++ (lea_r11_insn_32): Likewise. ++ (cmp_insn_64): Likewise. ++ (lea_r10_insn_64): Likewise. ++ (lea_r11_insn_64): Likewise. ++ (Target_x86_64::do_calls_non_split): Handle x32. ++ * testsuite/Makefile.am (check_SCRIPTS): Add split_x32.sh. ++ (check_DATA): Add split_x32 files. ++ (split_x32_[1234n].o): New targets. ++ (split_x32_[124]): New targets. ++ (split_x32_[1234r].stdout): New targets. ++ * testsuite/split_x32.sh: New file. ++ * testsuite/split_x32_1.s: Likewise. ++ * testsuite/split_x32_2.s: Likewise. ++ * testsuite/split_x32_3.s: Likewise. ++ * testsuite/split_x32_4.s: Likewise. ++ * testsuite/split_x32_n.s: Likewise. ++ * configure: Regenerated. ++ * testsuite/Makefile.in: Likewise. ++ ++2015-01-06 H.J. Lu ++ ++ PR gold/17809 ++ * x86_64.cc (Target_x86_64::Relocate::tls_ie_to_le): Handle ++ x32. ++ + 2014-12-04 Alan Modra + + * Powerpc.cc (Target_powerpc::Branch_info::make_stub): Ignore +diff --git a/gold/configure b/gold/configure +index 7d7b849..23e4735 100755 +--- a/gold/configure ++++ b/gold/configure +@@ -688,6 +688,8 @@ DEFAULT_TARGET_MIPS_FALSE + DEFAULT_TARGET_MIPS_TRUE + DEFAULT_TARGET_TILEGX_FALSE + DEFAULT_TARGET_TILEGX_TRUE ++DEFAULT_TARGET_X32_FALSE ++DEFAULT_TARGET_X32_TRUE + DEFAULT_TARGET_X86_64_FALSE + DEFAULT_TARGET_X86_64_TRUE + DEFAULT_TARGET_SPARC_FALSE +@@ -3475,7 +3477,19 @@ else + DEFAULT_TARGET_SPARC_FALSE= + fi + +- if test "$targ_obj" = "x86_64"; then ++ target_x86_64=no ++ target_x32=no ++ if test "$targ_obj" = "x86_64"; then ++ case "$target" in ++ x86_64*-linux-gnux32) ++ target_x32=yes ++ ;; ++ *) ++ target_x86_64=yes ++ ;; ++ esac ++ fi ++ if test "$target_x86_64" = "yes"; then + DEFAULT_TARGET_X86_64_TRUE= + DEFAULT_TARGET_X86_64_FALSE='#' + else +@@ -3483,6 +3497,14 @@ else + DEFAULT_TARGET_X86_64_FALSE= + fi + ++ if test "$target_x32" = "yes"; then ++ DEFAULT_TARGET_X32_TRUE= ++ DEFAULT_TARGET_X32_FALSE='#' ++else ++ DEFAULT_TARGET_X32_TRUE='#' ++ DEFAULT_TARGET_X32_FALSE= ++fi ++ + if test "$targ_obj" = "tilegx"; then + DEFAULT_TARGET_TILEGX_TRUE= + DEFAULT_TARGET_TILEGX_FALSE='#' +@@ -7811,6 +7833,10 @@ if test -z "${DEFAULT_TARGET_X86_64_TRUE}" && test -z "${DEFAULT_TARGET_X86_64_F + as_fn_error "conditional \"DEFAULT_TARGET_X86_64\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${DEFAULT_TARGET_X32_TRUE}" && test -z "${DEFAULT_TARGET_X32_FALSE}"; then ++ as_fn_error "conditional \"DEFAULT_TARGET_X32\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${DEFAULT_TARGET_TILEGX_TRUE}" && test -z "${DEFAULT_TARGET_TILEGX_FALSE}"; then + as_fn_error "conditional \"DEFAULT_TARGET_TILEGX\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/gold/configure.ac b/gold/configure.ac +index 0478011..64e603a 100644 +--- a/gold/configure.ac ++++ b/gold/configure.ac +@@ -204,7 +204,20 @@ for targ in $target $canon_targets; do + AM_CONDITIONAL(DEFAULT_TARGET_I386, test "$targ_obj" = "i386") + AM_CONDITIONAL(DEFAULT_TARGET_POWERPC, test "$targ_obj" = "powerpc") + AM_CONDITIONAL(DEFAULT_TARGET_SPARC, test "$targ_obj" = "sparc") +- AM_CONDITIONAL(DEFAULT_TARGET_X86_64, test "$targ_obj" = "x86_64") ++ target_x86_64=no ++ target_x32=no ++ if test "$targ_obj" = "x86_64"; then ++ case "$target" in ++ x86_64*-linux-gnux32) ++ target_x32=yes ++ ;; ++ *) ++ target_x86_64=yes ++ ;; ++ esac ++ fi ++ AM_CONDITIONAL(DEFAULT_TARGET_X86_64, test "$target_x86_64" = "yes") ++ AM_CONDITIONAL(DEFAULT_TARGET_X32, test "$target_x32" = "yes") + AM_CONDITIONAL(DEFAULT_TARGET_TILEGX, test "$targ_obj" = "tilegx") + AM_CONDITIONAL(DEFAULT_TARGET_MIPS, test "$targ_obj" = "mips") + DEFAULT_TARGET=${targ_obj} +diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am +index 35cd013..e015a3d 100644 +--- a/gold/testsuite/Makefile.am ++++ b/gold/testsuite/Makefile.am +@@ -2483,6 +2483,43 @@ MOSTLYCLEANFILES += split_x86_64_1 split_x86_64_2 split_x86_64_3 \ + + endif DEFAULT_TARGET_X86_64 + ++if DEFAULT_TARGET_X32 ++ ++check_SCRIPTS += split_x32.sh ++check_DATA += split_x32_1.stdout split_x32_2.stdout \ ++ split_x32_3.stdout split_x32_4.stdout split_x32_r.stdout ++SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 ++split_x32_1.o: split_x32_1.s ++ $(TEST_AS) -o $@ $< ++split_x32_2.o: split_x32_2.s ++ $(TEST_AS) -o $@ $< ++split_x32_3.o: split_x32_3.s ++ $(TEST_AS) -o $@ $< ++split_x32_4.o: split_x32_4.s ++ $(TEST_AS) -o $@ $< ++split_x32_n.o: split_x32_n.s ++ $(TEST_AS) -o $@ $< ++split_x32_1: split_x32_1.o split_x32_n.o ../ld-new ++ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_1.o split_x32_n.o ++split_x32_1.stdout: split_x32_1 ++ $(TEST_OBJDUMP) -d $< > $@ ++split_x32_2: split_x32_2.o split_x32_n.o ../ld-new ++ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_2.o split_x32_n.o ++split_x32_2.stdout: split_x32_2 ++ $(TEST_OBJDUMP) -d $< > $@ ++split_x32_3.stdout: split_x32_3.o split_x32_n.o ../ld-new ++ ../ld-new $(SPLIT_DEFSYMS) -o split_x32_3 split_x32_3.o split_x32_n.o > $@ 2>&1 || exit 0 ++split_x32_4: split_x32_4.o split_x32_n.o ../ld-new ++ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_4.o split_x32_n.o ++split_x32_4.stdout: split_x32_4 ++ $(TEST_OBJDUMP) -d $< > $@ ++split_x32_r.stdout: split_x32_1.o split_x32_n.o ../ld-new ++ ../ld-new -r split_x32_1.o split_x32_n.o -o split_x32_r > $@ 2>&1 || exit 0 ++MOSTLYCLEANFILES += split_x32_1 split_x32_2 split_x32_3 \ ++ split_x32_4 split_x32_r ++ ++endif DEFAULT_TARGET_X32 ++ + if DEFAULT_TARGET_ARM + + check_SCRIPTS += arm_abs_global.sh +diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in +index 8fbb644..befef5f 100644 +--- a/gold/testsuite/Makefile.in ++++ b/gold/testsuite/Makefile.in +@@ -623,6 +623,13 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_83 = split_x86_64_1 split_x86_64_2 split_x86_64_3 \ + @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_x86_64_4 split_x86_64_r + ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_84 = split_x32.sh ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_85 = split_x32_1.stdout split_x32_2.stdout \ ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_x32_3.stdout split_x32_4.stdout split_x32_r.stdout ++ ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_86 = split_x32_1 split_x32_2 split_x32_3 \ ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_x32_4 split_x32_r ++ + + # ARM1176 workaround test. + +@@ -635,7 +642,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + # Check Thumb to Thumb farcall veneers + + # Check Thumb to ARM farcall veneers +-@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_84 = arm_abs_global.sh \ ++@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_87 = arm_abs_global.sh \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_branch_in_range.sh \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_branch_out_of_range.sh \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_fix_v4bx.sh \ +@@ -649,7 +656,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_arm_thumb.sh \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_thumb.sh \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm.sh +-@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_85 = arm_abs_global.stdout \ ++@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_88 = arm_abs_global.stdout \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_in_range.stdout \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_out_of_range.stdout \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ thumb_bl_in_range.stdout \ +@@ -694,7 +701,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_thumb_6m.stdout \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm.stdout \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm_5t.stdout +-@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_86 = arm_abs_global \ ++@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_89 = arm_abs_global \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_in_range \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_out_of_range \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ thumb_bl_in_range \ +@@ -737,10 +744,10 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_thumb_6m \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm \ + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm_5t +-@DEFAULT_TARGET_X86_64_TRUE@am__append_87 = *.dwo *.dwp +-@DEFAULT_TARGET_X86_64_TRUE@am__append_88 = dwp_test_1.sh \ ++@DEFAULT_TARGET_X86_64_TRUE@am__append_90 = *.dwo *.dwp ++@DEFAULT_TARGET_X86_64_TRUE@am__append_91 = dwp_test_1.sh \ + @DEFAULT_TARGET_X86_64_TRUE@ dwp_test_2.sh +-@DEFAULT_TARGET_X86_64_TRUE@am__append_89 = dwp_test_1.stdout \ ++@DEFAULT_TARGET_X86_64_TRUE@am__append_92 = dwp_test_1.stdout \ + @DEFAULT_TARGET_X86_64_TRUE@ dwp_test_2.stdout + subdir = testsuite + DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +@@ -2224,7 +2231,8 @@ MOSTLYCLEANFILES = *.so *.syms *.stdout $(am__append_4) \ + $(am__append_41) $(am__append_47) $(am__append_63) \ + $(am__append_66) $(am__append_69) $(am__append_72) \ + $(am__append_74) $(am__append_77) $(am__append_80) \ +- $(am__append_83) $(am__append_86) $(am__append_87) ++ $(am__append_83) $(am__append_86) $(am__append_89) \ ++ $(am__append_90) + + # We will add to these later, for each individual test. Note + # that we add each test under check_SCRIPTS or check_PROGRAMS; +@@ -2233,13 +2241,13 @@ check_SCRIPTS = $(am__append_2) $(am__append_34) $(am__append_38) \ + $(am__append_42) $(am__append_45) $(am__append_61) \ + $(am__append_64) $(am__append_67) $(am__append_70) \ + $(am__append_75) $(am__append_78) $(am__append_81) \ +- $(am__append_84) $(am__append_88) ++ $(am__append_84) $(am__append_87) $(am__append_91) + check_DATA = $(am__append_3) $(am__append_27) $(am__append_29) \ + $(am__append_35) $(am__append_39) $(am__append_43) \ + $(am__append_46) $(am__append_62) $(am__append_65) \ + $(am__append_68) $(am__append_71) $(am__append_76) \ + $(am__append_79) $(am__append_82) $(am__append_85) \ +- $(am__append_89) ++ $(am__append_88) $(am__append_92) + BUILT_SOURCES = $(am__append_25) + TESTS = $(check_SCRIPTS) $(check_PROGRAMS) + +@@ -2736,6 +2744,7 @@ LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) \ + @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@exception_x86_64_bnd_test_LDFLAGS = $(exception_test_LDFLAGS) + @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@exception_x86_64_bnd_test_LDADD = exception_x86_64_bnd_1.o exception_x86_64_bnd_2.o + @DEFAULT_TARGET_I386_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 + @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 + all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am +@@ -4166,6 +4175,8 @@ split_i386.sh.log: split_i386.sh + @p='split_i386.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) + split_x86_64.sh.log: split_x86_64.sh + @p='split_x86_64.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) ++split_x32.sh.log: split_x32.sh ++ @p='split_x32.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) + arm_abs_global.sh.log: arm_abs_global.sh + @p='arm_abs_global.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) + arm_branch_in_range.sh.log: arm_branch_in_range.sh +@@ -5777,6 +5788,32 @@ uninstall-am: + @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ + @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x86_64_r.stdout: split_x86_64_1.o split_x86_64_n.o ../ld-new + @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -r split_x86_64_1.o split_x86_64_n.o -o split_x86_64_r > $@ 2>&1 || exit 0 ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_1.o: split_x32_1.s ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_2.o: split_x32_2.s ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_3.o: split_x32_3.s ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_4.o: split_x32_4.s ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_n.o: split_x32_n.s ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_1: split_x32_1.o split_x32_n.o ../ld-new ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_1.o split_x32_n.o ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_1.stdout: split_x32_1 ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_2: split_x32_2.o split_x32_n.o ../ld-new ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_2.o split_x32_n.o ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_2.stdout: split_x32_2 ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_3.stdout: split_x32_3.o split_x32_n.o ../ld-new ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o split_x32_3 split_x32_3.o split_x32_n.o > $@ 2>&1 || exit 0 ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_4: split_x32_4.o split_x32_n.o ../ld-new ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_4.o split_x32_n.o ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_4.stdout: split_x32_4 ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_r.stdout: split_x32_1.o split_x32_n.o ../ld-new ++@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -r split_x32_1.o split_x32_n.o -o split_x32_r > $@ 2>&1 || exit 0 + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_abs_lib.o: arm_abs_lib.s + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -march=armv7-a -o $@ $< + @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@libarm_abs.so: arm_abs_lib.o ../ld-new +diff --git a/gold/testsuite/split_x32.sh b/gold/testsuite/split_x32.sh +new file mode 100755 +index 0000000..0bc0cf3 +--- /dev/null ++++ b/gold/testsuite/split_x32.sh +@@ -0,0 +1,55 @@ ++#!/bin/sh ++ ++# split_x32.sh -- test -fstack-split for x32 ++ ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# Written by Ian Lance Taylor . ++# Modified by H.J. Lu . ++ ++# This file is part of gold. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++# MA 02110-1301, USA. ++ ++match() ++{ ++ if ! egrep "$1" "$2" >/dev/null 2>&1; then ++ echo 1>&2 "could not find '$1' in $2" ++ exit 1 ++ fi ++} ++ ++nomatch() ++{ ++ if egrep "$1" "$2" >/dev/null 2>&1; then ++ echo 1>&2 "found unexpected '$1' in $2" ++ exit 1 ++ fi ++} ++ ++match 'cmp.*+%fs:[^,]*,%esp' split_x32_1.stdout ++match 'callq.*__morestack>?$' split_x32_1.stdout ++match 'lea.*-0x200\(%rsp\),' split_x32_1.stdout ++ ++match 'stc' split_x32_2.stdout ++match 'callq.*__morestack_non_split>?$' split_x32_2.stdout ++nomatch 'callq.*__morestack>?$' split_x32_2.stdout ++match 'lea.*-0x4200\(%rsp\),' split_x32_2.stdout ++ ++match 'failed to match' split_x32_3.stdout ++ ++match 'callq.*__morestack>?$' split_x32_4.stdout ++ ++match 'cannot mix' split_x32_r.stdout +diff --git a/gold/testsuite/split_x32_1.s b/gold/testsuite/split_x32_1.s +new file mode 100644 +index 0000000..b78936e +--- /dev/null ++++ b/gold/testsuite/split_x32_1.s +@@ -0,0 +1,33 @@ ++# split_x32_1.s: x32 specific test case for -fsplit-stack. ++ ++ .text ++ ++ .global fn1 ++ .type fn1,@function ++fn1: ++ cmp %fs:0x40,%esp ++ jae 1f ++ callq __morestack ++ retq ++1: ++ callq fn2 ++ retq ++ ++ .size fn1,. - fn1 ++ ++ .global fn2 ++ .type fn2,@function ++fn2: ++ lea -0x200(%rsp),%r10d ++ cmp %fs:0x40,%r10d ++ jae 1f ++ callq __morestack ++ retq ++1: ++ callq fn1 ++ retq ++ ++ .size fn2,. - fn2 ++ ++ .section .note.GNU-stack,"",@progbits ++ .section .note.GNU-split-stack,"",@progbits +diff --git a/gold/testsuite/split_x32_2.s b/gold/testsuite/split_x32_2.s +new file mode 100644 +index 0000000..b789afd +--- /dev/null ++++ b/gold/testsuite/split_x32_2.s +@@ -0,0 +1,33 @@ ++# split_x32_2.s: x32 specific, -fsplit-stack calling non-split ++ ++ .text ++ ++ .global fn1 ++ .type fn1,@function ++fn1: ++ cmp %fs:0x40,%esp ++ jae 1f ++ callq __morestack ++ retq ++1: ++ callq fn3 ++ retq ++ ++ .size fn1,. - fn1 ++ ++ .global fn2 ++ .type fn2,@function ++fn2: ++ lea -0x200(%rsp),%r10d ++ cmp %fs:0x40,%r10d ++ jae 1f ++ callq __morestack ++ retq ++1: ++ callq fn3 ++ retq ++ ++ .size fn2,. - fn2 ++ ++ .section .note.GNU-stack,"",@progbits ++ .section .note.GNU-split-stack,"",@progbits +diff --git a/gold/testsuite/split_x32_3.s b/gold/testsuite/split_x32_3.s +new file mode 100644 +index 0000000..d7b09bd +--- /dev/null ++++ b/gold/testsuite/split_x32_3.s +@@ -0,0 +1,22 @@ ++# split_x32_3.s: x32 specific, adjustment failure ++ ++ .text ++ ++ .global fn1 ++ .type fn1,@function ++fn1: ++ push %rbp ++ mov %esp,%ebp ++ cmp %fs:0x40,%esp ++ jae 1f ++ callq __morestack ++ retq ++1: ++ callq fn3 ++ leaveq ++ retq ++ ++ .size fn1,. - fn1 ++ ++ .section .note.GNU-stack,"",@progbits ++ .section .note.GNU-split-stack,"",@progbits +diff --git a/gold/testsuite/split_x32_4.s b/gold/testsuite/split_x32_4.s +new file mode 100644 +index 0000000..1f4eece +--- /dev/null ++++ b/gold/testsuite/split_x32_4.s +@@ -0,0 +1,23 @@ ++# split_x32_4.s: x32 specific, permitted adjustment failure ++ ++ .text ++ ++ .global fn1 ++ .type fn1,@function ++fn1: ++ push %rbp ++ mov %esp,%ebp ++ cmp %fs:0x40,%esp ++ jae 1f ++ callq __morestack ++ retq ++1: ++ callq fn3 ++ leaveq ++ retq ++ ++ .size fn1,. - fn1 ++ ++ .section .note.GNU-stack,"",@progbits ++ .section .note.GNU-split-stack,"",@progbits ++ .section .note.GNU-no-split-stack,"",@progbits +diff --git a/gold/testsuite/split_x32_n.s b/gold/testsuite/split_x32_n.s +new file mode 100644 +index 0000000..54c0db6 +--- /dev/null ++++ b/gold/testsuite/split_x32_n.s +@@ -0,0 +1,12 @@ ++# split_x32_n.s: x32 specific, -fsplit-stack calling non-split ++ ++ .text ++ ++ .global fn3 ++ .type fn3,@function ++fn3: ++ retq ++ ++ .size fn3,. - fn3 ++ ++ .section .note.GNU-stack,"",@progbits +diff --git a/gold/x86_64.cc b/gold/x86_64.cc +index f58c843..10c75a2 100644 +--- a/gold/x86_64.cc ++++ b/gold/x86_64.cc +@@ -4100,6 +4100,8 @@ Target_x86_64::Relocate::tls_ie_to_le( + // movq + if (op1 == 0x4c) + view[-3] = 0x49; ++ else if (size == 32 && op1 == 0x44) ++ view[-3] = 0x41; + view[-2] = 0xc7; + view[-1] = 0xc0 | reg; + } +@@ -4108,6 +4110,8 @@ Target_x86_64::Relocate::tls_ie_to_le( + // Special handling for %rsp. + if (op1 == 0x4c) + view[-3] = 0x49; ++ else if (size == 32 && op1 == 0x44) ++ view[-3] = 0x41; + view[-2] = 0x81; + view[-1] = 0xc0 | reg; + } +@@ -4116,6 +4120,8 @@ Target_x86_64::Relocate::tls_ie_to_le( + // addq + if (op1 == 0x4c) + view[-3] = 0x4d; ++ else if (size == 32 && op1 == 0x44) ++ view[-3] = 0x45; + view[-2] = 0x8d; + view[-1] = 0x80 | reg | (reg << 3); + } +@@ -4457,6 +4463,14 @@ Target_x86_64::do_ehframe_datarel_base() const + // code. We have to change the function so that it always ensures + // that it has enough stack space to run some random function. + ++static const unsigned char cmp_insn_32[] = { 0x64, 0x3b, 0x24, 0x25 }; ++static const unsigned char lea_r10_insn_32[] = { 0x44, 0x8d, 0x94, 0x24 }; ++static const unsigned char lea_r11_insn_32[] = { 0x44, 0x8d, 0x9c, 0x24 }; ++ ++static const unsigned char cmp_insn_64[] = { 0x64, 0x48, 0x3b, 0x24, 0x25 }; ++static const unsigned char lea_r10_insn_64[] = { 0x4c, 0x8d, 0x94, 0x24 }; ++static const unsigned char lea_r11_insn_64[] = { 0x4c, 0x8d, 0x9c, 0x24 }; ++ + template + void + Target_x86_64::do_calls_non_split(Relobj* object, unsigned int shndx, +@@ -4467,25 +4481,40 @@ Target_x86_64::do_calls_non_split(Relobj* object, unsigned int shndx, + std::string* from, + std::string* to) const + { ++ const char* const cmp_insn = reinterpret_cast ++ (size == 32 ? cmp_insn_32 : cmp_insn_64); ++ const char* const lea_r10_insn = reinterpret_cast ++ (size == 32 ? lea_r10_insn_32 : lea_r10_insn_64); ++ const char* const lea_r11_insn = reinterpret_cast ++ (size == 32 ? lea_r11_insn_32 : lea_r11_insn_64); ++ ++ const size_t cmp_insn_len = ++ (size == 32 ? sizeof(cmp_insn_32) : sizeof(cmp_insn_64)); ++ const size_t lea_r10_insn_len = ++ (size == 32 ? sizeof(lea_r10_insn_32) : sizeof(lea_r10_insn_64)); ++ const size_t lea_r11_insn_len = ++ (size == 32 ? sizeof(lea_r11_insn_32) : sizeof(lea_r11_insn_64)); ++ const size_t nop_len = (size == 32 ? 7 : 8); ++ + // The function starts with a comparison of the stack pointer and a + // field in the TCB. This is followed by a jump. + + // cmp %fs:NN,%rsp +- if (this->match_view(view, view_size, fnoffset, "\x64\x48\x3b\x24\x25", 5) +- && fnsize > 9) ++ if (this->match_view(view, view_size, fnoffset, cmp_insn, cmp_insn_len) ++ && fnsize > nop_len + 1) + { + // We will call __morestack if the carry flag is set after this + // comparison. We turn the comparison into an stc instruction + // and some nops. + view[fnoffset] = '\xf9'; +- this->set_view_to_nop(view, view_size, fnoffset + 1, 8); ++ this->set_view_to_nop(view, view_size, fnoffset + 1, nop_len); + } + // lea NN(%rsp),%r10 + // lea NN(%rsp),%r11 + else if ((this->match_view(view, view_size, fnoffset, +- "\x4c\x8d\x94\x24", 4) ++ lea_r10_insn, lea_r10_insn_len) + || this->match_view(view, view_size, fnoffset, +- "\x4c\x8d\x9c\x24", 4)) ++ lea_r11_insn, lea_r11_insn_len)) + && fnsize > 8) + { + // This is loading an offset from the stack pointer for a +diff --git a/gprof/ChangeLog b/gprof/ChangeLog +index 866eb0d..af2ce55 100644 +--- a/gprof/ChangeLog ++++ b/gprof/ChangeLog +@@ -2,6 +2,10 @@ + + * configure: Regenerate. + ++2014-12-23 Tristan Gingold ++ ++ * configure: Regenerate. ++ + 2014-11-03 Nick Clifton + + * po/fi.po: Updated Finnish translation. +diff --git a/gprof/configure b/gprof/configure +index a6f7ac7..b09c8fb 100755 +--- a/gprof/configure ++++ b/gprof/configure +@@ -1,6 +1,6 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.64 for gprof 2.25. ++# Generated by GNU Autoconf 2.64 for gprof 2.25.0. + # + # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, + # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software +@@ -556,8 +556,8 @@ MAKEFLAGS= + # Identity of this package. + PACKAGE_NAME='gprof' + PACKAGE_TARNAME='gprof' +-PACKAGE_VERSION='2.25' +-PACKAGE_STRING='gprof 2.25' ++PACKAGE_VERSION='2.25.0' ++PACKAGE_STRING='gprof 2.25.0' + PACKAGE_BUGREPORT='' + PACKAGE_URL='' + +@@ -1299,7 +1299,7 @@ if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +-\`configure' configures gprof 2.25 to adapt to many kinds of systems. ++\`configure' configures gprof 2.25.0 to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + +@@ -1370,7 +1370,7 @@ fi + + if test -n "$ac_init_help"; then + case $ac_init_help in +- short | recursive ) echo "Configuration of gprof 2.25:";; ++ short | recursive ) echo "Configuration of gprof 2.25.0:";; + esac + cat <<\_ACEOF + +@@ -1476,7 +1476,7 @@ fi + test -n "$ac_init_help" && exit $ac_status + if $ac_init_version; then + cat <<\_ACEOF +-gprof configure 2.25 ++gprof configure 2.25.0 + generated by GNU Autoconf 2.64 + + Copyright (C) 2009 Free Software Foundation, Inc. +@@ -1841,7 +1841,7 @@ cat >config.log <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + +-It was created by gprof $as_me 2.25, which was ++It was created by gprof $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + $ $0 $@ +@@ -3649,7 +3649,7 @@ fi + + # Define the identity of the package. + PACKAGE='gprof' +- VERSION='2.25' ++ VERSION='2.25.0' + + + cat >>confdefs.h <<_ACEOF +@@ -12706,7 +12706,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + # report actual input values of CONFIG_FILES etc. instead of their + # values after options handling. + ac_log=" +-This file was extended by gprof $as_me 2.25, which was ++This file was extended by gprof $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES +@@ -12770,7 +12770,7 @@ Report bugs to the package provider." + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_cs_version="\\ +-gprof config.status 2.25 ++gprof config.status 2.25.0 + configured by $0, generated by GNU Autoconf 2.64, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +diff --git a/ld/ChangeLog b/ld/ChangeLog +index 28dd353..3a6e3c3 100644 +--- a/ld/ChangeLog ++++ b/ld/ChangeLog +@@ -2,6 +2,10 @@ + + * configure: Regenerate. + ++2014-12-23 Tristan Gingold ++ ++ * configure: Regenerate. ++ + 2014-11-24 Alan Modra + + * ld.texinfo: Correct --plt-align documentation. +diff --git a/ld/configure b/ld/configure +index 66d8024..4408b0d 100755 +--- a/ld/configure ++++ b/ld/configure +@@ -1,6 +1,6 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.64 for ld 2.25. ++# Generated by GNU Autoconf 2.64 for ld 2.25.0. + # + # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, + # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software +@@ -556,8 +556,8 @@ MAKEFLAGS= + # Identity of this package. + PACKAGE_NAME='ld' + PACKAGE_TARNAME='ld' +-PACKAGE_VERSION='2.25' +-PACKAGE_STRING='ld 2.25' ++PACKAGE_VERSION='2.25.0' ++PACKAGE_STRING='ld 2.25.0' + PACKAGE_BUGREPORT='' + PACKAGE_URL='' + +@@ -1347,7 +1347,7 @@ if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +-\`configure' configures ld 2.25 to adapt to many kinds of systems. ++\`configure' configures ld 2.25.0 to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + +@@ -1418,7 +1418,7 @@ fi + + if test -n "$ac_init_help"; then + case $ac_init_help in +- short | recursive ) echo "Configuration of ld 2.25:";; ++ short | recursive ) echo "Configuration of ld 2.25.0:";; + esac + cat <<\_ACEOF + +@@ -1541,7 +1541,7 @@ fi + test -n "$ac_init_help" && exit $ac_status + if $ac_init_version; then + cat <<\_ACEOF +-ld configure 2.25 ++ld configure 2.25.0 + generated by GNU Autoconf 2.64 + + Copyright (C) 2009 Free Software Foundation, Inc. +@@ -2250,7 +2250,7 @@ cat >config.log <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + +-It was created by ld $as_me 2.25, which was ++It was created by ld $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + $ $0 $@ +@@ -4059,7 +4059,7 @@ fi + + # Define the identity of the package. + PACKAGE='ld' +- VERSION='2.25' ++ VERSION='2.25.0' + + + cat >>confdefs.h <<_ACEOF +@@ -17594,7 +17594,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + # report actual input values of CONFIG_FILES etc. instead of their + # values after options handling. + ac_log=" +-This file was extended by ld $as_me 2.25, which was ++This file was extended by ld $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES +@@ -17658,7 +17658,7 @@ Report bugs to the package provider." + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_cs_version="\\ +-ld config.status 2.25 ++ld config.status 2.25.0 + configured by $0, generated by GNU Autoconf 2.64, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog +index f0344fd..1b1d935 100644 +--- a/ld/testsuite/ChangeLog ++++ b/ld/testsuite/ChangeLog +@@ -1,3 +1,29 @@ ++2015-01-22 Thomas Preud'homme ++ ++ Backport from mainline ++ 2015-01-13 Thomas Preud'homme ++ ++ * elfnn-aarch64.c (elfNN_aarch64_final_link_relocate): Use SYMBOLIC_BIND ++ to check if a symbol should be bound symbolically. ++ ++2015-01-11 H.J. Lu ++ ++ PR ld/17827 ++ * ld-x86-64/pr17689.out: Updated. ++ * ld-x86-64/pr17689b.S: Likewise. ++ ++ * ld-x86-64/pr17827.rd: New file. ++ ++ * ld-x86-64/x86-64.exp: Run PR ld/17827 test. ++ ++2015-01-05 H.J. Lu ++ ++ PR ld/17773 ++ * ld-elf/binutils.exp (binutils_test): Add an optional ++ readelf_options. Replace -l with $readelf_options. Add a ++ gap test. ++ * ld/testsuite/ld-elf/gap.s: New file. ++ + 2014-12-19 Matthew Fortune + + * ld-mips-elf/attr-gnu-4-00.d: Relax check for ISA extension. +diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp +index a75e070..c0bd39a 100644 +--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp ++++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp +@@ -175,6 +175,7 @@ run_dump_test "ifunc-21" + run_dump_test "ifunc-22" + + run_dump_test "relasz" ++run_dump_test "relocs-257-symbolic-func" + + set aarch64elflinktests { + {"ld-aarch64/so with global symbol" "-shared" "" "" {copy-reloc-so.s} +diff --git a/ld/testsuite/ld-aarch64/relocs-257-symbolic-func.d b/ld/testsuite/ld-aarch64/relocs-257-symbolic-func.d +new file mode 100644 +index 0000000..810fd43 +--- /dev/null ++++ b/ld/testsuite/ld-aarch64/relocs-257-symbolic-func.d +@@ -0,0 +1,5 @@ ++#source: relocs-257-symbolic-func.s ++#ld: -shared -Bsymbolic-functions ++#readelf: -r --wide ++#... ++.* +R_AARCH64_RELATIVE +.* +diff --git a/ld/testsuite/ld-aarch64/relocs-257-symbolic-func.s b/ld/testsuite/ld-aarch64/relocs-257-symbolic-func.s +new file mode 100644 +index 0000000..35d5ba8 +--- /dev/null ++++ b/ld/testsuite/ld-aarch64/relocs-257-symbolic-func.s +@@ -0,0 +1,11 @@ ++ .text ++ .global tempy ++ .type tempy, %function ++tempy: ++ .size tempy, .-tempy ++ .section .data.rel ++ .align 3 ++ .type tempy_ptr, %object ++ .size tempy_ptr, 8 ++tempy_ptr: ++ .xword tempy +diff --git a/ld/testsuite/ld-elf/binutils.exp b/ld/testsuite/ld-elf/binutils.exp +index 4ade8cb..37ab6b3 100644 +--- a/ld/testsuite/ld-elf/binutils.exp ++++ b/ld/testsuite/ld-elf/binutils.exp +@@ -38,8 +38,9 @@ if { [istarget *-*-linux*aout*] + # to hardwire the test name. This is important if ld_options contains + # absolute path names because the default test name is constructed + # from the prog_name and ld_options and we do not want absolute paths +-# to appear in the test_name. +-proc binutils_test { prog_name ld_options test {test_name ""}} { ++# to appear in the test_name. The optional readelf_options can be ++# used to specify different options for readelf. ++proc binutils_test { prog_name ld_options test {test_name ""} {readelf_options "-l"}} { + global as + global ld + global READELF +@@ -71,8 +72,8 @@ proc binutils_test { prog_name ld_options test {test_name ""}} { + return + } + +- send_log "$READELF -l --wide tmpdir/$test > tmpdir/$test.exp\n" +- set got [remote_exec host "$READELF -l --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.exp"] ++ send_log "$READELF $readelf_options --wide tmpdir/$test > tmpdir/$test.exp\n" ++ set got [remote_exec host "$READELF $readelf_options --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.exp"] + if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { + send_log "$got\n" + unresolved "$test_name" +@@ -111,8 +112,8 @@ proc binutils_test { prog_name ld_options test {test_name ""}} { + return + } + +- send_log "$READELF -l --wide tmpdir/$test > tmpdir/$test.out\n" +- set got [remote_exec host "$READELF -l --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"] ++ send_log "$READELF $readelf_options --wide tmpdir/$test > tmpdir/$test.out\n" ++ set got [remote_exec host "$READELF $readelf_options --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"] + if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { + send_log "$got\n" + unresolved "$test_name" +@@ -176,3 +177,5 @@ foreach testitem $tls_tests { + binutils_test objcopy $testopt $testitem + } + } ++ ++binutils_test strip "-s" gap "" "-lS" +diff --git a/ld/testsuite/ld-elf/gap.s b/ld/testsuite/ld-elf/gap.s +new file mode 100644 +index 0000000..039d26b +--- /dev/null ++++ b/ld/testsuite/ld-elf/gap.s +@@ -0,0 +1,4 @@ ++ .text ++ .global _start ++_start: ++ .long 0 +diff --git a/ld/testsuite/ld-x86-64/pr17689.out b/ld/testsuite/ld-x86-64/pr17689.out +index 7ef22e9..38e0352 100644 +--- a/ld/testsuite/ld-x86-64/pr17689.out ++++ b/ld/testsuite/ld-x86-64/pr17689.out +@@ -1 +1,2 @@ + PASS ++PASS +diff --git a/ld/testsuite/ld-x86-64/pr17689b.S b/ld/testsuite/ld-x86-64/pr17689b.S +index c95f891..64485c7 100644 +--- a/ld/testsuite/ld-x86-64/pr17689b.S ++++ b/ld/testsuite/ld-x86-64/pr17689b.S +@@ -5,8 +5,18 @@ main: + subq $8, %rsp + movq bar_alias(%rip), %rdi + call foo@PLT ++ movq ptr(%rip), %rax ++ movq (%rax), %rdi ++ call foo@PLT + xorl %eax, %eax + addq $8, %rsp + ret + .size main, .-main ++ .globl ptr ++ .section .data.rel,"aw",@progbits ++ .align 8 ++ .type ptr, @object ++ .size ptr, 8 ++ptr: ++ .quad bar_alias + .section .note.GNU-stack,"",@progbits +diff --git a/ld/testsuite/ld-x86-64/pr17827.rd b/ld/testsuite/ld-x86-64/pr17827.rd +new file mode 100644 +index 0000000..d78ea2f +--- /dev/null ++++ b/ld/testsuite/ld-x86-64/pr17827.rd +@@ -0,0 +1,4 @@ ++#failif ++#... ++[0-9a-f ]+R_X86_64_NONE.* ++#... +diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp +index 1119133..28e8108 100644 +--- a/ld/testsuite/ld-x86-64/x86-64.exp ++++ b/ld/testsuite/ld-x86-64/x86-64.exp +@@ -373,6 +373,14 @@ if { [isnative] && [which $CC] != 0 } { + {{readelf {-Wr} pr17689.rd}} \ + "pr17689" \ + ] \ ++ [list \ ++ "Build pr17827 with PIE without -fPIE" \ ++ "tmpdir/pr17689.so -pie" \ ++ "" \ ++ { pr17689b.S } \ ++ {{readelf {-Wr} pr17827.rd}} \ ++ "pr17827" \ ++ ] \ + ] + + run_ld_link_exec_tests [] [list \ +diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog +index 38de39a..e19e382 100644 +--- a/opcodes/ChangeLog ++++ b/opcodes/ChangeLog +@@ -2,6 +2,10 @@ + + * configure: Regenerate. + ++2014-12-23 Tristan Gingold ++ ++ * configure: Regenerate. ++ + 2014-12-16 Matthew Fortune + + * mips-opc.c (mips_builtin_opcodes): Add JALRC alias for +diff --git a/opcodes/configure b/opcodes/configure +index 1361ef6..c9c04ce 100755 +--- a/opcodes/configure ++++ b/opcodes/configure +@@ -1,6 +1,6 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.64 for opcodes 2.25. ++# Generated by GNU Autoconf 2.64 for opcodes 2.25.0. + # + # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, + # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software +@@ -556,8 +556,8 @@ MAKEFLAGS= + # Identity of this package. + PACKAGE_NAME='opcodes' + PACKAGE_TARNAME='opcodes' +-PACKAGE_VERSION='2.25' +-PACKAGE_STRING='opcodes 2.25' ++PACKAGE_VERSION='2.25.0' ++PACKAGE_STRING='opcodes 2.25.0' + PACKAGE_BUGREPORT='' + PACKAGE_URL='' + +@@ -1319,7 +1319,7 @@ if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +-\`configure' configures opcodes 2.25 to adapt to many kinds of systems. ++\`configure' configures opcodes 2.25.0 to adapt to many kinds of systems. + + Usage: $0 [OPTION]... [VAR=VALUE]... + +@@ -1390,7 +1390,7 @@ fi + + if test -n "$ac_init_help"; then + case $ac_init_help in +- short | recursive ) echo "Configuration of opcodes 2.25:";; ++ short | recursive ) echo "Configuration of opcodes 2.25.0:";; + esac + cat <<\_ACEOF + +@@ -1497,7 +1497,7 @@ fi + test -n "$ac_init_help" && exit $ac_status + if $ac_init_version; then + cat <<\_ACEOF +-opcodes configure 2.25 ++opcodes configure 2.25.0 + generated by GNU Autoconf 2.64 + + Copyright (C) 2009 Free Software Foundation, Inc. +@@ -1907,7 +1907,7 @@ cat >config.log <<_ACEOF + This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + +-It was created by opcodes $as_me 2.25, which was ++It was created by opcodes $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + $ $0 $@ +@@ -3715,7 +3715,7 @@ fi + + # Define the identity of the package. + PACKAGE='opcodes' +- VERSION='2.25' ++ VERSION='2.25.0' + + + cat >>confdefs.h <<_ACEOF +@@ -13209,7 +13209,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + # report actual input values of CONFIG_FILES etc. instead of their + # values after options handling. + ac_log=" +-This file was extended by opcodes $as_me 2.25, which was ++This file was extended by opcodes $as_me 2.25.0, which was + generated by GNU Autoconf 2.64. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES +@@ -13273,7 +13273,7 @@ Report bugs to the package provider." + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_cs_version="\\ +-opcodes config.status 2.25 ++opcodes config.status 2.25.0 + configured by $0, generated by GNU Autoconf 2.64, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + diff --git a/system/devel/binutils/pspec.xml b/system/devel/binutils/pspec.xml index e75ef7ef..a0155180 100644 --- a/system/devel/binutils/pspec.xml +++ b/system/devel/binutils/pspec.xml @@ -11,9 +11,10 @@ app:console Assembler and linker tools Contains commands like as, ld, nm, objdump, ar, ranlib for compiling assembly code to the machine language, and for linking and manipulating the binary object files. - http://ftp.gnu.org/gnu/binutils/binutils-2.24.tar.bz2 + http://ftp.gnu.org/gnu/binutils/binutils-2.25.tar.bz2 - binutils-2.24-lto-testsuite.patch + binutils-2.25-roundup.patch + + + glibc-32bit + @@ -43,6 +47,13 @@ + + 2015-03-09 + 2.25 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-11-28 2.24 diff --git a/system/devel/bison/pspec.xml b/system/devel/bison/pspec.xml index 8742f119..05f953f4 100644 --- a/system/devel/bison/pspec.xml +++ b/system/devel/bison/pspec.xml @@ -12,7 +12,7 @@ app:console A yacc-compatible parser generator A yacc-compatible parser generator. Once you are proficient with Bison, you can use it to develop a wide range of language parsers, from those used in simple desk calculators to complex programming languages - mirrors://gnu/bison/bison-3.0.2.tar.xz + mirrors://gnu/bison/bison-3.0.4.tar.xz m4 gettext @@ -40,6 +40,13 @@ + + 2015-03-01 + 3.0.4 + Version bump. + Stefan Gronewold(groni) + groni@pisilinux.org + 2014-09-06 3.0.2 diff --git a/system/devel/catbox/pspec.xml b/system/devel/catbox/pspec.xml index 5068892d..bd9c3785 100644 --- a/system/devel/catbox/pspec.xml +++ b/system/devel/catbox/pspec.xml @@ -13,6 +13,10 @@ Python sandboxing module catbox is a Python sandboxing module commonly used by the package management system of PiSi Linux, PiSi. https://github.com/baris/catbox/archive/catbox-1.6.1.tar.gz + + python-setuptools + python-devel + @@ -28,6 +32,13 @@ + + 2015-03-19 + 1.6.1 + Fix Buildeps. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-05-11 1.6.1 diff --git a/system/devel/ccache/actions.py b/system/devel/ccache/actions.py index 618768d9..0def369a 100644 --- a/system/devel/ccache/actions.py +++ b/system/devel/ccache/actions.py @@ -17,8 +17,8 @@ def setup(): def build(): autotools.make() -def check(): - autotools.make("check") +#def check(): +# autotools.make("check") def install(): autotools.install() diff --git a/system/devel/ccache/pspec.xml b/system/devel/ccache/pspec.xml index 386a1659..15f90095 100644 --- a/system/devel/ccache/pspec.xml +++ b/system/devel/ccache/pspec.xml @@ -13,6 +13,9 @@ Fast C/C++ compiler cache ccache is a compiler cache. It speeds up recompilation of C/C++ code by caching previous compiles and detecting when the same compile is being done. http://samba.org/ftp/ccache/ccache-3.2.tar.xz + + zlib-devel + diff --git a/system/devel/cloog/pspec.xml b/system/devel/cloog/pspec.xml index 1d53e61e..196abc46 100644 --- a/system/devel/cloog/pspec.xml +++ b/system/devel/cloog/pspec.xml @@ -17,6 +17,7 @@ gmp-devel ppl-devel + isl-devel cloog-0.18.1-isl-compat.patch diff --git a/system/devel/cmake/actions.py b/system/devel/cmake/actions.py index 91c52aa4..4ae7bd61 100644 --- a/system/devel/cmake/actions.py +++ b/system/devel/cmake/actions.py @@ -11,6 +11,7 @@ def setup(): autotools.rawConfigure("--parallel=%s \ --system-libs \ --no-qt-gui \ + --no-system-jsoncpp \ --prefix=/usr \ --datadir=/share/cmake \ --docdir=/share/doc/cmake \ diff --git a/system/devel/cmake/pspec.xml b/system/devel/cmake/pspec.xml index d4846c78..bcb715d6 100644 --- a/system/devel/cmake/pspec.xml +++ b/system/devel/cmake/pspec.xml @@ -12,7 +12,7 @@ app:console Cross-platform, open-source make system CMake, the cross-platform, open-source make system. CMake is used to control the software compilation process using simple platform and compiler independent configuration files. CMake generates native makefiles and workspaces that can be used in the compiler environment of your choice. - http://www.cmake.org/files/v3.0/cmake-3.0.2.tar.gz + http://www.cmake.org/files/v3.2/cmake-3.2.2.tar.gz curl-devel expat-devel @@ -42,6 +42,27 @@ + + 2015-04-17 + 3.2.2 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2015-04-04 + 3.2.1 + Version bump. + Yusuf Aydemir + yusuf.aydemir@pisilinux.org + + + 2015-02-27 + 3.1.3 + Version bump. + Stefan Gronewold(groni) + groni@pisilinux.org + 2014-12-17 3.0.2 diff --git a/system/devel/elfutils/pspec.xml b/system/devel/elfutils/pspec.xml index f174da48..92bfa43b 100644 --- a/system/devel/elfutils/pspec.xml +++ b/system/devel/elfutils/pspec.xml @@ -13,7 +13,7 @@ library Libraries/utilities to handle ELF objects elfutils contains libraries and utilities to handle ELF objects and is a replacement for libelf. - https://fedorahosted.org/releases/e/l/elfutils/0.160/elfutils-0.160.tar.bz2 + https://fedorahosted.org/releases/e/l/elfutils/0.161/elfutils-0.161.tar.bz2 bzip2 xz-devel @@ -27,6 +27,7 @@ xz zlib bzip2 + libgcc
    /usr/bin @@ -37,6 +38,13 @@ + + 2015-04-09 + 0.161 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + 2014-11-23 0.160 diff --git a/system/devel/gmp/pspec.xml b/system/devel/gmp/pspec.xml index 1b256fa1..8043359f 100644 --- a/system/devel/gmp/pspec.xml +++ b/system/devel/gmp/pspec.xml @@ -44,6 +44,9 @@ emul32 32-bit shared libraries for gmp emul32 + + glibc-32bit + gmp diff --git a/system/devel/gobject-introspection/pspec.xml b/system/devel/gobject-introspection/pspec.xml index 7a027614..ea74157f 100644 --- a/system/devel/gobject-introspection/pspec.xml +++ b/system/devel/gobject-introspection/pspec.xml @@ -14,11 +14,12 @@ app:console Introspection system for GObject-based libraries gobject-introspection can scan C header and source files in order to generate introspection typelib files. It also provides an API to examine typelib files, useful for creating language bindings among other things. - mirrors://gnome/gobject-introspection/1.40/gobject-introspection-1.40.0.tar.xz + mirrors://gnome/gobject-introspection/1.44/gobject-introspection-1.44.0.tar.xz cairo-devel python-devel python-mako + glib2-devel @@ -57,6 +58,13 @@ + + 2015-04-06 + 1.44.0 + Version bump. + Ayhan Yalçınsoy + ayhanyalcinsoy@pisilinux.org + 2014-05-11 1.40.0 diff --git a/system/devel/guile/actions.py b/system/devel/guile/actions.py index e36eb64e..75df0f70 100644 --- a/system/devel/guile/actions.py +++ b/system/devel/guile/actions.py @@ -37,5 +37,7 @@ def install(): major = ".".join(get.srcVERSION().split(".")[:2]) pisitools.dodir("/etc/env.d") shelltools.echo("%s/etc/env.d/50guile" % get.installDIR(), 'GUILE_LOAD_PATH="/usr/share/guile/%s"' % major) + + pisitools.domove("/usr/lib/libguile-2.0.so.22.7.2-gdb.scm", "/usr/share/gdb/auto-load") pisitools.dodoc("AUTHORS", "ChangeLog", "HACKING", "NEWS", "README", "THANKS") diff --git a/system/devel/guile/pspec.xml b/system/devel/guile/pspec.xml index 2b7b608b..ab6ec0bf 100644 --- a/system/devel/guile/pspec.xml +++ b/system/devel/guile/pspec.xml @@ -17,6 +17,8 @@ mirrors://gnu/guile/guile-2.0.11.tar.xz gc-devel + gettext-devel + gmp-devel @@ -30,6 +32,7 @@ libffi libtool-ltdl libunistring + readline /etc @@ -40,6 +43,7 @@ /usr/lib/lib* /usr/share/guile /usr/share/emacs + /usr/share/gdb/auto-load /usr/lib/guile/2.0 diff --git a/system/devel/isl/pspec.xml b/system/devel/isl/pspec.xml index 61524e00..2223b506 100644 --- a/system/devel/isl/pspec.xml +++ b/system/devel/isl/pspec.xml @@ -13,6 +13,9 @@ Integer Set Library isl is a library for manipulating sets and relations of integer points bounded by linear constraints. http://isl.gforge.inria.fr/isl-0.13.tar.bz2 + + gmp-devel + @@ -40,7 +43,7 @@ - 2014-09-06 + 2015-05-05 0.13 Version bump. Serdar Soytetir diff --git a/system/devel/libmpc/actions.py b/system/devel/libmpc/actions.py index 58964f02..94a8f17c 100644 --- a/system/devel/libmpc/actions.py +++ b/system/devel/libmpc/actions.py @@ -11,6 +11,9 @@ from pisi.actionsapi import get def setup(): autotools.configure() + + # for unused + pisitools.dosed("libtool", " -shared ", " -Wl,-O1,--as-needed -shared ") def build(): autotools.make() diff --git a/system/devel/libmpc/pspec.xml b/system/devel/libmpc/pspec.xml index 7ba194ed..35c520f0 100644 --- a/system/devel/libmpc/pspec.xml +++ b/system/devel/libmpc/pspec.xml @@ -12,7 +12,7 @@ library High precision and correct rounding library libmpc is a library for arithmetic of complex numbers with arbitrarily high precision and correct rounding. - ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.2.tar.gz + ftp://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz gmp-devel mpfr-devel @@ -44,6 +44,13 @@ + + 2015-03-08 + 1.0.3 + Version bump. + Ertuğrul Erata + ertugrulerata@gmail.com + 2014-09-06 1.0.2 diff --git a/system/devel/python-setuptools/pspec.xml b/system/devel/python-setuptools/pspec.xml index b98cfba2..208a5f6d 100644 --- a/system/devel/python-setuptools/pspec.xml +++ b/system/devel/python-setuptools/pspec.xml @@ -12,7 +12,7 @@ library Python setuptools python-setuptools is a collection of enhancements to the Python distutils that allow you to more easily build and distribute Python packages, especially ones that have dependencies on other packages. - http://pypi.python.org/packages/source/d/distribute/distribute-0.6.49.tar.gz + http://pypi.python.org/packages/source/d/distribute/distribute-0.6.49.tar.gz @@ -25,7 +25,7 @@ - + 2014-05-11 0.6.49 Release bump. diff --git a/system/devel/quilt/pspec.xml b/system/devel/quilt/pspec.xml index 7e02740a..dfccbb90 100644 --- a/system/devel/quilt/pspec.xml +++ b/system/devel/quilt/pspec.xml @@ -12,7 +12,7 @@ app:console Scripts for working with series of patches quilt allow one to manage a series of patches by keeping track of the changes each patch makes. - http://mirror.rackdc.com/savannah/quilt/quilt-0.61.tar.gz + http://mirror.rackdc.com/savannah/quilt/quilt-0.64.tar.gz gawk gettext @@ -37,6 +37,13 @@ + + 2015-03-01 + 0.64 + Version bump. + Stefan Gronewold(groni) + groni@pisilinux.org + 2014-05-11 0.61 diff --git a/system/devel/xorg-proto/actions.py b/system/devel/xorg-proto/actions.py deleted file mode 100644 index 24b007ed..00000000 --- a/system/devel/xorg-proto/actions.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Licensed under the GNU General Public License, version 3. -# See the file http://www.gnu.org/licenses/gpl.txt - -from pisi.actionsapi import autotools -from pisi.actionsapi import pisitools -from pisi.actionsapi import shelltools -from pisi.actionsapi import get - -WorkDir = "." -SkipFiles = [".pc", "filelist", "patches", "pisiBuildState"] - -def setup(): - pisitools.dosed("*/Makefile.am", r"/doc/\$\(PACKAGE\)", "/doc/xorg-proto") - - for package in shelltools.ls("."): - if package in SkipFiles: - continue - shelltools.cd(package) - autotools.autoreconf("-vif") - autotools.configure("--without-xmlto --without-fop") - shelltools.cd("../") - -def build(): - for package in shelltools.ls("."): - if package in SkipFiles: - continue - shelltools.cd(package) - autotools.make() - shelltools.cd("../") - -def install(): - for package in shelltools.ls("."): - if package in SkipFiles: - continue - shelltools.cd(package) - autotools.rawInstall("DESTDIR=%s" % get.installDIR()) - shelltools.cd("../") diff --git a/system/devel/xorg-proto/files/docdir.patch b/system/devel/xorg-proto/files/docdir.patch deleted file mode 100644 index e54071a7..00000000 --- a/system/devel/xorg-proto/files/docdir.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: work/xproxymanagementprotocol-1.0.3/Makefile.am -=================================================================== ---- work.orig/xproxymanagementprotocol-1.0.3/Makefile.am -+++ work/xproxymanagementprotocol-1.0.3/Makefile.am -@@ -6,7 +6,8 @@ xproxymng_HEADERS = \ - pkgconfigdir = $(libdir)/pkgconfig - pkgconfig_DATA = xproxymngproto.pc - --dist_doc_DATA = PM_spec -+xproxymngdocdir = $(datadir)/doc/$(PACKAGE) -+xproxymngdoc_DATA = PM_spec - - EXTRA_DIST = xproxymngproto.pc.in - diff --git a/system/devel/xorg-proto/pspec.xml b/system/devel/xorg-proto/pspec.xml deleted file mode 100644 index 5bdc3eab..00000000 --- a/system/devel/xorg-proto/pspec.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - xorg-proto - http://x.org/ - - PisiLinux Community - admins@pisilinux.org - - MIT - library - X.Org Protocol Headers - This package includes the protocol headers needed for X11 development. - mirrors://xorg/individual/proto/bigreqsproto-1.1.2.tar.bz2 - mirrors://xorg/individual/proto/presentproto-1.0.tar.bz2 - mirrors://xorg/individual/proto/compositeproto-0.4.2.tar.bz2 - mirrors://xorg/individual/proto/damageproto-1.2.1.tar.bz2 - mirrors://xorg/individual/proto/dmxproto-2.3.1.tar.bz2 - mirrors://xorg/individual/proto/dri2proto-2.8.tar.bz2 - mirrors://xorg/individual/proto/dri3proto-1.0.tar.bz2 - mirrors://xorg/individual/proto/fixesproto-5.0.tar.bz2 - mirrors://xorg/individual/proto/fontsproto-2.1.3.tar.bz2 - mirrors://xorg/individual/proto/glproto-1.4.17.tar.bz2 - mirrors://xorg/individual/proto/inputproto-2.3.1.tar.bz2 - mirrors://xorg/individual/proto/kbproto-1.0.6.tar.bz2 - mirrors://xorg/individual/proto/printproto-1.0.5.tar.bz2 - mirrors://xorg/individual/proto/randrproto-1.4.0.tar.bz2 - mirrors://xorg/individual/proto/recordproto-1.14.2.tar.bz2 - mirrors://xorg/individual/proto/renderproto-0.11.1.tar.bz2 - mirrors://xorg/individual/proto/resourceproto-1.2.0.tar.bz2 - mirrors://xorg/individual/proto/scrnsaverproto-1.2.2.tar.bz2 - mirrors://xorg/individual/proto/videoproto-2.3.2.tar.bz2 - mirrors://xorg/individual/proto/xcmiscproto-1.2.2.tar.bz2 - mirrors://xorg/individual/proto/xextproto-7.3.0.tar.bz2 - mirrors://xorg/individual/proto/xf86bigfontproto-1.2.0.tar.bz2 - mirrors://xorg/individual/proto/xf86dgaproto-2.1.tar.bz2 - mirrors://xorg/individual/proto/xf86driproto-2.1.1.tar.bz2 - mirrors://xorg/individual/proto/xf86vidmodeproto-2.3.1.tar.bz2 - mirrors://xorg/individual/proto/xineramaproto-1.2.1.tar.bz2 - mirrors://xorg/individual/proto/xproto-7.0.27.tar.bz2 - mirrors://xorg/individual/proto/xproxymanagementprotocol-1.0.3.tar.bz2 - https://github.com/bbidulock/vncproto/releases/download/vncproto-1.1/vncproto-1.1.tar.bz2 - - util-macros - libXau-devel - - - docdir.patch - - - - - xorg-proto - - libXau-devel - - - /usr/include - /usr/lib/pkgconfig - /usr/share/doc - /usr/share/man/man7/Xprint.7 - - - - - - 2015-01-27 - 7.6 - Update xproto - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-09-20 - 7.6 - Update vncproto, fix dependencies. - Marcin Bojara - marcin@pisilinux.org - - - 2014-08-31 - 7.6 - Update. - Marcin Bojara - marcin@pisilinux.org - - - 2014-05-11 - 7.6 - Release bump. - Marcin Bojara - marcin@pisilinux.org - - - 2014-04-15 - 7.6 - xproto fontsproto version bump - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2014-03-07 - 7.6 - add presentproto dri3proto - Yusuf Aydemir - yusuf.aydemir@pisilinux.org - - - 2013-04-13 - 7.6 - Update: - xproto to version 7.0.24 - inputproto to version 2.3 (needed for xorg-server-0.14.0) - Marcin Bojara - marcin@pisilinux.org - - - 2012-10-15 - 7.6 - First release - Marcin Bojara - marcin@pisilinux.org - - - diff --git a/system/devel/xorg-proto/translations.xml b/system/devel/xorg-proto/translations.xml deleted file mode 100644 index 1a917dfe..00000000 --- a/system/devel/xorg-proto/translations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - xorg-proto - Entêtes de protocole de X.Org. - X.Org Protokoll Header - X.Org Protokol Başlıkları - Bu paket, X11 geliştirme için gerekli protokol başlıklarını içerir. - - diff --git a/system/devel/xtrans/pspec.xml b/system/devel/xtrans/pspec.xml index ca5171ce..a6f9d1d9 100644 --- a/system/devel/xtrans/pspec.xml +++ b/system/devel/xtrans/pspec.xml @@ -12,9 +12,9 @@ library X.Org trans library xtrans includes a number of routines to make X implementations transport-independent. - mirrors://xorg/individual/lib/xtrans-1.3.4.tar.bz2 + mirrors://xorg/individual/lib/xtrans-1.3.5.tar.bz2 - xorg-proto + util-macros @@ -31,6 +31,13 @@ + + 2015-05-05 + 1.3.5 + Version bump. + Marcin Bojara + marcin@pisilinux.org + 2014-07-11 1.3.4